Compare commits

..

455 Commits

Author SHA1 Message Date
e9bbfd0c8c Merge branch 'master' into soc-2020-io-performance 2021-10-30 15:37:05 -04:00
1aa953bd19 Merge branch 'master' into soc-2020-io-performance 2021-10-24 08:31:22 -04:00
fc171c1be9 Add more regression tests for new obj exporter.
This adds regression tests for exporting most of the blend files
in the io_tests/blend_geometry and io_tests/blend_scene tests.
A fix was necessary in the BlendfileLoadingBaseTest class to prevent
leakage of some global data generated when a loaded file has metaballs.
Also, had to fix the exporter to deal with empty curves.
2021-10-17 16:17:45 -04:00
96c80950a1 Merge branch 'master' into soc-2020-io-performance 2021-10-14 13:25:59 -04:00
6e9eebe286 Merge branch 'master' into soc-2020-io-performance 2021-09-19 16:49:59 -04:00
53e7a2cb07 Merge branch 'master' into soc-2020-io-performance 2021-09-18 10:03:45 -04:00
e3edf862a9 Fix mistake with last commit - it didn't compile. 2021-09-18 10:03:16 -04:00
5f9eea200d Change where new obj exporter writes temp files.
The code was writing relative to the test_release_dir flag,
but this didn't make a lot of sense.
Better to use Blender's tempdir mechanism, though since Blender
isn't fully initialized when using it for gtests, we have
to call the function to initialize the tempdir.
2021-08-29 13:54:39 -04:00
4a7eca10ab Merge branch 'master' into soc-2020-io-performance 2021-08-28 07:25:52 -04:00
d619c62157 Merge branch 'master' into soc-2020-io-performance 2021-08-22 13:22:18 -04:00
1eed0031ec Add framework to fast obj i/o to regression test whole files.
One tricky aspect is that we want to allow for the version string
part of the header to mismatch, so only check for file equality
after the first lines.
2021-08-15 16:23:28 -04:00
fef2b9e2eb Fix new obj exporter curve test.
Due to a previous fix I made to the transform matrix code,
the golden data for the curve coordinates were incorrect.
2021-07-31 20:57:42 -04:00
db254aa981 Merge branch 'master' into soc-2020-io-performance 2021-07-31 15:40:11 -04:00
40027f31b3 Consistent var naming, function usage. 2021-07-10 19:08:45 +05:30
2cb056af9a Merge branch 'master' into soc-2020-io-performance 2021-07-10 19:04:19 +05:30
22686b4ccf Export transform was wrongly calculated.
Several mistakes fixed: Blender's axes convention was wrongly stated;
the mat3_from_axis_conversion in C returns a transposed matrix,
probably because it was copied from Python; the axis transformation
wasn't properly applied to the location part of an object transform.
2021-06-06 20:16:28 -07:00
984ab4719d Fix crash when UVs are not asked to be exported. 2021-06-05 20:56:20 -07:00
51ea8dc16d Fix (added argument) after master merge. 2021-06-05 12:25:00 -07:00
7a60565e54 Merge branch 'master' into soc-2020-io-performance 2021-06-05 11:33:11 -07:00
30ee3a1d5d Merge branch 'master' into soc-2020-io-performance 2021-05-09 09:25:36 -04:00
13be5a0e9b Merge branch 'master' into soc-2020-io-performance 2021-04-25 13:14:24 -04:00
1100dd8ad1 Merge branch 'master' into soc-2020-io-performance 2021-04-18 16:13:57 -04:00
ab97b22a1a Create test OBJ files in temporary place. 2021-04-18 15:59:37 -04:00
b3adbd8ed8 Fix test to not use Ankit's directory name. 2021-04-17 08:02:44 -04:00
b985418557 Merge branch 'master' into soc-2020-io-performance 2021-04-11 11:32:07 -04:00
fec16d4a8b Progress towards making material output the same as the python exporter.
The python exporter was stricter about what Principled BSDF node it
would use -- it only wanted one directly attached to the Material Output.
Also, the Python exporter sets the ambient to (1,1,1) if no reflections.
And there was a mistake in how the C++ exporter set the illumination model.

Also printed out the components in the same order as the python one,
for easier comparison.
2021-03-28 18:15:04 -04:00
ccc97b664c Fixed problem of repeated same materials output in MTL file.
The code was writing out all of the materials for each object.
Refactored so that the materials for all objects are gathered
together, deduping, and writing out at the end of a frame.
2021-03-28 08:03:17 -04:00
bfea06a639 Fix a bad default assignment and an unused parameter. 2021-03-27 08:52:57 -04:00
6af509f5a5 Merge branch 'master' into soc-2020-io-performance 2021-03-26 08:56:24 -04:00
85ab8eaa88 Put the blender file basename in comment in the header of the .mtl file. 2021-03-20 15:57:13 -04:00
dc68998aad Merge branch 'master' into soc-2020-io-performance 2021-03-20 13:30:59 -04:00
8268e687b0 Fixed up the TODOs re materials left when making it compile again.
Also, fixed a place where a newline belonged in material output.
2021-03-14 16:05:02 -04:00
7c603e6928 Blender source doesn't yet permit modernize-use-override 2021-03-14 13:57:11 -04:00
eb16cebee4 Current blender source hasn't modernized all string literals. 2021-03-14 13:47:57 -04:00
bee5c9720d Merge branch 'master' into soc-2020-io-performance 2021-03-14 13:37:08 -04:00
94dac497b2 Get branch into compling state again.
There are some changes in Materials in the exporter that make compiling
the importer fail. I fixed one and several others are just ifdef'd out
for now so that the branch compiles. TODO to fix the rest.
2021-02-23 11:03:29 -05:00
8abffed35a Merge branch 'master' into soc-2020-io-performance 2021-02-23 09:43:14 -05:00
3ce42cb959 Cleanup 2021-02-22 23:33:45 +05:30
9abc78c3f2 Writer: some tests 2021-02-22 23:33:40 +05:30
a9cf404223 Cleanup: fix typos 2021-02-22 23:33:34 +05:30
29d5149843 Tests: Cleanup 2021-02-22 23:33:13 +05:30
30def30420 Cleanup 2020-12-12 20:47:53 +05:30
10c8b88cf1 Merge branch 'master' into soc-2020-io-performance 2020-12-12 02:35:47 +05:30
5280200275 Exporter: Cleanup: clang-format, comment 2020-12-12 02:35:27 +05:30
ad40a7c3d6 Exporter: create new API for writer.
Isolate formatting options.
Add exceptions instead of three layers of booleans.
Separate header writing from constructor.
2020-12-12 02:35:19 +05:30
d6f0cf048d Exporter: Cleanup: clang-tidy 2020-12-12 02:35:15 +05:30
7b4bb69866 Cleanup: CMake file order and dependencies 2020-12-12 02:35:10 +05:30
fc71aaa487 Exporter: Fix scaling: change scale before applying locrot transform. 2020-12-05 00:28:58 +05:30
c59a5002e2 Merge branch 'master' into soc-2020-io-performance 2020-12-05 00:27:15 +05:30
5c48127877 Importer: Cleanup: const, remove unneeded assignment. 2020-12-02 10:03:25 +05:30
32dad88e8f Importer: Cleanup: single storer; reorder parameters. 2020-12-02 09:56:08 +05:30
7206226ee0 Importer: Use switch-case instead of else-if chain in main code. 2020-12-01 22:46:56 +05:30
b54aa8a77c Importer: make a class OBJStorer, and smaller functions. 2020-12-01 16:49:59 +05:30
7faaaf7fd7 Importer Cleanup: renames, const. 2020-12-01 00:58:44 +05:30
01fa2a239c Importer: remove useless {}s. renames. 2020-11-30 19:37:12 +05:30
6cc5e59b49 Exporter: remove useless {}s. 2020-11-30 19:31:33 +05:30
06d61d459f Merge branch 'master' into soc-2020-io-performance 2020-11-29 17:29:57 +05:30
f4b22244ca Merge branch 'master' into soc-2020-io-performance 2020-11-23 17:11:41 +05:30
df6fe191a9 Remove commented-out code; correct spelling. 2020-11-20 15:05:41 +05:30
d6f4c1f0d3 importer: fix \r issue for file created on windows. 2020-11-19 15:30:21 +05:30
9fc8ec7791 Exporter: Add more OBJCurve tests
File {F9302561}
2020-11-16 20:01:59 +05:30
65b7d952ff Tests: Cleanup: renames, comments. 2020-11-16 20:00:03 +05:30
e5a97df7b5 Cleanup tests: move default to header, add failures. 2020-11-16 18:43:41 +05:30
4b40cce671 Cleanup: rename, comments. 2020-11-16 18:43:16 +05:30
19f926f593 Importer: Cleanup: Spellings 2020-11-16 02:54:30 +05:30
ae8b87e757 Merge branch 'master' into soc-2020-io-performance 2020-11-16 02:28:59 +05:30
7859e3c280 Cleanup: renames, comments. 2020-11-14 18:41:55 +05:30
43c1e37d45 Merge branch 'master' into soc-2020-io-performance 2020-11-14 13:10:45 +05:30
d1492ebb6d cleanup: move defaults to header file; renaming. 2020-11-14 04:11:04 +05:30
36904f01a6 Exporter: add OBJCurves tests.
Corresponds to file https://developer.blender.org/F9278970 which
should be dropped at `io_tests/blend_scene/all_curves_2_92.blend`.
2020-11-14 04:10:21 +05:30
44629501fe Cleanup: renames. 2020-11-13 14:07:54 +05:30
533964ca7d cleanup: remove unneeded fixture; remove magic number. 2020-11-11 20:32:16 +05:30
1c3d4ace05 Merge branch 'master' into soc-2020-io-performance 2020-11-11 20:07:06 +05:30
57ae71dbf3 Exporter: start adding tests.
Corresponds to file https://developer.blender.org/F9260238

It should be put in "io_tests/blend_scene/all_objects_2_92.blend"
directory.
2020-11-11 19:56:28 +05:30
6ca3ca23de Cmake: add initial GTest support, placeholder file. 2020-11-11 19:53:17 +05:30
25bac75fae Exporter: Cleanup: minor rename 2020-11-11 14:42:21 +05:30
bc52869756 Cleanup: const, renames, remove single use variables. 2020-11-10 20:06:41 +05:30
347a12ba4f Merge branch 'master' into soc-2020-io-performance 2020-11-09 21:32:28 +05:30
1223782976 Cleanup: importer: const, range-based for-loops, etc. 2020-11-08 19:01:54 +05:30
30cc8b8567 Cleanup: exporter: const, clang-tidy. 2020-11-08 18:42:39 +05:30
9df5b84b1b Cleanup: exporter: use range-based for loops. 2020-11-08 18:39:40 +05:30
60b5a8ab62 Merge branch 'master' into soc-2020-io-performance 2020-11-08 15:02:13 +05:30
8a785ee54f Cleanup: Clang-format. 2020-11-07 18:37:57 +05:30
b046126ac5 Noise: fix uninitialized variable warning.
Mistake in 74188e6502
2020-11-07 18:34:57 +05:30
5d3533f4d5 Cleanup: use std::make_unique instead of new. 2020-11-07 18:33:17 +05:30
4e8c2cfd1c Cleanup: Importer: NULL to nullptr. 2020-11-07 18:32:04 +05:30
0bfa68c901 Cleanup: Exporter: NULL to nullptr, mismatching parameter name. 2020-11-07 18:26:09 +05:30
d58b2c258b Cleanup: Clang-tidy else-after-return 2020-11-07 18:24:56 +05:30
f830f7cdef Cleanup: Clang-tidy, modernize-concat-nested-namespaces 2020-11-07 18:17:12 +05:30
4db25c833a Merge branch 'master' into soc-2020-io-performance 2020-11-07 15:19:42 +05:30
16c51ce148 Merge branch 'master' into soc-2020-io-performance 2020-11-07 12:25:09 +05:30
af2161f901 Experiment: Remove return value arguments. rename face to poly/polygon everywhere. 2020-11-04 00:24:25 +05:30
5b3c7458e9 Exporter: Complete TODO about exiting edit mode gracefully. 2020-11-03 15:16:26 +05:30
2761a59387 Merge branch 'master' into soc-2020-io-performance 2020-11-03 15:01:24 +05:30
9f14881e61 Cleanup: fix function names 2020-10-28 11:16:39 +05:30
3f94db1af2 Merge branch 'master' into soc-2020-io-performance 2020-10-26 17:31:50 +05:30
53e53c1123 Cleanup: clang-format 2020-10-19 01:43:16 +05:30
447d2b5b12 main exporter file: create smaller functions. 2020-10-19 01:43:08 +05:30
3d12e92200 Cleanup: Remove unused function 2020-10-19 01:43:04 +05:30
d0bb2c6277 Writers: use NonMovable, and NonCopyable. 2020-10-19 01:42:57 +05:30
9554e93efd Cleanup: edit comments as per policy, function and variable names. 2020-10-19 01:42:49 +05:30
f52023a85c clang-tidy mismatched or missing arg names; else-after-return.
No functional change.
2020-10-19 01:42:44 +05:30
f5d986822d Merge branch 'master' into soc-2020-io-performance 2020-10-19 01:42:13 +05:30
7f854c4bc4 Merge branch 'master' into soc-2020-io-performance 2020-10-15 16:14:44 +05:30
2ace7521e3 Merge branch 'master' into soc-2020-io-performance 2020-10-15 14:57:05 +05:30
670c103f10 Move files to exporter and importer folder. 2020-10-07 00:10:47 +05:30
183c4af692 Cleanup: edit comments, spellings. 2020-10-07 00:06:12 +05:30
85f809ca39 Remove writer's destructor to .cc file 2020-10-07 00:06:06 +05:30
f1a60130bd Move normal indices update near normal writer code.
Remove `per_object_tot_normals_` from member variable.
2020-10-07 00:06:00 +05:30
b3f08db450 Merge branch 'master' into soc-2020-io-performance 2020-10-06 14:39:48 +05:30
4f041c98fc Merge branch 'master' into soc-2020-io-performance 2020-10-05 17:54:15 +05:30
0af469d131 Merge branch 'master' into soc-2020-io-performance 2020-10-02 16:33:14 +05:30
4c8253a966 Cleanup: Fix typo in comments. 2020-09-29 22:43:47 +05:30
9c622b9223 Merge branch 'master' into soc-2020-io-performance 2020-09-29 22:19:09 +05:30
1a658978e5 Cleanup: Edit comments, remove unused headers. 2020-09-29 22:18:10 +05:30
c2305201bc Remove the need to apply modifiers to use render properties. 2020-09-29 22:18:05 +05:30
61ad01ec0c Cleanup: edit comments 2020-09-29 22:18:01 +05:30
f0de7b58bf Rename curv_num to control_points 2020-09-29 22:17:56 +05:30
dbd7c31f86 Add more const default variables. 2020-09-29 22:17:50 +05:30
ac2b609e4e Fix UI: don't edit frame numbers if animation is disabled. 2020-09-29 22:17:44 +05:30
d5b0467732 Use fputs instead of fprintf for non-formatted strings. 2020-09-29 22:17:32 +05:30
84d32cb5c5 Cleanup: Remove unneeded headers.
No functional change.
2020-09-21 17:04:48 +05:30
55bc6ac173 Merge branch 'master' into soc-2020-io-performance 2020-09-21 16:52:00 +05:30
9e04dc90c7 Cleanup: clang format. 2020-09-21 16:36:01 +05:30
78bbdbd931 Add emission strength to MTL importer.
Ref rBAec4ad081e564
2020-09-21 16:36:01 +05:30
0444cabb41 Keep axes defaults same as python importer. 2020-09-21 16:36:01 +05:30
33bd98a97b Remove duplicate MTLMaterial, tex_map_XX. clean-up headers. 2020-09-21 16:36:01 +05:30
8b316eb7a8 Mesh: remove unused function, wrong assert, {} etc. 2020-09-21 15:59:25 +05:30
bc2a8f01ba Material: add emission strength's effect on Ke (color)
Ref {rBAec4ad081e564}
2020-09-21 15:59:25 +05:30
aaa4a544ae Material: add comments, use explicit float3 initialisation. 2020-09-21 15:56:45 +05:30
ef8b8f4030 Material: style guide, Class rearrangement. 2020-09-21 15:53:24 +05:30
2e16d14cee Writer: add object group writer member function 2020-09-21 15:46:46 +05:30
942039244e Nurbs: remove depsgraph from class, minor cleanup. 2020-09-21 15:46:45 +05:30
5ab177be32 Replace uint and short with int and int16_t 2020-09-21 15:46:45 +05:30
6570780a79 Cleanup: exporter main: use const, style guide. 2020-09-21 15:46:45 +05:30
e96dd70fac Cleanup: use const, edit comments, reorder includes.
No functional change.
2020-09-21 15:46:45 +05:30
b6b4aa99ff Change axes transform defaults to match old behavior. 2020-09-21 15:46:45 +05:30
ded6377ea0 Write empty usemtl if a polygon has no material. 2020-09-21 15:46:45 +05:30
3e544770f6 Merge branch 'master' into soc-2020-io-performance 2020-09-21 15:45:04 +05:30
8d5101ce1d MTLWriter: overwrite the file instead of appending to it. 2020-09-16 16:30:06 +05:30
8ce2fdee8b Prepend importer_ to mesh_utils; parser_ to string_utils. 2020-09-16 16:20:29 +05:30
9e15728380 Move MTLMaterial & float3_to_string to exporter files.
Keeping the branch in sync with D8754 and D8753.
2020-09-16 16:09:02 +05:30
c1c1e3ea88 Merge branch 'exporter_n' into soc-2020-io-performance 2020-09-16 15:57:09 +05:30
d1cc8c4712 Move vertex index Vector resize to OBJMesh. 2020-09-16 15:17:59 +05:30
fb75c957de Corrections: correct wrong assert, remove cast. 2020-09-16 15:17:07 +05:30
83e0db031a Simplify material group calculation. 2020-09-16 15:15:28 +05:30
9ea4a50fee Simplify vertex group calculation. 2020-09-16 15:13:53 +05:30
a45112a9ec Add smooth group constants, use "0" instead of "off". 2020-09-16 15:00:31 +05:30
dfeabd0032 Add polygon element writer selector to OBJWriter. 2020-09-16 14:56:54 +05:30
0f99e37602 Add polygon normal indices calculation method to OBJMesh. 2020-09-16 14:38:22 +05:30
1d19c96a1f Remove depsgraph member variable; use const variables. 2020-09-16 14:29:19 +05:30
641f859f88 Material: Disambiguate mat_nr + 1. 2020-09-16 14:27:09 +05:30
5e54c8a0d5 Add method to free mesh; disambiguate triangulate method. 2020-09-16 14:24:07 +05:30
047189baf0 Create MTLWriter object early, add methods for filename and file status. 2020-09-16 12:09:07 +05:30
8b3f87f9f7 Cleanup: rename functions, use const, edit comments. 2020-09-16 11:58:30 +05:30
b7689c0083 Create IndexOffsets struct instead of array[3].
Make OBJ indices one-based in Writer, not in Object processor.
2020-09-16 11:46:29 +05:30
b99246c613 Early return in a few places.
Fix two consecutive group name `g ...`  lines by adding an `else`.
2020-09-16 11:33:24 +05:30
e3e01ae8a2 Remove UNUSED macro from poly elements writers. 2020-09-16 11:28:38 +05:30
82b4639477 Break MTLWriter::append_materials into two functions.
Silence unused lambda warning in release build.
2020-09-16 11:26:50 +05:30
c5f984d96c Log errors in fopen and fclose. 2020-09-16 11:20:32 +05:30
b136e11526 CMake: Keep unconditional code together. 2020-09-16 11:13:59 +05:30
52d9d6cd21 Review update: Fix exporter UI issues:
Simplify frame correction logic.

Not reset bitflags checkbox.

Use INT_MIN, not -INT_MAX.

Simplify tool-tips.
2020-09-16 11:12:50 +05:30
d67476a83f Review update: fix exporter UI. 2020-09-15 01:15:09 +05:30
1a0909b15d Export loop normals not vertex normals. 2020-09-15 01:15:09 +05:30
2ce3ffb306 Don't write default scale and translation.
Also fix debug warning of material not found.

Add asserts to catch unchanged values.
2020-09-15 01:15:09 +05:30
159a6bc537 Minor fixes, use scoped_timer for export too. 2020-09-15 01:15:09 +05:30
30e48c58ba Cleanup: comments and rna warning. 2020-09-15 01:15:09 +05:30
5c3ec6245e Fix UI tooltips, layout, frame setting.
Fix NodetreeRef crashing due to null nodetree.
2020-09-15 01:15:09 +05:30
a742bede2b Move uv_indices in OBJMesh. Save some memory.
Since OBJMesh has dynamically allocated space in smooth groups
and uv_indices (which can be a lot), destruct objects that have
been written.

Use `const` at some places.
2020-09-15 01:15:09 +05:30
3bffab7a07 Hide Nurb from Writer. Rename OBJNurbs as per object type. 2020-09-15 01:15:09 +05:30
bc78649c01 Remove export_params_ from OBJNurbs. 2020-09-15 01:15:09 +05:30
eaf54f9eb7 Remove export_params_ member from OBJMesh. 2020-09-15 01:15:09 +05:30
31d6df6d35 Not expose MPoly to writer. Write normals correctly
Write vertex normals only of smooth shaded polygons, otherwise
write face normals.

Keep normal indices in writer only since OBJMesh doesn't need to know
about export parameters. (will remove more such items from OBJMesh
later on.)

Keep MPoly related operations inside OBJMesh only & don't expose it to
Writer.
2020-09-15 01:15:09 +05:30
f4c70d7c9f Review update: use float3, std::optional, c_str()
split nurbs function into two.

Add material name append if material groups are specified.
2020-09-15 01:15:09 +05:30
fd529c01c9 fix smooth groups calculation 2020-09-15 01:15:09 +05:30
0af083449e Review update: fix UI text; add comments.
Variable type change for `forward_axis` and `up_axis`.
2020-09-15 01:15:09 +05:30
448dc2da2b Add exporter specific code.
Files like `io_obj.c` which contain both importer and exporter code
are also here.

Differential Revision: https://developer.blender.org/D8754
2020-09-15 01:15:09 +05:30
67a147d2c4 Merge branch 'master' into soc-2020-io-performance 2020-09-14 20:54:38 +05:30
6a5b147a9f Review update: fix exporter UI. 2020-09-04 17:28:24 +05:30
8279501af5 Change bsdf values as per illum values.
Set defaults of MTLMaterial that is useful for importer.
For exporter, asserts have been added.
2020-09-04 17:07:50 +05:30
b96aec3691 Export loop normals not vertex normals. 2020-09-04 16:58:45 +05:30
5117948285 Don't write default scale and translation.
Also fix debug warning of material not found.

Add asserts to catch unchanged values.
2020-09-04 16:56:07 +05:30
6c8f6d5c44 Add float3 to string function to utilities.
Makes the MTL writer a bit compact. That change to be committed soon.
2020-09-04 13:33:03 +05:30
6f7d03b643 Move string utility functions in one file.
No functional change. Only renaming, and adding a few const.
2020-09-04 13:33:03 +05:30
d0e91f78fa Rename vert_treplet to vert_index_mlen; add comments 2020-09-03 16:09:31 +05:30
83ac5a0f5f Minor fixes, use scoped_timer for export too. 2020-09-03 16:08:47 +05:30
85b1234107 Minor fixes, clang-tidy warnings. 2020-09-03 16:07:21 +05:30
21a097f952 Revert renaming mesh_utils to utils.
No functional change.
2020-09-03 14:30:22 +05:30
6b62935e89 Fix importing multiple material for one object.
Also add sphere type reflection to Metallic socket.

Remove double inline warnings, and also trust compiler to inline
what it deems fit.
2020-09-03 00:10:45 +05:30
24a9729921 Cleanup: comments and rna warning. 2020-09-02 23:47:22 +05:30
008eb7af41 Fix build errors on MSVC. 2020-09-02 14:30:01 +05:30
3c4a67c575 Fix UI tooltips, layout, frame setting.
Fix NodetreeRef crashing due to null nodetree.
2020-09-02 14:29:28 +05:30
54f15a66a0 Move uv_indices in OBJMesh. Save some memory.
Since OBJMesh has dynamically allocated space in smooth groups
and uv_indices (which can be a lot), destruct objects that have
been written.

Use `const` at some places.
2020-09-01 17:49:16 +05:30
0ba0c3653b Use std::array, std::min, remove debug function.
Review update for D8753.
2020-09-01 15:13:46 +05:30
40a2caca86 Hide Nurb from Writer. Rename OBJNurbs as per object type. 2020-09-01 14:07:38 +05:30
be046b01d1 Remove export_params_ from OBJNurbs. 2020-09-01 04:39:45 +05:30
7a5d794862 Remove export_params_ member from OBJMesh. 2020-09-01 03:33:42 +05:30
9445be11fb Not expose MPoly to writer. Write normals correctly
Write vertex normals only of smooth shaded polygons, otherwise
write face normals.

Keep normal indices in writer only since OBJMesh doesn't need to know
about export parameters. (will remove more such items from OBJMesh
later on.)

Keep MPoly related operations inside OBJMesh only & don't expose it to
Writer.
2020-09-01 03:33:05 +05:30
0b9f41f4a0 Review update: use float3, std::optional, c_str()
split nurbs function into two.

Add material name append if material groups are specified.
2020-09-01 01:41:34 +05:30
a6ff8534f2 fix smooth groups calculation 2020-09-01 01:39:44 +05:30
c666a4c03c Review update: fix UI text; add comments.
Variable type change for `forward_axis` and `up_axis`.
2020-08-31 22:08:44 +05:30
e715c482cc Rename File menu item text. 2020-08-30 20:26:42 +05:30
c239d5f3b0 Rename files to shorten the name, remove ex/im.
Two letter abbreviations were not deemed good.
2020-08-30 20:19:27 +05:30
8290d2d15c Cleanup: Add description, rename conflicting name
max/min are also functions, so better not keep them as variables.
No functional change.
2020-08-30 19:31:39 +05:30
46ff12a5d2 Add transform options in the importer UI. 2020-08-30 19:21:32 +05:30
5be5f3b4bb Fix minor bugs in logging. 2020-08-30 18:58:18 +05:30
387c58847d Merge branch 'master' into soc-2020-io-performance 2020-08-29 22:39:03 +05:30
80abfd7d55 Fix face element import: index out of range crash 2020-08-28 19:38:45 +05:30
fc816d358e Fix build error after merge; add logging.
Fix typo in the {rB0aeb338d1952725cfb8}: really turn off tessellation
this time.
2020-08-28 17:39:06 +05:30
87f407d679 Merge branch 'master' into soc-2020-io-performance 2020-08-28 17:00:33 +05:30
0aeb338d19 Use unique_ptr for MTLMaterials Map.
Also, early return in `tessellate_polygons`. Turn off tessellation
for a while till valid/invalid options are added in parsing.
2020-08-28 16:52:33 +05:30
9ac8def136 Fix ngon_tessellate filling the holes.
Fix several issues from the commit {rBefab0bc704ece3a}.
Previously, `ngon_tessellate` was filling the holes instead of
triangulating around them by using the "triangle-fan" method.

Now it triangulates around the holes and doesn't fill them.
2020-08-28 03:13:36 +05:30
a662ddd76a Read multiple lines with \\n line breaks. 2020-08-24 00:39:01 +05:30
8c6a06e730 Cleanup: Mark unused variables. 2020-08-23 22:06:38 +05:30
32fe286919 Silence mesh_validate verbose warnings. 2020-08-23 22:05:38 +05:30
b22b962ca2 Silence some warnings; minor changes.
Since `map_bump_strength` was changed to have a
leading space, length should be increased too.

Pass by reference to avoid copy.

Release resources if not moved by the owner in Mesh and
Curve creation code.
2020-08-22 12:40:30 +05:30
6cd247c277 Cleanup: add r_ prefix.
No functional change.

r_offsets -> r_offset.
2020-08-22 12:33:21 +05:30
73454388fb Use blender::StringRef instead of std::string_view.
Context:
{rB9616e2ef78f0}
{rBc521b69ffb68}

In MTL parser, `Vector.first_index_of_try` result was being compared
with `string::npos` which gave correct results since `npos` is -1,
but is wrong semantically. So fix it.
2020-08-22 01:21:10 +05:30
ae122533e7 Use remove_prefix for easy transition to StringRef.
The relevant search functionality was added to StringRef in
{rBc521b69ffb68}
2020-08-22 00:44:43 +05:30
4777a6a54a Move object creation code from constructor.
Also add destructors with assert in case caller doesn't
own the object.

Rename `blender_object_` to `mesh_object_` to be like
`curve_object_`.
2020-08-21 23:06:55 +05:30
d514de67e6 Cleanup: Comments, clang-format. 2020-08-21 22:15:33 +05:30
edd5307e9e Remove unused uv vertex index offset. 2020-08-21 21:31:15 +05:30
10e3f23ba3 Edit FaceElem list outside polygon creating code.
`new_faces` was a lie after it was extended. Better is all_faces.
2020-08-21 21:06:40 +05:30
e76ab12454 Add newly creates faces to imported faces and dissolve edges.
The code so far imports triangles, but also fills holes.
Committing  since it doesn't crash.

test file:

```
o plane_with_hole
v 2 2 0
v 2 -2 0
v -2 -2 0
v -2 2 0

v 1 1 0
v 1 -1 0
v -1 -1 0
v -1 1 0

f 4 1 2 3 4 8 5 6 7 8 4
```
2020-08-21 16:13:02 +05:30
5b0cb5bbbe Fix tessellate crash due to wrong Vector size.
Also fix crash due to out of bound vertex indices.
2020-08-21 16:12:50 +05:30
efab0bc704 Commit as it is ngon-tessellate.
The code is totally untested and will very likely crash.
2020-08-21 15:46:02 +05:30
69270c7800 Cleanup: use const, remove single use variables. 2020-08-18 16:02:02 +05:30
0c7801fa2b Fix overlapping nodes in the nodetree.
Fix filepath being wrong in cases like `-bm 0 filepath`.

Use fallback value in out of range exception.
2020-08-18 16:01:31 +05:30
3f8a8d1757 Silence normal being zero warnings in mesh validate. 2020-08-18 14:30:32 +05:30
c583afd60b Parse vertex normals: vn lines.
Still need to understand how it translates to the
normals seen in the viewport.
2020-08-18 01:30:39 +05:30
0479dc410f Decouple getting smooth groups from export parameters 2020-08-18 01:28:59 +05:30
4923087d25 Export vertex normals if smooth shading is enabled.
`s on/off` line will not be written if that is not checked in the
exporter parameters.
2020-08-17 15:30:44 +05:30
491bd8b8bb Move file open errors to constructors. 2020-08-17 12:16:20 +05:30
c815ba0a3c Add a public member function in MaterialWrap. 2020-08-17 12:15:33 +05:30
c5e0e82f68 Cleanup : clang format; cout > cerr 2020-08-16 19:38:43 +05:30
a732abd99b Clean up: use const, header cleanup.
Also fix build issues that the last two commits introduced.

https://github.com/include-what-you-use/include-what-you-use
2020-08-16 19:32:52 +05:30
99ededd947 Skip parsing extra texture map options, move MTLWriter from Objects code. 2020-08-16 19:31:16 +05:30
ae1c5f16cb Move MTL writer code near OBJ writer code. 2020-08-16 19:28:16 +05:30
d882a63e98 Apply axes transform to exportable Nurbs. 2020-08-14 14:26:41 +05:30
69f70829d2 Fix usemtl line not being written.
`==` → `!=` : the bug.

`totface` → `totpoly`: it was a mistake.

Rest is cleanup.
2020-08-14 01:56:54 +05:30
ba0d376e26 Use function pointer; remove redundant variables. 2020-08-14 01:29:11 +05:30
d9cdfba21e Export packed image file names, not paths. 2020-08-13 23:39:21 +05:30
a725b6f7ac Use const; move constructors to implementation file. 2020-08-13 21:09:53 +05:30
97aeaf8dde Merge branch 'master' into soc-2020-io-performance 2020-08-13 18:18:40 +05:30
d5866e8d74 Cleanup: renaming & comments. 2020-08-13 18:07:58 +05:30
606b0d7da3 Fix several material import bugs, remove wrong assert.
Images were not being loaded since the parent directory was
missing in the path. So add it in tex_map_XX.
2020-08-13 18:00:56 +05:30
d2a798d29f Merge branch 'master' into soc-2020-io-performance 2020-08-12 02:52:04 +05:30
c010cf5814 Fix loose edge export & import, and offsets. 2020-08-12 02:47:11 +05:30
e0c0b8ffd1 Fix vertex offsets for MEdges and MLoops. 2020-08-11 20:34:56 +05:30
bb2eca07a6 Catch out of range exceptions for stoi/stof. 2020-08-11 03:20:59 +05:30
b378f84f7c Add vertex offset due to Curves' vertices also. 2020-08-11 02:53:01 +05:30
009b37719d Fix new Geometry creation with empty initial object. 2020-08-11 02:52:10 +05:30
82eff7a025 Use const& instead of pointers in Mesh class. 2020-08-11 00:05:00 +05:30
d062c712e2 Correct geometry creation code with Curves.
Also make `Geometry` and `GlobalVertices` members of
`CurveFromGeometry` as `const &` to match with
`MeshFromGeometry`.
2020-08-10 23:58:21 +05:30
a0f21e47ae Merge branch 'master' into soc-2020-io-performance 2020-08-10 21:06:18 +05:30
d2fcc7b48c Use FILE_MAX instead of PATH_MAX
Also, allow more vertices data points to be in int
strings.
2020-08-10 21:01:21 +05:30
6ee696e5bf Accept 3D UV vertex coordinates
The third one is still discarded.
2020-08-10 15:25:42 +05:30
9b37f94324 Create new Geometry instance at the start.
Since the following is a valid OBJ file, a new `Geometry` instance
is always required.

```
v 1.0 2.0
```
2020-08-10 15:20:19 +05:30
7f2893848e Move index offset from parsing to Object creation
The only place where the information needed about how many vertices
have been occupied by other objects is `mloop->v` since `v` has to
be in the range from zero to total vertices _in a_ mesh.

