Animation: Add "Frame Channel" operators #104523

Merged
Christoph Lendenfeld merged 27 commits from ChrisLend/blender:frame-channel-operator into main 2023-02-17 18:11:10 +01:00
196 changed files with 2363 additions and 1183 deletions
Showing only changes of commit e7bb249039 - Show all commits

View File

@ -1427,6 +1427,9 @@ if(CMAKE_COMPILER_IS_GNUCC)
add_check_c_compiler_flag(C_WARNINGS C_WARN_TYPE_LIMITS -Wtype-limits)
add_check_c_compiler_flag(C_WARNINGS C_WARN_FORMAT_SIGN -Wformat-signedness)
add_check_c_compiler_flag(C_WARNINGS C_WARN_RESTRICT -Wrestrict)
# Useful but too many false positives and inconvenient to suppress each occurrence.
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_STRINGOP_OVERREAD -Wno-stringop-overread)
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_STRINGOP_OVERFLOW -Wno-stringop-overflow)
# C-only.
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_NULL -Wnonnull)
@ -1466,6 +1469,9 @@ if(CMAKE_COMPILER_IS_GNUCC)
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_RESTRICT -Wrestrict)
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
# Useful but too many false positives and inconvenient to suppress each occurrence.
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_STRINGOP_OVERREAD -Wno-stringop-overread)
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_STRINGOP_OVERFLOW -Wno-stringop-overflow)
# causes too many warnings
if(NOT APPLE)

View File

@ -513,17 +513,19 @@ if(WITH_FFTW)
src/fx/Convolver.cpp
src/fx/ConvolverReader.cpp
src/fx/ConvolverSound.cpp
src/fx/Equalizer.cpp
src/fx/FFTConvolver.cpp
src/fx/HRTF.cpp
src/fx/ImpulseResponse.cpp
src/util/FFTPlan.cpp
)
set(FFTW_HDR
include/fx/BinauralSound.h
include/fx/BinauralSound.h
include/fx/BinauralReader.h
include/fx/Convolver.h
include/fx/ConvolverReader.h
include/fx/ConvolverSound.h
include/fx/Equalizer.h
include/fx/FFTConvolver.h
include/fx/HRTF.h
include/fx/HRTFLoader.h

View File

@ -54,6 +54,7 @@
#ifdef WITH_CONVOLUTION
#include "fx/BinauralSound.h"
#include "fx/ConvolverSound.h"
#include "fx/Equalizer.h"
#endif
#include <cassert>
@ -768,4 +769,14 @@ AUD_API AUD_Sound* AUD_Sound_Binaural(AUD_Sound* sound, AUD_HRTF* hrtfs, AUD_Sou
}
}
AUD_API AUD_Sound* AUD_Sound_equalize(AUD_Sound* sound, float *definition, int size, float maxFreqEq, int sizeConversion)
{
assert(sound);
std::shared_ptr<Buffer> buf = std::shared_ptr<Buffer>(new Buffer(sizeof(float)*size));
std::memcpy(buf->getBuffer(), definition, sizeof(float)*size);
AUD_Sound *equalizer=new AUD_Sound(new Equalizer(*sound, buf, size, maxFreqEq, sizeConversion));
return equalizer;
}
#endif

View File

@ -397,6 +397,16 @@ extern AUD_API AUD_Sound* AUD_Sound_mutable(AUD_Sound* sound);
#ifdef WITH_CONVOLUTION
extern AUD_API AUD_Sound* AUD_Sound_Convolver(AUD_Sound* sound, AUD_ImpulseResponse* filter, AUD_ThreadPool* threadPool);
extern AUD_API AUD_Sound* AUD_Sound_Binaural(AUD_Sound* sound, AUD_HRTF* hrtfs, AUD_Source* source, AUD_ThreadPool* threadPool);
/**
* Creates an Equalizer for the sound
* \param sound The handle of the sound
* \param definition buffer of size*sizeof(float) with the array of equalization values
* \param maxFreqEq Maximum frequency refered by the array
* \param sizeConversion Size of the transformation. Must be 2^number (for example 1024, 2048,...)
* \return A handle to the Equalizer refered to that sound
*/
extern AUD_API AUD_Sound* AUD_Sound_equalize(AUD_Sound* sound, float *definition, int size, float maxFreqEq, int sizeConversion);
#endif
#ifdef __cplusplus

View File

@ -53,6 +53,7 @@ extern AUD_API AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, double seconds);
* \param buffer The buffer to write to. Must have a size of 3*4*length.
* \param length How many samples to read from the sound.
* \param samples_per_second How many samples to read per second of the sound.
* \param interrupt Must point to a short that equals 0. If it is set to a non-zero value, the method will be interrupted and return 0.
* \return How many samples really have been read. Always <= length.
*/
extern AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int samples_per_second, short* interrupt);

View File

@ -5,12 +5,12 @@ import os
import codecs
import numpy
from distutils.core import setup, Extension
from setuptools import setup, Extension
if len(sys.argv) > 2 and sys.argv[1] == '--build-docs':
import subprocess
from distutils.core import Distribution
from distutils.command.build import build
from setuptools import Distribution
from setuptools.command.build import build
dist = Distribution()
cmd = build(dist)

106
extern/audaspace/include/fx/Equalizer.h vendored Normal file
View File

@ -0,0 +1,106 @@
/*******************************************************************************
* Copyright 2022 Marcos Perez Gonzalez
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#pragma once
/**
* @file Equalizer.h
* @ingroup fx
* The Equalizer class.
*/
#include <memory>
#include <vector>
#include "ISound.h"
#include "ImpulseResponse.h"
AUD_NAMESPACE_BEGIN
class Buffer;
class ImpulseResponse;
/**
* This class represents a sound that can be modified depending on a given impulse response.
*/
class AUD_API Equalizer : public ISound
{
private:
/**
* A pointer to the imput sound.
*/
std::shared_ptr<ISound> m_sound;
/**
* Local definition of Equalizer
*/
std::shared_ptr<Buffer> m_bufEQ;
/**
* A pointer to the impulse response.
*/
std::shared_ptr<ImpulseResponse> m_impulseResponse;
/**
* delete copy constructor and operator=
*/
Equalizer(const Equalizer&) = delete;
Equalizer& operator=(const Equalizer&) = delete;
/**
* Create ImpulseResponse from the definition in the Buffer,
* using at the end a minimum phase change
*/
std::shared_ptr<ImpulseResponse> createImpulseResponse();
/**
* Create an Impulse Response with minimum phase distortion using Homomorphic
* The input is an Impulse Response
*/
std::shared_ptr<Buffer> minimumPhaseFilterHomomorphic(std::shared_ptr<Buffer> original, int lOriginal, int lWork);
/**
* Create an Impulse Response with minimum phase distortion using Hilbert
* The input is an Impulse Response
*/
std::shared_ptr<Buffer> minimumPhaseFilterHilbert(std::shared_ptr<Buffer> original, int lOriginal, int lWork);
public:
/**
* Creates a new Equalizer.
* \param sound The sound that will be equalized
*/
Equalizer(std::shared_ptr<ISound> sound, std::shared_ptr<Buffer> bufEQ, int externalSizeEq, float maxFreqEq, int sizeConversion);
virtual ~Equalizer();
virtual std::shared_ptr<IReader> createReader();
/*
* Length of the external equalizer definition. It must be the number of "float" positions of the Buffer
*/
int external_size_eq;
/*
* Length of the internal equalizer definition
*/
int filter_length;
/*
* Maximum frequency used in the equalizer definition
*/
float maxFreqEq;
};
AUD_NAMESPACE_END

View File

