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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-06-26 22:40:55 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-06-26 22:40:55 +0400
commitca51930a90056aa3a65dcfc086ddd9ad19dcdf0f (patch)
tree8aab10f95727869b1e105a2ed9cb0a12f3cd84da /source/blender/editors/sculpt_paint
parent9c85cdceb2544740682490a07a3d3f77612f9691 (diff)
fix [#33068] Can't paint weights of some vertices in some situations.
old limitation where you could only paint onto one side of a mirrored mesh (weight paint, vertex paint).
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt1
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h15
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c41
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c244
4 files changed, 279 insertions, 22 deletions
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 9b46a07b60e..79ce4f879b7 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -50,6 +50,7 @@ set(SRC
paint_undo.c
paint_utils.c
paint_vertex.c
+ paint_vertex_proj.c
sculpt.c
sculpt_undo.c
sculpt_uv.c
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index df0fb8ec4f8..6c13f6efb74 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -54,6 +54,7 @@ struct wmOperator;
struct wmOperatorType;
struct ImagePaintState;
struct wmWindowManager;
+struct DMCoNo;
enum PaintMode;
/* paint_stroke.c */
@@ -115,6 +116,20 @@ void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
unsigned int vpaint_get_current_col(struct VPaint *vp);
+
+/* paint_vertex_proj.c */
+struct VertProjHandle;
+struct VertProjHandle *ED_vpaint_proj_handle_create(
+ struct Scene *scene, struct Object *ob,
+ struct DMCoNo **r_vcosnos);
+void ED_vpaint_proj_handle_update(
+ struct VertProjHandle *vp_handle,
+ /* runtime vars */
+ struct ARegion *ar, const float mval_fl[2]);
+void ED_vpaint_proj_handle_free(
+ struct VertProjHandle *vp_handle);
+
+
/* paint_image.c */
typedef struct ImagePaintPartialRedraw {
int x1, y1, x2, y2; /* XXX, could use 'rcti' */
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 181b32d58fc..158a6a92536 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -29,24 +29,11 @@
* \ingroup edsculpt
*/
-
-#include <math.h>
-#include <string.h>
-
-#ifdef WIN32
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_math_color.h"
#include "BLI_memarena.h"
-#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -57,14 +44,12 @@
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
#include "DNA_object_types.h"
-#include "DNA_meshdata_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_armature.h"
#include "BKE_action.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -87,7 +72,7 @@
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "paint_intern.h"
+#include "paint_intern.h" /* own include */
/* check if we can do partial updates and have them draw realtime
* (without rebuilding the 'derivedFinal') */
@@ -2135,7 +2120,10 @@ struct WPaintData {
int *indexar;
int vgroup_active;
int vgroup_mirror;
+
+ void *vp_handle;
DMCoNo *vertexcosnos;
+
float wpimat[3][3];
/* variables for auto normalize */
@@ -2244,7 +2232,8 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU
}
/* painting on subsurfs should give correct points too, this returns me->totvert amount */
- wpd->vertexcosnos = mesh_get_mapped_verts_nors(scene, ob);
+ wpd->vp_handle = ED_vpaint_proj_handle_create(scene, ob, &wpd->vertexcosnos);
+
wpd->indexar = get_indexarray(me);
copy_wpaint_prev(wp, me->dvert, me->totvert);
@@ -2378,6 +2367,9 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
indexar = NULL;
}
+ /* incase we have modifiers */
+ ED_vpaint_proj_handle_update(wpd->vp_handle, vc->ar, mval);
+
/* make sure each vertex gets treated only once */
/* and calculate filter weight */
totw = 0.0f;
@@ -2516,8 +2508,7 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
struct WPaintData *wpd = paint_stroke_mode_data(stroke);
if (wpd) {
- if (wpd->vertexcosnos)
- MEM_freeN(wpd->vertexcosnos);
+ ED_vpaint_proj_handle_free(wpd->vp_handle);
MEM_freeN(wpd->indexar);
if (wpd->vgroup_validmap)
@@ -2750,7 +2741,10 @@ typedef struct VPaintData {
ViewContext vc;
unsigned int paintcol;
int *indexar;
+
+ struct VertProjHandle *vp_handle;
DMCoNo *vertexcosnos;
+
float vpimat[3][3];
/* modify 'me->mcol' directly, since the derived mesh is drawing from this
@@ -2829,7 +2823,8 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
paint_stroke_set_mode_data(stroke, vpd);
view3d_set_viewcontext(C, &vpd->vc);
- vpd->vertexcosnos = mesh_get_mapped_verts_nors(vpd->vc.scene, ob);
+ vpd->vp_handle = ED_vpaint_proj_handle_create(vpd->vc.scene, ob, &vpd->vertexcosnos);
+
vpd->indexar = get_indexarray(me);
vpd->paintcol = vpaint_get_current_col(vp);
@@ -3027,6 +3022,9 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
swap_m4m4(vc->rv3d->persmat, mat);
+ /* incase we have modifiers */
+ ED_vpaint_proj_handle_update(vpd->vp_handle, vc->ar, mval);
+
/* clear modified tag for blur tool */
if (vpd->mlooptag)
memset(vpd->mlooptag, 0, sizeof(bool) * me->totloop);
@@ -3072,8 +3070,7 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
ViewContext *vc = &vpd->vc;
Object *ob = vc->obact;
- if (vpd->vertexcosnos)
- MEM_freeN(vpd->vertexcosnos);
+ ED_vpaint_proj_handle_free(vpd->vp_handle);
MEM_freeN(vpd->indexar);
/* frees prev buffer */
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
new file mode 100644
index 00000000000..51734447d1d
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -0,0 +1,244 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/sculpt_paint/paint_vertex_proj.c
+ * \ingroup edsculpt
+ *
+ * Utility functions for getting vertex locations while painting
+ * (since they may be instanced multiple times in a DerivedMesh)
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_context.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "paint_intern.h" /* own include */
+
+
+/* Opaque Structs for internal use */
+
+/* stored while painting */
+struct VertProjHandle {
+ DMCoNo *vcosnos;
+
+ bool use_update;
+
+ /* use for update */
+ float *dists;
+
+ Object *ob;
+ Scene *scene;
+};
+
+/* only for passing to the callbacks */
+struct VertProjUpdate {
+ struct VertProjHandle *vp_handle;
+
+ /* runtime */
+ ARegion *ar;
+ const float *mval_fl;
+};
+
+
+/* -------------------------------------------------------------------- */
+/* Internal Init */
+
+static void vpaint_proj_dm_map_cosnos_init__map_cb(void *userData, int index, const float co[3],
+ const float no_f[3], const short no_s[3])
+{
+ struct VertProjHandle *vp_handle = userData;
+ DMCoNo *co_no = &vp_handle->vcosnos[index];
+
+ /* check if we've been here before (normal should not be 0) */
+ if (!is_zero_v3(co_no->no)) {
+ /* remember that multiple dm verts share the same source vert */
+ vp_handle->use_update = true;
+ return;
+ }
+
+ copy_v3_v3(co_no->co, co);
+ if (no_f) {
+ copy_v3_v3(co_no->no, no_f);
+ }
+ else {
+ normal_short_to_float_v3(co_no->no, no_s);
+ }
+}
+
+static void vpaint_proj_dm_map_cosnos_init(Scene *scene, Object *ob,
+ struct VertProjHandle *vp_handle)
+{
+ Mesh *me = ob->data;
+ DerivedMesh *dm;
+
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
+
+ if (dm->foreachMappedVert) {
+ memset(vp_handle->vcosnos, 0, sizeof(DMCoNo) * me->totvert);
+ dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle);
+ }
+ else {
+ DMCoNo *v_co_no = vp_handle->vcosnos;
+ int a;
+ for (a = 0; a < me->totvert; a++, v_co_no++) {
+ dm->getVertCo(dm, a, v_co_no->co);
+ dm->getVertNo(dm, a, v_co_no->no);
+ }
+ }
+
+ dm->release(dm);
+}
+
+
+/* -------------------------------------------------------------------- */
+/* Internal Update */
+
+/* Same as init but take mouse location into account */
+
+static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, const float co[3],
+ const float no_f[3], const short no_s[3])
+{
+ struct VertProjUpdate *vp_update = userData;
+ struct VertProjHandle *vp_handle = vp_update->vp_handle;
+
+ DMCoNo *co_no = &vp_handle->vcosnos[index];
+
+ /* find closest vertex */
+ {
+ /* first find distance to this vertex */
+ float co_ss[2]; /* screenspace */
+
+ if (ED_view3d_project_float_object(vp_update->ar,
+ co, co_ss,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
+ const float dist = len_squared_v2v2(vp_update->mval_fl, co_ss);
+ if (dist > vp_handle->dists[index]) {
+ /* bail out! */
+ return;
+ }
+
+ vp_handle->dists[index] = dist;
+ }
+ }
+ /* continue with regular functionality */
+
+ copy_v3_v3(co_no->co, co);
+ if (no_f) {
+ copy_v3_v3(co_no->no, no_f);
+ }
+ else {
+ normal_short_to_float_v3(co_no->no, no_s);
+ }
+}
+
+static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle,
+ ARegion *ar, const float mval_fl[2])
+{
+ struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl};
+
+ Scene *scene = vp_handle->scene;
+ Object *ob = vp_handle->ob;
+ Mesh *me = ob->data;
+ DerivedMesh *dm;
+
+ /* quick sanity check - we shouldn't have to run this if there are no modifiers */
+ BLI_assert(ob->modifiers.first != NULL);
+
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
+
+ /* highly unlikely this will become unavailable once painting starts (perhaps with animated modifiers) */
+ if (LIKELY(dm->foreachMappedVert)) {
+ fill_vn_fl(vp_handle->dists, me->totvert, FLT_MAX);
+
+ dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update);
+ }
+
+ dm->release(dm);
+
+ (void)mval_fl;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* Public Functions */
+
+struct VertProjHandle *ED_vpaint_proj_handle_create(Scene *scene, Object *ob,
+ DMCoNo **r_vcosnos)
+{
+ struct VertProjHandle *vp_handle = MEM_mallocN(sizeof(struct VertProjHandle), __func__);
+ Mesh *me = ob->data;
+
+ /* setup the handle */
+ vp_handle->vcosnos = MEM_mallocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map");
+ vp_handle->use_update = false;
+
+ /* sets 'use_update' if needed */
+ vpaint_proj_dm_map_cosnos_init(scene, ob, vp_handle);
+
+ if (vp_handle->use_update) {
+ vp_handle->dists = MEM_mallocN(sizeof(float) * me->totvert, __func__);
+
+ vp_handle->ob = ob;
+ vp_handle->scene = scene;
+ }
+ else {
+ vp_handle->dists = NULL;
+
+ vp_handle->ob = NULL;
+ vp_handle->scene = NULL;
+ }
+
+ *r_vcosnos = vp_handle->vcosnos;
+ return vp_handle;
+}
+
+void ED_vpaint_proj_handle_update(struct VertProjHandle *vp_handle,
+ ARegion *ar, const float mval_fl[2])
+{
+ if (vp_handle->use_update) {
+ vpaint_proj_dm_map_cosnos_update(vp_handle, ar, mval_fl);
+ }
+}
+
+void ED_vpaint_proj_handle_free(struct VertProjHandle *vp_handle)
+{
+ if (vp_handle->use_update) {
+ MEM_freeN(vp_handle->dists);
+ }
+
+ MEM_freeN(vp_handle->vcosnos);
+ MEM_freeN(vp_handle);
+}