Merged changes in the trunk up to revision 55700.
Conflicts resolved: source/blender/editors/mesh/mesh_intern.h
This commit is contained in:
commit
5524ed9ba2
@ -1070,28 +1070,28 @@ elseif(WIN32)
|
||||
set(OPENCOLLADA ${LIBDIR}/opencollada)
|
||||
|
||||
set(OPENCOLLADA_INCLUDE_DIRS
|
||||
${LIBDIR}/opencollada/include/COLLADAStreamWriter/include
|
||||
${LIBDIR}/opencollada/include/COLLADABaseUtils/include
|
||||
${LIBDIR}/opencollada/include/COLLADAFramework/include
|
||||
${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include
|
||||
${LIBDIR}/opencollada/include/GeneratedSaxParser/include
|
||||
${OPENCOLLADA}/include/opencollada/COLLADAStreamWriter
|
||||
${OPENCOLLADA}/include/opencollada/COLLADABaseUtils
|
||||
${OPENCOLLADA}/include/opencollada/COLLADAFramework
|
||||
${OPENCOLLADA}/include/opencollada/COLLADASaxFrameworkLoader
|
||||
${OPENCOLLADA}/include/opencollada/GeneratedSaxParser
|
||||
)
|
||||
set_lib_path(OPENCOLLADA_LIBPATH "opencollada")
|
||||
|
||||
set(OPENCOLLADA_LIBRARIES
|
||||
${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADASaxFrameworkLoader.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADAFramework.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADABaseUtils.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADAStreamWriter.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/MathMLSolver.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/GeneratedSaxParser.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/xml2.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/buffer.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/ftoa.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/UTF.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADASaxFrameworkLoader.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADAFramework.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADABaseUtils.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADAStreamWriter.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/MathMLSolver.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/GeneratedSaxParser.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/xml.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/buffer.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/ftoa.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/UTF.lib
|
||||
)
|
||||
set(PCRE_LIBRARIES
|
||||
${OPENCOLLADA_LIBPATH}/lib/pcre.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/opencollada/pcre.lib
|
||||
)
|
||||
|
||||
unset(OPENCOLLADA_LIBPATH)
|
||||
@ -1292,13 +1292,13 @@ elseif(WIN32)
|
||||
if(WITH_OPENCOLLADA)
|
||||
set(OPENCOLLADA ${LIBDIR}/opencollada)
|
||||
set(OPENCOLLADA_INCLUDE_DIRS
|
||||
${LIBDIR}/opencollada/include/COLLADAStreamWriter/include
|
||||
${LIBDIR}/opencollada/include/COLLADABaseUtils/include
|
||||
${LIBDIR}/opencollada/include/COLLADAFramework/include
|
||||
${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include
|
||||
${LIBDIR}/opencollada/include/GeneratedSaxParser/include
|
||||
${OPENCOLLADA}/include/COLLADAStreamWriter
|
||||
${OPENCOLLADA}/include/COLLADABaseUtils
|
||||
${OPENCOLLADA}/include/COLLADAFramework
|
||||
${OPENCOLLADA}/include/COLLADASaxFrameworkLoader
|
||||
${OPENCOLLADA}/include/GeneratedSaxParser
|
||||
)
|
||||
set(OPENCOLLADA_LIBPATH ${OPENCOLLADA}/lib ${OPENCOLLADA}/lib)
|
||||
set(OPENCOLLADA_LIBPATH ${OPENCOLLADA}/lib/opencollada)
|
||||
if(WITH_MINGW64)
|
||||
set(OPENCOLLADA_LIBRARIES OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver pcre buffer ftoa xml)
|
||||
else()
|
||||
|
@ -272,7 +272,9 @@ project_eclipse:
|
||||
check_cppcheck:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; \
|
||||
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
|
||||
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py 2> \
|
||||
$(BLENDER_DIR)/check_cppcheck.txt
|
||||
@echo "written: check_cppcheck.txt"
|
||||
|
||||
check_clang_array:
|
||||
$(CMAKE_CONFIG)
|
||||
|
@ -1066,8 +1066,8 @@ compile_OpenCOLLADA() {
|
||||
# XXX For now, always update from latest repo...
|
||||
git pull origin master
|
||||
|
||||
# XXX We have to stick to this revision, the next one introduced a change to ExtraHandler' parseElement signature :/
|
||||
git checkout c89cf095c40aa2a518b1104c448825eacc92d174
|
||||
# Stick to same rev as windows' libs...
|
||||
git checkout e886e196673222f2f4bc32b936dc96419fff815f
|
||||
git reset --hard
|
||||
|
||||
# Always refresh the whole build!
|
||||
|
@ -156,9 +156,9 @@ else:
|
||||
if builder.find('win') != -1:
|
||||
dlls = ('msvcm90.dll', 'msvcp90.dll', 'msvcr90.dll', 'vcomp90.dll', 'Microsoft.VC90.CRT.manifest', 'Microsoft.VC90.OpenMP.manifest')
|
||||
if builder.find('win64') == -1:
|
||||
dlls_path = 'C:\\b\\redist\\x86'
|
||||
dlls_path = 'C:\\b\\redist\\x86'
|
||||
else:
|
||||
dlls_path = 'C:\\b\\redist\\amd64'
|
||||
dlls_path = 'C:\\b\\redist\\amd64'
|
||||
for dll in dlls:
|
||||
shutil.copyfile(os.path.join(dlls_path, dll), os.path.join(install_dir, dll))
|
||||
|
||||
|
@ -41,9 +41,9 @@ CHECKER_ARGS = [
|
||||
# not sure why this is needed, but it is.
|
||||
"-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"),
|
||||
"--suppress=*:%s/extern/glew/include/GL/glew.h:241" % project_source_info.SOURCE_DIR,
|
||||
# "--max-configs=1", # speeds up execution
|
||||
"--max-configs=1", # speeds up execution
|
||||
# "--check-config", # when includes are missing
|
||||
# "--enable=all", # if you want sixty hundred pedantic suggestions
|
||||
"--enable=all", # if you want sixty hundred pedantic suggestions
|
||||
]
|
||||
|
||||
if USE_QUIET:
|
||||
|
@ -141,9 +141,9 @@ BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver expat pcre buffer ftoa'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
|
||||
|
||||
#Cycles
|
||||
WITH_BF_CYCLES = True
|
||||
|
@ -139,9 +139,9 @@ BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml pcre buffer ftoa UTF'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
|
||||
|
||||
WITH_BF_3DMOUSE = True
|
||||
|
||||
|
@ -138,9 +138,9 @@ BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver pcre buffer ftoa xml'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
|
||||
|
||||
#Cycles
|
||||
WITH_BF_CYCLES = True
|
||||
|
@ -135,9 +135,9 @@ BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml pcre buffer ftoa UTF'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
|
||||
|
||||
WITH_BF_3DMOUSE = True
|
||||
|
||||
|
2
extern/recastnavigation/recast-capi.cpp
vendored
2
extern/recastnavigation/recast-capi.cpp
vendored
@ -309,7 +309,7 @@ static inline void swapfunc(char* a, char* b, int n, int swaptype)
|
||||
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
|
||||
#define CMP(t, x, y) (cmp((t), (x), (y)))
|
||||
|
||||
static inline char * med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk)
|
||||
static inline char *med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk)
|
||||
{
|
||||
return CMP(thunk, a, b) < 0 ?
|
||||
(CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
|
||||
|
@ -41,53 +41,65 @@ extern "C" {
|
||||
#include "ffmpeg_compat.h"
|
||||
}
|
||||
|
||||
int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer)
|
||||
int AUD_FFMPEGReader::decode(AVPacket& packet, AUD_Buffer& buffer)
|
||||
{
|
||||
// save packet parameters
|
||||
uint8_t *audio_pkg_data = packet->data;
|
||||
int audio_pkg_size = packet->size;
|
||||
AVFrame* frame = NULL;
|
||||
int got_frame;
|
||||
int read_length;
|
||||
uint8_t* orig_data = packet.data;
|
||||
int orig_size = packet.size;
|
||||
|
||||
int buf_size = buffer.getSize();
|
||||
int buf_pos = 0;
|
||||
|
||||
int read_length, data_size;
|
||||
|
||||
AVPacket tmp_pkt;
|
||||
|
||||
av_init_packet(&tmp_pkt);
|
||||
|
||||
// as long as there is still data in the package
|
||||
while(audio_pkg_size > 0)
|
||||
while(packet.size > 0)
|
||||
{
|
||||
// resize buffer if needed
|
||||
if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE)
|
||||
{
|
||||
buffer.resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true);
|
||||
buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||
}
|
||||
got_frame = 0;
|
||||
|
||||
// read samples from the packet
|
||||
data_size = buf_size - buf_pos;
|
||||
if(!frame)
|
||||
frame = avcodec_alloc_frame();
|
||||
else
|
||||
avcodec_get_frame_defaults(frame);
|
||||
|
||||
tmp_pkt.data = audio_pkg_data;
|
||||
tmp_pkt.size = audio_pkg_size;
|
||||
|
||||
read_length = avcodec_decode_audio3(
|
||||
m_codecCtx,
|
||||
(int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos),
|
||||
&data_size, &tmp_pkt);
|
||||
|
||||
// read error, next packet!
|
||||
read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
|
||||
if(read_length < 0)
|
||||
break;
|
||||
|
||||
buf_pos += data_size;
|
||||
if(got_frame)
|
||||
{
|
||||
int data_size = av_samples_get_buffer_size(NULL, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);
|
||||
|
||||
// move packet parameters
|
||||
audio_pkg_data += read_length;
|
||||
audio_pkg_size -= read_length;
|
||||
if(buf_size - buf_pos < data_size)
|
||||
{
|
||||
buffer.resize(buf_size + data_size, true);
|
||||
buf_size += data_size;
|
||||
}
|
||||
|
||||
if(m_tointerleave)
|
||||
{
|
||||
int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
|
||||
for(int channel = 0; channel < m_codecCtx->channels; channel++)
|
||||
{
|
||||
for(int i = 0; i < frame->nb_samples; i++)
|
||||
{
|
||||
memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
|
||||
frame->data[channel] + i * single_size, single_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[1], data_size);
|
||||
|
||||
buf_pos += data_size;
|
||||
}
|
||||
packet.size -= read_length;
|
||||
packet.data += read_length;
|
||||
}
|
||||
|
||||
packet.data = orig_data;
|
||||
packet.size = orig_size;
|
||||
av_free(frame);
|
||||
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
@ -133,11 +145,6 @@ void AUD_FFMPEGReader::init()
|
||||
if(!aCodec)
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error);
|
||||
|
||||
#ifdef FFMPEG_SAMPLE_FMT_S16P_SUPPORTED
|
||||
if(m_codecCtx->sample_fmt == AV_SAMPLE_FMT_S16P)
|
||||
m_codecCtx->request_sample_fmt = AV_SAMPLE_FMT_S16;
|
||||
#endif
|
||||
|
||||
if(avcodec_open2(m_codecCtx, aCodec, NULL) < 0)
|
||||
AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error);
|
||||
|
||||
@ -145,8 +152,9 @@ void AUD_FFMPEGReader::init()
|
||||
//dump_format(m_formatCtx, 0, NULL, 0);
|
||||
|
||||
m_specs.channels = (AUD_Channels) m_codecCtx->channels;
|
||||
m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
|
||||
|
||||
switch(m_codecCtx->sample_fmt)
|
||||
switch(av_get_packed_sample_fmt(m_codecCtx->sample_fmt))
|
||||
{
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
m_convert = AUD_convert_u8_float;
|
||||
@ -320,7 +328,7 @@ void AUD_FFMPEGReader::seek(int position)
|
||||
if(packet.stream_index == m_stream)
|
||||
{
|
||||
// decode the package
|
||||
m_pkgbuf_left = decode(&packet, m_pkgbuf);
|
||||
m_pkgbuf_left = decode(packet, m_pkgbuf);
|
||||
search = false;
|
||||
|
||||
// check position
|
||||
@ -405,7 +413,7 @@ void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
|
||||
if(packet.stream_index == m_stream)
|
||||
{
|
||||
// decode the package
|
||||
pkgbuf_pos = decode(&packet, m_pkgbuf);
|
||||
pkgbuf_pos = decode(packet, m_pkgbuf);
|
||||
|
||||
// copy to output buffer
|
||||
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
|
||||
|
@ -111,13 +111,18 @@ private:
|
||||
*/
|
||||
int64_t m_membufferpos;
|
||||
|
||||
/**
|
||||
* Whether the audio data has to be interleaved after reading.
|
||||
*/
|
||||
bool m_tointerleave;
|
||||
|
||||
/**
|
||||
* Decodes a packet into the given buffer.
|
||||
* \param packet The AVPacket to decode.
|
||||
* \param buffer The target buffer.
|
||||
* \return The count of read bytes.
|
||||
*/
|
||||
int decode(AVPacket* packet, AUD_Buffer& buffer);
|
||||
int decode(AVPacket& packet, AUD_Buffer& buffer);
|
||||
|
||||
/**
|
||||
* Initializes the object.
|
||||
|
@ -416,7 +416,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
|
||||
default=0.0,
|
||||
step=1,
|
||||
precision=4,
|
||||
subtype = 'DISTANCE'
|
||||
subtype='DISTANCE',
|
||||
)
|
||||
cls.aperture_blades = IntProperty(
|
||||
name="Aperture Blades",
|
||||
|
@ -219,7 +219,7 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
|
||||
sub.label(text="Final Render:")
|
||||
sub.prop(rd, "use_persistent_data", text="Persistent Images")
|
||||
|
||||
|
||||
|
||||
class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel):
|
||||
bl_label = "OpenGL Render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@ -230,18 +230,18 @@ class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel):
|
||||
rd = context.scene.render
|
||||
|
||||
split = layout.split()
|
||||
|
||||
|
||||
col = split.column()
|
||||
col.prop(rd, "use_antialiasing")
|
||||
sub = col.row()
|
||||
sub.active = rd.use_antialiasing
|
||||
sub.prop(rd, "antialiasing_samples", expand=True)
|
||||
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Alpha:")
|
||||
col.prop(rd, "alpha_mode", text="")
|
||||
|
||||
|
||||
|
||||
|
||||
class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Layers"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
@ -902,8 +902,8 @@ class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
|
||||
split = layout.split(percentage=0.2)
|
||||
split.label(text="Type:")
|
||||
split.prop(tex, "type", text="")
|
||||
|
||||
|
||||
|
||||
|
||||
class CyclesTexture_PT_node(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Node"
|
||||
bl_context = "texture"
|
||||
@ -932,7 +932,7 @@ class CyclesTexture_PT_mapping(CyclesButtonsPanel, Panel):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
|
||||
node = context.texture_node
|
||||
|
||||
mapping = node.texture_mapping
|
||||
@ -964,7 +964,7 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
|
||||
node = context.texture_node
|
||||
|
||||
mapping = node.color_mapping
|
||||
|
@ -576,7 +576,7 @@ void BlenderSession::update_status_progress()
|
||||
timestatus += ", " + b_rlay_name;
|
||||
timestatus += " | ";
|
||||
|
||||
BLI_timestr(total_time, time_str);
|
||||
BLI_timestr(total_time, time_str, sizeof(time_str));
|
||||
timestatus += "Elapsed: " + string(time_str) + " | ";
|
||||
|
||||
if(substatus.size() > 0)
|
||||
|
@ -30,7 +30,7 @@
|
||||
* todo: clean this up ... */
|
||||
|
||||
extern "C" {
|
||||
void BLI_timestr(double _time, char *str);
|
||||
void BLI_timestr(double _time, char *str, size_t maxlen);
|
||||
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
|
||||
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
|
||||
unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);
|
||||
|
@ -365,6 +365,45 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* remove unused mix closure input when factor is 0.0 or 1.0 */
|
||||
if(node->special_type == SHADER_SPECIAL_TYPE_MIX_CLOSURE) {
|
||||
MixClosureNode *mix = static_cast<MixClosureNode*>(node);
|
||||
/* Check for closure links and make sure factor link is disconnected */
|
||||
if(mix->outputs[0]->links.size() && mix->inputs[1]->link && mix->inputs[2]->link && !mix->inputs[0]->link) {
|
||||
|
||||
/* Factor 0.0 */
|
||||
if(mix->inputs[0]->value.x == 0.0f) {
|
||||
ShaderOutput *output = mix->inputs[1]->link;
|
||||
vector<ShaderInput*> inputs = mix->outputs[0]->links;
|
||||
|
||||
foreach(ShaderInput *sock, mix->inputs)
|
||||
if(sock->link)
|
||||
disconnect(sock);
|
||||
|
||||
foreach(ShaderInput *input, inputs) {
|
||||
disconnect(input);
|
||||
if (output)
|
||||
connect(output, input);
|
||||
}
|
||||
}
|
||||
/* Factor 1.0 */
|
||||
else if (mix->inputs[0]->value.x == 1.0f) {
|
||||
ShaderOutput *output = mix->inputs[2]->link;
|
||||
vector<ShaderInput*> inputs = mix->outputs[0]->links;
|
||||
|
||||
foreach(ShaderInput *sock, mix->inputs)
|
||||
if(sock->link)
|
||||
disconnect(sock);
|
||||
|
||||
foreach(ShaderInput *input, inputs) {
|
||||
disconnect(input);
|
||||
if (output)
|
||||
connect(output, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,14 +374,14 @@ class Octree
|
||||
/**
|
||||
* Functions to patch rings in a node
|
||||
*/
|
||||
Node *patch(Node * node, int st[3], int len, PathList * rings);
|
||||
Node *patchSplit(Node * node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2);
|
||||
Node *patchSplitSingle(Node * node, int st[3], int len, PathElement * head, int dir, PathList * &nrings1, PathList * &nrings2);
|
||||
Node *connectFace(Node * node, int st[3], int len, int dir, PathElement * f1, PathElement * f2);
|
||||
Node *locateCell(InternalNode * node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen);
|
||||
Node *patch(Node *node, int st[3], int len, PathList * rings);
|
||||
Node *patchSplit(Node *node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2);
|
||||
Node *patchSplitSingle(Node *node, int st[3], int len, PathElement *head, int dir, PathList * &nrings1, PathList * &nrings2);
|
||||
Node *connectFace(Node *node, int st[3], int len, int dir, PathElement * f1, PathElement * f2);
|
||||
Node *locateCell(InternalNode *node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen);
|
||||
void compressRing(PathElement *& ring);
|
||||
void getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q);
|
||||
LeafNode *patchAdjacent(InternalNode * node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha);
|
||||
LeafNode *patchAdjacent(InternalNode *node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha);
|
||||
int findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2);
|
||||
int getSide(PathElement *e, int pos, int dir);
|
||||
int isEqual(PathElement *e1, PathElement *e2);
|
||||
@ -412,8 +412,8 @@ class Octree
|
||||
/************************************************************************/
|
||||
void floodFill();
|
||||
void clearProcessBits(Node *node, int height);
|
||||
int floodFill(LeafNode * leaf, int st[3], int len, int height, int threshold);
|
||||
int floodFill(Node * node, int st[3], int len, int height, int threshold);
|
||||
int floodFill(LeafNode *leaf, int st[3], int len, int height, int threshold);
|
||||
int floodFill(Node *node, int st[3], int len, int height, int threshold);
|
||||
|
||||
/**
|
||||
* Write out polygon file
|
||||
@ -421,9 +421,9 @@ class Octree
|
||||
void writeOut();
|
||||
|
||||
void countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface);
|
||||
void generateMinimizer(Node * node, int st[3], int len, int height, int& offset);
|
||||
void generateMinimizer(Node *node, int st[3], int len, int height, int& offset);
|
||||
void computeMinimizer(const LeafNode * leaf, int st[3], int len,
|
||||
float rvalue[3]) const;
|
||||
float rvalue[3]) const;
|
||||
/**
|
||||
* Traversal functions to generate polygon model
|
||||
* op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY
|
||||
|
@ -691,7 +691,8 @@ bool LbmFsgrSolver::initializeSolverMemory()
|
||||
calculateMemreqEstimate( mSizex, mSizey, mSizez,
|
||||
mMaxRefine, mFarFieldSize, &memEstFromFunc, &memEstFine, &memreqStr );
|
||||
|
||||
double memLimit;
|
||||
bool noLimit = false;
|
||||
double memLimit = 0.;
|
||||
string memLimStr("-");
|
||||
if(sizeof(void*)==4) {
|
||||
// 32bit system, limit to 2GB
|
||||
@ -699,8 +700,9 @@ bool LbmFsgrSolver::initializeSolverMemory()
|
||||
memLimStr = string("2GB");
|
||||
} else {
|
||||
// 64bit, just take 16GB as limit for now...
|
||||
memLimit = 16.0* 1024.0*1024.0*1024.0;
|
||||
memLimStr = string("16GB");
|
||||
// memLimit = 16.0* 1024.0*1024.0*1024.0;
|
||||
// memLimStr = string("16GB");
|
||||
noLimit = true;
|
||||
}
|
||||
|
||||
// restrict max. chunk of 1 mem block to 1GB for windos
|
||||
@ -724,7 +726,7 @@ bool LbmFsgrSolver::initializeSolverMemory()
|
||||
memBlockAllocProblem = true;
|
||||
}
|
||||
|
||||
if(memEstFromFunc>memLimit || memBlockAllocProblem) {
|
||||
if(!noLimit && (memEstFromFunc>memLimit || memBlockAllocProblem)) {
|
||||
sizeReduction *= 0.9;
|
||||
mSizex = (int)(orgSx * sizeReduction);
|
||||
mSizey = (int)(orgSy * sizeReduction);
|
||||
|
@ -110,6 +110,16 @@ int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
|
||||
#define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
|
||||
#endif
|
||||
|
||||
#if ((LIBAVUTIL_VERSION_MAJOR < 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 54))
|
||||
static inline
|
||||
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
|
||||
return AV_SAMPLE_FMT_NONE;
|
||||
return sample_fmt;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24) && (LIBAVFORMAT_VERSION_MICRO < 2)))
|
||||
#define avformat_close_input(x) av_close_input_file(*(x))
|
||||
#endif
|
||||
|
@ -108,10 +108,6 @@ typedef uint64_t u_int64_t;
|
||||
#include <inttypes.h>
|
||||
|
||||
#elif defined(FREE_WINDOWS)
|
||||
#ifndef FREE_WINDOWS64
|
||||
/* define htoln here, there must be a syntax error in winsock2.h in MinGW */
|
||||
unsigned long __attribute__((__stdcall__)) htonl(unsigned long);
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
#else
|
||||
@ -144,4 +140,3 @@ unsigned long __attribute__((__stdcall__)) htonl(unsigned long);
|
||||
#endif
|
||||
|
||||
#endif /* __MEM_SYS_TYPES_H__ */
|
||||
|
||||
|
@ -48,10 +48,12 @@ if(WITH_OPENCOLORIO)
|
||||
|
||||
list(APPEND INC_SYS
|
||||
${OPENCOLORIO_INCLUDE_DIRS}
|
||||
${GLEW_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
list(APPEND SRC
|
||||
ocio_impl.cc
|
||||
ocio_impl_glsl.cc
|
||||
)
|
||||
|
||||
if(WIN32 AND NOT MINGW)
|
||||
|
@ -35,10 +35,12 @@ defs = []
|
||||
if env['WITH_BF_OCIO']:
|
||||
defs.append('WITH_OCIO')
|
||||
incs += ' ' + env['BF_OCIO_INC']
|
||||
incs += ' ' + '#/extern/glew/include'
|
||||
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||
incs += ' ' + env['BF_BOOST_INC']
|
||||
else:
|
||||
sources.remove('ocio_impl.cc')
|
||||
sources.remove('ocio_impl_glsl.cc')
|
||||
|
||||
env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185])
|
||||
|
@ -380,3 +380,15 @@ void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *)
|
||||
void FallbackImpl::matrixTransformScale(float * , float * , const float *)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::freeGLState(struct OCIO_GLSLDrawState *state_r)
|
||||
{
|
||||
}
|
||||
|
@ -282,3 +282,18 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4
|
||||
{
|
||||
impl->matrixTransformScale(m44, offset4, scale4f);
|
||||
}
|
||||
|
||||
void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
|
||||
{
|
||||
impl->setupGLSLDraw(state_r, processor);
|
||||
}
|
||||
|
||||
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state)
|
||||
{
|
||||
impl->finishGLSLDraw(state);
|
||||
}
|
||||
|
||||
void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state)
|
||||
{
|
||||
impl->freeGLState(state);
|
||||
}
|
||||
|
@ -32,6 +32,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct OCIO_GLSLDrawState;
|
||||
|
||||
#define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
|
||||
|
||||
#define OCIO_ROLE_SCENE_LINEAR "scene_linear"
|
||||
@ -119,6 +121,10 @@ void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
|
||||
|
||||
void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4);
|
||||
|
||||
void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
|
||||
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state);
|
||||
void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -26,8 +26,16 @@
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
|
||||
using namespace OCIO_NAMESPACE;
|
||||
@ -50,6 +58,8 @@ using namespace OCIO_NAMESPACE;
|
||||
#define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type()
|
||||
#define MEM_DELETE(what, type) if(what) { ((type*)(what))->~type(); MEM_freeN(what); } (void)0
|
||||
|
||||
static const int LUT3D_EDGE_SIZE = 32;
|
||||
|
||||
static void OCIO_reportError(const char *err)
|
||||
{
|
||||
std::cerr << "OpenColorIO Error: " << err << std::endl;
|
||||
@ -541,3 +551,228 @@ void OCIOImpl::matrixTransformScale(float * m44, float * offset4, const float *s
|
||||
{
|
||||
MatrixTransform::Scale(m44, offset4, scale4f);
|
||||
}
|
||||
|
||||
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
|
||||
|
||||
/* Some of the GLSL transform related functions below are adopted from
|
||||
* ociodisplay utility of OpenColorIO project which are originally
|
||||
*
|
||||
* Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved.
|
||||
*/
|
||||
|
||||
typedef struct OCIO_GLSLDrawState {
|
||||
bool lut3d_texture_allocated; /* boolean flag indicating whether
|
||||
* lut texture is allocated
|
||||
*/
|
||||
|
||||
GLuint lut3d_texture; /* OGL texture ID for 3D LUT */
|
||||
|
||||
float *lut3d; /* 3D LUT table */
|
||||
|
||||
/* Cache */
|
||||
std::string lut3dcacheid;
|
||||
std::string shadercacheid;
|
||||
|
||||
/* GLSL stuff */
|
||||
GLuint fragShader;
|
||||
GLuint program;
|
||||
|
||||
/* Previous OpenGL state. */
|
||||
GLint last_texture, last_texture_unit;
|
||||
} OCIO_GLSLDrawState;
|
||||
|
||||
static const char * g_fragShaderText = ""
|
||||
"\n"
|
||||
"uniform sampler2D tex1;\n"
|
||||
"uniform sampler3D tex2;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n"
|
||||
" gl_FragColor = OCIODisplay(col, tex2);\n"
|
||||
"}\n";
|
||||
|
||||
static GLuint compileShaderText(GLenum shaderType, const char *text)
|
||||
{
|
||||
GLuint shader;
|
||||
GLint stat;
|
||||
|
||||
shader = glCreateShader(shaderType);
|
||||
glShaderSource(shader, 1, (const GLchar **) &text, NULL);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
|
||||
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog(shader, 1000, &len, log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static GLuint linkShaders(GLuint fragShader)
|
||||
{
|
||||
if (!fragShader)
|
||||
return 0;
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
if (fragShader)
|
||||
glAttachShader(program, fragShader);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
/* check link */
|
||||
{
|
||||
GLint stat;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog(program, 1000, &len, log);
|
||||
fprintf(stderr, "Shader link error:\n%s\n", log);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
static OCIO_GLSLDrawState *allocateOpenGLState(void)
|
||||
{
|
||||
OCIO_GLSLDrawState *state;
|
||||
|
||||
/* Allocate memory for state. */
|
||||
state = (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState),
|
||||
"OCIO OpenGL State struct");
|
||||
|
||||
/* Call constructors on new memory. */
|
||||
new (&state->lut3dcacheid) std::string("");
|
||||
new (&state->shadercacheid) std::string("");
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/* Ensure LUT texture and array are allocated */
|
||||
static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
|
||||
{
|
||||
int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
|
||||
|
||||
if (state->lut3d_texture_allocated)
|
||||
return;
|
||||
|
||||
glGenTextures(1, &state->lut3d_texture);
|
||||
|
||||
state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
|
||||
LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
|
||||
0, GL_RGB,GL_FLOAT, &state->lut3d);
|
||||
|
||||
state->lut3d_texture_allocated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup OpenGL contexts for a transform defined by processor using GLSL
|
||||
* All LUT allocating baking and shader compilation happens here.
|
||||
*
|
||||
* Once this function is called, callee could start drawing images
|
||||
* using regular 2D texture.
|
||||
*
|
||||
* When all drawing is finished, finishGLSLDraw shall be called to
|
||||
* restore OpenGL context to it's pre-GLSL draw state.
|
||||
*/
|
||||
void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
|
||||
{
|
||||
ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor;
|
||||
|
||||
/* Create state if needed. */
|
||||
OCIO_GLSLDrawState *state;
|
||||
if (!*state_r)
|
||||
*state_r = allocateOpenGLState();
|
||||
state = *state_r;
|
||||
|
||||
glGetIntegerv(GL_TEXTURE_2D, &state->last_texture);
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
|
||||
|
||||
ensureLUT3DAllocated(state);
|
||||
|
||||
/* Step 1: Create a GPU Shader Description */
|
||||
GpuShaderDesc shaderDesc;
|
||||
shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0);
|
||||
shaderDesc.setFunctionName("OCIODisplay");
|
||||
shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
|
||||
|
||||
/* Step 2: Compute the 3D LUT */
|
||||
std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
|
||||
if (lut3dCacheID != state->lut3dcacheid) {
|
||||
state->lut3dcacheid = lut3dCacheID;
|
||||
ocio_processor->getGpuLut3D(state->lut3d, shaderDesc);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
||||
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0,
|
||||
LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
|
||||
GL_RGB, GL_FLOAT, state->lut3d);
|
||||
}
|
||||
|
||||
/* Step 3: Compute the Shader */
|
||||
std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc);
|
||||
if (state->program == 0 || shaderCacheID != state->shadercacheid) {
|
||||
state->shadercacheid = shaderCacheID;
|
||||
|
||||
std::ostringstream os;
|
||||
os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
|
||||
os << g_fragShaderText;
|
||||
|
||||
if (state->fragShader)
|
||||
glDeleteShader(state->fragShader);
|
||||
state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
|
||||
|
||||
if (state->program)
|
||||
glDeleteProgram(state->program);
|
||||
|
||||
state->program = linkShaders(state->fragShader);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glUseProgram(state->program);
|
||||
glUniform1i(glGetUniformLocation(state->program, "tex1"), 0);
|
||||
glUniform1i(glGetUniformLocation(state->program, "tex2"), 1);
|
||||
}
|
||||
|
||||
void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
|
||||
{
|
||||
glActiveTexture(state->last_texture_unit);
|
||||
glBindTexture(GL_TEXTURE_2D, state->last_texture);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
|
||||
{
|
||||
using std::string;
|
||||
|
||||
if (state->lut3d_texture_allocated)
|
||||
glDeleteTextures(1, &state->lut3d_texture);
|
||||
|
||||
if (state->lut3d)
|
||||
MEM_freeN(state->lut3d);
|
||||
|
||||
state->lut3dcacheid.~string();
|
||||
state->shadercacheid.~string();
|
||||
|
||||
MEM_freeN(state);
|
||||
}
|
||||
|
@ -95,6 +95,10 @@ public:
|
||||
virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0;
|
||||
|
||||
virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0;
|
||||
|
||||
virtual void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) = 0;
|
||||
virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
|
||||
virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
|
||||
};
|
||||
|
||||
class FallbackImpl : public IOCIOImpl {
|
||||
@ -164,6 +168,10 @@ public:
|
||||
void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
|
||||
|
||||
void matrixTransformScale(float * m44, float * offset4, const float * scale4);
|
||||
|
||||
void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
|
||||
void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
|
||||
void freeGLState(struct OCIO_GLSLDrawState *state_r);
|
||||
};
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
@ -234,6 +242,10 @@ public:
|
||||
void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
|
||||
|
||||
void matrixTransformScale(float * m44, float * offset4, const float * scale4);
|
||||
|
||||
void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
|
||||
void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
|
||||
void freeGLState(struct OCIO_GLSLDrawState *state_r);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
274
intern/opencolorio/ocio_impl_glsl.cc
Normal file
274
intern/opencolorio/ocio_impl_glsl.cc
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Adapted from OpenColorIO with this license:
|
||||
*
|
||||
* Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Sony Pictures Imageworks nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Modifications Copyright 2013, Blender Foundation.
|
||||
*
|
||||
* Contributor(s): Sergey Sharybin
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
|
||||
using namespace OCIO_NAMESPACE;
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "ocio_impl.h"
|
||||
|
||||
static const int LUT3D_EDGE_SIZE = 32;
|
||||
|
||||
|
||||
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
|
||||
|
||||
typedef struct OCIO_GLSLDrawState {
|
||||
bool lut3d_texture_allocated; /* boolean flag indicating whether
|
||||
* lut texture is allocated
|
||||
*/
|
||||
|
||||
GLuint lut3d_texture; /* OGL texture ID for 3D LUT */
|
||||
|
||||
float *lut3d; /* 3D LUT table */
|
||||
|
||||
/* Cache */
|
||||
std::string lut3dcacheid;
|
||||
std::string shadercacheid;
|
||||
|
||||
/* GLSL stuff */
|
||||
GLuint fragShader;
|
||||
GLuint program;
|
||||
|
||||
/* Previous OpenGL state. */
|
||||
GLint last_texture, last_texture_unit;
|
||||
} OCIO_GLSLDrawState;
|
||||
|
||||
static const char * g_fragShaderText = ""
|
||||
"\n"
|
||||
"uniform sampler2D tex1;\n"
|
||||
"uniform sampler3D tex2;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n"
|
||||
" gl_FragColor = OCIODisplay(col, tex2);\n"
|
||||
"}\n";
|
||||
|
||||
static GLuint compileShaderText(GLenum shaderType, const char *text)
|
||||
{
|
||||
GLuint shader;
|
||||
GLint stat;
|
||||
|
||||
shader = glCreateShader(shaderType);
|
||||
glShaderSource(shader, 1, (const GLchar **) &text, NULL);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
|
||||
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog(shader, 1000, &len, log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static GLuint linkShaders(GLuint fragShader)
|
||||
{
|
||||
if (!fragShader)
|
||||
return 0;
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
if (fragShader)
|
||||
glAttachShader(program, fragShader);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
/* check link */
|
||||
{
|
||||
GLint stat;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog(program, 1000, &len, log);
|
||||
fprintf(stderr, "Shader link error:\n%s\n", log);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
static OCIO_GLSLDrawState *allocateOpenGLState(void)
|
||||
{
|
||||
OCIO_GLSLDrawState *state;
|
||||
|
||||
/* Allocate memory for state. */
|
||||
state = (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState),
|
||||
"OCIO OpenGL State struct");
|
||||
|
||||
/* Call constructors on new memory. */
|
||||
new (&state->lut3dcacheid) std::string("");
|
||||
new (&state->shadercacheid) std::string("");
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/* Ensure LUT texture and array are allocated */
|
||||
static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
|
||||
{
|
||||
int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
|
||||
|
||||
if (state->lut3d_texture_allocated)
|
||||
return;
|
||||
|
||||
glGenTextures(1, &state->lut3d_texture);
|
||||
|
||||
state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
|
||||
LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
|
||||
0, GL_RGB,GL_FLOAT, &state->lut3d);
|
||||
|
||||
state->lut3d_texture_allocated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup OpenGL contexts for a transform defined by processor using GLSL
|
||||
* All LUT allocating baking and shader compilation happens here.
|
||||
*
|
||||
* Once this function is called, callee could start drawing images
|
||||
* using regular 2D texture.
|
||||
*
|
||||
* When all drawing is finished, finishGLSLDraw shall be called to
|
||||
* restore OpenGL context to it's pre-GLSL draw state.
|
||||
*/
|
||||
void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
|
||||
{
|
||||
ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor;
|
||||
|
||||
/* Create state if needed. */
|
||||
OCIO_GLSLDrawState *state;
|
||||
if (!*state_r)
|
||||
*state_r = allocateOpenGLState();
|
||||
state = *state_r;
|
||||
|
||||
glGetIntegerv(GL_TEXTURE_2D, &state->last_texture);
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
|
||||
|
||||
ensureLUT3DAllocated(state);
|
||||
|
||||
/* Step 1: Create a GPU Shader Description */
|
||||
GpuShaderDesc shaderDesc;
|
||||
shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0);
|
||||
shaderDesc.setFunctionName("OCIODisplay");
|
||||
shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
|
||||
|
||||
/* Step 2: Compute the 3D LUT */
|
||||
std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
|
||||
if (lut3dCacheID != state->lut3dcacheid) {
|
||||
state->lut3dcacheid = lut3dCacheID;
|
||||
ocio_processor->getGpuLut3D(state->lut3d, shaderDesc);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
||||
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0,
|
||||
LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
|
||||
GL_RGB, GL_FLOAT, state->lut3d);
|
||||
}
|
||||
|
||||
/* Step 3: Compute the Shader */
|
||||
std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc);
|
||||
if (state->program == 0 || shaderCacheID != state->shadercacheid) {
|
||||
state->shadercacheid = shaderCacheID;
|
||||
|
||||
std::ostringstream os;
|
||||
os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
|
||||
os << g_fragShaderText;
|
||||
|
||||
if (state->fragShader)
|
||||
glDeleteShader(state->fragShader);
|
||||
state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
|
||||
|
||||
if (state->program)
|
||||
glDeleteProgram(state->program);
|
||||
|
||||
state->program = linkShaders(state->fragShader);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glUseProgram(state->program);
|
||||
glUniform1i(glGetUniformLocation(state->program, "tex1"), 0);
|
||||
glUniform1i(glGetUniformLocation(state->program, "tex2"), 1);
|
||||
}
|
||||
|
||||
void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
|
||||
{
|
||||
glActiveTexture(state->last_texture_unit);
|
||||
glBindTexture(GL_TEXTURE_2D, state->last_texture);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
|
||||
{
|
||||
using std::string;
|
||||
|
||||
if (state->lut3d_texture_allocated)
|
||||
glDeleteTextures(1, &state->lut3d_texture);
|
||||
|
||||
if (state->lut3d)
|
||||
MEM_freeN(state->lut3d);
|
||||
|
||||
state->lut3dcacheid.~string();
|
||||
state->shadercacheid.~string();
|
||||
|
||||
MEM_freeN(state);
|
||||
}
|
@ -98,8 +98,6 @@ typedef unsigned long uintptr_t;
|
||||
#include <inttypes.h>
|
||||
|
||||
#elif defined(FREE_WINDOWS)
|
||||
/* define htoln here, there must be a syntax error in winsock2.h in MinGW */
|
||||
unsigned long __attribute__((__stdcall__)) htonl(unsigned long);
|
||||
#include <stdint.h>
|
||||
|
||||
#else
|
||||
|
@ -28,12 +28,13 @@
|
||||
#endif
|
||||
|
||||
#include "utf_winfunc.h"
|
||||
#include "utfconv.h"
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
|
||||
|
||||
FILE * ufopen(const char * filename, const char * mode)
|
||||
FILE *ufopen(const char *filename, const char *mode)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
UTF16_ENCODE(filename);
|
||||
@ -119,7 +120,7 @@ int umkdir(const char *pathname)
|
||||
return r ? 0 : -1;
|
||||
}
|
||||
|
||||
char * u_alloc_getenv(const char *varname)
|
||||
char *u_alloc_getenv(const char *varname)
|
||||
{
|
||||
char * r = 0;
|
||||
wchar_t * str;
|
||||
|
@ -23,22 +23,26 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __UTF_WINFUNC_H__
|
||||
#define __UTF_WINFUNC_H__
|
||||
|
||||
#ifndef WIN32
|
||||
# error "This file can only compile on windows"
|
||||
#endif
|
||||
|
||||
#include "utfconv.h"
|
||||
#include <stdio.h>
|
||||
|
||||
FILE * ufopen(const char * filename, const char * mode);
|
||||
FILE *ufopen(const char * filename, const char * mode);
|
||||
int uopen(const char *filename, int oflag, int pmode);
|
||||
int uaccess(const char *filename, int mode);
|
||||
int urename(const char *oldname, const char *newname );
|
||||
int urename(const char *oldname, const char *newname);
|
||||
|
||||
char * u_alloc_getenv(const char *varname);
|
||||
char *u_alloc_getenv(const char *varname);
|
||||
void u_free_getenv(char *val);
|
||||
|
||||
int uput_getenv(const char *varname, char * value, size_t buffsize);
|
||||
int uput_getenv(const char *varname, char *value, size_t buffsize);
|
||||
int uputenv(const char *name, const char *value);
|
||||
|
||||
int umkdir(const char *pathname);
|
||||
|
||||
#endif /* __UTF_WINFUNC_H__ */
|
||||
|
@ -23,12 +23,13 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __UTFCONV_H__
|
||||
#define __UTFCONV_H__
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -100,3 +101,5 @@ wchar_t *alloc_utf16_from_8(const char *in8, size_t add);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __UTFCONV_H__ */
|
||||
|
@ -409,6 +409,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
import ast
|
||||
|
||||
bpy_struct = bpy.types.ID.__base__
|
||||
i18n_contexts = bpy.app.translations.contexts
|
||||
|
||||
root_paths = tuple(bpy.utils.resource_path(t) for t in ('USER', 'LOCAL', 'SYSTEM'))
|
||||
def make_rel(path):
|
||||
@ -445,7 +446,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
nds_ls.extend(nds)
|
||||
ret = _extract_string_merge(estr_ls, nds_ls)
|
||||
return ret
|
||||
|
||||
|
||||
def extract_strings_split(node):
|
||||
"""
|
||||
Returns a list args as returned by 'extract_strings()', But split into groups based on separate_nodes, this way
|
||||
@ -468,20 +469,33 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
return [_extract_string_merge(estr_ls, nds_ls) for estr_ls, nds_ls in bag]
|
||||
|
||||
|
||||
i18n_ctxt_ids = {v for v in bpy.app.translations.contexts_C_to_py.values()}
|
||||
def _ctxt_to_ctxt(node):
|
||||
return extract_strings(node)[0]
|
||||
# We must try, to some extend, to get contexts from vars instead of only literal strings...
|
||||
ctxt = extract_strings(node)[0]
|
||||
if ctxt:
|
||||
return ctxt
|
||||
# Basically, we search for attributes matching py context names, for now.
|
||||
# So non-literal contexts should be used that way:
|
||||
# i18n_ctxt = bpy.app.translations.contexts
|
||||
# foobar(text="Foo", text_ctxt=i18n_ctxt.id_object)
|
||||
if type(node) == ast.Attribute:
|
||||
if node.attr in i18n_ctxt_ids:
|
||||
#print(node, node.attr, getattr(i18n_contexts, node.attr))
|
||||
return getattr(i18n_contexts, node.attr)
|
||||
return i18n_contexts.default
|
||||
|
||||
def _op_to_ctxt(node):
|
||||
opname, _ = extract_strings(node)
|
||||
if not opname:
|
||||
return settings.DEFAULT_CONTEXT
|
||||
return i18n_contexts.default
|
||||
op = bpy.ops
|
||||
for n in opname.split('.'):
|
||||
op = getattr(op, n)
|
||||
try:
|
||||
return op.get_rna().bl_rna.translation_context
|
||||
except Exception as e:
|
||||
default_op_context = bpy.app.translations.contexts.operator_default
|
||||
default_op_context = i18n_contexts.operator_default
|
||||
print("ERROR: ", str(e))
|
||||
print(" Assuming default operator context '{}'".format(default_op_context))
|
||||
return default_op_context
|
||||
@ -492,7 +506,8 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
pgettext_variants = (
|
||||
("pgettext", ("_",)),
|
||||
("pgettext_iface", ("iface_",)),
|
||||
("pgettext_tip", ("tip_",))
|
||||
("pgettext_tip", ("tip_",)),
|
||||
("pgettext_data", ("data_",)),
|
||||
)
|
||||
pgettext_variants_args = {"msgid": (0, {"msgctxt": 1})}
|
||||
|
||||
@ -858,9 +873,8 @@ def dump_addon_messages(module_name, messages_formats, do_checks, settings):
|
||||
|
||||
# and make the diff!
|
||||
for key in minus_msgs:
|
||||
if key == settings.PO_HEADER_KEY:
|
||||
continue
|
||||
del msgs[key]
|
||||
if key != settings.PO_HEADER_KEY:
|
||||
del msgs[key]
|
||||
|
||||
if check_ctxt:
|
||||
for key in check_ctxt:
|
||||
@ -873,7 +887,7 @@ def dump_addon_messages(module_name, messages_formats, do_checks, settings):
|
||||
|
||||
# get strings from UI layout definitions text="..." args
|
||||
reports["check_ctxt"] = check_ctxt
|
||||
dump_messages_pytext(msgs, reports, addons, settings, addons_only=True)
|
||||
dump_py_messages(msgs, reports, {addon}, settings, addons_only=True)
|
||||
|
||||
print_info(reports, pot)
|
||||
|
||||
|
@ -240,7 +240,7 @@ PYGETTEXT_KEYWORDS = (() +
|
||||
for it in ("IFACE_", "TIP_", "DATA_", "N_")) +
|
||||
|
||||
tuple((r"{}\(\s*" + _ctxt_re + r"\s*,\s*" + _msg_re + r"\s*\)").format(it)
|
||||
for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_DATA_", "CTX_N_")) +
|
||||
for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_DATA_", "CTX_N_")) +
|
||||
|
||||
tuple(("{}\\((?:[^\"',]+,){{1,2}}\\s*" + _msg_re + r"\s*(?:\)|,)").format(it)
|
||||
for it in ("BKE_report", "BKE_reportf", "BKE_reports_prepend", "BKE_reports_prependf",
|
||||
@ -252,7 +252,7 @@ PYGETTEXT_KEYWORDS = (() +
|
||||
tuple(("{}\\((?:[^\"',]+,)\\s*" + _msg_re + r"\s*(?:\)|,)").format(it)
|
||||
for it in ("modifier_setError",)) +
|
||||
|
||||
tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" + \
|
||||
tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" +
|
||||
r"\s*,\s*)?(?:".join(_ctxt_re_gen(i) for i in range(PYGETTEXT_MAX_MULTI_CTXT)) + r")?\s*\)").format(it)
|
||||
for it in ("BLF_I18N_MSGID_MULTI_CTXT",))
|
||||
)
|
||||
@ -354,7 +354,7 @@ PARSER_PY_ID = "__PY__"
|
||||
PARSER_PY_MARKER_BEGIN = "\n# ##### BEGIN AUTOGENERATED I18N SECTION #####\n"
|
||||
PARSER_PY_MARKER_END = "\n# ##### END AUTOGENERATED I18N SECTION #####\n"
|
||||
|
||||
PARSER_MAX_FILE_SIZE = 2**24 # in bytes, i.e. 16 Mb.
|
||||
PARSER_MAX_FILE_SIZE = 2 ** 24 # in bytes, i.e. 16 Mb.
|
||||
|
||||
###############################################################################
|
||||
# PATHS
|
||||
|
@ -173,7 +173,7 @@ class I18nMessage:
|
||||
self.comment_lines.remove(l)
|
||||
lines_src = []
|
||||
lines_src_custom = []
|
||||
for src in sources:
|
||||
for src in sources:
|
||||
if is_valid_po_path(src):
|
||||
lines_src.append(self.settings.PO_COMMENT_PREFIX_SOURCE + src)
|
||||
else:
|
||||
|
@ -169,7 +169,7 @@ def bake_action(frame_start,
|
||||
euler_prev = None
|
||||
|
||||
for (f, matrix) in zip(frame_range, obj_info):
|
||||
name = "Action Bake" # XXX: placeholder
|
||||
name = "Action Bake" # XXX: placeholder
|
||||
obj.matrix_basis = matrix
|
||||
|
||||
obj.keyframe_insert("location", -1, f, name, options)
|
||||
|
@ -729,6 +729,7 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
|
||||
self.preset_operator,
|
||||
filter_ext=lambda ext: ext.lower() in {".py", ".xml"})
|
||||
|
||||
|
||||
class Region(StructRNA):
|
||||
__slots__ = ()
|
||||
|
||||
@ -782,9 +783,11 @@ def gen_valid_identifier(seq):
|
||||
if ch == '_' or ch.isalpha() or ch.isdigit():
|
||||
yield ch
|
||||
|
||||
|
||||
def sanitize_identifier(name):
|
||||
return ''.join(gen_valid_identifier(name))
|
||||
|
||||
|
||||
def unique_identifier(name, identifier_list):
|
||||
# First some basic sanitation, to make a usable identifier string from the name
|
||||
base = sanitize_identifier(name)
|
||||
@ -796,6 +799,7 @@ def unique_identifier(name, identifier_list):
|
||||
identifier = base + str(index)
|
||||
return identifier
|
||||
|
||||
|
||||
class RNAMetaNode(RNAMetaPropGroup):
|
||||
def __new__(cls, name, bases, classdict, **args):
|
||||
# Wrapper for node.init, to add sockets from templates
|
||||
@ -846,7 +850,7 @@ class Node(StructRNA, metaclass=RNAMetaNode):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, ntree):
|
||||
return True
|
||||
return True
|
||||
|
||||
|
||||
class NodeSocket(StructRNA, metaclass=RNAMetaPropGroup):
|
||||
@ -870,17 +874,18 @@ class CompositorNode(Node):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, ntree):
|
||||
return ntree.bl_idname == 'CompositorNodeTree'
|
||||
return ntree.bl_idname == 'CompositorNodeTree'
|
||||
|
||||
def update(self):
|
||||
self.tag_need_exec()
|
||||
|
||||
|
||||
class ShaderNode(Node):
|
||||
__slots__ = ()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, ntree):
|
||||
return ntree.bl_idname == 'ShaderNodeTree'
|
||||
return ntree.bl_idname == 'ShaderNodeTree'
|
||||
|
||||
|
||||
class TextureNode(Node):
|
||||
@ -888,5 +893,4 @@ class TextureNode(Node):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, ntree):
|
||||
return ntree.bl_idname == 'TextureNodeTree'
|
||||
|
||||
return ntree.bl_idname == 'TextureNodeTree'
|
||||
|
@ -111,10 +111,11 @@ def module_list(path):
|
||||
else:
|
||||
folder_list = []
|
||||
#folder_list = glob.glob(os.path.join(path,'*'))
|
||||
folder_list = [p for p in folder_list \
|
||||
if os.path.exists(os.path.join(path, p, '__init__.py')) \
|
||||
or p[-3:] in {'.py', '.so'} \
|
||||
or p[-4:] in {'.pyc', '.pyo', '.pyd'}]
|
||||
folder_list = [
|
||||
p for p in folder_list
|
||||
if (os.path.exists(os.path.join(path, p, '__init__.py')) or
|
||||
p[-3:] in {'.py', '.so'} or
|
||||
p[-4:] in {'.pyc', '.pyo', '.pyd'})]
|
||||
|
||||
folder_list = [os.path.basename(p).split('.')[0] for p in folder_list]
|
||||
return folder_list
|
||||
|
@ -24,6 +24,7 @@ from bpy.props import (FloatProperty,
|
||||
IntProperty,
|
||||
BoolProperty,
|
||||
)
|
||||
from bpy.app.translations import pgettext_data as data_
|
||||
|
||||
from bpy_extras import object_utils
|
||||
|
||||
@ -142,7 +143,7 @@ class AddTorus(Operator, object_utils.AddObjectHelper):
|
||||
self.major_segments,
|
||||
self.minor_segments)
|
||||
|
||||
mesh = bpy.data.meshes.new("Torus")
|
||||
mesh = bpy.data.meshes.new(data_("Torus"))
|
||||
|
||||
mesh.vertices.add(len(verts_loc) // 3)
|
||||
|
||||
|
@ -127,7 +127,8 @@ def node_class_items_iter(node_class, context):
|
||||
tree_idname = context.space_data.edit_tree.bl_idname
|
||||
for group in bpy.data.node_groups:
|
||||
if group.bl_idname == tree_idname:
|
||||
yield (group.name, "", {"node_tree":group}) # XXX empty string should be replaced by description from tree
|
||||
# XXX empty string should be replaced by description from tree
|
||||
yield (group.name, "", {"node_tree": group})
|
||||
else:
|
||||
yield (node_class.bl_rna.name, node_class.bl_rna.description, {})
|
||||
|
||||
@ -169,7 +170,7 @@ class NODE_OT_add_search(NodeAddOperator, Operator):
|
||||
for index, item in enumerate(node_items_iter(context)):
|
||||
if str(index) == self.type:
|
||||
node = self.create_node(context, item[0].bl_rna.identifier)
|
||||
for prop,value in item[3].items():
|
||||
for prop, value in item[3].items():
|
||||
setattr(node, prop, value)
|
||||
break
|
||||
return {'FINISHED'}
|
||||
@ -257,4 +258,3 @@ class NODE_OT_tree_path_parent(Operator):
|
||||
space.path.pop()
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
@ -146,7 +146,7 @@ class BakeToKeyframes(Operator):
|
||||
# this is a little roundabout but there's no better way right now
|
||||
aa = mat.to_quaternion().to_axis_angle()
|
||||
obj.rotation_axis_angle = (aa[1], ) + aa[0][:]
|
||||
else: # euler
|
||||
else: # euler
|
||||
# make sure euler rotation is compatible to previous frame
|
||||
obj.rotation_euler = mat.to_euler(rot_mode, obj_prev.rotation_euler)
|
||||
|
||||
@ -275,10 +275,10 @@ class ConnectRigidBodies(Operator):
|
||||
self._add_constraint(context, objs_sorted[i-1], objs_sorted[i])
|
||||
change = True
|
||||
|
||||
else: # SELECTED_TO_ACTIVE
|
||||
else: # SELECTED_TO_ACTIVE
|
||||
for obj in objects:
|
||||
self._add_constraint(context, obj_act, obj)
|
||||
change = True;
|
||||
change = True
|
||||
|
||||
if change:
|
||||
# restore selection
|
||||
|
@ -830,7 +830,7 @@ def _wm_doc_get_id(doc_id, do_url=True, url_prefix=""):
|
||||
rna = "bpy.ops.%s.%s" % (class_name, class_prop)
|
||||
else:
|
||||
rna_class = getattr(bpy.types, class_name)
|
||||
|
||||
|
||||
# an operator setting (selected from a running operator), rare case
|
||||
# note: Py defined operators are subclass of Operator,
|
||||
# C defined operators are subclass of OperatorProperties.
|
||||
@ -1273,11 +1273,15 @@ class WM_OT_copy_prev_settings(Operator):
|
||||
else:
|
||||
shutil.copytree(path_src, path_dst, symlinks=True)
|
||||
|
||||
# reload recent-files.txt
|
||||
bpy.ops.wm.read_history()
|
||||
|
||||
# don't loose users work if they open the splash later.
|
||||
if bpy.data.is_saved is bpy.data.is_dirty is False:
|
||||
bpy.ops.wm.read_homefile()
|
||||
else:
|
||||
self.report({'INFO'}, "Reload Start-Up file to restore settings")
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
return {'CANCELLED'}
|
||||
|
@ -93,7 +93,7 @@ def brush_texture_settings(layout, brush, sculpt):
|
||||
col.prop(brush, "texture_angle_source_random", text="")
|
||||
else:
|
||||
col.prop(brush, "texture_angle_source_no_random", text="")
|
||||
|
||||
|
||||
else:
|
||||
col.prop(brush, "texture_angle_source_random", text="")
|
||||
else:
|
||||
|
@ -20,8 +20,7 @@
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel
|
||||
|
||||
i18n_default_ctxt = bpy.app.translations.contexts.default
|
||||
from bpy.app.translations import contexts as i18n_contexts
|
||||
|
||||
|
||||
class PhysicButtonsPanel():
|
||||
@ -39,20 +38,20 @@ def physics_add(self, layout, md, name, type, typeicon, toggles):
|
||||
sub = layout.row(align=True)
|
||||
if md:
|
||||
sub.context_pointer_set("modifier", md)
|
||||
sub.operator("object.modifier_remove", text=name, text_ctxt=i18n_default_ctxt, icon='X')
|
||||
sub.operator("object.modifier_remove", text=name, text_ctxt=i18n_contexts.default, icon='X')
|
||||
if(toggles):
|
||||
sub.prop(md, "show_render", text="")
|
||||
sub.prop(md, "show_viewport", text="")
|
||||
else:
|
||||
sub.operator("object.modifier_add", text=name, text_ctxt=i18n_default_ctxt, icon=typeicon).type = type
|
||||
sub.operator("object.modifier_add", text=name, text_ctxt=i18n_contexts.default, icon=typeicon).type = type
|
||||
|
||||
|
||||
def physics_add_special(self, layout, data, name, addop, removeop, typeicon):
|
||||
sub = layout.row(align=True)
|
||||
if data:
|
||||
sub.operator(removeop, text=name, text_ctxt=i18n_default_ctxt, icon='X')
|
||||
sub.operator(removeop, text=name, text_ctxt=i18n_contexts.default, icon='X')
|
||||
else:
|
||||
sub.operator(addop, text=name, text_ctxt=i18n_default_ctxt, icon=typeicon)
|
||||
sub.operator(addop, text=name, text_ctxt=i18n_contexts.default, icon=typeicon)
|
||||
|
||||
|
||||
class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
|
||||
|
@ -358,12 +358,12 @@ class RENDER_PT_output(RenderButtonsPanel, Panel):
|
||||
layout.prop(rd, "filepath", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
|
||||
col = split.column()
|
||||
col.active = not rd.is_movie_format
|
||||
col.prop(rd, "use_overwrite")
|
||||
col.prop(rd, "use_placeholder")
|
||||
|
||||
|
||||
split.prop(rd, "use_file_extension")
|
||||
|
||||
layout.template_image_settings(image_settings, color_management=False)
|
||||
|
@ -697,13 +697,6 @@ class IMAGE_PT_paint(Panel, ImagePaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
row = col.row(align=True)
|
||||
if(brush.use_relative_jitter):
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
else:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col.prop(brush, "blend", text="Blend")
|
||||
|
||||
@ -728,16 +721,24 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
|
||||
|
||||
brush_texture_settings(col, brush, 0)
|
||||
|
||||
# use_texture_overlay and texture_overlay_alpha
|
||||
col = layout.column(align=True)
|
||||
col.active = brush.brush_capabilities.has_overlay
|
||||
col.label(text="Overlay:")
|
||||
|
||||
row = col.row()
|
||||
if brush.use_texture_overlay:
|
||||
row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
|
||||
else:
|
||||
row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
|
||||
sub = row.row()
|
||||
sub.prop(brush, "texture_overlay_alpha", text="Alpha")
|
||||
|
||||
|
||||
class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel):
|
||||
bl_label = "Texture Mask"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
brush = context.tool_settings.image_paint.brush
|
||||
tex_slot_alpha = brush.mask_texture_slot
|
||||
self.layout.prop(brush, 'use_mask', text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
@ -778,32 +779,52 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
|
||||
|
||||
toolsettings = context.tool_settings.image_paint
|
||||
brush = toolsettings.brush
|
||||
|
||||
|
||||
col = layout.column()
|
||||
col.prop(toolsettings, "input_samples")
|
||||
|
||||
col.prop(brush, "use_airbrush")
|
||||
row = col.row()
|
||||
row.active = brush.use_airbrush
|
||||
row.prop(brush, "rate", slider=True)
|
||||
col = layout.column()
|
||||
|
||||
col.label(text="Stroke Method:")
|
||||
|
||||
col.prop(brush, "stroke_method", text="")
|
||||
|
||||
if brush.use_anchor:
|
||||
col.separator()
|
||||
col.prop(brush, "use_edge_to_edge", "Edge To Edge")
|
||||
|
||||
if brush.use_airbrush:
|
||||
col.separator()
|
||||
col.prop(brush, "rate", text="Rate", slider=True)
|
||||
|
||||
if brush.use_space:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
|
||||
col = layout.column()
|
||||
col.active = brush.use_smooth_stroke
|
||||
col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
sub = col.column()
|
||||
sub.active = brush.use_smooth_stroke
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.prop(brush, "use_space")
|
||||
row = col.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Distance", slider=True)
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
if brush.use_relative_jitter:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
else:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col.prop(brush, "use_wrap")
|
||||
|
||||
|
@ -167,7 +167,7 @@ class NLA_MT_add(Menu):
|
||||
layout.separator()
|
||||
layout.operator("nla.tracks_add").above_selected = False
|
||||
layout.operator("nla.tracks_add", text="Add Tracks Above Selected").above_selected = True
|
||||
|
||||
|
||||
layout.separator()
|
||||
layout.operator("nla.selected_objects_add")
|
||||
|
||||
|
@ -44,7 +44,7 @@ class NODE_HT_header(Header):
|
||||
row.menu("NODE_MT_node")
|
||||
|
||||
layout.prop(snode, "tree_type", text="", expand=True)
|
||||
|
||||
|
||||
if snode.tree_type == 'ShaderNodeTree':
|
||||
if scene.render.use_shading_nodes:
|
||||
layout.prop(snode, "shader_type", text="", expand=True)
|
||||
@ -84,7 +84,7 @@ class NODE_HT_header(Header):
|
||||
row = layout.row(align=True)
|
||||
row.prop(snode, "backdrop_channels", text="", expand=True)
|
||||
layout.prop(snode, "use_auto_render")
|
||||
|
||||
|
||||
else:
|
||||
# Custom node tree is edited as independent ID block
|
||||
layout.template_ID(snode, "node_tree", new="node.new_node_tree")
|
||||
@ -292,7 +292,7 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
row = layout.row(align=True)
|
||||
|
||||
# inputs get icon on the left
|
||||
# inputs get icon on the left
|
||||
if socket.in_out == 'IN':
|
||||
row.template_node_socket(color)
|
||||
|
||||
|
@ -514,9 +514,6 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
|
||||
layout.prop(strip, "speed_factor", text="Frame number")
|
||||
layout.prop(strip, "scale_to_length")
|
||||
|
||||
#doesn't work currently
|
||||
#layout.prop(strip, "use_frame_blend")
|
||||
|
||||
elif strip.type == 'TRANSFORM':
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
|
@ -20,6 +20,7 @@
|
||||
import bpy
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from bpy.app.translations import pgettext_iface as iface_
|
||||
from bpy.app.translations import contexts as i18n_contexts
|
||||
|
||||
|
||||
def ui_style_items(col, context):
|
||||
@ -528,7 +529,7 @@ class USERPREF_PT_system(Panel):
|
||||
if system.use_international_fonts:
|
||||
column.prop(system, "language")
|
||||
row = column.row()
|
||||
row.label(text="Translate:", text_ctxt=bpy.app.translations.contexts.id_windowmanager)
|
||||
row.label(text="Translate:", text_ctxt=i18n_contexts.id_windowmanager)
|
||||
row = column.row(True)
|
||||
row.prop(system, "use_translate_interface", text="Interface", toggle=True)
|
||||
row.prop(system, "use_translate_tooltips", text="Tooltips", toggle=True)
|
||||
|
@ -20,8 +20,7 @@
|
||||
import bpy
|
||||
from bpy.types import Menu
|
||||
from bpy.app.translations import pgettext_iface as iface_
|
||||
|
||||
km_i18n_context = bpy.app.translations.contexts.id_windowmanager
|
||||
from bpy.app.translations import contexts as i18n_contexts
|
||||
|
||||
|
||||
class USERPREF_MT_keyconfigs(Menu):
|
||||
@ -81,7 +80,7 @@ class InputKeyMapPanel:
|
||||
|
||||
row = col.row()
|
||||
row.prop(km, "show_expanded_children", text="", emboss=False)
|
||||
row.label(text=km.name, text_ctxt=km_i18n_context)
|
||||
row.label(text=km.name, text_ctxt=i18n_contexts.id_windowmanager)
|
||||
|
||||
row.label()
|
||||
row.label()
|
||||
@ -112,7 +111,8 @@ class InputKeyMapPanel:
|
||||
# "Add New" at end of keymap item list
|
||||
col = self.indented_layout(col, level + 1)
|
||||
subcol = col.split(percentage=0.2).column()
|
||||
subcol.operator("wm.keyitem_add", text="Add New", text_ctxt=km_i18n_context, icon='ZOOMIN')
|
||||
subcol.operator("wm.keyitem_add", text="Add New", text_ctxt=i18n_contexts.id_windowmanager,
|
||||
icon='ZOOMIN')
|
||||
|
||||
col.separator()
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
import bpy
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from bl_ui.properties_paint_common import UnifiedPaintPanel
|
||||
from bpy.app.translations import contexts as i18n_contexts
|
||||
|
||||
|
||||
class VIEW3D_HT_header(Header):
|
||||
@ -994,20 +995,20 @@ class VIEW3D_MT_object_apply(Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
props = layout.operator("object.transform_apply", text="Location")
|
||||
props = layout.operator("object.transform_apply", text="Location", text_ctxt=i18n_contexts.default)
|
||||
props.location, props.rotation, props.scale = True, False, False
|
||||
|
||||
props = layout.operator("object.transform_apply", text="Rotation")
|
||||
props = layout.operator("object.transform_apply", text="Rotation", text_ctxt=i18n_contexts.default)
|
||||
props.location, props.rotation, props.scale = False, True, False
|
||||
|
||||
props = layout.operator("object.transform_apply", text="Scale")
|
||||
props = layout.operator("object.transform_apply", text="Scale", text_ctxt=i18n_contexts.default)
|
||||
props.location, props.rotation, props.scale = False, False, True
|
||||
props = layout.operator("object.transform_apply", text="Rotation & Scale")
|
||||
props = layout.operator("object.transform_apply", text="Rotation & Scale", text_ctxt=i18n_contexts.default)
|
||||
props.location, props.rotation, props.scale = False, True, True
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("object.visual_transform_apply", text="Visual Transform")
|
||||
layout.operator("object.visual_transform_apply", text="Visual Transform", text_ctxt=i18n_contexts.default)
|
||||
layout.operator("object.duplicates_make_real")
|
||||
|
||||
|
||||
@ -1657,8 +1658,6 @@ class BoneOptions:
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
default_context = bpy.app.translations.contexts.default
|
||||
|
||||
options = [
|
||||
"show_wire",
|
||||
"use_deform",
|
||||
@ -1679,7 +1678,7 @@ class BoneOptions:
|
||||
|
||||
for opt in options:
|
||||
props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name,
|
||||
text_ctxt=default_context)
|
||||
text_ctxt=i18n_contexts.default)
|
||||
props.data_path_iter = data_path_iter
|
||||
props.data_path_item = opt_suffix + opt
|
||||
props.type = self.type
|
||||
@ -2561,7 +2560,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
|
||||
col.label()
|
||||
if not with_freestyle:
|
||||
col.prop(mesh, "show_edge_seams", text="Seams")
|
||||
col.prop(mesh, "show_edge_sharp", text="Sharp")
|
||||
col.prop(mesh, "show_edge_sharp", text="Sharp", text_ctxt=i18n_contexts.plural)
|
||||
col.prop(mesh, "show_edge_bevel_weight", text="Weights")
|
||||
if with_freestyle:
|
||||
col.prop(mesh, "show_freestyle_edge_marks", text="Edge Marks")
|
||||
@ -2584,6 +2583,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
|
||||
col.separator()
|
||||
col.label(text="Numerics:")
|
||||
col.prop(mesh, "show_extra_edge_length")
|
||||
col.prop(mesh, "show_extra_edge_angle")
|
||||
col.prop(mesh, "show_extra_face_angle")
|
||||
col.prop(mesh, "show_extra_face_area")
|
||||
if bpy.app.debug:
|
||||
|
@ -681,13 +681,6 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
row = col.row(align=True)
|
||||
if(brush.use_relative_jitter):
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
else:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col.prop(brush, "blend", text="Blend")
|
||||
|
||||
@ -714,14 +707,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
row = col.row(align=True)
|
||||
if(brush.use_relative_jitter):
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
else:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
|
||||
col.prop(brush, "vertex_tool", text="Blend")
|
||||
|
||||
# Vertex Paint Mode #
|
||||
@ -793,11 +779,6 @@ class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
|
||||
brush = context.tool_settings.image_paint.brush
|
||||
return (context.image_paint_object and brush and brush.image_tool != 'SOFTEN')
|
||||
|
||||
def draw_header(self, context):
|
||||
brush = context.tool_settings.image_paint.brush
|
||||
tex_slot_alpha = brush.mask_texture_slot
|
||||
self.layout.prop(brush, 'use_mask', text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
@ -830,29 +811,43 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
|
||||
settings = self.paint_settings(context)
|
||||
brush = settings.brush
|
||||
image_paint = context.image_paint_object
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.label(text="Stroke Method:")
|
||||
|
||||
if context.sculpt_object:
|
||||
col.label(text="Stroke Method:")
|
||||
col.prop(brush, "sculpt_stroke_method", text="")
|
||||
else:
|
||||
col.prop(brush, "stroke_method", text="")
|
||||
|
||||
if brush.use_anchor:
|
||||
col.separator()
|
||||
col.prop(brush, "use_edge_to_edge", "Edge To Edge")
|
||||
if brush.use_anchor:
|
||||
col.separator()
|
||||
col.prop(brush, "use_edge_to_edge", "Edge To Edge")
|
||||
|
||||
if brush.use_airbrush:
|
||||
col.separator()
|
||||
col.prop(brush, "rate", text="Rate", slider=True)
|
||||
if brush.use_airbrush:
|
||||
col.separator()
|
||||
col.prop(brush, "rate", text="Rate", slider=True)
|
||||
|
||||
if brush.use_space:
|
||||
if brush.use_space:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
if context.sculpt_object:
|
||||
if brush.sculpt_capabilities.has_jitter:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
if brush.use_relative_jitter:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
else:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
if brush.sculpt_capabilities.has_smooth_stroke:
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
@ -863,46 +858,27 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
sub.active = brush.use_smooth_stroke
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
if brush.sculpt_capabilities.has_jitter:
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
if(brush.use_relative_jitter):
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
else:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
else:
|
||||
col.prop(brush, "use_airbrush")
|
||||
col.separator()
|
||||
|
||||
row = col.row()
|
||||
row.active = brush.use_airbrush and (not brush.use_space) and (not brush.use_anchor)
|
||||
row.prop(brush, "rate", slider=True)
|
||||
row = col.row(align=True)
|
||||
if brush.use_relative_jitter:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
else:
|
||||
row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
|
||||
row.prop(brush, "jitter_absolute")
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
|
||||
col = layout.column()
|
||||
col.active = brush.use_smooth_stroke
|
||||
col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.active = brush.brush_capabilities.has_spacing
|
||||
col.prop(brush, "use_space")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = brush.use_smooth_stroke
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
|
||||
bl_label = "Curve"
|
||||
@ -1180,7 +1156,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
|
||||
|
||||
row = layout.row()
|
||||
row.prop(ipaint, "use_normal_falloff")
|
||||
|
||||
|
||||
sub = row.row()
|
||||
sub.active = (ipaint.use_normal_falloff)
|
||||
sub.prop(ipaint, "normal_angle", text="")
|
||||
@ -1214,7 +1190,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
|
||||
|
||||
col.operator("paint.project_image", text="Apply Camera Image")
|
||||
col.operator("image.save_dirty", text="Save All Edited")
|
||||
|
||||
|
||||
|
||||
class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
|
||||
bl_label = "Options"
|
||||
|
@ -111,7 +111,7 @@ __declspec(dllexport) HRESULT vfGetPluginInfo(
|
||||
return VF_OK;
|
||||
}
|
||||
|
||||
static unsigned long getipaddress(const char * ipaddr)
|
||||
static unsigned long getipaddress(const char *ipaddr)
|
||||
{
|
||||
struct hostent *host;
|
||||
unsigned long ip;
|
||||
|
@ -138,6 +138,9 @@ const char *BLF_translate_do_new_dataname(const char *msgctxt, const char *msgid
|
||||
/* Default context for operator names/labels. */
|
||||
#define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator"
|
||||
|
||||
/* Mark the msgid applies to several elements (needed in some cases, as english adjectives have no plural mark. :( */
|
||||
#define BLF_I18NCONTEXT_PLURAL "Plural"
|
||||
|
||||
/* ID-types contexts. */
|
||||
/* WARNING! Keep it in sync with idtypes in blenkernel/intern/idcode.c */
|
||||
#define BLF_I18NCONTEXT_ID_ACTION "Action"
|
||||
@ -188,6 +191,7 @@ typedef struct
|
||||
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT, "default_real"), \
|
||||
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT_BPYRNA, "default"), \
|
||||
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "operator_default"), \
|
||||
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_PLURAL, "plural"), \
|
||||
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ACTION, "id_action"), \
|
||||
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ARMATURE, "id_armature"), \
|
||||
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_BRUSH, "id_brush"), \
|
||||
|
@ -235,19 +235,19 @@ struct DerivedMesh {
|
||||
* from the derived mesh (this gives a pointer to the actual data, not
|
||||
* a copy)
|
||||
*/
|
||||
void *(*getVertData)(DerivedMesh * dm, int index, int type);
|
||||
void *(*getEdgeData)(DerivedMesh * dm, int index, int type);
|
||||
void *(*getTessFaceData)(DerivedMesh * dm, int index, int type);
|
||||
void *(*getPolyData)(DerivedMesh * dm, int index, int type);
|
||||
void *(*getVertData)(DerivedMesh *dm, int index, int type);
|
||||
void *(*getEdgeData)(DerivedMesh *dm, int index, int type);
|
||||
void *(*getTessFaceData)(DerivedMesh *dm, int index, int type);
|
||||
void *(*getPolyData)(DerivedMesh *dm, int index, int type);
|
||||
|
||||
/** Return a pointer to the entire array of vert/edge/face custom data
|
||||
* from the derived mesh (this gives a pointer to the actual data, not
|
||||
* a copy)
|
||||
*/
|
||||
void *(*getVertDataArray)(DerivedMesh * dm, int type);
|
||||
void *(*getEdgeDataArray)(DerivedMesh * dm, int type);
|
||||
void *(*getTessFaceDataArray)(DerivedMesh * dm, int type);
|
||||
void *(*getPolyDataArray)(DerivedMesh * dm, int type);
|
||||
void *(*getVertDataArray)(DerivedMesh *dm, int type);
|
||||
void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
|
||||
void *(*getTessFaceDataArray)(DerivedMesh *dm, int type);
|
||||
void *(*getPolyDataArray)(DerivedMesh *dm, int type);
|
||||
|
||||
/** Retrieves the base CustomData structures for
|
||||
* verts/edges/tessfaces/loops/facdes*/
|
||||
|
@ -42,7 +42,7 @@ extern "C" {
|
||||
* and keep comment above the defines.
|
||||
* Use STRINGIFY() rather than defining with quotes */
|
||||
#define BLENDER_VERSION 266
|
||||
#define BLENDER_SUBVERSION 4
|
||||
#define BLENDER_SUBVERSION 5
|
||||
|
||||
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
|
||||
#define BLENDER_MINVERSION 262
|
||||
|
@ -120,6 +120,7 @@ typedef struct bNodeSocketType {
|
||||
void (*interface_draw_color)(struct bContext *C, struct PointerRNA *ptr, float *r_color);
|
||||
void (*interface_register_properties)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct StructRNA *data_srna);
|
||||
void (*interface_init_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock, const char *data_path);
|
||||
void (*interface_verify_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock, const char *data_path);
|
||||
void (*interface_from_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock);
|
||||
|
||||
/* RNA integration */
|
||||
|
@ -121,6 +121,12 @@ static void brush_defaults(Brush *brush)
|
||||
brush->sub_col[0] = 0.39; /* subtract mode color is light blue */
|
||||
brush->sub_col[1] = 0.39;
|
||||
brush->sub_col[2] = 1.00;
|
||||
|
||||
brush->stencil_pos[0] = 256;
|
||||
brush->stencil_pos[1] = 256;
|
||||
|
||||
brush->stencil_dimension[0] = 256;
|
||||
brush->stencil_dimension[1] = 256;
|
||||
}
|
||||
|
||||
/* Datablock add/copy/free/make_local */
|
||||
@ -518,11 +524,45 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
|
||||
hasrgb = externtex(mtex, point, &intensity,
|
||||
rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
|
||||
}
|
||||
else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
|
||||
float rotation = -mtex->rot;
|
||||
float point_2d[2] = {point[0], point[1]};
|
||||
float x = 0.0f, y = 0.0f; /* Quite warnings */
|
||||
float co[3];
|
||||
|
||||
x = point_2d[0] - br->stencil_pos[0];
|
||||
y = point_2d[1] - br->stencil_pos[1];
|
||||
|
||||
if (rotation > 0.001f || rotation < -0.001f) {
|
||||
const float angle = atan2f(y, x) + rotation;
|
||||
const float flen = sqrtf(x * x + y * y);
|
||||
|
||||
x = flen * cosf(angle);
|
||||
y = flen * sinf(angle);
|
||||
}
|
||||
|
||||
if (fabs(x) > br->stencil_dimension[0] || fabs(y) > br->stencil_dimension[1]) {
|
||||
rgba[0] = rgba[1] = rgba[2] = rgba[3] = 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
x /= (br->stencil_dimension[0]);
|
||||
y /= (br->stencil_dimension[1]);
|
||||
|
||||
x *= br->mtex.size[0];
|
||||
y *= br->mtex.size[1];
|
||||
|
||||
co[0] = x + br->mtex.ofs[0];
|
||||
co[1] = y + br->mtex.ofs[1];
|
||||
co[2] = 0.0f;
|
||||
|
||||
hasrgb = externtex(mtex, co, &intensity,
|
||||
rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
|
||||
}
|
||||
else {
|
||||
float rotation = -mtex->rot;
|
||||
float point_2d[2] = {point[0], point[1]};
|
||||
float x = 0.0f, y = 0.0f; /* Quite warnings */
|
||||
float radius = 1.0f; /* Quite warnings */
|
||||
float invradius = 1.0f; /* Quite warnings */
|
||||
float co[3];
|
||||
|
||||
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
|
||||
@ -534,13 +574,13 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
|
||||
y = point_2d[1] - ups->tex_mouse[1];
|
||||
|
||||
/* use pressure adjusted size for fixed mode */
|
||||
radius = ups->pixel_radius;
|
||||
invradius = 1.0f / ups->pixel_radius;
|
||||
}
|
||||
else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
|
||||
/* leave the coordinates relative to the screen */
|
||||
|
||||
/* use unadjusted size for tiled mode */
|
||||
radius = BKE_brush_size_get(scene, br);
|
||||
invradius = 1.0f / BKE_brush_size_get(scene, br);
|
||||
|
||||
x = point_2d[0];
|
||||
y = point_2d[1];
|
||||
@ -551,11 +591,11 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
|
||||
x = point_2d[0] - ups->tex_mouse[0];
|
||||
y = point_2d[1] - ups->tex_mouse[1];
|
||||
|
||||
radius = ups->pixel_radius;
|
||||
invradius = 1.0f / ups->pixel_radius;
|
||||
}
|
||||
|
||||
x /= radius;
|
||||
y /= radius;
|
||||
x *= invradius;
|
||||
y *= invradius;
|
||||
|
||||
/* it is probably worth optimizing for those cases where
|
||||
* the texture is not rotated by skipping the calls to
|
||||
|
@ -1601,7 +1601,7 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
|
||||
RenderStats *stats = re ? RE_GetStats(re) : NULL;
|
||||
|
||||
if (stats && (scene->r.stamp & R_STAMP_RENDERTIME)) {
|
||||
BLI_timestr(stats->lastframetime, text);
|
||||
BLI_timestr(stats->lastframetime, text, sizeof(text));
|
||||
|
||||
BLI_snprintf(stamp_data->rendertime, sizeof(stamp_data->rendertime), do_prefix ? "RenderTime %s" : "%s", text);
|
||||
}
|
||||
@ -3011,7 +3011,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
|
||||
*lock_r = ima;
|
||||
|
||||
/* XXX anim play for viewer nodes not yet supported */
|
||||
frame = 0; // XXX iuser?iuser->framenr:0;
|
||||
frame = 0; // XXX iuser ? iuser->framenr : 0;
|
||||
ibuf = image_get_ibuf(ima, 0, frame);
|
||||
|
||||
if (!ibuf) {
|
||||
|
@ -1668,7 +1668,6 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *so
|
||||
MEM_freeN(sock->prop);
|
||||
}
|
||||
|
||||
/* can be left over from old files */
|
||||
if (sock->default_value)
|
||||
MEM_freeN(sock->default_value);
|
||||
}
|
||||
@ -2006,21 +2005,16 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
|
||||
|
||||
/* ************ NODE TREE INTERFACE *************** */
|
||||
|
||||
static bNodeSocket *make_socket_template(bNodeTree *ntree, int in_out,
|
||||
static bNodeSocket *make_socket_interface(bNodeTree *ntree, int in_out,
|
||||
const char *idname, const char *name)
|
||||
{
|
||||
bNodeSocketType *stype = nodeSocketTypeFind(idname);
|
||||
bNodeSocket *sock;
|
||||
int own_index = ntree->cur_index++;
|
||||
|
||||
if (stype == NULL) {
|
||||
printf("Error: node socket type '%s' undefined\n", idname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sock = MEM_callocN(sizeof(bNodeSocket), "socket template");
|
||||
sock->typeinfo = stype;
|
||||
BLI_strncpy(sock->idname, stype->idname, sizeof(sock->idname));
|
||||
node_socket_set_typeinfo(ntree, sock, stype);
|
||||
sock->in_out = in_out;
|
||||
sock->type = SOCK_CUSTOM; /* int type undefined by default */
|
||||
|
||||
@ -2073,7 +2067,7 @@ bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, int in_out, const char *i
|
||||
{
|
||||
bNodeSocket *iosock;
|
||||
|
||||
iosock = make_socket_template(ntree, in_out, idname, name);
|
||||
iosock = make_socket_interface(ntree, in_out, idname, name);
|
||||
if (in_out == SOCK_IN) {
|
||||
BLI_addtail(&ntree->inputs, iosock);
|
||||
ntree->update |= NTREE_UPDATE_GROUP_IN;
|
||||
@ -2091,7 +2085,7 @@ bNodeSocket *ntreeInsertSocketInterface(bNodeTree *ntree, int in_out, const char
|
||||
{
|
||||
bNodeSocket *iosock;
|
||||
|
||||
iosock = make_socket_template(ntree, in_out, idname, name);
|
||||
iosock = make_socket_interface(ntree, in_out, idname, name);
|
||||
if (in_out == SOCK_IN) {
|
||||
BLI_insertlinkbefore(&ntree->inputs, next_sock, iosock);
|
||||
ntree->update |= NTREE_UPDATE_GROUP_IN;
|
||||
|
@ -1346,7 +1346,7 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D
|
||||
ctx->jitoff= jitter_offset;
|
||||
ctx->weight= element_weight;
|
||||
ctx->maxweight= maxweight;
|
||||
ctx->from= (children)? PART_FROM_CHILD: from;
|
||||
ctx->from= (children) ? PART_FROM_CHILD : from;
|
||||
ctx->cfrom= cfrom;
|
||||
ctx->distr= distr;
|
||||
ctx->dm= dm;
|
||||
@ -2039,7 +2039,7 @@ static void set_keyed_keys(ParticleSimulationData *sim)
|
||||
|
||||
ksim.psys->flag |= keyed_flag;
|
||||
|
||||
pt = (pt->next && pt->next->flag & PTARGET_VALID)? pt->next : psys->targets.first;
|
||||
pt = (pt->next && pt->next->flag & PTARGET_VALID) ? pt->next : psys->targets.first;
|
||||
}
|
||||
|
||||
psys->flag |= PSYS_KEYED;
|
||||
|
@ -1396,7 +1396,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
|
||||
|
||||
static int ptcache_path(PTCacheID *pid, char *filename)
|
||||
{
|
||||
Library *lib= (pid->ob)? pid->ob->id.lib: NULL;
|
||||
Library *lib = (pid->ob) ? pid->ob->id.lib : NULL;
|
||||
const char *blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filepath: G.main->name;
|
||||
size_t i;
|
||||
|
||||
|
@ -705,7 +705,7 @@ void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up)
|
||||
bSensor *sens, *tmp;
|
||||
|
||||
int val;
|
||||
val = move_up ? 1:2;
|
||||
val = move_up ? 1 : 2;
|
||||
|
||||
/* make sure this sensor belongs to this object */
|
||||
sens= ob->sensors.first;
|
||||
@ -744,7 +744,7 @@ void sca_move_controller(bController *cont_to_move, Object *ob, int move_up)
|
||||
bController *cont, *tmp;
|
||||
|
||||
int val;
|
||||
val = move_up ? 1:2;
|
||||
val = move_up ? 1 : 2;
|
||||
|
||||
/* make sure this controller belongs to this object */
|
||||
cont= ob->controllers.first;
|
||||
@ -787,7 +787,7 @@ void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up)
|
||||
bActuator *act, *tmp;
|
||||
int val;
|
||||
|
||||
val = move_up ? 1:2;
|
||||
val = move_up ? 1 : 2;
|
||||
|
||||
/* make sure this actuator belongs to this object */
|
||||
act= ob->actuators.first;
|
||||
|
@ -965,10 +965,13 @@ static void do_sub_effect_byte(float facf0, float facf1, int x, int y, unsigned
|
||||
straight_uchar_to_premul_float(rt1, cp1);
|
||||
straight_uchar_to_premul_float(rt2, cp2);
|
||||
|
||||
tempc[0] = rt1[0] - fac1 * rt2[0];
|
||||
tempc[1] = rt1[1] - fac1 * rt2[1];
|
||||
tempc[2] = rt1[2] - fac1 * rt2[2];
|
||||
tempc[3] = rt1[3] - fac1 * rt2[3];
|
||||
tempc[0] = max_ff(rt1[0] - fac1 * rt2[0], 0.0f);
|
||||
tempc[1] = max_ff(rt1[1] - fac1 * rt2[1], 0.0f);
|
||||
tempc[2] = max_ff(rt1[2] - fac1 * rt2[2], 0.0f);
|
||||
tempc[3] = max_ff(rt1[3] - fac1 * rt2[3], 0.0f);
|
||||
|
||||
if (tempc[3] < 1e-6f)
|
||||
tempc[3] = 0.0f;
|
||||
|
||||
premul_float_to_straight_uchar(rt, tempc);
|
||||
|
||||
@ -984,10 +987,13 @@ static void do_sub_effect_byte(float facf0, float facf1, int x, int y, unsigned
|
||||
straight_uchar_to_premul_float(rt1, cp1);
|
||||
straight_uchar_to_premul_float(rt2, cp2);
|
||||
|
||||
tempc[0] = rt1[0] - fac3 * rt2[0];
|
||||
tempc[1] = rt1[1] - fac3 * rt2[1];
|
||||
tempc[2] = rt1[2] - fac3 * rt2[2];
|
||||
tempc[3] = rt1[3] - fac3 * rt2[3];
|
||||
tempc[0] = max_ff(rt1[0] - fac3 * rt2[0], 0.0f);
|
||||
tempc[1] = max_ff(rt1[1] - fac3 * rt2[1], 0.0f);
|
||||
tempc[2] = max_ff(rt1[2] - fac3 * rt2[2], 0.0f);
|
||||
tempc[3] = max_ff(rt1[3] - fac3 * rt2[3], 0.0f);
|
||||
|
||||
if (tempc[3] < 1e-6f)
|
||||
tempc[3] = 0.0f;
|
||||
|
||||
premul_float_to_straight_uchar(rt, tempc);
|
||||
|
||||
@ -1011,22 +1017,34 @@ static void do_sub_effect_float(float facf0, float facf1, int x, int y, float *r
|
||||
fac3 = facf1;
|
||||
|
||||
while (y--) {
|
||||
x = xo * 4;
|
||||
x = xo;
|
||||
while (x--) {
|
||||
*rt = *rt1 - fac1 * (*rt2);
|
||||
rt[0] = max_ff(rt1[0] - fac1 * rt2[0], 0.0f);
|
||||
rt[1] = max_ff(rt1[1] - fac1 * rt2[1], 0.0f);
|
||||
rt[2] = max_ff(rt1[2] - fac1 * rt2[2], 0.0f);
|
||||
rt[3] = max_ff(rt1[3] - fac1 * rt2[3], 0.0f);
|
||||
|
||||
rt1++; rt2++; rt++;
|
||||
if (rt[3] < 1e-6f)
|
||||
rt[3] = 0.0f;
|
||||
|
||||
rt1 += 4; rt2 += 4; rt += 4;
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
break;
|
||||
y--;
|
||||
|
||||
x = xo * 4;
|
||||
x = xo;
|
||||
while (x--) {
|
||||
*rt = *rt1 - fac3 * (*rt2);
|
||||
rt[0] = max_ff(rt1[0] - fac3 * rt2[0], 0.0f);
|
||||
rt[1] = max_ff(rt1[1] - fac3 * rt2[1], 0.0f);
|
||||
rt[2] = max_ff(rt1[2] - fac3 * rt2[2], 0.0f);
|
||||
rt[3] = max_ff(rt1[3] - fac3 * rt2[3], 0.0f);
|
||||
|
||||
rt1++; rt2++; rt++;
|
||||
if (rt[3] < 1e-6f)
|
||||
rt[3] = 0.0f;
|
||||
|
||||
rt1 += 4; rt2 += 4; rt += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,37 @@ void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src);
|
||||
/* create a generic list node containing link to provided data */
|
||||
struct LinkData *BLI_genericNodeN(void *data);
|
||||
|
||||
/**
|
||||
* Does a full loop on the list, with any value acting as first
|
||||
* (handy for cycling items)
|
||||
*
|
||||
* \code{.c}
|
||||
*
|
||||
* LISTBASE_CIRCULAR_FORWARD_BEGIN (listbase, item, item_init) {
|
||||
* ...operate on marker...
|
||||
* }
|
||||
* LISTBASE_CIRCULAR_FORWARD_END (listbase, item, item_init);
|
||||
*
|
||||
* \endcode
|
||||
*/
|
||||
#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init) \
|
||||
if ((lb)->first && (lb_init || (lb_init = (lb)->first))) { \
|
||||
lb_iter = lb_init; \
|
||||
do {
|
||||
#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init) \
|
||||
} while ((lb_iter = (lb_iter)->next ? (lb_iter)->next : (lb)->first), \
|
||||
(lb_iter != lb_init)); \
|
||||
}
|
||||
|
||||
#define LISTBASE_CIRCULAR_BACKWARD_BEGIN(lb, lb_iter, lb_init) \
|
||||
if ((lb)->last && (lb_init || (lb_init = (lb)->last))) { \
|
||||
lb_iter = lb_init; \
|
||||
do {
|
||||
#define LISTBASE_CIRCULAR_BACKWARD_END(lb, lb_iter, lb_init) \
|
||||
} while ((lb_iter = (lb_iter)->prev ? (lb_iter)->prev : (lb)->last), \
|
||||
(lb_iter != lb_init)); \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -92,6 +92,7 @@ MINLINE void add_v3_fl(float r[3], float f);
|
||||
MINLINE void add_v4_fl(float r[4], float f);
|
||||
MINLINE void add_v2_v2(float r[2], const float a[2]);
|
||||
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]);
|
||||
MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2]);
|
||||
MINLINE void add_v3_v3(float r[3], const float a[3]);
|
||||
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3]);
|
||||
MINLINE void add_v4_v4(float r[4], const float a[4]);
|
||||
@ -99,6 +100,7 @@ MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4]);
|
||||
|
||||
MINLINE void sub_v2_v2(float r[2], const float a[2]);
|
||||
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2]);
|
||||
MINLINE void sub_v2_v2v2_int(int r[2], const int a[2], const int b[2]);
|
||||
MINLINE void sub_v3_v3(float r[3], const float a[3]);
|
||||
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3]);
|
||||
MINLINE void sub_v4_v4(float r[4], const float a[4]);
|
||||
|
@ -150,7 +150,7 @@ __attribute__((warn_unused_result))
|
||||
__attribute__((nonnull))
|
||||
#endif
|
||||
;
|
||||
void BLI_timestr(double _time, char *str)
|
||||
void BLI_timestr(double _time, char *str, size_t maxlen)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((nonnull))
|
||||
#endif
|
||||
|
@ -30,12 +30,11 @@
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h> /* malloc */
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_dynstr.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_dlrbTree.h"
|
||||
|
||||
/* *********************************************** */
|
||||
|
@ -30,8 +30,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h> /* malloc */
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -42,10 +42,10 @@
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef __MINGW32__
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#include <io.h>
|
||||
# ifdef __MINGW32__
|
||||
# include <ctype.h>
|
||||
# endif
|
||||
# include <io.h>
|
||||
# include "BLI_winstuff.h"
|
||||
# include "BLI_callbacks.h"
|
||||
# include "utf_winfunc.h"
|
||||
@ -60,8 +60,11 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_fileops.h"
|
||||
|
||||
#include "MEM_sys_types.h" // for intptr_t support
|
||||
|
||||
@ -374,7 +377,7 @@ void BLI_dir_create_recursive(const char *dirname)
|
||||
* blah1/blah2 (without slash) */
|
||||
|
||||
BLI_strncpy(tmp, dirname, sizeof(tmp));
|
||||
lslash = BLI_last_slash(tmp);
|
||||
lslash = (char *)BLI_last_slash(tmp);
|
||||
|
||||
if (lslash && (*(lslash + 1) == '\0')) {
|
||||
*lslash = '\0';
|
||||
@ -385,7 +388,7 @@ void BLI_dir_create_recursive(const char *dirname)
|
||||
|
||||
if (BLI_exists(tmp)) return;
|
||||
|
||||
lslash = BLI_last_slash(tmp);
|
||||
lslash = (char *)BLI_last_slash(tmp);
|
||||
|
||||
if (lslash) {
|
||||
/* Split about the last slash and recurse */
|
||||
|
@ -47,10 +47,11 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_vfontdata.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vfontdata.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "DNA_vfont_types.h"
|
||||
#include "DNA_packedFile_types.h"
|
||||
|
@ -25,17 +25,15 @@
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
|
||||
#include <float.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_graph.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_graph.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
|
||||
static void testRadialSymmetry(BGraph *graph, BNode *root_node, RadialArc *ring, int total, float axis[3], float limit, int group);
|
||||
|
@ -215,18 +215,18 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const fl
|
||||
}
|
||||
else {
|
||||
if (components == 1) {
|
||||
byte_output[0] = out[0];
|
||||
byte_output[0] = out[0] + 0.5f;
|
||||
}
|
||||
else if (components == 3) {
|
||||
byte_output[0] = out[0];
|
||||
byte_output[1] = out[1];
|
||||
byte_output[2] = out[2];
|
||||
byte_output[0] = out[0] + 0.5f;
|
||||
byte_output[1] = out[1] + 0.5f;
|
||||
byte_output[2] = out[2] + 0.5f;
|
||||
}
|
||||
else {
|
||||
byte_output[0] = out[0];
|
||||
byte_output[1] = out[1];
|
||||
byte_output[2] = out[2];
|
||||
byte_output[3] = out[3];
|
||||
byte_output[0] = out[0] + 0.5f;
|
||||
byte_output[1] = out[1] + 0.5f;
|
||||
byte_output[2] = out[2] + 0.5f;
|
||||
byte_output[3] = out[3] + 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -322,18 +322,18 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const f
|
||||
a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
|
||||
|
||||
if (components == 1) {
|
||||
byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
|
||||
byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f;
|
||||
}
|
||||
else if (components == 3) {
|
||||
byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
|
||||
byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
|
||||
byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
|
||||
byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f;
|
||||
byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] + 0.5f;
|
||||
byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] + 0.5f;
|
||||
}
|
||||
else {
|
||||
byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
|
||||
byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
|
||||
byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
|
||||
byte_output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
|
||||
byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f;
|
||||
byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] + 0.5f;
|
||||
byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] + 0.5f;
|
||||
byte_output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3] + 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,6 +271,12 @@ MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
|
||||
r[1] = a[1] + b[1];
|
||||
}
|
||||
|
||||
MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2])
|
||||
{
|
||||
r[0] = a[0] + b[0];
|
||||
r[1] = a[1] + b[1];
|
||||
}
|
||||
|
||||
MINLINE void add_v3_v3(float r[3], const float a[3])
|
||||
{
|
||||
r[0] += a[0];
|
||||
@ -313,6 +319,12 @@ MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
|
||||
r[1] = a[1] - b[1];
|
||||
}
|
||||
|
||||
MINLINE void sub_v2_v2v2_int(int r[2], const int a[2], const int b[2])
|
||||
{
|
||||
r[0] = a[0] - b[0];
|
||||
r[1] = a[1] - b[1];
|
||||
}
|
||||
|
||||
MINLINE void sub_v3_v3(float r[3], const float a[3])
|
||||
{
|
||||
r[0] -= a[0];
|
||||
|
@ -61,7 +61,8 @@
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "utf_winfunc.h"
|
||||
# include "utf_winfunc.h"
|
||||
# include "utfconv.h"
|
||||
# include <io.h>
|
||||
# ifdef _WIN32_IE
|
||||
# undef _WIN32_IE
|
||||
|
@ -490,22 +490,20 @@ int BLI_natstrcmp(const char *s1, const char *s2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BLI_timestr(double _time, char *str)
|
||||
void BLI_timestr(double _time, char *str, size_t maxlen)
|
||||
{
|
||||
/* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
|
||||
int hr = ( (int) _time) / (60 * 60);
|
||||
int min = (((int) _time) / 60 ) % 60;
|
||||
int sec = ( (int) (_time)) % 60;
|
||||
int sec = ( (int) _time) % 60;
|
||||
int hun = ( (int) (_time * 100.0)) % 100;
|
||||
|
||||
|
||||
if (hr) {
|
||||
sprintf(str, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun);
|
||||
BLI_snprintf(str, maxlen, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun);
|
||||
}
|
||||
else {
|
||||
sprintf(str, "%.2d:%.2d.%.2d", min, sec, hun);
|
||||
BLI_snprintf(str, maxlen, "%.2d:%.2d.%.2d", min, sec, hun);
|
||||
}
|
||||
|
||||
str[11] = 0;
|
||||
}
|
||||
|
||||
/* determine the length of a fixed-size string */
|
||||
|
@ -602,7 +602,7 @@ size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf)
|
||||
*
|
||||
* Return value: a pointer to the found character or %NULL.
|
||||
**/
|
||||
char * BLI_str_find_prev_char_utf8(const char *str, const char *p)
|
||||
char *BLI_str_find_prev_char_utf8(const char *str, const char *p)
|
||||
{
|
||||
for (--p; p >= str; --p) {
|
||||
if ((*p & 0xc0) != 0x80) {
|
||||
|
@ -29,14 +29,13 @@
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
|
@ -100,10 +100,6 @@ typedef uint64_t u_int64_t;
|
||||
#include <inttypes.h>
|
||||
|
||||
#elif defined(FREE_WINDOWS)
|
||||
#ifndef FREE_WINDOWS64
|
||||
/* define htoln here, there must be a syntax error in winsock2.h in MinGW */
|
||||
unsigned long __attribute__((__stdcall__)) htonl(unsigned long);
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
#else
|
||||
|
@ -6364,7 +6364,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
|
||||
|
||||
sclip->scopes.track_search = NULL;
|
||||
sclip->scopes.track_preview = NULL;
|
||||
sclip->draw_context = NULL;
|
||||
sclip->scopes.ok = 0;
|
||||
}
|
||||
}
|
||||
@ -8127,7 +8126,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
if (ba->axis==(float) 'x') ba->axis=OB_POSX;
|
||||
else if (ba->axis==(float)'y') ba->axis=OB_POSY;
|
||||
/* don't do an if/else to avoid imediate subversion bump*/
|
||||
// ba->axis=((ba->axis == (float) 'x')?OB_POSX_X:OB_POSY);
|
||||
// ba->axis=((ba->axis == (float)'x') ? OB_POSX_X : OB_POSY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9269,7 +9268,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
}
|
||||
|
||||
if (main->versionfile < 267) {
|
||||
|
||||
//if(!DNA_struct_elem_find(fd->filesdna, "Brush", "int", "stencil_pos")) {
|
||||
Brush *brush;
|
||||
|
||||
for (brush = main->brush.first; brush; brush = brush->id.next) {
|
||||
if (brush->stencil_dimension[0] == 0) {
|
||||
brush->stencil_dimension[0] = 256;
|
||||
brush->stencil_dimension[1] = 256;
|
||||
brush->stencil_pos[0] = 256;
|
||||
brush->stencil_pos[1] = 256;
|
||||
}
|
||||
}
|
||||
|
||||
/* TIP: to initialize new variables added, use the new function
|
||||
DNA_struct_elem_find(fd->filesdna, "structname", "typename", "varname")
|
||||
example:
|
||||
|
@ -1070,7 +1070,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
|
||||
sce->gm.dome.warptext = sce->r.dometext;
|
||||
|
||||
/* Stand Alone */
|
||||
sce->gm.playerflag |= (sce->r.fullscreen?GAME_PLAYER_FULLSCREEN:0);
|
||||
sce->gm.playerflag |= (sce->r.fullscreen ? GAME_PLAYER_FULLSCREEN : 0);
|
||||
sce->gm.xplay = sce->r.xplay;
|
||||
sce->gm.yplay = sce->r.yplay;
|
||||
sce->gm.freqplay = sce->r.freqplay;
|
||||
|
@ -801,9 +801,9 @@ static void current_screen_compat(Main *mainvar, bScreen **screen)
|
||||
|
||||
/* find a global current screen in the first open window, to have
|
||||
* a reasonable default for reading in older versions */
|
||||
wm= mainvar->wm.first;
|
||||
window= (wm)? wm->windows.first: NULL;
|
||||
*screen= (window)? window->screen: NULL;
|
||||
wm = mainvar->wm.first;
|
||||
window = (wm) ? wm->windows.first : NULL;
|
||||
*screen = (window) ? window->screen : NULL;
|
||||
}
|
||||
|
||||
typedef struct RenderInfo {
|
||||
@ -3225,7 +3225,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
|
||||
|
||||
/* XXX still remap G */
|
||||
fg.curscreen= screen;
|
||||
fg.curscene= screen? screen->scene : NULL;
|
||||
fg.curscene= screen ? screen->scene : NULL;
|
||||
fg.displaymode= G.displaymode;
|
||||
fg.winpos= G.winpos;
|
||||
|
||||
@ -3286,7 +3286,11 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
|
||||
}
|
||||
#endif
|
||||
|
||||
sprintf(buf, "BLENDER%c%c%.3d", (sizeof(void*)==8)?'-':'_', (ENDIAN_ORDER==B_ENDIAN)?'V':'v', BLENDER_VERSION);
|
||||
sprintf(buf, "BLENDER%c%c%.3d",
|
||||
(sizeof(void *) == 8) ? '-' : '_',
|
||||
(ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v',
|
||||
BLENDER_VERSION);
|
||||
|
||||
mywrite(wd, buf, 12);
|
||||
|
||||
write_renderinfo(wd, mainvar);
|
||||
|
@ -105,6 +105,33 @@ int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, cons
|
||||
|
||||
return i;
|
||||
}
|
||||
/**
|
||||
* \brief Operator Iterator as Array
|
||||
*
|
||||
* Sometimes its convenient to get the iterator as an array.
|
||||
*/
|
||||
int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask,
|
||||
void **array, const int len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* sanity check */
|
||||
if (len > 0) {
|
||||
BMOIter oiter;
|
||||
void *ele;
|
||||
|
||||
for (ele = BMO_iter_new(&oiter, slot_args, slot_name, restrictmask); ele; ele = BMO_iter_step(&oiter)) {
|
||||
array[i] = ele;
|
||||
i++;
|
||||
if (i == len) {
|
||||
return len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Iterator as Array
|
||||
|
@ -131,6 +131,9 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
|
||||
__attribute__((warn_unused_result))
|
||||
#endif
|
||||
;
|
||||
int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask,
|
||||
void **array, const int len);
|
||||
|
||||
int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value);
|
||||
int BMO_iter_elem_count_flag(BMesh *bm, const char itype, void *data, const short oflag, const bool value);
|
||||
int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value);
|
||||
|
@ -22,9 +22,21 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_beautify.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Beautify the mesh by rotating edes between triangles
|
||||
* to more attractive positions until no more rotations can be made.
|
||||
*
|
||||
* In princible this is very simple however there is the possability of
|
||||
* going into an eternal loop where edges keep rotating.
|
||||
* To avoid this - each edge stores a hash of it previous
|
||||
* states so as not to rotate back.
|
||||
*
|
||||
* TODO
|
||||
* - Take face normals into account.
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_heap.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@ -112,21 +124,159 @@ static void erot_state_alternate(const BMEdge *e, EdRotState *e_state)
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Util for setting edge tag once rotated */
|
||||
/* Calculate the improvement of rotating the edge */
|
||||
|
||||
/**
|
||||
* \return a negative value means the edge can be rotated.
|
||||
*/
|
||||
static float bm_edge_calc_rotate_beauty(const BMEdge *e)
|
||||
{
|
||||
/* not a loop (only to be able to break out) */
|
||||
do {
|
||||
float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2];
|
||||
|
||||
/* first get the 2d values */
|
||||
{
|
||||
const float *v1, *v2, *v3, *v4;
|
||||
bool is_zero_a, is_zero_b;
|
||||
float no[3];
|
||||
float axis_mat[3][3];
|
||||
|
||||
v1 = e->l->prev->v->co; /* first face co */
|
||||
v2 = e->l->v->co; /* e->v1 or e->v2*/
|
||||
v3 = e->l->radial_next->prev->v->co; /* second face co */
|
||||
v4 = e->l->next->v->co; /* e->v1 or e->v2*/
|
||||
|
||||
if (UNLIKELY(v1 == v3)) {
|
||||
// printf("This should never happen, but does sometimes!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
|
||||
BLI_assert((ELEM3(v1, v2, v3, v4) == false) &&
|
||||
(ELEM3(v2, v1, v3, v4) == false) &&
|
||||
(ELEM3(v3, v1, v2, v4) == false) &&
|
||||
(ELEM3(v4, v1, v2, v3) == false));
|
||||
|
||||
is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON;
|
||||
is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON;
|
||||
|
||||
if (LIKELY(is_zero_a == false && is_zero_b == false)) {
|
||||
float no_a[3], no_b[3];
|
||||
normal_tri_v3(no_a, v2, v3, v4); /* a */
|
||||
normal_tri_v3(no_b, v2, v4, v1); /* b */
|
||||
add_v3_v3v3(no, no_a, no_b);
|
||||
if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (is_zero_a == false) {
|
||||
normal_tri_v3(no, v2, v3, v4); /* a */
|
||||
}
|
||||
else if (is_zero_b == false) {
|
||||
normal_tri_v3(no, v2, v4, v1); /* b */
|
||||
}
|
||||
else {
|
||||
/* both zero area, no useful normal can be calculated */
|
||||
break;
|
||||
}
|
||||
|
||||
// { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);}
|
||||
|
||||
axis_dominant_v3_to_m3(axis_mat, no);
|
||||
mul_v2_m3v3(v1_xy, axis_mat, v1);
|
||||
mul_v2_m3v3(v2_xy, axis_mat, v2);
|
||||
mul_v2_m3v3(v3_xy, axis_mat, v3);
|
||||
mul_v2_m3v3(v4_xy, axis_mat, v4);
|
||||
}
|
||||
|
||||
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
|
||||
|
||||
if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) {
|
||||
float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2;
|
||||
/* testing rule:
|
||||
* the area divided by the total edge lengths
|
||||
*/
|
||||
len1 = len_v2v2(v1_xy, v2_xy);
|
||||
len2 = len_v2v2(v2_xy, v3_xy);
|
||||
len3 = len_v2v2(v3_xy, v4_xy);
|
||||
len4 = len_v2v2(v4_xy, v1_xy);
|
||||
len5 = len_v2v2(v1_xy, v3_xy);
|
||||
len6 = len_v2v2(v2_xy, v4_xy);
|
||||
|
||||
opp1 = area_tri_v2(v1_xy, v2_xy, v3_xy);
|
||||
opp2 = area_tri_v2(v1_xy, v3_xy, v4_xy);
|
||||
|
||||
fac1 = opp1 / (len1 + len2 + len5) + opp2 / (len3 + len4 + len5);
|
||||
|
||||
opp1 = area_tri_v2(v2_xy, v3_xy, v4_xy);
|
||||
opp2 = area_tri_v2(v2_xy, v4_xy, v1_xy);
|
||||
|
||||
fac2 = opp1 / (len2 + len3 + len6) + opp2 / (len4 + len1 + len6);
|
||||
/* negative number if we're OK */
|
||||
return fac2 - fac1;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
return FLT_MAX;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Update the edge cost of rotation in the heap */
|
||||
|
||||
/* recalc an edge in the heap (surrounding geometry has changed) */
|
||||
static void bm_edge_update_beauty_cost_single(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GHash **edge_state_arr)
|
||||
{
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
const int i = BM_elem_index_get(e);
|
||||
GHash *e_state_hash = edge_state_arr[i];
|
||||
|
||||
if (eheap_table[i]) {
|
||||
BLI_heap_remove(eheap, eheap_table[i]);
|
||||
eheap_table[i] = NULL;
|
||||
}
|
||||
|
||||
/* check if we can add it back */
|
||||
BLI_assert(BM_edge_is_manifold(e) == true);
|
||||
//BLI_assert(BMO_elem_flag_test(bm, e->l->f, FACE_MARK) &&
|
||||
// BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK));
|
||||
|
||||
/* check we're not moving back into a state we have been in before */
|
||||
if (e_state_hash != NULL) {
|
||||
EdRotState e_state_alt;
|
||||
erot_state_alternate(e, &e_state_alt);
|
||||
if (BLI_ghash_haskey(e_state_hash, (void *)&e_state_alt)) {
|
||||
// printf(" skipping, we already have this state\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* recalculate edge */
|
||||
const float cost = bm_edge_calc_rotate_beauty(e);
|
||||
if (cost < 0.0f) {
|
||||
eheap_table[i] = BLI_heap_insert(eheap, cost, e);
|
||||
}
|
||||
else {
|
||||
eheap_table[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we have rotated an edge, tag other egdes and clear this one */
|
||||
static void bm_edge_tag_rotated(BMEdge *e)
|
||||
static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GHash **edge_state_arr)
|
||||
{
|
||||
BMLoop *l;
|
||||
BLI_assert(e->l->f->len == 3 &&
|
||||
e->l->radial_next->f->len == 3);
|
||||
|
||||
l = e->l;
|
||||
BM_elem_flag_enable(l->next->e, BM_ELEM_TAG);
|
||||
BM_elem_flag_enable(l->prev->e, BM_ELEM_TAG);
|
||||
bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr);
|
||||
bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr);
|
||||
l = l->radial_next;
|
||||
BM_elem_flag_enable(l->next->e, BM_ELEM_TAG);
|
||||
BM_elem_flag_enable(l->prev->e, BM_ELEM_TAG);
|
||||
bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr);
|
||||
bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@ -141,160 +291,71 @@ static void bm_edge_tag_rotated(BMEdge *e)
|
||||
*/
|
||||
static void bm_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len)
|
||||
{
|
||||
Heap *eheap; /* edge heap */
|
||||
HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */
|
||||
|
||||
GHash **edge_state_arr = MEM_callocN(edge_array_len * sizeof(GHash *), __func__);
|
||||
BLI_mempool *edge_state_pool = BLI_mempool_create(sizeof(EdRotState), 512, 512, BLI_MEMPOOL_SYSMALLOC);
|
||||
bool is_breaked;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
TIMEIT_START(beautify_fill);
|
||||
#endif
|
||||
|
||||
do {
|
||||
is_breaked = true;
|
||||
eheap = BLI_heap_new_ex(edge_array_len);
|
||||
eheap_table = MEM_mallocN(sizeof(HeapNode *) * edge_array_len, __func__);
|
||||
|
||||
for (i = 0; i < edge_array_len; i++) {
|
||||
BMEdge *e = edge_array[i];
|
||||
GHash *e_state_hash;
|
||||
|
||||
float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2];
|
||||
|
||||
BLI_assert(BM_edge_is_manifold(e) == true);
|
||||
BLI_assert(BMO_elem_flag_test(bm, e->l->f, FACE_MARK) &&
|
||||
BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK));
|
||||
|
||||
if (!BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
/* don't check this edge again, unless adjaced edges are rotated */
|
||||
BM_elem_flag_disable(e, BM_ELEM_TAG);
|
||||
}
|
||||
|
||||
/* check we're not moving back into a state we have been in before */
|
||||
e_state_hash = edge_state_arr[i];
|
||||
if (e_state_hash != NULL) {
|
||||
EdRotState e_state_alt;
|
||||
erot_state_alternate(e, &e_state_alt);
|
||||
if (BLI_ghash_haskey(e_state_hash, (void *)&e_state_alt)) {
|
||||
// printf(" skipping, we already have this state\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const float *v1, *v2, *v3, *v4;
|
||||
bool is_zero_a, is_zero_b;
|
||||
float no[3];
|
||||
float axis_mat[3][3];
|
||||
|
||||
v1 = e->l->prev->v->co; /* first face co */
|
||||
v2 = e->l->v->co; /* e->v1 or e->v2*/
|
||||
v3 = e->l->radial_next->prev->v->co; /* second face co */
|
||||
v4 = e->l->next->v->co; /* e->v1 or e->v2*/
|
||||
|
||||
if (UNLIKELY(v1 == v3)) {
|
||||
// printf("This should never happen, but does sometimes!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
|
||||
BLI_assert((ELEM3(v1, v2, v3, v4) == false) &&
|
||||
(ELEM3(v2, v1, v3, v4) == false) &&
|
||||
(ELEM3(v3, v1, v2, v4) == false) &&
|
||||
(ELEM3(v4, v1, v2, v3) == false));
|
||||
|
||||
is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON;
|
||||
is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON;
|
||||
|
||||
if (LIKELY(is_zero_a == false && is_zero_b == false)) {
|
||||
float no_a[3], no_b[3];
|
||||
normal_tri_v3(no_a, v2, v3, v4); /* a */
|
||||
normal_tri_v3(no_b, v2, v4, v1); /* b */
|
||||
add_v3_v3v3(no, no_a, no_b);
|
||||
if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (is_zero_a == false) {
|
||||
normal_tri_v3(no, v2, v3, v4); /* a */
|
||||
}
|
||||
else if (is_zero_b == false) {
|
||||
normal_tri_v3(no, v2, v4, v1); /* b */
|
||||
}
|
||||
else {
|
||||
/* both zero area, no useful normal can be calculated */
|
||||
continue;
|
||||
}
|
||||
|
||||
// { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);}
|
||||
|
||||
axis_dominant_v3_to_m3(axis_mat, no);
|
||||
mul_v2_m3v3(v1_xy, axis_mat, v1);
|
||||
mul_v2_m3v3(v2_xy, axis_mat, v2);
|
||||
mul_v2_m3v3(v3_xy, axis_mat, v3);
|
||||
mul_v2_m3v3(v4_xy, axis_mat, v4);
|
||||
}
|
||||
|
||||
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
|
||||
|
||||
if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) {
|
||||
float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2;
|
||||
/* testing rule:
|
||||
* the area divided by the total edge lengths
|
||||
*/
|
||||
len1 = len_v2v2(v1_xy, v2_xy);
|
||||
len2 = len_v2v2(v2_xy, v3_xy);
|
||||
len3 = len_v2v2(v3_xy, v4_xy);
|
||||
len4 = len_v2v2(v4_xy, v1_xy);
|
||||
len5 = len_v2v2(v1_xy, v3_xy);
|
||||
len6 = len_v2v2(v2_xy, v4_xy);
|
||||
|
||||
opp1 = area_tri_v2(v1_xy, v2_xy, v3_xy);
|
||||
opp2 = area_tri_v2(v1_xy, v3_xy, v4_xy);
|
||||
|
||||
fac1 = opp1 / (len1 + len2 + len5) + opp2 / (len3 + len4 + len5);
|
||||
|
||||
opp1 = area_tri_v2(v2_xy, v3_xy, v4_xy);
|
||||
opp2 = area_tri_v2(v2_xy, v4_xy, v1_xy);
|
||||
|
||||
fac2 = opp1 / (len2 + len3 + len6) + opp2 / (len4 + len1 + len6);
|
||||
|
||||
if (fac1 > fac2) {
|
||||
e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS);
|
||||
if (LIKELY(e)) {
|
||||
|
||||
/* add the new state into the hash so we don't move into this state again
|
||||
* note: we could add the previous state too but this isn't essential)
|
||||
* for avoiding eternal loops */
|
||||
EdRotState *e_state = BLI_mempool_alloc(edge_state_pool);
|
||||
erot_state_current(e, e_state);
|
||||
if (UNLIKELY(e_state_hash == NULL)) {
|
||||
edge_state_arr[i] = e_state_hash = erot_ghash_new(); /* store previous state */
|
||||
}
|
||||
BLI_assert(BLI_ghash_haskey(e_state_hash, (void *)e_state) == false);
|
||||
BLI_ghash_insert(e_state_hash, e_state, NULL);
|
||||
|
||||
|
||||
// printf(" %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2));
|
||||
|
||||
/* maintain the index array */
|
||||
edge_array[i] = e;
|
||||
BM_elem_index_set(e, i);
|
||||
|
||||
/* tag other edges so we know to check them again */
|
||||
bm_edge_tag_rotated(e);
|
||||
|
||||
/* update flags */
|
||||
BMO_elem_flag_enable(bm, e, ELE_NEW);
|
||||
BMO_elem_flag_enable(bm, e->l->f, FACE_MARK | ELE_NEW);
|
||||
BMO_elem_flag_enable(bm, e->l->radial_next->f, FACE_MARK | ELE_NEW);
|
||||
is_breaked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* build heap */
|
||||
for (i = 0; i < edge_array_len; i++) {
|
||||
BMEdge *e = edge_array[i];
|
||||
const float cost = bm_edge_calc_rotate_beauty(e);
|
||||
if (cost < 0.0f) {
|
||||
eheap_table[i] = BLI_heap_insert(eheap, cost, e);
|
||||
}
|
||||
} while (is_breaked == false);
|
||||
else {
|
||||
eheap_table[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
while (BLI_heap_is_empty(eheap) == false) {
|
||||
BMEdge *e = BLI_heap_popmin(eheap);
|
||||
i = BM_elem_index_get(e);
|
||||
eheap_table[i] = NULL;
|
||||
|
||||
e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS);
|
||||
if (LIKELY(e)) {
|
||||
GHash *e_state_hash = edge_state_arr[i];
|
||||
|
||||
/* add the new state into the hash so we don't move into this state again
|
||||
* note: we could add the previous state too but this isn't essential)
|
||||
* for avoiding eternal loops */
|
||||
EdRotState *e_state = BLI_mempool_alloc(edge_state_pool);
|
||||
erot_state_current(e, e_state);
|
||||
if (UNLIKELY(e_state_hash == NULL)) {
|
||||
edge_state_arr[i] = e_state_hash = erot_ghash_new(); /* store previous state */
|
||||
}
|
||||
BLI_assert(BLI_ghash_haskey(e_state_hash, (void *)e_state) == false);
|
||||
BLI_ghash_insert(e_state_hash, e_state, NULL);
|
||||
|
||||
|
||||
// printf(" %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2));
|
||||
|
||||
/* maintain the index array */
|
||||
edge_array[i] = e;
|
||||
BM_elem_index_set(e, i);
|
||||
|
||||
/* recalculate faces connected on the heap */
|
||||
bm_edge_update_beauty_cost(e, eheap, eheap_table, edge_state_arr);
|
||||
|
||||
/* update flags */
|
||||
BMO_elem_flag_enable(bm, e, ELE_NEW);
|
||||
BMO_elem_flag_enable(bm, e->l->f, FACE_MARK | ELE_NEW);
|
||||
BMO_elem_flag_enable(bm, e->l->radial_next->f, FACE_MARK | ELE_NEW);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_heap_free(eheap, NULL);
|
||||
MEM_freeN(eheap_table);
|
||||
|
||||
for (i = 0; i < edge_array_len; i++) {
|
||||
if (edge_state_arr[i]) {
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_bevel.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Bevel wrapper around #BM_mesh_bevel
|
||||
*/
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_connect.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Connect verts across faces (splits faces) and bridge tool.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -15,13 +15,15 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Joseph Eagar.
|
||||
* Contributor(s): Joseph Eagar, Campbell Barton.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_create.c
|
||||
* \ingroup bmesh
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Create faces or edges (Fkey by default).
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
@ -41,14 +43,9 @@
|
||||
*/
|
||||
void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOperator op2;
|
||||
BMOIter oiter;
|
||||
BMIter iter;
|
||||
BMHeader *h;
|
||||
BMVert *v, *verts[4];
|
||||
BMEdge *e;
|
||||
BMFace *f;
|
||||
int totv = 0, tote = 0, totf = 0, amount;
|
||||
int totv = 0, tote = 0, totf = 0;
|
||||
const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr");
|
||||
const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
|
||||
|
||||
@ -63,6 +60,24 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
|
||||
BMO_elem_flag_enable(bm, (BMElemF *)h, ELE_NEW);
|
||||
}
|
||||
|
||||
/* --- Support Edge Creation ---
|
||||
* simple case when we only have 2 verts selected.
|
||||
*/
|
||||
if (totv == 2 && tote == 0 && totf == 0) {
|
||||
BMVert *verts[2];
|
||||
BMEdge *e;
|
||||
|
||||
BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)verts, 2);
|
||||
|
||||
/* create edge */
|
||||
e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
|
||||
BMO_elem_flag_enable(bm, e, ELE_OUT);
|
||||
tote += 1;
|
||||
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* --- Support for Special Case ---
|
||||
* where there is a contiguous edge ring with one isolated vertex.
|
||||
*
|
||||
@ -83,29 +98,20 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
|
||||
/* Here we check for consistency and create 2 edges */
|
||||
if (totf == 0 && totv >= 4 && totv == tote + 2) {
|
||||
/* find a free standing vertex and 2 endpoint verts */
|
||||
BMVert *v_free = NULL, *v_a = NULL, *v_b = NULL;
|
||||
BMVert *v, *v_free = NULL, *v_a = NULL, *v_b = NULL;
|
||||
bool ok = true;
|
||||
|
||||
|
||||
BMO_ITER (v, &oiter, op->slots_in, "geom", BM_VERT) {
|
||||
/* count how many flagged edges this vertex uses */
|
||||
int tot_edges = 0;
|
||||
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
|
||||
if (BMO_elem_flag_test(bm, e, ELE_NEW)) {
|
||||
tot_edges++;
|
||||
if (tot_edges > 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int tot_edges = BMO_iter_elem_count_flag(bm, BM_EDGES_OF_VERT, v, ELE_NEW, true);
|
||||
if (tot_edges == 0) {
|
||||
/* only accept 1 free vert */
|
||||
if (v_free == NULL) v_free = v;
|
||||
else ok = false; /* only ever want one of these */
|
||||
}
|
||||
else if (tot_edges == 1) {
|
||||
if (v_a == NULL) v_a = v;
|
||||
if (v_a == NULL) v_a = v;
|
||||
else if (v_b == NULL) v_b = v;
|
||||
else ok = false; /* only ever want 2 of these */
|
||||
}
|
||||
@ -122,6 +128,8 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
|
||||
}
|
||||
|
||||
if (ok == true && v_free && v_a && v_b) {
|
||||
BMEdge *e;
|
||||
|
||||
e = BM_edge_create(bm, v_free, v_a, NULL, BM_CREATE_NO_DOUBLE);
|
||||
BMO_elem_flag_enable(bm, e, ELE_NEW);
|
||||
|
||||
@ -135,92 +143,81 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* EdgeNet Create */
|
||||
if (tote != 0) {
|
||||
/* call edgenet prepare op so additional face creation cases work */
|
||||
BMOperator op_sub;
|
||||
BMO_op_initf(bm, &op_sub, op->flag, "edgenet_prepare edges=%fe", ELE_NEW);
|
||||
BMO_op_exec(bm, &op_sub);
|
||||
BMO_slot_buffer_flag_enable(bm, op_sub.slots_out, "edges.out", BM_EDGE, ELE_NEW);
|
||||
BMO_op_finish(bm, &op_sub);
|
||||
|
||||
/* call edgenet prepare op so additional face creation cases wore */
|
||||
BMO_op_initf(bm, &op2, op->flag, "edgenet_prepare edges=%fe", ELE_NEW);
|
||||
BMO_op_exec(bm, &op2);
|
||||
BMO_slot_buffer_flag_enable(bm, op2.slots_out, "edges.out", BM_EDGE, ELE_NEW);
|
||||
BMO_op_finish(bm, &op2);
|
||||
BMO_op_initf(bm, &op_sub, op->flag,
|
||||
"edgenet_fill edges=%fe use_fill_check=%b mat_nr=%i use_smooth=%b",
|
||||
ELE_NEW, true, mat_nr, use_smooth);
|
||||
|
||||
BMO_op_initf(bm, &op2, op->flag,
|
||||
"edgenet_fill edges=%fe use_fill_check=%b mat_nr=%i use_smooth=%b",
|
||||
ELE_NEW, true, mat_nr, use_smooth);
|
||||
BMO_op_exec(bm, &op_sub);
|
||||
|
||||
BMO_op_exec(bm, &op2);
|
||||
/* return if edge net create did something */
|
||||
if (BMO_slot_buffer_count(op_sub.slots_out, "faces.out")) {
|
||||
BMO_slot_copy(&op_sub, slots_out, "faces.out",
|
||||
op, slots_out, "faces.out");
|
||||
BMO_op_finish(bm, &op_sub);
|
||||
return;
|
||||
}
|
||||
|
||||
/* return if edge net create did something */
|
||||
if (BMO_slot_buffer_count(op2.slots_out, "faces.out")) {
|
||||
BMO_slot_copy(&op2, slots_out, "faces.out",
|
||||
op, slots_out, "faces.out");
|
||||
BMO_op_finish(bm, &op2);
|
||||
return;
|
||||
BMO_op_finish(bm, &op_sub);
|
||||
}
|
||||
|
||||
BMO_op_finish(bm, &op2);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Dissolve Face */
|
||||
BMO_op_initf(bm, &op2, op->flag, "dissolve_faces faces=%ff", ELE_NEW);
|
||||
BMO_op_exec(bm, &op2);
|
||||
|
||||
/* if we dissolved anything, then return */
|
||||
if (BMO_slot_buffer_count(op2.slots_out, "region.out")) {
|
||||
BMO_slot_copy(&op2, slots_out, "region.out",
|
||||
op, slots_out, "faces.out");
|
||||
BMO_op_finish(bm, &op2);
|
||||
return;
|
||||
}
|
||||
if (totf != 0) { /* should be (totf > 1)... see below */
|
||||
/* note: allow this to run on single faces so running on a single face
|
||||
* won't go on to create a face, treating them as random */
|
||||
BMOperator op_sub;
|
||||
BMO_op_initf(bm, &op_sub, op->flag, "dissolve_faces faces=%ff", ELE_NEW);
|
||||
BMO_op_exec(bm, &op_sub);
|
||||
|
||||
BMO_op_finish(bm, &op2);
|
||||
/* if we dissolved anything, then return */
|
||||
if (BMO_slot_buffer_count(op_sub.slots_out, "region.out")) {
|
||||
BMO_slot_copy(&op_sub, slots_out, "region.out",
|
||||
op, slots_out, "faces.out");
|
||||
BMO_op_finish(bm, &op_sub);
|
||||
return;
|
||||
}
|
||||
|
||||
BMO_op_finish(bm, &op_sub);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Fill EdgeLoop's - fills isolated loops, different from edgenet */
|
||||
if (tote > 2) {
|
||||
BMOperator op_sub;
|
||||
/* note: in most cases 'edgenet_fill' will handle this case since in common cases
|
||||
* users fill in empty spaces, however its possible to have an edge selection around
|
||||
* existing geometry that makes 'edgenet_fill' fail. */
|
||||
BMO_op_initf(bm, &op_sub, op->flag, "edgeloop_fill edges=%fe", ELE_NEW);
|
||||
BMO_op_exec(bm, &op_sub);
|
||||
|
||||
/* note: in most cases 'edgenet_fill' will handle this case since in common cases
|
||||
* users fill in empty spaces, however its possible to have an edge selection around
|
||||
* existing geometry that makes 'edgenet_fill' fail. */
|
||||
BMO_op_initf(bm, &op2, op->flag, "edgeloop_fill edges=%fe", ELE_NEW);
|
||||
BMO_op_exec(bm, &op2);
|
||||
/* return if edge loop fill did something */
|
||||
if (BMO_slot_buffer_count(op_sub.slots_out, "faces.out")) {
|
||||
BMO_slot_copy(&op_sub, slots_out, "faces.out",
|
||||
op, slots_out, "faces.out");
|
||||
BMO_op_finish(bm, &op_sub);
|
||||
return;
|
||||
}
|
||||
|
||||
/* return if edge loop fill did something */
|
||||
if (BMO_slot_buffer_count(op2.slots_out, "faces.out")) {
|
||||
BMO_slot_copy(&op2, slots_out, "faces.out",
|
||||
op, slots_out, "faces.out");
|
||||
BMO_op_finish(bm, &op2);
|
||||
return;
|
||||
BMO_op_finish(bm, &op_sub);
|
||||
}
|
||||
|
||||
BMO_op_finish(bm, &op2);
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Continue with ad-hoc fill methods since operators fail,
|
||||
* edge, vcloud... may add more */
|
||||
|
||||
/* now, count how many verts we have */
|
||||
amount = 0;
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm, v, ELE_NEW)) {
|
||||
verts[amount] = v;
|
||||
if (amount == 3) {
|
||||
break;
|
||||
}
|
||||
amount++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (amount == 2) {
|
||||
/* create edge */
|
||||
e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
|
||||
BMO_elem_flag_enable(bm, e, ELE_OUT);
|
||||
tote += 1;
|
||||
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
|
||||
}
|
||||
else if (0) { /* nice feature but perhaps it should be a different tool? */
|
||||
if (0) { /* nice feature but perhaps it should be a different tool? */
|
||||
|
||||
/* tricky feature for making a line/edge from selection history...
|
||||
*
|
||||
@ -255,9 +252,9 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
for (ese = bm->selected.first; ese; ese = ese->next) {
|
||||
if (ese->htype == BM_VERT) {
|
||||
v = (BMVert *)ese->ele;
|
||||
BMVert *v = (BMVert *)ese->ele;
|
||||
if (v_prev) {
|
||||
e = BM_edge_create(bm, v, v_prev, NULL, BM_CREATE_NO_DOUBLE);
|
||||
BMEdge *e = BM_edge_create(bm, v, v_prev, NULL, BM_CREATE_NO_DOUBLE);
|
||||
BMO_elem_flag_enable(bm, e, ELE_OUT);
|
||||
}
|
||||
v_prev = v;
|
||||
@ -266,20 +263,25 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
|
||||
}
|
||||
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
|
||||
/* done creating edges */
|
||||
|
||||
return;
|
||||
}
|
||||
else if (amount > 2) {
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Fill Vertex Cloud
|
||||
*
|
||||
* last resort when all else fails.
|
||||
*/
|
||||
if (totv > 2) {
|
||||
/* TODO, some of these vertes may be connected by edges,
|
||||
* this connectivity could be used rather then treating
|
||||
* them as a bunch of isolated verts. */
|
||||
|
||||
BMVert **vert_arr = MEM_mallocN(sizeof(BMVert **) * totv, __func__);
|
||||
int i = 0;
|
||||
|
||||
BMO_ITER (v, &oiter, op->slots_in, "geom", BM_VERT) {
|
||||
vert_arr[i] = v;
|
||||
i++;
|
||||
}
|
||||
BMFace *f;
|
||||
|
||||
BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)vert_arr, totv);
|
||||
f = BM_face_create_ngon_vcloud(bm, vert_arr, totv, BM_CREATE_NO_DOUBLE);
|
||||
|
||||
if (f) {
|
||||
@ -293,6 +295,4 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
MEM_freeN(vert_arr);
|
||||
}
|
||||
|
||||
(void)tote;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_dissolve.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Removes isolated geometry regions without creating holes in the mesh.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_dupe.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Duplicate, Split, Spint operators.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
@ -124,7 +126,6 @@ static BMEdge *copy_edge(BMOperator *op,
|
||||
*
|
||||
* Copy an existing face from one bmesh to another.
|
||||
*/
|
||||
|
||||
static BMFace *copy_face(BMOperator *op,
|
||||
BMOpSlot *slot_facemap_out,
|
||||
BMesh *source_mesh,
|
||||
@ -183,7 +184,6 @@ static BMFace *copy_face(BMOperator *op,
|
||||
*
|
||||
* Internal Copy function.
|
||||
*/
|
||||
|
||||
static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
|
||||
{
|
||||
|
||||
@ -320,7 +320,6 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
|
||||
* BMOP_DUPE_ENEW: Buffer containing pointers to the new mesh edges
|
||||
* BMOP_DUPE_FNEW: Buffer containing pointers to the new mesh faces
|
||||
*/
|
||||
|
||||
void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOperator *dupeop = op;
|
||||
@ -378,11 +377,10 @@ void BMO_dupe_from_flag(BMesh *bm, int htype, const char hflag)
|
||||
* BMOP_DUPE_EOUTPUT: Buffer containing pointers to the split mesh edges
|
||||
* BMOP_DUPE_FOUTPUT: Buffer containing pointers to the split mesh faces
|
||||
*/
|
||||
|
||||
#define SPLIT_INPUT 1
|
||||
|
||||
void bmo_split_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
#define SPLIT_INPUT 1
|
||||
|
||||
BMOperator *splitop = op;
|
||||
BMOperator dupeop;
|
||||
BMOperator delop;
|
||||
@ -455,6 +453,8 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
|
||||
/* cleanup */
|
||||
BMO_op_finish(bm, &delop);
|
||||
BMO_op_finish(bm, &dupeop);
|
||||
|
||||
#undef SPLIT_INPUT
|
||||
}
|
||||
|
||||
|
||||
@ -478,7 +478,6 @@ void bmo_delete_exec(BMesh *bm, BMOperator *op)
|
||||
* Extrude or duplicate geometry a number of times,
|
||||
* rotating and possibly translating after each step
|
||||
*/
|
||||
|
||||
void bmo_spin_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOperator dupop, extop;
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_edgeloop_fill.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Fill discreet edge loop(s) with faces.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
@ -54,6 +56,7 @@ void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op)
|
||||
const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
|
||||
|
||||
/* 'VERT_USED' will be disabled, so enable and fill the array */
|
||||
i = 0;
|
||||
BMO_ITER (e, &oiter, op->slots_in, "edges", BM_EDGE) {
|
||||
BMIter viter;
|
||||
BMO_elem_flag_enable(bm, e, EDGE_MARK);
|
||||
@ -61,7 +64,7 @@ void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op)
|
||||
if (BMO_elem_flag_test(bm, v, VERT_USED) == false) {
|
||||
BMO_elem_flag_enable(bm, v, VERT_USED);
|
||||
verts[i++] = v;
|
||||
if (i > tote) {
|
||||
if (i == tote) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_edgenet.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Edge-Net for filling in open edge-loops.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
@ -43,7 +45,6 @@
|
||||
#define FACE_NEW 1
|
||||
|
||||
#define ELE_NEW 1
|
||||
#define ELE_OUT 2
|
||||
#define ELE_ORIG 4
|
||||
|
||||
#define FACE_IGNORE 16
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_extrude.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Extrude faces and solidify.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_hull.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Create a convex hull using bullet physics library.
|
||||
*/
|
||||
|
||||
#ifdef WITH_BULLET
|
||||
|
@ -22,6 +22,11 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_inset.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Inset face regions.
|
||||
*
|
||||
* TODO
|
||||
* - Inset indervidual faces.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -22,6 +22,11 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_join_triangles.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Convert triangle to quads.
|
||||
*
|
||||
* TODO
|
||||
* - convert triangles to any sided faces, not just quads.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_mirror.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Basic mirror, optionally with UVs's.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
/** \file blender/bmesh/operators/bmo_primitive.c
|
||||
* \ingroup bmesh
|
||||
*
|
||||
* Primitive shapes.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user