@ -27,7 +27,7 @@
AUD_NAMESPACE_BEGIN
BinauralReader::BinauralReader(std::shared_ptr<IReader> reader, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
m_reader(reader), m_hrtfs(hrtfs), m_source(source), m_N(plan->getSize()), m_threadPool(threadPool), m_position(0), m_eosReader(false), m_eosTail(false), m_transition(false), m_transPos(CROSSFADE_SAMPLES*NUM_OUTCHANNELS)
m_position(0), m_reader(reader), m_hrtfs(hrtfs), m_source(source), m_N(plan->getSize()), m_transition(false), m_transPos(CROSSFADE_SAMPLES*NUM_OUTCHANNELS), m_eosReader(false), m_eosTail(false), m_threadPool(threadPool)
{
if(m_hrtfs->isEmpty())
AUD_THROW(StateException, "The provided HRTF object is empty");

View File

@ -23,7 +23,7 @@
AUD_NAMESPACE_BEGIN
Convolver::Convolver(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir, int irLength, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffers(ir), m_irLength(irLength), m_threadPool(threadPool), m_numThreads(std::min(threadPool->getNumOfThreads(), static_cast<unsigned int>(m_irBuffers->size() - 1))), m_tailCounter(0), m_eos(false)
m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffers(ir), m_numThreads(std::min(threadPool->getNumOfThreads(), static_cast<unsigned int>(m_irBuffers->size() - 1))), m_threadPool(threadPool), m_irLength(irLength), m_tailCounter(0), m_eos(false)
{
m_resetFlag = false;

View File

@ -24,7 +24,7 @@
AUD_NAMESPACE_BEGIN
ConvolverReader::ConvolverReader(std::shared_ptr<IReader> reader, std::shared_ptr<ImpulseResponse> ir, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
m_reader(reader), m_ir(ir), m_N(plan->getSize()), m_eosReader(false), m_eosTail(false), m_inChannels(reader->getSpecs().channels), m_irChannels(ir->getSpecs().channels), m_threadPool(threadPool), m_position(0)
m_position(0), m_reader(reader), m_ir(ir), m_N(plan->getSize()), m_eosReader(false), m_eosTail(false), m_inChannels(reader->getSpecs().channels), m_irChannels(ir->getSpecs().channels), m_threadPool(threadPool)
{
m_nChannelThreads = std::min((int)threadPool->getNumOfThreads(), m_inChannels);
m_futures.resize(m_nChannelThreads);

367
extern/audaspace/src/fx/Equalizer.cpp vendored Normal file
View File

@ -0,0 +1,367 @@
/*******************************************************************************
* Copyright 2022 Marcos Perez Gonzalez
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#include "fx/Equalizer.h"
#include <chrono>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include "Exception.h"
#include "fx/ConvolverReader.h"
#include "fx/ImpulseResponse.h"
#include "util/Buffer.h"
#include "util/FFTPlan.h"
#include "util/ThreadPool.h"
AUD_NAMESPACE_BEGIN
Equalizer::Equalizer(std::shared_ptr<ISound> sound, std::shared_ptr<Buffer> bufEQ, int externalSizeEq, float maxFreqEq, int sizeConversion) : m_sound(sound), m_bufEQ(bufEQ)
{
this->maxFreqEq = maxFreqEq;
this->external_size_eq = externalSizeEq;
filter_length = sizeConversion;
}
Equalizer::~Equalizer()
{
}
std::shared_ptr<IReader> Equalizer::createReader()
{
std::shared_ptr<FFTPlan> fp = std::shared_ptr<FFTPlan>(new FFTPlan(filter_length));
// 2 threads to start with
return std::shared_ptr<ConvolverReader>(new ConvolverReader(m_sound->createReader(), createImpulseResponse(), std::shared_ptr<ThreadPool>(new ThreadPool(2)), fp));
}
float calculateValueArray(float* data, float minX, float maxX, int length, float posX)
{
if(posX < minX)
return 1.0;
if(posX > maxX)
return data[length - 1];
float interval = (maxX - minX) / (float) length;
int idx = (int) ((posX - minX) / interval);
return data[idx];
}
void complex_prod(float a, float b, float c, float d, float* r, float* imag)
{
float prod1 = a * c;
float prod2 = b * d;
float prod3 = (a + b) * (c + d);
// Real Part
*r = prod1 - prod2;
// Imaginary Part
*imag = prod3 - (prod1 + prod2);
}
/**
* The creation of the ImpuseResponse which will be convoluted with the sound
*
* The implementation is based on scikit-signal
*/
std::shared_ptr<ImpulseResponse> Equalizer::createImpulseResponse()
{
std::shared_ptr<FFTPlan> fp = std::shared_ptr<FFTPlan>(new FFTPlan(filter_length));
fftwf_complex* buffer = (fftwf_complex*) fp->getBuffer();
std::memset(buffer, 0, filter_length * sizeof(fftwf_complex));
std::shared_ptr<IReader> soundReader = m_sound.get()->createReader();
Specs specsSound = soundReader.get()->getSpecs();
int sampleRate = specsSound.rate;
for(unsigned i = 0; i < filter_length / 2; i++)
{
double freq = (((float) i) / (float) filter_length) * (float) sampleRate;
double dbGain = calculateValueArray(m_bufEQ->getBuffer(), 0.0, maxFreqEq, external_size_eq, freq);
// gain = 10^(decibels / 20.0)
// 0 db = 1
// 20 db = 10
// 40 db = 100
float gain = (float) pow(10.0, dbGain / 20.0);
if(i == filter_length / 2 - 1)
{
gain = 0;
}
// IMPORTANT!!!! It is needed for the minimum phase step.
// Without this, the amplitude would be square rooted
//
gain *= gain;
// Calculation of exponential with std.. or "by hand"
/*
std::complex<float> preShift= std::complex<float>(0.0, -(filter_length - 1)
/ 2. * M_PI * freq / ( sampleRate/2)); std::complex<float> shift =
std::exp(preShift);
std::complex<float> cGain = gain * shift;
*/
float imaginary_shift = -(filter_length - 1) / 2. * M_PI * freq / (sampleRate / 2);
float cGain_real = gain * cos(imaginary_shift);
float cGain_imag = gain * sin(imaginary_shift);
int i2 = filter_length - i - 1;
buffer[i][0] = cGain_real; // Real
buffer[i][1] = cGain_imag; // Imag
if(i > 0 && i2 < filter_length)
{
buffer[i2][0] = cGain_real; // Real
buffer[i2][1] = cGain_imag; // Imag
}
}
// In place. From Complex to sample_t
fp->IFFT(buffer);
// Window Hamming
sample_t* pt_sample_t = (sample_t*) buffer;
float half_filter = ((float) filter_length) / 2.0;
for(int i = 0; i < filter_length; i++)
{
// Centered in filter_length/2
float window = 0.54 - 0.46 * cos((2 * M_PI * (float) i) / (float) (filter_length - 1));
pt_sample_t[i] *= window;
}
std::shared_ptr<Buffer> b2 = std::shared_ptr<Buffer>(new Buffer(filter_length * sizeof(sample_t)));
sample_t* buffer_real = (sample_t*) buffer;
sample_t* buffer2 = b2->getBuffer();
float normaliziter = (float) filter_length;
for(int i = 0; i < filter_length; i++)
{
buffer2[i] = (buffer_real[i] / normaliziter);
}
fp->freeBuffer(buffer);
//
// Here b2 is the buffer with a "valid" FIR (remember the squared amplitude
//
std::shared_ptr<Buffer> ir_minimum = minimumPhaseFilterHomomorphic(b2, filter_length, -1);
Specs specsIR;
specsIR.rate = sampleRate;
specsIR.channels = CHANNELS_MONO;
return std::shared_ptr<ImpulseResponse>(new ImpulseResponse(std::shared_ptr<StreamBuffer>(new StreamBuffer(ir_minimum, specsIR)), fp));
}
std::shared_ptr<Buffer> Equalizer::minimumPhaseFilterHomomorphic(std::shared_ptr<Buffer> original, int lOriginal, int lWork)
{
void* b_orig = original->getBuffer();
if(lWork < lOriginal || lWork < 0)
{
lWork = (int) pow(2, ceil(log2((float) (2 * (lOriginal - 1) / 0.01))));
}
std::shared_ptr<FFTPlan> fp = std::shared_ptr<FFTPlan>(new FFTPlan(lWork, 0.1));
fftwf_complex* buffer = (fftwf_complex*) fp->getBuffer();
sample_t* b_work = (sample_t*) buffer;
// Padding with 0
std::memset(b_work, 0, lWork * sizeof(sample_t));
std::memcpy(b_work, b_orig, lOriginal * sizeof(sample_t));
fp->FFT(b_work);
for(int i = 0; i < lWork / 2; i++)
{
buffer[i][0] = fabs(sqrt(buffer[i][0] * buffer[i][0] + buffer[i][1] * buffer[i][1]));
buffer[i][1] = 0.0;
int conjugate = lWork - i - 1;
buffer[conjugate][0] = buffer[i][0];
buffer[conjugate][1] = 0.0;
}
double threshold = pow(10.0, -7);
float logThreshold = (float) log(threshold);
// take 0.25*log(|H|**2) = 0.5*log(|H|)
for(int i = 0; i < lWork; i++)
{
if(buffer[i][0] < threshold)
{
buffer[i][0] = 0.5 * logThreshold;
}
else
{
buffer[i][0] = 0.5 * log(buffer[i][0]);
}
}
fp->IFFT(buffer);
// homomorphic filter
int stop = (lOriginal + 1) / 2;
b_work[0] = b_work[0] / (float) lWork;
for(int i = 1; i < stop; i++)
{
b_work[i] = b_work[i] / (float) lWork * 2.0;
}
for(int i = stop; i < lWork; i++)
{
b_work[i] = 0;
}
fp->FFT(buffer);
// EXP
// e^x = e^ (a+bi)= e^a * e^bi = e^a * (cos b + i sin b)
for(int i = 0; i < lWork / 2; i++)
{
float new_real;
float new_imag;
new_real = exp(buffer[i][0]) * cos(buffer[i][1]);
new_imag = exp(buffer[i][0]) * sin(buffer[i][1]);
buffer[i][0] = new_real;
buffer[i][1] = new_imag;
int conjugate = lWork - i - 1;
buffer[conjugate][0] = new_real;
buffer[conjugate][1] = new_imag;
}
// IFFT
fp->IFFT(buffer);
// Create new clean Buffer with only the result and normalization
int lOut = (lOriginal / 2) + lOriginal % 2;
std::shared_ptr<Buffer> bOut = std::shared_ptr<Buffer>(new Buffer(sizeof(float) * lOut));
float* bbOut = (float*) bOut->getBuffer();
// Copy and normalize
for(int i = 0; i < lOut; i++)
{
bbOut[i] = b_work[i] / (float) lWork;
}
fp->freeBuffer(buffer);
return bOut;
}
std::shared_ptr<Buffer> Equalizer::minimumPhaseFilterHilbert(std::shared_ptr<Buffer> original, int lOriginal, int lWork)
{
void* b_orig = original->getBuffer();
if(lWork < lOriginal || lWork < 0)
{
lWork = (int) pow(2, ceil(log2((float) (2 * (lOriginal - 1) / 0.01))));
}
std::shared_ptr<FFTPlan> fp = std::shared_ptr<FFTPlan>(new FFTPlan(lWork, 0.1));
fftwf_complex* buffer = (fftwf_complex*) fp->getBuffer();
sample_t* b_work = (sample_t*) buffer;
// Padding with 0
std::memset(b_work, 0, lWork * sizeof(sample_t));
std::memcpy(b_work, b_orig, lOriginal * sizeof(sample_t));
fp->FFT(b_work);
float mymax, mymin;
float n_half = (float) (lOriginal >> 1);
for(int i = 0; i < lWork; i++)
{
float w = ((float) i) * 2.0 * M_PI / (float) lWork * n_half;
float f1 = cos(w);
float f2 = sin(w);
float f3, f4;
complex_prod(buffer[i][0], buffer[i][1], f1, f2, &f3, &f4);
buffer[i][0] = f3;
buffer[i][1] = 0.0;
if(i == 0)
{
mymax = f3;
mymin = f3;
}
else
{
if(f3 < mymin)
mymin = f3;
if(f3 > mymax)
mymax = f3;
}
}
float dp = mymax - 1;
float ds = 0 - mymin;
float S = 4.0 / pow(2, (sqrt(1 + dp + ds) + sqrt(1 - dp + ds)));
for(int i = 0; i < lWork; i++)
{
buffer[i][0] = sqrt((buffer[i][0] + ds) * S) + 1.0E-10;
}
fftwf_complex* buffer_tmp = (fftwf_complex*) std::malloc(lWork * sizeof(fftwf_complex));
std::memcpy(buffer_tmp, buffer, lWork * sizeof(fftwf_complex));
//
// Hilbert transform
//
int midpt = lWork >> 1;
for(int i = 0; i < lWork; i++)
buffer[i][0] = log(buffer[i][0]);
fp->IFFT(buffer);
b_work[0] = 0.0;
for(int i = 1; i < midpt; i++)
{
b_work[i] /= (float) lWork;
}
b_work[midpt] = 0.0;
for(int i = midpt + 1; i < lWork; i++)
{
b_work[i] /= (-1.0 * lWork);
}
fp->FFT(b_work);
// Exp
for(int i = 0; i < lWork; i++)
{
float base = exp(buffer[i][0]);
buffer[i][0] = base * cos(buffer[i][1]);
buffer[i][1] = base * sin(buffer[i][1]);
complex_prod(buffer_tmp[i][0], buffer_tmp[i][1], buffer[i][0], buffer[i][1], &(buffer[i][0]), &(buffer[i][1]));
}
std::free(buffer_tmp);
fp->IFFT(buffer);
//
// Copy and normalization
//
int n_out = n_half + lOriginal % 2;
std::shared_ptr<Buffer> b_minimum = std::shared_ptr<Buffer>(new Buffer(n_out * sizeof(sample_t)));
std::memcpy(b_minimum->getBuffer(), buffer, n_out * sizeof(sample_t));
sample_t* b_final = (sample_t*) b_minimum->getBuffer();
for(int i = 0; i < n_out; i++)
{
b_final[i] /= (float) lWork;
}
return b_minimum;
}
AUD_NAMESPACE_END

View File

@ -22,7 +22,7 @@
AUD_NAMESPACE_BEGIN
FFTConvolver::FFTConvolver(std::shared_ptr<std::vector<std::complex<sample_t>>> ir, std::shared_ptr<FFTPlan> plan) :
m_plan(plan), m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_tailPos(0), m_irBuffer(ir)
m_plan(plan), m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffer(ir), m_tailPos(0)
{
m_tail = (float*)calloc(m_M - 1, sizeof(float));
m_realBufLen = ((m_N / 2) + 1) * 2;

View File

@ -75,7 +75,7 @@ void HRTFLoader::loadHRTFs(std::shared_ptr<HRTF> hrtfs, char ear, const std::str
if(ear == 'L')
azim = 360 - azim;
}
catch(std::exception& e)
catch(...)
{
AUD_THROW(FileException, "The HRTF name doesn't follow the naming scheme: " + filename);
}
@ -86,4 +86,4 @@ void HRTFLoader::loadHRTFs(std::shared_ptr<HRTF> hrtfs, char ear, const std::str
return;
}
AUD_NAMESPACE_END
AUD_NAMESPACE_END

View File

@ -78,7 +78,7 @@ void HRTFLoader::loadHRTFs(std::shared_ptr<HRTF> hrtfs, char ear, const std::str
if(ear == 'L')
azim = 360 - azim;
}
catch(std::exception& e)
catch(...)
{
AUD_THROW(FileException, "The HRTF name doesn't follow the naming scheme: " + filename);
}
@ -90,4 +90,4 @@ void HRTFLoader::loadHRTFs(std::shared_ptr<HRTF> hrtfs, char ear, const std::str
return;
}
AUD_NAMESPACE_END
AUD_NAMESPACE_END

View File

@ -81,25 +81,26 @@ def rna_idprop_ui_create(
):
"""Create and initialize a custom property with limits, defaults and other settings."""
# Assign the value
item[prop] = default
rna_idprop_ui_prop_update(item, prop)
ui_data = item.id_properties_ui(prop)
proptype, _ = rna_idprop_value_item_type(default)
# Sanitize limits
if proptype is bool:
min = soft_min = False
max = soft_max = True
ui_data = item.id_properties_ui(prop)
ui_data.update(
description=description,
default=default,
)
return
if soft_min is None:
soft_min = min
if soft_max is None:
soft_max = max
# Assign the value
item[prop] = default
rna_idprop_ui_prop_update(item, prop)
# Update the UI settings.
ui_data = item.id_properties_ui(prop)
ui_data.update(
subtype=subtype,
min=min,

View File

@ -5056,7 +5056,7 @@ def km_sculpt(params):
("target", "MASK"),
("falloff_type", "GEODESIC"),
("invert", True),
("use_auto_mask", True),
("use_auto_mask", False),
("use_mask_preserve", True),
]}),
("sculpt.expand", {"type": 'A', "value": 'PRESS', "shift": True, "alt": True},
@ -5639,7 +5639,7 @@ def km_sculpt_curves(params):
("curves.set_selection_domain", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("domain", 'POINT')]}),
("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}),
*_template_paint_radial_control("curves_sculpt"),
*_template_items_select_actions(params, "sculpt_curves.select_all"),
*_template_items_select_actions(params, "curves.select_all"),
("sculpt_curves.min_distance_edit", {"type": 'R', "value": 'PRESS', "shift": True}, {}),
("sculpt_curves.select_grow", {"type": 'A', "value": 'PRESS', "shift": True}, {}),
])

View File

@ -14,6 +14,7 @@ from bpy.props import (
FloatProperty,
IntProperty,
StringProperty,
BoolVectorProperty,
IntVectorProperty,
FloatVectorProperty,
)
@ -1325,6 +1326,8 @@ rna_custom_property_type_items = (
('FLOAT_ARRAY', "Float Array", "An array of floating-point values"),
('INT', "Integer", "A single integer"),
('INT_ARRAY', "Integer Array", "An array of integers"),
('BOOL', "Boolean", "A true or false value"),
('BOOL_ARRAY', "Boolean Array", "An array of true or false values"),
('STRING', "String", "A string value"),
('PYTHON', "Python", "Edit a python value directly, for unsupported property types"),
)
@ -1410,6 +1413,14 @@ class WM_OT_properties_edit(Operator):
default=1,
)
# Boolean properties.
# This property stores values for both array and non-array properties.
default_bool: BoolVectorProperty(
name="Default Value",
size=32,
)
# Float properties.
# This property stores values for both array and non-array properties.
@ -1520,6 +1531,10 @@ class WM_OT_properties_edit(Operator):
if is_array:
return 'FLOAT_ARRAY'
return 'FLOAT'
elif prop_type == bool:
if is_array:
return 'BOOL_ARRAY'
return 'BOOL'
elif prop_type == str:
if is_array:
return 'PYTHON'
@ -1571,8 +1586,10 @@ class WM_OT_properties_edit(Operator):
self.default_int = self._convert_new_value_array(rna_data["default"], int, 32)
elif self.property_type == 'STRING':
self.default_string = rna_data["default"]
elif self.property_type in {'BOOL', 'BOOL_ARRAY'}:
self.default_int = self._convert_new_value_array(rna_data["default"], bool, 32)
if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY'}:
if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
self.array_length = len(item[name])
# The dictionary does not contain the description if it was empty.
@ -1591,16 +1608,26 @@ class WM_OT_properties_edit(Operator):
if prop_type_new == 'FLOAT':
return self._convert_new_value_single(item[name_old], float)
if prop_type_new == 'BOOL':
return self._convert_new_value_single(item[name_old], bool)
if prop_type_new == 'INT_ARRAY':
prop_type_old = self.get_property_type(item, name_old)
if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY'}:
if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY', 'BOOL_ARRAY'}:
return self._convert_new_value_array(item[name_old], int, self.array_length)
if prop_type_new == 'FLOAT_ARRAY':
prop_type_old = self.get_property_type(item, name_old)
if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}:
if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
return self._convert_new_value_array(item[name_old], float, self.array_length)
if prop_type_new == 'BOOL_ARRAY':
prop_type_old = self.get_property_type(item, name_old)
if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}:
return self._convert_new_value_array(item[name_old], bool, self.array_length)
else:
return [False] * self.array_length
if prop_type_new == 'STRING':
return self.convert_custom_property_to_string(item, name_old)
@ -1622,6 +1649,9 @@ class WM_OT_properties_edit(Operator):
self.soft_min_float = float(self.soft_min_int)
self.soft_max_float = float(self.soft_max_int)
self.default_float = self._convert_new_value_array(self.default_int, float, 32)
elif prop_type_new in {'BOOL', 'BOOL_ARRAY'} and prop_type_old in {'INT', 'INT_ARRAY'}:
self.default_bool = self._convert_new_value_array(self.default_int, bool, 32)
# Don't convert between string and float/int defaults here, it's not expected like the other conversions.
# Fill the property's UI data with the values chosen in the operator.
@ -1637,6 +1667,12 @@ class WM_OT_properties_edit(Operator):
default=self.default_int[0] if prop_type_new == 'INT' else self.default_int[:self.array_length],
description=self.description,
)
if prop_type_new in {'BOOL', 'BOOL_ARRAY'}:
ui_data = item.id_properties_ui(name)
ui_data.update(
default=self.default_bool[0] if prop_type_new == 'BOOL' else self.default_bool[:self.array_length],
description=self.description,
)
elif prop_type_new in {'FLOAT', 'FLOAT_ARRAY'}:
ui_data = item.id_properties_ui(name)
ui_data.update(
@ -1879,6 +1915,15 @@ class WM_OT_properties_edit(Operator):
col.prop(self, "soft_max_int", text="Max")
layout.prop(self, "step_int")
elif self.property_type in {'BOOL', 'BOOL_ARRAY'}:
if self.property_type == 'BOOL_ARRAY':
layout.prop(self, "array_length")
col = layout.column(align=True)
col.prop(self, "default_bool", index=0, text="Default")
for i in range(1, self.array_length):
col.prop(self, "default_bool", index=i, text=" ")
else:
layout.prop(self, "default_bool", index=0)
elif self.property_type == 'STRING':
layout.prop(self, "default_string")

View File

@ -12,9 +12,10 @@ class NODE_MT_geometry_node_GEO_ATTRIBUTE(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeAttributeStatistic")
node_add_menu.add_node_type(layout, "GeometryNodeAttributeDomainSize")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeBlurAttribute")
node_add_menu.add_node_type(layout, "GeometryNodeCaptureAttribute")
node_add_menu.add_node_type(layout, "GeometryNodeAttributeDomainSize")
node_add_menu.add_node_type(layout, "GeometryNodeRemoveAttribute")
node_add_menu.add_node_type(layout, "GeometryNodeStoreNamedAttribute")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
@ -27,12 +28,13 @@ class NODE_MT_geometry_node_GEO_COLOR(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "ShaderNodeValToRGB")
node_add_menu.add_node_type(layout, "ShaderNodeRGBCurve")
layout.separator()
node_add_menu.add_node_type(layout, "FunctionNodeCombineColor")
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=iface_("Mix Color"))
ops = props.settings.add()
ops.name = "data_type"
ops.value = "'RGBA'"
node_add_menu.add_node_type(layout, "ShaderNodeRGBCurve")
node_add_menu.add_node_type(layout, "FunctionNodeSeparateColor")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
@ -43,19 +45,23 @@ class NODE_MT_geometry_node_GEO_CURVE(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeCurveLength")
node_add_menu.add_node_type(layout, "GeometryNodeCurveToMesh")
node_add_menu.add_node_type(layout, "GeometryNodeCurveToPoints")
node_add_menu.add_node_type(layout, "GeometryNodeDeformCurvesOnSurface")
node_add_menu.add_node_type(layout, "GeometryNodeFillCurve")
node_add_menu.add_node_type(layout, "GeometryNodeFilletCurve")
node_add_menu.add_node_type(layout, "GeometryNodeResampleCurve")
node_add_menu.add_node_type(layout, "GeometryNodeReverseCurve")
node_add_menu.add_node_type(layout, "GeometryNodeSampleCurve")
node_add_menu.add_node_type(layout, "GeometryNodeSubdivideCurve")
node_add_menu.add_node_type(layout, "GeometryNodeTrimCurve")
layout.menu("NODE_MT_geometry_node_GEO_CURVE_READ")
layout.menu("NODE_MT_geometry_node_GEO_CURVE_WRITE")
layout.separator()
layout.menu("NODE_MT_geometry_node_GEO_CURVE_OPERATIONS")
layout.menu("NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE")
layout.menu("NODE_MT_geometry_node_curve_topology")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_CURVE_READ(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_CURVE_READ"
bl_label = "Read"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeInputCurveHandlePositions")
node_add_menu.add_node_type(layout, "GeometryNodeCurveLength")
node_add_menu.add_node_type(layout, "GeometryNodeInputTangent")
node_add_menu.add_node_type(layout, "GeometryNodeInputCurveTilt")
node_add_menu.add_node_type(layout, "GeometryNodeCurveEndpointSelection")
@ -64,7 +70,14 @@ class NODE_MT_geometry_node_GEO_CURVE(Menu):
node_add_menu.add_node_type(layout, "GeometryNodeSplineLength")
node_add_menu.add_node_type(layout, "GeometryNodeSplineParameter")
node_add_menu.add_node_type(layout, "GeometryNodeInputSplineResolution")
layout.separator()
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_CURVE_WRITE(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_CURVE_WRITE"
bl_label = "Write"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeSetCurveNormal")
node_add_menu.add_node_type(layout, "GeometryNodeSetCurveRadius")
node_add_menu.add_node_type(layout, "GeometryNodeSetCurveTilt")
@ -76,9 +89,28 @@ class NODE_MT_geometry_node_GEO_CURVE(Menu):
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_CURVE_OPERATIONS(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_CURVE_OPERATIONS"
bl_label = "Operations"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeCurveToMesh")
node_add_menu.add_node_type(layout, "GeometryNodeCurveToPoints")
node_add_menu.add_node_type(layout, "GeometryNodeDeformCurvesOnSurface")
node_add_menu.add_node_type(layout, "GeometryNodeFillCurve")
node_add_menu.add_node_type(layout, "GeometryNodeFilletCurve")
node_add_menu.add_node_type(layout, "GeometryNodeResampleCurve")
node_add_menu.add_node_type(layout, "GeometryNodeReverseCurve")
node_add_menu.add_node_type(layout, "GeometryNodeSampleCurve")
node_add_menu.add_node_type(layout, "GeometryNodeSubdivideCurve")
node_add_menu.add_node_type(layout, "GeometryNodeTrimCurve")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE"
bl_label = "Curve Primitives"
bl_label = "Primitives"
def draw(self, _context):
layout = self.layout
@ -95,7 +127,7 @@ class NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE(Menu):
class NODE_MT_geometry_node_curve_topology(Menu):
bl_idname = "NODE_MT_geometry_node_curve_topology"
bl_label = "Curve Topology"
bl_label = "Topology"
def draw(self, _context):
layout = self.layout
@ -109,25 +141,69 @@ class NODE_MT_geometry_node_GEO_GEOMETRY(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY"
bl_label = "Geometry"
def draw(self, _context):
layout = self.layout
layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_READ")
layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_WRITE")
layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS")
layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeJoinGeometry")
node_add_menu.add_node_type(layout, "GeometryNodeGeometryToInstance")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_GEOMETRY_READ(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_READ"
bl_label = "Read"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeInputID")
node_add_menu.add_node_type(layout, "GeometryNodeInputIndex")
node_add_menu.add_node_type(layout, "GeometryNodeInputNamedAttribute")
node_add_menu.add_node_type(layout, "GeometryNodeInputNormal")
node_add_menu.add_node_type(layout, "GeometryNodeInputPosition")
node_add_menu.add_node_type(layout, "GeometryNodeInputRadius")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_GEOMETRY_WRITE(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_WRITE"
bl_label = "Write"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeSetID")
node_add_menu.add_node_type(layout, "GeometryNodeSetPosition")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS"
bl_label = "Operations"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeBoundBox")
node_add_menu.add_node_type(layout, "GeometryNodeConvexHull")
node_add_menu.add_node_type(layout, "GeometryNodeDeleteGeometry")
node_add_menu.add_node_type(layout, "GeometryNodeDuplicateElements")
node_add_menu.add_node_type(layout, "GeometryNodeProximity")
node_add_menu.add_node_type(layout, "GeometryNodeGeometryToInstance")
node_add_menu.add_node_type(layout, "GeometryNodeJoinGeometry")
node_add_menu.add_node_type(layout, "GeometryNodeMergeByDistance")
node_add_menu.add_node_type(layout, "GeometryNodeTransform")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeSeparateComponents")
node_add_menu.add_node_type(layout, "GeometryNodeSeparateGeometry")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE"
bl_label = "Sample"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeProximity")
node_add_menu.add_node_type(layout, "GeometryNodeRaycast")
node_add_menu.add_node_type(layout, "GeometryNodeSampleIndex")
node_add_menu.add_node_type(layout, "GeometryNodeSampleNearest")
node_add_menu.add_node_type(layout, "GeometryNodeSeparateComponents")
node_add_menu.add_node_type(layout, "GeometryNodeSeparateGeometry")
node_add_menu.add_node_type(layout, "GeometryNodeTransform")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeSetID")
node_add_menu.add_node_type(layout, "GeometryNodeSetPosition")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
@ -135,28 +211,52 @@ class NODE_MT_geometry_node_GEO_INPUT(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_INPUT"
bl_label = "Input"
def draw(self, _context):
layout = self.layout
layout.menu("NODE_MT_geometry_node_GEO_INPUT_CONSTANT")
layout.menu("NODE_MT_geometry_node_GEO_INPUT_GROUP")
layout.menu("NODE_MT_geometry_node_GEO_INPUT_SCENE")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_INPUT_CONSTANT(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_INPUT_CONSTANT"
bl_label = "Constant"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "FunctionNodeInputBool")
node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo")
node_add_menu.add_node_type(layout, "FunctionNodeInputColor")
node_add_menu.add_node_type(layout, "GeometryNodeInputImage")
node_add_menu.add_node_type(layout, "GeometryNodeImageInfo")
node_add_menu.add_node_type(layout, "FunctionNodeInputInt")
node_add_menu.add_node_type(layout, "GeometryNodeIsViewport")
node_add_menu.add_node_type(layout, "GeometryNodeInputMaterial")
node_add_menu.add_node_type(layout, "GeometryNodeObjectInfo")
node_add_menu.add_node_type(layout, "GeometryNodeSelfObject")
node_add_menu.add_node_type(layout, "FunctionNodeInputString")
node_add_menu.add_node_type(layout, "ShaderNodeValue")
node_add_menu.add_node_type(layout, "FunctionNodeInputVector")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeInputID")
node_add_menu.add_node_type(layout, "GeometryNodeInputIndex")
node_add_menu.add_node_type(layout, "GeometryNodeInputNamedAttribute")
node_add_menu.add_node_type(layout, "GeometryNodeInputNormal")
node_add_menu.add_node_type(layout, "GeometryNodeInputPosition")
node_add_menu.add_node_type(layout, "GeometryNodeInputRadius")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_INPUT_GROUP(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_INPUT_GROUP"
bl_label = "Group"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "NodeGroupInput")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_INPUT_SCENE(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_INPUT_SCENE"
bl_label = "Scene"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo")
node_add_menu.add_node_type(layout, "GeometryNodeImageInfo")
node_add_menu.add_node_type(layout, "GeometryNodeIsViewport")
node_add_menu.add_node_type(layout, "GeometryNodeObjectInfo")
node_add_menu.add_node_type(layout, "GeometryNodeSelfObject")
node_add_menu.add_node_type(layout, "GeometryNodeInputSceneTime")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
@ -169,6 +269,7 @@ class NODE_MT_geometry_node_GEO_INSTANCE(Menu):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeInstanceOnPoints")
node_add_menu.add_node_type(layout, "GeometryNodeInstancesToPoints")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeRealizeInstances")
node_add_menu.add_node_type(layout, "GeometryNodeRotateInstances")
node_add_menu.add_node_type(layout, "GeometryNodeScaleInstances")
@ -199,6 +300,52 @@ class NODE_MT_geometry_node_GEO_MESH(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_MESH"
bl_label = "Mesh"
def draw(self, _context):
layout = self.layout
layout.menu("NODE_MT_geometry_node_GEO_MESH_READ")
layout.menu("NODE_MT_geometry_node_GEO_MESH_WRITE")
layout.separator()
layout.menu("NODE_MT_geometry_node_GEO_MESH_OPERATIONS")
layout.menu("NODE_MT_category_PRIMITIVES_MESH")
layout.menu("NODE_MT_geometry_node_mesh_topology")
layout.menu("NODE_MT_category_GEO_UV")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_MESH_READ(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_MESH_READ"
bl_label = "Read"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors")
node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceIsPlanar")
node_add_menu.add_node_type(layout, "GeometryNodeInputShadeSmooth")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshIsland")
node_add_menu.add_node_type(layout, "GeometryNodeInputShortestEdgePaths")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshVertexNeighbors")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_MESH_WRITE(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_MESH_WRITE"
bl_label = "Write"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeSetShadeSmooth")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_geometry_node_GEO_MESH_OPERATIONS(Menu):
bl_idname = "NODE_MT_geometry_node_GEO_MESH_OPERATIONS"
bl_label = "Operations"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeDualMesh")
@ -217,26 +364,12 @@ class NODE_MT_geometry_node_GEO_MESH(Menu):
node_add_menu.add_node_type(layout, "GeometryNodeSubdivideMesh")
node_add_menu.add_node_type(layout, "GeometryNodeSubdivisionSurface")
node_add_menu.add_node_type(layout, "GeometryNodeTriangulate")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors")
node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceIsPlanar")
node_add_menu.add_node_type(layout, "GeometryNodeInputShadeSmooth")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshIsland")
node_add_menu.add_node_type(layout, "GeometryNodeInputShortestEdgePaths")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshVertexNeighbors")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeSetShadeSmooth")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_category_PRIMITIVES_MESH(Menu):
bl_idname = "NODE_MT_category_PRIMITIVES_MESH"
bl_label = "Mesh Primitives"
bl_label = "Primitives"
def draw(self, _context):
layout = self.layout
@ -253,7 +386,7 @@ class NODE_MT_category_PRIMITIVES_MESH(Menu):
class NODE_MT_geometry_node_mesh_topology(Menu):
bl_idname = "NODE_MT_geometry_node_mesh_topology"
bl_label = "Mesh Topology"
bl_label = "Topology"
def draw(self, _context):
layout = self.layout
@ -273,6 +406,7 @@ class NODE_MT_category_GEO_OUTPUT(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "NodeGroupOutput")
node_add_menu.add_node_type(layout, "GeometryNodeViewer")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
@ -285,6 +419,7 @@ class NODE_MT_category_GEO_POINT(Menu):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeDistributePointsInVolume")
node_add_menu.add_node_type(layout, "GeometryNodeDistributePointsOnFaces")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodePoints")
node_add_menu.add_node_type(layout, "GeometryNodePointsToVertices")
node_add_menu.add_node_type(layout, "GeometryNodePointsToVolume")
@ -302,6 +437,7 @@ class NODE_MT_category_GEO_TEXT(Menu):
node_add_menu.add_node_type(layout, "GeometryNodeStringJoin")
node_add_menu.add_node_type(layout, "FunctionNodeReplaceString")
node_add_menu.add_node_type(layout, "FunctionNodeSliceString")
layout.separator()
node_add_menu.add_node_type(layout, "FunctionNodeStringLength")
node_add_menu.add_node_type(layout, "GeometryNodeStringToCurves")
node_add_menu.add_node_type(layout, "FunctionNodeValueToString")
@ -333,23 +469,57 @@ class NODE_MT_category_GEO_UTILITIES(Menu):
bl_idname = "NODE_MT_category_GEO_UTILITIES"
bl_label = "Utilities"
def draw(self, _context):
layout = self.layout
layout.menu("NODE_MT_geometry_node_GEO_COLOR")
layout.menu("NODE_MT_category_GEO_TEXT")
layout.menu("NODE_MT_category_GEO_VECTOR")
layout.separator()
layout.menu("NODE_MT_category_GEO_UTILITIES_FIELD")
layout.menu("NODE_MT_category_GEO_UTILITIES_MATH")
layout.menu("NODE_MT_category_GEO_UTILITIES_ROTATION")
layout.separator()
node_add_menu.add_node_type(layout, "FunctionNodeRandomValue")
node_add_menu.add_node_type(layout, "GeometryNodeSwitch")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_category_GEO_UTILITIES_FIELD(Menu):
bl_idname = "NODE_MT_category_GEO_UTILITIES_FIELD"
bl_label = "Field"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeAccumulateField")
node_add_menu.add_node_type(layout, "GeometryNodeFieldAtIndex")
node_add_menu.add_node_type(layout, "GeometryNodeFieldOnDomain")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_category_GEO_UTILITIES_ROTATION(Menu):
bl_idname = "NODE_MT_category_GEO_UTILITIES_ROTATION"
bl_label = "Rotation"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "FunctionNodeAlignEulerToVector")
node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
class NODE_MT_category_GEO_UTILITIES_MATH(Menu):
bl_idname = "NODE_MT_category_GEO_UTILITIES_MATH"
bl_label = "Math"
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "FunctionNodeBooleanMath")
node_add_menu.add_node_type(layout, "ShaderNodeClamp")
node_add_menu.add_node_type(layout, "FunctionNodeCompare")
node_add_menu.add_node_type(layout, "GeometryNodeFieldAtIndex")
node_add_menu.add_node_type(layout, "ShaderNodeFloatCurve")
node_add_menu.add_node_type(layout, "FunctionNodeFloatToInt")
node_add_menu.add_node_type(layout, "GeometryNodeFieldOnDomain")
node_add_menu.add_node_type(layout, "ShaderNodeMapRange")
node_add_menu.add_node_type(layout, "ShaderNodeMath")
node_add_menu.add_node_type(layout, "ShaderNodeMix")
node_add_menu.add_node_type(layout, "FunctionNodeRandomValue")
node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler")
node_add_menu.add_node_type(layout, "GeometryNodeSwitch")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
@ -370,11 +540,16 @@ class NODE_MT_category_GEO_VECTOR(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "ShaderNodeCombineXYZ")
node_add_menu.add_node_type(layout, "ShaderNodeSeparateXYZ")
node_add_menu.add_node_type(layout, "ShaderNodeVectorCurve")
node_add_menu.add_node_type(layout, "ShaderNodeVectorMath")
node_add_menu.add_node_type(layout, "ShaderNodeVectorRotate")
layout.separator()
node_add_menu.add_node_type(layout, "ShaderNodeCombineXYZ")
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=iface_("Mix Vector"))
ops = props.settings.add()
ops.name = "data_type"
ops.value = "'VECTOR'"
node_add_menu.add_node_type(layout, "ShaderNodeSeparateXYZ")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
@ -417,25 +592,21 @@ class NODE_MT_geometry_node_add_all(Menu):
def draw(self, _context):
layout = self.layout
layout.menu("NODE_MT_geometry_node_GEO_ATTRIBUTE")
layout.menu("NODE_MT_geometry_node_GEO_COLOR")
layout.menu("NODE_MT_geometry_node_GEO_CURVE")
layout.menu("NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE")
layout.menu("NODE_MT_geometry_node_curve_topology")
layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY")
layout.menu("NODE_MT_geometry_node_GEO_INPUT")
layout.menu("NODE_MT_geometry_node_GEO_INSTANCE")
layout.menu("NODE_MT_geometry_node_GEO_MATERIAL")
layout.menu("NODE_MT_geometry_node_GEO_MESH")
layout.menu("NODE_MT_category_PRIMITIVES_MESH")
layout.menu("NODE_MT_geometry_node_mesh_topology")
layout.menu("NODE_MT_category_GEO_OUTPUT")
layout.separator()
layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY")
layout.separator()
layout.menu("NODE_MT_geometry_node_GEO_CURVE")
layout.menu("NODE_MT_geometry_node_GEO_INSTANCE")
layout.menu("NODE_MT_geometry_node_GEO_MESH")
layout.menu("NODE_MT_category_GEO_POINT")
layout.menu("NODE_MT_category_GEO_TEXT")
layout.menu("NODE_MT_category_GEO_VOLUME")
layout.separator()
layout.menu("NODE_MT_geometry_node_GEO_MATERIAL")
layout.menu("NODE_MT_category_GEO_TEXTURE")
layout.menu("NODE_MT_category_GEO_UTILITIES")
layout.menu("NODE_MT_category_GEO_UV")
layout.menu("NODE_MT_category_GEO_VECTOR")
layout.menu("NODE_MT_category_GEO_VOLUME")
layout.separator()
layout.menu("NODE_MT_category_GEO_GROUP")
layout.menu("NODE_MT_category_GEO_LAYOUT")
node_add_menu.draw_root_assets(layout)
@ -444,25 +615,41 @@ class NODE_MT_geometry_node_add_all(Menu):
classes = (
NODE_MT_geometry_node_add_all,
NODE_MT_geometry_node_GEO_ATTRIBUTE,
NODE_MT_geometry_node_GEO_COLOR,
NODE_MT_geometry_node_GEO_INPUT,
NODE_MT_geometry_node_GEO_INPUT_CONSTANT,
NODE_MT_geometry_node_GEO_INPUT_GROUP,
NODE_MT_geometry_node_GEO_INPUT_SCENE,
NODE_MT_category_GEO_OUTPUT,
NODE_MT_geometry_node_GEO_CURVE,
NODE_MT_geometry_node_GEO_CURVE_READ,
NODE_MT_geometry_node_GEO_CURVE_WRITE,
NODE_MT_geometry_node_GEO_CURVE_OPERATIONS,
NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE,
NODE_MT_geometry_node_curve_topology,
NODE_MT_geometry_node_GEO_GEOMETRY,
NODE_MT_geometry_node_GEO_INPUT,
NODE_MT_geometry_node_GEO_GEOMETRY_READ,
NODE_MT_geometry_node_GEO_GEOMETRY_WRITE,
NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS,
NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE,
NODE_MT_geometry_node_GEO_INSTANCE,
NODE_MT_geometry_node_GEO_MATERIAL,
NODE_MT_geometry_node_GEO_MESH,
NODE_MT_geometry_node_GEO_MESH_READ,
NODE_MT_geometry_node_GEO_MESH_WRITE,
NODE_MT_geometry_node_GEO_MESH_OPERATIONS,
NODE_MT_category_GEO_UV,
NODE_MT_category_PRIMITIVES_MESH,
NODE_MT_geometry_node_mesh_topology,
NODE_MT_category_GEO_OUTPUT,
NODE_MT_category_GEO_POINT,
NODE_MT_category_GEO_TEXT,
NODE_MT_category_GEO_VOLUME,
NODE_MT_geometry_node_GEO_MATERIAL,
NODE_MT_category_GEO_TEXTURE,
NODE_MT_category_GEO_UTILITIES,
NODE_MT_category_GEO_UV,
NODE_MT_geometry_node_GEO_COLOR,
NODE_MT_category_GEO_TEXT,
NODE_MT_category_GEO_VECTOR,
NODE_MT_category_GEO_VOLUME,
NODE_MT_category_GEO_UTILITIES_FIELD,
NODE_MT_category_GEO_UTILITIES_MATH,
NODE_MT_category_GEO_UTILITIES_ROTATION,
NODE_MT_category_GEO_GROUP,
NODE_MT_category_GEO_LAYOUT,
)

View File

@ -2053,9 +2053,9 @@ class VIEW3D_MT_select_sculpt_curves(Menu):
def draw(self, _context):
layout = self.layout
layout.operator("sculpt_curves.select_all", text="All").action = 'SELECT'
layout.operator("sculpt_curves.select_all", text="None").action = 'DESELECT'
layout.operator("sculpt_curves.select_all", text="Invert").action = 'INVERT'
layout.operator("curves.select_all", text="All").action = 'SELECT'
layout.operator("curves.select_all", text="None").action = 'DESELECT'
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
layout.operator("sculpt_curves.select_random", text="Random")
layout.operator("sculpt_curves.select_end", text="Endpoints")
layout.operator("sculpt_curves.select_grow", text="Grow")

View File

@ -283,21 +283,6 @@ bool CustomData_has_layer(const struct CustomData *data, int type);
int CustomData_number_of_layers(const struct CustomData *data, int type);
int CustomData_number_of_layers_typemask(const struct CustomData *data, eCustomDataMask mask);
/**
* Duplicate data of a layer with flag NOFREE, and remove that flag.
* \return the layer data.
*/
void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type, int totelem);
void *CustomData_duplicate_referenced_layer_n(struct CustomData *data,
int type,
int n,
int totelem);
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
int type,
const char *name,
int totelem);
bool CustomData_is_referenced_layer(struct CustomData *data, int type);
/**
* Duplicate all the layers with flag NOFREE, and remove the flag from duplicated layers.
*/
@ -409,11 +394,15 @@ void CustomData_swap_corners(struct CustomData *data, int index, const int *corn
void CustomData_swap(struct CustomData *data, int index_a, int index_b);
/**
* Gets a pointer to the data element at index from the first layer of type.
* \return NULL if there is no layer of type.
* Retrieve a pointer to an element of the active layer of the given \a type, chosen by the
* \a index, if it exists.
*/
void *CustomData_get(const struct CustomData *data, int index, int type);
void *CustomData_get_n(const struct CustomData *data, int type, int index, int n);
void *CustomData_get_for_write(struct CustomData *data, int index, int type, int totelem);
/**
* Retrieve a pointer to an element of the \a nth layer of the given \a type, chosen by the
* \a index, if it exists.
*/
void *CustomData_get_n_for_write(struct CustomData *data, int type, int index, int n, int totelem);
/* BMesh Custom Data Functions.
* Should replace edit-mesh ones with these as well, due to more efficient memory alloc. */
@ -431,12 +420,29 @@ bool CustomData_set_layer_name(struct CustomData *data, int type, int n, const c
const char *CustomData_get_layer_name(const struct CustomData *data, int type, int n);
/**
* Gets a pointer to the active or first layer of type.
* \return NULL if there is no layer of type.
* Retrieve the data array of the active layer of the given \a type, if it exists. Return null
* otherwise.
*/
void *CustomData_get_layer(const struct CustomData *data, int type);
void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name);
const void *CustomData_get_layer(const struct CustomData *data, int type);
void *CustomData_get_layer_for_write(struct CustomData *data, int type, int totelem);
/**
* Retrieve the data array of the \a nth layer of the given \a type, if it exists. Return null
* otherwise.
*/
const void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
void *CustomData_get_layer_n_for_write(struct CustomData *data, int type, int n, int totelem);
/**
* Retrieve the data array of the layer with the given \a name and \a type, if it exists. Return
* null otherwise.
*/
const void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name);
void *CustomData_get_layer_named_for_write(CustomData *data,
int type,
const char *name,
int totelem);
int CustomData_get_offset(const struct CustomData *data, int type);
int CustomData_get_offset_named(const CustomData *data, int type, const char *name);
int CustomData_get_n_offset(const struct CustomData *data, int type, int n);

View File

@ -243,6 +243,7 @@ void IDP_ClearProperty(struct IDProperty *prop);
void IDP_Reset(struct IDProperty *prop, const struct IDProperty *reference);
#define IDP_Int(prop) ((prop)->data.val)
#define IDP_Bool(prop) ((prop)->data.val)
#define IDP_Array(prop) ((prop)->data.pointer)
/* C11 const correctness for casts */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
@ -334,6 +335,8 @@ typedef enum eIDPropertyUIDataType {
IDP_UI_DATA_TYPE_STRING = 2,
/** IDP_ID. */
IDP_UI_DATA_TYPE_ID = 3,
/** IDP_BOOLEAN or IDP_ARRAY with subtype IDP_BOOLEAN. */
IDP_UI_DATA_TYPE_BOOLEAN = 4,
} eIDPropertyUIDataType;
bool IDP_ui_data_supported(const struct IDProperty *prop);

View File

@ -145,7 +145,7 @@ void BKE_keyblock_convert_to_mesh(const struct KeyBlock *kb,
* \param r_loop_normals: if non-NULL, an array of vectors, same length as number of loops.
*/
void BKE_keyblock_mesh_calc_normals(const struct KeyBlock *kb,
const struct Mesh *mesh,
struct Mesh *mesh,
float (*r_vert_normals)[3],
float (*r_poly_normals)[3],
float (*r_loop_normals)[3]);

View File

@ -759,7 +759,8 @@ void BKE_mesh_polygon_flip_ex(const struct MPoly *mpoly,
bool use_loop_mdisp_flip);
void BKE_mesh_polygon_flip(const struct MPoly *mpoly,
struct MLoop *mloop,
struct CustomData *ldata);
struct CustomData *ldata,
int totloop);
/**
* Flip (invert winding of) all polygons (used to inverse their normals).
*
@ -983,7 +984,7 @@ BLI_INLINE const int *BKE_mesh_material_indices(const Mesh *mesh)
*/
BLI_INLINE int *BKE_mesh_material_indices_for_write(Mesh *mesh)
{
int *indices = (int *)CustomData_duplicate_referenced_layer_named(
int *indices = (int *)CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_INT32, "material_index", mesh->totpoly);
if (indices) {
return indices;
@ -998,7 +999,7 @@ BLI_INLINE const float (*BKE_mesh_vert_positions(const Mesh *mesh))[3]
}
BLI_INLINE float (*BKE_mesh_vert_positions_for_write(Mesh *mesh))[3]
{
return (float(*)[3])CustomData_duplicate_referenced_layer_named(
return (float(*)[3])CustomData_get_layer_named_for_write(
&mesh->vdata, CD_PROP_FLOAT3, "position", mesh->totvert);
}
@ -1008,7 +1009,7 @@ BLI_INLINE const MEdge *BKE_mesh_edges(const Mesh *mesh)
}
BLI_INLINE MEdge *BKE_mesh_edges_for_write(Mesh *mesh)
{
return (MEdge *)CustomData_duplicate_referenced_layer(&mesh->edata, CD_MEDGE, mesh->totedge);
return (MEdge *)CustomData_get_layer_for_write(&mesh->edata, CD_MEDGE, mesh->totedge);
}
BLI_INLINE const MPoly *BKE_mesh_polys(const Mesh *mesh)
@ -1017,7 +1018,7 @@ BLI_INLINE const MPoly *BKE_mesh_polys(const Mesh *mesh)
}
BLI_INLINE MPoly *BKE_mesh_polys_for_write(Mesh *mesh)
{
return (MPoly *)CustomData_duplicate_referenced_layer(&mesh->pdata, CD_MPOLY, mesh->totpoly);
return (MPoly *)CustomData_get_layer_for_write(&mesh->pdata, CD_MPOLY, mesh->totpoly);
}
BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh)
@ -1026,7 +1027,7 @@ BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh)
}
BLI_INLINE MLoop *BKE_mesh_loops_for_write(Mesh *mesh)
{
return (MLoop *)CustomData_duplicate_referenced_layer(&mesh->ldata, CD_MLOOP, mesh->totloop);
return (MLoop *)CustomData_get_layer_for_write(&mesh->ldata, CD_MLOOP, mesh->totloop);
}
BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh)
@ -1035,7 +1036,7 @@ BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh)
}
BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh)
{
MDeformVert *dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
MDeformVert *dvert = (MDeformVert *)CustomData_get_layer_for_write(
&mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
if (dvert) {
return dvert;

View File

@ -1494,7 +1494,7 @@ struct TexResult;
#define GEO_NODE_INPUT_SCENE_TIME 1145
#define GEO_NODE_ACCUMULATE_FIELD 1146
#define GEO_NODE_INPUT_MESH_EDGE_ANGLE 1147
#define GEO_NODE_FIELD_AT_INDEX 1148
#define GEO_NODE_EVALUATE_AT_INDEX 1148
#define GEO_NODE_CURVE_PRIMITIVE_ARC 1149
#define GEO_NODE_FLIP_FACES 1150
#define GEO_NODE_SCALE_ELEMENTS 1151
@ -1509,7 +1509,7 @@ struct TexResult;
#define GEO_NODE_INPUT_INSTANCE_SCALE 1160
#define GEO_NODE_VOLUME_CUBE 1161
#define GEO_NODE_POINTS 1162
#define GEO_NODE_INTERPOLATE_DOMAIN 1163
#define GEO_NODE_EVALUATE_ON_DOMAIN 1163
#define GEO_NODE_MESH_TO_VOLUME 1164
#define GEO_NODE_UV_UNWRAP 1165
#define GEO_NODE_UV_PACK_ISLANDS 1166

View File

@ -584,7 +584,7 @@ void psys_get_texture(struct ParticleSimulationData *sim,
void psys_interpolate_face(struct Mesh *mesh,
const float (*vert_positions)[3],
const float (*vert_normals)[3],
struct MFace *mface,
const struct MFace *mface,
struct MTFace *tface,
const float (*orcodata)[3],
float w[4],

View File

@ -94,8 +94,8 @@ static void editbmesh_calc_modifier_final_normals_or_defer(
static float *dm_getVertArray(DerivedMesh *dm)
{
float(*positions)[3] = (float(*)[3])CustomData_get_layer_named(
&dm->vertData, CD_PROP_FLOAT3, "position");
float(*positions)[3] = (float(*)[3])CustomData_get_layer_named_for_write(
&dm->vertData, CD_PROP_FLOAT3, "position", dm->getNumVerts(dm));
if (!positions) {
positions = (float(*)[3])CustomData_add_layer_named(
@ -109,7 +109,8 @@ static float *dm_getVertArray(DerivedMesh *dm)
static MEdge *dm_getEdgeArray(DerivedMesh *dm)
{
MEdge *medge = (MEdge *)CustomData_get_layer(&dm->edgeData, CD_MEDGE);
MEdge *medge = (MEdge *)CustomData_get_layer_for_write(
&dm->edgeData, CD_MEDGE, dm->getNumEdges(dm));
if (!medge) {
medge = (MEdge *)CustomData_add_layer(
@ -123,7 +124,8 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm)
static MLoop *dm_getLoopArray(DerivedMesh *dm)
{
MLoop *mloop = (MLoop *)CustomData_get_layer(&dm->loopData, CD_MLOOP);
MLoop *mloop = (MLoop *)CustomData_get_layer_for_write(
&dm->loopData, CD_MLOOP, dm->getNumLoops(dm));
if (!mloop) {
mloop = (MLoop *)CustomData_add_layer(
@ -137,7 +139,8 @@ static MLoop *dm_getLoopArray(DerivedMesh *dm)
static MPoly *dm_getPolyArray(DerivedMesh *dm)
{
MPoly *mpoly = (MPoly *)CustomData_get_layer(&dm->polyData, CD_MPOLY);
MPoly *mpoly = (MPoly *)CustomData_get_layer_for_write(
&dm->polyData, CD_MPOLY, dm->getNumPolys(dm));
if (!mpoly) {
mpoly = (MPoly *)CustomData_add_layer(
@ -351,7 +354,7 @@ static void mesh_set_only_copy(Mesh *mesh, const CustomData_MeshMasks *mask)
void *DM_get_vert_data_layer(DerivedMesh *dm, int type)
{
return CustomData_get_layer(&dm->vertData, type);
return CustomData_get_layer_for_write(&dm->vertData, type, dm->getNumVerts(dm));
}
void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
@ -360,17 +363,17 @@ void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
return dm->getEdgeArray(dm);
}
return CustomData_get_layer(&dm->edgeData, type);
return CustomData_get_layer_for_write(&dm->edgeData, type, dm->getNumEdges(dm));
}
void *DM_get_poly_data_layer(DerivedMesh *dm, int type)
{
return CustomData_get_layer(&dm->polyData, type);
return CustomData_get_layer_for_write(&dm->polyData, type, dm->getNumPolys(dm));
}
void *DM_get_loop_data_layer(DerivedMesh *dm, int type)
{
return CustomData_get_layer(&dm->loopData, type);
return CustomData_get_layer_for_write(&dm->loopData, type, dm->getNumLoops(dm));
}
void DM_copy_vert_data(
@ -499,10 +502,10 @@ static void add_orco_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orc
BKE_mesh_orco_verts_transform((Mesh *)ob->data, orco, totvert, 0);
}
if (!(layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer))) {
CustomData_add_layer(&mesh->vdata, layer, CD_SET_DEFAULT, nullptr, mesh->totvert);
layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer);
layerorco = (float(*)[3])CustomData_get_layer_for_write(&mesh->vdata, layer, mesh->totvert);
if (!layerorco) {
layerorco = (float(*)[3])CustomData_add_layer(
&mesh->vdata, layer, CD_SET_DEFAULT, nullptr, mesh->totvert);
}
memcpy(layerorco, orco, sizeof(float[3]) * totvert);
@ -924,13 +927,16 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Not worth parallelizing this,
* gives less than 0.1% overall speedup in best of best cases... */
range_vn_i((int *)CustomData_get_layer(&mesh_final->vdata, CD_ORIGINDEX),
range_vn_i((int *)CustomData_get_layer_for_write(
&mesh_final->vdata, CD_ORIGINDEX, mesh_final->totvert),
mesh_final->totvert,
0);
range_vn_i((int *)CustomData_get_layer(&mesh_final->edata, CD_ORIGINDEX),
range_vn_i((int *)CustomData_get_layer_for_write(
&mesh_final->edata, CD_ORIGINDEX, mesh_final->totedge),
mesh_final->totedge,
0);
range_vn_i((int *)CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX),
range_vn_i((int *)CustomData_get_layer_for_write(
&mesh_final->pdata, CD_ORIGINDEX, mesh_final->totpoly),
mesh_final->totpoly,
0);
}
@ -1932,8 +1938,8 @@ static void mesh_init_origspace(Mesh *mesh)
{
const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
OrigSpaceLoop *lof_array = (OrigSpaceLoop *)CustomData_get_layer(&mesh->ldata,
CD_ORIGSPACE_MLOOP);
OrigSpaceLoop *lof_array = (OrigSpaceLoop *)CustomData_get_layer_for_write(
&mesh->ldata, CD_ORIGSPACE_MLOOP, mesh->totloop);
const int numpoly = mesh->totpoly;
// const int numloop = mesh->totloop;
const Span<float3> positions = mesh->vert_positions();

View File

@ -340,11 +340,11 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner)
void *data = nullptr;
if (stored_as_named_attribute_) {
data = CustomData_duplicate_referenced_layer_named(
data = CustomData_get_layer_named_for_write(
custom_data, stored_type_, name_.c_str(), element_num);
}
else {
data = CustomData_duplicate_referenced_layer(custom_data, stored_type_, element_num);
data = CustomData_get_layer_for_write(custom_data, stored_type_, element_num);
}
if (data == nullptr) {
return {};
@ -461,7 +461,7 @@ GAttributeWriter CustomDataAttributeProvider::try_get_for_write(
if (!custom_data_layer_matches_attribute_id(layer, attribute_id)) {
continue;
}
CustomData_duplicate_referenced_layer_named(custom_data, layer.type, layer.name, element_num);
CustomData_get_layer_named_for_write(custom_data, layer.type, layer.name, element_num);
const CPPType *type = custom_data_type_to_cpp_type((eCustomDataType)layer.type);
if (type == nullptr) {

View File

@ -221,13 +221,14 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop);
CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly);
cddm->vert_positions = CustomData_get_layer_named(&dm->vertData, CD_PROP_FLOAT3, "position");
cddm->vert_positions = CustomData_get_layer_named_for_write(
&dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert);
/* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing
* or dirty normals. */
cddm->vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
cddm->medge = CustomData_get_layer_for_write(&dm->edgeData, CD_MEDGE, mesh->totedge);
cddm->mloop = CustomData_get_layer_for_write(&dm->loopData, CD_MLOOP, mesh->totloop);
cddm->mpoly = CustomData_get_layer_for_write(&dm->polyData, CD_MPOLY, mesh->totpoly);
#if 0
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
#else

View File

@ -216,8 +216,7 @@ static MutableSpan<T> get_mutable_attribute(CurvesGeometry &curves,
const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>());
CustomData &custom_data = domain_custom_data(curves, domain);
T *data = (T *)CustomData_duplicate_referenced_layer_named(
&custom_data, type, name.c_str(), num);
T *data = (T *)CustomData_get_layer_named_for_write(&custom_data, type, name.c_str(), num);
if (data != nullptr) {
return {data, num};
}

View File

@ -3052,35 +3052,6 @@ static void *customData_duplicate_referenced_layer_index(CustomData *data,
return layer->data;
}
void *CustomData_duplicate_referenced_layer(CustomData *data, const int type, const int totelem)
{
int layer_index = CustomData_get_active_layer_index(data, type);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
void *CustomData_duplicate_referenced_layer_n(CustomData *data,
const int type,
const int n,
const int totelem)
{
/* get the layer index of the desired layer */
int layer_index = CustomData_get_layer_index_n(data, type, n);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
void *CustomData_duplicate_referenced_layer_named(CustomData *data,
const int type,
const char *name,
const int totelem)
{
/* get the layer index of the desired layer */
int layer_index = CustomData_get_named_layer_index(data, type, name);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem)
{
for (int i = 0; i < data->totlayer; i++) {
@ -3089,18 +3060,6 @@ void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem)
}
}
bool CustomData_is_referenced_layer(CustomData *data, const int type)
{
int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) {
return false;
}
CustomDataLayer *layer = &data->layers[layer_index];
return (layer->flag & CD_FLAG_NOFREE) != 0;
}
void CustomData_free_temporary(CustomData *data, const int totelem)
{
int i, j;
@ -3415,20 +3374,21 @@ void CustomData_swap(CustomData *data, const int index_a, const int index_b)
}
}
void *CustomData_get(const CustomData *data, const int index, const int type)
void *CustomData_get_for_write(CustomData *data, const int index, const int type, int totelem)
{
BLI_assert(index >= 0);
void *layer_data = CustomData_get_layer(data, type);
void *layer_data = CustomData_get_layer_for_write(data, type, totelem);
if (!layer_data) {
return nullptr;
}
return POINTER_OFFSET(layer_data, size_t(index) * layerType_getInfo(type)->size);
}
void *CustomData_get_n(const CustomData *data, const int type, const int index, const int n)
void *CustomData_get_n_for_write(
CustomData *data, const int type, const int index, const int n, int totelem)
{
BLI_assert(index >= 0);
void *layer_data = CustomData_get_layer_n(data, type, n);
void *layer_data = CustomData_get_layer_n_for_write(data, type, n, totelem);
if (!layer_data) {
return nullptr;
}
@ -3436,7 +3396,7 @@ void *CustomData_get_n(const CustomData *data, const int type, const int index,
return POINTER_OFFSET(layer_data, size_t(index) * layerType_getInfo(type)->size);
}
void *CustomData_get_layer(const CustomData *data, const int type)
const void *CustomData_get_layer(const CustomData *data, const int type)
{
int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) {
@ -3446,7 +3406,13 @@ void *CustomData_get_layer(const CustomData *data, const int type)
return data->layers[layer_index].data;
}
void *CustomData_get_layer_n(const CustomData *data, const int type, const int n)
void *CustomData_get_layer_for_write(CustomData *data, const int type, const int totelem)
{
const int layer_index = CustomData_get_active_layer_index(data, type);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
const void *CustomData_get_layer_n(const CustomData *data, const int type, const int n)
{
int layer_index = CustomData_get_layer_index_n(data, type, n);
if (layer_index == -1) {
@ -3456,7 +3422,16 @@ void *CustomData_get_layer_n(const CustomData *data, const int type, const int n
return data->layers[layer_index].data;
}
void *CustomData_get_layer_named(const CustomData *data, const int type, const char *name)
void *CustomData_get_layer_n_for_write(CustomData *data,
const int type,
const int n,
const int totelem)
{
const int layer_index = CustomData_get_layer_index_n(data, type, n);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
const void *CustomData_get_layer_named(const CustomData *data, const int type, const char *name)
{
int layer_index = CustomData_get_named_layer_index(data, type, name);
if (layer_index == -1) {
@ -3466,6 +3441,15 @@ void *CustomData_get_layer_named(const CustomData *data, const int type, const c
return data->layers[layer_index].data;
}
void *CustomData_get_layer_named_for_write(CustomData *data,
const int type,
const char *name,
const int totelem)
{
const int layer_index = CustomData_get_named_layer_index(data, type, name);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
int CustomData_get_offset(const CustomData *data, const int type)
{
int layer_index = CustomData_get_active_layer_index(data, type);

View File

@ -277,10 +277,11 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
float(*loop_nors_dst)[3];
short(*custom_nors_dst)[2] = static_cast<short(*)[2]>(
CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL));
CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->totloop));
/* Cache loop nors into a temp CDLayer. */
loop_nors_dst = static_cast<float(*)[3]>(CustomData_get_layer(ldata_dst, CD_NORMAL));
loop_nors_dst = static_cast<float(*)[3]>(
CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->totloop));
const bool do_loop_nors_dst = (loop_nors_dst == nullptr);
if (do_loop_nors_dst) {
loop_nors_dst = static_cast<float(*)[3]>(
@ -337,9 +338,9 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/,
const float(*poly_nors_dst)[3] = BKE_mesh_poly_normals_ensure(me_dst);
float(*loop_nors_dst)[3] = static_cast<float(*)[3]>(
CustomData_get_layer(ldata_dst, CD_NORMAL));
CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->totloop));
short(*custom_nors_dst)[2] = static_cast<short(*)[2]>(
CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL));
CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->totloop));
if (!custom_nors_dst) {
custom_nors_dst = static_cast<short(*)[2]>(CustomData_add_layer(
@ -512,9 +513,8 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map
const int num_elem_dst,
const bool use_create,
const bool use_delete,
CustomData *cd_src,
const CustomData *cd_src,
CustomData *cd_dst,
const bool use_dupref_dst,
const int tolayers,
const bool *use_layers_src,
const int num_layers_src,
@ -571,15 +571,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map
continue;
}
data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
/* If dest is a evaluated mesh (from modifier),
* we do not want to overwrite cdlayers of orig mesh! */
if (use_dupref_dst) {
data_dst = CustomData_duplicate_referenced_layer_n(
cd_dst, cddata_type, idx_src, num_elem_dst);
}
else {
data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_src);
}
data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_src, num_elem_dst);
data_transfer_layersmapping_add_item_cd(r_map,
cddata_type,
mix_mode,
@ -627,15 +619,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map
data_dst_to_delete[idx_dst] = false;
}
if (r_map) {
/* If dest is a evaluated mesh (from modifier),
* we do not want to overwrite cdlayers of orig mesh! */
if (use_dupref_dst) {
data_dst = CustomData_duplicate_referenced_layer_n(
cd_dst, cddata_type, idx_dst, num_elem_dst);
}
else {
data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
}
data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
data_transfer_layersmapping_add_item_cd(r_map,
cddata_type,
mix_mode,
@ -677,9 +661,8 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map,
const int num_elem_dst,
const bool use_create,
const bool use_delete,
CustomData *cd_src,
const CustomData *cd_src,
CustomData *cd_dst,
const bool use_dupref_dst,
const int fromlayers,
const int tolayers,
cd_datatransfer_interp interp,
@ -697,18 +680,13 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map,
return true;
}
data_dst = CustomData_get_layer(cd_dst, cddata_type);
data_dst = CustomData_get_layer_for_write(cd_dst, cddata_type, num_elem_dst);
if (!data_dst) {
if (!use_create) {
return true;
}
data_dst = CustomData_add_layer(cd_dst, cddata_type, CD_SET_DEFAULT, nullptr, num_elem_dst);
}
else if (use_dupref_dst && r_map) {
/* If dest is a evaluated mesh (from modifier),
* we do not want to overwrite cdlayers of orig mesh! */
data_dst = CustomData_duplicate_referenced_layer(cd_dst, cddata_type, num_elem_dst);
}
if (r_map) {
data_transfer_layersmapping_add_item_cd(r_map,
@ -740,15 +718,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map,
if (tolayers >= 0) { /* Real-layer index */
idx_dst = tolayers;
/* If dest is a evaluated mesh (from modifier),
* we do not want to overwrite cdlayers of orig mesh! */
if (use_dupref_dst && r_map) {
data_dst = CustomData_duplicate_referenced_layer_n(
cd_dst, cddata_type, idx_dst, num_elem_dst);
}
else {
data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
}
data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
}
else if (tolayers == DT_LAYERS_ACTIVE_DST) {
if ((idx_dst = CustomData_get_active_layer(cd_dst, cddata_type)) == -1) {
@ -759,15 +729,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map,
cd_dst, cddata_type, CD_SET_DEFAULT, nullptr, num_elem_dst);
}
else {
/* If dest is a evaluated mesh (from modifier),
* we do not want to overwrite cdlayers of orig mesh! */
if (use_dupref_dst && r_map) {
data_dst = CustomData_duplicate_referenced_layer_n(
cd_dst, cddata_type, idx_dst, num_elem_dst);
}
else {
data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
}
data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
}
}
else if (tolayers == DT_LAYERS_INDEX_DST) {
@ -782,15 +744,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map,
CustomData_add_layer(cd_dst, cddata_type, CD_SET_DEFAULT, nullptr, num_elem_dst);
}
}
/* If dest is a evaluated mesh (from modifier),
* we do not want to overwrite cdlayers of orig mesh! */
if (use_dupref_dst && r_map) {
data_dst = CustomData_duplicate_referenced_layer_n(
cd_dst, cddata_type, idx_dst, num_elem_dst);
}
else {
data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
}
data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
}
else if (tolayers == DT_LAYERS_NAME_DST) {
const char *name = CustomData_get_layer_name(cd_src, cddata_type, idx_src);
@ -802,15 +756,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map,
cd_dst, cddata_type, CD_SET_DEFAULT, nullptr, num_elem_dst, name);
idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name);
}
/* If dest is a evaluated mesh (from modifier),
* we do not want to overwrite cdlayers of orig mesh! */
if (use_dupref_dst && r_map) {
data_dst = CustomData_duplicate_referenced_layer_n(
cd_dst, cddata_type, idx_dst, num_elem_dst);
}
else {
data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
}
data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
}
else {
return false;
@ -853,7 +799,6 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map,
use_delete,
cd_src,
cd_dst,
use_dupref_dst,
tolayers,
use_layers_src,
num_src,
@ -909,7 +854,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
use_delete,
cd_src,
cd_dst,
me_dst != ob_dst->data,
fromlayers,
tolayers,
interp,
@ -962,7 +906,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
use_delete,
cd_src,
cd_dst,
me_dst != ob_dst->data,
fromlayers,
tolayers,
interp,
@ -1007,7 +950,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_factor,
mix_weights,
CustomData_get_layer_named(&me_src->edata, CD_PROP_BOOL, "sharp_edge"),
CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge"),
CustomData_get_layer_named_for_write(
&me_dst->edata, CD_PROP_BOOL, "sharp_edge", me_dst->totedge),
interp,
interp_data);
return true;
@ -1040,7 +984,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
use_delete,
cd_src,
cd_dst,
me_dst != ob_dst->data,
fromlayers,
tolayers,
interp,
@ -1072,7 +1015,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
use_delete,
cd_src,
cd_dst,
me_dst != ob_dst->data,
fromlayers,
tolayers,
interp,

View File

@ -46,7 +46,7 @@ bool data_transfer_layersmapping_vgroups(struct ListBase *r_map,
bool use_delete,
struct Object *ob_src,
struct Object *ob_dst,
struct CustomData *cd_src,
const struct CustomData *cd_src,
struct CustomData *cd_dst,
bool use_dupref_dst,
int fromlayers,

View File

@ -1217,7 +1217,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
Object *ob_dst,
const MDeformVert *data_src,
MDeformVert *data_dst,
CustomData *UNUSED(cd_src),
const CustomData *UNUSED(cd_src),
CustomData *cd_dst,
const bool UNUSED(use_dupref_dst),
const int tolayers,
@ -1365,7 +1365,7 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map,
const bool use_delete,
Object *ob_src,
Object *ob_dst,
CustomData *cd_src,
const CustomData *cd_src,
CustomData *cd_dst,
const bool use_dupref_dst,
const int fromlayers,
@ -1395,10 +1395,10 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map,
const MDeformVert *data_src = CustomData_get_layer(cd_src, CD_MDEFORMVERT);
MDeformVert *data_dst = CustomData_get_layer(cd_dst, CD_MDEFORMVERT);
MDeformVert *data_dst = CustomData_get_layer_for_write(cd_dst, CD_MDEFORMVERT, num_elem_dst);
if (data_dst && use_dupref_dst && r_map) {
/* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
data_dst = CustomData_duplicate_referenced_layer(cd_dst, CD_MDEFORMVERT, num_elem_dst);
data_dst = CustomData_get_layer_for_write(cd_dst, CD_MDEFORMVERT, num_elem_dst);
}
if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {

View File

@ -1934,8 +1934,8 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
}
/* paint layer */
MLoopCol *mloopcol = CustomData_get_layer_named(
&result->ldata, CD_PROP_BYTE_COLOR, surface->output_name);
MLoopCol *mloopcol = CustomData_get_layer_named_for_write(
&result->ldata, CD_PROP_BYTE_COLOR, surface->output_name, result->totloop);
/* if output layer is lost from a constructive modifier, re-add it */
if (!mloopcol && dynamicPaint_outputLayerExists(surface, ob, 0)) {
mloopcol = CustomData_add_layer_named(&result->ldata,
@ -1947,8 +1947,8 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
}
/* wet layer */
MLoopCol *mloopcol_wet = CustomData_get_layer_named(
&result->ldata, CD_PROP_BYTE_COLOR, surface->output_name2);
MLoopCol *mloopcol_wet = CustomData_get_layer_named_for_write(
&result->ldata, CD_PROP_BYTE_COLOR, surface->output_name2, result->totloop);
/* if output layer is lost from a constructive modifier, re-add it */
if (!mloopcol_wet && dynamicPaint_outputLayerExists(surface, ob, 1)) {
mloopcol_wet = CustomData_add_layer_named(&result->ldata,
@ -1978,7 +1978,8 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
/* vertex group paint */
else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
int defgrp_index = BKE_object_defgroup_name_index(ob, surface->output_name);
MDeformVert *dvert = CustomData_get_layer(&result->vdata, CD_MDEFORMVERT);
MDeformVert *dvert = CustomData_get_layer_for_write(
&result->vdata, CD_MDEFORMVERT, result->totvert);
float *weight = (float *)sData->type_data;
/* apply weights into a vertex group, if doesn't exists add a new layer */

View File

@ -984,26 +984,26 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
});
}
void materialize(IndexMask mask, MutableSpan<float> r_span) const override
void materialize(IndexMask mask, float *dst) const override
{
if (dverts_ == nullptr) {
return r_span.fill_indices(mask, 0.0f);
mask.foreach_index([&](const int i) { dst[i] = 0.0f; });
}
threading::parallel_for(mask.index_range(), 4096, [&](const IndexRange range) {
for (const int64_t i : mask.slice(range)) {
if (const MDeformWeight *weight = this->find_weight_at_index(i)) {
r_span[i] = weight->weight;
dst[i] = weight->weight;
}
else {
r_span[i] = 0.0f;
dst[i] = 0.0f;
}
}
});
}
void materialize_to_uninitialized(IndexMask mask, MutableSpan<float> r_span) const override
void materialize_to_uninitialized(IndexMask mask, float *dst) const override
{
this->materialize(mask, r_span);
this->materialize(mask, dst);
}
private:

View File

@ -50,6 +50,8 @@ static size_t idp_size_table[] = {
sizeof(ListBase), /* Group type. */
sizeof(void *),
sizeof(double),
0,
sizeof(int8_t), /* Boolean type. */
};
/* -------------------------------------------------------------------- */
@ -272,6 +274,12 @@ IDPropertyUIData *IDP_ui_data_copy(const IDProperty *prop)
dst->default_array = MEM_dupallocN(src->default_array);
break;
}
case IDP_UI_DATA_TYPE_BOOLEAN: {
const IDPropertyUIDataBool *src = (const IDPropertyUIDataBool *)prop->ui_data;
IDPropertyUIDataBool *dst = (IDPropertyUIDataBool *)dst_ui_data;
dst->default_array = MEM_dupallocN(src->default_array);
break;
}
case IDP_UI_DATA_TYPE_FLOAT: {
const IDPropertyUIDataFloat *src = (const IDPropertyUIDataFloat *)prop->ui_data;
IDPropertyUIDataFloat *dst = (IDPropertyUIDataFloat *)dst_ui_data;
@ -497,6 +505,7 @@ void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src)
case IDP_INT:
case IDP_FLOAT:
case IDP_DOUBLE:
case IDP_BOOLEAN:
other->data = prop->data;
break;
case IDP_GROUP:
@ -708,6 +717,8 @@ int IDP_coerce_to_int_or_zero(const IDProperty *prop)
return (int)IDP_Double(prop);
case IDP_FLOAT:
return (int)IDP_Float(prop);
case IDP_BOOLEAN:
return (int)IDP_Bool(prop);
default:
return 0;
}
@ -722,6 +733,8 @@ double IDP_coerce_to_double_or_zero(const IDProperty *prop)
return (double)IDP_Float(prop);
case IDP_INT:
return (double)IDP_Int(prop);
case IDP_BOOLEAN:
return (double)IDP_Bool(prop);
default:
return 0.0;
}
@ -736,6 +749,8 @@ float IDP_coerce_to_float_or_zero(const IDProperty *prop)
return (float)IDP_Double(prop);
case IDP_INT:
return (float)IDP_Int(prop);
case IDP_BOOLEAN:
return (float)IDP_Bool(prop);
default:
return 0.0f;
}
@ -826,6 +841,8 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
return (IDP_Float(prop1) == IDP_Float(prop2));
case IDP_DOUBLE:
return (IDP_Double(prop1) == IDP_Double(prop2));
case IDP_BOOLEAN:
return (IDP_Bool(prop1) == IDP_Bool(prop2));
case IDP_STRING: {
return ((prop1->len == prop2->len) &&
STREQLEN(IDP_String(prop1), IDP_String(prop2), (size_t)prop1->len));
@ -899,9 +916,12 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
prop = MEM_callocN(sizeof(IDProperty), "IDProperty double");
*(double *)&prop->data.val = val->d;
break;
case IDP_BOOLEAN:
prop = MEM_callocN(sizeof(IDProperty), "IDProperty boolean");
prop->data.val = (bool)val->i;
break;
case IDP_ARRAY: {
/* for now, we only support float and int and double arrays */
if (ELEM(val->array.type, IDP_FLOAT, IDP_INT, IDP_DOUBLE, IDP_GROUP)) {
if (ELEM(val->array.type, IDP_FLOAT, IDP_INT, IDP_DOUBLE, IDP_GROUP, IDP_BOOLEAN)) {
prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
prop->subtype = val->array.type;
if (val->array.len) {
@ -1004,6 +1024,14 @@ void IDP_ui_data_free_unique_contents(IDPropertyUIData *ui_data,
}
break;
}
case IDP_UI_DATA_TYPE_BOOLEAN: {
const IDPropertyUIDataBool *other_bool = (const IDPropertyUIDataBool *)other;
IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)ui_data;
if (ui_data_bool->default_array != other_bool->default_array) {
MEM_SAFE_FREE(ui_data_bool->default_array);
}
break;
}
case IDP_UI_DATA_TYPE_FLOAT: {
const IDPropertyUIDataFloat *other_float = (const IDPropertyUIDataFloat *)other;
IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)ui_data;
@ -1034,6 +1062,11 @@ void IDP_ui_data_free(IDProperty *prop)
MEM_SAFE_FREE(ui_data_int->default_array);
break;
}
case IDP_UI_DATA_TYPE_BOOLEAN: {
IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)prop->ui_data;
MEM_SAFE_FREE(ui_data_bool->default_array);
break;
}
case IDP_UI_DATA_TYPE_FLOAT: {
IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)prop->ui_data;
MEM_SAFE_FREE(ui_data_float->default_array);
@ -1173,6 +1206,16 @@ static void write_ui_data(const IDProperty *prop, BlendWriter *writer)
BLO_write_struct(writer, IDPropertyUIDataInt, ui_data);
break;
}
case IDP_UI_DATA_TYPE_BOOLEAN: {
IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)ui_data;
if (prop->type == IDP_ARRAY) {
BLO_write_int8_array(writer,
(uint)ui_data_bool->default_array_len,
(const int8_t *)ui_data_bool->default_array);
}
BLO_write_struct(writer, IDPropertyUIDataBool, ui_data);
break;
}
case IDP_UI_DATA_TYPE_FLOAT: {
IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)ui_data;
if (prop->type == IDP_ARRAY) {
@ -1285,6 +1328,14 @@ static void read_ui_data(IDProperty *prop, BlendDataReader *reader)
}
break;
}
case IDP_UI_DATA_TYPE_BOOLEAN: {
IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)prop->ui_data;
if (prop->type == IDP_ARRAY) {
BLO_read_int8_array(
reader, ui_data_bool->default_array_len, (int8_t **)&ui_data_bool->default_array);
}
break;
}
case IDP_UI_DATA_TYPE_FLOAT: {
IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)prop->ui_data;
if (prop->type == IDP_ARRAY) {
@ -1336,10 +1387,13 @@ static void IDP_DirectLinkArray(IDProperty *prop, BlendDataReader *reader)
else if (prop->subtype == IDP_DOUBLE) {
BLO_read_double_array(reader, prop->len, (double **)&prop->data.pointer);
}
else {
else if (ELEM(prop->subtype, IDP_INT, IDP_FLOAT)) {
/* also used for floats */
BLO_read_int32_array(reader, prop->len, (int **)&prop->data.pointer);
}
else if (prop->subtype == IDP_BOOLEAN) {
BLO_read_int8_array(reader, prop->len, (int8_t **)&prop->data.pointer);
}
}
static void IDP_DirectLinkString(IDProperty *prop, BlendDataReader *reader)
@ -1392,6 +1446,7 @@ static void IDP_DirectLinkProperty(IDProperty *prop, BlendDataReader *reader)
break;
case IDP_INT:
case IDP_FLOAT:
case IDP_BOOLEAN:
case IDP_ID:
break; /* Nothing special to do here. */
default:
@ -1502,6 +1557,9 @@ eIDPropertyUIDataType IDP_ui_data_type(const IDProperty *prop)
(prop->type == IDP_ARRAY && ELEM(prop->subtype, IDP_FLOAT, IDP_DOUBLE))) {
return IDP_UI_DATA_TYPE_FLOAT;
}
if (prop->type == IDP_BOOLEAN || (prop->type == IDP_ARRAY && prop->subtype == IDP_BOOLEAN)) {
return IDP_UI_DATA_TYPE_BOOLEAN;
}
return IDP_UI_DATA_TYPE_UNSUPPORTED;
}
@ -1536,6 +1594,11 @@ IDPropertyUIData *IDP_ui_data_ensure(IDProperty *prop)
prop->ui_data = (IDPropertyUIData *)ui_data;
break;
}
case IDP_UI_DATA_TYPE_BOOLEAN: {
IDPropertyUIDataBool *ui_data = MEM_callocN(sizeof(IDPropertyUIDataBool), __func__);
prop->ui_data = (IDPropertyUIData *)ui_data;
break;
}
case IDP_UI_DATA_TYPE_FLOAT: {
IDPropertyUIDataFloat *ui_data = MEM_callocN(sizeof(IDPropertyUIDataFloat), __func__);
ui_data->min = -FLT_MAX;

View File

@ -111,6 +111,10 @@ static void idp_repr_fn_recursive(struct ReprState *state, const IDProperty *pro
STR_APPEND_FMT("%g", IDP_Double(prop));
break;
}
case IDP_BOOLEAN: {
STR_APPEND_FMT("%s", IDP_Bool(prop) ? "True" : "False");
break;
}
case IDP_ARRAY: {
STR_APPEND_STR("[");
switch (prop->subtype) {
@ -138,6 +142,14 @@ static void idp_repr_fn_recursive(struct ReprState *state, const IDProperty *pro
STR_APPEND_FMT("%g", *v);
}
break;
case IDP_BOOLEAN:
for (const double *v = prop->data.pointer, *v_end = v + prop->len; v != v_end; v++) {
if (v != prop->data.pointer) {
STR_APPEND_STR(", ");
}
STR_APPEND_FMT("%s", IDP_Bool(prop) ? "True" : "False");
}
break;
}
STR_APPEND_STR("]");
break;

View File

@ -2222,7 +2222,7 @@ void BKE_keyblock_convert_to_mesh(const KeyBlock *kb,
}
void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
const Mesh *mesh,
Mesh *mesh,
float (*r_vert_normals)[3],
float (*r_poly_normals)[3],
float (*r_loop_normals)[3])
@ -2272,8 +2272,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
vert_normals);
}
if (loop_normals_needed) {
short(*clnors)[2] = static_cast<short(*)[2]>(
CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL)); /* May be nullptr. */
short(*clnors)[2] = static_cast<short(*)[2]>(CustomData_get_layer_for_write(
&mesh->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop)); /* May be nullptr. */
const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"));
BKE_mesh_normals_loop_split(positions,

View File

@ -1601,7 +1601,7 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
/* don't update normals, caller can do this explicitly.
* We do update loop normals though, those may not be auto-generated
* (see e.g. STL import script)! */
float(*lnors)[3] = (float(*)[3])CustomData_duplicate_referenced_layer(
float(*lnors)[3] = (float(*)[3])CustomData_get_layer_for_write(
&me->ldata, CD_NORMAL, me->totloop);
if (lnors) {
float m3[3][3];
@ -1815,7 +1815,8 @@ static float (*ensure_corner_normal_layer(Mesh &mesh))[3]
{
float(*r_loop_normals)[3];
if (CustomData_has_layer(&mesh.ldata, CD_NORMAL)) {
r_loop_normals = (float(*)[3])CustomData_get_layer(&mesh.ldata, CD_NORMAL);
r_loop_normals = (float(*)[3])CustomData_get_layer_for_write(
&mesh.ldata, CD_NORMAL, mesh.totloop);
memset(r_loop_normals, 0, sizeof(float[3]) * mesh.totloop);
}
else {
@ -1838,7 +1839,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI);
/* may be nullptr */
short(*clnors)[2] = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
short(*clnors)[2] = (short(*)[2])CustomData_get_layer_for_write(
&mesh->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop);
const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"));

View File

@ -641,11 +641,14 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
}
int source_layer_type_index = source_layer_i - source_cd->typemap[ty];
BLI_assert(target_layer_type_index != -1 && source_layer_type_index >= 0);
const int size = CustomData_sizeof(ty);
for (int j = 0; j < orig_mp->totloop; ++j) {
src_blocks_ofs[j] = CustomData_get_n(
source_cd, ty, orig_mp->loopstart + j, source_layer_type_index);
const void *layer = CustomData_get_layer_n(source_cd, ty, source_layer_type_index);
src_blocks_ofs[j] = POINTER_OFFSET(layer, size * (orig_mp->loopstart + j));
}
void *dst_block_ofs = CustomData_get_n(target_cd, ty, loop_index, target_layer_type_index);
void *dst_layer = CustomData_get_layer_n_for_write(
target_cd, ty, target_layer_type_index, dest_mesh->totloop);
void *dst_block_ofs = POINTER_OFFSET(dst_layer, size * loop_index);
CustomData_bmesh_interp_n(target_cd,
src_blocks_ofs.data(),
weights.data(),

View File

@ -595,15 +595,15 @@ void BKE_mesh_polygon_flip_ex(const MPoly *mpoly,
}
}
void BKE_mesh_polygon_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata)
void BKE_mesh_polygon_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata, const int totloop)
{
MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS);
MDisps *mdisp = (MDisps *)CustomData_get_layer_for_write(ldata, CD_MDISPS, totloop);
BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, nullptr, mdisp, true);
}
void BKE_mesh_polys_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly)
{
MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS);
MDisps *mdisp = (MDisps *)CustomData_get_layer_for_write(ldata, CD_MDISPS, totpoly);
const MPoly *mp;
int i;

View File

@ -289,6 +289,7 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
static void bm_corners_to_loops_ex(ID *id,
CustomData *fdata,
const int totface,
CustomData *ldata,
MFace *mface,
int totloop,
@ -300,10 +301,11 @@ static void bm_corners_to_loops_ex(ID *id,
MFace *mf = mface + findex;
for (int i = 0; i < numTex; i++) {
const MTFace *texface = (const MTFace *)CustomData_get_n(fdata, CD_MTFACE, findex, i);
const MTFace *texface = (const MTFace *)CustomData_get_n_for_write(
fdata, CD_MTFACE, findex, i, totface);
blender::float2 *uv = static_cast<blender::float2 *>(
CustomData_get_n(ldata, CD_PROP_FLOAT2, loopstart, i));
CustomData_get_n_for_write(ldata, CD_PROP_FLOAT2, loopstart, i, totloop));
copy_v2_v2(*uv, texface->uv[0]);
uv++;
copy_v2_v2(*uv, texface->uv[1]);
@ -318,8 +320,10 @@ static void bm_corners_to_loops_ex(ID *id,
}
for (int i = 0; i < numCol; i++) {
MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n(ldata, CD_PROP_BYTE_COLOR, loopstart, i);
const MCol *mcol = (const MCol *)CustomData_get_n(fdata, CD_MCOL, findex, i);
MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n_for_write(
ldata, CD_PROP_BYTE_COLOR, loopstart, i, totloop);
const MCol *mcol = (const MCol *)CustomData_get_n_for_write(
fdata, CD_MCOL, findex, i, totface);
MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[0]);
mloopcol++;
@ -334,9 +338,10 @@ static void bm_corners_to_loops_ex(ID *id,
}
if (CustomData_has_layer(fdata, CD_TESSLOOPNORMAL)) {
float(*loop_normals)[3] = (float(*)[3])CustomData_get(ldata, loopstart, CD_NORMAL);
const short(*tessloop_normals)[3] = (short(*)[3])CustomData_get(
fdata, findex, CD_TESSLOOPNORMAL);
float(*loop_normals)[3] = (float(*)[3])CustomData_get_for_write(
ldata, loopstart, CD_NORMAL, totloop);
const short(*tessloop_normals)[3] = (short(*)[3])CustomData_get_for_write(
fdata, findex, CD_TESSLOOPNORMAL, totface);
const int max = mf->v4 ? 4 : 3;
for (int i = 0; i < max; i++, loop_normals++, tessloop_normals++) {
@ -345,8 +350,8 @@ static void bm_corners_to_loops_ex(ID *id,
}
if (CustomData_has_layer(fdata, CD_MDISPS)) {
MDisps *ld = (MDisps *)CustomData_get(ldata, loopstart, CD_MDISPS);
const MDisps *fd = (const MDisps *)CustomData_get(fdata, findex, CD_MDISPS);
MDisps *ld = (MDisps *)CustomData_get_for_write(ldata, loopstart, CD_MDISPS, totloop);
const MDisps *fd = (const MDisps *)CustomData_get_for_write(fdata, findex, CD_MDISPS, totface);
const float(*disps)[3] = fd->disps;
int tot = mf->v4 ? 4 : 3;
int corners;
@ -443,7 +448,7 @@ static void convert_mfaces_to_mpolys(ID *id,
totpoly = totface_i;
mpoly = (MPoly *)CustomData_add_layer(pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, totpoly);
int *material_indices = static_cast<int *>(
CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index"));
CustomData_get_layer_named_for_write(pdata, CD_PROP_INT32, "material_index", totpoly));
if (material_indices == nullptr) {
material_indices = static_cast<int *>(CustomData_add_layer_named(
pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, totpoly, "material_index"));
@ -515,7 +520,8 @@ static void convert_mfaces_to_mpolys(ID *id,
#undef ML
bm_corners_to_loops_ex(id, fdata, ldata, mface, totloop, i, mp->loopstart, numTex, numCol);
bm_corners_to_loops_ex(
id, fdata, totface_i, ldata, mface, totloop, i, mp->loopstart, numTex, numCol);
if (polyindex) {
*polyindex = i;
@ -804,7 +810,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata,
uint(*lidx)[4];
for (i = 0; i < numUV; i++) {
MTFace *texface = (MTFace *)CustomData_get_layer_n(fdata, CD_MTFACE, i);
MTFace *texface = (MTFace *)CustomData_get_layer_n_for_write(fdata, CD_MTFACE, i, num_faces);
const blender::float2 *uv = static_cast<const blender::float2 *>(
CustomData_get_layer_n(ldata, CD_PROP_FLOAT2, i));
@ -817,7 +823,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata,
}
for (i = 0; i < numCol; i++) {
MCol(*mcol)[4] = (MCol(*)[4])CustomData_get_layer_n(fdata, CD_MCOL, i);
MCol(*mcol)[4] = (MCol(*)[4])CustomData_get_layer_n_for_write(fdata, CD_MCOL, i, num_faces);
const MLoopCol *mloopcol = (const MLoopCol *)CustomData_get_layer_n(
ldata, CD_PROP_BYTE_COLOR, i);
@ -1835,7 +1841,7 @@ void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh)
using namespace blender;
using namespace blender::bke;
const Span<MVert> verts(static_cast<MVert *>(CustomData_get_layer(&mesh->vdata, CD_MVERT)),
const Span<MVert> verts(static_cast<const MVert *>(CustomData_get_layer(&mesh->vdata, CD_MVERT)),
mesh->totvert);
MutableSpan<float3> positions(
static_cast<float3 *>(CustomData_add_layer_named(

View File

@ -125,7 +125,8 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me)
Vector<float2 *> mloopuv_layers;
mloopuv_layers.reserve(mloopuv_layers_num);
for (int a = 0; a < mloopuv_layers_num; a++) {
float2 *mloopuv = static_cast<float2 *>(CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, a));
float2 *mloopuv = static_cast<float2 *>(
CustomData_get_layer_n_for_write(&me->ldata, CD_PROP_FLOAT2, a, me->totloop));
mloopuv_layers.append_unchecked(mloopuv);
}

View File

@ -298,7 +298,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
totshape = CustomData_number_of_layers(&result->vdata, CD_SHAPEKEY);
for (a = 0; a < totshape; a++) {
float(*cos)[3] = static_cast<float(*)[3]>(
CustomData_get_layer_n(&result->vdata, CD_SHAPEKEY, a));
CustomData_get_layer_n_for_write(&result->vdata, CD_SHAPEKEY, a, result->totvert));
for (i = maxVerts; i < result->totvert; i++) {
mul_m4_v3(mtx, cos[i]);
}
@ -361,7 +361,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
for (a = 0; a < totuv; a++) {
float(*dmloopuv)[2] = static_cast<float(*)[2]>(
CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, a));
CustomData_get_layer_n_for_write(&result->ldata, CD_PROP_FLOAT2, a, result->totloop));
int j = maxLoops;
dmloopuv += j; /* second set of loops only */
for (; j-- > 0; dmloopuv++) {
@ -397,7 +397,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
float(*loop_normals)[3] = static_cast<float(*)[3]>(
MEM_calloc_arrayN(size_t(totloop), sizeof(*loop_normals), __func__));
CustomData *ldata = &result->ldata;
short(*clnors)[2] = static_cast<short(*)[2]>(CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL));
short(*clnors)[2] = static_cast<short(*)[2]>(
CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, totloop));
MLoopNorSpaceArray lnors_spacearr = {nullptr};
/* The transform matrix of a normal must be

View File

@ -1913,7 +1913,8 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const
short(*clnors)[2];
const int numloops = mesh->totloop;
clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
clnors = (short(*)[2])CustomData_get_layer_for_write(
&mesh->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop);
if (clnors != nullptr) {
memset(clnors, 0, sizeof(*clnors) * size_t(numloops));
}

View File

@ -1357,10 +1357,11 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
}
if (need_lnors_dst) {
short(*custom_nors_dst)[2] = static_cast<short(*)[2]>(
CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL));
CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, numloops_dst));
/* Cache loop normals into a temporary custom data layer. */
loop_nors_dst = static_cast<float(*)[3]>(CustomData_get_layer(ldata_dst, CD_NORMAL));
loop_nors_dst = static_cast<float(*)[3]>(
CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, numloops_dst));
const bool do_loop_nors_dst = (loop_nors_dst == nullptr);
if (!loop_nors_dst) {
loop_nors_dst = static_cast<float(*)[3]>(

View File

@ -341,22 +341,22 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
do_fixes,
&changed);
is_valid &= BKE_mesh_validate_arrays(
me_eval,
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
static_cast<MFace *>(CustomData_get_layer(&me_eval->fdata, CD_MFACE)),
me_eval->totface,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me_eval->deform_verts_for_write().data(),
do_verbose,
do_fixes,
&changed);
is_valid &= BKE_mesh_validate_arrays(me_eval,
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
static_cast<MFace *>(CustomData_get_layer_for_write(
&me_eval->fdata, CD_MFACE, me_eval->totface)),
me_eval->totface,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me_eval->deform_verts_for_write().data(),
do_verbose,
do_fixes,
&changed);
BLI_assert(changed == false);

View File

@ -1071,21 +1071,22 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
BKE_mesh_validate_arrays(me,
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me->deform_verts_for_write().data(),
do_verbose,
true,
&changed);
BKE_mesh_validate_arrays(
me,
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
(MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface),
me->totface,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me->deform_verts_for_write().data(),
do_verbose,
true,
&changed);
if (changed) {
DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY_ALL_MODES);
@ -1122,21 +1123,22 @@ bool BKE_mesh_is_valid(Mesh *me)
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
is_valid &= BKE_mesh_validate_arrays(me,
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me->deform_verts_for_write().data(),
do_verbose,
do_fixes,
&changed);
is_valid &= BKE_mesh_validate_arrays(
me,
reinterpret_cast<float(*)[3]>(positions.data()),
positions.size(),
edges.data(),
edges.size(),
(MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface),
me->totface,
loops.data(),
loops.size(),
polys.data(),
polys.size(),
me->deform_verts_for_write().data(),
do_verbose,
do_fixes,
&changed);
if (!me->runtime->vert_normals_dirty) {
BLI_assert(me->runtime->vert_normals || me->totvert == 0);
@ -1186,7 +1188,7 @@ void BKE_mesh_strip_loose_faces(Mesh *me)
/* NOTE: We need to keep this for edge creation (for now?), and some old `readfile.c` code. */
MFace *f;
int a, b;
MFace *mfaces = (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE);
MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface);
for (a = b = 0, f = mfaces; a < me->totface; a++, f++) {
if (f->v3) {
@ -1323,7 +1325,7 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
{
const int numFaces = mesh->totface;
EdgeSet *eh = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces));
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface);
MFace *mf = mfaces;
for (int i = 0; i < numFaces; i++, mf++) {
@ -1347,8 +1349,8 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
CustomData_add_layer(&edgeData, CD_MEDGE, CD_SET_DEFAULT, nullptr, numEdges);
CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, numEdges);
MEdge *med = (MEdge *)CustomData_get_layer(&edgeData, CD_MEDGE);
int *index = (int *)CustomData_get_layer(&edgeData, CD_ORIGINDEX);
MEdge *med = (MEdge *)CustomData_get_layer_for_write(&edgeData, CD_MEDGE, mesh->totedge);
int *index = (int *)CustomData_get_layer_for_write(&edgeData, CD_ORIGINDEX, mesh->totedge);
EdgeSetIterator *ehi = BLI_edgesetIterator_new(eh);
for (int i = 0; BLI_edgesetIterator_isDone(ehi) == false;

View File

@ -340,7 +340,7 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
if (use_clnors) {
float(*lnors)[3] = static_cast<float(*)[3]>(
CustomData_get_layer(&subdiv_mesh->ldata, CD_NORMAL));
CustomData_get_layer_for_write(&subdiv_mesh->ldata, CD_NORMAL, subdiv_mesh->totloop));
BLI_assert(lnors != nullptr);
BKE_mesh_set_custom_normals(subdiv_mesh, lnors);
CustomData_set_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);

View File

@ -544,7 +544,8 @@ void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *o
static void multires_set_tot_mdisps(Mesh *me, int lvl)
{
MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
MDisps *mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop));
int i;
if (mdisps) {
@ -663,8 +664,10 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
multires_set_tot_mdisps(me, mmd->totlvl);
multiresModifier_ensure_external_read(me, mmd);
mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
gpm = static_cast<GridPaintMask *>(CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK));
mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop));
gpm = static_cast<GridPaintMask *>(
CustomData_get_layer_for_write(&me->ldata, CD_GRID_PAINT_MASK, me->totloop));
multires_force_sculpt_rebuild(ob);
@ -728,7 +731,8 @@ void multiresModifier_del_levels(MultiresModifierData *mmd,
multires_set_tot_mdisps(me, mmd->totlvl);
multiresModifier_ensure_external_read(me, mmd);
MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
MDisps *mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop));
multires_force_sculpt_rebuild(ob);
@ -965,7 +969,8 @@ static void multiresModifier_disp_run(
CCGElem **gridData, **subGridData;
CCGKey key;
const MPoly *mpoly = BKE_mesh_polys(me);
MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
MDisps *mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop));
GridPaintMask *grid_paint_mask = nullptr;
int *gridOffset;
int i, gridSize, dGridSize, dSkip;
@ -973,8 +978,10 @@ static void multiresModifier_disp_run(
/* this happens in the dm made by bmesh_mdisps_space_set */
if (dm2 && CustomData_has_layer(&dm2->loopData, CD_MDISPS)) {
mpoly = static_cast<const MPoly *>(CustomData_get_layer(&dm2->polyData, CD_MPOLY));
mdisps = static_cast<MDisps *>(CustomData_get_layer(&dm2->loopData, CD_MDISPS));
mpoly = static_cast<const MPoly *>(
CustomData_get_layer_for_write(&dm2->polyData, CD_MPOLY, dm2->getNumPolys(dm)));
mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&dm2->loopData, CD_MDISPS, dm2->getNumLoops(dm)));
totloop = dm2->numLoopData;
totpoly = dm2->numPolyData;
}
@ -1006,7 +1013,7 @@ static void multiresModifier_disp_run(
/* multires paint masks */
if (key.has_mask) {
grid_paint_mask = static_cast<GridPaintMask *>(
CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK));
CustomData_get_layer_for_write(&me->ldata, CD_GRID_PAINT_MASK, me->totloop));
}
/* when adding new faces in edit mode, need to allocate disps */
@ -1176,7 +1183,8 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
BLI_bitmap **grid_hidden = ccgdm->gridHidden;
Mesh *me = static_cast<Mesh *>(ccgdm->multires.ob->data);
MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
MDisps *mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop));
int totlvl = ccgdm->multires.totlvl;
int lvl = ccgdm->multires.lvl;
@ -1395,7 +1403,8 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
static void multires_apply_uniform_scale(Object *object, const float scale)
{
Mesh *mesh = (Mesh *)object->data;
MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&mesh->ldata, CD_MDISPS));
MDisps *mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop));
for (int i = 0; i < mesh->totloop; i++) {
MDisps *grid = &mdisps[i];
for (int j = 0; j < grid->totdisp; j++) {
@ -1479,7 +1488,8 @@ void multires_topology_changed(Mesh *me)
int i, grid = 0;
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
mdisp = static_cast<MDisps *>(CustomData_get_layer(&me->ldata, CD_MDISPS));
mdisp = static_cast<MDisps *>(
CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop));
if (!mdisp) {
return;
@ -1514,7 +1524,8 @@ void multires_ensure_external_read(struct Mesh *mesh, int top_level)
return;
}
MDisps *mdisps = static_cast<MDisps *>(CustomData_get_layer(&mesh->ldata, CD_MDISPS));
MDisps *mdisps = static_cast<MDisps *>(
CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop));
if (mdisps == nullptr) {
mdisps = static_cast<MDisps *>(
CustomData_add_layer(&mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, nullptr, mesh->totloop));

View File

@ -32,7 +32,7 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
const MPoly *polys = BKE_mesh_polys(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
MDisps *mdisps = CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop);
const int totpoly = mesh->totpoly;
for (int p = 0; p < totpoly; p++) {
const MPoly *poly = &polys[p];

View File

@ -103,8 +103,10 @@ static void context_init_lookup(MultiresReshapeContext *reshape_context)
static void context_init_grid_pointers(MultiresReshapeContext *reshape_context)
{
Mesh *base_mesh = reshape_context->base_mesh;
reshape_context->mdisps = CustomData_get_layer(&base_mesh->ldata, CD_MDISPS);
reshape_context->grid_paint_masks = CustomData_get_layer(&base_mesh->ldata, CD_GRID_PAINT_MASK);
reshape_context->mdisps = CustomData_get_layer_for_write(
&base_mesh->ldata, CD_MDISPS, base_mesh->totloop);
reshape_context->grid_paint_masks = CustomData_get_layer_for_write(
&base_mesh->ldata, CD_GRID_PAINT_MASK, base_mesh->totloop);
}
static void context_init_commoon(MultiresReshapeContext *reshape_context)
@ -559,7 +561,7 @@ static void ensure_displacement_grid(MDisps *displacement_grid, const int level)
static void ensure_displacement_grids(Mesh *mesh, const int grid_level)
{
const int num_grids = mesh->totloop;
MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
MDisps *mdisps = CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop);
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
ensure_displacement_grid(&mdisps[grid_index], grid_level);
}
@ -567,7 +569,8 @@ static void ensure_displacement_grids(Mesh *mesh, const int grid_level)
static void ensure_mask_grids(Mesh *mesh, const int level)
{
GridPaintMask *grid_paint_masks = CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK);
GridPaintMask *grid_paint_masks = CustomData_get_layer_for_write(
&mesh->ldata, CD_GRID_PAINT_MASK, mesh->totloop);
if (grid_paint_masks == NULL) {
return;
}

View File

@ -938,7 +938,8 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract(
bm_original_mesh, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
/* Get the mapping data-layer. */
context->base_to_orig_vmap = CustomData_get_layer_named(&base_mesh->vdata, CD_PROP_INT32, vname);
context->base_to_orig_vmap = CustomData_get_layer_named_for_write(
&base_mesh->vdata, CD_PROP_INT32, vname, base_mesh->totvert);
/* Tag the base mesh vertices in the original mesh. */
for (int i = 0; i < base_mesh->totvert; i++) {
@ -1001,7 +1002,8 @@ static void multires_unsubdivide_extract_grids(MultiresUnsubdivideContext *conte
int *orig_to_base_vmap = MEM_calloc_arrayN(bm_original_mesh->totvert, sizeof(int), "orig vmap");
int *base_to_orig_vmap = MEM_calloc_arrayN(base_mesh->totvert, sizeof(int), "base vmap");
context->base_to_orig_vmap = CustomData_get_layer_named(&base_mesh->vdata, CD_PROP_INT32, vname);
context->base_to_orig_vmap = CustomData_get_layer_named_for_write(
&base_mesh->vdata, CD_PROP_INT32, vname, base_mesh->totvert);
for (int i = 0; i < base_mesh->totvert; i++) {
base_to_orig_vmap[i] = context->base_to_orig_vmap[i];
}

View File

@ -1425,9 +1425,11 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
return false;
}
/* Only geometry objects should be able to get modifiers T25291. */
if (ELEM(ob->type, OB_POINTCLOUD, OB_VOLUME, OB_CURVES)) {
return (mti->modifyGeometrySet != nullptr);
if (ELEM(ob->type, OB_POINTCLOUD, OB_CURVES)) {
return modifier_type == eModifierType_Nodes;
}
if (ob->type == OB_VOLUME) {
return mti->modifyGeometrySet != nullptr;
}
if (ELEM(ob->type, OB_MESH, OB_CURVES_LEGACY, OB_SURF, OB_FONT, OB_LATTICE)) {
if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) {

View File

@ -176,7 +176,7 @@ static void object_fmap_remove_object_mode(Object *ob, bFaceMap *fmap, bool purg
Mesh *me = ob->data;
if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP);
int *map = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly);
int i;
if (map) {

View File

@ -1709,7 +1709,8 @@ static void sculpt_update_object(
ss->multires.active = false;
ss->multires.modifier = nullptr;
ss->multires.level = 0;
ss->vmask = static_cast<float *>(CustomData_get_layer(&me->vdata, CD_PAINT_MASK));
ss->vmask = static_cast<float *>(
CustomData_get_layer_for_write(&me->vdata, CD_PAINT_MASK, me->totvert));
CustomDataLayer *layer;
eAttrDomain domain;
@ -1736,14 +1737,15 @@ static void sculpt_update_object(
/* Sculpt Face Sets. */
if (use_face_sets) {
ss->face_sets = static_cast<int *>(
CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, ".sculpt_face_set"));
ss->face_sets = static_cast<int *>(CustomData_get_layer_named_for_write(
&me->pdata, CD_PROP_INT32, ".sculpt_face_set", me->totpoly));
}
else {
ss->face_sets = nullptr;
}
ss->hide_poly = (bool *)CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly");
ss->hide_poly = (bool *)CustomData_get_layer_named_for_write(
&me->pdata, CD_PROP_BOOL, ".hide_poly", me->totpoly);
ss->subdiv_ccg = me_eval->runtime->subdiv_ccg;
@ -1962,14 +1964,14 @@ int *BKE_sculpt_face_sets_ensure(Mesh *mesh)
face_sets.finish();
}
return static_cast<int *>(
CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set"));
return static_cast<int *>(CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly));
}
bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh)
{
bool *hide_poly = static_cast<bool *>(
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"));
bool *hide_poly = static_cast<bool *>(CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly));
if (hide_poly != nullptr) {
return hide_poly;
}

View File

@ -1702,7 +1702,7 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach
void psys_interpolate_face(Mesh *mesh,
const float (*vert_positions)[3],
const float (*vert_normals)[3],
MFace *mface,
const MFace *mface,
MTFace *tface,
const float (*orcodata)[3],
float w[4],
@ -1888,7 +1888,8 @@ static float psys_interpolate_value_from_verts(
return values[index];
case PART_FROM_FACE:
case PART_FROM_VOLUME: {
MFace *mfaces = static_cast<MFace *>(CustomData_get_layer(&mesh->fdata, CD_MFACE));
MFace *mfaces = static_cast<MFace *>(
CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface));
MFace *mf = &mfaces[index];
return interpolate_particle_value(
values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4);
@ -1981,9 +1982,10 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final,
index_mf_to_mpoly_deformed = nullptr;
mtessface_final = static_cast<MFace *>(CustomData_get_layer(&mesh_final->fdata, CD_MFACE));
mtessface_final = static_cast<MFace *>(
CustomData_get_layer_for_write(&mesh_final->fdata, CD_MFACE, mesh_final->totface));
osface_final = static_cast<OrigSpaceFace *>(
CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE));
CustomData_get_layer_for_write(&mesh_final->fdata, CD_ORIGSPACE, mesh_final->totface));
if (osface_final == nullptr) {
/* Assume we don't need osface_final data, and we get a direct 1-1 mapping... */
@ -2102,7 +2104,7 @@ static int psys_map_index_on_dm(Mesh *mesh,
/* modify the original weights to become
* weights for the derived mesh face */
OrigSpaceFace *osface = static_cast<OrigSpaceFace *>(
CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE));
CustomData_get_layer_for_write(&mesh->fdata, CD_ORIGSPACE, mesh->totface));
const MFace *mfaces = static_cast<const MFace *>(
CustomData_get_layer(&mesh->fdata, CD_MFACE));
const MFace *mface = &mfaces[i];
@ -2187,10 +2189,12 @@ void psys_particle_on_dm(Mesh *mesh_final,
MFace *mface;
MTFace *mtface;
MFace *mfaces = static_cast<MFace *>(CustomData_get_layer(&mesh_final->fdata, CD_MFACE));
MFace *mfaces = static_cast<MFace *>(
CustomData_get_layer_for_write(&mesh_final->fdata, CD_MFACE, mesh_final->totface));
mface = &mfaces[mapindex];
const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final);
mtface = static_cast<MTFace *>(CustomData_get_layer(&mesh_final->fdata, CD_MTFACE));
mtface = static_cast<MTFace *>(
CustomData_get_layer_for_write(&mesh_final->fdata, CD_MTFACE, mesh_final->totface));
if (mtface) {
mtface += mapindex;
@ -3893,10 +3897,11 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4]
return;
}
MFace *mfaces = static_cast<MFace *>(CustomData_get_layer(&mesh->fdata, CD_MFACE));
MFace *mfaces = static_cast<MFace *>(
CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface));
mface = &mfaces[i];
const OrigSpaceFace *osface = static_cast<const OrigSpaceFace *>(
CustomData_get(&mesh->fdata, i, CD_ORIGSPACE));
CustomData_get_for_write(&mesh->fdata, i, CD_ORIGSPACE, mesh->totface));
if (orco &&
(orcodata = static_cast<const float(*)[3]>(CustomData_get_layer(&mesh->vdata, CD_ORCO)))) {
@ -4204,7 +4209,7 @@ static int get_particle_uv(Mesh *mesh,
float *texco,
bool from_vert)
{
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface);
MFace *mf;
const MTFace *tf;
int i;
@ -5108,8 +5113,8 @@ void psys_get_dupli_texture(ParticleSystem *psys,
const MTFace *mtface = static_cast<const MTFace *>(
CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx));
if (mtface != nullptr) {
const MFace *mface = static_cast<const MFace *>(
CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE));
const MFace *mface = static_cast<const MFace *>(CustomData_get_for_write(
&psmd->mesh_final->fdata, cpa->num, CD_MFACE, psmd->mesh_final->totface));
mtface += cpa->num;
psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv);
}
@ -5153,8 +5158,8 @@ void psys_get_dupli_texture(ParticleSystem *psys,
if (uv_idx >= 0) {
const MTFace *mtface = static_cast<const MTFace *>(
CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx));
const MFace *mface = static_cast<const MFace *>(
CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE));
const MFace *mface = static_cast<const MFace *>(CustomData_get_for_write(
&psmd->mesh_final->fdata, num, CD_MFACE, psmd->mesh_final->totface));
mtface += num;
psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
}

View File

@ -179,7 +179,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
int amax = from == PART_FROM_FACE ? 3 : 1;
totface = mesh->totface;
mface = mface_array = CustomData_get_layer(&mesh->fdata, CD_MFACE);
mface = mface_array = CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface);
for (a = 0; a < amax; a++) {
if (a == 0) {
@ -462,7 +462,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i
ParticleThreadContext *ctx = thread->ctx;
MFace *mface;
mface = CustomData_get_layer(&ctx->mesh->fdata, CD_MFACE);
mface = CustomData_get_layer_for_write(&ctx->mesh->fdata, CD_MFACE, ctx->mesh->totface);
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
@ -523,7 +523,7 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i
int i;
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface);
MFace *mface;
pa->num = i = ctx->index[p];
@ -578,7 +578,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
pa->num = i = ctx->index[p];
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface);
mface = &mfaces[i];
switch (distr) {
@ -630,7 +630,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
min_d = FLT_MAX;
intersect = 0;
mface = CustomData_get_layer(&mesh->fdata, CD_MFACE);
mface = CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface);
for (i = 0; i < tot; i++, mface++) {
if (i == pa->num) {
continue;
@ -700,7 +700,7 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i
return;
}
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface);
mf = &mfaces[ctx->index[p]];
randu = BLI_rng_get_float(thread->rng);
@ -1053,7 +1053,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO);
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface);
for (i = 0; i < totelem; i++) {
MFace *mf = &mfaces[i];
@ -1114,7 +1114,8 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
}
}
else { /* PART_FROM_FACE / PART_FROM_VOLUME */
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mfaces = (MFace *)CustomData_get_layer_for_write(
&mesh->fdata, CD_MFACE, mesh->totface);
for (i = 0; i < totelem; i++) {
MFace *mf = &mfaces[i];
tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];

View File

@ -825,7 +825,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
pbvh->mesh = mesh;
pbvh->header.type = PBVH_FACES;
pbvh->mpoly = mpoly;
pbvh->hide_poly = (bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly");
pbvh->hide_poly = (bool *)CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly);
pbvh->material_indices = (const int *)CustomData_get_layer_named(
&mesh->pdata, CD_PROP_INT32, "material_index");
pbvh->mloop = mloop;
@ -833,7 +834,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
pbvh->vert_positions = vert_positions;
BKE_mesh_vertex_normals_ensure(mesh);
pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh);
pbvh->hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert");
pbvh->hide_vert = (bool *)CustomData_get_layer_named_for_write(
&mesh->vdata, CD_PROP_BOOL, ".hide_vert", mesh->totvert);
pbvh->vert_bitmap = MEM_calloc_arrayN(totvert, sizeof(bool), "bvh->vert_bitmap");
pbvh->totvert = totvert;
@ -3369,7 +3371,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->vert_normals = pbvh->vert_normals;
vi->hide_vert = pbvh->hide_vert;
vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK);
vi->vmask = CustomData_get_layer_for_write(pbvh->vdata, CD_PAINT_MASK, pbvh->mesh->totvert);
}
}
@ -3456,7 +3458,8 @@ bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh)
if (pbvh->hide_vert) {
return pbvh->hide_vert;
}
pbvh->hide_vert = CustomData_get_layer_named(&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert");
pbvh->hide_vert = CustomData_get_layer_named_for_write(
&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert", pbvh->mesh->totvert);
if (pbvh->hide_vert) {
return pbvh->hide_vert;
}
@ -3478,8 +3481,10 @@ void BKE_pbvh_face_sets_set(PBVH *pbvh, int *face_sets)
void BKE_pbvh_update_hide_attributes_from_mesh(PBVH *pbvh)
{
if (pbvh->header.type == PBVH_FACES) {
pbvh->hide_vert = CustomData_get_layer_named(&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert");
pbvh->hide_poly = CustomData_get_layer_named(&pbvh->mesh->pdata, CD_PROP_BOOL, ".hide_poly");
pbvh->hide_vert = CustomData_get_layer_named_for_write(
&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert", pbvh->mesh->totvert);
pbvh->hide_poly = CustomData_get_layer_named_for_write(
&pbvh->mesh->pdata, CD_PROP_BOOL, ".hide_poly", pbvh->mesh->totpoly);
}
}
@ -3799,8 +3804,8 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
const MPoly *mp = BKE_mesh_polys(mesh);
CCGKey key = pbvh->gridkey;
bool *hide_poly = (bool *)CustomData_get_layer_named(
&mesh->pdata, CD_PROP_BOOL, ".hide_poly");
bool *hide_poly = (bool *)CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly);
bool delete_hide_poly = true;
for (int face_index = 0; face_index < mesh->totpoly; face_index++, mp++) {
@ -3818,14 +3823,15 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
}
if (hidden && !hide_poly) {
hide_poly = (bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly");
hide_poly = (bool *)CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly);
if (!hide_poly) {
CustomData_add_layer_named(
&mesh->pdata, CD_PROP_BOOL, CD_CONSTRUCT, NULL, mesh->totpoly, ".hide_poly");
hide_poly = (bool *)CustomData_get_layer_named(
&mesh->pdata, CD_PROP_BOOL, ".hide_poly");
hide_poly = (bool *)CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly);
}
}

View File

@ -1529,7 +1529,6 @@ static void sb_sfesf_threads_run(struct Depsgraph *depsgraph,
}
sb_threads = MEM_callocN(sizeof(SB_thread_context) * totthread, "SBSpringsThread");
memset(sb_threads, 0, sizeof(SB_thread_context) * totthread);
left = totsprings;
dec = totsprings / totthread + 1;
for (i = 0; i < totthread; i++) {
@ -2208,7 +2207,6 @@ static void sb_cf_threads_run(Scene *scene,
// printf("sb_cf_threads_run spawning %d threads\n", totthread);
sb_threads = MEM_callocN(sizeof(SB_thread_context) * totthread, "SBThread");
memset(sb_threads, 0, sizeof(SB_thread_context) * totthread);
left = totpoint;
dec = totpoint / totthread + 1;
for (i = 0; i < totthread; i++) {

View File

@ -79,8 +79,8 @@ static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
Mesh *subdiv_mesh = ctx->subdiv_mesh;
ctx->num_uv_layers = CustomData_number_of_layers(&subdiv_mesh->ldata, CD_PROP_FLOAT2);
for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
ctx->uv_layers[layer_index] = static_cast<float2 *>(
CustomData_get_layer_n(&subdiv_mesh->ldata, CD_PROP_FLOAT2, layer_index));
ctx->uv_layers[layer_index] = static_cast<float2 *>(CustomData_get_layer_n_for_write(
&subdiv_mesh->ldata, CD_PROP_FLOAT2, layer_index, subdiv_mesh->totloop));
}
}
@ -93,19 +93,20 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
ctx->subdiv_loops = BKE_mesh_loops_for_write(subdiv_mesh);
/* Pointers to original indices layers. */
ctx->vert_origindex = static_cast<int *>(
CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX));
CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_ORIGINDEX, subdiv_mesh->totvert));
ctx->edge_origindex = static_cast<int *>(
CustomData_get_layer(&subdiv_mesh->edata, CD_ORIGINDEX));
CustomData_get_layer_for_write(&subdiv_mesh->edata, CD_ORIGINDEX, subdiv_mesh->totedge));
ctx->loop_origindex = static_cast<int *>(
CustomData_get_layer(&subdiv_mesh->ldata, CD_ORIGINDEX));
CustomData_get_layer_for_write(&subdiv_mesh->ldata, CD_ORIGINDEX, subdiv_mesh->totloop));
ctx->poly_origindex = static_cast<int *>(
CustomData_get_layer(&subdiv_mesh->pdata, CD_ORIGINDEX));
CustomData_get_layer_for_write(&subdiv_mesh->pdata, CD_ORIGINDEX, subdiv_mesh->totpoly));
/* UV layers interpolation. */
subdiv_mesh_ctx_cache_uv_layers(ctx);
/* Orco interpolation. */
ctx->orco = static_cast<float(*)[3]>(CustomData_get_layer(&subdiv_mesh->vdata, CD_ORCO));
ctx->orco = static_cast<float(*)[3]>(
CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_ORCO, subdiv_mesh->totvert));
ctx->cloth_orco = static_cast<float(*)[3]>(
CustomData_get_layer(&subdiv_mesh->vdata, CD_CLOTH_ORCO));
CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_CLOTH_ORCO, subdiv_mesh->totvert));
}
static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vertices)

