WIP: Onion Skinning Prototype #107641
|
@ -374,7 +374,7 @@ def external_script_add_origin_if_needed(args: argparse.Namespace,
|
|||
# - Rename remote "upstream" to "origin", which takes care of changing the names of
|
||||
# remotes the local branches are tracking.
|
||||
#
|
||||
# - Change the URL to the "origin", which so was was still pointing to upstream.
|
||||
# - Change the URL to the "origin", which was still pointing to upstream.
|
||||
#
|
||||
# - Re-introduce the "upstream" remote, with the same URL as it had prior to rename.
|
||||
|
||||
|
|
|
@ -24,3 +24,4 @@ Several people provided fixes:
|
|||
- Aaron Carlisle
|
||||
- Sebastian Parborg
|
||||
- Leon Zandman
|
||||
- Richard Antalik
|
||||
|
|
|
@ -124,7 +124,7 @@ Device_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Device_lock_doc,
|
||||
".. classmethod:: lock()\n\n"
|
||||
".. method:: lock()\n\n"
|
||||
" Locks the device so that it's guaranteed, that no samples are\n"
|
||||
" read from the streams until :meth:`unlock` is called.\n"
|
||||
" This is useful if you want to do start/stop/pause/resume some\n"
|
||||
|
@ -152,7 +152,7 @@ Device_lock(Device* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Device_play_doc,
|
||||
".. classmethod:: play(sound, keep=False)\n\n"
|
||||
".. method:: play(sound, keep=False)\n\n"
|
||||
" Plays a sound.\n\n"
|
||||
" :arg sound: The sound to play.\n"
|
||||
" :type sound: :class:`Sound`\n"
|
||||
|
@ -212,7 +212,7 @@ Device_play(Device* self, PyObject* args, PyObject* kwds)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Device_stopAll_doc,
|
||||
".. classmethod:: stopAll()\n\n"
|
||||
".. method:: stopAll()\n\n"
|
||||
" Stops all playing and paused sounds.");
|
||||
|
||||
static PyObject *
|
||||
|
@ -231,7 +231,7 @@ Device_stopAll(Device* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Device_unlock_doc,
|
||||
".. classmethod:: unlock()\n\n"
|
||||
".. method:: unlock()\n\n"
|
||||
" Unlocks the device after a lock call, see :meth:`lock` for\n"
|
||||
" details.");
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ DynamicMusic_dealloc(DynamicMusicP* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_DynamicMusic_addScene_doc,
|
||||
".. classmethod:: addScene(scene)\n\n"
|
||||
".. method:: addScene(scene)\n\n"
|
||||
" Adds a new scene.\n\n"
|
||||
" :arg scene: The scene sound.\n"
|
||||
" :type scene: :class:`Sound`\n"
|
||||
|
@ -90,7 +90,7 @@ DynamicMusic_addScene(DynamicMusicP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_DynamicMusic_addTransition_doc,
|
||||
".. classmethod:: addTransition(ini, end, transition)\n\n"
|
||||
".. method:: addTransition(ini, end, transition)\n\n"
|
||||
" Adds a new scene.\n\n"
|
||||
" :arg ini: the initial scene foor the transition.\n"
|
||||
" :type ini: int\n"
|
||||
|
@ -125,7 +125,7 @@ DynamicMusic_addTransition(DynamicMusicP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_DynamicMusic_resume_doc,
|
||||
".. classmethod:: resume()\n\n"
|
||||
".. method:: resume()\n\n"
|
||||
" Resumes playback of the scene.\n\n"
|
||||
" :return: Whether the action succeeded.\n"
|
||||
" :rtype: bool");
|
||||
|
@ -145,7 +145,7 @@ DynamicMusic_resume(DynamicMusicP* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_DynamicMusic_pause_doc,
|
||||
".. classmethod:: pause()\n\n"
|
||||
".. method:: pause()\n\n"
|
||||
" Pauses playback of the scene.\n\n"
|
||||
" :return: Whether the action succeeded.\n"
|
||||
" :rtype: bool");
|
||||
|
@ -165,7 +165,7 @@ DynamicMusic_pause(DynamicMusicP* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_DynamicMusic_stop_doc,
|
||||
".. classmethod:: stop()\n\n"
|
||||
".. method:: stop()\n\n"
|
||||
" Stops playback of the scene.\n\n"
|
||||
" :return: Whether the action succeeded.\n"
|
||||
" :rtype: bool\n\n");
|
||||
|
|
|
@ -54,7 +54,7 @@ HRTF_dealloc(HRTFP* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_HRTF_addImpulseResponse_doc,
|
||||
".. classmethod:: addImpulseResponseFromSound(sound, azimuth, elevation)\n\n"
|
||||
".. method:: addImpulseResponseFromSound(sound, azimuth, elevation)\n\n"
|
||||
" Adds a new hrtf to the HRTF object\n\n"
|
||||
" :arg sound: The sound that contains the hrtf.\n"
|
||||
" :type sound: :class:`Sound`\n"
|
||||
|
@ -90,7 +90,7 @@ HRTF_addImpulseResponseFromSound(HRTFP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_HRTF_loadLeftHrtfSet_doc,
|
||||
".. classmethod:: loadLeftHrtfSet(extension, directory)\n\n"
|
||||
".. method:: loadLeftHrtfSet(extension, directory)\n\n"
|
||||
" Loads all HRTFs from a directory.\n\n"
|
||||
" :arg extension: The file extension of the hrtfs.\n"
|
||||
" :type extension: string\n"
|
||||
|
@ -125,7 +125,7 @@ HRTF_loadLeftHrtfSet(PyTypeObject* type, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_HRTF_loadRightHrtfSet_doc,
|
||||
".. classmethod:: loadLeftHrtfSet(extension, directory)\n\n"
|
||||
".. method:: loadLeftHrtfSet(extension, directory)\n\n"
|
||||
" Loads all HRTFs from a directory.\n\n"
|
||||
" :arg extension: The file extension of the hrtfs.\n"
|
||||
" :type extension: string\n"
|
||||
|
|
|
@ -38,7 +38,7 @@ Handle_dealloc(Handle* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Handle_pause_doc,
|
||||
".. classmethod:: pause()\n\n"
|
||||
".. method:: pause()\n\n"
|
||||
" Pauses playback.\n\n"
|
||||
" :return: Whether the action succeeded.\n"
|
||||
" :rtype: bool");
|
||||
|
@ -58,7 +58,7 @@ Handle_pause(Handle* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Handle_resume_doc,
|
||||
".. classmethod:: resume()\n\n"
|
||||
".. method:: resume()\n\n"
|
||||
" Resumes playback.\n\n"
|
||||
" :return: Whether the action succeeded.\n"
|
||||
" :rtype: bool");
|
||||
|
@ -78,7 +78,7 @@ Handle_resume(Handle* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Handle_stop_doc,
|
||||
".. classmethod:: stop()\n\n"
|
||||
".. method:: stop()\n\n"
|
||||
" Stops playback.\n\n"
|
||||
" :return: Whether the action succeeded.\n"
|
||||
" :rtype: bool\n\n"
|
||||
|
|
|
@ -60,7 +60,7 @@ PlaybackManager_dealloc(PlaybackManagerP* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_PlaybackManager_play_doc,
|
||||
".. classmethod:: play(sound, catKey)\n\n"
|
||||
".. method:: play(sound, catKey)\n\n"
|
||||
" Plays a sound through the playback manager and assigns it to a category.\n\n"
|
||||
" :arg sound: The sound to play.\n"
|
||||
" :type sound: :class:`Sound`\n"
|
||||
|
@ -104,7 +104,7 @@ PlaybackManager_play(PlaybackManagerP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_PlaybackManager_resume_doc,
|
||||
".. classmethod:: resume(catKey)\n\n"
|
||||
".. method:: resume(catKey)\n\n"
|
||||
" Resumes playback of the catgory.\n\n"
|
||||
" :arg catKey: the key of the category.\n"
|
||||
" :type catKey: int\n"
|
||||
|
@ -131,7 +131,7 @@ PlaybackManager_resume(PlaybackManagerP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_PlaybackManager_pause_doc,
|
||||
".. classmethod:: pause(catKey)\n\n"
|
||||
".. method:: pause(catKey)\n\n"
|
||||
" Pauses playback of the category.\n\n"
|
||||
" :arg catKey: the key of the category.\n"
|
||||
" :type catKey: int\n"
|
||||
|
@ -158,7 +158,7 @@ PlaybackManager_pause(PlaybackManagerP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_PlaybackManager_add_category_doc,
|
||||
".. classmethod:: addCategory(volume)\n\n"
|
||||
".. method:: addCategory(volume)\n\n"
|
||||
" Adds a category with a custom volume.\n\n"
|
||||
" :arg volume: The volume for ther new category.\n"
|
||||
" :type volume: float\n"
|
||||
|
@ -185,7 +185,7 @@ PlaybackManager_add_category(PlaybackManagerP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_PlaybackManager_get_volume_doc,
|
||||
".. classmethod:: getVolume(catKey)\n\n"
|
||||
".. method:: getVolume(catKey)\n\n"
|
||||
" Retrieves the volume of a category.\n\n"
|
||||
" :arg catKey: the key of the category.\n"
|
||||
" :type catKey: int\n"
|
||||
|
@ -212,7 +212,7 @@ PlaybackManager_get_volume(PlaybackManagerP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_PlaybackManager_set_volume_doc,
|
||||
".. classmethod:: setVolume(volume, catKey)\n\n"
|
||||
".. method:: setVolume(volume, catKey)\n\n"
|
||||
" Changes the volume of a category.\n\n"
|
||||
" :arg volume: the new volume value.\n"
|
||||
" :type volume: float\n"
|
||||
|
@ -242,7 +242,7 @@ PlaybackManager_set_volume(PlaybackManagerP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_PlaybackManager_stop_doc,
|
||||
".. classmethod:: stop(catKey)\n\n"
|
||||
".. method:: stop(catKey)\n\n"
|
||||
" Stops playback of the category.\n\n"
|
||||
" :arg catKey: the key of the category.\n"
|
||||
" :type catKey: int\n"
|
||||
|
@ -269,7 +269,7 @@ PlaybackManager_stop(PlaybackManagerP* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_PlaybackManager_clean_doc,
|
||||
".. classmethod:: clean()\n\n"
|
||||
".. method:: clean()\n\n"
|
||||
" Cleans all the invalid and finished sound from the playback manager.\n\n");
|
||||
|
||||
static PyObject *
|
||||
|
|
|
@ -99,7 +99,7 @@ Sequence_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sequence_add_doc,
|
||||
".. classmethod:: add()\n\n"
|
||||
".. method:: add()\n\n"
|
||||
" Adds a new entry to the sequence.\n\n"
|
||||
" :arg sound: The sound this entry should play.\n"
|
||||
" :type sound: :class:`Sound`\n"
|
||||
|
@ -151,7 +151,7 @@ Sequence_add(Sequence* self, PyObject* args, PyObject* kwds)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sequence_remove_doc,
|
||||
".. classmethod:: remove()\n\n"
|
||||
".. method:: remove()\n\n"
|
||||
" Removes an entry from the sequence.\n\n"
|
||||
" :arg entry: The entry to remove.\n"
|
||||
" :type entry: :class:`SequenceEntry`\n");
|
||||
|
@ -183,7 +183,7 @@ Sequence_remove(Sequence* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sequence_setAnimationData_doc,
|
||||
".. classmethod:: setAnimationData()\n\n"
|
||||
".. method:: setAnimationData()\n\n"
|
||||
" Writes animation data to a sequence.\n\n"
|
||||
" :arg type: The type of animation data.\n"
|
||||
" :type type: int\n"
|
||||
|
|
|
@ -43,7 +43,7 @@ SequenceEntry_dealloc(SequenceEntry* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_SequenceEntry_move_doc,
|
||||
".. classmethod:: move()\n\n"
|
||||
".. method:: move()\n\n"
|
||||
" Moves the entry.\n\n"
|
||||
" :arg begin: The new start time.\n"
|
||||
" :type begin: double\n"
|
||||
|
@ -73,7 +73,7 @@ SequenceEntry_move(SequenceEntry* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_SequenceEntry_setAnimationData_doc,
|
||||
".. classmethod:: setAnimationData()\n\n"
|
||||
".. method:: setAnimationData()\n\n"
|
||||
" Writes animation data to a sequenced entry.\n\n"
|
||||
" :arg type: The type of animation data.\n"
|
||||
" :type type: int\n"
|
||||
|
|
|
@ -115,7 +115,7 @@ Sound_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_data_doc,
|
||||
".. classmethod:: data()\n\n"
|
||||
".. method:: data()\n\n"
|
||||
" Retrieves the data of the sound as numpy array.\n\n"
|
||||
" :return: A two dimensional numpy float array.\n"
|
||||
" :rtype: :class:`numpy.ndarray`\n\n"
|
||||
|
@ -146,7 +146,7 @@ Sound_data(Sound* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_write_doc,
|
||||
".. classmethod:: write(filename, rate, channels, format, container, codec, bitrate, buffersize)\n\n"
|
||||
".. method:: write(filename, rate, channels, format, container, codec, bitrate, buffersize)\n\n"
|
||||
" Writes the sound to a file.\n\n"
|
||||
" :arg filename: The path to write to.\n"
|
||||
" :type filename: string\n"
|
||||
|
@ -357,7 +357,7 @@ Sound_buffer(PyTypeObject* type, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_cache_doc,
|
||||
".. classmethod:: cache()\n\n"
|
||||
".. method:: cache()\n\n"
|
||||
" Caches a sound into RAM.\n\n"
|
||||
" This saves CPU usage needed for decoding and file access if the\n"
|
||||
" underlying sound reads from a file on the harddisk,\n"
|
||||
|
@ -631,7 +631,7 @@ Sound_triangle(PyTypeObject* type, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_accumulate_doc,
|
||||
".. classmethod:: accumulate(additive=False)\n\n"
|
||||
".. method:: accumulate(additive=False)\n\n"
|
||||
" Accumulates a sound by summing over positive input\n"
|
||||
" differences thus generating a monotonic sigal.\n"
|
||||
" If additivity is set to true negative input differences get added too,\n"
|
||||
|
@ -683,7 +683,7 @@ Sound_accumulate(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_ADSR_doc,
|
||||
".. classmethod:: ADSR(attack, decay, sustain, release)\n\n"
|
||||
".. method:: ADSR(attack, decay, sustain, release)\n\n"
|
||||
" Attack-Decay-Sustain-Release envelopes the volume of a sound.\n"
|
||||
" Note: there is currently no way to trigger the release with this API.\n\n"
|
||||
" :arg attack: The attack time in seconds.\n"
|
||||
|
@ -726,7 +726,7 @@ Sound_ADSR(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_delay_doc,
|
||||
".. classmethod:: delay(time)\n\n"
|
||||
".. method:: delay(time)\n\n"
|
||||
" Delays by playing adding silence in front of the other sound's data.\n\n"
|
||||
" :arg time: How many seconds of silence should be added before the sound.\n"
|
||||
" :type time: float\n"
|
||||
|
@ -762,7 +762,7 @@ Sound_delay(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_envelope_doc,
|
||||
".. classmethod:: envelope(attack, release, threshold, arthreshold)\n\n"
|
||||
".. method:: envelope(attack, release, threshold, arthreshold)\n\n"
|
||||
" Delays by playing adding silence in front of the other sound's data.\n\n"
|
||||
" :arg attack: The attack factor.\n"
|
||||
" :type attack: float\n"
|
||||
|
@ -804,7 +804,7 @@ Sound_envelope(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_fadein_doc,
|
||||
".. classmethod:: fadein(start, length)\n\n"
|
||||
".. method:: fadein(start, length)\n\n"
|
||||
" Fades a sound in by raising the volume linearly in the given\n"
|
||||
" time interval.\n\n"
|
||||
" :arg start: Time in seconds when the fading should start.\n"
|
||||
|
@ -844,7 +844,7 @@ Sound_fadein(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_fadeout_doc,
|
||||
".. classmethod:: fadeout(start, length)\n\n"
|
||||
".. method:: fadeout(start, length)\n\n"
|
||||
" Fades a sound in by lowering the volume linearly in the given\n"
|
||||
" time interval.\n\n"
|
||||
" :arg start: Time in seconds when the fading should start.\n"
|
||||
|
@ -886,7 +886,7 @@ Sound_fadeout(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_filter_doc,
|
||||
".. classmethod:: filter(b, a = (1))\n\n"
|
||||
".. method:: filter(b, a = (1))\n\n"
|
||||
" Filters a sound with the supplied IIR filter coefficients.\n"
|
||||
" Without the second parameter you'll get a FIR filter.\n\n"
|
||||
" If the first value of the a sequence is 0,\n"
|
||||
|
@ -986,7 +986,7 @@ Sound_filter(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_highpass_doc,
|
||||
".. classmethod:: highpass(frequency, Q=0.5)\n\n"
|
||||
".. method:: highpass(frequency, Q=0.5)\n\n"
|
||||
" Creates a second order highpass filter based on the transfer\n"
|
||||
" function :math:`H(s) = s^2 / (s^2 + s/Q + 1)`\n\n"
|
||||
" :arg frequency: The cut off trequency of the highpass.\n"
|
||||
|
@ -1026,7 +1026,7 @@ Sound_highpass(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_limit_doc,
|
||||
".. classmethod:: limit(start, end)\n\n"
|
||||
".. method:: limit(start, end)\n\n"
|
||||
" Limits a sound within a specific start and end time.\n\n"
|
||||
" :arg start: Start time in seconds.\n"
|
||||
" :type start: float\n"
|
||||
|
@ -1064,7 +1064,7 @@ Sound_limit(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_loop_doc,
|
||||
".. classmethod:: loop(count)\n\n"
|
||||
".. method:: loop(count)\n\n"
|
||||
" Loops a sound.\n\n"
|
||||
" :arg count: How often the sound should be looped.\n"
|
||||
" Negative values mean endlessly.\n"
|
||||
|
@ -1104,7 +1104,7 @@ Sound_loop(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
|
||||
".. classmethod:: lowpass(frequency, Q=0.5)\n\n"
|
||||
".. method:: lowpass(frequency, Q=0.5)\n\n"
|
||||
" Creates a second order lowpass filter based on the transfer "
|
||||
" function :math:`H(s) = 1 / (s^2 + s/Q + 1)`\n\n"
|
||||
" :arg frequency: The cut off trequency of the lowpass.\n"
|
||||
|
@ -1144,7 +1144,7 @@ Sound_lowpass(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_modulate_doc,
|
||||
".. classmethod:: modulate(sound)\n\n"
|
||||
".. method:: modulate(sound)\n\n"
|
||||
" Modulates two factories.\n\n"
|
||||
" :arg sound: The sound to modulate over the other.\n"
|
||||
" :type sound: :class:`Sound`\n"
|
||||
|
@ -1186,7 +1186,7 @@ Sound_modulate(Sound* self, PyObject* object)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_pitch_doc,
|
||||
".. classmethod:: pitch(factor)\n\n"
|
||||
".. method:: pitch(factor)\n\n"
|
||||
" Changes the pitch of a sound with a specific factor.\n\n"
|
||||
" :arg factor: The factor to change the pitch with.\n"
|
||||
" :type factor: float\n"
|
||||
|
@ -1229,7 +1229,7 @@ Sound_pitch(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_rechannel_doc,
|
||||
".. classmethod:: rechannel(channels)\n\n"
|
||||
".. method:: rechannel(channels)\n\n"
|
||||
" Rechannels the sound.\n\n"
|
||||
" :arg channels: The new channel configuration.\n"
|
||||
" :type channels: int\n"
|
||||
|
@ -1269,7 +1269,7 @@ Sound_rechannel(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_resample_doc,
|
||||
".. classmethod:: resample(rate, high_quality)\n\n"
|
||||
".. method:: resample(rate, high_quality)\n\n"
|
||||
" Resamples the sound.\n\n"
|
||||
" :arg rate: The new sample rate.\n"
|
||||
" :type rate: double\n"
|
||||
|
@ -1324,7 +1324,7 @@ Sound_resample(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_reverse_doc,
|
||||
".. classmethod:: reverse()\n\n"
|
||||
".. method:: reverse()\n\n"
|
||||
" Plays a sound reversed.\n\n"
|
||||
" :return: The created :class:`Sound` object.\n"
|
||||
" :rtype: :class:`Sound`\n\n"
|
||||
|
@ -1362,7 +1362,7 @@ Sound_reverse(Sound* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_sum_doc,
|
||||
".. classmethod:: sum()\n\n"
|
||||
".. method:: sum()\n\n"
|
||||
" Sums the samples of a sound.\n\n"
|
||||
" :return: The created :class:`Sound` object.\n"
|
||||
" :rtype: :class:`Sound`");
|
||||
|
@ -1391,7 +1391,7 @@ Sound_sum(Sound* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_threshold_doc,
|
||||
".. classmethod:: threshold(threshold = 0)\n\n"
|
||||
".. method:: threshold(threshold = 0)\n\n"
|
||||
" Makes a threshold wave out of an audio wave by setting all samples\n"
|
||||
" with a amplitude >= threshold to 1, all <= -threshold to -1 and\n"
|
||||
" all between to 0.\n\n"
|
||||
|
@ -1430,7 +1430,7 @@ Sound_threshold(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_volume_doc,
|
||||
".. classmethod:: volume(volume)\n\n"
|
||||
".. method:: volume(volume)\n\n"
|
||||
" Changes the volume of a sound.\n\n"
|
||||
" :arg volume: The new volume..\n"
|
||||
" :type volume: float\n"
|
||||
|
@ -1471,7 +1471,7 @@ Sound_volume(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_join_doc,
|
||||
".. classmethod:: join(sound)\n\n"
|
||||
".. method:: join(sound)\n\n"
|
||||
" Plays two factories in sequence.\n\n"
|
||||
" :arg sound: The sound to play second.\n"
|
||||
" :type sound: :class:`Sound`\n"
|
||||
|
@ -1514,7 +1514,7 @@ Sound_join(Sound* self, PyObject* object)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_mix_doc,
|
||||
".. classmethod:: mix(sound)\n\n"
|
||||
".. method:: mix(sound)\n\n"
|
||||
" Mixes two factories.\n\n"
|
||||
" :arg sound: The sound to mix over the other.\n"
|
||||
" :type sound: :class:`Sound`\n"
|
||||
|
@ -1556,7 +1556,7 @@ Sound_mix(Sound* self, PyObject* object)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_pingpong_doc,
|
||||
".. classmethod:: pingpong()\n\n"
|
||||
".. method:: pingpong()\n\n"
|
||||
" Plays a sound forward and then backward.\n"
|
||||
" This is like joining a sound with its reverse.\n\n"
|
||||
" :return: The created :class:`Sound` object.\n"
|
||||
|
@ -1622,7 +1622,7 @@ Sound_list(PyTypeObject* type, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_mutable_doc,
|
||||
".. classmethod:: mutable()\n\n"
|
||||
".. method:: mutable()\n\n"
|
||||
" Creates a sound that will be restarted when sought backwards.\n"
|
||||
" If the original sound is a sound list, the playing sound can change.\n\n"
|
||||
" :return: The created :class:`Sound` object.\n"
|
||||
|
@ -1652,7 +1652,7 @@ Sound_mutable(Sound* self)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_list_addSound_doc,
|
||||
".. classmethod:: addSound(sound)\n\n"
|
||||
".. method:: addSound(sound)\n\n"
|
||||
" Adds a new sound to a sound list.\n\n"
|
||||
" :arg sound: The sound that will be added to the list.\n"
|
||||
" :type sound: :class:`Sound`\n\n"
|
||||
|
@ -1685,7 +1685,7 @@ Sound_list_addSound(Sound* self, PyObject* object)
|
|||
#ifdef WITH_CONVOLUTION
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_convolver_doc,
|
||||
".. classmethod:: convolver()\n\n"
|
||||
".. method:: convolver()\n\n"
|
||||
" Creates a sound that will apply convolution to another sound.\n\n"
|
||||
" :arg impulseResponse: The filter with which convolve the sound.\n"
|
||||
" :type impulseResponse: :class:`ImpulseResponse`\n"
|
||||
|
@ -1734,7 +1734,7 @@ Sound_convolver(Sound* self, PyObject* args)
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_binaural_doc,
|
||||
".. classmethod:: convolver()\n\n"
|
||||
".. method:: binaural()\n\n"
|
||||
" Creates a binaural sound using another sound as source. The original sound must be mono\n\n"
|
||||
" :arg hrtfs: An HRTF set.\n"
|
||||
" :type hrtf: :class:`HRTF`\n"
|
||||
|
|
|
@ -2446,6 +2446,14 @@ def draw_pause(self, context):
|
|||
layout.prop(cscene, "preview_pause", icon='PLAY' if cscene.preview_pause else 'PAUSE', text="")
|
||||
|
||||
|
||||
def draw_make_links(self, context):
|
||||
if context.engine == "CYCLES":
|
||||
layout = self.layout
|
||||
layout.separator()
|
||||
layout.operator_menu_enum("object.light_linking_receivers_link", "link_state")
|
||||
layout.operator_menu_enum("object.light_linking_blockers_link", "link_state")
|
||||
|
||||
|
||||
def get_panels():
|
||||
exclude_panels = {
|
||||
'DATA_PT_camera_dof',
|
||||
|
@ -2584,6 +2592,7 @@ def register():
|
|||
|
||||
bpy.types.RENDER_PT_context.append(draw_device)
|
||||
bpy.types.VIEW3D_HT_header.append(draw_pause)
|
||||
bpy.types.VIEW3D_MT_make_links.append(draw_make_links)
|
||||
|
||||
for panel in get_panels():
|
||||
panel.COMPAT_ENGINES.add('CYCLES')
|
||||
|
@ -2597,6 +2606,7 @@ def unregister():
|
|||
|
||||
bpy.types.RENDER_PT_context.remove(draw_device)
|
||||
bpy.types.VIEW3D_HT_header.remove(draw_pause)
|
||||
bpy.types.VIEW3D_MT_make_links.remove(draw_make_links)
|
||||
|
||||
for panel in get_panels():
|
||||
if 'CYCLES' in panel.COMPAT_ENGINES:
|
||||
|
|
|
@ -38,6 +38,8 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
|||
}
|
||||
}
|
||||
|
||||
light->name = b_light.name().c_str();
|
||||
|
||||
/* type */
|
||||
switch (b_light.type()) {
|
||||
case BL::Light::type_POINT: {
|
||||
|
|
|
@ -396,7 +396,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
|
|||
* - Purely reflective closures can't have refraction.
|
||||
* - Purely refractive closures can't have reflection.
|
||||
*/
|
||||
if ((cos_NI <= 0) || (alpha_x * alpha_y <= 1e-7f) || ((cos_NgO < 0.0f) != is_refraction) ||
|
||||
if ((cos_NI <= 0) || (alpha_x * alpha_y <= 5e-7f) || ((cos_NgO < 0.0f) != is_refraction) ||
|
||||
(is_refraction && !m_refractive) || (!is_refraction && m_refractive && !m_glass))
|
||||
{
|
||||
*pdf = 0.0f;
|
||||
|
@ -478,7 +478,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
|
|||
const bool m_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type);
|
||||
const float alpha_x = bsdf->alpha_x;
|
||||
const float alpha_y = bsdf->alpha_y;
|
||||
bool m_singular = (m_type == MicrofacetType::SHARP) || (alpha_x * alpha_y <= 1e-7f);
|
||||
bool m_singular = (m_type == MicrofacetType::SHARP) || (alpha_x * alpha_y <= 5e-7f);
|
||||
|
||||
const float3 N = bsdf->N;
|
||||
const float cos_NI = dot(N, wi);
|
||||
|
|
|
@ -32,6 +32,14 @@ ccl_device_inline void integrate_camera_sample(KernelGlobals kg,
|
|||
path_rng_3D(kg, rng_hash, sample, PRNG_LENS_TIME) :
|
||||
zero_float3();
|
||||
|
||||
/* We use x for time and y,z for lens because in practice with Sobol
|
||||
* sampling this seems to give better convergence when an object is
|
||||
* both motion blurred and out of focus, without significantly harming
|
||||
* convergence for focal blur alone. This is a little surprising,
|
||||
* because one would expect using x,y for lens (the 2d part) would be
|
||||
* best, since x,y are the best stratified. Since it's not entirely
|
||||
* clear why this is, this is probably worth revisiting at some point
|
||||
* to investigate further. */
|
||||
const float rand_time = rand_time_lens.x;
|
||||
const float2 rand_lens = make_float2(rand_time_lens.y, rand_time_lens.z);
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ ccl_device int shadow_linking_pick_mesh_intersection(KernelGlobals kg,
|
|||
}
|
||||
|
||||
/* Only record primitives that potentially have emission.
|
||||
* TODO: optimize with a dedicated ray visiblity flag, which could then also be
|
||||
* TODO: optimize with a dedicated ray visibility flag, which could then also be
|
||||
* used once lights are in the BVH as geometry? */
|
||||
const int shader = intersection_get_shader(kg, ¤t_isect);
|
||||
const int shader_flags = kernel_data_fetch(shaders, shader).flags;
|
||||
|
|
|
@ -483,12 +483,7 @@ ccl_device_forceinline bool mnee_newton_solver(KernelGlobals kg,
|
|||
if (!hit)
|
||||
break;
|
||||
|
||||
// TODO: Is the fetch needed here? The shade_surface simply reads isect->object.
|
||||
int hit_object = (projection_isect.object == OBJECT_NONE) ?
|
||||
kernel_data_fetch(prim_object, projection_isect.prim) :
|
||||
projection_isect.object;
|
||||
|
||||
if (hit_object == mv.object) {
|
||||
if (projection_isect.object == mv.object) {
|
||||
projection_success = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -140,7 +140,9 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
|
|||
#endif
|
||||
|
||||
#ifdef __LIGHT_LINKING__
|
||||
if (!light_link_light_match(kg, light_link_receiver_forward(kg, state), lamp)) {
|
||||
if (!light_link_light_match(kg, light_link_receiver_forward(kg, state), lamp) &&
|
||||
!(path_flag & PATH_RAY_CAMERA))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "kernel/integrator/path_state.h"
|
||||
#include "kernel/integrator/shade_surface.h"
|
||||
|
||||
#include "kernel/light/distant.h"
|
||||
#include "kernel/light/light.h"
|
||||
#include "kernel/light/sample.h"
|
||||
|
||||
#include "kernel/integrator/shade_surface.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "kernel/film/denoising_passes.h"
|
||||
#include "kernel/film/light_passes.h"
|
||||
|
||||
#include "kernel/light/sample.h"
|
||||
|
||||
#include "kernel/integrator/mnee.h"
|
||||
|
||||
#include "kernel/integrator/guiding.h"
|
||||
|
@ -17,8 +19,6 @@
|
|||
#include "kernel/integrator/subsurface.h"
|
||||
#include "kernel/integrator/volume_stack.h"
|
||||
|
||||
#include "kernel/light/sample.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_forceinline void integrate_surface_shader_setup(KernelGlobals kg,
|
||||
|
@ -113,14 +113,16 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
|
|||
ccl_global float *ccl_restrict
|
||||
render_buffer)
|
||||
{
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
|
||||
#ifdef __LIGHT_LINKING__
|
||||
if (!light_link_object_match(kg, light_link_receiver_forward(kg, state), sd->object)) {
|
||||
if (!light_link_object_match(kg, light_link_receiver_forward(kg, state), sd->object) &&
|
||||
!(path_flag & PATH_RAY_CAMERA))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
|
||||
#ifdef __SHADOW_LINKING__
|
||||
/* Indirect emission of shadow-linked emissive surfaces is done via shadow rays to dedicated
|
||||
* light sources. */
|
||||
|
@ -284,8 +286,8 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
|
|||
|
||||
const bool is_transmission = dot(ls.D, sd->N) < 0.0f;
|
||||
|
||||
#ifdef __MNEE__
|
||||
int mnee_vertex_count = 0;
|
||||
#ifdef __MNEE__
|
||||
IF_KERNEL_FEATURE(MNEE)
|
||||
{
|
||||
if (ls.lamp != LAMP_NONE) {
|
||||
|
|
|
@ -95,9 +95,9 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg,
|
|||
bssrdf_sampling_fraction /= bsdf_bssrdf_sampling_sum;
|
||||
}
|
||||
|
||||
/* Init guiding */
|
||||
/* The the roughness because the function returns alpha.x * alpha.y. In addition alpha is squared
|
||||
* again */
|
||||
/* Initial guiding */
|
||||
/* The roughness because the function returns `alpha.x * alpha.y`.
|
||||
* In addition alpha is squared again. */
|
||||
float avg_roughness = surface_shader_average_sample_weight_squared_roughness(sd);
|
||||
avg_roughness = safe_sqrtf(avg_roughness);
|
||||
if (!fully_opaque || avg_roughness < guiding_roughness_threshold ||
|
||||
|
|
|
@ -54,8 +54,7 @@ ccl_device float3 background_map_sample(KernelGlobals kg, float2 rand, ccl_priva
|
|||
int middle = first + step;
|
||||
|
||||
if (kernel_data_fetch(light_background_conditional_cdf, index_v * cdf_width + middle).y <
|
||||
rand.x)
|
||||
{
|
||||
rand.x) {
|
||||
first = middle + 1;
|
||||
count -= step + 1;
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ ccl_device_forceinline int lights_intersect_impl(KernelGlobals kg,
|
|||
|
||||
#ifdef __LIGHT_LINKING__
|
||||
/* Light linking. */
|
||||
if (!light_link_light_match(kg, receiver_forward, lamp)) {
|
||||
if (!light_link_light_match(kg, receiver_forward, lamp) && !(path_flag & PATH_RAY_CAMERA)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -29,9 +29,6 @@ ccl_device_inline bool point_light_sample(const ccl_global KernelLight *klight,
|
|||
ls->Ng = -ls->D;
|
||||
|
||||
ls->eval_fac = M_1_PI_F * 0.25f * klight->spot.invarea;
|
||||
if (!in_volume_segment && ls->eval_fac == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float2 uv = map_to_sphere(ls->Ng);
|
||||
ls->u = uv.x;
|
||||
|
@ -90,10 +87,6 @@ ccl_device_inline bool point_light_sample_from_intersection(
|
|||
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
|
||||
ls->pdf = invarea;
|
||||
|
||||
if (ls->eval_fac == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float2 uv = map_to_sphere(ls->Ng);
|
||||
ls->u = uv.x;
|
||||
ls->v = uv.y;
|
||||
|
|
|
@ -13,6 +13,20 @@ CCL_NAMESPACE_BEGIN
|
|||
* this single threaded on a CPU for repeatable results. */
|
||||
//#define __DEBUG_CORRELATION__
|
||||
|
||||
/*
|
||||
* The `path_rng_*()` functions below use a shuffled scrambled Sobol
|
||||
* sequence to generate their samples. Sobol samplers have a property
|
||||
* that is worth being aware of when choosing how to use the sample
|
||||
* dimensions:
|
||||
*
|
||||
* 1. In general, earlier sets of dimensions are better stratified. So
|
||||
* prefer e.g. x,y over y,z over z,w for the things that are most
|
||||
* important to sample well.
|
||||
* 2. As a rule of thumb, dimensions that are closer to each other are
|
||||
* better stratified than dimensions that are far. So prefer e.g.
|
||||
* x,y over x,z.
|
||||
*/
|
||||
|
||||
ccl_device_forceinline float path_rng_1D(KernelGlobals kg,
|
||||
uint rng_hash,
|
||||
int sample,
|
||||
|
|
|
@ -174,6 +174,24 @@ bool Light::has_contribution(Scene *scene)
|
|||
return !is_zero(effective_shader->emission_estimate);
|
||||
}
|
||||
|
||||
bool Light::has_light_linking() const
|
||||
{
|
||||
if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Light::has_shadow_linking() const
|
||||
{
|
||||
if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Light Manager */
|
||||
|
||||
LightManager::LightManager()
|
||||
|
|
|
@ -82,6 +82,10 @@ class Light : public Node {
|
|||
/* Check whether the light has contribution the scene. */
|
||||
bool has_contribution(Scene *scene);
|
||||
|
||||
/* Check whether this light participates in light or shadow linking. */
|
||||
bool has_light_linking() const;
|
||||
bool has_shadow_linking() const;
|
||||
|
||||
friend class LightManager;
|
||||
friend class LightTree;
|
||||
};
|
||||
|
|
|
@ -276,6 +276,7 @@ struct LightTreeNode {
|
|||
__forceinline void add(const LightTreeEmitter &emitter)
|
||||
{
|
||||
measure.add(emitter.measure);
|
||||
light_link.add(emitter.light_set_membership);
|
||||
}
|
||||
|
||||
__forceinline Leaf &get_leaf()
|
||||
|
|
|
@ -403,6 +403,32 @@ bool Object::usable_as_light() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Object::has_light_linking() const
|
||||
{
|
||||
if (get_receiver_light_set()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Object::has_shadow_linking() const
|
||||
{
|
||||
if (get_blocker_shadow_set()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Object Manager */
|
||||
|
||||
ObjectManager::ObjectManager()
|
||||
|
|
|
@ -113,6 +113,11 @@ class Object : public Node {
|
|||
/* Check whether this object can be used as light-emissive. */
|
||||
bool usable_as_light() const;
|
||||
|
||||
/* Check whether the object participates in light or shadow linking, either as a receiver/blocker
|
||||
* or emitter. */
|
||||
bool has_light_linking() const;
|
||||
bool has_shadow_linking() const;
|
||||
|
||||
protected:
|
||||
/* Specifies the position of the object in scene->objects and
|
||||
* in the device vectors. Gets set in device_update. */
|
||||
|
|
|
@ -491,10 +491,10 @@ void Scene::update_kernel_features()
|
|||
else if (geom->is_pointcloud()) {
|
||||
kernel_features |= KERNEL_FEATURE_POINTCLOUD;
|
||||
}
|
||||
if (object->get_receiver_light_set()) {
|
||||
if (object->has_light_linking()) {
|
||||
kernel_features |= KERNEL_FEATURE_LIGHT_LINKING;
|
||||
}
|
||||
if (object->get_blocker_shadow_set()) {
|
||||
if (object->has_shadow_linking()) {
|
||||
kernel_features |= KERNEL_FEATURE_SHADOW_LINKING;
|
||||
}
|
||||
}
|
||||
|
@ -503,6 +503,13 @@ void Scene::update_kernel_features()
|
|||
if (light->get_use_caustics()) {
|
||||
has_caustics_light = true;
|
||||
}
|
||||
|
||||
if (light->has_light_linking()) {
|
||||
kernel_features |= KERNEL_FEATURE_LIGHT_LINKING;
|
||||
}
|
||||
if (light->has_shadow_linking()) {
|
||||
kernel_features |= KERNEL_FEATURE_SHADOW_LINKING;
|
||||
}
|
||||
}
|
||||
|
||||
dscene.data.integrator.use_caustics = false;
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
# define HAVE_MALLOC_STATS
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <malloc_np.h>
|
||||
#elif defined(__OpenBSD__)
|
||||
# undef USE_MALLOC_USABLE_SIZE
|
||||
#elif defined(__APPLE__)
|
||||
# include <malloc/malloc.h>
|
||||
# define malloc_usable_size malloc_size
|
||||
|
|
|
@ -1836,7 +1836,8 @@ def km_graph_editor(params):
|
|||
("graph.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
|
||||
("graph.paste", {"type": 'V', "value": 'PRESS', "shift": True, "ctrl": True},
|
||||
{"properties": [("flipped", True)]}),
|
||||
op_menu("GRAPH_MT_slider", {"type": 'D', "value": 'PRESS'}),
|
||||
op_menu("GRAPH_MT_key_smoothing", {"type": 'S', "value": 'PRESS', "alt": True}),
|
||||
op_menu("GRAPH_MT_key_blending", {"type": 'D', "value": 'PRESS', "alt": True}),
|
||||
("graph.previewrange_set", {"type": 'P', "value": 'PRESS', "ctrl": True, "alt": True}, None),
|
||||
("graph.view_all", {"type": 'HOME', "value": 'PRESS'}, None),
|
||||
("graph.view_all", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None),
|
||||
|
@ -4582,7 +4583,6 @@ def km_pose(params):
|
|||
("pose.breakdown", {"type": 'E', "value": 'PRESS', "shift": True}, None),
|
||||
("pose.blend_to_neighbor", {"type": 'E', "value": 'PRESS', "shift": True, "alt": True}, None),
|
||||
op_menu("VIEW3D_MT_pose_propagate", {"type": 'P', "value": 'PRESS', "alt": True}),
|
||||
*_template_object_hide_collection_from_number_keys(),
|
||||
*_template_items_context_menu("VIEW3D_MT_pose_context_menu", params.context_menu_event),
|
||||
])
|
||||
|
||||
|
|
|
@ -372,19 +372,6 @@ class GRAPH_MT_key_snap(Menu):
|
|||
layout.operator("graph.snap_cursor_value", text="Cursor Value to Selection")
|
||||
|
||||
|
||||
class GRAPH_MT_slider(Menu):
|
||||
bl_label = "Slider Operators"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator("graph.breakdown", text="Breakdown")
|
||||
layout.operator("graph.blend_to_neighbor", text="Blend to Neighbor")
|
||||
layout.operator("graph.blend_to_default", text="Blend to Default Value")
|
||||
layout.operator("graph.ease", text="Ease")
|
||||
layout.operator("graph.gaussian_smooth", text="Smooth")
|
||||
|
||||
|
||||
class GRAPH_MT_view_pie(Menu):
|
||||
bl_label = "View"
|
||||
|
||||
|
@ -526,7 +513,6 @@ classes = (
|
|||
GRAPH_MT_key_snap,
|
||||
GRAPH_MT_key_smoothing,
|
||||
GRAPH_MT_key_blending,
|
||||
GRAPH_MT_slider,
|
||||
GRAPH_MT_delete,
|
||||
GRAPH_MT_context_menu,
|
||||
GRAPH_MT_channel_context_menu,
|
||||
|
|
|
@ -3046,10 +3046,6 @@ class VIEW3D_MT_make_links(Menu):
|
|||
layout.operator("object.data_transfer")
|
||||
layout.operator("object.datalayout_transfer")
|
||||
|
||||
layout.separator()
|
||||
layout.operator_menu_enum("object.light_linking_receivers_link", "link_state")
|
||||
layout.operator_menu_enum("object.light_linking_blockers_link", "link_state")
|
||||
|
||||
|
||||
class VIEW3D_MT_brush_paint_modes(Menu):
|
||||
bl_label = "Enabled Modes"
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
|
@ -113,7 +114,7 @@ static int blf_search_by_filepath(const char *filepath)
|
|||
{
|
||||
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||
const FontBLF *font = global_font[i];
|
||||
if (font && STREQ(font->filepath, filepath)) {
|
||||
if (font && (BLI_path_cmp(font->filepath, filepath) == 0)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +250,7 @@ void BLF_unload(const char *filepath)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (STREQ(font->filepath, filepath)) {
|
||||
if (BLI_path_cmp(font->filepath, filepath) == 0) {
|
||||
BLI_assert(font->reference_count > 0);
|
||||
font->reference_count--;
|
||||
|
||||
|
|
|
@ -1436,7 +1436,9 @@ bool blf_ensure_face(FontBLF *font)
|
|||
* from our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the
|
||||
* same
|
||||
* (#101506). Enable again later with change of font, placement, or rendering - Harley. */
|
||||
if (font && font->filepath && BLI_str_endswith(font->filepath, BLF_DEFAULT_PROPORTIONAL_FONT)) {
|
||||
if (font && font->filepath &&
|
||||
(BLI_path_cmp(BLI_path_basename(font->filepath), BLF_DEFAULT_PROPORTIONAL_FONT) == 0))
|
||||
{
|
||||
font->face_flags &= ~FT_FACE_FLAG_KERNING;
|
||||
}
|
||||
|
||||
|
@ -1547,7 +1549,7 @@ static FontBLF *blf_font_new_impl(const char *filepath,
|
|||
if (font->filepath) {
|
||||
const char *filename = BLI_path_basename(font->filepath);
|
||||
for (int i = 0; i < (int)ARRAY_SIZE(static_face_details); i++) {
|
||||
if (STREQ(static_face_details[i].filename, filename)) {
|
||||
if (BLI_path_cmp(static_face_details[i].filename, filename) == 0) {
|
||||
const struct FaceDetails *static_details = &static_face_details[i];
|
||||
font->unicode_ranges[0] = static_details->coverage1;
|
||||
font->unicode_ranges[1] = static_details->coverage2;
|
||||
|
|
|
@ -28,6 +28,9 @@ typedef enum LightLinkingType {
|
|||
LIGHT_LINKING_BLOCKER,
|
||||
} LightLinkingType;
|
||||
|
||||
/* Free object's light_linking if it is not needed to hold any of collections. */
|
||||
void BKE_light_linking_free_if_empty(struct Object *object);
|
||||
|
||||
/* Get a collection of the given light linking type of the given object. */
|
||||
struct Collection *BKE_light_linking_collection_get(const struct Object *object,
|
||||
LightLinkingType link_type);
|
||||
|
|
|
@ -2495,7 +2495,7 @@ static void lib_override_resync_tagging_finalize_recurse(Main *bmain,
|
|||
}
|
||||
else if (!is_in_partial_resync_hierarchy) {
|
||||
/* This ID is not tagged for resync, and is part of a loop where none of the other IDs are
|
||||
* tagged for resync, nothing else to to. */
|
||||
* tagged for resync, nothing else to do. */
|
||||
return;
|
||||
}
|
||||
/* This ID is not yet tagged for resync, but is part of a loop which is (partially) tagged
|
||||
|
@ -4207,7 +4207,7 @@ void BKE_lib_override_library_main_operations_restore(Main *bmain, int *r_report
|
|||
ID *id;
|
||||
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id) {
|
||||
if (!(!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
|
||||
if (!(!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY_REAL(id) && id->override_library->runtime &&
|
||||
(id->override_library->runtime->tag & LIBOVERRIDE_TAG_NEEDS_RESTORE) != 0))
|
||||
{
|
||||
continue;
|
||||
|
|
|
@ -25,6 +25,15 @@
|
|||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_build.h"
|
||||
|
||||
void BKE_light_linking_free_if_empty(Object *object)
|
||||
{
|
||||
if (object->light_linking->receiver_collection == nullptr &&
|
||||
object->light_linking->blocker_collection == nullptr)
|
||||
{
|
||||
MEM_SAFE_FREE(object->light_linking);
|
||||
}
|
||||
}
|
||||
|
||||
Collection *BKE_light_linking_collection_get(const Object *object,
|
||||
const LightLinkingType link_type)
|
||||
{
|
||||
|
@ -108,12 +117,7 @@ void BKE_light_linking_collection_assign_only(struct Object *object,
|
|||
id_us_plus(&new_collection->id);
|
||||
}
|
||||
|
||||
/* Free if empty. */
|
||||
if (object->light_linking->receiver_collection == nullptr &&
|
||||
object->light_linking->blocker_collection == nullptr)
|
||||
{
|
||||
MEM_SAFE_FREE(object->light_linking);
|
||||
}
|
||||
BKE_light_linking_free_if_empty(object);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,8 +186,11 @@ void BKE_light_linking_add_receiver_to_collection(Main *bmain,
|
|||
CollectionLightLinking *collection_light_linking = nullptr;
|
||||
|
||||
if (id_type == ID_OB) {
|
||||
collection_light_linking = light_linking_collection_add_object(
|
||||
bmain, collection, reinterpret_cast<Object *>(receiver));
|
||||
Object *object = reinterpret_cast<Object *>(receiver);
|
||||
if (!OB_TYPE_IS_GEOMETRY(object->type)) {
|
||||
return;
|
||||
}
|
||||
collection_light_linking = light_linking_collection_add_object(bmain, collection, object);
|
||||
}
|
||||
else if (id_type == ID_GR) {
|
||||
collection_light_linking = light_linking_collection_add_collection(
|
||||
|
@ -240,6 +247,10 @@ void BKE_light_linking_link_receiver_to_emitter(Main *bmain,
|
|||
const LightLinkingType link_type,
|
||||
const eCollectionLightLinkingState link_state)
|
||||
{
|
||||
if (!OB_TYPE_IS_GEOMETRY(receiver->type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection *collection = BKE_light_linking_collection_get(emitter, link_type);
|
||||
|
||||
if (!collection) {
|
||||
|
|
|
@ -1444,6 +1444,16 @@ static void sculptsession_free_pbvh(Object *object)
|
|||
ss->pbvh = nullptr;
|
||||
}
|
||||
|
||||
ss->vert_to_poly_offsets = {};
|
||||
ss->vert_to_poly_indices = {};
|
||||
ss->pmap = {};
|
||||
ss->edge_to_poly_offsets = {};
|
||||
ss->edge_to_poly_indices = {};
|
||||
ss->epmap = {};
|
||||
ss->vert_to_edge_offsets = {};
|
||||
ss->vert_to_edge_indices = {};
|
||||
ss->vemap = {};
|
||||
|
||||
MEM_SAFE_FREE(ss->preview_vert_list);
|
||||
ss->preview_vert_count = 0;
|
||||
|
||||
|
|
|
@ -1418,7 +1418,7 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes)
|
|||
});
|
||||
},
|
||||
[&]() {
|
||||
/* Update all normals connected to affected faces faces, even if not explicitly tagged. */
|
||||
/* Update all normals connected to affected faces, even if not explicitly tagged. */
|
||||
verts_to_update.reserve(polys_to_update.size());
|
||||
for (const int poly : polys_to_update) {
|
||||
verts_to_update.add_multiple(corner_verts.slice(polys[poly]));
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace blender::index_mask {
|
|||
* - The second most-significant bit is not used for indices so that #max_segment_size itself can
|
||||
* be stored in the #int16_t.
|
||||
* - The maximum number of indices in a segment is 16384, which is generally enough to make the
|
||||
* overhead per segment negilible when processing large index masks.
|
||||
* overhead per segment negligible when processing large index masks.
|
||||
* - A power of two is used for #max_segment_size, because that allows for faster construction of
|
||||
* index masks for index ranges.
|
||||
*/
|
||||
|
@ -335,7 +335,7 @@ class IndexMask : private IndexMaskData {
|
|||
*/
|
||||
void to_bits(MutableBitSpan r_bits) const;
|
||||
/**
|
||||
* Set the bools at indies inthe mask to true and all others to false.
|
||||
* Set the bools at indies in the mask to true and all others to false.
|
||||
*/
|
||||
void to_bools(MutableSpan<bool> r_bools) const;
|
||||
/**
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
*
|
||||
* Ideally this could be could be even closer to Python's enumerate(). We might get that in the
|
||||
* future with newer C++ versions.
|
||||
*
|
||||
* One other important feature is the as_span method. This method returns a Span<int64_t>
|
||||
* that contains the interval as individual numbers.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -325,22 +322,11 @@ class IndexRange {
|
|||
return IndexRange(start_ + n, size_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get read-only access to a memory buffer that contains the range as actual numbers.
|
||||
*/
|
||||
Span<int64_t> as_span() const;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, IndexRange range)
|
||||
{
|
||||
stream << "[" << range.start() << ", " << range.one_after_last() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
private:
|
||||
static std::atomic<int64_t> s_current_array_size;
|
||||
static std::atomic<int64_t *> s_current_array;
|
||||
|
||||
Span<int64_t> as_span_internal() const;
|
||||
};
|
||||
|
||||
struct AlignedIndexRanges {
|
||||
|
|
|
@ -766,16 +766,4 @@ template<typename T> class MutableSpan {
|
|||
}
|
||||
};
|
||||
|
||||
/** This is defined here, because in `BLI_index_range.hh` `Span` is not yet defined. */
|
||||
inline Span<int64_t> IndexRange::as_span() const
|
||||
{
|
||||
const int64_t min_required_size = start_ + size_;
|
||||
const int64_t current_array_size = s_current_array_size.load(std::memory_order_acquire);
|
||||
const int64_t *current_array = s_current_array.load(std::memory_order_acquire);
|
||||
if (min_required_size <= current_array_size) {
|
||||
return Span<int64_t>(current_array + start_, size_);
|
||||
}
|
||||
return this->as_span_internal();
|
||||
}
|
||||
|
||||
} /* namespace blender */
|
||||
|
|
|
@ -10,40 +10,6 @@
|
|||
|
||||
namespace blender {
|
||||
|
||||
static RawVector<RawArray<int64_t, 0>> arrays;
|
||||
static std::mutex current_array_mutex;
|
||||
std::atomic<int64_t> IndexRange::s_current_array_size = 0;
|
||||
std::atomic<int64_t *> IndexRange::s_current_array = nullptr;
|
||||
|
||||
Span<int64_t> IndexRange::as_span_internal() const
|
||||
{
|
||||
int64_t min_required_size = start_ + size_;
|
||||
|
||||
std::lock_guard<std::mutex> lock(current_array_mutex);
|
||||
|
||||
/* Double checked lock. */
|
||||
if (min_required_size <= s_current_array_size) {
|
||||
return Span<int64_t>(s_current_array + start_, size_);
|
||||
}
|
||||
|
||||
/* Isolate, because a mutex is locked. */
|
||||
threading::isolate_task([&]() {
|
||||
int64_t new_size = std::max<int64_t>(1000, power_of_2_max_u(min_required_size));
|
||||
RawArray<int64_t, 0> new_array(new_size);
|
||||
threading::parallel_for(IndexRange(new_size), 4096, [&](const IndexRange range) {
|
||||
for (const int64_t i : range) {
|
||||
new_array[i] = i;
|
||||
}
|
||||
});
|
||||
arrays.append(std::move(new_array));
|
||||
|
||||
s_current_array.store(arrays.last().data(), std::memory_order_release);
|
||||
s_current_array_size.store(new_size, std::memory_order_release);
|
||||
});
|
||||
|
||||
return Span<int64_t>(s_current_array + start_, size_);
|
||||
}
|
||||
|
||||
AlignedIndexRanges split_index_range_by_alignment(const IndexRange range, const int64_t alignment)
|
||||
{
|
||||
BLI_assert(is_power_of_2_i(alignment));
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
namespace blender::offset_indices {
|
||||
|
||||
OffsetIndices<int> accumulate_counts_to_offsets(MutableSpan<int> counts_to_offsets, const int start_offset)
|
||||
OffsetIndices<int> accumulate_counts_to_offsets(MutableSpan<int> counts_to_offsets,
|
||||
const int start_offset)
|
||||
{
|
||||
int offset = start_offset;
|
||||
for (const int i : counts_to_offsets.index_range().drop_back(1)) {
|
||||
|
|
|
@ -655,7 +655,7 @@ void BLI_path_normalize_unc_16(wchar_t *path_16)
|
|||
void BLI_path_rel(char path[FILE_MAX], const char *basepath)
|
||||
{
|
||||
BLI_string_debug_size_after_nil(path, FILE_MAX);
|
||||
/* A `basepath` starting with `//` will be be made relative multiple times. */
|
||||
/* A `basepath` starting with `//` will be made relative multiple times. */
|
||||
BLI_assert_msg(!BLI_path_is_rel(basepath), "The 'basepath' cannot start with '//'!");
|
||||
|
||||
const char *lslash;
|
||||
|
@ -1095,7 +1095,7 @@ void BLI_path_to_display_name(char *display_name, int display_name_maxncpy, cons
|
|||
bool BLI_path_abs(char path[FILE_MAX], const char *basepath)
|
||||
{
|
||||
BLI_string_debug_size_after_nil(path, FILE_MAX);
|
||||
/* A `basepath` starting with `//` will be be made absolute multiple times. */
|
||||
/* A `basepath` starting with `//` will be made absolute multiple times. */
|
||||
BLI_assert_msg(!BLI_path_is_rel(basepath), "The 'basepath' cannot start with '//'!");
|
||||
|
||||
const bool wasrelative = BLI_path_is_rel(path);
|
||||
|
|
|
@ -44,7 +44,8 @@ int BLI_windows_get_executable_dir(char *str)
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool BLI_windows_is_store_install(void) {
|
||||
bool BLI_windows_is_store_install(void)
|
||||
{
|
||||
char install_dir[FILE_MAXDIR];
|
||||
BLI_windows_get_executable_dir(install_dir);
|
||||
return (BLI_strcasestr(install_dir, "\\WindowsApps\\") != NULL);
|
||||
|
|
|
@ -219,17 +219,6 @@ TEST(index_range, TakeBackLargeN)
|
|||
EXPECT_EQ(slice.size(), 4);
|
||||
}
|
||||
|
||||
TEST(index_range, AsSpan)
|
||||
{
|
||||
IndexRange range = IndexRange(4, 6);
|
||||
Span<int64_t> span = range.as_span();
|
||||
EXPECT_EQ(span.size(), 6);
|
||||
EXPECT_EQ(span[0], 4);
|
||||
EXPECT_EQ(span[1], 5);
|
||||
EXPECT_EQ(span[2], 6);
|
||||
EXPECT_EQ(span[3], 7);
|
||||
}
|
||||
|
||||
TEST(index_range, constexpr_)
|
||||
{
|
||||
constexpr IndexRange range = IndexRange(1, 1);
|
||||
|
|
|
@ -90,7 +90,7 @@ TEST(string, StrCopyUTF8_TruncateEncoding)
|
|||
TEST(string, StrCopyUTF8_TerminateEncodingEarly)
|
||||
{
|
||||
/* A UTF8 sequence that has a null byte before the sequence ends.
|
||||
* Ensure the the UTF8 sequence does not step over the null byte. */
|
||||
* Ensure the UTF8 sequence does not step over the null byte. */
|
||||
#define STRNCPY_UTF8_TERMINATE_EARLY(byte_size, ...) \
|
||||
{ \
|
||||
char src[] = {__VA_ARGS__, 0}; \
|
||||
|
|
|
@ -3984,7 +3984,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
|
||||
/* In case the current scene is a liboverride, while the ID pointer itself remains valid,
|
||||
* above update of liboverrides will have completely invalidated its old content, so the
|
||||
* current viewlayer needs to be searched for again. */
|
||||
* current view-layer needs to be searched for again. */
|
||||
if (bfd->cur_view_layer != nullptr) {
|
||||
bfd->cur_view_layer = BKE_view_layer_find(bfd->curscene, cur_view_layer_name.c_str());
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ struct Object *DEG_get_original_object(struct Object *object);
|
|||
struct ID *DEG_get_original_id(struct ID *id);
|
||||
|
||||
/**
|
||||
* Check whether given ID is an original,
|
||||
* Check whether given ID is an original.
|
||||
*
|
||||
* Original IDs are considered all the IDs which are not covered by copy-on-write system and are
|
||||
* not out-of-main localized data-blocks.
|
||||
|
|
|
@ -61,6 +61,13 @@ template<class T> static inline const T *get_original(const T *id)
|
|||
return reinterpret_cast<T *>(DEG_get_original_id(const_cast<ID *>(&id->id)));
|
||||
}
|
||||
|
||||
/* Check whether the ID is suitable to be an input of the dependency graph. */
|
||||
/* TODO(sergey): Move the function and check to a more generic place. */
|
||||
bool is_valid_input_id(const ID &id)
|
||||
{
|
||||
return (id.tag & LIB_TAG_LOCALIZED) || DEG_is_original_id(&id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace blender::deg::light_linking {
|
||||
|
@ -153,7 +160,7 @@ void EmitterDataMap::clear()
|
|||
|
||||
EmitterData *EmitterDataMap::ensure_data_if_possible(const Scene &scene, const Object &emitter)
|
||||
{
|
||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
||||
BLI_assert(is_valid_input_id(emitter.id));
|
||||
|
||||
const Collection *collection = get_collection(emitter);
|
||||
BLI_assert(collection);
|
||||
|
@ -209,7 +216,7 @@ const EmitterData *EmitterDataMap::get_data(const Object &emitter) const
|
|||
|
||||
bool EmitterDataMap::can_skip_emitter(const Object &emitter) const
|
||||
{
|
||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
||||
BLI_assert(is_valid_input_id(emitter.id));
|
||||
|
||||
const Collection *collection = get_collection(emitter);
|
||||
|
||||
|
@ -249,7 +256,7 @@ void LinkingData::link_object(const EmitterData &emitter_data,
|
|||
|
||||
LightSet &LinkingData::ensure_light_set_for(const Object &object)
|
||||
{
|
||||
BLI_assert(DEG_is_original_id(&object.id));
|
||||
BLI_assert(is_valid_input_id(object.id));
|
||||
|
||||
return light_linked_sets_.lookup_or_add_as(&object);
|
||||
}
|
||||
|
@ -363,7 +370,7 @@ void Cache::clear()
|
|||
|
||||
void Cache::add_emitter(const Scene &scene, const Object &emitter)
|
||||
{
|
||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
||||
BLI_assert(is_valid_input_id(emitter.id));
|
||||
|
||||
add_light_linking_emitter(scene, emitter);
|
||||
add_shadow_linking_emitter(scene, emitter);
|
||||
|
@ -371,7 +378,7 @@ void Cache::add_emitter(const Scene &scene, const Object &emitter)
|
|||
|
||||
void Cache::add_light_linking_emitter(const Scene &scene, const Object &emitter)
|
||||
{
|
||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
||||
BLI_assert(is_valid_input_id(emitter.id));
|
||||
|
||||
if (light_emitter_data_map_.can_skip_emitter(emitter)) {
|
||||
return;
|
||||
|
@ -390,7 +397,7 @@ void Cache::add_light_linking_emitter(const Scene &scene, const Object &emitter)
|
|||
|
||||
void Cache::add_shadow_linking_emitter(const Scene &scene, const Object &emitter)
|
||||
{
|
||||
BLI_assert(DEG_is_original_id(&emitter.id));
|
||||
BLI_assert(is_valid_input_id(emitter.id));
|
||||
|
||||
if (shadow_emitter_data_map_.can_skip_emitter(emitter)) {
|
||||
return;
|
||||
|
@ -411,7 +418,7 @@ void Cache::add_receiver_object(const EmitterData &emitter_data,
|
|||
const CollectionLightLinking &collection_light_linking,
|
||||
const Object &receiver)
|
||||
{
|
||||
BLI_assert(DEG_is_original_id(&receiver.id));
|
||||
BLI_assert(is_valid_input_id(receiver.id));
|
||||
|
||||
if (!can_link_to_emitter(receiver)) {
|
||||
return;
|
||||
|
@ -425,7 +432,7 @@ void Cache::add_blocker_object(const EmitterData &emitter_data,
|
|||
const CollectionLightLinking &collection_light_linking,
|
||||
const Object &blocker)
|
||||
{
|
||||
BLI_assert(DEG_is_original_id(&blocker.id));
|
||||
BLI_assert(is_valid_input_id(blocker.id));
|
||||
|
||||
if (!can_link_to_emitter(blocker)) {
|
||||
return;
|
||||
|
@ -483,11 +490,18 @@ void Cache::eval_runtime_data(Object &object_eval) const
|
|||
runtime.shadow_set_membership = EmitterSetMembership::SET_MEMBERSHIP_ALL;
|
||||
}
|
||||
|
||||
const bool need_runtime = (memcmp(&runtime, &runtime_no_links, sizeof(runtime)) != 0);
|
||||
|
||||
/* Assign, allocating light linking on demand if needed. */
|
||||
if (object_eval.light_linking) {
|
||||
object_eval.light_linking->runtime = runtime;
|
||||
if (!need_runtime) {
|
||||
/* Note that this will only remove lazily allocated light_linking on the evaluated object,
|
||||
* as an empty light_linking is not allowed on the original object. */
|
||||
BKE_light_linking_free_if_empty(&object_eval);
|
||||
}
|
||||
}
|
||||
else if (memcmp(&runtime, &runtime_no_links, sizeof(runtime)) != 0) {
|
||||
else if (need_runtime) {
|
||||
object_eval.light_linking = MEM_cnew<LightLinking>(__func__);
|
||||
object_eval.light_linking->runtime = runtime;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ class EmitterData {
|
|||
static constexpr int MAX_COLLECTION_ID = 63;
|
||||
|
||||
/* Mask of a light linking collection this emitter uses in its configuration.
|
||||
* A single bit is set in this bitfield which corresponds to an identifier of a light linking
|
||||
* A single bit is set in this bit-field which corresponds to an identifier of a light linking
|
||||
* collection in the scene. */
|
||||
uint64_t collection_mask = 0;
|
||||
|
||||
|
@ -121,7 +121,7 @@ class EmitterDataMap {
|
|||
}
|
||||
|
||||
private:
|
||||
/* Get linked collection depending on whether this is emitter information os for light or shadow
|
||||
/* Get linked collection depending on whether this is emitter information for light or shadow
|
||||
* linking. */
|
||||
/* TODO(sergey): Check whether template specialization is preferred here. */
|
||||
inline const Collection *get_collection(const Object &emitter) const
|
||||
|
|
|
@ -32,9 +32,6 @@ void ObjectRuntimeBackup::init_from_object(Object *object)
|
|||
if (object->light_linking) {
|
||||
light_linking_runtime = object->light_linking->runtime;
|
||||
}
|
||||
else {
|
||||
memset(&light_linking_runtime, 0, sizeof(light_linking_runtime));
|
||||
}
|
||||
BKE_object_runtime_reset(object);
|
||||
/* Keep bbox (for now at least). */
|
||||
object->runtime.bb = runtime.bb;
|
||||
|
@ -128,8 +125,13 @@ void ObjectRuntimeBackup::restore_to_object(Object *object)
|
|||
}
|
||||
}
|
||||
|
||||
if (object->light_linking) {
|
||||
object->light_linking->runtime = light_linking_runtime;
|
||||
if (light_linking_runtime) {
|
||||
/* Lazily allocate light linking on the evaluated object for the cases when the object is only
|
||||
* a receiver or a blocker and does not need its own LightLinking on the original object. */
|
||||
if (!object->light_linking) {
|
||||
object->light_linking = MEM_cnew<LightLinking>(__func__);
|
||||
}
|
||||
object->light_linking->runtime = *light_linking_runtime;
|
||||
}
|
||||
|
||||
object->base_flag = base_flag;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "BLI_session_uuid.h"
|
||||
|
||||
#include "intern/depsgraph_type.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_modifier.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_pose.h"
|
||||
|
||||
|
@ -39,7 +40,7 @@ class ObjectRuntimeBackup {
|
|||
void restore_pose_channel_runtime_data(Object *object);
|
||||
|
||||
Object_Runtime runtime;
|
||||
LightLinkingRuntime light_linking_runtime;
|
||||
optional<LightLinkingRuntime> light_linking_runtime;
|
||||
short base_flag;
|
||||
unsigned short base_local_view_bits;
|
||||
Map<SessionUUID, ModifierDataBackup> modifier_runtime_data;
|
||||
|
|
|
@ -1213,7 +1213,7 @@ void EEVEE_material_transparent_output_init(EEVEE_Data *vedata)
|
|||
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->transparent_accum)});
|
||||
|
||||
{
|
||||
/* This pass Accumulate 1 sample of the transparent pass into the the transparent
|
||||
/* This pass Accumulate 1 sample of the transparent pass into the transparent
|
||||
* accumulation buffer. */
|
||||
DRW_PASS_CREATE(psl->transparent_accum_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_renderpasses_accumulate_sh_get(),
|
||||
|
|
|
@ -300,7 +300,7 @@ GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void)
|
|||
{
|
||||
if (e_data.probe_filter_visibility_sh == nullptr) {
|
||||
e_data.probe_filter_visibility_sh = DRW_shader_create_from_info_name(
|
||||
"eevee_legacy_probe_filter_visiblity");
|
||||
"eevee_legacy_probe_filter_visibility");
|
||||
}
|
||||
return e_data.probe_filter_visibility_sh;
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_probe_filter_diffuse_hl2)
|
|||
.auto_resource_location(true);
|
||||
|
||||
/* EEVEE_shaders_probe_filter_visibility_sh_get */
|
||||
GPU_SHADER_CREATE_INFO(eevee_legacy_probe_filter_visiblity)
|
||||
GPU_SHADER_CREATE_INFO(eevee_legacy_probe_filter_visibility)
|
||||
.define("IRRADIANCE_HL2")
|
||||
.additional_info("eevee_legacy_irradiance_lib")
|
||||
.additional_info("draw_fullscreen")
|
||||
|
|
|
@ -203,7 +203,7 @@ MaterialPass MaterialModule::material_pass_get(Object *ob,
|
|||
matpass.sub_pass = nullptr;
|
||||
}
|
||||
else {
|
||||
ShaderKey shader_key(matpass.gpumat, geometry_type, pipeline_type);
|
||||
ShaderKey shader_key(matpass.gpumat, geometry_type, pipeline_type, blender_mat->blend_flag);
|
||||
|
||||
PassMain::Sub *shader_sub = shader_map_.lookup_or_add_cb(shader_key, [&]() {
|
||||
/* First time encountering this shader. Create a sub that will contain materials using it. */
|
||||
|
|
|
@ -108,7 +108,7 @@ static inline eMaterialGeometry to_material_geometry(const Object *ob)
|
|||
|
||||
/** Unique key to identify each material in the hash-map. */
|
||||
struct MaterialKey {
|
||||
Material *mat;
|
||||
::Material *mat;
|
||||
uint64_t options;
|
||||
|
||||
MaterialKey(::Material *mat_, eMaterialGeometry geometry, eMaterialPipeline surface_pipeline)
|
||||
|
@ -145,10 +145,14 @@ struct ShaderKey {
|
|||
GPUShader *shader;
|
||||
uint64_t options;
|
||||
|
||||
ShaderKey(GPUMaterial *gpumat, eMaterialGeometry geometry, eMaterialPipeline pipeline)
|
||||
ShaderKey(GPUMaterial *gpumat,
|
||||
eMaterialGeometry geometry,
|
||||
eMaterialPipeline pipeline,
|
||||
char blend_flags)
|
||||
{
|
||||
shader = GPU_material_get_shader(gpumat);
|
||||
options = shader_uuid_from_material_type(pipeline, geometry);
|
||||
options = blend_flags;
|
||||
options = (options << 6u) | shader_uuid_from_material_type(pipeline, geometry);
|
||||
options = (options << 16u) | shader_closure_bits_from_flag(gpumat);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,9 @@ namespace blender::draw::overlay {
|
|||
|
||||
class Background {
|
||||
private:
|
||||
const SelectionType selection_type_;
|
||||
|
||||
PassSimple bg_ps_ = {"Background"};
|
||||
|
||||
public:
|
||||
Background(const SelectionType selection_type) : selection_type_(selection_type){};
|
||||
|
||||
void begin_sync(Resources &res, const State &state)
|
||||
{
|
||||
DRWState pass_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_BACKGROUND;
|
||||
|
|
|
@ -17,8 +17,6 @@ namespace blender::draw::overlay {
|
|||
|
||||
class Grid {
|
||||
private:
|
||||
const SelectionType selection_type_;
|
||||
|
||||
UniformBuffer<OVERLAY_GridData> data_;
|
||||
|
||||
PassSimple grid_ps_ = {"grid_ps_"};
|
||||
|
@ -32,8 +30,6 @@ class Grid {
|
|||
bool enabled_ = false;
|
||||
|
||||
public:
|
||||
Grid(const SelectionType selection_type) : selection_type_(selection_type){};
|
||||
|
||||
void begin_sync(Resources &res, const State &state, const View &view)
|
||||
{
|
||||
this->update_ubo(state, view);
|
||||
|
|
|
@ -33,11 +33,11 @@ class Instance {
|
|||
State state;
|
||||
|
||||
/** Overlay types. */
|
||||
Background background = {selection_type_};
|
||||
Prepass prepass = {selection_type_};
|
||||
Background background;
|
||||
Prepass prepass;
|
||||
Metaballs metaballs = {selection_type_};
|
||||
Empties empties = {selection_type_};
|
||||
Grid grid = {selection_type_};
|
||||
Grid grid;
|
||||
|
||||
Instance(const SelectionType selection_type) : selection_type_(selection_type){};
|
||||
|
||||
|
|
|
@ -15,14 +15,10 @@ namespace blender::draw::overlay {
|
|||
|
||||
class Prepass {
|
||||
private:
|
||||
const SelectionType selection_type_;
|
||||
|
||||
PassMain prepass_ps_ = {"prepass"};
|
||||
PassMain prepass_in_front_ps_ = {"prepass_in_front"};
|
||||
|
||||
public:
|
||||
Prepass(const SelectionType selection_type) : selection_type_(selection_type){};
|
||||
|
||||
void begin_sync(Resources &res, const State &state)
|
||||
{
|
||||
auto init_pass = [&](PassMain &pass) {
|
||||
|
|
|
@ -15,8 +15,9 @@ ShaderModule::ShaderPtr ShaderModule::selectable_shader(const char *create_info_
|
|||
/* TODO: This is what it should be like with all variations defined with create infos. */
|
||||
// std::string create_info_name = base_create_info;
|
||||
// create_info_name += SelectEngineT::shader_suffix;
|
||||
// create_info_name += ClippingEnabled ? "_clipped" : "";
|
||||
// create_info_name += clipping_enabled_ ? "_clipped" : "";
|
||||
// this->shader_ = GPU_shader_create_from_info_name(create_info_name.c_str());
|
||||
UNUSED_VARS(clipping_enabled_);
|
||||
|
||||
/* WORKAROUND: ... but for now, we have to patch the create info used by the old engine. */
|
||||
gpu::shader::ShaderCreateInfo info = *reinterpret_cast<const gpu::shader::ShaderCreateInfo *>(
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
|
|
|
@ -122,10 +122,11 @@ void DofPass::init(const SceneState &scene_state)
|
|||
int2 half_res = scene_state.resolution / 2;
|
||||
half_res = {max_ii(half_res.x, 1), max_ii(half_res.y, 1)};
|
||||
|
||||
source_tx_.ensure_2d(GPU_RGBA16F, half_res, GPU_TEXTURE_USAGE_SHADER_READ, nullptr, 3);
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
|
||||
source_tx_.ensure_2d(GPU_RGBA16F, half_res, usage, nullptr, 3);
|
||||
source_tx_.ensure_mip_views();
|
||||
source_tx_.filter_mode(true);
|
||||
coc_halfres_tx_.ensure_2d(GPU_RG8, half_res, GPU_TEXTURE_USAGE_SHADER_READ, nullptr, 3);
|
||||
coc_halfres_tx_.ensure_2d(GPU_RG8, half_res, usage, nullptr, 3);
|
||||
coc_halfres_tx_.ensure_mip_views();
|
||||
coc_halfres_tx_.filter_mode(true);
|
||||
|
||||
|
|
|
@ -410,40 +410,41 @@ static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi
|
|||
const int cur_subdiv = tgpi->type == GP_STROKE_BOX ? tgpi->tot_edges - 1 : tgpi->tot_edges - 2;
|
||||
|
||||
if (tgpi->type == GP_STROKE_LINE) {
|
||||
BLI_strncpy(msg_str,
|
||||
TIP_("Line: ESC to cancel, LMB set origin, Enter/MMB to confirm, WHEEL/+- to "
|
||||
"adjust subdivision number, Shift to align, Alt to center, E: extrude"),
|
||||
UI_MAX_DRAW_STR);
|
||||
BLI_strncpy(
|
||||
msg_str,
|
||||
TIP_("Line: ESC to cancel, LMB set origin, Enter/MMB to confirm, WHEEL/+- to "
|
||||
"adjust subdivision number, Shift to align, Alt to center, E: extrude, G: grab"),
|
||||
UI_MAX_DRAW_STR);
|
||||
}
|
||||
else if (tgpi->type == GP_STROKE_POLYLINE) {
|
||||
BLI_strncpy(msg_str,
|
||||
TIP_("Polyline: ESC to cancel, LMB to set, Enter/MMB to confirm, WHEEL/+- to "
|
||||
"adjust subdivision number, Shift to align"),
|
||||
"adjust subdivision number, Shift to align, G: grab"),
|
||||
UI_MAX_DRAW_STR);
|
||||
}
|
||||
else if (tgpi->type == GP_STROKE_BOX) {
|
||||
BLI_strncpy(msg_str,
|
||||
TIP_("Rectangle: ESC to cancel, LMB set origin, Enter/MMB to confirm, WHEEL/+- "
|
||||
"to adjust subdivision number, Shift to square, Alt to center"),
|
||||
"to adjust subdivision number, Shift to square, Alt to center, G: grab"),
|
||||
UI_MAX_DRAW_STR);
|
||||
}
|
||||
else if (tgpi->type == GP_STROKE_CIRCLE) {
|
||||
BLI_strncpy(msg_str,
|
||||
TIP_("Circle: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust subdivision "
|
||||
"number, Shift to square, Alt to center"),
|
||||
"number, Shift to square, Alt to center, G: grab"),
|
||||
UI_MAX_DRAW_STR);
|
||||
}
|
||||
else if (tgpi->type == GP_STROKE_ARC) {
|
||||
BLI_strncpy(
|
||||
msg_str,
|
||||
TIP_("Arc: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust subdivision number, "
|
||||
"Shift to square, Alt to center, M: Flip, E: extrude"),
|
||||
"Shift to square, Alt to center, M: Flip, E: extrude, G: grab"),
|
||||
UI_MAX_DRAW_STR);
|
||||
}
|
||||
else if (tgpi->type == GP_STROKE_CURVE) {
|
||||
BLI_strncpy(msg_str,
|
||||
TIP_("Curve: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust subdivision "
|
||||
"number, Shift to square, Alt to center, E: extrude"),
|
||||
"number, Shift to square, Alt to center, E: extrude, G: grab"),
|
||||
UI_MAX_DRAW_STR);
|
||||
}
|
||||
|
||||
|
@ -1618,7 +1619,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
|
|||
copy_v2fl_v2i(tgpi->mval, event->mval);
|
||||
|
||||
if (tgpi->flag == IN_MOVE) {
|
||||
|
||||
bool is_mouse_event = true;
|
||||
switch (event->type) {
|
||||
case MOUSEMOVE: {
|
||||
gpencil_primitive_move(tgpi, false);
|
||||
|
@ -1639,8 +1640,14 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
|
|||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
is_mouse_event = false; /* Prevent overwriting `tgpi->mvalo`. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_mouse_event) {
|
||||
copy_v2_v2(tgpi->mvalo, tgpi->mval);
|
||||
}
|
||||
copy_v2_v2(tgpi->mvalo, tgpi->mval);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -373,9 +373,7 @@ ScrArea *ED_screen_temp_space_open(struct bContext *C,
|
|||
bool dialog);
|
||||
void ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg);
|
||||
void ED_screens_footer_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg);
|
||||
void ED_screens_navigation_bar_tools_menu_create(struct bContext *C,
|
||||
struct uiLayout *layout,
|
||||
void *arg);
|
||||
void ED_screens_region_flip_menu_create(struct bContext *C, struct uiLayout *layout, void *arg);
|
||||
/**
|
||||
* \return true if any active area requires to see in 3D.
|
||||
*/
|
||||
|
|
|
@ -1245,7 +1245,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
|
|||
uiItemMenuF(layout,
|
||||
IFACE_("Navigation Bar"),
|
||||
ICON_NONE,
|
||||
ED_screens_navigation_bar_tools_menu_create,
|
||||
ED_screens_region_flip_menu_create,
|
||||
nullptr);
|
||||
}
|
||||
else if (region->regiontype == RGN_TYPE_FOOTER) {
|
||||
|
|
|
@ -3631,6 +3631,26 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the jump type used for cursor motion & back-space/delete actions.
|
||||
*/
|
||||
static eStrCursorJumpType ui_textedit_jump_type_from_event(const wmEvent *event)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
if (event->modifier & KM_OSKEY) {
|
||||
return STRCUR_JUMP_ALL;
|
||||
}
|
||||
if (event->modifier & KM_ALT) {
|
||||
return STRCUR_JUMP_DELIM;
|
||||
}
|
||||
#else
|
||||
if (event->modifier & KM_CTRL) {
|
||||
return STRCUR_JUMP_DELIM;
|
||||
}
|
||||
#endif
|
||||
return STRCUR_JUMP_NONE;
|
||||
}
|
||||
|
||||
static void ui_do_but_textedit(
|
||||
bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
|
||||
{
|
||||
|
@ -3777,17 +3797,10 @@ static void ui_do_but_textedit(
|
|||
break;
|
||||
case EVT_RIGHTARROWKEY:
|
||||
case EVT_LEFTARROWKEY: {
|
||||
eStrCursorJumpDirection direction = (event->type == EVT_RIGHTARROWKEY) ? STRCUR_DIR_NEXT :
|
||||
STRCUR_DIR_PREV;
|
||||
#ifdef __APPLE__
|
||||
eStrCursorJumpType jump = (event->modifier & KM_OSKEY) ?
|
||||
STRCUR_JUMP_ALL :
|
||||
((event->modifier & KM_ALT) ? STRCUR_JUMP_DELIM :
|
||||
STRCUR_JUMP_NONE);
|
||||
#else
|
||||
eStrCursorJumpType jump = (event->modifier & KM_CTRL) ? STRCUR_JUMP_DELIM :
|
||||
STRCUR_JUMP_NONE;
|
||||
#endif
|
||||
const eStrCursorJumpDirection direction = (event->type == EVT_RIGHTARROWKEY) ?
|
||||
STRCUR_DIR_NEXT :
|
||||
STRCUR_DIR_PREV;
|
||||
const eStrCursorJumpType jump = ui_textedit_jump_type_from_event(event);
|
||||
ui_textedit_move(but, data, direction, event->modifier & KM_SHIFT, jump);
|
||||
retval = WM_UI_HANDLER_BREAK;
|
||||
break;
|
||||
|
@ -3833,17 +3846,9 @@ static void ui_do_but_textedit(
|
|||
break;
|
||||
case EVT_DELKEY:
|
||||
case EVT_BACKSPACEKEY: {
|
||||
eStrCursorJumpDirection direction = (event->type == EVT_DELKEY) ? STRCUR_DIR_NEXT :
|
||||
STRCUR_DIR_PREV;
|
||||
#ifdef __APPLE__
|
||||
eStrCursorJumpType jump = (event->modifier & KM_OSKEY) ?
|
||||
STRCUR_JUMP_ALL :
|
||||
((event->modifier & KM_ALT) ? STRCUR_JUMP_DELIM :
|
||||
STRCUR_JUMP_NONE);
|
||||
#else
|
||||
eStrCursorJumpType jump = (event->modifier & KM_CTRL) ? STRCUR_JUMP_DELIM :
|
||||
STRCUR_JUMP_NONE;
|
||||
#endif
|
||||
const eStrCursorJumpDirection direction = (event->type == EVT_DELKEY) ? STRCUR_DIR_NEXT :
|
||||
STRCUR_DIR_PREV;
|
||||
const eStrCursorJumpType jump = ui_textedit_jump_type_from_event(event);
|
||||
changed = ui_textedit_delete(but, data, direction, jump);
|
||||
retval = WM_UI_HANDLER_BREAK;
|
||||
break;
|
||||
|
|
|
@ -4297,10 +4297,6 @@ static void screen_area_menu_items(ScrArea *area, uiLayout *layout)
|
|||
void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
|
||||
{
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_TOP) ?
|
||||
IFACE_("Flip to Bottom") :
|
||||
IFACE_("Flip to Top");
|
||||
{
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, area->spacedata.first, &ptr);
|
||||
|
@ -4322,12 +4318,9 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN
|
|||
"SCREEN_OT_header_toggle_menus");
|
||||
}
|
||||
|
||||
/* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
|
||||
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
|
||||
|
||||
if (!ELEM(area->spacetype, SPACE_TOPBAR)) {
|
||||
uiItemS(layout);
|
||||
uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip");
|
||||
ED_screens_region_flip_menu_create(C, layout, NULL);
|
||||
uiItemS(layout);
|
||||
screen_area_menu_items(area, layout);
|
||||
}
|
||||
|
@ -4336,31 +4329,26 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN
|
|||
void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
|
||||
{
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_TOP) ?
|
||||
IFACE_("Flip to Bottom") :
|
||||
IFACE_("Flip to Top");
|
||||
|
||||
{
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, area->spacedata.first, &ptr);
|
||||
uiItemR(layout, &ptr, "show_region_footer", 0, IFACE_("Show Footer"), ICON_NONE);
|
||||
}
|
||||
|
||||
/* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
|
||||
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
|
||||
|
||||
uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip");
|
||||
|
||||
ED_screens_region_flip_menu_create(C, layout, NULL);
|
||||
uiItemS(layout);
|
||||
screen_area_menu_items(area, layout);
|
||||
}
|
||||
|
||||
void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
|
||||
void ED_screens_region_flip_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
|
||||
{
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
const char *but_flip_str = (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_LEFT) ?
|
||||
IFACE_("Flip to Right") :
|
||||
IFACE_("Flip to Left");
|
||||
const short region_alignment = RGN_ALIGN_ENUM_FROM_MASK(region->alignment);
|
||||
const char *but_flip_str = region_alignment == RGN_ALIGN_LEFT ? IFACE_("Flip to Right") :
|
||||
region_alignment == RGN_ALIGN_RIGHT ? IFACE_("Flip to Left") :
|
||||
region_alignment == RGN_ALIGN_BOTTOM ? IFACE_("Flip to Top") :
|
||||
IFACE_("Flip to Bottom");
|
||||
|
||||
/* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */
|
||||
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
|
||||
|
@ -4411,7 +4399,7 @@ static int screen_context_menu_invoke(bContext *C,
|
|||
else if (region->regiontype == RGN_TYPE_NAV_BAR) {
|
||||
uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Navigation Bar"), ICON_NONE);
|
||||
uiLayout *layout = UI_popup_menu_layout(pup);
|
||||
ED_screens_navigation_bar_tools_menu_create(C, layout, NULL);
|
||||
ED_screens_region_flip_menu_create(C, layout, NULL);
|
||||
UI_popup_menu_end(C, pup);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1180,7 +1180,7 @@ static void vertex_paint_init_session(Depsgraph *depsgraph,
|
|||
BKE_sculpt_toolsettings_data_ensure(scene);
|
||||
|
||||
BLI_assert(ob->sculpt == nullptr);
|
||||
ob->sculpt = (SculptSession *)MEM_callocN(sizeof(SculptSession), "sculpt session");
|
||||
ob->sculpt = MEM_new<SculptSession>(__func__);
|
||||
ob->sculpt->mode_type = object_mode;
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, true);
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ static void SCULPT_dynamic_topology_disable_ex(
|
|||
CustomData_free_layer_named(&me->pdata, ".sculpt_face_set", me->totpoly);
|
||||
me->face_sets_color_default = 1;
|
||||
|
||||
/* Sync the visibility to vertices manually as the pmap is still not initialized. */
|
||||
/* Sync the visibility to vertices manually as the `pmap` is still not initialized. */
|
||||
bool *hide_vert = (bool *)CustomData_get_layer_named_for_write(
|
||||
&me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert);
|
||||
if (hide_vert != nullptr) {
|
||||
|
|
|
@ -237,8 +237,7 @@ static void PREFERENCES_OT_asset_library_remove(wmOperatorType *ot)
|
|||
static bool associate_blend_poll(bContext *C)
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (BLI_windows_is_store_install())
|
||||
{
|
||||
if (BLI_windows_is_store_install()) {
|
||||
CTX_wm_operator_poll_msg_set(C, "Not available for Microsoft Store installations");
|
||||
return false;
|
||||
}
|
||||
|
@ -253,7 +252,8 @@ static int associate_blend_exec(bContext *UNUSED(C), wmOperator *op)
|
|||
{
|
||||
#ifdef WIN32
|
||||
if (BLI_windows_is_store_install()) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Registration not possible from Microsoft Store installations");
|
||||
BKE_report(
|
||||
op->reports, RPT_ERROR, "Registration not possible from Microsoft Store installations");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
|
|
@ -768,6 +768,7 @@ void applyMouseInput(struct TransInfo *t,
|
|||
const int mval[2],
|
||||
float output[3]);
|
||||
void transform_input_update(TransInfo *t, const float fac);
|
||||
void transform_input_virtual_mval_reset(TransInfo *t);
|
||||
|
||||
void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]);
|
||||
void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2]);
|
||||
|
|
|
@ -494,4 +494,18 @@ void transform_input_update(TransInfo *t, const float fac)
|
|||
}
|
||||
}
|
||||
|
||||
void transform_input_virtual_mval_reset(TransInfo *t)
|
||||
{
|
||||
MouseInput *mi = &t->mouse;
|
||||
if (ELEM(mi->apply, InputAngle, InputAngleSpring)) {
|
||||
struct InputAngle_Data *data = mi->data;
|
||||
data->angle = 0.0;
|
||||
data->mval_prev[0] = mi->imval[0];
|
||||
data->mval_prev[1] = mi->imval[1];
|
||||
}
|
||||
else {
|
||||
memset(&mi->virtual_mval, 0, sizeof(mi->virtual_mval));
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -420,28 +420,42 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
t->context = NULL;
|
||||
|
||||
/* Allow navigation while transforming. */
|
||||
if (t->vod && (exit_code & OPERATOR_PASS_THROUGH) && ED_view3d_navigation_do(C, t->vod, event)) {
|
||||
if (t->vod && (exit_code & OPERATOR_PASS_THROUGH)) {
|
||||
RegionView3D *rv3d = t->region->regiondata;
|
||||
if (rv3d->rflag & RV3D_NAVIGATING) {
|
||||
/* Do not update transform while navigating. This can be distracting. */
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
const bool is_navigating = (rv3d->rflag & RV3D_NAVIGATING) != 0;
|
||||
if (ED_view3d_navigation_do(C, t->vod, event)) {
|
||||
if (!is_navigating) {
|
||||
/* Navigation has started. */
|
||||
|
||||
if (t->modifiers & MOD_PRECISION) {
|
||||
/* WORKAROUND: Remove precision modification, it may have be unintentionally enabled. */
|
||||
t->modifiers &= ~MOD_PRECISION;
|
||||
t->mouse.precision = false;
|
||||
transform_input_virtual_mval_reset(t);
|
||||
}
|
||||
}
|
||||
|
||||
if (rv3d->rflag & RV3D_NAVIGATING) {
|
||||
/* Navigation is running. */
|
||||
|
||||
/* Do not update transform while navigating. This can be distracting. */
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
{
|
||||
/* Navigation has ended. */
|
||||
|
||||
/* Make sure `t->mval` is up to date before calling #transformViewUpdate. */
|
||||
copy_v2_v2_int(t->mval, event->mval);
|
||||
|
||||
/* Call before #applyMouseInput. */
|
||||
tranformViewUpdate(t);
|
||||
|
||||
/* Mouse input is outdated. */
|
||||
applyMouseInput(t, &t->mouse, t->mval, t->values);
|
||||
t->redraw |= TREDRAW_HARD;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->modifiers & MOD_PRECISION) {
|
||||
/* Remove Precision modifier, it may have be unintentionally enabled. */
|
||||
t->modifiers &= ~MOD_PRECISION;
|
||||
t->mouse.precision = 0;
|
||||
}
|
||||
|
||||
/* Make sure `t->mval` is up to date before calling #transformViewUpdate. */
|
||||
copy_v2_v2_int(t->mval, event->mval);
|
||||
|
||||
/* Call before #applyMouseInput. */
|
||||
tranformViewUpdate(t);
|
||||
|
||||
/* Mouse input is outdated. */
|
||||
applyMouseInput(t, &t->mouse, t->mval, t->values);
|
||||
t->redraw |= TREDRAW_HARD;
|
||||
}
|
||||
|
||||
transformApply(C, t);
|
||||
|
|
|
@ -413,7 +413,8 @@ void split_edges(Mesh &mesh,
|
|||
});
|
||||
|
||||
/* Used for transferring attributes. */
|
||||
Vector<int> new_to_old_edges_map(IndexRange(new_edges.size()).as_span());
|
||||
Vector<int> new_to_old_edges_map(new_edges.size());
|
||||
std::iota(new_to_old_edges_map.begin(), new_to_old_edges_map.end(), 0);
|
||||
|
||||
/* Step 1: Split the edges. */
|
||||
|
||||
|
|
|
@ -483,16 +483,26 @@ void GPUCodegen::generate_library()
|
|||
GPUCodegenCreateInfo &info = *create_info;
|
||||
|
||||
void *value;
|
||||
/* Iterate over libraries. We need to keep this struct intact in case
|
||||
* it is required for the optimization pass. */
|
||||
blender::Vector<std::string> source_files;
|
||||
|
||||
/* Iterate over libraries. We need to keep this struct intact in case it is required for the
|
||||
* optimization pass. The first pass just collects the keys from the GSET, given items in a GSET
|
||||
* are unordered this can cause order differences between invocations, so we collect the keys
|
||||
* first, and sort them before doing actual work, to guarantee stable behavior while still
|
||||
* having cheap insertions into the GSET */
|
||||
GHashIterator *ihash = BLI_ghashIterator_new((GHash *)graph.used_libraries);
|
||||
while (!BLI_ghashIterator_done(ihash)) {
|
||||
value = BLI_ghashIterator_getKey(ihash);
|
||||
auto deps = gpu_shader_dependency_get_resolved_source((const char *)value);
|
||||
info.dependencies_generated.extend_non_duplicates(deps);
|
||||
source_files.append((const char *)value);
|
||||
BLI_ghashIterator_step(ihash);
|
||||
}
|
||||
BLI_ghashIterator_free(ihash);
|
||||
|
||||
std::sort(source_files.begin(), source_files.end());
|
||||
for (auto &key : source_files) {
|
||||
auto deps = gpu_shader_dependency_get_resolved_source(key.c_str());
|
||||
info.dependencies_generated.extend_non_duplicates(deps);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUCodegen::node_serialize(std::stringstream &eval_ss, const GPUNode *node)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "GPU_framebuffer.h"
|
||||
|
|
|
@ -149,10 +149,12 @@ struct ImBuf *IMB_allocFromBuffer(const uint8_t *byte_buffer,
|
|||
unsigned int h,
|
||||
unsigned int channels);
|
||||
|
||||
/* Assign the content of the corresponding buffer using an implicitly shareable data pointer.
|
||||
/**
|
||||
* Assign the content of the corresponding buffer using an implicitly shareable data pointer.
|
||||
*
|
||||
* NOTE: Does not modify the the topology (width, height, number of channels) or the mipmaps in any
|
||||
* way. */
|
||||
* \note Does not modify the topology (width, height, number of channels)
|
||||
* or the mipmaps in any way.
|
||||
*/
|
||||
void IMB_assign_shared_byte_buffer(struct ImBuf *ibuf,
|
||||
uint8_t *buffer_data,
|
||||
const ImplicitSharingInfoHandle *implicit_sharing);
|
||||
|
@ -163,24 +165,30 @@ void IMB_assign_shared_float_z_buffer(struct ImBuf *ibuf,
|
|||
float *buffer_data,
|
||||
const ImplicitSharingInfoHandle *implicit_sharing);
|
||||
|
||||
/* Assign the content of the corresponding buffer with the given data and ownership.
|
||||
/**
|
||||
* Assign the content of the corresponding buffer with the given data and ownership.
|
||||
* The current content of the buffer is released corresponding to its ownership configuration.
|
||||
*
|
||||
* NOTE: Does not modify the the topology (width, height, number of channels) or the mipmaps in any
|
||||
* way. */
|
||||
* \note Does not modify the topology (width, height, number of channels)
|
||||
* or the mipmaps in any way.
|
||||
*/
|
||||
void IMB_assign_byte_buffer(struct ImBuf *ibuf, uint8_t *buffer_data, ImBufOwnership ownership);
|
||||
void IMB_assign_float_buffer(struct ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership);
|
||||
void IMB_assign_z_buffer(struct ImBuf *ibuf, int *buffer_data, ImBufOwnership ownership);
|
||||
void IMB_assign_float_z_buffer(struct ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership);
|
||||
|
||||
/* Make corresponding buffers available for modification.
|
||||
* Is achieved by ensuring that the given ImBuf is the only owner of the underlying buffer data. */
|
||||
/**
|
||||
* Make corresponding buffers available for modification.
|
||||
* Is achieved by ensuring that the given ImBuf is the only owner of the underlying buffer data.
|
||||
*/
|
||||
void IMB_make_writable_byte_buffer(struct ImBuf *ibuf);
|
||||
void IMB_make_writable_float_buffer(struct ImBuf *ibuf);
|
||||
|
||||
/* Steal the buffer data pointer: the ImBuf is no longer an owner of this data.
|
||||
* NOTE: If the ImBuf does not own the data the behavior is undefined.
|
||||
* NOTE: Stealing encoded buffer resets the encoded size. */
|
||||
/**
|
||||
* Steal the buffer data pointer: the ImBuf is no longer an owner of this data.
|
||||
* \note If the ImBuf does not own the data the behavior is undefined.
|
||||
* \note Stealing encoded buffer resets the encoded size.
|
||||
*/
|
||||
uint8_t *IMB_steal_byte_buffer(struct ImBuf *ibuf);
|
||||
float *IMB_steal_float_buffer(struct ImBuf *ibuf);
|
||||
uint8_t *IMB_steal_encoded_buffer(struct ImBuf *ibuf);
|
||||
|
|
|
@ -279,8 +279,8 @@ typedef struct LightLinkingRuntime {
|
|||
|
||||
/* For blocker objects: the index of the light set from which this object casts shadow from.
|
||||
*
|
||||
*If there is no shadow shadow in the scene or the blocker is not linked to any emitter this is
|
||||
*assigned zero. */
|
||||
* If there is no shadow in the scene or the blocker is not linked to any emitter this is
|
||||
* assigned zero. */
|
||||
uint8_t blocker_shadow_set;
|
||||
|
||||
uint8_t _pad[6];
|
||||
|
@ -289,7 +289,7 @@ typedef struct LightLinkingRuntime {
|
|||
typedef struct LightLinking {
|
||||
/* Collections which contains objects (possibly via nested collection indirection) which defines
|
||||
* the light linking relation: such as whether objects are included or excluded from being lit by
|
||||
* this emitter (receiver_collection), oe whether they block light from this emitter
|
||||
* this emitter (receiver_collection), or whether they block light from this emitter
|
||||
* (blocker_collection).
|
||||
*
|
||||
* If the collection is a null pointer then all objects from the current scene are receiving
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define __RNA_TYPES_H__
|
||||
|
||||
#include "../blenlib/BLI_sys_types.h"
|
||||
#include "../blenlib/BLI_utildefines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -81,6 +82,7 @@ typedef enum PropertyUnit {
|
|||
PROP_UNIT_POWER = (11 << 16), /* W */
|
||||
PROP_UNIT_TEMPERATURE = (12 << 16), /* C */
|
||||
} PropertyUnit;
|
||||
ENUM_OPERATORS(PropertyUnit, PROP_UNIT_TEMPERATURE)
|
||||
|
||||
/**
|
||||
* Use values besides #PROP_SCALE_LINEAR
|
||||
|
@ -367,6 +369,7 @@ typedef enum ParameterFlag {
|
|||
*/
|
||||
PARM_PYFUNC_OPTIONAL = (1 << 3),
|
||||
} ParameterFlag;
|
||||
ENUM_OPERATORS(ParameterFlag, PARM_PYFUNC_OPTIONAL)
|
||||
|
||||
struct CollectionPropertyIterator;
|
||||
struct Link;
|
||||
|
|
|
@ -1798,7 +1798,7 @@ static char *rna_def_property_lookup_string_func(FILE *f,
|
|||
fprintf(f, " }\n");
|
||||
fprintf(f, " }\n");
|
||||
fprintf(f, " else {\n");
|
||||
fprintf(f, " name = MEM_mallocN(namelen+1, \"name string\");\n");
|
||||
fprintf(f, " name = (char *)MEM_mallocN(namelen+1, \"name string\");\n");
|
||||
fprintf(f,
|
||||
" %s_%s_get(&iter.ptr, name);\n",
|
||||
item_name_base->identifier,
|
||||
|
@ -1916,7 +1916,8 @@ static void rna_set_raw_offset(FILE *f, StructRNA *srna, PropertyRNA *prop)
|
|||
{
|
||||
PropertyDefRNA *dp = rna_find_struct_property_def(srna, prop);
|
||||
|
||||
fprintf(f, "\toffsetof(%s, %s), %d", dp->dnastructname, dp->dnaname, prop->rawtype);
|
||||
fprintf(
|
||||
f, "\toffsetof(%s, %s), (RawPropertyType)%d", dp->dnastructname, dp->dnaname, prop->rawtype);
|
||||
}
|
||||
|
||||
static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
|
||||
|
@ -3506,7 +3507,7 @@ static void rna_generate_internal_property_prototypes(BlenderRNA *UNUSED(brna),
|
|||
|
||||
for (prop = srna->cont.properties.first; prop; prop = prop->next) {
|
||||
fprintf(f,
|
||||
"%s rna_%s_%s;\n",
|
||||
"extern %s rna_%s_%s;\n",
|
||||
rna_property_structname(prop->type),
|
||||
srna->identifier,
|
||||
prop->identifier);
|
||||
|
@ -4068,7 +4069,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
|
|||
rna_print_c_string(f, prop->translation_context);
|
||||
fprintf(f, ",\n");
|
||||
fprintf(f,
|
||||
"\t%s, %s | %s, %s, %u, {%u, %u, %u}, %u,\n",
|
||||
"\t%s, (PropertySubType)((int)%s | (int)%s), %s, %u, {%u, %u, %u}, %u,\n",
|
||||
RNA_property_typename(prop->type),
|
||||
rna_property_subtypename(prop->subtype),
|
||||
rna_property_subtype_unit(prop->subtype),
|
||||
|
@ -4093,7 +4094,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
|
|||
rna_set_raw_offset(f, srna, prop);
|
||||
}
|
||||
else {
|
||||
fprintf(f, "\t0, -1");
|
||||
fprintf(f, "\t0, PROP_RAW_UNSET");
|
||||
}
|
||||
|
||||
/* our own type - collections/arrays only */
|
||||
|
|
|
@ -449,7 +449,7 @@ static void rna_CollectionLightLinking_update(Main *bmain, Scene *UNUSED(scene),
|
|||
{
|
||||
/* The light linking collection comes from the collection. It does not have shading component,
|
||||
* but is collected to objects via hierarchy component. Tagging its hierarchy for update will
|
||||
* lead the the objects which use the collection to update its shading. */
|
||||
* lead the objects which use the collection to update its shading. */
|
||||
DEG_id_tag_update(ptr->owner_id, ID_RECALC_HIERARCHY);
|
||||
|
||||
/* Tag relations for update so that an updated state of light sets is calculated. */
|
||||
|
|
|
@ -7037,6 +7037,11 @@ static void rna_def_modifier_nodes(BlenderRNA *brna)
|
|||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, 0, "rna_NodesModifier_node_group_update");
|
||||
|
||||
prop = RNA_def_property(srna, "simulation_bake_directory", PROP_STRING, PROP_DIRPATH);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Simulation Bake Directory", "Location on disk where the bake data is stored");
|
||||
RNA_def_property_update(prop, 0, NULL);
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -5908,7 +5908,7 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
|
|||
# endif
|
||||
|
||||
# ifdef WITH_OPENJPEG
|
||||
/* Jpeg 2000 */
|
||||
/* JPEG 2000 */
|
||||
prop = RNA_def_property(srna, "use_jpeg2k_ycc", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "jp2_flag", R_IMF_JP2_FLAG_YCC);
|
||||
RNA_def_property_ui_text(
|
||||
|
|
|
@ -653,12 +653,17 @@ static void correctivesmooth_modifier_do(ModifierData *md,
|
|||
}
|
||||
else {
|
||||
int me_numVerts;
|
||||
rest_coords = em ? BKE_editmesh_vert_coords_alloc_orco(em, &me_numVerts) :
|
||||
BKE_mesh_vert_coords_alloc(static_cast<const Mesh *>(ob->data),
|
||||
&me_numVerts);
|
||||
if (em) {
|
||||
rest_coords = BKE_editmesh_vert_coords_alloc_orco(em, &me_numVerts);
|
||||
is_rest_coords_alloc = true;
|
||||
}
|
||||
else {
|
||||
const Mesh *me = static_cast<const Mesh *>(ob->data);
|
||||
rest_coords = BKE_mesh_vert_positions(me);
|
||||
me_numVerts = me->totvert;
|
||||
}
|
||||
|
||||
BLI_assert((uint)me_numVerts == verts_num);
|
||||
is_rest_coords_alloc = true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
|
|
|
@ -1922,6 +1922,8 @@ static void internal_dependencies_panel_draw(const bContext * /*C*/, Panel *pane
|
|||
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
|
||||
NodesModifierData *nmd = static_cast<NodesModifierData *>(ptr->data);
|
||||
|
||||
uiItemR(layout, ptr, "simulation_bake_directory", 0, "Bake", ICON_NONE);
|
||||
|
||||
geo_log::GeoTreeLog *tree_log = get_root_tree_log(*nmd);
|
||||
if (tree_log == nullptr) {
|
||||
return;
|
||||
|
|
|
@ -41,28 +41,30 @@ extern "C" {
|
|||
/* External Engine */
|
||||
|
||||
/** #RenderEngineType.flag */
|
||||
#define RE_INTERNAL 1
|
||||
/* #define RE_FLAG_DEPRECATED 2 */
|
||||
#define RE_USE_PREVIEW 4
|
||||
#define RE_USE_POSTPROCESS 8
|
||||
#define RE_USE_EEVEE_VIEWPORT 16
|
||||
/* #define RE_USE_SAVE_BUFFERS_DEPRECATED 32 */
|
||||
#define RE_USE_SHADING_NODES_CUSTOM 64
|
||||
#define RE_USE_SPHERICAL_STEREO 128
|
||||
#define RE_USE_STEREO_VIEWPORT 256
|
||||
#define RE_USE_GPU_CONTEXT 512
|
||||
#define RE_USE_CUSTOM_FREESTYLE 1024
|
||||
#define RE_USE_NO_IMAGE_SAVE 2048
|
||||
#define RE_USE_ALEMBIC_PROCEDURAL 4096
|
||||
enum RenderEngineTypeFlag {
|
||||
RE_INTERNAL = (1 << 0),
|
||||
RE_USE_PREVIEW = (1 << 1),
|
||||
RE_USE_POSTPROCESS = (1 << 2),
|
||||
RE_USE_EEVEE_VIEWPORT = (1 << 3),
|
||||
RE_USE_SHADING_NODES_CUSTOM = (1 << 4),
|
||||
RE_USE_SPHERICAL_STEREO = (1 << 5),
|
||||
RE_USE_STEREO_VIEWPORT = (1 << 6),
|
||||
RE_USE_GPU_CONTEXT = (1 << 7),
|
||||
RE_USE_CUSTOM_FREESTYLE = (1 << 8),
|
||||
RE_USE_NO_IMAGE_SAVE = (1 << 9),
|
||||
RE_USE_ALEMBIC_PROCEDURAL = (1 << 10),
|
||||
};
|
||||
|
||||
/** #RenderEngine.flag */
|
||||
#define RE_ENGINE_ANIMATION 1
|
||||
#define RE_ENGINE_PREVIEW 2
|
||||
#define RE_ENGINE_DO_DRAW 4
|
||||
#define RE_ENGINE_DO_UPDATE 8
|
||||
#define RE_ENGINE_RENDERING 16
|
||||
#define RE_ENGINE_HIGHLIGHT_TILES 32
|
||||
#define RE_ENGINE_CAN_DRAW 64
|
||||
enum RenderEngineFlag {
|
||||
RE_ENGINE_ANIMATION = (1 << 0),
|
||||
RE_ENGINE_PREVIEW = (1 << 1),
|
||||
RE_ENGINE_DO_DRAW = (1 << 2),
|
||||
RE_ENGINE_DO_UPDATE = (1 << 3),
|
||||
RE_ENGINE_RENDERING = (1 << 4),
|
||||
RE_ENGINE_HIGHLIGHT_TILES = (1 << 5),
|
||||
RE_ENGINE_CAN_DRAW = (1 << 6),
|
||||
};
|
||||
|
||||
extern ListBase R_engines;
|
||||
|
||||
|
|
Loading…
Reference in New Issue