diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2014-07-21 14:02:05 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2014-07-21 14:02:05 +0400 |
commit | f745564e4ee791e4faf804b09ce975b882f4f8d9 (patch) | |
tree | 90ebbe363ccd925cedc652c9bb018ce552b5a2ab /source/blender/blenkernel | |
parent | 8489b94e07f9e73bd3c9c3e4f6a91f1f0a259827 (diff) |
GSOC 2013 paint
Yep, at last it's here!
There are a few minor issues remaining but development can go on in
master after discussion at blender institute.
For full list of features see:
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72/Painting
Thanks to Sergey and Campbell for the extensive review and to the
countless artists that have given their input and reported issues during
development.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_brush.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_library.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_main.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 24 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 32 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 56 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 54 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editderivedmesh.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/idcode.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 19 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 115 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 103 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 50 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/texture.c | 5 |
18 files changed, 465 insertions, 38 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 1ab5ec51de8..868d9768172 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -150,8 +150,10 @@ typedef DMDrawOption (*DMSetDrawOptions)(void *userData, int index); typedef DMDrawOption (*DMSetDrawOptionsTex)(struct MTFace *tface, const bool has_vcol, int matnr); typedef enum DMDrawFlag { - DM_DRAW_USE_COLORS = 1, - DM_DRAW_ALWAYS_SMOOTH = 2 + DM_DRAW_USE_COLORS = (1 << 0), + DM_DRAW_ALWAYS_SMOOTH = (1 << 1), + DM_DRAW_USE_ACTIVE_UV = (1 << 2), + DM_DRAW_USE_TEXPAINT_UV = (1 << 3), } DMDrawFlag; typedef enum DMForeachFlag { @@ -389,7 +391,7 @@ struct DerivedMesh { void (*drawFacesTex)(DerivedMesh *dm, DMSetDrawOptionsTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData); + void *userData, DMDrawFlag uvflag); /** Draw all faces with GLSL materials * o setMaterial is called for every different material nr @@ -423,7 +425,7 @@ struct DerivedMesh { void (*drawMappedFacesTex)(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData); + void *userData, DMDrawFlag uvflag); /** Draw mapped faces with GLSL materials * - setMaterial is called for every different material nr @@ -593,6 +595,8 @@ void DM_ensure_tessface(DerivedMesh *dm); void DM_update_tessface_data(DerivedMesh *dm); void DM_update_materials(DerivedMesh *dm, struct Object *ob); +struct MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr); + /** interpolates vertex data from the vertices indexed by src_indices in the * source mesh using the given weights and stores the result in the vertex * indexed by dest_index in the dest mesh diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 19fa60f5827..5a53b19b345 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 271 -#define BLENDER_SUBVERSION 2 +#define BLENDER_SUBVERSION 3 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 270 #define BLENDER_MINSUBVERSION 5 diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index 104e80e815c..d48753590bb 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -81,7 +81,11 @@ unsigned int *BKE_brush_gen_texture_cache(struct Brush *br, int half_side, bool /* radial control */ struct ImBuf *BKE_brush_gen_radial_control_imbuf(struct Brush *br, bool secondary); -/* unified strength and size */ +/* unified strength size and color */ + +float *BKE_brush_color_get(const struct Scene *scene, struct Brush *brush); +float *BKE_brush_secondary_color_get(const struct Scene *scene, struct Brush *brush); +void BKE_brush_color_set(struct Scene *scene, struct Brush *brush, const float color[3]); int BKE_brush_size_get(const struct Scene *scene, struct Brush *brush); void BKE_brush_size_set(struct Scene *scene, struct Brush *brush, int value); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 0372931dc49..0c7af12edc8 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -71,7 +71,7 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id); struct ListBase *which_libbase(struct Main *mainlib, short type); -#define MAX_LIBARRAY 41 +#define MAX_LIBARRAY 43 int set_listbasepointers(struct Main *main, struct ListBase **lb); void BKE_libblock_free(struct Main *bmain, void *idv); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 82b03127237..ec654ea4b71 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -87,6 +87,8 @@ typedef struct Main { ListBase nodetree; ListBase brush; ListBase particle; + ListBase palettes; + ListBase paintcurves; ListBase wm; ListBase gpencil; ListBase movieclip; diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 89d310753fc..e69299a36bf 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -86,6 +86,10 @@ short find_material_index(struct Object *ob, struct Material *ma); bool object_add_material_slot(struct Object *ob); bool object_remove_material_slot(struct Object *ob); +void BKE_texpaint_slot_refresh_cache(struct Material *ma, bool use_nodes); +void BKE_texpaint_slots_refresh_object(struct Object *ob, bool use_nodes); +void BKE_texpaint_slots_clear(struct Material *ma); + /* rna api */ void BKE_material_resize_id(struct ID *id, short totcol, bool do_id_user); void BKE_material_append_id(struct ID *id, struct Material *ma); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 43813300850..0bdac6822f1 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -40,11 +40,15 @@ struct CurveMapping; struct MDisps; struct MeshElemMap; struct GridPaintMask; +struct Main; struct MFace; struct MultireModifierData; struct MVert; struct Object; struct Paint; +struct PaintCurve; +struct Palette; +struct PaletteColor; struct PBVH; struct Scene; struct Sculpt; @@ -52,6 +56,7 @@ struct StrokeCache; struct Tex; struct ImagePool; struct UnifiedPaintSettings; +struct wmOperator; enum OverlayFlags; @@ -91,6 +96,19 @@ OverlayControlFlags BKE_paint_get_overlay_flags(void); void BKE_paint_reset_overlay_invalid(OverlayControlFlags flag); void BKE_paint_set_overlay_override(enum OverlayFlags flag); +/* palettes */ +void BKE_palette_free(struct Palette *palette); +struct Palette *BKE_palette_add(struct Main *bmain, const char *name); +struct PaletteColor *BKE_palette_color_add(struct Palette *palette); +void BKE_palette_color_delete(struct Palette *palette); +bool BKE_palette_is_empty(const struct Palette *palette); +void BKE_palette_color_remove(struct Palette *palette, struct PaletteColor *color); +void BKE_palette_cleanup(struct Palette *palette); + +/* paint curves */ +struct PaintCurve *BKE_paint_curve_add(struct Main *bmain, const char *name); +void BKE_paint_curve_free(struct PaintCurve *pc); + void BKE_paint_init(struct Paint *p, const char col[3]); void BKE_paint_free(struct Paint *p); void BKE_paint_copy(struct Paint *src, struct Paint *tar); @@ -100,6 +118,9 @@ struct Paint *BKE_paint_get_active_from_context(const struct bContext *C); PaintMode BKE_paintmode_get_active_from_context(const struct bContext *C); struct Brush *BKE_paint_brush(struct Paint *paint); void BKE_paint_brush_set(struct Paint *paint, struct Brush *br); +struct Palette *BKE_paint_palette(struct Paint *paint); +void BKE_paint_palette_set(struct Paint *p, struct Palette *palette); +void BKE_paint_curve_set(struct Brush *br, struct PaintCurve *pc); /* testing face select mode * Texture paint could be removed since selected faces are not used @@ -117,7 +138,10 @@ bool paint_is_bmesh_face_hidden(struct BMFace *f); /* paint masks */ float paint_grid_paint_mask(const struct GridPaintMask *gpm, unsigned level, unsigned x, unsigned y); + +/* stroke related */ void paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, const float mouse_pos[2]); + /* Session data (mode-specific) */ typedef struct SculptSession { diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d9af6ac3454..bdfaf9a1be9 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -37,6 +37,7 @@ #include "DNA_cloth_types.h" #include "DNA_key_types.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -501,11 +502,36 @@ void DM_update_materials(DerivedMesh *dm, Object *ob) dm->mat = MEM_callocN(totmat * sizeof(*dm->mat), "DerivedMesh.mat"); - for (i = 1; i < totmat; i++) { - dm->mat[i] = give_current_material(ob, i); + /* we leave last material as empty - rationale here is being able to index + * the materials by using the mf->mat_nr directly and leaving the last + * material as NULL in case no materials exist on mesh, so indexing will not fail */ + for (i = 0; i < totmat - 1; i++) { + dm->mat[i] = give_current_material(ob, i + 1); } } +MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr) +{ + MTFace *tf_base; + + BLI_assert(mat_nr < dm->totmat); + + if (dm->mat[mat_nr] && dm->mat[mat_nr]->texpaintslot && + dm->mat[mat_nr]->texpaintslot[dm->mat[mat_nr]->paint_active_slot].uvname[0]) + { + tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, + dm->mat[mat_nr]->texpaintslot[dm->mat[mat_nr]->paint_active_slot].uvname); + /* This can fail if we have changed the name in the UV layer list and have assigned the old name in the material + * texture slot.*/ + if (!tf_base) + tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE); + } + else { + tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE); + } + + return tf_base; +} void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) { @@ -3091,7 +3117,7 @@ static void navmesh_drawColored(DerivedMesh *dm) static void navmesh_DM_drawFacesTex(DerivedMesh *dm, DMSetDrawOptionsTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag UNUSED(flag)) { (void) setDrawOptions; (void) compareDrawOptions; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 967e89e0dd1..cfdb1aa7a96 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -83,6 +83,7 @@ static void brush_defaults(Brush *brush) brush->plane_trim = 0.5f; brush->clone.alpha = 0.5f; brush->normal_weight = 0.0f; + brush->fill_threshold = 0.2f; brush->flag |= BRUSH_ALPHA_PRESSURE; /* BRUSH PAINT TOOL SETTINGS */ @@ -90,6 +91,8 @@ static void brush_defaults(Brush *brush) brush->rgb[1] = 1.0f; brush->rgb[2] = 1.0f; + zero_v3(brush->secondary_rgb); + /* BRUSH STROKE SETTINGS */ brush->flag |= (BRUSH_SPACE | BRUSH_SPACE_ATTEN); brush->spacing = 10; /* how far each brush dot should be spaced as a percentage of brush diameter */ @@ -161,6 +164,9 @@ Brush *BKE_brush_copy(Brush *brush) if (brush->mask_mtex.tex) id_us_plus((ID *)brush->mask_mtex.tex); + if (brush->paint_curve) + id_us_plus((ID *)brush->paint_curve); + if (brush->icon_imbuf) brushn->icon_imbuf = IMB_dupImBuf(brush->icon_imbuf); @@ -180,11 +186,9 @@ Brush *BKE_brush_copy(Brush *brush) /* not brush itself */ void BKE_brush_free(Brush *brush) { - if (brush->mtex.tex) - brush->mtex.tex->id.us--; - - if (brush->mask_mtex.tex) - brush->mask_mtex.tex->id.us--; + id_us_min((ID *)brush->mtex.tex); + id_us_min((ID *)brush->mask_mtex.tex); + id_us_min((ID *)brush->paint_curve); if (brush->icon_imbuf) IMB_freeImBuf(brush->icon_imbuf); @@ -192,6 +196,9 @@ void BKE_brush_free(Brush *brush) BKE_previewimg_free(&(brush->preview)); curvemapping_free(brush->curve); + + if (brush->gradient) + MEM_freeN(brush->gradient); } static void extern_local_brush(Brush *brush) @@ -199,6 +206,7 @@ static void extern_local_brush(Brush *brush) id_lib_extern((ID *)brush->mtex.tex); id_lib_extern((ID *)brush->mask_mtex.tex); id_lib_extern((ID *)brush->clone.image); + id_lib_extern((ID *)brush->paint_curve); } void BKE_brush_make_local(Brush *brush) @@ -742,10 +750,23 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br, rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); } + CLAMP(intensity, 0.0f, 1.0f); + + switch (br->mask_pressure) { + case BRUSH_MASK_PRESSURE_CUTOFF: + intensity = ((1.0f - intensity) < ups->size_pressure_value) ? 1.0f : 0.0f; + break; + case BRUSH_MASK_PRESSURE_RAMP: + intensity = ups->size_pressure_value + intensity * (1.0f - ups->size_pressure_value); + break; + default: + break; + } + return intensity; } -/* Unified Size and Strength */ +/* Unified Size / Strength / Color */ /* XXX: be careful about setting size and unprojected radius * because they depend on one another @@ -760,6 +781,29 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br, * In any case, a better solution is needed to prevent * inconsistency. */ + +float *BKE_brush_color_get(const struct Scene *scene, struct Brush *brush) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + return (ups->flag & UNIFIED_PAINT_COLOR) ? ups->rgb : brush->rgb; +} + +float *BKE_brush_secondary_color_get(const struct Scene *scene, struct Brush *brush) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + return (ups->flag & UNIFIED_PAINT_COLOR) ? ups->secondary_rgb : brush->secondary_rgb; +} + +void BKE_brush_color_set(struct Scene *scene, struct Brush *brush, const float color[3]) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + + if (ups->flag & UNIFIED_PAINT_COLOR) + copy_v3_v3(ups->rgb, color); + else + copy_v3_v3(brush->rgb, color); +} + void BKE_brush_size_set(Scene *scene, Brush *brush, int size) { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 3f8edbcf1be..ca4a4b3196c 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -51,6 +51,7 @@ #include "BKE_editmesh.h" #include "BKE_curve.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -669,7 +670,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, DMSetDrawOptionsTex drawParams, DMSetDrawOptions drawParamsMapped, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag uvflag) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MVert *mv = cddm->mvert; @@ -680,6 +681,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, MCol *mcol; int i, orig; int colType, startFace = 0; + bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0; /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); @@ -718,14 +720,35 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, cdDM_update_normals_from_pbvh(dm); if (GPU_buffer_legacy(dm)) { + int mat_nr_cache = -1; + MTFace *tf_base = DM_get_tessface_data_layer(dm, CD_MTFACE); + MTFace *tf_stencil_base = NULL; + MTFace *tf_stencil = NULL; + + if (uvflag & DM_DRAW_USE_TEXPAINT_UV) { + int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE); + tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil); + } + DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n"); for (i = 0; i < dm->numTessFaceData; i++, mf++) { MVert *mvert; DMDrawOption draw_option; unsigned char *cp = NULL; + if (uvflag & DM_DRAW_USE_TEXPAINT_UV) { + if (mf->mat_nr != mat_nr_cache) { + tf_base = DM_paint_uvlayer_active_get(dm, mf->mat_nr); + + mat_nr_cache = mf->mat_nr; + } + } + + tf = tf_base ? tf_base + i : NULL; + tf_stencil = tf_stencil_base ? tf_stencil_base + i : NULL; + if (drawParams) { - draw_option = drawParams(tf ? &tf[i] : NULL, (mcol != NULL), mf->mat_nr); + draw_option = drawParams(use_tface ? tf : NULL, (mcol != NULL), mf->mat_nr); } else { if (index_mf_to_mpoly) { @@ -778,21 +801,24 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, } glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); - if (tf) glTexCoord2fv(tf[i].uv[0]); + if (tf) glTexCoord2fv(tf->uv[0]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); mvert = &mv[mf->v1]; if (lnors) glNormal3sv((const GLshort *)lnors[0][0]); else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); - if (tf) glTexCoord2fv(tf[i].uv[1]); + if (tf) glTexCoord2fv(tf->uv[1]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); mvert = &mv[mf->v2]; if (lnors) glNormal3sv((const GLshort *)lnors[0][1]); else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); glVertex3fv(mvert->co); - if (tf) glTexCoord2fv(tf[i].uv[2]); + if (tf) glTexCoord2fv(tf->uv[2]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); mvert = &mv[mf->v3]; if (lnors) glNormal3sv((const GLshort *)lnors[0][2]); @@ -800,7 +826,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, glVertex3fv(mvert->co); if (mf->v4) { - if (tf) glTexCoord2fv(tf[i].uv[3]); + if (tf) glTexCoord2fv(tf->uv[3]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); mvert = &mv[mf->v4]; if (lnors) glNormal3sv((const GLshort *)lnors[0][3]); @@ -819,7 +846,10 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ GPU_vertex_setup(dm); GPU_normal_setup(dm); - GPU_uv_setup(dm); + if (uvflag & DM_DRAW_USE_TEXPAINT_UV) + GPU_texpaint_uv_setup(dm); + else + GPU_uv_setup(dm); if (mcol) { GPU_color_setup(dm, colType); } @@ -839,7 +869,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; if (drawParams) { - draw_option = drawParams(tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr); + draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr); } else { if (index_mf_to_mpoly) { @@ -895,9 +925,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, static void cdDM_drawFacesTex(DerivedMesh *dm, DMSetDrawOptionsTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag uvflag) { - cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData); + cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, uvflag); } static void cdDM_drawMappedFaces(DerivedMesh *dm, @@ -1123,9 +1153,9 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, static void cdDM_drawMappedFacesTex(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag flag) { - cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData); + cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag); } static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 136ca0098cb..4fa4031382b 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2472,6 +2472,17 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id) BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); } + if (ELEM(idtype, ID_MA, ID_TE)) { + const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(sce); + for (obt = bmain->object.first; obt; obt = obt->id.next) { + if (obt->mode & OB_MODE_TEXTURE_PAINT) { + obt->recalc |= OB_RECALC_DATA; + BKE_texpaint_slots_refresh_object(obt, new_shading_nodes); + lib_id_recalc_data_tag(bmain, &obt->id); + } + } + } + if (idtype == ID_MC) { MovieClip *clip = (MovieClip *) id; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 3a11b3431ae..40a4bc22ce9 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -911,7 +911,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, static void emDM_drawFacesTex(DerivedMesh *dm, DMSetDrawOptionsTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag UNUSED(flag)) { emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData); } @@ -919,7 +919,7 @@ static void emDM_drawFacesTex(DerivedMesh *dm, static void emDM_drawMappedFacesTex(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag UNUSED(flag)) { emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData); } diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index 2e201a0b8e8..1b7a03ec80e 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -73,6 +73,8 @@ static IDType idtypes[] = { { ID_NT, "NodeTree", "node_groups", IDTYPE_FLAGS_ISLINKABLE }, { ID_OB, "Object", "objects", IDTYPE_FLAGS_ISLINKABLE }, { ID_PA, "ParticleSettings", "particles", 0 }, + { ID_PAL, "Palettes", "palettes", IDTYPE_FLAGS_ISLINKABLE }, + { ID_PC, "PaintCurve", "paint_curves", IDTYPE_FLAGS_ISLINKABLE }, { ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE }, { ID_SCR, "Screen", "screens", 0 }, { ID_SEQ, "Sequence", "sequences", 0 }, /* not actually ID data */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index df343459d2f..8e07564dec4 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -104,6 +104,7 @@ #include "BKE_mask.h" #include "BKE_node.h" #include "BKE_object.h" +#include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_packedFile.h" #include "BKE_speaker.h" @@ -515,6 +516,10 @@ ListBase *which_libbase(Main *mainlib, short type) return &(mainlib->mask); case ID_LS: return &(mainlib->linestyle); + case ID_PAL: + return &(mainlib->palettes); + case ID_PC: + return &(mainlib->paintcurves); } return NULL; } @@ -596,6 +601,8 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[a++] = &(main->text); lb[a++] = &(main->sound); lb[a++] = &(main->group); + lb[a++] = &(main->palettes); + lb[a++] = &(main->paintcurves); lb[a++] = &(main->brush); lb[a++] = &(main->script); lb[a++] = &(main->particle); @@ -731,6 +738,12 @@ static ID *alloc_libblock_notest(short type) case ID_LS: id = MEM_callocN(sizeof(FreestyleLineStyle), "Freestyle Line Style"); break; + case ID_PAL: + id = MEM_callocN(sizeof(Palette), "Palette"); + break; + case ID_PC: + id = MEM_callocN(sizeof(PaintCurve), "Paint Curve"); + break; } return id; } @@ -1007,6 +1020,12 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user) case ID_LS: BKE_linestyle_free((FreestyleLineStyle *)id); break; + case ID_PAL: + BKE_palette_free((Palette *)id); + break; + case ID_PC: + BKE_paint_curve_free((PaintCurve *)id); + break; } /* avoid notifying on removed data */ diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index b8788a2bffb..b3e0f16f604 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -111,6 +111,9 @@ void BKE_material_free_ex(Material *ma, bool do_id_user) MEM_freeN(ma->nodetree); } + if (ma->texpaintslot) + MEM_freeN(ma->texpaintslot); + if (ma->gpumaterial.first) GPU_material_free(ma); } @@ -269,7 +272,9 @@ Material *localize_material(Material *ma) if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col); if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec); - + + if (ma->texpaintslot) man->texpaintslot = MEM_dupallocN(man->texpaintslot); + man->preview = NULL; if (ma->nodetree) @@ -1301,6 +1306,114 @@ bool object_remove_material_slot(Object *ob) return true; } +void BKE_texpaint_slots_clear(struct Material *ma) +{ + + if (ma->texpaintslot) { + MEM_freeN(ma->texpaintslot); + ma->texpaintslot = NULL; + } + ma->tot_slots = 0; + ma->paint_active_slot = 0; + ma->paint_clone_slot = 0; +} + + +static bool get_mtex_slot_valid_texpaint(struct MTex *mtex) +{ + return (mtex && (mtex->texco == TEXCO_UV) && + mtex->tex && (mtex->tex->type == TEX_IMAGE) && + mtex->tex->ima); +} + +void BKE_texpaint_slot_refresh_cache(Material *ma, bool use_nodes) +{ + MTex **mtex; + short count = 0; + short index = 0, i; + + if (!ma) + return; + + if (ma->texpaintslot) { + MEM_freeN(ma->texpaintslot); + ma->texpaintslot = NULL; + } + + if (use_nodes) { + bNode *node, *active_node; + + if (!(ma->use_nodes && ma->nodetree)) + return; + + for (node = ma->nodetree->nodes.first; node; node = node->next) { + if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) + count++; + } + + ma->tot_slots = count; + + if (count == 0) { + ma->paint_active_slot = 0; + return; + } + ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots"); + + active_node = nodeGetActiveTexture(ma->nodetree); + + for (node = ma->nodetree->nodes.first; node; node = node->next) { + if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) { + if (active_node == node) + ma->paint_active_slot = index; + ma->texpaintslot[index++].ima = (Image *)node->id; + } + } + } + else { + for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) { + if (get_mtex_slot_valid_texpaint(*mtex)) { + count++; + } + } + + ma->tot_slots = count; + + if (count == 0) { + ma->paint_active_slot = 0; + return; + } + + ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots"); + + for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) { + if (get_mtex_slot_valid_texpaint(*mtex)) { + ma->texpaintslot[index].ima = (*mtex)->tex->ima; + BLI_strncpy(ma->texpaintslot[index++].uvname, (*mtex)->uvname, 64); + } + } + } + + if (ma->paint_active_slot >= count) { + ma->paint_active_slot = count - 1; + } + + if (ma->paint_clone_slot >= count) { + ma->paint_clone_slot = count - 1; + } + + return; +} + +void BKE_texpaint_slots_refresh_object(struct Object *ob, bool use_nodes) +{ + int i; + + for (i = 1; i < ob->totcol + 1; i++) { + Material *ma = give_current_material(ob, i); + BKE_texpaint_slot_refresh_cache(ma, use_nodes); + } +} + /* r_col = current value, col = new value, (fac == 0) is no change */ void ramp_blend(int type, float r_col[3], const float fac, const float col[3]) diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 9a144b5461a..48211f2f627 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -45,8 +45,10 @@ #include "BLI_bitmap.h" #include "BLI_utildefines.h" #include "BLI_math_vector.h" +#include "BLI_listbase.h" #include "BKE_brush.h" +#include "BKE_main.h" #include "BKE_context.h" #include "BKE_crazyspace.h" #include "BKE_depsgraph.h" @@ -269,6 +271,105 @@ void BKE_paint_brush_set(Paint *p, Brush *br) } } +void BKE_paint_curve_free(PaintCurve *pc) +{ + if (pc->points) { + MEM_freeN(pc->points); + pc->points = NULL; + pc->tot_points = 0; + } +} + +PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name) +{ + PaintCurve *pc; + + pc = BKE_libblock_alloc(bmain, ID_PC, name); + + return pc; +} + +Palette *BKE_paint_palette(Paint *p) +{ + return p ? p->palette : NULL; +} + +void BKE_paint_palette_set(Paint *p, Palette *palette) +{ + if (p) { + id_us_min((ID *)p->palette); + id_us_plus((ID *)palette); + p->palette = palette; + } +} + +void BKE_paint_curve_set(Brush *br, PaintCurve *pc) +{ + if (br) { + id_us_min((ID *)br->paint_curve); + id_us_plus((ID *)pc); + br->paint_curve = pc; + } +} + +/* remove colour from palette. Must be certain color is inside the palette! */ +void BKE_palette_color_remove(Palette *palette, PaletteColor *color) +{ + BLI_remlink(&palette->colors, color); + BLI_addhead(&palette->deleted, color); +} + +void BKE_palette_cleanup(Palette *palette) +{ + BLI_freelistN(&palette->deleted); +} + + +Palette *BKE_palette_add(Main *bmain, const char *name) +{ + Palette *palette; + + palette = BKE_libblock_alloc(bmain, ID_PAL, name); + + /* enable fake user by default */ + palette->id.flag |= LIB_FAKEUSER; + + return palette; +} + +void BKE_palette_free(Palette *palette) +{ + BLI_freelistN(&palette->colors); +} + +PaletteColor *BKE_palette_color_add(Palette *palette) +{ + PaletteColor *color = MEM_callocN(sizeof(*color), "Pallete Color"); + BLI_addtail(&palette->colors, color); + palette->active_color = BLI_countlist(&palette->colors) - 1; + return color; +} + +void BKE_palette_color_delete(struct Palette *palette) +{ + PaletteColor *color = BLI_findlink(&palette->colors, palette->active_color); + + if(color) { + if ((color == palette->colors.last) && (palette->colors.last != palette->colors.first)) + palette->active_color--; + + BLI_remlink(&palette->colors, color); + BLI_addhead(&palette->deleted, color); + } +} + + +bool BKE_palette_is_empty(const struct Palette *palette) +{ + return BLI_listbase_is_empty(&palette->colors); +} + + /* are we in vertex paint or weight pain face select mode? */ bool BKE_paint_select_face_test(Object *ob) { @@ -318,6 +419,7 @@ void BKE_paint_init(Paint *p, const char col[3]) void BKE_paint_free(Paint *paint) { id_us_min((ID *)paint->brush); + id_us_min((ID *)paint->palette); } /* called when copying scene settings, so even if 'src' and 'tar' are the same @@ -328,6 +430,7 @@ void BKE_paint_copy(Paint *src, Paint *tar) { tar->brush = src->brush; id_us_plus((ID *)tar->brush); + id_us_plus((ID *)tar->palette); } /* returns non-zero if any of the face's vertices diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 11dc9150d8f..79c348ac181 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -41,6 +41,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" @@ -2291,18 +2292,23 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, DMSetDrawOptionsTex drawParams, DMSetDrawOptions drawParamsMapped, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag flag) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; CCGKey key; MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); + MTFace *tf_stencil_base = NULL; + MTFace *tf_stencil = NULL; + MTFace *tf_base; short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); DMFlagMat *faceFlags = ccgdm->faceFlags; DMDrawOption draw_option; int i, totface, gridSize = ccgSubSurf_getGridSize(ss); int gridFaces = gridSize - 1; + int gridOffset = 0; + int mat_nr_cache = -1; (void) compareDrawOptions; @@ -2316,6 +2322,12 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, mcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL); totface = ccgSubSurf_getNumFaces(ss); + + if (flag & DM_DRAW_USE_TEXPAINT_UV) { + int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE); + tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil); + } + for (i = 0; i < totface; i++) { CCGFace *f = ccgdm->faceMap[i].face; int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); @@ -2334,6 +2346,18 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, mat_nr = 0; } + /* texture painting, handle the correct uv layer here */ + if (flag & DM_DRAW_USE_TEXPAINT_UV) { + if (mat_nr != mat_nr_cache) { + tf_base = DM_paint_uvlayer_active_get(dm, mat_nr); + + mat_nr_cache = mat_nr; + } + tf = tf_base + gridOffset; + tf_stencil = tf_stencil_base + gridOffset; + gridOffset += gridFaces * gridFaces * numVerts; + } + if (drawParams) draw_option = drawParams(tf, (mcol != NULL), mat_nr); else if (index != ORIGINDEX_NONE) @@ -2374,26 +2398,31 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1); if (tf) glTexCoord2fv(tf->uv[1]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); glNormal3sv(ln[0][1]); glVertex3fv(d_co); if (tf) glTexCoord2fv(tf->uv[2]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); glNormal3sv(ln[0][2]); glVertex3fv(c_co); if (tf) glTexCoord2fv(tf->uv[3]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); glNormal3sv(ln[0][3]); glVertex3fv(b_co); if (tf) glTexCoord2fv(tf->uv[0]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); glNormal3sv(ln[0][0]); glVertex3fv(a_co); if (tf) tf++; + if (tf_stencil) tf_stencil++; if (cp) cp += 16; ln++; } @@ -2409,17 +2438,20 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, b = CCG_grid_elem(&key, faceGridData, x, y + 1); if (tf) glTexCoord2fv(tf->uv[0]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); glNormal3fv(CCG_elem_no(&key, a)); glVertex3fv(CCG_elem_co(&key, a)); if (tf) glTexCoord2fv(tf->uv[1]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); glNormal3fv(CCG_elem_no(&key, b)); glVertex3fv(CCG_elem_co(&key, b)); if (x != gridFaces - 1) { if (tf) tf++; + if (tf_stencil) tf_stencil++; if (cp) cp += 16; } } @@ -2428,16 +2460,19 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, b = CCG_grid_elem(&key, faceGridData, x, y + 1); if (tf) glTexCoord2fv(tf->uv[3]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); glNormal3fv(CCG_elem_no(&key, a)); glVertex3fv(CCG_elem_co(&key, a)); if (tf) glTexCoord2fv(tf->uv[2]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); glNormal3fv(CCG_elem_no(&key, b)); glVertex3fv(CCG_elem_co(&key, b)); if (tf) tf++; + if (tf_stencil) tf_stencil++; if (cp) cp += 16; glEnd(); @@ -2456,22 +2491,27 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, ccgDM_glNormalFast(a_co, b_co, c_co, d_co); if (tf) glTexCoord2fv(tf->uv[1]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]); if (cp) glColor3ub(cp[7], cp[6], cp[5]); glVertex3fv(d_co); if (tf) glTexCoord2fv(tf->uv[2]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]); if (cp) glColor3ub(cp[11], cp[10], cp[9]); glVertex3fv(c_co); if (tf) glTexCoord2fv(tf->uv[3]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]); if (cp) glColor3ub(cp[15], cp[14], cp[13]); glVertex3fv(b_co); if (tf) glTexCoord2fv(tf->uv[0]); + if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]); if (cp) glColor3ub(cp[3], cp[2], cp[1]); glVertex3fv(a_co); if (tf) tf++; + if (tf_stencil) tf_stencil++; if (cp) cp += 16; } } @@ -2484,17 +2524,17 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, static void ccgDM_drawFacesTex(DerivedMesh *dm, DMSetDrawOptionsTex setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag flag) { - ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData); + ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag); } static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, DMCompareDrawOptions compareDrawOptions, - void *userData) + void *userData, DMDrawFlag flag) { - ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData); + ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag); } static void ccgDM_drawUVEdges(DerivedMesh *dm) diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 105065e85cf..77f62771360 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -474,7 +474,8 @@ void BKE_texture_free(Tex *tex) void default_tex(Tex *tex) { - tex->type = TEX_CLOUDS; + tex->type = TEX_IMAGE; + tex->ima = NULL; tex->stype = 0; tex->flag = TEX_CHECKER_ODD; tex->imaflag = TEX_INTERPOL | TEX_MIPMAP | TEX_USEALPHA; @@ -592,7 +593,7 @@ Tex *add_texture(Main *bmain, const char *name) void default_mtex(MTex *mtex) { - mtex->texco = TEXCO_ORCO; + mtex->texco = TEXCO_UV; mtex->mapto = MAP_COL; mtex->object = NULL; mtex->projx = PROJ_X; |