diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2020-06-26 13:57:10 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2020-06-26 13:57:10 +0300 |
commit | b5640df6c017ee15571e217a782a87dc85f4de3c (patch) | |
tree | 03acba02adc1013f7f49b5a466a9e479a16adcb6 | |
parent | 302499b4a69a7d16eca7d0f1d7e621e8b9591e3c (diff) | |
parent | e3a420c4773a1d1a79c21f15137066d4411d3574 (diff) |
Merge branch 'master' into greasepencil-edit-curve
42 files changed, 566 insertions, 190 deletions
diff --git a/build_files/build_environment/cmake/usd.cmake b/build_files/build_environment/cmake/usd.cmake index c98a9cae959..5fa1872cabc 100644 --- a/build_files/build_environment/cmake/usd.cmake +++ b/build_files/build_environment/cmake/usd.cmake @@ -27,6 +27,9 @@ set(USD_EXTRA_ARGS -DTBB_INCLUDE_DIRS=${LIBDIR}/tbb/include -DTBB_LIBRARIES=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} -DTbb_TBB_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} + # USD wants the tbb debug lib set even when you are doing a release build + # Otherwise it will error out during the cmake configure phase. + -DTBB_LIBRARIES_DEBUG=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} # This is a preventative measure that avoids possible conflicts when add-ons # try to load another USD library into the same process space. diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 8c36d34aeea..1a94d3e9db7 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -61,8 +61,10 @@ Session::Session(const SessionParams ¶ms_) TaskScheduler::init(params.threads); + /* Create CPU/GPU devices. */ device = Device::create(params.device, stats, profiler, params.background); + /* Create buffers for interactive rendering. */ if (params.background && !params.write_render_cb) { buffers = NULL; display = NULL; @@ -72,6 +74,9 @@ Session::Session(const SessionParams ¶ms_) display = new DisplayBuffer(device, params.display_buffer_linear); } + /* Validate denoising parameters. */ + set_denoising(params.denoising); + session_thread = NULL; scene = NULL; @@ -944,17 +949,21 @@ void Session::set_pause(bool pause_) void Session::set_denoising(const DenoiseParams &denoising) { - const bool need_denoise = denoising.need_denoising_task(); - - if (need_denoise && !(params.device.denoisers & denoising.type)) { - progress.set_error("Denoiser type not supported by compute device"); - return; - } + bool need_denoise = denoising.need_denoising_task(); /* Lock buffers so no denoising operation is triggered while the settings are changed here. */ thread_scoped_lock buffers_lock(buffers_mutex); params.denoising = denoising; + if (!(params.device.denoisers & denoising.type)) { + if (need_denoise) { + progress.set_error("Denoiser type not supported by compute device"); + } + + params.denoising.use = false; + need_denoise = false; + } + // TODO(pmours): Query the required overlap value for denoising from the device? tile_manager.slice_overlap = need_denoise && !params.background ? 64 : 0; diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index e81b2b2e268..a008100a3e2 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -755,7 +755,7 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd) mRNAMap["USING_OUTFLOW"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW); mRNAMap["USING_LOG_DISSOLVE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DISSOLVE_LOG); mRNAMap["USING_DISSOLVE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DISSOLVE); - mRNAMap["DO_OPEN"] = getBooleanString(mds->border_collisions == 0); + mRNAMap["DOMAIN_CLOSED"] = getBooleanString(borderCollisions.compare("") == 0); mRNAMap["CACHE_RESUMABLE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE); mRNAMap["USING_ADAPTIVETIME"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_TIME); mRNAMap["USING_SPEEDVECTORS"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS); @@ -1280,7 +1280,7 @@ bool MANTA::readNoise(FluidModifierData *mmd, int framenr, bool resumable) FluidDomainSettings *mds = mmd->domain; string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE); - string resumable_cache = (resumable) ? "False" : "True"; + string resumable_cache = (!resumable) ? "False" : "True"; /* Support older caches which had more granular file format control. */ char format = (!strcmp(mds->cache_id, FLUID_CACHE_VERSION)) ? mds->cache_data_format : diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h index 0fb577cc109..62274101859 100644 --- a/intern/mantaflow/intern/strings/fluid_script.h +++ b/intern/mantaflow/intern/strings/fluid_script.h @@ -96,7 +96,7 @@ gravity_s$ID$ = vec3($GRAVITY_X$, $GRAVITY_Y$, $GRAVITY_Z$) # in SI unit (e.g. m gs_s$ID$ = vec3($RESX$, $RESY$, $RESZ$)\n\ maxVel_s$ID$ = 0\n\ \n\ -doOpen_s$ID$ = $DO_OPEN$\n\ +domainClosed_s$ID$ = $DOMAIN_CLOSED$\n\ boundConditions_s$ID$ = '$BOUND_CONDITIONS$'\n\ boundaryWidth_s$ID$ = $BOUNDARY_WIDTH$\n\ deleteInObstacle_s$ID$ = $DELETE_IN_OBSTACLE$\n\ diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h index 1dec61c02da..04505206601 100644 --- a/intern/mantaflow/intern/strings/liquid_script.h +++ b/intern/mantaflow/intern/strings/liquid_script.h @@ -211,10 +211,10 @@ def liquid_adaptive_step_$ID$(framenr):\n\ if using_invel_s$ID$:\n\ extrapolateVec3Simple(vel=invelC_s$ID$, phi=phiIn_s$ID$, distance=6, inside=True)\n\ resampleVec3ToMac(source=invelC_s$ID$, target=invel_s$ID$)\n\ - pVel_pp$ID$.setSource(invel_s$ID$, isMAC=True)\n\ - # ensure that pvel has vel as source (important when resuming bake jobs)\n\ + pVel_pp$ID$.setSource(grid=invel_s$ID$, isMAC=True)\n\ + # reset pvel grid source before sampling new particles - ensures that new particles are initialized with 0 velocity\n\ else:\n\ - pVel_pp$ID$.setSource(vel_s$ID$, isMAC=True)\n\ + pVel_pp$ID$.setSource(grid=None, isMAC=False)\n\ \n\ sampleLevelsetWithParticles(phi=phiIn_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, discretization=particleNumber_s$ID$, randomness=randomness_s$ID$)\n\ flags_s$ID$.updateFromLevelset(phi_s$ID$)\n\ @@ -257,7 +257,7 @@ def liquid_step_$ID$():\n\ extrapolateLsSimple(phi=phi_s$ID$, distance=3)\n\ phi_s$ID$.setBoundNeumann(0) # make sure no particles are placed at outer boundary\n\ \n\ - if doOpen_s$ID$ or using_outflow_s$ID$:\n\ + if not domainClosed_s$ID$ or using_outflow_s$ID$:\n\ resetOutflow(flags=flags_s$ID$, phi=phi_s$ID$, parts=pp_s$ID$, index=gpi_s$ID$, indexSys=pindex_s$ID$)\n\ flags_s$ID$.updateFromLevelset(phi_s$ID$)\n\ \n\ @@ -298,10 +298,10 @@ def liquid_step_$ID$():\n\ \n\ if using_guiding_s$ID$:\n\ mantaMsg('Guiding and pressure')\n\ - PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, zeroPressureFixing=not doOpen_s$ID$)\n\ + PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, zeroPressureFixing=domainClosed_s$ID$)\n\ else:\n\ mantaMsg('Pressure')\n\ - solvePressure(flags=flags_s$ID$, vel=vel_s$ID$, pressure=pressure_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, obvel=obvel_s$ID$ if using_fractions_s$ID$ else None)\n\ + solvePressure(flags=flags_s$ID$, vel=vel_s$ID$, pressure=pressure_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, obvel=obvel_s$ID$ if using_fractions_s$ID$ else None, zeroPressureFixing=domainClosed_s$ID$)\n\ \n\ extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$, distance=4, intoObs=True if using_fractions_s$ID$ else False)\n\ setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\ @@ -310,7 +310,7 @@ def liquid_step_$ID$():\n\ extrapolateMACSimple(flags=flags_s$ID$, vel=vel_s$ID$)\n\ \n\ # set source grids for resampling, used in adjustNumber!\n\ - pVel_pp$ID$.setSource(vel_s$ID$, isMAC=True)\n\ + pVel_pp$ID$.setSource(grid=vel_s$ID$, isMAC=True)\n\ adjustNumber(parts=pp_s$ID$, vel=vel_s$ID$, flags=flags_s$ID$, minParticles=minParticles_s$ID$, maxParticles=maxParticles_s$ID$, phi=phi_s$ID$, exclude=phiObs_s$ID$, radiusFactor=radiusFactor_s$ID$, narrowBand=adjustedNarrowBandWidth_s$ID$)\n\ flipVelocityUpdate(vel=vel_s$ID$, velOld=velOld_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, partVel=pVel_pp$ID$, flipRatio=flipRatio_s$ID$)\n"; @@ -347,7 +347,7 @@ def liquid_step_mesh_$ID$():\n\ # Vert vel vector needs to pull data from vel grid with correct dim\n\ if using_speedvectors_s$ID$:\n\ interpolateMACGrid(target=vel_sm$ID$, source=vel_s$ID$)\n\ - mVel_mesh$ID$.setSource(vel_sm$ID$, isMAC=True)\n\ + mVel_mesh$ID$.setSource(grid=vel_sm$ID$, isMAC=True)\n\ \n\ # Set 0.5 boundary at walls + account for extra wall thickness in fractions mode + account for grid scaling:\n\ # E.g. at upres=1 we expect 1 cell border (or 2 with fractions), at upres=2 we expect 2 cell border (or 4 with fractions), etc.\n\ diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h index 5e80e4443a3..612d01b85ef 100644 --- a/intern/mantaflow/intern/strings/smoke_script.h +++ b/intern/mantaflow/intern/strings/smoke_script.h @@ -365,7 +365,7 @@ def smoke_step_$ID$():\n\ mantaMsg('Advecting velocity')\n\ advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=vel_s$ID$, order=2)\n\ \n\ - if doOpen_s$ID$ or using_outflow_s$ID$:\n\ + if not domainClosed_s$ID$ or using_outflow_s$ID$:\n\ resetOutflow(flags=flags_s$ID$, real=density_s$ID$)\n\ \n\ mantaMsg('Vorticity')\n\ @@ -406,10 +406,10 @@ def smoke_step_$ID$():\n\ mantaMsg('Using preconditioner: ' + str(preconditioner_s$ID$))\n\ if using_guiding_s$ID$:\n\ mantaMsg('Guiding and pressure')\n\ - PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, preconditioner=preconditioner_s$ID$, zeroPressureFixing=not doOpen_s$ID$)\n\ + PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, preconditioner=preconditioner_s$ID$, zeroPressureFixing=domainClosed_s$ID$)\n\ else:\n\ mantaMsg('Pressure')\n\ - solvePressure(flags=flags_s$ID$, vel=vel_s$ID$, pressure=pressure_s$ID$, preconditioner=preconditioner_s$ID$, zeroPressureFixing=not doOpen_s$ID$) # closed domains require pressure fixing\n\ + solvePressure(flags=flags_s$ID$, vel=vel_s$ID$, pressure=pressure_s$ID$, preconditioner=preconditioner_s$ID$, zeroPressureFixing=domainClosed_s$ID$) # closed domains require pressure fixing\n\ \n\ def process_burn_$ID$():\n\ mantaMsg('Process burn')\n\ @@ -551,7 +551,7 @@ const std::string smoke_load_noise = "\n\ def smoke_load_noise_$ID$(path, framenr, file_format, resumable):\n\ mantaMsg('Smoke load noise')\n\ - dict = { **smoke_noise_dict_final_s$ID$, **smoke_data_dict_resume_s$ID$ } if resumable else { **smoke_noise_dict_final_s$ID$ } \n\ + dict = { **smoke_noise_dict_final_s$ID$, **smoke_noise_dict_resume_s$ID$ } if resumable else { **smoke_noise_dict_final_s$ID$ } \n\ fluid_file_import_s$ID$(dict=dict, path=path, framenr=framenr, file_format=file_format, file_name=file_noise_s$ID$)\n\ \n\ if resumable:\n\ diff --git a/release/datafiles/blender_icons_geom_update.py b/release/datafiles/blender_icons_geom_update.py index 3b7724756db..5b95961ae6b 100755 --- a/release/datafiles/blender_icons_geom_update.py +++ b/release/datafiles/blender_icons_geom_update.py @@ -21,10 +21,10 @@ def edit_text_file(filename, marker_begin, marker_end, content): while data[marker_end_index - 1] in {'\t', ' '}: marker_end_index -= 1 if marker_begin_index == -1: - print('Error: {!r} not found'.format(marker_begin)) + print('Error: %r not found' % marker_begin) return if marker_end_index == -1: - print('Error: {!r} not found'.format(marker_end)) + print('Error: %r not found' % marker_end) return marker_begin_index += len(marker_begin) + 1 data_update = data[:marker_begin_index] + content + data[marker_end_index:] diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index a65ff15393a..8a074d23db9 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -172,8 +172,8 @@ def modules_refresh(module_cache=addons_fake_modules): if mod.__file__ != mod_path: print( "multiple addons with the same name:\n" - " " f"{mod.__file__!r}" "\n" - " " f"{mod_path!r}" + " %r\n" + " %r" % (mod.__file__, mod_path) ) error_duplicates.append((mod.bl_info["name"], mod.__file__, mod_path)) @@ -241,7 +241,7 @@ def check(module_name): if loaded_state is Ellipsis: print( - "Warning: addon-module " f"{module_name:s}" " found module " + "Warning: addon-module", module_name, "found module " "but without '__addon_enabled__' field, " "possible name collision from file:", repr(getattr(mod, "__file__", "<unknown>")), @@ -439,8 +439,9 @@ def disable(module_name, *, default_set=False, handle_error=None): handle_error(ex) else: print( - "addon_utils.disable: " f"{module_name:s}" " not", - ("disabled" if mod is None else "loaded") + "addon_utils.disable: %s not %s" % ( + module_name, + "disabled" if mod is None else "loaded") ) # could be in more than once, unlikely but better do this just in case. @@ -502,7 +503,7 @@ def _blender_manual_url_prefix(): else: manual_version = "dev" - return f"https://docs.blender.org/manual/en/{manual_version}" + return "https://docs.blender.org/manual/en/" + manual_version def module_bl_info(mod, info_basis=None): @@ -544,11 +545,11 @@ def module_bl_info(mod, info_basis=None): addon_info["doc_url"] = doc_url if _bpy.app.debug: print( - "Warning: add-on \"{addon_name}\": 'wiki_url' in 'bl_info' " + "Warning: add-on \"%s\": 'wiki_url' in 'bl_info' " "is deprecated please use 'doc_url' instead!\n" - " {addon_path}".format( - addon_name=addon_info['name'], - addon_path=getattr(mod, "__file__", None), + " %s" % ( + addon_info['name'], + getattr(mod, "__file__", None), ) ) diff --git a/release/scripts/modules/bl_previews_utils/bl_previews_render.py b/release/scripts/modules/bl_previews_utils/bl_previews_render.py index b79c0b744d0..73004cee731 100644 --- a/release/scripts/modules/bl_previews_utils/bl_previews_render.py +++ b/release/scripts/modules/bl_previews_utils/bl_previews_render.py @@ -505,7 +505,7 @@ def main(): if __name__ == "__main__": - print("\n\n *** Running {} *** \n".format(__file__)) - print(" *** Blend file {} *** \n".format(bpy.data.filepath)) + print("\n\n *** Running %s *** \n" % __file__) + print(" *** Blend file %s *** \n" % bpy.data.filepath) main() bpy.ops.wm.quit_blender() diff --git a/release/scripts/modules/bl_ui_utils/bug_report_url.py b/release/scripts/modules/bl_ui_utils/bug_report_url.py index 2adee70bc86..5676e0d6815 100644 --- a/release/scripts/modules/bl_ui_utils/bug_report_url.py +++ b/release/scripts/modules/bl_ui_utils/bug_report_url.py @@ -31,13 +31,13 @@ def url_prefill_from_blender(addon_info=None): fh.write("**System Information**\n") fh.write( - "Operating system: {!s} {!s} Bits\n".format( + "Operating system: %s %d Bits\n" % ( platform.platform(), struct.calcsize("P") * 8, ) ) fh.write( - "Graphics card: {!s} {!s} {!s}\n".format( + "Graphics card: %s %s %s\n" % ( bgl.glGetString(bgl.GL_RENDERER), bgl.glGetString(bgl.GL_VENDOR), bgl.glGetString(bgl.GL_VERSION), @@ -48,7 +48,7 @@ def url_prefill_from_blender(addon_info=None): "**Blender Version**\n" ) fh.write( - "Broken: version: {!s}, branch: {!s}, commit date: {!s} {!s}, hash: `rB{!s}`\n".format( + "Broken: version: %s, branch: %s, commit date: %s %s, hash: `rB%s`\n" % ( bpy.app.version_string, bpy.app.build_branch.decode('utf-8', 'replace'), bpy.app.build_commit_date.decode('utf-8', 'replace'), diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py index 8f8f42bcd46..4e226f80f79 100644 --- a/release/scripts/modules/bpy/ops.py +++ b/release/scripts/modules/bpy/ops.py @@ -123,7 +123,7 @@ class BPyOpsSubModOp: # op_class = getattr(bpy.types, idname) op_class = op_get_rna_type(idname) descr = op_class.description - return f"{sig}\n{descr}" + return "%s\n%s" % (sig, descr) @staticmethod def _parse_args(args): diff --git a/release/scripts/modules/bpy/utils/previews.py b/release/scripts/modules/bpy/utils/previews.py index bfdf28e0db4..7f337677635 100644 --- a/release/scripts/modules/bpy/utils/previews.py +++ b/release/scripts/modules/bpy/utils/previews.py @@ -76,8 +76,7 @@ class ImagePreviewCollection(dict): return raise ResourceWarning( - f"{self!r}: left open, remove with " - "'bpy.utils.previews.remove()'" + "%r: left open, remove with 'bpy.utils.previews.remove()'" % self ) self.close() @@ -116,7 +115,9 @@ class ImagePreviewCollection(dict): super().__delitem__(key) def __repr__(self): - return f"<{self.__class__.__name__:s} id={self._uuid:s}[{len(self):d}], {super()!r}>" + return "<%s id=%s[%d], %r>" % ( + self.__class__.__name__, self._uuid, len(self), super() + ) def new(): diff --git a/release/scripts/startup/bl_operators/sequencer.py b/release/scripts/startup/bl_operators/sequencer.py index e0aaea3c085..f8f37953f1c 100644 --- a/release/scripts/startup/bl_operators/sequencer.py +++ b/release/scripts/startup/bl_operators/sequencer.py @@ -234,7 +234,7 @@ class SequencerFadesAdd(Operator): sequence.invalidate('COMPOSITE') sequence_string = "sequence" if len(faded_sequences) == 1 else "sequences" - self.report({'INFO'}, "Added fade animation to {} {}.".format(len(faded_sequences), sequence_string)) + self.report({'INFO'}, "Added fade animation to %d %s." % (len(faded_sequences), sequence_string)) return {'FINISHED'} def calculate_fade_duration(self, context, sequence): @@ -362,7 +362,7 @@ class Fade: return max_value if max_value > 0.0 else 1.0 def __repr__(self): - return "Fade {}: {} to {}".format(self.type, self.start, self.end) + return "Fade %r: %r to %r" % (self.type, self.start, self.end) def calculate_duration_frames(context, duration_seconds): diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 4c4736cd669..04bd5687364 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1697,7 +1697,7 @@ class WM_OT_tool_set_by_id(Operator): tool_settings.workspace_tool_type = 'FALLBACK' return {'FINISHED'} else: - self.report({'WARNING'}, f"Tool {self.name!r:s} not found for space {space_type!r:s}.") + self.report({'WARNING'}, "Tool %r not found for space %r." % (self.name, space_type)) return {'CANCELLED'} @@ -2216,8 +2216,8 @@ class WM_OT_batch_rename(Operator): elif ty == 'STRIP': chars = action.strip_chars chars_strip = ( - "{:s}{:s}{:s}" - ).format( + "%s%s%s" + ) % ( string.punctuation if 'PUNCT' in chars else "", string.digits if 'DIGIT' in chars else "", " " if 'SPACE' in chars else "", @@ -2282,7 +2282,7 @@ class WM_OT_batch_rename(Operator): split.prop(self, "data_type", text="") split = layout.split(factor=0.5) - split.label(text="Rename {:d} {:s}:".format(len(self._data[0]), self._data[2])) + split.label(text="Rename %d %s:" % (len(self._data[0]), self._data[2])) split.row().prop(self, "data_source", expand=True) for action in self.actions: @@ -2397,7 +2397,7 @@ class WM_OT_batch_rename(Operator): change_len += 1 total_len += 1 - self.report({'INFO'}, "Renamed {:d} of {:d} {:s}".format(change_len, total_len, descr)) + self.report({'INFO'}, "Renamed %d of %d %s" % (change_len, total_len, descr)) return {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 696883d965c..5b8d97488f9 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -1528,7 +1528,7 @@ class SEQUENCER_PT_time(SequencerButtonsPanel, Panel): split.alignment = 'RIGHT' split.label(text="End") split = split.split(factor=0.8 + max_factor, align=True) - split.label(text="{:>14}".format(smpte_from_frame(frame_final_end))) + split.label(text="%14s" % smpte_from_frame(frame_final_end)) split.alignment = 'RIGHT' split.label(text=str(frame_final_end) + " ") @@ -1572,7 +1572,7 @@ class SEQUENCER_PT_time(SequencerButtonsPanel, Panel): split.label(text="Playhead") split = split.split(factor=0.8 + max_factor, align=True) frame_display = frame_current - frame_final_start - split.label(text="{:>14}".format(smpte_from_frame(frame_display))) + split.label(text="%14s" % smpte_from_frame(frame_display)) split.alignment = 'RIGHT' split.label(text=str(frame_display) + " ") diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index e0651dcac2b..f052e42766c 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -450,7 +450,7 @@ class ToolSelectPanelHelper: @classmethod def _km_action_simple(cls, kc_default, kc, context_descr, label, keymap_fn): - km_idname = f"{cls.keymap_prefix:s} {context_descr:s}, {label:s}" + km_idname = "%s %s, %s" % (cls.keymap_prefix, context_descr, label) km = kc.keymaps.get(km_idname) km_kwargs = dict(space_type=cls.bl_space_type, region_type='WINDOW', tool=True) if km is None: diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 2605cf1e1b9..d52cc6a6dad 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -124,12 +124,12 @@ class _defs_view3d_generic: kmi_remove = None return tip_( "Measure distance and angles.\n" - "\u2022 {} anywhere for new measurement.\n" + "\u2022 %s anywhere for new measurement.\n" "\u2022 Drag ruler segment to measure an angle.\n" - "\u2022 {} to remove the active ruler.\n" + "\u2022 %s to remove the active ruler.\n" "\u2022 Ctrl while dragging to snap.\n" "\u2022 Shift while dragging to measure surface thickness" - ).format( + ) % ( kmi_to_string_or_none(kmi_add), kmi_to_string_or_none(kmi_remove), ) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 42ae00203f3..c1502165e44 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -45,7 +45,7 @@ class USERPREF_HT_header(Header): # Show '*' to let users know the preferences have been modified. layout.operator( "wm.save_userpref", - text="Save Preferences{:s}".format(" *" if prefs.is_dirty else ""), + text="Save Preferences" + (" *" if prefs.is_dirty else ""), ) def draw(self, context): @@ -1903,8 +1903,10 @@ class USERPREF_PT_addons(AddOnPanel, Panel): "wm.url_open", text="Report a Bug", icon='URL', ).url = info["tracker_url"] elif not user_addon: - addon_info = ("Name: {} {}\nAuthor: {}\n").format( - info["name"], info["version"], info["author"]) + addon_info = ( + "Name: %s %s\n" + "Author: %s\n" + ) % (info["name"], str(info["version"]), info["author"]) props = sub.operator( "wm.url_open_preset", text="Report a Bug", icon='URL', ) @@ -1987,7 +1989,7 @@ class StudioLightPanelMixin: for studio_light in lights: self.draw_studio_light(flow, studio_light) else: - layout.label(text="No custom {} configured".format(self.bl_label)) + layout.label(text="No custom %s configured" % self.bl_label) def draw_studio_light(self, layout, studio_light): box = layout.box() @@ -2132,19 +2134,39 @@ class USERPREF_PT_experimental_virtual_reality(ExperimentalPanel, Panel): """ -class USERPREF_PT_experimental_system(ExperimentalPanel, Panel): - bl_label = "System" +class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel): + bl_label = "New Features" def draw(self, context): self._draw_items( context, ( - ({"property": "use_undo_legacy"}, "T60695"), ({"property": "use_new_particle_system"}, "T73324"), + ), + ) + + +class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel): + bl_label = "Prototypes" + + def draw(self, context): + self._draw_items( + context, ( ({"property": "use_new_hair_type"}, "T68981"), ), ) +class USERPREF_PT_experimental_debugging(ExperimentalPanel, Panel): + bl_label = "Debugging" + + def draw(self, context): + self._draw_items( + context, ( + ({"property": "use_undo_legacy"}, "T60695"), + ), + ) + + # ----------------------------------------------------------------------------- # Class Registration @@ -2235,7 +2257,9 @@ classes = ( # Popovers. USERPREF_PT_ndof_settings, - USERPREF_PT_experimental_system, + USERPREF_PT_experimental_new_features, + USERPREF_PT_experimental_prototypes, + USERPREF_PT_experimental_debugging, # Add dynamically generated editor theme panels last, # so they show up last in the theme section. diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index c8c8ab2ebb7..25e87a39bc1 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -5642,8 +5642,8 @@ class VIEW3D_PT_object_type_visibility(Panel): elif attr == "pointcloud" and not hasattr(bpy.data, "pointclouds"): continue - attr_v = "show_object_viewport_" f"{attr:s}" - attr_s = "show_object_select_" f"{attr:s}" + attr_v = "show_object_viewport_" + attr + attr_s = "show_object_select_" + attr icon_v = 'HIDE_OFF' if getattr(view, attr_v) else 'HIDE_ON' icon_s = 'RESTRICT_SELECT_OFF' if getattr(view, attr_s) else 'RESTRICT_SELECT_ON' diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 0a991d3ef4a..417fd182e73 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1185,6 +1185,11 @@ void BKE_brush_gpencil_paint_presets(Main *bmain, ToolSettings *ts, const bool r if (reset || brush_prev == NULL) { BKE_paint_brush_set(paint, deft_draw); } + else { + if (brush_prev != NULL) { + BKE_paint_brush_set(paint, brush_prev); + } + } } /* Create a set of grease pencil Vertex Paint presets. */ @@ -1227,6 +1232,11 @@ void BKE_brush_gpencil_vertex_presets(Main *bmain, ToolSettings *ts, const bool if (reset || brush_prev == NULL) { BKE_paint_brush_set(vertexpaint, deft_vertex); } + else { + if (brush_prev != NULL) { + BKE_paint_brush_set(vertexpaint, brush_prev); + } + } } /* Create a set of grease pencil Sculpt Paint presets. */ @@ -1297,6 +1307,11 @@ void BKE_brush_gpencil_sculpt_presets(Main *bmain, ToolSettings *ts, const bool if (reset || brush_prev == NULL) { BKE_paint_brush_set(sculptpaint, deft_sculpt); } + else { + if (brush_prev != NULL) { + BKE_paint_brush_set(sculptpaint, brush_prev); + } + } } /* Create a set of grease pencil Weight Paint presets. */ @@ -1318,6 +1333,11 @@ void BKE_brush_gpencil_weight_presets(Main *bmain, ToolSettings *ts, const bool if (reset || brush_prev == NULL) { BKE_paint_brush_set(weightpaint, deft_weight); } + else { + if (brush_prev != NULL) { + BKE_paint_brush_set(weightpaint, brush_prev); + } + } } struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode) diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c index 72ee4c5ec4d..46faddf6e5a 100644 --- a/source/blender/blenloader/intern/versioning_cycles.c +++ b/source/blender/blenloader/intern/versioning_cycles.c @@ -1568,6 +1568,7 @@ void do_versions_after_linking_cycles(Main *bmain) } if (cscene) { + const int DENOISER_AUTO = 0; const int DENOISER_NLM = 1; const int DENOISER_OPTIX = 2; @@ -1578,7 +1579,7 @@ void do_versions_after_linking_cycles(Main *bmain) /* Migrate Optix denoiser to new settings. */ if (cycles_property_int(cscene, "preview_denoising", 0)) { cycles_property_boolean_set(cscene, "use_preview_denoising", true); - cycles_property_boolean_set(cscene, "preview_denoiser", DENOISER_OPTIX); + cycles_property_int_set(cscene, "preview_denoiser", DENOISER_AUTO); } } diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 10f93a8f095..e971e465eca 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -175,6 +175,26 @@ typedef struct ProfileSpacing { } ProfileSpacing; /** + * If the mesh has custom data Loop layers that 'have math' we use this + * data to help decide which face to use as representative when there + * is an ambiguous choice as to which face to use, which happens + * when there is an odd number of segments. + * + * The face_compent field of the following will only be set if there are an odd + * number of segments. The it uses BMFace indices to index into it, so will + * only be valid as long BMFaces are not added or deleted in the BMesh. + * "Connected Component" here means connected in UV space: + * i.e., one face is directly connected to another if they share an edge and + * all of Loop UV custom layers are contiguous across that edge. + */ +typedef struct MathLayerInfo { + /** A connected-component id for each BMFace in the mesh. */ + int *face_component; + /** Does the mesh have any custom loop uv layers? */ + bool has_math_layers; +} MathLayerInfo; + +/** * An element in a cyclic boundary of a Vertex Mesh (VMesh), placed on each side of beveled edges * where each profile starts, or on each side of a miter. */ @@ -297,6 +317,8 @@ typedef struct BevelParams { ProfileSpacing pro_spacing; /** Parameter values for evenly spaced profile points for the miter profiles. */ ProfileSpacing pro_spacing_miter; + /** Information about 'math' loop layers, like UV layers. */ + MathLayerInfo math_layer_info; /** Blender units to offset each side of a beveled edge. */ float offset; /** How offset is measured; enum defined in bmesh_operators.h. */ @@ -733,12 +755,13 @@ static BMFace *bev_create_quad_ex(BMesh *bm, BMEdge *e2, BMEdge *e3, BMEdge *e4, + BMFace *frep, int mat_nr) { BMVert *varr[4] = {v1, v2, v3, v4}; BMFace *farr[4] = {f1, f2, f3, f4}; BMEdge *earr[4] = {e1, e2, e3, e4}; - return bev_create_ngon(bm, varr, 4, farr, f1, earr, mat_nr, true); + return bev_create_ngon(bm, varr, 4, farr, frep, earr, mat_nr, true); } /* Is Loop layer layer_index contiguous across shared vertex of l1 and l2? */ @@ -752,7 +775,8 @@ static bool contig_ldata_across_loops(BMesh *bm, BMLoop *l1, BMLoop *l2, int lay } /* Are all loop layers with have math (e.g., UVs) - * contiguous from face f1 to face f2 across edge e? */ + * contiguous from face f1 to face f2 across edge e? + */ static bool contig_ldata_across_edge(BMesh *bm, BMEdge *e, BMFace *f1, BMFace *f2) { BMLoop *lef1, *lef2; @@ -764,41 +788,202 @@ static bool contig_ldata_across_edge(BMesh *bm, BMEdge *e, BMFace *f1, BMFace *f return true; } - v1 = e->v1; - v2 = e->v2; if (!BM_edge_loop_pair(e, &lef1, &lef2)) { return false; } + /* If faces are oriented consistently around e, + * should now have lef1 and lef2 being f1 and f2 in either order. + */ if (lef1->f == f2) { SWAP(BMLoop *, lef1, lef2); } - - if (lef1->v == v1) { - lv1f1 = lef1; - lv2f1 = BM_face_other_edge_loop(f1, e, v2); + if (lef1->f != f1 || lef2 != lef2) { + return false; } - else { - lv2f1 = lef1; - lv1f1 = BM_face_other_edge_loop(f1, e, v1); + v1 = lef1->v; + v2 = lef2->v; + BLI_assert((v1 == e->v1 && v2 == e->v2) || (v1 == e->v2 && v2 == e->v1)); + lv1f1 = lef1; + lv2f1 = lef1->next; + lv1f2 = lef2->next; + lv2f2 = lef2; + BLI_assert(lv1f1->v == v1 && lv1f1->f == f1 && lv2f1->v == v2 && lv2f1->f == f1 && + lv1f2->v == v1 && lv1f2->f == f2 && lv2f2->v == v2 && lv2f2->f == f2); + for (i = 0; i < bm->ldata.totlayer; i++) { + if (CustomData_layer_has_math(&bm->ldata, i)) { + if (!contig_ldata_across_loops(bm, lv1f1, lv1f2, i) || + !contig_ldata_across_loops(bm, lv2f1, lv2f2, i)) { + return false; + } + } } + return true; +} + +/* + * Set up the fields of bp->math_layer_info. + * We always set has_math_layers to the correct value. + * Only if there are UV layers and the number of segments is odd, + * we need to calculate connected face components in UV space. + */ +static void math_layer_info_init(BevelParams *bp, BMesh *bm) +{ + int i, f, stack_top, totface, current_component; + int bmf_index, bmf_other_index; + int *face_component; + BMFace *bmf, *bmf_other; + BMEdge *bme; + BMFace **stack; + BMIter eiter, fiter; - if (lef2->v == v1) { - lv1f2 = lef2; - lv2f2 = BM_face_other_edge_loop(f2, e, v2); + bp->math_layer_info.has_math_layers = false; + bp->math_layer_info.face_component = NULL; + for (i = 0; i < bm->ldata.totlayer; i++) { + if (CustomData_has_layer(&bm->ldata, CD_MLOOPUV)) { + bp->math_layer_info.has_math_layers = true; + break; + } } - else { - lv2f2 = lef2; - lv1f2 = BM_face_other_edge_loop(f2, e, v1); + if (!bp->math_layer_info.has_math_layers || (bp->seg % 2) == 0) { + return; } - for (i = 0; i < bm->ldata.totlayer; i++) { - if (CustomData_layer_has_math(&bm->ldata, i) && - (!contig_ldata_across_loops(bm, lv1f1, lv1f2, i) || - !contig_ldata_across_loops(bm, lv2f1, lv2f2, i))) { - return false; + BM_mesh_elem_index_ensure(bm, BM_FACE); + BM_mesh_elem_table_ensure(bm, BM_FACE); + totface = bm->totface; + face_component = BLI_memarena_alloc(bp->mem_arena, totface * sizeof(int)); + bp->math_layer_info.face_component = face_component; + + /* Set all component ids by DFS from faces with unassigned components. */ + for (f = 0; f < totface; f++) { + face_component[f] = -1; + } + current_component = -1; + + /* Use an array as a stack. Stack size can't exceed double total faces. */ + stack = MEM_malloc_arrayN(2 * totface, sizeof(BMFace *), __func__); + for (f = 0; f < totface; f++) { + if (face_component[f] == -1) { + stack_top = 0; + current_component++; + BLI_assert(stack_top < 2 * totface); + stack[stack_top] = BM_face_at_index(bm, f); + while (stack_top >= 0) { + bmf = stack[stack_top]; + stack_top--; + bmf_index = BM_elem_index_get(bmf); + if (face_component[bmf_index] != -1) { + continue; + } + face_component[bmf_index] = current_component; + /* Neighbors are faces that share an edge with bmf and + * are where contig_ldata_across_edge(...) is true for the + * shared edge and two faces. + */ + BM_ITER_ELEM (bme, &eiter, bmf, BM_EDGES_OF_FACE) { + BM_ITER_ELEM (bmf_other, &fiter, bme, BM_FACES_OF_EDGE) { + if (bmf_other != bmf) { + bmf_other_index = BM_elem_index_get(bmf_other); + if (face_component[bmf_other_index] != -1) { + continue; + } + if (contig_ldata_across_edge(bm, bme, bmf, bmf_other)) { + stack_top++; + BLI_assert(stack_top < 2 * totface); + stack[stack_top] = bmf_other; + } + } + } + } + } } } - return true; + MEM_freeN(stack); +} + +/* Use a tie-breaking rule to choose a representative face when + * there are number of choices, face[0], face[1], ..., face[nfaces]. + * This is needed when there are an odd number of segments, and the center + * segmment (and its continuation into vmesh) can usually arbitrarily be + * the previous face or the next face. + * Or, for the center polygon of a corner, all of the faces around + * the vertex are possible choices. + * If we just choose randomly, the resulting UV maps or material + * assignment can look ugly/inconsistent. + * Allow for the case when args are null. + */ +static BMFace *choose_rep_face(BevelParams *bp, BMFace **face, int nfaces) +{ + int f, bmf_index, value_index, best_f, i; + BMFace *bmf; + float cent[3]; +#define VEC_VALUE_LEN 6 + float(*value_vecs)[VEC_VALUE_LEN] = NULL; + bool *still_viable = NULL; + int num_viable = 0; + + value_vecs = BLI_array_alloca(value_vecs, nfaces); + still_viable = BLI_array_alloca(still_viable, nfaces); + for (int f = 0; f < nfaces; f++) { + bmf = face[f]; + if (bmf == NULL) { + still_viable[f] = false; + continue; + } + still_viable[f] = true; + num_viable++; + bmf_index = BM_elem_index_get(bmf); + value_index = 0; + /* First tie-breaker: lower math-layer connected component id. */ + value_vecs[f][value_index++] = bp->math_layer_info.face_component ? + (float)bp->math_layer_info.face_component[bmf_index] : + 0.0f; + /* Next tie-breaker: selected face beats unselected one. */ + value_vecs[f][value_index++] = BM_elem_flag_test(bmf, BM_ELEM_SELECT) ? 0.0f : 1.0f; + /* Next tie-breaker: lower material index. */ + value_vecs[f][value_index++] = bmf->mat_nr >= 0 ? (float)bmf->mat_nr : 0.0f; + /* Next three tie-breakers: z, x, y components of face center. */ + BM_face_calc_center_bounds(bmf, cent); + value_vecs[f][value_index++] = cent[2]; + value_vecs[f][value_index++] = cent[0]; + value_vecs[f][value_index++] = cent[1]; + BLI_assert(value_index == VEC_VALUE_LEN); + } + + /* Look for a face that has a unique minimum value for in a value_index, + * trying each value_index in turn until find a unique minimum. + */ + best_f = -1; + for (value_index = 0; num_viable > 1 && value_index < VEC_VALUE_LEN; value_index++) { + for (f = 0; f < nfaces; f++) { + if (!still_viable[f] || f == best_f) { + continue; + } + if (best_f == -1) { + best_f = f; + continue; + } + if (value_vecs[f][value_index] < value_vecs[best_f][value_index]) { + best_f = f; + /* Previous f's are now not viable any more. */ + for (i = f - 1; i >= 0; i--) { + if (still_viable[i]) { + still_viable[i] = false; + num_viable--; + } + } + } + else if (value_vecs[f][value_index] > value_vecs[best_f][value_index]) { + still_viable[f] = false; + num_viable--; + } + } + } + if (best_f == -1) { + best_f = 0; + } + return face[best_f]; +#undef VEC_VALUE_LEN } /* Merge (using average) all the UV values for loops of v's faces. @@ -4472,6 +4657,105 @@ static float snap_face_dist_squared(float *co, BMFace *f, BMEdge **r_snap_e, flo return beste_d2; } +/* What would be the area of the polygon around bv if interpolated in face frep? + */ +static float interp_poly_area(BevVert *bv, BMFace *frep) +{ + BoundVert *v; + VMesh *vm = bv->vmesh; + BMEdge *snape; + int n; + float(*uv_co)[3] = NULL; + float area; + + BLI_assert(vm != NULL); + uv_co = BLI_array_alloca(uv_co, vm->count); + v = vm->boundstart; + n = 0; + do { + BLI_assert(n < vm->count); + snap_face_dist_squared(v->nv.v->co, frep, &snape, uv_co[n]); + n++; + } while ((v = v->next) != vm->boundstart); + area = fabsf(area_poly_v3(uv_co, n)); + return area; +} + +/** + * If we make a poly out of verts around bv, snapping to rep frep, will uv poly have zero area? + * The uv poly is made by snapping all outside-of-frep vertices to the closest edge in frep. + * Sometimes this results in a zero or very small area polygon, which translates to a zero + * or very small area polygong in UV space -- not good for interpolating textures. + */ +static bool is_bad_uv_poly(BevVert *bv, BMFace *frep) +{ + float area = interp_poly_area(bv, frep); + return area < BEVEL_EPSILON_BIG; +} + +/* + * Pick a good face from all the faces around bv to use for + * a representative face, using choose_rep_face. + * We want to choose from among the faces that would be + * chosen for a single-segment edge polygon between two successive + * Boundverts. + * But the single beveled edge is a special case, + * where we also want to consider the third face (else can get + * zero-area UV interpolated face). + * + * If there are math-having custom loop layers, like UV, then + * don't include faces that would result in zero-area UV polygons + * if chosen as the rep. + */ +static BMFace *frep_for_center_poly(BevelParams *bp, BevVert *bv) +{ + int i, j, fcount; + BMFace **fchoices, *bmf, *bmf1, *bmf2, *any_bmf; + BMFace *ftwo[2]; + bool already_there; + bool consider_all_faces; + + fcount = 0; + any_bmf = NULL; + consider_all_faces = bv->selcount == 1; + /* Make an array that can hold maximum possible number of choices. */ + fchoices = BLI_array_alloca(fchoices, bv->edgecount); + for (i = 0; i < bv->edgecount; i++) { + if (!bv->edges[i].is_bev && !consider_all_faces) { + continue; + } + bmf1 = bv->edges[i].fprev; + bmf2 = bv->edges[i].fnext; + ftwo[0] = bmf1; + ftwo[1] = bmf2; + bmf = choose_rep_face(bp, ftwo, 2); + if (bmf != NULL) { + if (any_bmf == NULL) { + any_bmf = bmf; + } + already_there = false; + for (j = fcount - 1; j >= 0; j--) { + if (fchoices[j] == bmf) { + already_there = true; + break; + } + } + if (!already_there) { + if (bp->math_layer_info.has_math_layers) { + if (is_bad_uv_poly(bv, bmf)) { + continue; + } + } + fchoices[fcount++] = bmf; + } + } + } + if (fcount == 0) { + return any_bmf; + } + return choose_rep_face(bp, fchoices, fcount); +} + static void build_center_ngon(BevelParams *bp, BMesh *bm, BevVert *bv, int mat_nr) { VMesh *vm = bv->vmesh; @@ -4488,7 +4772,7 @@ static void build_center_ngon(BevelParams *bp, BMesh *bm, BevVert *bv, int mat_n ns2 = vm->seg / 2; if (bv->any_seam) { - frep = boundvert_rep_face(vm->boundstart, NULL); + frep = frep_for_center_poly(bp, bv); get_incident_edges(frep, bv->v, &frep_e1, &frep_e2); } else { @@ -4813,7 +5097,8 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert VMesh *vm1, *vm; BoundVert *bndv; BMVert *bmv1, *bmv2, *bmv3, *bmv4; - BMFace *f, *f2, *r_f; + BMFace *f, *f2, *r_f, *fc; + BMFace *fchoices[2]; BMEdge *bme, *bme1, *bme2, *bme3; EdgeHalf *e; int mat_nr = bp->mat_nr; @@ -4867,6 +5152,14 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert i = bndv->index; f = boundvert_rep_face(bndv, NULL); f2 = boundvert_rep_face(bndv->next, NULL); + fchoices[0] = f; + fchoices[1] = f2; + if (odd) { + fc = choose_rep_face(bp, fchoices, 2); + } + else { + fc = NULL; + } if (bp->vertex_only) { e = bndv->efirst; } @@ -4877,7 +5170,10 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert /* For odd ns, make polys with lower left corner at (i,j,k) for * j in [0, ns2-1], k in [0, ns2]. And then the center ngon. * For even ns, - * j in [0, ns2-1], k in [0, ns2-1]. */ + * j in [0, ns2-1], k in [0, ns2-1]. + * + * Recall: j is ring index, k is segment index. + */ for (j = 0; j < ns2; j++) { for (k = 0; k < ns2 + odd; k++) { bmv1 = mesh_vert(vm, i, j, k)->v; @@ -4901,6 +5197,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert NULL, bndv->next->efirst->e, bme, + f2, mat_nr); } else { @@ -4914,11 +5211,11 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert /* Only one edge attached to v, since vertex_only. */ if (e->is_seam) { r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, bme, NULL, bme, NULL, mat_nr); + bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, bme, NULL, bme, NULL, f2, mat_nr); } else { r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f, bme, NULL, bme, NULL, mat_nr); + bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f, bme, NULL, bme, NULL, f2, mat_nr); } } } @@ -4927,10 +5224,11 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert if (k == ns2) { if (e && e->is_seam) { r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, NULL, bme, bme, NULL, mat_nr); + bm, bmv1, bmv2, bmv3, bmv4, fc, fc, fc, fc, NULL, bme, bme, NULL, fc, mat_nr); } else { - r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f, f2, f2, f, mat_nr); + r_f = bev_create_quad_ex( + bm, bmv1, bmv2, bmv3, bmv4, f, f2, f2, f, NULL, bme, bme, NULL, fc, mat_nr); } } else { @@ -4945,7 +5243,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert } bme2 = bme1 != NULL ? bme1 : bme3; r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, NULL, bme1, bme2, bme3, mat_nr); + bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, NULL, bme1, bme2, bme3, f, mat_nr); } } record_face_kind(bp, r_f, F_VERT); @@ -5143,43 +5441,9 @@ static void bevel_build_cutoff(BevelParams *bp, BMesh *bm, BevVert *bv) } } -/** - * If we make a poly out of verts around bv, snapping to rep frep, will uv poly have zero area? - * The uv poly is made by snapping all outside-of-frep vertices to the closest edge in frep. - * Assume that this function is called when the only inside-of-frep vertex is vm->boundstart. - * The poly will have zero area if the distance of that first vertex to some edge e is zero, - * and all the other vertices snap to e or snap to an edge - * at a point that is essentially on e too. - */ -static bool is_bad_uv_poly(BevVert *bv, BMFace *frep) -{ - BoundVert *v; - BMEdge *snape, *firste; - float co[3]; - VMesh *vm = bv->vmesh; - float d2; - - v = vm->boundstart; - d2 = snap_face_dist_squared(v->nv.v->co, frep, &firste, co); - if (d2 > BEVEL_EPSILON_BIG_SQ || firste == NULL) { - return false; - } - - for (v = v->next; v != vm->boundstart; v = v->next) { - snap_face_dist_squared(v->nv.v->co, frep, &snape, co); - if (snape != firste) { - d2 = dist_to_line_v3(co, firste->v1->co, firste->v2->co); - if (d2 > BEVEL_EPSILON_BIG_SQ) { - return false; - } - } - } - return true; -} - static BMFace *bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv) { - BMFace *f, *repface, *frep2; + BMFace *f, *repface; int n, k; VMesh *vm = bv->vmesh; BoundVert *bndv; @@ -5192,10 +5456,7 @@ static BMFace *bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv) BLI_array_staticdeclare(bmfaces, BM_DEFAULT_NGON_STACK_SIZE); if (bv->any_seam) { - repface = boundvert_rep_face(vm->boundstart, &frep2); - if (frep2 && repface && is_bad_uv_poly(bv, repface)) { - repface = frep2; - } + repface = frep_for_center_poly(bp, bv); get_incident_edges(repface, bv->v, &repface_e1, &repface_e2); } else { @@ -6413,7 +6674,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) VMesh *vm1, *vm2; EdgeHalf *e1, *e2; BMEdge *bme1, *bme2, *center_bme; - BMFace *f1, *f2, *f, *r_f; + BMFace *f1, *f2, *f, *r_f, *f_choice; BMVert *verts[4]; BMFace *faces[4]; BMEdge *edges[4]; @@ -6474,15 +6735,17 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) verts[3] = mesh_vert(vm1, i1, 0, k)->v; verts[2] = mesh_vert(vm2, i2, 0, nseg - k)->v; if (odd && k == mid + 1) { + BMFace *fchoices[2] = {f1, f2}; + edges[0] = edges[1] = NULL; + edges[2] = edges[3] = bme; + f_choice = choose_rep_face(bp, fchoices, 2); if (e1->is_seam) { - /* Straddles a seam: choose to interpolate in f1 and snap right edge to bme. */ - edges[0] = edges[1] = NULL; - edges[2] = edges[3] = bme; - r_f = bev_create_ngon(bm, verts, 4, NULL, f1, edges, mat_nr, true); + /* Straddles a seam: choose to interpolate in f_choice and snap right edge to bme. */ + r_f = bev_create_ngon(bm, verts, 4, NULL, f_choice, edges, mat_nr, true); } else { /* Straddles but not a seam: interpolate left half in f1, right half in f2. */ - r_f = bev_create_ngon(bm, verts, 4, faces, NULL, NULL, mat_nr, true); + r_f = bev_create_ngon(bm, verts, 4, faces, f_choice, NULL, mat_nr, true); } } else if (!odd && k == mid) { @@ -7264,6 +7527,8 @@ void BM_mesh_bevel(BMesh *bm, bp.face_hash = BLI_ghash_ptr_new(__func__); BLI_ghash_flag_set(bp.face_hash, GHASH_FLAG_ALLOW_DUPES); + math_layer_info_init(&bp, bm); + /* Analyze input vertices, sorting edges and assigning initial new vertex positions. */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index d84ec9b1363..dab5c3ea911 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -594,7 +594,7 @@ void DepsgraphNodeBuilder::build_object(int base_index, } id_node->has_base |= (base_index != -1); /* Various flags, flushing from bases/collections. */ - build_object_flags(base_index, object, linked_state); + build_object_from_layer(base_index, object, linked_state); /* Transform. */ build_object_transform(object); /* Parent. */ @@ -662,6 +662,21 @@ void DepsgraphNodeBuilder::build_object(int base_index, function_bind(BKE_object_sync_to_original, _1, object_cow)); } +void DepsgraphNodeBuilder::build_object_from_layer(int base_index, + Object *object, + eDepsNode_LinkedState_Type linked_state) +{ + + OperationNode *entry_node = add_operation_node( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_FROM_LAYER_ENTRY); + entry_node->set_as_entry(); + OperationNode *exit_node = add_operation_node( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_FROM_LAYER_EXIT); + exit_node->set_as_exit(); + + build_object_flags(base_index, object, linked_state); +} + void DepsgraphNodeBuilder::build_object_flags(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index e0553182918..dbe3e310d72 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -168,6 +168,9 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { virtual void build_object_proxy_from(Object *object, bool is_object_visible); virtual void build_object_proxy_group(Object *object, bool is_object_visible); virtual void build_object_instance_collection(Object *object, bool is_object_visible); + virtual void build_object_from_layer(int base_index, + Object *object, + eDepsNode_LinkedState_Type linked_state); virtual void build_object_flags(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index e21a83485ad..5b49e13e17a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -621,12 +621,9 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll } } -void DepsgraphRelationBuilder::build_object(Base *base, Object *object) +void DepsgraphRelationBuilder::build_object(Base * /*base*/, Object *object) { if (built_map_.checkIsBuiltAndTag(object)) { - if (base != nullptr) { - build_object_flags(base, object); - } return; } /* Object Transforms */ @@ -644,7 +641,7 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object) OperationKey ob_eval_key(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL); add_relation(init_transform_key, local_transform_key, "Transform Init"); /* Various flags, flushing from bases/collections. */ - build_object_flags(base, object); + build_object_from_layer_relations(object); /* Parenting. */ if (object->parent != nullptr) { /* Make sure parent object's relations are built. */ @@ -755,20 +752,34 @@ void DepsgraphRelationBuilder::build_object_proxy_group(Object *object) add_relation(proxy_group_eval_key, transform_eval_key, "Proxy Group Transform"); } -void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object) +void DepsgraphRelationBuilder::build_object_from_layer_relations(Object *object) { - if (base == nullptr) { - return; + OperationKey object_from_layer_entry_key( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_FROM_LAYER_ENTRY); + OperationKey object_from_layer_exit_key( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_FROM_LAYER_EXIT); + OperationKey object_flags_key( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_BASE_FLAGS); + + /* Only connect Entry -> Exit if there is no OBJECT_BASE_FLAGS node. */ + if (has_node(object_flags_key)) { + /* Entry -> OBJECT_BASE_FLAGS -> Exit */ + add_relation(object_from_layer_entry_key, object_flags_key, "Base flags flush Entry"); + add_relation(object_flags_key, object_from_layer_exit_key, "Base flags flush Exit"); + + /* Synchronization back to original object. */ + OperationKey synchronize_key( + &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL); + add_relation(object_from_layer_exit_key, synchronize_key, "Synchronize to Original"); + } + else { + /* Directly connect Entry -> Exit. */ + add_relation(object_from_layer_entry_key, object_from_layer_exit_key, "Object from Layer"); } + OperationKey view_layer_done_key( &scene_->id, NodeType::LAYER_COLLECTIONS, OperationCode::VIEW_LAYER_EVAL); - OperationKey object_flags_key( - &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_BASE_FLAGS); - add_relation(view_layer_done_key, object_flags_key, "Base flags flush"); - /* Synchronization back to original object. */ - OperationKey synchronize_key( - &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL); - add_relation(object_flags_key, synchronize_key, "Synchronize to Original"); + add_relation(view_layer_done_key, object_from_layer_entry_key, "View Layer flags to Object"); } void DepsgraphRelationBuilder::build_object_data(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index aa6d8ababd3..1be68babbc5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -213,7 +213,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { virtual void build_object(Base *base, Object *object); virtual void build_object_proxy_from(Object *object); virtual void build_object_proxy_group(Object *object); - virtual void build_object_flags(Base *base, Object *object); + virtual void build_object_from_layer_relations(Object *object); virtual void build_object_data(Object *object); virtual void build_object_data_camera(Object *object); virtual void build_object_data_geometry(Object *object); diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index b757a4fc477..73aa58d2072 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -109,7 +109,7 @@ void depsgraph_select_tag_to_component_opcode(const ID *id, } else if (id_type == ID_OB) { *component_type = NodeType::OBJECT_FROM_LAYER; - *operation_code = OperationCode::OBJECT_BASE_FLAGS; + *operation_code = OperationCode::OBJECT_FROM_LAYER_ENTRY; } else if (id_type == ID_MC) { *component_type = NodeType::BATCH_CACHE; diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index 91bd0117f6c..33d2bf79a5e 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -63,8 +63,12 @@ const char *operationCodeAsString(OperationCode opcode) case OperationCode::AUDIO_VOLUME: return "AUDIO_VOLUME"; /* Object related. */ + case OperationCode::OBJECT_FROM_LAYER_ENTRY: + return "OBJECT_FROM_LAYER_ENTRY"; case OperationCode::OBJECT_BASE_FLAGS: return "OBJECT_BASE_FLAGS"; + case OperationCode::OBJECT_FROM_LAYER_EXIT: + return "OBJECT_FROM_LAYER_EXIT"; case OperationCode::DIMENSIONS: return "DIMENSIONS"; /* Transform. */ diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 6b14e6af02f..4ed266d355f 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -63,7 +63,9 @@ enum class OperationCode { AUDIO_VOLUME, /* Object related. ------------------------------------------------------ */ + OBJECT_FROM_LAYER_ENTRY, OBJECT_BASE_FLAGS, + OBJECT_FROM_LAYER_EXIT, DIMENSIONS, /* Transform. ----------------------------------------------------------- */ diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 04878c7268a..714481c39f1 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -365,8 +365,9 @@ void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata) effects->taa_current_sample += 1; } else { - if ((effects->taa_total_sample == 0) || - (effects->taa_current_sample < effects->taa_total_sample)) { + if (!DRW_state_is_playback() && + ((effects->taa_total_sample == 0) || + (effects->taa_current_sample < effects->taa_total_sample))) { DRW_viewport_request_redraw(); } } diff --git a/source/blender/draw/engines/overlay/overlay_grid.c b/source/blender/draw/engines/overlay/overlay_grid.c index 5ed32de6d93..e3079870d8f 100644 --- a/source/blender/draw/engines/overlay/overlay_grid.c +++ b/source/blender/draw/engines/overlay/overlay_grid.c @@ -41,6 +41,7 @@ enum { CLIP_ZPOS = (1 << 7), CLIP_ZNEG = (1 << 8), GRID_BACK = (1 << 9), + GRID_CAMERA = (1 << 10), }; void OVERLAY_grid_init(OVERLAY_Data *vedata) @@ -145,6 +146,9 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata) if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) { Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera); dist = ((Camera *)(camera_object->data))->clip_end; + shd->grid_flag |= GRID_CAMERA; + shd->zneg_flag |= GRID_CAMERA; + shd->zpos_flag |= GRID_CAMERA; } else { dist = v3d->clip_end; diff --git a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl index 9743f918ce3..317e9fe0447 100644 --- a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl @@ -28,7 +28,8 @@ uniform float gridSteps[STEPS_LEN] = float[](0.001, 0.01, 0.1, 1.0, 10.0, 100.0, #define PLANE_XY (1 << 4) #define PLANE_XZ (1 << 5) #define PLANE_YZ (1 << 6) -#define GRID_BACK (1 << 9) /* grid is behind objects */ +#define GRID_BACK (1 << 9) /* grid is behind objects */ +#define GRID_CAMERA (1 << 10) /* In camera view */ #define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */ @@ -104,7 +105,9 @@ void main() fade *= 1.0 - smoothstep(0.0, gridDistance, dist - gridDistance); } else { - dist = abs(gl_FragCoord.z * 2.0 - 1.0); + dist = gl_FragCoord.z * 2.0 - 1.0; + /* Avoid fading in +Z direction in camera view (see T70193). */ + dist = ((gridFlag & GRID_CAMERA) != 0) ? clamp(dist, 0.0, 1.0) : abs(dist); fade = 1.0 - smoothstep(0.0, 0.5, dist - 0.5); dist = 1.0; /* avoid branch after */ diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c index f4ed2add624..edc36326c57 100644 --- a/source/blender/editors/animation/time_scrub_ui.c +++ b/source/blender/editors/animation/time_scrub_ui.c @@ -112,16 +112,15 @@ static void draw_current_frame(const Scene *scene, /* Draw vertical line to from the bottom of the current frame box to the bottom of the screen. */ const float subframe_x = UI_view2d_view_to_region_x(v2d, current_frame + sub_frame); - GPU_line_width(2.0f); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_CFRAME); - immBegin(GPU_PRIM_LINES, 2); - - immVertex2f(pos, subframe_x, scrub_region_rect->ymax - box_padding); - immVertex2f(pos, subframe_x, 0.0f); - immEnd(); + immRectf(pos, + subframe_x - U.pixelsize, + scrub_region_rect->ymax - box_padding, + subframe_x + U.pixelsize, + 0.0f); immUnbindProgram(); } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 98cb85061f2..d9402261175 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -475,13 +475,18 @@ void UI_draw_roundbox_shade_x(bool filled, .color_outline[1] = clamp_f(col[1] + shadetop + shadedown, 0.0f, 1.0f), .color_outline[2] = clamp_f(col[2] + shadetop + shadedown, 0.0f, 1.0f), .color_outline[3] = clamp_f(col[3] + shadetop + shadedown, 0.0f, 1.0f), + .shade_dir = 1.0f, .alpha_discard = 1.0f, }; + GPU_blend(true); + GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); GPU_batch_draw(batch); + + GPU_blend(false); } #if 0 /* unused */ diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 173aa51f406..9ff678df0db 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -1491,11 +1491,6 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co ps->panel->ofsx = 0; ps->panel->ofsy = -get_panel_size_y(ps->panel); ps->panel->ofsx += ps->panel->runtime.region_ofsx; - /* Extra margin if the panel is a box style panel. */ - if (ps->panel->type && ps->panel->type->flag & PNL_DRAW_BOX) { - ps->panel->ofsx += UI_PANEL_BOX_STYLE_MARGIN; - ps->panel->ofsy -= UI_PANEL_BOX_STYLE_MARGIN; - } for (a = 0; a < tot - 1; a++, ps++) { psnext = ps + 1; @@ -1505,16 +1500,12 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co bool use_box_next = psnext->panel->type && psnext->panel->type->flag & PNL_DRAW_BOX; psnext->panel->ofsx = ps->panel->ofsx; psnext->panel->ofsy = get_panel_real_ofsy(ps->panel) - get_panel_size_y(psnext->panel); + /* Extra margin for box style panels. */ + ps->panel->ofsx += (use_box) ? UI_PANEL_BOX_STYLE_MARGIN : 0.0f; if (use_box || use_box_next) { psnext->panel->ofsy -= UI_PANEL_BOX_STYLE_MARGIN; } - if (use_box && !use_box_next) { - psnext->panel->ofsx -= UI_PANEL_BOX_STYLE_MARGIN; - } - else if (!use_box && use_box_next) { - psnext->panel->ofsx += UI_PANEL_BOX_STYLE_MARGIN; - } } else { psnext->panel->ofsx = get_panel_real_ofsx(ps->panel); @@ -1522,6 +1513,10 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co get_panel_size_y(psnext->panel); } } + /* Extra margin for the last panel if it's a box-style panel. */ + if (panelsort[tot - 1].panel->type && panelsort[tot - 1].panel->type->flag & PNL_DRAW_BOX) { + panelsort[tot - 1].panel->ofsx += UI_PANEL_BOX_STYLE_MARGIN; + } /* we interpolate */ done = false; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index f07bb800eca..bc272431e3a 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -2356,8 +2356,10 @@ void outliner_build_tree( for (lib = mainvar->libraries.first; lib; lib = lib->id.next) { ten = outliner_add_library_contents(mainvar, soops, &soops->tree, lib); - BLI_assert(ten != NULL); - lib->id.newid = (ID *)ten; + /* NULL-check matters, due to filtering there may not be a new element. */ + if (ten) { + lib->id.newid = (ID *)ten; + } } /* make hierarchy */ ten = soops->tree.first; diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl index 05fbae53e18..21c7f79a57c 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl @@ -19,9 +19,14 @@ vec3 compute_masks(vec2 uv) bool right_half = uv.x > outRectSize.x * 0.5; float corner_rad; + /* Correct aspect ratio for 2D views not using uniform scalling. + * uv is already in pixel space so a uniform scale should give us a ratio of 1. */ + float ratio = (butCo != -2.0) ? (dFdy(uv.y) / dFdx(uv.x)) : 1.0; vec2 uv_sdf = uv; + uv_sdf.x *= ratio; + if (right_half) { - uv_sdf.x = outRectSize.x - uv_sdf.x; + uv_sdf.x = outRectSize.x * ratio - uv_sdf.x; } if (upper_half) { uv_sdf.y = outRectSize.y - uv_sdf.y; @@ -43,7 +48,7 @@ vec3 compute_masks(vec2 uv) /* Clamp line width to be at least 1px wide. This can happen if the projection matrix * has been scaled (i.e: Node editor)... */ - float line_width = (lineWidth > 0.0) ? max(fwidth(uv.x), lineWidth) : 0.0; + float line_width = (lineWidth > 0.0) ? max(fwidth(uv.y), lineWidth) : 0.0; const float aa_radius = 0.5; vec3 masks; diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl index 30d0cd05926..2fd5effccce 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl @@ -163,7 +163,7 @@ vec2 do_tria() borderColor = vec4(0.0); embossColor = vec4(0.0); - butCo = -1.0; + butCo = -2.0; return pos; } diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 9e0194f8a1b..1670e08325f 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -445,7 +445,7 @@ void RNA_def_main(BlenderRNA *brna) 0, INT_MAX, "Version", - "Version of Blender the .blend was saved with", + "File format version the .blend file was saved with", 0, INT_MAX); RNA_def_property_int_funcs(prop, "rna_Main_version_get", NULL, NULL); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index c35b768fd01..57e46314777 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -5454,6 +5454,7 @@ static void rna_def_modifier_remesh(BlenderRNA *brna) prop = RNA_def_property(srna, "voxel_size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "voxel_size"); + RNA_def_property_range(prop, 0.0001f, FLT_MAX); RNA_def_property_ui_range(prop, 0.0001, 2, 0.1, 3); RNA_def_property_ui_text(prop, "Voxel Size", diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 9c07280e70f..6a6d9f3054f 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6074,11 +6074,11 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) prop = RNA_def_property(srna, "use_new_particle_system", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_new_particle_system", 1); RNA_def_property_ui_text( - prop, "Use New Particle System", "Enable the new particle system in the ui"); + prop, "New Particle System", "Enable the new particle system in the ui"); prop = RNA_def_property(srna, "use_new_hair_type", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_new_hair_type", 1); - RNA_def_property_ui_text(prop, "Use New Hair Type", "Enable the new hair type in the ui"); + RNA_def_property_ui_text(prop, "New Hair Type", "Enable the new hair type in the ui"); } static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop) diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 32e36fbd09e..894a48d9f62 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -440,6 +440,8 @@ static void panel_draw(const bContext *C, Panel *panel) PointerRNA ob_ptr; modifier_panel_get_property_pointers(C, panel, &ob_ptr, &ptr); + PointerRNA obj_data_ptr = RNA_pointer_get(&ob_ptr, "data"); + PointerRNA texture_ptr = RNA_pointer_get(&ptr, "texture"); bool has_texture = !RNA_pointer_is_null(&texture_ptr); int texture_coords = RNA_enum_get(&ptr, "texture_coords"); @@ -467,7 +469,7 @@ static void panel_draw(const bContext *C, Panel *panel) } } else if (texture_coords == MOD_DISP_MAP_UV && RNA_enum_get(&ob_ptr, "type") == OB_MESH) { - uiItemR(col, &ptr, "uv_layer", 0, NULL, ICON_NONE); + uiItemPointerR(col, &ptr, "uv_layer", &obj_data_ptr, "uv_layers", NULL, ICON_NONE); } uiItemS(layout); |