diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2019-06-21 23:31:01 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2019-06-21 23:31:01 +0300 |
commit | 28428b346243bc72ba4c7bc842362cb1cbec38e8 (patch) | |
tree | 3f662976c6e5ccf2e5a991416328215ee1155e0c | |
parent | 24146563a01665dca292f16cc1385c23fcb53c82 (diff) | |
parent | ad4f5092ecaf919e415fec4ca62b0172293a2075 (diff) |
Merge branch 'master' into soc-2019-openxr
121 files changed, 2271 insertions, 1710 deletions
diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py index c1a49a756a0..f1880a70018 100644 --- a/doc/python_api/examples/bpy.types.Operator.5.py +++ b/doc/python_api/examples/bpy.types.Operator.5.py @@ -11,8 +11,8 @@ will not run. Modal operators are especially useful for interactive tools, an operator can have its own state where keys toggle options as the operator runs. Grab, Rotate, Scale, and Fly-Mode are examples of modal operators. -:class:`Operator.invoke` is used to initialize the operator as being by -returning ``{'RUNNING_MODAL'}``, initializing the modal loop. +:class:`Operator.invoke` is used to initialize the operator as being active +by returning ``{'RUNNING_MODAL'}``, initializing the modal loop. Notice ``__init__()`` and ``__del__()`` are declared. For other operator types they are not useful but for modal operators they will diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 92dc8a8a4c6..da43f94708c 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -91,16 +91,31 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_rende { memset((void *)bcam, 0, sizeof(BlenderCamera)); + bcam->nearclip = 1e-5f; + bcam->farclip = 1e5f; + bcam->type = CAMERA_PERSPECTIVE; + bcam->ortho_scale = 1.0f; + + bcam->lens = 50.0f; + bcam->shuttertime = 1.0f; + + bcam->rolling_shutter_type = Camera::ROLLING_SHUTTER_NONE; + bcam->rolling_shutter_duration = 0.1f; + + bcam->aperturesize = 0.0f; + bcam->apertureblades = 0; + bcam->aperturerotation = 0.0f; + bcam->focaldistance = 10.0f; + bcam->zoom = 1.0f; bcam->pixelaspect = make_float2(1.0f, 1.0f); + bcam->aperture_ratio = 1.0f; + bcam->sensor_width = 36.0f; bcam->sensor_height = 24.0f; bcam->sensor_fit = BlenderCamera::AUTO; - bcam->shuttertime = 1.0f; bcam->motion_position = Camera::MOTION_POSITION_CENTER; - bcam->rolling_shutter_type = Camera::ROLLING_SHUTTER_NONE; - bcam->rolling_shutter_duration = 0.1f; bcam->border.right = 1.0f; bcam->border.top = 1.0f; bcam->pano_viewplane.right = 1.0f; @@ -108,6 +123,7 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_rende bcam->viewport_camera_border.right = 1.0f; bcam->viewport_camera_border.top = 1.0f; bcam->offscreen_dicing_scale = 1.0f; + bcam->matrix = transform_identity(); /* render resolution */ bcam->full_width = render_resolution_x(b_render); diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index fc7daaeeaa6..4f79a7518dc 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -313,7 +313,9 @@ void Node::set_default_value(const SocketType &socket) { const void *src = socket.default_value; void *dst = ((char *)this) + socket.struct_offset; - memcpy(dst, src, socket.size()); + if (socket.size() > 0) { + memcpy(dst, src, socket.size()); + } } template<typename T> diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 08821ffa099..9196caad1b3 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -617,7 +617,7 @@ static bool get_primitive_attribute(KernelGlobals *kg, return set_attribute_float3(fval, type, derivatives, val); } else if (attr.type == TypeFloat2) { - float2 fval[2]; + float2 fval[3]; fval[0] = primitive_attribute_float2( kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); return set_attribute_float2(fval, type, derivatives, val); diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index baa3ce77f84..7591d9dda0c 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -118,6 +118,8 @@ NODE_DEFINE(Camera) stereo_eye_enum.insert("right", STEREO_RIGHT); SOCKET_ENUM(stereo_eye, "Stereo Eye", stereo_eye_enum, STEREO_NONE); + SOCKET_BOOLEAN(use_spherical_stereo, "Use Spherical Stereo", false); + SOCKET_FLOAT(interocular_distance, "Interocular Distance", 0.065f); SOCKET_FLOAT(convergence_distance, "Convergence Distance", 30.0f * 0.065f); diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 9203c4468d2..a56871779cf 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -130,6 +130,7 @@ ShaderOutput *ShaderNode::output(ustring name) void ShaderNode::remove_input(ShaderInput *input) { assert(input->link == NULL); + delete input; inputs.erase(remove(inputs.begin(), inputs.end(), input), inputs.end()); } diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index f1622493455..78b9ec03273 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -1222,6 +1222,8 @@ void MeshManager::update_osl_attributes(Device *device, 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 osl_attr.type = TypeDesc::TypeColor; @@ -1243,6 +1245,8 @@ void MeshManager::update_osl_attributes(Device *device, 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 osl_attr.type = TypeDesc::TypeColor; diff --git a/intern/cycles/util/util_array.h b/intern/cycles/util/util_array.h index 1d7e39344f6..db80ab474e0 100644 --- a/intern/cycles/util/util_array.h +++ b/intern/cycles/util/util_array.h @@ -63,7 +63,9 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra } else { data_ = mem_allocate(from.datasize_); - memcpy(data_, from.data_, from.datasize_ * sizeof(T)); + if (from.datasize_ > 0) { + memcpy(data_, from.data_, from.datasize_ * sizeof(T)); + } datasize_ = from.datasize_; capacity_ = datasize_; } @@ -73,7 +75,9 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra { if (this != &from) { resize(from.size()); - memcpy((void *)data_, from.data_, datasize_ * sizeof(T)); + if (datasize_ > 0) { + memcpy((void *)data_, from.data_, datasize_ * sizeof(T)); + } } return *this; @@ -83,7 +87,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra { resize(from.size()); - if (from.size() > 0) { + if (from.size() > 0 && datasize_ > 0) { memcpy(data_, &from[0], datasize_ * sizeof(T)); } @@ -100,6 +104,9 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra if (datasize_ != other.datasize_) { return false; } + if (datasize_ == 0) { + return true; + } return memcmp(data_, other.data_, datasize_ * sizeof(T)) == 0; } diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc index fa45c0119ec..198f985a233 100644 --- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc @@ -771,11 +771,8 @@ OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal( } #endif // Generate bi-cubic patch table for the limit surface. - // TODO(sergey): Ideally we would want to expose end-cap settings via - // C-API to make it more generic. Currently it matches old Blender's - // subsurf code. PatchTableFactory::Options patch_options(level); - patch_options.SetEndCapType(PatchTableFactory::Options::ENDCAP_BSPLINE_BASIS); + patch_options.SetEndCapType(PatchTableFactory::Options::ENDCAP_GREGORY_BASIS); patch_options.useInfSharpPatch = use_inf_sharp_patch; patch_options.generateFVarTables = has_face_varying_data; patch_options.generateFVarLegacyLinearPatches = false; diff --git a/release/darwin/README.txt b/release/darwin/README.txt new file mode 100644 index 00000000000..cb4c321f674 --- /dev/null +++ b/release/darwin/README.txt @@ -0,0 +1,34 @@ +Bundling guide: + +Have your signing identity ready, you can check it by running: + +$ secruity find-identity -v -p codesign + +Check that your appleID has two step verification and app specified password generated. https://support.apple.com/en-us/HT204397 +Add it to the login keychain so it won't be in cleartext. + +$ security add-generic-password -a "AC_USERNAME" -w <secret> -s "AC_PASSWORD" + +You need then to make sure altool can access your keychain. First time run, there is popup, always allow. Or you can also add it on Keychain Access. + +Then you can make neat bundle using ./bundle.sh by + +$ ./bundle.sh --source <sourcedir> --dmg <dmg> --bundle-id <bundleid> --username <username> --password <password> --codesign <identity> + +where: + +<sourcedir> directory where built blender.app is +<dmg> location and name of the final disk image +<bundleid> id on notarization, you choose (for example org.blender.release) +<username> your appleid +<password> your password. having it in keychain, use "@keychain:AC_PASSWORD" +<identity> codesigning identity + +Only --sourcedir and --dmg are required flags. + +Example : +$ ./bundle.sh --source /data/build --dmg /data/Blender-2.8-alpha-macOS-10.11.dmg --bundle-id org.blender.alpha --username "foo@mac.com" --password "@keychain:AC_PASSWORD" --codesign AE825E26F12D08B692F360133210AF46F4CF7B97 + + + + diff --git a/release/darwin/background.tif b/release/darwin/background.tif Binary files differnew file mode 100644 index 00000000000..d242268c008 --- /dev/null +++ b/release/darwin/background.tif diff --git a/release/darwin/blender.app/Contents/Info.plist b/release/darwin/blender.app/Contents/Info.plist index 92e8d8cc761..9b09ef0f768 100644 --- a/release/darwin/blender.app/Contents/Info.plist +++ b/release/darwin/blender.app/Contents/Info.plist @@ -44,7 +44,7 @@ <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}, Blender Foundation</string> + <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> <key>NSPrincipalClass</key> <string>NSApplication</string> <key>NSHighResolutionCapable</key> diff --git a/release/darwin/blender.applescript b/release/darwin/blender.applescript new file mode 100644 index 00000000000..130dc2eb64c --- /dev/null +++ b/release/darwin/blender.applescript @@ -0,0 +1,18 @@ +tell application "Finder" + tell disk "Blender" + open + set current view of container window to icon view + set toolbar visible of container window to false + set statusbar visible of container window to false + set the bounds of container window to {100, 100, 640, 472} + set theViewOptions to icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 128 + set background picture of theViewOptions to file ".background:background.tif" + set position of item " " of container window to {400, 190} + set position of item "blender.app" of container window to {135, 190} + update without registering applications + delay 5 + close + end tell +end tell diff --git a/release/darwin/blenderplayer.app/Contents/Info.plist b/release/darwin/blenderplayer.app/Contents/Info.plist deleted file mode 100644 index 91eb2d7e84d..00000000000 --- a/release/darwin/blenderplayer.app/Contents/Info.plist +++ /dev/null @@ -1,51 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleExecutable</key> - <string>blenderplayer</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleIconFile</key> - <string>blender player icon.icns</string> - <key>CFBundleName</key> - <string>BlenderPlayer</string> - <key>CFBundleIdentifier</key> - <string>org.blenderfoundation.blenderplayer</string> - <key>CFBundleVersion</key> - <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}, Blender Foundation</string> - <key>CFBundleShortVersionString</key> - <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> - <key>CFBundleGetInfoString</key> - <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}, Blender Foundation</string> - <key>CFBundleDocumentTypes</key> - <array> - <dict> - <key>CFBundleTypeIconFile</key> - <string>blender file icon.icns</string> - <key>CFBundleTypeName</key> - <string>Blender File</string> - <key>CFBundleTypeOSTypes</key> - <array> - <string>BLND</string> - </array> - <key>CFBundleTypeExtensions</key> - <array> - <string>blend</string> - </array> - <key>CFBundleTypeRole</key> - <string>Viewer</string> - <key>LSIsAppleDefaultForType</key> - <false/> - </dict> - </array> - <key>NSPrincipalClass</key> - <string>NSApplication</string> - <key>NSHighResolutionCapable</key> - <true/> -</dict> -</plist> diff --git a/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer b/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer deleted file mode 100644 index 48cdce85287..00000000000 --- a/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer +++ /dev/null @@ -1 +0,0 @@ -placeholder diff --git a/release/darwin/blenderplayer.app/Contents/PkgInfo b/release/darwin/blenderplayer.app/Contents/PkgInfo deleted file mode 100644 index bd04210fb49..00000000000 --- a/release/darwin/blenderplayer.app/Contents/PkgInfo +++ /dev/null @@ -1 +0,0 @@ -APPL????
\ No newline at end of file diff --git a/release/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns b/release/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns Binary files differdeleted file mode 100644 index 9065f1b359c..00000000000 --- a/release/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns +++ /dev/null diff --git a/release/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns b/release/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns Binary files differdeleted file mode 100644 index 5eef94afde9..00000000000 --- a/release/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns +++ /dev/null diff --git a/release/darwin/bundle.sh b/release/darwin/bundle.sh new file mode 100755 index 00000000000..b61238dc620 --- /dev/null +++ b/release/darwin/bundle.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env bash + +# create blender distribution dmg + +# check that we have all needed tools + +for i in osascript git codesign hdiutil xcrun ; do + if [ ! -x "$(which ${i})" ]; then + echo "Unable to execute command $i, macOS broken?" + exit 1 + fi +done + +# some defaults settings + +_scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +_volname="Blender" +_tmpdir="$(mktemp -d)" +_tmpdmg="/tmp/blender-tmp.dmg" +BACKGROUND_IMAGE="${_scriptdir}/background.tif" +MOUNT_DIR="/Volumes/${_volname}" + +# handle arguments + +while [[ $# -gt 0 ]]; do + key=$1 + case $key in + -s|--source) + SRC_DIR="$2" + shift + shift + ;; + -d|--dmg) + DEST_DMG="$2" + shift + shift + ;; + -b|--bundle-id) + N_BUNDLE_ID="$2" + shift + shift + ;; + -u|--username) + N_USERNAME="$2" + shift + shift + ;; + -p|--password) + N_PASSWORD="$2" + shift + shift + ;; + -c|--codesign) + C_CERT="$2" + shift + shift + ;; + -h|--help) + echo "Usage:" + echo " $(basename "$0") --source DIR --dmg IMAGENAME " + echo " optional arguments:" + echo " --codesign <certname>" + echo " --username <username>" + echo " --password <password>" + echo " --bundle-id <bundleid>" + echo " Check https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/customizing_the_notarization_workflow " + exit 1 + ;; + esac +done + +if [ ! -d "${SRC_DIR}/blender.app" ]; then + echo "use --source parameter to set source directory where blender.app can be found" + exit 1 +fi + +if [ -z "${DEST_DMG}" ]; then + echo "use --dmg parameter to set output dmg name" + exit 1 +fi + +# destroy destination dmg if there is any. be warned. + +test -f "${DEST_DMG}" && rm "${DEST_DMG}" +if [ -d "${MOUNT_DIR}" ]; then + echo -n "Ejecting existing blender volume.." + DEV_FILE=$(mount | grep "${MOUNT_DIR}" | awk '{ print $1 }') + diskutil eject "${DEV_FILE}" || exit 1 + echo +fi + +# let's go. + +echo -n "Copying blender.app..." +cp -r "${SRC_DIR}/blender.app" "${_tmpdir}/" || exit 1 +echo + +# Create the disk image + +_ds=$(du -sh ${_tmpdir} | awk -F'[^0-9]*' '$0=$1') # directory size +_is=$(echo "${_ds}" + 200 | bc) # image size with extra 200 ! (why on earth!) for codesign to work +echo +echo -n "Creating disk image of size ${_is}M.." +test -f "${_tmpdmg}" && rm "${_tmpdmg}" +hdiutil create -size "${_is}m" -fs HFS+ -srcfolder "${_tmpdir}" -volname "${_volname}" -format UDRW "${_tmpdmg}" + +echo "Mounting readwrite image..." +hdiutil attach -readwrite -noverify -noautoopen "${_tmpdmg}" + +echo "Setting background picture.." +if ! test -z "${BACKGROUND_IMAGE}"; then + echo "Copying background image ..." + test -d "${MOUNT_DIR}/.background" || mkdir "${MOUNT_DIR}/.background" + BACKGROUND_IMAGE_NAME=$(basename "${BACKGROUND_IMAGE}") + cp "${BACKGROUND_IMAGE}" "${MOUNT_DIR}/.background/${BACKGROUND_IMAGE_NAME}" +fi + +# echo "Creating link to /Applications ..." +ln -s /Applications "${MOUNT_DIR}/Applications" +echo "Renaming Applications to empty string." +mv ${MOUNT_DIR}/Applications "${MOUNT_DIR}/ " + +echo "Running applescript to set folder looks ..." +cat "${_scriptdir}/blender.applescript" | osascript + +echo "Waiting after applescript ..." +sleep 5 + +if [ ! -z "${C_CERT}" ]; then + # codesigning seems to be thingie. all libs and binaries need to be + # signed separately. todo: use some find magic to find those + echo -n "Codesigning..." + codesign --timestamp --options runtime --sign "${C_CERT}" "${MOUNT_DIR}/blender.app/Contents/Resources/2.80/python/bin/python3.7m" + codesign --timestamp --options runtime --sign "${C_CERT}" "${MOUNT_DIR}/blender.app/Contents/Resources/2.80/python/lib/python3.7/site-packages/libextern_draco.dylib" + codesign --timestamp --options runtime --sign "${C_CERT}" "${MOUNT_DIR}/blender.app/Contents/Resources/lib/libomp.dylib" + codesign --timestamp --options runtime --sign "${C_CERT}" "${MOUNT_DIR}/blender.app" + echo +else + echo "No codesigning cert given, skipping..." +fi + + +echo "Unmounting rw disk image ..." +# need to eject dev files to remove /dev files and free .dmg for converting +DEV_FILE=$(mount | grep "${MOUNT_DIR}" | awk '{ print $1 }') +diskutil eject "${DEV_FILE}" + +sleep 3 + +echo "Compressing disk image ..." +hdiutil convert "${_tmpdmg}" -format UDZO -o "${DEST_DMG}" + +# codesign the dmg + +if [ ! -z "${C_CERT}" ]; then + echo -n "Codesigning dmg..." + codesign --timestamp --force --sign "${C_CERT}" "${DEST_DMG}" + echo +fi + +# cleanup + +rm -rf "${_tmpdir}" +rm "${_tmpdmg}" + +# send notarization +if [ ! -z "${N_USERNAME}" ] && [ ! -z "${N_PASSWORD}" ] && [ ! -z "${N_BUNDLE_ID}" ]; then + echo -n "Sending ${DEST_DMG} for notarization..." + _tmpout=$(mktemp) + xcrun altool --notarize-app -f "${DEST_DMG}" --primary-bundle-id "${N_BUNDLE_ID}" --username "${N_USERNAME}" --password "${N_PASSWORD}" >${_tmpout} 2>&1 + + # check the request uuid + + _requuid=$(cat "${_tmpout}" | grep "RequestUUID" | awk '{ print $3 }') + echo "RequestUUID: ${_requuid}" + if [ ! -z "${_requuid}" ]; then + echo "Waiting for notarization to be complete.." + for c in {20..0};do + sleep 600 + xcrun altool --notarization-info "${_requuid}" --username "${N_USERNAME}" --password "${N_PASSWORD}" >${_tmpout} 2>&1 + _status=$(cat "${_tmpout}" | grep "Status:" | awk '{ print $2 }') + if [ "${_status}" == "invalid" ]; then + echo "Got invalid notarization!" + break; + fi + + if [ "${_status}" == "success" ]; then + echo -n "Notarization successful! Stapling..." + xcrun stapler staple -v "${DEST_DMG}" + break; + fi + echo "Notarization in progress, waiting..." + done + else + echo "Error getting RequestUUID, notarization unsuccessful" + fi +else + echo "No notarization credentials supplied, skipping..." +fi + +echo "..done. You should have ${DEST_DMG} ready to upload" diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 3ff296d0be9..70768a102b3 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -342,8 +342,8 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non # Split registering up into 3 steps so we can undo # if it fails par way through. - # disable the context, using the context at all is - # really bad while loading an addon, don't do it! + # Disable the context: using the context at all + # while loading an addon is really bad, don't do it! with RestrictBlend(): # 1) try import @@ -362,16 +362,16 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non _addon_remove(module_name) return None - # 1.1) fail when add-on is too old + # 1.1) Fail when add-on is too old. # This is a temporary 2.8x migration check, so we can manage addons that are supported. if mod.bl_info.get("blender", (0, 0, 0)) < (2, 80, 0): if _bpy.app.debug: - print(f"Warning: Add-on '{module_name:s}' has not been upgraded to 2.8, ignoring") + print(f"Warning: Add-on '{module_name:s}' was not upgraded for 2.80, ignoring") return None - # 2) try register collected modules - # removed, addons need to handle own registration now. + # 2) Try register collected modules. + # Removed register_module, addons need to handle their own registration now. use_owner = mod.bl_info.get("use_owner", True) if use_owner: @@ -379,7 +379,7 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non owner_id_prev = _bl_owner_id_get() _bl_owner_id_set(module_name) - # 3) try run the modules register function + # 3) Try run the modules register function. try: mod.register() except Exception as ex: diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index c96b0b88c6b..e6424de0742 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -450,12 +450,12 @@ def preset_paths(subdir): return dirs -def smpte_from_seconds(time, fps=None): +def smpte_from_seconds(time, fps=None, fps_base=None): """ Returns an SMPTE formatted string from the *time*: ``HH:MM:SS:FF``. - If the *fps* is not given the current scene is used. + If *fps* and *fps_base* are not given the current scene is used. :arg time: time in seconds. :type time: int, float or ``datetime.timedelta``. @@ -463,7 +463,11 @@ def smpte_from_seconds(time, fps=None): :rtype: string """ - return smpte_from_frame(time_to_frame(time, fps=fps), fps) + return smpte_from_frame( + time_to_frame(time, fps=fps, fps_base=fps_base), + fps=fps, + fps_base=fps_base + ) def smpte_from_frame(frame, fps=None, fps_base=None): @@ -485,8 +489,9 @@ def smpte_from_frame(frame, fps=None, fps_base=None): if fps_base is None: fps_base = _bpy.context.scene.render.fps_base + fps = fps / fps_base sign = "-" if frame < 0 else "" - frame = abs(frame * fps_base) + frame = abs(frame) return ( "%s%02d:%02d:%02d:%02d" % ( @@ -516,9 +521,11 @@ def time_from_frame(frame, fps=None, fps_base=None): if fps_base is None: fps_base = _bpy.context.scene.render.fps_base + fps = fps / fps_base + from datetime import timedelta - return timedelta(0, (frame * fps_base) / fps) + return timedelta(0, frame / fps) def time_to_frame(time, fps=None, fps_base=None): @@ -540,12 +547,14 @@ def time_to_frame(time, fps=None, fps_base=None): if fps_base is None: fps_base = _bpy.context.scene.render.fps_base + fps = fps / fps_base + from datetime import timedelta if isinstance(time, timedelta): time = time.total_seconds() - return (time / fps_base) * fps + return time * fps def preset_find(name, preset_path, display_name=False, ext=".py"): diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index dd6c33934df..104994d0ee5 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -1078,7 +1078,7 @@ def km_view3d(params): items.extend([ op_menu_pie("VIEW3D_MT_snap_pie", {"type": 'S', "value": 'PRESS', "shift": True}), ("wm.context_toggle", {"type": 'ACCENT_GRAVE', "value": 'PRESS', "ctrl": True}, - {"properties": [("data_path", 'space_data.show_gizmo_context')]}), + {"properties": [("data_path", 'space_data.show_gizmo')]}), op_menu_pie("VIEW3D_MT_pivot_pie", {"type": 'PERIOD', "value": 'PRESS'}), op_menu_pie("VIEW3D_MT_orientations_pie", {"type": 'COMMA', "value": 'PRESS'}), op_menu_pie( diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index 0a070118069..cbd7e877a75 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -2720,16 +2720,14 @@ def km_curve(params): items.extend([ - ("curve.handle_type_set", {"type": 'V', "value": 'PRESS'}, None), - ("curve.vertex_add", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True}, None), - ("curve.select_all", {"type": 'A', "value": 'CLICK', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("curve.select_all", {"type": 'A', "value": 'CLICK', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), - ("curve.select_all", {"type": 'I', "value": 'CLICK', "ctrl": True}, {"properties": [("action", 'INVERT')]}), + ("curve.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), + ("curve.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("curve.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("curve.select_row", {"type": 'R', "value": 'PRESS', "shift": True}, None), ("curve.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), ("curve.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), ("curve.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), - ("curve.shortest_path_pick", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True, "shift": True}, None), + ("curve.shortest_path_pick", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True, "shift": True}, None), ("curve.duplicate_move", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), op_menu("VIEW3D_MT_edit_curve_delete", {"type": 'BACK_SPACE', "value": 'PRESS'}), op_menu("VIEW3D_MT_edit_curve_delete", {"type": 'DEL', "value": 'PRESS'}), diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index 28324891c53..93a022e6c3e 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -126,7 +126,7 @@ class SelectCamera(Operator): extend: BoolProperty( name="Extend", description="Extend the selection", - default=False + default=False, ) def execute(self, context): @@ -887,7 +887,7 @@ class LoadImageAsEmpty: view_align: BoolProperty( name="Align to view", - default=True + default=True, ) @classmethod diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 451d7b5a427..097b93ea9ca 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -436,7 +436,7 @@ class AddPresetTrackingCamera(AddPresetBase, Operator): name="Include Focal Length", description="Include focal length into the preset", options={'SKIP_SAVE'}, - default=True + default=True, ) @property diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py index 910fe4d3b2d..706afc6dcf8 100644 --- a/release/scripts/startup/bl_operators/userpref.py +++ b/release/scripts/startup/bl_operators/userpref.py @@ -968,7 +968,7 @@ class PREFERENCES_OT_studiolight_install(Operator): class PREFERENCES_OT_studiolight_new(Operator): """Save custom studio light from the studio light editor settings""" bl_idname = "preferences.studiolight_new" - bl_label = "Save custom Studio light" + bl_label = "Save Custom Studio Light" filename: StringProperty( name="Name", diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index b5cb5024ad0..2b20754a995 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -233,15 +233,16 @@ class prettyface: return self.width, self.height -def lightmap_uvpack(meshes, - PREF_SEL_ONLY=True, - PREF_NEW_UVLAYER=False, - PREF_PACK_IN_ONE=False, - PREF_APPLY_IMAGE=False, - PREF_IMG_PX_SIZE=512, - PREF_BOX_DIV=8, - PREF_MARGIN_DIV=512 - ): +def lightmap_uvpack( + meshes, + PREF_SEL_ONLY=True, + PREF_NEW_UVLAYER=False, + PREF_PACK_IN_ONE=False, + PREF_APPLY_IMAGE=False, + PREF_IMG_PX_SIZE=512, + PREF_BOX_DIV=8, + PREF_MARGIN_DIV=512, +): """ BOX_DIV if the maximum division of the UV map that a box may be consolidated into. diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index 321c4d76ef3..fdf74c420a9 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -1011,7 +1011,7 @@ class SmartProject(Operator): use_aspect: BoolProperty( name="Correct Aspect", description="Map UVs taking image aspect ratio into account", - default=True + default=True, ) stretch_to_bounds: BoolProperty( name="Stretch to UV Bounds", @@ -1029,8 +1029,8 @@ class SmartProject(Operator): self.angle_limit, self.user_area_weight, self.use_aspect, - self.stretch_to_bounds - ) + self.stretch_to_bounds, + ) return {'FINISHED'} def invoke(self, context, _event): diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index c7e2b78d872..3920ff95a9e 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1320,7 +1320,7 @@ class WM_OT_properties_edit(Operator): row = layout.row() row.prop(self, "use_soft_limits") - if bpy.app.use_library_override: + if bpy.app.use_override_library: row.prop(self, "is_overridable_library") row = layout.row(align=True) diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py index 872b51d51ff..fd8ca542f9f 100644 --- a/release/scripts/startup/bl_ui/properties_mask_common.py +++ b/release/scripts/startup/bl_ui/properties_mask_common.py @@ -239,7 +239,6 @@ class MASK_PT_transforms: # ~ bl_region_type = 'TOOLS' bl_label = "Transforms" bl_category = "Mask" - bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -257,6 +256,40 @@ class MASK_PT_transforms: col.operator("transform.transform", text="Scale Feather").mode = 'MASK_SHRINKFATTEN' +class MASK_PT_tools: + bl_label = "Mask Tools" + bl_category = "Mask" + + @classmethod + def poll(cls, context): + space_data = context.space_data + return space_data.mask and space_data.mode == 'MASK' + + def draw(self, _context): + layout = self.layout + + col = layout.column(align=True) + col.label(text="Spline:") + col.operator("mask.delete") + col.operator("mask.cyclic_toggle") + col.operator("mask.switch_direction") + col.operator("mask.handle_type_set").type = 'VECTOR' + col.operator("mask.feather_weight_clear") + + col = layout.column(align=True) + col.label(text="Parenting:") + row = col.row(align=True) + row.operator("mask.parent_set", text="Parent") + row.operator("mask.parent_clear", text="Clear") + + col = layout.column(align=True) + col.label(text="Animation:") + row = col.row(align=True) + row.operator("mask.shape_key_insert", text="Insert Key") + row.operator("mask.shape_key_clear", text="Clear Key") + col.operator("mask.shape_key_feather_reset", text="Reset Feather Animation") + col.operator("mask.shape_key_rekey", text="Re-Key Shape Points") + class MASK_MT_add(Menu): bl_label = "Add" diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 946760c3bd0..9dbe11b0c70 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -135,7 +135,7 @@ def point_cache_ui(self, cache, enabled, cachetype): row = layout.row() row.template_list( "UI_UL_list", "point_caches", cache, "point_caches", - cache.point_caches, "active_index", rows=1 + cache.point_caches, "active_index", rows=1, ) col = row.column(align=True) col.operator("ptcache.add", icon='ADD', text="") diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index 2b8e488cbe9..7e4f9e8370f 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -150,7 +150,7 @@ class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel): row = layout.row() row.template_list( "PHYSICS_UL_dynapaint_surfaces", "", canvas, "canvas_surfaces", - canvas.canvas_surfaces, "active_index", rows=1 + canvas.canvas_surfaces, "active_index", rows=1, ) col = row.column(align=True) @@ -163,7 +163,7 @@ class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel): if surface: flow = layout.grid_flow( - row_major=True, columns=0, even_columns=True, even_rows=False, align=False + row_major=True, columns=0, even_columns=True, even_rows=False, align=False, ) col = flow.column() @@ -191,7 +191,7 @@ class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel): layout.use_property_split = True flow = layout.grid_flow( - row_major=True, columns=0, even_columns=True, even_rows=False, align=False + row_major=True, columns=0, even_columns=True, even_rows=False, align=False, ) col = flow.column() col.prop(brush, "paint_color") diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index d138615e9be..f653f8f738f 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -465,17 +465,17 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel): row = layout.row(align=True) row.label(text="Track:") - props = row.operator("clip.track_markers", text="", icon='FRAME_PREV') + props = row.operator("clip.track_markers", text="", icon='TRACKING_BACKWARDS_SINGLE') props.backwards = True props.sequence = False props = row.operator("clip.track_markers", text="", - icon='PLAY_REVERSE') + icon='TRACKING_BACKWARDS') props.backwards = True props.sequence = True - props = row.operator("clip.track_markers", text="", icon='PLAY') + props = row.operator("clip.track_markers", text="", icon='TRACKING_FORWARDS') props.backwards = False props.sequence = True - props = row.operator("clip.track_markers", text="", icon='FRAME_NEXT') + props = row.operator("clip.track_markers", text="", icon='TRACKING_FORWARDS_SINGLE') props.backwards = False props.sequence = False @@ -484,10 +484,10 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel): row.label(text="Clear:") row.scale_x = 2.0 - props = row.operator("clip.clear_track_path", text="", icon='BACK') + props = row.operator("clip.clear_track_path", text="", icon='TRACKING_CLEAR_BACKWARDS') props.action = 'UPTO' - props = row.operator("clip.clear_track_path", text="", icon='FORWARD') + props = row.operator("clip.clear_track_path", text="", icon='TRACKING_CLEAR_FORWARDS') props.action = 'REMAINED' col = layout.column() @@ -495,10 +495,10 @@ class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel): row.label(text="Refine:") row.scale_x = 2.0 - props = row.operator("clip.refine_markers", text="", icon='LOOP_BACK') + props = row.operator("clip.refine_markers", text="", icon='TRACKING_REFINE_BACKWARDS') props.backwards = True - props = row.operator("clip.refine_markers", text="", icon='LOOP_FORWARDS') + props = row.operator("clip.refine_markers", text="", icon='TRACKING_REFINE_FORWARDS') props.backwards = False col = layout.column(align=True) @@ -1113,6 +1113,7 @@ from bl_ui.properties_mask_common import ( MASK_PT_point, MASK_PT_display, MASK_PT_transforms, + MASK_PT_tools ) @@ -1151,6 +1152,10 @@ class CLIP_PT_tools_mask_transforms(MASK_PT_transforms, Panel): bl_region_type = 'TOOLS' bl_category = "Mask" +class CLIP_PT_tools_mask_tools(MASK_PT_tools, Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_category = "Mask" # --- end mask --- @@ -1226,6 +1231,7 @@ class CLIP_MT_view(Menu): layout.prop(sc, "show_region_ui") layout.prop(sc, "show_region_toolbar") layout.prop(sc, "show_region_hud") + layout.prop(sc, "show_region_tool_header") layout.separator() @@ -1421,9 +1427,16 @@ class CLIP_MT_select_grouped(Menu): layout.operator_enum("clip.select_grouped", "group") +class CLIP_MT_mask_handle_type_menu(Menu): + bl_label = "Set Handle Type" + + def draw(self, _context): + layout = self.layout + + layout.operator_enum("mask.handle_type_set", "type") class CLIP_MT_tracking_context_menu(Menu): - bl_label = "Specials" + bl_label = "Context Menu" @classmethod def poll(cls, context): @@ -1432,25 +1445,73 @@ class CLIP_MT_tracking_context_menu(Menu): def draw(self, _context): layout = self.layout - layout.operator("clip.disable_markers", - text="Enable Markers").action = 'ENABLE' + mode = _context.space_data.mode - layout.operator("clip.disable_markers", - text="Disable Markers").action = 'DISABLE' + if mode == 'TRACKING': - layout.separator() - layout.operator("clip.set_origin") + layout.operator("clip.track_settings_to_track") + layout.operator("clip.track_settings_as_default") - layout.separator() - layout.operator("clip.hide_tracks") - layout.operator("clip.hide_tracks_clear", text="Show Tracks") + layout.separator() - layout.separator() - layout.operator("clip.lock_tracks", text="Lock Tracks").action = 'LOCK' + layout.operator("clip.track_copy_color") + + layout.separator() + + layout.operator("clip.copy_tracks", icon='COPYDOWN') + layout.operator("clip.paste_tracks", icon='PASTEDOWN') + + layout.separator() + + layout.operator("clip.disable_markers", + text="Disable Markers").action = 'DISABLE' + layout.operator("clip.disable_markers", + text="Enable Markers").action = 'ENABLE' + + layout.separator() + + layout.operator("clip.hide_tracks") + layout.operator("clip.hide_tracks_clear", text="Show Tracks") - layout.operator("clip.lock_tracks", - text="Unlock Tracks").action = 'UNLOCK' + layout.separator() + + layout.operator("clip.lock_tracks", text="Lock Tracks").action = 'LOCK' + layout.operator("clip.lock_tracks", + text="Unlock Tracks").action = 'UNLOCK' + + layout.separator() + + layout.operator("clip.join_tracks") + + layout.separator() + + layout.operator("clip.delete_track") + + elif mode == 'MASK': + + layout.menu("CLIP_MT_mask_handle_type_menu") + layout.operator("mask.switch_direction") + layout.operator("mask.cyclic_toggle") + + layout.separator() + + layout.operator("mask.copy_splines", icon='COPYDOWN') + layout.operator("mask.paste_splines", icon='PASTEDOWN') + + layout.separator() + + layout.operator("mask.shape_key_rekey", text="Re-key Shape Points") + layout.operator("mask.feather_weight_clear") + layout.operator("mask.shape_key_feather_reset", text="Reset Feather Animation") + + layout.separator() + + layout.operator("mask.parent_set") + layout.operator("mask.parent_clear") + + layout.separator() + layout.operator("mask.delete") class CLIP_PT_camera_presets(PresetPanel, Panel): """Predefined tracking camera intrinsics""" @@ -1696,6 +1757,7 @@ classes = ( CLIP_PT_active_mask_spline, CLIP_PT_active_mask_point, CLIP_PT_tools_mask_transforms, + CLIP_PT_tools_mask_tools, CLIP_PT_tools_scenesetup, CLIP_PT_grease_pencil, CLIP_PT_tools_grease_pencil_draw, @@ -1717,7 +1779,8 @@ classes = ( CLIP_MT_marker_pie, CLIP_MT_tracking_pie, CLIP_MT_reconstruction_pie, - CLIP_MT_solving_pie + CLIP_MT_solving_pie, + CLIP_MT_mask_handle_type_menu ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index eb9964bb180..b939586ff81 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -250,6 +250,11 @@ class FILEBROWSER_MT_view(Menu): st = context.space_data params = st.params + layout.prop(st, "show_region_toolbar") + layout.prop(st, "show_region_ui", text="File Path") + + layout.separator() + layout.prop_menu_enum(params, "display_size") layout.prop_menu_enum(params, "recursion_level") diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 1a0bc03dd38..2aba440bf1d 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -952,7 +952,7 @@ class IMAGE_PT_render_slots(Panel): col = row.column() col.template_list( "IMAGE_UL_render_slots", "render_slots", ima, - "render_slots", ima.render_slots, "active_index", rows=3 + "render_slots", ima.render_slots, "active_index", rows=3, ) col = row.column(align=True) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 41a5e496a66..896a1e2eae6 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -106,8 +106,6 @@ class SEQUENCER_HT_header(Header): layout.separator_spacer() - layout.template_running_jobs() - if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}: layout.separator() layout.operator("sequencer.refresh_all", icon='FILE_REFRESH', text="") @@ -808,26 +806,24 @@ class SequencerButtonsPanel_Output: return cls.has_preview(context) -class SEQUENCER_PT_info(SequencerButtonsPanel, Panel): - bl_label = "Info" - bl_options = {'DEFAULT_CLOSED'} +class SEQUENCER_PT_strip(SequencerButtonsPanel, Panel): + bl_label = "" + bl_options = {'HIDE_HEADER'} bl_category = "Strip" def draw(self, context): layout = self.layout - layout.use_property_split = True - layout.use_property_decorate = False - strip = act_strip(context) - row = layout.row(align=True) - row.prop(strip, "name", text=strip.type.title()) - row.prop(strip, "lock", toggle=True, icon_only=True) + row = layout.row() + row.label(text="", icon='SEQ_SEQUENCER') + row.prop(strip, "name", text="") + row.prop(strip, "mute", toggle=True, icon_only=True, emboss=False) -class SEQUENCER_PT_adjust_offset(SequencerButtonsPanel, Panel): +class SEQUENCER_PT_adjust_transform_offset(SequencerButtonsPanel, Panel): bl_label = "Offset" - bl_parent_id = "SEQUENCER_PT_adjust" + bl_parent_id = "SEQUENCER_PT_adjust_transform" bl_options = {'DEFAULT_CLOSED'} bl_category = "Strip" @@ -844,17 +840,17 @@ class SEQUENCER_PT_adjust_offset(SequencerButtonsPanel, Panel): strip = act_strip(context) layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False + + layout.active = strip.use_translation and (not strip.mute) col = layout.column(align=True) col.prop(strip.transform, "offset_x", text="Position X") - col.prop(strip.transform, "offset_y", text="Position Y") - col.active = strip.use_translation + col.prop(strip.transform, "offset_y", text="Y") -class SEQUENCER_PT_adjust_crop(SequencerButtonsPanel, Panel): +class SEQUENCER_PT_adjust_transform_crop(SequencerButtonsPanel, Panel): bl_label = "Crop" - bl_parent_id = "SEQUENCER_PT_adjust" + bl_parent_id = "SEQUENCER_PT_adjust_transform" bl_options = {'DEFAULT_CLOSED'} bl_category = "Strip" @@ -871,14 +867,14 @@ class SEQUENCER_PT_adjust_crop(SequencerButtonsPanel, Panel): strip = act_strip(context) layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False + + layout.active = strip.use_crop and (not strip.mute) col = layout.column(align=True) col.prop(strip.crop, "min_x") col.prop(strip.crop, "max_x") col.prop(strip.crop, "max_y") col.prop(strip.crop, "min_y") - col.active = strip.use_crop class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): @@ -904,10 +900,11 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False strip = act_strip(context) + layout.active = not strip.mute + if strip.input_count > 0: col = layout.column() col.enabled = False @@ -951,29 +948,28 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): layout.prop(strip, "use_scale_to_length") elif strip.type == 'TRANSFORM': - layout = self.layout col = layout.column() col.prop(strip, "interpolation") col.prop(strip, "translation_unit") - layout = layout.column(align=True) - layout.prop(strip, "translate_start_x", text="Position X") - layout.prop(strip, "translate_start_y", text="Y") + col = layout.column(align=True) + col.prop(strip, "translate_start_x", text="Position X") + col.prop(strip, "translate_start_y", text="Y") - layout.separator() + col.separator() - col = layout.column(align=True) - col.prop(strip, "use_uniform_scale") + colsub = col.column(align=True) + colsub.prop(strip, "use_uniform_scale") if strip.use_uniform_scale: - col = layout.column(align=True) - col.prop(strip, "scale_start_x", text="Scale") + colsub = col.column(align=True) + colsub.prop(strip, "scale_start_x", text="Scale") else: - layout.prop(strip, "scale_start_x", text="Scale X") - layout.prop(strip, "scale_start_y", text="Y") + col.prop(strip, "scale_start_x", text="Scale X") + col.prop(strip, "scale_start_y", text="Y") - layout.separator() + col.separator() - layout.prop(strip, "rotation_start", text="Rotation") + col.prop(strip, "rotation_start", text="Rotation") elif strip.type == 'MULTICAM': col = layout.column(align=True) @@ -1038,18 +1034,17 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): if not strip.use_default_fade: col.prop(strip, "effect_fader", text="Effect Fader") elif strip.type == 'GAUSSIAN_BLUR': - layout = layout.column(align=True) - layout.prop(strip, "size_x", text="Size X") - layout.prop(strip, "size_y", text="Y") + col = layout.column(align=True) + col.prop(strip, "size_x", text="Size X") + col.prop(strip, "size_y", text="Y") elif strip.type == 'COLORMIX': layout.prop(strip, "blend_effect", text="Blend Mode") row = layout.row(align=True) row.prop(strip, "factor", slider=True) -class SEQUENCER_PT_info_input(SequencerButtonsPanel, Panel): - bl_label = "Input" - bl_parent_id = "SEQUENCER_PT_info" +class SEQUENCER_PT_source(SequencerButtonsPanel, Panel): + bl_label = "Source" bl_options = {'DEFAULT_CLOSED'} bl_category = "Strip" @@ -1064,12 +1059,6 @@ class SEQUENCER_PT_info_input(SequencerButtonsPanel, Panel): return strip.type in {'MOVIE', 'IMAGE', 'SOUND'} - ''', 'SCENE', 'MOVIECLIP', 'META', - 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', - 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', - 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', - 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX' }''' - def draw(self, context): layout = self.layout layout.use_property_split = True @@ -1079,9 +1068,12 @@ class SEQUENCER_PT_info_input(SequencerButtonsPanel, Panel): strip = act_strip(context) seq_type = strip.type + layout.active = not strip.mute + # draw a filename if we have one if seq_type == 'IMAGE': - layout.prop(strip, "directory", text="") + col = layout.column() + col.prop(strip, "directory", text="") # Current element for the filename @@ -1089,31 +1081,31 @@ class SEQUENCER_PT_info_input(SequencerButtonsPanel, Panel): if elem: layout.prop(elem, "filename", text="") # strip.elements[0] could be a fallback - layout.prop(strip.colorspace_settings, "name", text="Color Space") + col.prop(strip.colorspace_settings, "name", text="Color Space") - layout.prop(strip, "alpha_mode", text="Alpha") - sub = layout.column(align=True) + col.prop(strip, "alpha_mode", text="Alpha") + sub = col.column(align=True) sub.operator("sequencer.change_path", text="Change Data/Files", icon='FILEBROWSER').filter_image = True elif seq_type == 'MOVIE': - layout.prop(strip, "filepath", text="") - layout.prop(strip.colorspace_settings, "name", text="Color Space") - - layout.prop(strip, "mpeg_preseek") - layout.prop(strip, "stream_index") + col = layout.column() + col.prop(strip, "filepath", text="") + col.prop(strip.colorspace_settings, "name", text="Color Space") + col.prop(strip, "mpeg_preseek") + col.prop(strip, "stream_index") + col.prop(strip, "use_deinterlace") elif seq_type == 'SOUND': sound = strip.sound layout.template_ID(strip, "sound", open="sound.open") if sound is not None: - layout.prop(sound, "filepath", text="") - layout.use_property_split = True - layout.use_property_decorate = False + col = layout.column() + col.prop(sound, "filepath", text="") - layout.alignment = 'RIGHT' - sub = layout.column(align=True) + col.alignment = 'RIGHT' + sub = col.column(align=True) split = sub.split(factor=0.5, align=True) split.alignment = 'RIGHT' if sound.packed_file: @@ -1137,6 +1129,27 @@ class SEQUENCER_PT_info_input(SequencerButtonsPanel, Panel): box.active = strip.views_format == 'STEREO_3D' box.template_image_stereo_3d(strip.stereo_3d_format) + if strip.type == 'IMAGE': + # Alreay set above. + # elem = strip.strip_elem_from_frame(scene.frame_current) + pass + elif strip.type == 'MOVIE': + elem = strip.elements[0] + else: + elem = None + + if strip.type != 'SOUND': + col = layout.column(align=True) + col = col.box() + split = col.split(factor=0.5, align=False) + split.alignment = 'RIGHT' + split.label(text="Resolution") + if elem and elem.orig_width > 0 and elem.orig_height > 0: + split.alignment = 'LEFT' + split.label(text="%dx%d" % (elem.orig_width, elem.orig_height), translate=False) + else: + split.label(text="None") + class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel): bl_label = "Sound" @@ -1157,11 +1170,12 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False strip = act_strip(context) sound = strip.sound + layout.active = not strip.mute + layout.template_ID(strip, "sound", open="sound.open") if sound is not None: layout.prop(sound, "filepath", text="") @@ -1205,25 +1219,26 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel): strip = act_strip(context) + layout.active = not strip.mute + layout.template_ID(strip, "scene") scene = strip.scene - layout.prop(strip, "use_sequence") + layout.prop(strip, "scene_input") if scene: layout.prop(scene, "audio_volume", text="Volume") - if not strip.use_sequence: + if strip.scene_input == '3D_CAMERA': layout.alignment = 'RIGHT' sub = layout.column(align=True) split = sub.split(factor=0.5, align=True) split.alignment = 'RIGHT' - split.label(text="Camera Override") + split.label(text="Camera") split.template_ID(strip, "scene_camera") layout.prop(strip, "use_grease_pencil", text="Show Grease Pencil") - if not strip.use_sequence: if scene: # Warning, this is not a good convention to follow. # Expose here because setting the alpha from the 'Render' menu is very inconvenient. @@ -1249,10 +1264,11 @@ class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False strip = act_strip(context) + layout.active = not strip.mute + layout.template_ID(strip, "mask") mask = strip.mask @@ -1263,10 +1279,10 @@ class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel): layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False) -class SEQUENCER_PT_info_timecodes(SequencerButtonsPanel, Panel): - bl_label = "Timecodes" +class SEQUENCER_PT_time(SequencerButtonsPanel, Panel): + bl_label = "Time" + bl_options = {'DEFAULT_CLOSED'} bl_category = "Strip" - bl_parent_id = "SEQUENCER_PT_info" @classmethod def poll(cls, context): @@ -1279,7 +1295,16 @@ class SEQUENCER_PT_info_timecodes(SequencerButtonsPanel, Panel): return strip.type + def draw_header_preset(self, context): + layout = self.layout + layout.alignment = 'RIGHT' + strip = act_strip(context) + + layout.prop(strip, "lock", text="", icon_only=True, emboss=False) + def draw(self, context): + from bpy.utils import smpte_from_frame + layout = self.layout layout.use_property_split = False layout.use_property_decorate = False @@ -1305,29 +1330,30 @@ class SEQUENCER_PT_info_timecodes(SequencerButtonsPanel, Panel): max_length = max(len(x) for x in length_list) max_factor = (1.9 - max_length) / 30 + layout.enabled = not strip.lock + layout.active = not strip.mute + sub = layout.row(align=True) - sub.enabled = not strip.lock split = sub.split(factor=0.5 + max_factor) split.alignment = 'RIGHT' split.label(text='Channel') split.prop(strip, "channel", text="") sub = layout.column(align=True) - sub.enabled = not strip.lock split = sub.split(factor=0.5 + max_factor, align=True) split.alignment = 'RIGHT' split.label(text="Start") - split.prop(strip, "frame_final_start", text=str(bpy.utils.smpte_from_frame(strip.frame_final_start))) + split.prop(strip, "frame_final_start", text=smpte_from_frame(strip.frame_final_start)) split = sub.split(factor=0.5 + max_factor, align=True) split.alignment = 'RIGHT' split.label(text="End") - split.prop(strip, "frame_final_end", text=str(bpy.utils.smpte_from_frame(strip.frame_final_end))) + split.prop(strip, "frame_final_end", text=smpte_from_frame(strip.frame_final_end)) split = sub.split(factor=0.5 + max_factor, align=True) split.alignment = 'RIGHT' split.label(text="Duration") - split.prop(strip, "frame_final_duration", text=str(bpy.utils.smpte_from_frame(strip.frame_final_duration))) + split.prop(strip, "frame_final_duration", text=smpte_from_frame(strip.frame_final_duration)) if not isinstance(strip, bpy.types.EffectSequence): @@ -1337,25 +1363,25 @@ class SEQUENCER_PT_info_timecodes(SequencerButtonsPanel, Panel): split = sub.split(factor=0.5 + max_factor, align=True) split.alignment = 'RIGHT' split.label(text="Strip Offset Start") - split.prop(strip, "frame_offset_start", text=str(bpy.utils.smpte_from_frame(strip.frame_offset_start))) + split.prop(strip, "frame_offset_start", text=smpte_from_frame(strip.frame_offset_start)) split = sub.split(factor=0.5 + max_factor, align=True) split.alignment = 'RIGHT' split.label(text='End') - split.prop(strip, "frame_offset_end", text=str(bpy.utils.smpte_from_frame(strip.frame_offset_end))) + split.prop(strip, "frame_offset_end", text=smpte_from_frame(strip.frame_offset_end)) layout.alignment = 'RIGHT' sub = layout.column(align=True) - split = sub.split(factor=0.5 + max_factor, align=True) + split = sub.split(factor=0.5 + max_factor, align=True) split.alignment = 'RIGHT' split.label(text="Hold Offset Start") - split.prop(strip, "animation_offset_start", text=str(bpy.utils.smpte_from_frame(strip.animation_offset_start))) + split.prop(strip, "animation_offset_start", text=smpte_from_frame(strip.animation_offset_start)) split = sub.split(factor=0.5 + max_factor, align=True) split.alignment = 'RIGHT' split.label(text='End') - split.prop(strip, "animation_offset_end", text=str(bpy.utils.smpte_from_frame(strip.animation_offset_end))) + split.prop(strip, "animation_offset_end", text=smpte_from_frame(strip.animation_offset_end)) col = layout.column(align=True) col = col.box() @@ -1369,25 +1395,9 @@ class SEQUENCER_PT_info_timecodes(SequencerButtonsPanel, Panel): split.label(text="Playhead") split = split.split(factor=0.8 + max_factor, align=True) playhead = frame_current - strip.frame_final_start - split.label(text='{:>14}'.format(bpy.utils.smpte_from_frame(playhead)+":")) + split.label(text='{:>14}'.format(smpte_from_frame(playhead) + ":")) split.alignment = 'RIGHT' - split.label(text=str(playhead)+" ") - - elem = False - - if strip.type == 'IMAGE': - elem = strip.strip_elem_from_frame(frame_current) - elif strip.type == 'MOVIE': - elem = strip.elements[0] - - if strip.type != 'SOUND': - split = col.split(factor=0.5 + max_factor, align=False) - split.alignment = 'RIGHT' - split.label(text="Resolution") - if elem and elem.orig_width > 0 and elem.orig_height > 0: - split.label(text="%dx%d" % (elem.orig_width, elem.orig_height), translate=False) - else: - split.label(text="None") + split.label(text=str(playhead) + " ") if strip.type == 'SCENE': scene = strip.scene @@ -1423,22 +1433,16 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False st = context.space_data strip = act_strip(context) - sound = strip.sound - col = layout.column() - - row = col.row(align=True) - sub = row.row(align=True) - sub.active = (not strip.mute) + layout.active = not strip.mute - sub.prop(strip, "volume", text="Volume") - sub.prop(strip, "mute", toggle=True, icon_only=True, icon='MUTE_IPO_ON') + col = layout.column() + col.prop(strip, "volume", text="Volume") col.prop(strip, "pitch") col.prop(strip, "pan") @@ -1462,18 +1466,54 @@ class SEQUENCER_PT_adjust_comp(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False strip = act_strip(context) - layout.prop(strip, "blend_type", text="Blend") + layout.active = not strip.mute + + col = layout.column() + col.prop(strip, "blend_type", text="Blend") + col.prop(strip, "blend_alpha", text="Opacity", slider=True) + + +class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel): + bl_label = "Transform" + bl_parent_id = "SEQUENCER_PT_adjust" + bl_category = "Strip" + + @classmethod + def poll(cls, context): + if not cls.has_sequencer(context): + return False + + strip = act_strip(context) + if not strip: + return False + + return strip.type in { + 'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK', + 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER', + 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', + 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', + 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX' + } + + def draw(self, context): + layout = self.layout + strip = act_strip(context) + + layout.active = not strip.mute + + split = layout.split() - row = layout.row(align=True) - sub = row.row(align=True) - sub.active = (not strip.mute) + col = split.column() + col.alignment = 'RIGHT' + col.label(text="Mirror") - sub.prop(strip, "blend_alpha", text="Opacity", slider=True) - sub.prop(strip, "mute", toggle=True, icon_only=True) + col = split.column() + row = col.row(align=True) + row.prop(strip, "use_flip_x", text="X", toggle=True) + row.prop(strip, "use_flip_y", text="Y", toggle=True) class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel): @@ -1501,12 +1541,15 @@ class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True - layout.use_property_decorate = False + + col = layout.column() strip = act_strip(context) - col = layout.column() + layout.active = not strip.mute + col.prop(strip, "strobe") if strip.type == 'MOVIECLIP': @@ -1519,13 +1562,7 @@ class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel): col.prop(strip, "undistort") col.separator() - col.prop(strip, "use_reverse_frames", text="Backwards") - col.prop(strip, "use_deinterlace") - - col.separator() - - col.prop(strip, "use_flip_x", text="Flip X") - col.prop(strip, "use_flip_y", text="Flip Y") + col.prop(strip, "playback_direction") class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel): @@ -1554,10 +1591,11 @@ class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False strip = act_strip(context) + layout.active = not strip.mute + col = layout.column() col.prop(strip, "color_saturation", text="Saturation") col.prop(strip, "color_multiply", text="Multiply") @@ -1574,14 +1612,19 @@ class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + ed = context.scene.sequence_editor - layout.prop(ed, "use_cache_raw") - layout.prop(ed, "use_cache_preprocessed") - layout.prop(ed, "use_cache_composite") - layout.prop(ed, "use_cache_final") - layout.separator() - layout.prop(ed, "recycle_max_cost") + col = layout.column() + + col.prop(ed, "use_cache_raw") + col.prop(ed, "use_cache_preprocessed") + col.prop(ed, "use_cache_composite") + col.prop(ed, "use_cache_final") + col.separator() + col.prop(ed, "recycle_max_cost") class SEQUENCER_PT_proxy_settings(SequencerButtonsPanel, Panel): @@ -1594,6 +1637,9 @@ class SEQUENCER_PT_proxy_settings(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + ed = context.scene.sequence_editor flow = layout.column_flow() flow.prop(ed, "proxy_storage", text="Storage") @@ -1648,15 +1694,14 @@ class SEQUENCER_PT_strip_proxy(SequencerButtonsPanel, Panel): if proxy.use_proxy_custom_file: flow.prop(proxy, "filepath") - layout = layout.box() - row = layout.row(align=True) + box = layout.box() + row = box.row(align=True) row.prop(strip.proxy, "build_25") row.prop(strip.proxy, "build_75") - row = layout.row(align=True) + row = box.row(align=True) row.prop(strip.proxy, "build_50") row.prop(strip.proxy, "build_100") - layout = self.layout layout.use_property_split = True layout.use_property_decorate = False @@ -1682,6 +1727,7 @@ class SEQUENCER_PT_strip_cache(SequencerButtonsPanel, Panel): return False if act_strip(context) is not None: return True + return False def draw_header(self, context): strip = act_strip(context) @@ -1689,12 +1735,16 @@ class SEQUENCER_PT_strip_cache(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + strip = act_strip(context) layout.active = strip.override_cache_settings - layout.prop(strip, "use_cache_raw") - layout.prop(strip, "use_cache_preprocessed") - layout.prop(strip, "use_cache_composite") + col = layout.column() + col.prop(strip, "use_cache_raw") + col.prop(strip, "use_cache_preprocessed") + col.prop(strip, "use_cache_composite") class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel): @@ -1708,6 +1758,7 @@ class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False + render = context.scene.render col = layout.column() @@ -1831,7 +1882,6 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False strip = act_strip(context) ed = context.scene.sequence_editor @@ -1955,22 +2005,26 @@ classes = ( SEQUENCER_MT_strip_lock_mute, SEQUENCER_MT_context_menu, + SEQUENCER_PT_strip, + SEQUENCER_PT_adjust, SEQUENCER_PT_adjust_comp, - SEQUENCER_PT_adjust_offset, - SEQUENCER_PT_adjust_crop, + SEQUENCER_PT_adjust_transform, + SEQUENCER_PT_adjust_transform_offset, + SEQUENCER_PT_adjust_transform_crop, SEQUENCER_PT_adjust_video, SEQUENCER_PT_adjust_color, SEQUENCER_PT_adjust_sound, - SEQUENCER_PT_info, - SEQUENCER_PT_info_input, - SEQUENCER_PT_info_timecodes, - SEQUENCER_PT_effect, SEQUENCER_PT_scene, SEQUENCER_PT_mask, + SEQUENCER_PT_time, + SEQUENCER_PT_source, + + SEQUENCER_PT_modifiers, + SEQUENCER_PT_cache_settings, SEQUENCER_PT_strip_cache, SEQUENCER_PT_proxy_settings, @@ -1978,8 +2032,6 @@ classes = ( SEQUENCER_PT_custom_props, - SEQUENCER_PT_modifiers, - SEQUENCER_PT_preview, SEQUENCER_PT_view, SEQUENCER_PT_frame_overlay, diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index f8ae62374b9..e7f233cd196 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1596,6 +1596,11 @@ class VIEW3D_MT_select_edit_text(Menu): layout.separator() + layout.operator("font.case_set", text="To Uppercase").case = 'UPPER' + layout.operator("font.case_set", text="To Lowercase").case = 'LOWER' + + layout.separator() + layout.menu("VIEW3D_MT_edit_text_chars") @@ -4612,10 +4617,6 @@ class VIEW3D_MT_edit_gpencil_transform(Menu): layout.operator("transform.tosphere", text="To Sphere") layout.operator("transform.transform", text="Shrink Fatten").mode = 'GPENCIL_SHRINKFATTEN' - layout.separator() - - layout.operator("gpencil.reproject") - class VIEW3D_MT_edit_gpencil_interpolate(Menu): bl_label = "Interpolate" diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 9a00140b0fc..de227be0044 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -830,7 +830,7 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) const Int32ArraySamplePtr &face_indices = mesh_data.face_indices; const Int32ArraySamplePtr &face_counts = mesh_data.face_counts; const V2fArraySamplePtr &uvs = mesh_data.uvs; - const size_t uvs_size = uvs->size(); + const size_t uvs_size = uvs == nullptr ? 0 : uvs->size(); const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices; const N3fArraySamplePtr &normals = mesh_data.face_normals; diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index 502c949be9a..c1e36f5dd83 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -176,11 +176,13 @@ typedef void (*BKE_scene_collections_Cb)(struct Collection *ob, void *data); #define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN(_collection, _object, _mode) \ { \ int _base_flag = (_mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER; \ + int _object_restrict_flag = (_mode == DAG_EVAL_VIEWPORT) ? OB_RESTRICT_VIEWPORT : \ + OB_RESTRICT_RENDER; \ int _base_id = 0; \ for (Base *_base = (Base *)BKE_collection_object_cache_get(_collection).first; _base; \ _base = _base->next, _base_id++) { \ - if (_base->flag & _base_flag) { \ - Object *_object = _base->object; + Object *_object = _base->object; \ + if ((_base->flag & _base_flag) && (_object->restrictflag & _object_restrict_flag) == 0) { #define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END \ } \ diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 00fd291d7cb..d6683509729 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -320,6 +320,8 @@ float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame); /* Image modifications */ bool BKE_image_is_dirty(struct Image *image); void BKE_image_mark_dirty(struct Image *image, struct ImBuf *ibuf); +bool BKE_image_buffer_format_writable(struct ImBuf *ibuf); +bool BKE_image_is_dirty_writable(struct Image *image, bool *is_format_writable); /* Guess offset for the first frame in the sequence */ int BKE_image_sequence_guess_offset(struct Image *image); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index ca3a560286f..164dbbbf482 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -38,7 +38,6 @@ struct ParticleKey; struct ParticleSettings; struct ParticleSystem; struct ParticleSystemModifierData; -struct ParticleSystemModifierDataRuntime; struct BVHTreeRay; struct BVHTreeRayHit; @@ -609,13 +608,6 @@ float psys_get_current_display_percentage(struct ParticleSystem *psys, #define DMCACHE_NOTFOUND -1 #define DMCACHE_ISCHILD -2 -/* **** Particle system modifier helpers. **** */ - -struct Mesh *BKE_particle_modifier_mesh_final_get(struct ParticleSystemModifierData *psmd); -struct Mesh *BKE_particle_modifier_mesh_original_get(struct ParticleSystemModifierData *psmd); -struct ParticleSystemModifierDataRuntime *BKE_particle_modifier_runtime_ensure( - struct ParticleSystemModifierData *psmd); - /* **** Depsgraph evaluation **** */ struct Depsgraph; diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 5b718909601..ac55846714b 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -443,15 +443,13 @@ static void collection_object_cache_fill(ListBase *lb, Collection *collection, i BLI_addtail(lb, base); } - int object_restrict = base->object->restrictflag; - - if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) && - ((object_restrict & OB_RESTRICT_VIEWPORT) == 0)) { + /* Only collection flags are checked here currently, object restrict flag is checked + * in FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN since it can be animated + * without updating the cache. */ + if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0)) { base->flag |= BASE_ENABLED_VIEWPORT; } - - if (((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) && - ((object_restrict & OB_RESTRICT_RENDER) == 0)) { + if (((child_restrict & COLLECTION_RESTRICT_RENDER) == 0)) { base->flag |= BASE_ENABLED_RENDER; } } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 9b7a6002035..76098db5fd1 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1888,7 +1888,7 @@ bool CustomData_merge(const struct CustomData *source, else if ((maxnumber != -1) && (number >= maxnumber)) { continue; } - else if (CustomData_get_layer_named(dest, type, layer->name)) { + else if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) { continue; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f3ef48cafa8..5c23987a8d9 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -4812,7 +4812,7 @@ void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra) iuser->framenr = framenr; - if (ima && ima->gpuframenr != framenr) { + if (ima && BKE_image_is_animated(ima) && ima->gpuframenr != framenr) { /* Note: a single texture and refresh doesn't really work when * multiple image users may use different frames, this is to * be improved with perhaps a GPU texture cache. */ @@ -5075,9 +5075,10 @@ bool BKE_image_is_animated(Image *image) } /* Image modifications */ -bool BKE_image_is_dirty(Image *image) +bool BKE_image_is_dirty_writable(Image *image, bool *r_is_writable) { bool is_dirty = false; + bool is_writable = false; BLI_spin_lock(&image_spin); if (image->cache != NULL) { @@ -5086,6 +5087,7 @@ bool BKE_image_is_dirty(Image *image) while (!IMB_moviecacheIter_done(iter)) { ImBuf *ibuf = IMB_moviecacheIter_getImBuf(iter); if (ibuf->userflags & IB_BITMAPDIRTY) { + is_writable = BKE_image_buffer_format_writable(ibuf); is_dirty = true; break; } @@ -5095,14 +5097,31 @@ bool BKE_image_is_dirty(Image *image) } BLI_spin_unlock(&image_spin); + if (r_is_writable) { + *r_is_writable = is_writable; + } + return is_dirty; } +bool BKE_image_is_dirty(Image *image) +{ + return BKE_image_is_dirty_writable(image, NULL); +} + void BKE_image_mark_dirty(Image *UNUSED(image), ImBuf *ibuf) { ibuf->userflags |= IB_BITMAPDIRTY; } +bool BKE_image_buffer_format_writable(ImBuf *ibuf) +{ + ImageFormatData im_format; + ImbFormatOptions options_dummy; + BKE_imbuf_to_image_format(&im_format, ibuf); + return (BKE_image_imtype_to_ftype(im_format.imtype, &options_dummy) == ibuf->ftype); +} + void BKE_image_file_format_set(Image *image, int ftype, const ImbFormatOptions *options) { BLI_spin_lock(&image_spin); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index c377223d14b..6bc83f8dd09 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -67,6 +67,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "GPU_texture.h" + #ifdef WITH_OPENEXR # include "intern/openexr/openexr_multi.h" #endif @@ -1353,6 +1355,17 @@ static void free_buffers(MovieClip *clip) IMB_free_anim(clip->anim); clip->anim = NULL; } + + MovieClip_RuntimeGPUTexture *tex; + for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) { + for (int i = 0; i < TEXTARGET_COUNT; i++) { + if (tex->gputexture[i] != NULL) { + GPU_texture_free(tex->gputexture[i]); + tex->gputexture[i] = NULL; + } + } + } + BLI_freelistN(&clip->runtime.gputextures); } void BKE_movieclip_clear_cache(MovieClip *clip) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index e74b2b0f671..2a66edc8d42 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -497,13 +497,12 @@ void BKE_object_free_caches(Object *object) for (md = object->modifiers.first; md != NULL; md = md->next) { if (md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - ParticleSystemModifierDataRuntime *psmd_runtime = BKE_particle_modifier_runtime_ensure(psmd); - if (psmd_runtime->mesh_final) { - BKE_id_free(NULL, psmd_runtime->mesh_final); - psmd_runtime->mesh_final = NULL; - if (psmd_runtime->mesh_original) { - BKE_id_free(NULL, psmd_runtime->mesh_original); - psmd_runtime->mesh_original = NULL; + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_original) { + BKE_id_free(NULL, psmd->mesh_original); + psmd->mesh_original = NULL; } psmd->flag |= eParticleSystemFlag_file_loaded; update_flag |= ID_RECALC_GEOMETRY; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 61ee5685451..13649eaf096 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1889,8 +1889,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, float vtan[3], float orco[3]) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd && mesh_final) { + if (psmd && psmd->mesh_final) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { if (vec) { copy_v3_v3(vec, fuv); @@ -1903,7 +1902,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, } /* we cant use the num_dmcache */ psys_particle_on_dm( - mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); + psmd->mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); } else { psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco); @@ -2254,15 +2253,13 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params tree = BLI_kdtree_3d_new(totparent); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) { psys_particle_on_emitter( sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); /* Check if particle doesn't exist because of texture influence. * Insert only existing particles into kdtree. */ - get_cpa_texture(mesh_final, + get_cpa_texture(sim->psmd->mesh_final, psys, part, psys->particles + cpa->pa[0], @@ -2430,8 +2427,6 @@ static void psys_thread_create_path(ParticleTask *task, return; } - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(ctx->sim.psmd); - if (ctx->between) { ParticleData *pa = psys->particles + cpa->pa[0]; int w, needupdate; @@ -2536,7 +2531,7 @@ static void psys_thread_create_path(ParticleTask *task, sub_v3_v3v3(off1[w], co, key[w]->co); } - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); } else { ParticleData *pa = psys->particles + cpa->parent; @@ -2567,7 +2562,7 @@ static void psys_thread_create_path(ParticleTask *task, pa->num_dmcache; /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */ - if (cpa_num > mesh_final->totface) { + if (cpa_num > ctx->sim.psmd->mesh_final->totface) { cpa_num = 0; } cpa_fuv = pa->fuv; @@ -2584,7 +2579,7 @@ static void psys_thread_create_path(ParticleTask *task, 0, orco); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); } child_keys->segments = ctx->segments; @@ -2930,21 +2925,19 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re copy_v3_v3(col, &ma->r); } - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) { if ((psys->part->flag & PART_CHILD_EFFECT) == 0) { - vg_effector = psys_cache_vgroup(mesh_final, psys, PSYS_VG_EFFECTOR); + vg_effector = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_EFFECTOR); } if (!psys->totchild) { - vg_length = psys_cache_vgroup(mesh_final, psys, PSYS_VG_LENGTH); + vg_length = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_LENGTH); } } /* ensure we have tessfaces to be used for mapping */ if (part->from != PART_FROM_VERT) { - BKE_mesh_tessface_ensure(mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); } /*---first main loop: create all actual particles' paths---*/ @@ -2954,7 +2947,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f); pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p)); if (vg_length) { - pa_length *= psys_particle_value_from_verts(mesh_final, part->from, pa, vg_length); + pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length); } } @@ -2972,7 +2965,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re init_particle_interpolation(sim->ob, sim->psys, pa, &pind); /* hairmat is needed for for non-hair particle too so we get proper rotations */ - psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, psmd->mesh_final, psys->part->from, pa, hairmat); copy_v3_v3(rotmat[0], hairmat[2]); copy_v3_v3(rotmat[1], hairmat[1]); copy_v3_v3(rotmat[2], hairmat[0]); @@ -3030,7 +3023,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re float effector = 1.0f; if (vg_effector) { effector *= psys_particle_value_from_verts( - mesh_final, psys->part->from, pa, vg_effector); + psmd->mesh_final, psys->part->from, pa, vg_effector); } sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co); @@ -3165,8 +3158,7 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, init_particle_interpolation(ob, psys, pa, &pind); if (psys) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat); copy_v3_v3(rotmat[0], hairmat[2]); copy_v3_v3(rotmat[1], hairmat[1]); copy_v3_v3(rotmat[2], hairmat[0]); @@ -4046,9 +4038,8 @@ void psys_get_texture( mul_m4_v3(mtex->object->imat, texvec); } break; - case TEXCO_UV: { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - if (get_particle_uv(mesh_final, + case TEXCO_UV: + if (get_particle_uv(sim->psmd->mesh_final, pa, 0, pa->fuv, @@ -4059,7 +4050,6 @@ void psys_get_texture( } /* no break, failed to get uv's, so let's try orco's */ ATTR_FALLTHROUGH; - } case TEXCO_ORCO: psys_particle_on_emitter(sim->psmd, sim->psys->part->from, @@ -4333,8 +4323,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, } else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) { if ((pa->flag & PARS_REKEY) == 0) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - psys_mat_hair_to_global(sim->ob, mesh_final, part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, part->from, pa, hairmat); mul_m4_v3(hairmat, state->co); mul_mat3_m4_v3(hairmat, state->vel); @@ -4416,8 +4405,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, 0, par_orco); if (part->type == PART_HAIR) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); } else { unit_m4(hairmat); @@ -4449,10 +4437,9 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, 0, par_orco); if (part->type == PART_HAIR) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); psys_particle_on_emitter( psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco); - psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); } else { copy_v3_v3(orco, cpa->fuv); @@ -4463,7 +4450,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, /* get different child parameters from textures & vgroups */ memset(&ctx, 0, sizeof(ParticleThreadContext)); ctx.sim = *sim; - ctx.mesh = BKE_particle_modifier_mesh_final_get(psmd); + ctx.mesh = psmd->mesh_final; ctx.ma = ma; /* TODO: assign vertex groups */ get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); @@ -4728,16 +4715,14 @@ void psys_get_dupli_texture(ParticleSystem *psys, /* Grid distribution doesn't support UV or emit from vertex mode */ bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (cpa) { - if ((part->childtype == PART_CHILD_FACES) && (mesh_final != NULL)) { - CustomData *mtf_data = &mesh_final->fdata; + if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) { + CustomData *mtf_data = &psmd->mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); if (mtface && !is_grid) { - mface = CustomData_get(&mesh_final->fdata, cpa->num, CD_MFACE); + mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE); mtface += cpa->num; psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); } @@ -4760,8 +4745,8 @@ void psys_get_dupli_texture(ParticleSystem *psys, } } - if ((part->from == PART_FROM_FACE) && (mesh_final != NULL) && !is_grid) { - CustomData *mtf_data = &mesh_final->fdata; + if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) { + CustomData *mtf_data = &psmd->mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); @@ -4771,14 +4756,14 @@ void psys_get_dupli_texture(ParticleSystem *psys, num = pa->num; } - if (num >= mesh_final->totface) { + if (num >= psmd->mesh_final->totface) { /* happens when simplify is enabled * gives invalid coords but would crash otherwise */ num = DMCACHE_NOTFOUND; } if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - mface = CustomData_get(&mesh_final->fdata, num, CD_MFACE); + mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE); mtface += num; psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); } @@ -4899,10 +4884,8 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par int p, h; float hairmat[4][4], imat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim.psmd); - for (p = 0; p < psys->totpart; p++, pa++) { - psys_mat_hair_to_global(sim.ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); hkey = pa->hair; @@ -4937,40 +4920,3 @@ void BKE_particle_batch_cache_free(ParticleSystem *psys) BKE_particle_batch_cache_free_cb(psys); } } - -/* **** Particle system modifier helpers. **** */ - -Mesh *BKE_particle_modifier_mesh_final_get(ParticleSystemModifierData *psmd) -{ - if (psmd == NULL) { - return NULL; - } - ParticleSystemModifierDataRuntime *runtime = psmd->modifier.runtime; - if (runtime == NULL) { - return NULL; - } - return runtime->mesh_final; -} - -Mesh *BKE_particle_modifier_mesh_original_get(ParticleSystemModifierData *psmd) -{ - if (psmd == NULL) { - return NULL; - } - ParticleSystemModifierDataRuntime *runtime = psmd->modifier.runtime; - if (runtime == NULL) { - return NULL; - } - return runtime->mesh_original; -} - -ParticleSystemModifierDataRuntime *BKE_particle_modifier_runtime_ensure( - ParticleSystemModifierData *psmd) -{ - BLI_assert(psmd != NULL); - if (psmd->modifier.runtime == NULL) { - psmd->modifier.runtime = MEM_callocN(sizeof(ParticleSystemModifierDataRuntime), - "psmd runtime"); - } - return psmd->modifier.runtime; -} diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 7bb2daeab23..070c3c7a566 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -878,7 +878,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, int from) { Scene *scene = sim->scene; - Mesh *final_mesh = BKE_particle_modifier_mesh_final_get(sim->psmd); + Mesh *final_mesh = sim->psmd->mesh_final; Object *ob = sim->ob; ParticleSystem *psys = sim->psys; ParticleData *pa = 0, *tpars = 0; @@ -926,8 +926,8 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, if (from == PART_FROM_CHILD) { /* Simple children */ if (part->childtype != PART_CHILD_FACES) { - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); - distribute_simple_children(scene, ob, final_mesh, mesh_original, psys, use_render_params); + distribute_simple_children( + scene, ob, final_mesh, sim->psmd->mesh_original, psys, use_render_params); return 0; } } @@ -1318,7 +1318,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) TaskPool *task_pool; ParticleThreadContext ctx; ParticleTask *tasks; - Mesh *final_mesh = BKE_particle_modifier_mesh_final_get(sim->psmd); + Mesh *final_mesh = sim->psmd->mesh_final; int i, totpart, numtasks; /* create a task pool for distribution tasks */ @@ -1346,8 +1346,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) BLI_task_pool_free(task_pool); - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); - psys_calc_dmcache(sim->ob, final_mesh, mesh_original, sim->psys); + psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_original, sim->psys); if (ctx.mesh != final_mesh) { BKE_id_free(NULL, ctx.mesh); @@ -1372,8 +1371,7 @@ void distribute_particles(ParticleSimulationData *sim, int from) int distr_error = 0; if (psmd) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (mesh_final) { + if (psmd->mesh_final) { distribute_particles_on_dm(sim, from); } else { diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 1b0655c6734..27722aab2d9 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -467,7 +467,7 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData { memset(ctx, 0, sizeof(ParticleThreadContext)); ctx->sim = *sim; - ctx->mesh = BKE_particle_modifier_mesh_final_get(ctx->sim.psmd); + ctx->mesh = ctx->sim.psmd->mesh_final; ctx->ma = give_current_material(sim->ob, sim->psys->part->omat); } @@ -3348,7 +3348,6 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, /* make vgroup for pin roots etc.. */ hair_index = 1; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); LOOP_PARTICLES { if (!(pa->flag & PARS_UNEXIST)) { @@ -3359,7 +3358,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, pa->hair_index = hair_index; use_hair = psys_hair_use_simulation(pa, max_length); - psys_mat_hair_to_object(sim->ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_object(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat); normalize_m4(root_mat); @@ -3525,9 +3524,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re if (psys->recalc & ID_RECALC_PSYS_RESET) { /* need this for changing subsurf levels */ - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); - psys_calc_dmcache(sim->ob, mesh_final, mesh_original, psys); + psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_original, psys); if (psys->clmd) { cloth_free_modifier(psys->clmd); @@ -3579,8 +3576,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) if (pa->totkey) { sub_v3_v3(key->co, root->co); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - psys_vec_rot_to_face(mesh_final, pa, key->co); + psys_vec_rot_to_face(sim->psmd->mesh_final, pa, key->co); } key->time = pa->state.time; @@ -4614,13 +4610,12 @@ void particle_system_update(struct Depsgraph *depsgraph, } } - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim.psmd); - if (!mesh_final) { + if (!sim.psmd->mesh_final) { return; } if (part->from != PART_FROM_VERT) { - BKE_mesh_tessface_ensure(mesh_final); + BKE_mesh_tessface_ensure(sim.psmd->mesh_final); } /* to verify if we need to restore object afterwards */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 2514bad5709..971ca77ff3d 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3578,7 +3578,8 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, re = RE_NewSceneRender(scene); } - RE_RenderFrame(re, context->bmain, scene, view_layer, camera, frame, false); + RE_RenderFrame( + re, context->bmain, scene, have_comp ? NULL : view_layer, camera, frame, false); /* restore previous state after it was toggled on & off by RE_RenderFrame */ G.is_rendering = is_rendering; diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c index 9b6ed00c704..228f656949c 100644 --- a/source/blender/blenlib/intern/timecode.c +++ b/source/blender/blenlib/intern/timecode.c @@ -213,7 +213,7 @@ size_t BLI_timecode_string_from_time_simple(char *str, const int hr = ((int)time_seconds) / (60 * 60); const int min = (((int)time_seconds) / 60) % 60; const int sec = ((int)time_seconds) % 60; - const int hun = ((int)(time_seconds * 100.0)) % 100; + const int hun = ((int)(fmod(time_seconds, 1.0) * 100)); if (hr) { rlen = BLI_snprintf(str, maxncpy, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index edc3c7fe555..cdd174d5e0b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2038,6 +2038,7 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) for (; clip; clip = clip->id.next) { clip->cache = newmclipadr(fd, clip->cache); clip->tracking.camera.intrinsics = newmclipadr(fd, clip->tracking.camera.intrinsics); + BLI_freelistN(&clip->runtime.gputextures); } for (; sce; sce = sce->id.next) { @@ -5668,6 +5669,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) else if (md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; + psmd->mesh_final = NULL; + psmd->mesh_original = NULL; psmd->psys = newdataadr(fd, psmd->psys); psmd->flag &= ~eParticleSystemFlag_psys_updated; psmd->flag |= eParticleSystemFlag_file_loaded; diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index 00bb02d7205..4148529d3f8 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -85,16 +85,6 @@ void DEG_get_customdata_mask_for_object(const struct Depsgraph *graph, * one. Assert will happen if it's not. */ struct Scene *DEG_get_evaluated_scene(const struct Depsgraph *graph); -/* Similar to DEG_get_evaluated_scene(), but allows to access non-fully evaluated pointer without - * causing asserts or crashes. Works the following way: - * - If the scene was never evaluated NULL returned. - * - Otherwise the last known state of the scene is returned. - * - * Use in exceptional case if it's absolutely must to. - * - * Allows to pass depsgraph == NULL, will return NULL in that case. */ -struct Scene *DEG_get_evaluated_scene_if_exists(const struct Depsgraph *graph); - /* Get view layer at its evaluated state. * This is a shortcut for accessing active view layer from evaluated scene. */ struct ViewLayer *DEG_get_evaluated_view_layer(const struct Depsgraph *graph); diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index 48dbd4b0945..f821af8cdc7 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -160,19 +160,6 @@ Scene *DEG_get_evaluated_scene(const Depsgraph *graph) return scene_cow; } -Scene *DEG_get_evaluated_scene_if_exists(const Depsgraph *graph) -{ - if (graph == NULL) { - return NULL; - } - const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); - Scene *scene_cow = deg_graph->scene_cow; - if (scene_cow == NULL || !DEG::deg_copy_on_write_is_expanded(&scene_cow->id)) { - return NULL; - } - return scene_cow; -} - ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph) { const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 44551a4e04b..8631a9f556b 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -249,6 +249,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_volume_vert.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_volume_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC) +data_to_c_simple(modes/shaders/common_colormanagement_lib.glsl SRC) data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC) data_to_c_simple(modes/shaders/common_hair_lib.glsl SRC) data_to_c_simple(modes/shaders/common_hair_refine_vert.glsl SRC) @@ -295,6 +296,8 @@ data_to_c_simple(modes/shaders/overlay_face_orientation_vert.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_wireframe_vert.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_wireframe_geom.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_wireframe_frag.glsl SRC) +data_to_c_simple(modes/shaders/object_camera_image_frag.glsl SRC) +data_to_c_simple(modes/shaders/object_camera_image_vert.glsl SRC) data_to_c_simple(modes/shaders/object_empty_axes_vert.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC) @@ -325,6 +328,7 @@ data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC) data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC) data_to_c_simple(modes/shaders/particle_strand_frag.glsl SRC) data_to_c_simple(modes/shaders/particle_strand_vert.glsl SRC) +data_to_c_simple(modes/shaders/pose_selection_vert.glsl SRC) data_to_c_simple(modes/shaders/sculpt_mask_vert.glsl SRC) data_to_c_simple(modes/shaders/volume_velocity_vert.glsl SRC) diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 6d1227bb0a8..ae3bf8cead6 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -61,6 +61,7 @@ extern char datatoc_gpencil_edit_point_geom_glsl[]; extern char datatoc_gpencil_edit_point_frag_glsl[]; extern char datatoc_gpencil_blend_frag_glsl[]; +extern char datatoc_common_colormanagement_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; /* *********** STATIC *********** */ @@ -169,29 +170,37 @@ static void GPENCIL_create_shaders(void) { /* normal fill shader */ if (!e_data.gpencil_fill_sh) { - e_data.gpencil_fill_sh = DRW_shader_create_with_lib(datatoc_gpencil_fill_vert_glsl, - NULL, - datatoc_gpencil_fill_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); + e_data.gpencil_fill_sh = GPU_shader_create_from_arrays({ + .vert = + (const char *[]){datatoc_common_view_lib_glsl, datatoc_gpencil_fill_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_gpencil_fill_frag_glsl, + NULL}, + }); } /* normal stroke shader using geometry to display lines (line mode) */ if (!e_data.gpencil_stroke_sh) { - e_data.gpencil_stroke_sh = DRW_shader_create_with_lib(datatoc_gpencil_stroke_vert_glsl, - datatoc_gpencil_stroke_geom_glsl, - datatoc_gpencil_stroke_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); + e_data.gpencil_stroke_sh = GPU_shader_create_from_arrays({ + .vert = + (const char *[]){datatoc_common_view_lib_glsl, datatoc_gpencil_stroke_vert_glsl, NULL}, + .geom = (const char *[]){datatoc_gpencil_stroke_geom_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_gpencil_stroke_frag_glsl, + NULL}, + }); } /* dot/rectangle mode for normal strokes using geometry */ if (!e_data.gpencil_point_sh) { - e_data.gpencil_point_sh = DRW_shader_create_with_lib(datatoc_gpencil_point_vert_glsl, - datatoc_gpencil_point_geom_glsl, - datatoc_gpencil_point_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); + e_data.gpencil_point_sh = GPU_shader_create_from_arrays({ + .vert = + (const char *[]){datatoc_common_view_lib_glsl, datatoc_gpencil_point_vert_glsl, NULL}, + .geom = (const char *[]){datatoc_gpencil_point_geom_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_gpencil_point_frag_glsl, + NULL}, + }); } /* used for edit points or strokes with one point only */ if (!e_data.gpencil_edit_point_sh) { diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl index 1fdfd05332e..87bf116ff89 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl @@ -90,31 +90,6 @@ void set_color(in vec4 color, ocolor.a *= layer_opacity; } -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * grease pencil still works in srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { vec2 t_center = vec2(0.5, 0.5); diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl index 7fed42aca0d..34777018a73 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl @@ -48,31 +48,6 @@ vec2 check_box_point(vec2 pt, vec2 radius) return rtn; } -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * grease pencil still works in srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { vec2 centered = mTexCoord - vec2(0.5); diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl index bc703d2a078..73baacb35d4 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl @@ -28,31 +28,6 @@ out vec4 fragColor; bool no_texture = (shading_type[0] == OB_SOLID) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR); -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * grease pencil still works in srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 467626bf2c8..c66a737d684 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -301,15 +301,14 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys, return; } ParticleData *particle = &psys->particles[parent_index]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num_dmcache; if (num == DMCACHE_NOTFOUND || num == DMCACHE_ISCHILD) { - if (particle->num < mesh_final->totface) { + if (particle->num < psmd->mesh_final->totface) { num = particle->num; } } if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) { - MFace *mface = &mesh_final->mface[num]; + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -331,17 +330,16 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys, return; } ParticleData *particle = &psys->particles[parent_index]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num_dmcache; if (num == DMCACHE_NOTFOUND || num == DMCACHE_ISCHILD) { - if (particle->num < mesh_final->totface) { + if (particle->num < psmd->mesh_final->totface) { num = particle->num; } } if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) { - MFace *mface = &mesh_final->mface[num]; + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_col_layers; j++) { - psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]); + psys_interpolate_mcol(mcols[j] + num, mface->v4, particle->fuv, &r_mcol[j]); } } } @@ -363,9 +361,8 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys, } ChildParticle *particle = &psys->child[child_index]; int num = particle->num; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); if (num != DMCACHE_NOTFOUND) { - MFace *mface = &mesh_final->mface[num]; + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -387,10 +384,9 @@ static void particle_interpolate_children_mcol(ParticleSystem *psys, return; } ChildParticle *particle = &psys->child[child_index]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num; if (num != DMCACHE_NOTFOUND) { - MFace *mface = &mesh_final->mface[num]; + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_col_layers; j++) { psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]); } @@ -842,16 +838,15 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit int active_col = 0; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd != NULL && mesh_final != NULL) { - if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { - cache->num_uv_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPUV); - active_uv = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPUV); + if (psmd != NULL && psmd->mesh_final != NULL) { + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { + cache->num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); + active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); } - if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { - cache->num_col_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPCOL); - active_col = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPCOL); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL)) { + cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPCOL); + active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); } } @@ -895,7 +890,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit GPU_vertbuf_data_alloc(cache->proc_uv_buf[i], cache->strands_len); GPU_vertbuf_attr_get_raw_data(cache->proc_uv_buf[i], uv_id, &uv_step[i]); - const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); uint hash = BLI_ghashutil_strhash_p(name); int n = 0; BLI_snprintf(cache->uv_layer_names[i][n++], MAX_LAYER_NAME_LEN, "u%u", hash); @@ -911,13 +906,13 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit GPU_vertbuf_data_alloc(cache->proc_col_buf[i], cache->strands_len); GPU_vertbuf_attr_get_raw_data(cache->proc_col_buf[i], col_id, &col_step[i]); - const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPCOL, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPCOL, i); uint hash = BLI_ghashutil_strhash_p(name); int n = 0; BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "c%u", hash); /* We only do vcols auto name that are not overridden by uvs */ - if (CustomData_get_named_layer_index(&mesh_final->ldata, CD_MLOOPUV, name) == -1) { + if (CustomData_get_named_layer_index(&psmd->mesh_final->ldata, CD_MLOOPUV, name) == -1) { BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "a%u", hash); } @@ -927,15 +922,15 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit } if (cache->num_uv_layers || cache->num_col_layers) { - BKE_mesh_tessface_ensure(mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); if (cache->num_uv_layers) { for (int j = 0; j < cache->num_uv_layers; j++) { - mtfaces[j] = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, j); + mtfaces[j] = (MTFace *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MTFACE, j); } } if (cache->num_col_layers) { for (int j = 0; j < cache->num_col_layers; j++) { - mcols[j] = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, j); + mcols[j] = (MCol *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MCOL, j); } } } @@ -1148,16 +1143,14 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, float(**parent_uvs)[2] = NULL; MCol **parent_mcol = NULL; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd != NULL) { - if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { - num_uv_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPUV); - active_uv = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPUV); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { + num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); + active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); } - if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { - num_col_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPCOL); - active_col = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPCOL); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL)) { + num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPCOL); + active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); } } @@ -1173,7 +1166,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, col_id = MEM_mallocN(sizeof(*col_id) * num_col_layers, "Col attr format"); for (int i = 0; i < num_uv_layers; i++) { - const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name)); @@ -1185,7 +1178,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, } for (int i = 0; i < num_uv_layers; i++) { - const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "c%u", BLI_ghashutil_strhash_p(name)); @@ -1204,17 +1197,17 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, hair_cache->elems_len, hair_cache->point_len); if (num_uv_layers || num_col_layers) { - BKE_mesh_tessface_ensure(mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); if (num_uv_layers) { mtfaces = MEM_mallocN(sizeof(*mtfaces) * num_uv_layers, "Faces UV layers"); for (int i = 0; i < num_uv_layers; i++) { - mtfaces[i] = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, i); + mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MTFACE, i); } } if (num_col_layers) { mcols = MEM_mallocN(sizeof(*mcols) * num_col_layers, "Color layers"); for (int i = 0; i < num_col_layers; i++) { - mcols[i] = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, i); + mcols[i] = (MCol *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MCOL, i); } } } diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 70fe13eeaa2..7606fa914d1 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1558,7 +1558,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, RegionView3D *rv3d = ar->regiondata; const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0)); - const bool do_camera_frame = !DST.options.is_image_render; DST.draw_ctx.evil_C = evil_C; DST.viewport = viewport; @@ -1650,24 +1649,8 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, drw_engines_draw_background(); - /* WIP, single image drawn over the camera view (replace) */ - bool do_bg_image = false; - if (rv3d->persp == RV3D_CAMOB) { - Object *cam_ob = v3d->camera; - if (cam_ob && cam_ob->type == OB_CAMERA) { - Camera *cam = cam_ob->data; - if (!BLI_listbase_is_empty(&cam->bg_images)) { - do_bg_image = true; - } - } - } - GPU_framebuffer_bind(DST.default_framebuffer); - if (do_bg_image) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, do_camera_frame); - } - DRW_draw_callbacks_pre_scene(); if (DST.draw_ctx.evil_C) { ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW); @@ -1734,10 +1717,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, DRW_stats_reset(); - if (do_bg_image) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, true, do_camera_frame); - } - if (G.debug_value > 20 && G.debug_value < 30) { GPU_depth_test(false); rcti rect; /* local coordinate visible rect inside region, to accommodate overlapping ui */ @@ -2001,10 +1980,10 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]); } - /* Reset state before drawing */ - DRW_state_reset(); /* Set the default Blender draw state */ GPU_state_init(); + /* Reset state before drawing */ + DRW_state_reset(); /* Init render result. */ RenderResult *render_result = RE_engine_begin_result(engine, diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index 068af2e2012..e3c120e80cb 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -269,7 +269,9 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob) } geom = DRW_cache_curve_edge_wire_get(ob); - DRW_shgroup_call(wire_shgrp, geom, ob); + if (geom) { + DRW_shgroup_call(wire_shgrp, geom, ob); + } if ((cu->flag & CU_3D) && (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_NORMALS) != 0) { geom = DRW_cache_curve_edge_normal_get(ob); @@ -282,17 +284,23 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob) } geom = DRW_cache_curve_vert_overlay_get(ob, stl->g_data->show_handles); - DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob); + if (geom) { + DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob); + } } } if (ob->type == OB_SURF) { if (BKE_object_is_in_editmode(ob)) { struct GPUBatch *geom = DRW_cache_curve_edge_overlay_get(ob); - DRW_shgroup_call(stl->g_data->overlay_edge_shgrp, geom, ob); + if (geom) { + DRW_shgroup_call(stl->g_data->overlay_edge_shgrp, geom, ob); + } geom = DRW_cache_curve_vert_overlay_get(ob, false); - DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob); + if (geom) { + DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob); + } } } } diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c index d1d17f2dc2d..03f26e8ce63 100644 --- a/source/blender/draw/modes/edit_text_mode.c +++ b/source/blender/draw/modes/edit_text_mode.c @@ -166,18 +166,17 @@ static void EDIT_TEXT_cache_init(void *vedata) "Font Wire", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->wire_shgrp = DRW_shgroup_create(e_data.wire_sh, psl->wire_pass); - psl->overlay_select_pass = DRW_pass_create("Font Select", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH); + /* Show selection & cursor on-top of everything (x-ray). */ + + psl->overlay_select_pass = DRW_pass_create("Font Select", DRW_STATE_WRITE_COLOR); stl->g_data->overlay_select_shgrp = DRW_shgroup_create(e_data.overlay_select_sh, psl->overlay_select_pass); - psl->overlay_cursor_pass = DRW_pass_create("Font Cursor", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH); + psl->overlay_cursor_pass = DRW_pass_create("Font Cursor", DRW_STATE_WRITE_COLOR); stl->g_data->overlay_cursor_shgrp = DRW_shgroup_create(e_data.overlay_cursor_sh, psl->overlay_cursor_pass); - psl->text_box_pass = DRW_pass_create("Font Text Boxes", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH); + psl->text_box_pass = DRW_pass_create("Font Text Boxes", DRW_STATE_WRITE_COLOR); stl->g_data->box_shgrp = buffer_dynlines_dashed_uniform_color( psl->text_box_pass, G_draw.block.colorWire, draw_ctx->sh_cfg); stl->g_data->box_active_shgrp = buffer_dynlines_dashed_uniform_color( diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index bbf364960c9..1c60fc09057 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -38,6 +38,7 @@ #include "DNA_rigidbody_types.h" #include "DNA_smoke_types.h" #include "DNA_view3d_types.h" +#include "DNA_screen_types.h" #include "DNA_world_types.h" #include "BKE_anim.h" @@ -45,6 +46,7 @@ #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_editmesh.h" +#include "BKE_image.h" #include "BKE_mball.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -55,6 +57,8 @@ #include "BLI_ghash.h" +#include "IMB_imbuf_types.h" + #include "ED_view3d.h" #include "GPU_batch.h" @@ -80,6 +84,8 @@ extern char datatoc_object_outline_detect_frag_glsl[]; extern char datatoc_object_outline_expand_frag_glsl[]; extern char datatoc_object_grid_frag_glsl[]; extern char datatoc_object_grid_vert_glsl[]; +extern char datatoc_object_camera_image_frag_glsl[]; +extern char datatoc_object_camera_image_vert_glsl[]; extern char datatoc_object_empty_image_frag_glsl[]; extern char datatoc_object_empty_image_vert_glsl[]; extern char datatoc_object_lightprobe_grid_vert_glsl[]; @@ -87,6 +93,7 @@ extern char datatoc_object_loose_points_frag_glsl[]; extern char datatoc_object_particle_prim_vert_glsl[]; extern char datatoc_object_particle_dot_vert_glsl[]; extern char datatoc_object_particle_dot_frag_glsl[]; +extern char datatoc_common_colormanagement_lib_glsl[]; extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; extern char datatoc_common_fxaa_lib_glsl[]; @@ -115,6 +122,8 @@ typedef struct OBJECT_PassList { struct DRWPass *bone_axes[2]; struct DRWPass *particle; struct DRWPass *lightprobes; + struct DRWPass *camera_images_back; + struct DRWPass *camera_images_front; } OBJECT_PassList; typedef struct OBJECT_FramebufferList { @@ -148,6 +157,8 @@ typedef struct OBJECT_Shaders { GPUShader *outline_fade_large; /* regular shaders */ + GPUShader *object_camera_image; + GPUShader *object_camera_image_cm; GPUShader *object_empty_image; GPUShader *object_empty_image_wire; GPUShader *grid; @@ -336,6 +347,7 @@ static struct { struct GPUTexture *outlines_blur_tx; ListBase smoke_domains; + ListBase movie_clips; } e_data = {NULL}; /* Engine data */ enum { @@ -460,7 +472,9 @@ static void OBJECT_engine_init(void *vedata) datatoc_common_view_lib_glsl, datatoc_object_empty_image_vert_glsl, NULL}, - .frag = (const char *[]){datatoc_object_empty_image_frag_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_object_empty_image_frag_glsl, + NULL}, .defs = (const char *[]){sh_cfg_data->def, empty_image_defs, NULL}, }); sh_data->object_empty_image_wire = GPU_shader_create_from_arrays({ @@ -471,6 +485,21 @@ static void OBJECT_engine_init(void *vedata) .frag = (const char *[]){datatoc_object_empty_image_frag_glsl, NULL}, .defs = (const char *[]){sh_cfg_data->def, "#define USE_WIRE\n", empty_image_defs, NULL}, }); + + sh_data->object_camera_image_cm = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, datatoc_object_camera_image_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_object_camera_image_frag_glsl, + NULL}, + .defs = + (const char *[]){sh_cfg_data->def, "#define DRW_STATE_DO_COLOR_MANAGEMENT\n", NULL}, + }); + sh_data->object_camera_image = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, datatoc_object_camera_image_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_object_camera_image_frag_glsl, + NULL}, + }); } /* Grid */ @@ -1035,6 +1064,291 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data, } } +/* Draw Camera Background Images */ +typedef struct CameraEngineData { + DrawData dd; + ListBase bg_data; +} CameraEngineData; +typedef struct CameraEngineBGData { + float transform_mat[4][4]; +} CameraEngineBGData; + +static void camera_engine_data_free(DrawData *dd) +{ + CameraEngineData *data = (CameraEngineData *)dd; + for (LinkData *link = data->bg_data.first; link; link = link->next) { + CameraEngineBGData *bg_data = (CameraEngineBGData *)link->data; + MEM_freeN(bg_data); + } + BLI_freelistN(&data->bg_data); +} + +static void camera_background_images_stereo_setup(Scene *scene, + View3D *v3d, + Image *ima, + ImageUser *iuser) +{ + if (BKE_image_is_stereo(ima)) { + iuser->flag |= IMA_SHOW_STEREO; + + if ((scene->r.scemode & R_MULTIVIEW) == 0) { + iuser->multiview_eye = STEREO_LEFT_ID; + } + else if (v3d->stereo3d_camera != STEREO_3D_ID) { + /* show only left or right camera */ + iuser->multiview_eye = v3d->stereo3d_camera; + } + + BKE_image_multiview_index(ima, iuser); + } + else { + iuser->flag &= ~IMA_SHOW_STEREO; + } +} + +static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data, + OBJECT_PassList *psl, + Object *ob, + RegionView3D *rv3d) +{ + if (!BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d)) { + return; + } + + const DRWContextState *draw_ctx = DRW_context_state_get(); + struct ARegion *ar = draw_ctx->ar; + View3D *v3d = draw_ctx->v3d; + Scene *scene = draw_ctx->scene; + Depsgraph *depsgraph = draw_ctx->depsgraph; + Camera *cam = ob->data; + const Object *camera_object = DEG_get_evaluated_object(depsgraph, v3d->camera); + const bool is_active = (ob == camera_object); + const bool look_through = (is_active && (rv3d->persp == RV3D_CAMOB)); + + if (look_through && (cam->flag & CAM_SHOW_BG_IMAGE)) { + GPUBatch *batch = DRW_cache_image_plane_get(); + + /* load camera engine data */ + CameraEngineData *camera_engine_data = (CameraEngineData *)DRW_drawdata_ensure( + &ob->id, + &draw_engine_object_type, + sizeof(CameraEngineData), + NULL, + camera_engine_data_free); + LinkData *list_node = camera_engine_data->bg_data.first; + + for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) { + if ((bgpic->flag & CAM_BGIMG_FLAG_DISABLED)) { + continue; + } + + /* retrieve the image we want to show, continue to next when no image could be found */ + ImBuf *ibuf = NULL; + GPUTexture *tex = NULL; + float image_aspect_x, image_aspect_y; + float image_aspect = 1.0; + int image_width, image_height; + bool premultiplied = false; + + if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { + Image *image = bgpic->ima; + if (image == NULL) { + continue; + } + premultiplied = (image->alpha_mode == IMA_ALPHA_PREMUL); + ImageUser *iuser = &bgpic->iuser; + BKE_image_user_frame_calc(image, iuser, (int)DEG_get_ctime(depsgraph)); + if (image->source == IMA_SRC_SEQUENCE && !(iuser->flag & IMA_USER_FRAME_IN_RANGE)) { + /* frame is out of range, dont show */ + continue; + } + else { + camera_background_images_stereo_setup(scene, v3d, image, iuser); + } + tex = GPU_texture_from_blender(image, iuser, GL_TEXTURE_2D); + if (tex == NULL) { + continue; + } + ibuf = BKE_image_acquire_ibuf(image, iuser, NULL); + if (ibuf == NULL) { + continue; + } + + image_aspect_x = bgpic->ima->aspx; + image_aspect_y = bgpic->ima->aspy; + + image_width = ibuf->x; + image_height = ibuf->y; + BKE_image_release_ibuf(image, ibuf, NULL); + image_aspect = (image_width * image_aspect_x) / (image_height * image_aspect_y); + } + else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) { + MovieClip *clip = NULL; + if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) { + if (scene->camera) { + clip = BKE_object_movieclip_get(scene, scene->camera, true); + } + } + else { + clip = bgpic->clip; + } + + if (clip == NULL) { + continue; + } + + image_aspect_x = clip->aspx; + image_aspect_y = clip->aspy; + + BKE_movieclip_user_set_frame(&bgpic->cuser, (int)DEG_get_ctime(depsgraph)); + tex = GPU_texture_from_movieclip(clip, &bgpic->cuser, GL_TEXTURE_2D); + if (tex == NULL) { + continue; + } + BLI_addtail(&e_data.movie_clips, BLI_genericNodeN(clip)); + BKE_movieclip_get_size(clip, &bgpic->cuser, &image_width, &image_height); + image_aspect = (image_width * image_aspect_x) / (image_height * image_aspect_y); + } + + /* ensure link_data is allocated to store matrice */ + CameraEngineBGData *bg_data; + if (list_node != NULL) { + bg_data = (CameraEngineBGData *)list_node->data; + list_node = list_node->next; + } + else { + bg_data = MEM_mallocN(sizeof(CameraEngineBGData), __func__); + BLI_addtail(&camera_engine_data->bg_data, BLI_genericNodeN(bg_data)); + } + + /* calculate the transformation matric for the current bg image */ + float uv2img_space[4][4]; + float img2cam_space[4][4]; + float rot_m4[4][4]; + float scale_m4[4][4]; + float translate_m4[4][4]; + float win_m4_scale[4][4]; + float win_m4_translate[4][4]; + + unit_m4(uv2img_space); + unit_m4(img2cam_space); + unit_m4(win_m4_scale); + unit_m4(win_m4_translate); + unit_m4(scale_m4); + axis_angle_to_mat4_single(rot_m4, 'Z', bgpic->rotation); + unit_m4(translate_m4); + + const float *size = DRW_viewport_size_get(); + float camera_aspect_x = 1.0; + float camera_aspect_y = 1.0; + float camera_offset_x = 0.0; + float camera_offset_y = 0.0; + float camera_aspect = 1.0; + float camera_width = size[0]; + float camera_height = size[1]; + + if (!DRW_state_is_image_render()) { + rctf render_border; + ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &render_border, true); + camera_width = render_border.xmax - render_border.xmin; + camera_height = render_border.ymax - render_border.ymin; + camera_aspect = camera_width / camera_height; + const float camera_aspect_center_x = (render_border.xmax + render_border.xmin) / 2.0; + const float camera_aspect_center_y = (render_border.ymax + render_border.ymin) / 2.0; + + camera_aspect_x = camera_width / size[0]; + camera_aspect_y = camera_height / size[1]; + win_m4_scale[0][0] = camera_aspect_x; + win_m4_scale[1][1] = camera_aspect_y; + + camera_offset_x = (camera_aspect_center_x - (ar->winx / 2.0)) / + (0.5 * camera_width / camera_aspect_x); + camera_offset_y = (camera_aspect_center_y - (ar->winy / 2.0)) / + (0.5 * camera_height / camera_aspect_y); + win_m4_translate[3][0] = camera_offset_x; + win_m4_translate[3][1] = camera_offset_y; + } + + /* Convert from uv space to image space -0.5..-.5 */ + uv2img_space[0][0] = image_width; + uv2img_space[1][1] = image_height; + + img2cam_space[0][0] = (1.0 / image_width); + img2cam_space[1][1] = (1.0 / image_height); + + /* Update scaling based on image and camera framing */ + float scale_x = bgpic->scale; + float scale_y = bgpic->scale; + + if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) { + float fit_scale = image_aspect / camera_aspect; + if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) { + if (image_aspect > camera_aspect) { + scale_x *= fit_scale; + } + else { + scale_y /= fit_scale; + } + } + else { + if (image_aspect > camera_aspect) { + scale_y /= fit_scale; + } + else { + scale_x *= fit_scale; + } + } + } + + // scale image to match the desired aspect ratio + scale_m4[0][0] = scale_x; + scale_m4[1][1] = scale_y; + + // translate + translate_m4[3][0] = bgpic->offset[0]; + translate_m4[3][1] = bgpic->offset[1]; + + mul_m4_series(bg_data->transform_mat, + win_m4_translate, + win_m4_scale, + translate_m4, + img2cam_space, + scale_m4, + rot_m4, + uv2img_space); + + DRWPass *pass = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? psl->camera_images_front : + psl->camera_images_back; + GPUShader *shader = DRW_state_do_color_management() ? sh_data->object_camera_image_cm : + sh_data->object_camera_image; + DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + + DRW_shgroup_uniform_float_copy( + grp, "depth", (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? 0.000001 : 0.999999); + DRW_shgroup_uniform_float_copy(grp, "alpha", bgpic->alpha); + DRW_shgroup_uniform_texture(grp, "image", tex); + DRW_shgroup_uniform_bool_copy(grp, "imagePremultiplied", premultiplied); + + DRW_shgroup_uniform_float_copy( + grp, "flipX", (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0); + DRW_shgroup_uniform_float_copy( + grp, "flipY", (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0); + DRW_shgroup_uniform_mat4(grp, "TransformMat", bg_data->transform_mat); + + DRW_shgroup_call(grp, batch, NULL); + } + } +} + +static void camera_background_images_free_textures(void) +{ + for (LinkData *link = e_data.movie_clips.first; link; link = link->next) { + MovieClip *clip = (MovieClip *)link->data; + GPU_free_texture_movieclip(clip); + } + BLI_freelistN(&e_data.movie_clips); +} + static void OBJECT_cache_init(void *vedata) { const GlobalsUboStorage *gb = &G_draw.block; @@ -1206,6 +1520,13 @@ static void OBJECT_cache_init(void *vedata) DRW_shgroup_call(grp, geom, NULL); } + /* Camera background images */ + { + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA; + psl->camera_images_back = DRW_pass_create("Camera Images Back", state); + psl->camera_images_front = DRW_pass_create("Camera Images Front", state); + } + for (int i = 0; i < 2; ++i) { OBJECT_ShadingGroupList *sgl = (i == 1) ? &stl->g_data->sgl_ghost : &stl->g_data->sgl; @@ -3221,10 +3542,12 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; } geom = DRW_cache_lattice_wire_get(ob, false); + if (geom == NULL) { + break; + } if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } - shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag); DRW_shgroup_call(shgroup, geom, ob); } @@ -3236,6 +3559,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; } geom = DRW_cache_curve_edge_wire_get(ob); + if (geom == NULL) { + break; + } if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } @@ -3261,6 +3587,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; } DRW_shgroup_camera(sgl, ob, view_layer); + DRW_shgroup_camera_background_images(sh_data, psl, ob, rv3d); break; case OB_EMPTY: if (hide_object_extra) { @@ -3444,6 +3771,8 @@ static void OBJECT_draw_scene(void *vedata) float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + DRW_draw_pass(psl->camera_images_back); + /* Don't draw Transparent passes in MSAA buffer. */ // DRW_draw_pass(psl->bone_envelope); /* Never drawn in Object mode currently. */ DRW_draw_pass(stl->g_data->sgl.transp_shapes); @@ -3513,7 +3842,6 @@ static void OBJECT_draw_scene(void *vedata) DRW_draw_pass(psl->outlines_resolve); } } - volumes_free_smoke_textures(); batch_camera_path_free(&stl->g_data->sgl.camera_path); @@ -3562,6 +3890,9 @@ static void OBJECT_draw_scene(void *vedata) batch_camera_path_free(&stl->g_data->sgl_ghost.camera_path); + DRW_draw_pass(psl->camera_images_front); + camera_background_images_free_textures(); + DRW_draw_pass(psl->ob_center); } diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 5f833e4c6a1..82c11a278de 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -40,6 +40,7 @@ #include "DEG_depsgraph_query.h" +extern char datatoc_common_colormanagement_lib_glsl[]; extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; extern char datatoc_paint_texture_vert_glsl[]; @@ -160,7 +161,9 @@ static void PAINT_TEXTURE_engine_init(void *vedata) datatoc_common_view_lib_glsl, datatoc_paint_texture_vert_glsl, NULL}, - .frag = (const char *[]){datatoc_paint_texture_frag_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_paint_texture_frag_glsl, + NULL}, .defs = (const char *[]){sh_cfg_data->def, NULL}, }); diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 8cdf28f177a..3a5c87688fe 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -35,6 +35,10 @@ #include "draw_common.h" #include "draw_mode_engines.h" +extern char datatoc_common_view_lib_glsl[]; +extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; +extern char datatoc_pose_selection_vert_glsl[]; + /* *********** LISTS *********** */ /** * All lists are per viewport specific datas. @@ -93,12 +97,18 @@ static bool POSE_is_bone_selection_overlay_active(void) static void POSE_engine_init(void *UNUSED(vedata)) { if (!e_data.bone_selection_sh) { - e_data.bone_selection_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); + e_data.bone_selection_sh = DRW_shader_create_with_lib( + datatoc_pose_selection_vert_glsl, + NULL, + datatoc_gpu_shader_uniform_color_frag_glsl, + datatoc_common_view_lib_glsl, + NULL); } } static void POSE_engine_free(void) { + DRW_SHADER_FREE_SAFE(e_data.bone_selection_sh); } /* Here init all passes and shading groups diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c index 42a2333f305..1b196cd8bb7 100644 --- a/source/blender/draw/modes/sculpt_mode.c +++ b/source/blender/draw/modes/sculpt_mode.c @@ -155,7 +155,8 @@ static void SCULPT_cache_populate(void *vedata, Object *ob) if (ob->sculpt) { const DRWContextState *draw_ctx = DRW_context_state_get(); - if ((ob == draw_ctx->obact) && BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d)) { + if ((ob == draw_ctx->obact) && + (BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) || !ob->sculpt->modifiers_active)) { PBVH *pbvh = ob->sculpt->pbvh; if (pbvh && pbvh_has_mask(pbvh)) { DRW_shgroup_call_sculpt(stl->g_data->mask_overlay_grp, ob, false, true, false); diff --git a/source/blender/draw/modes/shaders/common_colormanagement_lib.glsl b/source/blender/draw/modes/shaders/common_colormanagement_lib.glsl new file mode 100644 index 00000000000..45f711296f3 --- /dev/null +++ b/source/blender/draw/modes/shaders/common_colormanagement_lib.glsl @@ -0,0 +1,30 @@ +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308) { + return (c < 0.0) ? 0.0 : c * 12.92; + } + else { + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; + } +} + +vec4 texture_read_as_linearrgb(sampler2D tex, bool premultiplied, vec2 co) +{ + /* By convention image textures return scene linear colors, but + * overlays still assume srgb. */ + vec4 color = texture(tex, co); + /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ + if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { + color.rgb = color.rgb / color.a; + } + return color; +} + +vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) +{ + vec4 color = texture_read_as_linearrgb(tex, premultiplied, co); + color.r = linearrgb_to_srgb(color.r); + color.g = linearrgb_to_srgb(color.g); + color.b = linearrgb_to_srgb(color.b); + return color; +} diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl index 6aa20a9d21b..b79bae45f23 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl @@ -65,7 +65,7 @@ vec4 EDIT_MESH_face_color(int face_flag) vec4 EDIT_MESH_facedot_color(float facedot_flag) { if (facedot_flag < 0.0f) { - return colorEditMeshActive; + return vec4(colorEditMeshActive.xyz, 1.0); } else if (facedot_flag > 0.0f) { return colorFaceDot; diff --git a/source/blender/draw/modes/shaders/object_camera_image_frag.glsl b/source/blender/draw/modes/shaders/object_camera_image_frag.glsl new file mode 100644 index 00000000000..5d8ad3c79ea --- /dev/null +++ b/source/blender/draw/modes/shaders/object_camera_image_frag.glsl @@ -0,0 +1,23 @@ +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform sampler2D image; +uniform float alpha; +uniform bool imagePremultiplied; + +void main() +{ +#ifdef DRW_STATE_DO_COLOR_MANAGEMENT + /* render engine has already applied the view transform. We sample the + * camera images as srgb*/ + vec4 color = texture_read_as_srgb(image, imagePremultiplied, texCoord_interp); + +#else + /* Render engine renders in linearrgb. We sample the camera images as + * linearrgb */ + vec4 color = texture_read_as_linearrgb(image, imagePremultiplied, texCoord_interp); +#endif + + color.a *= alpha; + fragColor = color; +} diff --git a/source/blender/draw/modes/shaders/object_camera_image_vert.glsl b/source/blender/draw/modes/shaders/object_camera_image_vert.glsl new file mode 100644 index 00000000000..61b88c013aa --- /dev/null +++ b/source/blender/draw/modes/shaders/object_camera_image_vert.glsl @@ -0,0 +1,18 @@ +uniform mat4 TransformMat; +uniform float flipX; +uniform float flipY; +uniform float depth; + +in vec2 texCoord; +in vec2 pos; + +out vec2 texCoord_interp; + +void main() +{ + vec4 position = TransformMat * vec4((pos - 0.5) * 2.0, 1.0, 1.0); + gl_Position = vec4(position.xy, depth, 1.0); + + vec2 uv_mul = vec2(flipX, flipY); + texCoord_interp = texCoord * uv_mul; +} diff --git a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl index 88220140aec..7dfbf469adc 100644 --- a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl +++ b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl @@ -15,31 +15,6 @@ uniform bool imagePremultiplied; uniform int depthMode; uniform bool useAlphaTest; -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * overlays still assume srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { #ifdef USE_WIRE diff --git a/source/blender/draw/modes/shaders/paint_texture_frag.glsl b/source/blender/draw/modes/shaders/paint_texture_frag.glsl index af7ea99e6a1..e8722590802 100644 --- a/source/blender/draw/modes/shaders/paint_texture_frag.glsl +++ b/source/blender/draw/modes/shaders/paint_texture_frag.glsl @@ -18,31 +18,6 @@ uniform vec3 maskingColor; uniform bool maskingInvertStencil; #endif -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * overlays still assume srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { vec2 uv = uv_interp; diff --git a/source/blender/draw/modes/shaders/pose_selection_vert.glsl b/source/blender/draw/modes/shaders/pose_selection_vert.glsl new file mode 100644 index 00000000000..2dd84c0a060 --- /dev/null +++ b/source/blender/draw/modes/shaders/pose_selection_vert.glsl @@ -0,0 +1,12 @@ + +in vec3 pos; + +void main() +{ + vec3 world_pos = point_object_to_world(pos); + gl_Position = point_world_to_ndc(world_pos); + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance(world_pos); +#endif +} diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index f4e1268ab77..b42e8102c5b 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -70,8 +70,18 @@ #define B_REDR 1 #define B_FMODIFIER_REDRAW 20 +/* callback to update depsgraph on value changes */ +static void deg_update(bContext *C, void *owner_id, void *UNUSED(var2)) +{ + /* send notifiers */ + /* XXX for now, this is the only way to get updates in all the right places... + * but would be nice to have a special one in this case. */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); + DEG_id_tag_update(owner_id, ID_RECALC_ANIMATION); +} + /* callback to verify modifier data */ -static void validate_fmodifier_cb(bContext *UNUSED(C), void *fcm_v, void *UNUSED(arg)) +static void validate_fmodifier_cb(bContext *C, void *fcm_v, void *owner_id) { FModifier *fcm = (FModifier *)fcm_v; const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); @@ -80,6 +90,9 @@ static void validate_fmodifier_cb(bContext *UNUSED(C), void *fcm_v, void *UNUSED if (fmi && fmi->verify_data) { fmi->verify_data(fcm); } + if (owner_id) { + deg_update(C, owner_id, NULL); + } } /* callback to remove the given modifier */ @@ -98,13 +111,8 @@ static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v) ED_undo_push(C, "Delete F-Curve Modifier"); - /* send notifiers */ - /* XXX for now, this is the only way to get updates in all the right places... - * but would be nice to have a special one in this case. */ - WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); - DEG_id_tag_update(ctx->fcurve_owner_id, ID_RECALC_ANIMATION); + deg_update(C, ctx->fcurve_owner_id, NULL); } - /* --------------- */ /* draw settings for generator modifier */ @@ -176,6 +184,7 @@ static void draw_modifier__generator(uiLayout *layout, /* draw polynomial order selector */ row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); + but = uiDefButI( block, UI_BTYPE_NUM, @@ -191,7 +200,7 @@ static void draw_modifier__generator(uiLayout *layout, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); - UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL); + UI_but_func_set(but, validate_fmodifier_cb, fcm, fcurve_owner_id); /* calculate maximum width of label for "x^n" labels */ if (data->arraysize > 2) { @@ -208,6 +217,9 @@ static void draw_modifier__generator(uiLayout *layout, row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); + /* Update depsgraph when values change */ + UI_block_func_set(block, deg_update, fcurve_owner_id, NULL); + cp = data->coefficients; for (i = 0; (i < data->arraysize) && (cp); i++, cp++) { /* To align with first line... */ @@ -310,6 +322,7 @@ static void draw_modifier__generator(uiLayout *layout, /* draw polynomial order selector */ row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); + but = uiDefButI( block, UI_BTYPE_NUM, @@ -325,12 +338,15 @@ static void draw_modifier__generator(uiLayout *layout, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); - UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL); + UI_but_func_set(but, validate_fmodifier_cb, fcm, fcurve_owner_id); /* draw controls for each pair of coefficients */ row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); + /* Update depsgraph when values change */ + UI_block_func_set(block, deg_update, fcurve_owner_id, NULL); + cp = data->coefficients; for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) { /* To align with first line */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 21a18a0b387..99843c66d0e 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -519,6 +519,9 @@ struct EDSelectID_Context *ED_view3d_select_id_context_create(struct ViewContext short select_mode); void ED_view3d_select_id_context_destroy(struct EDSelectID_Context *sel_id_ctx); +void ED_view3d_select_id_validate_view_matrices(const struct EDSelectID_Context *sel_id_ctx, + struct ViewContext *vc); + uint ED_view3d_select_id_context_offset_for_object_elem( const struct EDSelectID_Context *sel_id_ctx, int base_index, char elem_type); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 9612eab0025..697c289491a 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -6324,7 +6324,7 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) char *tmp = NULL; if (type == BUT_GET_LABEL) { - if (but->str) { + if (but->str && but->str[0]) { const char *str_sep; size_t str_len; @@ -6401,18 +6401,35 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } } } - else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { - MenuType *mt = UI_but_menutype_get(but); - if (mt) { - /* not all menus are from python */ - if (mt->ext.srna) { + else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { + { + MenuType *mt = UI_but_menutype_get(but); + if (mt) { + if (type == BUT_GET_RNA_LABEL) { + tmp = BLI_strdup(mt->label); + } + else { + /* Not all menus are from Python. */ + if (mt->ext.srna) { + const char *t = RNA_struct_ui_description(mt->ext.srna); + if (t && t[0]) { + tmp = BLI_strdup(t); + } + } + } + } + } + + if (tmp == NULL) { + PanelType *pt = UI_but_paneltype_get(but); + if (pt) { if (type == BUT_GET_RNA_LABEL) { - tmp = BLI_strdup(RNA_struct_ui_name(mt->ext.srna)); + tmp = BLI_strdup(pt->label); } else { - const char *t = RNA_struct_ui_description(mt->ext.srna); - if (t && t[0]) { - tmp = BLI_strdup(t); + /* Not all panels are from Python. */ + if (pt->ext.srna) { + /* Panels don't yet have descriptions, this may be added. */ } } } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 022c3b3cb51..7afdbe9d266 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1526,6 +1526,7 @@ static void ui_draw_colorband_handle(uint shdr_pos, immUniformArray4fv( "colors", (float *)(float[][4]){{0.8f, 0.8f, 0.8f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", active ? 4.0f : 2.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 2); immVertex2f(shdr_pos, x, y1); diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 9d1b6fc92fc..f10702f3f3b 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -608,6 +608,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) { + uiStringInfo but_label = {BUT_GET_LABEL, NULL}; uiStringInfo but_tip = {BUT_GET_TIP, NULL}; uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL}; @@ -623,6 +624,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) UI_but_string_info_get(C, but, + &but_label, &but_tip, &enum_label, &enum_tip, @@ -632,6 +634,17 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) &rna_prop, NULL); + /* Tip Label (only for buttons not already showing the label). + * Check prefix instead of comparing because the button may include the shortcut. */ + if (but_label.strinfo && !STRPREFIX(but->drawstr, but_label.strinfo)) { + uiTooltipField *field = text_field_add(data, + &(uiTooltipFormat){ + .style = UI_TIP_STYLE_HEADER, + .color_id = UI_TIP_LC_NORMAL, + }); + field->text = BLI_sprintfN("%s.", but_label.strinfo); + } + /* Tip */ if (but_tip.strinfo) { { @@ -844,6 +857,9 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } /* Free strinfo's... */ + if (but_label.strinfo) { + MEM_freeN(but_label.strinfo); + } if (but_tip.strinfo) { MEM_freeN(but_tip.strinfo); } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index d9ca58fa88c..c00223a3c49 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -500,6 +500,7 @@ static void mask_draw_curve_type(const bContext *C, immUniform1i("colors_len", 2); /* "advanced" mode */ immUniformArray4fv("colors", colors, 2); immUniform1f("dash_width", 4.0f); + immUniform1f("dash_factor", 0.5f); GPU_line_width(1.0f); mask_draw_array(pos, draw_method, points, tot_point); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 4f1154c02e3..a390cf67cf5 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -869,6 +869,8 @@ static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op)) WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); + return OPERATOR_FINISHED; } @@ -1709,7 +1711,7 @@ void OBJECT_OT_move_to_collection(wmOperatorType *ot) /* identifiers */ ot->name = "Move to Collection"; - ot->description = "Move objects to a scene collection"; + ot->description = "Move objects to a collection"; ot->idname = "OBJECT_OT_move_to_collection"; /* api callbacks */ diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 86144937844..394fea2cf27 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -53,6 +53,7 @@ #include "BKE_multires.h" #include "BKE_armature.h" #include "BKE_lattice.h" +#include "BKE_library.h" #include "BKE_tracking.h" #include "BKE_gpencil.h" @@ -460,11 +461,10 @@ void OBJECT_OT_origin_clear(wmOperatorType *ot) /* use this when the loc/size/rot of the parent has changed but the children * should stay in the same place, e.g. for apply-size-rot or object center */ -static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Object *ob) +static void ignore_parent_tx(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob) { Object workob; Object *ob_child; - Depsgraph *depsgraph = CTX_data_depsgraph(C); /* a change was made, adjust the children to compensate */ for (ob_child = bmain->objects.first; ob_child; ob_child = ob_child->id.next) { @@ -479,6 +479,55 @@ static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Objec } } +static void append_sorted_object_parent_hierarchy(Object *root_object, + Object *object, + Object **sorted_objects, + int *object_index) +{ + if (object->parent != NULL && object->parent != root_object) { + append_sorted_object_parent_hierarchy( + root_object, object->parent, sorted_objects, object_index); + } + if (object->id.tag & LIB_TAG_DOIT) { + sorted_objects[*object_index] = object; + (*object_index)++; + object->id.tag &= ~LIB_TAG_DOIT; + } +} + +static Object **sorted_selected_editable_objects(bContext *C, int *r_num_objects) +{ + Main *bmain = CTX_data_main(C); + + /* Count all objects, but also tag all the selected ones. */ + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + int num_objects = 0; + CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) { + object->id.tag |= LIB_TAG_DOIT; + num_objects++; + } + CTX_DATA_END; + if (num_objects == 0) { + *r_num_objects = 0; + return NULL; + } + + /* Append all the objects. */ + Object **sorted_objects = MEM_malloc_arrayN(num_objects, sizeof(Object *), "sorted objects"); + int object_index = 0; + CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) { + if ((object->id.tag & LIB_TAG_DOIT) == 0) { + continue; + } + append_sorted_object_parent_hierarchy(object, object, sorted_objects, &object_index); + } + CTX_DATA_END; + + *r_num_objects = num_objects; + + return sorted_objects; +} + static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_loc, @@ -622,7 +671,14 @@ static int apply_objects_internal(bContext *C, changed = false; /* now execute */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { + int num_objects; + Object **objects = sorted_selected_editable_objects(C, &num_objects); + if (objects == NULL) { + return OPERATOR_CANCELLED; + } + + for (int object_index = 0; object_index < num_objects; ++object_index) { + Object *ob = objects[object_index]; /* calculate rotation/scale matrix */ if (apply_scale && apply_rot) { @@ -793,13 +849,14 @@ static int apply_objects_internal(bContext *C, BKE_pose_where_is(depsgraph, scene, ob_eval); } - ignore_parent_tx(C, bmain, scene, ob); + ignore_parent_tx(bmain, depsgraph, scene, ob); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); changed = true; } - CTX_DATA_END; + + MEM_freeN(objects); if (!changed) { BKE_report(reports, RPT_WARNING, "Objects have no data to transform"); @@ -914,10 +971,6 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) const float *cursor = scene->cursor.location; int centermode = RNA_enum_get(op->ptr, "type"); - ListBase ctx_data_list; - CollectionPointerLink *ctx_ob; - CollectionPointerLink *ctx_ob_act = NULL; - /* keep track of what is changed */ int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0; @@ -986,23 +1039,24 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } - CTX_data_selected_editable_objects(C, &ctx_data_list); + int num_objects; + Object **objects = sorted_selected_editable_objects(C, &num_objects); + if (objects == NULL) { + return OPERATOR_CANCELLED; + } /* reset flags */ - for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { - Object *ob = ctx_ob->ptr.data; + for (int object_index = 0; object_index < num_objects; ++object_index) { + Object *ob = objects[object_index]; ob->flag &= ~OB_DONE; /* move active first */ if (ob == obact) { - ctx_ob_act = ctx_ob; + memmove(&objects[1], objects, object_index); + objects[0] = ob; } } - if (ctx_ob_act) { - BLI_listbase_rotate_first(&ctx_data_list, (LinkData *)ctx_ob_act); - } - for (tob = bmain->objects.first; tob; tob = tob->id.next) { if (tob->data) { ((ID *)tob->data)->tag &= ~LIB_TAG_DOIT; @@ -1012,8 +1066,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } - for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { - Object *ob = ctx_ob->ptr.data; + for (int object_index = 0; object_index < num_objects; ++object_index) { + Object *ob = objects[object_index]; if ((ob->flag & OB_DONE) == 0) { bool do_inverse_offset = false; @@ -1166,7 +1220,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) BKE_object_where_is_calc(depsgraph, scene, ob); BKE_pose_where_is(depsgraph, scene, ob); /* needed for bone parents */ - ignore_parent_tx(C, bmain, scene, ob); + ignore_parent_tx(bmain, depsgraph, scene, ob); if (obedit) { break; @@ -1288,7 +1342,6 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* offset other selected objects */ if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { - CollectionPointerLink *ctx_link_other; float obmat[4][4]; /* was the object data modified @@ -1305,16 +1358,15 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) BKE_pose_where_is(depsgraph, scene, ob); /* needed for bone parents */ } - ignore_parent_tx(C, bmain, scene, ob); + ignore_parent_tx(bmain, depsgraph, scene, ob); /* other users? */ // CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) //{ /* use existing context looper */ - for (ctx_link_other = ctx_data_list.first; ctx_link_other; - ctx_link_other = ctx_link_other->next) { - Object *ob_other = ctx_link_other->ptr.data; + for (int other_object_index = 0; other_object_index < num_objects; ++other_object_index) { + Object *ob_other = objects[other_object_index]; if ((ob_other->flag & OB_DONE) == 0 && ((ob->data && (ob->data == ob_other->data)) || @@ -1331,14 +1383,14 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* needed for bone parents */ BKE_pose_where_is(depsgraph, scene, ob_other); } - ignore_parent_tx(C, bmain, scene, ob_other); + ignore_parent_tx(bmain, depsgraph, scene, ob_other); } } // CTX_DATA_END; } } } - BLI_freelistN(&ctx_data_list); + MEM_freeN(objects); for (tob = bmain->objects.first; tob; tob = tob->id.next) { if (tob->data && (((ID *)tob->data)->tag & LIB_TAG_DOIT)) { diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 7506ad37908..dc634865a0a 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -778,7 +778,6 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, } ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd_eval = iter_data->edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); ParticleEditSettings *pset = PE_settings(data->scene); const int selected = iter_data->selected; float mat[4][4], imat[4][4]; @@ -794,7 +793,7 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global( - data->ob, mesh_final, psys->part->from, psys->particles + iter, mat); + data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); invert_m4_m4(imat, mat); } iter_data->func(data, mat, imat, iter, point->totkey - 1, key, mouse_distance); @@ -813,7 +812,7 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global( - data->ob, mesh_final, psys->part->from, psys->particles + iter, mat); + data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); invert_m4_m4(imat, mat); } iter_data->func(data, mat, imat, iter, k, key, mouse_distance); @@ -928,9 +927,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) psmd_eval = edit->psmd_eval; totpart = psys->totpart; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - - if (!mesh_final) { + if (!psmd_eval->mesh_final) { return; } @@ -940,7 +937,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, mesh_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); BLI_kdtree_3d_insert(tree, p, co); @@ -956,7 +953,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, mesh_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); co[0] = -co[0]; @@ -1087,9 +1084,8 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) edit = psys->edit; psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - if (!mesh_final) { + if (!psmd_eval->mesh_final) { return; } @@ -1106,7 +1102,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) LOOP_POINTS { if (point->flag & PEP_EDIT_RECALC) { - PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); if (edit->mirror_cache[p] != -1) { edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC; @@ -1156,8 +1152,8 @@ static void deflect_emitter_iter(void *__restrict iter_data_v, float *vec, *nor, dvec[3], dot, dist_1st = 0.0f; const float dist = iter_data->dist; const float emitterdist = iter_data->emitterdist; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - psys_mat_hair_to_object(object, mesh_final, psys->part->from, psys->particles + iter, hairmat); + psys_mat_hair_to_object( + object, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, hairmat); LOOP_KEYS { @@ -1221,8 +1217,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) psys = edit->psys; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(edit->psmd_eval); - if (!mesh_final) { + if (!edit->psmd_eval->mesh_final) { return; } @@ -1387,7 +1382,7 @@ void recalc_lengths(PTCacheEdit *edit) void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), ParticleSystem *psys) { PTCacheEdit *edit = psys->edit; - Mesh *mesh = BKE_particle_modifier_mesh_final_get(edit->psmd_eval); + Mesh *mesh = edit->psmd_eval->mesh_final; float *vec, *nor; int i, totface /*, totvert*/; @@ -1494,16 +1489,15 @@ void update_world_cos(Depsgraph *UNUSED(depsgraph), Object *ob, PTCacheEdit *edi KEY_K; float hairmat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - - if (psys == 0 || psys->edit == 0 || mesh_final == NULL) { + if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL) { return; } LOOP_POINTS { if (!(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, hairmat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, hairmat); } LOOP_KEYS @@ -2275,12 +2269,11 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, const data.is_changed |= PE_deselect_all_visible_ex(edit); } - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - LOOP_VISIBLE_POINTS { if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); } if (pset->selectmode == SCE_SELECT_POINT) { @@ -2746,11 +2739,10 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror) if (mirror) { /* mirror tags */ psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); LOOP_TAGGED_POINTS { - PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); } } @@ -2839,13 +2831,12 @@ static void remove_tagged_keys(Depsgraph *depsgraph, Object *ob, ParticleSystem ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); ParticleSystemModifierData *psmd_eval = (ParticleSystemModifierData *)modifier_get_evaluated( depsgraph, ob, &psmd->modifier); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); LOOP_POINTS { LOOP_TAGGED_KEYS { - PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); break; } } @@ -3072,8 +3063,6 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) psmd_eval = edit->psmd_eval; totremoved = 0; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - do { removed = 0; @@ -3082,7 +3071,8 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* insert particles into kd tree */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object(ob, mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_object( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); BLI_kdtree_3d_insert(tree, p, co); @@ -3093,7 +3083,8 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* tag particles to be removed */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object(ob, mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_object( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); @@ -3356,22 +3347,20 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(psmd_eval); - - if (!mesh_final) { + if (!psmd_eval->mesh_final) { return; } const bool use_dm_final_indices = (psys->part->use_modifier_stack && - !mesh_final->runtime.deformed_only); + !psmd_eval->mesh_final->runtime.deformed_only); /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */ BKE_mesh_tessface_ensure(me); /* NOTE: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. * Avoids an (impossible) mesh -> orig -> mesh tessface indices conversion. */ - mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? mesh_final : NULL); + mirrorfaces = mesh_get_x_mirror_faces( + ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL); if (!edit->mirror_cache) { PE_update_mirror_cache(ob, psys); @@ -3387,7 +3376,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) if (point_is_selected(point)) { if (edit->mirror_cache[p] != -1) { /* already has a mirror, don't need to duplicate */ - PE_mirror_particle(ob, mesh_final, psys, pa, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, NULL); continue; } else { @@ -3402,7 +3391,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } if (newtotpart != psys->totpart) { - MFace *mtessface = use_dm_final_indices ? mesh_final->mface : me->mface; + MFace *mtessface = use_dm_final_indices ? psmd_eval->mesh_final->mface : me->mface; /* allocate new arrays and copy existing */ new_pars = MEM_callocN(newtotpart * sizeof(ParticleData), "ParticleData new"); @@ -3478,7 +3467,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } else { newpa->num_dmcache = psys_particle_dm_face_lookup( - mesh_final, mesh_original, newpa->num, newpa->fuv, NULL); + psmd_eval->mesh_final, psmd_eval->mesh_original, newpa->num, newpa->fuv, NULL); } /* update edit key pointers */ @@ -3489,7 +3478,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } /* map key positions as mirror over x axis */ - PE_mirror_particle(ob, mesh_final, psys, pa, newpa); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, newpa); newpa++; newpoint++; @@ -4168,18 +4157,19 @@ static void brush_add_count_iter(void *__restrict iter_data_v, 0, 0, 0)) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(psmd_eval); - if (psys->part->use_modifier_stack && !mesh_final->runtime.deformed_only) { + if (psys->part->use_modifier_stack && !psmd_eval->mesh_final->runtime.deformed_only) { add_pars[iter].num = add_pars[iter].num_dmcache; add_pars[iter].num_dmcache = DMCACHE_ISCHILD; } - else if (iter_data->mesh == mesh_original) { + else if (iter_data->mesh == psmd_eval->mesh_original) { /* Final DM is not same topology as orig mesh, * we have to map num_dmcache to real final dm. */ add_pars[iter].num = add_pars[iter].num_dmcache; - add_pars[iter].num_dmcache = psys_particle_dm_face_lookup( - mesh_final, mesh_original, add_pars[iter].num, add_pars[iter].fuv, NULL); + add_pars[iter].num_dmcache = psys_particle_dm_face_lookup(psmd_eval->mesh_final, + psmd_eval->mesh_original, + add_pars[iter].num, + add_pars[iter].fuv, + NULL); } else { add_pars[iter].num = add_pars[iter].num_dmcache; @@ -4237,12 +4227,11 @@ static int brush_add(const bContext *C, PEData *data, short number) timestep = psys_get_timestep(&sim); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - if (psys->part->use_modifier_stack || mesh_final->runtime.deformed_only) { - mesh = mesh_final; + if (psys->part->use_modifier_stack || psmd_eval->mesh_final->runtime.deformed_only) { + mesh = psmd_eval->mesh_final; } else { - mesh = BKE_particle_modifier_mesh_original_get(psmd_eval); + mesh = psmd_eval->mesh_original; } BLI_assert(mesh); @@ -4326,7 +4315,7 @@ static int brush_add(const bContext *C, PEData *data, short number) tree = BLI_kdtree_3d_new(psys->totpart); for (i = 0, pa = psys->particles; i < totpart; i++, pa++) { - psys_particle_on_dm(mesh_final, + psys_particle_on_dm(psmd_eval->mesh_final, psys->part->from, pa->num, pa->num_dmcache, @@ -4383,7 +4372,7 @@ static int brush_add(const bContext *C, PEData *data, short number) int w, maxw; float maxd, totw = 0.0, weight[3]; - psys_particle_on_dm(mesh_final, + psys_particle_on_dm(psmd_eval->mesh_final, psys->part->from, pa->num, pa->num_dmcache, @@ -4461,7 +4450,7 @@ static int brush_add(const bContext *C, PEData *data, short number) } } for (k = 0, hkey = pa->hair; k < pset->totaddkey; k++, hkey++) { - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); mul_m4_v3(imat, hkey->co); } @@ -4662,7 +4651,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) } case PE_BRUSH_PUFF: { if (edit->psys) { - data.mesh = BKE_particle_modifier_mesh_final_get(psmd_eval); + data.mesh = psmd_eval->mesh_final; data.mval = mval; data.rad = pe_brush_size_get(scene, brush); data.select = selected; @@ -4719,7 +4708,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) } case PE_BRUSH_WEIGHT: { if (edit->psys) { - data.mesh = BKE_particle_modifier_mesh_final_get(psmd_eval); + data.mesh = psmd_eval->mesh_final; data.mval = mval; data.rad = pe_brush_size_get(scene, brush); @@ -5093,8 +5082,8 @@ int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3]) LOOP_VISIBLE_POINTS { if (psys) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); } LOOP_SELECTED_KEYS @@ -5135,8 +5124,7 @@ void PE_create_particle_edit( } /* no psmd->dm happens in case particle system modifier is not enabled */ - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - if (!(psys && psmd && mesh_final) && !cache) { + if (!(psys && psmd && psmd_eval->mesh_final) && !cache) { return; } diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index d85bf72851d..b03ec56c7e4 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -620,7 +620,6 @@ static void disconnect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, Part edit = psys->edit; point = edit ? edit->points : NULL; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { if (point) { @@ -628,7 +627,7 @@ static void disconnect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, Part point++; } - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat); for (k = 0, key = pa->hair; k < pa->totkey; k++, key++) { mul_m4_v3(hairmat, key->co); @@ -726,8 +725,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, float from_ob_imat[4][4], to_ob_imat[4][4]; float from_imat[4][4], to_imat[4][4]; - Mesh *target_mesh_final = BKE_particle_modifier_mesh_final_get(target_psmd); - if (!target_mesh_final) { + if (!target_psmd->mesh_final) { return false; } if (!psys->part || psys->part->type != PART_HAIR) { @@ -744,14 +742,14 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, invert_m4_m4(from_imat, from_mat); invert_m4_m4(to_imat, to_mat); - if (target_mesh_final->runtime.deformed_only) { + if (target_psmd->mesh_final->runtime.deformed_only) { /* we don't want to mess up target_psmd->dm when converting to global coordinates below */ - mesh = target_mesh_final; + mesh = target_psmd->mesh_final; } else { - mesh = BKE_particle_modifier_mesh_original_get(target_psmd); + mesh = target_psmd->mesh_original; } - target_mesh = target_mesh_final; + target_mesh = target_psmd->mesh_final; if (mesh == NULL) { return false; } @@ -1157,13 +1155,10 @@ static bool copy_particle_systems_to_object(const bContext *C, modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd); psmd->psys = psys; + BKE_id_copy_ex(NULL, &final_mesh->id, (ID **)&psmd->mesh_final, LIB_ID_COPY_LOCALIZE); - /* TODO(sergey): This should probably be accessing evaluated psmd. */ - ParticleSystemModifierDataRuntime *runtime = BKE_particle_modifier_runtime_ensure(psmd); - BKE_id_copy_ex(NULL, &final_mesh->id, (ID **)&runtime->mesh_final, LIB_ID_COPY_LOCALIZE); - - BKE_mesh_calc_normals(runtime->mesh_final); - BKE_mesh_tessface_ensure(runtime->mesh_final); + BKE_mesh_calc_normals(psmd->mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); if (psys_from->edit) { copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 9a46dab8c20..12891484e73 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -182,6 +182,7 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata) immUniformArray4fv( "colors", (float *)(float[][4]){{0.0f, 0.0f, 0.0f, alpha}, {1.0f, 1.0f, 1.0f, alpha}}, 2); immUniform1f("dash_width", 6.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 2); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 5a7fb1abb7b..ec7cb410f2c 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5807,6 +5807,7 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o } WM_cursor_wait(0); + WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 75a2af4526f..8c8d4487ada 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -459,6 +459,7 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + View3D *v3d = CTX_wm_view3d(C); Object *ob = OBACT(view_layer); Depsgraph *depsgraph = CTX_data_depsgraph(C); SculptSession *ss = ob->sculpt; @@ -560,7 +561,7 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) } } - tag_update |= ((Mesh *)ob->data)->id.us > 1; + tag_update |= ((Mesh *)ob->data)->id.us > 1 || !BKE_sculptsession_use_pbvh_draw(ob, v3d); if (ss->kb || ss->modifiers_active) { Mesh *mesh = ob->data; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 9b57644b6ec..86db6d50fcc 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -699,6 +699,7 @@ void draw_image_sample_line(SpaceImage *sima) immUniformArray4fv( "colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 2); immVertex2fv(shdr_dashed_pos, hist->co[0]); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index bdc6c394609..9eda7ffdc34 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -234,14 +234,6 @@ static bool image_not_packed_poll(bContext *C) return (ima && BLI_listbase_is_empty(&ima->packedfiles)); } -static bool imbuf_format_writeable(const ImBuf *ibuf) -{ - ImageFormatData im_format; - ImbFormatOptions options_dummy; - BKE_imbuf_to_image_format(&im_format, ibuf); - return (BKE_image_imtype_to_ftype(im_format.imtype, &options_dummy) == ibuf->ftype); -} - bool space_image_main_region_poll(bContext *C) { SpaceImage *sima = CTX_wm_space_image(C); @@ -2060,7 +2052,7 @@ static bool image_file_path_saveable(bContext *C, Image *ima, ImageUser *iuser) else if (!BLI_file_is_writable(name)) { CTX_wm_operator_poll_msg_set(C, "image path can't be written to"); } - else if (!imbuf_format_writeable(ibuf)) { + else if (!BKE_image_buffer_format_writable(ibuf)) { CTX_wm_operator_poll_msg_set(C, "image format is read-only"); } else { @@ -2254,9 +2246,9 @@ static bool image_should_be_saved_when_modified(Image *ima) return !ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE); } -static bool image_should_be_saved(Image *ima) +static bool image_should_be_saved(Image *ima, bool *is_format_writable) { - if (BKE_image_is_dirty(ima) && + if (BKE_image_is_dirty_writable(ima, is_format_writable) && (ima->source == IMA_SRC_FILE || ima->source == IMA_SRC_GENERATED)) { return image_should_be_saved_when_modified(ima); } @@ -2272,7 +2264,15 @@ static bool image_has_valid_path(Image *ima) bool ED_image_should_save_modified(const bContext *C) { - return ED_image_save_all_modified_info(C, NULL) > 0; + ReportList reports; + BKE_reports_init(&reports, RPT_STORE); + + uint modified_images_count = ED_image_save_all_modified_info(C, &reports); + bool should_save = modified_images_count || !BLI_listbase_is_empty(&reports.list); + + BKE_reports_clear(&reports); + + return should_save; } int ED_image_save_all_modified_info(const bContext *C, ReportList *reports) @@ -2283,7 +2283,9 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports) int num_saveable_images = 0; for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { - if (image_should_be_saved(ima)) { + bool is_format_writable; + + if (image_should_be_saved(ima, &is_format_writable)) { if (BKE_image_has_packedfile(ima) || (ima->source == IMA_SRC_GENERATED)) { if (ima->id.lib == NULL) { num_saveable_images++; @@ -2292,10 +2294,16 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports) BKE_reportf(reports, RPT_WARNING, "Packed library image: %s from library %s can't be saved", - ima->id.name, + ima->id.name + 2, ima->id.lib->name); } } + else if (!is_format_writable) { + BKE_reportf(reports, + RPT_WARNING, + "Image %s can't be saved automatically, must use a different file format", + ima->id.name + 2); + } else { if (image_has_valid_path(ima)) { num_saveable_images++; @@ -2313,7 +2321,7 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports) BKE_reportf(reports, RPT_WARNING, "Image %s can't be saved, no valid file path: %s", - ima->id.name, + ima->id.name + 2, ima->name); } } @@ -2332,11 +2340,13 @@ bool ED_image_save_all_modified(const bContext *C, ReportList *reports) bool ok = true; for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { - if (image_should_be_saved(ima)) { + bool is_format_writable; + + if (image_should_be_saved(ima, &is_format_writable)) { if (BKE_image_has_packedfile(ima) || (ima->source == IMA_SRC_GENERATED)) { BKE_image_memorypack(ima); } - else { + else if (is_format_writable) { if (image_has_valid_path(ima)) { ImageSaveOptions opts; Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index fed56f3d452..a151061ae64 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -31,6 +31,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_object_force_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -2207,6 +2208,9 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) else if (ob->empty_drawtype == OB_EMPTY_IMAGE) { data.icon = ICON_OUTLINER_OB_IMAGE; } + else if (ob->pd && ob->pd->forcefield) { + data.icon = ICON_OUTLINER_OB_FORCE_FIELD; + } else { data.icon = ICON_OUTLINER_OB_EMPTY; } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 525874c5939..b24f8e8d00f 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -625,13 +625,14 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad } } + if (op->customdata) { + MEM_freeN(op->customdata); + } + if (seq_load.tot_success == 0) { BKE_reportf(op->reports, RPT_ERROR, "File '%s' could not be loaded", seq_load.path); - return OPERATOR_CANCELLED; - } - if (op->customdata) { - MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; } BKE_sequencer_sort(scene); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index f1ee606a06b..e53a3cb02a7 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -38,12 +38,14 @@ #include "DNA_space_types.h" #include "DNA_userdef_types.h" #include "DNA_sound_types.h" +#include "DNA_anim_types.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_sequencer.h" #include "BKE_sound.h" #include "BKE_scene.h" +#include "BKE_fcurve.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" @@ -251,8 +253,10 @@ static void drawseqwave(View2D *v2d, float yscale = (y2 - y1) / 2.0f; float samplestep; float startsample, endsample; + float volume = seq->volume; float value1, value2; bSound *sound = seq->sound; + FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL); SoundWaveform *waveform; @@ -329,8 +333,12 @@ static void drawseqwave(View2D *v2d, value2 = (1.0f - f) * value2 + f * waveform->data[p * 3 + 4]; } - value1 *= seq->volume; - value2 *= seq->volume; + if (fcu) { + float evaltime = x1_offset + (i * stepsize); + volume = evaluate_fcurve(fcu, evaltime); + } + value1 *= volume; + value2 *= volume; if (value2 > 1 || value1 < -1) { immAttr4f(col, 1.0f, 0.0f, 0.0f, 0.5f); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 1bc21664287..12b446c3f4c 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -849,7 +849,7 @@ void ED_spacetype_sequencer(void) /* regions: listview/buttons */ art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_UI; - art->prefsizex = UI_SIDEBAR_PANEL_WIDTH; + art->prefsizex = UI_SIDEBAR_PANEL_WIDTH * 1.3f; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; art->listener = sequencer_buttons_region_listener; art->init = sequencer_buttons_region_init; diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 08ac0d91d42..386c3164843 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -301,341 +301,6 @@ uint *ED_view3d_select_id_read(int xmin, int ymin, int xmax, int ymax, uint *r_b return buf; } -/* ************************************************************* */ - -static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser) -{ - if (BKE_image_is_stereo(ima)) { - iuser->flag |= IMA_SHOW_STEREO; - - if ((scene->r.scemode & R_MULTIVIEW) == 0) { - iuser->multiview_eye = STEREO_LEFT_ID; - } - else if (v3d->stereo3d_camera != STEREO_3D_ID) { - /* show only left or right camera */ - iuser->multiview_eye = v3d->stereo3d_camera; - } - - BKE_image_multiview_index(ima, iuser); - } - else { - iuser->flag &= ~IMA_SHOW_STEREO; - } -} - -static void view3d_draw_bgpic(Scene *scene, - Depsgraph *depsgraph, - ARegion *ar, - View3D *v3d, - const bool do_foreground, - const bool do_camera_frame) -{ - RegionView3D *rv3d = ar->regiondata; - int fg_flag = do_foreground ? CAM_BGIMG_FLAG_FOREGROUND : 0; - if (v3d->camera == NULL || v3d->camera->type != OB_CAMERA) { - return; - } - Camera *cam = v3d->camera->data; - - for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) { - if ((bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != fg_flag) { - continue; - } - - { - float image_aspect[2]; - float x1, y1, x2, y2, centx, centy; - - void *lock; - - Image *ima = NULL; - - /* disable individual images */ - if ((bgpic->flag & CAM_BGIMG_FLAG_DISABLED)) { - continue; - } - - ImBuf *ibuf = NULL; - ImBuf *freeibuf = NULL; - ImBuf *releaseibuf = NULL; - if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { - ima = bgpic->ima; - if (ima == NULL) { - continue; - } - - ImageUser iuser = bgpic->iuser; - iuser.scene = scene; /* Needed for render results. */ - BKE_image_user_frame_calc(ima, &iuser, (int)DEG_get_ctime(depsgraph)); - if (ima->source == IMA_SRC_SEQUENCE && !(iuser.flag & IMA_USER_FRAME_IN_RANGE)) { - ibuf = NULL; /* frame is out of range, dont show */ - } - else { - view3d_stereo_bgpic_setup(scene, v3d, ima, &iuser); - ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock); - releaseibuf = ibuf; - } - - image_aspect[0] = ima->aspx; - image_aspect[1] = ima->aspy; - } - else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) { - /* TODO: skip drawing when out of frame range (as image sequences do above) */ - MovieClip *clip = NULL; - - if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) { - if (scene->camera) { - clip = BKE_object_movieclip_get(scene, scene->camera, true); - } - } - else { - clip = bgpic->clip; - } - - if (clip == NULL) { - continue; - } - - BKE_movieclip_user_set_frame(&bgpic->cuser, (int)DEG_get_ctime(depsgraph)); - ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser); - - image_aspect[0] = clip->aspx; - image_aspect[1] = clip->aspy; - - /* working with ibuf from image and clip has got different workflow now. - * ibuf acquired from clip is referenced by cache system and should - * be dereferenced after usage. */ - freeibuf = ibuf; - } - else { - /* perhaps when loading future files... */ - BLI_assert(0); - copy_v2_fl(image_aspect, 1.0f); - } - - if (ibuf == NULL) { - continue; - } - - if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { - /* invalid image format */ - if (freeibuf) { - IMB_freeImBuf(freeibuf); - } - if (releaseibuf) { - BKE_image_release_ibuf(ima, releaseibuf, lock); - } - - continue; - } - - if (ibuf->rect == NULL) { - IMB_rect_from_float(ibuf); - } - - BLI_assert(rv3d->persp == RV3D_CAMOB); - { - if (do_camera_frame) { - rctf vb; - ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &vb, false); - x1 = vb.xmin; - y1 = vb.ymin; - x2 = vb.xmax; - y2 = vb.ymax; - } - else { - x1 = ar->winrct.xmin; - y1 = ar->winrct.ymin; - x2 = ar->winrct.xmax; - y2 = ar->winrct.ymax; - } - - /* apply offset last - camera offset is different to offset in blender units */ - /* so this has some sane way of working - this matches camera's shift _exactly_ */ - { - const float max_dim = max_ff(x2 - x1, y2 - y1); - const float xof_scale = bgpic->offset[0] * max_dim; - const float yof_scale = bgpic->offset[1] * max_dim; - - x1 += xof_scale; - y1 += yof_scale; - x2 += xof_scale; - y2 += yof_scale; - } - - centx = (x1 + x2) * 0.5f; - centy = (y1 + y2) * 0.5f; - - /* aspect correction */ - if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) { - /* apply aspect from clip */ - const float w_src = ibuf->x * image_aspect[0]; - const float h_src = ibuf->y * image_aspect[1]; - - /* destination aspect is already applied from the camera frame */ - const float w_dst = x1 - x2; - const float h_dst = y1 - y2; - - const float asp_src = w_src / h_src; - const float asp_dst = w_dst / h_dst; - - if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { - if ((asp_src > asp_dst) == ((bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) != 0)) { - /* fit X */ - const float div = asp_src / asp_dst; - x1 = ((x1 - centx) * div) + centx; - x2 = ((x2 - centx) * div) + centx; - } - else { - /* fit Y */ - const float div = asp_dst / asp_src; - y1 = ((y1 - centy) * div) + centy; - y2 = ((y2 - centy) * div) + centy; - } - } - } - } - - /* complete clip? */ - rctf clip_rect; - BLI_rctf_init(&clip_rect, x1, x2, y1, y2); - if (bgpic->rotation) { - BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation); - } - - if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || - clip_rect.ymin > ar->winy) { - if (freeibuf) { - IMB_freeImBuf(freeibuf); - } - if (releaseibuf) { - BKE_image_release_ibuf(ima, releaseibuf, lock); - } - - continue; - } - - float zoomx = (x2 - x1) / ibuf->x; - float zoomy = (y2 - y1) / ibuf->y; - - /* For some reason; zoom-levels down refuses to use GL_ALPHA_SCALE. */ - if (zoomx < 1.0f || zoomy < 1.0f) { - float tzoom = min_ff(zoomx, zoomy); - int mip = 0; - - if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) { - IMB_remakemipmap(ibuf, 0); - ibuf->userflags &= ~IB_MIPMAP_INVALID; - } - else if (ibuf->mipmap[0] == NULL) { - IMB_makemipmap(ibuf, 0); - } - - while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) { - tzoom *= 2.0f; - zoomx *= 2.0f; - zoomy *= 2.0f; - mip++; - } - if (mip > 0) { - ibuf = ibuf->mipmap[mip - 1]; - } - } - - GPU_depth_test(!do_foreground); - glDepthMask(GL_FALSE); - - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - - GPU_matrix_push_projection(); - GPU_matrix_push(); - ED_region_pixelspace(ar); - - GPU_matrix_translate_2f(centx, centy); - GPU_matrix_scale_1f(bgpic->scale); - GPU_matrix_rotate_2d(RAD2DEGF(-bgpic->rotation)); - - if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) { - zoomx *= -1.0f; - x1 = x2; - } - if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) { - zoomy *= -1.0f; - y1 = y2; - } - - float col[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha}; - IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); - immDrawPixelsTex(&state, - x1 - centx, - y1 - centy, - ibuf->x, - ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_LINEAR, - ibuf->rect, - zoomx, - zoomy, - col); - - GPU_matrix_pop_projection(); - GPU_matrix_pop(); - - GPU_blend(false); - - glDepthMask(GL_TRUE); - GPU_depth_test(true); - - if (freeibuf) { - IMB_freeImBuf(freeibuf); - } - if (releaseibuf) { - BKE_image_release_ibuf(ima, releaseibuf, lock); - } - } - } -} - -void ED_view3d_draw_bgpic_test(Scene *scene, - Depsgraph *depsgraph, - ARegion *ar, - View3D *v3d, - const bool do_foreground, - const bool do_camera_frame) -{ - RegionView3D *rv3d = ar->regiondata; - - if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) { - Camera *cam = v3d->camera->data; - if ((cam->flag & CAM_SHOW_BG_IMAGE) == 0) { - return; - } - } - else { - return; - } - - /* disabled - mango request, since footage /w only render is quite useful - * and this option is easy to disable all background images at once */ -#if 0 - if (v3d->flag2 & V3D_HIDE_OVERLAYS) { - return; - } -#endif - - if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { - if (rv3d->persp == RV3D_CAMOB) { - view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame); - } - } - else { - view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame); - } -} - /* *********************** */ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 566a15cc7b7..ebfd66008f7 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -563,6 +563,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2); immUniform1f("dash_width", 6.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINE_STRIP, 3); @@ -725,6 +726,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2); immUniform1f("dash_width", 6.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 2); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c1b5b553c21..a694a8e7305 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -138,6 +138,9 @@ struct EDSelectID_Context { uint bases_len; /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */ uint base_array_index_len; + /** Used to check for changes. (Use depsgraph instead?). */ + float persmat[4][4]; + short select_mode; }; static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt) @@ -191,6 +194,14 @@ static void ed_select_id_draw_bases(struct EDSelectID_Context *sel_id_ctx, DRW_framebuffer_select_id_release(vc->ar); } +void ED_view3d_select_id_validate_view_matrices(const struct EDSelectID_Context *sel_id_ctx, + ViewContext *vc) +{ + if (!compare_m4m4(sel_id_ctx->persmat, vc->rv3d->persmat, FLT_EPSILON)) { + ed_select_id_draw_bases(sel_id_ctx, vc, sel_id_ctx->select_mode); + } +} + uint ED_view3d_select_id_context_offset_for_object_elem( const struct EDSelectID_Context *sel_id_ctx, int base_index, char elem_type) { @@ -223,7 +234,8 @@ struct EDSelectID_Context *ED_view3d_select_id_context_create(ViewContext *vc, __func__); sel_id_ctx->bases = bases; sel_id_ctx->bases_len = bases_len; - + copy_m4_m4(sel_id_ctx->persmat, vc->rv3d->persmat); + sel_id_ctx->select_mode = select_mode; ed_select_id_draw_bases(sel_id_ctx, vc, select_mode); return sel_id_ctx; @@ -3520,6 +3532,7 @@ static bool mesh_circle_select(ViewContext *vc, struct EditSelectBuf_Cache *esel = wm_userdata->data; if (use_zbuf) { + ED_view3d_select_id_validate_view_matrices(esel->sel_id_ctx, vc); const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index a9acdcd001c..1ed0d5e9221 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2424,8 +2424,8 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { ParticleSystemModifierData *psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + i, mat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat); } for (k = 0, key = point->keys; k < point->totkey; k++, key++) { @@ -2516,8 +2516,8 @@ void flushTransParticles(TransInfo *t) if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { ParticleSystemModifierData *psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + i, mat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat); invert_m4_m4(imat, mat); for (k = 0, key = point->keys; k < point->totkey; k++, key++) { diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index fa2a7eb9812..b1d22e12b10 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -117,6 +117,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) immUniformArray4fv( "colors", (float *)(float[][4]){{1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 8); @@ -137,6 +138,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) immUniformArray4fv( "colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 8); @@ -360,6 +362,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph * edges, "viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC); GPU_batch_uniform_1i(edges, "colors_len", 2); /* "advanced" mode */ GPU_batch_uniform_1f(edges, "dash_width", 4.0f); + GPU_batch_uniform_1f(edges, "dash_factor", 0.5f); GPU_batch_draw(edges); break; } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index bb73d61a139..14cdb674698 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1272,10 +1272,11 @@ static void uv_map_rotation_matrix_ex(float result[4][4], } /* but shifting */ - copy_v4_fl(viewmatrix[3], 0.0f); + zero_v3(viewmatrix[3]); /* get rotation of the current object matrix */ copy_m4_m4(rotobj, ob->obmat); + zero_v3(rotobj[3]); /* but shifting */ add_v4_v4(rotobj[3], offset); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 3fb7dfc6331..d5e763987cb 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -33,6 +33,8 @@ extern "C" { struct GPUVertBuf; struct Image; struct ImageUser; +struct MovieClip; +struct MovieClipUser; struct PreviewImage; struct rcti; @@ -189,6 +191,12 @@ GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode); GPUTexture *GPU_texture_from_blender(struct Image *ima, struct ImageUser *iuser, int textarget); GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap); +/* movie clip drawing */ +GPUTexture *GPU_texture_from_movieclip(struct MovieClip *clip, + struct MovieClipUser *cuser, + int textarget); +void GPU_free_texture_movieclip(struct MovieClip *clip); + void GPU_texture_add_mipmap(GPUTexture *tex, eGPUDataFormat gpu_data_format, int miplvl, diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 7813ae68371..f5d599eb647 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -59,6 +59,7 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_movieclip.h" #include "BKE_node.h" #include "BKE_scene.h" @@ -247,7 +248,7 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) * this allows us to use sRGB texture formats and preserves color values in * zero alpha areas, and appears generally closer to what game engines that we * want to be compatible with do. */ - const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL); + const bool store_premultiplied = ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true; IMB_colormanagement_imbuf_to_byte_texture( rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied); } @@ -256,14 +257,13 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) /* Float image is already in scene linear colorspace or non-color data by * convention, no colorspace conversion needed. But we do require 4 channels * currently. */ - const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT); + const bool store_premultiplied = ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false; if (ibuf->channels != 4 || !store_premultiplied) { rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__); if (rect_float == NULL) { return bindcode; } - IMB_colormanagement_imbuf_to_float_texture( rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); } @@ -291,6 +291,36 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) return bindcode; } +static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip, + MovieClipUser *cuser, + GLenum textarget) +{ + MovieClip_RuntimeGPUTexture *tex; + for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) { + if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) { + break; + } + } + + if (tex == NULL) { + tex = MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), __func__); + + for (int i = 0; i < TEXTARGET_COUNT; i++) { + tex->gputexture[i] = NULL; + } + + memcpy(&tex->user, cuser, sizeof(MovieClipUser)); + BLI_addtail(&clip->runtime.gputextures, tex); + } + + if (textarget == GL_TEXTURE_2D) + return &tex->gputexture[TEXTARGET_TEXTURE_2D]; + else if (textarget == GL_TEXTURE_CUBE_MAP) + return &tex->gputexture[TEXTARGET_TEXTURE_CUBE_MAP]; + + return NULL; +} + static void gpu_texture_update_scaled( uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h) { @@ -472,6 +502,52 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget return *tex; } +GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, MovieClipUser *cuser, int textarget) +{ + if (clip == NULL) { + return NULL; + } + + GPUTexture **tex = gpu_get_movieclip_gputexture(clip, cuser, textarget); + if (*tex) { + return *tex; + } + + /* check if we have a valid image buffer */ + uint bindcode = 0; + ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser); + if (ibuf == NULL) { + *tex = GPU_texture_from_bindcode(textarget, bindcode); + return *tex; + } + + bindcode = gpu_texture_create_from_ibuf(NULL, ibuf, textarget); + IMB_freeImBuf(ibuf); + + *tex = GPU_texture_from_bindcode(textarget, bindcode); + return *tex; +} + +void GPU_free_texture_movieclip(struct MovieClip *clip) +{ + /* number of gpu textures to keep around as cache + * We don't want to keep too many GPU textures for + * movie clips around, as they can be large.*/ + const int MOVIECLIP_NUM_GPUTEXTURES = 1; + + while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) { + MovieClip_RuntimeGPUTexture *tex = BLI_pophead(&clip->runtime.gputextures); + for (int i = 0; i < TEXTARGET_COUNT; i++) { + /* free glsl image binding */ + if (tex->gputexture[i]) { + GPU_texture_free(tex->gputexture[i]); + tex->gputexture[i] = NULL; + } + } + MEM_freeN(tex); + } +} + static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth) { size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 0d87ae09943..a81bff60146 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -882,24 +882,17 @@ enum { MOD_MDEF_SURFACE = 1, }; -/* Is stored in ModifierData.runtime. */ -# -# -typedef struct ParticleSystemModifierDataRuntime { +typedef struct ParticleSystemModifierData { + ModifierData modifier; + + struct ParticleSystem *psys; /** Final Mesh - its topology may differ from orig mesh. */ struct Mesh *mesh_final; /** Original mesh that particles are attached to. */ struct Mesh *mesh_original; int totdmvert, totdmedge, totdmface; -} ParticleSystemModifierDataRuntime; - -typedef struct ParticleSystemModifierData { - ModifierData modifier; - - struct ParticleSystem *psys; - void *_pad1; short flag; - char _pad[6]; + char _pad[2]; } ParticleSystemModifierData; typedef enum { diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index c804a78eccb..efda24d6e0e 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -57,6 +57,17 @@ typedef struct MovieClipProxy { short build_tc_flag; } MovieClipProxy; +typedef struct MovieClip_RuntimeGPUTexture { + void *next, *prev; + MovieClipUser user; + /** Not written in file 2 = TEXTARGET_COUNT. */ + struct GPUTexture *gputexture[2]; +} MovieClip_RuntimeGPUTexture; + +typedef struct MovieClip_Runtime { + struct ListBase gputextures; +} MovieClip_Runtime; + typedef struct MovieClip { ID id; /** Animation data (must be immediately after id for utilities to use it). */ @@ -111,6 +122,8 @@ typedef struct MovieClip { /* color management */ ColorManagedColorspaceSettings colorspace_settings; + + struct MovieClip_Runtime runtime; } MovieClip; typedef struct MovieClipScopes { diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c index 7cb1610fd31..bb236fc3ef4 100644 --- a/source/blender/makesrna/intern/rna_camera.c +++ b/source/blender/makesrna/intern/rna_camera.c @@ -231,12 +231,14 @@ static void rna_def_camera_background_image(BlenderRNA *brna) prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "offset"); RNA_def_property_ui_text(prop, "Offset", ""); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "scale"); RNA_def_property_ui_text(prop, "Scale", "Scale the background image"); RNA_def_property_range(prop, 0.0, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0, 10.0, 0.100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 8112231ed16..c1822b35f28 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -173,8 +173,7 @@ static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, for (md = ob->modifiers.first; md; md = md->next) { if (md->type == eModifierType_ParticleSystem) { psmd = (ParticleSystemModifierData *)md; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd && mesh_final && psmd->psys) { + if (psmd && psmd->mesh_final && psmd->psys) { psys = psmd->psys; for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { /* hairkeys are stored sequentially in memory, so we can @@ -209,8 +208,7 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu } else { float hairmat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); copy_v3_v3(values, hkey->co); mul_m4_v3(hairmat, values); } @@ -240,8 +238,7 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float float hairmat[4][4]; float imat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); copy_v3_v3(hkey->co, values); mul_m4_v3(imat, hkey->co); @@ -268,8 +265,8 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, } else { float hairmat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - psys_mat_hair_to_object(object, mesh_final, modifier->psys->part->from, particle, hairmat); + psys_mat_hair_to_object( + object, modifier->mesh_final, modifier->psys->part->from, particle, hairmat); copy_v3_v3(n_co, hairkey->co); mul_m4_v3(hairmat, n_co); } @@ -293,15 +290,14 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, int num = particle->num_dmcache; int from = modifier->psys->part->from; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); return; } - BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ if (num == DMCACHE_NOTFOUND) { - if (particle->num < mesh_final->totface) { + if (particle->num < modifier->mesh_final->totface) { num = particle->num; } } @@ -313,8 +309,8 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, MFace *mface; MTFace *mtface; - mface = mesh_final->mface; - mtface = mesh_final->mtface; + mface = modifier->mesh_final->mface; + mtface = modifier->mesh_final->mtface; if (mface && mtface) { mtface += num; @@ -443,10 +439,9 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys int totvert; int num = -1; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ - totface = mesh_final->totface; - totvert = mesh_final->totvert; + BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + totface = modifier->mesh_final->totface; + totvert = modifier->mesh_final->totvert; /* 1. check that everything is ok & updated */ if (!particlesystem || !totface) { @@ -479,7 +474,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = mesh_final->mface; + MFace *mface = modifier->mesh_final->mface; *r_fuv = &particle->fuv; @@ -522,7 +517,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = mesh_final->mface; + MFace *mface = modifier->mesh_final->mface; *r_fuv = &parent->fuv; @@ -550,13 +545,12 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, int uv_no, float r_uv[2]) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - if (mesh_final == NULL) { + if (modifier->mesh_final == NULL) { BKE_report(reports, RPT_ERROR, "Object was not yet evaluated"); zero_v2(r_uv); return; } - if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); zero_v2(r_uv); return; @@ -573,8 +567,9 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, zero_v2(r_uv); } else { - MFace *mface = &mesh_final->mface[num]; - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, uv_no); + MFace *mface = &modifier->mesh_final->mface[num]; + MTFace *mtface = (MTFace *)CustomData_get_layer_n( + &modifier->mesh_final->fdata, CD_MTFACE, uv_no); psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv); } @@ -589,8 +584,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, int vcol_no, float r_mcol[3]) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPCOL)) { BKE_report(reports, RPT_ERROR, "Mesh has no VCol data"); zero_v3(r_mcol); return; @@ -607,8 +601,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, zero_v3(r_mcol); } else { - MFace *mface = &mesh_final->mface[num]; - MCol *mc = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, vcol_no); + MFace *mface = &modifier->mesh_final->mface[num]; + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MCOL, vcol_no); MCol mcol; psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 4e7f9f51d12..8eaccfd1066 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1606,7 +1606,7 @@ static void rna_def_sequence(BlenderRNA *brna) prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_MUTE); - RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1); + RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, -1); RNA_def_property_ui_text( prop, "Mute", "Disable strip so that it cannot be viewed in the output"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_mute_update"); @@ -1957,6 +1957,12 @@ static void rna_def_filter_video(StructRNA *srna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem playback_direction_items[] = { + {0, "FORWARD", 0, "Forwards", "Play strip forwards"}, + {SEQ_REVERSE_FRAMES, "BACKWARD", 0, "Backwards", "Play strip backwards"}, + {0, NULL, 0, NULL, NULL}, + }; + prop = RNA_def_property(srna, "use_deinterlace", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_FILTERY); RNA_def_property_ui_text(prop, "Deinterlace", "Remove fields from video movies"); @@ -1983,9 +1989,10 @@ static void rna_def_filter_video(StructRNA *srna) RNA_def_property_ui_text(prop, "Convert Float", "Convert input to float data"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); - prop = RNA_def_property(srna, "use_reverse_frames", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_REVERSE_FRAMES); - RNA_def_property_ui_text(prop, "Flip Time", "Reverse frame order"); + prop = RNA_def_property(srna, "playback_direction", PROP_ENUM, PROP_NONE); /* as an enum */ + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, playback_direction_items); + RNA_def_property_ui_text(prop, "Playback Direction", "Play strip forwards or backwards"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); prop = RNA_def_property(srna, "color_multiply", PROP_FLOAT, PROP_UNSIGNED); @@ -2201,6 +2208,16 @@ static void rna_def_scene(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static const EnumPropertyItem scene_input_items[] = { + {0, "3D_CAMERA", ICON_VIEW3D, "3D Camera", "Use the Scene's 3D camera as input"}, + {SEQ_SCENE_STRIPS, + "SEQUENCE", + ICON_SEQUENCE, + "Sequence", + "Use the Scene's Sequencer timeline as input"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "SceneSequence", "Sequence"); RNA_def_struct_ui_text( srna, "Scene Sequence", "Sequence strip to used the rendered image of a scene"); @@ -2217,10 +2234,10 @@ static void rna_def_scene(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Camera Override", "Override the scenes active camera"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); - prop = RNA_def_property(srna, "use_sequence", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SCENE_STRIPS); - RNA_def_property_ui_text( - prop, "Use Sequence", "Use scenes sequence strips directly, instead of rendering"); + prop = RNA_def_property(srna, "scene_input", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, scene_input_items); + RNA_def_property_ui_text(prop, "Input", "Input type to use for the Scene strip"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_use_sequence"); prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE); @@ -2401,7 +2418,8 @@ static void rna_def_sound(BlenderRNA *brna) prop = RNA_def_property(srna, "show_waveform", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_AUDIO_DRAW_WAVEFORM); - RNA_def_property_ui_text(prop, "Display Waveform", "Display the audio waveform inside the clip"); + RNA_def_property_ui_text( + prop, "Display Waveform", "Display the audio waveform inside the strip"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); rna_def_input(srna); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 561cbb2ec3a..2b51b1eee97 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -985,7 +985,7 @@ static int rna_3DViewShading_type_get(PointerRNA *ptr) return shading->type; } else if (BKE_scene_uses_blender_workbench(scene)) { - return (shading->type == OB_MATERIAL) ? OB_RENDER : shading->type; + return (shading->type == OB_MATERIAL) ? OB_SOLID : shading->type; } else { if (shading->type == OB_RENDER && !(type && type->view_draw)) { @@ -5489,6 +5489,8 @@ static void rna_def_space_filebrowser(BlenderRNA *brna) RNA_def_struct_sdna(srna, "SpaceFile"); RNA_def_struct_ui_text(srna, "Space File Browser", "File browser space data"); + rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_UI)); + prop = RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "params"); RNA_def_property_ui_text( diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 9b1586f4982..4ed787810a8 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1125,7 +1125,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (psys->part == NULL || psys->particles == NULL) { return mesh; } - if (BKE_particle_modifier_mesh_final_get(psmd) == NULL) { + if (psmd->mesh_final == NULL) { return mesh; } diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index c61ebe0448c..c64d9be1158 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -185,7 +185,10 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes * accessible via MVert. For this reason we do not evaluate multires to * grids when orco is requested. */ const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0; - if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) { + /* Needed when rendering or baking will in sculpt mode. */ + const bool for_render = (ctx->flag & MOD_APPLY_RENDER) != 0; + + if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render) { /* NOTE: CCG takes ownership over Subdiv. */ result = multires_as_ccg(mmd, ctx, mesh, subdiv); result->runtime.subdiv_ccg_tot_level = mmd->totlvl; diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 651feb836cc..71913378277 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -415,11 +415,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes ChildParticle *cpa = psys->child + (p - psys->totpart); pa = psys->particles + (between ? cpa->pa[0] : cpa->parent); } - psys_mat_hair_to_global(sim.ob, - BKE_particle_modifier_mesh_final_get(sim.psmd), - sim.psys->part->from, - pa, - hairmat); + psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat); copy_m3_m4(mat, hairmat); /* to quaternion */ mat3_to_quat(frame, mat); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 02d477b1bde..5d7b380a751 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -23,8 +23,6 @@ #include <stddef.h> -#include "MEM_guardedalloc.h" - #include "BLI_utildefines.h" #include "DNA_material_types.h" @@ -44,27 +42,24 @@ static void initData(ModifierData *md) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; psmd->psys = NULL; + psmd->mesh_final = NULL; + psmd->mesh_original = NULL; + psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; } - -static void freeRuntimeData(void *runtime_data_v) -{ - if (runtime_data_v == NULL) { - return; - } - ParticleSystemModifierDataRuntime *runtime_data = runtime_data_v; - if (runtime_data->mesh_final) { - BKE_id_free(NULL, runtime_data->mesh_final); - } - if (runtime_data->mesh_original) { - BKE_id_free(NULL, runtime_data->mesh_original); - } - MEM_freeN(runtime_data); -} - static void freeData(ModifierData *md) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - freeRuntimeData(md->runtime); + + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_original) { + BKE_id_free(NULL, psmd->mesh_original); + psmd->mesh_original = NULL; + } + } + psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; + /* ED_object_modifier_remove may have freed this first before calling * modifier_free (which calls this function) */ if (psmd->psys) { @@ -72,6 +67,20 @@ static void freeData(ModifierData *md) } } +static void copyData(const ModifierData *md, ModifierData *target, const int flag) +{ +#if 0 + const ParticleSystemModifierData *psmd = (const ParticleSystemModifierData *)md; +#endif + ParticleSystemModifierData *tpsmd = (ParticleSystemModifierData *)target; + + modifier_copyData_generic(md, target, flag); + + tpsmd->mesh_final = NULL; + tpsmd->mesh_original = NULL; + tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0; +} + static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks) @@ -111,16 +120,14 @@ static void deformVerts(ModifierData *md, } } - ParticleSystemModifierDataRuntime *runtime = BKE_particle_modifier_runtime_ensure(psmd); - /* clear old dm */ - bool had_mesh_final = (runtime->mesh_final != NULL); - if (runtime->mesh_final) { - BKE_id_free(NULL, runtime->mesh_final); - runtime->mesh_final = NULL; - if (runtime->mesh_original) { - BKE_id_free(NULL, runtime->mesh_original); - runtime->mesh_original = NULL; + bool had_mesh_final = (psmd->mesh_final != NULL); + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_original) { + BKE_id_free(NULL, psmd->mesh_original); + psmd->mesh_original = NULL; } } else if (psmd->flag & eParticleSystemFlag_file_loaded) { @@ -136,13 +143,13 @@ static void deformVerts(ModifierData *md, } /* make new mesh */ - runtime->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false); - BKE_mesh_apply_vert_coords(runtime->mesh_final, vertexCos); - BKE_mesh_calc_normals(runtime->mesh_final); + psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false); + BKE_mesh_apply_vert_coords(psmd->mesh_final, vertexCos); + BKE_mesh_calc_normals(psmd->mesh_final); - BKE_mesh_tessface_ensure(runtime->mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); - if (!runtime->mesh_final->runtime.deformed_only) { + if (!psmd->mesh_final->runtime.deformed_only) { /* Get the original mesh from the object, this is what the particles * are attached to so in case of non-deform modifiers we need to remap * them to the final mesh (typically subdivision surfaces). */ @@ -153,7 +160,7 @@ static void deformVerts(ModifierData *md, if (em) { /* In edit mode get directly from the edit mesh. */ - runtime->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL); + psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL); } else { /* Otherwise get regular mesh. */ @@ -168,13 +175,13 @@ static void deformVerts(ModifierData *md, /* Make a persistent copy of the mesh. We don't actually need * all this data, just some topology for remapping. Could be * optimized once. */ - runtime->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false); + psmd->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false); } - BKE_mesh_tessface_ensure(runtime->mesh_original); + BKE_mesh_tessface_ensure(psmd->mesh_original); } - if (mesh_src != runtime->mesh_final && mesh_src != mesh) { + if (mesh_src != psmd->mesh_final && mesh_src != mesh) { BKE_id_free(NULL, mesh_src); } @@ -182,13 +189,13 @@ static void deformVerts(ModifierData *md, * This is an unreliable check for the topology check, but allows some * handy configuration like emitting particles from inside particle * instance. */ - if (had_mesh_final && (runtime->mesh_final->totvert != runtime->totdmvert || - runtime->mesh_final->totedge != runtime->totdmedge || - runtime->mesh_final->totface != runtime->totdmface)) { + if (had_mesh_final && (psmd->mesh_final->totvert != psmd->totdmvert || + psmd->mesh_final->totedge != psmd->totdmedge || + psmd->mesh_final->totface != psmd->totdmface)) { psys->recalc |= ID_RECALC_PSYS_RESET; - runtime->totdmvert = runtime->mesh_final->totvert; - runtime->totdmedge = runtime->mesh_final->totedge; - runtime->totdmface = runtime->mesh_final->totface; + psmd->totdmvert = psmd->mesh_final->totvert; + psmd->totdmedge = psmd->mesh_final->totedge; + psmd->totdmface = psmd->mesh_final->totface; } if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) { @@ -238,11 +245,12 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* structSize */ sizeof(ParticleSystemModifierData), /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | - eModifierTypeFlag_UsesPointCache, /* | + eModifierTypeFlag_UsesPointCache /* | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode */ + , - /* copyData */ modifier_copyData_generic, + /* copyData */ copyData, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, @@ -260,5 +268,5 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, /* foreachTexLink */ NULL, - /* freeRuntimeData */ freeRuntimeData, + /* freeRuntimeData */ NULL, }; diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c index a2c7c9099c1..b90483e89b9 100644 --- a/source/blender/python/generic/blf_py_api.c +++ b/source/blender/python/generic/blf_py_api.c @@ -468,7 +468,7 @@ static PyMethodDef BLF_methods[] = { {NULL, NULL, 0, NULL}, }; -PyDoc_STRVAR(BLF_doc, "This module provides access to blenders text drawing functions."); +PyDoc_STRVAR(BLF_doc, "This module provides access to Blender's text drawing functions."); static struct PyModuleDef BLF_module_def = { PyModuleDef_HEAD_INIT, "blf", /* m_name */ diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index a3dd8ef93f2..cbd57b28242 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -86,7 +86,7 @@ static PyStructSequence_Field app_info_fields[] = { {(char *)"version_char", (char *)"The Blender version character (for minor releases)"}, {(char *)"version_cycle", (char *)"The release status of this build alpha/beta/rc/release"}, {(char *)"binary_path", - (char *)"The location of blenders executable, useful for utilities that spawn new instances"}, + (char *)"The location of Blender's executable, useful for utilities that open new instances"}, {(char *)"background", (char *)"Boolean, True when blender is running without a user interface (started with -b)"}, {(char *)"factory_startup", diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c index cb79a1f7f93..1c48dc1baae 100644 --- a/source/blender/python/intern/bpy_interface_atexit.c +++ b/source/blender/python/intern/bpy_interface_atexit.c @@ -17,7 +17,7 @@ /** \file * \ingroup pythonintern * - * This file inserts an exit callback into pythons 'atexit' module. + * This file inserts an exit callback into Python's 'atexit' module. * Without this sys.exit() can crash because blender is not properly closing * resources. */ diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index 3de8e49dffd..5ea16c8c197 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -19,9 +19,9 @@ * * This file exposed blend file library appending/linking to python, typically * this would be done via RNA api but in this case a hand written python api - * allows us to use pythons context manager (__enter__ and __exit__). + * allows us to use Python's context manager (`__enter__` and `__exit__`). * - * Everything here is exposed via bpy.data.libraries.load(...) which returns + * Everything here is exposed via `bpy.data.libraries.load(...)` which returns * a context manager. */ diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 074d72f094f..ad7d5137ebc 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -2986,8 +2986,8 @@ PyDoc_STRVAR( " .. warning::\n" "\n" " There is a known bug with using a callback,\n" - " Python must keep a reference to the strings returned or Blender will misbehave\n" - " or even crash." + " Python must keep a reference to the strings returned by the callback or Blender\n" + " will misbehave or even crash." "\n" " :type items: sequence of string tuples or a function\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 8385bff0256..734e929fdf4 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -17,11 +17,11 @@ /** \file * \ingroup pythonintern * - * This file is the main interface between python and blenders data api (RNA), - * exposing RNA to python so blender data can be accessed in a python like way. + * This file is the main interface between Python and Blender's data api (RNA), + * exposing RNA to Python so blender data can be accessed in a Python like way. * - * The two main types are 'BPy_StructRNA' and 'BPy_PropertyRNA' - the base - * classes for most of the data python accesses in blender. + * The two main types are #BPy_StructRNA and #BPy_PropertyRNA - the base + * classes for most of the data Python accesses in blender. */ #include <Python.h> @@ -67,10 +67,10 @@ #include "BKE_report.h" #include "BKE_idprop.h" -/* only for types */ +/* Only for types. */ #include "BKE_node.h" -#include "../generic/idprop_py_api.h" /* for IDprop lookups */ +#include "../generic/idprop_py_api.h" /* For IDprop lookups. */ #include "../generic/py_capi_utils.h" #include "../generic/python_utildefines.h" @@ -86,7 +86,7 @@ static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self); #define BPY_DOC_ID_PROP_TYPE_NOTE \ " .. note::\n" \ "\n" \ - " Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and\n" \ + " Only the :class:`bpy.types.ID`, :class:`bpy.types.Bone` and\n" \ " :class:`bpy.types.PoseBone` classes support custom properties.\n" int pyrna_struct_validity_check(BPy_StructRNA *pysrna) @@ -119,7 +119,7 @@ void pyrna_invalidate(BPy_DummyPointerRNA *self) #ifdef USE_PYRNA_INVALIDATE_GC # define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1)) -/* only for sizeof() */ +/* Only for sizeof(). */ struct gc_generation { PyGC_Head head; int threshold; @@ -131,7 +131,7 @@ static void id_release_gc(struct ID *id) unsigned int j; // unsigned int i = 0; for (j = 0; j < 3; j++) { - /* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */ + /* Hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed. */ PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j)); PyGC_Head *g = gen->gc.gc_next; while ((g = g->gc.gc_next) != gen) { @@ -159,7 +159,7 @@ static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref); static PyMethodDef id_free_weakref_cb_def = { "id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL}; -/* adds a reference to the list, remember to decref */ +/* Adds a reference to the list, remember to decref. */ static GHash *id_weakref_pool_get(ID *id) { GHash *weakinfo_hash = NULL; @@ -168,13 +168,13 @@ static GHash *id_weakref_pool_get(ID *id) weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id); } else { - /* first time, allocate pool */ + /* First time, allocate pool. */ id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool"); weakinfo_hash = NULL; } if (weakinfo_hash == NULL) { - /* we're using a ghash as a set, could use libHX's HXMAP_SINGULAR but would be an extra dep. */ + /* We use a ghash as a set, we could use libHX's HXMAP_SINGULAR, but would be an extra dep. */ weakinfo_hash = BLI_ghash_ptr_new("rna_id"); BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash); } @@ -182,7 +182,7 @@ static GHash *id_weakref_pool_get(ID *id) return weakinfo_hash; } -/* called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject() */ +/* Called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject(). */ static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna) { PyObject *weakref; @@ -191,24 +191,25 @@ static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna) /* Create a new function instance and insert the list as 'self' * so we can remove ourself from it. */ - GHash *weakinfo_hash = id_weakref_pool_get(id); /* new or existing */ + GHash *weakinfo_hash = id_weakref_pool_get(id); /* New or existing. */ weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL); weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule); Py_DECREF(weakref_capsule); - /* add weakref to weakinfo_hash list */ + /* Add weakref to weakinfo_hash list. */ weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py); - Py_DECREF(weakref_cb_py); /* function owned by the weakref now */ + Py_DECREF(weakref_cb_py); /* Function owned by the weakref now. */ - /* important to add at the end, since first removal looks at the end */ - BLI_ghash_insert( - weakinfo_hash, weakref, id); /* using a hash table as a set, all 'id's are the same */ + /* Important to add at the end of the hash, since first removal looks at the end. */ + + /* Using a hash table as a set, all 'id's are the same. */ + BLI_ghash_insert(weakinfo_hash, weakref, id); /* weakinfo_hash owns the weakref */ } -/* workaround to get the last id without a lookup */ +/* Workaround to get the last id without a lookup. */ static ID *_id_tmp_ptr; static void value_id_set(void *id) { @@ -218,13 +219,13 @@ static void value_id_set(void *id) static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash); static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref) { - /* important to search backwards */ + /* Important to search backwards. */ GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL); if (BLI_ghash_len(weakinfo_hash) > 1) { BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL); } - else { /* get the last id and free it */ + else { /* Get the last id and free it. */ BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set); id_release_weakref_list(_id_tmp_ptr, weakinfo_hash); } @@ -310,7 +311,8 @@ static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) ID *id = ptr->id.data; if (id) { const short idcode = GS(id->name); - if (!ELEM(idcode, ID_WM, ID_SCR, ID_WS)) { /* may need more added here */ + /* May need more ID types added here. */ + if (!ELEM(idcode, ID_WM, ID_SCR, ID_WS)) { const char *idtype = BKE_idcode_to_name(idcode); const char *pyname; if (key && PyUnicode_Check(key)) { @@ -320,7 +322,7 @@ static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) pyname = "<UNKNOWN>"; } - /* make a nice string error */ + /* Make a nice string error. */ BLI_assert(idtype != NULL); PyErr_Format(PyExc_AttributeError, "Writing to ID classes in this context is not allowed: " @@ -354,7 +356,7 @@ bool pyrna_write_check(void) } void pyrna_write_set(bool UNUSED(val)) { - /* nothing */ + /* pass */ } #endif /* USE_PEDANTIC_WRITE */ @@ -365,7 +367,7 @@ static int pyrna_py_to_prop( static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item); #ifdef USE_MATHUTILS -# include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */ +# include "../mathutils/mathutils.h" /* So we can have mathutils callbacks. */ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, @@ -377,10 +379,10 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, const short order_fallback, PropertyRNA **r_prop_eul_order); -/* bpyrna vector/euler/quat callbacks */ -static unsigned char mathutils_rna_array_cb_index = -1; /* index for our callbacks */ +/* bpyrna vector/euler/quat callbacks. */ +static unsigned char mathutils_rna_array_cb_index = -1; /* Index for our callbacks. */ -/* subtype not used much yet */ +/* Subtype not used much yet. */ # define MATHUTILS_CB_SUBTYPE_EUL 0 # define MATHUTILS_CB_SUBTYPE_VEC 1 # define MATHUTILS_CB_SUBTYPE_QUAT 2 @@ -407,7 +409,7 @@ static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype) RNA_property_float_get_array(&self->ptr, self->prop, bmo->data); - /* Euler order exception */ + /* Euler order exception. */ if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { EulerObject *eul = (EulerObject *)bmo; PropertyRNA *prop_eul_order = NULL; @@ -456,7 +458,7 @@ static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype) RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); } - /* Euler order exception */ + /* Euler order exception. */ if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { EulerObject *eul = (EulerObject *)bmo; PropertyRNA *prop_eul_order = NULL; @@ -528,7 +530,7 @@ static Mathutils_Callback mathutils_rna_array_cb = { }; /* bpyrna matrix callbacks */ -static unsigned char mathutils_rna_matrix_cb_index = -1; /* index for our callbacks */ +static unsigned char mathutils_rna_matrix_cb_index = -1; /* Index for our callbacks. */ static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype)) { @@ -568,7 +570,7 @@ static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype)) return -1; } - /* can ignore clamping here */ + /* Can ignore clamping here. */ RNA_property_float_set_array(&self->ptr, self->prop, bmo->data); if (RNA_property_update_check(self->prop)) { @@ -589,14 +591,14 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, const short order_fallback, PropertyRNA **r_prop_eul_order) { - /* attempt to get order */ + /* Attempt to get order. */ if (*r_prop_eul_order == NULL) { *r_prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode"); } if (*r_prop_eul_order) { short order = RNA_property_enum_get(ptr, *r_prop_eul_order); - /* could be quat or axisangle */ + /* Could be quat or axisangle. */ if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) { return order; } @@ -607,8 +609,10 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, #endif /* USE_MATHUTILS */ -/* note that PROP_NONE is included as a vector subtype. this is because its handy to - * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. */ +/** + * Note that #PROP_NONE is included as a vector subtype. this is because it is handy to + * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. + */ #define PROP_ALL_VECTOR_SUBTYPES \ PROP_COORDS: \ case PROP_TRANSLATION: \ @@ -656,7 +660,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) { if (!is_thick) { - /* owned by the mathutils PyObject */ + /* Owned by the mathutils PyObject. */ ret = pyrna_prop_CreatePyObject(ptr, prop); } @@ -670,8 +674,8 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *vec_cb = Vector_CreatePyObject_cb( ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC); - Py_DECREF(ret); /* the vector owns now */ - ret = vec_cb; /* return the vector instead */ + Py_DECREF(ret); /* The vector owns 'ret' now. */ + ret = vec_cb; /* Return the vector instead. */ } } break; @@ -684,8 +688,8 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *mat_cb = Matrix_CreatePyObject_cb( ret, 4, 4, mathutils_rna_matrix_cb_index, 0); - Py_DECREF(ret); /* the matrix owns now */ - ret = mat_cb; /* return the matrix instead */ + Py_DECREF(ret); /* The matrix owns 'ret' now. */ + ret = mat_cb; /* Return the matrix instead. */ } } else if (len == 9) { @@ -696,30 +700,30 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *mat_cb = Matrix_CreatePyObject_cb( ret, 3, 3, mathutils_rna_matrix_cb_index, 0); - Py_DECREF(ret); /* the matrix owns now */ - ret = mat_cb; /* return the matrix instead */ + Py_DECREF(ret); /* The matrix owns 'ret' now. */ + ret = mat_cb; /* Return the matrix instead. */ } } break; case PROP_EULER: case PROP_QUATERNION: - if (len == 3) { /* euler */ + if (len == 3) { /* Euler. */ if (is_thick) { /* Attempt to get order, * only needed for thick types since wrapped with update via callbacks. */ PropertyRNA *prop_eul_order = NULL; short order = pyrna_rotation_euler_order_get(ptr, EULER_ORDER_XYZ, &prop_eul_order); - ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA */ + ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA. */ RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul); } else { - /* order will be updated from callback on use */ + /* Order will be updated from callback on use. */ // TODO, get order from RNA PyObject *eul_cb = Euler_CreatePyObject_cb( ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); - Py_DECREF(ret); /* the euler owns now */ - ret = eul_cb; /* return the euler instead */ + Py_DECREF(ret); /* The euler owns 'ret' now. */ + ret = eul_cb; /* Return the euler instead. */ } } else if (len == 4) { @@ -730,14 +734,14 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *quat_cb = Quaternion_CreatePyObject_cb( ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT); - Py_DECREF(ret); /* the quat owns now */ - ret = quat_cb; /* return the quat instead */ + Py_DECREF(ret); /* The quat owns 'ret' now. */ + ret = quat_cb; /* Return the quat instead. */ } } break; case PROP_COLOR: case PROP_COLOR_GAMMA: - if (len == 3) { /* color */ + if (len == 3) { /* Color. */ if (is_thick) { ret = Color_CreatePyObject(NULL, NULL); RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col); @@ -745,8 +749,8 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *col_cb = Color_CreatePyObject_cb( ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR); - Py_DECREF(ret); /* the color owns now */ - ret = col_cb; /* return the color instead */ + Py_DECREF(ret); /* The color owns 'ret' now. */ + ret = col_cb; /* Return the color instead. */ } } break; @@ -757,13 +761,13 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) if (ret == NULL) { if (is_thick) { - /* this is an array we cant reference (since its not thin wrappable) - * and cannot be coerced into a mathutils type, so return as a list */ + /* This is an array we can't reference (since it is not thin wrappable) + * and cannot be coerced into a mathutils type, so return as a list. */ thick_wrap_slice: ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len); } else { - ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */ + ret = pyrna_prop_CreatePyObject(ptr, prop); /* Owned by the mathutils PyObject. */ } } #else /* USE_MATHUTILS */ @@ -774,7 +778,9 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) return ret; } -/* same as RNA_enum_value_from_id but raises an exception */ +/** + * Same as #RNA_enum_value_from_id, but raises an exception. + */ int pyrna_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value, @@ -817,7 +823,7 @@ static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b) static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok = -1; /* zero is true */ + int ok = -1; /* Zero is true. */ if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) { ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b); @@ -848,7 +854,7 @@ static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op) static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok = -1; /* zero is true */ + int ok = -1; /* Zero is true. */ if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) { ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b); @@ -886,7 +892,7 @@ static PyObject *pyrna_struct_str(BPy_StructRNA *self) return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name); } - /* print name if available */ + /* Print name if available. */ name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL); if (name) { ret = PyUnicode_FromFormat( @@ -920,7 +926,7 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self) const char *path; path = RNA_path_from_ID_to_struct(&self->ptr); if (path) { - if (GS(id->name) == ID_NT) { /* nodetree paths are not accurate */ + if (GS(id->name) == ID_NT) { /* Nodetree paths are not accurate. */ ret = PyUnicode_FromFormat("bpy.data...%s", path); } else { @@ -930,7 +936,8 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self) MEM_freeN((void *)path); } - else { /* cant find, print something sane */ + else { + /* Can't find the path, print something useful as a fallback. */ ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", BKE_idcode_to_name_plural(GS(id->name)), tmp_str, @@ -957,12 +964,12 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) type = RNA_property_type(self->prop); if (RNA_enum_id_from_value(rna_enum_property_type_items, type, &type_id) == 0) { - PyErr_SetString(PyExc_RuntimeError, - "could not use property type, internal error"); /* should never happen */ + /* Should never happen. */ + PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); return NULL; } else { - /* this should never fail */ + /* This should never fail. */ int len = -1; char *c = type_fmt; @@ -981,7 +988,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) } } - /* if a pointer, try to print name of pointer target too */ + /* If a pointer, try to print name of pointer target too. */ if (type == PROP_POINTER) { ptr = RNA_property_pointer_get(&self->ptr, self->prop); name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL); @@ -1020,7 +1027,7 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, PYRNA_PROP_CHECK_OBJ(self); if (id == NULL) { - /* fallback */ + /* Fallback. */ return pyrna_prop_str(self); } @@ -1030,7 +1037,7 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, if (path) { const char *data_delim = (path[0] == '[') ? "" : "."; - if (GS(id->name) == ID_NT) { /* nodetree paths are not accurate */ + if (GS(id->name) == ID_NT) { /* Nodetree paths are not accurate. */ ret = PyUnicode_FromFormat("bpy.data...%s", path); } else { @@ -1043,7 +1050,8 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, MEM_freeN((void *)path); } - else { /* cant find, print something sane */ + else { + /* Can't find the path, print something useful as a fallback. */ ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", BKE_idcode_to_name_plural(GS(id->name)), tmp_str, @@ -1078,7 +1086,7 @@ static Py_hash_t pyrna_struct_hash(BPy_StructRNA *self) return _Py_HashPointer(self->ptr.data); } -/* from python's meth_hash v3.1.2 */ +/* From Python's meth_hash v3.1.2. */ static long pyrna_prop_hash(BPy_PropertyRNA *self) { long x, y; @@ -1116,7 +1124,7 @@ static int pyrna_struct_clear(BPy_StructRNA *self) } #endif /* !USE_PYRNA_STRUCT_REFERENCE */ -/* use our own dealloc so we can free a property if we use one */ +/* Use our own dealloc so we can free a property if we use one. */ static void pyrna_struct_dealloc(BPy_StructRNA *self) { #ifdef PYRNA_FREE_SUPPORT @@ -1139,7 +1147,7 @@ static void pyrna_struct_dealloc(BPy_StructRNA *self) } #endif /* !USE_PYRNA_STRUCT_REFERENCE */ - /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ + /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ Py_TYPE(self)->tp_free(self); } @@ -1150,7 +1158,7 @@ static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference) // PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */ pyrna_struct_clear(self); } - /* reference is now NULL */ + /* Reference is now NULL. */ if (reference) { self->reference = reference; @@ -1160,7 +1168,7 @@ static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference) } #endif /* !USE_PYRNA_STRUCT_REFERENCE */ -/* use our own dealloc so we can free a property if we use one */ +/* Use our own dealloc so we can free a property if we use one. */ static void pyrna_prop_dealloc(BPy_PropertyRNA *self) { #ifdef USE_WEAKREFS @@ -1168,7 +1176,7 @@ static void pyrna_prop_dealloc(BPy_PropertyRNA *self) PyObject_ClearWeakRefs((PyObject *)self); } #endif - /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ + /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ Py_TYPE(self)->tp_free(self); } @@ -1179,7 +1187,7 @@ static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self) PyObject_ClearWeakRefs((PyObject *)self); } #endif - /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ + /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ Py_TYPE(self)->tp_free(self); } @@ -1247,7 +1255,7 @@ BLI_bitmap *pyrna_set_to_enum_bitmap(const EnumPropertyItem *items, int bitmap_size, const char *error_prefix) { - /* set looping */ + /* Set looping. */ Py_ssize_t pos = 0; Py_ssize_t hash = 0; PyObject *key; @@ -1303,16 +1311,16 @@ error: return NULL; } -/* 'value' _must_ be a set type, error check before calling */ +/* 'value' _must_ be a set type, error check before calling. */ int pyrna_set_to_enum_bitfield(const EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix) { - /* set of enum items, concatenate all values with OR */ + /* Set of enum items, concatenate all values with OR. */ int ret, flag = 0; - /* set looping */ + /* Set looping. */ Py_ssize_t pos = 0; Py_ssize_t hash = 0; PyObject *key; @@ -1439,7 +1447,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) if (enum_item != DummyRNA_NULL_items) { const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL); - /* prefer not fail silently in case of api errors, maybe disable it later */ + /* Prefer not to fail silently in case of API errors, maybe disable it later. */ CLOG_WARN(BPY_LOG_RNA, "current value '%d' " "matches no enum in '%s', '%s', '%s'", @@ -1448,7 +1456,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) ptr_name, RNA_property_identifier(prop)); -#if 0 /* gives python decoding errors while generating docs :( */ +#if 0 /* Gives Python decoding errors while generating docs :( */ char error_str[256]; BLI_snprintf(error_str, sizeof(error_str), @@ -1487,7 +1495,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) return pyrna_py_from_array(ptr, prop); } - /* see if we can coerce into a python type - PropertyType */ + /* See if we can coerce into a Python type - 'PropertyType'. */ switch (type) { case PROP_BOOLEAN: ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop)); @@ -1506,7 +1514,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len); #ifdef USE_STRING_COERCE - /* only file paths get special treatment, they may contain non utf-8 chars */ + /* Only file paths get special treatment, they may contain non utf-8 chars. */ if (subtype == PROP_BYTESTRING) { ret = PyBytes_FromStringAndSize(buf, buf_len); } @@ -1561,7 +1569,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) /** * This function is used by operators and converting dicts into collections. - * Its takes keyword args and fills them with property values + * It takes keyword args and fills them with property values. */ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, @@ -1591,7 +1599,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, break; } - item = PyDict_GetItemString(kw, arg_name); /* wont set an error */ + item = PyDict_GetItemString(kw, arg_name); /* Wont set an error. */ if (item == NULL) { if (all_args) { @@ -1599,7 +1607,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, "%.200s: keyword \"%.200s\" missing", error_prefix, arg_name ? arg_name : "<UNKNOWN>"); - error_val = -1; /* pyrna_py_to_prop sets the error */ + error_val = -1; /* pyrna_py_to_prop sets the error. */ break; } } @@ -1613,7 +1621,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, } RNA_STRUCT_END; - if (error_val == 0 && totkw > 0) { /* some keywords were given that were not used :/ */ + if (error_val == 0 && totkw > 0) { /* Some keywords were given that were not used :/. */ PyObject *key, *value; Py_ssize_t pos = 0; @@ -1646,33 +1654,33 @@ static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func) static int pyrna_py_to_prop( PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) { - /* XXX hard limits should be checked here */ + /* XXX hard limits should be checked here. */ const int type = RNA_property_type(prop); if (RNA_property_array_check(prop)) { - /* done getting the length */ + /* Done getting the length. */ if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) { return -1; } } else { - /* Normal Property (not an array) */ + /* Normal Property (not an array). */ - /* see if we can coerce into a python type - PropertyType */ + /* See if we can coerce into a Python type - 'PropertyType'. */ switch (type) { case PROP_BOOLEAN: { int param; - /* prefer not to have an exception here + /* Prefer not to have an exception here * however so many poll functions return None or a valid Object. - * its a hassle to convert these into a bool before returning, */ + * It's a hassle to convert these into a bool before returning. */ if (RNA_parameter_flag(prop) & PARM_OUTPUT) { param = PyObject_IsTrue(value); } else { param = PyC_Long_AsI32(value); - if (UNLIKELY(param & ~1)) { /* only accept 0/1 */ - param = -1; /* error out below */ + if (UNLIKELY(param & ~1)) { /* Only accept 0/1. */ + param = -1; /* Error out below. */ } } @@ -1774,7 +1782,7 @@ static int pyrna_py_to_prop( } else if (subtype == PROP_BYTESTRING) { - /* Byte String */ + /* Byte String. */ param = PyBytes_AsString(value); @@ -1810,11 +1818,11 @@ static int pyrna_py_to_prop( } } else { - /* Unicode String */ + /* Unicode String. */ #ifdef USE_STRING_COERCE PyObject *value_coerce = NULL; if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { - /* TODO, get size */ + /* TODO, get size. */ param = PyC_UnicodeAsByte(value, &value_coerce); } else { @@ -1847,8 +1855,8 @@ static int pyrna_py_to_prop( return -1; } else { - /* same as bytes */ - /* XXX, this is suspect but needed for function calls, + /* Same as bytes. */ + /* XXX, this is suspect, but needed for function calls, * need to see if theres a better way. */ if (data) { *((char **)data) = (char *)param; @@ -1866,15 +1874,15 @@ static int pyrna_py_to_prop( case PROP_ENUM: { int val = 0; - /* type checkins is done by each function */ + /* Type checking is done by each function. */ if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { - /* set of enum items, concatenate all values with OR */ + /* Set of enum items, concatenate all values with OR. */ if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) { return -1; } } else { - /* simple enum string */ + /* Simple enum string. */ if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) { return -1; } @@ -1896,18 +1904,18 @@ static int pyrna_py_to_prop( int flag = RNA_property_flag(prop); int flag_parameter = RNA_parameter_flag(prop); - /* this is really nasty!, so we can fake the operator having direct properties eg: + /* This is really nasty! Done so we can fake the operator having direct properties, eg: * layout.prop(self, "filepath") - * ... which in fact should be + * ... which in fact should be: * layout.prop(self.properties, "filepath") * * we need to do this trick. * if the prop is not an operator type and the pyobject is an operator, - * use its properties in place of its self. + * use its properties in place of itself. * - * This is so bad that its almost a good reason to do away with fake + * This is so bad that it is almost a good reason to do away with fake * 'self.properties -> self' - * class mixing if this causes problems in the future it should be removed. + * class mixing. If this causes problems in the future it should be removed. */ if ((ptr_type == &RNA_AnyType) && (BPy_StructRNA_Check(value))) { const StructRNA *base_type = RNA_struct_base_child_of( @@ -1932,8 +1940,8 @@ static int pyrna_py_to_prop( } } - /* another exception, allow to pass a collection as an RNA property */ - if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* ok to ignore idprop collections */ + /* Another exception, allow to pass a collection as an RNA property. */ + if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* Ok to ignore idprop collections. */ PointerRNA c_ptr; BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value; if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) { @@ -1943,7 +1951,7 @@ static int pyrna_py_to_prop( else { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s collection has no type, " - "cant be used as a %.200s type", + "can't be used as a %.200s type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), @@ -1976,7 +1984,7 @@ static int pyrna_py_to_prop( else if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA *)value)->ptr.id.data)) { PyErr_Format(PyExc_TypeError, - "%.200s %.200s.%.200s ID type does not support assignment to its self", + "%.200s %.200s.%.200s ID type does not support assignment to itself", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop)); @@ -2002,8 +2010,8 @@ static int pyrna_py_to_prop( } else { /* For function calls, we sometimes want to pass the 'ptr' directly, - * watch out that it remains valid!, - * possibly we could support this later if needed. */ + * but watch out that it remains valid! + * We could possibly support this later if needed. */ BLI_assert(value_new == NULL); if (value == Py_None) { *((void **)data) = NULL; @@ -2027,7 +2035,7 @@ static int pyrna_py_to_prop( } } else { - /* data == NULL, assign to RNA */ + /* Data == NULL, assign to RNA. */ if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) { ReportList reports; BKE_reports_init(&reports, RPT_STORE); @@ -2046,7 +2054,7 @@ static int pyrna_py_to_prop( if (raise_error) { if (pyrna_struct_validity_check(param) == -1) { - /* error set */ + /* Error set. */ } else { PointerRNA tmp; @@ -2077,7 +2085,7 @@ static int pyrna_py_to_prop( lb = (data) ? (ListBase *)data : NULL; - /* convert a sequence of dict's into a collection */ + /* Convert a sequence of dict's into a collection. */ if (!PySequence_Check(value)) { PyErr_Format( PyExc_TypeError, @@ -2127,7 +2135,7 @@ static int pyrna_py_to_prop( } if (pyrna_pydict_to_props( - &itemptr, item, true, "Converting a python list to an RNA collection") == -1) { + &itemptr, item, true, "Converting a Python list to an RNA collection") == -1) { PyObject *msg = PyC_ExceptionBuffer(); const char *msg_char = _PyUnicode_AsString(msg); @@ -2158,7 +2166,7 @@ static int pyrna_py_to_prop( } } - /* Run rna property functions */ + /* Run RNA property functions. */ if (RNA_property_update_check(prop)) { RNA_property_update(BPy_GetContext(), ptr, prop); } @@ -2181,21 +2189,21 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P const int totdim = RNA_property_array_dimension(ptr, prop, NULL); if (totdim > 1) { - /* char error_str[512]; */ + // char error_str[512]; if (pyrna_py_to_array_index( &self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) { - /* error is set */ + /* Error is set. */ ret = -1; } } else { - /* see if we can coerce into a python type - PropertyType */ + /* See if we can coerce into a Python type - 'PropertyType'. */ switch (RNA_property_type(prop)) { case PROP_BOOLEAN: { int param = PyC_Long_AsBool(value); if (param == -1) { - /* error is set */ + /* Error is set. */ ret = -1; } else { @@ -2234,7 +2242,7 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P } } - /* Run rna property functions */ + /* Run RNA property functions. */ if (RNA_property_update_check(prop)) { RNA_property_update(BPy_GetContext(), ptr, prop); } @@ -2273,7 +2281,7 @@ static int pyrna_prop_array_bool(BPy_PropertyRNA *self) static int pyrna_prop_collection_bool(BPy_PropertyRNA *self) { - /* no callback defined, just iterate and find the nth item */ + /* No callback defined, just iterate and find the nth item. */ CollectionPropertyIterator iter; int test; @@ -2298,7 +2306,7 @@ static int pyrna_prop_collection_bool(BPy_PropertyRNA *self) } \ (void)0 -/* internal use only */ +/* Internal use only. */ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum) { PointerRNA newptr; @@ -2323,7 +2331,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s else { PyErr_Format(PyExc_RuntimeError, "bpy_prop_collection[index]: internal error, " - "valid index %d given in %d sized collection but value not found", + "valid index %d given in %d sized collection, but value not found", keynum_abs, len); } @@ -2332,7 +2340,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s } } -/* values type must have been already checked */ +/* Values type must have been already checked. */ static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value) @@ -2399,15 +2407,15 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname); return NULL; } -/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */ +// static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) /** * Special case: `bpy.data.objects["some_id_name", "//some_lib_name.blend"]` * also for: `bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)` * * \note - * error codes since this is not to be called directly from python, - * this matches pythons `__contains__` values capi. + * error codes since this is not to be called directly from Python, + * this matches Python's `__contains__` values C-API. * - -1: exception set * - 0: not found * - 1: found @@ -2420,7 +2428,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel { const char *keyname; - /* first validate the args, all we know is that they are a tuple */ + /* First validate the args, all we know is that they are a tuple. */ if (PyTuple_GET_SIZE(key) != 2) { PyErr_Format(PyExc_KeyError, "%s: tuple key must be a pair, not size %d", @@ -2480,7 +2488,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel * either way can do direct comparison with id.lib */ RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { - ID *id = itemptr.data; /* always an ID */ + ID *id = itemptr.data; /* Always an ID. */ if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) { found = true; if (r_ptr) { @@ -2491,14 +2499,14 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel } RNA_PROP_END; - /* we may want to fail silently as with collection.get() */ + /* We may want to fail silently as with collection.get(). */ if ((found == false) && err_not_found) { - /* only runs for getitem access so use fixed string */ + /* Only runs for getitem access so use fixed string. */ PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); return -1; } else { - return found; /* 1 / 0, no exception */ + return found; /* 1 / 0, no exception. */ } } } @@ -2534,11 +2542,11 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, list = PyList_New(0); - /* skip to start */ + /* Skip to start. */ RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); RNA_property_collection_skip(&rna_macro_iter, start); - /* add items until stop */ + /* Add items until stop. */ for (count = start; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr); PyList_APPEND(list, item); @@ -2554,8 +2562,8 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, return list; } -/* TODO - dimensions - * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower +/** TODO - dimensions + * \note Could also use pyrna_prop_array_to_py_index(self, count) in a loop, but it's much slower * since at the moment it reads (and even allocates) the entire array for each index. */ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, @@ -2568,7 +2576,7 @@ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, int count, totdim; PyObject *tuple; - /* isn't needed, internal use only */ + /* Isn't needed, internal use only. */ // PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); tuple = PyTuple_New(stop - start); @@ -2686,7 +2694,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject else { Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { return NULL; } @@ -2695,7 +2703,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject } if (start < 0 || stop < 0) { - /* only get the length for negative values */ + /* Only get the length for negative values. */ Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); if (start < 0) { start += len; @@ -2714,7 +2722,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject } } else if (PyTuple_Check(key)) { - /* special case, for ID datablocks we */ + /* Special case, for ID datablocks we. */ return pyrna_prop_collection_subscript_str_lib_pair( self, key, "bpy_prop_collection[id, lib]", true); } @@ -2741,7 +2749,7 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val return -1; } else { - return 0; /* None is OK */ + return 0; /* None is OK. */ } } else if (BPy_StructRNA_Check(value) == 0) { @@ -2762,7 +2770,7 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val return -1; } else { - return 0; /* OK, this is the correct type!*/ + return 0; /* OK, this is the correct type! */ } } @@ -2780,13 +2788,13 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, { PYRNA_PROP_CHECK_INT(self); - /* validate the assigned value */ + /* Validate the assigned value. */ if (value == NULL) { PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported"); return -1; } else if (pyrna_prop_collection_type_check(self, value) == -1) { - return -1; /* exception is set */ + return -1; /* Exception is set. */ } #if 0 @@ -2803,7 +2811,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, return pyrna_prop_collection_ass_subscript_int(self, i, value); } -#if 0 /* TODO, fake slice assignment */ +#if 0 /* TODO, fake slice assignment. */ else if (PySlice_Check(key)) { PySliceObject *key_slice = (PySliceObject *)key; Py_ssize_t step = 1; @@ -2821,7 +2829,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, else { Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { return NULL; } @@ -2830,7 +2838,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, } if (start < 0 || stop < 0) { - /* only get the length for negative values */ + /* Only get the length for negative values. */ Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); if (start < 0) { start += len; @@ -2887,7 +2895,7 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject return NULL; } else if (key_slice->start == Py_None && key_slice->stop == Py_None) { - /* note, no significant advantage with optimizing [:] slice as with collections + /* Note: no significant advantage with optimizing [:] slice as with collections, * but include here for consistency with collection slice func */ Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self); return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len); @@ -3038,7 +3046,7 @@ static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items } } -/* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */ +/* Could call `pyrna_py_to_prop_array_index(self, i, value)` in a loop, but it is slow. */ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int arraydim, @@ -3094,7 +3102,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) : values_stack; if (start != 0 || stop != length) { - /* partial assignment? - need to get the array */ + /* Partial assignment? - need to get the array. */ RNA_property_float_get_array(ptr, prop, values); } @@ -3122,7 +3130,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) : values_stack; if (start != 0 || stop != length) { - /* partial assignment? - need to get the array */ + /* Partial assignment? - need to get the array. */ RNA_property_int_get_array(ptr, prop, values); } @@ -3151,7 +3159,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, values_stack; if (start != 0 || stop != length) { - /* partial assignment? - need to get the array */ + /* Partial assignment? - need to get the array. */ RNA_property_boolean_get_array(ptr, prop, values); } @@ -3210,7 +3218,7 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value) { - /* char *keyname = NULL; */ /* not supported yet */ + // char *keyname = NULL; /* Not supported yet. */ int ret = -1; PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self); @@ -3240,14 +3248,14 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, ret = -1; } else if (slicelength <= 0) { - ret = 0; /* do nothing */ + ret = 0; /* Do nothing. */ } else if (step == 1) { ret = prop_subscript_ass_array_slice( &self->ptr, self->prop, self->arraydim, self->arrayoffset, start, stop, len, value); } else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); + PyErr_SetString(PyExc_TypeError, "slice steps not supported with RNA"); ret = -1; } } @@ -3265,7 +3273,7 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, return ret; } -/* for slice only */ +/* For slice only. */ static PyMappingMethods pyrna_prop_array_as_mapping = { (lenfunc)pyrna_prop_array_length, /* mp_length */ (binaryfunc)pyrna_prop_array_subscript, /* mp_subscript */ @@ -3278,7 +3286,7 @@ static PyMappingMethods pyrna_prop_collection_as_mapping = { (objobjargproc)pyrna_prop_collection_ass_subscript, /* mp_ass_subscript */ }; -/* only for fast bool's, large structs, assign nb_bool on init */ +/* Only for fast bool's, large structs, assign nb_bool on init. */ static PyNumberMethods pyrna_prop_array_as_number = { NULL, /* nb_add */ NULL, /* nb_subtract */ @@ -3311,16 +3319,16 @@ static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value) static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key) { - PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */ + PointerRNA newptr; /* Not used, just so RNA_property_collection_lookup_string runs. */ if (PyTuple_Check(key)) { - /* special case, for ID datablocks we */ + /* Special case, for ID data-blocks. */ return pyrna_prop_collection_subscript_str_lib_pair_ptr( self, key, "(id, lib) in bpy_prop_collection", false, NULL); } else { - /* key in dict style check */ + /* Key in dict style check. */ const char *keyname = _PyUnicode_AsString(key); if (keyname == NULL) { @@ -3393,7 +3401,7 @@ static PySequenceMethods pyrna_prop_collection_as_sequence = { }; static PySequenceMethods pyrna_struct_as_sequence = { - NULL, /* Cant set the len otherwise it can evaluate as false */ + NULL, /* Can't set the len otherwise it can evaluate as false */ NULL, /* sq_concat */ NULL, /* sq_repeat */ NULL, @@ -3408,7 +3416,7 @@ static PySequenceMethods pyrna_struct_as_sequence = { static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key) { - /* mostly copied from BPy_IDGroup_Map_GetItem */ + /* Mostly copied from BPy_IDGroup_Map_GetItem. */ IDProperty *group, *idprop; const char *name = _PyUnicode_AsString(key); @@ -3487,7 +3495,7 @@ static PyMappingMethods pyrna_struct_as_mapping = { PyDoc_STRVAR(pyrna_struct_keys_doc, ".. method:: keys()\n" "\n" - " Returns the keys of this objects custom properties (matches pythons\n" + " Returns the keys of this objects custom properties (matches Python's\n" " dictionary function of the same name).\n" "\n" " :return: custom property keys.\n" @@ -3514,7 +3522,7 @@ static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self) PyDoc_STRVAR(pyrna_struct_items_doc, ".. method:: items()\n" "\n" - " Returns the items of this objects custom properties (matches pythons\n" + " Returns the items of this objects custom properties (matches Python's\n" " dictionary function of the same name).\n" "\n" " :return: custom property key, value pairs.\n" @@ -3541,7 +3549,7 @@ static PyObject *pyrna_struct_items(BPy_PropertyRNA *self) PyDoc_STRVAR(pyrna_struct_values_doc, ".. method:: values()\n" "\n" - " Returns the values of this objects custom properties (matches pythons\n" + " Returns the values of this objects custom properties (matches Python's\n" " dictionary function of the same name).\n" "\n" " :return: custom property values.\n" @@ -3750,7 +3758,7 @@ PyDoc_STRVAR(pyrna_struct_path_resolve_doc, " :arg path: path which this property resolves.\n" " :type path: string\n" " :arg coerce: optional argument, when True, the property will be converted\n" - " into its python representation.\n" + " into its Python representation.\n" " :type coerce: boolean\n"); static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args) { @@ -3845,7 +3853,7 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args) if (path == NULL) { if (name) { PyErr_Format(PyExc_ValueError, - "%.200s.path_from_id(\"%s\") found but does not support path creation", + "%.200s.path_from_id(\"%s\") found, but does not support path creation", RNA_struct_identifier(self->ptr.type), name); } @@ -3895,7 +3903,7 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self) PyDoc_STRVAR(pyrna_prop_as_bytes_doc, ".. method:: as_bytes()\n" "\n" - " Returns this string property as a byte rather than a python string.\n" + " Returns this string property as a byte rather than a Python string.\n" "\n" " :return: The string as bytes.\n" " :rtype: bytes\n"); @@ -3934,7 +3942,7 @@ PyDoc_STRVAR(pyrna_prop_update_doc, "\n" " .. note::\n" " This is called when assigning a property,\n" - " however in rare cases its useful to call explicitly.\n"); + " however in rare cases it's useful to call explicitly.\n"); static PyObject *pyrna_prop_update(BPy_PropertyRNA *self) { RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); @@ -4085,7 +4093,7 @@ static void pyrna_dir_members_py(PyObject *list, PyObject *self) pyrna_dir_members_py__add_keys(list, dict); } - /* since this is least common case, handle it last */ + /* Since this is least common case, handle it last. */ if (BPy_PropertyRNA_Check(self)) { BPy_PropertyRNA *self_prop = (BPy_PropertyRNA *)self; if (RNA_property_type(self_prop->prop) == PROP_COLLECTION) { @@ -4105,7 +4113,7 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr) { const char *idname; - /* for looping over attrs and funcs */ + /* For looping over attrs and funcs. */ PointerRNA tptr; PropertyRNA *iterprop; @@ -4153,9 +4161,8 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self) PYRNA_STRUCT_CHECK_OBJ(self); - /* Include this in case this instance is a subtype of a python class - * In these instances we may want to return a function or variable provided by the subtype - * */ + /* Include this in case this instance is a subtype of a Python class + * In these instances we may want to return a function or variable provided by the subtype. */ ret = PyList_New(0); if (!BPy_StructRNA_CheckExact(self)) { @@ -4177,7 +4184,7 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self) { /* set(), this is needed to remove-doubles because the deferred - * register-props will be in both the python __dict__ and accessed as RNA */ + * register-props will be in both the Python __dict__ and accessed as RNA */ PyObject *set = PySet_New(ret); @@ -4204,9 +4211,9 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) ret = NULL; } else if ( - /* rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups */ + /* RNA can't start with a "_", so for __dict__ and similar we can skip using RNA lookups. */ name[0] == '_') { - /* annoying exception, maybe we need to have different types for this... */ + /* Annoying exception, maybe we need to have different types for this... */ if (STR_ELEM(name, "__getitem__", "__setitem__") && !RNA_struct_idprops_check(self->ptr.type)) { PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type"); @@ -4219,7 +4226,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) else if ((prop = RNA_struct_find_property(&self->ptr, name))) { ret = pyrna_prop_to_py(&self->ptr, prop); } - /* RNA function only if callback is declared (no optional functions) */ + /* RNA function only if callback is declared (no optional functions). */ else if ((func = RNA_struct_find_function(self->ptr.type, name)) && RNA_function_defined(func)) { ret = pyrna_func_to_py(&self->ptr, func); } @@ -4238,7 +4245,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) int done = CTX_data_get(C, name, &newptr, &newlb, &newtype); - if (done == 1) { /* found */ + if (done == 1) { /* Found. */ switch (newtype) { case CTX_DATA_TYPE_POINTER: if (newptr.data == NULL) { @@ -4260,7 +4267,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) break; } default: - /* should never happen */ + /* Should never happen. */ BLI_assert(!"Invalid context type"); PyErr_Format(PyExc_AttributeError, @@ -4271,12 +4278,12 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) break; } } - else if (done == -1) { /* found but not set */ + else if (done == -1) { /* Found, but not set. */ ret = Py_None; Py_INCREF(ret); } - else { /* not found in the context */ - /* lookup the subclass. raise an error if its not found */ + else { /* Not found in the context. */ + /* Lookup the subclass. raise an error if it's not found. */ ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } @@ -4288,11 +4295,11 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name); ret = NULL; #endif - /* Include this in case this instance is a subtype of a python class + /* Include this in case this instance is a subtype of a Python class * In these instances we may want to return a function or variable provided by the subtype * - * Also needed to return methods when its not a subtype - * */ + * Also needed to return methods when it's not a subtype. + */ /* The error raised here will be displayed */ ret = PyObject_GenericGetAttr((PyObject *)self, pyname); @@ -4342,7 +4349,7 @@ static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr PropertyRNA *prop = RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr)); if (prop) { PointerRNA tptr; - PyErr_Clear(); /* clear error from tp_getattro */ + PyErr_Clear(); /* Clear error from tp_getattro. */ RNA_pointer_create(NULL, &RNA_Property, prop, &tptr); ret = pyrna_struct_CreatePyObject(&tptr); } @@ -4371,7 +4378,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb } if (srna == NULL) { - /* allow setting on unregistered classes which can be registered later on */ + /* Allow setting on unregistered classes which can be registered later on. */ #if 0 if (value && is_deferred_prop) { PyErr_Format(PyExc_AttributeError, @@ -4380,31 +4387,31 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb return -1; } #endif - /* srna_from_self may set an error */ + /* srna_from_self may set an error. */ PyErr_Clear(); return PyType_Type.tp_setattro(cls, attr, value); } if (value) { - /* check if the value is a property */ + /* Check if the value is a property. */ if (is_deferred_prop) { int ret = deferred_register_prop(srna, attr, value); if (ret == -1) { - /* error set */ + /* Error set. */ return ret; } /* pass through and assign to the classes __dict__ as well - * when the value isn't assigned it still creates the RNA property - * but gets confusing from script writers POV if the assigned value cant be read back. */ + * so when the value isn't assigned it still creates the RNA property, + * but gets confusing from script writers POV if the assigned value can't be read back. */ } else { - /* remove existing property if its set or we also end up with confusion */ - RNA_def_property_free_identifier(srna, attr_str); /* ignore on failure */ + /* Remove existing property if it's set or we also end up with confusion. */ + RNA_def_property_free_identifier(srna, attr_str); /* Ignore on failure. */ } } else { /* __delattr__ */ - /* first find if this is a registered property */ + /* First find if this is a registered property. */ const int ret = RNA_def_property_free_identifier(srna, attr_str); if (ret == -1) { PyErr_Format( @@ -4413,7 +4420,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb } } - /* fallback to standard py, delattr/setattr */ + /* Fallback to standard py, delattr/setattr. */ return PyType_Type.tp_setattro(cls, attr, value); } @@ -4444,8 +4451,8 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject } } else if (self->ptr.type == &RNA_Context) { - /* Code just raises correct error, context prop's cant be set, - * unless its apart of the py class. */ + /* Code just raises correct error, context prop's can't be set, + * unless it's a part of the py class. */ bContext *C = self->ptr.data; if (C == NULL) { PyErr_Format(PyExc_AttributeError, @@ -4489,9 +4496,8 @@ static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self) PyObject *ret; PointerRNA r_ptr; - /* Include this in case this instance is a subtype of a python class - * In these instances we may want to return a function or variable provided by the subtype - * */ + /* Include this in case this instance is a subtype of a Python class + * In these instances we may want to return a function or variable provided by the subtype. */ ret = PyList_New(0); if (!BPy_PropertyRNA_CheckExact(self)) { @@ -4553,8 +4559,8 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject PyObject *ret = PyObject_GenericGetAttr((PyObject *)self, pyname); - if (ret == NULL && name[0] != '_') { /* avoid inheriting __call__ and similar */ - /* since this is least common case, handle it last */ + if (ret == NULL && name[0] != '_') { /* Avoid inheriting __call__ and similar. */ + /* Since this is least common case, handle it last. */ PointerRNA r_ptr; if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { PyObject *cls; @@ -4567,7 +4573,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject ret = PyObject_GenericGetAttr(cls, pyname); Py_DECREF(cls); - /* restore the original error */ + /* Restore the original error. */ if (ret == NULL) { PyErr_Restore(error_type, error_value, error_traceback); } @@ -4602,7 +4608,7 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam } else if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { if ((prop = RNA_struct_find_property(&r_ptr, name))) { - /* pyrna_py_to_prop sets its own exceptions */ + /* pyrna_py_to_prop sets its own exceptions. */ return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):"); } } @@ -4611,7 +4617,9 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam return -1; } -/* odd case, we need to be able return a python method from a tp_getset */ +/** + * Odd case, we need to be able return a Python method from a #PyTypeObject.tp_getset. + */ static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self) { PointerRNA r_ptr; @@ -4699,7 +4707,7 @@ PyDoc_STRVAR(pyrna_struct_get_id_data_doc, "all data types)"); static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self) { - /* used for struct and pointer since both have a ptr */ + /* Used for struct and pointer since both have a ptr. */ if (self->ptr.id.data) { PointerRNA id_ptr; RNA_id_pointer_create((ID *)self->ptr.id.data, &id_ptr); @@ -4767,7 +4775,7 @@ PyDoc_STRVAR(pyrna_prop_collection_keys_doc, ".. method:: keys()\n" "\n" " Return the identifiers of collection members\n" - " (matching pythons dict.keys() functionality).\n" + " (matching Python's dict.keys() functionality).\n" "\n" " :return: the identifiers for each member of this collection.\n" " :rtype: list of strings\n"); @@ -4797,7 +4805,7 @@ PyDoc_STRVAR(pyrna_prop_collection_items_doc, ".. method:: items()\n" "\n" " Return the identifiers of collection members\n" - " (matching pythons dict.items() functionality).\n" + " (matching Python's dict.items() functionality).\n" "\n" " :return: (key, value) pairs for each member of this collection.\n" " :rtype: list of tuples\n"); @@ -4811,7 +4819,7 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self) RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { if (itemptr.data) { - /* add to python list */ + /* Add to Python list. */ item = PyTuple_New(2); nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); if (nameptr) { @@ -4821,7 +4829,7 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self) } } else { - /* a bit strange but better then returning an empty list */ + /* A bit strange, but better then returning an empty list. */ PyTuple_SET_ITEM(item, 0, PyLong_FromLong(i)); } PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr)); @@ -4840,13 +4848,13 @@ PyDoc_STRVAR(pyrna_prop_collection_values_doc, ".. method:: values()\n" "\n" " Return the values of collection\n" - " (matching pythons dict.values() functionality).\n" + " (matching Python's dict.values() functionality).\n" "\n" " :return: the members of this collection.\n" " :rtype: list\n"); static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self) { - /* re-use slice*/ + /* Re-use slice. */ return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); } @@ -4854,7 +4862,7 @@ PyDoc_STRVAR(pyrna_struct_get_doc, ".. method:: get(key, default=None)\n" "\n" " Returns the value of the custom property assigned to key or default\n" - " when not found (matches pythons dictionary function of the same name).\n" + " when not found (matches Python's dictionary function of the same name).\n" "\n" " :arg key: The key associated with the custom property.\n" " :type key: string\n" @@ -4875,7 +4883,7 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args) return NULL; } - /* mostly copied from BPy_IDGroup_Map_GetItem */ + /* Mostly copied from BPy_IDGroup_Map_GetItem. */ if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); return NULL; @@ -4897,7 +4905,7 @@ PyDoc_STRVAR(pyrna_struct_pop_doc, ".. method:: pop(key, default=None)\n" "\n" " Remove and return the value of the custom property assigned to key or default\n" - " when not found (matches pythons dictionary function of the same name).\n" + " when not found (matches Python's dictionary function of the same name).\n" "\n" " :arg key: The key associated with the custom property.\n" " :type key: string\n" @@ -4918,7 +4926,7 @@ static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args) return NULL; } - /* mostly copied from BPy_IDGroup_Map_GetItem */ + /* Mostly copied from BPy_IDGroup_Map_GetItem. */ if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); return NULL; @@ -4945,7 +4953,7 @@ static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args) PyDoc_STRVAR(pyrna_struct_as_pointer_doc, ".. method:: as_pointer()\n" "\n" - " Returns the memory address which holds a pointer to blenders internal data\n" + " Returns the memory address which holds a pointer to Blender's internal data\n" "\n" " :return: int (memory address).\n" " :rtype: int\n" @@ -4961,7 +4969,7 @@ PyDoc_STRVAR(pyrna_prop_collection_get_doc, ".. method:: get(key, default=None)\n" "\n" " Returns the value of the item assigned to key or default when not found\n" - " (matches pythons dictionary function of the same name).\n" + " (matches Python's dictionary function of the same name).\n" "\n" " :arg key: The identifier for the collection member.\n" " :type key: string\n" @@ -5008,7 +5016,7 @@ PyDoc_STRVAR(pyrna_prop_collection_find_doc, ".. method:: find(key)\n" "\n" " Returns the index of a key in a collection or -1 when not found\n" - " (matches pythons string find function of the same name).\n" + " (matches Python's string find function of the same name).\n" "\n" " :arg key: The identifier for the collection member.\n" " :type key: string\n" @@ -5018,7 +5026,7 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key { Py_ssize_t key_len_ssize_t; const char *key = _PyUnicode_AsStringAndSize(key_ob, &key_len_ssize_t); - const int key_len = (int)key_len_ssize_t; /* comare with same type */ + const int key_len = (int)key_len_ssize_t; /* Comare with same type. */ char name[256], *nameptr; int namelen; @@ -5050,7 +5058,7 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key static bool foreach_attr_type(BPy_PropertyRNA *self, const char *attr, - /* values to assign */ + /* Values to assign. */ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed) @@ -5061,7 +5069,7 @@ static bool foreach_attr_type(BPy_PropertyRNA *self, *attr_tot = 0; *attr_signed = false; - /* note: this is fail with zero length lists, so don't let this get caled in that case */ + /* Note: this is fail with zero length lists, so don't let this get caled in that case. */ RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { prop = RNA_struct_find_property(&itemptr, attr); if (prop) { @@ -5079,11 +5087,11 @@ static bool foreach_attr_type(BPy_PropertyRNA *self, return attr_ok; } -/* pyrna_prop_collection_foreach_get/set both use this */ +/* pyrna_prop_collection_foreach_get/set both use this. */ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, - /* values to assign */ + /* Values to assign. */ const char **attr, PyObject **seq, int *tot, @@ -5113,7 +5121,8 @@ static int foreach_parse_args(BPy_PropertyRNA *self, return -1; } - *tot = PySequence_Size(*seq); /* TODO - buffer may not be a sequence! array.array() is tho. */ + /* TODO - buffer may not be a sequence! array.array() is though. */ + *tot = PySequence_Size(*seq); if (*tot > 0) { if (!foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed)) { @@ -5126,7 +5135,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, } *size = RNA_raw_type_sizeof(*raw_type); -#if 0 /* works fine but not strictly needed, \ +#if 0 /* Works fine, but not strictly needed. \ * we could allow RNA_property_collection_raw_* to do the checks */ if ((*attr_tot) < 1) { *attr_tot = 1; @@ -5141,7 +5150,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, target_tot = array_tot * (*attr_tot); - /* rna_access.c - rna_raw_access(...) uses this same method */ + /* rna_access.c - rna_raw_access(...) uses this same method. */ if (target_tot != (*tot)) { PyErr_Format(PyExc_TypeError, "foreach_get(attr, sequence) sequence length mismatch given %d, needed %d", @@ -5152,9 +5161,9 @@ static int foreach_parse_args(BPy_PropertyRNA *self, #endif } - /* Check 'attr_tot' otherwise we don't know if any values were set - * this isn't ideal because it means running on an empty list may - * fail silently when its not compatible. */ + /* Check 'attr_tot' otherwise we don't know if any values were set. + * This isn't ideal because it means running on an empty list may + * fail silently when it's not compatible. */ if (*size == 0 && *attr_tot != 0) { PyErr_SetString(PyExc_AttributeError, "attribute does not support foreach method"); return -1; @@ -5208,7 +5217,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) bool buffer_is_compat; void *array = NULL; - /* get/set both take the same args currently */ + /* Get/set both take the same args currently. */ const char *attr; PyObject *seq; int tot, size, attr_tot; @@ -5224,13 +5233,13 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) Py_RETURN_NONE; } - if (set) { /* get the array from python */ + if (set) { /* Get the array from python. */ buffer_is_compat = false; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); - /* check if the buffer matches */ + /* Check if the buffer matches. */ buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); @@ -5242,7 +5251,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) PyBuffer_Release(&buf); } - /* could not use the buffer, fallback to sequence */ + /* Could not use the buffer, fallback to sequence. */ if (!buffer_is_compat) { array = PyMem_Malloc(size * tot); @@ -5268,7 +5277,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) ((double *)array)[i] = (double)PyFloat_AsDouble(item); break; case PROP_RAW_UNSET: - /* should never happen */ + /* Should never happen. */ BLI_assert(!"Invalid array type - set"); break; } @@ -5286,7 +5295,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); - /* check if the buffer matches, TODO - signed/unsigned types */ + /* Check if the buffer matches, TODO - signed/unsigned types. */ buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); @@ -5298,7 +5307,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) PyBuffer_Release(&buf); } - /* could not use the buffer, fallback to sequence */ + /* Could not use the buffer, fallback to sequence. */ if (!buffer_is_compat) { array = PyMem_Malloc(size * tot); @@ -5306,7 +5315,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) NULL, &self->ptr, self->prop, attr, array, raw_type, tot); if (!ok) { - /* skip the loop */ + /* Skip the loop. */ i = tot; } @@ -5332,7 +5341,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) item = PyBool_FromLong((long)((bool *)array)[i]); break; default: /* PROP_RAW_UNSET */ - /* should never happen */ + /* Should never happen. */ BLI_assert(!"Invalid array type - get"); item = Py_None; Py_INCREF(item); @@ -5350,7 +5359,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) } if (PyErr_Occurred()) { - /* Maybe we could make our own error */ + /* Maybe we could make our own error. */ PyErr_Print(); PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence"); return NULL; @@ -5386,10 +5395,10 @@ static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObje } /* A bit of a kludge, make a list out of a collection or array, - * then return the lists iter function, not especially fast but convenient for now */ + * then return the list's iter function, not especially fast, but convenient for now. */ static PyObject *pyrna_prop_array_iter(BPy_PropertyArrayRNA *self) { - /* Try get values from a collection */ + /* Try get values from a collection. */ PyObject *ret; PyObject *iter = NULL; int len; @@ -5414,7 +5423,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self); #ifndef USE_PYRNA_ITER static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) { - /* Try get values from a collection */ + /* Try get values from a collection. */ PyObject *ret; PyObject *iter = NULL; ret = pyrna_prop_collection_values(self); @@ -5432,7 +5441,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) static struct PyMethodDef pyrna_struct_methods[] = { - /* only for PointerRNA's with ID'props */ + /* Only for PointerRNA's with ID'props. */ {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, pyrna_struct_keys_doc}, {"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, pyrna_struct_values_doc}, {"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, pyrna_struct_items_doc}, @@ -5581,7 +5590,7 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * } else if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) { /* this almost never runs, only when using user defined subclasses of built-in object. - * this isn't common since its NOT related to registerable subclasses. eg: + * this isn't common since it's NOT related to registerable subclasses. eg: * * >>> class MyObSubclass(bpy.types.Object): * ... def test_func(self): @@ -5597,11 +5606,11 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) { ret->ptr = base->ptr; } - /* pass on exception & NULL if tp_alloc fails */ + /* Pass on exception & NULL if tp_alloc fails. */ return (PyObject *)ret; } - /* error, invalid type given */ + /* Error, invalid type given. */ PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct", type->tp_name); @@ -5659,9 +5668,9 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat len = RNA_property_array_length(ptr, prop); } - /* resolve the array from a new pytype */ + /* Resolve the array from a new pytype. */ - /* kazanbas: TODO make multidim sequences here */ + /* TODO(Kazanbas) make multi-dimensional sequences here. */ switch (type) { case PROP_BOOLEAN: @@ -5709,7 +5718,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat } } else { - /* see if we can coerce into a python type - PropertyType */ + /* See if we can coerce into a python type - PropertyType. */ switch (type) { case PROP_BOOLEAN: ret = PyBool_FromLong(*(bool *)data); @@ -5766,7 +5775,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat StructRNA *ptype = RNA_property_pointer_type(ptr, prop); if (flag_parameter & PARM_RNAPTR) { - /* in this case we get the full ptr */ + /* In this case we get the full ptr. */ newptr = *(PointerRNA *)data; } else { @@ -5813,9 +5822,11 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat return ret; } -/* Use to replace PyDict_GetItemString() when the overhead of converting a - * string into a python unicode is higher than a non hash lookup. - * works on small dict's such as keyword args. */ +/** + * Use to replace PyDict_GetItemString() when the overhead of converting a + * string into a Python unicode is higher than a non hash lookup. + * works on small dict's such as keyword args. + */ static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_lookup) { PyObject *key = NULL; @@ -5835,7 +5846,7 @@ static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_look static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw) { - /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */ + /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here. */ PointerRNA *self_ptr = &self->ptr; FunctionRNA *self_func = self->func; @@ -5858,24 +5869,24 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject PyObject *string_free_ls = PyList_New(0); #endif - /* Should never happen but it does in rare cases */ + /* Should never happen, but it does in rare cases. */ BLI_assert(self_ptr != NULL); if (self_ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, - "rna functions internal rna pointer is NULL, this is a bug. aborting"); + "RNA functions internal RNA pointer is NULL, this is a bug. aborting"); return NULL; } if (self_func == NULL) { PyErr_Format( PyExc_RuntimeError, - "%.200s.<unknown>(): rna function internal function is NULL, this is a bug. aborting", + "%.200s.<unknown>(): RNA function internal function is NULL, this is a bug. aborting", RNA_struct_identifier(self_ptr->type)); return NULL; } - /* for testing */ + /* For testing. */ #if 0 { const char *fn; @@ -5913,12 +5924,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject err = -1; } - /* parse function parameters */ + /* Parse function parameters. */ for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) { parm = iter.parm; flag_parameter = RNA_parameter_flag(parm); - /* only useful for single argument returns, we'll need another list loop for multiple */ + /* Only useful for single argument returns, we'll need another list loop for multiple. */ if (flag_parameter & PARM_OUTPUT) { ret_len++; if (pret_single == NULL) { @@ -5932,7 +5943,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject item = NULL; if (i < pyargs_len) { - /* New in 2.8x, optional arguments must be keywords. */ + /* New in 2.8x, optional arguments must be keywords. */ if (UNLIKELY((flag_parameter & PARM_REQUIRED) == 0)) { PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): required parameter \"%.200s\" to be a keyword argument!", @@ -5948,18 +5959,18 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject } else if (kw != NULL) { #if 0 - item = PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* borrow ref */ + item = PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* Borrow reference. */ #else - item = small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* borrow ref */ + item = small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* Borrow reference. */ #endif if (item) { - kw_tot++; /* make sure invalid keywords are not given */ + kw_tot++; /* Make sure invalid keywords are not given. */ } kw_arg = true; } - i++; /* current argument */ + i++; /* Current argument. */ if (item == NULL) { if (flag_parameter & PARM_REQUIRED) { @@ -5971,7 +5982,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject err = -1; break; } - else { /* PyDict_GetItemString wont raise an error */ + else { /* PyDict_GetItemString wont raise an error. */ continue; } } @@ -5989,7 +6000,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject /* the error generated isn't that useful, so generate it again with a useful prefix * could also write a function to prepend to error messages */ char error_prefix[512]; - PyErr_Clear(); /* re-raise */ + PyErr_Clear(); /* Re-raise. */ if (kw_arg == true) { BLI_snprintf(error_prefix, @@ -6018,8 +6029,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject RNA_parameter_list_end(&iter); /* Check if we gave args that don't exist in the function - * printing the error is slow but it should only happen when developing. - * the if below is quick, checking if it passed less keyword args then we gave. + * Printing the error is slow, but it should only happen when developing. + * The "if" below is quick check to make sure less keyword args were passed then we gave. * (Don't overwrite the error if we have one, * otherwise can skip important messages and confuse with args). */ @@ -6038,11 +6049,11 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject arg_name = _PyUnicode_AsString(key); found = false; - if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/ + if (arg_name == NULL) { /* Unlikely the argname is not a string, but ignore if it is. */ PyErr_Clear(); } else { - /* Search for arg_name */ + /* Search for arg_name. */ RNA_parameter_list_begin(&parms, &iter); for (; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; @@ -6061,7 +6072,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject } } - /* list good args */ + /* List good args. */ first = true; RNA_parameter_list_begin(&parms, &iter); @@ -6097,7 +6108,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject ret = NULL; if (err == 0) { - /* call function */ + /* Call function. */ ReportList reports; bContext *C = BPy_GetContext(); @@ -6106,12 +6117,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); - /* return value */ + /* Return value. */ if (err != -1) { if (ret_len > 0) { if (ret_len > 1) { ret = PyTuple_New(ret_len); - i = 0; /* arg index */ + i = 0; /* Arg index. */ RNA_parameter_list_begin(&parms, &iter); @@ -6129,7 +6140,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single); } - /* possible there is an error in conversion */ + /* Possible there is an error in conversion. */ if (ret == NULL) { err = -1; } @@ -6150,7 +6161,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject # undef DEBUG_STRING_FREE #endif - /* cleanup */ + /* Cleanup. */ RNA_parameter_list_end(&iter); RNA_parameter_list_free(&parms); @@ -6183,7 +6194,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure) return ret; } -/* subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass */ +/* Subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass. */ /* note: tp_base member is set to &PyType_Type on init */ PyTypeObject pyrna_struct_meta_idprop_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct_meta_idprop", /* tp_name */ @@ -6198,7 +6209,7 @@ PyTypeObject pyrna_struct_meta_idprop_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* deprecated in python 3.0! */ + /* tp_compare */ /* deprecated in Python 3.0! */ NULL, /* tp_repr */ /* Method suites for standard classes */ @@ -6279,7 +6290,7 @@ PyTypeObject pyrna_struct_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ (reprfunc)pyrna_struct_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -6368,7 +6379,7 @@ PyTypeObject pyrna_prop_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ (reprfunc)pyrna_prop_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -6452,7 +6463,7 @@ PyTypeObject pyrna_prop_array_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ (reprfunc)pyrna_prop_array_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -6535,7 +6546,7 @@ PyTypeObject pyrna_prop_collection_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ NULL, /* subclassed */ /* tp_repr */ @@ -6621,7 +6632,7 @@ static PyTypeObject pyrna_prop_collection_idprop_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ NULL, /* subclassed */ /* tp_repr */ @@ -6707,7 +6718,7 @@ PyTypeObject pyrna_func_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ (reprfunc)pyrna_func_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -6783,7 +6794,7 @@ PyTypeObject pyrna_func_Type = { #ifdef USE_PYRNA_ITER /* --- collection iterator: start --- */ -/* wrap rna collection iterator functions */ +/* wrap RNA collection iterator functions */ /* * RNA_property_collection_begin(...) * RNA_property_collection_next(...) @@ -6803,7 +6814,7 @@ static PyTypeObject pyrna_prop_collection_iter_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ NULL, /* subclassed */ /* tp_repr */ @@ -6914,7 +6925,7 @@ static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA * BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr); # ifdef USE_PYRNA_STRUCT_REFERENCE - if (pyrna) { /* unlikely but may fail */ + if (pyrna) { /* Unlikely, but may fail. */ if ((PyObject *)pyrna != Py_None) { /* hold a reference to the iterator since it may have * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's */ @@ -6962,18 +6973,19 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) RNA_struct_py_type_set(srna, (void *)newclass); /* Store for later use */ - /* Not 100% needed but useful, - * having an instance within a type looks wrong however this instance IS an rna type */ + /* Not 100% needed, but useful, + * having an instance within a type looks wrong, but this instance _is_ an RNA type. */ - /* python deals with the circular ref */ + /* Python deals with the circular reference. */ RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr); item = pyrna_struct_CreatePyObject(&ptr); - /* note, must set the class not the __dict__ else the internal slots are not updated correctly */ + /* Note, must set the class not the __dict__ else the internal slots are not updated correctly. + */ PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item); Py_DECREF(item); - /* add staticmethods and classmethods */ + /* Add staticmethods and classmethods. */ { const PointerRNA func_ptr = {{NULL}, srna, NULL}; const ListBase *lb; @@ -6983,10 +6995,10 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) for (link = lb->first; link; link = link->next) { FunctionRNA *func = (FunctionRNA *)link; const int flag = RNA_function_flag(func); - if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */ - (flag & FUNC_REGISTER) == false) /* is not for registration */ + if ((flag & FUNC_NO_SELF) && /* Is staticmethod or classmethod. */ + (flag & FUNC_REGISTER) == false) /* Is not for registration. */ { - /* we may want to set the type of this later */ + /* We may want to set the type of this later. */ PyObject *func_py = pyrna_func_to_py(&func_ptr, func); PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py); Py_DECREF(func_py); @@ -6994,26 +7006,26 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) } } - /* done with rna instance */ + /* Done with RNA instance. */ } static PyObject *pyrna_srna_Subtype(StructRNA *srna); -/* return a borrowed reference */ +/* Return a borrowed reference. */ static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dict) { - /* Assume RNA_struct_py_type_get(srna) was already checked */ + /* Assume RNA_struct_py_type_get(srna) was already checked. */ StructRNA *base; PyObject *py_base = NULL; - /* get the base type */ + /* Get the base type. */ base = RNA_struct_base(srna); if (base && base != srna) { - /* printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); */ + // printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); py_base = pyrna_srna_Subtype(base); //, bpy_types_dict); - Py_DECREF(py_base); /* srna owns, this is only to pass as an arg */ + Py_DECREF(py_base); /* Srna owns, this is only to pass as an arg. */ } if (py_base == NULL) { @@ -7023,8 +7035,8 @@ static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dic return py_base; } -/* check if we have a native python subclass, use it when it exists - * return a borrowed reference */ +/* Check if we have a native Python subclass, use it when it exists + * return a borrowed reference. */ static PyObject *bpy_types_dict = NULL; static PyObject *pyrna_srna_ExternalType(StructRNA *srna) @@ -7041,18 +7053,18 @@ static PyObject *pyrna_srna_ExternalType(StructRNA *srna) CLOG_ERROR(BPY_LOG_RNA, "failed to find 'bpy_types' module"); return NULL; } - bpy_types_dict = PyModule_GetDict(bpy_types); /* borrow */ - Py_DECREF(bpy_types); /* fairly safe to assume the dict is kept */ + bpy_types_dict = PyModule_GetDict(bpy_types); /* Borrow. */ + Py_DECREF(bpy_types); /* Fairly safe to assume the dict is kept. */ } newclass = PyDict_GetItemString(bpy_types_dict, idname); - /* sanity check, could skip this unless in debug mode */ + /* Sanity check, could skip this unless in debug mode. */ if (newclass) { PyObject *base_compare = pyrna_srna_PyBase(srna); /* Can't do this because it gets superclasses values! */ // PyObject *slots = PyObject_GetAttrString(newclass, "__slots__"); - /* Can do this but faster not to. */ + /* Can do this, but faster not to. */ // PyObject *bases = PyObject_GetAttrString(newclass, "__bases__"); PyObject *tp_bases = ((PyTypeObject *)newclass)->tp_bases; PyObject *tp_slots = PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict, @@ -7088,18 +7100,18 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) { PyObject *newclass = NULL; - /* stupid/simple case */ + /* Stupid/simple case. */ if (srna == NULL) { - newclass = NULL; /* Nothing to do */ - } /* the class may have already been declared & allocated */ + newclass = NULL; /* Nothing to do. */ + } /* The class may have already been declared & allocated. */ else if ((newclass = RNA_struct_py_type_get(srna))) { Py_INCREF(newclass); - } /* check if bpy_types.py module has the class defined in it */ + } /* Check if bpy_types.py module has the class defined in it. */ else if ((newclass = pyrna_srna_ExternalType(srna))) { pyrna_subtype_set_rna(newclass, srna); Py_INCREF(newclass); } /* create a new class instance with the C api - * mainly for the purposing of matching the C/rna type hierarchy */ + * mainly for the purposing of matching the C/RNA type hierarchy */ else { /* subclass equivalents * - class myClass(myBase): @@ -7110,12 +7122,12 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) * ) */ - /* Assume RNA_struct_py_type_get(srna) was already checked */ + /* Assume RNA_struct_py_type_get(srna) was already checked. */ PyObject *py_base = pyrna_srna_PyBase(srna); PyObject *metaclass; const char *idname = RNA_struct_identifier(srna); - /* remove __doc__ for now */ + /* Remove __doc__ for now. */ // const char *descr = RNA_struct_ui_description(srna); // if (!descr) descr = "(no docs)"; // "__doc__", descr @@ -7128,13 +7140,13 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) metaclass = (PyObject *)&PyType_Type; } - /* always use O not N when calling, N causes refcount errors */ + /* Always use O not N when calling, N causes refcount errors. */ #if 0 newclass = PyObject_CallFunction( metaclass, "s(O) {sss()}", idname, py_base, "__module__", "bpy.types", "__slots__"); #else { - /* longhand of the call above */ + /* Longhand of the call above. */ PyObject *args, *item, *value; int ok; @@ -7168,14 +7180,14 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) /* PyC_ObSpit("new class ref", newclass); */ if (newclass) { - /* srna owns one, and the other is owned by the caller */ + /* srna owns one, and the other is owned by the caller. */ pyrna_subtype_set_rna(newclass, srna); - /* XXX, adding this back segfaults blender on load. */ + /* XXX, adding this back segfaults Blender on load. */ // Py_DECREF(newclass); /* let srna own */ } else { - /* this should not happen */ + /* This should not happen. */ CLOG_ERROR(BPY_LOG_RNA, "failed to register '%s'", idname); PyErr_Print(); PyErr_Clear(); @@ -7185,7 +7197,7 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) return newclass; } -/* use for subtyping so we know which srna is used for a PointerRNA */ +/* Use for subtyping so we know which srna is used for a PointerRNA. */ static StructRNA *srna_from_ptr(PointerRNA *ptr) { if (ptr->type == &RNA_Struct) { @@ -7196,7 +7208,7 @@ static StructRNA *srna_from_ptr(PointerRNA *ptr) } } -/* always returns a new ref, be sure to decref when done */ +/* Always returns a new ref, be sure to decref when done. */ static PyObject *pyrna_struct_Subtype(PointerRNA *ptr) { return pyrna_srna_Subtype(srna_from_ptr(ptr)); @@ -7207,8 +7219,8 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) { BPy_StructRNA *pyrna = NULL; - /* note: don't rely on this to return None since NULL data with a valid type can often crash */ - if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data */ + /* Note: don't rely on this to return None since NULL data with a valid type can often crash. */ + if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data. */ Py_RETURN_NONE; } @@ -7227,8 +7239,8 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) /* Existing users will need to use 'type_recast' method. */ Py_DECREF(pyrna); *instance = NULL; - /* Continue as if no instance was made */ -#if 0 /* no need to assign, will be written to next... */ + /* Continue as if no instance was made. */ +#if 0 /* No need to assign, will be written to next... */ pyrna = NULL; #endif } @@ -7239,7 +7251,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) if (tp) { pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0); - Py_DECREF(tp); /* srna owns, cant hold a ref */ + Py_DECREF(tp); /* srna owns, can't hold a reference. */ } else { CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type)); @@ -7330,7 +7342,7 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop) return (PyObject *)pyrna; } -/* utility func to be used by external modules, *sneaky!* */ +/* Utility func to be used by external modules, sneaky! */ PyObject *pyrna_id_CreatePyObject(ID *id) { if (id) { @@ -7362,12 +7374,12 @@ bool pyrna_id_CheckPyObject(PyObject *obj) void BPY_rna_init(void) { -#ifdef USE_MATHUTILS /* register mathutils callbacks, ok to run more than once. */ +#ifdef USE_MATHUTILS /* Register mathutils callbacks, ok to run more than once. */ mathutils_rna_array_cb_index = Mathutils_RegisterCallback(&mathutils_rna_array_cb); mathutils_rna_matrix_cb_index = Mathutils_RegisterCallback(&mathutils_rna_matrix_cb); #endif - /* for some reason MSVC complains of these */ + /* For some reason MSVC complains of these. */ #if defined(_MSC_VER) pyrna_struct_meta_idprop_Type.tp_base = &PyType_Type; @@ -7411,14 +7423,14 @@ void BPY_rna_init(void) #endif } -/* bpy.data from python */ +/* 'bpy.data' from Python. */ static PointerRNA *rna_module_ptr = NULL; PyObject *BPY_rna_module(void) { BPy_StructRNA *pyrna; PointerRNA ptr; - /* for now, return the base RNA type rather than a real module */ + /* For now, return the base RNA type rather than a real module. */ RNA_main_pointer_create(G_MAIN, &ptr); pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); @@ -7432,7 +7444,7 @@ void BPY_update_rna_module(void) #if 0 RNA_main_pointer_create(G_MAIN, rna_module_ptr); #else - rna_module_ptr->data = G_MAIN; /* just set data is enough */ + rna_module_ptr->data = G_MAIN; /* Just set data is enough. */ #endif } } @@ -7444,7 +7456,7 @@ PyObject *BPY_rna_doc(void) { PointerRNA ptr; - /* for now, return the base RNA type rather than a real module */ + /* For now, return the base RNA type rather than a real module. */ RNA_blender_rna_pointer_create(&ptr); return pyrna_struct_CreatePyObject(&ptr); @@ -7479,7 +7491,7 @@ static PyObject *pyrna_basetype_getattro(BPy_BaseTypeRNA *self, PyObject *pyname _PyUnicode_AsString(pyname)); return NULL; #endif - /* The error raised here will be displayed */ + /* The error raised here will be displayed. */ ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } @@ -7495,7 +7507,7 @@ static struct PyMethodDef pyrna_basetype_methods[] = { {NULL, NULL, 0, NULL}, }; -/* used to call ..._keys() direct, but we need to filter out operator subclasses */ +/* Used to call ..._keys() direct, but we need to filter out operator subclasses. */ #if 0 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) { @@ -7504,9 +7516,9 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) PyMethodDef *meth; # endif - list = pyrna_prop_collection_keys(self); /* like calling structs.keys(), avoids looping here */ + list = pyrna_prop_collection_keys(self); /* Like calling structs.keys(), avoids looping here. */ -# if 0 /* for now only contains __dir__ */ +# if 0 /* For now only contains __dir__. */ for (meth = pyrna_basetype_methods; meth->ml_name; meth++) { PyList_APPEND(list, PyUnicode_FromString(meth->ml_name)); } @@ -7552,11 +7564,11 @@ PyObject *BPY_rna_types(void) } } - /* static members for the base class */ - /* add __name__ since help() expects its */ + /* Static members for the base class. */ + /* Add __name__ since help() expects it. */ PyDict_SetItem(pyrna_basetype_Type.tp_dict, bpy_intern_str___name__, bpy_intern_str_bpy_types); - /* internal base types we have no other accessors for */ + /* Internal base types we have no other accessors for. */ { PyTypeObject *pyrna_types[] = { &pyrna_struct_meta_idprop_Type, @@ -7575,7 +7587,7 @@ PyObject *BPY_rna_types(void) self = (BPy_BaseTypeRNA *)PyObject_NEW(BPy_BaseTypeRNA, &pyrna_basetype_Type); - /* avoid doing this lookup for every getattr */ + /* Avoid doing this lookup for every getattr. */ RNA_blender_rna_pointer_create(&self->ptr); self->prop = RNA_struct_find_property(&self->ptr, "structs"); #ifdef USE_WEAKREFS @@ -7589,7 +7601,7 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e BPy_StructRNA *py_srna = NULL; StructRNA *srna; - /* ack, PyObject_GetAttrString wont look up this types tp_dict first :/ */ + /* Unfortunately PyObject_GetAttrString wont look up this types tp_dict first :/ */ if (PyType_Check(self)) { py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); @@ -7637,8 +7649,8 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e return srna; } -/* Orphan functions, not sure where they should go */ -/* get the srna for methods attached to types */ +/* Orphan functions, not sure where they should go. */ +/* Get the srna for methods attached to types. */ /* * Caller needs to raise error.*/ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) @@ -7694,7 +7706,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item } py_srna_cobject = PyCapsule_New(srna, NULL, NULL); - /* not 100% nice :/, modifies the dict passed, should be ok */ + /* Not 100% nice :/, modifies the dict passed, should be ok. */ PyDict_SetItem(py_kw, bpy_intern_str_attr, key); args_fake = PyTuple_New(1); @@ -7719,14 +7731,14 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item if (py_ret) { Py_DECREF(py_ret); - Py_DECREF(args_fake); /* free's py_srna_cobject too */ + Py_DECREF(args_fake); /* Free's py_srna_cobject too. */ } else { - /* _must_ print before decreffing args_fake */ + /* _must_ print before decreffing args_fake. */ PyErr_Print(); PyErr_Clear(); - Py_DECREF(args_fake); /* free's py_srna_cobject too */ + Py_DECREF(args_fake); /* Free's py_srna_cobject too. */ // PyC_LineSpit(); PyErr_Format(PyExc_ValueError, @@ -7738,9 +7750,9 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item } } else { - /* Since this is a class dict, ignore args that can't be passed */ + /* Since this is a class dict, ignore args that can't be passed. */ - /* for testing only */ + /* For testing only. */ #if 0 PyC_ObSpit("Why doesn't this work??", item); PyErr_Print(); @@ -7780,12 +7792,12 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) if (!has_warning) { printf( "Warning: class %.200s " - "contains a properties which should be an annotation!\n", + "contains a property which should be an annotation!\n", RNA_struct_identifier(srna)); PyC_LineSpit(); has_warning = true; } - printf(" make annotation: %.200s.%.200s\n", + printf(" assign as a type annotation: %.200s.%.200s\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); } @@ -7805,7 +7817,7 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject const int len = PyTuple_GET_SIZE(py_class->tp_bases); int i, ret; - /* first scan base classes for registerable properties */ + /* First scan base classes for registerable properties. */ for (i = 0; i < len; i++) { PyTypeObject *py_superclass = (PyTypeObject *)PyTuple_GET_ITEM(py_class->tp_bases, i); @@ -7813,7 +7825,7 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject * 'object' is of course not worth looking into and * existing subclasses of RNA would cause a lot more dictionary * looping then is needed (SomeOperator would scan Operator.__dict__) - * which is harmless but not at all useful. + * which is harmless, but not at all useful. * * So only scan base classes which are not subclasses if blender types. * This best fits having 'mix-in' classes for operators and render engines. @@ -7828,9 +7840,9 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject } } - /* not register out own properties */ - return pyrna_deferred_register_props( - srna, py_class->tp_dict); /* getattr(..., "__dict__") returns a proxy */ + /* Not register out own properties. */ + /* getattr(..., "__dict__") returns a proxy. */ + return pyrna_deferred_register_props(srna, py_class->tp_dict); } int pyrna_deferred_register_class(StructRNA *srna, PyTypeObject *py_class) @@ -7860,7 +7872,7 @@ static int rna_function_arg_count(FunctionRNA *func, int *min_count) parm = (PropertyRNA *)link; if (!(RNA_parameter_flag(parm) & PARM_OUTPUT)) { if (!done_min_count && (RNA_parameter_flag(parm) & PARM_PYFUNC_OPTIONAL)) { - /* From now on, following parameters are optional in py func */ + /* From now on, the following parameters are optional in a Python function. */ if (min_count) { *min_count = count; } @@ -7907,7 +7919,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, } } - /* verify callback functions */ + /* Verify callback functions. */ lb = RNA_struct_type_functions(srna); i = 0; for (link = lb->first; link; link = link->next) { @@ -7915,7 +7927,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, const int flag = RNA_function_flag(func); /* TODO(campbell): this is used for classmethod's too, * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg. - * Keep this as-is since its working but we should be using + * Keep this as-is since it's working, but we should be using * 'FUNC_USE_SELF_TYPE' for many functions. */ const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); @@ -7941,7 +7953,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, PyErr_Clear(); } else { - /* No need to keep a ref, the class owns it (technically we should keep a ref but...). */ + /* No need to keep a ref, the class owns it + * (technically we should keep a reference, but...). */ Py_DECREF(item); if (is_staticmethod) { @@ -7972,11 +7985,11 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, func_arg_count = rna_function_arg_count(func, &func_arg_min_count); - if (func_arg_count >= 0) { /* -1 if we don't care*/ + if (func_arg_count >= 0) { /* -1 if we don't care. */ arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount; /* note, the number of args we check for and the number of args we give to - * '@staticmethods' are different (quirk of python), + * '@staticmethods' are different (quirk of Python), * this is why rna_function_arg_count() doesn't return the value -1*/ if (is_staticmethod) { func_arg_count++; @@ -8012,7 +8025,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, } } - /* verify properties */ + /* Verify properties. */ lb = RNA_struct_type_properties(srna); for (link = lb->first; link; link = link->next) { const char *identifier; @@ -8029,7 +8042,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, if (item == NULL) { PyErr_Clear(); - /* Sneaky workaround to use the class name as the bl_idname */ + /* Sneaky workaround to use the class name as the bl_idname. */ #define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \ else if (STREQ(identifier, rna_attr)) \ @@ -8046,10 +8059,10 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, else { \ PyErr_Clear(); \ } \ - } /* intentionally allow else here */ + } /* Intentionally allow else here. */ if (false) { - } /* needed for macro */ + } /* Needed for macro. */ BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__) BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__) @@ -8083,7 +8096,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun return bpy_class_validate_recursive(dummyptr, dummyptr->type, py_data, have_function); } -/* TODO - multiple return values like with rna functions */ +/* TODO - multiple return values like with RNA functions. */ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) { PyObject *args; @@ -8106,33 +8119,33 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param const bool is_readonly_init = !(RNA_struct_is_a(ptr->type, &RNA_Operator) || RNA_struct_is_a(ptr->type, &RNA_Gizmo)); // const char *func_id = RNA_function_identifier(func); /* UNUSED */ - /* testing, for correctness, not operator and not draw function */ + /* Testing, for correctness, not operator and not draw function. */ const bool is_readonly = !(RNA_function_flag(func) & FUNC_ALLOW_WRITE); #endif py_class = RNA_struct_py_type_get(ptr->type); - /* rare case. can happen when registering subclasses */ + /* Rare case. can happen when registering subclasses. */ if (py_class == NULL) { CLOG_WARN(BPY_LOG_RNA, - "unable to get Python class for rna struct '%.200s'", + "unable to get Python class for RNA struct '%.200s'", RNA_struct_identifier(ptr->type)); return -1; } /* XXX, this is needed because render engine calls without a context - * this should be supported at some point but at the moment its not! */ + * this should be supported at some point, but at the moment it's not! */ if (C == NULL) { C = BPy_GetContext(); } - /* annoying!, need to check if the screen gets set to NULL which is a + /* Annoying! We need to check if the screen gets set to NULL which is a * hint that the file was actually re-loaded. */ const bool is_valid_wm = (CTX_wm_manager(C) != NULL); bpy_context_set(C, &gilstate); if (!(is_staticmethod || is_classmethod)) { - /* some datatypes (operator, render engine) can store PyObjects for re-use */ + /* Some datatypes (operator, render engine) can store PyObjects for re-use. */ if (ptr->data) { void **instance = RNA_struct_instance(ptr); @@ -8143,19 +8156,19 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } } } - /* end exception */ + /* End exception. */ if (py_class_instance == NULL) { py_srna = pyrna_struct_CreatePyObject(ptr); } if (py_class_instance) { - /* special case, instance is cached */ + /* Special case, instance is cached. */ } else if (py_srna == NULL) { py_class_instance = NULL; } - else if (py_srna == Py_None) { /* probably wont ever happen but possible */ + else if (py_srna == Py_None) { /* Probably wont ever happen, but possible. */ Py_DECREF(py_srna); py_class_instance = NULL; } @@ -8163,21 +8176,22 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #if 1 /* Skip the code below and call init directly on the allocated 'py_srna' * otherwise __init__() always needs to take a second self argument, see pyrna_struct_new(). - * Although this is annoying to have to implement a part of pythons typeobject.c:type_call(). + * Although this is annoying to have to implement a part of Python's + * typeobject.c:type_call(). */ if (py_class->tp_init) { # ifdef USE_PEDANTIC_WRITE const int prev_write = rna_disallow_writes; rna_disallow_writes = is_readonly_init ? false : - true; /* only operators can write on __init__ */ + true; /* Only operators can write on __init__. */ # endif - /* true in most cases even when the class its self doesn't define an __init__ function. */ + /* True in most cases even when the class itself doesn't define an __init__ function. */ args = PyTuple_New(0); if (py_class->tp_init(py_srna, args, NULL) < 0) { Py_DECREF(py_srna); py_srna = NULL; - /* err set below */ + /* Err set below. */ } Py_DECREF(args); # ifdef USE_PEDANTIC_WRITE @@ -8197,8 +8211,8 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param Py_INCREF(py_class_instance); # endif /* - * This would work fine but means __init__ functions wouldn't run. - * none of blenders default scripts use __init__ but its nice to call it + * This would work fine, but means __init__ functions wouldn't run. + * None of Blender's default scripts use __init__ but it's nice to call it * for general correctness. just to note why this is here when it could be safely removed. */ args = PyTuple_New(1); @@ -8211,12 +8225,12 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #endif if (py_class_instance == NULL) { - err = -1; /* so the error is not overridden below */ + err = -1; /* So the error is not overridden below. */ } } } - /* Initializing the class worked, now run its invoke function */ + /* Initializing the class worked, now run its invoke function. */ if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) { PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func)); @@ -8235,7 +8249,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param /* First arg is included in 'item'. */ args = PyTuple_New(rna_function_arg_count(func)); #endif - args = PyTuple_New(arg_count); /* first arg is included in 'item' */ + args = PyTuple_New(arg_count); /* First arg is included in 'item'. */ if (is_staticmethod) { i = 0; @@ -8251,11 +8265,11 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param RNA_parameter_list_begin(parms, &iter); - /* parse function parameters */ + /* Parse function parameters. */ for (; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; - /* only useful for single argument returns, we'll need another list loop for multiple */ + /* Only useful for single argument returns, we'll need another list loop for multiple. */ if (RNA_parameter_flag(parm) & PARM_OUTPUT) { ret_len++; if (pret_single == NULL) { @@ -8301,7 +8315,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } } else { - /* the error may be already set if the class instance couldn't be created */ + /* The error may be already set if the class instance couldn't be created. */ if (err != -1) { PyErr_Format(PyExc_RuntimeError, "could not create instance of %.200s to call callback function %.200s", @@ -8311,7 +8325,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } } - if (ret == NULL) { /* covers py_class_instance failing too */ + if (ret == NULL) { /* Covers py_class_instance failing too. */ err = -1; } else { @@ -8362,11 +8376,11 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param RNA_parameter_list_begin(parms, &iter); - /* parse function parameters */ + /* Parse function parameters. */ for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; - /* only useful for single argument returns, we'll need another list loop for multiple */ + /* Only useful for single argument returns, we'll need another list loop for multiple. */ if (RNA_parameter_flag(parm) & PARM_OUTPUT) { err = pyrna_py_to_prop( &funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:"); @@ -8384,7 +8398,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param if (err != 0) { ReportList *reports; - /* alert the user, else they wont know unless they see the console. */ + /* Alert the user, else they wont know unless they see the console. */ if ((!is_staticmethod) && (!is_classmethod) && (ptr->data) && (RNA_struct_is_a(ptr->type, &RNA_Operator)) && (is_valid_wm == (CTX_wm_manager(C) != NULL))) { @@ -8392,13 +8406,13 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param reports = op->reports; } else { - /* wont alert users but they can view in 'info' space */ + /* Wont alert users, but they can view in 'info' space. */ reports = CTX_wm_reports(C); } BPy_errors_to_report(reports); - /* also print in the console for py */ + /* Also print in the console for Python. */ PyErr_Print(); PyErr_Clear(); } @@ -8415,19 +8429,19 @@ static void bpy_class_free(void *pyob_ptr) gilstate = PyGILState_Ensure(); - /* breaks re-registering classes */ + /* Breaks re-registering classes. */ // PyDict_Clear(((PyTypeObject *)self)->tp_dict); - /* remove the rna attribute instead. */ + /* Remove the RNA attribute instead. */ PyDict_DelItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); if (PyErr_Occurred()) { PyErr_Clear(); } -#if 0 /* needs further investigation, too annoying so quiet for now */ +#if 0 /* Needs further investigation, too annoying so quiet for now. */ if (G.debug & G_DEBUG_PYTHON) { if (self->ob_refcnt > 1) { - PyC_ObSpit("zombie class - ref should be 1", self); + PyC_ObSpit("zombie class - reference should be 1", self); } } #endif @@ -8451,7 +8465,7 @@ void pyrna_alloc_types(void) gilstate = PyGILState_Ensure(); - /* avoid doing this lookup for every getattr */ + /* Avoid doing this lookup for every getattr. */ RNA_blender_rna_pointer_create(&ptr); prop = RNA_struct_find_property(&ptr, "structs"); @@ -8478,7 +8492,7 @@ void pyrna_free_types(void) PointerRNA ptr; PropertyRNA *prop; - /* avoid doing this lookup for every getattr */ + /* Avoid doing this lookup for every getattr. */ RNA_blender_rna_pointer_create(&ptr); prop = RNA_struct_find_property(&ptr, "structs"); @@ -8487,7 +8501,7 @@ void pyrna_free_types(void) void *py_ptr = RNA_struct_py_type_get(srna); if (py_ptr) { -#if 0 /* XXX - should be able to do this but makes python crash on exit */ +#if 0 /* XXX - should be able to do this, but makes Python crash on exit. */ bpy_class_free(py_ptr); #endif RNA_struct_py_type_set(srna, NULL); @@ -8498,9 +8512,9 @@ void pyrna_free_types(void) /* Note! MemLeak XXX * - * There is currently a bug where moving registering a python class does - * not properly manage refcounts from the python class, since the srna owns - * the python class this should not be so tricky but changing the references as + * There is currently a bug where moving the registration of a Python class does + * not properly manage reference-counts from the Python class. As the srna owns + * the Python class this should not be so tricky, but changing the references as * you'd expect when changing ownership crashes blender on exit so I had to comment out * the decref. This is not so bad because the leak only happens when re-registering (hold F8) * - Should still be fixed - Campbell @@ -8557,13 +8571,13 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class return NULL; } - /* warning: gets parent classes srna, only for the register function */ + /* Warning: gets parent classes srna, only for the register function. */ srna = pyrna_struct_as_srna(py_class, true, "register_class(...):"); if (srna == NULL) { return NULL; } - /* fails in cases, cant use this check but would like to :| */ + /* Fails in some cases, so can't use this check, but would like to :| */ #if 0 if (RNA_struct_py_type_get(srna)) { PyErr_Format(PyExc_ValueError, @@ -8575,21 +8589,21 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class } #endif - /* check that we have a register callback for this type */ + /* Check that we have a register callback for this type. */ reg = RNA_struct_register(srna); if (!reg) { PyErr_Format(PyExc_ValueError, "register_class(...): expected a subclass of a registerable " - "rna type (%.200s does not support registration)", + "RNA type (%.200s does not support registration)", RNA_struct_identifier(srna)); return NULL; } - /* get the context, so register callback can do necessary refreshes */ + /* Get the context, so register callback can do necessary refreshes. */ C = BPy_GetContext(); - /* call the register callback with reports & identifier */ + /* Call the register callback with reports & identifier. */ BKE_reports_init(&reports, RPT_STORE); identifier = ((PyTypeObject *)py_class)->tp_name; @@ -8613,18 +8627,19 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class } } - /* python errors validating are not converted into reports so the check above will fail. + /* Python errors validating are not converted into reports so the check above will fail. * the cause for returning NULL will be printed as an error */ if (srna_new == NULL) { return NULL; } - pyrna_subtype_set_rna(py_class, srna_new); /* takes a ref to py_class */ + /* Takes a reference to 'py_class'. */ + pyrna_subtype_set_rna(py_class, srna_new); - /* old srna still references us, keep the check in case registering somehow can free it */ + /* Old srna still references us, keep the check in case registering somehow can free it. */ if (RNA_struct_py_type_get(srna)) { RNA_struct_py_type_set(srna, NULL); - // Py_DECREF(py_class); // should be able to do this XXX since the old rna adds a new ref. + // Py_DECREF(py_class); /* Should be able to do this XXX since the old RNA adds a new ref. */ } /* Can't use this because it returns a dict proxy @@ -8635,7 +8650,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class return NULL; } - /* call classed register method () */ + /* Call classed register method. */ switch (_PyObject_LookupAttr(py_class, bpy_intern_str_register, &py_cls_meth)) { case 1: { PyObject *ret = PyObject_CallObject(py_cls_meth, NULL); @@ -8662,7 +8677,7 @@ static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props, PropertyRNA *prop; LinkData *link; - /* verify properties */ + /* Verify properties. */ const ListBase *lb = RNA_struct_type_properties(srna); for (link = lb->first; link; link = link->next) { @@ -8684,7 +8699,7 @@ static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props, PyDoc_STRVAR(pyrna_unregister_class_doc, ".. method:: unregister_class(cls)\n" "\n" - " Unload the python class from blender.\n" + " Unload the Python class from blender.\n" "\n" " If the class has an *unregister* class method it will be called\n" " before unregistering.\n"); @@ -8730,18 +8745,18 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla return NULL; } - /* check that we have a unregister callback for this type */ + /* Check that we have a unregister callback for this type. */ unreg = RNA_struct_unregister(srna); if (!unreg) { PyErr_SetString( PyExc_ValueError, "unregister_class(...): " - "expected a Type subclassed from a registerable rna type (no unregister supported)"); + "expected a Type subclassed from a registerable RNA type (no unregister supported)"); return NULL; } - /* call classed unregister method */ + /* Call classed unregister method. */ switch (_PyObject_LookupAttr(py_class, bpy_intern_str_unregister, &py_cls_meth)) { case 1: { PyObject *ret = PyObject_CallObject(py_cls_meth, NULL); @@ -8758,9 +8773,9 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla } } - /* should happen all the time but very slow */ + /* Should happen all the time, however it's very slow. */ if (G.debug & G_DEBUG_PYTHON) { - /* remove all properties using this class */ + /* Remove all properties using this class. */ StructRNA *srna_iter; PointerRNA ptr_rna; PropertyRNA *prop_rna; @@ -8769,7 +8784,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla RNA_blender_rna_pointer_create(&ptr_rna); prop_rna = RNA_struct_find_property(&ptr_rna, "structs"); - /* loop over all structs */ + /* Loop over all structs. */ RNA_PROP_BEGIN (&ptr_rna, itemptr, prop_rna) { srna_iter = itemptr.data; if (pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) { @@ -8789,11 +8804,11 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla } } - /* get the context, so register callback can do necessary refreshes */ + /* Get the context, so register callback can do necessary refreshes. */ C = BPy_GetContext(); - /* call unregister */ - unreg(CTX_data_main(C), srna); /* calls bpy_class_free, this decref's py_class */ + /* Call unregister. */ + unreg(CTX_data_main(C), srna); /* Calls bpy_class_free, this decref's py_class. */ PyDict_DelItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna); if (PyErr_Occurred()) { @@ -8931,7 +8946,7 @@ void BPY_rna_register_cb(void) PyObject_SetAttrString(cls, pyrna_cb_methods[i].py_method.ml_name, classmethod); Py_DECREF(classmethod); - Py_DECREF(args); /* clears 'func' too */ + Py_DECREF(args); /* Clears 'func' too. */ Py_DECREF(cls); } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index f20bc6b11fe..a95ccd65dff 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -3230,14 +3230,11 @@ void wm_event_do_handlers(bContext *C) } else { Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false); + Scene *scene_eval = (depsgraph != NULL) ? DEG_get_evaluated_scene(depsgraph) : NULL; - CTX_wm_window_set(C, win); - CTX_data_scene_set(C, scene); - - Depsgraph *depsgraph = CTX_data_depsgraph(C); - Scene *scene_eval = DEG_get_evaluated_scene_if_exists(depsgraph); - - if (scene_eval) { + if (scene_eval != NULL) { const int is_playing_sound = BKE_sound_scene_playing(scene_eval); if (is_playing_sound != -1) { @@ -3263,10 +3260,6 @@ void wm_event_do_handlers(bContext *C) } } } - - CTX_data_scene_set(C, NULL); - CTX_wm_screen_set(C, NULL); - CTX_wm_window_set(C, NULL); } while ((event = win->queue.first)) { diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 0c525d6946c..fe93e39b085 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -2949,11 +2949,9 @@ static void wm_block_file_close_save(bContext *C, void *arg_block, void *arg_dat UI_popup_block_close(C, win, arg_block); if (save_images_when_file_is_closed) { - ReportList *reports = CTX_wm_reports(C); - if (!ED_image_save_all_modified(C, reports)) { + if (!ED_image_should_save_modified(C)) { execute_callback = false; } - WM_report_banner_show(); } Main *bmain = CTX_data_main(C); @@ -3059,10 +3057,10 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, struct ARegi 0, 0, ""); + } - LISTBASE_FOREACH (Report *, report, &reports.list) { - uiItemL(layout, report->message, ICON_ERROR); - } + LISTBASE_FOREACH (Report *, report, &reports.list) { + uiItemL(layout, report->message, ICON_ERROR); } BKE_reports_clear(&reports); diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 11f9ef917fd..b79de4370d0 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -215,6 +215,7 @@ static void wm_gesture_draw_line(wmGesture *gt) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); + immUniform1f("dash_factor", 0.5f); float xmin = (float)rect->xmin; float ymin = (float)rect->ymin; @@ -257,6 +258,7 @@ static void wm_gesture_draw_rect(wmGesture *gt) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); + immUniform1f("dash_factor", 0.5f); imm_draw_box_wire_2d( shdr_pos, (float)rect->xmin, (float)rect->ymin, (float)rect->xmax, (float)rect->ymax); @@ -295,6 +297,7 @@ static void wm_gesture_draw_circle(wmGesture *gt) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 4.0f); + immUniform1f("dash_factor", 0.5f); imm_draw_circle_wire_2d(shdr_pos, (float)rect->xmin, (float)rect->ymin, (float)rect->xmax, 40); @@ -418,6 +421,7 @@ static void wm_gesture_draw_lasso(wmGesture *gt, bool filled) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); + immUniform1f("dash_factor", 0.5f); immBegin((gt->type == WM_GESTURE_LASSO) ? GPU_PRIM_LINE_LOOP : GPU_PRIM_LINE_STRIP, numverts); @@ -451,6 +455,7 @@ static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 4); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 842fa5394bd..4cbb56ec289 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1940,6 +1940,10 @@ void wm_window_lower(wmWindow *win) void wm_window_raise(wmWindow *win) { + /* Restore window if minimized */ + if (GHOST_GetWindowState(win->ghostwin) == GHOST_kWindowStateMinimized) { + GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateNormal); + } GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderTop); } |