From 9c183f60e1b0892614cf64db274488ff5bc61620 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 2 Mar 2016 12:45:46 +0500 Subject: [PATCH] Fix T47610: Texture node in compositing nodes does not update The issue was caused by some code accessing R from a functions which are marked as safe for use from outside of render pipeline. Now those functions are safe(er) for use. --- source/blender/blenkernel/intern/brush.c | 12 +- source/blender/blenkernel/intern/particle.c | 4 +- source/blender/editors/mesh/editmesh_tools.c | 2 +- .../editors/sculpt_paint/paint_utils.c | 4 +- .../render/extern/include/RE_render_ext.h | 2 +- .../render/intern/include/render_types.h | 2 +- .../render/intern/source/render_texture.c | 148 +++++++++++++++--- .../render/intern/source/renderdatabase.c | 22 ++- 8 files changed, 161 insertions(+), 35 deletions(-) diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 166c2b26d27..31dac038e43 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -570,7 +570,7 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, /* Get strength by feeding the vertex * location directly into a texture */ hasrgb = externtex(mtex, point, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false); + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); } else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) { float rotation = -mtex->rot; @@ -601,7 +601,7 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, co[2] = 0.0f; hasrgb = externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false); + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); } else { float rotation = -mtex->rot; @@ -658,7 +658,7 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, co[2] = 0.0f; hasrgb = externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false); + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); } intensity += br->texture_sample_bias; @@ -718,7 +718,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br, co[2] = 0.0f; externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false); + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); } else { float rotation = -mtex->rot; @@ -775,7 +775,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br, co[2] = 0.0f; externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false); + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); } CLAMP(intensity, 0.0f, 1.0f); @@ -1048,7 +1048,7 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side, bool use_sec /* This is copied from displace modifier code */ /* TODO(sergey): brush are always cacheing with CM enabled for now. */ externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false); + rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false, false); ((char *)texcache)[(iy * side + ix) * 4] = ((char *)texcache)[(iy * side + ix) * 4 + 1] = diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index d02308b6482..66d6252c273 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3499,7 +3499,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti break; } - externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false); + externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false, false); if ((event & mtex->mapto) & PAMAP_ROUGH) ptex->rough1 = ptex->rough2 = ptex->roughe = texture_value_blend(def, ptex->rough1, value, mtex->roughfac, blend); @@ -3582,7 +3582,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex break; } - externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false); + externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false, false); if ((event & mtex->mapto) & PAMAP_TIME) { /* the first time has to set the base value for time regardless of blend mode */ diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index b240836b153..33dd3cd960a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4987,7 +4987,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op) BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { float tin, dum; - externtex(ma->mtex[0], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL, false); + externtex(ma->mtex[0], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL, false, false); eve->co[2] += fac * tin; } } diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index dc0852aaee0..31c471c3517 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -177,7 +177,7 @@ float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool, float co[3] = {u, v, 0.0f}; externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false); + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); return intensity; } @@ -189,7 +189,7 @@ void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct float intensity; hasrgb = externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false); + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); if (!hasrgb) { rgba[0] = intensity; rgba[1] = intensity; diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 075db3a8145..2b5d0ca4e14 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -46,7 +46,7 @@ struct Scene; /* used by particle.c, effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */ int externtex( struct MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, - const int thread, struct ImagePool *pool, const bool skip_load_image); + const int thread, struct ImagePool *pool, const bool skip_load_image, const bool texnode_preview); void texture_rgb_blend(float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype); float texture_value_blend(float tex, float out, float fact, float facg, int blendtype); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 3b69c124753..ed83cfec764 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -437,7 +437,7 @@ typedef struct HaloRen { unsigned int lay; struct Material *mat; struct ImagePool *pool; - bool skip_load_image; + bool skip_load_image, texnode_preview; } HaloRen; /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 29d8f17a72b..172fc999897 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1103,7 +1103,16 @@ static void do_2d_mapping(MTex *mtex, float texvec[3], VlakRen *vlr, const float /* ************************************** */ -static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output, struct ImagePool *pool, const bool skip_load_image) +static int multitex(Tex *tex, + float texvec[3], + float dxt[3], float dyt[3], + int osatex, + TexResult *texres, + const short thread, + const short which_output, + struct ImagePool *pool, + const bool skip_load_image, + const bool texnode_preview) { float tmpvec[3]; int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */ @@ -1112,7 +1121,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o if (tex->use_nodes && tex->nodetree) { retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread, - tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL); + tex, which_output, R.r.cfra, texnode_preview, NULL, NULL); } else { switch (tex->type) { @@ -1218,9 +1227,19 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o return retval; } -static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, - const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool, - bool scene_color_manage, const bool skip_load_image) +static int multitex_nodes_intern(Tex *tex, + float texvec[3], + float dxt[3], float dyt[3], + int osatex, + TexResult *texres, + const short thread, + short which_output, + ShadeInput *shi, + MTex *mtex, struct + ImagePool *pool, + const bool scene_color_manage, + const bool skip_load_image, + const bool texnode_preview) { if (tex==NULL) { memset(texres, 0, sizeof(TexResult)); @@ -1236,7 +1255,16 @@ static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float if (mtex) { /* we have mtex, use it for 2d mapping images only */ do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); - rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool, skip_load_image); + rgbnor = multitex(tex, + texvec, + dxt, dyt, + osatex, + texres, + thread, + which_output, + pool, + skip_load_image, + texnode_preview); if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); @@ -1269,7 +1297,16 @@ static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float } do_2d_mapping(&localmtex, texvec_l, NULL, NULL, dxt_l, dyt_l); - rgbnor = multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output, pool, skip_load_image); + rgbnor = multitex(tex, + texvec_l, + dxt_l, dyt_l, + osatex, + texres, + thread, + which_output, + pool, + skip_load_image, + texnode_preview); { ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); @@ -1285,7 +1322,16 @@ static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float return rgbnor; } else { - return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool, skip_load_image); + return multitex(tex, + texvec, + dxt, dyt, + osatex, + texres, + thread, + which_output, + pool, + skip_load_image, + texnode_preview); } } @@ -1297,14 +1343,15 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os { return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, shi, mtex, pool, R.scene_color_manage, - (R.r.scemode & R_NO_IMAGE_LOAD) != 0); + (R.r.scemode & R_NO_IMAGE_LOAD) != 0, + (R.r.scemode & R_TEXNODE_PREVIEW) != 0); } /* this is called for surface shading */ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres, struct ImagePool *pool, const bool skip_load_image) { Tex *tex = mtex->tex; - + /* TODO(sergey): Texture preview should become an argument? */ if (tex->use_nodes && tex->nodetree) { /* stupid exception here .. but we have to pass shi and mtex to * textures nodes for 2d mapping and color management for images */ @@ -1312,7 +1359,16 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex); } else { - return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output, pool, skip_load_image); + return multitex(mtex->tex, + texvec, + dxt, dyt, + shi->osatex, + texres, + shi->thread, + mtex->which_output, + pool, + skip_load_image, + (R.r.scemode & R_TEXNODE_PREVIEW) != 0); } } @@ -1323,7 +1379,7 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt */ int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image) { - return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image); + return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image, false); } /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on)\ @@ -1335,7 +1391,7 @@ int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct Image int use_nodes= tex->use_nodes, retval; tex->use_nodes = false; - retval= multitex_nodes_intern(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image); + retval= multitex_nodes_intern(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image, false); tex->use_nodes= use_nodes; return retval; @@ -2672,6 +2728,7 @@ void do_material_tex(ShadeInput *shi, Render *re) void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_r[3], float *val, Render *re) { const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; + const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0; MTex *mtex; Tex *tex; TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; @@ -2759,7 +2816,16 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ else texvec[2]= mtex->size[2]*(mtex->ofs[2]); } - rgbnor = multitex(tex, texvec, NULL, NULL, 0, &texres, shi->thread, mtex->which_output, re->pool, skip_load_image); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */ + rgbnor = multitex(tex, + texvec, + NULL, NULL, + 0, + &texres, + shi->thread, + mtex->which_output, + re->pool, + skip_load_image, + texnode_preview); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */ /* texture output */ @@ -2871,6 +2937,7 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) { const bool skip_load_image = har->skip_load_image; + const bool texnode_preview = har->texnode_preview; MTex *mtex; TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; float texvec[3], dxt[3], dyt[3], fact, facm, dx; @@ -2927,7 +2994,16 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) if (mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); - rgb = multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output, har->pool, skip_load_image); + rgb = multitex(mtex->tex, + texvec, + dxt, dyt, + osatex, + &texres, + 0, + mtex->which_output, + har->pool, + skip_load_image, + texnode_preview); /* texture output */ if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { @@ -3017,6 +3093,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) void do_sky_tex(const float rco[3], const float lo[3], const float dxyview[2], float hor[3], float zen[3], float *blend, int skyflag, short thread) { const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0; + const bool texnode_preview = (R.r.scemode & R_TEXNODE_PREVIEW) != 0; MTex *mtex; Tex *tex; TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; @@ -3134,7 +3211,16 @@ void do_sky_tex(const float rco[3], const float lo[3], const float dxyview[2], f /* texture */ if (tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); - rgb = multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output, R.pool, skip_load_image); + rgb = multitex(mtex->tex, + texvec, + dxt, dyt, + R.osa, + &texres, + thread, + mtex->which_output, + R.pool, + skip_load_image, + texnode_preview); /* texture output */ if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { @@ -3227,6 +3313,7 @@ void do_sky_tex(const float rco[3], const float lo[3], const float dxyview[2], f void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r[3], int effect) { const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0; + const bool texnode_preview = (R.r.scemode & R_TEXNODE_PREVIEW) != 0; Object *ob; MTex *mtex; Tex *tex; @@ -3350,7 +3437,16 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); } - rgb = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output, R.pool, skip_load_image); + rgb = multitex(tex, + texvec, + dxt, dyt, + shi->osatex, + &texres, + shi->thread, + mtex->which_output, + R.pool, + skip_load_image, + texnode_preview); /* texture output */ if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { @@ -3424,7 +3520,13 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r /* ------------------------------------------------------------------------- */ -int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread, struct ImagePool *pool, const bool skip_load_image) +int externtex(MTex *mtex, + const float vec[3], + float *tin, float *tr, float *tg, float *tb, float *ta, + const int thread, + struct ImagePool *pool, + const bool skip_load_image, + const bool texnode_preview) { Tex *tex; TexResult texr; @@ -3450,7 +3552,15 @@ int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); } - rgb = multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output, pool, skip_load_image); + rgb = multitex(tex, + texvec, + dxt, dyt, + 0, &texr, + thread, + mtex->which_output, + pool, + skip_load_image, + texnode_preview); if (rgb) { texr.tin = IMB_colormanagement_get_luminance(&texr.tr); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 560627b1be1..e8db096c9a5 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -956,6 +956,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, const float *orco, float hasize, float vectsize, int seed) { const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; + const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0; HaloRen *har; MTex *mtex; float tin, tr, tg, tb, ta; @@ -1047,7 +1048,13 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, } } - externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool, skip_load_image); + externtex(mtex, + texvec, + &tin, &tr, &tg, &tb, &ta, + 0, + re->pool, + skip_load_image, + texnode_preview); yn= tin*mtex->colfac; //zn= tin*mtex->alphafac; @@ -1067,7 +1074,8 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, } har->pool = re->pool; - har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; + har->skip_load_image = skip_load_image; + har->texnode_preview = texnode_preview; return har; } @@ -1077,6 +1085,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater const float *orco, const float *uvco, float hasize, float vectsize, int seed, const float pa_co[3]) { const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; + const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0; HaloRen *har; MTex *mtex; float tin, tr, tg, tb, ta; @@ -1180,7 +1189,13 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater copy_v3_v3(texvec, orco); } - hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool, skip_load_image); + hasrgb = externtex(mtex, + texvec, + &tin, &tr, &tg, &tb, &ta, + 0, + re->pool, + skip_load_image, + texnode_preview); //yn= tin*mtex->colfac; //zn= tin*mtex->alphafac; @@ -1225,6 +1240,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater har->pool = re->pool; har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; + har->texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0; return har; }