Compare commits
137 Commits
temp-geome
...
geometry-n
Author | SHA1 | Date | |
---|---|---|---|
778a07a30b | |||
8ede468a5d | |||
df4e97214d | |||
a7a5a348b3 | |||
6c777e9bb7 | |||
abf3ce811f | |||
cee67f3be2 | |||
a14ee85ccd | |||
231b313c55 | |||
![]() |
3059853732 | ||
a9121640be | |||
14f94fd1ca | |||
1b53fde9fc | |||
71d7505487 | |||
a0cba9fb95 | |||
faa65f151d | |||
c17a266e29 | |||
![]() |
1a3cb90e4e | ||
12afb19959 | |||
![]() |
6abf63f463 | ||
501bca9f5b | |||
828c66f393 | |||
471d4b105a | |||
a77d203932 | |||
0cb25a51de | |||
6a673b6000 | |||
8fda1f363a | |||
4886ed2863 | |||
0aad8100ae | |||
![]() |
aa32121174 | ||
c971c851d3 | |||
a2ccd0e495 | |||
1029577a51 | |||
05c7d935e7 | |||
8fe0aecfde | |||
ede1ce6e9a | |||
8031326262 | |||
![]() |
2beff6197e | ||
3123f33380 | |||
![]() |
a092baa7f9 | ||
5e3d0840a3 | |||
c41b93bda5 | |||
eb43477851 | |||
239a74a130 | |||
6ac378e685 | |||
25fc77f46c | |||
de2c4ee587 | |||
f23b14091f | |||
ced94bc11c | |||
7ce0d9d791 | |||
36c0649d32 | |||
66548007a8 | |||
eea65cbd42 | |||
66dfef10a7 | |||
fd9fc809b7 | |||
39b2a7bb7e | |||
4ba06ad0a8 | |||
3fb47956c0 | |||
![]() |
fafd21b14c | ||
49e68f15f2 | |||
f76dfe8fb4 | |||
524d172742 | |||
![]() |
f013e3de81 | ||
e77a1dc6b0 | |||
1b44b47f69 | |||
1a91c57320 | |||
b1bf4c2a05 | |||
48e27ad122 | |||
91e2b1dcaf | |||
5f28a90b34 | |||
97712b018d | |||
![]() |
0e8d1c6bcf | ||
320f34af86 | |||
19b597c55d | |||
f2cce48698 | |||
0eccf57161 | |||
![]() |
574995478a | ||
![]() |
57668d84cf | ||
8d5b9478a2 | |||
64bb49fa4e | |||
![]() |
178086d581 | ||
785d87ee42 | |||
c830c5b16b | |||
e850c2b06d | |||
10e28bd270 | |||
8de2b6a020 | |||
952ded57de | |||
581a6da804 | |||
63da2c4082 | |||
![]() |
22bef356ae | ||
3cfd6439c6 | |||
16804297e6 | |||
d1e1d6c491 | |||
bbcc8330f7 | |||
e7082fbdb0 | |||
ab101d444d | |||
8b0fac4116 | |||
82ff5dd911 | |||
9aa0a3f533 | |||
75e41b1279 | |||
265c3a4724 | |||
![]() |
dc8a924efa | ||
![]() |
14d5a45750 | ||
807bb450a0 | |||
bfe6b55aa7 | |||
d3445496b1 | |||
cb0b017d8f | |||
0af08cea40 | |||
e99801390c | |||
5a1b1c0ed2 | |||
207df439e1 | |||
36fb03e2b9 | |||
8ffc3ee257 | |||
aeee7f390d | |||
cf28398471 | |||
1e063a0242 | |||
b65ec08bbb | |||
![]() |
26b2a35dd4 | ||
f53ca7e41c | |||
6754d7aef6 | |||
c4f71f3193 | |||
3e4c98429b | |||
f763929486 | |||
3ea4c6b9c9 | |||
f164188a6d | |||
3e29175af3 | |||
![]() |
83b6fcc70c | ||
76a3ff70d5 | |||
c3a400b73f | |||
48a45c43e4 | |||
9e1fdd1f14 | |||
6c5f8bf5aa | |||
9471715720 | |||
75c9788c27 | |||
d218ba8009 | |||
77e927b58f | |||
fe2f43a15c |
@@ -82,7 +82,7 @@ def create_nb_project_main():
|
||||
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
|
||||
make_exe_basename = os.path.basename(make_exe)
|
||||
|
||||
# --------------- NB specific
|
||||
# --------------- NetBeans specific.
|
||||
defines = [("%s=%s" % cdef) if cdef[1] else cdef[0] for cdef in defines]
|
||||
defines += [cdef.replace("#define", "").strip() for cdef in cmake_compiler_defines()]
|
||||
|
||||
|
@@ -404,7 +404,7 @@ endif()
|
||||
|
||||
# CMake FindOpenMP doesn't know about AppleClang before 3.12, so provide custom flags.
|
||||
if(WITH_OPENMP)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# Use OpenMP from our precompiled libraries.
|
||||
message(STATUS "Using ${LIBDIR}/openmp for OpenMP")
|
||||
set(OPENMP_CUSTOM ON)
|
||||
@@ -480,10 +480,8 @@ else()
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic")
|
||||
endif()
|
||||
|
||||
if(${XCODE_VERSION} VERSION_EQUAL 5 OR ${XCODE_VERSION} VERSION_GREATER 5)
|
||||
# Xcode 5 is always using CLANG, which has too low template depth of 128 for libmv
|
||||
string(APPEND CMAKE_CXX_FLAGS " -ftemplate-depth=1024")
|
||||
endif()
|
||||
# Clang has too low template depth of 128 for libmv.
|
||||
string(APPEND CMAKE_CXX_FLAGS " -ftemplate-depth=1024")
|
||||
|
||||
# Avoid conflicts with Luxrender, and other plug-ins that may use the same
|
||||
# libraries as Blender with a different version or build options.
|
||||
|
@@ -122,7 +122,7 @@ is a full-featured 3D application. It supports the entirety of the 3D pipeline -
|
||||
'''modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
|
||||
|
||||
Use Blender to create 3D images and animations, films and commercials, content for games, '''
|
||||
r'''architectural and industrial visualizatons, and scientific visualizations.
|
||||
r'''architectural and industrial visualizations, and scientific visualizations.
|
||||
|
||||
https://www.blender.org''')
|
||||
|
||||
|
@@ -1047,6 +1047,7 @@ context_type_map = {
|
||||
"annotation_data": ("GreasePencil", False),
|
||||
"annotation_data_owner": ("ID", False),
|
||||
"armature": ("Armature", False),
|
||||
"asset_library": ("AssetLibraryReference", False),
|
||||
"bone": ("Bone", False),
|
||||
"brush": ("Brush", False),
|
||||
"camera": ("Camera", False),
|
||||
@@ -1113,6 +1114,7 @@ context_type_map = {
|
||||
"texture_slot": ("MaterialTextureSlot", False),
|
||||
"texture_user": ("ID", False),
|
||||
"texture_user_property": ("Property", False),
|
||||
"ui_list": ("UIList", False),
|
||||
"vertex_paint_object": ("Object", False),
|
||||
"view_layer": ("ViewLayer", False),
|
||||
"visible_bones": ("EditBone", True),
|
||||
|
2
extern/rangetree/intern/generic_alloc_impl.h
vendored
2
extern/rangetree/intern/generic_alloc_impl.h
vendored
@@ -32,7 +32,7 @@
|
||||
* - #TPOOL_STRUCT: Name for pool struct name.
|
||||
* - #TPOOL_CHUNK_SIZE: Chunk size (optional), use 64kb when not defined.
|
||||
*
|
||||
* \note #TPOOL_ALLOC_TYPE must be at least ``sizeof(void *)``.
|
||||
* \note #TPOOL_ALLOC_TYPE must be at least `sizeof(void *)`.
|
||||
*
|
||||
* Defines the API, uses #TPOOL_IMPL_PREFIX to prefix each function.
|
||||
*
|
||||
|
@@ -1136,7 +1136,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
|
||||
col = row.column(align=True)
|
||||
col.operator("object.material_slot_add", icon='ADD', text="")
|
||||
col.operator("object.material_slot_remove", icon='REMOVE', text="")
|
||||
|
||||
col.separator()
|
||||
col.menu("MATERIAL_MT_context_menu", icon='DOWNARROW_HLT', text="")
|
||||
|
||||
if is_sortable:
|
||||
@@ -1151,16 +1151,15 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
|
||||
row.operator("object.material_slot_select", text="Select")
|
||||
row.operator("object.material_slot_deselect", text="Deselect")
|
||||
|
||||
split = layout.split(factor=0.65)
|
||||
row = layout.row()
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "active_material", new="material.new")
|
||||
row = split.row()
|
||||
row.template_ID(ob, "active_material", new="material.new")
|
||||
|
||||
if slot:
|
||||
row.prop(slot, "link", text="")
|
||||
else:
|
||||
row.label()
|
||||
icon_link = 'MESH_DATA' if slot.link == 'DATA' else 'OBJECT_DATA'
|
||||
row.prop(slot, "link", text="", icon=icon_link, icon_only=True)
|
||||
|
||||
elif mat:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.separator()
|
||||
|
@@ -385,7 +385,7 @@ void ColorSpaceManager::free_memory()
|
||||
{
|
||||
#ifdef WITH_OCIO
|
||||
map_free_memory(cached_colorspaces);
|
||||
map_free_memory(cached_colorspaces);
|
||||
map_free_memory(cached_processors);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -993,7 +993,7 @@ void OSLCompiler::parameter_array(const char *name, const float f[], int arrayle
|
||||
|
||||
void OSLCompiler::parameter_color_array(const char *name, const array<float3> &f)
|
||||
{
|
||||
/* NB: cycles float3 type is actually 4 floats! need to use an explicit array */
|
||||
/* NOTE: cycles float3 type is actually 4 floats! need to use an explicit array. */
|
||||
array<float[3]> table(f.size());
|
||||
|
||||
for (int i = 0; i < f.size(); ++i) {
|
||||
|
@@ -188,8 +188,8 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||
GHOST_GLSettings glSettings);
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Never explicitly delete the context, use disposeContext() instead.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \param systemhandle: The handle to the system.
|
||||
* \param platform_support_callback: An optional callback to check platform support.
|
||||
* \return A handle to the new context ( == NULL if creation failed).
|
||||
@@ -628,7 +628,7 @@ extern void GHOST_ScreenToClient(
|
||||
GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY);
|
||||
|
||||
/**
|
||||
* Converts a point in screen coordinates to client rectangle coordinates
|
||||
* Converts a point in client rectangle coordinates to screen coordinates.
|
||||
* \param windowhandle: The handle to the window.
|
||||
* \param inX: The x-coordinate in the client rectangle.
|
||||
* \param inY: The y-coordinate in the client rectangle.
|
||||
|
@@ -29,8 +29,8 @@
|
||||
/**
|
||||
* Interface for GHOST context.
|
||||
*
|
||||
* You can create a offscreen context (windowless) with the system's
|
||||
* GHOST_ISystem::createOffscreenContext method.
|
||||
* You can create a off-screen context (windowless) with the system's
|
||||
* #GHOST_ISystem::createOffscreenContext method.
|
||||
* \see GHOST_ISystem#createOffscreenContext
|
||||
*/
|
||||
class GHOST_IContext {
|
||||
|
@@ -261,8 +261,8 @@ class GHOST_ISystem {
|
||||
virtual GHOST_TSuccess disposeWindow(GHOST_IWindow *window) = 0;
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Never explicitly delete the context, use disposeContext() instead.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
|
||||
|
@@ -133,7 +133,7 @@ class GHOST_IWindow {
|
||||
virtual void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const = 0;
|
||||
|
||||
/**
|
||||
* Converts a point in screen coordinates to client rectangle coordinates
|
||||
* Converts a point in client rectangle coordinates to screen coordinates.
|
||||
* \param inX: The x-coordinate in the client rectangle.
|
||||
* \param inY: The y-coordinate in the client rectangle.
|
||||
* \param outX: The x-coordinate on the screen.
|
||||
|
@@ -611,9 +611,9 @@ typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, uint64_
|
||||
struct GHOST_XrDrawViewInfo;
|
||||
struct GHOST_XrError;
|
||||
/**
|
||||
* The XR view (i.e. the OpenXR runtime) may require a different graphics library than OpenGL. An
|
||||
* offscreen texture of the viewport will then be drawn into using OpenGL, but the final texture
|
||||
* draw call will happen through another lib (say DirectX).
|
||||
* The XR view (i.e. the OpenXR runtime) may require a different graphics library than OpenGL.
|
||||
* An off-screen texture of the viewport will then be drawn into using OpenGL,
|
||||
* but the final texture draw call will happen through another library (say DirectX).
|
||||
*
|
||||
* This enum defines the possible graphics bindings to attempt to enable.
|
||||
*/
|
||||
@@ -683,6 +683,10 @@ typedef struct GHOST_XrDrawViewInfo {
|
||||
|
||||
/** Set if the buffer should be submitted with a SRGB transfer applied. */
|
||||
char expects_srgb_buffer;
|
||||
|
||||
/** The view that this info represents. Not necessarily the "eye index" (e.g. for quad view
|
||||
* systems, etc). */
|
||||
char view_idx;
|
||||
} GHOST_XrDrawViewInfo;
|
||||
|
||||
typedef struct GHOST_XrError {
|
||||
|
@@ -217,7 +217,7 @@ static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs,
|
||||
attribs.push_back(NSOpenGLPFAOpenGLProfile);
|
||||
attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy);
|
||||
|
||||
// Pixel Format Attributes for the windowed NSOpenGLContext
|
||||
/* Pixel Format Attributes for the windowed NSOpenGLContext. */
|
||||
attribs.push_back(NSOpenGLPFADoubleBuffer);
|
||||
|
||||
if (softwareGL) {
|
||||
@@ -250,7 +250,8 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
||||
static const bool needAlpha = false;
|
||||
#endif
|
||||
|
||||
static bool softwareGL = getenv("BLENDER_SOFTWAREGL"); // command-line argument would be better
|
||||
/* Command-line argument would be better. */
|
||||
static bool softwareGL = getenv("BLENDER_SOFTWAREGL");
|
||||
|
||||
std::vector<NSOpenGLPixelFormatAttribute> attribs;
|
||||
attribs.reserve(40);
|
||||
@@ -287,7 +288,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
||||
|
||||
if (m_metalView) {
|
||||
if (m_defaultFramebuffer == 0) {
|
||||
// Create a virtual framebuffer
|
||||
/* Create a virtual frame-buffer. */
|
||||
[m_openGLContext makeCurrentContext];
|
||||
metalInitFramebuffer();
|
||||
initClearGL();
|
||||
@@ -342,11 +343,11 @@ void GHOST_ContextCGL::metalInit()
|
||||
/* clang-format on */
|
||||
id<MTLDevice> device = m_metalLayer.device;
|
||||
|
||||
// Create a command queue for blit/present operation
|
||||
/* Create a command queue for blit/present operation. */
|
||||
m_metalCmdQueue = (MTLCommandQueue *)[device newCommandQueue];
|
||||
[m_metalCmdQueue retain];
|
||||
|
||||
// Create shaders for blit operation
|
||||
/* Create shaders for blit operation. */
|
||||
NSString *source = @R"msl(
|
||||
using namespace metal;
|
||||
|
||||
@@ -387,7 +388,7 @@ void GHOST_ContextCGL::metalInit()
|
||||
"GHOST_ContextCGL::metalInit: newLibraryWithSource:options:error: failed!");
|
||||
}
|
||||
|
||||
// Create a render pipeline for blit operation
|
||||
/* Create a render pipeline for blit operation. */
|
||||
MTLRenderPipelineDescriptor *desc = [[[MTLRenderPipelineDescriptor alloc] init] autorelease];
|
||||
|
||||
desc.fragmentFunction = [library newFunctionWithName:@"fragment_shader"];
|
||||
@@ -460,7 +461,7 @@ void GHOST_ContextCGL::metalUpdateFramebuffer()
|
||||
"GHOST_ContextCGL::metalUpdateFramebuffer: CVPixelBufferCreate failed!");
|
||||
}
|
||||
|
||||
// Create an OpenGL texture
|
||||
/* Create an OpenGL texture. */
|
||||
CVOpenGLTextureCacheRef cvGLTexCache = nil;
|
||||
cvret = CVOpenGLTextureCacheCreate(kCFAllocatorDefault,
|
||||
nil,
|
||||
@@ -485,7 +486,7 @@ void GHOST_ContextCGL::metalUpdateFramebuffer()
|
||||
unsigned int glTex;
|
||||
glTex = CVOpenGLTextureGetName(cvGLTex);
|
||||
|
||||
// Create a Metal texture
|
||||
/* Create a Metal texture. */
|
||||
CVMetalTextureCacheRef cvMetalTexCache = nil;
|
||||
cvret = CVMetalTextureCacheCreate(
|
||||
kCFAllocatorDefault, nil, m_metalLayer.device, nil, &cvMetalTexCache);
|
||||
|
@@ -283,8 +283,8 @@ GHOST_TSuccess GHOST_ContextEGL::setSwapInterval(int interval)
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::getSwapInterval(int &intervalOut)
|
||||
{
|
||||
// This is a bit of a kludge because there does not seem to
|
||||
// be a way to query the swap interval with EGL.
|
||||
/* This is a bit of a kludge because there does not seem to
|
||||
* be a way to query the swap interval with EGL. */
|
||||
intervalOut = m_swap_interval;
|
||||
|
||||
return GHOST_kSuccess;
|
||||
@@ -365,21 +365,21 @@ static const std::string &api_string(EGLenum api)
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
{
|
||||
// objects have to be declared here due to the use of goto
|
||||
/* Objects have to be declared here due to the use of `goto`. */
|
||||
std::vector<EGLint> attrib_list;
|
||||
EGLint num_config = 0;
|
||||
|
||||
if (m_stereoVisual)
|
||||
fprintf(stderr, "Warning! Stereo OpenGL ES contexts are not supported.\n");
|
||||
|
||||
m_stereoVisual = false; // It doesn't matter what the Window wants.
|
||||
m_stereoVisual = false; /* It doesn't matter what the Window wants. */
|
||||
|
||||
if (!initContextEGLEW()) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
#ifdef WITH_GL_ANGLE
|
||||
// d3dcompiler_XX.dll needs to be loaded before ANGLE will work
|
||||
/* `d3dcompiler_XX.dll` needs to be loaded before ANGLE will work. */
|
||||
if (s_d3dcompiler == NULL) {
|
||||
s_d3dcompiler = LoadLibrary(D3DCOMPILER);
|
||||
|
||||
@@ -410,13 +410,13 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
if (!bindAPI(m_api))
|
||||
goto error;
|
||||
|
||||
// build attribute list
|
||||
/* Build attribute list. */
|
||||
|
||||
attrib_list.reserve(20);
|
||||
|
||||
if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) {
|
||||
// According to the spec it seems that you are required to set EGL_RENDERABLE_TYPE,
|
||||
// but some implementations (ANGLE) do not seem to care.
|
||||
/* According to the spec it seems that you are required to set EGL_RENDERABLE_TYPE,
|
||||
* but some implementations (ANGLE) do not seem to care. */
|
||||
|
||||
if (m_contextMajorVersion == 1) {
|
||||
attrib_list.push_back(EGL_RENDERABLE_TYPE);
|
||||
@@ -469,7 +469,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
#endif
|
||||
|
||||
if (m_nativeWindow == 0) {
|
||||
// off-screen surface
|
||||
/* Off-screen surface. */
|
||||
attrib_list.push_back(EGL_SURFACE_TYPE);
|
||||
attrib_list.push_back(EGL_PBUFFER_BIT);
|
||||
}
|
||||
@@ -479,8 +479,8 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &m_config, 1, &num_config)))
|
||||
goto error;
|
||||
|
||||
// A common error is to assume that ChooseConfig worked because it returned EGL_TRUE
|
||||
if (num_config != 1) // num_config should be exactly 1
|
||||
/* A common error is to assume that ChooseConfig worked because it returned EGL_TRUE. */
|
||||
if (num_config != 1) /* `num_config` should be exactly 1. */
|
||||
goto error;
|
||||
|
||||
if (m_nativeWindow != 0) {
|
||||
|
@@ -239,7 +239,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
|
||||
}
|
||||
attribs[i++] = 0;
|
||||
|
||||
/* Some drivers don't like having a true offscreen context.
|
||||
/* Some drivers don't like having a true off-screen context.
|
||||
* Create a pixel buffer instead of a window to render to.
|
||||
* even if it will never be used for drawing. */
|
||||
int pbuffer_attribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None};
|
||||
|
@@ -335,10 +335,11 @@ void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD)
|
||||
if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC)))
|
||||
goto finalize;
|
||||
|
||||
if (GLEW_CHK(glewInit()) != GLEW_OK)
|
||||
if (GLEW_CHK(glewInit()) != GLEW_OK) {
|
||||
fprintf(stderr, "Warning! Dummy GLEW/WGLEW failed to initialize properly.\n");
|
||||
}
|
||||
|
||||
// the following are not technially WGLEW, but they also require a context to work
|
||||
/* The following are not technically WGLEW, but they also require a context to work. */
|
||||
|
||||
#ifndef NDEBUG
|
||||
free((void *)m_dummyRenderer);
|
||||
|
@@ -51,7 +51,7 @@ GHOST_TSuccess GHOST_DisplayManager::initialize(void)
|
||||
|
||||
GHOST_TSuccess GHOST_DisplayManager::getNumDisplays(uint8_t & /*numDisplays*/) const
|
||||
{
|
||||
// Don't know if we have a display...
|
||||
/* Don't know if we have a display. */
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
@@ -120,18 +120,18 @@ GHOST_TSuccess GHOST_DisplayManager::findMatch(uint8_t display,
|
||||
(int)setting.xPixels, (int)setting.yPixels, (int)setting.bpp, (int)setting.frequency};
|
||||
int capabilities[4];
|
||||
double field, score;
|
||||
double best = 1e12; // A big number
|
||||
double best = 1e12; /* A big number. */
|
||||
int found = 0;
|
||||
|
||||
// Look at all the display modes
|
||||
/* Look at all the display modes. */
|
||||
for (int i = 0; (i < (int)m_settings[display].size()); i++) {
|
||||
// Store the capabilities of the display device
|
||||
/* Store the capabilities of the display device. */
|
||||
capabilities[0] = m_settings[display][i].xPixels;
|
||||
capabilities[1] = m_settings[display][i].yPixels;
|
||||
capabilities[2] = m_settings[display][i].bpp;
|
||||
capabilities[3] = m_settings[display][i].frequency;
|
||||
|
||||
// Match against all the fields of the display settings
|
||||
/* Match against all the fields of the display settings. */
|
||||
score = 0;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
field = capabilities[j] - criteria[j];
|
||||
|
@@ -115,8 +115,10 @@ GHOST_DropTargetX11::~GHOST_DropTargetX11()
|
||||
/* Based on: https://stackoverflow.com/a/2766963/432509 */
|
||||
|
||||
typedef enum DecodeState_e {
|
||||
STATE_SEARCH = 0, ///< searching for an ampersand to convert
|
||||
STATE_CONVERTING ///< convert the two proceeding characters from hex
|
||||
/** Searching for an ampersand to convert. */
|
||||
STATE_SEARCH = 0,
|
||||
/** Convert the two proceeding characters from hex. */
|
||||
STATE_CONVERTING
|
||||
} DecodeState_e;
|
||||
|
||||
void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn)
|
||||
|
@@ -90,7 +90,7 @@ class GHOST_EventDragnDrop : public GHOST_Event {
|
||||
|
||||
~GHOST_EventDragnDrop()
|
||||
{
|
||||
// Free the dropped object data
|
||||
/* Free the dropped object data. */
|
||||
if (m_dragnDropEventData.data == NULL)
|
||||
return;
|
||||
|
||||
|
@@ -108,12 +108,12 @@ GHOST_TSuccess GHOST_EventManager::addConsumer(GHOST_IEventConsumer *consumer)
|
||||
GHOST_TSuccess success;
|
||||
GHOST_ASSERT(consumer, "invalid consumer");
|
||||
|
||||
// Check to see whether the consumer is already in our list
|
||||
/* Check to see whether the consumer is already in our list. */
|
||||
TConsumerVector::const_iterator iter = std::find(
|
||||
m_consumers.begin(), m_consumers.end(), consumer);
|
||||
|
||||
if (iter == m_consumers.end()) {
|
||||
// Add the consumer
|
||||
/* Add the consumer. */
|
||||
m_consumers.push_back(consumer);
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
@@ -128,11 +128,11 @@ GHOST_TSuccess GHOST_EventManager::removeConsumer(GHOST_IEventConsumer *consumer
|
||||
GHOST_TSuccess success;
|
||||
GHOST_ASSERT(consumer, "invalid consumer");
|
||||
|
||||
// Check to see whether the consumer is in our list
|
||||
/* Check to see whether the consumer is in our list. */
|
||||
TConsumerVector::iterator iter = std::find(m_consumers.begin(), m_consumers.end(), consumer);
|
||||
|
||||
if (iter != m_consumers.end()) {
|
||||
// Remove the consumer
|
||||
/* Remove the consumer. */
|
||||
m_consumers.erase(iter);
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
|
@@ -60,6 +60,8 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
|
||||
}
|
||||
catch (const std::runtime_error &) {
|
||||
/* fallback to X11. */
|
||||
delete m_system;
|
||||
m_system = nullptr;
|
||||
}
|
||||
if (!m_system) {
|
||||
m_system = new GHOST_SystemX11();
|
||||
|
@@ -22,51 +22,51 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h> // for error/info reporting
|
||||
#include <string.h> // for memory functions
|
||||
#include <stdio.h> /* For error/info reporting. */
|
||||
#include <string.h> /* For memory functions. */
|
||||
|
||||
#ifdef DEBUG_NDOF_MOTION
|
||||
// printable version of each GHOST_TProgress value
|
||||
/* Printable version of each GHOST_TProgress value. */
|
||||
static const char *progress_string[] = {
|
||||
"not started", "starting", "in progress", "finishing", "finished"};
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_NDOF_BUTTONS
|
||||
static const char *ndof_button_names[] = {
|
||||
// used internally, never sent
|
||||
/* used internally, never sent */
|
||||
"NDOF_BUTTON_NONE",
|
||||
// these two are available from any 3Dconnexion device
|
||||
/* these two are available from any 3Dconnexion device */
|
||||
"NDOF_BUTTON_MENU",
|
||||
"NDOF_BUTTON_FIT",
|
||||
// standard views
|
||||
/* standard views */
|
||||
"NDOF_BUTTON_TOP",
|
||||
"NDOF_BUTTON_BOTTOM",
|
||||
"NDOF_BUTTON_LEFT",
|
||||
"NDOF_BUTTON_RIGHT",
|
||||
"NDOF_BUTTON_FRONT",
|
||||
"NDOF_BUTTON_BACK",
|
||||
// more views
|
||||
/* more views */
|
||||
"NDOF_BUTTON_ISO1",
|
||||
"NDOF_BUTTON_ISO2",
|
||||
// 90 degree rotations
|
||||
/* 90 degree rotations */
|
||||
"NDOF_BUTTON_ROLL_CW",
|
||||
"NDOF_BUTTON_ROLL_CCW",
|
||||
"NDOF_BUTTON_SPIN_CW",
|
||||
"NDOF_BUTTON_SPIN_CCW",
|
||||
"NDOF_BUTTON_TILT_CW",
|
||||
"NDOF_BUTTON_TILT_CCW",
|
||||
// device control
|
||||
/* device control */
|
||||
"NDOF_BUTTON_ROTATE",
|
||||
"NDOF_BUTTON_PANZOOM",
|
||||
"NDOF_BUTTON_DOMINANT",
|
||||
"NDOF_BUTTON_PLUS",
|
||||
"NDOF_BUTTON_MINUS",
|
||||
// keyboard emulation
|
||||
/* keyboard emulation */
|
||||
"NDOF_BUTTON_ESC",
|
||||
"NDOF_BUTTON_ALT",
|
||||
"NDOF_BUTTON_SHIFT",
|
||||
"NDOF_BUTTON_CTRL",
|
||||
// general-purpose buttons
|
||||
/* general-purpose buttons */
|
||||
"NDOF_BUTTON_1",
|
||||
"NDOF_BUTTON_2",
|
||||
"NDOF_BUTTON_3",
|
||||
@@ -77,17 +77,17 @@ static const char *ndof_button_names[] = {
|
||||
"NDOF_BUTTON_8",
|
||||
"NDOF_BUTTON_9",
|
||||
"NDOF_BUTTON_10",
|
||||
// more general-purpose buttons
|
||||
/* more general-purpose buttons */
|
||||
"NDOF_BUTTON_A",
|
||||
"NDOF_BUTTON_B",
|
||||
"NDOF_BUTTON_C",
|
||||
// the end
|
||||
/* the end */
|
||||
"NDOF_BUTTON_LAST"};
|
||||
#endif
|
||||
|
||||
// shared by the latest 3Dconnexion hardware
|
||||
// SpacePilotPro uses all of these
|
||||
// smaller devices use only some, based on button mask
|
||||
/* Shared by the latest 3Dconnexion hardware
|
||||
* SpacePilotPro uses all of these
|
||||
* smaller devices use only some, based on button mask. */
|
||||
static const NDOF_ButtonT Modern3Dx_HID_map[] = {
|
||||
NDOF_BUTTON_MENU, NDOF_BUTTON_FIT, NDOF_BUTTON_TOP, NDOF_BUTTON_LEFT,
|
||||
NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, NDOF_BUTTON_BOTTOM, NDOF_BUTTON_BACK,
|
||||
@@ -116,15 +116,15 @@ static const NDOF_ButtonT SpaceExplorer_HID_map[] = {
|
||||
NDOF_BUTTON_ROTATE,
|
||||
};
|
||||
|
||||
// this is the older SpacePilot (sans Pro)
|
||||
// thanks to polosson for info about this device
|
||||
/* This is the older SpacePilot (sans Pro)
|
||||
* thanks to polosson for info about this device. */
|
||||
static const NDOF_ButtonT SpacePilot_HID_map[] = {
|
||||
NDOF_BUTTON_1, NDOF_BUTTON_2, NDOF_BUTTON_3, NDOF_BUTTON_4,
|
||||
NDOF_BUTTON_5, NDOF_BUTTON_6, NDOF_BUTTON_TOP, NDOF_BUTTON_LEFT,
|
||||
NDOF_BUTTON_RIGHT, NDOF_BUTTON_FRONT, NDOF_BUTTON_ESC, NDOF_BUTTON_ALT,
|
||||
NDOF_BUTTON_SHIFT, NDOF_BUTTON_CTRL, NDOF_BUTTON_FIT, NDOF_BUTTON_MENU,
|
||||
NDOF_BUTTON_PLUS, NDOF_BUTTON_MINUS, NDOF_BUTTON_DOMINANT, NDOF_BUTTON_ROTATE,
|
||||
NDOF_BUTTON_NONE // the CONFIG button -- what does it do?
|
||||
NDOF_BUTTON_NONE /* the CONFIG button -- what does it do? */
|
||||
};
|
||||
|
||||
static const NDOF_ButtonT Generic_HID_map[] = {
|
||||
@@ -146,7 +146,7 @@ static const int genericButtonCount = sizeof(Generic_HID_map) / sizeof(NDOF_Butt
|
||||
|
||||
GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System &sys)
|
||||
: m_system(sys),
|
||||
m_deviceType(NDOF_UnknownDevice), // each platform has its own device detection code
|
||||
m_deviceType(NDOF_UnknownDevice), /* Each platform has its own device detection code. */
|
||||
m_buttonCount(genericButtonCount),
|
||||
m_buttonMask(0),
|
||||
m_hidMap(Generic_HID_map),
|
||||
@@ -157,37 +157,37 @@ GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System &sys)
|
||||
m_motionEventPending(false),
|
||||
m_deadZone(0.0f)
|
||||
{
|
||||
// to avoid the rare situation where one triple is updated and
|
||||
// the other is not, initialize them both here:
|
||||
/* To avoid the rare situation where one triple is updated and
|
||||
* the other is not, initialize them both here: */
|
||||
memset(m_translation, 0, sizeof(m_translation));
|
||||
memset(m_rotation, 0, sizeof(m_rotation));
|
||||
}
|
||||
|
||||
bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short product_id)
|
||||
{
|
||||
// call this function until it returns true
|
||||
// it's a good idea to stop calling it after that, as it will "forget"
|
||||
// whichever device it already found
|
||||
/* Call this function until it returns true
|
||||
* it's a good idea to stop calling it after that, as it will "forget"
|
||||
* whichever device it already found */
|
||||
|
||||
// default to safe generic behavior for "unknown" devices
|
||||
// unidentified devices will emit motion events like normal
|
||||
// rogue buttons do nothing by default, but can be customized by the user
|
||||
/* Default to safe generic behavior for "unknown" devices
|
||||
* unidentified devices will emit motion events like normal
|
||||
* rogue buttons do nothing by default, but can be customized by the user. */
|
||||
|
||||
m_deviceType = NDOF_UnknownDevice;
|
||||
m_hidMap = Generic_HID_map;
|
||||
m_buttonCount = genericButtonCount;
|
||||
m_buttonMask = 0;
|
||||
|
||||
// "mystery device" owners can help build a HID_map for their hardware
|
||||
// A few users have already contributed information about several older devices
|
||||
// that I don't have access to. Thanks!
|
||||
/* "mystery device" owners can help build a HID_map for their hardware
|
||||
* A few users have already contributed information about several older devices
|
||||
* that I don't have access to. Thanks! */
|
||||
|
||||
switch (vendor_id) {
|
||||
case 0x046D: // Logitech (3Dconnexion was a subsidiary)
|
||||
case 0x046D: /* Logitech (3Dconnexion was a subsidiary). */
|
||||
switch (product_id) {
|
||||
// -- current devices --
|
||||
case 0xC626: // full-size SpaceNavigator
|
||||
case 0xC628: // the "for Notebooks" one
|
||||
/* -- current devices -- */
|
||||
case 0xC626: /* full-size SpaceNavigator */
|
||||
case 0xC628: /* the "for Notebooks" one */
|
||||
puts("ndof: using SpaceNavigator");
|
||||
m_deviceType = NDOF_SpaceNavigator;
|
||||
m_buttonCount = 2;
|
||||
@@ -209,12 +209,12 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
|
||||
puts("ndof: using SpaceMouse Pro");
|
||||
m_deviceType = NDOF_SpaceMousePro;
|
||||
m_buttonCount = 27;
|
||||
// ^^ actually has 15 buttons, but their HID codes range from 0 to 26
|
||||
/* ^^ actually has 15 buttons, but their HID codes range from 0 to 26 */
|
||||
m_buttonMask = 0x07C0F137;
|
||||
m_hidMap = Modern3Dx_HID_map;
|
||||
break;
|
||||
|
||||
// -- older devices --
|
||||
/* -- older devices -- */
|
||||
case 0xC625:
|
||||
puts("ndof: using SpacePilot");
|
||||
m_deviceType = NDOF_SpacePilot;
|
||||
@@ -236,21 +236,21 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
|
||||
printf("ndof: unknown Logitech product %04hx\n", product_id);
|
||||
}
|
||||
break;
|
||||
case 0x256F: // 3Dconnexion
|
||||
case 0x256F: /* 3Dconnexion */
|
||||
switch (product_id) {
|
||||
case 0xC62E: // plugged in
|
||||
case 0xC62F: // wireless
|
||||
case 0xC62E: /* Plugged in. */
|
||||
case 0xC62F: /* Wireless. */
|
||||
puts("ndof: using SpaceMouse Wireless");
|
||||
m_deviceType = NDOF_SpaceMouseWireless;
|
||||
m_buttonCount = 2;
|
||||
m_hidMap = Modern3Dx_HID_map;
|
||||
break;
|
||||
case 0xC631: // plugged in
|
||||
case 0xC632: // wireless
|
||||
case 0xC631: /* Plugged in. */
|
||||
case 0xC632: /* Wireless. */
|
||||
puts("ndof: using SpaceMouse Pro Wireless");
|
||||
m_deviceType = NDOF_SpaceMouseProWireless;
|
||||
m_buttonCount = 27;
|
||||
// ^^ actually has 15 buttons, but their HID codes range from 0 to 26
|
||||
/* ^^ actually has 15 buttons, but their HID codes range from 0 to 26. */
|
||||
m_buttonMask = 0x07C0F137;
|
||||
m_hidMap = Modern3Dx_HID_map;
|
||||
break;
|
||||
@@ -364,16 +364,16 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim
|
||||
|
||||
int mask = 1 << button_number;
|
||||
if (press) {
|
||||
m_buttons |= mask; // set this button's bit
|
||||
m_buttons |= mask; /* Set this button's bit. */
|
||||
}
|
||||
else {
|
||||
m_buttons &= ~mask; // clear this button's bit
|
||||
m_buttons &= ~mask; /* Clear this button's bit. */
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_NDOFManager::updateButtons(int button_bits, uint64_t time)
|
||||
{
|
||||
button_bits &= m_buttonMask; // discard any "garbage" bits
|
||||
button_bits &= m_buttonMask; /* Discard any "garbage" bits. */
|
||||
|
||||
int diff = m_buttons ^ button_bits;
|
||||
|
||||
@@ -390,11 +390,11 @@ void GHOST_NDOFManager::updateButtons(int button_bits, uint64_t time)
|
||||
void GHOST_NDOFManager::setDeadZone(float dz)
|
||||
{
|
||||
if (dz < 0.0f) {
|
||||
// negative values don't make sense, so clamp at zero
|
||||
/* Negative values don't make sense, so clamp at zero. */
|
||||
dz = 0.0f;
|
||||
}
|
||||
else if (dz > 0.5f) {
|
||||
// warn the rogue user/developer, but allow it
|
||||
/* Warn the rogue user/developer, but allow it. */
|
||||
GHOST_PRINTF("ndof: dead zone of %.2f is rather high...\n", dz);
|
||||
}
|
||||
m_deadZone = dz;
|
||||
@@ -426,22 +426,22 @@ bool GHOST_NDOFManager::sendMotionEvent()
|
||||
if (!m_motionEventPending)
|
||||
return false;
|
||||
|
||||
m_motionEventPending = false; // any pending motion is handled right now
|
||||
m_motionEventPending = false; /* Any pending motion is handled right now. */
|
||||
|
||||
GHOST_IWindow *window = m_system.getWindowManager()->getActiveWindow();
|
||||
|
||||
if (window == NULL) {
|
||||
m_motionState = GHOST_kNotStarted; // avoid large 'dt' times when changing windows
|
||||
return false; // delivery will fail, so don't bother sending
|
||||
m_motionState = GHOST_kNotStarted; /* Avoid large `dt` times when changing windows. */
|
||||
return false; /* Delivery will fail, so don't bother sending. */
|
||||
}
|
||||
|
||||
GHOST_EventNDOFMotion *event = new GHOST_EventNDOFMotion(m_motionTime, window);
|
||||
GHOST_TEventNDOFMotionData *data = (GHOST_TEventNDOFMotionData *)event->getData();
|
||||
|
||||
// scale axis values here to normalize them to around +/- 1
|
||||
// they are scaled again for overall sensitivity in the WM based on user prefs
|
||||
/* Scale axis values here to normalize them to around +/- 1
|
||||
* they are scaled again for overall sensitivity in the WM based on user preferences. */
|
||||
|
||||
const float scale = 1.0f / 350.0f; // 3Dconnexion devices send +/- 350 usually
|
||||
const float scale = 1.0f / 350.0f; /* 3Dconnexion devices send +/- 350 usually */
|
||||
|
||||
data->tx = scale * m_translation[0];
|
||||
data->ty = scale * m_translation[1];
|
||||
@@ -451,24 +451,24 @@ bool GHOST_NDOFManager::sendMotionEvent()
|
||||
data->ry = scale * m_rotation[1];
|
||||
data->rz = scale * m_rotation[2];
|
||||
|
||||
data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds
|
||||
data->dt = 0.001f * (m_motionTime - m_prevMotionTime); /* In seconds. */
|
||||
m_prevMotionTime = m_motionTime;
|
||||
|
||||
bool weHaveMotion = !nearHomePosition(data, m_deadZone);
|
||||
|
||||
// determine what kind of motion event to send (Starting, InProgress, Finishing)
|
||||
// and where that leaves this NDOF manager (NotStarted, InProgress, Finished)
|
||||
/* Determine what kind of motion event to send `(Starting, InProgress, Finishing)`
|
||||
* and where that leaves this NDOF manager `(NotStarted, InProgress, Finished)`. */
|
||||
switch (m_motionState) {
|
||||
case GHOST_kNotStarted:
|
||||
case GHOST_kFinished:
|
||||
if (weHaveMotion) {
|
||||
data->progress = GHOST_kStarting;
|
||||
m_motionState = GHOST_kInProgress;
|
||||
// prev motion time will be ancient, so just make up a reasonable time delta
|
||||
/* Previous motion time will be ancient, so just make up a reasonable time delta. */
|
||||
data->dt = 0.0125f;
|
||||
}
|
||||
else {
|
||||
// send no event and keep current state
|
||||
/* Send no event and keep current state. */
|
||||
#ifdef DEBUG_NDOF_MOTION
|
||||
printf("ndof motion ignored -- %s\n", progress_string[data->progress]);
|
||||
#endif
|
||||
@@ -479,20 +479,22 @@ bool GHOST_NDOFManager::sendMotionEvent()
|
||||
case GHOST_kInProgress:
|
||||
if (weHaveMotion) {
|
||||
data->progress = GHOST_kInProgress;
|
||||
// remain 'InProgress'
|
||||
/* Remain 'InProgress'. */
|
||||
}
|
||||
else {
|
||||
data->progress = GHOST_kFinishing;
|
||||
m_motionState = GHOST_kFinished;
|
||||
}
|
||||
break;
|
||||
default:; // will always be one of the above
|
||||
default:
|
||||
/* Will always be one of the above. */
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NDOF_MOTION
|
||||
printf("ndof motion sent -- %s\n", progress_string[data->progress]);
|
||||
|
||||
// show details about this motion event
|
||||
/* Show details about this motion event. */
|
||||
printf(" T=(%d,%d,%d) R=(%d,%d,%d) raw\n",
|
||||
m_translation[0],
|
||||
m_translation[1],
|
||||
|
@@ -28,7 +28,7 @@
|
||||
typedef enum {
|
||||
NDOF_UnknownDevice,
|
||||
|
||||
// current devices
|
||||
/* Current devices. */
|
||||
NDOF_SpaceNavigator,
|
||||
NDOF_SpaceExplorer,
|
||||
NDOF_SpacePilotPro,
|
||||
@@ -37,51 +37,51 @@ typedef enum {
|
||||
NDOF_SpaceMouseProWireless,
|
||||
NDOF_SpaceMouseEnterprise,
|
||||
|
||||
// older devices
|
||||
/* Older devices. */
|
||||
NDOF_SpacePilot,
|
||||
NDOF_Spaceball5000,
|
||||
NDOF_SpaceTraveler
|
||||
|
||||
} NDOF_DeviceT;
|
||||
|
||||
// NDOF device button event types
|
||||
/* NDOF device button event types */
|
||||
typedef enum {
|
||||
// used internally, never sent
|
||||
/* Used internally, never sent. */
|
||||
NDOF_BUTTON_NONE,
|
||||
// these two are available from any 3Dconnexion device
|
||||
/* These two are available from any 3Dconnexion device. */
|
||||
NDOF_BUTTON_MENU,
|
||||
NDOF_BUTTON_FIT,
|
||||
// standard views
|
||||
/* Standard views. */
|
||||
NDOF_BUTTON_TOP,
|
||||
NDOF_BUTTON_BOTTOM,
|
||||
NDOF_BUTTON_LEFT,
|
||||
NDOF_BUTTON_RIGHT,
|
||||
NDOF_BUTTON_FRONT,
|
||||
NDOF_BUTTON_BACK,
|
||||
// more views
|
||||
/* More views. */
|
||||
NDOF_BUTTON_ISO1,
|
||||
NDOF_BUTTON_ISO2,
|
||||
// 90 degree rotations
|
||||
// these don't all correspond to physical buttons
|
||||
/* 90 degree rotations.
|
||||
* These don't all correspond to physical buttons. */
|
||||
NDOF_BUTTON_ROLL_CW,
|
||||
NDOF_BUTTON_ROLL_CCW,
|
||||
NDOF_BUTTON_SPIN_CW,
|
||||
NDOF_BUTTON_SPIN_CCW,
|
||||
NDOF_BUTTON_TILT_CW,
|
||||
NDOF_BUTTON_TILT_CCW,
|
||||
// device control
|
||||
/* Device control. */
|
||||
NDOF_BUTTON_ROTATE,
|
||||
NDOF_BUTTON_PANZOOM,
|
||||
NDOF_BUTTON_DOMINANT,
|
||||
NDOF_BUTTON_PLUS,
|
||||
NDOF_BUTTON_MINUS,
|
||||
// keyboard emulation
|
||||
/* Keyboard emulation. */
|
||||
NDOF_BUTTON_ESC,
|
||||
NDOF_BUTTON_ALT,
|
||||
NDOF_BUTTON_SHIFT,
|
||||
NDOF_BUTTON_CTRL,
|
||||
// general-purpose buttons
|
||||
// users can assign functions via keymap editor
|
||||
/* General-purpose buttons.
|
||||
* Users can assign functions via keymap editor. */
|
||||
NDOF_BUTTON_1,
|
||||
NDOF_BUTTON_2,
|
||||
NDOF_BUTTON_3,
|
||||
@@ -92,11 +92,11 @@ typedef enum {
|
||||
NDOF_BUTTON_8,
|
||||
NDOF_BUTTON_9,
|
||||
NDOF_BUTTON_10,
|
||||
// more general-purpose buttons
|
||||
/* More general-purpose buttons. */
|
||||
NDOF_BUTTON_A,
|
||||
NDOF_BUTTON_B,
|
||||
NDOF_BUTTON_C,
|
||||
// the end
|
||||
/* The end. */
|
||||
NDOF_BUTTON_LAST
|
||||
} NDOF_ButtonT;
|
||||
|
||||
@@ -107,40 +107,53 @@ class GHOST_NDOFManager {
|
||||
{
|
||||
}
|
||||
|
||||
// whether multi-axis functionality is available (via the OS or driver)
|
||||
// does not imply that a device is plugged in or being used
|
||||
/**
|
||||
* Whether multi-axis functionality is available (via the OS or driver)
|
||||
* does not imply that a device is plugged in or being used.
|
||||
*/
|
||||
virtual bool available() = 0;
|
||||
|
||||
// each platform's device detection should call this
|
||||
// use standard USB/HID identifiers
|
||||
/**
|
||||
* Each platform's device detection should call this
|
||||
* use standard USB/HID identifiers.
|
||||
*/
|
||||
bool setDevice(unsigned short vendor_id, unsigned short product_id);
|
||||
|
||||
// filter out small/accidental/uncalibrated motions by
|
||||
// setting up a "dead zone" around home position
|
||||
// set to 0 to disable
|
||||
// 0.1 is a safe and reasonable value
|
||||
/**
|
||||
* Filter out small/accidental/un-calibrated motions by
|
||||
* setting up a "dead zone" around home position
|
||||
* set to 0 to disable
|
||||
* 0.1 is a safe and reasonable value.
|
||||
*/
|
||||
void setDeadZone(float);
|
||||
|
||||
// the latest raw axis data from the device
|
||||
// NOTE: axis data should be in blender view coordinates
|
||||
// +X is to the right
|
||||
// +Y is up
|
||||
// +Z is out of the screen
|
||||
// for rotations, look from origin to each +axis
|
||||
// rotations are + when CCW, - when CW
|
||||
// each platform is responsible for getting axis data into this form
|
||||
// these values should not be scaled (just shuffled or flipped)
|
||||
/**
|
||||
* The latest raw axis data from the device.
|
||||
*
|
||||
* \note axis data should be in blender view coordinates
|
||||
* - +X is to the right.
|
||||
* - +Y is up.
|
||||
* - +Z is out of the screen.
|
||||
* - for rotations, look from origin to each +axis.
|
||||
* - rotations are + when CCW, - when CW.
|
||||
* Each platform is responsible for getting axis data into this form
|
||||
* these values should not be scaled (just shuffled or flipped).
|
||||
*/
|
||||
void updateTranslation(const int t[3], uint64_t time);
|
||||
void updateRotation(const int r[3], uint64_t time);
|
||||
|
||||
// the latest raw button data from the device
|
||||
// use HID button encoding (not NDOF_ButtonT)
|
||||
/**
|
||||
* The latest raw button data from the device
|
||||
* use HID button encoding (not #NDOF_ButtonT).
|
||||
*/
|
||||
void updateButton(int button_number, bool press, uint64_t time);
|
||||
void updateButtons(int button_bits, uint64_t time);
|
||||
// NDOFButton events are sent immediately
|
||||
/* #NDOFButton events are sent immediately */
|
||||
|
||||
// processes and sends most recent raw data as an NDOFMotion event
|
||||
// returns whether an event was sent
|
||||
/**
|
||||
* Processes and sends most recent raw data as an #NDOFMotion event
|
||||
* returns whether an event was sent.
|
||||
*/
|
||||
bool sendMotionEvent();
|
||||
|
||||
protected:
|
||||
@@ -157,12 +170,12 @@ class GHOST_NDOFManager {
|
||||
|
||||
int m_translation[3];
|
||||
int m_rotation[3];
|
||||
int m_buttons; // bit field
|
||||
int m_buttons; /* Bit field. */
|
||||
|
||||
uint64_t m_motionTime; // in milliseconds
|
||||
uint64_t m_prevMotionTime; // time of most recent Motion event sent
|
||||
uint64_t m_motionTime; /* In milliseconds. */
|
||||
uint64_t m_prevMotionTime; /* Time of most recent motion event sent. */
|
||||
|
||||
GHOST_TProgress m_motionState;
|
||||
bool m_motionEventPending;
|
||||
float m_deadZone; // discard motion with each component < this
|
||||
float m_deadZone; /* Discard motion with each component < this. */
|
||||
};
|
||||
|
@@ -26,14 +26,14 @@
|
||||
void GHOST_Rect::inset(int32_t i)
|
||||
{
|
||||
if (i > 0) {
|
||||
// Grow the rectangle
|
||||
/* Grow the rectangle. */
|
||||
m_l -= i;
|
||||
m_r += i;
|
||||
m_t -= i;
|
||||
m_b += i;
|
||||
}
|
||||
else if (i < 0) {
|
||||
// Shrink the rectangle, check for insets larger than half the size
|
||||
/* Shrink the rectangle, check for insets larger than half the size. */
|
||||
int32_t i2 = i * 2;
|
||||
if (getWidth() > i2) {
|
||||
m_l += i;
|
||||
@@ -62,12 +62,12 @@ GHOST_TVisibility GHOST_Rect::getVisibility(GHOST_Rect &r) const
|
||||
bool rb = isInside(r.m_r, r.m_b);
|
||||
GHOST_TVisibility v;
|
||||
if (lt && rt && lb && rb) {
|
||||
// All points inside, rectangle is inside this
|
||||
/* All points inside, rectangle is inside this. */
|
||||
v = GHOST_kFullyVisible;
|
||||
}
|
||||
else if (!(lt || rt || lb || rb)) {
|
||||
// None of the points inside
|
||||
// Check to see whether the rectangle is larger than this one
|
||||
/* None of the points inside.
|
||||
* Check to see whether the rectangle is larger than this one. */
|
||||
if ((r.m_l < m_l) && (r.m_t < m_t) && (r.m_r > m_r) && (r.m_b > m_b)) {
|
||||
v = GHOST_kPartiallyVisible;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ GHOST_TVisibility GHOST_Rect::getVisibility(GHOST_Rect &r) const
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Some of the points inside, rectangle is partially inside
|
||||
/* Some of the points inside, rectangle is partially inside. */
|
||||
v = GHOST_kPartiallyVisible;
|
||||
}
|
||||
return v;
|
||||
|
@@ -72,7 +72,7 @@ GHOST_ITimerTask *GHOST_System::installTimer(uint64_t delay,
|
||||
GHOST_TimerTask *timer = new GHOST_TimerTask(millis + delay, interval, timerProc, userData);
|
||||
if (timer) {
|
||||
if (m_timerManager->addTimer(timer) == GHOST_kSuccess) {
|
||||
// Check to see whether we need to fire the timer right away
|
||||
/* Check to see whether we need to fire the timer right away. */
|
||||
m_timerManager->fireTimers(millis);
|
||||
}
|
||||
else {
|
||||
@@ -208,7 +208,7 @@ bool GHOST_System::getFullScreen(void)
|
||||
void GHOST_System::dispatchEvents()
|
||||
{
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
// NDOF Motion event is sent only once per dispatch, so do it now:
|
||||
/* NDOF Motion event is sent only once per dispatch, so do it now: */
|
||||
if (m_ndofManager) {
|
||||
m_ndofManager->sendMotionEvent();
|
||||
}
|
||||
@@ -260,10 +260,10 @@ GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent *event)
|
||||
GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bool &isDown) const
|
||||
{
|
||||
GHOST_ModifierKeys keys;
|
||||
// Get the state of all modifier keys
|
||||
/* Get the state of all modifier keys. */
|
||||
GHOST_TSuccess success = getModifierKeys(keys);
|
||||
if (success) {
|
||||
// Isolate the state of the key requested
|
||||
/* Isolate the state of the key requested. */
|
||||
isDown = keys.get(mask);
|
||||
}
|
||||
return success;
|
||||
@@ -272,10 +272,10 @@ GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bo
|
||||
GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButtonMask mask, bool &isDown) const
|
||||
{
|
||||
GHOST_Buttons buttons;
|
||||
// Get the state of all mouse buttons
|
||||
/* Get the state of all mouse buttons. */
|
||||
GHOST_TSuccess success = getButtons(buttons);
|
||||
if (success) {
|
||||
// Isolate the state of the mouse button requested
|
||||
/* Isolate the state of the mouse button requested. */
|
||||
isDown = buttons.get(mask);
|
||||
}
|
||||
return success;
|
||||
@@ -311,7 +311,7 @@ GHOST_TSuccess GHOST_System::init()
|
||||
m_eventPrinter = new GHOST_EventPrinter();
|
||||
m_eventManager->addConsumer(m_eventPrinter);
|
||||
}
|
||||
#endif // WITH_GHOST_DEBUG
|
||||
#endif /* WITH_GHOST_DEBUG */
|
||||
|
||||
if (m_timerManager && m_windowManager && m_eventManager) {
|
||||
return GHOST_kSuccess;
|
||||
@@ -359,7 +359,7 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
|
||||
if (alphaBackground)
|
||||
glSettings.flags |= GHOST_glAlphaBackground;
|
||||
|
||||
/* note: don't use getCurrentDisplaySetting() because on X11 we may
|
||||
/* NOTE: don't use #getCurrentDisplaySetting() because on X11 we may
|
||||
* be zoomed in and the desktop may be bigger than the viewport. */
|
||||
GHOST_ASSERT(m_displayManager,
|
||||
"GHOST_System::createFullScreenWindow(): invalid display manager");
|
||||
|
@@ -113,8 +113,8 @@ class GHOST_System : public GHOST_ISystem {
|
||||
GHOST_TSuccess disposeWindow(GHOST_IWindow *window);
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Never explicitly delete the context, use disposeContext() instead.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
|
||||
|
@@ -112,8 +112,8 @@ class GHOST_SystemCocoa : public GHOST_System {
|
||||
const GHOST_IWindow *parentWindow = NULL);
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Never explicitly delete the context, use disposeContext() instead.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
|
@@ -761,7 +761,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
|
@@ -143,7 +143,7 @@ GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GLSettings glSetti
|
||||
{
|
||||
GHOST_Context *context = new GHOST_ContextSDL(0,
|
||||
NULL,
|
||||
0, // profile bit
|
||||
0, /* Profile bit. */
|
||||
3,
|
||||
3,
|
||||
GHOST_OPENGL_SDL_CONTEXT_FLAGS,
|
||||
@@ -279,7 +279,7 @@ static GHOST_TKey convertSDLKey(SDL_Scancode key)
|
||||
GXMAP(type, SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay);
|
||||
GXMAP(type, SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop);
|
||||
GXMAP(type, SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst);
|
||||
// GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
|
||||
// GXMAP(type, XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
|
||||
GXMAP(type, SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast);
|
||||
|
||||
default:
|
||||
@@ -315,7 +315,10 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
SDL_WindowEvent &sdl_sub_evt = sdl_event->window;
|
||||
GHOST_WindowSDL *window = findGhostWindow(
|
||||
SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
|
||||
// assert(window != NULL); // can be NULL on close window.
|
||||
/* Can be NULL on close window. */
|
||||
#if 0
|
||||
assert(window != NULL);
|
||||
#endif
|
||||
|
||||
switch (sdl_sub_evt.event) {
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
@@ -376,14 +379,14 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis());
|
||||
window->getCursorGrabAccum(x_accum, y_accum);
|
||||
|
||||
// can't use setCursorPosition because the mouse may have no focus!
|
||||
/* Can't use #setCursorPosition because the mouse may have no focus! */
|
||||
if (x_new != x_root || y_new != y_root) {
|
||||
if (1) { //xme.time > m_last_warp) {
|
||||
if (1 /* `xme.time > m_last_warp` */ ) {
|
||||
/* when wrapping we don't need to add an event because the
|
||||
* setCursorPosition call will cause a new event after */
|
||||
* #setCursorPosition call will cause a new event after */
|
||||
SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */
|
||||
window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new));
|
||||
// m_last_warp= lastEventTime(xme.time);
|
||||
// m_last_warp = lastEventTime(xme.time);
|
||||
}
|
||||
else {
|
||||
// setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
|
||||
@@ -659,8 +662,8 @@ bool GHOST_SystemSDL::generateWindowExposeEvents()
|
||||
|
||||
bool GHOST_SystemSDL::processEvents(bool waitForEvent)
|
||||
{
|
||||
// Get all the current events -- translate them into
|
||||
// ghost events and call base class pushEvent() method.
|
||||
/* Get all the current events - translate them into
|
||||
* ghost events and call base class #pushEvent() method. */
|
||||
|
||||
bool anyProcessed = false;
|
||||
|
||||
@@ -679,7 +682,7 @@ bool GHOST_SystemSDL::processEvents(bool waitForEvent)
|
||||
|
||||
if (maxSleep >= 0) {
|
||||
SDL_WaitEventTimeout(NULL, next - getMilliSeconds());
|
||||
// SleepTillEvent(m_display, next - getMilliSeconds()); // X11
|
||||
// SleepTillEvent(m_display, next - getMilliSeconds()); /* X11. */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -707,10 +710,10 @@ GHOST_WindowSDL *GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
|
||||
if (sdl_win == NULL)
|
||||
return NULL;
|
||||
|
||||
// It is not entirely safe to do this as the backptr may point
|
||||
// to a window that has recently been removed.
|
||||
// We should always check the window manager's list of windows
|
||||
// and only process events on these windows.
|
||||
/* It is not entirely safe to do this as the backptr may point
|
||||
* to a window that has recently been removed.
|
||||
* We should always check the window manager's list of windows
|
||||
* and only process events on these windows. */
|
||||
|
||||
const std::vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
|
||||
|
||||
|
@@ -259,7 +259,7 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the window, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
@@ -363,7 +363,7 @@ GHOST_TSuccess GHOST_SystemWin32::disposeContext(GHOST_IContext *context)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new offscreen DirectX 11 context.
|
||||
* Create a new off-screen DirectX 11 context.
|
||||
* Never explicitly delete the window, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
|
@@ -138,8 +138,8 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
const GHOST_IWindow *parentWindow = 0);
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Never explicitly delete the window, use disposeContext() instead.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the window, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
@@ -152,8 +152,8 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
GHOST_TSuccess disposeContext(GHOST_IContext *context);
|
||||
|
||||
/**
|
||||
* Create a new offscreen DirectX context.
|
||||
* Never explicitly delete the context, use disposeContext() instead.
|
||||
* Create a new off-screen DirectX context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* This is for GHOST internal, Win32 specific use, so it can be called statically.
|
||||
*
|
||||
* \return The new context (or 0 if creation failed).
|
||||
@@ -360,8 +360,8 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw);
|
||||
|
||||
/**
|
||||
* Process special keys (VK_OEM_*), to see if current key layout
|
||||
* gives us anything special, like ! on french AZERTY.
|
||||
* Process special keys `VK_OEM_*`, to see if current key layout
|
||||
* gives us anything special, like `!` on French AZERTY.
|
||||
* \param vKey: The virtual key from #hardKey.
|
||||
* \param scanCode: The ScanCode of pressed key (similar to PS/2 Set 1).
|
||||
*/
|
||||
|
@@ -390,21 +390,21 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Never explicitly delete the context, use disposeContext() instead.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
{
|
||||
// During development:
|
||||
// try 4.x compatibility profile
|
||||
// try 3.3 compatibility profile
|
||||
// fall back to 3.0 if needed
|
||||
//
|
||||
// Final Blender 2.8:
|
||||
// try 4.x core profile
|
||||
// try 3.3 core profile
|
||||
// no fallbacks
|
||||
/* During development:
|
||||
* try 4.x compatibility profile
|
||||
* try 3.3 compatibility profile
|
||||
* fall back to 3.0 if needed
|
||||
*
|
||||
* Final Blender 2.8:
|
||||
* try 4.x core profile
|
||||
* try 3.3 core profile
|
||||
* no fall-backs. */
|
||||
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
|
||||
@@ -2014,7 +2014,7 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
|
||||
return;
|
||||
}
|
||||
|
||||
// not using INCR mechanism, just read the property
|
||||
/* Not using INCR mechanism, just read the property. */
|
||||
XGetWindowProperty(m_display,
|
||||
win,
|
||||
m_atom.XCLIP_OUT,
|
||||
|
@@ -148,8 +148,8 @@ class GHOST_SystemX11 : public GHOST_System {
|
||||
const GHOST_IWindow *parentWindow = 0);
|
||||
|
||||
/**
|
||||
* Create a new offscreen context.
|
||||
* Never explicitly delete the context, use disposeContext() instead.
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
|
@@ -55,7 +55,7 @@ GHOST_TSuccess GHOST_TimerManager::addTimer(GHOST_TimerTask *timer)
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
if (!getTimerFound(timer)) {
|
||||
// Add the timer task
|
||||
/* Add the timer task. */
|
||||
m_timers.push_back(timer);
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ GHOST_TSuccess GHOST_TimerManager::removeTimer(GHOST_TimerTask *timer)
|
||||
GHOST_TSuccess success;
|
||||
TTimerVector::iterator iter = std::find(m_timers.begin(), m_timers.end(), timer);
|
||||
if (iter != m_timers.end()) {
|
||||
// Remove the timer task
|
||||
/* Remove the timer task. */
|
||||
m_timers.erase(iter);
|
||||
delete timer;
|
||||
success = GHOST_kSuccess;
|
||||
@@ -113,14 +113,14 @@ bool GHOST_TimerManager::fireTimer(uint64_t time, GHOST_TimerTask *task)
|
||||
{
|
||||
uint64_t next = task->getNext();
|
||||
|
||||
// Check if the timer should be fired
|
||||
/* Check if the timer should be fired. */
|
||||
if (time > next) {
|
||||
// Fire the timer
|
||||
/* Fire the timer. */
|
||||
GHOST_TimerProcPtr timerProc = task->getTimerProc();
|
||||
uint64_t start = task->getStart();
|
||||
timerProc(task, time - start);
|
||||
|
||||
// Update the time at which we will fire it again
|
||||
/* Update the time at which we will fire it again. */
|
||||
uint64_t interval = task->getInterval();
|
||||
uint64_t numCalls = (next - start) / interval;
|
||||
numCalls++;
|
||||
|
@@ -157,7 +157,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
|
||||
void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const;
|
||||
|
||||
/**
|
||||
* Converts a point in screen coordinates to client rectangle coordinates
|
||||
* Converts a point in client rectangle coordinates to screen coordinates.
|
||||
* \param inX: The x-coordinate in the client rectangle.
|
||||
* \param inY: The y-coordinate in the client rectangle.
|
||||
* \param outX: The x-coordinate on the screen.
|
||||
@@ -166,7 +166,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
|
||||
void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const;
|
||||
|
||||
/**
|
||||
* Converts a point in screen coordinates to client rectangle coordinates
|
||||
* Converts a point in client rectangle coordinates to screen coordinates.
|
||||
* but without the y coordinate conversion needed for ghost compatibility.
|
||||
* \param inX: The x-coordinate in the client rectangle.
|
||||
* \param inY: The y-coordinate in the client rectangle.
|
||||
@@ -178,10 +178,10 @@ class GHOST_WindowCocoa : public GHOST_Window {
|
||||
/**
|
||||
* Converts a point in screen coordinates to client rectangle coordinates,
|
||||
* but without the y coordinate conversion needed for ghost compatibility.
|
||||
* \param inX: The x-coordinate in the client rectangle.
|
||||
* \param inY: The y-coordinate in the client rectangle.
|
||||
* \param outX: The x-coordinate on the screen.
|
||||
* \param outY: The y-coordinate on the screen.
|
||||
* \param inX: The x-coordinate on the screen.
|
||||
* \param inY: The y-coordinate on the screen.
|
||||
* \param outX: The x-coordinate in the client rectangle.
|
||||
* \param outY: The y-coordinate in the client rectangle.
|
||||
*/
|
||||
void screenToClientIntern(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const;
|
||||
|
||||
|
@@ -45,7 +45,7 @@ GHOST_TSuccess GHOST_WindowManager::addWindow(GHOST_IWindow *window)
|
||||
GHOST_TSuccess success = GHOST_kFailure;
|
||||
if (window) {
|
||||
if (!getWindowFound(window)) {
|
||||
// Store the pointer to the window
|
||||
/* Store the pointer to the window. */
|
||||
m_windows.push_back(window);
|
||||
success = GHOST_kSuccess;
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ static constexpr size_t base_dpi = 96;
|
||||
struct window_t {
|
||||
GHOST_WindowWayland *w;
|
||||
wl_surface *surface;
|
||||
// outputs on which the window is currently shown on
|
||||
/* Outputs on which the window is currently shown on. */
|
||||
std::unordered_set<const output_t *> outputs;
|
||||
uint16_t dpi = 0;
|
||||
int scale = 1;
|
||||
@@ -154,8 +154,8 @@ static bool update_scale(GHOST_WindowWayland *window)
|
||||
|
||||
if (scale > 0 && window->scale() != scale) {
|
||||
window->scale() = scale;
|
||||
// using the real DPI will cause wrong scaling of the UI
|
||||
// use a multiplier for the default DPI as workaround
|
||||
/* Using the real DPI will cause wrong scaling of the UI
|
||||
* use a multiplier for the default DPI as workaround. */
|
||||
window->dpi() = scale * base_dpi;
|
||||
wl_surface_set_buffer_scale(window->surface(), scale);
|
||||
return true;
|
||||
|
@@ -183,7 +183,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const;
|
||||
|
||||
/**
|
||||
* Converts a point in screen coordinates to client rectangle coordinates
|
||||
* Converts a point in client rectangle coordinates to screen coordinates.
|
||||
* \param inX: The x-coordinate in the client rectangle.
|
||||
* \param inY: The y-coordinate in the client rectangle.
|
||||
* \param outX: The x-coordinate on the screen.
|
||||
|
@@ -120,7 +120,7 @@ static void create_reference_spaces(OpenXRSessionData &oxr, const GHOST_XrPose &
|
||||
XrReferenceSpaceCreateInfo create_info = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
|
||||
create_info.poseInReferenceSpace.orientation.w = 1.0f;
|
||||
|
||||
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
|
||||
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
|
||||
#if 0
|
||||
/* TODO
|
||||
*
|
||||
@@ -144,8 +144,47 @@ static void create_reference_spaces(OpenXRSessionData &oxr, const GHOST_XrPose &
|
||||
(void)base_pose;
|
||||
#endif
|
||||
|
||||
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space),
|
||||
"Failed to create reference space.");
|
||||
XrResult result = xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space);
|
||||
|
||||
if (XR_FAILED(result)) {
|
||||
/* One of the rare cases where we don't want to immediately throw an exception on failure,
|
||||
* since run-times are not required to support the stage reference space. Although we need the
|
||||
* stage reference space for absolute tracking, if the runtime doesn't support it then just
|
||||
* fallback to the local space. */
|
||||
if (result == XR_ERROR_REFERENCE_SPACE_UNSUPPORTED) {
|
||||
printf(
|
||||
"Warning: XR runtime does not support stage reference space, disabling absolute "
|
||||
"tracking.\n");
|
||||
|
||||
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
|
||||
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space),
|
||||
"Failed to create local reference space.");
|
||||
}
|
||||
else {
|
||||
throw GHOST_XrException("Failed to create stage reference space.", result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Check if tracking bounds are valid. Tracking bounds may be invalid if the user did not
|
||||
* define a tracking space via the XR runtime. */
|
||||
XrExtent2Df extents;
|
||||
CHECK_XR(xrGetReferenceSpaceBoundsRect(oxr.session, XR_REFERENCE_SPACE_TYPE_STAGE, &extents),
|
||||
"Failed to get stage reference space bounds.");
|
||||
if (extents.width == 0.0f || extents.height == 0.0f) {
|
||||
printf(
|
||||
"Warning: Invalid stage reference space bounds, disabling absolute tracking. To enable "
|
||||
"absolute tracking, please define a tracking space via the XR runtime.\n");
|
||||
|
||||
/* Fallback to local space. */
|
||||
if (oxr.reference_space != XR_NULL_HANDLE) {
|
||||
CHECK_XR(xrDestroySpace(oxr.reference_space), "Failed to destroy stage reference space.");
|
||||
}
|
||||
|
||||
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
|
||||
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space),
|
||||
"Failed to create local reference space.");
|
||||
}
|
||||
}
|
||||
|
||||
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
|
||||
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.view_space),
|
||||
@@ -370,6 +409,7 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
|
||||
XrCompositionLayerProjectionView &r_proj_layer_view,
|
||||
XrSpaceLocation &view_location,
|
||||
XrView &view,
|
||||
uint32_t view_idx,
|
||||
void *draw_customdata)
|
||||
{
|
||||
XrSwapchainImageBaseHeader *swapchain_image = swapchain.acquireDrawableSwapchainImage();
|
||||
@@ -380,6 +420,8 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
|
||||
r_proj_layer_view.fov = view.fov;
|
||||
swapchain.updateCompositionLayerProjectViewSubImage(r_proj_layer_view.subImage);
|
||||
|
||||
assert(view_idx < 256);
|
||||
draw_view_info.view_idx = (char)view_idx;
|
||||
draw_view_info.expects_srgb_buffer = swapchain.isBufferSRGB();
|
||||
draw_view_info.ofsx = r_proj_layer_view.subImage.imageRect.offset.x;
|
||||
draw_view_info.ofsy = r_proj_layer_view.subImage.imageRect.offset.y;
|
||||
@@ -429,6 +471,7 @@ XrCompositionLayerProjection GHOST_XrSession::drawLayer(
|
||||
r_proj_layer_views[view_idx],
|
||||
view_location,
|
||||
m_oxr->views[view_idx],
|
||||
view_idx,
|
||||
draw_customdata);
|
||||
}
|
||||
|
||||
|
@@ -117,6 +117,7 @@ class GHOST_XrSession {
|
||||
XrCompositionLayerProjectionView &r_proj_layer_view,
|
||||
XrSpaceLocation &view_location,
|
||||
XrView &view,
|
||||
uint32_t view_idx,
|
||||
void *draw_customdata);
|
||||
void beginFrameDrawing();
|
||||
void endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> &layers);
|
||||
|
@@ -67,7 +67,7 @@ const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr;
|
||||
|
||||
void *aligned_malloc(size_t size, size_t alignment)
|
||||
{
|
||||
/* posix_memalign requires alignment to be a multiple of sizeof(void *). */
|
||||
/* #posix_memalign requires alignment to be a multiple of `sizeof(void *)`. */
|
||||
assert(alignment >= ALIGNED_MALLOC_MINIMUM_ALIGNMENT);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@@ -217,39 +217,39 @@ if(WITH_LIBMV)
|
||||
if(WITH_GTESTS)
|
||||
include(GTestTesting)
|
||||
|
||||
blender_add_lib(libmv_test_dataset "./libmv/multiview/test_data_sets.cc" "" "" "")
|
||||
blender_add_lib(libmv_test_dataset "./libmv/multiview/test_data_sets.cc" "${INC}" "${INC_SYS}" "")
|
||||
|
||||
BLENDER_SRC_GTEST("libmv_predict_tracks" "./libmv/autotrack/predict_tracks_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_tracks" "./libmv/autotrack/tracks_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_scoped_ptr" "./libmv/base/scoped_ptr_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_vector" "./libmv/base/vector_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_array_nd" "./libmv/image/array_nd_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_convolve" "./libmv/image/convolve_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_image" "./libmv/image/image_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_sample" "./libmv/image/sample_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_tuple" "./libmv/image/tuple_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_euclidean_resection" "./libmv/multiview/euclidean_resection_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_fundamental" "./libmv/multiview/fundamental_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_homography" "./libmv/multiview/homography_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_nviewtriangulation" "./libmv/multiview/nviewtriangulation_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_panography" "./libmv/multiview/panography_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_projection" "./libmv/multiview/projection_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_resection" "./libmv/multiview/resection_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_triangulation" "./libmv/multiview/triangulation_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_dogleg" "./libmv/numeric/dogleg_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_function_derivative" "./libmv/numeric/function_derivative_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_levenberg_marquardt" "./libmv/numeric/levenberg_marquardt_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_numeric" "./libmv/numeric/numeric_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_poly" "./libmv/numeric/poly_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_camera_intrinsics" "./libmv/simple_pipeline/camera_intrinsics_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_detect" "./libmv/simple_pipeline/detect_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_intersect" "./libmv/simple_pipeline/intersect_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_keyframe_selection" "./libmv/simple_pipeline/keyframe_selection_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_modal_solver" "./libmv/simple_pipeline/modal_solver_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_resect" "./libmv/simple_pipeline/resect_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_brute_region_tracker" "./libmv/tracking/brute_region_tracker_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_klt_region_tracker" "./libmv/tracking/klt_region_tracker_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
BLENDER_SRC_GTEST("libmv_pyramid_region_tracker" "./libmv/tracking/pyramid_region_tracker_test.cc" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_predict_tracks" "./libmv/autotrack/predict_tracks_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_tracks" "./libmv/autotrack/tracks_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_scoped_ptr" "./libmv/base/scoped_ptr_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_vector" "./libmv/base/vector_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_array_nd" "./libmv/image/array_nd_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_convolve" "./libmv/image/convolve_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_image" "./libmv/image/image_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_sample" "./libmv/image/sample_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_tuple" "./libmv/image/tuple_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_euclidean_resection" "./libmv/multiview/euclidean_resection_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_fundamental" "./libmv/multiview/fundamental_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_homography" "./libmv/multiview/homography_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_nviewtriangulation" "./libmv/multiview/nviewtriangulation_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_panography" "./libmv/multiview/panography_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_projection" "./libmv/multiview/projection_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_resection" "./libmv/multiview/resection_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_triangulation" "./libmv/multiview/triangulation_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_dogleg" "./libmv/numeric/dogleg_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_function_derivative" "./libmv/numeric/function_derivative_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_levenberg_marquardt" "./libmv/numeric/levenberg_marquardt_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_numeric" "./libmv/numeric/numeric_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_poly" "./libmv/numeric/poly_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_camera_intrinsics" "./libmv/simple_pipeline/camera_intrinsics_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_detect" "./libmv/simple_pipeline/detect_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_intersect" "./libmv/simple_pipeline/intersect_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_keyframe_selection" "./libmv/simple_pipeline/keyframe_selection_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_modal_solver" "./libmv/simple_pipeline/modal_solver_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_resect" "./libmv/simple_pipeline/resect_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_brute_region_tracker" "./libmv/tracking/brute_region_tracker_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_klt_region_tracker" "./libmv/tracking/klt_region_tracker_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
blender_add_test_executable("libmv_pyramid_region_tracker" "./libmv/tracking/pyramid_region_tracker_test.cc" "${INC}" "${INC_SYS}" "libmv_test_dataset;bf_intern_libmv;extern_ceres")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND SRC
|
||||
|
@@ -62,8 +62,8 @@ template<typename _Tp> struct MEM_Allocator {
|
||||
return &__x;
|
||||
}
|
||||
|
||||
// NB: __n is permitted to be 0. The C++ standard says nothing
|
||||
// about what the return value is when __n == 0.
|
||||
/* NOTE: `__n` is permitted to be 0.
|
||||
* The C++ standard says nothing about what the return value is when `__n == 0`. */
|
||||
_Tp *allocate(size_type __n, const void * = 0)
|
||||
{
|
||||
_Tp *__ret = NULL;
|
||||
|
@@ -129,5 +129,5 @@ if(WITH_GTESTS AND WITH_OPENSUBDIV)
|
||||
add_definitions(${GLOG_DEFINES})
|
||||
add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
|
||||
|
||||
BLENDER_SRC_GTEST(opensubdiv_mesh_topology_test "internal/topology/mesh_topology_test.cc" "${LIB};bf_intern_opensubdiv")
|
||||
blender_add_test_executable(opensubdiv_mesh_topology_test "internal/topology/mesh_topology_test.cc" "${INC}" "${INC_SYS}" "${LIB};bf_intern_opensubdiv")
|
||||
endif()
|
||||
|
@@ -64,7 +64,7 @@ typedef struct rbConstraint rbConstraint;
|
||||
/* Setup ---------------------------- */
|
||||
|
||||
/* Create a new dynamics world instance */
|
||||
// TODO: add args to set the type of constraint solvers, etc.
|
||||
/* TODO: add args to set the type of constraint solvers, etc. */
|
||||
rbDynamicsWorld *RB_dworld_new(const float gravity[3]);
|
||||
|
||||
/* Delete the given dynamics world, and free any extra data it may require */
|
||||
|
Submodule release/datafiles/locale updated: 4833954c0a...62e82958a7
@@ -113,7 +113,7 @@ const UserDef U_default = {
|
||||
.gp_eraser = 25,
|
||||
.gp_settings = 0,
|
||||
|
||||
/** Initialized by: #BKE_studiolight_default . */
|
||||
/** Initialized by: #BKE_studiolight_default. */
|
||||
.light_param = {{0}},
|
||||
.light_ambient = {0, 0, 0},
|
||||
|
||||
|
Submodule release/scripts/addons updated: f86f25e622...1adb56d8b0
Submodule release/scripts/addons_contrib updated: 5a82baad9f...788441f293
@@ -71,7 +71,7 @@ def rtl_process_po(args, settings):
|
||||
po.write(kind="PO", dest=args.dst)
|
||||
|
||||
|
||||
def language_menu(_args, settings):
|
||||
def language_menu(args, settings):
|
||||
# 'DEFAULT' and en_US are always valid, fully-translated "languages"!
|
||||
stats = {"DEFAULT": 1.0, "en_US": 1.0}
|
||||
|
||||
|
@@ -77,7 +77,7 @@ class NodeItem:
|
||||
else:
|
||||
return bpy.app.translations.contexts.default
|
||||
|
||||
# NB: is a staticmethod because called with an explicit self argument
|
||||
# NOTE: is a staticmethod because called with an explicit self argument
|
||||
# NodeItemCustom sets this as a variable attribute in __init__
|
||||
@staticmethod
|
||||
def draw(self, layout, _context):
|
||||
|
@@ -81,7 +81,10 @@ class NewGeometryNodeTreeAssign(Operator):
|
||||
return geometry_modifier_poll(context)
|
||||
|
||||
def execute(self, context):
|
||||
modifier = context.object.modifiers.active
|
||||
if context.area.type == 'PROPERTIES':
|
||||
modifier = context.modifier
|
||||
else:
|
||||
modifier = context.object.modifiers.active
|
||||
|
||||
if not modifier:
|
||||
return {'CANCELLED'}
|
||||
|
@@ -60,17 +60,22 @@ class CopyRigidbodySettings(Operator):
|
||||
|
||||
def execute(self, context):
|
||||
obj_act = context.object
|
||||
view_layer = context.view_layer
|
||||
|
||||
# deselect all but mesh objects
|
||||
# Deselect all non mesh objects and objects that
|
||||
# already have a rigid body attached.
|
||||
rb_objects = []
|
||||
for o in context.selected_objects:
|
||||
if o.type != 'MESH':
|
||||
if o.type != 'MESH' or o.rigid_body is not None:
|
||||
o.select_set(False)
|
||||
elif o.rigid_body is None:
|
||||
# Add rigidbody to object!
|
||||
view_layer.objects.active = o
|
||||
bpy.ops.rigidbody.object_add()
|
||||
view_layer.objects.active = obj_act
|
||||
if o.rigid_body is not None:
|
||||
rb_objects.append(o)
|
||||
|
||||
bpy.ops.rigidbody.objects_add()
|
||||
|
||||
# Ensure that the rigid body objects
|
||||
# we've de-selected are selected again.
|
||||
for o in rb_objects:
|
||||
o.select_set(True)
|
||||
|
||||
objects = context.selected_objects
|
||||
if objects:
|
||||
|
@@ -86,12 +86,15 @@ class COLLECTION_PT_lineart_collection(CollectionButtonsPanel, Panel):
|
||||
row = layout.row()
|
||||
row.prop(collection, "lineart_usage")
|
||||
|
||||
layout.prop(collection, "lineart_use_intersection_mask")
|
||||
layout.prop(collection, "lineart_use_intersection_mask", text="Collection Mask")
|
||||
|
||||
row = layout.row(align=True, heading="Masks")
|
||||
row.active = collection.lineart_use_intersection_mask
|
||||
col = layout.column(align=True)
|
||||
col.active = collection.lineart_use_intersection_mask
|
||||
row = col.row(align=True, heading="Masks")
|
||||
for i in range(8):
|
||||
row.prop(collection, "lineart_intersection_mask", index=i, text=str(i), toggle=True)
|
||||
row.prop(collection, "lineart_intersection_mask", index=i, text=" ", toggle=True)
|
||||
if i == 3:
|
||||
row = col.row(align=True)
|
||||
|
||||
|
||||
classes = (
|
||||
|
@@ -291,18 +291,18 @@ class MATERIAL_PT_lineart(MaterialButtonsPanel, Panel):
|
||||
mat = context.material
|
||||
lineart = mat.lineart
|
||||
|
||||
layout.prop(lineart, "use_material_mask")
|
||||
layout.prop(lineart, "use_material_mask", text="Material Mask")
|
||||
|
||||
row = layout.row(align=True, heading="Masks")
|
||||
row.active = lineart.use_material_mask
|
||||
col = layout.column(align=True)
|
||||
col.active = lineart.use_material_mask
|
||||
row = col.row(align=True, heading="Masks")
|
||||
for i in range(8):
|
||||
row.prop(lineart, "use_material_mask_bits", text=str(i), index=i, toggle=True)
|
||||
row.prop(lineart, "use_material_mask_bits", text=" ", index=i, toggle=True)
|
||||
if i == 3:
|
||||
row = col.row(align=True)
|
||||
|
||||
row = layout.row(align=True, heading="Custom Occlusion")
|
||||
row.prop(lineart, "use_mat_occlusion", text="")
|
||||
sub = row.row(align=False)
|
||||
sub.active = lineart.use_mat_occlusion
|
||||
sub.prop(lineart, "mat_occlusion", slider=True, text="Levels")
|
||||
row.prop(lineart, "mat_occlusion", text="Levels")
|
||||
|
||||
|
||||
classes = (
|
||||
|
@@ -734,11 +734,9 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel):
|
||||
|
||||
col = flow.column()
|
||||
col.prop(domain, "noise_scale", text="Upres Factor")
|
||||
# TODO (sebbas): Mantaflow only supports wavelet noise. Maybe get rid of noise type field.
|
||||
col.prop(domain, "noise_type", text="Noise Method")
|
||||
col.prop(domain, "noise_strength", text="Strength")
|
||||
|
||||
col = flow.column()
|
||||
col.prop(domain, "noise_strength", text="Strength")
|
||||
col.prop(domain, "noise_pos_scale", text="Scale")
|
||||
col.prop(domain, "noise_time_anim", text="Time")
|
||||
|
||||
|
@@ -1156,14 +1156,19 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
|
||||
flow.prop(strip, "use_only_boost")
|
||||
|
||||
elif strip_type == 'SPEED':
|
||||
layout.prop(strip, "use_default_fade", text="Stretch to Input Strip Length")
|
||||
if not strip.use_default_fade:
|
||||
layout.prop(strip, "use_as_speed")
|
||||
if strip.use_as_speed:
|
||||
layout.prop(strip, "speed_factor")
|
||||
else:
|
||||
layout.prop(strip, "speed_factor", text="Frame Number")
|
||||
layout.prop(strip, "use_scale_to_length")
|
||||
col = layout.column(align=True)
|
||||
col.prop(strip, "speed_control", text="Speed Control")
|
||||
if strip.speed_control == "MULTIPLY":
|
||||
col.prop(strip, "speed_factor", text=" ")
|
||||
elif strip.speed_control == "LENGTH":
|
||||
col.prop(strip, "speed_length", text=" ")
|
||||
elif strip.speed_control == "FRAME_NUMBER":
|
||||
col.prop(strip, "speed_frame_number", text=" ")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.enabled = strip.speed_control != "STRETCH"
|
||||
row = layout.row(align=True, heading="Interpolation")
|
||||
row.prop(strip, "use_frame_interpolate", text="")
|
||||
|
||||
elif strip_type == 'TRANSFORM':
|
||||
col = layout.column()
|
||||
@@ -1233,11 +1238,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
|
||||
layout.prop(strip, "wrap_width", text="Wrap Width")
|
||||
|
||||
col = layout.column(align=True)
|
||||
if strip_type == 'SPEED':
|
||||
col.prop(strip, "multiply_speed")
|
||||
col.prop(strip, "use_frame_interpolate")
|
||||
|
||||
elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
|
||||
if strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
|
||||
col.prop(strip, "use_default_fade", text="Default Fade")
|
||||
if not strip.use_default_fade:
|
||||
col.prop(strip, "effect_fader", text="Effect Fader")
|
||||
@@ -2293,8 +2294,8 @@ class SEQUENCER_PT_snapping(Panel):
|
||||
col.prop(sequencer_tool_settings, "snap_ignore_muted", text="Muted Strips")
|
||||
col.prop(sequencer_tool_settings, "snap_ignore_sound", text="Sound Strips")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(sequencer_tool_settings, "use_snap_current_frame_to_strips")
|
||||
col = layout.column(heading="Current Frame", align=True)
|
||||
col.prop(sequencer_tool_settings, "use_snap_current_frame_to_strips", text="Snap to Strips")
|
||||
|
||||
|
||||
classes = (
|
||||
|
@@ -493,6 +493,7 @@ geometry_node_categories = [
|
||||
NodeItem("GeometryNodeAttributeRemove"),
|
||||
NodeItem("GeometryNodeAttributeMapRange"),
|
||||
NodeItem("GeometryNodeAttributeTransfer"),
|
||||
NodeItem("GeometryNodeAttributeRangeQuery"),
|
||||
]),
|
||||
GeometryNodeCategory("GEO_COLOR", "Color", items=[
|
||||
NodeItem("ShaderNodeRGBCurve"),
|
||||
@@ -510,6 +511,7 @@ geometry_node_categories = [
|
||||
NodeItem("GeometryNodeCurveTrim"),
|
||||
NodeItem("GeometryNodeCurveLength"),
|
||||
NodeItem("GeometryNodeCurveReverse"),
|
||||
NodeItem("GeometryNodeCurveSetHandles"),
|
||||
]),
|
||||
GeometryNodeCategory("GEO_PRIMITIVES_CURVE", "Curve Primitives", items=[
|
||||
NodeItem("GeometryNodeCurvePrimitiveLine"),
|
||||
|
@@ -147,7 +147,7 @@ node_categories = [
|
||||
MyNodeCategory('OTHERNODES', "Other Nodes", items=[
|
||||
# the node item can have additional settings,
|
||||
# which are applied to new nodes
|
||||
# NB: settings values are stored as string expressions,
|
||||
# NOTE: settings values are stored as string expressions,
|
||||
# for this reason they should be converted to strings using repr()
|
||||
NodeItem("CustomNodeType", label="Node A", settings={
|
||||
"my_string_prop": repr("Lorem ipsum dolor sit amet"),
|
||||
|
@@ -158,7 +158,7 @@ struct DerivedMesh {
|
||||
int (*getNumPolys)(DerivedMesh *dm);
|
||||
|
||||
/** Copy a single vert/edge/tessellated face from the derived mesh into
|
||||
* ``*r_{vert/edge/face}``. note that the current implementation
|
||||
* `*r_{vert/edge/face}`. note that the current implementation
|
||||
* of this function can be quite slow, iterating over all
|
||||
* elements (editmesh)
|
||||
*/
|
||||
|
35
source/blender/blenkernel/BKE_action.hh
Normal file
35
source/blender/blenkernel/BKE_action.hh
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
# error This is a C++ only header.
|
||||
#endif
|
||||
|
||||
#include "BLI_function_ref.hh"
|
||||
|
||||
struct bAction;
|
||||
struct FCurve;
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
using FoundFCurveCallback = blender::FunctionRef<void(FCurve *fcurve, const char *bone_name)>;
|
||||
void BKE_action_find_fcurves_with_bones(const bAction *action, FoundFCurveCallback callback);
|
||||
|
||||
}; // namespace blender::bke
|
48
source/blender/blenkernel/BKE_armature.hh
Normal file
48
source/blender/blenkernel/BKE_armature.hh
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
# error This is a C++ only header.
|
||||
#endif
|
||||
|
||||
#include "BKE_armature.h"
|
||||
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_set.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
struct SelectedBonesResult {
|
||||
bool all_bones_selected = true;
|
||||
bool no_bones_selected = true;
|
||||
};
|
||||
|
||||
using SelectedBoneCallback = blender::FunctionRef<void(Bone *bone)>;
|
||||
SelectedBonesResult BKE_armature_find_selected_bones(const bArmature *armature,
|
||||
SelectedBoneCallback callback);
|
||||
|
||||
using BoneNameSet = blender::Set<std::string>;
|
||||
/**
|
||||
* Return a set of names of the selected bones. An empty set means "ignore bone
|
||||
* selection", which either means all bones are selected, or none are.
|
||||
*/
|
||||
BoneNameSet BKE_armature_find_selected_bone_names(const bArmature *armature);
|
||||
|
||||
}; // namespace blender::bke
|
@@ -39,7 +39,7 @@ extern "C" {
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 12
|
||||
#define BLENDER_FILE_SUBVERSION 13
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
@@ -39,14 +39,14 @@ struct Scene;
|
||||
|
||||
#define DO_INLINE MALWAYS_INLINE
|
||||
|
||||
/* goal defines */
|
||||
/* Goal defines. */
|
||||
#define SOFTGOALSNAP 0.999f
|
||||
|
||||
/* This is approximately the smallest number that can be
|
||||
* represented by a float, given its precision. */
|
||||
#define ALMOST_ZERO FLT_EPSILON
|
||||
|
||||
/* Bits to or into the ClothVertex.flags. */
|
||||
/* Bits to or into the #ClothVertex.flags. */
|
||||
typedef enum eClothVertexFlag {
|
||||
CLOTH_VERT_FLAG_PINNED = (1 << 0),
|
||||
CLOTH_VERT_FLAG_NOSELFCOLL = (1 << 1), /* vertex NOT used for self collisions */
|
||||
@@ -150,7 +150,7 @@ typedef struct ClothSpring {
|
||||
float target[3];
|
||||
} ClothSpring;
|
||||
|
||||
// some macro enhancements for vector treatment
|
||||
/* Some macro enhancements for vector treatment. */
|
||||
#define VECSUBADDSS(v1, v2, aS, v3, bS) \
|
||||
{ \
|
||||
*(v1) -= *(v2)*aS + *(v3)*bS; \
|
||||
@@ -211,9 +211,8 @@ typedef enum {
|
||||
CLOTH_SPRING_FLAG_NEEDED = (1 << 2), /* Springs has values to be applied. */
|
||||
} CLOTH_SPRINGS_FLAGS;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// collision.c
|
||||
////////////////////////////////////////////////
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* collision.c */
|
||||
|
||||
struct CollPair;
|
||||
|
||||
@@ -225,20 +224,17 @@ typedef struct ColliderContacts {
|
||||
int totcollisions;
|
||||
} ColliderContacts;
|
||||
|
||||
// needed for implicit.c
|
||||
/* needed for implicit.c */
|
||||
int cloth_bvh_collision(struct Depsgraph *depsgraph,
|
||||
struct Object *ob,
|
||||
struct ClothModifierData *clmd,
|
||||
float step,
|
||||
float dt);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* cloth.c */
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// cloth.c
|
||||
////////////////////////////////////////////////
|
||||
|
||||
// needed for modifier.c
|
||||
/* Needed for modifier.c */
|
||||
void cloth_free_modifier_extern(struct ClothModifierData *clmd);
|
||||
void cloth_free_modifier(struct ClothModifierData *clmd);
|
||||
void clothModifier_do(struct ClothModifierData *clmd,
|
||||
@@ -250,18 +246,16 @@ void clothModifier_do(struct ClothModifierData *clmd,
|
||||
|
||||
int cloth_uses_vgroup(struct ClothModifierData *clmd);
|
||||
|
||||
// needed for collision.c
|
||||
/* Needed for collision.c */
|
||||
void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving, bool self);
|
||||
|
||||
// needed for button_object.c
|
||||
/* Needed for button_object.c */
|
||||
void cloth_clear_cache(struct Object *ob, struct ClothModifierData *clmd, float framenr);
|
||||
|
||||
void cloth_parallel_transport_hair_frame(float mat[3][3],
|
||||
const float dir_old[3],
|
||||
const float dir_new[3]);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -501,7 +501,7 @@ enum {
|
||||
CD_FAKE = 1 << 8,
|
||||
|
||||
/* Vertices. */
|
||||
CD_FAKE_MDEFORMVERT = CD_FAKE | CD_MDEFORMVERT, /* *sigh* due to how vgroups are stored :( . */
|
||||
CD_FAKE_MDEFORMVERT = CD_FAKE | CD_MDEFORMVERT, /* *sigh* due to how vgroups are stored :(. */
|
||||
CD_FAKE_SHAPEKEY = CD_FAKE |
|
||||
CD_SHAPEKEY, /* Not available as real CD layer in non-bmesh context. */
|
||||
|
||||
|
@@ -98,6 +98,9 @@ struct LayerCollection *BKE_layer_collection_from_index(struct ViewLayer *view_l
|
||||
const int index);
|
||||
int BKE_layer_collection_findindex(struct ViewLayer *view_layer, const struct LayerCollection *lc);
|
||||
|
||||
void BKE_layer_collection_resync_forbid(void);
|
||||
void BKE_layer_collection_resync_allow(void);
|
||||
|
||||
void BKE_main_collection_sync(const struct Main *bmain);
|
||||
void BKE_scene_collection_sync(const struct Scene *scene);
|
||||
void BKE_layer_collection_sync(const struct Scene *scene, struct ViewLayer *view_layer);
|
||||
|
@@ -399,6 +399,12 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
|
||||
const char data_type);
|
||||
void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr);
|
||||
void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr);
|
||||
|
||||
void BKE_lnor_spacearr_tls_init(MLoopNorSpaceArray *lnors_spacearr,
|
||||
MLoopNorSpaceArray *lnors_spacearr_tls);
|
||||
void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr,
|
||||
MLoopNorSpaceArray *lnors_spacearr_tls);
|
||||
|
||||
MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr);
|
||||
void BKE_lnor_space_define(MLoopNorSpace *lnor_space,
|
||||
const float lnor[3],
|
||||
|
@@ -41,6 +41,7 @@ void BKE_mesh_foreach_mapped_vert(struct Mesh *mesh,
|
||||
MeshForeachFlag flag);
|
||||
void BKE_mesh_foreach_mapped_edge(
|
||||
struct Mesh *mesh,
|
||||
int tot_edges,
|
||||
void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
|
||||
void *userData);
|
||||
void BKE_mesh_foreach_mapped_loop(struct Mesh *mesh,
|
||||
|
@@ -1465,6 +1465,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
|
||||
#define GEO_NODE_CURVE_ENDPOINTS 1069
|
||||
#define GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL 1070
|
||||
#define GEO_NODE_CURVE_TRIM 1071
|
||||
#define GEO_NODE_CURVE_SET_HANDLES 1072
|
||||
#define GEO_NODE_ATTRIBUTE_RANGE_QUERY 1073
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@@ -306,6 +306,7 @@ class BezierSpline final : public Spline {
|
||||
blender::MutableSpan<HandleType> handle_types_right();
|
||||
blender::Span<blender::float3> handle_positions_right() const;
|
||||
blender::MutableSpan<blender::float3> handle_positions_right();
|
||||
void ensure_auto_handles() const;
|
||||
|
||||
void translate(const blender::float3 &translation) override;
|
||||
void transform(const blender::float4x4 &matrix) override;
|
||||
@@ -353,8 +354,6 @@ class BezierSpline final : public Spline {
|
||||
void correct_end_tangents() const final;
|
||||
void copy_settings(Spline &dst) const final;
|
||||
void copy_data(Spline &dst) const final;
|
||||
|
||||
void ensure_auto_handles() const;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -544,6 +543,7 @@ struct CurveEval {
|
||||
|
||||
blender::Span<SplinePtr> splines() const;
|
||||
blender::MutableSpan<SplinePtr> splines();
|
||||
bool has_spline_with_type(const Spline::Type type) const;
|
||||
|
||||
void resize(const int size);
|
||||
void add_spline(SplinePtr spline);
|
||||
|
@@ -69,6 +69,7 @@ set(SRC
|
||||
intern/CCGSubSurf_util.c
|
||||
intern/DerivedMesh.cc
|
||||
intern/action.c
|
||||
intern/action_bones.cc
|
||||
intern/action_mirror.c
|
||||
intern/addon.c
|
||||
intern/anim_data.c
|
||||
@@ -77,6 +78,7 @@ set(SRC
|
||||
intern/anim_visualization.c
|
||||
intern/appdir.c
|
||||
intern/armature.c
|
||||
intern/armature_selection.cc
|
||||
intern/armature_deform.c
|
||||
intern/armature_pose.cc
|
||||
intern/armature_update.c
|
||||
@@ -287,6 +289,7 @@ set(SRC
|
||||
|
||||
BKE_DerivedMesh.h
|
||||
BKE_action.h
|
||||
BKE_action.hh
|
||||
BKE_addon.h
|
||||
BKE_anim_data.h
|
||||
BKE_anim_path.h
|
||||
@@ -294,6 +297,7 @@ set(SRC
|
||||
BKE_animsys.h
|
||||
BKE_appdir.h
|
||||
BKE_armature.h
|
||||
BKE_armature.hh
|
||||
BKE_asset.h
|
||||
BKE_attribute.h
|
||||
BKE_attribute_access.hh
|
||||
|
48
source/blender/blenkernel/intern/action_bones.cc
Normal file
48
source/blender/blenkernel/intern/action_bones.cc
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BKE_action.hh"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_anim_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
void BKE_action_find_fcurves_with_bones(const bAction *action, FoundFCurveCallback callback)
|
||||
{
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &action->curves) {
|
||||
char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
|
||||
if (!bone_name) {
|
||||
continue;
|
||||
}
|
||||
callback(fcu, bone_name);
|
||||
MEM_freeN(bone_name);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
@@ -1947,7 +1947,7 @@ static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs,
|
||||
return;
|
||||
}
|
||||
default:
|
||||
BLI_assert("Mix mode should've been handled");
|
||||
BLI_assert_msg(0, "Mix mode should've been handled");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1960,7 +1960,7 @@ static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs,
|
||||
return;
|
||||
}
|
||||
default:
|
||||
BLI_assert("Blend mode should've been handled");
|
||||
BLI_assert_msg(0, "Blend mode should've been handled");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2110,7 +2110,7 @@ static void nlaevalchan_blendOrcombine_get_inverted_upper_evalchan(
|
||||
return;
|
||||
}
|
||||
default:
|
||||
BLI_assert("Mix mode should've been handled");
|
||||
BLI_assert_msg(0, "Mix mode should've been handled");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -2123,7 +2123,7 @@ static void nlaevalchan_blendOrcombine_get_inverted_upper_evalchan(
|
||||
return;
|
||||
}
|
||||
default:
|
||||
BLI_assert("Blend mode should've been handled");
|
||||
BLI_assert_msg(0, "Blend mode should've been handled");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -23,8 +23,9 @@
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BKE_action.hh"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_armature.hh"
|
||||
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_set.hh"
|
||||
@@ -36,14 +37,14 @@
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
using namespace blender::bke;
|
||||
|
||||
namespace {
|
||||
using BoneNameSet = blender::Set<std::string>;
|
||||
|
||||
using ActionApplier =
|
||||
blender::FunctionRef<void(PointerRNA *, bAction *, const AnimationEvalContext *)>;
|
||||
|
||||
// Forward declarations.
|
||||
BoneNameSet pose_apply_find_selected_bones(const bArmature *armature, const bPose *pose);
|
||||
/* Forward declarations. */
|
||||
void pose_apply_disable_fcurves_for_unselected_bones(bAction *action,
|
||||
const BoneNameSet &selected_bone_names);
|
||||
void pose_apply_restore_fcurves(bAction *action);
|
||||
@@ -102,7 +103,7 @@ void pose_apply(struct Object *ob,
|
||||
}
|
||||
|
||||
const bArmature *armature = (bArmature *)ob->data;
|
||||
const BoneNameSet selected_bone_names = pose_apply_find_selected_bones(armature, pose);
|
||||
const BoneNameSet selected_bone_names = BKE_armature_find_selected_bone_names(armature);
|
||||
const bool limit_to_selected_bones = !selected_bone_names.is_empty();
|
||||
|
||||
if (limit_to_selected_bones) {
|
||||
@@ -122,30 +123,6 @@ void pose_apply(struct Object *ob,
|
||||
}
|
||||
}
|
||||
|
||||
BoneNameSet pose_apply_find_selected_bones(const bArmature *armature, const bPose *pose)
|
||||
{
|
||||
BoneNameSet selected_bone_names;
|
||||
bool all_bones_selected = true;
|
||||
bool no_bones_selected = true;
|
||||
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
||||
const bool is_selected = PBONE_SELECTED(armature, pchan->bone);
|
||||
all_bones_selected &= is_selected;
|
||||
no_bones_selected &= !is_selected;
|
||||
|
||||
if (is_selected) {
|
||||
/* Bone names are unique, so no need to check for duplicates. */
|
||||
selected_bone_names.add_new(pchan->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* If no bones are selected, act as if all are. */
|
||||
if (all_bones_selected || no_bones_selected) {
|
||||
return BoneNameSet(); /* An empty set means "ignore bone selection". */
|
||||
}
|
||||
return selected_bone_names;
|
||||
}
|
||||
|
||||
void pose_apply_restore_fcurves(bAction *action)
|
||||
{
|
||||
/* TODO(Sybren): Restore the FCurve flags, instead of just erasing the 'disabled' flag. */
|
||||
@@ -157,24 +134,13 @@ void pose_apply_restore_fcurves(bAction *action)
|
||||
void pose_apply_disable_fcurves_for_unselected_bones(bAction *action,
|
||||
const BoneNameSet &selected_bone_names)
|
||||
{
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &action->curves) {
|
||||
if (!fcu->rna_path || !strstr(fcu->rna_path, "pose.bones[")) {
|
||||
continue;
|
||||
auto disable_unselected_fcurve = [&](FCurve *fcu, const char *bone_name) {
|
||||
const bool is_bone_selected = selected_bone_names.contains(bone_name);
|
||||
if (!is_bone_selected) {
|
||||
fcu->flag |= FCURVE_DISABLED;
|
||||
}
|
||||
|
||||
/* Get bone name, and check if this bone is selected. */
|
||||
char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
|
||||
if (!bone_name) {
|
||||
continue;
|
||||
}
|
||||
const bool is_selected = selected_bone_names.contains(bone_name);
|
||||
MEM_freeN(bone_name);
|
||||
if (is_selected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fcu->flag |= FCURVE_DISABLED;
|
||||
}
|
||||
};
|
||||
BKE_action_find_fcurves_with_bones(action, disable_unselected_fcurve);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
78
source/blender/blenkernel/intern/armature_selection.cc
Normal file
78
source/blender/blenkernel/intern/armature_selection.cc
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BKE_armature.hh"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
namespace {
|
||||
|
||||
void find_selected_bones__visit_bone(const bArmature *armature,
|
||||
SelectedBoneCallback callback,
|
||||
SelectedBonesResult &result,
|
||||
Bone *bone)
|
||||
{
|
||||
const bool is_selected = PBONE_SELECTED(armature, bone);
|
||||
result.all_bones_selected &= is_selected;
|
||||
result.no_bones_selected &= !is_selected;
|
||||
|
||||
if (is_selected) {
|
||||
callback(bone);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Bone *, child_bone, &bone->childbase) {
|
||||
find_selected_bones__visit_bone(armature, callback, result, child_bone);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SelectedBonesResult BKE_armature_find_selected_bones(const bArmature *armature,
|
||||
SelectedBoneCallback callback)
|
||||
{
|
||||
SelectedBonesResult result;
|
||||
LISTBASE_FOREACH (Bone *, root_bone, &armature->bonebase) {
|
||||
find_selected_bones__visit_bone(armature, callback, result, root_bone);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BoneNameSet BKE_armature_find_selected_bone_names(const bArmature *armature)
|
||||
{
|
||||
BoneNameSet selected_bone_names;
|
||||
|
||||
/* Iterate over the selected bones to fill the set of bone names. */
|
||||
auto callback = [&](Bone *bone) { selected_bone_names.add(bone->name); };
|
||||
SelectedBonesResult result = BKE_armature_find_selected_bones(armature, callback);
|
||||
|
||||
/* If no bones are selected, act as if all are. */
|
||||
if (result.all_bones_selected || result.no_bones_selected) {
|
||||
return BoneNameSet();
|
||||
}
|
||||
|
||||
return selected_bone_names;
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
@@ -17,10 +17,13 @@
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_armature.hh"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
namespace blender::bke::tests {
|
||||
@@ -157,4 +160,80 @@ TEST(vec_roll_to_mat3_normalized, Rotationmatrix)
|
||||
}
|
||||
}
|
||||
|
||||
class BKE_armature_find_selected_bones_test : public testing::Test {
|
||||
protected:
|
||||
bArmature arm;
|
||||
Bone bone1, bone2, bone3;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
strcpy(bone1.name, "bone1");
|
||||
strcpy(bone2.name, "bone2");
|
||||
strcpy(bone3.name, "bone3");
|
||||
|
||||
arm.bonebase = {nullptr, nullptr};
|
||||
bone1.childbase = {nullptr, nullptr};
|
||||
bone2.childbase = {nullptr, nullptr};
|
||||
bone3.childbase = {nullptr, nullptr};
|
||||
|
||||
BLI_addtail(&arm.bonebase, &bone1); // bone1 is root bone
|
||||
BLI_addtail(&arm.bonebase, &bone2); // bone2 is root bone
|
||||
BLI_addtail(&bone2.childbase, &bone3); // bone3 has bone2 as parent
|
||||
|
||||
// Make sure the armature & its bones are visible, to make them selectable.
|
||||
arm.layer = bone1.layer = bone2.layer = bone3.layer = 1;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(BKE_armature_find_selected_bones_test, some_bones_selected)
|
||||
{
|
||||
bone1.flag = BONE_SELECTED;
|
||||
bone2.flag = 0;
|
||||
bone3.flag = BONE_SELECTED;
|
||||
|
||||
std::vector<Bone *> seen_bones;
|
||||
auto callback = [&](Bone *bone) { seen_bones.push_back(bone); };
|
||||
|
||||
SelectedBonesResult result = BKE_armature_find_selected_bones(&arm, callback);
|
||||
|
||||
ASSERT_EQ(seen_bones.size(), 2) << "Expected 2 selected bones, got " << seen_bones.size();
|
||||
EXPECT_EQ(seen_bones[0], &bone1);
|
||||
EXPECT_EQ(seen_bones[1], &bone3);
|
||||
|
||||
EXPECT_FALSE(result.all_bones_selected); // Bone 2 was not selected.
|
||||
EXPECT_FALSE(result.no_bones_selected); // Bones 1 and 3 were selected.
|
||||
}
|
||||
|
||||
TEST_F(BKE_armature_find_selected_bones_test, no_bones_selected)
|
||||
{
|
||||
bone1.flag = bone2.flag = bone3.flag = 0;
|
||||
|
||||
std::vector<Bone *> seen_bones;
|
||||
auto callback = [&](Bone *bone) { seen_bones.push_back(bone); };
|
||||
|
||||
SelectedBonesResult result = BKE_armature_find_selected_bones(&arm, callback);
|
||||
|
||||
EXPECT_TRUE(seen_bones.empty()) << "Expected no selected bones, got " << seen_bones.size();
|
||||
EXPECT_FALSE(result.all_bones_selected);
|
||||
EXPECT_TRUE(result.no_bones_selected);
|
||||
}
|
||||
|
||||
TEST_F(BKE_armature_find_selected_bones_test, all_bones_selected)
|
||||
{
|
||||
bone1.flag = bone2.flag = bone3.flag = BONE_SELECTED;
|
||||
|
||||
std::vector<Bone *> seen_bones;
|
||||
auto callback = [&](Bone *bone) { seen_bones.push_back(bone); };
|
||||
|
||||
SelectedBonesResult result = BKE_armature_find_selected_bones(&arm, callback);
|
||||
|
||||
ASSERT_EQ(seen_bones.size(), 3) << "Expected 3 selected bones, got " << seen_bones.size();
|
||||
EXPECT_EQ(seen_bones[0], &bone1);
|
||||
EXPECT_EQ(seen_bones[1], &bone2);
|
||||
EXPECT_EQ(seen_bones[2], &bone3);
|
||||
|
||||
EXPECT_TRUE(result.all_bones_selected);
|
||||
EXPECT_FALSE(result.no_bones_selected);
|
||||
}
|
||||
|
||||
} // namespace blender::bke::tests
|
||||
|
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_hair.h"
|
||||
#include "BKE_pointcloud.h"
|
||||
#include "BKE_report.h"
|
||||
@@ -63,14 +64,28 @@ static void get_domains(ID *id, DomainInfo info[ATTR_DOMAIN_NUM])
|
||||
}
|
||||
case ID_ME: {
|
||||
Mesh *mesh = (Mesh *)id;
|
||||
info[ATTR_DOMAIN_POINT].customdata = &mesh->vdata;
|
||||
info[ATTR_DOMAIN_POINT].length = mesh->totvert;
|
||||
info[ATTR_DOMAIN_EDGE].customdata = &mesh->edata;
|
||||
info[ATTR_DOMAIN_EDGE].length = mesh->totedge;
|
||||
info[ATTR_DOMAIN_CORNER].customdata = &mesh->ldata;
|
||||
info[ATTR_DOMAIN_CORNER].length = mesh->totloop;
|
||||
info[ATTR_DOMAIN_FACE].customdata = &mesh->pdata;
|
||||
info[ATTR_DOMAIN_FACE].length = mesh->totpoly;
|
||||
BMEditMesh *em = mesh->edit_mesh;
|
||||
if (em != NULL) {
|
||||
BMesh *bm = em->bm;
|
||||
info[ATTR_DOMAIN_POINT].customdata = &bm->vdata;
|
||||
info[ATTR_DOMAIN_POINT].length = bm->totvert;
|
||||
info[ATTR_DOMAIN_EDGE].customdata = &bm->edata;
|
||||
info[ATTR_DOMAIN_EDGE].length = bm->totedge;
|
||||
info[ATTR_DOMAIN_CORNER].customdata = &bm->ldata;
|
||||
info[ATTR_DOMAIN_CORNER].length = bm->totloop;
|
||||
info[ATTR_DOMAIN_FACE].customdata = &bm->pdata;
|
||||
info[ATTR_DOMAIN_FACE].length = bm->totface;
|
||||
}
|
||||
else {
|
||||
info[ATTR_DOMAIN_POINT].customdata = &mesh->vdata;
|
||||
info[ATTR_DOMAIN_POINT].length = mesh->totvert;
|
||||
info[ATTR_DOMAIN_EDGE].customdata = &mesh->edata;
|
||||
info[ATTR_DOMAIN_EDGE].length = mesh->totedge;
|
||||
info[ATTR_DOMAIN_CORNER].customdata = &mesh->ldata;
|
||||
info[ATTR_DOMAIN_CORNER].length = mesh->totloop;
|
||||
info[ATTR_DOMAIN_FACE].customdata = &mesh->pdata;
|
||||
info[ATTR_DOMAIN_FACE].length = mesh->totpoly;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ID_HA: {
|
||||
@@ -146,7 +161,24 @@ CustomDataLayer *BKE_id_attribute_new(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name);
|
||||
switch (GS(id->name)) {
|
||||
case ID_ME: {
|
||||
Mesh *me = (Mesh *)id;
|
||||
BMEditMesh *em = me->edit_mesh;
|
||||
if (em != NULL) {
|
||||
BM_data_layer_add_named(em->bm, customdata, type, name);
|
||||
}
|
||||
else {
|
||||
CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
CustomData_add_layer_named(customdata, type, CD_DEFAULT, NULL, info[domain].length, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const int index = CustomData_get_named_layer_index(customdata, type, name);
|
||||
return (index == -1) ? NULL : &(customdata->layers[index]);
|
||||
}
|
||||
@@ -168,8 +200,26 @@ bool BKE_id_attribute_remove(ID *id, CustomDataLayer *layer, ReportList *reports
|
||||
return false;
|
||||
}
|
||||
|
||||
const int length = BKE_id_attribute_data_length(id, layer);
|
||||
CustomData_free_layer(customdata, layer->type, length, index);
|
||||
switch (GS(id->name)) {
|
||||
case ID_ME: {
|
||||
Mesh *me = (Mesh *)id;
|
||||
BMEditMesh *em = me->edit_mesh;
|
||||
if (em != NULL) {
|
||||
BM_data_layer_free(em->bm, customdata, layer->type);
|
||||
}
|
||||
else {
|
||||
const int length = BKE_id_attribute_data_length(id, layer);
|
||||
CustomData_free_layer(customdata, layer->type, length, index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const int length = BKE_id_attribute_data_length(id, layer);
|
||||
CustomData_free_layer(customdata, layer->type, length, index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -316,7 +366,7 @@ CustomData *BKE_id_attributes_iterator_next_domain(ID *id, CustomDataLayer *laye
|
||||
|
||||
for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
|
||||
CustomData *customdata = info[domain].customdata;
|
||||
if (customdata && customdata->layers) {
|
||||
if (customdata && customdata->layers && customdata->totlayer) {
|
||||
if (customdata->layers == layers) {
|
||||
use_next = true;
|
||||
}
|
||||
|
@@ -231,7 +231,7 @@ static bool rule_avoid_collision(BoidRule *rule,
|
||||
int n, neighbors = 0, nearest = 0;
|
||||
bool ret = 0;
|
||||
|
||||
// check deflector objects first
|
||||
/* Check deflector objects first. */
|
||||
if (acbr->options & BRULE_ACOLL_WITH_DEFLECTORS && bbd->sim->colliders) {
|
||||
ParticleCollision col;
|
||||
BVHTreeRayHit hit;
|
||||
@@ -293,7 +293,7 @@ static bool rule_avoid_collision(BoidRule *rule,
|
||||
}
|
||||
}
|
||||
|
||||
// check boids in own system
|
||||
/* Check boids in own system. */
|
||||
if (acbr->options & BRULE_ACOLL_WITH_BOIDS) {
|
||||
neighbors = BLI_kdtree_3d_range_search_with_len_squared_cb(bbd->sim->psys->tree,
|
||||
pa->prev_state.co,
|
||||
@@ -823,11 +823,13 @@ static boid_rule_cb boid_rules[] = {
|
||||
rule_follow_leader,
|
||||
rule_average_speed,
|
||||
rule_fight,
|
||||
// rule_help,
|
||||
// rule_protect,
|
||||
// rule_hide,
|
||||
// rule_follow_path,
|
||||
// rule_follow_wall,
|
||||
#if 0
|
||||
rule_help,
|
||||
rule_protect,
|
||||
rule_hide,
|
||||
rule_follow_path,
|
||||
rule_follow_wall,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *pa)
|
||||
@@ -1069,11 +1071,13 @@ static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa)
|
||||
|
||||
return state;
|
||||
}
|
||||
// static int boid_condition_is_true(BoidCondition *cond)
|
||||
//{
|
||||
// /* TODO */
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
#if 0 /* TODO */
|
||||
static int boid_condition_is_true(BoidCondition *cond)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* determines the velocity the boid wants to have */
|
||||
void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
|
||||
@@ -1085,7 +1089,6 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
|
||||
BoidParticle *bpa = pa->boid;
|
||||
ParticleSystem *psys = bbd->sim->psys;
|
||||
int rand;
|
||||
// BoidCondition *cond;
|
||||
|
||||
if (bpa->data.health <= 0.0f) {
|
||||
pa->alive = PARS_DYING;
|
||||
@@ -1093,15 +1096,17 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
|
||||
return;
|
||||
}
|
||||
|
||||
// planned for near future
|
||||
// cond = state->conditions.first;
|
||||
// for (; cond; cond=cond->next) {
|
||||
// if (boid_condition_is_true(cond)) {
|
||||
// pa->boid->state_id = cond->state_id;
|
||||
// state = get_boid_state(boids, pa);
|
||||
// break; /* only first true condition is used */
|
||||
// }
|
||||
//}
|
||||
/* Planned for near future. */
|
||||
#if 0
|
||||
BoidCondition *cond = state->conditions.first;
|
||||
for (; cond; cond = cond->next) {
|
||||
if (boid_condition_is_true(cond)) {
|
||||
pa->boid->state_id = cond->state_id;
|
||||
state = get_boid_state(boids, pa);
|
||||
break; /* only first true condition is used */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
zero_v3(bbd->wanted_co);
|
||||
bbd->wanted_speed = 0.0f;
|
||||
@@ -1507,20 +1512,22 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
|
||||
}
|
||||
case eBoidMode_Climbing: {
|
||||
boid_climb(boids, pa, ground_co, ground_nor);
|
||||
// float nor[3];
|
||||
// copy_v3_v3(nor, ground_nor);
|
||||
#if 0
|
||||
float nor[3];
|
||||
copy_v3_v3(nor, ground_nor);
|
||||
|
||||
///* gather apparent gravity to r_ve */
|
||||
// madd_v3_v3fl(pa->r_ve, ground_nor, -1.0);
|
||||
// normalize_v3(pa->r_ve);
|
||||
/* Gather apparent gravity to r_ve. */
|
||||
madd_v3_v3fl(pa->r_ve, ground_nor, -1.0);
|
||||
normalize_v3(pa->r_ve);
|
||||
|
||||
///* raise boid it's size from surface */
|
||||
// mul_v3_fl(nor, pa->size * boids->height);
|
||||
// add_v3_v3v3(pa->state.co, ground_co, nor);
|
||||
/* Raise boid it's size from surface. */
|
||||
mul_v3_fl(nor, pa->size * boids->height);
|
||||
add_v3_v3v3(pa->state.co, ground_co, nor);
|
||||
|
||||
///* remove normal component from velocity */
|
||||
// project_v3_v3v3(v, pa->state.vel, ground_nor);
|
||||
// sub_v3_v3v3(pa->state.vel, pa->state.vel, v);
|
||||
/* Remove normal component from velocity. */
|
||||
project_v3_v3v3(v, pa->state.vel, ground_nor);
|
||||
sub_v3_v3v3(pa->state.vel, pa->state.vel, v);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case eBoidMode_OnLand: {
|
||||
|
@@ -48,6 +48,22 @@ blender::MutableSpan<SplinePtr> CurveEval::splines()
|
||||
return splines_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \return True if the curve contains a spline with the given type.
|
||||
*
|
||||
* \note If you are looping over all of the splines in the same scope anyway,
|
||||
* it's better to avoid calling this function, in case there are many splines.
|
||||
*/
|
||||
bool CurveEval::has_spline_with_type(const Spline::Type type) const
|
||||
{
|
||||
for (const SplinePtr &spline : this->splines()) {
|
||||
if (spline->type() == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CurveEval::resize(const int size)
|
||||
{
|
||||
splines_.resize(size);
|
||||
|
@@ -306,7 +306,7 @@ const float (*BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph
|
||||
}
|
||||
else if ((em->mesh_eval_final != NULL) &&
|
||||
(em->mesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
|
||||
/* If this is an edit-mesh type, leave NULL as we can use the vertex coords. . */
|
||||
/* If this is an edit-mesh type, leave NULL as we can use the vertex coords. */
|
||||
}
|
||||
else {
|
||||
/* Constructive modifiers have been used, we need to allocate coordinates. */
|
||||
|
@@ -547,7 +547,7 @@ static float eff_calc_visibility(ListBase *colliders,
|
||||
return visibility;
|
||||
}
|
||||
|
||||
// noise function for wind e.g.
|
||||
/* Noise function for wind e.g. */
|
||||
static float wind_func(struct RNG *rng, float strength)
|
||||
{
|
||||
int random = (BLI_rng_get_int(rng) + 1) % 128; /* max 2357 */
|
||||
|
@@ -918,7 +918,7 @@ void BKE_fcurve_active_keyframe_set(FCurve *fcu, const BezTriple *active_bezt)
|
||||
}
|
||||
|
||||
/* The active keyframe should always be selected. */
|
||||
BLI_assert(BEZT_ISSEL_ANY(active_bezt) || !"active keyframe must be selected");
|
||||
BLI_assert_msg(BEZT_ISSEL_ANY(active_bezt), "active keyframe must be selected");
|
||||
|
||||
fcu->active_keyframe_index = (int)offset;
|
||||
}
|
||||
|
@@ -1545,7 +1545,7 @@ static void emit_from_particles(Object *flow_ob,
|
||||
float dt)
|
||||
{
|
||||
if (ffs && ffs->psys && ffs->psys->part &&
|
||||
ELEM(ffs->psys->part->type, PART_EMITTER, PART_FLUID)) // is particle system selected
|
||||
ELEM(ffs->psys->part->type, PART_EMITTER, PART_FLUID)) /* Is particle system selected. */
|
||||
{
|
||||
ParticleSimulationData sim;
|
||||
ParticleSystem *psys = ffs->psys;
|
||||
@@ -5005,7 +5005,6 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
|
||||
tfds->noise_pos_scale = fds->noise_pos_scale;
|
||||
tfds->noise_time_anim = fds->noise_time_anim;
|
||||
tfds->noise_scale = fds->noise_scale;
|
||||
tfds->noise_type = fds->noise_type;
|
||||
|
||||
/* liquid domain options */
|
||||
tfds->flip_ratio = fds->flip_ratio;
|
||||
|
@@ -854,17 +854,9 @@ class PositionAttributeProvider final : public BuiltinPointAttributeProvider<flo
|
||||
return {};
|
||||
}
|
||||
|
||||
bool curve_has_bezier_spline = false;
|
||||
for (SplinePtr &spline : curve->splines()) {
|
||||
if (spline->type() == Spline::Type::Bezier) {
|
||||
curve_has_bezier_spline = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the regular position virtual array when there aren't any Bezier splines
|
||||
* to avoid the overhead of checking the spline type for every point. */
|
||||
if (!curve_has_bezier_spline) {
|
||||
if (!curve->has_spline_with_type(Spline::Type::Bezier)) {
|
||||
return BuiltinPointAttributeProvider<float3>::try_get_for_write(component);
|
||||
}
|
||||
|
||||
|
@@ -667,7 +667,7 @@ void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
|
||||
BKE_previewimg_finish(prv, i);
|
||||
}
|
||||
else {
|
||||
/* Only for old files that didn't write the flag . */
|
||||
/* Only for old files that didn't write the flag. */
|
||||
prv->flag[i] |= PRV_UNFINISHED;
|
||||
}
|
||||
}
|
||||
|
@@ -135,8 +135,8 @@ static void imbuf_save_post(ImBuf *ibuf, ImBuf *colormanaged_ibuf)
|
||||
|
||||
/**
|
||||
* \return success.
|
||||
* \note ``ima->filepath`` and ``ibuf->name`` should end up the same.
|
||||
* \note for multiview the first ``ibuf`` is important to get the settings.
|
||||
* \note `ima->filepath` and `ibuf->name` should end up the same.
|
||||
* \note for multi-view the first `ibuf` is important to get the settings.
|
||||
*/
|
||||
static bool image_save_single(ReportList *reports,
|
||||
Image *ima,
|
||||
|
@@ -737,6 +737,35 @@ int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection
|
||||
* in at least one layer collection. That list is also synchronized here, and
|
||||
* stores state like selection. */
|
||||
|
||||
/* This API allows to temporarily forbid resync of LayerCollections.
|
||||
*
|
||||
* This can greatly improve performances in cases where those functions get
|
||||
* called a lot (e.g. during massive remappings of IDs).
|
||||
*
|
||||
* Usage of these should be done very carefully though. In particular, calling
|
||||
* code must ensures it resync LayerCollections before any UI/Eevnt loop
|
||||
* handling can happen.
|
||||
*
|
||||
* WARNING: This is not threadsafe at all, only use from main thread.
|
||||
*
|
||||
* NOTE: This is a quick and safe band-aid around the long-known issue
|
||||
* regarding this resync process.
|
||||
* Proper fix would be to make resync itself lazy, i.e. only happen
|
||||
* when actually needed.
|
||||
* See also T73411.
|
||||
*/
|
||||
static bool no_resync = false;
|
||||
|
||||
void BKE_layer_collection_resync_forbid(void)
|
||||
{
|
||||
no_resync = true;
|
||||
}
|
||||
|
||||
void BKE_layer_collection_resync_allow(void)
|
||||
{
|
||||
no_resync = false;
|
||||
}
|
||||
|
||||
static void layer_collection_objects_sync(ViewLayer *view_layer,
|
||||
LayerCollection *layer,
|
||||
ListBase *r_lb_new_object_bases,
|
||||
@@ -933,6 +962,10 @@ static void layer_collection_sync(ViewLayer *view_layer,
|
||||
*/
|
||||
void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
|
||||
{
|
||||
if (no_resync) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!scene->master_collection) {
|
||||
/* Happens for old files that don't have versioning applied yet. */
|
||||
return;
|
||||
@@ -997,6 +1030,10 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
|
||||
|
||||
void BKE_scene_collection_sync(const Scene *scene)
|
||||
{
|
||||
if (no_resync) {
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
|
||||
BKE_layer_collection_sync(scene, view_layer);
|
||||
}
|
||||
@@ -1004,6 +1041,10 @@ void BKE_scene_collection_sync(const Scene *scene)
|
||||
|
||||
void BKE_main_collection_sync(const Main *bmain)
|
||||
{
|
||||
if (no_resync) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: if a single collection changed, figure out which
|
||||
* scenes it belongs to and only update those. */
|
||||
|
||||
@@ -1018,6 +1059,10 @@ void BKE_main_collection_sync(const Main *bmain)
|
||||
|
||||
void BKE_main_collection_sync_remap(const Main *bmain)
|
||||
{
|
||||
if (no_resync) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* On remapping of object or collection pointers free caches. */
|
||||
/* TODO: try to make this faster */
|
||||
|
||||
@@ -1237,7 +1282,7 @@ void BKE_layer_collection_isolate_global(Scene *scene,
|
||||
bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE_VIEW_LAYER);
|
||||
|
||||
if (!extend) {
|
||||
/* Hide all collections . */
|
||||
/* Hide all collections. */
|
||||
LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
|
||||
layer_collection_flag_set_recursive(lc_iter, LAYER_COLLECTION_HIDE);
|
||||
}
|
||||
@@ -1320,6 +1365,10 @@ static void layer_collection_local_sync(ViewLayer *view_layer,
|
||||
|
||||
void BKE_layer_collection_local_sync(ViewLayer *view_layer, const View3D *v3d)
|
||||
{
|
||||
if (no_resync) {
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned short local_collections_uuid = v3d->local_collections_uuid;
|
||||
|
||||
/* Reset flags and set the bases visible by default. */
|
||||
@@ -1337,6 +1386,10 @@ void BKE_layer_collection_local_sync(ViewLayer *view_layer, const View3D *v3d)
|
||||
*/
|
||||
void BKE_layer_collection_local_sync_all(const Main *bmain)
|
||||
{
|
||||
if (no_resync) {
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
|
||||
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
||||
|
@@ -1722,6 +1722,11 @@ void BKE_lib_override_library_main_resync(Main *bmain,
|
||||
COLLECTION_RESTRICT_RENDER;
|
||||
}
|
||||
|
||||
/* Necessary to improve performances, and prevent layers matching override sub-collections to be
|
||||
* lost when re-syncing the parent override collection.
|
||||
* Ref. T73411. */
|
||||
BKE_layer_collection_resync_forbid();
|
||||
|
||||
int library_indirect_level = lib_override_libraries_index_define(bmain);
|
||||
while (library_indirect_level >= 0) {
|
||||
/* Update overrides from each indirect level separately. */
|
||||
@@ -1734,6 +1739,8 @@ void BKE_lib_override_library_main_resync(Main *bmain,
|
||||
library_indirect_level--;
|
||||
}
|
||||
|
||||
BKE_layer_collection_resync_allow();
|
||||
|
||||
/* Essentially ensures that potentially new overrides of new objects will be instantiated. */
|
||||
lib_override_library_create_post_process(
|
||||
bmain, scene, view_layer, NULL, NULL, override_resync_residual_storage, true);
|
||||
|
@@ -49,9 +49,9 @@
|
||||
* \{ */
|
||||
|
||||
struct IDNameLib_Key {
|
||||
/** ``ID.name + 2``: without the ID type prefix, since each id type gets its own 'map' */
|
||||
/** `ID.name + 2`: without the ID type prefix, since each id type gets its own 'map'. */
|
||||
const char *name;
|
||||
/** ``ID.lib``: */
|
||||
/** `ID.lib`: */
|
||||
const Library *lib;
|
||||
};
|
||||
|
||||
|
@@ -305,7 +305,7 @@ static void build_bvh_spatial(PROCESS *process,
|
||||
|
||||
/**
|
||||
* Computes density from given metaball at given position.
|
||||
* Metaball equation is: ``(1 - r^2 / R^2)^3 * s``
|
||||
* Metaball equation is: `(1 - r^2 / R^2)^3 * s`
|
||||
*
|
||||
* r = distance from center
|
||||
* R = metaball radius
|
||||
|
@@ -1874,6 +1874,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac
|
||||
}
|
||||
|
||||
mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
|
||||
mesh->runtime.cd_dirty_poly &= ~CD_MASK_NORMAL;
|
||||
mesh->runtime.cd_dirty_loop &= ~CD_MASK_NORMAL;
|
||||
}
|
||||
|
||||
void BKE_mesh_calc_normals_split(Mesh *mesh)
|
||||
|
@@ -97,6 +97,8 @@ class MeshesToIMeshInfo {
|
||||
/* Transformation matrix to transform a coordinate in the corresponding
|
||||
* Mesh to the local space of the first Mesh. */
|
||||
Array<float4x4> to_target_transform;
|
||||
/* For each input mesh, whether or not their transform is negative. */
|
||||
Array<bool> has_negative_transform;
|
||||
/* For each input mesh, how to remap the material slot numbers to
|
||||
* the material slots in the first mesh. */
|
||||
Span<Array<short>> material_remaps;
|
||||
@@ -277,6 +279,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
|
||||
r_info->mesh_edge_offset = Array<int>(nmeshes);
|
||||
r_info->mesh_poly_offset = Array<int>(nmeshes);
|
||||
r_info->to_target_transform = Array<float4x4>(nmeshes);
|
||||
r_info->has_negative_transform = Array<bool>(nmeshes);
|
||||
r_info->material_remaps = material_remaps;
|
||||
int v = 0;
|
||||
int e = 0;
|
||||
@@ -309,6 +312,12 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
|
||||
const float4x4 objn_mat = (obmats[mi] == nullptr) ? float4x4::identity() :
|
||||
clean_obmat(*obmats[mi]);
|
||||
r_info->to_target_transform[mi] = inv_target_mat * objn_mat;
|
||||
r_info->has_negative_transform[mi] = objn_mat.is_negative();
|
||||
|
||||
/* All meshes 1 and up will be transformed into the local space of operand 0.
|
||||
* Historical behavior of the modifier has been to flip the faces of any meshes
|
||||
* that would have a negative transform if you do that. */
|
||||
bool need_face_flip = r_info->has_negative_transform[mi] != r_info->has_negative_transform[0];
|
||||
|
||||
Vector<Vert *> verts(me->totvert);
|
||||
Span<MVert> mverts = Span(me->mvert, me->totvert);
|
||||
@@ -346,14 +355,21 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
|
||||
|
||||
for (const MPoly &poly : Span(me->mpoly, me->totpoly)) {
|
||||
int flen = poly.totloop;
|
||||
face_vert.clear();
|
||||
face_edge_orig.clear();
|
||||
face_vert.resize(flen);
|
||||
face_edge_orig.resize(flen);
|
||||
const MLoop *l = &me->mloop[poly.loopstart];
|
||||
for (int i = 0; i < flen; ++i) {
|
||||
int mverti = r_info->mesh_vert_offset[mi] + l->v;
|
||||
const Vert *fv = r_info->mesh_to_imesh_vert[mverti];
|
||||
face_vert.append(fv);
|
||||
face_edge_orig.append(e + l->e);
|
||||
if (need_face_flip) {
|
||||
face_vert[flen - i - 1] = fv;
|
||||
int iedge = i < flen - 1 ? flen - i - 2 : flen - 1;
|
||||
face_edge_orig[iedge] = e + l->e;
|
||||
}
|
||||
else {
|
||||
face_vert[i] = fv;
|
||||
face_edge_orig[i] = e + l->e;
|
||||
}
|
||||
++l;
|
||||
}
|
||||
r_info->mesh_to_imesh_face[f] = arena.add_face(face_vert, f, face_edge_orig);
|
||||
|
@@ -95,9 +95,14 @@ void BKE_mesh_foreach_mapped_vert(Mesh *mesh,
|
||||
}
|
||||
}
|
||||
|
||||
/* Copied from cdDM_foreachMappedEdge */
|
||||
/**
|
||||
* Copied from #cdDM_foreachMappedEdge.
|
||||
* \param tot_edges: Number of original edges. Used to avoid calling the callback with invalid
|
||||
* edge indices.
|
||||
*/
|
||||
void BKE_mesh_foreach_mapped_edge(
|
||||
Mesh *mesh,
|
||||
const int tot_edges,
|
||||
void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
|
||||
void *userData)
|
||||
{
|
||||
@@ -138,7 +143,7 @@ void BKE_mesh_foreach_mapped_edge(
|
||||
func(userData, orig, mv[med->v1].co, mv[med->v2].co);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (mesh->totedge == tot_edges) {
|
||||
for (int i = 0; i < mesh->totedge; i++, med++) {
|
||||
func(userData, i, mv[med->v1].co, mv[med->v2].co);
|
||||
}
|
||||
|
@@ -539,8 +539,8 @@ void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
|
||||
* \param totfinal: The size of \a final_origindex
|
||||
* \param final_origindex: The size of the final array.
|
||||
*
|
||||
* \note ``totsource`` could be ``totpoly``,
|
||||
* ``totfinal`` could be ``tottessface`` and ``final_origindex`` its ORIGINDEX customdata.
|
||||
* \note `totsource` could be `totpoly`,
|
||||
* `totfinal` could be `tottessface` and `final_origindex` its ORIGINDEX custom-data.
|
||||
* This would allow an MPoly to loop over its tessfaces.
|
||||
*/
|
||||
void BKE_mesh_origindex_map_create(MeshElemMap **r_map,
|
||||
|
@@ -530,6 +530,36 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
|
||||
lnors_spacearr->data_type = data_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for multi-threaded calculation that ensures
|
||||
* `lnors_spacearr_tls` doesn't share memory with `lnors_spacearr`
|
||||
* that would cause it not to be thread safe.
|
||||
*
|
||||
* \note This works as long as threads never operate on the same loops at once.
|
||||
*/
|
||||
void BKE_lnor_spacearr_tls_init(MLoopNorSpaceArray *lnors_spacearr,
|
||||
MLoopNorSpaceArray *lnors_spacearr_tls)
|
||||
{
|
||||
*lnors_spacearr_tls = *lnors_spacearr;
|
||||
lnors_spacearr_tls->mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for multi-threaded calculation
|
||||
* that merges `lnors_spacearr_tls` into `lnors_spacearr`.
|
||||
*/
|
||||
void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr,
|
||||
MLoopNorSpaceArray *lnors_spacearr_tls)
|
||||
{
|
||||
BLI_assert(lnors_spacearr->data_type == lnors_spacearr_tls->data_type);
|
||||
BLI_assert(lnors_spacearr->mem != lnors_spacearr_tls->mem);
|
||||
lnors_spacearr->num_spaces += lnors_spacearr_tls->num_spaces;
|
||||
BLI_memarena_merge(lnors_spacearr->mem, lnors_spacearr_tls->mem);
|
||||
BLI_memarena_free(lnors_spacearr_tls->mem);
|
||||
lnors_spacearr_tls->mem = nullptr;
|
||||
BKE_lnor_spacearr_clear(lnors_spacearr_tls);
|
||||
}
|
||||
|
||||
void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
|
||||
{
|
||||
lnors_spacearr->num_spaces = 0;
|
||||
|
@@ -516,6 +516,11 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
|
||||
BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->curve_vec);
|
||||
BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->curve_rgb);
|
||||
}
|
||||
else if ((ntree->type == NTREE_GEOMETRY) && (node->type == GEO_NODE_ATTRIBUTE_RANGE_QUERY)) {
|
||||
BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
|
||||
NodeGeometryAttributeRangeQuery *data = (NodeGeometryAttributeRangeQuery *)node->storage;
|
||||
BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->falloff_curve);
|
||||
}
|
||||
else if (ntree->type == NTREE_SHADER && (node->type == SH_NODE_SCRIPT)) {
|
||||
NodeShaderScript *nss = (NodeShaderScript *)node->storage;
|
||||
if (nss->bytecode) {
|
||||
@@ -701,6 +706,14 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GEO_NODE_ATTRIBUTE_RANGE_QUERY: {
|
||||
NodeGeometryAttributeRangeQuery *data = (NodeGeometryAttributeRangeQuery *)node->storage;
|
||||
BLO_read_data_address(reader, &data->falloff_curve);
|
||||
if (data->falloff_curve) {
|
||||
BKE_curvemapping_blend_read(reader, data->falloff_curve);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SH_NODE_SCRIPT: {
|
||||
NodeShaderScript *nss = (NodeShaderScript *)node->storage;
|
||||
BLO_read_data_address(reader, &nss->bytecode);
|
||||
@@ -1212,10 +1225,12 @@ static void update_typeinfo(Main *bmain,
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
/* Try to initialize all typeinfo in a node tree.
|
||||
* NB: In general undefined typeinfo is a perfectly valid case,
|
||||
/**
|
||||
* Try to initialize all type-info in a node tree.
|
||||
*
|
||||
* \note In general undefined type-info is a perfectly valid case,
|
||||
* the type may just be registered later.
|
||||
* In that case the update_typeinfo function will set typeinfo on registration
|
||||
* In that case the update_typeinfo function will set type-info on registration
|
||||
* and do necessary updates.
|
||||
*/
|
||||
void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree)
|
||||
@@ -5097,6 +5112,7 @@ static void registerGeometryNodes()
|
||||
register_node_type_geo_attribute_mix();
|
||||
register_node_type_geo_attribute_proximity();
|
||||
register_node_type_geo_attribute_randomize();
|
||||
register_node_type_geo_attribute_range_query();
|
||||
register_node_type_geo_attribute_remove();
|
||||
register_node_type_geo_attribute_separate_xyz();
|
||||
register_node_type_geo_attribute_transfer();
|
||||
@@ -5117,6 +5133,7 @@ static void registerGeometryNodes()
|
||||
register_node_type_geo_curve_primitive_star();
|
||||
register_node_type_geo_curve_resample();
|
||||
register_node_type_geo_curve_reverse();
|
||||
register_node_type_geo_curve_set_handles();
|
||||
register_node_type_geo_curve_subdivide();
|
||||
register_node_type_geo_curve_to_mesh();
|
||||
register_node_type_geo_curve_to_points();
|
||||
|
@@ -1653,7 +1653,7 @@ static void object_update_from_subsurf_ccg(Object *object)
|
||||
*
|
||||
* All this is defeating all the designs we need to follow to allow safe
|
||||
* threaded evaluation, but this is as good as we can make it within the
|
||||
* current sculpt//evaluated mesh design. This is also how we've survived
|
||||
* current sculpt/evaluated mesh design. This is also how we've survived
|
||||
* with old DerivedMesh based solutions. So, while this is all wrong and
|
||||
* needs reconsideration, doesn't seem to be a big stopper for real
|
||||
* production artists.
|
||||
|
@@ -880,7 +880,7 @@ static int palettecolor_compare_luminance(const void *a1, const void *a2)
|
||||
|
||||
void BKE_palette_sort_hsv(tPaletteColorHSV *color_array, const int totcol)
|
||||
{
|
||||
/* Sort by Hue , Saturation and Value. */
|
||||
/* Sort by Hue, Saturation and Value. */
|
||||
qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_hsv);
|
||||
}
|
||||
|
||||
|
@@ -1168,12 +1168,12 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
|
||||
}
|
||||
|
||||
/**
|
||||
* The 2 new faces created and assigned to ``f_new`` have their
|
||||
* The 2 new faces created and assigned to `f_new` have their
|
||||
* verts & edges shuffled around.
|
||||
*
|
||||
* - faces wind anticlockwise in this example.
|
||||
* - original edge is ``(v1, v2)``
|
||||
* - original face is ``(v1, v2, v3)``
|
||||
* - original edge is `(v1, v2)`
|
||||
* - original face is `(v1, v2, v3)`
|
||||
*
|
||||
* <pre>
|
||||
* + v3(v_opp)
|
||||
@@ -1189,8 +1189,8 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
|
||||
* (first) (second)
|
||||
* </pre>
|
||||
*
|
||||
* - f_new (first): ``v_tri=(v1, v4, v3), e_tri=(e1, e5, e4)``
|
||||
* - f_new (second): ``v_tri=(v4, v2, v3), e_tri=(e2, e3, e5)``
|
||||
* - f_new (first): `v_tri=(v1, v4, v3), e_tri=(e1, e5, e4)`
|
||||
* - f_new (second): `v_tri=(v4, v2, v3), e_tri=(e2, e3, e5)`
|
||||
*/
|
||||
|
||||
/* Create two new faces */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user