From 27d29e29986ac912dc87ed78b448fab1290a6e2a Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Tue, 8 Nov 2011 12:44:57 +0000 Subject: [PATCH 1/3] Fix an issue with uninitialized memory --- source/blender/makesrna/intern/rna_scene.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ca325747d8e..f9be61bb749 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -573,6 +573,7 @@ static int rna_SceneRender_file_ext_length(PointerRNA *ptr) static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str) { RenderData *rd= (RenderData*)ptr->data; + rna_SceneRender_file_ext_get: str[0] = '\0'; BKE_add_image_extension(str, rd->imtype); } From 19df3147f6920a2856bccb6e4601d57288119999 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 8 Nov 2011 12:58:03 +0000 Subject: [PATCH 2/3] Fix for last fix, guess this compiled ok because it's interpreted as a goto label. --- source/blender/makesrna/intern/rna_scene.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f9be61bb749..c22ded39a74 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -573,7 +573,7 @@ static int rna_SceneRender_file_ext_length(PointerRNA *ptr) static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str) { RenderData *rd= (RenderData*)ptr->data; - rna_SceneRender_file_ext_get: str[0] = '\0'; + str[0]= '\0'; BKE_add_image_extension(str, rd->imtype); } From 28ee0f92184af8ba6f44d08eda23ce5eb3815697 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 8 Nov 2011 13:07:16 +0000 Subject: [PATCH 3/3] Texturing: texture and 3d view draw type changes, these should only have any effect for a render engine using new shading nodes. In short: * No longer uses images assigned to faces in the uv layer, rather the active image texture node is what is edited/painted/drawn. * Textured draw type now shows the active image texture node, with solid lighting. * Material draw mode shows GLSL shader of a simplified material node tree, using solid lighting. * Textures for modifiers, brushes, etc, are now available from a dropdown in the texture tab in the properties editor. These do not use new shading nodes yet. http://wiki.blender.org/index.php/Dev:2.6/Source/Render/TextureWorkflow --- source/blender/blenkernel/BKE_DerivedMesh.h | 8 + source/blender/blenkernel/BKE_node.h | 1 + .../blender/blenkernel/intern/DerivedMesh.c | 135 +++++ .../blender/blenkernel/intern/cdderivedmesh.c | 80 +++ source/blender/blenkernel/intern/node.c | 4 + .../blender/blenkernel/intern/subsurf_ccg.c | 150 ++++++ source/blender/editors/include/ED_uvedit.h | 9 +- source/blender/editors/include/UI_interface.h | 2 + .../editors/interface/interface_templates.c | 11 +- source/blender/editors/mesh/mesh_data.c | 4 +- .../editors/sculpt_paint/paint_image.c | 82 ++- .../editors/space_buttons/CMakeLists.txt | 1 + .../editors/space_buttons/buttons_context.c | 263 ++++++---- .../editors/space_buttons/buttons_intern.h | 49 +- .../editors/space_buttons/buttons_texture.c | 469 ++++++++++++++++++ .../editors/space_buttons/space_buttons.c | 7 + .../blender/editors/space_image/space_image.c | 40 +- .../blender/editors/space_node/CMakeLists.txt | 1 + source/blender/editors/space_node/SConscript | 2 +- source/blender/editors/space_node/node_edit.c | 13 + .../editors/space_node/node_templates.c | 9 + .../blender/editors/space_view3d/drawmesh.c | 183 ++++++- .../blender/editors/space_view3d/drawobject.c | 4 +- .../editors/space_view3d/view3d_draw.c | 12 +- source/blender/editors/uvedit/uvedit_ops.c | 109 +++- .../editors/uvedit/uvedit_unwrap_ops.c | 4 +- source/blender/gpu/intern/gpu_draw.c | 49 +- source/blender/gpu/intern/gpu_material.c | 20 +- source/blender/makesdna/DNA_space_types.h | 2 + source/blender/makesrna/intern/rna_space.c | 12 +- source/blender/makesrna/intern/rna_ui_api.c | 3 + .../blender/nodes/shader/node_shader_util.c | 23 + .../bad_level_call_stubs/stubs.c | 2 + 33 files changed, 1560 insertions(+), 203 deletions(-) create mode 100644 source/blender/editors/space_buttons/buttons_texture.c diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 5e403849289..0c5dc32f6d8 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -324,6 +324,14 @@ struct DerivedMesh { float t), void *userData); + /* Draw all faces with materials + * o setMaterial is called for every different material nr + * o setFace is called to verify if a face must be hidden + */ + void (*drawMappedFacesMat)(DerivedMesh *dm, + void (*setMaterial)(void *userData, int, void *attribs), + int (*setFace)(void *userData, int index), void *userData); + /* Release reference to the DerivedMesh. This function decides internally * if the DerivedMesh will be freed, or cached for later use. */ void (*release)(DerivedMesh *dm); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index a06d57ae517..580f78d3063 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -351,6 +351,7 @@ struct bNode *nodeGetActive(struct bNodeTree *ntree); struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype); int nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id); void nodeClearActiveID(struct bNodeTree *ntree, short idtype); +struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree); void nodeUpdate(struct bNodeTree *ntree, struct bNode *node); int nodeUpdateID(struct bNodeTree *ntree, struct ID *id); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index aaed0381b2e..ecabd1a79bc 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1123,6 +1123,140 @@ static void emDM_drawFacesGLSL(DerivedMesh *dm, dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); } +static void emDM_drawMappedFacesMat(DerivedMesh *dm, + void (*setMaterial)(void *userData, int, void *attribs), + int (*setFace)(void *userData, int index), void *userData) +{ + EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; + EditMesh *em= emdm->em; + float (*vertexCos)[3]= emdm->vertexCos; + float (*vertexNos)[3]= emdm->vertexNos; + EditVert *eve; + EditFace *efa; + DMVertexAttribs attribs= {{{0}}}; + GPUVertexAttribs gattribs; + int i, b, matnr, new_matnr; + + matnr = -1; + + /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ + glShadeModel(GL_SMOOTH); + + for (i=0,eve=em->verts.first; eve; eve= eve->next) + eve->tmp.l = (intptr_t) i++; + +#define PASSATTRIB(efa, eve, vert) { \ + if(attribs.totorco) { \ + float *orco = attribs.orco.array[eve->tmp.l]; \ + if(attribs.orco.glTexco) \ + glTexCoord3fv(orco); \ + else \ + glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \ + } \ + for(b = 0; b < attribs.tottface; b++) { \ + MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset); \ + if(attribs.tface[b].glTexco) \ + glTexCoord2fv(_tf->uv[vert]); \ + else \ + glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]); \ + } \ + for(b = 0; b < attribs.totmcol; b++) { \ + MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \ + GLubyte col[4]; \ + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \ + glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \ + } \ + if(attribs.tottang) { \ + float *tang = attribs.tang.array[i*4 + vert]; \ + glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \ + } \ +} + + for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { + int drawSmooth= (efa->flag & ME_SMOOTH); + + /* face hiding */ + if(setFace && !setFace(userData, i)) + continue; + + /* material */ + new_matnr = efa->mat_nr + 1; + if(new_matnr != matnr) { + setMaterial(userData, matnr = new_matnr, &gattribs); + DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + } + + /* face */ + glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); + if (!drawSmooth) { + if(vertexCos) glNormal3fv(emdm->faceNos[i]); + else glNormal3fv(efa->n); + + PASSATTRIB(efa, efa->v1, 0); + if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + else glVertex3fv(efa->v1->co); + + PASSATTRIB(efa, efa->v2, 1); + if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + else glVertex3fv(efa->v2->co); + + PASSATTRIB(efa, efa->v3, 2); + if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + else glVertex3fv(efa->v3->co); + + if(efa->v4) { + PASSATTRIB(efa, efa->v4, 3); + if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + else glVertex3fv(efa->v4->co); + } + } else { + PASSATTRIB(efa, efa->v1, 0); + if(vertexCos) { + glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + } + else { + glNormal3fv(efa->v1->no); + glVertex3fv(efa->v1->co); + } + + PASSATTRIB(efa, efa->v2, 1); + if(vertexCos) { + glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + } + else { + glNormal3fv(efa->v2->no); + glVertex3fv(efa->v2->co); + } + + PASSATTRIB(efa, efa->v3, 2); + if(vertexCos) { + glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + } + else { + glNormal3fv(efa->v3->no); + glVertex3fv(efa->v3->co); + } + + if(efa->v4) { + PASSATTRIB(efa, efa->v4, 3); + if(vertexCos) { + glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } + else { + glNormal3fv(efa->v4->no); + glVertex3fv(efa->v4->co); + } + } + } + glEnd(); + } +#undef PASSATTRIB +} + static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; @@ -1429,6 +1563,7 @@ DerivedMesh *editmesh_get_derived(EditMesh *em, float (*vertexCos)[3]) emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL; emdm->dm.drawFacesTex = emDM_drawFacesTex; emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL; + emdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat; emdm->dm.drawUVEdges = emDM_drawUVEdges; emdm->dm.release = emDM_release; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index d2c86a14572..5ebdd1ec547 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1351,6 +1351,85 @@ static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *at dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); } +static void cdDM_drawMappedFacesMat(DerivedMesh *dm, + void (*setMaterial)(void *userData, int, void *attribs), + int (*setFace)(void *userData, int index), void *userData) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + GPUVertexAttribs gattribs; + DMVertexAttribs attribs; + MVert *mvert = cddm->mvert; + MFace *mf = cddm->mface; + float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL); + int a, matnr, new_matnr; + int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX); + + cdDM_update_normals_from_pbvh(dm); + + matnr = -1; + + glShadeModel(GL_SMOOTH); + + memset(&attribs, 0, sizeof(attribs)); + + glBegin(GL_QUADS); + + for(a = 0; a < dm->numFaceData; a++, mf++) { + const int smoothnormal = (mf->flag & ME_SMOOTH); + + /* material */ + new_matnr = mf->mat_nr + 1; + + if(new_matnr != matnr) { + glEnd(); + + setMaterial(userData, matnr = new_matnr, &gattribs); + DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + + glBegin(GL_QUADS); + } + + /* skipping faces */ + if(setFace) { + orig = (index)? index[a]: a; + + if(orig != ORIGINDEX_NONE && !setFace(userData, orig)) + continue; + } + + /* smooth normal */ + if(!smoothnormal) { + if(nors) { + glNormal3fv(nors[a]); + } + else { + /* TODO ideally a normal layer should always be available */ + float nor[3]; + + if(mf->v4) + normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); + else + normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); + + glNormal3fv(nor); + } + } + + /* vertices */ + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal); + + if(mf->v4) + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal); + else + cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal); + } + glEnd(); + + glShadeModel(GL_FLAT); +} + static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; @@ -1521,6 +1600,7 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->drawMappedFaces = cdDM_drawMappedFaces; dm->drawMappedFacesTex = cdDM_drawMappedFacesTex; dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL; + dm->drawMappedFacesMat = cdDM_drawMappedFacesMat; dm->foreachMappedVert = cdDM_foreachMappedVert; dm->foreachMappedEdge = cdDM_foreachMappedEdge; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 9fc18c3e0fc..fa023d8fb43 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1314,11 +1314,15 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) if(GS(node->id->name) == GS(tnode->id->name)) tnode->flag &= ~NODE_ACTIVE_ID; } + if(node->typeinfo->nclass == NODE_CLASS_TEXTURE) + tnode->flag &= ~NODE_ACTIVE_TEXTURE; } node->flag |= NODE_ACTIVE; if(node->id) node->flag |= NODE_ACTIVE_ID; + if(node->typeinfo->nclass == NODE_CLASS_TEXTURE) + node->flag |= NODE_ACTIVE_TEXTURE; } /* use flags are not persistent yet, groups might need different tagging, so we do it each time diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 9848b27d32e..da2245f8401 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1511,6 +1511,155 @@ static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *a dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); } + /* Only used by non-editmesh types */ +static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) { + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + CCGSubSurf *ss = ccgdm->ss; + CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); + GPUVertexAttribs gattribs; + DMVertexAttribs attribs= {{{NULL}}}; + int gridSize = ccgSubSurf_getGridSize(ss); + int gridFaces = gridSize - 1; + int edgeSize = ccgSubSurf_getEdgeSize(ss); + char *faceFlags = ccgdm->faceFlags; + int a, b, i, numVerts, matnr, new_matnr, totface; + + ccgdm_pbvh_update(ccgdm); + + matnr = -1; + +#define PASSATTRIB(dx, dy, vert) { \ + if(attribs.totorco) { \ + index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize); \ + if(attribs.orco.glTexco) \ + glTexCoord3fv(attribs.orco.array[index]); \ + else \ + glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \ + } \ + for(b = 0; b < attribs.tottface; b++) { \ + MTFace *tf = &attribs.tface[b].array[a]; \ + if(attribs.tface[b].glTexco) \ + glTexCoord2fv(tf->uv[vert]); \ + else \ + glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \ + } \ + for(b = 0; b < attribs.totmcol; b++) { \ + MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \ + GLubyte col[4]; \ + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \ + glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \ + } \ + if(attribs.tottang) { \ + float *tang = attribs.tang.array[a*4 + vert]; \ + glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \ + } \ +} + + totface = ccgSubSurf_getNumFaces(ss); + for(a = 0, i = 0; i < totface; i++) { + CCGFace *f = ccgdm->faceMap[i].face; + int S, x, y, drawSmooth; + int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); + int origIndex = ccgDM_getFaceMapIndex(ss, f); + + numVerts = ccgSubSurf_getFaceNumVerts(f); + + /* get flags */ + if(faceFlags) { + drawSmooth = (faceFlags[index*2] & ME_SMOOTH); + new_matnr= faceFlags[index*2 + 1] + 1; + } + else { + drawSmooth = 1; + new_matnr= 1; + } + + /* material */ + if(new_matnr != matnr) { + setMaterial(userData, matnr = new_matnr, &gattribs); + DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + } + + /* face hiding */ + if((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) { + a += gridFaces*gridFaces*numVerts; + continue; + } + + /* draw face*/ + glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT); + for (S=0; Sno); + glVertex3fv(vda->co); + + PASSATTRIB(0, 1, 1); + glNormal3fv(vdb->no); + glVertex3fv(vdb->co); + + if(x != gridFaces-1) + a++; + } + + vda = &faceGridData[(y+0)*gridSize + x]; + vdb = &faceGridData[(y+1)*gridSize + x]; + + PASSATTRIB(0, 0, 3); + glNormal3fv(vda->no); + glVertex3fv(vda->co); + + PASSATTRIB(0, 1, 2); + glNormal3fv(vdb->no); + glVertex3fv(vdb->co); + + glEnd(); + + a++; + } + } else { + glBegin(GL_QUADS); + for (y=0; yss; @@ -2382,6 +2531,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex; ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL; + ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat; ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges; ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp; diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 2b4c213bc52..0666884351a 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -33,19 +33,26 @@ struct ARegionType; struct EditFace; struct Image; +struct Main; +struct ImageUser; struct MTFace; struct Object; struct Scene; +struct SpaceImage; struct bContext; +struct bNode; struct wmKeyConfig; /* uvedit_ops.c */ void ED_operatortypes_uvedit(void); void ED_keymap_uvedit(struct wmKeyConfig *keyconf); -void ED_uvedit_assign_image(struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma); +void ED_uvedit_assign_image(struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma); int ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float *min, float *max); +int ED_object_get_active_image(struct Object *ob, int mat_nr, struct Image **ima, struct ImageUser **iuser, struct bNode **node); +void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int mat_nr, struct Image *ima); + int ED_uvedit_test_silent(struct Object *obedit); int ED_uvedit_test(struct Object *obedit); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 02b8cc9e2c6..329f4599e01 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -758,6 +758,8 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr); void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *activeptr, const char *activeprop, const char *prop_list, int rows, int maxrows, int type); void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input); void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input); +void uiTemplateTextureUser(uiLayout *layout, struct bContext *C); +void uiTemplateTextureShow(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop); void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact); void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 7c745c3cfef..a3d71674a03 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -332,7 +332,7 @@ static const char *template_id_browse_tip(StructRNA *type) return N_("Browse ID data to be linked"); } -static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag, const char *newop, const char *openop, const char *unlinkop) +static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag, const char *newop, const char *openop, const char *unlinkop) { uiBut *but; uiBlock *block; @@ -478,6 +478,9 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str if((idfrom && idfrom->lib) || !editable) uiButSetFlag(but, UI_BUT_DISABLED); } + + if(idcode == ID_TE) + uiTemplateTextureShow(layout, C, &template->ptr, template->prop); uiBlockEndAlign(block); } @@ -487,6 +490,7 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const TemplateID *template; PropertyRNA *prop; StructRNA *type; + short idcode; prop= RNA_struct_find_property(ptr, propname); @@ -507,14 +511,15 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const flag |= UI_ID_OPEN; type= RNA_property_pointer_type(ptr, prop); - template->idlb= which_libbase(CTX_data_main(C), RNA_type_to_ID_code(type)); + idcode= RNA_type_to_ID_code(type); + template->idlb= which_libbase(CTX_data_main(C), idcode); /* create UI elements for this template * - template_ID makes a copy of the template data and assigns it to the relevant buttons */ if(template->idlb) { uiLayoutRow(layout, 1); - template_ID(C, layout, template, type, flag, newop, openop, unlinkop); + template_ID(C, layout, template, type, idcode, flag, newop, openop, unlinkop); } MEM_freeN(template); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index ed890fd9b90..6e35865fb4d 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -51,6 +51,7 @@ #include "BKE_displist.h" #include "BKE_image.h" #include "BKE_library.h" +#include "BKE_main.h" #include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_report.h" @@ -331,6 +332,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot) static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) { + Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); View3D *v3d= CTX_wm_view3d(C); Base *base= ED_view3d_give_base_under_cursor(C, event->mval); @@ -375,7 +377,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) if(me->edit_mesh==NULL) return OPERATOR_CANCELLED; - ED_uvedit_assign_image(scene, obedit, ima, NULL); + ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL); if(exitmode) { load_editMesh(scene, obedit); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index ce603ce80b6..e283927b76f 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -79,6 +79,7 @@ #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_report.h" +#include "BKE_scene.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -88,6 +89,7 @@ #include "ED_image.h" #include "ED_screen.h" #include "ED_sculpt.h" +#include "ED_uvedit.h" #include "ED_view3d.h" #include "WM_api.h" @@ -498,6 +500,40 @@ static void image_undo_free(ListBase *lb) MEM_freeN(tile->rect); } +/* get active image for face depending on old/new shading system */ + +static Image *imapaint_face_image(const ImagePaintState *s, int face_index) +{ + Image *ima; + + if(scene_use_new_shading_nodes(s->scene)) { + MFace *mf = s->me->mface+face_index; + ED_object_get_active_image(s->ob, mf->mat_nr, &ima, NULL, NULL); + } + else { + MTFace *tf = s->me->mtface+face_index; + ima = tf->tpage; + } + + return ima; +} + +static Image *project_paint_face_image(const ProjPaintState *ps, int face_index) +{ + Image *ima; + + if(scene_use_new_shading_nodes(ps->scene)) { + MFace *mf = ps->dm_mface+face_index; + ED_object_get_active_image(ps->ob, mf->mat_nr, &ima, NULL, NULL); + } + else { + MTFace *tf = ps->dm_mtface+face_index; + ima = tf->tpage; + } + + return ima; +} + /* fast projection bucket array lookup, use the safe version for bound checking */ static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2]) { @@ -670,6 +706,7 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float int side; int face_index; MTFace *tf; + Image *ima; ImBuf *ibuf; int xi, yi; @@ -687,8 +724,9 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float else { /* QUAD */ interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w); } - - ibuf = tf->tpage->ibufs.first; /* we must have got the imbuf before getting here */ + + ima = project_paint_face_image(ps, face_index); + ibuf = ima->ibufs.first; /* we must have got the imbuf before getting here */ if (!ibuf) return 0; if (interp) { @@ -1053,6 +1091,9 @@ static int check_seam(const ProjPaintState *ps, const int orig_face, const int o /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */ if (i2_fidx != -1) { + Image *tpage = project_paint_face_image(ps, face_index); + Image *orig_tpage = project_paint_face_image(ps, orig_face); + /* This IS an adjacent face!, now lets check if the UVs are ok */ tf = ps->dm_mtface + face_index; @@ -1061,7 +1102,7 @@ static int check_seam(const ProjPaintState *ps, const int orig_face, const int o *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx; /* first test if they have the same image */ - if ( (orig_tf->tpage == tf->tpage) && + if ( (orig_tpage == tpage) && cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) && cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) ) { @@ -1308,9 +1349,10 @@ static float project_paint_uvpixel_mask( if (ps->do_layer_stencil) { /* another UV layers image is masking this one's */ ImBuf *ibuf_other; + Image *other_tpage = project_paint_face_image(ps, face_index); const MTFace *tf_other = ps->dm_mtface_stencil + face_index; - if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) { + if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) { /* BKE_image_get_ibuf - TODO - this may be slow */ unsigned char rgba_ub[4]; float rgba_f[4]; @@ -1464,9 +1506,10 @@ static ProjPixel *project_paint_uvpixel_init( if (ps->tool==PAINT_TOOL_CLONE) { if (ps->dm_mtface_clone) { ImBuf *ibuf_other; + Image *other_tpage = project_paint_face_image(ps, face_index); const MTFace *tf_other = ps->dm_mtface_clone + face_index; - if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) { + if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) { /* BKE_image_get_ibuf - TODO - this may be slow */ if (ibuf->rect_float) { @@ -2684,11 +2727,8 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index LinkNode *node; int face_index, image_index=0; ImBuf *ibuf = NULL; + Image *tpage_last = NULL, *tpage; Image *ima = NULL; - MTFace *tf; - - Image *tpage_last = NULL; - if (ps->image_tot==1) { /* Simple loop, no context switching */ @@ -2706,9 +2746,9 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index face_index = GET_INT_FROM_POINTER(node->link); /* Image context switching */ - tf = ps->dm_mtface+face_index; - if (tpage_last != tf->tpage) { - tpage_last = tf->tpage; + tpage = project_paint_face_image(ps, face_index); + if (tpage_last != tpage) { + tpage_last = tpage; for (image_index=0; image_index < ps->image_tot; image_index++) { if (ps->projImages[image_index].ima == tpage_last) { @@ -2876,7 +2916,7 @@ static void project_paint_begin(ProjPaintState *ps) LinkNode *node; ProjPaintImage *projIma; - Image *tpage_last = NULL; + Image *tpage_last = NULL, *tpage; /* Face vars */ MFace *mf; @@ -3210,7 +3250,9 @@ static void project_paint_begin(ProjPaintState *ps) } #endif - if (tf->tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_MASK)==0 || mf->flag & ME_FACE_SEL)) { + tpage = project_paint_face_image(ps, face_index); + + if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_MASK)==0 || mf->flag & ME_FACE_SEL)) { float *v1coSS, *v2coSS, *v3coSS, *v4coSS=NULL; @@ -3283,17 +3325,17 @@ static void project_paint_begin(ProjPaintState *ps) } } - if (tpage_last != tf->tpage) { + if (tpage_last != tpage) { - image_index = BLI_linklist_index(image_LinkList, tf->tpage); + image_index = BLI_linklist_index(image_LinkList, tpage); - if (image_index==-1 && BKE_image_get_ibuf(tf->tpage, NULL)) { /* MemArena dosnt have an append func */ - BLI_linklist_append(&image_LinkList, tf->tpage); + if (image_index==-1 && BKE_image_get_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */ + BLI_linklist_append(&image_LinkList, tpage); image_index = ps->image_tot; ps->image_tot++; } - tpage_last = tf->tpage; + tpage_last = tpage; } if (image_index != -1) { @@ -4481,7 +4523,7 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint ) { ImBuf *ibuf; - newimage = (s->me->mtface+newfaceindex)->tpage; + newimage = imapaint_face_image(s, newfaceindex); ibuf= BKE_image_get_ibuf(newimage, s->sima? &s->sima->iuser: NULL); if(ibuf && ibuf->rect) diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index dbb96b68587..ee118f12062 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -38,6 +38,7 @@ set(SRC buttons_context.c buttons_header.c buttons_ops.c + buttons_texture.c space_buttons.c buttons_intern.h diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 6d6f73e98d8..e38ac7bd413 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -54,7 +54,6 @@ #include "BKE_screen.h" #include "BKE_texture.h" - #include "RNA_access.h" #include "ED_armature.h" @@ -66,13 +65,6 @@ #include "buttons_intern.h" // own include -typedef struct ButsContextPath { - PointerRNA ptr[8]; - int len; - int flag; - int tex_ctx; -} ButsContextPath; - static int set_pointer_type(ButsContextPath *path, bContextDataResult *result, StructRNA *type) { PointerRNA *ptr; @@ -373,102 +365,141 @@ static int buttons_context_path_brush(ButsContextPath *path) return 0; } -static int buttons_context_path_texture(ButsContextPath *path) +static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct) { - Material *ma; - Lamp *la; - Brush *br; - World *wo; - ParticleSystem *psys; - Tex *tex; - PointerRNA *ptr= &path->ptr[path->len-1]; - int orig_len = path->len; + if(ct) { + /* new shading system */ + PointerRNA *ptr= &path->ptr[path->len-1]; + ID *id; + + /* if we already have a (pinned) texture, we're done */ + if(RNA_struct_is_a(ptr->type, &RNA_Texture)) + return 1; + + if(!ct->user) + return 0; + + id= ct->user->id; + + if(id) { + if(GS(id->name) == ID_BR) + buttons_context_path_brush(path); + else if(GS(id->name) == ID_MA) + buttons_context_path_material(path, 0); + else if(GS(id->name) == ID_WO) + buttons_context_path_world(path); + else if(GS(id->name) == ID_LA) + buttons_context_path_data(path, OB_LAMP); + else if(GS(id->name) == ID_PA) + buttons_context_path_particle(path); + else if(GS(id->name) == ID_OB) + buttons_context_path_object(path); + } + + if(ct->texture) { + RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]); + path->len++; + } - /* if we already have a (pinned) texture, we're done */ - if(RNA_struct_is_a(ptr->type, &RNA_Texture)) { return 1; } - /* try brush */ - if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) { - br= path->ptr[path->len-1].data; - - if(br) { - tex= give_current_brush_texture(br); + else { + /* old shading system */ + Material *ma; + Lamp *la; + Brush *br; + World *wo; + ParticleSystem *psys; + Tex *tex; + PointerRNA *ptr= &path->ptr[path->len-1]; + int orig_len = path->len; - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; + /* if we already have a (pinned) texture, we're done */ + if(RNA_struct_is_a(ptr->type, &RNA_Texture)) { return 1; } - } - /* try world */ - if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) { - wo= path->ptr[path->len-1].data; - - if(wo && GS(wo->id.name)==ID_WO) { - tex= give_current_world_texture(wo); - - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - /* try particles */ - if((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) { - if(path->ptr[path->len-1].type == &RNA_ParticleSettings) { - ParticleSettings *part = path->ptr[path->len-1].data; - - tex= give_current_particle_texture(part); - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - else { - psys= path->ptr[path->len-1].data; - - if(psys && psys->part && GS(psys->part->id.name)==ID_PA) { - tex= give_current_particle_texture(psys->part); + /* try brush */ + if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) { + br= path->ptr[path->len-1].data; + + if(br) { + tex= give_current_brush_texture(br); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; return 1; } } - } - /* try material */ - if(buttons_context_path_material(path, 1)) { - ma= path->ptr[path->len-1].data; + /* try world */ + if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) { + wo= path->ptr[path->len-1].data; - if(ma) { - tex= give_current_material_texture(ma); + if(wo && GS(wo->id.name)==ID_WO) { + tex= give_current_world_texture(wo); - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } } - } - /* try lamp */ - if(buttons_context_path_data(path, OB_LAMP)) { - la= path->ptr[path->len-1].data; + /* try particles */ + if((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) { + if(path->ptr[path->len-1].type == &RNA_ParticleSettings) { + ParticleSettings *part = path->ptr[path->len-1].data; - if(la) { - tex= give_current_lamp_texture(la); + tex= give_current_particle_texture(part); + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } + else { + psys= path->ptr[path->len-1].data; - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; + if(psys && psys->part && GS(psys->part->id.name)==ID_PA) { + tex= give_current_particle_texture(psys->part); + + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } + } } - } - /* try brushes again in case of no material, lamp, etc */ - path->len = orig_len; - if(buttons_context_path_brush(path)) { - br= path->ptr[path->len-1].data; - - if(br) { - tex= give_current_brush_texture(br); + /* try material */ + if(buttons_context_path_material(path, 1)) { + ma= path->ptr[path->len-1].data; + + if(ma) { + tex= give_current_material_texture(ma); + + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } + } + /* try lamp */ + if(buttons_context_path_data(path, OB_LAMP)) { + la= path->ptr[path->len-1].data; + + if(la) { + tex= give_current_lamp_texture(la); + + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } + } + /* try brushes again in case of no material, lamp, etc */ + path->len = orig_len; + if(buttons_context_path_brush(path)) { + br= path->ptr[path->len-1].data; - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; + if(br) { + tex= give_current_brush_texture(br); + + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } } } @@ -530,7 +561,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma found= buttons_context_path_material(path, 0); break; case BCONTEXT_TEXTURE: - found= buttons_context_path_texture(path); + found= buttons_context_path_texture(path, sbuts->texuser); break; case BCONTEXT_BONE: found= buttons_context_path_bone(path); @@ -580,6 +611,8 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts) PointerRNA *ptr; int a, pflag= 0, flag= 0; + buttons_texture_context_compute(C, sbuts); + if(!sbuts->path) sbuts->path= MEM_callocN(sizeof(ButsContextPath), "ButsContextPath"); @@ -649,7 +682,8 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts) const char *buttons_context_dir[] = { "world", "object", "mesh", "armature", "lattice", "curve", "meta_ball", "lamp", "speaker", "camera", "material", "material_slot", - "texture", "texture_slot", "bone", "edit_bone", "pose_bone", "particle_system", "particle_system_editable", + "texture", "texture_slot", "texture_user", "bone", "edit_bone", + "pose_bone", "particle_system", "particle_system_editable", "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL}; int buttons_context(const bContext *C, const char *member, bContextDataResult *result) @@ -710,7 +744,17 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r return 1; } else if(CTX_data_equals(member, "texture")) { - set_pointer_type(path, result, &RNA_Texture); + ButsContextTexture *ct= sbuts->texuser; + + if(ct) { + /* new shading system */ + CTX_data_pointer_set(result, &ct->texture->id, &RNA_Texture, ct->texture); + } + else { + /* old shading system */ + set_pointer_type(path, result, &RNA_Texture); + } + return 1; } else if(CTX_data_equals(member, "material_slot")) { @@ -729,23 +773,52 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r return 1; } - else if(CTX_data_equals(member, "texture_node")) { - PointerRNA *ptr; + else if(CTX_data_equals(member, "texture_user")) { + ButsContextTexture *ct= sbuts->texuser; - if((ptr=get_pointer_type(path, &RNA_Material))) { - Material *ma= ptr->data; + if(!ct) + return 0; /* old shading system */ - if(ma) { - bNode *node= give_current_material_texture_node(ma); - CTX_data_pointer_set(result, &ma->id, &RNA_Node, node); - } + if(ct->user && ct->user->ptr.data) { + ButsTextureUser *user= ct->user; + CTX_data_pointer_set(result, user->ptr.id.data, user->ptr.type, user->ptr.data); } return 1; } + else if(CTX_data_equals(member, "texture_node")) { + ButsContextTexture *ct= sbuts->texuser; + + if(ct) { + /* new shading system */ + if(ct->user && ct->user->node) + CTX_data_pointer_set(result, &ct->user->ntree->id, &RNA_Node, ct->user->node); + + return 1; + } + else { + /* old shading system */ + PointerRNA *ptr; + + if((ptr=get_pointer_type(path, &RNA_Material))) { + Material *ma= ptr->data; + + if(ma) { + bNode *node= give_current_material_texture_node(ma); + CTX_data_pointer_set(result, &ma->id, &RNA_Node, node); + } + } + + return 1; + } + } else if(CTX_data_equals(member, "texture_slot")) { + ButsContextTexture *ct= sbuts->texuser; PointerRNA *ptr; + if(ct) + return 0; /* new shading system */ + if((ptr=get_pointer_type(path, &RNA_Material))) { Material *ma= ptr->data; diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index 27084488163..aa692a940d8 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -31,14 +31,20 @@ #ifndef ED_BUTTONS_INTERN_H #define ED_BUTTONS_INTERN_H +#include "DNA_listBase.h" +#include "RNA_types.h" + struct ARegion; struct ARegionType; +struct ID; +struct SpaceButs; +struct Tex; struct bContext; struct bContextDataResult; -struct SpaceButs; +struct bNode; +struct bNodeTree; struct uiLayout; struct wmOperatorType; -struct ID; /* buts->scaflag */ #define BUTS_SENS_SEL 1 @@ -53,6 +59,42 @@ struct ID; #define BUTS_SENS_STATE 512 #define BUTS_ACT_STATE 1024 +/* context data */ + +typedef struct ButsContextPath { + PointerRNA ptr[8]; + int len; + int flag; + int tex_ctx; +} ButsContextPath; + +typedef struct ButsTextureUser { + struct ButsTextureUser *next, *prev; + + struct ID *id; + + PointerRNA ptr; + PropertyRNA *prop; + + struct bNodeTree *ntree; + struct bNode *node; + + const char *category; + int icon; + const char *name; + + int index; +} ButsTextureUser; + +typedef struct ButsContextTexture { + ListBase users; + + struct Tex *texture; + + struct ButsTextureUser *user; + int index; +} ButsContextTexture; + /* internal exports only */ /* buttons_header.c */ @@ -67,6 +109,9 @@ struct ID *buttons_context_id_path(const struct bContext *C); extern const char *buttons_context_dir[]; /* doc access */ +/* buttons_texture.c */ +void buttons_texture_context_compute(const struct bContext *C, struct SpaceButs *sbuts); + /* buttons_ops.c */ void BUTTONS_OT_file_browse(struct wmOperatorType *ot); void BUTTONS_OT_directory_browse(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c new file mode 100644 index 00000000000..dd9f3c57896 --- /dev/null +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -0,0 +1,469 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_buttons/buttons_texture.c + * \ingroup spbuttons + */ + + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "DNA_brush_types.h" +#include "DNA_ID.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_world_types.h" + +#include "BKE_context.h" +#include "BKE_material.h" +#include "BKE_modifier.h" +#include "BKE_node.h" +#include "BKE_paint.h" +#include "BKE_particle.h" +#include "BKE_scene.h" + +#include "RNA_access.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "ED_node.h" +#include "ED_screen.h" + +#include "../interface/interface_intern.h" + +#include "buttons_intern.h" // own include + +/************************* Texture User **************************/ + +static void buttons_texture_user_property_add(ListBase *users, ID *id, + PointerRNA ptr, PropertyRNA *prop, + const char *category, int icon, const char *name) +{ + ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser"); + + user->id= id; + user->ptr = ptr; + user->prop = prop; + user->category = category; + user->icon = icon; + user->name = name; + user->index = BLI_countlist(users); + + BLI_addtail(users, user); +} + +static void buttons_texture_user_node_add(ListBase *users, ID *id, + bNodeTree *ntree, bNode *node, + const char *category, int icon, const char *name) +{ + ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser"); + + user->id= id; + user->ntree = ntree; + user->node = node; + user->category = category; + user->icon = icon; + user->name = name; + user->index = BLI_countlist(users); + + BLI_addtail(users, user); +} + +static void buttons_texture_users_find_nodetree(ListBase *users, ID *id, + bNodeTree *ntree, const char *category) +{ + bNode *node; + + if(ntree) { + for(node=ntree->nodes.first; node; node=node->next) { + if(node->typeinfo->nclass == NODE_CLASS_TEXTURE) { + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + prop = RNA_struct_find_property(&ptr, "texture"); + + buttons_texture_user_node_add(users, id, ntree, node, + category, RNA_struct_ui_icon(ptr.type), node->name); + } + else if(node->type == NODE_GROUP && node->id) { + buttons_texture_users_find_nodetree(users, id, (bNodeTree*)node->id, category); + } + } + } +} + +static void buttons_texture_modifier_foreach(void *userData, Object *ob, ModifierData *md, const char *propname) +{ + PointerRNA ptr; + PropertyRNA *prop; + ListBase *users = userData; + + RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr); + prop = RNA_struct_find_property(&ptr, propname); + + buttons_texture_user_property_add(users, &ob->id, ptr, prop, + "Modifiers", RNA_struct_ui_icon(ptr.type), md->name); +} + +static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceButs *sbuts) +{ + Scene *scene= NULL; + Object *ob= NULL; + Material *ma= NULL; + Lamp *la= NULL; + World *wrld= NULL; + Brush *brush= NULL; + ID *pinid = sbuts->pinid; + + /* get data from context */ + if(pinid) { + if(GS(pinid->name) == ID_SCE) + scene= (Scene*)pinid; + else if(GS(pinid->name) == ID_OB) + ob= (Object*)pinid; + else if(GS(pinid->name) == ID_LA) + la= (Lamp*)pinid; + else if(GS(pinid->name) == ID_WO) + wrld= (World*)pinid; + else if(GS(pinid->name) == ID_MA) + ma= (Material*)pinid; + else if(GS(pinid->name) == ID_BR) + brush= (Brush*)pinid; + } + + if(!scene) + scene= CTX_data_scene(C); + + if(!(pinid || pinid == &scene->id)) { + ob= (scene->basact)? scene->basact->object: NULL; + wrld= scene->world; + brush= paint_brush(paint_get_active(scene)); + } + + if(ob && ob->type == OB_LAMP && !la) + la= ob->data; + if(ob && !ma) + ma= give_current_material(ob, ob->actcol); + + /* fill users */ + users->first = users->last = NULL; + + if(ma) + buttons_texture_users_find_nodetree(users, &ma->id, ma->nodetree, "Material"); + if(la) + buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, "Lamp"); + if(wrld) + buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, "World"); + + if(ob) { + ParticleSystem *psys= psys_get_current(ob); + MTex *mtex; + int a; + + /* modifiers */ + modifiers_foreachTexLink(ob, buttons_texture_modifier_foreach, users); + + /* particle systems */ + if(psys) { + /* todo: these slots are not in the UI */ + for(a=0; apart->mtex[a]; + + if(mtex) { + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(&psys->part->id, &RNA_ParticleSettingsTextureSlot, mtex, &ptr); + prop = RNA_struct_find_property(&ptr, "texture"); + + buttons_texture_user_property_add(users, &psys->part->id, ptr, prop, + "Particles", RNA_struct_ui_icon(&RNA_ParticleSettings), psys->name); + } + } + } + + /* field */ + if(ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) { + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(&ob->id, &RNA_FieldSettings, ob->pd, &ptr); + prop = RNA_struct_find_property(&ptr, "texture"); + + buttons_texture_user_property_add(users, &ob->id, ptr, prop, + "Fields", ICON_FORCE_TEXTURE, "Texture Field"); + } + } + + /* brush */ + if(brush) { + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(&brush->id, &RNA_BrushTextureSlot, &brush->mtex, &ptr); + prop= RNA_struct_find_property(&ptr, "texture"); + + buttons_texture_user_property_add(users, &brush->id, ptr, prop, + "Brush", ICON_BRUSH_DATA, brush->id.name+2); + } +} + +void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts) +{ + /* gatheravailable texture users in context. runs on every draw of + properties editor, before the buttons are created. */ + ButsContextTexture *ct= sbuts->texuser; + Scene *scene= CTX_data_scene(C); + + if(!scene_use_new_shading_nodes(scene)) { + if(ct) { + MEM_freeN(ct); + BLI_freelistN(&ct->users); + sbuts->texuser= NULL; + } + + return; + } + + if(!ct) { + ct= MEM_callocN(sizeof(ButsContextTexture), "ButsContextTexture"); + sbuts->texuser= ct; + } + else { + BLI_freelistN(&ct->users); + } + + buttons_texture_users_from_context(&ct->users, C, sbuts); + + /* set one user as active based on active index */ + if(ct->index >= BLI_countlist(&ct->users)) + ct->index= 0; + + ct->user = BLI_findlink(&ct->users, ct->index); + ct->texture = NULL; + + if(ct->user) { + if(ct->user->ptr.data) { + PointerRNA texptr; + Tex *tex; + + /* get texture datablock pointer if it's a property */ + texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop); + tex = (RNA_struct_is_a(texptr.type, &RNA_Texture))? texptr.data: NULL; + + ct->texture = tex; + } + else if(ct->user->node && !(ct->user->node->flag & NODE_ACTIVE_TEXTURE)) { + ButsTextureUser *user; + + /* detect change of active texture node in same node tree, in that + case we also automatically switch to the other node */ + for(user=ct->users.first; user; user=user->next) { + if(user->ntree == ct->user->ntree && user->node != ct->user->node) { + if(user->node->flag & NODE_ACTIVE_TEXTURE) { + ct->user = user; + ct->index = BLI_findindex(&ct->users, user); + break; + } + } + } + } + } +} + +static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg)) +{ + /* callback when selecting a texture user in the menu */ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + ButsTextureUser *user = (ButsTextureUser*)user_p; + PointerRNA texptr; + Tex *tex; + + if(!ct) + return; + + /* set user as active */ + if(user->node) { + ED_node_set_active(CTX_data_main(C), user->ntree, user->node); + ct->texture = NULL; + } + else { + texptr = RNA_property_pointer_get(&user->ptr, user->prop); + tex = (RNA_struct_is_a(texptr.type, &RNA_Texture))? texptr.data: NULL; + + ct->texture = tex; + } + + ct->user = user; + ct->index = user->index; +} + +static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUSED(arg)) +{ + /* callback when opening texture user selection menu, to create buttons. */ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + ButsTextureUser *user; + uiBlock *block = uiLayoutGetBlock(layout); + const char *last_category = NULL; + + for(user=ct->users.first; user; user=user->next) { + uiBut *but; + char name[UI_MAX_NAME_STR]; + + /* add label per category */ + if(!last_category || strcmp(last_category, user->category) != 0) { + uiItemL(layout, user->category, ICON_NONE); + but= block->buttons.last; + but->flag= UI_TEXT_LEFT; + } + + /* create button */ + BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); + + but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiButSetNFunc(but, template_texture_select, MEM_dupallocN(user), NULL); + + last_category = user->category; + } +} + +void uiTemplateTextureUser(uiLayout *layout, bContext *C) +{ + /* texture user selection dropdown menu. the available users have been + gathered before drawing in ButsContextTexture, we merely need to + display the current item. */ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + uiBlock *block = uiLayoutGetBlock(layout); + uiBut *but; + ButsTextureUser *user; + char name[UI_MAX_NAME_STR]; + + if(!ct) + return; + + /* get current user */ + user= ct->user; + + if(!user) { + uiItemL(layout, "No textures in context.", ICON_NONE); + return; + } + + /* create button */ + BLI_snprintf(name, UI_MAX_NAME_STR, "%s", user->name); + + if(user->icon) { + but= uiDefIconTextMenuBut(block, template_texture_user_menu, NULL, + user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, ""); + } + else { + but= uiDefMenuBut(block, template_texture_user_menu, NULL, + name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, ""); + } + + /* some cosmetic tweaks */ + but->type= MENU; + but->flag |= UI_TEXT_LEFT; + but->flag &= ~UI_ICON_SUBMENU; +} + +/************************* Texture Show **************************/ + +static void template_texture_show(bContext *C, void *data_p, void *prop_p) +{ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + ButsTextureUser *user; + + if(!ct) + return; + + for(user=ct->users.first; user; user=user->next) + if(user->ptr.data == data_p && user->prop == prop_p) + break; + + if(user) { + /* select texture */ + template_texture_select(C, user, NULL); + + /* change context */ + sbuts->mainb= BCONTEXT_TEXTURE; + sbuts->mainbuser= sbuts->mainb; + sbuts->preview= 1; + + /* redraw editor */ + ED_area_tag_redraw(CTX_wm_area(C)); + } +} + +void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, PropertyRNA *prop) +{ + /* button to quickly show texture in texture tab */ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + ButsTextureUser *user; + + /* only show button in other tabs in properties editor */ + if(!ct || sbuts->mainb == BCONTEXT_TEXTURE) + return; + + /* find corresponding texture user */ + for(user=ct->users.first; user; user=user->next) + if(user->ptr.data == ptr->data && user->prop == prop) + break; + + /* draw button */ + if(user) { + uiBlock *block = uiLayoutGetBlock(layout); + uiBut *but; + + but= uiDefIconBut(block, BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, "Show texture in texture tab"); + uiButSetFunc(but, template_texture_show, user->ptr.data, user->prop); + } +} + diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 4c328d174e9..0c326af406f 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -104,6 +104,12 @@ static void buttons_free(SpaceLink *sl) if(sbuts->path) MEM_freeN(sbuts->path); + + if(sbuts->texuser) { + ButsContextTexture *ct= sbuts->texuser; + BLI_freelistN(&ct->users); + MEM_freeN(ct); + } } /* spacetype; init callback */ @@ -127,6 +133,7 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl) /* clear or remove stuff from old */ sbutsn->ri= NULL; sbutsn->path= NULL; + sbutsn->texuser= NULL; return (SpaceLink *)sbutsn; } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 3b9876329ec..c29553a9c87 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -47,7 +47,10 @@ #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_image.h" +#include "BKE_global.h" +#include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_scene.h" #include "BKE_screen.h" #include "IMB_imbuf_types.h" @@ -81,7 +84,7 @@ Image *ED_space_image(SpaceImage *sima) /* called to assign images to UV faces */ void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) { - ED_uvedit_assign_image(scene, obedit, ima, sima->image); + ED_uvedit_assign_image(CTX_data_main(C), scene, obedit, ima, sima->image); /* change the space ima after because uvedit_face_visible uses the space ima * to check if the face is displayed in UV-localview */ @@ -572,6 +575,7 @@ static void image_dropboxes(void) static void image_refresh(const bContext *C, ScrArea *UNUSED(sa)) { + Scene *scene = CTX_data_scene(C); SpaceImage *sima= CTX_wm_space_image(C); Object *obedit= CTX_data_edit_object(C); Image *ima; @@ -586,19 +590,31 @@ static void image_refresh(const bContext *C, ScrArea *UNUSED(sa)) else if(obedit && obedit->type == OB_MESH) { Mesh *me= (Mesh*)obedit->data; EditMesh *em= BKE_mesh_get_editmesh(me); - MTFace *tf; - - if(em && EM_texFaceCheck(em)) { - sima->image= NULL; + int sloppy= 1; /* partially selected face is ok */ + + if(scene_use_new_shading_nodes(scene)) { + /* new shading system, get image from material */ + EditFace *efa= EM_get_actFace(em, sloppy); + + if(efa) + ED_object_get_active_image(obedit, efa->mat_nr, &sima->image, NULL, NULL); + } + else { + /* old shading system, we set texface */ + MTFace *tf; - tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */ - - if(tf) { - /* don't need to check for pin here, see above */ - sima->image= tf->tpage; + if(em && EM_texFaceCheck(em)) { + sima->image= NULL; - if(sima->flag & SI_EDITTILE); - else sima->curtile= tf->tile; + tf = EM_get_active_mtface(em, NULL, NULL, sloppy); + + if(tf) { + /* don't need to check for pin here, see above */ + sima->image= tf->tpage; + + if(sima->flag & SI_EDITTILE); + else sima->curtile= tf->tile; + } } } diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 991b35585a6..f33b784c5d2 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -25,6 +25,7 @@ set(INC ../../blenlib ../../blenloader ../../imbuf + ../../gpu ../../makesdna ../../makesrna ../../nodes diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript index c4309dcfca3..6b72fd066e0 100644 --- a/source/blender/editors/space_node/SConscript +++ b/source/blender/editors/space_node/SConscript @@ -4,7 +4,7 @@ Import ('env') sources = env.Glob('*.c') incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf' -incs += ' ../../nodes ../../render/extern/include ../../blenloader' +incs += ' ../../nodes ../../render/extern/include ../../blenloader ../../gpu' incs += ' ../../windowmanager #intern/guardedalloc #extern/glew/include' defs = [] cf = [] diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index a1b705610f4..23855ff24e1 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -90,6 +90,8 @@ #include "RNA_enum_types.h" +#include "GPU_material.h" + #include "node_intern.h" static EnumPropertyItem socket_in_out_items[] = { @@ -598,6 +600,8 @@ static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup) void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) { + int was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE); + nodeSetActive(ntree, node); if(node->type!=NODE_GROUP) { @@ -621,6 +625,15 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) ED_node_generic_update(bmain, ntree, node); } + /* if active texture changed, free glsl materials */ + if((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { + Material *ma; + + for(ma=bmain->mat.first; ma; ma=ma->id.next) + if(ma->nodetree && ma->use_nodes && has_nodetree(ma->nodetree, ntree)) + GPU_material_free(ma); + } + WM_main_add_notifier(NC_MATERIAL|ND_NODES, node->id); } else if(ntree->type==NTREE_COMPOSIT) { diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 806a6f98828..5aa15cc68d6 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -215,6 +215,11 @@ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_t } } + /* also preserve mapping for texture nodes */ + if(node_from->typeinfo->nclass == NODE_CLASS_TEXTURE && + node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE) + memcpy(node_from->storage, node_prev->storage, sizeof(NodeTexBase)); + /* remove node */ node_remove_linked(ntree, node_prev); } @@ -503,6 +508,10 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo but->flag |= UI_TEXT_LEFT|UI_BUT_NODE_LINK; but->poin= (char*)but; but->func_argN = arg; + + if(sock->link && sock->link->fromnode) + if(sock->link->fromnode->flag & NODE_ACTIVE_TEXTURE) + but->flag |= UI_BUT_NODE_ACTIVE; } /**************************** Node Tree Layout *******************************/ diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 670943afdd3..e23824a2210 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -40,11 +40,12 @@ #include "DNA_material_types.h" #include "DNA_meshdata_types.h" +#include "DNA_node_types.h" +#include "DNA_object_types.h" #include "DNA_property_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_view3d_types.h" -#include "DNA_object_types.h" #include "BKE_DerivedMesh.h" #include "BKE_effect.h" @@ -52,6 +53,7 @@ #include "BKE_material.h" #include "BKE_paint.h" #include "BKE_property.h" +#include "BKE_scene.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -64,6 +66,7 @@ #include "GPU_material.h" #include "ED_mesh.h" +#include "ED_uvedit.h" #include "view3d_intern.h" // own include @@ -619,7 +622,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl) ddm->release(ddm); } -void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect) +void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect) { Mesh *me= ob->data; @@ -676,3 +679,179 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } +/************************** NEW SHADING NODES ********************************/ + +typedef struct TexMatCallback { + Scene *scene; + Object *ob; + Mesh *me; + DerivedMesh *dm; +} TexMatCallback; + +static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs) +{ + /* all we have to do here is simply enable the GLSL material, but note + that the GLSL code will give different result depending on the drawtype, + in texture draw mode it will output the active texture node, in material + draw mode it will show the full material. */ + GPU_enable_material(mat_nr, attribs); +} + +static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs) +{ + /* texture draw mode without GLSL */ + TexMatCallback *data= (TexMatCallback*)userData; + GPUVertexAttribs *gattribs = attribs; + Image *ima; + ImageUser *iuser; + bNode *node; + int texture_set= 0; + + /* draw image texture if we find one */ + if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) { + /* get openl texture */ + int mipmap= 1; + int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0; + float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + if(bindcode) { + NodeTexBase *texbase= node->storage; + + /* disable existing material */ + GPU_disable_material(); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0); + + /* bind texture */ + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, ima->bindcode); + glColor3f(1.0f, 1.0f, 1.0f); + + glMatrixMode(GL_TEXTURE); + glLoadMatrixf(texbase->tex_mapping.mat); + glMatrixMode(GL_MODELVIEW); + + /* use active UV texture layer */ + memset(gattribs, 0, sizeof(*gattribs)); + + gattribs->layer[0].type= CD_MTFACE; + gattribs->layer[0].name[0]= '\0'; + gattribs->layer[0].gltexco= 1; + gattribs->totlayer= 1; + + texture_set= 1; + } + } + + if(!texture_set) { + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + /* disable texture */ + glDisable(GL_TEXTURE_2D); + glDisable(GL_COLOR_MATERIAL); + + /* draw single color */ + GPU_enable_material(mat_nr, attribs); + } +} + +static int tex_mat_set_face_mesh_cb(void *userData, int index) +{ + /* faceselect mode face hiding */ + TexMatCallback *data= (TexMatCallback*)userData; + Mesh *me = (Mesh*)data->me; + MFace *mface = &me->mface[index]; + + return !(mface->flag & ME_HIDE); +} + +static int tex_mat_set_face_editmesh_cb(void *UNUSED(userData), int index) +{ + /* editmode face hiding */ + EditFace *efa= EM_get_face_for_index(index); + + return !(efa->h); +} + +void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect) +{ + if(!scene_use_new_shading_nodes(scene)) { + draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, faceselect); + return; + } + + /* set opengl state for negative scale & color */ + if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); + else glFrontFace(GL_CCW); + + glEnable(GL_LIGHTING); + + if(ob->mode & OB_MODE_WEIGHT_PAINT) { + /* weight paint mode exception */ + int useColors= 1; + + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, + ob->data, useColors, GPU_enable_material, NULL); + } + else { + Mesh *me= ob->data; + TexMatCallback data = {scene, ob, me, dm}; + int (*set_face_cb)(void*, int); + int glsl; + + /* face hiding callback depending on mode */ + if(ob == scene->obedit) + set_face_cb= tex_mat_set_face_editmesh_cb; + else if(faceselect) + set_face_cb= tex_mat_set_face_mesh_cb; + else + set_face_cb= NULL; + + /* test if we can use glsl */ + glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support(); + + GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL); + + if(glsl) { + /* draw glsl */ + dm->drawMappedFacesMat(dm, + tex_mat_set_material_cb, + set_face_cb, &data); + } + else { + float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + /* draw textured */ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0); + + dm->drawMappedFacesMat(dm, + tex_mat_set_texture_cb, + set_face_cb, &data); + } + + GPU_end_object_materials(); + } + + /* reset opengl state */ + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glBindTexture(GL_TEXTURE_2D, 0); + glFrontFace(GL_CCW); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + /* faceselect mode drawing over textured mesh */ + if(!(ob == scene->obedit) && faceselect) + draw_mesh_face_select(rv3d, ob->data, dm); +} + diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index f2bd4b51d94..8e592ad9f68 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -108,7 +108,7 @@ /* this condition has been made more complex since editmode can draw textures */ #define CHECK_OB_DRAWTEXTURE(vd, dt) \ - ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \ + ((ELEM(vd->drawtype, OB_TEXTURE, OB_MATERIAL) && dt>OB_SOLID) || \ (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX)) static void draw_bounding_volume(Scene *scene, Object *ob, char type); @@ -252,6 +252,8 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt) return 0; if(ob==OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)) return 0; + if(scene_use_new_shading_nodes(scene)) + return 0; return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 51bbf591bb3..8e20f331698 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2229,11 +2229,17 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d) { CustomDataMask mask= 0; - if((v3d->drawtype == OB_TEXTURE) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) { + if(ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) { mask |= CD_MASK_MTFACE | CD_MASK_MCOL; - if(scene->gm.matmode == GAME_MAT_GLSL) - mask |= CD_MASK_ORCO; + if(scene_use_new_shading_nodes(scene)) { + if(v3d->drawtype == OB_MATERIAL) + mask |= CD_MASK_ORCO; + } + else { + if(scene->gm.matmode == GAME_MAT_GLSL) + mask |= CD_MASK_ORCO; + } } return mask; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 62b875c82de..173ab809b53 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -37,7 +37,9 @@ #include "MEM_guardedalloc.h" #include "DNA_object_types.h" +#include "DNA_material_types.h" #include "DNA_meshdata_types.h" +#include "DNA_node_types.h" #include "DNA_scene_types.h" #include "BLI_math.h" @@ -50,11 +52,16 @@ #include "BKE_depsgraph.h" #include "BKE_image.h" #include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" #include "BKE_mesh.h" +#include "BKE_node.h" #include "BKE_report.h" +#include "BKE_scene.h" #include "ED_image.h" #include "ED_mesh.h" +#include "ED_node.h" #include "ED_uvedit.h" #include "ED_object.h" #include "ED_screen.h" @@ -87,9 +94,46 @@ int ED_uvedit_test(Object *obedit) return ret; } +/**************************** object active image *****************************/ + +static int is_image_texture_node(bNode *node) +{ + return ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT); +} + +int ED_object_get_active_image(Object *ob, int mat_nr, Image **ima, ImageUser **iuser, bNode **node_r) +{ + Material *ma= give_current_material(ob, mat_nr); + bNode *node= (ma && ma->use_nodes)? nodeGetActiveTexture(ma->nodetree): NULL; + + if(node && is_image_texture_node(node)) { + if(ima) *ima= (Image*)node->id; + if(iuser) *iuser= NULL; + if(node_r) *node_r= node; + return TRUE; + } + + if(ima) *ima= NULL; + if(iuser) *iuser= NULL; + if(node_r) *node_r= node; + + return FALSE; +} + +void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *ima) +{ + Material *ma= give_current_material(ob, mat_nr); + bNode *node= (ma && ma->use_nodes)? nodeGetActiveTexture(ma->nodetree): NULL; + + if(node && is_image_texture_node(node)) { + node->id= &ima->id; + ED_node_generic_update(bmain, ma->nodetree, node); + } +} + /************************* assign image ************************/ -void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *previma) +void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *ima, Image *previma) { EditMesh *em; EditFace *efa; @@ -109,35 +153,46 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre BKE_mesh_end_editmesh(obedit->data, em); return; } - - /* ensure we have a uv layer */ - if(!CustomData_has_layer(&em->fdata, CD_MTFACE)) { - EM_add_data_layer(em, &em->fdata, CD_MTFACE, NULL); - update= 1; + + if(scene_use_new_shading_nodes(scene)) { + /* new shading system, assign image in material */ + int sloppy= 1; + EditFace *efa= EM_get_actFace(em, sloppy); + + if(efa) + ED_object_assign_active_image(bmain, obedit, efa->mat_nr, ima); } - - /* now assign to all visible faces */ - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, previma, efa, tf)) { - if(ima) { - tf->tpage= ima; - - if(ima->id.us==0) id_us_plus(&ima->id); - else id_lib_extern(&ima->id); - } - else { - tf->tpage= NULL; - } - - update = 1; + else { + /* old shading system, assign image to selected faces */ + + /* ensure we have a uv layer */ + if(!CustomData_has_layer(&em->fdata, CD_MTFACE)) { + EM_add_data_layer(em, &em->fdata, CD_MTFACE, NULL); + update= 1; } - } - /* and update depdency graph */ - if(update) - DAG_id_tag_update(obedit->data, 0); + /* now assign to all visible faces */ + for(efa= em->faces.first; efa; efa= efa->next) { + tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + if(uvedit_face_visible(scene, previma, efa, tf)) { + if(ima) { + tf->tpage= ima; + + if(ima->id.us==0) id_us_plus(&ima->id); + else id_lib_extern(&ima->id); + } + else + tf->tpage= NULL; + + update = 1; + } + } + + /* and update depdency graph */ + if(update) + DAG_id_tag_update(obedit->data, 0); + } BKE_mesh_end_editmesh(obedit->data, em); } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 29a9ae84cd5..11cd50a7d4e 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -51,6 +51,7 @@ #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_image.h" +#include "BKE_main.h" #include "BKE_mesh.h" #include "PIL_time.h" @@ -73,6 +74,7 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) { + Main *bmain= CTX_data_main(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); EditFace *efa; MTFace *tf; @@ -118,7 +120,7 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) } if(ima) - ED_uvedit_assign_image(scene, obedit, ima, NULL); + ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL); /* select new UV's */ for(efa=em->faces.first; efa; efa=efa->next) { diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 4c828264061..d08d7cf2ead 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -62,7 +62,7 @@ #include "BKE_material.h" #include "BKE_node.h" #include "BKE_object.h" - +#include "BKE_scene.h" #include "BLI_threads.h" #include "BLI_blenlib.h" @@ -952,15 +952,17 @@ static struct GPUMaterialState { } GMS = {NULL}; /* fixed function material, alpha handed by caller */ -static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob) +static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob, const int new_shading_nodes) { - if (bmat->mode & MA_SHLESS) { + if(new_shading_nodes || bmat->mode & MA_SHLESS) { copy_v3_v3(smat->diff, &bmat->r); smat->diff[3]= 1.0; - if(gamma) { + if(gamma) linearrgb_to_srgb_v3_v3(smat->diff, smat->diff); - } + + zero_v4(smat->spec); + smat->hard= 0; } else { mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit); @@ -1001,6 +1003,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GPUBlendMode alphablend; int a; int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; + int new_shading_nodes = scene_use_new_shading_nodes(scene); /* initialize state */ memset(&GMS, 0, sizeof(GMS)); @@ -1032,7 +1035,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O /* no materials assigned? */ if(ob->totcol==0) { - gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob); + gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes); /* do material 1 too, for displists! */ memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed)); @@ -1049,7 +1052,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O for(a=1; a<=ob->totcol; a++) { /* find a suitable material */ ma= give_current_material(ob, a); - if(!glsl) ma= gpu_active_node_material(ma); + if(!glsl && !new_shading_nodes) ma= gpu_active_node_material(ma); if(ma==NULL) ma= &defmaterial; /* create glsl material if requested */ @@ -1062,7 +1065,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O } else { /* fixed function opengl materials */ - gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob); + gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes); alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA; if(do_alpha_pass && GMS.alphapass) @@ -1223,6 +1226,7 @@ void GPU_end_object_materials(void) int GPU_default_lights(void) { + float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}, position[4]; int a, count = 0; /* initialize */ @@ -1248,27 +1252,28 @@ int GPU_default_lights(void) glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE); - glLightfv(GL_LIGHT0, GL_POSITION, U.light[0].vec); - glLightfv(GL_LIGHT0, GL_DIFFUSE, U.light[0].col); - glLightfv(GL_LIGHT0, GL_SPECULAR, U.light[0].spec); - - glLightfv(GL_LIGHT1, GL_POSITION, U.light[1].vec); - glLightfv(GL_LIGHT1, GL_DIFFUSE, U.light[1].col); - glLightfv(GL_LIGHT1, GL_SPECULAR, U.light[1].spec); - - glLightfv(GL_LIGHT2, GL_POSITION, U.light[2].vec); - glLightfv(GL_LIGHT2, GL_DIFFUSE, U.light[2].col); - glLightfv(GL_LIGHT2, GL_SPECULAR, U.light[2].spec); - for(a=0; a<8; a++) { if(a<3) { if(U.light[a].flag) { glEnable(GL_LIGHT0+a); + + normalize_v3_v3(position, U.light[a].vec); + position[3]= 0.0f; + + glLightfv(GL_LIGHT0+a, GL_POSITION, position); + glLightfv(GL_LIGHT0+a, GL_DIFFUSE, U.light[a].col); + glLightfv(GL_LIGHT0+a, GL_SPECULAR, U.light[a].spec); + count++; } - else + else { glDisable(GL_LIGHT0+a); - + + glLightfv(GL_LIGHT0+a, GL_POSITION, zero); + glLightfv(GL_LIGHT0+a, GL_DIFFUSE, zero); + glLightfv(GL_LIGHT0+a, GL_SPECULAR, zero); + } + // clear stuff from other opengl lamp usage glLightf(GL_LIGHT0+a, GL_SPOT_CUTOFF, 180.0); glLightf(GL_LIGHT0+a, GL_CONSTANT_ATTENUATION, 1.0); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9344b4e680a..02ba2eba9e9 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1415,29 +1415,33 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) if(((GPUMaterial*)link->data)->scene == scene) return link->data; + /* allocate material */ mat = GPU_material_construct_begin(ma); mat->scene = scene; if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) { + /* create nodes */ ntreeGPUMaterialNodes(ma->nodetree, mat); } else { + /* create material */ outlink = GPU_blender_material(mat, ma); GPU_material_output_link(mat, outlink); } - if(gpu_do_color_management(mat)) - if(mat->outlink) - GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); + if(!scene_use_new_shading_nodes(scene)) { + if(gpu_do_color_management(mat)) + if(mat->outlink) + GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); + } - /*if(!GPU_material_construct_end(mat)) { - GPU_material_free(mat); - mat= NULL; - return 0; - }*/ GPU_material_construct_end(mat); + /* note that even if building the shader fails in some way, we still keep + it to avoid trying to compile again and again, and simple do not use + the actual shader on drawing */ + link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); link->data = mat; BLI_addtail(&ma->gpumaterial, link); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 289c7ac2fc3..3e74243f858 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -145,6 +145,8 @@ typedef struct SpaceButs { void *path; /* runtime */ int pathflag, dataicon; /* runtime */ ID *pinid; + + void *texuser; } SpaceButs; typedef struct SpaceSeq { diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index bb07fa86f3a..d698e7c8fbf 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -102,7 +102,8 @@ EnumPropertyItem viewport_shade_items[] = { {OB_BOUNDBOX, "BOUNDBOX", ICON_BBOX, "Bounding Box", "Display the object's local bounding boxes only"}, {OB_WIRE, "WIREFRAME", ICON_WIRE, "Wireframe", "Display the object as wire edges"}, {OB_SOLID, "SOLID", ICON_SOLID, "Solid", "Display the object solid, lit with default OpenGL lights"}, - {OB_TEXTURE, "TEXTURED", ICON_POTATO, "Textured", "Display the object solid, with face-assigned textures"}, + {OB_TEXTURE, "TEXTURED", ICON_POTATO, "Texture", "Display the object solid, with a texture"}, + {OB_MATERIAL, "MATERIAL", ICON_MATERIAL_DATA, "Material", "Display objects solid, with GLSL material"}, {OB_RENDER, "RENDERED", ICON_SMOOTH, "Rendered", "Display render preview"}, {0, NULL, 0, NULL, NULL}}; @@ -114,13 +115,14 @@ EnumPropertyItem viewport_shade_items[] = { #include "BLI_math.h" -#include "BKE_screen.h" #include "BKE_animsys.h" #include "BKE_brush.h" #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_paint.h" +#include "BKE_scene.h" +#include "BKE_screen.h" #include "ED_image.h" #include "ED_node.h" @@ -461,10 +463,12 @@ static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *UNUSED(C RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_WIRE); RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_SOLID); RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_TEXTURE); + + if(scene_use_new_shading_nodes(scene)) + RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_MATERIAL); - if(type->view_draw) { + if(type->view_draw) RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_RENDER); - } RNA_enum_item_end(&item, &totitem); *free= 1; diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 9ff56f1aeb0..366ba1daf85 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -465,6 +465,9 @@ void RNA_api_ui_layout(StructRNA *srna) parm= RNA_def_pointer(func, "socket", "NodeSocket", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + func= RNA_def_function(srna, "template_texture_user", "uiTemplateTextureUser"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + func= RNA_def_function(srna, "template_keymap_item_properties", "uiTemplateKeymapItemProperties"); parm= RNA_def_pointer(func, "item", "KeyMapItem", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index ebcef97404d..dcfdb97f91a 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -242,6 +242,29 @@ static void data_from_gpu_stack_list(ListBase *sockets, bNodeStack **ns, GPUNode node_data_from_gpu_stack(ns[i], &gs[i]); } +bNode *nodeGetActiveTexture(bNodeTree *ntree) +{ + /* this is the node we texture paint and draw in textured draw */ + bNode *node; + + if(!ntree) + return NULL; + + /* check for group edit */ + for(node= ntree->nodes.first; node; node= node->next) + if(node->flag & NODE_GROUP_EDIT) + break; + + if(node) + ntree= (bNodeTree*)node->id; + + for(node= ntree->nodes.first; node; node= node->next) + if(node->flag & NODE_ACTIVE_TEXTURE) + return node; + + return NULL; +} + void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs) { bNodeExec *nodeexec; diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 2f297926fc7..bf31f82483e 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -374,6 +374,8 @@ void uiTemplateWaveform(struct uiLayout *layout, struct PointerRNA *ptr, char *p void uiTemplateVectorscope(struct uiLayout *_self, struct PointerRNA *data, char* property, int expand){} void uiTemplateNodeLink(struct uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input) {} void uiTemplateNodeView(struct uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input) {} +void uiTemplateTextureUser(struct uiLayout *layout, struct bContext *C) {} +void uiTemplateTextureShow(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop) {} void uiTemplateKeymapItemProperties(struct uiLayout *layout, struct PointerRNA *ptr){} void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact){} void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname){}