All other indices (edge, UV, normal) work best when they're parsed
the way they're written and the corresponding data from the global
list is read directly.

So instead of modifying every index just to keep `mloop->v` happy,
use a `Map<int, int>` for storing vertex indices. This reduces chances
of error greatly and avoid "indices to indices to coordinates".

`Vector` would've been very slow it being unsorted & lookups being done
for _all_ `mloop`s. `Map` gives no drop in performance.

UV vertices from `Geometry` have been removed since `FaceCorner`s store
a direct index indexing into the Global list of UV coordinates.
2020-08-09 19:52:27 +05:30
8598993157 Fix wrong material exporter assert added recently.
Since Alpha in RGBA is not written to the MTL file, callers
use array of length 3.
2020-08-09 17:32:23 +05:30
9616e2ef78 Use std::string_view for string splitting.
While being slightly more error prone, this change
gives a speedup of 1.9 s vs 1.2 s on a 23.3 MB 8-level
subdivided cube OBJ file. [1] The biggest time sink earlier
was splitting strings into smaller ones. Now it is `std::stof`
about which nothing much can be done.

`StringRef` has been completely removed to avoid
casts between `std::string_view::size_type` & `int64_t`
that `StringRef::size()` gives. Also, `find_{first/last}_{not/}_of`
and `substr` have been used a lot, which are missing in `StrinRef`.

The change also removes `\r\n` carriage return line breaks
while cleaning up the string.

Use `blender::StringRefNull`  where null-terminated strings
are present.

`fprintf` has been replaced with `std::cerr` since
`std::string_view::data()` may give a pointer to a non
null terminated buffer. Also, error logging is not performance
-critical. [2]

[1] See week 7 reports for breakdown on the older timings.
https://wiki.blender.org/wiki/User:Ankitm/GSoC_2020_Daily_Reports#Week_7
[2] https://en.cppreference.com/w/cpp/string/basic_string_view/data
2020-08-09 01:12:36 +05:30
6e419e95e7 Remove deleted header from CMakeLists.txt 2020-08-08 02:58:31 +05:30
0a339bb5e7 Use pragma once 2020-08-08 00:28:09 +05:30
5fa1e0eb38 Merge branch 'master' into soc-2020-io-performance 2020-08-07 23:59:55 +05:30
3cff0de435 Fix crash due to OBJ files with no o name line
In some exporters, the group serves as the object name.

Also add some asserts.

Rename `list_of_objects` to `all_geometries`.
2020-08-07 19:46:21 +05:30
27cebf309f Merge branch 'master' into soc-2020-io-performance 2020-08-06 20:46:54 +05:30
06336941b3 Cleanup: Renaming, comments. 2020-08-06 20:07:13 +05:30
2c20b379f9 Don't add null Image* to the p-BSDF node. 2020-08-06 19:03:23 +05:30
d081bf97df Clean-up: Warnings, renaming variables. 2020-08-06 16:41:39 +05:30
befe950f18 Avoid .data() while creating a std::string from StringRef. 2020-08-06 16:28:45 +05:30
1b1727ea6a Remove OBJ prefix from containers.
That is indicated by the namespace itself..
2020-08-06 16:27:56 +05:30
d660455882 Cleanup: Remove Raw* terminology, use geom_type.
After discussion with the mentors [1], the terminology to use
Raw has been removed & `Geometry` is the new name for
"raw objects". eGeometryType has also been added to remove
confusion with OB_MESH etc.

`std::unique_ptr<T > *a` has been replaced with `T *a`.

Naming changes:

`curr_ob` -> `current_geometry` in the parser &
`geometry` in the `Mesh` & `Curve` creators.

`mesh_from_raw_` -> `blender_mesh_`. Similar for curve.

[1]: https://docs.google.com/document/d/17Uzl47OljjoKgaMbukiLHUVGQP220lPTmPS-atb65mw/
2020-08-06 16:08:26 +05:30
8339dd6647 Replace std::string_view with StringRef.
Add comments.
2020-08-06 15:04:36 +05:30
d6f9400417 Merge branch 'master' into soc-2020-io-performance 2020-08-06 01:41:16 +05:30
928736b173 Replace enum and its functions with Map for maps
The enum approach was adding lots of repetitive functions
and switch-case blocks.  Use `blender::Map` instead.

Also fix nodes overlapping.

Connect Texture nodes with correct sockets of p-BSDF.
2020-08-06 01:39:14 +05:30
9b8f2042b0 Add created material to the object. 2020-08-05 23:09:08 +05:30
f9348be84f Create image for image texture node.
Also keep pointer to MTLMaterial in the class itself.
2020-08-05 20:27:20 +05:30
b8e4d4c6da Cleanup: clang-tidy warnings
else after return.

"..." can be made a static function instead of member function.
2020-08-05 20:24:04 +05:30
d5ad01edf3 Fix bsdf_ being null; asserts for SOCK_RGBA
Use  `ntreeType_Shader->idname` instead of manually entering the
ID to avoid mistakes (which I did!
`ShaderNodeTree` vs `ShaderNodetree`).

Add assert in case caller doesn't own the `nodetree_`.

Fix passing `float a, int b` to `Span` instead
of `float *, size_t size`.
2020-08-04 21:27:29 +05:30
64ff38a7a7 Use Map's lookup instead of direct pointer to MTLMaterial
A direct pointer to a struct no longer points to the internal struct
of the `Map`, it seems. So use lookup which returns the reference too.
2020-08-04 19:30:38 +05:30
722a793b74 MTL: use mtllib for importing MTL files.
Create a utility function for splitting lines into the first words
& the rest of it.
2020-08-04 18:53:17 +05:30
8e58bd0996 MTL: release shader_output_ node instead of bsdf_. 2020-08-04 16:35:53 +05:30
a26657cdb8 Merge branch 'master' into soc-2020-io-performance 2020-08-04 15:57:54 +05:30
c401d8a0ae Initial material creation support. 2020-08-04 15:56:33 +05:30
48d3582196 Cleanup: Use MutableSpan, add asserts
Remove passing of unnecessary variables.

Limit scope of `tex_image_filepath`.
2020-08-04 15:54:45 +05:30
9433124290 Merge branch 'master' into soc-2020-io-performance 2020-07-31 16:36:55 +05:30
7b77d88275 Merge branch 'master' into soc-2020-io-performance 2020-07-30 18:26:03 +05:30
19145856ba Add MTL parser. 2020-07-30 18:24:52 +05:30
c5bd1631f6 Add fallback value in string to number conversions
Remove remnant `stringstream s_line` which was used with `>>`
operator for storing floats and ints. That has been replaced
with `stof`/ `stoi`.

Limit the scope of MTL exporter's tex_node pointer.
2020-07-30 18:07:13 +05:30
a59bbede21 Merge branch 'master' into soc-2020-io-performance 2020-07-27 14:31:03 +05:30
78f29f6c0a Fix build error due to forward enum declaration
In full build, the following error happens. So fix it by including the
definition file before the forward declaration one.

```
In file included from source/blender/io/collada/SkinInfo.cpp:40:
source/blender/blenkernel/BKE_object_deform.h:62:6: error:
 enumeration previously declared with nonfixed underlying type
enum eVGroupSelect
     ^
In file included from source/blender/io/collada/SkinInfo.cpp:36:
source/blender/makesdna/DNA_scene_types.h:2099:14: note:
previous declaration is here
typedef enum eVGroupSelect {
             ^
1 error generated.
```
2020-07-27 13:38:08 +05:30
b33a4592a3 Use VectorSet instead of vector for def_group.
The lookups are now faster and insertion order is also
 retained since no item is removed from the `VectorSet`.

Also fix a leak that happened due to mishandling of the pointer
to the allocated memory of `MDeformWeight`.

Remove potentially confusing loop index that is used with
`tot_loop_idx`.
2020-07-25 13:20:34 +05:30
ffaa1df439 Cleanup: silence clang-tidy warnings; comments.
Use static_cast wherever applicable.

Pass struct by reference.

Remove unnecessary const qualifiers for primitive types.

Make some member functions static instead.

Remove intermediate non-owning pointers to new class instances.

Remove else in else-after-return.

Initialise variables at definition.
2020-07-25 00:05:45 +05:30
37467ec5e9 Keep vertex deform group names and def_nr in sync
I realised later on that Map is unordered, so the order of insertion,
on which def_nr depends, is not retained. So a Vector of strings
has been used & the index of the string-of-interest is the def_nr.

Unfortunately, it will be slow on large number of vertex groups.
2020-07-24 21:02:29 +05:30
5898f6ef1f Merge branch 'master' into soc-2020-io-performance 2020-07-24 03:34:53 +05:30
af278ce58b Fix curve not being visible in Object mode.
Thanks to Howard Trickey(@howardt) for finding the fix!
2020-07-24 03:33:16 +05:30
25526821a4 Support importing vertex deform groups.
Remove unnecessary casting in exporter's deform group related code.

The fix in `BKE_object_deform.h` is temporary, until D8378
is committed to master.
2020-07-24 03:15:21 +05:30
4ec4f5b309 Fix build errors due to wrong auto to type changes
They were the last changes I made and didn't build afterwards.
2020-07-24 00:54:06 +05:30
ed8c902a6a Cleanup: Fix typo in comments. 2020-07-23 21:38:09 +05:30
2bb56c83fa Move Object creation code in Mesh creation class.
This is required for setting deform groups which are a part of `Object` struct.

Also rename NurbsElem > OBJNurbsElem.

Remove forward declarations from *nurbs.hh & *mesh.hh files
since the cyclic dependency with *object.hh is removed.

Remove auto.
2020-07-23 21:35:16 +05:30
4716660591 Rename exportable_meshes to exportable_as_mesh
This change is to make it more clear that this is not a list of
Blender meshes, but objects that are being exported in Mesh form.
Same for NURBS curve.
2020-07-23 16:11:34 +05:30
97aa9d44fa Refactor: Conform to style guide, add documentation.
Rename classes OBJImporter > OBJParser, OBJParentCollection >
OBJmportCollection.

Move OBJRawObject items to private access & use getters. Parser class
is set to its friend since it edits the Raw object heavily.

Break OBJMeshFromRaw and OBJCurveFromRaw into smaller functions with
one responsibility.

Add comments wherever required.

Use int instead of uint.

Remove typedef, use Span.
2020-07-23 15:58:43 +05:30
cab598f2b2 Set active NURBS of a curve; set object group.
Correction for `CU_NURB_ENDPOINT` being a valid `flagu` value , not
`flag`.
2020-07-22 20:50:12 +05:30
31b7a53605 Cleanup: fix grammar in comments. 2020-07-22 14:53:47 +05:30
7bd38c2776 Fix build errors: avoid uint with Vector size() function.
https://wiki.blender.org/wiki/Style_Guide/C_Cpp#Integer_Types
2020-07-22 03:04:53 +05:30
95716b7681 Merge branch 'master' into soc-2020-io-performance 2020-07-22 02:43:56 +05:30
6e21f8c20d Support NURBS curve import & minimal groups support.
There's a problem though: the curve's vertices appear in edit mode
just fine, but the black line doesn't appear in object mode. But the code
so far should've been committed.

Also, some semantics have been made consistent which needed mesh
related functions/ members to be edited:
- `add_object_to_parent` for mesh is now similar to that of curves.
- `OB_MESH` is the default type of a raw object.

`copy_string_to_int` is also added to support multiple `int` values.
2020-07-22 02:40:47 +05:30
9cb750ba66 Cleanup: Remove unused functions and headers.
Explicitly specify empty string.
2020-07-22 01:52:21 +05:30
b9718a4795 Refactor: move functions out of Importer class
It got left out of the last commit.
2020-07-21 15:57:59 +05:30
a7f5998550 Refactor: move functions out of Importer class
No functional change
2020-07-21 14:23:18 +05:30
71eadb4b62 Move vertex (and UV vertex) list outside OBJRawObject
Since an OBJ file may contain data like [1], the vertex coordinates
list should be detached from any `OBJRawObject`. So every raw object
keeps track of its vertices by indexing into the global list of coordinates.

[1]
```
o plane
v 0 0 2
v 0 2 0
v 2 0 0
f 1 2 3
# note missing o <name>
v 1 1 0
v 1 0 0
v 0 1 0
v 0 0 0
g curve
cstype bspline
curv 0 1 -1 -2 -3 -4
...
```
2020-07-20 16:56:10 +05:30
5468cc0aae Fix wrong curve indices: missing parentheses. 2020-07-18 23:23:16 +05:30
7139d216f3 Fix build issues after merge: BKE_* -> NOD_*
Also remove some extra paths from CMakeLists.txt.
2020-07-18 15:32:23 +05:30
dce0a628a2 Merge branch 'master' into soc-2020-io-performance 2020-07-18 14:54:24 +05:30
65fd3be1fa Use MutableSpan instead of raw pointers
Since nearly all but one use cases for `copy_string_to_int`
is for single integer, MutableSpan only adds extra
`{&integer ,1}` syntax at the caller. Better use `int &r_dst`.

Also make exception `const`

Add assert before casting `int` to `uint` for MEdge.
2020-07-18 14:50:28 +05:30
5a9b983263 Support meshes with edges with or without polygons. 2020-07-17 23:16:52 +05:30
37d59dbc8c Cleanup: Rename variables, use {} initialisation.
`{}` syntax would help catch when the C++ containers size() function
changes to `int64_t` since initialiser lists don't allow narrowing variables.

Specify that the strings are `_split`.
2020-07-17 22:55:21 +05:30
e33d8f79a9 Merge branch 'master' into soc-2020-io-performance 2020-07-17 11:33:27 +05:30
ef5941f31a Move stoi into a function; Add exception handling
Also add comments for utility functions.

Also make `string` a `const &`; prefix return variables with `r_`.

Use `string::empty()` instead of comparing it with "" (clang-tidy).
2020-07-17 02:13:04 +05:30
fa0daf9a3e Rename: mesh_from_bm_ to mesh_from_ob_ 2020-07-16 21:28:46 +05:30
151e882512 Exporter: Fix UV indices being edited by the writer.
Also revert
{{rBd68899e99a0c}}
2020-07-16 21:08:07 +05:30
fe4c5350c4 Importer: Fix misaligned UV vertices of a mesh
The previous code was not initialising duplicate UV vertices which
created bad shapes in UV editor.

Also use range-loop.

Also since set_uv needs not be edited, mark curr_object const again.
2020-07-16 20:57:40 +05:30
c275b2784b Exporter: Fix freeing invalid pointer in ~OBJMesh 2020-07-16 20:52:26 +05:30
aab8982f9e Merge branch 'master' into soc-2020-io-performance 2020-07-16 16:04:07 +05:30
92be92befe Fix UV crashes and redundant loops in v1//vn1 case. 2020-07-16 16:00:46 +05:30
031c4732f4 Importer: Support smooth shading for polygons. 2020-07-16 15:59:42 +05:30
501ead4bbc Exporter: fix vertex normals not being exported
The smooth group calculation must be done before normals are
written, to decide between vertex normals and face normals.
So moved the smooth group array in the OBJMesh's private members.
2020-07-16 13:15:06 +05:30
81d46ef2bd Null check: Break if no UV layer found.
Also conditionally add an UV layer, not always.
2020-07-15 20:56:05 +05:30
a4a1184ece Add UV vertices to the newly created mesh.
The mesh->mloopuv has the correct vertices, however it hits
the assert at  `(uniform), function GPU_batch_uniform_4fv,`
`blender/source/blender/gpu/intern/gpu_batch.c, line 617.`
if one switches to UV editing workspace.
2020-07-15 20:21:21 +05:30
d68899e99a Exporter: Fix UV vertex indices off by one. 2020-07-15 20:16:57 +05:30
aa9e4b23e5 Cleanup single use variable, comments, formatting
Also, vert_texture.size() was wrongly compared to 1. It's changed to 2.
2020-07-15 14:39:29 +05:30
aacb1f4756 Use stoi and stof instead of >> for faster parsing. 2020-07-15 04:02:51 +05:30
5e9196ed11 Parse UV coordinates and normals.
Adding UV to the mesh is not done yet.
Using `std:stoi` seems to add some benefits, so UVs will be added
to mesh after parser is complete.
2020-07-15 03:12:35 +05:30
4c9b344a5d Merge branch 'master' into soc-2020-io-performance 2020-07-14 19:35:30 +05:30
ec04edfe5c Directly create Mesh without using intermediate BMesh 2020-07-14 19:23:54 +05:30
3cfcf37cea Refactor: Keep mesh_from_raw_object in a class
The function is moved to a class for a self-contained mesh operation.
BMesh operations will not be required without a mesh first, so they
should be kept in a Mesh operation class.

Remove unused variable: bmain

Keep classes ordered as per Style Guide.

Pass object_name to add_object_to_parent since only that is required.
2020-07-14 01:32:16 +05:30
f8d64b396d Fix build error in due to BKE_mesh.h 2020-07-13 15:35:14 +05:30
582bf4397c Rename files: exporter -> ex, importer -> im.
Minor header cleanup.
2020-07-13 15:32:22 +05:30
7582bbd574 Break code into mesh, objects, and reader files. 2020-07-13 15:13:48 +05:30
f7c2fb187d clang format, style: use {} initialization, nullptr. 2020-07-12 22:04:36 +05:30
c4cec5e52c Make custom B/Mesh deleters for clean syntax 2020-07-12 22:03:43 +05:30
7b123fec1c Fix build error 2020-07-12 19:14:26 +05:30
3e30be30ac Merge local branch for importer into soc-2020-io-performance 2020-07-12 19:08:47 +05:30
e3fb4d0dd6 Merge branch 'master' into soc-2020-io-performance 2020-07-12 18:57:01 +05:30
fc58522598 Use custom creators and deleters for Mesh and BMesh
Avoid freeing meshes allocated by Guarded allocated by unique_ptr
2020-07-12 18:54:06 +05:30
d00d2bd308 Mark OBJRawObject const in add_object_to_parent. 2020-07-12 18:48:47 +05:30
e9aa1b92d6 Add add_polygon_from_verts and add_bmvert to OBJBmeshFromRaw 2020-07-11 22:42:53 +05:30
a10942814a Rename OBJMeshToBmesh to OBJRawToBmesh 2020-07-11 22:25:01 +05:30
f4abd34699 Use better memory management for intermediate meshes. 2020-07-11 22:21:00 +05:30
5299b52d7a Removed extra vertices in the new bmesh
Also considering to use `BM_mesh_bm_to_me_for_eval` to avoid
time spent in `BM_mesh_bm_to_me` for mesh data not required for OBJ.
So some commented code is present.
2020-07-11 02:49:41 +05:30
d14811e517 Commit a basic working importer, with some extra-to-be-removed code. 2020-07-10 23:23:08 +05:30
928f5c9b9a Merge branch 'master' into soc-2020-io-performance 2020-07-10 23:22:41 +05:30
550b7cfba0 Merge branch 'master' into soc-2020-io-performance 2020-07-07 23:15:43 +05:30
e517cc0a06 Use short for tot_col: total materials in an object. 2020-07-06 15:56:13 +05:30
a344a1cbe8 Grammar fixes in comments. 2020-07-06 15:38:42 +05:30
d7f9a627f6 Merge branch 'master' into soc-2020-io-performance 2020-07-06 14:21:19 +05:30
639d512369 Support modifiers' render and viewport properties 2020-07-06 14:07:20 +05:30
e072382976 Add null check for poly_smooth_groups array. 2020-07-04 14:44:05 +05:30
e061df6497 Merge branch 'master' into soc-2020-io-performance 2020-07-04 14:21:32 +05:30
fe3a359fb1 Support multiple smooth groups and bitflags
For uniformity, removed `const MPoly &mpoly` from `write_vertex_groups`
and `write_poly_material`, and replaced it with poly_index. And use
`get_ith_poly` to get the polygon needed.

Removed `is_shaded_smooth`. It was wrong to compare an object level
flag with a polygon level flag. Replaced its usage with
`tot_smooth_groups()`.
2020-07-04 14:06:27 +05:30
c2eb16f662 Cleanup: style guide, reorder classes, comments
https://wiki.blender.org/wiki/Style_Guide

Changes here:
Move non trivial and non-inlined implementations to cc files instead
of header files.

Reorder classes according to style guide.

Remove documentation comments from header files and keep it near
implementation

Break up some functions into smaller ones: `insert_frame_in_path` etc.

Use reference as much as possible, instead of pointers.

Move `_` prefix to suffix of private class members.

Clean up warnings of implicit float conversions, uint conversions.

Use `ATTR_FALLTHROUGH` in switch cases. Move break inside the case
braces.

Remove `blender::io::obj::OBJ_export` function. It was a mistake.

Use `const` in getters.
2020-07-03 20:51:18 +05:30
68807cf466 Fix T78533: Skip image texture if image filepath is empty 2020-07-02 19:48:50 +05:30
d85c2620b8 Export smooth groups for smooth shaded meshes. 2020-07-02 19:28:54 +05:30
91072928cd Fix GPL license copyright year 2020-07-02 17:18:16 +05:30
42a8ea1af3 Remove object filtering code from export_frame.
Also return early if the file cannot be opened before looping over all
the objects in a frame.
2020-07-02 13:45:44 +05:30
fd4e5563fd Use BKE_mesh_calc_poly_normal
Replace custom normal calculation function with an existing function.
2020-07-02 13:43:44 +05:30
5a1ecb1702 Add null check for dvert 2020-07-02 00:32:12 +05:30
df4e43d9fd Rename get_object_deform_vert; add comments
`get_object_deform_vert` → `get_poly_deform_group_name`

Edit comments, and the UI tooltip of the export option.
2020-07-01 23:58:13 +05:30
5ee4aa5744 Merge branch 'master' into soc-2020-io-performance 2020-07-01 21:33:46 +05:30
242df25b28 Fix same group name being duplicated.
Prefix `r_` to values being modified in other functions.

Reorder arguments in vertex group and material functions for
consistency.
2020-07-01 20:18:36 +05:30
3fb230d6fe Resize deform group only upto total groups present. 2020-07-01 14:23:22 +05:30
012175f843 Support vertex group to which a face element belongs.
Differential Revision: https://developer.blender.org/D8170
2020-07-01 14:04:08 +05:30
71c6d384c1 Replace nodes_with_idname with nodes_by_type
The former was removed in
{84901f2edaf1}
2020-06-30 22:07:51 +05:30
905f470598 Merge branch 'master' into soc-2020-io-performance 2020-06-30 21:48:06 +05:30
2585882973 Cleanup: simplified conditionals, remove warnings on linux
Use unsigned int to avoid any range issues.
Remove trailing whitespaces in face elements.
Remove `== false` from conditionals.
2020-06-30 16:47:05 +05:30
9279377f4b Use unique_ptr to avoid early destruction of new meshes. 2020-06-30 16:03:15 +05:30
054f3981b1 Cleanup: AT was redundant in the destructor debug 2020-06-30 12:08:11 +05:30
fdac45d68e Remove redundant call to OBJMesh destructor. 2020-06-30 11:58:42 +05:30
e3e5ae5da8 Fix build issues: namespace BKE > bke
{b51d6e8012e5}
2020-06-30 02:36:45 +05:30
6343c98a8e Merge branch 'master' into soc-2020-io-performance 2020-06-30 02:24:54 +05:30
c2e43ca99a Remove axis transform defines and use existing enums 2020-06-30 02:13:30 +05:30
ddbc43afe0 Clean up: comments, minor refactor.
Use `const char *set_name` instead of `void get_name` which was meant
to copy the buffer originally but then was neglected.

Don't expose `_export_mesh_eval` just for ensuring normals, moved it to
another function.

Use conventional destructor function names.

Upper case enums.
2020-06-30 02:04:03 +05:30
35dc587fd6 Check if there is any material to write. 2020-06-29 20:57:17 +05:30
469398155d Null check: no image is present in the texture node 2020-06-29 20:41:50 +05:30
02fa1f0bba Fix crash when exporting uv vertices with no UV map. 2020-06-29 20:33:01 +05:30
faa11ec04a Support multiple materials in the same object.
Design has slightly changed:
The line with `usemtl` has moved just before a face element is
being written. So whenever a face with a new material is encountered,
it can be labelled.

Appending to the MTL file is still at the same place, writing once every
object.
2020-06-29 19:19:58 +05:30
bab0fce914 Support material groups: writing material name with object name 2020-06-29 14:04:51 +05:30
9086989744 Support for object groups: name of object and its mesh 2020-06-29 13:55:34 +05:30
7685d9e450 Fix socket vector being read as socket RGBA
Wrong typecasting as bNodeSocketRGBA instead of bNodeSocketVector
causes `SOCK_VECTOR`'s `type` being read as `value[0]`.

So instead of having three different functions for float, vector & color, merging
into one and specifying Datatype seems better.
2020-06-29 00:59:21 +05:30
9c6e3e103a Use findNodeSocket since it accepts const bNode*
{rB340130719f4d}
2020-06-28 15:53:37 +05:30
6529b3a09e Merge branch 'master' into soc-2020-io-performance 2020-06-28 15:33:17 +05:30
2e12333c19 Add object name in MTL related errors. 2020-06-28 14:45:12 +05:30
cfa167d57f Use Span<T> instead of const Vector<T> &
Reasons to prefer `Span`:
> - It is shorter.
> - It is const by default (whereas you could easily forget the const  in `const Vector<T> &`).
And I did forget the `const` here!
https://developer.blender.org/D7987#inline-64852
2020-06-28 14:14:19 +05:30
b22f8aec2b Typo: write OBJ & MTL comments properly with # 2020-06-28 13:49:28 +05:30
d724bf3797 Support exporting selected objects only, not the whole scene. 2020-06-28 13:47:04 +05:30
c39128ca97 UI: show warning when overwriting an export file 2020-06-28 02:46:20 +05:30
360ea0a715 Replace char * with string in texture map types.
Review update rB827869a45bccbf1e016580b#271046 (by Jacques Lucke)

As mentioned in his comments, `Map` will do a pointer comparison for
`char *` keys. So string would be better. Even though  the `lookup` has
been removed, `std::string` is still okay.

Also instead of iterating over `Map.keys()`, and then looking up value,
now it's iterating over a key-value pair: `Map<T, T>::item` of strings.

Minor comment changes.
2020-06-28 02:14:41 +05:30
eadc23273e Remove redundant blender:: from Vector, Map etc.
In rB96d6571073d3, `namespace blender` was added.
2020-06-28 01:10:37 +05:30
11e63662be Add texture transform options, Blender version comment.
Two texture transform options, out of several, are supported now:
- Translation (origin offset) (syntax: "-o u v w")
- Scale (syntax: "-s u v w")

For Normal Map textures, Strength (bump multiplier) (syntax: "-bm s")
is also added.

I had to temporarily replace `nodeFindSocket` with its own
implementation to be able to build, since it doesn't accept
`const bNode*` which we're using everywhere.

I proposed a simple fix: D8142 for that. If and when it gets committed,
I'll remove the duplicate code.

Blender version string is also added in the MTL file.

Test file: {F8647881}
2020-06-27 21:53:42 +05:30
96d6571073 Move code to namespace blender; clang-format 2020-06-27 18:49:46 +05:30
eb56b73895 Merge branch 'master' into soc-2020-io-performance 2020-06-27 18:42:38 +05:30
827869a45b Add support for exporting Material Library file
**Why not reuse the `write_mtl` in `export_obj.py` ?**
Because there are no benefits except saving some time now, only to later
waste it in debugging or extending it.
Having it in C++ provides easy extensibility when we need to
add more nodes' support without having to modify node_utils.py, which
itself is a hardcoded wrapper for BSDF and normal map shader nodes.

Quick Summary:
If export_params->export_materials is true, we create an empty MTL file
with the same name (not extension, of course) in the same directory.
`frame_writer` writes its name (with extension) to the OBJ file, to
reference it, as per format specs.

MTLWriter class is added in the new files. It uses NodeTreeRef committed
recently in rBe1cc9aa7f281 for a faster way to find two linked sockets.

`frame_writer` instantiates an MTLWriter for an object which then
*appends* that object's material to the previously created MTL file.
2020-06-27 18:36:36 +05:30
6c98925d5a Refactor: create separate files for mesh & nurbs.
`*exporter_nurbs.{cc/hh}` have been added for OBJNurbs.
`*exporter_mesh.{cc/hh}` have been added for OBJMesh.

Header file cleanup in other files.
2020-06-25 21:33:56 +05:30
42f24a134c Merge branch 'master' into soc-2020-io-performance 2020-06-25 17:54:49 +05:30
dd92c95ea7 Cleanup: clang-format. 2020-06-24 19:29:27 +05:30
ef0eff0b8a Fix repeated UV vertices and their indices
`append`'s usage causes `export_mesh_eval->totloop` many UV vertices
being written to the OBJ file. There are duplicates in that list.

So _tot_uv_vertices is being used to track the unique ones.
2020-06-24 18:13:39 +05:30
31d480174a Add support for exporting nurbs curves & surfaces
Added functionality in OBJNurbs & OBJWriter to export nurbs curve, not
as vertices and edges, but rather control points.

Nurbs surfaces are always converted to mesh and then exported as a
regular mesh with vertices, normals, UV (if it has any), and edges
(if it has no polygons) etc.
2020-06-24 15:38:42 +05:30
12fbd19ee7 Add support for curves to be exported as nurbs 2020-06-24 03:00:45 +05:30
0f383a3d7c Review update: move more things to private access
Review as per D8089:

Add constructors and destructors for both OBJWriter and OBJMesh classes

Move more variables to private and access the required via getters.

Remove unnecessary variables.

Rename ob_mesh to export_mesh_data.
2020-06-24 00:28:26 +05:30
117c990540 Optimisation: reserve memory early; use UNLIKELY
Since we know the minimum number of UV vertices that a mesh can have,
its memory is reserved in advance. `append` later in the loop simply
checks whether there's sufficient space and edits the vector.

Also, in the edge writer, the last iteration is very unlikely :).
2020-06-23 00:31:53 +05:30
d13a05a6cf Use blender::Vector and Array instead of std
The equivalent functions have also been replaced:
`back()` -> `last()`
`push_back()` -> `append()`
2020-06-23 00:31:53 +05:30
3a61338a09 Remove unused comments. 2020-06-23 00:31:53 +05:30
f2a1a66b8c Refactor: arrange the code in OOP style.
The OBJWriter class' one instance writes to one file.
All OBJWriter handles is writing to the file after calling functions
of OBJMesh which collect the required data.

OBJNurbs and OBJMaterial will be added soon too.
2020-06-23 00:31:53 +05:30
0d20c0a6ea Add support for curves to be exported as meshes.
An option in the exporter UI is added for exporting curves as NURBS.
But it doesn't do anything. All curves are exported as a mesh with
vertex coordinates and edges indexing into those coords.

The code duplication is obvious, it will be refactored to be reused
and with keeping object oriented style in mind.
2020-06-23 00:31:53 +05:30
f9289bb5ea Review update: Renaming, comments, minor refactor
Review update for comments in D7959. No new feature has been added.
Changes here:

Use PIL_time.h instead of chrono. Use BLI_path_util.h instead of stdio.

Remove redundant `_to_export` suffix from some variables.

Clarify that `object_to_export` is `ob_mesh` to distinguish it from
curves objects later on.

Edited comments.

Change in face normal calculation in one loop instead of three for the
three axes components.

Add const where required.

Not hardcode Blender version but use `BKE_blender_version_string()`.

Add filenames to error messages in file opening.
2020-06-23 00:31:53 +05:30
c4c1d7b0b9 Renaming: Specify mesh objects instead of object
No functional change is there.

This change is required to distinguish mesh objects from curve objects.
Both of them have different requirements for the structs they'd use to
store their processed data.
So instead of adding if-else everywhere, curves and meshes can be
separated into different files.
2020-06-23 00:31:53 +05:30
f3342b4bfc Merge branch 'master' into soc-2020-io-performance 2020-06-23 00:28:13 +05:30
11357e18f7 Merge branch 'master' into soc-2020-io-performance 2020-06-22 13:45:14 +05:30
b8e80fbce1 Merge branch 'master' into soc-2020-io-performance 2020-06-18 13:49:42 +05:30
c3f8e9550c Export triangulated mesh, not modifying the scene
Add UI checkbox for triangulating before writing the OBJ file.
The scene is not modified at all. Actual modifier should be used if one
needs the mesh to be modified too.

The settings for triangulation are the same as default ones of the
modifier:
ngon-method: "Beauty", quad-method: "Shortest Diagonal", min vertices:4
2020-06-18 13:45:16 +05:30
41f47cd8d6 Make UV coords and face normals optional to write
Adds options in the UI for writing normals and UV coordinates to
the OBJ file.
{F8627897}

As expected, calculating both of them is also skipped conditionally.
However, the memory for normals is still allocated; just not used.
2020-06-17 18:51:29 +05:30
d47318fb45 Add scaling factor in geometry transform. 2020-06-17 15:37:28 +05:30
4ad57b2d7f Merge branch 'master' into soc-2020-io-performance 2020-06-17 15:02:06 +05:30
1d75ece6ad Add forward and up axes transform in preferences. 2020-06-17 14:58:21 +05:30
4a59ba4bc2 Fix crash: exporting object from Edit mode. 2020-06-15 23:26:03 +05:30
4546101237 Make all frames exportable; UI & filename changes
All frames are now exportable including negative ones, instead of
only 0-1000.

Added checkbox for Animation for better UI {F8622012}

File name doesn't contain frame name if no animation is being exported.

Noticed that `source/blender/io/wavefront_obj/IO_wavefront_obj.h` is
missing in the IDE's edited files list. So edited that in.
2020-06-15 22:52:36 +05:30
a79618a719 Merge branch 'master' into soc-2020-io-performance 2020-06-15 14:49:49 +05:30
d21b3ff680 Cleanup: unused headers, minor edits in comments
Since fstream was removed, these headers are useless here.
2020-06-15 14:13:11 +05:30
6d088bdde4 Export multiple frames to separate files.
Frame 20 with mentioned filename `name` is exported to `name020.obj`
It should be modified to exclude cases when a single frame is being
exported to avoid overwriting what the user intended to name it.

Also a filter is added to include only OB_MESH type objects for export.

