Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Molenkamp <github@lazydodo.com>2022-10-05 18:46:18 +0300
committerRay Molenkamp <github@lazydodo.com>2022-10-05 18:46:18 +0300
commit42736e0b3f85dc248186dd6dc5349a99addc8c84 (patch)
treed0768a91d8ebfb50642034fdf8437199a5e420b7 /source/blender/io
parent42ce93a2cbc28836d22b7fa47e99aa3df76e1acc (diff)
parentb47a234f98dd7e6e0b53ad96b5b4d278635874d8 (diff)
Merge remote-tracking branch 'origin/master' into tmp-vfx-platform-2023
Diffstat (limited to 'source/blender/io')
-rw-r--r--source/blender/io/alembic/exporter/abc_archive.cc4
-rw-r--r--source/blender/io/alembic/exporter/abc_export_capi.cc4
-rw-r--r--source/blender/io/alembic/exporter/abc_subdiv_disabler.cc4
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_curves.cc2
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_hair.cc15
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.cc59
-rw-r--r--source/blender/io/alembic/intern/abc_customdata.cc17
-rw-r--r--source/blender/io/alembic/intern/abc_reader_camera.cc18
-rw-r--r--source/blender/io/alembic/intern/abc_reader_curves.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc88
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.h9
-rw-r--r--source/blender/io/alembic/intern/abc_reader_object.cc12
-rw-r--r--source/blender/io/alembic/intern/abc_reader_points.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_transform.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_util.cc4
-rw-r--r--source/blender/io/alembic/intern/alembic_capi.cc10
-rw-r--r--source/blender/io/avi/intern/avi.c16
-rw-r--r--source/blender/io/avi/intern/avi_mjpeg.c53
-rw-r--r--source/blender/io/avi/intern/avi_mjpeg.h7
-rw-r--r--source/blender/io/avi/intern/avi_rgb.c25
-rw-r--r--source/blender/io/avi/intern/avi_rgb32.c14
-rw-r--r--source/blender/io/collada/AnimationExporter.cpp2
-rw-r--r--source/blender/io/collada/AnimationImporter.cpp102
-rw-r--r--source/blender/io/collada/ArmatureExporter.cpp2
-rw-r--r--source/blender/io/collada/ArmatureImporter.cpp8
-rw-r--r--source/blender/io/collada/BCAnimationCurve.cpp13
-rw-r--r--source/blender/io/collada/BCMath.cpp8
-rw-r--r--source/blender/io/collada/BCSampleData.cpp2
-rw-r--r--source/blender/io/collada/BlenderContext.cpp28
-rw-r--r--source/blender/io/collada/BlenderContext.h8
-rw-r--r--source/blender/io/collada/CMakeLists.txt9
-rw-r--r--source/blender/io/collada/CameraExporter.cpp4
-rw-r--r--source/blender/io/collada/ControllerExporter.cpp7
-rw-r--r--source/blender/io/collada/DocumentImporter.cpp35
-rw-r--r--source/blender/io/collada/EffectExporter.cpp2
-rw-r--r--source/blender/io/collada/ExportSettings.h7
-rw-r--r--source/blender/io/collada/ExtraHandler.cpp4
-rw-r--r--source/blender/io/collada/ExtraTags.cpp6
-rw-r--r--source/blender/io/collada/GeometryExporter.cpp111
-rw-r--r--source/blender/io/collada/ImportSettings.h1
-rw-r--r--source/blender/io/collada/Materials.cpp2
-rw-r--r--source/blender/io/collada/MeshImporter.cpp215
-rw-r--r--source/blender/io/collada/MeshImporter.h6
-rw-r--r--source/blender/io/collada/SceneExporter.cpp8
-rw-r--r--source/blender/io/collada/SkinInfo.cpp14
-rw-r--r--source/blender/io/collada/TransformReader.cpp14
-rw-r--r--source/blender/io/collada/collada.cpp4
-rw-r--r--source/blender/io/collada/collada_internal.cpp14
-rw-r--r--source/blender/io/collada/collada_utils.cpp17
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator.cc9
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.cc21
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.hh2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc4
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_export_svg.cc2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_import_base.cc2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_import_svg.cc22
-rw-r--r--source/blender/io/stl/importer/stl_import.cc3
-rw-r--r--source/blender/io/stl/importer/stl_import_ascii_reader.cc2
-rw-r--r--source/blender/io/stl/importer/stl_import_mesh.cc25
-rw-r--r--source/blender/io/usd/CMakeLists.txt9
-rw-r--r--source/blender/io/usd/intern/usd_capi_export.cc5
-rw-r--r--source/blender/io/usd/intern/usd_capi_import.cc6
-rw-r--r--source/blender/io/usd/intern/usd_hierarchy_iterator.cc2
-rw-r--r--source/blender/io/usd/intern/usd_reader_camera.cc2
-rw-r--r--source/blender/io/usd/intern/usd_reader_curve.cc6
-rw-r--r--source/blender/io/usd/intern/usd_reader_curve.h2
-rw-r--r--source/blender/io/usd/intern/usd_reader_light.cc4
-rw-r--r--source/blender/io/usd/intern/usd_reader_material.cc7
-rw-r--r--source/blender/io/usd/intern/usd_reader_mesh.cc128
-rw-r--r--source/blender/io/usd/intern/usd_reader_mesh.h11
-rw-r--r--source/blender/io/usd/intern/usd_reader_nurbs.cc10
-rw-r--r--source/blender/io/usd/intern/usd_reader_nurbs.h2
-rw-r--r--source/blender/io/usd/intern/usd_reader_volume.cc6
-rw-r--r--source/blender/io/usd/intern/usd_reader_volume.h2
-rw-r--r--source/blender/io/usd/intern/usd_writer_hair.cc2
-rw-r--r--source/blender/io/usd/intern/usd_writer_material.cc4
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.cc73
-rw-r--r--source/blender/io/usd/intern/usd_writer_volume.cc4
-rw-r--r--source/blender/io/usd/usd.h2
-rw-r--r--source/blender/io/wavefront_obj/IO_wavefront_obj.h11
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc321
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh34
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_io.hh404
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc124
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh5
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc214
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh87
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_exporter.cc22
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc105
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_mesh.cc68
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_mtl.cc259
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_mtl.hh88
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_objects.hh2
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc4
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_importer.cc4
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc45
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh1
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_importer_tests.cc21
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc259
99 files changed, 1820 insertions, 1657 deletions
diff --git a/source/blender/io/alembic/exporter/abc_archive.cc b/source/blender/io/alembic/exporter/abc_archive.cc
index 9c8a36958d5..55e172db241 100644
--- a/source/blender/io/alembic/exporter/abc_archive.cc
+++ b/source/blender/io/alembic/exporter/abc_archive.cc
@@ -130,13 +130,13 @@ static TimeSamplingPtr create_time_sampling(double scene_fps,
get_shutter_samples(scene_fps, params, nr_of_samples, true, samples);
- TimeSamplingType ts(static_cast<uint32_t>(samples.size()), 1.0 / scene_fps);
+ TimeSamplingType ts(uint32_t(samples.size()), 1.0 / scene_fps);
return TimeSamplingPtr(new TimeSampling(ts, samples)); // NOLINT: modernize-make-shared
}
static void get_frames(double scene_fps,
const AlembicExportParams &params,
- unsigned int nr_of_samples,
+ uint nr_of_samples,
std::set<double> &r_frames)
{
/* Get one set of shutter samples, then add those around each frame to export. */
diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc
index dfca89e2c6d..546bc9d49cc 100644
--- a/source/blender/io/alembic/exporter/abc_export_capi.cc
+++ b/source/blender/io/alembic/exporter/abc_export_capi.cc
@@ -144,8 +144,8 @@ static void export_startjob(void *customdata,
}
/* Update the scene for the next frame to render. */
- scene->r.cfra = static_cast<int>(frame);
- scene->r.subframe = static_cast<float>(frame - scene->r.cfra);
+ scene->r.cfra = int(frame);
+ scene->r.subframe = float(frame - scene->r.cfra);
BKE_scene_graph_update_for_newframe(data->depsgraph);
CLOG_INFO(&LOG, 2, "Exporting frame %.2f", frame);
diff --git a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
index 514ce389e36..712b04f3992 100644
--- a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
+++ b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
@@ -14,6 +14,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
+#include "BKE_layer.h"
#include "BKE_modifier.h"
namespace blender::io::alembic {
@@ -34,7 +35,8 @@ void SubdivModifierDisabler::disable_modifiers()
Scene *scene = DEG_get_input_scene(depsgraph_);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph_);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_MESH) {
diff --git a/source/blender/io/alembic/exporter/abc_writer_curves.cc b/source/blender/io/alembic/exporter/abc_writer_curves.cc
index 4717d3ec26e..e5e8053d7d3 100644
--- a/source/blender/io/alembic/exporter/abc_writer_curves.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_curves.cc
@@ -142,7 +142,7 @@ void ABCCurveWriter::do_write(HierarchyContext &context)
}
}
- orders.push_back(static_cast<uint8_t>(nurbs->orderu));
+ orders.push_back(uint8_t(nurbs->orderu));
vert_counts.push_back(verts.size() - current_point_count);
}
diff --git a/source/blender/io/alembic/exporter/abc_writer_hair.cc b/source/blender/io/alembic/exporter/abc_writer_hair.cc
index 99c609b0235..f872943ad5c 100644
--- a/source/blender/io/alembic/exporter/abc_writer_hair.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_hair.cc
@@ -120,9 +120,9 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context,
float inv_mat[4][4];
invert_m4_m4_safe(inv_mat, context.object->obmat);
- MTFace *mtface = mesh->mtface;
- MFace *mface = mesh->mface;
- MVert *mverts = mesh->mvert;
+ MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE);
+ MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ const MVert *mverts = BKE_mesh_verts(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
if ((!mtface || !mface) && !uv_warning_shown_) {
@@ -190,7 +190,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context,
for (int n = 0; n < mesh->totface; n++) {
MFace *face = &mface[n];
MTFace *tface = mtface + n;
- unsigned int vtx[4];
+ uint vtx[4];
vtx[0] = face->v1;
vtx[1] = face->v2;
vtx[2] = face->v3;
@@ -243,8 +243,9 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context,
float inv_mat[4][4];
invert_m4_m4_safe(inv_mat, context.object->obmat);
- MTFace *mtface = mesh->mtface;
- MVert *mverts = mesh->mvert;
+ MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE);
+ const MVert *mverts = BKE_mesh_verts(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
ParticleSystem *psys = context.particle_system;
@@ -269,7 +270,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context,
continue;
}
- MFace *face = &mesh->mface[num];
+ MFace *face = &mface[num];
MTFace *tface = mtface + num;
float r_uv[2], tmpnor[3], mapfw[4], vec[3];
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
index 07b185ffd64..084d26198bc 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
@@ -12,6 +12,7 @@
#include "BLI_math_vector.h"
#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
@@ -175,8 +176,8 @@ void ABCGenericMeshWriter::do_write(HierarchyContext &context)
m_custom_data_config.pack_uvs = args_.export_params->packuv;
m_custom_data_config.mesh = mesh;
- m_custom_data_config.mpoly = mesh->mpoly;
- m_custom_data_config.mloop = mesh->mloop;
+ m_custom_data_config.mpoly = mesh->polys_for_write().data();
+ m_custom_data_config.mloop = mesh->loops_for_write().data();
m_custom_data_config.totpoly = mesh->totpoly;
m_custom_data_config.totloop = mesh->totloop;
m_custom_data_config.totvert = mesh->totvert;
@@ -366,7 +367,7 @@ bool ABCGenericMeshWriter::get_velocities(struct Mesh *mesh, std::vector<Imath::
{
/* Export velocity attribute output by fluid sim, sequence cache modifier
* and geometry nodes. */
- CustomDataLayer *velocity_layer = BKE_id_attribute_find(
+ const CustomDataLayer *velocity_layer = BKE_id_attribute_find(
&mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT);
if (velocity_layer == nullptr) {
@@ -390,12 +391,12 @@ void ABCGenericMeshWriter::get_geo_groups(Object *object,
struct Mesh *mesh,
std::map<std::string, std::vector<int32_t>> &geo_groups)
{
- const int num_poly = mesh->totpoly;
- MPoly *polygons = mesh->mpoly;
+ const bke::AttributeAccessor attributes = mesh->attributes();
+ const VArraySpan<int> material_indices = attributes.lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
- for (int i = 0; i < num_poly; i++) {
- MPoly &current_poly = polygons[i];
- short mnr = current_poly.mat_nr;
+ for (const int i : material_indices.index_range()) {
+ short mnr = material_indices[i];
Material *mat = BKE_object_material_get(object, mnr + 1);
@@ -435,8 +436,7 @@ static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points)
points.clear();
points.resize(mesh->totvert);
- MVert *verts = mesh->mvert;
-
+ const Span<MVert> verts = mesh->verts();
for (int i = 0, e = mesh->totvert; i < e; i++) {
copy_yup_from_zup(points[i].getValue(), verts[i].co);
}
@@ -447,25 +447,23 @@ static void get_topology(struct Mesh *mesh,
std::vector<int32_t> &loop_counts,
bool &r_has_flat_shaded_poly)
{
- const int num_poly = mesh->totpoly;
- const int num_loops = mesh->totloop;
- MLoop *mloop = mesh->mloop;
- MPoly *mpoly = mesh->mpoly;
+ const Span<MPoly> polys = mesh->polys();
+ const Span<MLoop> loops = mesh->loops();
r_has_flat_shaded_poly = false;
poly_verts.clear();
loop_counts.clear();
- poly_verts.reserve(num_loops);
- loop_counts.reserve(num_poly);
+ poly_verts.reserve(loops.size());
+ loop_counts.reserve(polys.size());
/* NOTE: data needs to be written in the reverse order. */
- for (int i = 0; i < num_poly; i++) {
- MPoly &poly = mpoly[i];
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
loop_counts.push_back(poly.totloop);
r_has_flat_shaded_poly |= (poly.flag & ME_SMOOTH) == 0;
- MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1);
+ const MLoop *loop = &loops[poly.loopstart + (poly.totloop - 1)];
for (int j = 0; j < poly.totloop; j++, loop--) {
poly_verts.push_back(loop->v);
@@ -478,20 +476,21 @@ static void get_edge_creases(struct Mesh *mesh,
std::vector<int32_t> &lengths,
std::vector<float> &sharpnesses)
{
- const float factor = 1.0f / 255.0f;
-
indices.clear();
lengths.clear();
sharpnesses.clear();
- MEdge *edge = mesh->medge;
-
- for (int i = 0, e = mesh->totedge; i < e; i++) {
- const float sharpness = static_cast<float>(edge[i].crease) * factor;
+ const float *creases = static_cast<const float *>(CustomData_get_layer(&mesh->edata, CD_CREASE));
+ if (!creases) {
+ return;
+ }
+ const Span<MEdge> edges = mesh->edges();
+ for (const int i : edges.index_range()) {
+ const float sharpness = creases[i];
if (sharpness != 0.0f) {
- indices.push_back(edge[i].v1);
- indices.push_back(edge[i].v2);
+ indices.push_back(edges[i].v1);
+ indices.push_back(edges[i].v2);
sharpnesses.push_back(sharpness);
}
}
@@ -543,8 +542,10 @@ static void get_loop_normals(struct Mesh *mesh,
/* NOTE: data needs to be written in the reverse order. */
int abc_index = 0;
- MPoly *mp = mesh->mpoly;
- for (int i = 0, e = mesh->totpoly; i < e; i++, mp++) {
+ const Span<MPoly> polys = mesh->polys();
+
+ for (const int i : polys.index_range()) {
+ const MPoly *mp = &polys[i];
for (int j = mp->totloop - 1; j >= 0; j--, abc_index++) {
int blender_index = mp->loopstart + j;
copy_yup_from_zup(normals[abc_index].getValue(), lnors[blender_index]);
diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc
index 2820a128072..3349f9fc30b 100644
--- a/source/blender/io/alembic/intern/abc_customdata.cc
+++ b/source/blender/io/alembic/intern/abc_customdata.cc
@@ -57,7 +57,7 @@ static void get_uvs(const CDStreamConfig &config,
}
const int num_poly = config.totpoly;
- MPoly *polygons = config.mpoly;
+ MPoly *mpoly = config.mpoly;
MLoop *mloop = config.mloop;
if (!config.pack_uvs) {
@@ -67,7 +67,7 @@ static void get_uvs(const CDStreamConfig &config,
/* Iterate in reverse order to match exported polygons. */
for (int i = 0; i < num_poly; i++) {
- MPoly &current_poly = polygons[i];
+ MPoly &current_poly = mpoly[i];
const MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
for (int j = 0; j < current_poly.totloop; j++, count++) {
@@ -85,7 +85,7 @@ static void get_uvs(const CDStreamConfig &config,
int idx_count = 0;
for (int i = 0; i < num_poly; i++) {
- MPoly &current_poly = polygons[i];
+ MPoly &current_poly = mpoly[i];
MLoop *looppoly = mloop + current_poly.loopstart + current_poly.totloop;
const MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
@@ -322,14 +322,14 @@ static void read_uvs(const CDStreamConfig &config,
MLoop *mloops = config.mloop;
MLoopUV *mloopuvs = static_cast<MLoopUV *>(data);
- unsigned int uv_index, loop_index, rev_loop_index;
+ uint uv_index, loop_index, rev_loop_index;
BLI_assert(uv_scope != ABC_UV_SCOPE_NONE);
const bool do_uvs_per_loop = (uv_scope == ABC_UV_SCOPE_LOOP);
for (int i = 0; i < config.totpoly; i++) {
MPoly &poly = mpolys[i];
- unsigned int rev_loop_offset = poly.loopstart + poly.totloop - 1;
+ uint rev_loop_offset = poly.loopstart + poly.totloop - 1;
for (int f = 0; f < poly.totloop; f++) {
rev_loop_index = rev_loop_offset - f;
@@ -540,7 +540,7 @@ void read_generated_coordinates(const ICompoundProperty &prop,
cd_data = CustomData_get_layer(&mesh->vdata, CD_ORCO);
}
else {
- cd_data = CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_CALLOC, nullptr, totvert);
+ cd_data = CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_CONSTRUCT, nullptr, totvert);
}
float(*orcodata)[3] = static_cast<float(*)[3]>(cd_data);
@@ -564,7 +564,6 @@ void read_custom_data(const std::string &iobject_full_name,
}
int num_uvs = 0;
- int num_colors = 0;
const size_t num_props = prop.getNumProperties();
@@ -583,10 +582,6 @@ void read_custom_data(const std::string &iobject_full_name,
/* Read vertex colors according to convention. */
if (IC3fGeomParam::matches(prop_header) || IC4fGeomParam::matches(prop_header)) {
- if (++num_colors > MAX_MCOL) {
- continue;
- }
-
read_custom_data_mcols(iobject_full_name, prop, prop_header, config, iss);
continue;
}
diff --git a/source/blender/io/alembic/intern/abc_reader_camera.cc b/source/blender/io/alembic/intern/abc_reader_camera.cc
index 830526a11ac..e7a319730b6 100644
--- a/source/blender/io/alembic/intern/abc_reader_camera.cc
+++ b/source/blender/io/alembic/intern/abc_reader_camera.cc
@@ -77,11 +77,11 @@ void AbcCameraReader::readObjectData(Main *bmain, const ISampleSelector &sample_
bcam->stereo.convergence_distance = convergence_plane.getValue(sample_sel);
}
- const float lens = static_cast<float>(cam_sample.getFocalLength());
- const float apperture_x = static_cast<float>(cam_sample.getHorizontalAperture());
- const float apperture_y = static_cast<float>(cam_sample.getVerticalAperture());
- const float h_film_offset = static_cast<float>(cam_sample.getHorizontalFilmOffset());
- const float v_film_offset = static_cast<float>(cam_sample.getVerticalFilmOffset());
+ const float lens = float(cam_sample.getFocalLength());
+ const float apperture_x = float(cam_sample.getHorizontalAperture());
+ const float apperture_y = float(cam_sample.getVerticalAperture());
+ const float h_film_offset = float(cam_sample.getHorizontalFilmOffset());
+ const float v_film_offset = float(cam_sample.getVerticalFilmOffset());
const float film_aspect = apperture_x / apperture_y;
bcam->lens = lens;
@@ -89,10 +89,10 @@ void AbcCameraReader::readObjectData(Main *bmain, const ISampleSelector &sample_
bcam->sensor_y = apperture_y * 10;
bcam->shiftx = h_film_offset / apperture_x;
bcam->shifty = v_film_offset / apperture_y / film_aspect;
- bcam->clip_start = max_ff(0.1f, static_cast<float>(cam_sample.getNearClippingPlane()));
- bcam->clip_end = static_cast<float>(cam_sample.getFarClippingPlane());
- bcam->dof.focus_distance = static_cast<float>(cam_sample.getFocusDistance());
- bcam->dof.aperture_fstop = static_cast<float>(cam_sample.getFStop());
+ bcam->clip_start = max_ff(0.1f, float(cam_sample.getNearClippingPlane()));
+ bcam->clip_end = float(cam_sample.getFarClippingPlane());
+ bcam->dof.focus_distance = float(cam_sample.getFocusDistance());
+ bcam->dof.aperture_fstop = float(cam_sample.getFStop());
m_object = BKE_object_add_only_object(bmain, OB_CAMERA, m_object_name.c_str());
m_object->data = bcam;
diff --git a/source/blender/io/alembic/intern/abc_reader_curves.cc b/source/blender/io/alembic/intern/abc_reader_curves.cc
index d8859acdf5f..24bdae3ac50 100644
--- a/source/blender/io/alembic/intern/abc_reader_curves.cc
+++ b/source/blender/io/alembic/intern/abc_reader_curves.cc
@@ -152,7 +152,7 @@ void AbcCurveReader::read_curve_sample(Curve *cu,
break;
case Alembic::AbcGeom::kVariableOrder:
if (orders && orders->size() > i) {
- nu->orderu = static_cast<short>((*orders)[i]);
+ nu->orderu = short((*orders)[i]);
break;
}
ATTR_FALLTHROUGH;
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index bacc1f06599..f08514dc45c 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -25,7 +25,8 @@
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
-#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
@@ -93,6 +94,7 @@ static void assign_materials(Main *bmain,
mat_iter = matname_to_material.find(mat_name);
if (mat_iter == matname_to_material.end()) {
assigned_mat = BKE_material_add(bmain, mat_name.c_str());
+ id_us_min(&assigned_mat->id);
matname_to_material[mat_name] = assigned_mat;
}
else {
@@ -101,6 +103,9 @@ static void assign_materials(Main *bmain,
BKE_object_material_assign_single_obdata(bmain, ob, assigned_mat, mat_index);
}
+ if (ob->totcol > 0) {
+ ob->actcol = 1;
+ }
}
} /* namespace utils */
@@ -128,10 +133,8 @@ static void read_mverts_interp(MVert *mverts,
const Imath::V3f &floor_pos = (*positions)[i];
const Imath::V3f &ceil_pos = (*ceil_positions)[i];
- interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), static_cast<float>(weight));
+ interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), float(weight));
copy_zup_from_yup(mvert.co, tmp);
-
- mvert.bweight = 0;
}
}
@@ -152,13 +155,12 @@ static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
void read_mverts(Mesh &mesh, const P3fArraySamplePtr positions, const N3fArraySamplePtr normals)
{
+ MutableSpan<MVert> verts = mesh.verts_for_write();
for (int i = 0; i < positions->size(); i++) {
- MVert &mvert = mesh.mvert[i];
+ MVert &mvert = verts[i];
Imath::V3f pos_in = (*positions)[i];
copy_zup_from_yup(mvert.co, pos_in.getValue());
-
- mvert.bweight = 0;
}
if (normals) {
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(&mesh);
@@ -186,9 +188,9 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
const bool do_uvs = (mloopuvs && uvs && uvs_indices);
const bool do_uvs_per_loop = do_uvs && mesh_data.uv_scope == ABC_UV_SCOPE_LOOP;
BLI_assert(!do_uvs || mesh_data.uv_scope != ABC_UV_SCOPE_NONE);
- unsigned int loop_index = 0;
- unsigned int rev_loop_index = 0;
- unsigned int uv_index = 0;
+ uint loop_index = 0;
+ uint rev_loop_index = 0;
+ uint uv_index = 0;
bool seen_invalid_geometry = false;
for (int i = 0; i < face_counts->size(); i++) {
@@ -269,7 +271,7 @@ static void process_loop_normals(CDStreamConfig &config, const N3fArraySamplePtr
float(*lnors)[3] = static_cast<float(*)[3]>(
MEM_malloc_arrayN(loop_count, sizeof(float[3]), "ABC::FaceNormals"));
- MPoly *mpoly = mesh->mpoly;
+ MPoly *mpoly = mesh->polys_for_write().data();
const N3fArraySample &loop_normals = *loop_normals_ptr;
int abc_index = 0;
for (int i = 0, e = mesh->totpoly; i < e; i++, mpoly++) {
@@ -304,7 +306,7 @@ static void process_vertex_normals(CDStreamConfig &config,
}
config.mesh->flag |= ME_AUTOSMOOTH;
- BKE_mesh_set_custom_normals_from_vertices(config.mesh, vnors);
+ BKE_mesh_set_custom_normals_from_verts(config.mesh, vnors);
MEM_freeN(vnors);
}
@@ -391,7 +393,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type)
/* Create a new layer. */
int numloops = mesh->totloop;
cd_ptr = CustomData_add_layer_named(
- &mesh->ldata, cd_data_type, CD_DEFAULT, nullptr, numloops, name);
+ &mesh->ldata, cd_data_type, CD_SET_DEFAULT, nullptr, numloops, name);
return cd_ptr;
}
@@ -446,7 +448,7 @@ static void read_velocity(const V3fArraySamplePtr &velocities,
const CDStreamConfig &config,
const float velocity_scale)
{
- const int num_velocity_vectors = static_cast<int>(velocities->size());
+ const int num_velocity_vectors = int(velocities->size());
if (num_velocity_vectors != config.mesh->totvert) {
/* Files containing videogrammetry data may be malformed and export velocity data on missing
* frames (most likely by copying the last valid data). */
@@ -514,13 +516,10 @@ static void read_mesh_sample(const std::string &iobject_full_name,
CDStreamConfig get_config(Mesh *mesh, const bool use_vertex_interpolation)
{
CDStreamConfig config;
-
- BLI_assert(mesh->mvert || mesh->totvert == 0);
-
config.mesh = mesh;
- config.mvert = mesh->mvert;
- config.mloop = mesh->mloop;
- config.mpoly = mesh->mpoly;
+ config.mvert = mesh->verts_for_write().data();
+ config.mloop = mesh->loops_for_write().data();
+ config.mpoly = mesh->polys_for_write().data();
config.totvert = mesh->totvert;
config.totloop = mesh->totloop;
config.totpoly = mesh->totpoly;
@@ -616,11 +615,7 @@ void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, "", 0.0f, nullptr);
if (read_mesh != mesh) {
- /* XXX FIXME: after 2.80; mesh->flag isn't copied by #BKE_mesh_nomain_to_mesh(). */
- /* read_mesh can be freed by BKE_mesh_nomain_to_mesh(), so get the flag before that happens. */
- uint16_t autosmooth = (read_mesh->flag & ME_AUTOSMOOTH);
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_EVERYTHING, true);
- mesh->flag |= autosmooth;
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object);
}
if (m_settings->validate_meshes) {
@@ -766,7 +761,11 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
size_t num_polys = new_mesh->totpoly;
if (num_polys > 0) {
std::map<std::string, int> mat_map;
- assign_facesets_to_mpoly(sample_sel, new_mesh->mpoly, num_polys, mat_map);
+ bke::MutableAttributeAccessor attributes = new_mesh->attributes_for_write();
+ bke::SpanAttributeWriter<int> material_indices =
+ attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ assign_facesets_to_material_indices(sample_sel, material_indices.span, mat_map);
+ material_indices.finish();
}
return new_mesh;
@@ -775,10 +774,9 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
return existing_mesh;
}
-void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
- MPoly *mpoly,
- int totpoly,
- std::map<std::string, int> &r_mat_map)
+void AbcMeshReader::assign_facesets_to_material_indices(const ISampleSelector &sample_sel,
+ MutableSpan<int> material_indices,
+ std::map<std::string, int> &r_mat_map)
{
std::vector<std::string> face_sets;
m_schema.getFaceSetNames(face_sets);
@@ -811,13 +809,12 @@ void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
for (size_t l = 0; l < num_group_faces; l++) {
size_t pos = (*group_faces)[l];
- if (pos >= totpoly) {
+ if (pos >= material_indices.size()) {
std::cerr << "Faceset overflow on " << faceset.getName() << '\n';
break;
}
- MPoly &poly = mpoly[pos];
- poly.mat_nr = assigned_mat - 1;
+ material_indices[pos] = assigned_mat - 1;
}
}
}
@@ -825,7 +822,11 @@ void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const ISampleSelector &sample_sel)
{
std::map<std::string, int> mat_map;
- assign_facesets_to_mpoly(sample_sel, mesh->mpoly, mesh->totpoly, mat_map);
+ bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ bke::SpanAttributeWriter<int> material_indices =
+ attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ assign_facesets_to_material_indices(sample_sel, material_indices.span, mat_map);
+ material_indices.finish();
utils::assign_materials(bmain, m_object, mat_map);
}
@@ -890,7 +891,7 @@ static void read_vertex_creases(Mesh *mesh,
}
float *vertex_crease_data = (float *)CustomData_add_layer(
- &mesh->vdata, CD_CREASE, CD_DEFAULT, nullptr, mesh->totvert);
+ &mesh->vdata, CD_CREASE, CD_SET_DEFAULT, nullptr, mesh->totvert);
const int totvert = mesh->totvert;
for (int i = 0, v = indices->size(); i < v; ++i) {
@@ -902,8 +903,6 @@ static void read_vertex_creases(Mesh *mesh,
vertex_crease_data[idx] = (*sharpnesses)[i];
}
-
- mesh->cd_flag |= ME_CDFLAG_VERT_CREASE;
}
static void read_edge_creases(Mesh *mesh,
@@ -914,12 +913,13 @@ static void read_edge_creases(Mesh *mesh,
return;
}
- MEdge *edges = mesh->medge;
- const int totedge = mesh->totedge;
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, edges.size());
- EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, mesh->totedge);
+ float *creases = static_cast<float *>(
+ CustomData_add_layer(&mesh->edata, CD_CREASE, CD_SET_DEFAULT, nullptr, edges.size()));
- for (int i = 0; i < totedge; i++) {
+ for (const int i : edges.index_range()) {
MEdge *edge = &edges[i];
BLI_edgehash_insert(edge_hash, edge->v1, edge->v2, edge);
}
@@ -940,13 +940,11 @@ static void read_edge_creases(Mesh *mesh,
}
if (edge) {
- edge->crease = unit_float_to_uchar_clamp((*sharpnesses)[s]);
+ creases[edge - edges.data()] = unit_float_to_uchar_clamp((*sharpnesses)[s]);
}
}
BLI_edgehash_free(edge_hash, nullptr);
-
- mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
}
/* ************************************************************************** */
@@ -996,7 +994,7 @@ void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, "", 0.0f, nullptr);
if (read_mesh != mesh) {
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_EVERYTHING, true);
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object);
}
ISubDSchema::Sample sample;
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.h b/source/blender/io/alembic/intern/abc_reader_mesh.h
index f97525297b7..151f4d82226 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.h
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.h
@@ -5,6 +5,8 @@
* \ingroup balembic
*/
+#include "BLI_span.hh"
+
#include "abc_customdata.h"
#include "abc_reader_object.h"
@@ -38,10 +40,9 @@ class AbcMeshReader final : public AbcObjectReader {
Mesh *mesh,
const Alembic::AbcGeom::ISampleSelector &sample_sel);
- void assign_facesets_to_mpoly(const Alembic::Abc::ISampleSelector &sample_sel,
- MPoly *mpoly,
- int totpoly,
- std::map<std::string, int> &r_mat_map);
+ void assign_facesets_to_material_indices(const Alembic::Abc::ISampleSelector &sample_sel,
+ MutableSpan<int> material_indices,
+ std::map<std::string, int> &r_mat_map);
};
class AbcSubDReader final : public AbcObjectReader {
diff --git a/source/blender/io/alembic/intern/abc_reader_object.cc b/source/blender/io/alembic/intern/abc_reader_object.cc
index db056c0eef6..af26565f8d6 100644
--- a/source/blender/io/alembic/intern/abc_reader_object.cc
+++ b/source/blender/io/alembic/intern/abc_reader_object.cc
@@ -110,7 +110,7 @@ static Imath::M44d blend_matrices(const Imath::M44d &m0,
convert_matrix_datatype(m0, mat0);
convert_matrix_datatype(m1, mat1);
- interp_m4_m4m4(ret, mat0, mat1, static_cast<float>(weight));
+ interp_m4_m4m4(ret, mat0, mat1, float(weight));
return convert_matrix_datatype(ret);
}
@@ -133,11 +133,11 @@ Imath::M44d get_matrix(const IXformSchema &schema, const chrono_t time)
}
struct Mesh *AbcObjectReader::read_mesh(struct Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &UNUSED(sample_sel),
- int UNUSED(read_flag),
- const char *UNUSED(velocity_name),
- const float UNUSED(velocity_scale),
- const char **UNUSED(err_str))
+ const Alembic::Abc::ISampleSelector & /*sample_sel*/,
+ int /*read_flag*/,
+ const char * /*velocity_name*/,
+ const float /*velocity_scale*/,
+ const char ** /*err_str*/)
{
return existing_mesh;
}
diff --git a/source/blender/io/alembic/intern/abc_reader_points.cc b/source/blender/io/alembic/intern/abc_reader_points.cc
index ff189bc92dc..54ae71ad7a6 100644
--- a/source/blender/io/alembic/intern/abc_reader_points.cc
+++ b/source/blender/io/alembic/intern/abc_reader_points.cc
@@ -69,7 +69,7 @@ void AbcPointsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSel
Mesh *read_mesh = this->read_mesh(mesh, sample_sel, 0, "", 0.0f, nullptr);
if (read_mesh != mesh) {
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object);
}
if (m_settings->validate_meshes) {
diff --git a/source/blender/io/alembic/intern/abc_reader_transform.cc b/source/blender/io/alembic/intern/abc_reader_transform.cc
index 0d3227fc718..71682531378 100644
--- a/source/blender/io/alembic/intern/abc_reader_transform.cc
+++ b/source/blender/io/alembic/intern/abc_reader_transform.cc
@@ -55,7 +55,7 @@ bool AbcEmptyReader::accepts_object_type(
return true;
}
-void AbcEmptyReader::readObjectData(Main *bmain, const ISampleSelector &UNUSED(sample_sel))
+void AbcEmptyReader::readObjectData(Main *bmain, const ISampleSelector & /*sample_sel*/)
{
m_object = BKE_object_add_only_object(bmain, OB_EMPTY, m_object_name.c_str());
m_object->data = nullptr;
diff --git a/source/blender/io/alembic/intern/abc_util.cc b/source/blender/io/alembic/intern/abc_util.cc
index 90f73d25c22..846a3622d62 100644
--- a/source/blender/io/alembic/intern/abc_util.cc
+++ b/source/blender/io/alembic/intern/abc_util.cc
@@ -73,7 +73,7 @@ Imath::M44d convert_matrix_datatype(float mat[4][4])
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- m[i][j] = static_cast<double>(mat[i][j]);
+ m[i][j] = double(mat[i][j]);
}
}
@@ -84,7 +84,7 @@ void convert_matrix_datatype(const Imath::M44d &xform, float r_mat[4][4])
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- r_mat[i][j] = static_cast<float>(xform[i][j]);
+ r_mat[i][j] = float(xform[i][j]);
}
}
}
diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc
index 86622719f6e..39595089109 100644
--- a/source/blender/io/alembic/intern/alembic_capi.cc
+++ b/source/blender/io/alembic/intern/alembic_capi.cc
@@ -502,7 +502,7 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
/* Create objects and set scene frame range. */
- const float size = static_cast<float>(data->readers.size());
+ const float size = float(data->readers.size());
size_t i = 0;
chrono_t min_time = std::numeric_limits<chrono_t>::max();
@@ -542,8 +542,8 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
scene->r.cfra = scene->r.sfra;
}
else if (min_time < max_time) {
- scene->r.sfra = static_cast<int>(round(min_time * FPS));
- scene->r.efra = static_cast<int>(round(max_time * FPS));
+ scene->r.sfra = int(round(min_time * FPS));
+ scene->r.efra = int(round(max_time * FPS));
scene->r.cfra = scene->r.sfra;
}
}
@@ -601,9 +601,10 @@ static void import_endjob(void *user_data)
else {
Base *base;
LayerCollection *lc;
+ const Scene *scene = data->scene;
ViewLayer *view_layer = data->view_layer;
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
lc = BKE_layer_collection_get_active(view_layer);
@@ -616,6 +617,7 @@ static void import_endjob(void *user_data)
/* Sync the collection, and do view layer operations. */
BKE_layer_collection_resync_allow();
BKE_main_collection_sync(data->bmain);
+ BKE_view_layer_synced_ensure(scene, view_layer);
for (AbcObjectReader *reader : data->readers) {
Object *ob = reader->object();
base = BKE_view_layer_base_find(view_layer, ob);
diff --git a/source/blender/io/avi/intern/avi.c b/source/blender/io/avi/intern/avi.c
index 8bf4f8124a3..298aa9c8dfa 100644
--- a/source/blender/io/avi/intern/avi.c
+++ b/source/blender/io/avi/intern/avi.c
@@ -38,14 +38,14 @@ static char DEBUG_FCC[4];
(void)0
/* local functions */
-char *fcc_to_char(unsigned int fcc);
-char *tcc_to_char(unsigned int tcc);
+char *fcc_to_char(uint fcc);
+char *tcc_to_char(uint tcc);
/* implementation */
-unsigned int GET_FCC(FILE *fp)
+uint GET_FCC(FILE *fp)
{
- unsigned char tmp[4];
+ uchar tmp[4];
tmp[0] = getc(fp);
tmp[1] = getc(fp);
@@ -55,7 +55,7 @@ unsigned int GET_FCC(FILE *fp)
return FCC(tmp);
}
-unsigned int GET_TCC(FILE *fp)
+uint GET_TCC(FILE *fp)
{
char tmp[5];
@@ -67,7 +67,7 @@ unsigned int GET_TCC(FILE *fp)
return FCC(tmp);
}
-char *fcc_to_char(unsigned int fcc)
+char *fcc_to_char(uint fcc)
{
DEBUG_FCC[0] = (fcc)&127;
DEBUG_FCC[1] = (fcc >> 8) & 127;
@@ -77,7 +77,7 @@ char *fcc_to_char(unsigned int fcc)
return DEBUG_FCC;
}
-char *tcc_to_char(unsigned int tcc)
+char *tcc_to_char(uint tcc)
{
DEBUG_FCC[0] = (tcc)&127;
DEBUG_FCC[1] = (tcc >> 8) & 127;
@@ -917,7 +917,7 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...)
va_start(ap, frame_num);
for (stream = 0; stream < movie->header->Streams; stream++) {
- unsigned int tbuf = 0;
+ uint tbuf = 0;
format = va_arg(ap, AviFormat);
buffer = va_arg(ap, void *);
diff --git a/source/blender/io/avi/intern/avi_mjpeg.c b/source/blender/io/avi/intern/avi_mjpeg.c
index fb42274fef2..de75fe8d69e 100644
--- a/source/blender/io/avi/intern/avi_mjpeg.c
+++ b/source/blender/io/avi/intern/avi_mjpeg.c
@@ -22,10 +22,8 @@
#include "avi_mjpeg.h"
-static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize);
-static void jpegmemsrcmgr_build(j_decompress_ptr dinfo,
- const unsigned char *buffer,
- size_t bufsize);
+static void jpegmemdestmgr_build(j_compress_ptr cinfo, uchar *buffer, size_t bufsize);
+static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, const uchar *buffer, size_t bufsize);
static size_t numbytes;
@@ -215,11 +213,7 @@ static void std_huff_tables(j_decompress_ptr dinfo)
sizeof(val_ac_chrominance));
}
-static int Decode_JPEG(unsigned char *inBuffer,
- unsigned char *outBuffer,
- unsigned int width,
- unsigned int height,
- size_t bufsize)
+static int Decode_JPEG(uchar *inBuffer, uchar *outBuffer, uint width, uint height, size_t bufsize)
{
struct jpeg_decompress_struct dinfo;
struct jpeg_error_mgr jerr;
@@ -272,16 +266,12 @@ static int Decode_JPEG(unsigned char *inBuffer,
return 1;
}
-static void Compress_JPEG(int quality,
- unsigned char *outbuffer,
- const unsigned char *inBuffer,
- int width,
- int height,
- size_t bufsize)
+static void Compress_JPEG(
+ int quality, uchar *outbuffer, const uchar *inBuffer, int width, int height, size_t bufsize)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
- unsigned char marker[60];
+ uchar marker[60];
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
@@ -339,7 +329,7 @@ static void Compress_JPEG(int quality,
jpeg_destroy_compress(&cinfo);
}
-static void interlace(unsigned char *to, unsigned char *from, int width, int height)
+static void interlace(uchar *to, uchar *from, int width, int height)
{
size_t i, rowstride = width * 3;
@@ -353,7 +343,7 @@ static void interlace(unsigned char *to, unsigned char *from, int width, int hei
}
}
-static void deinterlace(int odd, unsigned char *to, unsigned char *from, int width, int height)
+static void deinterlace(int odd, uchar *to, uchar *from, int width, int height)
{
size_t i, rowstride = width * 3;
@@ -367,20 +357,17 @@ static void deinterlace(int odd, unsigned char *to, unsigned char *from, int wid
}
}
-void *avi_converter_from_mjpeg(AviMovie *movie,
- int stream,
- unsigned char *buffer,
- const size_t *size)
+void *avi_converter_from_mjpeg(AviMovie *movie, int stream, uchar *buffer, const size_t *size)
{
int deint;
- unsigned char *buf;
+ uchar *buf;
(void)stream; /* unused */
buf = imb_alloc_pixels(movie->header->Height,
movie->header->Width,
3,
- sizeof(unsigned char),
+ sizeof(uchar),
"avi.avi_converter_from_mjpeg 1");
if (!buf) {
return NULL;
@@ -394,7 +381,7 @@ void *avi_converter_from_mjpeg(AviMovie *movie,
buffer = imb_alloc_pixels(movie->header->Height,
movie->header->Width,
3,
- sizeof(unsigned char),
+ sizeof(uchar),
"avi.avi_converter_from_mjpeg 2");
if (buffer) {
interlace(buffer, buf, movie->header->Width, movie->header->Height);
@@ -407,9 +394,9 @@ void *avi_converter_from_mjpeg(AviMovie *movie,
return buf;
}
-void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_to_mjpeg(AviMovie *movie, int stream, uchar *buffer, size_t *size)
{
- unsigned char *buf;
+ uchar *buf;
size_t bufsize = *size;
numbytes = 0;
@@ -418,7 +405,7 @@ void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer,
buf = imb_alloc_pixels(movie->header->Height,
movie->header->Width,
3,
- sizeof(unsigned char),
+ sizeof(uchar),
"avi.avi_converter_to_mjpeg 1");
if (!buf) {
return NULL;
@@ -441,7 +428,7 @@ void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer,
buf = imb_alloc_pixels(movie->header->Height,
movie->header->Width,
3,
- sizeof(unsigned char),
+ sizeof(uchar),
"avi.avi_converter_to_mjpeg 1");
if (buf) {
@@ -488,7 +475,7 @@ static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo)
MEM_freeN(cinfo->dest);
}
-static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize)
+static void jpegmemdestmgr_build(j_compress_ptr cinfo, uchar *buffer, size_t bufsize)
{
cinfo->dest = MEM_mallocN(sizeof(*(cinfo->dest)), "avi.jpegmemdestmgr_build");
@@ -511,7 +498,7 @@ static void jpegmemsrcmgr_init_source(j_decompress_ptr dinfo)
static boolean jpegmemsrcmgr_fill_input_buffer(j_decompress_ptr dinfo)
{
- unsigned char *buf = (unsigned char *)dinfo->src->next_input_byte - 2;
+ uchar *buf = (uchar *)dinfo->src->next_input_byte - 2;
/* if we get called, must have run out of data */
WARNMS(dinfo, JWRN_JPEG_EOF);
@@ -542,9 +529,7 @@ static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo)
MEM_freeN(dinfo->src);
}
-static void jpegmemsrcmgr_build(j_decompress_ptr dinfo,
- const unsigned char *buffer,
- size_t bufsize)
+static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, const uchar *buffer, size_t bufsize)
{
dinfo->src = MEM_mallocN(sizeof(*(dinfo->src)), "avi.jpegmemsrcmgr_build");
diff --git a/source/blender/io/avi/intern/avi_mjpeg.h b/source/blender/io/avi/intern/avi_mjpeg.h
index 79fa0fe9995..aa74d771646 100644
--- a/source/blender/io/avi/intern/avi_mjpeg.h
+++ b/source/blender/io/avi/intern/avi_mjpeg.h
@@ -7,8 +7,5 @@
#pragma once
-void *avi_converter_from_mjpeg(AviMovie *movie,
- int stream,
- unsigned char *buffer,
- const size_t *size);
-void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size);
+void *avi_converter_from_mjpeg(AviMovie *movie, int stream, uchar *buffer, const size_t *size);
+void *avi_converter_to_mjpeg(AviMovie *movie, int stream, uchar *buffer, size_t *size);
diff --git a/source/blender/io/avi/intern/avi_rgb.c b/source/blender/io/avi/intern/avi_rgb.c
index ffc3d0477fa..71022361df1 100644
--- a/source/blender/io/avi/intern/avi_rgb.c
+++ b/source/blender/io/avi/intern/avi_rgb.c
@@ -21,12 +21,9 @@
/* implementation */
-void *avi_converter_from_avi_rgb(AviMovie *movie,
- int stream,
- unsigned char *buffer,
- const size_t *size)
+void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, uchar *buffer, const size_t *size)
{
- unsigned char *buf;
+ uchar *buf;
AviBitmapInfoHeader *bi;
short bits = 32;
@@ -38,24 +35,24 @@ void *avi_converter_from_avi_rgb(AviMovie *movie,
}
if (bits == 16) {
- unsigned short *pxl;
- unsigned char *to;
+ ushort *pxl;
+ uchar *to;
#ifdef __BIG_ENDIAN__
- unsigned char *pxla;
+ uchar *pxla;
#endif
buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromavirgbbuf");
+ movie->header->Height, movie->header->Width, 3, sizeof(uchar), "fromavirgbbuf");
if (buf) {
size_t y = movie->header->Height;
to = buf;
while (y--) {
- pxl = (unsigned short *)(buffer + y * movie->header->Width * 2);
+ pxl = (ushort *)(buffer + y * movie->header->Width * 2);
#ifdef __BIG_ENDIAN__
- pxla = (unsigned char *)pxl;
+ pxla = (uchar *)pxl;
#endif
size_t x = movie->header->Width;
@@ -82,7 +79,7 @@ void *avi_converter_from_avi_rgb(AviMovie *movie,
}
buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromavirgbbuf");
+ movie->header->Height, movie->header->Width, 3, sizeof(uchar), "fromavirgbbuf");
if (buf) {
size_t rowstride = movie->header->Width * 3;
@@ -110,9 +107,9 @@ void *avi_converter_from_avi_rgb(AviMovie *movie,
return buf;
}
-void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, uchar *buffer, size_t *size)
{
- unsigned char *buf;
+ uchar *buf;
(void)stream; /* unused */
diff --git a/source/blender/io/avi/intern/avi_rgb32.c b/source/blender/io/avi/intern/avi_rgb32.c
index 84ae023fcdd..fcb83ffe47d 100644
--- a/source/blender/io/avi/intern/avi_rgb32.c
+++ b/source/blender/io/avi/intern/avi_rgb32.c
@@ -17,15 +17,15 @@
#include "AVI_avi.h"
#include "avi_rgb32.h"
-void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_from_rgb32(AviMovie *movie, int stream, uchar *buffer, size_t *size)
{
- unsigned char *buf;
+ uchar *buf;
(void)stream; /* unused */
*size = (size_t)movie->header->Height * (size_t)movie->header->Width * 3;
buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromrgb32buf");
+ movie->header->Height, movie->header->Width, 3, sizeof(uchar), "fromrgb32buf");
if (!buf) {
return NULL;
}
@@ -46,16 +46,16 @@ void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffe
return buf;
}
-void *avi_converter_to_rgb32(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_to_rgb32(AviMovie *movie, int stream, uchar *buffer, size_t *size)
{
- unsigned char *buf;
- unsigned char *to, *from;
+ uchar *buf;
+ uchar *to, *from;
(void)stream; /* unused */
*size = (size_t)movie->header->Height * (size_t)movie->header->Width * 4;
buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 4, sizeof(unsigned char), "torgb32buf");
+ movie->header->Height, movie->header->Width, 4, sizeof(uchar), "torgb32buf");
if (!buf) {
return NULL;
}
diff --git a/source/blender/io/collada/AnimationExporter.cpp b/source/blender/io/collada/AnimationExporter.cpp
index 7df9df1f460..85e8ccf9f2a 100644
--- a/source/blender/io/collada/AnimationExporter.cpp
+++ b/source/blender/io/collada/AnimationExporter.cpp
@@ -687,7 +687,7 @@ std::string AnimationExporter::collada_interpolation_source(const BCAnimationCur
std::vector<float> frames;
curve.get_frames(frames);
- for (unsigned int i = 0; i < curve.sample_count(); i++) {
+ for (uint i = 0; i < curve.sample_count(); i++) {
float frame = frames[i];
int ipo = curve.get_interpolation_type(frame);
if (ipo == BEZT_IPO_BEZ) {
diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp
index cc91c3eeac9..2d872377bbf 100644
--- a/source/blender/io/collada/AnimationImporter.cpp
+++ b/source/blender/io/collada/AnimationImporter.cpp
@@ -55,7 +55,7 @@ void AnimationImporter::add_bezt(FCurve *fcu,
float value,
eBezTriple_Interpolation ipo)
{
- // float fps = (float)FPS;
+ // float fps = float(FPS);
BezTriple bez;
memset(&bez, 0, sizeof(BezTriple));
bez.vec[1][0] = frame;
@@ -72,9 +72,9 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
COLLADAFW::FloatOrDoubleArray &input = curve->getInputValues();
COLLADAFW::FloatOrDoubleArray &output = curve->getOutputValues();
- float fps = (float)FPS;
+ float fps = float(FPS);
size_t dim = curve->getOutDimension();
- unsigned int i;
+ uint i;
std::vector<FCurve *> &fcurves = curve_map[curve->getUniqueId()];
@@ -91,7 +91,7 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
fcu->array_index = 0;
fcu->auto_smoothing = U.auto_smoothing_new;
- for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
+ for (uint j = 0; j < curve->getKeyCount(); j++) {
BezTriple bez;
memset(&bez, 0, sizeof(BezTriple));
@@ -106,7 +106,7 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
COLLADAFW::FloatOrDoubleArray &outtan = curve->getOutTangentValues();
/* In-tangent. */
- unsigned int index = 2 * (j * dim + i);
+ uint index = 2 * (j * dim + i);
bez.vec[0][0] = bc_get_float_value(intan, index) * fps;
bez.vec[0][1] = bc_get_float_value(intan, index + 1);
@@ -141,14 +141,14 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
default:
fprintf(stderr,
"Output dimension of %d is not yet supported (animation id = %s)\n",
- (int)dim,
+ int(dim),
curve->getOriginalId().c_str());
}
}
void AnimationImporter::fcurve_deg_to_rad(FCurve *cu)
{
- for (unsigned int i = 0; i < cu->totvert; i++) {
+ for (uint i = 0; i < cu->totvert; i++) {
/* TODO: convert handles too. */
cu->bezt[i].vec[1][1] *= DEG2RADF(1.0f);
cu->bezt[i].vec[0][1] *= DEG2RADF(1.0f);
@@ -158,7 +158,7 @@ void AnimationImporter::fcurve_deg_to_rad(FCurve *cu)
void AnimationImporter::fcurve_scale(FCurve *cu, int scale)
{
- for (unsigned int i = 0; i < cu->totvert; i++) {
+ for (uint i = 0; i < cu->totvert; i++) {
/* TODO: convert handles too. */
cu->bezt[i].vec[1][1] *= scale;
cu->bezt[i].vec[0][1] *= scale;
@@ -262,7 +262,7 @@ AnimationImporter::~AnimationImporter()
}
if (!unused_curves.empty()) {
- fprintf(stderr, "removed %d unused curves\n", (int)unused_curves.size());
+ fprintf(stderr, "removed %d unused curves\n", int(unused_curves.size()));
}
}
@@ -484,7 +484,7 @@ void AnimationImporter::find_frames(std::vector<float> *frames, std::vector<FCur
for (iter = curves->begin(); iter != curves->end(); iter++) {
FCurve *fcu = *iter;
- for (unsigned int k = 0; k < fcu->totvert; k++) {
+ for (uint k = 0; k < fcu->totvert; k++) {
/* get frame value from bezTriple */
float fra = fcu->bezt[k].vec[1][0];
/* if frame already not added add frame to frames */
@@ -525,12 +525,12 @@ void AnimationImporter::Assign_transform_animations(
bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
/* to check if the no of curves are valid */
- bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE ||
- tm_type == COLLADAFW::Transformation::SCALE) &&
- binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
+ bool xyz =
+ (ELEM(tm_type, COLLADAFW::Transformation::TRANSLATE, COLLADAFW::Transformation::SCALE) &&
+ binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) {
- fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves->size());
+ fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, int(curves->size()));
return;
}
@@ -649,7 +649,7 @@ void AnimationImporter::Assign_color_animations(const COLLADAFW::UniqueId &listi
const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
/* all the curves belonging to the current binding */
std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
switch (bindings[j].animationClass) {
@@ -699,7 +699,7 @@ void AnimationImporter::Assign_float_animations(const COLLADAFW::UniqueId &listi
const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
/* all the curves belonging to the current binding */
std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
@@ -756,7 +756,7 @@ void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId &listid
const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
/* all the curves belonging to the current binding */
std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
@@ -767,7 +767,7 @@ void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId &listid
for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
FCurve *fcu = *iter;
- for (unsigned int i = 0; i < fcu->totvert; i++) {
+ for (uint i = 0; i < fcu->totvert; i++) {
fcu->bezt[i].vec[0][1] = convert_to_focal_length(
fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x);
fcu->bezt[i].vec[1][1] = convert_to_focal_length(
@@ -817,7 +817,7 @@ void AnimationImporter::apply_matrix_curves(Object *ob,
}
/* new curves to assign matrix transform animation */
FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale */
- unsigned int totcu = 10;
+ uint totcu = 10;
const char *tm_str = nullptr;
char rna_path[200];
for (int i = 0; i < totcu; i++) {
@@ -1033,7 +1033,7 @@ void AnimationImporter::translate_Animations(
const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
/* for each transformation in node */
- for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+ for (uint i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
@@ -1053,7 +1053,7 @@ void AnimationImporter::translate_Animations(
animlist->getAnimationBindings();
/* all the curves belonging to the current binding */
std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
if (is_matrix) {
apply_matrix_curves(ob, animcurves, root, node, transform);
@@ -1092,7 +1092,7 @@ void AnimationImporter::translate_Animations(
ListBase *AnimCurves = &(act->curves);
const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights();
- for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
+ for (uint i = 0; i < nodeLights.getCount(); i++) {
const COLLADAFW::Light *light = (COLLADAFW::Light *)
FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
@@ -1130,7 +1130,7 @@ void AnimationImporter::translate_Animations(
ListBase *AnimCurves = &(act->curves);
const COLLADAFW::InstanceCameraPointerArray &nodeCameras = node->getInstanceCameras();
- for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
+ for (uint i = 0; i < nodeCameras.getCount(); i++) {
const COLLADAFW::Camera *camera = (COLLADAFW::Camera *)
FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
@@ -1184,9 +1184,9 @@ void AnimationImporter::translate_Animations(
}
const COLLADAFW::InstanceGeometryPointerArray &nodeGeoms = node->getInstanceGeometries();
- for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
+ for (uint i = 0; i < nodeGeoms.getCount(); i++) {
const COLLADAFW::MaterialBindingArray &matBinds = nodeGeoms[i]->getMaterialBindings();
- for (unsigned int j = 0; j < matBinds.getCount(); j++) {
+ for (uint j = 0; j < matBinds.getCount(); j++) {
const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial();
const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]);
if (ef != nullptr) { /* can be NULL T28909. */
@@ -1273,7 +1273,7 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob,
/* new curves to assign matrix transform animation */
FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale. */
- unsigned int totcu = 10;
+ uint totcu = 10;
const char *tm_str = nullptr;
char rna_path[200];
for (int i = 0; i < totcu; i++) {
@@ -1381,7 +1381,7 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
/* for each transformation in node */
- for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+ for (uint i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
const COLLADAFW::UniqueId &listid = transform->getAnimationList();
@@ -1395,7 +1395,7 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
}
const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights();
- for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
+ for (uint i = 0; i < nodeLights.getCount(); i++) {
const COLLADAFW::Light *light = (COLLADAFW::Light *)
FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
types->light = setAnimType(&(light->getColor()), (types->light), LIGHT_COLOR);
@@ -1408,7 +1408,7 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
}
const COLLADAFW::InstanceCameraPointerArray &nodeCameras = node->getInstanceCameras();
- for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
+ for (uint i = 0; i < nodeCameras.getCount(); i++) {
const COLLADAFW::Camera *camera = (COLLADAFW::Camera *)
FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
if (camera == nullptr) {
@@ -1440,9 +1440,9 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
}
const COLLADAFW::InstanceGeometryPointerArray &nodeGeoms = node->getInstanceGeometries();
- for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
+ for (uint i = 0; i < nodeGeoms.getCount(); i++) {
const COLLADAFW::MaterialBindingArray &matBinds = nodeGeoms[i]->getMaterialBindings();
- for (unsigned int j = 0; j < matBinds.getCount(); j++) {
+ for (uint j = 0; j < matBinds.getCount(); j++) {
const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial();
const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]);
if (ef != nullptr) { /* can be NULL T28909. */
@@ -1490,7 +1490,7 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames,
/* for each <rotate>, <translate>, etc. there is a separate Transformation */
const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
- unsigned int i;
+ uint i;
/* find frames at which to sample plus convert all rotation keys to radians */
for (i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
@@ -1508,10 +1508,11 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames,
if (bindings.getCount()) {
/* for each AnimationBinding get the fcurves which animate the transform */
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ for (uint j = 0; j < bindings.getCount(); j++) {
std::vector<FCurve *> &curves = curve_map[bindings[j].animation];
- bool xyz = ((nodeTmType == COLLADAFW::Transformation::TRANSLATE ||
- nodeTmType == COLLADAFW::Transformation::SCALE) &&
+ bool xyz = (ELEM(nodeTmType,
+ COLLADAFW::Transformation::TRANSLATE,
+ COLLADAFW::Transformation::SCALE) &&
bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
@@ -1525,7 +1526,7 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames,
fcurve_deg_to_rad(fcu);
}
- for (unsigned int k = 0; k < fcu->totvert; k++) {
+ for (uint k = 0; k < fcu->totvert; k++) {
/* get frame value from bezTriple */
float fra = fcu->bezt[k].vec[1][0];
/* if frame already not added add frame to frames */
@@ -1536,7 +1537,7 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames,
}
}
else {
- fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves.size());
+ fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, int(curves.size()));
}
}
}
@@ -1573,7 +1574,7 @@ Object *AnimationImporter::translate_animation_OLD(
find_frames_old(&frames, node, tm_type);
- unsigned int i;
+ uint i;
float irest_dae[4][4];
float rest[4][4], irest[4][4];
@@ -1632,7 +1633,7 @@ Object *AnimationImporter::translate_animation_OLD(
/* new curves */
FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale */
- unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3);
+ uint totcu = is_matrix ? 10 : (is_rotation ? 4 : 3);
for (i = 0; i < totcu; i++) {
@@ -1825,7 +1826,7 @@ void AnimationImporter::evaluate_transform_at_frame(float mat[4][4],
unit_m4(mat);
- for (unsigned int i = 0; i < tms.getCount(); i++) {
+ for (uint i = 0; i < tms.getCount(); i++) {
COLLADAFW::Transformation *tm = tms[i];
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
float m[4][4];
@@ -1883,8 +1884,11 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
const COLLADAFW::UniqueId &listid = tm->getAnimationList();
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
- if (type != COLLADAFW::Transformation::ROTATE && type != COLLADAFW::Transformation::SCALE &&
- type != COLLADAFW::Transformation::TRANSLATE && type != COLLADAFW::Transformation::MATRIX) {
+ if (!ELEM(type,
+ COLLADAFW::Transformation::ROTATE,
+ COLLADAFW::Transformation::SCALE,
+ COLLADAFW::Transformation::TRANSLATE,
+ COLLADAFW::Transformation::MATRIX)) {
fprintf(stderr, "animation of transformation %d is not supported yet\n", type);
return false;
}
@@ -1909,7 +1913,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
dae_translate_to_v3(tm, vec);
}
- for (unsigned int index = 0; index < bindings.getCount(); index++) {
+ for (uint index = 0; index < bindings.getCount(); index++) {
const COLLADAFW::AnimationList::AnimationBinding &binding = bindings[index];
std::vector<FCurve *> &curves = curve_map[binding.animation];
COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass;
@@ -1934,7 +1938,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
if (type == COLLADAFW::Transformation::ROTATE) {
if (curves.size() != 1) {
- fprintf(stderr, "expected 1 curve, got %d\n", (int)curves.size());
+ fprintf(stderr, "expected 1 curve, got %d\n", int(curves.size()));
return false;
}
@@ -1946,7 +1950,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
COLLADABU::Math::Vector3 &axis = ((COLLADAFW::Rotate *)tm)->getRotationAxis();
- float ax[3] = {(float)axis[0], (float)axis[1], (float)axis[2]};
+ float ax[3] = {float(axis[0]), float(axis[1]), float(axis[2])};
float angle = evaluate_fcurve(curves[0], fra);
axis_angle_to_mat4(mat, ax, angle);
@@ -1957,10 +1961,10 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) {
if (is_xyz) {
- fprintf(stderr, "%s: expected 3 curves, got %d\n", path, (int)curves.size());
+ fprintf(stderr, "%s: expected 3 curves, got %d\n", path, int(curves.size()));
}
else {
- fprintf(stderr, "%s: expected 1 curve, got %d\n", path, (int)curves.size());
+ fprintf(stderr, "%s: expected 1 curve, got %d\n", path, int(curves.size()));
}
return false;
}
@@ -1989,7 +1993,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
/* for now, of matrix animation,
* support only the case when all values are packed into one animation */
if (curves.size() != 16) {
- fprintf(stderr, "%s: expected 16 curves, got %d\n", path, (int)curves.size());
+ fprintf(stderr, "%s: expected 16 curves, got %d\n", path, int(curves.size()));
return false;
}
@@ -2062,7 +2066,7 @@ bool AnimationImporter::calc_joint_parent_mat_rest(float mat[4][4],
}
COLLADAFW::NodePointerArray &children = node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
if (calc_joint_parent_mat_rest(mat, m, children[i], end)) {
return true;
}
diff --git a/source/blender/io/collada/ArmatureExporter.cpp b/source/blender/io/collada/ArmatureExporter.cpp
index 87dd2fbd816..3cc98917116 100644
--- a/source/blender/io/collada/ArmatureExporter.cpp
+++ b/source/blender/io/collada/ArmatureExporter.cpp
@@ -76,7 +76,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob)
ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id));
Mesh *me = (Mesh *)ob->data;
- if (!me->dvert) {
+ if (BKE_mesh_deform_verts(me) == nullptr) {
return false;
}
diff --git a/source/blender/io/collada/ArmatureImporter.cpp b/source/blender/io/collada/ArmatureImporter.cpp
index f056488fe93..1310337f501 100644
--- a/source/blender/io/collada/ArmatureImporter.cpp
+++ b/source/blender/io/collada/ArmatureImporter.cpp
@@ -190,7 +190,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin,
COLLADAFW::NodePointerArray &children = node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm, layer_labels);
if (cl > chain_length) {
chain_length = cl;
@@ -719,7 +719,7 @@ void ArmatureImporter::set_pose(Object *ob_arm,
#endif
COLLADAFW::NodePointerArray &children = root_node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
set_pose(ob_arm, children[i], bone_name, mat);
}
}
@@ -727,7 +727,7 @@ void ArmatureImporter::set_pose(Object *ob_arm,
bool ArmatureImporter::node_is_decomposed(const COLLADAFW::Node *node)
{
const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
- for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
+ for (uint i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
if (tm_type == COLLADAFW::Transformation::MATRIX) {
@@ -879,7 +879,7 @@ bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControlle
/* store join inv bind matrix to use it later in armature construction */
const COLLADAFW::Matrix4Array &inv_bind_mats = data->getInverseBindMatrices();
- for (unsigned int i = 0; i < data->getJointsCount(); i++) {
+ for (uint i = 0; i < data->getJointsCount(); i++) {
skin.add_joint(inv_bind_mats[i]);
}
diff --git a/source/blender/io/collada/BCAnimationCurve.cpp b/source/blender/io/collada/BCAnimationCurve.cpp
index fe90dc5d5fa..ac7fa81883a 100644
--- a/source/blender/io/collada/BCAnimationCurve.cpp
+++ b/source/blender/io/collada/BCAnimationCurve.cpp
@@ -329,8 +329,7 @@ bool BCAnimationCurve::is_transform_curve() const
bool BCAnimationCurve::is_rotation_curve() const
{
std::string channel_type = this->get_channel_type();
- return (channel_type == "rotation" || channel_type == "rotation_euler" ||
- channel_type == "rotation_quaternion");
+ return ELEM(channel_type, "rotation", "rotation_euler", "rotation_quaternion");
}
float BCAnimationCurve::get_value(const float frame)
@@ -426,10 +425,10 @@ bool BCAnimationCurve::add_value_from_rna(const int frame_index)
if ((array_index >= 0) && (array_index < RNA_property_array_length(&ptr, prop))) {
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
- value = (float)RNA_property_boolean_get_index(&ptr, prop, array_index);
+ value = float(RNA_property_boolean_get_index(&ptr, prop, array_index));
break;
case PROP_INT:
- value = (float)RNA_property_int_get_index(&ptr, prop, array_index);
+ value = float(RNA_property_int_get_index(&ptr, prop, array_index));
break;
case PROP_FLOAT:
value = RNA_property_float_get_index(&ptr, prop, array_index);
@@ -449,16 +448,16 @@ bool BCAnimationCurve::add_value_from_rna(const int frame_index)
/* not an array */
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
- value = (float)RNA_property_boolean_get(&ptr, prop);
+ value = float(RNA_property_boolean_get(&ptr, prop));
break;
case PROP_INT:
- value = (float)RNA_property_int_get(&ptr, prop);
+ value = float(RNA_property_int_get(&ptr, prop));
break;
case PROP_FLOAT:
value = RNA_property_float_get(&ptr, prop);
break;
case PROP_ENUM:
- value = (float)RNA_property_enum_get(&ptr, prop);
+ value = float(RNA_property_enum_get(&ptr, prop));
break;
default:
fprintf(stderr,
diff --git a/source/blender/io/collada/BCMath.cpp b/source/blender/io/collada/BCMath.cpp
index d48e46ca115..6e052ee960d 100644
--- a/source/blender/io/collada/BCMath.cpp
+++ b/source/blender/io/collada/BCMath.cpp
@@ -140,9 +140,9 @@ void BCMatrix::sanitize(Matrix &mat, int precision)
{
for (auto &row : mat) {
for (float &cell : row) {
- double val = (double)cell;
+ double val = double(cell);
val = double_round(val, precision);
- cell = (float)val;
+ cell = float(val);
}
}
}
@@ -169,7 +169,7 @@ void BCMatrix::get_matrix(DMatrix &mat, const bool transposed, const int precisi
for (int j = 0; j < 4; j++) {
float val = (transposed) ? matrix[j][i] : matrix[i][j];
if (precision >= 0) {
- val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision);
+ val = floor(val * pow(10, precision) + 0.5) / pow(10, precision);
}
mat[i][j] = val;
}
@@ -185,7 +185,7 @@ void BCMatrix::get_matrix(Matrix &mat,
for (int j = 0; j < 4; j++) {
float val = (transposed) ? matrix[j][i] : matrix[i][j];
if (precision >= 0) {
- val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision);
+ val = floor(val * pow(10, precision) + 0.5) / pow(10, precision);
}
mat[i][j] = val;
}
diff --git a/source/blender/io/collada/BCSampleData.cpp b/source/blender/io/collada/BCSampleData.cpp
index 42b436ec6fb..422ecdc598f 100644
--- a/source/blender/io/collada/BCSampleData.cpp
+++ b/source/blender/io/collada/BCSampleData.cpp
@@ -51,7 +51,7 @@ bool BCSample::get_value(std::string channel_target, const int array_index, floa
else if (channel_type == "scale") {
*val = matrix->scale()[array_index];
}
- else if (channel_type == "rotation" || channel_type == "rotation_euler") {
+ else if (ELEM(channel_type, "rotation", "rotation_euler")) {
*val = matrix->rotation()[array_index];
}
else if (channel_type == "rotation_quaternion") {
diff --git a/source/blender/io/collada/BlenderContext.cpp b/source/blender/io/collada/BlenderContext.cpp
index 5f54f38a0ab..807488233ce 100644
--- a/source/blender/io/collada/BlenderContext.cpp
+++ b/source/blender/io/collada/BlenderContext.cpp
@@ -9,21 +9,25 @@
#include "BlenderContext.h"
#include "ExportSettings.h"
+#include "BKE_layer.h"
#include "BKE_scene.h"
-bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer)
+#include "BLI_listbase.h"
+
+bool bc_is_base_node(LinkNode *export_set, Object *ob, const Scene *scene, ViewLayer *view_layer)
{
- Object *root = bc_get_highest_exported_ancestor_or_self(export_set, ob, view_layer);
+ Object *root = bc_get_highest_exported_ancestor_or_self(export_set, ob, scene, view_layer);
return (root == ob);
}
Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set,
Object *ob,
+ const Scene *scene,
ViewLayer *view_layer)
{
Object *ancestor = ob;
while (ob->parent) {
- if (bc_is_in_Export_set(export_set, ob->parent, view_layer)) {
+ if (bc_is_in_Export_set(export_set, ob->parent, scene, view_layer)) {
ancestor = ob->parent;
}
ob = ob->parent;
@@ -31,10 +35,13 @@ Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set,
return ancestor;
}
-void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer)
+void bc_get_children(std::vector<Object *> &child_set,
+ Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer)
{
- Base *base;
- for (base = (Base *)view_layer->object_bases.first; base; base = base->next) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *cob = base->object;
if (cob->parent == ob) {
switch (ob->type) {
@@ -51,7 +58,10 @@ void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *vi
}
}
-bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer)
+bool bc_is_in_Export_set(LinkNode *export_set,
+ Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer)
{
bool to_export = (BLI_linklist_index(export_set, ob) != -1);
@@ -60,9 +70,9 @@ bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer
* export list, but it contains children to export. */
std::vector<Object *> children;
- bc_get_children(children, ob, view_layer);
+ bc_get_children(children, ob, scene, view_layer);
for (Object *child : children) {
- if (bc_is_in_Export_set(export_set, child, view_layer)) {
+ if (bc_is_in_Export_set(export_set, child, scene, view_layer)) {
to_export = true;
break;
}
diff --git a/source/blender/io/collada/BlenderContext.h b/source/blender/io/collada/BlenderContext.h
index 6fdb043b3dc..8a782b74e52 100644
--- a/source/blender/io/collada/BlenderContext.h
+++ b/source/blender/io/collada/BlenderContext.h
@@ -22,8 +22,11 @@ extern "C" {
static const BC_global_forward_axis BC_DEFAULT_FORWARD = BC_GLOBAL_FORWARD_Y;
static const BC_global_up_axis BC_DEFAULT_UP = BC_GLOBAL_UP_Z;
-bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer);
-bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer);
+bool bc_is_in_Export_set(LinkNode *export_set,
+ Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer);
+bool bc_is_base_node(LinkNode *export_set, Object *ob, const Scene *scene, ViewLayer *view_layer);
/**
* Returns the highest selected ancestor
* returns NULL if no ancestor is selected
@@ -32,6 +35,7 @@ bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer);
*/
Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set,
Object *ob,
+ const Scene *scene,
ViewLayer *view_layer);
int bc_is_marked(Object *ob);
void bc_remove_mark(Object *ob);
diff --git a/source/blender/io/collada/CMakeLists.txt b/source/blender/io/collada/CMakeLists.txt
index 3289a7c6e66..43cc0642921 100644
--- a/source/blender/io/collada/CMakeLists.txt
+++ b/source/blender/io/collada/CMakeLists.txt
@@ -2,7 +2,7 @@
# Copyright 2006 Blender Foundation. All rights reserved.
remove_strict_flags()
-FIND_FILE(OPENCOLLADA_ANIMATION_CLIP
+find_file(OPENCOLLADA_ANIMATION_CLIP
NAMES
COLLADAFWAnimationClip.h
PATHS
@@ -14,7 +14,7 @@ if(OPENCOLLADA_ANIMATION_CLIP)
add_definitions(-DWITH_OPENCOLLADA_ANIMATION_CLIP)
endif()
-# In cmake version 3.21 and up, we can instead use the NO_CACHE option for
+# In CMAKE version 3.21 and up, we can instead use the NO_CACHE option for
# find_file so we don't need to clear it from the cache here.
unset(OPENCOLLADA_ANIMATION_CLIP CACHE)
@@ -122,9 +122,4 @@ if(WITH_BUILDINFO)
add_definitions(-DWITH_BUILDINFO)
endif()
-if(CMAKE_COMPILER_IS_GNUCXX)
- # COLLADAFWArray.h gives error with gcc 4.5
- string(APPEND CMAKE_CXX_FLAGS " -fpermissive")
-endif()
-
blender_add_lib(bf_collada "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/io/collada/CameraExporter.cpp b/source/blender/io/collada/CameraExporter.cpp
index 45a73914256..7c3f304b722 100644
--- a/source/blender/io/collada/CameraExporter.cpp
+++ b/source/blender/io/collada/CameraExporter.cpp
@@ -51,7 +51,7 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
case CAM_PERSP: {
COLLADASW::PerspectiveOptic persp(mSW);
persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov");
- persp.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio");
+ persp.setAspectRatio(float(sce->r.xsch) / float(sce->r.ysch), false, "aspect_ratio");
persp.setZFar(cam->clip_end, false, "zfar");
persp.setZNear(cam->clip_start, false, "znear");
COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name);
@@ -64,7 +64,7 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
default: {
COLLADASW::OrthographicOptic ortho(mSW);
ortho.setXMag(cam->ortho_scale / 2, "xmag");
- ortho.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio");
+ ortho.setAspectRatio(float(sce->r.xsch) / float(sce->r.ysch), false, "aspect_ratio");
ortho.setZFar(cam->clip_end, false, "zfar");
ortho.setZNear(cam->clip_start, false, "znear");
COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name);
diff --git a/source/blender/io/collada/ControllerExporter.cpp b/source/blender/io/collada/ControllerExporter.cpp
index 38ad0e42d0f..6bf8d904a41 100644
--- a/source/blender/io/collada/ControllerExporter.cpp
+++ b/source/blender/io/collada/ControllerExporter.cpp
@@ -63,7 +63,7 @@ bool ControllerExporter::add_instance_controller(Object *ob)
ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id));
Mesh *me = (Mesh *)ob->data;
- if (!me->dvert) {
+ if (BKE_mesh_deform_verts(me) == nullptr) {
return false;
}
@@ -160,7 +160,7 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
bool use_instantiation = this->export_settings.get_use_object_instantiation();
Mesh *me;
- if (((Mesh *)ob->data)->dvert == nullptr) {
+ if (BKE_mesh_deform_verts((Mesh *)ob->data) == nullptr) {
return;
}
@@ -203,9 +203,10 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
}
}
+ const MDeformVert *dvert = BKE_mesh_deform_verts(me);
int oob_counter = 0;
for (i = 0; i < me->totvert; i++) {
- MDeformVert *vert = &me->dvert[i];
+ const MDeformVert *vert = &dvert[i];
std::map<int, float> jw;
/* We're normalizing the weights later */
diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp
index 2ce97bc8b5d..660bbd7edb2 100644
--- a/source/blender/io/collada/DocumentImporter.cpp
+++ b/source/blender/io/collada/DocumentImporter.cpp
@@ -90,8 +90,12 @@ DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_set
CTX_data_scene(C),
view_layer,
import_settings),
- mesh_importer(
- &unit_converter, &armature_importer, CTX_data_main(C), CTX_data_scene(C), view_layer),
+ mesh_importer(&unit_converter,
+ import_settings->custom_normals,
+ &armature_importer,
+ CTX_data_main(C),
+ CTX_data_scene(C),
+ view_layer),
anim_importer(C, &unit_converter, &armature_importer, CTX_data_scene(C))
{
}
@@ -116,7 +120,7 @@ bool DocumentImporter::import()
loader.registerExtraDataCallbackHandler(ehandler);
/* deselect all to select new objects */
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(CTX_data_scene(mContext), view_layer);
std::string mFilename = std::string(this->import_settings->filepath);
const std::string encodedFilename = bc_url_encode(mFilename);
@@ -209,7 +213,7 @@ void DocumentImporter::finish()
/* Write nodes to scene */
fprintf(stderr, "+-- Import Scene --------\n");
const COLLADAFW::NodePointerArray &roots = (*sit)->getRootNodes();
- for (unsigned int i = 0; i < roots.getCount(); i++) {
+ for (uint i = 0; i < roots.getCount(); i++) {
std::vector<Object *> *objects_done = write_node(roots[i], nullptr, sce, nullptr, false);
objects_to_scale->insert(
objects_to_scale->end(), objects_done->begin(), objects_done->end());
@@ -230,14 +234,14 @@ void DocumentImporter::finish()
for (const COLLADAFW::VisualScene *vscene : vscenes) {
const COLLADAFW::NodePointerArray &roots = vscene->getRootNodes();
- for (unsigned int i = 0; i < roots.getCount(); i++) {
+ for (uint i = 0; i < roots.getCount(); i++) {
translate_anim_recursive(roots[i], nullptr, nullptr);
}
}
if (!libnode_ob.empty()) {
- fprintf(stderr, "| Cleanup: free %d library nodes\n", (int)libnode_ob.size());
+ fprintf(stderr, "| Cleanup: free %d library nodes\n", int(libnode_ob.size()));
/* free all library_nodes */
std::vector<Object *>::iterator it;
for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
@@ -288,7 +292,7 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node,
Object *ob;
#endif
- unsigned int i;
+ uint i;
if (node->getType() == COLLADAFW::Node::JOINT && par == nullptr) {
/* For Skeletons without root node we have to simulate the
@@ -420,7 +424,7 @@ Object *DocumentImporter::create_instance_node(Object *source_ob,
COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
if (children.getCount()) {
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
COLLADAFW::Node *child_node = children[i];
const COLLADAFW::UniqueId &child_id = child_node->getUniqueId();
if (object_map.find(child_id) == object_map.end()) {
@@ -430,7 +434,7 @@ Object *DocumentImporter::create_instance_node(Object *source_ob,
Object *new_child = nullptr;
if (inodes.getCount()) { /* \todo loop through instance nodes */
const COLLADAFW::UniqueId &id = inodes[0]->getInstanciatedObjectId();
- fprintf(stderr, "Doing %d child nodes\n", (int)node_map.count(id));
+ fprintf(stderr, "Doing %d child nodes\n", int(node_map.count(id)));
new_child = create_instance_node(
object_map.find(id)->second, node_map[id], child_node, sce, is_library_node);
}
@@ -671,7 +675,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node,
ob = *objects_done->begin();
}
- for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
+ for (uint i = 0; i < child_nodes.getCount(); i++) {
std::vector<Object *> *child_objects;
child_objects = write_node(child_nodes[i], node, sce, ob, is_library_node);
delete child_objects;
@@ -716,7 +720,7 @@ bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryN
const COLLADAFW::NodePointerArray &nodes = libraryNodes->getNodes();
fprintf(stderr, "+-- Read Library nodes ----------\n");
- for (unsigned int i = 0; i < nodes.getCount(); i++) {
+ for (uint i = 0; i < nodes.getCount(); i++) {
std::vector<Object *> *child_objects;
child_objects = write_node(nodes[i], nullptr, sce, nullptr, true);
delete child_objects;
@@ -743,6 +747,7 @@ bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat)
const std::string &str_mat_id = cmat->getName().empty() ? cmat->getOriginalId() :
cmat->getName();
Material *ma = BKE_material_add(bmain, (char *)str_mat_id.c_str());
+ id_us_min(&ma->id);
this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
this->uid_material_map[cmat->getUniqueId()] = ma;
@@ -864,7 +869,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
double ymag = 2 * camera->getYMag().getValue();
double aspect = camera->getAspectRatio().getValue();
double xmag = aspect * ymag;
- cam->ortho_scale = (float)xmag;
+ cam->ortho_scale = float(xmag);
} break;
case CAM_PERSP:
default: {
@@ -885,7 +890,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
case COLLADAFW::Camera::X_AND_Y: {
switch (cam->type) {
case CAM_ORTHO:
- cam->ortho_scale = (float)camera->getXMag().getValue() * 2;
+ cam->ortho_scale = float(camera->getXMag().getValue()) * 2;
break;
case CAM_PERSP:
default: {
@@ -898,7 +903,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
case COLLADAFW::Camera::SINGLE_Y: {
switch (cam->type) {
case CAM_ORTHO:
- cam->ortho_scale = (float)camera->getYMag().getValue();
+ cam->ortho_scale = float(camera->getYMag().getValue());
break;
case CAM_PERSP:
default: {
@@ -1177,7 +1182,7 @@ bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *e
bool DocumentImporter::is_armature(COLLADAFW::Node *node)
{
COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
- for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
+ for (uint i = 0; i < child_nodes.getCount(); i++) {
if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) {
return true;
}
diff --git a/source/blender/io/collada/EffectExporter.cpp b/source/blender/io/collada/EffectExporter.cpp
index 40ce20617fc..e8a715633e1 100644
--- a/source/blender/io/collada/EffectExporter.cpp
+++ b/source/blender/io/collada/EffectExporter.cpp
@@ -217,7 +217,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
create_image_samplers(ep, material_image_map, active_uv);
#if 0
- unsigned int a, b;
+ uint a, b;
for (a = 0, b = 0; a < tex_indices.size(); a++) {
MTex *t = ma->mtex[tex_indices[a]];
Image *ima = t->tex->ima;
diff --git a/source/blender/io/collada/ExportSettings.h b/source/blender/io/collada/ExportSettings.h
index b3f192fdac6..e4c1b41fdde 100644
--- a/source/blender/io/collada/ExportSettings.h
+++ b/source/blender/io/collada/ExportSettings.h
@@ -81,7 +81,10 @@ typedef struct ExportSettings {
#ifdef __cplusplus
}
-void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer);
+void bc_get_children(std::vector<Object *> &child_set,
+ Object *ob,
+ const Scene *scene,
+ ViewLayer *view_layer);
class BCExportSettings {
@@ -271,7 +274,7 @@ class BCExportSettings {
bool is_export_root(Object *ob)
{
- return bc_is_base_node(get_export_set(), ob, get_view_layer());
+ return bc_is_base_node(get_export_set(), ob, get_scene(), get_view_layer());
}
};
diff --git a/source/blender/io/collada/ExtraHandler.cpp b/source/blender/io/collada/ExtraHandler.cpp
index b281f0e1a0a..d9c193ddbb5 100644
--- a/source/blender/io/collada/ExtraHandler.cpp
+++ b/source/blender/io/collada/ExtraHandler.cpp
@@ -43,7 +43,7 @@ bool ExtraHandler::textData(const char *text, size_t textLength)
}
bool ExtraHandler::parseElement(const char *profileName,
- const unsigned long &elementHash,
+ const ulong &elementHash,
const COLLADAFW::UniqueId &uniqueId)
{
/* implement for backwards compatibility, new version added object parameter */
@@ -51,7 +51,7 @@ bool ExtraHandler::parseElement(const char *profileName,
}
bool ExtraHandler::parseElement(const char *profileName,
- const unsigned long &elementHash,
+ const ulong &elementHash,
const COLLADAFW::UniqueId &uniqueId,
COLLADAFW::Object *object)
{
diff --git a/source/blender/io/collada/ExtraTags.cpp b/source/blender/io/collada/ExtraTags.cpp
index 398718f1133..9fb7bbb2295 100644
--- a/source/blender/io/collada/ExtraTags.cpp
+++ b/source/blender/io/collada/ExtraTags.cpp
@@ -49,7 +49,7 @@ float ExtraTags::asFloat(std::string tag, bool *ok)
return -1.0f;
}
*ok = true;
- return (float)atof(tags[tag].c_str());
+ return float(atof(tags[tag].c_str()));
}
std::string ExtraTags::asString(std::string tag, bool *ok)
@@ -67,7 +67,7 @@ bool ExtraTags::setData(std::string tag, short *data)
bool ok = false;
int tmp = asInt(tag, &ok);
if (ok) {
- *data = (short)tmp;
+ *data = short(tmp);
}
return ok;
}
@@ -97,7 +97,7 @@ bool ExtraTags::setData(std::string tag, char *data)
bool ok = false;
int tmp = asInt(tag, &ok);
if (ok) {
- *data = (char)tmp;
+ *data = char(tmp);
}
return ok;
}
diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp
index 7e2a24aeb41..a069c32026b 100644
--- a/source/blender/io/collada/GeometryExporter.cpp
+++ b/source/blender/io/collada/GeometryExporter.cpp
@@ -17,6 +17,7 @@
#include "BLI_utildefines.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_lib_id.h"
@@ -26,6 +27,8 @@
#include "collada_internal.h"
#include "collada_utils.h"
+using blender::Span;
+
void GeometryExporter::exportGeom()
{
Scene *sce = blender_context.get_scene();
@@ -61,7 +64,7 @@ void GeometryExporter::operator()(Object *ob)
exportedGeometry.insert(geom_id);
- bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);
+ bool has_color = bool(CustomData_has_layer(&me->fdata, CD_MCOL));
create_normals(nor, norind, me);
@@ -74,7 +77,7 @@ void GeometryExporter::operator()(Object *ob)
/* writes <source> for normal coords */
createNormalsSource(geom_id, me, nor);
- bool has_uvs = (bool)CustomData_has_layer(&me->ldata, CD_MLOOPUV);
+ bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
/* writes <source> for uv coords if mesh has uv coords */
if (has_uvs) {
@@ -116,11 +119,12 @@ void GeometryExporter::operator()(Object *ob)
if (this->export_settings.get_include_shapekeys()) {
Key *key = BKE_key_from_object(ob);
if (key) {
+ blender::MutableSpan<MVert> verts = me->verts_for_write();
KeyBlock *kb = (KeyBlock *)key->block.first;
/* skip the basis */
kb = kb->next;
for (; kb; kb = kb->next) {
- BKE_keyblock_convert_to_mesh(kb, me->mvert, me->totvert);
+ BKE_keyblock_convert_to_mesh(kb, verts.data(), me->totvert);
export_key_mesh(ob, me, kb);
}
}
@@ -143,7 +147,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
exportedGeometry.insert(geom_id);
- bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);
+ bool has_color = bool(CustomData_has_layer(&me->fdata, CD_MCOL));
create_normals(nor, norind, me);
@@ -156,7 +160,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
/* writes <source> for normal coords */
createNormalsSource(geom_id, me, nor);
- bool has_uvs = (bool)CustomData_has_layer(&me->ldata, CD_MLOOPUV);
+ bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
/* writes <source> for uv coords if mesh has uv coords */
if (has_uvs) {
@@ -196,17 +200,16 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &geom_id)
{
-
- MEdge *medges = me->medge;
+ const Span<MEdge> edges = me->edges();
int totedges = me->totedge;
int edges_in_linelist = 0;
- std::vector<unsigned int> edge_list;
+ std::vector<uint> edge_list;
int index;
/* Find all loose edges in Mesh
* and save vertex indices in edge_list */
for (index = 0; index < totedges; index++) {
- MEdge *edge = &medges[index];
+ const MEdge *edge = &edges[index];
if (edge->flag & ME_LOOSEEDGE) {
edges_in_linelist += 1;
@@ -241,7 +244,7 @@ void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &ge
static void prepareToAppendValues(bool is_triangulated,
COLLADASW::PrimitivesBase &primitive_list,
- std::vector<unsigned long> &vcount_list)
+ std::vector<ulong> &vcount_list)
{
/* performs the actual writing */
if (is_triangulated) {
@@ -282,18 +285,19 @@ static COLLADASW::PrimitivesBase *create_primitive_list(bool is_triangulated,
static bool collect_vertex_counts_per_poly(Mesh *me,
int material_index,
- std::vector<unsigned long> &vcount_list)
+ std::vector<ulong> &vcount_list)
{
- MPoly *mpolys = me->mpoly;
- int totpolys = me->totpoly;
+ const Span<MPoly> polys = me->polys();
+ const blender::bke::AttributeAccessor attributes = me->attributes();
+ const blender::VArray<int> material_indices = attributes.lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
bool is_triangulated = true;
- int i;
- /* Expecting that p->mat_nr is always 0 if the mesh has no materials assigned */
- for (i = 0; i < totpolys; i++) {
- MPoly *p = &mpolys[i];
- if (p->mat_nr == material_index) {
- int vertex_count = p->totloop;
+ /* Expecting that the material index is always 0 if the mesh has no materials assigned */
+ for (const int i : polys.index_range()) {
+ if (material_indices[i] == material_index) {
+ const MPoly &poly = polys[i];
+ const int vertex_count = poly.totloop;
vcount_list.push_back(vertex_count);
if (vertex_count != 3) {
is_triangulated = false;
@@ -318,12 +322,10 @@ void GeometryExporter::create_mesh_primitive_list(short material_index,
std::string &geom_id,
std::vector<BCPolygonNormalsIndices> &norind)
{
+ const Span<MPoly> polys = me->polys();
+ const Span<MLoop> loops = me->loops();
- MPoly *mpolys = me->mpoly;
- MLoop *mloops = me->mloop;
- int totpolys = me->totpoly;
-
- std::vector<unsigned long> vcount_list;
+ std::vector<ulong> vcount_list;
bool is_triangulated = collect_vertex_counts_per_poly(me, material_index, vcount_list);
int polygon_count = vcount_list.size();
@@ -397,14 +399,18 @@ void GeometryExporter::create_mesh_primitive_list(short material_index,
/* performs the actual writing */
prepareToAppendValues(is_triangulated, *primitive_list, vcount_list);
+ const blender::bke::AttributeAccessor attributes = me->attributes();
+ const blender::VArray<int> material_indices = attributes.lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
+
/* <p> */
int texindex = 0;
- for (int i = 0; i < totpolys; i++) {
- MPoly *p = &mpolys[i];
+ for (const int i : polys.index_range()) {
+ const MPoly *p = &polys[i];
int loop_count = p->totloop;
- if (p->mat_nr == material_index) {
- MLoop *l = &mloops[p->loopstart];
+ if (material_indices[i] == material_index) {
+ const MLoop *l = &loops[p->loopstart];
BCPolygonNormalsIndices normal_indices = norind[i];
for (int j = 0; j < loop_count; j++) {
@@ -428,18 +434,13 @@ void GeometryExporter::create_mesh_primitive_list(short material_index,
void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
{
-#if 0
- int totverts = dm->getNumVerts(dm);
- MVert *verts = dm->getVertArray(dm);
-#endif
- int totverts = me->totvert;
- MVert *verts = me->mvert;
+ const Span<MVert> verts = me->verts();
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) +
ARRAY_ID_SUFFIX);
- source.setAccessorCount(totverts);
+ source.setAccessorCount(verts.size());
source.setAccessorStride(3);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
@@ -450,8 +451,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
* count = ""> */
source.prepareToAppendValues();
/* appends data to <float_array> */
- int i = 0;
- for (i = 0; i < totverts; i++) {
+ for (const int i : verts.index_range()) {
Vector co;
if (export_settings.get_apply_global_orientation()) {
bc_add_global_transform(co, verts[i].co, export_settings.get_global_transform());
@@ -500,11 +500,11 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
source.prepareToAppendValues();
- MPoly *mpoly;
- int i;
- for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
- const MLoopCol *mlc = mloopcol + mpoly->loopstart;
- for (int j = 0; j < mpoly->totloop; j++, mlc++) {
+ const Span<MPoly> polys = me->polys();
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ const MLoopCol *mlc = mloopcol + poly.loopstart;
+ for (int j = 0; j < poly.totloop; j++, mlc++) {
source.appendValues(mlc->r / 255.0f, mlc->g / 255.0f, mlc->b / 255.0f, mlc->a / 255.0f);
}
}
@@ -529,10 +529,8 @@ std::string GeometryExporter::makeTexcoordSourceId(std::string &geom_id,
void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
{
-
- int totpoly = me->totpoly;
int totuv = me->totloop;
- MPoly *mpolys = me->mpoly;
+ const Span<MPoly> polys = me->polys();
int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
@@ -558,8 +556,8 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
source.prepareToAppendValues();
- for (int index = 0; index < totpoly; index++) {
- MPoly *mpoly = mpolys + index;
+ for (const int i : polys.index_range()) {
+ const MPoly *mpoly = &polys[i];
MLoopUV *mloop = mloops + mpoly->loopstart;
for (int j = 0; j < mpoly->totloop; j++) {
source.appendValues(mloop[j].uv[0], mloop[j].uv[1]);
@@ -587,7 +585,7 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) + ARRAY_ID_SUFFIX);
- source.setAccessorCount((unsigned long)nor.size());
+ source.setAccessorCount(ulong(nor.size()));
source.setAccessorStride(3);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("X");
@@ -614,12 +612,13 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals,
std::vector<BCPolygonNormalsIndices> &polygons_normals,
Mesh *me)
{
- std::map<Normal, unsigned int> shared_normal_indices;
+ std::map<Normal, uint> shared_normal_indices;
int last_normal_index = -1;
- MVert *verts = me->mvert;
+ const Span<MVert> verts = me->verts();
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me);
- MLoop *mloops = me->mloop;
+ const Span<MPoly> polys = me->polys();
+ const Span<MLoop> loops = me->loops();
const float(*lnors)[3] = nullptr;
bool use_custom_normals = false;
@@ -629,15 +628,15 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals,
use_custom_normals = true;
}
- for (int poly_index = 0; poly_index < me->totpoly; poly_index++) {
- MPoly *mpoly = &me->mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly *mpoly = &polys[poly_index];
bool use_vertex_normals = use_custom_normals || mpoly->flag & ME_SMOOTH;
if (!use_vertex_normals) {
/* For flat faces use face normal as vertex normal: */
float vector[3];
- BKE_mesh_calc_poly_normal(mpoly, mloops + mpoly->loopstart, verts, vector);
+ BKE_mesh_calc_poly_normal(mpoly, &loops[mpoly->loopstart], verts.data(), vector);
Normal n = {vector[0], vector[1], vector[2]};
normals.push_back(n);
@@ -646,7 +645,7 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals,
BCPolygonNormalsIndices poly_indices;
for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) {
- unsigned int loop_idx = mpoly->loopstart + loop_index;
+ uint loop_idx = mpoly->loopstart + loop_index;
if (use_vertex_normals) {
float normalized[3];
@@ -654,7 +653,7 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals,
normalize_v3_v3(normalized, lnors[loop_idx]);
}
else {
- copy_v3_v3(normalized, vert_normals[mloops[loop_index].v]);
+ copy_v3_v3(normalized, vert_normals[loops[loop_index].v]);
normalize_v3(normalized);
}
Normal n = {normalized[0], normalized[1], normalized[2]};
diff --git a/source/blender/io/collada/ImportSettings.h b/source/blender/io/collada/ImportSettings.h
index c92cf580112..2772314900c 100644
--- a/source/blender/io/collada/ImportSettings.h
+++ b/source/blender/io/collada/ImportSettings.h
@@ -8,6 +8,7 @@
typedef struct ImportSettings {
bool import_units;
+ bool custom_normals;
bool find_chains;
bool auto_connect;
bool fix_orientation;
diff --git a/source/blender/io/collada/Materials.cpp b/source/blender/io/collada/Materials.cpp
index b5d89d8d1cf..997da31b939 100644
--- a/source/blender/io/collada/Materials.cpp
+++ b/source/blender/io/collada/Materials.cpp
@@ -86,7 +86,7 @@ bNodeTree *MaterialNode::prepare_material_nodetree()
return nullptr;
}
- material->nodetree = ntreeAddTree(nullptr, "Shader Nodetree", "ShaderNodeTree");
+ ntreeAddTreeEmbedded(nullptr, &material->id, "Shader Nodetree", "ShaderNodeTree");
material->use_nodes = true;
ntree = material->nodetree;
return ntree;
diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp
index 9fbba1b97fb..6d7593afb8b 100644
--- a/source/blender/io/collada/MeshImporter.cpp
+++ b/source/blender/io/collada/MeshImporter.cpp
@@ -33,6 +33,8 @@
#include "MeshImporter.h"
#include "collada_utils.h"
+using blender::MutableSpan;
+
/* get node name, or fall back to original id if not present (name is optional) */
template<class T> static std::string bc_get_dae_name(T *node)
{
@@ -100,7 +102,7 @@ void WVDataWrapper::print()
COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
if (values->getCount()) {
for (int i = 0; i < values->getCount(); i += 2) {
- fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i + 1]);
+ fprintf(stderr, "%.1f, %.1f\n", float((*values)[i]), float((*values)[i + 1]));
}
}
} break;
@@ -131,8 +133,8 @@ void UVDataWrapper::getUV(int uv_index, float *uv)
if (values->empty()) {
return;
}
- uv[0] = (float)(*values)[uv_index * stride];
- uv[1] = (float)(*values)[uv_index * stride + 1];
+ uv[0] = float((*values)[uv_index * stride]);
+ uv[1] = float((*values)[uv_index * stride + 1]);
} break;
case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
@@ -189,9 +191,14 @@ void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
}
}
-MeshImporter::MeshImporter(
- UnitConverter *unitconv, ArmatureImporter *arm, Main *bmain, Scene *sce, ViewLayer *view_layer)
+MeshImporter::MeshImporter(UnitConverter *unitconv,
+ bool use_custom_normals,
+ ArmatureImporter *arm,
+ Main *bmain,
+ Scene *sce,
+ ViewLayer *view_layer)
: unitconverter(unitconv),
+ use_custom_normals(use_custom_normals),
m_bmain(bmain),
scene(sce),
view_layer(view_layer),
@@ -201,7 +208,7 @@ MeshImporter::MeshImporter(
}
bool MeshImporter::set_poly_indices(
- MPoly *mpoly, MLoop *mloop, int loop_index, const unsigned int *indices, int loop_count)
+ MPoly *mpoly, MLoop *mloop, int loop_index, const uint *indices, int loop_count)
{
mpoly->loopstart = loop_index;
mpoly->totloop = loop_count;
@@ -269,7 +276,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
const std::string &name = bc_get_dae_name(mesh);
- for (unsigned int i = 0; i < prim_arr.getCount(); i++) {
+ for (uint i = 0; i < prim_arr.getCount(); i++) {
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
@@ -277,7 +284,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
const char *type_str = bc_primTypeToStr(type);
/* OpenCollada passes POLYGONS type for <polylist> */
- if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
+ if (ELEM(type, COLLADAFW::MeshPrimitive::POLYLIST, COLLADAFW::MeshPrimitive::POLYGONS)) {
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
COLLADAFW::Polygons::VertexCountArray &vca = mpvc->getGroupedVerticesVertexCountArray();
@@ -285,7 +292,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
int hole_count = 0;
int nonface_count = 0;
- for (unsigned int j = 0; j < vca.getCount(); j++) {
+ for (uint j = 0; j < vca.getCount(); j++) {
int count = vca[j];
if (abs(count) < 3) {
nonface_count++;
@@ -317,8 +324,9 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
/* TODO: Add Checker for line syntax here */
}
- else if (type != COLLADAFW::MeshPrimitive::TRIANGLES &&
- type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
+ else if (!ELEM(type,
+ COLLADAFW::MeshPrimitive::TRIANGLES,
+ COLLADAFW::MeshPrimitive::TRIANGLE_FANS)) {
fprintf(stderr, "ERROR: Primitive type %s is not supported.\n", type_str);
return false;
}
@@ -341,13 +349,10 @@ void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me)
}
me->totvert = pos.getFloatValues()->getCount() / stride;
- me->mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, nullptr, me->totvert);
-
- MVert *mvert;
- int i;
-
- for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
- get_vector(mvert->co, pos, i, stride);
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert);
+ MutableSpan<MVert> verts = me->verts_for_write();
+ for (const int i : verts.index_range()) {
+ get_vector(verts[i].co, pos, i, stride);
}
}
@@ -448,12 +453,10 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
if (total_poly_count > 0) {
me->totpoly = total_poly_count;
me->totloop = total_loop_count;
- me->mpoly = (MPoly *)CustomData_add_layer(
- &me->pdata, CD_MPOLY, CD_CALLOC, nullptr, me->totpoly);
- me->mloop = (MLoop *)CustomData_add_layer(
- &me->ldata, CD_MLOOP, CD_CALLOC, nullptr, me->totloop);
+ CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly);
+ CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop);
- unsigned int totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount();
+ uint totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount();
for (int i = 0; i < totuvset; i++) {
if (collada_mesh->getUVCoords().getLength(i) == 0) {
totuvset = 0;
@@ -468,10 +471,10 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
COLLADAFW::String &uvname = info->mName;
/* Allocate space for UV_data */
CustomData_add_layer_named(
- &me->ldata, CD_MLOOPUV, CD_DEFAULT, nullptr, me->totloop, uvname.c_str());
+ &me->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, me->totloop, uvname.c_str());
}
/* activate the first uv map */
- me->mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0);
+ CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, 0);
}
int totcolset = collada_mesh->getColors().getInputInfosArray().getCount();
@@ -481,14 +484,14 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
collada_mesh->getColors().getInputInfosArray()[i];
COLLADAFW::String colname = extract_vcolname(info->mName);
CustomData_add_layer_named(
- &me->ldata, CD_PROP_BYTE_COLOR, CD_DEFAULT, nullptr, me->totloop, colname.c_str());
+ &me->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, me->totloop, colname.c_str());
}
- me->mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_PROP_BYTE_COLOR, 0);
+ CustomData_set_layer_active(&me->ldata, CD_PROP_BYTE_COLOR, 0);
}
}
}
-unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index)
+uint MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index)
{
int type = mp->getPrimitiveType();
int result;
@@ -511,7 +514,7 @@ unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index)
return result;
}
-unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh)
+uint MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh)
{
COLLADAFW::MeshPrimitiveArray &prim_arr = mesh->getMeshPrimitives();
int loose_edge_count = 0;
@@ -546,21 +549,22 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
totedge = mesh->totedge + len;
/* Update custom-data. */
- CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH.emask, CD_DEFAULT, totedge);
+ CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, totedge);
CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
if (!CustomData_has_layer(&edata, CD_MEDGE)) {
- CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, nullptr, totedge);
+ CustomData_add_layer(&edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, totedge);
}
CustomData_free(&mesh->edata, mesh->totedge);
mesh->edata = edata;
- BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */
+
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
/* set default flags */
- medge = &mesh->medge[mesh->totedge];
+ medge = &edges[mesh->totedge];
for (int i = 0; i < len; i++, medge++) {
- medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
+ medge->flag = ME_EDGEDRAW | ME_EDGERENDER;
}
mesh->totedge = totedge;
@@ -568,14 +572,15 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
{
- unsigned int loose_edge_count = get_loose_edge_count(mesh);
+ uint loose_edge_count = get_loose_edge_count(mesh);
if (loose_edge_count > 0) {
- unsigned int face_edge_count = me->totedge;
- /* unsigned int total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */
+ uint face_edge_count = me->totedge;
+ /* uint total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */
mesh_add_edges(me, loose_edge_count);
- MEdge *med = me->medge + face_edge_count;
+ MutableSpan<MEdge> edges = me->edges_for_write();
+ MEdge *med = edges.data() + face_edge_count;
COLLADAFW::MeshPrimitiveArray &prim_arr = mesh->getMeshPrimitives();
@@ -584,12 +589,10 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
int type = mp->getPrimitiveType();
if (type == COLLADAFW::MeshPrimitive::LINES) {
- unsigned int edge_count = mp->getFaceCount();
- unsigned int *indices = mp->getPositionIndices().getData();
+ uint edge_count = mp->getFaceCount();
+ uint *indices = mp->getPositionIndices().getData();
for (int j = 0; j < edge_count; j++, med++) {
- med->bweight = 0;
- med->crease = 0;
med->flag |= ME_LOOSEEDGE;
med->v1 = indices[2 * j];
med->v2 = indices[2 * j + 1];
@@ -599,21 +602,28 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
}
}
-void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
+void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
+ Mesh *me,
+ blender::Vector<blender::float3> &loop_normals)
{
- unsigned int i;
+ uint i;
allocate_poly_data(collada_mesh, me);
UVDataWrapper uvs(collada_mesh->getUVCoords());
VCOLDataWrapper vcol(collada_mesh->getColors());
- MPoly *mpoly = me->mpoly;
- MLoop *mloop = me->mloop;
+ MutableSpan<MPoly> polys = me->polys_for_write();
+ MutableSpan<MLoop> loops = me->loops_for_write();
+ MPoly *mpoly = polys.data();
+ MLoop *mloop = loops.data();
int loop_index = 0;
MaterialIdPrimitiveArrayMap mat_prim_map;
+ int *material_indices = (int *)CustomData_add_layer_named(
+ &me->pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, me->totpoly, "material_index");
+
COLLADAFW::MeshPrimitiveArray &prim_arr = collada_mesh->getMeshPrimitives();
COLLADAFW::MeshVertexData &nor = collada_mesh->getNormals();
@@ -623,8 +633,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
/* faces */
size_t prim_totpoly = mp->getFaceCount();
- unsigned int *position_indices = mp->getPositionIndices().getData();
- unsigned int *normal_indices = mp->getNormalIndices().getData();
+ uint *position_indices = mp->getPositionIndices().getData();
+ uint *normal_indices = mp->getNormalIndices().getData();
bool mp_has_normals = primitive_has_useable_normals(mp);
bool mp_has_faces = primitive_has_faces(mp);
@@ -632,29 +642,29 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
int collada_meshtype = mp->getPrimitiveType();
/* since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive */
- Primitive prim = {mpoly, 0};
+ Primitive prim = {mpoly, material_indices, 0};
/* If MeshPrimitive is TRIANGLE_FANS we split it into triangles
* The first triangle-fan vertex will be the first vertex in every triangle
* XXX The proper function of TRIANGLE_FANS is not tested!!!
- * XXX In particular the handling of the normal_indices looks very wrong to me */
+ * XXX In particular the handling of the normal_indices is very wrong */
+ /* TODO: UV, vertex color and custom normal support */
if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
- unsigned int grouped_vertex_count = mp->getGroupedVertexElementsCount();
- for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) {
- unsigned int first_vertex = position_indices[0]; /* Store first trifan vertex */
- unsigned int first_normal = normal_indices[0]; /* Store first trifan vertex normal */
- unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index);
+ uint grouped_vertex_count = mp->getGroupedVertexElementsCount();
+ for (uint group_index = 0; group_index < grouped_vertex_count; group_index++) {
+ uint first_vertex = position_indices[0]; /* Store first trifan vertex */
+ uint first_normal = normal_indices[0]; /* Store first trifan vertex normal */
+ uint vertex_count = mp->getGroupedVerticesVertexCount(group_index);
- for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) {
+ for (uint vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) {
/* For each triangle store indices of its 3 vertices */
- unsigned int triangle_vertex_indices[3] = {
+ uint triangle_vertex_indices[3] = {
first_vertex, position_indices[1], position_indices[2]};
set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3);
if (mp_has_normals) { /* vertex normals, same implementation as for the triangles */
/* The same for vertices normals. */
- unsigned int vertex_normal_indices[3] = {
- first_normal, normal_indices[1], normal_indices[2]};
+ uint vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]};
if (!is_flat_face(vertex_normal_indices, nor, 3)) {
mpoly->flag |= ME_SMOOTH;
}
@@ -662,6 +672,9 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
}
mpoly++;
+ if (material_indices) {
+ material_indices++;
+ }
mloop += 3;
loop_index += 3;
prim.totpoly++;
@@ -676,17 +689,18 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
}
}
- if (collada_meshtype == COLLADAFW::MeshPrimitive::POLYLIST ||
- collada_meshtype == COLLADAFW::MeshPrimitive::POLYGONS ||
- collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLES) {
+ if (ELEM(collada_meshtype,
+ COLLADAFW::MeshPrimitive::POLYLIST,
+ COLLADAFW::MeshPrimitive::POLYGONS,
+ COLLADAFW::MeshPrimitive::TRIANGLES)) {
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
- unsigned int start_index = 0;
+ uint start_index = 0;
COLLADAFW::IndexListArray &index_list_array_uvcoord = mp->getUVCoordIndicesArray();
COLLADAFW::IndexListArray &index_list_array_vcolor = mp->getColorIndicesArray();
int invalid_loop_holes = 0;
- for (unsigned int j = 0; j < prim_totpoly; j++) {
+ for (uint j = 0; j < prim_totpoly; j++) {
/* Vertices in polygon: */
int vcount = get_vertex_count(mpvc, j);
@@ -699,7 +713,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
invalid_loop_holes += 1;
}
- for (unsigned int uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount();
+ for (uint uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount();
uvset_index++) {
/* get mtface by face index and uv set index */
COLLADAFW::IndexList &index_list = *index_list_array_uvcoord[uvset_index];
@@ -721,15 +735,28 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
}
if (mp_has_normals) {
+ /* If it turns out that we have complete custom normals for each MPoly
+ * and we want to use custom normals, this will be overridden. */
if (!is_flat_face(normal_indices, nor, vcount)) {
mpoly->flag |= ME_SMOOTH;
}
+
+ if (use_custom_normals) {
+ /* Store the custom normals for later application. */
+ float vert_normal[3];
+ uint *cur_normal = normal_indices;
+ for (int k = 0; k < vcount; k++, cur_normal++) {
+ get_vector(vert_normal, nor, *cur_normal, 3);
+ normalize_v3(vert_normal);
+ loop_normals.append(vert_normal);
+ }
+ }
}
if (mp->hasColorIndices()) {
int vcolor_count = index_list_array_vcolor.getCount();
- for (unsigned int vcolor_index = 0; vcolor_index < vcolor_count; vcolor_index++) {
+ for (uint vcolor_index = 0; vcolor_index < vcolor_count; vcolor_index++) {
COLLADAFW::IndexList &color_index_list = *mp->getColorIndices(vcolor_index);
COLLADAFW::String colname = extract_vcolname(color_index_list.getName());
@@ -807,10 +834,10 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData &arr, int i,
return;
}
- v[0] = (float)(*values)[i++];
- v[1] = (float)(*values)[i++];
+ v[0] = float((*values)[i++]);
+ v[1] = float((*values)[i++]);
if (stride >= 3) {
- v[2] = (float)(*values)[i];
+ v[2] = float((*values)[i]);
}
else {
v[2] = 0.0f;
@@ -821,7 +848,7 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData &arr, int i,
}
}
-bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData &nor, int count)
+bool MeshImporter::is_flat_face(uint *nind, COLLADAFW::MeshVertexData &nor, int count)
{
float a[3], b[3];
@@ -868,6 +895,16 @@ std::string *MeshImporter::get_geometry_name(const std::string &mesh_name)
return nullptr;
}
+static bool bc_has_out_of_bound_indices(Mesh *me)
+{
+ for (const MLoop &loop : me->loops()) {
+ if (loop.v >= me->totvert) {
+ return true;
+ }
+ }
+ return false;
+}
+
/**
* this function checks if both objects have the same
* materials assigned to Object (in the same order)
@@ -1006,10 +1043,9 @@ void MeshImporter::assign_material_to_geom(
for (it = prims.begin(); it != prims.end(); it++) {
Primitive &prim = *it;
- MPoly *mpoly = prim.mpoly;
- for (int i = 0; i < prim.totpoly; i++, mpoly++) {
- mpoly->mat_nr = mat_index;
+ for (int i = 0; i < prim.totpoly; i++) {
+ prim.material_indices[i] = mat_index;
}
}
}
@@ -1072,7 +1108,7 @@ Object *MeshImporter::create_mesh_object(
COLLADAFW::MaterialBindingArray &mat_array = geom->getMaterialBindings();
/* loop through geom's materials */
- for (unsigned int i = 0; i < mat_array.getCount(); i++) {
+ for (uint i = 0; i < mat_array.getCount(); i++) {
if (mat_array[i].getReferencedMaterial().isValid()) {
assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, i);
@@ -1115,8 +1151,37 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
this->mesh_geom_map[std::string(me->id.name)] = str_geom_id;
read_vertices(mesh, me);
- read_polys(mesh, me);
+
+ blender::Vector<blender::float3> loop_normals;
+ read_polys(mesh, me, loop_normals);
+
BKE_mesh_calc_edges(me, false, false);
+
+ /* We must apply custom normals after edges have been calculated, because
+ * BKE_mesh_set_custom_normals()'s internals expect me->medge to be populated
+ * and for the MLoops to have correct edge indices. */
+ if (use_custom_normals && !loop_normals.is_empty()) {
+ /* BKE_mesh_set_custom_normals()'s internals also expect that each MLoop
+ * has a valid vertex index, which may not be the case due to the existing
+ * logic in read_polys(). This check isn't necessary in the no-custom-normals
+ * case because the invalid MLoops get stripped in a later step. */
+ if (bc_has_out_of_bound_indices(me)) {
+ fprintf(stderr, "Can't apply custom normals, encountered invalid loop vert indices!\n");
+ }
+ /* There may be a mismatch in lengths if one or more of the MeshPrimitives in
+ * the Geometry had missing or otherwise invalid normals. */
+ else if (me->totloop != loop_normals.size()) {
+ fprintf(stderr,
+ "Can't apply custom normals, me->totloop != loop_normals.size() (%d != %d)\n",
+ me->totloop,
+ int(loop_normals.size()));
+ }
+ else {
+ BKE_mesh_set_custom_normals(me, reinterpret_cast<float(*)[3]>(loop_normals.data()));
+ me->flag |= ME_AUTOSMOOTH;
+ }
+ }
+
/* read_lines() must be called after the face edges have been generated.
* Otherwise the loose edges will be silently deleted again. */
read_lines(mesh, me);
diff --git a/source/blender/io/collada/MeshImporter.h b/source/blender/io/collada/MeshImporter.h
index 92b387a4bfe..a59b24d4f24 100644
--- a/source/blender/io/collada/MeshImporter.h
+++ b/source/blender/io/collada/MeshImporter.h
@@ -24,6 +24,7 @@
#include "collada_utils.h"
#include "BLI_edgehash.h"
+#include "BLI_math_vec_types.hh"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -63,6 +64,7 @@ class VCOLDataWrapper {
class MeshImporter : public MeshImporterBase {
private:
UnitConverter *unitconverter;
+ bool use_custom_normals;
Main *m_bmain;
Scene *scene;
@@ -80,6 +82,7 @@ class MeshImporter : public MeshImporterBase {
* (<triangles>, <polylist>, etc.) */
struct Primitive {
MPoly *mpoly;
+ int *material_indices;
unsigned int totpoly;
};
typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive>> MaterialIdPrimitiveArrayMap;
@@ -155,7 +158,7 @@ class MeshImporter : public MeshImporterBase {
*
* TODO: import uv set names.
*/
- void read_polys(COLLADAFW::Mesh *mesh, Mesh *me);
+ void read_polys(COLLADAFW::Mesh *mesh, Mesh *me, blender::Vector<blender::float3> &loop_normals);
/**
* Read all loose edges.
* IMPORTANT: This function assumes that all edges from existing
@@ -178,6 +181,7 @@ class MeshImporter : public MeshImporterBase {
public:
MeshImporter(UnitConverter *unitconv,
+ bool use_custom_normals,
ArmatureImporter *arm,
Main *bmain,
Scene *sce,
diff --git a/source/blender/io/collada/SceneExporter.cpp b/source/blender/io/collada/SceneExporter.cpp
index 1b1da110573..b98ff27c89e 100644
--- a/source/blender/io/collada/SceneExporter.cpp
+++ b/source/blender/io/collada/SceneExporter.cpp
@@ -82,11 +82,13 @@ void SceneExporter::writeNodeList(std::vector<Object *> &child_objects, Object *
void SceneExporter::writeNode(Object *ob)
{
+ const Scene *scene = blender_context.get_scene();
ViewLayer *view_layer = blender_context.get_view_layer();
std::vector<Object *> child_objects;
- bc_get_children(child_objects, ob, view_layer);
- bool can_export = bc_is_in_Export_set(this->export_settings.get_export_set(), ob, view_layer);
+ bc_get_children(child_objects, ob, scene, view_layer);
+ bool can_export = bc_is_in_Export_set(
+ this->export_settings.get_export_set(), ob, scene, view_layer);
/* Add associated armature first if available */
bool armature_exported = false;
@@ -94,7 +96,7 @@ void SceneExporter::writeNode(Object *ob)
if (ob_arm != nullptr) {
armature_exported = bc_is_in_Export_set(
- this->export_settings.get_export_set(), ob_arm, view_layer);
+ this->export_settings.get_export_set(), ob_arm, scene, view_layer);
if (armature_exported && bc_is_marked(ob_arm)) {
writeNode(ob_arm);
bc_remove_mark(ob_arm);
diff --git a/source/blender/io/collada/SkinInfo.cpp b/source/blender/io/collada/SkinInfo.cpp
index 8144e0a499d..0654bae3730 100644
--- a/source/blender/io/collada/SkinInfo.cpp
+++ b/source/blender/io/collada/SkinInfo.cpp
@@ -77,7 +77,7 @@ void SkinInfo::transfer_int_array_data_const(const COLLADAFW::IntValuesArray &sr
void SkinInfo::transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray &src,
COLLADAFW::UIntValuesArray &dest)
{
- dest.setData((unsigned int *)src.getData(), src.getCount());
+ dest.setData((uint *)src.getData(), src.getCount());
dest.yieldOwnerShip();
}
@@ -90,7 +90,7 @@ void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData *
/* cannot transfer data for FloatOrDoubleArray, copy values manually */
const COLLADAFW::FloatOrDoubleArray &weight = skin->getWeights();
- for (unsigned int i = 0; i < weight.getValuesCount(); i++) {
+ for (uint i = 0; i < weight.getValuesCount(); i++) {
weights.push_back(bc_get_float_value(weight, i));
}
@@ -118,7 +118,7 @@ void SkinInfo::set_controller(const COLLADAFW::SkinController *co)
/* fill in joint UIDs */
const COLLADAFW::UniqueIdArray &joint_uids = co->getJoints();
- for (unsigned int i = 0; i < joint_uids.getCount(); i++) {
+ for (uint i = 0; i < joint_uids.getCount(); i++) {
joint_data[i].joint_uid = joint_uids[i];
/* store armature pointer */
@@ -181,7 +181,7 @@ bool SkinInfo::uses_joint_or_descendant(COLLADAFW::Node *node)
}
COLLADAFW::NodePointerArray &children = node->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
if (uses_joint_or_descendant(children[i])) {
return true;
}
@@ -254,9 +254,9 @@ void SkinInfo::link_armature(bContext *C,
*
* get def group by index with BLI_findlink */
- for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) {
+ for (uint vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) {
- unsigned int limit = weight + joints_per_vertex[vertex];
+ uint limit = weight + joints_per_vertex[vertex];
for (; weight < limit; weight++) {
int joint = joint_indices[weight], joint_weight = weight_indices[weight];
@@ -319,7 +319,7 @@ bool SkinInfo::find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_ro
}
COLLADAFW::NodePointerArray &children = tree_root->getChildNodes();
- for (unsigned int i = 0; i < children.getCount(); i++) {
+ for (uint i = 0; i < children.getCount(); i++) {
if (find_node_in_tree(node, children[i])) {
return true;
}
diff --git a/source/blender/io/collada/TransformReader.cpp b/source/blender/io/collada/TransformReader.cpp
index e5872c28bce..cc1334bd99b 100644
--- a/source/blender/io/collada/TransformReader.cpp
+++ b/source/blender/io/collada/TransformReader.cpp
@@ -33,7 +33,7 @@ void TransformReader::get_node_mat(float mat[4][4],
unit_m4(mat);
- for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) {
+ for (uint i = 0; i < node->getTransformations().getCount(); i++) {
COLLADAFW::Transformation *tm = node->getTransformations()[i];
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
@@ -87,8 +87,8 @@ void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[
{
COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm;
COLLADABU::Math::Vector3 &axis = ro->getRotationAxis();
- const float angle = (float)DEG2RAD(ro->getRotationAngle());
- const float ax[] = {(float)axis[0], (float)axis[1], (float)axis[2]};
+ const float angle = float(DEG2RAD(ro->getRotationAngle()));
+ const float ax[] = {float(axis[0]), float(axis[1]), float(axis[2])};
#if 0
float quat[4];
axis_angle_to_quat(quat, axis, angle);
@@ -104,15 +104,15 @@ void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float
unit_m4(m);
- m[3][0] = (float)t[0];
- m[3][1] = (float)t[1];
- m[3][2] = (float)t[2];
+ m[3][0] = float(t[0]);
+ m[3][1] = float(t[1]);
+ m[3][2] = float(t[2]);
}
void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
COLLADABU::Math::Vector3 &s = ((COLLADAFW::Scale *)tm)->getScale();
- float size[3] = {(float)s[0], (float)s[1], (float)s[2]};
+ float size[3] = {float(s[0]), float(s[1]), float(s[2])};
size_to_mat4(m, size);
}
diff --git a/source/blender/io/collada/collada.cpp b/source/blender/io/collada/collada.cpp
index d559c0b4962..c33363ef205 100644
--- a/source/blender/io/collada/collada.cpp
+++ b/source/blender/io/collada/collada.cpp
@@ -29,6 +29,7 @@ static void print_import_header(ImportSettings &import_settings)
fprintf(stderr, "+-- Collada Import parameters------\n");
fprintf(stderr, "| input file : %s\n", import_settings.filepath);
fprintf(stderr, "| use units : %s\n", (import_settings.import_units) ? "yes" : "no");
+ fprintf(stderr, "| custom normals : %s\n", (import_settings.custom_normals) ? "yes" : "no");
fprintf(stderr, "| autoconnect : %s\n", (import_settings.auto_connect) ? "yes" : "no");
fprintf(stderr, "+-- Armature Import parameters ----\n");
fprintf(stderr, "| find bone chains: %s\n", (import_settings.find_chains) ? "yes" : "no");
@@ -57,6 +58,7 @@ int collada_import(bContext *C, ImportSettings *import_settings)
int collada_export(bContext *C, ExportSettings *export_settings)
{
BlenderContext blender_context(C);
+ const Scene *scene = blender_context.get_scene();
ViewLayer *view_layer = blender_context.get_view_layer();
int includeFilter = OB_REL_NONE;
@@ -72,7 +74,7 @@ int collada_export(bContext *C, ExportSettings *export_settings)
*/
eObjectSet objectSet = (export_settings->selected) ? OB_SET_SELECTED : OB_SET_ALL;
export_settings->export_set = BKE_object_relational_superset(
- view_layer, objectSet, (eObRelationTypes)includeFilter);
+ scene, view_layer, objectSet, (eObRelationTypes)includeFilter);
int export_count = BLI_linklist_count(export_settings->export_set);
diff --git a/source/blender/io/collada/collada_internal.cpp b/source/blender/io/collada/collada_internal.cpp
index da9a4cd4a9b..60e8edaa3bc 100644
--- a/source/blender/io/collada/collada_internal.cpp
+++ b/source/blender/io/collada/collada_internal.cpp
@@ -47,7 +47,7 @@ UnitConverter::UnitSystem UnitConverter::isMetricSystem()
float UnitConverter::getLinearMeter()
{
- return (float)unit.getLinearUnitMeter();
+ return float(unit.getLinearUnitMeter());
}
void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
@@ -153,7 +153,7 @@ void UnitConverter::calculate_scale(Scene &sce)
* The COLLADA spec also allows additional chars for member access ('.'), these
* must obviously be removed too, otherwise they would be heavily misinterpreted.
*/
-const unsigned char translate_start_name_map[256] = {
+const uchar translate_start_name_map[256] = {
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
@@ -172,7 +172,7 @@ const unsigned char translate_start_name_map[256] = {
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
};
-const unsigned char translate_name_map[256] = {
+const uchar translate_name_map[256] = {
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
@@ -212,16 +212,16 @@ std::string translate_id(const std::string &id)
}
std::string id_translated = id;
- id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]];
- for (unsigned int i = 1; i < id_translated.size(); i++) {
- id_translated[i] = translate_name_map[(unsigned int)id_translated[i]];
+ id_translated[0] = translate_start_name_map[uint(id_translated[0])];
+ for (uint i = 1; i < id_translated.size(); i++) {
+ id_translated[i] = translate_name_map[uint(id_translated[i])];
}
/* It's so much workload now, the if () should speed up things. */
if (id_translated != id) {
/* Search duplicates. */
map_string_list::iterator iter = global_id_map.find(id_translated);
if (iter != global_id_map.end()) {
- unsigned int i = 0;
+ uint i = 0;
bool found = false;
for (i = 0; i < iter->second.size(); i++) {
if (id == iter->second[i]) {
diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp
index 75842734b08..22a73cd7db2 100644
--- a/source/blender/io/collada/collada_utils.cpp
+++ b/source/blender/io/collada/collada_utils.cpp
@@ -66,7 +66,7 @@
#include "ExportSettings.h"
#include "collada_utils.h"
-float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, unsigned int index)
+float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, uint index)
{
if (index >= array.getValuesCount()) {
return 0.0f;
@@ -197,6 +197,7 @@ Object *bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type
LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
BKE_collection_object_add(bmain, layer_collection->collection, ob);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, ob);
/* TODO: is setting active needed? */
BKE_view_layer_base_select_and_set_active(view_layer, base);
@@ -709,13 +710,13 @@ float bc_get_property(Bone *bone, std::string key, float def)
if (property) {
switch (property->type) {
case IDP_INT:
- result = (float)(IDP_Int(property));
+ result = float(IDP_Int(property));
break;
case IDP_FLOAT:
- result = (float)(IDP_Float(property));
+ result = float(IDP_Float(property));
break;
case IDP_DOUBLE:
- result = (float)(IDP_Double(property));
+ result = float(IDP_Double(property));
break;
default:
result = def;
@@ -1007,9 +1008,9 @@ void bc_create_restpose_mat(BCExportSettings &export_settings,
void bc_sanitize_v3(float v[3], int precision)
{
for (int i = 0; i < 3; i++) {
- double val = (double)v[i];
+ double val = double(v[i]);
val = double_round(val, precision);
- v[i] = (float)val;
+ v[i] = float(val);
}
}
@@ -1108,7 +1109,7 @@ static std::string bc_get_uvlayer_name(Mesh *me, int layer)
static bNodeTree *prepare_material_nodetree(Material *ma)
{
if (ma->nodetree == nullptr) {
- ma->nodetree = ntreeAddTree(nullptr, "Shader Nodetree", "ShaderNodeTree");
+ ntreeAddTreeEmbedded(nullptr, &ma->id, "Shader Nodetree", "ShaderNodeTree");
ma->use_nodes = true;
}
return ma->nodetree;
@@ -1338,7 +1339,7 @@ bool bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid)
bNodeSocket *socket = nodeFindSocket(shader, SOCK_IN, nodeid.c_str());
if (socket) {
bNodeSocketValueFloat *ref = (bNodeSocketValueFloat *)socket->default_value;
- val = (double)ref->value;
+ val = double(ref->value);
return true;
}
return false;
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
index 1fbddc45964..03c1ba94d94 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
@@ -272,10 +272,11 @@ void AbstractHierarchyIterator::export_graph_construct()
ExportGraph::key_type root_node_id = ObjectIdentifier::for_real_object(nullptr);
export_graph_[root_node_id] = ExportChildren();
- DEG_OBJECT_ITER_BEGIN (depsgraph_,
- object,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) {
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = depsgraph_;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, object) {
/* Non-instanced objects always have their object-parent as export-parent. */
const bool weak_export = mark_as_weak_export(object);
visit_object(object, object->parent, weak_export);
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc
index 6db3eccedbe..b9d7b6719b1 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc
@@ -20,6 +20,7 @@
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_scene.h"
@@ -127,13 +128,15 @@ void GpencilIO::prepare_camera_params(Scene *scene, const GpencilIOParams *ipara
void GpencilIO::create_object_list()
{
+ Scene *scene = CTX_data_scene(params_.C);
ViewLayer *view_layer = CTX_data_view_layer(params_.C);
float3 camera_z_axis;
copy_v3_v3(camera_z_axis, rv3d_->viewinv[2]);
ob_list_.clear();
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_GPENCIL) {
@@ -224,16 +227,16 @@ float2 GpencilIO::gpencil_3D_point_to_render_space(const float3 co)
float2 r_co;
mul_v2_project_m4_v3(&r_co.x, persmat_, &parent_co.x);
- r_co.x = (r_co.x + 1.0f) / 2.0f * (float)render_x_;
- r_co.y = (r_co.y + 1.0f) / 2.0f * (float)render_y_;
+ r_co.x = (r_co.x + 1.0f) / 2.0f * float(render_x_);
+ r_co.y = (r_co.y + 1.0f) / 2.0f * float(render_y_);
/* Invert X axis. */
if (invert_axis_[0]) {
- r_co.x = (float)render_x_ - r_co.x;
+ r_co.x = float(render_x_) - r_co.x;
}
/* Invert Y axis. */
if (invert_axis_[1]) {
- r_co.y = (float)render_y_ - r_co.y;
+ r_co.y = float(render_y_) - r_co.y;
}
return r_co;
@@ -241,7 +244,7 @@ float2 GpencilIO::gpencil_3D_point_to_render_space(const float3 co)
float2 GpencilIO::gpencil_3D_point_to_2D(const float3 co)
{
- const bool is_camera = (bool)(rv3d_->persp == RV3D_CAMOB);
+ const bool is_camera = bool(rv3d_->persp == RV3D_CAMOB);
if (is_camera) {
return gpencil_3D_point_to_render_space(co);
}
@@ -257,7 +260,7 @@ float GpencilIO::stroke_point_radius_get(bGPDlayer *gpl, bGPDstroke *gps)
/* Radius. */
bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view(
- rv3d_, gpd_, gpl, gps, 3, diff_mat_.values);
+ rv3d_->viewmat, gpd_, gpl, gps, 3, diff_mat_.values, 0.0f);
pt = &gps_perimeter->points[0];
const float2 screen_ex = gpencil_3D_point_to_2D(&pt->x);
@@ -289,9 +292,9 @@ void GpencilIO::prepare_stroke_export_colors(Object *ob, bGPDstroke *gps)
avg_opacity_ += pt.strength;
}
- mul_v4_v4fl(avg_color, avg_color, 1.0f / (float)gps->totpoints);
+ mul_v4_v4fl(avg_color, avg_color, 1.0f / float(gps->totpoints));
interp_v3_v3v3(stroke_color_, stroke_color_, avg_color, avg_color[3]);
- avg_opacity_ /= (float)gps->totpoints;
+ avg_opacity_ /= float(gps->totpoints);
/* Fill color. */
copy_v4_v4(fill_color_, gp_style->fill_rgba);
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.hh b/source/blender/io/gpencil/intern/gpencil_io_base.hh
index 4987ab34ffc..f712ed839d9 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.hh
@@ -70,7 +70,7 @@ class GpencilIO {
float stroke_color_[4], fill_color_[4];
/* Geometry functions. */
- /** Convert to screenspace. */
+ /** Convert to screen-space. */
bool gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co);
/** Convert to render space. */
float2 gpencil_3D_point_to_render_space(const float3 co);
diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
index 700d91791a8..ddd72f816b0 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
@@ -37,7 +37,7 @@
namespace blender ::io ::gpencil {
-static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *UNUSED(user_data))
+static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void * /*user_data*/)
{
printf("ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no, (HPDF_UINT)detail_no);
}
@@ -192,7 +192,7 @@ void GpencilExporterPDF::export_gpencil_layers()
}
else {
bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view(
- rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values);
+ rv3d_->viewmat, gpd_, gpl, gps_duplicate, 3, diff_mat_.values, 0.0f);
/* Sample stroke. */
if (params_.stroke_sample > 0.0f) {
diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
index 2601ad05ea7..58f12e9b8b1 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
@@ -217,7 +217,7 @@ void GpencilExporterSVG::export_gpencil_layers()
}
else {
bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view(
- rv3d_, gpd_, gpl, gps_duplicate, 3, diff_mat_.values);
+ rv3d_->viewmat, gpd_, gpl, gps_duplicate, 3, diff_mat_.values, 0.0f);
/* Sample stroke. */
if (params_.stroke_sample > 0.0f) {
diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_base.cc b/source/blender/io/gpencil/intern/gpencil_io_import_base.cc
index 6d4439243fd..f6d02d36a17 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_import_base.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_import_base.cc
@@ -31,7 +31,7 @@ Object *GpencilImporter::create_object()
const float *cur_loc = scene_->cursor.location;
const float rot[3] = {0.0f};
ushort local_view_bits = (params_.v3d && params_.v3d->localvd) ? params_.v3d->local_view_uuid :
- (ushort)0;
+ ushort(0);
Object *ob_gpencil = ED_object_add_type(params_.C,
OB_GPENCIL,
diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
index 06460a1beba..23c80900659 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
@@ -93,8 +93,8 @@ bool GpencilImporterSVG::read()
/* Check frame. */
bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, cfra_, GP_GETFRAME_ADD_NEW);
/* Create materials. */
- bool is_stroke = (bool)shape->stroke.type;
- bool is_fill = (bool)shape->fill.type;
+ bool is_stroke = bool(shape->stroke.type);
+ bool is_fill = bool(shape->fill.type);
if ((!is_stroke) && (!is_fill)) {
is_stroke = true;
}
@@ -148,11 +148,11 @@ void GpencilImporterSVG::create_stroke(bGPdata *gpd,
const int32_t mat_index,
const float matrix[4][4])
{
- const bool is_stroke = (bool)shape->stroke.type;
- const bool is_fill = (bool)shape->fill.type;
+ const bool is_stroke = bool(shape->stroke.type);
+ const bool is_fill = bool(shape->fill.type);
const int edges = params_.resolution;
- const float step = 1.0f / (float)(edges - 1);
+ const float step = 1.0f / float(edges - 1);
const int totpoints = (path->npts / 3) * params_.resolution;
@@ -212,19 +212,19 @@ void GpencilImporterSVG::create_stroke(bGPdata *gpd,
}
/* Unpack internal NanoSVG color. */
-static void unpack_nano_color(const unsigned int pack, float r_col[4])
+static void unpack_nano_color(const uint pack, float r_col[4])
{
- unsigned char rgb_u[4];
+ uchar rgb_u[4];
rgb_u[0] = ((pack) >> 0) & 0xFF;
rgb_u[1] = ((pack) >> 8) & 0xFF;
rgb_u[2] = ((pack) >> 16) & 0xFF;
rgb_u[3] = ((pack) >> 24) & 0xFF;
- r_col[0] = (float)rgb_u[0] / 255.0f;
- r_col[1] = (float)rgb_u[1] / 255.0f;
- r_col[2] = (float)rgb_u[2] / 255.0f;
- r_col[3] = (float)rgb_u[3] / 255.0f;
+ r_col[0] = float(rgb_u[0]) / 255.0f;
+ r_col[1] = float(rgb_u[1]) / 255.0f;
+ r_col[2] = float(rgb_u[2]) / 255.0f;
+ r_col[3] = float(rgb_u[3]) / 255.0f;
}
void GpencilImporterSVG::convert_color(const int32_t color, float r_linear_rgba[4])
diff --git a/source/blender/io/stl/importer/stl_import.cc b/source/blender/io/stl/importer/stl_import.cc
index 097d14b038c..e5fde6658ab 100644
--- a/source/blender/io/stl/importer/stl_import.cc
+++ b/source/blender/io/stl/importer/stl_import.cc
@@ -99,11 +99,12 @@ void importer_main(Main *bmain,
BKE_mesh_validate(mesh, verbose_validate, false);
}
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
Object *obj = BKE_object_add_only_object(bmain, OB_MESH, ob_name);
BKE_mesh_assign_object(bmain, obj, mesh);
BKE_collection_object_add(bmain, lc->collection, obj);
+ BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, obj);
BKE_view_layer_base_select_and_set_active(view_layer, base);
diff --git a/source/blender/io/stl/importer/stl_import_ascii_reader.cc b/source/blender/io/stl/importer/stl_import_ascii_reader.cc
index 2edb3c6a114..6a976a2fd2c 100644
--- a/source/blender/io/stl/importer/stl_import_ascii_reader.cc
+++ b/source/blender/io/stl/importer/stl_import_ascii_reader.cc
@@ -97,7 +97,7 @@ class StringBuffer {
start++;
}
fast_float::from_chars_result res = fast_float::from_chars(start, end, out);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
out = 0.0f;
}
start = const_cast<char *>(res.ptr);
diff --git a/source/blender/io/stl/importer/stl_import_mesh.cc b/source/blender/io/stl/importer/stl_import_mesh.cc
index b9ed441f0d9..de993cd2f27 100644
--- a/source/blender/io/stl/importer/stl_import_mesh.cc
+++ b/source/blender/io/stl/importer/stl_import_mesh.cc
@@ -76,27 +76,26 @@ Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name)
id_us_min(&mesh->id);
mesh->totvert = verts_.size();
- mesh->mvert = static_cast<MVert *>(
- CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, nullptr, mesh->totvert));
+ CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, mesh->totvert);
+ MutableSpan<MVert> verts = mesh->verts_for_write();
for (int i = 0; i < mesh->totvert; i++) {
- copy_v3_v3(mesh->mvert[i].co, verts_[i]);
+ copy_v3_v3(verts[i].co, verts_[i]);
}
mesh->totpoly = tris_.size();
mesh->totloop = tris_.size() * 3;
- mesh->mpoly = static_cast<MPoly *>(
- CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, nullptr, mesh->totpoly));
- mesh->mloop = static_cast<MLoop *>(
- CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, nullptr, mesh->totloop));
-
+ CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, mesh->totpoly);
+ CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, mesh->totloop);
+ MutableSpan<MPoly> polys = mesh->polys_for_write();
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
threading::parallel_for(tris_.index_range(), 2048, [&](IndexRange tris_range) {
for (const int i : tris_range) {
- mesh->mpoly[i].loopstart = 3 * i;
- mesh->mpoly[i].totloop = 3;
+ polys[i].loopstart = 3 * i;
+ polys[i].totloop = 3;
- mesh->mloop[3 * i].v = tris_[i].v1;
- mesh->mloop[3 * i + 1].v = tris_[i].v2;
- mesh->mloop[3 * i + 2].v = tris_[i].v3;
+ loops[3 * i].v = tris_[i].v1;
+ loops[3 * i + 1].v = tris_[i].v2;
+ loops[3 * i + 2].v = tris_[i].v3;
}
});
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 73b7d875c2f..efa22b2add2 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -20,13 +20,14 @@ add_definitions(-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1)
# add a USD_HAS_IMAGING define so code can dynamically detect this.
# Cleanup of this variable is done at the end of the file since
# test code further down uses it to add imaging tests.
-FIND_FILE(USD_IMAGING_HEADERS
+find_file(
+ USD_IMAGING_HEADERS
NAMES
capsuleAdapter.h
PATHS
- ${USD_INCLUDE_DIRS}
+ ${USD_INCLUDE_DIRS}
PATH_SUFFIXES
- pxr/usdImaging/usdImaging/
+ pxr/usdImaging/usdImaging/
NO_DEFAULT_PATH
)
@@ -164,7 +165,7 @@ if(WITH_GTESTS)
tests/usd_tests_common.h
)
if(USD_IMAGING_HEADERS)
- LIST(APPEND TEST_SRC tests/usd_imaging_test.cc)
+ list(APPEND TEST_SRC tests/usd_imaging_test.cc)
endif()
set(TEST_INC
diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc
index 0fbfa4c6d5d..6731412e158 100644
--- a/source/blender/io/usd/intern/usd_capi_export.cc
+++ b/source/blender/io/usd/intern/usd_capi_export.cc
@@ -96,8 +96,7 @@ static void export_startjob(void *customdata,
}
usd_stage->SetMetadata(pxr::UsdGeomTokens->upAxis, pxr::VtValue(pxr::UsdGeomTokens->z));
- usd_stage->SetMetadata(pxr::UsdGeomTokens->metersPerUnit,
- static_cast<double>(scene->unit.scale_length));
+ usd_stage->SetMetadata(pxr::UsdGeomTokens->metersPerUnit, double(scene->unit.scale_length));
usd_stage->GetRootLayer()->SetDocumentation(std::string("Blender v") +
BKE_blender_version_string());
@@ -120,7 +119,7 @@ static void export_startjob(void *customdata,
}
/* Update the scene for the next frame to render. */
- scene->r.cfra = static_cast<int>(frame);
+ scene->r.cfra = int(frame);
scene->r.subframe = frame - scene->r.cfra;
BKE_scene_graph_update_for_newframe(data->depsgraph);
diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc
index c80faa5960e..cd50f41b9fb 100644
--- a/source/blender/io/usd/intern/usd_capi_import.cc
+++ b/source/blender/io/usd/intern/usd_capi_import.cc
@@ -230,7 +230,7 @@ static void import_startjob(void *customdata, short *stop, short *do_update, flo
*data->do_update = true;
*data->progress = 0.2f;
- const float size = static_cast<float>(archive->readers().size());
+ const float size = float(archive->readers().size());
size_t i = 0;
/* Sort readers by name: when creating a lot of objects in Blender,
@@ -310,9 +310,10 @@ static void import_endjob(void *customdata)
else if (data->archive) {
Base *base;
LayerCollection *lc;
+ const Scene *scene = data->scene;
ViewLayer *view_layer = data->view_layer;
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
lc = BKE_layer_collection_get_active(view_layer);
@@ -332,6 +333,7 @@ static void import_endjob(void *customdata)
/* Sync the collection, and do view layer operations. */
BKE_layer_collection_resync_allow();
BKE_main_collection_sync(data->bmain);
+ BKE_view_layer_synced_ensure(scene, view_layer);
for (USDPrimReader *reader : data->archive->readers()) {
if (!reader) {
continue;
diff --git a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
index 51261c4d91e..fbfda975055 100644
--- a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
+++ b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
@@ -141,7 +141,7 @@ AbstractHierarchyWriter *USDHierarchyIterator::create_hair_writer(const Hierarch
}
AbstractHierarchyWriter *USDHierarchyIterator::create_particle_writer(
- const HierarchyContext *UNUSED(context))
+ const HierarchyContext * /*context*/)
{
return nullptr;
}
diff --git a/source/blender/io/usd/intern/usd_reader_camera.cc b/source/blender/io/usd/intern/usd_reader_camera.cc
index 7f1e9fef89d..da51787e437 100644
--- a/source/blender/io/usd/intern/usd_reader_camera.cc
+++ b/source/blender/io/usd/intern/usd_reader_camera.cc
@@ -71,7 +71,7 @@ void USDCameraReader::read_object_data(Main *bmain, const double motionSampleTim
bcam->clip_end = clippingRangeVal.UncheckedGet<pxr::GfVec2f>()[1];
bcam->dof.focus_distance = focalDistanceVal.Get<float>();
- bcam->dof.aperture_fstop = static_cast<float>(fstopVal.Get<float>());
+ bcam->dof.aperture_fstop = float(fstopVal.Get<float>());
if (bcam->type == CAM_ORTHO) {
bcam->ortho_scale = max_ff(verAp.Get<float>(), horAp.Get<float>());
diff --git a/source/blender/io/usd/intern/usd_reader_curve.cc b/source/blender/io/usd/intern/usd_reader_curve.cc
index 0d3c2feb8f3..ca48f3c2391 100644
--- a/source/blender/io/usd/intern/usd_reader_curve.cc
+++ b/source/blender/io/usd/intern/usd_reader_curve.cc
@@ -139,9 +139,9 @@ void USDCurvesReader::read_curve_sample(Curve *cu, const double motionSampleTime
BPoint *bp = nu->bp;
for (int j = 0; j < nu->pntsu; j++, bp++, idx++) {
- bp->vec[0] = (float)usdPoints[idx][0];
- bp->vec[1] = (float)usdPoints[idx][1];
- bp->vec[2] = (float)usdPoints[idx][2];
+ bp->vec[0] = float(usdPoints[idx][0]);
+ bp->vec[1] = float(usdPoints[idx][1]);
+ bp->vec[2] = float(usdPoints[idx][2]);
bp->vec[3] = weight;
bp->f1 = SELECT;
bp->weight = weight;
diff --git a/source/blender/io/usd/intern/usd_reader_curve.h b/source/blender/io/usd/intern/usd_reader_curve.h
index 1e9330b81f1..48fb2c5e2d1 100644
--- a/source/blender/io/usd/intern/usd_reader_curve.h
+++ b/source/blender/io/usd/intern/usd_reader_curve.h
@@ -27,7 +27,7 @@ class USDCurvesReader : public USDGeomReader {
bool valid() const override
{
- return static_cast<bool>(curve_prim_);
+ return bool(curve_prim_);
}
void create_object(Main *bmain, double motionSampleTime) override;
diff --git a/source/blender/io/usd/intern/usd_reader_light.cc b/source/blender/io/usd/intern/usd_reader_light.cc
index 55b9557dfb5..7204ea91896 100644
--- a/source/blender/io/usd/intern/usd_reader_light.cc
+++ b/source/blender/io/usd/intern/usd_reader_light.cc
@@ -203,7 +203,7 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime
if (pxr::UsdAttribute cone_angle_attr = shaping_api.GetShapingConeAngleAttr()) {
float cone_angle = 0.0f;
if (cone_angle_attr.Get(&cone_angle, motionSampleTime)) {
- blight->spotsize = cone_angle * ((float)M_PI / 180.0f) * 2.0f;
+ blight->spotsize = cone_angle * (float(M_PI) / 180.0f) * 2.0f;
}
}
@@ -226,7 +226,7 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime
if (pxr::UsdAttribute angle_attr = distant_light.GetAngleAttr()) {
float angle = 0.0f;
if (angle_attr.Get(&angle, motionSampleTime)) {
- blight->sun_angle = angle * (float)M_PI / 180.0f;
+ blight->sun_angle = angle * float(M_PI) / 180.0f;
}
}
}
diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc
index f59b8be147e..d1af4553083 100644
--- a/source/blender/io/usd/intern/usd_reader_material.cc
+++ b/source/blender/io/usd/intern/usd_reader_material.cc
@@ -4,6 +4,7 @@
#include "usd_reader_material.h"
#include "BKE_image.h"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
@@ -323,6 +324,7 @@ Material *USDMaterialReader::add_material(const pxr::UsdShadeMaterial &usd_mater
/* Create the material. */
Material *mtl = BKE_material_add(bmain_, mtl_name.c_str());
+ id_us_min(&mtl->id);
/* Get the UsdPreviewSurface shader source for the material,
* if there is one. */
@@ -351,8 +353,7 @@ void USDMaterialReader::import_usd_preview(Material *mtl,
* and output shaders. */
/* Add the node tree. */
- bNodeTree *ntree = ntreeAddTree(nullptr, "Shader Nodetree", "ShaderNodeTree");
- mtl->nodetree = ntree;
+ bNodeTree *ntree = ntreeAddTreeEmbedded(nullptr, &mtl->id, "Shader Nodetree", "ShaderNodeTree");
mtl->use_nodes = true;
/* Create the Principled BSDF shader node. */
@@ -561,7 +562,7 @@ void USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
/* For now, only convert UsdUVTexture and UsdPrimvarReader_float2 inputs. */
if (shader_id == usdtokens::UsdUVTexture) {
- if (strcmp(dest_socket_name, "Normal") == 0) {
+ if (STREQ(dest_socket_name, "Normal")) {
/* The normal texture input requires creating a normal map node. */
float locx = 0.0f;
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc
index 103bb0d0cef..77c79852141 100644
--- a/source/blender/io/usd/intern/usd_reader_mesh.cc
+++ b/source/blender/io/usd/intern/usd_reader_mesh.cc
@@ -6,6 +6,7 @@
#include "usd_reader_mesh.h"
#include "usd_reader_material.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -102,7 +103,7 @@ static Material *find_existing_material(
return mat_iter->second;
}
/* We can't find the Blender material which was previously created for this USD
- * material, which should never happen. */
+ * material, which should never happen. */
BLI_assert_unreachable();
}
}
@@ -182,6 +183,9 @@ static void assign_materials(Main *bmain,
std::cout << "WARNING: Couldn't assign material " << it->first << std::endl;
}
}
+ if (ob->totcol > 0) {
+ ob->actcol = 1;
+ }
}
} // namespace utils
@@ -207,7 +211,8 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, const int data_type
/* Create a new layer. */
numloops = mesh->totloop;
- cd_ptr = CustomData_add_layer_named(loopdata, cd_data_type, CD_DEFAULT, nullptr, numloops, name);
+ cd_ptr = CustomData_add_layer_named(
+ loopdata, cd_data_type, CD_SET_DEFAULT, nullptr, numloops, name);
return cd_ptr;
}
@@ -243,11 +248,7 @@ void USDMeshReader::read_object_data(Main *bmain, const double motionSampleTime)
is_initial_load_ = false;
if (read_mesh != mesh) {
- /* FIXME: after 2.80; `mesh->flag` isn't copied by #BKE_mesh_nomain_to_mesh() */
- /* read_mesh can be freed by BKE_mesh_nomain_to_mesh(), so get the flag before that happens. */
- uint16_t autosmooth = (read_mesh->flag & ME_AUTOSMOOTH);
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, object_, &CD_MASK_MESH, true);
- mesh->flag |= autosmooth;
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, object_);
}
readFaceSetsSample(bmain, mesh, motionSampleTime);
@@ -274,7 +275,7 @@ void USDMeshReader::read_object_data(Main *bmain, const double motionSampleTime)
bool USDMeshReader::valid() const
{
- return static_cast<bool>(mesh_prim_);
+ return bool(mesh_prim_);
}
bool USDMeshReader::topology_changed(const Mesh *existing_mesh, const double motionSampleTime)
@@ -307,18 +308,17 @@ bool USDMeshReader::topology_changed(const Mesh *existing_mesh, const double mot
void USDMeshReader::read_mpolys(Mesh *mesh)
{
- MPoly *mpolys = mesh->mpoly;
- MLoop *mloops = mesh->mloop;
+ MutableSpan<MPoly> polys = mesh->polys_for_write();
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
int loop_index = 0;
for (int i = 0; i < face_counts_.size(); i++) {
const int face_size = face_counts_[i];
- MPoly &poly = mpolys[i];
+ MPoly &poly = polys[i];
poly.loopstart = loop_index;
poly.totloop = face_size;
- poly.mat_nr = 0;
/* Polygons are always assumed to be smooth-shaded. If the mesh should be flat-shaded,
* this is encoded in custom loop normals. */
@@ -327,12 +327,12 @@ void USDMeshReader::read_mpolys(Mesh *mesh)
if (is_left_handed_) {
int loop_end_index = loop_index + (face_size - 1);
for (int f = 0; f < face_size; ++f, ++loop_index) {
- mloops[loop_index].v = face_indices_[loop_end_index - f];
+ loops[loop_index].v = face_indices_[loop_end_index - f];
}
}
else {
for (int f = 0; f < face_size; ++f, ++loop_index) {
- mloops[loop_index].v = face_indices_[loop_index];
+ loops[loop_index].v = face_indices_[loop_index];
}
}
}
@@ -342,9 +342,9 @@ void USDMeshReader::read_mpolys(Mesh *mesh)
void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bool load_uvs)
{
- unsigned int loop_index = 0;
- unsigned int rev_loop_index = 0;
- unsigned int uv_index = 0;
+ uint loop_index = 0;
+ uint rev_loop_index = 0;
+ uint uv_index = 0;
const CustomData *ldata = &mesh->ldata;
@@ -396,6 +396,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
}
}
+ const Span<MLoop> loops = mesh->loops();
for (int i = 0; i < face_counts_.size(); i++) {
const int face_size = face_counts_[i];
@@ -421,9 +422,9 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
const UVSample &sample = uv_primvars[layer_idx];
- if (!(ELEM(sample.interpolation,
- pxr::UsdGeomTokens->faceVarying,
- pxr::UsdGeomTokens->vertex))) {
+ if (!ELEM(sample.interpolation,
+ pxr::UsdGeomTokens->faceVarying,
+ pxr::UsdGeomTokens->vertex)) {
std::cerr << "WARNING: unexpected interpolation type " << sample.interpolation
<< " for uv " << layer->name << std::endl;
continue;
@@ -431,7 +432,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
/* For Vertex interpolation, use the vertex index. */
int usd_uv_index = sample.interpolation == pxr::UsdGeomTokens->vertex ?
- mesh->mloop[loop_index].v :
+ loops[loop_index].v :
loop_index;
if (usd_uv_index >= sample.uvs.size()) {
@@ -511,24 +512,23 @@ void USDMeshReader::read_colors(Mesh *mesh, const double motionSampleTime)
MLoopCol *colors = static_cast<MLoopCol *>(cd_ptr);
- mesh->mloopcol = colors;
-
- MPoly *poly = mesh->mpoly;
-
- for (int i = 0, e = mesh->totpoly; i < e; ++i, ++poly) {
- for (int j = 0; j < poly->totloop; ++j) {
- int loop_index = poly->loopstart + j;
+ const Span<MPoly> polys = mesh->polys();
+ const Span<MLoop> loops = mesh->loops();
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ for (int j = 0; j < poly.totloop; ++j) {
+ int loop_index = poly.loopstart + j;
/* Default for constant varying interpolation. */
int usd_index = 0;
if (interp == pxr::UsdGeomTokens->vertex) {
- usd_index = mesh->mloop[loop_index].v;
+ usd_index = loops[loop_index].v;
}
else if (interp == pxr::UsdGeomTokens->faceVarying) {
- usd_index = poly->loopstart;
+ usd_index = poly.loopstart;
if (is_left_handed_) {
- usd_index += poly->totloop - 1 - j;
+ usd_index += poly.totloop - 1 - j;
}
else {
usd_index += j;
@@ -576,7 +576,7 @@ void USDMeshReader::read_vertex_creases(Mesh *mesh, const double motionSampleTim
}
float *creases = static_cast<float *>(
- CustomData_add_layer(&mesh->vdata, CD_CREASE, CD_DEFAULT, nullptr, mesh->totvert));
+ CustomData_add_layer(&mesh->vdata, CD_CREASE, CD_SET_DEFAULT, nullptr, mesh->totvert));
for (size_t i = 0; i < corner_indices.size(); i++) {
creases[corner_indices[i]] = corner_sharpnesses[i];
@@ -601,7 +601,7 @@ void USDMeshReader::process_normals_vertex_varying(Mesh *mesh)
MutableSpan vert_normals{(float3 *)BKE_mesh_vertex_normals_for_write(mesh), mesh->totvert};
BLI_STATIC_ASSERT(sizeof(normals_[0]) == sizeof(float3), "Expected float3 normals size");
- vert_normals.copy_from({(float3 *)normals_.data(), static_cast<int64_t>(normals_.size())});
+ vert_normals.copy_from({(float3 *)normals_.data(), int64_t(normals_.size())});
BKE_mesh_vertex_normals_clear_dirty(mesh);
}
@@ -626,15 +626,15 @@ void USDMeshReader::process_normals_face_varying(Mesh *mesh)
float(*lnors)[3] = static_cast<float(*)[3]>(
MEM_malloc_arrayN(loop_count, sizeof(float[3]), "USD::FaceNormals"));
- MPoly *mpoly = mesh->mpoly;
-
- for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mpoly) {
- for (int j = 0; j < mpoly->totloop; j++) {
- int blender_index = mpoly->loopstart + j;
+ const Span<MPoly> polys = mesh->polys();
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ for (int j = 0; j < poly.totloop; j++) {
+ int blender_index = poly.loopstart + j;
- int usd_index = mpoly->loopstart;
+ int usd_index = poly.loopstart;
if (is_left_handed_) {
- usd_index += mpoly->totloop - 1 - j;
+ usd_index += poly.totloop - 1 - j;
}
else {
usd_index += j;
@@ -667,12 +667,11 @@ void USDMeshReader::process_normals_uniform(Mesh *mesh)
float(*lnors)[3] = static_cast<float(*)[3]>(
MEM_malloc_arrayN(mesh->totloop, sizeof(float[3]), "USD::FaceNormals"));
- MPoly *mpoly = mesh->mpoly;
-
- for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mpoly) {
-
- for (int j = 0; j < mpoly->totloop; j++) {
- int loop_index = mpoly->loopstart + j;
+ const Span<MPoly> polys = mesh->polys();
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ for (int j = 0; j < poly.totloop; j++) {
+ int loop_index = poly.loopstart + j;
lnors[loop_index][0] = normals_[i][0];
lnors[loop_index][1] = normals_[i][1];
lnors[loop_index][2] = normals_[i][2];
@@ -695,8 +694,9 @@ void USDMeshReader::read_mesh_sample(ImportSettings *settings,
* in code that expect this data to be there. */
if (new_mesh || (settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
+ MutableSpan<MVert> verts = mesh->verts_for_write();
for (int i = 0; i < positions_.size(); i++) {
- MVert &mvert = mesh->mvert[i];
+ MVert &mvert = verts[i];
mvert.co[0] = positions_[i][0];
mvert.co[1] = positions_[i][1];
mvert.co[2] = positions_[i][2];
@@ -734,10 +734,9 @@ void USDMeshReader::read_mesh_sample(ImportSettings *settings,
}
}
-void USDMeshReader::assign_facesets_to_mpoly(double motionSampleTime,
- MPoly *mpoly,
- const int /* totpoly */,
- std::map<pxr::SdfPath, int> *r_mat_map)
+void USDMeshReader::assign_facesets_to_material_indices(double motionSampleTime,
+ MutableSpan<int> material_indices,
+ std::map<pxr::SdfPath, int> *r_mat_map)
{
if (r_mat_map == nullptr) {
return;
@@ -777,9 +776,8 @@ void USDMeshReader::assign_facesets_to_mpoly(double motionSampleTime,
pxr::VtIntArray indices;
indicesAttribute.Get(&indices, motionSampleTime);
- for (int i = 0; i < indices.size(); i++) {
- MPoly &poly = mpoly[indices[i]];
- poly.mat_nr = mat_idx;
+ for (const int i : indices) {
+ material_indices[i] = mat_idx;
}
}
}
@@ -804,7 +802,12 @@ void USDMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const double mot
}
std::map<pxr::SdfPath, int> mat_map;
- assign_facesets_to_mpoly(motionSampleTime, mesh->mpoly, mesh->totpoly, &mat_map);
+
+ bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ bke::SpanAttributeWriter<int> material_indices =
+ attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ this->assign_facesets_to_material_indices(motionSampleTime, material_indices.span, &mat_map);
+ material_indices.finish();
/* Build material name map if it's not built yet. */
if (this->settings_->mat_name_to_mat.empty()) {
utils::build_mat_map(bmain, &this->settings_->mat_name_to_mat);
@@ -862,7 +865,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
pxr::TfToken interp = p.GetInterpolation();
- if (!(ELEM(interp, pxr::UsdGeomTokens->faceVarying, pxr::UsdGeomTokens->vertex))) {
+ if (!ELEM(interp, pxr::UsdGeomTokens->faceVarying, pxr::UsdGeomTokens->vertex)) {
continue;
}
@@ -896,8 +899,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
existing_mesh, positions_.size(), 0, 0, face_indices_.size(), face_counts_.size());
for (pxr::TfToken token : uv_tokens) {
- void *cd_ptr = add_customdata_cb(active_mesh, token.GetText(), CD_MLOOPUV);
- active_mesh->mloopuv = static_cast<MLoopUV *>(cd_ptr);
+ add_customdata_cb(active_mesh, token.GetText(), CD_MLOOPUV);
}
}
@@ -907,10 +909,14 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
/* Here we assume that the number of materials doesn't change, i.e. that
* the material slots that were created when the object was loaded from
* USD are still valid now. */
- size_t num_polys = active_mesh->totpoly;
- if (num_polys > 0 && import_params_.import_materials) {
+ MutableSpan<MPoly> polys = active_mesh->polys_for_write();
+ if (!polys.is_empty() && import_params_.import_materials) {
std::map<pxr::SdfPath, int> mat_map;
- assign_facesets_to_mpoly(motionSampleTime, active_mesh->mpoly, num_polys, &mat_map);
+ bke::MutableAttributeAccessor attributes = active_mesh->attributes_for_write();
+ bke::SpanAttributeWriter<int> material_indices =
+ attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ assign_facesets_to_material_indices(motionSampleTime, material_indices.span, &mat_map);
+ material_indices.finish();
}
}
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.h b/source/blender/io/usd/intern/usd_reader_mesh.h
index 5e33ce8b5e8..181fd5ebf79 100644
--- a/source/blender/io/usd/intern/usd_reader_mesh.h
+++ b/source/blender/io/usd/intern/usd_reader_mesh.h
@@ -3,13 +3,13 @@
* Modifications Copyright 2021 Tangent Animation and. NVIDIA Corporation. All rights reserved. */
#pragma once
+#include "BLI_span.hh"
+
#include "usd.h"
#include "usd_reader_geom.h"
#include "pxr/usd/usdGeom/mesh.h"
-struct MPoly;
-
namespace blender::io::usd {
class USDMeshReader : public USDGeomReader {
@@ -61,10 +61,9 @@ class USDMeshReader : public USDGeomReader {
/** Set USD uniform (per-face) normals as Blender loop normals. */
void process_normals_uniform(Mesh *mesh);
void readFaceSetsSample(Main *bmain, Mesh *mesh, double motionSampleTime);
- void assign_facesets_to_mpoly(double motionSampleTime,
- struct MPoly *mpoly,
- int totpoly,
- std::map<pxr::SdfPath, int> *r_mat_map);
+ void assign_facesets_to_material_indices(double motionSampleTime,
+ MutableSpan<int> material_indices,
+ std::map<pxr::SdfPath, int> *r_mat_map);
void read_mpolys(Mesh *mesh);
void read_uvs(Mesh *mesh, double motionSampleTime, bool load_uvs = false);
diff --git a/source/blender/io/usd/intern/usd_reader_nurbs.cc b/source/blender/io/usd/intern/usd_reader_nurbs.cc
index d0a5dc1c4b4..0a7058fb100 100644
--- a/source/blender/io/usd/intern/usd_reader_nurbs.cc
+++ b/source/blender/io/usd/intern/usd_reader_nurbs.cc
@@ -33,7 +33,7 @@ static bool set_knots(const pxr::VtDoubleArray &knots, float *&nu_knots)
nu_knots = static_cast<float *>(MEM_callocN(num_knots * sizeof(float), __func__));
for (size_t i = 0; i < num_knots; i++) {
- nu_knots[i] = (float)knots[i];
+ nu_knots[i] = float(knots[i]);
}
return true;
@@ -117,7 +117,7 @@ void USDNurbsReader::read_curve_sample(Curve *cu, const double motionSampleTime)
nu->pntsv = 1;
if (i < orders.size()) {
- nu->orderu = static_cast<short>(orders[i]);
+ nu->orderu = short(orders[i]);
}
else {
nu->orderu = 4;
@@ -141,9 +141,9 @@ void USDNurbsReader::read_curve_sample(Curve *cu, const double motionSampleTime)
BPoint *bp = nu->bp;
for (int j = 0; j < nu->pntsu; j++, bp++, idx++) {
- bp->vec[0] = (float)usdPoints[idx][0];
- bp->vec[1] = (float)usdPoints[idx][1];
- bp->vec[2] = (float)usdPoints[idx][2];
+ bp->vec[0] = float(usdPoints[idx][0]);
+ bp->vec[1] = float(usdPoints[idx][1]);
+ bp->vec[2] = float(usdPoints[idx][2]);
bp->vec[3] = weight;
bp->f1 = SELECT;
bp->weight = weight;
diff --git a/source/blender/io/usd/intern/usd_reader_nurbs.h b/source/blender/io/usd/intern/usd_reader_nurbs.h
index a5441aad3cf..aa3940dc540 100644
--- a/source/blender/io/usd/intern/usd_reader_nurbs.h
+++ b/source/blender/io/usd/intern/usd_reader_nurbs.h
@@ -27,7 +27,7 @@ class USDNurbsReader : public USDGeomReader {
bool valid() const override
{
- return static_cast<bool>(curve_prim_);
+ return bool(curve_prim_);
}
void create_object(Main *bmain, double motionSampleTime) override;
diff --git a/source/blender/io/usd/intern/usd_reader_volume.cc b/source/blender/io/usd/intern/usd_reader_volume.cc
index 13044de5002..fc25dda53b9 100644
--- a/source/blender/io/usd/intern/usd_reader_volume.cc
+++ b/source/blender/io/usd/intern/usd_reader_volume.cc
@@ -65,10 +65,10 @@ void USDVolumeReader::read_object_data(Main *bmain, const double motionSampleTim
filepathAttr.GetTimeSamples(&filePathTimes);
if (!filePathTimes.empty()) {
- int start = static_cast<int>(filePathTimes.front());
- int end = static_cast<int>(filePathTimes.back());
+ int start = int(filePathTimes.front());
+ int end = int(filePathTimes.back());
- volume->is_sequence = static_cast<char>(true);
+ volume->is_sequence = char(true);
volume->frame_start = start;
volume->frame_duration = (end - start) + 1;
}
diff --git a/source/blender/io/usd/intern/usd_reader_volume.h b/source/blender/io/usd/intern/usd_reader_volume.h
index 350fae6ada0..923c3d140c9 100644
--- a/source/blender/io/usd/intern/usd_reader_volume.h
+++ b/source/blender/io/usd/intern/usd_reader_volume.h
@@ -23,7 +23,7 @@ class USDVolumeReader : public USDXformReader {
bool valid() const override
{
- return static_cast<bool>(volume_);
+ return bool(volume_);
}
void create_object(Main *bmain, double motionSampleTime) override;
diff --git a/source/blender/io/usd/intern/usd_writer_hair.cc b/source/blender/io/usd/intern/usd_writer_hair.cc
index 478a9e26274..8ec1447b505 100644
--- a/source/blender/io/usd/intern/usd_writer_hair.cc
+++ b/source/blender/io/usd/intern/usd_writer_hair.cc
@@ -64,7 +64,7 @@ void USDHairWriter::do_write(HierarchyContext &context)
}
}
-bool USDHairWriter::check_is_animated(const HierarchyContext &UNUSED(context)) const
+bool USDHairWriter::check_is_animated(const HierarchyContext & /*context*/) const
{
return true;
}
diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc
index 6862f3835cf..c195bf0e0bd 100644
--- a/source/blender/io/usd/intern/usd_writer_material.cc
+++ b/source/blender/io/usd/intern/usd_writer_material.cc
@@ -455,7 +455,7 @@ static bNode *traverse_channel(bNodeSocket *input, const short target_type)
static bNode *find_bsdf_node(Material *material)
{
LISTBASE_FOREACH (bNode *, node, &material->nodetree->nodes) {
- if (node->type == SH_NODE_BSDF_PRINCIPLED || node->type == SH_NODE_BSDF_DIFFUSE) {
+ if (ELEM(node->type, SH_NODE_BSDF_PRINCIPLED, SH_NODE_BSDF_DIFFUSE)) {
return node;
}
}
@@ -707,7 +707,7 @@ static void export_texture(bNode *node,
const pxr::UsdStageRefPtr stage,
const bool allow_overwrite)
{
- if (node->type != SH_NODE_TEX_IMAGE && node->type != SH_NODE_TEX_ENVIRONMENT) {
+ if (!ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT)) {
return;
}
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc
index b76f74cfd3d..e949bafe517 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/io/usd/intern/usd_writer_mesh.cc
@@ -11,6 +11,7 @@
#include "BLI_math_vector.h"
#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
@@ -245,8 +246,8 @@ static void get_vertices(const Mesh *mesh, USDMeshData &usd_mesh_data)
{
usd_mesh_data.points.reserve(mesh->totvert);
- const MVert *verts = mesh->mvert;
- for (int i = 0; i < mesh->totvert; ++i) {
+ const Span<MVert> verts = mesh->verts();
+ for (const int i : verts.index_range()) {
usd_mesh_data.points.push_back(pxr::GfVec3f(verts[i].co));
}
}
@@ -255,46 +256,49 @@ static void get_loops_polys(const Mesh *mesh, USDMeshData &usd_mesh_data)
{
/* Only construct face groups (a.k.a. geometry subsets) when we need them for material
* assignments. */
- bool construct_face_groups = mesh->totcol > 1;
+ const bke::AttributeAccessor attributes = mesh->attributes();
+ const VArray<int> material_indices = attributes.lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
+ if (!material_indices.is_single() && mesh->totcol > 1) {
+ const VArraySpan<int> indices_span(material_indices);
+ for (const int i : indices_span.index_range()) {
+ usd_mesh_data.face_groups[indices_span[i]].push_back(i);
+ }
+ }
usd_mesh_data.face_vertex_counts.reserve(mesh->totpoly);
usd_mesh_data.face_indices.reserve(mesh->totloop);
- MLoop *mloop = mesh->mloop;
- MPoly *mpoly = mesh->mpoly;
- for (int i = 0; i < mesh->totpoly; ++i, ++mpoly) {
- MLoop *loop = mloop + mpoly->loopstart;
- usd_mesh_data.face_vertex_counts.push_back(mpoly->totloop);
- for (int j = 0; j < mpoly->totloop; ++j, ++loop) {
- usd_mesh_data.face_indices.push_back(loop->v);
- }
+ const Span<MPoly> polys = mesh->polys();
+ const Span<MLoop> loops = mesh->loops();
- if (construct_face_groups) {
- usd_mesh_data.face_groups[mpoly->mat_nr].push_back(i);
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ usd_mesh_data.face_vertex_counts.push_back(poly.totloop);
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ usd_mesh_data.face_indices.push_back(loop.v);
}
}
}
static void get_edge_creases(const Mesh *mesh, USDMeshData &usd_mesh_data)
{
- const float factor = 1.0f / 255.0f;
+ const float *creases = static_cast<const float *>(CustomData_get_layer(&mesh->edata, CD_CREASE));
+ if (!creases) {
+ return;
+ }
- MEdge *edge = mesh->medge;
- float sharpness;
- for (int edge_idx = 0, totedge = mesh->totedge; edge_idx < totedge; ++edge_idx, ++edge) {
- if (edge->crease == 0) {
+ const Span<MEdge> edges = mesh->edges();
+ for (const int i : edges.index_range()) {
+ const float crease = creases[i];
+ if (crease == 0.0f) {
continue;
}
- if (edge->crease == 255) {
- sharpness = pxr::UsdGeomMesh::SHARPNESS_INFINITE;
- }
- else {
- sharpness = static_cast<float>(edge->crease) * factor;
- }
+ const float sharpness = crease >= 1.0f ? pxr::UsdGeomMesh::SHARPNESS_INFINITE : crease;
- usd_mesh_data.crease_vertex_indices.push_back(edge->v1);
- usd_mesh_data.crease_vertex_indices.push_back(edge->v2);
+ usd_mesh_data.crease_vertex_indices.push_back(edges[i].v1);
+ usd_mesh_data.crease_vertex_indices.push_back(edges[i].v2);
usd_mesh_data.crease_lengths.push_back(2);
usd_mesh_data.crease_sharpnesses.push_back(sharpness);
}
@@ -392,6 +396,8 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_
{
pxr::UsdTimeCode timecode = get_export_time_code();
const float(*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
+ const Span<MPoly> polys = mesh->polys();
+ const Span<MLoop> loops = mesh->loops();
pxr::VtVec3fArray loop_normals;
loop_normals.reserve(mesh->totloop);
@@ -406,21 +412,20 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_
/* Compute the loop normals based on the 'smooth' flag. */
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
const float(*face_normals)[3] = BKE_mesh_poly_normals_ensure(mesh);
- MPoly *mpoly = mesh->mpoly;
- for (int poly_idx = 0, totpoly = mesh->totpoly; poly_idx < totpoly; ++poly_idx, ++mpoly) {
- MLoop *mloop = mesh->mloop + mpoly->loopstart;
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
- if ((mpoly->flag & ME_SMOOTH) == 0) {
+ if ((poly.flag & ME_SMOOTH) == 0) {
/* Flat shaded, use common normal for all verts. */
- pxr::GfVec3f pxr_normal(face_normals[poly_idx]);
- for (int loop_idx = 0; loop_idx < mpoly->totloop; ++loop_idx) {
+ pxr::GfVec3f pxr_normal(face_normals[i]);
+ for (int loop_idx = 0; loop_idx < poly.totloop; ++loop_idx) {
loop_normals.push_back(pxr_normal);
}
}
else {
/* Smooth shaded, use individual vert normals. */
- for (int loop_idx = 0; loop_idx < mpoly->totloop; ++loop_idx, ++mloop) {
- loop_normals.push_back(pxr::GfVec3f(vert_normals[mloop->v]));
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ loop_normals.push_back(pxr::GfVec3f(vert_normals[loop.v]));
}
}
}
diff --git a/source/blender/io/usd/intern/usd_writer_volume.cc b/source/blender/io/usd/intern/usd_writer_volume.cc
index 6300e5c657c..8cc3c65ee70 100644
--- a/source/blender/io/usd/intern/usd_writer_volume.cc
+++ b/source/blender/io/usd/intern/usd_writer_volume.cc
@@ -145,14 +145,14 @@ std::optional<std::string> USDVolumeWriter::construct_vdb_file_path(const Volume
BLI_strncpy(vdb_file_name, volume->id.name + 2, FILE_MAXFILE);
const pxr::UsdTimeCode timecode = get_export_time_code();
if (!timecode.IsDefault()) {
- const int frame = (int)timecode.GetValue();
+ const int frame = int(timecode.GetValue());
const int num_frame_digits = frame == 0 ? 1 : integer_digits_i(abs(frame));
BLI_path_frame(vdb_file_name, frame, num_frame_digits);
}
strcat(vdb_file_name, ".vdb");
char vdb_file_path[FILE_MAX];
- BLI_path_join(vdb_file_path, sizeof(vdb_file_path), vdb_directory_path, vdb_file_name, NULL);
+ BLI_path_join(vdb_file_path, sizeof(vdb_file_path), vdb_directory_path, vdb_file_name, nullptr);
return vdb_file_path;
}
diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h
index ebf37df27eb..98d544df251 100644
--- a/source/blender/io/usd/usd.h
+++ b/source/blender/io/usd/usd.h
@@ -52,7 +52,7 @@ struct USDImportParams {
bool import_materials;
bool import_meshes;
bool import_volumes;
- char *prim_path_mask;
+ char prim_path_mask[1024];
bool import_subdiv;
bool import_instance_proxies;
bool create_collection;
diff --git a/source/blender/io/wavefront_obj/IO_wavefront_obj.h b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
index 847b02d3fd1..0a92bbca477 100644
--- a/source/blender/io/wavefront_obj/IO_wavefront_obj.h
+++ b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
@@ -16,8 +16,6 @@
extern "C" {
#endif
-static const int TOTAL_AXES = 3;
-
struct OBJExportParams {
/** Full path to the destination .OBJ file. */
char filepath[FILE_MAX];
@@ -50,18 +48,15 @@ struct OBJExportParams {
bool export_triangulated_mesh;
bool export_curves_as_nurbs;
ePathReferenceMode path_mode;
+ bool export_pbr_extensions;
/* Grouping options. */
bool export_object_groups;
bool export_material_groups;
bool export_vertex_groups;
- /**
- * Calculate smooth groups from sharp edges.
- */
+ /* Calculate smooth groups from sharp edges. */
bool export_smooth_groups;
- /**
- * Create bitflags instead of the default "0"/"1" group IDs.
- */
+ /* Create bitflags instead of the default "0"/"1" group IDs. */
bool smooth_groups_bitflags;
};
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
index 53aa80700cc..95be927589e 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
@@ -44,7 +44,7 @@ static const char *DEFORM_GROUP_DISABLED = "off";
* So an empty material name is written. */
static const char *MATERIAL_GROUP_DISABLED = "";
-void OBJWriter::write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh,
+void OBJWriter::write_vert_uv_normal_indices(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
@@ -57,12 +57,12 @@ void OBJWriter::write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh,
const int uv_offset = offsets.uv_vertex_offset + 1;
const int normal_offset = offsets.normal_offset + 1;
const int n = vert_indices.size();
- fh.write<eOBJSyntaxElement::poly_element_begin>();
+ fh.write_obj_poly_begin();
if (!flip) {
for (int j = 0; j < n; ++j) {
- fh.write<eOBJSyntaxElement::vertex_uv_normal_indices>(vert_indices[j] + vertex_offset,
- uv_indices[j] + uv_offset,
- normal_indices[j] + normal_offset);
+ fh.write_obj_poly_v_uv_normal(vert_indices[j] + vertex_offset,
+ uv_indices[j] + uv_offset,
+ normal_indices[j] + normal_offset);
}
}
else {
@@ -71,15 +71,15 @@ void OBJWriter::write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh,
* then go backwards. Same logic in other write_*_indices functions below. */
for (int k = 0; k < n; ++k) {
int j = k == 0 ? 0 : n - k;
- fh.write<eOBJSyntaxElement::vertex_uv_normal_indices>(vert_indices[j] + vertex_offset,
- uv_indices[j] + uv_offset,
- normal_indices[j] + normal_offset);
+ fh.write_obj_poly_v_uv_normal(vert_indices[j] + vertex_offset,
+ uv_indices[j] + uv_offset,
+ normal_indices[j] + normal_offset);
}
}
- fh.write<eOBJSyntaxElement::poly_element_end>();
+ fh.write_obj_poly_end();
}
-void OBJWriter::write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh,
+void OBJWriter::write_vert_normal_indices(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> /*uv_indices*/,
@@ -90,24 +90,24 @@ void OBJWriter::write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh,
const int vertex_offset = offsets.vertex_offset + 1;
const int normal_offset = offsets.normal_offset + 1;
const int n = vert_indices.size();
- fh.write<eOBJSyntaxElement::poly_element_begin>();
+ fh.write_obj_poly_begin();
if (!flip) {
for (int j = 0; j < n; ++j) {
- fh.write<eOBJSyntaxElement::vertex_normal_indices>(vert_indices[j] + vertex_offset,
- normal_indices[j] + normal_offset);
+ fh.write_obj_poly_v_normal(vert_indices[j] + vertex_offset,
+ normal_indices[j] + normal_offset);
}
}
else {
for (int k = 0; k < n; ++k) {
int j = k == 0 ? 0 : n - k;
- fh.write<eOBJSyntaxElement::vertex_normal_indices>(vert_indices[j] + vertex_offset,
- normal_indices[j] + normal_offset);
+ fh.write_obj_poly_v_normal(vert_indices[j] + vertex_offset,
+ normal_indices[j] + normal_offset);
}
}
- fh.write<eOBJSyntaxElement::poly_element_end>();
+ fh.write_obj_poly_end();
}
-void OBJWriter::write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh,
+void OBJWriter::write_vert_uv_indices(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
@@ -118,24 +118,22 @@ void OBJWriter::write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh,
const int vertex_offset = offsets.vertex_offset + 1;
const int uv_offset = offsets.uv_vertex_offset + 1;
const int n = vert_indices.size();
- fh.write<eOBJSyntaxElement::poly_element_begin>();
+ fh.write_obj_poly_begin();
if (!flip) {
for (int j = 0; j < n; ++j) {
- fh.write<eOBJSyntaxElement::vertex_uv_indices>(vert_indices[j] + vertex_offset,
- uv_indices[j] + uv_offset);
+ fh.write_obj_poly_v_uv(vert_indices[j] + vertex_offset, uv_indices[j] + uv_offset);
}
}
else {
for (int k = 0; k < n; ++k) {
int j = k == 0 ? 0 : n - k;
- fh.write<eOBJSyntaxElement::vertex_uv_indices>(vert_indices[j] + vertex_offset,
- uv_indices[j] + uv_offset);
+ fh.write_obj_poly_v_uv(vert_indices[j] + vertex_offset, uv_indices[j] + uv_offset);
}
}
- fh.write<eOBJSyntaxElement::poly_element_end>();
+ fh.write_obj_poly_end();
}
-void OBJWriter::write_vert_indices(FormatHandler<eFileType::OBJ> &fh,
+void OBJWriter::write_vert_indices(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> /*uv_indices*/,
@@ -144,27 +142,27 @@ void OBJWriter::write_vert_indices(FormatHandler<eFileType::OBJ> &fh,
{
const int vertex_offset = offsets.vertex_offset + 1;
const int n = vert_indices.size();
- fh.write<eOBJSyntaxElement::poly_element_begin>();
+ fh.write_obj_poly_begin();
if (!flip) {
for (int j = 0; j < n; ++j) {
- fh.write<eOBJSyntaxElement::vertex_indices>(vert_indices[j] + vertex_offset);
+ fh.write_obj_poly_v(vert_indices[j] + vertex_offset);
}
}
else {
for (int k = 0; k < n; ++k) {
int j = k == 0 ? 0 : n - k;
- fh.write<eOBJSyntaxElement::vertex_indices>(vert_indices[j] + vertex_offset);
+ fh.write_obj_poly_v(vert_indices[j] + vertex_offset);
}
}
- fh.write<eOBJSyntaxElement::poly_element_end>();
+ fh.write_obj_poly_end();
}
void OBJWriter::write_header() const
{
using namespace std::string_literals;
- FormatHandler<eFileType::OBJ> fh;
- fh.write<eOBJSyntaxElement::string>("# Blender "s + BKE_blender_version_string() + "\n");
- fh.write<eOBJSyntaxElement::string>("# www.blender.org\n");
+ FormatHandler fh;
+ fh.write_string("# Blender "s + BKE_blender_version_string());
+ fh.write_string("# www.blender.org");
fh.write_to_file(outfile_);
}
@@ -174,8 +172,8 @@ void OBJWriter::write_mtllib_name(const StringRefNull mtl_filepath) const
char mtl_file_name[FILE_MAXFILE];
char mtl_dir_name[FILE_MAXDIR];
BLI_split_dirfile(mtl_filepath.data(), mtl_dir_name, mtl_file_name, FILE_MAXDIR, FILE_MAXFILE);
- FormatHandler<eFileType::OBJ> fh;
- fh.write<eOBJSyntaxElement::mtllib>(mtl_file_name);
+ FormatHandler fh;
+ fh.write_obj_mtllib(mtl_file_name);
fh.write_to_file(outfile_);
}
@@ -184,18 +182,17 @@ static void spaces_to_underscores(std::string &r_name)
std::replace(r_name.begin(), r_name.end(), ' ', '_');
}
-void OBJWriter::write_object_name(FormatHandler<eFileType::OBJ> &fh,
- const OBJMesh &obj_mesh_data) const
+void OBJWriter::write_object_name(FormatHandler &fh, const OBJMesh &obj_mesh_data) const
{
std::string object_name = obj_mesh_data.get_object_name();
spaces_to_underscores(object_name);
if (export_params_.export_object_groups) {
std::string mesh_name = obj_mesh_data.get_object_mesh_name();
spaces_to_underscores(mesh_name);
- fh.write<eOBJSyntaxElement::object_group>(object_name + "_" + mesh_name);
+ fh.write_obj_group(object_name + "_" + mesh_name);
return;
}
- fh.write<eOBJSyntaxElement::object_name>(object_name);
+ fh.write_obj_object(object_name);
}
/* Split up large meshes into multi-threaded jobs; each job processes
@@ -213,9 +210,7 @@ static int calc_chunk_count(int count)
* will be written into the final /fh/ buffer at the end.
*/
template<typename Function>
-void obj_parallel_chunked_output(FormatHandler<eFileType::OBJ> &fh,
- int tot_count,
- const Function &function)
+void obj_parallel_chunked_output(FormatHandler &fh, int tot_count, const Function &function)
{
if (tot_count <= 0) {
return;
@@ -231,7 +226,7 @@ void obj_parallel_chunked_output(FormatHandler<eFileType::OBJ> &fh,
return;
}
/* Give each chunk its own temporary output buffer, and process them in parallel. */
- std::vector<FormatHandler<eFileType::OBJ>> buffers(chunk_count);
+ std::vector<FormatHandler> buffers(chunk_count);
blender::threading::parallel_for(IndexRange(chunk_count), 1, [&](IndexRange range) {
for (const int r : range) {
int i_start = r * chunk_size;
@@ -248,58 +243,57 @@ void obj_parallel_chunked_output(FormatHandler<eFileType::OBJ> &fh,
}
}
-void OBJWriter::write_vertex_coords(FormatHandler<eFileType::OBJ> &fh,
+void OBJWriter::write_vertex_coords(FormatHandler &fh,
const OBJMesh &obj_mesh_data,
bool write_colors) const
{
const int tot_count = obj_mesh_data.tot_vertices();
Mesh *mesh = obj_mesh_data.get_mesh();
- CustomDataLayer *colors_layer = nullptr;
+ const CustomDataLayer *colors_layer = nullptr;
if (write_colors) {
colors_layer = BKE_id_attributes_active_color_get(&mesh->id);
}
if (write_colors && (colors_layer != nullptr)) {
- const bke::AttributeAccessor attributes = bke::mesh_attributes(*mesh);
+ const bke::AttributeAccessor attributes = mesh->attributes();
const VArray<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
colors_layer->name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f});
BLI_assert(tot_count == attribute.size());
- obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) {
+ obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor);
ColorGeometry4f linear = attribute.get(i);
float srgb[3];
linearrgb_to_srgb_v3_v3(srgb, linear);
- buf.write<eOBJSyntaxElement::vertex_coords_color>(
- vertex[0], vertex[1], vertex[2], srgb[0], srgb[1], srgb[2]);
+ buf.write_obj_vertex_color(vertex[0], vertex[1], vertex[2], srgb[0], srgb[1], srgb[2]);
});
}
else {
- obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) {
+ obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor);
- buf.write<eOBJSyntaxElement::vertex_coords>(vertex[0], vertex[1], vertex[2]);
+ buf.write_obj_vertex(vertex[0], vertex[1], vertex[2]);
});
}
}
-void OBJWriter::write_uv_coords(FormatHandler<eFileType::OBJ> &fh, OBJMesh &r_obj_mesh_data) const
+void OBJWriter::write_uv_coords(FormatHandler &fh, OBJMesh &r_obj_mesh_data) const
{
const Vector<float2> &uv_coords = r_obj_mesh_data.get_uv_coords();
const int tot_count = uv_coords.size();
- obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) {
+ obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
const float2 &uv_vertex = uv_coords[i];
- buf.write<eOBJSyntaxElement::uv_vertex_coords>(uv_vertex[0], uv_vertex[1]);
+ buf.write_obj_uv(uv_vertex[0], uv_vertex[1]);
});
}
-void OBJWriter::write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data)
+void OBJWriter::write_poly_normals(FormatHandler &fh, OBJMesh &obj_mesh_data)
{
/* Poly normals should be calculated earlier via store_normal_coords_and_indices. */
const Vector<float3> &normal_coords = obj_mesh_data.get_normal_coords();
const int tot_count = normal_coords.size();
- obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) {
+ obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
const float3 &normal = normal_coords[i];
- buf.write<eOBJSyntaxElement::normal>(normal[0], normal[1], normal[2]);
+ buf.write_obj_normal(normal[0], normal[1], normal[2]);
});
}
@@ -334,7 +328,7 @@ static int get_smooth_group(const OBJMesh &mesh, const OBJExportParams &params,
return group;
}
-void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
+void OBJWriter::write_poly_elements(FormatHandler &fh,
const IndexOffsets &offsets,
const OBJMesh &obj_mesh_data,
std::function<const char *(int)> matname_fn)
@@ -346,7 +340,7 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
const int tot_deform_groups = obj_mesh_data.tot_deform_groups();
threading::EnumerableThreadSpecific<Vector<float>> group_weights;
- obj_parallel_chunked_output(fh, tot_polygons, [&](FormatHandler<eFileType::OBJ> &buf, int idx) {
+ obj_parallel_chunked_output(fh, tot_polygons, [&](FormatHandler &buf, int idx) {
/* Polygon order for writing into the file is not necessarily the same
* as order in the mesh; it will be sorted by material indices. Remap current
* and previous indices here according to the order. */
@@ -362,7 +356,7 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
const int prev_group = get_smooth_group(obj_mesh_data, export_params_, prev_i);
const int group = get_smooth_group(obj_mesh_data, export_params_, i);
if (group != prev_group) {
- buf.write<eOBJSyntaxElement::smooth_group>(group);
+ buf.write_obj_smooth(group);
}
}
@@ -375,19 +369,22 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
prev_i, local_weights);
const int16_t group = obj_mesh_data.get_poly_deform_group_index(i, local_weights);
if (group != prev_group) {
- buf.write<eOBJSyntaxElement::object_group>(
- group == NOT_FOUND ? DEFORM_GROUP_DISABLED :
- obj_mesh_data.get_poly_deform_group_name(group));
+ buf.write_obj_group(group == NOT_FOUND ? DEFORM_GROUP_DISABLED :
+ obj_mesh_data.get_poly_deform_group_name(group));
}
}
+ const bke::AttributeAccessor attributes = obj_mesh_data.get_mesh()->attributes();
+ const VArray<int> material_indices = attributes.lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
+
/* Write material name and material group if different from previous. */
if (export_params_.export_materials && obj_mesh_data.tot_materials() > 0) {
- const int16_t prev_mat = idx == 0 ? NEGATIVE_INIT : obj_mesh_data.ith_poly_matnr(prev_i);
- const int16_t mat = obj_mesh_data.ith_poly_matnr(i);
+ const int16_t prev_mat = idx == 0 ? NEGATIVE_INIT : std::max(0, material_indices[prev_i]);
+ const int16_t mat = std::max(0, material_indices[i]);
if (mat != prev_mat) {
if (mat == NOT_FOUND) {
- buf.write<eOBJSyntaxElement::poly_usemtl>(MATERIAL_GROUP_DISABLED);
+ buf.write_obj_usemtl(MATERIAL_GROUP_DISABLED);
}
else {
const char *mat_name = matname_fn(mat);
@@ -397,9 +394,9 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
if (export_params_.export_material_groups) {
std::string object_name = obj_mesh_data.get_object_name();
spaces_to_underscores(object_name);
- fh.write<eOBJSyntaxElement::object_group>(object_name + "_" + mat_name);
+ fh.write_obj_group(object_name + "_" + mat_name);
}
- buf.write<eOBJSyntaxElement::poly_usemtl>(mat_name);
+ buf.write_obj_usemtl(mat_name);
}
}
}
@@ -414,7 +411,7 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
});
}
-void OBJWriter::write_edges_indices(FormatHandler<eFileType::OBJ> &fh,
+void OBJWriter::write_edges_indices(FormatHandler &fh,
const IndexOffsets &offsets,
const OBJMesh &obj_mesh_data) const
{
@@ -426,13 +423,12 @@ void OBJWriter::write_edges_indices(FormatHandler<eFileType::OBJ> &fh,
if (!vertex_indices) {
continue;
}
- fh.write<eOBJSyntaxElement::edge>((*vertex_indices)[0] + offsets.vertex_offset + 1,
- (*vertex_indices)[1] + offsets.vertex_offset + 1);
+ fh.write_obj_edge((*vertex_indices)[0] + offsets.vertex_offset + 1,
+ (*vertex_indices)[1] + offsets.vertex_offset + 1);
}
}
-void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh,
- const OBJCurve &obj_nurbs_data) const
+void OBJWriter::write_nurbs_curve(FormatHandler &fh, const OBJCurve &obj_nurbs_data) const
{
const int total_splines = obj_nurbs_data.total_splines();
for (int spline_idx = 0; spline_idx < total_splines; spline_idx++) {
@@ -440,15 +436,14 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh,
for (int vertex_idx = 0; vertex_idx < total_vertices; vertex_idx++) {
const float3 vertex_coords = obj_nurbs_data.vertex_coordinates(
spline_idx, vertex_idx, export_params_.scaling_factor);
- fh.write<eOBJSyntaxElement::vertex_coords>(
- vertex_coords[0], vertex_coords[1], vertex_coords[2]);
+ fh.write_obj_vertex(vertex_coords[0], vertex_coords[1], vertex_coords[2]);
}
const char *nurbs_name = obj_nurbs_data.get_curve_name();
const int nurbs_degree = obj_nurbs_data.get_nurbs_degree(spline_idx);
- fh.write<eOBJSyntaxElement::object_group>(nurbs_name);
- fh.write<eOBJSyntaxElement::cstype>();
- fh.write<eOBJSyntaxElement::nurbs_degree>(nurbs_degree);
+ fh.write_obj_group(nurbs_name);
+ fh.write_obj_cstype();
+ fh.write_obj_nurbs_degree(nurbs_degree);
/**
* The numbers written here are indices into the vertex coordinates written
* earlier, relative to the line that is going to be written.
@@ -457,13 +452,13 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh,
* 0.0 1.0 -1 -2 -3 -4 -1 -2 -3 for a cyclic curve with 4 vertices.
*/
const int total_control_points = obj_nurbs_data.total_spline_control_points(spline_idx);
- fh.write<eOBJSyntaxElement::curve_element_begin>();
+ fh.write_obj_curve_begin();
for (int i = 0; i < total_control_points; i++) {
/* "+1" to keep indices one-based, even if they're negative: i.e., -1 refers to the
* last vertex coordinate, -2 second last. */
- fh.write<eOBJSyntaxElement::vertex_indices>(-((i % total_vertices) + 1));
+ fh.write_obj_poly_v(-((i % total_vertices) + 1));
}
- fh.write<eOBJSyntaxElement::curve_element_end>();
+ fh.write_obj_curve_end();
/**
* In `parm u 0 0.1 ..` line:, (total control points + 2) equidistant numbers in the
@@ -474,7 +469,7 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh,
const short flagsu = obj_nurbs_data.get_nurbs_flagu(spline_idx);
const bool cyclic = flagsu & CU_NURB_CYCLIC;
const bool endpoint = !cyclic && (flagsu & CU_NURB_ENDPOINT);
- fh.write<eOBJSyntaxElement::nurbs_parameter_begin>();
+ fh.write_obj_nurbs_parm_begin();
for (int i = 1; i <= total_control_points + 2; i++) {
float parm = 1.0f * i / (total_control_points + 2 + 1);
if (endpoint) {
@@ -485,11 +480,10 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh,
parm = 1;
}
}
- fh.write<eOBJSyntaxElement::nurbs_parameters>(parm);
+ fh.write_obj_nurbs_parm(parm);
}
- fh.write<eOBJSyntaxElement::nurbs_parameter_end>();
-
- fh.write<eOBJSyntaxElement::nurbs_group_end>();
+ fh.write_obj_nurbs_parm_end();
+ fh.write_obj_nurbs_group_end();
}
}
@@ -497,6 +491,21 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh,
/** \name .MTL writers.
* \{ */
+static const char *tex_map_type_to_string[] = {
+ "map_Kd",
+ "map_Pm",
+ "map_Ks",
+ "map_Ns",
+ "map_Pr",
+ "map_Ps",
+ "map_refl",
+ "map_Ke",
+ "map_d",
+ "map_Bump",
+};
+BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_string) == int(MTLTexMapType::Count),
+ "array size mismatch");
+
/**
* Convert #float3 to string of space-separated numbers, with no leading or trailing space.
* Only to be used in NON-performance-critical code.
@@ -537,9 +546,9 @@ void MTLWriter::write_header(const char *blen_filepath)
const char *blen_basename = (blen_filepath && blen_filepath[0] != '\0') ?
BLI_path_basename(blen_filepath) :
"None";
- fmt_handler_.write<eMTLSyntaxElement::string>("# Blender "s + BKE_blender_version_string() +
- " MTL File: '" + blen_basename + "'\n");
- fmt_handler_.write<eMTLSyntaxElement::string>("# www.blender.org\n");
+ fmt_handler_.write_string("# Blender "s + BKE_blender_version_string() + " MTL File: '" +
+ blen_basename + "'");
+ fmt_handler_.write_string("# www.blender.org");
}
StringRefNull MTLWriter::mtl_file_path() const
@@ -547,77 +556,109 @@ StringRefNull MTLWriter::mtl_file_path() const
return mtl_filepath_;
}
-void MTLWriter::write_bsdf_properties(const MTLMaterial &mtl)
+void MTLWriter::write_bsdf_properties(const MTLMaterial &mtl, bool write_pbr)
{
/* For various material properties, we only capture information
* coming from the texture, or the default value of the socket.
* When the texture is present, do not emit the default value. */
- if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_Ns).is_valid()) {
- fmt_handler_.write<eMTLSyntaxElement::Ns>(mtl.Ns);
+
+ /* Do not write Ns & Ka when writing in PBR mode. */
+ if (!write_pbr) {
+ if (!mtl.tex_map_of_type(MTLTexMapType::SpecularExponent).is_valid()) {
+ fmt_handler_.write_mtl_float("Ns", mtl.spec_exponent);
+ }
+ fmt_handler_.write_mtl_float3(
+ "Ka", mtl.ambient_color.x, mtl.ambient_color.y, mtl.ambient_color.z);
}
- fmt_handler_.write<eMTLSyntaxElement::Ka>(mtl.Ka.x, mtl.Ka.y, mtl.Ka.z);
- if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_Kd).is_valid()) {
- fmt_handler_.write<eMTLSyntaxElement::Kd>(mtl.Kd.x, mtl.Kd.y, mtl.Kd.z);
+ if (!mtl.tex_map_of_type(MTLTexMapType::Color).is_valid()) {
+ fmt_handler_.write_mtl_float3("Kd", mtl.color.x, mtl.color.y, mtl.color.z);
}
- if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_Ks).is_valid()) {
- fmt_handler_.write<eMTLSyntaxElement::Ks>(mtl.Ks.x, mtl.Ks.y, mtl.Ks.z);
+ if (!mtl.tex_map_of_type(MTLTexMapType::Specular).is_valid()) {
+ fmt_handler_.write_mtl_float3("Ks", mtl.spec_color.x, mtl.spec_color.y, mtl.spec_color.z);
}
- if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_Ke).is_valid()) {
- fmt_handler_.write<eMTLSyntaxElement::Ke>(mtl.Ke.x, mtl.Ke.y, mtl.Ke.z);
+ if (!mtl.tex_map_of_type(MTLTexMapType::Emission).is_valid()) {
+ fmt_handler_.write_mtl_float3(
+ "Ke", mtl.emission_color.x, mtl.emission_color.y, mtl.emission_color.z);
}
- fmt_handler_.write<eMTLSyntaxElement::Ni>(mtl.Ni);
- if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_d).is_valid()) {
- fmt_handler_.write<eMTLSyntaxElement::d>(mtl.d);
+ fmt_handler_.write_mtl_float("Ni", mtl.ior);
+ if (!mtl.tex_map_of_type(MTLTexMapType::Alpha).is_valid()) {
+ fmt_handler_.write_mtl_float("d", mtl.alpha);
+ }
+ fmt_handler_.write_mtl_illum(mtl.illum_mode);
+
+ if (write_pbr) {
+ if (!mtl.tex_map_of_type(MTLTexMapType::Roughness).is_valid() && mtl.roughness >= 0.0f) {
+ fmt_handler_.write_mtl_float("Pr", mtl.roughness);
+ }
+ if (!mtl.tex_map_of_type(MTLTexMapType::Metallic).is_valid() && mtl.metallic >= 0.0f) {
+ fmt_handler_.write_mtl_float("Pm", mtl.metallic);
+ }
+ if (!mtl.tex_map_of_type(MTLTexMapType::Sheen).is_valid() && mtl.sheen >= 0.0f) {
+ fmt_handler_.write_mtl_float("Ps", mtl.sheen);
+ }
+ if (mtl.cc_thickness >= 0.0f) {
+ fmt_handler_.write_mtl_float("Pc", mtl.cc_thickness);
+ }
+ if (mtl.cc_roughness >= 0.0f) {
+ fmt_handler_.write_mtl_float("Pcr", mtl.cc_roughness);
+ }
+ if (mtl.aniso >= 0.0f) {
+ fmt_handler_.write_mtl_float("aniso", mtl.aniso);
+ }
+ if (mtl.aniso_rot >= 0.0f) {
+ fmt_handler_.write_mtl_float("anisor", mtl.aniso_rot);
+ }
+ if (mtl.transmit_color.x > 0.0f || mtl.transmit_color.y > 0.0f ||
+ mtl.transmit_color.z > 0.0f) {
+ fmt_handler_.write_mtl_float3(
+ "Tf", mtl.transmit_color.x, mtl.transmit_color.y, mtl.transmit_color.z);
+ }
}
- fmt_handler_.write<eMTLSyntaxElement::illum>(mtl.illum);
}
-void MTLWriter::write_texture_map(
- const MTLMaterial &mtl_material,
- const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map,
- const char *blen_filedir,
- const char *dest_dir,
- ePathReferenceMode path_mode,
- Set<std::pair<std::string, std::string>> &copy_set)
+void MTLWriter::write_texture_map(const MTLMaterial &mtl_material,
+ MTLTexMapType texture_key,
+ const MTLTexMap &texture_map,
+ const char *blen_filedir,
+ const char *dest_dir,
+ ePathReferenceMode path_mode,
+ Set<std::pair<std::string, std::string>> &copy_set)
{
std::string options;
/* Option strings should have their own leading spaces. */
- if (texture_map.value.translation != float3{0.0f, 0.0f, 0.0f}) {
- options.append(" -o ").append(float3_to_string(texture_map.value.translation));
+ if (texture_map.translation != float3{0.0f, 0.0f, 0.0f}) {
+ options.append(" -o ").append(float3_to_string(texture_map.translation));
}
- if (texture_map.value.scale != float3{1.0f, 1.0f, 1.0f}) {
- options.append(" -s ").append(float3_to_string(texture_map.value.scale));
+ if (texture_map.scale != float3{1.0f, 1.0f, 1.0f}) {
+ options.append(" -s ").append(float3_to_string(texture_map.scale));
}
- if (texture_map.key == eMTLSyntaxElement::map_Bump && mtl_material.map_Bump_strength > 0.0001f) {
- options.append(" -bm ").append(std::to_string(mtl_material.map_Bump_strength));
+ if (texture_key == MTLTexMapType::Normal && mtl_material.normal_strength > 0.0001f) {
+ options.append(" -bm ").append(std::to_string(mtl_material.normal_strength));
}
std::string path = path_reference(
- texture_map.value.image_path.c_str(), blen_filedir, dest_dir, path_mode, &copy_set);
+ texture_map.image_path.c_str(), blen_filedir, dest_dir, path_mode, &copy_set);
/* Always emit forward slashes for cross-platform compatibility. */
std::replace(path.begin(), path.end(), '\\', '/');
-#define SYNTAX_DISPATCH(eMTLSyntaxElement) \
- if (texture_map.key == eMTLSyntaxElement) { \
- fmt_handler_.write<eMTLSyntaxElement>(options, path.c_str()); \
- return; \
- }
+ fmt_handler_.write_mtl_map(tex_map_type_to_string[int(texture_key)], options, path);
+}
- SYNTAX_DISPATCH(eMTLSyntaxElement::map_Kd);
- SYNTAX_DISPATCH(eMTLSyntaxElement::map_Ks);
- SYNTAX_DISPATCH(eMTLSyntaxElement::map_Ns);
- SYNTAX_DISPATCH(eMTLSyntaxElement::map_d);
- SYNTAX_DISPATCH(eMTLSyntaxElement::map_refl);
- SYNTAX_DISPATCH(eMTLSyntaxElement::map_Ke);
- SYNTAX_DISPATCH(eMTLSyntaxElement::map_Bump);
-#undef SYNTAX_DISPATCH
+static bool is_pbr_map(MTLTexMapType type)
+{
+ return type == MTLTexMapType::Metallic || type == MTLTexMapType::Roughness ||
+ type == MTLTexMapType::Sheen;
+}
- BLI_assert(!"This map type was not written to the file.");
+static bool is_non_pbr_map(MTLTexMapType type)
+{
+ return type == MTLTexMapType::SpecularExponent || type == MTLTexMapType::Reflection;
}
void MTLWriter::write_materials(const char *blen_filepath,
ePathReferenceMode path_mode,
- const char *dest_dir)
+ const char *dest_dir,
+ bool write_pbr)
{
if (mtlmaterials_.size() == 0) {
return;
@@ -633,14 +674,22 @@ void MTLWriter::write_materials(const char *blen_filepath,
[](const MTLMaterial &a, const MTLMaterial &b) { return a.name < b.name; });
Set<std::pair<std::string, std::string>> copy_set;
for (const MTLMaterial &mtlmat : mtlmaterials_) {
- fmt_handler_.write<eMTLSyntaxElement::string>("\n");
- fmt_handler_.write<eMTLSyntaxElement::newmtl>(mtlmat.name);
- write_bsdf_properties(mtlmat);
- for (const auto &tex : mtlmat.texture_maps.items()) {
- if (!tex.value.is_valid()) {
+ fmt_handler_.write_string("");
+ fmt_handler_.write_mtl_newmtl(mtlmat.name);
+ write_bsdf_properties(mtlmat, write_pbr);
+ for (int key = 0; key < int(MTLTexMapType::Count); key++) {
+ const MTLTexMap &tex = mtlmat.texture_maps[key];
+ if (!tex.is_valid()) {
+ continue;
+ }
+ if (!write_pbr && is_pbr_map((MTLTexMapType)key)) {
+ continue;
+ }
+ if (write_pbr && is_non_pbr_map((MTLTexMapType)key)) {
continue;
}
- write_texture_map(mtlmat, tex, blen_filedir, dest_dir, path_mode, copy_set);
+ write_texture_map(
+ mtlmat, (MTLTexMapType)key, tex, blen_filedir, dest_dir, path_mode, copy_set);
}
}
path_reference_copy(copy_set);
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
index 97c23484426..eda4576297b 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
@@ -66,7 +66,7 @@ class OBJWriter : NonMovable, NonCopyable {
/**
* Write object's name or group.
*/
- void write_object_name(FormatHandler<eFileType::OBJ> &fh, const OBJMesh &obj_mesh_data) const;
+ void write_object_name(FormatHandler &fh, const OBJMesh &obj_mesh_data) const;
/**
* Write file name of Material Library in .OBJ file.
*/
@@ -74,19 +74,19 @@ class OBJWriter : NonMovable, NonCopyable {
/**
* Write vertex coordinates for all vertices as "v x y z" or "v x y z r g b".
*/
- void write_vertex_coords(FormatHandler<eFileType::OBJ> &fh,
+ void write_vertex_coords(FormatHandler &fh,
const OBJMesh &obj_mesh_data,
bool write_colors) const;
/**
* Write UV vertex coordinates for all vertices as `vt u v`.
* \note UV indices are stored here, but written with polygons later.
*/
- void write_uv_coords(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data) const;
+ void write_uv_coords(FormatHandler &fh, OBJMesh &obj_mesh_data) const;
/**
* Write loop normals for smooth-shaded polygons, and polygon normals otherwise, as "vn x y z".
* \note Normal indices ares stored here, but written with polygons later.
*/
- void write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data);
+ void write_poly_normals(FormatHandler &fh, OBJMesh &obj_mesh_data);
/**
* Write polygon elements with at least vertex indices, and conditionally with UV vertex
* indices and polygon normal indices. Also write groups: smooth, vertex, material.
@@ -94,23 +94,23 @@ class OBJWriter : NonMovable, NonCopyable {
* name used in the .obj file.
* \note UV indices were stored while writing UV vertices.
*/
- void write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
+ void write_poly_elements(FormatHandler &fh,
const IndexOffsets &offsets,
const OBJMesh &obj_mesh_data,
std::function<const char *(int)> matname_fn);
/**
* Write loose edges of a mesh as "l v1 v2".
*/
- void write_edges_indices(FormatHandler<eFileType::OBJ> &fh,
+ void write_edges_indices(FormatHandler &fh,
const IndexOffsets &offsets,
const OBJMesh &obj_mesh_data) const;
/**
* Write a NURBS curve to the .OBJ file in parameter form.
*/
- void write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, const OBJCurve &obj_nurbs_data) const;
+ void write_nurbs_curve(FormatHandler &fh, const OBJCurve &obj_nurbs_data) const;
private:
- using func_vert_uv_normal_indices = void (OBJWriter::*)(FormatHandler<eFileType::OBJ> &fh,
+ using func_vert_uv_normal_indices = void (OBJWriter::*)(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
@@ -124,7 +124,7 @@ class OBJWriter : NonMovable, NonCopyable {
/**
* Write one line of polygon indices as "f v1/vt1/vn1 v2/vt2/vn2 ...".
*/
- void write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh,
+ void write_vert_uv_normal_indices(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
@@ -133,7 +133,7 @@ class OBJWriter : NonMovable, NonCopyable {
/**
* Write one line of polygon indices as "f v1//vn1 v2//vn2 ...".
*/
- void write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh,
+ void write_vert_normal_indices(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> /*uv_indices*/,
@@ -142,7 +142,7 @@ class OBJWriter : NonMovable, NonCopyable {
/**
* Write one line of polygon indices as "f v1/vt1 v2/vt2 ...".
*/
- void write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh,
+ void write_vert_uv_indices(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
@@ -151,7 +151,7 @@ class OBJWriter : NonMovable, NonCopyable {
/**
* Write one line of polygon indices as "f v1 v2 ...".
*/
- void write_vert_indices(FormatHandler<eFileType::OBJ> &fh,
+ void write_vert_indices(FormatHandler &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> /*uv_indices*/,
@@ -164,7 +164,7 @@ class OBJWriter : NonMovable, NonCopyable {
*/
class MTLWriter : NonMovable, NonCopyable {
private:
- FormatHandler<eFileType::MTL> fmt_handler_;
+ FormatHandler fmt_handler_;
FILE *outfile_;
std::string mtl_filepath_;
Vector<MTLMaterial> mtlmaterials_;
@@ -186,7 +186,8 @@ class MTLWriter : NonMovable, NonCopyable {
*/
void write_materials(const char *blen_filepath,
ePathReferenceMode path_mode,
- const char *dest_dir);
+ const char *dest_dir,
+ bool write_pbr);
StringRefNull mtl_file_path() const;
/**
* Add the materials of the given object to #MTLWriter, de-duplicating
@@ -203,12 +204,13 @@ class MTLWriter : NonMovable, NonCopyable {
/**
* Write properties sourced from p-BSDF node or #Object.Material.
*/
- void write_bsdf_properties(const MTLMaterial &mtl_material);
+ void write_bsdf_properties(const MTLMaterial &mtl_material, bool write_pbr);
/**
* Write a texture map in the form "map_XX -s 1. 1. 1. -o 0. 0. 0. [-bm 1.] path/to/image".
*/
void write_texture_map(const MTLMaterial &mtl_material,
- const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map,
+ MTLTexMapType texture_key,
+ const MTLTexMap &texture_map,
const char *blen_filedir,
const char *dest_dir,
ePathReferenceMode mode,
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
index 5413c9969e3..59ee7bd32c0 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
@@ -23,268 +23,24 @@
namespace blender::io::obj {
-enum class eFileType {
- OBJ,
- MTL,
-};
-
-enum class eOBJSyntaxElement {
- vertex_coords,
- vertex_coords_color,
- uv_vertex_coords,
- normal,
- poly_element_begin,
- vertex_uv_normal_indices,
- vertex_normal_indices,
- vertex_uv_indices,
- vertex_indices,
- poly_element_end,
- poly_usemtl,
- edge,
- cstype,
- nurbs_degree,
- curve_element_begin,
- curve_element_end,
- nurbs_parameter_begin,
- nurbs_parameters,
- nurbs_parameter_end,
- nurbs_group_end,
- new_line,
- mtllib,
- smooth_group,
- object_group,
- object_name,
- /* Use rarely. New line is NOT included for string. */
- string,
-};
-
-enum class eMTLSyntaxElement {
- newmtl,
- Ni,
- d,
- Ns,
- illum,
- Ka,
- Kd,
- Ks,
- Ke,
- map_Kd,
- map_Ks,
- map_Ns,
- map_d,
- map_refl,
- map_Ke,
- map_Bump,
- /* Use rarely. New line is NOT included for string. */
- string,
-};
-
-template<eFileType filetype> struct FileTypeTraits;
-
-/* Used to prevent mixing of say OBJ file format with MTL syntax elements. */
-template<> struct FileTypeTraits<eFileType::OBJ> {
- using SyntaxType = eOBJSyntaxElement;
-};
-
-template<> struct FileTypeTraits<eFileType::MTL> {
- using SyntaxType = eMTLSyntaxElement;
-};
-
-struct FormattingSyntax {
- /* Formatting syntax with the file format key like `newmtl %s\n`. */
- const char *fmt = nullptr;
- /* Number of arguments needed by the syntax. */
- const int total_args = 0;
- /* Whether types of the given arguments are accepted by the syntax above. Fail to compile by
- * default.
- */
- const bool are_types_valid = false;
-};
-
-/**
- * Type dependent but always false. Use to add a `constexpr` conditional compile-time error.
- */
-template<typename T> struct always_false : std::false_type {
-};
-
-template<typename... T>
-constexpr bool is_type_float = (... && std::is_floating_point_v<std::decay_t<T>>);
-
-template<typename... T>
-constexpr bool is_type_integral = (... && std::is_integral_v<std::decay_t<T>>);
-
-template<typename... T>
-constexpr bool is_type_string_related = (... && std::is_constructible_v<std::string, T>);
-
-/* GCC (at least 9.3) while compiling the obj_exporter_tests.cc with optimizations on,
- * results in "obj_export_io.hh:205:18: warning: ‘%s’ directive output truncated writing 34 bytes
- * into a region of size 6" and similar warnings. Yes the output is truncated, and that is covered
- * as an edge case by tests on purpose. */
-#if defined(__GNUC__) && !defined(__clang__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wformat-truncation"
-#endif
-template<typename... T>
-constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key)
-{
- switch (key) {
- case eOBJSyntaxElement::vertex_coords: {
- return {"v {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
- }
- case eOBJSyntaxElement::vertex_coords_color: {
- return {"v {:.6f} {:.6f} {:.6f} {:.4f} {:.4f} {:.4f}\n", 6, is_type_float<T...>};
- }
- case eOBJSyntaxElement::uv_vertex_coords: {
- return {"vt {:.6f} {:.6f}\n", 2, is_type_float<T...>};
- }
- case eOBJSyntaxElement::normal: {
- return {"vn {:.4f} {:.4f} {:.4f}\n", 3, is_type_float<T...>};
- }
- case eOBJSyntaxElement::poly_element_begin: {
- return {"f", 0, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::vertex_uv_normal_indices: {
- return {" {}/{}/{}", 3, is_type_integral<T...>};
- }
- case eOBJSyntaxElement::vertex_normal_indices: {
- return {" {}//{}", 2, is_type_integral<T...>};
- }
- case eOBJSyntaxElement::vertex_uv_indices: {
- return {" {}/{}", 2, is_type_integral<T...>};
- }
- case eOBJSyntaxElement::vertex_indices: {
- return {" {}", 1, is_type_integral<T...>};
- }
- case eOBJSyntaxElement::poly_usemtl: {
- return {"usemtl {}\n", 1, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::edge: {
- return {"l {} {}\n", 2, is_type_integral<T...>};
- }
- case eOBJSyntaxElement::cstype: {
- return {"cstype bspline\n", 0, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::nurbs_degree: {
- return {"deg {}\n", 1, is_type_integral<T...>};
- }
- case eOBJSyntaxElement::curve_element_begin: {
- return {"curv 0.0 1.0", 0, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::nurbs_parameter_begin: {
- return {"parm u 0.0", 0, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::nurbs_parameters: {
- return {" {:.6f}", 1, is_type_float<T...>};
- }
- case eOBJSyntaxElement::nurbs_parameter_end: {
- return {" 1.0\n", 0, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::nurbs_group_end: {
- return {"end\n", 0, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::poly_element_end: {
- ATTR_FALLTHROUGH;
- }
- case eOBJSyntaxElement::curve_element_end: {
- ATTR_FALLTHROUGH;
- }
- case eOBJSyntaxElement::new_line: {
- return {"\n", 0, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::mtllib: {
- return {"mtllib {}\n", 1, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::smooth_group: {
- return {"s {}\n", 1, is_type_integral<T...>};
- }
- case eOBJSyntaxElement::object_group: {
- return {"g {}\n", 1, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::object_name: {
- return {"o {}\n", 1, is_type_string_related<T...>};
- }
- case eOBJSyntaxElement::string: {
- return {"{}", 1, is_type_string_related<T...>};
- }
- }
-}
-
-template<typename... T>
-constexpr FormattingSyntax syntax_elem_to_formatting(const eMTLSyntaxElement key)
-{
- switch (key) {
- case eMTLSyntaxElement::newmtl: {
- return {"newmtl {}\n", 1, is_type_string_related<T...>};
- }
- case eMTLSyntaxElement::Ni: {
- return {"Ni {:.6f}\n", 1, is_type_float<T...>};
- }
- case eMTLSyntaxElement::d: {
- return {"d {:.6f}\n", 1, is_type_float<T...>};
- }
- case eMTLSyntaxElement::Ns: {
- return {"Ns {:.6f}\n", 1, is_type_float<T...>};
- }
- case eMTLSyntaxElement::illum: {
- return {"illum {}\n", 1, is_type_integral<T...>};
- }
- case eMTLSyntaxElement::Ka: {
- return {"Ka {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
- }
- case eMTLSyntaxElement::Kd: {
- return {"Kd {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
- }
- case eMTLSyntaxElement::Ks: {
- return {"Ks {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
- }
- case eMTLSyntaxElement::Ke: {
- return {"Ke {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
- }
- /* NOTE: first texture map related argument, if present, will have its own leading space. */
- case eMTLSyntaxElement::map_Kd: {
- return {"map_Kd{} {}\n", 2, is_type_string_related<T...>};
- }
- case eMTLSyntaxElement::map_Ks: {
- return {"map_Ks{} {}\n", 2, is_type_string_related<T...>};
- }
- case eMTLSyntaxElement::map_Ns: {
- return {"map_Ns{} {}\n", 2, is_type_string_related<T...>};
- }
- case eMTLSyntaxElement::map_d: {
- return {"map_d{} {}\n", 2, is_type_string_related<T...>};
- }
- case eMTLSyntaxElement::map_refl: {
- return {"map_refl{} {}\n", 2, is_type_string_related<T...>};
- }
- case eMTLSyntaxElement::map_Ke: {
- return {"map_Ke{} {}\n", 2, is_type_string_related<T...>};
- }
- case eMTLSyntaxElement::map_Bump: {
- return {"map_Bump{} {}\n", 2, is_type_string_related<T...>};
- }
- case eMTLSyntaxElement::string: {
- return {"{}", 1, is_type_string_related<T...>};
- }
- }
-}
-#if defined(__GNUC__) && !defined(__clang__)
-# pragma GCC diagnostic pop
-#endif
-
/**
- * File format and syntax agnostic file buffer writer.
+ * File buffer writer.
* All writes are done into an internal chunked memory buffer
* (list of default 64 kilobyte blocks).
* Call write_fo_file once in a while to write the memory buffer(s)
* into the given file.
*/
-template<eFileType filetype, size_t buffer_chunk_size = 64 * 1024>
class FormatHandler : NonCopyable, NonMovable {
private:
typedef std::vector<char> VectorChar;
std::vector<VectorChar> blocks_;
+ size_t buffer_chunk_size_;
public:
+ FormatHandler(size_t buffer_chunk_size = 64 * 1024) : buffer_chunk_size_(buffer_chunk_size)
+ {
+ }
+
/* Write contents to the buffer(s) into a file, and clear the buffers. */
void write_to_file(FILE *f)
{
@@ -305,7 +61,7 @@ class FormatHandler : NonCopyable, NonMovable {
return blocks_.size();
}
- void append_from(FormatHandler<filetype, buffer_chunk_size> &v)
+ void append_from(FormatHandler &v)
{
blocks_.insert(blocks_.end(),
std::make_move_iterator(v.blocks_.begin()),
@@ -313,24 +69,132 @@ class FormatHandler : NonCopyable, NonMovable {
v.blocks_.clear();
}
- /**
- * Example invocation: `writer->write<eMTLSyntaxElement::newmtl>("foo")`.
- *
- * \param key: Must match what the instance's filetype expects; i.e., `eMTLSyntaxElement` for
- * `eFileType::MTL`.
- */
- template<typename FileTypeTraits<filetype>::SyntaxType key, typename... T>
- constexpr void write(T &&...args)
- {
- /* Get format syntax, number of arguments expected and whether types of given arguments are
- * valid.
- */
- constexpr FormattingSyntax fmt_nargs_valid = syntax_elem_to_formatting<T...>(key);
- BLI_STATIC_ASSERT(fmt_nargs_valid.are_types_valid &&
- (sizeof...(T) == fmt_nargs_valid.total_args),
- "Types of all arguments and the number of arguments should match what the "
- "formatting specifies.");
- write_impl(fmt_nargs_valid.fmt, std::forward<T>(args)...);
+ void write_obj_vertex(float x, float y, float z)
+ {
+ write_impl("v {:.6f} {:.6f} {:.6f}\n", x, y, z);
+ }
+ void write_obj_vertex_color(float x, float y, float z, float r, float g, float b)
+ {
+ write_impl("v {:.6f} {:.6f} {:.6f} {:.4f} {:.4f} {:.4f}\n", x, y, z, r, g, b);
+ }
+ void write_obj_uv(float x, float y)
+ {
+ write_impl("vt {:.6f} {:.6f}\n", x, y);
+ }
+ void write_obj_normal(float x, float y, float z)
+ {
+ write_impl("vn {:.4f} {:.4f} {:.4f}\n", x, y, z);
+ }
+ void write_obj_poly_begin()
+ {
+ write_impl("f");
+ }
+ void write_obj_poly_end()
+ {
+ write_obj_newline();
+ }
+ void write_obj_poly_v_uv_normal(int v, int uv, int n)
+ {
+ write_impl(" {}/{}/{}", v, uv, n);
+ }
+ void write_obj_poly_v_normal(int v, int n)
+ {
+ write_impl(" {}//{}", v, n);
+ }
+ void write_obj_poly_v_uv(int v, int uv)
+ {
+ write_impl(" {}/{}", v, uv);
+ }
+ void write_obj_poly_v(int v)
+ {
+ write_impl(" {}", v);
+ }
+ void write_obj_usemtl(StringRef s)
+ {
+ write_impl("usemtl {}\n", s);
+ }
+ void write_obj_mtllib(StringRef s)
+ {
+ write_impl("mtllib {}\n", s);
+ }
+ void write_obj_smooth(int s)
+ {
+ write_impl("s {}\n", s);
+ }
+ void write_obj_group(StringRef s)
+ {
+ write_impl("g {}\n", s);
+ }
+ void write_obj_object(StringRef s)
+ {
+ write_impl("o {}\n", s);
+ }
+ void write_obj_edge(int a, int b)
+ {
+ write_impl("l {} {}\n", a, b);
+ }
+ void write_obj_cstype()
+ {
+ write_impl("cstype bspline\n");
+ }
+ void write_obj_nurbs_degree(int deg)
+ {
+ write_impl("deg {}\n", deg);
+ }
+ void write_obj_curve_begin()
+ {
+ write_impl("curv 0.0 1.0");
+ }
+ void write_obj_curve_end()
+ {
+ write_obj_newline();
+ }
+ void write_obj_nurbs_parm_begin()
+ {
+ write_impl("parm u 0.0");
+ }
+ void write_obj_nurbs_parm(float v)
+ {
+ write_impl(" {:.6f}", v);
+ }
+ void write_obj_nurbs_parm_end()
+ {
+ write_impl(" 1.0\n");
+ }
+ void write_obj_nurbs_group_end()
+ {
+ write_impl("end\n");
+ }
+ void write_obj_newline()
+ {
+ write_impl("\n");
+ }
+
+ void write_mtl_newmtl(StringRef s)
+ {
+ write_impl("newmtl {}\n", s);
+ }
+ void write_mtl_float(const char *type, float v)
+ {
+ write_impl("{} {:.6f}\n", type, v);
+ }
+ void write_mtl_float3(const char *type, float r, float g, float b)
+ {
+ write_impl("{} {:.6f} {:.6f} {:.6f}\n", type, r, g, b);
+ }
+ void write_mtl_illum(int mode)
+ {
+ write_impl("illum {}\n", mode);
+ }
+ /* 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, options, value);
+ }
+
+ void write_string(StringRef s)
+ {
+ write_impl("{}\n", s);
}
private:
@@ -340,7 +204,7 @@ class FormatHandler : NonCopyable, NonMovable {
{
if (blocks_.empty() || (blocks_.back().capacity() - blocks_.back().size() < at_least)) {
VectorChar &b = blocks_.emplace_back(VectorChar());
- b.reserve(std::max(at_least, buffer_chunk_size));
+ b.reserve(std::max(at_least, buffer_chunk_size_));
}
}
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
index 815163ad19e..9f19a6390d3 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
@@ -6,6 +6,7 @@
/* Silence warnings from copying deprecated fields. Needed for an Object copy constructor use. */
#define DNA_DEPRECATED_ALLOW
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_lib_id.h"
@@ -187,28 +188,38 @@ void OBJMesh::ensure_mesh_edges() const
void OBJMesh::calc_smooth_groups(const bool use_bitflags)
{
- poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(export_mesh_eval_->medge,
- export_mesh_eval_->totedge,
- export_mesh_eval_->mpoly,
- export_mesh_eval_->totpoly,
- export_mesh_eval_->mloop,
- export_mesh_eval_->totloop,
+ const Span<MEdge> edges = export_mesh_eval_->edges();
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+ const Span<MLoop> loops = export_mesh_eval_->loops();
+ poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(edges.data(),
+ edges.size(),
+ polys.data(),
+ polys.size(),
+ loops.data(),
+ loops.size(),
&tot_smooth_groups_,
use_bitflags);
}
void OBJMesh::calc_poly_order()
{
- const int tot_polys = tot_polygons();
- poly_order_.resize(tot_polys);
- for (int i = 0; i < tot_polys; ++i) {
+ const bke::AttributeAccessor attributes = export_mesh_eval_->attributes();
+ const VArray<int> material_indices = attributes.lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
+ if (material_indices.is_single() && material_indices.get_internal_single() == 0) {
+ return;
+ }
+ const VArraySpan<int> material_indices_span(material_indices);
+
+ poly_order_.resize(material_indices_span.size());
+ for (const int i : material_indices_span.index_range()) {
poly_order_[i] = i;
}
- const MPoly *mpolys = export_mesh_eval_->mpoly;
+
/* Sort polygons by their material index. */
blender::parallel_sort(poly_order_.begin(), poly_order_.end(), [&](int a, int b) {
- int mat_a = mpolys[a].mat_nr;
- int mat_b = mpolys[b].mat_nr;
+ int mat_a = material_indices_span[a];
+ int mat_b = material_indices_span[b];
if (mat_a != mat_b) {
return mat_a < mat_b;
}
@@ -231,14 +242,8 @@ const Material *OBJMesh::get_object_material(const int16_t mat_nr) const
bool OBJMesh::is_ith_poly_smooth(const int poly_index) const
{
- return export_mesh_eval_->mpoly[poly_index].flag & ME_SMOOTH;
-}
-
-int16_t OBJMesh::ith_poly_matnr(const int poly_index) const
-{
- BLI_assert(poly_index < export_mesh_eval_->totpoly);
- const int16_t r_mat_nr = export_mesh_eval_->mpoly[poly_index].mat_nr;
- return r_mat_nr >= 0 ? r_mat_nr : NOT_FOUND;
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+ return polys[poly_index].flag & ME_SMOOTH;
}
const char *OBJMesh::get_object_name() const
@@ -263,7 +268,8 @@ const char *OBJMesh::get_object_material_name(const int16_t mat_nr) const
float3 OBJMesh::calc_vertex_coords(const int vert_index, const float scaling_factor) const
{
float3 r_coords;
- copy_v3_v3(r_coords, export_mesh_eval_->mvert[vert_index].co);
+ const Span<MVert> verts = export_mesh_eval_->verts();
+ copy_v3_v3(r_coords, verts[vert_index].co);
mul_m4_v3(world_and_axes_transform_, r_coords);
mul_v3_fl(r_coords, scaling_factor);
return r_coords;
@@ -271,8 +277,10 @@ float3 OBJMesh::calc_vertex_coords(const int vert_index, const float scaling_fac
Vector<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const
{
- const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index];
- const MLoop *mloop = &export_mesh_eval_->mloop[mpoly.loopstart];
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+ const Span<MLoop> loops = export_mesh_eval_->loops();
+ const MPoly &mpoly = polys[poly_index];
+ const MLoop *mloop = &loops[mpoly.loopstart];
const int totloop = mpoly.totloop;
Vector<int> r_poly_vertex_indices(totloop);
for (int loop_index = 0; loop_index < totloop; loop_index++) {
@@ -283,9 +291,8 @@ Vector<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const
void OBJMesh::store_uv_coords_and_indices()
{
- const MPoly *mpoly = export_mesh_eval_->mpoly;
- const MLoop *mloop = export_mesh_eval_->mloop;
- const int totpoly = export_mesh_eval_->totpoly;
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+ const Span<MLoop> loops = export_mesh_eval_->loops();
const int totvert = export_mesh_eval_->totvert;
const MLoopUV *mloopuv = static_cast<const MLoopUV *>(
CustomData_get_layer(&export_mesh_eval_->ldata, CD_MLOOPUV));
@@ -295,10 +302,18 @@ void OBJMesh::store_uv_coords_and_indices()
}
const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
- UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
- mpoly, nullptr, mloop, mloopuv, totpoly, totvert, limit, false, false);
-
- uv_indices_.resize(totpoly);
+ UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(polys.data(),
+ nullptr,
+ nullptr,
+ loops.data(),
+ mloopuv,
+ polys.size(),
+ totvert,
+ limit,
+ false,
+ false);
+
+ uv_indices_.resize(polys.size());
/* At least total vertices of a mesh will be present in its texture map. So
* reserve minimum space early. */
uv_coords_.reserve(totvert);
@@ -310,16 +325,16 @@ void OBJMesh::store_uv_coords_and_indices()
if (uv_vert->separate) {
tot_uv_vertices_ += 1;
}
- const int vertices_in_poly = mpoly[uv_vert->poly_index].totloop;
+ const int verts_in_poly = polys[uv_vert->poly_index].totloop;
/* Store UV vertex coordinates. */
uv_coords_.resize(tot_uv_vertices_);
- const int loopstart = mpoly[uv_vert->poly_index].loopstart;
+ const int loopstart = polys[uv_vert->poly_index].loopstart;
Span<float> vert_uv_coords(mloopuv[loopstart + uv_vert->loop_of_poly_index].uv, 2);
uv_coords_[tot_uv_vertices_ - 1] = float2(vert_uv_coords[0], vert_uv_coords[1]);
/* Store UV vertex indices. */
- uv_indices_[uv_vert->poly_index].resize(vertices_in_poly);
+ uv_indices_[uv_vert->poly_index].resize(verts_in_poly);
/* Keep indices zero-based and let the writer handle the "+ 1" as per OBJ spec. */
uv_indices_[uv_vert->poly_index][uv_vert->loop_of_poly_index] = tot_uv_vertices_ - 1;
}
@@ -340,10 +355,11 @@ Span<int> OBJMesh::calc_poly_uv_indices(const int poly_index) const
float3 OBJMesh::calc_poly_normal(const int poly_index) const
{
float3 r_poly_normal;
- const MPoly &poly = export_mesh_eval_->mpoly[poly_index];
- const MLoop &mloop = export_mesh_eval_->mloop[poly.loopstart];
- const MVert &mvert = *(export_mesh_eval_->mvert);
- BKE_mesh_calc_poly_normal(&poly, &mloop, &mvert, r_poly_normal);
+ const Span<MVert> verts = export_mesh_eval_->verts();
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+ const Span<MLoop> loops = export_mesh_eval_->loops();
+ const MPoly &poly = polys[poly_index];
+ BKE_mesh_calc_poly_normal(&poly, &loops[poly.loopstart], verts.data(), r_poly_normal);
mul_m3_v3(world_and_axes_normal_transform_, r_poly_normal);
normalize_v3(r_poly_normal);
return r_poly_normal;
@@ -353,7 +369,7 @@ float3 OBJMesh::calc_poly_normal(const int poly_index) const
static float round_float_to_n_digits(const float f, int round_digits)
{
float scale = powf(10.0, round_digits);
- return ceilf((scale * f - 0.49999999f)) / scale;
+ return ceilf(scale * f - 0.49999999f) / scale;
}
static float3 round_float3_to_n_digits(const float3 &v, int round_digits)
@@ -367,6 +383,8 @@ static float3 round_float3_to_n_digits(const float3 &v, int round_digits)
void OBJMesh::store_normal_coords_and_indices()
{
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+
/* We'll round normal components to 4 digits.
* This will cover up some minor differences
* between floating point calculations on different platforms.
@@ -382,7 +400,7 @@ void OBJMesh::store_normal_coords_and_indices()
const float(*lnors)[3] = static_cast<const float(*)[3]>(
CustomData_get_layer(&export_mesh_eval_->ldata, CD_NORMAL));
for (int poly_index = 0; poly_index < export_mesh_eval_->totpoly; ++poly_index) {
- const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index];
+ const MPoly &mpoly = polys[poly_index];
bool need_per_loop_normals = lnors != nullptr || (mpoly.flag & ME_SMOOTH);
if (need_per_loop_normals) {
for (int loop_of_poly = 0; loop_of_poly < mpoly.totloop; ++loop_of_poly) {
@@ -426,7 +444,8 @@ Vector<int> OBJMesh::calc_poly_normal_indices(const int poly_index) const
if (loop_to_normal_index_.is_empty()) {
return {};
}
- const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index];
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+ const MPoly &mpoly = polys[poly_index];
const int totloop = mpoly.totloop;
Vector<int> r_poly_normal_indices(totloop);
for (int poly_loop_index = 0; poly_loop_index < totloop; poly_loop_index++) {
@@ -449,23 +468,23 @@ int16_t OBJMesh::get_poly_deform_group_index(const int poly_index,
{
BLI_assert(poly_index < export_mesh_eval_->totpoly);
BLI_assert(group_weights.size() == BKE_object_defgroup_count(&export_object_eval_));
-
- const MDeformVert *dvert_layer = static_cast<const MDeformVert *>(
- CustomData_get_layer(&export_mesh_eval_->vdata, CD_MDEFORMVERT));
- if (!dvert_layer) {
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+ const Span<MLoop> loops = export_mesh_eval_->loops();
+ const Span<MDeformVert> dverts = export_mesh_eval_->deform_verts();
+ if (dverts.is_empty()) {
return NOT_FOUND;
}
group_weights.fill(0);
bool found_any_group = false;
- const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index];
- const MLoop *mloop = &export_mesh_eval_->mloop[mpoly.loopstart];
+ const MPoly &mpoly = polys[poly_index];
+ const MLoop *mloop = &loops[mpoly.loopstart];
for (int loop_i = 0; loop_i < mpoly.totloop; ++loop_i, ++mloop) {
- const MDeformVert &dvert = dvert_layer[mloop->v];
- for (int weight_i = 0; weight_i < dvert.totweight; ++weight_i) {
- const auto group = dvert.dw[weight_i].def_nr;
+ const MDeformVert &dv = dverts[mloop->v];
+ for (int weight_i = 0; weight_i < dv.totweight; ++weight_i) {
+ const auto group = dv.dw[weight_i].def_nr;
if (group < group_weights.size()) {
- group_weights[group] += dvert.dw[weight_i].weight;
+ group_weights[group] += dv.dw[weight_i].weight;
found_any_group = true;
}
}
@@ -489,9 +508,10 @@ const char *OBJMesh::get_poly_deform_group_name(const int16_t def_group_index) c
std::optional<std::array<int, 2>> OBJMesh::calc_loose_edge_vert_indices(const int edge_index) const
{
- const MEdge &edge = export_mesh_eval_->medge[edge_index];
+ const Span<MEdge> edges = export_mesh_eval_->edges();
+ const MEdge &edge = edges[edge_index];
if (edge.flag & ME_LOOSEEDGE) {
- return std::array<int, 2>{static_cast<int>(edge.v1), static_cast<int>(edge.v2)};
+ return std::array<int, 2>{int(edge.v1), int(edge.v2)};
}
return std::nullopt;
}
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh
index ee2e6227700..db29f5651ed 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh
@@ -130,11 +130,6 @@ class OBJMesh : NonCopyable {
* Return mat_nr-th material of the object. The given index should be zero-based.
*/
const Material *get_object_material(int16_t mat_nr) const;
- /**
- * Returns a zero-based index of a polygon's material indexing into
- * the Object's material slots.
- */
- int16_t ith_poly_matnr(int poly_index) const;
void ensure_mesh_normals() const;
void ensure_mesh_edges() const;
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
index 4ed148ec64e..0231bc79b89 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
@@ -6,6 +6,7 @@
#include "BKE_image.h"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "BLI_map.hh"
#include "BLI_math_vector.h"
@@ -15,13 +16,26 @@
#include "DNA_material_types.h"
#include "DNA_node_types.h"
-#include "NOD_node_tree_ref.hh"
-
#include "obj_export_mesh.hh"
#include "obj_export_mtl.hh"
namespace blender::io::obj {
+const char *tex_map_type_to_socket_id[] = {
+ "Base Color",
+ "Metallic",
+ "Specular",
+ "Roughness", /* Map specular exponent to roughness. */
+ "Roughness",
+ "Sheen",
+ "Metallic", /* Map reflection to metallic. */
+ "Emission",
+ "Alpha",
+ "Normal",
+};
+BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_socket_id) == int(MTLTexMapType::Count),
+ "array size mismatch");
+
/**
* Copy a float property of the given type from the bNode to given buffer.
*/
@@ -72,25 +86,25 @@ static void copy_property_from_node(const eNodeSocketDatatype property_type,
* Collect all the source sockets linked to the destination socket in a destination node.
*/
static void linked_sockets_to_dest_id(const bNode *dest_node,
- const nodes::NodeTreeRef &node_tree,
- StringRefNull dest_socket_id,
- Vector<const nodes::OutputSocketRef *> &r_linked_sockets)
+ const bNodeTree &node_tree,
+ const char *dest_socket_id,
+ Vector<const bNodeSocket *> &r_linked_sockets)
{
r_linked_sockets.clear();
if (!dest_node) {
return;
}
- Span<const nodes::NodeRef *> object_dest_nodes = node_tree.nodes_by_type(dest_node->idname);
- Span<const nodes::InputSocketRef *> dest_inputs = object_dest_nodes.first()->inputs();
- const nodes::InputSocketRef *dest_socket = nullptr;
- for (const nodes::InputSocketRef *curr_socket : dest_inputs) {
- if (STREQ(curr_socket->bsocket()->identifier, dest_socket_id.c_str())) {
+ Span<const bNode *> object_dest_nodes = node_tree.nodes_by_type(dest_node->idname);
+ Span<const bNodeSocket *> dest_inputs = object_dest_nodes.first()->input_sockets();
+ const bNodeSocket *dest_socket = nullptr;
+ for (const bNodeSocket *curr_socket : dest_inputs) {
+ if (STREQ(curr_socket->identifier, dest_socket_id)) {
dest_socket = curr_socket;
break;
}
}
if (dest_socket) {
- Span<const nodes::OutputSocketRef *> linked_sockets = dest_socket->directly_linked_sockets();
+ Span<const bNodeSocket *> linked_sockets = dest_socket->directly_linked_sockets();
r_linked_sockets.resize(linked_sockets.size());
r_linked_sockets = linked_sockets;
}
@@ -99,40 +113,52 @@ static void linked_sockets_to_dest_id(const bNode *dest_node,
/**
* From a list of sockets, get the parent node which is of the given node type.
*/
-static const bNode *get_node_of_type(Span<const nodes::OutputSocketRef *> sockets_list,
- const int node_type)
+static const bNode *get_node_of_type(Span<const bNodeSocket *> sockets_list, const int node_type)
{
- for (const nodes::SocketRef *socket : sockets_list) {
- const bNode *parent_node = socket->bnode();
- if (parent_node->typeinfo->type == node_type) {
- return parent_node;
+ for (const bNodeSocket *socket : sockets_list) {
+ const bNode &parent_node = socket->owner_node();
+ if (parent_node.typeinfo->type == node_type) {
+ return &parent_node;
}
}
return nullptr;
}
-/**
+/*
* From a texture image shader node, get the image's filepath.
* If packed image is found, only the file "name" is returned.
*/
-static const char *get_image_filepath(const bNode *tex_node)
+static std::string get_image_filepath(const bNode *tex_node)
{
if (!tex_node) {
- return nullptr;
+ return "";
}
Image *tex_image = reinterpret_cast<Image *>(tex_node->id);
if (!tex_image || !BKE_image_has_filepath(tex_image)) {
- return nullptr;
+ return "";
}
- const char *path = tex_image->filepath;
+
if (BKE_image_has_packedfile(tex_image)) {
/* Put image in the same directory as the .MTL file. */
- path = BLI_path_slash_rfind(path) + 1;
+ const char *filename = BLI_path_slash_rfind(tex_image->filepath) + 1;
fprintf(stderr,
"Packed image found:'%s'. Unpack and place the image in the same "
"directory as the .MTL file.\n",
- path);
+ filename);
+ return filename;
}
+
+ char path[FILE_MAX];
+ BLI_strncpy(path, tex_image->filepath, FILE_MAX);
+
+ if (tex_image->source == IMA_SRC_SEQUENCE) {
+ char head[FILE_MAX], tail[FILE_MAX];
+ ushort numlen;
+ int framenr = static_cast<NodeTexImage *>(tex_node->storage)->iuser.framenr;
+ BLI_path_sequence_decode(path, head, tail, &numlen);
+ BLI_path_sequence_encode(path, head, tail, numlen, framenr);
+ }
+
return path;
}
@@ -141,16 +167,16 @@ static const char *get_image_filepath(const bNode *tex_node)
* We only want one that feeds directly into a Material Output node
* (that is the behavior of the legacy Python exporter).
*/
-static const nodes::NodeRef *find_bsdf_node(const nodes::NodeTreeRef *nodetree)
+static const bNode *find_bsdf_node(const bNodeTree *nodetree)
{
if (!nodetree) {
return nullptr;
}
- for (const nodes::NodeRef *node : nodetree->nodes_by_type("ShaderNodeOutputMaterial")) {
- const nodes::InputSocketRef *node_input_socket0 = node->inputs()[0];
- for (const nodes::OutputSocketRef *out_sock : node_input_socket0->directly_linked_sockets()) {
- const nodes::NodeRef &in_node = out_sock->node();
- if (in_node.typeinfo()->type == SH_NODE_BSDF_PRINCIPLED) {
+ for (const bNode *node : nodetree->nodes_by_type("ShaderNodeOutputMaterial")) {
+ const bNodeSocket &node_input_socket0 = node->input_socket(0);
+ for (const bNodeSocket *out_sock : node_input_socket0.directly_linked_sockets()) {
+ const bNode &in_node = out_sock->owner_node();
+ if (in_node.typeinfo->type == SH_NODE_BSDF_PRINCIPLED) {
return &in_node;
}
}
@@ -161,58 +187,68 @@ static const nodes::NodeRef *find_bsdf_node(const nodes::NodeTreeRef *nodetree)
/**
* Store properties found either in bNode or material into r_mtl_mat.
*/
-static void store_bsdf_properties(const nodes::NodeRef *bsdf_node,
+static void store_bsdf_properties(const bNode *bsdf_node,
const Material *material,
MTLMaterial &r_mtl_mat)
{
- const bNode *bnode = nullptr;
- if (bsdf_node) {
- bnode = bsdf_node->bnode();
- }
-
- /* If p-BSDF is not present, fallback to #Object.Material. */
float roughness = material->roughness;
- if (bnode) {
- copy_property_from_node(SOCK_FLOAT, bnode, "Roughness", {&roughness, 1});
+ if (bsdf_node) {
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Roughness", {&roughness, 1});
}
/* Empirical approximation. Importer should use the inverse of this method. */
float spec_exponent = (1.0f - roughness);
spec_exponent *= spec_exponent * 1000.0f;
float specular = material->spec;
- if (bnode) {
- copy_property_from_node(SOCK_FLOAT, bnode, "Specular", {&specular, 1});
+ if (bsdf_node) {
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Specular", {&specular, 1});
}
float metallic = material->metallic;
- if (bnode) {
- copy_property_from_node(SOCK_FLOAT, bnode, "Metallic", {&metallic, 1});
+ if (bsdf_node) {
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Metallic", {&metallic, 1});
}
float refraction_index = 1.0f;
- if (bnode) {
- copy_property_from_node(SOCK_FLOAT, bnode, "IOR", {&refraction_index, 1});
+ if (bsdf_node) {
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "IOR", {&refraction_index, 1});
}
- float dissolved = material->a;
- if (bnode) {
- copy_property_from_node(SOCK_FLOAT, bnode, "Alpha", {&dissolved, 1});
+ float alpha = material->a;
+ if (bsdf_node) {
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Alpha", {&alpha, 1});
}
- const bool transparent = dissolved != 1.0f;
+ const bool transparent = alpha != 1.0f;
float3 diffuse_col = {material->r, material->g, material->b};
- if (bnode) {
- copy_property_from_node(SOCK_RGBA, bnode, "Base Color", {diffuse_col, 3});
+ if (bsdf_node) {
+ copy_property_from_node(SOCK_RGBA, bsdf_node, "Base Color", {diffuse_col, 3});
}
float3 emission_col{0.0f};
float emission_strength = 0.0f;
- if (bnode) {
- copy_property_from_node(SOCK_FLOAT, bnode, "Emission Strength", {&emission_strength, 1});
- copy_property_from_node(SOCK_RGBA, bnode, "Emission", {emission_col, 3});
+ if (bsdf_node) {
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Emission Strength", {&emission_strength, 1});
+ copy_property_from_node(SOCK_RGBA, bsdf_node, "Emission", {emission_col, 3});
}
mul_v3_fl(emission_col, emission_strength);
+ float sheen = -1.0f;
+ float clearcoat = -1.0f;
+ float clearcoat_roughness = -1.0f;
+ float aniso = -1.0f;
+ float aniso_rot = -1.0f;
+ float transmission = -1.0f;
+ if (bsdf_node) {
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Sheen", {&sheen, 1});
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Clearcoat", {&clearcoat, 1});
+ copy_property_from_node(
+ SOCK_FLOAT, bsdf_node, "Clearcoat Roughness", {&clearcoat_roughness, 1});
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Anisotropic", {&aniso, 1});
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Anisotropic Rotation", {&aniso_rot, 1});
+ copy_property_from_node(SOCK_FLOAT, bsdf_node, "Transmission", {&transmission, 1});
+ }
+
/* See https://wikipedia.org/wiki/Wavefront_.obj_file for all possible values of `illum`. */
/* Highlight on. */
int illum = 2;
@@ -235,26 +271,34 @@ static void store_bsdf_properties(const nodes::NodeRef *bsdf_node,
/* Transparency: Glass on, Reflection: Ray trace off */
illum = 9;
}
- r_mtl_mat.Ns = spec_exponent;
+ r_mtl_mat.spec_exponent = spec_exponent;
if (metallic != 0.0f) {
- r_mtl_mat.Ka = {metallic, metallic, metallic};
+ r_mtl_mat.ambient_color = {metallic, metallic, metallic};
}
else {
- r_mtl_mat.Ka = {1.0f, 1.0f, 1.0f};
+ r_mtl_mat.ambient_color = {1.0f, 1.0f, 1.0f};
}
- r_mtl_mat.Kd = diffuse_col;
- r_mtl_mat.Ks = {specular, specular, specular};
- r_mtl_mat.Ke = emission_col;
- r_mtl_mat.Ni = refraction_index;
- r_mtl_mat.d = dissolved;
- r_mtl_mat.illum = illum;
+ r_mtl_mat.color = diffuse_col;
+ r_mtl_mat.spec_color = {specular, specular, specular};
+ r_mtl_mat.emission_color = emission_col;
+ r_mtl_mat.ior = refraction_index;
+ r_mtl_mat.alpha = alpha;
+ r_mtl_mat.illum_mode = illum;
+ r_mtl_mat.roughness = roughness;
+ r_mtl_mat.metallic = metallic;
+ r_mtl_mat.sheen = sheen;
+ r_mtl_mat.cc_thickness = clearcoat;
+ r_mtl_mat.cc_roughness = clearcoat_roughness;
+ r_mtl_mat.aniso = aniso;
+ r_mtl_mat.aniso_rot = aniso_rot;
+ r_mtl_mat.transmit_color = {transmission, transmission, transmission};
}
/**
* Store image texture options and file-paths in `r_mtl_mat`.
*/
-static void store_image_textures(const nodes::NodeRef *bsdf_node,
- const nodes::NodeTreeRef *node_tree,
+static void store_image_textures(const bNode *bsdf_node,
+ const bNodeTree *node_tree,
const Material *material,
MTLMaterial &r_mtl_mat)
{
@@ -262,21 +306,20 @@ static void store_image_textures(const nodes::NodeRef *bsdf_node,
/* No nodetree, no images, or no Principled BSDF node. */
return;
}
- const bNode *bnode = bsdf_node->bnode();
/* Normal Map Texture has two extra tasks of:
* - finding a Normal Map node before finding a texture node.
* - finding "Strength" property of the node for `-bm` option.
*/
- for (Map<const eMTLSyntaxElement, tex_map_XX>::MutableItem texture_map :
- r_mtl_mat.texture_maps.items()) {
- Vector<const nodes::OutputSocketRef *> linked_sockets;
+ for (int key = 0; key < int(MTLTexMapType::Count); ++key) {
+ MTLTexMap &value = r_mtl_mat.texture_maps[key];
+ Vector<const bNodeSocket *> linked_sockets;
const bNode *normal_map_node{nullptr};
- if (texture_map.key == eMTLSyntaxElement::map_Bump) {
+ if (key == int(MTLTexMapType::Normal)) {
/* Find sockets linked to destination "Normal" socket in P-BSDF node. */
- linked_sockets_to_dest_id(bnode, *node_tree, "Normal", linked_sockets);
+ linked_sockets_to_dest_id(bsdf_node, *node_tree, "Normal", linked_sockets);
/* Among the linked sockets, find Normal Map shader node. */
normal_map_node = get_node_of_type(linked_sockets, SH_NODE_NORMAL_MAP);
@@ -285,16 +328,17 @@ static void store_image_textures(const nodes::NodeRef *bsdf_node,
}
else {
/* Skip emission map if emission strength is zero. */
- if (texture_map.key == eMTLSyntaxElement::map_Ke) {
+ if (key == int(MTLTexMapType::Emission)) {
float emission_strength = 0.0f;
- copy_property_from_node(SOCK_FLOAT, bnode, "Emission Strength", {&emission_strength, 1});
+ copy_property_from_node(
+ SOCK_FLOAT, bsdf_node, "Emission Strength", {&emission_strength, 1});
if (emission_strength == 0.0f) {
continue;
}
}
/* Find sockets linked to the destination socket of interest, in P-BSDF node. */
linked_sockets_to_dest_id(
- bnode, *node_tree, texture_map.value.dest_socket_id, linked_sockets);
+ bsdf_node, *node_tree, tex_map_type_to_socket_id[key], linked_sockets);
}
/* Among the linked sockets, find Image Texture shader node. */
@@ -302,8 +346,8 @@ static void store_image_textures(const nodes::NodeRef *bsdf_node,
if (!tex_node) {
continue;
}
- const char *tex_image_filepath = get_image_filepath(tex_node);
- if (!tex_image_filepath) {
+ const std::string tex_image_filepath = get_image_filepath(tex_node);
+ if (tex_image_filepath.empty()) {
continue;
}
@@ -313,14 +357,14 @@ static void store_image_textures(const nodes::NodeRef *bsdf_node,
if (normal_map_node) {
copy_property_from_node(
- SOCK_FLOAT, normal_map_node, "Strength", {&r_mtl_mat.map_Bump_strength, 1});
+ SOCK_FLOAT, normal_map_node, "Strength", {&r_mtl_mat.normal_strength, 1});
}
/* Texture transform options. Only translation (origin offset, "-o") and scale
* ("-o") are supported. */
- copy_property_from_node(SOCK_VECTOR, mapping, "Location", {texture_map.value.translation, 3});
- copy_property_from_node(SOCK_VECTOR, mapping, "Scale", {texture_map.value.scale, 3});
+ copy_property_from_node(SOCK_VECTOR, mapping, "Location", {value.translation, 3});
+ copy_property_from_node(SOCK_VECTOR, mapping, "Scale", {value.scale, 3});
- texture_map.value.image_path = tex_image_filepath;
+ value.image_path = tex_image_filepath;
}
}
@@ -330,14 +374,14 @@ MTLMaterial mtlmaterial_for_material(const Material *material)
MTLMaterial mtlmat;
mtlmat.name = std::string(material->id.name + 2);
std::replace(mtlmat.name.begin(), mtlmat.name.end(), ' ', '_');
- const nodes::NodeTreeRef *nodetree = nullptr;
- if (material->nodetree) {
- nodetree = new nodes::NodeTreeRef(material->nodetree);
+ const bNodeTree *nodetree = material->nodetree;
+ if (nodetree != nullptr) {
+ nodetree->ensure_topology_cache();
}
- const nodes::NodeRef *bsdf_node = find_bsdf_node(nodetree);
+
+ const bNode *bsdf_node = find_bsdf_node(nodetree);
store_bsdf_properties(bsdf_node, material, mtlmat);
store_image_textures(bsdf_node, nodetree, material, mtlmat);
- delete nodetree;
return mtlmat;
}
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh
index f83b3b49bf5..2d4edd8979d 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh
@@ -6,36 +6,35 @@
#pragma once
-#include "BLI_map.hh"
#include "BLI_math_vec_types.hh"
#include "DNA_node_types.h"
-#include "obj_export_io.hh"
-
-namespace blender {
-template<> struct DefaultHash<io::obj::eMTLSyntaxElement> {
- uint64_t operator()(const io::obj::eMTLSyntaxElement value) const
- {
- return static_cast<uint64_t>(value);
- }
-};
-
-} // namespace blender
+struct Material;
namespace blender::io::obj {
-/**
- * Generic container for texture node properties.
- */
-struct tex_map_XX {
- tex_map_XX(StringRef to_socket_id) : dest_socket_id(to_socket_id){};
+enum class MTLTexMapType {
+ Color = 0,
+ Metallic,
+ Specular,
+ SpecularExponent,
+ Roughness,
+ Sheen,
+ Reflection,
+ Emission,
+ Alpha,
+ Normal,
+ Count
+};
+extern const char *tex_map_type_to_socket_id[];
+
+struct MTLTexMap {
bool is_valid() const
{
return !image_path.empty();
}
/* Target socket which this texture node connects to. */
- const std::string dest_socket_id;
float3 translation{0.0f};
float3 scale{1.0f};
/* Only Flat and Sphere projections are supported. */
@@ -48,42 +47,38 @@ struct tex_map_XX {
* Container suited for storing Material data for/from a .MTL file.
*/
struct MTLMaterial {
- MTLMaterial()
- {
- texture_maps.add(eMTLSyntaxElement::map_Kd, tex_map_XX("Base Color"));
- texture_maps.add(eMTLSyntaxElement::map_Ks, tex_map_XX("Specular"));
- texture_maps.add(eMTLSyntaxElement::map_Ns, tex_map_XX("Roughness"));
- texture_maps.add(eMTLSyntaxElement::map_d, tex_map_XX("Alpha"));
- texture_maps.add(eMTLSyntaxElement::map_refl, tex_map_XX("Metallic"));
- texture_maps.add(eMTLSyntaxElement::map_Ke, tex_map_XX("Emission"));
- texture_maps.add(eMTLSyntaxElement::map_Bump, tex_map_XX("Normal"));
- }
-
- const tex_map_XX &tex_map_of_type(const eMTLSyntaxElement key) const
+ const MTLTexMap &tex_map_of_type(MTLTexMapType key) const
{
- BLI_assert(texture_maps.contains(key));
- return texture_maps.lookup(key);
+ return texture_maps[int(key)];
}
- tex_map_XX &tex_map_of_type(const eMTLSyntaxElement key)
+ MTLTexMap &tex_map_of_type(MTLTexMapType key)
{
- BLI_assert(texture_maps.contains(key));
- return texture_maps.lookup(key);
+ return texture_maps[int(key)];
}
std::string name;
/* Always check for negative values while importing or exporting. Use defaults if
* any value is negative. */
- float Ns{-1.0f};
- float3 Ka{-1.0f};
- float3 Kd{-1.0f};
- float3 Ks{-1.0f};
- float3 Ke{-1.0f};
- float Ni{-1.0f};
- float d{-1.0f};
- int illum{-1};
- Map<const eMTLSyntaxElement, tex_map_XX> texture_maps;
- /** Only used for Normal Map node: "map_Bump". */
- float map_Bump_strength{-1.0f};
+ float spec_exponent{-1.0f}; /* `Ns` */
+ float3 ambient_color{-1.0f}; /* `Ka` */
+ float3 color{-1.0f}; /* `Kd` */
+ float3 spec_color{-1.0f}; /* `Ks` */
+ float3 emission_color{-1.0f}; /* `Ke` */
+ float ior{-1.0f}; /* `Ni` */
+ float alpha{-1.0f}; /* `d` */
+ float3 transmit_color{-1.0f}; /* `Kt` / `Tf` */
+ float roughness{-1.0f}; /* `Pr` */
+ float metallic{-1.0f}; /* `Pm` */
+ float sheen{-1.0f}; /* `Ps` */
+ float cc_thickness{-1.0f}; /* `Pc` */
+ float cc_roughness{-1.0f}; /* `Pcr` */
+ float aniso{-1.0f}; /* `aniso` */
+ float aniso_rot{-1.0f}; /* `anisor` */
+
+ int illum_mode{-1};
+ MTLTexMap texture_maps[int(MTLTexMapType::Count)];
+ /* Only used for Normal Map node: `map_Bump`. */
+ float normal_strength{-1.0f};
};
MTLMaterial mtlmaterial_for_material(const Material *material);
diff --git a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc
index 77d4f6268bc..daf2a06e112 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc
@@ -89,11 +89,12 @@ filter_supported_objects(Depsgraph *depsgraph, const OBJExportParams &export_par
{
Vector<std::unique_ptr<OBJMesh>> r_exportable_meshes;
Vector<std::unique_ptr<OBJCurve>> r_exportable_nurbs;
- const int deg_objects_visibility_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
- DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI;
- DEG_OBJECT_ITER_BEGIN (depsgraph, object, deg_objects_visibility_flags) {
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, object) {
if (export_params.export_selected_objects && !(object->base_flag & BASE_SELECTED)) {
continue;
}
@@ -143,7 +144,7 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me
* we have to have the output text buffer for each object,
* and write them all into the file at the end. */
size_t count = exportable_as_mesh.size();
- std::vector<FormatHandler<eFileType::OBJ>> buffers(count);
+ std::vector<FormatHandler> buffers(count);
/* Serial: gather material indices, ensure normals & edges. */
Vector<Vector<int>> mtlindices;
@@ -242,7 +243,7 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me
static void write_nurbs_curve_objects(const Vector<std::unique_ptr<OBJCurve>> &exportable_as_nurbs,
const OBJWriter &obj_writer)
{
- FormatHandler<eFileType::OBJ> fh;
+ FormatHandler fh;
/* #OBJCurve doesn't have any dynamically allocated memory, so it's fine
* to wait for #blender::Vector to clean the objects up. */
for (const std::unique_ptr<OBJCurve> &obj_curve : exportable_as_nurbs) {
@@ -268,7 +269,7 @@ void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, co
std::unique_ptr<MTLWriter> mtl_writer = nullptr;
if (export_params.export_materials) {
try {
- mtl_writer = std::make_unique<MTLWriter>(export_params.filepath);
+ mtl_writer = std::make_unique<MTLWriter>(filepath);
}
catch (const std::system_error &ex) {
print_exception_error(ex);
@@ -293,7 +294,10 @@ void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, co
}
BLI_path_slash_native(dest_dir);
BLI_path_normalize(nullptr, dest_dir);
- mtl_writer->write_materials(export_params.blen_filepath, export_params.path_mode, dest_dir);
+ mtl_writer->write_materials(export_params.blen_filepath,
+ export_params.path_mode,
+ dest_dir,
+ export_params.export_pbr_extensions);
}
write_nurbs_curve_objects(std::move(exportable_as_nurbs), *frame_writer);
}
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
index 7069e1185e0..bd1c2d32a12 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
@@ -10,6 +10,7 @@
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
+#include "obj_export_mtl.hh"
#include "obj_import_file_reader.hh"
#include "obj_import_string_utils.hh"
@@ -102,10 +103,10 @@ static void geom_add_mrgb_colors(const char *p, const char *end, GlobalVertices
while (p + mrgb_length <= end) {
uint32_t value = 0;
std::from_chars_result res = std::from_chars(p, p + mrgb_length, value, 16);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
return;
}
- unsigned char srgb[4];
+ uchar srgb[4];
srgb[0] = (value >> 16) & 0xFF;
srgb[1] = (value >> 8) & 0xFF;
srgb[2] = value & 0xFF;
@@ -163,7 +164,7 @@ static void geom_add_edge(Geometry *geom,
edge_v1 += edge_v1 < 0 ? r_global_vertices.vertices.size() : -1;
edge_v2 += edge_v2 < 0 ? r_global_vertices.vertices.size() : -1;
BLI_assert(edge_v1 >= 0 && edge_v2 >= 0);
- geom->edges_.append({static_cast<uint>(edge_v1), static_cast<uint>(edge_v2)});
+ geom->edges_.append({uint(edge_v1), uint(edge_v2)});
geom->track_vertex_index(edge_v1);
geom->track_vertex_index(edge_v2);
}
@@ -215,7 +216,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid vertex index %i (valid range [0, %zu)), ignoring face\n",
corner.vert_index,
- (size_t)global_vertices.vertices.size());
+ size_t(global_vertices.vertices.size()));
face_valid = false;
}
else {
@@ -227,7 +228,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid UV index %i (valid range [0, %zu)), ignoring face\n",
corner.uv_vert_index,
- (size_t)global_vertices.uv_vertices.size());
+ size_t(global_vertices.uv_vertices.size()));
face_valid = false;
}
}
@@ -243,7 +244,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid normal index %i (valid range [0, %zu)), ignoring face\n",
corner.vertex_normal_index,
- (size_t)global_vertices.vertex_normals.size());
+ size_t(global_vertices.vertex_normals.size()));
face_valid = false;
}
}
@@ -484,7 +485,7 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
/* Parse the buffer (until last newline) that we have so far,
* line by line. */
- StringRef buffer_str{buffer.data(), (int64_t)last_nl};
+ StringRef buffer_str{buffer.data(), int64_t(last_nl)};
while (!buffer_str.is_empty()) {
StringRef line = read_next_line(buffer_str);
const char *p = line.begin(), *end = line.end();
@@ -592,36 +593,40 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
add_default_mtl_library();
}
-static eMTLSyntaxElement mtl_line_start_to_enum(const char *&p, const char *end)
+static MTLTexMapType mtl_line_start_to_texture_type(const char *&p, const char *end)
{
if (parse_keyword(p, end, "map_Kd")) {
- return eMTLSyntaxElement::map_Kd;
+ return MTLTexMapType::Color;
}
if (parse_keyword(p, end, "map_Ks")) {
- return eMTLSyntaxElement::map_Ks;
+ return MTLTexMapType::Specular;
}
if (parse_keyword(p, end, "map_Ns")) {
- return eMTLSyntaxElement::map_Ns;
+ return MTLTexMapType::SpecularExponent;
}
if (parse_keyword(p, end, "map_d")) {
- return eMTLSyntaxElement::map_d;
+ return MTLTexMapType::Alpha;
}
- if (parse_keyword(p, end, "refl")) {
- return eMTLSyntaxElement::map_refl;
- }
- if (parse_keyword(p, end, "map_refl")) {
- return eMTLSyntaxElement::map_refl;
+ if (parse_keyword(p, end, "refl") || parse_keyword(p, end, "map_refl")) {
+ return MTLTexMapType::Reflection;
}
if (parse_keyword(p, end, "map_Ke")) {
- return eMTLSyntaxElement::map_Ke;
+ return MTLTexMapType::Emission;
+ }
+ if (parse_keyword(p, end, "bump") || parse_keyword(p, end, "map_Bump") ||
+ parse_keyword(p, end, "map_bump")) {
+ return MTLTexMapType::Normal;
+ }
+ if (parse_keyword(p, end, "map_Pr")) {
+ return MTLTexMapType::Roughness;
}
- if (parse_keyword(p, end, "bump")) {
- return eMTLSyntaxElement::map_Bump;
+ if (parse_keyword(p, end, "map_Pm")) {
+ return MTLTexMapType::Metallic;
}
- if (parse_keyword(p, end, "map_Bump") || parse_keyword(p, end, "map_bump")) {
- return eMTLSyntaxElement::map_Bump;
+ if (parse_keyword(p, end, "map_Ps")) {
+ return MTLTexMapType::Sheen;
}
- return eMTLSyntaxElement::string;
+ return MTLTexMapType::Count;
}
static const std::pair<StringRef, int> unsupported_texture_options[] = {
@@ -639,7 +644,7 @@ static const std::pair<StringRef, int> unsupported_texture_options[] = {
static bool parse_texture_option(const char *&p,
const char *end,
MTLMaterial *material,
- tex_map_XX &tex_map)
+ MTLTexMap &tex_map)
{
p = drop_whitespace(p, end);
if (parse_keyword(p, end, "-o")) {
@@ -651,7 +656,7 @@ static bool parse_texture_option(const char *&p,
return true;
}
if (parse_keyword(p, end, "-bm")) {
- p = parse_float(p, end, 1.0f, material->map_Bump_strength, true, true);
+ p = parse_float(p, end, 1.0f, material->normal_strength, true, true);
return true;
}
if (parse_keyword(p, end, "-type")) {
@@ -693,13 +698,13 @@ static void parse_texture_map(const char *p,
if (!is_map && !is_refl && !is_bump) {
return;
}
- eMTLSyntaxElement key = mtl_line_start_to_enum(p, end);
- if (key == eMTLSyntaxElement::string || !material->texture_maps.contains(key)) {
+ MTLTexMapType key = mtl_line_start_to_texture_type(p, end);
+ if (key == MTLTexMapType::Count) {
/* No supported texture map found. */
std::cerr << "OBJ import: MTL texture map type not supported: '" << line << "'" << std::endl;
return;
}
- tex_map_XX &tex_map = material->texture_maps.lookup(key);
+ MTLTexMap &tex_map = material->tex_map_of_type(key);
tex_map.mtl_dir_path = mtl_dir_path;
/* Parse texture map options. */
@@ -748,7 +753,7 @@ MTLParser::MTLParser(StringRefNull mtl_library, StringRefNull obj_filepath)
{
char obj_file_dir[FILE_MAXDIR];
BLI_split_dir_part(obj_filepath.data(), obj_file_dir, FILE_MAXDIR);
- BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library.data(), NULL);
+ BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library.data(), nullptr);
BLI_split_dir_part(mtl_file_path_, mtl_dir_path_, FILE_MAXDIR);
}
@@ -763,7 +768,7 @@ void MTLParser::parse_and_store(Map<string, std::unique_ptr<MTLMaterial>> &r_mat
MTLMaterial *material = nullptr;
- StringRef buffer_str{(const char *)buffer, (int64_t)buffer_len};
+ StringRef buffer_str{(const char *)buffer, int64_t(buffer_len)};
while (!buffer_str.is_empty()) {
const StringRef line = read_next_line(buffer_str);
const char *p = line.begin(), *end = line.end();
@@ -784,31 +789,55 @@ void MTLParser::parse_and_store(Map<string, std::unique_ptr<MTLMaterial>> &r_mat
}
else if (material != nullptr) {
if (parse_keyword(p, end, "Ns")) {
- parse_float(p, end, 324.0f, material->Ns);
+ parse_float(p, end, 324.0f, material->spec_exponent);
}
else if (parse_keyword(p, end, "Ka")) {
- parse_floats(p, end, 0.0f, material->Ka, 3);
+ parse_floats(p, end, 0.0f, material->ambient_color, 3);
}
else if (parse_keyword(p, end, "Kd")) {
- parse_floats(p, end, 0.8f, material->Kd, 3);
+ parse_floats(p, end, 0.8f, material->color, 3);
}
else if (parse_keyword(p, end, "Ks")) {
- parse_floats(p, end, 0.5f, material->Ks, 3);
+ parse_floats(p, end, 0.5f, material->spec_color, 3);
}
else if (parse_keyword(p, end, "Ke")) {
- parse_floats(p, end, 0.0f, material->Ke, 3);
+ parse_floats(p, end, 0.0f, material->emission_color, 3);
}
else if (parse_keyword(p, end, "Ni")) {
- parse_float(p, end, 1.45f, material->Ni);
+ parse_float(p, end, 1.45f, material->ior);
}
else if (parse_keyword(p, end, "d")) {
- parse_float(p, end, 1.0f, material->d);
+ parse_float(p, end, 1.0f, material->alpha);
}
else if (parse_keyword(p, end, "illum")) {
/* Some files incorrectly use a float (T60135). */
float val;
parse_float(p, end, 1.0f, val);
- material->illum = val;
+ material->illum_mode = val;
+ }
+ else if (parse_keyword(p, end, "Pr")) {
+ parse_float(p, end, 0.5f, material->roughness);
+ }
+ else if (parse_keyword(p, end, "Pm")) {
+ parse_float(p, end, 0.0f, material->metallic);
+ }
+ else if (parse_keyword(p, end, "Ps")) {
+ parse_float(p, end, 0.0f, material->sheen);
+ }
+ else if (parse_keyword(p, end, "Pc")) {
+ parse_float(p, end, 0.0f, material->cc_thickness);
+ }
+ else if (parse_keyword(p, end, "Pcr")) {
+ parse_float(p, end, 0.0f, material->cc_roughness);
+ }
+ else if (parse_keyword(p, end, "aniso")) {
+ parse_float(p, end, 0.0f, material->aniso);
+ }
+ else if (parse_keyword(p, end, "anisor")) {
+ parse_float(p, end, 0.0f, material->aniso_rot);
+ }
+ else if (parse_keyword(p, end, "Kt") || parse_keyword(p, end, "Tf")) {
+ parse_floats(p, end, 0.0f, material->transmit_color, 3);
}
else {
parse_texture_map(p, end, material, mtl_dir_path_);
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
index a570b374231..33ece88d3d4 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
@@ -8,7 +8,7 @@
#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
-#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_material.h"
@@ -22,6 +22,7 @@
#include "IO_wavefront_obj.h"
#include "importer_mesh_utils.hh"
+#include "obj_export_mtl.hh"
#include "obj_import_mesh.hh"
namespace blender::io::obj {
@@ -68,11 +69,7 @@ Object *MeshFromGeometry::create_mesh(Main *bmain,
}
transform_object(obj, import_params);
- /* FIXME: after 2.80; `mesh->flag` isn't copied by #BKE_mesh_nomain_to_mesh() */
- const uint16_t autosmooth = (mesh->flag & ME_AUTOSMOOTH);
- Mesh *dst = static_cast<Mesh *>(obj->data);
- BKE_mesh_nomain_to_mesh(mesh, dst, obj, &CD_MASK_EVERYTHING, true);
- dst->flag |= autosmooth;
+ BKE_mesh_nomain_to_mesh(mesh, static_cast<Mesh *>(obj->data), obj);
/* NOTE: vertex groups have to be created after final mesh is assigned to the object. */
create_vertex_groups(obj);
@@ -157,6 +154,7 @@ void MeshFromGeometry::fixup_invalid_faces()
void MeshFromGeometry::create_vertices(Mesh *mesh)
{
+ MutableSpan<MVert> verts = mesh->verts_for_write();
/* Go through all the global vertex indices from min to max,
* checking which ones are actually and building a global->local
* index mapping. Write out the used vertex positions into the Mesh
@@ -168,22 +166,27 @@ void MeshFromGeometry::create_vertices(Mesh *mesh)
if (!mesh_geometry_.vertices_.contains(vi)) {
continue;
}
- int local_vi = (int)mesh_geometry_.global_to_local_vertices_.size();
+ int local_vi = int(mesh_geometry_.global_to_local_vertices_.size());
BLI_assert(local_vi >= 0 && local_vi < mesh->totvert);
- copy_v3_v3(mesh->mvert[local_vi].co, global_vertices_.vertices[vi]);
+ copy_v3_v3(verts[local_vi].co, global_vertices_.vertices[vi]);
mesh_geometry_.global_to_local_vertices_.add_new(vi, local_vi);
}
}
void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups)
{
- mesh->dvert = nullptr;
+ MutableSpan<MDeformVert> dverts;
const int64_t total_verts = mesh_geometry_.get_vertex_count();
if (use_vertex_groups && total_verts && mesh_geometry_.has_vertex_groups_) {
- mesh->dvert = static_cast<MDeformVert *>(
- CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, nullptr, total_verts));
+ dverts = mesh->deform_verts_for_write();
}
+ MutableSpan<MPoly> polys = mesh->polys_for_write();
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
+ bke::SpanAttributeWriter<int> material_indices =
+ mesh->attributes_for_write().lookup_or_add_for_write_only_span<int>("material_index",
+ ATTR_DOMAIN_FACE);
+
const int64_t tot_face_elems{mesh->totpoly};
int tot_loop_idx = 0;
@@ -195,40 +198,42 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups)
continue;
}
- MPoly &mpoly = mesh->mpoly[poly_idx];
+ MPoly &mpoly = polys[poly_idx];
mpoly.totloop = curr_face.corner_count_;
mpoly.loopstart = tot_loop_idx;
if (curr_face.shaded_smooth) {
mpoly.flag |= ME_SMOOTH;
}
- mpoly.mat_nr = curr_face.material_index;
+ material_indices.span[poly_idx] = curr_face.material_index;
/* Importing obj files without any materials would result in negative indices, which is not
* supported. */
- if (mpoly.mat_nr < 0) {
- mpoly.mat_nr = 0;
+ if (material_indices.span[poly_idx] < 0) {
+ material_indices.span[poly_idx] = 0;
}
for (int idx = 0; idx < curr_face.corner_count_; ++idx) {
const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
- MLoop &mloop = mesh->mloop[tot_loop_idx];
+ MLoop &mloop = loops[tot_loop_idx];
tot_loop_idx++;
mloop.v = mesh_geometry_.global_to_local_vertices_.lookup_default(curr_corner.vert_index, 0);
/* Setup vertex group data, if needed. */
- if (!mesh->dvert) {
+ if (dverts.is_empty()) {
continue;
}
const int group_index = curr_face.vertex_group_index;
- MDeformWeight *dw = BKE_defvert_ensure_index(mesh->dvert + mloop.v, group_index);
+ MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[mloop.v], group_index);
dw->weight = 1.0f;
}
}
+
+ material_indices.finish();
}
void MeshFromGeometry::create_vertex_groups(Object *obj)
{
Mesh *mesh = static_cast<Mesh *>(obj->data);
- if (mesh->dvert == nullptr) {
+ if (mesh->deform_verts().is_empty()) {
return;
}
for (const std::string &name : mesh_geometry_.group_order_) {
@@ -238,12 +243,14 @@ void MeshFromGeometry::create_vertex_groups(Object *obj)
void MeshFromGeometry::create_edges(Mesh *mesh)
{
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+
const int64_t tot_edges{mesh_geometry_.edges_.size()};
const int64_t total_verts{mesh_geometry_.get_vertex_count()};
UNUSED_VARS_NDEBUG(total_verts);
for (int i = 0; i < tot_edges; ++i) {
const MEdge &src_edge = mesh_geometry_.edges_[i];
- MEdge &dst_edge = mesh->medge[i];
+ MEdge &dst_edge = edges[i];
dst_edge.v1 = mesh_geometry_.global_to_local_vertices_.lookup_default(src_edge.v1, 0);
dst_edge.v2 = mesh_geometry_.global_to_local_vertices_.lookup_default(src_edge.v2, 0);
BLI_assert(dst_edge.v1 < total_verts && dst_edge.v2 < total_verts);
@@ -262,18 +269,19 @@ void MeshFromGeometry::create_uv_verts(Mesh *mesh)
return;
}
MLoopUV *mluv_dst = static_cast<MLoopUV *>(CustomData_add_layer(
- &mesh->ldata, CD_MLOOPUV, CD_DEFAULT, nullptr, mesh_geometry_.total_loops_));
+ &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh_geometry_.total_loops_));
int tot_loop_idx = 0;
for (const PolyElem &curr_face : mesh_geometry_.face_elements_) {
for (int idx = 0; idx < curr_face.corner_count_; ++idx) {
const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
- if (curr_corner.uv_vert_index >= 0 &&
- curr_corner.uv_vert_index < global_vertices_.uv_vertices.size()) {
- const float2 &mluv_src = global_vertices_.uv_vertices[curr_corner.uv_vert_index];
- copy_v2_v2(mluv_dst[tot_loop_idx].uv, mluv_src);
- tot_loop_idx++;
+ const int uv_index = curr_corner.uv_vert_index;
+ float2 uv(0, 0);
+ if (uv_index >= 0 && uv_index < global_vertices_.uv_vertices.size()) {
+ uv = global_vertices_.uv_vertices[uv_index];
}
+ copy_v2_v2(mluv_dst[tot_loop_idx].uv, uv);
+ tot_loop_idx++;
}
}
}
@@ -296,9 +304,10 @@ static Material *get_or_create_material(Main *bmain,
const MTLMaterial &mtl = *materials.lookup_or_add(name, std::make_unique<MTLMaterial>());
Material *mat = BKE_material_add(bmain, name.c_str());
- ShaderNodetreeWrap mat_wrap{bmain, mtl, mat, relative_paths};
+ id_us_min(&mat->id);
+
mat->use_nodes = true;
- mat->nodetree = mat_wrap.get_nodetree();
+ mat->nodetree = create_mtl_node_tree(bmain, mtl, mat, relative_paths);
BKE_ntree_update_main_tree(bmain, mat->nodetree, nullptr);
created_materials.add_new(name, mat);
@@ -319,6 +328,9 @@ void MeshFromGeometry::create_materials(Main *bmain,
}
BKE_object_material_assign_single_obdata(bmain, obj, mat, obj->totcol + 1);
}
+ if (obj->totcol > 0) {
+ obj->actcol = 1;
+ }
}
void MeshFromGeometry::create_normals(Mesh *mesh)
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc
index 093cbec32fe..787b1fc9730 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc
@@ -17,8 +17,7 @@
#include "NOD_shader.h"
-/* TODO: move eMTLSyntaxElement out of following file into a more neutral place */
-#include "obj_export_io.hh"
+#include "obj_export_mtl.hh"
#include "obj_import_mtl.hh"
#include "obj_import_string_utils.hh"
@@ -29,12 +28,12 @@ namespace blender::io::obj {
* Only float value(s) can be set using this method.
*/
static void set_property_of_socket(eNodeSocketDatatype property_type,
- StringRef socket_id,
+ const char *socket_id,
Span<float> value,
bNode *r_node)
{
BLI_assert(r_node);
- bNodeSocket *socket{nodeFindSocket(r_node, SOCK_IN, socket_id.data())};
+ bNodeSocket *socket{nodeFindSocket(r_node, SOCK_IN, socket_id)};
BLI_assert(socket && socket->type == property_type);
switch (property_type) {
case SOCK_FLOAT: {
@@ -95,7 +94,7 @@ static Image *create_placeholder_image(Main *bmain, const std::string &path)
return image;
}
-static Image *load_texture_image(Main *bmain, const tex_map_XX &tex_map, bool relative_paths)
+static Image *load_texture_image(Main *bmain, const MTLTexMap &tex_map, bool relative_paths)
{
Image *image = nullptr;
@@ -124,7 +123,7 @@ static Image *load_texture_image(Main *bmain, const tex_map_XX &tex_map, bool re
/* Try replacing underscores with spaces. */
std::string no_underscore_path{no_quote_path};
std::replace(no_underscore_path.begin(), no_underscore_path.end(), '_', ' ');
- if (no_underscore_path != no_quote_path && no_underscore_path != tex_path) {
+ if (!ELEM(no_underscore_path, no_quote_path, tex_path)) {
image = load_image_at_path(bmain, no_underscore_path, relative_paths);
if (image != nullptr) {
return image;
@@ -143,85 +142,43 @@ static Image *load_texture_image(Main *bmain, const tex_map_XX &tex_map, bool re
return image;
}
-ShaderNodetreeWrap::ShaderNodetreeWrap(Main *bmain,
- const MTLMaterial &mtl_mat,
- Material *mat,
- bool relative_paths)
- : mtl_mat_(mtl_mat)
-{
- nodetree_.reset(ntreeAddTree(nullptr, "Shader Nodetree", ntreeType_Shader->idname));
- bsdf_ = add_node_to_tree(SH_NODE_BSDF_PRINCIPLED);
- shader_output_ = add_node_to_tree(SH_NODE_OUTPUT_MATERIAL);
-
- set_bsdf_socket_values(mat);
- add_image_textures(bmain, mat, relative_paths);
- link_sockets(bsdf_, "BSDF", shader_output_, "Surface", 4);
-
- nodeSetActive(nodetree_.get(), shader_output_);
-}
-
-/**
- * Assert if caller hasn't acquired nodetree.
- */
-ShaderNodetreeWrap::~ShaderNodetreeWrap()
-{
- if (nodetree_) {
- /* nodetree's ownership must be acquired by the caller. */
- nodetree_.reset();
- BLI_assert(0);
- }
-}
+/* Nodes are arranged in columns by type, with manually placed x coordinates
+ * based on node widths. */
+const float node_locx_texcoord = -880.0f;
+const float node_locx_mapping = -680.0f;
+const float node_locx_image = -480.0f;
+const float node_locx_normalmap = -200.0f;
+const float node_locx_bsdf = 0.0f;
+const float node_locx_output = 280.0f;
-bNodeTree *ShaderNodetreeWrap::get_nodetree()
-{
- /* If this function has been reached, we know that nodes and the nodetree
- * can be added to the scene safely. */
- return nodetree_.release();
-}
-
-bNode *ShaderNodetreeWrap::add_node_to_tree(const int node_type)
-{
- return nodeAddStaticNode(nullptr, nodetree_.get(), node_type);
-}
+/* Nodes are arranged in rows; one row for each image being used. */
+const float node_locy_top = 300.0f;
+const float node_locy_step = 300.0f;
-std::pair<float, float> ShaderNodetreeWrap::set_node_locations(const int pos_x)
+/* Add a node of the given type at the given location. */
+static bNode *add_node(bNodeTree *ntree, int type, float x, float y)
{
- int pos_y = 0;
- bool found = false;
- while (true) {
- for (Span<int> location : node_locations) {
- if (location[0] == pos_x && location[1] == pos_y) {
- pos_y += 1;
- found = true;
- }
- else {
- found = false;
- }
- }
- if (!found) {
- node_locations.append({pos_x, pos_y});
- return {pos_x * node_size_, pos_y * node_size_ * 2.0 / 3.0};
- }
- }
+ bNode *node = nodeAddStaticNode(nullptr, ntree, type);
+ node->locx = x;
+ node->locy = y;
+ return node;
}
-void ShaderNodetreeWrap::link_sockets(bNode *from_node,
- StringRef from_node_id,
- bNode *to_node,
- StringRef to_node_id,
- const int from_node_pos_x)
+static void link_sockets(bNodeTree *ntree,
+ bNode *from_node,
+ const char *from_node_id,
+ bNode *to_node,
+ const char *to_node_id)
{
- std::tie(from_node->locx, from_node->locy) = set_node_locations(from_node_pos_x);
- std::tie(to_node->locx, to_node->locy) = set_node_locations(from_node_pos_x + 1);
- bNodeSocket *from_sock{nodeFindSocket(from_node, SOCK_OUT, from_node_id.data())};
- bNodeSocket *to_sock{nodeFindSocket(to_node, SOCK_IN, to_node_id.data())};
+ bNodeSocket *from_sock{nodeFindSocket(from_node, SOCK_OUT, from_node_id)};
+ bNodeSocket *to_sock{nodeFindSocket(to_node, SOCK_IN, to_node_id)};
BLI_assert(from_sock && to_sock);
- nodeAddLink(nodetree_.get(), from_node, from_sock, to_node, to_sock);
+ nodeAddLink(ntree, from_node, from_sock, to_node, to_sock);
}
-void ShaderNodetreeWrap::set_bsdf_socket_values(Material *mat)
+static void set_bsdf_socket_values(bNode *bsdf, Material *mat, const MTLMaterial &mtl_mat)
{
- const int illum = mtl_mat_.illum;
+ const int illum = mtl_mat.illum_mode;
bool do_highlight = false;
bool do_tranparency = false;
bool do_reflection = false;
@@ -287,21 +244,23 @@ void ShaderNodetreeWrap::set_bsdf_socket_values(Material *mat)
/* Approximations for trying to map obj/mtl material model into
* Principled BSDF: */
/* Specular: average of Ks components. */
- float specular = (mtl_mat_.Ks[0] + mtl_mat_.Ks[1] + mtl_mat_.Ks[2]) / 3;
+ float specular = (mtl_mat.spec_color[0] + mtl_mat.spec_color[1] + mtl_mat.spec_color[2]) / 3;
if (specular < 0.0f) {
specular = do_highlight ? 1.0f : 0.0f;
}
/* Roughness: map 0..1000 range to 1..0 and apply non-linearity. */
float roughness;
- if (mtl_mat_.Ns < 0.0f) {
+ if (mtl_mat.spec_exponent < 0.0f) {
roughness = do_highlight ? 0.0f : 1.0f;
}
else {
- float clamped_ns = std::max(0.0f, std::min(1000.0f, mtl_mat_.Ns));
+ float clamped_ns = std::max(0.0f, std::min(1000.0f, mtl_mat.spec_exponent));
roughness = 1.0f - sqrt(clamped_ns / 1000.0f);
}
- /* Metallic: average of Ka components. */
- float metallic = (mtl_mat_.Ka[0] + mtl_mat_.Ka[1] + mtl_mat_.Ka[2]) / 3;
+ /* Metallic: average of `Ka` components. */
+ float metallic = (mtl_mat.ambient_color[0] + mtl_mat.ambient_color[1] +
+ mtl_mat.ambient_color[2]) /
+ 3;
if (do_reflection) {
if (metallic < 0.0f) {
metallic = 1.0f;
@@ -311,7 +270,7 @@ void ShaderNodetreeWrap::set_bsdf_socket_values(Material *mat)
metallic = 0.0f;
}
- float ior = mtl_mat_.Ni;
+ float ior = mtl_mat.ior;
if (ior < 0) {
if (do_tranparency) {
ior = 1.0f;
@@ -320,93 +279,153 @@ void ShaderNodetreeWrap::set_bsdf_socket_values(Material *mat)
ior = 1.5f;
}
}
- float alpha = mtl_mat_.d;
+ float alpha = mtl_mat.alpha;
if (do_tranparency && alpha < 0) {
alpha = 1.0f;
}
- float3 base_color = {mtl_mat_.Kd[0], mtl_mat_.Kd[1], mtl_mat_.Kd[2]};
+ /* PBR values, when present, override the ones calculated above. */
+ if (mtl_mat.roughness >= 0) {
+ roughness = mtl_mat.roughness;
+ }
+ if (mtl_mat.metallic >= 0) {
+ metallic = mtl_mat.metallic;
+ }
+
+ float3 base_color = mtl_mat.color;
if (base_color.x >= 0 && base_color.y >= 0 && base_color.z >= 0) {
- set_property_of_socket(SOCK_RGBA, "Base Color", {base_color, 3}, bsdf_);
+ set_property_of_socket(SOCK_RGBA, "Base Color", {base_color, 3}, bsdf);
/* Viewport shading uses legacy r,g,b base color. */
mat->r = base_color.x;
mat->g = base_color.y;
mat->b = base_color.z;
}
- float3 emission_color = {mtl_mat_.Ke[0], mtl_mat_.Ke[1], mtl_mat_.Ke[2]};
+ float3 emission_color = mtl_mat.emission_color;
if (emission_color.x >= 0 && emission_color.y >= 0 && emission_color.z >= 0) {
- set_property_of_socket(SOCK_RGBA, "Emission", {emission_color, 3}, bsdf_);
+ set_property_of_socket(SOCK_RGBA, "Emission", {emission_color, 3}, bsdf);
}
- if (mtl_mat_.tex_map_of_type(eMTLSyntaxElement::map_Ke).is_valid()) {
- set_property_of_socket(SOCK_FLOAT, "Emission Strength", {1.0f}, bsdf_);
+ if (mtl_mat.tex_map_of_type(MTLTexMapType::Emission).is_valid()) {
+ set_property_of_socket(SOCK_FLOAT, "Emission Strength", {1.0f}, bsdf);
}
- set_property_of_socket(SOCK_FLOAT, "Specular", {specular}, bsdf_);
- set_property_of_socket(SOCK_FLOAT, "Roughness", {roughness}, bsdf_);
+ set_property_of_socket(SOCK_FLOAT, "Specular", {specular}, bsdf);
+ set_property_of_socket(SOCK_FLOAT, "Roughness", {roughness}, bsdf);
mat->roughness = roughness;
- set_property_of_socket(SOCK_FLOAT, "Metallic", {metallic}, bsdf_);
+ set_property_of_socket(SOCK_FLOAT, "Metallic", {metallic}, bsdf);
mat->metallic = metallic;
if (ior != -1) {
- set_property_of_socket(SOCK_FLOAT, "IOR", {ior}, bsdf_);
+ set_property_of_socket(SOCK_FLOAT, "IOR", {ior}, bsdf);
}
if (alpha != -1) {
- set_property_of_socket(SOCK_FLOAT, "Alpha", {alpha}, bsdf_);
+ set_property_of_socket(SOCK_FLOAT, "Alpha", {alpha}, bsdf);
}
if (do_tranparency || (alpha >= 0.0f && alpha < 1.0f)) {
mat->blend_method = MA_BM_BLEND;
}
+
+ if (mtl_mat.sheen >= 0) {
+ set_property_of_socket(SOCK_FLOAT, "Sheen", {mtl_mat.sheen}, bsdf);
+ }
+ if (mtl_mat.cc_thickness >= 0) {
+ set_property_of_socket(SOCK_FLOAT, "Clearcoat", {mtl_mat.cc_thickness}, bsdf);
+ }
+ if (mtl_mat.cc_roughness >= 0) {
+ set_property_of_socket(SOCK_FLOAT, "Clearcoat Roughness", {mtl_mat.cc_roughness}, bsdf);
+ }
+ if (mtl_mat.aniso >= 0) {
+ set_property_of_socket(SOCK_FLOAT, "Anisotropic", {mtl_mat.aniso}, bsdf);
+ }
+ if (mtl_mat.aniso_rot >= 0) {
+ set_property_of_socket(SOCK_FLOAT, "Anisotropic Rotation", {mtl_mat.aniso_rot}, bsdf);
+ }
+
+ /* Transmission: average of transmission color. */
+ float transmission = (mtl_mat.transmit_color[0] + mtl_mat.transmit_color[1] +
+ mtl_mat.transmit_color[2]) /
+ 3;
+ if (transmission >= 0) {
+ set_property_of_socket(SOCK_FLOAT, "Transmission", {transmission}, bsdf);
+ }
}
-void ShaderNodetreeWrap::add_image_textures(Main *bmain, Material *mat, bool relative_paths)
+static void add_image_textures(Main *bmain,
+ bNodeTree *ntree,
+ bNode *bsdf,
+ Material *mat,
+ const MTLMaterial &mtl_mat,
+ bool relative_paths)
{
- for (const Map<const eMTLSyntaxElement, tex_map_XX>::Item texture_map :
- mtl_mat_.texture_maps.items()) {
- if (!texture_map.value.is_valid()) {
+ float node_locy = node_locy_top;
+ for (int key = 0; key < int(MTLTexMapType::Count); ++key) {
+ const MTLTexMap &value = mtl_mat.texture_maps[key];
+ if (!value.is_valid()) {
/* No Image texture node of this map type can be added to this material. */
continue;
}
- bNode *image_texture = add_node_to_tree(SH_NODE_TEX_IMAGE);
- BLI_assert(image_texture);
- Image *image = load_texture_image(bmain, texture_map.value, relative_paths);
+ Image *image = load_texture_image(bmain, value, relative_paths);
if (image == nullptr) {
continue;
}
- image_texture->id = &image->id;
- static_cast<NodeTexImage *>(image_texture->storage)->projection =
- texture_map.value.projection_type;
+
+ bNode *image_node = add_node(ntree, SH_NODE_TEX_IMAGE, node_locx_image, node_locy);
+ BLI_assert(image_node);
+ image_node->id = &image->id;
+ static_cast<NodeTexImage *>(image_node->storage)->projection = value.projection_type;
/* Add normal map node if needed. */
bNode *normal_map = nullptr;
- if (texture_map.key == eMTLSyntaxElement::map_Bump) {
- normal_map = add_node_to_tree(SH_NODE_NORMAL_MAP);
- const float bump = std::max(0.0f, mtl_mat_.map_Bump_strength);
+ if (key == int(MTLTexMapType::Normal)) {
+ normal_map = add_node(ntree, SH_NODE_NORMAL_MAP, node_locx_normalmap, node_locy);
+ const float bump = std::max(0.0f, mtl_mat.normal_strength);
set_property_of_socket(SOCK_FLOAT, "Strength", {bump}, normal_map);
}
/* Add UV mapping & coordinate nodes only if needed. */
- if (texture_map.value.translation != float3(0, 0, 0) ||
- texture_map.value.scale != float3(1, 1, 1)) {
- bNode *mapping = add_node_to_tree(SH_NODE_MAPPING);
- bNode *texture_coordinate = add_node_to_tree(SH_NODE_TEX_COORD);
- set_property_of_socket(SOCK_VECTOR, "Location", {texture_map.value.translation, 3}, mapping);
- set_property_of_socket(SOCK_VECTOR, "Scale", {texture_map.value.scale, 3}, mapping);
-
- link_sockets(texture_coordinate, "UV", mapping, "Vector", 0);
- link_sockets(mapping, "Vector", image_texture, "Vector", 1);
+ if (value.translation != float3(0, 0, 0) || value.scale != float3(1, 1, 1)) {
+ bNode *texcoord = add_node(ntree, SH_NODE_TEX_COORD, node_locx_texcoord, node_locy);
+ bNode *mapping = add_node(ntree, SH_NODE_MAPPING, node_locx_mapping, node_locy);
+ set_property_of_socket(SOCK_VECTOR, "Location", {value.translation, 3}, mapping);
+ set_property_of_socket(SOCK_VECTOR, "Scale", {value.scale, 3}, mapping);
+
+ link_sockets(ntree, texcoord, "UV", mapping, "Vector");
+ link_sockets(ntree, mapping, "Vector", image_node, "Vector");
}
if (normal_map) {
- link_sockets(image_texture, "Color", normal_map, "Color", 2);
- link_sockets(normal_map, "Normal", bsdf_, "Normal", 3);
+ link_sockets(ntree, image_node, "Color", normal_map, "Color");
+ link_sockets(ntree, normal_map, "Normal", bsdf, "Normal");
}
- else if (texture_map.key == eMTLSyntaxElement::map_d) {
- link_sockets(image_texture, "Alpha", bsdf_, texture_map.value.dest_socket_id, 2);
+ else if (key == int(MTLTexMapType::Alpha)) {
+ link_sockets(ntree, image_node, "Alpha", bsdf, tex_map_type_to_socket_id[key]);
mat->blend_method = MA_BM_BLEND;
}
else {
- link_sockets(image_texture, "Color", bsdf_, texture_map.value.dest_socket_id, 2);
+ link_sockets(ntree, image_node, "Color", bsdf, tex_map_type_to_socket_id[key]);
}
+
+ /* Next layout row: goes downwards on the screen. */
+ node_locy -= node_locy_step;
}
}
+
+bNodeTree *create_mtl_node_tree(Main *bmain,
+ const MTLMaterial &mtl,
+ Material *mat,
+ bool relative_paths)
+{
+ bNodeTree *ntree = ntreeAddTreeEmbedded(
+ nullptr, &mat->id, "Shader Nodetree", ntreeType_Shader->idname);
+
+ bNode *bsdf = add_node(ntree, SH_NODE_BSDF_PRINCIPLED, node_locx_bsdf, node_locy_top);
+ bNode *output = add_node(ntree, SH_NODE_OUTPUT_MATERIAL, node_locx_output, node_locy_top);
+
+ set_bsdf_socket_values(bsdf, mat, mtl);
+ add_image_textures(bmain, ntree, bsdf, mat, mtl, relative_paths);
+ link_sockets(ntree, bsdf, "BSDF", output, "Surface");
+ nodeSetActive(ntree, output);
+
+ return ntree;
+}
+
} // namespace blender::io::obj
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh b/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh
index 17dd0106fea..a3ba803e921 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh
@@ -1,93 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-/** \file
- * \ingroup obj
- */
-
#pragma once
-#include <array>
-
-#include "BLI_map.hh"
-#include "BLI_math_vec_types.hh"
-#include "BLI_string_ref.hh"
-#include "BLI_vector.hh"
-
#include "DNA_node_types.h"
-#include "MEM_guardedalloc.h"
-
-#include "obj_export_mtl.hh"
+struct Main;
+struct Material;
namespace blender::io::obj {
-struct UniqueNodetreeDeleter {
- void operator()(bNodeTree *node)
- {
- MEM_freeN(node);
- }
-};
-
-using unique_nodetree_ptr = std::unique_ptr<bNodeTree, UniqueNodetreeDeleter>;
-
-class ShaderNodetreeWrap {
- private:
- /* Node arrangement:
- * Texture Coordinates -> Mapping -> Image Texture -> (optional) Normal Map -> p-BSDF -> Material
- * Output. */
- unique_nodetree_ptr nodetree_;
- bNode *bsdf_;
- bNode *shader_output_;
- const MTLMaterial &mtl_mat_;
-
- /* List of all locations occupied by nodes. */
- Vector<std::array<int, 2>> node_locations;
- const float node_size_{300.f};
-
- public:
- /**
- * Initializes a nodetree with a p-BSDF node's BSDF socket connected to shader output node's
- * surface socket.
- */
- ShaderNodetreeWrap(Main *bmain, const MTLMaterial &mtl_mat, Material *mat, bool relative_paths);
- ~ShaderNodetreeWrap();
-
- /**
- * Release nodetree for materials to own it. nodetree has its unique deleter
- * if destructor is not reached for some reason.
- */
- bNodeTree *get_nodetree();
+struct MTLMaterial;
- private:
- /**
- * Add a new static node to the tree.
- * No two nodes are linked here.
- */
- bNode *add_node_to_tree(const int node_type);
- /**
- * Return x-y coordinates for a node where y is determined by other nodes present in
- * the same vertical column.
- */
- std::pair<float, float> set_node_locations(const int pos_x);
- /**
- * Link two nodes by the sockets of given IDs.
- * Also releases the ownership of the "from" node for nodetree to free it.
- * \param from_node_pos_x: 0 to 4 value as per nodetree arrangement.
- */
- void link_sockets(bNode *from_node,
- StringRef from_node_id,
- bNode *to_node,
- StringRef to_node_id,
- const int from_node_pos_x);
- /**
- * Set values of sockets in p-BSDF node of the nodetree.
- */
- void set_bsdf_socket_values(Material *mat);
- /**
- * Create image texture, vector and normal mapping nodes from MTL materials and link the
- * nodes to p-BSDF node.
- */
- void add_image_textures(Main *bmain, Material *mat, bool relative_paths);
-};
+bNodeTree *create_mtl_node_tree(Main *bmain,
+ const MTLMaterial &mtl_mat,
+ Material *mat,
+ bool relative_paths);
} // namespace blender::io::obj
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
index 04d9a665588..91f09d9e188 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
+++ b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
@@ -110,7 +110,7 @@ struct Geometry {
int get_vertex_count() const
{
- return (int)vertices_.size();
+ return int(vertices_.size());
}
void track_vertex_index(int index)
{
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
index 7e282b164b0..a69b4206db6 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc
@@ -94,7 +94,7 @@ const char *parse_float(const char *p,
}
p = drop_plus(p, end);
fast_float::from_chars_result res = fast_float::from_chars(p, end, dst);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
dst = fallback;
}
else if (require_trailing_space && res.ptr < end && !is_whitespace(*res.ptr)) {
@@ -125,7 +125,7 @@ const char *parse_int(const char *p, const char *end, int fallback, int &dst, bo
}
p = drop_plus(p, end);
std::from_chars_result res = std::from_chars(p, end, dst);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
dst = fallback;
}
return res.ptr;
diff --git a/source/blender/io/wavefront_obj/importer/obj_importer.cc b/source/blender/io/wavefront_obj/importer/obj_importer.cc
index 5d3f75e7f38..ccbcce64d65 100644
--- a/source/blender/io/wavefront_obj/importer/obj_importer.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_importer.cc
@@ -19,6 +19,7 @@
#include "DNA_collection_types.h"
+#include "obj_export_mtl.hh"
#include "obj_import_file_reader.hh"
#include "obj_import_mesh.hh"
#include "obj_import_nurbs.hh"
@@ -75,6 +76,7 @@ static void geometry_to_blender_objects(Main *bmain,
/* Sync the collection after all objects are created. */
BKE_layer_collection_resync_allow();
BKE_main_collection_sync(bmain);
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* After collection sync, select objects in the view layer and do DEG updates. */
for (Object *obj : objects) {
@@ -122,7 +124,7 @@ void importer_main(Main *bmain,
}
if (import_params.clear_selection) {
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
}
geometry_to_blender_objects(bmain,
scene,
diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
index f582064e0c1..dcba78ac99e 100644
--- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
@@ -185,17 +185,17 @@ TEST(obj_exporter_writer, mtllib)
TEST(obj_exporter_writer, format_handler_buffer_chunking)
{
/* Use a tiny buffer chunk size, so that the test below ends up creating several blocks. */
- FormatHandler<eFileType::OBJ, 16> h;
- h.write<eOBJSyntaxElement::object_name>("abc");
- h.write<eOBJSyntaxElement::object_name>("abcd");
- h.write<eOBJSyntaxElement::object_name>("abcde");
- h.write<eOBJSyntaxElement::object_name>("abcdef");
- h.write<eOBJSyntaxElement::object_name>("012345678901234567890123456789abcd");
- h.write<eOBJSyntaxElement::object_name>("123");
- h.write<eOBJSyntaxElement::curve_element_begin>();
- h.write<eOBJSyntaxElement::new_line>();
- h.write<eOBJSyntaxElement::nurbs_parameter_begin>();
- h.write<eOBJSyntaxElement::new_line>();
+ FormatHandler h(16);
+ h.write_obj_object("abc");
+ h.write_obj_object("abcd");
+ h.write_obj_object("abcde");
+ h.write_obj_object("abcdef");
+ h.write_obj_object("012345678901234567890123456789abcd");
+ h.write_obj_object("123");
+ h.write_obj_curve_begin();
+ h.write_obj_newline();
+ h.write_obj_nurbs_parm_begin();
+ h.write_obj_newline();
size_t got_blocks = h.get_block_count();
ASSERT_EQ(got_blocks, 7);
@@ -527,4 +527,27 @@ TEST_F(obj_exporter_regression_test, all_objects_mat_groups)
_export.params);
}
+TEST_F(obj_exporter_regression_test, materials_without_pbr)
+{
+ OBJExportParamsDefault _export;
+ _export.params.export_normals = false;
+ _export.params.path_mode = PATH_REFERENCE_RELATIVE;
+ compare_obj_export_to_golden("io_tests/blend_geometry/materials_pbr.blend",
+ "io_tests/obj/materials_without_pbr.obj",
+ "io_tests/obj/materials_without_pbr.mtl",
+ _export.params);
+}
+
+TEST_F(obj_exporter_regression_test, materials_pbr)
+{
+ OBJExportParamsDefault _export;
+ _export.params.export_normals = false;
+ _export.params.path_mode = PATH_REFERENCE_RELATIVE;
+ _export.params.export_pbr_extensions = true;
+ compare_obj_export_to_golden("io_tests/blend_geometry/materials_pbr.blend",
+ "io_tests/obj/materials_pbr.obj",
+ "io_tests/obj/materials_pbr.mtl",
+ _export.params);
+}
+
} // namespace blender::io::obj
diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh
index 7d3b41ed527..006d86312b6 100644
--- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh
+++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.hh
@@ -31,6 +31,7 @@ struct OBJExportParamsDefault {
params.path_mode = PATH_REFERENCE_AUTO;
params.export_triangulated_mesh = false;
params.export_curves_as_nurbs = false;
+ params.export_pbr_extensions = false;
params.export_object_groups = false;
params.export_material_groups = false;
diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
index bd9360548af..cd97d5fb485 100644
--- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
@@ -8,11 +8,12 @@
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BLI_listbase.h"
-#include "BLI_math_base.h"
+#include "BLI_math_base.hh"
#include "BLI_math_vec_types.hh"
#include "BLO_readfile.h"
@@ -71,12 +72,13 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
depsgraph_create(DAG_EVAL_VIEWPORT);
- const int deg_objects_visibility_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
- DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEGObjectIterSettings deg_iter_settings{};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
size_t object_index = 0;
- DEG_OBJECT_ITER_BEGIN (depsgraph, object, deg_objects_visibility_flags) {
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, object) {
if (object_index >= expect_count) {
ADD_FAILURE();
break;
@@ -85,7 +87,7 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
ASSERT_STREQ(object->id.name, exp.name.c_str());
EXPECT_EQ(object->type, exp.type);
EXPECT_V3_NEAR(object->loc, float3(0, 0, 0), 0.0001f);
- if (strcmp(object->id.name, "OBCube") != 0) {
+ if (!STREQ(object->id.name, "OBCube")) {
EXPECT_V3_NEAR(object->rot, float3(M_PI_2, 0, 0), 0.0001f);
}
EXPECT_V3_NEAR(object->scale, float3(1, 1, 1), 0.0001f);
@@ -95,8 +97,9 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
EXPECT_EQ(mesh->totedge, exp.mesh_totedge_or_curve_endp);
EXPECT_EQ(mesh->totpoly, exp.mesh_totpoly_or_curve_order);
EXPECT_EQ(mesh->totloop, exp.mesh_totloop_or_curve_cyclic);
- EXPECT_V3_NEAR(mesh->mvert[0].co, exp.vert_first, 0.0001f);
- EXPECT_V3_NEAR(mesh->mvert[mesh->totvert - 1].co, exp.vert_last, 0.0001f);
+ const Span<MVert> verts = mesh->verts();
+ EXPECT_V3_NEAR(verts.first().co, exp.vert_first, 0.0001f);
+ EXPECT_V3_NEAR(verts.last().co, exp.vert_last, 0.0001f);
const float3 *lnors = (const float3 *)(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
float3 normal_first = lnors != nullptr ? lnors[0] : float3(0, 0, 0);
EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f);
diff --git a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc
index 08050ac34c9..ce3c14a2939 100644
--- a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc
@@ -6,6 +6,7 @@
#include "testing/testing.h"
+#include "obj_export_mtl.hh"
#include "obj_import_file_reader.hh"
namespace blender::io::obj {
@@ -49,18 +50,26 @@ class obj_mtl_parser_test : public testing::Test {
}
const MTLMaterial &got = *materials.lookup(exp.name);
const float tol = 0.0001f;
- EXPECT_V3_NEAR(exp.Ka, got.Ka, tol);
- EXPECT_V3_NEAR(exp.Kd, got.Kd, tol);
- EXPECT_V3_NEAR(exp.Ks, got.Ks, tol);
- EXPECT_V3_NEAR(exp.Ke, got.Ke, tol);
- EXPECT_NEAR(exp.Ns, got.Ns, tol);
- EXPECT_NEAR(exp.Ni, got.Ni, tol);
- EXPECT_NEAR(exp.d, got.d, tol);
- EXPECT_NEAR(exp.map_Bump_strength, got.map_Bump_strength, tol);
- EXPECT_EQ(exp.illum, got.illum);
- for (const auto &it : exp.texture_maps.items()) {
- const tex_map_XX &exp_tex = it.value;
- const tex_map_XX &got_tex = got.texture_maps.lookup(it.key);
+ EXPECT_V3_NEAR(exp.ambient_color, got.ambient_color, tol);
+ EXPECT_V3_NEAR(exp.color, got.color, tol);
+ EXPECT_V3_NEAR(exp.spec_color, got.spec_color, tol);
+ EXPECT_V3_NEAR(exp.emission_color, got.emission_color, tol);
+ EXPECT_V3_NEAR(exp.transmit_color, got.transmit_color, tol);
+ EXPECT_NEAR(exp.spec_exponent, got.spec_exponent, tol);
+ EXPECT_NEAR(exp.ior, got.ior, tol);
+ EXPECT_NEAR(exp.alpha, got.alpha, tol);
+ EXPECT_NEAR(exp.normal_strength, got.normal_strength, tol);
+ EXPECT_EQ(exp.illum_mode, got.illum_mode);
+ EXPECT_NEAR(exp.roughness, got.roughness, tol);
+ EXPECT_NEAR(exp.metallic, got.metallic, tol);
+ EXPECT_NEAR(exp.sheen, got.sheen, tol);
+ EXPECT_NEAR(exp.cc_thickness, got.cc_thickness, tol);
+ EXPECT_NEAR(exp.cc_roughness, got.cc_roughness, tol);
+ EXPECT_NEAR(exp.aniso, got.aniso, tol);
+ EXPECT_NEAR(exp.aniso_rot, got.aniso_rot, tol);
+ for (int key = 0; key < int(MTLTexMapType::Count); key++) {
+ const MTLTexMap &exp_tex = exp.texture_maps[key];
+ const MTLTexMap &got_tex = got.texture_maps[key];
EXPECT_STREQ(exp_tex.image_path.c_str(), got_tex.image_path.c_str());
EXPECT_V3_NEAR(exp_tex.translation, got_tex.translation, tol);
EXPECT_V3_NEAR(exp_tex.scale, got_tex.scale, tol);
@@ -101,20 +110,20 @@ TEST_F(obj_mtl_parser_test, string_newlines_whitespace)
"map_Ks sometex_s_spaces_after_name.png \t \r\n";
MTLMaterial mat[6];
mat[0].name = "simple";
- mat[0].Ka = {0.1f, 0.2f, 0.3f};
- mat[0].illum = 4;
+ mat[0].ambient_color = {0.1f, 0.2f, 0.3f};
+ mat[0].illum_mode = 4;
mat[1].name = "tab_indentation";
- mat[1].Kd = {0.2f, 0.3f, 0.4f};
+ mat[1].color = {0.2f, 0.3f, 0.4f};
mat[2].name = "space_after_name";
- mat[2].Ks = {0.4f, 0.5f, 0.6f};
+ mat[2].spec_color = {0.4f, 0.5f, 0.6f};
mat[3].name = "space_before_name";
mat[4].name = "indented_values";
- mat[4].Ka = {0.5f, 0.6f, 0.7f};
- mat[4].Kd = {0.6f, 0.7f, 0.8f};
+ mat[4].ambient_color = {0.5f, 0.6f, 0.7f};
+ mat[4].color = {0.6f, 0.7f, 0.8f};
mat[5].name = "crlf_ending";
- mat[5].Ns = 5.0f;
- mat[5].tex_map_of_type(eMTLSyntaxElement::map_Kd).image_path = "sometex_d.png";
- mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ks).image_path = "sometex_s_spaces_after_name.png";
+ mat[5].spec_exponent = 5.0f;
+ mat[5].tex_map_of_type(MTLTexMapType::Color).image_path = "sometex_d.png";
+ mat[5].tex_map_of_type(MTLTexMapType::Specular).image_path = "sometex_s_spaces_after_name.png";
check_string(text, mat, ARRAY_SIZE(mat));
}
@@ -122,8 +131,8 @@ TEST_F(obj_mtl_parser_test, cube)
{
MTLMaterial mat;
mat.name = "red";
- mat.Ka = {0.2f, 0.2f, 0.2f};
- mat.Kd = {1, 0, 0};
+ mat.ambient_color = {0.2f, 0.2f, 0.2f};
+ mat.color = {1, 0, 0};
check("cube.mtl", &mat, 1);
}
@@ -131,28 +140,28 @@ TEST_F(obj_mtl_parser_test, all_objects)
{
MTLMaterial mat[7];
for (auto &m : mat) {
- m.Ka = {1, 1, 1};
- m.Ks = {0.5f, 0.5f, 0.5f};
- m.Ke = {0, 0, 0};
- m.Ns = 250;
- m.Ni = 1;
- m.d = 1;
- m.illum = 2;
+ m.ambient_color = {1, 1, 1};
+ m.spec_color = {0.5f, 0.5f, 0.5f};
+ m.emission_color = {0, 0, 0};
+ m.spec_exponent = 250;
+ m.ior = 1;
+ m.alpha = 1;
+ m.illum_mode = 2;
}
mat[0].name = "Blue";
- mat[0].Kd = {0, 0, 1};
+ mat[0].color = {0, 0, 1};
mat[1].name = "BlueDark";
- mat[1].Kd = {0, 0, 0.5f};
+ mat[1].color = {0, 0, 0.5f};
mat[2].name = "Green";
- mat[2].Kd = {0, 1, 0};
+ mat[2].color = {0, 1, 0};
mat[3].name = "GreenDark";
- mat[3].Kd = {0, 0.5f, 0};
+ mat[3].color = {0, 0.5f, 0};
mat[4].name = "Material";
- mat[4].Kd = {0.8f, 0.8f, 0.8f};
+ mat[4].color = {0.8f, 0.8f, 0.8f};
mat[5].name = "Red";
- mat[5].Kd = {1, 0, 0};
+ mat[5].color = {1, 0, 0};
mat[6].name = "RedDark";
- mat[6].Kd = {0.5f, 0, 0};
+ mat[6].color = {0.5f, 0, 0};
check("all_objects.mtl", mat, ARRAY_SIZE(mat));
}
@@ -160,92 +169,101 @@ TEST_F(obj_mtl_parser_test, materials)
{
MTLMaterial mat[6];
mat[0].name = "no_textures_red";
- mat[0].Ka = {0.3f, 0.3f, 0.3f};
- mat[0].Kd = {0.8f, 0.3f, 0.1f};
- mat[0].Ns = 5.624998f;
+ mat[0].ambient_color = {0.3f, 0.3f, 0.3f};
+ mat[0].color = {0.8f, 0.3f, 0.1f};
+ mat[0].spec_exponent = 5.624998f;
mat[1].name = "four_maps";
- mat[1].Ka = {1, 1, 1};
- mat[1].Kd = {0.8f, 0.8f, 0.8f};
- mat[1].Ks = {0.5f, 0.5f, 0.5f};
- mat[1].Ke = {0, 0, 0};
- mat[1].Ns = 1000;
- mat[1].Ni = 1.45f;
- mat[1].d = 1;
- mat[1].illum = 2;
- mat[1].map_Bump_strength = 1;
+ mat[1].ambient_color = {1, 1, 1};
+ mat[1].color = {0.8f, 0.8f, 0.8f};
+ mat[1].spec_color = {0.5f, 0.5f, 0.5f};
+ mat[1].emission_color = {0, 0, 0};
+ mat[1].spec_exponent = 1000;
+ mat[1].ior = 1.45f;
+ mat[1].alpha = 1;
+ mat[1].illum_mode = 2;
+ mat[1].normal_strength = 1;
{
- tex_map_XX &kd = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Kd);
+ MTLTexMap &kd = mat[1].tex_map_of_type(MTLTexMapType::Color);
kd.image_path = "texture.png";
- tex_map_XX &ns = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Ns);
+ MTLTexMap &ns = mat[1].tex_map_of_type(MTLTexMapType::SpecularExponent);
ns.image_path = "sometexture_Roughness.png";
- tex_map_XX &refl = mat[1].tex_map_of_type(eMTLSyntaxElement::map_refl);
+ MTLTexMap &refl = mat[1].tex_map_of_type(MTLTexMapType::Reflection);
refl.image_path = "sometexture_Metallic.png";
- tex_map_XX &bump = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Bump);
+ MTLTexMap &bump = mat[1].tex_map_of_type(MTLTexMapType::Normal);
bump.image_path = "sometexture_Normal.png";
}
mat[2].name = "Clay";
- mat[2].Ka = {1, 1, 1};
- mat[2].Kd = {0.8f, 0.682657f, 0.536371f};
- mat[2].Ks = {0.5f, 0.5f, 0.5f};
- mat[2].Ke = {0, 0, 0};
- mat[2].Ns = 440.924042f;
- mat[2].Ni = 1.45f;
- mat[2].d = 1;
- mat[2].illum = 2;
+ mat[2].ambient_color = {1, 1, 1};
+ mat[2].color = {0.8f, 0.682657f, 0.536371f};
+ mat[2].spec_color = {0.5f, 0.5f, 0.5f};
+ mat[2].emission_color = {0, 0, 0};
+ mat[2].spec_exponent = 440.924042f;
+ mat[2].ior = 1.45f;
+ mat[2].alpha = 1;
+ mat[2].illum_mode = 2;
mat[3].name = "Hat";
- mat[3].Ka = {1, 1, 1};
- mat[3].Kd = {0.8f, 0.8f, 0.8f};
- mat[3].Ks = {0.5f, 0.5f, 0.5f};
- mat[3].Ns = 800;
- mat[3].map_Bump_strength = 0.5f;
+ mat[3].ambient_color = {1, 1, 1};
+ mat[3].color = {0.8f, 0.8f, 0.8f};
+ mat[3].spec_color = {0.5f, 0.5f, 0.5f};
+ mat[3].spec_exponent = 800;
+ mat[3].normal_strength = 0.5f;
{
- tex_map_XX &kd = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Kd);
+ MTLTexMap &kd = mat[3].tex_map_of_type(MTLTexMapType::Color);
kd.image_path = "someHatTexture_BaseColor.jpg";
- tex_map_XX &ns = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Ns);
+ MTLTexMap &ns = mat[3].tex_map_of_type(MTLTexMapType::SpecularExponent);
ns.image_path = "someHatTexture_Roughness.jpg";
- tex_map_XX &refl = mat[3].tex_map_of_type(eMTLSyntaxElement::map_refl);
+ MTLTexMap &refl = mat[3].tex_map_of_type(MTLTexMapType::Reflection);
refl.image_path = "someHatTexture_Metalness.jpg";
- tex_map_XX &bump = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Bump);
+ MTLTexMap &bump = mat[3].tex_map_of_type(MTLTexMapType::Normal);
bump.image_path = "someHatTexture_Normal.jpg";
}
mat[4].name = "Parser_Test";
- mat[4].Ka = {0.1f, 0.2f, 0.3f};
- mat[4].Kd = {0.4f, 0.5f, 0.6f};
- mat[4].Ks = {0.7f, 0.8f, 0.9f};
- mat[4].illum = 6;
- mat[4].Ns = 15.5;
- mat[4].Ni = 1.5;
- mat[4].d = 0.5;
- mat[4].map_Bump_strength = 0.1f;
+ mat[4].ambient_color = {0.1f, 0.2f, 0.3f};
+ mat[4].color = {0.4f, 0.5f, 0.6f};
+ mat[4].spec_color = {0.7f, 0.8f, 0.9f};
+ mat[4].illum_mode = 6;
+ mat[4].spec_exponent = 15.5;
+ mat[4].ior = 1.5;
+ mat[4].alpha = 0.5;
+ mat[4].normal_strength = 0.1f;
+ mat[4].transmit_color = {0.1f, 0.3f, 0.5f};
+ mat[4].normal_strength = 0.1f;
+ mat[4].roughness = 0.2f;
+ mat[4].metallic = 0.3f;
+ mat[4].sheen = 0.4f;
+ mat[4].cc_thickness = 0.5f;
+ mat[4].cc_roughness = 0.6f;
+ mat[4].aniso = 0.7f;
+ mat[4].aniso_rot = 0.8f;
{
- tex_map_XX &kd = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Kd);
+ MTLTexMap &kd = mat[4].tex_map_of_type(MTLTexMapType::Color);
kd.image_path = "sometex_d.png";
- tex_map_XX &ns = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Ns);
+ MTLTexMap &ns = mat[4].tex_map_of_type(MTLTexMapType::SpecularExponent);
ns.image_path = "sometex_ns.psd";
- tex_map_XX &refl = mat[4].tex_map_of_type(eMTLSyntaxElement::map_refl);
+ MTLTexMap &refl = mat[4].tex_map_of_type(MTLTexMapType::Reflection);
refl.image_path = "clouds.tiff";
refl.scale = {1.5f, 2.5f, 3.5f};
refl.translation = {4.5f, 5.5f, 6.5f};
refl.projection_type = SHD_PROJ_SPHERE;
- tex_map_XX &bump = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Bump);
+ MTLTexMap &bump = mat[4].tex_map_of_type(MTLTexMapType::Normal);
bump.image_path = "somebump.tga";
bump.scale = {3, 4, 5};
}
mat[5].name = "Parser_ScaleOffset_Test";
{
- tex_map_XX &kd = mat[5].tex_map_of_type(eMTLSyntaxElement::map_Kd);
+ MTLTexMap &kd = mat[5].tex_map_of_type(MTLTexMapType::Color);
kd.translation = {2.5f, 0.0f, 0.0f};
kd.image_path = "OffsetOneValue.png";
- tex_map_XX &ks = mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ks);
+ MTLTexMap &ks = mat[5].tex_map_of_type(MTLTexMapType::Specular);
ks.scale = {1.5f, 2.5f, 1.0f};
ks.translation = {3.5f, 4.5f, 0.0f};
ks.image_path = "ScaleOffsetBothTwovalues.png";
- tex_map_XX &ns = mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ns);
+ MTLTexMap &ns = mat[5].tex_map_of_type(MTLTexMapType::SpecularExponent);
ns.scale = {0.5f, 1.0f, 1.0f};
ns.image_path = "1.Value.png";
}
@@ -253,4 +271,75 @@ TEST_F(obj_mtl_parser_test, materials)
check("materials.mtl", mat, ARRAY_SIZE(mat));
}
+TEST_F(obj_mtl_parser_test, materials_without_pbr)
+{
+ MTLMaterial mat[2];
+ mat[0].name = "Mat1";
+ mat[0].spec_exponent = 360.0f;
+ mat[0].ambient_color = {0.9f, 0.9f, 0.9f};
+ mat[0].color = {0.8f, 0.276449f, 0.101911f};
+ mat[0].spec_color = {0.25f, 0.25f, 0.25f};
+ mat[0].emission_color = {0, 0, 0};
+ mat[0].ior = 1.45f;
+ mat[0].alpha = 1;
+ mat[0].illum_mode = 3;
+
+ mat[1].name = "Mat2";
+ mat[1].ambient_color = {1, 1, 1};
+ mat[1].color = {0.8f, 0.8f, 0.8f};
+ mat[1].spec_color = {0.5f, 0.5f, 0.5f};
+ mat[1].ior = 1.45f;
+ mat[1].alpha = 1;
+ mat[1].illum_mode = 2;
+ {
+ MTLTexMap &ns = mat[1].tex_map_of_type(MTLTexMapType::SpecularExponent);
+ ns.image_path = "../blend_geometry/texture_roughness.png";
+ MTLTexMap &ke = mat[1].tex_map_of_type(MTLTexMapType::Emission);
+ ke.image_path = "../blend_geometry/texture_illum.png";
+ }
+
+ check("materials_without_pbr.mtl", mat, ARRAY_SIZE(mat));
+}
+
+TEST_F(obj_mtl_parser_test, materials_pbr)
+{
+ MTLMaterial mat[2];
+ mat[0].name = "Mat1";
+ mat[0].color = {0.8f, 0.276449f, 0.101911f};
+ mat[0].spec_color = {0.25f, 0.25f, 0.25f};
+ mat[0].emission_color = {0, 0, 0};
+ mat[0].ior = 1.45f;
+ mat[0].alpha = 1;
+ mat[0].illum_mode = 3;
+ mat[0].roughness = 0.4f;
+ mat[0].metallic = 0.9f;
+ mat[0].sheen = 0.3f;
+ mat[0].cc_thickness = 0.393182f;
+ mat[0].cc_roughness = 0.05f;
+ mat[0].aniso = 0.2f;
+ mat[0].aniso_rot = 0.0f;
+
+ mat[1].name = "Mat2";
+ mat[1].color = {0.8f, 0.8f, 0.8f};
+ mat[1].spec_color = {0.5f, 0.5f, 0.5f};
+ mat[1].ior = 1.45f;
+ mat[1].alpha = 1;
+ mat[1].illum_mode = 2;
+ mat[1].metallic = 0.0f;
+ mat[1].cc_thickness = 0.3f;
+ mat[1].cc_roughness = 0.4f;
+ mat[1].aniso = 0.8f;
+ mat[1].aniso_rot = 0.7f;
+ {
+ MTLTexMap &pr = mat[1].tex_map_of_type(MTLTexMapType::Roughness);
+ pr.image_path = "../blend_geometry/texture_roughness.png";
+ MTLTexMap &ps = mat[1].tex_map_of_type(MTLTexMapType::Sheen);
+ ps.image_path = "../blend_geometry/texture_checker.png";
+ MTLTexMap &ke = mat[1].tex_map_of_type(MTLTexMapType::Emission);
+ ke.image_path = "../blend_geometry/texture_illum.png";
+ }
+
+ check("materials_pbr.mtl", mat, ARRAY_SIZE(mat));
+}
+
} // namespace blender::io::obj