WIP: Brush assets project #106303
|
@ -73,8 +73,8 @@ Static Source Code Checking
|
|||
|
||||
Documentation Checking
|
||||
|
||||
* check_wiki_file_structure:
|
||||
Check the WIKI documentation for the source-tree's file structure
|
||||
* check_docs_file_structure:
|
||||
Check the documentation for the source-tree's file structure
|
||||
matches Blender's source-code.
|
||||
See: https://developer.blender.org/docs/features/code_layout/
|
||||
|
||||
|
@ -503,9 +503,9 @@ check_clang_array: .FORCE
|
|||
check_mypy: .FORCE
|
||||
@$(PYTHON) "$(BLENDER_DIR)/tools/check_source/check_mypy.py"
|
||||
|
||||
check_wiki_file_structure: .FORCE
|
||||
check_docs_file_structure: .FORCE
|
||||
@PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/tools/check_wiki/check_wiki_file_structure.py"
|
||||
"$(BLENDER_DIR)/tools/check_docs/check_docs_code_layout.py"
|
||||
|
||||
check_spelling_py: .FORCE
|
||||
@PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(INC
|
||||
include
|
||||
PUBLIC include
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
@ -20,3 +20,4 @@ set(LIB
|
|||
)
|
||||
|
||||
blender_add_lib(extern_fmtlib "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
add_library(bf::extern::fmtlib ALIAS extern_fmtlib)
|
||||
|
|
|
@ -76,8 +76,9 @@ ccl_device int bsdf_transparent_sample(ccl_private const ShaderClosure *sc,
|
|||
{
|
||||
// only one direction is possible
|
||||
*wo = -wi;
|
||||
*pdf = 1;
|
||||
*eval = one_spectrum();
|
||||
/* Some high number for MIS. */
|
||||
*pdf = 1e6f;
|
||||
*eval = one_spectrum() * 1e6f;
|
||||
return LABEL_TRANSMIT | LABEL_TRANSPARENT;
|
||||
}
|
||||
|
||||
|
|
|
@ -208,6 +208,7 @@ void Scene::device_update(Device *device_, Progress &progress)
|
|||
if (film->update_lightgroups(this)) {
|
||||
light_manager->tag_update(this, ccl::LightManager::LIGHT_MODIFIED);
|
||||
object_manager->tag_update(this, ccl::ObjectManager::OBJECT_MODIFIED);
|
||||
background->tag_modified();
|
||||
}
|
||||
if (film->exposure_is_modified()) {
|
||||
integrator->tag_modified();
|
||||
|
|
|
@ -1320,9 +1320,14 @@ class UserExtensionRepo(StructRNA):
|
|||
"""Return ``directory`` or a default path derived from the users scripts path."""
|
||||
if self.use_custom_directory:
|
||||
return self.custom_directory
|
||||
import os
|
||||
import bpy
|
||||
return os.path.join(bpy.utils.user_resource('SCRIPTS', path="extensions"), self.module)
|
||||
import os
|
||||
# TODO: this should eventually be accessed via `bpy.utils.user_resource('EXTENSIONS')`
|
||||
# which points to the same location (by default).
|
||||
if (path := bpy.utils.resource_path('USER')):
|
||||
return os.path.join(path, "extensions", self.module)
|
||||
# Unlikely this is ever encountered.
|
||||
return ""
|
||||
|
||||
|
||||
class HydraRenderEngine(RenderEngine):
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "BLI_fileops.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_serialize.hh"
|
||||
|
||||
#include "BKE_bake_items.hh"
|
||||
|
@ -33,6 +34,13 @@ class BlobReader {
|
|||
* \return True on success, otherwise false.
|
||||
*/
|
||||
[[nodiscard]] virtual bool read(const BlobSlice &slice, void *r_data) const = 0;
|
||||
|
||||
/**
|
||||
* Provides an #istream that can be used to read the data from the given slice.
|
||||
* \return True on success, otherwise false.
|
||||
*/
|
||||
[[nodiscard]] virtual bool read_as_stream(const BlobSlice &slice,
|
||||
FunctionRef<bool(std::istream &)> fn) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -45,6 +53,15 @@ class BlobWriter {
|
|||
* \return Slice where the data has been written to.
|
||||
*/
|
||||
virtual BlobSlice write(const void *data, int64_t size) = 0;
|
||||
|
||||
/**
|
||||
* Provides an #ostream that can be used to write the blob.
|
||||
* \param file_extension: May be used if the data is written to an independent file. Based on the
|
||||
* implementation, this may be ignored.
|
||||
* \return Slice where the data has been written to.
|
||||
*/
|
||||
virtual BlobSlice write_as_stream(StringRef file_extension,
|
||||
FunctionRef<void(std::ostream &)> fn);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -72,6 +89,24 @@ class BlobWriteSharing : NonCopyable, NonMovable {
|
|||
*/
|
||||
Map<const ImplicitSharingInfo *, StoredByRuntimeValue> stored_by_runtime_;
|
||||
|
||||
struct SliceHash {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
|
||||
BLI_STRUCT_EQUALITY_OPERATORS_2(SliceHash, a, b)
|
||||
|
||||
uint64_t hash() const
|
||||
{
|
||||
return get_default_hash(this->a, this->b);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remembers where data was stored based on the hash of the data. This allows us to skip writing
|
||||
* the same array again if it has the same hash.
|
||||
*/
|
||||
Map<SliceHash, BlobSlice> slice_by_content_hash_;
|
||||
|
||||
public:
|
||||
~BlobWriteSharing();
|
||||
|
||||
|
@ -84,6 +119,14 @@ class BlobWriteSharing : NonCopyable, NonMovable {
|
|||
[[nodiscard]] std::shared_ptr<io::serialize::DictionaryValue> write_implicitly_shared(
|
||||
const ImplicitSharingInfo *sharing_info,
|
||||
FunctionRef<std::shared_ptr<io::serialize::DictionaryValue>()> write_fn);
|
||||
|
||||
/**
|
||||
* Checks if the given data was written before. If it was, it's not written again, but a
|
||||
* reference to the previously written data is returned. If the data is new, it's written now.
|
||||
* Its hash is remembered so that the same data won't be written again.
|
||||
*/
|
||||
[[nodiscard]] std::shared_ptr<io::serialize::DictionaryValue> write_deduplicated(
|
||||
BlobWriter &writer, const void *data, int64_t size_in_bytes);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -132,17 +175,25 @@ class DiskBlobReader : public BlobReader {
|
|||
*/
|
||||
class DiskBlobWriter : public BlobWriter {
|
||||
private:
|
||||
/** Directory path that contains all blob files. */
|
||||
std::string blob_dir_;
|
||||
/** Name of the file that data is written to. */
|
||||
std::string base_name_;
|
||||
std::string blob_name_;
|
||||
/** File handle. */
|
||||
std::ostream &blob_file_;
|
||||
/** File handle. The file is opened when the first data is written. */
|
||||
std::fstream blob_stream_;
|
||||
/** Current position in the file. */
|
||||
int64_t current_offset_;
|
||||
int64_t current_offset_ = 0;
|
||||
/** Used to generate file names for bake data that is stored in independent files. */
|
||||
int independent_file_count_ = 0;
|
||||
|
||||
public:
|
||||
DiskBlobWriter(std::string blob_name, std::ostream &blob_file, int64_t current_offset);
|
||||
DiskBlobWriter(std::string blob_dir, std::string base_name);
|
||||
|
||||
BlobSlice write(const void *data, int64_t size) override;
|
||||
|
||||
BlobSlice write_as_stream(StringRef file_extension,
|
||||
FunctionRef<void(std::ostream &)> fn) override;
|
||||
};
|
||||
|
||||
void serialize_bake(const BakeState &bake_state,
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_index_mask_fwd.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
|
@ -31,17 +32,11 @@
|
|||
|
||||
struct Object;
|
||||
struct Collection;
|
||||
namespace blender {
|
||||
namespace index_mask {
|
||||
class IndexMask;
|
||||
}
|
||||
using index_mask::IndexMask;
|
||||
namespace bke {
|
||||
namespace blender::bke {
|
||||
class AnonymousAttributePropagationInfo;
|
||||
class AttributeAccessor;
|
||||
class MutableAttributeAccessor;
|
||||
} // namespace bke
|
||||
} // namespace blender
|
||||
} // namespace blender::bke
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
|
|
|
@ -8,13 +8,7 @@
|
|||
* \ingroup bke
|
||||
*/
|
||||
|
||||
namespace blender {
|
||||
namespace index_mask {
|
||||
class IndexMask;
|
||||
}
|
||||
using index_mask::IndexMask;
|
||||
} // namespace blender
|
||||
|
||||
#include "BLI_index_mask_fwd.hh"
|
||||
#include "BLI_offset_indices.hh"
|
||||
|
||||
#include "BKE_mesh.h"
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
|
@ -67,8 +68,6 @@ struct wmSpaceTypeListenerParams {
|
|||
};
|
||||
|
||||
struct SpaceType {
|
||||
SpaceType *next, *prev;
|
||||
|
||||
char name[BKE_ST_MAXNAME]; /* for menus */
|
||||
int spaceid; /* unique space identifier */
|
||||
int iconid; /* icon lookup for menus */
|
||||
|
@ -147,6 +146,8 @@ struct SpaceType {
|
|||
|
||||
/** Default key-maps to add. */
|
||||
int keymapflag;
|
||||
|
||||
~SpaceType();
|
||||
};
|
||||
|
||||
/* region types are also defined using spacetypes_init, via a callback */
|
||||
|
@ -547,8 +548,8 @@ struct AssetShelfType {
|
|||
|
||||
SpaceType *BKE_spacetype_from_id(int spaceid);
|
||||
ARegionType *BKE_regiontype_from_id(const SpaceType *st, int regionid);
|
||||
const ListBase *BKE_spacetypes_list();
|
||||
void BKE_spacetype_register(SpaceType *st);
|
||||
blender::Span<std::unique_ptr<SpaceType>> BKE_spacetypes_list();
|
||||
void BKE_spacetype_register(std::unique_ptr<SpaceType> st);
|
||||
bool BKE_spacetype_exists(int spaceid);
|
||||
void BKE_spacetypes_free(); /* only for quitting blender */
|
||||
|
||||
|
|
|
@ -10,15 +10,9 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
namespace blender {
|
||||
namespace index_mask {
|
||||
class IndexMask;
|
||||
}
|
||||
using index_mask::IndexMask;
|
||||
} // namespace blender
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_bit_group_vector.hh"
|
||||
#include "BLI_index_mask_fwd.hh"
|
||||
#include "BLI_offset_indices.hh"
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* \brief Volume data-block.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "BLI_bounds_types.hh"
|
||||
|
@ -24,6 +25,10 @@ struct Scene;
|
|||
struct Volume;
|
||||
struct VolumeGridVector;
|
||||
|
||||
namespace blender::bke::bake {
|
||||
struct BakeMaterialsList;
|
||||
}
|
||||
|
||||
/* Module */
|
||||
|
||||
void BKE_volumes_init();
|
||||
|
@ -133,6 +138,8 @@ struct VolumeRuntime {
|
|||
char velocity_x_grid[64] = "";
|
||||
char velocity_y_grid[64] = "";
|
||||
char velocity_z_grid[64] = "";
|
||||
|
||||
std::unique_ptr<bake::BakeMaterialsList> bake_materials;
|
||||
};
|
||||
|
||||
} // namespace blender::bke
|
||||
|
|
|
@ -29,7 +29,6 @@ set(INC
|
|||
../../../intern/memutil
|
||||
../../../intern/mikktspace
|
||||
../../../intern/opensubdiv
|
||||
../../../extern/fmtlib/include
|
||||
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -575,7 +574,7 @@ set(LIB
|
|||
bf_rna
|
||||
bf_shader_fx
|
||||
bf_simulation
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
PRIVATE bf::intern::atomic
|
||||
# For `vfontdata_freetype.c`.
|
||||
${FREETYPE_LIBRARIES} ${BROTLI_LIBRARIES}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_pointcloud.hh"
|
||||
#include "BKE_volume.hh"
|
||||
|
||||
#include "BLI_endian_defines.h"
|
||||
#include "BLI_endian_switch.h"
|
||||
|
@ -16,6 +17,7 @@
|
|||
#include "BLI_path_util.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_volume_types.h"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_enum_types.hh"
|
||||
|
@ -71,12 +73,17 @@ void GeometryBakeItem::prepare_geometry_for_bake(GeometrySet &main_geometry,
|
|||
pointcloud->runtime->bake_materials = materials_to_weak_references(
|
||||
&pointcloud->mat, &pointcloud->totcol, data_block_map);
|
||||
}
|
||||
if (Volume *volume = geometry.get_volume_for_write()) {
|
||||
volume->runtime->bake_materials = materials_to_weak_references(
|
||||
&volume->mat, &volume->totcol, data_block_map);
|
||||
}
|
||||
if (bke::Instances *instances = geometry.get_instances_for_write()) {
|
||||
instances->attributes_for_write().remove_anonymous();
|
||||
}
|
||||
geometry.keep_only_during_modify({GeometryComponent::Type::Mesh,
|
||||
GeometryComponent::Type::Curve,
|
||||
GeometryComponent::Type::PointCloud,
|
||||
GeometryComponent::Type::Volume,
|
||||
GeometryComponent::Type::Instance});
|
||||
});
|
||||
}
|
||||
|
@ -125,6 +132,12 @@ void GeometryBakeItem::try_restore_data_blocks(GeometrySet &main_geometry,
|
|||
std::move(pointcloud->runtime->bake_materials),
|
||||
data_block_map);
|
||||
}
|
||||
if (Volume *volume = geometry.get_volume_for_write()) {
|
||||
restore_materials(&volume->mat,
|
||||
&volume->totcol,
|
||||
std::move(volume->runtime->bake_materials),
|
||||
data_block_map);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,19 +10,30 @@
|
|||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_pointcloud.hh"
|
||||
#include "BKE_volume.hh"
|
||||
|
||||
#include "BLI_endian_defines.h"
|
||||
#include "BLI_endian_switch.h"
|
||||
#include "BLI_hash_md5.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_volume_types.h"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_enum_types.hh"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/io/Stream.h>
|
||||
# include <openvdb/openvdb.h>
|
||||
|
||||
# include "BKE_volume_grid.hh"
|
||||
#endif
|
||||
|
||||
namespace blender::bke::bake {
|
||||
|
||||
using namespace io::serialize;
|
||||
|
@ -49,6 +60,30 @@ std::optional<BlobSlice> BlobSlice::deserialize(const DictionaryValue &io_slice)
|
|||
return BlobSlice{*name, {*start, *size}};
|
||||
}
|
||||
|
||||
BlobSlice BlobWriter::write_as_stream(const StringRef /*file_extension*/,
|
||||
const FunctionRef<void(std::ostream &)> fn)
|
||||
{
|
||||
std::ostringstream stream{std::ios::binary};
|
||||
fn(stream);
|
||||
std::string data = stream.rdbuf()->str();
|
||||
return this->write(data.data(), data.size());
|
||||
}
|
||||
|
||||
bool BlobReader::read_as_stream(const BlobSlice &slice, FunctionRef<bool(std::istream &)> fn) const
|
||||
{
|
||||
const int64_t size = slice.range.size();
|
||||
std::string buffer;
|
||||
buffer.resize(size);
|
||||
if (!this->read(slice, buffer.data())) {
|
||||
return false;
|
||||
}
|
||||
std::istringstream stream{buffer, std::ios::binary};
|
||||
if (!fn(stream)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DiskBlobReader::DiskBlobReader(std::string blobs_dir) : blobs_dir_(std::move(blobs_dir)) {}
|
||||
|
||||
[[nodiscard]] bool DiskBlobReader::read(const BlobSlice &slice, void *r_data) const
|
||||
|
@ -72,21 +107,44 @@ DiskBlobReader::DiskBlobReader(std::string blobs_dir) : blobs_dir_(std::move(blo
|
|||
return true;
|
||||
}
|
||||
|
||||
DiskBlobWriter::DiskBlobWriter(std::string blob_name,
|
||||
std::ostream &blob_file,
|
||||
const int64_t current_offset)
|
||||
: blob_name_(std::move(blob_name)), blob_file_(blob_file), current_offset_(current_offset)
|
||||
DiskBlobWriter::DiskBlobWriter(std::string blob_dir, std::string base_name)
|
||||
: blob_dir_(std::move(blob_dir)), base_name_(std::move(base_name))
|
||||
{
|
||||
blob_name_ = base_name_ + ".blob";
|
||||
}
|
||||
|
||||
BlobSlice DiskBlobWriter::write(const void *data, const int64_t size)
|
||||
{
|
||||
if (!blob_stream_.is_open()) {
|
||||
char blob_path[FILE_MAX];
|
||||
BLI_path_join(blob_path, sizeof(blob_path), blob_dir_.c_str(), blob_name_.c_str());
|
||||
BLI_file_ensure_parent_dir_exists(blob_path);
|
||||
blob_stream_.open(blob_path, std::ios::out | std::ios::binary);
|
||||
}
|
||||
|
||||
const int64_t old_offset = current_offset_;
|
||||
blob_file_.write(static_cast<const char *>(data), size);
|
||||
blob_stream_.write(static_cast<const char *>(data), size);
|
||||
current_offset_ += size;
|
||||
return {blob_name_, {old_offset, size}};
|
||||
}
|
||||
|
||||
BlobSlice DiskBlobWriter::write_as_stream(const StringRef file_extension,
|
||||
const FunctionRef<void(std::ostream &)> fn)
|
||||
{
|
||||
BLI_assert(file_extension.startswith("."));
|
||||
independent_file_count_++;
|
||||
const std::string file_name = fmt::format(
|
||||
"{}_file_{}{}", base_name_, independent_file_count_, file_extension);
|
||||
|
||||
char path[FILE_MAX];
|
||||
BLI_path_join(path, sizeof(path), blob_dir_.c_str(), file_name.c_str());
|
||||
BLI_file_ensure_parent_dir_exists(path);
|
||||
std::fstream stream{path, std::ios::out | std::ios::binary};
|
||||
fn(stream);
|
||||
const int64_t written_bytes_num = stream.tellg();
|
||||
return {file_name, {0, written_bytes_num}};
|
||||
}
|
||||
|
||||
BlobWriteSharing::~BlobWriteSharing()
|
||||
{
|
||||
for (const ImplicitSharingInfo *sharing_info : stored_by_runtime_.keys()) {
|
||||
|
@ -131,6 +189,16 @@ DictionaryValuePtr BlobWriteSharing::write_implicitly_shared(
|
|||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<io::serialize::DictionaryValue> BlobWriteSharing::write_deduplicated(
|
||||
BlobWriter &writer, const void *data, const int64_t size_in_bytes)
|
||||
{
|
||||
SliceHash content_hash;
|
||||
BLI_hash_md5_buffer(static_cast<const char *>(data), size_in_bytes, &content_hash);
|
||||
const BlobSlice slice = slice_by_content_hash_.lookup_or_add_cb(
|
||||
content_hash, [&]() { return writer.write(data, size_in_bytes); });
|
||||
return slice.serialize();
|
||||
}
|
||||
|
||||
std::optional<ImplicitSharingInfoAndData> BlobReadSharing::read_shared(
|
||||
const DictionaryValue &io_data,
|
||||
FunctionRef<std::optional<ImplicitSharingInfoAndData>()> read_fn) const
|
||||
|
@ -202,9 +270,12 @@ static std::optional<eCustomDataType> get_data_type_from_io_name(const StringRef
|
|||
* Write the data and remember which endianness the data had.
|
||||
*/
|
||||
static std::shared_ptr<DictionaryValue> write_blob_raw_data_with_endian(
|
||||
BlobWriter &blob_writer, const void *data, const int64_t size_in_bytes)
|
||||
BlobWriter &blob_writer,
|
||||
BlobWriteSharing &blob_sharing,
|
||||
const void *data,
|
||||
const int64_t size_in_bytes)
|
||||
{
|
||||
auto io_data = blob_writer.write(data, size_in_bytes).serialize();
|
||||
auto io_data = blob_sharing.write_deduplicated(blob_writer, data, size_in_bytes);
|
||||
if (ENDIAN_ORDER == B_ENDIAN) {
|
||||
io_data->append_str("endian", get_endian_io_name(ENDIAN_ORDER));
|
||||
}
|
||||
|
@ -255,10 +326,11 @@ static std::shared_ptr<DictionaryValue> write_blob_raw_data_with_endian(
|
|||
|
||||
/** Write bytes ignoring endianness. */
|
||||
static std::shared_ptr<DictionaryValue> write_blob_raw_bytes(BlobWriter &blob_writer,
|
||||
BlobWriteSharing &blob_sharing,
|
||||
const void *data,
|
||||
const int64_t size_in_bytes)
|
||||
{
|
||||
return blob_writer.write(data, size_in_bytes).serialize();
|
||||
return blob_sharing.write_deduplicated(blob_writer, data, size_in_bytes);
|
||||
}
|
||||
|
||||
/** Read bytes ignoring endianness. */
|
||||
|
@ -278,14 +350,16 @@ static std::shared_ptr<DictionaryValue> write_blob_raw_bytes(BlobWriter &blob_wr
|
|||
}
|
||||
|
||||
static std::shared_ptr<DictionaryValue> write_blob_simple_gspan(BlobWriter &blob_writer,
|
||||
BlobWriteSharing &blob_sharing,
|
||||
const GSpan data)
|
||||
{
|
||||
const CPPType &type = data.type();
|
||||
BLI_assert(type.is_trivial());
|
||||
if (type.size() == 1 || type.is<ColorGeometry4b>()) {
|
||||
return write_blob_raw_bytes(blob_writer, data.data(), data.size_in_bytes());
|
||||
return write_blob_raw_bytes(blob_writer, blob_sharing, data.data(), data.size_in_bytes());
|
||||
}
|
||||
return write_blob_raw_data_with_endian(blob_writer, data.data(), data.size_in_bytes());
|
||||
return write_blob_raw_data_with_endian(
|
||||
blob_writer, blob_sharing, data.data(), data.size_in_bytes());
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool read_blob_simple_gspan(const BlobReader &blob_reader,
|
||||
|
@ -327,7 +401,7 @@ static std::shared_ptr<DictionaryValue> write_blob_shared_simple_gspan(
|
|||
const ImplicitSharingInfo *sharing_info)
|
||||
{
|
||||
return blob_sharing.write_implicitly_shared(
|
||||
sharing_info, [&]() { return write_blob_simple_gspan(blob_writer, data); });
|
||||
sharing_info, [&]() { return write_blob_simple_gspan(blob_writer, blob_sharing, data); });
|
||||
}
|
||||
|
||||
[[nodiscard]] static const void *read_blob_shared_simple_gspan(
|
||||
|
@ -666,6 +740,54 @@ static std::unique_ptr<Instances> try_load_instances(const DictionaryValue &io_g
|
|||
return instances;
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
static Volume *try_load_volume(const DictionaryValue &io_geometry, const BlobReader &blob_reader)
|
||||
{
|
||||
const DictionaryValue *io_volume = io_geometry.lookup_dict("volume");
|
||||
if (!io_volume) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto *io_vdb = io_volume->lookup_dict("vdb");
|
||||
if (!io_vdb) {
|
||||
return nullptr;
|
||||
}
|
||||
openvdb::GridPtrVecPtr vdb_grids;
|
||||
if (std::optional<BlobSlice> vdb_slice = BlobSlice::deserialize(*io_vdb)) {
|
||||
if (!blob_reader.read_as_stream(*vdb_slice, [&](std::istream &stream) {
|
||||
try {
|
||||
openvdb::io::Stream vdb_stream{stream};
|
||||
vdb_grids = vdb_stream.getGrids();
|
||||
return true;
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
}))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Volume *volume = reinterpret_cast<Volume *>(BKE_id_new_nomain(ID_VO, nullptr));
|
||||
auto cancel = [&]() {
|
||||
BKE_id_free(nullptr, volume);
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
for (openvdb::GridBase::Ptr &vdb_grid : *vdb_grids) {
|
||||
if (vdb_grid) {
|
||||
bke::GVolumeGrid grid{std::move(vdb_grid)};
|
||||
BKE_volume_grid_add(volume, *grid.release());
|
||||
}
|
||||
}
|
||||
if (const io::serialize::ArrayValue *io_materials = io_volume->lookup_array("materials")) {
|
||||
if (!load_materials(*io_materials, volume->runtime->bake_materials)) {
|
||||
return cancel();
|
||||
}
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
#endif
|
||||
|
||||
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobReadSharing &blob_sharing)
|
||||
|
@ -675,6 +797,9 @@ static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
|||
geometry.replace_pointcloud(try_load_pointcloud(io_geometry, blob_reader, blob_sharing));
|
||||
geometry.replace_curves(try_load_curves(io_geometry, blob_reader, blob_sharing));
|
||||
geometry.replace_instances(try_load_instances(io_geometry, blob_reader, blob_sharing).release());
|
||||
#ifdef WITH_OPENVDB
|
||||
geometry.replace_volume(try_load_volume(io_geometry, blob_reader));
|
||||
#endif
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
@ -801,6 +926,34 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
|||
auto io_attributes = serialize_attributes(curves.attributes(), blob_writer, blob_sharing, {});
|
||||
io_curves->append("attributes", io_attributes);
|
||||
}
|
||||
#ifdef WITH_OPENVDB
|
||||
if (geometry.has_volume()) {
|
||||
const Volume &volume = *geometry.get_volume();
|
||||
const int grids_num = BKE_volume_num_grids(&volume);
|
||||
|
||||
auto io_volume = io_geometry->append_dict("volume");
|
||||
auto io_vdb = blob_writer
|
||||
.write_as_stream(".vdb",
|
||||
[&](std::ostream &stream) {
|
||||
openvdb::GridCPtrVec vdb_grids;
|
||||
Vector<bke::VolumeTreeAccessToken> tree_tokens;
|
||||
for (const int i : IndexRange(grids_num)) {
|
||||
const bke::VolumeGridData *grid = BKE_volume_grid_get(
|
||||
&volume, i);
|
||||
tree_tokens.append_as();
|
||||
vdb_grids.push_back(grid->grid_ptr(tree_tokens.last()));
|
||||
}
|
||||
|
||||
openvdb::io::Stream vdb_stream(stream);
|
||||
vdb_stream.write(vdb_grids);
|
||||
})
|
||||
.serialize();
|
||||
io_volume->append("vdb", std::move(io_vdb));
|
||||
|
||||
auto io_materials = serialize_materials(volume.runtime->bake_materials);
|
||||
io_volume->append("materials", io_materials);
|
||||
}
|
||||
#endif
|
||||
if (geometry.has_instances()) {
|
||||
const Instances &instances = *geometry.get_instances();
|
||||
auto io_instances = io_geometry->append_dict("instances");
|
||||
|
@ -814,10 +967,11 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
|||
serialize_geometry_set(reference.geometry_set(), blob_writer, blob_sharing));
|
||||
}
|
||||
|
||||
io_instances->append("transforms",
|
||||
write_blob_simple_gspan(blob_writer, instances.transforms()));
|
||||
io_instances->append("handles",
|
||||
write_blob_simple_gspan(blob_writer, instances.reference_handles()));
|
||||
io_instances->append(
|
||||
"transforms", write_blob_simple_gspan(blob_writer, blob_sharing, instances.transforms()));
|
||||
io_instances->append(
|
||||
"handles",
|
||||
write_blob_simple_gspan(blob_writer, blob_sharing, instances.reference_handles()));
|
||||
|
||||
auto io_attributes = serialize_attributes(
|
||||
instances.attributes(), blob_writer, blob_sharing, {"position"});
|
||||
|
@ -1037,7 +1191,8 @@ static void serialize_bake_item(const BakeItem &item,
|
|||
r_io_item.append_str("data", string_state_item->value());
|
||||
}
|
||||
else {
|
||||
r_io_item.append("data", write_blob_raw_bytes(blob_writer, str.data(), str.size()));
|
||||
r_io_item.append("data",
|
||||
write_blob_raw_bytes(blob_writer, blob_sharing, str.data(), str.size()));
|
||||
}
|
||||
}
|
||||
else if (const auto *primitive_state_item = dynamic_cast<const PrimitiveBakeItem *>(&item)) {
|
||||
|
|
|
@ -209,8 +209,13 @@ static void default_initialize_socket_value(const eNodeSocketDatatype socket_typ
|
|||
{
|
||||
const char *socket_idname = nodeStaticSocketType(socket_type, 0);
|
||||
const bNodeSocketType *typeinfo = nodeSocketTypeFind(socket_idname);
|
||||
typeinfo->geometry_nodes_cpp_type->copy_construct(typeinfo->geometry_nodes_default_cpp_value,
|
||||
r_value);
|
||||
if (typeinfo->geometry_nodes_default_cpp_value) {
|
||||
typeinfo->geometry_nodes_cpp_type->copy_construct(typeinfo->geometry_nodes_default_cpp_value,
|
||||
r_value);
|
||||
}
|
||||
else {
|
||||
typeinfo->geometry_nodes_cpp_type->value_initialize(r_value);
|
||||
}
|
||||
}
|
||||
|
||||
void move_bake_items_to_socket_values(
|
||||
|
|
|
@ -242,15 +242,14 @@ void BKE_preferences_extension_repo_dirpath_get(const bUserExtensionRepo *repo,
|
|||
return;
|
||||
}
|
||||
|
||||
char subdir[16 + sizeof(bUserExtensionRepo::module)];
|
||||
BLI_string_join(subdir, sizeof(subdir), "extensions", SEP_STR, repo->module);
|
||||
const std::optional<std::string> path = BKE_appdir_folder_id(BLENDER_USER_SCRIPTS, subdir);
|
||||
if (path.has_value()) {
|
||||
BLI_strncpy(dirpath, path.value().c_str(), dirpath_maxncpy);
|
||||
}
|
||||
else {
|
||||
/* TODO: support `BLENDER_USER_EXTENSIONS`, until then add to user resource. */
|
||||
std::optional<std::string> path = BKE_appdir_resource_path_id(BLENDER_RESOURCE_PATH_USER, false);
|
||||
/* Highly unlikely to fail as the directory doesn't have to exist. */
|
||||
if (!path) {
|
||||
dirpath[0] = '\0';
|
||||
return;
|
||||
}
|
||||
BLI_path_join(dirpath, dirpath_maxncpy, path.value().c_str(), "extensions", repo->module);
|
||||
}
|
||||
|
||||
bUserExtensionRepo *BKE_preferences_extension_repo_find_index(const UserDef *userdef, int index)
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
# include "BPY_extern.h"
|
||||
#endif
|
||||
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name ID Type Implementation
|
||||
* \{ */
|
||||
|
@ -201,12 +204,16 @@ IDTypeInfo IDType_ID_SCR = {
|
|||
* \{ */
|
||||
|
||||
/** Keep global; this has to be accessible outside of window-manager. */
|
||||
static ListBase spacetypes = {nullptr, nullptr};
|
||||
static Vector<std::unique_ptr<SpaceType>> &get_space_types()
|
||||
{
|
||||
static Vector<std::unique_ptr<SpaceType>> space_types;
|
||||
return space_types;
|
||||
}
|
||||
|
||||
/* not SpaceType itself */
|
||||
static void spacetype_free(SpaceType *st)
|
||||
SpaceType::~SpaceType()
|
||||
{
|
||||
LISTBASE_FOREACH (ARegionType *, art, &st->regiontypes) {
|
||||
LISTBASE_FOREACH (ARegionType *, art, &this->regiontypes) {
|
||||
#ifdef WITH_PYTHON
|
||||
BPY_callback_screen_free(art);
|
||||
#endif
|
||||
|
@ -230,24 +237,20 @@ static void spacetype_free(SpaceType *st)
|
|||
BLI_freelistN(&art->headertypes);
|
||||
}
|
||||
|
||||
BLI_freelistN(&st->regiontypes);
|
||||
BLI_freelistN(&st->asset_shelf_types);
|
||||
BLI_freelistN(&this->regiontypes);
|
||||
BLI_freelistN(&this->asset_shelf_types);
|
||||
}
|
||||
|
||||
void BKE_spacetypes_free()
|
||||
{
|
||||
LISTBASE_FOREACH (SpaceType *, st, &spacetypes) {
|
||||
spacetype_free(st);
|
||||
}
|
||||
|
||||
BLI_freelistN(&spacetypes);
|
||||
get_space_types().clear_and_shrink();
|
||||
}
|
||||
|
||||
SpaceType *BKE_spacetype_from_id(int spaceid)
|
||||
{
|
||||
LISTBASE_FOREACH (SpaceType *, st, &spacetypes) {
|
||||
for (std::unique_ptr<SpaceType> &st : get_space_types()) {
|
||||
if (st->spaceid == spaceid) {
|
||||
return st;
|
||||
return st.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -263,22 +266,21 @@ ARegionType *BKE_regiontype_from_id(const SpaceType *st, int regionid)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const ListBase *BKE_spacetypes_list()
|
||||
Span<std::unique_ptr<SpaceType>> BKE_spacetypes_list()
|
||||
{
|
||||
return &spacetypes;
|
||||
return get_space_types();
|
||||
}
|
||||
|
||||
void BKE_spacetype_register(SpaceType *st)
|
||||
void BKE_spacetype_register(std::unique_ptr<SpaceType> st)
|
||||
{
|
||||
/* sanity check */
|
||||
SpaceType *stype = BKE_spacetype_from_id(st->spaceid);
|
||||
if (stype) {
|
||||
printf("error: redefinition of spacetype %s\n", stype->name);
|
||||
spacetype_free(stype);
|
||||
MEM_freeN(stype);
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_addtail(&spacetypes, st);
|
||||
get_space_types().append(std::move(st));
|
||||
}
|
||||
|
||||
bool BKE_spacetype_exists(int spaceid)
|
||||
|
@ -408,7 +410,7 @@ void BKE_spacedata_copylist(ListBase *lb_dst, ListBase *lb_src)
|
|||
|
||||
void BKE_spacedata_draw_locks(bool set)
|
||||
{
|
||||
LISTBASE_FOREACH (SpaceType *, st, &spacetypes) {
|
||||
for (std::unique_ptr<SpaceType> &st : get_space_types()) {
|
||||
LISTBASE_FOREACH (ARegionType *, art, &st->regiontypes) {
|
||||
if (set) {
|
||||
art->do_lock = art->lock;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_anim_data.h"
|
||||
#include "BKE_bake_data_block_id.hh"
|
||||
#include "BKE_bpath.h"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_global.h"
|
||||
|
@ -170,6 +171,11 @@ static void volume_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, con
|
|||
STRNCPY(volume_dst->runtime->velocity_y_grid, volume_src->runtime->velocity_y_grid);
|
||||
STRNCPY(volume_dst->runtime->velocity_z_grid, volume_src->runtime->velocity_z_grid);
|
||||
|
||||
if (volume_src->runtime->bake_materials) {
|
||||
volume_dst->runtime->bake_materials = std::make_unique<blender::bke::bake::BakeMaterialsList>(
|
||||
*volume_src->runtime->bake_materials);
|
||||
}
|
||||
|
||||
volume_dst->batch_cache = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,15 +11,13 @@
|
|||
|
||||
#include "BLI_bit_span.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_index_mask_fwd.hh"
|
||||
#include "BLI_linear_allocator.hh"
|
||||
#include "BLI_offset_span.hh"
|
||||
#include "BLI_task.hh"
|
||||
#include "BLI_unique_sorted_indices.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
namespace blender {
|
||||
template<typename T> class VArray;
|
||||
}
|
||||
#include "BLI_virtual_array_fwd.hh"
|
||||
|
||||
namespace blender::index_mask {
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace blender::index_mask {
|
||||
|
||||
class IndexMask;
|
||||
|
||||
} // namespace blender::index_mask
|
||||
|
||||
namespace blender {
|
||||
|
||||
using index_mask::IndexMask;
|
||||
|
||||
} // namespace blender
|
|
@ -6,13 +6,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
namespace blender {
|
||||
namespace index_mask {
|
||||
class IndexMask;
|
||||
}
|
||||
using index_mask::IndexMask;
|
||||
} // namespace blender
|
||||
|
||||
#include "BLI_index_mask_fwd.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
|
|
|
@ -621,4 +621,18 @@ constexpr bool operator>=(StringRef a, StringRef b)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Formatting
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Support using the fmt library with #StringRef and implicitly also #StringRefNull.
|
||||
*/
|
||||
inline std::string_view format_as(StringRef str)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace blender {
|
||||
|
||||
template<typename T> class VArray;
|
||||
template<typename T> class VMutableArray;
|
||||
|
||||
} // namespace blender
|
|
@ -14,7 +14,6 @@ set(INC
|
|||
set(INC_SYS
|
||||
../../../extern/wcwidth
|
||||
../../../extern/json/include
|
||||
../../../extern/fmtlib/include
|
||||
|
||||
${EIGEN3_INCLUDE_DIRS}
|
||||
${ZLIB_INCLUDE_DIRS}
|
||||
|
@ -252,6 +251,7 @@ set(SRC
|
|||
BLI_implicit_sharing.hh
|
||||
BLI_implicit_sharing_ptr.hh
|
||||
BLI_index_mask.hh
|
||||
BLI_index_mask_fwd.hh
|
||||
BLI_index_range.hh
|
||||
BLI_inplace_priority_queue.hh
|
||||
BLI_iterator.h
|
||||
|
@ -381,6 +381,7 @@ set(SRC
|
|||
BLI_vector_set.hh
|
||||
BLI_vector_set_slots.hh
|
||||
BLI_virtual_array.hh
|
||||
BLI_virtual_array_fwd.hh
|
||||
BLI_virtual_vector_array.hh
|
||||
BLI_voxel.h
|
||||
BLI_winstuff.h
|
||||
|
@ -392,6 +393,7 @@ set(SRC
|
|||
|
||||
set(LIB
|
||||
PUBLIC bf::dna
|
||||
PRIVATE bf::extern::fmtlib
|
||||
bf_intern_eigen
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
extern_wcwidth
|
||||
|
|
|
@ -84,7 +84,7 @@ static const unsigned char fillbuf[64] = {0x80, 0 /* , 0, 0, ... */};
|
|||
* Initialize structure containing state of computation.
|
||||
* (RFC 1321, 3.3: Step 3)
|
||||
*/
|
||||
static void md5_init_ctx(struct md5_ctx *ctx)
|
||||
static void md5_init_ctx(md5_ctx *ctx)
|
||||
{
|
||||
ctx->A = 0x67452301;
|
||||
ctx->B = 0xefcdab89;
|
||||
|
@ -97,7 +97,7 @@ static void md5_init_ctx(struct md5_ctx *ctx)
|
|||
* this function updates the 'ctx' context for the next 'len' bytes starting at 'buffer'.
|
||||
* It is necessary that 'len' is a multiple of 64!!!
|
||||
*/
|
||||
static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
|
||||
static void md5_process_block(const void *buffer, size_t len, md5_ctx *ctx)
|
||||
{
|
||||
/* These are the four functions used in the four steps of the MD5 algorithm and defined in the
|
||||
* RFC 1321. The first function is a little bit optimized
|
||||
|
@ -257,7 +257,7 @@ static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ct
|
|||
* The result is always in little endian byte order,
|
||||
* so that a byte-wise output yields to the wanted ASCII representation of the message digest.
|
||||
*/
|
||||
static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
|
||||
static void *md5_read_ctx(const md5_ctx *ctx, void *resbuf)
|
||||
{
|
||||
md5_uint32 *digest = static_cast<md5_uint32 *>(resbuf);
|
||||
digest[0] = SWAP(ctx->A);
|
||||
|
@ -274,7 +274,7 @@ Top level public functions. */
|
|||
int BLI_hash_md5_stream(FILE *stream, void *resblock)
|
||||
{
|
||||
#define BLOCKSIZE 4096 /* IMPORTANT: must be a multiple of 64. */
|
||||
struct md5_ctx ctx;
|
||||
md5_ctx ctx;
|
||||
md5_uint32 len[2];
|
||||
char buffer[BLOCKSIZE + 72];
|
||||
size_t pad, sum;
|
||||
|
@ -346,7 +346,7 @@ int BLI_hash_md5_stream(FILE *stream, void *resblock)
|
|||
|
||||
void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock)
|
||||
{
|
||||
struct md5_ctx ctx;
|
||||
md5_ctx ctx;
|
||||
char restbuf[64 + 72];
|
||||
size_t blocks = len & ~63;
|
||||
size_t pad, rest;
|
||||
|
|
|
@ -1517,19 +1517,14 @@ bool isect_point_tri_v2_cw(const float pt[2],
|
|||
|
||||
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
|
||||
{
|
||||
if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v3, v1, pt) >= 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
float side12 = line_point_side_v2(v1, v2, pt);
|
||||
float side23 = line_point_side_v2(v2, v3, pt);
|
||||
float side31 = line_point_side_v2(v3, v1, pt);
|
||||
if (side12 >= 0.0f && side23 >= 0.0f && side31 >= 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
|
||||
if (!(line_point_side_v2(v3, v1, pt) >= 0.0f)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (side12 <= 0.0f && side23 <= 0.0f && side31 <= 0.0f) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1538,25 +1533,16 @@ int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2],
|
|||
int isect_point_quad_v2(
|
||||
const float pt[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2])
|
||||
{
|
||||
if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v3, v4, pt) >= 0.0f) {
|
||||
if (line_point_side_v2(v4, v1, pt) >= 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
float side12 = line_point_side_v2(v1, v2, pt);
|
||||
float side23 = line_point_side_v2(v2, v3, pt);
|
||||
float side34 = line_point_side_v2(v3, v4, pt);
|
||||
float side41 = line_point_side_v2(v4, v1, pt);
|
||||
if (side12 >= 0.0f && side23 >= 0.0f && side34 >= 0.0f && side41 >= 0.0f) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
|
||||
if (!(line_point_side_v2(v3, v4, pt) >= 0.0f)) {
|
||||
if (!(line_point_side_v2(v4, v1, pt) >= 0.0f)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (side12 <= 0.0f && side23 <= 0.0f && side34 <= 0.0f && side41 <= 0.0f) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_timeit.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
|
@ -43,7 +43,7 @@ void print_duration(Nanoseconds duration)
|
|||
{
|
||||
fmt::memory_buffer buf;
|
||||
format_duration(duration, buf);
|
||||
std::cout << std::string_view(buf.data(), buf.size());
|
||||
std::cout << StringRef(buf.data(), buf.size());
|
||||
}
|
||||
|
||||
ScopedTimer::~ScopedTimer()
|
||||
|
@ -54,8 +54,8 @@ ScopedTimer::~ScopedTimer()
|
|||
fmt::memory_buffer buf;
|
||||
fmt::format_to(fmt::appender(buf), FMT_STRING("Timer '{}' took "), name_);
|
||||
format_duration(duration, buf);
|
||||
buf.append(std::string_view("\n"));
|
||||
std::cout << std::string_view(buf.data(), buf.size());
|
||||
buf.append(StringRef("\n"));
|
||||
std::cout << StringRef(buf.data(), buf.size());
|
||||
}
|
||||
|
||||
ScopedTimerAveraged::~ScopedTimerAveraged()
|
||||
|
@ -70,12 +70,12 @@ ScopedTimerAveraged::~ScopedTimerAveraged()
|
|||
fmt::memory_buffer buf;
|
||||
fmt::format_to(fmt::appender(buf), FMT_STRING("Timer '{}': (Average: "), name_);
|
||||
format_duration(total_time_ / total_count_, buf);
|
||||
buf.append(std::string_view(", Min: "));
|
||||
buf.append(StringRef(", Min: "));
|
||||
format_duration(min_time_, buf);
|
||||
buf.append(std::string_view(", Last: "));
|
||||
buf.append(StringRef(", Last: "));
|
||||
format_duration(duration, buf);
|
||||
buf.append(std::string_view(")\n"));
|
||||
std::cout << std::string_view(buf.data(), buf.size());
|
||||
buf.append(StringRef(")\n"));
|
||||
std::cout << StringRef(buf.data(), buf.size());
|
||||
}
|
||||
|
||||
} // namespace blender::timeit
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
using namespace blender;
|
||||
|
||||
TEST(math_geom, DistToLine2DSimple)
|
||||
{
|
||||
|
@ -19,3 +22,95 @@ TEST(math_geom, DistToLineSegment2DSimple)
|
|||
float distance = dist_to_line_segment_v2(p, a, b);
|
||||
EXPECT_NEAR(sqrtf(2.0f), distance, 1e-6);
|
||||
}
|
||||
|
||||
TEST(math_geom, IsectPointTri2D)
|
||||
{
|
||||
float2 tri_cw[3] = {{-2, 1}, {4, 4}, {2, -3}};
|
||||
float2 tri_ccw[3] = {{-2, 1}, {2, -3}, {4, 4}};
|
||||
|
||||
float2 inside1{0, 0};
|
||||
float2 inside2{2, 2};
|
||||
float2 inside3{2, -1};
|
||||
float2 inside4{-1, 1};
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(inside1, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(inside1, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(inside2, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(inside2, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(inside3, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(inside3, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(inside4, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(inside4, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
|
||||
float2 outside1{2, 4};
|
||||
float2 outside2{-1, -1};
|
||||
float2 outside3{0, 3};
|
||||
float2 outside4{-4, 0};
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside1, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside1, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside2, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside2, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside3, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside3, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside4, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(0, isect_point_tri_v2(outside4, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
|
||||
float2 edge1{0, 2};
|
||||
float2 edge2{1, -2};
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(edge1, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(edge1, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(edge2, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(edge2, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
|
||||
float2 corner1{4, 4};
|
||||
float2 corner2{2, -3};
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(corner1, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(corner1, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
EXPECT_EQ(-1, isect_point_tri_v2(corner2, tri_cw[0], tri_cw[1], tri_cw[2]));
|
||||
EXPECT_EQ(+1, isect_point_tri_v2(corner2, tri_ccw[0], tri_ccw[1], tri_ccw[2]));
|
||||
}
|
||||
|
||||
TEST(math_geom, IsectPointQuad2D)
|
||||
{
|
||||
float2 quad_cw[4] = {{-2, 1}, {4, 4}, {5, 1}, {2, -3}};
|
||||
float2 quad_ccw[4] = {{-2, 1}, {2, -3}, {5, 1}, {4, 4}};
|
||||
|
||||
float2 inside1{0, 0};
|
||||
float2 inside2{2, 2};
|
||||
float2 inside3{3, -1};
|
||||
float2 inside4{-1, 1};
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(inside1, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(inside1, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(inside2, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(inside2, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(inside3, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(inside3, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(inside4, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(inside4, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
|
||||
float2 outside1{2, 4};
|
||||
float2 outside2{-1, -1};
|
||||
float2 outside3{0, 3};
|
||||
float2 outside4{-4, 0};
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside1, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside1, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside2, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside2, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside3, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside3, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside4, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(0, isect_point_quad_v2(outside4, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
|
||||
float2 edge1{0, 2};
|
||||
float2 edge2{1, -2};
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(edge1, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(edge1, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(edge2, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(edge2, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
|
||||
float2 corner1{4, 4};
|
||||
float2 corner2{2, -3};
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(corner1, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(corner1, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
EXPECT_EQ(-1, isect_point_quad_v2(corner2, quad_cw[0], quad_cw[1], quad_cw[2], quad_cw[3]));
|
||||
EXPECT_EQ(+1, isect_point_quad_v2(corner2, quad_ccw[0], quad_ccw[1], quad_ccw[2], quad_ccw[3]));
|
||||
}
|
||||
|
|
|
@ -194,11 +194,26 @@ class MemoryBuffer {
|
|||
return buffer_ + get_coords_offset(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get buffer element at given coordinates, clamped to border.
|
||||
*/
|
||||
const float *get_elem_clamped(int x, int y) const
|
||||
{
|
||||
const int clamped_x = math::clamp(x, 0, this->get_width() - 1);
|
||||
const int clamped_y = math::clamp(y, 0, this->get_height() - 1);
|
||||
return buffer_ + get_coords_offset(clamped_x, clamped_y);
|
||||
}
|
||||
|
||||
void read_elem(int x, int y, float *out) const
|
||||
{
|
||||
memcpy(out, get_elem(x, y), get_elem_bytes_len());
|
||||
}
|
||||
|
||||
void read_elem_clamped(int x, int y, float *out) const
|
||||
{
|
||||
memcpy(out, get_elem_clamped(x, y), get_elem_bytes_len());
|
||||
}
|
||||
|
||||
void read_elem_checked(int x, int y, float *out) const
|
||||
{
|
||||
if (!has_coords(x, y)) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_hash.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_threads.h"
|
||||
|
@ -591,6 +592,14 @@ class NodeOperation {
|
|||
execute_pixel(result, x, y, chunk_data);
|
||||
}
|
||||
|
||||
inline void read_clamped(float result[4], int x, int y, void *chunk_data)
|
||||
{
|
||||
execute_pixel(result,
|
||||
math::clamp(x, 0, int(this->get_width()) - 1),
|
||||
math::clamp(y, 0, int(this->get_height()) - 1),
|
||||
chunk_data);
|
||||
}
|
||||
|
||||
virtual void *initialize_tile_data(rcti * /*rect*/)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -34,12 +34,7 @@ void BilateralBlurOperation::execute_pixel(float output[4], int x, int y, void *
|
|||
float temp_color[4];
|
||||
float blur_color[4];
|
||||
float blur_divider;
|
||||
float space = space_;
|
||||
float sigmacolor = data_->sigma_color;
|
||||
int minx = floor(x - space);
|
||||
int maxx = ceil(x + space);
|
||||
int miny = floor(y - space);
|
||||
int maxy = ceil(y + space);
|
||||
float delta_color;
|
||||
input_determinator_program_->read(determinator_reference_color, x, y, data);
|
||||
|
||||
|
@ -49,17 +44,17 @@ void BilateralBlurOperation::execute_pixel(float output[4], int x, int y, void *
|
|||
* using gaussian bell for weights. Also sigma_color doesn't seem to be
|
||||
* used correct at all.
|
||||
*/
|
||||
for (int yi = miny; yi < maxy; yi += QualityStepHelper::get_step()) {
|
||||
for (int xi = minx; xi < maxx; xi += QualityStepHelper::get_step()) {
|
||||
for (int yi = -radius_; yi <= radius_; yi += QualityStepHelper::get_step()) {
|
||||
for (int xi = -radius_; xi <= radius_; xi += QualityStepHelper::get_step()) {
|
||||
/* Read determinator. */
|
||||
input_determinator_program_->read(determinator, xi, yi, data);
|
||||
input_determinator_program_->read_clamped(determinator, x + xi, y + yi, data);
|
||||
delta_color = (fabsf(determinator_reference_color[0] - determinator[0]) +
|
||||
fabsf(determinator_reference_color[1] - determinator[1]) +
|
||||
/* Do not take the alpha channel into account. */
|
||||
fabsf(determinator_reference_color[2] - determinator[2]));
|
||||
if (delta_color < sigmacolor) {
|
||||
/* Add this to the blur. */
|
||||
input_color_program_->read(temp_color, xi, yi, data);
|
||||
input_color_program_->read_clamped(temp_color, x + xi, y + yi, data);
|
||||
add_v4_v4(blur_color, temp_color);
|
||||
blur_divider += 1.0f;
|
||||
}
|
||||
|
@ -87,7 +82,7 @@ bool BilateralBlurOperation::determine_depending_area_of_interest(
|
|||
rcti *input, ReadBufferOperation *read_operation, rcti *output)
|
||||
{
|
||||
rcti new_input;
|
||||
int add = ceil(space_) + 1;
|
||||
int add = radius_ + 1;
|
||||
|
||||
new_input.xmax = input->xmax + (add);
|
||||
new_input.xmin = input->xmin - (add);
|
||||
|
@ -101,7 +96,7 @@ void BilateralBlurOperation::get_area_of_interest(const int /*input_idx*/,
|
|||
const rcti &output_area,
|
||||
rcti &r_input_area)
|
||||
{
|
||||
const int add = ceil(space_) + 1;
|
||||
const int add = radius_ + 1;
|
||||
|
||||
r_input_area.xmax = output_area.xmax + (add);
|
||||
r_input_area.xmin = output_area.xmin - (add);
|
||||
|
@ -117,8 +112,9 @@ struct PixelCursor {
|
|||
const float *determ_reference_color;
|
||||
float temp_color[4];
|
||||
float *out;
|
||||
int min_x, max_x;
|
||||
int min_y, max_y;
|
||||
int radius;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
static void blur_pixel(PixelCursor &p)
|
||||
|
@ -130,16 +126,16 @@ static void blur_pixel(PixelCursor &p)
|
|||
* using gaussian bell for weights. Also sigma_color doesn't seem to be
|
||||
* used correct at all.
|
||||
*/
|
||||
for (int yi = p.min_y; yi < p.max_y; yi += p.step) {
|
||||
for (int xi = p.min_x; xi < p.max_x; xi += p.step) {
|
||||
p.input_determinator->read(p.temp_color, xi, yi);
|
||||
for (int yi = -p.radius; yi <= p.radius; yi += p.step) {
|
||||
for (int xi = -p.radius; xi <= p.radius; xi += p.step) {
|
||||
p.input_determinator->read_elem_clamped(p.x + xi, p.y + yi, p.temp_color);
|
||||
/* Do not take the alpha channel into account. */
|
||||
const float delta_color = (fabsf(p.determ_reference_color[0] - p.temp_color[0]) +
|
||||
fabsf(p.determ_reference_color[1] - p.temp_color[1]) +
|
||||
fabsf(p.determ_reference_color[2] - p.temp_color[2]));
|
||||
if (delta_color < p.sigma_color) {
|
||||
/* Add this to the blur. */
|
||||
p.input_color->read(p.temp_color, xi, yi);
|
||||
p.input_color->read_elem_clamped(p.x + xi, p.y + yi, p.temp_color);
|
||||
add_v4_v4(p.out, p.temp_color);
|
||||
blur_divider += 1.0f;
|
||||
}
|
||||
|
@ -161,22 +157,17 @@ void BilateralBlurOperation::update_memory_buffer_partial(MemoryBuffer *output,
|
|||
PixelCursor p = {};
|
||||
p.step = QualityStepHelper::get_step();
|
||||
p.sigma_color = data_->sigma_color;
|
||||
p.radius = radius_;
|
||||
p.input_color = inputs[0];
|
||||
p.input_determinator = inputs[1];
|
||||
const float space = space_;
|
||||
for (int y = area.ymin; y < area.ymax; y++) {
|
||||
p.out = output->get_elem(area.xmin, y);
|
||||
/* This will be used as the reference color for the determinator. */
|
||||
p.determ_reference_color = p.input_determinator->get_elem(area.xmin, y);
|
||||
p.min_y = floor(y - space);
|
||||
p.max_y = ceil(y + space);
|
||||
p.y = y;
|
||||
for (int x = area.xmin; x < area.xmax; x++) {
|
||||
p.min_x = floor(x - space);
|
||||
p.max_x = ceil(x + space);
|
||||
|
||||
p.x = x;
|
||||
/* This will be used as the reference color for the determinator. */
|
||||
p.determ_reference_color = p.input_determinator->get_elem(x, y);
|
||||
blur_pixel(p);
|
||||
|
||||
p.determ_reference_color += p.input_determinator->elem_stride;
|
||||
p.out += output->elem_stride;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_math_base.hh"
|
||||
|
||||
#include "COM_MultiThreadedOperation.h"
|
||||
#include "COM_QualityStepHelper.h"
|
||||
|
||||
|
@ -14,7 +16,7 @@ class BilateralBlurOperation : public MultiThreadedOperation, public QualityStep
|
|||
SocketReader *input_color_program_;
|
||||
SocketReader *input_determinator_program_;
|
||||
NodeBilateralBlurData *data_;
|
||||
float space_;
|
||||
int radius_;
|
||||
|
||||
public:
|
||||
BilateralBlurOperation();
|
||||
|
@ -41,7 +43,7 @@ class BilateralBlurOperation : public MultiThreadedOperation, public QualityStep
|
|||
void set_data(NodeBilateralBlurData *data)
|
||||
{
|
||||
data_ = data;
|
||||
space_ = data->sigma_space + data->iter;
|
||||
radius_ = int(math::ceil(data->sigma_space + data->iter));
|
||||
}
|
||||
|
||||
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
|
||||
|
|
|
@ -419,6 +419,8 @@ static bool bone_collection_assign_poll(bContext *C)
|
|||
return false;
|
||||
}
|
||||
|
||||
CTX_wm_operator_poll_msg_set(C, "Linked bone collections are not editable");
|
||||
|
||||
/* The target bone collection can be specified by name in an operator property, but that's not
|
||||
* available here. So just allow in the poll function, and do the final check in the execute. */
|
||||
return true;
|
||||
|
@ -1004,6 +1006,8 @@ static bool move_to_collection_poll(bContext *C)
|
|||
return false;
|
||||
}
|
||||
|
||||
CTX_wm_operator_poll_msg_set(C, "Linked bone collections are not editable");
|
||||
|
||||
/* Ideally this would also check the target bone collection to move/assign to.
|
||||
* However, that requires access to the operator properties, and those are not
|
||||
* available in the poll function. */
|
||||
|
@ -1134,7 +1138,6 @@ static void move_to_collection_menu_create(bContext *C, uiLayout *layout, void *
|
|||
uiLayout *sub = uiLayoutRow(layout, false);
|
||||
uiLayoutSetEnabled(sub, false);
|
||||
|
||||
/* TODO: figure out if we can add a 'disabled' message in the tooltip. */
|
||||
menu_add_item_for_move_assign_unassign(sub, arm, bcoll, index, is_move_operation);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ set(INC
|
|||
../../render
|
||||
../../windowmanager
|
||||
../../../../intern/ghost
|
||||
../../../../extern/fmtlib/include
|
||||
../../bmesh
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -103,6 +102,7 @@ set(LIB
|
|||
PRIVATE bf::depsgraph
|
||||
PRIVATE bf::dna
|
||||
bf_editor_datafiles
|
||||
PRIVATE bf::extern::fmtlib
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::animrig
|
||||
)
|
||||
|
|
|
@ -131,8 +131,8 @@ class BoneCollectionDropTarget : public TreeViewItemDropTarget {
|
|||
const BoneCollection &drag_bcoll = drag_bone_collection->bcoll();
|
||||
const BoneCollection &drop_bcoll = drop_bonecoll_.bcoll();
|
||||
|
||||
std::string_view drag_name = drag_bcoll.name;
|
||||
std::string_view drop_name = drop_bcoll.name;
|
||||
const StringRef drag_name = drag_bcoll.name;
|
||||
const StringRef drop_name = drop_bcoll.name;
|
||||
|
||||
switch (drag_info.drop_location) {
|
||||
case DropLocation::Into:
|
||||
|
|
|
@ -60,8 +60,8 @@ class LayerNodeDropTarget : public TreeViewItemDropTarget {
|
|||
static_cast<const wmDragGreasePencilLayer *>(drag_info.drag_data.poin);
|
||||
Layer &drag_layer = drag_grease_pencil->layer->wrap();
|
||||
|
||||
std::string_view drag_name = drag_layer.name();
|
||||
std::string_view drop_name = drop_tree_node_.name();
|
||||
const StringRef drag_name = drag_layer.name();
|
||||
const StringRef drop_name = drop_tree_node_.name();
|
||||
|
||||
switch (drag_info.drop_location) {
|
||||
case DropLocation::Into:
|
||||
|
|
|
@ -133,7 +133,7 @@ class ReorderCollectionDropTarget : public TreeViewItemDropTarget {
|
|||
|
||||
std::string drop_tooltip(const DragInfo &drag) const override
|
||||
{
|
||||
const std::string_view drop_name = std::string_view(drop_id_.name + 2);
|
||||
const StringRef drop_name = drop_id_.name + 2;
|
||||
|
||||
switch (drag.drop_location) {
|
||||
case DropLocation::Into:
|
||||
|
|
|
@ -19,7 +19,6 @@ set(INC
|
|||
../../render
|
||||
../../shader_fx
|
||||
../../windowmanager
|
||||
../../../../extern/fmtlib/include
|
||||
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -69,6 +68,7 @@ set(LIB
|
|||
PRIVATE bf::dna
|
||||
bf_editor_mesh
|
||||
bf_editor_grease_pencil
|
||||
PRIVATE bf::extern::fmtlib
|
||||
PRIVATE bf::intern::clog
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
bf_render
|
||||
|
|
|
@ -318,19 +318,13 @@ static void bake_geometry_nodes_startjob(void *customdata, wmJobWorkerStatus *wo
|
|||
|
||||
const bake::BakePath path = request.path;
|
||||
|
||||
const std::string blob_file_name = frame_file_name + ".blob";
|
||||
|
||||
char blob_path[FILE_MAX];
|
||||
BLI_path_join(blob_path, sizeof(blob_path), path.blobs_dir.c_str(), blob_file_name.c_str());
|
||||
char meta_path[FILE_MAX];
|
||||
BLI_path_join(meta_path,
|
||||
sizeof(meta_path),
|
||||
path.meta_dir.c_str(),
|
||||
(frame_file_name + ".json").c_str());
|
||||
BLI_file_ensure_parent_dir_exists(meta_path);
|
||||
BLI_file_ensure_parent_dir_exists(blob_path);
|
||||
fstream blob_file{blob_path, std::ios::out | std::ios::binary};
|
||||
bake::DiskBlobWriter blob_writer{blob_file_name, blob_file, 0};
|
||||
bake::DiskBlobWriter blob_writer{path.blobs_dir, frame_file_name};
|
||||
fstream meta_file{meta_path, std::ios::out};
|
||||
bake::serialize_bake(frame_cache.state, blob_writer, *request.blob_sharing, meta_file);
|
||||
}
|
||||
|
|
|
@ -920,7 +920,8 @@ PaintStroke *paint_stroke_new(bContext *C,
|
|||
ups->colorspace = nullptr;
|
||||
|
||||
if (br->mtex.tex && br->mtex.tex->type == TEX_IMAGE && br->mtex.tex->ima) {
|
||||
ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(br->mtex.tex->ima, &br->mtex.tex->iuser, NULL);
|
||||
ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(
|
||||
br->mtex.tex->ima, &br->mtex.tex->iuser, nullptr);
|
||||
if (tex_ibuf && tex_ibuf->float_buffer.data == nullptr) {
|
||||
ups->do_linear_conversion = true;
|
||||
ups->colorspace = tex_ibuf->byte_buffer.colorspace;
|
||||
|
|
|
@ -865,7 +865,7 @@ static void action_main_region_view2d_changed(const bContext * /*C*/, ARegion *r
|
|||
|
||||
void ED_spacetype_action()
|
||||
{
|
||||
SpaceType *st = MEM_cnew<SpaceType>("spacetype action");
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_ACTION;
|
||||
|
@ -942,7 +942,7 @@ void ED_spacetype_action()
|
|||
art = ED_area_type_hud(st->spaceid);
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -136,8 +136,7 @@ void ED_spacetypes_init()
|
|||
ED_gizmotypes_snap_3d();
|
||||
|
||||
/* Register types for operators and gizmos. */
|
||||
const ListBase *spacetypes = BKE_spacetypes_list();
|
||||
LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
|
||||
for (const std::unique_ptr<SpaceType> &type : BKE_spacetypes_list()) {
|
||||
/* Initialize gizmo types first, operator types need them. */
|
||||
if (type->gizmos) {
|
||||
type->gizmos();
|
||||
|
@ -173,8 +172,7 @@ void ED_spacemacros_init()
|
|||
|
||||
/* Register dropboxes (can use macros). */
|
||||
ED_dropboxes_ui();
|
||||
const ListBase *spacetypes = BKE_spacetypes_list();
|
||||
LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
|
||||
for (const std::unique_ptr<SpaceType> &type : BKE_spacetypes_list()) {
|
||||
if (type->dropboxes) {
|
||||
type->dropboxes();
|
||||
}
|
||||
|
@ -207,8 +205,7 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf)
|
|||
|
||||
ED_keymap_transform(keyconf);
|
||||
|
||||
const ListBase *spacetypes = BKE_spacetypes_list();
|
||||
LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
|
||||
for (const std::unique_ptr<SpaceType> &type : BKE_spacetypes_list()) {
|
||||
if (type->keymap) {
|
||||
type->keymap(keyconf);
|
||||
}
|
||||
|
@ -292,61 +289,3 @@ void ED_region_draw_cb_remove_by_type(ARegionType *art, void *draw_fn, void (*fr
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ********************* space template *********************** */
|
||||
/* forward declare */
|
||||
void ED_spacetype_xxx();
|
||||
|
||||
/* allocate and init some vars */
|
||||
static SpaceLink *xxx_create(const ScrArea * /*area*/, const Scene * /*scene*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Doesn't free the space-link itself. */
|
||||
static void xxx_free(SpaceLink * /*sl*/) {}
|
||||
|
||||
/* spacetype; init callback for usage, should be re-doable. */
|
||||
static void xxx_init(wmWindowManager * /*wm*/, ScrArea * /*area*/)
|
||||
{
|
||||
|
||||
/* link area to SpaceXXX struct */
|
||||
|
||||
/* define how many regions, the order and types */
|
||||
|
||||
/* add types to regions */
|
||||
}
|
||||
|
||||
static SpaceLink *xxx_duplicate(SpaceLink * /*sl*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void xxx_operatortypes()
|
||||
{
|
||||
/* register operator types for this space */
|
||||
}
|
||||
|
||||
static void xxx_keymap(wmKeyConfig * /*keyconf*/)
|
||||
{
|
||||
/* add default items to keymap */
|
||||
}
|
||||
|
||||
/* only called once, from screen/spacetypes.cc */
|
||||
void ED_spacetype_xxx()
|
||||
{
|
||||
static SpaceType st;
|
||||
|
||||
st.spaceid = SPACE_VIEW3D;
|
||||
|
||||
st.create = xxx_create;
|
||||
st.free = xxx_free;
|
||||
st.init = xxx_init;
|
||||
st.duplicate = xxx_duplicate;
|
||||
st.operatortypes = xxx_operatortypes;
|
||||
st.keymap = xxx_keymap;
|
||||
|
||||
BKE_spacetype_register(&st);
|
||||
}
|
||||
|
||||
/* ****************************** end template *********************** */
|
||||
|
|
|
@ -971,7 +971,7 @@ static void buttons_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_buttons()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype buttons"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_PROPERTIES;
|
||||
|
@ -1048,7 +1048,7 @@ void ED_spacetype_buttons()
|
|||
art->message_subscribe = buttons_navigation_bar_region_message_subscribe;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -1199,7 +1199,7 @@ static void clip_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_clip()
|
||||
{
|
||||
SpaceType *st = MEM_cnew<SpaceType>("spacetype clip");
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_CLIP;
|
||||
|
@ -1281,8 +1281,6 @@ void ED_spacetype_clip()
|
|||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
|
||||
/* channels */
|
||||
art = MEM_cnew<ARegionType>("spacetype clip channels region");
|
||||
art->regionid = RGN_TYPE_CHANNELS;
|
||||
|
@ -1298,6 +1296,8 @@ void ED_spacetype_clip()
|
|||
/* regions: hud */
|
||||
art = ED_area_type_hud(st->spaceid);
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -324,7 +324,7 @@ static void console_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_console()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype console"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_CONSOLE;
|
||||
|
@ -364,5 +364,5 @@ void ED_spacetype_console()
|
|||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ set(INC
|
|||
../../makesrna
|
||||
../../render
|
||||
../../windowmanager
|
||||
../../../../extern/fmtlib/include
|
||||
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -50,7 +49,7 @@ set(LIB
|
|||
PRIVATE bf::blenlib
|
||||
PRIVATE bf::dna
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
PRIVATE bf::intern::atomic
|
||||
)
|
||||
|
||||
|
|
|
@ -406,9 +406,8 @@ std::string AssetCatalogDropTarget::drop_tooltip_asset_catalog(const wmDrag &dra
|
|||
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||
const AssetCatalog *src_catalog = get_drag_catalog(drag, get_asset_library());
|
||||
|
||||
return fmt::format(TIP_("Move catalog {} into {}"),
|
||||
std::string_view(src_catalog->path.name()),
|
||||
std::string_view(catalog_item_.get_name()));
|
||||
return fmt::format(
|
||||
TIP_("Move catalog {} into {}"), src_catalog->path.name(), catalog_item_.get_name());
|
||||
}
|
||||
|
||||
std::string AssetCatalogDropTarget::drop_tooltip_asset_list(const wmDrag &drag) const
|
||||
|
@ -623,7 +622,7 @@ std::string AssetCatalogTreeViewAllItem::DropTarget::drop_tooltip(
|
|||
drag_info.drag_data, *get_view<AssetCatalogTreeView>().asset_library_);
|
||||
|
||||
return fmt::format(TIP_("Move catalog {} to the top level of the tree"),
|
||||
std::string_view(drag_catalog->path.name()));
|
||||
drag_catalog->path.name());
|
||||
}
|
||||
|
||||
bool AssetCatalogTreeViewAllItem::DropTarget::on_drop(bContext * /*C*/,
|
||||
|
|
|
@ -905,7 +905,7 @@ static void file_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_file()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype file"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_FILE;
|
||||
|
@ -999,7 +999,7 @@ void ED_spacetype_file()
|
|||
file_tool_props_region_panels_register(art);
|
||||
file_external_operations_menu_register();
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
||||
void ED_file_init()
|
||||
|
|
|
@ -874,7 +874,7 @@ static void graph_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_ipo()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype ipo"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_GRAPH;
|
||||
|
@ -949,5 +949,5 @@ void ED_spacetype_ipo()
|
|||
art = ED_area_type_hud(st->spaceid);
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -1102,7 +1102,7 @@ static void image_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_image()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype image"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_IMAGE;
|
||||
|
@ -1192,5 +1192,5 @@ void ED_spacetype_image()
|
|||
art = ED_area_type_hud(st->spaceid);
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ static void info_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_info()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype info"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_INFO;
|
||||
|
@ -294,5 +294,5 @@ void ED_spacetype_info()
|
|||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -598,7 +598,7 @@ static void nla_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_nla()
|
||||
{
|
||||
SpaceType *st = MEM_cnew<SpaceType>("spacetype nla");
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_NLA;
|
||||
|
@ -670,5 +670,5 @@ void ED_spacetype_nla()
|
|||
art = ED_area_type_hud(st->spaceid);
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ set(INC
|
|||
../../nodes
|
||||
../../render
|
||||
../../windowmanager
|
||||
../../../../extern/fmtlib/include
|
||||
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -58,7 +57,7 @@ set(LIB
|
|||
PRIVATE bf::dna
|
||||
bf_editor_screen
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
)
|
||||
|
||||
if(WITH_COMPOSITOR_CPU)
|
||||
|
|
|
@ -2524,7 +2524,7 @@ static std::string named_attribute_tooltip(bContext * /*C*/, void *argN, const c
|
|||
for (const NameWithUsage &attribute : sorted_used_attribute) {
|
||||
const StringRefNull name = attribute.name;
|
||||
const geo_log::NamedAttributeUsage usage = attribute.usage;
|
||||
ss << fmt::format(TIP_(" \u2022 \"{}\": "), std::string_view(name));
|
||||
ss << fmt::format(TIP_(" \u2022 \"{}\": "), name);
|
||||
Vector<std::string> usages;
|
||||
if ((usage & geo_log::NamedAttributeUsage::Read) != geo_log::NamedAttributeUsage::None) {
|
||||
usages.append(TIP_("read"));
|
||||
|
|
|
@ -1399,7 +1399,7 @@ void ED_spacetype_node()
|
|||
{
|
||||
using namespace blender::ed::space_node;
|
||||
|
||||
SpaceType *st = MEM_cnew<SpaceType>("spacetype node");
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_NODE;
|
||||
|
@ -1480,5 +1480,5 @@ void ED_spacetype_node()
|
|||
WM_menutype_add(MEM_new<MenuType>(__func__, add_unassigned_assets_menu_type()));
|
||||
WM_menutype_add(MEM_new<MenuType>(__func__, add_root_catalogs_menu_type()));
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -616,7 +616,7 @@ void ED_spacetype_outliner()
|
|||
{
|
||||
using namespace blender::ed::outliner;
|
||||
|
||||
SpaceType *st = MEM_cnew<SpaceType>("spacetype time");
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_OUTLINER;
|
||||
|
@ -661,5 +661,5 @@ void ED_spacetype_outliner()
|
|||
art->listener = outliner_header_region_listener;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ static void script_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_script()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype script"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_SCRIPT;
|
||||
|
@ -210,5 +210,5 @@ void ED_spacetype_script()
|
|||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -631,28 +631,116 @@ static void draw_waveform_graticule(ARegion *region, SeqQuadsBatch &quads, const
|
|||
UI_view2d_text_cache_draw(region);
|
||||
}
|
||||
|
||||
static void draw_vectorscope_graticule(SeqQuadsBatch &quads, const rctf &area)
|
||||
static void draw_vectorscope_graticule(ARegion *region, SeqQuadsBatch &quads, const rctf &area)
|
||||
{
|
||||
using namespace blender;
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
|
||||
|
||||
const float w = BLI_rctf_size_x(&area);
|
||||
const float h = BLI_rctf_size_y(&area);
|
||||
const float centerx = BLI_rctf_cent_x(&area);
|
||||
const float centery = BLI_rctf_cent_y(&area);
|
||||
const float rad_base = ((w < h) ? w : h) * 0.5f;
|
||||
/* vectorscope image is scaled over YUV range, +/- (0.436, 0.615) */
|
||||
const float rad_x = rad_base * (0.5f / 0.436f);
|
||||
const float rad_y = rad_base * (0.5f / 0.615f);
|
||||
const float2 center{BLI_rctf_cent_x(&area), BLI_rctf_cent_y(&area)};
|
||||
/* Vectorscope image is scaled over UV range (+/-0.615). */
|
||||
const float radius = ((w < h) ? w : h) * 0.5f * (0.5f / 0.615f);
|
||||
|
||||
/* center cross */
|
||||
uchar col_grid[4] = {128, 128, 128, 96};
|
||||
quads.add_line(centerx - rad_base * 0.1f, centery, centerx + rad_base * 0.1f, centery, col_grid);
|
||||
quads.add_line(centerx, centery - rad_base * 0.1f, centerx, centery + rad_base * 0.1f, col_grid);
|
||||
/* Precalculate circle points/colors. */
|
||||
constexpr int circle_delta = 6;
|
||||
constexpr int num_circle_points = 360 / circle_delta;
|
||||
float2 circle_pos[num_circle_points];
|
||||
float3 circle_col[num_circle_points];
|
||||
for (int i = 0; i < num_circle_points; i++) {
|
||||
float a = DEG2RADF(i * circle_delta);
|
||||
float u = cosf(a);
|
||||
float v = sinf(a);
|
||||
circle_pos[i] = float2(u, v);
|
||||
|
||||
/* fully saturated vs "safe" (0.75) colored areas */
|
||||
float3 col;
|
||||
yuv_to_rgb(0.5f, u, v, &col.x, &col.y, &col.z, BLI_YUV_ITU_BT709);
|
||||
circle_col[i] = col;
|
||||
}
|
||||
|
||||
/* Draw colored background and outer ring, additively blended
|
||||
* since vectorscope image is already drawn. */
|
||||
GPU_blend(GPU_BLEND_ADDITIVE);
|
||||
|
||||
constexpr float alpha_f = 0.8f;
|
||||
constexpr uchar alpha_b = uchar(alpha_f * 255.0f);
|
||||
const uchar4 col_center(50, 50, 50, alpha_b);
|
||||
|
||||
uchar4 col1(0, 0, 0, alpha_b);
|
||||
uchar4 col2(0, 0, 0, alpha_b);
|
||||
uchar4 col3(0, 0, 0, alpha_b);
|
||||
|
||||
/* Background: since the quads batch utility draws quads, draw two
|
||||
* segments of the circle (two triangles) in one iteration. */
|
||||
constexpr float mul_background = 0.2f;
|
||||
for (int i = 0; i < num_circle_points; i += 2) {
|
||||
int idx1 = i;
|
||||
int idx2 = (i + 1) % num_circle_points;
|
||||
int idx3 = (i + 2) % num_circle_points;
|
||||
float2 pt1 = center + circle_pos[idx1] * radius;
|
||||
float2 pt2 = center + circle_pos[idx2] * radius;
|
||||
float2 pt3 = center + circle_pos[idx3] * radius;
|
||||
float3 rgb1 = circle_col[idx1] * mul_background;
|
||||
float3 rgb2 = circle_col[idx2] * mul_background;
|
||||
float3 rgb3 = circle_col[idx3] * mul_background;
|
||||
rgb_float_to_uchar(col1, rgb1);
|
||||
rgb_float_to_uchar(col2, rgb2);
|
||||
rgb_float_to_uchar(col3, rgb3);
|
||||
quads.add_quad(pt1.x,
|
||||
pt1.y,
|
||||
pt2.x,
|
||||
pt2.y,
|
||||
center.x,
|
||||
center.y,
|
||||
pt3.x,
|
||||
pt3.y,
|
||||
col1,
|
||||
col2,
|
||||
col_center,
|
||||
col3);
|
||||
}
|
||||
|
||||
/* Outer ring. */
|
||||
const float outer_radius = radius * 1.02f;
|
||||
for (int i = 0; i < num_circle_points; i++) {
|
||||
int idx1 = i;
|
||||
int idx2 = (i + 1) % num_circle_points;
|
||||
float2 pt1a = center + circle_pos[idx1] * radius;
|
||||
float2 pt2a = center + circle_pos[idx2] * radius;
|
||||
float2 pt1b = center + circle_pos[idx1] * outer_radius;
|
||||
float2 pt2b = center + circle_pos[idx2] * outer_radius;
|
||||
float3 rgb1 = circle_col[idx1];
|
||||
float3 rgb2 = circle_col[idx2];
|
||||
rgb_float_to_uchar(col1, rgb1);
|
||||
rgb_float_to_uchar(col2, rgb2);
|
||||
quads.add_quad(
|
||||
pt1a.x, pt1a.y, pt1b.x, pt1b.y, pt2a.x, pt2a.y, pt2b.x, pt2b.y, col1, col1, col2, col2);
|
||||
}
|
||||
|
||||
quads.draw();
|
||||
|
||||
/* Draw grid and other labels using regular alpha blending. */
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
const uchar4 col_grid(128, 128, 128, 128);
|
||||
|
||||
/* Cross. */
|
||||
quads.add_line(center.x - radius, center.y, center.x + radius, center.y, col_grid);
|
||||
quads.add_line(center.x, center.y - radius, center.x, center.y + radius, col_grid);
|
||||
|
||||
/* Inner circles. */
|
||||
for (int j = 1; j < 5; j++) {
|
||||
float r = radius * j * 0.2f;
|
||||
for (int i = 0; i < num_circle_points; i++) {
|
||||
int idx1 = i;
|
||||
int idx2 = (i + 1) % num_circle_points;
|
||||
float2 pt1 = center + circle_pos[idx1] * r;
|
||||
float2 pt2 = center + circle_pos[idx2] * r;
|
||||
quads.add_line(pt1.x, pt1.y, pt2.x, pt2.y, col_grid);
|
||||
}
|
||||
}
|
||||
|
||||
/* "Safe" (0.75 saturation) primary color locations and labels. */
|
||||
const float3 primaries[6] = {
|
||||
{1, 0, 0},
|
||||
{1, 1, 0},
|
||||
|
@ -661,35 +749,43 @@ static void draw_vectorscope_graticule(SeqQuadsBatch &quads, const rctf &area)
|
|||
{0, 0, 1},
|
||||
{1, 0, 1},
|
||||
};
|
||||
float2 center{centerx, centery};
|
||||
float2 rad_scale{rad_x * 2, rad_y * 2};
|
||||
const char *names = "RYGCBM";
|
||||
|
||||
/* Calculate size of single text letter. */
|
||||
char buf[2] = {'M', 0};
|
||||
float text_scale_x, text_scale_y;
|
||||
UI_view2d_scale_get_inverse(®ion->v2d, &text_scale_x, &text_scale_y);
|
||||
float text_width, text_height;
|
||||
BLF_width_and_height(BLF_default(), buf, 1, &text_width, &text_height);
|
||||
text_width *= text_scale_x;
|
||||
text_height *= text_scale_y;
|
||||
|
||||
const uchar4 col_target(128, 128, 128, 192);
|
||||
const float delta = radius * 0.01f;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
float3 prim0 = primaries[i];
|
||||
float3 prim1 = primaries[(i + 1) % 6];
|
||||
float3 safe0 = prim0 * 0.75f;
|
||||
float3 safe1 = prim1 * 0.75f;
|
||||
float2 uv0 = center + rgb_to_uv(prim0) * rad_scale;
|
||||
float2 uv1 = center + rgb_to_uv(prim1) * rad_scale;
|
||||
float2 uv2 = center + rgb_to_uv(safe0) * rad_scale;
|
||||
float2 uv3 = center + rgb_to_uv(safe1) * rad_scale;
|
||||
uchar col0[4] = {uchar(prim0.x * 255), uchar(prim0.y * 255), uchar(prim0.z * 255), 64};
|
||||
uchar col1[4] = {uchar(prim1.x * 255), uchar(prim1.y * 255), uchar(prim1.z * 255), 64};
|
||||
uchar col2[4] = {uchar(safe0.x * 255), uchar(safe0.y * 255), uchar(safe0.z * 255), 64};
|
||||
uchar col3[4] = {uchar(safe1.x * 255), uchar(safe1.y * 255), uchar(safe1.z * 255), 64};
|
||||
quads.add_quad(uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y, uv3.x, uv3.y, col0, col1, col2, col3);
|
||||
col0[3] = col1[3] = col2[3] = col3[3] = 192;
|
||||
quads.add_line(uv0.x, uv0.y, uv1.x, uv1.y, col0, col1);
|
||||
quads.add_line(uv2.x, uv2.y, uv3.x, uv3.y, col2, col3);
|
||||
float3 safe = primaries[i] * 0.75f;
|
||||
float2 pos = center + rgb_to_uv(safe) * (radius * 2);
|
||||
quads.add_wire_quad(pos.x - delta, pos.y - delta, pos.x + delta, pos.y + delta, col_target);
|
||||
|
||||
buf[0] = names[i];
|
||||
UI_view2d_text_cache_add(®ion->v2d,
|
||||
pos.x + delta * 1.2f + text_width / 4,
|
||||
pos.y - text_height / 2,
|
||||
buf,
|
||||
1,
|
||||
col_target);
|
||||
}
|
||||
|
||||
/* skin tone line */
|
||||
uchar col_tone[4] = {255, 102, 0, 128};
|
||||
const float tone_line_len = 0.895f; /* makes it end at outer edge of saturation ring. */
|
||||
quads.add_line(centerx,
|
||||
centery,
|
||||
centerx + cosf(skin_rad) * rad_x * tone_line_len,
|
||||
centery + sinf(skin_rad) * rad_y * tone_line_len,
|
||||
/* Skin tone line. */
|
||||
const uchar4 col_tone(255, 102, 0, 128);
|
||||
quads.add_line(center.x,
|
||||
center.y,
|
||||
center.x + cosf(skin_rad) * radius,
|
||||
center.y + sinf(skin_rad) * radius,
|
||||
col_tone);
|
||||
|
||||
quads.draw();
|
||||
UI_view2d_text_cache_draw(region);
|
||||
}
|
||||
|
||||
static void sequencer_draw_scopes(Scene *scene, ARegion *region, SpaceSeq *sseq)
|
||||
|
@ -794,7 +890,7 @@ static void sequencer_draw_scopes(Scene *scene, ARegion *region, SpaceSeq *sseq)
|
|||
}
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_VECTORSCOPE) {
|
||||
use_blend = true;
|
||||
draw_vectorscope_graticule(quads, preview);
|
||||
draw_vectorscope_graticule(region, quads, preview);
|
||||
}
|
||||
|
||||
quads.draw();
|
||||
|
|
|
@ -64,8 +64,8 @@ static blender::float2 rgb_to_uv_normalized(const float rgb[3])
|
|||
float u = -0.09991f * r - 0.33609f * g + 0.436f * b;
|
||||
float v = 0.615f * r - 0.55861f * g - 0.05639f * b;
|
||||
|
||||
/* Normalize: (U, V) range is +/- (0.436, 0.615) */
|
||||
u = clamp_f(u * (0.5f / 0.436f) + 0.5f, 0.0f, 1.0f);
|
||||
/* Normalize: possible range is +/- 0.615. */
|
||||
u = clamp_f(u * (0.5f / 0.615f) + 0.5f, 0.0f, 1.0f);
|
||||
v = clamp_f(v * (0.5f / 0.615f) + 0.5f, 0.0f, 1.0f);
|
||||
return float2(u, v);
|
||||
}
|
||||
|
|
|
@ -974,7 +974,7 @@ static void sequencer_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_sequencer()
|
||||
{
|
||||
SpaceType *st = MEM_cnew<SpaceType>("spacetype sequencer");
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_SEQ;
|
||||
|
@ -1088,7 +1088,7 @@ void ED_spacetype_sequencer()
|
|||
art = ED_area_type_hud(st->spaceid);
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
|
||||
/* Set the sequencer callback when not in background mode. */
|
||||
if (G.background == 0) {
|
||||
|
|
|
@ -13,7 +13,6 @@ set(INC
|
|||
../../makesrna
|
||||
../../nodes
|
||||
../../windowmanager
|
||||
../../../../extern/fmtlib/include
|
||||
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -54,6 +53,7 @@ set(LIB
|
|||
PRIVATE bf::blenlib
|
||||
PRIVATE bf::depsgraph
|
||||
PRIVATE bf::dna
|
||||
PRIVATE bf::extern::fmtlib
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
)
|
||||
|
||||
|
|
|
@ -718,7 +718,7 @@ static void spreadsheet_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void register_spacetype()
|
||||
{
|
||||
SpaceType *st = MEM_cnew<SpaceType>("spacetype spreadsheet");
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_SPREADSHEET;
|
||||
|
@ -803,7 +803,7 @@ void register_spacetype()
|
|||
spreadsheet_data_set_region_panels_register(*art);
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
||||
} // namespace blender::ed::spreadsheet
|
||||
|
|
|
@ -132,7 +132,7 @@ static void statusbar_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_statusbar()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(*st), "spacetype statusbar"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_STATUSBAR;
|
||||
|
@ -159,5 +159,5 @@ void ED_spacetype_statusbar()
|
|||
art->message_subscribe = statusbar_header_region_message_subscribe;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -405,7 +405,7 @@ static void text_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_text()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype text"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_TEXT;
|
||||
|
@ -465,7 +465,7 @@ void ED_spacetype_text()
|
|||
art->draw = text_header_region_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
|
||||
/* register formatters */
|
||||
ED_text_format_register_py();
|
||||
|
|
|
@ -4107,6 +4107,9 @@ static int text_jump_to_file_at_point_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Useful to copy-paste from the terminal. */
|
||||
printf("%s:%d:%d\n", filepath, line_index + 1, column_index);
|
||||
|
||||
bool success;
|
||||
if (U.text_editor[0] != '\0') {
|
||||
success = text_jump_to_file_at_point_external(
|
||||
|
|
|
@ -277,7 +277,7 @@ static void topbar_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_topbar()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype topbar"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_TOPBAR;
|
||||
|
@ -322,5 +322,5 @@ void ED_spacetype_topbar()
|
|||
recent_files_menu_register();
|
||||
undo_history_menu_register();
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ set(INC
|
|||
../../blentranslation
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../extern/fmtlib/include
|
||||
|
||||
)
|
||||
|
||||
|
@ -27,6 +26,7 @@ set(SRC
|
|||
set(LIB
|
||||
PRIVATE bf::blenlib
|
||||
PRIVATE bf::dna
|
||||
PRIVATE bf::extern::fmtlib
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
)
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ static void userpref_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
|
||||
void ED_spacetype_userpref()
|
||||
{
|
||||
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype userpref"));
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_USERPREF;
|
||||
|
@ -246,5 +246,5 @@ void ED_spacetype_userpref()
|
|||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -243,7 +243,7 @@ static void PREFERENCES_OT_asset_library_remove(wmOperatorType *ot)
|
|||
* \{ */
|
||||
|
||||
enum class bUserExtensionRepoAddType {
|
||||
Online = 0,
|
||||
Remote = 0,
|
||||
Local = 1,
|
||||
};
|
||||
|
||||
|
@ -274,7 +274,7 @@ static int preferences_extension_repo_add_exec(bContext *C, wmOperator *op)
|
|||
new_repo->flag |= USER_EXTENSION_REPO_FLAG_USE_CUSTOM_DIRECTORY;
|
||||
}
|
||||
|
||||
if (repo_type == bUserExtensionRepoAddType::Online) {
|
||||
if (repo_type == bUserExtensionRepoAddType::Remote) {
|
||||
RNA_string_get(op->ptr, "remote_path", new_repo->remote_path);
|
||||
new_repo->flag |= USER_EXTENSION_REPO_FLAG_USE_REMOTE_PATH;
|
||||
}
|
||||
|
@ -298,8 +298,8 @@ static int preferences_extension_repo_add_invoke(bContext *C, wmOperator *op, co
|
|||
PropertyRNA *prop_name = RNA_struct_find_property(op->ptr, "name");
|
||||
if (!RNA_property_is_set(op->ptr, prop_name)) {
|
||||
const char *name_default = nullptr;
|
||||
if (repo_type == bUserExtensionRepoAddType::Online) {
|
||||
name_default = "Online Repository";
|
||||
if (repo_type == bUserExtensionRepoAddType::Remote) {
|
||||
name_default = "Remote Repository";
|
||||
}
|
||||
else {
|
||||
name_default = "User Repository";
|
||||
|
@ -321,7 +321,7 @@ static bool preferences_extension_repo_add_poll_property(const bContext * /*C*/,
|
|||
|
||||
/* Only show remote_path for remote repositories. */
|
||||
if (STREQ(prop_id, "remote_path")) {
|
||||
if (repo_type != bUserExtensionRepoAddType::Online) {
|
||||
if (repo_type != bUserExtensionRepoAddType::Remote) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -349,10 +349,10 @@ static void PREFERENCES_OT_extension_repo_add(wmOperatorType *ot)
|
|||
ot->flag = OPTYPE_INTERNAL | OPTYPE_REGISTER;
|
||||
|
||||
static const EnumPropertyItem repo_type_items[] = {
|
||||
{int(bUserExtensionRepoAddType::Online),
|
||||
"ONLINE",
|
||||
{int(bUserExtensionRepoAddType::Remote),
|
||||
"REMOTE",
|
||||
ICON_WORLD,
|
||||
"Add Online Repository",
|
||||
"Add Remote Repository",
|
||||
"Add a repository referencing an remote repository "
|
||||
"with support for listing and updating extensions"},
|
||||
{int(bUserExtensionRepoAddType::Local),
|
||||
|
|
|
@ -2107,7 +2107,7 @@ static void view3d_space_blend_write(BlendWriter *writer, SpaceLink *sl)
|
|||
void ED_spacetype_view3d()
|
||||
{
|
||||
using namespace blender::ed;
|
||||
SpaceType *st = MEM_cnew<SpaceType>("spacetype view3d");
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
ARegionType *art;
|
||||
|
||||
st->spaceid = SPACE_VIEW3D;
|
||||
|
@ -2237,5 +2237,5 @@ void ED_spacetype_view3d()
|
|||
WM_menutype_add(MEM_new<MenuType>(
|
||||
__func__, blender::ed::geometry::node_group_operator_assets_menu_unassigned()));
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
BKE_spacetype_register(std::move(st));
|
||||
}
|
||||
|
|
|
@ -207,8 +207,8 @@ static void WIDGETGROUP_navigate_setup(const bContext *C, wmGizmoGroup *gzgroup)
|
|||
}
|
||||
|
||||
wmOperatorType *ot = WM_operatortype_find(info->opname, true);
|
||||
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot, NULL);
|
||||
if (info->op_prop_fn != NULL) {
|
||||
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot, nullptr);
|
||||
if (info->op_prop_fn != nullptr) {
|
||||
info->op_prop_fn(ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ set(INC
|
|||
|
||||
set(INC_SYS
|
||||
../../../../extern/fast_float
|
||||
../../../../extern/fmtlib/include
|
||||
)
|
||||
|
||||
set(SRC
|
||||
|
@ -57,7 +56,7 @@ set(LIB
|
|||
PRIVATE bf::dna
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
bf_io_common
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
)
|
||||
|
||||
blender_add_lib(bf_io_ply "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
|
|
@ -44,26 +44,23 @@ void FileBuffer::close_file()
|
|||
|
||||
void FileBuffer::write_header_element(StringRef name, int count)
|
||||
{
|
||||
write_fstring("element {} {}\n", std::string_view(name), count);
|
||||
write_fstring("element {} {}\n", name, count);
|
||||
}
|
||||
void FileBuffer::write_header_scalar_property(StringRef dataType, StringRef name)
|
||||
{
|
||||
write_fstring("property {} {}\n", std::string_view(dataType), std::string_view(name));
|
||||
write_fstring("property {} {}\n", dataType, name);
|
||||
}
|
||||
|
||||
void FileBuffer::write_header_list_property(StringRef countType,
|
||||
StringRef dataType,
|
||||
StringRef name)
|
||||
{
|
||||
write_fstring("property list {} {} {}\n",
|
||||
std::string_view(countType),
|
||||
std::string_view(dataType),
|
||||
std::string_view(name));
|
||||
write_fstring("property list {} {} {}\n", countType, dataType, name);
|
||||
}
|
||||
|
||||
void FileBuffer::write_string(StringRef s)
|
||||
{
|
||||
write_fstring("{}\n", std::string_view(s));
|
||||
write_fstring("{}\n", s);
|
||||
}
|
||||
|
||||
void FileBuffer::write_newline()
|
||||
|
|
|
@ -18,7 +18,6 @@ set(INC
|
|||
|
||||
set(INC_SYS
|
||||
../../../../extern/fast_float
|
||||
../../../../extern/fmtlib/include
|
||||
)
|
||||
|
||||
set(SRC
|
||||
|
@ -46,7 +45,7 @@ set(LIB
|
|||
PRIVATE bf::dna
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
bf_io_common
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
)
|
||||
|
||||
blender_add_lib(bf_io_stl "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
|
|
@ -77,6 +77,7 @@ set(INC_SYS
|
|||
${BOOST_INCLUDE_DIR}
|
||||
${TBB_INCLUDE_DIR}
|
||||
${PYTHON_INCLUDE_DIR}
|
||||
|
||||
)
|
||||
|
||||
set(SRC
|
||||
|
@ -200,6 +201,7 @@ set(LIB
|
|||
PRIVATE bf::intern::clog
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
bf_io_common
|
||||
PRIVATE bf::extern::fmtlib
|
||||
)
|
||||
|
||||
list(APPEND LIB
|
||||
|
|
|
@ -223,8 +223,9 @@ void create_blend_shapes(pxr::UsdStageRefPtr stage,
|
|||
pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI::Apply(mesh_prim);
|
||||
|
||||
if (!skel_api) {
|
||||
printf("WARNING: couldn't apply UsdSkelBindingAPI to prim %s\n",
|
||||
mesh_prim.GetPath().GetAsString().c_str());
|
||||
CLOG_WARN(&LOG,
|
||||
"Couldn't apply UsdSkelBindingAPI to mesh prim %s",
|
||||
mesh_prim.GetPath().GetAsString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace usdtokens {
|
|||
/* Parameter names. */
|
||||
static const pxr::TfToken a("a", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken b("b", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken bias("bias", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken clearcoat("clearcoat", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken clearcoatRoughness("clearcoatRoughness", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken diffuseColor("diffuseColor", pxr::TfToken::Immortal);
|
||||
|
@ -57,6 +58,7 @@ static const pxr::TfToken result("result", pxr::TfToken::Immortal);
|
|||
static const pxr::TfToken rgb("rgb", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken rgba("rgba", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken scale("scale", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken sourceColorSpace("sourceColorSpace", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken specularColor("specularColor", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken st("st", pxr::TfToken::Immortal);
|
||||
|
@ -77,7 +79,6 @@ static const pxr::TfToken wrapT("wrapT", pxr::TfToken::Immortal);
|
|||
|
||||
/* Transform 2d names. */
|
||||
static const pxr::TfToken rotation("rotation", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken scale("scale", pxr::TfToken::Immortal);
|
||||
static const pxr::TfToken translation("translation", pxr::TfToken::Immortal);
|
||||
|
||||
/* USD shader names. */
|
||||
|
@ -679,6 +680,107 @@ bool USDMaterialReader::set_node_input(const pxr::UsdShadeInput &usd_input,
|
|||
return false;
|
||||
}
|
||||
|
||||
struct IntermediateNode {
|
||||
bNode *node;
|
||||
const char *sock_input_name;
|
||||
const char *sock_output_name;
|
||||
};
|
||||
|
||||
static IntermediateNode add_normal_map(const pxr::UsdShadeShader &usd_shader,
|
||||
bNodeTree *ntree,
|
||||
int column,
|
||||
NodePlacementContext *r_ctx)
|
||||
{
|
||||
float locx = 0.0f;
|
||||
float locy = 0.0f;
|
||||
compute_node_loc(column, &locx, &locy, r_ctx);
|
||||
|
||||
/* Currently, the Normal Map node has Tangent Space as the default,
|
||||
* which is what we need, so we don't need to explicitly set it. */
|
||||
IntermediateNode normal_map{};
|
||||
normal_map.node = add_node(nullptr, ntree, SH_NODE_NORMAL_MAP, locx, locy);
|
||||
normal_map.sock_input_name = "Color";
|
||||
normal_map.sock_output_name = "Normal";
|
||||
|
||||
return normal_map;
|
||||
}
|
||||
|
||||
static IntermediateNode add_scale_bias(const pxr::UsdShadeShader &usd_shader,
|
||||
bNodeTree *ntree,
|
||||
int column,
|
||||
bool feeds_normal_map,
|
||||
NodePlacementContext *r_ctx)
|
||||
{
|
||||
/* Handle the scale-bias inputs if present. */
|
||||
pxr::UsdShadeInput scale_input = usd_shader.GetInput(usdtokens::scale);
|
||||
pxr::UsdShadeInput bias_input = usd_shader.GetInput(usdtokens::bias);
|
||||
pxr::GfVec4f scale(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
pxr::GfVec4f bias(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
pxr::VtValue val;
|
||||
if (scale_input.Get(&val) && val.CanCast<pxr::GfVec4f>()) {
|
||||
scale = val.Cast<pxr::GfVec4f>(val).UncheckedGet<pxr::GfVec4f>();
|
||||
}
|
||||
if (bias_input.Get(&val) && val.CanCast<pxr::GfVec4f>()) {
|
||||
bias = val.Cast<pxr::GfVec4f>(val).UncheckedGet<pxr::GfVec4f>();
|
||||
}
|
||||
|
||||
/* Nothing to be done if the values match their defaults. */
|
||||
if (scale == pxr::GfVec4f{1.0f, 1.0f, 1.0f, 1.0f} &&
|
||||
bias == pxr::GfVec4f{0.0f, 0.0f, 0.0f, 0.0f})
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
/* Nothing to be done if this feeds a Normal Map and the values match those defaults. */
|
||||
if (feeds_normal_map && (scale[0] == 2.0f && scale[1] == 2.0f && scale[2] == 2.0f) &&
|
||||
(bias[0] == -1.0f && bias[1] == -1.0f && bias[2] == -1.0f))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
float locx = 0.0f;
|
||||
float locy = 0.0f;
|
||||
/* If we know a Normal Map node will be involved, leave room for the another
|
||||
* adjustment node which will be added later. */
|
||||
compute_node_loc(feeds_normal_map ? column + 1 : column, &locx, &locy, r_ctx);
|
||||
|
||||
IntermediateNode scale_bias{};
|
||||
scale_bias.node = add_node(nullptr, ntree, SH_NODE_VECTOR_MATH, locx, locy);
|
||||
scale_bias.node->custom1 = NODE_VECTOR_MATH_MULTIPLY_ADD;
|
||||
scale_bias.sock_input_name = "Vector";
|
||||
scale_bias.sock_output_name = "Vector";
|
||||
|
||||
bNodeSocket *sock_scale = nodeFindSocket(scale_bias.node, SOCK_IN, "Vector_001");
|
||||
bNodeSocket *sock_bias = nodeFindSocket(scale_bias.node, SOCK_IN, "Vector_002");
|
||||
copy_v3_v3(((bNodeSocketValueVector *)sock_scale->default_value)->value, scale.data());
|
||||
copy_v3_v3(((bNodeSocketValueVector *)sock_bias->default_value)->value, bias.data());
|
||||
|
||||
return scale_bias;
|
||||
}
|
||||
|
||||
static IntermediateNode add_scale_bias_adjust(bNodeTree *ntree,
|
||||
int column,
|
||||
NodePlacementContext *r_ctx)
|
||||
{
|
||||
float locx = 0.0f;
|
||||
float locy = 0.0f;
|
||||
compute_node_loc(column, &locx, &locy, r_ctx);
|
||||
|
||||
IntermediateNode adjust{};
|
||||
adjust.node = add_node(nullptr, ntree, SH_NODE_VECTOR_MATH, locx, locy);
|
||||
adjust.node->custom1 = NODE_VECTOR_MATH_MULTIPLY_ADD;
|
||||
adjust.sock_input_name = "Vector";
|
||||
adjust.sock_output_name = "Vector";
|
||||
|
||||
bNodeSocket *sock_scale = nodeFindSocket(adjust.node, SOCK_IN, "Vector_001");
|
||||
bNodeSocket *sock_bias = nodeFindSocket(adjust.node, SOCK_IN, "Vector_002");
|
||||
copy_v3_fl3(((bNodeSocketValueVector *)sock_scale->default_value)->value, 0.5f, 0.5f, 0.5f);
|
||||
copy_v3_fl3(((bNodeSocketValueVector *)sock_bias->default_value)->value, 0.5f, 0.5f, 0.5f);
|
||||
|
||||
return adjust;
|
||||
}
|
||||
|
||||
bool USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
bNode *dest_node,
|
||||
const char *dest_socket_name,
|
||||
|
@ -717,40 +819,66 @@ bool USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
|||
|
||||
/* For now, only convert UsdUVTexture, UsdTransform2d and UsdPrimvarReader_float2 inputs. */
|
||||
if (shader_id == usdtokens::UsdUVTexture) {
|
||||
if (STREQ(dest_socket_name, "Normal")) {
|
||||
/* The normal texture input requires creating a normal map node. */
|
||||
float locx = 0.0f;
|
||||
float locy = 0.0f;
|
||||
compute_node_loc(column + 1, &locx, &locy, r_ctx);
|
||||
int shift = 1;
|
||||
|
||||
bNode *normal_map = add_node(nullptr, ntree, SH_NODE_NORMAL_MAP, locx, locy);
|
||||
|
||||
/* Currently, the Normal Map node has Tangent Space as the default,
|
||||
* which is what we need, so we don't need to explicitly set it. */
|
||||
|
||||
/* Connect the Normal Map to the Normal input. */
|
||||
link_nodes(ntree, normal_map, "Normal", dest_node, "Normal");
|
||||
|
||||
/* Now, create the Texture Image node input to the Normal Map "Color" input. */
|
||||
convert_usd_uv_texture(source_shader,
|
||||
source_name,
|
||||
normal_map,
|
||||
"Color",
|
||||
ntree,
|
||||
column + 2,
|
||||
r_ctx,
|
||||
is_color_corrected);
|
||||
/* Create a Normal Map node if the source is flowing into a 'Normal' socket. */
|
||||
IntermediateNode normal_map{};
|
||||
const bool is_normal_map = STREQ(dest_socket_name, "Normal");
|
||||
if (is_normal_map) {
|
||||
normal_map = add_normal_map(source_shader, ntree, column + shift, r_ctx);
|
||||
shift++;
|
||||
}
|
||||
else {
|
||||
convert_usd_uv_texture(source_shader,
|
||||
source_name,
|
||||
dest_node,
|
||||
dest_socket_name,
|
||||
ntree,
|
||||
column + 1,
|
||||
r_ctx,
|
||||
is_color_corrected);
|
||||
|
||||
/* Create a Scale-Bias adjustment node if necessary. */
|
||||
IntermediateNode scale_bias = add_scale_bias(
|
||||
source_shader, ntree, column + shift, is_normal_map, r_ctx);
|
||||
|
||||
/* Wire up any intermediate nodes that are present. Keep track of the
|
||||
* final "target" destination for the Image link. */
|
||||
bNode *target_node = dest_node;
|
||||
const char *target_sock_name = dest_socket_name;
|
||||
if (normal_map.node) {
|
||||
/* If a scale-bias node is required, we need to re-adjust the output
|
||||
* so it can be passed into the NormalMap node properly. */
|
||||
if (scale_bias.node) {
|
||||
IntermediateNode re_adjust = add_scale_bias_adjust(ntree, column + shift, r_ctx);
|
||||
link_nodes(ntree,
|
||||
scale_bias.node,
|
||||
scale_bias.sock_output_name,
|
||||
re_adjust.node,
|
||||
re_adjust.sock_input_name);
|
||||
link_nodes(ntree,
|
||||
re_adjust.node,
|
||||
re_adjust.sock_output_name,
|
||||
normal_map.node,
|
||||
normal_map.sock_input_name);
|
||||
|
||||
target_node = scale_bias.node;
|
||||
target_sock_name = scale_bias.sock_input_name;
|
||||
shift += 2;
|
||||
}
|
||||
else {
|
||||
target_node = normal_map.node;
|
||||
target_sock_name = normal_map.sock_input_name;
|
||||
}
|
||||
|
||||
link_nodes(ntree, normal_map.node, normal_map.sock_output_name, dest_node, dest_socket_name);
|
||||
}
|
||||
else if (scale_bias.node) {
|
||||
link_nodes(ntree, scale_bias.node, scale_bias.sock_output_name, dest_node, dest_socket_name);
|
||||
target_node = scale_bias.node;
|
||||
target_sock_name = scale_bias.sock_input_name;
|
||||
shift++;
|
||||
}
|
||||
|
||||
convert_usd_uv_texture(source_shader,
|
||||
source_name,
|
||||
target_node,
|
||||
target_sock_name,
|
||||
ntree,
|
||||
column + shift,
|
||||
r_ctx,
|
||||
is_color_corrected);
|
||||
}
|
||||
else if (shader_id == usdtokens::UsdPrimvarReader_float2) {
|
||||
convert_usd_primvar_reader_float2(
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
#include "DNA_collection_types.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <pxr/usd/usdGeom/pointInstancer.h>
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#include "DNA_collection_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <fmt/format.h>
|
||||
|
||||
static CLG_LogRef LOG = {"io.usd"};
|
||||
|
||||
|
@ -690,7 +690,7 @@ void USDStageReader::create_proto_collections(Main *bmain, Collection *parent_co
|
|||
|
||||
/* Determine the max number of digits we will need for the possibly zero-padded
|
||||
* string representing the prototype index. */
|
||||
int max_index_digits = integer_digits_i(instancer_reader->proto_paths().size());
|
||||
const int max_index_digits = integer_digits_i(instancer_reader->proto_paths().size());
|
||||
|
||||
int proto_index = 0;
|
||||
|
||||
|
@ -698,9 +698,7 @@ void USDStageReader::create_proto_collections(Main *bmain, Collection *parent_co
|
|||
BLI_assert(max_index_digits > 0);
|
||||
|
||||
/* Format the collection name to follow the proto_<index> pattern. */
|
||||
std::ostringstream ss;
|
||||
ss << std::setw(max_index_digits) << std::setfill('0') << proto_index;
|
||||
std::string coll_name = "proto_" + ss.str();
|
||||
std::string coll_name = fmt::format("proto_{0:0{1}}", proto_index, max_index_digits);
|
||||
|
||||
/* Create the collection and populate it with the prototype objects. */
|
||||
Collection *proto_coll = create_collection(bmain, instancer_protos_coll, coll_name.c_str());
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
static CLG_LogRef LOG = {"io.usd"};
|
||||
|
||||
/* TfToken objects are not cheap to construct, so we do it once. */
|
||||
namespace usdtokens {
|
||||
/* Materials */
|
||||
|
@ -140,7 +143,9 @@ bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const
|
|||
BLI_assert(context.is_instance());
|
||||
|
||||
if (context.export_path == context.original_export_path) {
|
||||
printf("USD ref error: export path is reference path: %s\n", context.export_path.c_str());
|
||||
CLOG_ERROR(&LOG,
|
||||
"Reference error: export path matches reference path: %s",
|
||||
context.export_path.c_str());
|
||||
BLI_assert_msg(0, "USD reference error");
|
||||
return false;
|
||||
}
|
||||
|
@ -150,9 +155,10 @@ bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const
|
|||
/* See this URL for a description for why referencing may fail"
|
||||
* https://graphics.pixar.com/usd/docs/api/class_usd_references.html#Usd_Failing_References
|
||||
*/
|
||||
printf("USD Export warning: unable to add reference from %s to %s, not instancing object\n",
|
||||
context.export_path.c_str(),
|
||||
context.original_export_path.c_str());
|
||||
CLOG_WARN(&LOG,
|
||||
"Unable to add reference from %s to %s, not instancing object for export",
|
||||
context.export_path.c_str(),
|
||||
context.original_export_path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -234,6 +234,45 @@ static void create_usd_preview_surface_material(const USDExporterContext &usd_ex
|
|||
export_texture(usd_export_context, input_node);
|
||||
}
|
||||
|
||||
/* If a Vector Math node was detected ahead of the texture node, and it has
|
||||
* the correct type, NODE_VECTOR_MATH_MULTIPLY_ADD, assume it's meant to be
|
||||
* used for scale-bias. */
|
||||
bNodeLink *scale_link = traverse_channel(sock, SH_NODE_VECTOR_MATH);
|
||||
if (scale_link) {
|
||||
bNode *vector_math_node = scale_link->fromnode;
|
||||
if (vector_math_node->custom1 == NODE_VECTOR_MATH_MULTIPLY_ADD) {
|
||||
/* Attempt one more traversal in case the current node is not not the
|
||||
* correct NODE_VECTOR_MATH_MULTIPLY_ADD (see code in usd_reader_material). */
|
||||
bNodeSocket *sock_current = nodeFindSocket(vector_math_node, SOCK_IN, "Vector");
|
||||
bNodeLink *temp_link = traverse_channel(sock_current, SH_NODE_VECTOR_MATH);
|
||||
if (temp_link && temp_link->fromnode->custom1 == NODE_VECTOR_MATH_MULTIPLY_ADD) {
|
||||
vector_math_node = temp_link->fromnode;
|
||||
}
|
||||
|
||||
bNodeSocket *sock_scale = nodeFindSocket(vector_math_node, SOCK_IN, "Vector_001");
|
||||
bNodeSocket *sock_bias = nodeFindSocket(vector_math_node, SOCK_IN, "Vector_002");
|
||||
const float *scale_value =
|
||||
static_cast<bNodeSocketValueVector *>(sock_scale->default_value)->value;
|
||||
const float *bias_value =
|
||||
static_cast<bNodeSocketValueVector *>(sock_bias->default_value)->value;
|
||||
|
||||
const pxr::GfVec4f scale(scale_value[0], scale_value[1], scale_value[2], 1.0f);
|
||||
const pxr::GfVec4f bias(bias_value[0], bias_value[1], bias_value[2], 0.0f);
|
||||
|
||||
pxr::UsdShadeInput scale_attr = usd_shader.GetInput(usdtokens::scale);
|
||||
if (!scale_attr) {
|
||||
scale_attr = usd_shader.CreateInput(usdtokens::scale, pxr::SdfValueTypeNames->Float4);
|
||||
}
|
||||
scale_attr.Set(scale);
|
||||
|
||||
pxr::UsdShadeInput bias_attr = usd_shader.GetInput(usdtokens::bias);
|
||||
if (!bias_attr) {
|
||||
bias_attr = usd_shader.CreateInput(usdtokens::bias, pxr::SdfValueTypeNames->Float4);
|
||||
}
|
||||
bias_attr.Set(bias);
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for a connected uvmap node. */
|
||||
if (bNodeSocket *socket = nodeFindSocket(input_node, SOCK_IN, "Vector")) {
|
||||
if (pxr::UsdShadeInput st_input = usd_shader.CreateInput(usdtokens::st,
|
||||
|
@ -244,8 +283,6 @@ static void create_usd_preview_surface_material(const USDExporterContext &usd_ex
|
|||
}
|
||||
}
|
||||
|
||||
set_normal_texture_range(usd_shader, input_spec);
|
||||
|
||||
/* Set opacityThreshold if an alpha cutout is used. */
|
||||
if ((input_spec.input_name == usdtokens::opacity) &&
|
||||
(material->blend_method == MA_BM_CLIP) && (material->alpha_threshold > 0.0))
|
||||
|
|
|
@ -18,7 +18,6 @@ set(INC
|
|||
|
||||
set(INC_SYS
|
||||
../../../../extern/fast_float
|
||||
../../../../extern/fmtlib/include
|
||||
)
|
||||
|
||||
set(SRC
|
||||
|
@ -60,7 +59,7 @@ set(LIB
|
|||
PRIVATE bf::dna
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
bf_io_common
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
)
|
||||
|
||||
if(WITH_TBB)
|
||||
|
|
|
@ -111,11 +111,11 @@ class FormatHandler : NonCopyable, NonMovable {
|
|||
}
|
||||
void write_obj_usemtl(StringRef s)
|
||||
{
|
||||
write_impl("usemtl {}\n", std::string_view(s));
|
||||
write_impl("usemtl {}\n", s);
|
||||
}
|
||||
void write_obj_mtllib(StringRef s)
|
||||
{
|
||||
write_impl("mtllib {}\n", std::string_view(s));
|
||||
write_impl("mtllib {}\n", s);
|
||||
}
|
||||
void write_obj_smooth(int s)
|
||||
{
|
||||
|
@ -123,11 +123,11 @@ class FormatHandler : NonCopyable, NonMovable {
|
|||
}
|
||||
void write_obj_group(StringRef s)
|
||||
{
|
||||
write_impl("g {}\n", std::string_view(s));
|
||||
write_impl("g {}\n", s);
|
||||
}
|
||||
void write_obj_object(StringRef s)
|
||||
{
|
||||
write_impl("o {}\n", std::string_view(s));
|
||||
write_impl("o {}\n", s);
|
||||
}
|
||||
void write_obj_edge(int a, int b)
|
||||
{
|
||||
|
@ -172,7 +172,7 @@ class FormatHandler : NonCopyable, NonMovable {
|
|||
|
||||
void write_mtl_newmtl(StringRef s)
|
||||
{
|
||||
write_impl("newmtl {}\n", std::string_view(s));
|
||||
write_impl("newmtl {}\n", s);
|
||||
}
|
||||
void write_mtl_float(const char *type, float v)
|
||||
{
|
||||
|
@ -189,12 +189,12 @@ class FormatHandler : NonCopyable, NonMovable {
|
|||
/* NOTE: options, if present, will have its own leading space. */
|
||||
void write_mtl_map(const char *type, StringRef options, StringRef value)
|
||||
{
|
||||
write_impl("{}{} {}\n", type, std::string_view(options), std::string_view(value));
|
||||
write_impl("{}{} {}\n", type, options, value);
|
||||
}
|
||||
|
||||
void write_string(StringRef s)
|
||||
{
|
||||
write_impl("{}\n", std::string_view(s));
|
||||
write_impl("{}\n", s);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -625,7 +625,7 @@ typedef struct bUserExtensionRepo {
|
|||
|
||||
/**
|
||||
* The "local" directory where extensions are stored.
|
||||
* When unset, use `{BLENDER_USER_SCRIPTS}/extensions/{bUserExtensionRepo::module}`.
|
||||
* When unset, use `{BLENDER_RESOURCE_PATH_USER}/extensions/{bUserExtensionRepo::module}`.
|
||||
*/
|
||||
char custom_dirpath[1024]; /* FILE_MAX */
|
||||
char remote_path[1024]; /* FILE_MAX */
|
||||
|
|
|
@ -1969,7 +1969,7 @@ static void rna_def_gpencil_layer_mask(BlenderRNA *brna)
|
|||
|
||||
prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_MASK_INVERT);
|
||||
RNA_def_property_ui_icon(prop, ICON_SELECT_INTERSECT, -1);
|
||||
RNA_def_property_ui_icon(prop, ICON_SELECT_INTERSECT, 1);
|
||||
RNA_def_property_ui_text(prop, "Invert", "Invert mask");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
}
|
||||
|
|
|
@ -978,7 +978,7 @@ static std::optional<std::string> rna_prepend_real_ID_path(Main * /*bmain*/,
|
|||
if (!path.is_empty()) {
|
||||
if (real_id) {
|
||||
if (prefix[0]) {
|
||||
return fmt::format("{}{}{}", prefix, path[0] == '[' ? "" : ".", std::string_view(path));
|
||||
return fmt::format("{}{}{}", prefix, path[0] == '[' ? "" : ".", path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
@ -1105,11 +1105,11 @@ static std::string rna_path_from_ptr_to_property_index_ex(const PointerRNA *ptr,
|
|||
|
||||
if (!path_prefix.is_empty()) {
|
||||
if (is_rna) {
|
||||
return fmt::format("{}.{}{}", std::string_view(path_prefix), propname, index_str);
|
||||
return fmt::format("{}.{}{}", path_prefix, propname, index_str);
|
||||
}
|
||||
char propname_esc[MAX_IDPROP_NAME * 2];
|
||||
BLI_str_escape(propname_esc, propname, sizeof(propname_esc));
|
||||
return fmt::format("{}[\"{}\"]{}", std::string_view(path_prefix), propname_esc, index_str);
|
||||
return fmt::format("{}[\"{}\"]{}", path_prefix, propname_esc, index_str);
|
||||
}
|
||||
|
||||
if (is_rna) {
|
||||
|
|
|
@ -17,7 +17,6 @@ set(INC
|
|||
../render
|
||||
../windowmanager
|
||||
../../../intern/eigen
|
||||
../../../extern/fmtlib/include
|
||||
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -123,7 +122,7 @@ set(LIB
|
|||
PRIVATE bf::depsgraph
|
||||
PUBLIC bf::dna
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
)
|
||||
|
||||
if(WITH_ALEMBIC)
|
||||
|
|
|
@ -66,7 +66,6 @@ set(INC
|
|||
../modifiers
|
||||
../render
|
||||
../windowmanager
|
||||
../../../extern/fmtlib/include
|
||||
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -134,7 +133,7 @@ set(LIB
|
|||
bf_nodes_geometry
|
||||
bf_nodes_shader
|
||||
bf_nodes_texture
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
)
|
||||
|
||||
if(WITH_BULLET)
|
||||
|
|
|
@ -18,7 +18,6 @@ set(INC
|
|||
../../modifiers
|
||||
../../render
|
||||
../../windowmanager
|
||||
../../../../extern/fmtlib/include
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
@ -215,7 +214,7 @@ set(LIB
|
|||
bf_geometry
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
bf_nodes
|
||||
extern_fmtlib
|
||||
PRIVATE bf::extern::fmtlib
|
||||
)
|
||||
|
||||
if(WITH_BULLET)
|
||||
|
|
|
@ -274,14 +274,14 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
if (!mesh_attributes_eval.contains(uv_map_name)) {
|
||||
pass_through_input();
|
||||
const std::string message = fmt::format(TIP_("Evaluated surface missing UV map: \"{}\""),
|
||||
std::string_view(uv_map_name));
|
||||
uv_map_name);
|
||||
params.error_message_add(NodeWarningType::Error, message);
|
||||
return;
|
||||
}
|
||||
if (!mesh_attributes_orig.contains(uv_map_name)) {
|
||||
pass_through_input();
|
||||
const std::string message = fmt::format(TIP_("Original surface missing UV map: \"{}\""),
|
||||
std::string_view(uv_map_name));
|
||||
uv_map_name);
|
||||
params.error_message_add(NodeWarningType::Error, message);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -345,7 +345,7 @@ class LazyFunctionForGeometryNode : public LazyFunction {
|
|||
GField output_field{std::make_shared<AnonymousAttributeFieldInput>(
|
||||
std::move(attribute_id),
|
||||
*bsocket.typeinfo->base_cpp_type,
|
||||
fmt::format(TIP_("{} node"), std::string_view(node_.label_or_name())))};
|
||||
fmt::format(TIP_("{} node"), node_.label_or_name()))};
|
||||
void *r_value = params.get_output_data_ptr(lf_index);
|
||||
new (r_value) SocketValueVariant(std::move(output_field));
|
||||
params.output_set(lf_index);
|
||||
|
|
|
@ -222,7 +222,9 @@ static bool python_script_exec(
|
|||
}
|
||||
}
|
||||
}
|
||||
PyErr_Print();
|
||||
if (!reports) {
|
||||
PyErr_Print();
|
||||
}
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -20,7 +20,6 @@ set(INC
|
|||
../render
|
||||
../sequencer
|
||||
../../../intern/memutil
|
||||
../../../extern/fmtlib/include
|
||||
../bmesh
|
||||
|
||||
# RNA_prototypes.h
|
||||
|
@ -101,6 +100,7 @@ set(LIB
|
|||
PRIVATE bf::depsgraph
|
||||
PRIVATE bf::dna
|
||||
bf_editor_screen
|
||||
PRIVATE bf::extern::fmtlib
|
||||
PRIVATE bf::intern::clog
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::animrig
|
||||
|
|
|
@ -52,13 +52,15 @@ def html_extract_markdown_from_url(url: str) -> Optional[str]:
|
|||
with urllib.request.urlopen(req) as fh:
|
||||
data = fh.read().decode('utf-8')
|
||||
|
||||
# Quiet `mypy` checker warning.
|
||||
assert isinstance(data, str)
|
||||
return data
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# markdown Text Parsing
|
||||
|
||||
def markdown_to_paths(markdown: str) -> Tuple[List[str], List[str]]:
|
||||
def markdown_to_paths(markdown: str) -> List[str]:
|
||||
file_paths = []
|
||||
markdown = markdown.replace("<p>", "")
|
||||
markdown = markdown.replace("</p>", "")
|
||||
|
@ -113,7 +115,7 @@ def report_incomplete(file_paths: List[str]) -> int:
|
|||
basedirs = {os.path.dirname(p) for p in file_paths}
|
||||
for base in sorted(basedirs):
|
||||
base_abs = os.path.join(SOURCE_DIR, base)
|
||||
if(os.path.exists(base_abs)):
|
||||
if os.path.exists(base_abs):
|
||||
for p in os.listdir(base_abs):
|
||||
if not p.startswith("."):
|
||||
p_abs = os.path.join(base_abs, p)
|
||||
|
|
|
@ -14,10 +14,11 @@ PATHS: Tuple[Tuple[str, Tuple[Any, ...], Dict[str, str]], ...] = (
|
|||
("build_files/utils/", (), {'MYPYPATH': "modules"}),
|
||||
("doc/manpage/blender.1.py", (), {}),
|
||||
("release/datafiles/", (), {}),
|
||||
("tests/utils/", (), {}),
|
||||
("tools/check_blender_release/", (), {}),
|
||||
("tools/check_docs/", (), {}),
|
||||
("tools/check_source/", (), {'MYPYPATH': "modules"}),
|
||||
("tools/check_wiki/", (), {}),
|
||||
("tools/config/", (), {}),
|
||||
("tools/triage/", (), {}),
|
||||
("tools/utils/", (), {}),
|
||||
("tools/utils_api/", (), {}),
|
||||
("tools/utils_build/", (), {}),
|
||||
|
@ -36,9 +37,6 @@ PATHS_EXCLUDE = set(
|
|||
"build_files/cmake/clang_array_check.py",
|
||||
"build_files/cmake/cmake_netbeans_project.py",
|
||||
"build_files/cmake/cmake_qtcreator_project.py",
|
||||
"build_files/cmake/cmake_static_check_smatch.py",
|
||||
"build_files/cmake/cmake_static_check_sparse.py",
|
||||
"build_files/cmake/cmake_static_check_splint.py",
|
||||
"release/datafiles/blender_icons_geom.py", # Uses `bpy` too much.
|
||||
"tests/utils/bl_run_operators.py", # Uses `bpy` too much.
|
||||
"tests/utils/bl_run_operators_event_simulate.py", # Uses `bpy` too much.
|
||||
|
@ -54,6 +52,9 @@ PATHS_EXCLUDE = set(
|
|||
"tools/check_source/check_descriptions.py",
|
||||
"tools/check_source/check_header_duplicate.py",
|
||||
"tools/check_source/check_unused_defines.py",
|
||||
"tools/triage/gitea_utils.py", # TODO (low priority).
|
||||
"tools/triage/issues_needing_info.py", # TODO (low priority).
|
||||
"tools/triage/weekly_report.py", # TODO (low priority).
|
||||
"tools/utils/blend2json.py",
|
||||
"tools/utils/blender_keyconfig_export_permutations.py",
|
||||
"tools/utils/blender_merge_format_changes.py",
|
||||
|
@ -67,7 +68,6 @@ PATHS_EXCLUDE = set(
|
|||
"tools/utils/make_cursor_gui.py",
|
||||
"tools/utils/make_gl_stipple_from_xpm.py",
|
||||
"tools/utils/make_shape_2d_from_blend.py",
|
||||
"tools/utils/weekly_report.py",
|
||||
"tools/utils_api/bpy_introspect_ui.py", # Uses `bpy`.
|
||||
"tools/utils_doc/rna_manual_reference_updater.py",
|
||||
"tools/utils_ide/qtcreator/externaltools/qtc_assembler_preview.py",
|
||||
|
@ -87,3 +87,12 @@ PATHS = tuple(
|
|||
(os.path.join(SOURCE_DIR, p_items[0].replace("/", os.sep)), *p_items[1:])
|
||||
for p_items in PATHS
|
||||
)
|
||||
|
||||
# Validate:
|
||||
for p_items in PATHS:
|
||||
if not os.path.exists(os.path.join(SOURCE_DIR, p_items[0])):
|
||||
print("PATH:", p_items[0], "doesn't exist")
|
||||
|
||||
for p in PATHS_EXCLUDE:
|
||||
if not os.path.exists(os.path.join(SOURCE_DIR, p)):
|
||||
print("PATHS_EXCLUDE:", p, "doesn't exist")
|
||||
|
|
Loading…
Reference in New Issue