The limits on frames can be changed, the current limits are like this:
Let's say unknowingly, the user selects the maximum 1000 frames & every
file is 1 MB in size. That will quickly fill up 1 GB on the disk.
More frames add to this risk.
2020-06-15 13:34:44 +05:30
ad5b8bd899 Cleanup: function & variable renaming; comments. 2020-06-13 20:22:46 +05:30
c161c69179 Fix indices with offset for multiple objects.
In case of multiple objects, the vertex, normal, and UV vertex indices
keep adding up for every upcoming object.
2020-06-13 17:59:34 +05:30
40736795ec Export mutiple objects; remove unused fstream.
Adds support for multiple objects to be exported from a frame.
Also checks for them to be OB_MESH types. More object types need to be
supported yet.

Renamed data_to_export to more fitting, object_to_export of which we
use vector to contain all exportable objects.

Remove unused fstream based file writer since fprintf is consistently
faster.

Also reduce function calls of fprintf since lengthy arguments were
already removed.
2020-06-13 16:22:00 +05:30
387d96294a Merge branch 'master' into soc-2020-io-performance 2020-06-12 19:41:54 +05:30
3cbd4516c6 Change export time resolution to milliseconds 2020-06-11 22:56:30 +05:30
c2fbfb421b Fix out of bounds assert and crash in UV vector. 2020-06-11 22:53:33 +05:30
f01a7d508d Export UV vertex coordinates & their indices.
This commit adds support for UV vertex coordinates in the form:
`vt u v` for all vertices in the texture map.

Also, their indices are exported as per file format specification [1,2]
`f */vt1/* */vt2/*` for all polygons.

The text written by this and the python exporter has different order
of coordinates and thus their indices too. So direct diff of the two
files will not work.

Minor comments about 0-based/ 1-based indices are also added.

[1]: https://en.wikipedia.org/wiki/Wavefront_.obj_file#File_format
[2]: http://www.martinreddy.net/gfx/3d/OBJ.spec
2020-06-11 21:12:40 +05:30
37074c26df Comment about mvert normals memory allocation.
Readability: Replace integers to indicate axes with AXIS_{X,Y,Z}.

Consistency: Use uint with indices, like the vectors of the indices
themselves.
2020-06-11 00:21:26 +05:30
0ea70ab8e5 Add faster fprintf writer, remove unused headers
Changes here:

Reverted temporarily to std::vector to keep working, instead of
waiting for D7931 to get committed in master.

Adds an forced inline function for calculation of face/ polygon normals
by averaging vertex normals. I will look for an existing method.
This way, the allocated memory in `data_to_export->mvert[i].no` is
actually used.
Also, `BLI::Vector<uint> face_normal_index` is not needed anymore since
we loop over the same polygon list while writing normals, so
their indices will be the same.

Adds a writer method option, `fprintf`, which is faster than `fstream`.
With fstream, 478 MB of an ico-sphere with 8 subsurf takes 22 seconds.
with fprintf, the same takes 13 seconds.
With fstream, a 44 MB of cube with 8 subsurf take 2.3 seconds.
with fprintf, the same takes 1.4 seconds.

Adds timing info of the full export directly in console.

Removed unused and repeated headers from `wavefront_obj.cc`.

Differential Revision: https://developer.blender.org/D7959
2020-06-09 00:27:27 +05:30
86845ea907 Move iteration variable inside the loops.
To limit the scope & for better naming, moved the variables
`MVert *vertex` and `const Polygon &polygon` inside the loops.
2020-06-08 21:26:05 +05:30
7af1ec516f Formatting, edit comments, remove extra io::obj
Changes here:

Made variables `vertex` & `polygon` for better readability in writer.
`data_to_export->mvert`
`data_to_export->polygon_list`

Edited comments as per review in D7918.

Removed extraneous `io::obj::` being used in the same namespace.
2020-06-08 20:24:46 +05:30
b234b2fcf1 Merge branch 'master' into soc-2020-io-performance
Fixes memory leak in subsurf modifier, most probably fixed by Sergey
between 25th to 28th May 2020, in Opensubdiv improvements.
2020-06-06 20:39:54 +05:30
02c7cf5322 Namespace in lower case; rename dummy UI settings
Since capitalised namespaces could cause confusion with classes, they
are changed to lower case, in uniformity with the rest of the code.

Also, in some old settings in exporter file selector are renamed to
show that they do nothing. As William Reynish suggested on devtalk
feedback thread, at some point, it'd be good to have them drawn with
python panels. [1]

[1]: devtalk.blender.org/t/13528/2
2020-06-06 15:40:51 +05:30
083e110c49 Review: Better comments, shorter functions.
Changes here:

- Removed unused ex(im)port_params members.
- Made ex(im)port_params consistent.
- Moved `filepath` to OBJEx(Im)port_Params.
- Edited comments as per comments.
- Use <BLI_vector.hh> instead of <vector>.
- Move functions to namespace IO::OBJ.
2020-06-04 21:31:06 +05:30
5f951f96b6 Review: Added documentation & comments.
Review update. Changes here:

Rearrangement of struct members in OBJdata_to_export.

Better comments & documentation.

Linkage: internal `wavefront_obj.hh` & external `IO_wavefront_obj.h`.

Move functions to `namespace IO::OBJ`.
2020-06-04 21:11:48 +05:30
472c67eec2 Style Guide: Rename .h header files to .hh.
Since all headers internal to wavefront_obj are C++ headers, renamed
them to `.hh` following the style guide about extensions.

All occurrences of the header files & their include guards are also
modified.
2020-06-04 18:44:20 +05:30
7c19ab2c61 Rename files from obj to wavefront; move to intern
Changes here:

Move the files in `blender/io/obj` to `blender/io/obj/intern` following
the rest of the code structure.

Prefix `obj` in filenames with `wavefront_` to avoid confusion with
Blender object data type or compiled C file.

Include guards renaming according to new filenames.

`#include "*"` renames: for example
`#include "obj.h"` to  `#include "wavefront_obj.h`

Rename `bf_obj` to `bf_wavefront_obj` in CMakeLists.txt.
2020-06-04 18:31:36 +05:30
485cc4330a Preliminary geometry data exported, without any axes modification.
Single object geometry data exporter: vertex, vertex normal, faces.
Completed the todos in rB3c947bd5a6a2.

Todo:
Add object name.
Export multiple objects in the same file.
Verify it on other complex shapes.
Texture coordinates.
2020-06-02 13:19:16 +05:30
3c947bd5a6 Working UI for importer too. Got the mesh.
- Added all required dummy files.
- Finished rudimentary UI for Importer too.
- Among the several ways to get the current/ active object, picked
the most common way to get to the vertices. Might have to change
it, when _export all objects_,  etc settings appear.

TODO:
- Will finalise a singular data structure.
- Will discuss about `#include`s in `.h` vs `.cpp`.
- Filepath may be moved inside `OBJExportParams`.
- Clear up `io_obj.c`'s includes.
2020-05-27 01:32:58 +05:30
7294f0ce3d Revert the changes for ccache and lld.
These were meant to be local changes & not pushed to the GSoC branch.
After discussion with the mentors, I'm adding this reverting commit.
Moreover, LLD for mach-o is not production ready & under development.
See [1] [2].

Now building the branch will not need any modifications.

[1]: https://reviews.llvm.org/D75382
[2]: http://clang-developers.42468.n3.nabble.com/Building-clang-on-OSX-td4064374.html#a4064378
2020-05-25 17:07:29 +05:30
4864f7e281 LLD & ccache under if blocks. Use AND 0 to avoid changes. 2020-05-21 21:48:01 +05:30
3e3cee15bf Placeholder exporter UI and settings working. 2020-05-21 20:24:09 +05:30
475f15210d Placeholder files, WIP 2020-05-21 20:24:09 +05:30
e2d9b9fd6a Placeholder files, WIP 2020-05-21 20:24:09 +05:30
3cfb3360ca Linker changes. 2020-05-21 20:23:43 +05:30
781b74589a enabled ccahe; modified compilers it seems 2020-05-21 20:23:43 +05:30
3245 changed files with 80155 additions and 120694 deletions

View File

@@ -12,8 +12,6 @@ Checks: >
-readability-avoid-const-params-in-decls,
-readability-simplify-boolean-expr,
-readability-make-member-function-const,
-readability-suspicious-call-argument,
-readability-redundant-member-init,
-readability-misleading-indentation,
@@ -27,8 +25,6 @@ Checks: >
-bugprone-branch-clone,
-bugprone-macro-parentheses,
-bugprone-reserved-identifier,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-sizeof-expression,
-bugprone-integer-division,
@@ -44,8 +40,7 @@ Checks: >
-modernize-pass-by-value,
# Cannot be enabled yet, because using raw string literals in tests breaks
# the windows compiler currently.
-modernize-raw-string-literal,
-modernize-return-braced-init-list
-modernize-raw-string-literal
CheckOptions:
- key: modernize-use-default-member-init.UseAssignment

View File

@@ -187,13 +187,6 @@ mark_as_advanced(CPACK_OVERRIDE_PACKAGENAME)
mark_as_advanced(BUILDINFO_OVERRIDE_DATE)
mark_as_advanced(BUILDINFO_OVERRIDE_TIME)
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16")
option(WITH_UNITY_BUILD "Enable unity build for modules that support it to improve compile times" ON)
mark_as_advanced(WITH_UNITY_BUILD)
else()
set(WITH_UNITY_BUILD OFF)
endif()
option(WITH_IK_ITASC "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
option(WITH_IK_SOLVER "Enable Legacy IK solver (only disable for development)" ON)
option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke, ocean sim, and audio effects)" ON)
@@ -418,7 +411,6 @@ option(WITH_CYCLES "Enable Cycles Render Engine" ON)
option(WITH_CYCLES_OSL "Build Cycles with OpenShadingLanguage support" ON)
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
option(WITH_CYCLES_DEBUG "Build Cycles with options useful for debugging (e.g., MIS)" OFF)
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
@@ -433,40 +425,26 @@ mark_as_advanced(WITH_CYCLES_DEBUG_NAN)
mark_as_advanced(WITH_CYCLES_NATIVE_ONLY)
# NVIDIA CUDA & OptiX
if(NOT APPLE)
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles NVIDIA CUDA compute support" ON)
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles NVIDIA OptiX support" ON)
mark_as_advanced(WITH_CYCLES_DEVICE_CUDA)
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles NVIDIA CUDA compute support" ON)
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles NVIDIA OptiX support" ON)
mark_as_advanced(WITH_CYCLES_DEVICE_CUDA)
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles NVIDIA CUDA binaries" OFF)
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 compute_75 CACHE STRING "CUDA architectures to build binaries for")
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime (for developers, makes cuda-gdb work)" ON)
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
mark_as_advanced(WITH_CYCLES_CUBIN_COMPILER)
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
mark_as_advanced(WITH_CUDA_DYNLOAD)
endif()
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles NVIDIA CUDA binaries" OFF)
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 compute_75 CACHE STRING "CUDA architectures to build binaries for")
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime (for developers, makes cuda-gdb work)" ON)
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
mark_as_advanced(WITH_CYCLES_CUBIN_COMPILER)
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
mark_as_advanced(WITH_CUDA_DYNLOAD)
# AMD HIP
if(NOT APPLE)
if(WIN32)
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
else()
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" OFF)
endif()
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for")
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
endif()
# Apple Metal
if(APPLE)
option(WITH_CYCLES_DEVICE_METAL "Enable Cycles Apple Metal compute support" ON)
endif()
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" OFF)
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for")
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
# Draw Manager
option(WITH_DRAW_DEBUG "Add extra debug capabilities to Draw Manager" OFF)
@@ -511,10 +489,11 @@ if(WIN32)
endif()
# This should be turned off when Blender enter beta/rc/release
if("${BLENDER_VERSION_CYCLE}" STREQUAL "alpha")
set(WITH_EXPERIMENTAL_FEATURES ON)
else()
if("${BLENDER_VERSION_CYCLE}" STREQUAL "release" OR
"${BLENDER_VERSION_CYCLE}" STREQUAL "rc")
set(WITH_EXPERIMENTAL_FEATURES OFF)
else()
set(WITH_EXPERIMENTAL_FEATURES ON)
endif()
# Unit testsing
@@ -663,7 +642,7 @@ if(WIN32)
option(WITH_WINDOWS_PDB "Generate a pdb file for client side stacktraces" ON)
mark_as_advanced(WITH_WINDOWS_PDB)
option(WITH_WINDOWS_STRIPPED_PDB "Use a stripped PDB file" ON)
option(WITH_WINDOWS_STRIPPED_PDB "Use a stripped PDB file" On)
mark_as_advanced(WITH_WINDOWS_STRIPPED_PDB)
endif()
@@ -856,7 +835,7 @@ if(WITH_AUDASPACE)
endif()
# Auto-enable CUDA dynload if toolkit is not found.
if(WITH_CYCLES AND WITH_CYCLES_DEVICE_CUDA AND NOT WITH_CUDA_DYNLOAD)
if(NOT WITH_CUDA_DYNLOAD)
find_package(CUDA)
if(NOT CUDA_FOUND)
message(STATUS "CUDA toolkit not found, using dynamic runtime loading of libraries (WITH_CUDA_DYNLOAD) instead")
@@ -1086,7 +1065,7 @@ if(MSVC)
add_definitions(-D__LITTLE_ENDIAN__)
# OSX-Note: as we do cross-compiling with specific set architecture,
# endianness-detection and auto-setting is counterproductive
# endianess-detection and auto-setting is counterproductive
# so we just set endianness according CMAKE_OSX_ARCHITECTURES
elseif(CMAKE_OSX_ARCHITECTURES MATCHES i386 OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64 OR CMAKE_OSX_ARCHITECTURES MATCHES arm64)
@@ -1776,7 +1755,7 @@ endif()
set(CMAKE_CXX_STANDARD 17)
# If C++17 is not available, downgrading to an earlier standard is NOT OK.
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Do not enable compiler specific language extensions.
# Do not enable compiler specific language extentions.
set(CMAKE_CXX_EXTENSIONS OFF)
# Make MSVC properly report the value of the __cplusplus preprocessor macro

View File

@@ -51,7 +51,7 @@ Other Convenience Targets
* config: Run cmake configuration tool to set build options.
* deps: Build library dependencies (intended only for platform maintainers).
The existance of locally build dependencies overrides the pre-built dependencies from subversion.
The existance of locally build dependancies overrides the pre-built dependencies from subversion.
These must be manually removed from '../lib/' to go back to using the pre-compiled libraries.
Project Files

View File

@@ -17,7 +17,7 @@
# ***** END GPL LICENSE BLOCK *****
########################################################################
# Copy all generated files to the proper structure as blender prefers
# Copy all generated files to the proper strucure as blender prefers
########################################################################
if(NOT DEFINED HARVEST_TARGET)

View File

@@ -42,7 +42,6 @@ ExternalProject_Add(nanovdb
URL_HASH ${NANOVDB_HASH_TYPE}=${NANOVDB_HASH}
PREFIX ${BUILD_DIR}/nanovdb
SOURCE_SUBDIR nanovdb
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/nanovdb/src/nanovdb < ${PATCH_DIR}/nanovdb.diff
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/nanovdb ${DEFAULT_CMAKE_FLAGS} ${NANOVDB_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/nanovdb
)

View File

@@ -39,7 +39,7 @@ endif()
set(DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/downloads" CACHE STRING "Path for downloaded files")
# This path must be hard-coded like this, so that the GNUmakefile knows where it is and can pass it to make_source_archive.py:
set(PACKAGE_DIR "${CMAKE_CURRENT_BINARY_DIR}/packages")
option(PACKAGE_USE_UPSTREAM_SOURCES "Use sources upstream to download the package sources, when OFF the blender mirror will be used" ON)
option(PACKAGE_USE_UPSTREAM_SOURCES "Use soures upstream to download the package sources, when OFF the blender mirror will be used" ON)
file(TO_CMAKE_PATH ${DOWNLOAD_DIR} DOWNLOAD_DIR)
file(TO_CMAKE_PATH ${PACKAGE_DIR} PACKAGE_DIR)

View File

@@ -24,7 +24,7 @@ if(MSVC)
add_custom_command(
OUTPUT ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
COMMAND echo packaging python
COMMAND echo this should output at ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
COMMAND echo this should ouput at ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTARGET}/libs
COMMAND ${CMAKE_COMMAND} -E copy ${PYSRC}/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}.lib ${PYTARGET}/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}.lib
COMMAND ${CMAKE_COMMAND} -E copy ${PYSRC}/python.exe ${PYTARGET}/bin/python.exe
@@ -43,7 +43,7 @@ if(MSVC)
add_custom_command(
OUTPUT ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
COMMAND echo packaging python
COMMAND echo this should output at ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
COMMAND echo this should ouput at ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTARGET}/libs
COMMAND ${CMAKE_COMMAND} -E copy ${PYSRC}/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib ${PYTARGET}/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib
COMMAND ${CMAKE_COMMAND} -E copy ${PYSRC}/python${PYTHON_POSTFIX}.exe ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe

View File

