[Bf-blender-cvs] [8aa365745a7] master: Fix T96430: new OBJ exporter wrong normals for non-uniform scale, and wrong face order for negative scale
Aras Pranckevicius
noreply at git.blender.org
Sat Mar 19 21:23:43 CET 2022
Commit: 8aa365745a78c0a6778c871f865ab55df3e87e9d
Author: Aras Pranckevicius
Date: Sat Mar 19 16:20:22 2022 -0400
Branches: master
https://developer.blender.org/rB8aa365745a78c0a6778c871f865ab55df3e87e9d
Fix T96430: new OBJ exporter wrong normals for non-uniform scale, and wrong face order for negative scale
This applies patch D14343 from Aras Pranckevicius, with a description:
The new 3.1+ OBJ exporter did not have correct logic when faced with
non-uniform & mirrored (negative on odd number of axes) object scale:
- Normals were not transformed correctly (should use inverse transpose of the matrix),
and were not normalized,
- Face order was not "flipped" when transform has negative scale on odd number of axes
(visible when using "face orientation" viewport overlay).
===================================================================
M source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
M source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
M source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
M source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh
M source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
===================================================================
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 5631bdde2f8..1668ce3269c 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
@@ -43,16 +43,33 @@ void OBJWriter::write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
- Span<int> normal_indices) const
+ Span<int> normal_indices,
+ bool flip) const
{
BLI_assert(vert_indices.size() == uv_indices.size() &&
vert_indices.size() == normal_indices.size());
+ const int vertex_offset = offsets.vertex_offset + 1;
+ 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>();
- for (int j = 0; j < vert_indices.size(); j++) {
- fh.write<eOBJSyntaxElement::vertex_uv_normal_indices>(
- vert_indices[j] + offsets.vertex_offset + 1,
- uv_indices[j] + offsets.uv_vertex_offset + 1,
- normal_indices[j] + offsets.normal_offset + 1);
+ 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);
+ }
+ }
+ else {
+ /* For a transform that is mirrored (negative scale on odd number of axes),
+ * we want to flip the face index order. Start from the same index, and
+ * 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<eOBJSyntaxElement::poly_element_end>();
}
@@ -61,14 +78,26 @@ void OBJWriter::write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> /*uv_indices*/,
- Span<int> normal_indices) const
+ Span<int> normal_indices,
+ bool flip) const
{
BLI_assert(vert_indices.size() == normal_indices.size());
+ 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>();
- for (int j = 0; j < vert_indices.size(); j++) {
- fh.write<eOBJSyntaxElement::vertex_normal_indices>(vert_indices[j] + offsets.vertex_offset + 1,
- normal_indices[j] + offsets.normal_offset +
- 1);
+ 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);
+ }
+ }
+ 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<eOBJSyntaxElement::poly_element_end>();
}
@@ -77,13 +106,26 @@ void OBJWriter::write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
- Span<int> /*normal_indices*/) const
+ Span<int> /*normal_indices*/,
+ bool flip) const
{
BLI_assert(vert_indices.size() == uv_indices.size());
+ 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>();
- for (int j = 0; j < vert_indices.size(); j++) {
- fh.write<eOBJSyntaxElement::vertex_uv_indices>(vert_indices[j] + offsets.vertex_offset + 1,
- uv_indices[j] + offsets.uv_vertex_offset + 1);
+ 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);
+ }
+ }
+ 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<eOBJSyntaxElement::poly_element_end>();
}
@@ -92,11 +134,22 @@ void OBJWriter::write_vert_indices(FormatHandler<eFileType::OBJ> &fh,
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> /*uv_indices*/,
- Span<int> /*normal_indices*/) const
+ Span<int> /*normal_indices*/,
+ bool flip) const
{
+ const int vertex_offset = offsets.vertex_offset + 1;
+ const int n = vert_indices.size();
fh.write<eOBJSyntaxElement::poly_element_begin>();
- for (const int vert_index : vert_indices) {
- fh.write<eOBJSyntaxElement::vertex_indices>(vert_index + offsets.vertex_offset + 1);
+ if (!flip) {
+ for (int j = 0; j < n; ++j) {
+ fh.write<eOBJSyntaxElement::vertex_indices>(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<eOBJSyntaxElement::poly_element_end>();
}
@@ -323,8 +376,12 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
}
/* Write polygon elements. */
- (this->*poly_element_writer)(
- buf, offsets, poly_vertex_indices, poly_uv_indices, poly_normal_indices);
+ (this->*poly_element_writer)(buf,
+ offsets,
+ poly_vertex_indices,
+ poly_uv_indices,
+ poly_normal_indices,
+ obj_mesh_data.is_mirrored_transform());
});
}
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 6048c6d8d7b..50de8ad3282 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
@@ -115,7 +115,8 @@ class OBJWriter : NonMovable, NonCopyable {
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
- Span<int> normal_indices) const;
+ Span<int> normal_indices,
+ bool flip) const;
/**
* \return Writer function with appropriate polygon-element syntax.
*/
@@ -128,7 +129,8 @@ class OBJWriter : NonMovable, NonCopyable {
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
- Span<int> normal_indices) const;
+ Span<int> normal_indices,
+ bool flip) const;
/**
* Write one line of polygon indices as "f v1//vn1 v2//vn2 ...".
*/
@@ -136,7 +138,8 @@ class OBJWriter : NonMovable, NonCopyable {
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> /*uv_indices*/,
- Span<int> normal_indices) const;
+ Span<int> normal_indices,
+ bool flip) const;
/**
* Write one line of polygon indices as "f v1/vt1 v2/vt2 ...".
*/
@@ -144,7 +147,8 @@ class OBJWriter : NonMovable, NonCopyable {
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> uv_indices,
- Span<int> /*normal_indices*/) const;
+ Span<int> /*normal_indices*/,
+ bool flip) const;
/**
* Write one line of polygon indices as "f v1 v2 ...".
*/
@@ -152,7 +156,8 @@ class OBJWriter : NonMovable, NonCopyable {
const IndexOffsets &offsets,
Span<int> vert_indices,
Span<int> /*uv_indices*/,
- Span<int> /*normal_indices*/) const;
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list