View File

@ -390,8 +390,10 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *
const float(*dmloopuv)[2] = CustomData_get_layer_n(&dm->loopData, CD_PROP_FLOAT2, n);
/* need to update both CD_MTFACE & CD_PROP_FLOAT2, hrmf, we could get away with
* just tface except applying the modifier then looses subsurf UV */
MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
float(*mloopuv)[2] = CustomData_get_layer_n(&result->loopData, CD_PROP_FLOAT2, n);
MTFace *tface = CustomData_get_layer_n_for_write(
&result->faceData, CD_MTFACE, n, result->numTessFaceData);
float(*mloopuv)[2] = CustomData_get_layer_n_for_write(
&result->loopData, CD_PROP_FLOAT2, n, result->getNumLoops(dm));
if (!dmloopuv || (!tface && !mloopuv)) {
return;

View File

@ -388,25 +388,24 @@ template<typename T> class VArrayImpl_For_GVArray : public VArrayImpl<T> {
return true;
}
void materialize(IndexMask mask, MutableSpan<T> r_span) const override
void materialize(IndexMask mask, T *dst) const override
{
varray_.materialize(mask, r_span.data());
varray_.materialize(mask, dst);
}
void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_to_uninitialized(IndexMask mask, T *dst) const override
{
varray_.materialize_to_uninitialized(mask, r_span.data());
varray_.materialize_to_uninitialized(mask, dst);
}
void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_compressed(IndexMask mask, T *dst) const override
{
varray_.materialize_compressed(mask, r_span.data());
varray_.materialize_compressed(mask, dst);
}
void materialize_compressed_to_uninitialized(IndexMask mask,
MutableSpan<T> r_span) const override
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
{
varray_.materialize_compressed_to_uninitialized(mask, r_span.data());
varray_.materialize_compressed_to_uninitialized(mask, dst);
}
};
@ -539,25 +538,24 @@ template<typename T> class VMutableArrayImpl_For_GVMutableArray : public VMutabl
return true;
}
void materialize(IndexMask mask, MutableSpan<T> r_span) const override
void materialize(IndexMask mask, T *dst) const override
{
varray_.materialize(mask, r_span.data());
varray_.materialize(mask, dst);
}
void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_to_uninitialized(IndexMask mask, T *dst) const override
{
varray_.materialize_to_uninitialized(mask, r_span.data());
varray_.materialize_to_uninitialized(mask, dst);
}
void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_compressed(IndexMask mask, T *dst) const override
{
varray_.materialize_compressed(mask, r_span.data());
varray_.materialize_compressed(mask, dst);
}
void materialize_compressed_to_uninitialized(IndexMask mask,
MutableSpan<T> r_span) const override
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
{
varray_.materialize_compressed_to_uninitialized(mask, r_span.data());
varray_.materialize_compressed_to_uninitialized(mask, dst);
}
};