@@ -1826,7 +1826,7 @@ compile_OCIO() {
# Force linking against static libs
#rm -f $_inst/lib/*.so*
# Additional dependencies
# Additional depencencies
#cp ext/dist/lib/libtinyxml.a $_inst/lib
#cp ext/dist/lib/libyaml-cpp.a $_inst/lib
@@ -2083,9 +2083,9 @@ compile_OIIO() {
cmake_d="$cmake_d -D OPENEXR_VERSION=$OPENEXR_VERSION"
if [ "$_with_built_openexr" = true ]; then
cmake_d="$cmake_d -D ILMBASE_ROOT=$INST/openexr"
cmake_d="$cmake_d -D OPENEXR_ROOT=$INST/openexr"
INFO "Ilmbase_ROOT=$INST/openexr"
cmake_d="$cmake_d -D ILMBASE_HOME=$INST/openexr"
cmake_d="$cmake_d -D OPENEXR_HOME=$INST/openexr"
INFO "ILMBASE_HOME=$INST/openexr"
fi
# ptex is only needed when nicholas bishop is ready
@@ -2374,9 +2374,9 @@ compile_OSL() {
#~ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
if [ "$_with_built_openexr" = true ]; then
cmake_d="$cmake_d -D ILMBASE_ROOT=$INST/openexr"
cmake_d="$cmake_d -D OPENEXR_ROOT=$INST/openexr"
INFO "Ilmbase_ROOT=$INST/openexr"
INFO "ILMBASE_HOME=$INST/openexr"
cmake_d="$cmake_d -D OPENEXR_ROOT_DIR=$INST/openexr"
cmake_d="$cmake_d -D ILMBASE_ROOT_DIR=$INST/openexr"
# XXX Temp workaround... sigh, ILMBase really messed the things up by defining their custom names ON by default :(
fi
@@ -5801,7 +5801,7 @@ print_info() {
PRINT "If you're using CMake add this to your configuration flags:"
_buildargs="-U *SNDFILE* -U PYTHON* -U *BOOST* -U *Boost* -U *TBB*"
_buildargs="$_buildargs -U *OPENCOLORIO* -U *OPENEXR* -U *OPENIMAGEIO* -U *LLVM* -U *CLANG* -U *CYCLES*"
_buildargs="$_buildargs -U *OPENCOLORIO* -U *OPENEXR* -U *OPENIMAGEIO* -U *LLVM* -U *CYCLES*"
_buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *BLOSC* -U *COLLADA* -U *FFMPEG* -U *ALEMBIC* -U *USD*"
_buildargs="$_buildargs -U *EMBREE* -U *OPENIMAGEDENOISE* -U *OPENXR*"

View File

@@ -1,374 +0,0 @@
Index: nanovdb/nanovdb/NanoVDB.h
===================================================================
--- a/nanovdb/nanovdb/NanoVDB.h (revision 62751)
+++ b/nanovdb/nanovdb/NanoVDB.h (working copy)
@@ -152,8 +152,8 @@
#endif // __CUDACC_RTC__
-#ifdef __CUDACC__
-// Only define __hostdev__ when using NVIDIA CUDA compiler
+#if defined(__CUDACC__) || defined(__HIP__)
+// Only define __hostdev__ when using NVIDIA CUDA or HIP compiler
#define __hostdev__ __host__ __device__
#else
#define __hostdev__
@@ -461,7 +461,7 @@
/// Maximum floating-point values
template<typename T>
struct Maximum;
-#ifdef __CUDA_ARCH__
+#if defined(__CUDA_ARCH__) || defined(__HIP__)
template<>
struct Maximum<int>
{
@@ -1006,10 +1006,10 @@
using Vec3i = Vec3<int>;
/// @brief Return a single precision floating-point vector of this coordinate
-Vec3f Coord::asVec3s() const { return Vec3f(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
+inline __hostdev__ Vec3f Coord::asVec3s() const { return Vec3f(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
/// @brief Return a double precision floating-point vector of this coordinate
-Vec3d Coord::asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
+inline __hostdev__ Vec3d Coord::asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
// ----------------------------> Vec4 <--------------------------------------
@@ -1820,7 +1820,7 @@
}; // Map
template<typename Mat4T>
-void Map::set(const Mat4T& mat, const Mat4T& invMat, double taper)
+__hostdev__ void Map::set(const Mat4T& mat, const Mat4T& invMat, double taper)
{
float * mf = mMatF, *vf = mVecF;
float* mif = mInvMatF;
@@ -2170,7 +2170,7 @@
}; // Class Grid
template<typename TreeT>
-int Grid<TreeT>::findBlindDataForSemantic(GridBlindDataSemantic semantic) const
+__hostdev__ int Grid<TreeT>::findBlindDataForSemantic(GridBlindDataSemantic semantic) const
{
for (uint32_t i = 0, n = blindDataCount(); i < n; ++i)
if (blindMetaData(i).mSemantic == semantic)
@@ -2328,7 +2328,7 @@
}; // Tree class
template<typename RootT>
-void Tree<RootT>::extrema(ValueType& min, ValueType& max) const
+__hostdev__ void Tree<RootT>::extrema(ValueType& min, ValueType& max) const
{
min = this->root().valueMin();
max = this->root().valueMax();
@@ -2336,7 +2336,7 @@
template<typename RootT>
template<typename NodeT>
-const NodeT* Tree<RootT>::getNode(uint32_t i) const
+__hostdev__ const NodeT* Tree<RootT>::getNode(uint32_t i) const
{
static_assert(is_same<TreeNodeT<NodeT::LEVEL>, NodeT>::value, "Tree::getNode: unvalid node type");
NANOVDB_ASSERT(i < DataType::mCount[NodeT::LEVEL]);
@@ -2345,7 +2345,7 @@
template<typename RootT>
template<int LEVEL>
-const typename TreeNode<Tree<RootT>, LEVEL>::type* Tree<RootT>::getNode(uint32_t i) const
+__hostdev__ const typename TreeNode<Tree<RootT>, LEVEL>::type* Tree<RootT>::getNode(uint32_t i) const
{
NANOVDB_ASSERT(i < DataType::mCount[LEVEL]);
return reinterpret_cast<const TreeNodeT<LEVEL>*>(reinterpret_cast<const uint8_t*>(this) + DataType::mBytes[LEVEL]) + i;
@@ -2353,7 +2353,7 @@
template<typename RootT>
template<typename NodeT>
-NodeT* Tree<RootT>::getNode(uint32_t i)
+__hostdev__ NodeT* Tree<RootT>::getNode(uint32_t i)
{
static_assert(is_same<TreeNodeT<NodeT::LEVEL>, NodeT>::value, "Tree::getNode: invalid node type");
NANOVDB_ASSERT(i < DataType::mCount[NodeT::LEVEL]);
@@ -2362,7 +2362,7 @@
template<typename RootT>
template<int LEVEL>
-typename TreeNode<Tree<RootT>, LEVEL>::type* Tree<RootT>::getNode(uint32_t i)
+__hostdev__ typename TreeNode<Tree<RootT>, LEVEL>::type* Tree<RootT>::getNode(uint32_t i)
{
NANOVDB_ASSERT(i < DataType::mCount[LEVEL]);
return reinterpret_cast<TreeNodeT<LEVEL>*>(reinterpret_cast<uint8_t*>(this) + DataType::mBytes[LEVEL]) + i;
@@ -2370,7 +2370,7 @@
template<typename RootT>
template<typename NodeT>
-uint32_t Tree<RootT>::getNodeID(const NodeT& node) const
+__hostdev__ uint32_t Tree<RootT>::getNodeID(const NodeT& node) const
{
static_assert(is_same<TreeNodeT<NodeT::LEVEL>, NodeT>::value, "Tree::getNodeID: invalid node type");
const NodeT* first = reinterpret_cast<const NodeT*>(reinterpret_cast<const uint8_t*>(this) + DataType::mBytes[NodeT::LEVEL]);
@@ -2380,7 +2380,7 @@
template<typename RootT>
template<typename NodeT>
-uint32_t Tree<RootT>::getLinearOffset(const NodeT& node) const
+__hostdev__ uint32_t Tree<RootT>::getLinearOffset(const NodeT& node) const
{
return this->getNodeID(node) + DataType::mPFSum[NodeT::LEVEL];
}
@@ -3366,7 +3366,7 @@
}; // LeafNode class
template<typename ValueT, typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
-inline void LeafNode<ValueT, CoordT, MaskT, LOG2DIM>::updateBBox()
+inline __hostdev__ void LeafNode<ValueT, CoordT, MaskT, LOG2DIM>::updateBBox()
{
static_assert(LOG2DIM == 3, "LeafNode::updateBBox: only supports LOGDIM = 3!");
if (!this->isActive()) return;
Index: nanovdb/nanovdb/util/SampleFromVoxels.h
===================================================================
--- a/nanovdb/nanovdb/util/SampleFromVoxels.h (revision 62751)
+++ b/nanovdb/nanovdb/util/SampleFromVoxels.h (working copy)
@@ -22,7 +22,7 @@
#define NANOVDB_SAMPLE_FROM_VOXELS_H_HAS_BEEN_INCLUDED
// Only define __hostdev__ when compiling as NVIDIA CUDA
-#ifdef __CUDACC__
+#if defined(__CUDACC__) || defined(__HIP__)
#define __hostdev__ __host__ __device__
#else
#include <cmath> // for floor
@@ -136,7 +136,7 @@
template<typename TreeOrAccT>
template<typename Vec3T>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, true>::operator()(const Vec3T& xyz) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, true>::operator()(const Vec3T& xyz) const
{
const CoordT ijk = Round<CoordT>(xyz);
if (ijk != mPos) {
@@ -147,7 +147,7 @@
}
template<typename TreeOrAccT>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, true>::operator()(const CoordT& ijk) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, true>::operator()(const CoordT& ijk) const
{
if (ijk != mPos) {
mPos = ijk;
@@ -158,7 +158,7 @@
template<typename TreeOrAccT>
template<typename Vec3T>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, false>::operator()(const Vec3T& xyz) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, false>::operator()(const Vec3T& xyz) const
{
return mAcc.getValue(Round<CoordT>(xyz));
}
@@ -195,7 +195,7 @@
}; // TrilinearSamplerBase
template<typename TreeOrAccT>
-void TrilinearSampler<TreeOrAccT>::stencil(CoordT& ijk, ValueT (&v)[2][2][2]) const
+__hostdev__ void TrilinearSampler<TreeOrAccT>::stencil(CoordT& ijk, ValueT (&v)[2][2][2]) const
{
v[0][0][0] = mAcc.getValue(ijk); // i, j, k
@@ -224,7 +224,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-typename TreeOrAccT::ValueType TrilinearSampler<TreeOrAccT>::sample(const Vec3T<RealT> &uvw, const ValueT (&v)[2][2][2])
+__hostdev__ typename TreeOrAccT::ValueType TrilinearSampler<TreeOrAccT>::sample(const Vec3T<RealT> &uvw, const ValueT (&v)[2][2][2])
{
#if 0
auto lerp = [](ValueT a, ValueT b, ValueT w){ return fma(w, b-a, a); };// = w*(b-a) + a
@@ -239,7 +239,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-Vec3T<typename TreeOrAccT::ValueType> TrilinearSampler<TreeOrAccT>::gradient(const Vec3T<RealT> &uvw, const ValueT (&v)[2][2][2])
+__hostdev__ Vec3T<typename TreeOrAccT::ValueType> TrilinearSampler<TreeOrAccT>::gradient(const Vec3T<RealT> &uvw, const ValueT (&v)[2][2][2])
{
static_assert(std::is_floating_point<ValueT>::value, "TrilinearSampler::gradient requires a floating-point type");
#if 0
@@ -270,7 +270,7 @@
}
template<typename TreeOrAccT>
-bool TrilinearSampler<TreeOrAccT>::zeroCrossing(const ValueT (&v)[2][2][2])
+__hostdev__ bool TrilinearSampler<TreeOrAccT>::zeroCrossing(const ValueT (&v)[2][2][2])
{
static_assert(std::is_floating_point<ValueT>::value, "TrilinearSampler::zeroCrossing requires a floating-point type");
const bool less = v[0][0][0] < ValueT(0);
@@ -363,7 +363,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, true>::operator()(Vec3T<RealT> xyz) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, true>::operator()(Vec3T<RealT> xyz) const
{
this->cache(xyz);
return BaseT::sample(xyz, mVal);
@@ -370,7 +370,7 @@
}
template<typename TreeOrAccT>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, true>::operator()(const CoordT &ijk) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, true>::operator()(const CoordT &ijk) const
{
return ijk == mPos ? mVal[0][0][0] : BaseT::mAcc.getValue(ijk);
}
@@ -377,7 +377,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-Vec3T<typename TreeOrAccT::ValueType> SampleFromVoxels<TreeOrAccT, 1, true>::gradient(Vec3T<RealT> xyz) const
+__hostdev__ Vec3T<typename TreeOrAccT::ValueType> SampleFromVoxels<TreeOrAccT, 1, true>::gradient(Vec3T<RealT> xyz) const
{
this->cache(xyz);
return BaseT::gradient(xyz, mVal);
@@ -393,7 +393,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-void SampleFromVoxels<TreeOrAccT, 1, true>::cache(Vec3T<RealT>& xyz) const
+__hostdev__ void SampleFromVoxels<TreeOrAccT, 1, true>::cache(Vec3T<RealT>& xyz) const
{
CoordT ijk = Floor<CoordT>(xyz);
if (ijk != mPos) {
@@ -406,7 +406,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, false>::operator()(Vec3T<RealT> xyz) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, false>::operator()(Vec3T<RealT> xyz) const
{
ValueT val[2][2][2];
CoordT ijk = Floor<CoordT>(xyz);
@@ -418,7 +418,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, false>::operator()(Vec3T<RealT> xyz) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, false>::operator()(Vec3T<RealT> xyz) const
{
auto lerp = [](ValueT a, ValueT b, RealT w) { return a + ValueT(w) * (b - a); };
@@ -463,7 +463,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-inline Vec3T<typename TreeOrAccT::ValueType> SampleFromVoxels<TreeOrAccT, 1, false>::gradient(Vec3T<RealT> xyz) const
+inline __hostdev__ Vec3T<typename TreeOrAccT::ValueType> SampleFromVoxels<TreeOrAccT, 1, false>::gradient(Vec3T<RealT> xyz) const
{
ValueT val[2][2][2];
CoordT ijk = Floor<CoordT>(xyz);
@@ -473,7 +473,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-bool SampleFromVoxels<TreeOrAccT, 1, false>::zeroCrossing(Vec3T<RealT> xyz) const
+__hostdev__ bool SampleFromVoxels<TreeOrAccT, 1, false>::zeroCrossing(Vec3T<RealT> xyz) const
{
ValueT val[2][2][2];
CoordT ijk = Floor<CoordT>(xyz);
@@ -510,7 +510,7 @@
}; // TriquadraticSamplerBase
template<typename TreeOrAccT>
-void TriquadraticSampler<TreeOrAccT>::stencil(const CoordT &ijk, ValueT (&v)[3][3][3]) const
+__hostdev__ void TriquadraticSampler<TreeOrAccT>::stencil(const CoordT &ijk, ValueT (&v)[3][3][3]) const
{
CoordT p(ijk[0] - 1, 0, 0);
for (int dx = 0; dx < 3; ++dx, ++p[0]) {
@@ -526,7 +526,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-typename TreeOrAccT::ValueType TriquadraticSampler<TreeOrAccT>::sample(const Vec3T<RealT> &uvw, const ValueT (&v)[3][3][3])
+__hostdev__ typename TreeOrAccT::ValueType TriquadraticSampler<TreeOrAccT>::sample(const Vec3T<RealT> &uvw, const ValueT (&v)[3][3][3])
{
auto kernel = [](const ValueT* value, double weight)->ValueT {
return weight * (weight * (0.5f * (value[0] + value[2]) - value[1]) +
@@ -545,7 +545,7 @@
}
template<typename TreeOrAccT>
-bool TriquadraticSampler<TreeOrAccT>::zeroCrossing(const ValueT (&v)[3][3][3])
+__hostdev__ bool TriquadraticSampler<TreeOrAccT>::zeroCrossing(const ValueT (&v)[3][3][3])
{
static_assert(std::is_floating_point<ValueT>::value, "TrilinearSampler::zeroCrossing requires a floating-point type");
const bool less = v[0][0][0] < ValueT(0);
@@ -624,7 +624,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, true>::operator()(Vec3T<RealT> xyz) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, true>::operator()(Vec3T<RealT> xyz) const
{
this->cache(xyz);
return BaseT::sample(xyz, mVal);
@@ -631,7 +631,7 @@
}
template<typename TreeOrAccT>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, true>::operator()(const CoordT &ijk) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, true>::operator()(const CoordT &ijk) const
{
return ijk == mPos ? mVal[1][1][1] : BaseT::mAcc.getValue(ijk);
}
@@ -646,7 +646,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-void SampleFromVoxels<TreeOrAccT, 2, true>::cache(Vec3T<RealT>& xyz) const
+__hostdev__ void SampleFromVoxels<TreeOrAccT, 2, true>::cache(Vec3T<RealT>& xyz) const
{
CoordT ijk = Floor<CoordT>(xyz);
if (ijk != mPos) {
@@ -657,7 +657,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, false>::operator()(Vec3T<RealT> xyz) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, false>::operator()(Vec3T<RealT> xyz) const
{
ValueT val[3][3][3];
CoordT ijk = Floor<CoordT>(xyz);
@@ -667,7 +667,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-bool SampleFromVoxels<TreeOrAccT, 2, false>::zeroCrossing(Vec3T<RealT> xyz) const
+__hostdev__ bool SampleFromVoxels<TreeOrAccT, 2, false>::zeroCrossing(Vec3T<RealT> xyz) const
{
ValueT val[3][3][3];
CoordT ijk = Floor<CoordT>(xyz);
@@ -710,7 +710,7 @@
}; // TricubicSampler
template<typename TreeOrAccT>
-void TricubicSampler<TreeOrAccT>::stencil(const CoordT& ijk, ValueT (&C)[64]) const
+__hostdev__ void TricubicSampler<TreeOrAccT>::stencil(const CoordT& ijk, ValueT (&C)[64]) const
{
auto fetch = [&](int i, int j, int k) -> ValueT& { return C[((i + 1) << 4) + ((j + 1) << 2) + k + 1]; };
@@ -929,7 +929,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 3, true>::operator()(Vec3T<RealT> xyz) const
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 3, true>::operator()(Vec3T<RealT> xyz) const
{
this->cache(xyz);
return BaseT::sample(xyz, mC);
@@ -937,7 +937,7 @@
template<typename TreeOrAccT>
template<typename RealT, template<typename...> class Vec3T>
-void SampleFromVoxels<TreeOrAccT, 3, true>::cache(Vec3T<RealT>& xyz) const
+__hostdev__ void SampleFromVoxels<TreeOrAccT, 3, true>::cache(Vec3T<RealT>& xyz) const
{
CoordT ijk = Floor<CoordT>(xyz);
if (ijk != mPos) {

View File

@@ -197,38 +197,3 @@ index 67ec0d15f..6dc3e85a0 100644
#else
#error Unknown architecture.
#endif
diff --git a/pxr/base/arch/demangle.cpp b/pxr/base/arch/demangle.cpp
index 67ec0d15f..6dc3e85a0 100644
--- a/pxr/base/arch/demangle.cpp
+++ b/pxr/base/arch/demangle.cpp
@@ -36,6 +36,7 @@
#if (ARCH_COMPILER_GCC_MAJOR == 3 && ARCH_COMPILER_GCC_MINOR >= 1) || \
ARCH_COMPILER_GCC_MAJOR > 3 || defined(ARCH_COMPILER_CLANG)
#define _AT_LEAST_GCC_THREE_ONE_OR_CLANG
+#include <cxxabi.h>
#endif
PXR_NAMESPACE_OPEN_SCOPE
@@ -138,7 +139,6 @@
#endif
#if defined(_AT_LEAST_GCC_THREE_ONE_OR_CLANG)
-#include <cxxabi.h>
/*
* This routine doesn't work when you get to gcc3.4.
diff --git a/pxr/base/work/singularTask.h b/pxr/base/work/singularTask.h
index 67ec0d15f..6dc3e85a0 100644
--- a/pxr/base/work/singularTask.h
+++ b/pxr/base/work/singularTask.h
@@ -120,7 +120,7 @@
// case we go again to ensure the task can do whatever it
// was awakened to do. Once we successfully take the count
// to zero, we stop.
- size_t old = count;
+ std::size_t old = count;
do { _fn(); } while (
!count.compare_exchange_strong(old, 0));
});

View File

@@ -21,7 +21,7 @@ ENDIF()
SET(_optix_SEARCH_DIRS
${OPTIX_ROOT_DIR}
"$ENV{PROGRAMDATA}/NVIDIA Corporation/OptiX SDK 7.3.0"
"$ENV{PROGRAMDATA}/NVIDIA Corporation/OptiX SDK 7.0.0"
)
FIND_PATH(OPTIX_INCLUDE_DIR

View File

@@ -168,7 +168,7 @@ def function_parm_wash_tokens(parm):
# if tokens[-1].kind == To
# remove trailing char
if tokens[-1].kind == TokenKind.PUNCTUATION:
if tokens[-1].spelling in {",", ")", ";"}:
if tokens[-1].spelling in (",", ")", ";"):
tokens.pop()
# else:
# print(tokens[-1].spelling)
@@ -179,7 +179,7 @@ def function_parm_wash_tokens(parm):
t_spelling = t.spelling
ok = True
if t_kind == TokenKind.KEYWORD:
if t_spelling in {"const", "restrict", "volatile"}:
if t_spelling in ("const", "restrict", "volatile"):
ok = False
elif t_spelling.startswith("__"):
ok = False # __restrict

View File

@@ -114,7 +114,7 @@ def is_c_header(filename: str) -> bool:
def is_c(filename: str) -> bool:
ext = splitext(filename)[1]
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".metal"})
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"})
def is_c_any(filename: str) -> bool:

View File

@@ -180,7 +180,7 @@ def create_nb_project_main():
f.write(' </logicalFolder>\n')
f.write(' </logicalFolder>\n')
# default, but this dir is in fact not in blender dir so we can ignore it
# default, but this dir is infact not in blender dir so we can ignore it
# f.write(' <sourceFolderFilter>^(nbproject)$</sourceFolderFilter>\n')
f.write(r' <sourceFolderFilter>^(nbproject|__pycache__|.*\.py|.*\.html|.*\.blend)$</sourceFolderFilter>\n')

View File

@@ -19,6 +19,9 @@ set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_EMBREE OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)

View File

@@ -61,7 +61,6 @@ set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
# platform dependent options
if(APPLE)
set(WITH_COREAUDIO ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_DEVICE_METAL ON CACHE BOOL "" FORCE)
endif()
if(NOT WIN32)
set(WITH_JACK ON CACHE BOOL "" FORCE)
@@ -82,5 +81,4 @@ if(NOT APPLE)
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_HIP_BINARIES ON CACHE BOOL "" FORCE)
endif()

View File

@@ -529,7 +529,7 @@ function(SETUP_LIBDIRS)
# NOTE: For all new libraries, use absolute library paths.
# This should eventually be phased out.
# APPLE platform uses full paths for linking libraries, and avoids link_directories.
# APPLE plaform uses full paths for linking libraries, and avoids link_directories.
if(NOT MSVC AND NOT APPLE)
link_directories(${JPEG_LIBPATH} ${PNG_LIBPATH} ${ZLIB_LIBPATH} ${FREETYPE_LIBPATH})

View File

@@ -257,6 +257,9 @@ if(WITH_BOOST)
if(WITH_INTERNATIONAL)
list(APPEND _boost_FIND_COMPONENTS locale)
endif()
if(WITH_CYCLES_NETWORK)
list(APPEND _boost_FIND_COMPONENTS serialization)
endif()
if(WITH_OPENVDB)
list(APPEND _boost_FIND_COMPONENTS iostreams)
endif()
@@ -336,7 +339,7 @@ if(WITH_LLVM)
endif()
if(WITH_CYCLES AND WITH_CYCLES_OSL)
if(WITH_CYCLES_OSL)
set(CYCLES_OSL ${LIBDIR}/osl)
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
@@ -356,7 +359,7 @@ if(WITH_CYCLES AND WITH_CYCLES_OSL)
endif()
endif()
if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
if(WITH_CYCLES_EMBREE)
find_package(Embree 3.8.0 REQUIRED)
# Increase stack size for Embree, only works for executables.
if(NOT WITH_PYTHON_MODULE)

View File

@@ -96,7 +96,7 @@ else()
# Detect SDK version to use.
if(NOT DEFINED OSX_SYSTEM)
execute_process(
COMMAND xcrun --sdk macosx --show-sdk-version
COMMAND xcrun --show-sdk-version
OUTPUT_VARIABLE OSX_SYSTEM
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()

View File

@@ -241,7 +241,7 @@ if(WITH_INPUT_NDOF)
endif()
endif()
if(WITH_CYCLES AND WITH_CYCLES_OSL)
if(WITH_CYCLES_OSL)
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
if(EXISTS ${CYCLES_OSL} AND NOT OSL_ROOT)
set(OSL_ROOT ${CYCLES_OSL})
@@ -314,7 +314,7 @@ if(WITH_BOOST)
endif()
set(Boost_USE_MULTITHREADED ON)
set(__boost_packages filesystem regex thread date_time)
if(WITH_CYCLES AND WITH_CYCLES_OSL)
if(WITH_CYCLES_OSL)
if(NOT (${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6"))
list(APPEND __boost_packages wave)
else()
@@ -323,6 +323,9 @@ if(WITH_BOOST)
if(WITH_INTERNATIONAL)
list(APPEND __boost_packages locale)
endif()
if(WITH_CYCLES_NETWORK)
list(APPEND __boost_packages serialization)
endif()
if(WITH_OPENVDB)
list(APPEND __boost_packages iostreams)
endif()
@@ -400,7 +403,7 @@ if(WITH_OPENCOLORIO)
endif()
endif()
if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
if(WITH_CYCLES_EMBREE)
find_package(Embree 3.8.0 REQUIRED)
endif()

View File

@@ -27,7 +27,7 @@ if(NOT MSVC)
endif()
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(MSVC_CLANG ON)
set(MSVC_CLANG On)
set(VC_TOOLS_DIR $ENV{VCToolsRedistDir} CACHE STRING "Location of the msvc redistributables")
set(MSVC_REDIST_DIR ${VC_TOOLS_DIR})
if(DEFINED MSVC_REDIST_DIR)
@@ -53,7 +53,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
endif()
if(WITH_WINDOWS_STRIPPED_PDB)
message(WARNING "stripped pdb not supported with clang, disabling..")
set(WITH_WINDOWS_STRIPPED_PDB OFF)
set(WITH_WINDOWS_STRIPPED_PDB Off)
endif()
endif()
@@ -159,7 +159,7 @@ endif()
if(WITH_COMPILER_ASAN AND MSVC AND NOT MSVC_CLANG)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28.29828)
#set a flag so we don't have to do this comparison all the time
SET(MSVC_ASAN ON)
SET(MSVC_ASAN On)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address")
string(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG " /INCREMENTAL:NO")
@@ -179,22 +179,22 @@ endif()
if(WITH_WINDOWS_SCCACHE AND CMAKE_VS_MSBUILD_COMMAND)
message(WARNING "Disabling sccache, sccache is not supported with msbuild")
set(WITH_WINDOWS_SCCACHE OFF)
set(WITH_WINDOWS_SCCACHE Off)
endif()
# Debug Symbol format
# sccache # MSVC_ASAN # format # why
# ON # ON # Z7 # sccache will only play nice with Z7
# ON # OFF # Z7 # sccache will only play nice with Z7
# OFF # ON # Zi # Asan will not play nice with Edit and Continue
# OFF # OFF # ZI # Neither asan nor sscache is enabled Edit and Continue is available
# On # On # Z7 # sccache will only play nice with Z7
# On # Off # Z7 # sccache will only play nice with Z7
# Off # On # Zi # Asan will not play nice with Edit and Continue
# Off # Off # ZI # Neither asan nor sscache is enabled Edit and Continue is available
# Release Symbol format
# sccache # MSVC_ASAN # format # why
# ON # ON # Z7 # sccache will only play nice with Z7
# ON # OFF # Z7 # sccache will only play nice with Z7
# OFF # ON # Zi # Asan will not play nice with Edit and Continue
# OFF # OFF # Zi # Edit and Continue disables some optimizations
# On # On # Z7 # sccache will only play nice with Z7
# On # Off # Z7 # sccache will only play nice with Z7
# Off # On # Zi # Asan will not play nice with Edit and Continue
# Off # Off # Zi # Edit and Continue disables some optimizations
if(WITH_WINDOWS_SCCACHE)
@@ -288,7 +288,7 @@ if(CMAKE_GENERATOR MATCHES "^Visual Studio.+" AND # Only supported in the VS IDE
"EnableMicrosoftCodeAnalysis=false"
"EnableClangTidyCodeAnalysis=true"
)
set(VS_CLANG_TIDY ON)
set(VS_CLANG_TIDY On)
endif()
# Mark libdir as system headers with a lower warn level, to resolve some warnings
@@ -469,7 +469,7 @@ if(WITH_PYTHON)
set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/include)
set(PYTHON_NUMPY_INCLUDE_DIRS ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/lib/site-packages/numpy/core/include)
set(NUMPY_FOUND ON)
set(NUMPY_FOUND On)
unset(_PYTHON_VERSION_NO_DOTS)
# uncached vars
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
@@ -477,7 +477,7 @@ if(WITH_PYTHON)
endif()
if(WITH_BOOST)
if(WITH_CYCLES AND WITH_CYCLES_OSL)
if(WITH_CYCLES_OSL)
set(boost_extra_libs wave)
endif()
if(WITH_INTERNATIONAL)
@@ -520,7 +520,7 @@ if(WITH_BOOST)
debug ${BOOST_LIBPATH}/libboost_thread-${BOOST_DEBUG_POSTFIX}
debug ${BOOST_LIBPATH}/libboost_chrono-${BOOST_DEBUG_POSTFIX}
)
if(WITH_CYCLES AND WITH_CYCLES_OSL)
if(WITH_CYCLES_OSL)
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
optimized ${BOOST_LIBPATH}/libboost_wave-${BOOST_POSTFIX}
debug ${BOOST_LIBPATH}/libboost_wave-${BOOST_DEBUG_POSTFIX})
@@ -708,7 +708,7 @@ if(WITH_CODEC_SNDFILE)
set(LIBSNDFILE_LIBRARIES ${LIBSNDFILE_LIBPATH}/libsndfile-1.lib)
endif()
if(WITH_CYCLES AND WITH_CYCLES_OSL)
if(WITH_CYCLES_OSL)
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
set(OSL_SHADER_DIR ${CYCLES_OSL}/shaders)
# Shaders have moved around a bit between OSL versions, check multiple locations
@@ -741,7 +741,7 @@ if(WITH_CYCLES AND WITH_CYCLES_OSL)
endif()
endif()
if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
if(WITH_CYCLES_EMBREE)
windows_find_package(Embree)
if(NOT EMBREE_FOUND)
set(EMBREE_INCLUDE_DIRS ${LIBDIR}/embree/include)
@@ -853,18 +853,18 @@ if(WITH_GMP)
set(GMP_INCLUDE_DIRS ${LIBDIR}/gmp/include)
set(GMP_LIBRARIES ${LIBDIR}/gmp/lib/libgmp-10.lib optimized ${LIBDIR}/gmp/lib/libgmpxx.lib debug ${LIBDIR}/gmp/lib/libgmpxx_d.lib)
set(GMP_ROOT_DIR ${LIBDIR}/gmp)
set(GMP_FOUND ON)
set(GMP_FOUND On)
endif()
if(WITH_POTRACE)
set(POTRACE_INCLUDE_DIRS ${LIBDIR}/potrace/include)
set(POTRACE_LIBRARIES ${LIBDIR}/potrace/lib/potrace.lib)
set(POTRACE_FOUND ON)
set(POTRACE_FOUND On)
endif()
if(WITH_HARU)
if(EXISTS ${LIBDIR}/haru)
set(HARU_FOUND ON)
set(HARU_FOUND On)
set(HARU_ROOT_DIR ${LIBDIR}/haru)
set(HARU_INCLUDE_DIRS ${HARU_ROOT_DIR}/include)
set(HARU_LIBRARIES ${HARU_ROOT_DIR}/lib/libhpdfs.lib)

View File

@@ -27,7 +27,7 @@ if(WITH_WINDOWS_BUNDLE_CRT)
# Install the CRT to the blender.crt Sub folder.
install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ./blender.crt COMPONENT Libraries)
# Generating the manifest is a relatively expensive operation since
# Generating the manifest is a relativly expensive operation since
# it is collecting an sha1 hash for every file required. so only do
# this work when the libs have either changed or the manifest does
# not exist yet.

View File

@@ -6,87 +6,91 @@
* as part of the normal development process.
*/
/* TODO: other modules.
* - `libmv`
* - `cycles`
* - `opencolorio`
* - `opensubdiv`
* - `openvdb`
* - `quadriflow`
/** \defgroup MEM Guarded memory (de)allocation
* \ingroup intern
*/
/** \defgroup intern_atomic Atomic Operations
* \ingroup intern */
/** \defgroup clog C-Logging (CLOG)
* \ingroup intern
*/
/** \defgroup intern_clog C-Logging (CLOG)
* \ingroup intern */
/** \defgroup ctr container
* \ingroup intern
*/
/** \defgroup intern_eigen Eigen
* \ingroup intern */
/** \defgroup iksolver iksolver
* \ingroup intern
*/
/** \defgroup intern_glew-mx GLEW with Multiple Rendering Context's
* \ingroup intern */
/** \defgroup itasc itasc
* \ingroup intern
*/
/** \defgroup intern_iksolver Inverse Kinematics (Solver)
* \ingroup intern */
/** \defgroup memutil memutil
* \ingroup intern
*/
/** \defgroup intern_itasc Inverse Kinematics (ITASC)
* \ingroup intern */
/** \defgroup mikktspace mikktspace
* \ingroup intern
*/
/** \defgroup intern_libc_compat libc Compatibility For Linux
* \ingroup intern */
/** \defgroup moto moto
* \ingroup intern
*/
/** \defgroup intern_locale Locale
* \ingroup intern */
/** \defgroup eigen eigen
* \ingroup intern
*/
/** \defgroup intern_mantaflow Manta-Flow Fluid Simulation
* \ingroup intern */
/** \defgroup smoke smoke
* \ingroup intern
*/
/** \defgroup intern_mem Guarded Memory (de)allocation
* \ingroup intern */
/** \defgroup intern_memutil Memory Utilities (memutil)
* \ingroup intern */
/** \defgroup intern_mikktspace MikktSpace
* \ingroup intern */
/** \defgroup intern_rigidbody Rigid-Body C-API
* \ingroup intern */
/** \defgroup intern_sky_model Sky Model
* \ingroup intern */
/** \defgroup intern_utf_conv UTF-8/16 Conversion (utfconv)
* \ingroup intern */
/** \defgroup string string
* \ingroup intern
*/
/** \defgroup audaspace Audaspace
* \ingroup intern undoc
* \todo add to doxygen */
* \todo add to doxygen
*/
/** \defgroup audcoreaudio Audaspace CoreAudio
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audfx Audaspace FX
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audopenal Audaspace OpenAL
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audpulseaudio Audaspace PulseAudio
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audwasapi Audaspace WASAPI
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audpython Audaspace Python
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audsdl Audaspace SDL
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audsrc Audaspace SRC
* \ingroup audaspace */
*
* \ingroup audaspace
*/
/** \defgroup audffmpeg Audaspace FFMpeg
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audfftw Audaspace FFTW
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audjack Audaspace Jack
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup audsndfile Audaspace sndfile
* \ingroup audaspace */
* \ingroup audaspace
*/
/** \defgroup GHOST GHOST API
* \ingroup intern GUI

View File

@@ -5,8 +5,7 @@
/** \defgroup bmesh BMesh
* \ingroup blender
*/
/** \defgroup compositor Compositing
* \ingroup blender */
/** \defgroup compositor Compositing */
/** \defgroup python Python
* \ingroup blender
@@ -79,8 +78,7 @@
* \ingroup blender
*/
/** \defgroup data DNA, RNA and .blend access
* \ingroup blender */
/** \defgroup data DNA, RNA and .blend access*/
/** \defgroup gpu GPU
* \ingroup blender
@@ -103,12 +101,11 @@
* merged in docs.
*/
/**
* \defgroup gui GUI
* \ingroup blender */
/** \defgroup gui GUI */
/** \defgroup wm Window Manager
* \ingroup gui */
* \ingroup blender gui
*/
/* ================================ */
@@ -282,8 +279,7 @@
* \ingroup gui
*/
/** \defgroup externformats External Formats
* \ingroup blender */
/** \defgroup externformats External Formats */
/** \defgroup collada COLLADA
* \ingroup externformats
@@ -312,7 +308,4 @@
/* ================================ */
/** \defgroup undoc Undocumented
*
* \brief Modules and libraries that are still undocumented,
* or lacking proper integration into the doxygen system, are marked in this group.
*/
* \brief Modules and libraries that are still undocumented, or lacking proper integration into the doxygen system, are marked in this group. */

View File

@@ -61,7 +61,7 @@ def blender_extract_info(blender_bin: str) -> Dict[str, str]:
stdout=subprocess.PIPE,
).stdout.decode(encoding="utf-8")
blender_version_output = subprocess.run(
blender_version_ouput = subprocess.run(
[blender_bin, "--version"],
env=blender_env,
check=True,
@@ -73,7 +73,7 @@ def blender_extract_info(blender_bin: str) -> Dict[str, str]:
# check for each lines prefix to ensure these aren't included.
blender_version = ""
blender_date = ""
for l in blender_version_output.split("\n"):
for l in blender_version_ouput.split("\n"):
if l.startswith("Blender "):
# Remove 'Blender' prefix.
blender_version = l.split(" ", 1)[1].strip()

View File

@@ -11,7 +11,7 @@ import queue
execution_queue = queue.Queue()
# This function can safely be called in another thread.
# This function can savely be called in another thread.
# The function will be executed when the timer runs the next time.
def run_in_main_thread(function):
execution_queue.put(function)

View File

@@ -42,13 +42,8 @@ class SimpleMouseOperator(bpy.types.Operator):
self.y = event.mouse_y
return self.execute(context)
# Only needed if you want to add into a dynamic menu
def menu_func(self, context):
self.layout.operator(SimpleMouseOperator.bl_idname, text="Simple Mouse Operator")
# Register and add to the view menu (required to also use F3 search "Simple Mouse Operator" for quick access)
bpy.utils.register_class(SimpleMouseOperator)
bpy.types.VIEW3D_MT_view.append(menu_func)
# Test call to the newly defined operator.
# Here we call the operator and invoke it, meaning that the settings are taken

View File

@@ -43,7 +43,7 @@ def menu_func(self, context):
self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")
# Register and add to the file selector (required to also use F3 search "Text Export Operator" for quick access)
# Register and add to the file selector
bpy.utils.register_class(ExportSomeData)
bpy.types.TOPBAR_MT_file_export.append(menu_func)

View File

@@ -27,14 +27,8 @@ class DialogOperator(bpy.types.Operator):
wm = context.window_manager
return wm.invoke_props_dialog(self)
# Only needed if you want to add into a dynamic menu
def menu_func(self, context):
self.layout.operator(DialogOperator.bl_idname, text="Dialog Operator")
# Register and add to the object menu (required to also use F3 search "Dialog Operator" for quick access)
bpy.utils.register_class(DialogOperator)
bpy.types.VIEW3D_MT_object.append(menu_func)
# Test call.
bpy.ops.object.dialog_operator('INVOKE_DEFAULT')

View File

@@ -41,13 +41,8 @@ class CustomDrawOperator(bpy.types.Operator):
col.prop(self, "my_string")
# Only needed if you want to add into a dynamic menu
def menu_func(self, context):
self.layout.operator(CustomDrawOperator.bl_idname, text="Custom Draw Operator")
# Register and add to the object menu (required to also use F3 search "Custom Draw Operator" for quick access)
bpy.utils.register_class(CustomDrawOperator)
bpy.types.VIEW3D_MT_object.append(menu_func)
# test call
bpy.ops.object.custom_draw('INVOKE_DEFAULT')

View File

@@ -55,13 +55,8 @@ class ModalOperator(bpy.types.Operator):
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
# Only needed if you want to add into a dynamic menu
def menu_func(self, context):
self.layout.operator(ModalOperator.bl_idname, text="Modal Operator")
# Register and add to the object menu (required to also use F3 search "Modal Operator" for quick access)
bpy.utils.register_class(ModalOperator)
bpy.types.VIEW3D_MT_object.append(menu_func)
# test call
bpy.ops.object.modal_operator('INVOKE_DEFAULT')

View File

@@ -31,13 +31,8 @@ class SearchEnumOperator(bpy.types.Operator):
context.window_manager.invoke_search_popup(self)
return {'RUNNING_MODAL'}
# Only needed if you want to add into a dynamic menu
def menu_func(self, context):
self.layout.operator(SearchEnumOperator.bl_idname, text="Search Enum Operator")
# Register and add to the object menu (required to also use F3 search "Search Enum Operator" for quick access)
bpy.utils.register_class(SearchEnumOperator)
bpy.types.VIEW3D_MT_object.append(menu_func)
# test call
bpy.ops.object.search_enum_operator('INVOKE_DEFAULT')

View File

@@ -22,13 +22,8 @@ class HelloWorldOperator(bpy.types.Operator):
print("Hello World")
return {'FINISHED'}
# Only needed if you want to add into a dynamic menu
def menu_func(self, context):
self.layout.operator(HelloWorldOperator.bl_idname, text="Hello World Operator")
# Register and add to the view menu (required to also use F3 search "Hello World Operator" for quick access)
bpy.utils.register_class(HelloWorldOperator)
bpy.types.VIEW3D_MT_view.append(menu_func)
# test call to the newly defined operator
bpy.ops.wm.hello_world()

View File

@@ -106,6 +106,24 @@ including advanced features.
floating-point values. These values are interpreted as a plane equation.
.. function:: glColor (red, green, blue, alpha):
B{glColor3b, glColor3d, glColor3f, glColor3i, glColor3s, glColor3ub, glColor3ui, glColor3us,
glColor4b, glColor4d, glColor4f, glColor4i, glColor4s, glColor4ub, glColor4ui, glColor4us,
glColor3bv, glColor3dv, glColor3fv, glColor3iv, glColor3sv, glColor3ubv, glColor3uiv,
glColor3usv, glColor4bv, glColor4dv, glColor4fv, glColor4iv, glColor4sv, glColor4ubv,
glColor4uiv, glColor4usv}
Set a new color.
.. seealso:: `OpenGL Docs <https://khronos.org/registry/OpenGL-Refpages/gl4/html/glColor.xhtml>`__
:type red, green, blue, alpha: Depends on function prototype.
:arg red, green, blue: Specify new red, green, and blue values for the current color.
:arg alpha: Specifies a new alpha value for the current color. Included only in the
four-argument glColor4 commands. (With '4' colors only)
.. function:: glColorMask(red, green, blue, alpha):
Enable and disable writing of frame buffer color components

View File

@@ -728,7 +728,7 @@ Abusing RNA property callbacks
------------------------------
Python-defined RNA properties can have custom callbacks. Trying to perform complex operations
from there, like calling an operator, may work, but is not officially recommended nor supported.
from there, like calling an operator, may work, but is not officialy recommended nor supported.
Main reason is that those callback should be very fast, but additionally, it may for example
create issues with undo/redo system (most operators store an history step, and editing an RNA

View File

@@ -1103,7 +1103,6 @@ context_type_map = {
"selectable_objects": ("Object", True),
"selected_asset_files": ("FileSelectEntry", True),
"selected_bones": ("EditBone", True),
"selected_editable_actions": ("Action", True),
"selected_editable_bones": ("EditBone", True),
"selected_editable_fcurves": ("FCurve", True),
"selected_editable_keyframes": ("Keyframe", True),
@@ -1119,13 +1118,12 @@ context_type_map = {
"selected_pose_bones": ("PoseBone", True),
"selected_pose_bones_from_active_object": ("PoseBone", True),
"selected_sequences": ("Sequence", True),
"selected_visible_actions": ("Action", True),
"selected_visible_fcurves": ("FCurve", True),
"sequences": ("Sequence", True),
"soft_body": ("SoftBodyModifier", False),
"speaker": ("Speaker", False),
"texture": ("Texture", False),
"texture_slot": ("TextureSlot", False),
"texture_slot": ("MaterialTextureSlot", False),
"texture_user": ("ID", False),
"texture_user_property": ("Property", False),
"ui_list": ("UIList", False),
@@ -2256,7 +2254,7 @@ def main():
# First monkey patch to load in fake members.
setup_monkey_patch()
# Perform changes to Blender itself.
# Perform changes to Blender it's self.
setup_data = setup_blender()
# eventually, create the dirs

12
extern/hipew/README vendored
View File

@@ -1,12 +0,0 @@
The HIP Extension Wrangler Library (HIPEW) is a cross-platform open-source
C/C++ library to dynamically load the HIP library.
HIP (Heterogeneous-Compute Interface for Portability) is an API for C++
programming on AMD GPUs.
It is maintained as part of the Blender project, but included in extern/
for consistency with CUEW and CLEW libraries.
LICENSE
HIPEW is released under the Apache 2.0 license.

View File

@@ -1,5 +0,0 @@
Project: Blender
URL: https://git.blender.org/blender.git
License: Apache 2.0
Upstream version: N/A
Local modifications: None

View File

@@ -804,29 +804,31 @@ typedef enum hipDeviceP2PAttr {
} hipDeviceP2PAttr;
typedef struct HIP_MEMCPY3D {
unsigned int srcXInBytes;
unsigned int srcY;
unsigned int srcZ;
unsigned int srcLOD;
size_t srcXInBytes;
size_t srcY;
size_t srcZ;
size_t srcLOD;
hipMemoryType srcMemoryType;
const void* srcHost;
hipDeviceptr_t srcDevice;
hArray srcArray;
unsigned int srcPitch;
unsigned int srcHeight;
unsigned int dstXInBytes;
unsigned int dstY;
unsigned int dstZ;
unsigned int dstLOD;
hArray * srcArray;
void* reserved0;
size_t srcPitch;
size_t srcHeight;
size_t dstXInBytes;
size_t dstY;
size_t dstZ;
size_t dstLOD;
hipMemoryType dstMemoryType;
void* dstHost;
hipDeviceptr_t dstDevice;
hArray dstArray;
unsigned int dstPitch;
unsigned int dstHeight;
unsigned int WidthInBytes;
unsigned int Height;
unsigned int Depth;
hArray * dstArray;
void* reserved1;
size_t dstPitch;
size_t dstHeight;
size_t WidthInBytes;
size_t Height;
size_t Depth;
} HIP_MEMCPY3D;
typedef struct HIP_MEMCPY3D_PEER_st {
@@ -877,7 +879,7 @@ typedef struct HIP_RESOURCE_DESC_st {
hipResourceType resType;
union {
struct {
hArray h_Array;
hArray * h_Array;
} array;
struct {
hipMipmappedArray_t hMipmappedArray;
@@ -1072,10 +1074,9 @@ typedef enum hiprtcResult {
typedef hipError_t HIPAPI thipGetErrorName(hipError_t error, const char** pStr);
typedef hipError_t HIPAPI thipInit(unsigned int Flags);
typedef hipError_t HIPAPI thipDriverGetVersion(int* driverVersion);
typedef hipError_t HIPAPI thipGetDevice(int* device);
typedef hipError_t HIPAPI thipGetDevice(hipDevice_t* device, int ordinal);
typedef hipError_t HIPAPI thipGetDeviceCount(int* count);
typedef hipError_t HIPAPI thipGetDeviceProperties(hipDeviceProp_t* props, int deviceId);
typedef hipError_t HIPAPI thipDeviceGet(hipDevice_t* device, int ordinal);
typedef hipError_t HIPAPI thipDeviceGetName(char* name, int len, hipDevice_t dev);
typedef hipError_t HIPAPI thipDeviceGetAttribute(int* pi, hipDeviceAttribute_t attrib, hipDevice_t dev);
typedef hipError_t HIPAPI thipDeviceComputeCapability(int* major, int* minor, hipDevice_t dev);
@@ -1208,7 +1209,6 @@ extern thipDriverGetVersion *hipDriverGetVersion;
extern thipGetDevice *hipGetDevice;
extern thipGetDeviceCount *hipGetDeviceCount;
extern thipGetDeviceProperties *hipGetDeviceProperties;
extern thipDeviceGet* hipDeviceGet;
extern thipDeviceGetName *hipDeviceGetName;
extern thipDeviceGetAttribute *hipDeviceGetAttribute;
extern thipDeviceComputeCapability *hipDeviceComputeCapability;
@@ -1333,7 +1333,6 @@ enum {
HIPEW_SUCCESS = 0,
HIPEW_ERROR_OPEN_FAILED = -1,
HIPEW_ERROR_ATEXIT_FAILED = -2,
HIPEW_ERROR_OLD_DRIVER = -3,
};
enum {

View File

@@ -71,7 +71,6 @@ thipDriverGetVersion *hipDriverGetVersion;
thipGetDevice *hipGetDevice;
thipGetDeviceCount *hipGetDeviceCount;
thipGetDeviceProperties *hipGetDeviceProperties;
thipDeviceGet* hipDeviceGet;
thipDeviceGetName *hipDeviceGetName;
thipDeviceGetAttribute *hipDeviceGetAttribute;
thipDeviceComputeCapability *hipDeviceComputeCapability;
@@ -214,36 +213,6 @@ static void hipewHipExit(void) {
}
}
#ifdef _WIN32
static int hipewHasOldDriver(const char *hip_path) {
DWORD verHandle = 0;
DWORD verSize = GetFileVersionInfoSize(hip_path, &verHandle);
int old_driver = 0;
if (verSize != 0) {
LPSTR verData = (LPSTR)malloc(verSize);
if (GetFileVersionInfo(hip_path, verHandle, verSize, verData)) {
LPBYTE lpBuffer = NULL;
UINT size = 0;
if (VerQueryValue(verData, "\\", (VOID FAR * FAR *)&lpBuffer, &size)) {
if (size) {
VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *)lpBuffer;
/* Magic value from
* https://docs.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo */
if (verInfo->dwSignature == 0xfeef04bd) {
unsigned int fileVersionLS0 = (verInfo->dwFileVersionLS >> 16) & 0xffff;
unsigned int fileversionLS1 = (verInfo->dwFileVersionLS >> 0) & 0xffff;
/* Corresponds to versions older than AMD Radeon Pro 21.Q4. */
old_driver = ((fileVersionLS0 < 3354) || (fileVersionLS0 == 3354 && fileversionLS1 < 13));
}
}
}
}
free(verData);
}
return old_driver;
}
#endif
static int hipewHipInit(void) {
/* Library paths. */
#ifdef _WIN32
@@ -271,14 +240,6 @@ static int hipewHipInit(void) {
return result;
}
#ifdef _WIN32
/* Test for driver version. */
if(hipewHasOldDriver(hip_paths[0])) {
result = HIPEW_ERROR_OLD_DRIVER;
return result;
}
#endif
/* Load library. */
hip_lib = dynamic_library_open_find(hip_paths);
@@ -294,7 +255,6 @@ static int hipewHipInit(void) {
HIP_LIBRARY_FIND_CHECKED(hipGetDevice);
HIP_LIBRARY_FIND_CHECKED(hipGetDeviceCount);
HIP_LIBRARY_FIND_CHECKED(hipGetDeviceProperties);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGet);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetName);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetAttribute);
HIP_LIBRARY_FIND_CHECKED(hipDeviceComputeCapability);

View File

@@ -1,7 +1,7 @@
Project: NanoSVG
URL: https://github.com/memononen/nanosvg
License: zlib
Upstream version: 3cdd4a9d7886
Upstream version:
Local modifications: Added some functionality to manage grease pencil layers
Added a fix to SVG import arc and float errors (https://developer.blender.org/rB11dc674c78b49fc4e0b7c134c375b6c8b8eacbcc)

View File

@@ -25,6 +25,7 @@ add_subdirectory(ghost)
add_subdirectory(guardedalloc)
add_subdirectory(libmv)
add_subdirectory(memutil)
add_subdirectory(numaapi)
add_subdirectory(opencolorio)
add_subdirectory(opensubdiv)
add_subdirectory(mikktspace)

View File

@@ -45,7 +45,7 @@
*/
/** \file
* \ingroup intern_atomic
* \ingroup Atomic
*
* \brief Provides wrapper around system-specific atomic primitives,
* and some extensions (faked-atomic operations over float numbers).

View File

@@ -44,10 +44,6 @@
* The Original Code is: adapted from jemalloc.
*/
/** \file
* \ingroup intern_atomic
*/
#ifndef __ATOMIC_OPS_EXT_H__
#define __ATOMIC_OPS_EXT_H__

View File

@@ -5,7 +5,7 @@
* All rights reserved.
* Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
* Copyright (C) 2009-2013 Facebook, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice(s),
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
@@ -26,10 +26,6 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \file
* \ingroup intern_atomic
*/
#ifndef __ATOMIC_OPS_MSVC_H__
#define __ATOMIC_OPS_MSVC_H__

View File

@@ -44,10 +44,6 @@
* The Original Code is: adapted from jemalloc.
*/
/** \file
* \ingroup intern_atomic
*/
#ifndef __ATOMIC_OPS_UNIX_H__
#define __ATOMIC_OPS_UNIX_H__

View File

@@ -44,10 +44,6 @@
* The Original Code is: adapted from jemalloc.
*/
/** \file
* \ingroup intern_atomic
*/
#ifndef __ATOMIC_OPS_UTILS_H__
#define __ATOMIC_OPS_UTILS_H__

View File

@@ -14,8 +14,11 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __CLG_LOG_H__
#define __CLG_LOG_H__
/** \file
* \ingroup intern_clog
* \ingroup clog
*
* C Logging Library (clog)
* ========================
@@ -65,9 +68,6 @@
* - 4+: May be used for more details than 3, should be avoided but not prevented.
*/
#ifndef __CLG_LOG_H__
#define __CLG_LOG_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

View File

@@ -15,7 +15,7 @@
*/
/** \file
* \ingroup intern_clog
* \ingroup clog
*/
#include <assert.h>
@@ -388,7 +388,7 @@ static void clg_ctx_fatal_action(CLogContext *ctx)
static void clg_ctx_backtrace(CLogContext *ctx)
{
/* NOTE: we avoid writing to 'FILE', for back-trace we make an exception,
/* Note: we avoid writing to 'FILE', for back-trace we make an exception,
* if necessary we could have a version of the callback that writes to file
* descriptor all at once. */
ctx->callbacks.backtrace_fn(ctx->output_file);

View File

@@ -226,9 +226,6 @@ add_definitions(
-DCCL_NAMESPACE_END=}
)
if(WITH_CYCLES_DEBUG)
add_definitions(-DWITH_CYCLES_DEBUG)
endif()
if(WITH_CYCLES_STANDALONE_GUI)
add_definitions(-DWITH_CYCLES_STANDALONE_GUI)
endif()
@@ -337,7 +334,7 @@ else()
endif()
# Warnings
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang")
if(CMAKE_COMPILER_IS_GNUCXX)
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_double_promotion "-Werror=double-promotion")
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_no_error_unused_macros "-Wno-error=unused-macros")

View File

@@ -82,7 +82,7 @@ static void session_print_status()
string status, substatus;
/* get status */
double progress = options.session->progress.get_progress();
float progress = options.session->progress.get_progress();
options.session->progress.get_status(status, substatus);
if (substatus != "")
@@ -183,7 +183,7 @@ static void display_info(Progress &progress)
progress.get_time(total_time, sample_time);
progress.get_status(status, substatus);
double progress_val = progress.get_progress();
float progress_val = progress.get_progress();
if (substatus != "")
status += ": " + substatus;

View File

@@ -40,7 +40,6 @@ set(SRC
object_cull.cpp
output_driver.cpp
particles.cpp
pointcloud.cpp
curves.cpp
logging.cpp
python.cpp
@@ -88,7 +87,6 @@ endif()
set(ADDON_FILES
addon/__init__.py
addon/camera.py
addon/engine.py
addon/operators.py
addon/osl.py
@@ -103,11 +101,6 @@ add_definitions(${GL_DEFINITIONS})
if(WITH_CYCLES_DEVICE_HIP)
add_definitions(-DWITH_HIP)
endif()
if(WITH_CYCLES_DEVICE_METAL)
add_definitions(-DWITH_METAL)
endif()
if(WITH_MOD_FLUID)
add_definitions(-DWITH_FLUID)
endif()
@@ -145,6 +138,11 @@ endif()
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# avoid link failure with clang 3.4 debug
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4')
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -gline-tables-only")
endif()
add_dependencies(bf_intern_cycles bf_rna)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${ADDON_FILES}" ${CYCLES_INSTALL_PATH})

View File

@@ -1,84 +0,0 @@
#
# Copyright 2011-2021 Blender Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# <pep8 compliant>
# Fit to match default projective camera with focal_length 50 and sensor_width 36.
default_fisheye_polynomial = [-1.1735143712967577e-05,
-0.019988736953434998,
-3.3525322965709175e-06,
3.099275275886036e-06,
-2.6064646454854524e-08]
# Utilities to generate lens polynomials to match built-in camera types, only here
# for reference at the moment, not used by the code.
def create_grid(sensor_height, sensor_width):
import numpy as np
if sensor_height is None:
sensor_height = sensor_width / (16 / 9) # Default aspect ration 16:9
uu, vv = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))
uu = (uu - 0.5) * sensor_width
vv = (vv - 0.5) * sensor_height
rr = np.sqrt(uu ** 2 + vv ** 2)
return rr
def fisheye_lens_polynomial_from_projective(focal_length=50, sensor_width=36, sensor_height=None):
import numpy as np
rr = create_grid(sensor_height, sensor_width)
polynomial = np.polyfit(rr.flat, (-np.arctan(rr / focal_length)).flat, 4)
return list(reversed(polynomial))
def fisheye_lens_polynomial_from_projective_fov(fov, sensor_width=36, sensor_height=None):
import numpy as np
f = sensor_width / 2 / np.tan(fov / 2)
return fisheye_lens_polynomial_from_projective(f, sensor_width, sensor_height)
def fisheye_lens_polynomial_from_equisolid(lens=10.5, sensor_width=36, sensor_height=None):
import numpy as np
rr = create_grid(sensor_height, sensor_width)
x = rr.reshape(-1)
x = np.stack([x**i for i in [1, 2, 3, 4]])
y = (-2 * np.arcsin(rr / (2 * lens))).reshape(-1)
polynomial = np.linalg.lstsq(x.T, y.T, rcond=None)[0]
return [0] + list(polynomial)
def fisheye_lens_polynomial_from_equidistant(fov=180, sensor_width=36, sensor_height=None):
import numpy as np
return [0, -np.radians(fov) / sensor_width, 0, 0, 0]
def fisheye_lens_polynomial_from_distorted_projective_polynomial(k1, k2, k3, focal_length=50, sensor_width=36, sensor_height=None):
import numpy as np
rr = create_grid(sensor_height, sensor_width)
r2 = (rr / focal_length) ** 2
r4 = r2 * r2
r6 = r4 * r2
r_coeff = 1 + k1 * r2 + k2 * r4 + k3 * r6
polynomial = np.polyfit(rr.flat, (-np.arctan(rr / focal_length * r_coeff)).flat, 4)
return list(reversed(polynomial))
def fisheye_lens_polynomial_from_distorted_projective_divisions(k1, k2, focal_length=50, sensor_width=36, sensor_height=None):
import numpy as np
rr = create_grid(sensor_height, sensor_width)
r2 = (rr / focal_length) ** 2
r4 = r2 * r2
r_coeff = 1 + k1 * r2 + k2 * r4
polynomial = np.polyfit(rr.flat, (-np.arctan(rr / focal_length / r_coeff)).flat, 4)
return list(reversed(polynomial))

View File

@@ -28,7 +28,7 @@ def _configure_argument_parser():
action='store_true')
parser.add_argument("--cycles-device",
help="Set the device to use for Cycles, overriding user preferences and the scene setting."
"Valid options are 'CPU', 'CUDA', 'OPTIX', 'HIP' or 'METAL'."
"Valid options are 'CPU', 'CUDA', 'OPTIX', or 'HIP'"
"Additionally, you can append '+CPU' to any GPU type for hybrid rendering.",
default=None)
return parser
@@ -60,8 +60,9 @@ def init():
path = os.path.dirname(__file__)
user_path = os.path.dirname(os.path.abspath(bpy.utils.user_resource('CONFIG', path='')))
temp_path = bpy.app.tempdir
_cycles.init(path, user_path, bpy.app.background)
_cycles.init(path, user_path, temp_path, bpy.app.background)
_parse_command_line()
@@ -232,7 +233,6 @@ def list_render_passes(scene, srl):
if crl.denoising_store_passes:
yield ("Denoising Normal", "XYZ", 'VECTOR')
yield ("Denoising Albedo", "RGB", 'COLOR')
yield ("Denoising Depth", "Z", 'VALUE')
# Custom AOV passes.
for aov in srl.aovs:

View File

@@ -40,10 +40,10 @@ class AddPresetIntegrator(AddPresetBase, Operator):
"cycles.transparent_max_bounces",
"cycles.caustics_reflective",
"cycles.caustics_refractive",
"cycles.blur_glossy",
"cycles.use_fast_gi",
"cycles.ao_bounces",
"cycles.ao_bounces_render",
"cycles.blur_glossy"
"cycles.use_fast_gi"
"cycles.ao_bounces"
"cycles.ao_bounces_render"
]
preset_subdir = "cycles/integrator"

View File

@@ -33,7 +33,6 @@ from math import pi
# enums
from . import engine
from . import camera
enum_devices = (
('CPU', "CPU", "Use CPU for rendering"),
@@ -73,8 +72,6 @@ enum_panorama_types = (
('FISHEYE_EQUISOLID', "Fisheye Equisolid",
"Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
('MIRRORBALL', "Mirror Ball", "Uses the mirror ball mapping"),
('FISHEYE_LENS_POLYNOMIAL', "Fisheye Lens Polynomial",
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked."),
)
enum_curve_shape = (
@@ -90,7 +87,7 @@ enum_use_layer_samples = (
enum_sampling_pattern = (
('SOBOL', "Sobol", "Use Sobol random sampling pattern", 0),
('PROGRESSIVE_MULTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern", 1),
('PROGRESSIVE_MUTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern", 1),
)
enum_volume_sampling = (
@@ -114,8 +111,7 @@ enum_device_type = (
('CPU', "CPU", "CPU", 0),
('CUDA', "CUDA", "CUDA", 1),
('OPTIX', "OptiX", "OptiX", 3),
('HIP', "HIP", "HIP", 4),
('METAL', "Metal", "Metal", 5)
("HIP", "HIP", "HIP", 4)
)
enum_texture_limit = (
@@ -222,12 +218,6 @@ enum_denoising_prefilter = (
('ACCURATE', "Accurate", "Prefilter noisy guiding passes before denoising color. Improves quality when guiding passes are noisy using extra processing time", 3),
)
enum_direct_light_sampling_type = (
('MULTIPLE_IMPORTANCE_SAMPLING', "Multiple Importance Sampling", "Multiple importance sampling is used to combine direct light contributions from next-event estimation and forward path tracing", 0),
('FORWARD_PATH_TRACING', "Forward Path Tracing", "Direct light contributions are only sampled using forward path tracing", 1),
('NEXT_EVENT_ESTIMATION', "Next-Event Estimation", "Direct light contributions are only sampled using next-event estimation", 2),
)
def update_render_passes(self, context):
scene = context.scene
view_layer = context.view_layer
@@ -335,13 +325,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=1024,
)
sample_offset: IntProperty(
name="Sample Offset",
description="Number of samples to skip when starting render",
min=0, max=(1 << 24),
default=0,
)
time_limit: FloatProperty(
name="Time Limit",
description="Limit the render time (excluding synchronization time)."
@@ -356,14 +339,14 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
name="Sampling Pattern",
description="Random sampling pattern used by the integrator. When adaptive sampling is enabled, Progressive Multi-Jitter is always used instead of Sobol",
items=enum_sampling_pattern,
default='PROGRESSIVE_MULTI_JITTER',
default='PROGRESSIVE_MUTI_JITTER',
)
scrambling_distance: FloatProperty(
name="Scrambling Distance",
default=1.0,
min=0.0, max=1.0,
description="Reduce randomization between pixels to improve GPU rendering performance, at the cost of possible rendering artifacts if set too low. Only works when not using adaptive sampling",
description="Lower values give faster rendering with GPU rendering and less noise with all devices at the cost of possible artifacts if set too low. Only works when not using adaptive sampling",
)
preview_scrambling_distance: BoolProperty(
name="Scrambling Distance viewport",
@@ -371,10 +354,10 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Uses the Scrambling Distance value for the viewport. Faster but may flicker",
)
auto_scrambling_distance: BoolProperty(
name="Automatic Scrambling Distance",
adaptive_scrambling_distance: BoolProperty(
name="Adaptive Scrambling Distance",
default=False,
description="Automatically reduce the randomization between pixels to improve GPU rendering performance, at the cost of possible rendering artifacts. Only works when not using adaptive sampling",
description="Uses a formula to adapt the scrambling distance strength based on the sample count",
)
use_layer_samples: EnumProperty(
@@ -432,13 +415,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=0,
)
direct_light_sampling_type: EnumProperty(
name="Direct Light Sampling",
description="The type of strategy used for sampling direct light contributions",
items=enum_direct_light_sampling_type,
default='MULTIPLE_IMPORTANCE_SAMPLING',
)
min_light_bounces: IntProperty(
name="Min Light Bounces",
description="Minimum number of light bounces. Setting this higher reduces noise in the first bounces, "
@@ -794,15 +770,15 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
)
use_auto_tile: BoolProperty(
name="Use Tiling",
description="Render high resolution images in tiles to reduce memory usage, using the specified tile size. Tiles are cached to disk while rendering to save memory",
name="Auto Tiles",
description="Automatically render high resolution images in tiles to reduce memory usage, using the specified tile size. Tiles are cached to disk while rendering to save memory",
default=True,
)
tile_size: IntProperty(
name="Tile Size",
default=2048,
description="",
min=8, max=8192,
min=8, max=16384,
)
# Various fine-tuning debug flags
@@ -894,32 +870,6 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
default=pi,
)
fisheye_polynomial_k0: FloatProperty(
name="Fisheye Polynomial K0",
description="Coefficient K0 of the lens polinomial",
default=camera.default_fisheye_polynomial[0], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k1: FloatProperty(
name="Fisheye Polynomial K1",
description="Coefficient K1 of the lens polinomial",
default=camera.default_fisheye_polynomial[1], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k2: FloatProperty(
name="Fisheye Polynomial K2",
description="Coefficient K2 of the lens polinomial",
default=camera.default_fisheye_polynomial[2], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k3: FloatProperty(
name="Fisheye Polynomial K3",
description="Coefficient K3 of the lens polinomial",
default=camera.default_fisheye_polynomial[3], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k4: FloatProperty(
name="Fisheye Polynomial K4",
description="Coefficient K4 of the lens polinomial",
default=camera.default_fisheye_polynomial[4], precision=6, step=0.1, subtype='ANGLE',
)
@classmethod
def register(cls):
bpy.types.Camera.cycles = PointerProperty(
@@ -1342,7 +1292,8 @@ class CyclesPreferences(bpy.types.AddonPreferences):
def get_device_types(self, context):
import _cycles
has_cuda, has_optix, has_hip, has_metal = _cycles.get_device_types()
has_cuda, has_optix, has_hip = _cycles.get_device_types()
list = [('NONE', "None", "Don't use compute device", 0)]
if has_cuda:
list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
@@ -1350,8 +1301,6 @@ class CyclesPreferences(bpy.types.AddonPreferences):
list.append(('OPTIX', "OptiX", "Use OptiX for GPU acceleration", 3))
if has_hip:
list.append(('HIP', "HIP", "Use HIP for GPU acceleration", 4))
if has_metal:
list.append(('METAL', "Metal", "Use Metal for GPU acceleration", 5))
return list
@@ -1377,7 +1326,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
def update_device_entries(self, device_list):
for device in device_list:
if not device[1] in {'CUDA', 'OPTIX', 'CPU', 'HIP', 'METAL'}:
if not device[1] in {'CUDA', 'OPTIX', 'CPU', 'HIP'}:
continue
# Try to find existing Device entry
entry = self.find_existing_device_entry(device)
@@ -1411,7 +1360,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
elif entry.type == 'CPU':
cpu_devices.append(entry)
# Extend all GPU devices with CPU.
if len(devices) and compute_device_type != 'CPU':
if compute_device_type != 'CPU':
devices.extend(cpu_devices)
return devices
@@ -1421,7 +1370,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
import _cycles
# Ensure `self.devices` is not re-allocated when the second call to
# get_devices_for_type is made, freeing items from the first list.
for device_type in ('CUDA', 'OPTIX', 'HIP', 'METAL'):
for device_type in ('CUDA', 'OPTIX', 'HIP'):
self.update_device_entries(_cycles.available_devices(device_type))
# Deprecated: use refresh_devices instead.
@@ -1429,18 +1378,12 @@ class CyclesPreferences(bpy.types.AddonPreferences):
self.refresh_devices()
return None
def get_compute_device_type(self):
if self.compute_device_type == '':
return 'NONE'
return self.compute_device_type
def get_num_gpu_devices(self):
import _cycles
compute_device_type = self.get_compute_device_type()
device_list = _cycles.available_devices(compute_device_type)
device_list = _cycles.available_devices(self.compute_device_type)
num = 0
for device in device_list:
if device[1] != compute_device_type:
if device[1] != self.compute_device_type:
continue
for dev in self.devices:
if dev.use and dev.id == device[2]:
@@ -1470,11 +1413,9 @@ class CyclesPreferences(bpy.types.AddonPreferences):
col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1')
elif device_type == 'HIP':
import sys
col.label(text="Requires discrete AMD GPU with RDNA architecture", icon='BLANK1')
col.label(text="Requires discrete AMD GPU with ??? architecture", icon='BLANK1')
if sys.platform[:3] == "win":
col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1')
elif device_type == 'METAL':
col.label(text="Requires Apple Silicon and macOS 12.0 or newer", icon='BLANK1')
col.label(text="and AMD driver version ??? or newer", icon='BLANK1')
return
for device in devices:
@@ -1484,16 +1425,15 @@ class CyclesPreferences(bpy.types.AddonPreferences):
row = layout.row()
row.prop(self, "compute_device_type", expand=True)
compute_device_type = self.get_compute_device_type()
if compute_device_type == 'NONE':
if self.compute_device_type == 'NONE':
return
row = layout.row()
devices = self.get_devices_for_type(compute_device_type)
self._draw_devices(row, compute_device_type, devices)
devices = self.get_devices_for_type(self.compute_device_type)
self._draw_devices(row, self.compute_device_type, devices)
import _cycles
has_peer_memory = 0
for device in _cycles.available_devices(compute_device_type):
for device in _cycles.available_devices(self.compute_device_type):
if device[3] and self.find_existing_device_entry(device).use:
has_peer_memory += 1
if has_peer_memory > 1:

View File

@@ -97,11 +97,6 @@ def use_cpu(context):
return (get_device_type(context) == 'NONE' or cscene.device == 'CPU')
def use_metal(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'METAL' and cscene.device == 'GPU')
def use_cuda(context):
cscene = context.scene.cycles
@@ -295,18 +290,15 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
col.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
col.prop(cscene, "sampling_pattern", text="Pattern")
col = layout.column(align=True)
col.prop(cscene, "sample_offset")
layout.separator()
heading = layout.column(align=True, heading="Scrambling Distance")
heading.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
heading.prop(cscene, "auto_scrambling_distance", text="Automatic")
sub = heading.row()
col = layout.column(align=True)
col.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
col.prop(cscene, "scrambling_distance", text="Scrambling Distance")
col.prop(cscene, "adaptive_scrambling_distance", text="Adaptive")
sub = col.row(align=True)
sub.active = not cscene.use_preview_adaptive_sampling
sub.prop(cscene, "preview_scrambling_distance", text="Viewport")
heading.prop(cscene, "scrambling_distance", text="Multiplier")
layout.separator()
@@ -1020,7 +1012,7 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
def poll(cls, context):
ob = context.object
if CyclesButtonsPanel.poll(context) and ob:
if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA', 'HAIR', 'POINTCLOUD'}:
if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA'}:
return True
if ob.instance_type == 'COLLECTION' and ob.instance_collection:
return True
@@ -1059,7 +1051,7 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
def has_geometry_visibility(ob):
return ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT', 'VOLUME', 'POINTCLOUD', 'HAIR'}) or
return ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or
(ob.instance_type == 'COLLECTION' and ob.instance_collection))
@@ -1824,38 +1816,37 @@ class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False # No animation.
scene = context.scene
cscene = scene.cycles
col = layout.column(heading="CPU")
col = layout.column()
col.label(text="CPU Flags:")
row = col.row(align=True)
row.prop(cscene, "debug_use_cpu_sse2", toggle=True)
row.prop(cscene, "debug_use_cpu_sse3", toggle=True)
row.prop(cscene, "debug_use_cpu_sse41", toggle=True)
row.prop(cscene, "debug_use_cpu_avx", toggle=True)
row.prop(cscene, "debug_use_cpu_avx2", toggle=True)
col.prop(cscene, "debug_bvh_layout", text="BVH")
col.prop(cscene, "debug_bvh_layout")
col.separator()
col = layout.column(heading="CUDA")
col = layout.column()
col.label(text="CUDA Flags:")
col.prop(cscene, "debug_use_cuda_adaptive_compile")
col = layout.column(heading="OptiX")
col.prop(cscene, "debug_use_optix_debug", text="Module Debug")
col.separator()
col.prop(cscene, "debug_bvh_type", text="Viewport BVH")
col = layout.column()
col.label(text="OptiX Flags:")
col.prop(cscene, "debug_use_optix_debug")
col.separator()
import _cycles
if _cycles.with_debug:
col.prop(cscene, "direct_light_sampling_type")
col = layout.column()
col.prop(cscene, "debug_bvh_type")
class CYCLES_RENDER_PT_simplify(CyclesButtonsPanel, Panel):

View File

@@ -86,7 +86,7 @@ def do_versions(self):
# Device might not currently be available so this can fail
try:
if system.legacy_compute_device_type == 1:
prop.compute_device_type = 'NONE' # Was OpenCL
prop.compute_device_type = 'OPENCL'
elif system.legacy_compute_device_type == 2:
prop.compute_device_type = 'CUDA'
else:
@@ -97,12 +97,6 @@ def do_versions(self):
# Init device list for UI
prop.get_devices(prop.compute_device_type)
if bpy.context.preferences.version <= (3, 0, 40):
# Disable OpenCL device
prop = bpy.context.preferences.addons[__package__].preferences
if prop.is_property_set("compute_device_type") and prop['compute_device_type'] == 4:
prop.compute_device_type = 'NONE'
# We don't modify startup file because it assumes to
# have all the default values only.
if not bpy.data.is_saved:
@@ -243,7 +237,7 @@ def do_versions(self):
cscene.use_preview_denoising = False
if not cscene.is_property_set("sampling_pattern") or \
cscene.get('sampling_pattern') >= 2:
cscene.sampling_pattern = 'PROGRESSIVE_MULTI_JITTER'
cscene.sampling_pattern = 'PROGRESSIVE_MUTI_JITTER'
# Removal of square samples.
cscene = scene.cycles

View File

@@ -69,12 +69,6 @@ struct BlenderCamera {
float pole_merge_angle_from;
float pole_merge_angle_to;
float fisheye_polynomial_k0;
float fisheye_polynomial_k1;
float fisheye_polynomial_k2;
float fisheye_polynomial_k3;
float fisheye_polynomial_k4;
enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
float sensor_width;
float sensor_height;
@@ -206,12 +200,6 @@ static void blender_camera_from_object(BlenderCamera *bcam,
bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min");
bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max");
bcam->fisheye_polynomial_k0 = RNA_float_get(&ccamera, "fisheye_polynomial_k0");
bcam->fisheye_polynomial_k1 = RNA_float_get(&ccamera, "fisheye_polynomial_k1");
bcam->fisheye_polynomial_k2 = RNA_float_get(&ccamera, "fisheye_polynomial_k2");
bcam->fisheye_polynomial_k3 = RNA_float_get(&ccamera, "fisheye_polynomial_k3");
bcam->fisheye_polynomial_k4 = RNA_float_get(&ccamera, "fisheye_polynomial_k4");
bcam->interocular_distance = b_camera.stereo().interocular_distance();
if (b_camera.stereo().convergence_mode() == BL::CameraStereoData::convergence_mode_PARALLEL) {
bcam->convergence_distance = FLT_MAX;
@@ -434,8 +422,7 @@ static void blender_camera_sync(Camera *cam,
cam->set_full_height(height);
/* panorama sensor */
if (bcam->type == CAMERA_PANORAMA && (bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID ||
bcam->panorama_type == PANORAMA_FISHEYE_LENS_POLYNOMIAL)) {
if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
float fit_xratio = (float)bcam->render_width * bcam->pixelaspect.x;
float fit_yratio = (float)bcam->render_height * bcam->pixelaspect.y;
bool horizontal_fit;
@@ -478,12 +465,6 @@ static void blender_camera_sync(Camera *cam,
cam->set_latitude_min(bcam->latitude_min);
cam->set_latitude_max(bcam->latitude_max);
cam->set_fisheye_polynomial_k0(bcam->fisheye_polynomial_k0);
cam->set_fisheye_polynomial_k1(bcam->fisheye_polynomial_k1);
cam->set_fisheye_polynomial_k2(bcam->fisheye_polynomial_k2);
cam->set_fisheye_polynomial_k3(bcam->fisheye_polynomial_k3);
cam->set_fisheye_polynomial_k4(bcam->fisheye_polynomial_k4);
cam->set_longitude_min(bcam->longitude_min);
cam->set_longitude_max(bcam->longitude_max);
@@ -658,7 +639,7 @@ void BlenderSync::sync_camera_motion(
/* TODO(sergey): De-duplicate calculation with camera sync. */
float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
if (fov != cam->get_fov()) {
VLOG(3) << "Camera " << b_ob.name() << " FOV change detected.";
VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
if (motion_time == 0.0f) {
cam->set_fov(fov);
}

View File

@@ -199,7 +199,7 @@ static bool ObtainCacheParticleUV(Hair *hair,
b_mesh->uv_layers.begin(l);
float2 uv = zero_float2();
if (!b_mesh->uv_layers.empty())
if (b_mesh->uv_layers.length())
b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
CData->curve_uv.push_back_slow(uv);
@@ -261,7 +261,7 @@ static bool ObtainCacheParticleVcol(Hair *hair,
b_mesh->vertex_colors.begin(l);
float4 vcol = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
if (!b_mesh->vertex_colors.empty())
if (b_mesh->vertex_colors.length())
b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
CData->curve_vcol.push_back_slow(vcol);
@@ -304,6 +304,10 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
}
}
if (num_curves > 0) {
VLOG(1) << "Exporting curve segments for mesh " << hair->name;
}
hair->reserve_curves(hair->num_curves() + num_curves, hair->get_curve_keys().size() + num_keys);
num_keys = 0;
@@ -352,7 +356,7 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
/* check allocation */
if ((hair->get_curve_keys().size() != num_keys) || (hair->num_curves() != num_curves)) {
VLOG(1) << "Hair memory allocation failed, clearing data.";
VLOG(1) << "Allocation failed, clearing data";
hair->clear(true);
}
}
@@ -408,11 +412,16 @@ static void export_hair_motion_validate_attribute(Hair *hair,
if (num_motion_keys != num_keys || !have_motion) {
/* No motion or hair "topology" changed, remove attributes again. */
if (num_motion_keys != num_keys) {
VLOG(1) << "Hair topology changed, removing motion attribute.";
VLOG(1) << "Hair topology changed, removing attribute.";
}
else {
VLOG(1) << "No motion, removing attribute.";
}
hair->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
}
else if (motion_step > 0) {
VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step;
/* Motion, fill up previous steps that we might have skipped because
* they had no motion, but we need them anyway now. */
for (int step = 0; step < motion_step; step++) {
@@ -428,12 +437,16 @@ static void export_hair_motion_validate_attribute(Hair *hair,
static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int motion_step)
{
VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
<< motion_step;
/* find attribute */
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
bool new_attribute = false;
/* add new attribute if it doesn't exist already */
if (!attr_mP) {
VLOG(1) << "Creating new motion vertex position attribute";
attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
new_attribute = true;
}
@@ -669,6 +682,10 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
const int num_keys = b_hair.points.length();
const int num_curves = b_hair.curves.length();
if (num_curves > 0) {
VLOG(1) << "Exporting curve segments for hair " << hair->name;
}
hair->reserve_curves(num_curves, num_keys);
/* Export curves and points. */
@@ -726,11 +743,15 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_step)
{
VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
<< motion_step;
/* Find or add attribute. */
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
bool new_attribute = false;
if (!attr_mP) {
VLOG(1) << "Creating new motion vertex position attribute";
attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
new_attribute = true;
}
@@ -819,14 +840,11 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, H
new_hair.set_used_shaders(used_shaders);
if (view_layer.use_hair) {
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair)) {
/* Hair object. */
sync_hair(&new_hair, b_ob_info, false);
}
else
#endif
{
else {
/* Particle hair. */
bool need_undeformed = new_hair.need_attribute(scene, ATTR_STD_GENERATED);
BL::Mesh b_mesh = object_to_mesh(
@@ -873,15 +891,12 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
/* Export deformed coordinates. */
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair)) {
/* Hair object. */
sync_hair(hair, b_ob_info, true, motion_step);
return;
}
else
#endif
{
else {
/* Particle hair. */
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob_info, b_depsgraph, false, Mesh::SUBDIVISION_NONE);

View File

@@ -27,7 +27,6 @@ enum ComputeDevice {
COMPUTE_DEVICE_CUDA = 1,
COMPUTE_DEVICE_OPTIX = 3,
COMPUTE_DEVICE_HIP = 4,
COMPUTE_DEVICE_METAL = 5,
COMPUTE_DEVICE_NUM
};
@@ -86,9 +85,6 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
else if (compute_device == COMPUTE_DEVICE_HIP) {
mask |= DEVICE_MASK_HIP;
}
else if (compute_device == COMPUTE_DEVICE_METAL) {
mask |= DEVICE_MASK_METAL;
}
vector<DeviceInfo> devices = Device::available_devices(mask);
/* Match device preferences and available devices. */

View File

@@ -272,300 +272,12 @@ uint BlenderDisplaySpaceShader::get_shader_program()
return shader_program_;
}
/* --------------------------------------------------------------------
* DrawTile.
*/
/* Higher level representation of a texture from the graphics library. */
class GLTexture {
public:
/* Global counter for all allocated OpenGL textures used by instances of this class. */
static inline std::atomic<int> num_used = 0;
GLTexture() = default;
~GLTexture()
{
assert(gl_id == 0);
}
GLTexture(const GLTexture &other) = delete;
GLTexture &operator=(GLTexture &other) = delete;
GLTexture(GLTexture &&other) noexcept
: gl_id(other.gl_id), width(other.width), height(other.height)
{
other.reset();
}
GLTexture &operator=(GLTexture &&other)
{
if (this == &other) {
return *this;
}
gl_id = other.gl_id;
width = other.width;
height = other.height;
other.reset();
return *this;
}
bool gl_resources_ensure()
{
if (gl_id) {
return true;
}
/* Create texture. */
glGenTextures(1, &gl_id);
if (!gl_id) {
LOG(ERROR) << "Error creating texture.";
return false;
}
/* Configure the texture. */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gl_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/* Clamp to edge so that precision issues when zoomed out (which forces linear interpolation)
* does not cause unwanted repetition. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
++num_used;
return true;
}
void gl_resources_destroy()
{
if (!gl_id) {
return;
}
glDeleteTextures(1, &gl_id);
reset();
--num_used;
}
/* OpenGL resource IDs of the texture.
*
* NOTE: Allocated on the render engine's context. */
uint gl_id = 0;
/* Dimensions of the texture in pixels. */
int width = 0;
int height = 0;
protected:
void reset()
{
gl_id = 0;
width = 0;
height = 0;
}
};
/* Higher level representation of a Pixel Buffer Object (PBO) from the graphics library. */
class GLPixelBufferObject {
public:
/* Global counter for all allocated OpenGL PBOs used by instances of this class. */
static inline std::atomic<int> num_used = 0;
GLPixelBufferObject() = default;
~GLPixelBufferObject()
{
assert(gl_id == 0);
}
GLPixelBufferObject(const GLPixelBufferObject &other) = delete;
GLPixelBufferObject &operator=(GLPixelBufferObject &other) = delete;
GLPixelBufferObject(GLPixelBufferObject &&other) noexcept
: gl_id(other.gl_id), width(other.width), height(other.height)
{
other.reset();
}
GLPixelBufferObject &operator=(GLPixelBufferObject &&other)
{
if (this == &other) {
return *this;
}
gl_id = other.gl_id;
width = other.width;
height = other.height;
other.reset();
return *this;
}
bool gl_resources_ensure()
{
if (gl_id) {
return true;
}
glGenBuffers(1, &gl_id);
if (!gl_id) {
LOG(ERROR) << "Error creating texture pixel buffer object.";
return false;
}
++num_used;
return true;
}
void gl_resources_destroy()
{
if (!gl_id) {
return;
}
glDeleteBuffers(1, &gl_id);
reset();
--num_used;
}
/* OpenGL resource IDs of the PBO.
*
* NOTE: Allocated on the render engine's context. */
uint gl_id = 0;
/* Dimensions of the PBO. */
int width = 0;
int height = 0;
protected:
void reset()
{
gl_id = 0;
width = 0;
height = 0;
}
};
class DrawTile {
public:
DrawTile() = default;
~DrawTile() = default;
DrawTile(const DrawTile &other) = delete;
DrawTile &operator=(const DrawTile &other) = delete;
DrawTile(DrawTile &&other) noexcept = default;
DrawTile &operator=(DrawTile &&other) = default;
bool gl_resources_ensure()
{
if (!texture.gl_resources_ensure()) {
gl_resources_destroy();
return false;
}
if (!gl_vertex_buffer) {
glGenBuffers(1, &gl_vertex_buffer);
if (!gl_vertex_buffer) {
LOG(ERROR) << "Error allocating tile VBO.";
gl_resources_destroy();
return false;
}
}
return true;
}
void gl_resources_destroy()
{
texture.gl_resources_destroy();
if (gl_vertex_buffer) {
glDeleteBuffers(1, &gl_vertex_buffer);
gl_vertex_buffer = 0;
}
}
inline bool ready_to_draw() const
{
return texture.gl_id != 0;
}
/* Texture which contains pixels of the tile. */
GLTexture texture;
/* Display parameters the texture of this tile has been updated for. */
BlenderDisplayDriver::Params params;
/* OpenGL resources needed for drawing. */
uint gl_vertex_buffer = 0;
};
class DrawTileAndPBO {
public:
bool gl_resources_ensure()
{
if (!tile.gl_resources_ensure() || !buffer_object.gl_resources_ensure()) {
gl_resources_destroy();
return false;
}
return true;
}
void gl_resources_destroy()
{
tile.gl_resources_destroy();
buffer_object.gl_resources_destroy();
}
DrawTile tile;
GLPixelBufferObject buffer_object;
};
/* --------------------------------------------------------------------
* BlenderDisplayDriver.
*/
struct BlenderDisplayDriver::Tiles {
/* Resources of a tile which is being currently rendered. */
DrawTileAndPBO current_tile;
/* All tiles which rendering is finished and which content will not be changed. */
struct {
vector<DrawTile> tiles;
void gl_resources_destroy_and_clear()
{
for (DrawTile &tile : tiles) {
tile.gl_resources_destroy();
}
tiles.clear();
}
} finished_tiles;
};
BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
: b_engine_(b_engine),
display_shader_(BlenderDisplayShader::create(b_engine, b_scene)),
tiles_(make_unique<Tiles>())
: b_engine_(b_engine), display_shader_(BlenderDisplayShader::create(b_engine, b_scene))
{
/* Create context while on the main thread. */
gl_context_create();
@@ -580,21 +292,6 @@ BlenderDisplayDriver::~BlenderDisplayDriver()
* Update procedure.
*/
void BlenderDisplayDriver::next_tile_begin()
{
if (!tiles_->current_tile.tile.ready_to_draw()) {
LOG(ERROR)
<< "Unexpectedly moving to the next tile without any data provided for current tile.";
return;
}
/* Moving to the next tile without giving render data for the current tile is not an expected
* situation. */
DCHECK(!need_clear_);
tiles_->finished_tiles.tiles.emplace_back(std::move(tiles_->current_tile.tile));
}
bool BlenderDisplayDriver::update_begin(const Params &params,
int texture_width,
int texture_height)
@@ -615,96 +312,58 @@ bool BlenderDisplayDriver::update_begin(const Params &params,
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
}
DrawTile &current_tile = tiles_->current_tile.tile;
GLPixelBufferObject &current_tile_buffer_object = tiles_->current_tile.buffer_object;
/* Clear storage of all finished tiles when display clear is requested.
* Do it when new tile data is provided to handle the display clear flag in a single place.
* It also makes the logic reliable from the whether drawing did happen or not point of view. */
if (need_clear_) {
tiles_->finished_tiles.gl_resources_destroy_and_clear();
need_clear_ = false;
}
if (!tiles_->current_tile.gl_resources_ensure()) {
tiles_->current_tile.gl_resources_destroy();
if (!gl_texture_resources_ensure()) {
gl_context_disable();
return false;
}
/* Update texture dimensions if needed. */
if (current_tile.texture.width != texture_width ||
current_tile.texture.height != texture_height) {
if (texture_.width != texture_width || texture_.height != texture_height) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, current_tile.texture.gl_id);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA16F, texture_width, texture_height, 0, GL_RGBA, GL_HALF_FLOAT, 0);
current_tile.texture.width = texture_width;
current_tile.texture.height = texture_height;
texture_.width = texture_width;
texture_.height = texture_height;
glBindTexture(GL_TEXTURE_2D, 0);
/* Texture did change, and no pixel storage was provided. Tag for an explicit zeroing out to
* avoid undefined content. */
texture_.need_clear = true;
}
/* Update PBO dimensions if needed.
*
* NOTE: Allocate the PBO for the size which will fit the final render resolution (as in,
* NOTE: Allocate the PBO for the the size which will fit the final render resolution (as in,
* at a resolution divider 1. This was we don't need to recreate graphics interoperability
* objects which are costly and which are tied to the specific underlying buffer size.
* The downside of this approach is that when graphics interoperability is not used we are
* sending too much data to GPU when resolution divider is not 1. */
/* TODO(sergey): Investigate whether keeping the PBO exact size of the texture makes non-interop
* mode faster. */
const int buffer_width = params.size.x;
const int buffer_height = params.size.y;
if (current_tile_buffer_object.width != buffer_width ||
current_tile_buffer_object.height != buffer_height) {
const int buffer_width = params.full_size.x;
const int buffer_height = params.full_size.y;
if (texture_.buffer_width != buffer_width || texture_.buffer_height != buffer_height) {
const size_t size_in_bytes = sizeof(half4) * buffer_width * buffer_height;
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, current_tile_buffer_object.gl_id);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
glBufferData(GL_PIXEL_UNPACK_BUFFER, size_in_bytes, 0, GL_DYNAMIC_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
current_tile_buffer_object.width = buffer_width;
current_tile_buffer_object.height = buffer_height;
texture_.buffer_width = buffer_width;
texture_.buffer_height = buffer_height;
}
/* Store an updated parameters of the current tile.
* In theory it is only needed once per update of the tile, but doing it on every update is
* the easiest and is not expensive. */
tiles_->current_tile.tile.params = params;
/* New content will be provided to the texture in one way or another, so mark this in a
* centralized place. */
texture_.need_update = true;
texture_.params = params;
return true;
}
static void update_tile_texture_pixels(const DrawTileAndPBO &tile)
{
const GLTexture &texture = tile.tile.texture;
DCHECK_NE(tile.buffer_object.gl_id, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture.gl_id);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, tile.buffer_object.gl_id);
glTexSubImage2D(
GL_TEXTURE_2D, 0, 0, 0, texture.width, texture.height, GL_RGBA, GL_HALF_FLOAT, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
void BlenderDisplayDriver::update_end()
{
/* Unpack the PBO into the texture as soon as the new content is provided.
*
* This allows to ensure that the unpacking happens while resources like graphics interop (which
* lifetime is outside of control of the display driver) are still valid, as well as allows to
* move the tile from being current to finished immediately after this call.
*
* One concern with this approach is that if the update happens more often than drawing then
* doing the unpack here occupies GPU transfer for no good reason. However, the render scheduler
* takes care of ensuring updates don't happen that often. In regular applications redraw will
* happen much more often than this update. */
update_tile_texture_pixels(tiles_->current_tile);
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
@@ -717,11 +376,7 @@ void BlenderDisplayDriver::update_end()
half4 *BlenderDisplayDriver::map_texture_buffer()
{
const uint pbo_gl_id = tiles_->current_tile.buffer_object.gl_id;
DCHECK_NE(pbo_gl_id, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_gl_id);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
half4 *mapped_rgba_pixels = reinterpret_cast<half4 *>(
glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
@@ -729,6 +384,15 @@ half4 *BlenderDisplayDriver::map_texture_buffer()
LOG(ERROR) << "Error mapping BlenderDisplayDriver pixel buffer object.";
}
if (texture_.need_clear) {
const int64_t texture_width = texture_.width;
const int64_t texture_height = texture_.height;
memset(reinterpret_cast<void *>(mapped_rgba_pixels),
0,
texture_width * texture_height * sizeof(half4));
texture_.need_clear = false;
}
return mapped_rgba_pixels;
}
@@ -747,9 +411,12 @@ BlenderDisplayDriver::GraphicsInterop BlenderDisplayDriver::graphics_interop_get
{
GraphicsInterop interop_dst;
interop_dst.buffer_width = tiles_->current_tile.buffer_object.width;
interop_dst.buffer_height = tiles_->current_tile.buffer_object.height;
interop_dst.opengl_pbo_id = tiles_->current_tile.buffer_object.gl_id;
interop_dst.buffer_width = texture_.buffer_width;
interop_dst.buffer_height = texture_.buffer_height;
interop_dst.opengl_pbo_id = texture_.gl_pbo_id;
interop_dst.need_clear = texture_.need_clear;
texture_.need_clear = false;
return interop_dst;
}
@@ -770,7 +437,7 @@ void BlenderDisplayDriver::graphics_interop_deactivate()
void BlenderDisplayDriver::clear()
{
need_clear_ = true;
texture_.need_clear = true;
}
void BlenderDisplayDriver::set_zoom(float zoom_x, float zoom_y)
@@ -778,155 +445,26 @@ void BlenderDisplayDriver::set_zoom(float zoom_x, float zoom_y)
zoom_ = make_float2(zoom_x, zoom_y);
}
/* Update vertex buffer with new coordinates of vertex positions and texture coordinates.
* This buffer is used to render texture in the viewport.
*
* NOTE: The buffer needs to be bound. */
static void vertex_buffer_update(const DisplayDriver::Params &params)
{
const int x = params.full_offset.x;
const int y = params.full_offset.y;
const int width = params.size.x;
const int height = params.size.y;
/* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
* rendered. */
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
float *vpointer = reinterpret_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (!vpointer) {
return;
}
vpointer[0] = 0.0f;
vpointer[1] = 0.0f;
vpointer[2] = x;
vpointer[3] = y;
vpointer[4] = 1.0f;
vpointer[5] = 0.0f;
vpointer[6] = x + width;
vpointer[7] = y;
vpointer[8] = 1.0f;
vpointer[9] = 1.0f;
vpointer[10] = x + width;
vpointer[11] = y + height;
vpointer[12] = 0.0f;
vpointer[13] = 1.0f;
vpointer[14] = x;
vpointer[15] = y + height;
glUnmapBuffer(GL_ARRAY_BUFFER);
}
static void draw_tile(const float2 &zoom,
const int texcoord_attribute,
const int position_attribute,
const DrawTile &draw_tile)
{
if (!draw_tile.ready_to_draw()) {
return;
}
const GLTexture &texture = draw_tile.texture;
DCHECK_NE(texture.gl_id, 0);
DCHECK_NE(draw_tile.gl_vertex_buffer, 0);
glBindBuffer(GL_ARRAY_BUFFER, draw_tile.gl_vertex_buffer);
/* Draw at the parameters for which the texture has been updated for. This allows to always draw
* texture during bordered-rendered camera view without flickering. The validness of the display
* parameters for a texture is guaranteed by the initial "clear" state which makes drawing to
* have an early output.
*
* Such approach can cause some extra "jelly" effect during panning, but it is not more jelly
* than overlay of selected objects. Also, it's possible to redraw texture at an intersection of
* the texture draw parameters and the latest updated draw parameters (although, complexity of
* doing it might not worth it. */
vertex_buffer_update(draw_tile.params);
glBindTexture(GL_TEXTURE_2D, texture.gl_id);
/* Trick to keep sharp rendering without jagged edges on all GPUs.
*
* The idea here is to enforce driver to use linear interpolation when the image is not zoomed
* in.
* For the render result with a resolution divider in effect we always use nearest interpolation.
*
* Use explicit MIN assignment to make sure the driver does not have an undefined behavior at
* the zoom level 1. The MAG filter is always NEAREST. */
const float zoomed_width = draw_tile.params.size.x * zoom.x;
const float zoomed_height = draw_tile.params.size.y * zoom.y;
if (texture.width != draw_tile.params.size.x || texture.height != draw_tile.params.size.y) {
/* Resolution divider is different from 1, force nearest interpolation. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else if (zoomed_width - draw_tile.params.size.x > 0.5f ||
zoomed_height - draw_tile.params.size.y > 0.5f) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
glVertexAttribPointer(
texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
glVertexAttribPointer(position_attribute,
2,
GL_FLOAT,
GL_FALSE,
4 * sizeof(float),
(const GLvoid *)(sizeof(float) * 2));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
void BlenderDisplayDriver::flush()
{
/* This is called from the render thread that also calls update_begin/end, right before ending
* the render loop. We wait for any queued PBO and render commands to be done, before destroying
* the render thread and activating the context in the main thread to destroy resources.
*
* If we don't do this, the NVIDIA driver hangs for a few seconds for when ending 3D viewport
* rendering, for unknown reasons. This was found with NVIDIA driver version 470.73 and a Quadro
* RTX 6000 on Linux. */
if (!gl_context_enable()) {
return;
}
if (gl_upload_sync_) {
glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
}
if (gl_render_sync_) {
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
}
gl_context_disable();
}
void BlenderDisplayDriver::draw(const Params &params)
{
/* See do_update_begin() for why no locking is required here. */
const bool transparent = true; // TODO(sergey): Derive this from Film.
if (!gl_draw_resources_ensure()) {
return;
}
if (use_gl_context_) {
gl_context_mutex_.lock();
}
if (need_clear_) {
if (texture_.need_clear) {
/* Texture is requested to be cleared and was not yet cleared.
*
* Do early return which should be equivalent of drawing all-zero texture.
* Watch out for the lock though so that the clear happening during update is properly
* synchronized here. */
if (use_gl_context_) {
gl_context_mutex_.unlock();
}
gl_context_mutex_.unlock();
return;
}
@@ -939,37 +477,66 @@ void BlenderDisplayDriver::draw(const Params &params)
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
glActiveTexture(GL_TEXTURE0);
display_shader_->bind(params.full_size.x, params.full_size.y);
/* NOTE: The VAO is to be allocated on the drawing context as it is not shared across contexts.
* Simplest is to allocate it on every redraw so that it is possible to destroy it from a
* correct context. */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
/* Trick to keep sharp rendering without jagged edges on all GPUs.
*
* The idea here is to enforce driver to use linear interpolation when the image is not zoomed
* in.
* For the render result with a resolution divider in effect we always use nearest interpolation.
*
* Use explicit MIN assignment to make sure the driver does not have an undefined behavior at
* the zoom level 1. The MAG filter is always NEAREST. */
const float zoomed_width = params.size.x * zoom_.x;
const float zoomed_height = params.size.y * zoom_.y;
if (texture_.width != params.size.x || texture_.height != params.size.y) {
/* Resolution divider is different from 1, force nearest interpolation. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else if (zoomed_width - params.size.x > 0.5f || zoomed_height - params.size.y > 0.5f) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
texture_update_if_needed();
vertex_buffer_update(params);
/* TODO(sergey): Does it make sense/possible to cache/reuse the VAO? */
GLuint vertex_array_object;
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
display_shader_->bind(params.full_size.x, params.full_size.y);
const int texcoord_attribute = display_shader_->get_tex_coord_attrib_location();
const int position_attribute = display_shader_->get_position_attrib_location();
glEnableVertexAttribArray(texcoord_attribute);
glEnableVertexAttribArray(position_attribute);
draw_tile(zoom_, texcoord_attribute, position_attribute, tiles_->current_tile.tile);
glVertexAttribPointer(
texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
glVertexAttribPointer(position_attribute,
2,
GL_FLOAT,
GL_FALSE,
4 * sizeof(float),
(const GLvoid *)(sizeof(float) * 2));
for (const DrawTile &tile : tiles_->finished_tiles.tiles) {
draw_tile(zoom_, texcoord_attribute, position_attribute, tile);
}
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
display_shader_->unbind();
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteVertexArrays(1, &vertex_array_object);
display_shader_->unbind();
if (transparent) {
glDisable(GL_BLEND);
}
@@ -977,11 +544,6 @@ void BlenderDisplayDriver::draw(const Params &params)
gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
if (VLOG_IS_ON(5)) {
VLOG(5) << "Number of textures: " << GLTexture::num_used;
VLOG(5) << "Number of PBOs: " << GLPixelBufferObject::num_used;
}
if (use_gl_context_) {
gl_context_mutex_.unlock();
}
@@ -1056,16 +618,154 @@ void BlenderDisplayDriver::gl_context_dispose()
}
}
bool BlenderDisplayDriver::gl_draw_resources_ensure()
{
if (!texture_.gl_id) {
/* If there is no texture allocated, there is nothing to draw. Inform the draw call that it can
* can not continue. Note that this is not an unrecoverable error, so once the texture is known
* we will come back here and create all the GPU resources needed for draw. */
return false;
}
if (gl_draw_resource_creation_attempted_) {
return gl_draw_resources_created_;
}
gl_draw_resource_creation_attempted_ = true;
if (!vertex_buffer_) {
glGenBuffers(1, &vertex_buffer_);
if (!vertex_buffer_) {
LOG(ERROR) << "Error creating vertex buffer.";
return false;
}
}
gl_draw_resources_created_ = true;
return true;
}
void BlenderDisplayDriver::gl_resources_destroy()
{
gl_context_enable();
tiles_->current_tile.gl_resources_destroy();
tiles_->finished_tiles.gl_resources_destroy_and_clear();
if (vertex_buffer_ != 0) {
glDeleteBuffers(1, &vertex_buffer_);
}
if (texture_.gl_pbo_id) {
glDeleteBuffers(1, &texture_.gl_pbo_id);
texture_.gl_pbo_id = 0;
}
if (texture_.gl_id) {
glDeleteTextures(1, &texture_.gl_id);
texture_.gl_id = 0;
}
gl_context_disable();
gl_context_dispose();
}
bool BlenderDisplayDriver::gl_texture_resources_ensure()
{
if (texture_.creation_attempted) {
return texture_.is_created;
}
texture_.creation_attempted = true;
DCHECK(!texture_.gl_id);
DCHECK(!texture_.gl_pbo_id);
/* Create texture. */
glGenTextures(1, &texture_.gl_id);
if (!texture_.gl_id) {
LOG(ERROR) << "Error creating texture.";
return false;
}
/* Configure the texture. */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
/* Create PBO for the texture. */
glGenBuffers(1, &texture_.gl_pbo_id);
if (!texture_.gl_pbo_id) {
LOG(ERROR) << "Error creating texture pixel buffer object.";
return false;
}
/* Creation finished with a success. */
texture_.is_created = true;
return true;
}
void BlenderDisplayDriver::texture_update_if_needed()
{
if (!texture_.need_update) {
return;
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
glTexSubImage2D(
GL_TEXTURE_2D, 0, 0, 0, texture_.width, texture_.height, GL_RGBA, GL_HALF_FLOAT, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
texture_.need_update = false;
}
void BlenderDisplayDriver::vertex_buffer_update(const Params & /*params*/)
{
/* Draw at the parameters for which the texture has been updated for. This allows to always draw
* texture during bordered-rendered camera view without flickering. The validness of the display
* parameters for a texture is guaranteed by the initial "clear" state which makes drawing to
* have an early output.
*
* Such approach can cause some extra "jelly" effect during panning, but it is not more jelly
* than overlay of selected objects. Also, it's possible to redraw texture at an intersection of
* the texture draw parameters and the latest updated draw parameters (although, complexity of
* doing it might not worth it. */
const int x = texture_.params.full_offset.x;
const int y = texture_.params.full_offset.y;
const int width = texture_.params.size.x;
const int height = texture_.params.size.y;
/* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
* rendered. */
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
float *vpointer = reinterpret_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (!vpointer) {
return;
}
vpointer[0] = 0.0f;
vpointer[1] = 0.0f;
vpointer[2] = x;
vpointer[3] = y;
vpointer[4] = 1.0f;
vpointer[5] = 0.0f;
vpointer[6] = x + width;
vpointer[7] = y;
vpointer[8] = 1.0f;
vpointer[9] = 1.0f;
vpointer[10] = x + width;
vpointer[11] = y + height;
vpointer[12] = 0.0f;
vpointer[13] = 1.0f;
vpointer[14] = x;
vpointer[15] = y + height;
glUnmapBuffer(GL_ARRAY_BUFFER);
}
CCL_NAMESPACE_END

View File

@@ -26,7 +26,6 @@
#include "util/thread.h"
#include "util/unique_ptr.h"
#include "util/vector.h"
CCL_NAMESPACE_BEGIN
@@ -113,8 +112,6 @@ class BlenderDisplayDriver : public DisplayDriver {
void set_zoom(float zoom_x, float zoom_y);
protected:
virtual void next_tile_begin() override;
virtual bool update_begin(const Params &params, int texture_width, int texture_height) override;
virtual void update_end() override;
@@ -125,17 +122,33 @@ class BlenderDisplayDriver : public DisplayDriver {
virtual void draw(const Params &params) override;
virtual void flush() override;
/* Helper function which allocates new GPU context. */
void gl_context_create();
bool gl_context_enable();
void gl_context_disable();
void gl_context_dispose();
/* Make sure texture is allocated and its initial configuration is performed. */
bool gl_texture_resources_ensure();
/* Ensure all runtime GPU resources needed for drawing are allocated.
* Returns true if all resources needed for drawing are available. */
bool gl_draw_resources_ensure();
/* Destroy all GPU resources which are being used by this object. */
void gl_resources_destroy();
/* Update GPU texture dimensions and content if needed (new pixel data was provided).
*
* NOTE: The texture needs to be bound. */
void texture_update_if_needed();
/* Update vertex buffer with new coordinates of vertex positions and texture coordinates.
* This buffer is used to render texture in the viewport.
*
* NOTE: The buffer needs to be bound. */
void vertex_buffer_update(const Params &params);
BL::RenderEngine b_engine_;
/* OpenGL context which is used the render engine doesn't have its own. */
@@ -146,14 +159,50 @@ class BlenderDisplayDriver : public DisplayDriver {
/* Mutex used to guard the `gl_context_`. */
thread_mutex gl_context_mutex_;
/* Content of the display is to be filled with zeroes. */
std::atomic<bool> need_clear_ = true;
/* Texture which contains pixels of the render result. */
struct {
/* Indicates whether texture creation was attempted and succeeded.
* Used to avoid multiple attempts of texture creation on GPU issues or GPU context
* misconfiguration. */
bool creation_attempted = false;
bool is_created = false;
/* OpenGL resource IDs of the texture itself and Pixel Buffer Object (PBO) used to write
* pixels to it.
*
* NOTE: Allocated on the engine's context. */
uint gl_id = 0;
uint gl_pbo_id = 0;
/* Is true when new data was written to the PBO, meaning, the texture might need to be resized
* and new data is to be uploaded to the GPU. */
bool need_update = false;
/* Content of the texture is to be filled with zeroes. */
std::atomic<bool> need_clear = true;
/* Dimensions of the texture in pixels. */
int width = 0;
int height = 0;
/* Dimensions of the underlying PBO. */
int buffer_width = 0;
int buffer_height = 0;
/* Display parameters the texture has been updated for. */
Params params;
} texture_;
unique_ptr<BlenderDisplayShader> display_shader_;
/* Opaque storage for an internal state and data for tiles. */
struct Tiles;
unique_ptr<Tiles> tiles_;
/* Special track of whether GPU resources were attempted to be created, to avoid attempts of
* their re-creation on failure on every redraw. */
bool gl_draw_resource_creation_attempted_ = false;
bool gl_draw_resources_created_ = false;
/* Vertex buffer which hold vertices of a triangle fan which is textures with the texture
* holding the render result. */
uint vertex_buffer_ = 0;
void *gl_render_sync_ = nullptr;
void *gl_upload_sync_ = nullptr;

View File

@@ -19,7 +19,6 @@
#include "scene/hair.h"
#include "scene/mesh.h"
#include "scene/object.h"
#include "scene/pointcloud.h"
#include "scene/volume.h"
#include "blender/sync.h"
@@ -32,18 +31,10 @@ CCL_NAMESPACE_BEGIN
static Geometry::Type determine_geom_type(BObjectInfo &b_ob_info, bool use_particle_hair)
{
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) {
#else
if (use_particle_hair) {
#endif
return Geometry::HAIR;
}
if (b_ob_info.object_data.is_a(&RNA_PointCloud)) {
return Geometry::POINTCLOUD;
}
if (b_ob_info.object_data.is_a(&RNA_Volume) ||
(b_ob_info.object_data == b_ob_info.real_object.data() &&
object_fluid_gas_domain_find(b_ob_info.real_object))) {
@@ -116,9 +107,6 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
else if (geom_type == Geometry::VOLUME) {
geom = scene->create_node<Volume>();
}
else if (geom_type == Geometry::POINTCLOUD) {
geom = scene->create_node<PointCloud>();
}
else {
geom = scene->create_node<Mesh>();
}
@@ -178,10 +166,6 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
Volume *volume = static_cast<Volume *>(geom);
sync_volume(b_ob_info, volume);
}
else if (geom_type == Geometry::POINTCLOUD) {
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
sync_pointcloud(pointcloud, b_ob_info);
}
else {
Mesh *mesh = static_cast<Mesh *>(geom);
sync_mesh(b_depsgraph, b_ob_info, mesh);
@@ -231,11 +215,7 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
if (progress.get_cancel())
return;
#ifdef WITH_HAIR_NODES
if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) {
#else
if (use_particle_hair) {
#endif
Hair *hair = static_cast<Hair *>(geom);
sync_hair_motion(b_depsgraph, b_ob_info, hair, motion_step);
}
@@ -243,10 +223,6 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
object_fluid_gas_domain_find(b_ob_info.real_object)) {
/* No volume motion blur support yet. */
}
else if (b_ob_info.object_data.is_a(&RNA_PointCloud)) {
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
sync_pointcloud_motion(pointcloud, b_ob_info, motion_step);
}
else {
Mesh *mesh = static_cast<Mesh *>(geom);
sync_mesh_motion(b_depsgraph, b_ob_info, mesh, motion_step);

View File

@@ -24,14 +24,8 @@ CCL_NAMESPACE_BEGIN
/* Packed Images */
BlenderImageLoader::BlenderImageLoader(BL::Image b_image,
const int frame,
const bool is_preview_render)
: b_image(b_image),
frame(frame),
/* Don't free cache for preview render to avoid race condition from T93560, to be fixed
properly later as we are close to release. */
free_cache(!is_preview_render && !b_image.has_data())
BlenderImageLoader::BlenderImageLoader(BL::Image b_image, int frame)
: b_image(b_image), frame(frame), free_cache(!b_image.has_data())
{
}

View File

@@ -25,7 +25,7 @@ CCL_NAMESPACE_BEGIN
class BlenderImageLoader : public ImageLoader {
public:
BlenderImageLoader(BL::Image b_image, const int frame, const bool is_preview_render);
BlenderImageLoader(BL::Image b_image, int frame);
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override;
bool load_pixels(const ImageMetaData &metadata,

View File

@@ -555,7 +555,7 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
/* Create uv map attributes. */
static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
{
if (!b_mesh.uv_layers.empty()) {
if (b_mesh.uv_layers.length() != 0) {
for (BL::MeshUVLoopLayer &l : b_mesh.uv_layers) {
const bool active_render = l.active_render();
AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
@@ -619,7 +619,7 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
{
if (!b_mesh.uv_layers.empty()) {
if (b_mesh.uv_layers.length() != 0) {
BL::Mesh::uv_layers_iterator l;
int i = 0;
@@ -951,7 +951,7 @@ static void create_mesh(Scene *scene,
N = attr_N->data_float3();
/* create generated coordinates from undeformed coordinates */
const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.empty()) &&
const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) &&
(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) {
Attribute *attr = attributes.add(ATTR_STD_GENERATED);
@@ -1086,6 +1086,40 @@ static void create_subd_mesh(Scene *scene,
/* Sync */
/* Check whether some of "built-in" motion-related attributes are needed to be exported (includes
* things like velocity from cache modifier, fluid simulation).
*
* NOTE: This code is run prior to object motion blur initialization. so can not access properties
* set by `sync_object_motion_init()`. */
static bool mesh_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene)
{
const Scene::MotionType need_motion = scene->need_motion();
if (need_motion == Scene::MOTION_NONE) {
/* Simple case: neither motion pass nor motion blur is needed, no need in the motion related
* attributes. */
return false;
}
if (need_motion == Scene::MOTION_BLUR) {
/* A bit tricky and implicit case:
* - Motion blur is enabled in the scene, which implies specific number of time steps for
* objects.
* - If the object has motion blur disabled on it, it will have 0 time steps.
* - Motion attribute expects non-zero time steps.
*
* Avoid adding motion attributes if the motion blur will enforce 0 motion steps. */
PointerRNA cobject = RNA_pointer_get(&b_ob_info.real_object.ptr, "cycles");
const bool use_motion = get_boolean(cobject, "use_motion_blur");
if (!use_motion) {
return false;
}
}
/* Motion pass which implies 3 motion steps, or motion blur which is not disabled on object
* level. */
return true;
}
void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Mesh *mesh)
{
/* make a copy of the shaders as the caller in the main thread still need them for syncing the
@@ -1110,7 +1144,7 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
if (b_mesh) {
/* Motion blur attribute is relative to seconds, we need it relative to frames. */
const bool need_motion = object_need_motion_attribute(b_ob_info, scene);
const bool need_motion = mesh_need_motion_attribute(b_ob_info, scene);
const float motion_scale = (need_motion) ?
scene->motion_shutter_time() /
(b_scene.render().fps() / b_scene.render().fps_base()) :

View File

@@ -62,47 +62,31 @@ bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
return false;
}
bool BlenderSync::object_is_geometry(BObjectInfo &b_ob_info)
bool BlenderSync::object_is_geometry(BL::Object &b_ob)
{
BL::ID b_ob_data = b_ob_info.object_data;
BL::ID b_ob_data = b_ob.data();
if (!b_ob_data) {
return false;
}
BL::Object::type_enum type = b_ob_info.iter_object.type();
BL::Object::type_enum type = b_ob.type();
if (type == BL::Object::type_VOLUME || type == BL::Object::type_HAIR ||
type == BL::Object::type_POINTCLOUD) {
if (type == BL::Object::type_VOLUME || type == BL::Object::type_HAIR) {
/* Will be exported attached to mesh. */
return true;
}
else if (type == BL::Object::type_CURVE) {
/* Skip exporting curves without faces, overhead can be
* significant if there are many for path animation. */
BL::Curve b_curve(b_ob_data);
/* Other object types that are not meshes but evaluate to meshes are presented to render engines
* as separate instance objects. Metaballs and surface objects have not been affected by that
* change yet. */
if (type == BL::Object::type_SURFACE || type == BL::Object::type_META) {
return true;
return (b_curve.bevel_object() || b_curve.extrude() != 0.0f || b_curve.bevel_depth() != 0.0f ||
b_curve.dimensions() == BL::Curve::dimensions_2D || b_ob.modifiers.length());
}
return b_ob_data.is_a(&RNA_Mesh);
}
bool BlenderSync::object_can_have_geometry(BL::Object &b_ob)
{
BL::Object::type_enum type = b_ob.type();
switch (type) {
case BL::Object::type_MESH:
case BL::Object::type_CURVE:
case BL::Object::type_SURFACE:
case BL::Object::type_META:
case BL::Object::type_FONT:
case BL::Object::type_HAIR:
case BL::Object::type_POINTCLOUD:
case BL::Object::type_VOLUME:
return true;
default:
return false;
else {
return (b_ob_data.is_a(&RNA_Mesh) || b_ob_data.is_a(&RNA_Curve) ||
b_ob_data.is_a(&RNA_MetaBall));
}
}
@@ -177,11 +161,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
if (is_instance) {
persistent_id_array = b_instance.persistent_id();
persistent_id = persistent_id_array.data;
if (!b_ob_info.is_real_object_data()) {
/* Remember which object data the geometry is coming from, so that we can sync it when the
* object has changed. */
instance_geometries_by_object[b_ob_info.real_object.ptr.data].insert(b_ob_info.object_data);
}
}
/* light is handled separately */
@@ -207,8 +186,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
return NULL;
}
/* only interested in object that we can create geometry from */
if (!object_is_geometry(b_ob_info)) {
/* only interested in object that we can create meshes from */
if (!object_is_geometry(b_ob)) {
return NULL;
}
@@ -295,7 +274,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
object->set_visibility(visibility);
object->set_is_shadow_catcher(b_ob.is_shadow_catcher() || b_parent.is_shadow_catcher());
object->set_is_shadow_catcher(b_ob.is_shadow_catcher());
float shadow_terminator_shading_offset = get_float(cobject, "shadow_terminator_offset");
object->set_shadow_terminator_shading_offset(shadow_terminator_shading_offset);
@@ -581,7 +560,6 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
else {
geometry_motion_synced.clear();
}
instance_geometries_by_object.clear();
/* initialize culling */
BlenderObjectCulling culling(scene, b_scene);

View File

@@ -66,7 +66,7 @@ bool BlenderOutputDriver::read_render_tile(const Tile &tile)
bool BlenderOutputDriver::update_render_tile(const Tile &tile)
{
/* Use final write for preview renders, otherwise render result wouldn't be updated
/* Use final write for preview renders, otherwise render result wouldn't be be updated
* quickly on Blender side. For all other cases we use the display driver. */
if (b_engine_.is_preview()) {
write_render_tile(tile);
@@ -120,7 +120,7 @@ void BlenderOutputDriver::write_render_tile(const Tile &tile)
b_pass.rect(&pixels[0]);
}
b_engine_.end_result(b_rr, false, false, true);
b_engine_.end_result(b_rr, true, false, true);
}
CCL_NAMESPACE_END

View File

@@ -1,303 +0,0 @@
/*
* Copyright 2011-2013 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "scene/pointcloud.h"
#include "scene/attribute.h"
#include "scene/scene.h"
#include "blender/sync.h"
#include "blender/util.h"
#include "util/foreach.h"
#include "util/hash.h"
CCL_NAMESPACE_BEGIN
template<typename TypeInCycles, typename GetValueAtIndex>
static void fill_generic_attribute(BL::PointCloud &b_pointcloud,
TypeInCycles *data,
const GetValueAtIndex &get_value_at_index)
{
const int num_points = b_pointcloud.points.length();
for (int i = 0; i < num_points; i++) {
data[i] = get_value_at_index(i);
}
}
static void attr_create_motion(PointCloud *pointcloud,
BL::Attribute &b_attribute,
const float motion_scale)
{
if (!(b_attribute.domain() == BL::Attribute::domain_POINT) &&
(b_attribute.data_type() == BL::Attribute::data_type_FLOAT_VECTOR)) {
return;
}
BL::FloatVectorAttribute b_vector_attribute(b_attribute);
const int num_points = pointcloud->get_points().size();
/* Find or add attribute */
float3 *P = &pointcloud->get_points()[0];
Attribute *attr_mP = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (!attr_mP) {
attr_mP = pointcloud->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
}
/* Only export previous and next frame, we don't have any in between data. */
float motion_times[2] = {-1.0f, 1.0f};
for (int step = 0; step < 2; step++) {
const float relative_time = motion_times[step] * 0.5f * motion_scale;
float3 *mP = attr_mP->data_float3() + step * num_points;
for (int i = 0; i < num_points; i++) {
mP[i] = P[i] + get_float3(b_vector_attribute.data[i].vector()) * relative_time;
}
}
}
static void copy_attributes(PointCloud *pointcloud,
BL::PointCloud b_pointcloud,
const bool need_motion,
const float motion_scale)
{
AttributeSet &attributes = pointcloud->attributes;
static const ustring u_velocity("velocity");
for (BL::Attribute &b_attribute : b_pointcloud.attributes) {
const ustring name{b_attribute.name().c_str()};
if (need_motion && name == u_velocity) {
attr_create_motion(pointcloud, b_attribute, motion_scale);
}
if (attributes.find(name)) {
continue;
}
const AttributeElement element = ATTR_ELEMENT_VERTEX;
const BL::Attribute::data_type_enum b_data_type = b_attribute.data_type();
switch (b_data_type) {
case BL::Attribute::data_type_FLOAT: {
BL::FloatAttribute b_float_attribute{b_attribute};
Attribute *attr = attributes.add(name, TypeFloat, element);
float *data = attr->data_float();
fill_generic_attribute(
b_pointcloud, data, [&](int i) { return b_float_attribute.data[i].value(); });
break;
}
case BL::Attribute::data_type_BOOLEAN: {
BL::BoolAttribute b_bool_attribute{b_attribute};
Attribute *attr = attributes.add(name, TypeFloat, element);
float *data = attr->data_float();
fill_generic_attribute(
b_pointcloud, data, [&](int i) { return (float)b_bool_attribute.data[i].value(); });
break;
}
case BL::Attribute::data_type_INT: {
BL::IntAttribute b_int_attribute{b_attribute};
Attribute *attr = attributes.add(name, TypeFloat, element);
float *data = attr->data_float();
fill_generic_attribute(
b_pointcloud, data, [&](int i) { return (float)b_int_attribute.data[i].value(); });
break;
}
case BL::Attribute::data_type_FLOAT_VECTOR: {
BL::FloatVectorAttribute b_vector_attribute{b_attribute};
Attribute *attr = attributes.add(name, TypeVector, element);
float3 *data = attr->data_float3();
fill_generic_attribute(b_pointcloud, data, [&](int i) {
BL::Array<float, 3> v = b_vector_attribute.data[i].vector();
return make_float3(v[0], v[1], v[2]);
});
break;
}
case BL::Attribute::data_type_FLOAT_COLOR: {
BL::FloatColorAttribute b_color_attribute{b_attribute};
Attribute *attr = attributes.add(name, TypeRGBA, element);
float4 *data = attr->data_float4();
fill_generic_attribute(b_pointcloud, data, [&](int i) {
BL::Array<float, 4> v = b_color_attribute.data[i].color();
return make_float4(v[0], v[1], v[2], v[3]);
});
break;
}
case BL::Attribute::data_type_FLOAT2: {
BL::Float2Attribute b_float2_attribute{b_attribute};
Attribute *attr = attributes.add(name, TypeFloat2, element);
float2 *data = attr->data_float2();
fill_generic_attribute(b_pointcloud, data, [&](int i) {
BL::Array<float, 2> v = b_float2_attribute.data[i].vector();
return make_float2(v[0], v[1]);
});
break;
}
default:
/* Not supported. */
break;
}
}
}
static void export_pointcloud(Scene *scene,
PointCloud *pointcloud,
BL::PointCloud b_pointcloud,
const bool need_motion,
const float motion_scale)
{
/* TODO: optimize so we can straight memcpy arrays from Blender? */
/* Add requested attributes. */
Attribute *attr_random = NULL;
if (pointcloud->need_attribute(scene, ATTR_STD_POINT_RANDOM)) {
attr_random = pointcloud->attributes.add(ATTR_STD_POINT_RANDOM);
}
/* Reserve memory. */
const int num_points = b_pointcloud.points.length();
pointcloud->reserve(num_points);
/* Export points. */
BL::PointCloud::points_iterator b_point_iter;
for (b_pointcloud.points.begin(b_point_iter); b_point_iter != b_pointcloud.points.end();
++b_point_iter) {
BL::Point b_point = *b_point_iter;
const float3 co = get_float3(b_point.co());
const float radius = b_point.radius();
pointcloud->add_point(co, radius);
/* Random number per point. */
if (attr_random != NULL) {
attr_random->add(hash_uint2_to_float(b_point.index(), 0));
}
}
/* Export attributes */
copy_attributes(pointcloud, b_pointcloud, need_motion, motion_scale);
}
static void export_pointcloud_motion(PointCloud *pointcloud,
BL::PointCloud b_pointcloud,
int motion_step)
{
/* Find or add attribute. */
Attribute *attr_mP = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
bool new_attribute = false;
if (!attr_mP) {
attr_mP = pointcloud->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
new_attribute = true;
}
/* Export motion points. */
const int num_points = pointcloud->num_points();
float3 *mP = attr_mP->data_float3() + motion_step * num_points;
bool have_motion = false;
int num_motion_points = 0;
const array<float3> &pointcloud_points = pointcloud->get_points();
BL::PointCloud::points_iterator b_point_iter;
for (b_pointcloud.points.begin(b_point_iter); b_point_iter != b_pointcloud.points.end();
++b_point_iter) {
BL::Point b_point = *b_point_iter;
if (num_motion_points < num_points) {
float3 P = get_float3(b_point.co());
P.w = b_point.radius();
mP[num_motion_points] = P;
have_motion = have_motion || (P != pointcloud_points[num_motion_points]);
num_motion_points++;
}
}
/* In case of new attribute, we verify if there really was any motion. */
if (new_attribute) {
if (num_motion_points != num_points || !have_motion) {
pointcloud->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
}
else if (motion_step > 0) {
/* Motion, fill up previous steps that we might have skipped because
* they had no motion, but we need them anyway now. */
for (int step = 0; step < motion_step; step++) {
pointcloud->copy_center_to_motion_step(step);
}
}
}
/* Export attributes */
copy_attributes(pointcloud, b_pointcloud, false, 0.0f);
}
void BlenderSync::sync_pointcloud(PointCloud *pointcloud, BObjectInfo &b_ob_info)
{
size_t old_numpoints = pointcloud->num_points();
array<Node *> used_shaders = pointcloud->get_used_shaders();
PointCloud new_pointcloud;
new_pointcloud.set_used_shaders(used_shaders);
/* TODO: add option to filter out points in the view layer. */
BL::PointCloud b_pointcloud(b_ob_info.object_data);
/* Motion blur attribute is relative to seconds, we need it relative to frames. */
const bool need_motion = object_need_motion_attribute(b_ob_info, scene);
const float motion_scale = (need_motion) ?
scene->motion_shutter_time() /
(b_scene.render().fps() / b_scene.render().fps_base()) :
0.0f;
export_pointcloud(scene, &new_pointcloud, b_pointcloud, need_motion, motion_scale);
/* update original sockets */
for (const SocketType &socket : new_pointcloud.type->inputs) {
/* Those sockets are updated in sync_object, so do not modify them. */
if (socket.name == "use_motion_blur" || socket.name == "motion_steps" ||
socket.name == "used_shaders") {
continue;
}
pointcloud->set_value(socket, new_pointcloud, socket);
}
pointcloud->attributes.clear();
foreach (Attribute &attr, new_pointcloud.attributes.attributes) {
pointcloud->attributes.attributes.push_back(std::move(attr));
}
/* tag update */
const bool rebuild = (pointcloud && old_numpoints != pointcloud->num_points());
pointcloud->tag_update(scene, rebuild);
}
void BlenderSync::sync_pointcloud_motion(PointCloud *pointcloud,
BObjectInfo &b_ob_info,
int motion_step)
{
/* Skip if nothing exported. */
if (pointcloud->num_points() == 0) {
return;
}
/* Export deformed coordinates. */
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
/* PointCloud object. */
BL::PointCloud b_pointcloud(b_ob_info.object_data);
export_pointcloud_motion(pointcloud, b_pointcloud, motion_step);
}
else {
/* No deformation on this frame, copy coordinates if other frames did have it. */
pointcloud->copy_center_to_motion_step(motion_step);
}
}
CCL_NAMESPACE_END

View File

@@ -138,23 +138,27 @@ static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
static PyObject *init_func(PyObject * /*self*/, PyObject *args)
{
PyObject *path, *user_path;
PyObject *path, *user_path, *temp_path;
int headless;
if (!PyArg_ParseTuple(args, "OOi", &path, &user_path, &headless)) {
if (!PyArg_ParseTuple(args, "OOOi", &path, &user_path, &temp_path, &headless)) {
return nullptr;
}
PyObject *path_coerce = nullptr, *user_path_coerce = nullptr;
PyObject *path_coerce = nullptr, *user_path_coerce = nullptr, *temp_path_coerce = nullptr;
path_init(PyC_UnicodeAsByte(path, &path_coerce),
PyC_UnicodeAsByte(user_path, &user_path_coerce));
PyC_UnicodeAsByte(user_path, &user_path_coerce),
PyC_UnicodeAsByte(temp_path, &temp_path_coerce));
Py_XDECREF(path_coerce);
Py_XDECREF(user_path_coerce);
Py_XDECREF(temp_path_coerce);
BlenderSession::headless = headless;
DebugFlags().running_inside_blender = true;
VLOG(2) << "Debug flags initialized to:\n" << DebugFlags();
Py_RETURN_NONE;
}
@@ -733,20 +737,27 @@ static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string> &filepat
static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
{
#if 1
(void)args;
(void)keywords;
#else
static const char *keyword_list[] = {
"preferences", "scene", "view_layer", "input", "output", NULL};
"preferences", "scene", "view_layer", "input", "output", "tile_size", "samples", NULL};
PyObject *pypreferences, *pyscene, *pyviewlayer;
PyObject *pyinput, *pyoutput = NULL;
int tile_size = 0, samples = 0;
if (!PyArg_ParseTupleAndKeywords(args,
keywords,
"OOOO|O",
"OOOO|Oii",
(char **)keyword_list,
&pypreferences,
&pyscene,
&pyviewlayer,
&pyinput,
&pyoutput)) {
&pyoutput,
&tile_size,
&samples)) {
return NULL;
}
@@ -768,10 +779,14 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
&RNA_ViewLayer,
PyLong_AsVoidPtr(pyviewlayer),
&viewlayerptr);
BL::ViewLayer b_view_layer(viewlayerptr);
PointerRNA cviewlayer = RNA_pointer_get(&viewlayerptr, "cycles");
DenoiseParams params = BlenderSync::get_denoise_params(b_scene, b_view_layer, true);
params.use = true;
DenoiseParams params;
params.radius = get_int(cviewlayer, "denoising_radius");
params.strength = get_float(cviewlayer, "denoising_strength");
params.feature_strength = get_float(cviewlayer, "denoising_feature_strength");
params.relative_pca = get_boolean(cviewlayer, "denoising_relative_pca");
params.neighbor_frames = get_int(cviewlayer, "denoising_neighbor_frames");
/* Parse file paths list. */
vector<string> input, output;
@@ -799,15 +814,24 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
}
/* Create denoiser. */
DenoiserPipeline denoiser(device, params);
DenoiserPipeline denoiser(device);
denoiser.params = params;
denoiser.input = input;
denoiser.output = output;
if (tile_size > 0) {
denoiser.tile_size = make_int2(tile_size, tile_size);
}
if (samples > 0) {
denoiser.samples_override = samples;
}
/* Run denoiser. */
if (!denoiser.run()) {
PyErr_SetString(PyExc_ValueError, denoiser.error.c_str());
return NULL;
}
#endif
Py_RETURN_NONE;
}
@@ -861,6 +885,8 @@ static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
debug_flags_sync_from_scene(b_scene);
VLOG(2) << "Debug flags set to:\n" << DebugFlags();
debug_flags_set = true;
Py_RETURN_NONE;
@@ -870,6 +896,7 @@ static PyObject *debug_flags_reset_func(PyObject * /*self*/, PyObject * /*args*/
{
debug_flags_reset();
if (debug_flags_set) {
VLOG(2) << "Debug flags reset to:\n" << DebugFlags();
debug_flags_set = false;
}
Py_RETURN_NONE;
@@ -884,18 +911,16 @@ static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*
static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/)
{
vector<DeviceType> device_types = Device::available_types();
bool has_cuda = false, has_optix = false, has_hip = false, has_metal = false;
bool has_cuda = false, has_optix = false, has_hip = false;
foreach (DeviceType device_type, device_types) {
has_cuda |= (device_type == DEVICE_CUDA);
has_optix |= (device_type == DEVICE_OPTIX);
has_hip |= (device_type == DEVICE_HIP);
has_metal |= (device_type == DEVICE_METAL);
}
PyObject *list = PyTuple_New(4);
PyObject *list = PyTuple_New(3);
PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_optix));
PyTuple_SET_ITEM(list, 2, PyBool_FromLong(has_hip));
PyTuple_SET_ITEM(list, 3, PyBool_FromLong(has_metal));
return list;
}
@@ -924,9 +949,6 @@ static PyObject *set_device_override_func(PyObject * /*self*/, PyObject *arg)
else if (override == "HIP") {
BlenderSession::device_override = DEVICE_MASK_HIP;
}
else if (override == "METAL") {
BlenderSession::device_override = DEVICE_MASK_METAL;
}
else {
printf("\nError: %s is not a valid Cycles device.\n", override.c_str());
Py_RETURN_FALSE;
@@ -1037,13 +1059,5 @@ void *CCL_python_module_init()
Py_INCREF(Py_False);
}
#ifdef WITH_CYCLES_DEBUG
PyModule_AddObject(mod, "with_debug", Py_True);
Py_INCREF(Py_True);
#else /* WITH_CYCLES_DEBUG */
PyModule_AddObject(mod, "with_debug", Py_False);
Py_INCREF(Py_False);
#endif /* WITH_CYCLES_DEBUG */
return (void *)mod;
}

View File

@@ -129,7 +129,7 @@ void BlenderSession::create_session()
/* reset status/progress */
last_status = "";
last_error = "";
last_progress = -1.0;
last_progress = -1.0f;
start_resize_time = 0.0;
/* create session */
@@ -396,13 +396,6 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
/* set the current view */
b_engine.active_view_set(b_rview_name.c_str());
/* Force update in this case, since the camera transform on each frame changes
* in different views. This could be optimized by somehow storing the animated
* camera transforms separate from the fixed stereo transform. */
if ((scene->need_motion() != Scene::MOTION_NONE) && view_index > 0) {
sync->tag_update();
}
/* update scene */
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
@@ -502,15 +495,10 @@ void BlenderSession::render_frame_finish()
path_remove(filename);
}
/* Clear output driver. */
/* Clear driver. */
session->set_output_driver(nullptr);
session->full_buffer_written_cb = function_null;
/* The display driver holds OpenGL resources which belong to an OpenGL context held by the render
* engine on Blender side. Force destruction of those resources. */
display_driver_ = nullptr;
session->set_display_driver(nullptr);
/* All the files are handled.
* Clear the list so that this session can be re-used by Persistent Data. */
full_buffer_files_.clear();
@@ -627,24 +615,6 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
/* Filtering settings for combined pass. */
if (pass->get_type() == PASS_COMBINED) {
Integrator *integrator = scene->integrator;
integrator->set_use_direct_light((bake_filter & BL::BakeSettings::pass_filter_DIRECT) != 0);
integrator->set_use_indirect_light((bake_filter & BL::BakeSettings::pass_filter_INDIRECT) !=
0);
integrator->set_use_diffuse((bake_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0);
integrator->set_use_glossy((bake_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0);
integrator->set_use_transmission(
(bake_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0);
integrator->set_use_emission((bake_filter & BL::BakeSettings::pass_filter_EMIT) != 0);
}
/* Always use transparent background for baking. */
scene->background->set_transparent(true);
/* Load built-in images from Blender. */
builtin_images_load();
}
@@ -871,7 +841,7 @@ void BlenderSession::get_status(string &status, string &substatus)
session->progress.get_status(status, substatus);
}
void BlenderSession::get_progress(double &progress, double &total_time, double &render_time)
void BlenderSession::get_progress(float &progress, double &total_time, double &render_time)
{
session->progress.get_time(total_time, render_time);
progress = session->progress.get_progress();
@@ -879,10 +849,10 @@ void BlenderSession::get_progress(double &progress, double &total_time, double &
void BlenderSession::update_bake_progress()
{
double progress = session->progress.get_progress();
float progress = session->progress.get_progress();
if (progress != last_progress) {
b_engine.update_progress((float)progress);
b_engine.update_progress(progress);
last_progress = progress;
}
}
@@ -891,7 +861,7 @@ void BlenderSession::update_status_progress()
{
string timestatus, status, substatus;
string scene_status = "";
double progress;
float progress;
double total_time, remaining_time = 0, render_time;
float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f;
float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
@@ -935,7 +905,7 @@ void BlenderSession::update_status_progress()
last_status_time = current_time;
}
if (progress != last_progress) {
b_engine.update_progress((float)progress);
b_engine.update_progress(progress);
last_progress = progress;
}

View File

@@ -82,7 +82,7 @@ class BlenderSession {
void tag_redraw();
void tag_update();
void get_status(string &status, string &substatus);
void get_progress(double &progress, double &total_time, double &render_time);
void get_progress(float &progress, double &total_time, double &render_time);
void test_cancel();
void update_status_progress();
void update_bake_progress();
@@ -108,7 +108,7 @@ class BlenderSession {
string last_status;
string last_error;
double last_progress;
float last_progress;
double last_status_time;
int width, height;

View File

@@ -378,19 +378,10 @@ static ShaderNode *add_node(Scene *scene,
}
else if (b_node.is_a(&RNA_ShaderNodeMapRange)) {
BL::ShaderNodeMapRange b_map_range_node(b_node);
if (b_map_range_node.data_type() == BL::ShaderNodeMapRange::data_type_FLOAT_VECTOR) {
VectorMapRangeNode *vector_map_range_node = graph->create_node<VectorMapRangeNode>();
vector_map_range_node->set_use_clamp(b_map_range_node.clamp());
vector_map_range_node->set_range_type(
(NodeMapRangeType)b_map_range_node.interpolation_type());
node = vector_map_range_node;
}
else {
MapRangeNode *map_range_node = graph->create_node<MapRangeNode>();
map_range_node->set_clamp(b_map_range_node.clamp());
map_range_node->set_range_type((NodeMapRangeType)b_map_range_node.interpolation_type());
node = map_range_node;
}
MapRangeNode *map_range_node = graph->create_node<MapRangeNode>();
map_range_node->set_clamp(b_map_range_node.clamp());
map_range_node->set_range_type((NodeMapRangeType)b_map_range_node.interpolation_type());
node = map_range_node;
}
else if (b_node.is_a(&RNA_ShaderNodeClamp)) {
BL::ShaderNodeClamp b_clamp_node(b_node);
@@ -771,12 +762,11 @@ static ShaderNode *add_node(Scene *scene,
int scene_frame = b_scene.frame_current();
int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
image->handle = scene->image_manager->add_image(
new BlenderImageLoader(b_image, image_frame, b_engine.is_preview()),
image->image_params());
new BlenderImageLoader(b_image, image_frame), image->image_params());
}
else {
ustring filename = ustring(
image_user_file_path(b_image_user, b_image, b_scene.frame_current()));
image_user_file_path(b_image_user, b_image, b_scene.frame_current(), true));
image->set_filename(filename);
}
}
@@ -807,13 +797,12 @@ static ShaderNode *add_node(Scene *scene,
if (is_builtin) {
int scene_frame = b_scene.frame_current();
int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
env->handle = scene->image_manager->add_image(
new BlenderImageLoader(b_image, image_frame, b_engine.is_preview()),
env->image_params());
env->handle = scene->image_manager->add_image(new BlenderImageLoader(b_image, image_frame),
env->image_params());
}
else {
env->set_filename(
ustring(image_user_file_path(b_image_user, b_image, b_scene.frame_current())));
ustring(image_user_file_path(b_image_user, b_image, b_scene.frame_current(), false)));
}
}
node = env;

View File

@@ -95,11 +95,6 @@ void BlenderSync::reset(BL::BlendData &b_data, BL::Scene &b_scene)
this->b_scene = b_scene;
}
void BlenderSync::tag_update()
{
has_updates_ = true;
}
/* Sync */
void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d)
@@ -167,19 +162,19 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
/* Object */
else if (b_id.is_a(&RNA_Object)) {
BL::Object b_ob(b_id);
const bool can_have_geometry = object_can_have_geometry(b_ob);
const bool is_light = !can_have_geometry && object_is_light(b_ob);
const bool is_geometry = object_is_geometry(b_ob);
const bool is_light = !is_geometry && object_is_light(b_ob);
if (b_ob.is_instancer() && b_update.is_updated_shading()) {
/* Needed for e.g. object color updates on instancer. */
object_map.set_recalc(b_ob);
}
if (can_have_geometry || is_light) {
if (is_geometry || is_light) {
const bool updated_geometry = b_update.is_updated_geometry();
/* Geometry (mesh, hair, volume). */
if (can_have_geometry) {
if (is_geometry) {
if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
object_map.set_recalc(b_ob);
}
@@ -188,15 +183,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
(object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) {
BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data();
geometry_map.set_recalc(key);
/* Sync all contained geometry instances as well when the object changed.. */
map<void *, set<BL::ID>>::const_iterator instance_geometries =
instance_geometries_by_object.find(b_ob.ptr.data);
if (instance_geometries != instance_geometries_by_object.end()) {
for (BL::ID geometry : instance_geometries->second) {
geometry_map.set_recalc(geometry);
}
}
}
if (updated_geometry) {
@@ -370,8 +356,8 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
int samples = get_int(cscene, "samples");
float scrambling_distance = get_float(cscene, "scrambling_distance");
bool auto_scrambling_distance = get_boolean(cscene, "auto_scrambling_distance");
if (auto_scrambling_distance) {
bool adaptive_scrambling_distance = get_boolean(cscene, "adaptive_scrambling_distance");
if (adaptive_scrambling_distance) {
scrambling_distance *= 4.0f / sqrtf(samples);
}
@@ -380,9 +366,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
if ((preview && !preview_scrambling_distance) || use_adaptive_sampling)
scrambling_distance = 1.0f;
if (scrambling_distance != 1.0f) {
VLOG(3) << "Using scrambling distance: " << scrambling_distance;
}
VLOG(1) << "Used Scrambling Distance: " << scrambling_distance;
integrator->set_scrambling_distance(scrambling_distance);
if (get_boolean(cscene, "use_fast_gi")) {
@@ -397,12 +381,6 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
integrator->set_ao_bounces(0);
}
#ifdef WITH_CYCLES_DEBUG
DirectLightSamplingType direct_light_sampling_type = (DirectLightSamplingType)get_enum(
cscene, "direct_light_sampling_type", DIRECT_LIGHT_SAMPLING_NUM, DIRECT_LIGHT_SAMPLING_MIS);
integrator->set_direct_light_sampling_type(direct_light_sampling_type);
#endif
const DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
integrator->set_use_denoise(denoise_params.use);
@@ -832,14 +810,6 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
SessionParams params;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
if (background && !b_engine.is_preview()) {
/* Viewport and preview renders do not require temp directory and do request session
* parameters more often than the background render.
* Optimize RNA-C++ usage and memory allocation a bit by saving string access which we know is
* not needed for viewport render. */
params.temp_dir = b_engine.temporary_directory();
}
/* feature set */
params.experimental = (get_enum(cscene, "feature_set") != 0);
@@ -854,25 +824,18 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
/* samples */
int samples = get_int(cscene, "samples");
int preview_samples = get_int(cscene, "preview_samples");
int sample_offset = get_int(cscene, "sample_offset");
if (background) {
params.samples = samples;
params.sample_offset = sample_offset;
}
else {
params.samples = preview_samples;
if (params.samples == 0) {
if (params.samples == 0)
params.samples = INT_MAX;
}
params.sample_offset = 0;
}
/* Clamp sample offset. */
params.sample_offset = clamp(params.sample_offset, 0, Integrator::MAX_SAMPLES);
/* Clamp samples. */
params.samples = clamp(params.samples, 0, Integrator::MAX_SAMPLES - params.sample_offset);
params.samples = min(params.samples, Integrator::MAX_SAMPLES);
/* Viewport Performance */
params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
@@ -891,7 +854,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
/* Time limit. */
if (background) {
params.time_limit = (double)get_float(cscene, "time_limit");
params.time_limit = get_float(cscene, "time_limit");
}
else {
/* For the viewport it kind of makes more sense to think in terms of the noise floor, which is

View File

@@ -66,8 +66,6 @@ class BlenderSync {
void reset(BL::BlendData &b_data, BL::Scene &b_scene);
void tag_update();
/* sync */
void sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d);
void sync_data(BL::RenderSettings &b_render,
@@ -105,11 +103,11 @@ class BlenderSync {
static BufferParams get_buffer_params(
BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, Camera *cam, int width, int height);
private:
static DenoiseParams get_denoise_params(BL::Scene &b_scene,
BL::ViewLayer &b_view_layer,
bool background);
private:
/* sync */
void sync_lights(BL::Depsgraph &b_depsgraph, bool update_all);
void sync_materials(BL::Depsgraph &b_depsgraph, bool update_all);
@@ -169,16 +167,12 @@ class BlenderSync {
Hair *hair, BL::Mesh &b_mesh, BObjectInfo &b_ob_info, bool motion, int motion_step = 0);
bool object_has_particle_hair(BL::Object b_ob);
/* Point Cloud */
void sync_pointcloud(PointCloud *pointcloud, BObjectInfo &b_ob_info);
void sync_pointcloud_motion(PointCloud *pointcloud, BObjectInfo &b_ob_info, int motion_step = 0);
/* Camera */
void sync_camera_motion(
BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time);
/* Geometry */
Geometry *sync_geometry(BL::Depsgraph &b_depsgraph,
Geometry *sync_geometry(BL::Depsgraph &b_depsgrpah,
BObjectInfo &b_ob_info,
bool object_updated,
bool use_particle_hair,
@@ -214,8 +208,7 @@ class BlenderSync {
/* util */
void find_shader(BL::ID &id, array<Node *> &used_shaders, Shader *default_shader);
bool BKE_object_is_modified(BL::Object &b_ob);
bool object_is_geometry(BObjectInfo &b_ob_info);
bool object_can_have_geometry(BL::Object &b_ob);
bool object_is_geometry(BL::Object &b_ob);
bool object_is_light(BL::Object &b_ob);
/* variables */
@@ -232,8 +225,6 @@ class BlenderSync {
set<Geometry *> geometry_synced;
set<Geometry *> geometry_motion_synced;
set<Geometry *> geometry_motion_attribute_synced;
/** Remember which geometries come from which objects to be able to sync them after changes. */
map<void *, set<BL::ID>> instance_geometries_by_object;
set<float> motion_times;
void *world_map;
bool world_recalc;
@@ -273,6 +264,7 @@ class BlenderSync {
Progress &progress;
protected:
/* Indicates that `sync_recalc()` detected changes in the scene.
* If this flag is false then the data is considered to be up-to-date and will not be
* synchronized at all. */

View File

@@ -18,7 +18,6 @@
#define __BLENDER_UTIL_H__
#include "scene/mesh.h"
#include "scene/scene.h"
#include "util/algorithm.h"
#include "util/array.h"
@@ -34,7 +33,7 @@
extern "C" {
void BKE_image_user_frame_calc(void *ima, void *iuser, int cfra);
void BKE_image_user_file_path_ex(void *iuser, void *ima, char *path, bool resolve_udim);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame, int tile);
float *BKE_image_get_float_pixels_for_frame(void *image, int frame, int tile);
}
@@ -291,14 +290,25 @@ static inline int render_resolution_y(BL::RenderSettings &b_render)
return b_render.resolution_y() * b_render.resolution_percentage() / 100;
}
static inline string image_user_file_path(BL::ImageUser &iuser, BL::Image &ima, int cfra)
static inline string image_user_file_path(BL::ImageUser &iuser,
BL::Image &ima,
int cfra,
bool load_tiled)
{
char filepath[1024];
iuser.tile(0);
BKE_image_user_frame_calc(ima.ptr.data, iuser.ptr.data, cfra);
BKE_image_user_file_path_ex(iuser.ptr.data, ima.ptr.data, filepath, false);
BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
return string(filepath);
string filepath_str = string(filepath);
if (load_tiled && ima.source() == BL::Image::source_TILED) {
string udim;
if (ima.tiles.length() > 0) {
udim = to_string(ima.tiles[0].number());
}
string_replace(filepath_str, udim, "<UDIM>");
}
return filepath_str;
}
static inline int image_user_frame_number(BL::ImageUser &iuser, BL::Image &ima, int cfra)
@@ -637,7 +647,7 @@ static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob,
{
PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
if (cobj.data && !b_ob.modifiers.empty() && experimental) {
if (cobj.data && b_ob.modifiers.length() > 0 && experimental) {
BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length() - 1];
bool enabled = preview ? mod.show_viewport() : mod.show_render();
@@ -671,40 +681,6 @@ static inline uint object_ray_visibility(BL::Object &b_ob)
return flag;
}
/* Check whether some of "built-in" motion-related attributes are needed to be exported (includes
* things like velocity from cache modifier, fluid simulation).
*
* NOTE: This code is run prior to object motion blur initialization. so can not access properties
* set by `sync_object_motion_init()`. */
static inline bool object_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene)
{
const Scene::MotionType need_motion = scene->need_motion();
if (need_motion == Scene::MOTION_NONE) {
/* Simple case: neither motion pass nor motion blur is needed, no need in the motion related
* attributes. */
return false;
}
if (need_motion == Scene::MOTION_BLUR) {
/* A bit tricky and implicit case:
* - Motion blur is enabled in the scene, which implies specific number of time steps for
* objects.
* - If the object has motion blur disabled on it, it will have 0 time steps.
* - Motion attribute expects non-zero time steps.
*
* Avoid adding motion attributes if the motion blur will enforce 0 motion steps. */
PointerRNA cobject = RNA_pointer_get(&b_ob_info.real_object.ptr, "cycles");
const bool use_motion = get_boolean(cobject, "use_motion_blur");
if (!use_motion) {
return false;
}
}
/* Motion pass which implies 3 motion steps, or motion blur which is not disabled on object
* level. */
return true;
}
class EdgeMap {
public:
EdgeMap()

View File

@@ -33,17 +33,6 @@ set(SRC
unaligned.cpp
)
set(SRC_METAL
metal.mm
)
if(WITH_CYCLES_DEVICE_METAL)
list(APPEND SRC
${SRC_METAL}
)
add_definitions(-DWITH_METAL)
endif()
set(SRC_HEADERS
bvh.h
bvh2.h
@@ -57,7 +46,6 @@ set(SRC_HEADERS
sort.h
split.h
unaligned.h
metal.h
)
set(LIB

View File

@@ -26,7 +26,6 @@
#include "scene/hair.h"
#include "scene/mesh.h"
#include "scene/object.h"
#include "scene/pointcloud.h"
#include "scene/scene.h"
#include "util/algorithm.h"
@@ -114,9 +113,9 @@ void BVHBuild::add_reference_triangles(BoundBox &root,
else {
/* Motion triangles, trace optimized case: we split triangle
* primitives into separate nodes for each of the time steps.
* This way we minimize overlap of neighbor triangle primitives.
* This way we minimize overlap of neighbor curve primitives.
*/
const int num_bvh_steps = params.num_motion_triangle_steps * 2 + 1;
const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
const size_t num_verts = mesh->verts.size();
const size_t num_steps = mesh->motion_steps;
@@ -270,101 +269,6 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair
}
}
void BVHBuild::add_reference_points(BoundBox &root,
BoundBox &center,
PointCloud *pointcloud,
int i)
{
const Attribute *point_attr_mP = NULL;
if (pointcloud->has_motion_blur()) {
point_attr_mP = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
}
const float3 *points_data = &pointcloud->points[0];
const float *radius_data = &pointcloud->radius[0];
const size_t num_points = pointcloud->num_points();
const float3 *motion_data = (point_attr_mP) ? point_attr_mP->data_float3() : NULL;
const size_t num_steps = pointcloud->get_motion_steps();
if (point_attr_mP == NULL) {
/* Really simple logic for static points. */
for (uint j = 0; j < num_points; j++) {
const PointCloud::Point point = pointcloud->get_point(j);
BoundBox bounds = BoundBox::empty;
point.bounds_grow(points_data, radius_data, bounds);
if (bounds.valid()) {
references.push_back(BVHReference(bounds, j, i, PRIMITIVE_POINT));
root.grow(bounds);
center.grow(bounds.center2());
}
}
}
else if (params.num_motion_point_steps == 0 || params.use_spatial_split) {
/* Simple case of motion points: single node for the whole
* shutter time. Lowest memory usage but less optimal
* rendering.
*/
/* TODO(sergey): Support motion steps for spatially split BVH. */
for (uint j = 0; j < num_points; j++) {
const PointCloud::Point point = pointcloud->get_point(j);
BoundBox bounds = BoundBox::empty;
point.bounds_grow(points_data, radius_data, bounds);
for (size_t step = 0; step < num_steps - 1; step++) {
point.bounds_grow(motion_data + step * num_points, radius_data, bounds);
}
if (bounds.valid()) {
references.push_back(BVHReference(bounds, j, i, PRIMITIVE_MOTION_POINT));
root.grow(bounds);
center.grow(bounds.center2());
}
}
}
else {
/* Motion points, trace optimized case: we split point
* primitives into separate nodes for each of the time steps.
* This way we minimize overlap of neighbor point primitives.
*/
const int num_bvh_steps = params.num_motion_point_steps * 2 + 1;
const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
for (uint j = 0; j < num_points; j++) {
const PointCloud::Point point = pointcloud->get_point(j);
const size_t num_steps = pointcloud->get_motion_steps();
const float3 *point_steps = point_attr_mP->data_float3();
/* Calculate bounding box of the previous time step.
* Will be reused later to avoid duplicated work on
* calculating BVH time step boundbox.
*/
float4 prev_key = point.motion_key(
points_data, radius_data, point_steps, num_points, num_steps, 0.0f, j);
BoundBox prev_bounds = BoundBox::empty;
point.bounds_grow(prev_key, prev_bounds);
/* Create all primitive time steps, */
for (int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
const float curr_time = (float)(bvh_step)*num_bvh_steps_inv_1;
float4 curr_key = point.motion_key(
points_data, radius_data, point_steps, num_points, num_steps, curr_time, j);
BoundBox curr_bounds = BoundBox::empty;
point.bounds_grow(curr_key, curr_bounds);
BoundBox bounds = prev_bounds;
bounds.grow(curr_bounds);
if (bounds.valid()) {
const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
references.push_back(
BVHReference(bounds, j, i, PRIMITIVE_MOTION_POINT, prev_time, curr_time));
root.grow(bounds);
center.grow(bounds.center2());
}
/* Current time boundbox becomes previous one for the
* next time step.
*/
prev_bounds = curr_bounds;
}
}
}
}
void BVHBuild::add_reference_geometry(BoundBox &root,
BoundBox &center,
Geometry *geom,
@@ -378,10 +282,6 @@ void BVHBuild::add_reference_geometry(BoundBox &root,
Hair *hair = static_cast<Hair *>(geom);
add_reference_curves(root, center, hair, object_index);
}
else if (geom->geometry_type == Geometry::POINTCLOUD) {
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
add_reference_points(root, center, pointcloud, object_index);
}
}
void BVHBuild::add_reference_object(BoundBox &root, BoundBox &center, Object *ob, int i)
@@ -411,10 +311,6 @@ static size_t count_primitives(Geometry *geom)
Hair *hair = static_cast<Hair *>(geom);
return count_curve_segments(hair);
}
else if (geom->geometry_type == Geometry::POINTCLOUD) {
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
return pointcloud->num_points();
}
return 0;
}
@@ -432,9 +328,8 @@ void BVHBuild::add_references(BVHRange &root)
if (!ob->get_geometry()->is_instanced()) {
num_alloc_references += count_primitives(ob->get_geometry());
}
else {
else
num_alloc_references++;
}
}
else {
num_alloc_references += count_primitives(ob->get_geometry());
@@ -499,7 +394,7 @@ BVHNode *BVHBuild::run()
spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha;
spatial_free_index = 0;
need_prim_time = params.use_motion_steps();
need_prim_time = params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0;
/* init progress updates */
double build_start_time;
@@ -640,8 +535,7 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange &range,
const vector<BVHReference> &references) const
{
size_t size = range.size();
size_t max_leaf_size = max(max(params.max_triangle_leaf_size, params.max_curve_leaf_size),
params.max_point_leaf_size);
size_t max_leaf_size = max(params.max_triangle_leaf_size, params.max_curve_leaf_size);
if (size > max_leaf_size)
return false;
@@ -650,44 +544,32 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange &range,
size_t num_motion_triangles = 0;
size_t num_curves = 0;
size_t num_motion_curves = 0;
size_t num_points = 0;
size_t num_motion_points = 0;
for (int i = 0; i < size; i++) {
const BVHReference &ref = references[range.start() + i];
if (ref.prim_type() & PRIMITIVE_CURVE) {
if (ref.prim_type() & PRIMITIVE_MOTION) {
if (ref.prim_type() & PRIMITIVE_ALL_CURVE) {
if (ref.prim_type() & PRIMITIVE_ALL_MOTION) {
num_motion_curves++;
}
else {
num_curves++;
}
}
else if (ref.prim_type() & PRIMITIVE_TRIANGLE) {
if (ref.prim_type() & PRIMITIVE_MOTION) {
else if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
if (ref.prim_type() & PRIMITIVE_ALL_MOTION) {
num_motion_triangles++;
}
else {
num_triangles++;
}
}
else if (ref.prim_type() & PRIMITIVE_POINT) {
if (ref.prim_type() & PRIMITIVE_MOTION) {
num_motion_points++;
}
else {
num_points++;
}
}
}
return (num_triangles <= params.max_triangle_leaf_size) &&
(num_motion_triangles <= params.max_motion_triangle_leaf_size) &&
(num_curves <= params.max_curve_leaf_size) &&
(num_motion_curves <= params.max_motion_curve_leaf_size) &&
(num_points <= params.max_point_leaf_size) &&
(num_motion_points <= params.max_motion_point_leaf_size);
(num_motion_curves <= params.max_motion_curve_leaf_size);
}
/* multithreaded binning builder */
@@ -973,7 +855,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
for (int i = 0; i < range.size(); i++) {
const BVHReference &ref = references[range.start() + i];
if (ref.prim_index() != -1) {
uint32_t type_index = PRIMITIVE_INDEX(ref.prim_type() & PRIMITIVE_ALL);
uint32_t type_index = bitscan((uint32_t)(ref.prim_type() & PRIMITIVE_ALL));
p_ref[type_index].push_back(ref);
p_type[type_index].push_back(ref.prim_type());
p_index[type_index].push_back(ref.prim_index());

View File

@@ -39,7 +39,6 @@ class Geometry;
class Hair;
class Mesh;
class Object;
class PointCloud;
class Progress;
/* BVH Builder */
@@ -69,7 +68,6 @@ class BVHBuild {
/* Adding references. */
void add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *mesh, int i);
void add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair, int i);
void add_reference_points(BoundBox &root, BoundBox &center, PointCloud *pointcloud, int i);
void add_reference_geometry(BoundBox &root, BoundBox &center, Geometry *geom, int i);
void add_reference_object(BoundBox &root, BoundBox &center, Object *ob, int i);
void add_references(BVHRange &root);

View File

@@ -19,7 +19,6 @@
#include "bvh/bvh2.h"
#include "bvh/embree.h"
#include "bvh/metal.h"
#include "bvh/multi.h"
#include "bvh/optix.h"
@@ -41,12 +40,8 @@ const char *bvh_layout_name(BVHLayout layout)
return "EMBREE";
case BVH_LAYOUT_OPTIX:
return "OPTIX";
case BVH_LAYOUT_METAL:
return "METAL";
case BVH_LAYOUT_MULTI_OPTIX:
case BVH_LAYOUT_MULTI_METAL:
case BVH_LAYOUT_MULTI_OPTIX_EMBREE:
case BVH_LAYOUT_MULTI_METAL_EMBREE:
return "MULTI";
case BVH_LAYOUT_ALL:
return "ALL";
@@ -107,18 +102,9 @@ BVH *BVH::create(const BVHParams &params,
#else
(void)device;
break;
#endif
case BVH_LAYOUT_METAL:
#ifdef WITH_METAL
return bvh_metal_create(params, geometry, objects, device);
#else
(void)device;
break;
#endif
case BVH_LAYOUT_MULTI_OPTIX:
case BVH_LAYOUT_MULTI_METAL:
case BVH_LAYOUT_MULTI_OPTIX_EMBREE:
case BVH_LAYOUT_MULTI_METAL_EMBREE:
return new BVHMulti(params, geometry, objects);
case BVH_LAYOUT_NONE:
case BVH_LAYOUT_ALL:

View File

@@ -20,7 +20,6 @@
#include "scene/hair.h"
#include "scene/mesh.h"
#include "scene/object.h"
#include "scene/pointcloud.h"
#include "bvh/build.h"
#include "bvh/node.h"
@@ -387,7 +386,7 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
}
else {
/* Primitives. */
if (pack.prim_type[prim] & PRIMITIVE_CURVE) {
if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* Curves. */
const Hair *hair = static_cast<const Hair *>(ob->get_geometry());
int prim_offset = (params.top_level) ? hair->prim_offset : 0;
@@ -410,30 +409,6 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
}
}
}
else if (pack.prim_type[prim] & PRIMITIVE_POINT) {
/* Points. */
const PointCloud *pointcloud = static_cast<const PointCloud *>(ob->get_geometry());
int prim_offset = (params.top_level) ? pointcloud->prim_offset : 0;
const float3 *points = &pointcloud->points[0];
const float *radius = &pointcloud->radius[0];
PointCloud::Point point = pointcloud->get_point(pidx - prim_offset);
point.bounds_grow(points, radius, bbox);
/* Motion points. */
if (pointcloud->get_use_motion_blur()) {
Attribute *attr = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr) {
size_t pointcloud_size = pointcloud->points.size();
size_t steps = pointcloud->get_motion_steps() - 1;
float3 *point_steps = attr->data_float3();
for (size_t i = 0; i < steps; i++)
point.bounds_grow(point_steps + i * pointcloud_size, radius, bbox);
}
}
}
else {
/* Triangles. */
const Mesh *mesh = static_cast<const Mesh *>(ob->get_geometry());
@@ -530,8 +505,7 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
pack.leaf_nodes.resize(leaf_nodes_size);
pack.object_node.resize(objects.size());
if (params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0 ||
params.num_motion_point_steps > 0) {
if (params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0) {
pack.prim_time.resize(prim_index_size);
}
@@ -590,7 +564,13 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
float2 *bvh_prim_time = bvh->pack.prim_time.size() ? &bvh->pack.prim_time[0] : NULL;
for (size_t i = 0; i < bvh_prim_index_size; i++) {
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
}
else {
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
}
pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances

View File

@@ -45,7 +45,6 @@
# include "scene/hair.h"
# include "scene/mesh.h"
# include "scene/object.h"
# include "scene/pointcloud.h"
# include "util/foreach.h"
# include "util/log.h"
@@ -91,7 +90,7 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
++ctx->num_hits;
/* Always use baked shadow transparency for curves. */
if (current_isect.type & PRIMITIVE_CURVE) {
if (current_isect.type & PRIMITIVE_ALL_CURVE) {
ctx->throughput *= intersection_curve_shadow_transparency(
kg, current_isect.object, current_isect.prim, current_isect.u);
@@ -246,7 +245,7 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
}
}
static void rtc_filter_func_backface_cull(const RTCFilterFunctionNArguments *args)
static void rtc_filter_func_thick_curve(const RTCFilterFunctionNArguments *args)
{
const RTCRay *ray = (RTCRay *)args->ray;
RTCHit *hit = (RTCHit *)args->hit;
@@ -259,7 +258,7 @@ static void rtc_filter_func_backface_cull(const RTCFilterFunctionNArguments *arg
}
}
static void rtc_filter_occluded_func_backface_cull(const RTCFilterFunctionNArguments *args)
static void rtc_filter_occluded_func_thick_curve(const RTCFilterFunctionNArguments *args)
{
const RTCRay *ray = (RTCRay *)args->ray;
RTCHit *hit = (RTCHit *)args->hit;
@@ -304,7 +303,7 @@ static void rtc_error_func(void *, enum RTCError, const char *str)
VLOG(1) << str;
}
static double progress_start_time = 0.0;
static double progress_start_time = 0.0f;
static bool rtc_progress_func(void *user_ptr, const double n)
{
@@ -411,12 +410,6 @@ void BVHEmbree::add_object(Object *ob, int i)
add_curves(ob, hair, i);
}
}
else if (geom->geometry_type == Geometry::POINTCLOUD) {
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
if (pointcloud->num_points() > 0) {
add_points(ob, pointcloud, i);
}
}
}
void BVHEmbree::add_instance(Object *ob, int i)
@@ -631,89 +624,6 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c
}
}
void BVHEmbree::set_point_vertex_buffer(RTCGeometry geom_id,
const PointCloud *pointcloud,
const bool update)
{
const Attribute *attr_mP = NULL;
size_t num_motion_steps = 1;
if (pointcloud->has_motion_blur()) {
attr_mP = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr_mP) {
num_motion_steps = pointcloud->get_motion_steps();
}
}
const size_t num_points = pointcloud->num_points();
/* Copy the point data to Embree */
const int t_mid = (num_motion_steps - 1) / 2;
const float *radius = pointcloud->get_radius().data();
for (int t = 0; t < num_motion_steps; ++t) {
const float3 *verts;
if (t == t_mid || attr_mP == NULL) {
verts = pointcloud->get_points().data();
}
else {
int t_ = (t > t_mid) ? (t - 1) : t;
verts = &attr_mP->data_float3()[t_ * num_points];
}
float4 *rtc_verts = (update) ? (float4 *)rtcGetGeometryBufferData(
geom_id, RTC_BUFFER_TYPE_VERTEX, t) :
(float4 *)rtcSetNewGeometryBuffer(geom_id,
RTC_BUFFER_TYPE_VERTEX,
t,
RTC_FORMAT_FLOAT4,
sizeof(float) * 4,
num_points);
assert(rtc_verts);
if (rtc_verts) {
for (size_t j = 0; j < num_points; ++j) {
rtc_verts[j] = float3_to_float4(verts[j]);
rtc_verts[j].w = radius[j];
}
}
if (update) {
rtcUpdateGeometryBuffer(geom_id, RTC_BUFFER_TYPE_VERTEX, t);
}
}
}
void BVHEmbree::add_points(const Object *ob, const PointCloud *pointcloud, int i)
{
size_t prim_offset = pointcloud->prim_offset;
const Attribute *attr_mP = NULL;
size_t num_motion_steps = 1;
if (pointcloud->has_motion_blur()) {
attr_mP = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr_mP) {
num_motion_steps = pointcloud->get_motion_steps();
}
}
enum RTCGeometryType type = RTC_GEOMETRY_TYPE_SPHERE_POINT;
RTCGeometry geom_id = rtcNewGeometry(rtc_device, type);
rtcSetGeometryBuildQuality(geom_id, build_quality);
rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
set_point_vertex_buffer(geom_id, pointcloud, false);
rtcSetGeometryUserData(geom_id, (void *)prim_offset);
rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func_backface_cull);
rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func_backface_cull);
rtcSetGeometryMask(geom_id, ob->visibility_for_tracing());
rtcCommitGeometry(geom_id);
rtcAttachGeometryByID(scene, geom_id, i * 2);
rtcReleaseGeometry(geom_id);
}
void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
{
size_t prim_offset = hair->curve_segment_offset;
@@ -768,8 +678,8 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func);
}
else {
rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func_backface_cull);
rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func_backface_cull);
rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func_thick_curve);
rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func_thick_curve);
}
rtcSetGeometryMask(geom_id, ob->visibility_for_tracing());
@@ -806,14 +716,6 @@ void BVHEmbree::refit(Progress &progress)
rtcCommitGeometry(geom);
}
}
else if (geom->geometry_type == Geometry::POINTCLOUD) {
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
if (pointcloud->num_points() > 0) {
RTCGeometry geom = rtcGetGeometry(scene, geom_id);
set_point_vertex_buffer(geom, pointcloud, true);
rtcCommitGeometry(geom);
}
}
}
geom_id += 2;
}

View File

@@ -33,7 +33,6 @@ CCL_NAMESPACE_BEGIN
class Hair;
class Mesh;
class PointCloud;
class BVHEmbree : public BVH {
public:
@@ -52,15 +51,11 @@ class BVHEmbree : public BVH {
void add_object(Object *ob, int i);
void add_instance(Object *ob, int i);
void add_curves(const Object *ob, const Hair *hair, int i);
void add_points(const Object *ob, const PointCloud *pointcloud, int i);
void add_triangles(const Object *ob, const Mesh *mesh, int i);
private:
void set_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh, const bool update);
void set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, const bool update);
void set_point_vertex_buffer(RTCGeometry geom_id,
const PointCloud *pointcloud,
const bool update);
RTCDevice rtc_device;
enum RTCBuildQuality build_quality;

View File

@@ -1,35 +0,0 @@
/*
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __BVH_METAL_H__
#define __BVH_METAL_H__
#ifdef WITH_METAL
# include "bvh/bvh.h"
CCL_NAMESPACE_BEGIN
BVH *bvh_metal_create(const BVHParams &params,
const vector<Geometry *> &geometry,
const vector<Object *> &objects,
Device *device);
CCL_NAMESPACE_END
#endif /* WITH_METAL */
#endif /* __BVH_METAL_H__ */

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef WITH_METAL
# include "device/metal/bvh.h"
CCL_NAMESPACE_BEGIN
BVH *bvh_metal_create(const BVHParams &params,
const vector<Geometry *> &geometry,
const vector<Object *> &objects,
Device *device)
{
return new BVHMetal(params, geometry, objects, device);
}
CCL_NAMESPACE_END
#endif /* WITH_METAL */

View File

@@ -153,7 +153,7 @@ void BVHNode::update_time()
namespace {
struct DumpTraversalContext {
/* Descriptor of while where writing is happening. */
/* Descriptor of wile where writing is happening. */
FILE *stream;
/* Unique identifier of the node current. */
int id;

View File

@@ -178,7 +178,7 @@ class InnerNode : public BVHNode {
reset_unused_children();
}
/* NOTE: This function is only used during binary BVH builder, and it's
/* NOTE: This function is only used during binary BVH builder, and it
* supposed to be configured to have 2 children which will be filled-in in a
* bit. But this is important to have children reset to NULL. */
explicit InnerNode(const BoundBox &bounds) : BVHNode(bounds), num_children_(0)

View File

@@ -30,17 +30,15 @@ BVHOptiX::BVHOptiX(const BVHParams &params_,
: BVH(params_, geometry_, objects_),
device(device),
traversable_handle(0),
as_data(make_unique<device_only_memory<char>>(
device, params.top_level ? "optix tlas" : "optix blas", false)),
motion_transform_data(
make_unique<device_only_memory<char>>(device, "optix motion transform", false))
as_data(device, params_.top_level ? "optix tlas" : "optix blas", false),
motion_transform_data(device, "optix motion transform", false)
{
}
BVHOptiX::~BVHOptiX()
{
/* Acceleration structure memory is delayed freed on device, since deleting the
* BVH may happen while still being used for rendering. */
// Acceleration structure memory is delayed freed on device, since deleting the
// BVH may happen while still being used for rendering.
device->release_optix_bvh(this);
}

View File

@@ -25,16 +25,14 @@
# include "device/memory.h"
# include "util/unique_ptr.h"
CCL_NAMESPACE_BEGIN
class BVHOptiX : public BVH {
public:
Device *device;
uint64_t traversable_handle;
unique_ptr<device_only_memory<char>> as_data;
unique_ptr<device_only_memory<char>> motion_transform_data;
device_only_memory<char> as_data;
device_only_memory<char> motion_transform_data;
protected:
friend class BVH;

View File

@@ -83,8 +83,6 @@ class BVHParams {
int max_motion_triangle_leaf_size;
int max_curve_leaf_size;
int max_motion_curve_leaf_size;
int max_point_leaf_size;
int max_motion_point_leaf_size;
/* object or mesh level bvh */
bool top_level;
@@ -100,13 +98,13 @@ class BVHParams {
/* Split time range to this number of steps and create leaf node for each
* of this time steps.
*
* Speeds up rendering of motion primitives in the cost of higher memory usage.
* Speeds up rendering of motion curve primitives in the cost of higher
* memory usage.
*/
int num_motion_curve_steps;
/* Same as above, but for triangle primitives. */
int num_motion_triangle_steps;
int num_motion_curve_steps;
int num_motion_point_steps;
/* Same as in SceneParams. */
int bvh_type;
@@ -134,8 +132,6 @@ class BVHParams {
max_motion_triangle_leaf_size = 8;
max_curve_leaf_size = 1;
max_motion_curve_leaf_size = 4;
max_point_leaf_size = 8;
max_motion_point_leaf_size = 8;
top_level = false;
bvh_layout = BVH_LAYOUT_BVH2;
@@ -143,7 +139,6 @@ class BVHParams {
num_motion_curve_steps = 0;
num_motion_triangle_steps = 0;
num_motion_point_steps = 0;
bvh_type = 0;
@@ -171,12 +166,6 @@ class BVHParams {
return (size <= min_leaf_size || level >= MAX_DEPTH);
}
bool use_motion_steps()
{
return num_motion_curve_steps > 0 || num_motion_triangle_steps > 0 ||
num_motion_point_steps > 0;
}
/* Gets best matching BVH.
*
* If the requested layout is supported by the device, it will be used.

View File

@@ -23,7 +23,6 @@
#include "scene/hair.h"
#include "scene/mesh.h"
#include "scene/object.h"
#include "scene/pointcloud.h"
#include "util/algorithm.h"
@@ -427,32 +426,6 @@ void BVHSpatialSplit::split_curve_primitive(const Hair *hair,
}
}
void BVHSpatialSplit::split_point_primitive(const PointCloud *pointcloud,
const Transform *tfm,
int prim_index,
int dim,
float pos,
BoundBox &left_bounds,
BoundBox &right_bounds)
{
/* No real splitting support for points, assume they are small enough for it
* not to matter. */
float3 point = pointcloud->get_points()[prim_index];
if (tfm != NULL) {
point = transform_point(tfm, point);
}
point = get_unaligned_point(point);
if (point[dim] <= pos) {
left_bounds.grow(point);
}
if (point[dim] >= pos) {
right_bounds.grow(point);
}
}
void BVHSpatialSplit::split_triangle_reference(const BVHReference &ref,
const Mesh *mesh,
int dim,
@@ -480,16 +453,6 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference &ref,
right_bounds);
}
void BVHSpatialSplit::split_point_reference(const BVHReference &ref,
const PointCloud *pointcloud,
int dim,
float pos,
BoundBox &left_bounds,
BoundBox &right_bounds)
{
split_point_primitive(pointcloud, NULL, ref.prim_index(), dim, pos, left_bounds, right_bounds);
}
void BVHSpatialSplit::split_object_reference(
const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
{
@@ -512,13 +475,6 @@ void BVHSpatialSplit::split_object_reference(
}
}
}
else if (geom->geometry_type == Geometry::POINTCLOUD) {
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
for (int point_idx = 0; point_idx < pointcloud->num_points(); ++point_idx) {
split_point_primitive(
pointcloud, &object->get_tfm(), point_idx, dim, pos, left_bounds, right_bounds);
}
}
}
void BVHSpatialSplit::split_reference(const BVHBuild &builder,
@@ -535,18 +491,14 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder,
/* loop over vertices/edges. */
const Object *ob = builder.objects[ref.prim_object()];
if (ref.prim_type() & PRIMITIVE_TRIANGLE) {
if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
Mesh *mesh = static_cast<Mesh *>(ob->get_geometry());
split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds);
}
else if (ref.prim_type() & PRIMITIVE_CURVE) {
else if (ref.prim_type() & PRIMITIVE_ALL_CURVE) {
Hair *hair = static_cast<Hair *>(ob->get_geometry());
split_curve_reference(ref, hair, dim, pos, left_bounds, right_bounds);
}
else if (ref.prim_type() & PRIMITIVE_POINT) {
PointCloud *pointcloud = static_cast<PointCloud *>(ob->get_geometry());
split_point_reference(ref, pointcloud, dim, pos, left_bounds, right_bounds);
}
else {
split_object_reference(ob, dim, pos, left_bounds, right_bounds);
}

View File

@@ -26,7 +26,6 @@ CCL_NAMESPACE_BEGIN
class BVHBuild;
class Hair;
class Mesh;
class PointCloud;
struct Transform;
/* Object Split */
@@ -124,13 +123,6 @@ class BVHSpatialSplit {
float pos,
BoundBox &left_bounds,
BoundBox &right_bounds);
void split_point_primitive(const PointCloud *pointcloud,
const Transform *tfm,
int prim_index,
int dim,
float pos,
BoundBox &left_bounds,
BoundBox &right_bounds);
/* Lower-level functions which calculates boundaries of left and right nodes
* needed for spatial split.
@@ -149,12 +141,6 @@ class BVHSpatialSplit {
float pos,
BoundBox &left_bounds,
BoundBox &right_bounds);
void split_point_reference(const BVHReference &ref,
const PointCloud *pointcloud,
int dim,
float pos,
BoundBox &left_bounds,
BoundBox &right_bounds);
void split_object_reference(
const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds);

View File

@@ -69,7 +69,7 @@ bool BVHUnaligned::compute_aligned_space(const BVHReference &ref, Transform *ali
const int packed_type = ref.prim_type();
const int type = (packed_type & PRIMITIVE_ALL);
/* No motion blur curves here, we can't fit them to aligned boxes well. */
if ((type & PRIMITIVE_CURVE) && !(type & PRIMITIVE_MOTION)) {
if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) {
const int curve_index = ref.prim_index();
const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
const Hair *hair = static_cast<const Hair *>(object->get_geometry());
@@ -95,7 +95,7 @@ BoundBox BVHUnaligned::compute_aligned_prim_boundbox(const BVHReference &prim,
const int packed_type = prim.prim_type();
const int type = (packed_type & PRIMITIVE_ALL);
/* No motion blur curves here, we can't fit them to aligned boxes well. */
if ((type & PRIMITIVE_CURVE) && !(type & PRIMITIVE_MOTION)) {
if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) {
const int curve_index = prim.prim_index();
const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
const Hair *hair = static_cast<const Hair *>(object->get_geometry());

View File

@@ -551,23 +551,4 @@ if(NOT WITH_HIP_DYNLOAD)
set(WITH_HIP_DYNLOAD ON)
endif()
###########################################################################
# Metal
###########################################################################
if(WITH_CYCLES_DEVICE_METAL)
find_library(METAL_LIBRARY Metal)
# This file was added in the 12.0 SDK, use it as a way to detect the version.
if (METAL_LIBRARY AND NOT EXISTS "${METAL_LIBRARY}/Headers/MTLFunctionStitching.h")
message(STATUS "Metal version too old, must be SDK 12.0 or newer, disabling WITH_CYCLES_DEVICE_METAL")
set(WITH_CYCLES_DEVICE_METAL OFF)
elseif (NOT METAL_LIBRARY)
message(STATUS "Metal not found, disabling WITH_CYCLES_DEVICE_METAL")
set(WITH_CYCLES_DEVICE_METAL OFF)
else()
message(STATUS "Found Metal: ${METAL_LIBRARY}")
endif()
endif()
unset(_cycles_lib_dir)

View File

@@ -88,7 +88,7 @@ endmacro()
function(cycles_link_directories)
if(APPLE)
# APPLE platform uses full paths for linking libraries, and avoids link_directories.
# APPLE plaform uses full paths for linking libraries, and avoids link_directories.
return()
endif()
@@ -168,6 +168,12 @@ macro(cycles_target_link_libraries target)
target_link_libraries(${target} extern_hipew)
endif()
if(CYCLES_STANDALONE_REPOSITORY)
target_link_libraries(${target} extern_numaapi)
else()
target_link_libraries(${target} bf_intern_numaapi)
endif()
if(UNIX AND NOT APPLE)
if(CYCLES_STANDALONE_REPOSITORY)
target_link_libraries(${target} extern_libc_compat)

View File

@@ -43,7 +43,7 @@ if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
add_definitions(-DWITH_HIP_DYNLOAD)
endif()
set(SRC_BASE
set(SRC
device.cpp
denoise.cpp
graphics_interop.cpp
@@ -104,21 +104,6 @@ set(SRC_MULTI
multi/device.h
)
set(SRC_METAL
metal/bvh.mm
metal/bvh.h
metal/device.mm
metal/device.h
metal/device_impl.mm
metal/device_impl.h
metal/kernel.mm
metal/kernel.h
metal/queue.mm
metal/queue.h
metal/util.mm
metal/util.h
)
set(SRC_OPTIX
optix/device.cpp
optix/device.h
@@ -138,17 +123,6 @@ set(SRC_HEADERS
queue.h
)
set(SRC
${SRC_BASE}
${SRC_CPU}
${SRC_CUDA}
${SRC_HIP}
${SRC_DUMMY}
${SRC_MULTI}
${SRC_OPTIX}
${SRC_HEADERS}
)
set(LIB
cycles_kernel
cycles_util
@@ -184,15 +158,6 @@ endif()
if(WITH_CYCLES_DEVICE_OPTIX)
add_definitions(-DWITH_OPTIX)
endif()
if(WITH_CYCLES_DEVICE_METAL)
list(APPEND LIB
${METAL_LIBRARY}
)
add_definitions(-DWITH_METAL)
list(APPEND SRC
${SRC_METAL}
)
endif()
if(WITH_OPENIMAGEDENOISE)
list(APPEND LIB
@@ -203,12 +168,20 @@ endif()
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
cycles_add_library(cycles_device "${LIB}" ${SRC})
cycles_add_library(cycles_device "${LIB}"
${SRC}
${SRC_CPU}
${SRC_CUDA}
${SRC_HIP}
${SRC_DUMMY}
${SRC_MULTI}
${SRC_OPTIX}
${SRC_HEADERS}
)
source_group("cpu" FILES ${SRC_CPU})
source_group("cuda" FILES ${SRC_CUDA})
source_group("dummy" FILES ${SRC_DUMMY})
source_group("multi" FILES ${SRC_MULTI})
source_group("metal" FILES ${SRC_METAL})
source_group("optix" FILES ${SRC_OPTIX})
source_group("common" FILES ${SRC} ${SRC_HEADERS})

View File

@@ -38,6 +38,7 @@ void device_cpu_info(vector<DeviceInfo> &devices)
info.id = "CPU";
info.num = 0;
info.has_osl = true;
info.has_half_images = true;
info.has_nanovdb = true;
info.has_profiling = true;
if (openimagedenoise_supported()) {

View File

@@ -68,8 +68,8 @@ CPUDevice::CPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_
{
/* Pick any kernel, all of them are supposed to have same level of microarchitecture
* optimization. */
VLOG(1) << "Using " << get_cpu_kernels().integrator_init_from_camera.get_uarch_name()
<< " CPU kernels.";
VLOG(1) << "Will be using " << kernels.integrator_init_from_camera.get_uarch_name()
<< " kernels.";
if (info.cpu_threads == 0) {
info.cpu_threads = TaskScheduler::num_threads();
@@ -93,6 +93,11 @@ CPUDevice::~CPUDevice()
texture_info.free();
}
bool CPUDevice::show_samples() const
{
return (info.cpu_threads == 1);
}
BVHLayoutMask CPUDevice::get_bvh_layout_mask() const
{
BVHLayoutMask bvh_layout_mask = BVH_LAYOUT_BVH2;
@@ -129,7 +134,8 @@ void CPUDevice::mem_alloc(device_memory &mem)
<< string_human_readable_size(mem.memory_size()) << ")";
}
if (mem.type == MEM_DEVICE_ONLY || !mem.host_pointer) {
if (mem.type == MEM_DEVICE_ONLY) {
assert(!mem.host_pointer);
size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES;
void *data = util_aligned_malloc(mem.memory_size(), alignment);
mem.device_pointer = (device_ptr)data;
@@ -188,7 +194,7 @@ void CPUDevice::mem_free(device_memory &mem)
tex_free((device_texture &)mem);
}
else if (mem.device_pointer) {
if (mem.type == MEM_DEVICE_ONLY || !mem.host_pointer) {
if (mem.type == MEM_DEVICE_ONLY) {
util_aligned_free((void *)mem.device_pointer);
}
mem.device_pointer = 0;
@@ -273,8 +279,7 @@ void CPUDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
{
#ifdef WITH_EMBREE
if (bvh->params.bvh_layout == BVH_LAYOUT_EMBREE ||
bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE ||
bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL_EMBREE) {
bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE) {
BVHEmbree *const bvh_embree = static_cast<BVHEmbree *>(bvh);
if (refit) {
bvh_embree->refit(progress);
@@ -292,6 +297,11 @@ void CPUDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
Device::build_bvh(bvh, progress, refit);
}
const CPUKernels *CPUDevice::get_cpu_kernels() const
{
return &kernels;
}
void CPUDevice::get_cpu_kernel_thread_globals(
vector<CPUKernelThreadGlobals> &kernel_thread_globals)
{

View File

@@ -57,9 +57,13 @@ class CPUDevice : public Device {
RTCDevice embree_device;
#endif
CPUKernels kernels;
CPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_);
~CPUDevice();
virtual bool show_samples() const override;
virtual BVHLayoutMask get_bvh_layout_mask() const override;
/* Returns true if the texture info was copied to the device (meaning, some more
@@ -86,6 +90,7 @@ class CPUDevice : public Device {
void build_bvh(BVH *bvh, Progress &progress, bool refit) override;
virtual const CPUKernels *get_cpu_kernels() const override;
virtual void get_cpu_kernel_thread_globals(
vector<CPUKernelThreadGlobals> &kernel_thread_globals) override;
virtual void *get_cpu_osl_memory() override;

Some files were not shown because too many files have changed in this diff Show More