Compositor: add new node: Kuwahara filter #107015
|
@ -98,6 +98,14 @@ typedef enum {
|
|||
* This is a convention for X11/WAYLAND, select text & MMB to paste (without an explicit copy).
|
||||
*/
|
||||
GHOST_kCapabilityPrimaryClipboard = (1 << 2),
|
||||
/**
|
||||
* Support for reading the front-buffer.
|
||||
*/
|
||||
GHOST_kCapabilityGPUReadFrontBuffer = (1 << 3),
|
||||
/**
|
||||
* Set when there is support for system clipboard copy/paste.
|
||||
*/
|
||||
GHOST_kCapabilityClipboardImages = (1 << 4),
|
||||
} GHOST_TCapabilityFlag;
|
||||
|
||||
/**
|
||||
|
@ -106,7 +114,7 @@ typedef enum {
|
|||
*/
|
||||
#define GHOST_CAPABILITY_FLAG_ALL \
|
||||
(GHOST_kCapabilityCursorWarp | GHOST_kCapabilityWindowPosition | \
|
||||
GHOST_kCapabilityPrimaryClipboard)
|
||||
GHOST_kCapabilityPrimaryClipboard | GHOST_kCapabilityGPUReadFrontBuffer)
|
||||
|
||||
/* Xtilt and Ytilt represent how much the pen is tilted away from
|
||||
* vertically upright in either the X or Y direction, with X and Y the
|
||||
|
|
|
@ -903,7 +903,9 @@ GHOST_TCapabilityFlag GHOST_SystemCocoa::getCapabilities() const
|
|||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
/* Cocoa has no support for a primary selection clipboard. */
|
||||
GHOST_kCapabilityPrimaryClipboard));
|
||||
GHOST_kCapabilityPrimaryClipboard |
|
||||
/* This Cocoa back-end has not yet implemented image copy/paste. */
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
|
||||
#pragma mark Event handlers
|
||||
|
|
|
@ -47,7 +47,8 @@ class GHOST_SystemHeadless : public GHOST_System {
|
|||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||
/* No windowing functionality supported. */
|
||||
~(GHOST_kCapabilityWindowPosition | GHOST_kCapabilityCursorWarp |
|
||||
GHOST_kCapabilityPrimaryClipboard));
|
||||
GHOST_kCapabilityPrimaryClipboard |
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
char *getClipboard(bool /*selection*/) const override
|
||||
{
|
||||
|
|
|
@ -757,7 +757,9 @@ GHOST_TCapabilityFlag GHOST_SystemSDL::getCapabilities() const
|
|||
GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
/* This SDL back-end has not yet implemented primary clipboard. */
|
||||
GHOST_kCapabilityPrimaryClipboard));
|
||||
GHOST_kCapabilityPrimaryClipboard |
|
||||
/* This SDL back-end has not yet implemented image copy/paste. */
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
|
||||
char *GHOST_SystemSDL::getClipboard(bool /*selection*/) const
|
||||
|
|
|
@ -6762,7 +6762,12 @@ GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const
|
|||
GHOST_kCapabilityWindowPosition |
|
||||
/* WAYLAND doesn't support setting the cursor position directly,
|
||||
* this is an intentional choice, forcing us to use a software cursor in this case. */
|
||||
GHOST_kCapabilityCursorWarp));
|
||||
GHOST_kCapabilityCursorWarp |
|
||||
/* Some drivers don't support front-buffer reading, see: #98462 & #106264.
|
||||
* We could inspect the graphics card driver - for now just disable on WAYLAND. */
|
||||
GHOST_kCapabilityGPUReadFrontBuffer |
|
||||
/* This WAYLAND back-end has not yet implemented image copy/paste. */
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
|
||||
bool GHOST_SystemWayland::cursor_grab_use_software_display_get(const GHOST_TGrabCursorMode mode)
|
||||
|
|
|
@ -1742,7 +1742,10 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y)
|
|||
|
||||
GHOST_TCapabilityFlag GHOST_SystemX11::getCapabilities() const
|
||||
{
|
||||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL);
|
||||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
/* No support yet for image copy/paste. */
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
|
||||
void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind)
|
||||
|
|
|
@ -16,7 +16,7 @@ def batch_for_shader(shader, type, content, *, indices=None):
|
|||
:arg content: Maps the name of the shader attribute with the data to fill the vertex buffer.
|
||||
:type content: dict
|
||||
:return: compatible batch
|
||||
:rtype: :class:`gpu.types.Batch`
|
||||
:rtype: :class:`gpu.types.GPUBatch`
|
||||
"""
|
||||
from gpu.types import (
|
||||
GPUBatch,
|
||||
|
|
|
@ -33,7 +33,7 @@ enum {
|
|||
ICON_DATA_PREVIEW,
|
||||
/** 2D triangles: obj is #Icon_Geom */
|
||||
ICON_DATA_GEOM,
|
||||
/** Studiolight */
|
||||
/** Studio-light. */
|
||||
ICON_DATA_STUDIOLIGHT,
|
||||
/** GPencil Layer color preview (annotations): obj is #bGPDlayer */
|
||||
ICON_DATA_GPLAYER,
|
||||
|
|
|
@ -245,7 +245,7 @@ void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
|
|||
struct CCGFace **effected_faces,
|
||||
int num_effected_faces);
|
||||
|
||||
/* Average grid coordinates and normals along the grid boundatries. */
|
||||
/* Average grid coordinates and normals along the grid boundaries. */
|
||||
void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg);
|
||||
|
||||
/* Similar to above, but only updates given faces. */
|
||||
|
|
|
@ -592,8 +592,8 @@ bGPDframe *BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe)
|
|||
break;
|
||||
}
|
||||
if (gpf->framenum == cframe) {
|
||||
/* This only happens when we're editing with framelock on...
|
||||
* - Delete the new frame and don't do anything else here...
|
||||
/* This only happens when we're editing with frame-lock on.
|
||||
* - Delete the new frame and don't do anything else here.
|
||||
*/
|
||||
BKE_gpencil_free_strokes(new_frame);
|
||||
MEM_freeN(new_frame);
|
||||
|
|
|
@ -1404,9 +1404,24 @@ void nodeUnregisterType(bNodeType *nt)
|
|||
|
||||
bool nodeTypeUndefined(const bNode *node)
|
||||
{
|
||||
return (node->typeinfo == &NodeTypeUndefined) ||
|
||||
(ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id && ID_IS_LINKED(node->id) &&
|
||||
(node->id->tag & LIB_TAG_MISSING));
|
||||
if (node->typeinfo == &NodeTypeUndefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (node->is_group()) {
|
||||
const ID *group_tree = node->id;
|
||||
if (group_tree == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (!ID_IS_LINKED(group_tree)) {
|
||||
return false;
|
||||
}
|
||||
if ((group_tree->tag & LIB_TAG_MISSING) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
GHashIterator *nodeTypeGetIterator()
|
||||
|
@ -1464,7 +1479,10 @@ GHashIterator *nodeSocketTypeGetIterator()
|
|||
const char *nodeSocketTypeLabel(const bNodeSocketType *stype)
|
||||
{
|
||||
/* Use socket type name as a fallback if label is undefined. */
|
||||
return stype->label[0] != '\0' ? stype->label : RNA_struct_ui_name(stype->ext_socket.srna);
|
||||
if (stype->label[0] == '\0') {
|
||||
return RNA_struct_ui_name(stype->ext_socket.srna);
|
||||
}
|
||||
return stype->label;
|
||||
}
|
||||
|
||||
const char *nodeSocketSubTypeLabel(int subtype)
|
||||
|
@ -2132,18 +2150,23 @@ void nodeChainIter(const bNodeTree *ntree,
|
|||
/* Skip links marked as cyclic. */
|
||||
continue;
|
||||
}
|
||||
if (link->tonode && link->fromnode) {
|
||||
/* Is the link part of the chain meaning node_start == fromnode
|
||||
* (or tonode for reversed case)? */
|
||||
if ((reversed && (link->tonode == node_start)) ||
|
||||
(!reversed && link->fromnode == node_start)) {
|
||||
if (!callback(link->fromnode, link->tonode, userdata, reversed)) {
|
||||
return;
|
||||
}
|
||||
nodeChainIter(
|
||||
ntree, reversed ? link->fromnode : link->tonode, callback, userdata, reversed);
|
||||
/* Is the link part of the chain meaning node_start == fromnode
|
||||
* (or tonode for reversed case)? */
|
||||
if (!reversed) {
|
||||
if (link->fromnode != node_start) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (link->tonode != node_start) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!callback(link->fromnode, link->tonode, userdata, reversed)) {
|
||||
return;
|
||||
}
|
||||
nodeChainIter(ntree, reversed ? link->fromnode : link->tonode, callback, userdata, reversed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2289,8 +2312,12 @@ bNode *nodeAddStaticNode(const bContext *C, bNodeTree *ntree, const int type)
|
|||
NODE_TYPES_BEGIN (ntype) {
|
||||
/* Do an extra poll here, because some int types are used
|
||||
* for multiple node types, this helps find the desired type. */
|
||||
if (ntype->type != type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *disabled_hint;
|
||||
if (ntype->type == type && (!ntype->poll || ntype->poll(ntype, ntree, &disabled_hint))) {
|
||||
if (ntype->poll && ntype->poll(ntype, ntree, &disabled_hint)) {
|
||||
idname = ntype->idname;
|
||||
break;
|
||||
}
|
||||
|
@ -2635,55 +2662,49 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
|
|||
/* redirect downstream links */
|
||||
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
|
||||
/* do we have internal link? */
|
||||
if (link->fromnode == node) {
|
||||
if (link->fromsock->link) {
|
||||
/* get the upstream input link */
|
||||
bNodeLink *fromlink = link->fromsock->link->fromsock->link;
|
||||
/* skip the node */
|
||||
if (fromlink) {
|
||||
if (link->tosock->flag & SOCK_MULTI_INPUT) {
|
||||
/* remove the link that would be the same as the relinked one */
|
||||
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link_to_compare, &ntree->links) {
|
||||
if (link_to_compare->fromsock == fromlink->fromsock &&
|
||||
link_to_compare->tosock == link->tosock) {
|
||||
adjust_multi_input_indices_after_removed_link(
|
||||
ntree, link_to_compare->tosock, link_to_compare->multi_input_socket_index);
|
||||
duplicate_links_to_remove.append_non_duplicates(link_to_compare);
|
||||
}
|
||||
}
|
||||
}
|
||||
link->fromnode = fromlink->fromnode;
|
||||
link->fromsock = fromlink->fromsock;
|
||||
if (link->fromnode != node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if the up- or downstream link is invalid,
|
||||
* the replacement link will be invalid too.
|
||||
*/
|
||||
if (!(fromlink->flag & NODE_LINK_VALID)) {
|
||||
link->flag &= ~NODE_LINK_VALID;
|
||||
}
|
||||
bNodeLink *internal_link = link->fromsock->link;
|
||||
bNodeLink *fromlink = internal_link ? internal_link->fromsock->link : nullptr;
|
||||
|
||||
if (fromlink->flag & NODE_LINK_MUTED) {
|
||||
link->flag |= NODE_LINK_MUTED;
|
||||
}
|
||||
|
||||
BKE_ntree_update_tag_link_changed(ntree);
|
||||
}
|
||||
else {
|
||||
if (link->tosock->flag & SOCK_MULTI_INPUT) {
|
||||
adjust_multi_input_indices_after_removed_link(
|
||||
ntree, link->tosock, link->multi_input_socket_index);
|
||||
}
|
||||
nodeRemLink(ntree, link);
|
||||
}
|
||||
if (fromlink == nullptr) {
|
||||
if (link->tosock->flag & SOCK_MULTI_INPUT) {
|
||||
adjust_multi_input_indices_after_removed_link(
|
||||
ntree, link->tosock, link->multi_input_socket_index);
|
||||
}
|
||||
else {
|
||||
if (link->tosock->flag & SOCK_MULTI_INPUT) {
|
||||
nodeRemLink(ntree, link);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (link->tosock->flag & SOCK_MULTI_INPUT) {
|
||||
/* remove the link that would be the same as the relinked one */
|
||||
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link_to_compare, &ntree->links) {
|
||||
if (link_to_compare->fromsock == fromlink->fromsock &&
|
||||
link_to_compare->tosock == link->tosock) {
|
||||
adjust_multi_input_indices_after_removed_link(
|
||||
ntree, link->tosock, link->multi_input_socket_index);
|
||||
};
|
||||
nodeRemLink(ntree, link);
|
||||
ntree, link_to_compare->tosock, link_to_compare->multi_input_socket_index);
|
||||
duplicate_links_to_remove.append_non_duplicates(link_to_compare);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
link->fromnode = fromlink->fromnode;
|
||||
link->fromsock = fromlink->fromsock;
|
||||
|
||||
/* if the up- or downstream link is invalid,
|
||||
* the replacement link will be invalid too.
|
||||
*/
|
||||
if (!(fromlink->flag & NODE_LINK_VALID)) {
|
||||
link->flag &= ~NODE_LINK_VALID;
|
||||
}
|
||||
|
||||
if (fromlink->flag & NODE_LINK_MUTED) {
|
||||
link->flag |= NODE_LINK_MUTED;
|
||||
}
|
||||
|
||||
BKE_ntree_update_tag_link_changed(ntree);
|
||||
}
|
||||
|
||||
for (bNodeLink *link : duplicate_links_to_remove) {
|
||||
|
@ -3292,6 +3313,7 @@ void ntreeFreeLocalTree(bNodeTree *ntree)
|
|||
|
||||
void ntreeSetOutput(bNodeTree *ntree)
|
||||
{
|
||||
const bool is_compositor = ntree->type == NTREE_COMPOSIT;
|
||||
/* find the active outputs, might become tree type dependent handler */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
|
||||
|
@ -3299,37 +3321,29 @@ void ntreeSetOutput(bNodeTree *ntree)
|
|||
if (ELEM(node->type, CMP_NODE_OUTPUT_FILE, GEO_NODE_VIEWER)) {
|
||||
continue;
|
||||
}
|
||||
const bool node_is_output = ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER);
|
||||
|
||||
int output = 0;
|
||||
/* there is more types having output class, each one is checked */
|
||||
|
||||
LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
|
||||
if (tnode->typeinfo->nclass == NODE_CLASS_OUTPUT) {
|
||||
if (ntree->type == NTREE_COMPOSIT) {
|
||||
/* same type, exception for viewer */
|
||||
if (tnode->type == node->type ||
|
||||
(ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) &&
|
||||
ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) {
|
||||
if (tnode->flag & NODE_DO_OUTPUT) {
|
||||
output++;
|
||||
if (output > 1) {
|
||||
tnode->flag &= ~NODE_DO_OUTPUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* same type */
|
||||
if (tnode->type == node->type) {
|
||||
if (tnode->flag & NODE_DO_OUTPUT) {
|
||||
output++;
|
||||
if (output > 1) {
|
||||
tnode->flag &= ~NODE_DO_OUTPUT;
|
||||
}
|
||||
}
|
||||
if (tnode->typeinfo->nclass != NODE_CLASS_OUTPUT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* same type, exception for viewer */
|
||||
const bool tnode_is_output = ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER);
|
||||
const bool compositor_case = is_compositor && tnode_is_output && node_is_output;
|
||||
if (tnode->type == node->type || compositor_case) {
|
||||
if (tnode->flag & NODE_DO_OUTPUT) {
|
||||
output++;
|
||||
if (output > 1) {
|
||||
tnode->flag &= ~NODE_DO_OUTPUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output == 0) {
|
||||
node->flag |= NODE_DO_OUTPUT;
|
||||
}
|
||||
|
@ -3339,12 +3353,13 @@ void ntreeSetOutput(bNodeTree *ntree)
|
|||
if (node->type == NODE_GROUP_OUTPUT) {
|
||||
int output = 0;
|
||||
LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
|
||||
if (tnode->type == NODE_GROUP_OUTPUT) {
|
||||
if (tnode->flag & NODE_DO_OUTPUT) {
|
||||
output++;
|
||||
if (output > 1) {
|
||||
tnode->flag &= ~NODE_DO_OUTPUT;
|
||||
}
|
||||
if (tnode->type != NODE_GROUP_OUTPUT) {
|
||||
continue;
|
||||
}
|
||||
if (tnode->flag & NODE_DO_OUTPUT) {
|
||||
output++;
|
||||
if (output > 1) {
|
||||
tnode->flag &= ~NODE_DO_OUTPUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3547,10 +3562,11 @@ bNodeSocket *ntreeAddSocketInterfaceFromSocketWithName(bNodeTree *ntree,
|
|||
{
|
||||
bNodeSocket *iosock = ntreeAddSocketInterface(
|
||||
ntree, static_cast<eNodeSocketInOut>(from_sock->in_out), idname, DATA_(name));
|
||||
if (iosock) {
|
||||
if (iosock->typeinfo->interface_from_socket) {
|
||||
iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock);
|
||||
}
|
||||
if (iosock == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (iosock->typeinfo->interface_from_socket) {
|
||||
iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock);
|
||||
}
|
||||
return iosock;
|
||||
}
|
||||
|
@ -3677,17 +3693,15 @@ void nodeSetSelected(bNode *node, const bool select)
|
|||
{
|
||||
if (select) {
|
||||
node->flag |= NODE_SELECT;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
node->flag &= ~NODE_SELECT;
|
||||
|
||||
/* deselect sockets too */
|
||||
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
|
||||
sock->flag &= ~NODE_SELECT;
|
||||
}
|
||||
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
|
||||
sock->flag &= ~NODE_SELECT;
|
||||
}
|
||||
node->flag &= ~NODE_SELECT;
|
||||
/* deselect sockets too */
|
||||
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
|
||||
sock->flag &= ~NODE_SELECT;
|
||||
}
|
||||
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
|
||||
sock->flag &= ~NODE_SELECT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3734,17 +3748,17 @@ void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, const bool i
|
|||
|
||||
int nodeSocketLinkLimit(const bNodeSocket *sock)
|
||||
{
|
||||
const bNodeSocketType *stype = sock->typeinfo;
|
||||
if (sock->flag & SOCK_MULTI_INPUT) {
|
||||
return 4095;
|
||||
}
|
||||
if (stype != nullptr && stype->use_link_limits_of_type) {
|
||||
const int limit = (sock->in_out == SOCK_IN) ? stype->input_link_limit :
|
||||
stype->output_link_limit;
|
||||
return limit;
|
||||
if (sock->typeinfo == nullptr) {
|
||||
return sock->limit;
|
||||
}
|
||||
|
||||
return sock->limit;
|
||||
const bNodeSocketType &stype = *sock->typeinfo;
|
||||
if (!stype.use_link_limits_of_type) {
|
||||
return sock->limit;
|
||||
}
|
||||
return sock->in_out == SOCK_IN ? stype.input_link_limit : stype.output_link_limit;
|
||||
}
|
||||
|
||||
static void update_socket_declarations(ListBase *sockets,
|
||||
|
@ -3770,11 +3784,10 @@ void nodeSocketDeclarationsUpdate(bNode *node)
|
|||
if (node->runtime->declaration->skip_updating_sockets) {
|
||||
reset_socket_declarations(&node->inputs);
|
||||
reset_socket_declarations(&node->outputs);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
update_socket_declarations(&node->inputs, node->runtime->declaration->inputs);
|
||||
update_socket_declarations(&node->outputs, node->runtime->declaration->outputs);
|
||||
}
|
||||
update_socket_declarations(&node->inputs, node->runtime->declaration->inputs);
|
||||
update_socket_declarations(&node->outputs, node->runtime->declaration->outputs);
|
||||
}
|
||||
|
||||
bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *ntree, bNode *node)
|
||||
|
@ -4034,16 +4047,17 @@ void nodeLabel(const bNodeTree *ntree, const bNode *node, char *label, const int
|
|||
else if (node->typeinfo->labelfunc) {
|
||||
node->typeinfo->labelfunc(ntree, node, label, maxlen);
|
||||
}
|
||||
|
||||
/* The previous methods (labelfunc) could not provide an adequate label for the node. */
|
||||
if (label[0] == '\0') {
|
||||
/* Kind of hacky and weak... Ideally would be better to use RNA here. :| */
|
||||
const char *tmp = CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, node->typeinfo->ui_name);
|
||||
if (tmp == node->typeinfo->ui_name) {
|
||||
tmp = IFACE_(node->typeinfo->ui_name);
|
||||
}
|
||||
BLI_strncpy(label, tmp, maxlen);
|
||||
if (label[0] != '\0') {
|
||||
/* The previous methods (labelfunc) could not provide an adequate label for the node. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Kind of hacky and weak... Ideally would be better to use RNA here. :| */
|
||||
const char *tmp = CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, node->typeinfo->ui_name);
|
||||
if (tmp == node->typeinfo->ui_name) {
|
||||
tmp = IFACE_(node->typeinfo->ui_name);
|
||||
}
|
||||
BLI_strncpy(label, tmp, maxlen);
|
||||
}
|
||||
|
||||
const char *nodeSocketLabel(const bNodeSocket *sock)
|
||||
|
|
|
@ -602,7 +602,7 @@ static void annotation_draw_onionskins(
|
|||
for (gf = gpf->prev; gf; gf = gf->prev) {
|
||||
/* check if frame is drawable */
|
||||
if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
|
||||
/* alpha decreases with distance from curframe index */
|
||||
/* Alpha decreases with distance from current-frame index. */
|
||||
fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
|
||||
color[3] = alpha * fac * 0.66f;
|
||||
annotation_draw_strokes(gf, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
|
||||
|
@ -634,7 +634,7 @@ static void annotation_draw_onionskins(
|
|||
for (gf = gpf->next; gf; gf = gf->next) {
|
||||
/* check if frame is drawable */
|
||||
if ((gf->framenum - gpf->framenum) <= gpl->gstep_next) {
|
||||
/* alpha decreases with distance from curframe index */
|
||||
/* Alpha decreases with distance from current-frame index. */
|
||||
fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1));
|
||||
color[3] = alpha * fac * 0.66f;
|
||||
annotation_draw_strokes(gf, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
|
||||
|
|
|
@ -291,7 +291,7 @@ static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], const
|
|||
|
||||
/* Check if the distance since the last point is significant enough:
|
||||
* - Prevents points being added too densely
|
||||
* - Distance here doesn't use sqrt to prevent slowness.
|
||||
* - Distance here doesn't use `sqrt` to prevent slowness.
|
||||
* We should still be safe from overflows though.
|
||||
*/
|
||||
if ((dx * dx + dy * dy) > MIN_EUCLIDEAN_PX * MIN_EUCLIDEAN_PX) {
|
||||
|
@ -2457,7 +2457,7 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
}
|
||||
|
||||
/* We don't pass on key events, GP is used with key-modifiers -
|
||||
* prevents Dkey to insert drivers. */
|
||||
* prevents D-key to insert drivers. */
|
||||
if (ISKEYBOARD(event->type)) {
|
||||
if (ELEM(event->type,
|
||||
EVT_LEFTARROWKEY,
|
||||
|
|
|
@ -188,7 +188,7 @@ static void gpencil_draw_stroke_3d(tGPDdraw *tgpw,
|
|||
int keep_size = (int)((tgpw->gpd) && (tgpw->gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
|
||||
gpencil_stroke_data.keep_size = keep_size;
|
||||
gpencil_stroke_data.pixfactor = tgpw->gpd->pixfactor;
|
||||
/* xray mode always to 3D space to avoid wrong zdepth calculation (#60051) */
|
||||
/* X-ray mode always to 3D space to avoid wrong Z-depth calculation (#60051). */
|
||||
gpencil_stroke_data.xraymode = GP_XRAY_3DSPACE;
|
||||
gpencil_stroke_data.caps_start = tgpw->gps->caps[0];
|
||||
gpencil_stroke_data.caps_end = tgpw->gps->caps[1];
|
||||
|
|
|
@ -2754,7 +2754,7 @@ void GPENCIL_OT_vertex_group_normalize_all(wmOperatorType *ot)
|
|||
|
||||
/****************************** Join ***********************************/
|
||||
|
||||
/* userdata for joined_gpencil_fix_animdata_cb() */
|
||||
/** User-data for #gpencil_joined_fix_animdata_cb(). */
|
||||
typedef struct tJoinGPencil_AdtFixData {
|
||||
bGPdata *src_gpd;
|
||||
bGPdata *tar_gpd;
|
||||
|
|
|
@ -193,7 +193,7 @@ static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *op)
|
|||
ob->mode = mode;
|
||||
}
|
||||
|
||||
/* Recalculate editcurves for strokes where the geometry/vertex colors have changed */
|
||||
/* Recalculate edit-curves for strokes where the geometry/vertex colors have changed. */
|
||||
if (GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd)) {
|
||||
GP_EDITABLE_CURVES_BEGIN(gps_iter, C, gpl, gps, gpc)
|
||||
{
|
||||
|
@ -1410,9 +1410,8 @@ void ED_gpencil_strokes_copybuf_free(void)
|
|||
{
|
||||
bGPDstroke *gps, *gpsn;
|
||||
|
||||
/* Free the colors buffer
|
||||
* NOTE: This is done before the strokes so that the ptrs are still safe
|
||||
*/
|
||||
/* Free the colors buffer.
|
||||
* NOTE: This is done before the strokes so that the pointers are still safe. */
|
||||
if (gpencil_strokes_copypastebuf_colors) {
|
||||
BLI_ghash_free(gpencil_strokes_copypastebuf_colors, NULL, MEM_freeN);
|
||||
gpencil_strokes_copypastebuf_colors = NULL;
|
||||
|
|
|
@ -715,7 +715,7 @@ static void gpencil_update_extensions_line(tGPDfill *tgpf)
|
|||
}
|
||||
}
|
||||
|
||||
/* Cut overlength strokes. */
|
||||
/* Cut over-length strokes. */
|
||||
gpencil_cut_extensions(tgpf);
|
||||
}
|
||||
|
||||
|
@ -1317,10 +1317,10 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
|
|||
|
||||
/* create a image to see result of template */
|
||||
if (ibuf->rect_float) {
|
||||
GPU_offscreen_read_pixels(offscreen, GPU_DATA_FLOAT, ibuf->rect_float);
|
||||
GPU_offscreen_read_color(offscreen, GPU_DATA_FLOAT, ibuf->rect_float);
|
||||
}
|
||||
else if (ibuf->rect) {
|
||||
GPU_offscreen_read_pixels(offscreen, GPU_DATA_UBYTE, ibuf->rect);
|
||||
GPU_offscreen_read_color(offscreen, GPU_DATA_UBYTE, ibuf->rect);
|
||||
}
|
||||
if (ibuf->rect_float && ibuf->rect) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
|
|
|
@ -1371,7 +1371,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
|
|||
float factor = (float)(cframe - prevFrame->framenum) / framerange;
|
||||
|
||||
if (type == GP_IPO_CURVEMAP) {
|
||||
/* custom curvemap */
|
||||
/* Custom curve-map. */
|
||||
if (ipo_settings->custom_ipo) {
|
||||
factor = BKE_curvemapping_evaluateF(ipo_settings->custom_ipo, 0, factor);
|
||||
}
|
||||
|
|
|
@ -374,7 +374,7 @@ static bool gpencil_stroke_filtermval(tGPsdata *p, const float mval[2], const fl
|
|||
}
|
||||
/* Check if the distance since the last point is significant enough:
|
||||
* - Prevents points being added too densely
|
||||
* - Distance here doesn't use sqrt to prevent slowness.
|
||||
* - Distance here doesn't use `sqrt` to prevent slowness.
|
||||
* We should still be safe from overflows though.
|
||||
*/
|
||||
if ((dx * dx + dy * dy) > MIN_EUCLIDEAN_PX * MIN_EUCLIDEAN_PX) {
|
||||
|
|
|
@ -1222,7 +1222,7 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op)
|
|||
"gp primitive cpoint");
|
||||
tgpi->gpd->runtime.tot_cp_points = 0;
|
||||
|
||||
/* getcolor info */
|
||||
/* Get color info. */
|
||||
tgpi->material = BKE_gpencil_object_material_ensure_from_active_input_toolsettings(
|
||||
bmain, tgpi->ob, ts);
|
||||
|
||||
|
|
|
@ -1324,7 +1324,7 @@ static void gpencil_sculpt_brush_exit(bContext *C, wmOperator *op)
|
|||
BLI_ghash_free(gso->automasking_strokes, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Disable headerprints. */
|
||||
/* Clear status-bar text. */
|
||||
ED_workspace_status_text(C, NULL);
|
||||
|
||||
/* disable temp invert flag */
|
||||
|
@ -2320,21 +2320,21 @@ static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
bool redraw_region = false;
|
||||
bool redraw_toolsettings = false;
|
||||
|
||||
/* The operator can be in 2 states: Painting and Idling */
|
||||
/* The operator can be in 2 states: Painting and Idling. */
|
||||
if (gso->is_painting) {
|
||||
/* Painting. */
|
||||
switch (event->type) {
|
||||
/* Mouse Move = Apply somewhere else */
|
||||
/* Mouse Move: Apply somewhere else. */
|
||||
case MOUSEMOVE:
|
||||
case INBETWEEN_MOUSEMOVE:
|
||||
/* apply brush effect at new position */
|
||||
/* apply brush effect at new position. */
|
||||
gpencil_sculpt_brush_apply_event(C, op, event);
|
||||
|
||||
/* force redraw, so that the cursor will at least be valid */
|
||||
/* force redraw, so that the cursor will at least be valid. */
|
||||
redraw_region = true;
|
||||
break;
|
||||
|
||||
/* Timer Tick - Only if this was our own timer */
|
||||
/* Timer Tick - Only if this was our own timer. */
|
||||
case TIMER:
|
||||
if (event->customdata == gso->timer) {
|
||||
gso->timerTick = true;
|
||||
|
@ -2343,7 +2343,7 @@ static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
}
|
||||
break;
|
||||
|
||||
/* Painting mbut release = Stop painting (back to idle) */
|
||||
/* Painting mouse-button release: Stop painting (back to idle). */
|
||||
case LEFTMOUSE:
|
||||
// BLI_assert(event->val == KM_RELEASE);
|
||||
if (is_modal) {
|
||||
|
@ -2351,7 +2351,7 @@ static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
gso->is_painting = false;
|
||||
}
|
||||
else {
|
||||
/* end sculpt session, since we're not modal */
|
||||
/* end sculpt session, since we're not modal. */
|
||||
gso->is_painting = false;
|
||||
|
||||
gpencil_sculpt_brush_exit(C, op);
|
||||
|
@ -2359,7 +2359,7 @@ static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
}
|
||||
break;
|
||||
|
||||
/* Abort painting if any of the usual things are tried */
|
||||
/* Abort painting if any of the usual things are tried. */
|
||||
case MIDDLEMOUSE:
|
||||
case RIGHTMOUSE:
|
||||
case EVT_ESCKEY:
|
||||
|
@ -2368,13 +2368,13 @@ static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* Idling */
|
||||
/* Idling. */
|
||||
BLI_assert(is_modal == true);
|
||||
|
||||
switch (event->type) {
|
||||
/* Painting mbut press = Start painting (switch to painting state) */
|
||||
/* Painting mouse-button press: Start painting (switch to painting state). */
|
||||
case LEFTMOUSE:
|
||||
/* do initial "click" apply */
|
||||
/* do initial "click" apply. */
|
||||
gso->is_painting = true;
|
||||
gso->first = true;
|
||||
|
||||
|
@ -2382,30 +2382,30 @@ static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
gpencil_sculpt_brush_apply_event(C, op, event);
|
||||
break;
|
||||
|
||||
/* Exit modal operator, based on the "standard" ops */
|
||||
/* Exit modal operator, based on the "standard" ops. */
|
||||
case RIGHTMOUSE:
|
||||
case EVT_ESCKEY:
|
||||
gpencil_sculpt_brush_exit(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
/* MMB is often used for view manipulations */
|
||||
/* MMB is often used for view manipulations. */
|
||||
case MIDDLEMOUSE:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Mouse movements should update the brush cursor - Just redraw the active region */
|
||||
/* Mouse movements should update the brush cursor - Just redraw the active region. */
|
||||
case MOUSEMOVE:
|
||||
case INBETWEEN_MOUSEMOVE:
|
||||
redraw_region = true;
|
||||
break;
|
||||
|
||||
/* Change Frame - Allowed */
|
||||
/* Change Frame - Allowed. */
|
||||
case EVT_LEFTARROWKEY:
|
||||
case EVT_RIGHTARROWKEY:
|
||||
case EVT_UPARROWKEY:
|
||||
case EVT_DOWNARROWKEY:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Camera/View Gizmo's - Allowed */
|
||||
/* Camera/View Gizmo's - Allowed. */
|
||||
/* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */
|
||||
case EVT_PAD0:
|
||||
case EVT_PAD1:
|
||||
|
@ -2419,7 +2419,7 @@ static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent
|
|||
case EVT_PAD9:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Unhandled event */
|
||||
/* Unhandled event. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -761,7 +761,7 @@ static void gpencil_vertexpaint_brush_exit(bContext *C, wmOperator *op)
|
|||
{
|
||||
tGP_BrushVertexpaintData *gso = op->customdata;
|
||||
|
||||
/* Disable headerprints. */
|
||||
/* Clear status-bar text. */
|
||||
ED_workspace_status_text(C, NULL);
|
||||
|
||||
/* Disable temp invert flag. */
|
||||
|
@ -1318,28 +1318,28 @@ static int gpencil_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wm
|
|||
bool redraw_region = false;
|
||||
bool redraw_toolsettings = false;
|
||||
|
||||
/* The operator can be in 2 states: Painting and Idling */
|
||||
/* The operator can be in 2 states: Painting and Idling. */
|
||||
if (gso->is_painting) {
|
||||
/* Painting. */
|
||||
switch (event->type) {
|
||||
/* Mouse Move = Apply somewhere else */
|
||||
/* Mouse Move: Apply somewhere else. */
|
||||
case MOUSEMOVE:
|
||||
case INBETWEEN_MOUSEMOVE:
|
||||
/* apply brush effect at new position */
|
||||
/* Apply brush effect at new position. */
|
||||
gpencil_vertexpaint_brush_apply_event(C, op, event);
|
||||
|
||||
/* force redraw, so that the cursor will at least be valid */
|
||||
/* Force redraw, so that the cursor will at least be valid. */
|
||||
redraw_region = true;
|
||||
break;
|
||||
|
||||
/* Painting mbut release = Stop painting (back to idle) */
|
||||
/* Painting mouse-button release means: Stop painting (back to idle). */
|
||||
case LEFTMOUSE:
|
||||
if (is_modal) {
|
||||
/* go back to idling... */
|
||||
gso->is_painting = false;
|
||||
}
|
||||
else {
|
||||
/* end painting, since we're not modal */
|
||||
/* end painting, since we're not modal. */
|
||||
gso->is_painting = false;
|
||||
|
||||
gpencil_vertexpaint_brush_exit(C, op);
|
||||
|
@ -1347,7 +1347,7 @@ static int gpencil_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wm
|
|||
}
|
||||
break;
|
||||
|
||||
/* Abort painting if any of the usual things are tried */
|
||||
/* Abort painting if any of the usual things are tried. */
|
||||
case MIDDLEMOUSE:
|
||||
case RIGHTMOUSE:
|
||||
case EVT_ESCKEY:
|
||||
|
@ -1356,43 +1356,43 @@ static int gpencil_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wm
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* Idling */
|
||||
/* Idling. */
|
||||
BLI_assert(is_modal == true);
|
||||
|
||||
switch (event->type) {
|
||||
/* Painting mbut press = Start painting (switch to painting state) */
|
||||
/* Painting mouse-button press means: Start painting (switch to painting state). */
|
||||
case LEFTMOUSE:
|
||||
/* do initial "click" apply */
|
||||
/* do initial "click" apply. */
|
||||
gso->is_painting = true;
|
||||
gso->first = true;
|
||||
|
||||
gpencil_vertexpaint_brush_apply_event(C, op, event);
|
||||
break;
|
||||
|
||||
/* Exit modal operator, based on the "standard" ops */
|
||||
/* Exit modal operator, based on the "standard" ops. */
|
||||
case RIGHTMOUSE:
|
||||
case EVT_ESCKEY:
|
||||
gpencil_vertexpaint_brush_exit(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
/* MMB is often used for view manipulations */
|
||||
/* MMB is often used for view manipulations. */
|
||||
case MIDDLEMOUSE:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Mouse movements should update the brush cursor - Just redraw the active region */
|
||||
/* Mouse movements should update the brush cursor - Just redraw the active region. */
|
||||
case MOUSEMOVE:
|
||||
case INBETWEEN_MOUSEMOVE:
|
||||
redraw_region = true;
|
||||
break;
|
||||
|
||||
/* Change Frame - Allowed */
|
||||
/* Change Frame - Allowed. */
|
||||
case EVT_LEFTARROWKEY:
|
||||
case EVT_RIGHTARROWKEY:
|
||||
case EVT_UPARROWKEY:
|
||||
case EVT_DOWNARROWKEY:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Camera/View Gizmo's - Allowed */
|
||||
/* Camera/View Gizmo's - Allowed. */
|
||||
/* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */
|
||||
case EVT_PAD0:
|
||||
case EVT_PAD1:
|
||||
|
@ -1406,7 +1406,7 @@ static int gpencil_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wm
|
|||
case EVT_PAD9:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Unhandled event */
|
||||
/* Unhandled event. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -345,7 +345,7 @@ static void gpencil_weightpaint_brush_exit(bContext *C, wmOperator *op)
|
|||
{
|
||||
tGP_BrushWeightpaintData *gso = op->customdata;
|
||||
|
||||
/* Disable headerprints. */
|
||||
/* Clear status bar text. */
|
||||
ED_workspace_status_text(C, NULL);
|
||||
|
||||
/* Free operator data */
|
||||
|
@ -767,7 +767,7 @@ static int gpencil_weightpaint_brush_invoke(bContext *C, wmOperator *op, const w
|
|||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
/* painting - handle events */
|
||||
/* painting - handle events. */
|
||||
static int gpencil_weightpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
tGP_BrushWeightpaintData *gso = op->customdata;
|
||||
|
@ -775,28 +775,28 @@ static int gpencil_weightpaint_brush_modal(bContext *C, wmOperator *op, const wm
|
|||
bool redraw_region = false;
|
||||
bool redraw_toolsettings = false;
|
||||
|
||||
/* The operator can be in 2 states: Painting and Idling */
|
||||
/* The operator can be in 2 states: Painting and Idling. */
|
||||
if (gso->is_painting) {
|
||||
/* Painting. */
|
||||
switch (event->type) {
|
||||
/* Mouse Move = Apply somewhere else */
|
||||
/* Mouse Move: Apply somewhere else. */
|
||||
case MOUSEMOVE:
|
||||
case INBETWEEN_MOUSEMOVE:
|
||||
/* apply brush effect at new position */
|
||||
/* Apply brush effect at new position. */
|
||||
gpencil_weightpaint_brush_apply_event(C, op, event);
|
||||
|
||||
/* force redraw, so that the cursor will at least be valid */
|
||||
/* Force redraw, so that the cursor will at least be valid. */
|
||||
redraw_region = true;
|
||||
break;
|
||||
|
||||
/* Painting mbut release = Stop painting (back to idle) */
|
||||
/* Painting mouse-button release: Stop painting (back to idle). */
|
||||
case LEFTMOUSE:
|
||||
if (is_modal) {
|
||||
/* go back to idling... */
|
||||
gso->is_painting = false;
|
||||
}
|
||||
else {
|
||||
/* end painting, since we're not modal */
|
||||
/* end painting, since we're not modal. */
|
||||
gso->is_painting = false;
|
||||
|
||||
gpencil_weightpaint_brush_exit(C, op);
|
||||
|
@ -804,7 +804,7 @@ static int gpencil_weightpaint_brush_modal(bContext *C, wmOperator *op, const wm
|
|||
}
|
||||
break;
|
||||
|
||||
/* Abort painting if any of the usual things are tried */
|
||||
/* Abort painting if any of the usual things are tried. */
|
||||
case MIDDLEMOUSE:
|
||||
case RIGHTMOUSE:
|
||||
case EVT_ESCKEY:
|
||||
|
@ -813,43 +813,43 @@ static int gpencil_weightpaint_brush_modal(bContext *C, wmOperator *op, const wm
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* Idling */
|
||||
/* Idling. */
|
||||
BLI_assert(is_modal == true);
|
||||
|
||||
switch (event->type) {
|
||||
/* Painting mbut press = Start painting (switch to painting state) */
|
||||
/* Painting mouse-button press = Start painting (switch to painting state). */
|
||||
case LEFTMOUSE:
|
||||
/* do initial "click" apply */
|
||||
/* do initial "click" apply. */
|
||||
gso->is_painting = true;
|
||||
gso->first = true;
|
||||
|
||||
gpencil_weightpaint_brush_apply_event(C, op, event);
|
||||
break;
|
||||
|
||||
/* Exit modal operator, based on the "standard" ops */
|
||||
/* Exit modal operator, based on the "standard" ops. */
|
||||
case RIGHTMOUSE:
|
||||
case EVT_ESCKEY:
|
||||
gpencil_weightpaint_brush_exit(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
/* MMB is often used for view manipulations */
|
||||
/* MMB is often used for view manipulations. */
|
||||
case MIDDLEMOUSE:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Mouse movements should update the brush cursor - Just redraw the active region */
|
||||
/* Mouse movements should update the brush cursor - Just redraw the active region. */
|
||||
case MOUSEMOVE:
|
||||
case INBETWEEN_MOUSEMOVE:
|
||||
redraw_region = true;
|
||||
break;
|
||||
|
||||
/* Change Frame - Allowed */
|
||||
/* Change Frame - Allowed. */
|
||||
case EVT_LEFTARROWKEY:
|
||||
case EVT_RIGHTARROWKEY:
|
||||
case EVT_UPARROWKEY:
|
||||
case EVT_DOWNARROWKEY:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Camera/View Gizmo's - Allowed */
|
||||
/* Camera/View Gizmo's - Allowed. */
|
||||
/* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */
|
||||
case EVT_PAD0:
|
||||
case EVT_PAD1:
|
||||
|
@ -863,7 +863,7 @@ static int gpencil_weightpaint_brush_modal(bContext *C, wmOperator *op, const wm
|
|||
case EVT_PAD9:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* Unhandled event */
|
||||
/* Unhandled event. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -361,7 +361,13 @@ void eyedropper_color_sample_fl(bContext *C, const int m_xy[2], float r_col[3])
|
|||
|
||||
if (win) {
|
||||
/* Fallback to simple opengl picker. */
|
||||
WM_window_pixel_sample_read(wm, win, mval, r_col);
|
||||
if (WM_capabilities_flag() & WM_CAPABILITY_GPU_FRONT_BUFFER_READ) {
|
||||
WM_window_pixels_read_sample(wm, win, mval, r_col);
|
||||
}
|
||||
else {
|
||||
WM_window_pixels_read_sample_offscreen(C, win, mval, r_col);
|
||||
}
|
||||
|
||||
IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -333,7 +333,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
|
|||
|
||||
gp_rect = static_cast<uchar *>(
|
||||
MEM_mallocN(sizeof(uchar[4]) * sizex * sizey, "offscreen rect"));
|
||||
GPU_offscreen_read_pixels(oglrender->ofs, GPU_DATA_UBYTE, gp_rect);
|
||||
GPU_offscreen_read_color(oglrender->ofs, GPU_DATA_UBYTE, gp_rect);
|
||||
|
||||
for (i = 0; i < sizex * sizey * 4; i += 4) {
|
||||
blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]);
|
||||
|
|
|
@ -439,7 +439,7 @@ void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uin
|
|||
|
||||
screen_preview_draw(screen, size_x, size_y);
|
||||
|
||||
GPU_offscreen_read_pixels(offscreen, GPU_DATA_UBYTE, r_rect);
|
||||
GPU_offscreen_read_color(offscreen, GPU_DATA_UBYTE, r_rect);
|
||||
GPU_offscreen_unbind(offscreen, true);
|
||||
|
||||
GPU_offscreen_free(offscreen);
|
||||
|
|
|
@ -56,12 +56,15 @@ static int screenshot_data_create(bContext *C, wmOperator *op, ScrArea *area)
|
|||
{
|
||||
int dumprect_size[2];
|
||||
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
|
||||
/* do redraw so we don't show popups/menus */
|
||||
WM_redraw_windows(C);
|
||||
|
||||
uint *dumprect = WM_window_pixels_read_offscreen(C, win, dumprect_size);
|
||||
uint *dumprect = (WM_capabilities_flag() & WM_CAPABILITY_GPU_FRONT_BUFFER_READ) ?
|
||||
WM_window_pixels_read(wm, win, dumprect_size) :
|
||||
WM_window_pixels_read_offscreen(C, win, dumprect_size);
|
||||
|
||||
if (dumprect) {
|
||||
ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
|
||||
|
|
|
@ -537,7 +537,7 @@ void paint_sample_color(
|
|||
/* No sample found; sample directly from the GPU front buffer. */
|
||||
{
|
||||
float rgba_f[4];
|
||||
GPU_frontbuffer_read_pixels(
|
||||
GPU_frontbuffer_read_color(
|
||||
x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, 4, GPU_DATA_FLOAT, &rgba_f);
|
||||
|
||||
if (use_palette) {
|
||||
|
|
|
@ -3021,7 +3021,7 @@ static void do_vpaint_brush_blur_loops(bContext *C,
|
|||
for (const int corner : poly) {
|
||||
Color *col = lcol + corner;
|
||||
|
||||
/* Color is squared to compensate the sqrt color encoding. */
|
||||
/* Color is squared to compensate the `sqrt` color encoding. */
|
||||
blend[0] += (Blend)col->r * (Blend)col->r;
|
||||
blend[1] += (Blend)col->g * (Blend)col->g;
|
||||
blend[2] += (Blend)col->b * (Blend)col->b;
|
||||
|
@ -3164,7 +3164,7 @@ static void do_vpaint_brush_blur_verts(bContext *C,
|
|||
for (const int vert : ss->corner_verts.slice(poly)) {
|
||||
Color *col = lcol + vert;
|
||||
|
||||
/* Color is squared to compensate the sqrt color encoding. */
|
||||
/* Color is squared to compensate the `sqrt` color encoding. */
|
||||
blend[0] += (Blend)col->r * (Blend)col->r;
|
||||
blend[1] += (Blend)col->g * (Blend)col->g;
|
||||
blend[2] += (Blend)col->b * (Blend)col->b;
|
||||
|
@ -3463,7 +3463,7 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd,
|
|||
|
||||
Color *col = lcol + elem_index;
|
||||
|
||||
/* Color is squared to compensate the sqrt color encoding. */
|
||||
/* Color is squared to compensate the `sqrt` color encoding. */
|
||||
accum2->value[0] += col->r * col->r;
|
||||
accum2->value[1] += col->g * col->g;
|
||||
accum2->value[2] += col->b * col->b;
|
||||
|
|
|
@ -470,10 +470,10 @@ static int console_insert_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
/* NOTE: the "text" property is always set from key-map,
|
||||
* so we can't use #RNA_struct_property_is_set, check the length instead. */
|
||||
if (!RNA_string_length(op->ptr, "text")) {
|
||||
/* if alt/ctrl/super are pressed pass through except for utf8 character event
|
||||
* (when input method are used for utf8 inputs, the user may assign key event
|
||||
* including alt/ctrl/super like ctrl+m to commit utf8 string. in such case,
|
||||
* the modifiers in the utf8 character event make no sense.) */
|
||||
/* If alt/control/super are pressed pass through except for UTF8 character event
|
||||
* (when input method are used for UTF8 inputs, the user may assign key event
|
||||
* including alt/control/super like control-m to commit UTF8 string.
|
||||
* in such case, the modifiers in the UTF8 character event make no sense.) */
|
||||
if ((event->modifier & (KM_CTRL | KM_OSKEY)) && !event->utf8_buf[0]) {
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
|
|
@ -2177,7 +2177,7 @@ static void outliner_batch_delete_object_tag(ReportList *reports,
|
|||
reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", object->id.name + 2);
|
||||
BLI_assert((object->id.tag & LIB_TAG_DOIT) == 0);
|
||||
}
|
||||
/* FIXME: This code checking object usercount won't work as expected if a same object belongs to
|
||||
/* FIXME: This code checking object user-count won't work as expected if a same object belongs to
|
||||
* more than one collection in the scene. */
|
||||
if (ID_REAL_USERS(object) <= 1 && ID_EXTRA_USERS(object) == 0 &&
|
||||
BKE_library_ID_is_indirectly_used(bmain, object)) {
|
||||
|
|
|
@ -1976,10 +1976,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
|
|||
nullptr);
|
||||
|
||||
if (ibuf->rect_float) {
|
||||
GPU_offscreen_read_pixels(ofs, GPU_DATA_FLOAT, ibuf->rect_float);
|
||||
GPU_offscreen_read_color(ofs, GPU_DATA_FLOAT, ibuf->rect_float);
|
||||
}
|
||||
else if (ibuf->rect) {
|
||||
GPU_offscreen_read_pixels(ofs, GPU_DATA_UBYTE, ibuf->rect);
|
||||
GPU_offscreen_read_color(ofs, GPU_DATA_UBYTE, ibuf->rect);
|
||||
}
|
||||
|
||||
/* unbind */
|
||||
|
|
|
@ -160,12 +160,66 @@ void view3d_orbit_apply_dyn_ofs(float r_ofs[3],
|
|||
add_v3_v3(r_ofs, dyn_ofs);
|
||||
}
|
||||
|
||||
static void view3d_orbit_apply_dyn_ofs_ortho_correction(float ofs[3],
|
||||
const float viewquat_old[4],
|
||||
const float viewquat_new[4],
|
||||
const float dyn_ofs[3])
|
||||
{
|
||||
/* NOTE(@ideasman42): While orbiting in orthographic mode the "depth" of the offset
|
||||
* (position along the views Z-axis) is only noticeable when the view contents is clipped.
|
||||
* The likelihood of clipping depends on the clipping range & size of the scene.
|
||||
* In practice some users might not run into this, however using dynamic-offset in
|
||||
* orthographic views can cause the depth of the offset to drift while navigating the view,
|
||||
* causing unexpected clipping that seems like a bug from the user perspective, see: #104385.
|
||||
*
|
||||
* Imagine a camera is focused on a distant object. Now imagine a closer object in front of
|
||||
* the camera is used as a pivot, the camera is rotated to view it from the side (~90d rotation).
|
||||
* The outcome is the camera is now focused on a distant region to the left/right.
|
||||
* The new focal point is unlikely to point to anything useful (unless by accident).
|
||||
* Instead of a focal point - the `rv3d->ofs` is being manipulated in this case.
|
||||
*
|
||||
* Resolve by moving #RegionView3D::ofs so it is depth-aligned to `dyn_ofs`,
|
||||
* this is interpolated by the amount of rotation so minor rotations don't cause
|
||||
* the view-clipping to suddenly jump. */
|
||||
|
||||
float q_inv[4];
|
||||
|
||||
float view_z_init[3] = {0.0f, 0.0f, 1.0f};
|
||||
invert_qt_qt_normalized(q_inv, viewquat_old);
|
||||
mul_qt_v3(q_inv, view_z_init);
|
||||
|
||||
float view_z_curr[3] = {0.0f, 0.0f, 1.0f};
|
||||
invert_qt_qt_normalized(q_inv, viewquat_new);
|
||||
mul_qt_v3(q_inv, view_z_curr);
|
||||
|
||||
const float angle_cos = max_ff(0.0f, dot_v3v3(view_z_init, view_z_curr));
|
||||
/* 1.0 or more means no rotation, there is nothing to do in that case. */
|
||||
if (LIKELY(angle_cos < 1.0f)) {
|
||||
const float dot_ofs_curr = dot_v3v3(view_z_curr, ofs);
|
||||
const float dot_ofs_next = dot_v3v3(view_z_curr, dyn_ofs);
|
||||
const float ofs_delta = dot_ofs_next - dot_ofs_curr;
|
||||
if (LIKELY(ofs_delta != 0.0f)) {
|
||||
/* Calculate a factor where 0.0 represents no rotation and 1.0 represents 90d or more.
|
||||
* NOTE: Without applying the factor, the distances immediately changes
|
||||
* (useful for testing), but not good for the users experience as minor rotations
|
||||
* should not immediately adjust the depth. */
|
||||
const float factor = acosf(angle_cos) / M_PI_2;
|
||||
madd_v3_v3fl(ofs, view_z_curr, ofs_delta * factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat_new[4])
|
||||
{
|
||||
if (vod->use_dyn_ofs) {
|
||||
RegionView3D *rv3d = vod->rv3d;
|
||||
view3d_orbit_apply_dyn_ofs(
|
||||
rv3d->ofs, vod->init.ofs, vod->init.quat, viewquat_new, vod->dyn_ofs);
|
||||
|
||||
if (vod->use_dyn_ofs_ortho_correction) {
|
||||
view3d_orbit_apply_dyn_ofs_ortho_correction(
|
||||
rv3d->ofs, vod->init.quat, viewquat_new, vod->dyn_ofs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,15 @@ typedef struct ViewOpsData {
|
|||
/** Use for orbit selection and auto-dist. */
|
||||
float dyn_ofs[3];
|
||||
bool use_dyn_ofs;
|
||||
|
||||
/**
|
||||
* In orthographic views, a dynamic offset should not cause #RegionView3D::ofs to end up
|
||||
* at a location that has no relation to the content where `ofs` originated or to `dyn_ofs`.
|
||||
* Failing to do so can cause the orthographic views `ofs` to be far away from the content
|
||||
* to the point it gets clipped out of the view.
|
||||
* See #view3d_orbit_apply_dyn_ofs code-comments for an example, also see: #104385.
|
||||
*/
|
||||
bool use_dyn_ofs_ortho_correction;
|
||||
} ViewOpsData;
|
||||
|
||||
/* view3d_navigate.cc */
|
||||
|
|
|
@ -430,6 +430,10 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
viewops_flag_from_prefs() | VIEWOPS_FLAG_PERSP_ENSURE |
|
||||
(use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
|
||||
|
||||
if (vod->use_dyn_ofs && (vod->rv3d->is_persp == false)) {
|
||||
vod->use_dyn_ofs_ortho_correction = true;
|
||||
}
|
||||
|
||||
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
|
||||
|
||||
if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) {
|
||||
|
|
|
@ -218,7 +218,7 @@ static void createTransGPencil_curves(bContext *C,
|
|||
if (IS_AUTOKEY_ON(scene)) {
|
||||
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
}
|
||||
/* in some weird situations (framelock enabled) return NULL */
|
||||
/* In some weird situations (frame-lock enabled) return NULL. */
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
if (IS_AUTOKEY_ON(scene)) {
|
||||
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
}
|
||||
/* in some weird situations (framelock enabled) return NULL */
|
||||
/* In some weird situations (frame-lock enabled) return NULL. */
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
@ -628,14 +628,14 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
/* screenspace needs special matrices... */
|
||||
/* Screen-space needs special matrices. */
|
||||
if ((gps->flag & (GP_STROKE_3DSPACE | GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) ==
|
||||
0) {
|
||||
/* screenspace */
|
||||
/* Screen-space. */
|
||||
td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
|
||||
}
|
||||
else {
|
||||
/* configure 2D dataspace points so that they don't play up... */
|
||||
/* configure 2D data-space points so that they don't play up. */
|
||||
if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) {
|
||||
td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
|
||||
}
|
||||
|
@ -646,10 +646,10 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
copy_m3_m3(td->axismtx, diff_mat); /* axis orientation */
|
||||
|
||||
/* Triangulation must be calculated again,
|
||||
* so save the stroke for recalc function */
|
||||
* so save the stroke for recalculate function. */
|
||||
td->extra = gps;
|
||||
|
||||
/* save pointer to object */
|
||||
/* Save pointer to object. */
|
||||
td->ob = obact;
|
||||
|
||||
td++;
|
||||
|
@ -657,7 +657,7 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
/* March over these points, and calculate the proportional editing distances */
|
||||
/* March over these points, and calculate the proportional editing distances. */
|
||||
if (is_prop_edit && (head != tail)) {
|
||||
calc_distanceCurveVerts(head, tail - 1, false);
|
||||
}
|
||||
|
|
|
@ -285,7 +285,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
|
|||
invert_m3_m3_safe_ortho(td->mtx, td->smtx);
|
||||
}
|
||||
else {
|
||||
/* no conversion to/from dataspace */
|
||||
/* No conversion to/from data-space. */
|
||||
unit_m3(td->smtx);
|
||||
unit_m3(td->mtx);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ static void drawArrow(const uint pos_id, const enum eArrowDirection dir)
|
|||
int size = (3.0f * UI_SCALE_FAC) + (2.0f * U.pixelsize);
|
||||
|
||||
/* To line up the arrow point nicely, one end has to be extended by half its width. But
|
||||
* being on a 45 degree angle, Pythagoras says a movement of sqrt(2)/2 * (line width /2) */
|
||||
* being on a 45 degree angle, Pythagoras says a movement of `sqrt(2) / 2 * (line width / 2)`. */
|
||||
float adjust = (M_SQRT2 * ARROW_WIDTH / 4.0f);
|
||||
|
||||
if (ELEM(dir, LEFT, DOWN)) {
|
||||
|
|
|
@ -1273,7 +1273,7 @@ class OverlapMerger {
|
|||
}
|
||||
|
||||
/** Return a new root of the binary tree, with `a` and `b` as leaves. */
|
||||
static PackIsland *merge_islands(PackIsland *a, PackIsland *b, const UVPackIsland_Params ¶ms)
|
||||
static PackIsland *merge_islands(PackIsland *a, PackIsland *b)
|
||||
{
|
||||
PackIsland *result = new PackIsland();
|
||||
result->aspect_y = sqrtf(a->aspect_y * b->aspect_y);
|
||||
|
@ -1306,7 +1306,7 @@ class OverlapMerger {
|
|||
if (overlap(island, sub_islands[j])) {
|
||||
merge_trace.append(island);
|
||||
merge_trace.append(sub_islands[j]);
|
||||
island = merge_islands(island, sub_islands[j], params);
|
||||
island = merge_islands(island, sub_islands[j]);
|
||||
merge_trace.append(island);
|
||||
sub_islands.remove(j);
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ static void generate_geometry(GpencilModifierData *md,
|
|||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
bool found = false;
|
||||
|
||||
/* Get bounbox for relative offset. */
|
||||
/* Get bound-box for relative offset. */
|
||||
float size[3] = {0.0f, 0.0f, 0.0f};
|
||||
if (mmd->flag & GP_ARRAY_USE_RELATIVE) {
|
||||
float min[3];
|
||||
|
|
|
@ -61,7 +61,7 @@ static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
|
|||
BKE_gpencil_modifier_copydata_generic(md, target);
|
||||
}
|
||||
|
||||
/* change stroke offsetness */
|
||||
/* Change stroke offset. */
|
||||
static void deformStroke(GpencilModifierData *md,
|
||||
Depsgraph *UNUSED(depsgraph),
|
||||
Object *ob,
|
||||
|
|
|
@ -539,7 +539,7 @@ void GPU_framebuffer_read_color(GPUFrameBuffer *framebuffer,
|
|||
* TODO: Emulate this by doing some slow texture copy on the backend side or try to read the areas
|
||||
* offscreen textures directly.
|
||||
*/
|
||||
void GPU_frontbuffer_read_pixels(
|
||||
void GPU_frontbuffer_read_color(
|
||||
int x, int y, int width, int height, int channels, eGPUDataFormat data_format, void *r_data);
|
||||
|
||||
/**
|
||||
|
@ -623,7 +623,12 @@ void GPU_offscreen_unbind(GPUOffScreen *offscreen, bool restore);
|
|||
* attachment type.
|
||||
* IMPORTANT: \a r_data must be big enough for all pixels in \a data_format .
|
||||
*/
|
||||
void GPU_offscreen_read_pixels(GPUOffScreen *offscreen, eGPUDataFormat data_format, void *r_data);
|
||||
void GPU_offscreen_read_color(GPUOffScreen *offscreen, eGPUDataFormat data_format, void *r_data);
|
||||
/**
|
||||
* A version of #GPU_offscreen_read_color that reads into a region.
|
||||
*/
|
||||
void GPU_offscreen_read_color_region(
|
||||
GPUOffScreen *offscreen, eGPUDataFormat data_format, int x, int y, int w, int h, void *r_data);
|
||||
|
||||
/**
|
||||
* Blit the offscreen color texture to the active framebuffer at the `(x, y)` location.
|
||||
|
|
|
@ -484,8 +484,7 @@ void GPU_framebuffer_read_color(GPUFrameBuffer *gpu_fb,
|
|||
unwrap(gpu_fb)->read(GPU_COLOR_BIT, format, rect, channels, slot, data);
|
||||
}
|
||||
|
||||
/* TODO(fclem): rename to read_color. */
|
||||
void GPU_frontbuffer_read_pixels(
|
||||
void GPU_frontbuffer_read_color(
|
||||
int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data)
|
||||
{
|
||||
int rect[4] = {x, y, w, h};
|
||||
|
@ -747,15 +746,26 @@ void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y)
|
|||
ofs_fb->blit_to(GPU_COLOR_BIT, 0, ctx->active_fb, 0, x, y);
|
||||
}
|
||||
|
||||
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, eGPUDataFormat format, void *pixels)
|
||||
void GPU_offscreen_read_color_region(
|
||||
GPUOffScreen *ofs, eGPUDataFormat format, int x, int y, int w, int h, void *r_data)
|
||||
{
|
||||
BLI_assert(ELEM(format, GPU_DATA_UBYTE, GPU_DATA_FLOAT));
|
||||
BLI_assert(x >= 0 && y >= 0 && w > 0 && h > 0);
|
||||
BLI_assert(x + w <= GPU_texture_width(ofs->color));
|
||||
BLI_assert(y + h <= GPU_texture_height(ofs->color));
|
||||
|
||||
GPUFrameBuffer *ofs_fb = gpu_offscreen_fb_get(ofs);
|
||||
GPU_framebuffer_read_color(ofs_fb, x, y, w, h, 4, 0, format, r_data);
|
||||
}
|
||||
|
||||
void GPU_offscreen_read_color(GPUOffScreen *ofs, eGPUDataFormat format, void *r_data)
|
||||
{
|
||||
BLI_assert(ELEM(format, GPU_DATA_UBYTE, GPU_DATA_FLOAT));
|
||||
|
||||
const int w = GPU_texture_width(ofs->color);
|
||||
const int h = GPU_texture_height(ofs->color);
|
||||
|
||||
GPUFrameBuffer *ofs_fb = gpu_offscreen_fb_get(ofs);
|
||||
GPU_framebuffer_read_color(ofs_fb, 0, 0, w, h, 4, 0, format, pixels);
|
||||
GPU_offscreen_read_color_region(ofs, format, 0, 0, w, h, r_data);
|
||||
}
|
||||
|
||||
int GPU_offscreen_width(const GPUOffScreen *ofs)
|
||||
|
|
|
@ -196,37 +196,41 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams
|
|||
world_and_axes_normal_transform);
|
||||
|
||||
/* Face data. */
|
||||
plyData.face_vertices.reserve(mesh->totloop);
|
||||
plyData.face_sizes.reserve(mesh->totpoly);
|
||||
plyData.face_vertices.reserve(plyData.face_vertices.size() + mesh->totloop);
|
||||
for (const int corner : IndexRange(mesh->totloop)) {
|
||||
int ply_index = loop_to_ply[corner];
|
||||
BLI_assert(ply_index >= 0 && ply_index < ply_to_vertex.size());
|
||||
plyData.face_vertices.append_unchecked(ply_index + vertex_offset);
|
||||
}
|
||||
|
||||
plyData.face_sizes.reserve(plyData.face_sizes.size() + mesh->totpoly);
|
||||
for (const int i : polys.index_range()) {
|
||||
const IndexRange poly = polys[i];
|
||||
for (const int corner : poly) {
|
||||
int ply_index = loop_to_ply[corner];
|
||||
BLI_assert(ply_index >= 0 && ply_index < ply_to_vertex.size());
|
||||
plyData.face_vertices.append(ply_index + vertex_offset);
|
||||
}
|
||||
plyData.face_sizes.append(poly.size());
|
||||
plyData.face_sizes.append_unchecked(poly.size());
|
||||
}
|
||||
|
||||
/* Vertices */
|
||||
plyData.vertices.reserve(ply_to_vertex.size());
|
||||
plyData.vertices.reserve(plyData.vertices.size() + ply_to_vertex.size());
|
||||
Span<float3> vert_positions = mesh->vert_positions();
|
||||
for (int vertex_index : ply_to_vertex) {
|
||||
float3 pos = vert_positions[vertex_index];
|
||||
mul_m4_v3(world_and_axes_transform, pos);
|
||||
mul_v3_fl(pos, export_params.global_scale);
|
||||
plyData.vertices.append(pos);
|
||||
plyData.vertices.append_unchecked(pos);
|
||||
}
|
||||
|
||||
/* UV's */
|
||||
if (!uvs.is_empty()) {
|
||||
if (uvs.is_empty()) {
|
||||
uvs.append_n_times(float2(0), ply_to_vertex.size());
|
||||
}
|
||||
else {
|
||||
BLI_assert(uvs.size() == ply_to_vertex.size());
|
||||
plyData.uv_coordinates = uvs;
|
||||
plyData.uv_coordinates.extend(uvs);
|
||||
}
|
||||
|
||||
/* Normals */
|
||||
if (export_params.export_normals) {
|
||||
plyData.vertex_normals.reserve(ply_to_vertex.size());
|
||||
plyData.vertex_normals.reserve(plyData.vertex_normals.size() + ply_to_vertex.size());
|
||||
const Span<float3> vert_normals = mesh->vert_normals();
|
||||
for (int vertex_index : ply_to_vertex) {
|
||||
float3 normal = vert_normals[vertex_index];
|
||||
|
|
|
@ -715,7 +715,7 @@ enum {
|
|||
/**
|
||||
* Long-life tags giving important info about general ID management.
|
||||
*
|
||||
* These tags are typically not chnaged often, if ever, during an ID's life.
|
||||
* These tags are typically not changed often, if ever, during an ID's life.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -793,7 +793,7 @@ enum {
|
|||
LIB_TAG_LIB_OVERRIDE_NEED_RESYNC = 1 << 8,
|
||||
|
||||
/**
|
||||
* Short-life tags used during specific processes, like blendfile readind.
|
||||
* Short-life tags used during specific processes, like blend-file reading.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -2548,7 +2548,7 @@ static void rna_def_modifier_gpencilbuild(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Time Alignment", "How should strokes start to appear/disappear");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
/* Which time mode to use: Current frames, manual percentage, or drawspeed. */
|
||||
/* Which time mode to use: Current frames, manual percentage, or draw-speed. */
|
||||
prop = RNA_def_property(srna, "time_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "time_mode");
|
||||
RNA_def_property_enum_items(prop, gpencil_build_time_mode_items);
|
||||
|
|
|
@ -1038,7 +1038,7 @@ static void rna_EnumProperty_items_begin(CollectionPropertyIterator *iter, Point
|
|||
|
||||
static void rna_EnumProperty_items_ui_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
/* No skip-funciton, include all "UI" items. */
|
||||
/* No skip-function, include all "UI" items. */
|
||||
rna_EnumProperty_items_begin_impl(iter, ptr, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -2787,7 +2787,7 @@ static void rna_def_gpencil_interpolate(BlenderRNA *brna)
|
|||
"Grease Pencil Interpolate Settings",
|
||||
"Settings for Grease Pencil interpolation tools");
|
||||
|
||||
/* custom curvemap */
|
||||
/* Custom curve-map. */
|
||||
prop = RNA_def_property(srna, "interpolation_curve", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "custom_ipo");
|
||||
RNA_def_property_struct_type(prop, "CurveMapping");
|
||||
|
|
|
@ -134,6 +134,12 @@ typedef enum eWM_CapabilitiesFlag {
|
|||
* (typically set when interactively selecting text).
|
||||
*/
|
||||
WM_CAPABILITY_PRIMARY_CLIPBOARD = (1 << 2),
|
||||
/**
|
||||
* Reading from the back-buffer is supported.
|
||||
*/
|
||||
WM_CAPABILITY_GPU_FRONT_BUFFER_READ = (1 << 3),
|
||||
/** Ability to copy/paste system clipboard images. */
|
||||
WM_CAPABILITY_CLIPBOARD_IMAGES = (1 << 4),
|
||||
} eWM_CapabilitiesFlag;
|
||||
|
||||
eWM_CapabilitiesFlag WM_capabilities_flag(void);
|
||||
|
@ -155,11 +161,6 @@ wmWindow *WM_window_find_under_cursor(wmWindow *win, const int mval[2], int r_mv
|
|||
*/
|
||||
wmWindow *WM_window_find_by_area(wmWindowManager *wm, const struct ScrArea *area);
|
||||
|
||||
void WM_window_pixel_sample_read(const wmWindowManager *wm,
|
||||
const wmWindow *win,
|
||||
const int pos[2],
|
||||
float r_col[3]);
|
||||
|
||||
/**
|
||||
* Read pixels from the front-buffer (fast).
|
||||
*
|
||||
|
@ -171,6 +172,11 @@ void WM_window_pixel_sample_read(const wmWindowManager *wm,
|
|||
* the front-buffer state to be invalid under some EGL configurations.
|
||||
*/
|
||||
uint *WM_window_pixels_read(struct wmWindowManager *wm, struct wmWindow *win, int r_size[2]);
|
||||
void WM_window_pixels_read_sample(const wmWindowManager *wm,
|
||||
const wmWindow *win,
|
||||
const int pos[2],
|
||||
float r_col[3]);
|
||||
|
||||
/**
|
||||
* Draw the window & read pixels from an off-screen buffer (slower than #WM_window_pixels_read).
|
||||
*
|
||||
|
@ -178,6 +184,10 @@ uint *WM_window_pixels_read(struct wmWindowManager *wm, struct wmWindow *win, in
|
|||
* (see in-line code comments for details).
|
||||
*/
|
||||
uint *WM_window_pixels_read_offscreen(struct bContext *C, struct wmWindow *win, int r_size[2]);
|
||||
bool WM_window_pixels_read_sample_offscreen(struct bContext *C,
|
||||
struct wmWindow *win,
|
||||
const int pos[2],
|
||||
float r_col[3]);
|
||||
|
||||
/**
|
||||
* Support for native pixel size
|
||||
|
|
|
@ -983,7 +983,7 @@ static void wm_drag_draw_default(bContext *C, wmWindow *win, wmDrag *drag, const
|
|||
}
|
||||
wm_drag_draw_item_name(drag, UNPACK2(xy_tmp));
|
||||
|
||||
/* Operator name with roundbox. */
|
||||
/* Operator name with round-box. */
|
||||
wm_drag_draw_tooltip(C, win, drag, xy);
|
||||
}
|
||||
|
||||
|
|
|
@ -1238,11 +1238,43 @@ uint *WM_window_pixels_read_offscreen(bContext *C, wmWindow *win, int r_size[2])
|
|||
GPU_offscreen_bind(offscreen, false);
|
||||
wm_draw_window_onscreen(C, win, -1);
|
||||
GPU_offscreen_unbind(offscreen, false);
|
||||
GPU_offscreen_read_pixels(offscreen, GPU_DATA_UBYTE, rect);
|
||||
GPU_offscreen_read_color(offscreen, GPU_DATA_UBYTE, rect);
|
||||
GPU_offscreen_free(offscreen);
|
||||
return rect;
|
||||
}
|
||||
|
||||
bool WM_window_pixels_read_sample_offscreen(bContext *C,
|
||||
wmWindow *win,
|
||||
const int pos[2],
|
||||
float r_col[3])
|
||||
{
|
||||
/* A version of #WM_window_pixels_read_offscreen. */
|
||||
|
||||
const int size[2] = {WM_window_pixels_x(win), WM_window_pixels_y(win)};
|
||||
zero_v3(r_col);
|
||||
|
||||
/* While this shouldn't happen, return in the case it does. */
|
||||
BLI_assert((uint)pos[0] < (uint)size[0] && (uint)pos[1] < (uint)size[1]);
|
||||
if (!((uint)pos[0] < (uint)size[0] && (uint)pos[1] < (uint)size[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(
|
||||
size[0], size[1], false, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
|
||||
if (UNLIKELY(!offscreen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float rect_pixel[4];
|
||||
GPU_offscreen_bind(offscreen, false);
|
||||
wm_draw_window_onscreen(C, win, -1);
|
||||
GPU_offscreen_unbind(offscreen, false);
|
||||
GPU_offscreen_read_color_region(offscreen, GPU_DATA_FLOAT, pos[0], pos[1], 1, 1, rect_pixel);
|
||||
GPU_offscreen_free(offscreen);
|
||||
copy_v3_v3(r_col, rect_pixel);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -1347,11 +1347,10 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
|
|||
if (state != GHOST_kWindowStateMinimized) {
|
||||
/*
|
||||
* Ghost sometimes send size or move events when the window hasn't changed.
|
||||
* One case of this is using compiz on linux. To alleviate the problem
|
||||
* we ignore all such event here.
|
||||
* One case of this is using COMPIZ on Linux.
|
||||
* To alleviate the problem we ignore all such event here.
|
||||
*
|
||||
* It might be good to eventually do that at Ghost level, but that is for
|
||||
* another time.
|
||||
* It might be good to eventually do that at GHOST level, but that is for another time.
|
||||
*/
|
||||
if (wm_window_update_size_position(win)) {
|
||||
const bScreen *screen = WM_window_get_active_screen(win);
|
||||
|
@ -1850,6 +1849,12 @@ eWM_CapabilitiesFlag WM_capabilities_flag(void)
|
|||
if (ghost_flag & GHOST_kCapabilityPrimaryClipboard) {
|
||||
flag |= WM_CAPABILITY_PRIMARY_CLIPBOARD;
|
||||
}
|
||||
if (ghost_flag & GHOST_kCapabilityGPUReadFrontBuffer) {
|
||||
flag |= WM_CAPABILITY_GPU_FRONT_BUFFER_READ;
|
||||
}
|
||||
if (ghost_flag & GHOST_kCapabilityClipboardImages) {
|
||||
flag |= WM_CAPABILITY_CLIPBOARD_IMAGES;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
@ -2218,28 +2223,6 @@ wmWindow *WM_window_find_by_area(wmWindowManager *wm, const struct ScrArea *area
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void WM_window_pixel_sample_read(const wmWindowManager *wm,
|
||||
const wmWindow *win,
|
||||
const int pos[2],
|
||||
float r_col[3])
|
||||
{
|
||||
bool setup_context = wm->windrawable != win;
|
||||
|
||||
if (setup_context) {
|
||||
GHOST_ActivateWindowDrawingContext(win->ghostwin);
|
||||
GPU_context_active_set(win->gpuctx);
|
||||
}
|
||||
|
||||
GPU_frontbuffer_read_pixels(pos[0], pos[1], 1, 1, 3, GPU_DATA_FLOAT, r_col);
|
||||
|
||||
if (setup_context) {
|
||||
if (wm->windrawable) {
|
||||
GHOST_ActivateWindowDrawingContext(wm->windrawable->ghostwin);
|
||||
GPU_context_active_set(wm->windrawable->gpuctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -2251,6 +2234,8 @@ void WM_window_pixel_sample_read(const wmWindowManager *wm,
|
|||
|
||||
uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2])
|
||||
{
|
||||
BLI_assert(WM_capabilities_flag() & WM_CAPABILITY_GPU_FRONT_BUFFER_READ);
|
||||
|
||||
/* WARNING: Reading from the front-buffer immediately after drawing may fail,
|
||||
* for a slower but more reliable version of this function #WM_window_pixels_read_offscreen
|
||||
* should be preferred. See it's comments for details on why it's needed, see also #98462. */
|
||||
|
@ -2266,7 +2251,7 @@ uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2])
|
|||
const uint rect_len = r_size[0] * r_size[1];
|
||||
uint *rect = MEM_mallocN(sizeof(*rect) * rect_len, __func__);
|
||||
|
||||
GPU_frontbuffer_read_pixels(0, 0, r_size[0], r_size[1], 4, GPU_DATA_UBYTE, rect);
|
||||
GPU_frontbuffer_read_color(0, 0, r_size[0], r_size[1], 4, GPU_DATA_UBYTE, rect);
|
||||
|
||||
if (setup_context) {
|
||||
if (wm->windrawable) {
|
||||
|
@ -2284,6 +2269,29 @@ uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2])
|
|||
return (uint *)rect;
|
||||
}
|
||||
|
||||
void WM_window_pixels_read_sample(const wmWindowManager *wm,
|
||||
const wmWindow *win,
|
||||
const int pos[2],
|
||||
float r_col[3])
|
||||
{
|
||||
BLI_assert(WM_capabilities_flag() & WM_CAPABILITY_GPU_FRONT_BUFFER_READ);
|
||||
bool setup_context = wm->windrawable != win;
|
||||
|
||||
if (setup_context) {
|
||||
GHOST_ActivateWindowDrawingContext(win->ghostwin);
|
||||
GPU_context_active_set(win->gpuctx);
|
||||
}
|
||||
|
||||
GPU_frontbuffer_read_color(pos[0], pos[1], 1, 1, 3, GPU_DATA_FLOAT, r_col);
|
||||
|
||||
if (setup_context) {
|
||||
if (wm->windrawable) {
|
||||
GHOST_ActivateWindowDrawingContext(wm->windrawable->ghostwin);
|
||||
GPU_context_active_set(wm->windrawable->gpuctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -58,6 +58,7 @@ PATHS_EXCLUDE = set(
|
|||
"tools/utils/git_log.py",
|
||||
"tools/utils/git_log_review_commits.py",
|
||||
"tools/utils/git_log_review_commits_advanced.py",
|
||||
"tools/utils/gitea_inactive_developers.py",
|
||||
"tools/utils/make_cursor_gui.py",
|
||||
"tools/utils/make_gl_stipple_from_xpm.py",
|
||||
"tools/utils/make_shape_2d_from_blend.py",
|
||||
|
|
|
@ -83,6 +83,7 @@ dict_custom = {
|
|||
"deduplication",
|
||||
"defocus",
|
||||
"degeneracies",
|
||||
"deletable",
|
||||
"deleter",
|
||||
"denoised",
|
||||
"denoiser",
|
||||
|
@ -187,6 +188,7 @@ dict_custom = {
|
|||
"orthonormalized",
|
||||
"overridable",
|
||||
"paddings",
|
||||
"paintable",
|
||||
"pannable",
|
||||
"parallelepiped",
|
||||
"parallelize",
|
||||
|
|
|
@ -31,7 +31,9 @@ from typing import (
|
|||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
Union,
|
||||
)
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
|
||||
logger = logging.getLogger(__file__)
|
||||
|
||||
|
@ -43,7 +45,7 @@ class TeamMember():
|
|||
full_name: str
|
||||
last_login: datetime.datetime
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
return "{id};{login};{full_name};{last_login};{url}\n".format(
|
||||
id=self.id,
|
||||
login=self.login,
|
||||
|
@ -64,22 +66,25 @@ retry: Callable[[F], F] = retry_decorator(
|
|||
|
||||
def assert_cast(typ: Type[T], obj: object) -> T:
|
||||
assert isinstance(obj, typ), f'object is not of type {typ}: {obj}'
|
||||
return cast(T, obj)
|
||||
# NOTE: MYPY warns the cast is redundant, we might consider removing it.
|
||||
return cast(T, obj) # type: ignore
|
||||
|
||||
|
||||
def get_date_object(date_string: str) -> datetime.datetime:
|
||||
return iso8601.parse_date(date_string)
|
||||
result = iso8601.parse_date(date_string)
|
||||
assert isinstance(result, datetime.datetime)
|
||||
return result
|
||||
|
||||
|
||||
results_per_page = 25
|
||||
|
||||
|
||||
def get_next_page(headers: Dict, page: int) -> int:
|
||||
def get_next_page(headers: CaseInsensitiveDict[str], page: Optional[Page]) -> Optional[Page]:
|
||||
"""
|
||||
Parse the header looking for reference to next.
|
||||
"""
|
||||
total_count = int(assert_cast(str, headers.get('X-Total-Count')))
|
||||
next_page = page + 1 if page else 1
|
||||
next_page = Page(page + 1 if page else 1)
|
||||
|
||||
if next_page * results_per_page > total_count:
|
||||
return None
|
||||
|
@ -105,7 +110,7 @@ def fetch_single(
|
|||
'Authorization': 'token ' + api_token,
|
||||
}
|
||||
|
||||
params = {
|
||||
params: Dict[str, Union[str, int]] = {
|
||||
'limit': results_per_page,
|
||||
**data,
|
||||
}
|
||||
|
@ -119,7 +124,7 @@ def fetch_single(
|
|||
response_json = response.json()
|
||||
|
||||
next_page = get_next_page(response.headers, page)
|
||||
return response_json, None if next_page is None else Page(next_page)
|
||||
return response_json, None if next_page is None else next_page
|
||||
|
||||
|
||||
def fetch_all(
|
||||
|
@ -226,7 +231,7 @@ api_url = yarl.URL(gitea_domain + 'api/v1/')
|
|||
organization_name = "blender"
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
for team_name in teams:
|
||||
logger.warning(team_name)
|
||||
members = fetch_team_members(
|
||||
|
|
Loading…
Reference in New Issue