View File

@ -234,8 +234,15 @@ class IndexMask {
return indices_.first() >= range.first() && indices_.last() <= range.last();
}
IndexMask slice(int64_t start, int64_t size) const;
IndexMask slice(IndexRange slice) const;
IndexMask slice(const int64_t start, const int64_t size) const
{
return IndexMask(indices_.slice(start, size));
}
IndexMask slice(const IndexRange slice) const
{
return IndexMask(indices_.slice(slice));
}
IndexMask slice_safe(int64_t start, int64_t size) const;
IndexMask slice_safe(IndexRange slice) const;

View File

@ -203,7 +203,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap_self(const BVHTree *tree,
BVHTree_OverlapCallback callback,
void *userdata);
int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_num);
int *BLI_bvhtree_intersect_plane(const BVHTree *tree, float plane[4], uint *r_intersect_num);
/**
* Number of times #BLI_bvhtree_insert has been called.
@ -218,20 +218,20 @@ float BLI_bvhtree_get_epsilon(const BVHTree *tree);
/**
* This function returns the bounding box of the BVH tree.
*/
void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3]);
void BLI_bvhtree_get_bounding_box(const BVHTree *tree, float r_bb_min[3], float r_bb_max[3]);
/**
* Find nearest node to the given coordinates
* (if nearest is given it will only search nodes where
* square distance is smaller than nearest->dist).
*/
int BLI_bvhtree_find_nearest_ex(BVHTree *tree,
int BLI_bvhtree_find_nearest_ex(const BVHTree *tree,
const float co[3],
BVHTreeNearest *nearest,
BVHTree_NearestPointCallback callback,
void *userdata,
int flag);
int BLI_bvhtree_find_nearest(BVHTree *tree,
int BLI_bvhtree_find_nearest(const BVHTree *tree,
const float co[3],
BVHTreeNearest *nearest,
BVHTree_NearestPointCallback callback,
@ -241,13 +241,13 @@ int BLI_bvhtree_find_nearest(BVHTree *tree,
* Find the first node nearby.
* Favors speed over quality since it doesn't find the best target node.
*/
int BLI_bvhtree_find_nearest_first(BVHTree *tree,
int BLI_bvhtree_find_nearest_first(const BVHTree *tree,
const float co[3],
float dist_sq,
BVHTree_NearestPointCallback callback,
void *userdata);
int BLI_bvhtree_ray_cast_ex(BVHTree *tree,
int BLI_bvhtree_ray_cast_ex(const BVHTree *tree,
const float co[3],
const float dir[3],
float radius,
@ -255,7 +255,7 @@ int BLI_bvhtree_ray_cast_ex(BVHTree *tree,
BVHTree_RayCastCallback callback,
void *userdata,
int flag);
int BLI_bvhtree_ray_cast(BVHTree *tree,
int BLI_bvhtree_ray_cast(const BVHTree *tree,
const float co[3],
const float dir[3],
float radius,
@ -272,7 +272,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree,
* It also avoid redundant argument and return value which aren't meaningful
* when collecting multiple hits.
*/
void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree,
void BLI_bvhtree_ray_cast_all_ex(const BVHTree *tree,
const float co[3],
const float dir[3],
float radius,
@ -280,7 +280,7 @@ void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree,
BVHTree_RayCastCallback callback,
void *userdata,
int flag);
void BLI_bvhtree_ray_cast_all(BVHTree *tree,
void BLI_bvhtree_ray_cast_all(const BVHTree *tree,
const float co[3],
const float dir[3],
float radius,
@ -296,10 +296,13 @@ float BLI_bvhtree_bb_raycast(const float bv[6],
/**
* Range query.
*/
int BLI_bvhtree_range_query(
BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata);
int BLI_bvhtree_range_query(const BVHTree *tree,
const float co[3],
float radius,
BVHTree_RangeQuery callback,
void *userdata);
int BLI_bvhtree_find_nearest_projected(BVHTree *tree,
int BLI_bvhtree_find_nearest_projected(const BVHTree *tree,
float projmat[4][4],
float winsize[2],
float mval[2],
@ -321,7 +324,7 @@ int BLI_bvhtree_find_nearest_projected(BVHTree *tree,
* either from the node with the lower or higher K-DOP axis value.
* \param userdata: Argument passed to all callbacks.
*/
void BLI_bvhtree_walk_dfs(BVHTree *tree,
void BLI_bvhtree_walk_dfs(const BVHTree *tree,
BVHTree_WalkParentCallback walk_parent_cb,
BVHTree_WalkLeafCallback walk_leaf_cb,
BVHTree_WalkOrderCallback walk_order_cb,
@ -346,7 +349,7 @@ namespace blender {
using BVHTree_RayCastCallback_CPP =
FunctionRef<void(int index, const BVHTreeRay &ray, BVHTreeRayHit &hit)>;
inline void BLI_bvhtree_ray_cast_all_cpp(BVHTree &tree,
inline void BLI_bvhtree_ray_cast_all_cpp(const BVHTree &tree,
const float3 co,
const float3 dir,
float radius,
@ -368,7 +371,7 @@ inline void BLI_bvhtree_ray_cast_all_cpp(BVHTree &tree,
using BVHTree_RangeQuery_CPP = FunctionRef<void(int index, const float3 &co, float dist_sq)>;
inline void BLI_bvhtree_range_query_cpp(BVHTree &tree,
inline void BLI_bvhtree_range_query_cpp(const BVHTree &tree,
const float3 co,
float radius,
BVHTree_RangeQuery_CPP fn)

View File

@ -107,17 +107,16 @@ template<typename T> class VArrayImpl {
* Copy values from the virtual array into the provided span. The index of the value in the
* virtual array is the same as the index in the span.
*/
virtual void materialize(IndexMask mask, MutableSpan<T> r_span) const
virtual void materialize(IndexMask mask, T *dst) const
{
mask.foreach_index([&](const int64_t i) { r_span[i] = this->get(i); });
mask.foreach_index([&](const int64_t i) { dst[i] = this->get(i); });
}
/**
* Same as #materialize but #r_span is expected to be uninitialized.
*/
virtual void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const
virtual void materialize_to_uninitialized(IndexMask mask, T *dst) const
{
T *dst = r_span.data();
mask.foreach_index([&](const int64_t i) { new (dst + i) T(this->get(i)); });
}
@ -126,12 +125,11 @@ template<typename T> class VArrayImpl {
* in virtual array is not the same as the index in the output span. Instead, the span is filled
* without gaps.
*/
virtual void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const
virtual void materialize_compressed(IndexMask mask, T *dst) const
{
BLI_assert(mask.size() == r_span.size());
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
r_span[i] = this->get(best_mask[i]);
dst[i] = this->get(best_mask[i]);
}
});
}
@ -139,10 +137,8 @@ template<typename T> class VArrayImpl {
/**
* Same as #materialize_compressed but #r_span is expected to be uninitialized.
*/
virtual void materialize_compressed_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const
virtual void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const
{
BLI_assert(mask.size() == r_span.size());
T *dst = r_span.data();
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst + i) T(this->get(best_mask[i]));
@ -254,32 +250,27 @@ template<typename T> class VArrayImpl_For_Span : public VMutableArrayImpl<T> {
return data_ == static_cast<const T *>(other_info.data);
}
void materialize(IndexMask mask, MutableSpan<T> r_span) const override
void materialize(IndexMask mask, T *dst) const override
{
mask.foreach_index([&](const int64_t i) { r_span[i] = data_[i]; });
mask.foreach_index([&](const int64_t i) { dst[i] = data_[i]; });
}
void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_to_uninitialized(IndexMask mask, T *dst) const override
{
T *dst = r_span.data();
mask.foreach_index([&](const int64_t i) { new (dst + i) T(data_[i]); });
}
void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_compressed(IndexMask mask, T *dst) const override
{
BLI_assert(mask.size() == r_span.size());
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
r_span[i] = data_[best_mask[i]];
dst[i] = data_[best_mask[i]];
}
});
}
void materialize_compressed_to_uninitialized(IndexMask mask,
MutableSpan<T> r_span) const override
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
{
BLI_assert(mask.size() == r_span.size());
T *dst = r_span.data();
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst + i) T(data_[best_mask[i]]);
@ -357,29 +348,24 @@ template<typename T> class VArrayImpl_For_Single final : public VArrayImpl<T> {
return CommonVArrayInfo(CommonVArrayInfo::Type::Single, true, &value_);
}
void materialize(IndexMask mask, MutableSpan<T> r_span) const override
void materialize(IndexMask mask, T *dst) const override
{
r_span.fill_indices(mask, value_);
mask.foreach_index([&](const int64_t i) { dst[i] = value_; });
}
void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_to_uninitialized(IndexMask mask, T *dst) const override
{
T *dst = r_span.data();
mask.foreach_index([&](const int64_t i) { new (dst + i) T(value_); });
}
void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_compressed(IndexMask mask, T *dst) const override
{
BLI_assert(mask.size() == r_span.size());
UNUSED_VARS_NDEBUG(mask);
r_span.fill(value_);
initialized_fill_n(dst, mask.size(), value_);
}
void materialize_compressed_to_uninitialized(IndexMask mask,
MutableSpan<T> r_span) const override
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
{
BLI_assert(mask.size() == r_span.size());
uninitialized_fill_n(r_span.data(), mask.size(), value_);
uninitialized_fill_n(dst, mask.size(), value_);
}
};
@ -406,22 +392,18 @@ template<typename T, typename GetFunc> class VArrayImpl_For_Func final : public
return get_func_(index);
}
void materialize(IndexMask mask, MutableSpan<T> r_span) const override
void materialize(IndexMask mask, T *dst) const override
{
T *dst = r_span.data();
mask.foreach_index([&](const int64_t i) { dst[i] = get_func_(i); });
}
void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_to_uninitialized(IndexMask mask, T *dst) const override
{
T *dst = r_span.data();
mask.foreach_index([&](const int64_t i) { new (dst + i) T(get_func_(i)); });
}
void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override
void materialize_compressed(IndexMask mask, T *dst) const override
{
BLI_assert(mask.size() == r_span.size());
T *dst = r_span.data();
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
dst[i] = get_func_(best_mask[i]);
@ -429,11 +411,8 @@ template<typename T, typename GetFunc> class VArrayImpl_For_Func final : public
});
}
void materialize_compressed_to_uninitialized(IndexMask mask,
MutableSpan<T> r_span) const override
void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override
{
BLI_assert(mask.size() == r_span.size());
T *dst = r_span.data();
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst + i) T(get_func_(best_mask[i]));
@ -476,22 +455,18 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
SetFunc(data_[index], std::move(value));
}
void materialize(IndexMask mask, MutableSpan<ElemT> r_span) const override
void materialize(IndexMask mask, ElemT *dst) const override
{
ElemT *dst = r_span.data();
mask.foreach_index([&](const int64_t i) { dst[i] = GetFunc(data_[i]); });
}
void materialize_to_uninitialized(IndexMask mask, MutableSpan<ElemT> r_span) const override
void materialize_to_uninitialized(IndexMask mask, ElemT *dst) const override
{
ElemT *dst = r_span.data();
mask.foreach_index([&](const int64_t i) { new (dst + i) ElemT(GetFunc(data_[i])); });
}
void materialize_compressed(IndexMask mask, MutableSpan<ElemT> r_span) const override
void materialize_compressed(IndexMask mask, ElemT *dst) const override
{
BLI_assert(mask.size() == r_span.size());
ElemT *dst = r_span.data();
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
dst[i] = GetFunc(data_[best_mask[i]]);
@ -499,11 +474,8 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
});
}
void materialize_compressed_to_uninitialized(IndexMask mask,
MutableSpan<ElemT> r_span) const override
void materialize_compressed_to_uninitialized(IndexMask mask, ElemT *dst) const override
{
BLI_assert(mask.size() == r_span.size());
ElemT *dst = r_span.data();
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
new (dst + i) ElemT(GetFunc(data_[best_mask[i]]));
@ -835,7 +807,7 @@ template<typename T> class VArrayCommon {
void materialize(IndexMask mask, MutableSpan<T> r_span) const
{
BLI_assert(mask.min_array_size() <= this->size());
impl_->materialize(mask, r_span);
impl_->materialize(mask, r_span.data());
}
void materialize_to_uninitialized(MutableSpan<T> r_span) const
@ -846,18 +818,18 @@ template<typename T> class VArrayCommon {
void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const
{
BLI_assert(mask.min_array_size() <= this->size());
impl_->materialize_to_uninitialized(mask, r_span);
impl_->materialize_to_uninitialized(mask, r_span.data());
}
/** Copy some elements of the virtual array into a span. */
void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const
{
impl_->materialize_compressed(mask, r_span);
impl_->materialize_compressed(mask, r_span.data());
}
void materialize_compressed_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const
{
impl_->materialize_compressed_to_uninitialized(mask, r_span);
impl_->materialize_compressed_to_uninitialized(mask, r_span.data());
}
/** See #GVArrayImpl::try_assign_GVArray. */
@ -865,6 +837,11 @@ template<typename T> class VArrayCommon {
{
return impl_->try_assign_GVArray(varray);
}
const VArrayImpl<T> *get_implementation() const
{
return impl_;
}
};
template<typename T> class VMutableArray;

View File

@ -1047,7 +1047,7 @@ float BLI_bvhtree_get_epsilon(const BVHTree *tree)
return tree->epsilon;
}
void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3])
void BLI_bvhtree_get_bounding_box(const BVHTree *tree, float r_bb_min[3], float r_bb_max[3])
{
BVHNode *root = tree->nodes[tree->leaf_num];
if (root != NULL) {
@ -1494,7 +1494,7 @@ static void bvhtree_intersect_plane_dfs_recursive(BVHIntersectPlaneData *__restr
}
}
int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_num)
int *BLI_bvhtree_intersect_plane(const BVHTree *tree, float plane[4], uint *r_intersect_num)
{
int *intersect = NULL;
size_t total = 0;
@ -1641,7 +1641,7 @@ static void heap_find_nearest_begin(BVHNearestData *data, BVHNode *root)
}
}
int BLI_bvhtree_find_nearest_ex(BVHTree *tree,
int BLI_bvhtree_find_nearest_ex(const BVHTree *tree,
const float co[3],
BVHTreeNearest *nearest,
BVHTree_NearestPointCallback callback,
@ -1690,7 +1690,7 @@ int BLI_bvhtree_find_nearest_ex(BVHTree *tree,
return data.nearest.index;
}
int BLI_bvhtree_find_nearest(BVHTree *tree,
int BLI_bvhtree_find_nearest(const BVHTree *tree,
const float co[3],
BVHTreeNearest *nearest,
BVHTree_NearestPointCallback callback,
@ -1756,7 +1756,7 @@ static bool dfs_find_duplicate_fast_dfs(BVHNearestData *data, BVHNode *node)
return false;
}
int BLI_bvhtree_find_nearest_first(BVHTree *tree,
int BLI_bvhtree_find_nearest_first(const BVHTree *tree,
const float co[3],
const float dist_sq,
BVHTree_NearestPointCallback callback,
@ -1971,7 +1971,7 @@ static void bvhtree_ray_cast_data_precalc(BVHRayCastData *data, int flag)
#endif
}
int BLI_bvhtree_ray_cast_ex(BVHTree *tree,
int BLI_bvhtree_ray_cast_ex(const BVHTree *tree,
const float co[3],
const float dir[3],
float radius,
@ -2016,7 +2016,7 @@ int BLI_bvhtree_ray_cast_ex(BVHTree *tree,
return data.hit.index;
}
int BLI_bvhtree_ray_cast(BVHTree *tree,
int BLI_bvhtree_ray_cast(const BVHTree *tree,
const float co[3],
const float dir[3],
float radius,
@ -2055,7 +2055,7 @@ float BLI_bvhtree_bb_raycast(const float bv[6],
return dist;
}
void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree,
void BLI_bvhtree_ray_cast_all_ex(const BVHTree *tree,
const float co[3],
const float dir[3],
float radius,
@ -2089,7 +2089,7 @@ void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree,
}
}
void BLI_bvhtree_ray_cast_all(BVHTree *tree,
void BLI_bvhtree_ray_cast_all(const BVHTree *tree,
const float co[3],
const float dir[3],
float radius,
@ -2113,7 +2113,7 @@ void BLI_bvhtree_ray_cast_all(BVHTree *tree,
* \{ */
typedef struct RangeQueryData {
BVHTree *tree;
const BVHTree *tree;
const float *center;
float radius_sq; /* squared radius */
@ -2154,8 +2154,11 @@ static void dfs_range_query(RangeQueryData *data, BVHNode *node)
}
}
int BLI_bvhtree_range_query(
BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata)
int BLI_bvhtree_range_query(const BVHTree *tree,
const float co[3],
float radius,
BVHTree_RangeQuery callback,
void *userdata)
{
BVHNode *root = tree->nodes[tree->leaf_num];
@ -2307,7 +2310,7 @@ static void bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(
}
}
int BLI_bvhtree_find_nearest_projected(BVHTree *tree,
int BLI_bvhtree_find_nearest_projected(const BVHTree *tree,
float projmat[4][4],
float winsize[2],
float mval[2],
@ -2421,7 +2424,7 @@ static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNod
return true;
}
void BLI_bvhtree_walk_dfs(BVHTree *tree,
void BLI_bvhtree_walk_dfs(const BVHTree *tree,
BVHTree_WalkParentCallback walk_parent_cb,
BVHTree_WalkLeafCallback walk_leaf_cb,
BVHTree_WalkOrderCallback walk_order_cb,

View File

@ -5,16 +5,6 @@
namespace blender {
IndexMask IndexMask::slice(int64_t start, int64_t size) const
{
return this->slice(IndexRange(start, size));
}
IndexMask IndexMask::slice(IndexRange slice) const
{
return IndexMask(indices_.slice(slice));
}
IndexMask IndexMask::slice_safe(int64_t start, int64_t size) const
{
return this->slice_safe(IndexRange(start, size));

View File

@ -162,6 +162,7 @@ void blo_write_id_struct(BlendWriter *writer,
* Write raw data.
*/
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr);
void BLO_write_int8_array(BlendWriter *writer, uint num, const int8_t *data_ptr);
void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr);
void BLO_write_uint32_array(BlendWriter *writer, uint num, const uint32_t *data_ptr);
void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr);
@ -228,6 +229,7 @@ void BLO_read_list(BlendDataReader *reader, struct ListBase *list);
/* Update data pointers and correct byte-order if necessary. */
void BLO_read_int8_array(BlendDataReader *reader, int array_size, int8_t **ptr_p);
void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p);
void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p);
void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p);

View File

@ -4976,6 +4976,11 @@ void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr
}
}
void BLO_read_int8_array(BlendDataReader *reader, int /*array_size*/, int8_t **ptr_p)
{
BLO_read_data_address(reader, ptr_p);
}
void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p)
{
BLO_read_data_address(reader, ptr_p);

View File

@ -996,7 +996,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
if ((key = blo_do_versions_newlibadr(fd, lib, me->key)) && key->refkey) {
data = key->refkey->data;
tot = MIN2(me->totvert, key->refkey->totelem);
MVert *verts = (MVert *)CustomData_get_layer(&me->vdata, CD_MVERT);
MVert *verts = (MVert *)CustomData_get_layer_for_write(&me->vdata, CD_MVERT, me->totvert);
for (a = 0; a < tot; a++, data += 3) {
copy_v3_v3(verts[a].co_legacy, data);
}

View File

@ -821,21 +821,22 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
for (const MPoly *mp = BKE_mesh_polys(me), *mp_end = mp + me->totpoly; mp < mp_end; mp++) {
if (mp->totloop == 2) {
bool changed;
BKE_mesh_validate_arrays(me,
BKE_mesh_vert_positions_for_write(me),
me->totvert,
BKE_mesh_edges_for_write(me),
me->totedge,
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
BKE_mesh_loops_for_write(me),
me->totloop,
BKE_mesh_polys_for_write(me),
me->totpoly,
BKE_mesh_deform_verts_for_write(me),
false,
true,
&changed);
BKE_mesh_validate_arrays(
me,
BKE_mesh_vert_positions_for_write(me),
me->totvert,
BKE_mesh_edges_for_write(me),
me->totedge,
(MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface),
me->totface,
BKE_mesh_loops_for_write(me),
me->totloop,
BKE_mesh_polys_for_write(me),
me->totpoly,
BKE_mesh_deform_verts_for_write(me),
false,
true,
&changed);
break;
}
}

View File

@ -248,6 +248,7 @@ static void version_idproperty_ui_data(IDProperty *idprop_group)
case IDP_UI_DATA_TYPE_FLOAT:
version_idproperty_move_data_float((IDPropertyUIDataFloat *)ui_data, prop_ui_data);
break;
case IDP_UI_DATA_TYPE_BOOLEAN:
case IDP_UI_DATA_TYPE_UNSUPPORTED:
BLI_assert_unreachable();
break;
@ -876,7 +877,7 @@ static void version_geometry_nodes_primitive_uv_maps(bNodeTree &ntree)
bNodeSocket *store_attribute_geometry_input = static_cast<bNodeSocket *>(
store_attribute_node->inputs.first);
bNodeSocket *store_attribute_name_input = store_attribute_geometry_input->next;
bNodeSocket *store_attribute_name_input = store_attribute_geometry_input->next->next;
bNodeSocket *store_attribute_value_input = nullptr;
LISTBASE_FOREACH (bNodeSocket *, socket, &store_attribute_node->inputs) {
if (socket->type == SOCK_VECTOR) {

View File

@ -359,7 +359,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
{0.625, 0.75}, {0.375, 0.75}, {0.375, 0.25}, {0.625, 0.25}, {0.625, 0.50}, {0.375, 0.50},
};
float(*mloopuv)[2] = static_cast<float(*)[2]>(
CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2));
CustomData_get_layer_for_write(&me->ldata, CD_PROP_FLOAT2, me->totloop));
memcpy(mloopuv, uv_values, sizeof(float[2]) * me->totloop);
}

View File

@ -1639,6 +1639,11 @@ int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name)
return struct_id;
}
void BLO_write_int8_array(BlendWriter *writer, uint num, const int8_t *data_ptr)
{
BLO_write_raw(writer, sizeof(int8_t) * size_t(num), data_ptr);
}
void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr)
{
BLO_write_raw(writer, sizeof(int32_t) * size_t(num), data_ptr);

View File

@ -64,7 +64,7 @@ typedef struct PBVH_GPU_Args {
int *prim_indices;
int totprim;
bool *hide_poly;
const bool *hide_poly;
int node_verts_num;

View File

@ -367,7 +367,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
mr->loop_normals = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__));
short(*clnors)[2] = static_cast<short(*)[2]>(
CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL));
CustomData_get_layer_for_write(&mr->me->ldata, CD_CUSTOMLOOPNORMAL, mr->me->totloop));
const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&mr->me->edata, CD_PROP_BOOL, "sharp_edge"));
BKE_mesh_normals_loop_split(reinterpret_cast<const float(*)[3]>(mr->vert_positions),

View File

@ -310,8 +310,8 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys,
}
}
if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
MFace *mface = &mfaces[num];
const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
const MFace *mface = &mfaces[num];
for (int j = 0; j < num_uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]);
}
@ -340,8 +340,8 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys,
}
}
if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
MFace *mface = &mfaces[num];
const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
const MFace *mface = &mfaces[num];
for (int j = 0; j < num_col_layers; j++) {
/* CustomDataLayer CD_MCOL has 4 structs per face. */
psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]);
@ -367,8 +367,8 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys,
ChildParticle *particle = &psys->child[child_index];
int num = particle->num;
if (num != DMCACHE_NOTFOUND) {
MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
MFace *mface = &mfaces[num];
const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
const MFace *mface = &mfaces[num];
for (int j = 0; j < num_uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]);
}
@ -392,8 +392,8 @@ static void particle_interpolate_children_mcol(ParticleSystem *psys,
ChildParticle *particle = &psys->child[child_index];
int num = particle->num;
if (num != DMCACHE_NOTFOUND) {
MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
MFace *mface = &mfaces[num];
const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE);
const MFace *mface = &mfaces[num];
for (int j = 0; j < num_col_layers; j++) {
/* CustomDataLayer CD_MCOL has 4 structs per face. */
psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]);

View File

@ -595,7 +595,8 @@ struct PBVHBatches {
fill_vbo_normal_faces(vbo, args, foreach_faces, &access);
break;
case CD_PBVH_MASK_TYPE: {
float *mask = static_cast<float *>(CustomData_get_layer(args->vdata, CD_PAINT_MASK));
const float *mask = static_cast<const float *>(
CustomData_get_layer(args->vdata, CD_PAINT_MASK));
if (mask) {
foreach_faces(
@ -613,7 +614,7 @@ struct PBVHBatches {
break;
}
case CD_PBVH_FSET_TYPE: {
int *face_sets = static_cast<int *>(
const int *face_sets = static_cast<const int *>(
CustomData_get_layer_named(args->pdata, CD_PROP_INT32, ".sculpt_face_set"));
if (face_sets) {
@ -653,13 +654,13 @@ struct PBVHBatches {
}
case CD_PROP_COLOR:
if (vbo.domain == ATTR_DOMAIN_POINT) {
MPropCol *mpropcol = static_cast<MPropCol *>(
const MPropCol *mpropcol = static_cast<const MPropCol *>(
CustomData_get_layer_named(args->vdata, CD_PROP_COLOR, vbo.name.c_str()));
foreach_faces(
[&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) {
ushort color[4];
MPropCol *col = mpropcol + vertex_i;
const MPropCol *col = mpropcol + vertex_i;
color[0] = unit_float_to_ushort_clamp(col->color[0]);
color[1] = unit_float_to_ushort_clamp(col->color[1]);
@ -670,12 +671,12 @@ struct PBVHBatches {
});
}
else if (vbo.domain == ATTR_DOMAIN_CORNER) {
MPropCol *mpropcol = static_cast<MPropCol *>(
const MPropCol *mpropcol = static_cast<const MPropCol *>(
CustomData_get_layer_named(args->ldata, CD_PROP_COLOR, vbo.name.c_str()));
foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) {
ushort color[4];
MPropCol *col = mpropcol + tri->tri[tri_i];
const MPropCol *col = mpropcol + tri->tri[tri_i];
color[0] = unit_float_to_ushort_clamp(col->color[0]);
color[1] = unit_float_to_ushort_clamp(col->color[1]);
@ -688,13 +689,13 @@ struct PBVHBatches {
break;
case CD_PROP_BYTE_COLOR:
if (vbo.domain == ATTR_DOMAIN_POINT) {
MLoopCol *mbytecol = static_cast<MLoopCol *>(
const MLoopCol *mbytecol = static_cast<const MLoopCol *>(
CustomData_get_layer_named(args->vdata, CD_PROP_BYTE_COLOR, vbo.name.c_str()));
foreach_faces(
[&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) {
ushort color[4];
MLoopCol *col = mbytecol + vertex_i;
const MLoopCol *col = mbytecol + vertex_i;
color[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->r]);
color[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->g]);
@ -705,12 +706,12 @@ struct PBVHBatches {
});
}
else if (vbo.domain == ATTR_DOMAIN_CORNER) {
MLoopCol *mbytecol = static_cast<MLoopCol *>(
const MLoopCol *mbytecol = static_cast<const MLoopCol *>(
CustomData_get_layer_named(args->ldata, CD_PROP_BYTE_COLOR, vbo.name.c_str()));
foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) {
ushort color[4];
MLoopCol *col = mbytecol + tri->tri[tri_i];
const MLoopCol *col = mbytecol + tri->tri[tri_i];
color[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->r]);
color[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->g]);
@ -722,7 +723,7 @@ struct PBVHBatches {
}
break;
case CD_PROP_FLOAT2: {
float2 *mloopuv = static_cast<float2 *>(
const float2 *mloopuv = static_cast<const float2 *>(
CustomData_get_layer_named(args->ldata, CD_PROP_FLOAT2, vbo.name.c_str()));
foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) {
@ -730,7 +731,6 @@ struct PBVHBatches {
});
break;
}
}
}
@ -972,7 +972,7 @@ struct PBVHBatches {
void create_index_faces(PBVH_GPU_Args *args)
{
int *mat_index = static_cast<int *>(
const int *mat_index = static_cast<const int *>(
CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index"));
if (mat_index && args->totprim) {
@ -1062,7 +1062,7 @@ struct PBVHBatches {
void create_index_grids(PBVH_GPU_Args *args, bool do_coarse)
{
int *mat_index = static_cast<int *>(
const int *mat_index = static_cast<const int *>(
CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index"));
if (mat_index && args->totprim) {

View File

@ -40,8 +40,8 @@ static void extract_tan_init_common(const MeshRenderData *mr,
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata;
uint32_t tan_layers = cache->cd_used.tan;
float(*orco)[3] = (float(*)[3])CustomData_get_layer(cd_vdata, CD_ORCO);
bool orco_allocated = false;
const float(*orco)[3] = (const float(*)[3])CustomData_get_layer(cd_vdata, CD_ORCO);
float(*orco_allocated)[3] = nullptr;
bool use_orco_tan = cache->cd_used.tan_orco != 0;
int tan_len = 0;
@ -76,8 +76,7 @@ static void extract_tan_init_common(const MeshRenderData *mr,
}
if (use_orco_tan && orco == nullptr) {
/* If `orco` is not available compute it ourselves */
orco_allocated = true;
orco = (float(*)[3])MEM_mallocN(sizeof(*orco) * mr->vert_len, __func__);
orco_allocated = (float(*)[3])MEM_mallocN(sizeof(*orco) * mr->vert_len, __func__);
if (mr->extract_type == MR_EXTRACT_BMESH) {
BMesh *bm = mr->bm;
@ -85,15 +84,16 @@ static void extract_tan_init_common(const MeshRenderData *mr,
const BMVert *eve = BM_vert_at_index(bm, v);
/* Exceptional case where #bm_vert_co_get can be avoided, as we want the original coords.
* not the distorted ones. */
copy_v3_v3(orco[v], eve->co);
copy_v3_v3(orco_allocated[v], eve->co);
}
}
else {
for (int v = 0; v < mr->vert_len; v++) {
copy_v3_v3(orco[v], mr->vert_positions[v]);
copy_v3_v3(orco_allocated[v], mr->vert_positions[v]);
}
}
BKE_mesh_orco_verts_transform(mr->me, orco, mr->vert_len, 0);
BKE_mesh_orco_verts_transform(mr->me, orco_allocated, mr->vert_len, 0);
orco = orco_allocated;
}
/* Start Fresh */
@ -144,9 +144,7 @@ static void extract_tan_init_common(const MeshRenderData *mr,
GPU_vertformat_alias_add(format, "at");
}
if (orco_allocated) {
MEM_SAFE_FREE(orco);
}
MEM_SAFE_FREE(orco_allocated);
int v_len = mr->loop_len;
if (format->attr_len == 0) {
@ -192,7 +190,7 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
short(*tan_data)[4] = (short(*)[4])GPU_vertbuf_get_data(vbo);
for (int i = 0; i < tan_len; i++) {
const char *name = tangent_names[i];
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(
const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_named(
&loop_data, CD_TANGENT, name);
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) {
normal_float_to_short_v3(*tan_data, layer_data[ml_index]);
@ -201,7 +199,8 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
}
}
if (use_orco_tan) {
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(&loop_data, CD_TANGENT, 0);
const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_n(
&loop_data, CD_TANGENT, 0);
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) {
normal_float_to_short_v3(*tan_data, layer_data[ml_index]);
(*tan_data)[3] = (layer_data[ml_index][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
@ -213,7 +212,7 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
GPUPackedNormal *tan_data = (GPUPackedNormal *)GPU_vertbuf_get_data(vbo);
for (int i = 0; i < tan_len; i++) {
const char *name = tangent_names[i];
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(
const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_named(
&loop_data, CD_TANGENT, name);
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) {
*tan_data = GPU_normal_convert_i10_v3(layer_data[ml_index]);
@ -222,7 +221,8 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
}
}
if (use_orco_tan) {
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(&loop_data, CD_TANGENT, 0);
const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_n(
&loop_data, CD_TANGENT, 0);
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) {
*tan_data = GPU_normal_convert_i10_v3(layer_data[ml_index]);
tan_data->w = (layer_data[ml_index][3] > 0.0f) ? 1 : -2;
@ -291,7 +291,7 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
for (int i = 0; i < tan_len; i++) {
float(*tan_data)[4] = (float(*)[4])GPU_vertbuf_get_data(coarse_vbo);
const char *name = tangent_names[i];
const float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(
const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_named(
&loop_data, CD_TANGENT, name);
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) {
copy_v3_v3(*tan_data, layer_data[ml_index]);
@ -308,7 +308,8 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
}
if (use_orco_tan) {
float(*tan_data)[4] = (float(*)[4])GPU_vertbuf_get_data(coarse_vbo);
const float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(&loop_data, CD_TANGENT, 0);
const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_n(
&loop_data, CD_TANGENT, 0);
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) {
copy_v3_v3(*tan_data, layer_data[ml_index]);
(*tan_data)[3] = (layer_data[ml_index][3] > 0.0f) ? 1.0f : -1.0f;

View File

@ -109,7 +109,7 @@ static void extract_uv_init(const MeshRenderData *mr,
}
}
else {
const float2 *layer_data = static_cast<float2 *>(
const float2 *layer_data = static_cast<const float2 *>(
CustomData_get_layer_n(cd_ldata, CD_PROP_FLOAT2, i));
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, uv_data++, layer_data++) {
memcpy(uv_data, layer_data, sizeof(*uv_data));

View File

@ -923,10 +923,10 @@ static int select_all_exec(bContext *C, wmOperator *op)
} // namespace select_all
static void SCULPT_CURVES_OT_select_all(wmOperatorType *ot)
static void CURVES_OT_select_all(wmOperatorType *ot)
{
ot->name = "(De)select All";
ot->idname = __func__;
ot->idname = "CURVES_OT_select_all";
ot->description = "(De)select all control points";
ot->exec = select_all::select_all_exec;
@ -1029,6 +1029,6 @@ void ED_operatortypes_curves()
WM_operatortype_append(CURVES_OT_convert_from_particle_system);
WM_operatortype_append(CURVES_OT_snap_curves_to_surface);
WM_operatortype_append(CURVES_OT_set_selection_domain);
WM_operatortype_append(SCULPT_CURVES_OT_select_all);
WM_operatortype_append(CURVES_OT_select_all);
WM_operatortype_append(CURVES_OT_surface_set);
}

View File

@ -1104,13 +1104,15 @@ char ED_view3d_lock_view_from_index(int index);
char ED_view3d_axis_view_opposite(char view);
bool ED_view3d_lock(struct RegionView3D *rv3d);
void ED_view3d_datamask(const struct ViewLayer *view_layer,
void ED_view3d_datamask(const struct Scene *scene,
struct ViewLayer *view_layer,
const struct View3D *v3d,
struct CustomData_MeshMasks *r_cddata_masks);
/**
* Goes over all modes and view3d settings.
*/
void ED_view3d_screen_datamask(const struct ViewLayer *view_layer,
void ED_view3d_screen_datamask(const struct Scene *scene,
struct ViewLayer *view_layer,
const struct bScreen *screen,
struct CustomData_MeshMasks *r_cddata_masks);

View File

@ -573,8 +573,10 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
if (ob->mode == OB_MODE_SCULPT) {
SculptSession *ss = ob->sculpt;
ss->face_sets = CustomData_get_layer_named(
&((Mesh *)ob->data)->pdata, CD_PROP_INT32, ".sculpt_face_set");
ss->face_sets = CustomData_get_layer_named_for_write(&((Mesh *)ob->data)->pdata,
CD_PROP_INT32,
".sculpt_face_set",
((Mesh *)ob->data)->totpoly);
if (ss->face_sets) {
/* Assign a new Face Set ID to the new faces created by the slice operation. */
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data);

View File

@ -899,18 +899,17 @@ static bool loop_uv_match(BMLoop *loop,
compare_v2v2(luv_b, luv_d, STD_UV_CONNECT_LIMIT);
}
/* Given `anchor` and `edge`, return true if there are edges that fan between them that are
/* Given `luv_anchor` and `needle`, return true if there are edges that fan between them that are
* seam-free. */
static bool seam_connected_recursive(BMVert *anchor,
BMEdge *edge,
float luv_anchor[2],
float luv_fan[2],
static bool seam_connected_recursive(BMEdge *edge,
const float luv_anchor[2],
const float luv_fan[2],
BMLoop *needle,
GSet *visited,
int cd_loop_uv_offset)
{
BMVert *anchor = needle->v;
BLI_assert(edge->v1 == anchor || edge->v2 == anchor);
BLI_assert(needle->v == anchor || needle->next->v == anchor);
if (BM_elem_flag_test(edge, BM_ELEM_SEAM)) {
return false; /* Edge is a seam, don't traverse. */
@ -928,13 +927,13 @@ static bool seam_connected_recursive(BMVert *anchor,
continue; /* `loop` is disjoint in UV space. */
}
if (loop->prev == needle) {
if (loop == needle) {
return true; /* Success. */
}
float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->prev, cd_loop_uv_offset);
if (seam_connected_recursive(
anchor, loop->prev->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) {
loop->prev->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) {
return true;
}
}
@ -950,7 +949,7 @@ static bool seam_connected_recursive(BMVert *anchor,
float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->next->next, cd_loop_uv_offset);
if (seam_connected_recursive(
anchor, loop->next->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) {
loop->next->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) {
return true;
}
}
@ -971,10 +970,18 @@ static bool seam_connected(BMLoop *loop_a, BMLoop *loop_b, GSet *visited, int cd
BLI_gset_clear(visited, NULL);
float *luv_anchor = BM_ELEM_CD_GET_FLOAT_P(loop_a, cd_loop_uv_offset);
float *luv_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->next, cd_loop_uv_offset);
const bool result = seam_connected_recursive(
loop_a->v, loop_a->e, luv_anchor, luv_fan, loop_b, visited, cd_loop_uv_offset);
const float *luv_anchor = BM_ELEM_CD_GET_FLOAT_P(loop_a, cd_loop_uv_offset);
const float *luv_next_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->next, cd_loop_uv_offset);
bool result = seam_connected_recursive(
loop_a->e, luv_anchor, luv_next_fan, loop_b, visited, cd_loop_uv_offset);
if (!result) {
/* Search around `loop_a` in the opposite direction, as one of the edges may be delimited by
* a boundary, seam or disjoint UV, or itself be one of these. See: T103670, T103787. */
float *luv_prev_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->prev, cd_loop_uv_offset);
result = seam_connected_recursive(
loop_a->prev->e, luv_anchor, luv_prev_fan, loop_b, visited, cd_loop_uv_offset);
}
return result;
}

View File

@ -232,7 +232,7 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum)
/* Collect Mesh UVs */
BLI_assert(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2));
float2 *mloopuv = static_cast<float2 *>(
CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, layernum));
CustomData_get_layer_n_for_write(&me->ldata, CD_PROP_FLOAT2, layernum, me->totloop));
const MPoly *polys = BKE_mesh_polys(me);
for (int i = 0; i < me->totpoly; i++) {
@ -302,7 +302,8 @@ int ED_mesh_uv_add(
CustomData_add_layer_named(&me->ldata,
CD_PROP_FLOAT2,
CD_DUPLICATE,
CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2),
const_cast<float2 *>(static_cast<const float2 *>(
CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2))),
me->totloop,
unique_name);
@ -364,8 +365,8 @@ const bool *ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, const int uv_index)
static bool *ensure_corner_boolean_attribute(Mesh &mesh, const blender::StringRefNull name)
{
bool *data = static_cast<bool *>(CustomData_duplicate_referenced_layer_named(
&mesh.ldata, CD_PROP_BOOL, name.c_str(), mesh.totloop));
bool *data = static_cast<bool *>(
CustomData_get_layer_named_for_write(&mesh.ldata, CD_PROP_BOOL, name.c_str(), mesh.totloop));
if (!data) {
data = static_cast<bool *>(CustomData_add_layer_named(
&mesh.ldata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, mesh.totpoly, name.c_str()));

View File

@ -108,9 +108,10 @@ static void join_mesh_single(Depsgraph *depsgraph,
CustomData_copy_data_named(&me->vdata, vdata, 0, *vertofs, me->totvert);
/* vertex groups */
MDeformVert *dvert = (MDeformVert *)CustomData_get(vdata, *vertofs, CD_MDEFORMVERT);
const MDeformVert *dvert_src = (const MDeformVert *)CustomData_get(
&me->vdata, 0, CD_MDEFORMVERT);
MDeformVert *dvert = (MDeformVert *)CustomData_get_for_write(
vdata, *vertofs, CD_MDEFORMVERT, totvert);
const MDeformVert *dvert_src = (const MDeformVert *)CustomData_get_layer(&me->vdata,
CD_MDEFORMVERT);
/* Remap to correct new vgroup indices, if needed. */
if (dvert_src) {
@ -254,7 +255,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
/* Apply matmap. In case we don't have material indices yet, create them if more than one
* material is the result of joining. */
int *material_indices = static_cast<int *>(
CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index"));
CustomData_get_layer_named_for_write(pdata, CD_PROP_INT32, "material_index", totpoly));
if (!material_indices && totcol > 1) {
material_indices = (int *)CustomData_add_layer_named(
pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, totpoly, "material_index");
@ -270,8 +271,9 @@ static void join_mesh_single(Depsgraph *depsgraph,
}
/* Face maps. */
int *fmap = (int *)CustomData_get(pdata, *polyofs, CD_FACEMAP);
const int *fmap_src = (const int *)CustomData_get(&me->pdata, 0, CD_FACEMAP);
int *fmap = (int *)CustomData_get_for_write(pdata, *polyofs, CD_FACEMAP, totpoly);
const int *fmap_src = (const int *)CustomData_get_for_write(
&me->pdata, 0, CD_FACEMAP, me->totpoly);
/* Remap to correct new face-map indices, if needed. */
if (fmap_src) {
@ -300,14 +302,14 @@ static void join_mesh_single(Depsgraph *depsgraph,
/* Face Sets IDs are a sparse sequence, so this function offsets all the IDs by face_set_offset and
* updates face_set_offset with the maximum ID value. This way, when used in multiple meshes, all
* of them will have different IDs for their Face Sets. */
static void mesh_join_offset_face_sets_ID(const Mesh *mesh, int *face_set_offset)
static void mesh_join_offset_face_sets_ID(Mesh *mesh, int *face_set_offset)
{
if (!mesh->totpoly) {
return;
}
int *face_sets = (int *)CustomData_get_layer_named(
&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set");
int *face_sets = (int *)CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly);
if (!face_sets) {
return;
}
@ -1081,7 +1083,7 @@ static uint mirror_facehash(const void *ptr)
return ((v0 * 39) ^ (v1 * 31));
}
static int mirror_facerotation(MFace *a, MFace *b)
static int mirror_facerotation(const MFace *a, const MFace *b)
{
if (b->v4) {
if (a->v1 == b->v1 && a->v2 == b->v2 && a->v3 == b->v3 && a->v4 == b->v4) {
@ -1120,7 +1122,8 @@ static bool mirror_facecmp(const void *a, const void *b)
int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
{
Mesh *me = static_cast<Mesh *>(ob->data);
MFace mirrormf, *mf, *hashmf;
MFace mirrormf;
const MFace *mf, *hashmf;
GHash *fhash;
int *mirrorverts, *mirrorfaces;
@ -1135,7 +1138,8 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
mirrorfaces = static_cast<int *>(MEM_callocN(sizeof(int[2]) * totface, "MirrorFaces"));
const Span<float3> vert_positions = me_eval ? me_eval->vert_positions() : me->vert_positions();
MFace *mface = (MFace *)CustomData_get_layer(&(me_eval ? me_eval : me)->fdata, CD_MFACE);
const MFace *mface = (const MFace *)CustomData_get_layer(&(me_eval ? me_eval : me)->fdata,
CD_MFACE);
ED_mesh_mirror_spatial_table_begin(ob, em, me_eval);
@ -1147,7 +1151,7 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
for (a = 0, mf = mface; a < totface; a++, mf++) {
BLI_ghash_insert(fhash, mf, mf);
BLI_ghash_insert(fhash, (void *)mf, (void *)mf);
}
for (a = 0, mf = mface; a < totface; a++, mf++) {
@ -1162,7 +1166,7 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
std::swap(mirrormf.v2, mirrormf.v4);
}
hashmf = static_cast<MFace *>(BLI_ghash_lookup(fhash, &mirrormf));
hashmf = static_cast<const MFace *>(BLI_ghash_lookup(fhash, &mirrormf));
if (hashmf) {
mirrorfaces[a * 2] = hashmf - mface;
mirrorfaces[a * 2 + 1] = mirror_facerotation(&mirrormf, hashmf);

View File

@ -52,7 +52,7 @@ void ED_object_facemap_face_add(Object *ob, bFaceMap *fmap, int facenum)
Mesh *me = ob->data;
/* if there's is no facemap layer then create one */
if ((facemap = CustomData_get_layer(&me->pdata, CD_FACEMAP)) == NULL) {
if ((facemap = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly)) == NULL) {
facemap = CustomData_add_layer(&me->pdata, CD_FACEMAP, CD_SET_DEFAULT, NULL, me->totpoly);
}
@ -74,7 +74,7 @@ void ED_object_facemap_face_remove(Object *ob, bFaceMap *fmap, int facenum)
int *facemap;
Mesh *me = ob->data;
if ((facemap = CustomData_get_layer(&me->pdata, CD_FACEMAP)) == NULL) {
if ((facemap = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly)) == NULL) {
return;
}
@ -117,7 +117,7 @@ static void object_fmap_remap_object_mode(Object *ob, const int *remap)
Mesh *me = ob->data;
if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP);
int *map = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly);
if (map) {
for (int i = 0; i < me->totpoly; i++) {
if (map[i] != -1) {

View File

@ -2900,7 +2900,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
arm->edbo = MEM_cnew<ListBase>("edbo armature");
MVertSkin *mvert_skin = static_cast<MVertSkin *>(
CustomData_get_layer(&me->vdata, CD_MVERT_SKIN));
CustomData_get_layer_for_write(&me->vdata, CD_MVERT_SKIN, me->totvert));
int *emap_mem;
MeshElemMap *emap;
BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me_edges.data(), me->totvert, me->totedge);

View File

@ -1454,9 +1454,9 @@ void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), Part
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
const MFace *mfaces = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (i = 0; i < totface; i++, vec += 6, nor += 6) {
MFace *mface = &mfaces[i];
const MFace *mface = &mfaces[i];
copy_v3_v3(vec, positions[mface->v1]);
copy_v3_v3(nor, vert_normals[mface->v1]);
@ -3564,9 +3564,10 @@ static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagg
}
if (newtotpart != psys->totpart) {
MFace *mtessface = use_dm_final_indices ?
(MFace *)CustomData_get_layer(&psmd_eval->mesh_final->fdata, CD_MFACE) :
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE);
const MFace *mtessface = use_dm_final_indices ?
(const MFace *)CustomData_get_layer(&psmd_eval->mesh_final->fdata,
CD_MFACE) :
(const MFace *)CustomData_get_layer(&me->fdata, CD_MFACE);
/* allocate new arrays and copy existing */
new_pars = MEM_callocN(newtotpart * sizeof(ParticleData), "ParticleData new");
@ -4136,7 +4137,7 @@ static int particle_intersect_mesh(Depsgraph *depsgraph,
float radius,
float *ipoint)
{
MFace *mface = NULL;
const MFace *mface = NULL;
int i, totface, intersect = 0;
float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3];
float cur_ipoint[3];
@ -4173,7 +4174,7 @@ static int particle_intersect_mesh(Depsgraph *depsgraph,
}
totface = mesh->totface;
mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
mface = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
/* lets intersect the faces */

View File

@ -705,7 +705,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
PTCacheEditPoint *edit_point;
PTCacheEditKey *ekey;
BVHTreeFromMesh bvhtree = {NULL};
MFace *mface = NULL, *mf;
const MFace *mface = NULL, *mf;
const MEdge *medge = NULL, *me;
Mesh *mesh, *target_mesh;
int numverts;

View File

@ -808,8 +808,10 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
memset(&oglrender->scene->customdata_mask_modal,
0,
sizeof(oglrender->scene->customdata_mask_modal));
ED_view3d_datamask(
oglrender->view_layer, oglrender->v3d, &oglrender->scene->customdata_mask_modal);
ED_view3d_datamask(oglrender->scene,
oglrender->view_layer,
oglrender->v3d,
&oglrender->scene->customdata_mask_modal);
/* apply immediately in case we're rendering from a script,
* running notifiers again will overwrite */

View File

@ -286,6 +286,7 @@ static void curves_sculptmode_enter(bContext *C)
ob->mode = OB_MODE_SCULPT_CURVES;
ED_paint_cursor_start(&curves_sculpt->paint, CURVES_SCULPT_mode_poll_view3d);
paint_init_pivot(ob, scene);
/* Necessary to change the object mode on the evaluated object. */
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);

View File

@ -77,7 +77,8 @@ static void partialvis_update_mesh(Object *ob,
const int *vert_indices = BKE_pbvh_node_get_vert_indices(node);
paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
bool *hide_vert = CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert");
bool *hide_vert = CustomData_get_layer_named_for_write(
&me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert);
if (hide_vert == NULL) {
hide_vert = CustomData_add_layer_named(
&me->vdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totvert, ".hide_vert");

View File

@ -759,23 +759,47 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
/******************** texture paint toggle operator ********************/
void paint_init_pivot(Object *ob, Scene *scene)
static void paint_init_pivot_mesh(Object *ob, float location[3])
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
if (!me_eval) {
me_eval = (const Mesh *)ob->data;
}
float location[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
if (!BKE_mesh_minmax(me_eval, location, max)) {
if (!BKE_mesh_minmax(me_eval, min, max)) {
zero_v3(location);
zero_v3(max);
}
interp_v3_v3v3(location, location, max, 0.5f);
interp_v3_v3v3(location, min, max, 0.5f);
}
static void paint_init_pivot_curves(Object *ob, float location[3])
{
const BoundBox *bbox = BKE_object_boundbox_get(ob);
interp_v3_v3v3(location, bbox->vec[0], bbox->vec[6], 0.5f);
}
void paint_init_pivot(Object *ob, Scene *scene)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
float location[3];
switch (ob->type) {
case OB_MESH:
paint_init_pivot_mesh(ob, location);
break;
case OB_CURVES:
paint_init_pivot_curves(ob, location);
break;
default:
BLI_assert_unreachable();
ups->last_stroke_valid = false;
return;
}
mul_m4_v3(ob->object_to_world, location);
ups->last_stroke_valid = true;

View File

@ -1408,7 +1408,8 @@ static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *s
SculptSession *ss = object->sculpt;
Mesh *mesh = (Mesh *)object->data;
ss->face_sets = CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set");
ss->face_sets = CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly);
if (ss->face_sets) {
/* Assign a new Face Set ID to the new faces created by the trim operation. */
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data);

View File

@ -173,7 +173,8 @@ static void SCULPT_dynamic_topology_disable_ex(
me->face_sets_color_default = 1;
/* Sync the visibility to vertices manually as the pmap is still not initialized. */
bool *hide_vert = (bool *)CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert");
bool *hide_vert = (bool *)CustomData_get_layer_named_for_write(
&me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert);
if (hide_vert != NULL) {
memset(hide_vert, 0, sizeof(bool) * me->totvert);
}

View File

@ -74,8 +74,8 @@ int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh)
void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id)
{
int *face_sets = static_cast<int *>(
CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set"));
int *face_sets = static_cast<int *>(CustomData_get_layer_named_for_write(
&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly));
if (!face_sets) {
return;
}
@ -613,7 +613,8 @@ static void sculpt_face_sets_init_loop(Object *ob, const int mode)
}
}
else if (mode == SCULPT_FACE_SETS_FROM_FACE_MAPS) {
const int *face_maps = static_cast<int *>(CustomData_get_layer(&mesh->pdata, CD_FACEMAP));
const int *face_maps = static_cast<const int *>(
CustomData_get_layer(&mesh->pdata, CD_FACEMAP));
for (const int i : IndexRange(mesh->totpoly)) {
ss->face_sets[i] = face_maps ? face_maps[i] : 1;
}

View File

@ -108,6 +108,9 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node
const asset_system::AssetCatalog *catalog = all_library->catalog_service->find_catalog(
meta_data.catalog_id);
if (catalog == nullptr) {
return true;
}
assets_per_path.add(catalog->path, LibraryAsset{all_library_ref, asset});
return true;
});
@ -121,6 +124,9 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node
}
asset_system::AssetCatalog *catalog = all_library->catalog_service->find_catalog(
item.get_catalog_id());
if (catalog == nullptr) {
return;
}
catalogs_with_node_assets.insert_item(*catalog);
});

View File

@ -294,7 +294,7 @@ IndexMask GeometryDataSource::apply_selection_filter(Vector<int64_t> &indices) c
BMesh *bm = mesh_orig->edit_mesh->bm;
BM_mesh_elem_table_ensure(bm, BM_VERT);
const int *orig_indices = (int *)CustomData_get_layer(&mesh_eval->vdata, CD_ORIGINDEX);
const int *orig_indices = (const int *)CustomData_get_layer(&mesh_eval->vdata, CD_ORIGINDEX);
if (orig_indices != nullptr) {
/* Use CD_ORIGINDEX layer if it exists. */
VArray<bool> selection = attributes_eval.adapt_domain<bool>(

Some files were not shown because too many files have changed in this diff Show More