Texture Paint: unify missing data and slots panels, better auto position nodes.
Differential Revision: https://developer.blender.org/D3694
This commit is contained in:
parent
09ea940e7b
commit
d0eed5e50a
|
@ -207,64 +207,6 @@ class View3DPaintPanel(UnifiedPaintPanel):
|
|||
bl_region_type = 'WINDOW'
|
||||
|
||||
|
||||
class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
|
||||
bl_category = "Tools"
|
||||
bl_context = ".imagepaint" # dot on purpose (access from topbar)
|
||||
bl_label = "Missing Data"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
toolsettings = context.tool_settings.image_paint
|
||||
return context.image_paint_object and not toolsettings.detect_data()
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
toolsettings = context.tool_settings.image_paint
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Missing Data", icon='ERROR')
|
||||
if toolsettings.missing_uvs:
|
||||
col.separator()
|
||||
col.label(text="Missing UVs", icon='INFO')
|
||||
col.label(text="Unwrap the mesh in edit mode or generate a simple UV layer")
|
||||
col.operator("paint.add_simple_uvs")
|
||||
|
||||
if toolsettings.mode == 'MATERIAL':
|
||||
if toolsettings.missing_materials:
|
||||
col.separator()
|
||||
col.label(text="Missing Materials", icon='INFO')
|
||||
col.label(text="Add a material and paint slot below")
|
||||
col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
|
||||
elif toolsettings.missing_texture:
|
||||
ob = context.active_object
|
||||
mat = ob.active_material
|
||||
|
||||
col.separator()
|
||||
if mat:
|
||||
col.label(text="Missing Texture Slots", icon='INFO')
|
||||
col.label(text="Add a paint slot below")
|
||||
col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
|
||||
else:
|
||||
col.label(text="Missing Materials", icon='INFO')
|
||||
col.label(text="Add a material and paint slot below")
|
||||
col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
|
||||
|
||||
elif toolsettings.mode == 'IMAGE':
|
||||
if toolsettings.missing_texture:
|
||||
col.separator()
|
||||
col.label(text="Missing Canvas", icon='INFO')
|
||||
col.label(text="Add or assign a canvas image below")
|
||||
col.label(text="Canvas Image:")
|
||||
col.template_ID(toolsettings, "canvas", new="image.new", open="image.open")
|
||||
|
||||
if toolsettings.missing_stencil:
|
||||
col.separator()
|
||||
col.label(text="Missing Stencil", icon='INFO')
|
||||
col.label(text="Add or assign a stencil image below")
|
||||
col.label(text="Stencil Image:")
|
||||
col.template_ID(toolsettings, "stencil_image", new="image.new", open="image.open")
|
||||
|
||||
|
||||
# TODO, move to space_view3d.py
|
||||
class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
bl_context = ".paint_common" # dot on purpose (access from topbar)
|
||||
|
@ -567,7 +509,6 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
|
|||
col.template_list("MATERIAL_UL_matslots", "layers",
|
||||
ob, "material_slots",
|
||||
ob, "active_material_index", rows=2)
|
||||
|
||||
mat = ob.active_material
|
||||
if mat:
|
||||
col.label(text="Available Paint Slots:")
|
||||
|
@ -595,6 +536,43 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
|
|||
col.separator()
|
||||
col.operator("image.save_dirty", text="Save All Images")
|
||||
|
||||
### Add Texture paint UVs/slots
|
||||
if settings.missing_uvs:
|
||||
col.separator()
|
||||
col.label(text="No UVs available", icon='INFO')
|
||||
col.operator("paint.add_simple_uvs")
|
||||
|
||||
if settings.mode == 'MATERIAL':
|
||||
if settings.missing_materials:
|
||||
col.separator()
|
||||
col.label(text="Add a material and paint slot below")
|
||||
col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
|
||||
else:
|
||||
ob = context.active_object
|
||||
mat = ob.active_material
|
||||
|
||||
col.separator()
|
||||
if mat:
|
||||
col.label(text="Add a paint slot below")
|
||||
col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
|
||||
else:
|
||||
col.label(text="Add a material and paint slot below")
|
||||
col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
|
||||
|
||||
elif settings.mode == 'IMAGE':
|
||||
if settings.missing_texture:
|
||||
col.separator()
|
||||
col.label(text="Missing Canvas", icon='INFO')
|
||||
col.label(text="Add or assign a canvas image below")
|
||||
col.label(text="Canvas Image:")
|
||||
col.template_ID(settings, "canvas", new="image.new", open="image.open")
|
||||
|
||||
if settings.missing_stencil:
|
||||
col.separator()
|
||||
col.label(text="Missing Stencil", icon='INFO')
|
||||
col.label(text="Add or assign a stencil image below")
|
||||
col.label(text="Stencil Image:")
|
||||
col.template_ID(settings, "stencil_image", new="image.new", open="image.open")
|
||||
|
||||
# TODO, move to space_view3d.py
|
||||
class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
|
||||
|
@ -1781,7 +1759,6 @@ classes = (
|
|||
VIEW3D_PT_tools_curveedit_options_stroke,
|
||||
VIEW3D_PT_tools_armatureedit_options,
|
||||
VIEW3D_PT_tools_posemode_options,
|
||||
VIEW3D_PT_imapaint_tools_missing,
|
||||
VIEW3D_PT_tools_brush,
|
||||
TEXTURE_UL_texpaintslots,
|
||||
VIEW3D_MT_tools_projectpaint_uvlayer,
|
||||
|
|
|
@ -466,6 +466,10 @@ bool nodeAttachNodeCheck(struct bNode *node, struct bNode *parent);
|
|||
void nodeAttachNode(struct bNode *node, struct bNode *parent);
|
||||
void nodeDetachNode(struct bNode *node);
|
||||
|
||||
void nodePositionRelative(struct bNode *from_node, struct bNode *to_node,
|
||||
struct bNodeSocket *from_sock, struct bNodeSocket *to_sock);
|
||||
void nodePositionPropagate(struct bNode *node);
|
||||
|
||||
struct bNode *nodeFindNodebyName(struct bNodeTree *ntree, const char *name);
|
||||
int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex);
|
||||
struct bNode *nodeFindRootParent(bNode *node);
|
||||
|
|
|
@ -1213,6 +1213,54 @@ void nodeDetachNode(struct bNode *node)
|
|||
}
|
||||
}
|
||||
|
||||
void nodePositionRelative(bNode *from_node, bNode *to_node, bNodeSocket *from_sock, bNodeSocket *to_sock)
|
||||
{
|
||||
float offset_x;
|
||||
int tot_sock_idx;
|
||||
|
||||
/* Socket to plug into. */
|
||||
if (SOCK_IN == to_sock->in_out) {
|
||||
offset_x = - (from_node->typeinfo->width + 50);
|
||||
tot_sock_idx = BLI_listbase_count(&to_node->outputs);
|
||||
tot_sock_idx += BLI_findindex(&to_node->inputs, to_sock);
|
||||
}
|
||||
else {
|
||||
offset_x = to_node->typeinfo->width + 50;
|
||||
tot_sock_idx = BLI_findindex(&to_node->outputs, to_sock);
|
||||
}
|
||||
|
||||
BLI_assert(tot_sock_idx != -1);
|
||||
|
||||
float offset_y = U.widget_unit * tot_sock_idx;
|
||||
|
||||
/* Output socket. */
|
||||
if (SOCK_IN == from_sock->in_out) {
|
||||
tot_sock_idx = BLI_listbase_count(&from_node->outputs);
|
||||
tot_sock_idx += BLI_findindex(&from_node->inputs, from_sock);
|
||||
}
|
||||
else {
|
||||
tot_sock_idx = BLI_findindex(&from_node->outputs, from_sock);
|
||||
}
|
||||
|
||||
BLI_assert(tot_sock_idx != -1);
|
||||
|
||||
offset_y -= U.widget_unit * tot_sock_idx;
|
||||
|
||||
from_node->locx = to_node->locx + offset_x;
|
||||
from_node->locy = to_node->locy - offset_y;
|
||||
}
|
||||
|
||||
void nodePositionPropagate(bNode *node)
|
||||
{
|
||||
for (bNodeSocket *nsock = node->inputs.first; nsock; nsock = nsock->next) {
|
||||
if (nsock->link != NULL) {
|
||||
bNodeLink *link = nsock->link;
|
||||
nodePositionRelative(link->fromnode, link->tonode, link->fromsock, link->tosock);
|
||||
nodePositionPropagate(link->fromnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ntreeInitDefault(bNodeTree *ntree)
|
||||
{
|
||||
ntree_set_typeinfo(ntree, NULL);
|
||||
|
|
|
@ -5696,10 +5696,10 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
|
|||
|
||||
/* Connect to first available principled bsdf node. */
|
||||
bNode *in_node;
|
||||
bNode *out_node = imanode;
|
||||
in_node = ntreeFindType(ntree, SH_NODE_BSDF_PRINCIPLED);
|
||||
|
||||
if (in_node != NULL) {
|
||||
bNode *out_node = imanode;
|
||||
bNodeSocket *out_sock = nodeFindSocket(out_node, SOCK_OUT, "Color");
|
||||
bNodeSocket *in_sock = NULL;
|
||||
|
||||
|
@ -5752,10 +5752,14 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
|
|||
bNodeLink *link = in_sock ? in_sock->link : NULL;
|
||||
if (in_sock != NULL && link == NULL) {
|
||||
nodeAddLink(ntree, out_node, out_sock, in_node, in_sock);
|
||||
|
||||
nodePositionRelative(out_node, in_node, out_sock, in_sock);
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
/* In case we added more than one node, position them too. */
|
||||
nodePositionPropagate(out_node);
|
||||
|
||||
if (ima) {
|
||||
BKE_texpaint_slot_refresh_cache(scene, ma);
|
||||
|
|
|
@ -218,20 +218,15 @@ static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *
|
|||
else if (!node_from) {
|
||||
node_from = nodeAddStaticNode(C, ntree, type);
|
||||
if (node_prev != NULL) {
|
||||
/* If we're replacing existing node, use it's location. */
|
||||
/* If we're replacing existing node, use its location. */
|
||||
node_from->locx = node_prev->locx;
|
||||
node_from->locy = node_prev->locy;
|
||||
node_from->offsetx = node_prev->offsetx;
|
||||
node_from->offsety = node_prev->offsety;
|
||||
}
|
||||
else {
|
||||
/* Avoid exact intersection of nodes.
|
||||
* TODO(sergey): Still not ideal, but better than nothing.
|
||||
*/
|
||||
int index = BLI_findindex(&node_to->inputs, sock_to);
|
||||
BLI_assert(index != -1);
|
||||
node_from->locx = node_to->locx - (node_from->typeinfo->width + 50);
|
||||
node_from->locy = node_to->locy - (node_from->typeinfo->height * index);
|
||||
sock_from_tmp = BLI_findlink(&node_from->outputs, item->socket_index);
|
||||
nodePositionRelative(node_from, node_to, sock_from_tmp, sock_to);
|
||||
}
|
||||
|
||||
node_link_item_apply(bmain, node_from, item);
|
||||
|
|
Loading…
Reference in New Issue