PBVH: update mesh data pointers stored in pbvh #106271
|
@ -14,3 +14,13 @@ The first three of them were employed by the Blender Foundation during that time
|
|||
Some features (random sounds, dynamic music, playback manager, convolution and HRTFs support) were added as part of the VALS (Virtual Alliances for Learning Society) project by
|
||||
|
||||
- Juan Francisco Crespo Galán <dethon_5@outlook.com>
|
||||
|
||||
The Equalizer sound effect has been added by
|
||||
|
||||
- Marcos Perez
|
||||
|
||||
Several people provided fixes:
|
||||
|
||||
- Aaron Carlisle
|
||||
- Sebastian Parborg
|
||||
- Leon Zandman
|
||||
|
|
|
@ -1,3 +1,104 @@
|
|||
Audaspace 1.4
|
||||
|
||||
- Support for OS specific/native audio devices/backends has been added, that is PulseAudio (Linux), WASAPI (Windows) and CoreAudio (MacOS).
|
||||
- New sound effects have been added, namely Modulator and Equalizer. Thanks to Marcos Perez for contributing the Equalizer.
|
||||
- File stream info: if an audio file contains multiple streams you can choose which one to process instead of taking the first one (this feature is only supported by ffmpeg, not libsndfile).
|
||||
- API Change: double instead of float for time values for more precise timing control.
|
||||
- There have been lots of bugfixes, which are basically the majority of all changes.
|
||||
- And some other minor improvements were implemented as well.
|
||||
|
||||
Detailed list of changes:
|
||||
|
||||
d4042d9 Port changes in Blender to upstream.
|
||||
b60fb45 Equalizer
|
||||
ab04e84 Fixes
|
||||
8f0c305 Fix build error with MSVC 17.4+ ported from Blender.
|
||||
ce44342 Minor documentation update.
|
||||
cdcb3f4 Migrate from distuils to setuptools for python module.
|
||||
21eccef Fix FindFFTW to find the float version fftw3f.
|
||||
ab15e2f Bugfix: API change in new ffmpeg version.
|
||||
a097be8 Clang format file added, valid from now on.
|
||||
2fc9fb7 Porting bugfix from Blender upstream.
|
||||
bb655b7 Bugfix: wrong sample size computation for PulseAudio.
|
||||
a150495 Bugfix: Buffer did not support buffers > 2 GB.
|
||||
034645c Update for ffmpeg 5.
|
||||
932739c Bugfix: WASAPI hangs.
|
||||
4fcd47c WASAPI: fix bug when switching the default device while there is no playback.
|
||||
a16fbd2 Python API: fix to get convolution in the python API.
|
||||
27ac5c1 WASAPI: always switch to default audio device.
|
||||
1b03e6c Bugfix: catch exception if file cannot be read.
|
||||
369ff6e PulseAudio: remove unused underflow callback.
|
||||
2d8bf3a PulseAudio: improve synchronization accuracy.
|
||||
4868e14 Revert PulseAudioDevice back from ThreadedDevice to threaded mainloop.
|
||||
6a04446 Adding a jack style mixing thread with a ring buffer for pulseaudio.
|
||||
5d4b57b Implement RingBuffer class.
|
||||
e02d3aa FFMPEG: fix seeking and duration calculation.
|
||||
07b9fa0 Adding file stream functionality.
|
||||
5a8ad27 Porting changes from Blender.
|
||||
fa47258 Bugfix: PulseAudio writing to little data on request.
|
||||
ca3edb5 PulseAudio: increase buffersize.
|
||||
6d36f3e Pulseaudio: may fix crackling playback start bug.
|
||||
dbeac4b WASAPI: reinitialize device when lost.
|
||||
0cba4d3 Bugfix Pulseaudio: might hang.
|
||||
b73dc6d Bugfix: ffmpeg 4.4 requires channels to be set.
|
||||
f1ecbe0 Fixed typo.
|
||||
09e4f27 Rewrite PulseAudioDevice to use ThreadedDevice.
|
||||
9516924 WASAPI: refactor to simplify and use ThreadedDevice.
|
||||
749c974 Add ThreadedDevice.
|
||||
e68b355 Fix some locks in SoftwareDevice.
|
||||
44b57af Bugfix for deadlock in WASAPIDevice.
|
||||
8c4b266 CMake: fix ERROR to FATAL_ERROR in MESSAGE.
|
||||
5a17338 Rename NullDevice's reported name to None.
|
||||
cd138d7 PulseAudio: add dynamic loading and threading fixes.
|
||||
6e0250f CoreAudio: add CoreAudioClock as synchronizer.
|
||||
43aff35 Fix leakage in CoreAudioDevice.cpp
|
||||
7f6f059 Remove unnecessary cmake code.
|
||||
a5c1a02 Add CoreAudio device for Apple.
|
||||
af96f67 Indentation fix.
|
||||
eec8fd5 WASAPI: use padding also for first buffer submission.
|
||||
c63bd9b WASAPI: deal with IsFormatSupported case.
|
||||
079cccb Hide WITH_PULSEAUDIO when not on Linux.
|
||||
67b5013 Add mingw64 cross compilation toolchain on Linux.
|
||||
a7bfa58 Add WASAPI backend for Windows.
|
||||
be1cb25 Allow AUD_init with nullptr to use default device.
|
||||
fc68868 Compilation fix for mingw.
|
||||
bb79d25 Add a PulseAudio output device.
|
||||
a11f593 Bugfix for unwanted volume fading at the beginning of sounds.
|
||||
8510acf Bugfix: more accurate positioning of sequences.
|
||||
cb816c1 Fix API docs for python playback manager play function
|
||||
d125fa2 Add callback for mixing down audio.
|
||||
789832e Fix numpy import.
|
||||
9a6a802 Bugfix: JOS resampling type bugfix caused integer underflow.
|
||||
ece0842 Fix corrupted document in python bindings
|
||||
28b2ea2 SDL 2: support more audio formats.
|
||||
a39b7e3 Trying to fix Travis CI build for OS X.
|
||||
c924007 Some more changes of times from flaot to double.
|
||||
659afd4 Porting fixes from blender.
|
||||
8e5e2e6 Fix documentation warnings.
|
||||
7a6054f API: All times are now double instead of float.
|
||||
452a724 Mixer sample buffer added channels twice
|
||||
8ddb6c1 Docs: Cleanup Line Wrapping for python examples
|
||||
a0c37b2 Docs: Use class methods for api docs
|
||||
2f8b2e3 Bugfix for invalid offsets provided by ffmpeg's seeking code.
|
||||
20a7a28 Bug fixes for files with more than 8 channels.
|
||||
94dc527 Bugfix: Fading from full volume.
|
||||
2fb9862 Fix: Missing include in FileManager.h.
|
||||
afadb94 Minor CMakeLists.txt formatting fixes.
|
||||
734ef03 Add sample rate parameter to silence generation.
|
||||
ed50f3b Bugfix: Return correct length for modulator and superpose.
|
||||
cb7a314 Adding a modulator sound effect.
|
||||
101c714 Bugfix: don't add non-existing devices to the device manager.
|
||||
7ad99df OpenAL: recreate device if disconnected.
|
||||
a2ff4e8 Bugfix: memory leak in python API.
|
||||
5fb21bb Silence some warnings.
|
||||
9b38605 Some fixes backported from Blender.
|
||||
40a0a34 Udpate for travis.ci.
|
||||
212b4b6 Support newer ffmpeg versions.
|
||||
d27746c Build option: configure whether to build versioned plugins.
|
||||
19c8d9f Make fftw3 optional.
|
||||
aa11968 Bugfix for building with gcc7.
|
||||
10413c5 Fix for seeking with modified pitch.
|
||||
|
||||
Audaspace 1.3
|
||||
=============
|
||||
|
||||
|
@ -10,6 +111,8 @@ Audaspace 1.3
|
|||
- filter python API parameter check
|
||||
- finding ffmpeg with pkgconfig
|
||||
|
||||
Detailed list of changes:
|
||||
|
||||
64884a7 Windows fixes.
|
||||
53ba3e6 Implemented JACK dynamic loading.
|
||||
5ee0ee1 Continues last commit.
|
||||
|
@ -46,6 +149,8 @@ Audaspace 1.2
|
|||
- assuring numpy is installed
|
||||
- building the Python module on Mac OS X with CMake
|
||||
|
||||
Detailed list of changes:
|
||||
|
||||
a6b6e70 Changing default sample rate from 44.1 to 48 kHz.
|
||||
20f0164 Bugfix: CMake custom command for python module on OS X.
|
||||
98679a2 Bugfix: using standard library (s)rand.
|
||||
|
|
|
@ -23,7 +23,7 @@ endif()
|
|||
|
||||
project(audaspace)
|
||||
|
||||
set(AUDASPACE_VERSION 1.3)
|
||||
set(AUDASPACE_VERSION 1.4)
|
||||
set(AUDASPACE_LONG_VERSION ${AUDASPACE_VERSION}.0)
|
||||
|
||||
if(DEFINED AUDASPACE_CMAKE_CFG)
|
||||
|
|
|
@ -15,7 +15,7 @@ Audaspace is written in C++ 11 so a fairly recent compiler (g++ 4.8.2, clang 3.3
|
|||
- Jack (output device)
|
||||
- libsndfile (file access)
|
||||
- ffmpeg (file access)
|
||||
- Python (language binding)
|
||||
- Python (language binding, needs NumPy as well)
|
||||
|
||||
Getting the Code
|
||||
----------------
|
||||
|
|
|
@ -32,7 +32,7 @@ The following (probably incomplete) features are supported by audaspace:
|
|||
License
|
||||
-------
|
||||
|
||||
> Copyright © 2009-2015 Jörg Müller. All rights reserved.
|
||||
> Copyright © 2009-2023 Jörg Müller. All rights reserved.
|
||||
>
|
||||
> Licensed under the Apache License, Version 2.0 (the "License");
|
||||
> you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -165,6 +165,12 @@ AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, double begin, doub
|
|||
(*entry)->move(begin, end, skip);
|
||||
}
|
||||
|
||||
AUD_API void AUD_SequenceEntry_setConstantRangeAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data)
|
||||
{
|
||||
AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast<AnimateablePropertyType>(type));
|
||||
prop->writeConstantRange(data, frame_start, frame_end);
|
||||
}
|
||||
|
||||
AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated)
|
||||
{
|
||||
AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast<AnimateablePropertyType>(type));
|
||||
|
|
|
@ -68,6 +68,16 @@ extern AUD_API void AUD_Sequence_remove(AUD_Sound* sequence, AUD_SequenceEntry*
|
|||
* Writes animation data to a sequence.
|
||||
* \param sequence The sound scene.
|
||||
* \param type The type of animation data.
|
||||
* \param frame_start Start of the frame range.
|
||||
* \param frame_end End of the frame range.
|
||||
* \param data The data to write.
|
||||
*/
|
||||
AUD_API void AUD_SequenceEntry_setConstantRangeAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data);
|
||||
|
||||
/**
|
||||
* Writes animation data to a sequenced entry.
|
||||
* \param entry The sequenced entry.
|
||||
* \param type The type of animation data.
|
||||
* \param frame The frame this data is for.
|
||||
* \param data The data to write.
|
||||
* \param animated Whether the attribute is animated.
|
||||
|
|
|
@ -112,6 +112,14 @@ public:
|
|||
*/
|
||||
void write(const float* data, int position, int count);
|
||||
|
||||
/**
|
||||
* Fills the properties frame range with constant value and marks it animated.
|
||||
* \param data The new value.
|
||||
* \param position_start The start position in the animation in frames.
|
||||
* \param position_end The end position in the animation in frames.
|
||||
*/
|
||||
void writeConstantRange(const float* data, int position_start, int position_end);
|
||||
|
||||
/**
|
||||
* Reads the properties value.
|
||||
* \param position The position in the animation in frames.
|
||||
|
|
|
@ -198,12 +198,13 @@ public:
|
|||
/**
|
||||
* Adds a new entry to the scene.
|
||||
* \param sound The sound this entry should play.
|
||||
* \param sequence_data Reference to sequence_data. Mainly needed to get the FPS of the scene.
|
||||
* \param begin The start time.
|
||||
* \param end The end time or a negative value if determined by the sound.
|
||||
* \param skip How much seconds should be skipped at the beginning.
|
||||
* \return The entry added.
|
||||
*/
|
||||
std::shared_ptr<SequenceEntry> add(std::shared_ptr<ISound> sound, double begin, double end, double skip);
|
||||
std::shared_ptr<SequenceEntry> add(std::shared_ptr<ISound> sound, std::shared_ptr<SequenceData> sequence_data, double begin, double end, double skip);
|
||||
|
||||
/**
|
||||
* Removes an entry from the scene.
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "sequence/AnimateableProperty.h"
|
||||
#include "sequence/SequenceData.h"
|
||||
#include "util/ILockable.h"
|
||||
|
||||
#include <mutex>
|
||||
|
@ -63,6 +64,9 @@ private:
|
|||
/// How many seconds are skipped at the beginning.
|
||||
double m_skip;
|
||||
|
||||
/// reference to sequence_data. Mainly needed to get the FPS of the scene.
|
||||
std::shared_ptr<SequenceData> m_sequence_data;
|
||||
|
||||
/// Whether the entry is muted.
|
||||
bool m_muted;
|
||||
|
||||
|
@ -122,9 +126,10 @@ public:
|
|||
* \param begin The start time.
|
||||
* \param end The end time or a negative value if determined by the sound.
|
||||
* \param skip How much seconds should be skipped at the beginning.
|
||||
* \param sequence_data Reference to sequence_data. Mainly needed to get the FPS of the scene.
|
||||
* \param id The ID of the entry.
|
||||
*/
|
||||
SequenceEntry(std::shared_ptr<ISound> sound, double begin, double end, double skip, int id);
|
||||
SequenceEntry(std::shared_ptr<ISound> sound, double begin, double end, double skip, std::shared_ptr<SequenceData> sequence_data, int id);
|
||||
virtual ~SequenceEntry();
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,6 +65,19 @@ void AnimateableProperty::write(const float* data)
|
|||
std::memcpy(getBuffer(), data, m_count * sizeof(float));
|
||||
}
|
||||
|
||||
void AnimateableProperty::writeConstantRange(const float* data, int position_start, int position_end)
|
||||
{
|
||||
assureSize(position_end * m_count * sizeof(float), true);
|
||||
float* buffer = getBuffer();
|
||||
|
||||
for(int i = position_start; i < position_end; i++)
|
||||
{
|
||||
std::memcpy(buffer + i * m_count, data, m_count * sizeof(float));
|
||||
}
|
||||
|
||||
m_isAnimated = true;
|
||||
}
|
||||
|
||||
void AnimateableProperty::write(const float* data, int position, int count)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
|
|
@ -92,7 +92,7 @@ AnimateableProperty* Sequence::getAnimProperty(AnimateablePropertyType type)
|
|||
|
||||
std::shared_ptr<SequenceEntry> Sequence::add(std::shared_ptr<ISound> sound, double begin, double end, double skip)
|
||||
{
|
||||
return m_sequence->add(sound, begin, end, skip);
|
||||
return m_sequence->add(sound, m_sequence, begin, end, skip);
|
||||
}
|
||||
|
||||
void Sequence::remove(std::shared_ptr<SequenceEntry> entry)
|
||||
|
|
|
@ -149,11 +149,11 @@ AnimateableProperty* SequenceData::getAnimProperty(AnimateablePropertyType type)
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<SequenceEntry> SequenceData::add(std::shared_ptr<ISound> sound, double begin, double end, double skip)
|
||||
std::shared_ptr<SequenceEntry> SequenceData::add(std::shared_ptr<ISound> sound, std::shared_ptr<SequenceData> sequence_data, double begin, double end, double skip)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
std::shared_ptr<SequenceEntry> entry = std::shared_ptr<SequenceEntry>(new SequenceEntry(sound, begin, end, skip, m_id++));
|
||||
std::shared_ptr<SequenceEntry> entry = std::shared_ptr<SequenceEntry>(new SequenceEntry(sound, begin, end, skip, sequence_data, m_id++));
|
||||
|
||||
m_entries.push_back(entry);
|
||||
m_entry_status++;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
SequenceEntry::SequenceEntry(std::shared_ptr<ISound> sound, double begin, double end, double skip, int id) :
|
||||
SequenceEntry::SequenceEntry(std::shared_ptr<ISound> sound, double begin, double end, double skip, std::shared_ptr<SequenceData> sequence_data, int id) :
|
||||
m_status(0),
|
||||
m_pos_status(1),
|
||||
m_sound_status(0),
|
||||
|
@ -31,6 +31,7 @@ SequenceEntry::SequenceEntry(std::shared_ptr<ISound> sound, double begin, double
|
|||
m_begin(begin),
|
||||
m_end(end),
|
||||
m_skip(skip),
|
||||
m_sequence_data(sequence_data),
|
||||
m_muted(false),
|
||||
m_relative(true),
|
||||
m_volume_max(1.0f),
|
||||
|
|
|
@ -241,10 +241,38 @@ bool SequenceHandle::seek(double position)
|
|||
return false;
|
||||
|
||||
std::lock_guard<ILockable> lock(*m_entry);
|
||||
double seekpos = position - m_entry->m_begin;
|
||||
if(seekpos < 0)
|
||||
seekpos = 0;
|
||||
seekpos += m_entry->m_skip;
|
||||
|
||||
double seek_frame = (position - m_entry->m_begin) * m_entry->m_sequence_data->getFPS();
|
||||
|
||||
if(seek_frame < 0)
|
||||
seek_frame = 0;
|
||||
|
||||
seek_frame += m_entry->m_skip * m_entry->m_sequence_data->getFPS();
|
||||
|
||||
AnimateableProperty* pitch_property = m_entry->getAnimProperty(AP_PITCH);
|
||||
|
||||
double target_frame = 0;
|
||||
|
||||
if(pitch_property != nullptr)
|
||||
{
|
||||
int frame_start = (m_entry->m_begin - m_entry->m_skip) * m_entry->m_sequence_data->getFPS();
|
||||
|
||||
for(int i = 0; seek_frame > 0; i++)
|
||||
{
|
||||
float pitch;
|
||||
pitch_property->read(frame_start + i, &pitch);
|
||||
const double factor = seek_frame > 1.0 ? 1.0 : seek_frame;
|
||||
target_frame += pitch * factor;
|
||||
seek_frame--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target_frame = seek_frame;
|
||||
}
|
||||
|
||||
double seekpos = target_frame / m_entry->m_sequence_data->getFPS();
|
||||
|
||||
m_handle->setPitch(1.0f);
|
||||
m_handle->seek(seekpos);
|
||||
|
||||
|
|
|
@ -609,59 +609,60 @@ void BlenderSync::sync_particle_hair(
|
|||
}
|
||||
}
|
||||
|
||||
static std::optional<BL::FloatAttribute> find_curves_radius_attribute(BL::Curves b_curves)
|
||||
static const float *find_radius_attribute(BL::Curves b_curves)
|
||||
{
|
||||
for (BL::Attribute &b_attribute : b_curves.attributes) {
|
||||
if (b_attribute.name() != "radius") {
|
||||
continue;
|
||||
}
|
||||
if (b_attribute.domain() != BL::Attribute::domain_POINT) {
|
||||
continue;
|
||||
}
|
||||
if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT) {
|
||||
continue;
|
||||
}
|
||||
return BL::FloatAttribute{b_attribute};
|
||||
BL::FloatAttribute b_float_attribute{b_attribute};
|
||||
if (b_float_attribute.data.length() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<const float *>(b_float_attribute.data[0].ptr.data);
|
||||
}
|
||||
return std::nullopt;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static BL::FloatVectorAttribute find_curves_position_attribute(BL::Curves b_curves)
|
||||
static const float (*find_position_attribute(BL::Curves b_curves))[3]
|
||||
{
|
||||
for (BL::Attribute &b_attribute : b_curves.attributes) {
|
||||
if (b_attribute.name() != "position") {
|
||||
continue;
|
||||
}
|
||||
if (b_attribute.domain() != BL::Attribute::domain_POINT) {
|
||||
continue;
|
||||
}
|
||||
if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT_VECTOR) {
|
||||
continue;
|
||||
}
|
||||
return BL::FloatVectorAttribute{b_attribute};
|
||||
BL::FloatVectorAttribute b_float3_attribute{b_attribute};
|
||||
if (b_float3_attribute.data.length() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<const float(*)[3]>(b_float3_attribute.data[0].ptr.data);
|
||||
}
|
||||
/* The position attribute must exist. */
|
||||
assert(false);
|
||||
return BL::FloatVectorAttribute{b_curves.attributes[0]};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename TypeInCycles, typename GetValueAtIndex>
|
||||
static void fill_generic_attribute(BL::Curves &b_curves,
|
||||
static void fill_generic_attribute(const int num_curves,
|
||||
const int num_points,
|
||||
TypeInCycles *data,
|
||||
const AttributeElement element,
|
||||
const GetValueAtIndex &get_value_at_index)
|
||||
{
|
||||
switch (element) {
|
||||
case ATTR_ELEMENT_CURVE_KEY: {
|
||||
const int num_points = b_curves.points.length();
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = get_value_at_index(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATTR_ELEMENT_CURVE: {
|
||||
const int num_verts = b_curves.curves.length();
|
||||
for (int i = 0; i < num_verts; i++) {
|
||||
for (int i = 0; i < num_curves; i++) {
|
||||
data[i] = get_value_at_index(i);
|
||||
}
|
||||
break;
|
||||
|
@ -681,6 +682,7 @@ static void attr_create_motion(Hair *hair, BL::Attribute &b_attribute, const flo
|
|||
}
|
||||
|
||||
BL::FloatVectorAttribute b_vector_attribute(b_attribute);
|
||||
const float(*src)[3] = static_cast<const float(*)[3]>(b_vector_attribute.data[0].ptr.data);
|
||||
const int num_curve_keys = hair->get_curve_keys().size();
|
||||
|
||||
/* Find or add attribute */
|
||||
|
@ -698,23 +700,24 @@ static void attr_create_motion(Hair *hair, BL::Attribute &b_attribute, const flo
|
|||
float3 *mP = attr_mP->data_float3() + step * num_curve_keys;
|
||||
|
||||
for (int i = 0; i < num_curve_keys; i++) {
|
||||
mP[i] = P[i] + get_float3(b_vector_attribute.data[i].vector()) * relative_time;
|
||||
mP[i] = P[i] + make_float3(src[i][0], src[i][1], src[i][2]) * relative_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void attr_create_uv(AttributeSet &attributes,
|
||||
BL::Curves &b_curves,
|
||||
const int num_curves,
|
||||
const int num_points,
|
||||
BL::Attribute &b_attribute,
|
||||
const ustring name)
|
||||
{
|
||||
BL::Float2Attribute b_float2_attribute{b_attribute};
|
||||
const float(*src)[2] = static_cast<const float(*)[2]>(b_float2_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(ATTR_STD_UV, name);
|
||||
|
||||
float2 *data = attr->data_float2();
|
||||
fill_generic_attribute(b_curves, data, ATTR_ELEMENT_CURVE, [&](int i) {
|
||||
BL::Array<float, 2> v = b_float2_attribute.data[i].vector();
|
||||
return make_float2(v[0], v[1]);
|
||||
fill_generic_attribute(num_curves, num_points, data, ATTR_ELEMENT_CURVE, [&](int i) {
|
||||
return make_float2(src[i][0], src[i][1]);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -724,6 +727,9 @@ static void attr_create_generic(Scene *scene,
|
|||
const bool need_motion,
|
||||
const float motion_scale)
|
||||
{
|
||||
const int num_keys = b_curves.points.length();
|
||||
const int num_curves = b_curves.curves.length();
|
||||
|
||||
AttributeSet &attributes = hair->attributes;
|
||||
static const ustring u_velocity("velocity");
|
||||
const bool need_uv = hair->need_attribute(scene, ATTR_STD_UV);
|
||||
|
@ -743,7 +749,7 @@ static void attr_create_generic(Scene *scene,
|
|||
/* Weak, use first float2 attribute as standard UV. */
|
||||
if (need_uv && !have_uv && b_data_type == BL::Attribute::data_type_FLOAT2 &&
|
||||
b_domain == BL::Attribute::domain_CURVE) {
|
||||
attr_create_uv(attributes, b_curves, b_attribute, name);
|
||||
attr_create_uv(attributes, num_curves, num_keys, b_attribute, name);
|
||||
have_uv = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -773,57 +779,70 @@ static void attr_create_generic(Scene *scene,
|
|||
switch (b_data_type) {
|
||||
case BL::Attribute::data_type_FLOAT: {
|
||||
BL::FloatAttribute b_float_attribute{b_attribute};
|
||||
const float *src = static_cast<const float *>(b_float_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeFloat, element);
|
||||
float *data = attr->data_float();
|
||||
fill_generic_attribute(
|
||||
b_curves, data, element, [&](int i) { return b_float_attribute.data[i].value(); });
|
||||
fill_generic_attribute(num_curves, num_keys, data, element, [&](int i) { return src[i]; });
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_BOOLEAN: {
|
||||
BL::BoolAttribute b_bool_attribute{b_attribute};
|
||||
const bool *src = static_cast<const bool *>(b_bool_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeFloat, element);
|
||||
float *data = attr->data_float();
|
||||
fill_generic_attribute(b_curves, data, element, [&](int i) {
|
||||
return (float)b_bool_attribute.data[i].value();
|
||||
});
|
||||
fill_generic_attribute(
|
||||
num_curves, num_keys, data, element, [&](int i) { return float(src[i]); });
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_INT: {
|
||||
BL::IntAttribute b_int_attribute{b_attribute};
|
||||
const int *src = static_cast<const int *>(b_int_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeFloat, element);
|
||||
float *data = attr->data_float();
|
||||
fill_generic_attribute(b_curves, data, element, [&](int i) {
|
||||
return (float)b_int_attribute.data[i].value();
|
||||
});
|
||||
fill_generic_attribute(
|
||||
num_curves, num_keys, data, element, [&](int i) { return float(src[i]); });
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_FLOAT_VECTOR: {
|
||||
BL::FloatVectorAttribute b_vector_attribute{b_attribute};
|
||||
const float(*src)[3] = static_cast<const float(*)[3]>(b_vector_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeVector, element);
|
||||
float3 *data = attr->data_float3();
|
||||
fill_generic_attribute(b_curves, data, element, [&](int i) {
|
||||
BL::Array<float, 3> v = b_vector_attribute.data[i].vector();
|
||||
return make_float3(v[0], v[1], v[2]);
|
||||
fill_generic_attribute(num_curves, num_keys, data, element, [&](int i) {
|
||||
return make_float3(src[i][0], src[i][1], src[i][2]);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_BYTE_COLOR: {
|
||||
BL::ByteColorAttribute b_color_attribute{b_attribute};
|
||||
const uchar(*src)[4] = static_cast<const uchar(*)[4]>(b_color_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeRGBA, element);
|
||||
float4 *data = attr->data_float4();
|
||||
fill_generic_attribute(num_curves, num_keys, data, element, [&](int i) {
|
||||
return make_float4(color_srgb_to_linear(byte_to_float(src[i][0])),
|
||||
color_srgb_to_linear(byte_to_float(src[i][1])),
|
||||
color_srgb_to_linear(byte_to_float(src[i][2])),
|
||||
color_srgb_to_linear(byte_to_float(src[i][3])));
|
||||
});
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_FLOAT_COLOR: {
|
||||
BL::FloatColorAttribute b_color_attribute{b_attribute};
|
||||
const float(*src)[4] = static_cast<const float(*)[4]>(b_color_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeRGBA, element);
|
||||
float4 *data = attr->data_float4();
|
||||
fill_generic_attribute(b_curves, data, element, [&](int i) {
|
||||
BL::Array<float, 4> v = b_color_attribute.data[i].color();
|
||||
return make_float4(v[0], v[1], v[2], v[3]);
|
||||
fill_generic_attribute(num_curves, num_keys, data, element, [&](int i) {
|
||||
return make_float4(src[i][0], src[i][1], src[i][2], src[i][3]);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_FLOAT2: {
|
||||
BL::Float2Attribute b_float2_attribute{b_attribute};
|
||||
const float(*src)[2] = static_cast<const float(*)[2]>(b_float2_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeFloat2, element);
|
||||
float2 *data = attr->data_float2();
|
||||
fill_generic_attribute(b_curves, data, element, [&](int i) {
|
||||
BL::Array<float, 2> v = b_float2_attribute.data[i].vector();
|
||||
return make_float2(v[0], v[1]);
|
||||
fill_generic_attribute(num_curves, num_keys, data, element, [&](int i) {
|
||||
return make_float2(src[i][0], src[i][1]);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -834,27 +853,28 @@ static void attr_create_generic(Scene *scene,
|
|||
}
|
||||
}
|
||||
|
||||
static float4 hair_point_as_float4(BL::FloatVectorAttribute b_attr_position,
|
||||
std::optional<BL::FloatAttribute> b_attr_radius,
|
||||
const int index)
|
||||
static float4 curve_point_as_float4(const float (*b_attr_position)[3],
|
||||
const float *b_attr_radius,
|
||||
const int index)
|
||||
{
|
||||
float4 mP = float3_to_float4(get_float3(b_attr_position.data[index].vector()));
|
||||
mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.005f;
|
||||
float4 mP = make_float4(
|
||||
b_attr_position[index][0], b_attr_position[index][1], b_attr_position[index][2], 0.0f);
|
||||
mP.w = b_attr_radius ? b_attr_radius[index] : 0.005f;
|
||||
return mP;
|
||||
}
|
||||
|
||||
static float4 interpolate_hair_points(BL::FloatVectorAttribute b_attr_position,
|
||||
std::optional<BL::FloatAttribute> b_attr_radius,
|
||||
const int first_point_index,
|
||||
const int num_points,
|
||||
const float step)
|
||||
static float4 interpolate_curve_points(const float (*b_attr_position)[3],
|
||||
const float *b_attr_radius,
|
||||
const int first_point_index,
|
||||
const int num_points,
|
||||
const float step)
|
||||
{
|
||||
const float curve_t = step * (num_points - 1);
|
||||
const int point_a = clamp((int)curve_t, 0, num_points - 1);
|
||||
const int point_b = min(point_a + 1, num_points - 1);
|
||||
const float t = curve_t - (float)point_a;
|
||||
return lerp(hair_point_as_float4(b_attr_position, b_attr_radius, first_point_index + point_a),
|
||||
hair_point_as_float4(b_attr_position, b_attr_radius, first_point_index + point_b),
|
||||
return lerp(curve_point_as_float4(b_attr_position, b_attr_radius, first_point_index + point_a),
|
||||
curve_point_as_float4(b_attr_position, b_attr_radius, first_point_index + point_b),
|
||||
t);
|
||||
}
|
||||
|
||||
|
@ -864,8 +884,6 @@ static void export_hair_curves(Scene *scene,
|
|||
const bool need_motion,
|
||||
const float motion_scale)
|
||||
{
|
||||
/* TODO: optimize so we can straight memcpy arrays from Blender? */
|
||||
|
||||
const int num_keys = b_curves.points.length();
|
||||
const int num_curves = b_curves.curves.length();
|
||||
|
||||
|
@ -879,7 +897,6 @@ static void export_hair_curves(Scene *scene,
|
|||
/* Add requested attributes. */
|
||||
float *attr_intercept = NULL;
|
||||
float *attr_length = NULL;
|
||||
float *attr_random = NULL;
|
||||
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
|
||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT)->data_float();
|
||||
|
@ -888,28 +905,40 @@ static void export_hair_curves(Scene *scene,
|
|||
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH)->data_float();
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
|
||||
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM)->data_float();
|
||||
float *attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM)->data_float();
|
||||
for (int i = 0; i < num_curves; i++) {
|
||||
attr_random[i] = hash_uint2_to_float(i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BL::FloatVectorAttribute b_attr_position = find_curves_position_attribute(b_curves);
|
||||
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
|
||||
const int *point_offsets = static_cast<const int *>(b_curves.curve_offset_data[0].ptr.data);
|
||||
const float(*b_attr_position)[3] = find_position_attribute(b_curves);
|
||||
const float *b_attr_radius = find_radius_attribute(b_curves);
|
||||
|
||||
std::copy(point_offsets, point_offsets + num_curves, curve_first_key);
|
||||
std::fill(curve_shader, curve_shader + num_curves, 0);
|
||||
if (b_attr_radius) {
|
||||
std::copy(b_attr_radius, b_attr_radius + num_keys, curve_radius);
|
||||
}
|
||||
else {
|
||||
std::fill(curve_radius, curve_radius + num_curves, 0.005f);
|
||||
}
|
||||
|
||||
/* Export curves and points. */
|
||||
for (int i = 0; i < num_curves; i++) {
|
||||
const int first_point_index = b_curves.curve_offset_data[i].value();
|
||||
const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
|
||||
const int first_point_index = point_offsets[i];
|
||||
const int num_points = point_offsets[i + 1] - first_point_index;
|
||||
|
||||
float3 prev_co = zero_float3();
|
||||
float length = 0.0f;
|
||||
|
||||
/* Position and radius. */
|
||||
for (int j = 0; j < num_points; j++) {
|
||||
const int point_offset = first_point_index + j;
|
||||
const float3 co = get_float3(b_attr_position.data[point_offset].vector());
|
||||
const float radius = b_attr_radius ? b_attr_radius->data[point_offset].value() : 0.005f;
|
||||
const int point = first_point_index + j;
|
||||
const float3 co = make_float3(
|
||||
b_attr_position[point][0], b_attr_position[point][1], b_attr_position[point][2]);
|
||||
|
||||
curve_keys[point_offset] = co;
|
||||
curve_radius[point_offset] = radius;
|
||||
curve_keys[point] = co;
|
||||
|
||||
if (attr_length || attr_intercept) {
|
||||
if (j > 0) {
|
||||
|
@ -918,7 +947,7 @@ static void export_hair_curves(Scene *scene,
|
|||
prev_co = co;
|
||||
|
||||
if (attr_intercept) {
|
||||
attr_intercept[point_offset] = length;
|
||||
attr_intercept[point] = length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -926,8 +955,8 @@ static void export_hair_curves(Scene *scene,
|
|||
/* Normalized 0..1 attribute along curve. */
|
||||
if (attr_intercept && length > 0.0f) {
|
||||
for (int j = 1; j < num_points; j++) {
|
||||
const int point_offset = first_point_index + j;
|
||||
attr_intercept[point_offset] /= length;
|
||||
const int point = first_point_index + j;
|
||||
attr_intercept[point] /= length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -935,15 +964,6 @@ static void export_hair_curves(Scene *scene,
|
|||
if (attr_length) {
|
||||
attr_length[i] = length;
|
||||
}
|
||||
|
||||
/* Random number per curve. */
|
||||
if (attr_random != NULL) {
|
||||
attr_random[i] = hash_uint2_to_float(i, 0);
|
||||
}
|
||||
|
||||
/* Curve. */
|
||||
curve_shader[i] = 0;
|
||||
curve_first_key[i] = first_point_index;
|
||||
}
|
||||
|
||||
attr_create_generic(scene, hair, b_curves, need_motion, motion_scale);
|
||||
|
@ -968,12 +988,13 @@ static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motio
|
|||
int num_motion_keys = 0;
|
||||
int curve_index = 0;
|
||||
|
||||
BL::FloatVectorAttribute b_attr_position = find_curves_position_attribute(b_curves);
|
||||
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
|
||||
const int *point_offsets = static_cast<const int *>(b_curves.curve_offset_data[0].ptr.data);
|
||||
const float(*b_attr_position)[3] = find_position_attribute(b_curves);
|
||||
const float *b_attr_radius = find_radius_attribute(b_curves);
|
||||
|
||||
for (int i = 0; i < num_curves; i++) {
|
||||
const int first_point_index = b_curves.curve_offset_data[i].value();
|
||||
const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
|
||||
const int first_point_index = point_offsets[i];
|
||||
const int num_points = point_offsets[i + 1] - first_point_index;
|
||||
|
||||
Hair::Curve curve = hair->get_curve(curve_index);
|
||||
curve_index++;
|
||||
|
@ -981,10 +1002,10 @@ static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motio
|
|||
if (num_points == curve.num_keys) {
|
||||
/* Number of keys matches. */
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
int point_index = first_point_index + i;
|
||||
int point = first_point_index + i;
|
||||
|
||||
if (point_index < num_keys) {
|
||||
mP[num_motion_keys] = hair_point_as_float4(b_attr_position, b_attr_radius, point_index);
|
||||
if (point < num_keys) {
|
||||
mP[num_motion_keys] = curve_point_as_float4(b_attr_position, b_attr_radius, point);
|
||||
num_motion_keys++;
|
||||
|
||||
if (!have_motion) {
|
||||
|
@ -1003,7 +1024,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motio
|
|||
const float step_size = curve.num_keys > 1 ? 1.0f / (curve.num_keys - 1) : 0.0f;
|
||||
for (int i = 0; i < curve.num_keys; i++) {
|
||||
const float step = i * step_size;
|
||||
mP[num_motion_keys] = interpolate_hair_points(
|
||||
mP[num_motion_keys] = interpolate_curve_points(
|
||||
b_attr_position, b_attr_radius, first_point_index, num_points, step);
|
||||
num_motion_keys++;
|
||||
}
|
||||
|
|
|
@ -10,22 +10,12 @@
|
|||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
|
||||
#include "util/color.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/hash.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
template<typename TypeInCycles, typename GetValueAtIndex>
|
||||
static void fill_generic_attribute(BL::PointCloud &b_pointcloud,
|
||||
TypeInCycles *data,
|
||||
const GetValueAtIndex &get_value_at_index)
|
||||
{
|
||||
const int num_points = b_pointcloud.points.length();
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = get_value_at_index(i);
|
||||
}
|
||||
}
|
||||
|
||||
static void attr_create_motion(PointCloud *pointcloud,
|
||||
BL::Attribute &b_attribute,
|
||||
const float motion_scale)
|
||||
|
@ -63,6 +53,11 @@ static void copy_attributes(PointCloud *pointcloud,
|
|||
const bool need_motion,
|
||||
const float motion_scale)
|
||||
{
|
||||
const int num_points = b_pointcloud.points.length();
|
||||
if (num_points == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
AttributeSet &attributes = pointcloud->attributes;
|
||||
static const ustring u_velocity("velocity");
|
||||
for (BL::Attribute &b_attribute : b_pointcloud.attributes) {
|
||||
|
@ -81,56 +76,73 @@ static void copy_attributes(PointCloud *pointcloud,
|
|||
switch (b_data_type) {
|
||||
case BL::Attribute::data_type_FLOAT: {
|
||||
BL::FloatAttribute b_float_attribute{b_attribute};
|
||||
const float *src = static_cast<const float *>(b_float_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeFloat, element);
|
||||
float *data = attr->data_float();
|
||||
fill_generic_attribute(
|
||||
b_pointcloud, data, [&](int i) { return b_float_attribute.data[i].value(); });
|
||||
std::copy(src, src + num_points, data);
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_BOOLEAN: {
|
||||
BL::BoolAttribute b_bool_attribute{b_attribute};
|
||||
const bool *src = static_cast<const bool *>(b_bool_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeFloat, element);
|
||||
float *data = attr->data_float();
|
||||
fill_generic_attribute(
|
||||
b_pointcloud, data, [&](int i) { return (float)b_bool_attribute.data[i].value(); });
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = float(src[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_INT: {
|
||||
BL::IntAttribute b_int_attribute{b_attribute};
|
||||
const int *src = static_cast<const int *>(b_int_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeFloat, element);
|
||||
float *data = attr->data_float();
|
||||
fill_generic_attribute(
|
||||
b_pointcloud, data, [&](int i) { return (float)b_int_attribute.data[i].value(); });
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = float(src[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_FLOAT_VECTOR: {
|
||||
BL::FloatVectorAttribute b_vector_attribute{b_attribute};
|
||||
const float(*src)[3] = static_cast<const float(*)[3]>(b_vector_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeVector, element);
|
||||
float3 *data = attr->data_float3();
|
||||
fill_generic_attribute(b_pointcloud, data, [&](int i) {
|
||||
BL::Array<float, 3> v = b_vector_attribute.data[i].vector();
|
||||
return make_float3(v[0], v[1], v[2]);
|
||||
});
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = make_float3(src[i][0], src[i][1], src[i][2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_BYTE_COLOR: {
|
||||
BL::ByteColorAttribute b_color_attribute{b_attribute};
|
||||
const uchar(*src)[4] = static_cast<const uchar(*)[4]>(b_color_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeRGBA, element);
|
||||
float4 *data = attr->data_float4();
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = make_float4(color_srgb_to_linear(byte_to_float(src[i][0])),
|
||||
color_srgb_to_linear(byte_to_float(src[i][1])),
|
||||
color_srgb_to_linear(byte_to_float(src[i][2])),
|
||||
color_srgb_to_linear(byte_to_float(src[i][3])));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_FLOAT_COLOR: {
|
||||
BL::FloatColorAttribute b_color_attribute{b_attribute};
|
||||
const float(*src)[4] = static_cast<const float(*)[4]>(b_color_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeRGBA, element);
|
||||
float4 *data = attr->data_float4();
|
||||
fill_generic_attribute(b_pointcloud, data, [&](int i) {
|
||||
BL::Array<float, 4> v = b_color_attribute.data[i].color();
|
||||
return make_float4(v[0], v[1], v[2], v[3]);
|
||||
});
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = make_float4(src[i][0], src[i][1], src[i][2], src[i][3]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::data_type_FLOAT2: {
|
||||
BL::Float2Attribute b_float2_attribute{b_attribute};
|
||||
const float(*src)[2] = static_cast<const float(*)[2]>(b_float2_attribute.data[0].ptr.data);
|
||||
Attribute *attr = attributes.add(name, TypeFloat2, element);
|
||||
float2 *data = attr->data_float2();
|
||||
fill_generic_attribute(b_pointcloud, data, [&](int i) {
|
||||
BL::Array<float, 2> v = b_float2_attribute.data[i].vector();
|
||||
return make_float2(v[0], v[1]);
|
||||
});
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = make_float2(src[i][0], src[i][1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -140,7 +152,7 @@ static void copy_attributes(PointCloud *pointcloud,
|
|||
}
|
||||
}
|
||||
|
||||
static std::optional<BL::FloatAttribute> find_radius_attribute(BL::PointCloud b_pointcloud)
|
||||
static const float *find_radius_attribute(BL::PointCloud b_pointcloud)
|
||||
{
|
||||
for (BL::Attribute &b_attribute : b_pointcloud.attributes) {
|
||||
if (b_attribute.name() != "radius") {
|
||||
|
@ -149,12 +161,16 @@ static std::optional<BL::FloatAttribute> find_radius_attribute(BL::PointCloud b_
|
|||
if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT) {
|
||||
continue;
|
||||
}
|
||||
return BL::FloatAttribute{b_attribute};
|
||||
BL::FloatAttribute b_float_attribute{b_attribute};
|
||||
if (b_float_attribute.data.length() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<const float *>(b_float_attribute.data[0].ptr.data);
|
||||
}
|
||||
return std::nullopt;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static BL::FloatVectorAttribute find_position_attribute(BL::PointCloud b_pointcloud)
|
||||
static const float (*find_position_attribute(BL::PointCloud b_pointcloud))[3]
|
||||
{
|
||||
for (BL::Attribute &b_attribute : b_pointcloud.attributes) {
|
||||
if (b_attribute.name() != "position") {
|
||||
|
@ -163,11 +179,15 @@ static BL::FloatVectorAttribute find_position_attribute(BL::PointCloud b_pointcl
|
|||
if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT_VECTOR) {
|
||||
continue;
|
||||
}
|
||||
return BL::FloatVectorAttribute{b_attribute};
|
||||
BL::FloatVectorAttribute b_float3_attribute{b_attribute};
|
||||
if (b_float3_attribute.data.length() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<const float(*)[3]>(b_float3_attribute.data[0].ptr.data);
|
||||
}
|
||||
/* The position attribute must exist. */
|
||||
assert(false);
|
||||
return BL::FloatVectorAttribute{b_pointcloud.attributes[0]};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void export_pointcloud(Scene *scene,
|
||||
|
@ -176,34 +196,36 @@ static void export_pointcloud(Scene *scene,
|
|||
const bool need_motion,
|
||||
const float motion_scale)
|
||||
{
|
||||
/* TODO: optimize so we can straight memcpy arrays from Blender? */
|
||||
const int num_points = b_pointcloud.points.length();
|
||||
pointcloud->resize(num_points);
|
||||
|
||||
/* Add requested attributes. */
|
||||
Attribute *attr_random = NULL;
|
||||
if (pointcloud->need_attribute(scene, ATTR_STD_POINT_RANDOM)) {
|
||||
attr_random = pointcloud->attributes.add(ATTR_STD_POINT_RANDOM);
|
||||
const float(*b_attr_position)[3] = find_position_attribute(b_pointcloud);
|
||||
float3 *points = pointcloud->get_points().data();
|
||||
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
points[i] = make_float3(b_attr_position[i][0], b_attr_position[i][1], b_attr_position[i][2]);
|
||||
}
|
||||
|
||||
/* Reserve memory. */
|
||||
const int num_points = b_pointcloud.points.length();
|
||||
pointcloud->reserve(num_points);
|
||||
const float *b_attr_radius = find_radius_attribute(b_pointcloud);
|
||||
float *radius = pointcloud->get_radius().data();
|
||||
if (b_attr_radius) {
|
||||
std::copy(b_attr_radius, b_attr_radius + num_points, radius);
|
||||
}
|
||||
else {
|
||||
std::fill(radius, radius + num_points, 0.01f);
|
||||
}
|
||||
|
||||
BL::FloatVectorAttribute b_attr_position = find_position_attribute(b_pointcloud);
|
||||
std::optional<BL::FloatAttribute> b_attr_radius = find_radius_attribute(b_pointcloud);
|
||||
int *shader = pointcloud->get_shader().data();
|
||||
std::fill(shader, shader + num_points, 0);
|
||||
|
||||
/* Export points. */
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
const float3 co = get_float3(b_attr_position.data[i].vector());
|
||||
const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.01f;
|
||||
pointcloud->add_point(co, radius);
|
||||
|
||||
/* Random number per point. */
|
||||
if (attr_random != NULL) {
|
||||
attr_random->add(hash_uint2_to_float(i, 0));
|
||||
if (pointcloud->need_attribute(scene, ATTR_STD_POINT_RANDOM)) {
|
||||
Attribute *attr_random = pointcloud->attributes.add(ATTR_STD_POINT_RANDOM);
|
||||
float *data = attr_random->data_float();
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
data[i] = hash_uint2_to_float(i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Export attributes */
|
||||
copy_attributes(pointcloud, b_pointcloud, need_motion, motion_scale);
|
||||
}
|
||||
|
||||
|
@ -220,22 +242,22 @@ static void export_pointcloud_motion(PointCloud *pointcloud,
|
|||
new_attribute = true;
|
||||
}
|
||||
|
||||
/* Export motion points. */
|
||||
const int num_points = pointcloud->num_points();
|
||||
// Point cloud attributes are stored as float4 with the radius
|
||||
// in the w element. This is explict now as float3 is no longer
|
||||
// interchangeable with float4 as it is packed now.
|
||||
/* Point cloud attributes are stored as float4 with the radius in the w element.
|
||||
* This is explict now as float3 is no longer interchangeable with float4 as it
|
||||
* is packed now. */
|
||||
float4 *mP = attr_mP->data_float4() + motion_step * num_points;
|
||||
bool have_motion = false;
|
||||
const array<float3> &pointcloud_points = pointcloud->get_points();
|
||||
|
||||
const int b_points_num = b_pointcloud.points.length();
|
||||
BL::FloatVectorAttribute b_attr_position = find_position_attribute(b_pointcloud);
|
||||
std::optional<BL::FloatAttribute> b_attr_radius = find_radius_attribute(b_pointcloud);
|
||||
const float(*b_attr_position)[3] = find_position_attribute(b_pointcloud);
|
||||
const float *b_attr_radius = find_radius_attribute(b_pointcloud);
|
||||
|
||||
for (int i = 0; i < std::min(num_points, b_points_num); i++) {
|
||||
const float3 P = get_float3(b_attr_position.data[i].vector());
|
||||
const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.01f;
|
||||
const float3 P = make_float3(
|
||||
b_attr_position[i][0], b_attr_position[i][1], b_attr_position[i][2]);
|
||||
const float radius = b_attr_radius ? b_attr_radius[i] : 0.01f;
|
||||
mP[i] = make_float4(P.x, P.y, P.z, radius);
|
||||
have_motion = have_motion || (P != pointcloud_points[i]);
|
||||
}
|
||||
|
@ -277,7 +299,7 @@ void BlenderSync::sync_pointcloud(PointCloud *pointcloud, BObjectInfo &b_ob_info
|
|||
0.0f;
|
||||
export_pointcloud(scene, &new_pointcloud, b_pointcloud, need_motion, motion_scale);
|
||||
|
||||
/* update original sockets */
|
||||
/* Update original sockets. */
|
||||
for (const SocketType &socket : new_pointcloud.type->inputs) {
|
||||
/* Those sockets are updated in sync_object, so do not modify them. */
|
||||
if (socket.name == "use_motion_blur" || socket.name == "motion_steps" ||
|
||||
|
@ -292,7 +314,7 @@ void BlenderSync::sync_pointcloud(PointCloud *pointcloud, BObjectInfo &b_ob_info
|
|||
pointcloud->attributes.attributes.push_back(std::move(attr));
|
||||
}
|
||||
|
||||
/* tag update */
|
||||
/* Tag update. */
|
||||
const bool rebuild = (pointcloud && old_numpoints != pointcloud->num_points());
|
||||
pointcloud->tag_update(scene, rebuild);
|
||||
}
|
||||
|
|
|
@ -109,6 +109,11 @@ class PassAccessor {
|
|||
/* Set pass data for the given render buffers. Used for baking to read from passes. */
|
||||
bool set_render_tile_pixels(RenderBuffers *render_buffers, const Source &source);
|
||||
|
||||
const PassAccessInfo &get_pass_access_info() const
|
||||
{
|
||||
return pass_access_info_;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void init_kernel_film_convert(KernelFilmConvert *kfilm_convert,
|
||||
const BufferParams &buffer_params,
|
||||
|
|
|
@ -1036,7 +1036,12 @@ bool PathTrace::get_render_tile_pixels(const PassAccessor &pass_accessor,
|
|||
}
|
||||
|
||||
if (big_tile_denoise_work_ && render_state_.has_denoised_result) {
|
||||
return big_tile_denoise_work_->get_render_tile_pixels(pass_accessor, destination);
|
||||
/* Only use the big tile denoised buffer to access the denoised passes.
|
||||
* The guiding passes are allowed to be modified in-place for the needs of the denoiser,
|
||||
* so copy those from the original devices buffers. */
|
||||
if (pass_accessor.get_pass_access_info().mode == PassMode::DENOISED) {
|
||||
return big_tile_denoise_work_->get_render_tile_pixels(pass_accessor, destination);
|
||||
}
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
|
|
|
@ -555,8 +555,8 @@ class NODE_MT_context_menu(Menu):
|
|||
layout.operator("node.group_edit", text="Edit").exit = False
|
||||
layout.operator("node.group_ungroup", text="Ungroup")
|
||||
|
||||
if is_nested:
|
||||
layout.operator("node.tree_path_parent", text="Exit Group", icon='FILE_PARENT')
|
||||
if is_nested:
|
||||
layout.operator("node.tree_path_parent", text="Exit Group", icon='FILE_PARENT')
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
|
|
@ -171,6 +171,15 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w,
|
|||
*/
|
||||
int BLI_wcwidth(char32_t ucs) ATTR_WARN_UNUSED_RESULT;
|
||||
int BLI_wcswidth(const char32_t *pwcs, size_t n) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
|
||||
|
||||
/**
|
||||
* Upper and lowercase for 32-bit characters for all scripts that distinguish case. One-to-one
|
||||
* mappings so this doesn't work corectly for uppercase Σ (two lowercase forms) and lowercase ß
|
||||
* won't become "SS".
|
||||
*/
|
||||
char32_t BLI_str_utf32_char_to_upper(char32_t wc);
|
||||
char32_t BLI_str_utf32_char_to_lower(char32_t wc);
|
||||
|
||||
/**
|
||||
* \warning can return -1 on bad chars.
|
||||
*/
|
||||
|
|
|
@ -399,6 +399,218 @@ int BLI_str_utf8_char_width_safe(const char *p)
|
|||
return (columns < 0) ? 1 : columns;
|
||||
}
|
||||
|
||||
char32_t BLI_str_utf32_char_to_upper(char32_t wc)
|
||||
{
|
||||
if (wc < U'\xFF') { /* Latin. */
|
||||
if ((wc <= U'z' && wc >= U'a') || (wc <= U'\xF6' && wc >= U'\xE0') ||
|
||||
(wc <= U'\xFE' && wc >= U'\xF8')) {
|
||||
return wc - 32;
|
||||
}
|
||||
return wc;
|
||||
}
|
||||
|
||||
if ((wc <= U'\x137' && wc >= U'\x101') || (wc <= U'\x1E95' && wc >= U'\x1E01')) {
|
||||
/* Latin Extended. */
|
||||
return (wc & 1) ? wc - 1 : wc;
|
||||
}
|
||||
if ((wc <= U'\x586' && wc >= U'\x561') || (wc <= U'\x10F5' && wc >= U'\x10D0')) {
|
||||
/* Armenian and Georgian */
|
||||
return wc - 48;
|
||||
}
|
||||
if (wc <= U'\x24E9' && wc >= U'\x24D0') { /* Enclosed Numerals. */
|
||||
return wc - 26;
|
||||
}
|
||||
if (wc <= U'\xFF5A' && wc >= U'\xFF41') { /* Fullwidth Forms. */
|
||||
return wc - 32;
|
||||
}
|
||||
|
||||
/* There are only three remaining ranges that contain capitalization. */
|
||||
if (!(wc <= U'\x0292' && wc >= U'\x00FF') && !(wc <= U'\x04F9' && wc >= U'\x03AC') &&
|
||||
!(wc <= U'\x1FE1' && wc >= U'\x1E01')) {
|
||||
return wc;
|
||||
}
|
||||
|
||||
static const char32_t from[] =
|
||||
U"\x00FF\x013A\x013C\x013E\x0140\x0142\x0144\x0146\x0148\x014B\x014D\x014F\x0151\x0153\x0155"
|
||||
U"\x0157\x0159\x015B\x015D\x015F\x0161\x0163\x0165\x0167\x0169\x016B\x016D\x016F\x0171\x0173"
|
||||
U"\x0175\x0177\x017A\x017C\x017E\x0183\x0185\x0188\x018C\x0192\x0199\x01A1\x01A3\x01A5\x01A8"
|
||||
U"\x01AD\x01B0\x01B4\x01B6\x01B9\x01BD\x01C6\x01C9\x01CC\x01CE\x01D0\x01D2\x01D4\x01D6\x01D8"
|
||||
U"\x01DA\x01DC\x01DF\x01E1\x01E3\x01E5\x01E7\x01E9\x01EB\x01ED\x01EF\x01F3\x01F5\x01FB\x01FD"
|
||||
U"\x01FF\x0201\x0203\x0205\x0207\x0209\x020B\x020D\x020F\x0211\x0213\x0215\x0217\x0253\x0254"
|
||||
U"\x0257\x0258\x0259\x025B\x0260\x0263\x0268\x0269\x026F\x0272\x0275\x0283\x0288\x028A\x028B"
|
||||
U"\x0292\x03AC\x03AD\x03AE\x03AF\x03B1\x03B2\x03B3\x03B4\x03B5\x03B6\x03B7\x03B8\x03B9\x03BA"
|
||||
U"\x03BB\x03BC\x03BD\x03BE\x03BF\x03C0\x03C1\x03C3\x03C4\x03C5\x03C6\x03C7\x03C8\x03C9\x03CA"
|
||||
U"\x03CB\x03CC\x03CD\x03CE\x03E3\x03E5\x03E7\x03E9\x03EB\x03ED\x03EF\x0430\x0431\x0432\x0433"
|
||||
U"\x0434\x0435\x0436\x0437\x0438\x0439\x043A\x043B\x043C\x043D\x043E\x043F\x0440\x0441\x0442"
|
||||
U"\x0443\x0444\x0445\x0446\x0447\x0448\x0449\x044A\x044B\x044C\x044D\x044E\x044F\x0451\x0452"
|
||||
U"\x0453\x0454\x0455\x0456\x0457\x0458\x0459\x045A\x045B\x045C\x045E\x045F\x0461\x0463\x0465"
|
||||
U"\x0467\x0469\x046B\x046D\x046F\x0471\x0473\x0475\x0477\x0479\x047B\x047D\x047F\x0481\x0491"
|
||||
U"\x0493\x0495\x0497\x0499\x049B\x049D\x049F\x04A1\x04A3\x04A5\x04A7\x04A9\x04AB\x04AD\x04AF"
|
||||
U"\x04B1\x04B3\x04B5\x04B7\x04B9\x04BB\x04BD\x04BF\x04C2\x04C4\x04C8\x04CC\x04D1\x04D3\x04D5"
|
||||
U"\x04D7\x04D9\x04DB\x04DD\x04DF\x04E1\x04E3\x04E5\x04E7\x04E9\x04EB\x04EF\x04F1\x04F3\x04F5"
|
||||
U"\x04F9\x1EA1\x1EA3\x1EA5\x1EA7\x1EA9\x1EAB\x1EAD\x1EAF\x1EB1\x1EB3\x1EB5\x1EB7\x1EB9\x1EBB"
|
||||
U"\x1EBD\x1EBF\x1EC1\x1EC3\x1EC5\x1EC7\x1EC9\x1ECB\x1ECD\x1ECF\x1ED1\x1ED3\x1ED5\x1ED7\x1ED9"
|
||||
U"\x1EDB\x1EDD\x1EDF\x1EE1\x1EE3\x1EE5\x1EE7\x1EE9\x1EEB\x1EED\x1EEF\x1EF1\x1EF3\x1EF5\x1EF7"
|
||||
U"\x1EF9\x1F00\x1F01\x1F02\x1F03\x1F04\x1F05\x1F06\x1F07\x1F10\x1F11\x1F12\x1F13\x1F14\x1F15"
|
||||
U"\x1F20\x1F21\x1F22\x1F23\x1F24\x1F25\x1F26\x1F27\x1F30\x1F31\x1F32\x1F33\x1F34\x1F35\x1F36"
|
||||
U"\x1F37\x1F40\x1F41\x1F42\x1F43\x1F44\x1F45\x1F51\x1F53\x1F55\x1F57\x1F60\x1F61\x1F62\x1F63"
|
||||
U"\x1F64\x1F65\x1F66\x1F67\x1F80\x1F81\x1F82\x1F83\x1F84\x1F85\x1F86\x1F87\x1F90\x1F91\x1F92"
|
||||
U"\x1F93\x1F94\x1F95\x1F96\x1F97\x1FA0\x1FA1\x1FA2\x1FA3\x1FA4\x1FA5\x1FA6\x1FA7\x1FB0\x1FB1"
|
||||
U"\x1FD0\x1FD1\x1FE0\x1FE1";
|
||||
static const char32_t to[] =
|
||||
U"\x0178\x0139\x013B\x013D\x013F\x0141\x0143\x0145\x0147\x014A\x014C\x014E\x0150\x0152\x0154"
|
||||
U"\x0156\x0158\x015A\x015C\x015E\x0160\x0162\x0164\x0166\x0168\x016A\x016C\x016E\x0170\x0172"
|
||||
U"\x0174\x0176\x0179\x017B\x017D\x0182\x0184\x0187\x018B\x0191\x0198\x01A0\x01A2\x01A4\x01A7"
|
||||
U"\x01AC\x01AF\x01B3\x01B5\x01B8\x01BC\x01C4\x01C7\x01CA\x01CD\x01CF\x01D1\x01D3\x01D5\x01D7"
|
||||
U"\x01D9\x01DB\x01DE\x01E0\x01E2\x01E4\x01E6\x01E8\x01EA\x01EC\x01EE\x01F1\x01F4\x01FA\x01FC"
|
||||
U"\x01FE\x0200\x0202\x0204\x0206\x0208\x020A\x020C\x020E\x0210\x0212\x0214\x0216\x0181\x0186"
|
||||
U"\x018A\x018E\x018F\x0190\x0193\x0194\x0197\x0196\x019C\x019D\x019F\x01A9\x01AE\x01B1\x01B2"
|
||||
U"\x01B7\x0386\x0388\x0389\x038A\x0391\x0392\x0393\x0394\x0395\x0396\x0397\x0398\x0399\x039A"
|
||||
U"\x039B\x039C\x039D\x039E\x039F\x03A0\x03A1\x03A3\x03A4\x03A5\x03A6\x03A7\x03A8\x03A9\x03AA"
|
||||
U"\x03AB\x038C\x038E\x038F\x03E2\x03E4\x03E6\x03E8\x03EA\x03EC\x03EE\x0410\x0411\x0412\x0413"
|
||||
U"\x0414\x0415\x0416\x0417\x0418\x0419\x041A\x041B\x041C\x041D\x041E\x041F\x0420\x0421\x0422"
|
||||
U"\x0423\x0424\x0425\x0426\x0427\x0428\x0429\x042A\x042B\x042C\x042D\x042E\x042F\x0401\x0402"
|
||||
U"\x0403\x0404\x0405\x0406\x0407\x0408\x0409\x040A\x040B\x040C\x040E\x040F\x0460\x0462\x0464"
|
||||
U"\x0466\x0468\x046A\x046C\x046E\x0470\x0472\x0474\x0476\x0478\x047A\x047C\x047E\x0480\x0490"
|
||||
U"\x0492\x0494\x0496\x0498\x049A\x049C\x049E\x04A0\x04A2\x04A4\x04A6\x04A8\x04AA\x04AC\x04AE"
|
||||
U"\x04B0\x04B2\x04B4\x04B6\x04B8\x04BA\x04BC\x04BE\x04C1\x04C3\x04C7\x04CB\x04D0\x04D2\x04D4"
|
||||
U"\x04D6\x04D8\x04DA\x04DC\x04DE\x04E0\x04E2\x04E4\x04E6\x04E8\x04EA\x04EE\x04F0\x04F2\x04F4"
|
||||
U"\x04F8\x1EA0\x1EA2\x1EA4\x1EA6\x1EA8\x1EAA\x1EAC\x1EAE\x1EB0\x1EB2\x1EB4\x1EB6\x1EB8\x1EBA"
|
||||
U"\x1EBC\x1EBE\x1EC0\x1EC2\x1EC4\x1EC6\x1EC8\x1ECA\x1ECC\x1ECE\x1ED0\x1ED2\x1ED4\x1ED6\x1ED8"
|
||||
U"\x1EDA\x1EDC\x1EDE\x1EE0\x1EE2\x1EE4\x1EE6\x1EE8\x1EEA\x1EEC\x1EEE\x1EF0\x1EF2\x1EF4\x1EF6"
|
||||
U"\x1EF8\x1F08\x1F09\x1F0A\x1F0B\x1F0C\x1F0D\x1F0E\x1F0F\x1F18\x1F19\x1F1A\x1F1B\x1F1C\x1F1D"
|
||||
U"\x1F28\x1F29\x1F2A\x1F2B\x1F2C\x1F2D\x1F2E\x1F2F\x1F38\x1F39\x1F3A\x1F3B\x1F3C\x1F3D\x1F3E"
|
||||
U"\x1F3F\x1F48\x1F49\x1F4A\x1F4B\x1F4C\x1F4D\x1F59\x1F5B\x1F5D\x1F5F\x1F68\x1F69\x1F6A\x1F6B"
|
||||
U"\x1F6C\x1F6D\x1F6E\x1F6F\x1F88\x1F89\x1F8A\x1F8B\x1F8C\x1F8D\x1F8E\x1F8F\x1F98\x1F99\x1F9A"
|
||||
U"\x1F9B\x1F9C\x1F9D\x1F9E\x1F9F\x1FA8\x1FA9\x1FAA\x1FAB\x1FAC\x1FAD\x1FAE\x1FAF\x1FB8\x1FB9"
|
||||
U"\x1FD8\x1FD9\x1FE8\x1FE9";
|
||||
|
||||
if (wc >= from[0] && wc <= from[ARRAY_SIZE(from) - 2]) {
|
||||
/* Binary search since these are sorted. */
|
||||
int min = 0;
|
||||
int max = ARRAY_SIZE(from) - 2;
|
||||
while (max >= min) {
|
||||
const int mid = (min + max) / 2;
|
||||
if (wc > from[mid]) {
|
||||
min = mid + 1;
|
||||
}
|
||||
else if (wc < from[mid]) {
|
||||
max = mid - 1;
|
||||
}
|
||||
else {
|
||||
return to[mid];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wc;
|
||||
}
|
||||
|
||||
char32_t BLI_str_utf32_char_to_lower(char32_t wc)
|
||||
{
|
||||
if (wc < U'\xD8') { /* Latin. */
|
||||
if ((wc <= U'Z' && wc >= U'A') || (wc <= U'\xD6' && wc >= U'\xC0')) {
|
||||
return wc + 32;
|
||||
}
|
||||
return wc;
|
||||
}
|
||||
if ((wc <= U'\x136' && wc >= U'\x100') || (wc <= U'\x1E94' && wc >= U'\x1E00')) {
|
||||
/* Latin Extended. */
|
||||
return (wc % 2 == 0) ? wc + 1 : wc;
|
||||
}
|
||||
if ((wc <= U'\x556' && wc >= U'\x531') || (wc <= U'\x10C5' && wc >= U'\x10A0')) {
|
||||
/* Armenian and Georgian. */
|
||||
return wc + 48;
|
||||
}
|
||||
if (wc <= U'\x24CF' && wc >= U'\x24B6') { /* Enclosed Numerals. */
|
||||
return wc + 26;
|
||||
}
|
||||
if (wc <= U'\xFF3A' && wc >= U'\xFF21') { /* Fullwidth Forms. */
|
||||
return wc + 32;
|
||||
}
|
||||
|
||||
/* There are only three remaining ranges that contain capitalization. */
|
||||
if (!(wc <= U'\x0216' && wc >= U'\x00D8') && !(wc <= U'\x04F8' && wc >= U'\x0386') &&
|
||||
!(wc <= U'\x1FE9' && wc >= U'\x1E00')) {
|
||||
return wc;
|
||||
}
|
||||
|
||||
static const char32_t from[] =
|
||||
U"\x00D8\x00D9\x00DA\x00DB\x00DC\x00DD\x00DE\x0139\x013B\x013D\x013F\x0141\x0143\x0145\x0147"
|
||||
U"\x014A\x014C\x014E\x0150\x0152\x0154\x0156\x0158\x015A\x015C\x015E\x0160\x0162\x0164\x0166"
|
||||
U"\x0168\x016A\x016C\x016E\x0170\x0172\x0174\x0176\x0178\x0179\x017B\x017D\x0181\x0182\x0184"
|
||||
U"\x0186\x0187\x018A\x018B\x018E\x018F\x0190\x0191\x0193\x0194\x0196\x0197\x0198\x019C\x019D"
|
||||
U"\x019F\x01A0\x01A2\x01A4\x01A7\x01A9\x01AC\x01AE\x01AF\x01B1\x01B2\x01B3\x01B5\x01B7\x01B8"
|
||||
U"\x01BC\x01C4\x01C5\x01C7\x01C8\x01CA\x01CB\x01CD\x01CF\x01D1\x01D3\x01D5\x01D7\x01D9\x01DB"
|
||||
U"\x01DE\x01E0\x01E2\x01E4\x01E6\x01E8\x01EA\x01EC\x01EE\x01F1\x01F4\x01FA\x01FC\x01FE\x0200"
|
||||
U"\x0202\x0204\x0206\x0208\x020A\x020C\x020E\x0210\x0212\x0214\x0216\x0386\x0388\x0389\x038A"
|
||||
U"\x038C\x038E\x038F\x0391\x0392\x0393\x0394\x0395\x0396\x0397\x0398\x0399\x039A\x039B\x039C"
|
||||
U"\x039D\x039E\x039F\x03A0\x03A1\x03A3\x03A4\x03A5\x03A6\x03A7\x03A8\x03A9\x03AA\x03AB\x03E2"
|
||||
U"\x03E4\x03E6\x03E8\x03EA\x03EC\x03EE\x0401\x0402\x0403\x0404\x0405\x0406\x0407\x0408\x0409"
|
||||
U"\x040A\x040B\x040C\x040E\x040F\x0410\x0411\x0412\x0413\x0414\x0415\x0416\x0417\x0418\x0419"
|
||||
U"\x041A\x041B\x041C\x041D\x041E\x041F\x0420\x0421\x0422\x0423\x0424\x0425\x0426\x0427\x0428"
|
||||
U"\x0429\x042A\x042B\x042C\x042D\x042E\x042F\x0460\x0462\x0464\x0466\x0468\x046A\x046C\x046E"
|
||||
U"\x0470\x0472\x0474\x0476\x0478\x047A\x047C\x047E\x0480\x0490\x0492\x0494\x0496\x0498\x049A"
|
||||
U"\x049C\x049E\x04A0\x04A2\x04A4\x04A6\x04A8\x04AA\x04AC\x04AE\x04B0\x04B2\x04B4\x04B6\x04B8"
|
||||
U"\x04BA\x04BC\x04BE\x04C1\x04C3\x04C7\x04CB\x04D0\x04D2\x04D4\x04D6\x04D8\x04DA\x04DC\x04DE"
|
||||
U"\x04E0\x04E2\x04E4\x04E6\x04E8\x04EA\x04EE\x04F0\x04F2\x04F4\x04F8\x1EA0\x1EA2\x1EA4\x1EA6"
|
||||
U"\x1EA8\x1EAA\x1EAC\x1EAE\x1EB0\x1EB2\x1EB4\x1EB6\x1EB8\x1EBA\x1EBC\x1EBE\x1EC0\x1EC2\x1EC4"
|
||||
U"\x1EC6\x1EC8\x1ECA\x1ECC\x1ECE\x1ED0\x1ED2\x1ED4\x1ED6\x1ED8\x1EDA\x1EDC\x1EDE\x1EE0\x1EE2"
|
||||
U"\x1EE4\x1EE6\x1EE8\x1EEA\x1EEC\x1EEE\x1EF0\x1EF2\x1EF4\x1EF6\x1EF8\x1F08\x1F09\x1F0A\x1F0B"
|
||||
U"\x1F0C\x1F0D\x1F0E\x1F0F\x1F18\x1F19\x1F1A\x1F1B\x1F1C\x1F1D\x1F28\x1F29\x1F2A\x1F2B\x1F2C"
|
||||
U"\x1F2D\x1F2E\x1F2F\x1F38\x1F39\x1F3A\x1F3B\x1F3C\x1F3D\x1F3E\x1F3F\x1F48\x1F49\x1F4A\x1F4B"
|
||||
U"\x1F4C\x1F4D\x1F59\x1F5B\x1F5D\x1F5F\x1F68\x1F69\x1F6A\x1F6B\x1F6C\x1F6D\x1F6E\x1F6F\x1F88"
|
||||
U"\x1F89\x1F8A\x1F8B\x1F8C\x1F8D\x1F8E\x1F8F\x1F98\x1F99\x1F9A\x1F9B\x1F9C\x1F9D\x1F9E\x1F9F"
|
||||
U"\x1FA8\x1FA9\x1FAA\x1FAB\x1FAC\x1FAD\x1FAE\x1FAF\x1FB8\x1FB9\x1FD8\x1FD9\x1FE8\x1FE9";
|
||||
static const char32_t to[] =
|
||||
U"\x00F8\x00F9\x00FA\x00FB\x00FC\x00FD\x00FE\x013A\x013C\x013E\x0140\x0142\x0144\x0146\x0148"
|
||||
U"\x014B\x014D\x014F\x0151\x0153\x0155\x0157\x0159\x015B\x015D\x015F\x0161\x0163\x0165\x0167"
|
||||
U"\x0169\x016B\x016D\x016F\x0171\x0173\x0175\x0177\x00FF\x017A\x017C\x017E\x0253\x0183\x0185"
|
||||
U"\x0254\x0188\x0257\x018C\x0258\x0259\x025B\x0192\x0260\x0263\x0269\x0268\x0199\x026f\x0272"
|
||||
U"\x0275\x01A1\x01A3\x01A5\x01A8\x0283\x01AD\x0288\x01B0\x028A\x028B\x01B4\x01B6\x0292\x01B9"
|
||||
U"\x01BD\x01C6\x01C6\x01C9\x01C9\x01CC\x01CC\x01CE\x01D0\x01D2\x01D4\x01D6\x01D8\x01DA\x01DC"
|
||||
U"\x01DF\x01E1\x01E3\x01E5\x01E7\x01E9\x01EB\x01ED\x01EF\x01F3\x01F5\x01FB\x01FD\x01FF\x0201"
|
||||
U"\x0203\x0205\x0207\x0209\x020B\x020D\x020F\x0211\x0213\x0215\x0217\x03AC\x03AD\x03AE\x03AF"
|
||||
U"\x03CC\x03CD\x03CE\x03B1\x03B2\x03B3\x03B4\x03B5\x03B6\x03B7\x03B8\x03B9\x03BA\x03BB\x03BC"
|
||||
U"\x03BD\x03BE\x03BF\x03C0\x03C1\x03C3\x03C4\x03C5\x03C6\x03C7\x03C8\x03C9\x03CA\x03CB\x03E3"
|
||||
U"\x03E5\x03E7\x03E9\x03EB\x03ED\x03EF\x0451\x0452\x0453\x0454\x0455\x0456\x0457\x0458\x0459"
|
||||
U"\x045A\x045B\x045C\x045E\x045F\x0430\x0431\x0432\x0433\x0434\x0435\x0436\x0437\x0438\x0439"
|
||||
U"\x043A\x043B\x043C\x043D\x043E\x043F\x0440\x0441\x0442\x0443\x0444\x0445\x0446\x0447\x0448"
|
||||
U"\x0449\x044A\x044B\x044C\x044D\x044E\x044F\x0461\x0463\x0465\x0467\x0469\x046B\x046D\x046F"
|
||||
U"\x0471\x0473\x0475\x0477\x0479\x047B\x047D\x047F\x0481\x0491\x0493\x0495\x0497\x0499\x049B"
|
||||
U"\x049D\x049F\x04A1\x04A3\x04A5\x04A7\x04A9\x04AB\x04AD\x04AF\x04B1\x04B3\x04B5\x04B7\x04B9"
|
||||
U"\x04BB\x04BD\x04BF\x04C2\x04C4\x04C8\x04CC\x04D1\x04D3\x04D5\x04D7\x04D9\x04DB\x04DD\x04DF"
|
||||
U"\x04E1\x04E3\x04E5\x04E7\x04E9\x04EB\x04EF\x04F1\x04F3\x04F5\x04F9\x1EA1\x1EA3\x1EA5\x1EA7"
|
||||
U"\x1EA9\x1EAB\x1EAD\x1EAF\x1EB1\x1EB3\x1EB5\x1EB7\x1EB9\x1EBB\x1EBD\x1EBF\x1EC1\x1EC3\x1EC5"
|
||||
U"\x1EC7\x1EC9\x1ECB\x1ECD\x1ECF\x1ED1\x1ED3\x1ED5\x1ED7\x1ED9\x1EDB\x1EDD\x1EDF\x1EE1\x1EE3"
|
||||
U"\x1EE5\x1EE7\x1EE9\x1EEB\x1EED\x1EEF\x1EF1\x1EF3\x1EF5\x1EF7\x1EF9\x1F00\x1F01\x1F02\x1F03"
|
||||
U"\x1F04\x1F05\x1F06\x1F07\x1F10\x1F11\x1F12\x1F13\x1F14\x1F15\x1F20\x1F21\x1F22\x1F23\x1F24"
|
||||
U"\x1F25\x1F26\x1F27\x1F30\x1F31\x1F32\x1F33\x1F34\x1F35\x1F36\x1F37\x1F40\x1F41\x1F42\x1F43"
|
||||
U"\x1F44\x1F45\x1F51\x1F53\x1F55\x1F57\x1F60\x1F61\x1F62\x1F63\x1F64\x1F65\x1F66\x1F67\x1F80"
|
||||
U"\x1F81\x1F82\x1F83\x1F84\x1F85\x1F86\x1F87\x1F90\x1F91\x1F92\x1F93\x1F94\x1F95\x1F96\x1F97"
|
||||
U"\x1FA0\x1FA1\x1FA2\x1FA3\x1FA4\x1FA5\x1FA6\x1FA7\x1FB0\x1FB1\x1FD0\x1FD1\x1FE0\x1FE1";
|
||||
|
||||
if (wc >= from[0] && wc <= from[ARRAY_SIZE(from) - 2]) {
|
||||
/* Binary search since these are sorted. */
|
||||
int min = 0;
|
||||
int max = ARRAY_SIZE(from) - 2;
|
||||
while (max >= min) {
|
||||
const int mid = (min + max) / 2;
|
||||
if (wc > from[mid]) {
|
||||
min = mid + 1;
|
||||
}
|
||||
else if (wc < from[mid]) {
|
||||
max = mid - 1;
|
||||
}
|
||||
else {
|
||||
return to[mid];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/* copied from glib's gutf8.c, added 'Err' arg */
|
||||
|
|
|
@ -25,35 +25,35 @@ enum {
|
|||
* Arbitrary allocated memory
|
||||
* (typically owned by #ID's, will be freed when there are no users).
|
||||
*/
|
||||
DATA = BLEND_MAKE_ID('D', 'A', 'T', 'A'),
|
||||
BLO_CODE_DATA = BLEND_MAKE_ID('D', 'A', 'T', 'A'),
|
||||
/**
|
||||
* Used for #Global struct.
|
||||
*/
|
||||
GLOB = BLEND_MAKE_ID('G', 'L', 'O', 'B'),
|
||||
BLO_CODE_GLOB = BLEND_MAKE_ID('G', 'L', 'O', 'B'),
|
||||
/**
|
||||
* Used for storing the encoded SDNA string
|
||||
* (decoded into an #SDNA on load).
|
||||
*/
|
||||
DNA1 = BLEND_MAKE_ID('D', 'N', 'A', '1'),
|
||||
BLO_CODE_DNA1 = BLEND_MAKE_ID('D', 'N', 'A', '1'),
|
||||
/**
|
||||
* Used to store thumbnail previews, written between #REND and #GLOB blocks,
|
||||
* (ignored for regular file reading).
|
||||
*/
|
||||
TEST = BLEND_MAKE_ID('T', 'E', 'S', 'T'),
|
||||
BLO_CODE_TEST = BLEND_MAKE_ID('T', 'E', 'S', 'T'),
|
||||
/**
|
||||
* Used for #RenderInfo, basic Scene and frame range info,
|
||||
* can be easily read by other applications without writing a full blend file parser.
|
||||
*/
|
||||
REND = BLEND_MAKE_ID('R', 'E', 'N', 'D'),
|
||||
BLO_CODE_REND = BLEND_MAKE_ID('R', 'E', 'N', 'D'),
|
||||
/**
|
||||
* Used for #UserDef, (user-preferences data).
|
||||
* (written to #BLENDER_STARTUP_FILE & #BLENDER_USERPREF_FILE).
|
||||
*/
|
||||
USER = BLEND_MAKE_ID('U', 'S', 'E', 'R'),
|
||||
BLO_CODE_USER = BLEND_MAKE_ID('U', 'S', 'E', 'R'),
|
||||
/**
|
||||
* Terminate reading (no data).
|
||||
*/
|
||||
ENDB = BLEND_MAKE_ID('E', 'N', 'D', 'B'),
|
||||
BLO_CODE_ENDB = BLEND_MAKE_ID('E', 'N', 'D', 'B'),
|
||||
};
|
||||
|
||||
#define BLEN_THUMB_MEMSIZE_FILE(_x, _y) (sizeof(int) * (2 + (size_t)(_x) * (size_t)(_y)))
|
||||
|
|
|
@ -89,7 +89,7 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
|
|||
|
||||
fprintf(static_cast<FILE *>(fp), "[\n");
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (bhead->code == ENDB) {
|
||||
if (bhead->code == BLO_CODE_ENDB) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh,
|
|||
BLI_linklist_prepend(&names, BLI_strdup(idname + 2));
|
||||
tot++;
|
||||
}
|
||||
else if (bhead->code == ENDB) {
|
||||
else if (bhead->code == BLO_CODE_ENDB) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
|
|||
const int sdna_nr_preview_image = DNA_struct_find_nr(fd->filesdna, "PreviewImage");
|
||||
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (bhead->code == ENDB) {
|
||||
if (bhead->code == BLO_CODE_ENDB) {
|
||||
break;
|
||||
}
|
||||
if (bhead->code == ofblocktype) {
|
||||
|
@ -190,7 +190,7 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
|
|||
|
||||
bool has_preview = false;
|
||||
/* See if we can find a preview in the data of this ID. */
|
||||
for (BHead *data_bhead = blo_bhead_next(fd, id_bhead); data_bhead->code == DATA;
|
||||
for (BHead *data_bhead = blo_bhead_next(fd, id_bhead); data_bhead->code == BLO_CODE_DATA;
|
||||
data_bhead = blo_bhead_next(fd, data_bhead)) {
|
||||
if (data_bhead->SDNAnr == sdna_nr_preview_image) {
|
||||
has_preview = true;
|
||||
|
@ -260,7 +260,7 @@ PreviewImage *BLO_blendhandle_get_preview_for_id(BlendHandle *bh,
|
|||
const int sdna_preview_image = DNA_struct_find_nr(fd->filesdna, "PreviewImage");
|
||||
|
||||
for (BHead *bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (bhead->code == DATA) {
|
||||
if (bhead->code == BLO_CODE_DATA) {
|
||||
if (looking && bhead->SDNAnr == sdna_preview_image) {
|
||||
PreviewImage *preview_from_file = static_cast<PreviewImage *>(
|
||||
BLO_library_read_struct(fd, bhead, "PreviewImage"));
|
||||
|
@ -275,7 +275,7 @@ PreviewImage *BLO_blendhandle_get_preview_for_id(BlendHandle *bh,
|
|||
return result;
|
||||
}
|
||||
}
|
||||
else if (looking || bhead->code == ENDB) {
|
||||
else if (looking || bhead->code == BLO_CODE_ENDB) {
|
||||
/* We were looking for a preview image, but didn't find any belonging to block. So it doesn't
|
||||
* exist. */
|
||||
break;
|
||||
|
@ -324,7 +324,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (bhead->code == DATA) {
|
||||
else if (bhead->code == BLO_CODE_DATA) {
|
||||
if (looking) {
|
||||
if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage")) {
|
||||
prv = static_cast<PreviewImage *>(BLO_library_read_struct(fd, bhead, "PreviewImage"));
|
||||
|
@ -337,7 +337,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (bhead->code == ENDB) {
|
||||
else if (bhead->code == BLO_CODE_ENDB) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
|
@ -359,7 +359,7 @@ LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
|
|||
BHead *bhead;
|
||||
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (bhead->code == ENDB) {
|
||||
if (bhead->code == BLO_CODE_ENDB) {
|
||||
break;
|
||||
}
|
||||
if (BKE_idtype_idcode_is_valid(bhead->code)) {
|
||||
|
|
|
@ -199,7 +199,7 @@ struct BHeadN {
|
|||
* We could change this in the future, for now it's simplest if only data is delayed
|
||||
* because ID names are used in lookup tables.
|
||||
*/
|
||||
#define BHEAD_USE_READ_ON_DEMAND(bhead) ((bhead)->code == DATA)
|
||||
#define BHEAD_USE_READ_ON_DEMAND(bhead) ((bhead)->code == BLO_CODE_DATA)
|
||||
|
||||
void BLO_reportf_wrap(BlendFileReadReport *reports, eReportType type, const char *format, ...)
|
||||
{
|
||||
|
@ -423,7 +423,7 @@ static void read_file_version(FileData *fd, Main *main)
|
|||
BHead *bhead;
|
||||
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (bhead->code == GLOB) {
|
||||
if (bhead->code == BLO_CODE_GLOB) {
|
||||
FileGlobal *fg = static_cast<FileGlobal *>(read_struct(fd, bhead, "Global"));
|
||||
if (fg) {
|
||||
main->subversionfile = fg->subversion;
|
||||
|
@ -431,7 +431,7 @@ static void read_file_version(FileData *fd, Main *main)
|
|||
main->minsubversionfile = fg->minsubversion;
|
||||
MEM_freeN(fg);
|
||||
}
|
||||
else if (bhead->code == ENDB) {
|
||||
else if (bhead->code == BLO_CODE_ENDB) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ static void read_file_bhead_idname_map_create(FileData *fd)
|
|||
|
||||
/* dummy values */
|
||||
bool is_link = false;
|
||||
int code_prev = ENDB;
|
||||
int code_prev = BLO_CODE_ENDB;
|
||||
uint reserve = 0;
|
||||
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
|
@ -595,7 +595,7 @@ static void switch_endian_bh4(BHead4 *bhead)
|
|||
bhead->code >>= 16;
|
||||
}
|
||||
|
||||
if (bhead->code != ENDB) {
|
||||
if (bhead->code != BLO_CODE_ENDB) {
|
||||
BLI_endian_switch_int32(&bhead->len);
|
||||
BLI_endian_switch_int32(&bhead->SDNAnr);
|
||||
BLI_endian_switch_int32(&bhead->nr);
|
||||
|
@ -609,7 +609,7 @@ static void switch_endian_bh8(BHead8 *bhead)
|
|||
bhead->code >>= 16;
|
||||
}
|
||||
|
||||
if (bhead->code != ENDB) {
|
||||
if (bhead->code != BLO_CODE_ENDB) {
|
||||
BLI_endian_switch_int32(&bhead->len);
|
||||
BLI_endian_switch_int32(&bhead->SDNAnr);
|
||||
BLI_endian_switch_int32(&bhead->nr);
|
||||
|
@ -624,7 +624,7 @@ static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, bool do_endian_swap)
|
|||
bhead4->code = bhead8->code;
|
||||
bhead4->len = bhead8->len;
|
||||
|
||||
if (bhead4->code != ENDB) {
|
||||
if (bhead4->code != BLO_CODE_ENDB) {
|
||||
/* perform a endian swap on 64bit pointers, otherwise the pointer might map to zero
|
||||
* 0x0000000000000000000012345678 would become 0x12345678000000000000000000000000
|
||||
*/
|
||||
|
@ -649,7 +649,7 @@ static void bh8_from_bh4(BHead *bhead, BHead4 *bhead4)
|
|||
bhead8->code = bhead4->code;
|
||||
bhead8->len = bhead4->len;
|
||||
|
||||
if (bhead8->code != ENDB) {
|
||||
if (bhead8->code != BLO_CODE_ENDB) {
|
||||
bhead8->old = bhead4->old;
|
||||
bhead8->SDNAnr = bhead4->SDNAnr;
|
||||
bhead8->nr = bhead4->nr;
|
||||
|
@ -677,10 +677,10 @@ static BHeadN *get_bhead(FileData *fd)
|
|||
* needs some special handling. We don't want to EOF just yet.
|
||||
*/
|
||||
if (fd->flags & FD_FLAGS_FILE_POINTSIZE_IS_4) {
|
||||
bhead4.code = DATA;
|
||||
bhead4.code = BLO_CODE_DATA;
|
||||
readsize = fd->file->read(fd->file, &bhead4, sizeof(bhead4));
|
||||
|
||||
if (readsize == sizeof(bhead4) || bhead4.code == ENDB) {
|
||||
if (readsize == sizeof(bhead4) || bhead4.code == BLO_CODE_ENDB) {
|
||||
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
||||
switch_endian_bh4(&bhead4);
|
||||
}
|
||||
|
@ -700,10 +700,10 @@ static BHeadN *get_bhead(FileData *fd)
|
|||
}
|
||||
}
|
||||
else {
|
||||
bhead8.code = DATA;
|
||||
bhead8.code = BLO_CODE_DATA;
|
||||
readsize = fd->file->read(fd->file, &bhead8, sizeof(bhead8));
|
||||
|
||||
if (readsize == sizeof(bhead8) || bhead8.code == ENDB) {
|
||||
if (readsize == sizeof(bhead8) || bhead8.code == BLO_CODE_ENDB) {
|
||||
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
||||
switch_endian_bh8(&bhead8);
|
||||
}
|
||||
|
@ -957,7 +957,7 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
|
|||
int subversion = 0;
|
||||
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (bhead->code == GLOB) {
|
||||
if (bhead->code == BLO_CODE_GLOB) {
|
||||
/* Before this, the subversion didn't exist in 'FileGlobal' so the subversion
|
||||
* value isn't accessible for the purpose of DNA versioning in this case. */
|
||||
if (fd->fileversion <= 242) {
|
||||
|
@ -972,7 +972,7 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
|
|||
num[4] = 0;
|
||||
subversion = atoi(num);
|
||||
}
|
||||
else if (bhead->code == DNA1) {
|
||||
else if (bhead->code == BLO_CODE_DNA1) {
|
||||
const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
|
||||
|
||||
fd->filesdna = DNA_sdna_from_data(
|
||||
|
@ -993,7 +993,7 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
|
|||
|
||||
return false;
|
||||
}
|
||||
else if (bhead->code == ENDB) {
|
||||
else if (bhead->code == BLO_CODE_ENDB) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1008,7 +1008,7 @@ static int *read_file_thumbnail(FileData *fd)
|
|||
int *blend_thumb = nullptr;
|
||||
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (bhead->code == TEST) {
|
||||
if (bhead->code == BLO_CODE_TEST) {
|
||||
const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
|
||||
int *data = (int *)(bhead + 1);
|
||||
|
||||
|
@ -1033,7 +1033,7 @@ static int *read_file_thumbnail(FileData *fd)
|
|||
blend_thumb = data;
|
||||
break;
|
||||
}
|
||||
if (bhead->code != REND) {
|
||||
if (bhead->code != BLO_CODE_REND) {
|
||||
/* Thumbnail is stored in TEST immediately after first REND... */
|
||||
break;
|
||||
}
|
||||
|
@ -2952,7 +2952,7 @@ static BHead *read_data_into_datamap(FileData *fd, BHead *bhead, const char *all
|
|||
{
|
||||
bhead = blo_bhead_next(fd, bhead);
|
||||
|
||||
while (bhead && bhead->code == DATA) {
|
||||
while (bhead && bhead->code == BLO_CODE_DATA) {
|
||||
/* The code below is useful for debugging leaks in data read from the blend file.
|
||||
* Without this the messages only tell us what ID-type the memory came from,
|
||||
* eg: `Data from OB len 64`, see #dataname.
|
||||
|
@ -2995,7 +2995,7 @@ static bool read_libblock_is_identical(FileData *fd, BHead *bhead)
|
|||
/* Test any other data that is part of ID (logic must match read_data_into_datamap). */
|
||||
bhead = blo_bhead_next(fd, bhead);
|
||||
|
||||
while (bhead && bhead->code == DATA) {
|
||||
while (bhead && bhead->code == BLO_CODE_DATA) {
|
||||
if (bhead->len && !BHEADN_FROM_BHEAD(bhead)->is_memchunk_identical) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3837,16 +3837,16 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
|
||||
while (bhead) {
|
||||
switch (bhead->code) {
|
||||
case DATA:
|
||||
case DNA1:
|
||||
case TEST: /* used as preview since 2.5x */
|
||||
case REND:
|
||||
case BLO_CODE_DATA:
|
||||
case BLO_CODE_DNA1:
|
||||
case BLO_CODE_TEST: /* used as preview since 2.5x */
|
||||
case BLO_CODE_REND:
|
||||
bhead = blo_bhead_next(fd, bhead);
|
||||
break;
|
||||
case GLOB:
|
||||
case BLO_CODE_GLOB:
|
||||
bhead = read_global(bfd, fd, bhead);
|
||||
break;
|
||||
case USER:
|
||||
case BLO_CODE_USER:
|
||||
if (fd->skip_flags & BLO_READ_SKIP_USERDEF) {
|
||||
bhead = blo_bhead_next(fd, bhead);
|
||||
}
|
||||
|
@ -3854,7 +3854,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
bhead = read_userdef(bfd, fd, bhead);
|
||||
}
|
||||
break;
|
||||
case ENDB:
|
||||
case BLO_CODE_ENDB:
|
||||
bhead = nullptr;
|
||||
break;
|
||||
|
||||
|
|
|
@ -841,7 +841,7 @@ static void write_renderinfo(WriteData *wd, Main *mainvar)
|
|||
|
||||
BLI_strncpy(data.scene_name, sce->id.name + 2, sizeof(data.scene_name));
|
||||
|
||||
writedata(wd, REND, sizeof(data), &data);
|
||||
writedata(wd, BLO_CODE_REND, sizeof(data), &data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -856,7 +856,7 @@ static void write_keymapitem(BlendWriter *writer, const wmKeyMapItem *kmi)
|
|||
|
||||
static void write_userdef(BlendWriter *writer, const UserDef *userdef)
|
||||
{
|
||||
writestruct(writer->wd, USER, UserDef, 1, userdef);
|
||||
writestruct(writer->wd, BLO_CODE_USER, UserDef, 1, userdef);
|
||||
|
||||
LISTBASE_FOREACH (const bTheme *, btheme, &userdef->themes) {
|
||||
BLO_write_struct(writer, bTheme, btheme);
|
||||
|
@ -1063,7 +1063,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
|
|||
fg.build_commit_timestamp = 0;
|
||||
BLI_strncpy(fg.build_hash, "unknown", sizeof(fg.build_hash));
|
||||
#endif
|
||||
writestruct(wd, GLOB, FileGlobal, 1, &fg);
|
||||
writestruct(wd, BLO_CODE_GLOB, FileGlobal, 1, &fg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1074,7 +1074,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
|
|||
static void write_thumb(WriteData *wd, const BlendThumbnail *thumb)
|
||||
{
|
||||
if (thumb) {
|
||||
writedata(wd, TEST, BLEN_THUMB_MEMSIZE_FILE(thumb->width, thumb->height), thumb);
|
||||
writedata(wd, BLO_CODE_TEST, BLEN_THUMB_MEMSIZE_FILE(thumb->width, thumb->height), thumb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1332,11 +1332,11 @@ static bool write_file_handle(Main *mainvar,
|
|||
*
|
||||
* Note that we *borrow* the pointer to 'DNAstr',
|
||||
* so writing each time uses the same address and doesn't cause unnecessary undo overhead. */
|
||||
writedata(wd, DNA1, size_t(wd->sdna->data_len), wd->sdna->data);
|
||||
writedata(wd, BLO_CODE_DNA1, size_t(wd->sdna->data_len), wd->sdna->data);
|
||||
|
||||
/* end of file */
|
||||
memset(&bhead, 0, sizeof(BHead));
|
||||
bhead.code = ENDB;
|
||||
bhead.code = BLO_CODE_ENDB;
|
||||
mywrite(wd, &bhead, sizeof(BHead));
|
||||
|
||||
blo_join_main(&mainlist);
|
||||
|
@ -1569,7 +1569,7 @@ bool BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int w
|
|||
|
||||
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr)
|
||||
{
|
||||
writedata(writer->wd, DATA, size_in_bytes, data_ptr);
|
||||
writedata(writer->wd, BLO_CODE_DATA, size_in_bytes, data_ptr);
|
||||
}
|
||||
|
||||
void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr)
|
||||
|
@ -1592,7 +1592,7 @@ void BLO_write_struct_array_by_name(BlendWriter *writer,
|
|||
|
||||
void BLO_write_struct_by_id(BlendWriter *writer, int struct_id, const void *data_ptr)
|
||||
{
|
||||
writestruct_nr(writer->wd, DATA, struct_id, 1, data_ptr);
|
||||
writestruct_nr(writer->wd, BLO_CODE_DATA, struct_id, 1, data_ptr);
|
||||
}
|
||||
|
||||
void BLO_write_struct_at_address_by_id(BlendWriter *writer,
|
||||
|
@ -1600,7 +1600,8 @@ void BLO_write_struct_at_address_by_id(BlendWriter *writer,
|
|||
const void *address,
|
||||
const void *data_ptr)
|
||||
{
|
||||
BLO_write_struct_at_address_by_id_with_filecode(writer, DATA, struct_id, address, data_ptr);
|
||||
BLO_write_struct_at_address_by_id_with_filecode(
|
||||
writer, BLO_CODE_DATA, struct_id, address, data_ptr);
|
||||
}
|
||||
|
||||
void BLO_write_struct_at_address_by_id_with_filecode(
|
||||
|
@ -1614,18 +1615,18 @@ void BLO_write_struct_array_by_id(BlendWriter *writer,
|
|||
int array_size,
|
||||
const void *data_ptr)
|
||||
{
|
||||
writestruct_nr(writer->wd, DATA, struct_id, array_size, data_ptr);
|
||||
writestruct_nr(writer->wd, BLO_CODE_DATA, struct_id, array_size, data_ptr);
|
||||
}
|
||||
|
||||
void BLO_write_struct_array_at_address_by_id(
|
||||
BlendWriter *writer, int struct_id, int array_size, const void *address, const void *data_ptr)
|
||||
{
|
||||
writestruct_at_address_nr(writer->wd, DATA, struct_id, array_size, address, data_ptr);
|
||||
writestruct_at_address_nr(writer->wd, BLO_CODE_DATA, struct_id, array_size, address, data_ptr);
|
||||
}
|
||||
|
||||
void BLO_write_struct_list_by_id(BlendWriter *writer, int struct_id, ListBase *list)
|
||||
{
|
||||
writelist_nr(writer->wd, DATA, struct_id, list);
|
||||
writelist_nr(writer->wd, BLO_CODE_DATA, struct_id, list);
|
||||
}
|
||||
|
||||
void BLO_write_struct_list_by_name(BlendWriter *writer, const char *struct_name, ListBase *list)
|
||||
|
|
|
@ -167,7 +167,7 @@ OperationNode *ComponentNode::add_operation(const DepsEvalOperationCb &op,
|
|||
op_node = (OperationNode *)factory->create_node(this->owner->id_orig, "", name);
|
||||
|
||||
/* register opnode in this component's operation set */
|
||||
OperationIDKey key(opcode, name, name_tag);
|
||||
OperationIDKey key(opcode, op_node->name.c_str(), name_tag);
|
||||
operations_map->add(key, op_node);
|
||||
|
||||
/* Set back-link. */
|
||||
|
|
|
@ -155,7 +155,7 @@ ComponentNode *IDNode::add_component(NodeType type, const char *name)
|
|||
comp_node = (ComponentNode *)factory->create_node(this->id_orig, "", name);
|
||||
|
||||
/* Register. */
|
||||
ComponentIDKey key(type, name);
|
||||
ComponentIDKey key(type, comp_node->name.c_str());
|
||||
components.add_new(key, comp_node);
|
||||
comp_node->owner = this;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "BKE_report.h"
|
||||
#include "BKE_vfont.h"
|
||||
|
||||
#include "BLI_string_utf8.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
@ -1972,33 +1974,16 @@ static const EnumPropertyItem case_items[] = {
|
|||
static int set_case(bContext *C, int ccase)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
char32_t *str;
|
||||
int len;
|
||||
int selstart, selend;
|
||||
|
||||
if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
|
||||
len = (selend - selstart) + 1;
|
||||
str = &ef->textbuf[selstart];
|
||||
while (len) {
|
||||
if (*str >= 'a' && *str <= 'z') {
|
||||
*str -= 32;
|
||||
}
|
||||
len--;
|
||||
str++;
|
||||
}
|
||||
Curve *cu = (Curve *)obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
char32_t *str = &ef->textbuf[selstart];
|
||||
|
||||
if (ccase == CASE_LOWER) {
|
||||
len = (selend - selstart) + 1;
|
||||
str = &ef->textbuf[selstart];
|
||||
while (len) {
|
||||
if (*str >= 'A' && *str <= 'Z') {
|
||||
*str += 32;
|
||||
}
|
||||
len--;
|
||||
str++;
|
||||
}
|
||||
for (int len = (selend - selstart) + 1; len; len--, str++) {
|
||||
*str = (ccase == CASE_LOWER) ? BLI_str_utf32_char_to_lower(*str) :
|
||||
BLI_str_utf32_char_to_upper(*str);
|
||||
}
|
||||
|
||||
text_update_edited(C, obedit, FO_EDIT);
|
||||
|
|
|
@ -99,8 +99,14 @@ void MTLFrameBuffer::bind(bool enabled_srgb)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Ensure local MTLAttachment data is up to date. */
|
||||
this->update_attachments(true);
|
||||
/* Ensure local MTLAttachment data is up to date.
|
||||
* NOTE: We only refresh viewport/scissor region when attachments are updated during bind.
|
||||
* This is to ensure state is consistent with the OpenGL backend. */
|
||||
if (dirty_attachments_) {
|
||||
this->update_attachments(true);
|
||||
this->viewport_reset();
|
||||
this->scissor_reset();
|
||||
}
|
||||
|
||||
/* Ensure SRGB state is up-to-date and valid. */
|
||||
bool srgb_state_changed = enabled_srgb_ != enabled_srgb;
|
||||
|
@ -465,6 +471,11 @@ void MTLFrameBuffer::read(eGPUFrameBufferBits planes,
|
|||
BLI_assert(area[2] > 0);
|
||||
BLI_assert(area[3] > 0);
|
||||
|
||||
/* Early exit if requested read region area is zero. */
|
||||
if (area[2] <= 0 || area[3] <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (planes) {
|
||||
case GPU_DEPTH_BIT: {
|
||||
if (this->has_depth_attachment()) {
|
||||
|
@ -742,10 +753,6 @@ void MTLFrameBuffer::update_attachments(bool update_viewport)
|
|||
height_ = 0;
|
||||
}
|
||||
|
||||
/* Reset viewport and Scissor. */
|
||||
this->viewport_reset();
|
||||
this->scissor_reset();
|
||||
|
||||
/* We have now updated our internal structures. */
|
||||
dirty_attachments_ = false;
|
||||
}
|
||||
|
@ -760,15 +767,18 @@ void MTLFrameBuffer::apply_state()
|
|||
}
|
||||
|
||||
/* Ensure viewport has been set. NOTE: This should no longer happen, but kept for safety to
|
||||
* track bugs. */
|
||||
if (viewport_[2] == 0 || viewport_[3] == 0) {
|
||||
* track bugs. If viewport size is zero, use framebuffer size. */
|
||||
int viewport_w = viewport_[2];
|
||||
int viewport_h = viewport_[3];
|
||||
if (viewport_w == 0 || viewport_h == 0) {
|
||||
MTL_LOG_WARNING(
|
||||
"Viewport had width and height of (0,0) -- Updating -- DEBUG Safety check\n");
|
||||
viewport_reset();
|
||||
viewport_w = width_;
|
||||
viewport_h = height_;
|
||||
}
|
||||
|
||||
/* Update Context State. */
|
||||
mtl_ctx->set_viewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]);
|
||||
mtl_ctx->set_viewport(viewport_[0], viewport_[1], viewport_w, viewport_h);
|
||||
mtl_ctx->set_scissor(scissor_[0], scissor_[1], scissor_[2], scissor_[3]);
|
||||
mtl_ctx->set_scissor_enabled(scissor_test_);
|
||||
|
||||
|
@ -895,8 +905,6 @@ bool MTLFrameBuffer::add_color_attachment(gpu::MTLTexture *texture,
|
|||
|
||||
if (width_ == 0 || height_ == 0) {
|
||||
this->size_set(width_of_miplayer, height_of_miplayer);
|
||||
this->scissor_reset();
|
||||
this->viewport_reset();
|
||||
BLI_assert(width_ > 0);
|
||||
BLI_assert(height_ > 0);
|
||||
}
|
||||
|
@ -1017,8 +1025,6 @@ bool MTLFrameBuffer::add_depth_attachment(gpu::MTLTexture *texture, int miplevel
|
|||
/* Update Frame-buffer Resolution. */
|
||||
if (width_ == 0 || height_ == 0) {
|
||||
this->size_set(width_of_miplayer, height_of_miplayer);
|
||||
this->scissor_reset();
|
||||
this->viewport_reset();
|
||||
BLI_assert(width_ > 0);
|
||||
BLI_assert(height_ > 0);
|
||||
}
|
||||
|
@ -1139,8 +1145,6 @@ bool MTLFrameBuffer::add_stencil_attachment(gpu::MTLTexture *texture, int miplev
|
|||
/* Update Frame-buffer Resolution. */
|
||||
if (width_ == 0 || height_ == 0) {
|
||||
this->size_set(width_of_miplayer, height_of_miplayer);
|
||||
this->scissor_reset();
|
||||
this->viewport_reset();
|
||||
BLI_assert(width_ > 0);
|
||||
BLI_assert(height_ > 0);
|
||||
}
|
||||
|
@ -1225,10 +1229,8 @@ void MTLFrameBuffer::ensure_render_target_size()
|
|||
if (colour_attachment_count_ == 0 && !this->has_depth_attachment() &&
|
||||
!this->has_stencil_attachment()) {
|
||||
|
||||
/* Reset Viewport and Scissor for NULL framebuffer. */
|
||||
/* Reset size for empty framebuffer. */
|
||||
this->size_set(0, 0);
|
||||
this->scissor_reset();
|
||||
this->viewport_reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue