Making the Hue Correct Curves Wrap #117114
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
|
@ -45,6 +46,8 @@ class AssetCatalogService {
|
|||
* Cached catalog tree storage. Lazy-created by #AssetCatalogService::catalog_tree().
|
||||
*/
|
||||
std::unique_ptr<AssetCatalogTree> catalog_tree_;
|
||||
std::mutex catalog_tree_mutex_;
|
||||
|
||||
CatalogFilePath asset_library_root_;
|
||||
|
||||
Vector<std::unique_ptr<AssetCatalogCollection>> undo_snapshots_;
|
||||
|
@ -177,6 +180,9 @@ class AssetCatalogService {
|
|||
*/
|
||||
void update_catalog_path(CatalogID catalog_id, const AssetCatalogPath &new_catalog_path);
|
||||
|
||||
/**
|
||||
* May be called from multiple threads.
|
||||
*/
|
||||
const AssetCatalogTree &catalog_tree();
|
||||
|
||||
/** Return true only if there are no catalogs known. */
|
||||
|
@ -250,8 +256,11 @@ class AssetCatalogService {
|
|||
const CatalogFilePath &blend_file_path);
|
||||
|
||||
std::unique_ptr<AssetCatalogTree> read_into_tree() const;
|
||||
/** Ensure a #catalog_tree() will update the tree. Must be called whenever the contained user
|
||||
* visible catalogs change. */
|
||||
/**
|
||||
* Ensure a #catalog_tree() will update the tree. Must be called whenever the contained user
|
||||
* visible catalogs change.
|
||||
* May be called from multiple threads.
|
||||
*/
|
||||
void invalidate_catalog_tree();
|
||||
|
||||
/**
|
||||
|
@ -265,9 +274,9 @@ class AssetCatalogService {
|
|||
void tag_all_catalogs_as_unsaved_changes();
|
||||
|
||||
/* For access by subclasses, as those will not be marked as friend by #AssetCatalogCollection. */
|
||||
AssetCatalogDefinitionFile *get_catalog_definition_file() const;
|
||||
OwningAssetCatalogMap &get_catalogs() const;
|
||||
OwningAssetCatalogMap &get_deleted_catalogs() const;
|
||||
const AssetCatalogDefinitionFile *get_catalog_definition_file() const;
|
||||
const OwningAssetCatalogMap &get_catalogs() const;
|
||||
const OwningAssetCatalogMap &get_deleted_catalogs() const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -115,16 +115,16 @@ bool AssetCatalogService::is_empty() const
|
|||
return catalog_collection_->catalogs_.is_empty();
|
||||
}
|
||||
|
||||
OwningAssetCatalogMap &AssetCatalogService::get_catalogs() const
|
||||
const OwningAssetCatalogMap &AssetCatalogService::get_catalogs() const
|
||||
{
|
||||
return catalog_collection_->catalogs_;
|
||||
}
|
||||
OwningAssetCatalogMap &AssetCatalogService::get_deleted_catalogs() const
|
||||
const OwningAssetCatalogMap &AssetCatalogService::get_deleted_catalogs() const
|
||||
{
|
||||
return catalog_collection_->deleted_catalogs_;
|
||||
}
|
||||
|
||||
AssetCatalogDefinitionFile *AssetCatalogService::get_catalog_definition_file() const
|
||||
const AssetCatalogDefinitionFile *AssetCatalogService::get_catalog_definition_file() const
|
||||
{
|
||||
return catalog_collection_->catalog_definition_file_.get();
|
||||
}
|
||||
|
@ -589,11 +589,13 @@ std::unique_ptr<AssetCatalogTree> AssetCatalogService::read_into_tree() const
|
|||
|
||||
void AssetCatalogService::invalidate_catalog_tree()
|
||||
{
|
||||
std::lock_guard lock{catalog_tree_mutex_};
|
||||
this->catalog_tree_ = nullptr;
|
||||
}
|
||||
|
||||
const AssetCatalogTree &AssetCatalogService::catalog_tree()
|
||||
{
|
||||
std::lock_guard lock{catalog_tree_mutex_};
|
||||
if (!catalog_tree_) {
|
||||
/* Ensure all catalog paths lead to valid catalogs. This is important for the catalog tree to
|
||||
* be usable, e.g. it makes sure every item in the tree maps to an actual catalog. */
|
||||
|
|
|
@ -44,12 +44,12 @@ class TestableAssetCatalogService : public AssetCatalogService {
|
|||
{
|
||||
}
|
||||
|
||||
AssetCatalogDefinitionFile *get_catalog_definition_file()
|
||||
const AssetCatalogDefinitionFile *get_catalog_definition_file()
|
||||
{
|
||||
return AssetCatalogService::get_catalog_definition_file();
|
||||
}
|
||||
|
||||
OwningAssetCatalogMap &get_deleted_catalogs() const
|
||||
const OwningAssetCatalogMap &get_deleted_catalogs() const
|
||||
{
|
||||
return AssetCatalogService::get_deleted_catalogs();
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class TestableAssetCatalogService : public AssetCatalogService {
|
|||
int64_t count_catalogs_with_path(const CatalogFilePath &path)
|
||||
{
|
||||
int64_t count = 0;
|
||||
for (auto &catalog_uptr : get_catalogs().values()) {
|
||||
for (const auto &catalog_uptr : get_catalogs().values()) {
|
||||
if (catalog_uptr->path == path) {
|
||||
count++;
|
||||
}
|
||||
|
@ -124,9 +124,10 @@ class AssetCatalogTest : public AssetLibraryTestBase {
|
|||
<< "Overwritten CDF should have been backed up.";
|
||||
|
||||
/* Test that the in-memory CDF has the expected file path. */
|
||||
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
BLI_path_slash_native(cdf->file_path.data());
|
||||
EXPECT_EQ(cdf_toplevel, cdf->file_path);
|
||||
const AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
std::string native_cdf_path = cdf->file_path;
|
||||
BLI_path_slash_native(native_cdf_path.data());
|
||||
EXPECT_EQ(cdf_toplevel, native_cdf_path);
|
||||
|
||||
/* Test that the in-memory catalogs have been merged with the on-disk one. */
|
||||
AssetCatalogService loaded_service(cdf_toplevel);
|
||||
|
@ -265,7 +266,7 @@ TEST_F(AssetCatalogTest, write_single_file)
|
|||
|
||||
const CatalogFilePath save_to_path = use_temp_path() +
|
||||
AssetCatalogService::DEFAULT_CATALOG_FILENAME;
|
||||
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
const AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
cdf->write_to_disk(save_to_path);
|
||||
|
||||
AssetCatalogService loaded_service(save_to_path);
|
||||
|
@ -293,7 +294,7 @@ TEST_F(AssetCatalogTest, read_write_unicode_filepath)
|
|||
service.load_from_disk(load_from_path);
|
||||
|
||||
const CatalogFilePath save_to_path = use_temp_path() + "новый.cats.txt";
|
||||
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
const AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
ASSERT_NE(nullptr, cdf) << "unable to load " << load_from_path;
|
||||
EXPECT_TRUE(cdf->write_to_disk(save_to_path));
|
||||
|
||||
|
@ -375,7 +376,7 @@ TEST_F(AssetCatalogTest, on_blendfile_save__from_memory_into_empty_directory)
|
|||
EXPECT_TRUE(BLI_exists(expected_cdf_path.c_str()));
|
||||
|
||||
/* Test that the in-memory CDF has been created, and contains the expected catalog. */
|
||||
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
const AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
ASSERT_NE(nullptr, cdf);
|
||||
EXPECT_TRUE(cdf->contains(cat->catalog_id));
|
||||
|
||||
|
@ -410,7 +411,7 @@ TEST_F(AssetCatalogTest, on_blendfile_save__from_memory_into_existing_cdf_and_me
|
|||
<< "Overwritten CDF should have been backed up.";
|
||||
|
||||
/* Test that the in-memory CDF has the expected file path. */
|
||||
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
const AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
ASSERT_NE(nullptr, cdf);
|
||||
EXPECT_EQ(writable_cdf_file, cdf->file_path);
|
||||
|
||||
|
@ -633,7 +634,7 @@ TEST_F(AssetCatalogTest, delete_catalog_write_to_disk)
|
|||
service.delete_catalog_by_id_soft(UUID_POSES_ELLIE);
|
||||
|
||||
const CatalogFilePath save_to_path = use_temp_path();
|
||||
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
const AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
|
||||
cdf->write_to_disk(save_to_path + SEP_STR + AssetCatalogService::DEFAULT_CATALOG_FILENAME);
|
||||
|
||||
AssetCatalogService loaded_service(save_to_path);
|
||||
|
@ -1022,7 +1023,7 @@ TEST_F(AssetCatalogTest, create_missing_catalogs_after_loading)
|
|||
EXPECT_TRUE(cat_ruzena->flags.has_unsaved_changes)
|
||||
<< "Missing parents should be marked as having changes.";
|
||||
|
||||
AssetCatalogDefinitionFile *cdf = loaded_service.get_catalog_definition_file();
|
||||
const AssetCatalogDefinitionFile *cdf = loaded_service.get_catalog_definition_file();
|
||||
ASSERT_NE(nullptr, cdf);
|
||||
EXPECT_TRUE(cdf->contains(cat_char->catalog_id)) << "Missing parents should be saved to a CDF.";
|
||||
EXPECT_TRUE(cdf->contains(cat_ellie->catalog_id)) << "Missing parents should be saved to a CDF.";
|
||||
|
|
|
@ -106,6 +106,8 @@ static int wm_obj_export_exec(bContext *C, wmOperator *op)
|
|||
export_params.export_smooth_groups = RNA_boolean_get(op->ptr, "export_smooth_groups");
|
||||
export_params.smooth_groups_bitflags = RNA_boolean_get(op->ptr, "smooth_group_bitflags");
|
||||
|
||||
export_params.reports = op->reports;
|
||||
|
||||
OBJ_export(C, &export_params);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -404,6 +406,8 @@ static int wm_obj_import_exec(bContext *C, wmOperator *op)
|
|||
import_params.relative_paths = ((U.flag & USER_RELPATHS) != 0);
|
||||
import_params.clear_selection = true;
|
||||
|
||||
import_params.reports = op->reports;
|
||||
|
||||
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
|
||||
|
||||
if (paths.is_empty()) {
|
||||
|
|
|
@ -67,7 +67,7 @@ static int wm_ply_export_exec(bContext *C, wmOperator *op)
|
|||
BKE_report(op->reports, RPT_ERROR, "No filepath given");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
PLYExportParams export_params = {"\0"};
|
||||
PLYExportParams export_params{};
|
||||
export_params.file_base_for_tests[0] = '\0';
|
||||
RNA_string_get(op->ptr, "filepath", export_params.filepath);
|
||||
export_params.blen_filepath = CTX_data_main(C)->filepath;
|
||||
|
@ -85,6 +85,8 @@ static int wm_ply_export_exec(bContext *C, wmOperator *op)
|
|||
export_params.export_triangulated_mesh = RNA_boolean_get(op->ptr, "export_triangulated_mesh");
|
||||
export_params.ascii_format = RNA_boolean_get(op->ptr, "ascii_format");
|
||||
|
||||
export_params.reports = op->reports;
|
||||
|
||||
PLY_export(C, &export_params);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -248,6 +250,8 @@ static int wm_ply_import_exec(bContext *C, wmOperator *op)
|
|||
params.import_attributes = RNA_boolean_get(op->ptr, "import_attributes");
|
||||
params.vertex_colors = ePLYVertexColorMode(RNA_enum_get(op->ptr, "import_colors"));
|
||||
|
||||
params.reports = op->reports;
|
||||
|
||||
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
|
||||
|
||||
if (paths.is_empty()) {
|
||||
|
@ -256,7 +260,7 @@ static int wm_ply_import_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
for (const auto &path : paths) {
|
||||
STRNCPY(params.filepath, path.c_str());
|
||||
PLY_import(C, ¶ms, op);
|
||||
PLY_import(C, ¶ms);
|
||||
};
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
|
|
@ -48,7 +48,7 @@ static int wm_stl_export_execute(bContext *C, wmOperator *op)
|
|||
BKE_report(op->reports, RPT_ERROR, "No filename given");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
STLExportParams export_params;
|
||||
STLExportParams export_params{};
|
||||
RNA_string_get(op->ptr, "filepath", export_params.filepath);
|
||||
export_params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
|
||||
export_params.up_axis = eIOAxis(RNA_enum_get(op->ptr, "up_axis"));
|
||||
|
@ -59,6 +59,8 @@ static int wm_stl_export_execute(bContext *C, wmOperator *op)
|
|||
export_params.ascii_format = RNA_boolean_get(op->ptr, "ascii_format");
|
||||
export_params.use_batch = RNA_boolean_get(op->ptr, "use_batch");
|
||||
|
||||
export_params.reports = op->reports;
|
||||
|
||||
STL_export(C, &export_params);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -189,6 +191,8 @@ static int wm_stl_import_exec(bContext *C, wmOperator *op)
|
|||
params.global_scale = RNA_float_get(op->ptr, "global_scale");
|
||||
params.use_mesh_validate = RNA_boolean_get(op->ptr, "use_mesh_validate");
|
||||
|
||||
params.reports = op->reports;
|
||||
|
||||
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
|
||||
|
||||
if (paths.is_empty()) {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "BLI_bounds.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
#include "DNA_modifier_types.h"
|
||||
|
@ -47,7 +49,9 @@ float volume_compute_voxel_size(const Depsgraph *depsgraph,
|
|||
*/
|
||||
bke::VolumeGridData *fog_volume_grid_add_from_mesh(Volume *volume,
|
||||
StringRefNull name,
|
||||
const Mesh *mesh,
|
||||
Span<float3> positions,
|
||||
Span<int> corner_verts,
|
||||
Span<int3> corner_tris,
|
||||
const float4x4 &mesh_to_volume_space_transform,
|
||||
float voxel_size,
|
||||
float interior_band_width,
|
||||
|
@ -55,7 +59,12 @@ bke::VolumeGridData *fog_volume_grid_add_from_mesh(Volume *volume,
|
|||
/**
|
||||
* Add a new SDF VolumeGrid to the Volume by converting the supplied mesh.
|
||||
*/
|
||||
bke::VolumeGridData *sdf_volume_grid_add_from_mesh(
|
||||
Volume *volume, StringRefNull name, const Mesh &mesh, float voxel_size, float half_band_width);
|
||||
bke::VolumeGridData *sdf_volume_grid_add_from_mesh(Volume *volume,
|
||||
StringRefNull name,
|
||||
Span<float3> positions,
|
||||
Span<int> corner_verts,
|
||||
Span<int3> corner_tris,
|
||||
float voxel_size,
|
||||
float half_band_width);
|
||||
#endif
|
||||
} // namespace blender::geometry
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "BLI_math_matrix.hh"
|
||||
#include "BLI_task.hh"
|
||||
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_volume.hh"
|
||||
#include "BKE_volume_openvdb.hh"
|
||||
|
||||
|
@ -29,17 +28,23 @@ class OpenVDBMeshAdapter {
|
|||
float4x4 transform_;
|
||||
|
||||
public:
|
||||
OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform);
|
||||
OpenVDBMeshAdapter(const Span<float3> positions,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris,
|
||||
const float4x4 &transform);
|
||||
size_t polygonCount() const;
|
||||
size_t pointCount() const;
|
||||
size_t vertexCount(size_t /*polygon_index*/) const;
|
||||
void getIndexSpacePoint(size_t polygon_index, size_t vertex_index, openvdb::Vec3d &pos) const;
|
||||
};
|
||||
|
||||
OpenVDBMeshAdapter::OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform)
|
||||
: positions_(mesh.vert_positions()),
|
||||
corner_verts_(mesh.corner_verts()),
|
||||
corner_tris_(mesh.corner_tris()),
|
||||
OpenVDBMeshAdapter::OpenVDBMeshAdapter(const Span<float3> positions,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris,
|
||||
const float4x4 &transform)
|
||||
: positions_(positions),
|
||||
corner_verts_(corner_verts),
|
||||
corner_tris_(corner_tris),
|
||||
transform_(transform)
|
||||
{
|
||||
}
|
||||
|
@ -105,7 +110,9 @@ float volume_compute_voxel_size(const Depsgraph *depsgraph,
|
|||
}
|
||||
|
||||
static openvdb::FloatGrid::Ptr mesh_to_fog_volume_grid(
|
||||
const Mesh *mesh,
|
||||
const Span<float3> positions,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris,
|
||||
const float4x4 &mesh_to_volume_space_transform,
|
||||
const float voxel_size,
|
||||
const float interior_band_width,
|
||||
|
@ -120,7 +127,8 @@ static openvdb::FloatGrid::Ptr mesh_to_fog_volume_grid(
|
|||
/* Better align generated grid with the source mesh. */
|
||||
mesh_to_index_space_transform.location() -= 0.5f;
|
||||
|
||||
OpenVDBMeshAdapter mesh_adapter{*mesh, mesh_to_index_space_transform};
|
||||
OpenVDBMeshAdapter mesh_adapter{
|
||||
positions, corner_verts, corner_tris, mesh_to_index_space_transform};
|
||||
const float interior = std::max(1.0f, interior_band_width / voxel_size);
|
||||
|
||||
openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
|
||||
|
@ -139,7 +147,9 @@ static openvdb::FloatGrid::Ptr mesh_to_fog_volume_grid(
|
|||
return new_grid;
|
||||
}
|
||||
|
||||
static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh,
|
||||
static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Span<float3> positions,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris,
|
||||
const float voxel_size,
|
||||
const float half_band_width)
|
||||
{
|
||||
|
@ -147,10 +157,6 @@ static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const Span<float3> positions = mesh.vert_positions();
|
||||
const Span<int> corner_verts = mesh.corner_verts();
|
||||
const Span<int3> corner_tris = mesh.corner_tris();
|
||||
|
||||
std::vector<openvdb::Vec3s> points(positions.size());
|
||||
std::vector<openvdb::Vec3I> triangles(corner_tris.size());
|
||||
|
||||
|
@ -179,24 +185,34 @@ static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh,
|
|||
|
||||
bke::VolumeGridData *fog_volume_grid_add_from_mesh(Volume *volume,
|
||||
const StringRefNull name,
|
||||
const Mesh *mesh,
|
||||
const Span<float3> positions,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris,
|
||||
const float4x4 &mesh_to_volume_space_transform,
|
||||
const float voxel_size,
|
||||
const float interior_band_width,
|
||||
const float density)
|
||||
{
|
||||
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_fog_volume_grid(
|
||||
mesh, mesh_to_volume_space_transform, voxel_size, interior_band_width, density);
|
||||
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_fog_volume_grid(positions,
|
||||
corner_verts,
|
||||
corner_tris,
|
||||
mesh_to_volume_space_transform,
|
||||
voxel_size,
|
||||
interior_band_width,
|
||||
density);
|
||||
return mesh_grid ? BKE_volume_grid_add_vdb(*volume, name, std::move(mesh_grid)) : nullptr;
|
||||
}
|
||||
|
||||
bke::VolumeGridData *sdf_volume_grid_add_from_mesh(Volume *volume,
|
||||
const StringRefNull name,
|
||||
const Mesh &mesh,
|
||||
const Span<float3> positions,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris,
|
||||
const float voxel_size,
|
||||
const float half_band_width)
|
||||
{
|
||||
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_sdf_volume_grid(mesh, voxel_size, half_band_width);
|
||||
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_sdf_volume_grid(
|
||||
positions, corner_verts, corner_tris, voxel_size, half_band_width);
|
||||
return mesh_grid ? BKE_volume_grid_add_vdb(*volume, name, std::move(mesh_grid)) : nullptr;
|
||||
}
|
||||
} // namespace blender::geometry
|
||||
|
|
|
@ -32,9 +32,9 @@ void PLY_export(bContext *C, const PLYExportParams *export_params)
|
|||
report_duration("export", start_time, export_params->filepath);
|
||||
}
|
||||
|
||||
void PLY_import(bContext *C, const PLYImportParams *import_params, wmOperator *op)
|
||||
void PLY_import(bContext *C, const PLYImportParams *import_params)
|
||||
{
|
||||
TimePoint start_time = Clock::now();
|
||||
blender::io::ply::importer_main(C, *import_params, op);
|
||||
blender::io::ply::importer_main(C, *import_params);
|
||||
report_duration("import", start_time, import_params->filepath);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ struct PLYExportParams {
|
|||
ePLYVertexColorMode vertex_colors;
|
||||
bool export_attributes;
|
||||
bool export_triangulated_mesh;
|
||||
|
||||
ReportList *reports = nullptr;
|
||||
};
|
||||
|
||||
struct PLYImportParams {
|
||||
|
@ -57,6 +59,8 @@ struct PLYImportParams {
|
|||
ePLYVertexColorMode vertex_colors;
|
||||
bool import_attributes;
|
||||
bool merge_verts;
|
||||
|
||||
ReportList *reports = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -64,4 +68,4 @@ struct PLYImportParams {
|
|||
*/
|
||||
void PLY_export(bContext *C, const PLYExportParams *export_params);
|
||||
|
||||
void PLY_import(bContext *C, const PLYImportParams *import_params, wmOperator *op);
|
||||
void PLY_import(bContext *C, const PLYImportParams *import_params);
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
* \ingroup ply
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_report.hh"
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
@ -32,11 +35,21 @@ void exporter_main(bContext *C, const PLYExportParams &export_params)
|
|||
|
||||
std::unique_ptr<FileBuffer> buffer;
|
||||
|
||||
if (export_params.ascii_format) {
|
||||
buffer = std::make_unique<FileBufferAscii>(export_params.filepath);
|
||||
try {
|
||||
if (export_params.ascii_format) {
|
||||
buffer = std::make_unique<FileBufferAscii>(export_params.filepath);
|
||||
}
|
||||
else {
|
||||
buffer = std::make_unique<FileBufferBinary>(export_params.filepath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
buffer = std::make_unique<FileBufferBinary>(export_params.filepath);
|
||||
catch (const std::system_error &ex) {
|
||||
fprintf(stderr, "%s\n", ex.what());
|
||||
BKE_reportf(export_params.reports,
|
||||
RPT_ERROR,
|
||||
"PLY Export: Cannot open file '%s'",
|
||||
export_params.filepath);
|
||||
return;
|
||||
}
|
||||
|
||||
write_header(*buffer.get(), *plyData.get(), export_params);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* \ingroup ply
|
||||
*/
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
|
@ -161,19 +162,18 @@ const char *read_header(PlyReadBuffer &file, PlyHeader &r_header)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void importer_main(bContext *C, const PLYImportParams &import_params, wmOperator *op)
|
||||
void importer_main(bContext *C, const PLYImportParams &import_params)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
importer_main(bmain, scene, view_layer, import_params, op);
|
||||
importer_main(bmain, scene, view_layer, import_params);
|
||||
}
|
||||
|
||||
void importer_main(Main *bmain,
|
||||
Scene *scene,
|
||||
ViewLayer *view_layer,
|
||||
const PLYImportParams &import_params,
|
||||
wmOperator *op)
|
||||
const PLYImportParams &import_params)
|
||||
{
|
||||
/* File base name used for both mesh and object. */
|
||||
char ob_name[FILE_MAX];
|
||||
|
@ -187,7 +187,7 @@ void importer_main(Main *bmain,
|
|||
const char *err = read_header(file, header);
|
||||
if (err != nullptr) {
|
||||
fprintf(stderr, "PLY Importer: %s: %s\n", ob_name, err);
|
||||
BKE_reportf(op->reports, RPT_ERROR, "PLY Importer: %s: %s", ob_name, err);
|
||||
BKE_reportf(import_params.reports, RPT_ERROR, "PLY Importer: %s: %s", ob_name, err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -195,17 +195,17 @@ void importer_main(Main *bmain,
|
|||
std::unique_ptr<PlyData> data = import_ply_data(file, header);
|
||||
if (data == nullptr) {
|
||||
fprintf(stderr, "PLY Importer: failed importing %s, unknown error\n", ob_name);
|
||||
BKE_report(op->reports, RPT_ERROR, "PLY Importer: failed importing, unknown error");
|
||||
BKE_report(import_params.reports, RPT_ERROR, "PLY Importer: failed importing, unknown error");
|
||||
return;
|
||||
}
|
||||
if (!data->error.empty()) {
|
||||
fprintf(stderr, "PLY Importer: failed importing %s: %s\n", ob_name, data->error.c_str());
|
||||
BKE_report(op->reports, RPT_ERROR, "PLY Importer: failed importing, unknown error");
|
||||
BKE_report(import_params.reports, RPT_ERROR, "PLY Importer: failed importing, unknown error");
|
||||
return;
|
||||
}
|
||||
if (data->vertices.is_empty()) {
|
||||
fprintf(stderr, "PLY Importer: file %s contains no vertices\n", ob_name);
|
||||
BKE_report(op->reports, RPT_ERROR, "PLY Importer: failed importing, no vertices");
|
||||
BKE_report(import_params.reports, RPT_ERROR, "PLY Importer: failed importing, no vertices");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,17 +15,14 @@ namespace blender::io::ply {
|
|||
|
||||
class PlyReadBuffer;
|
||||
|
||||
void splitstr(std::string str, Vector<std::string> &words, const StringRef &deli);
|
||||
|
||||
/* Main import function used from within Blender. */
|
||||
void importer_main(bContext *C, const PLYImportParams &import_params, wmOperator *op);
|
||||
void importer_main(bContext *C, const PLYImportParams &import_params);
|
||||
|
||||
/* Used from tests, where full bContext does not exist. */
|
||||
void importer_main(Main *bmain,
|
||||
Scene *scene,
|
||||
ViewLayer *view_layer,
|
||||
const PLYImportParams &import_params,
|
||||
wmOperator *op);
|
||||
const PLYImportParams &import_params);
|
||||
|
||||
const char *read_header(PlyReadBuffer &file, PlyHeader &r_header);
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ struct STLImportParams {
|
|||
bool use_scene_unit;
|
||||
float global_scale;
|
||||
bool use_mesh_validate;
|
||||
|
||||
ReportList *reports = nullptr;
|
||||
};
|
||||
|
||||
struct STLExportParams {
|
||||
|
@ -34,6 +36,8 @@ struct STLExportParams {
|
|||
bool apply_modifiers;
|
||||
bool ascii_format;
|
||||
bool use_batch;
|
||||
|
||||
ReportList *reports = nullptr;
|
||||
};
|
||||
|
||||
void STL_import(bContext *C, const STLImportParams *import_params);
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_report.hh"
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
|
@ -40,7 +42,17 @@ void export_frame(Depsgraph *depsgraph,
|
|||
|
||||
/* If not exporting in batch, create single writer for all objects. */
|
||||
if (!export_params.use_batch) {
|
||||
writer = std::make_unique<FileWriter>(export_params.filepath, export_params.ascii_format);
|
||||
try {
|
||||
writer = std::make_unique<FileWriter>(export_params.filepath, export_params.ascii_format);
|
||||
}
|
||||
catch (const std::runtime_error &ex) {
|
||||
fprintf(stderr, "%s\n", ex.what());
|
||||
BKE_reportf(export_params.reports,
|
||||
RPT_ERROR,
|
||||
"STL Export: Cannot open file '%s'",
|
||||
export_params.filepath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DEGObjectIterSettings deg_iter_settings{};
|
||||
|
@ -70,7 +82,15 @@ void export_frame(Depsgraph *depsgraph,
|
|||
char filepath[FILE_MAX];
|
||||
STRNCPY(filepath, export_params.filepath);
|
||||
BLI_path_extension_replace(filepath, FILE_MAX, suffix.c_str());
|
||||
writer = std::make_unique<FileWriter>(filepath, export_params.ascii_format);
|
||||
try {
|
||||
writer = std::make_unique<FileWriter>(filepath, export_params.ascii_format);
|
||||
}
|
||||
catch (const std::runtime_error &ex) {
|
||||
fprintf(stderr, "%s\n", ex.what());
|
||||
BKE_reportf(
|
||||
export_params.reports, RPT_ERROR, "STL Export: Cannot open file '%s'", filepath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Object *obj_eval = DEG_get_evaluated_object(depsgraph, object);
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
|
||||
#include <cstdio>
|
||||
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_report.hh"
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_fileops.hh"
|
||||
|
@ -61,6 +63,10 @@ void importer_main(Main *bmain,
|
|||
FILE *file = BLI_fopen(import_params.filepath, "rb");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Failed to open STL file:'%s'.\n", import_params.filepath);
|
||||
BKE_reportf(import_params.reports,
|
||||
RPT_ERROR,
|
||||
"STL Import: Cannot open file '%s'",
|
||||
import_params.filepath);
|
||||
return;
|
||||
}
|
||||
BLI_SCOPED_DEFER([&]() { fclose(file); });
|
||||
|
@ -74,6 +80,10 @@ void importer_main(Main *bmain,
|
|||
fseek(file, BINARY_HEADER_SIZE, SEEK_SET);
|
||||
if (fread(&num_tri, sizeof(uint32_t), 1, file) != 1) {
|
||||
stl_import_report_error(file);
|
||||
BKE_reportf(import_params.reports,
|
||||
RPT_ERROR,
|
||||
"STL Import: Failed to read file '%s'",
|
||||
import_params.filepath);
|
||||
return;
|
||||
}
|
||||
bool is_ascii_stl = (file_size != (BINARY_HEADER_SIZE + 4 + BINARY_STRIDE * num_tri));
|
||||
|
@ -89,6 +99,10 @@ void importer_main(Main *bmain,
|
|||
|
||||
if (mesh == nullptr) {
|
||||
fprintf(stderr, "STL Importer: Failed to import mesh '%s'\n", import_params.filepath);
|
||||
BKE_reportf(import_params.reports,
|
||||
RPT_ERROR,
|
||||
"STL Import: Failed to import mesh from file '%s'",
|
||||
import_params.filepath);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "IO_stl.hh"
|
||||
#include "stl_export.hh"
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ struct OBJExportParams {
|
|||
bool export_smooth_groups;
|
||||
/* Create bitflags instead of the default "0"/"1" group IDs. */
|
||||
bool smooth_groups_bitflags;
|
||||
|
||||
ReportList *reports = nullptr;
|
||||
};
|
||||
|
||||
struct OBJImportParams {
|
||||
|
@ -76,6 +78,8 @@ struct OBJImportParams {
|
|||
bool validate_meshes = false;
|
||||
bool relative_paths = true;
|
||||
bool clear_selection = true;
|
||||
|
||||
ReportList *reports = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <system_error>
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_report.hh"
|
||||
#include "BKE_scene.hh"
|
||||
|
||||
#include "BLI_path_util.h"
|
||||
|
@ -259,6 +261,7 @@ void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, co
|
|||
}
|
||||
catch (const std::system_error &ex) {
|
||||
print_exception_error(ex);
|
||||
BKE_reportf(export_params.reports, RPT_ERROR, "OBJ Export: Cannot open file '%s'", filepath);
|
||||
return;
|
||||
}
|
||||
if (!frame_writer) {
|
||||
|
@ -272,6 +275,10 @@ void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, co
|
|||
}
|
||||
catch (const std::system_error &ex) {
|
||||
print_exception_error(ex);
|
||||
BKE_reportf(export_params.reports,
|
||||
RPT_WARNING,
|
||||
"OBJ Export: Cannot create mtl file for '%s'",
|
||||
filepath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* \ingroup obj
|
||||
*/
|
||||
|
||||
#include "BKE_report.hh"
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_color.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
@ -441,6 +443,10 @@ OBJParser::OBJParser(const OBJImportParams &import_params, size_t read_buffer_si
|
|||
obj_file_ = BLI_fopen(import_params_.filepath, "rb");
|
||||
if (!obj_file_) {
|
||||
fprintf(stderr, "Cannot read from OBJ file:'%s'.\n", import_params_.filepath);
|
||||
BKE_reportf(import_params_.reports,
|
||||
RPT_ERROR,
|
||||
"OBJ Import: Cannot open file '%s'",
|
||||
import_params_.filepath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "BLI_string.h"
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_scene.hh"
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ struct OBJExportParamsDefault {
|
|||
params.export_vertex_groups = false;
|
||||
params.export_smooth_groups = true;
|
||||
params.smooth_groups_bitflags = false;
|
||||
|
||||
params.reports = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_wrapper.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
#include "BKE_volume.hh"
|
||||
|
@ -158,7 +159,9 @@ static Volume *mesh_to_volume(ModifierData *md,
|
|||
/* Convert mesh to grid and add to volume. */
|
||||
geometry::fog_volume_grid_add_from_mesh(volume,
|
||||
"density",
|
||||
mesh,
|
||||
mesh->vert_positions(),
|
||||
mesh->corner_verts(),
|
||||
mesh->corner_tris(),
|
||||
mesh_to_own_object_space_transform,
|
||||
voxel_size,
|
||||
mvmd->interior_band_width,
|
||||
|
|
|
@ -421,8 +421,8 @@ DefNode(GeometryNode, GEO_NODE_REPLACE_MATERIAL, 0, "REPLACE_MATERIAL", ReplaceM
|
|||
DefNode(GeometryNode, GEO_NODE_RESAMPLE_CURVE, 0, "RESAMPLE_CURVE", ResampleCurve, "Resample Curve", "Generate a poly spline for each input spline")
|
||||
DefNode(GeometryNode, GEO_NODE_REVERSE_CURVE, 0, "REVERSE_CURVE", ReverseCurve, "Reverse Curve", "Change the direction of curves by swapping their start and end data")
|
||||
DefNode(GeometryNode, GEO_NODE_ROTATE_INSTANCES, 0, "ROTATE_INSTANCES", RotateInstances, "Rotate Instances", "Rotate geometry instances in local or global space")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_GRID, 0, "SAMPLE_GRID", SampleGrid, "Sample Grid", "")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_CURVE, def_geo_curve_sample, "SAMPLE_CURVE", SampleCurve, "Sample Curve", "Retrieve data from a point on a curve at a certain distance from its start")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_GRID, 0, "SAMPLE_GRID", SampleGrid, "Sample Grid", "")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_INDEX, def_geo_sample_index, "SAMPLE_INDEX", SampleIndex, "Sample Index", "Retrieve values from specific geometry elements")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_NEAREST_SURFACE, 0, "SAMPLE_NEAREST_SURFACE", SampleNearestSurface, "Sample Nearest Surface", "Calculate the interpolated value of a mesh attribute on the closest point of its surface")
|
||||
DefNode(GeometryNode, GEO_NODE_SAMPLE_NEAREST, 0, "SAMPLE_NEAREST", SampleNearest, "Sample Nearest", "Find the element of a geometry closest to a position. Similar to the \"Index of Nearest\" node")
|
||||
|
|
|
@ -108,7 +108,9 @@ static Volume *create_volume_from_mesh(const Mesh &mesh, GeoNodeExecParams ¶
|
|||
/* Convert mesh to grid and add to volume. */
|
||||
geometry::fog_volume_grid_add_from_mesh(volume,
|
||||
"density",
|
||||
&mesh,
|
||||
mesh.vert_positions(),
|
||||
mesh.corner_verts(),
|
||||
mesh.corner_tris(),
|
||||
mesh_to_volume_space_transform,
|
||||
voxel_size,
|
||||
interior_band_width,
|
||||
|
|
|
@ -88,8 +88,7 @@ static void convert_to_grid_index_space(const float voxel_size,
|
|||
*/
|
||||
static void initialize_volume_component_from_points(GeoNodeExecParams ¶ms,
|
||||
const NodeGeometryPointsToVolume &storage,
|
||||
GeometrySet &r_geometry_set,
|
||||
openvdb::GridClass gridClass)
|
||||
GeometrySet &r_geometry_set)
|
||||
{
|
||||
Vector<float3> positions;
|
||||
Vector<float> radii;
|
||||
|
@ -131,15 +130,10 @@ static void initialize_volume_component_from_points(GeoNodeExecParams ¶ms,
|
|||
|
||||
convert_to_grid_index_space(voxel_size, positions, radii);
|
||||
|
||||
if (gridClass == openvdb::GRID_FOG_VOLUME) {
|
||||
const float density = params.get_input<float>("Density");
|
||||
blender::geometry::fog_volume_grid_add_from_points(
|
||||
volume, "density", positions, radii, voxel_size, density);
|
||||
}
|
||||
else if (gridClass == openvdb::GRID_LEVEL_SET) {
|
||||
blender::geometry::sdf_volume_grid_add_from_points(
|
||||
volume, "distance", positions, radii, voxel_size);
|
||||
}
|
||||
const float density = params.get_input<float>("Density");
|
||||
blender::geometry::fog_volume_grid_add_from_points(
|
||||
volume, "density", positions, radii, voxel_size, density);
|
||||
|
||||
r_geometry_set.keep_only_during_modify({GeometryComponent::Type::Volume});
|
||||
r_geometry_set.replace_volume(volume);
|
||||
}
|
||||
|
@ -208,8 +202,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
|
||||
const NodeGeometryPointsToVolume &storage = node_storage(params.node());
|
||||
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
|
||||
initialize_volume_component_from_points(
|
||||
params, storage, geometry_set, openvdb::GRID_FOG_VOLUME);
|
||||
initialize_volume_component_from_points(params, storage, geometry_set);
|
||||
});
|
||||
params.set_output("Volume", std::move(geometry_set));
|
||||
#else
|
||||
|
|
|
@ -34,8 +34,31 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
|
||||
static void search_link_ops(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
if (U.experimental.use_new_volume_nodes) {
|
||||
nodes::search_link_ops_for_basic_node(params);
|
||||
if (!U.experimental.use_new_volume_nodes) {
|
||||
return;
|
||||
}
|
||||
params.add_item(IFACE_("Volume"), [](LinkSearchOpParams ¶ms) {
|
||||
bNode &node = params.add_node("GeometryNodeStoreNamedGrid");
|
||||
params.update_and_connect_available_socket(node, "Volume");
|
||||
});
|
||||
if (params.in_out() == SOCK_IN) {
|
||||
if (params.other_socket().type == SOCK_STRING) {
|
||||
params.add_item(IFACE_("Name"), [](LinkSearchOpParams ¶ms) {
|
||||
bNode &node = params.add_node("GeometryNodeStoreNamedGrid");
|
||||
params.update_and_connect_available_socket(node, "Name");
|
||||
});
|
||||
}
|
||||
if (const std::optional<eCustomDataType> data_type = bke::socket_type_to_custom_data_type(
|
||||
eNodeSocketDatatype(params.other_socket().type)))
|
||||
{
|
||||
if (grid_type_supported(*data_type)) {
|
||||
params.add_item(IFACE_("Grid"), [data_type](LinkSearchOpParams ¶ms) {
|
||||
bNode &node = params.add_node("GeometryNodeStoreNamedGrid");
|
||||
node.custom1 = *data_type;
|
||||
params.update_and_connect_available_socket(node, "Grid");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue