Merge branch 'master' into sculpt-dev
This commit is contained in:
commit
93305b97df
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
/**
|
||||
* Rach 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");
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -396,15 +396,15 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
|
|||
*/
|
||||
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,
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -29,9 +29,9 @@
|
|||
|
||||
class GHOST_SystemWayland;
|
||||
|
||||
struct output_t;
|
||||
struct window_t;
|
||||
struct wl_surface;
|
||||
struct output_t;
|
||||
|
||||
class GHOST_WindowWayland : public GHOST_Window {
|
||||
public:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 4833954c0ac85cc407e1d5a153aa11b1d1823ec0
|
||||
Subproject commit 62e82958a760dad775d9b3387d7fb535fd6de4c6
|
|
@ -1 +1 @@
|
|||
Subproject commit f86f25e62217264495d05f116ccb09d575fe9841
|
||||
Subproject commit 1adb56d8b01cf1327f58c6fb8b1ccc8b7efd76ad
|
|
@ -1 +1 @@
|
|||
Subproject commit 5a82baad9f986722104280e8354a4427d8e9eab1
|
||||
Subproject commit 788441f2930465bbfba8f0797b12dcef1d46694d
|
|
@ -139,6 +139,7 @@ url_manual_mapping = (
|
|||
("bpy.types.fluiddomainsettings.use_resumable_cache*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-use-resumable-cache"),
|
||||
("bpy.types.fluiddomainsettings.use_spray_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-spray-particles"),
|
||||
("bpy.types.fluiddomainsettings.vector_display_type*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-display-type"),
|
||||
("bpy.types.geometrynodecurveprimitivebeziersegment*", "modeling/geometry_nodes/curve_primitives/bezier_segment.html#bpy-types-geometrynodecurveprimitivebeziersegment"),
|
||||
("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"),
|
||||
("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"),
|
||||
("bpy.types.materialgpencilstyle.use_stroke_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-stroke-holdout"),
|
||||
|
@ -215,6 +216,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spacesequenceeditor.proxy_render_size*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-proxy-render-size"),
|
||||
("bpy.types.spacesequenceeditor.show_strip_offset*", "video_editing/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-strip-offset"),
|
||||
("bpy.types.spacesequenceeditor.show_strip_source*", "video_editing/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-strip-source"),
|
||||
("bpy.types.spacespreadsheetrowfilter.column_name*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-column-name"),
|
||||
("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"),
|
||||
("bpy.types.toolsettings.use_keyframe_cycle_aware*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-cycle-aware"),
|
||||
("bpy.types.toolsettings.use_keyframe_insert_auto*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-insert-auto"),
|
||||
|
@ -233,6 +235,7 @@ url_manual_mapping = (
|
|||
("bpy.types.rendersettings.resolution_percentage*", "render/output/properties/dimensions.html#bpy-types-rendersettings-resolution-percentage"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"),
|
||||
("bpy.types.spaceoutliner.use_filter_object_mesh*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-mesh"),
|
||||
("bpy.types.spaceoutliner.use_filter_view_layers*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-view-layers"),
|
||||
("bpy.types.spacesequenceeditor.show_overexposed*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-show-overexposed"),
|
||||
("bpy.types.toolsettings.use_gpencil_draw_onback*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-onback"),
|
||||
("bpy.types.toolsettings.use_snap_align_rotation*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-align-rotation"),
|
||||
|
@ -273,6 +276,8 @@ url_manual_mapping = (
|
|||
("bpy.types.spacesequenceeditor.show_safe_areas*", "video_editing/preview/introduction.html#bpy-types-spacesequenceeditor-show-safe-areas"),
|
||||
("bpy.types.spacesequenceeditor.show_strip_name*", "video_editing/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-strip-name"),
|
||||
("bpy.types.spacespreadsheet.show_only_selected*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-show-only-selected"),
|
||||
("bpy.types.spacespreadsheetrowfilter.operation*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-operation"),
|
||||
("bpy.types.spacespreadsheetrowfilter.threshold*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-threshold"),
|
||||
("bpy.types.toolsettings.use_snap_grid_absolute*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-grid-absolute"),
|
||||
("bpy.types.view3doverlay.show_face_orientation*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-face-orientation"),
|
||||
("bpy.ops.object.blenderkit_material_thumbnail*", "addons/3d_view/blenderkit.html#bpy-ops-object-blenderkit-material-thumbnail"),
|
||||
|
@ -343,6 +348,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spaceoutliner.use_filter_complete*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-complete"),
|
||||
("bpy.types.spacesequenceeditor.show_metadata*", "video_editing/preview/introduction.html#bpy-types-spacesequenceeditor-show-metadata"),
|
||||
("bpy.types.spacespreadsheet.attribute_domain*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-attribute-domain"),
|
||||
("bpy.types.spacespreadsheetrowfilter.enabled*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-enabled"),
|
||||
("bpy.types.spaceview3d.transform_orientation*", "editors/3dview/controls/orientation.html#bpy-types-spaceview3d-transform-orientation"),
|
||||
("bpy.types.spaceview3d.use_local_collections*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-local-collections"),
|
||||
("bpy.types.toolsettings.use_snap_peel_object*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-peel-object"),
|
||||
|
@ -350,7 +356,6 @@ url_manual_mapping = (
|
|||
("bpy.types.view3doverlay.wireframe_threshold*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-threshold"),
|
||||
("bpy.ops.object.constraint_add_with_targets*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraint-add-with-targets"),
|
||||
("bpy.ops.object.material_slot_remove_unused*", "scene_layout/object/editing/cleanup.html#bpy-ops-object-material-slot-remove-unused"),
|
||||
("bpy.ops.object.vertex_group_copy_to_linked*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-linked"),
|
||||
("bpy.ops.outliner.collection_disable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable-render"),
|
||||
("bpy.types.brush.cloth_simulation_area_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-simulation-area-type"),
|
||||
("bpy.types.brushgpencilsettings.fill_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-factor"),
|
||||
|
@ -372,6 +377,7 @@ url_manual_mapping = (
|
|||
("bpy.types.fluidflowsettings.use_plane_init*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-plane-init"),
|
||||
("bpy.types.fluidflowsettings.velocity_coord*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-coord"),
|
||||
("bpy.types.fluidflowsettings.volume_density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-volume-density"),
|
||||
("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve_primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"),
|
||||
("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-stroke"),
|
||||
("bpy.types.movietrackingcamera.focal_length*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-focal-length"),
|
||||
("bpy.types.movietrackingcamera.pixel_aspect*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-pixel-aspect"),
|
||||
|
@ -471,6 +477,7 @@ url_manual_mapping = (
|
|||
("bpy.types.geometrynodeattributecolorramp*", "modeling/geometry_nodes/attribute/attribute_color_ramp.html#bpy-types-geometrynodeattributecolorramp"),
|
||||
("bpy.types.geometrynodeattributeproximity*", "modeling/geometry_nodes/attribute/attribute_proximity.html#bpy-types-geometrynodeattributeproximity"),
|
||||
("bpy.types.geometrynodeattributerandomize*", "modeling/geometry_nodes/attribute/attribute_randomize.html#bpy-types-geometrynodeattributerandomize"),
|
||||
("bpy.types.geometrynodecurvequadrilateral*", "modeling/geometry_nodes/curve_primitives/quadrilateral.html#bpy-types-geometrynodecurvequadrilateral"),
|
||||
("bpy.types.geometrynodeseparatecomponents*", "modeling/geometry_nodes/geometry/separate_components.html#bpy-types-geometrynodeseparatecomponents"),
|
||||
("bpy.types.geometrynodesubdivisionsurface*", "modeling/geometry_nodes/mesh/subdivision_surface.html#bpy-types-geometrynodesubdivisionsurface"),
|
||||
("bpy.types.imageformatsettings.color_mode*", "render/output/properties/output.html#bpy-types-imageformatsettings-color-mode"),
|
||||
|
@ -490,7 +497,7 @@ url_manual_mapping = (
|
|||
("bpy.types.rendersettings.use_compositing*", "render/output/properties/post_processing.html#bpy-types-rendersettings-use-compositing"),
|
||||
("bpy.types.rendersettings.use_placeholder*", "render/output/properties/output.html#bpy-types-rendersettings-use-placeholder"),
|
||||
("bpy.types.shadernodesubsurfacescattering*", "render/shader_nodes/shader/sss.html#bpy-types-shadernodesubsurfacescattering"),
|
||||
("bpy.types.spaceclipeditor.lock_selection*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-lock-selection"),
|
||||
("bpy.types.spaceclipeditor.lock_selection*", "editors/clip/introduction.html#bpy-types-spaceclipeditor-lock-selection"),
|
||||
("bpy.types.spacedopesheeteditor.auto_snap*", "editors/dope_sheet/editing.html#bpy-types-spacedopesheeteditor-auto-snap"),
|
||||
("bpy.types.spaceoutliner.show_mode_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-mode-column"),
|
||||
("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"),
|
||||
|
@ -508,6 +515,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.outliner.collection_show_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show-inside"),
|
||||
("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"),
|
||||
("bpy.ops.sequencer.strip_transform_clear*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-strip-transform-clear"),
|
||||
("bpy.ops.spreadsheet.add_row_filter_rule*", "editors/spreadsheet.html#bpy-ops-spreadsheet-add-row-filter-rule"),
|
||||
("bpy.types.animdata.action_extrapolation*", "editors/nla/sidebar.html#bpy-types-animdata-action-extrapolation"),
|
||||
("bpy.types.bakesettings.max_ray_distance*", "render/cycles/baking.html#bpy-types-bakesettings-max-ray-distance"),
|
||||
("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"),
|
||||
|
@ -695,6 +703,7 @@ url_manual_mapping = (
|
|||
("bpy.types.fmodifierfunctiongenerator*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fmodifierfunctiongenerator"),
|
||||
("bpy.types.geometrynodeattributeclamp*", "modeling/geometry_nodes/attribute/attribute_clamp.html#bpy-types-geometrynodeattributeclamp"),
|
||||
("bpy.types.geometrynodecollectioninfo*", "modeling/geometry_nodes/input/collection_info.html#bpy-types-geometrynodecollectioninfo"),
|
||||
("bpy.types.geometrynodecurveendpoints*", "modeling/geometry_nodes/curve/curve_endpoints.html#bpy-types-geometrynodecurveendpoints"),
|
||||
("bpy.types.geometrynodecurvesubdivide*", "modeling/geometry_nodes/curve/curve_subdivide.html#bpy-types-geometrynodecurvesubdivide"),
|
||||
("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/delete_geometry.html#bpy-types-geometrynodedeletegeometry"),
|
||||
("bpy.types.geometrynodematerialassign*", "modeling/geometry_nodes/material/assign.html#bpy-types-geometrynodematerialassign"),
|
||||
|
@ -765,6 +774,7 @@ url_manual_mapping = (
|
|||
("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/curve_to_points.html#bpy-types-geometrynodecurvetopoints"),
|
||||
("bpy.types.geometrynodeinputmaterial*", "modeling/geometry_nodes/input/material.html#bpy-types-geometrynodeinputmaterial"),
|
||||
("bpy.types.geometrynodemeshicosphere*", "modeling/geometry_nodes/mesh_primitives/icosphere.html#bpy-types-geometrynodemeshicosphere"),
|
||||
("bpy.types.geometrynodemeshsubdivide*", "modeling/geometry_nodes/mesh/subdivide.html#bpy-types-geometrynodemeshsubdivide"),
|
||||
("bpy.types.geometrynodepointinstance*", "modeling/geometry_nodes/point/point_instance.html#bpy-types-geometrynodepointinstance"),
|
||||
("bpy.types.geometrynodepointseparate*", "modeling/geometry_nodes/point/point_separate.html#bpy-types-geometrynodepointseparate"),
|
||||
("bpy.types.geometrynoderesamplecurve*", "modeling/geometry_nodes/curve/resample_curve.html#bpy-types-geometrynoderesamplecurve"),
|
||||
|
@ -795,6 +805,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spline.tilt_interpolation*", "modeling/curves/properties/active_spline.html#bpy-types-spline-tilt-interpolation"),
|
||||
("bpy.types.transformorientation.name*", "editors/3dview/controls/orientation.html#bpy-types-transformorientation-name"),
|
||||
("bpy.types.volumedisplay.slice_depth*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-depth"),
|
||||
("bpy.ops.clip.lock_selection_toggle*", "editors/clip/introduction.html#bpy-ops-clip-lock-selection-toggle"),
|
||||
("bpy.ops.mesh.customdata_mask_clear*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-mesh-customdata-mask-clear"),
|
||||
("bpy.ops.mesh.extrude_vertices_move*", "modeling/meshes/editing/vertex/extrude_vertices.html#bpy-ops-mesh-extrude-vertices-move"),
|
||||
("bpy.ops.mesh.mod_weighted_strength*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-mod-weighted-strength"),
|
||||
|
@ -802,7 +813,6 @@ url_manual_mapping = (
|
|||
("bpy.ops.mesh.select_interior_faces*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-interior-faces"),
|
||||
("bpy.ops.mesh.select_similar_region*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar-region"),
|
||||
("bpy.ops.mesh.tris_convert_to_quads*", "modeling/meshes/editing/face/triangles_quads.html#bpy-ops-mesh-tris-convert-to-quads"),
|
||||
("bpy.ops.node.active_preview_toggle*", "modeling/geometry_nodes/introduction.html#bpy-ops-node-active-preview-toggle"),
|
||||
("bpy.ops.object.datalayout_transfer*", "scene_layout/object/editing/link_transfer/transfer_mesh_data_layout.html#bpy-ops-object-datalayout-transfer"),
|
||||
("bpy.ops.object.multires_base_apply*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-base-apply"),
|
||||
("bpy.ops.object.randomize_transform*", "scene_layout/object/editing/transform/randomize.html#bpy-ops-object-randomize-transform"),
|
||||
|
@ -872,6 +882,7 @@ url_manual_mapping = (
|
|||
("bpy.types.volumedisplay.slice_axis*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-axis"),
|
||||
("bpy.ops.anim.channels_clean_empty*", "editors/nla/editing.html#bpy-ops-anim-channels-clean-empty"),
|
||||
("bpy.ops.armature.select_hierarchy*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-hierarchy"),
|
||||
("bpy.ops.armature.switch_direction*", "animation/armatures/bones/editing/switch_direction.html#bpy-ops-armature-switch-direction"),
|
||||
("bpy.ops.clip.apply_solution_scale*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-apply-solution-scale"),
|
||||
("bpy.ops.clip.set_center_principal*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-center-principal"),
|
||||
("bpy.ops.clip.setup_tracking_scene*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-setup-tracking-scene"),
|
||||
|
@ -925,7 +936,9 @@ url_manual_mapping = (
|
|||
("bpy.types.functionnodeinputstring*", "modeling/geometry_nodes/input/string.html#bpy-types-functionnodeinputstring"),
|
||||
("bpy.types.functionnodeinputvector*", "modeling/geometry_nodes/input/vector.html#bpy-types-functionnodeinputvector"),
|
||||
("bpy.types.functionnoderandomfloat*", "modeling/geometry_nodes/input/random_float.html#bpy-types-functionnoderandomfloat"),
|
||||
("bpy.types.geometrynodecurvecircle*", "modeling/geometry_nodes/curve_primitives/circle.html#bpy-types-geometrynodecurvecircle"),
|
||||
("bpy.types.geometrynodecurvelength*", "modeling/geometry_nodes/curve/curve_length.html#bpy-types-geometrynodecurvelength"),
|
||||
("bpy.types.geometrynodecurvespiral*", "modeling/geometry_nodes/curve_primitives/spiral.html#bpy-types-geometrynodecurvespiral"),
|
||||
("bpy.types.geometrynodecurvetomesh*", "modeling/geometry_nodes/curve/curve_to_mesh.html#bpy-types-geometrynodecurvetomesh"),
|
||||
("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/curve/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"),
|
||||
("bpy.types.geometrynodepointrotate*", "modeling/geometry_nodes/point/point_rotate.html#bpy-types-geometrynodepointrotate"),
|
||||
|
@ -989,6 +1002,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.sequencer.select_handles*", "video_editing/sequencer/selecting.html#bpy-ops-sequencer-select-handles"),
|
||||
("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"),
|
||||
("bpy.ops.view3d.blenderkit_search*", "addons/3d_view/blenderkit.html#bpy-ops-view3d-blenderkit-search"),
|
||||
("bpy.types.armature.axes_position*", "animation/armatures/properties/display.html#bpy-types-armature-axes-position"),
|
||||
("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"),
|
||||
("bpy.types.bakesettings.use_clear*", "render/cycles/baking.html#bpy-types-bakesettings-use-clear"),
|
||||
("bpy.types.bone.envelope_distance*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-distance"),
|
||||
|
@ -1024,6 +1038,7 @@ url_manual_mapping = (
|
|||
("bpy.types.editbone.bbone_scalein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-scalein"),
|
||||
("bpy.types.editbone.inherit_scale*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-inherit-scale"),
|
||||
("bpy.types.geometrynodeconvexhull*", "modeling/geometry_nodes/geometry/convex_hull.html#bpy-types-geometrynodeconvexhull"),
|
||||
("bpy.types.geometrynodefloattoint*", "modeling/geometry_nodes/utilities/float_to_int.html#bpy-types-geometrynodefloattoint"),
|
||||
("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/is_viewport.html#bpy-types-geometrynodeisviewport"),
|
||||
("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh_primitives/circle.html#bpy-types-geometrynodemeshcircle"),
|
||||
("bpy.types.geometrynodeobjectinfo*", "modeling/geometry_nodes/input/object_info.html#bpy-types-geometrynodeobjectinfo"),
|
||||
|
@ -1051,6 +1066,8 @@ url_manual_mapping = (
|
|||
("bpy.types.volumerender.step_size*", "modeling/volumes/properties.html#bpy-types-volumerender-step-size"),
|
||||
("bpy.types.weightednormalmodifier*", "modeling/modifiers/modify/weighted_normal.html#bpy-types-weightednormalmodifier"),
|
||||
("bpy.ops.armature.autoside_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-autoside-names"),
|
||||
("bpy.ops.armature.calculate_roll*", "animation/armatures/bones/editing/bone_roll.html#bpy-ops-armature-calculate-roll"),
|
||||
("bpy.ops.armature.duplicate_move*", "animation/armatures/bones/editing/duplicate.html#bpy-ops-armature-duplicate-move"),
|
||||
("bpy.ops.armature.select_similar*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-similar"),
|
||||
("bpy.ops.clip.create_plane_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-create-plane-track"),
|
||||
("bpy.ops.curve.spline_weight_set*", "modeling/curves/editing/other.html#bpy-ops-curve-spline-weight-set"),
|
||||
|
@ -1099,6 +1116,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.wm.operator_cheat_sheet*", "advanced/operators.html#bpy-ops-wm-operator-cheat-sheet"),
|
||||
("bpy.ops.wm.previews_batch_clear*", "files/blend/previews.html#bpy-ops-wm-previews-batch-clear"),
|
||||
("bpy.ops.wm.recover_last_session*", "files/blend/open_save.html#bpy-ops-wm-recover-last-session"),
|
||||
("bpy.types.armature.display_type*", "animation/armatures/properties/display.html#bpy-types-armature-display-type"),
|
||||
("bpy.types.armature.use_mirror_x*", "animation/armatures/bones/tools/tool_settings.html#bpy-types-armature-use-mirror-x"),
|
||||
("bpy.types.bakesettings.normal_b*", "render/cycles/baking.html#bpy-types-bakesettings-normal-b"),
|
||||
("bpy.types.bakesettings.normal_g*", "render/cycles/baking.html#bpy-types-bakesettings-normal-g"),
|
||||
|
@ -1127,8 +1145,10 @@ url_manual_mapping = (
|
|||
("bpy.types.editbone.bbone_rollin*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollin"),
|
||||
("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"),
|
||||
("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"),
|
||||
("bpy.types.geometrynodecurveline*", "modeling/geometry_nodes/curve_primitives/line.html#bpy-types-geometrynodecurveline"),
|
||||
("bpy.types.geometrynodecurvestar*", "modeling/geometry_nodes/curve_primitives/star.html#bpy-types-geometrynodecurvestar"),
|
||||
("bpy.types.geometrynodecurvetrim*", "modeling/geometry_nodes/curve/curve_trim.html#bpy-types-geometrynodecurvetrim"),
|
||||
("bpy.types.geometrynodeedgesplit*", "modeling/geometry_nodes/mesh/edge_split.html#bpy-types-geometrynodeedgesplit"),
|
||||
("bpy.types.geometrynodesubdivide*", "modeling/geometry_nodes/mesh/subdivide.html#bpy-types-geometrynodesubdivide"),
|
||||
("bpy.types.geometrynodetransform*", "modeling/geometry_nodes/geometry/transform.html#bpy-types-geometrynodetransform"),
|
||||
("bpy.types.gpencilsculptsettings*", "grease_pencil/properties/index.html#bpy-types-gpencilsculptsettings"),
|
||||
("bpy.types.light.cutoff_distance*", "render/eevee/lighting.html#bpy-types-light-cutoff-distance"),
|
||||
|
@ -1247,6 +1267,8 @@ url_manual_mapping = (
|
|||
("bpy.types.volumetomeshmodifier*", "modeling/modifiers/generate/volume_to_mesh.html#bpy-types-volumetomeshmodifier"),
|
||||
("bpy.types.whitebalancemodifier*", "video_editing/sequencer/sidebar/modifiers.html#bpy-types-whitebalancemodifier"),
|
||||
("bpy.ops.anim.channels_ungroup*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-ungroup"),
|
||||
("bpy.ops.armature.extrude_move*", "animation/armatures/bones/editing/extrude.html#bpy-ops-armature-extrude-move"),
|
||||
("bpy.ops.armature.parent_clear*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-clear"),
|
||||
("bpy.ops.clip.clear_track_path*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clear-track-path"),
|
||||
("bpy.ops.clip.set_scene_frames*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-scene-frames"),
|
||||
("bpy.ops.curve.handle_type_set*", "modeling/curves/editing/control_points.html#bpy-ops-curve-handle-type-set"),
|
||||
|
@ -1424,6 +1446,7 @@ url_manual_mapping = (
|
|||
("bpy.types.freestylelinestyle*", "render/freestyle/parameter_editor/line_style/index.html#bpy-types-freestylelinestyle"),
|
||||
("bpy.types.gammacrosssequence*", "video_editing/sequencer/strips/transitions/gamma_cross.html#bpy-types-gammacrosssequence"),
|
||||
("bpy.types.geometrynodeswitch*", "modeling/geometry_nodes/utilities/switch.html#bpy-types-geometrynodeswitch"),
|
||||
("bpy.types.geometrynodeviewer*", "modeling/geometry_nodes/output/viewer.html#bpy-types-geometrynodeviewer"),
|
||||
("bpy.types.gpencilsculptguide*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide"),
|
||||
("bpy.types.huecorrectmodifier*", "video_editing/sequencer/sidebar/modifiers.html#bpy-types-huecorrectmodifier"),
|
||||
("bpy.types.imagepaint.stencil*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-imagepaint-stencil"),
|
||||
|
@ -1462,7 +1485,9 @@ url_manual_mapping = (
|
|||
("bpy.ops.anim.channels_group*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-group"),
|
||||
("bpy.ops.anim.keyframe_clear*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-clear"),
|
||||
("bpy.ops.armature.flip_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-flip-names"),
|
||||
("bpy.ops.armature.parent_set*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-set"),
|
||||
("bpy.ops.armature.select_all*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-all"),
|
||||
("bpy.ops.armature.symmetrize*", "animation/armatures/bones/editing/symmetrize.html#bpy-ops-armature-symmetrize"),
|
||||
("bpy.ops.clip.average_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-average-tracks"),
|
||||
("bpy.ops.clip.refine_markers*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-refine-markers"),
|
||||
("bpy.ops.clip.select_grouped*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-grouped"),
|
||||
|
@ -1501,6 +1526,8 @@ url_manual_mapping = (
|
|||
("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"),
|
||||
("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"),
|
||||
("bpy.ops.pose.armature_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-armature-apply"),
|
||||
("bpy.ops.pose.group_deselect*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-deselect"),
|
||||
("bpy.ops.pose.group_unassign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-unassign"),
|
||||
("bpy.ops.pose.select_grouped*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-grouped"),
|
||||
("bpy.ops.poselib.pose_remove*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-remove"),
|
||||
("bpy.ops.poselib.pose_rename*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-rename"),
|
||||
|
@ -1574,6 +1601,7 @@ url_manual_mapping = (
|
|||
("bpy.types.wireframemodifier*", "modeling/modifiers/generate/wireframe.html#bpy-types-wireframemodifier"),
|
||||
("bpy.types.worldmistsettings*", "render/cycles/world_settings.html#bpy-types-worldmistsettings"),
|
||||
("bpy.ops.anim.channels_move*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-move"),
|
||||
("bpy.ops.armature.subdivide*", "animation/armatures/bones/editing/subdivide.html#bpy-ops-armature-subdivide"),
|
||||
("bpy.ops.buttons.toggle_pin*", "editors/properties_editor.html#bpy-ops-buttons-toggle-pin"),
|
||||
("bpy.ops.clip.filter_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-filter-tracks"),
|
||||
("bpy.ops.clip.select_circle*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-circle"),
|
||||
|
@ -1675,6 +1703,8 @@ url_manual_mapping = (
|
|||
("bpy.types.texturenodegroup*", "editors/texture_node/types/groups.html#bpy-types-texturenodegroup"),
|
||||
("bpy.types.texturenodeimage*", "editors/texture_node/types/input/image.html#bpy-types-texturenodeimage"),
|
||||
("bpy.types.viewlayer.use_ao*", "render/layers/introduction.html#bpy-types-viewlayer-use-ao"),
|
||||
("bpy.ops.armature.dissolve*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-dissolve"),
|
||||
("bpy.ops.armature.separate*", "animation/armatures/bones/editing/separate_bones.html#bpy-ops-armature-separate"),
|
||||
("bpy.ops.clip.clean_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clean-tracks"),
|
||||
("bpy.ops.clip.delete_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-delete-track"),
|
||||
("bpy.ops.clip.solve_camera*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-solve-camera"),
|
||||
|
@ -1703,6 +1733,8 @@ url_manual_mapping = (
|
|||
("bpy.ops.object.proxy_make*", "files/linked_libraries/library_proxies.html#bpy-ops-object-proxy-make"),
|
||||
("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"),
|
||||
("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"),
|
||||
("bpy.ops.pose.group_assign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-assign"),
|
||||
("bpy.ops.pose.group_select*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-select"),
|
||||
("bpy.ops.poselib.pose_move*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-pose-move"),
|
||||
("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"),
|
||||
("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"),
|
||||
|
@ -1872,6 +1904,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.wm.owner_enable*", "interface/window_system/workspaces.html#bpy-ops-wm-owner-enable"),
|
||||
("bpy.ops.wm.redraw_timer*", "advanced/operators.html#bpy-ops-wm-redraw-timer"),
|
||||
("bpy.types.*light.shadow*", "render/eevee/lighting.html#bpy-types-light-shadow"),
|
||||
("bpy.types.armature.show*", "animation/armatures/properties/display.html#bpy-types-armature-show"),
|
||||
("bpy.types.armaturebones*", "animation/armatures/bones/index.html#bpy-types-armaturebones"),
|
||||
("bpy.types.arraymodifier*", "modeling/modifiers/generate/array.html#bpy-types-arraymodifier"),
|
||||
("bpy.types.bevelmodifier*", "modeling/modifiers/generate/bevel.html#bpy-types-bevelmodifier"),
|
||||
|
@ -1919,6 +1952,8 @@ url_manual_mapping = (
|
|||
("bpy.types.volumedisplay*", "modeling/volumes/properties.html#bpy-types-volumedisplay"),
|
||||
("bpy.types.windowmanager*", "interface/index.html#bpy-types-windowmanager"),
|
||||
("bpy.ops.*.select_lasso*", "interface/selecting.html#bpy-ops-select-lasso"),
|
||||
("bpy.ops.armature.align*", "animation/armatures/bones/editing/transform.html#bpy-ops-armature-align"),
|
||||
("bpy.ops.armature.split*", "animation/armatures/bones/editing/split.html#bpy-ops-armature-split"),
|
||||
("bpy.ops.clip.set_plane*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-plane"),
|
||||
("bpy.ops.clip.set_scale*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-scale"),
|
||||
("bpy.ops.curve.decimate*", "modeling/curves/editing/curve.html#bpy-ops-curve-decimate"),
|
||||
|
@ -1993,6 +2028,7 @@ url_manual_mapping = (
|
|||
("bpy.types.wavemodifier*", "modeling/modifiers/deform/wave.html#bpy-types-wavemodifier"),
|
||||
("bpy.types.weldmodifier*", "modeling/modifiers/generate/weld.html#bpy-types-weldmodifier"),
|
||||
("bpy.types.wipesequence*", "video_editing/sequencer/strips/transitions/wipe.html#bpy-types-wipesequence"),
|
||||
("bpy.ops.armature.fill*", "animation/armatures/bones/editing/fill_between_joints.html#bpy-ops-armature-fill"),
|
||||
("bpy.ops.clip.prefetch*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-prefetch"),
|
||||
("bpy.ops.clip.set_axis*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-axis"),
|
||||
("bpy.ops.file.pack_all*", "files/blend/packed_data.html#bpy-ops-file-pack-all"),
|
||||
|
@ -2064,6 +2100,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.uv.mark_seam*", "modeling/meshes/uv/unwrapping/seams.html#bpy-ops-uv-mark-seam"),
|
||||
("bpy.ops.view3d.ruler*", "editors/3dview/toolbar/measure.html#bpy-ops-view3d-ruler"),
|
||||
("bpy.types.areaspaces*", "interface/window_system/areas.html#bpy-types-areaspaces"),
|
||||
("bpy.types.bonegroups*", "animation/armatures/properties/bone_groups.html#bpy-types-bonegroups"),
|
||||
("bpy.types.bpy_struct*", "files/data_blocks.html#bpy-types-bpy-struct"),
|
||||
("bpy.types.collection*", "scene_layout/collections/collections.html#bpy-types-collection"),
|
||||
("bpy.types.compositor*", "compositing/index.html#bpy-types-compositor"),
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
# <pep8 compliant>
|
||||
from __future__ import annotations
|
||||
from pathlib import Path
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -108,14 +108,13 @@ class SequencerSplitMulticam(Operator):
|
|||
if s.multicam_source == camera or camera >= s.channel:
|
||||
return {'FINISHED'}
|
||||
|
||||
if not s.select:
|
||||
s.select = True
|
||||
|
||||
cfra = context.scene.frame_current
|
||||
bpy.ops.sequencer.split(frame=cfra, type='SOFT', side='RIGHT')
|
||||
for s in context.scene.sequence_editor.sequences_all:
|
||||
if s.select and s.type == 'MULTICAM' and s.frame_final_start <= cfra and cfra < s.frame_final_end:
|
||||
context.scene.sequence_editor.active_strip = s
|
||||
right_strip = s.split(frame=cfra, split_method='SOFT')
|
||||
|
||||
if right_strip:
|
||||
s.select = False
|
||||
right_strip.select = True
|
||||
context.scene.sequence_editor.active_strip = right_strip
|
||||
|
||||
context.scene.sequence_editor.active_strip.multicam_source = camera
|
||||
return {'FINISHED'}
|
||||
|
|
|
@ -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 = (
|
||||
|
|
|
@ -647,7 +647,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
|
|||
if len(colliding_names) == 0:
|
||||
return
|
||||
|
||||
layout.label(text="Name Collisions: {}".format(", ".join(colliding_names)), icon='INFO')
|
||||
layout.label(text="Name collisions: {}".format(", ".join(colliding_names)), icon='ERROR')
|
||||
|
||||
|
||||
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 = (
|
||||
|
|
|
@ -507,6 +507,7 @@ geometry_node_categories = [
|
|||
NodeItem("GeometryNodeMeshToCurve"),
|
||||
NodeItem("GeometryNodeCurveToPoints"),
|
||||
NodeItem("GeometryNodeCurveEndpoints"),
|
||||
NodeItem("GeometryNodeCurveTrim"),
|
||||
NodeItem("GeometryNodeCurveLength"),
|
||||
NodeItem("GeometryNodeCurveReverse"),
|
||||
]),
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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
|
|
@ -28,7 +28,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct AnimationEvalContext;
|
||||
struct bAction;
|
||||
struct BMEditMesh;
|
||||
struct Bone;
|
||||
struct Depsgraph;
|
||||
|
@ -39,6 +38,7 @@ struct Mesh;
|
|||
struct Object;
|
||||
struct PoseTree;
|
||||
struct Scene;
|
||||
struct bAction;
|
||||
struct bArmature;
|
||||
struct bConstraint;
|
||||
struct bGPDstroke;
|
||||
|
|
|
@ -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,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
|
||||
|
|
|
@ -97,7 +97,6 @@ struct BoundBox *BKE_curve_boundbox_get(struct Object *ob);
|
|||
|
||||
void BKE_curve_texspace_calc(struct Curve *cu);
|
||||
void BKE_curve_texspace_ensure(struct Curve *cu);
|
||||
void BKE_curve_texspace_get(struct Curve *cu, float r_loc[3], float r_size[3]);
|
||||
|
||||
bool BKE_curve_minmax(struct Curve *cu, bool use_radius, float min[3], float max[3]);
|
||||
bool BKE_curve_center_median(struct Curve *cu, float cent[3]);
|
||||
|
|
|
@ -30,6 +30,7 @@ extern "C" {
|
|||
|
||||
struct BlendDataReader;
|
||||
struct BlendWriter;
|
||||
struct ID;
|
||||
struct ListBase;
|
||||
struct MDeformVert;
|
||||
struct MEdge;
|
||||
|
@ -37,7 +38,6 @@ struct MLoop;
|
|||
struct MPoly;
|
||||
struct Object;
|
||||
struct bDeformGroup;
|
||||
struct ID;
|
||||
|
||||
bool BKE_object_supports_vertex_groups(const struct Object *ob);
|
||||
const struct ListBase *BKE_object_defgroup_list(const struct Object *ob);
|
||||
|
|
|
@ -32,8 +32,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct BMLoop;
|
||||
struct BMesh;
|
||||
struct BMPartialUpdate;
|
||||
struct BMesh;
|
||||
struct BMeshCalcTessellation_Params;
|
||||
struct BoundBox;
|
||||
struct Depsgraph;
|
||||
|
|
|
@ -35,12 +35,12 @@
|
|||
#include "BKE_geometry_set.h"
|
||||
|
||||
struct Collection;
|
||||
struct Curve;
|
||||
struct CurveEval;
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
struct PointCloud;
|
||||
struct Volume;
|
||||
struct Curve;
|
||||
struct CurveEval;
|
||||
|
||||
enum class GeometryOwnershipType {
|
||||
/* The geometry is owned. This implies that it can be changed. */
|
||||
|
|
|
@ -49,22 +49,22 @@ struct bGPDlayer_Mask;
|
|||
struct bGPDstroke;
|
||||
struct bGPdata;
|
||||
|
||||
#define GPENCIL_SIMPLIFY(scene) ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE))
|
||||
#define GPENCIL_SIMPLIFY(scene) (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE)
|
||||
#define GPENCIL_SIMPLIFY_ONPLAY(playing) \
|
||||
(((playing == true) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY)) || \
|
||||
((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY) == 0))
|
||||
#define GPENCIL_SIMPLIFY_FILL(scene, playing) \
|
||||
((GPENCIL_SIMPLIFY_ONPLAY(playing) && (GPENCIL_SIMPLIFY(scene)) && \
|
||||
((GPENCIL_SIMPLIFY_ONPLAY(playing) && GPENCIL_SIMPLIFY(scene) && \
|
||||
(scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FILL)))
|
||||
#define GPENCIL_SIMPLIFY_MODIF(scene) \
|
||||
((GPENCIL_SIMPLIFY(scene) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_MODIFIER)))
|
||||
#define GPENCIL_SIMPLIFY_FX(scene, playing) \
|
||||
((GPENCIL_SIMPLIFY_ONPLAY(playing) && (GPENCIL_SIMPLIFY(scene)) && \
|
||||
((GPENCIL_SIMPLIFY_ONPLAY(playing) && GPENCIL_SIMPLIFY(scene) && \
|
||||
(scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FX)))
|
||||
#define GPENCIL_SIMPLIFY_TINT(scene) \
|
||||
((GPENCIL_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_TINT))
|
||||
(GPENCIL_SIMPLIFY(scene) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_TINT))
|
||||
#define GPENCIL_SIMPLIFY_AA(scene) \
|
||||
((GPENCIL_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_AA))
|
||||
(GPENCIL_SIMPLIFY(scene) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_AA))
|
||||
|
||||
/* Vertex Color macros. */
|
||||
#define GPENCIL_USE_VERTEX_COLOR(toolsettings) \
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Collection;
|
||||
struct BlendFileReadReport;
|
||||
struct Collection;
|
||||
struct ID;
|
||||
struct IDOverrideLibrary;
|
||||
struct IDOverrideLibraryProperty;
|
||||
|
|
|
@ -126,8 +126,8 @@ void BKE_mesh_eval_delete(struct Mesh *mesh_eval);
|
|||
struct Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference);
|
||||
|
||||
/* These functions construct a new Mesh,
|
||||
* contrary to BKE_mesh_from_nurbs which modifies ob itself. */
|
||||
struct Mesh *BKE_mesh_new_nomain_from_curve(struct Object *ob);
|
||||
* contrary to BKE_mesh_to_curve_nurblist which modifies ob itself. */
|
||||
struct Mesh *BKE_mesh_new_nomain_from_curve(const struct Object *ob);
|
||||
struct Mesh *BKE_mesh_new_nomain_from_curve_displist(const struct Object *ob,
|
||||
const struct ListBase *dispbase);
|
||||
|
||||
|
@ -143,32 +143,11 @@ int BKE_mesh_mface_index_validate(struct MFace *mface,
|
|||
struct Mesh *BKE_mesh_from_object(struct Object *ob);
|
||||
void BKE_mesh_assign_object(struct Main *bmain, struct Object *ob, struct Mesh *me);
|
||||
void BKE_mesh_from_metaball(struct ListBase *lb, struct Mesh *me);
|
||||
int BKE_mesh_nurbs_to_mdata(struct Object *ob,
|
||||
struct MVert **r_allvert,
|
||||
int *r_totvert,
|
||||
struct MEdge **r_alledge,
|
||||
int *r_totedge,
|
||||
struct MLoop **r_allloop,
|
||||
struct MPoly **r_allpoly,
|
||||
int *r_totloop,
|
||||
int *r_totpoly);
|
||||
int BKE_mesh_nurbs_displist_to_mdata(const struct Object *ob,
|
||||
const struct ListBase *dispbase,
|
||||
struct MVert **r_allvert,
|
||||
int *r_totvert,
|
||||
struct MEdge **r_alledge,
|
||||
int *r_totedge,
|
||||
struct MLoop **r_allloop,
|
||||
struct MPoly **r_allpoly,
|
||||
struct MLoopUV **r_alluv,
|
||||
int *r_totloop,
|
||||
int *r_totpoly);
|
||||
void BKE_mesh_from_nurbs_displist(struct Main *bmain,
|
||||
struct Object *ob,
|
||||
struct ListBase *dispbase,
|
||||
const char *obdata_name,
|
||||
bool temporary);
|
||||
void BKE_mesh_from_nurbs(struct Main *bmain, struct Object *ob);
|
||||
void BKE_mesh_to_curve_nurblist(const struct Mesh *me,
|
||||
struct ListBase *nurblist,
|
||||
const int edge_users_test);
|
||||
|
|
|
@ -27,7 +27,6 @@ typedef enum eMeshBatchDirtyMode {
|
|||
BKE_MESH_BATCH_DIRTY_SELECT,
|
||||
BKE_MESH_BATCH_DIRTY_SELECT_PAINT,
|
||||
BKE_MESH_BATCH_DIRTY_SHADING,
|
||||
BKE_MESH_BATCH_DIRTY_DEFORM,
|
||||
BKE_MESH_BATCH_DIRTY_UVEDIT_ALL,
|
||||
BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT,
|
||||
} eMeshBatchDirtyMode;
|
||||
|
|
|
@ -1274,6 +1274,11 @@ void ntreeGPUMaterialNodes(struct bNodeTree *localtree,
|
|||
#define CMP_CRYPTOMATTE_SRC_RENDER 0
|
||||
#define CMP_CRYPTOMATTE_SRC_IMAGE 1
|
||||
|
||||
/* Default SMAA configuration values. */
|
||||
#define CMP_DEFAULT_SMAA_THRESHOLD 1.0f
|
||||
#define CMP_DEFAULT_SMAA_CONTRAST_LIMIT 0.2f
|
||||
#define CMP_DEFAULT_SMAA_CORNER_ROUNDING 0.25f
|
||||
|
||||
/* API */
|
||||
void ntreeCompositExecTree(struct Scene *scene,
|
||||
struct bNodeTree *ntree,
|
||||
|
@ -1459,6 +1464,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
|
|||
#define GEO_NODE_CURVE_PRIMITIVE_LINE 1068
|
||||
#define GEO_NODE_CURVE_ENDPOINTS 1069
|
||||
#define GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL 1070
|
||||
#define GEO_NODE_CURVE_TRIM 1071
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -374,10 +374,6 @@ void BKE_object_runtime_free_data(struct Object *object);
|
|||
|
||||
void BKE_object_batch_cache_dirty_tag(struct Object *ob);
|
||||
void BKE_object_data_batch_cache_dirty_tag(struct ID *object_data);
|
||||
void BKE_object_data_eval_batch_cache_dirty_tag(struct Depsgraph *depsgraph,
|
||||
struct ID *object_data);
|
||||
void BKE_object_data_eval_batch_cache_deform_tag(struct Depsgraph *depsgraph,
|
||||
struct ID *object_data);
|
||||
|
||||
/* this function returns a superset of the scenes selection based on relationships */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -143,7 +145,7 @@ set(SRC
|
|||
intern/geometry_set_instances.cc
|
||||
intern/gpencil.c
|
||||
intern/gpencil_curve.c
|
||||
intern/gpencil_geom.c
|
||||
intern/gpencil_geom.cc
|
||||
intern/gpencil_modifier.c
|
||||
intern/hair.c
|
||||
intern/icons.cc
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -324,8 +324,9 @@ static void action_flip_pchan(Object *ob_arm,
|
|||
|
||||
/* The rest pose having an X-axis that is not mapping to a left/right direction (so aligned
|
||||
* with the Y or Z axis) creates issues when flipping the pose. Instead of a negative scale on
|
||||
* the X-axis, it turns into a 180 degree rotation over the Y-axis. This has only been observed
|
||||
* with non-flippable bones, hence the check for `pchan_flip`. */
|
||||
* the X-axis, it turns into a 180 degree rotation over the Y-axis.
|
||||
* This has only been observed with bones that can't be flipped,
|
||||
* hence the check for `pchan_flip`. */
|
||||
const float unit_x[4] = {1.0f, 0.0f, 0.0f, 0.0f};
|
||||
const bool is_problematic = pchan_flip == NULL &&
|
||||
fabsf(dot_v4v4(pchan->bone->arm_mat[0], unit_x)) <= 1e-6;
|
||||
|
|
|
@ -501,7 +501,7 @@ static void armature_deform_coords_impl(const Object *ob_arm,
|
|||
BLI_assert(0);
|
||||
}
|
||||
|
||||
if (ELEM(ob_target->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
|
||||
if (BKE_object_supports_vertex_groups(ob_target)) {
|
||||
/* get the def_nr for the overall armature vertex group if present */
|
||||
armature_def_nr = BKE_object_defgroup_name_index(ob_target, defgrp_name);
|
||||
|
||||
|
@ -529,11 +529,9 @@ static void armature_deform_coords_impl(const Object *ob_arm,
|
|||
dverts_len = gps_target->totpoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get a vertex-deform-index to posechannel array */
|
||||
if (deformflag & ARM_DEF_VGROUP) {
|
||||
if (ELEM(ob_target->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
|
||||
/* get a vertex-deform-index to posechannel array */
|
||||
if (deformflag & ARM_DEF_VGROUP) {
|
||||
/* if we have a Mesh, only use dverts if it has them */
|
||||
if (em_target) {
|
||||
cd_dvert_offset = CustomData_get_offset(&em_target->bm->vdata, CD_MDEFORMVERT);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,76 @@ 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 = {NULL, NULL};
|
||||
BLI_addtail(&arm.bonebase, &bone1);
|
||||
BLI_addtail(&arm.bonebase, &bone2);
|
||||
BLI_addtail(&arm.bonebase, &bone3);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -332,16 +332,6 @@ IDTypeInfo IDType_ID_CU = {
|
|||
.lib_override_apply_post = NULL,
|
||||
};
|
||||
|
||||
static int cu_isectLL(const float v1[3],
|
||||
const float v2[3],
|
||||
const float v3[3],
|
||||
const float v4[3],
|
||||
short cox,
|
||||
short coy,
|
||||
float *lambda,
|
||||
float *mu,
|
||||
float vec[3]);
|
||||
|
||||
/* frees editcurve entirely */
|
||||
void BKE_curve_editfont_free(Curve *cu)
|
||||
{
|
||||
|
@ -566,18 +556,6 @@ void BKE_curve_texspace_ensure(Curve *cu)
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_curve_texspace_get(Curve *cu, float r_loc[3], float r_size[3])
|
||||
{
|
||||
BKE_curve_texspace_ensure(cu);
|
||||
|
||||
if (r_loc) {
|
||||
copy_v3_v3(r_loc, cu->loc);
|
||||
}
|
||||
if (r_size) {
|
||||
copy_v3_v3(r_size, cu->size);
|
||||
}
|
||||
}
|
||||
|
||||
bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3])
|
||||
{
|
||||
int tot = 0;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -688,7 +688,7 @@ static float fcm_cycles_time(
|
|||
ofs = lastkey[0];
|
||||
}
|
||||
}
|
||||
if ((ELEM(0, side, mode))) {
|
||||
if (ELEM(0, side, mode)) {
|
||||
return evaltime;
|
||||
}
|
||||
|
||||
|
|
|
@ -565,6 +565,7 @@ static PointCloud *join_pointcloud_position_attribute(Span<GeometryInstanceGroup
|
|||
}
|
||||
|
||||
PointCloud *new_pointcloud = BKE_pointcloud_new_nomain(totpoint);
|
||||
MutableSpan new_positions{(float3 *)new_pointcloud->co, new_pointcloud->totpoint};
|
||||
|
||||
/* Transform each instance's point locations into the new point cloud. */
|
||||
int offset = 0;
|
||||
|
@ -576,9 +577,7 @@ static PointCloud *join_pointcloud_position_attribute(Span<GeometryInstanceGroup
|
|||
}
|
||||
for (const float4x4 &transform : set_group.transforms) {
|
||||
for (const int i : IndexRange(pointcloud->totpoint)) {
|
||||
const float3 old_position = pointcloud->co[i];
|
||||
const float3 new_position = transform * old_position;
|
||||
copy_v3_v3(new_pointcloud->co[offset + i], new_position);
|
||||
new_positions[offset + i] = transform * float3(pointcloud->co[i]);
|
||||
}
|
||||
offset += pointcloud->totpoint;
|
||||
}
|
||||
|
|
|
@ -2730,7 +2730,7 @@ void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer,
|
|||
int cfra)
|
||||
{
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
const bool is_multiedit = ((GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) && (!GPENCIL_PLAY_ON(gpd)));
|
||||
const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && (!GPENCIL_PLAY_ON(gpd)));
|
||||
const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
|
||||
const bool is_drawing = (gpd->runtime.sbuffer_used > 0);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -273,7 +273,7 @@ int BKE_gpencil_time_modifier_cfra(Depsgraph *depsgraph,
|
|||
if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
|
||||
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
|
||||
|
||||
if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
|
||||
if (GPENCIL_MODIFIER_EDIT(md, is_edit) && (!is_render)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -838,7 +838,7 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
|||
if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
|
||||
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
|
||||
|
||||
if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
|
||||
if (GPENCIL_MODIFIER_EDIT(md, is_edit) && (!is_render)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -937,7 +937,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
|
|||
ListBase isect_remedgebase = {NULL, NULL};
|
||||
|
||||
/* now we have all the splines */
|
||||
face_coords = MEM_mallocN((sizeof(float[3])) * sf_vert_tot, "maskrast_face_coords");
|
||||
face_coords = MEM_mallocN(sizeof(float[3]) * sf_vert_tot, "maskrast_face_coords");
|
||||
|
||||
/* init bounds */
|
||||
BLI_rctf_init_minmax(&bounds);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -312,7 +312,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
mesh->totselect = 0;
|
||||
}
|
||||
|
||||
if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) {
|
||||
if (BLO_read_requires_endian_switch(reader) && mesh->tface) {
|
||||
TFace *tf = mesh->tface;
|
||||
for (int i = 0; i < mesh->totface; i++, tf++) {
|
||||
BLI_endian_switch_uint32_array(tf->col, 4);
|
||||
|
@ -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)
|
||||
|
|
|
@ -211,55 +211,20 @@ static void make_edges_mdata_extend(
|
|||
BLI_edgehash_free(eh, NULL);
|
||||
}
|
||||
|
||||
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
|
||||
/* return non-zero on error */
|
||||
int BKE_mesh_nurbs_to_mdata(Object *ob,
|
||||
MVert **r_allvert,
|
||||
int *r_totvert,
|
||||
MEdge **r_alledge,
|
||||
int *r_totedge,
|
||||
MLoop **r_allloop,
|
||||
MPoly **r_allpoly,
|
||||
int *r_totloop,
|
||||
int *r_totpoly)
|
||||
{
|
||||
ListBase disp = {NULL, NULL};
|
||||
|
||||
if (ob->runtime.curve_cache) {
|
||||
disp = ob->runtime.curve_cache->disp;
|
||||
}
|
||||
|
||||
return BKE_mesh_nurbs_displist_to_mdata(ob,
|
||||
&disp,
|
||||
r_allvert,
|
||||
r_totvert,
|
||||
r_alledge,
|
||||
r_totedge,
|
||||
r_allloop,
|
||||
r_allpoly,
|
||||
NULL,
|
||||
r_totloop,
|
||||
r_totpoly);
|
||||
}
|
||||
|
||||
/* BMESH: this doesn't calculate all edges from polygons,
|
||||
* only free standing edges are calculated */
|
||||
|
||||
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
|
||||
/* use specified dispbase */
|
||||
int BKE_mesh_nurbs_displist_to_mdata(const Object *ob,
|
||||
const ListBase *dispbase,
|
||||
MVert **r_allvert,
|
||||
int *r_totvert,
|
||||
MEdge **r_alledge,
|
||||
int *r_totedge,
|
||||
MLoop **r_allloop,
|
||||
MPoly **r_allpoly,
|
||||
MLoopUV **r_alluv,
|
||||
int *r_totloop,
|
||||
int *r_totpoly)
|
||||
static int mesh_nurbs_displist_to_mdata(const Curve *cu,
|
||||
const ListBase *dispbase,
|
||||
MVert **r_allvert,
|
||||
int *r_totvert,
|
||||
MEdge **r_alledge,
|
||||
int *r_totedge,
|
||||
MLoop **r_allloop,
|
||||
MPoly **r_allpoly,
|
||||
MLoopUV **r_alluv,
|
||||
int *r_totloop,
|
||||
int *r_totpoly)
|
||||
{
|
||||
const Curve *cu = ob->data;
|
||||
MVert *mvert;
|
||||
MPoly *mpoly;
|
||||
MLoop *mloop;
|
||||
|
@ -272,7 +237,7 @@ int BKE_mesh_nurbs_displist_to_mdata(const Object *ob,
|
|||
/* 2d polys are filled with DL_INDEX3 displists */
|
||||
(CU_DO_2DFILL(cu) == false) ||
|
||||
/* surf polys are never filled */
|
||||
(ob->type == OB_SURF));
|
||||
BKE_curve_type_get(cu) == OB_SURF);
|
||||
|
||||
/* count */
|
||||
LISTBASE_FOREACH (const DispList *, dl, dispbase) {
|
||||
|
@ -527,17 +492,17 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *
|
|||
MLoopUV *alluv = NULL;
|
||||
int totvert, totedge, totloop, totpoly;
|
||||
|
||||
if (BKE_mesh_nurbs_displist_to_mdata(ob,
|
||||
dispbase,
|
||||
&allvert,
|
||||
&totvert,
|
||||
&alledge,
|
||||
&totedge,
|
||||
&allloop,
|
||||
&allpoly,
|
||||
&alluv,
|
||||
&totloop,
|
||||
&totpoly) != 0) {
|
||||
if (mesh_nurbs_displist_to_mdata(ob->data,
|
||||
dispbase,
|
||||
&allvert,
|
||||
&totvert,
|
||||
&alledge,
|
||||
&totedge,
|
||||
&allloop,
|
||||
&allpoly,
|
||||
&alluv,
|
||||
&totloop,
|
||||
&totpoly) != 0) {
|
||||
/* Error initializing mdata. This often happens when curve is empty */
|
||||
return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
|
||||
}
|
||||
|
@ -571,7 +536,7 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *
|
|||
return mesh;
|
||||
}
|
||||
|
||||
Mesh *BKE_mesh_new_nomain_from_curve(Object *ob)
|
||||
Mesh *BKE_mesh_new_nomain_from_curve(const Object *ob)
|
||||
{
|
||||
ListBase disp = {NULL, NULL};
|
||||
|
||||
|
@ -589,7 +554,6 @@ void BKE_mesh_from_nurbs_displist(
|
|||
Object *ob1;
|
||||
Mesh *me_eval = (Mesh *)ob->runtime.data_eval;
|
||||
Mesh *me;
|
||||
Curve *cu;
|
||||
MVert *allvert = NULL;
|
||||
MEdge *alledge = NULL;
|
||||
MLoop *allloop = NULL;
|
||||
|
@ -597,20 +561,20 @@ void BKE_mesh_from_nurbs_displist(
|
|||
MPoly *allpoly = NULL;
|
||||
int totvert, totedge, totloop, totpoly;
|
||||
|
||||
cu = ob->data;
|
||||
Curve *cu = ob->data;
|
||||
|
||||
if (me_eval == NULL) {
|
||||
if (BKE_mesh_nurbs_displist_to_mdata(ob,
|
||||
dispbase,
|
||||
&allvert,
|
||||
&totvert,
|
||||
&alledge,
|
||||
&totedge,
|
||||
&allloop,
|
||||
&allpoly,
|
||||
&alluv,
|
||||
&totloop,
|
||||
&totpoly) != 0) {
|
||||
if (mesh_nurbs_displist_to_mdata(cu,
|
||||
dispbase,
|
||||
&allvert,
|
||||
&totvert,
|
||||
&alledge,
|
||||
&totedge,
|
||||
&allloop,
|
||||
&allpoly,
|
||||
&alluv,
|
||||
&totloop,
|
||||
&totpoly) != 0) {
|
||||
/* Error initializing */
|
||||
return;
|
||||
}
|
||||
|
@ -702,18 +666,6 @@ void BKE_mesh_from_nurbs_displist(
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_from_nurbs(Main *bmain, Object *ob)
|
||||
{
|
||||
Curve *cu = (Curve *)ob->data;
|
||||
ListBase disp = {NULL, NULL};
|
||||
|
||||
if (ob->runtime.curve_cache) {
|
||||
disp = ob->runtime.curve_cache->disp;
|
||||
}
|
||||
|
||||
BKE_mesh_from_nurbs_displist(bmain, ob, &disp, cu->id.name, false);
|
||||
}
|
||||
|
||||
typedef struct EdgeLink {
|
||||
struct EdgeLink *next, *prev;
|
||||
void *edge;
|
||||
|
@ -1152,8 +1104,8 @@ static Mesh *mesh_new_from_curve_type_object(Object *object)
|
|||
BKE_mesh_from_nurbs_displist(
|
||||
NULL, temp_object, &temp_object->runtime.curve_cache->disp, curve->id.name + 2, true);
|
||||
|
||||
/* BKE_mesh_from_nurbs changes the type to a mesh, check it worked. If it didn't the curve did
|
||||
* not have any segments or otherwise would have generated an empty mesh. */
|
||||
/* BKE_mesh_from_nurbs_displist changes the type to a mesh, check it worked. If it didn't
|
||||
* the curve did not have any segments or otherwise would have generated an empty mesh. */
|
||||
if (temp_object->type != OB_MESH) {
|
||||
BKE_id_free(NULL, temp_object->data);
|
||||
BKE_id_free(NULL, temp_object);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -506,7 +506,7 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
|
|||
|
||||
if (node->storage) {
|
||||
/* could be handlerized at some point, now only 1 exception still */
|
||||
if ((ELEM(ntree->type, NTREE_SHADER, NTREE_GEOMETRY)) &&
|
||||
if (ELEM(ntree->type, NTREE_SHADER, NTREE_GEOMETRY) &&
|
||||
ELEM(node->type, SH_NODE_CURVE_VEC, SH_NODE_CURVE_RGB)) {
|
||||
BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
|
||||
}
|
||||
|
@ -3143,7 +3143,7 @@ static void free_localized_node_groups(bNodeTree *ntree)
|
|||
}
|
||||
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id) {
|
||||
if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
|
||||
bNodeTree *ngroup = (bNodeTree *)node->id;
|
||||
ntreeFreeTree(ngroup);
|
||||
MEM_freeN(ngroup);
|
||||
|
@ -3335,7 +3335,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
|
|||
ltree->id.tag |= LIB_TAG_LOCALIZED;
|
||||
|
||||
LISTBASE_FOREACH (bNode *, node, <ree->nodes) {
|
||||
if ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id) {
|
||||
if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
|
||||
node->id = (ID *)ntreeLocalize((bNodeTree *)node->id);
|
||||
}
|
||||
}
|
||||
|
@ -5120,6 +5120,7 @@ static void registerGeometryNodes()
|
|||
register_node_type_geo_curve_subdivide();
|
||||
register_node_type_geo_curve_to_mesh();
|
||||
register_node_type_geo_curve_to_points();
|
||||
register_node_type_geo_curve_trim();
|
||||
register_node_type_geo_delete_geometry();
|
||||
register_node_type_geo_edge_split();
|
||||
register_node_type_geo_input_material();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -388,31 +388,12 @@ void BKE_object_batch_cache_dirty_tag(Object *ob)
|
|||
BKE_object_data_batch_cache_dirty_tag(ob->data);
|
||||
}
|
||||
|
||||
void BKE_object_data_eval_batch_cache_dirty_tag(Depsgraph *depsgraph, ID *object_data)
|
||||
{
|
||||
DEG_debug_print_eval(depsgraph, __func__, object_data->name, object_data);
|
||||
BKE_object_data_batch_cache_dirty_tag(object_data);
|
||||
}
|
||||
|
||||
void BKE_object_data_eval_batch_cache_deform_tag(Depsgraph *depsgraph, ID *object_data)
|
||||
{
|
||||
DEG_debug_print_eval(depsgraph, __func__, object_data->name, object_data);
|
||||
switch (GS(object_data->name)) {
|
||||
case ID_ME:
|
||||
BKE_mesh_batch_cache_dirty_tag((Mesh *)object_data, BKE_MESH_BATCH_DIRTY_DEFORM);
|
||||
break;
|
||||
default:
|
||||
/* Only mesh is currently supported. Fallback to dirty all for other datablocks types. */
|
||||
BKE_object_data_batch_cache_dirty_tag(object_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_object_eval_uber_data(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
||||
{
|
||||
DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob);
|
||||
BLI_assert(ob->type != OB_ARMATURE);
|
||||
BKE_object_handle_data_update(depsgraph, scene, ob);
|
||||
BKE_object_batch_cache_dirty_tag(ob);
|
||||
}
|
||||
|
||||
void BKE_object_eval_ptcache_reset(Depsgraph *depsgraph, Scene *scene, Object *object)
|
||||
|
|
|
@ -4418,12 +4418,12 @@ void psys_get_texture(
|
|||
|
||||
if ((event & mtex->mapto) & PAMAP_TIME) {
|
||||
/* the first time has to set the base value for time regardless of blend mode */
|
||||
if ((setvars & MAP_PA_TIME) == 0) {
|
||||
if ((setvars & PAMAP_TIME) == 0) {
|
||||
int flip = (mtex->timefac < 0.0f);
|
||||
float timefac = fabsf(mtex->timefac);
|
||||
ptex->time *= 1.0f - timefac;
|
||||
ptex->time += timefac * ((flip) ? 1.0f - value : value);
|
||||
setvars |= MAP_PA_TIME;
|
||||
setvars |= PAMAP_TIME;
|
||||
}
|
||||
else {
|
||||
ptex->time = texture_value_blend(def, ptex->time, value, mtex->timefac, blend);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -2105,7 +2105,7 @@ Object *BKE_scene_object_find_by_name(const Scene *scene, const char *name)
|
|||
|
||||
/**
|
||||
* Sets the active scene, mainly used when running in background mode
|
||||
* (``--scene`` command line argument).
|
||||
* (`--scene` command line argument).
|
||||
* This is also called to set the scene directly, bypassing windowing code.
|
||||
* Otherwise #WM_window_set_active_scene is used when changing scenes by the user.
|
||||
*/
|
||||
|
@ -3242,9 +3242,9 @@ void BKE_scene_multiview_filepath_get(SceneRenderView *srv, const char *filepath
|
|||
}
|
||||
|
||||
/**
|
||||
* When multiview is not used the filepath is as usual (e.g., ``Image.jpg``).
|
||||
* When multiview is not used the filepath is as usual (e.g., `Image.jpg`).
|
||||
* When multiview is on, even if only one view is enabled the view is incorporated
|
||||
* into the file name (e.g., ``Image_L.jpg``). That allows for the user to re-render
|
||||
* into the file name (e.g., `Image_L.jpg`). That allows for the user to re-render
|
||||
* individual views.
|
||||
*/
|
||||
void BKE_scene_multiview_view_filepath_get(const RenderData *rd,
|
||||
|
|
|
@ -410,7 +410,7 @@ Spline::LookupResult Spline::lookup_evaluated_length(const float length) const
|
|||
|
||||
const float *offset = std::lower_bound(lengths.begin(), lengths.end(), length);
|
||||
const int index = offset - lengths.begin();
|
||||
const int next_index = (index == this->size() - 1) ? 0 : index + 1;
|
||||
const int next_index = (index == this->evaluated_points_size() - 1) ? 0 : index + 1;
|
||||
|
||||
const float previous_length = (index == 0) ? 0.0f : lengths[index - 1];
|
||||
const float factor = (length - previous_length) / (lengths[index] - previous_length);
|
||||
|
|
|
@ -58,7 +58,7 @@ void _bli_array_grow_func(void **arr_p,
|
|||
/** \name Public defines
|
||||
* \{ */
|
||||
|
||||
/** use ``sizeof(*(arr))`` to ensure the array exists and is an array */
|
||||
/** use `sizeof(*(arr))` to ensure the array exists and is an array */
|
||||
#define BLI_array_declare(arr) \
|
||||
int _##arr##_len = ((void)(sizeof(*(arr))), 0); \
|
||||
void *_##arr##_static = NULL
|
||||
|
|
|
@ -34,11 +34,11 @@ namespace blender {
|
|||
* Usage:
|
||||
*
|
||||
* Convert a theme byte color to a linearrgb premultiplied.
|
||||
* ```
|
||||
* \code{.cc}
|
||||
* ColorTheme4b theme_color;
|
||||
* ColorSceneLinear4f<eAlpha::Premultiplied> linearrgb_color =
|
||||
* BLI_color_convert_to_scene_linear(theme_color).premultiply_alpha();
|
||||
* ```
|
||||
* \endcode
|
||||
*
|
||||
* The API is structured to make most use of inlining. Most notable are space
|
||||
* conversions done via `BLI_color_convert_to*` functions.
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
|
||||
/**
|
||||
* CHECK_TYPE_ANY: handy macro, eg:
|
||||
* ``CHECK_TYPE_ANY(var, Foo *, Bar *, Baz *)``
|
||||
* `CHECK_TYPE_ANY(var, Foo *, Bar *, Baz *)`
|
||||
*
|
||||
* excuse ridiculously long generated args.
|
||||
* \code{.py}
|
||||
|
|
|
@ -110,6 +110,10 @@ extern "C" {
|
|||
* If zero is supplied for epsilon, an internal value of 1e-8 used
|
||||
* instead, since this code will not work correctly if it is not allowed
|
||||
* to merge "too near" vertices.
|
||||
*
|
||||
* Normally the output will contain mappings from outputs to inputs.
|
||||
* If this is not needed, set need_ids to false and the execution may be much
|
||||
* faster in some circumstances.
|
||||
*/
|
||||
typedef struct CDT_input {
|
||||
int verts_len;
|
||||
|
@ -121,6 +125,7 @@ typedef struct CDT_input {
|
|||
int *faces_start_table;
|
||||
int *faces_len_table;
|
||||
float epsilon;
|
||||
bool need_ids;
|
||||
} CDT_input;
|
||||
|
||||
/**
|
||||
|
@ -140,6 +145,7 @@ typedef struct CDT_input {
|
|||
* a run-together array and a "start" and "len" extra array,
|
||||
* similar triples are used to represent the output to input
|
||||
* mapping of vertices, edges, and faces.
|
||||
* These are only set if need_ids is true in the input.
|
||||
*
|
||||
* Those triples are:
|
||||
* - verts_orig, verts_orig_start_table, verts_orig_len_table
|
||||
|
@ -236,6 +242,7 @@ template<typename Arith_t> class CDT_input {
|
|||
Array<std::pair<int, int>> edge;
|
||||
Array<Vector<int>> face;
|
||||
Arith_t epsilon{0};
|
||||
bool need_ids{true};
|
||||
};
|
||||
|
||||
template<typename Arith_t> class CDT_result {
|
||||
|
@ -243,6 +250,7 @@ template<typename Arith_t> class CDT_result {
|
|||
Array<vec2<Arith_t>> vert;
|
||||
Array<std::pair<int, int>> edge;
|
||||
Array<Vector<int>> face;
|
||||
/* The orig vectors are only populated if the need_ids input field is true. */
|
||||
/** For each output vert, which input verts correspond to it? */
|
||||
Array<Vector<int>> vert_orig;
|
||||
/**
|
||||
|
|
|
@ -111,20 +111,22 @@ void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree);
|
|||
/* Searching ------------------------------------ */
|
||||
|
||||
/* Find the node which matches or is the closest to the requested node */
|
||||
DLRBT_Node *BLI_dlrbTree_search(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data);
|
||||
DLRBT_Node *BLI_dlrbTree_search(const DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
void *search_data);
|
||||
|
||||
/* Find the node which exactly matches the required data */
|
||||
DLRBT_Node *BLI_dlrbTree_search_exact(DLRBT_Tree *tree,
|
||||
DLRBT_Node *BLI_dlrbTree_search_exact(const DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
void *search_data);
|
||||
|
||||
/* Find the node which occurs immediately before the best matching node */
|
||||
DLRBT_Node *BLI_dlrbTree_search_prev(DLRBT_Tree *tree,
|
||||
DLRBT_Node *BLI_dlrbTree_search_prev(const DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
void *search_data);
|
||||
|
||||
/* Find the node which occurs immediately after the best matching node */
|
||||
DLRBT_Node *BLI_dlrbTree_search_next(DLRBT_Tree *tree,
|
||||
DLRBT_Node *BLI_dlrbTree_search_next(const DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
void *search_data);
|
||||
|
||||
|
@ -137,7 +139,8 @@ short BLI_dlrbTree_contains(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *
|
|||
*/
|
||||
|
||||
/* Add the given data to the tree, and return the node added */
|
||||
// NOTE: for duplicates, the update_cb is called (if available), and the existing node is returned
|
||||
/* NOTE: for duplicates, the update_cb is called (if available),
|
||||
* and the existing node is returned. */
|
||||
DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
DLRBT_NAlloc_FP new_cb,
|
||||
|
@ -145,7 +148,7 @@ DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree,
|
|||
void *data);
|
||||
|
||||
/* Remove the given element from the tree and balance again */
|
||||
// FIXME: this is not implemented yet...
|
||||
/* FIXME: this is not implemented yet... */
|
||||
// void BLI_dlrbTree_remove(DLRBT_Tree *tree, DLRBT_Node *node);
|
||||
|
||||
/* Node Operations (Manual) --------------------- */
|
||||
|
|
|
@ -77,7 +77,7 @@ enum {
|
|||
/* -------------------------------------------------------------------- */
|
||||
/** \name GHash API
|
||||
*
|
||||
* Defined in ``BLI_ghash.c``
|
||||
* Defined in `BLI_ghash.c`
|
||||
* \{ */
|
||||
|
||||
GHash *BLI_ghash_new_ex(GHashHashFP hashfp,
|
||||
|
@ -333,11 +333,11 @@ double BLI_gset_calc_quality(GSet *gs);
|
|||
/* -------------------------------------------------------------------- */
|
||||
/** \name GHash/GSet Utils
|
||||
*
|
||||
* Defined in ``BLI_ghash_utils.c``
|
||||
* Defined in `BLI_ghash_utils.c`
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Callbacks for GHash (``BLI_ghashutil_``)
|
||||
* Callbacks for GHash (`BLI_ghashutil_`)
|
||||
*
|
||||
* \note '_p' suffix denotes void pointer arg,
|
||||
* so we can have functions that take correctly typed args too.
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* \ingroup bli
|
||||
* \brief Single link-list utility macros. (header only api).
|
||||
*
|
||||
* Use this api when the structure defines its own ``next`` pointer
|
||||
* Use this api when the structure defines its own `next` pointer
|
||||
* and a double linked list such as #ListBase isn't needed.
|
||||
*/
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* \note These macros follow STACK_* macros defined in 'BLI_utildefines.h'
|
||||
* and should be kept (mostly) interchangeable.
|
||||
*
|
||||
* \note ``_##var##_type`` is a dummy variable only used for typechecks.
|
||||
* \note `_##var##_type` is a dummy variable only used for type-checks.
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -26,32 +26,32 @@
|
|||
*
|
||||
* \section mathabbrev Abbreviations
|
||||
*
|
||||
* - ``fl`` = float
|
||||
* - ``db`` = double
|
||||
* - ``v2`` = vec2 = vector 2
|
||||
* - ``v3`` = vec3 = vector 3
|
||||
* - ``v4`` = vec4 = vector 4
|
||||
* - ``vn`` = vec4 = vector N dimensions, *passed as an arg, after the vector*.
|
||||
* - ``qt`` = quat = quaternion
|
||||
* - ``dq`` = dquat = dual quaternion
|
||||
* - ``m2`` = mat2 = matrix 2x2
|
||||
* - ``m3`` = mat3 = matrix 3x3
|
||||
* - ``m4`` = mat4 = matrix 4x4
|
||||
* - ``eul`` = euler rotation
|
||||
* - ``eulO`` = euler with order
|
||||
* - ``plane`` = plane 4, (vec3, distance)
|
||||
* - ``plane3`` = plane 3 (same as a ``plane`` with a zero 4th component)
|
||||
* - `fl` = float
|
||||
* - `db` = double
|
||||
* - `v2` = vec2 = vector 2
|
||||
* - `v3` = vec3 = vector 3
|
||||
* - `v4` = vec4 = vector 4
|
||||
* - `vn` = vec4 = vector N dimensions, *passed as an arg, after the vector*.
|
||||
* - `qt` = quat = quaternion
|
||||
* - `dq` = dquat = dual quaternion
|
||||
* - `m2` = mat2 = matrix 2x2
|
||||
* - `m3` = mat3 = matrix 3x3
|
||||
* - `m4` = mat4 = matrix 4x4
|
||||
* - `eul` = euler rotation
|
||||
* - `eulO` = euler with order
|
||||
* - `plane` = plane 4, (vec3, distance)
|
||||
* - `plane3` = plane 3 (same as a `plane` with a zero 4th component)
|
||||
*
|
||||
* \subsection mathabbrev_all Function Type Abbreviations
|
||||
*
|
||||
* For non float versions of functions (which typically operate on floats),
|
||||
* use single suffix abbreviations.
|
||||
*
|
||||
* - ``_d`` = double
|
||||
* - ``_i`` = int
|
||||
* - ``_u`` = unsigned int
|
||||
* - ``_char`` = char
|
||||
* - ``_uchar`` = unsigned char
|
||||
* - `_d` = double
|
||||
* - `_i` = int
|
||||
* - `_u` = unsigned int
|
||||
* - `_char` = char
|
||||
* - `_uchar` = unsigned char
|
||||
*
|
||||
* \section mathvarnames Variable Names
|
||||
*
|
||||
|
|
|
@ -291,7 +291,7 @@ int BLI_dynstr_get_len(const DynStr *ds)
|
|||
/**
|
||||
* Get a DynStr's contents as a c-string.
|
||||
* The \a rets argument must be allocated to be at
|
||||
* least the size of ``BLI_dynstr_get_len(ds) + 1``.
|
||||
* least the size of `BLI_dynstr_get_len(ds) + 1`.
|
||||
*
|
||||
* \param ds: The DynStr of interest.
|
||||
* \param rets: The string to fill.
|
||||
|
|
|
@ -1270,7 +1270,7 @@ void BLI_gset_flag_clear(GSet *gs, uint flag)
|
|||
/* -------------------------------------------------------------------- */
|
||||
/** \name GSet Combined Key/Value Usage
|
||||
*
|
||||
* \note Not typical ``set`` use, only use when the pointer identity matters.
|
||||
* \note Not typical `set` use, only use when the pointer identity matters.
|
||||
* This can be useful when the key references data stored outside the GSet.
|
||||
* \{ */
|
||||
|
||||
|
|
|
@ -138,8 +138,8 @@ size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
|
|||
* This function implements the widely used "djb" hash apparently posted
|
||||
* by Daniel Bernstein to comp.lang.c some time ago. The 32 bit
|
||||
* unsigned hash value starts at 5381 and for each byte 'c' in the
|
||||
* string, is updated: ``hash = hash * 33 + c``. This
|
||||
* function uses the signed value of each byte.
|
||||
* string, is updated: `hash = hash * 33 + c`.
|
||||
* This function uses the signed value of each byte.
|
||||
*
|
||||
* NOTE: this is the same hash method that glib 2.34.0 uses.
|
||||
*/
|
||||
|
|
|
@ -868,7 +868,7 @@ static void non_recursive_bvh_div_nodes(const BVHTree *tree,
|
|||
* \{ */
|
||||
|
||||
/**
|
||||
* \note many callers don't check for ``NULL`` return.
|
||||
* \note many callers don't check for `NULL` return.
|
||||
*/
|
||||
BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
|
||||
{
|
||||
|
|
|
@ -73,7 +73,7 @@ typedef struct BLI_memiter_chunk {
|
|||
struct BLI_memiter_chunk *next;
|
||||
/**
|
||||
* internal format is:
|
||||
* ``[next_pointer, size:data, size:data, ..., negative_offset]``
|
||||
* `[next_pointer, size:data, size:data, ..., negative_offset]`
|
||||
*
|
||||
* Where negative offset rewinds to the start.
|
||||
*/
|
||||
|
|
|
@ -63,9 +63,9 @@
|
|||
#endif
|
||||
|
||||
/**
|
||||
* Important that this value is an is _not_ aligned with ``sizeof(void *)``.
|
||||
* Important that this value is an is _not_ aligned with `sizeof(void *)`.
|
||||
* So having a pointer to 2/4/8... aligned memory is enough to ensure
|
||||
* the freeword will never be used.
|
||||
* the `freeword` will never be used.
|
||||
* To be safe, use a word that's the same in both directions.
|
||||
*/
|
||||
#define FREEWORD \
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
#ifndef WIN32
|
||||
# include <signal.h>
|
||||
# include <stdlib.h>
|
||||
# include <sys/mman.h> // for mmap
|
||||
# include <unistd.h> // for read close
|
||||
# include <sys/mman.h> /* For mmap. */
|
||||
# include <unistd.h> /* For read close. */
|
||||
#else
|
||||
# include "BLI_winstuff.h"
|
||||
# include <io.h> // for open close read
|
||||
# include <io.h> /* For open close read. */
|
||||
#endif
|
||||
|
||||
struct BLI_mmap_file {
|
||||
|
|
|
@ -128,7 +128,9 @@ void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree)
|
|||
/* Tree Search Utilities */
|
||||
|
||||
/* Find the node which matches or is the closest to the requested node */
|
||||
DLRBT_Node *BLI_dlrbTree_search(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
|
||||
DLRBT_Node *BLI_dlrbTree_search(const DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
void *search_data)
|
||||
{
|
||||
DLRBT_Node *node = (tree) ? tree->root : NULL;
|
||||
short found = 0;
|
||||
|
@ -174,7 +176,7 @@ DLRBT_Node *BLI_dlrbTree_search(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, vo
|
|||
}
|
||||
|
||||
/* Find the node which exactly matches the required data */
|
||||
DLRBT_Node *BLI_dlrbTree_search_exact(DLRBT_Tree *tree,
|
||||
DLRBT_Node *BLI_dlrbTree_search_exact(const DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
void *search_data)
|
||||
{
|
||||
|
@ -222,7 +224,7 @@ DLRBT_Node *BLI_dlrbTree_search_exact(DLRBT_Tree *tree,
|
|||
}
|
||||
|
||||
/* Find the node which occurs immediately before the best matching node */
|
||||
DLRBT_Node *BLI_dlrbTree_search_prev(DLRBT_Tree *tree,
|
||||
DLRBT_Node *BLI_dlrbTree_search_prev(const DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
void *search_data)
|
||||
{
|
||||
|
@ -253,7 +255,7 @@ DLRBT_Node *BLI_dlrbTree_search_prev(DLRBT_Tree *tree,
|
|||
}
|
||||
|
||||
/* Find the node which occurs immediately after the best matching node */
|
||||
DLRBT_Node *BLI_dlrbTree_search_next(DLRBT_Tree *tree,
|
||||
DLRBT_Node *BLI_dlrbTree_search_next(const DLRBT_Tree *tree,
|
||||
DLRBT_Comparator_FP cmp_cb,
|
||||
void *search_data)
|
||||
{
|
||||
|
|
|
@ -1403,16 +1403,16 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info,
|
|||
* Create a new array store, which can store any number of arrays
|
||||
* as long as their stride matches.
|
||||
*
|
||||
* \param stride: ``sizeof()`` each element,
|
||||
* \param stride: `sizeof()` each element,
|
||||
*
|
||||
* \note while a stride of ``1`` will always work,
|
||||
* \note while a stride of `1` will always work,
|
||||
* its less efficient since duplicate chunks of memory will be searched
|
||||
* at positions unaligned with the array data.
|
||||
*
|
||||
* \param chunk_count: Number of elements to split each chunk into.
|
||||
* - A small value increases the ability to de-duplicate chunks,
|
||||
* but adds overhead by increasing the number of chunks to look up when searching for duplicates,
|
||||
* as well as some overhead constructing the original array again, with more calls to ``memcpy``.
|
||||
* as well as some overhead constructing the original array again, with more calls to `memcpy`.
|
||||
* - Larger values reduce the *book keeping* overhead,
|
||||
* but increase the chance a small,
|
||||
* isolated change will cause a larger amount of data to be duplicated.
|
||||
|
|
|
@ -188,7 +188,7 @@ static int pointref_cmp_yx(const void *a_, const void *b_)
|
|||
* \param points: An array of 2D points.
|
||||
* \param n: The number of points in points.
|
||||
* \param r_points: An array of the convex hull vertex indices (max is n).
|
||||
* _must_ be allocated as ``n * 2`` because of how its used internally,
|
||||
* _must_ be allocated as `n * 2` because of how its used internally,
|
||||
* even though the final result will be no more than \a n in size.
|
||||
* \returns the number of points in r_points.
|
||||
*/
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
@ -29,6 +30,8 @@
|
|||
#include "BLI_math_boolean.hh"
|
||||
#include "BLI_math_mpq.hh"
|
||||
#include "BLI_mpq2.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_task.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BLI_delaunay_2d.h"
|
||||
|
@ -77,8 +80,8 @@ template<> double math_to_double<double>(const double v)
|
|||
* Define a templated 2D arrangement of vertices, edges, and faces.
|
||||
* The #SymEdge data structure is the basis for a structure that allows
|
||||
* easy traversal to neighboring (by topology) geometric elements.
|
||||
* Each of #CDTVert, #CDTEdge, and #CDTFace have an input_id linked list,
|
||||
* whose nodes contain integers that keep track of which input verts, edges,
|
||||
* Each of #CDTVert, #CDTEdge, and #CDTFace have an input_id set,
|
||||
* which contain integers that keep track of which input verts, edges,
|
||||
* and faces, respectively, that the element was derived from.
|
||||
*
|
||||
* While this could be cleaned up some, it is usable by other routines in Blender
|
||||
|
@ -195,8 +198,8 @@ template<typename T> struct CDTVert {
|
|||
FatCo<T> co;
|
||||
/** Some edge attached to it. */
|
||||
SymEdge<T> *symedge{nullptr};
|
||||
/** List of corresponding vertex input ids. */
|
||||
LinkNode *input_ids{nullptr};
|
||||
/** Set of corresponding vertex input ids. Not used if don't need_ids. */
|
||||
blender::Set<int> input_ids;
|
||||
/** Index into array that #CDTArrangement keeps. */
|
||||
int index{-1};
|
||||
/** Index of a CDTVert that this has merged to. -1 if no merge. */
|
||||
|
@ -209,8 +212,10 @@ template<typename T> struct CDTVert {
|
|||
};
|
||||
|
||||
template<typename Arith_t> struct CDTEdge {
|
||||
/** List of input edge ids that this is part of. */
|
||||
LinkNode *input_ids{nullptr};
|
||||
/** Set of input edge ids that this is part of.
|
||||
* If don't need_ids, then should contain 0 if it is a constrained edge,
|
||||
* else empty. */
|
||||
blender::Set<int> input_ids;
|
||||
/** The directed edges for this edge. */
|
||||
SymEdge<Arith_t> symedges[2]{SymEdge<Arith_t>(), SymEdge<Arith_t>()};
|
||||
|
||||
|
@ -220,8 +225,10 @@ template<typename Arith_t> struct CDTEdge {
|
|||
template<typename Arith_t> struct CDTFace {
|
||||
/** A symedge in face; only used during output, so only valid then. */
|
||||
SymEdge<Arith_t> *symedge{nullptr};
|
||||
/** List of input face ids that this is part of. */
|
||||
LinkNode *input_ids{nullptr};
|
||||
/** Set of input face ids that this is part of.
|
||||
* If don't need_ids, then should contain 0 if it is part of a constrained face,
|
||||
* else empty. */
|
||||
blender::Set<int> input_ids;
|
||||
/** Used by algorithms operating on CDT structures. */
|
||||
int visit_index{0};
|
||||
/** Marks this face no longer used. */
|
||||
|
@ -334,27 +341,30 @@ template<typename T> class CDT_state {
|
|||
int face_edge_offset;
|
||||
/** How close before coords considered equal. */
|
||||
T epsilon;
|
||||
/** Do we need to track ids? */
|
||||
bool need_ids;
|
||||
|
||||
explicit CDT_state(int num_input_verts, int num_input_edges, int num_input_faces, T epsilon);
|
||||
explicit CDT_state(
|
||||
int num_input_verts, int num_input_edges, int num_input_faces, T epsilon, bool need_ids);
|
||||
};
|
||||
|
||||
template<typename T> CDTArrangement<T>::~CDTArrangement()
|
||||
{
|
||||
for (int i : this->verts.index_range()) {
|
||||
CDTVert<T> *v = this->verts[i];
|
||||
BLI_linklist_free(v->input_ids, nullptr);
|
||||
v->input_ids.clear();
|
||||
delete v;
|
||||
this->verts[i] = nullptr;
|
||||
}
|
||||
for (int i : this->edges.index_range()) {
|
||||
CDTEdge<T> *e = this->edges[i];
|
||||
BLI_linklist_free(e->input_ids, nullptr);
|
||||
e->input_ids.clear();
|
||||
delete e;
|
||||
this->edges[i] = nullptr;
|
||||
}
|
||||
for (int i : this->faces.index_range()) {
|
||||
CDTFace<T> *f = this->faces[i];
|
||||
BLI_linklist_free(f->input_ids, nullptr);
|
||||
f->input_ids.clear();
|
||||
delete f;
|
||||
this->faces[i] = nullptr;
|
||||
}
|
||||
|
@ -431,11 +441,11 @@ template<typename T> std::ostream &operator<<(std::ostream &os, const CDT_state<
|
|||
if (se) {
|
||||
os << " edges out:\n";
|
||||
do {
|
||||
if (se->next == NULL) {
|
||||
if (se->next == nullptr) {
|
||||
os << " [NULL] next/rot symedge, se=" << trunc_ptr(se) << "\n";
|
||||
break;
|
||||
}
|
||||
if (se->next->next == NULL) {
|
||||
if (se->next->next == nullptr) {
|
||||
os << " [NULL] next-next/rot symedge, se=" << trunc_ptr(se) << "\n";
|
||||
break;
|
||||
}
|
||||
|
@ -495,6 +505,7 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
|
|||
constexpr int vert_radius = 3;
|
||||
constexpr bool draw_vert_labels = true;
|
||||
constexpr bool draw_edge_labels = false;
|
||||
constexpr bool draw_face_labels = false;
|
||||
|
||||
if (cdt.verts.size() == 0) {
|
||||
return;
|
||||
|
@ -559,7 +570,7 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
|
|||
const CDTVert<T> *v = e->symedges[1].vert;
|
||||
const vec2<double> &uco = u->co.approx;
|
||||
const vec2<double> &vco = v->co.approx;
|
||||
int strokew = e->input_ids == nullptr ? thin_line : thick_line;
|
||||
int strokew = e->input_ids.size() == 0 ? thin_line : thick_line;
|
||||
f << R"(<line fill="none" stroke="black" stroke-width=")" << strokew << "\" x1=\""
|
||||
<< SX(uco[0]) << "\" y1=\"" << SY(uco[1]) << "\" x2=\"" << SX(vco[0]) << "\" y2=\""
|
||||
<< SY(vco[1]) << "\">\n";
|
||||
|
@ -586,6 +597,54 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
|
|||
++i;
|
||||
}
|
||||
|
||||
if (draw_face_labels) {
|
||||
for (const CDTFace<T> *face : cdt.faces) {
|
||||
if (!face->deleted) {
|
||||
/* Since may not have prepared output yet, need a slow find of a SymEdge for this face. */
|
||||
const SymEdge<T> *se_face_start = nullptr;
|
||||
for (const CDTEdge<T> *e : cdt.edges) {
|
||||
if (e->symedges[0].face == face) {
|
||||
se_face_start = &e->symedges[0];
|
||||
break;
|
||||
}
|
||||
if (e->symedges[1].face == face) {
|
||||
se_face_start = &e->symedges[1];
|
||||
}
|
||||
}
|
||||
if (se_face_start != nullptr) {
|
||||
/* Find center of face. */
|
||||
int face_nverts = 0;
|
||||
vec2<double> cen(0.0, 0.0);
|
||||
if (face == cdt.outer_face) {
|
||||
cen.x = minx;
|
||||
cen.y = miny;
|
||||
}
|
||||
else {
|
||||
const SymEdge<T> *se = se_face_start;
|
||||
do {
|
||||
if (se->face == face) {
|
||||
cen = cen + se->vert->co.approx;
|
||||
face_nverts++;
|
||||
}
|
||||
} while ((se = se->next) != se_face_start);
|
||||
if (face_nverts > 0) {
|
||||
cen = cen / double(face_nverts);
|
||||
}
|
||||
}
|
||||
f << "<text x=\"" << SX(cen[0]) << "\" y=\"" << SY(cen[1]) << "\""
|
||||
<< " font-size=\"small\">[";
|
||||
f << trunc_ptr(face);
|
||||
if (face->input_ids.size() > 0) {
|
||||
for (int id : face->input_ids) {
|
||||
f << " " << id;
|
||||
}
|
||||
}
|
||||
f << "]</text>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
append = true;
|
||||
# undef SX
|
||||
# undef SY
|
||||
|
@ -754,7 +813,6 @@ template<> CDTVert<double>::CDTVert(const vec2<double> &pt)
|
|||
this->co.exact = pt;
|
||||
this->co.approx = pt;
|
||||
this->co.abs_approx = pt; /* Not used, so doesn't matter. */
|
||||
this->input_ids = nullptr;
|
||||
this->symedge = nullptr;
|
||||
this->index = -1;
|
||||
this->merge_to_index = -1;
|
||||
|
@ -767,7 +825,6 @@ template<> CDTVert<mpq_class>::CDTVert(const vec2<mpq_class> &pt)
|
|||
this->co.exact = pt;
|
||||
this->co.approx = double2(pt.x.get_d(), pt.y.get_d());
|
||||
this->co.abs_approx = double2(fabs(this->co.approx.x), fabs(this->co.approx.y));
|
||||
this->input_ids = nullptr;
|
||||
this->symedge = nullptr;
|
||||
this->index = -1;
|
||||
this->merge_to_index = -1;
|
||||
|
@ -824,35 +881,21 @@ template<typename T> void CDTArrangement<T>::reserve(int num_verts, int num_edge
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
CDT_state<T>::CDT_state(int num_input_verts, int num_input_edges, int num_input_faces, T epsilon)
|
||||
CDT_state<T>::CDT_state(
|
||||
int num_input_verts, int num_input_edges, int num_input_faces, T epsilon, bool need_ids)
|
||||
{
|
||||
this->input_vert_tot = num_input_verts;
|
||||
this->cdt.reserve(num_input_verts, num_input_edges, num_input_faces);
|
||||
this->cdt.outer_face = this->cdt.add_face();
|
||||
this->epsilon = epsilon;
|
||||
this->need_ids = need_ids;
|
||||
this->visit_count = 0;
|
||||
}
|
||||
|
||||
static bool id_in_list(const LinkNode *id_list, int id)
|
||||
{
|
||||
const LinkNode *ln;
|
||||
|
||||
for (ln = id_list; ln != nullptr; ln = ln->next) {
|
||||
if (POINTER_AS_INT(ln->link) == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Is any id in (range_start, range_start+1, ... , range_end) in id_list? */
|
||||
static bool id_range_in_list(const LinkNode *id_list, int range_start, int range_end)
|
||||
static bool id_range_in_list(const blender::Set<int> &id_list, int range_start, int range_end)
|
||||
{
|
||||
const LinkNode *ln;
|
||||
int id;
|
||||
|
||||
for (ln = id_list; ln != nullptr; ln = ln->next) {
|
||||
id = POINTER_AS_INT(ln->link);
|
||||
for (int id : id_list) {
|
||||
if (id >= range_start && id <= range_end) {
|
||||
return true;
|
||||
}
|
||||
|
@ -860,19 +903,15 @@ static bool id_range_in_list(const LinkNode *id_list, int range_start, int range
|
|||
return false;
|
||||
}
|
||||
|
||||
static void add_to_input_ids(LinkNode **dst, int input_id)
|
||||
static void add_to_input_ids(blender::Set<int> &dst, int input_id)
|
||||
{
|
||||
if (!id_in_list(*dst, input_id)) {
|
||||
BLI_linklist_prepend(dst, POINTER_FROM_INT(input_id));
|
||||
}
|
||||
dst.add(input_id);
|
||||
}
|
||||
|
||||
static void add_list_to_input_ids(LinkNode **dst, const LinkNode *src)
|
||||
static void add_list_to_input_ids(blender::Set<int> &dst, const blender::Set<int> &src)
|
||||
{
|
||||
const LinkNode *ln;
|
||||
|
||||
for (ln = src; ln != nullptr; ln = ln->next) {
|
||||
add_to_input_ids(dst, POINTER_AS_INT(ln->link));
|
||||
for (int value : src) {
|
||||
dst.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,7 +922,7 @@ template<typename T> inline bool is_border_edge(const CDTEdge<T> *e, const CDT_s
|
|||
|
||||
template<typename T> inline bool is_constrained_edge(const CDTEdge<T> *e)
|
||||
{
|
||||
return e->input_ids != nullptr;
|
||||
return e->input_ids.size() > 0;
|
||||
}
|
||||
|
||||
template<typename T> inline bool is_deleted_edge(const CDTEdge<T> *e)
|
||||
|
@ -979,7 +1018,7 @@ template<typename T> CDTEdge<T> *CDTArrangement<T>::add_diagonal(SymEdge<T> *s1,
|
|||
for (SymEdge<T> *se = s2; se != sdiag; se = se->next) {
|
||||
se->face = fnew;
|
||||
}
|
||||
add_list_to_input_ids(&fnew->input_ids, fold->input_ids);
|
||||
add_list_to_input_ids(fnew->input_ids, fold->input_ids);
|
||||
return ediag;
|
||||
}
|
||||
|
||||
|
@ -1058,7 +1097,7 @@ template<typename T> CDTEdge<T> *CDTArrangement<T>::split_edge(SymEdge<T> *se, T
|
|||
if (newsesym->vert->symedge == sesym) {
|
||||
newsesym->vert->symedge = newsesym;
|
||||
}
|
||||
add_list_to_input_ids(&e->input_ids, se->edge->input_ids);
|
||||
add_list_to_input_ids(e->input_ids, se->edge->input_ids);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -1880,7 +1919,7 @@ void add_edge_constraint(
|
|||
SymEdge<T> *t = find_symedge_between_verts(v1, v2);
|
||||
if (t != nullptr) {
|
||||
/* Segment already there. */
|
||||
add_to_input_ids(&t->edge->input_ids, input_id);
|
||||
add_to_input_ids(t->edge->input_ids, input_id);
|
||||
if (r_edges != nullptr) {
|
||||
BLI_linklist_append(&edge_list, t->edge);
|
||||
*r_edges = edge_list.list;
|
||||
|
@ -2041,7 +2080,7 @@ void add_edge_constraint(
|
|||
BLI_assert(cd_prev->lambda == 0.0);
|
||||
BLI_assert(cd_prev->out->next->vert == cd->vert);
|
||||
edge = cd_prev->out->edge;
|
||||
add_to_input_ids(&edge->input_ids, input_id);
|
||||
add_to_input_ids(edge->input_ids, input_id);
|
||||
if (r_edges != nullptr) {
|
||||
BLI_linklist_append(&edge_list, edge);
|
||||
}
|
||||
|
@ -2054,7 +2093,7 @@ void add_edge_constraint(
|
|||
else {
|
||||
edge = cdt_state->cdt.add_diagonal(tstart, t);
|
||||
}
|
||||
add_to_input_ids(&edge->input_ids, input_id);
|
||||
add_to_input_ids(edge->input_ids, input_id);
|
||||
if (r_edges != nullptr) {
|
||||
BLI_linklist_append(&edge_list, edge);
|
||||
}
|
||||
|
@ -2093,7 +2132,8 @@ template<typename T> void add_edge_constraints(CDT_state<T> *cdt_state, const CD
|
|||
}
|
||||
CDTVert<T> *v1 = cdt_state->cdt.get_vert_resolve_merge(iv1);
|
||||
CDTVert<T> *v2 = cdt_state->cdt.get_vert_resolve_merge(iv2);
|
||||
add_edge_constraint(cdt_state, v1, v2, i, nullptr);
|
||||
int id = cdt_state->need_ids ? i : 0;
|
||||
add_edge_constraint(cdt_state, v1, v2, id, nullptr);
|
||||
}
|
||||
cdt_state->face_edge_offset = ne;
|
||||
}
|
||||
|
@ -2132,7 +2172,7 @@ void add_face_ids(
|
|||
continue;
|
||||
}
|
||||
face->visit_index = visit;
|
||||
add_to_input_ids(&face->input_ids, face_id);
|
||||
add_to_input_ids(face->input_ids, face_id);
|
||||
SymEdge<T> *se_start = se;
|
||||
for (se = se->next; se != se_start; se = se->next) {
|
||||
if (!id_range_in_list(se->edge->input_ids, fedge_start, fedge_end)) {
|
||||
|
@ -2206,7 +2246,8 @@ template<typename T> void add_face_constraints(CDT_state<T> *cdt_state, const CD
|
|||
CDTVert<T> *v1 = cdt->get_vert_resolve_merge(iv1);
|
||||
CDTVert<T> *v2 = cdt->get_vert_resolve_merge(iv2);
|
||||
LinkNode *edge_list;
|
||||
add_edge_constraint(cdt_state, v1, v2, face_edge_id, &edge_list);
|
||||
int id = cdt_state->need_ids ? face_edge_id : 0;
|
||||
add_edge_constraint(cdt_state, v1, v2, id, &edge_list);
|
||||
/* Set a new face_symedge0 each time since earlier ones may not
|
||||
* survive later symedge splits. Really, just want the one when
|
||||
* i == flen -1, but this code guards against that one somehow
|
||||
|
@ -2224,7 +2265,8 @@ template<typename T> void add_face_constraints(CDT_state<T> *cdt_state, const CD
|
|||
}
|
||||
int fedge_end = fedge_start + flen - 1;
|
||||
if (face_symedge0 != nullptr) {
|
||||
add_face_ids(cdt_state, face_symedge0, f, fedge_start, fedge_end);
|
||||
int id = cdt_state->need_ids ? f : 0;
|
||||
add_face_ids(cdt_state, face_symedge0, id, fedge_start, fedge_end);
|
||||
}
|
||||
fstart += flen;
|
||||
}
|
||||
|
@ -2349,7 +2391,7 @@ template<typename T> void remove_non_constraint_edges_leave_valid_bmesh(CDT_stat
|
|||
CDTFace<T> *fleft = se->face;
|
||||
CDTFace<T> *fright = sym(se)->face;
|
||||
if (fleft != cdt->outer_face && fright != cdt->outer_face &&
|
||||
(fleft->input_ids != nullptr || fright->input_ids != nullptr)) {
|
||||
(fleft->input_ids.size() > 0 || fright->input_ids.size() > 0)) {
|
||||
/* Is there another #SymEdge with same left and right faces?
|
||||
* Or is there a vertex not part of e touching the same left and right faces? */
|
||||
for (SymEdge<T> *se2 = se->next; dissolve && se2 != se; se2 = se2->next) {
|
||||
|
@ -2507,30 +2549,33 @@ template<typename T> void detect_holes(CDT_state<T> *cdt_state)
|
|||
mid.exact[1] = (f->symedge->vert->co.exact[1] + f->symedge->next->vert->co.exact[1] +
|
||||
f->symedge->next->next->vert->co.exact[1]) /
|
||||
3;
|
||||
int hits = 0;
|
||||
std::atomic<int> hits = 0;
|
||||
/* TODO: Use CDT data structure here to greatly reduce search for intersections! */
|
||||
for (const CDTEdge<T> *e : cdt->edges) {
|
||||
if (!is_deleted_edge(e) && is_constrained_edge(e)) {
|
||||
if (e->symedges[0].face->visit_index == e->symedges[1].face->visit_index) {
|
||||
continue; /* Don't count hits on edges between faces in same region. */
|
||||
}
|
||||
auto isect = vec2<T>::isect_seg_seg(ray_end.exact,
|
||||
mid.exact,
|
||||
e->symedges[0].vert->co.exact,
|
||||
e->symedges[1].vert->co.exact);
|
||||
switch (isect.kind) {
|
||||
case vec2<T>::isect_result::LINE_LINE_CROSS: {
|
||||
hits++;
|
||||
break;
|
||||
threading::parallel_for(cdt->edges.index_range(), 256, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
const CDTEdge<T> *e = cdt->edges[i];
|
||||
if (!is_deleted_edge(e) && is_constrained_edge(e)) {
|
||||
if (e->symedges[0].face->visit_index == e->symedges[1].face->visit_index) {
|
||||
continue; /* Don't count hits on edges between faces in same region. */
|
||||
}
|
||||
auto isect = vec2<T>::isect_seg_seg(ray_end.exact,
|
||||
mid.exact,
|
||||
e->symedges[0].vert->co.exact,
|
||||
e->symedges[1].vert->co.exact);
|
||||
switch (isect.kind) {
|
||||
case vec2<T>::isect_result::LINE_LINE_CROSS: {
|
||||
hits++;
|
||||
break;
|
||||
}
|
||||
case vec2<T>::isect_result::LINE_LINE_EXACT:
|
||||
case vec2<T>::isect_result::LINE_LINE_NONE:
|
||||
case vec2<T>::isect_result::LINE_LINE_COLINEAR:
|
||||
break;
|
||||
}
|
||||
case vec2<T>::isect_result::LINE_LINE_EXACT:
|
||||
case vec2<T>::isect_result::LINE_LINE_NONE:
|
||||
case vec2<T>::isect_result::LINE_LINE_COLINEAR:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
f->hole = (hits % 2) == 0;
|
||||
});
|
||||
f->hole = (hits.load() % 2) == 0;
|
||||
}
|
||||
|
||||
/* Finally, propagate hole status to all holes of a region. */
|
||||
|
@ -2631,25 +2676,31 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
|
|||
for (int i = 0; i < verts_size; ++i) {
|
||||
CDTVert<T> *v = cdt->verts[i];
|
||||
if (v->merge_to_index != -1) {
|
||||
if (i < cdt_state->input_vert_tot) {
|
||||
add_to_input_ids(&cdt->verts[v->merge_to_index]->input_ids, i);
|
||||
if (cdt_state->need_ids) {
|
||||
if (i < cdt_state->input_vert_tot) {
|
||||
add_to_input_ids(cdt->verts[v->merge_to_index]->input_ids, i);
|
||||
}
|
||||
}
|
||||
vert_to_output_map[i] = vert_to_output_map[v->merge_to_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
result.vert = Array<vec2<T>>(nv);
|
||||
result.vert_orig = Array<Vector<int>>(nv);
|
||||
if (cdt_state->need_ids) {
|
||||
result.vert_orig = Array<Vector<int>>(nv);
|
||||
}
|
||||
int i_out = 0;
|
||||
for (int i = 0; i < verts_size; ++i) {
|
||||
CDTVert<T> *v = cdt->verts[i];
|
||||
if (v->merge_to_index == -1) {
|
||||
result.vert[i_out] = v->co.exact;
|
||||
if (i < cdt_state->input_vert_tot) {
|
||||
result.vert_orig[i_out].append(i);
|
||||
}
|
||||
for (LinkNode *ln = v->input_ids; ln; ln = ln->next) {
|
||||
result.vert_orig[i_out].append(POINTER_AS_INT(ln->link));
|
||||
if (cdt_state->need_ids) {
|
||||
if (i < cdt_state->input_vert_tot) {
|
||||
result.vert_orig[i_out].append(i);
|
||||
}
|
||||
for (int vert : v->input_ids) {
|
||||
result.vert_orig[i_out].append(vert);
|
||||
}
|
||||
}
|
||||
++i_out;
|
||||
}
|
||||
|
@ -2660,15 +2711,19 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
|
|||
return !is_deleted_edge(e);
|
||||
});
|
||||
result.edge = Array<std::pair<int, int>>(ne);
|
||||
result.edge_orig = Array<Vector<int>>(ne);
|
||||
if (cdt_state->need_ids) {
|
||||
result.edge_orig = Array<Vector<int>>(ne);
|
||||
}
|
||||
int e_out = 0;
|
||||
for (const CDTEdge<T> *e : cdt->edges) {
|
||||
if (!is_deleted_edge(e)) {
|
||||
int vo1 = vert_to_output_map[e->symedges[0].vert->index];
|
||||
int vo2 = vert_to_output_map[e->symedges[1].vert->index];
|
||||
result.edge[e_out] = std::pair<int, int>(vo1, vo2);
|
||||
for (LinkNode *ln = e->input_ids; ln; ln = ln->next) {
|
||||
result.edge_orig[e_out].append(POINTER_AS_INT(ln->link));
|
||||
if (cdt_state->need_ids) {
|
||||
for (int edge : e->input_ids) {
|
||||
result.edge_orig[e_out].append(edge);
|
||||
}
|
||||
}
|
||||
++e_out;
|
||||
}
|
||||
|
@ -2679,7 +2734,9 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
|
|||
return !f->deleted && f != cdt->outer_face;
|
||||
});
|
||||
result.face = Array<Vector<int>>(nf);
|
||||
result.face_orig = Array<Vector<int>>(nf);
|
||||
if (cdt_state->need_ids) {
|
||||
result.face_orig = Array<Vector<int>>(nf);
|
||||
}
|
||||
int f_out = 0;
|
||||
for (const CDTFace<T> *f : cdt->faces) {
|
||||
if (!f->deleted && f != cdt->outer_face) {
|
||||
|
@ -2690,8 +2747,10 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
|
|||
result.face[f_out].append(vert_to_output_map[se->vert->index]);
|
||||
se = se->next;
|
||||
} while (se != se_start);
|
||||
for (LinkNode *ln = f->input_ids; ln; ln = ln->next) {
|
||||
result.face_orig[f_out].append(POINTER_AS_INT(ln->link));
|
||||
if (cdt_state->need_ids) {
|
||||
for (int face : f->input_ids) {
|
||||
result.face_orig[f_out].append(face);
|
||||
}
|
||||
}
|
||||
++f_out;
|
||||
}
|
||||
|
@ -2716,7 +2775,7 @@ CDT_result<T> delaunay_calc(const CDT_input<T> &input, CDT_output_type output_ty
|
|||
int nv = input.vert.size();
|
||||
int ne = input.edge.size();
|
||||
int nf = input.face.size();
|
||||
CDT_state<T> cdt_state(nv, ne, nf, input.epsilon);
|
||||
CDT_state<T> cdt_state(nv, ne, nf, input.epsilon, input.need_ids);
|
||||
add_input_verts(&cdt_state, input);
|
||||
initial_triangulation(&cdt_state.cdt);
|
||||
add_edge_constraints(&cdt_state, input);
|
||||
|
@ -2772,6 +2831,7 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
|
|||
}
|
||||
}
|
||||
in.epsilon = static_cast<double>(input->epsilon);
|
||||
in.need_ids = input->need_ids;
|
||||
|
||||
blender::meshintersect::CDT_result<double> res = blender::meshintersect::delaunay_2d_calc(
|
||||
in, output_type);
|
||||
|
@ -2784,74 +2844,101 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
|
|||
int tot_e_orig = 0;
|
||||
int tot_f_orig = 0;
|
||||
int tot_f_lens = 0;
|
||||
for (int v = 0; v < nv; ++v) {
|
||||
tot_v_orig += res.vert_orig[v].size();
|
||||
}
|
||||
for (int e = 0; e < ne; ++e) {
|
||||
tot_e_orig += res.edge_orig[e].size();
|
||||
if (input->need_ids) {
|
||||
for (int v = 0; v < nv; ++v) {
|
||||
tot_v_orig += res.vert_orig[v].size();
|
||||
}
|
||||
for (int e = 0; e < ne; ++e) {
|
||||
tot_e_orig += res.edge_orig[e].size();
|
||||
}
|
||||
}
|
||||
for (int f = 0; f < nf; ++f) {
|
||||
tot_f_orig += res.face_orig[f].size();
|
||||
if (input->need_ids) {
|
||||
tot_f_orig += res.face_orig[f].size();
|
||||
}
|
||||
tot_f_lens += res.face[f].size();
|
||||
}
|
||||
|
||||
output->vert_coords = static_cast<decltype(output->vert_coords)>(
|
||||
MEM_malloc_arrayN(nv, sizeof(output->vert_coords[0]), __func__));
|
||||
output->verts_orig = static_cast<int *>(MEM_malloc_arrayN(tot_v_orig, sizeof(int), __func__));
|
||||
output->verts_orig_start_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(nv, sizeof(int), __func__));
|
||||
output->verts_orig_len_table = static_cast<int *>(MEM_malloc_arrayN(nv, sizeof(int), __func__));
|
||||
output->edges = static_cast<decltype(output->edges)>(
|
||||
MEM_malloc_arrayN(ne, sizeof(output->edges[0]), __func__));
|
||||
output->edges_orig = static_cast<int *>(MEM_malloc_arrayN(tot_e_orig, sizeof(int), __func__));
|
||||
output->edges_orig_start_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(ne, sizeof(int), __func__));
|
||||
output->edges_orig_len_table = static_cast<int *>(MEM_malloc_arrayN(ne, sizeof(int), __func__));
|
||||
output->faces = static_cast<int *>(MEM_malloc_arrayN(tot_f_lens, sizeof(int), __func__));
|
||||
output->faces_start_table = static_cast<int *>(MEM_malloc_arrayN(nf, sizeof(int), __func__));
|
||||
output->faces_len_table = static_cast<int *>(MEM_malloc_arrayN(nf, sizeof(int), __func__));
|
||||
output->faces_orig = static_cast<int *>(MEM_malloc_arrayN(tot_f_orig, sizeof(int), __func__));
|
||||
output->faces_orig_start_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(nf, sizeof(int), __func__));
|
||||
output->faces_orig_len_table = static_cast<int *>(MEM_malloc_arrayN(nf, sizeof(int), __func__));
|
||||
if (input->need_ids) {
|
||||
output->verts_orig = static_cast<int *>(MEM_malloc_arrayN(tot_v_orig, sizeof(int), __func__));
|
||||
output->verts_orig_start_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(nv, sizeof(int), __func__));
|
||||
output->verts_orig_len_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(nv, sizeof(int), __func__));
|
||||
output->edges_orig = static_cast<int *>(MEM_malloc_arrayN(tot_e_orig, sizeof(int), __func__));
|
||||
output->edges_orig_start_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(ne, sizeof(int), __func__));
|
||||
output->edges_orig_len_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(ne, sizeof(int), __func__));
|
||||
output->faces_orig = static_cast<int *>(MEM_malloc_arrayN(tot_f_orig, sizeof(int), __func__));
|
||||
output->faces_orig_start_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(nf, sizeof(int), __func__));
|
||||
output->faces_orig_len_table = static_cast<int *>(
|
||||
MEM_malloc_arrayN(nf, sizeof(int), __func__));
|
||||
}
|
||||
else {
|
||||
output->verts_orig = nullptr;
|
||||
output->verts_orig_start_table = nullptr;
|
||||
output->verts_orig_len_table = nullptr;
|
||||
output->edges_orig = nullptr;
|
||||
output->edges_orig_start_table = nullptr;
|
||||
output->edges_orig_len_table = nullptr;
|
||||
output->faces_orig = nullptr;
|
||||
output->faces_orig_start_table = nullptr;
|
||||
output->faces_orig_len_table = nullptr;
|
||||
}
|
||||
|
||||
int v_orig_index = 0;
|
||||
for (int v = 0; v < nv; ++v) {
|
||||
output->vert_coords[v][0] = static_cast<float>(res.vert[v][0]);
|
||||
output->vert_coords[v][1] = static_cast<float>(res.vert[v][1]);
|
||||
int this_start = v_orig_index;
|
||||
output->verts_orig_start_table[v] = this_start;
|
||||
for (int j : res.vert_orig[v].index_range()) {
|
||||
output->verts_orig[v_orig_index++] = res.vert_orig[v][j];
|
||||
if (input->need_ids) {
|
||||
int this_start = v_orig_index;
|
||||
output->verts_orig_start_table[v] = this_start;
|
||||
for (int j : res.vert_orig[v].index_range()) {
|
||||
output->verts_orig[v_orig_index++] = res.vert_orig[v][j];
|
||||
}
|
||||
output->verts_orig_len_table[v] = v_orig_index - this_start;
|
||||
}
|
||||
output->verts_orig_len_table[v] = v_orig_index - this_start;
|
||||
}
|
||||
int e_orig_index = 0;
|
||||
for (int e = 0; e < ne; ++e) {
|
||||
output->edges[e][0] = res.edge[e].first;
|
||||
output->edges[e][1] = res.edge[e].second;
|
||||
int this_start = e_orig_index;
|
||||
output->edges_orig_start_table[e] = this_start;
|
||||
for (int j : res.edge_orig[e].index_range()) {
|
||||
output->edges_orig[e_orig_index++] = res.edge_orig[e][j];
|
||||
if (input->need_ids) {
|
||||
int this_start = e_orig_index;
|
||||
output->edges_orig_start_table[e] = this_start;
|
||||
for (int j : res.edge_orig[e].index_range()) {
|
||||
output->edges_orig[e_orig_index++] = res.edge_orig[e][j];
|
||||
}
|
||||
output->edges_orig_len_table[e] = e_orig_index - this_start;
|
||||
}
|
||||
output->edges_orig_len_table[e] = e_orig_index - this_start;
|
||||
}
|
||||
int f_orig_index = 0;
|
||||
int f_index = 0;
|
||||
for (int f = 0; f < nf; ++f) {
|
||||
|
||||
output->faces_start_table[f] = f_index;
|
||||
int flen = res.face[f].size();
|
||||
output->faces_len_table[f] = flen;
|
||||
for (int j = 0; j < flen; ++j) {
|
||||
output->faces[f_index++] = res.face[f][j];
|
||||
}
|
||||
int this_start = f_orig_index;
|
||||
output->faces_orig_start_table[f] = this_start;
|
||||
for (int k : res.face_orig[f].index_range()) {
|
||||
output->faces_orig[f_orig_index++] = res.face_orig[f][k];
|
||||
if (input->need_ids) {
|
||||
int this_start = f_orig_index;
|
||||
output->faces_orig_start_table[f] = this_start;
|
||||
for (int k : res.face_orig[f].index_range()) {
|
||||
output->faces_orig[f_orig_index++] = res.face_orig[f][k];
|
||||
}
|
||||
output->faces_orig_len_table[f] = f_orig_index - this_start;
|
||||
}
|
||||
output->faces_orig_len_table[f] = f_orig_index - this_start;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
@ -2863,14 +2950,16 @@ extern "C" void BLI_delaunay_2d_cdt_free(::CDT_result *result)
|
|||
MEM_freeN(result->faces);
|
||||
MEM_freeN(result->faces_start_table);
|
||||
MEM_freeN(result->faces_len_table);
|
||||
MEM_freeN(result->verts_orig);
|
||||
MEM_freeN(result->verts_orig_start_table);
|
||||
MEM_freeN(result->verts_orig_len_table);
|
||||
MEM_freeN(result->edges_orig);
|
||||
MEM_freeN(result->edges_orig_start_table);
|
||||
MEM_freeN(result->edges_orig_len_table);
|
||||
MEM_freeN(result->faces_orig);
|
||||
MEM_freeN(result->faces_orig_start_table);
|
||||
MEM_freeN(result->faces_orig_len_table);
|
||||
if (result->verts_orig) {
|
||||
MEM_freeN(result->verts_orig);
|
||||
MEM_freeN(result->verts_orig_start_table);
|
||||
MEM_freeN(result->verts_orig_len_table);
|
||||
MEM_freeN(result->edges_orig);
|
||||
MEM_freeN(result->edges_orig_start_table);
|
||||
MEM_freeN(result->edges_orig_len_table);
|
||||
MEM_freeN(result->faces_orig);
|
||||
MEM_freeN(result->faces_orig_start_table);
|
||||
MEM_freeN(result->faces_orig_len_table);
|
||||
}
|
||||
MEM_freeN(result);
|
||||
}
|
||||
|
|
|
@ -410,7 +410,7 @@ MINLINE float pingpongf(float value, float scale)
|
|||
return fabsf(fractf((value - scale) / (scale * 2.0f)) * scale * 2.0f - scale);
|
||||
}
|
||||
|
||||
// Square.
|
||||
/* Square. */
|
||||
|
||||
MINLINE int square_s(short a)
|
||||
{
|
||||
|
@ -442,7 +442,7 @@ MINLINE double square_d(double a)
|
|||
return a * a;
|
||||
}
|
||||
|
||||
// Cube.
|
||||
/* Cube. */
|
||||
|
||||
MINLINE int cube_s(short a)
|
||||
{
|
||||
|
@ -474,7 +474,7 @@ MINLINE double cube_d(double a)
|
|||
return a * a * a;
|
||||
}
|
||||
|
||||
// Min/max
|
||||
/* Min/max */
|
||||
|
||||
MINLINE float min_ff(float a, float b)
|
||||
{
|
||||
|
|
|
@ -276,14 +276,14 @@ MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack)
|
|||
* https://en.wikipedia.org/wiki/Relative_luminance
|
||||
*
|
||||
* Real values are:
|
||||
* ``Y = 0.2126390059(R) + 0.7151686788(G) + 0.0721923154(B)``
|
||||
* `Y = 0.2126390059(R) + 0.7151686788(G) + 0.0721923154(B)`
|
||||
* according to: "Derivation of Basic Television Color Equations", RP 177-1993
|
||||
*
|
||||
* As this sums slightly above 1.0, the document recommends to use:
|
||||
* ``0.2126(R) + 0.7152(G) + 0.0722(B)``, as used here.
|
||||
* `0.2126(R) + 0.7152(G) + 0.0722(B)`, as used here.
|
||||
*
|
||||
* The high precision values are used to calculate the rounded byte weights so they add up to 255:
|
||||
* ``54(R) + 182(G) + 19(B)``
|
||||
* `54(R) + 182(G) + 19(B)`
|
||||
*/
|
||||
MINLINE float rgb_to_grayscale(const float rgb[3])
|
||||
{
|
||||
|
|
|
@ -165,7 +165,7 @@ float area_squared_poly_v3(const float verts[][3], unsigned int nr)
|
|||
/**
|
||||
* Scalar cross product of a 2d polygon.
|
||||
*
|
||||
* - equivalent to ``area * 2``
|
||||
* - equivalent to `area * 2`
|
||||
* - useful for checking polygon winding (a positive value is clockwise).
|
||||
*/
|
||||
float cross_poly_v2(const float verts[][2], unsigned int nr)
|
||||
|
@ -518,7 +518,7 @@ float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3])
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if \a p is inside the 2x planes defined by ``(v1, v2, v3)``
|
||||
* Check if \a p is inside the 2x planes defined by `(v1, v2, v3)`
|
||||
* where the 3x points define 2x planes.
|
||||
*
|
||||
* \param axis_ref: used when v1,v2,v3 form a line and to check if the corner is concave/convex.
|
||||
|
@ -527,7 +527,7 @@ float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3])
|
|||
* (it just defines the planes).
|
||||
*
|
||||
* \return the lowest squared distance to either of the planes.
|
||||
* where ``(return < 0.0)`` is outside.
|
||||
* where `(return < 0.0)` is outside.
|
||||
*
|
||||
* <pre>
|
||||
* v1
|
||||
|
@ -1421,7 +1421,7 @@ int isect_seg_seg_v2_lambda_mu_db(const double v1[2],
|
|||
* \return r_p1, r_p2: Intersection coordinates.
|
||||
*
|
||||
* \note The order of assignment for intersection points (\a r_p1, \a r_p2) is predictable,
|
||||
* based on the direction defined by ``l2 - l1``,
|
||||
* based on the direction defined by `l2 - l1`,
|
||||
* this direction compared with the normal of each point on the sphere:
|
||||
* \a r_p1 always has a >= 0.0 dot product.
|
||||
* \a r_p2 always has a <= 0.0 dot product.
|
||||
|
@ -3426,7 +3426,7 @@ float ray_point_factor_v3(const float p[3],
|
|||
|
||||
/**
|
||||
* A simplified version of #closest_to_line_v3
|
||||
* we only need to return the ``lambda``
|
||||
* we only need to return the `lambda`
|
||||
*
|
||||
* \param epsilon: avoid approaching divide-by-zero.
|
||||
* Passing a zero will just check for nonzero division.
|
||||
|
|
|
@ -272,7 +272,7 @@ MINLINE float shell_angle_to_dist(const float angle)
|
|||
return (UNLIKELY(angle < SMALL_NUMBER)) ? 1.0f : fabsf(1.0f / cosf(angle));
|
||||
}
|
||||
/**
|
||||
* equivalent to ``shell_angle_to_dist(angle_normalized_v3v3(a, b))``
|
||||
* Equivalent to `shell_angle_to_dist(angle_normalized_v3v3(a, b))`.
|
||||
*/
|
||||
MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3])
|
||||
{
|
||||
|
@ -282,7 +282,7 @@ MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3])
|
|||
return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
|
||||
}
|
||||
/**
|
||||
* equivalent to ``shell_angle_to_dist(angle_normalized_v2v2(a, b))``
|
||||
* Equivalent to `shell_angle_to_dist(angle_normalized_v2v2(a, b))`.
|
||||
*/
|
||||
MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2])
|
||||
{
|
||||
|
@ -293,7 +293,7 @@ MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2])
|
|||
}
|
||||
|
||||
/**
|
||||
* equivalent to ``shell_angle_to_dist(angle_normalized_v3v3(a, b) / 2)``
|
||||
* Equivalent to `shell_angle_to_dist(angle_normalized_v3v3(a, b) / 2)`.
|
||||
*/
|
||||
MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3])
|
||||
{
|
||||
|
@ -307,7 +307,7 @@ MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[
|
|||
}
|
||||
|
||||
/**
|
||||
* equivalent to ``shell_angle_to_dist(angle_normalized_v2v2(a, b) / 2)``
|
||||
* Equivalent to `shell_angle_to_dist(angle_normalized_v2v2(a, b) / 2)`.
|
||||
*/
|
||||
MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2])
|
||||
{
|
||||
|
|
|
@ -1312,7 +1312,7 @@ MINLINE bool is_one_v3(const float v[3])
|
|||
/* -------------------------------------------------------------------- */
|
||||
/** \name Vector Comparison
|
||||
*
|
||||
* \note use ``value <= limit``, so a limit of zero doesn't fail on an exact match.
|
||||
* \note use `value <= limit`, so a limit of zero doesn't fail on an exact match.
|
||||
* \{ */
|
||||
|
||||
MINLINE bool equals_v2v2(const float v1[2], const float v2[2])
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue