Animation: Add "Frame Channel" operators #104523
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}, {}),
|
||||
])
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"));
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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]>(
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue