Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorLuca Rood <dev@lucarood.com>2017-05-03 19:55:40 +0300
committerLuca Rood <dev@lucarood.com>2017-05-03 19:57:35 +0300
commit20f95de6ba2d32dcff553251ff4de2efd5b76955 (patch)
tree3249c645c766757e18f6231afe4e90ad76b996bb /source
parentb9451c04931d228161c1fb212c6c7a09545a86b7 (diff)
Weight painting with draw manager
This implements weight rendering with the draw manager, with all drawing options (Shading, wire, face masking, vertex masking). This is part of T51208 Reviewers: campbellbarton Subscribers: dfelinto Differential Revision: https://developer.blender.org/D2654
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_mesh.h1
-rw-r--r--source/blender/blenkernel/intern/deform.c3
-rw-r--r--source/blender/blenkernel/intern/layer.c20
-rw-r--r--source/blender/blenkernel/intern/object_deform.c3
-rw-r--r--source/blender/draw/DRW_engine.h1
-rw-r--r--source/blender/draw/intern/draw_cache.c32
-rw-r--r--source/blender/draw/intern/draw_cache.h5
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h4
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c598
-rw-r--r--source/blender/draw/modes/object_mode.c2
-rw-r--r--source/blender/draw/modes/paint_weight_mode.c244
-rw-r--r--source/blender/editors/mesh/editface.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c2
-rw-r--r--source/blender/gpu/CMakeLists.txt1
-rw-r--r--source/blender/gpu/GPU_shader.h1
-rw-r--r--source/blender/gpu/intern/gpu_shader.c2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl14
-rw-r--r--source/blender/makesdna/DNA_ID.h11
-rw-r--r--source/blender/makesdna/DNA_layer_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c15
-rw-r--r--source/blender/makesrna/intern/rna_scene.c48
22 files changed, 865 insertions, 150 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index a24ce490262..db6f40756a4 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -411,6 +411,7 @@ void BKE_mesh_eval_geometry(struct EvaluationContext *eval_ctx,
enum {
BKE_MESH_BATCH_DIRTY_ALL = 0,
BKE_MESH_BATCH_DIRTY_SELECT,
+ BKE_MESH_BATCH_DIRTY_WEIGHT,
};
void BKE_mesh_batch_cache_dirty(struct Mesh *me, int mode);
void BKE_mesh_batch_cache_free(struct Mesh *me);
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 13b1aab5e1c..22ba050e4fb 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -54,6 +54,7 @@
#include "BKE_customdata.h"
#include "BKE_data_transfer.h"
#include "BKE_deform.h" /* own include */
+#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_object_deform.h"
@@ -73,6 +74,8 @@ bDeformGroup *BKE_defgroup_new(Object *ob, const char *name)
BLI_addtail(&ob->defbase, defgroup);
defgroup_unique_name(defgroup, ob);
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_WEIGHT);
+
return defgroup;
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index d9398ae83c7..1a920a155b8 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1088,6 +1088,22 @@ static void layer_collection_create_mode_settings_edit(IDProperty *root, const b
IDP_AddToGroup(root, props);
}
+static void layer_collection_create_mode_settings_paint_weight(IDProperty *root, const bool populate)
+{
+ IDProperty *props;
+ IDPropertyTemplate val = {0};
+
+ props = IDP_New(IDP_GROUP, &val, "WeightPaintMode");
+ props->subtype = IDP_GROUP_SUB_MODE_PAINT_WEIGHT;
+
+ /* properties */
+ if (populate) {
+ PAINT_WEIGHT_collection_settings_create(props);
+ }
+
+ IDP_AddToGroup(root, props);
+}
+
static void collection_create_render_settings(IDProperty *root, const bool populate)
{
CollectionEngineSettingsCB_Type *ces_type;
@@ -1103,6 +1119,7 @@ static void collection_create_mode_settings(IDProperty *root, const bool populat
* and have IDP_AddToGroup outside the callbacks */
layer_collection_create_mode_settings_object(root, populate);
layer_collection_create_mode_settings_edit(root, populate);
+ layer_collection_create_mode_settings_paint_weight(root, populate);
}
static int idproperty_group_subtype(const int mode_type)
@@ -1116,6 +1133,9 @@ static int idproperty_group_subtype(const int mode_type)
case COLLECTION_MODE_EDIT:
idgroup_type = IDP_GROUP_SUB_MODE_EDIT;
break;
+ case COLLECTION_MODE_PAINT_WEIGHT:
+ idgroup_type = IDP_GROUP_SUB_MODE_PAINT_WEIGHT;
+ break;
default:
case COLLECTION_MODE_NONE:
return IDP_GROUP_SUB_ENGINE_RENDER;
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index ccf2aec5c7a..990c96c9576 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -51,6 +51,7 @@
#include "BKE_editmesh.h"
#include "BKE_object_deform.h" /* own include */
#include "BKE_object.h"
+#include "BKE_mesh.h"
#include "BKE_modifier.h"
/** \name Misc helpers
@@ -405,6 +406,8 @@ void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
object_defgroup_remove_edit_mode(ob, defgroup);
else
object_defgroup_remove_object_mode(ob, defgroup);
+
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_WEIGHT);
}
/**
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 125a9d8d992..239919fd826 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -89,5 +89,6 @@ void DRW_pass_free(struct DRWPass *pass);
void OBJECT_collection_settings_create(struct IDProperty *properties);
void EDIT_MESH_collection_settings_create(struct IDProperty *properties);
void EDIT_ARMATURE_collection_settings_create(struct IDProperty *properties);
+void PAINT_WEIGHT_collection_settings_create(struct IDProperty *properties);
#endif /* __DRW_ENGINE_H__ */
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 79ca4209894..9fa79c41265 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -1769,6 +1769,14 @@ Batch *DRW_cache_mesh_surface_get(Object *ob)
return DRW_mesh_batch_cache_get_triangles_with_normals(me);
}
+Batch *DRW_cache_mesh_surface_weights_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(me, ob->actdef - 1);
+}
+
/* Return list of batches */
Batch **DRW_cache_mesh_surface_shaded_get(Object *ob)
{
@@ -1802,6 +1810,30 @@ Batch *DRW_cache_mesh_verts_get(Object *ob)
return DRW_mesh_batch_cache_get_all_verts(me);
}
+Batch *DRW_cache_mesh_edges_weight_overlay_get(Object *ob, bool use_wire, bool use_sel)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_weight_overlay_edges(me, use_wire, use_sel);
+}
+
+Batch *DRW_cache_mesh_faces_weight_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_weight_overlay_faces(me);
+}
+
+Batch *DRW_cache_mesh_verts_weight_overlay_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
+ return DRW_mesh_batch_cache_get_weight_overlay_verts(me);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 586ed98fed0..a725eb2c37a 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -94,12 +94,15 @@ void DRW_cache_mesh_wire_overlay_get(
struct Batch *DRW_cache_face_centers_get(struct Object *ob);
struct Batch *DRW_cache_mesh_wire_outline_get(struct Object *ob);
struct Batch *DRW_cache_mesh_surface_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_surface_weights_get(struct Object *ob);
struct Batch *DRW_cache_mesh_surface_verts_get(struct Object *ob);
struct Batch *DRW_cache_mesh_edges_get(struct Object *ob);
struct Batch *DRW_cache_mesh_verts_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_edges_weight_overlay_get(struct Object *ob, bool use_wire, bool use_sel);
+struct Batch *DRW_cache_mesh_faces_weight_overlay_get(struct Object *ob);
+struct Batch *DRW_cache_mesh_verts_weight_overlay_get(struct Object *ob);
struct Batch **DRW_cache_mesh_surface_shaded_get(struct Object *ob);
-
/* Curve */
struct Batch *DRW_cache_curve_surface_get(struct Object *ob);
struct Batch *DRW_cache_curve_surface_verts_get(struct Object *ob);
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index c988a5703dc..d9bc448967c 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -68,9 +68,13 @@ struct Batch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt);
/* Mesh */
struct Batch **DRW_mesh_batch_cache_get_surface_shaded(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel);
+struct Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me);
struct Batch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me);
struct Batch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me);
struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
+struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int index);
struct Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me);
struct Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me);
struct Batch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index fbddcd60d46..5a5d0260699 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -37,11 +37,14 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
#include "BKE_customdata.h"
+#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
+#include "BKE_texture.h"
#include "bmesh.h"
@@ -120,6 +123,7 @@ typedef struct MeshRenderData {
MLoopUV **mloopuv;
MCol **mcol;
float (**mtangent)[4];
+ MDeformVert *dvert;
BMVert *eve_act;
BMEdge *eed_act;
@@ -152,8 +156,10 @@ typedef struct MeshRenderData {
int *loose_verts;
float (*poly_normals)[3];
+ float (*vert_color)[3];
short (*poly_normals_short)[3];
short (*vert_normals_short)[3];
+ bool *edge_selection;
} MeshRenderData;
enum {
@@ -164,6 +170,7 @@ enum {
MR_DATATYPE_POLY = 1 << 4,
MR_DATATYPE_OVERLAY = 1 << 5,
MR_DATATYPE_SHADING = 1 << 6,
+ MR_DATATYPE_DVERT = 1 << 7,
};
/**
@@ -236,6 +243,10 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
rdata->crease_ofs = CustomData_get_offset(&bm->edata, CD_CREASE);
rdata->bweight_ofs = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
}
+ if (types & (MR_DATATYPE_DVERT)) {
+ bm_ensure_types |= BM_VERT;
+ }
+
BM_mesh_elem_index_ensure(bm, bm_ensure_types);
BM_mesh_elem_table_ensure(bm, bm_ensure_types & ~BM_LOOP);
if (types & MR_DATATYPE_OVERLAY) {
@@ -298,6 +309,10 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
rdata->poly_len = me->totpoly;
rdata->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
}
+ if (types & MR_DATATYPE_DVERT) {
+ rdata->vert_len = me->totvert;
+ rdata->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
+ }
}
if (types & MR_DATATYPE_SHADING) {
@@ -450,6 +465,8 @@ static void mesh_render_data_free(MeshRenderData *rdata)
MEM_SAFE_FREE(rdata->uv_names);
MEM_SAFE_FREE(rdata->vcol_names);
MEM_SAFE_FREE(rdata->tangent_names);
+ MEM_SAFE_FREE(rdata->vert_color);
+ MEM_SAFE_FREE(rdata->edge_selection);
MEM_freeN(rdata);
}
@@ -958,6 +975,301 @@ static bool mesh_render_data_looptri_cos_nors_smooth_get(
return true;
}
+static void rgb_from_weight(float r_rgb[3], const float weight)
+{
+ const float blend = ((weight / 2.0f) + 0.5f);
+
+ if (weight <= 0.25f) { /* blue->cyan */
+ r_rgb[0] = 0.0f;
+ r_rgb[1] = blend * weight * 4.0f;
+ r_rgb[2] = blend;
+ }
+ else if (weight <= 0.50f) { /* cyan->green */
+ r_rgb[0] = 0.0f;
+ r_rgb[1] = blend;
+ r_rgb[2] = blend * (1.0f - ((weight - 0.25f) * 4.0f));
+ }
+ else if (weight <= 0.75f) { /* green->yellow */
+ r_rgb[0] = blend * ((weight - 0.50f) * 4.0f);
+ r_rgb[1] = blend;
+ r_rgb[2] = 0.0f;
+ }
+ else if (weight <= 1.0f) { /* yellow->red */
+ r_rgb[0] = blend;
+ r_rgb[1] = blend * (1.0f - ((weight - 0.75f) * 4.0f));
+ r_rgb[2] = 0.0f;
+ }
+ else {
+ /* exceptional value, unclamped or nan,
+ * avoid uninitialized memory use */
+ r_rgb[0] = 1.0f;
+ r_rgb[1] = 0.0f;
+ r_rgb[2] = 1.0f;
+ }
+}
+
+static bool mesh_render_data_looptri_cos_weights_get(
+ MeshRenderData *rdata, const int tri_idx,
+ float *(*r_vert_cos)[3], float *(*r_vert_weights)[3],
+ short **r_tri_nor, short *(*r_vert_nors)[3], bool *r_is_smooth, int index)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_DVERT | MR_DATATYPE_POLY));
+
+ if (rdata->edit_bmesh) {
+ const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx];
+
+ if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
+ return false;
+ }
+
+ float (*vweight)[3] = rdata->vert_color;
+ short (*pnors_short)[3] = rdata->poly_normals_short;
+ short (*vnors_short)[3] = rdata->vert_normals_short;
+
+ if (!pnors_short) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter fiter;
+ BMFace *face;
+ int i;
+
+ pnors_short = rdata->poly_normals_short = MEM_mallocN(sizeof(*pnors_short) * rdata->poly_len, __func__);
+ BM_ITER_MESH_INDEX(face, &fiter, bm, BM_FACES_OF_MESH, i) {
+ normal_float_to_short_v3(pnors_short[i], face->no);
+ }
+ }
+ if (!vnors_short) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter viter;
+ BMVert *vert;
+ int i;
+
+ vnors_short = rdata->vert_normals_short = MEM_mallocN(sizeof(*vnors_short) * rdata->vert_len, __func__);
+ BM_ITER_MESH_INDEX(vert, &viter, bm, BM_VERT, i) {
+ normal_float_to_short_v3(vnors_short[i], vert->no);
+ }
+ }
+
+ if (!vweight) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+
+ if (CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
+ BMIter viter;
+ BMVert *vert;
+ int i;
+
+ const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
+ BLI_assert(cd_dvert_offset != -1);
+
+ vweight = rdata->vert_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
+ BM_ITER_MESH_INDEX(vert, &viter, bm, BM_VERT, i) {
+ const MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(vert, cd_dvert_offset);
+ float weight = defvert_find_weight(dvert, index);
+ if (U.flag & USER_CUSTOM_RANGE) {
+ do_colorband(&U.coba_weight, weight, vweight[i]);
+ }
+ else {
+ rgb_from_weight(vweight[i], weight);
+ }
+ }
+ }
+ else {
+ vweight = rdata->vert_color = MEM_callocN(sizeof(*vweight) * rdata->vert_len, __func__);
+
+ for (int i = 0; i < rdata->vert_len; i++) {
+ vweight[i][2] = 0.5f;
+ }
+ }
+ }
+
+ (*r_vert_cos)[0] = bm_looptri[0]->v->co;
+ (*r_vert_cos)[1] = bm_looptri[1]->v->co;
+ (*r_vert_cos)[2] = bm_looptri[2]->v->co;
+ (*r_vert_weights)[0] = vweight[BM_elem_index_get(bm_looptri[0]->v)];
+ (*r_vert_weights)[1] = vweight[BM_elem_index_get(bm_looptri[1]->v)];
+ (*r_vert_weights)[2] = vweight[BM_elem_index_get(bm_looptri[2]->v)];
+ *r_tri_nor = pnors_short[BM_elem_index_get(bm_looptri[0]->f)];
+ (*r_vert_nors)[0] = vnors_short[BM_elem_index_get(bm_looptri[0]->v)];
+ (*r_vert_nors)[1] = vnors_short[BM_elem_index_get(bm_looptri[1]->v)];
+ (*r_vert_nors)[2] = vnors_short[BM_elem_index_get(bm_looptri[2]->v)];
+
+ *r_is_smooth = BM_elem_flag_test_bool(bm_looptri[0]->f, BM_ELEM_SMOOTH);
+ }
+ else {
+ const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
+ float (*vweight)[3] = rdata->vert_color;
+ short (*pnors_short)[3] = rdata->poly_normals_short;
+
+ if (!pnors_short) {
+ float (*pnors)[3] = rdata->poly_normals;
+
+ if (!pnors) {
+ pnors = rdata->poly_normals = MEM_mallocN(sizeof(*pnors) * rdata->poly_len, __func__);
+ BKE_mesh_calc_normals_poly(
+ rdata->mvert, NULL, rdata->vert_len,
+ rdata->mloop, rdata->mpoly, rdata->loop_len, rdata->poly_len, pnors, true);
+ }
+
+ pnors_short = rdata->poly_normals_short = MEM_mallocN(sizeof(*pnors_short) * rdata->poly_len, __func__);
+ for (int i = 0; i < rdata->poly_len; i++) {
+ normal_float_to_short_v3(pnors_short[i], pnors[i]);
+ }
+ }
+
+ if (!vweight) {
+ if (rdata->dvert) {
+ vweight = rdata->vert_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
+
+ for (int i = 0; i < rdata->vert_len; i++) {
+ float weight = defvert_find_weight(&rdata->dvert[i], index);
+ if (U.flag & USER_CUSTOM_RANGE) {
+ do_colorband(&U.coba_weight, weight, vweight[i]);
+ }
+ else {
+ rgb_from_weight(vweight[i], weight);
+ }
+ }
+ }
+ else {
+ vweight = rdata->vert_color = MEM_callocN(sizeof(*vweight) * rdata->vert_len, __func__);
+
+ for (int i = 0; i < rdata->vert_len; i++) {
+ vweight[i][2] = 0.5f;
+ }
+ }
+ }
+
+ (*r_vert_cos)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].co;
+ (*r_vert_cos)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].co;
+ (*r_vert_cos)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].co;
+ (*r_vert_weights)[0] = vweight[rdata->mloop[mlt->tri[0]].v];
+ (*r_vert_weights)[1] = vweight[rdata->mloop[mlt->tri[1]].v];
+ (*r_vert_weights)[2] = vweight[rdata->mloop[mlt->tri[2]].v];
+ *r_tri_nor = pnors_short[mlt->poly];
+ (*r_vert_nors)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].no;
+ (*r_vert_nors)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].no;
+ (*r_vert_nors)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].no;
+
+ *r_is_smooth = (rdata->mpoly[mlt->poly].flag & ME_SMOOTH) != 0;
+ }
+
+ return true;
+}
+
+static bool mesh_render_data_edge_cos_sel_get(
+ MeshRenderData *rdata, const int edge_idx,
+ float r_vert_cos[2][3], float r_vert_col[3],
+ bool use_wire, bool use_sel)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP));
+
+ if (rdata->edit_bmesh) {
+ return false;
+ }
+ else {
+ const MEdge *ed = &rdata->medge[edge_idx];
+
+ if (!rdata->edge_selection && use_sel) {
+ rdata->edge_selection = MEM_callocN(sizeof(*rdata->edge_selection) * rdata->edge_len, __func__);
+
+ for (int i = 0; i < rdata->poly_len; i++) {
+ MPoly *poly = &rdata->mpoly[i];
+
+ if (poly->flag & ME_FACE_SEL) {
+ for (int j = 0; j < poly->totloop; j++) {
+ MLoop *loop = &rdata->mloop[poly->loopstart + j];
+ if (use_wire) {
+ rdata->edge_selection[loop->e] = true;
+ }
+ else {
+ rdata->edge_selection[loop->e] = !rdata->edge_selection[loop->e];
+ }
+ }
+ }
+ }
+ }
+
+ if (use_sel && rdata->edge_selection[edge_idx]) {
+ r_vert_col[0] = 1.0f;
+ r_vert_col[1] = 1.0f;
+ r_vert_col[2] = 1.0f;
+ }
+ else {
+ if (use_wire) {
+ r_vert_col[0] = 0.5f;
+ r_vert_col[1] = 0.5f;
+ r_vert_col[2] = 0.5f;
+ }
+ else {
+ return false;
+ }
+ }
+
+ copy_v3_v3(r_vert_cos[0], rdata->mvert[ed->v1].co);
+ copy_v3_v3(r_vert_cos[1], rdata->mvert[ed->v2].co);
+ }
+
+ return true;
+}
+
+static bool mesh_render_data_tri_cos_sel_get(
+ MeshRenderData *rdata, const int tri_idx,
+ float r_vert_cos[3][3], float r_vert_col[4])
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
+
+ if (rdata->edit_bmesh) {
+ return false;
+ }
+ else {
+ const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
+
+ if (rdata->mpoly[mlt->poly].flag & ME_FACE_SEL) {
+ r_vert_col[3] = 0.0f;
+ }
+ else {
+ r_vert_col[0] = 1.0f;
+ r_vert_col[1] = 1.0f;
+ r_vert_col[2] = 1.0f;
+ r_vert_col[3] = 0.2f;
+ }
+
+ copy_v3_v3(r_vert_cos[0], rdata->mvert[rdata->mloop[mlt->tri[0]].v].co);
+ copy_v3_v3(r_vert_cos[1], rdata->mvert[rdata->mloop[mlt->tri[1]].v].co);
+ copy_v3_v3(r_vert_cos[2], rdata->mvert[rdata->mloop[mlt->tri[2]].v].co);
+ }
+
+ return true;
+}
+
+static bool mesh_render_data_vert_cos_sel_get(
+ MeshRenderData *rdata, const int vert_idx,
+ float r_vert_co[3], float r_vert_col[3])
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT));
+
+ if (rdata->edit_bmesh) {
+ return false;
+ }
+ else {
+ const MVert *mv = &rdata->mvert[vert_idx];
+
+ if (mv->flag & SELECT) {
+ r_vert_col[0] = 1.0f;
+ r_vert_col[1] = 1.0f;
+ r_vert_col[2] = 1.0f;
+ }
+ else {
+ r_vert_col[0] = 0.4f;
+ r_vert_col[1] = 0.4f;
+ r_vert_col[2] = 0.4f;
+ }
+
+ copy_v3_v3(r_vert_co, mv->co);
+ }
+
+ return true;
+}
+
/* First 2 bytes are bit flags
* 3rd is for sharp edges
* 4rd is for creased edges */
@@ -1141,7 +1453,12 @@ typedef struct MeshBatchCache {
Batch *all_triangles;
VertexBuffer *pos_with_normals;
+ VertexBuffer *pos_with_weights;
+ VertexBuffer *edge_pos_with_sel;
+ VertexBuffer *tri_pos_with_sel;
+ VertexBuffer *pos_with_sel;
Batch *triangles_with_normals;
+ Batch *triangles_with_weights;
Batch *points_with_normals;
Batch *fancy_edges; /* owns its vertex buffer (not shared) */
@@ -1160,9 +1477,13 @@ typedef struct MeshBatchCache {
Batch *overlay_loose_verts;
Batch *overlay_loose_edges;
Batch *overlay_facedots;
+ Batch *overlay_weight_edges;
+ Batch *overlay_weight_faces;
+ Batch *overlay_weight_verts;
/* settings to determine if cache is invalid */
bool is_dirty;
+ bool is_weight_dirty;
int edge_len;
int tri_len;
int poly_len;
@@ -1190,6 +1511,10 @@ static bool mesh_batch_cache_valid(Mesh *me)
return false;
}
+ if (cache->is_weight_dirty) {
+ return false;
+ }
+
if (cache->is_dirty == false) {
return true;
}
@@ -1233,6 +1558,7 @@ static void mesh_batch_cache_init(Mesh *me)
cache->mat_ct = mesh_render_mat_ct_get(me);
cache->is_dirty = false;
+ cache->is_weight_dirty = false;
}
static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
@@ -1261,6 +1587,9 @@ void DRW_mesh_batch_cache_dirty(Mesh *me, int mode)
BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_edges);
BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots);
break;
+ case BKE_MESH_BATCH_DIRTY_WEIGHT:
+ cache->is_weight_dirty = true;
+ break;
default:
BLI_assert(0);
}
@@ -1285,10 +1614,14 @@ static void mesh_batch_cache_clear(Mesh *me)
BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_verts);
BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_edges);
BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots);
+ BATCH_DISCARD_ALL_SAFE(cache->overlay_weight_edges);
+ BATCH_DISCARD_ALL_SAFE(cache->overlay_weight_faces);
+ BATCH_DISCARD_ALL_SAFE(cache->overlay_weight_verts);
BATCH_DISCARD_SAFE(cache->triangles_with_normals);
BATCH_DISCARD_SAFE(cache->points_with_normals);
VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_normals);
+ BATCH_DISCARD_ALL_SAFE(cache->triangles_with_weights);
BATCH_DISCARD_ALL_SAFE(cache->fancy_edges);
@@ -1539,6 +1872,68 @@ static VertexBuffer *mesh_batch_cache_get_pos_and_normals(MeshRenderData *rdata,
return cache->pos_with_normals;
}
+static VertexBuffer *mesh_batch_cache_get_pos_normals_and_weights(MeshRenderData *rdata, MeshBatchCache *cache, int index)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_DVERT | MR_DATATYPE_POLY));
+
+ if (cache->pos_with_weights == NULL) {
+ unsigned int vidx = 0, cidx = 0, nidx = 0;
+
+ static VertexFormat format = { 0 };
+ static unsigned int pos_id, col_id, nor_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ nor_id = VertexFormat_add_attrib(&format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT);
+ col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ VertexBuffer *vbo = cache->pos_with_weights = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = tri_len * 3;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ for (int i = 0; i < tri_len; i++) {
+ float *tri_vert_cos[3], *tri_vert_weights[3];
+ short *tri_nor, *tri_vert_nors[3];
+ bool is_smooth;
+
+ if (mesh_render_data_looptri_cos_weights_get(
+ rdata, i, &tri_vert_cos, &tri_vert_weights, &tri_nor, &tri_vert_nors, &is_smooth, index))
+ {
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_weights[0]);
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_weights[1]);
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_weights[2]);
+
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[0]);
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[1]);
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[2]);
+
+ if (is_smooth) {
+ VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_vert_nors[0]);
+ VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_vert_nors[1]);
+ VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_vert_nors[2]);
+ }
+ else {
+ VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor);
+ VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor);
+ VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor);
+ }
+ }
+ }
+ vbo_len_used = vidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->pos_with_weights;
+}
+
static VertexBuffer *mesh_batch_cache_get_pos_and_nor_in_order(MeshRenderData *rdata, MeshBatchCache *cache)
{
BLI_assert(rdata->types & MR_DATATYPE_VERT);
@@ -1657,6 +2052,146 @@ static ElementList **mesh_batch_cache_get_shaded_triangles_in_order(MeshRenderDa
return cache->shaded_triangles_in_order;
}
+static VertexBuffer *mesh_batch_cache_get_edge_pos_with_sel(MeshRenderData *rdata, MeshBatchCache *cache, bool use_wire, bool use_sel)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP));
+
+ if (!cache->edge_pos_with_sel) {
+ unsigned int vidx = 0, cidx = 0;
+
+ static VertexFormat format = { 0 };
+ static unsigned int pos_id, col_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ const int edge_len = mesh_render_data_edges_len_get(rdata);
+
+ VertexBuffer *vbo = cache->edge_pos_with_sel = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = edge_len * 2;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ for (int i = 0; i < edge_len; i++) {
+ static float edge_vert_cos[2][3], edge_vert_col[3];
+
+ if (mesh_render_data_edge_cos_sel_get(
+ rdata, i, edge_vert_cos, edge_vert_col, use_wire, use_sel))
+ {
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, edge_vert_col);
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, edge_vert_col);
+
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, edge_vert_cos[0]);
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, edge_vert_cos[1]);
+ }
+ }
+
+ vbo_len_used = vidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->edge_pos_with_sel;
+}
+
+static VertexBuffer *mesh_batch_cache_get_tri_pos_with_sel(MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
+
+ if (cache->tri_pos_with_sel == NULL) {
+ unsigned int vidx = 0, cidx = 0;
+
+ static VertexFormat format = { 0 };
+ static unsigned int pos_id, col_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 4, KEEP_FLOAT);
+ }
+
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+
+ VertexBuffer *vbo = cache->tri_pos_with_sel = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = tri_len * 3;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ for (int i = 0; i < tri_len; i++) {
+ static float tri_vert_cos[3][3], tri_vert_col[4];
+
+ if (mesh_render_data_tri_cos_sel_get(
+ rdata, i, tri_vert_cos, tri_vert_col))
+ {
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_col);
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_col);
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_col);
+
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[0]);
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[1]);
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[2]);
+ }
+ }
+
+ vbo_len_used = vidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->tri_pos_with_sel;
+}
+
+static VertexBuffer *mesh_batch_cache_get_pos_with_sel(MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT));
+
+ if (cache->pos_with_sel == NULL) {
+ unsigned int vidx = 0, cidx = 0;
+
+ static VertexFormat format = { 0 };
+ static unsigned int pos_id, col_id;
+ if (format.attrib_ct == 0) {
+ /* initialize vertex format */
+ pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+ col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 3, KEEP_FLOAT);
+ }
+
+ const int vert_len = mesh_render_data_verts_len_get(rdata);
+
+ VertexBuffer *vbo = cache->pos_with_sel = VertexBuffer_create_with_format(&format);
+
+ const int vbo_len_capacity = vert_len;
+ int vbo_len_used = 0;
+ VertexBuffer_allocate_data(vbo, vbo_len_capacity);
+
+ for (int i = 0; i < vert_len; i++) {
+ static float vert_co[3], vert_col[3];
+
+ if (mesh_render_data_vert_cos_sel_get(
+ rdata, i, vert_co, vert_col))
+ {
+ VertexBuffer_set_attrib(vbo, col_id, cidx++, vert_col);
+ VertexBuffer_set_attrib(vbo, pos_id, vidx++, vert_co);
+ }
+ }
+
+ vbo_len_used = vidx;
+
+ if (vbo_len_capacity != vbo_len_used) {
+ VertexBuffer_resize_data(vbo, vbo_len_used);
+ }
+ }
+
+ return cache->pos_with_sel;
+}
+
Batch *DRW_mesh_batch_cache_get_all_edges(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
@@ -1706,6 +2241,21 @@ Batch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me)
return cache->triangles_with_normals;
}
+Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, int index)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->triangles_with_weights == NULL) {
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_DVERT | MR_DATATYPE_POLY);
+
+ cache->triangles_with_weights = Batch_create(PRIM_TRIANGLES, mesh_batch_cache_get_pos_normals_and_weights(rdata, cache, index), NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->triangles_with_weights;
+}
+
Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
@@ -2009,4 +2559,52 @@ Batch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me)
return cache->shaded_triangles;
}
+Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_weight_edges == NULL) {
+ /* create batch from Mesh */
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
+
+ cache->overlay_weight_edges = Batch_create(PRIM_LINES, mesh_batch_cache_get_edge_pos_with_sel(rdata, cache, use_wire, use_sel), NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->overlay_weight_edges;
+}
+
+Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_weight_faces == NULL) {
+ /* create batch from Mesh */
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
+
+ cache->overlay_weight_faces = Batch_create(PRIM_TRIANGLES, mesh_batch_cache_get_tri_pos_with_sel(rdata, cache), NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->overlay_weight_faces;
+}
+
+Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->overlay_weight_verts == NULL) {
+ /* create batch from Mesh */
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT);
+
+ cache->overlay_weight_verts = Batch_create(PRIM_POINTS, mesh_batch_cache_get_pos_with_sel(rdata, cache), NULL);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->overlay_weight_verts;
+}
+
#undef MESH_RENDER_FUNCTION
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 4a77a9f4c6a..65d3fba619f 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -1189,7 +1189,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
if (do_outlines) {
Object *obedit = scene->obedit;
- if (ob != obedit) {
+ if (ob != obedit && !(sl->basact->object == ob && ob->mode & OB_MODE_WEIGHT_PAINT)) {
struct Batch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c
index fe5fdf9ba91..2819dcbc6c5 100644
--- a/source/blender/draw/modes/paint_weight_mode.c
+++ b/source/blender/draw/modes/paint_weight_mode.c
@@ -33,53 +33,34 @@
#include "draw_mode_engines.h"
-/* If needed, contains all global/Theme colors
- * Add needed theme colors / values to DRW_globals_update() and update UBO
- * Not needed for constant color. */
+#include "DNA_mesh_types.h"
+
+#include "BKE_mesh.h"
+
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
extern struct GlobalsUboStorage ts; /* draw_common.c */
/* *********** LISTS *********** */
-/* All lists are per viewport specific datas.
- * They are all free when viewport changes engines
- * or is free itself. Use PAINT_WEIGHT_engine_init() to
- * initialize most of them and PAINT_WEIGHT_cache_init()
- * for PAINT_WEIGHT_PassList */
typedef struct PAINT_WEIGHT_PassList {
- /* Declare all passes here and init them in
- * PAINT_WEIGHT_cache_init().
- * Only contains (DRWPass *) */
- struct DRWPass *pass;
+ struct DRWPass *weight_faces;
+ struct DRWPass *wire_overlay;
+ struct DRWPass *face_overlay;
+ struct DRWPass *vert_overlay;
} PAINT_WEIGHT_PassList;
typedef struct PAINT_WEIGHT_FramebufferList {
- /* Contains all framebuffer objects needed by this engine.
- * Only contains (GPUFrameBuffer *) */
- struct GPUFrameBuffer *fb;
} PAINT_WEIGHT_FramebufferList;
typedef struct PAINT_WEIGHT_TextureList {
- /* Contains all framebuffer textures / utility textures
- * needed by this engine. Only viewport specific textures
- * (not per object). Only contains (GPUTexture *) */
- struct GPUTexture *texture;
} PAINT_WEIGHT_TextureList;
typedef struct PAINT_WEIGHT_StorageList {
- /* Contains any other memory block that the engine needs.
- * Only directly MEM_(m/c)allocN'ed blocks because they are
- * free with MEM_freeN() when viewport is freed.
- * (not per object) */
- struct CustomStruct *block;
struct PAINT_WEIGHT_PrivateData *g_data;
} PAINT_WEIGHT_StorageList;
typedef struct PAINT_WEIGHT_Data {
- /* Struct returned by DRW_viewport_engine_data_get.
- * If you don't use one of these, just make it a (void *) */
- // void *fbl;
- void *engine_type; /* Required */
+ void *engine_type;
PAINT_WEIGHT_FramebufferList *fbl;
PAINT_WEIGHT_TextureList *txl;
PAINT_WEIGHT_PassList *psl;
@@ -89,54 +70,46 @@ typedef struct PAINT_WEIGHT_Data {
/* *********** STATIC *********** */
static struct {
- /* Custom shaders :
- * Add sources to source/blender/draw/modes/shaders
- * init in PAINT_WEIGHT_engine_init();
- * free in PAINT_WEIGHT_engine_free(); */
- struct GPUShader *custom_shader;
+ struct GPUShader *weight_face_shader;
+ struct GPUShader *flat_overlay_shader;
+ struct GPUShader *vert_overlay_shader;
+ int actdef;
} e_data = {NULL}; /* Engine data */
typedef struct PAINT_WEIGHT_PrivateData {
- /* This keeps the references of the shading groups for
- * easy access in PAINT_WEIGHT_cache_populate() */
- DRWShadingGroup *group;
+ DRWShadingGroup *fweights_shgrp;
+ DRWShadingGroup *lwire_shgrp;
+ DRWShadingGroup *face_shgrp;
+ DRWShadingGroup *vert_shgrp;
} PAINT_WEIGHT_PrivateData;
/* *********** FUNCTIONS *********** */
-/* Init Textures, Framebuffers, Storage and Shaders.
- * It is called for every frames.
- * (Optional) */
-static void PAINT_WEIGHT_engine_init(void *vedata)
+static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata))
{
- PAINT_WEIGHT_TextureList *txl = ((PAINT_WEIGHT_Data *)vedata)->txl;
- PAINT_WEIGHT_FramebufferList *fbl = ((PAINT_WEIGHT_Data *)vedata)->fbl;
- PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if (e_data.actdef != draw_ctx->sl->basact->object->actdef) {
+ e_data.actdef = draw_ctx->sl->basact->object->actdef;
+
+ BKE_mesh_batch_cache_dirty(draw_ctx->sl->basact->object->data, BKE_MESH_BATCH_DIRTY_WEIGHT);
+ }
+
+ if (!e_data.weight_face_shader) {
+ e_data.weight_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA);
+ }
+
+ if (!e_data.flat_overlay_shader) {
+ e_data.flat_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
+ }
- UNUSED_VARS(txl, fbl, stl);
-
- /* Init Framebuffers like this: order is attachment order (for color texs) */
- /*
- * DRWFboTexture tex[2] = {{&txl->depth, DRW_BUF_DEPTH_24, 0},
- * {&txl->color, DRW_BUF_RGBA_8, DRW_TEX_FILTER}};
- */
-
- /* DRW_framebuffer_init takes care of checking if
- * the framebuffer is valid and has the right size*/
- /*
- * float *viewport_size = DRW_viewport_size_get();
- * DRW_framebuffer_init(&fbl->occlude_wire_fb,
- * (int)viewport_size[0], (int)viewport_size[1],
- * tex, 2);
- */
-
- if (!e_data.custom_shader) {
- e_data.custom_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (!e_data.vert_overlay_shader) {
+ e_data.vert_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
}
}
-/* Here init all passes and shading groups
- * Assume that all Passes are NULL */
+static float world_light;
+
static void PAINT_WEIGHT_cache_init(void *vedata)
{
PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl;
@@ -149,105 +122,94 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
{
/* Create a pass */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
- psl->pass = DRW_pass_create("My Pass", state);
-
- /* Create a shadingGroup using a function in draw_common.c or custom one */
- /*
- * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
- * -- or --
- * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
- */
- stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
-
- /* Uniforms need a pointer to it's value so be sure it's accessible at
- * any given time (i.e. use static vars) */
- static float color[4] = {0.2f, 0.5f, 0.3f, 1.0};
- DRW_shgroup_uniform_vec4(stl->g_data->group, "color", color, 1);
+ psl->weight_faces = DRW_pass_create("Weight Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces);
+
+ static float light[3] = {-0.3f, 0.5f, 1.0f};
+ static float alpha = 1.0f;
+ DRW_shgroup_uniform_vec3(stl->g_data->fweights_shgrp, "light", light, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "alpha", &alpha, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "global", &world_light, 1);
}
-}
+ {
+ psl->wire_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
-/* Add geometry to shadingGroups. Execute for each objects */
-static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob)
-{
- PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
+ stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.flat_overlay_shader, psl->wire_overlay);
+ }
- if (ob->type == OB_MESH) {
- /* Get geometry cache */
- struct Batch *geom = DRW_cache_mesh_surface_get(ob);
+ {
+ psl->face_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+
+ stl->g_data->face_shgrp = DRW_shgroup_create(e_data.flat_overlay_shader, psl->face_overlay);
+ }
+
+ {
+ psl->vert_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- /* Add geom to a shading group */
- DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat);
+ stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay);
}
}
-/* Optional: Post-cache_populate callback */
-static void PAINT_WEIGHT_cache_finish(void *vedata)
+static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob)
{
- PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl;
PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
-
- /* Do something here! dependant on the objects gathered */
- UNUSED_VARS(psl, stl);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SceneLayer *sl = draw_ctx->sl;
+
+ if (ob->type == OB_MESH && ob == sl->basact->object) {
+ IDProperty *ces_mode_pw = BKE_object_collection_engine_get(ob, COLLECTION_MODE_PAINT_WEIGHT, "");
+ bool use_wire = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_wire");
+ char flag = ((Mesh *)ob->data)->editflag;
+ struct Batch *geom;
+
+ world_light = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_shading") ? 0.5f : 1.0f;
+
+ geom = DRW_cache_mesh_surface_weights_get(ob);
+ DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
+
+ if (flag & ME_EDIT_PAINT_FACE_SEL || use_wire) {
+ geom = DRW_cache_mesh_edges_weight_overlay_get(ob, use_wire, flag & ME_EDIT_PAINT_FACE_SEL);
+ DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
+ }
+
+ if (flag & ME_EDIT_PAINT_FACE_SEL) {
+ geom = DRW_cache_mesh_faces_weight_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
+ }
+
+ if (flag & ME_EDIT_PAINT_VERT_SEL) {
+ geom = DRW_cache_mesh_verts_weight_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->vert_shgrp, geom, ob->obmat);
+ }
+ }
}
-/* Draw time ! Control rendering pipeline from here */
static void PAINT_WEIGHT_draw_scene(void *vedata)
{
PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl;
- PAINT_WEIGHT_FramebufferList *fbl = ((PAINT_WEIGHT_Data *)vedata)->fbl;
- /* Default framebuffer and texture */
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
-
- UNUSED_VARS(fbl, dfbl, dtxl);
-
- /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
- /*
- * DRW_framebuffer_texture_detach(dtxl->depth);
- * DRW_framebuffer_bind(fbl->custom_fb);
- * DRW_draw_pass(psl->pass);
- * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
- * DRW_framebuffer_bind(dfbl->default_fb);
- */
-
- /* ... or just render passes on default framebuffer. */
- DRW_draw_pass(psl->pass);
-
- /* If you changed framebuffer, double check you rebind
- * the default one with its textures attached before finishing */
+ DRW_draw_pass(psl->weight_faces);
+ DRW_draw_pass(psl->face_overlay);
+ DRW_draw_pass(psl->wire_overlay);
+ DRW_draw_pass(psl->vert_overlay);
}
-/* Cleanup when destroying the engine.
- * This is not per viewport ! only when quitting blender.
- * Mostly used for freeing shaders */
static void PAINT_WEIGHT_engine_free(void)
{
- // DRW_SHADER_FREE_SAFE(custom_shader);
}
-/* Create collection settings here.
- *
- * Be sure to add this function there :
- * source/blender/draw/DRW_engine.h
- * source/blender/blenkernel/intern/layer.c
- * source/blenderplayer/bad_level_call_stubs/stubs.c
- *
- * And relevant collection settings to :
- * source/blender/makesrna/intern/rna_scene.c
- * source/blender/blenkernel/intern/layer.c
- */
-#if 0
-void PAINT_WEIGHT_collection_settings_create(CollectionEngineSettings *ces)
+void PAINT_WEIGHT_collection_settings_create(IDProperty *properties)
{
- BLI_assert(ces);
- // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
- // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
- // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+ BLI_assert(properties &&
+ properties->type == IDP_GROUP &&
+ properties->subtype == IDP_GROUP_SUB_MODE_PAINT_WEIGHT);
+
+ BKE_collection_engine_property_add_bool(properties, "use_shading", true);
+ BKE_collection_engine_property_add_bool(properties, "use_wire", false);
}
-#endif
+
static const DrawEngineDataSize PAINT_WEIGHT_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_WEIGHT_Data);
@@ -259,7 +221,7 @@ DrawEngineType draw_engine_paint_weight_type = {
&PAINT_WEIGHT_engine_free,
&PAINT_WEIGHT_cache_init,
&PAINT_WEIGHT_cache_populate,
- &PAINT_WEIGHT_cache_finish,
- NULL, /* draw_background but not needed by mode engines */
+ NULL,
+ NULL,
&PAINT_WEIGHT_draw_scene
};
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index a478526dee0..93a075aa9ec 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -106,6 +106,8 @@ void paintface_flush_flags(Object *ob, short flag)
/* draw-object caches hidden faces, force re-generation T46867 */
GPU_drawobject_free(dm);
}
+
+ BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_WEIGHT);
}
void paintface_hide(Object *ob, const bool unselected)
@@ -387,7 +389,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b
}
/* image window redraw */
-
+
paintface_flush_flags(ob, SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
@@ -515,6 +517,8 @@ void paintvert_flush_flags(Object *ob)
dm_mv->flag = me->mvert[i].flag;
}
}
+
+ BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_WEIGHT);
}
/* note: if the caller passes false to flush_flags, then they will need to run paintvert_flush_flags(ob) themselves */
void paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index e53cf05bb15..bc561c345b4 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -51,6 +51,7 @@
#include "BKE_curve.h"
#include "BKE_colortools.h"
#include "BKE_image.h"
+#include "BKE_mesh.h"
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 729dd9dc57b..de40a666145 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2382,6 +2382,8 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* also needed for "View Selected" on last stroke */
paint_last_stroke_update(scene, vc->ar, mval);
+ BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_WEIGHT);
+
DAG_id_tag_update(ob->data, 0);
ED_region_tag_redraw(vc->ar);
}
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index e0b798216da..eaa0ec65d00 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -129,6 +129,7 @@ data_to_c_simple(shaders/gpu_shader_checker_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_diag_stripes_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_simple_lighting_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_flat_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index e88bffb98ed..d26218382c8 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -106,6 +106,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_KEYFRAME_DIAMOND,
GPU_SHADER_SIMPLE_LIGHTING,
GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR,
+ GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA,
/* for simple 2D drawing */
GPU_SHADER_2D_UNIFORM_COLOR,
GPU_SHADER_2D_FLAT_COLOR,
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index c6688164d15..d72d7f7c2b5 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -53,6 +53,7 @@ extern char datatoc_gpu_shader_checker_frag_glsl[];
extern char datatoc_gpu_shader_diag_stripes_frag_glsl[];
extern char datatoc_gpu_shader_simple_lighting_frag_glsl[];
extern char datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl[];
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
extern char datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl[];
extern char datatoc_gpu_shader_2D_vert_glsl[];
@@ -670,6 +671,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
datatoc_gpu_shader_edges_overlay_geom_glsl },
[GPU_SHADER_SIMPLE_LIGHTING] = { datatoc_gpu_shader_3D_normal_vert_glsl, datatoc_gpu_shader_simple_lighting_frag_glsl },
[GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl, datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl },
+ [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA] = { datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl, datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl },
[GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_image_vert_glsl,
datatoc_gpu_shader_image_mask_uniform_color_frag_glsl },
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl
new file mode 100644
index 00000000000..6b13f408c84
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl
@@ -0,0 +1,14 @@
+
+uniform vec3 light;
+uniform float alpha;
+uniform float global;
+
+in vec3 normal;
+in vec4 finalColor;
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = finalColor * (global + (1.0 - global) * max(0.0, dot(normalize(normal), light)));
+ fragColor.a = alpha;
+}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 14b9b17e02c..3efc3d875ea 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -98,11 +98,12 @@ enum {
/* IDP_GROUP */
enum {
- IDP_GROUP_SUB_NONE = 0, /* default */
- IDP_GROUP_SUB_MODE_OBJECT = 1, /* object mode settings */
- IDP_GROUP_SUB_MODE_EDIT = 2, /* mesh edit mode settings */
- IDP_GROUP_SUB_ENGINE_RENDER = 3, /* render engine settings */
- IDP_GROUP_SUB_OVERRIDE = 4, /* data override */
+ IDP_GROUP_SUB_NONE = 0, /* default */
+ IDP_GROUP_SUB_MODE_OBJECT = 1, /* object mode settings */
+ IDP_GROUP_SUB_MODE_EDIT = 2, /* mesh edit mode settings */
+ IDP_GROUP_SUB_ENGINE_RENDER = 3, /* render engine settings */
+ IDP_GROUP_SUB_OVERRIDE = 4, /* data override */
+ IDP_GROUP_SUB_MODE_PAINT_WEIGHT = 5, /* weight paint mode settings */
};
/*->flag*/
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 6233cdb8c24..348244d6279 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -120,6 +120,7 @@ typedef enum CollectionEngineSettingsType {
COLLECTION_MODE_NONE = 0,
COLLECTION_MODE_OBJECT = 1,
COLLECTION_MODE_EDIT = 2,
+ COLLECTION_MODE_PAINT_WEIGHT = 5,
} CollectionModeSettingsType;
/* *************************************************************** */
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index ad5f320625c..29c267127ae 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -237,6 +237,13 @@ static void rna_Mesh_update_data_edit_color(Main *bmain, Scene *scene, PointerRN
}
}
+static void rna_Mesh_update_data_edit_weight(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ BKE_mesh_batch_cache_dirty(rna_mesh(ptr), BKE_MESH_BATCH_DIRTY_WEIGHT);
+
+ rna_Mesh_update_data(bmain, scene, ptr);
+}
+
static void rna_Mesh_update_select(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
@@ -262,6 +269,9 @@ static void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr)
if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
me->editflag &= ~ME_EDIT_PAINT_FACE_SEL;
}
+
+ BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_WEIGHT);
+
rna_Mesh_update_draw(bmain, scene, ptr);
}
@@ -271,6 +281,9 @@ static void rna_Mesh_update_facemask(Main *bmain, Scene *scene, PointerRNA *ptr)
if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
me->editflag &= ~ME_EDIT_PAINT_VERT_SEL;
}
+
+ BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_WEIGHT);
+
rna_Mesh_update_draw(bmain, scene, ptr);
}
@@ -1883,7 +1896,7 @@ static void rna_def_mvert_group(BlenderRNA *brna)
prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Weight", "Vertex Weight");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_weight");
}
static void rna_def_mvert(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 2703faf8036..a2c7458d395 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -441,6 +441,7 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[] = {
{COLLECTION_MODE_OBJECT, "OBJECT", 0, "Object", ""},
{COLLECTION_MODE_EDIT, "EDIT", 0, "Edit", ""},
+ {COLLECTION_MODE_PAINT_WEIGHT, "PAINT_WIGHT", 0, "Weight Paint", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1949,7 +1950,11 @@ static StructRNA *rna_LayerCollectionSettings_refine(PointerRNA *ptr)
case IDP_GROUP_SUB_MODE_EDIT:
return &RNA_LayerCollectionModeSettingsEdit;
break;
+ case IDP_GROUP_SUB_MODE_PAINT_WEIGHT:
+ return &RNA_LayerCollectionModeSettingsPaintWeight;
+ break;
default:
+ BLI_assert(!"Mode not fully implemented");
break;
}
@@ -2488,6 +2493,9 @@ static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_set(PointerRNA *ptr,
#define RNA_LAYER_MODE_EDIT_GET_SET_BOOL(_NAME_) \
RNA_LAYER_ENGINE_GET_SET(bool, EditMode, COLLECTION_MODE_EDIT, _NAME_)
+#define RNA_LAYER_MODE_PAINT_WEIGHT_GET_SET_BOOL(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(bool, PaintWeightMode, COLLECTION_MODE_PAINT_WEIGHT, _NAME_)
+
/* clay engine */
#ifdef WITH_CLAY_ENGINE
RNA_LAYER_ENGINE_CLAY_GET_SET_INT(matcap_icon)
@@ -2513,6 +2521,10 @@ RNA_LAYER_MODE_EDIT_GET_SET_BOOL(loop_normals_show)
RNA_LAYER_MODE_EDIT_GET_SET_FLOAT(normals_length)
RNA_LAYER_MODE_EDIT_GET_SET_FLOAT(backwire_opacity)
+/* weight paint engine */
+RNA_LAYER_MODE_PAINT_WEIGHT_GET_SET_BOOL(use_shading)
+RNA_LAYER_MODE_PAINT_WEIGHT_GET_SET_BOOL(use_wire)
+
#undef RNA_LAYER_ENGINE_GET_SET
static void rna_LayerCollectionEngineSettings_update(bContext *C, PointerRNA *UNUSED(ptr))
@@ -2522,6 +2534,15 @@ static void rna_LayerCollectionEngineSettings_update(bContext *C, PointerRNA *UN
DAG_id_tag_update(&scene->id, 0);
}
+static void rna_LayerCollectionEngineSettings_weight_wire_update(bContext *C, PointerRNA *UNUSED(ptr))
+{
+ Scene *scene = CTX_data_scene(C);
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ BKE_mesh_batch_cache_dirty(sl->basact->object->data, BKE_MESH_BATCH_DIRTY_WEIGHT);
+ /* TODO(sergey): Use proper flag for tagging here. */
+ DAG_id_tag_update(&scene->id, 0);
+}
+
/***********************************/
static void rna_LayerCollectionSettings_name_get(PointerRNA *ptr, char *value)
@@ -6154,6 +6175,32 @@ static void rna_def_layer_collection_mode_settings_edit(BlenderRNA *brna)
RNA_define_verify_sdna(1); /* not in sdna */
}
+static void rna_def_layer_collection_mode_settings_paint_weight(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "LayerCollectionModeSettingsPaintWeight", "LayerCollectionSettings");
+ RNA_def_struct_ui_text(srna, "Collections Weight Paint Mode Settings", "Weight Paint Mode specific settings to be overridden per collection");
+ RNA_define_verify_sdna(0); /* not in sdna */
+
+ /* see RNA_LAYER_ENGINE_GET_SET macro */
+
+ prop = RNA_def_property(srna, "use_shading", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Use Shading", "Whether to use shaded or shadeless drawing");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_PaintWeightMode_use_shading_get", "rna_LayerEngineSettings_PaintWeightMode_use_shading_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
+ prop = RNA_def_property(srna, "use_wire", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Wire", "Whether to overlay wireframe onto the mesh");
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_PaintWeightMode_use_wire_get", "rna_LayerEngineSettings_PaintWeightMode_use_wire_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_weight_wire_update");
+
+ RNA_define_verify_sdna(1); /* not in sdna */
+}
+
static void rna_def_layer_collection_settings(BlenderRNA *brna)
{
StructRNA *srna;
@@ -6193,6 +6240,7 @@ static void rna_def_layer_collection_settings(BlenderRNA *brna)
rna_def_layer_collection_mode_settings_object(brna);
rna_def_layer_collection_mode_settings_edit(brna);
+ rna_def_layer_collection_mode_settings_paint_weight(brna);
RNA_define_verify_sdna(1);
}