bugfix #26267
ImageWindow + 3D view texture paint + texture preview render + texture nodes. Threading hell! But it works now :)
This commit is contained in:
@@ -81,6 +81,7 @@ void default_mtex(struct MTex *mtex);
|
|||||||
struct MTex *add_mtex(void);
|
struct MTex *add_mtex(void);
|
||||||
struct MTex *add_mtex_id(struct ID *id, int slot);
|
struct MTex *add_mtex_id(struct ID *id, int slot);
|
||||||
struct Tex *copy_texture(struct Tex *tex);
|
struct Tex *copy_texture(struct Tex *tex);
|
||||||
|
struct Tex *localize_texture(struct Tex *tex);
|
||||||
void make_local_texture(struct Tex *tex);
|
void make_local_texture(struct Tex *tex);
|
||||||
void autotexname(struct Tex *tex);
|
void autotexname(struct Tex *tex);
|
||||||
|
|
||||||
|
@@ -1188,6 +1188,12 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
|
|||||||
newtree= MEM_dupallocN(ntree);
|
newtree= MEM_dupallocN(ntree);
|
||||||
copy_libblock_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */
|
copy_libblock_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* in case a running nodetree is copied */
|
||||||
|
newtree->init &= ~(NTREE_EXEC_INIT);
|
||||||
|
newtree->threadstack= NULL;
|
||||||
|
newtree->stack= NULL;
|
||||||
|
|
||||||
newtree->nodes.first= newtree->nodes.last= NULL;
|
newtree->nodes.first= newtree->nodes.last= NULL;
|
||||||
newtree->links.first= newtree->links.last= NULL;
|
newtree->links.first= newtree->links.last= NULL;
|
||||||
|
|
||||||
@@ -2771,8 +2777,8 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
|||||||
/* ********** copy composite tree entirely, to allow threaded exec ******************* */
|
/* ********** copy composite tree entirely, to allow threaded exec ******************* */
|
||||||
/* ***************** do NOT execute this in a thread! ****************** */
|
/* ***************** do NOT execute this in a thread! ****************** */
|
||||||
|
|
||||||
/* returns localized composite tree for execution in threads */
|
/* returns localized tree for execution in threads */
|
||||||
/* local tree then owns all compbufs */
|
/* local tree then owns all compbufs (for composite) */
|
||||||
bNodeTree *ntreeLocalize(bNodeTree *ntree)
|
bNodeTree *ntreeLocalize(bNodeTree *ntree)
|
||||||
{
|
{
|
||||||
bNodeTree *ltree;
|
bNodeTree *ltree;
|
||||||
@@ -2886,7 +2892,7 @@ void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ntree->type==NTREE_SHADER) {
|
else if(ELEM(ntree->type, NTREE_SHADER, NTREE_TEXTURE)) {
|
||||||
/* copy over contents of previews */
|
/* copy over contents of previews */
|
||||||
for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
|
for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
|
||||||
if(node_exists(ntree, lnode->new_node)) {
|
if(node_exists(ntree, lnode->new_node)) {
|
||||||
|
@@ -480,11 +480,13 @@ int colorband_element_remove(struct ColorBand *coba, int index)
|
|||||||
void free_texture(Tex *tex)
|
void free_texture(Tex *tex)
|
||||||
{
|
{
|
||||||
free_plugin_tex(tex->plugin);
|
free_plugin_tex(tex->plugin);
|
||||||
|
|
||||||
if(tex->coba) MEM_freeN(tex->coba);
|
if(tex->coba) MEM_freeN(tex->coba);
|
||||||
if(tex->env) BKE_free_envmap(tex->env);
|
if(tex->env) BKE_free_envmap(tex->env);
|
||||||
if(tex->pd) BKE_free_pointdensity(tex->pd);
|
if(tex->pd) BKE_free_pointdensity(tex->pd);
|
||||||
if(tex->vd) BKE_free_voxeldata(tex->vd);
|
if(tex->vd) BKE_free_voxeldata(tex->vd);
|
||||||
BKE_free_animdata((struct ID *)tex);
|
BKE_free_animdata((struct ID *)tex);
|
||||||
|
|
||||||
BKE_previewimg_free(&tex->preview);
|
BKE_previewimg_free(&tex->preview);
|
||||||
BKE_icon_delete((struct ID*)tex);
|
BKE_icon_delete((struct ID*)tex);
|
||||||
tex->id.icon_id = 0;
|
tex->id.icon_id = 0;
|
||||||
@@ -750,10 +752,6 @@ Tex *copy_texture(Tex *tex)
|
|||||||
if(texn->type==TEX_IMAGE) id_us_plus((ID *)texn->ima);
|
if(texn->type==TEX_IMAGE) id_us_plus((ID *)texn->ima);
|
||||||
else texn->ima= NULL;
|
else texn->ima= NULL;
|
||||||
|
|
||||||
#if 0 // XXX old animation system
|
|
||||||
id_us_plus((ID *)texn->ipo);
|
|
||||||
#endif // XXX old animation system
|
|
||||||
|
|
||||||
if(texn->plugin) {
|
if(texn->plugin) {
|
||||||
texn->plugin= MEM_dupallocN(texn->plugin);
|
texn->plugin= MEM_dupallocN(texn->plugin);
|
||||||
open_plugin_tex(texn->plugin);
|
open_plugin_tex(texn->plugin);
|
||||||
@@ -768,12 +766,42 @@ Tex *copy_texture(Tex *tex)
|
|||||||
|
|
||||||
if(tex->nodetree) {
|
if(tex->nodetree) {
|
||||||
ntreeEndExecTree(tex->nodetree);
|
ntreeEndExecTree(tex->nodetree);
|
||||||
texn->nodetree= ntreeCopyTree(tex->nodetree); /* 0 == full new tree */
|
texn->nodetree= ntreeCopyTree(tex->nodetree);
|
||||||
}
|
}
|
||||||
|
|
||||||
return texn;
|
return texn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* texture copy without adding to main dbase */
|
||||||
|
Tex *localize_texture(Tex *tex)
|
||||||
|
{
|
||||||
|
Tex *texn;
|
||||||
|
|
||||||
|
texn= copy_libblock(tex);
|
||||||
|
BLI_remlink(&G.main->tex, texn);
|
||||||
|
|
||||||
|
/* image texture: free_texture also doesn't decrease */
|
||||||
|
|
||||||
|
if(texn->plugin) {
|
||||||
|
texn->plugin= MEM_dupallocN(texn->plugin);
|
||||||
|
open_plugin_tex(texn->plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(texn->coba) texn->coba= MEM_dupallocN(texn->coba);
|
||||||
|
if(texn->env) texn->env= BKE_copy_envmap(texn->env);
|
||||||
|
if(texn->pd) texn->pd= MEM_dupallocN(texn->pd);
|
||||||
|
if(texn->vd) texn->vd= MEM_dupallocN(texn->vd);
|
||||||
|
|
||||||
|
texn->preview = NULL;
|
||||||
|
|
||||||
|
if(tex->nodetree) {
|
||||||
|
texn->nodetree= ntreeLocalize(tex->nodetree);
|
||||||
|
}
|
||||||
|
|
||||||
|
return texn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void make_local_texture(Tex *tex)
|
void make_local_texture(Tex *tex)
|
||||||
|
@@ -67,13 +67,14 @@
|
|||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_depsgraph.h"
|
#include "BKE_depsgraph.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_idprop.h"
|
||||||
#include "BKE_image.h"
|
#include "BKE_image.h"
|
||||||
#include "BKE_icons.h"
|
#include "BKE_icons.h"
|
||||||
#include "BKE_library.h"
|
#include "BKE_library.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
#include "BKE_material.h"
|
#include "BKE_material.h"
|
||||||
#include "BKE_node.h"
|
#include "BKE_node.h"
|
||||||
#include "BKE_idprop.h"
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
#include "IMB_imbuf.h"
|
#include "IMB_imbuf.h"
|
||||||
#include "IMB_imbuf_types.h"
|
#include "IMB_imbuf_types.h"
|
||||||
@@ -156,8 +157,10 @@ typedef struct ShaderPreview {
|
|||||||
ID *parent;
|
ID *parent;
|
||||||
MTex *slot;
|
MTex *slot;
|
||||||
|
|
||||||
/* node materials need full copy during preview render, glsl uses it too */
|
/* node materials/texture need full copy during preview render, glsl uses it too */
|
||||||
Material *matcopy;
|
Material *matcopy;
|
||||||
|
Tex *texcopy;
|
||||||
|
|
||||||
float col[4]; /* active object color */
|
float col[4]; /* active object color */
|
||||||
|
|
||||||
int sizex, sizey;
|
int sizex, sizey;
|
||||||
@@ -482,8 +485,13 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(id_type==ID_TE) {
|
else if(id_type==ID_TE) {
|
||||||
Tex *tex= (Tex *)id;
|
Tex *tex= NULL, *origtex= (Tex *)id;
|
||||||
|
|
||||||
|
if(origtex) {
|
||||||
|
tex= localize_texture(origtex);
|
||||||
|
sp->texcopy= tex;
|
||||||
|
BLI_addtail(&pr_main->tex, tex);
|
||||||
|
}
|
||||||
sce->lay= 1<<MA_TEXTURE;
|
sce->lay= 1<<MA_TEXTURE;
|
||||||
|
|
||||||
for(base= sce->base.first; base; base= base->next) {
|
for(base= sce->base.first; base; base= base->next) {
|
||||||
@@ -508,8 +516,11 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tex && tex->nodetree && sp->pr_method==PR_NODE_RENDER)
|
if(tex && tex->nodetree && sp->pr_method==PR_NODE_RENDER) {
|
||||||
|
/* two previews, they get copied by wmJob */
|
||||||
|
ntreeInitPreview(origtex->nodetree, sp->sizex, sp->sizey);
|
||||||
ntreeInitPreview(tex->nodetree, sp->sizex, sp->sizey);
|
ntreeInitPreview(tex->nodetree, sp->sizex, sp->sizey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(id_type==ID_LA) {
|
else if(id_type==ID_LA) {
|
||||||
Lamp *la= (Lamp *)id;
|
Lamp *la= (Lamp *)id;
|
||||||
@@ -971,11 +982,20 @@ static void shader_preview_updatejob(void *spv)
|
|||||||
{
|
{
|
||||||
ShaderPreview *sp= spv;
|
ShaderPreview *sp= spv;
|
||||||
|
|
||||||
if(sp->id && GS(sp->id->name) == ID_MA) {
|
if(sp->id) {
|
||||||
Material *mat= (Material *)sp->id;
|
if( GS(sp->id->name) == ID_MA) {
|
||||||
|
Material *mat= (Material *)sp->id;
|
||||||
|
|
||||||
|
if(sp->matcopy && mat->nodetree && sp->matcopy->nodetree)
|
||||||
|
ntreeLocalSync(sp->matcopy->nodetree, mat->nodetree);
|
||||||
|
}
|
||||||
|
else if( GS(sp->id->name) == ID_TE) {
|
||||||
|
Tex *tex= (Tex *)sp->id;
|
||||||
|
|
||||||
|
if(sp->texcopy && tex->nodetree && sp->texcopy->nodetree)
|
||||||
|
ntreeLocalSync(sp->texcopy->nodetree, tex->nodetree);
|
||||||
|
}
|
||||||
|
|
||||||
if(sp->matcopy && mat->nodetree && sp->matcopy->nodetree)
|
|
||||||
ntreeLocalSync(sp->matcopy->nodetree, mat->nodetree);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1062,11 +1082,11 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
|
|||||||
preview_prepare_scene(sp->scene, NULL, GS(id->name), sp);
|
preview_prepare_scene(sp->scene, NULL, GS(id->name), sp);
|
||||||
|
|
||||||
/* XXX bad exception, end-exec is not being called in render, because it uses local main */
|
/* XXX bad exception, end-exec is not being called in render, because it uses local main */
|
||||||
if(idtype == ID_TE) {
|
// if(idtype == ID_TE) {
|
||||||
Tex *tex= (Tex *)id;
|
// Tex *tex= (Tex *)id;
|
||||||
if(tex->use_nodes && tex->nodetree)
|
// if(tex->use_nodes && tex->nodetree)
|
||||||
ntreeEndExecTree(tex->nodetree);
|
// ntreeEndExecTree(tex->nodetree);
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1108,6 +1128,22 @@ static void shader_preview_free(void *customdata)
|
|||||||
}
|
}
|
||||||
MEM_freeN(sp->matcopy);
|
MEM_freeN(sp->matcopy);
|
||||||
}
|
}
|
||||||
|
if(sp->texcopy) {
|
||||||
|
struct IDProperty *properties;
|
||||||
|
/* node previews */
|
||||||
|
shader_preview_updatejob(sp);
|
||||||
|
|
||||||
|
/* get rid of copied texture */
|
||||||
|
BLI_remlink(&pr_main->tex, sp->texcopy);
|
||||||
|
free_texture(sp->texcopy);
|
||||||
|
|
||||||
|
properties= IDP_GetProperties((ID *)sp->texcopy, FALSE);
|
||||||
|
if (properties) {
|
||||||
|
IDP_FreeProperty(properties);
|
||||||
|
MEM_freeN(properties);
|
||||||
|
}
|
||||||
|
MEM_freeN(sp->texcopy);
|
||||||
|
}
|
||||||
|
|
||||||
MEM_freeN(sp);
|
MEM_freeN(sp);
|
||||||
}
|
}
|
||||||
|
@@ -57,24 +57,26 @@
|
|||||||
#include "IMB_imbuf.h"
|
#include "IMB_imbuf.h"
|
||||||
#include "IMB_imbuf_types.h"
|
#include "IMB_imbuf_types.h"
|
||||||
|
|
||||||
|
#include "DNA_brush_types.h"
|
||||||
#include "DNA_mesh_types.h"
|
#include "DNA_mesh_types.h"
|
||||||
#include "DNA_meshdata_types.h"
|
#include "DNA_meshdata_types.h"
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_brush_types.h"
|
#include "DNA_texture_types.h"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
|
#include "BKE_depsgraph.h"
|
||||||
|
#include "BKE_DerivedMesh.h"
|
||||||
#include "BKE_idprop.h"
|
#include "BKE_idprop.h"
|
||||||
#include "BKE_object.h"
|
|
||||||
#include "BKE_brush.h"
|
#include "BKE_brush.h"
|
||||||
#include "BKE_image.h"
|
#include "BKE_image.h"
|
||||||
|
#include "BKE_library.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
#include "BKE_mesh.h"
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_node.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
#include "BKE_paint.h"
|
#include "BKE_paint.h"
|
||||||
#include "BKE_DerivedMesh.h"
|
|
||||||
#include "BKE_report.h"
|
#include "BKE_report.h"
|
||||||
#include "BKE_depsgraph.h"
|
|
||||||
#include "BKE_library.h"
|
|
||||||
|
|
||||||
#include "BIF_gl.h"
|
#include "BIF_gl.h"
|
||||||
#include "BIF_glutil.h"
|
#include "BIF_glutil.h"
|
||||||
@@ -4620,6 +4622,17 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps)
|
|||||||
ps->do_mask_normal = 0; /* no need to do blending */
|
ps->do_mask_normal = 0; /* no need to do blending */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void paint_brush_init_tex(Brush *brush)
|
||||||
|
{
|
||||||
|
/* init mtex nodes */
|
||||||
|
if(brush) {
|
||||||
|
MTex *mtex= &brush->mtex;
|
||||||
|
if(mtex->tex && mtex->tex->nodetree)
|
||||||
|
ntreeBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int texture_paint_init(bContext *C, wmOperator *op)
|
static int texture_paint_init(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
Scene *scene= CTX_data_scene(C);
|
Scene *scene= CTX_data_scene(C);
|
||||||
@@ -4678,12 +4691,16 @@ static int texture_paint_init(bContext *C, wmOperator *op)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
paint_brush_init_tex(pop->s.brush);
|
||||||
|
|
||||||
/* note, if we have no UVs on the derived mesh, then we must return here */
|
/* note, if we have no UVs on the derived mesh, then we must return here */
|
||||||
if(pop->mode == PAINT_MODE_3D_PROJECT) {
|
if(pop->mode == PAINT_MODE_3D_PROJECT) {
|
||||||
|
|
||||||
/* initialize all data from the context */
|
/* initialize all data from the context */
|
||||||
project_state_init(C, OBACT, &pop->ps);
|
project_state_init(C, OBACT, &pop->ps);
|
||||||
|
|
||||||
|
paint_brush_init_tex(pop->ps.brush);
|
||||||
|
|
||||||
pop->ps.source= PROJ_SRC_VIEW;
|
pop->ps.source= PROJ_SRC_VIEW;
|
||||||
|
|
||||||
@@ -4748,6 +4765,15 @@ static void paint_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
|||||||
pop->first= 0;
|
pop->first= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void paint_brush_exit_tex(Brush *brush)
|
||||||
|
{
|
||||||
|
if(brush) {
|
||||||
|
MTex *mtex= &brush->mtex;
|
||||||
|
if(mtex->tex && mtex->tex->nodetree)
|
||||||
|
ntreeEndExecTree(mtex->tex->nodetree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void paint_exit(bContext *C, wmOperator *op)
|
static void paint_exit(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
Scene *scene= CTX_data_scene(C);
|
Scene *scene= CTX_data_scene(C);
|
||||||
@@ -4760,12 +4786,16 @@ static void paint_exit(bContext *C, wmOperator *op)
|
|||||||
if(pop->restore_projection)
|
if(pop->restore_projection)
|
||||||
settings->imapaint.flag &= ~IMAGEPAINT_PROJECT_DISABLE;
|
settings->imapaint.flag &= ~IMAGEPAINT_PROJECT_DISABLE;
|
||||||
|
|
||||||
|
paint_brush_exit_tex(pop->s.brush);
|
||||||
|
|
||||||
settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
|
settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
|
||||||
imapaint_canvas_free(&pop->s);
|
imapaint_canvas_free(&pop->s);
|
||||||
brush_painter_free(pop->painter);
|
brush_painter_free(pop->painter);
|
||||||
|
|
||||||
if(pop->mode == PAINT_MODE_3D_PROJECT) {
|
if(pop->mode == PAINT_MODE_3D_PROJECT) {
|
||||||
brush_set_size(pop->ps.brush, pop->orig_brush_size);
|
brush_set_size(pop->ps.brush, pop->orig_brush_size);
|
||||||
|
paint_brush_exit_tex(pop->ps.brush);
|
||||||
|
|
||||||
project_paint_end(&pop->ps);
|
project_paint_end(&pop->ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user