From 807aefd6234f7349d1bef2579def24c8bba9f31f Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 6 Feb 2020 10:23:55 +0100 Subject: Fix (unreported) timeline missing refresh on VSE selection change Keyframes and channels were not updating immediately (you had to enter channel and main regions with the mouse to force a redraw). Differential Revision: https://developer.blender.org/D6762 --- source/blender/editors/space_action/space_action.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 901efbdf0ff..f06b1a02675 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -546,6 +546,12 @@ static void action_listener(wmWindow *UNUSED(win), break; case NC_SCENE: switch (wmn->data) { + case ND_SEQUENCER: + if (wmn->action == NA_SELECTED) { + saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC; + ED_area_tag_refresh(sa); + } + break; case ND_OB_ACTIVE: case ND_OB_SELECT: /* Selection changed, so force refresh to flush -- cgit v1.2.3 From b088d1e9969d440ffb7cc9614cef0ca81da46433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 15:56:02 +0100 Subject: Particle: Added sanity in particle system removal function Added a NULL check since psys_get_modifier() might also return a NULL pointer. --- source/blender/blenkernel/intern/particle.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 97fcef4fd27..eafd530b0d8 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3638,12 +3638,14 @@ void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob } } - /* clear modifier */ + /* Clear modifier, skip empty ones. */ psmd = psys_get_modifier(ob, psys); - BLI_remlink(&ob->modifiers, psmd); - modifier_free((ModifierData *)psmd); + if (psmd) { + BLI_remlink(&ob->modifiers, psmd); + modifier_free((ModifierData *)psmd); + } - /* clear particle system */ + /* Clear particle system. */ BLI_remlink(&ob->particlesystem, psys); if (psys->part) { id_us_min(&psys->part->id); -- cgit v1.2.3 From ae112a38ab8d5b6cb7fe8e9209aa7e0e0209a6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 15:59:10 +0100 Subject: Fluid: Removed UI locks for cache file types Caches that haven't been baked yet should not be locked. --- .../scripts/startup/bl_ui/properties_physics_fluid.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 28c9895f53b..2a918f0c58b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -680,7 +680,7 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings # Deactivate UI if guides are enabled but not baked yet. - layout.active = domain.use_noise and not self.check_domain_has_unbaked_guide(domain) + layout.enabled = domain.use_noise and not self.check_domain_has_unbaked_guide(domain) is_baking_any = domain.is_cache_baking_any has_baked_noise = domain.has_cache_baked_noise @@ -746,7 +746,7 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings # Deactivate UI if guides are enabled but not baked yet. - layout.active = domain.use_mesh and not self.check_domain_has_unbaked_guide(domain) + layout.enabled = domain.use_mesh and not self.check_domain_has_unbaked_guide(domain) is_baking_any = domain.is_cache_baking_any has_baked_mesh = domain.has_cache_baked_mesh @@ -818,7 +818,7 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings # Deactivate UI if guides are enabled but not baked yet. - layout.active = not self.check_domain_has_unbaked_guide(domain) + layout.enabled = not self.check_domain_has_unbaked_guide(domain) is_baking_any = domain.is_cache_baking_any has_baked_particles = domain.has_cache_baked_particles @@ -1072,7 +1072,10 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): domain = context.fluid.domain_settings is_baking_any = domain.is_cache_baking_any - has_baked_any = domain.has_cache_baked_any + has_baked_data = domain.has_cache_baked_data + has_baked_noise = domain.has_cache_baked_noise + has_baked_mesh = domain.has_cache_baked_mesh + has_baked_particles = domain.has_cache_baked_particles col = layout.column() col.prop(domain, "cache_directory", text="") @@ -1096,18 +1099,24 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): col.separator() col = flow.column() - col.enabled = not is_baking_any and not has_baked_any + col.enabled = not is_baking_any and not has_baked_data col.prop(domain, "cache_data_format", text="Data File Format") if md.domain_settings.domain_type in {'GAS'}: if domain.use_noise: + col = flow.column() + col.enabled = not is_baking_any and not has_baked_noise col.prop(domain, "cache_noise_format", text="Noise File Format") if md.domain_settings.domain_type in {'LIQUID'}: # File format for all particle systemes (FLIP and secondary) + col = flow.column() + col.enabled = not is_baking_any and not has_baked_particles col.prop(domain, "cache_particle_format", text="Particle File Format") if domain.use_mesh: + col = flow.column() + col.enabled = not is_baking_any and not has_baked_mesh col.prop(domain, "cache_mesh_format", text="Mesh File Format") if domain.cache_type == 'FINAL': -- cgit v1.2.3 From e7d71ce9cf1eb8ea73d5d77527fc65e7bd6f5d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 16:53:00 +0100 Subject: Fluid: Fixed slow cache loading for smoke data Cache files are currently loaded via the Manta Python API. With very big caches this can slow down the viewport playback. Especially smoke simulations, which just load grids and no meshes, can suffer from this. This fix solves this problem by directly loading the cache files from disk (no Python). This fix has been in the works for some time. The developer of this patch is ready to handle any potential fall-out of this patch quickly. --- intern/mantaflow/CMakeLists.txt | 29 ++ intern/mantaflow/extern/manta_fluid_API.h | 2 + intern/mantaflow/intern/MANTA_main.cpp | 418 +++++++++++++++++++++++++++- intern/mantaflow/intern/MANTA_main.h | 8 + intern/mantaflow/intern/manta_fluid_API.cpp | 14 + source/blender/blenkernel/intern/fluid.c | 25 +- 6 files changed, 488 insertions(+), 8 deletions(-) diff --git a/intern/mantaflow/CMakeLists.txt b/intern/mantaflow/CMakeLists.txt index c7b3c56c3c2..a3d891907a9 100644 --- a/intern/mantaflow/CMakeLists.txt +++ b/intern/mantaflow/CMakeLists.txt @@ -47,6 +47,35 @@ set(INC_SYS ${ZLIB_INCLUDE_DIRS} ) +if(WITH_TBB) + list(APPEND INC_SYS + ${TBB_INCLUDE_DIRS} + ) + list(APPEND LIB + ${TBB_LIBRARIES} + ) +endif() + +if(WITH_OPENVDB) + list(APPEND INC_SYS + ${BOOST_INCLUDE_DIR} + ${OPENEXR_INCLUDE_DIRS} + ${OPENVDB_INCLUDE_DIRS} + ) + list(APPEND LIB + ${OPENVDB_LIBRARIES} + ${OPENEXR_LIBRARIES} + ${ZLIB_LIBRARIES} + ${BOOST_LIBRARIES} + ) + if(WITH_OPENVDB_BLOSC) + list(APPEND LIB + ${BLOSC_LIBRARIES} + ${ZLIB_LIBRARIES} + ) + endif() +endif() + set(SRC intern/manta_python_API.cpp intern/manta_fluid_API.cpp diff --git a/intern/mantaflow/extern/manta_fluid_API.h b/intern/mantaflow/extern/manta_fluid_API.h index 8dc2cf1805a..4ebedeb5e38 100644 --- a/intern/mantaflow/extern/manta_fluid_API.h +++ b/intern/mantaflow/extern/manta_fluid_API.h @@ -55,6 +55,8 @@ int manta_update_mesh_structures(struct MANTA *fluid, struct FluidModifierData * int manta_update_particle_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); +int manta_update_smoke_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); +int manta_update_noise_structures(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_data(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_noise(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); int manta_bake_mesh(struct MANTA *fluid, struct FluidModifierData *mmd, int framenr); diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index 7f6ff9094c6..11b8fb820d6 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -27,6 +27,10 @@ #include #include +#if OPENVDB == 1 +# include "openvdb/openvdb.h" +#endif + #include "MANTA_main.h" #include "manta.h" #include "Python.h" @@ -1168,6 +1172,244 @@ int MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr) return 1; } +int MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr) +{ + if (MANTA::with_debug) + std::cout << "MANTA::updateGridStructures()" << std::endl; + + mSmokeFromFile = false; + + if (!mUsingSmoke) + return 0; + if (BLI_path_is_rel(mmd->domain->cache_directory)) + return 0; + + int result = 0; + int expected = 0; /* Expected number of read successes for this frame. */ + + std::ostringstream ss; + char cacheDir[FILE_MAX], targetFile[FILE_MAX]; + cacheDir[0] = '\0'; + targetFile[0] = '\0'; + + std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + BLI_path_join( + cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr); + + expected += 1; + ss.str(""); + ss << "density_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mDensity); + + expected += 1; + ss.str(""); + ss << "shadow_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mShadow); + + if (mUsingHeat) { + expected += 1; + ss.str(""); + ss << "heat_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mHeat); + } + + if (mUsingColors) { + expected += 3; + ss.str(""); + ss << "color_r_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorR); + + ss.str(""); + ss << "color_g_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorG); + + ss.str(""); + ss << "color_b_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorB); + } + + if (mUsingFire) { + expected += 3; + ss.str(""); + ss << "flame_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mFlame); + + ss.str(""); + ss << "fuel_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mFuel); + + ss.str(""); + ss << "react_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDir, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mReact); + } + + mSmokeFromFile = true; + return (result == expected) ? 1 : 0; +} + +int MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr) +{ + if (MANTA::with_debug) + std::cout << "MANTA::updateNoiseStructures()" << std::endl; + + mNoiseFromFile = false; + + if (!mUsingSmoke || !mUsingNoise) + return 0; + if (BLI_path_is_rel(mmd->domain->cache_directory)) + return 0; + + int result = 0; + int expected = 0; /* Expected number of read successes for this frame. */ + + std::ostringstream ss; + char cacheDirData[FILE_MAX], cacheDirNoise[FILE_MAX], targetFile[FILE_MAX]; + cacheDirData[0] = '\0'; + cacheDirNoise[0] = '\0'; + targetFile[0] = '\0'; + + std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format); + BLI_path_join(cacheDirData, + sizeof(cacheDirData), + mmd->domain->cache_directory, + FLUID_DOMAIN_DIR_DATA, + nullptr); + BLI_path_join(cacheDirNoise, + sizeof(cacheDirNoise), + mmd->domain->cache_directory, + FLUID_DOMAIN_DIR_NOISE, + nullptr); + + expected += 1; + ss.str(""); + ss << "density_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mDensityHigh); + + expected += 1; + ss.str(""); + ss << "shadow_####" << dformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirData, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mShadow); + + if (mUsingColors) { + expected += 3; + ss.str(""); + ss << "color_r_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorRHigh); + + ss.str(""); + ss << "color_g_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorGHigh); + + ss.str(""); + ss << "color_b_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mColorBHigh); + } + + if (mUsingFire) { + expected += 3; + ss.str(""); + ss << "flame_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mFlameHigh); + + ss.str(""); + ss << "fuel_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mFuelHigh); + + ss.str(""); + ss << "react_noise_####" << nformat; + BLI_join_dirfile(targetFile, sizeof(targetFile), cacheDirNoise, ss.str().c_str()); + BLI_path_frame(targetFile, framenr, 0); + if (!BLI_exists(targetFile)) { + return 0; + } + result += updateGridFromFile(targetFile, mReactHigh); + } + + mNoiseFromFile = true; + return (result == expected) ? 1 : 0; +} + /* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */ static std::string escapeSlashes(std::string const &s) { @@ -1194,7 +1436,7 @@ int MANTA::writeConfiguration(FluidModifierData *mmd, int framenr) cacheDir[0] = '\0'; targetFile[0] = '\0'; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + std::string dformat = ".uni"; BLI_path_join( cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_CONFIG, nullptr); @@ -1287,7 +1529,7 @@ int MANTA::readConfiguration(FluidModifierData *mmd, int framenr) targetFile[0] = '\0'; float dummy; - std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format); + std::string dformat = ".uni"; BLI_path_join( cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_CONFIG, nullptr); @@ -2533,6 +2775,174 @@ void MANTA::updateParticlesFromUni(const char *filename, bool isSecondarySys, bo gzclose(gzf); } +int MANTA::updateGridFromFile(const char *filename, float *grid) +{ + if (with_debug) + std::cout << "MANTA::updateGridFromFile()" << std::endl; + + if (!grid) { + std::cout << "MANTA::updateGridFromFile(): cannot read into uninitialized grid, grid is null" + << std::endl; + return 0; + } + + std::string fname(filename); + std::string::size_type idx; + + idx = fname.rfind('.'); + if (idx != std::string::npos) { + std::string extension = fname.substr(idx + 1); + + if (extension.compare("uni") == 0) + return updateGridFromUni(filename, grid); + else if (extension.compare("vdb") == 0) + return updateGridFromVDB(filename, grid); + else if (extension.compare("raw") == 0) + return updateGridFromRaw(filename, grid); + else + std::cerr << "MANTA::updateGridFromFile(): invalid file extension in file: " << filename + << std::endl; + return 0; + } + else { + std::cerr << "MANTA::updateGridFromFile(): unable to open file: " << filename << std::endl; + return 0; + } +} + +int MANTA::updateGridFromUni(const char *filename, float *grid) +{ + if (with_debug) + std::cout << "MANTA::updateGridFromUni()" << std::endl; + + gzFile gzf; + int ibuffer[4]; + + gzf = (gzFile)BLI_gzopen(filename, "rb1"); + if (!gzf) { + std::cout << "MANTA::updateGridFromUni(): unable to open file" << std::endl; + return 0; + } + + char ID[5] = {0, 0, 0, 0, 0}; + gzread(gzf, ID, 4); + + if (!strcmp(ID, "DDF2")) { + std::cout << "MANTA::updateGridFromUni(): grid uni file format DDF2 not supported anymore" + << std::endl; + return 0; + } + if (!strcmp(ID, "MNT1")) { + std::cout << "MANTA::updateGridFromUni(): grid uni file format MNT1 not supported anymore" + << std::endl; + return 0; + } + if (!strcmp(ID, "MNT2")) { + std::cout << "MANTA::updateGridFromUni(): grid uni file format MNT2 not supported anymore" + << std::endl; + return 0; + } + + // grid uni header + const int STR_LEN_GRID = 252; + int elementType, bytesPerElement; // data type info + char info[STR_LEN_GRID]; // mantaflow build information + int dimT; // optionally store forth dimension for 4d grids + unsigned long long timestamp; // creation time + + // read grid header + gzread(gzf, &ibuffer, sizeof(int) * 4); // dimX, dimY, dimZ, gridType + gzread(gzf, &elementType, sizeof(int)); + gzread(gzf, &bytesPerElement, sizeof(int)); + gzread(gzf, &info, sizeof(info)); + gzread(gzf, &dimT, sizeof(int)); + gzread(gzf, ×tamp, sizeof(unsigned long long)); + + if (with_debug) + std::cout << "read " << ibuffer[3] << " grid type in file: " << filename << std::endl; + + // Sanity checks + if (ibuffer[0] != mResX || ibuffer[1] != mResY || ibuffer[2] != mResZ) { + std::cout << "grid dim doesn't match, read: (" << ibuffer[0] << ", " << ibuffer[1] << ", " + << ibuffer[2] << ") vs setup: (" << mResX << ", " << mResY << ", " << mResZ << ")" + << std::endl; + return 0; + } + + // Actual data reading + if (!strcmp(ID, "MNT3")) { + gzread(gzf, grid, sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2]); + } + + if (with_debug) + std::cout << "read successfully: " << filename << std::endl; + + gzclose(gzf); + return 1; +} + +int MANTA::updateGridFromVDB(const char *filename, float *grid) +{ + if (with_debug) + std::cout << "MANTA::updateGridFromVDB()" << std::endl; + + openvdb::initialize(); + openvdb::io::File file(filename); + try { + file.open(); + } + catch (const openvdb::v5_1::IoError) { + std::cout << "MANTA::updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename + << std::endl; + return 0; + } + + openvdb::GridBase::Ptr baseGrid; + for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName(); + ++nameIter) { + baseGrid = file.readGrid(nameIter.gridName()); + break; + } + file.close(); + openvdb::FloatGrid::Ptr gridVDB = openvdb::gridPtrCast(baseGrid); + openvdb::FloatGrid::Accessor accessor = gridVDB->getAccessor(); + + size_t index = 0; + for (int z = 0; z < mResZ; ++z) { + for (int y = 0; y < mResY; ++y) { + for (int x = 0; x < mResX; ++x, ++index) { + openvdb::Coord xyz(x, y, z); + float v = accessor.getValue(xyz); + grid[index] = v; + } + } + } + return 1; +} + +int MANTA::updateGridFromRaw(const char *filename, float *grid) +{ + if (with_debug) + std::cout << "MANTA::updateGridFromRaw()" << std::endl; + + gzFile gzf; + int expectedBytes, readBytes; + + gzf = (gzFile)BLI_gzopen(filename, "rb"); + if (!gzf) { + std::cout << "MANTA::updateGridFromRaw(): unable to open file" << std::endl; + return 0; + } + + expectedBytes = sizeof(float) * mResX * mResY * mResZ; + readBytes = gzread(gzf, grid, expectedBytes); + + assert(expectedBytes == readBytes); + + gzclose(gzf); + return 1; +} + void MANTA::updatePointers() { if (with_debug) @@ -2660,7 +3070,9 @@ void MANTA::updatePointers() callPythonFunction("pLifeSnd" + parts_ext, func)); } - mFlipFromFile = true; + mFlipFromFile = false; mMeshFromFile = false; mParticlesFromFile = false; + mSmokeFromFile = false; + mNoiseFromFile = false; } diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h index f8d94e2631c..c1c2c042a73 100644 --- a/intern/mantaflow/intern/MANTA_main.h +++ b/intern/mantaflow/intern/MANTA_main.h @@ -93,6 +93,8 @@ struct MANTA { int updateMeshStructures(FluidModifierData *mmd, int framenr); int updateFlipStructures(FluidModifierData *mmd, int framenr); int updateParticleStructures(FluidModifierData *mmd, int framenr); + int updateSmokeStructures(FluidModifierData *mmd, int framenr); + int updateNoiseStructures(FluidModifierData *mmd, int framenr); void updateVariables(FluidModifierData *mmd); // Bake cache @@ -742,6 +744,8 @@ struct MANTA { bool mFlipFromFile; bool mMeshFromFile; bool mParticlesFromFile; + bool mSmokeFromFile; + bool mNoiseFromFile; int mResX; int mResY; @@ -852,8 +856,12 @@ struct MANTA { void updateMeshFromObj(const char *filename); void updateMeshFromUni(const char *filename); void updateParticlesFromUni(const char *filename, bool isSecondarySys, bool isVelData); + int updateGridFromUni(const char *filename, float *grid); + int updateGridFromVDB(const char *filename, float *grid); + int updateGridFromRaw(const char *filename, float *grid); void updateMeshFromFile(const char *filename); void updateParticlesFromFile(const char *filename, bool isSecondarySys, bool isVelData); + int updateGridFromFile(const char *filename, float *grid); }; #endif diff --git a/intern/mantaflow/intern/manta_fluid_API.cpp b/intern/mantaflow/intern/manta_fluid_API.cpp index 35f2ebbaf44..82bfed7cf61 100644 --- a/intern/mantaflow/intern/manta_fluid_API.cpp +++ b/intern/mantaflow/intern/manta_fluid_API.cpp @@ -143,6 +143,20 @@ int manta_update_particle_structures(MANTA *fluid, FluidModifierData *mmd, int f return fluid->updateParticleStructures(mmd, framenr); } +int manta_update_smoke_structures(MANTA *fluid, FluidModifierData *mmd, int framenr) +{ + if (!fluid || !mmd) + return 0; + return fluid->updateSmokeStructures(mmd, framenr); +} + +int manta_update_noise_structures(MANTA *fluid, FluidModifierData *mmd, int framenr) +{ + if (!fluid || !mmd) + return 0; + return fluid->updateNoiseStructures(mmd, framenr); +} + int manta_bake_data(MANTA *fluid, FluidModifierData *mmd, int framenr) { if (!fluid || !mmd) diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index f35aebbae16..8b959e30aff 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -3505,10 +3505,14 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, manta_needs_realloc(mds->fluid, mmd)) { BKE_fluid_reallocate_fluid(mds, mds->res, 1); } - has_noise = manta_read_noise(mds->fluid, mmd, noise_frame); + if (!baking_data && !baking_noise && !mode_replay) { + has_data = manta_update_noise_structures(mds->fluid, mmd, noise_frame); + } + else { + has_noise = manta_read_noise(mds->fluid, mmd, noise_frame); + } - /* In case of using the adaptive domain, copy all data that was read to a new fluid object. - */ + /* When using the adaptive domain, copy all data that was read to a new fluid object. */ if (with_adaptive && baking_noise) { /* Adaptive domain needs to know about current state, so save it, then copy. */ copy_v3_v3_int(o_res, mds->res); @@ -3521,7 +3525,13 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, mds, o_res, mds->res, o_min, mds->res_min, o_max, o_shift, mds->shift); } } - has_data = manta_read_data(mds->fluid, mmd, data_frame); + if (!baking_data && !baking_noise && !mode_replay) { + /* There is no need to call manta_update_smoke_structures() here. + * The noise cache has already been read with manta_update_noise_structures(). */ + } + else { + has_data = manta_read_data(mds->fluid, mmd, data_frame); + } } /* Read data cache only */ else { @@ -3532,7 +3542,12 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, BKE_fluid_reallocate_fluid(mds, mds->res, 1); } /* Read data cache */ - has_data = manta_read_data(mds->fluid, mmd, data_frame); + if (!baking_data && !baking_particles && !baking_mesh && !mode_replay) { + has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame); + } + else { + has_data = manta_read_data(mds->fluid, mmd, data_frame); + } } if (with_liquid) { if (!baking_data && !baking_particles && !baking_mesh && !mode_replay) { -- cgit v1.2.3 From 1bb702df1e1678b83a7238af2a28ecb73b4fb069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 17:24:09 +0100 Subject: OpenVDB: Fix IOError in try catch statement Broader exception handling for OpenVDB IO errors. --- intern/mantaflow/intern/MANTA_main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index 11b8fb820d6..798ad9c2854 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -2174,6 +2174,7 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) bool floater = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM; bool tracer = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_TRACER; bool obstacle = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE; + bool fractions = mmd->domain->flags & FLUID_DOMAIN_USE_FRACTIONS; bool guiding = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE; bool invel = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL; @@ -2210,6 +2211,8 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd) manta_script += fluid_alloc_guiding; if (obstacle) manta_script += fluid_alloc_obstacle; + if (fractions) + manta_script += fluid_alloc_fractions; if (invel) manta_script += fluid_alloc_invel; @@ -2891,7 +2894,7 @@ int MANTA::updateGridFromVDB(const char *filename, float *grid) try { file.open(); } - catch (const openvdb::v5_1::IoError) { + catch (const openvdb::IoError) { std::cout << "MANTA::updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename << std::endl; return 0; -- cgit v1.2.3 From f8756554180e583ea765eca4e3931d1bda84ebd9 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 6 Feb 2020 18:24:57 +0200 Subject: Reference correct sha1s of submodules --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 8a05b618f03..34d98762cef 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 8a05b618f031582c006c6f62b9e60619ab3eef8b +Subproject commit 34d98762cef85b9c065f21a051d1dbe3bf2979b7 diff --git a/release/scripts/addons b/release/scripts/addons index 1470f353c65..8b659917bae 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 1470f353c65034db91131d21ab9c782d029a2ee9 +Subproject commit 8b659917baecbea5471a05369aa754ae544a814b diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index ffbaca558a2..70b649775ee 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit ffbaca558a27bab4716bcd51ca7ea1df8e4f4b14 +Subproject commit 70b649775eeeebedb02c1c7b7aa996a7f6294177 -- cgit v1.2.3 From 921d74dd365661c52dd91dd12d29314ffd9f26ab Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 6 Feb 2020 16:24:19 +0100 Subject: NodeTree: Add access to the address of an ID's nodetree pointer. --- source/blender/blenkernel/BKE_node.h | 3 ++- source/blender/blenkernel/intern/node.c | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b599e1e1b2c..1c479c92ef5 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -387,7 +387,8 @@ struct bNodeTree *ntreeCopyTree(struct Main *bmain, const struct bNodeTree *ntre void ntreeUserIncrefID(struct bNodeTree *ntree); void ntreeUserDecrefID(struct bNodeTree *ntree); -struct bNodeTree *ntreeFromID(const struct ID *id); +struct bNodeTree **BKE_ntree_ptr_from_id(struct ID *id); +struct bNodeTree *ntreeFromID(struct ID *id); struct ID *BKE_node_tree_find_owner_ID(struct Main *bmain, struct bNodeTree *ntree); void ntreeMakeLocal(struct Main *bmain, diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 75e0d044c7c..94c06e46cb9 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2242,27 +2242,37 @@ void ntreeSetOutput(bNodeTree *ntree) * might be different for editor or for "real" use... */ } -/* Returns the private NodeTree object of the datablock, if it has one. */ -bNodeTree *ntreeFromID(const ID *id) +/** Get address of potential nodetree pointer of given ID. + * + * \warning Using this function directly is potentially dangerous, if you don't know or are not + * sure, please use `ntreeFromID()` instead. */ +bNodeTree **BKE_ntree_ptr_from_id(ID *id) { switch (GS(id->name)) { case ID_MA: - return ((const Material *)id)->nodetree; + return &((Material *)id)->nodetree; case ID_LA: - return ((const Light *)id)->nodetree; + return &((Light *)id)->nodetree; case ID_WO: - return ((const World *)id)->nodetree; + return &((World *)id)->nodetree; case ID_TE: - return ((const Tex *)id)->nodetree; + return &((Tex *)id)->nodetree; case ID_SCE: - return ((const Scene *)id)->nodetree; + return &((Scene *)id)->nodetree; case ID_LS: - return ((const FreestyleLineStyle *)id)->nodetree; + return &((FreestyleLineStyle *)id)->nodetree; default: return NULL; } } +/* Returns the private NodeTree object of the datablock, if it has one. */ +bNodeTree *ntreeFromID(ID *id) +{ + bNodeTree **nodetree = BKE_ntree_ptr_from_id(id); + return (nodetree != NULL) ? *nodetree : NULL; +} + /* Finds and returns the datablock that privately owns the given tree, or NULL. */ ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree) { -- cgit v1.2.3 From 7954e672c555037733b4ac298d558155d1862055 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 6 Feb 2020 16:25:15 +0100 Subject: Readfile: refactor/factorize more handling of common ID data. - Move handling of private ID data (nodetree and master_collection) under generic ID code. This shortens code a bit, but mostly avoids having to modify all type-specific callback functions if/when we have to add generic processing to IDs there. - Seriously factorize `expand_xxx` area, in the same way we were already doing in `direct_link_xxx` and `lib_link_xxx` areas. Note that this actually also fixes some bugs (at least, potential ones), like e.g. missing call to expand_id() for our beloved 'private ID' (nodetrees & co), in current master code... Differential Revision: https://developer.blender.org/D6764 --- source/blender/blenloader/intern/readfile.c | 422 +++++++++++----------------- 1 file changed, 161 insertions(+), 261 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 651f390d23e..c1a39711bf8 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2613,7 +2613,29 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p /** \name Read ID * \{ */ -static void lib_link_id(FileData *fd, Main *UNUSED(bmain), ID *id) +static void lib_link_id(FileData *fd, Main *bmain, ID *id); +static void lib_link_nodetree(FileData *fd, Main *bmain, bNodeTree *ntree); +static void lib_link_collection(FileData *fd, Main *bmain, Collection *collection); + +static void lib_link_id_private_id(FileData *fd, Main *bmain, ID *id) +{ + /* Handle 'private IDs'. */ + bNodeTree *nodetree = ntreeFromID(id); + if (nodetree != NULL) { + lib_link_id(fd, bmain, &nodetree->id); + lib_link_nodetree(fd, bmain, nodetree); + } + + if (GS(id->name) == ID_SCE) { + Scene *scene = (Scene *)id; + if (scene->master_collection != NULL) { + lib_link_id(fd, bmain, &scene->master_collection->id); + lib_link_collection(fd, bmain, scene->master_collection); + } + } +} + +static void lib_link_id(FileData *fd, Main *bmain, ID *id) { /* Note: WM IDProperties are never written to file, hence they should always be NULL here. */ BLI_assert((GS(id->name) != ID_WM) || id->properties == NULL); @@ -2628,6 +2650,8 @@ static void lib_link_id(FileData *fd, Main *UNUSED(bmain), ID *id) id->override_library->reference = newlibadr_us(fd, id->lib, id->override_library->reference); id->override_library->storage = newlibadr_us(fd, id->lib, id->override_library->storage); } + + lib_link_id_private_id(fd, bmain, id); } static void direct_link_id_override_property_operation_cb(FileData *fd, void *data) @@ -2646,6 +2670,30 @@ static void direct_link_id_override_property_cb(FileData *fd, void *data) link_list_ex(fd, &op->operations, direct_link_id_override_property_operation_cb); } +static void direct_link_id(FileData *fd, ID *id); +static void direct_link_nodetree(FileData *fd, bNodeTree *ntree); +static void direct_link_collection(FileData *fd, Collection *collection); + +static void direct_link_id_private_id(FileData *fd, ID *id) +{ + /* Handle 'private IDs'. */ + bNodeTree **nodetree = BKE_ntree_ptr_from_id(id); + if (nodetree != NULL && *nodetree != NULL) { + *nodetree = newdataadr(fd, *nodetree); + direct_link_id(fd, (ID *)*nodetree); + direct_link_nodetree(fd, *nodetree); + } + + if (GS(id->name) == ID_SCE) { + Scene *scene = (Scene *)id; + if (scene->master_collection != NULL) { + scene->master_collection = newdataadr(fd, scene->master_collection); + direct_link_id(fd, &scene->master_collection->id); + direct_link_collection(fd, scene->master_collection); + } + } +} + static void direct_link_id(FileData *fd, ID *id) { /*link direct data of ID properties*/ @@ -2685,6 +2733,9 @@ static void direct_link_id(FileData *fd, ID *id) if (drawdata) { BLI_listbase_clear((ListBase *)drawdata); } + + /* Handle 'private IDs'. */ + direct_link_id_private_id(fd, id); } /** \} */ @@ -3874,14 +3925,9 @@ static void direct_link_camera(FileData *fd, Camera *ca) /** \name Read ID: Light * \{ */ -static void lib_link_light(FileData *fd, Main *bmain, Light *la) +static void lib_link_light(FileData *fd, Main *UNUSED(bmain), Light *la) { la->ipo = newlibadr_us(fd, la->id.lib, la->ipo); // XXX deprecated - old animation system - - if (la->nodetree) { - lib_link_id(fd, bmain, &la->nodetree->id); - lib_link_ntree(fd, la->id.lib, la->nodetree); - } } static void direct_link_light(FileData *fd, Light *la) @@ -3894,12 +3940,6 @@ static void direct_link_light(FileData *fd, Light *la) direct_link_curvemapping(fd, la->curfalloff); } - la->nodetree = newdataadr(fd, la->nodetree); - if (la->nodetree) { - direct_link_id(fd, &la->nodetree->id); - direct_link_nodetree(fd, la->nodetree); - } - la->preview = direct_link_preview_image(fd, la->preview); } @@ -4016,14 +4056,9 @@ static void direct_link_mball(FileData *fd, MetaBall *mb) /** \name Read ID: World * \{ */ -static void lib_link_world(FileData *fd, Main *bmain, World *wrld) +static void lib_link_world(FileData *fd, Main *UNUSED(bmain), World *wrld) { wrld->ipo = newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX deprecated - old animation system - - if (wrld->nodetree) { - lib_link_id(fd, bmain, &wrld->nodetree->id); - lib_link_ntree(fd, wrld->id.lib, wrld->nodetree); - } } static void direct_link_world(FileData *fd, World *wrld) @@ -4031,12 +4066,6 @@ static void direct_link_world(FileData *fd, World *wrld) wrld->adt = newdataadr(fd, wrld->adt); direct_link_animdata(fd, wrld->adt); - wrld->nodetree = newdataadr(fd, wrld->nodetree); - if (wrld->nodetree) { - direct_link_id(fd, &wrld->nodetree->id); - direct_link_nodetree(fd, wrld->nodetree); - } - wrld->preview = direct_link_preview_image(fd, wrld->preview); BLI_listbase_clear(&wrld->gpumaterial); } @@ -4278,15 +4307,10 @@ static void direct_link_curve(FileData *fd, Curve *cu) /** \name Read ID: Texture * \{ */ -static void lib_link_texture(FileData *fd, Main *bmain, Tex *tex) +static void lib_link_texture(FileData *fd, Main *UNUSED(bmain), Tex *tex) { tex->ima = newlibadr_us(fd, tex->id.lib, tex->ima); tex->ipo = newlibadr_us(fd, tex->id.lib, tex->ipo); // XXX deprecated - old animation system - - if (tex->nodetree) { - lib_link_id(fd, bmain, &tex->nodetree->id); - lib_link_ntree(fd, tex->id.lib, tex->nodetree); - } } static void direct_link_texture(FileData *fd, Tex *tex) @@ -4296,12 +4320,6 @@ static void direct_link_texture(FileData *fd, Tex *tex) tex->coba = newdataadr(fd, tex->coba); - tex->nodetree = newdataadr(fd, tex->nodetree); - if (tex->nodetree) { - direct_link_id(fd, &tex->nodetree->id); - direct_link_nodetree(fd, tex->nodetree); - } - tex->preview = direct_link_preview_image(fd, tex->preview); tex->iuser.ok = 1; @@ -4314,15 +4332,10 @@ static void direct_link_texture(FileData *fd, Tex *tex) /** \name Read ID: Material * \{ */ -static void lib_link_material(FileData *fd, Main *bmain, Material *ma) +static void lib_link_material(FileData *fd, Main *UNUSED(bmain), Material *ma) { ma->ipo = newlibadr_us(fd, ma->id.lib, ma->ipo); // XXX deprecated - old animation system - if (ma->nodetree) { - lib_link_id(fd, bmain, &ma->nodetree->id); - lib_link_ntree(fd, ma->id.lib, ma->nodetree); - } - /* relink grease pencil settings */ if (ma->gp_style != NULL) { MaterialGPencilStyle *gp_style = ma->gp_style; @@ -4342,12 +4355,6 @@ static void direct_link_material(FileData *fd, Material *ma) ma->texpaintslot = NULL; - ma->nodetree = newdataadr(fd, ma->nodetree); - if (ma->nodetree) { - direct_link_id(fd, &ma->nodetree->id); - direct_link_nodetree(fd, ma->nodetree); - } - ma->preview = direct_link_preview_image(fd, ma->preview); BLI_listbase_clear(&ma->gpumaterial); @@ -6325,7 +6332,7 @@ static bool scene_validate_setscene__liblink(Scene *sce, const int totscene) } #endif -static void lib_link_scene(FileData *fd, Main *bmain, Scene *sce) +static void lib_link_scene(FileData *fd, Main *UNUSED(bmain), Scene *sce) { lib_link_keyingsets(fd, &sce->id, &sce->keyingsets); @@ -6459,8 +6466,6 @@ static void lib_link_scene(FileData *fd, Main *bmain, Scene *sce) } if (sce->nodetree) { - lib_link_id(fd, bmain, &sce->nodetree->id); - lib_link_ntree(fd, sce->id.lib, sce->nodetree); composite_patch(sce->nodetree, sce); } @@ -6483,11 +6488,6 @@ static void lib_link_scene(FileData *fd, Main *bmain, Scene *sce) } #endif - if (sce->master_collection) { - lib_link_id(fd, bmain, &sce->master_collection->id); - lib_link_collection_data(fd, sce->id.lib, sce->master_collection); - } - for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { lib_link_view_layer(fd, sce->id.lib, view_layer); } @@ -6817,12 +6817,6 @@ static void direct_link_scene(FileData *fd, Scene *sce) link_list(fd, &(srl->freestyleConfig.linesets)); } - sce->nodetree = newdataadr(fd, sce->nodetree); - if (sce->nodetree) { - direct_link_id(fd, &sce->nodetree->id); - direct_link_nodetree(fd, sce->nodetree); - } - direct_link_view_settings(fd, &sce->view_settings); sce->rigidbody_world = newdataadr(fd, sce->rigidbody_world); @@ -6878,13 +6872,6 @@ static void direct_link_scene(FileData *fd, Scene *sce) } #endif - if (sce->master_collection) { - sce->master_collection = newdataadr(fd, sce->master_collection); - /* Needed because this is an ID outside of Main. */ - direct_link_id(fd, &sce->master_collection->id); - direct_link_collection(fd, sce->master_collection); - } - /* insert into global old-new map for reading without UI (link_global accesses it again) */ link_glob_list(fd, &sce->view_layers); for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { @@ -8576,7 +8563,7 @@ static void lib_link_mask(FileData *fd, Main *UNUSED(bmain), Mask *mask) /** \name Read ID: Line Style * \{ */ -static void lib_link_linestyle(FileData *fd, Main *bmain, FreestyleLineStyle *linestyle) +static void lib_link_linestyle(FileData *fd, Main *UNUSED(bmain), FreestyleLineStyle *linestyle) { LineStyleModifier *m; @@ -8617,10 +8604,6 @@ static void lib_link_linestyle(FileData *fd, Main *bmain, FreestyleLineStyle *li mtex->object = newlibadr(fd, linestyle->id.lib, mtex->object); } } - if (linestyle->nodetree) { - lib_link_id(fd, bmain, &linestyle->nodetree->id); - lib_link_ntree(fd, linestyle->id.lib, linestyle->nodetree); - } } static void direct_link_linestyle_color_modifier(FileData *fd, LineStyleModifier *modifier) @@ -8811,11 +8794,6 @@ static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle) for (a = 0; a < MAX_MTEX; a++) { linestyle->mtex[a] = newdataadr(fd, linestyle->mtex[a]); } - linestyle->nodetree = newdataadr(fd, linestyle->nodetree); - if (linestyle->nodetree) { - direct_link_id(fd, &linestyle->nodetree->id); - direct_link_nodetree(fd, linestyle->nodetree); - } } /** \} */ @@ -10104,39 +10082,6 @@ static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *ch } } -static void expand_id(FileData *fd, Main *mainvar, ID *id) -{ - if (id->override_library) { - expand_doit(fd, mainvar, id->override_library->reference); - expand_doit(fd, mainvar, id->override_library->storage); - } -} - -static void expand_idprops(FileData *fd, Main *mainvar, IDProperty *prop) -{ - if (!prop) { - return; - } - - switch (prop->type) { - case IDP_ID: - expand_doit(fd, mainvar, IDP_Id(prop)); - break; - case IDP_IDPARRAY: { - IDProperty *idp_array = IDP_IDPArray(prop); - for (int i = 0; i < prop->len; i++) { - expand_idprops(fd, mainvar, &idp_array[i]); - } - break; - } - case IDP_GROUP: - for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) { - expand_idprops(fd, mainvar, loop); - } - break; - } -} - static void expand_fmodifiers(FileData *fd, Main *mainvar, ListBase *list) { FModifier *fcm; @@ -10179,40 +10124,6 @@ static void expand_fcurves(FileData *fd, Main *mainvar, ListBase *list) } } -static void expand_action(FileData *fd, Main *mainvar, bAction *act) -{ - bActionChannel *chan; - - // XXX deprecated - old animation system -------------- - for (chan = act->chanbase.first; chan; chan = chan->next) { - expand_doit(fd, mainvar, chan->ipo); - expand_constraint_channels(fd, mainvar, &chan->constraintChannels); - } - // --------------------------------------------------- - - /* F-Curves in Action */ - expand_fcurves(fd, mainvar, &act->curves); - - for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) { - if (marker->camera) { - expand_doit(fd, mainvar, marker->camera); - } - } -} - -static void expand_keyingsets(FileData *fd, Main *mainvar, ListBase *list) -{ - KeyingSet *ks; - KS_Path *ksp; - - /* expand the ID-pointers in KeyingSets's paths */ - for (ks = list->first; ks; ks = ks->next) { - for (ksp = ks->paths.first; ksp; ksp = ksp->next) { - expand_doit(fd, mainvar, ksp->id); - } - } -} - static void expand_animdata_nlastrips(FileData *fd, Main *mainvar, ListBase *list) { NlaStrip *strip; @@ -10249,6 +10160,104 @@ static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt) } } +static void expand_idprops(FileData *fd, Main *mainvar, IDProperty *prop) +{ + if (!prop) { + return; + } + + switch (prop->type) { + case IDP_ID: + expand_doit(fd, mainvar, IDP_Id(prop)); + break; + case IDP_IDPARRAY: { + IDProperty *idp_array = IDP_IDPArray(prop); + for (int i = 0; i < prop->len; i++) { + expand_idprops(fd, mainvar, &idp_array[i]); + } + break; + } + case IDP_GROUP: + for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) { + expand_idprops(fd, mainvar, loop); + } + break; + } +} + +static void expand_id(FileData *fd, Main *mainvar, ID *id); +static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree); +static void expand_collection(FileData *fd, Main *mainvar, Collection *collection); + +static void expand_id_private_id(FileData *fd, Main *mainvar, ID *id) +{ + /* Handle 'private IDs'. */ + bNodeTree *nodetree = ntreeFromID(id); + if (nodetree != NULL) { + expand_id(fd, mainvar, id); + expand_nodetree(fd, mainvar, nodetree); + } + + if (GS(id->name) == ID_SCE) { + Scene *scene = (Scene *)id; + if (scene->master_collection != NULL) { + expand_id(fd, mainvar, id); + expand_collection(fd, mainvar, scene->master_collection); + } + } +} + +static void expand_id(FileData *fd, Main *mainvar, ID *id) +{ + expand_idprops(fd, mainvar, id->properties); + + if (id->override_library) { + expand_doit(fd, mainvar, id->override_library->reference); + expand_doit(fd, mainvar, id->override_library->storage); + } + + AnimData *adt = BKE_animdata_from_id(id); + if (adt != NULL) { + expand_animdata(fd, mainvar, adt); + } + + expand_id_private_id(fd, mainvar, id); +} + +static void expand_action(FileData *fd, Main *mainvar, bAction *act) +{ + bActionChannel *chan; + + // XXX deprecated - old animation system -------------- + for (chan = act->chanbase.first; chan; chan = chan->next) { + expand_doit(fd, mainvar, chan->ipo); + expand_constraint_channels(fd, mainvar, &chan->constraintChannels); + } + // --------------------------------------------------- + + /* F-Curves in Action */ + expand_fcurves(fd, mainvar, &act->curves); + + for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) { + if (marker->camera) { + expand_doit(fd, mainvar, marker->camera); + } + } +} + +static void expand_keyingsets(FileData *fd, Main *mainvar, ListBase *list) +{ + KeyingSet *ks; + KS_Path *ksp; + + /* expand the ID-pointers in KeyingSets's paths */ + for (ks = list->first; ks; ks = ks->next) { + for (ksp = ks->paths.first; ksp; ksp = ksp->next) { + expand_doit(fd, mainvar, ksp->id); + } + } +} + static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part) { int a; @@ -10259,10 +10268,6 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting expand_doit(fd, mainvar, part->bb_ob); expand_doit(fd, mainvar, part->collision_group); - if (part->adt) { - expand_animdata(fd, mainvar, part->adt); - } - for (a = 0; a < MAX_MTEX; a++) { if (part->mtex[a]) { expand_doit(fd, mainvar, part->mtex[a]->tex); @@ -10326,10 +10331,6 @@ static void expand_collection(FileData *fd, Main *mainvar, Collection *collectio static void expand_key(FileData *fd, Main *mainvar, Key *key) { expand_doit(fd, mainvar, key->ipo); // XXX deprecated - old animation system - - if (key->adt) { - expand_animdata(fd, mainvar, key->adt); - } } static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree) @@ -10337,10 +10338,6 @@ static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree) bNode *node; bNodeSocket *sock; - if (ntree->adt) { - expand_animdata(fd, mainvar, ntree->adt); - } - if (ntree->gpd) { expand_doit(fd, mainvar, ntree->gpd); } @@ -10372,14 +10369,6 @@ static void expand_texture(FileData *fd, Main *mainvar, Tex *tex) { expand_doit(fd, mainvar, tex->ima); expand_doit(fd, mainvar, tex->ipo); // XXX deprecated - old animation system - - if (tex->adt) { - expand_animdata(fd, mainvar, tex->adt); - } - - if (tex->nodetree) { - expand_nodetree(fd, mainvar, tex->nodetree); - } } static void expand_brush(FileData *fd, Main *mainvar, Brush *brush) @@ -10397,14 +10386,6 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma) { expand_doit(fd, mainvar, ma->ipo); // XXX deprecated - old animation system - if (ma->adt) { - expand_animdata(fd, mainvar, ma->adt); - } - - if (ma->nodetree) { - expand_nodetree(fd, mainvar, ma->nodetree); - } - if (ma->gp_style) { MaterialGPencilStyle *gp_style = ma->gp_style; expand_doit(fd, mainvar, gp_style->sima); @@ -10415,37 +10396,17 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma) static void expand_light(FileData *fd, Main *mainvar, Light *la) { expand_doit(fd, mainvar, la->ipo); // XXX deprecated - old animation system - - if (la->adt) { - expand_animdata(fd, mainvar, la->adt); - } - - if (la->nodetree) { - expand_nodetree(fd, mainvar, la->nodetree); - } } static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt) { expand_doit(fd, mainvar, lt->ipo); // XXX deprecated - old animation system expand_doit(fd, mainvar, lt->key); - - if (lt->adt) { - expand_animdata(fd, mainvar, lt->adt); - } } static void expand_world(FileData *fd, Main *mainvar, World *wrld) { expand_doit(fd, mainvar, wrld->ipo); // XXX deprecated - old animation system - - if (wrld->adt) { - expand_animdata(fd, mainvar, wrld->adt); - } - - if (wrld->nodetree) { - expand_nodetree(fd, mainvar, wrld->nodetree); - } } static void expand_mball(FileData *fd, Main *mainvar, MetaBall *mb) @@ -10455,10 +10416,6 @@ static void expand_mball(FileData *fd, Main *mainvar, MetaBall *mb) for (a = 0; a < mb->totcol; a++) { expand_doit(fd, mainvar, mb->mat[a]); } - - if (mb->adt) { - expand_animdata(fd, mainvar, mb->adt); - } } static void expand_curve(FileData *fd, Main *mainvar, Curve *cu) @@ -10478,20 +10435,12 @@ static void expand_curve(FileData *fd, Main *mainvar, Curve *cu) expand_doit(fd, mainvar, cu->bevobj); expand_doit(fd, mainvar, cu->taperobj); expand_doit(fd, mainvar, cu->textoncurve); - - if (cu->adt) { - expand_animdata(fd, mainvar, cu->adt); - } } static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me) { int a; - if (me->adt) { - expand_animdata(fd, mainvar, me->adt); - } - for (a = 0; a < me->totcol; a++) { expand_doit(fd, mainvar, me->mat[a]); } @@ -10560,10 +10509,6 @@ static void expand_bones(FileData *fd, Main *mainvar, Bone *bone) static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm) { - if (arm->adt) { - expand_animdata(fd, mainvar, arm->adt); - } - for (Bone *curBone = arm->bonebase.first; curBone; curBone = curBone->next) { expand_bones(fd, mainvar, curBone); } @@ -10649,10 +10594,6 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) } // XXX deprecated - old animation system (for version patching only) - if (ob->adt) { - expand_animdata(fd, mainvar, ob->adt); - } - for (a = 0; a < ob->totcol; a++) { expand_doit(fd, mainvar, ob->mat[a]); } @@ -10728,19 +10669,12 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) expand_doit(fd, mainvar, sce->camera); expand_doit(fd, mainvar, sce->world); - if (sce->adt) { - expand_animdata(fd, mainvar, sce->adt); - } expand_keyingsets(fd, mainvar, &sce->keyingsets); if (sce->set) { expand_doit(fd, mainvar, sce->set); } - if (sce->nodetree) { - expand_nodetree(fd, mainvar, sce->nodetree); - } - for (srl = sce->r.layers.first; srl; srl = srl->next) { expand_doit(fd, mainvar, srl->mat_override); for (module = srl->freestyleConfig.modules.first; module; module = module->next) { @@ -10826,10 +10760,6 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) } #endif - if (sce->master_collection) { - expand_collection(fd, mainvar, sce->master_collection); - } - if (sce->r.bake.cage_object) { expand_doit(fd, mainvar, sce->r.bake.cage_object); } @@ -10847,26 +10777,17 @@ static void expand_camera(FileData *fd, Main *mainvar, Camera *ca) expand_doit(fd, mainvar, bgpic->ima); } } - - if (ca->adt) { - expand_animdata(fd, mainvar, ca->adt); - } } -static void expand_cachefile(FileData *fd, Main *mainvar, CacheFile *cache_file) +static void expand_cachefile(FileData *UNUSED(fd), + Main *UNUSED(mainvar), + CacheFile *UNUSED(cache_file)) { - if (cache_file->adt) { - expand_animdata(fd, mainvar, cache_file->adt); - } } static void expand_speaker(FileData *fd, Main *mainvar, Speaker *spk) { expand_doit(fd, mainvar, spk->sound); - - if (spk->adt) { - expand_animdata(fd, mainvar, spk->adt); - } } static void expand_sound(FileData *fd, Main *mainvar, bSound *snd) @@ -10874,18 +10795,12 @@ static void expand_sound(FileData *fd, Main *mainvar, bSound *snd) expand_doit(fd, mainvar, snd->ipo); // XXX deprecated - old animation system } -static void expand_lightprobe(FileData *fd, Main *mainvar, LightProbe *prb) +static void expand_lightprobe(FileData *UNUSED(fd), Main *UNUSED(mainvar), LightProbe *UNUSED(prb)) { - if (prb->adt) { - expand_animdata(fd, mainvar, prb->adt); - } } -static void expand_movieclip(FileData *fd, Main *mainvar, MovieClip *clip) +static void expand_movieclip(FileData *UNUSED(fd), Main *UNUSED(mainvar), MovieClip *UNUSED(clip)) { - if (clip->adt) { - expand_animdata(fd, mainvar, clip->adt); - } } static void expand_mask_parent(FileData *fd, Main *mainvar, MaskParent *parent) @@ -10899,10 +10814,6 @@ static void expand_mask(FileData *fd, Main *mainvar, Mask *mask) { MaskLayer *mask_layer; - if (mask->adt) { - expand_animdata(fd, mainvar, mask->adt); - } - for (mask_layer = mask->masklayers.first; mask_layer; mask_layer = mask_layer->next) { MaskSpline *spline; @@ -10931,13 +10842,7 @@ static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *li expand_doit(fd, mainvar, linestyle->mtex[a]->object); } } - if (linestyle->nodetree) { - expand_nodetree(fd, mainvar, linestyle->nodetree); - } - if (linestyle->adt) { - expand_animdata(fd, mainvar, linestyle->adt); - } for (m = linestyle->color_modifiers.first; m; m = m->next) { if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) { expand_doit(fd, mainvar, ((LineStyleColorModifier_DistanceFromObject *)m)->target); @@ -10957,10 +10862,6 @@ static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *li static void expand_gpencil(FileData *fd, Main *mainvar, bGPdata *gpd) { - if (gpd->adt) { - expand_animdata(fd, mainvar, gpd->adt); - } - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { expand_doit(fd, mainvar, gpl->parent); } @@ -11013,7 +10914,6 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) while (id) { if (id->tag & LIB_TAG_NEED_EXPAND) { expand_id(fd, mainvar, id); - expand_idprops(fd, mainvar, id->properties); switch (GS(id->name)) { case ID_OB: -- cgit v1.2.3 From ffb94e88b0857e8262f9e026444b327dddffa8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 19:06:07 +0100 Subject: Fluid: Hide Advanced cache options The Manta script export should not be visible in the UI. At least not to normal users. The export feature is only useful for developers. --- release/scripts/startup/bl_ui/properties_physics_fluid.py | 3 ++- source/blender/blenkernel/BKE_global.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 2a918f0c58b..cdd6a31aeda 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -1141,7 +1141,8 @@ class PHYSICS_PT_export(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): - if not PhysicButtonsPanel.poll_fluid_domain(context): + # Only show the advanced panel to advanced users who know Mantaflow's birthday :) + if not PhysicButtonsPanel.poll_fluid_domain(context) or bpy.app.debug_value != 3001: return False return (context.engine in cls.COMPAT_ENGINES) diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 65c3725d994..93840db49c9 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -77,6 +77,7 @@ typedef struct Global { * * 799: Enable some mysterious new depsgraph behavior (05/2015). * * 1112: Disable new Cloth internal springs handling (09/2014). * * 1234: Disable new dyntopo code fixing skinny faces generation (04/2015). + * * 3001: Enable additional Fluid modifier (Mantaflow) options (02/2020). * * 16384 and above: Reserved for python (add-ons) usage. */ short debug_value; -- cgit v1.2.3 From a24b5a74b5715777746d3e7b5273574a46f94cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Thu, 6 Feb 2020 19:27:47 +0100 Subject: Fluid: Optimization for fluid domain obstacle boundary handling This fix should especially improve liquid obstacles boundaries, i.e. help with the problem of particles sticking to the surface. --- intern/mantaflow/intern/strings/liquid_script.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h index 442b09b5a8a..9a494a1cb6a 100644 --- a/intern/mantaflow/intern/strings/liquid_script.h +++ b/intern/mantaflow/intern/strings/liquid_script.h @@ -181,7 +181,7 @@ def liquid_adaptive_step_$ID$(framenr):\n\ phi_s$ID$.join(phiIn_s$ID$)\n\ \n\ if using_obstacle_s$ID$:\n\ - phi_s$ID$.subtract(phiObsIn_s$ID$)\n\ + phi_s$ID$.subtract(o=phiObsIn_s$ID$, flags=flags_s$ID$, subtractType=FlagObstacle)\n\ \n\ if using_outflow_s$ID$:\n\ phiOut_s$ID$.join(phiOutIn_s$ID$)\n\ -- cgit v1.2.3 From 763f117c480e508e6a9bf3c53b929630879bdfc1 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Thu, 6 Feb 2020 13:44:30 -0700 Subject: Fix: Build error on windows in bf_intern_mantaflow bf_intern_mantaflow lacked the `-DOPENVDB_STATICLIB` define causing it to dynamically import openvdb, linked against our static libs a happy time was not had by the linker. --- intern/mantaflow/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/mantaflow/CMakeLists.txt b/intern/mantaflow/CMakeLists.txt index a3d891907a9..2d49f96a451 100644 --- a/intern/mantaflow/CMakeLists.txt +++ b/intern/mantaflow/CMakeLists.txt @@ -27,6 +27,7 @@ add_definitions(-DWITH_FLUID=1) if(WITH_OPENVDB) add_definitions(-DOPENVDB=1) + add_definitions(-DOPENVDB_STATICLIB) endif() set(INC -- cgit v1.2.3 From d8830048f7ae9a9d2763111f062aeafba07069bc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 7 Feb 2020 13:13:13 +1100 Subject: Keymap: preference for relative/absolute Alt-MMB navigation Original request from Hjalti was to set absolute view axis, so make this an option. --- release/scripts/presets/keyconfig/blender.py | 21 ++++++++++++++- .../keyconfig/keymap_data/blender_default.py | 31 ++++++++++++++++------ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/release/scripts/presets/keyconfig/blender.py b/release/scripts/presets/keyconfig/blender.py index 11cd76335f1..8cbbb900154 100644 --- a/release/scripts/presets/keyconfig/blender.py +++ b/release/scripts/presets/keyconfig/blender.py @@ -108,6 +108,22 @@ class Prefs(bpy.types.KeyConfigPreferences): update=update_fn, ) + v3d_alt_mmb_drag_action: EnumProperty( + name="Alt-MMB Drag Action", + items=( + ('RELATIVE', "Relative", + "Set the view axis where each mouse direction maps to an axis relative to the current orientation", + 0), + ('ABSOLUTE', "Absolute", + "Set the view axis where each mouse direction always maps to the same axis", + 1), + ), + description=( + "Action when Alt-MMB dragging in the 3D viewport" + ), + update=update_fn, + ) + # Developer note, this is an experemental option. use_pie_click_drag: BoolProperty( name="Pie Menu on Drag", @@ -149,10 +165,12 @@ class Prefs(bpy.types.KeyConfigPreferences): col = split.column() col.prop(self, "use_v3d_tab_menu") col.prop(self, "use_pie_click_drag") + col.prop(self, "use_v3d_shade_ex_pie") col = split.column() col.label(text="Tilde Action:") col.row().prop(self, "v3d_tilde_action", expand=True) - col.prop(self, "use_v3d_shade_ex_pie") + col.label(text="Alt Middle Mouse Drag Action:") + col.row().prop(self, "v3d_alt_mmb_drag_action", expand=True) blender_default = bpy.utils.execfile(os.path.join(DIRNAME, "keymap_data", "blender_default.py")) @@ -176,6 +194,7 @@ def load(): ), spacebar_action=kc_prefs.spacebar_action, v3d_tilde_action=kc_prefs.v3d_tilde_action, + v3d_alt_mmb_drag_action=kc_prefs.v3d_alt_mmb_drag_action, use_select_all_toggle=kc_prefs.use_select_all_toggle, use_v3d_tab_menu=kc_prefs.use_v3d_tab_menu, use_v3d_shade_ex_pie=kc_prefs.use_v3d_shade_ex_pie, diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 8b398d1541c..bfd0066e66d 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -53,6 +53,8 @@ class Params: # Experimental option. "use_pie_click_drag", "v3d_tilde_action", + # Alt-MMB axis switching 'RELATIVE' or 'ABSOLUTE' axis switching. + "v3d_alt_mmb_drag_action", ) def __init__( @@ -70,6 +72,7 @@ class Params: use_v3d_shade_ex_pie=False, use_pie_click_drag=False, v3d_tilde_action='VIEW', + v3d_alt_mmb_drag_action='RELATIVE', ): from sys import platform self.apple = (platform == 'darwin') @@ -117,6 +120,7 @@ class Params: self.use_v3d_tab_menu = use_v3d_tab_menu self.use_v3d_shade_ex_pie = use_v3d_shade_ex_pie self.v3d_tilde_action = v3d_tilde_action + self.v3d_alt_mmb_drag_action = v3d_alt_mmb_drag_action self.use_pie_click_drag = use_pie_click_drag if not use_pie_click_drag: @@ -1040,14 +1044,25 @@ def km_view3d(params): {"properties": [("type", 'LEFT'), ("align_active", True)]}), ("view3d.view_axis", {"type": 'NUMPAD_7', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'BOTTOM'), ("align_active", True)]}), - ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'NORTH', "alt": True}, - {"properties": [("type", 'TOP'), ("relative", True)]}), - ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'SOUTH', "alt": True}, - {"properties": [("type", 'BOTTOM'), ("relative", True)]}), - ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'EAST', "alt": True}, - {"properties": [("type", 'RIGHT'), ("relative", True)]}), - ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'WEST', "alt": True}, - {"properties": [("type", 'LEFT'), ("relative", True)]}), + *(( + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'NORTH', "alt": True}, + {"properties": [("type", 'TOP'), ("relative", True)]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'SOUTH', "alt": True}, + {"properties": [("type", 'BOTTOM'), ("relative", True)]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'EAST', "alt": True}, + {"properties": [("type", 'RIGHT'), ("relative", True)]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'WEST', "alt": True}, + {"properties": [("type", 'LEFT'), ("relative", True)]}), + ) if params.v3d_alt_mmb_drag_action == 'RELATIVE' else ( + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'NORTH', "alt": True}, + {"properties": [("type", 'TOP')]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'SOUTH', "alt": True}, + {"properties": [("type", 'BOTTOM')]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'EAST', "alt": True}, + {"properties": [("type", 'RIGHT')]}), + ("view3d.view_axis", {"type": 'EVT_TWEAK_M', "value": 'WEST', "alt": True}, + {"properties": [("type", 'LEFT')]}), + )), ("view3d.view_center_pick", {"type": 'MIDDLEMOUSE', "value": 'CLICK', "alt": True}, None), ("view3d.ndof_orbit_zoom", {"type": 'NDOF_MOTION', "value": 'ANY'}, None), ("view3d.ndof_orbit", {"type": 'NDOF_MOTION', "value": 'ANY', "ctrl": True}, None), -- cgit v1.2.3 From 1778efc89777f3c25654254e33dc702f10cdf210 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 7 Feb 2020 13:18:05 +1100 Subject: Keymap: preference to swap 3D orbit/pan actions Requested by @pepeland for grease pencil/2D usage. --- release/scripts/presets/keyconfig/blender.py | 19 +++++++++++++++++++ .../presets/keyconfig/keymap_data/blender_default.py | 13 +++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/release/scripts/presets/keyconfig/blender.py b/release/scripts/presets/keyconfig/blender.py index 8cbbb900154..73be645d037 100644 --- a/release/scripts/presets/keyconfig/blender.py +++ b/release/scripts/presets/keyconfig/blender.py @@ -108,6 +108,22 @@ class Prefs(bpy.types.KeyConfigPreferences): update=update_fn, ) + v3d_mmb_action: EnumProperty( + name="MMB Action", + items=( + ('ORBIT', "Orbit", + "Orbit", + 0), + ('PAN', "Pan", + "Set the view axis where each mouse direction always maps to the same axis", + 1), + ), + description=( + "The action when Middle-Mouse dragging in the viewport. Shift-Middle-Mouse is used for the other action" + ), + update=update_fn, + ) + v3d_alt_mmb_drag_action: EnumProperty( name="Alt-MMB Drag Action", items=( @@ -169,6 +185,8 @@ class Prefs(bpy.types.KeyConfigPreferences): col = split.column() col.label(text="Tilde Action:") col.row().prop(self, "v3d_tilde_action", expand=True) + col.label(text="Middle Mouse Action:") + col.row().prop(self, "v3d_mmb_action", expand=True) col.label(text="Alt Middle Mouse Drag Action:") col.row().prop(self, "v3d_alt_mmb_drag_action", expand=True) @@ -194,6 +212,7 @@ def load(): ), spacebar_action=kc_prefs.spacebar_action, v3d_tilde_action=kc_prefs.v3d_tilde_action, + use_v3d_mmb_pan=(kc_prefs.v3d_mmb_action == 'PAN'), v3d_alt_mmb_drag_action=kc_prefs.v3d_alt_mmb_drag_action, use_select_all_toggle=kc_prefs.use_select_all_toggle, use_v3d_tab_menu=kc_prefs.use_v3d_tab_menu, diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index bfd0066e66d..cc480a43de3 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -50,6 +50,8 @@ class Params: "use_v3d_tab_menu", # Use extended pie menu for shading. "use_v3d_shade_ex_pie", + # Swap orbit/pan keys (for 2D workflows). + "use_v3d_mmb_pan", # Experimental option. "use_pie_click_drag", "v3d_tilde_action", @@ -70,6 +72,7 @@ class Params: use_gizmo_drag=True, use_v3d_tab_menu=False, use_v3d_shade_ex_pie=False, + use_v3d_mmb_pan=False, use_pie_click_drag=False, v3d_tilde_action='VIEW', v3d_alt_mmb_drag_action='RELATIVE', @@ -119,6 +122,7 @@ class Params: self.use_select_all_toggle = use_select_all_toggle self.use_v3d_tab_menu = use_v3d_tab_menu self.use_v3d_shade_ex_pie = use_v3d_shade_ex_pie + self.use_v3d_mmb_pan = use_v3d_mmb_pan self.v3d_tilde_action = v3d_tilde_action self.v3d_alt_mmb_drag_action = v3d_alt_mmb_drag_action @@ -946,8 +950,13 @@ def km_view3d(params): ("view3d.localview", {"type": 'SLASH', "value": 'PRESS'}, None), ("view3d.localview_remove_from", {"type": 'M', "value": 'PRESS'}, None), # Navigation. - ("view3d.rotate", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), - ("view3d.move", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None), + *(( + ("view3d.rotate", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None), + ("view3d.move", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), + ) if params.use_v3d_mmb_pan else ( + ("view3d.rotate", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), + ("view3d.move", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None), + )), ("view3d.zoom", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "ctrl": True}, None), ("view3d.dolly", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("view3d.view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS', "ctrl": True}, -- cgit v1.2.3 From 753323af15d7d8986efbdc4ad8d81331ddeee470 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 7 Feb 2020 10:58:18 +0100 Subject: Fix crash when linking. Stupid mistake in yesterday's own refactoring of readfile code... --- source/blender/blenloader/intern/readfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c1a39711bf8..9547e4cd05a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10194,14 +10194,14 @@ static void expand_id_private_id(FileData *fd, Main *mainvar, ID *id) /* Handle 'private IDs'. */ bNodeTree *nodetree = ntreeFromID(id); if (nodetree != NULL) { - expand_id(fd, mainvar, id); + expand_id(fd, mainvar, &nodetree->id); expand_nodetree(fd, mainvar, nodetree); } if (GS(id->name) == ID_SCE) { Scene *scene = (Scene *)id; if (scene->master_collection != NULL) { - expand_id(fd, mainvar, id); + expand_id(fd, mainvar, &scene->master_collection->id); expand_collection(fd, mainvar, scene->master_collection); } } -- cgit v1.2.3 From f12b4e53aaf768d54bd85ec4713f94e77aaf72f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Fri, 7 Feb 2020 11:02:55 +0100 Subject: Fluid: Fixed try/catch exception issue and unsed variable issue Sergey just pointed this out, fixing in it the release branch to avoid any compilation issues during the actual release. Thx! --- intern/mantaflow/intern/MANTA_main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index 798ad9c2854..c0c7ef5dbf2 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -2894,7 +2894,7 @@ int MANTA::updateGridFromVDB(const char *filename, float *grid) try { file.open(); } - catch (const openvdb::IoError) { + catch (const openvdb::IoError &) { std::cout << "MANTA::updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename << std::endl; return 0; @@ -2941,6 +2941,7 @@ int MANTA::updateGridFromRaw(const char *filename, float *grid) readBytes = gzread(gzf, grid, expectedBytes); assert(expectedBytes == readBytes); + (void)readBytes; // Unused in release. gzclose(gzf); return 1; -- cgit v1.2.3 From f2695c9c1d8da179ce155817ba620b56b5ff5e62 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 7 Feb 2020 10:58:07 +0100 Subject: Cleanup: Remove view3d_draw_legacy.c This file was originally a placeholder for all the old functions that have not yet been ported to the new draw system. Over time all the functions that needed refactor were gone, and the functions here are still needed. While moving the functions around I removed dead code and made sure the existent comments start with a capital letter and end with a full stop. --- source/blender/editors/space_view3d/CMakeLists.txt | 1 - source/blender/editors/space_view3d/view3d_draw.c | 473 ++++++++++++++++- .../editors/space_view3d/view3d_draw_legacy.c | 578 --------------------- 3 files changed, 471 insertions(+), 581 deletions(-) delete mode 100644 source/blender/editors/space_view3d/view3d_draw_legacy.c diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 95d7f79f666..9e3c9d6725d 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -48,7 +48,6 @@ set(SRC view3d_buttons.c view3d_camera_control.c view3d_draw.c - view3d_draw_legacy.c view3d_edit.c view3d_fly.c view3d_gizmo_armature.c diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 0e5592abfd2..6704fc9908f 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -33,7 +33,9 @@ #include "BKE_camera.h" #include "BKE_collection.h" #include "BKE_context.h" +#include "BKE_customdata.h" #include "BKE_global.h" +#include "BKE_layer.h" #include "BKE_key.h" #include "BKE_main.h" #include "BKE_scene.h" @@ -56,11 +58,13 @@ #include "DNA_windowmanager_types.h" #include "DRW_engine.h" +#include "DRW_select_buffer.h" #include "ED_armature.h" #include "ED_keyframing.h" #include "ED_gpencil.h" #include "ED_screen.h" +#include "ED_screen_types.h" #include "ED_transform.h" #include "DEG_depsgraph_query.h" @@ -1936,11 +1940,476 @@ static bool view3d_clipping_test(const float co[3], const float clip[6][4]) return true; } -/* for 'local' ED_view3d_clipping_local must run first - * then all comparisons can be done in localspace */ +/* For 'local' ED_view3d_clipping_local must run first + * then all comparisons can be done in localspace. */ bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local) { return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip); } +/* Legacy 2.7x, now use shaders that use clip distance instead. + * Remove once clipping is working properly. */ +#define USE_CLIP_PLANES + +void ED_view3d_clipping_set(RegionView3D *rv3d) +{ +#ifdef USE_CLIP_PLANES + double plane[4]; + const uint tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6; + + for (unsigned a = 0; a < tot; a++) { + copy_v4db_v4fl(plane, rv3d->clip[a]); + glClipPlane(GL_CLIP_PLANE0 + a, plane); + glEnable(GL_CLIP_PLANE0 + a); + glEnable(GL_CLIP_DISTANCE0 + a); + } +#else + for (unsigned a = 0; a < 6; a++) { + glEnable(GL_CLIP_DISTANCE0 + a); + } +#endif +} + +/* Use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set. */ +void ED_view3d_clipping_disable(void) +{ + for (unsigned a = 0; a < 6; a++) { +#ifdef USE_CLIP_PLANES + glDisable(GL_CLIP_PLANE0 + a); +#endif + glDisable(GL_CLIP_DISTANCE0 + a); + } +} +void ED_view3d_clipping_enable(void) +{ + for (unsigned a = 0; a < 6; a++) { +#ifdef USE_CLIP_PLANES + glEnable(GL_CLIP_PLANE0 + a); +#endif + glEnable(GL_CLIP_DISTANCE0 + a); + } +} + +/* *********************** backdraw for selection *************** */ + +/** + * \note Only use in object mode. + */ +static void validate_object_select_id( + struct Depsgraph *depsgraph, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Object *obact) +{ + Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact); + + BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); + UNUSED_VARS_NDEBUG(ar); + + if (obact_eval && (obact_eval->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) || + BKE_paint_select_face_test(obact_eval))) { + /* do nothing */ + } + /* texture paint mode sampling */ + else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) && + (v3d->shading.type > OB_WIRE)) { + /* do nothing */ + } + else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) && !XRAY_ENABLED(v3d)) { + /* do nothing */ + } + else { + v3d->flag &= ~V3D_INVALID_BACKBUF; + return; + } + + if (!(v3d->flag & V3D_INVALID_BACKBUF)) { + return; + } + + if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE_DEPSGRAPH) != 0)) { + Base *base = BKE_view_layer_base_find(view_layer, obact); + DRW_select_buffer_context_create(&base, 1, -1); + } + + /* TODO: Create a flag in `DRW_manager` because the drawing is no longer + * made on the backbuffer in this case. */ + v3d->flag &= ~V3D_INVALID_BACKBUF; +} + +/* TODO: Creating, attaching texture, and destroying a framebuffer is quite slow. + * Calling this function should be avoided during interactive drawing. */ +static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data) +{ + DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(viewport); + + GPUFrameBuffer *tmp_fb = GPU_framebuffer_create(); + GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0); + GPU_framebuffer_bind(tmp_fb); + + glReadPixels(rect->xmin, + rect->ymin, + BLI_rcti_size_x(rect), + BLI_rcti_size_y(rect), + GL_DEPTH_COMPONENT, + GL_FLOAT, + data); + + GPU_framebuffer_restore(); + GPU_framebuffer_free(tmp_fb); +} + +void ED_view3d_select_id_validate(ViewContext *vc) +{ + /* TODO: Create a flag in `DRW_manager` because the drawing is no longer + * made on the backbuffer in this case. */ + if (vc->v3d->flag & V3D_INVALID_BACKBUF) { + validate_object_select_id(vc->depsgraph, vc->view_layer, vc->ar, vc->v3d, vc->obact); + } +} + +void ED_view3d_backbuf_depth_validate(ViewContext *vc) +{ + if (vc->v3d->flag & V3D_INVALID_BACKBUF) { + ARegion *ar = vc->ar; + Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact); + + if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE_DEPSGRAPH) != 0)) { + GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); + DRW_draw_depth_object(vc->ar, vc->v3d, viewport, obact_eval); + } + + vc->v3d->flag &= ~V3D_INVALID_BACKBUF; + } +} + +/** + * allow for small values [0.5 - 2.5], + * and large values, FLT_MAX by clamping by the area size + */ +int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist) +{ + return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx)); +} + +/* *********************** */ + +void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) +{ + /* clamp rect by region */ + rcti r = { + .xmin = 0, + .xmax = ar->winx - 1, + .ymin = 0, + .ymax = ar->winy - 1, + }; + + /* Constrain rect to depth bounds */ + BLI_rcti_isect(&r, rect, rect); + + /* assign values to compare with the ViewDepths */ + int x = rect->xmin; + int y = rect->ymin; + + int w = BLI_rcti_size_x(rect); + int h = BLI_rcti_size_y(rect); + + if (w <= 0 || h <= 0) { + if (d->depths) { + MEM_freeN(d->depths); + } + d->depths = NULL; + + d->damaged = false; + } + else if (d->w != w || d->h != h || d->x != x || d->y != y || d->depths == NULL) { + d->x = x; + d->y = y; + d->w = w; + d->h = h; + + if (d->depths) { + MEM_freeN(d->depths); + } + + d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset"); + + d->damaged = true; + } + + if (d->damaged) { + GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); + view3d_opengl_read_Z_pixels(viewport, rect, d->depths); + glGetDoublev(GL_DEPTH_RANGE, d->depth_range); + d->damaged = false; + } +} + +/* Note, with nouveau drivers the glReadPixels() is very slow. [#24339]. */ +void ED_view3d_depth_update(ARegion *ar) +{ + RegionView3D *rv3d = ar->regiondata; + + /* Create storage for, and, if necessary, copy depth buffer. */ + if (!rv3d->depths) { + rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths"); + } + if (rv3d->depths) { + ViewDepths *d = rv3d->depths; + if (d->w != ar->winx || d->h != ar->winy || !d->depths) { + d->w = ar->winx; + d->h = ar->winy; + if (d->depths) { + MEM_freeN(d->depths); + } + d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths"); + d->damaged = true; + } + + if (d->damaged) { + GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); + rcti r = { + .xmin = 0, + .xmax = d->w, + .ymin = 0, + .ymax = d->h, + }; + view3d_opengl_read_Z_pixels(viewport, &r, d->depths); + glGetDoublev(GL_DEPTH_RANGE, d->depth_range); + d->damaged = false; + } + } +} + +/* Utility function to find the closest Z value, use for autodepth. */ +float view3d_depth_near(ViewDepths *d) +{ + /* Convert to float for comparisons. */ + const float near = (float)d->depth_range[0]; + const float far_real = (float)d->depth_range[1]; + float far = far_real; + + const float *depths = d->depths; + float depth = FLT_MAX; + int i = (int)d->w * (int)d->h; /* Cast to avoid short overflow. */ + + /* Far is both the starting 'far' value + * and the closest value found. */ + while (i--) { + depth = *depths++; + if ((depth < far) && (depth > near)) { + far = depth; + } + } + + return far == far_real ? FLT_MAX : far; +} + +void ED_view3d_draw_depth_gpencil(Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d) +{ + /* Setup view matrix. */ + ED_view3d_draw_setup_view(NULL, depsgraph, scene, ar, v3d, NULL, NULL, NULL); + + GPU_clear(GPU_DEPTH_BIT); + + GPU_depth_test(true); + + GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); + DRW_draw_depth_loop_gpencil(depsgraph, ar, v3d, viewport); + + GPU_depth_test(false); +} + +/* *********************** customdata **************** */ + +void ED_view3d_datamask(const bContext *C, + const Scene *UNUSED(scene), + const View3D *v3d, + CustomData_MeshMasks *r_cddata_masks) +{ + if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) { + r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; + r_cddata_masks->vmask |= CD_MASK_ORCO; + } + else if (v3d->shading.type == OB_SOLID) { + if (v3d->shading.color_type == V3D_SHADING_TEXTURE_COLOR) { + r_cddata_masks->lmask |= CD_MASK_MLOOPUV; + } + if (v3d->shading.color_type == V3D_SHADING_VERTEX_COLOR) { + r_cddata_masks->lmask |= CD_MASK_MLOOPCOL; + } + } + + if ((CTX_data_mode_enum(C) == CTX_MODE_EDIT_MESH) && + (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT)) { + r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; + } +} + +/* Goes over all modes and view3d settings. */ +void ED_view3d_screen_datamask(const bContext *C, + const Scene *scene, + const bScreen *screen, + CustomData_MeshMasks *r_cddata_masks) +{ + CustomData_MeshMasks_update(r_cddata_masks, &CD_MASK_BAREMESH); + + /* Check if we need tfaces & mcols due to view mode. */ + for (const ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + if (sa->spacetype == SPACE_VIEW3D) { + ED_view3d_datamask(C, scene, sa->spacedata.first, r_cddata_masks); + } + } +} + +/** + * Store values from #RegionView3D, set when drawing. + * This is needed when we draw with to a viewport using a different matrix + * (offscreen drawing for example). + * + * Values set by #ED_view3d_update_viewmat should be handled here. + */ +struct RV3DMatrixStore { + float winmat[4][4]; + float viewmat[4][4]; + float viewinv[4][4]; + float persmat[4][4]; + float persinv[4][4]; + float viewcamtexcofac[4]; + float pixsize; +}; + +struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d) +{ + struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__); + copy_m4_m4(rv3dmat->winmat, rv3d->winmat); + copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat); + copy_m4_m4(rv3dmat->persmat, rv3d->persmat); + copy_m4_m4(rv3dmat->persinv, rv3d->persinv); + copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv); + copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac); + rv3dmat->pixsize = rv3d->pixsize; + return (void *)rv3dmat; +} + +void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat_pt) +{ + struct RV3DMatrixStore *rv3dmat = rv3dmat_pt; + copy_m4_m4(rv3d->winmat, rv3dmat->winmat); + copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat); + copy_m4_m4(rv3d->persmat, rv3dmat->persmat); + copy_m4_m4(rv3d->persinv, rv3dmat->persinv); + copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv); + copy_v4_v4(rv3d->viewcamtexcofac, rv3dmat->viewcamtexcofac); + rv3d->pixsize = rv3dmat->pixsize; +} + +/** + * \note The info that this uses is updated in #ED_refresh_viewport_fps, + * which currently gets called during #SCREEN_OT_animation_step. + */ +void ED_scene_draw_fps(Scene *scene, int xoffset, int *yoffset) +{ + ScreenFrameRateInfo *fpsi = scene->fps_info; + char printable[16]; + + if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime) { + return; + } + + printable[0] = '\0'; + + /* Doing an average for a more robust calculation. */ + fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / + (fpsi->lredrawtime - fpsi->redrawtime)); + + float fps = 0.0f; + int tot = 0; + for (int i = 0; i < REDRAW_FRAME_AVERAGE; i++) { + if (fpsi->redrawtimes_fps[i]) { + fps += fpsi->redrawtimes_fps[i]; + tot++; + } + } + if (tot) { + fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE; + fps = fps / tot; + } + + const int font_id = BLF_default(); + + /* Is this more than half a frame behind? */ + if (fps + 0.5f < (float)(FPS)) { + UI_FontThemeColor(font_id, TH_REDALERT); + BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps); + } + else { + UI_FontThemeColor(font_id, TH_TEXT_HI); + BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f)); + } + + BLF_enable(font_id, BLF_SHADOW); + BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f}); + BLF_shadow_offset(font_id, 1, -1); + + *yoffset -= U.widget_unit; + +#ifdef WITH_INTERNATIONAL + BLF_draw_default(xoffset, *yoffset, 0.0f, printable, sizeof(printable)); +#else + BLF_draw_default_ascii(xoffset, *yoffset, 0.0f, printable, sizeof(printable)); +#endif + + BLF_disable(font_id, BLF_SHADOW); +} + +static bool view3d_main_region_do_render_draw(const Scene *scene) +{ + RenderEngineType *type = RE_engines_find(scene->r.engine); + return (type && type->view_update && type->view_draw); +} + +bool ED_view3d_calc_render_border( + const Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *ar, rcti *rect) +{ + RegionView3D *rv3d = ar->regiondata; + bool use_border; + + /* Test if there is a 3d view rendering. */ + if (v3d->shading.type != OB_RENDER || !view3d_main_region_do_render_draw(scene)) { + return false; + } + + /* Test if there is a border render. */ + if (rv3d->persp == RV3D_CAMOB) { + use_border = (scene->r.mode & R_BORDER) != 0; + } + else { + use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0; + } + + if (!use_border) { + return false; + } + + /* Compute border. */ + if (rv3d->persp == RV3D_CAMOB) { + rctf viewborder; + ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false); + + rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); + rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); + rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); + rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + } + else { + rect->xmin = v3d->render_border.xmin * ar->winx; + rect->xmax = v3d->render_border.xmax * ar->winx; + rect->ymin = v3d->render_border.ymin * ar->winy; + rect->ymax = v3d->render_border.ymax * ar->winy; + } + + BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin); + BLI_rcti_isect(&ar->winrct, rect, rect); + + return true; +} + /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c deleted file mode 100644 index 38cb5ad8651..00000000000 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup spview3d - */ - -#include -#include -#include - -#include "DNA_armature_types.h" -#include "DNA_camera_types.h" -#include "DNA_collection_types.h" -#include "DNA_customdata_types.h" -#include "DNA_object_types.h" -#include "DNA_mesh_types.h" -#include "DNA_key_types.h" -#include "DNA_light_types.h" -#include "DNA_scene_types.h" -#include "DNA_world_types.h" -#include "DNA_brush_types.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" -#include "BLI_endian_switch.h" -#include "BLI_threads.h" - -#include "BKE_anim.h" -#include "BKE_camera.h" -#include "BKE_context.h" -#include "BKE_customdata.h" -#include "BKE_image.h" -#include "BKE_key.h" -#include "BKE_layer.h" -#include "BKE_object.h" -#include "BKE_global.h" -#include "BKE_paint.h" -#include "BKE_scene.h" -#include "BKE_unit.h" -#include "BKE_movieclip.h" - -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_query.h" - -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" -#include "IMB_colormanagement.h" - -#include "BIF_glutil.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "BLF_api.h" -#include "BLT_translation.h" - -#include "ED_armature.h" -#include "ED_keyframing.h" -#include "ED_gpencil.h" -#include "ED_mesh.h" -#include "ED_screen.h" -#include "ED_space_api.h" -#include "ED_screen_types.h" -#include "ED_transform.h" -#include "ED_view3d.h" - -#include "UI_interface.h" -#include "UI_interface_icons.h" -#include "UI_resources.h" - -#include "GPU_framebuffer.h" -#include "GPU_immediate.h" -#include "GPU_state.h" -#include "GPU_viewport.h" - -#include "RE_engine.h" - -#include "DRW_engine.h" -#include "DRW_select_buffer.h" - -#include "view3d_intern.h" /* own include */ - -/* ********* custom clipping *********** */ - -/* Legacy 2.7x, now use shaders that use clip distance instead. - * Remove once clipping is working properly. */ -#define USE_CLIP_PLANES - -void ED_view3d_clipping_set(RegionView3D *rv3d) -{ -#ifdef USE_CLIP_PLANES - double plane[4]; - const uint tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6; - - for (unsigned a = 0; a < tot; a++) { - copy_v4db_v4fl(plane, rv3d->clip[a]); - glClipPlane(GL_CLIP_PLANE0 + a, plane); - glEnable(GL_CLIP_PLANE0 + a); - glEnable(GL_CLIP_DISTANCE0 + a); - } -#else - for (unsigned a = 0; a < 6; a++) { - glEnable(GL_CLIP_DISTANCE0 + a); - } -#endif -} - -/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */ -void ED_view3d_clipping_disable(void) -{ - for (unsigned a = 0; a < 6; a++) { -#ifdef USE_CLIP_PLANES - glDisable(GL_CLIP_PLANE0 + a); -#endif - glDisable(GL_CLIP_DISTANCE0 + a); - } -} -void ED_view3d_clipping_enable(void) -{ - for (unsigned a = 0; a < 6; a++) { -#ifdef USE_CLIP_PLANES - glEnable(GL_CLIP_PLANE0 + a); -#endif - glEnable(GL_CLIP_DISTANCE0 + a); - } -} - -/* *********************** backdraw for selection *************** */ - -/** - * \note Only use in object mode. - */ -static void validate_object_select_id( - struct Depsgraph *depsgraph, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Object *obact) -{ - Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact); - - BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); - UNUSED_VARS_NDEBUG(ar); - - if (obact_eval && (obact_eval->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) || - BKE_paint_select_face_test(obact_eval))) { - /* do nothing */ - } - /* texture paint mode sampling */ - else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) && - (v3d->shading.type > OB_WIRE)) { - /* do nothing */ - } - else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) && !XRAY_ENABLED(v3d)) { - /* do nothing */ - } - else { - v3d->flag &= ~V3D_INVALID_BACKBUF; - return; - } - - if (!(v3d->flag & V3D_INVALID_BACKBUF)) { - return; - } - - if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE_DEPSGRAPH) != 0)) { - Base *base = BKE_view_layer_base_find(view_layer, obact); - DRW_select_buffer_context_create(&base, 1, -1); - } - - /* TODO: Create a flag in `DRW_manager` because the drawing is no longer - * made on the backbuffer in this case. */ - v3d->flag &= ~V3D_INVALID_BACKBUF; -} - -/* TODO: Creating, attaching texture, and destroying a framebuffer is quite slow. - * Calling this function should be avoided during interactive drawing. */ -static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data) -{ - DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(viewport); - - GPUFrameBuffer *tmp_fb = GPU_framebuffer_create(); - GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0); - GPU_framebuffer_bind(tmp_fb); - - glReadPixels(rect->xmin, - rect->ymin, - BLI_rcti_size_x(rect), - BLI_rcti_size_y(rect), - GL_DEPTH_COMPONENT, - GL_FLOAT, - data); - - GPU_framebuffer_restore(); - GPU_framebuffer_free(tmp_fb); -} - -void ED_view3d_select_id_validate(ViewContext *vc) -{ - /* TODO: Create a flag in `DRW_manager` because the drawing is no longer - * made on the backbuffer in this case. */ - if (vc->v3d->flag & V3D_INVALID_BACKBUF) { - validate_object_select_id(vc->depsgraph, vc->view_layer, vc->ar, vc->v3d, vc->obact); - } -} - -void ED_view3d_backbuf_depth_validate(ViewContext *vc) -{ - if (vc->v3d->flag & V3D_INVALID_BACKBUF) { - ARegion *ar = vc->ar; - Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact); - - if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE_DEPSGRAPH) != 0)) { - GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); - DRW_draw_depth_object(vc->ar, vc->v3d, viewport, obact_eval); - } - - vc->v3d->flag &= ~V3D_INVALID_BACKBUF; - } -} - -/** - * allow for small values [0.5 - 2.5], - * and large values, FLT_MAX by clamping by the area size - */ -int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist) -{ - return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx)); -} - -/* *********************** */ - -void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) -{ - /* clamp rect by region */ - rcti r = { - .xmin = 0, - .xmax = ar->winx - 1, - .ymin = 0, - .ymax = ar->winy - 1, - }; - - /* Constrain rect to depth bounds */ - BLI_rcti_isect(&r, rect, rect); - - /* assign values to compare with the ViewDepths */ - int x = rect->xmin; - int y = rect->ymin; - - int w = BLI_rcti_size_x(rect); - int h = BLI_rcti_size_y(rect); - - if (w <= 0 || h <= 0) { - if (d->depths) { - MEM_freeN(d->depths); - } - d->depths = NULL; - - d->damaged = false; - } - else if (d->w != w || d->h != h || d->x != x || d->y != y || d->depths == NULL) { - d->x = x; - d->y = y; - d->w = w; - d->h = h; - - if (d->depths) { - MEM_freeN(d->depths); - } - - d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset"); - - d->damaged = true; - } - - if (d->damaged) { - GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); - view3d_opengl_read_Z_pixels(viewport, rect, d->depths); - glGetDoublev(GL_DEPTH_RANGE, d->depth_range); - d->damaged = false; - } -} - -/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */ -void ED_view3d_depth_update(ARegion *ar) -{ - RegionView3D *rv3d = ar->regiondata; - - /* Create storage for, and, if necessary, copy depth buffer */ - if (!rv3d->depths) { - rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths"); - } - if (rv3d->depths) { - ViewDepths *d = rv3d->depths; - if (d->w != ar->winx || d->h != ar->winy || !d->depths) { - d->w = ar->winx; - d->h = ar->winy; - if (d->depths) { - MEM_freeN(d->depths); - } - d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths"); - d->damaged = true; - } - - if (d->damaged) { - GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); - rcti r = { - .xmin = 0, - .xmax = d->w, - .ymin = 0, - .ymax = d->h, - }; - view3d_opengl_read_Z_pixels(viewport, &r, d->depths); - glGetDoublev(GL_DEPTH_RANGE, d->depth_range); - d->damaged = false; - } - } -} - -/* utility function to find the closest Z value, use for autodepth */ -float view3d_depth_near(ViewDepths *d) -{ - /* convert to float for comparisons */ - const float near = (float)d->depth_range[0]; - const float far_real = (float)d->depth_range[1]; - float far = far_real; - - const float *depths = d->depths; - float depth = FLT_MAX; - int i = (int)d->w * (int)d->h; /* cast to avoid short overflow */ - - /* far is both the starting 'far' value - * and the closest value found. */ - while (i--) { - depth = *depths++; - if ((depth < far) && (depth > near)) { - far = depth; - } - } - - return far == far_real ? FLT_MAX : far; -} - -void ED_view3d_draw_depth_gpencil(Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d) -{ - /* Setup view matrix. */ - ED_view3d_draw_setup_view(NULL, depsgraph, scene, ar, v3d, NULL, NULL, NULL); - - GPU_clear(GPU_DEPTH_BIT); - - GPU_depth_test(true); - - GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); - DRW_draw_depth_loop_gpencil(depsgraph, ar, v3d, viewport); - - GPU_depth_test(false); -} - -/* *********************** customdata **************** */ - -void ED_view3d_datamask(const bContext *C, - const Scene *UNUSED(scene), - const View3D *v3d, - CustomData_MeshMasks *r_cddata_masks) -{ - if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) { - r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; - r_cddata_masks->vmask |= CD_MASK_ORCO; - } - else if (v3d->shading.type == OB_SOLID) { - if (v3d->shading.color_type == V3D_SHADING_TEXTURE_COLOR) { - r_cddata_masks->lmask |= CD_MASK_MLOOPUV; - } - if (v3d->shading.color_type == V3D_SHADING_VERTEX_COLOR) { - r_cddata_masks->lmask |= CD_MASK_MLOOPCOL; - } - } - - if ((CTX_data_mode_enum(C) == CTX_MODE_EDIT_MESH) && - (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT)) { - r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; - } -} - -/* goes over all modes and view3d settings */ -void ED_view3d_screen_datamask(const bContext *C, - const Scene *scene, - const bScreen *screen, - CustomData_MeshMasks *r_cddata_masks) -{ - CustomData_MeshMasks_update(r_cddata_masks, &CD_MASK_BAREMESH); - - /* check if we need tfaces & mcols due to view mode */ - for (const ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - if (sa->spacetype == SPACE_VIEW3D) { - ED_view3d_datamask(C, scene, sa->spacedata.first, r_cddata_masks); - } - } -} - -/** - * Store values from #RegionView3D, set when drawing. - * This is needed when we draw with to a viewport using a different matrix - * (offscreen drawing for example). - * - * Values set by #ED_view3d_update_viewmat should be handled here. - */ -struct RV3DMatrixStore { - float winmat[4][4]; - float viewmat[4][4]; - float viewinv[4][4]; - float persmat[4][4]; - float persinv[4][4]; - float viewcamtexcofac[4]; - float pixsize; -}; - -struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d) -{ - struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__); - copy_m4_m4(rv3dmat->winmat, rv3d->winmat); - copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat); - copy_m4_m4(rv3dmat->persmat, rv3d->persmat); - copy_m4_m4(rv3dmat->persinv, rv3d->persinv); - copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv); - copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac); - rv3dmat->pixsize = rv3d->pixsize; - return (void *)rv3dmat; -} - -void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat_pt) -{ - struct RV3DMatrixStore *rv3dmat = rv3dmat_pt; - copy_m4_m4(rv3d->winmat, rv3dmat->winmat); - copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat); - copy_m4_m4(rv3d->persmat, rv3dmat->persmat); - copy_m4_m4(rv3d->persinv, rv3dmat->persinv); - copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv); - copy_v4_v4(rv3d->viewcamtexcofac, rv3dmat->viewcamtexcofac); - rv3d->pixsize = rv3dmat->pixsize; -} - -/** - * \note The info that this uses is updated in #ED_refresh_viewport_fps, - * which currently gets called during #SCREEN_OT_animation_step. - */ -void ED_scene_draw_fps(Scene *scene, int xoffset, int *yoffset) -{ - ScreenFrameRateInfo *fpsi = scene->fps_info; - char printable[16]; - - if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime) { - return; - } - - printable[0] = '\0'; - -#if 0 - /* this is too simple, better do an average */ - fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime)) -#else - fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / - (fpsi->lredrawtime - fpsi->redrawtime)); - - float fps = 0.0f; - int tot = 0; - for (int i = 0; i < REDRAW_FRAME_AVERAGE; i++) { - if (fpsi->redrawtimes_fps[i]) { - fps += fpsi->redrawtimes_fps[i]; - tot++; - } - } - if (tot) { - fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE; - - // fpsi->redrawtime_index++; - // if (fpsi->redrawtime >= REDRAW_FRAME_AVERAGE) { - // fpsi->redrawtime = 0; - //} - - fps = fps / tot; - } -#endif - - const int font_id = BLF_default(); - - /* is this more than half a frame behind? */ - if (fps + 0.5f < (float)(FPS)) { - UI_FontThemeColor(font_id, TH_REDALERT); - BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps); - } - else { - UI_FontThemeColor(font_id, TH_TEXT_HI); - BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f)); - } - - BLF_enable(font_id, BLF_SHADOW); - BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f}); - BLF_shadow_offset(font_id, 1, -1); - - *yoffset -= U.widget_unit; - -#ifdef WITH_INTERNATIONAL - BLF_draw_default(xoffset, *yoffset, 0.0f, printable, sizeof(printable)); -#else - BLF_draw_default_ascii(xoffset, *yoffset, 0.0f, printable, sizeof(printable)); -#endif - - BLF_disable(font_id, BLF_SHADOW); -} - -static bool view3d_main_region_do_render_draw(const Scene *scene) -{ - RenderEngineType *type = RE_engines_find(scene->r.engine); - return (type && type->view_update && type->view_draw); -} - -bool ED_view3d_calc_render_border( - const Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *ar, rcti *rect) -{ - RegionView3D *rv3d = ar->regiondata; - bool use_border; - - /* test if there is a 3d view rendering */ - if (v3d->shading.type != OB_RENDER || !view3d_main_region_do_render_draw(scene)) { - return false; - } - - /* test if there is a border render */ - if (rv3d->persp == RV3D_CAMOB) { - use_border = (scene->r.mode & R_BORDER) != 0; - } - else { - use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0; - } - - if (!use_border) { - return false; - } - - /* compute border */ - if (rv3d->persp == RV3D_CAMOB) { - rctf viewborder; - ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false); - - rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); - rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); - rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); - rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); - } - else { - rect->xmin = v3d->render_border.xmin * ar->winx; - rect->xmax = v3d->render_border.xmax * ar->winx; - rect->ymin = v3d->render_border.ymin * ar->winy; - rect->ymax = v3d->render_border.ymax * ar->winy; - } - - BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin); - BLI_rcti_isect(&ar->winrct, rect, rect); - - return true; -} -- cgit v1.2.3 From 0f7a90d4ad2c144b82679c24020e1338a3fc7cef Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 7 Feb 2020 11:58:51 +0100 Subject: Cleanup: `make format` Dear developers remember to set your coding environment to use clang-format. --- source/blender/blenkernel/intern/lattice.c | 11 ++++++----- source/blender/collada/ErrorHandler.cpp | 3 ++- source/blender/editors/mesh/editmesh_tools.c | 10 ++++++++-- source/blender/editors/render/render_preview.c | 3 ++- source/blender/makesrna/intern/rna_brush.c | 6 +++++- source/blender/modifiers/intern/MOD_curve.c | 10 ++++++++-- source/blender/modifiers/intern/MOD_lattice.c | 10 ++++++++-- source/blender/modifiers/intern/MOD_smooth.c | 5 +++-- 8 files changed, 42 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 243c63a8f03..a09e97d4fed 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -783,7 +783,7 @@ void curve_deform_verts(Object *cuOb, if (cu->flag & CU_DEFORM_BOUNDS_OFF) { for (a = 0, dvert_iter = dvert; a < numVerts; a++, dvert_iter++) { - const float weight = invert_vgroup? 1.0f - defvert_find_weight(dvert_iter, defgrp_index) : + const float weight = invert_vgroup ? 1.0f - defvert_find_weight(dvert_iter, defgrp_index) : defvert_find_weight(dvert_iter, defgrp_index); if (weight > 0.0f) { @@ -800,7 +800,7 @@ void curve_deform_verts(Object *cuOb, INIT_MINMAX(cd.dmin, cd.dmax); for (a = 0, dvert_iter = dvert; a < numVerts; a++, dvert_iter++) { - const float weight = invert_vgroup? 1.0f - defvert_find_weight(dvert_iter, defgrp_index) : + const float weight = invert_vgroup ? 1.0f - defvert_find_weight(dvert_iter, defgrp_index) : defvert_find_weight(dvert_iter, defgrp_index); if (weight > 0.0f) { mul_m4_v3(cd.curvespace, vert_coords[a]); @@ -809,7 +809,7 @@ void curve_deform_verts(Object *cuOb, } for (a = 0, dvert_iter = dvert; a < numVerts; a++, dvert_iter++) { - const float weight = invert_vgroup? 1.0f - defvert_find_weight(dvert_iter, defgrp_index) : + const float weight = invert_vgroup ? 1.0f - defvert_find_weight(dvert_iter, defgrp_index) : defvert_find_weight(dvert_iter, defgrp_index); if (weight > 0.0f) { @@ -899,8 +899,9 @@ static void lattice_deform_vert_task(void *__restrict userdata, const LatticeDeformUserdata *data = userdata; if (data->dvert != NULL) { - const float weight = data->invert_vgroup? 1.0f - defvert_find_weight(data->dvert + index, data->defgrp_index) : - defvert_find_weight(data->dvert + index, data->defgrp_index); + const float weight = data->invert_vgroup ? + 1.0f - defvert_find_weight(data->dvert + index, data->defgrp_index) : + defvert_find_weight(data->dvert + index, data->defgrp_index); if (weight > 0.0f) { calc_latt_deform(data->lattice_deform_data, data->vert_coords[index], weight * data->fac); } diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp index 4f70281fb45..286bcbfb759 100644 --- a/source/blender/collada/ErrorHandler.cpp +++ b/source/blender/collada/ErrorHandler.cpp @@ -79,7 +79,8 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) error_context = "File access"; } - else if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_REQUIRED_ATTRIBUTE_MISSING) { + else if (parserError.getErrorType() == + GeneratedSaxParser::ParserError::ERROR_REQUIRED_ATTRIBUTE_MISSING) { isError = true; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 0c564bb7593..bd8017acd28 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3935,7 +3935,10 @@ static Base *mesh_separate_tagged( /* DAG_relations_tag_update(bmain); */ /* new in 2.5 */ - BKE_object_material_array_assign(bmain, base_new->object, BKE_object_material_array(obedit), *BKE_object_material_num(obedit)); + BKE_object_material_array_assign(bmain, + base_new->object, + BKE_object_material_array(obedit), + *BKE_object_material_num(obedit)); ED_object_base_select(base_new, BA_SELECT); @@ -4002,7 +4005,10 @@ static Base *mesh_separate_arrays(Main *bmain, /* DAG_relations_tag_update(bmain); */ /* new in 2.5 */ - BKE_object_material_array_assign(bmain, base_new->object, BKE_object_material_array(obedit), *BKE_object_material_num(obedit)); + BKE_object_material_array_assign(bmain, + base_new->object, + BKE_object_material_array(obedit), + *BKE_object_material_num(obedit)); ED_object_base_select(base_new, BA_SELECT); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 3ea583e5b1f..96bc5648b75 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -465,7 +465,8 @@ static Scene *preview_prepare_scene( copy_v4_v4(base->object->color, sp->color); if (OB_TYPE_SUPPORT_MATERIAL(base->object->type)) { - /* don't use BKE_object_material_assign, it changed mat->id.us, which shows in the UI */ + /* don't use BKE_object_material_assign, it changed mat->id.us, which shows in the UI + */ Material ***matar = BKE_object_material_array(base->object); int actcol = max_ii(base->object->actcol - 1, 0); diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index edbaa13f80c..3c9942f32c7 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -151,7 +151,11 @@ const EnumPropertyItem rna_enum_brush_gpencil_types_items[] = { #ifndef RNA_RUNTIME static EnumPropertyItem rna_enum_gpencil_brush_eraser_modes_items[] = { - {GP_BRUSH_ERASER_SOFT, "SOFT", 0, "Dissolve,", "Erase strokes, fading their points strength and thickness"}, + {GP_BRUSH_ERASER_SOFT, + "SOFT", + 0, + "Dissolve,", + "Erase strokes, fading their points strength and thickness"}, {GP_BRUSH_ERASER_HARD, "HARD", 0, "Point", "Erase stroke points"}, {GP_BRUSH_ERASER_STROKE, "STROKE", 0, "Stroke", "Erase entire strokes"}, {0, NULL, 0, NULL, NULL}, diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 7bfe63e562a..3f26686d45a 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -119,8 +119,14 @@ static void deformVerts(ModifierData *md, /* silly that defaxis and curve_deform_verts are off by 1 * but leave for now to save having to call do_versions */ - curve_deform_verts( - cmd->object, ctx->object, vertexCos, numVerts, dvert, defgrp_index, cmd->flag, cmd->defaxis - 1); + curve_deform_verts(cmd->object, + ctx->object, + vertexCos, + numVerts, + dvert, + defgrp_index, + cmd->flag, + cmd->defaxis - 1); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index 3128183060a..21131a7c898 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -101,8 +101,14 @@ static void deformVerts(ModifierData *md, MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */ - lattice_deform_verts( - lmd->object, ctx->object, mesh_src, vertexCos, numVerts, lmd->flag, lmd->name, lmd->strength); + lattice_deform_verts(lmd->object, + ctx->object, + mesh_src, + vertexCos, + numVerts, + lmd->flag, + lmd->name, + lmd->strength); if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 59ed3b0b005..c879b2d3754 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -140,8 +140,9 @@ static void smoothModifier_do( } float *vco_new = accumulated_vecs[i]; - const float f_new = invert_vgroup ? (1.0f - defvert_find_weight(dv, defgrp_index)) * fac_new : - defvert_find_weight(dv, defgrp_index) * fac_new; + const float f_new = invert_vgroup ? + (1.0f - defvert_find_weight(dv, defgrp_index)) * fac_new : + defvert_find_weight(dv, defgrp_index) * fac_new; if (f_new <= 0.0f) { continue; } -- cgit v1.2.3 From 28cd16ec448f57b863f8be0a8f5d303d94bc1f1f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 7 Feb 2020 12:00:57 +0100 Subject: Cleanup: Tracking, reduce scope of variables Mainly affects for() loops. The reason why loop parameter was declared outside of the loop roots back to the times when not all compilers supported C99. --- source/blender/blenkernel/intern/tracking.c | 114 ++++++++------------- source/blender/blenkernel/intern/tracking_auto.c | 24 ++--- source/blender/blenkernel/intern/tracking_detect.c | 7 +- .../blenkernel/intern/tracking_plane_tracker.c | 19 ++-- .../blenkernel/intern/tracking_region_tracker.c | 8 +- source/blender/blenkernel/intern/tracking_solver.c | 35 +++---- .../blender/blenkernel/intern/tracking_stabilize.c | 29 +++--- source/blender/blenkernel/intern/tracking_util.c | 27 ++--- 8 files changed, 97 insertions(+), 166 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 1e7b3af53d5..0b732677dcb 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -80,9 +80,7 @@ static struct { /* Free the whole list of tracks, list's head and tail are set to NULL. */ static void tracking_tracks_free(ListBase *tracks) { - MovieTrackingTrack *track; - - for (track = tracks->first; track; track = track->next) { + for (MovieTrackingTrack *track = tracks->first; track; track = track->next) { BKE_tracking_track_free(track); } @@ -92,9 +90,8 @@ static void tracking_tracks_free(ListBase *tracks) /* Free the whole list of plane tracks, list's head and tail are set to NULL. */ static void tracking_plane_tracks_free(ListBase *plane_tracks) { - MovieTrackingPlaneTrack *plane_track; - - for (plane_track = plane_tracks->first; plane_track; plane_track = plane_track->next) { + for (MovieTrackingPlaneTrack *plane_track = plane_tracks->first; plane_track; + plane_track = plane_track->next) { BKE_tracking_plane_track_free(plane_track); } @@ -128,10 +125,8 @@ static void tracking_object_free(MovieTrackingObject *object) /* Free list of tracking objects, list's head and tail is set to NULL. */ static void tracking_objects_free(ListBase *objects) { - MovieTrackingObject *object; - /* Free objects contents. */ - for (object = objects->first; object; object = object->next) { + for (MovieTrackingObject *object = objects->first; object; object = object->next) { tracking_object_free(object); } @@ -191,13 +186,12 @@ static void tracking_tracks_copy(ListBase *tracks_dst, GHash *tracks_mapping, const int flag) { - MovieTrackingTrack *track_dst, *track_src; - BLI_listbase_clear(tracks_dst); BLI_ghash_clear(tracks_mapping, NULL, NULL); - for (track_src = tracks_src->first; track_src != NULL; track_src = track_src->next) { - track_dst = MEM_dupallocN(track_src); + for (MovieTrackingTrack *track_src = tracks_src->first; track_src != NULL; + track_src = track_src->next) { + MovieTrackingTrack *track_dst = MEM_dupallocN(track_src); if (track_src->markers) { track_dst->markers = MEM_dupallocN(track_src->markers); } @@ -217,13 +211,12 @@ static void tracking_plane_tracks_copy(ListBase *plane_tracks_list_dst, GHash *tracks_mapping, const int flag) { - MovieTrackingPlaneTrack *plane_track_dst, *plane_track_src; - BLI_listbase_clear(plane_tracks_list_dst); - for (plane_track_src = plane_tracks_list_src->first; plane_track_src != NULL; + for (MovieTrackingPlaneTrack *plane_track_src = plane_tracks_list_src->first; + plane_track_src != NULL; plane_track_src = plane_track_src->next) { - plane_track_dst = MEM_dupallocN(plane_track_src); + MovieTrackingPlaneTrack *plane_track_dst = MEM_dupallocN(plane_track_src); if (plane_track_src->markers) { plane_track_dst->markers = MEM_dupallocN(plane_track_src->markers); } @@ -278,12 +271,11 @@ static void tracking_objects_copy(ListBase *objects_dst, GHash *tracks_mapping, const int flag) { - MovieTrackingObject *object_dst, *object_src; - BLI_listbase_clear(objects_dst); - for (object_src = objects_src->first; object_src != NULL; object_src = object_src->next) { - object_dst = MEM_mallocN(sizeof(*object_dst), __func__); + for (MovieTrackingObject *object_src = objects_src->first; object_src != NULL; + object_src = object_src->next) { + MovieTrackingObject *object_dst = MEM_mallocN(sizeof(*object_dst), __func__); tracking_object_copy(object_dst, object_src, tracks_mapping, flag); BLI_addtail(objects_dst, object_dst); } @@ -1180,9 +1172,7 @@ void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area) void BKE_tracking_tracks_deselect_all(ListBase *tracksbase) { - MovieTrackingTrack *track; - - for (track = tracksbase->first; track; track = track->next) { + for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { if ((track->flag & TRACK_HIDDEN) == 0) { BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } @@ -1269,13 +1259,12 @@ void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr) void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) { - int a; float pat_min[2], pat_max[2]; BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); if (event == CLAMP_PAT_DIM) { - for (a = 0; a < 2; a++) { + for (int a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]); marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]); @@ -1286,7 +1275,7 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) sub_v2_v2v2(dim, pat_max, pat_min); - for (a = 0; a < 2; a++) { + for (int a = 0; a < 2; a++) { int b; /* pattern shouldn't be moved outside of search */ if (pat_min[a] < marker->search_min[a]) { @@ -1302,7 +1291,7 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) } } else if (event == CLAMP_SEARCH_DIM) { - for (a = 0; a < 2; a++) { + for (int a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]); marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]); @@ -1313,7 +1302,7 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) sub_v2_v2v2(dim, marker->search_max, marker->search_min); - for (a = 0; a < 2; a++) { + for (int a = 0; a < 2; a++) { /* search shouldn't be moved inside pattern */ if (marker->search_min[a] > pat_min[a]) { marker->search_min[a] = pat_min[a]; @@ -1552,9 +1541,9 @@ MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_named(MovieTracking *track const char *name) { ListBase *plane_tracks_base = BKE_tracking_object_get_plane_tracks(tracking, object); - MovieTrackingPlaneTrack *plane_track; - for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; + plane_track = plane_track->next) { if (STREQ(plane_track->name, name)) { return plane_track; } @@ -1565,13 +1554,11 @@ MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_named(MovieTracking *track MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_active(struct MovieTracking *tracking) { - ListBase *plane_tracks_base; - if (tracking->act_plane_track == NULL) { return NULL; } - plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); + ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); /* Check that active track is in current plane tracks list */ if (BLI_findindex(plane_tracks_base, tracking->act_plane_track) != -1) { @@ -1583,9 +1570,8 @@ MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_active(struct MovieTrackin void BKE_tracking_plane_tracks_deselect_all(ListBase *plane_tracks_base) { - MovieTrackingPlaneTrack *plane_track; - - for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; + plane_track = plane_track->next) { plane_track->flag &= ~SELECT; } } @@ -1593,8 +1579,7 @@ void BKE_tracking_plane_tracks_deselect_all(ListBase *plane_tracks_base) bool BKE_tracking_plane_track_has_point_track(MovieTrackingPlaneTrack *plane_track, MovieTrackingTrack *track) { - int i; - for (i = 0; i < plane_track->point_tracksnr; i++) { + for (int i = 0; i < plane_track->point_tracksnr; i++) { if (plane_track->point_tracks[i] == track) { return true; } @@ -1605,17 +1590,14 @@ bool BKE_tracking_plane_track_has_point_track(MovieTrackingPlaneTrack *plane_tra bool BKE_tracking_plane_track_remove_point_track(MovieTrackingPlaneTrack *plane_track, MovieTrackingTrack *track) { - int i, track_index; - MovieTrackingTrack **new_point_tracks; - if (plane_track->point_tracksnr <= 4) { return false; } - new_point_tracks = MEM_mallocN(sizeof(*new_point_tracks) * (plane_track->point_tracksnr - 1), - "new point tracks array"); + MovieTrackingTrack **new_point_tracks = MEM_mallocN( + sizeof(*new_point_tracks) * (plane_track->point_tracksnr - 1), "new point tracks array"); - for (i = 0, track_index = 0; i < plane_track->point_tracksnr; i++) { + for (int i = 0, track_index = 0; i < plane_track->point_tracksnr; i++) { if (plane_track->point_tracks[i] != track) { new_point_tracks[track_index++] = plane_track->point_tracks[i]; } @@ -1649,8 +1631,7 @@ void BKE_tracking_plane_track_replace_point_track(MovieTrackingPlaneTrack *plane MovieTrackingTrack *old_track, MovieTrackingTrack *new_track) { - int i; - for (i = 0; i < plane_track->point_tracksnr; i++) { + for (int i = 0; i < plane_track->point_tracksnr; i++) { if (plane_track->point_tracks[i] == old_track) { plane_track->point_tracks[i] = new_track; break; @@ -1662,9 +1643,9 @@ void BKE_tracking_plane_tracks_replace_point_track(MovieTracking *tracking, MovieTrackingTrack *old_track, MovieTrackingTrack *new_track) { - MovieTrackingPlaneTrack *plane_track; ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); - for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; + plane_track = plane_track->next) { if (BKE_tracking_plane_track_has_point_track(plane_track, old_track)) { BKE_tracking_plane_track_replace_point_track(plane_track, old_track, new_track); } @@ -1838,23 +1819,22 @@ void BKE_tracking_plane_marker_get_subframe_corners(MovieTrackingPlaneTrack *pla { MovieTrackingPlaneMarker *marker = BKE_tracking_plane_marker_get(plane_track, (int)framenr); MovieTrackingPlaneMarker *marker_last = plane_track->markers + (plane_track->markersnr - 1); - int i; if (marker != marker_last) { MovieTrackingPlaneMarker *marker_next = marker + 1; if (marker_next->framenr == marker->framenr + 1) { float fac = (framenr - (int)framenr) / (marker_next->framenr - marker->framenr); - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { interp_v2_v2v2(corners[i], marker->corners[i], marker_next->corners[i], fac); } } else { - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { copy_v2_v2(corners[i], marker->corners[i]); } } } else { - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { copy_v2_v2(corners[i], marker->corners[i]); } } @@ -2399,7 +2379,6 @@ void BKE_tracking_max_distortion_delta_across_bound(MovieTracking *tracking, bool undistort, float delta[2]) { - int a; float pos[2], warped_pos[2]; const int coord_delta = 5; void (*apply_distortion)(MovieTracking * tracking, const float pos[2], float out[2]); @@ -2413,7 +2392,7 @@ void BKE_tracking_max_distortion_delta_across_bound(MovieTracking *tracking, delta[0] = delta[1] = -FLT_MAX; - for (a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) { + for (int a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) { if (a > rect->xmax) { a = rect->xmax; } @@ -2441,7 +2420,7 @@ void BKE_tracking_max_distortion_delta_across_bound(MovieTracking *tracking, } } - for (a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) { + for (int a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) { if (a > rect->ymax) { a = rect->ymax; } @@ -2515,9 +2494,7 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, * fractional part of offset */ if (from_anchor) { - int a; - - for (a = 0; a < 5; a++) { + for (int a = 0; a < 5; a++) { src_pixel_x[a] += (double)((track->offset[0] * frame_width) - ((int)(track->offset[0] * frame_width))); src_pixel_y[a] += (double)((track->offset[1] * frame_height) - @@ -2664,9 +2641,6 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, void BKE_tracking_disable_channels( ImBuf *ibuf, bool disable_red, bool disable_green, bool disable_blue, bool grayscale) { - int x, y; - float scale; - if (!disable_red && !disable_green && !disable_blue && !grayscale) { return; } @@ -2674,11 +2648,11 @@ void BKE_tracking_disable_channels( /* if only some components are selected, it's important to rescale the result * appropriately so that e.g. if only blue is selected, it's not zeroed out. */ - scale = (disable_red ? 0.0f : 0.2126f) + (disable_green ? 0.0f : 0.7152f) + - (disable_blue ? 0.0f : 0.0722f); + float scale = (disable_red ? 0.0f : 0.2126f) + (disable_green ? 0.0f : 0.7152f) + + (disable_blue ? 0.0f : 0.0722f); - for (y = 0; y < ibuf->y; y++) { - for (x = 0; x < ibuf->x; x++) { + for (int y = 0; y < ibuf->y; y++) { + for (int x = 0; x < ibuf->x; x++) { int pixel = ibuf->x * y + x; if (ibuf->rect_float) { @@ -2916,7 +2890,6 @@ static void tracking_dopesheet_channels_calc(MovieTracking *tracking) { MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; - MovieTrackingTrack *track; MovieTrackingReconstruction *reconstruction = BKE_tracking_object_get_reconstruction(tracking, object); ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); @@ -2924,7 +2897,7 @@ static void tracking_dopesheet_channels_calc(MovieTracking *tracking) bool sel_only = (dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY) != 0; bool show_hidden = (dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN) != 0; - for (track = tracksbase->first; track; track = track->next) { + for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { MovieTrackingDopesheetChannel *channel; if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0) { @@ -3012,13 +2985,12 @@ static void tracking_dopesheet_calc_coverage(MovieTracking *tracking) MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); - MovieTrackingTrack *track; int frames, start_frame = INT_MAX, end_frame = -INT_MAX; int *per_frame_counter; int prev_coverage, last_segment_frame; /* find frame boundaries */ - for (track = tracksbase->first; track; track = track->next) { + for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { start_frame = min_ii(start_frame, track->markers[0].framenr); end_frame = max_ii(end_frame, track->markers[track->markersnr - 1].framenr); } @@ -3029,7 +3001,7 @@ static void tracking_dopesheet_calc_coverage(MovieTracking *tracking) per_frame_counter = MEM_callocN(sizeof(int) * frames, "per frame track counter"); /* find per-frame markers count */ - for (track = tracksbase->first; track; track = track->next) { + for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { for (int i = 0; i < track->markersnr; i++) { MovieTrackingMarker *marker = &track->markers[i]; diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c index fad928c12fe..1a4df73c8aa 100644 --- a/source/blender/blenkernel/intern/tracking_auto.c +++ b/source/blender/blenkernel/intern/tracking_auto.c @@ -127,13 +127,12 @@ static void dna_marker_to_libmv_marker(/*const*/ MovieTrackingTrack *track, libmv_Marker *libmv_marker) { const int frame_dimensions[2] = {frame_width, frame_height}; - int i; libmv_marker->clip = clip; libmv_marker->frame = marker->framenr; libmv_marker->track = track_index; normalized_to_libmv_frame(marker->pos, frame_dimensions, libmv_marker->center); - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { normalized_relative_to_libmv_frame( marker->pattern_corners[i], marker->pos, frame_dimensions, libmv_marker->patch[i]); } @@ -183,11 +182,10 @@ static void libmv_marker_to_dna_marker(libmv_Marker *libmv_marker, MovieTrackingMarker *marker) { const int frame_dimensions[2] = {frame_width, frame_height}; - int i; marker->framenr = libmv_marker->frame; libmv_frame_to_normalized(libmv_marker->center, frame_dimensions, marker->pos); - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { libmv_frame_to_normalized_relative(libmv_marker->patch[i], libmv_marker->center, frame_dimensions, @@ -461,17 +459,16 @@ bool BKE_autotrack_context_step(AutoTrackContext *context) void BKE_autotrack_context_sync(AutoTrackContext *context) { int newframe, frame_delta = context->backwards ? -1 : 1; - int frame; BLI_spin_lock(&context->spin_lock); newframe = context->user.framenr; - for (frame = context->sync_frame; frame != (context->backwards ? newframe - 1 : newframe + 1); + for (int frame = context->sync_frame; + frame != (context->backwards ? newframe - 1 : newframe + 1); frame += frame_delta) { MovieTrackingMarker marker; libmv_Marker libmv_marker; int clip = 0; - int track; - for (track = 0; track < context->num_tracks; track++) { + for (int track = 0; track < context->num_tracks; track++) { AutoTrackOptions *options = &context->options[track]; int track_frame = BKE_movieclip_remap_scene_to_clip_frame( context->clips[options->clip_index], frame); @@ -522,17 +519,14 @@ void BKE_autotrack_context_sync_user(AutoTrackContext *context, MovieClipUser *u void BKE_autotrack_context_finish(AutoTrackContext *context) { - int clip_index; - - for (clip_index = 0; clip_index < context->num_clips; clip_index++) { + for (int clip_index = 0; clip_index < context->num_clips; clip_index++) { MovieClip *clip = context->clips[clip_index]; ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); - MovieTrackingPlaneTrack *plane_track; - for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; + plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { - int track; - for (track = 0; track < context->num_tracks; track++) { + for (int track = 0; track < context->num_tracks; track++) { if (BKE_tracking_plane_track_has_point_track(plane_track, context->options[track].track)) { BKE_tracking_track_plane_from_existing_motion(plane_track, context->first_frame); diff --git a/source/blender/blenkernel/intern/tracking_detect.c b/source/blender/blenkernel/intern/tracking_detect.c index ec044f14fa8..08719161e1a 100644 --- a/source/blender/blenkernel/intern/tracking_detect.c +++ b/source/blender/blenkernel/intern/tracking_detect.c @@ -38,7 +38,6 @@ /* Check whether point is inside grease pencil stroke. */ static bool check_point_in_stroke(bGPDstroke *stroke, float x, float y) { - int i, prev; int count = 0; bGPDspoint *points = stroke->points; @@ -50,9 +49,7 @@ static bool check_point_in_stroke(bGPDstroke *stroke, float x, float y) * work, but such situation is crappy anyway. */ - prev = stroke->totpoints - 1; - - for (i = 0; i < stroke->totpoints; i++) { + for (int i = 0, prev = stroke->totpoints - 1; i < stroke->totpoints; prev = i, i++) { if ((points[i].y < y && points[prev].y >= y) || (points[prev].y < y && points[i].y >= y)) { float fac = (y - points[i].y) / (points[prev].y - points[i].y); @@ -60,8 +57,6 @@ static bool check_point_in_stroke(bGPDstroke *stroke, float x, float y) count++; } } - - prev = i; } return (count % 2) ? true : false; diff --git a/source/blender/blenkernel/intern/tracking_plane_tracker.c b/source/blender/blenkernel/intern/tracking_plane_tracker.c index 602243a7d50..e0e8a68bb1e 100644 --- a/source/blender/blenkernel/intern/tracking_plane_tracker.c +++ b/source/blender/blenkernel/intern/tracking_plane_tracker.c @@ -39,13 +39,13 @@ typedef double Vec2[2]; static int point_markers_correspondences_on_both_image( MovieTrackingPlaneTrack *plane_track, int frame1, int frame2, Vec2 **x1_r, Vec2 **x2_r) { - int i, correspondence_index; Vec2 *x1, *x2; *x1_r = x1 = MEM_mallocN(sizeof(*x1) * plane_track->point_tracksnr, "point correspondences x1"); *x2_r = x2 = MEM_mallocN(sizeof(*x1) * plane_track->point_tracksnr, "point correspondences x2"); - for (i = 0, correspondence_index = 0; i < plane_track->point_tracksnr; i++) { + int correspondence_index = 0; + for (int i = 0; i < plane_track->point_tracksnr; i++) { MovieTrackingTrack *point_track = plane_track->point_tracks[i]; MovieTrackingMarker *point_marker1, *point_marker2; @@ -77,11 +77,11 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac start_frame); MovieTrackingPlaneMarker *keyframe_plane_marker = NULL; MovieTrackingPlaneMarker new_plane_marker; - int current_frame, frame_delta = direction > 0 ? 1 : -1; + int frame_delta = direction > 0 ? 1 : -1; if (plane_track->flag & PLANE_TRACK_AUTOKEY) { /* Find a keyframe in given direction. */ - for (current_frame = start_frame;; current_frame += frame_delta) { + for (int current_frame = start_frame;; current_frame += frame_delta) { MovieTrackingPlaneMarker *next_plane_marker = BKE_tracking_plane_marker_get_exact( plane_track, current_frame + frame_delta); @@ -102,11 +102,10 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac new_plane_marker = *start_plane_marker; new_plane_marker.flag |= PLANE_MARKER_TRACKED; - for (current_frame = start_frame;; current_frame += frame_delta) { + for (int current_frame = start_frame;; current_frame += frame_delta) { MovieTrackingPlaneMarker *next_plane_marker = BKE_tracking_plane_marker_get_exact( plane_track, current_frame + frame_delta); Vec2 *x1, *x2; - int i, num_correspondences; double H_double[3][3]; float H[3][3]; @@ -118,13 +117,11 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac } } - num_correspondences = point_markers_correspondences_on_both_image( + const int num_correspondences = point_markers_correspondences_on_both_image( plane_track, current_frame, current_frame + frame_delta, &x1, &x2); - if (num_correspondences < 4) { MEM_freeN(x1); MEM_freeN(x2); - break; } @@ -132,7 +129,7 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac copy_m3_m3d(H, H_double); - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { float vec[3] = {0.0f, 0.0f, 1.0f}, vec2[3]; copy_v2_v2(vec, new_plane_marker.corners[i]); @@ -155,7 +152,7 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac fac = 3 * fac * fac - 2 * fac * fac * fac; - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { interp_v2_v2v2(new_plane_marker.corners[i], new_plane_marker.corners[i], next_plane_marker->corners[i], diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c index 1d6bb88c3f4..967642c03a8 100644 --- a/source/blender/blenkernel/intern/tracking_region_tracker.c +++ b/source/blender/blenkernel/intern/tracking_region_tracker.c @@ -50,9 +50,7 @@ static void float_rgba_to_gray(const float *rgba, float weight_green, float weight_blue) { - int i; - - for (i = 0; i < num_pixels; i++) { + for (int i = 0; i < num_pixels; i++) { const float *pixel = rgba + 4 * i; gray[i] = weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]; @@ -66,9 +64,7 @@ static void uint8_rgba_to_float_gray(const unsigned char *rgba, float weight_green, float weight_blue) { - int i; - - for (i = 0; i < num_pixels; i++) { + for (int i = 0; i < num_pixels; i++) { const unsigned char *pixel = rgba + i * 4; gray[i] = (weight_red * pixel[0] + weight_green * pixel[1] + weight_blue * pixel[2]) / 255.0f; diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c index ab741eed410..bedb55ae44e 100644 --- a/source/blender/blenkernel/intern/tracking_solver.c +++ b/source/blender/blenkernel/intern/tracking_solver.c @@ -90,13 +90,10 @@ static struct libmv_Tracks *libmv_tracks_new(MovieClip *clip, track = tracksbase->first; while (track) { - FCurve *weight_fcurve; - int a = 0; - - weight_fcurve = id_data_find_fcurve( + FCurve *weight_fcurve = id_data_find_fcurve( &clip->id, track, &RNA_MovieTrackingTrack, "weight", 0, NULL); - for (a = 0; a < track->markersnr; a++) { + for (int a = 0; a < track->markersnr; a++) { MovieTrackingMarker *marker = &track->markers[a]; if ((marker->flag & MARKER_DISABLED) == 0) { @@ -149,7 +146,7 @@ static bool reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, MovieReconstructedCamera *reconstructed; MovieTrackingTrack *track; ListBase *tracksbase = NULL; - int tracknr = 0, a; + int tracknr = 0; bool ok = true; bool origin_set = false; int sfra = context->sfra, efra = context->efra; @@ -200,16 +197,16 @@ static bool reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, reconstructed = MEM_callocN((efra - sfra + 1) * sizeof(MovieReconstructedCamera), "temp reconstructed camera"); - for (a = sfra; a <= efra; a++) { + for (int a = sfra; a <= efra; a++) { double matd[4][4]; if (libmv_reprojectionCameraForImage(libmv_reconstruction, a, matd)) { - int i, j; float mat[4][4]; float error = libmv_reprojectionErrorForImage(libmv_reconstruction, a); - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { + /* TODO(sergey): Use transpose utility. */ + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { mat[i][j] = matd[i][j]; } } @@ -591,21 +588,19 @@ static void tracking_scale_reconstruction(ListBase *tracksbase, MovieTrackingReconstruction *reconstruction, const float scale[3]) { - MovieTrackingTrack *track; - int i; float first_camera_delta[3] = {0.0f, 0.0f, 0.0f}; if (reconstruction->camnr > 0) { mul_v3_v3v3(first_camera_delta, reconstruction->cameras[0].mat[3], scale); } - for (i = 0; i < reconstruction->camnr; i++) { + for (int i = 0; i < reconstruction->camnr; i++) { MovieReconstructedCamera *camera = &reconstruction->cameras[i]; mul_v3_v3(camera->mat[3], scale); sub_v3_v3(camera->mat[3], first_camera_delta); } - for (track = tracksbase->first; track; track = track->next) { + for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { if (track->flag & TRACK_HAS_BUNDLE) { mul_v3_v3(track->bundle_pos, scale); sub_v3_v3(track->bundle_pos, first_camera_delta); @@ -618,14 +613,10 @@ static void tracking_scale_reconstruction(ListBase *tracksbase, */ void BKE_tracking_reconstruction_scale(MovieTracking *tracking, float scale[3]) { - MovieTrackingObject *object; - - for (object = tracking->objects.first; object; object = object->next) { - ListBase *tracksbase; - MovieTrackingReconstruction *reconstruction; - - tracksbase = BKE_tracking_object_get_tracks(tracking, object); - reconstruction = BKE_tracking_object_get_reconstruction(tracking, object); + for (MovieTrackingObject *object = tracking->objects.first; object; object = object->next) { + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); + MovieTrackingReconstruction *reconstruction = BKE_tracking_object_get_reconstruction(tracking, + object); tracking_scale_reconstruction(tracksbase, reconstruction, scale); } diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c index 2c270f10908..d2d60e93a08 100644 --- a/source/blender/blenkernel/intern/tracking_stabilize.c +++ b/source/blender/blenkernel/intern/tracking_stabilize.c @@ -545,7 +545,6 @@ static bool average_track_contributions(StabContext *ctx, { bool ok; float weight_sum; - MovieTrackingTrack *track; MovieTracking *tracking = ctx->tracking; MovieTrackingStabilization *stab = &tracking->stabilization; float ref_pos[2]; @@ -559,7 +558,7 @@ static bool average_track_contributions(StabContext *ctx, ok = false; weight_sum = 0.0f; - for (track = tracking->tracks.first; track; track = track->next) { + for (MovieTrackingTrack *track = tracking->tracks.first; track; track = track->next) { if (!is_init_for_stabilization(ctx, track)) { continue; } @@ -597,7 +596,7 @@ static bool average_track_contributions(StabContext *ctx, ok = false; weight_sum = 0.0f; - for (track = tracking->tracks.first; track; track = track->next) { + for (MovieTrackingTrack *track = tracking->tracks.first; track; track = track->next) { if (!is_init_for_stabilization(ctx, track)) { continue; } @@ -652,12 +651,11 @@ static void average_marker_positions(StabContext *ctx, int framenr, float r_ref_ { bool ok = false; float weight_sum; - MovieTrackingTrack *track; MovieTracking *tracking = ctx->tracking; zero_v2(r_ref_pos); weight_sum = 0.0f; - for (track = tracking->tracks.first; track; track = track->next) { + for (MovieTrackingTrack *track = tracking->tracks.first; track; track = track->next) { if (track->flag & TRACK_USE_2D_STAB) { float weight = 0.0f; MovieTrackingMarker *marker = get_tracking_data_point(ctx, track, framenr, &weight); @@ -680,7 +678,7 @@ static void average_marker_positions(StabContext *ctx, int framenr, float r_ref_ int next_lower = MINAFRAME; int next_higher = MAXFRAME; use_values_from_fcurves(ctx, true); - for (track = tracking->tracks.first; track; track = track->next) { + for (MovieTrackingTrack *track = tracking->tracks.first; track; track = track->next) { /* Note: we deliberately do not care if this track * is already initialized for stabilization. */ if (track->flag & TRACK_USE_2D_STAB) { @@ -771,11 +769,10 @@ static bool interpolate_averaged_track_contributions(StabContext *ctx, static int establish_track_initialization_order(StabContext *ctx, TrackInitOrder *order) { size_t tracknr = 0; - MovieTrackingTrack *track; MovieTracking *tracking = ctx->tracking; int anchor_frame = tracking->stabilization.anchor_frame; - for (track = tracking->tracks.first; track != NULL; track = track->next) { + for (MovieTrackingTrack *track = tracking->tracks.first; track != NULL; track = track->next) { MovieTrackingMarker *marker; order[tracknr].data = track; marker = get_closest_marker(ctx, track, anchor_frame); @@ -880,10 +877,9 @@ static void initialize_track_for_stabilization(StabContext *ctx, static void initialize_all_tracks(StabContext *ctx, float aspect) { - size_t i, track_len = 0; + size_t track_len = 0; MovieClip *clip = ctx->clip; MovieTracking *tracking = ctx->tracking; - MovieTrackingTrack *track; TrackInitOrder *order; /* Attempt to start initialization at anchor_frame. @@ -896,7 +892,7 @@ static void initialize_all_tracks(StabContext *ctx, float aspect) zero_v2(pivot); /* Initialize private working data. */ - for (track = tracking->tracks.first; track != NULL; track = track->next) { + for (MovieTrackingTrack *track = tracking->tracks.first; track != NULL; track = track->next) { TrackStabilizationBase *local_data = access_stabilization_baseline_data(ctx, track); if (!local_data) { local_data = MEM_callocN(sizeof(TrackStabilizationBase), @@ -927,8 +923,8 @@ static void initialize_all_tracks(StabContext *ctx, float aspect) average_marker_positions(ctx, reference_frame, average_pos); setup_pivot(average_pos, pivot); - for (i = 0; i < track_len; i++) { - track = order[i].data; + for (int i = 0; i < track_len; i++) { + MovieTrackingTrack *track = order[i].data; if (reference_frame != order[i].reference_frame) { reference_frame = order[i].reference_frame; average_track_contributions(ctx, @@ -1142,12 +1138,11 @@ static float calculate_autoscale_factor(StabContext *ctx, int size, float aspect float pixel_aspect = ctx->tracking->camera.pixel_aspect; int height = size, width = aspect * size; - int sfra = INT_MAX, efra = INT_MIN, cfra; + int sfra = INT_MAX, efra = INT_MIN; float scale = 1.0f, scale_step = 0.0f; - MovieTrackingTrack *track; /* Calculate maximal frame range of tracks where stabilization is active. */ - for (track = ctx->tracking->tracks.first; track; track = track->next) { + for (MovieTrackingTrack *track = ctx->tracking->tracks.first; track; track = track->next) { if ((track->flag & TRACK_USE_2D_STAB) || ((stab->flag & TRACKING_STABILIZE_ROTATION) && (track->flag & TRACK_USE_2D_STAB_ROT))) { int first_frame = track->markers[0].framenr; @@ -1158,7 +1153,7 @@ static float calculate_autoscale_factor(StabContext *ctx, int size, float aspect } use_values_from_fcurves(ctx, true); - for (cfra = sfra; cfra <= efra; cfra++) { + for (int cfra = sfra; cfra <= efra; cfra++) { float translation[2], pivot[2], angle, tmp_scale; float mat[4][4]; const float points[4][2] = {{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}}; diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c index ed582dc5b94..ada6ce96d58 100644 --- a/source/blender/blenkernel/intern/tracking_util.c +++ b/source/blender/blenkernel/intern/tracking_util.c @@ -126,7 +126,6 @@ void tracks_map_merge(TracksMap *map, MovieTracking *tracking) MovieTrackingTrack *track; ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL}; ListBase *old_tracks; - int a; if (map->is_camera) { old_tracks = &tracking->tracks; @@ -146,7 +145,7 @@ void tracks_map_merge(TracksMap *map, MovieTracking *tracking) * this is needed to keep names in unique state and it's faster to change names * of currently operating tracks (if needed) */ - for (a = 0; a < map->num_tracks; a++) { + for (int a = 0; a < map->num_tracks; a++) { MovieTrackingTrack *old_track; bool mapped_to_old = false; @@ -221,11 +220,9 @@ void tracks_map_merge(TracksMap *map, MovieTracking *tracking) void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata)) { - int i = 0; - BLI_ghash_free(map->hash, NULL, NULL); - for (i = 0; i < map->num_tracks; i++) { + for (int i = 0; i < map->num_tracks; i++) { if (map->customdata && customdata_free) { customdata_free(&map->customdata[i * map->customdata_size]); } @@ -345,12 +342,11 @@ void tracking_get_marker_coords_for_tracking(int frame_width, double search_pixel_x[5], double search_pixel_y[5]) { - int i; float unified_coords[2]; float pixel_coords[2]; /* Convert the corners into search space coordinates. */ - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { marker_unified_to_search_pixel( frame_width, frame_height, marker, marker->pattern_corners[i], pixel_coords); search_pixel_x[i] = pixel_coords[0] - 0.5f; @@ -373,12 +369,11 @@ void tracking_set_marker_coords_from_tracking(int frame_width, const double search_pixel_x[5], const double search_pixel_y[5]) { - int i; float marker_unified[2]; float search_pixel[2]; /* Convert the corners into search space coordinates. */ - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { search_pixel[0] = search_pixel_x[i] + 0.5; search_pixel[1] = search_pixel_y[i] + 0.5; search_pixel_to_marker_unified( @@ -394,7 +389,7 @@ void tracking_set_marker_coords_from_tracking(int frame_width, * Otherwise, the entire patch shifted, and that delta should be applied to * all the coordinates. */ - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { marker->pattern_corners[i][0] -= marker_unified[0]; marker->pattern_corners[i][1] -= marker_unified[1]; } @@ -672,8 +667,6 @@ static ImBuf *accessor_get_preprocessed_ibuf(TrackingImageAccessor *accessor, static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf) { ImBuf *grayscale = IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0); - size_t size; - int i; BLI_assert(ibuf->channels == 3 || ibuf->channels == 4); @@ -682,13 +675,13 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf) * * Will generalize it later. */ - size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float); + const size_t size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float); grayscale->channels = 1; if ((grayscale->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) { grayscale->mall |= IB_rectfloat; grayscale->flags |= IB_rectfloat; - for (i = 0; i < grayscale->x * grayscale->y; i++) { + for (int i = 0; i < grayscale->x * grayscale->y; i++) { const float *pixel = ibuf->rect_float + ibuf->channels * i; grayscale->rect_float[i] = 0.2126f * pixel[0] + 0.7152f * pixel[1] + 0.0722f * pixel[2]; @@ -785,14 +778,12 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, clamped_height); } else { - int y; /* TODO(sergey): We don't do any color space or alpha conversion * here. Probably Libmv is better to work in the linear space, * but keep sRGB space here for compatibility for now. */ - for (y = 0; y < clamped_height; y++) { - int x; - for (x = 0; x < clamped_width; x++) { + for (int y = 0; y < clamped_height; y++) { + for (int x = 0; x < clamped_width; x++) { int src_x = x + clamped_origin_x, src_y = y + clamped_origin_y; int dst_x = x + dst_offset_x, dst_y = y + dst_offset_y; int dst_index = (dst_y * width + dst_x) * 4, -- cgit v1.2.3 From b1f1a1ca6035e23d66656c97c16fe081caafcae8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 7 Feb 2020 12:16:23 +0100 Subject: Cleanup: Tracking, reduce scope of more variables --- source/blender/blenkernel/intern/tracking.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 0b732677dcb..37ca6b1885d 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1276,15 +1276,14 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) sub_v2_v2v2(dim, pat_max, pat_min); for (int a = 0; a < 2; a++) { - int b; /* pattern shouldn't be moved outside of search */ if (pat_min[a] < marker->search_min[a]) { - for (b = 0; b < 4; b++) { + for (int b = 0; b < 4; b++) { marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a]; } } if (pat_max[a] > marker->search_max[a]) { - for (b = 0; b < 4; b++) { + for (int b = 0; b < 4; b++) { marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a]; } } -- cgit v1.2.3 From ad489b71646a2e03e2ce9b0d193d541e3987b4cd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 3 Feb 2020 09:02:00 +0100 Subject: Cleanup: add type inheritance for Cycles nodes --- intern/cycles/app/cycles_xml.cpp | 4 ++++ intern/cycles/graph/node.cpp | 10 ++++++++++ intern/cycles/graph/node.h | 3 +++ intern/cycles/graph/node_type.cpp | 11 ++++++++--- intern/cycles/graph/node_type.h | 16 ++++++++++++++-- intern/cycles/graph/node_xml.cpp | 4 ++-- 6 files changed, 41 insertions(+), 7 deletions(-) diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 1dbe8a30ff2..bdb014d31ef 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -326,6 +326,10 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node fprintf(stderr, "Node type \"%s\" is not a shader node.\n", node_type->name.c_str()); continue; } + else if (node_type->create == NULL) { + fprintf(stderr, "Can't create abstract node type \"%s\".\n", node_type->name.c_str()); + continue; + } snode = (ShaderNode *)node_type->create(node_type); } diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index 4f79a7518dc..1439fb5a407 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -669,4 +669,14 @@ size_t Node::get_total_size_in_bytes() const return total_size; } +bool Node::is_a(const NodeType *type_) +{ + for (const NodeType *base = type; base; base = base->base) { + if (base == type_) { + return true; + } + } + return false; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h index d35a1bb489c..4473b8aca28 100644 --- a/intern/cycles/graph/node.h +++ b/intern/cycles/graph/node.h @@ -94,6 +94,9 @@ struct Node { /* Get total size of this node. */ size_t get_total_size_in_bytes() const; + /* Type testing, taking into account base classes. */ + bool is_a(const NodeType *type); + ustring name; const NodeType *type; }; diff --git a/intern/cycles/graph/node_type.cpp b/intern/cycles/graph/node_type.cpp index f46d4e48026..0283ed7c817 100644 --- a/intern/cycles/graph/node_type.cpp +++ b/intern/cycles/graph/node_type.cpp @@ -135,8 +135,13 @@ bool SocketType::is_float3(Type type) /* Node Type */ -NodeType::NodeType(Type type_) : type(type_) +NodeType::NodeType(Type type, const NodeType *base) : type(type), base(base) { + if (base) { + /* Inherit sockets. */ + inputs = base->inputs; + outputs = base->outputs; + } } NodeType::~NodeType() @@ -209,7 +214,7 @@ unordered_map &NodeType::types() return _types; } -NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_) +NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_, const NodeType *base_) { ustring name(name_); @@ -219,7 +224,7 @@ NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_) return NULL; } - types()[name] = NodeType(type_); + types()[name] = NodeType(type_, base_); NodeType *type = &types()[name]; type->name = name; diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h index e9496a42658..a4461ec7abb 100644 --- a/intern/cycles/graph/node_type.h +++ b/intern/cycles/graph/node_type.h @@ -103,7 +103,7 @@ struct SocketType { struct NodeType { enum Type { NONE, SHADER }; - explicit NodeType(Type type = NONE); + explicit NodeType(Type type = NONE, const NodeType *base = NULL); ~NodeType(); void register_input(ustring name, @@ -124,11 +124,15 @@ struct NodeType { ustring name; Type type; + const NodeType *base; vector> inputs; vector> outputs; CreateFunc create; - static NodeType *add(const char *name, CreateFunc create, Type type = NONE); + static NodeType *add(const char *name, + CreateFunc create, + Type type = NONE, + const NodeType *base = NULL); static const NodeType *find(ustring name); static unordered_map &types(); }; @@ -148,6 +152,14 @@ struct NodeType { } \ template const NodeType *structname::register_type() +#define NODE_ABSTRACT_DECLARE \ + template static const NodeType *register_type(); \ + static const NodeType *node_type; + +#define NODE_ABSTRACT_DEFINE(structname) \ + const NodeType *structname::node_type = structname::register_type(); \ + template const NodeType *structname::register_type() + /* Sock Definition Macros */ #define SOCKET_OFFSETOF(T, name) (((char *)&(((T *)1)->name)) - (char *)1) diff --git a/intern/cycles/graph/node_xml.cpp b/intern/cycles/graph/node_xml.cpp index a96970cc904..d333400cc4a 100644 --- a/intern/cycles/graph/node_xml.cpp +++ b/intern/cycles/graph/node_xml.cpp @@ -200,7 +200,7 @@ void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node) map::iterator it = reader.node_map.find(value); if (it != reader.node_map.end()) { Node *value_node = it->second; - if (value_node->type == *(socket.node_type)) + if (value_node->is_a(*(socket.node_type))) node->set(socket, it->second); } break; @@ -215,7 +215,7 @@ void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node) map::iterator it = reader.node_map.find(ustring(tokens[i])); if (it != reader.node_map.end()) { Node *value_node = it->second; - value[i] = (value_node->type == *(socket.node_type)) ? value_node : NULL; + value[i] = (value_node->is_a(*(socket.node_type))) ? value_node : NULL; } else { value[i] = NULL; -- cgit v1.2.3 From 7b66f73558d1e4dda308366bc8ad2b5dfa8009d3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 2 Feb 2020 13:09:18 +0100 Subject: Cleanup: export particle hair as a separate Cycles object --- intern/cycles/blender/blender_curves.cpp | 24 ++++++++++++++- intern/cycles/blender/blender_mesh.cpp | 20 +++++++------ intern/cycles/blender/blender_object.cpp | 42 ++++++++++++++++---------- intern/cycles/blender/blender_sync.cpp | 6 ++-- intern/cycles/blender/blender_sync.h | 11 ++++--- intern/cycles/blender/blender_util.h | 51 ++++++++++++++++++++++++++++---- 6 files changed, 114 insertions(+), 40 deletions(-) diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 78db1d5c832..755214f422c 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -964,7 +964,29 @@ void BlenderSync::sync_curve_settings() curve_system_manager->tag_update(scene); } -void BlenderSync::sync_curves( +bool BlenderSync::object_has_particle_hair(BL::Object b_ob) +{ + /* Test if the object has a particle modifier with hair. */ + BL::Object::modifiers_iterator b_mod; + for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) { + if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && + (preview ? b_mod->show_viewport() : b_mod->show_render())) { + BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr); + BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr); + BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); + + if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && + (b_part.type() == BL::ParticleSettings::type_HAIR)) { + return true; + } + } + } + + return false; +} + +/* Old particle hair. */ +void BlenderSync::sync_particle_hair( Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) { if (!motion) { diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index b18f9a37948..d3dac3c6151 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -967,12 +967,12 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, BL::Object &b_ob, BL::Object &b_ob_instance, bool object_updated, - bool show_self, - bool show_particles) + bool use_particle_hair) { /* test if we can instance or if the object is modified */ BL::ID b_ob_data = b_ob.data(); - BL::ID key = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; + BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; + MeshKey key(b_key_id.ptr.data, use_particle_hair); BL::Material material_override = view_layer.material_override; /* find shader indices */ @@ -1006,7 +1006,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, } Mesh *mesh; - if (!mesh_map.sync(&mesh, key)) { + if (!mesh_map.sync(&mesh, b_key_id, key)) { /* if transform was applied to mesh, need full update */ if (object_updated && mesh->transform_applied) ; @@ -1078,7 +1078,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, if (b_mesh) { /* Sync mesh itself. */ - if (view_layer.use_surfaces && show_self) { + if (view_layer.use_surfaces && !use_particle_hair) { if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders, dicing_rate, max_subdivisions); else @@ -1088,9 +1088,9 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, } /* Sync hair curves. */ - if (view_layer.use_hair && show_particles && + if (view_layer.use_hair && use_particle_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE) { - sync_curves(mesh, b_mesh, b_ob, false); + sync_particle_hair(mesh, b_mesh, b_ob, false); } free_object_to_mesh(b_data, b_ob, b_mesh); @@ -1099,7 +1099,9 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, mesh->geometry_flags = requested_geometry_flags; /* mesh fluid motion mantaflow */ - sync_mesh_fluid_motion(b_ob, scene, mesh); + if (!use_particle_hair) { + sync_mesh_fluid_motion(b_ob, scene, mesh); + } /* tag update */ bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) || @@ -1258,7 +1260,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph &b_depsgraph, /* hair motion */ if (numkeys) - sync_curves(mesh, b_mesh, b_ob, true, motion_step); + sync_particle_hair(mesh, b_mesh, b_ob, true, motion_step); /* free derived mesh */ free_object_to_mesh(b_data, b_ob, b_mesh); diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 6981412bb88..c397a95fa71 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -115,7 +115,7 @@ void BlenderSync::sync_light(BL::Object &b_parent, { /* test if we need to sync */ Light *light; - ObjectKey key(b_parent, persistent_id, b_ob_instance); + ObjectKey key(b_parent, persistent_id, b_ob_instance, false); BL::Light b_light(b_ob.data()); /* Update if either object or light data changed. */ @@ -254,7 +254,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) if (sample_as_light || use_portal) { /* test if we need to sync */ Light *light; - ObjectKey key(b_world, 0, b_world); + ObjectKey key(b_world, 0, b_world, false); if (light_map.sync(&light, b_world, b_world, key) || world_recalc || b_world.ptr.data != world_map) { @@ -295,8 +295,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, BL::ViewLayer &b_view_layer, BL::DepsgraphObjectInstance &b_instance, float motion_time, - bool show_self, - bool show_particles, + bool use_particle_hair, bool show_lights, BlenderObjectCulling &culling, bool *use_portal) @@ -378,7 +377,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, } /* key to lookup object */ - ObjectKey key(b_parent, persistent_id, b_ob_instance); + ObjectKey key(b_parent, persistent_id, b_ob_instance, use_particle_hair); Object *object; /* motion vector case */ @@ -407,8 +406,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, object_updated = true; /* mesh sync */ - object->mesh = sync_mesh( - b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles); + object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, use_particle_hair); /* special case not tracked by object update flags */ @@ -552,22 +550,34 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, BL::DepsgraphObjectInstance b_instance = *b_instance_iter; BL::Object b_ob = b_instance.object(); - /* load per-object culling data */ + /* Viewport visibility. */ + const bool show_in_viewport = !b_v3d || b_ob.visible_in_viewport_get(b_v3d); + if (show_in_viewport == false) { + continue; + } + + /* Load per-object culling data. */ culling.init_object(scene, b_ob); - /* test if object needs to be hidden */ - const bool show_self = b_instance.show_self(); - const bool show_particles = b_instance.show_particles(); - const bool show_in_viewport = !b_v3d || b_ob.visible_in_viewport_get(b_v3d); + /* Object itself. */ + if (b_instance.show_self()) { + sync_object(b_depsgraph, + b_view_layer, + b_instance, + motion_time, + false, + show_lights, + culling, + &use_portal); + } - if (show_in_viewport && (show_self || show_particles)) { - /* object itself */ + /* Particle hair as separate object. */ + if (b_instance.show_particles() && object_has_particle_hair(b_ob)) { sync_object(b_depsgraph, b_view_layer, b_instance, motion_time, - show_self, - show_particles, + true, show_lights, culling, &use_portal); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 20dbe23cdb7..bb8a132ebb7 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -108,10 +108,12 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d } if (dicing_prop_changed) { - for (const pair &iter : mesh_map.key_to_scene_data()) { + for (const pair &iter : mesh_map.key_to_scene_data()) { Mesh *mesh = iter.second; if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { - mesh_map.set_recalc(iter.first); + PointerRNA id_ptr; + RNA_id_pointer_create((::ID *)iter.first.id, &id_ptr); + mesh_map.set_recalc(BL::ID(id_ptr)); } } } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index a80f484fb92..07dccdc5a73 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -127,16 +127,15 @@ class BlenderSync { BL::Object &b_ob, BL::Object &b_ob_instance, bool object_updated, - bool show_self, - bool show_particles); - void sync_curves( + bool use_particle_hair); + bool object_has_particle_hair(BL::Object b_ob); + void sync_particle_hair( Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); Object *sync_object(BL::Depsgraph &b_depsgraph, BL::ViewLayer &b_view_layer, BL::DepsgraphObjectInstance &b_instance, float motion_time, - bool show_self, - bool show_particles, + bool use_particle_hair, bool show_lights, BlenderObjectCulling &culling, bool *use_portal); @@ -179,7 +178,7 @@ class BlenderSync { id_map shader_map; id_map object_map; - id_map mesh_map; + id_map mesh_map; id_map light_map; id_map particle_system_map; set mesh_synced; diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index bea30a20b8c..6d6dd75db6b 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -625,6 +625,11 @@ template class id_map { return sync(r_data, id, id, id.ptr.owner_id); } + bool sync(T **r_data, const BL::ID &id, const K &key) + { + return sync(r_data, id, id, key); + } + bool sync(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) { T *data = find(key); @@ -639,8 +644,9 @@ template class id_map { } else { recalc = (b_recalc.find(id.ptr.data) != b_recalc.end()); - if (parent.ptr.data) + if (parent.ptr.data && parent.ptr.data != id.ptr.data) { recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end()); + } } used(data); @@ -725,9 +731,10 @@ struct ObjectKey { void *parent; int id[OBJECT_PERSISTENT_ID_SIZE]; void *ob; + bool use_particle_hair; - ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_) - : parent(parent_), ob(ob_) + ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_, bool use_particle_hair_) + : parent(parent_), ob(ob_), use_particle_hair(use_particle_hair_) { if (id_) memcpy(id, id_, sizeof(id)); @@ -741,10 +748,42 @@ struct ObjectKey { return true; } else if (ob == k.ob) { - if (parent < k.parent) + if (parent < k.parent) { + return true; + } + else if (parent == k.parent) { + if (use_particle_hair < k.use_particle_hair) { + return true; + } + else if (use_particle_hair == k.use_particle_hair) { + return memcmp(id, k.id, sizeof(id)) < 0; + } + } + } + + return false; + } +}; + +/* Mesh Key */ + +struct MeshKey { + void *id; + bool use_particle_hair; + + MeshKey(void *id, bool use_particle_hair) : id(id), use_particle_hair(use_particle_hair) + { + } + + bool operator<(const MeshKey &k) const + { + if (id < k.id) { + return true; + } + else if (id == k.id) { + if (use_particle_hair < k.use_particle_hair) { return true; - else if (parent == k.parent) - return memcmp(id, k.id, sizeof(id)) < 0; + } } return false; -- cgit v1.2.3 From 47402dcb9160793fcfd87ea3c6e6685ea6954b3f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 2 Feb 2020 13:09:18 +0100 Subject: Cleanup: split Cycles export into smaller files --- intern/cycles/blender/CMakeLists.txt | 5 + intern/cycles/blender/blender_curves.cpp | 57 ++++ intern/cycles/blender/blender_geometry.cpp | 146 +++++++++++ intern/cycles/blender/blender_id_map.h | 279 ++++++++++++++++++++ intern/cycles/blender/blender_image.cpp | 360 ++++++++++++++++++++++++++ intern/cycles/blender/blender_light.cpp | 213 +++++++++++++++ intern/cycles/blender/blender_mesh.cpp | 281 +++----------------- intern/cycles/blender/blender_object.cpp | 206 +-------------- intern/cycles/blender/blender_object_cull.cpp | 1 + intern/cycles/blender/blender_python.cpp | 1 + intern/cycles/blender/blender_session.cpp | 335 ------------------------ intern/cycles/blender/blender_sync.h | 57 ++-- intern/cycles/blender/blender_util.h | 276 +++----------------- intern/cycles/blender/blender_volume.cpp | 95 +++++++ 14 files changed, 1274 insertions(+), 1038 deletions(-) create mode 100644 intern/cycles/blender/blender_geometry.cpp create mode 100644 intern/cycles/blender/blender_id_map.h create mode 100644 intern/cycles/blender/blender_image.cpp create mode 100644 intern/cycles/blender/blender_light.cpp create mode 100644 intern/cycles/blender/blender_volume.cpp diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index 0888eeb78bb..d9a2ebf8571 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -18,6 +18,9 @@ set(INC_SYS set(SRC blender_camera.cpp blender_device.cpp + blender_image.cpp + blender_geometry.cpp + blender_light.cpp blender_mesh.cpp blender_object.cpp blender_object_cull.cpp @@ -30,9 +33,11 @@ set(SRC blender_sync.cpp blender_texture.cpp blender_viewport.cpp + blender_volume.cpp CCL_api.h blender_device.h + blender_id_map.h blender_object_cull.h blender_sync.h blender_session.h diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 755214f422c..64efaab70e0 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -1160,6 +1160,63 @@ void BlenderSync::sync_particle_hair( } mesh->compute_bounds(); + mesh->geometry_flags |= Mesh::GEOMETRY_CURVES; +} + +void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) +{ + /* compares curve_keys rather than strands in order to handle quick hair + * adjustments in dynamic BVH - other methods could probably do this better*/ + array oldcurve_keys; + array oldcurve_radius; + oldcurve_keys.steal_data(mesh->curve_keys); + oldcurve_radius.steal_data(mesh->curve_radius); + + if (view_layer.use_hair) { + /* Particle hair. */ + bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); + BL::Mesh b_mesh = object_to_mesh( + b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE); + + if (b_mesh) { + sync_particle_hair(mesh, b_mesh, b_ob, false); + free_object_to_mesh(b_data, b_ob, b_mesh); + } + } + + /* tag update */ + bool rebuild = (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius); + mesh->tag_update(scene, rebuild); +} + +void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, + BL::Object b_ob, + Mesh *mesh, + int motion_step) +{ + /* Skip if no curves were exported. */ + size_t numkeys = mesh->curve_keys.size(); + if (numkeys == 0) { + return; + } + + /* Export deformed coordinates. */ + if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) { + /* Particle hair. */ + BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); + if (b_mesh) { + sync_particle_hair(mesh, b_mesh, b_ob, true, motion_step); + free_object_to_mesh(b_data, b_ob, b_mesh); + return; + } + } + + /* No deformation on this frame, copy coordinates if other frames did have it. */ + Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (attr_mP) { + float3 *keys = &mesh->curve_keys[0]; + memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp new file mode 100644 index 00000000000..151b741b003 --- /dev/null +++ b/intern/cycles/blender/blender_geometry.cpp @@ -0,0 +1,146 @@ + +/* + * 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 "render/mesh.h" +#include "render/object.h" + +#include "blender/blender_sync.h" +#include "blender/blender_util.h" + +CCL_NAMESPACE_BEGIN + +Mesh *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, + BL::Object &b_ob, + BL::Object &b_ob_instance, + bool object_updated, + bool use_particle_hair) +{ + /* Test if we can instance or if the object is modified. */ + BL::ID b_ob_data = b_ob.data(); + BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; + MeshKey key(b_key_id.ptr.data, use_particle_hair); + BL::Material material_override = view_layer.material_override; + Shader *default_shader = scene->default_surface; + + /* Find shader indices. */ + vector used_shaders; + + BL::Object::material_slots_iterator slot; + for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { + if (material_override) { + find_shader(material_override, used_shaders, default_shader); + } + else { + BL::ID b_material(slot->material()); + find_shader(b_material, used_shaders, default_shader); + } + } + + if (used_shaders.size() == 0) { + if (material_override) + find_shader(material_override, used_shaders, default_shader); + else + used_shaders.push_back(default_shader); + } + + /* Test if we need to sync. */ + Mesh *mesh; + + if (!mesh_map.sync(&mesh, b_key_id, key)) { + /* If transform was applied to mesh, need full update. */ + if (object_updated && mesh->transform_applied) + ; + /* Test if shaders changed, these can be object level so mesh + * does not get tagged for recalc. */ + else if (mesh->used_shaders != used_shaders) + ; + else { + /* Even if not tagged for recalc, we may need to sync anyway + * because the shader needs different mesh attributes. */ + bool attribute_recalc = false; + + foreach (Shader *shader, mesh->used_shaders) + if (shader->need_update_mesh) + attribute_recalc = true; + + if (!attribute_recalc) + return mesh; + } + } + + /* Ensure we only sync instanced meshes once. */ + if (mesh_synced.find(mesh) != mesh_synced.end()) + return mesh; + + progress.set_sync_status("Synchronizing object", b_ob.name()); + + mesh_synced.insert(mesh); + + mesh->clear(); + mesh->used_shaders = used_shaders; + mesh->name = ustring(b_ob_data.name().c_str()); + + if (use_particle_hair) { + sync_hair(b_depsgraph, b_ob, mesh); + } + else if (object_fluid_gas_domain_find(b_ob)) { + sync_volume(b_ob, mesh); + } + else { + sync_mesh(b_depsgraph, b_ob, mesh); + } + + return mesh; +} + +void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, + BL::Object &b_ob, + Object *object, + float motion_time, + bool use_particle_hair) +{ + /* Ensure we only sync instanced meshes once. */ + Mesh *mesh = object->mesh; + + if (mesh_motion_synced.find(mesh) != mesh_motion_synced.end()) + return; + + mesh_motion_synced.insert(mesh); + + /* Ensure we only motion sync meshes that also had mesh synced, to avoid + * unnecessary work and to ensure that its attributes were clear. */ + if (mesh_synced.find(mesh) == mesh_synced.end()) + return; + + /* Find time matching motion step required by mesh. */ + int motion_step = mesh->motion_step(motion_time); + if (motion_step < 0) { + return; + } + + if (use_particle_hair) { + sync_hair_motion(b_depsgraph, b_ob, mesh, motion_step); + } + else if (object_fluid_gas_domain_find(b_ob)) { + /* No volume motion blur support yet. */ + } + else { + sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step); + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_id_map.h b/intern/cycles/blender/blender_id_map.h new file mode 100644 index 00000000000..52031cd9f34 --- /dev/null +++ b/intern/cycles/blender/blender_id_map.h @@ -0,0 +1,279 @@ +/* + * 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. + */ + +#ifndef __BLENDER_ID_MAP_H__ +#define __BLENDER_ID_MAP_H__ + +#include + +#include "util/util_map.h" +#include "util/util_set.h" +#include "util/util_vector.h" + +CCL_NAMESPACE_BEGIN + +/* ID Map + * + * Utility class to map between Blender datablocks and Cycles data structures, + * and keep track of recalc tags from the dependency graph. */ + +template class id_map { + public: + id_map(vector *scene_data_) + { + scene_data = scene_data_; + } + + T *find(const BL::ID &id) + { + return find(id.ptr.owner_id); + } + + T *find(const K &key) + { + if (b_map.find(key) != b_map.end()) { + T *data = b_map[key]; + return data; + } + + return NULL; + } + + void set_recalc(const BL::ID &id) + { + b_recalc.insert(id.ptr.data); + } + + void set_recalc(void *id_ptr) + { + b_recalc.insert(id_ptr); + } + + bool has_recalc() + { + return !(b_recalc.empty()); + } + + void pre_sync() + { + used_set.clear(); + } + + bool sync(T **r_data, const BL::ID &id) + { + return sync(r_data, id, id, id.ptr.owner_id); + } + + bool sync(T **r_data, const BL::ID &id, const K &key) + { + return sync(r_data, id, id, key); + } + + bool sync(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) + { + T *data = find(key); + bool recalc; + + if (!data) { + /* add data if it didn't exist yet */ + data = new T(); + scene_data->push_back(data); + b_map[key] = data; + recalc = true; + } + else { + recalc = (b_recalc.find(id.ptr.data) != b_recalc.end()); + if (parent.ptr.data && parent.ptr.data != id.ptr.data) { + recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end()); + } + } + + used(data); + + *r_data = data; + return recalc; + } + + bool is_used(const K &key) + { + T *data = find(key); + return (data) ? used_set.find(data) != used_set.end() : false; + } + + void used(T *data) + { + /* tag data as still in use */ + used_set.insert(data); + } + + void set_default(T *data) + { + b_map[NULL] = data; + } + + bool post_sync(bool do_delete = true) + { + /* remove unused data */ + vector new_scene_data; + typename vector::iterator it; + bool deleted = false; + + for (it = scene_data->begin(); it != scene_data->end(); it++) { + T *data = *it; + + if (do_delete && used_set.find(data) == used_set.end()) { + delete data; + deleted = true; + } + else + new_scene_data.push_back(data); + } + + *scene_data = new_scene_data; + + /* update mapping */ + map new_map; + typedef pair TMapPair; + typename map::iterator jt; + + for (jt = b_map.begin(); jt != b_map.end(); jt++) { + TMapPair &pair = *jt; + + if (used_set.find(pair.second) != used_set.end()) + new_map[pair.first] = pair.second; + } + + used_set.clear(); + b_recalc.clear(); + b_map = new_map; + + return deleted; + } + + const map &key_to_scene_data() + { + return b_map; + } + + protected: + vector *scene_data; + map b_map; + set used_set; + set b_recalc; +}; + +/* Object Key + * + * To uniquely identify instances, we use the parent, object and persistent instance ID. + * We also export separate object for a mesh and its particle hair. */ + +enum { OBJECT_PERSISTENT_ID_SIZE = 16 }; + +struct ObjectKey { + void *parent; + int id[OBJECT_PERSISTENT_ID_SIZE]; + void *ob; + bool use_particle_hair; + + ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_, bool use_particle_hair_) + : parent(parent_), ob(ob_), use_particle_hair(use_particle_hair_) + { + if (id_) + memcpy(id, id_, sizeof(id)); + else + memset(id, 0, sizeof(id)); + } + + bool operator<(const ObjectKey &k) const + { + if (ob < k.ob) { + return true; + } + else if (ob == k.ob) { + if (parent < k.parent) { + return true; + } + else if (parent == k.parent) { + if (use_particle_hair < k.use_particle_hair) { + return true; + } + else if (use_particle_hair == k.use_particle_hair) { + return memcmp(id, k.id, sizeof(id)) < 0; + } + } + } + + return false; + } +}; + +/* Mesh Key + * + * We export separate geomtry for a mesh and its particle hair, so key needs to + * distinguish between them. */ + +struct MeshKey { + void *id; + bool use_particle_hair; + + MeshKey(void *id, bool use_particle_hair) : id(id), use_particle_hair(use_particle_hair) + { + } + + bool operator<(const MeshKey &k) const + { + if (id < k.id) { + return true; + } + else if (id == k.id) { + if (use_particle_hair < k.use_particle_hair) { + return true; + } + } + + return false; + } +}; + +/* Particle System Key */ + +struct ParticleSystemKey { + void *ob; + int id[OBJECT_PERSISTENT_ID_SIZE]; + + ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE]) : ob(ob_) + { + if (id_) + memcpy(id, id_, sizeof(id)); + else + memset(id, 0, sizeof(id)); + } + + bool operator<(const ParticleSystemKey &k) const + { + /* first id is particle index, we don't compare that */ + if (ob < k.ob) + return true; + else if (ob == k.ob) + return memcmp(id + 1, k.id + 1, sizeof(int) * (OBJECT_PERSISTENT_ID_SIZE - 1)) < 0; + + return false; + } +}; + +CCL_NAMESPACE_END + +#endif /* __BLENDER_ID_MAP_H__ */ diff --git a/intern/cycles/blender/blender_image.cpp b/intern/cycles/blender/blender_image.cpp new file mode 100644 index 00000000000..0fe42b2d479 --- /dev/null +++ b/intern/cycles/blender/blender_image.cpp @@ -0,0 +1,360 @@ +/* + * 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 "render/image.h" + +#include "blender/blender_sync.h" +#include "blender/blender_session.h" +#include "blender/blender_util.h" + +CCL_NAMESPACE_BEGIN + +/* builtin image file name is actually an image datablock name with + * absolute sequence frame number concatenated via '@' character + * + * this function splits frame from builtin name + */ +int BlenderSession::builtin_image_frame(const string &builtin_name) +{ + int last = builtin_name.find_last_of('@'); + return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str()); +} + +void BlenderSession::builtin_image_info(const string &builtin_name, + void *builtin_data, + ImageMetaData &metadata) +{ + /* empty image */ + metadata.width = 1; + metadata.height = 1; + + if (!builtin_data) + return; + + /* recover ID pointer */ + PointerRNA ptr; + RNA_id_pointer_create((ID *)builtin_data, &ptr); + BL::ID b_id(ptr); + + if (b_id.is_a(&RNA_Image)) { + /* image data */ + BL::Image b_image(b_id); + + metadata.builtin_free_cache = !b_image.has_data(); + metadata.is_float = b_image.is_float(); + metadata.width = b_image.size()[0]; + metadata.height = b_image.size()[1]; + metadata.depth = 1; + metadata.channels = b_image.channels(); + + if (metadata.is_float) { + /* Float images are already converted on the Blender side, + * no need to do anything in Cycles. */ + metadata.colorspace = u_colorspace_raw; + } + } + else if (b_id.is_a(&RNA_Object)) { + /* smoke volume data */ + BL::Object b_ob(b_id); + BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob); + + metadata.is_float = true; + metadata.depth = 1; + metadata.channels = 1; + + if (!b_domain) + return; + + if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) || + builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) || + builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT) || + builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) + metadata.channels = 1; + else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) + metadata.channels = 4; + else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) + metadata.channels = 3; + else + return; + + int3 resolution = get_int3(b_domain.domain_resolution()); + int amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1; + + /* Velocity and heat data is always low-resolution. */ + if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) || + builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) { + amplify = 1; + } + + metadata.width = resolution.x * amplify; + metadata.height = resolution.y * amplify; + metadata.depth = resolution.z * amplify; + } + else { + /* TODO(sergey): Check we're indeed in shader node tree. */ + PointerRNA ptr; + RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr); + BL::Node b_node(ptr); + if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { + BL::ShaderNodeTexPointDensity b_point_density_node(b_node); + metadata.channels = 4; + metadata.width = b_point_density_node.resolution(); + metadata.height = metadata.width; + metadata.depth = metadata.width; + metadata.is_float = true; + } + } +} + +bool BlenderSession::builtin_image_pixels(const string &builtin_name, + void *builtin_data, + int tile, + unsigned char *pixels, + const size_t pixels_size, + const bool associate_alpha, + const bool free_cache) +{ + if (!builtin_data) { + return false; + } + + const int frame = builtin_image_frame(builtin_name); + + PointerRNA ptr; + RNA_id_pointer_create((ID *)builtin_data, &ptr); + BL::Image b_image(ptr); + + const int width = b_image.size()[0]; + const int height = b_image.size()[1]; + const int channels = b_image.channels(); + + unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame, tile); + const size_t num_pixels = ((size_t)width) * height; + + if (image_pixels && num_pixels * channels == pixels_size) { + memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char)); + } + else { + if (channels == 1) { + memset(pixels, 0, pixels_size * sizeof(unsigned char)); + } + else { + const size_t num_pixels_safe = pixels_size / channels; + unsigned char *cp = pixels; + for (size_t i = 0; i < num_pixels_safe; i++, cp += channels) { + cp[0] = 255; + cp[1] = 0; + cp[2] = 255; + if (channels == 4) { + cp[3] = 255; + } + } + } + } + + if (image_pixels) { + MEM_freeN(image_pixels); + } + + /* Free image buffers to save memory during render. */ + if (free_cache) { + b_image.buffers_free(); + } + + if (associate_alpha) { + /* Premultiply, byte images are always straight for Blender. */ + unsigned char *cp = pixels; + for (size_t i = 0; i < num_pixels; i++, cp += channels) { + cp[0] = (cp[0] * cp[3]) >> 8; + cp[1] = (cp[1] * cp[3]) >> 8; + cp[2] = (cp[2] * cp[3]) >> 8; + } + } + return true; +} + +bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, + void *builtin_data, + int tile, + float *pixels, + const size_t pixels_size, + const bool, + const bool free_cache) +{ + if (!builtin_data) { + return false; + } + + PointerRNA ptr; + RNA_id_pointer_create((ID *)builtin_data, &ptr); + BL::ID b_id(ptr); + + if (b_id.is_a(&RNA_Image)) { + /* image data */ + BL::Image b_image(b_id); + int frame = builtin_image_frame(builtin_name); + + const int width = b_image.size()[0]; + const int height = b_image.size()[1]; + const int channels = b_image.channels(); + + float *image_pixels; + image_pixels = image_get_float_pixels_for_frame(b_image, frame, tile); + const size_t num_pixels = ((size_t)width) * height; + + if (image_pixels && num_pixels * channels == pixels_size) { + memcpy(pixels, image_pixels, pixels_size * sizeof(float)); + } + else { + if (channels == 1) { + memset(pixels, 0, num_pixels * sizeof(float)); + } + else { + const size_t num_pixels_safe = pixels_size / channels; + float *fp = pixels; + for (int i = 0; i < num_pixels_safe; i++, fp += channels) { + fp[0] = 1.0f; + fp[1] = 0.0f; + fp[2] = 1.0f; + if (channels == 4) { + fp[3] = 1.0f; + } + } + } + } + + if (image_pixels) { + MEM_freeN(image_pixels); + } + + /* Free image buffers to save memory during render. */ + if (free_cache) { + b_image.buffers_free(); + } + + return true; + } + else if (b_id.is_a(&RNA_Object)) { + /* smoke volume data */ + BL::Object b_ob(b_id); + BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob); + + if (!b_domain) { + return false; + } +#if WITH_FLUID + int3 resolution = get_int3(b_domain.domain_resolution()); + int length, amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1; + + /* Velocity and heat data is always low-resolution. */ + if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) || + builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) { + amplify = 1; + } + + const int width = resolution.x * amplify; + const int height = resolution.y * amplify; + const int depth = resolution.z * amplify; + const size_t num_pixels = ((size_t)width) * height * depth; + + if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) { + FluidDomainSettings_density_grid_get_length(&b_domain.ptr, &length); + if (length == num_pixels) { + FluidDomainSettings_density_grid_get(&b_domain.ptr, pixels); + return true; + } + } + else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) { + /* this is in range 0..1, and interpreted by the OpenGL smoke viewer + * as 1500..3000 K with the first part faded to zero density */ + FluidDomainSettings_flame_grid_get_length(&b_domain.ptr, &length); + if (length == num_pixels) { + FluidDomainSettings_flame_grid_get(&b_domain.ptr, pixels); + return true; + } + } + else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) { + /* the RGB is "premultiplied" by density for better interpolation results */ + FluidDomainSettings_color_grid_get_length(&b_domain.ptr, &length); + if (length == num_pixels * 4) { + FluidDomainSettings_color_grid_get(&b_domain.ptr, pixels); + return true; + } + } + else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) { + FluidDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length); + if (length == num_pixels * 3) { + FluidDomainSettings_velocity_grid_get(&b_domain.ptr, pixels); + return true; + } + } + else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) { + FluidDomainSettings_heat_grid_get_length(&b_domain.ptr, &length); + if (length == num_pixels) { + FluidDomainSettings_heat_grid_get(&b_domain.ptr, pixels); + return true; + } + } + else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) { + FluidDomainSettings_temperature_grid_get_length(&b_domain.ptr, &length); + if (length == num_pixels) { + FluidDomainSettings_temperature_grid_get(&b_domain.ptr, pixels); + return true; + } + } + else { + fprintf( + stderr, "Cycles error: unknown volume attribute %s, skipping\n", builtin_name.c_str()); + pixels[0] = 0.0f; + return false; + } +#endif + fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n"); + } + else { + /* We originally were passing view_layer here but in reality we need a + * a depsgraph to pass to the RE_point_density_minmax() function. + */ + /* TODO(sergey): Check we're indeed in shader node tree. */ + PointerRNA ptr; + RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr); + BL::Node b_node(ptr); + if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { + BL::ShaderNodeTexPointDensity b_point_density_node(b_node); + int length; + b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels); + } + } + + return false; +} + +void BlenderSession::builtin_images_load() +{ + /* Force builtin images to be loaded along with Blender data sync. This + * is needed because we may be reading from depsgraph evaluated data which + * can be freed by Blender before Cycles reads it. + * + * TODO: the assumption that no further access to builtin image data will + * happen is really weak, and likely to break in the future. We should find + * a better solution to hand over the data directly to the image manager + * instead of through callbacks whose timing is difficult to control. */ + ImageManager *manager = session->scene->image_manager; + Device *device = session->device; + manager->device_load_builtin(device, session->scene, session->progress); +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp new file mode 100644 index 00000000000..a8e28a011d7 --- /dev/null +++ b/intern/cycles/blender/blender_light.cpp @@ -0,0 +1,213 @@ + + +/* + * 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 "render/light.h" + +#include "blender/blender_sync.h" +#include "blender/blender_util.h" + +#include "util/util_hash.h" + +CCL_NAMESPACE_BEGIN + +void BlenderSync::sync_light(BL::Object &b_parent, + int persistent_id[OBJECT_PERSISTENT_ID_SIZE], + BL::Object &b_ob, + BL::Object &b_ob_instance, + int random_id, + Transform &tfm, + bool *use_portal) +{ + /* test if we need to sync */ + Light *light; + ObjectKey key(b_parent, persistent_id, b_ob_instance, false); + BL::Light b_light(b_ob.data()); + + /* Update if either object or light data changed. */ + if (!light_map.sync(&light, b_ob, b_parent, key)) { + Shader *shader; + if (!shader_map.sync(&shader, b_light)) { + if (light->is_portal) + *use_portal = true; + return; + } + } + + /* type */ + switch (b_light.type()) { + case BL::Light::type_POINT: { + BL::PointLight b_point_light(b_light); + light->size = b_point_light.shadow_soft_size(); + light->type = LIGHT_POINT; + break; + } + case BL::Light::type_SPOT: { + BL::SpotLight b_spot_light(b_light); + light->size = b_spot_light.shadow_soft_size(); + light->type = LIGHT_SPOT; + light->spot_angle = b_spot_light.spot_size(); + light->spot_smooth = b_spot_light.spot_blend(); + break; + } + /* Hemi were removed from 2.8 */ + // case BL::Light::type_HEMI: { + // light->type = LIGHT_DISTANT; + // light->size = 0.0f; + // break; + // } + case BL::Light::type_SUN: { + BL::SunLight b_sun_light(b_light); + light->angle = b_sun_light.angle(); + light->type = LIGHT_DISTANT; + break; + } + case BL::Light::type_AREA: { + BL::AreaLight b_area_light(b_light); + light->size = 1.0f; + light->axisu = transform_get_column(&tfm, 0); + light->axisv = transform_get_column(&tfm, 1); + light->sizeu = b_area_light.size(); + switch (b_area_light.shape()) { + case BL::AreaLight::shape_SQUARE: + light->sizev = light->sizeu; + light->round = false; + break; + case BL::AreaLight::shape_RECTANGLE: + light->sizev = b_area_light.size_y(); + light->round = false; + break; + case BL::AreaLight::shape_DISK: + light->sizev = light->sizeu; + light->round = true; + break; + case BL::AreaLight::shape_ELLIPSE: + light->sizev = b_area_light.size_y(); + light->round = true; + break; + } + light->type = LIGHT_AREA; + break; + } + } + + /* strength */ + light->strength = get_float3(b_light.color()); + light->strength *= BL::PointLight(b_light).energy(); + + /* location and (inverted!) direction */ + light->co = transform_get_column(&tfm, 3); + light->dir = -transform_get_column(&tfm, 2); + light->tfm = tfm; + + /* shader */ + vector used_shaders; + find_shader(b_light, used_shaders, scene->default_light); + light->shader = used_shaders[0]; + + /* shadow */ + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); + PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles"); + light->cast_shadow = get_boolean(clight, "cast_shadow"); + light->use_mis = get_boolean(clight, "use_multiple_importance_sampling"); + + int samples = get_int(clight, "samples"); + if (get_boolean(cscene, "use_square_samples")) + light->samples = samples * samples; + else + light->samples = samples; + + light->max_bounces = get_int(clight, "max_bounces"); + + if (b_ob != b_ob_instance) { + light->random_id = random_id; + } + else { + light->random_id = hash_uint2(hash_string(b_ob.name().c_str()), 0); + } + + if (light->type == LIGHT_AREA) + light->is_portal = get_boolean(clight, "is_portal"); + else + light->is_portal = false; + + if (light->is_portal) + *use_portal = true; + + /* visibility */ + uint visibility = object_ray_visibility(b_ob); + light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0; + light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0; + light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0; + light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0; + + /* tag */ + light->tag_update(scene); +} + +void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) +{ + BL::World b_world = b_scene.world(); + + if (b_world) { + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); + PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles"); + + enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM }; + int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC); + bool sample_as_light = (sampling_method != SAMPLING_NONE); + + if (sample_as_light || use_portal) { + /* test if we need to sync */ + Light *light; + ObjectKey key(b_world, 0, b_world, false); + + if (light_map.sync(&light, b_world, b_world, key) || world_recalc || + b_world.ptr.data != world_map) { + light->type = LIGHT_BACKGROUND; + if (sampling_method == SAMPLING_MANUAL) { + light->map_resolution = get_int(cworld, "sample_map_resolution"); + } + else { + light->map_resolution = 0; + } + light->shader = scene->default_background; + light->use_mis = sample_as_light; + light->max_bounces = get_int(cworld, "max_bounces"); + + /* force enable light again when world is resynced */ + light->is_enabled = true; + + int samples = get_int(cworld, "samples"); + if (get_boolean(cscene, "use_square_samples")) + light->samples = samples * samples; + else + light->samples = samples; + + light->tag_update(scene); + light_map.set_recalc(b_world); + } + } + } + + world_map = b_world.ptr.data; + world_recalc = false; + viewport_parameters = BlenderViewportParameters(b_v3d); +} + +CCL_NAMESPACE_END + diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index d3dac3c6151..00faafe29ee 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -278,54 +278,6 @@ static void mikk_compute_tangents( genTangSpaceDefault(&context); } -/* Create Volume Attribute */ - -static void create_mesh_volume_attribute( - BL::Object &b_ob, Mesh *mesh, ImageManager *image_manager, AttributeStandard std, float frame) -{ - BL::FluidDomainSettings b_domain = object_fluid_domain_find(b_ob); - - if (!b_domain) - return; - - mesh->volume_isovalue = b_domain.clipping(); - - Attribute *attr = mesh->attributes.add(std); - VoxelAttribute *volume_data = attr->data_voxel(); - ImageMetaData metadata; - bool animated = false; - - volume_data->manager = image_manager; - volume_data->slot = image_manager->add_image(Attribute::standard_name(std), - b_ob.ptr.data, - animated, - frame, - INTERPOLATION_LINEAR, - EXTENSION_CLIP, - IMAGE_ALPHA_AUTO, - u_colorspace_raw, - metadata); -} - -static void create_mesh_volume_attributes(Scene *scene, BL::Object &b_ob, Mesh *mesh, float frame) -{ - /* for smoke volume rendering */ - if (mesh->need_attribute(scene, ATTR_STD_VOLUME_DENSITY)) - create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_DENSITY, frame); - if (mesh->need_attribute(scene, ATTR_STD_VOLUME_COLOR)) - create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_COLOR, frame); - if (mesh->need_attribute(scene, ATTR_STD_VOLUME_FLAME)) - create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_FLAME, frame); - if (mesh->need_attribute(scene, ATTR_STD_VOLUME_HEAT)) - create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_HEAT, frame); - if (mesh->need_attribute(scene, ATTR_STD_VOLUME_TEMPERATURE)) - create_mesh_volume_attribute( - b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_TEMPERATURE, frame); - if (mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY)) - create_mesh_volume_attribute( - b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY, frame); -} - /* Create vertex color attributes. */ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision) { @@ -767,6 +719,7 @@ static void create_mesh(Scene *scene, /* allocate memory */ mesh->reserve_mesh(numverts, numtris); mesh->reserve_subd_faces(numfaces, numngons, numcorners); + mesh->geometry_flags |= Mesh::GEOMETRY_TRIANGLES; /* create vertex coordinates and normals */ BL::Mesh::vertices_iterator v; @@ -859,9 +812,9 @@ static void create_mesh(Scene *scene, attr_create_uv_map(scene, mesh, b_mesh); } - /* for volume objects, create a matrix to transform from object space to + /* For volume objects, create a matrix to transform from object space to * mesh texture space. this does not work with deformations but that can - * probably only be done well with a volume grid mapping of coordinates */ + * probably only be done well with a volume grid mapping of coordinates. */ if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM); Transform *tfm = attr->data_transform(); @@ -930,7 +883,7 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) if (scene->need_motion() == Scene::MOTION_NONE) return; - BL::FluidDomainSettings b_fluid_domain = object_fluid_domain_find(b_ob); + BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob); if (!b_fluid_domain) return; @@ -963,82 +916,8 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) } } -Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, - BL::Object &b_ob, - BL::Object &b_ob_instance, - bool object_updated, - bool use_particle_hair) +void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) { - /* test if we can instance or if the object is modified */ - BL::ID b_ob_data = b_ob.data(); - BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; - MeshKey key(b_key_id.ptr.data, use_particle_hair); - BL::Material material_override = view_layer.material_override; - - /* find shader indices */ - vector used_shaders; - - BL::Object::material_slots_iterator slot; - for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { - if (material_override) { - find_shader(material_override, used_shaders, scene->default_surface); - } - else { - BL::ID b_material(slot->material()); - find_shader(b_material, used_shaders, scene->default_surface); - } - } - - if (used_shaders.size() == 0) { - if (material_override) - find_shader(material_override, used_shaders, scene->default_surface); - else - used_shaders.push_back(scene->default_surface); - } - - /* test if we need to sync */ - int requested_geometry_flags = Mesh::GEOMETRY_NONE; - if (view_layer.use_surfaces) { - requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES; - } - if (view_layer.use_hair) { - requested_geometry_flags |= Mesh::GEOMETRY_CURVES; - } - Mesh *mesh; - - if (!mesh_map.sync(&mesh, b_key_id, key)) { - /* if transform was applied to mesh, need full update */ - if (object_updated && mesh->transform_applied) - ; - /* test if shaders changed, these can be object level so mesh - * does not get tagged for recalc */ - else if (mesh->used_shaders != used_shaders) - ; - else if (requested_geometry_flags != mesh->geometry_flags) - ; - else { - /* even if not tagged for recalc, we may need to sync anyway - * because the shader needs different mesh attributes */ - bool attribute_recalc = false; - - foreach (Shader *shader, mesh->used_shaders) - if (shader->need_update_mesh) - attribute_recalc = true; - - if (!attribute_recalc) - return mesh; - } - } - - /* ensure we only sync instanced meshes once */ - if (mesh_synced.find(mesh) != mesh_synced.end()) - return mesh; - - progress.set_sync_status("Synchronizing object", b_ob.name()); - - mesh_synced.insert(mesh); - - /* create derived mesh */ array oldtriangles; array oldsubd_faces; array oldsubd_face_corners; @@ -1046,152 +925,64 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, oldsubd_faces.steal_data(mesh->subd_faces); oldsubd_face_corners.steal_data(mesh->subd_face_corners); - /* compares curve_keys rather than strands in order to handle quick hair - * adjustments in dynamic BVH - other methods could probably do this better*/ - array oldcurve_keys; - array oldcurve_radius; - oldcurve_keys.steal_data(mesh->curve_keys); - oldcurve_radius.steal_data(mesh->curve_radius); - - /* ensure bvh rebuild (instead of refit) if has_voxel_attributes() changed */ - bool oldhas_voxel_attributes = mesh->has_voxel_attributes(); + mesh->subdivision_type = Mesh::SUBDIVISION_NONE; - mesh->clear(); - mesh->used_shaders = used_shaders; - mesh->name = ustring(b_ob_data.name().c_str()); - - if (requested_geometry_flags != Mesh::GEOMETRY_NONE) { + if (view_layer.use_surfaces) { /* Adaptive subdivision setup. Not for baking since that requires * exact mapping to the Blender mesh. */ - if (scene->bake_manager->get_baking()) { - mesh->subdivision_type = Mesh::SUBDIVISION_NONE; - } - else { + if (!scene->bake_manager->get_baking()) { mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental); } /* For some reason, meshes do not need this... */ bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); - BL::Mesh b_mesh = object_to_mesh( b_data, b_ob, b_depsgraph, need_undeformed, mesh->subdivision_type); if (b_mesh) { /* Sync mesh itself. */ - if (view_layer.use_surfaces && !use_particle_hair) { - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) - create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders, dicing_rate, max_subdivisions); - else - create_mesh(scene, mesh, b_mesh, used_shaders, false); - - create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current()); - } - - /* Sync hair curves. */ - if (view_layer.use_hair && use_particle_hair && - mesh->subdivision_type == Mesh::SUBDIVISION_NONE) { - sync_particle_hair(mesh, b_mesh, b_ob, false); - } + if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) + create_subd_mesh( + scene, mesh, b_ob, b_mesh, mesh->used_shaders, dicing_rate, max_subdivisions); + else + create_mesh(scene, mesh, b_mesh, mesh->used_shaders, false); free_object_to_mesh(b_data, b_ob, b_mesh); } } - mesh->geometry_flags = requested_geometry_flags; /* mesh fluid motion mantaflow */ - if (!use_particle_hair) { - sync_mesh_fluid_motion(b_ob, scene, mesh); - } + sync_mesh_fluid_motion(b_ob, scene, mesh); /* tag update */ bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) || - (oldsubd_face_corners != mesh->subd_face_corners) || - (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius) || - (oldhas_voxel_attributes != mesh->has_voxel_attributes()); + (oldsubd_face_corners != mesh->subd_face_corners); mesh->tag_update(scene, rebuild); - - return mesh; } -void BlenderSync::sync_mesh_motion(BL::Depsgraph &b_depsgraph, - BL::Object &b_ob, - Object *object, - float motion_time) +void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, + BL::Object b_ob, + Mesh *mesh, + int motion_step) { - /* ensure we only sync instanced meshes once */ - Mesh *mesh = object->mesh; - - if (mesh_motion_synced.find(mesh) != mesh_motion_synced.end()) - return; - - mesh_motion_synced.insert(mesh); - - /* ensure we only motion sync meshes that also had mesh synced, to avoid - * unnecessary work and to ensure that its attributes were clear */ - if (mesh_synced.find(mesh) == mesh_synced.end()) - return; - - /* Find time matching motion step required by mesh. */ - int motion_step = mesh->motion_step(motion_time); - if (motion_step < 0) { + /* Skip if no vertices were exported. */ + size_t numverts = mesh->verts.size(); + if (numverts == 0) { return; } - /* skip empty meshes */ - const size_t numverts = mesh->verts.size(); - const size_t numkeys = mesh->curve_keys.size(); - - if (!numverts && !numkeys) - return; - - /* skip objects without deforming modifiers. this is not totally reliable, - * would need a more extensive check to see which objects are animated */ + /* Skip objects without deforming modifiers. this is not totally reliable, + * would need a more extensive check to see which objects are animated. */ BL::Mesh b_mesh(PointerRNA_NULL); - - /* manta motion is exported immediate with mesh, skip here */ - BL::FluidDomainSettings b_fluid_domain = object_fluid_domain_find(b_ob); - if (b_fluid_domain) - return; - if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) { /* get derived mesh */ b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); } - if (!b_mesh) { - /* if we have no motion blur on this frame, but on other frames, copy */ - if (numverts) { - /* triangles */ - Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - - if (attr_mP) { - Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); - Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL); - float3 *P = &mesh->verts[0]; - float3 *N = (attr_N) ? attr_N->data_float3() : NULL; - - memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts); - if (attr_mN) - memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts); - } - } - - if (numkeys) { - /* curves */ - Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - - if (attr_mP) { - float3 *keys = &mesh->curve_keys[0]; - memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys); - } - } - - return; - } - /* TODO(sergey): Perform preliminary check for number of vertices. */ - if (numverts) { + if (b_mesh) { + /* Export deformed coordinates. */ /* Find attributes. */ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); @@ -1256,14 +1047,24 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph &b_depsgraph, } } } + + free_object_to_mesh(b_data, b_ob, b_mesh); + return; } - /* hair motion */ - if (numkeys) - sync_particle_hair(mesh, b_mesh, b_ob, true, motion_step); + /* No deformation on this frame, copy coordinates if other frames did have it. */ + Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - /* free derived mesh */ - free_object_to_mesh(b_data, b_ob, b_mesh); + if (attr_mP) { + Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); + Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL); + float3 *P = &mesh->verts[0]; + float3 *N = (attr_N) ? attr_N->data_float3() : NULL; + + memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts); + if (attr_mN) + memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index c397a95fa71..13dfd0867ba 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -88,207 +88,6 @@ bool BlenderSync::object_is_light(BL::Object &b_ob) return (b_ob_data && b_ob_data.is_a(&RNA_Light)); } -static uint object_ray_visibility(BL::Object &b_ob) -{ - PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility"); - uint flag = 0; - - flag |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0; - flag |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : 0; - flag |= get_boolean(cvisibility, "glossy") ? PATH_RAY_GLOSSY : 0; - flag |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0; - flag |= get_boolean(cvisibility, "shadow") ? PATH_RAY_SHADOW : 0; - flag |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0; - - return flag; -} - -/* Light */ - -void BlenderSync::sync_light(BL::Object &b_parent, - int persistent_id[OBJECT_PERSISTENT_ID_SIZE], - BL::Object &b_ob, - BL::Object &b_ob_instance, - int random_id, - Transform &tfm, - bool *use_portal) -{ - /* test if we need to sync */ - Light *light; - ObjectKey key(b_parent, persistent_id, b_ob_instance, false); - BL::Light b_light(b_ob.data()); - - /* Update if either object or light data changed. */ - if (!light_map.sync(&light, b_ob, b_parent, key)) { - Shader *shader; - if (!shader_map.sync(&shader, b_light)) { - if (light->is_portal) - *use_portal = true; - return; - } - } - - /* type */ - switch (b_light.type()) { - case BL::Light::type_POINT: { - BL::PointLight b_point_light(b_light); - light->size = b_point_light.shadow_soft_size(); - light->type = LIGHT_POINT; - break; - } - case BL::Light::type_SPOT: { - BL::SpotLight b_spot_light(b_light); - light->size = b_spot_light.shadow_soft_size(); - light->type = LIGHT_SPOT; - light->spot_angle = b_spot_light.spot_size(); - light->spot_smooth = b_spot_light.spot_blend(); - break; - } - /* Hemi were removed from 2.8 */ - // case BL::Light::type_HEMI: { - // light->type = LIGHT_DISTANT; - // light->size = 0.0f; - // break; - // } - case BL::Light::type_SUN: { - BL::SunLight b_sun_light(b_light); - light->angle = b_sun_light.angle(); - light->type = LIGHT_DISTANT; - break; - } - case BL::Light::type_AREA: { - BL::AreaLight b_area_light(b_light); - light->size = 1.0f; - light->axisu = transform_get_column(&tfm, 0); - light->axisv = transform_get_column(&tfm, 1); - light->sizeu = b_area_light.size(); - switch (b_area_light.shape()) { - case BL::AreaLight::shape_SQUARE: - light->sizev = light->sizeu; - light->round = false; - break; - case BL::AreaLight::shape_RECTANGLE: - light->sizev = b_area_light.size_y(); - light->round = false; - break; - case BL::AreaLight::shape_DISK: - light->sizev = light->sizeu; - light->round = true; - break; - case BL::AreaLight::shape_ELLIPSE: - light->sizev = b_area_light.size_y(); - light->round = true; - break; - } - light->type = LIGHT_AREA; - break; - } - } - - /* strength */ - light->strength = get_float3(b_light.color()); - light->strength *= BL::PointLight(b_light).energy(); - - /* location and (inverted!) direction */ - light->co = transform_get_column(&tfm, 3); - light->dir = -transform_get_column(&tfm, 2); - light->tfm = tfm; - - /* shader */ - vector used_shaders; - find_shader(b_light, used_shaders, scene->default_light); - light->shader = used_shaders[0]; - - /* shadow */ - PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles"); - light->cast_shadow = get_boolean(clight, "cast_shadow"); - light->use_mis = get_boolean(clight, "use_multiple_importance_sampling"); - - int samples = get_int(clight, "samples"); - if (get_boolean(cscene, "use_square_samples")) - light->samples = samples * samples; - else - light->samples = samples; - - light->max_bounces = get_int(clight, "max_bounces"); - - if (b_ob != b_ob_instance) { - light->random_id = random_id; - } - else { - light->random_id = hash_uint2(hash_string(b_ob.name().c_str()), 0); - } - - if (light->type == LIGHT_AREA) - light->is_portal = get_boolean(clight, "is_portal"); - else - light->is_portal = false; - - if (light->is_portal) - *use_portal = true; - - /* visibility */ - uint visibility = object_ray_visibility(b_ob); - light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0; - light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0; - light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0; - light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0; - - /* tag */ - light->tag_update(scene); -} - -void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) -{ - BL::World b_world = b_scene.world(); - - if (b_world) { - PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles"); - - enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM }; - int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC); - bool sample_as_light = (sampling_method != SAMPLING_NONE); - - if (sample_as_light || use_portal) { - /* test if we need to sync */ - Light *light; - ObjectKey key(b_world, 0, b_world, false); - - if (light_map.sync(&light, b_world, b_world, key) || world_recalc || - b_world.ptr.data != world_map) { - light->type = LIGHT_BACKGROUND; - if (sampling_method == SAMPLING_MANUAL) { - light->map_resolution = get_int(cworld, "sample_map_resolution"); - } - else { - light->map_resolution = 0; - } - light->shader = scene->default_background; - light->use_mis = sample_as_light; - light->max_bounces = get_int(cworld, "max_bounces"); - - /* force enable light again when world is resynced */ - light->is_enabled = true; - - int samples = get_int(cworld, "samples"); - if (get_boolean(cscene, "use_square_samples")) - light->samples = samples * samples; - else - light->samples = samples; - - light->tag_update(scene); - light_map.set_recalc(b_world); - } - } - } - - world_map = b_world.ptr.data; - world_recalc = false; - viewport_parameters = BlenderViewportParameters(b_v3d); -} - /* Object */ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, @@ -393,7 +192,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* mesh deformation */ if (object->mesh) - sync_mesh_motion(b_depsgraph, b_ob, object, motion_time); + sync_geometry_motion(b_depsgraph, b_ob, object, motion_time, use_particle_hair); } return object; @@ -406,7 +205,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, object_updated = true; /* mesh sync */ - object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, use_particle_hair); + object->mesh = sync_geometry( + b_depsgraph, b_ob, b_ob_instance, object_updated, use_particle_hair); /* special case not tracked by object update flags */ diff --git a/intern/cycles/blender/blender_object_cull.cpp b/intern/cycles/blender/blender_object_cull.cpp index 74f8fb1dc53..bebecb364eb 100644 --- a/intern/cycles/blender/blender_object_cull.cpp +++ b/intern/cycles/blender/blender_object_cull.cpp @@ -19,6 +19,7 @@ #include "render/camera.h" #include "blender/blender_object_cull.h" +#include "blender/blender_util.h" CCL_NAMESPACE_BEGIN diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 335d4daf09c..816b4552fff 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -21,6 +21,7 @@ #include "blender/blender_device.h" #include "blender/blender_sync.h" #include "blender/blender_session.h" +#include "blender/blender_util.h" #include "render/denoising.h" #include "render/merge.h" diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index e2dea24fdd1..663f3d72110 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -1112,341 +1112,6 @@ void BlenderSession::test_cancel() session->progress.set_cancel("Cancelled"); } -/* builtin image file name is actually an image datablock name with - * absolute sequence frame number concatenated via '@' character - * - * this function splits frame from builtin name - */ -int BlenderSession::builtin_image_frame(const string &builtin_name) -{ - int last = builtin_name.find_last_of('@'); - return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str()); -} - -void BlenderSession::builtin_image_info(const string &builtin_name, - void *builtin_data, - ImageMetaData &metadata) -{ - /* empty image */ - metadata.width = 1; - metadata.height = 1; - - if (!builtin_data) - return; - - /* recover ID pointer */ - PointerRNA ptr; - RNA_id_pointer_create((ID *)builtin_data, &ptr); - BL::ID b_id(ptr); - - if (b_id.is_a(&RNA_Image)) { - /* image data */ - BL::Image b_image(b_id); - - metadata.builtin_free_cache = !b_image.has_data(); - metadata.is_float = b_image.is_float(); - metadata.width = b_image.size()[0]; - metadata.height = b_image.size()[1]; - metadata.depth = 1; - metadata.channels = b_image.channels(); - - if (metadata.is_float) { - /* Float images are already converted on the Blender side, - * no need to do anything in Cycles. */ - metadata.colorspace = u_colorspace_raw; - } - } - else if (b_id.is_a(&RNA_Object)) { - /* smoke volume data */ - BL::Object b_ob(b_id); - BL::FluidDomainSettings b_domain = object_fluid_domain_find(b_ob); - - metadata.is_float = true; - metadata.depth = 1; - metadata.channels = 1; - - if (!b_domain) - return; - - if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) || - builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) || - builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT) || - builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) - metadata.channels = 1; - else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) - metadata.channels = 4; - else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) - metadata.channels = 3; - else - return; - - int3 resolution = get_int3(b_domain.domain_resolution()); - int amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1; - - /* Velocity and heat data is always low-resolution. */ - if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) || - builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) { - amplify = 1; - } - - metadata.width = resolution.x * amplify; - metadata.height = resolution.y * amplify; - metadata.depth = resolution.z * amplify; - } - else { - /* TODO(sergey): Check we're indeed in shader node tree. */ - PointerRNA ptr; - RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr); - BL::Node b_node(ptr); - if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { - BL::ShaderNodeTexPointDensity b_point_density_node(b_node); - metadata.channels = 4; - metadata.width = b_point_density_node.resolution(); - metadata.height = metadata.width; - metadata.depth = metadata.width; - metadata.is_float = true; - } - } -} - -bool BlenderSession::builtin_image_pixels(const string &builtin_name, - void *builtin_data, - int tile, - unsigned char *pixels, - const size_t pixels_size, - const bool associate_alpha, - const bool free_cache) -{ - if (!builtin_data) { - return false; - } - - const int frame = builtin_image_frame(builtin_name); - - PointerRNA ptr; - RNA_id_pointer_create((ID *)builtin_data, &ptr); - BL::Image b_image(ptr); - - const int width = b_image.size()[0]; - const int height = b_image.size()[1]; - const int channels = b_image.channels(); - - unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame, tile); - const size_t num_pixels = ((size_t)width) * height; - - if (image_pixels && num_pixels * channels == pixels_size) { - memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char)); - } - else { - if (channels == 1) { - memset(pixels, 0, pixels_size * sizeof(unsigned char)); - } - else { - const size_t num_pixels_safe = pixels_size / channels; - unsigned char *cp = pixels; - for (size_t i = 0; i < num_pixels_safe; i++, cp += channels) { - cp[0] = 255; - cp[1] = 0; - cp[2] = 255; - if (channels == 4) { - cp[3] = 255; - } - } - } - } - - if (image_pixels) { - MEM_freeN(image_pixels); - } - - /* Free image buffers to save memory during render. */ - if (free_cache) { - b_image.buffers_free(); - } - - if (associate_alpha) { - /* Premultiply, byte images are always straight for Blender. */ - unsigned char *cp = pixels; - for (size_t i = 0; i < num_pixels; i++, cp += channels) { - cp[0] = (cp[0] * cp[3]) >> 8; - cp[1] = (cp[1] * cp[3]) >> 8; - cp[2] = (cp[2] * cp[3]) >> 8; - } - } - return true; -} - -bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, - void *builtin_data, - int tile, - float *pixels, - const size_t pixels_size, - const bool, - const bool free_cache) -{ - if (!builtin_data) { - return false; - } - - PointerRNA ptr; - RNA_id_pointer_create((ID *)builtin_data, &ptr); - BL::ID b_id(ptr); - - if (b_id.is_a(&RNA_Image)) { - /* image data */ - BL::Image b_image(b_id); - int frame = builtin_image_frame(builtin_name); - - const int width = b_image.size()[0]; - const int height = b_image.size()[1]; - const int channels = b_image.channels(); - - float *image_pixels; - image_pixels = image_get_float_pixels_for_frame(b_image, frame, tile); - const size_t num_pixels = ((size_t)width) * height; - - if (image_pixels && num_pixels * channels == pixels_size) { - memcpy(pixels, image_pixels, pixels_size * sizeof(float)); - } - else { - if (channels == 1) { - memset(pixels, 0, num_pixels * sizeof(float)); - } - else { - const size_t num_pixels_safe = pixels_size / channels; - float *fp = pixels; - for (int i = 0; i < num_pixels_safe; i++, fp += channels) { - fp[0] = 1.0f; - fp[1] = 0.0f; - fp[2] = 1.0f; - if (channels == 4) { - fp[3] = 1.0f; - } - } - } - } - - if (image_pixels) { - MEM_freeN(image_pixels); - } - - /* Free image buffers to save memory during render. */ - if (free_cache) { - b_image.buffers_free(); - } - - return true; - } - else if (b_id.is_a(&RNA_Object)) { - /* smoke volume data */ - BL::Object b_ob(b_id); - BL::FluidDomainSettings b_domain = object_fluid_domain_find(b_ob); - - if (!b_domain) { - return false; - } -#if WITH_FLUID - int3 resolution = get_int3(b_domain.domain_resolution()); - int length, amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1; - - /* Velocity and heat data is always low-resolution. */ - if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) || - builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) { - amplify = 1; - } - - const int width = resolution.x * amplify; - const int height = resolution.y * amplify; - const int depth = resolution.z * amplify; - const size_t num_pixels = ((size_t)width) * height * depth; - - if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) { - FluidDomainSettings_density_grid_get_length(&b_domain.ptr, &length); - if (length == num_pixels) { - FluidDomainSettings_density_grid_get(&b_domain.ptr, pixels); - return true; - } - } - else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) { - /* this is in range 0..1, and interpreted by the OpenGL smoke viewer - * as 1500..3000 K with the first part faded to zero density */ - FluidDomainSettings_flame_grid_get_length(&b_domain.ptr, &length); - if (length == num_pixels) { - FluidDomainSettings_flame_grid_get(&b_domain.ptr, pixels); - return true; - } - } - else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) { - /* the RGB is "premultiplied" by density for better interpolation results */ - FluidDomainSettings_color_grid_get_length(&b_domain.ptr, &length); - if (length == num_pixels * 4) { - FluidDomainSettings_color_grid_get(&b_domain.ptr, pixels); - return true; - } - } - else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) { - FluidDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length); - if (length == num_pixels * 3) { - FluidDomainSettings_velocity_grid_get(&b_domain.ptr, pixels); - return true; - } - } - else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) { - FluidDomainSettings_heat_grid_get_length(&b_domain.ptr, &length); - if (length == num_pixels) { - FluidDomainSettings_heat_grid_get(&b_domain.ptr, pixels); - return true; - } - } - else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) { - FluidDomainSettings_temperature_grid_get_length(&b_domain.ptr, &length); - if (length == num_pixels) { - FluidDomainSettings_temperature_grid_get(&b_domain.ptr, pixels); - return true; - } - } - else { - fprintf( - stderr, "Cycles error: unknown volume attribute %s, skipping\n", builtin_name.c_str()); - pixels[0] = 0.0f; - return false; - } -#endif - fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n"); - } - else { - /* We originally were passing view_layer here but in reality we need a - * a depsgraph to pass to the RE_point_density_minmax() function. - */ - /* TODO(sergey): Check we're indeed in shader node tree. */ - PointerRNA ptr; - RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr); - BL::Node b_node(ptr); - if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { - BL::ShaderNodeTexPointDensity b_point_density_node(b_node); - int length; - b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels); - } - } - - return false; -} - -void BlenderSession::builtin_images_load() -{ - /* Force builtin images to be loaded along with Blender data sync. This - * is needed because we may be reading from depsgraph evaluated data which - * can be freed by Blender before Cycles reads it. - * - * TODO: the assumption that no further access to builtin image data will - * happen is really weak, and likely to break in the future. We should find - * a better solution to hand over the data directly to the image manager - * instead of through callbacks whose timing is difficult to control. */ - ImageManager *manager = session->scene->image_manager; - Device *device = session->device; - manager->device_load_builtin(device, session->scene, session->progress); -} - void BlenderSession::update_resumable_tile_manager(int num_samples) { const int num_resumable_chunks = BlenderSession::num_resumable_chunks, diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 07dccdc5a73..295d9d2e307 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -22,7 +22,7 @@ #include "RNA_access.h" #include "RNA_blender_cpp.h" -#include "blender/blender_util.h" +#include "blender/blender_id_map.h" #include "blender/blender_viewport.h" #include "render/scene.h" @@ -118,19 +118,13 @@ class BlenderSync { void **python_thread_state); void sync_film(BL::SpaceView3D &b_v3d); void sync_view(); + + /* Shader */ void sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all); void sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d); - void sync_curve_settings(); - void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree); - Mesh *sync_mesh(BL::Depsgraph &b_depsgrpah, - BL::Object &b_ob, - BL::Object &b_ob_instance, - bool object_updated, - bool use_particle_hair); - bool object_has_particle_hair(BL::Object b_ob); - void sync_particle_hair( - Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); + + /* Object */ Object *sync_object(BL::Depsgraph &b_depsgraph, BL::ViewLayer &b_view_layer, BL::DepsgraphObjectInstance &b_instance, @@ -139,6 +133,39 @@ class BlenderSync { bool show_lights, BlenderObjectCulling &culling, bool *use_portal); + + /* Volume */ + void sync_volume(BL::Object &b_ob, Mesh *mesh); + + /* Mesh */ + void sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh); + void sync_mesh_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step); + + /* Hair */ + void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh); + void sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step); + void sync_particle_hair( + Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); + void sync_curve_settings(); + bool object_has_particle_hair(BL::Object b_ob); + + /* Camera */ + void sync_camera_motion( + BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time); + + /* Geometry */ + Mesh *sync_geometry(BL::Depsgraph &b_depsgrpah, + BL::Object &b_ob, + BL::Object &b_ob_instance, + bool object_updated, + bool use_particle_hair); + void sync_geometry_motion(BL::Depsgraph &b_depsgraph, + BL::Object &b_ob, + Object *object, + float motion_time, + bool use_particle_hair); + + /* Light */ void sync_light(BL::Object &b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object &b_ob, @@ -147,14 +174,8 @@ class BlenderSync { Transform &tfm, bool *use_portal); void sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal); - void sync_mesh_motion(BL::Depsgraph &b_depsgraph, - BL::Object &b_ob, - Object *object, - float motion_time); - void sync_camera_motion( - BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time); - /* particles */ + /* Particles */ bool sync_dupli_particle(BL::Object &b_ob, BL::DepsgraphObjectInstance &b_instance, Object *object); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 6d6dd75db6b..cb7d1c62f60 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -531,7 +531,7 @@ static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_ return use_deform_motion; } -static inline BL::FluidDomainSettings object_fluid_domain_find(BL::Object &b_ob) +static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object &b_ob) { BL::Object::modifiers_iterator b_mod; @@ -539,8 +539,28 @@ static inline BL::FluidDomainSettings object_fluid_domain_find(BL::Object &b_ob) if (b_mod->is_a(&RNA_FluidModifier)) { BL::FluidModifier b_mmd(*b_mod); - if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN) + if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN && + b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_LIQUID) { return b_mmd.domain_settings(); + } + } + } + + return BL::FluidDomainSettings(PointerRNA_NULL); +} + +static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b_ob) +{ + BL::Object::modifiers_iterator b_mod; + + for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) { + if (b_mod->is_a(&RNA_FluidModifier)) { + BL::FluidModifier b_mmd(*b_mod); + + if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN && + b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_GAS) { + return b_mmd.domain_settings(); + } } } @@ -573,248 +593,20 @@ static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob, return Mesh::SUBDIVISION_NONE; } -/* ID Map - * - * Utility class to keep in sync with blender data. - * Used for objects, meshes, lights and shaders. */ - -template class id_map { - public: - id_map(vector *scene_data_) - { - scene_data = scene_data_; - } - - T *find(const BL::ID &id) - { - return find(id.ptr.owner_id); - } - - T *find(const K &key) - { - if (b_map.find(key) != b_map.end()) { - T *data = b_map[key]; - return data; - } - - return NULL; - } - - void set_recalc(const BL::ID &id) - { - b_recalc.insert(id.ptr.data); - } - - void set_recalc(void *id_ptr) - { - b_recalc.insert(id_ptr); - } - - bool has_recalc() - { - return !(b_recalc.empty()); - } - - void pre_sync() - { - used_set.clear(); - } - - bool sync(T **r_data, const BL::ID &id) - { - return sync(r_data, id, id, id.ptr.owner_id); - } - - bool sync(T **r_data, const BL::ID &id, const K &key) - { - return sync(r_data, id, id, key); - } - - bool sync(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) - { - T *data = find(key); - bool recalc; - - if (!data) { - /* add data if it didn't exist yet */ - data = new T(); - scene_data->push_back(data); - b_map[key] = data; - recalc = true; - } - else { - recalc = (b_recalc.find(id.ptr.data) != b_recalc.end()); - if (parent.ptr.data && parent.ptr.data != id.ptr.data) { - recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end()); - } - } - - used(data); - - *r_data = data; - return recalc; - } - - bool is_used(const K &key) - { - T *data = find(key); - return (data) ? used_set.find(data) != used_set.end() : false; - } - - void used(T *data) - { - /* tag data as still in use */ - used_set.insert(data); - } - - void set_default(T *data) - { - b_map[NULL] = data; - } - - bool post_sync(bool do_delete = true) - { - /* remove unused data */ - vector new_scene_data; - typename vector::iterator it; - bool deleted = false; - - for (it = scene_data->begin(); it != scene_data->end(); it++) { - T *data = *it; - - if (do_delete && used_set.find(data) == used_set.end()) { - delete data; - deleted = true; - } - else - new_scene_data.push_back(data); - } - - *scene_data = new_scene_data; - - /* update mapping */ - map new_map; - typedef pair TMapPair; - typename map::iterator jt; - - for (jt = b_map.begin(); jt != b_map.end(); jt++) { - TMapPair &pair = *jt; - - if (used_set.find(pair.second) != used_set.end()) - new_map[pair.first] = pair.second; - } - - used_set.clear(); - b_recalc.clear(); - b_map = new_map; - - return deleted; - } - - const map &key_to_scene_data() - { - return b_map; - } - - protected: - vector *scene_data; - map b_map; - set used_set; - set b_recalc; -}; - -/* Object Key */ - -enum { OBJECT_PERSISTENT_ID_SIZE = 16 }; - -struct ObjectKey { - void *parent; - int id[OBJECT_PERSISTENT_ID_SIZE]; - void *ob; - bool use_particle_hair; - - ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_, bool use_particle_hair_) - : parent(parent_), ob(ob_), use_particle_hair(use_particle_hair_) - { - if (id_) - memcpy(id, id_, sizeof(id)); - else - memset(id, 0, sizeof(id)); - } - - bool operator<(const ObjectKey &k) const - { - if (ob < k.ob) { - return true; - } - else if (ob == k.ob) { - if (parent < k.parent) { - return true; - } - else if (parent == k.parent) { - if (use_particle_hair < k.use_particle_hair) { - return true; - } - else if (use_particle_hair == k.use_particle_hair) { - return memcmp(id, k.id, sizeof(id)) < 0; - } - } - } - - return false; - } -}; - -/* Mesh Key */ - -struct MeshKey { - void *id; - bool use_particle_hair; - - MeshKey(void *id, bool use_particle_hair) : id(id), use_particle_hair(use_particle_hair) - { - } - - bool operator<(const MeshKey &k) const - { - if (id < k.id) { - return true; - } - else if (id == k.id) { - if (use_particle_hair < k.use_particle_hair) { - return true; - } - } - - return false; - } -}; - -/* Particle System Key */ - -struct ParticleSystemKey { - void *ob; - int id[OBJECT_PERSISTENT_ID_SIZE]; - - ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE]) : ob(ob_) - { - if (id_) - memcpy(id, id_, sizeof(id)); - else - memset(id, 0, sizeof(id)); - } +static inline uint object_ray_visibility(BL::Object &b_ob) +{ + PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility"); + uint flag = 0; - bool operator<(const ParticleSystemKey &k) const - { - /* first id is particle index, we don't compare that */ - if (ob < k.ob) - return true; - else if (ob == k.ob) - return memcmp(id + 1, k.id + 1, sizeof(int) * (OBJECT_PERSISTENT_ID_SIZE - 1)) < 0; + flag |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0; + flag |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : 0; + flag |= get_boolean(cvisibility, "glossy") ? PATH_RAY_GLOSSY : 0; + flag |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0; + flag |= get_boolean(cvisibility, "shadow") ? PATH_RAY_SHADOW : 0; + flag |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0; - return false; - } -}; + return flag; +} class EdgeMap { public: diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp new file mode 100644 index 00000000000..87fb9620725 --- /dev/null +++ b/intern/cycles/blender/blender_volume.cpp @@ -0,0 +1,95 @@ + +/* + * 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 "render/colorspace.h" +#include "render/mesh.h" +#include "render/object.h" + +#include "blender/blender_sync.h" +#include "blender/blender_util.h" + +CCL_NAMESPACE_BEGIN + +static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float frame) +{ + BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob); + if (!b_domain) { + return; + } + + ImageManager *image_manager = scene->image_manager; + AttributeStandard attributes[] = {ATTR_STD_VOLUME_DENSITY, + ATTR_STD_VOLUME_COLOR, + ATTR_STD_VOLUME_FLAME, + ATTR_STD_VOLUME_HEAT, + ATTR_STD_VOLUME_TEMPERATURE, + ATTR_STD_VOLUME_VELOCITY, + ATTR_STD_NONE}; + + for (int i = 0; attributes[i] != ATTR_STD_NONE; i++) { + AttributeStandard std = attributes[i]; + if (!mesh->need_attribute(scene, std)) { + continue; + } + + mesh->volume_isovalue = b_domain.clipping(); + + Attribute *attr = mesh->attributes.add(std); + VoxelAttribute *volume_data = attr->data_voxel(); + ImageMetaData metadata; + bool animated = false; + + volume_data->manager = image_manager; + volume_data->slot = image_manager->add_image(Attribute::standard_name(std), + b_ob.ptr.data, + animated, + frame, + INTERPOLATION_LINEAR, + EXTENSION_CLIP, + IMAGE_ALPHA_AUTO, + u_colorspace_raw, + metadata); + } + + /* Create a matrix to transform from object space to mesh texture space. + * This does not work with deformations but that can probably only be done + * well with a volume grid mapping of coordinates. */ + if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) { + Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM); + Transform *tfm = attr->data_transform(); + + BL::Mesh b_mesh(b_ob.data()); + float3 loc, size; + mesh_texture_space(b_mesh, loc, size); + + *tfm = transform_translate(-loc) * transform_scale(size); + } +} + +void BlenderSync::sync_volume(BL::Object &b_ob, Mesh *mesh) +{ + bool old_has_voxel_attributes = mesh->has_voxel_attributes(); + + /* Smoke domain. */ + sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current()); + + /* Tag update. */ + bool rebuild = (old_has_voxel_attributes != mesh->has_voxel_attributes()); + mesh->tag_update(scene, rebuild); +} + +CCL_NAMESPACE_END -- cgit v1.2.3 From 46c9872afaa8053f8b2894c038402b1beb3ac66c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 3 Feb 2020 21:21:11 +0100 Subject: Cleanup: remove unnecessary operations in Cycles curves export Clearing and computing bounds is already done elsewhere. --- intern/cycles/blender/blender_curves.cpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 64efaab70e0..e42151d8f48 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -989,24 +989,11 @@ bool BlenderSync::object_has_particle_hair(BL::Object b_ob) void BlenderSync::sync_particle_hair( Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) { - if (!motion) { - /* Clear stored curve data */ - mesh->curve_keys.clear(); - mesh->curve_radius.clear(); - mesh->curve_first_key.clear(); - mesh->curve_shader.clear(); - mesh->curve_attributes.clear(); - } - - /* obtain general settings */ - const bool use_curves = scene->curve_system_manager->use_curves; - - if (!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT && b_ob.mode() != b_ob.mode_EDIT)) { - if (!motion) - mesh->compute_bounds(); + if (b_ob.mode() == b_ob.mode_PARTICLE_EDIT || b_ob.mode() == b_ob.mode_EDIT) { return; } + /* obtain general settings */ const int primitive = scene->curve_system_manager->primitive; const int triangle_method = scene->curve_system_manager->triangle_method; const int resolution = scene->curve_system_manager->resolution; @@ -1159,7 +1146,6 @@ void BlenderSync::sync_particle_hair( } } - mesh->compute_bounds(); mesh->geometry_flags |= Mesh::GEOMETRY_CURVES; } @@ -1172,7 +1158,7 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me oldcurve_keys.steal_data(mesh->curve_keys); oldcurve_radius.steal_data(mesh->curve_radius); - if (view_layer.use_hair) { + if (view_layer.use_hair && scene->curve_system_manager->use_curves) { /* Particle hair. */ bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( -- cgit v1.2.3 From d9c5f0d25fc91b069158ae1ab4fddc21bfd85846 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 2 Feb 2020 12:04:19 +0100 Subject: Cleanup: split Cycles Hair and Mesh classes, with Geometry base class --- intern/cycles/app/cycles_xml.cpp | 4 +- intern/cycles/blender/blender_curves.cpp | 242 ++-- intern/cycles/blender/blender_geometry.cpp | 100 +- intern/cycles/blender/blender_id_map.h | 56 +- intern/cycles/blender/blender_light.cpp | 6 +- intern/cycles/blender/blender_mesh.cpp | 14 +- intern/cycles/blender/blender_object.cpp | 33 +- intern/cycles/blender/blender_particles.cpp | 6 +- intern/cycles/blender/blender_session.cpp | 7 +- intern/cycles/blender/blender_shader.cpp | 4 +- intern/cycles/blender/blender_sync.cpp | 25 +- intern/cycles/blender/blender_sync.h | 26 +- intern/cycles/bvh/bvh.cpp | 82 +- intern/cycles/bvh/bvh.h | 10 +- intern/cycles/bvh/bvh2.cpp | 4 +- intern/cycles/bvh/bvh2.h | 4 +- intern/cycles/bvh/bvh4.cpp | 4 +- intern/cycles/bvh/bvh4.h | 4 +- intern/cycles/bvh/bvh8.cpp | 29 +- intern/cycles/bvh/bvh8.h | 4 +- intern/cycles/bvh/bvh_build.cpp | 79 +- intern/cycles/bvh/bvh_build.h | 6 +- intern/cycles/bvh/bvh_embree.cpp | 165 +-- intern/cycles/bvh/bvh_embree.h | 10 +- intern/cycles/bvh/bvh_optix.cpp | 129 +- intern/cycles/bvh/bvh_optix.h | 7 +- intern/cycles/bvh/bvh_params.h | 5 - intern/cycles/bvh/bvh_split.cpp | 41 +- intern/cycles/bvh/bvh_split.h | 6 +- intern/cycles/bvh/bvh_unaligned.cpp | 14 +- intern/cycles/device/device_optix.cpp | 286 ++-- intern/cycles/graph/node_type.h | 8 +- intern/cycles/kernel/kernel_types.h | 2 +- intern/cycles/render/CMakeLists.txt | 4 + intern/cycles/render/attribute.cpp | 118 +- intern/cycles/render/attribute.h | 15 +- intern/cycles/render/bake.cpp | 4 +- intern/cycles/render/camera.cpp | 2 +- intern/cycles/render/film.cpp | 6 +- intern/cycles/render/geometry.cpp | 1548 ++++++++++++++++++++++ intern/cycles/render/geometry.h | 202 +++ intern/cycles/render/hair.cpp | 489 +++++++ intern/cycles/render/hair.h | 151 +++ intern/cycles/render/light.cpp | 16 +- intern/cycles/render/mesh.cpp | 1891 +-------------------------- intern/cycles/render/mesh.h | 239 +--- intern/cycles/render/mesh_displace.cpp | 6 +- intern/cycles/render/mesh_volume.cpp | 2 +- intern/cycles/render/nodes.cpp | 6 +- intern/cycles/render/object.cpp | 240 ++-- intern/cycles/render/object.h | 4 +- intern/cycles/render/scene.cpp | 22 +- intern/cycles/render/scene.h | 8 +- intern/cycles/render/session.cpp | 27 +- intern/cycles/render/shader.cpp | 16 +- intern/cycles/render/shader.h | 2 +- 56 files changed, 3509 insertions(+), 2931 deletions(-) create mode 100644 intern/cycles/render/geometry.cpp create mode 100644 intern/cycles/render/geometry.h create mode 100644 intern/cycles/render/hair.cpp create mode 100644 intern/cycles/render/hair.h diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index bdb014d31ef..2540786a014 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -380,11 +380,11 @@ static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm) { /* create mesh */ Mesh *mesh = new Mesh(); - scene->meshes.push_back(mesh); + scene->geometry.push_back(mesh); /* create object*/ Object *object = new Object(); - object->mesh = mesh; + object->geometry = mesh; object->tfm = tfm; scene->objects.push_back(object); diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index e42151d8f48..affd5685337 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -17,6 +17,7 @@ #include "render/attribute.h" #include "render/camera.h" #include "render/curves.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/object.h" #include "render/scene.h" @@ -107,12 +108,12 @@ static void InterpolateKeySegments( } static bool ObtainCacheParticleData( - Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background) + Geometry *geom, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background) { int curvenum = 0; int keyno = 0; - if (!(mesh && b_mesh && b_ob && CData)) + if (!(geom && b_mesh && b_ob && CData)) return false; Transform tfm = get_transform(b_ob->matrix_world()); @@ -128,7 +129,7 @@ static bool ObtainCacheParticleData( if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) { - int shader = clamp(b_part.material() - 1, 0, mesh->used_shaders.size() - 1); + int shader = clamp(b_part.material() - 1, 0, geom->used_shaders.size() - 1); int display_step = background ? b_part.render_step() : b_part.display_step(); int totparts = b_psys.particles.length(); int totchild = background ? b_psys.child_particles.length() : @@ -202,14 +203,14 @@ static bool ObtainCacheParticleData( return true; } -static bool ObtainCacheParticleUV(Mesh *mesh, +static bool ObtainCacheParticleUV(Geometry *geom, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int uv_num) { - if (!(mesh && b_mesh && b_ob && CData)) + if (!(geom && b_mesh && b_ob && CData)) return false; CData->curve_uv.clear(); @@ -265,14 +266,14 @@ static bool ObtainCacheParticleUV(Mesh *mesh, return true; } -static bool ObtainCacheParticleVcol(Mesh *mesh, +static bool ObtainCacheParticleVcol(Geometry *geom, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num) { - if (!(mesh && b_mesh && b_ob && CData)) + if (!(geom && b_mesh && b_ob && CData)) return false; CData->curve_vcol.clear(); @@ -594,21 +595,55 @@ static void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, in /* texture coords still needed */ } -static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData) +static void export_hair_motion_validate_attribute(Hair *hair, + int motion_step, + int num_motion_keys, + bool have_motion) +{ + Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + const int num_keys = hair->curve_keys.size(); + + 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 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++) { + float4 *mP = attr_mP->data_float4() + step * num_keys; + + for (int key = 0; key < num_keys; key++) { + mP[key] = float3_to_float4(hair->curve_keys[key]); + mP[key].w = hair->curve_radius[key]; + } + } + } +} + +static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CData) { int num_keys = 0; int num_curves = 0; - if (mesh->num_curves()) + if (hair->num_curves()) return; Attribute *attr_intercept = NULL; Attribute *attr_random = NULL; - if (mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) - attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT); - if (mesh->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) - attr_random = mesh->curve_attributes.add(ATTR_STD_CURVE_RANDOM); + if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) + attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT); + if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) + attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM); /* compute and reserve size of arrays */ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { @@ -621,10 +656,10 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa } if (num_curves > 0) { - VLOG(1) << "Exporting curve segments for mesh " << mesh->name; + VLOG(1) << "Exporting curve segments for mesh " << hair->name; } - mesh->reserve_curves(mesh->num_curves() + num_curves, mesh->curve_keys.size() + num_keys); + hair->reserve_curves(hair->num_curves() + num_curves, hair->curve_keys.size() + num_keys); num_keys = 0; num_curves = 0; @@ -649,7 +684,7 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) { radius = 0.0f; } - mesh->add_curve_key(ickey_loc, radius); + hair->add_curve_key(ickey_loc, radius); if (attr_intercept) attr_intercept->add(time); @@ -660,16 +695,16 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa attr_random->add(hash_uint2_to_float(num_curves, 0)); } - mesh->add_curve(num_keys, CData->psys_shader[sys]); + hair->add_curve(num_keys, CData->psys_shader[sys]); num_keys += num_curve_keys; num_curves++; } } /* check allocation */ - if ((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) { + if ((hair->curve_keys.size() != num_keys) || (hair->num_curves() != num_curves)) { VLOG(1) << "Allocation failed, clearing data"; - mesh->clear(); + hair->clear(); } } @@ -713,24 +748,24 @@ static float4 LerpCurveSegmentMotionCV(ParticleCurveData *CData, int sys, int cu return lerp(mP, mP2, remainder); } -static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int motion_step) +static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int motion_step) { - VLOG(1) << "Exporting curve motion segments for mesh " << mesh->name << ", motion step " + VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step " << motion_step; /* find attribute */ - Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + 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 = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); + attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); new_attribute = true; } /* export motion vectors for curve keys */ - size_t numkeys = mesh->curve_keys.size(); + size_t numkeys = hair->curve_keys.size(); float4 *mP = attr_mP->data_float4() + motion_step * numkeys; bool have_motion = false; int i = 0; @@ -741,24 +776,24 @@ static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { /* Curve lengths may not match! Curves can be clipped. */ - int curve_key_end = (num_curves + 1 < (int)mesh->curve_first_key.size() ? - mesh->curve_first_key[num_curves + 1] : - (int)mesh->curve_keys.size()); - const int num_center_curve_keys = curve_key_end - mesh->curve_first_key[num_curves]; + int curve_key_end = (num_curves + 1 < (int)hair->curve_first_key.size() ? + hair->curve_first_key[num_curves + 1] : + (int)hair->curve_keys.size()); + const int num_center_curve_keys = curve_key_end - hair->curve_first_key[num_curves]; const int is_num_keys_different = CData->curve_keynum[curve] - num_center_curve_keys; if (!is_num_keys_different) { for (int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) { - if (i < mesh->curve_keys.size()) { + if (i < hair->curve_keys.size()) { mP[i] = CurveSegmentMotionCV(CData, sys, curve, curvekey); if (!have_motion) { /* unlike mesh coordinates, these tend to be slightly different * between frames due to particle transforms into/out of object * space, so we use an epsilon to detect actual changes */ - float4 curve_key = float3_to_float4(mesh->curve_keys[i]); - curve_key.w = mesh->curve_radius[i]; + float4 curve_key = float3_to_float4(hair->curve_keys[i]); + curve_key.w = hair->curve_radius[i]; if (len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f) have_motion = true; } @@ -784,40 +819,15 @@ static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int /* in case of new attribute, we verify if there really was any motion */ if (new_attribute) { - if (i != numkeys || !have_motion) { - /* No motion or hair "topology" changed, remove attributes again. */ - if (i != numkeys) { - VLOG(1) << "Hair topology changed, removing attribute."; - } - else { - VLOG(1) << "No motion, removing attribute."; - } - mesh->curve_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++) { - float4 *mP = attr_mP->data_float4() + step * numkeys; - - for (int key = 0; key < numkeys; key++) { - mP[key] = float3_to_float4(mesh->curve_keys[key]); - mP[key].w = mesh->curve_radius[key]; - } - } - } + export_hair_motion_validate_attribute(hair, motion_step, i, have_motion); } } -static void ExportCurveTriangleUV(ParticleCurveData *CData, - int vert_offset, - int resol, - float2 *uvdata) +static void ExportCurveTriangleUV(ParticleCurveData *CData, int resol, float2 *uvdata) { if (uvdata == NULL) return; - int vertexindex = vert_offset; + int vertexindex = 0; for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { for (int curve = CData->psys_firstcurve[sys]; @@ -845,15 +855,12 @@ static void ExportCurveTriangleUV(ParticleCurveData *CData, } } -static void ExportCurveTriangleVcol(ParticleCurveData *CData, - int vert_offset, - int resol, - uchar4 *cdata) +static void ExportCurveTriangleVcol(ParticleCurveData *CData, int resol, uchar4 *cdata) { if (cdata == NULL) return; - int vertexindex = vert_offset; + int vertexindex = 0; for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { for (int curve = CData->psys_firstcurve[sys]; @@ -952,7 +959,7 @@ void BlenderSync::sync_curve_settings() if ((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) && (b_psys->settings().type() == BL::ParticleSettings::type_HAIR)) { BL::ID key = BKE_object_is_modified(*b_ob) ? *b_ob : b_ob->data(); - mesh_map.set_recalc(key); + geometry_map.set_recalc(key); object_map.set_recalc(*b_ob); } } @@ -987,28 +994,28 @@ bool BlenderSync::object_has_particle_hair(BL::Object b_ob) /* Old particle hair. */ void BlenderSync::sync_particle_hair( - Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) + Geometry *geom, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) { + Hair *hair = (geom->type == Geometry::HAIR) ? static_cast(geom) : NULL; + Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast(geom) : NULL; + + /* obtain general settings */ if (b_ob.mode() == b_ob.mode_PARTICLE_EDIT || b_ob.mode() == b_ob.mode_EDIT) { return; } - /* obtain general settings */ - const int primitive = scene->curve_system_manager->primitive; const int triangle_method = scene->curve_system_manager->triangle_method; const int resolution = scene->curve_system_manager->resolution; - const size_t vert_num = mesh->verts.size(); - const size_t tri_num = mesh->num_triangles(); int used_res = 1; /* extract particle hair data - should be combined with connecting to mesh later*/ ParticleCurveData CData; - ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview); + ObtainCacheParticleData(geom, &b_mesh, &b_ob, &CData, !preview); /* add hair geometry to mesh */ - if (primitive == CURVE_TRIANGLES) { + if (mesh) { if (triangle_method == CURVE_CAMERA_TRIANGLES) { /* obtain camera parameters */ float3 RotCam; @@ -1032,31 +1039,31 @@ void BlenderSync::sync_particle_hair( } else { if (motion) - ExportCurveSegmentsMotion(mesh, &CData, motion_step); + ExportCurveSegmentsMotion(hair, &CData, motion_step); else - ExportCurveSegments(scene, mesh, &CData); + ExportCurveSegments(scene, hair, &CData); } /* generated coordinates from first key. we should ideally get this from * blender to handle deforming objects */ if (!motion) { - if (mesh->need_attribute(scene, ATTR_STD_GENERATED)) { + if (geom->need_attribute(scene, ATTR_STD_GENERATED)) { float3 loc, size; mesh_texture_space(b_mesh, loc, size); - if (primitive == CURVE_TRIANGLES) { + if (mesh) { Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED); float3 *generated = attr_generated->data_float3(); - for (size_t i = vert_num; i < mesh->verts.size(); i++) + for (size_t i = 0; i < mesh->verts.size(); i++) generated[i] = mesh->verts[i] * size - loc; } else { - Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED); + Attribute *attr_generated = hair->attributes.add(ATTR_STD_GENERATED); float3 *generated = attr_generated->data_float3(); - for (size_t i = 0; i < mesh->num_curves(); i++) { - float3 co = mesh->curve_keys[mesh->get_curve(i).first_key]; + for (size_t i = 0; i < hair->num_curves(); i++) { + float3 co = hair->curve_keys[hair->get_curve(i).first_key]; generated[i] = co * size - loc; } } @@ -1069,21 +1076,21 @@ void BlenderSync::sync_particle_hair( int vcol_num = 0; for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) { - if (!mesh->need_attribute(scene, ustring(l->name().c_str()))) + if (!geom->need_attribute(scene, ustring(l->name().c_str()))) continue; - ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num); + ObtainCacheParticleVcol(geom, &b_mesh, &b_ob, &CData, !preview, vcol_num); - if (primitive == CURVE_TRIANGLES) { + if (mesh) { Attribute *attr_vcol = mesh->attributes.add( ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE); uchar4 *cdata = attr_vcol->data_uchar4(); - ExportCurveTriangleVcol(&CData, tri_num * 3, used_res, cdata); + ExportCurveTriangleVcol(&CData, used_res, cdata); } else { - Attribute *attr_vcol = mesh->curve_attributes.add( + Attribute *attr_vcol = hair->attributes.add( ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); float3 *fdata = attr_vcol->data_float3(); @@ -1111,12 +1118,12 @@ void BlenderSync::sync_particle_hair( ustring name = ustring(l->name().c_str()); /* UV map */ - if (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) { + if (geom->need_attribute(scene, name) || geom->need_attribute(scene, std)) { Attribute *attr_uv; - ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num); + ObtainCacheParticleUV(geom, &b_mesh, &b_ob, &CData, !preview, uv_num); - if (primitive == CURVE_TRIANGLES) { + if (mesh) { if (active_render) attr_uv = mesh->attributes.add(std, name); else @@ -1124,13 +1131,13 @@ void BlenderSync::sync_particle_hair( float2 *uv = attr_uv->data_float2(); - ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv); + ExportCurveTriangleUV(&CData, used_res, uv); } else { if (active_render) - attr_uv = mesh->curve_attributes.add(std, name); + attr_uv = hair->attributes.add(std, name); else - attr_uv = mesh->curve_attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE); + attr_uv = hair->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE); float2 *uv = attr_uv->data_float2(); @@ -1145,44 +1152,56 @@ void BlenderSync::sync_particle_hair( } } } - - mesh->geometry_flags |= Mesh::GEOMETRY_CURVES; } -void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) +void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Geometry *geom) { - /* compares curve_keys rather than strands in order to handle quick hair - * adjustments in dynamic BVH - other methods could probably do this better*/ + Hair *hair = (geom->type == Geometry::HAIR) ? static_cast(geom) : NULL; + Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast(geom) : NULL; + + /* Compares curve_keys rather than strands in order to handle quick hair + * adjustments in dynamic BVH - other methods could probably do this better. */ array oldcurve_keys; array oldcurve_radius; - oldcurve_keys.steal_data(mesh->curve_keys); - oldcurve_radius.steal_data(mesh->curve_radius); + array oldtriangles; + if (hair) { + oldcurve_keys.steal_data(hair->curve_keys); + oldcurve_radius.steal_data(hair->curve_radius); + } + else { + oldtriangles.steal_data(mesh->triangles); + } if (view_layer.use_hair && scene->curve_system_manager->use_curves) { /* Particle hair. */ - bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); + bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(mesh, b_mesh, b_ob, false); + sync_particle_hair(geom, b_mesh, b_ob, false); free_object_to_mesh(b_data, b_ob, b_mesh); } } /* tag update */ - bool rebuild = (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius); - mesh->tag_update(scene, rebuild); + const bool rebuild = (hair && ((oldcurve_keys != hair->curve_keys) || + (oldcurve_radius != hair->curve_radius))) || + (mesh && (oldtriangles != mesh->triangles)); + + geom->tag_update(scene, rebuild); } void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, - Mesh *mesh, + Geometry *geom, int motion_step) { - /* Skip if no curves were exported. */ - size_t numkeys = mesh->curve_keys.size(); - if (numkeys == 0) { + Hair *hair = (geom->type == Geometry::HAIR) ? static_cast(geom) : NULL; + Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast(geom) : NULL; + + /* Skip if nothing exported. */ + if ((hair && hair->num_keys() == 0) || (mesh && mesh->verts.size() == 0)) { return; } @@ -1191,17 +1210,18 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, /* Particle hair. */ BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(mesh, b_mesh, b_ob, true, motion_step); + sync_particle_hair(geom, b_mesh, b_ob, true, motion_step); free_object_to_mesh(b_data, b_ob, b_mesh); return; } } /* No deformation on this frame, copy coordinates if other frames did have it. */ - Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if (attr_mP) { - float3 *keys = &mesh->curve_keys[0]; - memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys); + if (hair) { + hair->copy_center_to_motion_step(motion_step); + } + else { + mesh->copy_center_to_motion_step(motion_step); } } diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp index 151b741b003..8b803835b62 100644 --- a/intern/cycles/blender/blender_geometry.cpp +++ b/intern/cycles/blender/blender_geometry.cpp @@ -15,6 +15,8 @@ * limitations under the License. */ +#include "render/curves.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/object.h" @@ -23,18 +25,22 @@ CCL_NAMESPACE_BEGIN -Mesh *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, - BL::Object &b_ob, - BL::Object &b_ob_instance, - bool object_updated, - bool use_particle_hair) +Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, + BL::Object &b_ob, + BL::Object &b_ob_instance, + bool object_updated, + bool use_particle_hair) { /* Test if we can instance or if the object is modified. */ BL::ID b_ob_data = b_ob.data(); BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; - MeshKey key(b_key_id.ptr.data, use_particle_hair); + GeometryKey key(b_key_id.ptr.data, use_particle_hair); BL::Material material_override = view_layer.material_override; Shader *default_shader = scene->default_surface; + Geometry::Type geom_type = (use_particle_hair && + (scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ? + Geometry::HAIR : + Geometry::MESH; /* Find shader indices. */ vector used_shaders; @@ -58,53 +64,76 @@ Mesh *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, } /* Test if we need to sync. */ - Mesh *mesh; + Geometry *geom = geometry_map.find(key); + bool sync = true; + if (geom == NULL) { + /* Add new geometry if it did not exist yet. */ + if (geom_type == Geometry::HAIR) { + geom = new Hair(); + } + else { + geom = new Mesh(); + } + geometry_map.add(key, geom); + } + else { + /* Test if we need to update existing geometry. */ + sync = geometry_map.update(geom, b_key_id); + } - if (!mesh_map.sync(&mesh, b_key_id, key)) { - /* If transform was applied to mesh, need full update. */ - if (object_updated && mesh->transform_applied) + if (!sync) { + /* If transform was applied to geometry, need full update. */ + if (object_updated && geom->transform_applied) { ; - /* Test if shaders changed, these can be object level so mesh + } + /* Test if shaders changed, these can be object level so geometry * does not get tagged for recalc. */ - else if (mesh->used_shaders != used_shaders) + else if (geom->used_shaders != used_shaders) { ; + } else { /* Even if not tagged for recalc, we may need to sync anyway - * because the shader needs different mesh attributes. */ + * because the shader needs different geometry attributes. */ bool attribute_recalc = false; - foreach (Shader *shader, mesh->used_shaders) - if (shader->need_update_mesh) + foreach (Shader *shader, geom->used_shaders) { + if (shader->need_update_geometry) { attribute_recalc = true; + } + } - if (!attribute_recalc) - return mesh; + if (!attribute_recalc) { + return geom; + } } } - /* Ensure we only sync instanced meshes once. */ - if (mesh_synced.find(mesh) != mesh_synced.end()) - return mesh; + /* Ensure we only sync instanced geometry once. */ + if (geometry_synced.find(geom) != geometry_synced.end()) { + return geom; + } progress.set_sync_status("Synchronizing object", b_ob.name()); - mesh_synced.insert(mesh); + geometry_synced.insert(geom); - mesh->clear(); - mesh->used_shaders = used_shaders; - mesh->name = ustring(b_ob_data.name().c_str()); + geom->clear(); + geom->used_shaders = used_shaders; + geom->name = ustring(b_ob_data.name().c_str()); if (use_particle_hair) { - sync_hair(b_depsgraph, b_ob, mesh); + sync_hair(b_depsgraph, b_ob, geom); } else if (object_fluid_gas_domain_find(b_ob)) { + Mesh *mesh = static_cast(geom); sync_volume(b_ob, mesh); } else { + Mesh *mesh = static_cast(geom); sync_mesh(b_depsgraph, b_ob, mesh); } - return mesh; + return geom; } void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, @@ -113,32 +142,33 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, float motion_time, bool use_particle_hair) { - /* Ensure we only sync instanced meshes once. */ - Mesh *mesh = object->mesh; + /* Ensure we only sync instanced geometry once. */ + Geometry *geom = object->geometry; - if (mesh_motion_synced.find(mesh) != mesh_motion_synced.end()) + if (geometry_motion_synced.find(geom) != geometry_motion_synced.end()) return; - mesh_motion_synced.insert(mesh); + geometry_motion_synced.insert(geom); - /* Ensure we only motion sync meshes that also had mesh synced, to avoid + /* Ensure we only motion sync geometry that also had geometry synced, to avoid * unnecessary work and to ensure that its attributes were clear. */ - if (mesh_synced.find(mesh) == mesh_synced.end()) + if (geometry_synced.find(geom) == geometry_synced.end()) return; - /* Find time matching motion step required by mesh. */ - int motion_step = mesh->motion_step(motion_time); + /* Find time matching motion step required by geometry. */ + int motion_step = geom->motion_step(motion_time); if (motion_step < 0) { return; } if (use_particle_hair) { - sync_hair_motion(b_depsgraph, b_ob, mesh, motion_step); + sync_hair_motion(b_depsgraph, b_ob, geom, motion_step); } else if (object_fluid_gas_domain_find(b_ob)) { /* No volume motion blur support yet. */ } else { + Mesh *mesh = static_cast(geom); sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step); } } diff --git a/intern/cycles/blender/blender_id_map.h b/intern/cycles/blender/blender_id_map.h index 52031cd9f34..83c93bb09ee 100644 --- a/intern/cycles/blender/blender_id_map.h +++ b/intern/cycles/blender/blender_id_map.h @@ -72,41 +72,61 @@ template class id_map { used_set.clear(); } - bool sync(T **r_data, const BL::ID &id) + /* Add new data. */ + void add(const K &key, T *data) { - return sync(r_data, id, id, id.ptr.owner_id); + assert(find(key) == NULL); + scene_data->push_back(data); + b_map[key] = data; + used(data); } - bool sync(T **r_data, const BL::ID &id, const K &key) + /* Update existing data. */ + bool update(T *data, const BL::ID &id) { - return sync(r_data, id, id, key); + return update(data, id, id); + } + bool update(T *data, const BL::ID &id, const BL::ID &parent) + { + bool recalc = (b_recalc.find(id.ptr.data) != b_recalc.end()); + if (parent.ptr.data && parent.ptr.data != id.ptr.data) { + recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end()); + } + used(data); + return recalc; } - bool sync(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) + /* Combined add and update as needed. */ + bool add_or_update(T **r_data, const BL::ID &id) + { + return add_or_update(r_data, id, id, id.ptr.owner_id); + } + bool add_or_update(T **r_data, const BL::ID &id, const K &key) + { + return add_or_update(r_data, id, id, key); + } + bool add_or_update(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) { T *data = find(key); bool recalc; if (!data) { - /* add data if it didn't exist yet */ + /* Add data if it didn't exist yet. */ data = new T(); - scene_data->push_back(data); - b_map[key] = data; + add(key, data); recalc = true; } else { - recalc = (b_recalc.find(id.ptr.data) != b_recalc.end()); - if (parent.ptr.data && parent.ptr.data != id.ptr.data) { - recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end()); - } + /* check if updated needed. */ + recalc = update(data, id, parent); } - used(data); - *r_data = data; return recalc; } + /* Combined add or update for convenience. */ + bool is_used(const K &key) { T *data = find(key); @@ -220,20 +240,20 @@ struct ObjectKey { } }; -/* Mesh Key +/* Geometry Key * * We export separate geomtry for a mesh and its particle hair, so key needs to * distinguish between them. */ -struct MeshKey { +struct GeometryKey { void *id; bool use_particle_hair; - MeshKey(void *id, bool use_particle_hair) : id(id), use_particle_hair(use_particle_hair) + GeometryKey(void *id, bool use_particle_hair) : id(id), use_particle_hair(use_particle_hair) { } - bool operator<(const MeshKey &k) const + bool operator<(const GeometryKey &k) const { if (id < k.id) { return true; diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp index a8e28a011d7..5351de2e84b 100644 --- a/intern/cycles/blender/blender_light.cpp +++ b/intern/cycles/blender/blender_light.cpp @@ -39,9 +39,9 @@ void BlenderSync::sync_light(BL::Object &b_parent, BL::Light b_light(b_ob.data()); /* Update if either object or light data changed. */ - if (!light_map.sync(&light, b_ob, b_parent, key)) { + if (!light_map.add_or_update(&light, b_ob, b_parent, key)) { Shader *shader; - if (!shader_map.sync(&shader, b_light)) { + if (!shader_map.add_or_update(&shader, b_light)) { if (light->is_portal) *use_portal = true; return; @@ -176,7 +176,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) Light *light; ObjectKey key(b_world, 0, b_world, false); - if (light_map.sync(&light, b_world, b_world, key) || world_recalc || + if (light_map.add_or_update(&light, b_world, b_world, key) || world_recalc || b_world.ptr.data != world_map) { light->type = LIGHT_BACKGROUND; if (sampling_method == SAMPLING_MANUAL) { diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 00faafe29ee..332c26161dc 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -719,7 +719,6 @@ static void create_mesh(Scene *scene, /* allocate memory */ mesh->reserve_mesh(numverts, numtris); mesh->reserve_subd_faces(numfaces, numngons, numcorners); - mesh->geometry_flags |= Mesh::GEOMETRY_TRIANGLES; /* create vertex coordinates and normals */ BL::Mesh::vertices_iterator v; @@ -1053,18 +1052,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, } /* No deformation on this frame, copy coordinates if other frames did have it. */ - Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - - if (attr_mP) { - Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); - Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL); - float3 *P = &mesh->verts[0]; - float3 *N = (attr_N) ? attr_N->data_float3() : NULL; - - memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts); - if (attr_mN) - memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts); - } + mesh->copy_center_to_motion_step(motion_step); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 13dfd0867ba..2b1d1eff7e5 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -191,7 +191,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, } /* mesh deformation */ - if (object->mesh) + if (object->geometry) sync_geometry_motion(b_depsgraph, b_ob, object, motion_time, use_particle_hair); } @@ -201,11 +201,11 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* test if we need to sync */ bool object_updated = false; - if (object_map.sync(&object, b_ob, b_parent, key)) + if (object_map.add_or_update(&object, b_ob, b_parent, key)) object_updated = true; /* mesh sync */ - object->mesh = sync_geometry( + object->geometry = sync_geometry( b_depsgraph, b_ob, b_ob_instance, object_updated, use_particle_hair); /* special case not tracked by object update flags */ @@ -248,7 +248,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* object sync * transform comparison should not be needed, but duplis don't work perfect * in the depsgraph and may not signal changes, so this is a workaround */ - if (object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) { + if (object_updated || (object->geometry && object->geometry->need_update) || + tfm != object->tfm) { object->name = b_ob.name().c_str(); object->pass_id = b_ob.pass_index(); object->color = get_float3(b_ob.color()); @@ -257,23 +258,23 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* motion blur */ Scene::MotionType need_motion = scene->need_motion(); - if (need_motion != Scene::MOTION_NONE && object->mesh) { - Mesh *mesh = object->mesh; - mesh->use_motion_blur = false; - mesh->motion_steps = 0; + if (need_motion != Scene::MOTION_NONE && object->geometry) { + Geometry *geom = object->geometry; + geom->use_motion_blur = false; + geom->motion_steps = 0; uint motion_steps; if (need_motion == Scene::MOTION_BLUR) { motion_steps = object_motion_steps(b_parent, b_ob); - mesh->motion_steps = motion_steps; + geom->motion_steps = motion_steps; if (motion_steps && object_use_deform_motion(b_parent, b_ob)) { - mesh->use_motion_blur = true; + geom->use_motion_blur = true; } } else { motion_steps = 3; - mesh->motion_steps = motion_steps; + geom->motion_steps = motion_steps; } object->motion.clear(); @@ -324,13 +325,13 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, if (!motion) { /* prepare for sync */ light_map.pre_sync(); - mesh_map.pre_sync(); + geometry_map.pre_sync(); object_map.pre_sync(); particle_system_map.pre_sync(); motion_times.clear(); } else { - mesh_motion_synced.clear(); + geometry_motion_synced.clear(); } /* initialize culling */ @@ -394,8 +395,8 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, /* handle removed data and modified pointers */ if (light_map.post_sync()) scene->light_manager->tag_update(scene); - if (mesh_map.post_sync()) - scene->mesh_manager->tag_update(scene); + if (geometry_map.post_sync()) + scene->geometry_manager->tag_update(scene); if (object_map.post_sync()) scene->object_manager->tag_update(scene); if (particle_system_map.post_sync()) @@ -403,7 +404,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, } if (motion) - mesh_motion_synced.clear(); + geometry_motion_synced.clear(); } void BlenderSync::sync_motion(BL::RenderSettings &b_render, diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index d74f132ed60..e5eab1ae62b 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -39,7 +39,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, object->hide_on_missing_motion = true; /* test if we need particle data */ - if (!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE)) + if (!object->geometry->need_attribute(scene, ATTR_STD_PARTICLE)) return false; /* don't handle child particles yet */ @@ -53,10 +53,10 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, ParticleSystem *psys; bool first_use = !particle_system_map.is_used(key); - bool need_update = particle_system_map.sync(&psys, b_ob, b_instance.object(), key); + bool need_update = particle_system_map.add_or_update(&psys, b_ob, b_instance.object(), key); /* no update needed? */ - if (!need_update && !object->mesh->need_update && !scene->object_manager->need_update) + if (!need_update && !object->geometry->need_update && !scene->object_manager->need_update) return true; /* first time used in this sync loop? clear and tag update */ diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 663f3d72110..1490348743e 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -720,9 +720,12 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, int tri_offset = 0; for (size_t i = 0; i < scene->objects.size(); i++) { - if (strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) { + const Object *object = scene->objects[i]; + const Geometry *geom = object->geometry; + if (object->name == b_object.name() && geom->type == Geometry::MESH) { + const Mesh *mesh = static_cast(geom); object_index = i; - tri_offset = scene->objects[i]->mesh->tri_offset; + tri_offset = mesh->prim_offset; break; } } diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 206058259af..635405e42c7 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -1255,7 +1255,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) Shader *shader; /* test if we need to sync */ - if (shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) { + if (shader_map.add_or_update(&shader, b_mat) || shader->need_sync_object || update_all) { ShaderGraph *graph = new ShaderGraph(); shader->name = b_mat.name().c_str(); @@ -1480,7 +1480,7 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all) Shader *shader; /* test if we need to sync */ - if (shader_map.sync(&shader, b_light) || update_all) { + if (shader_map.add_or_update(&shader, b_light) || update_all) { ShaderGraph *graph = new ShaderGraph(); /* create nodes */ diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index bb8a132ebb7..8960c84567e 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -56,7 +56,7 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine, b_scene(b_scene), shader_map(&scene->shaders), object_map(&scene->objects), - mesh_map(&scene->meshes), + geometry_map(&scene->geometry), light_map(&scene->lights), particle_system_map(&scene->particle_systems), world_map(NULL), @@ -108,12 +108,15 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d } if (dicing_prop_changed) { - for (const pair &iter : mesh_map.key_to_scene_data()) { - Mesh *mesh = iter.second; - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { - PointerRNA id_ptr; - RNA_id_pointer_create((::ID *)iter.first.id, &id_ptr); - mesh_map.set_recalc(BL::ID(id_ptr)); + for (const pair &iter : geometry_map.key_to_scene_data()) { + Geometry *geom = iter.second; + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { + PointerRNA id_ptr; + RNA_id_pointer_create((::ID *)iter.first.id, &id_ptr); + geometry_map.set_recalc(BL::ID(id_ptr)); + } } } } @@ -148,7 +151,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d if (updated_geometry || (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) { BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data(); - mesh_map.set_recalc(key); + geometry_map.set_recalc(key); } } else if (object_is_light(b_ob)) { @@ -166,7 +169,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d /* Mesh */ else if (b_id.is_a(&RNA_Mesh)) { BL::Mesh b_mesh(b_id); - mesh_map.set_recalc(b_mesh); + geometry_map.set_recalc(b_mesh); } /* World */ else if (b_id.is_a(&RNA_World)) { @@ -213,7 +216,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, sync_images(); sync_curve_settings(); - mesh_synced.clear(); /* use for objects and motion sync */ + geometry_synced.clear(); /* use for objects and motion sync */ if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE || scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) { @@ -221,7 +224,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, } sync_motion(b_render, b_depsgraph, b_v3d, b_override, width, height, python_thread_state); - mesh_synced.clear(); + geometry_synced.clear(); /* Shader sync done at the end, since object sync uses it. * false = don't delete unused shaders, not supported. */ diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 295d9d2e307..f8134ff8b5c 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -40,6 +40,7 @@ class BlenderObjectCulling; class BlenderViewportParameters; class Camera; class Film; +class Hair; class Light; class Mesh; class Object; @@ -142,10 +143,13 @@ class BlenderSync { void sync_mesh_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step); /* Hair */ - void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh); - void sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step); + void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Geometry *geom); + void sync_hair_motion(BL::Depsgraph b_depsgraph, + BL::Object b_ob, + Geometry *geom, + int motion_step); void sync_particle_hair( - Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); + Geometry *geom, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); void sync_curve_settings(); bool object_has_particle_hair(BL::Object b_ob); @@ -154,11 +158,11 @@ class BlenderSync { BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time); /* Geometry */ - Mesh *sync_geometry(BL::Depsgraph &b_depsgrpah, - BL::Object &b_ob, - BL::Object &b_ob_instance, - bool object_updated, - bool use_particle_hair); + Geometry *sync_geometry(BL::Depsgraph &b_depsgrpah, + BL::Object &b_ob, + BL::Object &b_ob_instance, + bool object_updated, + bool use_particle_hair); void sync_geometry_motion(BL::Depsgraph &b_depsgraph, BL::Object &b_ob, Object *object, @@ -199,11 +203,11 @@ class BlenderSync { id_map shader_map; id_map object_map; - id_map mesh_map; + id_map geometry_map; id_map light_map; id_map particle_system_map; - set mesh_synced; - set mesh_motion_synced; + set geometry_synced; + set geometry_motion_synced; set motion_times; void *world_map; bool world_recalc; diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 16c721da06a..3a8b0fe7fa2 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -17,6 +17,7 @@ #include "bvh/bvh.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/object.h" @@ -99,31 +100,33 @@ int BVHStackEntry::encodeIdx() const /* BVH */ -BVH::BVH(const BVHParams ¶ms_, const vector &meshes_, const vector &objects_) - : params(params_), meshes(meshes_), objects(objects_) +BVH::BVH(const BVHParams ¶ms_, + const vector &geometry_, + const vector &objects_) + : params(params_), geometry(geometry_), objects(objects_) { } BVH *BVH::create(const BVHParams ¶ms, - const vector &meshes, + const vector &geometry, const vector &objects) { switch (params.bvh_layout) { case BVH_LAYOUT_BVH2: - return new BVH2(params, meshes, objects); + return new BVH2(params, geometry, objects); case BVH_LAYOUT_BVH4: - return new BVH4(params, meshes, objects); + return new BVH4(params, geometry, objects); case BVH_LAYOUT_BVH8: - return new BVH8(params, meshes, objects); + return new BVH8(params, geometry, objects); case BVH_LAYOUT_EMBREE: #ifdef WITH_EMBREE - return new BVHEmbree(params, meshes, objects); + return new BVHEmbree(params, geometry, objects); #else break; #endif case BVH_LAYOUT_OPTIX: #ifdef WITH_OPTIX - return new BVHOptiX(params, meshes, objects); + return new BVHOptiX(params, geometry, objects); #else break; #endif @@ -217,36 +220,36 @@ void BVH::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility) } else { /* Primitives. */ - const Mesh *mesh = ob->mesh; - if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) { /* Curves. */ - int str_offset = (params.top_level) ? mesh->curve_offset : 0; - Mesh::Curve curve = mesh->get_curve(pidx - str_offset); + const Hair *hair = static_cast(ob->geometry); + int prim_offset = (params.top_level) ? hair->prim_offset : 0; + Hair::Curve curve = hair->get_curve(pidx - prim_offset); int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]); - curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox); + curve.bounds_grow(k, &hair->curve_keys[0], &hair->curve_radius[0], bbox); visibility |= PATH_RAY_CURVE; /* Motion curves. */ - if (mesh->use_motion_blur) { - Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (hair->use_motion_blur) { + Attribute *attr = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr) { - size_t mesh_size = mesh->curve_keys.size(); - size_t steps = mesh->motion_steps - 1; + size_t hair_size = hair->curve_keys.size(); + size_t steps = hair->motion_steps - 1; float3 *key_steps = attr->data_float3(); for (size_t i = 0; i < steps; i++) - curve.bounds_grow(k, key_steps + i * mesh_size, &mesh->curve_radius[0], bbox); + curve.bounds_grow(k, key_steps + i * hair_size, &hair->curve_radius[0], bbox); } } } else { /* Triangles. */ - int tri_offset = (params.top_level) ? mesh->tri_offset : 0; - Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset); + const Mesh *mesh = static_cast(ob->geometry); + int prim_offset = (params.top_level) ? mesh->prim_offset : 0; + Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset); const float3 *vpos = &mesh->verts[0]; triangle.bounds_grow(vpos, bbox); @@ -276,7 +279,7 @@ void BVH::pack_triangle(int idx, float4 tri_verts[3]) { int tob = pack.prim_object[idx]; assert(tob >= 0 && tob < objects.size()); - const Mesh *mesh = objects[tob]->mesh; + const Mesh *mesh = static_cast(objects[tob]->geometry); int tidx = pack.prim_index[idx]; Mesh::Triangle t = mesh->get_triangle(tidx); @@ -347,15 +350,13 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) const bool use_obvh = (params.bvh_layout == BVH_LAYOUT_BVH8); /* Adjust primitive index to point to the triangle in the global array, for - * meshes with transform applied and already in the top level BVH. + * geometry with transform applied and already in the top level BVH. */ - for (size_t i = 0; i < pack.prim_index.size(); i++) + for (size_t i = 0; i < pack.prim_index.size(); i++) { if (pack.prim_index[i] != -1) { - if (pack.prim_type[i] & PRIMITIVE_ALL_CURVE) - pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset; - else - pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset; + pack.prim_index[i] += objects[pack.prim_object[i]]->geometry->prim_offset; } + } /* track offsets of instanced BVH data in global array */ size_t prim_offset = pack.prim_index.size(); @@ -375,10 +376,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) size_t pack_leaf_nodes_offset = leaf_nodes_size; size_t object_offset = 0; - foreach (Mesh *mesh, meshes) { - BVH *bvh = mesh->bvh; + foreach (Geometry *geom, geometry) { + BVH *bvh = geom->bvh; - if (mesh->need_build_bvh(params.bvh_layout)) { + if (geom->need_build_bvh(params.bvh_layout)) { prim_index_size += bvh->pack.prim_index.size(); prim_tri_verts_size += bvh->pack.prim_tri_verts.size(); nodes_size += bvh->pack.nodes.size(); @@ -410,36 +411,35 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) int4 *pack_leaf_nodes = (pack.leaf_nodes.size()) ? &pack.leaf_nodes[0] : NULL; float2 *pack_prim_time = (pack.prim_time.size()) ? &pack.prim_time[0] : NULL; - map mesh_map; + map geometry_map; /* merge */ foreach (Object *ob, objects) { - Mesh *mesh = ob->mesh; + Geometry *geom = ob->geometry; /* We assume that if mesh doesn't need own BVH it was already included * into a top-level BVH and no packing here is needed. */ - if (!mesh->need_build_bvh(params.bvh_layout)) { + if (!geom->need_build_bvh(params.bvh_layout)) { pack.object_node[object_offset++] = 0; continue; } /* if mesh already added once, don't add it again, but used set * node offset for this object */ - map::iterator it = mesh_map.find(mesh); + map::iterator it = geometry_map.find(geom); - if (mesh_map.find(mesh) != mesh_map.end()) { + if (geometry_map.find(geom) != geometry_map.end()) { int noffset = it->second; pack.object_node[object_offset++] = noffset; continue; } - BVH *bvh = mesh->bvh; + BVH *bvh = geom->bvh; int noffset = nodes_offset; int noffset_leaf = nodes_leaf_offset; - int mesh_tri_offset = mesh->tri_offset; - int mesh_curve_offset = mesh->curve_offset; + int geom_prim_offset = geom->prim_offset; /* fill in node indexes for instances */ if (bvh->pack.root_index == -1) @@ -447,7 +447,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) else pack.object_node[object_offset++] = noffset; - mesh_map[mesh] = pack.object_node[object_offset - 1]; + geometry_map[geom] = pack.object_node[object_offset - 1]; /* merge primitive, object and triangle indexes */ if (bvh->pack.prim_index.size()) { @@ -460,11 +460,11 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) for (size_t i = 0; i < bvh_prim_index_size; i++) { if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) { - pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset; + pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset; pack_prim_tri_index[pack_prim_index_offset] = -1; } else { - pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset; + pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset; pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] + pack_prim_tri_verts_offset; } diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h index 92082e4de86..bdde38640c9 100644 --- a/intern/cycles/bvh/bvh.h +++ b/intern/cycles/bvh/bvh.h @@ -33,7 +33,7 @@ struct BVHStackEntry; class BVHParams; class BoundBox; class LeafNode; -class Mesh; +class Geometry; class Object; class Progress; @@ -84,11 +84,11 @@ class BVH { public: PackedBVH pack; BVHParams params; - vector meshes; + vector geometry; vector objects; static BVH *create(const BVHParams ¶ms, - const vector &meshes, + const vector &geometry, const vector &objects); virtual ~BVH() { @@ -102,7 +102,9 @@ class BVH { void refit(Progress &progress); protected: - BVH(const BVHParams ¶ms, const vector &meshes, const vector &objects); + BVH(const BVHParams ¶ms, + const vector &geometry, + const vector &objects); /* Refit range of primitives. */ void refit_primitives(int start, int end, BoundBox &bbox, uint &visibility); diff --git a/intern/cycles/bvh/bvh2.cpp b/intern/cycles/bvh/bvh2.cpp index b1a9148c297..c903070429e 100644 --- a/intern/cycles/bvh/bvh2.cpp +++ b/intern/cycles/bvh/bvh2.cpp @@ -26,9 +26,9 @@ CCL_NAMESPACE_BEGIN BVH2::BVH2(const BVHParams ¶ms_, - const vector &meshes_, + const vector &geometry_, const vector &objects_) - : BVH(params_, meshes_, objects_) + : BVH(params_, geometry_, objects_) { } diff --git a/intern/cycles/bvh/bvh2.h b/intern/cycles/bvh/bvh2.h index a3eaff9cf65..fa3e45b72d2 100644 --- a/intern/cycles/bvh/bvh2.h +++ b/intern/cycles/bvh/bvh2.h @@ -46,7 +46,9 @@ class BVH2 : public BVH { protected: /* constructor */ friend class BVH; - BVH2(const BVHParams ¶ms, const vector &meshes, const vector &objects); + BVH2(const BVHParams ¶ms, + const vector &geometry, + const vector &objects); /* Building process. */ virtual BVHNode *widen_children_nodes(const BVHNode *root) override; diff --git a/intern/cycles/bvh/bvh4.cpp b/intern/cycles/bvh/bvh4.cpp index 89b42ee1d21..143c3e54f94 100644 --- a/intern/cycles/bvh/bvh4.cpp +++ b/intern/cycles/bvh/bvh4.cpp @@ -32,9 +32,9 @@ CCL_NAMESPACE_BEGIN */ BVH4::BVH4(const BVHParams ¶ms_, - const vector &meshes_, + const vector &geometry_, const vector &objects_) - : BVH(params_, meshes_, objects_) + : BVH(params_, geometry_, objects_) { params.bvh_layout = BVH_LAYOUT_BVH4; } diff --git a/intern/cycles/bvh/bvh4.h b/intern/cycles/bvh/bvh4.h index c44f2833c84..afbb9007afb 100644 --- a/intern/cycles/bvh/bvh4.h +++ b/intern/cycles/bvh/bvh4.h @@ -46,7 +46,9 @@ class BVH4 : public BVH { protected: /* constructor */ friend class BVH; - BVH4(const BVHParams ¶ms, const vector &meshes, const vector &objects); + BVH4(const BVHParams ¶ms, + const vector &geometry, + const vector &objects); /* Building process. */ virtual BVHNode *widen_children_nodes(const BVHNode *root) override; diff --git a/intern/cycles/bvh/bvh8.cpp b/intern/cycles/bvh/bvh8.cpp index d3516525f78..342dd9e85a5 100644 --- a/intern/cycles/bvh/bvh8.cpp +++ b/intern/cycles/bvh/bvh8.cpp @@ -28,6 +28,7 @@ #include "bvh/bvh8.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/object.h" @@ -37,9 +38,9 @@ CCL_NAMESPACE_BEGIN BVH8::BVH8(const BVHParams ¶ms_, - const vector &meshes_, + const vector &geometry_, const vector &objects_) - : BVH(params_, meshes_, objects_) + : BVH(params_, geometry_, objects_) { } @@ -429,37 +430,37 @@ void BVH8::refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility) } else { /* Primitives. */ - const Mesh *mesh = ob->mesh; - if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) { /* Curves. */ - int str_offset = (params.top_level) ? mesh->curve_offset : 0; - Mesh::Curve curve = mesh->get_curve(pidx - str_offset); + const Hair *hair = static_cast(ob->geometry); + int prim_offset = (params.top_level) ? hair->prim_offset : 0; + Hair::Curve curve = hair->get_curve(pidx - prim_offset); int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]); - curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox); + curve.bounds_grow(k, &hair->curve_keys[0], &hair->curve_radius[0], bbox); visibility |= PATH_RAY_CURVE; /* Motion curves. */ - if (mesh->use_motion_blur) { - Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (hair->use_motion_blur) { + Attribute *attr = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr) { - size_t mesh_size = mesh->curve_keys.size(); - size_t steps = mesh->motion_steps - 1; + size_t hair_size = hair->curve_keys.size(); + size_t steps = hair->motion_steps - 1; float3 *key_steps = attr->data_float3(); for (size_t i = 0; i < steps; i++) { - curve.bounds_grow(k, key_steps + i * mesh_size, &mesh->curve_radius[0], bbox); + curve.bounds_grow(k, key_steps + i * hair_size, &hair->curve_radius[0], bbox); } } } } else { /* Triangles. */ - int tri_offset = (params.top_level) ? mesh->tri_offset : 0; - Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset); + const Mesh *mesh = static_cast(ob->geometry); + int prim_offset = (params.top_level) ? mesh->prim_offset : 0; + Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset); const float3 *vpos = &mesh->verts[0]; triangle.bounds_grow(vpos, bbox); diff --git a/intern/cycles/bvh/bvh8.h b/intern/cycles/bvh/bvh8.h index 5f26fd423e1..d23fa528e3e 100644 --- a/intern/cycles/bvh/bvh8.h +++ b/intern/cycles/bvh/bvh8.h @@ -57,7 +57,9 @@ class BVH8 : public BVH { protected: /* constructor */ friend class BVH; - BVH8(const BVHParams ¶ms, const vector &meshes, const vector &objects); + BVH8(const BVHParams ¶ms, + const vector &geometry, + const vector &objects); /* Building process. */ virtual BVHNode *widen_children_nodes(const BVHNode *root) override; diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 1d9b006e8cb..b472c55d156 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -22,6 +22,7 @@ #include "bvh/bvh_params.h" #include "bvh_split.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/object.h" #include "render/scene.h" @@ -194,21 +195,21 @@ void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox ¢er, Mesh *m } } -void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Mesh *mesh, int i) +void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair, int i) { const Attribute *curve_attr_mP = NULL; - if (mesh->has_motion_blur()) { - curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (hair->has_motion_blur()) { + curve_attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); } - const size_t num_curves = mesh->num_curves(); + const size_t num_curves = hair->num_curves(); for (uint j = 0; j < num_curves; j++) { - const Mesh::Curve curve = mesh->get_curve(j); - const float *curve_radius = &mesh->curve_radius[0]; + const Hair::Curve curve = hair->get_curve(j); + const float *curve_radius = &hair->curve_radius[0]; for (int k = 0; k < curve.num_keys - 1; k++) { if (curve_attr_mP == NULL) { /* Really simple logic for static hair. */ BoundBox bounds = BoundBox::empty; - curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds); + curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds); if (bounds.valid()) { int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k); references.push_back(BVHReference(bounds, j, i, packed_type)); @@ -223,9 +224,9 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Mesh *mesh */ /* TODO(sergey): Support motion steps for spatially split BVH. */ BoundBox bounds = BoundBox::empty; - curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds); - const size_t num_keys = mesh->curve_keys.size(); - const size_t num_steps = mesh->motion_steps; + curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds); + const size_t num_keys = hair->curve_keys.size(); + const size_t num_steps = hair->motion_steps; const float3 *key_steps = curve_attr_mP->data_float3(); for (size_t step = 0; step < num_steps - 1; step++) { curve.bounds_grow(k, key_steps + step * num_keys, curve_radius, bounds); @@ -244,10 +245,10 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Mesh *mesh */ 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_steps = mesh->motion_steps; - const float3 *curve_keys = &mesh->curve_keys[0]; + const size_t num_steps = hair->motion_steps; + const float3 *curve_keys = &hair->curve_keys[0]; const float3 *key_steps = curve_attr_mP->data_float3(); - const size_t num_keys = mesh->curve_keys.size(); + const size_t num_keys = hair->curve_keys.size(); /* Calculate bounding box of the previous time step. * Will be reused later to avoid duplicated work on * calculating BVH time step boundbox. @@ -302,13 +303,15 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Mesh *mesh } } -void BVHBuild::add_reference_mesh(BoundBox &root, BoundBox ¢er, Mesh *mesh, int i) +void BVHBuild::add_reference_geometry(BoundBox &root, BoundBox ¢er, Geometry *geom, int i) { - if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); add_reference_triangles(root, center, mesh, i); } - if (params.primitive_mask & PRIMITIVE_ALL_CURVE) { - add_reference_curves(root, center, mesh, i); + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + add_reference_curves(root, center, hair, i); } } @@ -319,16 +322,30 @@ void BVHBuild::add_reference_object(BoundBox &root, BoundBox ¢er, Object *ob center.grow(ob->bounds.center2()); } -static size_t count_curve_segments(Mesh *mesh) +static size_t count_curve_segments(Hair *hair) { - size_t num = 0, num_curves = mesh->num_curves(); + size_t num = 0, num_curves = hair->num_curves(); for (size_t i = 0; i < num_curves; i++) - num += mesh->get_curve(i).num_keys - 1; + num += hair->get_curve(i).num_keys - 1; return num; } +static size_t count_primitives(Geometry *geom) +{ + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + return mesh->num_triangles(); + } + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + return count_curve_segments(hair); + } + + return 0; +} + void BVHBuild::add_references(BVHRange &root) { /* reserve space for references */ @@ -339,24 +356,14 @@ void BVHBuild::add_references(BVHRange &root) if (!ob->is_traceable()) { continue; } - if (!ob->mesh->is_instanced()) { - if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) { - num_alloc_references += ob->mesh->num_triangles(); - } - if (params.primitive_mask & PRIMITIVE_ALL_CURVE) { - num_alloc_references += count_curve_segments(ob->mesh); - } + if (!ob->geometry->is_instanced()) { + num_alloc_references += count_primitives(ob->geometry); } else num_alloc_references++; } else { - if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) { - num_alloc_references += ob->mesh->num_triangles(); - } - if (params.primitive_mask & PRIMITIVE_ALL_CURVE) { - num_alloc_references += count_curve_segments(ob->mesh); - } + num_alloc_references += count_primitives(ob->geometry); } } @@ -372,13 +379,13 @@ void BVHBuild::add_references(BVHRange &root) ++i; continue; } - if (!ob->mesh->is_instanced()) - add_reference_mesh(bounds, center, ob->mesh, i); + if (!ob->geometry->is_instanced()) + add_reference_geometry(bounds, center, ob->geometry, i); else add_reference_object(bounds, center, ob, i); } else - add_reference_mesh(bounds, center, ob->mesh, i); + add_reference_geometry(bounds, center, ob->geometry, i); i++; diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h index 9685e26cfac..3fe4c3799e2 100644 --- a/intern/cycles/bvh/bvh_build.h +++ b/intern/cycles/bvh/bvh_build.h @@ -35,6 +35,8 @@ class BVHNode; class BVHSpatialSplitBuildTask; class BVHParams; class InnerNode; +class Geometry; +class Hair; class Mesh; class Object; class Progress; @@ -65,8 +67,8 @@ class BVHBuild { /* Adding references. */ void add_reference_triangles(BoundBox &root, BoundBox ¢er, Mesh *mesh, int i); - void add_reference_curves(BoundBox &root, BoundBox ¢er, Mesh *mesh, int i); - void add_reference_mesh(BoundBox &root, BoundBox ¢er, Mesh *mesh, int i); + void add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair, int i); + void add_reference_geometry(BoundBox &root, BoundBox ¢er, Geometry *geom, int i); void add_reference_object(BoundBox &root, BoundBox ¢er, Object *ob, int i); void add_references(BVHRange &root); diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp index 3e4978a2c0a..88302f11e7e 100644 --- a/intern/cycles/bvh/bvh_embree.cpp +++ b/intern/cycles/bvh/bvh_embree.cpp @@ -49,6 +49,7 @@ # include "kernel/kernel_globals.h" # include "kernel/kernel_random.h" +# include "render/hair.h" # include "render/mesh.h" # include "render/object.h" # include "util/util_foreach.h" @@ -301,10 +302,24 @@ RTCDevice BVHEmbree::rtc_shared_device = NULL; int BVHEmbree::rtc_shared_users = 0; thread_mutex BVHEmbree::rtc_shared_mutex; +static size_t count_primitives(Geometry *geom) +{ + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + return mesh->num_triangles(); + } + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + return hair->num_segments(); + } + + return 0; +} + BVHEmbree::BVHEmbree(const BVHParams ¶ms_, - const vector &meshes_, + const vector &geometry_, const vector &objects_) - : BVH(params_, meshes_, objects_), + : BVH(params_, geometry_, objects_), scene(NULL), mem_used(0), top_level(NULL), @@ -436,29 +451,15 @@ void BVHEmbree::build(Progress &progress, Stats *stats_) if (!ob->is_traceable()) { continue; } - if (!ob->mesh->is_instanced()) { - if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) { - prim_count += ob->mesh->num_triangles(); - } - if (params.primitive_mask & PRIMITIVE_ALL_CURVE) { - for (size_t j = 0; j < ob->mesh->num_curves(); ++j) { - prim_count += ob->mesh->get_curve(j).num_segments(); - } - } + if (!ob->geometry->is_instanced()) { + prim_count += count_primitives(ob->geometry); } else { ++prim_count; } } else { - if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) { - prim_count += ob->mesh->num_triangles(); - } - if (params.primitive_mask & PRIMITIVE_ALL_CURVE) { - for (size_t j = 0; j < ob->mesh->num_curves(); ++j) { - prim_count += ob->mesh->get_curve(j).num_segments(); - } - } + prim_count += count_primitives(ob->geometry); } } @@ -477,7 +478,7 @@ void BVHEmbree::build(Progress &progress, Stats *stats_) ++i; continue; } - if (!ob->mesh->is_instanced()) { + if (!ob->geometry->is_instanced()) { add_object(ob, i); } else { @@ -528,22 +529,29 @@ BVHNode *BVHEmbree::widen_children_nodes(const BVHNode * /*root*/) void BVHEmbree::add_object(Object *ob, int i) { - Mesh *mesh = ob->mesh; - if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) { - add_triangles(ob, i); + Geometry *geom = ob->geometry; + + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (mesh->num_triangles() > 0) { + add_triangles(ob, mesh, i); + } } - if (params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) { - add_curves(ob, i); + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + if (hair->num_curves() > 0) { + add_curves(ob, hair, i); + } } } void BVHEmbree::add_instance(Object *ob, int i) { - if (!ob || !ob->mesh) { + if (!ob || !ob->geometry) { assert(0); return; } - BVHEmbree *instance_bvh = (BVHEmbree *)(ob->mesh->bvh); + BVHEmbree *instance_bvh = (BVHEmbree *)(ob->geometry->bvh); if (instance_bvh->top_level != this) { instance_bvh->top_level = this; @@ -577,10 +585,9 @@ void BVHEmbree::add_instance(Object *ob, int i) rtcReleaseGeometry(geom_id); } -void BVHEmbree::add_triangles(Object *ob, int i) +void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i) { size_t prim_offset = pack.prim_index.size(); - Mesh *mesh = ob->mesh; const Attribute *attr_mP = NULL; size_t num_motion_steps = 1; if (mesh->has_motion_blur()) { @@ -684,31 +691,31 @@ void BVHEmbree::update_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh) } } -void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh) +void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair) { const Attribute *attr_mP = NULL; size_t num_motion_steps = 1; - if (mesh->has_motion_blur()) { - attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (hair->has_motion_blur()) { + attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_motion_steps = mesh->motion_steps; + num_motion_steps = hair->motion_steps; } } - const size_t num_curves = mesh->num_curves(); + const size_t num_curves = hair->num_curves(); size_t num_keys = 0; for (size_t j = 0; j < num_curves; ++j) { - const Mesh::Curve c = mesh->get_curve(j); + const Hair::Curve c = hair->get_curve(j); num_keys += c.num_keys; } /* Copy the CV data to Embree */ const int t_mid = (num_motion_steps - 1) / 2; - const float *curve_radius = &mesh->curve_radius[0]; + const float *curve_radius = &hair->curve_radius[0]; for (int t = 0; t < num_motion_steps; ++t) { const float3 *verts; if (t == t_mid || attr_mP == NULL) { - verts = &mesh->curve_keys[0]; + verts = &hair->curve_keys[0]; } else { int t_ = (t > t_mid) ? (t - 1) : t; @@ -726,9 +733,9 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh assert(rtc_verts); if (rtc_verts) { if (use_curves && rtc_tangents) { - const size_t num_curves = mesh->num_curves(); + const size_t num_curves = hair->num_curves(); for (size_t j = 0; j < num_curves; ++j) { - Mesh::Curve c = mesh->get_curve(j); + Hair::Curve c = hair->get_curve(j); int fk = c.first_key; rtc_verts[0] = float3_to_float4(verts[fk]); rtc_verts[0].w = curve_radius[fk]; @@ -760,23 +767,22 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh } } -void BVHEmbree::add_curves(Object *ob, int i) +void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i) { size_t prim_offset = pack.prim_index.size(); - const Mesh *mesh = ob->mesh; const Attribute *attr_mP = NULL; size_t num_motion_steps = 1; - if (mesh->has_motion_blur()) { - attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (hair->has_motion_blur()) { + attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_motion_steps = mesh->motion_steps; + num_motion_steps = hair->motion_steps; } } - const size_t num_curves = mesh->num_curves(); + const size_t num_curves = hair->num_curves(); size_t num_segments = 0; for (size_t j = 0; j < num_curves; ++j) { - Mesh::Curve c = mesh->get_curve(j); + Hair::Curve c = hair->get_curve(j); assert(c.num_segments() > 0); num_segments += c.num_segments(); } @@ -802,7 +808,7 @@ void BVHEmbree::add_curves(Object *ob, int i) geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT, sizeof(int), num_segments); size_t rtc_index = 0; for (size_t j = 0; j < num_curves; ++j) { - Mesh::Curve c = mesh->get_curve(j); + Hair::Curve c = hair->get_curve(j); for (size_t k = 0; k < c.num_segments(); ++k) { rtc_indices[rtc_index] = c.first_key + k; /* Cycles specific data. */ @@ -819,7 +825,7 @@ void BVHEmbree::add_curves(Object *ob, int i) rtcSetGeometryBuildQuality(geom_id, build_quality); rtcSetGeometryTimeStepCount(geom_id, num_motion_steps); - update_curve_vertex_buffer(geom_id, mesh); + update_curve_vertex_buffer(geom_id, hair); rtcSetGeometryUserData(geom_id, (void *)prim_offset); rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func); @@ -840,10 +846,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) for (size_t i = 0; i < pack.prim_index.size(); ++i) { if (pack.prim_index[i] != -1) { - if (pack.prim_type[i] & PRIMITIVE_ALL_CURVE) - pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset; - else - pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset; + pack.prim_index[i] += objects[pack.prim_object[i]]->geometry->prim_offset; } } @@ -857,22 +860,22 @@ void BVHEmbree::pack_nodes(const BVHNode *) size_t pack_prim_tri_verts_offset = prim_tri_verts_size; size_t object_offset = 0; - map mesh_map; + map geometry_map; foreach (Object *ob, objects) { - Mesh *mesh = ob->mesh; - BVH *bvh = mesh->bvh; + Geometry *geom = ob->geometry; + BVH *bvh = geom->bvh; - if (mesh->need_build_bvh(BVH_LAYOUT_EMBREE)) { - if (mesh_map.find(mesh) == mesh_map.end()) { + if (geom->need_build_bvh(BVH_LAYOUT_EMBREE)) { + if (geometry_map.find(geom) == geometry_map.end()) { prim_index_size += bvh->pack.prim_index.size(); prim_tri_verts_size += bvh->pack.prim_tri_verts.size(); - mesh_map[mesh] = 1; + geometry_map[geom] = 1; } } } - mesh_map.clear(); + geometry_map.clear(); pack.prim_index.resize(prim_index_size); pack.prim_type.resize(prim_index_size); @@ -890,38 +893,37 @@ void BVHEmbree::pack_nodes(const BVHNode *) /* merge */ foreach (Object *ob, objects) { - Mesh *mesh = ob->mesh; + Geometry *geom = ob->geometry; /* We assume that if mesh doesn't need own BVH it was already included * into a top-level BVH and no packing here is needed. */ - if (!mesh->need_build_bvh(BVH_LAYOUT_EMBREE)) { + if (!geom->need_build_bvh(BVH_LAYOUT_EMBREE)) { pack.object_node[object_offset++] = prim_offset; continue; } - /* if mesh already added once, don't add it again, but used set + /* if geom already added once, don't add it again, but used set * node offset for this object */ - map::iterator it = mesh_map.find(mesh); + map::iterator it = geometry_map.find(geom); - if (mesh_map.find(mesh) != mesh_map.end()) { + if (geometry_map.find(geom) != geometry_map.end()) { int noffset = it->second; pack.object_node[object_offset++] = noffset; continue; } - BVHEmbree *bvh = (BVHEmbree *)mesh->bvh; + BVHEmbree *bvh = (BVHEmbree *)geom->bvh; rtc_memory_monitor_func(stats, unaccounted_mem, true); unaccounted_mem = 0; - int mesh_tri_offset = mesh->tri_offset; - int mesh_curve_offset = mesh->curve_offset; + int prim_offset = geom->prim_offset; /* fill in node indexes for instances */ pack.object_node[object_offset++] = prim_offset; - mesh_map[mesh] = pack.object_node[object_offset - 1]; + geometry_map[geom] = pack.object_node[object_offset - 1]; /* merge primitive, object and triangle indexes */ if (bvh->pack.prim_index.size()) { @@ -932,11 +934,11 @@ void BVHEmbree::pack_nodes(const BVHNode *) for (size_t i = 0; i < bvh_prim_index_size; ++i) { if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) { - pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset; + pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + prim_offset; pack_prim_tri_index[pack_prim_index_offset] = -1; } else { - pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset; + pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + prim_offset; pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] + pack_prim_tri_verts_offset; } @@ -966,15 +968,22 @@ void BVHEmbree::refit_nodes() /* Update all vertex buffers, then tell Embree to rebuild/-fit the BVHs. */ unsigned geom_id = 0; foreach (Object *ob, objects) { - if (!params.top_level || (ob->is_traceable() && !ob->mesh->is_instanced())) { - if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) { - update_tri_vertex_buffer(rtcGetGeometry(scene, geom_id), ob->mesh); - rtcCommitGeometry(rtcGetGeometry(scene, geom_id)); + if (!params.top_level || (ob->is_traceable() && !ob->geometry->is_instanced())) { + Geometry *geom = ob->geometry; + + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (mesh->num_triangles() > 0) { + update_tri_vertex_buffer(rtcGetGeometry(scene, geom_id), mesh); + rtcCommitGeometry(rtcGetGeometry(scene, geom_id)); + } } - - if (params.primitive_mask & PRIMITIVE_ALL_CURVE && ob->mesh->num_curves() > 0) { - update_curve_vertex_buffer(rtcGetGeometry(scene, geom_id + 1), ob->mesh); - rtcCommitGeometry(rtcGetGeometry(scene, geom_id + 1)); + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + if (hair->num_curves() > 0) { + update_curve_vertex_buffer(rtcGetGeometry(scene, geom_id + 1), hair); + rtcCommitGeometry(rtcGetGeometry(scene, geom_id + 1)); + } } } geom_id += 2; diff --git a/intern/cycles/bvh/bvh_embree.h b/intern/cycles/bvh/bvh_embree.h index 123e87dd9b0..eb121d060b7 100644 --- a/intern/cycles/bvh/bvh_embree.h +++ b/intern/cycles/bvh/bvh_embree.h @@ -31,6 +31,8 @@ CCL_NAMESPACE_BEGIN +class Geometry; +class Hair; class Mesh; class BVHEmbree : public BVH { @@ -47,7 +49,7 @@ class BVHEmbree : public BVH { protected: friend class BVH; BVHEmbree(const BVHParams ¶ms, - const vector &meshes, + const vector &geometry, const vector &objects); virtual void pack_nodes(const BVHNode *) override; @@ -55,8 +57,8 @@ class BVHEmbree : public BVH { void add_object(Object *ob, int i); void add_instance(Object *ob, int i); - void add_curves(Object *ob, int i); - void add_triangles(Object *ob, int i); + void add_curves(const Object *ob, const Hair *hair, int i); + void add_triangles(const Object *ob, const Mesh *mesh, int i); ssize_t mem_used; @@ -69,7 +71,7 @@ class BVHEmbree : public BVH { private: void delete_rtcScene(); void update_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh); - void update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh); + void update_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair); static RTCDevice rtc_shared_device; static int rtc_shared_users; diff --git a/intern/cycles/bvh/bvh_optix.cpp b/intern/cycles/bvh/bvh_optix.cpp index 86d755ab06a..a3b6261dcad 100644 --- a/intern/cycles/bvh/bvh_optix.cpp +++ b/intern/cycles/bvh/bvh_optix.cpp @@ -18,6 +18,8 @@ #ifdef WITH_OPTIX # include "bvh/bvh_optix.h" +# include "render/hair.h" +# include "render/geometry.h" # include "render/mesh.h" # include "render/object.h" # include "util/util_logging.h" @@ -26,9 +28,9 @@ CCL_NAMESPACE_BEGIN BVHOptiX::BVHOptiX(const BVHParams ¶ms_, - const vector &meshes_, + const vector &geometry_, const vector &objects_) - : BVH(params_, meshes_, objects_) + : BVH(params_, geometry_, objects_) { } @@ -56,47 +58,52 @@ void BVHOptiX::copy_to_device(Progress &progress, DeviceScene *dscene) void BVHOptiX::pack_blas() { // Bottom-level BVH can contain multiple primitive types, so merge them: - assert(meshes.size() == 1 && objects.size() == 1); // These are build per-mesh - Mesh *const mesh = meshes[0]; - - if (params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) { - const size_t num_curves = mesh->num_curves(); - const size_t num_segments = mesh->num_segments(); - pack.prim_type.reserve(pack.prim_type.size() + num_segments); - pack.prim_index.reserve(pack.prim_index.size() + num_segments); - pack.prim_object.reserve(pack.prim_object.size() + num_segments); - // 'pack.prim_time' is only used in geom_curve_intersect.h - // It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH - - uint type = PRIMITIVE_CURVE; - if (mesh->use_motion_blur && mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) - type = PRIMITIVE_MOTION_CURVE; - - for (size_t j = 0; j < num_curves; ++j) { - const Mesh::Curve curve = mesh->get_curve(j); - for (size_t k = 0; k < curve.num_segments(); ++k) { - pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k)); - // Each curve segment points back to its curve index - pack.prim_index.push_back_reserved(j); - pack.prim_object.push_back_reserved(0); + assert(geometry.size() == 1 && objects.size() == 1); // These are built per-mesh + Geometry *const geom = geometry[0]; + + if (geom->type == Geometry::HAIR) { + Hair *const hair = static_cast(geom); + if (hair->num_curves() > 0) { + const size_t num_curves = hair->num_curves(); + const size_t num_segments = hair->num_segments(); + pack.prim_type.reserve(pack.prim_type.size() + num_segments); + pack.prim_index.reserve(pack.prim_index.size() + num_segments); + pack.prim_object.reserve(pack.prim_object.size() + num_segments); + // 'pack.prim_time' is only used in geom_curve_intersect.h + // It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH + + uint type = PRIMITIVE_CURVE; + if (hair->use_motion_blur && hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) + type = PRIMITIVE_MOTION_CURVE; + + for (size_t j = 0; j < num_curves; ++j) { + const Hair::Curve curve = hair->get_curve(j); + for (size_t k = 0; k < curve.num_segments(); ++k) { + pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k)); + // Each curve segment points back to its curve index + pack.prim_index.push_back_reserved(j); + pack.prim_object.push_back_reserved(0); + } } } } - - if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) { - const size_t num_triangles = mesh->num_triangles(); - pack.prim_type.reserve(pack.prim_type.size() + num_triangles); - pack.prim_index.reserve(pack.prim_index.size() + num_triangles); - pack.prim_object.reserve(pack.prim_object.size() + num_triangles); - - uint type = PRIMITIVE_TRIANGLE; - if (mesh->use_motion_blur && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) - type = PRIMITIVE_MOTION_TRIANGLE; - - for (size_t k = 0; k < num_triangles; ++k) { - pack.prim_type.push_back_reserved(type); - pack.prim_index.push_back_reserved(k); - pack.prim_object.push_back_reserved(0); + else if (geom->type == Geometry::MESH) { + Mesh *const mesh = static_cast(geom); + if (mesh->num_triangles() > 0) { + const size_t num_triangles = mesh->num_triangles(); + pack.prim_type.reserve(pack.prim_type.size() + num_triangles); + pack.prim_index.reserve(pack.prim_index.size() + num_triangles); + pack.prim_object.reserve(pack.prim_object.size() + num_triangles); + + uint type = PRIMITIVE_TRIANGLE; + if (mesh->use_motion_blur && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) + type = PRIMITIVE_MOTION_TRIANGLE; + + for (size_t k = 0; k < num_triangles; ++k) { + pack.prim_type.push_back_reserved(type); + pack.prim_index.push_back_reserved(k); + pack.prim_object.push_back_reserved(0); + } } } @@ -116,8 +123,8 @@ void BVHOptiX::pack_tlas() // Calculate total packed size size_t prim_index_size = 0; size_t prim_tri_verts_size = 0; - foreach (Mesh *mesh, meshes) { - BVH *const bvh = mesh->bvh; + foreach (Geometry *geom, geometry) { + BVH *const bvh = geom->bvh; prim_index_size += bvh->pack.prim_index.size(); prim_tri_verts_size += bvh->pack.prim_tri_verts.size(); } @@ -141,13 +148,12 @@ void BVHOptiX::pack_tlas() pack.prim_tri_verts.resize(prim_tri_verts_size); float4 *pack_prim_tri_verts = pack.prim_tri_verts.data(); - // Top-level BVH should only contain instances, see 'Mesh::need_build_bvh' + // Top-level BVH should only contain instances, see 'Geometry::need_build_bvh' // Iterate over scene mesh list instead of objects, since the 'prim_offset' is calculated based // on that list, which may be ordered differently from the object list. - foreach (Mesh *mesh, meshes) { - PackedBVH &bvh_pack = mesh->bvh->pack; - int mesh_tri_offset = mesh->tri_offset; - int mesh_curve_offset = mesh->curve_offset; + foreach (Geometry *geom, geometry) { + PackedBVH &bvh_pack = geom->bvh->pack; + int geom_prim_offset = geom->prim_offset; // Merge primitive, object and triangle indexes if (!bvh_pack.prim_index.empty()) { @@ -158,16 +164,16 @@ void BVHOptiX::pack_tlas() for (size_t i = 0; i < bvh_pack.prim_index.size(); i++, pack_offset++) { if (bvh_pack.prim_type[i] & PRIMITIVE_ALL_CURVE) { - pack_prim_index[pack_offset] = bvh_prim_index[i] + mesh_curve_offset; + pack_prim_index[pack_offset] = bvh_prim_index[i] + geom_prim_offset; pack_prim_tri_index[pack_offset] = -1; } else { - pack_prim_index[pack_offset] = bvh_prim_index[i] + mesh_tri_offset; + pack_prim_index[pack_offset] = bvh_prim_index[i] + geom_prim_offset; pack_prim_tri_index[pack_offset] = bvh_prim_tri_index[i] + pack_verts_offset; } pack_prim_type[pack_offset] = bvh_prim_type[i]; - pack_prim_object[pack_offset] = 0; // Unused for instanced meshes + pack_prim_object[pack_offset] = 0; // Unused for instanced geometry pack_prim_visibility[pack_offset] = bvh_prim_visibility[i]; } } @@ -182,15 +188,24 @@ void BVHOptiX::pack_tlas() } } - // Merge visibility flags of all objects and fix object indices for non-instanced meshes + // Merge visibility flags of all objects and fix object indices for non-instanced geometry foreach (Object *ob, objects) { - Mesh *const mesh = ob->mesh; - for (size_t i = 0; i < mesh->num_primitives(); ++i) { - if (!ob->mesh->is_instanced()) { - assert(pack.prim_object[mesh->prim_offset + i] == 0); - pack.prim_object[mesh->prim_offset + i] = ob->get_device_index(); + Geometry *const geom = ob->geometry; + size_t num_primitives = 0; + + if (geom->type == Geometry::MESH) { + num_primitives = static_cast(geom)->num_triangles(); + } + else if (geom->type == Geometry::HAIR) { + num_primitives = static_cast(geom)->num_segments(); + } + + for (size_t i = 0; i < num_primitives; ++i) { + if (!geom->is_instanced()) { + assert(pack.prim_object[geom->optix_prim_offset + i] == 0); + pack.prim_object[geom->optix_prim_offset + i] = ob->get_device_index(); } - pack.prim_visibility[mesh->prim_offset + i] |= ob->visibility_for_tracing(); + pack.prim_visibility[geom->optix_prim_offset + i] |= ob->visibility_for_tracing(); } } } diff --git a/intern/cycles/bvh/bvh_optix.h b/intern/cycles/bvh/bvh_optix.h index 35033fe635f..e4745b093b5 100644 --- a/intern/cycles/bvh/bvh_optix.h +++ b/intern/cycles/bvh/bvh_optix.h @@ -26,11 +26,16 @@ CCL_NAMESPACE_BEGIN +class Geometry; +class Optix; + class BVHOptiX : public BVH { friend class BVH; public: - BVHOptiX(const BVHParams ¶ms, const vector &meshes, const vector &objects); + BVHOptiX(const BVHParams ¶ms, + const vector &geometry, + const vector &objects); virtual ~BVHOptiX(); virtual void build(Progress &progress, Stats *) override; diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h index 2731662a39d..5e2c4b63f1b 100644 --- a/intern/cycles/bvh/bvh_params.h +++ b/intern/cycles/bvh/bvh_params.h @@ -69,9 +69,6 @@ class BVHParams { /* BVH layout to be built. */ BVHLayout bvh_layout; - /* Mask of primitives to be included into the BVH. */ - int primitive_mask; - /* Use unaligned bounding boxes. * Only used for curves BVH. */ @@ -120,8 +117,6 @@ class BVHParams { bvh_layout = BVH_LAYOUT_BVH2; use_unaligned_nodes = false; - primitive_mask = PRIMITIVE_ALL; - num_motion_curve_steps = 0; num_motion_triangle_steps = 0; diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index bd261c10d55..7e787674b74 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -20,6 +20,7 @@ #include "bvh/bvh_build.h" #include "bvh/bvh_sort.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/object.h" @@ -378,7 +379,7 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, } } -void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, +void BVHSpatialSplit::split_curve_primitive(const Hair *hair, const Transform *tfm, int prim_index, int segment_index, @@ -388,11 +389,11 @@ void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, BoundBox &right_bounds) { /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ - Mesh::Curve curve = mesh->get_curve(prim_index); + Hair::Curve curve = hair->get_curve(prim_index); const int k0 = curve.first_key + segment_index; const int k1 = k0 + 1; - float3 v0 = mesh->curve_keys[k0]; - float3 v1 = mesh->curve_keys[k1]; + float3 v0 = hair->curve_keys[k0]; + float3 v1 = hair->curve_keys[k1]; if (tfm != NULL) { v0 = transform_point(tfm, v0); @@ -436,13 +437,13 @@ void BVHSpatialSplit::split_triangle_reference(const BVHReference &ref, } void BVHSpatialSplit::split_curve_reference(const BVHReference &ref, - const Mesh *mesh, + const Hair *hair, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds) { - split_curve_primitive(mesh, + split_curve_primitive(hair, NULL, ref.prim_index(), PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()), @@ -455,15 +456,22 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference &ref, void BVHSpatialSplit::split_object_reference( const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds) { - Mesh *mesh = object->mesh; - for (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) { - split_triangle_primitive(mesh, &object->tfm, tri_idx, dim, pos, left_bounds, right_bounds); + Geometry *geom = object->geometry; + + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + for (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) { + split_triangle_primitive(mesh, &object->tfm, tri_idx, dim, pos, left_bounds, right_bounds); + } } - for (int curve_idx = 0; curve_idx < mesh->num_curves(); ++curve_idx) { - Mesh::Curve curve = mesh->get_curve(curve_idx); - for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) { - split_curve_primitive( - mesh, &object->tfm, curve_idx, segment_idx, dim, pos, left_bounds, right_bounds); + else if (geom->type == Geometry::MESH) { + Hair *hair = static_cast(geom); + for (int curve_idx = 0; curve_idx < hair->num_curves(); ++curve_idx) { + Hair::Curve curve = hair->get_curve(curve_idx); + for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) { + split_curve_primitive( + hair, &object->tfm, curve_idx, segment_idx, dim, pos, left_bounds, right_bounds); + } } } } @@ -481,13 +489,14 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder, /* loop over vertices/edges. */ const Object *ob = builder.objects[ref.prim_object()]; - const Mesh *mesh = ob->mesh; if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { + Mesh *mesh = static_cast(ob->geometry); split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds); } else if (ref.prim_type() & PRIMITIVE_ALL_CURVE) { - split_curve_reference(ref, mesh, dim, pos, left_bounds, right_bounds); + Hair *hair = static_cast(ob->geometry); + split_curve_reference(ref, hair, dim, pos, left_bounds, right_bounds); } else { split_object_reference(ob, dim, pos, left_bounds, right_bounds); diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h index eddd1c27f49..5f2e41cf343 100644 --- a/intern/cycles/bvh/bvh_split.h +++ b/intern/cycles/bvh/bvh_split.h @@ -24,6 +24,8 @@ CCL_NAMESPACE_BEGIN class BVHBuild; +class Hair; +class Mesh; struct Transform; /* Object Split */ @@ -113,7 +115,7 @@ class BVHSpatialSplit { float pos, BoundBox &left_bounds, BoundBox &right_bounds); - void split_curve_primitive(const Mesh *mesh, + void split_curve_primitive(const Hair *hair, const Transform *tfm, int prim_index, int segment_index, @@ -134,7 +136,7 @@ class BVHSpatialSplit { BoundBox &left_bounds, BoundBox &right_bounds); void split_curve_reference(const BVHReference &ref, - const Mesh *mesh, + const Hair *hair, int dim, float pos, BoundBox &left_bounds, diff --git a/intern/cycles/bvh/bvh_unaligned.cpp b/intern/cycles/bvh/bvh_unaligned.cpp index 1843ca403a5..f0995f343fe 100644 --- a/intern/cycles/bvh/bvh_unaligned.cpp +++ b/intern/cycles/bvh/bvh_unaligned.cpp @@ -16,7 +16,7 @@ #include "bvh/bvh_unaligned.h" -#include "render/mesh.h" +#include "render/hair.h" #include "render/object.h" #include "bvh/bvh_binning.h" @@ -71,10 +71,10 @@ bool BVHUnaligned::compute_aligned_space(const BVHReference &ref, Transform *ali if (type & PRIMITIVE_CURVE) { const int curve_index = ref.prim_index(); const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type); - const Mesh *mesh = object->mesh; - const Mesh::Curve &curve = mesh->get_curve(curve_index); + const Hair *hair = static_cast(object->geometry); + const Hair::Curve &curve = hair->get_curve(curve_index); const int key = curve.first_key + segment; - const float3 v1 = mesh->curve_keys[key], v2 = mesh->curve_keys[key + 1]; + const float3 v1 = hair->curve_keys[key], v2 = hair->curve_keys[key + 1]; float length; const float3 axis = normalize_len(v2 - v1, &length); if (length > 1e-6f) { @@ -96,10 +96,10 @@ BoundBox BVHUnaligned::compute_aligned_prim_boundbox(const BVHReference &prim, if (type & PRIMITIVE_CURVE) { const int curve_index = prim.prim_index(); const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type); - const Mesh *mesh = object->mesh; - const Mesh::Curve &curve = mesh->get_curve(curve_index); + const Hair *hair = static_cast(object->geometry); + const Hair::Curve &curve = hair->get_curve(curve_index); curve.bounds_grow( - segment, &mesh->curve_keys[0], &mesh->curve_radius[0], aligned_space, bounds); + segment, &hair->curve_keys[0], &hair->curve_radius[0], aligned_space, bounds); } else { bounds = prim.bounds().transformed(&aligned_space); diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp index f479cbd7414..98469fb37b0 100644 --- a/intern/cycles/device/device_optix.cpp +++ b/intern/cycles/device/device_optix.cpp @@ -22,6 +22,7 @@ # include "device/device_denoising.h" # include "bvh/bvh.h" # include "render/scene.h" +# include "render/hair.h" # include "render/mesh.h" # include "render/object.h" # include "render/buffers.h" @@ -1229,8 +1230,8 @@ class OptiXDevice : public Device { assert(bvh->params.top_level); unsigned int num_instances = 0; - unordered_map> meshes; - meshes.reserve(bvh->meshes.size()); + unordered_map geometry; + geometry.reserve(bvh->geometry.size()); // Free all previous acceleration structures for (CUdeviceptr mem : as_mem) { @@ -1241,23 +1242,25 @@ class OptiXDevice : public Device { // Build bottom level acceleration structures (BLAS) // Note: Always keep this logic in sync with bvh_optix.cpp! for (Object *ob : bvh->objects) { - // Skip meshes for which acceleration structure already exists - if (meshes.find(ob->mesh) != meshes.end()) + // Skip geometry for which acceleration structure already exists + Geometry *geom = ob->geometry; + if (geometry.find(geom) != geometry.end()) continue; - Mesh *const mesh = ob->mesh; - vector handles; - handles.reserve(2); + if (geom->type == Geometry::HAIR) { + // Build BLAS for curve primitives + Hair *const hair = static_cast(ob->geometry); + if (hair->num_curves() == 0) { + continue; + } - // Build BLAS for curve primitives - if (bvh->params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) { - const size_t num_curves = mesh->num_curves(); - const size_t num_segments = mesh->num_segments(); + const size_t num_curves = hair->num_curves(); + const size_t num_segments = hair->num_segments(); size_t num_motion_steps = 1; - Attribute *motion_keys = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if (motion_blur && mesh->use_motion_blur && motion_keys) { - num_motion_steps = mesh->motion_steps; + Attribute *motion_keys = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (motion_blur && hair->use_motion_blur && motion_keys) { + num_motion_steps = hair->motion_steps; } device_vector aabb_data(this, "temp_aabb_data", MEM_READ_ONLY); @@ -1266,21 +1269,21 @@ class OptiXDevice : public Device { // Get AABBs for each motion step for (size_t step = 0; step < num_motion_steps; ++step) { // The center step for motion vertices is not stored in the attribute - const float3 *keys = mesh->curve_keys.data(); + const float3 *keys = hair->curve_keys.data(); size_t center_step = (num_motion_steps - 1) / 2; if (step != center_step) { size_t attr_offset = (step > center_step) ? step - 1 : step; // Technically this is a float4 array, but sizeof(float3) is the same as sizeof(float4) - keys = motion_keys->data_float3() + attr_offset * mesh->curve_keys.size(); + keys = motion_keys->data_float3() + attr_offset * hair->curve_keys.size(); } size_t i = step * num_segments; for (size_t j = 0; j < num_curves; ++j) { - const Mesh::Curve c = mesh->get_curve(j); + const Hair::Curve c = hair->get_curve(j); for (size_t k = 0; k < c.num_segments(); ++i, ++k) { BoundBox bounds = BoundBox::empty; - c.bounds_grow(k, keys, mesh->curve_radius.data(), bounds); + c.bounds_grow(k, keys, hair->curve_radius.data(), bounds); aabb_data[i].minX = bounds.min.x; aabb_data[i].minY = bounds.min.y; @@ -1311,16 +1314,24 @@ class OptiXDevice : public Device { build_input.aabbArray.strideInBytes = sizeof(OptixAabb); build_input.aabbArray.flags = &build_flags; build_input.aabbArray.numSbtRecords = 1; - build_input.aabbArray.primitiveIndexOffset = mesh->prim_offset; + build_input.aabbArray.primitiveIndexOffset = hair->optix_prim_offset; // Allocate memory for new BLAS and build it - handles.emplace_back(); - if (!build_optix_bvh(build_input, num_motion_steps, handles.back())) + OptixTraversableHandle handle; + if (build_optix_bvh(build_input, num_motion_steps, handle)) { + geometry.insert({ob->geometry, handle}); + } + else { return false; + } } + else if (geom->type == Geometry::MESH) { + // Build BLAS for triangle primitives + Mesh *const mesh = static_cast(ob->geometry); + if (mesh->num_triangles() == 0) { + continue; + } - // Build BLAS for triangle primitives - if (bvh->params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) { const size_t num_verts = mesh->verts.size(); size_t num_motion_steps = 1; @@ -1375,23 +1386,24 @@ class OptiXDevice : public Device { // buffers for that purpose. OptiX does not allow this to be zero though, so just pass in // one and rely on that having the same meaning in this case. build_input.triangleArray.numSbtRecords = 1; - // Triangle primitives are packed right after the curve primitives of this mesh - build_input.triangleArray.primitiveIndexOffset = mesh->prim_offset + mesh->num_segments(); + build_input.triangleArray.primitiveIndexOffset = mesh->optix_prim_offset; // Allocate memory for new BLAS and build it - handles.emplace_back(); - if (!build_optix_bvh(build_input, num_motion_steps, handles.back())) + OptixTraversableHandle handle; + if (build_optix_bvh(build_input, num_motion_steps, handle)) { + geometry.insert({ob->geometry, handle}); + } + else { return false; + } } - - meshes.insert({mesh, handles}); } // Fill instance descriptions device_vector aabbs(this, "tlas_aabbs", MEM_READ_ONLY); - aabbs.alloc(bvh->objects.size() * 2); + aabbs.alloc(bvh->objects.size()); device_vector instances(this, "tlas_instances", MEM_READ_ONLY); - instances.alloc(bvh->objects.size() * 2); + instances.alloc(bvh->objects.size()); for (Object *ob : bvh->objects) { // Skip non-traceable objects @@ -1399,113 +1411,117 @@ class OptiXDevice : public Device { continue; // Create separate instance for triangle/curve meshes of an object - for (OptixTraversableHandle handle : meshes[ob->mesh]) { - OptixAabb &aabb = aabbs[num_instances]; - aabb.minX = ob->bounds.min.x; - aabb.minY = ob->bounds.min.y; - aabb.minZ = ob->bounds.min.z; - aabb.maxX = ob->bounds.max.x; - aabb.maxY = ob->bounds.max.y; - aabb.maxZ = ob->bounds.max.z; - - OptixInstance &instance = instances[num_instances++]; - memset(&instance, 0, sizeof(instance)); - - // Clear transform to identity matrix - instance.transform[0] = 1.0f; - instance.transform[5] = 1.0f; - instance.transform[10] = 1.0f; - - // Set user instance ID to object index - instance.instanceId = ob->get_device_index(); - - // Volumes have a special bit set in the visibility mask so a trace can mask only volumes - // See 'scene_intersect_volume' in bvh.h - instance.visibilityMask = (ob->mesh->has_volume ? 3 : 1); - - // Insert motion traversable if object has motion - if (motion_blur && ob->use_motion()) { - size_t motion_keys = max(ob->motion.size(), 2) - 2; - size_t motion_transform_size = sizeof(OptixSRTMotionTransform) + - motion_keys * sizeof(OptixSRTData); - - const CUDAContextScope scope(cuda_context); - - CUdeviceptr motion_transform_gpu = 0; - check_result_cuda_ret(cuMemAlloc(&motion_transform_gpu, motion_transform_size)); - as_mem.push_back(motion_transform_gpu); - - // Allocate host side memory for motion transform and fill it with transform data - OptixSRTMotionTransform &motion_transform = *reinterpret_cast( - new uint8_t[motion_transform_size]); - motion_transform.child = handle; - motion_transform.motionOptions.numKeys = ob->motion.size(); - motion_transform.motionOptions.flags = OPTIX_MOTION_FLAG_NONE; - motion_transform.motionOptions.timeBegin = 0.0f; - motion_transform.motionOptions.timeEnd = 1.0f; - - OptixSRTData *const srt_data = motion_transform.srtData; - array decomp(ob->motion.size()); - transform_motion_decompose(decomp.data(), ob->motion.data(), ob->motion.size()); - - for (size_t i = 0; i < ob->motion.size(); ++i) { - // Scale - srt_data[i].sx = decomp[i].y.w; // scale.x.x - srt_data[i].sy = decomp[i].z.w; // scale.y.y - srt_data[i].sz = decomp[i].w.w; // scale.z.z - - // Shear - srt_data[i].a = decomp[i].z.x; // scale.x.y - srt_data[i].b = decomp[i].z.y; // scale.x.z - srt_data[i].c = decomp[i].w.x; // scale.y.z - assert(decomp[i].z.z == 0.0f); // scale.y.x - assert(decomp[i].w.y == 0.0f); // scale.z.x - assert(decomp[i].w.z == 0.0f); // scale.z.y - - // Pivot point - srt_data[i].pvx = 0.0f; - srt_data[i].pvy = 0.0f; - srt_data[i].pvz = 0.0f; - - // Rotation - srt_data[i].qx = decomp[i].x.x; - srt_data[i].qy = decomp[i].x.y; - srt_data[i].qz = decomp[i].x.z; - srt_data[i].qw = decomp[i].x.w; - - // Translation - srt_data[i].tx = decomp[i].y.x; - srt_data[i].ty = decomp[i].y.y; - srt_data[i].tz = decomp[i].y.z; - } + auto handle_it = geometry.find(ob->geometry); + if (handle_it == geometry.end()) { + continue; + } + OptixTraversableHandle handle = handle_it->second; - // Upload motion transform to GPU - cuMemcpyHtoD(motion_transform_gpu, &motion_transform, motion_transform_size); - delete[] reinterpret_cast(&motion_transform); + OptixAabb &aabb = aabbs[num_instances]; + aabb.minX = ob->bounds.min.x; + aabb.minY = ob->bounds.min.y; + aabb.minZ = ob->bounds.min.z; + aabb.maxX = ob->bounds.max.x; + aabb.maxY = ob->bounds.max.y; + aabb.maxZ = ob->bounds.max.z; - // Disable instance transform if object uses motion transform already - instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; + OptixInstance &instance = instances[num_instances++]; + memset(&instance, 0, sizeof(instance)); - // Get traversable handle to motion transform - optixConvertPointerToTraversableHandle(context, - motion_transform_gpu, - OPTIX_TRAVERSABLE_TYPE_SRT_MOTION_TRANSFORM, - &instance.traversableHandle); + // Clear transform to identity matrix + instance.transform[0] = 1.0f; + instance.transform[5] = 1.0f; + instance.transform[10] = 1.0f; + + // Set user instance ID to object index + instance.instanceId = ob->get_device_index(); + + // Volumes have a special bit set in the visibility mask so a trace can mask only volumes + // See 'scene_intersect_volume' in bvh.h + instance.visibilityMask = (ob->geometry->has_volume ? 3 : 1); + + // Insert motion traversable if object has motion + if (motion_blur && ob->use_motion()) { + size_t motion_keys = max(ob->motion.size(), 2) - 2; + size_t motion_transform_size = sizeof(OptixSRTMotionTransform) + + motion_keys * sizeof(OptixSRTData); + + const CUDAContextScope scope(cuda_context); + + CUdeviceptr motion_transform_gpu = 0; + check_result_cuda_ret(cuMemAlloc(&motion_transform_gpu, motion_transform_size)); + as_mem.push_back(motion_transform_gpu); + + // Allocate host side memory for motion transform and fill it with transform data + OptixSRTMotionTransform &motion_transform = *reinterpret_cast( + new uint8_t[motion_transform_size]); + motion_transform.child = handle; + motion_transform.motionOptions.numKeys = ob->motion.size(); + motion_transform.motionOptions.flags = OPTIX_MOTION_FLAG_NONE; + motion_transform.motionOptions.timeBegin = 0.0f; + motion_transform.motionOptions.timeEnd = 1.0f; + + OptixSRTData *const srt_data = motion_transform.srtData; + array decomp(ob->motion.size()); + transform_motion_decompose(decomp.data(), ob->motion.data(), ob->motion.size()); + + for (size_t i = 0; i < ob->motion.size(); ++i) { + // Scale + srt_data[i].sx = decomp[i].y.w; // scale.x.x + srt_data[i].sy = decomp[i].z.w; // scale.y.y + srt_data[i].sz = decomp[i].w.w; // scale.z.z + + // Shear + srt_data[i].a = decomp[i].z.x; // scale.x.y + srt_data[i].b = decomp[i].z.y; // scale.x.z + srt_data[i].c = decomp[i].w.x; // scale.y.z + assert(decomp[i].z.z == 0.0f); // scale.y.x + assert(decomp[i].w.y == 0.0f); // scale.z.x + assert(decomp[i].w.z == 0.0f); // scale.z.y + + // Pivot point + srt_data[i].pvx = 0.0f; + srt_data[i].pvy = 0.0f; + srt_data[i].pvz = 0.0f; + + // Rotation + srt_data[i].qx = decomp[i].x.x; + srt_data[i].qy = decomp[i].x.y; + srt_data[i].qz = decomp[i].x.z; + srt_data[i].qw = decomp[i].x.w; + + // Translation + srt_data[i].tx = decomp[i].y.x; + srt_data[i].ty = decomp[i].y.y; + srt_data[i].tz = decomp[i].y.z; } - else { - instance.traversableHandle = handle; - if (ob->mesh->is_instanced()) { - // Set transform matrix - memcpy(instance.transform, &ob->tfm, sizeof(instance.transform)); - } - else { - // Disable instance transform if mesh already has it applied to vertex data - instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; - // Non-instanced objects read ID from prim_object, so - // distinguish them from instanced objects with high bit set - instance.instanceId |= 0x800000; - } + // Upload motion transform to GPU + cuMemcpyHtoD(motion_transform_gpu, &motion_transform, motion_transform_size); + delete[] reinterpret_cast(&motion_transform); + + // Disable instance transform if object uses motion transform already + instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; + + // Get traversable handle to motion transform + optixConvertPointerToTraversableHandle(context, + motion_transform_gpu, + OPTIX_TRAVERSABLE_TYPE_SRT_MOTION_TRANSFORM, + &instance.traversableHandle); + } + else { + instance.traversableHandle = handle; + + if (ob->geometry->is_instanced()) { + // Set transform matrix + memcpy(instance.transform, &ob->tfm, sizeof(instance.transform)); + } + else { + // Disable instance transform if geometry already has it applied to vertex data + instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM; + // Non-instanced objects read ID from prim_object, so + // distinguish them from instanced objects with high bit set + instance.instanceId |= 0x800000; } } } @@ -2603,8 +2619,8 @@ bool device_optix_init() # ifdef WITH_CUDA_DYNLOAD // Load NVRTC function pointers for adaptive kernel compilation if (DebugFlags().cuda.adaptive_compile && cuewInit(CUEW_INIT_NVRTC) != CUEW_SUCCESS) { - VLOG(1) - << "CUEW initialization failed for NVRTC. Adaptive kernel compilation won't be available."; + VLOG(1) << "CUEW initialization failed for NVRTC. Adaptive kernel compilation won't be " + "available."; } # endif diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h index a4461ec7abb..a79d44b82f3 100644 --- a/intern/cycles/graph/node_type.h +++ b/intern/cycles/graph/node_type.h @@ -153,12 +153,12 @@ struct NodeType { template const NodeType *structname::register_type() #define NODE_ABSTRACT_DECLARE \ - template static const NodeType *register_type(); \ - static const NodeType *node_type; + template static const NodeType *register_base_type(); \ + static const NodeType *node_base_type; #define NODE_ABSTRACT_DEFINE(structname) \ - const NodeType *structname::node_type = structname::register_type(); \ - template const NodeType *structname::register_type() + const NodeType *structname::node_base_type = structname::register_base_type(); \ + template const NodeType *structname::register_base_type() /* Sock Definition Macros */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 4cac6e9ca5f..1e1d161ff9b 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -726,8 +726,8 @@ typedef enum PrimitiveType { typedef enum AttributePrimitive { ATTR_PRIM_TRIANGLE = 0, - ATTR_PRIM_CURVE, ATTR_PRIM_SUBD, + ATTR_PRIM_CURVE, ATTR_PRIM_TYPES } AttributePrimitive; diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index 92578b888a6..9e876b8d95c 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -19,7 +19,9 @@ set(SRC coverage.cpp denoising.cpp film.cpp + geometry.cpp graph.cpp + hair.cpp image.cpp integrator.cpp light.cpp @@ -54,7 +56,9 @@ set(SRC_HEADERS coverage.h denoising.h film.h + geometry.h graph.h + hair.h image.h integrator.h light.h diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index b65c2faa788..fcba901ae6c 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -15,6 +15,7 @@ */ #include "render/image.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/attribute.h" @@ -52,13 +53,13 @@ void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_) type == TypeRGBA); } -void Attribute::resize(Mesh *mesh, AttributePrimitive prim, bool reserve_only) +void Attribute::resize(Geometry *geom, AttributePrimitive prim, bool reserve_only) { if (reserve_only) { - buffer.reserve(buffer_size(mesh, prim)); + buffer.reserve(buffer_size(geom, prim)); } else { - buffer.resize(buffer_size(mesh, prim), 0); + buffer.resize(buffer_size(geom, prim), 0); } } @@ -157,13 +158,13 @@ size_t Attribute::data_sizeof() const return sizeof(float3); } -size_t Attribute::element_size(Mesh *mesh, AttributePrimitive prim) const +size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const { if (flags & ATTR_FINAL_SIZE) { return buffer.size() / data_sizeof(); } - size_t size; + size_t size = 0; switch (element) { case ATTR_ELEMENT_OBJECT: @@ -172,54 +173,74 @@ size_t Attribute::element_size(Mesh *mesh, AttributePrimitive prim) const size = 1; break; case ATTR_ELEMENT_VERTEX: - size = mesh->verts.size() + mesh->num_ngons; - if (prim == ATTR_PRIM_SUBD) { - size -= mesh->num_subd_verts; + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + size = mesh->verts.size() + mesh->num_ngons; + if (prim == ATTR_PRIM_SUBD) { + size -= mesh->num_subd_verts; + } } break; case ATTR_ELEMENT_VERTEX_MOTION: - size = (mesh->verts.size() + mesh->num_ngons) * (mesh->motion_steps - 1); - if (prim == ATTR_PRIM_SUBD) { - size -= mesh->num_subd_verts * (mesh->motion_steps - 1); + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + size = (mesh->verts.size() + mesh->num_ngons) * (mesh->motion_steps - 1); + if (prim == ATTR_PRIM_SUBD) { + size -= mesh->num_subd_verts * (mesh->motion_steps - 1); + } } break; case ATTR_ELEMENT_FACE: - if (prim == ATTR_PRIM_TRIANGLE) { - size = mesh->num_triangles(); - } - else { - size = mesh->subd_faces.size() + mesh->num_ngons; + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (prim == ATTR_PRIM_TRIANGLE) { + size = mesh->num_triangles(); + } + else { + size = mesh->subd_faces.size() + mesh->num_ngons; + } } break; case ATTR_ELEMENT_CORNER: case ATTR_ELEMENT_CORNER_BYTE: - if (prim == ATTR_PRIM_TRIANGLE) { - size = mesh->num_triangles() * 3; - } - else { - size = mesh->subd_face_corners.size() + mesh->num_ngons; + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (prim == ATTR_PRIM_TRIANGLE) { + size = mesh->num_triangles() * 3; + } + else { + size = mesh->subd_face_corners.size() + mesh->num_ngons; + } } break; case ATTR_ELEMENT_CURVE: - size = mesh->num_curves(); + if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + size = hair->num_curves(); + } break; case ATTR_ELEMENT_CURVE_KEY: - size = mesh->curve_keys.size(); + if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + size = hair->curve_keys.size(); + } break; case ATTR_ELEMENT_CURVE_KEY_MOTION: - size = mesh->curve_keys.size() * (mesh->motion_steps - 1); + if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + size = hair->curve_keys.size() * (hair->motion_steps - 1); + } break; default: - size = 0; break; } return size; } -size_t Attribute::buffer_size(Mesh *mesh, AttributePrimitive prim) const +size_t Attribute::buffer_size(Geometry *geom, AttributePrimitive prim) const { - return element_size(mesh, prim) * data_sizeof(); + return element_size(geom, prim) * data_sizeof(); } bool Attribute::same_storage(TypeDesc a, TypeDesc b) @@ -336,13 +357,44 @@ AttributeStandard Attribute::name_standard(const char *name) return ATTR_STD_NONE; } +void Attribute::get_uv_tiles(Geometry *geom, + AttributePrimitive prim, + unordered_set &tiles) const +{ + if (type != TypeFloat2) { + return; + } + + const int num = element_size(geom, prim); + const float2 *uv = data_float2(); + for (int i = 0; i < num; i++, uv++) { + float u = uv->x, v = uv->y; + int x = (int)u, y = (int)v; + + if (x < 0 || y < 0 || x >= 10) { + continue; + } + + /* Be conservative in corners - precisely touching the right or upper edge of a tile + * should not load its right/upper neighbor as well. */ + if (x > 0 && (u < x + 1e-6f)) { + x--; + } + if (y > 0 && (v < y + 1e-6f)) { + y--; + } + + tiles.insert(1001 + 10 * y + x); + } +} + /* Attribute Set */ AttributeSet::AttributeSet() { triangle_mesh = NULL; - curve_mesh = NULL; subd_mesh = NULL; + hair = NULL; } AttributeSet::~AttributeSet() @@ -378,10 +430,10 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme /* this is weak .. */ if (triangle_mesh) attr->resize(triangle_mesh, ATTR_PRIM_TRIANGLE, false); - if (curve_mesh) - attr->resize(curve_mesh, ATTR_PRIM_CURVE, false); if (subd_mesh) attr->resize(subd_mesh, ATTR_PRIM_SUBD, false); + if (hair) + attr->resize(hair, ATTR_PRIM_CURVE, false); return attr; } @@ -478,7 +530,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) break; } } - else if (curve_mesh) { + else if (hair) { switch (std) { case ATTR_STD_UV: attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE); @@ -563,10 +615,10 @@ void AttributeSet::resize(bool reserve_only) foreach (Attribute &attr, attributes) { if (triangle_mesh) attr.resize(triangle_mesh, ATTR_PRIM_TRIANGLE, reserve_only); - if (curve_mesh) - attr.resize(curve_mesh, ATTR_PRIM_CURVE, reserve_only); if (subd_mesh) attr.resize(subd_mesh, ATTR_PRIM_SUBD, reserve_only); + if (hair) + attr.resize(hair, ATTR_PRIM_CURVE, reserve_only); } } diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h index ebab0fe7f88..d4bf630aeb6 100644 --- a/intern/cycles/render/attribute.h +++ b/intern/cycles/render/attribute.h @@ -21,6 +21,7 @@ #include "util/util_list.h" #include "util/util_param.h" +#include "util/util_set.h" #include "util/util_types.h" #include "util/util_vector.h" @@ -31,6 +32,8 @@ class AttributeRequest; class AttributeRequestSet; class AttributeSet; class ImageManager; +class Geometry; +class Hair; class Mesh; struct Transform; @@ -61,12 +64,12 @@ class Attribute { } ~Attribute(); void set(ustring name, TypeDesc type, AttributeElement element); - void resize(Mesh *mesh, AttributePrimitive prim, bool reserve_only); + void resize(Geometry *geom, AttributePrimitive prim, bool reserve_only); void resize(size_t num_elements); size_t data_sizeof() const; - size_t element_size(Mesh *mesh, AttributePrimitive prim) const; - size_t buffer_size(Mesh *mesh, AttributePrimitive prim) const; + size_t element_size(Geometry *geom, AttributePrimitive prim) const; + size_t buffer_size(Geometry *geom, AttributePrimitive prim) const; char *data() { @@ -157,6 +160,8 @@ class Attribute { static bool same_storage(TypeDesc a, TypeDesc b); static const char *standard_name(AttributeStandard std); static AttributeStandard name_standard(const char *name); + + void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set &tiles) const; }; /* Attribute Set @@ -166,8 +171,8 @@ class Attribute { class AttributeSet { public: Mesh *triangle_mesh; - Mesh *curve_mesh; Mesh *subd_mesh; + Hair *hair; list attributes; AttributeSet(); @@ -200,7 +205,7 @@ class AttributeRequest { ustring name; AttributeStandard std; - /* temporary variables used by MeshManager */ + /* temporary variables used by GeometryManager */ TypeDesc triangle_type, curve_type, subd_type; AttributeDescriptor triangle_desc, curve_desc, subd_desc; diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp index b906357b7b5..9613da7c152 100644 --- a/intern/cycles/render/bake.cpp +++ b/intern/cycles/render/bake.cpp @@ -253,8 +253,8 @@ int BakeManager::aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType ty /* Only antialias normal if mesh has bump mapping. */ Object *object = scene->objects[bake_data->object()]; - if (object->mesh) { - foreach (Shader *shader, object->mesh->used_shaders) { + if (object->geometry) { + foreach (Shader *shader, object->geometry->used_shaders) { if (shader->has_bump) { return scene->integrator->aa_samples; } diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 38306a63c74..14ccf6696bd 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -498,7 +498,7 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen BoundBox viewplane_boundbox = viewplane_bounds_get(); for (size_t i = 0; i < scene->objects.size(); ++i) { Object *object = scene->objects[i]; - if (object->mesh->has_volume && viewplane_boundbox.intersects(object->bounds)) { + if (object->geometry->has_volume && viewplane_boundbox.intersects(object->bounds)) { /* TODO(sergey): Consider adding more grained check. */ VLOG(1) << "Detected camera inside volume."; kcam->is_inside_volume = 1; diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index 4af0f3c45f0..00356790261 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -593,13 +593,13 @@ bool Film::modified(const Film &film) void Film::tag_passes_update(Scene *scene, const vector &passes_, bool update_passes) { if (Pass::contains(passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) { - scene->mesh_manager->tag_update(scene); + scene->geometry_manager->tag_update(scene); foreach (Shader *shader, scene->shaders) - shader->need_update_mesh = true; + shader->need_update_geometry = true; } else if (Pass::contains(passes, PASS_MOTION) != Pass::contains(passes_, PASS_MOTION)) { - scene->mesh_manager->tag_update(scene); + scene->geometry_manager->tag_update(scene); } else if (Pass::contains(passes, PASS_AO) != Pass::contains(passes_, PASS_AO)) { scene->integrator->tag_update(scene); diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp new file mode 100644 index 00000000000..a75a114e4f2 --- /dev/null +++ b/intern/cycles/render/geometry.cpp @@ -0,0 +1,1548 @@ +/* + * Copyright 2011-2020 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 "bvh/bvh.h" +#include "bvh/bvh_build.h" + +#ifdef WITH_EMBREE +# include "bvh/bvh_embree.h" +#endif + +#include "render/attribute.h" +#include "render/camera.h" +#include "render/geometry.h" +#include "render/hair.h" +#include "render/light.h" +#include "render/mesh.h" +#include "render/nodes.h" +#include "render/object.h" +#include "render/scene.h" +#include "render/shader.h" +#include "render/stats.h" + +#include "subd/subd_split.h" +#include "subd/subd_patch_table.h" + +#include "kernel/osl/osl_globals.h" + +#include "util/util_foreach.h" +#include "util/util_logging.h" +#include "util/util_progress.h" + +CCL_NAMESPACE_BEGIN + +/* Geometry */ + +NODE_ABSTRACT_DEFINE(Geometry) +{ + NodeType *type = NodeType::add("geometry_base", NULL); + + SOCKET_UINT(motion_steps, "Motion Steps", 3); + SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false); + + return type; +} + +Geometry::Geometry(const NodeType *node_type, const Type type) : Node(node_type), type(type) +{ + need_update = true; + need_update_rebuild = false; + + transform_applied = false; + transform_negative_scaled = false; + transform_normal = transform_identity(); + bounds = BoundBox::empty; + + has_volume = false; + has_surface_bssrdf = false; + + bvh = NULL; + attr_map_offset = 0; + optix_prim_offset = 0; + prim_offset = 0; +} + +Geometry::~Geometry() +{ + delete bvh; +} + +void Geometry::clear() +{ + used_shaders.clear(); + transform_applied = false; + transform_negative_scaled = false; + transform_normal = transform_identity(); +} + +bool Geometry::need_attribute(Scene *scene, AttributeStandard std) +{ + if (std == ATTR_STD_NONE) + return false; + + if (scene->need_global_attribute(std)) + return true; + + foreach (Shader *shader, used_shaders) + if (shader->attributes.find(std)) + return true; + + return false; +} + +bool Geometry::need_attribute(Scene * /*scene*/, ustring name) +{ + if (name == ustring()) + return false; + + foreach (Shader *shader, used_shaders) + if (shader->attributes.find(name)) + return true; + + return false; +} + +float Geometry::motion_time(int step) const +{ + return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f; +} + +int Geometry::motion_step(float time) const +{ + if (motion_steps > 1) { + int attr_step = 0; + + for (int step = 0; step < motion_steps; step++) { + float step_time = motion_time(step); + if (step_time == time) { + return attr_step; + } + + /* Center step is stored in a separate attribute. */ + if (step != motion_steps / 2) { + attr_step++; + } + } + } + + return -1; +} + +bool Geometry::need_build_bvh(BVHLayout layout) const +{ + return !transform_applied || has_surface_bssrdf || layout == BVH_LAYOUT_OPTIX; +} + +bool Geometry::is_instanced() const +{ + /* Currently we treat subsurface objects as instanced. + * + * While it might be not very optimal for ray traversal, it avoids having + * duplicated BVH in the memory, saving quite some space. + */ + return !transform_applied || has_surface_bssrdf; +} + +bool Geometry::has_true_displacement() const +{ + foreach (Shader *shader, used_shaders) { + if (shader->has_displacement && shader->displacement_method != DISPLACE_BUMP) { + return true; + } + } + + return false; +} + +void Geometry::compute_bvh( + Device *device, DeviceScene *dscene, SceneParams *params, Progress *progress, int n, int total) +{ + if (progress->get_cancel()) + return; + + compute_bounds(); + + const BVHLayout bvh_layout = BVHParams::best_bvh_layout(params->bvh_layout, + device->get_bvh_layout_mask()); + if (need_build_bvh(bvh_layout)) { + string msg = "Updating Geometry BVH "; + if (name.empty()) + msg += string_printf("%u/%u", (uint)(n + 1), (uint)total); + else + msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total); + + Object object; + object.geometry = this; + + vector geometry; + geometry.push_back(this); + vector objects; + objects.push_back(&object); + + if (bvh && !need_update_rebuild) { + progress->set_status(msg, "Refitting BVH"); + + bvh->geometry = geometry; + bvh->objects = objects; + + bvh->refit(*progress); + } + else { + progress->set_status(msg, "Building BVH"); + + BVHParams bparams; + bparams.use_spatial_split = params->use_bvh_spatial_split; + bparams.bvh_layout = bvh_layout; + bparams.use_unaligned_nodes = dscene->data.bvh.have_curves && + params->use_bvh_unaligned_nodes; + bparams.num_motion_triangle_steps = params->num_bvh_time_steps; + bparams.num_motion_curve_steps = params->num_bvh_time_steps; + bparams.bvh_type = params->bvh_type; + bparams.curve_flags = dscene->data.curve.curveflags; + bparams.curve_subdivisions = dscene->data.curve.subdivisions; + + delete bvh; + bvh = BVH::create(bparams, geometry, objects); + MEM_GUARDED_CALL(progress, bvh->build, *progress); + } + } + + need_update = false; + need_update_rebuild = false; +} + +bool Geometry::has_motion_blur() const +{ + return (use_motion_blur && attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)); +} + +bool Geometry::has_voxel_attributes() const +{ + foreach (const Attribute &attr, attributes.attributes) { + if (attr.element == ATTR_ELEMENT_VOXEL) { + return true; + } + } + + return false; +} + +void Geometry::tag_update(Scene *scene, bool rebuild) +{ + need_update = true; + + if (rebuild) { + need_update_rebuild = true; + scene->light_manager->need_update = true; + } + else { + foreach (Shader *shader, used_shaders) + if (shader->has_surface_emission) + scene->light_manager->need_update = true; + } + + scene->geometry_manager->need_update = true; + scene->object_manager->need_update = true; +} + +/* Geometry Manager */ + +GeometryManager::GeometryManager() +{ + need_update = true; + need_flags_update = true; +} + +GeometryManager::~GeometryManager() +{ +} + +void GeometryManager::update_osl_attributes(Device *device, + Scene *scene, + vector &geom_attributes) +{ +#ifdef WITH_OSL + /* for OSL, a hash map is used to lookup the attribute by name. */ + OSLGlobals *og = (OSLGlobals *)device->osl_memory(); + + og->object_name_map.clear(); + og->attribute_map.clear(); + og->object_names.clear(); + + og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES); + + for (size_t i = 0; i < scene->objects.size(); i++) { + /* set object name to object index map */ + Object *object = scene->objects[i]; + og->object_name_map[object->name] = i; + og->object_names.push_back(object->name); + + /* set object attributes */ + foreach (ParamValue &attr, object->attributes) { + OSLGlobals::Attribute osl_attr; + + osl_attr.type = attr.type(); + osl_attr.desc.element = ATTR_ELEMENT_OBJECT; + osl_attr.value = attr; + osl_attr.desc.offset = 0; + osl_attr.desc.flags = 0; + + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][attr.name()] = osl_attr; + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr; + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr; + } + + /* find geometry attributes */ + size_t j; + + for (j = 0; j < scene->geometry.size(); j++) + if (scene->geometry[j] == object->geometry) + break; + + AttributeRequestSet &attributes = geom_attributes[j]; + + /* set object attributes */ + foreach (AttributeRequest &req, attributes.requests) { + OSLGlobals::Attribute osl_attr; + + if (req.triangle_desc.element != ATTR_ELEMENT_NONE) { + osl_attr.desc = req.triangle_desc; + + if (req.triangle_type == TypeDesc::TypeFloat) + osl_attr.type = TypeDesc::TypeFloat; + else if (req.triangle_type == TypeDesc::TypeMatrix) + osl_attr.type = TypeDesc::TypeMatrix; + else if (req.triangle_type == TypeFloat2) + osl_attr.type = TypeFloat2; + else if (req.triangle_type == TypeRGBA) + osl_attr.type = TypeRGBA; + else + osl_attr.type = TypeDesc::TypeColor; + + if (req.std != ATTR_STD_NONE) { + /* if standard attribute, add lookup by geom: name convention */ + ustring stdname(string("geom:") + string(Attribute::standard_name(req.std))); + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][stdname] = osl_attr; + } + else if (req.name != ustring()) { + /* add lookup by geometry attribute name */ + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][req.name] = osl_attr; + } + } + + if (req.curve_desc.element != ATTR_ELEMENT_NONE) { + osl_attr.desc = req.curve_desc; + + if (req.curve_type == TypeDesc::TypeFloat) + osl_attr.type = TypeDesc::TypeFloat; + else if (req.curve_type == TypeDesc::TypeMatrix) + osl_attr.type = TypeDesc::TypeMatrix; + else if (req.curve_type == TypeFloat2) + osl_attr.type = TypeFloat2; + else if (req.curve_type == TypeRGBA) + osl_attr.type = TypeRGBA; + else + osl_attr.type = TypeDesc::TypeColor; + + if (req.std != ATTR_STD_NONE) { + /* if standard attribute, add lookup by geom: name convention */ + ustring stdname(string("geom:") + string(Attribute::standard_name(req.std))); + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr; + } + else if (req.name != ustring()) { + /* add lookup by geometry attribute name */ + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr; + } + } + + if (req.subd_desc.element != ATTR_ELEMENT_NONE) { + osl_attr.desc = req.subd_desc; + + if (req.subd_type == TypeDesc::TypeFloat) + osl_attr.type = TypeDesc::TypeFloat; + else if (req.subd_type == TypeDesc::TypeMatrix) + osl_attr.type = TypeDesc::TypeMatrix; + else if (req.subd_type == TypeFloat2) + osl_attr.type = TypeFloat2; + else if (req.subd_type == TypeRGBA) + osl_attr.type = TypeRGBA; + else + osl_attr.type = TypeDesc::TypeColor; + + if (req.std != ATTR_STD_NONE) { + /* if standard attribute, add lookup by geom: name convention */ + ustring stdname(string("geom:") + string(Attribute::standard_name(req.std))); + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr; + } + else if (req.name != ustring()) { + /* add lookup by geometry attribute name */ + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr; + } + } + } + } +#else + (void)device; + (void)scene; + (void)geom_attributes; +#endif +} + +void GeometryManager::update_svm_attributes(Device *, + DeviceScene *dscene, + Scene *scene, + vector &geom_attributes) +{ + /* for SVM, the attributes_map table is used to lookup the offset of an + * attribute, based on a unique shader attribute id. */ + + /* compute array stride */ + int attr_map_size = 0; + + for (size_t i = 0; i < scene->geometry.size(); i++) { + Geometry *geom = scene->geometry[i]; + geom->attr_map_offset = attr_map_size; + attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES; + } + + if (attr_map_size == 0) + return; + + /* create attribute map */ + uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size); + memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint)); + + for (size_t i = 0; i < scene->geometry.size(); i++) { + Geometry *geom = scene->geometry[i]; + AttributeRequestSet &attributes = geom_attributes[i]; + + /* set object attributes */ + int index = geom->attr_map_offset; + + foreach (AttributeRequest &req, attributes.requests) { + uint id; + + if (req.std == ATTR_STD_NONE) + id = scene->shader_manager->get_attribute_id(req.name); + else + id = scene->shader_manager->get_attribute_id(req.std); + + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (mesh->num_triangles()) { + attr_map[index].x = id; + attr_map[index].y = req.triangle_desc.element; + attr_map[index].z = as_uint(req.triangle_desc.offset); + + if (req.triangle_type == TypeDesc::TypeFloat) + attr_map[index].w = NODE_ATTR_FLOAT; + else if (req.triangle_type == TypeDesc::TypeMatrix) + attr_map[index].w = NODE_ATTR_MATRIX; + else if (req.triangle_type == TypeFloat2) + attr_map[index].w = NODE_ATTR_FLOAT2; + else if (req.triangle_type == TypeRGBA) + attr_map[index].w = NODE_ATTR_RGBA; + else + attr_map[index].w = NODE_ATTR_FLOAT3; + + attr_map[index].w |= req.triangle_desc.flags << 8; + } + } + + index++; + + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (mesh->subd_faces.size()) { + attr_map[index].x = id; + attr_map[index].y = req.subd_desc.element; + attr_map[index].z = as_uint(req.subd_desc.offset); + + if (req.subd_type == TypeDesc::TypeFloat) + attr_map[index].w = NODE_ATTR_FLOAT; + else if (req.subd_type == TypeDesc::TypeMatrix) + attr_map[index].w = NODE_ATTR_MATRIX; + else if (req.subd_type == TypeFloat2) + attr_map[index].w = NODE_ATTR_FLOAT2; + else if (req.triangle_type == TypeRGBA) + attr_map[index].w = NODE_ATTR_RGBA; + else + attr_map[index].w = NODE_ATTR_FLOAT3; + + attr_map[index].w |= req.subd_desc.flags << 8; + } + } + + index++; + + if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + if (hair->num_curves()) { + attr_map[index].x = id; + attr_map[index].y = req.curve_desc.element; + attr_map[index].z = as_uint(req.curve_desc.offset); + + if (req.curve_type == TypeDesc::TypeFloat) + attr_map[index].w = NODE_ATTR_FLOAT; + else if (req.curve_type == TypeDesc::TypeMatrix) + attr_map[index].w = NODE_ATTR_MATRIX; + else if (req.curve_type == TypeFloat2) + attr_map[index].w = NODE_ATTR_FLOAT2; + else + attr_map[index].w = NODE_ATTR_FLOAT3; + + attr_map[index].w |= req.curve_desc.flags << 8; + } + } + + index++; + } + + /* terminator */ + for (int j = 0; j < ATTR_PRIM_TYPES; j++) { + attr_map[index].x = ATTR_STD_NONE; + attr_map[index].y = 0; + attr_map[index].z = 0; + attr_map[index].w = 0; + + index++; + } + } + + /* copy to device */ + dscene->attributes_map.copy_to_device(); +} + +static void update_attribute_element_size(Geometry *geom, + Attribute *mattr, + AttributePrimitive prim, + size_t *attr_float_size, + size_t *attr_float2_size, + size_t *attr_float3_size, + size_t *attr_uchar4_size) +{ + if (mattr) { + size_t size = mattr->element_size(geom, prim); + + if (mattr->element == ATTR_ELEMENT_VOXEL) { + /* pass */ + } + else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) { + *attr_uchar4_size += size; + } + else if (mattr->type == TypeDesc::TypeFloat) { + *attr_float_size += size; + } + else if (mattr->type == TypeFloat2) { + *attr_float2_size += size; + } + else if (mattr->type == TypeDesc::TypeMatrix) { + *attr_float3_size += size * 4; + } + else { + *attr_float3_size += size; + } + } +} + +static void update_attribute_element_offset(Geometry *geom, + device_vector &attr_float, + size_t &attr_float_offset, + device_vector &attr_float2, + size_t &attr_float2_offset, + device_vector &attr_float3, + size_t &attr_float3_offset, + device_vector &attr_uchar4, + size_t &attr_uchar4_offset, + Attribute *mattr, + AttributePrimitive prim, + TypeDesc &type, + AttributeDescriptor &desc) +{ + if (mattr) { + /* store element and type */ + desc.element = mattr->element; + desc.flags = mattr->flags; + type = mattr->type; + + /* store attribute data in arrays */ + size_t size = mattr->element_size(geom, prim); + + AttributeElement &element = desc.element; + int &offset = desc.offset; + + if (mattr->element == ATTR_ELEMENT_VOXEL) { + /* store slot in offset value */ + VoxelAttribute *voxel_data = mattr->data_voxel(); + offset = voxel_data->slot; + } + else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) { + uchar4 *data = mattr->data_uchar4(); + offset = attr_uchar4_offset; + + assert(attr_uchar4.size() >= offset + size); + for (size_t k = 0; k < size; k++) { + attr_uchar4[offset + k] = data[k]; + } + attr_uchar4_offset += size; + } + else if (mattr->type == TypeDesc::TypeFloat) { + float *data = mattr->data_float(); + offset = attr_float_offset; + + assert(attr_float.size() >= offset + size); + for (size_t k = 0; k < size; k++) { + attr_float[offset + k] = data[k]; + } + attr_float_offset += size; + } + else if (mattr->type == TypeFloat2) { + float2 *data = mattr->data_float2(); + offset = attr_float2_offset; + + assert(attr_float2.size() >= offset + size); + for (size_t k = 0; k < size; k++) { + attr_float2[offset + k] = data[k]; + } + attr_float2_offset += size; + } + else if (mattr->type == TypeDesc::TypeMatrix) { + Transform *tfm = mattr->data_transform(); + offset = attr_float3_offset; + + assert(attr_float3.size() >= offset + size * 3); + for (size_t k = 0; k < size * 3; k++) { + attr_float3[offset + k] = (&tfm->x)[k]; + } + attr_float3_offset += size * 3; + } + else { + float4 *data = mattr->data_float4(); + offset = attr_float3_offset; + + assert(attr_float3.size() >= offset + size); + for (size_t k = 0; k < size; k++) { + attr_float3[offset + k] = data[k]; + } + attr_float3_offset += size; + } + + /* mesh vertex/curve index is global, not per object, so we sneak + * a correction for that in here */ + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK && + desc.flags & ATTR_SUBDIVIDED) { + /* indices for subdivided attributes are retrieved + * from patch table so no need for correction here*/ + } + else if (element == ATTR_ELEMENT_VERTEX) + offset -= mesh->vert_offset; + else if (element == ATTR_ELEMENT_VERTEX_MOTION) + offset -= mesh->vert_offset; + else if (element == ATTR_ELEMENT_FACE) { + if (prim == ATTR_PRIM_TRIANGLE) + offset -= mesh->prim_offset; + else + offset -= mesh->face_offset; + } + else if (element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE) { + if (prim == ATTR_PRIM_TRIANGLE) + offset -= 3 * mesh->prim_offset; + else + offset -= mesh->corner_offset; + } + } + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + if (element == ATTR_ELEMENT_CURVE) + offset -= hair->prim_offset; + else if (element == ATTR_ELEMENT_CURVE_KEY) + offset -= hair->curvekey_offset; + else if (element == ATTR_ELEMENT_CURVE_KEY_MOTION) + offset -= hair->curvekey_offset; + } + } + else { + /* attribute not found */ + desc.element = ATTR_ELEMENT_NONE; + desc.offset = 0; + } +} + +void GeometryManager::device_update_attributes(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress &progress) +{ + progress.set_status("Updating Mesh", "Computing attributes"); + + /* gather per mesh requested attributes. as meshes may have multiple + * shaders assigned, this merges the requested attributes that have + * been set per shader by the shader manager */ + vector geom_attributes(scene->geometry.size()); + + for (size_t i = 0; i < scene->geometry.size(); i++) { + Geometry *geom = scene->geometry[i]; + + scene->need_global_attributes(geom_attributes[i]); + + foreach (Shader *shader, geom->used_shaders) { + geom_attributes[i].add(shader->attributes); + } + } + + /* mesh attribute are stored in a single array per data type. here we fill + * those arrays, and set the offset and element type to create attribute + * maps next */ + + /* Pre-allocate attributes to avoid arrays re-allocation which would + * take 2x of overall attribute memory usage. + */ + size_t attr_float_size = 0; + size_t attr_float2_size = 0; + size_t attr_float3_size = 0; + size_t attr_uchar4_size = 0; + for (size_t i = 0; i < scene->geometry.size(); i++) { + Geometry *geom = scene->geometry[i]; + AttributeRequestSet &attributes = geom_attributes[i]; + foreach (AttributeRequest &req, attributes.requests) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + Attribute *triangle_mattr = mesh->attributes.find(req); + Attribute *subd_mattr = mesh->subd_attributes.find(req); + + update_attribute_element_size(mesh, + triangle_mattr, + ATTR_PRIM_TRIANGLE, + &attr_float_size, + &attr_float2_size, + &attr_float3_size, + &attr_uchar4_size); + update_attribute_element_size(mesh, + subd_mattr, + ATTR_PRIM_SUBD, + &attr_float_size, + &attr_float2_size, + &attr_float3_size, + &attr_uchar4_size); + } + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + Attribute *curve_mattr = hair->attributes.find(req); + + update_attribute_element_size(hair, + curve_mattr, + ATTR_PRIM_CURVE, + &attr_float_size, + &attr_float2_size, + &attr_float3_size, + &attr_uchar4_size); + } + } + } + + dscene->attributes_float.alloc(attr_float_size); + dscene->attributes_float2.alloc(attr_float2_size); + dscene->attributes_float3.alloc(attr_float3_size); + dscene->attributes_uchar4.alloc(attr_uchar4_size); + + size_t attr_float_offset = 0; + size_t attr_float2_offset = 0; + size_t attr_float3_offset = 0; + size_t attr_uchar4_offset = 0; + + /* Fill in attributes. */ + for (size_t i = 0; i < scene->geometry.size(); i++) { + Geometry *geom = scene->geometry[i]; + AttributeRequestSet &attributes = geom_attributes[i]; + + /* todo: we now store std and name attributes from requests even if + * they actually refer to the same mesh attributes, optimize */ + foreach (AttributeRequest &req, attributes.requests) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + Attribute *triangle_mattr = mesh->attributes.find(req); + Attribute *subd_mattr = mesh->subd_attributes.find(req); + + update_attribute_element_offset(mesh, + dscene->attributes_float, + attr_float_offset, + dscene->attributes_float2, + attr_float2_offset, + dscene->attributes_float3, + attr_float3_offset, + dscene->attributes_uchar4, + attr_uchar4_offset, + triangle_mattr, + ATTR_PRIM_TRIANGLE, + req.triangle_type, + req.triangle_desc); + update_attribute_element_offset(mesh, + dscene->attributes_float, + attr_float_offset, + dscene->attributes_float2, + attr_float2_offset, + dscene->attributes_float3, + attr_float3_offset, + dscene->attributes_uchar4, + attr_uchar4_offset, + subd_mattr, + ATTR_PRIM_SUBD, + req.subd_type, + req.subd_desc); + } + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + Attribute *curve_mattr = hair->attributes.find(req); + + update_attribute_element_offset(hair, + dscene->attributes_float, + attr_float_offset, + dscene->attributes_float2, + attr_float2_offset, + dscene->attributes_float3, + attr_float3_offset, + dscene->attributes_uchar4, + attr_uchar4_offset, + curve_mattr, + ATTR_PRIM_CURVE, + req.curve_type, + req.curve_desc); + } + + if (progress.get_cancel()) + return; + } + } + + /* create attribute lookup maps */ + if (scene->shader_manager->use_osl()) + update_osl_attributes(device, scene, geom_attributes); + + update_svm_attributes(device, dscene, scene, geom_attributes); + + if (progress.get_cancel()) + return; + + /* copy to device */ + progress.set_status("Updating Mesh", "Copying Attributes to device"); + + if (dscene->attributes_float.size()) { + dscene->attributes_float.copy_to_device(); + } + if (dscene->attributes_float2.size()) { + dscene->attributes_float2.copy_to_device(); + } + if (dscene->attributes_float3.size()) { + dscene->attributes_float3.copy_to_device(); + } + if (dscene->attributes_uchar4.size()) { + dscene->attributes_uchar4.copy_to_device(); + } + + if (progress.get_cancel()) + return; + + /* After mesh attributes and patch tables have been copied to device memory, + * we need to update offsets in the objects. */ + scene->object_manager->device_update_mesh_offsets(device, dscene, scene); +} + +void GeometryManager::mesh_calc_offset(Scene *scene) +{ + size_t vert_size = 0; + size_t tri_size = 0; + + size_t curve_key_size = 0; + size_t curve_size = 0; + + size_t patch_size = 0; + size_t face_size = 0; + size_t corner_size = 0; + + size_t optix_prim_size = 0; + + foreach (Geometry *geom, scene->geometry) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + + mesh->vert_offset = vert_size; + mesh->prim_offset = tri_size; + + mesh->patch_offset = patch_size; + mesh->face_offset = face_size; + mesh->corner_offset = corner_size; + + vert_size += mesh->verts.size(); + tri_size += mesh->num_triangles(); + + if (mesh->subd_faces.size()) { + Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1]; + patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8; + + /* patch tables are stored in same array so include them in patch_size */ + if (mesh->patch_table) { + mesh->patch_table_offset = patch_size; + patch_size += mesh->patch_table->total_size(); + } + } + + face_size += mesh->subd_faces.size(); + corner_size += mesh->subd_face_corners.size(); + + mesh->optix_prim_offset = optix_prim_size; + optix_prim_size += mesh->num_triangles(); + } + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + + hair->curvekey_offset = curve_key_size; + hair->prim_offset = curve_size; + + curve_key_size += hair->curve_keys.size(); + curve_size += hair->num_curves(); + + hair->optix_prim_offset = optix_prim_size; + optix_prim_size += hair->num_segments(); + } + } +} + +void GeometryManager::device_update_mesh( + Device *, DeviceScene *dscene, Scene *scene, bool for_displacement, Progress &progress) +{ + /* Count. */ + size_t vert_size = 0; + size_t tri_size = 0; + + size_t curve_key_size = 0; + size_t curve_size = 0; + + size_t patch_size = 0; + + foreach (Geometry *geom, scene->geometry) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + + vert_size += mesh->verts.size(); + tri_size += mesh->num_triangles(); + + if (mesh->subd_faces.size()) { + Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1]; + patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8; + + /* patch tables are stored in same array so include them in patch_size */ + if (mesh->patch_table) { + mesh->patch_table_offset = patch_size; + patch_size += mesh->patch_table->total_size(); + } + } + } + else if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + + curve_key_size += hair->curve_keys.size(); + curve_size += hair->num_curves(); + } + } + + /* Create mapping from triangle to primitive triangle array. */ + vector tri_prim_index(tri_size); + if (for_displacement) { + /* For displacement kernels we do some trickery to make them believe + * we've got all required data ready. However, that data is different + * from final render kernels since we don't have BVH yet, so can't + * really use same semantic of arrays. + */ + foreach (Geometry *geom, scene->geometry) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + for (size_t i = 0; i < mesh->num_triangles(); ++i) { + tri_prim_index[i + mesh->prim_offset] = 3 * (i + mesh->prim_offset); + } + } + } + } + else { + for (size_t i = 0; i < dscene->prim_index.size(); ++i) { + if ((dscene->prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) { + tri_prim_index[dscene->prim_index[i]] = dscene->prim_tri_index[i]; + } + } + } + + /* Fill in all the arrays. */ + if (tri_size != 0) { + /* normals */ + progress.set_status("Updating Mesh", "Computing normals"); + + uint *tri_shader = dscene->tri_shader.alloc(tri_size); + float4 *vnormal = dscene->tri_vnormal.alloc(vert_size); + uint4 *tri_vindex = dscene->tri_vindex.alloc(tri_size); + uint *tri_patch = dscene->tri_patch.alloc(tri_size); + float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size); + + foreach (Geometry *geom, scene->geometry) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]); + mesh->pack_normals(&vnormal[mesh->vert_offset]); + mesh->pack_verts(tri_prim_index, + &tri_vindex[mesh->prim_offset], + &tri_patch[mesh->prim_offset], + &tri_patch_uv[mesh->vert_offset], + mesh->vert_offset, + mesh->prim_offset); + if (progress.get_cancel()) + return; + } + } + + /* vertex coordinates */ + progress.set_status("Updating Mesh", "Copying Mesh to device"); + + dscene->tri_shader.copy_to_device(); + dscene->tri_vnormal.copy_to_device(); + dscene->tri_vindex.copy_to_device(); + dscene->tri_patch.copy_to_device(); + dscene->tri_patch_uv.copy_to_device(); + } + + if (curve_size != 0) { + progress.set_status("Updating Mesh", "Copying Strands to device"); + + float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size); + float4 *curves = dscene->curves.alloc(curve_size); + + foreach (Geometry *geom, scene->geometry) { + if (geom->type == Geometry::HAIR) { + Hair *hair = static_cast(geom); + hair->pack_curves(scene, + &curve_keys[hair->curvekey_offset], + &curves[hair->prim_offset], + hair->curvekey_offset); + if (progress.get_cancel()) + return; + } + } + + dscene->curve_keys.copy_to_device(); + dscene->curves.copy_to_device(); + } + + if (patch_size != 0) { + progress.set_status("Updating Mesh", "Copying Patches to device"); + + uint *patch_data = dscene->patches.alloc(patch_size); + + foreach (Geometry *geom, scene->geometry) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + mesh->pack_patches(&patch_data[mesh->patch_offset], + mesh->vert_offset, + mesh->face_offset, + mesh->corner_offset); + + if (mesh->patch_table) { + mesh->patch_table->copy_adjusting_offsets(&patch_data[mesh->patch_table_offset], + mesh->patch_table_offset); + } + + if (progress.get_cancel()) + return; + } + } + + dscene->patches.copy_to_device(); + } + + if (for_displacement) { + float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3); + foreach (Geometry *geom, scene->geometry) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + for (size_t i = 0; i < mesh->num_triangles(); ++i) { + Mesh::Triangle t = mesh->get_triangle(i); + size_t offset = 3 * (i + mesh->prim_offset); + prim_tri_verts[offset + 0] = float3_to_float4(mesh->verts[t.v[0]]); + prim_tri_verts[offset + 1] = float3_to_float4(mesh->verts[t.v[1]]); + prim_tri_verts[offset + 2] = float3_to_float4(mesh->verts[t.v[2]]); + } + } + } + dscene->prim_tri_verts.copy_to_device(); + } +} + +void GeometryManager::device_update_bvh(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress &progress) +{ + /* bvh build */ + progress.set_status("Updating Scene BVH", "Building"); + + BVHParams bparams; + bparams.top_level = true; + bparams.bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout, + device->get_bvh_layout_mask()); + bparams.use_spatial_split = scene->params.use_bvh_spatial_split; + bparams.use_unaligned_nodes = dscene->data.bvh.have_curves && + scene->params.use_bvh_unaligned_nodes; + bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps; + bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps; + bparams.bvh_type = scene->params.bvh_type; + bparams.curve_flags = dscene->data.curve.curveflags; + bparams.curve_subdivisions = dscene->data.curve.subdivisions; + + VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout."; + +#ifdef WITH_EMBREE + if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) { + if (dscene->data.bvh.scene) { + BVHEmbree::destroy(dscene->data.bvh.scene); + } + } +#endif + + BVH *bvh = BVH::create(bparams, scene->geometry, scene->objects); + bvh->build(progress, &device->stats); + + if (progress.get_cancel()) { +#ifdef WITH_EMBREE + if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) { + if (dscene->data.bvh.scene) { + BVHEmbree::destroy(dscene->data.bvh.scene); + } + } +#endif + delete bvh; + return; + } + + /* copy to device */ + progress.set_status("Updating Scene BVH", "Copying BVH to device"); + + PackedBVH &pack = bvh->pack; + + if (pack.nodes.size()) { + dscene->bvh_nodes.steal_data(pack.nodes); + dscene->bvh_nodes.copy_to_device(); + } + if (pack.leaf_nodes.size()) { + dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes); + dscene->bvh_leaf_nodes.copy_to_device(); + } + if (pack.object_node.size()) { + dscene->object_node.steal_data(pack.object_node); + dscene->object_node.copy_to_device(); + } + if (pack.prim_tri_index.size()) { + dscene->prim_tri_index.steal_data(pack.prim_tri_index); + dscene->prim_tri_index.copy_to_device(); + } + if (pack.prim_tri_verts.size()) { + dscene->prim_tri_verts.steal_data(pack.prim_tri_verts); + dscene->prim_tri_verts.copy_to_device(); + } + if (pack.prim_type.size()) { + dscene->prim_type.steal_data(pack.prim_type); + dscene->prim_type.copy_to_device(); + } + if (pack.prim_visibility.size()) { + dscene->prim_visibility.steal_data(pack.prim_visibility); + dscene->prim_visibility.copy_to_device(); + } + if (pack.prim_index.size()) { + dscene->prim_index.steal_data(pack.prim_index); + dscene->prim_index.copy_to_device(); + } + if (pack.prim_object.size()) { + dscene->prim_object.steal_data(pack.prim_object); + dscene->prim_object.copy_to_device(); + } + if (pack.prim_time.size()) { + dscene->prim_time.steal_data(pack.prim_time); + dscene->prim_time.copy_to_device(); + } + + dscene->data.bvh.root = pack.root_index; + dscene->data.bvh.bvh_layout = bparams.bvh_layout; + dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0); + + bvh->copy_to_device(progress, dscene); + + delete bvh; +} + +void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress) +{ + if (!need_update && !need_flags_update) { + return; + } + + progress.set_status("Updating Meshes Flags"); + + /* Update flags. */ + bool volume_images_updated = false; + + foreach (Geometry *geom, scene->geometry) { + geom->has_volume = false; + + foreach (const Shader *shader, geom->used_shaders) { + if (shader->has_volume) { + geom->has_volume = true; + } + if (shader->has_surface_bssrdf) { + geom->has_surface_bssrdf = true; + } + } + + if (need_update && geom->has_volume && geom->type == Geometry::MESH) { + /* Create volume meshes if there is voxel data. */ + if (geom->has_voxel_attributes()) { + if (!volume_images_updated) { + progress.set_status("Updating Meshes Volume Bounds"); + device_update_volume_images(device, scene, progress); + volume_images_updated = true; + } + + Mesh *mesh = static_cast(geom); + create_volume_mesh(scene, mesh, progress); + } + } + } + + need_flags_update = false; +} + +void GeometryManager::device_update_displacement_images(Device *device, + Scene *scene, + Progress &progress) +{ + progress.set_status("Updating Displacement Images"); + TaskPool pool; + ImageManager *image_manager = scene->image_manager; + set bump_images; + foreach (Geometry *geom, scene->geometry) { + if (geom->need_update) { + foreach (Shader *shader, geom->used_shaders) { + if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) { + continue; + } + foreach (ShaderNode *node, shader->graph->nodes) { + if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) { + continue; + } + + ImageSlotTextureNode *image_node = static_cast(node); + foreach (int slot, image_node->slots) { + if (slot != -1) { + bump_images.insert(slot); + } + } + } + } + } + } + foreach (int slot, bump_images) { + pool.push(function_bind( + &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress)); + } + pool.wait_work(); +} + +void GeometryManager::device_update_volume_images(Device *device, Scene *scene, Progress &progress) +{ + progress.set_status("Updating Volume Images"); + TaskPool pool; + ImageManager *image_manager = scene->image_manager; + set volume_images; + + foreach (Geometry *geom, scene->geometry) { + if (!geom->need_update) { + continue; + } + + foreach (Attribute &attr, geom->attributes.attributes) { + if (attr.element != ATTR_ELEMENT_VOXEL) { + continue; + } + + VoxelAttribute *voxel = attr.data_voxel(); + + if (voxel->slot != -1) { + volume_images.insert(voxel->slot); + } + } + } + + foreach (int slot, volume_images) { + pool.push(function_bind( + &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress)); + } + pool.wait_work(); +} + +void GeometryManager::device_update(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress &progress) +{ + if (!need_update) + return; + + VLOG(1) << "Total " << scene->geometry.size() << " meshes."; + + bool true_displacement_used = false; + size_t total_tess_needed = 0; + + foreach (Geometry *geom, scene->geometry) { + foreach (Shader *shader, geom->used_shaders) { + if (shader->need_update_geometry) + geom->need_update = true; + } + + if (geom->need_update && geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + + /* Update normals. */ + mesh->add_face_normals(); + mesh->add_vertex_normals(); + + if (mesh->need_attribute(scene, ATTR_STD_POSITION_UNDISPLACED)) { + mesh->add_undisplaced(); + } + + /* Test if we need tessellation. */ + if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 && + mesh->subd_params) { + total_tess_needed++; + } + + /* Test if we need displacement. */ + if (mesh->has_true_displacement()) { + true_displacement_used = true; + } + + if (progress.get_cancel()) + return; + } + } + + /* Tessellate meshes that are using subdivision */ + if (total_tess_needed) { + Camera *dicing_camera = scene->dicing_camera; + dicing_camera->update(scene); + + size_t i = 0; + foreach (Geometry *geom, scene->geometry) { + if (!(geom->need_update && geom->type == Geometry::MESH)) { + continue; + } + + Mesh *mesh = static_cast(geom); + if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 && + mesh->subd_params) { + string msg = "Tessellating "; + if (mesh->name == "") + msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed); + else + msg += string_printf( + "%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)total_tess_needed); + + progress.set_status("Updating Mesh", msg); + + mesh->subd_params->camera = dicing_camera; + DiagSplit dsplit(*mesh->subd_params); + mesh->tessellate(&dsplit); + + i++; + + if (progress.get_cancel()) + return; + } + } + } + + /* Update images needed for true displacement. */ + bool old_need_object_flags_update = false; + if (true_displacement_used) { + VLOG(1) << "Updating images used for true displacement."; + device_update_displacement_images(device, scene, progress); + old_need_object_flags_update = scene->object_manager->need_flags_update; + scene->object_manager->device_update_flags(device, dscene, scene, progress, false); + } + + /* Device update. */ + device_free(device, dscene); + + mesh_calc_offset(scene); + if (true_displacement_used) { + device_update_mesh(device, dscene, scene, true, progress); + } + if (progress.get_cancel()) + return; + + device_update_attributes(device, dscene, scene, progress); + if (progress.get_cancel()) + return; + + /* Update displacement. */ + bool displacement_done = false; + size_t num_bvh = 0; + BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout, + device->get_bvh_layout_mask()); + + foreach (Geometry *geom, scene->geometry) { + if (geom->need_update) { + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (displace(device, dscene, scene, mesh, progress)) { + displacement_done = true; + } + } + + if (geom->need_build_bvh(bvh_layout)) { + num_bvh++; + } + } + + if (progress.get_cancel()) + return; + } + + /* Device re-update after displacement. */ + if (displacement_done) { + device_free(device, dscene); + + device_update_attributes(device, dscene, scene, progress); + if (progress.get_cancel()) + return; + } + + TaskPool pool; + + size_t i = 0; + foreach (Geometry *geom, scene->geometry) { + if (geom->need_update) { + pool.push(function_bind( + &Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh)); + if (geom->need_build_bvh(bvh_layout)) { + i++; + } + } + } + + TaskPool::Summary summary; + pool.wait_work(&summary); + VLOG(2) << "Objects BVH build pool statistics:\n" << summary.full_report(); + + foreach (Shader *shader, scene->shaders) { + shader->need_update_geometry = false; + } + + Scene::MotionType need_motion = scene->need_motion(); + bool motion_blur = need_motion == Scene::MOTION_BLUR; + + /* Update objects. */ + vector volume_objects; + foreach (Object *object, scene->objects) { + object->compute_bounds(motion_blur); + } + + if (progress.get_cancel()) + return; + + device_update_bvh(device, dscene, scene, progress); + if (progress.get_cancel()) + return; + + device_update_mesh(device, dscene, scene, false, progress); + if (progress.get_cancel()) + return; + + need_update = false; + + if (true_displacement_used) { + /* Re-tag flags for update, so they're re-evaluated + * for meshes with correct bounding boxes. + * + * This wouldn't cause wrong results, just true + * displacement might be less optimal ot calculate. + */ + scene->object_manager->need_flags_update = old_need_object_flags_update; + } +} + +void GeometryManager::device_free(Device *device, DeviceScene *dscene) +{ + dscene->bvh_nodes.free(); + dscene->bvh_leaf_nodes.free(); + dscene->object_node.free(); + dscene->prim_tri_verts.free(); + dscene->prim_tri_index.free(); + dscene->prim_type.free(); + dscene->prim_visibility.free(); + dscene->prim_index.free(); + dscene->prim_object.free(); + dscene->prim_time.free(); + dscene->tri_shader.free(); + dscene->tri_vnormal.free(); + dscene->tri_vindex.free(); + dscene->tri_patch.free(); + dscene->tri_patch_uv.free(); + dscene->curves.free(); + dscene->curve_keys.free(); + dscene->patches.free(); + dscene->attributes_map.free(); + dscene->attributes_float.free(); + dscene->attributes_float2.free(); + dscene->attributes_float3.free(); + dscene->attributes_uchar4.free(); + + /* Signal for shaders like displacement not to do ray tracing. */ + dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE; + +#ifdef WITH_OSL + OSLGlobals *og = (OSLGlobals *)device->osl_memory(); + + if (og) { + og->object_name_map.clear(); + og->attribute_map.clear(); + og->object_names.clear(); + } +#else + (void)device; +#endif +} + +void GeometryManager::tag_update(Scene *scene) +{ + need_update = true; + scene->object_manager->need_update = true; +} + +void GeometryManager::collect_statistics(const Scene *scene, RenderStats *stats) +{ + foreach (Geometry *geometry, scene->geometry) { + stats->mesh.geometry.add_entry( + NamedSizeEntry(string(geometry->name.c_str()), geometry->get_total_size_in_bytes())); + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h new file mode 100644 index 00000000000..711da1c81e8 --- /dev/null +++ b/intern/cycles/render/geometry.h @@ -0,0 +1,202 @@ +/* + * Copyright 2011-2020 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 __GEOMETRY_H__ +#define __GEOMETRY_H__ + +#include "graph/node.h" + +#include "bvh/bvh_params.h" + +#include "render/attribute.h" + +#include "util/util_boundbox.h" +#include "util/util_transform.h" +#include "util/util_set.h" +#include "util/util_types.h" +#include "util/util_vector.h" + +CCL_NAMESPACE_BEGIN + +class BVH; +class Device; +class DeviceScene; +class Mesh; +class Progress; +class RenderStats; +class Scene; +class SceneParams; +class Shader; + +/* Geometry + * + * Base class for geometric types like Mesh and Hair. */ + +class Geometry : public Node { + public: + NODE_ABSTRACT_DECLARE + + enum Type { + MESH, + HAIR, + }; + + Type type; + + /* Attributes */ + AttributeSet attributes; + + /* Shaders */ + vector used_shaders; + + /* Transform */ + BoundBox bounds; + bool transform_applied; + bool transform_negative_scaled; + Transform transform_normal; + + /* Motion Blur */ + uint motion_steps; + bool use_motion_blur; + + /* BVH */ + BVH *bvh; + size_t attr_map_offset; + size_t prim_offset; + size_t optix_prim_offset; + + /* Shader Properties */ + bool has_volume; /* Set in the device_update_flags(). */ + bool has_surface_bssrdf; /* Set in the device_update_flags(). */ + + /* Update Flags */ + bool need_update; + bool need_update_rebuild; + + /* Constructor/Destructor */ + explicit Geometry(const NodeType *node_type, const Type type); + virtual ~Geometry(); + + /* Geometry */ + virtual void clear(); + virtual void compute_bounds() = 0; + virtual void apply_transform(const Transform &tfm, const bool apply_to_motion) = 0; + + /* Attribute Requests */ + bool need_attribute(Scene *scene, AttributeStandard std); + bool need_attribute(Scene *scene, ustring name); + + /* UDIM */ + virtual void get_uv_tiles(ustring map, unordered_set &tiles) = 0; + + /* Convert between normalized -1..1 motion time and index in the + * VERTEX_MOTION attribute. */ + float motion_time(int step) const; + int motion_step(float time) const; + + /* BVH */ + void compute_bvh(Device *device, + DeviceScene *dscene, + SceneParams *params, + Progress *progress, + int n, + int total); + + /* Check whether the geometry should have own BVH built separately. Briefly, + * own BVH is needed for geometry, if: + * + * - It is instanced multiple times, so each instance object should share the + * same BVH tree. + * - Special ray intersection is needed, for example to limit subsurface rays + * to only the geometry itself. + * - The BVH layout requires the top level to only contain instances. + */ + bool need_build_bvh(BVHLayout layout) const; + + /* Test if the geometry should be treated as instanced. */ + bool is_instanced() const; + + bool has_true_displacement() const; + bool has_motion_blur() const; + bool has_voxel_attributes() const; + + /* Updates */ + void tag_update(Scene *scene, bool rebuild); +}; + +/* Geometry Manager */ + +class GeometryManager { + public: + /* Update Flags */ + bool need_update; + bool need_flags_update; + + /* Constructor/Destructor */ + GeometryManager(); + ~GeometryManager(); + + /* Device Updates */ + void device_update_preprocess(Device *device, Scene *scene, Progress &progress); + void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress); + void device_free(Device *device, DeviceScene *dscene); + + /* Updates */ + void tag_update(Scene *scene); + + /* Statistics */ + void collect_statistics(const Scene *scene, RenderStats *stats); + + protected: + bool displace(Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress &progress); + + void create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress); + + /* Attributes */ + void update_osl_attributes(Device *device, + Scene *scene, + vector &geom_attributes); + void update_svm_attributes(Device *device, + DeviceScene *dscene, + Scene *scene, + vector &geom_attributes); + + /* Compute verts/triangles/curves offsets in global arrays. */ + void mesh_calc_offset(Scene *scene); + + void device_update_object(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress); + + void device_update_mesh(Device *device, + DeviceScene *dscene, + Scene *scene, + bool for_displacement, + Progress &progress); + + void device_update_attributes(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress &progress); + + void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress); + + void device_update_displacement_images(Device *device, Scene *scene, Progress &progress); + + void device_update_volume_images(Device *device, Scene *scene, Progress &progress); +}; + +CCL_NAMESPACE_END + +#endif /* __GEOMETRY_H__ */ diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp new file mode 100644 index 00000000000..a35d4b6f1da --- /dev/null +++ b/intern/cycles/render/hair.cpp @@ -0,0 +1,489 @@ +/* + * Copyright 2011-2020 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 "render/curves.h" +#include "render/hair.h" +#include "render/scene.h" + +CCL_NAMESPACE_BEGIN + +/* Hair Curve */ + +void Hair::Curve::bounds_grow(const int k, + const float3 *curve_keys, + const float *curve_radius, + BoundBox &bounds) const +{ + float3 P[4]; + + P[0] = curve_keys[max(first_key + k - 1, first_key)]; + P[1] = curve_keys[first_key + k]; + P[2] = curve_keys[first_key + k + 1]; + P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]; + + float3 lower; + float3 upper; + + curvebounds(&lower.x, &upper.x, P, 0); + curvebounds(&lower.y, &upper.y, P, 1); + curvebounds(&lower.z, &upper.z, P, 2); + + float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]); + + bounds.grow(lower, mr); + bounds.grow(upper, mr); +} + +void Hair::Curve::bounds_grow(const int k, + const float3 *curve_keys, + const float *curve_radius, + const Transform &aligned_space, + BoundBox &bounds) const +{ + float3 P[4]; + + P[0] = curve_keys[max(first_key + k - 1, first_key)]; + P[1] = curve_keys[first_key + k]; + P[2] = curve_keys[first_key + k + 1]; + P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]; + + P[0] = transform_point(&aligned_space, P[0]); + P[1] = transform_point(&aligned_space, P[1]); + P[2] = transform_point(&aligned_space, P[2]); + P[3] = transform_point(&aligned_space, P[3]); + + float3 lower; + float3 upper; + + curvebounds(&lower.x, &upper.x, P, 0); + curvebounds(&lower.y, &upper.y, P, 1); + curvebounds(&lower.z, &upper.z, P, 2); + + float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]); + + bounds.grow(lower, mr); + bounds.grow(upper, mr); +} + +void Hair::Curve::bounds_grow(float4 keys[4], BoundBox &bounds) const +{ + float3 P[4] = { + float4_to_float3(keys[0]), + float4_to_float3(keys[1]), + float4_to_float3(keys[2]), + float4_to_float3(keys[3]), + }; + + float3 lower; + float3 upper; + + curvebounds(&lower.x, &upper.x, P, 0); + curvebounds(&lower.y, &upper.y, P, 1); + curvebounds(&lower.z, &upper.z, P, 2); + + float mr = max(keys[1].w, keys[2].w); + + bounds.grow(lower, mr); + bounds.grow(upper, mr); +} + +void Hair::Curve::motion_keys(const float3 *curve_keys, + const float *curve_radius, + const float3 *key_steps, + size_t num_curve_keys, + size_t num_steps, + float time, + size_t k0, + size_t k1, + float4 r_keys[2]) const +{ + /* Figure out which steps we need to fetch and their interpolation factor. */ + const size_t max_step = num_steps - 1; + const size_t step = min((int)(time * max_step), max_step - 1); + const float t = time * max_step - step; + /* Fetch vertex coordinates. */ + float4 curr_keys[2]; + float4 next_keys[2]; + keys_for_step( + curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step, k0, k1, curr_keys); + keys_for_step( + curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step + 1, k0, k1, next_keys); + /* Interpolate between steps. */ + r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0]; + r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1]; +} + +void Hair::Curve::cardinal_motion_keys(const float3 *curve_keys, + const float *curve_radius, + const float3 *key_steps, + size_t num_curve_keys, + size_t num_steps, + float time, + size_t k0, + size_t k1, + size_t k2, + size_t k3, + float4 r_keys[4]) const +{ + /* Figure out which steps we need to fetch and their interpolation factor. */ + const size_t max_step = num_steps - 1; + const size_t step = min((int)(time * max_step), max_step - 1); + const float t = time * max_step - step; + /* Fetch vertex coordinates. */ + float4 curr_keys[4]; + float4 next_keys[4]; + cardinal_keys_for_step(curve_keys, + curve_radius, + key_steps, + num_curve_keys, + num_steps, + step, + k0, + k1, + k2, + k3, + curr_keys); + cardinal_keys_for_step(curve_keys, + curve_radius, + key_steps, + num_curve_keys, + num_steps, + step + 1, + k0, + k1, + k2, + k3, + next_keys); + /* Interpolate between steps. */ + r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0]; + r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1]; + r_keys[2] = (1.0f - t) * curr_keys[2] + t * next_keys[2]; + r_keys[3] = (1.0f - t) * curr_keys[3] + t * next_keys[3]; +} + +void Hair::Curve::keys_for_step(const float3 *curve_keys, + const float *curve_radius, + const float3 *key_steps, + size_t num_curve_keys, + size_t num_steps, + size_t step, + size_t k0, + size_t k1, + float4 r_keys[2]) const +{ + k0 = max(k0, 0); + k1 = min(k1, num_keys - 1); + const size_t center_step = ((num_steps - 1) / 2); + if (step == center_step) { + /* Center step: regular key location. */ + /* TODO(sergey): Consider adding make_float4(float3, float) + * function. + */ + r_keys[0] = make_float4(curve_keys[first_key + k0].x, + curve_keys[first_key + k0].y, + curve_keys[first_key + k0].z, + curve_radius[first_key + k0]); + r_keys[1] = make_float4(curve_keys[first_key + k1].x, + curve_keys[first_key + k1].y, + curve_keys[first_key + k1].z, + curve_radius[first_key + k1]); + } + else { + /* Center step is not stored in this array. */ + if (step > center_step) { + step--; + } + const size_t offset = first_key + step * num_curve_keys; + r_keys[0] = make_float4(key_steps[offset + k0].x, + key_steps[offset + k0].y, + key_steps[offset + k0].z, + curve_radius[first_key + k0]); + r_keys[1] = make_float4(key_steps[offset + k1].x, + key_steps[offset + k1].y, + key_steps[offset + k1].z, + curve_radius[first_key + k1]); + } +} + +void Hair::Curve::cardinal_keys_for_step(const float3 *curve_keys, + const float *curve_radius, + const float3 *key_steps, + size_t num_curve_keys, + size_t num_steps, + size_t step, + size_t k0, + size_t k1, + size_t k2, + size_t k3, + float4 r_keys[4]) const +{ + k0 = max(k0, 0); + k3 = min(k3, num_keys - 1); + const size_t center_step = ((num_steps - 1) / 2); + if (step == center_step) { + /* Center step: regular key location. */ + r_keys[0] = make_float4(curve_keys[first_key + k0].x, + curve_keys[first_key + k0].y, + curve_keys[first_key + k0].z, + curve_radius[first_key + k0]); + r_keys[1] = make_float4(curve_keys[first_key + k1].x, + curve_keys[first_key + k1].y, + curve_keys[first_key + k1].z, + curve_radius[first_key + k1]); + r_keys[2] = make_float4(curve_keys[first_key + k2].x, + curve_keys[first_key + k2].y, + curve_keys[first_key + k2].z, + curve_radius[first_key + k2]); + r_keys[3] = make_float4(curve_keys[first_key + k3].x, + curve_keys[first_key + k3].y, + curve_keys[first_key + k3].z, + curve_radius[first_key + k3]); + } + else { + /* Center step is not stored in this array. */ + if (step > center_step) { + step--; + } + const size_t offset = first_key + step * num_curve_keys; + r_keys[0] = make_float4(key_steps[offset + k0].x, + key_steps[offset + k0].y, + key_steps[offset + k0].z, + curve_radius[first_key + k0]); + r_keys[1] = make_float4(key_steps[offset + k1].x, + key_steps[offset + k1].y, + key_steps[offset + k1].z, + curve_radius[first_key + k1]); + r_keys[2] = make_float4(key_steps[offset + k2].x, + key_steps[offset + k2].y, + key_steps[offset + k2].z, + curve_radius[first_key + k2]); + r_keys[3] = make_float4(key_steps[offset + k3].x, + key_steps[offset + k3].y, + key_steps[offset + k3].z, + curve_radius[first_key + k3]); + } +} + +/* Hair */ + +NODE_DEFINE(Hair) +{ + NodeType *type = NodeType::add("hair", create, NodeType::NONE, Geometry::node_base_type); + + SOCKET_POINT_ARRAY(curve_keys, "Curve Keys", array()); + SOCKET_FLOAT_ARRAY(curve_radius, "Curve Radius", array()); + SOCKET_INT_ARRAY(curve_first_key, "Curve First Key", array()); + SOCKET_INT_ARRAY(curve_shader, "Curve Shader", array()); + + return type; +} + +Hair::Hair() : Geometry(node_type, Geometry::HAIR) +{ + curvekey_offset = 0; + + attributes.hair = this; +} + +Hair::~Hair() +{ +} + +void Hair::resize_curves(int numcurves, int numkeys) +{ + curve_keys.resize(numkeys); + curve_radius.resize(numkeys); + curve_first_key.resize(numcurves); + curve_shader.resize(numcurves); + + attributes.resize(); +} + +void Hair::reserve_curves(int numcurves, int numkeys) +{ + curve_keys.reserve(numkeys); + curve_radius.reserve(numkeys); + curve_first_key.reserve(numcurves); + curve_shader.reserve(numcurves); + + attributes.resize(true); +} + +void Hair::clear() +{ + Geometry::clear(); + + curve_keys.clear(); + curve_radius.clear(); + curve_first_key.clear(); + curve_shader.clear(); + + attributes.clear(); +} + +void Hair::add_curve_key(float3 co, float radius) +{ + curve_keys.push_back_reserved(co); + curve_radius.push_back_reserved(radius); +} + +void Hair::add_curve(int first_key, int shader) +{ + curve_first_key.push_back_reserved(first_key); + curve_shader.push_back_reserved(shader); +} + +void Hair::copy_center_to_motion_step(const int motion_step) +{ + Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (attr_mP) { + float3 *keys = &curve_keys[0]; + size_t numkeys = curve_keys.size(); + memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys); + } +} + +void Hair::get_uv_tiles(ustring map, unordered_set &tiles) +{ + Attribute *attr; + + if (map.empty()) { + attr = attributes.find(ATTR_STD_UV); + } + else { + attr = attributes.find(map); + } + + if (attr) { + attr->get_uv_tiles(this, ATTR_PRIM_CURVE, tiles); + } +} + +void Hair::compute_bounds() +{ + BoundBox bnds = BoundBox::empty; + size_t curve_keys_size = curve_keys.size(); + + if (curve_keys_size > 0) { + for (size_t i = 0; i < curve_keys_size; i++) + bnds.grow(curve_keys[i], curve_radius[i]); + + Attribute *curve_attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + if (use_motion_blur && curve_attr) { + size_t steps_size = curve_keys.size() * (motion_steps - 1); + float3 *key_steps = curve_attr->data_float3(); + + for (size_t i = 0; i < steps_size; i++) + bnds.grow(key_steps[i]); + } + + if (!bnds.valid()) { + bnds = BoundBox::empty; + + /* skip nan or inf coordinates */ + for (size_t i = 0; i < curve_keys_size; i++) + bnds.grow_safe(curve_keys[i], curve_radius[i]); + + if (use_motion_blur && curve_attr) { + size_t steps_size = curve_keys.size() * (motion_steps - 1); + float3 *key_steps = curve_attr->data_float3(); + + for (size_t i = 0; i < steps_size; i++) + bnds.grow_safe(key_steps[i]); + } + } + } + + if (!bnds.valid()) { + /* empty mesh */ + bnds.grow(make_float3(0.0f, 0.0f, 0.0f)); + } + + bounds = bnds; +} + +void Hair::apply_transform(const Transform &tfm, const bool apply_to_motion) +{ + /* compute uniform scale */ + float3 c0 = transform_get_column(&tfm, 0); + float3 c1 = transform_get_column(&tfm, 1); + float3 c2 = transform_get_column(&tfm, 2); + float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f / 3.0f); + + /* apply transform to curve keys */ + for (size_t i = 0; i < curve_keys.size(); i++) { + float3 co = transform_point(&tfm, curve_keys[i]); + float radius = curve_radius[i] * scalar; + + /* scale for curve radius is only correct for uniform scale */ + curve_keys[i] = co; + curve_radius[i] = radius; + } + + if (apply_to_motion) { + Attribute *curve_attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + + if (curve_attr) { + /* apply transform to motion curve keys */ + size_t steps_size = curve_keys.size() * (motion_steps - 1); + float4 *key_steps = curve_attr->data_float4(); + + for (size_t i = 0; i < steps_size; i++) { + float3 co = transform_point(&tfm, float4_to_float3(key_steps[i])); + float radius = key_steps[i].w * scalar; + + /* scale for curve radius is only correct for uniform scale */ + key_steps[i] = float3_to_float4(co); + key_steps[i].w = radius; + } + } + } +} + +void Hair::pack_curves(Scene *scene, + float4 *curve_key_co, + float4 *curve_data, + size_t curvekey_offset) +{ + size_t curve_keys_size = curve_keys.size(); + + /* pack curve keys */ + if (curve_keys_size) { + float3 *keys_ptr = curve_keys.data(); + float *radius_ptr = curve_radius.data(); + + for (size_t i = 0; i < curve_keys_size; i++) + curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]); + } + + /* pack curve segments */ + size_t curve_num = num_curves(); + + for (size_t i = 0; i < curve_num; i++) { + Curve curve = get_curve(i); + int shader_id = curve_shader[i]; + Shader *shader = (shader_id < used_shaders.size()) ? used_shaders[shader_id] : + scene->default_surface; + shader_id = scene->shader_manager->get_shader_id(shader, false); + + curve_data[i] = make_float4(__int_as_float(curve.first_key + curvekey_offset), + __int_as_float(curve.num_keys), + __int_as_float(shader_id), + 0.0f); + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/render/hair.h b/intern/cycles/render/hair.h new file mode 100644 index 00000000000..79f77a78753 --- /dev/null +++ b/intern/cycles/render/hair.h @@ -0,0 +1,151 @@ +/* + * Copyright 2011-2020 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 __HAIR_H__ +#define __HAIR_H__ + +#include "render/geometry.h" + +CCL_NAMESPACE_BEGIN + +class Hair : public Geometry { + public: + NODE_DECLARE + + /* Hair Curve */ + struct Curve { + int first_key; + int num_keys; + + int num_segments() const + { + return num_keys - 1; + } + + void bounds_grow(const int k, + const float3 *curve_keys, + const float *curve_radius, + BoundBox &bounds) const; + void bounds_grow(float4 keys[4], BoundBox &bounds) const; + void bounds_grow(const int k, + const float3 *curve_keys, + const float *curve_radius, + const Transform &aligned_space, + BoundBox &bounds) const; + + void motion_keys(const float3 *curve_keys, + const float *curve_radius, + const float3 *key_steps, + size_t num_curve_keys, + size_t num_steps, + float time, + size_t k0, + size_t k1, + float4 r_keys[2]) const; + void cardinal_motion_keys(const float3 *curve_keys, + const float *curve_radius, + const float3 *key_steps, + size_t num_curve_keys, + size_t num_steps, + float time, + size_t k0, + size_t k1, + size_t k2, + size_t k3, + float4 r_keys[4]) const; + + void keys_for_step(const float3 *curve_keys, + const float *curve_radius, + const float3 *key_steps, + size_t num_curve_keys, + size_t num_steps, + size_t step, + size_t k0, + size_t k1, + float4 r_keys[2]) const; + void cardinal_keys_for_step(const float3 *curve_keys, + const float *curve_radius, + const float3 *key_steps, + size_t num_curve_keys, + size_t num_steps, + size_t step, + size_t k0, + size_t k1, + size_t k2, + size_t k3, + float4 r_keys[4]) const; + }; + + array curve_keys; + array curve_radius; + array curve_first_key; + array curve_shader; + + /* BVH */ + size_t curvekey_offset; + + /* Constructor/Destructor */ + Hair(); + ~Hair(); + + /* Geometry */ + void clear() override; + + void resize_curves(int numcurves, int numkeys); + void reserve_curves(int numcurves, int numkeys); + void add_curve_key(float3 loc, float radius); + void add_curve(int first_key, int shader); + + void copy_center_to_motion_step(const int motion_step); + + void compute_bounds() override; + void apply_transform(const Transform &tfm, const bool apply_to_motion) override; + + /* Curves */ + Curve get_curve(size_t i) const + { + int first = curve_first_key[i]; + int next_first = (i + 1 < curve_first_key.size()) ? curve_first_key[i + 1] : curve_keys.size(); + + Curve curve = {first, next_first - first}; + return curve; + } + + size_t num_keys() const + { + return curve_keys.size(); + } + + size_t num_curves() const + { + return curve_first_key.size(); + } + + size_t num_segments() const + { + return curve_keys.size() - curve_first_key.size(); + } + + /* UDIM */ + void get_uv_tiles(ustring map, unordered_set &tiles) override; + + /* BVH */ + void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset); +}; + +CCL_NAMESPACE_END + +#endif /* __HAIR_H__ */ diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 664217d6f26..509637aedd9 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -232,7 +232,10 @@ void LightManager::disable_ineffective_light(Scene *scene) bool LightManager::object_usable_as_light(Object *object) { - Mesh *mesh = object->mesh; + Geometry *geom = object->geometry; + if (geom->type != Geometry::MESH) { + return false; + } /* Skip objects with NaNs */ if (!object->bounds.valid()) { return false; @@ -243,10 +246,10 @@ bool LightManager::object_usable_as_light(Object *object) } /* Skip if we have no emission shaders. */ /* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll - * iterate all mesh shaders twice (when counting and when calculating + * iterate all geometry shaders twice (when counting and when calculating * triangle area. */ - foreach (const Shader *shader, mesh->used_shaders) { + foreach (const Shader *shader, geom->used_shaders) { if (shader->use_mis && shader->has_surface_emission) { return true; } @@ -285,8 +288,9 @@ void LightManager::device_update_distribution(Device *, if (!object_usable_as_light(object)) { continue; } + /* Count triangles. */ - Mesh *mesh = object->mesh; + Mesh *mesh = static_cast(object->geometry); size_t mesh_num_triangles = mesh->num_triangles(); for (size_t i = 0; i < mesh_num_triangles; i++) { int shader_index = mesh->shader[i]; @@ -320,7 +324,7 @@ void LightManager::device_update_distribution(Device *, continue; } /* Sum area. */ - Mesh *mesh = object->mesh; + Mesh *mesh = static_cast(object->geometry); bool transform_applied = mesh->transform_applied; Transform tfm = object->tfm; int object_id = j; @@ -352,7 +356,7 @@ void LightManager::device_update_distribution(Device *, if (shader->use_mis && shader->has_surface_emission) { distribution[offset].totarea = totarea; - distribution[offset].prim = i + mesh->tri_offset; + distribution[offset].prim = i + mesh->prim_offset; distribution[offset].mesh_light.shader_flag = shader_flag; distribution[offset].mesh_light.object_id = object_id; offset++; diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index d9e6d998ebd..792848e744a 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -17,19 +17,13 @@ #include "bvh/bvh.h" #include "bvh/bvh_build.h" -#include "render/camera.h" -#include "render/curves.h" #include "device/device.h" + #include "render/graph.h" -#include "render/shader.h" -#include "render/light.h" +#include "render/hair.h" #include "render/mesh.h" -#include "render/nodes.h" #include "render/object.h" #include "render/scene.h" -#include "render/stats.h" - -#include "kernel/osl/osl_globals.h" #include "subd/subd_split.h" #include "subd/subd_patch_table.h" @@ -39,10 +33,6 @@ #include "util/util_progress.h" #include "util/util_set.h" -#ifdef WITH_EMBREE -# include "bvh/bvh_embree.h" -#endif - CCL_NAMESPACE_BEGIN /* Triangle */ @@ -120,263 +110,6 @@ bool Mesh::Triangle::valid(const float3 *verts) const return isfinite3_safe(verts[v[0]]) && isfinite3_safe(verts[v[1]]) && isfinite3_safe(verts[v[2]]); } -/* Curve */ - -void Mesh::Curve::bounds_grow(const int k, - const float3 *curve_keys, - const float *curve_radius, - BoundBox &bounds) const -{ - float3 P[4]; - - P[0] = curve_keys[max(first_key + k - 1, first_key)]; - P[1] = curve_keys[first_key + k]; - P[2] = curve_keys[first_key + k + 1]; - P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]; - - float3 lower; - float3 upper; - - curvebounds(&lower.x, &upper.x, P, 0); - curvebounds(&lower.y, &upper.y, P, 1); - curvebounds(&lower.z, &upper.z, P, 2); - - float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]); - - bounds.grow(lower, mr); - bounds.grow(upper, mr); -} - -void Mesh::Curve::bounds_grow(const int k, - const float3 *curve_keys, - const float *curve_radius, - const Transform &aligned_space, - BoundBox &bounds) const -{ - float3 P[4]; - - P[0] = curve_keys[max(first_key + k - 1, first_key)]; - P[1] = curve_keys[first_key + k]; - P[2] = curve_keys[first_key + k + 1]; - P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]; - - P[0] = transform_point(&aligned_space, P[0]); - P[1] = transform_point(&aligned_space, P[1]); - P[2] = transform_point(&aligned_space, P[2]); - P[3] = transform_point(&aligned_space, P[3]); - - float3 lower; - float3 upper; - - curvebounds(&lower.x, &upper.x, P, 0); - curvebounds(&lower.y, &upper.y, P, 1); - curvebounds(&lower.z, &upper.z, P, 2); - - float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]); - - bounds.grow(lower, mr); - bounds.grow(upper, mr); -} - -void Mesh::Curve::bounds_grow(float4 keys[4], BoundBox &bounds) const -{ - float3 P[4] = { - float4_to_float3(keys[0]), - float4_to_float3(keys[1]), - float4_to_float3(keys[2]), - float4_to_float3(keys[3]), - }; - - float3 lower; - float3 upper; - - curvebounds(&lower.x, &upper.x, P, 0); - curvebounds(&lower.y, &upper.y, P, 1); - curvebounds(&lower.z, &upper.z, P, 2); - - float mr = max(keys[1].w, keys[2].w); - - bounds.grow(lower, mr); - bounds.grow(upper, mr); -} - -void Mesh::Curve::motion_keys(const float3 *curve_keys, - const float *curve_radius, - const float3 *key_steps, - size_t num_curve_keys, - size_t num_steps, - float time, - size_t k0, - size_t k1, - float4 r_keys[2]) const -{ - /* Figure out which steps we need to fetch and their interpolation factor. */ - const size_t max_step = num_steps - 1; - const size_t step = min((int)(time * max_step), max_step - 1); - const float t = time * max_step - step; - /* Fetch vertex coordinates. */ - float4 curr_keys[2]; - float4 next_keys[2]; - keys_for_step( - curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step, k0, k1, curr_keys); - keys_for_step( - curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step + 1, k0, k1, next_keys); - /* Interpolate between steps. */ - r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0]; - r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1]; -} - -void Mesh::Curve::cardinal_motion_keys(const float3 *curve_keys, - const float *curve_radius, - const float3 *key_steps, - size_t num_curve_keys, - size_t num_steps, - float time, - size_t k0, - size_t k1, - size_t k2, - size_t k3, - float4 r_keys[4]) const -{ - /* Figure out which steps we need to fetch and their interpolation factor. */ - const size_t max_step = num_steps - 1; - const size_t step = min((int)(time * max_step), max_step - 1); - const float t = time * max_step - step; - /* Fetch vertex coordinates. */ - float4 curr_keys[4]; - float4 next_keys[4]; - cardinal_keys_for_step(curve_keys, - curve_radius, - key_steps, - num_curve_keys, - num_steps, - step, - k0, - k1, - k2, - k3, - curr_keys); - cardinal_keys_for_step(curve_keys, - curve_radius, - key_steps, - num_curve_keys, - num_steps, - step + 1, - k0, - k1, - k2, - k3, - next_keys); - /* Interpolate between steps. */ - r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0]; - r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1]; - r_keys[2] = (1.0f - t) * curr_keys[2] + t * next_keys[2]; - r_keys[3] = (1.0f - t) * curr_keys[3] + t * next_keys[3]; -} - -void Mesh::Curve::keys_for_step(const float3 *curve_keys, - const float *curve_radius, - const float3 *key_steps, - size_t num_curve_keys, - size_t num_steps, - size_t step, - size_t k0, - size_t k1, - float4 r_keys[2]) const -{ - k0 = max(k0, 0); - k1 = min(k1, num_keys - 1); - const size_t center_step = ((num_steps - 1) / 2); - if (step == center_step) { - /* Center step: regular key location. */ - /* TODO(sergey): Consider adding make_float4(float3, float) - * function. - */ - r_keys[0] = make_float4(curve_keys[first_key + k0].x, - curve_keys[first_key + k0].y, - curve_keys[first_key + k0].z, - curve_radius[first_key + k0]); - r_keys[1] = make_float4(curve_keys[first_key + k1].x, - curve_keys[first_key + k1].y, - curve_keys[first_key + k1].z, - curve_radius[first_key + k1]); - } - else { - /* Center step is not stored in this array. */ - if (step > center_step) { - step--; - } - const size_t offset = first_key + step * num_curve_keys; - r_keys[0] = make_float4(key_steps[offset + k0].x, - key_steps[offset + k0].y, - key_steps[offset + k0].z, - curve_radius[first_key + k0]); - r_keys[1] = make_float4(key_steps[offset + k1].x, - key_steps[offset + k1].y, - key_steps[offset + k1].z, - curve_radius[first_key + k1]); - } -} - -void Mesh::Curve::cardinal_keys_for_step(const float3 *curve_keys, - const float *curve_radius, - const float3 *key_steps, - size_t num_curve_keys, - size_t num_steps, - size_t step, - size_t k0, - size_t k1, - size_t k2, - size_t k3, - float4 r_keys[4]) const -{ - k0 = max(k0, 0); - k3 = min(k3, num_keys - 1); - const size_t center_step = ((num_steps - 1) / 2); - if (step == center_step) { - /* Center step: regular key location. */ - r_keys[0] = make_float4(curve_keys[first_key + k0].x, - curve_keys[first_key + k0].y, - curve_keys[first_key + k0].z, - curve_radius[first_key + k0]); - r_keys[1] = make_float4(curve_keys[first_key + k1].x, - curve_keys[first_key + k1].y, - curve_keys[first_key + k1].z, - curve_radius[first_key + k1]); - r_keys[2] = make_float4(curve_keys[first_key + k2].x, - curve_keys[first_key + k2].y, - curve_keys[first_key + k2].z, - curve_radius[first_key + k2]); - r_keys[3] = make_float4(curve_keys[first_key + k3].x, - curve_keys[first_key + k3].y, - curve_keys[first_key + k3].z, - curve_radius[first_key + k3]); - } - else { - /* Center step is not stored in this array. */ - if (step > center_step) { - step--; - } - const size_t offset = first_key + step * num_curve_keys; - r_keys[0] = make_float4(key_steps[offset + k0].x, - key_steps[offset + k0].y, - key_steps[offset + k0].z, - curve_radius[first_key + k0]); - r_keys[1] = make_float4(key_steps[offset + k1].x, - key_steps[offset + k1].y, - key_steps[offset + k1].z, - curve_radius[first_key + k1]); - r_keys[2] = make_float4(key_steps[offset + k2].x, - key_steps[offset + k2].y, - key_steps[offset + k2].z, - curve_radius[first_key + k2]); - r_keys[3] = make_float4(key_steps[offset + k3].x, - key_steps[offset + k3].y, - key_steps[offset + k3].z, - curve_radius[first_key + k3]); - } -} - /* SubdFace */ float3 Mesh::SubdFace::normal(const Mesh *mesh) const @@ -392,60 +125,30 @@ float3 Mesh::SubdFace::normal(const Mesh *mesh) const NODE_DEFINE(Mesh) { - NodeType *type = NodeType::add("mesh", create); - - SOCKET_UINT(motion_steps, "Motion Steps", 3); - SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false); + NodeType *type = NodeType::add("mesh", create, NodeType::NONE, Geometry::node_base_type); SOCKET_INT_ARRAY(triangles, "Triangles", array()); SOCKET_POINT_ARRAY(verts, "Vertices", array()); SOCKET_INT_ARRAY(shader, "Shader", array()); SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array()); - SOCKET_POINT_ARRAY(curve_keys, "Curve Keys", array()); - SOCKET_FLOAT_ARRAY(curve_radius, "Curve Radius", array()); - SOCKET_INT_ARRAY(curve_first_key, "Curve First Key", array()); - SOCKET_INT_ARRAY(curve_shader, "Curve Shader", array()); - return type; } -Mesh::Mesh() : Node(node_type) +Mesh::Mesh() : Geometry(node_type, Geometry::MESH) { - need_update = true; - need_update_rebuild = false; - transform_applied = false; - transform_negative_scaled = false; - transform_normal = transform_identity(); - bounds = BoundBox::empty; - - bvh = NULL; - - tri_offset = 0; vert_offset = 0; - curve_offset = 0; - curvekey_offset = 0; - patch_offset = 0; face_offset = 0; corner_offset = 0; - attr_map_offset = 0; - - prim_offset = 0; - num_subd_verts = 0; attributes.triangle_mesh = this; - curve_attributes.curve_mesh = this; subd_attributes.subd_mesh = this; - geometry_flags = GEOMETRY_NONE; - volume_isovalue = 0.001f; - has_volume = false; - has_surface_bssrdf = false; num_ngons = 0; @@ -457,7 +160,6 @@ Mesh::Mesh() : Node(node_type) Mesh::~Mesh() { - delete bvh; delete patch_table; delete subd_params; } @@ -493,26 +195,6 @@ void Mesh::reserve_mesh(int numverts, int numtris) attributes.resize(true); } -void Mesh::resize_curves(int numcurves, int numkeys) -{ - curve_keys.resize(numkeys); - curve_radius.resize(numkeys); - curve_first_key.resize(numcurves); - curve_shader.resize(numcurves); - - curve_attributes.resize(); -} - -void Mesh::reserve_curves(int numcurves, int numkeys) -{ - curve_keys.reserve(numkeys); - curve_radius.reserve(numkeys); - curve_first_key.reserve(numcurves); - curve_shader.reserve(numcurves); - - curve_attributes.resize(true); -} - void Mesh::resize_subd_faces(int numfaces, int num_ngons_, int numcorners) { subd_faces.resize(numfaces); @@ -533,6 +215,8 @@ void Mesh::reserve_subd_faces(int numfaces, int num_ngons_, int numcorners) void Mesh::clear(bool preserve_voxel_data) { + Geometry::clear(); + /* clear all verts and triangles */ verts.clear(); triangles.clear(); @@ -542,11 +226,6 @@ void Mesh::clear(bool preserve_voxel_data) triangle_patch.clear(); vert_patch_uv.clear(); - curve_keys.clear(); - curve_radius.clear(); - curve_first_key.clear(); - curve_shader.clear(); - subd_faces.clear(); subd_face_corners.clear(); @@ -554,27 +233,21 @@ void Mesh::clear(bool preserve_voxel_data) subd_creases.clear(); - curve_attributes.clear(); subd_attributes.clear(); attributes.clear(preserve_voxel_data); - used_shaders.clear(); - vert_to_stitching_key_map.clear(); vert_stitching_map.clear(); - if (!preserve_voxel_data) { - geometry_flags = GEOMETRY_NONE; - } - - transform_applied = false; - transform_negative_scaled = false; - transform_normal = transform_identity(); - delete patch_table; patch_table = NULL; } +void Mesh::clear() +{ + clear(false); +} + void Mesh::add_vertex(float3 P) { verts.push_back_reserved(P); @@ -606,18 +279,6 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) } } -void Mesh::add_curve_key(float3 co, float radius) -{ - curve_keys.push_back_reserved(co); - curve_radius.push_back_reserved(radius); -} - -void Mesh::add_curve(int first_key, int shader) -{ - curve_first_key.push_back_reserved(first_key); - curve_shader.push_back_reserved(shader); -} - void Mesh::add_subd_face(int *corners, int num_corners, int shader_, bool smooth_) { int start_corner = subd_face_corners.size(); @@ -637,47 +298,39 @@ void Mesh::add_subd_face(int *corners, int num_corners, int shader_, bool smooth subd_faces.push_back_reserved(face); } -static void get_uv_tiles_from_attribute(Attribute *attr, int num, unordered_set &tiles) +void Mesh::copy_center_to_motion_step(const int motion_step) { - if (attr == NULL) { - return; - } - - const float2 *uv = attr->data_float2(); - for (int i = 0; i < num; i++, uv++) { - float u = uv->x, v = uv->y; - int x = (int)u, y = (int)v; - - if (x < 0 || y < 0 || x >= 10) { - continue; - } + Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - /* Be conservative in corners - precisely touching the right or upper edge of a tile - * should not load its right/upper neighbor as well. */ - if (x > 0 && (u < x + 1e-6f)) { - x--; - } - if (y > 0 && (v < y + 1e-6f)) { - y--; - } + if (attr_mP) { + Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); + Attribute *attr_N = attributes.find(ATTR_STD_VERTEX_NORMAL); + float3 *P = &verts[0]; + float3 *N = (attr_N) ? attr_N->data_float3() : NULL; + size_t numverts = verts.size(); - tiles.insert(1001 + 10 * y + x); + memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts); + if (attr_mN) + memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts); } } void Mesh::get_uv_tiles(ustring map, unordered_set &tiles) { + Attribute *attr, *subd_attr; + if (map.empty()) { - get_uv_tiles_from_attribute(attributes.find(ATTR_STD_UV), num_triangles() * 3, tiles); - get_uv_tiles_from_attribute( - subd_attributes.find(ATTR_STD_UV), subd_face_corners.size() + num_ngons, tiles); - get_uv_tiles_from_attribute(curve_attributes.find(ATTR_STD_UV), num_curves(), tiles); + attr = attributes.find(ATTR_STD_UV); + subd_attr = subd_attributes.find(ATTR_STD_UV); } else { - get_uv_tiles_from_attribute(attributes.find(map), num_triangles() * 3, tiles); - get_uv_tiles_from_attribute( - subd_attributes.find(map), subd_face_corners.size() + num_ngons, tiles); - get_uv_tiles_from_attribute(curve_attributes.find(map), num_curves(), tiles); + attr = attributes.find(map); + subd_attr = subd_attributes.find(map); + } + + if (attr) { + attr->get_uv_tiles(this, ATTR_PRIM_TRIANGLE, tiles); + subd_attr->get_uv_tiles(this, ATTR_PRIM_SUBD, tiles); } } @@ -685,15 +338,11 @@ void Mesh::compute_bounds() { BoundBox bnds = BoundBox::empty; size_t verts_size = verts.size(); - size_t curve_keys_size = curve_keys.size(); - if (verts_size + curve_keys_size > 0) { + if (verts_size > 0) { for (size_t i = 0; i < verts_size; i++) bnds.grow(verts[i]); - for (size_t i = 0; i < curve_keys_size; i++) - bnds.grow(curve_keys[i], curve_radius[i]); - Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (use_motion_blur && attr) { size_t steps_size = verts.size() * (motion_steps - 1); @@ -703,15 +352,6 @@ void Mesh::compute_bounds() bnds.grow(vert_steps[i]); } - Attribute *curve_attr = curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if (use_motion_blur && curve_attr) { - size_t steps_size = curve_keys.size() * (motion_steps - 1); - float3 *key_steps = curve_attr->data_float3(); - - for (size_t i = 0; i < steps_size; i++) - bnds.grow(key_steps[i]); - } - if (!bnds.valid()) { bnds = BoundBox::empty; @@ -719,9 +359,6 @@ void Mesh::compute_bounds() for (size_t i = 0; i < verts_size; i++) bnds.grow_safe(verts[i]); - for (size_t i = 0; i < curve_keys_size; i++) - bnds.grow_safe(curve_keys[i], curve_radius[i]); - if (use_motion_blur && attr) { size_t steps_size = verts.size() * (motion_steps - 1); float3 *vert_steps = attr->data_float3(); @@ -729,14 +366,6 @@ void Mesh::compute_bounds() for (size_t i = 0; i < steps_size; i++) bnds.grow_safe(vert_steps[i]); } - - if (use_motion_blur && curve_attr) { - size_t steps_size = curve_keys.size() * (motion_steps - 1); - float3 *key_steps = curve_attr->data_float3(); - - for (size_t i = 0; i < steps_size; i++) - bnds.grow_safe(key_steps[i]); - } } } @@ -748,6 +377,38 @@ void Mesh::compute_bounds() bounds = bnds; } +void Mesh::apply_transform(const Transform &tfm, const bool apply_to_motion) +{ + transform_normal = transform_transposed_inverse(tfm); + + /* apply to mesh vertices */ + for (size_t i = 0; i < verts.size(); i++) + verts[i] = transform_point(&tfm, verts[i]); + + if (apply_to_motion) { + Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + + if (attr) { + size_t steps_size = verts.size() * (motion_steps - 1); + float3 *vert_steps = attr->data_float3(); + + for (size_t i = 0; i < steps_size; i++) + vert_steps[i] = transform_point(&tfm, vert_steps[i]); + } + + Attribute *attr_N = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); + + if (attr_N) { + Transform ntfm = transform_normal; + size_t steps_size = verts.size() * (motion_steps - 1); + float3 *normal_steps = attr_N->data_float3(); + + for (size_t i = 0; i < steps_size; i++) + normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i])); + } + } +} + void Mesh::add_face_normals() { /* don't compute if already there */ @@ -975,39 +636,6 @@ void Mesh::pack_verts(const vector &tri_prim_index, } } -void Mesh::pack_curves(Scene *scene, - float4 *curve_key_co, - float4 *curve_data, - size_t curvekey_offset) -{ - size_t curve_keys_size = curve_keys.size(); - - /* pack curve keys */ - if (curve_keys_size) { - float3 *keys_ptr = curve_keys.data(); - float *radius_ptr = curve_radius.data(); - - for (size_t i = 0; i < curve_keys_size; i++) - curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]); - } - - /* pack curve segments */ - size_t curve_num = num_curves(); - - for (size_t i = 0; i < curve_num; i++) { - Curve curve = get_curve(i); - int shader_id = curve_shader[i]; - Shader *shader = (shader_id < used_shaders.size()) ? used_shaders[shader_id] : - scene->default_surface; - shader_id = scene->shader_manager->get_shader_id(shader, false); - - curve_data[i] = make_float4(__int_as_float(curve.first_key + curvekey_offset), - __int_as_float(curve.num_keys), - __int_as_float(shader_id), - 0.0f); - } -} - void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset) { size_t num_faces = subd_faces.size(); @@ -1054,1391 +682,4 @@ void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, ui } } -void Mesh::compute_bvh( - Device *device, DeviceScene *dscene, SceneParams *params, Progress *progress, int n, int total) -{ - if (progress->get_cancel()) - return; - - compute_bounds(); - - const BVHLayout bvh_layout = BVHParams::best_bvh_layout(params->bvh_layout, - device->get_bvh_layout_mask()); - if (need_build_bvh(bvh_layout)) { - string msg = "Updating Mesh BVH "; - if (name.empty()) - msg += string_printf("%u/%u", (uint)(n + 1), (uint)total); - else - msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total); - - Object object; - object.mesh = this; - - vector meshes; - meshes.push_back(this); - vector objects; - objects.push_back(&object); - - if (bvh && !need_update_rebuild) { - progress->set_status(msg, "Refitting BVH"); - - bvh->meshes = meshes; - bvh->objects = objects; - - bvh->refit(*progress); - } - else { - progress->set_status(msg, "Building BVH"); - - BVHParams bparams; - bparams.use_spatial_split = params->use_bvh_spatial_split; - bparams.bvh_layout = bvh_layout; - bparams.use_unaligned_nodes = dscene->data.bvh.have_curves && - params->use_bvh_unaligned_nodes; - bparams.num_motion_triangle_steps = params->num_bvh_time_steps; - bparams.num_motion_curve_steps = params->num_bvh_time_steps; - bparams.bvh_type = params->bvh_type; - bparams.curve_flags = dscene->data.curve.curveflags; - bparams.curve_subdivisions = dscene->data.curve.subdivisions; - - delete bvh; - bvh = BVH::create(bparams, meshes, objects); - MEM_GUARDED_CALL(progress, bvh->build, *progress); - } - } - - need_update = false; - need_update_rebuild = false; -} - -void Mesh::tag_update(Scene *scene, bool rebuild) -{ - need_update = true; - - if (rebuild) { - need_update_rebuild = true; - scene->light_manager->need_update = true; - } - else { - foreach (Shader *shader, used_shaders) - if (shader->has_surface_emission) - scene->light_manager->need_update = true; - } - - scene->mesh_manager->need_update = true; - scene->object_manager->need_update = true; -} - -bool Mesh::has_motion_blur() const -{ - return (use_motion_blur && (attributes.find(ATTR_STD_MOTION_VERTEX_POSITION) || - curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION))); -} - -bool Mesh::has_true_displacement() const -{ - foreach (Shader *shader, used_shaders) { - if (shader->has_displacement && shader->displacement_method != DISPLACE_BUMP) { - return true; - } - } - - return false; -} - -bool Mesh::has_voxel_attributes() const -{ - foreach (const Attribute &attr, attributes.attributes) { - if (attr.element == ATTR_ELEMENT_VOXEL) { - return true; - } - } - - return false; -} - -float Mesh::motion_time(int step) const -{ - return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f; -} - -int Mesh::motion_step(float time) const -{ - if (motion_steps > 1) { - int attr_step = 0; - - for (int step = 0; step < motion_steps; step++) { - float step_time = motion_time(step); - if (step_time == time) { - return attr_step; - } - - /* Center step is stored in a separate attribute. */ - if (step != motion_steps / 2) { - attr_step++; - } - } - } - - return -1; -} - -bool Mesh::need_build_bvh(BVHLayout layout) const -{ - return !transform_applied || has_surface_bssrdf || layout == BVH_LAYOUT_OPTIX; -} - -bool Mesh::is_instanced() const -{ - /* Currently we treat subsurface objects as instanced. - * - * While it might be not very optimal for ray traversal, it avoids having - * duplicated BVH in the memory, saving quite some space. - */ - return !transform_applied || has_surface_bssrdf; -} - -/* Mesh Manager */ - -MeshManager::MeshManager() -{ - need_update = true; - need_flags_update = true; -} - -MeshManager::~MeshManager() -{ -} - -void MeshManager::update_osl_attributes(Device *device, - Scene *scene, - vector &mesh_attributes) -{ -#ifdef WITH_OSL - /* for OSL, a hash map is used to lookup the attribute by name. */ - OSLGlobals *og = (OSLGlobals *)device->osl_memory(); - - og->object_name_map.clear(); - og->attribute_map.clear(); - og->object_names.clear(); - - og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES); - - for (size_t i = 0; i < scene->objects.size(); i++) { - /* set object name to object index map */ - Object *object = scene->objects[i]; - og->object_name_map[object->name] = i; - og->object_names.push_back(object->name); - - /* set object attributes */ - foreach (ParamValue &attr, object->attributes) { - OSLGlobals::Attribute osl_attr; - - osl_attr.type = attr.type(); - osl_attr.desc.element = ATTR_ELEMENT_OBJECT; - osl_attr.value = attr; - osl_attr.desc.offset = 0; - osl_attr.desc.flags = 0; - - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][attr.name()] = osl_attr; - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr; - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr; - } - - /* find mesh attributes */ - size_t j; - - for (j = 0; j < scene->meshes.size(); j++) - if (scene->meshes[j] == object->mesh) - break; - - AttributeRequestSet &attributes = mesh_attributes[j]; - - /* set object attributes */ - foreach (AttributeRequest &req, attributes.requests) { - OSLGlobals::Attribute osl_attr; - - if (req.triangle_desc.element != ATTR_ELEMENT_NONE) { - osl_attr.desc = req.triangle_desc; - - if (req.triangle_type == TypeDesc::TypeFloat) - osl_attr.type = TypeDesc::TypeFloat; - else if (req.triangle_type == TypeDesc::TypeMatrix) - osl_attr.type = TypeDesc::TypeMatrix; - else if (req.triangle_type == TypeFloat2) - osl_attr.type = TypeFloat2; - else if (req.triangle_type == TypeRGBA) - osl_attr.type = TypeRGBA; - else - osl_attr.type = TypeDesc::TypeColor; - - if (req.std != ATTR_STD_NONE) { - /* if standard attribute, add lookup by geom: name convention */ - ustring stdname(string("geom:") + string(Attribute::standard_name(req.std))); - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][stdname] = osl_attr; - } - else if (req.name != ustring()) { - /* add lookup by mesh attribute name */ - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][req.name] = osl_attr; - } - } - - if (req.curve_desc.element != ATTR_ELEMENT_NONE) { - osl_attr.desc = req.curve_desc; - - if (req.curve_type == TypeDesc::TypeFloat) - osl_attr.type = TypeDesc::TypeFloat; - else if (req.curve_type == TypeDesc::TypeMatrix) - osl_attr.type = TypeDesc::TypeMatrix; - else if (req.curve_type == TypeFloat2) - osl_attr.type = TypeFloat2; - else if (req.curve_type == TypeRGBA) - osl_attr.type = TypeRGBA; - else - osl_attr.type = TypeDesc::TypeColor; - - if (req.std != ATTR_STD_NONE) { - /* if standard attribute, add lookup by geom: name convention */ - ustring stdname(string("geom:") + string(Attribute::standard_name(req.std))); - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr; - } - else if (req.name != ustring()) { - /* add lookup by mesh attribute name */ - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr; - } - } - - if (req.subd_desc.element != ATTR_ELEMENT_NONE) { - osl_attr.desc = req.subd_desc; - - if (req.subd_type == TypeDesc::TypeFloat) - osl_attr.type = TypeDesc::TypeFloat; - else if (req.subd_type == TypeDesc::TypeMatrix) - osl_attr.type = TypeDesc::TypeMatrix; - else if (req.subd_type == TypeFloat2) - osl_attr.type = TypeFloat2; - else if (req.subd_type == TypeRGBA) - osl_attr.type = TypeRGBA; - else - osl_attr.type = TypeDesc::TypeColor; - - if (req.std != ATTR_STD_NONE) { - /* if standard attribute, add lookup by geom: name convention */ - ustring stdname(string("geom:") + string(Attribute::standard_name(req.std))); - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr; - } - else if (req.name != ustring()) { - /* add lookup by mesh attribute name */ - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr; - } - } - } - } -#else - (void)device; - (void)scene; - (void)mesh_attributes; -#endif -} - -void MeshManager::update_svm_attributes(Device *, - DeviceScene *dscene, - Scene *scene, - vector &mesh_attributes) -{ - /* for SVM, the attributes_map table is used to lookup the offset of an - * attribute, based on a unique shader attribute id. */ - - /* compute array stride */ - int attr_map_size = 0; - - for (size_t i = 0; i < scene->meshes.size(); i++) { - Mesh *mesh = scene->meshes[i]; - mesh->attr_map_offset = attr_map_size; - attr_map_size += (mesh_attributes[i].size() + 1) * ATTR_PRIM_TYPES; - } - - if (attr_map_size == 0) - return; - - /* create attribute map */ - uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size); - memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint)); - - for (size_t i = 0; i < scene->meshes.size(); i++) { - Mesh *mesh = scene->meshes[i]; - AttributeRequestSet &attributes = mesh_attributes[i]; - - /* set object attributes */ - int index = mesh->attr_map_offset; - - foreach (AttributeRequest &req, attributes.requests) { - uint id; - - if (req.std == ATTR_STD_NONE) - id = scene->shader_manager->get_attribute_id(req.name); - else - id = scene->shader_manager->get_attribute_id(req.std); - - if (mesh->num_triangles()) { - attr_map[index].x = id; - attr_map[index].y = req.triangle_desc.element; - attr_map[index].z = as_uint(req.triangle_desc.offset); - - if (req.triangle_type == TypeDesc::TypeFloat) - attr_map[index].w = NODE_ATTR_FLOAT; - else if (req.triangle_type == TypeDesc::TypeMatrix) - attr_map[index].w = NODE_ATTR_MATRIX; - else if (req.triangle_type == TypeFloat2) - attr_map[index].w = NODE_ATTR_FLOAT2; - else if (req.triangle_type == TypeRGBA) - attr_map[index].w = NODE_ATTR_RGBA; - else - attr_map[index].w = NODE_ATTR_FLOAT3; - - attr_map[index].w |= req.triangle_desc.flags << 8; - } - - index++; - - if (mesh->num_curves()) { - attr_map[index].x = id; - attr_map[index].y = req.curve_desc.element; - attr_map[index].z = as_uint(req.curve_desc.offset); - - if (req.curve_type == TypeDesc::TypeFloat) - attr_map[index].w = NODE_ATTR_FLOAT; - else if (req.curve_type == TypeDesc::TypeMatrix) - attr_map[index].w = NODE_ATTR_MATRIX; - else if (req.curve_type == TypeFloat2) - attr_map[index].w = NODE_ATTR_FLOAT2; - else - attr_map[index].w = NODE_ATTR_FLOAT3; - - attr_map[index].w |= req.curve_desc.flags << 8; - } - - index++; - - if (mesh->subd_faces.size()) { - attr_map[index].x = id; - attr_map[index].y = req.subd_desc.element; - attr_map[index].z = as_uint(req.subd_desc.offset); - - if (req.subd_type == TypeDesc::TypeFloat) - attr_map[index].w = NODE_ATTR_FLOAT; - else if (req.subd_type == TypeDesc::TypeMatrix) - attr_map[index].w = NODE_ATTR_MATRIX; - else if (req.subd_type == TypeFloat2) - attr_map[index].w = NODE_ATTR_FLOAT2; - else if (req.triangle_type == TypeRGBA) - attr_map[index].w = NODE_ATTR_RGBA; - else - attr_map[index].w = NODE_ATTR_FLOAT3; - - attr_map[index].w |= req.subd_desc.flags << 8; - } - - index++; - } - - /* terminator */ - for (int j = 0; j < ATTR_PRIM_TYPES; j++) { - attr_map[index].x = ATTR_STD_NONE; - attr_map[index].y = 0; - attr_map[index].z = 0; - attr_map[index].w = 0; - - index++; - } - } - - /* copy to device */ - dscene->attributes_map.copy_to_device(); -} - -static void update_attribute_element_size(Mesh *mesh, - Attribute *mattr, - AttributePrimitive prim, - size_t *attr_float_size, - size_t *attr_float2_size, - size_t *attr_float3_size, - size_t *attr_uchar4_size) -{ - if (mattr) { - size_t size = mattr->element_size(mesh, prim); - - if (mattr->element == ATTR_ELEMENT_VOXEL) { - /* pass */ - } - else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) { - *attr_uchar4_size += size; - } - else if (mattr->type == TypeDesc::TypeFloat) { - *attr_float_size += size; - } - else if (mattr->type == TypeFloat2) { - *attr_float2_size += size; - } - else if (mattr->type == TypeDesc::TypeMatrix) { - *attr_float3_size += size * 4; - } - else { - *attr_float3_size += size; - } - } -} - -static void update_attribute_element_offset(Mesh *mesh, - device_vector &attr_float, - size_t &attr_float_offset, - device_vector &attr_float2, - size_t &attr_float2_offset, - device_vector &attr_float3, - size_t &attr_float3_offset, - device_vector &attr_uchar4, - size_t &attr_uchar4_offset, - Attribute *mattr, - AttributePrimitive prim, - TypeDesc &type, - AttributeDescriptor &desc) -{ - if (mattr) { - /* store element and type */ - desc.element = mattr->element; - desc.flags = mattr->flags; - type = mattr->type; - - /* store attribute data in arrays */ - size_t size = mattr->element_size(mesh, prim); - - AttributeElement &element = desc.element; - int &offset = desc.offset; - - if (mattr->element == ATTR_ELEMENT_VOXEL) { - /* store slot in offset value */ - VoxelAttribute *voxel_data = mattr->data_voxel(); - offset = voxel_data->slot; - } - else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) { - uchar4 *data = mattr->data_uchar4(); - offset = attr_uchar4_offset; - - assert(attr_uchar4.size() >= offset + size); - for (size_t k = 0; k < size; k++) { - attr_uchar4[offset + k] = data[k]; - } - attr_uchar4_offset += size; - } - else if (mattr->type == TypeDesc::TypeFloat) { - float *data = mattr->data_float(); - offset = attr_float_offset; - - assert(attr_float.size() >= offset + size); - for (size_t k = 0; k < size; k++) { - attr_float[offset + k] = data[k]; - } - attr_float_offset += size; - } - else if (mattr->type == TypeFloat2) { - float2 *data = mattr->data_float2(); - offset = attr_float2_offset; - - assert(attr_float2.size() >= offset + size); - for (size_t k = 0; k < size; k++) { - attr_float2[offset + k] = data[k]; - } - attr_float2_offset += size; - } - else if (mattr->type == TypeDesc::TypeMatrix) { - Transform *tfm = mattr->data_transform(); - offset = attr_float3_offset; - - assert(attr_float3.size() >= offset + size * 3); - for (size_t k = 0; k < size * 3; k++) { - attr_float3[offset + k] = (&tfm->x)[k]; - } - attr_float3_offset += size * 3; - } - else { - float4 *data = mattr->data_float4(); - offset = attr_float3_offset; - - assert(attr_float3.size() >= offset + size); - for (size_t k = 0; k < size; k++) { - attr_float3[offset + k] = data[k]; - } - attr_float3_offset += size; - } - - /* mesh vertex/curve index is global, not per object, so we sneak - * a correction for that in here */ - if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK && - desc.flags & ATTR_SUBDIVIDED) { - /* indices for subdivided attributes are retrieved - * from patch table so no need for correction here*/ - } - else if (element == ATTR_ELEMENT_VERTEX) - offset -= mesh->vert_offset; - else if (element == ATTR_ELEMENT_VERTEX_MOTION) - offset -= mesh->vert_offset; - else if (element == ATTR_ELEMENT_FACE) { - if (prim == ATTR_PRIM_TRIANGLE) - offset -= mesh->tri_offset; - else - offset -= mesh->face_offset; - } - else if (element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE) { - if (prim == ATTR_PRIM_TRIANGLE) - offset -= 3 * mesh->tri_offset; - else - offset -= mesh->corner_offset; - } - else if (element == ATTR_ELEMENT_CURVE) - offset -= mesh->curve_offset; - else if (element == ATTR_ELEMENT_CURVE_KEY) - offset -= mesh->curvekey_offset; - else if (element == ATTR_ELEMENT_CURVE_KEY_MOTION) - offset -= mesh->curvekey_offset; - } - else { - /* attribute not found */ - desc.element = ATTR_ELEMENT_NONE; - desc.offset = 0; - } -} - -void MeshManager::device_update_attributes(Device *device, - DeviceScene *dscene, - Scene *scene, - Progress &progress) -{ - progress.set_status("Updating Mesh", "Computing attributes"); - - /* gather per mesh requested attributes. as meshes may have multiple - * shaders assigned, this merges the requested attributes that have - * been set per shader by the shader manager */ - vector mesh_attributes(scene->meshes.size()); - - for (size_t i = 0; i < scene->meshes.size(); i++) { - Mesh *mesh = scene->meshes[i]; - - scene->need_global_attributes(mesh_attributes[i]); - - foreach (Shader *shader, mesh->used_shaders) { - mesh_attributes[i].add(shader->attributes); - } - } - - /* mesh attribute are stored in a single array per data type. here we fill - * those arrays, and set the offset and element type to create attribute - * maps next */ - - /* Pre-allocate attributes to avoid arrays re-allocation which would - * take 2x of overall attribute memory usage. - */ - size_t attr_float_size = 0; - size_t attr_float2_size = 0; - size_t attr_float3_size = 0; - size_t attr_uchar4_size = 0; - for (size_t i = 0; i < scene->meshes.size(); i++) { - Mesh *mesh = scene->meshes[i]; - AttributeRequestSet &attributes = mesh_attributes[i]; - foreach (AttributeRequest &req, attributes.requests) { - Attribute *triangle_mattr = mesh->attributes.find(req); - Attribute *curve_mattr = mesh->curve_attributes.find(req); - Attribute *subd_mattr = mesh->subd_attributes.find(req); - - update_attribute_element_size(mesh, - triangle_mattr, - ATTR_PRIM_TRIANGLE, - &attr_float_size, - &attr_float2_size, - &attr_float3_size, - &attr_uchar4_size); - update_attribute_element_size(mesh, - curve_mattr, - ATTR_PRIM_CURVE, - &attr_float_size, - &attr_float2_size, - &attr_float3_size, - &attr_uchar4_size); - update_attribute_element_size(mesh, - subd_mattr, - ATTR_PRIM_SUBD, - &attr_float_size, - &attr_float2_size, - &attr_float3_size, - &attr_uchar4_size); - } - } - - dscene->attributes_float.alloc(attr_float_size); - dscene->attributes_float2.alloc(attr_float2_size); - dscene->attributes_float3.alloc(attr_float3_size); - dscene->attributes_uchar4.alloc(attr_uchar4_size); - - size_t attr_float_offset = 0; - size_t attr_float2_offset = 0; - size_t attr_float3_offset = 0; - size_t attr_uchar4_offset = 0; - - /* Fill in attributes. */ - for (size_t i = 0; i < scene->meshes.size(); i++) { - Mesh *mesh = scene->meshes[i]; - AttributeRequestSet &attributes = mesh_attributes[i]; - - /* todo: we now store std and name attributes from requests even if - * they actually refer to the same mesh attributes, optimize */ - foreach (AttributeRequest &req, attributes.requests) { - Attribute *triangle_mattr = mesh->attributes.find(req); - Attribute *curve_mattr = mesh->curve_attributes.find(req); - Attribute *subd_mattr = mesh->subd_attributes.find(req); - - update_attribute_element_offset(mesh, - dscene->attributes_float, - attr_float_offset, - dscene->attributes_float2, - attr_float2_offset, - dscene->attributes_float3, - attr_float3_offset, - dscene->attributes_uchar4, - attr_uchar4_offset, - triangle_mattr, - ATTR_PRIM_TRIANGLE, - req.triangle_type, - req.triangle_desc); - - update_attribute_element_offset(mesh, - dscene->attributes_float, - attr_float_offset, - dscene->attributes_float2, - attr_float2_offset, - dscene->attributes_float3, - attr_float3_offset, - dscene->attributes_uchar4, - attr_uchar4_offset, - curve_mattr, - ATTR_PRIM_CURVE, - req.curve_type, - req.curve_desc); - - update_attribute_element_offset(mesh, - dscene->attributes_float, - attr_float_offset, - dscene->attributes_float2, - attr_float2_offset, - dscene->attributes_float3, - attr_float3_offset, - dscene->attributes_uchar4, - attr_uchar4_offset, - subd_mattr, - ATTR_PRIM_SUBD, - req.subd_type, - req.subd_desc); - - if (progress.get_cancel()) - return; - } - } - - /* create attribute lookup maps */ - if (scene->shader_manager->use_osl()) - update_osl_attributes(device, scene, mesh_attributes); - - update_svm_attributes(device, dscene, scene, mesh_attributes); - - if (progress.get_cancel()) - return; - - /* copy to device */ - progress.set_status("Updating Mesh", "Copying Attributes to device"); - - if (dscene->attributes_float.size()) { - dscene->attributes_float.copy_to_device(); - } - if (dscene->attributes_float2.size()) { - dscene->attributes_float2.copy_to_device(); - } - if (dscene->attributes_float3.size()) { - dscene->attributes_float3.copy_to_device(); - } - if (dscene->attributes_uchar4.size()) { - dscene->attributes_uchar4.copy_to_device(); - } - - if (progress.get_cancel()) - return; - - /* After mesh attributes and patch tables have been copied to device memory, - * we need to update offsets in the objects. */ - scene->object_manager->device_update_mesh_offsets(device, dscene, scene); -} - -void MeshManager::mesh_calc_offset(Scene *scene) -{ - size_t vert_size = 0; - size_t tri_size = 0; - - size_t curve_key_size = 0; - size_t curve_size = 0; - - size_t patch_size = 0; - size_t face_size = 0; - size_t corner_size = 0; - - size_t prim_size = 0; - - foreach (Mesh *mesh, scene->meshes) { - mesh->vert_offset = vert_size; - mesh->tri_offset = tri_size; - - mesh->curvekey_offset = curve_key_size; - mesh->curve_offset = curve_size; - - mesh->patch_offset = patch_size; - mesh->face_offset = face_size; - mesh->corner_offset = corner_size; - - vert_size += mesh->verts.size(); - tri_size += mesh->num_triangles(); - - curve_key_size += mesh->curve_keys.size(); - curve_size += mesh->num_curves(); - - if (mesh->subd_faces.size()) { - Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1]; - patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8; - - /* patch tables are stored in same array so include them in patch_size */ - if (mesh->patch_table) { - mesh->patch_table_offset = patch_size; - patch_size += mesh->patch_table->total_size(); - } - } - face_size += mesh->subd_faces.size(); - corner_size += mesh->subd_face_corners.size(); - - mesh->prim_offset = prim_size; - prim_size += mesh->num_primitives(); - } -} - -void MeshManager::device_update_mesh( - Device *, DeviceScene *dscene, Scene *scene, bool for_displacement, Progress &progress) -{ - /* Count. */ - size_t vert_size = 0; - size_t tri_size = 0; - - size_t curve_key_size = 0; - size_t curve_size = 0; - - size_t patch_size = 0; - - foreach (Mesh *mesh, scene->meshes) { - vert_size += mesh->verts.size(); - tri_size += mesh->num_triangles(); - - curve_key_size += mesh->curve_keys.size(); - curve_size += mesh->num_curves(); - - if (mesh->subd_faces.size()) { - Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1]; - patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8; - - /* patch tables are stored in same array so include them in patch_size */ - if (mesh->patch_table) { - mesh->patch_table_offset = patch_size; - patch_size += mesh->patch_table->total_size(); - } - } - } - - /* Create mapping from triangle to primitive triangle array. */ - vector tri_prim_index(tri_size); - if (for_displacement) { - /* For displacement kernels we do some trickery to make them believe - * we've got all required data ready. However, that data is different - * from final render kernels since we don't have BVH yet, so can't - * really use same semantic of arrays. - */ - foreach (Mesh *mesh, scene->meshes) { - for (size_t i = 0; i < mesh->num_triangles(); ++i) { - tri_prim_index[i + mesh->tri_offset] = 3 * (i + mesh->tri_offset); - } - } - } - else { - for (size_t i = 0; i < dscene->prim_index.size(); ++i) { - if ((dscene->prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) { - tri_prim_index[dscene->prim_index[i]] = dscene->prim_tri_index[i]; - } - } - } - - /* Fill in all the arrays. */ - if (tri_size != 0) { - /* normals */ - progress.set_status("Updating Mesh", "Computing normals"); - - uint *tri_shader = dscene->tri_shader.alloc(tri_size); - float4 *vnormal = dscene->tri_vnormal.alloc(vert_size); - uint4 *tri_vindex = dscene->tri_vindex.alloc(tri_size); - uint *tri_patch = dscene->tri_patch.alloc(tri_size); - float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size); - - foreach (Mesh *mesh, scene->meshes) { - mesh->pack_shaders(scene, &tri_shader[mesh->tri_offset]); - mesh->pack_normals(&vnormal[mesh->vert_offset]); - mesh->pack_verts(tri_prim_index, - &tri_vindex[mesh->tri_offset], - &tri_patch[mesh->tri_offset], - &tri_patch_uv[mesh->vert_offset], - mesh->vert_offset, - mesh->tri_offset); - if (progress.get_cancel()) - return; - } - - /* vertex coordinates */ - progress.set_status("Updating Mesh", "Copying Mesh to device"); - - dscene->tri_shader.copy_to_device(); - dscene->tri_vnormal.copy_to_device(); - dscene->tri_vindex.copy_to_device(); - dscene->tri_patch.copy_to_device(); - dscene->tri_patch_uv.copy_to_device(); - } - - if (curve_size != 0) { - progress.set_status("Updating Mesh", "Copying Strands to device"); - - float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size); - float4 *curves = dscene->curves.alloc(curve_size); - - foreach (Mesh *mesh, scene->meshes) { - mesh->pack_curves(scene, - &curve_keys[mesh->curvekey_offset], - &curves[mesh->curve_offset], - mesh->curvekey_offset); - if (progress.get_cancel()) - return; - } - - dscene->curve_keys.copy_to_device(); - dscene->curves.copy_to_device(); - } - - if (patch_size != 0) { - progress.set_status("Updating Mesh", "Copying Patches to device"); - - uint *patch_data = dscene->patches.alloc(patch_size); - - foreach (Mesh *mesh, scene->meshes) { - mesh->pack_patches(&patch_data[mesh->patch_offset], - mesh->vert_offset, - mesh->face_offset, - mesh->corner_offset); - - if (mesh->patch_table) { - mesh->patch_table->copy_adjusting_offsets(&patch_data[mesh->patch_table_offset], - mesh->patch_table_offset); - } - - if (progress.get_cancel()) - return; - } - - dscene->patches.copy_to_device(); - } - - if (for_displacement) { - float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3); - foreach (Mesh *mesh, scene->meshes) { - for (size_t i = 0; i < mesh->num_triangles(); ++i) { - Mesh::Triangle t = mesh->get_triangle(i); - size_t offset = 3 * (i + mesh->tri_offset); - prim_tri_verts[offset + 0] = float3_to_float4(mesh->verts[t.v[0]]); - prim_tri_verts[offset + 1] = float3_to_float4(mesh->verts[t.v[1]]); - prim_tri_verts[offset + 2] = float3_to_float4(mesh->verts[t.v[2]]); - } - } - dscene->prim_tri_verts.copy_to_device(); - } -} - -void MeshManager::device_update_bvh(Device *device, - DeviceScene *dscene, - Scene *scene, - Progress &progress) -{ - /* bvh build */ - progress.set_status("Updating Scene BVH", "Building"); - - BVHParams bparams; - bparams.top_level = true; - bparams.bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout, - device->get_bvh_layout_mask()); - bparams.use_spatial_split = scene->params.use_bvh_spatial_split; - bparams.use_unaligned_nodes = dscene->data.bvh.have_curves && - scene->params.use_bvh_unaligned_nodes; - bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps; - bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps; - bparams.bvh_type = scene->params.bvh_type; - bparams.curve_flags = dscene->data.curve.curveflags; - bparams.curve_subdivisions = dscene->data.curve.subdivisions; - - VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout."; - -#ifdef WITH_EMBREE - if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) { - if (dscene->data.bvh.scene) { - BVHEmbree::destroy(dscene->data.bvh.scene); - } - } -#endif - - BVH *bvh = BVH::create(bparams, scene->meshes, scene->objects); - bvh->build(progress, &device->stats); - - if (progress.get_cancel()) { -#ifdef WITH_EMBREE - if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) { - if (dscene->data.bvh.scene) { - BVHEmbree::destroy(dscene->data.bvh.scene); - } - } -#endif - delete bvh; - return; - } - - /* copy to device */ - progress.set_status("Updating Scene BVH", "Copying BVH to device"); - - PackedBVH &pack = bvh->pack; - - if (pack.nodes.size()) { - dscene->bvh_nodes.steal_data(pack.nodes); - dscene->bvh_nodes.copy_to_device(); - } - if (pack.leaf_nodes.size()) { - dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes); - dscene->bvh_leaf_nodes.copy_to_device(); - } - if (pack.object_node.size()) { - dscene->object_node.steal_data(pack.object_node); - dscene->object_node.copy_to_device(); - } - if (pack.prim_tri_index.size()) { - dscene->prim_tri_index.steal_data(pack.prim_tri_index); - dscene->prim_tri_index.copy_to_device(); - } - if (pack.prim_tri_verts.size()) { - dscene->prim_tri_verts.steal_data(pack.prim_tri_verts); - dscene->prim_tri_verts.copy_to_device(); - } - if (pack.prim_type.size()) { - dscene->prim_type.steal_data(pack.prim_type); - dscene->prim_type.copy_to_device(); - } - if (pack.prim_visibility.size()) { - dscene->prim_visibility.steal_data(pack.prim_visibility); - dscene->prim_visibility.copy_to_device(); - } - if (pack.prim_index.size()) { - dscene->prim_index.steal_data(pack.prim_index); - dscene->prim_index.copy_to_device(); - } - if (pack.prim_object.size()) { - dscene->prim_object.steal_data(pack.prim_object); - dscene->prim_object.copy_to_device(); - } - if (pack.prim_time.size()) { - dscene->prim_time.steal_data(pack.prim_time); - dscene->prim_time.copy_to_device(); - } - - dscene->data.bvh.root = pack.root_index; - dscene->data.bvh.bvh_layout = bparams.bvh_layout; - dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0); - - bvh->copy_to_device(progress, dscene); - - delete bvh; -} - -void MeshManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress) -{ - if (!need_update && !need_flags_update) { - return; - } - - progress.set_status("Updating Meshes Flags"); - - /* Update flags. */ - bool volume_images_updated = false; - - foreach (Mesh *mesh, scene->meshes) { - mesh->has_volume = false; - - foreach (const Shader *shader, mesh->used_shaders) { - if (shader->has_volume) { - mesh->has_volume = true; - } - if (shader->has_surface_bssrdf) { - mesh->has_surface_bssrdf = true; - } - } - - if (need_update && mesh->has_volume) { - /* Create volume meshes if there is voxel data. */ - if (mesh->has_voxel_attributes()) { - if (!volume_images_updated) { - progress.set_status("Updating Meshes Volume Bounds"); - device_update_volume_images(device, scene, progress); - volume_images_updated = true; - } - - create_volume_mesh(scene, mesh, progress); - } - } - } - - need_flags_update = false; -} - -void MeshManager::device_update_displacement_images(Device *device, - Scene *scene, - Progress &progress) -{ - progress.set_status("Updating Displacement Images"); - TaskPool pool; - ImageManager *image_manager = scene->image_manager; - set bump_images; - foreach (Mesh *mesh, scene->meshes) { - if (mesh->need_update) { - foreach (Shader *shader, mesh->used_shaders) { - if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) { - continue; - } - foreach (ShaderNode *node, shader->graph->nodes) { - if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) { - continue; - } - - ImageSlotTextureNode *image_node = static_cast(node); - foreach (int slot, image_node->slots) { - if (slot != -1) { - bump_images.insert(slot); - } - } - } - } - } - } - foreach (int slot, bump_images) { - pool.push(function_bind( - &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress)); - } - pool.wait_work(); -} - -void MeshManager::device_update_volume_images(Device *device, Scene *scene, Progress &progress) -{ - progress.set_status("Updating Volume Images"); - TaskPool pool; - ImageManager *image_manager = scene->image_manager; - set volume_images; - - foreach (Mesh *mesh, scene->meshes) { - if (!mesh->need_update) { - continue; - } - - foreach (Attribute &attr, mesh->attributes.attributes) { - if (attr.element != ATTR_ELEMENT_VOXEL) { - continue; - } - - VoxelAttribute *voxel = attr.data_voxel(); - - if (voxel->slot != -1) { - volume_images.insert(voxel->slot); - } - } - } - - foreach (int slot, volume_images) { - pool.push(function_bind( - &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress)); - } - pool.wait_work(); -} - -void MeshManager::device_update(Device *device, - DeviceScene *dscene, - Scene *scene, - Progress &progress) -{ - if (!need_update) - return; - - VLOG(1) << "Total " << scene->meshes.size() << " meshes."; - - bool true_displacement_used = false; - size_t total_tess_needed = 0; - - foreach (Mesh *mesh, scene->meshes) { - foreach (Shader *shader, mesh->used_shaders) { - if (shader->need_update_mesh) - mesh->need_update = true; - } - - if (mesh->need_update) { - /* Update normals. */ - mesh->add_face_normals(); - mesh->add_vertex_normals(); - - if (mesh->need_attribute(scene, ATTR_STD_POSITION_UNDISPLACED)) { - mesh->add_undisplaced(); - } - - /* Test if we need tessellation. */ - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 && - mesh->subd_params) { - total_tess_needed++; - } - - /* Test if we need displacement. */ - if (mesh->has_true_displacement()) { - true_displacement_used = true; - } - - if (progress.get_cancel()) - return; - } - } - - /* Tessellate meshes that are using subdivision */ - if (total_tess_needed) { - Camera *dicing_camera = scene->dicing_camera; - dicing_camera->update(scene); - - size_t i = 0; - foreach (Mesh *mesh, scene->meshes) { - if (mesh->need_update && mesh->subdivision_type != Mesh::SUBDIVISION_NONE && - mesh->num_subd_verts == 0 && mesh->subd_params) { - string msg = "Tessellating "; - if (mesh->name == "") - msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed); - else - msg += string_printf( - "%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)total_tess_needed); - - progress.set_status("Updating Mesh", msg); - - mesh->subd_params->camera = dicing_camera; - DiagSplit dsplit(*mesh->subd_params); - mesh->tessellate(&dsplit); - - i++; - - if (progress.get_cancel()) - return; - } - } - } - - /* Update images needed for true displacement. */ - bool old_need_object_flags_update = false; - if (true_displacement_used) { - VLOG(1) << "Updating images used for true displacement."; - device_update_displacement_images(device, scene, progress); - old_need_object_flags_update = scene->object_manager->need_flags_update; - scene->object_manager->device_update_flags(device, dscene, scene, progress, false); - } - - /* Device update. */ - device_free(device, dscene); - - mesh_calc_offset(scene); - if (true_displacement_used) { - device_update_mesh(device, dscene, scene, true, progress); - } - if (progress.get_cancel()) - return; - - device_update_attributes(device, dscene, scene, progress); - if (progress.get_cancel()) - return; - - /* Update displacement. */ - bool displacement_done = false; - size_t num_bvh = 0; - BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout, - device->get_bvh_layout_mask()); - - foreach (Mesh *mesh, scene->meshes) { - if (mesh->need_update) { - if (displace(device, dscene, scene, mesh, progress)) { - displacement_done = true; - } - - if (mesh->need_build_bvh(bvh_layout)) { - num_bvh++; - } - } - - if (progress.get_cancel()) - return; - } - - /* Device re-update after displacement. */ - if (displacement_done) { - device_free(device, dscene); - - device_update_attributes(device, dscene, scene, progress); - if (progress.get_cancel()) - return; - } - - TaskPool pool; - - size_t i = 0; - foreach (Mesh *mesh, scene->meshes) { - if (mesh->need_update) { - pool.push(function_bind( - &Mesh::compute_bvh, mesh, device, dscene, &scene->params, &progress, i, num_bvh)); - if (mesh->need_build_bvh(bvh_layout)) { - i++; - } - } - } - - TaskPool::Summary summary; - pool.wait_work(&summary); - VLOG(2) << "Objects BVH build pool statistics:\n" << summary.full_report(); - - foreach (Shader *shader, scene->shaders) { - shader->need_update_mesh = false; - } - - Scene::MotionType need_motion = scene->need_motion(); - bool motion_blur = need_motion == Scene::MOTION_BLUR; - - /* Update objects. */ - vector volume_objects; - foreach (Object *object, scene->objects) { - object->compute_bounds(motion_blur); - } - - if (progress.get_cancel()) - return; - - device_update_bvh(device, dscene, scene, progress); - if (progress.get_cancel()) - return; - - device_update_mesh(device, dscene, scene, false, progress); - if (progress.get_cancel()) - return; - - need_update = false; - - if (true_displacement_used) { - /* Re-tag flags for update, so they're re-evaluated - * for meshes with correct bounding boxes. - * - * This wouldn't cause wrong results, just true - * displacement might be less optimal ot calculate. - */ - scene->object_manager->need_flags_update = old_need_object_flags_update; - } -} - -void MeshManager::device_free(Device *device, DeviceScene *dscene) -{ - dscene->bvh_nodes.free(); - dscene->bvh_leaf_nodes.free(); - dscene->object_node.free(); - dscene->prim_tri_verts.free(); - dscene->prim_tri_index.free(); - dscene->prim_type.free(); - dscene->prim_visibility.free(); - dscene->prim_index.free(); - dscene->prim_object.free(); - dscene->prim_time.free(); - dscene->tri_shader.free(); - dscene->tri_vnormal.free(); - dscene->tri_vindex.free(); - dscene->tri_patch.free(); - dscene->tri_patch_uv.free(); - dscene->curves.free(); - dscene->curve_keys.free(); - dscene->patches.free(); - dscene->attributes_map.free(); - dscene->attributes_float.free(); - dscene->attributes_float2.free(); - dscene->attributes_float3.free(); - dscene->attributes_uchar4.free(); - - /* Signal for shaders like displacement not to do ray tracing. */ - dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE; - -#ifdef WITH_OSL - OSLGlobals *og = (OSLGlobals *)device->osl_memory(); - - if (og) { - og->object_name_map.clear(); - og->attribute_map.clear(); - og->object_names.clear(); - } -#else - (void)device; -#endif -} - -void MeshManager::tag_update(Scene *scene) -{ - need_update = true; - scene->object_manager->need_update = true; -} - -void MeshManager::collect_statistics(const Scene *scene, RenderStats *stats) -{ - foreach (Mesh *mesh, scene->meshes) { - stats->mesh.geometry.add_entry( - NamedSizeEntry(string(mesh->name.c_str()), mesh->get_total_size_in_bytes())); - } -} - -bool Mesh::need_attribute(Scene *scene, AttributeStandard std) -{ - if (std == ATTR_STD_NONE) - return false; - - if (scene->need_global_attribute(std)) - return true; - - foreach (Shader *shader, used_shaders) - if (shader->attributes.find(std)) - return true; - - return false; -} - -bool Mesh::need_attribute(Scene * /*scene*/, ustring name) -{ - if (name == ustring()) - return false; - - foreach (Shader *shader, used_shaders) - if (shader->attributes.find(name)) - return true; - - return false; -} - CCL_NAMESPACE_END diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index c5be0ba60b9..5583e9c0400 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -21,6 +21,7 @@ #include "bvh/bvh_params.h" #include "render/attribute.h" +#include "render/geometry.h" #include "render/shader.h" #include "util/util_array.h" @@ -29,7 +30,6 @@ #include "util/util_map.h" #include "util/util_param.h" #include "util/util_set.h" -#include "util/util_transform.h" #include "util/util_types.h" #include "util/util_vector.h" @@ -51,7 +51,7 @@ struct PackedPatchTable; /* Mesh */ -class Mesh : public Node { +class Mesh : public Geometry { public: NODE_DECLARE @@ -91,94 +91,6 @@ class Mesh : public Node { return triangles.size() / 3; } - /* Mesh Curve */ - struct Curve { - int first_key; - int num_keys; - - int num_segments() const - { - return num_keys - 1; - } - - void bounds_grow(const int k, - const float3 *curve_keys, - const float *curve_radius, - BoundBox &bounds) const; - void bounds_grow(float4 keys[4], BoundBox &bounds) const; - void bounds_grow(const int k, - const float3 *curve_keys, - const float *curve_radius, - const Transform &aligned_space, - BoundBox &bounds) const; - - void motion_keys(const float3 *curve_keys, - const float *curve_radius, - const float3 *key_steps, - size_t num_curve_keys, - size_t num_steps, - float time, - size_t k0, - size_t k1, - float4 r_keys[2]) const; - void cardinal_motion_keys(const float3 *curve_keys, - const float *curve_radius, - const float3 *key_steps, - size_t num_curve_keys, - size_t num_steps, - float time, - size_t k0, - size_t k1, - size_t k2, - size_t k3, - float4 r_keys[4]) const; - - void keys_for_step(const float3 *curve_keys, - const float *curve_radius, - const float3 *key_steps, - size_t num_curve_keys, - size_t num_steps, - size_t step, - size_t k0, - size_t k1, - float4 r_keys[2]) const; - void cardinal_keys_for_step(const float3 *curve_keys, - const float *curve_radius, - const float3 *key_steps, - size_t num_curve_keys, - size_t num_steps, - size_t step, - size_t k0, - size_t k1, - size_t k2, - size_t k3, - float4 r_keys[4]) const; - }; - - Curve get_curve(size_t i) const - { - int first = curve_first_key[i]; - int next_first = (i + 1 < curve_first_key.size()) ? curve_first_key[i + 1] : curve_keys.size(); - - Curve curve = {first, next_first - first}; - return curve; - } - - size_t num_curves() const - { - return curve_first_key.size(); - } - - size_t num_segments() const - { - return curve_keys.size() - curve_first_key.size(); - } - - size_t num_primitives() const - { - return num_triangles() + num_segments(); - } - /* Mesh SubdFace */ struct SubdFace { int start_corner; @@ -212,14 +124,6 @@ class Mesh : public Node { SubdivisionType subdivision_type; /* Mesh Data */ - enum GeometryFlags { - GEOMETRY_NONE = 0, - GEOMETRY_TRIANGLES = (1 << 0), - GEOMETRY_CURVES = (1 << 1), - }; - int geometry_flags; /* used to distinguish meshes with no verts - and meshed for which geometry is not created */ - array triangles; array verts; array shader; @@ -230,13 +134,6 @@ class Mesh : public Node { array vert_patch_uv; float volume_isovalue; - bool has_volume; /* Set in the device_update_flags(). */ - bool has_surface_bssrdf; /* Set in the device_update_flags(). */ - - array curve_keys; - array curve_radius; - array curve_first_key; - array curve_shader; array subd_faces; array subd_face_corners; @@ -246,42 +143,18 @@ class Mesh : public Node { SubdParams *subd_params; - vector used_shaders; - AttributeSet attributes; - AttributeSet curve_attributes; AttributeSet subd_attributes; - BoundBox bounds; - bool transform_applied; - bool transform_negative_scaled; - Transform transform_normal; - PackedPatchTable *patch_table; - uint motion_steps; - bool use_motion_blur; - - /* Update Flags */ - bool need_update; - bool need_update_rebuild; - /* BVH */ - BVH *bvh; - size_t tri_offset; size_t vert_offset; - size_t curve_offset; - size_t curvekey_offset; - size_t patch_offset; size_t patch_table_offset; size_t face_offset; size_t corner_offset; - size_t attr_map_offset; - - size_t prim_offset; - size_t num_subd_verts; private: @@ -289,7 +162,7 @@ class Mesh : public Node { unordered_multimap vert_stitching_map; /* stitching index -> multiple real vert indices */ friend class DiagSplit; - friend class MeshManager; + friend class GeometryManager; public: /* Functions */ @@ -298,24 +171,24 @@ class Mesh : public Node { void resize_mesh(int numverts, int numfaces); void reserve_mesh(int numverts, int numfaces); - void resize_curves(int numcurves, int numkeys); - void reserve_curves(int numcurves, int numkeys); void resize_subd_faces(int numfaces, int num_ngons, int numcorners); void reserve_subd_faces(int numfaces, int num_ngons, int numcorners); - void clear(bool preserve_voxel_data = false); + void clear(bool preserve_voxel_data); + void clear() override; void add_vertex(float3 P); void add_vertex_slow(float3 P); void add_triangle(int v0, int v1, int v2, int shader, bool smooth); - void add_curve_key(float3 loc, float radius); - void add_curve(int first_key, int shader); void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_); - void compute_bounds(); + void copy_center_to_motion_step(const int motion_step); + + void compute_bounds() override; + void apply_transform(const Transform &tfm, const bool apply_to_motion) override; void add_face_normals(); void add_vertex_normals(); void add_undisplaced(); - void get_uv_tiles(ustring map, unordered_set &tiles); + void get_uv_tiles(ustring map, unordered_set &tiles) override; void pack_shaders(Scene *scene, uint *shader); void pack_normals(float4 *vnormal); @@ -325,103 +198,11 @@ class Mesh : public Node { float2 *tri_patch_uv, size_t vert_offset, size_t tri_offset); - void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset); void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset); - void compute_bvh(Device *device, - DeviceScene *dscene, - SceneParams *params, - Progress *progress, - int n, - int total); - - bool need_attribute(Scene *scene, AttributeStandard std); - bool need_attribute(Scene *scene, ustring name); - - void tag_update(Scene *scene, bool rebuild); - - bool has_motion_blur() const; - bool has_true_displacement() const; - bool has_voxel_attributes() const; - - /* Convert between normalized -1..1 motion time and index - * in the VERTEX_MOTION attribute. */ - float motion_time(int step) const; - int motion_step(float time) const; - - /* Check whether the mesh should have own BVH built separately. Briefly, - * own BVH is needed for mesh, if: - * - * - It is instanced multiple times, so each instance object should share the - * same BVH tree. - * - Special ray intersection is needed, for example to limit subsurface rays - * to only the mesh itself. - * - The BVH layout requires the top level to only contain instances. - */ - bool need_build_bvh(BVHLayout layout) const; - - /* Check if the mesh should be treated as instanced. */ - bool is_instanced() const; - void tessellate(DiagSplit *split); }; -/* Mesh Manager */ - -class MeshManager { - public: - bool need_update; - bool need_flags_update; - - MeshManager(); - ~MeshManager(); - - bool displace(Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress &progress); - - /* attributes */ - void update_osl_attributes(Device *device, - Scene *scene, - vector &mesh_attributes); - void update_svm_attributes(Device *device, - DeviceScene *dscene, - Scene *scene, - vector &mesh_attributes); - - void device_update_preprocess(Device *device, Scene *scene, Progress &progress); - void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress); - - void device_free(Device *device, DeviceScene *dscene); - - void tag_update(Scene *scene); - - void create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress); - - void collect_statistics(const Scene *scene, RenderStats *stats); - - protected: - /* Calculate verts/triangles/curves offsets in global arrays. */ - void mesh_calc_offset(Scene *scene); - - void device_update_object(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress); - - void device_update_mesh(Device *device, - DeviceScene *dscene, - Scene *scene, - bool for_displacement, - Progress &progress); - - void device_update_attributes(Device *device, - DeviceScene *dscene, - Scene *scene, - Progress &progress); - - void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress); - - void device_update_displacement_images(Device *device, Scene *scene, Progress &progress); - - void device_update_volume_images(Device *device, Scene *scene, Progress &progress); -}; - CCL_NAMESPACE_END #endif /* __MESH_H__ */ diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp index 6a6c2fbb3eb..467810f9273 100644 --- a/intern/cycles/render/mesh_displace.cpp +++ b/intern/cycles/render/mesh_displace.cpp @@ -43,7 +43,7 @@ static float3 compute_face_normal(const Mesh::Triangle &t, float3 *verts) return norm / normlen; } -bool MeshManager::displace( +bool GeometryManager::displace( Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress &progress) { /* verify if we have a displacement shader */ @@ -58,7 +58,7 @@ bool MeshManager::displace( size_t object_index = OBJECT_NONE; for (size_t i = 0; i < scene->objects.size(); i++) { - if (scene->objects[i]->mesh == mesh) { + if (scene->objects[i]->geometry == mesh) { object_index = i; break; } @@ -91,7 +91,7 @@ bool MeshManager::displace( /* set up object, primitive and barycentric coordinates */ int object = object_index; - int prim = mesh->tri_offset + i; + int prim = mesh->prim_offset + i; float u, v; switch (j) { diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp index f451b58e92a..74c6a7759a6 100644 --- a/intern/cycles/render/mesh_volume.cpp +++ b/intern/cycles/render/mesh_volume.cpp @@ -362,7 +362,7 @@ struct VoxelAttributeGrid { int channels; }; -void MeshManager::create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress) +void GeometryManager::create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress) { string msg = string_printf("Computing Volume Mesh %s", mesh->name.c_str()); progress.set_status("Updating Mesh", msg); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 00f4a7283bb..75e21e00dcf 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -333,10 +333,10 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) /* TODO(lukas): This is quite inefficient. A fairly simple improvement would * be to have a cache in each mesh that is indexed by attribute. * Additionally, building a graph-to-meshes list once could help. */ - foreach (Mesh *mesh, scene->meshes) { - foreach (Shader *shader, mesh->used_shaders) { + foreach (Geometry *geom, scene->geometry) { + foreach (Shader *shader, geom->used_shaders) { if (shader->graph == graph) { - mesh->get_uv_tiles(attribute, used_tiles); + geom->get_uv_tiles(attribute, used_tiles); } } } diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 849329a086d..4987b6089d7 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -16,6 +16,7 @@ #include "render/camera.h" #include "device/device.h" +#include "render/hair.h" #include "render/light.h" #include "render/mesh.h" #include "render/curves.h" @@ -87,7 +88,7 @@ NODE_DEFINE(Object) { NodeType *type = NodeType::add("object", create); - SOCKET_NODE(mesh, "Mesh", &Mesh::node_type); + SOCKET_NODE(geometry, "Geometry", &Geometry::node_base_type); SOCKET_TRANSFORM(tfm, "Transform", transform_identity()); SOCKET_UINT(visibility, "Visibility", ~0); SOCKET_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f)); @@ -152,7 +153,7 @@ void Object::update_motion() void Object::compute_bounds(bool motion_blur) { - BoundBox mbounds = mesh->bounds; + BoundBox mbounds = geometry->bounds; if (motion_blur && use_motion()) { array decomp(motion.size()); @@ -172,7 +173,7 @@ void Object::compute_bounds(bool motion_blur) } else { /* No motion blur case. */ - if (mesh->transform_applied) { + if (geometry->transform_applied) { bounds = mbounds; } else { @@ -183,89 +184,18 @@ void Object::compute_bounds(bool motion_blur) void Object::apply_transform(bool apply_to_motion) { - if (!mesh || tfm == transform_identity()) + if (!geometry || tfm == transform_identity()) return; - /* triangles */ - if (mesh->verts.size()) { - /* store matrix to transform later. when accessing these as attributes we - * do not want the transform to be applied for consistency between static - * and dynamic BVH, so we do it on packing. */ - mesh->transform_normal = transform_transposed_inverse(tfm); - - /* apply to mesh vertices */ - for (size_t i = 0; i < mesh->verts.size(); i++) - mesh->verts[i] = transform_point(&tfm, mesh->verts[i]); - - if (apply_to_motion) { - Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - - if (attr) { - size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1); - float3 *vert_steps = attr->data_float3(); - - for (size_t i = 0; i < steps_size; i++) - vert_steps[i] = transform_point(&tfm, vert_steps[i]); - } - - Attribute *attr_N = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); - - if (attr_N) { - Transform ntfm = mesh->transform_normal; - size_t steps_size = mesh->verts.size() * (mesh->motion_steps - 1); - float3 *normal_steps = attr_N->data_float3(); - - for (size_t i = 0; i < steps_size; i++) - normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i])); - } - } - } - - /* curves */ - if (mesh->curve_keys.size()) { - /* compute uniform scale */ - float3 c0 = transform_get_column(&tfm, 0); - float3 c1 = transform_get_column(&tfm, 1); - float3 c2 = transform_get_column(&tfm, 2); - float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f / 3.0f); - - /* apply transform to curve keys */ - for (size_t i = 0; i < mesh->curve_keys.size(); i++) { - float3 co = transform_point(&tfm, mesh->curve_keys[i]); - float radius = mesh->curve_radius[i] * scalar; - - /* scale for curve radius is only correct for uniform scale */ - mesh->curve_keys[i] = co; - mesh->curve_radius[i] = radius; - } - - if (apply_to_motion) { - Attribute *curve_attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - - if (curve_attr) { - /* apply transform to motion curve keys */ - size_t steps_size = mesh->curve_keys.size() * (mesh->motion_steps - 1); - float4 *key_steps = curve_attr->data_float4(); - - for (size_t i = 0; i < steps_size; i++) { - float3 co = transform_point(&tfm, float4_to_float3(key_steps[i])); - float radius = key_steps[i].w * scalar; - - /* scale for curve radius is only correct for uniform scale */ - key_steps[i] = float3_to_float4(co); - key_steps[i].w = radius; - } - } - } - } + geometry->apply_transform(tfm, apply_to_motion); /* we keep normals pointing in same direction on negative scale, notify - * mesh about this in it (re)calculates normals */ + * geometry about this in it (re)calculates normals */ if (transform_negative_scale(tfm)) - mesh->transform_negative_scaled = true; + geometry->transform_negative_scaled = true; if (bounds.valid()) { - mesh->compute_bounds(); + geometry->compute_bounds(); compute_bounds(false); } @@ -275,11 +205,11 @@ void Object::apply_transform(bool apply_to_motion) void Object::tag_update(Scene *scene) { - if (mesh) { - if (mesh->transform_applied) - mesh->need_update = true; + if (geometry) { + if (geometry->transform_applied) + geometry->need_update = true; - foreach (Shader *shader, mesh->used_shaders) { + foreach (Shader *shader, geometry->used_shaders) { if (shader->use_mis && shader->has_surface_emission) scene->light_manager->need_update = true; } @@ -287,7 +217,7 @@ void Object::tag_update(Scene *scene) scene->camera->need_flags_update = true; scene->curve_system_manager->need_update = true; - scene->mesh_manager->need_update = true; + scene->geometry_manager->need_update = true; scene->object_manager->need_update = true; } @@ -353,32 +283,22 @@ ObjectManager::~ObjectManager() { } -void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob) +static float object_surface_area(UpdateObjectTransformState *state, + const Transform &tfm, + Geometry *geom) { - KernelObject &kobject = state->objects[ob->index]; - Transform *object_motion_pass = state->object_motion_pass; - - Mesh *mesh = ob->mesh; - uint flag = 0; - - /* Compute transformations. */ - Transform tfm = ob->tfm; - Transform itfm = transform_inverse(tfm); + if (geom->type != Geometry::MESH) { + return 0.0f; + } /* Compute surface area. for uniform scale we can do avoid the many * transform calls and share computation for instances. * * TODO(brecht): Correct for displacement, and move to a better place. */ - float uniform_scale; + Mesh *mesh = static_cast(geom); float surface_area = 0.0f; - float3 color = ob->color; - float pass_id = ob->pass_id; - float random_number = (float)ob->random_id * (1.0f / (float)0xFFFFFFFF); - int particle_index = (ob->particle_system) ? - ob->particle_index + state->particle_offset[ob->particle_system] : - 0; - + float uniform_scale; if (transform_uniform_scale(tfm, uniform_scale)) { map::iterator it; @@ -424,9 +344,31 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s } } + return surface_area; +} + +void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob) +{ + KernelObject &kobject = state->objects[ob->index]; + Transform *object_motion_pass = state->object_motion_pass; + + Geometry *geom = ob->geometry; + uint flag = 0; + + /* Compute transformations. */ + Transform tfm = ob->tfm; + Transform itfm = transform_inverse(tfm); + + float3 color = ob->color; + float pass_id = ob->pass_id; + float random_number = (float)ob->random_id * (1.0f / (float)0xFFFFFFFF); + int particle_index = (ob->particle_system) ? + ob->particle_index + state->particle_offset[ob->particle_system] : + 0; + kobject.tfm = tfm; kobject.itfm = itfm; - kobject.surface_area = surface_area; + kobject.surface_area = object_surface_area(state, tfm, geom); kobject.color[0] = color.x; kobject.color[1] = color.y; kobject.color[2] = color.z; @@ -435,11 +377,16 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s kobject.particle_index = particle_index; kobject.motion_offset = 0; - if (mesh->use_motion_blur) { + if (geom->use_motion_blur) { state->have_motion = true; } - if (mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) { - flag |= SD_OBJECT_HAS_VERTEX_MOTION; + + if (geom->type == Geometry::MESH) { + /* TODO: why only mesh? */ + Mesh *mesh = static_cast(geom); + if (mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) { + flag |= SD_OBJECT_HAS_VERTEX_MOTION; + } } if (state->need_motion == Scene::MOTION_PASS) { @@ -460,7 +407,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s /* Motion transformations, is world/object space depending if mesh * comes with deformed position in object space, or if we transform * the shading point in world space. */ - if (!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) { + if (!(flag & SD_OBJECT_HAS_VERTEX_MOTION)) { tfm_pre = tfm_pre * itfm; tfm_post = tfm_post * itfm; } @@ -485,12 +432,13 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s kobject.dupli_generated[0] = ob->dupli_generated[0]; kobject.dupli_generated[1] = ob->dupli_generated[1]; kobject.dupli_generated[2] = ob->dupli_generated[2]; - kobject.numkeys = mesh->curve_keys.size(); + kobject.numkeys = (geom->type == Geometry::HAIR) ? static_cast(geom)->curve_keys.size() : + 0; kobject.dupli_uv[0] = ob->dupli_uv[0]; kobject.dupli_uv[1] = ob->dupli_uv[1]; - int totalsteps = mesh->motion_steps; + int totalsteps = geom->motion_steps; kobject.numsteps = (totalsteps - 1) / 2; - kobject.numverts = mesh->verts.size(); + kobject.numverts = (geom->type == Geometry::MESH) ? static_cast(geom)->verts.size() : 0; kobject.patch_map_offset = 0; kobject.attribute_map_offset = 0; uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0); @@ -505,7 +453,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s state->object_flag[ob->index] = flag; /* Have curves. */ - if (mesh->num_curves()) { + if (geom->type == Geometry::HAIR) { state->have_curves = true; } } @@ -681,7 +629,7 @@ void ObjectManager::device_update_flags( vector volume_objects; bool has_volume_objects = false; foreach (Object *object, scene->objects) { - if (object->mesh->has_volume) { + if (object->geometry->has_volume) { if (bounds_valid) { volume_objects.push_back(object); } @@ -690,11 +638,11 @@ void ObjectManager::device_update_flags( } foreach (Object *object, scene->objects) { - if (object->mesh->has_volume) { + if (object->geometry->has_volume) { object_flag[object->index] |= SD_OBJECT_HAS_VOLUME; object_flag[object->index] &= ~SD_OBJECT_HAS_VOLUME_ATTRIBUTES; - foreach (Attribute &attr, object->mesh->attributes.attributes) { + foreach (Attribute &attr, object->geometry->attributes.attributes) { if (attr.element == ATTR_ELEMENT_VOXEL) { object_flag[object->index] |= SD_OBJECT_HAS_VOLUME_ATTRIBUTES; } @@ -744,21 +692,24 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc bool update = false; foreach (Object *object, scene->objects) { - Mesh *mesh = object->mesh; - - if (mesh->patch_table) { - uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() - - mesh->patch_table->num_nodes * PATCH_NODE_SIZE) - - mesh->patch_offset; - - if (kobjects[object->index].patch_map_offset != patch_map_offset) { - kobjects[object->index].patch_map_offset = patch_map_offset; - update = true; + Geometry *geom = object->geometry; + + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + if (mesh->patch_table) { + uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() - + mesh->patch_table->num_nodes * PATCH_NODE_SIZE) - + mesh->patch_offset; + + if (kobjects[object->index].patch_map_offset != patch_map_offset) { + kobjects[object->index].patch_map_offset = patch_map_offset; + update = true; + } } } - if (kobjects[object->index].attribute_map_offset != mesh->attr_map_offset) { - kobjects[object->index].attribute_map_offset = mesh->attr_map_offset; + if (kobjects[object->index].attribute_map_offset != geom->attr_map_offset) { + kobjects[object->index].attribute_map_offset = geom->attr_map_offset; update = true; } } @@ -779,10 +730,10 @@ void ObjectManager::device_free(Device *, DeviceScene *dscene) void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress) { /* todo: normals and displacement should be done before applying transform! */ - /* todo: create objects/meshes in right order! */ + /* todo: create objects/geometry in right order! */ - /* counter mesh users */ - map mesh_users; + /* counter geometry users */ + map geometry_users; Scene::MotionType need_motion = scene->need_motion(); bool motion_blur = need_motion == Scene::MOTION_BLUR; bool apply_to_motion = need_motion != Scene::MOTION_PASS; @@ -790,10 +741,10 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P bool have_instancing = false; foreach (Object *object, scene->objects) { - map::iterator it = mesh_users.find(object->mesh); + map::iterator it = geometry_users.find(object->geometry); - if (it == mesh_users.end()) - mesh_users[object->mesh] = 1; + if (it == geometry_users.end()) + geometry_users[object->geometry] = 1; else it->second++; } @@ -803,27 +754,34 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P uint *object_flag = dscene->object_flag.data(); - /* apply transforms for objects with single user meshes */ + /* apply transforms for objects with single user geometry */ foreach (Object *object, scene->objects) { /* Annoying feedback loop here: we can't use is_instanced() because * it'll use uninitialized transform_applied flag. * - * Could be solved by moving reference counter to Mesh. + * Could be solved by moving reference counter to Geometry. */ - if ((mesh_users[object->mesh] == 1 && !object->mesh->has_surface_bssrdf) && - !object->mesh->has_true_displacement() && - object->mesh->subdivision_type == Mesh::SUBDIVISION_NONE) { + Geometry *geom = object->geometry; + bool apply = (geometry_users[geom] == 1) && !geom->has_surface_bssrdf && + !geom->has_true_displacement(); + + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); + apply = apply && mesh->subdivision_type == Mesh::SUBDIVISION_NONE; + } + + if (apply) { if (!(motion_blur && object->use_motion())) { - if (!object->mesh->transform_applied) { + if (!geom->transform_applied) { object->apply_transform(apply_to_motion); - object->mesh->transform_applied = true; + geom->transform_applied = true; if (progress.get_cancel()) return; } object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED; - if (object->mesh->transform_negative_scaled) + if (geom->transform_negative_scaled) object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED; } else @@ -842,7 +800,7 @@ void ObjectManager::tag_update(Scene *scene) { need_update = true; scene->curve_system_manager->need_update = true; - scene->mesh_manager->need_update = true; + scene->geometry_manager->need_update = true; scene->light_manager->need_update = true; } diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index cbbff0d4c6d..c5d878ec938 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -32,7 +32,7 @@ CCL_NAMESPACE_BEGIN class Device; class DeviceScene; -class Mesh; +class Geometry; class ParticleSystem; class Progress; class Scene; @@ -46,7 +46,7 @@ class Object : public Node { public: NODE_DECLARE - Mesh *mesh; + Geometry *geometry; Transform tfm; BoundBox bounds; uint random_id; diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 1e75fa0f99b..4f7d886cb10 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -94,7 +94,7 @@ Scene::Scene(const SceneParams ¶ms_, Device *device) film = new Film(); background = new Background(); light_manager = new LightManager(); - mesh_manager = new MeshManager(); + geometry_manager = new GeometryManager(); object_manager = new ObjectManager(); integrator = new Integrator(); image_manager = new ImageManager(device->info); @@ -118,8 +118,8 @@ void Scene::free_memory(bool final) { foreach (Shader *s, shaders) delete s; - foreach (Mesh *m, meshes) - delete m; + foreach (Geometry *g, geometry) + delete g; foreach (Object *o, objects) delete o; foreach (Light *l, lights) @@ -128,7 +128,7 @@ void Scene::free_memory(bool final) delete p; shaders.clear(); - meshes.clear(); + geometry.clear(); objects.clear(); lights.clear(); particle_systems.clear(); @@ -140,7 +140,7 @@ void Scene::free_memory(bool final) integrator->device_free(device, &dscene); object_manager->device_free(device, &dscene); - mesh_manager->device_free(device, &dscene); + geometry_manager->device_free(device, &dscene); shader_manager->device_free(device, &dscene, this); light_manager->device_free(device, &dscene); @@ -165,7 +165,7 @@ void Scene::free_memory(bool final) delete background; delete integrator; delete object_manager; - delete mesh_manager; + delete geometry_manager; delete shader_manager; delete light_manager; delete particle_system_manager; @@ -211,7 +211,7 @@ void Scene::device_update(Device *device_, Progress &progress) if (progress.get_cancel() || device->have_error()) return; - mesh_manager->device_update_preprocess(device, this, progress); + geometry_manager->device_update_preprocess(device, this, progress); if (progress.get_cancel() || device->have_error()) return; @@ -235,7 +235,7 @@ void Scene::device_update(Device *device_, Progress &progress) return; progress.set_status("Updating Meshes"); - mesh_manager->device_update(device, &dscene, this, progress); + geometry_manager->device_update(device, &dscene, this, progress); if (progress.get_cancel() || device->have_error()) return; @@ -356,7 +356,7 @@ bool Scene::need_update() bool Scene::need_data_update() { return (background->need_update || image_manager->need_update || object_manager->need_update || - mesh_manager->need_update || light_manager->need_update || lookup_tables->need_update || + geometry_manager->need_update || light_manager->need_update || lookup_tables->need_update || integrator->need_update || shader_manager->need_update || particle_system_manager->need_update || curve_system_manager->need_update || bake_manager->need_update || film->need_update); @@ -379,7 +379,7 @@ void Scene::reset() background->tag_update(this); integrator->tag_update(this); object_manager->tag_update(this); - mesh_manager->tag_update(this); + geometry_manager->tag_update(this); light_manager->tag_update(this); particle_system_manager->tag_update(this); curve_system_manager->tag_update(this); @@ -392,7 +392,7 @@ void Scene::device_free() void Scene::collect_statistics(RenderStats *stats) { - mesh_manager->collect_statistics(this, stats); + geometry_manager->collect_statistics(this, stats); image_manager->collect_statistics(stats); } diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index f99510d2d42..ab30aaa1f43 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -44,8 +44,8 @@ class Integrator; class Light; class LightManager; class LookupTables; -class Mesh; -class MeshManager; +class Geometry; +class GeometryManager; class Object; class ObjectManager; class ParticleSystemManager; @@ -213,7 +213,7 @@ class Scene { /* data lists */ vector objects; - vector meshes; + vector geometry; vector shaders; vector lights; vector particle_systems; @@ -222,7 +222,7 @@ class Scene { ImageManager *image_manager; LightManager *light_manager; ShaderManager *shader_manager; - MeshManager *mesh_manager; + GeometryManager *geometry_manager; ObjectManager *object_manager; ParticleSystemManager *particle_system_manager; CurveSystemManager *curve_system_manager; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index c77a20787f5..dac7fbac806 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -701,23 +701,26 @@ DeviceRequestedFeatures Session::get_requested_device_features() requested_features.use_object_motion = false; requested_features.use_camera_motion = use_motion && scene->camera->use_motion(); foreach (Object *object, scene->objects) { - Mesh *mesh = object->mesh; - if (mesh->num_curves()) { - requested_features.use_hair = true; - } + Geometry *geom = object->geometry; if (use_motion) { - requested_features.use_object_motion |= object->use_motion() | mesh->use_motion_blur; - requested_features.use_camera_motion |= mesh->use_motion_blur; - } -#ifdef WITH_OPENSUBDIV - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { - requested_features.use_patch_evaluation = true; + requested_features.use_object_motion |= object->use_motion() | geom->use_motion_blur; + requested_features.use_camera_motion |= geom->use_motion_blur; } -#endif if (object->is_shadow_catcher) { requested_features.use_shadow_tricks = true; } - requested_features.use_true_displacement |= mesh->has_true_displacement(); + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast(geom); +#ifdef WITH_OPENSUBDIV + if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { + requested_features.use_patch_evaluation = true; + } +#endif + requested_features.use_true_displacement |= mesh->has_true_displacement(); + } + else if (geom->type == Geometry::HAIR) { + requested_features.use_hair = true; + } } requested_features.use_background_light = scene->light_manager->has_background_light(scene); diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 661208c6463..60f38aa14da 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -214,7 +214,7 @@ Shader::Shader() : Node(node_type) used = false; need_update = true; - need_update_mesh = true; + need_update_geometry = true; need_sync_object = false; } @@ -288,7 +288,7 @@ void Shader::set_graph(ShaderGraph *graph_) const char *new_hash = (graph_) ? graph_->displacement_hash.c_str() : ""; if (strcmp(old_hash, new_hash) != 0) { - need_update_mesh = true; + need_update_geometry = true; } } @@ -347,14 +347,14 @@ void Shader::tag_update(Scene *scene) } /* compare if the attributes changed, mesh manager will check - * need_update_mesh, update the relevant meshes and clear it. */ + * need_update_geometry, update the relevant meshes and clear it. */ if (attributes.modified(prev_attributes)) { - need_update_mesh = true; - scene->mesh_manager->need_update = true; + need_update_geometry = true; + scene->geometry_manager->need_update = true; } if (has_volume != prev_has_volume) { - scene->mesh_manager->need_flags_update = true; + scene->geometry_manager->need_flags_update = true; scene->object_manager->need_flags_update = true; } } @@ -489,8 +489,8 @@ void ShaderManager::device_update_shaders_used(Scene *scene) if (scene->background->shader) scene->background->shader->used = true; - foreach (Mesh *mesh, scene->meshes) - foreach (Shader *shader, mesh->used_shaders) + foreach (Geometry *geom, scene->geometry) + foreach (Shader *shader, geom->used_shaders) shader->used = true; foreach (Light *light, scene->lights) diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index f74204df355..c6f40bb7833 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -95,7 +95,7 @@ class Shader : public Node { /* synchronization */ bool need_update; - bool need_update_mesh; + bool need_update_geometry; bool need_sync_object; /* If the shader has only volume components, the surface is assumed to -- cgit v1.2.3 From d809853513c1333c9d9a22ab6ba35617b5ed2b8c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 3 Feb 2020 21:40:58 +0100 Subject: Cleanup: simplify Cycles primitive attribute map storage --- intern/cycles/kernel/geom/geom_attribute.h | 10 +- intern/cycles/kernel/geom/geom_motion_curve.h | 2 +- intern/cycles/kernel/kernel_types.h | 3 +- intern/cycles/kernel/osl/osl_shader.cpp | 4 - intern/cycles/render/attribute.cpp | 54 +++---- intern/cycles/render/attribute.h | 11 +- intern/cycles/render/geometry.cpp | 195 ++++++++------------------ intern/cycles/render/hair.cpp | 4 +- intern/cycles/render/mesh.cpp | 12 +- 9 files changed, 89 insertions(+), 206 deletions(-) diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h index 456608bfa22..e1b0e6fb81c 100644 --- a/intern/cycles/kernel/geom/geom_attribute.h +++ b/intern/cycles/kernel/geom/geom_attribute.h @@ -29,17 +29,11 @@ ccl_device_inline uint subd_triangle_patch(KernelGlobals *kg, const ShaderData * ccl_device_inline uint attribute_primitive_type(KernelGlobals *kg, const ShaderData *sd) { -#ifdef __HAIR__ - if (sd->type & PRIMITIVE_ALL_CURVE) { - return ATTR_PRIM_CURVE; - } - else -#endif - if (subd_triangle_patch(kg, sd) != ~0) { + if ((sd->type & PRIMITIVE_ALL_TRIANGLE) && subd_triangle_patch(kg, sd) != ~0) { return ATTR_PRIM_SUBD; } else { - return ATTR_PRIM_TRIANGLE; + return ATTR_PRIM_GEOMETRY; } } diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h index 7380c506bf4..0e2a00e9d2e 100644 --- a/intern/cycles/kernel/geom/geom_motion_curve.h +++ b/intern/cycles/kernel/geom/geom_motion_curve.h @@ -36,7 +36,7 @@ ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg, * zero iterations and rendering is really slow with motion curves. For until other * areas are speed up it's probably not so crucial to optimize this out. */ - uint attr_offset = object_attribute_map_offset(kg, object) + ATTR_PRIM_CURVE; + uint attr_offset = object_attribute_map_offset(kg, object) + ATTR_PRIM_GEOMETRY; uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); while (attr_map.x != id) { diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 1e1d161ff9b..bf34450df4b 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -725,9 +725,8 @@ typedef enum PrimitiveType { /* Attributes */ typedef enum AttributePrimitive { - ATTR_PRIM_TRIANGLE = 0, + ATTR_PRIM_GEOMETRY = 0, ATTR_PRIM_SUBD, - ATTR_PRIM_CURVE, ATTR_PRIM_TYPES } AttributePrimitive; diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index db5ad06d3fc..0994bfaf950 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -382,10 +382,6 @@ int OSLShader::find_attribute(KernelGlobals *kg, { /* for OSL, a hash map is used to lookup the attribute by name. */ int object = sd->object * ATTR_PRIM_TYPES; -#ifdef __HAIR__ - if (sd->type & PRIMITIVE_ALL_CURVE) - object += ATTR_PRIM_CURVE; -#endif OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object]; ustring stdname(std::string("geom:") + diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index fcba901ae6c..05c0b5693bc 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -193,7 +193,7 @@ size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const case ATTR_ELEMENT_FACE: if (geom->type == Geometry::MESH) { Mesh *mesh = static_cast(geom); - if (prim == ATTR_PRIM_TRIANGLE) { + if (prim == ATTR_PRIM_GEOMETRY) { size = mesh->num_triangles(); } else { @@ -205,7 +205,7 @@ size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const case ATTR_ELEMENT_CORNER_BYTE: if (geom->type == Geometry::MESH) { Mesh *mesh = static_cast(geom); - if (prim == ATTR_PRIM_TRIANGLE) { + if (prim == ATTR_PRIM_GEOMETRY) { size = mesh->num_triangles() * 3; } else { @@ -390,11 +390,9 @@ void Attribute::get_uv_tiles(Geometry *geom, /* Attribute Set */ -AttributeSet::AttributeSet() +AttributeSet::AttributeSet(Geometry *geometry, AttributePrimitive prim) + : geometry(geometry), prim(prim) { - triangle_mesh = NULL; - subd_mesh = NULL; - hair = NULL; } AttributeSet::~AttributeSet() @@ -428,12 +426,7 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme #endif /* this is weak .. */ - if (triangle_mesh) - attr->resize(triangle_mesh, ATTR_PRIM_TRIANGLE, false); - if (subd_mesh) - attr->resize(subd_mesh, ATTR_PRIM_SUBD, false); - if (hair) - attr->resize(hair, ATTR_PRIM_CURVE, false); + attr->resize(geometry, prim, false); return attr; } @@ -470,7 +463,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) if (name == ustring()) name = Attribute::standard_name(std); - if (triangle_mesh || subd_mesh) { + if (geometry->type == Geometry::MESH) { switch (std) { case ATTR_STD_VERTEX_NORMAL: attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX); @@ -530,7 +523,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) break; } } - else if (hair) { + else if (geometry->type == Geometry::HAIR) { switch (std) { case ATTR_STD_UV: attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE); @@ -613,12 +606,7 @@ void AttributeSet::remove(Attribute *attribute) void AttributeSet::resize(bool reserve_only) { foreach (Attribute &attr, attributes) { - if (triangle_mesh) - attr.resize(triangle_mesh, ATTR_PRIM_TRIANGLE, reserve_only); - if (subd_mesh) - attr.resize(subd_mesh, ATTR_PRIM_SUBD, reserve_only); - if (hair) - attr.resize(hair, ATTR_PRIM_CURVE, reserve_only); + attr.resize(geometry, prim, reserve_only); } } @@ -648,15 +636,10 @@ AttributeRequest::AttributeRequest(ustring name_) name = name_; std = ATTR_STD_NONE; - triangle_type = TypeDesc::TypeFloat; - triangle_desc.element = ATTR_ELEMENT_NONE; - triangle_desc.offset = 0; - triangle_desc.type = NODE_ATTR_FLOAT; - - curve_type = TypeDesc::TypeFloat; - curve_desc.element = ATTR_ELEMENT_NONE; - curve_desc.offset = 0; - curve_desc.type = NODE_ATTR_FLOAT; + type = TypeDesc::TypeFloat; + desc.element = ATTR_ELEMENT_NONE; + desc.offset = 0; + desc.type = NODE_ATTR_FLOAT; subd_type = TypeDesc::TypeFloat; subd_desc.element = ATTR_ELEMENT_NONE; @@ -669,15 +652,10 @@ AttributeRequest::AttributeRequest(AttributeStandard std_) name = ustring(); std = std_; - triangle_type = TypeDesc::TypeFloat; - triangle_desc.element = ATTR_ELEMENT_NONE; - triangle_desc.offset = 0; - triangle_desc.type = NODE_ATTR_FLOAT; - - curve_type = TypeDesc::TypeFloat; - curve_desc.element = ATTR_ELEMENT_NONE; - curve_desc.offset = 0; - curve_desc.type = NODE_ATTR_FLOAT; + type = TypeDesc::TypeFloat; + desc.element = ATTR_ELEMENT_NONE; + desc.offset = 0; + desc.type = NODE_ATTR_FLOAT; subd_type = TypeDesc::TypeFloat; subd_desc.element = ATTR_ELEMENT_NONE; diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h index d4bf630aeb6..f1fd30fd85a 100644 --- a/intern/cycles/render/attribute.h +++ b/intern/cycles/render/attribute.h @@ -170,12 +170,11 @@ class Attribute { class AttributeSet { public: - Mesh *triangle_mesh; - Mesh *subd_mesh; - Hair *hair; + Geometry *geometry; + AttributePrimitive prim; list attributes; - AttributeSet(); + AttributeSet(Geometry *geometry, AttributePrimitive prim); ~AttributeSet(); Attribute *add(ustring name, TypeDesc type, AttributeElement element); @@ -206,8 +205,8 @@ class AttributeRequest { AttributeStandard std; /* temporary variables used by GeometryManager */ - TypeDesc triangle_type, curve_type, subd_type; - AttributeDescriptor triangle_desc, curve_desc, subd_desc; + TypeDesc type, subd_type; + AttributeDescriptor desc, subd_desc; explicit AttributeRequest(ustring name_); explicit AttributeRequest(AttributeStandard std); diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp index a75a114e4f2..880fb7b4c7d 100644 --- a/intern/cycles/render/geometry.cpp +++ b/intern/cycles/render/geometry.cpp @@ -56,7 +56,8 @@ NODE_ABSTRACT_DEFINE(Geometry) return type; } -Geometry::Geometry(const NodeType *node_type, const Type type) : Node(node_type), type(type) +Geometry::Geometry(const NodeType *node_type, const Type type) + : Node(node_type), type(type), attributes(this, ATTR_PRIM_GEOMETRY) { need_update = true; need_update_rebuild = false; @@ -300,9 +301,8 @@ void GeometryManager::update_osl_attributes(Device *device, osl_attr.desc.offset = 0; osl_attr.desc.flags = 0; - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][attr.name()] = osl_attr; + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][attr.name()] = osl_attr; og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr; - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr; } /* find geometry attributes */ @@ -318,16 +318,16 @@ void GeometryManager::update_osl_attributes(Device *device, foreach (AttributeRequest &req, attributes.requests) { OSLGlobals::Attribute osl_attr; - if (req.triangle_desc.element != ATTR_ELEMENT_NONE) { - osl_attr.desc = req.triangle_desc; + if (req.desc.element != ATTR_ELEMENT_NONE) { + osl_attr.desc = req.desc; - if (req.triangle_type == TypeDesc::TypeFloat) + if (req.type == TypeDesc::TypeFloat) osl_attr.type = TypeDesc::TypeFloat; - else if (req.triangle_type == TypeDesc::TypeMatrix) + else if (req.type == TypeDesc::TypeMatrix) osl_attr.type = TypeDesc::TypeMatrix; - else if (req.triangle_type == TypeFloat2) + else if (req.type == TypeFloat2) osl_attr.type = TypeFloat2; - else if (req.triangle_type == TypeRGBA) + else if (req.type == TypeRGBA) osl_attr.type = TypeRGBA; else osl_attr.type = TypeDesc::TypeColor; @@ -335,36 +335,11 @@ void GeometryManager::update_osl_attributes(Device *device, if (req.std != ATTR_STD_NONE) { /* if standard attribute, add lookup by geom: name convention */ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std))); - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][stdname] = osl_attr; + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][stdname] = osl_attr; } else if (req.name != ustring()) { /* add lookup by geometry attribute name */ - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][req.name] = osl_attr; - } - } - - if (req.curve_desc.element != ATTR_ELEMENT_NONE) { - osl_attr.desc = req.curve_desc; - - if (req.curve_type == TypeDesc::TypeFloat) - osl_attr.type = TypeDesc::TypeFloat; - else if (req.curve_type == TypeDesc::TypeMatrix) - osl_attr.type = TypeDesc::TypeMatrix; - else if (req.curve_type == TypeFloat2) - osl_attr.type = TypeFloat2; - else if (req.curve_type == TypeRGBA) - osl_attr.type = TypeRGBA; - else - osl_attr.type = TypeDesc::TypeColor; - - if (req.std != ATTR_STD_NONE) { - /* if standard attribute, add lookup by geom: name convention */ - ustring stdname(string("geom:") + string(Attribute::standard_name(req.std))); - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr; - } - else if (req.name != ustring()) { - /* add lookup by geometry attribute name */ - og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr; + og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][req.name] = osl_attr; } } @@ -440,27 +415,22 @@ void GeometryManager::update_svm_attributes(Device *, else id = scene->shader_manager->get_attribute_id(req.std); - if (geom->type == Geometry::MESH) { - Mesh *mesh = static_cast(geom); - if (mesh->num_triangles()) { - attr_map[index].x = id; - attr_map[index].y = req.triangle_desc.element; - attr_map[index].z = as_uint(req.triangle_desc.offset); - - if (req.triangle_type == TypeDesc::TypeFloat) - attr_map[index].w = NODE_ATTR_FLOAT; - else if (req.triangle_type == TypeDesc::TypeMatrix) - attr_map[index].w = NODE_ATTR_MATRIX; - else if (req.triangle_type == TypeFloat2) - attr_map[index].w = NODE_ATTR_FLOAT2; - else if (req.triangle_type == TypeRGBA) - attr_map[index].w = NODE_ATTR_RGBA; - else - attr_map[index].w = NODE_ATTR_FLOAT3; + attr_map[index].x = id; + attr_map[index].y = req.desc.element; + attr_map[index].z = as_uint(req.desc.offset); + + if (req.type == TypeDesc::TypeFloat) + attr_map[index].w = NODE_ATTR_FLOAT; + else if (req.type == TypeDesc::TypeMatrix) + attr_map[index].w = NODE_ATTR_MATRIX; + else if (req.type == TypeFloat2) + attr_map[index].w = NODE_ATTR_FLOAT2; + else if (req.type == TypeRGBA) + attr_map[index].w = NODE_ATTR_RGBA; + else + attr_map[index].w = NODE_ATTR_FLOAT3; - attr_map[index].w |= req.triangle_desc.flags << 8; - } - } + attr_map[index].w |= req.desc.flags << 8; index++; @@ -477,7 +447,7 @@ void GeometryManager::update_svm_attributes(Device *, attr_map[index].w = NODE_ATTR_MATRIX; else if (req.subd_type == TypeFloat2) attr_map[index].w = NODE_ATTR_FLOAT2; - else if (req.triangle_type == TypeRGBA) + else if (req.subd_type == TypeRGBA) attr_map[index].w = NODE_ATTR_RGBA; else attr_map[index].w = NODE_ATTR_FLOAT3; @@ -487,28 +457,6 @@ void GeometryManager::update_svm_attributes(Device *, } index++; - - if (geom->type == Geometry::HAIR) { - Hair *hair = static_cast(geom); - if (hair->num_curves()) { - attr_map[index].x = id; - attr_map[index].y = req.curve_desc.element; - attr_map[index].z = as_uint(req.curve_desc.offset); - - if (req.curve_type == TypeDesc::TypeFloat) - attr_map[index].w = NODE_ATTR_FLOAT; - else if (req.curve_type == TypeDesc::TypeMatrix) - attr_map[index].w = NODE_ATTR_MATRIX; - else if (req.curve_type == TypeFloat2) - attr_map[index].w = NODE_ATTR_FLOAT2; - else - attr_map[index].w = NODE_ATTR_FLOAT3; - - attr_map[index].w |= req.curve_desc.flags << 8; - } - } - - index++; } /* terminator */ @@ -654,13 +602,13 @@ static void update_attribute_element_offset(Geometry *geom, else if (element == ATTR_ELEMENT_VERTEX_MOTION) offset -= mesh->vert_offset; else if (element == ATTR_ELEMENT_FACE) { - if (prim == ATTR_PRIM_TRIANGLE) + if (prim == ATTR_PRIM_GEOMETRY) offset -= mesh->prim_offset; else offset -= mesh->face_offset; } else if (element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE) { - if (prim == ATTR_PRIM_TRIANGLE) + if (prim == ATTR_PRIM_GEOMETRY) offset -= 3 * mesh->prim_offset; else offset -= mesh->corner_offset; @@ -720,38 +668,28 @@ void GeometryManager::device_update_attributes(Device *device, Geometry *geom = scene->geometry[i]; AttributeRequestSet &attributes = geom_attributes[i]; foreach (AttributeRequest &req, attributes.requests) { + Attribute *attr = geom->attributes.find(req); + + update_attribute_element_size(geom, + attr, + ATTR_PRIM_GEOMETRY, + &attr_float_size, + &attr_float2_size, + &attr_float3_size, + &attr_uchar4_size); + if (geom->type == Geometry::MESH) { Mesh *mesh = static_cast(geom); - Attribute *triangle_mattr = mesh->attributes.find(req); - Attribute *subd_mattr = mesh->subd_attributes.find(req); + Attribute *subd_attr = mesh->subd_attributes.find(req); update_attribute_element_size(mesh, - triangle_mattr, - ATTR_PRIM_TRIANGLE, - &attr_float_size, - &attr_float2_size, - &attr_float3_size, - &attr_uchar4_size); - update_attribute_element_size(mesh, - subd_mattr, + subd_attr, ATTR_PRIM_SUBD, &attr_float_size, &attr_float2_size, &attr_float3_size, &attr_uchar4_size); } - else if (geom->type == Geometry::HAIR) { - Hair *hair = static_cast(geom); - Attribute *curve_mattr = hair->attributes.find(req); - - update_attribute_element_size(hair, - curve_mattr, - ATTR_PRIM_CURVE, - &attr_float_size, - &attr_float2_size, - &attr_float3_size, - &attr_uchar4_size); - } } } @@ -773,10 +711,24 @@ void GeometryManager::device_update_attributes(Device *device, /* todo: we now store std and name attributes from requests even if * they actually refer to the same mesh attributes, optimize */ foreach (AttributeRequest &req, attributes.requests) { + Attribute *attr = geom->attributes.find(req); + update_attribute_element_offset(geom, + dscene->attributes_float, + attr_float_offset, + dscene->attributes_float2, + attr_float2_offset, + dscene->attributes_float3, + attr_float3_offset, + dscene->attributes_uchar4, + attr_uchar4_offset, + attr, + ATTR_PRIM_GEOMETRY, + req.type, + req.desc); + if (geom->type == Geometry::MESH) { Mesh *mesh = static_cast(geom); - Attribute *triangle_mattr = mesh->attributes.find(req); - Attribute *subd_mattr = mesh->subd_attributes.find(req); + Attribute *subd_attr = mesh->subd_attributes.find(req); update_attribute_element_offset(mesh, dscene->attributes_float, @@ -787,42 +739,11 @@ void GeometryManager::device_update_attributes(Device *device, attr_float3_offset, dscene->attributes_uchar4, attr_uchar4_offset, - triangle_mattr, - ATTR_PRIM_TRIANGLE, - req.triangle_type, - req.triangle_desc); - update_attribute_element_offset(mesh, - dscene->attributes_float, - attr_float_offset, - dscene->attributes_float2, - attr_float2_offset, - dscene->attributes_float3, - attr_float3_offset, - dscene->attributes_uchar4, - attr_uchar4_offset, - subd_mattr, + subd_attr, ATTR_PRIM_SUBD, req.subd_type, req.subd_desc); } - else if (geom->type == Geometry::HAIR) { - Hair *hair = static_cast(geom); - Attribute *curve_mattr = hair->attributes.find(req); - - update_attribute_element_offset(hair, - dscene->attributes_float, - attr_float_offset, - dscene->attributes_float2, - attr_float2_offset, - dscene->attributes_float3, - attr_float3_offset, - dscene->attributes_uchar4, - attr_uchar4_offset, - curve_mattr, - ATTR_PRIM_CURVE, - req.curve_type, - req.curve_desc); - } if (progress.get_cancel()) return; diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp index a35d4b6f1da..7220fe7093b 100644 --- a/intern/cycles/render/hair.cpp +++ b/intern/cycles/render/hair.cpp @@ -294,8 +294,6 @@ NODE_DEFINE(Hair) Hair::Hair() : Geometry(node_type, Geometry::HAIR) { curvekey_offset = 0; - - attributes.hair = this; } Hair::~Hair() @@ -368,7 +366,7 @@ void Hair::get_uv_tiles(ustring map, unordered_set &tiles) } if (attr) { - attr->get_uv_tiles(this, ATTR_PRIM_CURVE, tiles); + attr->get_uv_tiles(this, ATTR_PRIM_GEOMETRY, tiles); } } diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 792848e744a..e80e87f2980 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -135,7 +135,7 @@ NODE_DEFINE(Mesh) return type; } -Mesh::Mesh() : Geometry(node_type, Geometry::MESH) +Mesh::Mesh() : Geometry(node_type, Geometry::MESH), subd_attributes(this, ATTR_PRIM_SUBD) { vert_offset = 0; @@ -145,9 +145,6 @@ Mesh::Mesh() : Geometry(node_type, Geometry::MESH) num_subd_verts = 0; - attributes.triangle_mesh = this; - subd_attributes.subd_mesh = this; - volume_isovalue = 0.001f; num_ngons = 0; @@ -329,7 +326,9 @@ void Mesh::get_uv_tiles(ustring map, unordered_set &tiles) } if (attr) { - attr->get_uv_tiles(this, ATTR_PRIM_TRIANGLE, tiles); + attr->get_uv_tiles(this, ATTR_PRIM_GEOMETRY, tiles); + } + if (subd_attr) { subd_attr->get_uv_tiles(this, ATTR_PRIM_SUBD, tiles); } } @@ -546,8 +545,7 @@ void Mesh::add_undisplaced() float3 *data = attr->data_float3(); /* copy verts */ - size_t size = attr->buffer_size( - this, (subdivision_type == SUBDIVISION_NONE) ? ATTR_PRIM_TRIANGLE : ATTR_PRIM_SUBD); + size_t size = attr->buffer_size(this, attrs.prim); /* Center points for ngons aren't stored in Mesh::verts but are included in size since they will * be calculated later, we subtract them from size here so we don't have an overflow while -- cgit v1.2.3 From dfa7e1cd9f6d495c6bdf01a140fdc59b0cced38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 7 Feb 2020 12:58:01 +0100 Subject: Cleanup: reduced indentations by returning/continuing early No functional changes. --- source/blender/blenkernel/intern/fcurve.c | 394 +++++++++++++++--------------- 1 file changed, 196 insertions(+), 198 deletions(-) diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 833b8409f7d..5708cb0379b 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -204,29 +204,31 @@ FCurve *id_data_find_fcurve( RNA_pointer_create(id, type, data, &ptr); prop = RNA_struct_find_property(&ptr, prop_name); + if (prop == NULL) { + return NULL; + } - if (prop) { - path = RNA_path_from_ID_to_property(&ptr, prop); - - if (path) { - /* animation takes priority over drivers */ - if ((adt->action) && (adt->action->curves.first)) { - fcu = list_find_fcurve(&adt->action->curves, path, index); - } + path = RNA_path_from_ID_to_property(&ptr, prop); + if (path == NULL) { + return NULL; + } - /* if not animated, check if driven */ - if ((fcu == NULL) && (adt->drivers.first)) { - fcu = list_find_fcurve(&adt->drivers, path, index); - if (fcu && r_driven) { - *r_driven = true; - } - fcu = NULL; - } + /* animation takes priority over drivers */ + if (adt->action && adt->action->curves.first) { + fcu = list_find_fcurve(&adt->action->curves, path, index); + } - MEM_freeN(path); + /* if not animated, check if driven */ + if (fcu == NULL && adt->drivers.first) { + fcu = list_find_fcurve(&adt->drivers, path, index); + if (fcu && r_driven) { + *r_driven = true; } + fcu = NULL; } + MEM_freeN(path); + return fcu; } @@ -309,26 +311,28 @@ int list_find_data_fcurves(ListBase *dst, /* search each F-Curve one by one */ for (fcu = src->first; fcu; fcu = fcu->next) { /* check if quoted string matches the path */ - if ((fcu->rna_path) && strstr(fcu->rna_path, dataPrefix)) { - char *quotedName = BLI_str_quoted_substrN(fcu->rna_path, dataPrefix); + if (fcu->rna_path == NULL || !strstr(fcu->rna_path, dataPrefix)) { + continue; + } - if (quotedName) { - /* check if the quoted name matches the required name */ - if (STREQ(quotedName, dataName)) { - LinkData *ld = MEM_callocN(sizeof(LinkData), __func__); + char *quotedName = BLI_str_quoted_substrN(fcu->rna_path, dataPrefix); + if (quotedName == NULL) { + continue; + } - ld->data = fcu; - BLI_addtail(dst, ld); + /* check if the quoted name matches the required name */ + if (STREQ(quotedName, dataName)) { + LinkData *ld = MEM_callocN(sizeof(LinkData), __func__); - matches++; - } + ld->data = fcu; + BLI_addtail(dst, ld); - /* always free the quoted string, since it needs freeing */ - MEM_freeN(quotedName); - } + matches++; } - } + /* always free the quoted string, since it needs freeing */ + MEM_freeN(quotedName); + } /* return the number of matches */ return matches; } @@ -397,53 +401,58 @@ FCurve *rna_get_fcurve_context_ui(bContext *C, /* Standard F-Curve - Animation (Action) or Drivers */ while (adt && step--) { - if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) { - /* XXX this function call can become a performance bottleneck */ - if (step) { - path = RNA_path_from_ID_to_property(&tptr, prop); - } + if ((adt->action == NULL || adt->action->curves.first == NULL) && + (adt->drivers.first == NULL)) { + continue; + } - // XXX: the logic here is duplicated with a function up above - if (path) { - /* animation takes priority over drivers */ - if (adt->action && adt->action->curves.first) { - fcu = list_find_fcurve(&adt->action->curves, path, rnaindex); + /* XXX this function call can become a performance bottleneck */ + if (step) { + path = RNA_path_from_ID_to_property(&tptr, prop); + } + if (path == NULL) { + continue; + } - if (fcu && r_action) { - *r_action = adt->action; - } - } + // XXX: the logic here is duplicated with a function up above + /* animation takes priority over drivers */ + if (adt->action && adt->action->curves.first) { + fcu = list_find_fcurve(&adt->action->curves, path, rnaindex); - /* if not animated, check if driven */ - if (!fcu && (adt->drivers.first)) { - fcu = list_find_fcurve(&adt->drivers, path, rnaindex); + if (fcu && r_action) { + *r_action = adt->action; + } + } - if (fcu) { - if (r_animdata) { - *r_animdata = adt; - } - *r_driven = true; - } - } + /* if not animated, check if driven */ + if (!fcu && (adt->drivers.first)) { + fcu = list_find_fcurve(&adt->drivers, path, rnaindex); - if (fcu && r_action) { - if (r_animdata) { - *r_animdata = adt; - } - *r_action = adt->action; - break; - } - else if (step) { - char *tpath = BKE_animdata_driver_path_hack(C, &tptr, prop, path); - if (tpath && tpath != path) { - MEM_freeN(path); - path = tpath; - adt = BKE_animdata_from_id(tptr.owner_id); - } - else { - adt = NULL; - } + if (fcu) { + if (r_animdata) { + *r_animdata = adt; } + *r_driven = true; + } + } + + if (fcu && r_action) { + if (r_animdata) { + *r_animdata = adt; + } + *r_action = adt->action; + break; + } + + if (step) { + char *tpath = BKE_animdata_driver_path_hack(C, &tptr, prop, path); + if (tpath && tpath != path) { + MEM_freeN(path); + path = tpath; + adt = BKE_animdata_from_id(tptr.owner_id); + } + else { + adt = NULL; } } } @@ -476,29 +485,28 @@ static int binarysearch_bezt_index_ex( CLOG_WARN(&LOG, "encountered invalid array"); return 0; } - else { - /* check whether to add before/after/on */ - float framenum; - /* 'First' Keyframe (when only one keyframe, this case is used) */ - framenum = array[0].vec[1][0]; - if (IS_EQT(frame, framenum, threshold)) { - *r_replace = true; - return 0; - } - else if (frame < framenum) { - return 0; - } + /* check whether to add before/after/on */ + float framenum; - /* 'Last' Keyframe */ - framenum = array[(arraylen - 1)].vec[1][0]; - if (IS_EQT(frame, framenum, threshold)) { - *r_replace = true; - return (arraylen - 1); - } - else if (frame > framenum) { - return arraylen; - } + /* 'First' Keyframe (when only one keyframe, this case is used) */ + framenum = array[0].vec[1][0]; + if (IS_EQT(frame, framenum, threshold)) { + *r_replace = true; + return 0; + } + if (frame < framenum) { + return 0; + } + + /* 'Last' Keyframe */ + framenum = array[(arraylen - 1)].vec[1][0]; + if (IS_EQT(frame, framenum, threshold)) { + *r_replace = true; + return (arraylen - 1); + } + if (frame > framenum) { + return arraylen; } /* most of the time, this loop is just to find where to put it @@ -1171,41 +1179,42 @@ void testhandles_fcurve(FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_ha */ void sort_time_fcurve(FCurve *fcu) { + if (fcu->bezt == NULL) { + return; + } /* keep adjusting order of beztriples until nothing moves (bubble-sort) */ - if (fcu->bezt) { - BezTriple *bezt; - uint a; - - bool ok = true; - while (ok) { - ok = 0; - /* currently, will only be needed when there are beztriples */ - - /* loop over ALL points to adjust position in array and recalculate handles */ - for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) { - /* check if thee's a next beztriple which we could try to swap with current */ - if (a < (fcu->totvert - 1)) { - /* swap if one is after the other (and indicate that order has changed) */ - if (bezt->vec[1][0] > (bezt + 1)->vec[1][0]) { - SWAP(BezTriple, *bezt, *(bezt + 1)); - ok = 1; - } + BezTriple *bezt; + uint a; + + bool ok = true; + while (ok) { + ok = 0; + /* currently, will only be needed when there are beztriples */ + + /* loop over ALL points to adjust position in array and recalculate handles */ + for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) { + /* check if thee's a next beztriple which we could try to swap with current */ + if (a < (fcu->totvert - 1)) { + /* swap if one is after the other (and indicate that order has changed) */ + if (bezt->vec[1][0] > (bezt + 1)->vec[1][0]) { + SWAP(BezTriple, *bezt, *(bezt + 1)); + ok = 1; } } } + } - for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) { - /* if either one of both of the points exceeds crosses over the keyframe time... */ - if ((bezt->vec[0][0] > bezt->vec[1][0]) && (bezt->vec[2][0] < bezt->vec[1][0])) { - /* swap handles if they have switched sides for some reason */ - swap_v2_v2(bezt->vec[0], bezt->vec[2]); - } - else { - /* clamp handles */ - CLAMP_MAX(bezt->vec[0][0], bezt->vec[1][0]); - CLAMP_MIN(bezt->vec[2][0], bezt->vec[1][0]); - } + for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) { + /* if either one of both of the points exceeds crosses over the keyframe time... */ + if ((bezt->vec[0][0] > bezt->vec[1][0]) && (bezt->vec[2][0] < bezt->vec[1][0])) { + /* swap handles if they have switched sides for some reason */ + swap_v2_v2(bezt->vec[0], bezt->vec[2]); + } + else { + /* clamp handles */ + CLAMP_MAX(bezt->vec[0][0], bezt->vec[1][0]); + CLAMP_MIN(bezt->vec[2][0], bezt->vec[1][0]); } } } @@ -2539,11 +2548,10 @@ static int findzero(float x, float q0, float q1, float q2, float q3, float *o) if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) { return 1; } - else { - return 0; - } + return 0; } - else if (d == 0.0) { + + if (d == 0.0) { t = sqrt3d(-q); o[0] = (float)(2 * t - a); @@ -2555,87 +2563,78 @@ static int findzero(float x, float q0, float q1, float q2, float q3, float *o) if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) { return nr + 1; } - else { - return nr; - } + return nr; } - else { - phi = acos(-q / sqrt(-(p * p * p))); - t = sqrt(-p); - p = cos(phi / 3); - q = sqrt(3 - 3 * p * p); - o[0] = (float)(2 * t * p - a); - if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) { - nr++; - } - o[nr] = (float)(-t * (p + q) - a); + phi = acos(-q / sqrt(-(p * p * p))); + t = sqrt(-p); + p = cos(phi / 3); + q = sqrt(3 - 3 * p * p); + o[0] = (float)(2 * t * p - a); - if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) { - nr++; - } - o[nr] = (float)(-t * (p - q) - a); + if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) { + nr++; + } + o[nr] = (float)(-t * (p + q) - a); - if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) { - return nr + 1; - } - else { - return nr; - } + if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) { + nr++; } - } - else { - a = c2; - b = c1; - c = c0; + o[nr] = (float)(-t * (p - q) - a); - if (a != 0.0) { - /* discriminant */ - p = b * b - 4 * a * c; + if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) { + return nr + 1; + } + return nr; + } + a = c2; + b = c1; + c = c0; - if (p > 0) { - p = sqrt(p); - o[0] = (float)((-b - p) / (2 * a)); + if (a != 0.0) { + /* discriminant */ + p = b * b - 4 * a * c; - if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) { - nr++; - } - o[nr] = (float)((-b + p) / (2 * a)); + if (p > 0) { + p = sqrt(p); + o[0] = (float)((-b - p) / (2 * a)); - if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) { - return nr + 1; - } - else { - return nr; - } + if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) { + nr++; } - else if (p == 0) { - o[0] = (float)(-b / (2 * a)); - if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) { - return 1; - } - else { - return 0; - } + o[nr] = (float)((-b + p) / (2 * a)); + + if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) { + return nr + 1; } + return nr; } - else if (b != 0.0) { - o[0] = (float)(-c / b); + if (p == 0) { + o[0] = (float)(-b / (2 * a)); if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) { return 1; } - else { - return 0; - } } - else if (c == 0.0) { - o[0] = 0.0; + + return 0; + } + + if (b != 0.0) { + o[0] = (float)(-c / b); + + if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) { return 1; } - return 0; } + + if (c == 0.0) { + o[0] = 0.0; + return 1; + } + + return 0; } static void berekeny(float f1, float f2, float f3, float f4, float *o, int b) @@ -3244,19 +3243,18 @@ float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime) /* only calculate + set curval (overriding the existing value) if curve has * any data which warrants this... */ - if (!BKE_fcurve_is_empty(fcu)) { - /* calculate and set curval (evaluates driver too if necessary) */ - float curval; - if (fcu->driver) { - curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, evaltime); - } - else { - curval = evaluate_fcurve(fcu, evaltime); - } - fcu->curval = curval; /* debug display only, not thread safe! */ - return curval; + if (BKE_fcurve_is_empty(fcu)) { + return 0.0f; + } + + /* calculate and set curval (evaluates driver too if necessary) */ + float curval; + if (fcu->driver) { + curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, evaltime); } else { - return 0.0f; + curval = evaluate_fcurve(fcu, evaltime); } + fcu->curval = curval; /* debug display only, not thread safe! */ + return curval; } -- cgit v1.2.3 From 3e738a60d06acc3ebecc8f4e23bf0262d7b57f3c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 7 Feb 2020 12:20:05 +0100 Subject: Cleanup: Tracking, reduce scope of variables --- source/blender/blenkernel/intern/tracking.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 37ca6b1885d..9caecb73e89 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -836,7 +836,7 @@ void BKE_tracking_tracks_join(MovieTracking *tracking, MovieTrackingMarker *marker_a, *marker_b; int start_a = a, start_b = b, len = 0, frame = src_track->markers[a].framenr; - int j, inverse = 0; + int inverse = 0; inverse = (b == 0) || (dst_track->markers[b - 1].flag & MARKER_DISABLED) || (dst_track->markers[b - 1].framenr != frame - 1); @@ -864,7 +864,7 @@ void BKE_tracking_tracks_join(MovieTracking *tracking, b = start_b; /* linear interpolation for intersecting frames */ - for (j = 0; j < len; j++) { + for (int j = 0; j < len; j++) { float fac = 0.5f; if (len > 1) { @@ -2897,8 +2897,6 @@ static void tracking_dopesheet_channels_calc(MovieTracking *tracking) bool show_hidden = (dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN) != 0; for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { - MovieTrackingDopesheetChannel *channel; - if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0) { continue; } @@ -2907,7 +2905,8 @@ static void tracking_dopesheet_channels_calc(MovieTracking *tracking) continue; } - channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel"); + MovieTrackingDopesheetChannel *channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), + "tracking dopesheet channel"); channel->track = track; if (reconstruction->flag & TRACKING_RECONSTRUCTED) { -- cgit v1.2.3 From f81fe8a3a0711a416091081b5e25256031d94e77 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 7 Feb 2020 12:51:18 +0100 Subject: Cleanup: Tracking, use LISTBASE_FOREACH Makes loops declaration shorter and cleaner. --- source/blender/blenkernel/intern/tracking.c | 46 +++++++++------------- source/blender/blenkernel/intern/tracking_auto.c | 11 +++--- source/blender/blenkernel/intern/tracking_solver.c | 2 +- .../blender/blenkernel/intern/tracking_stabilize.c | 18 ++++----- 4 files changed, 33 insertions(+), 44 deletions(-) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 9caecb73e89..86fb2ab58bc 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -80,7 +80,7 @@ static struct { /* Free the whole list of tracks, list's head and tail are set to NULL. */ static void tracking_tracks_free(ListBase *tracks) { - for (MovieTrackingTrack *track = tracks->first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks) { BKE_tracking_track_free(track); } @@ -90,8 +90,7 @@ static void tracking_tracks_free(ListBase *tracks) /* Free the whole list of plane tracks, list's head and tail are set to NULL. */ static void tracking_plane_tracks_free(ListBase *plane_tracks) { - for (MovieTrackingPlaneTrack *plane_track = plane_tracks->first; plane_track; - plane_track = plane_track->next) { + LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks) { BKE_tracking_plane_track_free(plane_track); } @@ -126,7 +125,7 @@ static void tracking_object_free(MovieTrackingObject *object) static void tracking_objects_free(ListBase *objects) { /* Free objects contents. */ - for (MovieTrackingObject *object = objects->first; object; object = object->next) { + LISTBASE_FOREACH (MovieTrackingObject *, object, objects) { tracking_object_free(object); } @@ -189,8 +188,7 @@ static void tracking_tracks_copy(ListBase *tracks_dst, BLI_listbase_clear(tracks_dst); BLI_ghash_clear(tracks_mapping, NULL, NULL); - for (MovieTrackingTrack *track_src = tracks_src->first; track_src != NULL; - track_src = track_src->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track_src, tracks_src) { MovieTrackingTrack *track_dst = MEM_dupallocN(track_src); if (track_src->markers) { track_dst->markers = MEM_dupallocN(track_src->markers); @@ -213,9 +211,7 @@ static void tracking_plane_tracks_copy(ListBase *plane_tracks_list_dst, { BLI_listbase_clear(plane_tracks_list_dst); - for (MovieTrackingPlaneTrack *plane_track_src = plane_tracks_list_src->first; - plane_track_src != NULL; - plane_track_src = plane_track_src->next) { + LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track_src, plane_tracks_list_src) { MovieTrackingPlaneTrack *plane_track_dst = MEM_dupallocN(plane_track_src); if (plane_track_src->markers) { plane_track_dst->markers = MEM_dupallocN(plane_track_src->markers); @@ -273,8 +269,7 @@ static void tracking_objects_copy(ListBase *objects_dst, { BLI_listbase_clear(objects_dst); - for (MovieTrackingObject *object_src = objects_src->first; object_src != NULL; - object_src = object_src->next) { + LISTBASE_FOREACH (MovieTrackingObject *, object_src, objects_src) { MovieTrackingObject *object_dst = MEM_mallocN(sizeof(*object_dst), __func__); tracking_object_copy(object_dst, object_src, tracks_mapping, flag); BLI_addtail(objects_dst, object_dst); @@ -1172,7 +1167,7 @@ void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area) void BKE_tracking_tracks_deselect_all(ListBase *tracksbase) { - for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { if ((track->flag & TRACK_HIDDEN) == 0) { BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } @@ -1445,15 +1440,14 @@ MovieTrackingPlaneTrack *BKE_tracking_plane_track_add(MovieTracking *tracking, { MovieTrackingPlaneTrack *plane_track; MovieTrackingPlaneMarker plane_marker; - MovieTrackingTrack *track; float tracks_min[2], tracks_max[2]; - int track_index, num_selected_tracks = 0; + int num_selected_tracks = 0; (void)tracking; /* Ignored. */ /* Use bounding box of selected markers as an initial size of plane. */ INIT_MINMAX2(tracks_min, tracks_max); - for (track = tracks->first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks) { if (TRACK_SELECTED(track)) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); float pattern_min[2], pattern_max[2]; @@ -1481,7 +1475,8 @@ MovieTrackingPlaneTrack *BKE_tracking_plane_track_add(MovieTracking *tracking, /* Use selected tracks from given list as a plane. */ plane_track->point_tracks = MEM_mallocN(sizeof(MovieTrackingTrack *) * num_selected_tracks, "new plane tracks array"); - for (track = tracks->first, track_index = 0; track; track = track->next) { + int track_index = 0; + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks) { if (TRACK_SELECTED(track)) { plane_track->point_tracks[track_index] = track; track_index++; @@ -1541,8 +1536,7 @@ MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_named(MovieTracking *track { ListBase *plane_tracks_base = BKE_tracking_object_get_plane_tracks(tracking, object); - for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; - plane_track = plane_track->next) { + LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) { if (STREQ(plane_track->name, name)) { return plane_track; } @@ -1569,8 +1563,7 @@ MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_active(struct MovieTrackin void BKE_tracking_plane_tracks_deselect_all(ListBase *plane_tracks_base) { - for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; - plane_track = plane_track->next) { + LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) { plane_track->flag &= ~SELECT; } } @@ -1612,10 +1605,8 @@ bool BKE_tracking_plane_track_remove_point_track(MovieTrackingPlaneTrack *plane_ void BKE_tracking_plane_tracks_remove_point_track(MovieTracking *tracking, MovieTrackingTrack *track) { - MovieTrackingPlaneTrack *plane_track, *next_plane_track; ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); - for (plane_track = plane_tracks_base->first; plane_track; plane_track = next_plane_track) { - next_plane_track = plane_track->next; + LISTBASE_FOREACH_MUTABLE (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) { if (BKE_tracking_plane_track_has_point_track(plane_track, track)) { if (!BKE_tracking_plane_track_remove_point_track(plane_track, track)) { /* Delete planes with less than 3 point tracks in it. */ @@ -1643,8 +1634,7 @@ void BKE_tracking_plane_tracks_replace_point_track(MovieTracking *tracking, MovieTrackingTrack *new_track) { ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); - for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; - plane_track = plane_track->next) { + LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) { if (BKE_tracking_plane_track_has_point_track(plane_track, old_track)) { BKE_tracking_plane_track_replace_point_track(plane_track, old_track, new_track); } @@ -2896,7 +2886,7 @@ static void tracking_dopesheet_channels_calc(MovieTracking *tracking) bool sel_only = (dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY) != 0; bool show_hidden = (dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN) != 0; - for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0) { continue; } @@ -2988,7 +2978,7 @@ static void tracking_dopesheet_calc_coverage(MovieTracking *tracking) int prev_coverage, last_segment_frame; /* find frame boundaries */ - for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { start_frame = min_ii(start_frame, track->markers[0].framenr); end_frame = max_ii(end_frame, track->markers[track->markersnr - 1].framenr); } @@ -2999,7 +2989,7 @@ static void tracking_dopesheet_calc_coverage(MovieTracking *tracking) per_frame_counter = MEM_callocN(sizeof(int) * frames, "per frame track counter"); /* find per-frame markers count */ - for (MovieTrackingTrack *track = tracksbase->first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { for (int i = 0; i < track->markersnr; i++) { MovieTrackingMarker *marker = &track->markers[i]; diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c index 1a4df73c8aa..9d8395defcd 100644 --- a/source/blender/blenkernel/intern/tracking_auto.c +++ b/source/blender/blenkernel/intern/tracking_auto.c @@ -258,7 +258,7 @@ static void fill_autotrack_tracks(const int frame_width, { /* Count number of markers to be put to a context. */ size_t num_trackable_markers = 0; - for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { for (int i = 0; i < track->markersnr; i++) { const MovieTrackingMarker *marker = track->markers + i; if ((marker->flag & MARKER_DISABLED) == 0) { @@ -275,7 +275,7 @@ static void fill_autotrack_tracks(const int frame_width, "libmv markers array"); /* Fill in markers array. */ int track_index = 0, num_filled_libmv_markers = 0; - for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { for (int i = 0; i < track->markersnr; i++) { MovieTrackingMarker *marker = track->markers + i; if ((marker->flag & MARKER_DISABLED) != 0) { @@ -305,7 +305,7 @@ static void create_per_track_tracking_options(const MovieClip *clip, AutoTrackContext *context) { /* Count number of trackable tracks. */ - for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { if (check_track_trackable(clip, track, user)) { context->num_tracks++; } @@ -315,7 +315,7 @@ static void create_per_track_tracking_options(const MovieClip *clip, "auto track options"); /* Fill in all the settings. */ int i = 0, track_index = 0; - for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) { if (!check_track_trackable(clip, track, user)) { track_index++; continue; @@ -523,8 +523,7 @@ void BKE_autotrack_context_finish(AutoTrackContext *context) MovieClip *clip = context->clips[clip_index]; ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); - for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; - plane_track = plane_track->next) { + LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) { if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { for (int track = 0; track < context->num_tracks; track++) { if (BKE_tracking_plane_track_has_point_track(plane_track, diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c index bedb55ae44e..527a2f59491 100644 --- a/source/blender/blenkernel/intern/tracking_solver.c +++ b/source/blender/blenkernel/intern/tracking_solver.c @@ -613,7 +613,7 @@ static void tracking_scale_reconstruction(ListBase *tracksbase, */ void BKE_tracking_reconstruction_scale(MovieTracking *tracking, float scale[3]) { - for (MovieTrackingObject *object = tracking->objects.first; object; object = object->next) { + LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) { ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); MovieTrackingReconstruction *reconstruction = BKE_tracking_object_get_reconstruction(tracking, object); diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c index d2d60e93a08..b5b33353ed7 100644 --- a/source/blender/blenkernel/intern/tracking_stabilize.c +++ b/source/blender/blenkernel/intern/tracking_stabilize.c @@ -34,6 +34,7 @@ #include "BLI_sort_utils.h" #include "BLI_ghash.h" #include "BLI_math_vector.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_task.h" @@ -332,8 +333,7 @@ static void find_next_working_frames(StabContext *ctx, int *next_lower, int *next_higher) { - for (MovieTrackingTrack *track = ctx->tracking->tracks.first; track != NULL; - track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, &ctx->tracking->tracks) { if (is_usable_for_stabilization(ctx, track)) { int startpoint = search_closest_marker_index(track, framenr); retrieve_next_higher_usable_frame(ctx, track, startpoint, framenr, next_higher); @@ -558,7 +558,7 @@ static bool average_track_contributions(StabContext *ctx, ok = false; weight_sum = 0.0f; - for (MovieTrackingTrack *track = tracking->tracks.first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) { if (!is_init_for_stabilization(ctx, track)) { continue; } @@ -596,7 +596,7 @@ static bool average_track_contributions(StabContext *ctx, ok = false; weight_sum = 0.0f; - for (MovieTrackingTrack *track = tracking->tracks.first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) { if (!is_init_for_stabilization(ctx, track)) { continue; } @@ -655,7 +655,7 @@ static void average_marker_positions(StabContext *ctx, int framenr, float r_ref_ zero_v2(r_ref_pos); weight_sum = 0.0f; - for (MovieTrackingTrack *track = tracking->tracks.first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) { if (track->flag & TRACK_USE_2D_STAB) { float weight = 0.0f; MovieTrackingMarker *marker = get_tracking_data_point(ctx, track, framenr, &weight); @@ -678,7 +678,7 @@ static void average_marker_positions(StabContext *ctx, int framenr, float r_ref_ int next_lower = MINAFRAME; int next_higher = MAXFRAME; use_values_from_fcurves(ctx, true); - for (MovieTrackingTrack *track = tracking->tracks.first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) { /* Note: we deliberately do not care if this track * is already initialized for stabilization. */ if (track->flag & TRACK_USE_2D_STAB) { @@ -772,7 +772,7 @@ static int establish_track_initialization_order(StabContext *ctx, TrackInitOrder MovieTracking *tracking = ctx->tracking; int anchor_frame = tracking->stabilization.anchor_frame; - for (MovieTrackingTrack *track = tracking->tracks.first; track != NULL; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) { MovieTrackingMarker *marker; order[tracknr].data = track; marker = get_closest_marker(ctx, track, anchor_frame); @@ -892,7 +892,7 @@ static void initialize_all_tracks(StabContext *ctx, float aspect) zero_v2(pivot); /* Initialize private working data. */ - for (MovieTrackingTrack *track = tracking->tracks.first; track != NULL; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) { TrackStabilizationBase *local_data = access_stabilization_baseline_data(ctx, track); if (!local_data) { local_data = MEM_callocN(sizeof(TrackStabilizationBase), @@ -1142,7 +1142,7 @@ static float calculate_autoscale_factor(StabContext *ctx, int size, float aspect float scale = 1.0f, scale_step = 0.0f; /* Calculate maximal frame range of tracks where stabilization is active. */ - for (MovieTrackingTrack *track = ctx->tracking->tracks.first; track; track = track->next) { + LISTBASE_FOREACH (MovieTrackingTrack *, track, &ctx->tracking->tracks) { if ((track->flag & TRACK_USE_2D_STAB) || ((stab->flag & TRACKING_STABILIZE_ROTATION) && (track->flag & TRACK_USE_2D_STAB_ROT))) { int first_frame = track->markers[0].framenr; -- cgit v1.2.3 From 6dc9f89c6a06f3e7870177c5067f58520c6d275c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 7 Feb 2020 13:52:01 +0100 Subject: Constraint: Fix forced request of evaluated camera Constraint stack similarly to modifier stack is fully operate on what have been given to it, without requesting original or evaluated IDs. Validness of datablocks passed to constraint stack are to be handled on dependency graph/evaluation stream levels. --- source/blender/blenkernel/intern/constraint.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index a17a09297c5..708d0600e91 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -4557,9 +4557,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase MovieTracking *tracking; MovieTrackingTrack *track; MovieTrackingObject *tracking_object; - - Object *camob_eval = DEG_get_evaluated_object(depsgraph, - data->camera ? data->camera : scene->camera); + Object *camob = data->camera ? data->camera : scene->camera; float ctime = DEG_get_ctime(depsgraph); float framenr; @@ -4568,7 +4566,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase clip = scene->clip; } - if (!clip || !data->track[0] || !camob_eval) { + if (!clip || !data->track[0] || !camob) { return; } @@ -4602,7 +4600,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) { float imat[4][4]; - copy_m4_m4(mat, camob_eval->obmat); + copy_m4_m4(mat, camob->obmat); BKE_tracking_camera_get_reconstructed_interpolate( tracking, tracking_object, framenr, imat); @@ -4613,7 +4611,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); } else { - BKE_tracking_get_camera_object_matrix(cob->scene, camob_eval, mat); + BKE_tracking_get_camera_object_matrix(cob->scene, camob, mat); mul_m4_m4m4(cob->matrix, obmat, mat); translate_m4( @@ -4626,7 +4624,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase float aspect = (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp); float len, d; - BKE_object_where_is_calc_mat4(camob_eval, mat); + BKE_object_where_is_calc_mat4(camob, mat); /* camera axis */ vec[0] = 0.0f; @@ -4694,7 +4692,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase } BKE_camera_params_init(¶ms); - BKE_camera_params_from_object(¶ms, camob_eval); + BKE_camera_params_from_object(¶ms, camob); if (params.is_ortho) { vec[0] = params.ortho_scale * (pos[0] - 0.5f + params.shiftx); @@ -4708,9 +4706,9 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase vec[0] *= aspect; } - mul_v3_m4v3(disp, camob_eval->obmat, vec); + mul_v3_m4v3(disp, camob->obmat, vec); - copy_m4_m4(rmat, camob_eval->obmat); + copy_m4_m4(rmat, camob->obmat); zero_v3(rmat[3]); mul_m4_m4m4(cob->matrix, cob->matrix, rmat); @@ -4730,10 +4728,10 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase vec[0] *= aspect; } - mul_v3_m4v3(disp, camob_eval->obmat, vec); + mul_v3_m4v3(disp, camob->obmat, vec); /* apply camera rotation so Z-axis would be co-linear */ - copy_m4_m4(rmat, camob_eval->obmat); + copy_m4_m4(rmat, camob->obmat); zero_v3(rmat[3]); mul_m4_m4m4(cob->matrix, cob->matrix, rmat); @@ -4751,7 +4749,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase invert_m4_m4(imat, depth_ob->obmat); - mul_v3_m4v3(ray_start, imat, camob_eval->obmat[3]); + mul_v3_m4v3(ray_start, imat, camob->obmat[3]); mul_v3_m4v3(ray_end, imat, cob->matrix[3]); sub_v3_v3v3(ray_nor, ray_end, ray_start); -- cgit v1.2.3 From ccda7ef9961314a7e60a3f81bd63171dbde0019c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 7 Feb 2020 13:56:04 +0100 Subject: Cleanup: Animation, match parameter names in declaration with implementation The implementation had more descriptive parameter names, so I copied those to the declarations. No functional changes. --- source/blender/blenkernel/BKE_fcurve.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 405b052f477..d389b557503 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -87,7 +87,7 @@ void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt); void fcurve_free_driver(struct FCurve *fcu); struct ChannelDriver *fcurve_copy_driver(const struct ChannelDriver *driver); -void driver_variables_copy(struct ListBase *dst_list, const struct ListBase *src_list); +void driver_variables_copy(struct ListBase *dst_vars, const struct ListBase *src_vars); void BKE_driver_target_matrix_to_rot_channels( float mat[4][4], int auto_order, int rotation_mode, int channel, bool angles, float r_buf[4]); @@ -280,7 +280,7 @@ struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, - struct AnimData **r_adt, + struct AnimData **r_animdata, struct bAction **r_action, bool *r_driven, bool *r_special); -- cgit v1.2.3 From b40ac820524b1fa7124c38ebd2ac02beb23c048a Mon Sep 17 00:00:00 2001 From: mano-wii Date: Fri, 7 Feb 2020 10:02:11 -0300 Subject: Cleanup: transform_convert comment and spacing --- .../blender/editors/transform/transform_convert.h | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index 53ff9952d05..e81a896e062 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -19,6 +19,7 @@ /** \file * \ingroup edtransform + * \brief conversion and adaptation of different datablocks to a common struct. */ #ifndef __TRANSFORM_CONVERT_H__ @@ -60,28 +61,38 @@ void clipUVData(TransInfo *t); /* transform_convert_action.c */ void flushTransIntFrameActionData(TransInfo *t); + /* transform_convert_armature.c */ void restoreMirrorPoseBones(TransDataContainer *tc); void restoreBones(TransDataContainer *tc); + /* transform_convert_graph.c */ void flushTransGraphData(TransInfo *t); + /* transform_convert_mask.c */ void flushTransMasking(TransInfo *t); + /* transform_convert_mesh.c */ void flushTransUVs(TransInfo *t); void trans_mesh_customdata_correction_init(TransInfo *t); void trans_mesh_customdata_correction_apply(struct TransDataContainer *tc, bool is_final); + /* transform_convert_node.c */ void flushTransNodes(TransInfo *t); + /* transform_convert_object.c */ void trans_obdata_in_obmode_update_all(struct TransInfo *t); void trans_obchild_in_obmode_update_all(struct TransInfo *t); + /* transform_convert_paintcurve.c */ void flushTransPaintCurve(TransInfo *t); + /* transform_convert_particle.c */ void flushTransParticles(TransInfo *t); + /* transform_convert_sequencer.c */ void flushTransSeq(TransInfo *t); + /* transform_convert_tracking.c */ void flushTransTracking(TransInfo *t); @@ -96,45 +107,62 @@ bool FrameOnMouseSide(char side, float frame, float cframe); /* transform_convert_action.c */ void createTransActionData(bContext *C, TransInfo *t); + /* transform_convert_armature.c */ struct bKinematicConstraint *has_targetless_ik(struct bPoseChannel *pchan); void createTransPose(TransInfo *t); void createTransArmatureVerts(TransInfo *t); + /* transform_convert_cursor.c */ void createTransCursor_image(TransInfo *t); void createTransCursor_view3d(TransInfo *t); + /* transform_convert_curve.c */ void createTransCurveVerts(TransInfo *t); + /* transform_convert_graph.c */ void createTransGraphEditData(bContext *C, TransInfo *t); + /* transform_convert_gpencil.c */ void createTransGPencil(bContext *C, TransInfo *t); + /* transform_convert_lattice.c */ void createTransLatticeVerts(TransInfo *t); + /* transform_convert_mask.c */ void createTransMaskingData(bContext *C, TransInfo *t); + /* transform_convert_mball.c */ void createTransMBallVerts(TransInfo *t); + /* transform_convert_mesh.c */ void createTransEditVerts(TransInfo *t); void createTransEdge(TransInfo *t); void createTransUVs(bContext *C, TransInfo *t); + /* transform_convert_nla.c */ void createTransNlaData(bContext *C, TransInfo *t); + /* transform_convert_node.c */ void createTransNodeData(bContext *UNUSED(C), TransInfo *t); + /* transform_convert_object.c */ void clear_trans_object_base_flags(TransInfo *t); void createTransObject(bContext *C, TransInfo *t); void createTransTexspace(TransInfo *t); + /* transform_convert_paintcurve.c */ void createTransPaintCurveVerts(bContext *C, TransInfo *t); + /* transform_convert_particle.c */ void createTransParticleVerts(bContext *C, TransInfo *t); + /* transform_convert_sculpt.c */ void createTransSculpt(TransInfo *t); + /* transform_convert_sequence.c */ void createTransSeqData(bContext *C, TransInfo *t); + /* transform_convert_tracking.c */ void createTransTrackingData(bContext *C, TransInfo *t); void cancelTransTracking(TransInfo *t); -- cgit v1.2.3 From 636fe3df0e95999d5a2029c913a8812fd95fe25a Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 7 Feb 2020 14:14:50 +0100 Subject: CodeCleanup: Workbench Code was already hidden by a compile directive. --- .../draw/engines/workbench/workbench_forward.c | 2 +- .../draw/engines/workbench/workbench_studiolight.c | 57 ---------------------- 2 files changed, 1 insertion(+), 58 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index fcdf24d2d2f..05494b79af0 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -665,7 +665,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) return; } - WORKBENCH_MaterialData *material; + WORKBENCH_MaterialData *material = NULL; if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) { const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) && !DRW_state_is_image_render(); diff --git a/source/blender/draw/engines/workbench/workbench_studiolight.c b/source/blender/draw/engines/workbench/workbench_studiolight.c index 941a6741998..1fb0b394cb1 100644 --- a/source/blender/draw/engines/workbench/workbench_studiolight.c +++ b/source/blender/draw/engines/workbench/workbench_studiolight.c @@ -69,63 +69,6 @@ void studiolight_update_world(WORKBENCH_PrivateData *wpd, } copy_v3_v3(wd->ambient_color, studiolight->light_ambient); - -#if 0 - BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED); - -# if STUDIOLIGHT_SH_BANDS == 2 - /* Use Geomerics non-linear SH. */ - mul_v3_v3fl(wd->spherical_harmonics_coefs[0], sl->spherical_harmonics_coefs[0], M_1_PI); - /* Swizzle to make shader code simpler. */ - for (int i = 0; i < 3; i++) { - copy_v3_fl3(wd->spherical_harmonics_coefs[i + 1], - -sl->spherical_harmonics_coefs[3][i], - sl->spherical_harmonics_coefs[2][i], - -sl->spherical_harmonics_coefs[1][i]); - - /* 1.5f is to improve the contrast a bit. */ - mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], M_1_PI * 1.5f); - } - - /* Precompute as much as we can. See shader code for derivation. */ - float len_r1[3], lr1_r0[3], p[3], a[3]; - for (int i = 0; i < 3; i++) { - mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], 0.5f); - len_r1[i] = len_v3(wd->spherical_harmonics_coefs[i + 1]); - mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], 1.0f / len_r1[i]); - } - /* lr1_r0 = lenR1 / R0; */ - copy_v3_v3(lr1_r0, wd->spherical_harmonics_coefs[0]); - invert_v3(lr1_r0); - mul_v3_v3(lr1_r0, len_r1); - /* p = 1.0 + 2.0 * lr1_r0; */ - copy_v3_v3(p, lr1_r0); - mul_v3_fl(p, 2.0f); - add_v3_fl(p, 1.0f); - /* a = (1.0 - lr1_r0) / (1.0 + lr1_r0); */ - copy_v3_v3(a, lr1_r0); - add_v3_fl(a, 1.0f); - invert_v3(a); - negate_v3(lr1_r0); - add_v3_fl(lr1_r0, 1.0f); - mul_v3_v3(a, lr1_r0); - /* sh_coefs[4] = p; */ - copy_v3_v3(wd->spherical_harmonics_coefs[4], p); - /* sh_coefs[5] = R0 * a; */ - mul_v3_v3v3(wd->spherical_harmonics_coefs[5], wd->spherical_harmonics_coefs[0], a); - /* sh_coefs[0] = R0 * (1.0 - a) * (p + 1.0); */ - negate_v3(a); - add_v3_fl(a, 1.0f); - add_v3_fl(p, 1.0f); - mul_v3_v3(a, p); - mul_v3_v3(wd->spherical_harmonics_coefs[0], a); -# else - for (int i = 0; i < STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN; i++) { - /* Can't memcpy because of alignment */ - copy_v3_v3(wd->spherical_harmonics_coefs[i], sl->spherical_harmonics_coefs[i]); - } -# endif -#endif } static void compute_parallel_lines_nor_and_dist(const float v1[2], -- cgit v1.2.3 From 91c64b5ca330e1e940a9b60507b30e7aff54c7be Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 7 Feb 2020 14:19:08 +0100 Subject: CodeCleanup: Remove unused studiolight algorithm Code was originally added to test a different approach to calculate the irradiance buffer. The approach was just to slow so we never used it. This change will remove it from the code base --- source/blender/blenkernel/intern/studiolight.c | 62 -------------------------- 1 file changed, 62 deletions(-) diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 9008348ed3b..4a69fcfa9d0 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -56,17 +56,6 @@ static int last_studiolight_id = 0; #define STUDIOLIGHT_IRRADIANCE_EQUIRECT_WIDTH (STUDIOLIGHT_IRRADIANCE_EQUIRECT_HEIGHT * 2) #define STUDIOLIGHT_PASSNAME_DIFFUSE "diffuse" #define STUDIOLIGHT_PASSNAME_SPECULAR "specular" -/* - * The method to calculate the irradiance buffers - * The irradiance buffer is only shown in the background when in LookDev. - * - * STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE is very slow, but very accurate - * STUDIOLIGHT_IRRADIANCE_METHOD_SPHERICAL_HARMONICS is faster but has artifacts - * Cannot have both enabled at the same time!!! - */ -// #define STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE -#define STUDIOLIGHT_IRRADIANCE_METHOD_SPHERICAL_HARMONICS - /* Temporarily disabled due to the creation of textures with -nan(ind)s */ #define STUDIOLIGHT_SH_WINDOWING 0.0f /* 0.0 is disabled */ @@ -1024,40 +1013,6 @@ BLI_INLINE void studiolight_evaluate_specular_radiance_buffer(ImBuf *radiance_bu madd_v3_v3fl(color, accum, 1.0f / accum_weight); } -#ifdef STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE -static void studiolight_irradiance_eval(StudioLight *sl, float color[3], const float normal[3]) -{ - copy_v3_fl(color, 0.0f); - - /* XXX: This is madness, iterating over all cubemap pixels for each destination pixels - * even if their weight is 0.0f. - * It should use hemisphere, cosine sampling at least. */ - - /* back */ - studiolight_evaluate_specular_radiance_buffer( - sl->radiance_cubemap_buffers[STUDIOLIGHT_Y_POS], normal, color, 0, 2, 1, 1); - /* front */ - studiolight_evaluate_specular_radiance_buffer( - sl->radiance_cubemap_buffers[STUDIOLIGHT_Y_NEG], normal, color, 0, 2, 1, -1); - - /* left */ - studiolight_evaluate_specular_radiance_buffer( - sl->radiance_cubemap_buffers[STUDIOLIGHT_X_POS], normal, color, 1, 2, 0, 1); - /* right */ - studiolight_evaluate_specular_radiance_buffer( - sl->radiance_cubemap_buffers[STUDIOLIGHT_X_NEG], normal, color, 1, 2, 0, -1); - - /* top */ - studiolight_evaluate_specular_radiance_buffer( - sl->radiance_cubemap_buffers[STUDIOLIGHT_Z_POS], normal, color, 0, 1, 2, 1); - /* bottom */ - studiolight_evaluate_specular_radiance_buffer( - sl->radiance_cubemap_buffers[STUDIOLIGHT_Z_NEG], normal, color, 0, 1, 2, -1); - - mul_v3_fl(color, 1.0 / M_PI); -} -#endif - static float brdf_approx(float spec_color, float roughness, float NV) { /* Very rough own approx. We don't need it to be correct, just fast. @@ -1185,11 +1140,7 @@ static bool studiolight_load_spherical_harmonics_coefficients(StudioLight *sl) static void studiolight_calculate_irradiance_equirect_image(StudioLight *sl) { if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) { -#ifdef STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE - BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED); -#else BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED); -#endif float *colbuf = MEM_mallocN(STUDIOLIGHT_IRRADIANCE_EQUIRECT_WIDTH * STUDIOLIGHT_IRRADIANCE_EQUIRECT_HEIGHT * sizeof(float[4]), @@ -1202,11 +1153,7 @@ static void studiolight_calculate_irradiance_equirect_image(StudioLight *sl) STUDIOLIGHT_IRRADIANCE_EQUIRECT_HEIGHT) { float dir[3]; equirect_to_direction(dir, x, y); -#ifdef STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE - studiolight_irradiance_eval(sl, pixel, dir); -#else studiolight_spherical_harmonics_eval(sl, pixel, dir); -#endif pixel[3] = 1.0f; } ITER_PIXELS_END; @@ -1217,15 +1164,6 @@ static void studiolight_calculate_irradiance_equirect_image(StudioLight *sl) STUDIOLIGHT_IRRADIANCE_EQUIRECT_HEIGHT, 4); MEM_freeN(colbuf); - -#ifdef STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE - /* - * Only store cached files when using STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE - */ - if (sl->flag & STUDIOLIGHT_USER_DEFINED) { - IMB_saveiff(sl->equirect_irradiance_buffer, sl->path_irr_cache, IB_rectfloat); - } -#endif } sl->flag |= STUDIOLIGHT_EQUIRECT_IRRADIANCE_IMAGE_CALCULATED; } -- cgit v1.2.3 From 80415ee2031f1b1b9ef38774fa9a297f7a5018aa Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 8 Feb 2020 00:38:40 +1100 Subject: Cleanup: remove legacy OpenGL viewport clipping code --- source/blender/editors/space_view3d/view3d_draw.c | 30 +++-------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 6704fc9908f..d092de4fcce 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1947,45 +1947,23 @@ bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip); } -/* Legacy 2.7x, now use shaders that use clip distance instead. - * Remove once clipping is working properly. */ -#define USE_CLIP_PLANES - -void ED_view3d_clipping_set(RegionView3D *rv3d) +void ED_view3d_clipping_set(RegionView3D *UNUSED(rv3d)) { -#ifdef USE_CLIP_PLANES - double plane[4]; - const uint tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6; - - for (unsigned a = 0; a < tot; a++) { - copy_v4db_v4fl(plane, rv3d->clip[a]); - glClipPlane(GL_CLIP_PLANE0 + a, plane); - glEnable(GL_CLIP_PLANE0 + a); - glEnable(GL_CLIP_DISTANCE0 + a); - } -#else - for (unsigned a = 0; a < 6; a++) { + for (uint a = 0; a < 6; a++) { glEnable(GL_CLIP_DISTANCE0 + a); } -#endif } /* Use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set. */ void ED_view3d_clipping_disable(void) { - for (unsigned a = 0; a < 6; a++) { -#ifdef USE_CLIP_PLANES - glDisable(GL_CLIP_PLANE0 + a); -#endif + for (uint a = 0; a < 6; a++) { glDisable(GL_CLIP_DISTANCE0 + a); } } void ED_view3d_clipping_enable(void) { - for (unsigned a = 0; a < 6; a++) { -#ifdef USE_CLIP_PLANES - glEnable(GL_CLIP_PLANE0 + a); -#endif + for (uint a = 0; a < 6; a++) { glEnable(GL_CLIP_DISTANCE0 + a); } } -- cgit v1.2.3 From 6f3e498e7d5e0c772ef795e7301dd332bccada22 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 8 Feb 2020 01:02:18 +1100 Subject: Cleanup: use of 'unsigned' - Replace 'unsigned' used on it's own with 'uint'. - Replace 'unsigned const char' with 'const uchar'. --- source/blender/blenkernel/BKE_mesh.h | 4 +- source/blender/blenkernel/BKE_paint.h | 5 +- source/blender/blenkernel/intern/mask_evaluate.c | 2 +- source/blender/blenkernel/intern/mesh.c | 2 +- source/blender/blenkernel/intern/paint.c | 4 +- source/blender/blenkernel/intern/pbvh.c | 2 +- source/blender/blenlib/BLI_math_color_blend.h | 64 +++---- source/blender/blenlib/intern/BLI_ghash.c | 10 +- source/blender/blenlib/intern/math_base_inline.c | 2 +- .../blenlib/intern/math_color_blend_inline.c | 200 ++++++++------------- source/blender/blenlib/intern/math_vector.c | 34 ++-- source/blender/blenlib/intern/string_utf8.c | 2 +- source/blender/bmesh/intern/bmesh_log.c | 14 +- .../blender/bmesh/intern/bmesh_polygon_edgenet.c | 2 +- source/blender/bmesh/intern/bmesh_private.h | 2 +- source/blender/bmesh/operators/bmo_connect.c | 2 +- source/blender/bmesh/operators/bmo_fill_grid.c | 2 +- .../blender/bmesh/operators/bmo_join_triangles.c | 2 +- .../bmesh/tools/bmesh_decimate_unsubdivide.c | 4 +- source/blender/collada/MeshImporter.cpp | 4 +- source/blender/editors/include/ED_node.h | 2 +- source/blender/editors/include/ED_view3d.h | 2 +- source/blender/editors/interface/view2d.c | 2 +- source/blender/editors/object/object_vgroup.c | 10 +- source/blender/editors/screen/area.c | 2 +- source/blender/editors/sculpt_paint/sculpt.c | 10 +- source/blender/editors/space_graph/graph_draw.c | 21 +-- source/blender/editors/space_image/image_draw.c | 26 +-- source/blender/editors/space_node/drawnode.c | 25 ++- source/blender/editors/space_node/node_draw.c | 12 +- .../blender/editors/space_outliner/outliner_draw.c | 14 +- source/blender/editors/space_view3d/drawobject.c | 2 +- source/blender/modifiers/intern/MOD_screw.c | 2 +- source/blender/windowmanager/intern/wm_cursors.c | 11 +- 34 files changed, 217 insertions(+), 287 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 570541eb990..d6934e8a7da 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -91,9 +91,7 @@ struct Mesh *BKE_mesh_from_editmesh_with_coords_thin_wrap( float (*vertexCos)[3], const struct Mesh *me_settings); -int poly_find_loop_from_vert(const struct MPoly *poly, - const struct MLoop *loopstart, - unsigned vert); +int poly_find_loop_from_vert(const struct MPoly *poly, const struct MLoop *loopstart, uint vert); int poly_get_adj_loops_from_vert(const struct MPoly *poly, const struct MLoop *mloop, unsigned int vert, diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index db35fbde2c8..28e564f0fe2 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -194,10 +194,7 @@ bool paint_is_grid_face_hidden(const unsigned int *grid_hidden, int gridsize, in bool paint_is_bmesh_face_hidden(struct BMFace *f); /* paint masks */ -float paint_grid_paint_mask(const struct GridPaintMask *gpm, - unsigned level, - unsigned x, - unsigned y); +float paint_grid_paint_mask(const struct GridPaintMask *gpm, uint level, uint x, uint y); /* stroke related */ bool paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c index f4f93fcb698..cb8b3b5ecc9 100644 --- a/source/blender/blenkernel/intern/mask_evaluate.c +++ b/source/blender/blenkernel/intern/mask_evaluate.c @@ -198,7 +198,7 @@ float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, float (*BKE_mask_spline_differentiate( MaskSpline *spline, int width, int height, unsigned int *tot_diff_point))[2] { - int unsigned resol = BKE_mask_spline_resolution(spline, width, height); + uint resol = BKE_mask_spline_resolution(spline, width, height); return BKE_mask_spline_differentiate_with_resolution(spline, tot_diff_point, resol); } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 3835e405630..098da997d8f 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1200,7 +1200,7 @@ void BKE_mesh_smooth_flag_set(Mesh *me, const bool use_smooth) * Find the index of the loop in 'poly' which references vertex, * returns -1 if not found */ -int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, unsigned vert) +int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, uint vert) { int j; for (j = 0; j < poly->totloop; j++, loopstart++) { diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 46c2f735761..25f6682e9a7 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -846,7 +846,7 @@ bool paint_is_face_hidden(const MLoopTri *lt, const MVert *mvert, const MLoop *m /* returns non-zero if any of the corners of the grid * face whose inner corner is at (x, y) are hidden, * zero otherwise */ -bool paint_is_grid_face_hidden(const unsigned int *grid_hidden, int gridsize, int x, int y) +bool paint_is_grid_face_hidden(const uint *grid_hidden, int gridsize, int x, int y) { /* skip face if any of its corners are hidden */ return (BLI_BITMAP_TEST(grid_hidden, y * gridsize + x) || @@ -871,7 +871,7 @@ bool paint_is_bmesh_face_hidden(BMFace *f) return false; } -float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level, unsigned x, unsigned y) +float paint_grid_paint_mask(const GridPaintMask *gpm, uint level, uint x, uint y) { int factor = BKE_ccg_factor(level, gpm->level); int gridsize = BKE_ccg_gridsize(gpm->level); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index ec520e188f1..141e93183fb 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1410,7 +1410,7 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, bool clear, void ***r_gridfaces, int * while ((node = pbvh_iter_next(&iter))) { if (node->flag & PBVH_UpdateNormals) { - for (unsigned i = 0; i < node->totprim; i++) { + for (uint i = 0; i < node->totprim; i++) { void *face = bvh->gridfaces[node->prim_indices[i]]; BLI_gset_add(face_set, face); } diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h index 2e756b14424..a3efb5d72e9 100644 --- a/source/blender/blenlib/BLI_math_color_blend.h +++ b/source/blender/blenlib/BLI_math_color_blend.h @@ -64,53 +64,53 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], const unsigned char src2[4]); MINLINE void blend_color_overlay_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_hardlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_burn_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_linearburn_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_dodge_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_screen_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_softlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_pinlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_linearlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_vividlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_difference_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_exclusion_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_color_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_hue_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_saturation_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_luminosity_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_interpolate_byte(unsigned char dst[4], const unsigned char src1[4], diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 05ffb02597d..1c518cf1487 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -220,8 +220,8 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets) if (nbuckets > nbuckets_old) { for (i = 0; i < nbuckets_old; i++) { for (Entry *e = buckets_old[i], *e_next; e; e = e_next) { - const unsigned hash = ghash_entryhash(gh, e); - const unsigned bucket_index = ghash_bucket_index(gh, hash); + const uint hash = ghash_entryhash(gh, e); + const uint bucket_index = ghash_bucket_index(gh, hash); e_next = e->next; e->next = buckets_new[bucket_index]; buckets_new[bucket_index] = e; @@ -232,8 +232,8 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets) for (i = 0; i < nbuckets_old; i++) { #ifdef GHASH_USE_MODULO_BUCKETS for (Entry *e = buckets_old[i], *e_next; e; e = e_next) { - const unsigned hash = ghash_entryhash(gh, e); - const unsigned bucket_index = ghash_bucket_index(gh, hash); + const uint hash = ghash_entryhash(gh, e); + const uint bucket_index = ghash_bucket_index(gh, hash); e_next = e->next; e->next = buckets_new[bucket_index]; buckets_new[bucket_index] = e; @@ -241,7 +241,7 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets) #else /* No need to recompute hashes in this case, since our mask is just smaller, * all items in old bucket 'i' will go in same new bucket (i & new_mask)! */ - const unsigned bucket_index = ghash_bucket_index(gh, i); + const uint bucket_index = ghash_bucket_index(gh, i); BLI_assert(!buckets_old[i] || (bucket_index == ghash_bucket_index(gh, ghash_entryhash(gh, buckets_old[i])))); Entry *e; diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index a1c88edca6f..0a496d2bd68 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -224,7 +224,7 @@ MINLINE unsigned int power_of_2_max_u(unsigned int x) return x + 1; } -MINLINE unsigned power_of_2_min_u(unsigned x) +MINLINE unsigned int power_of_2_min_u(unsigned int x) { x |= (x >> 1); x |= (x >> 2); diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c index 7241779b32a..eb82bb81a89 100644 --- a/source/blender/blenlib/intern/math_color_blend_inline.c +++ b/source/blender/blenlib/intern/math_color_blend_inline.c @@ -49,9 +49,7 @@ /* straight alpha byte blending modes */ -MINLINE void blend_color_mix_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_mix_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight over operation */ @@ -64,10 +62,10 @@ MINLINE void blend_color_mix_byte(unsigned char dst[4], tmp[2] = (mt * src1[3] * src1[2]) + (t * 255 * src2[2]); tmp[3] = (mt * src1[3]) + (t * 255); - dst[0] = (unsigned char)divide_round_i(tmp[0], tmp[3]); - dst[1] = (unsigned char)divide_round_i(tmp[1], tmp[3]); - dst[2] = (unsigned char)divide_round_i(tmp[2], tmp[3]); - dst[3] = (unsigned char)divide_round_i(tmp[3], 255); + dst[0] = (uchar)divide_round_i(tmp[0], tmp[3]); + dst[1] = (uchar)divide_round_i(tmp[1], tmp[3]); + dst[2] = (uchar)divide_round_i(tmp[2], tmp[3]); + dst[3] = (uchar)divide_round_i(tmp[3], 255); } else { /* no op */ @@ -75,9 +73,7 @@ MINLINE void blend_color_mix_byte(unsigned char dst[4], } } -MINLINE void blend_color_add_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_add_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight add operation */ @@ -88,9 +84,9 @@ MINLINE void blend_color_add_byte(unsigned char dst[4], tmp[1] = (src1[1] * 255) + (src2[1] * t); tmp[2] = (src1[2] * 255) + (src2[2] * t); - dst[0] = (unsigned char)min_ii(divide_round_i(tmp[0], 255), 255); - dst[1] = (unsigned char)min_ii(divide_round_i(tmp[1], 255), 255); - dst[2] = (unsigned char)min_ii(divide_round_i(tmp[2], 255), 255); + dst[0] = (uchar)min_ii(divide_round_i(tmp[0], 255), 255); + dst[1] = (uchar)min_ii(divide_round_i(tmp[1], 255), 255); + dst[2] = (uchar)min_ii(divide_round_i(tmp[2], 255), 255); dst[3] = src1[3]; } else { @@ -99,9 +95,7 @@ MINLINE void blend_color_add_byte(unsigned char dst[4], } } -MINLINE void blend_color_sub_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_sub_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight sub operation */ @@ -112,9 +106,9 @@ MINLINE void blend_color_sub_byte(unsigned char dst[4], tmp[1] = (src1[1] * 255) - (src2[1] * t); tmp[2] = (src1[2] * 255) - (src2[2] * t); - dst[0] = (unsigned char)max_ii(divide_round_i(tmp[0], 255), 0); - dst[1] = (unsigned char)max_ii(divide_round_i(tmp[1], 255), 0); - dst[2] = (unsigned char)max_ii(divide_round_i(tmp[2], 255), 0); + dst[0] = (uchar)max_ii(divide_round_i(tmp[0], 255), 0); + dst[1] = (uchar)max_ii(divide_round_i(tmp[1], 255), 0); + dst[2] = (uchar)max_ii(divide_round_i(tmp[2], 255), 0); dst[3] = src1[3]; } else { @@ -123,9 +117,7 @@ MINLINE void blend_color_sub_byte(unsigned char dst[4], } } -MINLINE void blend_color_mul_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_mul_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight multiply operation */ @@ -137,9 +129,9 @@ MINLINE void blend_color_mul_byte(unsigned char dst[4], tmp[1] = (mt * src1[1] * 255) + (t * src1[1] * src2[1]); tmp[2] = (mt * src1[2] * 255) + (t * src1[2] * src2[2]); - dst[0] = (unsigned char)divide_round_i(tmp[0], 255 * 255); - dst[1] = (unsigned char)divide_round_i(tmp[1], 255 * 255); - dst[2] = (unsigned char)divide_round_i(tmp[2], 255 * 255); + dst[0] = (uchar)divide_round_i(tmp[0], 255 * 255); + dst[1] = (uchar)divide_round_i(tmp[1], 255 * 255); + dst[2] = (uchar)divide_round_i(tmp[2], 255 * 255); dst[3] = src1[3]; } else { @@ -148,9 +140,7 @@ MINLINE void blend_color_mul_byte(unsigned char dst[4], } } -MINLINE void blend_color_lighten_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_lighten_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight lighten operation */ @@ -162,9 +152,9 @@ MINLINE void blend_color_lighten_byte(unsigned char dst[4], tmp[1] = (mt * src1[1]) + (t * max_ii(src1[1], src2[1])); tmp[2] = (mt * src1[2]) + (t * max_ii(src1[2], src2[2])); - dst[0] = (unsigned char)divide_round_i(tmp[0], 255); - dst[1] = (unsigned char)divide_round_i(tmp[1], 255); - dst[2] = (unsigned char)divide_round_i(tmp[2], 255); + dst[0] = (uchar)divide_round_i(tmp[0], 255); + dst[1] = (uchar)divide_round_i(tmp[1], 255); + dst[2] = (uchar)divide_round_i(tmp[2], 255); dst[3] = src1[3]; } else { @@ -173,9 +163,7 @@ MINLINE void blend_color_lighten_byte(unsigned char dst[4], } } -MINLINE void blend_color_darken_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_darken_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight darken operation */ @@ -187,9 +175,9 @@ MINLINE void blend_color_darken_byte(unsigned char dst[4], tmp[1] = (mt * src1[1]) + (t * min_ii(src1[1], src2[1])); tmp[2] = (mt * src1[2]) + (t * min_ii(src1[2], src2[2])); - dst[0] = (unsigned char)divide_round_i(tmp[0], 255); - dst[1] = (unsigned char)divide_round_i(tmp[1], 255); - dst[2] = (unsigned char)divide_round_i(tmp[2], 255); + dst[0] = (uchar)divide_round_i(tmp[0], 255); + dst[1] = (uchar)divide_round_i(tmp[1], 255); + dst[2] = (uchar)divide_round_i(tmp[2], 255); dst[3] = src1[3]; } else { @@ -198,9 +186,7 @@ MINLINE void blend_color_darken_byte(unsigned char dst[4], } } -MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_erase_alpha_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight so just modify alpha channel */ @@ -209,7 +195,7 @@ MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], dst[0] = src1[0]; dst[1] = src1[1]; dst[2] = src1[2]; - dst[3] = (unsigned char)max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0); + dst[3] = (uchar)max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0); } else { /* no op */ @@ -217,9 +203,7 @@ MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], } } -MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_add_alpha_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight so just modify alpha channel */ @@ -228,7 +212,7 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], dst[0] = src1[0]; dst[1] = src1[1]; dst[2] = src1[2]; - dst[3] = (unsigned char)min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255); + dst[3] = (uchar)min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255); } else { /* no op */ @@ -236,9 +220,7 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], } } -MINLINE void blend_color_overlay_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_overlay_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = (int)src2[3]; if (fac != 0) { @@ -254,7 +236,7 @@ MINLINE void blend_color_overlay_byte(unsigned char dst[4], else { temp = (2 * src1[i] * src2[i]) >> 8; } - dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255); + dst[i] = (uchar)min_ii((temp * fac + src1[i] * mfac) / 255, 255); } } else { @@ -263,9 +245,7 @@ MINLINE void blend_color_overlay_byte(unsigned char dst[4], } } -MINLINE void blend_color_hardlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_hardlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = (int)src2[3]; if (fac != 0) { @@ -281,7 +261,7 @@ MINLINE void blend_color_hardlight_byte(unsigned char dst[4], else { temp = (2 * src2[i] * src1[i]) >> 8; } - dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255); + dst[i] = (uchar)min_ii((temp * fac + src1[i] * mfac) / 255, 255); } } else { @@ -290,9 +270,7 @@ MINLINE void blend_color_hardlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_burn_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_burn_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -301,7 +279,7 @@ MINLINE void blend_color_burn_byte(unsigned char dst[4], while (i--) { const int temp = (src2[i] == 0) ? 0 : max_ii(255 - ((255 - src1[i]) * 255) / src2[i], 0); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -310,9 +288,7 @@ MINLINE void blend_color_burn_byte(unsigned char dst[4], } } -MINLINE void blend_color_linearburn_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_linearburn_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -321,7 +297,7 @@ MINLINE void blend_color_linearburn_byte(unsigned char dst[4], while (i--) { const int temp = max_ii(src1[i] + src2[i] - 255, 0); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -330,9 +306,7 @@ MINLINE void blend_color_linearburn_byte(unsigned char dst[4], } } -MINLINE void blend_color_dodge_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_dodge_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -341,7 +315,7 @@ MINLINE void blend_color_dodge_byte(unsigned char dst[4], while (i--) { const int temp = (src2[i] == 255) ? 255 : min_ii((src1[i] * 255) / (255 - src2[i]), 255); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -350,9 +324,7 @@ MINLINE void blend_color_dodge_byte(unsigned char dst[4], } } -MINLINE void blend_color_screen_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_screen_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -361,7 +333,7 @@ MINLINE void blend_color_screen_byte(unsigned char dst[4], while (i--) { const int temp = max_ii(255 - (((255 - src1[i]) * (255 - src2[i])) / 255), 0); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -370,9 +342,7 @@ MINLINE void blend_color_screen_byte(unsigned char dst[4], } } -MINLINE void blend_color_softlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_softlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -388,7 +358,7 @@ MINLINE void blend_color_softlight_byte(unsigned char dst[4], else { temp = 255 - (2 * (255 - ((src2[i] / 2) + 64)) * (255 - src1[i]) / 255); } - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -397,9 +367,7 @@ MINLINE void blend_color_softlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_pinlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_pinlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -415,7 +383,7 @@ MINLINE void blend_color_pinlight_byte(unsigned char dst[4], else { temp = min_ii(2 * src2[i], src1[i]); } - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -424,9 +392,7 @@ MINLINE void blend_color_pinlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_linearlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_linearlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -442,7 +408,7 @@ MINLINE void blend_color_linearlight_byte(unsigned char dst[4], else { temp = max_ii(src1[i] + 2 * src2[i] - 255, 0); } - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -451,9 +417,7 @@ MINLINE void blend_color_linearlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_vividlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_vividlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -475,7 +439,7 @@ MINLINE void blend_color_vividlight_byte(unsigned char dst[4], else { temp = max_ii(255 - ((255 - src1[i]) * 255 / (2 * src2[i])), 0); } - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -484,9 +448,7 @@ MINLINE void blend_color_vividlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_difference_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_difference_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -495,7 +457,7 @@ MINLINE void blend_color_difference_byte(unsigned char dst[4], while (i--) { const int temp = abs(src1[i] - src2[i]); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -504,9 +466,7 @@ MINLINE void blend_color_difference_byte(unsigned char dst[4], } } -MINLINE void blend_color_exclusion_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_exclusion_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -515,7 +475,7 @@ MINLINE void blend_color_exclusion_byte(unsigned char dst[4], while (i--) { const int temp = 127 - ((2 * (src1[i] - 127) * (src2[i] - 127)) / 255); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -524,9 +484,7 @@ MINLINE void blend_color_exclusion_byte(unsigned char dst[4], } } -MINLINE void blend_color_color_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_color_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -542,9 +500,9 @@ MINLINE void blend_color_color_byte(unsigned char dst[4], hsv_to_rgb(h1, s1, v1, &r, &g, &b); - dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); - dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); - dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); } else { /* no op */ @@ -552,9 +510,7 @@ MINLINE void blend_color_color_byte(unsigned char dst[4], } } -MINLINE void blend_color_hue_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_hue_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -569,9 +525,9 @@ MINLINE void blend_color_hue_byte(unsigned char dst[4], hsv_to_rgb(h1, s1, v1, &r, &g, &b); - dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); - dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); - dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); } else { /* no op */ @@ -579,9 +535,7 @@ MINLINE void blend_color_hue_byte(unsigned char dst[4], } } -MINLINE void blend_color_saturation_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_saturation_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -598,9 +552,9 @@ MINLINE void blend_color_saturation_byte(unsigned char dst[4], hsv_to_rgb(h1, s1, v1, &r, &g, &b); - dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); - dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); - dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); } else { /* no op */ @@ -608,9 +562,7 @@ MINLINE void blend_color_saturation_byte(unsigned char dst[4], } } -MINLINE void blend_color_luminosity_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_luminosity_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -625,9 +577,9 @@ MINLINE void blend_color_luminosity_byte(unsigned char dst[4], hsv_to_rgb(h1, s1, v1, &r, &g, &b); - dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); - dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); - dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); } else { /* no op */ @@ -635,9 +587,9 @@ MINLINE void blend_color_luminosity_byte(unsigned char dst[4], } } -MINLINE void blend_color_interpolate_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4], +MINLINE void blend_color_interpolate_byte(uchar dst[4], + const uchar src1[4], + const uchar src2[4], float ft) { /* do color interpolation, but in premultiplied space so that RGB colors @@ -647,10 +599,10 @@ MINLINE void blend_color_interpolate_byte(unsigned char dst[4], int tmp = (mt * src1[3] + t * src2[3]); if (tmp > 0) { - dst[0] = (unsigned char)divide_round_i(mt * src1[0] * src1[3] + t * src2[0] * src2[3], tmp); - dst[1] = (unsigned char)divide_round_i(mt * src1[1] * src1[3] + t * src2[1] * src2[3], tmp); - dst[2] = (unsigned char)divide_round_i(mt * src1[2] * src1[3] + t * src2[2] * src2[3], tmp); - dst[3] = (unsigned char)divide_round_i(tmp, 255); + dst[0] = (uchar)divide_round_i(mt * src1[0] * src1[3] + t * src2[0] * src2[3], tmp); + dst[1] = (uchar)divide_round_i(mt * src1[1] * src1[3] + t * src2[1] * src2[3], tmp); + dst[2] = (uchar)divide_round_i(mt * src1[2] * src1[3] + t * src2[2] * src2[3], tmp); + dst[3] = (uchar)divide_round_i(tmp, 255); } else { copy_v4_v4_uchar(dst, src1); diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 55f21250659..5919b7e1dd6 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -240,10 +240,7 @@ void interp_v3_v3v3v3_uv( p[2] = v1[2] + ((v2[2] - v1[2]) * uv[0]) + ((v3[2] - v1[2]) * uv[1]); } -void interp_v3_v3v3_uchar(char unsigned target[3], - const unsigned char a[3], - const unsigned char b[3], - const float t) +void interp_v3_v3v3_uchar(uchar target[3], const uchar a[3], const uchar b[3], const float t) { const float s = 1.0f - t; @@ -253,14 +250,10 @@ void interp_v3_v3v3_uchar(char unsigned target[3], } void interp_v3_v3v3_char(char target[3], const char a[3], const char b[3], const float t) { - interp_v3_v3v3_uchar( - (unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t); + interp_v3_v3v3_uchar((uchar *)target, (const uchar *)a, (const uchar *)b, t); } -void interp_v4_v4v4_uchar(char unsigned target[4], - const unsigned char a[4], - const unsigned char b[4], - const float t) +void interp_v4_v4v4_uchar(uchar target[4], const uchar a[4], const uchar b[4], const float t) { const float s = 1.0f - t; @@ -271,8 +264,7 @@ void interp_v4_v4v4_uchar(char unsigned target[4], } void interp_v4_v4v4_char(char target[4], const char a[4], const char b[4], const float t) { - interp_v4_v4v4_uchar( - (unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t); + interp_v4_v4v4_uchar((uchar *)target, (const uchar *)a, (const uchar *)b, t); } void mid_v3_v3v3(float v[3], const float v1[3], const float v2[3]) @@ -303,12 +295,12 @@ void mid_v3_v3v3v3v3( v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f; } -void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const unsigned int nbr) +void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint nbr) { const float factor = 1.0f / (float)nbr; zero_v3(r); - for (unsigned int i = 0; i < nbr; i++) { + for (uint i = 0; i < nbr; i++) { madd_v3_v3fl(r, vec_arr[i], factor); } } @@ -1119,10 +1111,10 @@ void range_vn_i(int *array_tar, const int size, const int start) } } -void range_vn_u(unsigned int *array_tar, const int size, const unsigned int start) +void range_vn_u(uint *array_tar, const int size, const uint start) { - unsigned int *array_pt = array_tar + (size - 1); - unsigned int j = start + (unsigned int)(size - 1); + uint *array_pt = array_tar + (size - 1); + uint j = start + (uint)(size - 1); int i = size; while (i--) { *(array_pt--) = j--; @@ -1329,18 +1321,18 @@ void copy_vn_short(short *array_tar, const int size, const short val) } } -void copy_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val) +void copy_vn_ushort(ushort *array_tar, const int size, const ushort val) { - unsigned short *tar = array_tar + (size - 1); + ushort *tar = array_tar + (size - 1); int i = size; while (i--) { *(tar--) = val; } } -void copy_vn_uchar(unsigned char *array_tar, const int size, const unsigned char val) +void copy_vn_uchar(uchar *array_tar, const int size, const uchar val) { - unsigned char *tar = array_tar + (size - 1); + uchar *tar = array_tar + (size - 1); int i = size; while (i--) { *(tar--) = val; diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index 63657f33bba..7fc95a33092 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -600,7 +600,7 @@ uint BLI_str_utf8_as_unicode(const char *p) uint BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index) { int i, len; - unsigned mask = 0; + uint mask = 0; uint result; const unsigned char c = (unsigned char)*p; diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index 8cbbf765f66..d14b7a51a94 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -476,7 +476,7 @@ BMLog *BM_log_create(BMesh *bm) BMLog *log = MEM_callocN(sizeof(*log), __func__); const uint reserve_num = (uint)(bm->totvert + bm->totface); - log->unused_ids = range_tree_uint_alloc(0, (unsigned)-1); + log->unused_ids = range_tree_uint_alloc(0, (uint)-1); log->id_to_elem = BLI_ghash_new_ex(logkey_hash, logkey_cmp, __func__, reserve_num); log->elem_to_id = BLI_ghash_ptr_new_ex(__func__, reserve_num); @@ -618,7 +618,7 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log) /* Create BMVert index remap array */ id_to_idx = bm_log_compress_ids_to_indices(varr, (uint)bm->totvert); BM_ITER_MESH_INDEX (v, &bm_iter, bm, BM_VERTS_OF_MESH, i) { - const unsigned id = bm_log_vert_id_get(log, v); + const uint id = bm_log_vert_id_get(log, v); const void *key = POINTER_FROM_UINT(id); const void *val = BLI_ghash_lookup(id_to_idx, key); varr[i] = POINTER_AS_UINT(val); @@ -628,7 +628,7 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log) /* Create BMFace index remap array */ id_to_idx = bm_log_compress_ids_to_indices(farr, (uint)bm->totface); BM_ITER_MESH_INDEX (f, &bm_iter, bm, BM_FACES_OF_MESH, i) { - const unsigned id = bm_log_face_id_get(log, f); + const uint id = bm_log_face_id_get(log, f); const void *key = POINTER_FROM_UINT(id); const void *val = BLI_ghash_lookup(id_to_idx, key); farr[i] = POINTER_AS_UINT(val); @@ -1039,7 +1039,7 @@ const float *BM_log_original_vert_co(BMLog *log, BMVert *v) { BMLogEntry *entry = log->current_entry; const BMLogVert *lv; - unsigned v_id = bm_log_vert_id_get(log, v); + uint v_id = bm_log_vert_id_get(log, v); void *key = POINTER_FROM_UINT(v_id); BLI_assert(entry); @@ -1057,7 +1057,7 @@ const short *BM_log_original_vert_no(BMLog *log, BMVert *v) { BMLogEntry *entry = log->current_entry; const BMLogVert *lv; - unsigned v_id = bm_log_vert_id_get(log, v); + uint v_id = bm_log_vert_id_get(log, v); void *key = POINTER_FROM_UINT(v_id); BLI_assert(entry); @@ -1075,7 +1075,7 @@ float BM_log_original_mask(BMLog *log, BMVert *v) { BMLogEntry *entry = log->current_entry; const BMLogVert *lv; - unsigned v_id = bm_log_vert_id_get(log, v); + uint v_id = bm_log_vert_id_get(log, v); void *key = POINTER_FROM_UINT(v_id); BLI_assert(entry); @@ -1090,7 +1090,7 @@ void BM_log_original_vert_data(BMLog *log, BMVert *v, const float **r_co, const { BMLogEntry *entry = log->current_entry; const BMLogVert *lv; - unsigned v_id = bm_log_vert_id_get(log, v); + uint v_id = bm_log_vert_id_get(log, v); void *key = POINTER_FROM_UINT(v_id); BLI_assert(entry); diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c index 374c912e3f5..f6ed95d322d 100644 --- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c +++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c @@ -1298,7 +1298,7 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm, if (use_partial_connect) { for (uint i = 0; i < edge_net_init_len; i++) { - for (unsigned j = 0; j < 2; j++) { + for (uint j = 0; j < 2; j++) { BMVert *v_delimit = (&edge_arr[i]->v1)[j]; BMVert *v_other; diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index d5cbe947293..8b4a59d5b9b 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -86,7 +86,7 @@ enum { } \ (void)0 -void poly_rotate_plane(const float normal[3], float (*verts)[3], unsigned const int nverts); +void poly_rotate_plane(const float normal[3], float (*verts)[3], const uint nverts); /* include the rest of our private declarations */ #include "bmesh_structure.h" diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index e52467614ac..2f0b21667e4 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -41,7 +41,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f, const bool check_degenerate) { - const unsigned pair_split_max = f->len / 2; + const uint pair_split_max = f->len / 2; BMLoop *(*loops_split)[2] = BLI_array_alloca(loops_split, pair_split_max); STACK_DECLARE(loops_split); BMVert *(*verts_pair)[2] = BLI_array_alloca(verts_pair, pair_split_max); diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c index c3d19862ffb..adc612cfb54 100644 --- a/source/blender/bmesh/operators/bmo_fill_grid.c +++ b/source/blender/bmesh/operators/bmo_fill_grid.c @@ -205,7 +205,7 @@ static void barycentric_weights_v2_grid_cache(const uint xtot, static void bm_grid_fill_array(BMesh *bm, BMVert **v_grid, const uint xtot, - unsigned const int ytot, + const uint ytot, const short mat_nr, const bool use_smooth, const bool use_flip, diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 848669301c3..efb8b810581 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -260,7 +260,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) BMEdge *e; /* data: edge-to-join, sort_value: error weight */ struct SortPtrByFloat *jedges; - unsigned i, totedge; + uint i, totedge; uint totedge_tag = 0; struct DelimitData delimit_data = {0}; diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c index 2cc86a7c93f..e2741b806c2 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c +++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c @@ -177,8 +177,8 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool #else BMVert **vert_seek_a = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); BMVert **vert_seek_b = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); - unsigned vert_seek_a_tot = 0; - unsigned vert_seek_b_tot = 0; + uint vert_seek_a_tot = 0; + uint vert_seek_b_tot = 0; #endif BMIter iter; diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index c76cb8c80a6..32f5463a0e7 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -279,7 +279,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) const std::string &name = bc_get_dae_name(mesh); - for (unsigned i = 0; i < prim_arr.getCount(); i++) { + for (unsigned int i = 0; i < prim_arr.getCount(); i++) { COLLADAFW::MeshPrimitive *mp = prim_arr[i]; COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType(); @@ -683,7 +683,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) // XXX The proper function of TRIANGLE_FANS is not tested!!! // XXX In particular the handling of the normal_indices looks very wrong to me if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { - unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount(); + unsigned int grouped_vertex_count = mp->getGroupedVertexElementsCount(); for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) { unsigned int first_vertex = position_indices[0]; // Store first trifan vertex unsigned int first_normal = normal_indices[0]; // Store first trifan vertex normal diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index d2d8972c245..de7d2e1a395 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -72,7 +72,7 @@ void ED_init_standard_node_socket_type(struct bNodeSocketType *stype); void ED_init_node_socket_type_virtual(struct bNodeSocketType *stype); void ED_node_sample_set(const float col[4]); void ED_node_draw_snap( - struct View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos); + struct View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned int pos); /* node_draw.c */ void ED_node_tree_update(const struct bContext *C); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 37ffb1b9d6d..622b64f547f 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -452,7 +452,7 @@ float ED_view3d_radius_to_dist(const struct View3D *v3d, const bool use_aspect, const float radius); -void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos); +void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned int pos); /* backbuffer select and draw support */ void ED_view3d_backbuf_depth_validate(struct ViewContext *vc); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index a23bd7dad35..8af3664d41b 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1343,7 +1343,7 @@ void UI_view2d_multi_grid_draw(View2D *v2d, int colorid, float step, int level_s uchar grid_line_color[3]; /* Make an estimate of at least how many vertices will be needed */ - unsigned vertex_count = 4; + uint vertex_count = 4; vertex_count += 2 * ((int)((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1); vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 05fa78aab1c..9ccbc7a1a0a 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -701,7 +701,7 @@ const EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(const bContext * PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free, - const unsigned int selection_mask) + const uint selection_mask) { Object *ob; EnumPropertyItem *item = NULL; @@ -1807,10 +1807,10 @@ static void vgroup_smooth_subset(Object *ob, float *weight_accum_prev; float *weight_accum_curr; - unsigned int subset_index; + uint subset_index; /* vertex indices that will be smoothed, (only to avoid iterating over verts that do nothing) */ - unsigned int *verts_used; + uint *verts_used; STACK_DECLARE(verts_used); BKE_object_defgroup_subset_to_index_array(vgroup_validmap, vgroup_tot, vgroup_subset_map); @@ -1882,12 +1882,12 @@ static void vgroup_smooth_subset(Object *ob, memcpy(weight_accum_curr, weight_accum_prev, sizeof(*weight_accum_curr) * dvert_tot); for (iter = 0; iter < repeat; iter++) { - unsigned *vi_step, *vi_end = verts_used + STACK_SIZE(verts_used); + uint *vi_step, *vi_end = verts_used + STACK_SIZE(verts_used); /* avoid looping over all verts */ // for (i = 0; i < dvert_tot; i++) for (vi_step = verts_used; vi_step != vi_end; vi_step++) { - const unsigned int i = *vi_step; + const uint i = *vi_step; float weight_tot = 0.0f; float weight = 0.0f; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 7db634660af..c85beefe1f4 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -3290,7 +3290,7 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy, float x0, float if (count_fine > 0) { GPU_vertformat_clear(format); pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - unsigned color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); immBegin(GPU_PRIM_LINES, 4 * count_fine + 4 * count_large); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 015657318b2..cf66ba14328 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -291,7 +291,7 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss, for (i = 0; i < ss->pmap[(int)index].count; i++) { const MPoly *p = &ss->mpoly[vert_map->indices[i]]; - unsigned f_adj_v[2]; + uint f_adj_v[2]; if (poly_get_adj_loops_from_vert(p, ss->mloop, (int)index, f_adj_v) != -1) { int j; for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { @@ -2203,7 +2203,7 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) /* For the smooth brush, uses the neighboring vertices around vert to calculate * a smoothed location for vert. Skips corner vertices (used by only one * polygon.) */ -static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert) +static void neighbor_average(SculptSession *ss, float avg[3], uint vert) { const MeshElemMap *vert_map = &ss->pmap[vert]; const MVert *mvert = ss->mvert; @@ -2217,7 +2217,7 @@ static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert) for (i = 0; i < vert_map->count; i++) { const MPoly *p = &ss->mpoly[vert_map->indices[i]]; - unsigned f_adj_v[2]; + uint f_adj_v[2]; if (poly_get_adj_loops_from_vert(p, ss->mloop, vert, f_adj_v) != -1) { int j; @@ -2243,7 +2243,7 @@ static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert) /* Similar to neighbor_average(), but returns an averaged mask value * instead of coordinate. Also does not restrict based on border or * corner vertices. */ -static float neighbor_average_mask(SculptSession *ss, unsigned vert) +static float neighbor_average_mask(SculptSession *ss, uint vert) { const float *vmask = ss->vmask; float avg = 0; @@ -2251,7 +2251,7 @@ static float neighbor_average_mask(SculptSession *ss, unsigned vert) for (i = 0; i < ss->pmap[vert].count; i++) { const MPoly *p = &ss->mpoly[ss->pmap[vert].indices[i]]; - unsigned f_adj_v[2]; + uint f_adj_v[2]; if (poly_get_adj_loops_from_vert(p, ss->mloop, vert, f_adj_v) != -1) { int j; diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 42a1566629a..8dd5a7c7d0c 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -164,7 +164,7 @@ static void set_fcurve_vertex_color(FCurve *fcu, bool sel) } static void draw_fcurve_selected_keyframe_vertices( - FCurve *fcu, View2D *v2d, bool edit, bool sel, unsigned pos) + FCurve *fcu, View2D *v2d, bool edit, bool sel, uint pos) { const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur); @@ -200,7 +200,7 @@ static void draw_fcurve_selected_keyframe_vertices( } /* helper func - draw keyframe vertices only for an F-Curve */ -static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, unsigned pos) +static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, uint pos) { immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); @@ -214,7 +214,7 @@ static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, u /* helper func - draw handle vertices only for an F-Curve (if it is not protected) */ static void draw_fcurve_selected_handle_vertices( - FCurve *fcu, View2D *v2d, bool sel, bool sel_handle_only, unsigned pos) + FCurve *fcu, View2D *v2d, bool sel, bool sel_handle_only, uint pos) { (void)v2d; /* TODO: use this to draw only points in view */ @@ -259,10 +259,7 @@ static void draw_fcurve_selected_handle_vertices( } /* helper func - draw handle vertices only for an F-Curve (if it is not protected) */ -static void draw_fcurve_handle_vertices(FCurve *fcu, - View2D *v2d, - bool sel_handle_only, - unsigned pos) +static void draw_fcurve_handle_vertices(FCurve *fcu, View2D *v2d, bool sel_handle_only, uint pos) { /* smooth outlines for more consistent appearance */ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); @@ -353,7 +350,7 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu) BezTriple *bezt = fcu->bezt, *prevbezt = NULL; int basecol = (sel) ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE; const float *fp; - unsigned char col[4]; + uchar col[4]; for (b = 0; b < fcu->totvert; b++, prevbezt = bezt, bezt++) { /* if only selected keyframes can get their handles shown, @@ -428,7 +425,7 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu) * have a consistent appearance (due to off-pixel alignments)... */ static void draw_fcurve_sample_control( - float x, float y, float xscale, float yscale, float hsize, unsigned int pos) + float x, float y, float xscale, float yscale, float hsize, uint pos) { /* adjust view transform before starting */ GPU_matrix_push(); @@ -491,8 +488,7 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *ar, FCurve *fcu) /* Helper func - just draw the F-Curve by sampling the visible region * (for drawing curves with modifiers). */ -static void draw_fcurve_curve( - bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, unsigned int pos) +static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, uint pos) { SpaceGraph *sipo = (SpaceGraph *)ac->sl; float samplefreq; @@ -684,8 +680,7 @@ static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu) } /* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */ -static void draw_fcurve_curve_bezts( - bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, unsigned int pos) +static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, uint pos) { BezTriple *prevbezt = fcu->bezt; BezTriple *bezt = prevbezt + 1; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 3f563fe9033..c455b7d7c54 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -147,7 +147,7 @@ void ED_image_draw_info(Scene *scene, int channels, int x, int y, - const unsigned char cp[4], + const uchar cp[4], const float fp[4], const float linearcol[4], int *zp, @@ -164,13 +164,13 @@ void ED_image_draw_info(Scene *scene, /* text colors */ /* XXX colored text not allowed in Blender UI */ #if 0 - unsigned char red[3] = {255, 50, 50}; - unsigned char green[3] = {0, 255, 0}; - unsigned char blue[3] = {100, 100, 255}; + uchar red[3] = {255, 50, 50}; + uchar green[3] = {0, 255, 0}; + uchar blue[3] = {100, 100, 255}; #else - unsigned char red[3] = {255, 255, 255}; - unsigned char green[3] = {255, 255, 255}; - unsigned char blue[3] = {255, 255, 255}; + uchar red[3] = {255, 255, 255}; + uchar green[3] = {255, 255, 255}; + uchar blue[3] = {255, 255, 255}; #endif float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0; float col[4], finalcol[4]; @@ -613,7 +613,7 @@ static void draw_image_buffer(const bContext *C, } else { float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - unsigned char *display_buffer; + uchar *display_buffer; void *cache_handle; ColorManagedViewSettings *view_settings; ColorManagedDisplaySettings *display_settings; @@ -760,7 +760,7 @@ static void draw_image_paint_helpers( float col[4] = {1.0f, 1.0f, 1.0f, brush->clone.alpha}; UI_view2d_view_to_region(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y); - unsigned char *display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); + uchar *display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); if (!display_buffer) { BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); @@ -794,8 +794,8 @@ static void draw_image_paint_helpers( } } -static void draw_udim_tile_grid(unsigned int pos_attr, - unsigned int color_attr, +static void draw_udim_tile_grid(uint pos_attr, + uint color_attr, ARegion *ar, int x, int y, @@ -832,8 +832,8 @@ static void draw_udim_tile_grids(ARegion *ar, SpaceImage *sima, Image *ima) float stepy = BLI_rcti_size_y(&ar->v2d.mask) / BLI_rctf_size_y(&ar->v2d.cur); GPUVertFormat *format = immVertexFormat(); - unsigned int pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - unsigned color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); immBegin(GPU_PRIM_LINES, 8 * num_tiles); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 35c9082b54c..121c597c1bb 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -376,7 +376,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp const int font_size = data->label_size / aspect; const float margin = (float)(NODE_DY / 4); int label_height; - unsigned char color[3]; + uchar color[3]; nodeLabel(ntree, node, label, sizeof(label)); @@ -3483,7 +3483,7 @@ void draw_nodespace_back_pix(const bContext *C, y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof; if (ibuf->rect || ibuf->rect_float) { - unsigned char *display_buffer = NULL; + uchar *display_buffer = NULL; void *cache_handle = NULL; if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B | SNODE_SHOW_ALPHA)) { @@ -3707,11 +3707,11 @@ static struct { GPUBatch *batch; /* for batching line together */ GPUBatch *batch_single; /* for single line */ GPUVertBuf *inst_vbo; - unsigned int p0_id, p1_id, p2_id, p3_id; - unsigned int colid_id; + uint p0_id, p1_id, p2_id, p3_id; + uint colid_id; GPUVertBufRaw p0_step, p1_step, p2_step, p3_step; GPUVertBufRaw colid_step; - unsigned int count; + uint count; bool enabled; } g_batch_link = {0}; @@ -3727,11 +3727,11 @@ static void nodelink_batch_reset(void) } static void set_nodelink_vertex(GPUVertBuf *vbo, - unsigned int uv_id, - unsigned int pos_id, - unsigned int exp_id, - unsigned int v, - const unsigned char uv[2], + uint uv_id, + uint pos_id, + uint exp_id, + uint v, + const uchar uv[2], const float pos[2], const float exp[2]) { @@ -3756,7 +3756,7 @@ static void nodelink_batch_init(void) int v = 0; for (int k = 0; k < 2; k++) { - unsigned char uv[2] = {0, 0}; + uchar uv[2] = {0, 0}; float pos[2] = {0.0f, 0.0f}; float exp[2] = {0.0f, 1.0f}; @@ -4000,8 +4000,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) // node_draw_link_straight(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3); } -void ED_node_draw_snap( - View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos) +void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border, uint pos) { immBegin(GPU_PRIM_LINES, 4); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 2081c69a1a4..6e165df3e2b 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -722,18 +722,18 @@ static void node_socket_draw(const bContext *C, bNodeTree *ntree, PointerRNA node_ptr, bNodeSocket *sock, - unsigned pos_id, - unsigned col_id, - unsigned shape_id, - unsigned size_id, - unsigned outline_col_id, + uint pos_id, + uint col_id, + uint shape_id, + uint size_id, + uint outline_col_id, float size, bool selected) { PointerRNA ptr; float color[4]; float outline_color[4]; - unsigned int flags = 0; + uint flags = 0; RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); sock->typeinfo->draw_color((bContext *)C, &ptr, &node_ptr, color); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index a341be5bf65..8bd1fae645f 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2700,7 +2700,7 @@ static void outliner_draw_iconrow_number(const uiFontStyle *fstyle, color); /* Now the numbers. */ - unsigned char text_col[4]; + uchar text_col[4]; UI_GetThemeColor4ubv(TH_TEXT_HI, text_col); text_col[3] = 255; @@ -2953,7 +2953,7 @@ static void outliner_draw_tree_element(bContext *C, float ufac = UI_UNIT_X / 20.0f; int offsx = 0; eOLDrawState active = OL_DRAWSEL_NONE; - unsigned char text_color[4]; + uchar text_color[4]; UI_GetThemeColor4ubv(TH_TEXT, text_color); float icon_bgcolor[4], icon_border[4]; outliner_icon_background_colors(icon_bgcolor, icon_border); @@ -3208,11 +3208,11 @@ static void outliner_draw_tree_element(bContext *C, } } -static void outliner_draw_hierarchy_lines_recursive(unsigned pos, +static void outliner_draw_hierarchy_lines_recursive(uint pos, SpaceOutliner *soops, ListBase *lb, int startx, - const unsigned char col[4], + const uchar col[4], bool draw_grayed_out, int *starty) { @@ -3234,7 +3234,7 @@ static void outliner_draw_hierarchy_lines_recursive(unsigned pos, dash.step_len = UI_UNIT_X / dash.steps_num; dash.gap_len = dash.step_len / 2; - const unsigned char grayed_alpha = col[3] / 2; + const uchar grayed_alpha = col[3] / 2; /* For vertical lines between objects. */ y1 = y2 = y1_dashed = y2_dashed = *starty; @@ -3316,7 +3316,7 @@ static void outliner_draw_hierarchy_lines(SpaceOutliner *soops, { GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - unsigned char col[4]; + uchar col[4]; immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.4f, col); @@ -3369,7 +3369,7 @@ static void outliner_draw_struct_marks(ARegion *ar, } } -static void outliner_draw_highlights_recursive(unsigned pos, +static void outliner_draw_highlights_recursive(uint pos, const ARegion *ar, const SpaceOutliner *soops, const ListBase *lb, diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 2cdfd8039c1..0daa5aa53ae 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -87,7 +87,7 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], } } -void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos) +void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], uint pos) { float verts[CIRCLE_RESOL][3]; diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 773cbf72d5b..51ad40bdd87 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -1090,7 +1090,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes /* validate loop edges */ #if 0 { - unsigned i = 0; + uint i = 0; printf("\n"); for (; i < maxPolys * 4; i += 4) { uint ii; diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index b82865a727d..e22863bc602 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -132,11 +132,8 @@ static GHOST_TStandardCursor convert_to_ghost_standard_cursor(WMCursorType curs) } } -static void window_set_custom_cursor(wmWindow *win, - unsigned const char mask[16][2], - unsigned char bitmap[16][2], - int hotx, - int hoty) +static void window_set_custom_cursor( + wmWindow *win, const uchar mask[16][2], uchar bitmap[16][2], int hotx, int hoty) { GHOST_SetCustomCursorShape( win->ghostwin, (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotx, hoty, true); @@ -380,8 +377,8 @@ void WM_cursor_time(wmWindow *win, int nr) {0, 60, 66, 66, 60, 66, 66, 60}, {0, 56, 68, 68, 120, 64, 68, 56}, }; - unsigned char mask[16][2]; - unsigned char bitmap[16][2] = {{0}}; + uchar mask[16][2]; + uchar bitmap[16][2] = {{0}}; int i, idx; if (win->lastcursor == 0) { -- cgit v1.2.3 From ffcccf654c8e05f464c59fad82404833160f5b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Fri, 7 Feb 2020 15:19:17 +0100 Subject: OpenVDB: Added missing macros in fluid wrapper file These were needed to compile when WITH_FLUID=1 and WITH_OPENVDB=0. --- intern/mantaflow/intern/MANTA_main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index c0c7ef5dbf2..2cbf058d8de 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -2798,8 +2798,10 @@ int MANTA::updateGridFromFile(const char *filename, float *grid) if (extension.compare("uni") == 0) return updateGridFromUni(filename, grid); +#ifdef WITH_OPENVDB else if (extension.compare("vdb") == 0) return updateGridFromVDB(filename, grid); +#endif else if (extension.compare("raw") == 0) return updateGridFromRaw(filename, grid); else @@ -2884,6 +2886,7 @@ int MANTA::updateGridFromUni(const char *filename, float *grid) return 1; } +#ifdef WITH_OPENVDB int MANTA::updateGridFromVDB(const char *filename, float *grid) { if (with_debug) @@ -2922,6 +2925,7 @@ int MANTA::updateGridFromVDB(const char *filename, float *grid) } return 1; } +#endif int MANTA::updateGridFromRaw(const char *filename, float *grid) { -- cgit v1.2.3 From 6477fcf40f541bcb8de24aa8023df53775cc7827 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Fri, 7 Feb 2020 07:27:40 -0700 Subject: BuildSystem/Cleanup: Fix warning behaviour regarding library dependencies Adding USD to a lite build fails to build due to boost errors, when you turn boost on and rebuild still boost errors, boost was silently turned off since it was not deemed needed. Once boost was forced on, it still fails due to TBB being off. This patch fixes: - The Silent disabling of boost - Add a check that USD is is not on before doing that - move the TBB checks to a central location rather than the individual platform files - Add USD to the TBB checks. Differential Revision: https://developer.blender.org/D6479 Reviewers: brecht, sybren --- CMakeLists.txt | 36 +++++++++++-------------- build_files/cmake/macros.cmake | 10 +++++++ build_files/cmake/platform/platform_apple.cmake | 15 ----------- build_files/cmake/platform/platform_unix.cmake | 11 -------- build_files/cmake/platform/platform_win32.cmake | 13 --------- 5 files changed, 26 insertions(+), 59 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 509de9943e2..60656a9e4fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -613,29 +613,25 @@ endif() # enable boost for cycles, audaspace or i18n # otherwise if the user disabled -if(NOT WITH_BOOST) - # Explicitly disabled. so disable all deps. - macro(set_and_warn - _setting _val) - if(${${_setting}}) - message(STATUS "'WITH_BOOST' is disabled: forcing 'set(${_setting} ${_val})'") - endif() - set(${_setting} ${_val}) - endmacro() - - set_and_warn(WITH_CYCLES OFF) - set_and_warn(WITH_INTERNATIONAL OFF) - set_and_warn(WITH_OPENVDB OFF) - set_and_warn(WITH_OPENCOLORIO OFF) - set_and_warn(WITH_QUADRIFLOW OFF) -elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR - WITH_OPENVDB OR WITH_OPENCOLORIO) - # Keep enabled -else() - # Disable boost if not needed. + +set_and_warn_dependency(WITH_BOOST WITH_CYCLES OFF) +set_and_warn_dependency(WITH_BOOST WITH_INTERNATIONAL OFF) +set_and_warn_dependency(WITH_BOOST WITH_OPENVDB OFF) +set_and_warn_dependency(WITH_BOOST WITH_OPENCOLORIO OFF) +set_and_warn_dependency(WITH_BOOST WITH_QUADRIFLOW OFF) +set_and_warn_dependency(WITH_BOOST WITH_USD OFF) + +if(NOT (WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR + WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_USD)) + message(STATUS "No dependencies need 'WITH_BOOST' forcing WITH_BOOST=OFF") set(WITH_BOOST OFF) endif() +set_and_warn_dependency(WITH_TBB WITH_USD OFF) +set_and_warn_dependency(WITH_TBB WITH_OPENIMAGEDENOISE OFF) +set_and_warn_dependency(WITH_TBB WITH_OPENVDB OFF) +set_and_warn_dependency(WITH_TBB WITH_MOD_FLUID OFF) + # auto enable openimageio for cycles if(WITH_CYCLES) set(WITH_OPENIMAGEIO ON) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 2d13476f09a..daf156bc3f2 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -1157,3 +1157,13 @@ macro(blender_precompile_headers target cpp header) set_source_files_properties(${cpp} PROPERTIES COMPILE_FLAGS "/Yc${header} /Fp${pchfinal}") endif() endmacro() + +macro(set_and_warn_dependency + _dependency _setting _val) + # when $_dependency is disabled, forces $_setting = $_val + if(NOT ${${_dependency}} AND ${${_setting}}) + message(STATUS "'${_dependency}' is disabled: forcing 'set(${_setting} ${_val})'") + set(${_setting} ${_val}) + endif() +endmacro() + diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index a4de3876243..b231a2b6fa4 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -398,21 +398,6 @@ if(WITH_TBB) find_package(TBB) endif() -if(NOT WITH_TBB OR NOT TBB_FOUND) - if(WITH_OPENIMAGEDENOISE) - message(STATUS "TBB not found, disabling OpenImageDenoise") - set(WITH_OPENIMAGEDENOISE OFF) - endif() - if(WITH_OPENVDB) - message(STATUS "TBB not found, disabling OpenVDB") - set(WITH_OPENVDB OFF) - endif() - if(WITH_MOD_FLUID) - message(STATUS "TBB not found, disabling Fluid modifier") - set(WITH_MOD_FLUID OFF) - endif() -endif() - # CMake FindOpenMP doesn't know about AppleClang before 3.12, so provide custom flags. if(WITH_OPENMP) if(CMAKE_C_COMPILER_ID MATCHES "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0") diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 2f9f39b46d9..91f836d5265 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -448,17 +448,6 @@ if(WITH_TBB) find_package_wrapper(TBB) endif() -if(NOT WITH_TBB OR NOT TBB_FOUND) - if(WITH_OPENIMAGEDENOISE) - message(STATUS "TBB not found, disabling OpenImageDenoise") - set(WITH_OPENIMAGEDENOISE OFF) - endif() - if(WITH_OPENVDB) - message(STATUS "TBB not found, disabling OpenVDB") - set(WITH_OPENVDB OFF) - endif() -endif() - # OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed if(HAIKU) list(APPEND PLATFORM_LINKLIBS -lnetwork) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index 04e5848dcfe..4241f307abc 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -570,19 +570,6 @@ if(WITH_TBB) if(WITH_TBB_MALLOC_PROXY) add_definitions(-DWITH_TBB_MALLOC) endif() -else() - if(WITH_OPENIMAGEDENOISE) - message(STATUS "TBB disabled, also disabling OpenImageDenoise") - set(WITH_OPENIMAGEDENOISE OFF) - endif() - if(WITH_OPENVDB) - message(STATUS "TBB disabled, also disabling OpenVDB") - set(WITH_OPENVDB OFF) - endif() - if(WITH_MOD_FLUID) - message(STATUS "TBB disabled, disabling Fluid modifier") - set(WITH_MOD_FLUID OFF) - endif() endif() # used in many places so include globally, like OpenGL -- cgit v1.2.3 From 08a4cb0727d2a176fd541676bf0cabcb6d9541d9 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 7 Feb 2020 15:26:35 +0100 Subject: Cleanup: `make format` Remember to run `make format` after cleanups/renames/... --- intern/cycles/blender/blender_light.cpp | 1 - intern/cycles/render/scene.cpp | 4 ++-- source/blender/blenlib/BLI_math_color_blend.h | 8 ++------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp index 5351de2e84b..6f95821e31e 100644 --- a/intern/cycles/blender/blender_light.cpp +++ b/intern/cycles/blender/blender_light.cpp @@ -210,4 +210,3 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) } CCL_NAMESPACE_END - diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 4f7d886cb10..24469620840 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -356,8 +356,8 @@ bool Scene::need_update() bool Scene::need_data_update() { return (background->need_update || image_manager->need_update || object_manager->need_update || - geometry_manager->need_update || light_manager->need_update || lookup_tables->need_update || - integrator->need_update || shader_manager->need_update || + geometry_manager->need_update || light_manager->need_update || + lookup_tables->need_update || integrator->need_update || shader_manager->need_update || particle_system_manager->need_update || curve_system_manager->need_update || bake_manager->need_update || film->need_update); } diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h index a3efb5d72e9..47bafff3a49 100644 --- a/source/blender/blenlib/BLI_math_color_blend.h +++ b/source/blender/blenlib/BLI_math_color_blend.h @@ -69,9 +69,7 @@ MINLINE void blend_color_overlay_byte(unsigned char dst[4], MINLINE void blend_color_hardlight_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]); -MINLINE void blend_color_burn_byte(unsigned char dst[4], - const uchar src1[4], - const uchar src2[4]); +MINLINE void blend_color_burn_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]); MINLINE void blend_color_linearburn_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]); @@ -102,9 +100,7 @@ MINLINE void blend_color_exclusion_byte(unsigned char dst[4], MINLINE void blend_color_color_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]); -MINLINE void blend_color_hue_byte(unsigned char dst[4], - const uchar src1[4], - const uchar src2[4]); +MINLINE void blend_color_hue_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]); MINLINE void blend_color_saturation_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]); -- cgit v1.2.3 From f2df4e0076a29a32813f870741b0f89fcbf00eed Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Fri, 7 Feb 2020 07:35:17 -0700 Subject: Build optimization: Compile glew for size rather than speed with msvc. Glew.obj is one of the more expensive targets we have to build clocking in at 34.907 seconds. The root cause [1] is the msvc inliner is not super thrilled with the glewIsSupported supported function, this patch changes the buildflags of extern_glew to optimize for size rather than speed. Given glew is only in play at initalization time there will be no performance impact. Time to build glew.obj Before: 34.907s After : 1.961s [1] https://developercommunity.visualstudio.com/content/problem/732941/slow-compilation-of-glewc-for-visual-studio-2019-x.html Differential Revision: https://developer.blender.org/D6656 Reviewers: brecht, sergey, fclem --- extern/glew/CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/extern/glew/CMakeLists.txt b/extern/glew/CMakeLists.txt index 18ca88e6fec..59f13eb73c7 100644 --- a/extern/glew/CMakeLists.txt +++ b/extern/glew/CMakeLists.txt @@ -25,6 +25,16 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") ) endif() +# MSVC's inliner is not having a happy time with glewIsSupported +# causing this to be one of the most expensive things to build +# in blender. Optimize for size rather than speed sidesteps this +# problem, more details at +# https://developercommunity.visualstudio.com/content/problem/732941/slow-compilation-of-glewc-for-visual-studio-2019-x.html + +if(MSVC) + add_c_flag("/Os") +endif() + set(INC include ) -- cgit v1.2.3 From faf08954d572c84d42de074effbca02fee3b27df Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 7 Feb 2020 16:29:02 +0100 Subject: Cleanup: Rename `BKE_library_idmap` file to `BKE_main_idmap` Part of T72604: > Proposal: BKE_library and BKE_main API naming: prefixes conventions --- source/blender/blenkernel/BKE_library_idmap.h | 45 ----- source/blender/blenkernel/BKE_main_idmap.h | 45 +++++ source/blender/blenkernel/CMakeLists.txt | 4 +- source/blender/blenkernel/intern/library_idmap.c | 214 ----------------------- source/blender/blenkernel/intern/main_idmap.c | 214 +++++++++++++++++++++++ source/blender/blenloader/intern/readfile.c | 2 +- 6 files changed, 262 insertions(+), 262 deletions(-) delete mode 100644 source/blender/blenkernel/BKE_library_idmap.h create mode 100644 source/blender/blenkernel/BKE_main_idmap.h delete mode 100644 source/blender/blenkernel/intern/library_idmap.c create mode 100644 source/blender/blenkernel/intern/main_idmap.c diff --git a/source/blender/blenkernel/BKE_library_idmap.h b/source/blender/blenkernel/BKE_library_idmap.h deleted file mode 100644 index 0285699dea3..00000000000 --- a/source/blender/blenkernel/BKE_library_idmap.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef __BKE_LIBRARY_IDMAP_H__ -#define __BKE_LIBRARY_IDMAP_H__ - -/** \file - * \ingroup bke - */ - -#include "BLI_compiler_attrs.h" - -struct ID; -struct IDNameLib_Map; -struct Main; - -struct IDNameLib_Map *BKE_main_idmap_create(struct Main *bmain, - const bool create_valid_ids_set, - struct Main *old_bmain) ATTR_WARN_UNUSED_RESULT - ATTR_NONNULL(1); -void BKE_main_idmap_destroy(struct IDNameLib_Map *id_typemap) ATTR_NONNULL(); -struct Main *BKE_main_idmap_main_get(struct IDNameLib_Map *id_typemap) ATTR_WARN_UNUSED_RESULT - ATTR_NONNULL(); -struct ID *BKE_main_idmap_lookup(struct IDNameLib_Map *id_typemap, - short id_type, - const char *name, - const struct Library *lib) ATTR_WARN_UNUSED_RESULT - ATTR_NONNULL(1, 3); -struct ID *BKE_main_idmap_lookup_id(struct IDNameLib_Map *id_typemap, - const struct ID *id) ATTR_WARN_UNUSED_RESULT - ATTR_NONNULL(1, 2); - -#endif /* __BKE_LIBRARY_IDMAP_H__ */ diff --git a/source/blender/blenkernel/BKE_main_idmap.h b/source/blender/blenkernel/BKE_main_idmap.h new file mode 100644 index 00000000000..d95f32b162a --- /dev/null +++ b/source/blender/blenkernel/BKE_main_idmap.h @@ -0,0 +1,45 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __BKE_MAIN_IDMAP_H__ +#define __BKE_MAIN_IDMAP_H__ + +/** \file + * \ingroup bke + */ + +#include "BLI_compiler_attrs.h" + +struct ID; +struct IDNameLib_Map; +struct Main; + +struct IDNameLib_Map *BKE_main_idmap_create(struct Main *bmain, + const bool create_valid_ids_set, + struct Main *old_bmain) ATTR_WARN_UNUSED_RESULT + ATTR_NONNULL(1); +void BKE_main_idmap_destroy(struct IDNameLib_Map *id_typemap) ATTR_NONNULL(); +struct Main *BKE_main_idmap_main_get(struct IDNameLib_Map *id_typemap) ATTR_WARN_UNUSED_RESULT + ATTR_NONNULL(); +struct ID *BKE_main_idmap_lookup(struct IDNameLib_Map *id_typemap, + short id_type, + const char *name, + const struct Library *lib) ATTR_WARN_UNUSED_RESULT + ATTR_NONNULL(1, 3); +struct ID *BKE_main_idmap_lookup_id(struct IDNameLib_Map *id_typemap, + const struct ID *id) ATTR_WARN_UNUSED_RESULT + ATTR_NONNULL(1, 2); + +#endif /* __BKE_MAIN_IDMAP_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 0aa4f0fe677..2f839aafa2c 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -136,7 +136,6 @@ set(SRC intern/layer.c intern/layer_utils.c intern/library.c - intern/library_idmap.c intern/library_override.c intern/library_query.c intern/library_remap.c @@ -144,6 +143,7 @@ set(SRC intern/lightprobe.c intern/linestyle.c intern/main.c + intern/main_idmap.c intern/mask.c intern/mask_evaluate.c intern/mask_rasterize.c @@ -299,7 +299,6 @@ set(SRC BKE_lattice.h BKE_layer.h BKE_library.h - BKE_library_idmap.h BKE_library_override.h BKE_library_query.h BKE_library_remap.h @@ -307,6 +306,7 @@ set(SRC BKE_lightprobe.h BKE_linestyle.h BKE_main.h + BKE_main_idmap.h BKE_mask.h BKE_material.h BKE_mball.h diff --git a/source/blender/blenkernel/intern/library_idmap.c b/source/blender/blenkernel/intern/library_idmap.c deleted file mode 100644 index ab0ff5b0096..00000000000 --- a/source/blender/blenkernel/intern/library_idmap.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_ghash.h" -#include "BLI_listbase.h" - -#include "DNA_ID.h" - -#include "BKE_idcode.h" -#include "BKE_library_idmap.h" /* own include */ -#include "BKE_main.h" - -/** \file - * \ingroup bke - * - * Utility functions for faster ID lookups. - */ - -/** \name BKE_main_idmap API - * - * Cache ID (name, library lookups). - * This doesn't account for adding/removing data-blocks, - * and should only be used when performing many lookups. - * - * \note GHash's are initialized on demand, - * since its likely some types will never have lookups run on them, - * so its a waste to create and never use. - * \{ */ - -struct IDNameLib_Key { - /** ``ID.name + 2``: without the ID type prefix, since each id type gets it's own 'map' */ - const char *name; - /** ``ID.lib``: */ - const Library *lib; -}; - -struct IDNameLib_TypeMap { - GHash *map; - short id_type; - /* only for storage of keys in the ghash, avoid many single allocs */ - struct IDNameLib_Key *keys; -}; - -/** - * Opaque structure, external API users only see this. - */ -struct IDNameLib_Map { - struct IDNameLib_TypeMap type_maps[MAX_LIBARRAY]; - struct Main *bmain; - struct GSet *valid_id_pointers; -}; - -static struct IDNameLib_TypeMap *main_idmap_from_idcode(struct IDNameLib_Map *id_map, - short id_type) -{ - for (int i = 0; i < MAX_LIBARRAY; i++) { - if (id_map->type_maps[i].id_type == id_type) { - return &id_map->type_maps[i]; - } - } - return NULL; -} - -/** - * Generate mapping from ID type/name to ID pointer for given \a bmain. - * - * \note When used during undo/redo, there is no guaranty that ID pointers from UI area - * are not pointing to freed memory (when some IDs have been deleted). To avoid crashes - * in those cases, one can provide the 'old' (aka current) Main database as reference. - * #BKE_main_idmap_lookup_id will then check that given ID does exist in \a old_bmain - * before trying to use it. - * - * \param create_valid_ids_set: If \a true, generate a reference to prevent freed memory accesses. - * \param old_bmain: If not NULL, its IDs will be added the valid references set. - */ -struct IDNameLib_Map *BKE_main_idmap_create(struct Main *bmain, - const bool create_valid_ids_set, - struct Main *old_bmain) -{ - struct IDNameLib_Map *id_map = MEM_mallocN(sizeof(*id_map), __func__); - - int index = 0; - while (index < MAX_LIBARRAY) { - struct IDNameLib_TypeMap *type_map = &id_map->type_maps[index]; - type_map->map = NULL; - type_map->id_type = BKE_idcode_iter_step(&index); - BLI_assert(type_map->id_type != 0); - } - BLI_assert(index == MAX_LIBARRAY); - - id_map->bmain = bmain; - - if (create_valid_ids_set) { - id_map->valid_id_pointers = BKE_main_gset_create(bmain, NULL); - if (old_bmain != NULL) { - id_map->valid_id_pointers = BKE_main_gset_create(old_bmain, id_map->valid_id_pointers); - } - } - else { - id_map->valid_id_pointers = NULL; - } - - return id_map; -} - -struct Main *BKE_main_idmap_main_get(struct IDNameLib_Map *id_map) -{ - return id_map->bmain; -} - -static unsigned int idkey_hash(const void *ptr) -{ - const struct IDNameLib_Key *idkey = ptr; - unsigned int key = BLI_ghashutil_strhash(idkey->name); - if (idkey->lib) { - key ^= BLI_ghashutil_ptrhash(idkey->lib); - } - return key; -} - -static bool idkey_cmp(const void *a, const void *b) -{ - const struct IDNameLib_Key *idkey_a = a; - const struct IDNameLib_Key *idkey_b = b; - return strcmp(idkey_a->name, idkey_b->name) || (idkey_a->lib != idkey_b->lib); -} - -ID *BKE_main_idmap_lookup(struct IDNameLib_Map *id_map, - short id_type, - const char *name, - const Library *lib) -{ - struct IDNameLib_TypeMap *type_map = main_idmap_from_idcode(id_map, id_type); - - if (UNLIKELY(type_map == NULL)) { - return NULL; - } - - /* lazy init */ - if (type_map->map == NULL) { - ListBase *lb = which_libbase(id_map->bmain, id_type); - const int lb_len = BLI_listbase_count(lb); - if (lb_len == 0) { - return NULL; - } - type_map->map = BLI_ghash_new_ex(idkey_hash, idkey_cmp, __func__, lb_len); - type_map->keys = MEM_mallocN(sizeof(struct IDNameLib_Key) * lb_len, __func__); - - GHash *map = type_map->map; - struct IDNameLib_Key *key = type_map->keys; - - for (ID *id = lb->first; id; id = id->next, key++) { - key->name = id->name + 2; - key->lib = id->lib; - BLI_ghash_insert(map, key, id); - } - } - - const struct IDNameLib_Key key_lookup = {name, lib}; - return BLI_ghash_lookup(type_map->map, &key_lookup); -} - -ID *BKE_main_idmap_lookup_id(struct IDNameLib_Map *id_map, const ID *id) -{ - /* When used during undo/redo, this function cannot assume that given id points to valid memory - * (i.e. has not been freed), - * so it has to check that it does exist in 'old' (aka current) Main database. - * Otherwise, we cannot provide new ID pointer that way (would crash accessing freed memory - * when trying to get ID name). - */ - if (id_map->valid_id_pointers == NULL || BLI_gset_haskey(id_map->valid_id_pointers, id)) { - return BKE_main_idmap_lookup(id_map, GS(id->name), id->name + 2, id->lib); - } - return NULL; -} - -void BKE_main_idmap_destroy(struct IDNameLib_Map *id_map) -{ - struct IDNameLib_TypeMap *type_map = id_map->type_maps; - for (int i = 0; i < MAX_LIBARRAY; i++, type_map++) { - if (type_map->map) { - BLI_ghash_free(type_map->map, NULL, NULL); - type_map->map = NULL; - MEM_freeN(type_map->keys); - } - } - - if (id_map->valid_id_pointers != NULL) { - BLI_gset_free(id_map->valid_id_pointers, NULL); - } - - MEM_freeN(id_map); -} - -/** \} */ diff --git a/source/blender/blenkernel/intern/main_idmap.c b/source/blender/blenkernel/intern/main_idmap.c new file mode 100644 index 00000000000..a210961b212 --- /dev/null +++ b/source/blender/blenkernel/intern/main_idmap.c @@ -0,0 +1,214 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_ghash.h" +#include "BLI_listbase.h" + +#include "DNA_ID.h" + +#include "BKE_idcode.h" +#include "BKE_main.h" +#include "BKE_main_idmap.h" /* own include */ + +/** \file + * \ingroup bke + * + * Utility functions for faster ID lookups. + */ + +/** \name BKE_main_idmap API + * + * Cache ID (name, library lookups). + * This doesn't account for adding/removing data-blocks, + * and should only be used when performing many lookups. + * + * \note GHash's are initialized on demand, + * since its likely some types will never have lookups run on them, + * so its a waste to create and never use. + * \{ */ + +struct IDNameLib_Key { + /** ``ID.name + 2``: without the ID type prefix, since each id type gets it's own 'map' */ + const char *name; + /** ``ID.lib``: */ + const Library *lib; +}; + +struct IDNameLib_TypeMap { + GHash *map; + short id_type; + /* only for storage of keys in the ghash, avoid many single allocs */ + struct IDNameLib_Key *keys; +}; + +/** + * Opaque structure, external API users only see this. + */ +struct IDNameLib_Map { + struct IDNameLib_TypeMap type_maps[MAX_LIBARRAY]; + struct Main *bmain; + struct GSet *valid_id_pointers; +}; + +static struct IDNameLib_TypeMap *main_idmap_from_idcode(struct IDNameLib_Map *id_map, + short id_type) +{ + for (int i = 0; i < MAX_LIBARRAY; i++) { + if (id_map->type_maps[i].id_type == id_type) { + return &id_map->type_maps[i]; + } + } + return NULL; +} + +/** + * Generate mapping from ID type/name to ID pointer for given \a bmain. + * + * \note When used during undo/redo, there is no guaranty that ID pointers from UI area + * are not pointing to freed memory (when some IDs have been deleted). To avoid crashes + * in those cases, one can provide the 'old' (aka current) Main database as reference. + * #BKE_main_idmap_lookup_id will then check that given ID does exist in \a old_bmain + * before trying to use it. + * + * \param create_valid_ids_set: If \a true, generate a reference to prevent freed memory accesses. + * \param old_bmain: If not NULL, its IDs will be added the valid references set. + */ +struct IDNameLib_Map *BKE_main_idmap_create(struct Main *bmain, + const bool create_valid_ids_set, + struct Main *old_bmain) +{ + struct IDNameLib_Map *id_map = MEM_mallocN(sizeof(*id_map), __func__); + + int index = 0; + while (index < MAX_LIBARRAY) { + struct IDNameLib_TypeMap *type_map = &id_map->type_maps[index]; + type_map->map = NULL; + type_map->id_type = BKE_idcode_iter_step(&index); + BLI_assert(type_map->id_type != 0); + } + BLI_assert(index == MAX_LIBARRAY); + + id_map->bmain = bmain; + + if (create_valid_ids_set) { + id_map->valid_id_pointers = BKE_main_gset_create(bmain, NULL); + if (old_bmain != NULL) { + id_map->valid_id_pointers = BKE_main_gset_create(old_bmain, id_map->valid_id_pointers); + } + } + else { + id_map->valid_id_pointers = NULL; + } + + return id_map; +} + +struct Main *BKE_main_idmap_main_get(struct IDNameLib_Map *id_map) +{ + return id_map->bmain; +} + +static unsigned int idkey_hash(const void *ptr) +{ + const struct IDNameLib_Key *idkey = ptr; + unsigned int key = BLI_ghashutil_strhash(idkey->name); + if (idkey->lib) { + key ^= BLI_ghashutil_ptrhash(idkey->lib); + } + return key; +} + +static bool idkey_cmp(const void *a, const void *b) +{ + const struct IDNameLib_Key *idkey_a = a; + const struct IDNameLib_Key *idkey_b = b; + return strcmp(idkey_a->name, idkey_b->name) || (idkey_a->lib != idkey_b->lib); +} + +ID *BKE_main_idmap_lookup(struct IDNameLib_Map *id_map, + short id_type, + const char *name, + const Library *lib) +{ + struct IDNameLib_TypeMap *type_map = main_idmap_from_idcode(id_map, id_type); + + if (UNLIKELY(type_map == NULL)) { + return NULL; + } + + /* lazy init */ + if (type_map->map == NULL) { + ListBase *lb = which_libbase(id_map->bmain, id_type); + const int lb_len = BLI_listbase_count(lb); + if (lb_len == 0) { + return NULL; + } + type_map->map = BLI_ghash_new_ex(idkey_hash, idkey_cmp, __func__, lb_len); + type_map->keys = MEM_mallocN(sizeof(struct IDNameLib_Key) * lb_len, __func__); + + GHash *map = type_map->map; + struct IDNameLib_Key *key = type_map->keys; + + for (ID *id = lb->first; id; id = id->next, key++) { + key->name = id->name + 2; + key->lib = id->lib; + BLI_ghash_insert(map, key, id); + } + } + + const struct IDNameLib_Key key_lookup = {name, lib}; + return BLI_ghash_lookup(type_map->map, &key_lookup); +} + +ID *BKE_main_idmap_lookup_id(struct IDNameLib_Map *id_map, const ID *id) +{ + /* When used during undo/redo, this function cannot assume that given id points to valid memory + * (i.e. has not been freed), + * so it has to check that it does exist in 'old' (aka current) Main database. + * Otherwise, we cannot provide new ID pointer that way (would crash accessing freed memory + * when trying to get ID name). + */ + if (id_map->valid_id_pointers == NULL || BLI_gset_haskey(id_map->valid_id_pointers, id)) { + return BKE_main_idmap_lookup(id_map, GS(id->name), id->name + 2, id->lib); + } + return NULL; +} + +void BKE_main_idmap_destroy(struct IDNameLib_Map *id_map) +{ + struct IDNameLib_TypeMap *type_map = id_map->type_maps; + for (int i = 0; i < MAX_LIBARRAY; i++, type_map++) { + if (type_map->map) { + BLI_ghash_free(type_map->map, NULL, NULL); + type_map->map = NULL; + MEM_freeN(type_map->keys); + } + } + + if (id_map->valid_id_pointers != NULL) { + BLI_gset_free(id_map->valid_id_pointers, NULL); + } + + MEM_freeN(id_map); +} + +/** \} */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9547e4cd05a..2ad79b4e252 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -121,7 +121,7 @@ #include "BKE_idprop.h" #include "BKE_layer.h" #include "BKE_library.h" -#include "BKE_library_idmap.h" +#include "BKE_main_idmap.h" #include "BKE_library_override.h" #include "BKE_library_query.h" #include "BKE_main.h" // for Main -- cgit v1.2.3 From 677e027f2069dac18891db931c860542cbcb4bbe Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Fri, 7 Feb 2020 16:35:26 +0100 Subject: Fix T73625: GPencil array offset wrong whe use Scale or Rotation This is not 100% a bug but a design change. The old method used the object origin as pivot point for Scale a nd Rotation, so when you moved the stroke in edit mode, the whole array ittems where offset because the pivot point distance changed. Now, before applying scale and rotation, the stroke is moved to object origin to keep the offset when scale or rotate, so these transformations are done in stroke local space. --- .../gpencil_modifiers/intern/MOD_gpencilarray.c | 30 ++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c index bb70b548675..e258fbdccd1 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c @@ -228,24 +228,34 @@ static void generate_geometry(GpencilModifierData *md, for (gps = gpf->strokes.first, idx = 0; gps; gps = gps->next, idx++) { /* check if stroke can be duplicated */ if (valid_strokes[idx]) { - /* Duplicate stroke */ - bGPDstroke *gps_dst = MEM_dupallocN(gps); - gps_dst->points = MEM_dupallocN(gps->points); - if (gps->dvert) { - gps_dst->dvert = MEM_dupallocN(gps->dvert); - BKE_gpencil_stroke_weights_duplicate(gps, gps_dst); + /* Calculate original stroke center (only first loop). */ + float r_min[3], r_max[3], center[3]; + if (x == 1) { + INIT_MINMAX(r_min, r_max); + BKE_gpencil_stroke_minmax(gps, false, r_min, r_max); + add_v3_v3v3(center, r_min, r_max); + mul_v3_fl(center, 0.5f); + sub_v3_v3v3(center, center, ob->obmat[3]); } - gps_dst->triangles = MEM_dupallocN(gps->triangles); + + /* Duplicate stroke */ + bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps); /* Move points */ for (int i = 0; i < gps->totpoints; i++) { bGPDspoint *pt = &gps_dst->points[i]; + /* Apply object local transform (Rot/Scale). */ if (mmd->object) { - /* apply local changes (rot/scale) */ mul_m4_v3(mat, &pt->x); } - /* global changes */ - mul_m4_v3(current_offset, &pt->x); + /* Translate to object origin. */ + float fpt[3]; + sub_v3_v3v3(fpt, &pt->x, center); + /* Global Rotate and scale. */ + mul_mat3_m4_v3(current_offset, fpt); + /* Global translate. */ + add_v3_v3(fpt, center); + add_v3_v3v3(&pt->x, fpt, current_offset[3]); } /* if replace material, use new one */ -- cgit v1.2.3