forked from bartvdbraak/blender
Vertex/Weight Paint: Use PBVH for painting
2016 GSOC project by @nathanvollmer, see D2150 - Mirrored painting and radial symmetry, like in sculpt mode. - Volume based splash prevention, which avoids painting vertices far away from the 3D brush location. - Normal based splash prevention, which avoids painting vertices with normals opposite the normal at the 3D brush location. - Blur mode now uses a nearest neighbor average. - Average mode, which averages the color/weight of the vertices within the brush - Smudge mode, which pulls the colors/weights along the direction of the brush - RGB^2 color blending, which gives a more accurate blend between two colors - multithreading support. (PBVH leaves are painted in parallel.) - Foreground/background color picker in vertex paint
This commit is contained in:
parent
2de5e14f53
commit
4f616c93f7
@ -51,6 +51,19 @@ def draw_keyframing_tools(context, layout):
|
||||
row.operator("anim.keyframe_delete_v3d", text="Remove")
|
||||
|
||||
|
||||
# Used by vertex & weight paint
|
||||
def draw_vpaint_symmetry(layout, vpaint):
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Mirror:")
|
||||
row = col.row(align=True)
|
||||
|
||||
row.prop(vpaint, "use_symmetry_x", text="X", toggle=True)
|
||||
row.prop(vpaint, "use_symmetry_y", text="Y", toggle=True)
|
||||
row.prop(vpaint, "use_symmetry_z", text="Z", toggle=True)
|
||||
|
||||
col = layout.column()
|
||||
col.prop(vpaint, "radial_symmetry", text="Radial")
|
||||
|
||||
# ********** default tools for object-mode ****************
|
||||
|
||||
|
||||
@ -1134,7 +1147,11 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_color_picker(col, context, brush, "color", value_slider=True)
|
||||
if settings.palette:
|
||||
col.template_palette(settings, "palette", color=True)
|
||||
self.prop_unified_color(col, context, brush, "color", text="")
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_color(row, context, brush, "color", text="")
|
||||
self.prop_unified_color(row, context, brush, "secondary_color", text="")
|
||||
row.separator()
|
||||
row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="")
|
||||
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
@ -1717,6 +1734,19 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
|
||||
props.data_type = 'VGROUP_WEIGHTS'
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel):
|
||||
bl_category = "Tools"
|
||||
bl_context = "weightpaint"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_label = "Symmetry"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
toolsettings = context.tool_settings
|
||||
wpaint = toolsettings.weight_paint
|
||||
draw_vpaint_symmetry(layout, wpaint)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
|
||||
bl_category = "Options"
|
||||
bl_context = "weightpaint"
|
||||
@ -1779,6 +1809,20 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
|
||||
#~ col.label(text="Multiply:")
|
||||
#~ col.prop(vpaint, "mul", text="")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
|
||||
bl_category = "Tools"
|
||||
bl_context = "vertexpaint"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_label = "Symmetry"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
toolsettings = context.tool_settings
|
||||
vpaint = toolsettings.vertex_paint
|
||||
draw_vpaint_symmetry(layout, vpaint)
|
||||
|
||||
|
||||
# ********** default tools for texture-paint ****************
|
||||
|
||||
|
||||
@ -2058,8 +2102,10 @@ classes = (
|
||||
VIEW3D_PT_sculpt_symmetry,
|
||||
VIEW3D_PT_tools_brush_appearance,
|
||||
VIEW3D_PT_tools_weightpaint,
|
||||
VIEW3D_PT_tools_weightpaint_symmetry,
|
||||
VIEW3D_PT_tools_weightpaint_options,
|
||||
VIEW3D_PT_tools_vertexpaint,
|
||||
VIEW3D_PT_tools_vertexpaint_symmetry,
|
||||
VIEW3D_PT_tools_imagepaint_external,
|
||||
VIEW3D_PT_tools_imagepaint_symmetry,
|
||||
VIEW3D_PT_tools_projectpaint,
|
||||
|
@ -160,6 +160,14 @@ void paint_update_brush_rake_rotation(struct UnifiedPaintSettings *ups, struct B
|
||||
|
||||
void BKE_paint_stroke_get_average(struct Scene *scene, struct Object *ob, float stroke[3]);
|
||||
|
||||
/* Used for both vertex color and weight paint */
|
||||
struct SculptVertexPaintGeomMap {
|
||||
int *vert_map_mem;
|
||||
struct MeshElemMap *vert_to_loop;
|
||||
int *poly_map_mem;
|
||||
struct MeshElemMap *vert_to_poly;
|
||||
};
|
||||
|
||||
/* Session data (mode-specific) */
|
||||
|
||||
typedef struct SculptSession {
|
||||
@ -205,10 +213,38 @@ typedef struct SculptSession {
|
||||
|
||||
struct SculptStroke *stroke;
|
||||
struct StrokeCache *cache;
|
||||
|
||||
union {
|
||||
struct {
|
||||
struct SculptVertexPaintGeomMap gmap;
|
||||
|
||||
/* For non-airbrush painting to re-apply from the original (MLoop aligned). */
|
||||
unsigned int *previous_color;
|
||||
} vpaint;
|
||||
|
||||
struct {
|
||||
struct SculptVertexPaintGeomMap gmap;
|
||||
|
||||
/* Vertex aligned arrays of weights. */
|
||||
/* For non-airbrush painting to re-apply from the original. */
|
||||
float *previous_weight;
|
||||
/* Keep track of how much each vertex has been painted (non-airbrush only). */
|
||||
float *alpha_weight;
|
||||
} wpaint;
|
||||
|
||||
//struct {
|
||||
//ToDo: identify sculpt-only fields
|
||||
//} sculpt;
|
||||
} mode;
|
||||
int mode_type;
|
||||
|
||||
/* This flag prevents PBVH from being freed when creating the vp_handle for texture paint. */
|
||||
bool building_vp_handle;
|
||||
} SculptSession;
|
||||
|
||||
void BKE_sculptsession_free(struct Object *ob);
|
||||
void BKE_sculptsession_free_deformMats(struct SculptSession *ss);
|
||||
void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss);
|
||||
void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
|
||||
void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
|
||||
void BKE_sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob,
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
struct CCGElem;
|
||||
struct CCGKey;
|
||||
struct CCGDerivedMesh;
|
||||
struct CustomData;
|
||||
struct DMFlagMat;
|
||||
struct MPoly;
|
||||
@ -71,7 +72,7 @@ void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
|
||||
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
|
||||
unsigned int **grid_hidden);
|
||||
void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, bool smooth_shading, struct BMLog *log, const int cd_vert_node_offset, const int cd_face_node_offset);
|
||||
|
||||
void BKE_pbvh_set_ccgdm(PBVH *bvh, struct CCGDerivedMesh *ccgdm);
|
||||
void BKE_pbvh_free(PBVH *bvh);
|
||||
void BKE_pbvh_free_layer_disp(PBVH *bvh);
|
||||
|
||||
@ -118,6 +119,7 @@ void BKE_pbvh_raycast_project_ray_root(
|
||||
void BKE_pbvh_node_draw(PBVHNode *node, void *data);
|
||||
void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
|
||||
int (*setMaterial)(int matnr, void *attribs), bool wireframe, bool fast);
|
||||
void BKE_pbvh_draw_BB(PBVH *bvh);
|
||||
|
||||
/* PBVH Access */
|
||||
typedef enum {
|
||||
@ -141,6 +143,7 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
|
||||
|
||||
/* multires level, only valid for type == PBVH_GRIDS */
|
||||
void BKE_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
|
||||
struct CCGDerivedMesh *BKE_pbvh_get_ccgdm(const PBVH *bvh);
|
||||
|
||||
/* Only valid for type == PBVH_BMESH */
|
||||
struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
|
||||
|
@ -2663,7 +2663,7 @@ static void mesh_build_data(
|
||||
ob->lastDataMask = dataMask;
|
||||
ob->lastNeedMapping = need_mapping;
|
||||
|
||||
if ((ob->mode & OB_MODE_SCULPT) && ob->sculpt) {
|
||||
if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
|
||||
/* create PBVH immediately (would be created on the fly too,
|
||||
* but this avoids waiting on first stroke) */
|
||||
|
||||
|
@ -662,6 +662,11 @@ static void cdDM_drawMappedFaces(
|
||||
|
||||
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
|
||||
|
||||
if (cddm->pbvh) {
|
||||
if (G.debug_value == 14)
|
||||
BKE_pbvh_draw_BB(cddm->pbvh);
|
||||
}
|
||||
|
||||
/* fist, setup common buffers */
|
||||
GPU_vertex_setup(dm);
|
||||
GPU_triangle_setup(dm);
|
||||
|
@ -2682,7 +2682,7 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
if (ss) {
|
||||
if (ss && ss->building_vp_handle == false) {
|
||||
if (!ss->cache) {
|
||||
/* we free pbvh on changes, except during sculpt since it can't deal with
|
||||
* changing PVBH node organization, we hope topology does not change in
|
||||
@ -2693,6 +2693,9 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
|
||||
}
|
||||
|
||||
BKE_sculptsession_free_deformMats(ob->sculpt);
|
||||
|
||||
/* In vertex/weight paint, force maps to be rebuilt. */
|
||||
BKE_sculptsession_free_vwpaint_data(ob->sculpt);
|
||||
}
|
||||
else {
|
||||
PBVHNode **nodes;
|
||||
|
@ -673,6 +673,29 @@ void BKE_sculptsession_free_deformMats(SculptSession *ss)
|
||||
MEM_SAFE_FREE(ss->deform_imats);
|
||||
}
|
||||
|
||||
void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
|
||||
{
|
||||
struct SculptVertexPaintGeomMap *gmap = NULL;
|
||||
if (ss->mode_type == OB_MODE_VERTEX_PAINT) {
|
||||
gmap = &ss->mode.vpaint.gmap;
|
||||
|
||||
MEM_SAFE_FREE(ss->mode.vpaint.previous_color);
|
||||
}
|
||||
else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) {
|
||||
gmap = &ss->mode.wpaint.gmap;
|
||||
|
||||
MEM_SAFE_FREE(ss->mode.wpaint.alpha_weight);
|
||||
MEM_SAFE_FREE(ss->mode.wpaint.previous_weight);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
MEM_SAFE_FREE(gmap->vert_to_loop);
|
||||
MEM_SAFE_FREE(gmap->vert_map_mem);
|
||||
MEM_SAFE_FREE(gmap->vert_to_poly);
|
||||
MEM_SAFE_FREE(gmap->poly_map_mem);
|
||||
}
|
||||
|
||||
/* Write out the sculpt dynamic-topology BMesh to the Mesh */
|
||||
static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
|
||||
{
|
||||
@ -714,10 +737,7 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object)
|
||||
*/
|
||||
BKE_object_free_derived_caches(object);
|
||||
|
||||
if (object->sculpt->pbvh) {
|
||||
BKE_pbvh_free(object->sculpt->pbvh);
|
||||
object->sculpt->pbvh = NULL;
|
||||
}
|
||||
MEM_SAFE_FREE(object->sculpt->pbvh);
|
||||
|
||||
sculptsession_bm_to_me_update_data_only(object, false);
|
||||
|
||||
@ -764,6 +784,8 @@ void BKE_sculptsession_free(Object *ob)
|
||||
if (ss->deform_imats)
|
||||
MEM_freeN(ss->deform_imats);
|
||||
|
||||
BKE_sculptsession_free_vwpaint_data(ob->sculpt);
|
||||
|
||||
MEM_freeN(ss);
|
||||
|
||||
ob->sculpt = NULL;
|
||||
@ -848,6 +870,8 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
|
||||
ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob);
|
||||
ss->show_diffuse_color = (sd->flags & SCULPT_SHOW_DIFFUSE) != 0;
|
||||
|
||||
ss->building_vp_handle = false;
|
||||
|
||||
if (need_mask) {
|
||||
if (mmd == NULL) {
|
||||
if (!CustomData_has_layer(&me->vdata, CD_PAINT_MASK)) {
|
||||
@ -876,7 +900,8 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
|
||||
|
||||
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
||||
|
||||
if (mmd) {
|
||||
/* VWPaint require mesh info for loop lookup, so require sculpt mode here */
|
||||
if (mmd && ob->mode & OB_MODE_SCULPT) {
|
||||
ss->multires = mmd;
|
||||
ss->totvert = dm->getNumVerts(dm);
|
||||
ss->totpoly = dm->getNumPolys(dm);
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_subsurf.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mesh.h" /* for BKE_mesh_calc_normals */
|
||||
@ -606,6 +607,10 @@ void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids,
|
||||
MEM_freeN(prim_bbc);
|
||||
}
|
||||
|
||||
void BKE_pbvh_set_ccgdm(PBVH *bvh, CCGDerivedMesh *ccgdm) {
|
||||
bvh->ccgdm = ccgdm;
|
||||
}
|
||||
|
||||
PBVH *BKE_pbvh_new(void)
|
||||
{
|
||||
PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
|
||||
@ -1156,7 +1161,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
||||
}
|
||||
}
|
||||
|
||||
static void pbvh_draw_BB(PBVH *bvh)
|
||||
void BKE_pbvh_draw_BB(PBVH *bvh)
|
||||
{
|
||||
GPU_pbvh_BB_draw_init();
|
||||
|
||||
@ -1329,6 +1334,11 @@ void BKE_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
|
||||
*key = bvh->gridkey;
|
||||
}
|
||||
|
||||
CCGDerivedMesh *BKE_pbvh_get_ccgdm(const PBVH *bvh) {
|
||||
return bvh->ccgdm;
|
||||
}
|
||||
|
||||
|
||||
BMesh *BKE_pbvh_get_bmesh(PBVH *bvh)
|
||||
{
|
||||
BLI_assert(bvh->type == PBVH_BMESH);
|
||||
@ -1860,7 +1870,7 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*fnors)[3],
|
||||
}
|
||||
|
||||
if (G.debug_value == 14)
|
||||
pbvh_draw_BB(bvh);
|
||||
BKE_pbvh_draw_BB(bvh);
|
||||
}
|
||||
|
||||
void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, void **gridfaces,
|
||||
|
@ -149,6 +149,8 @@ struct PBVH {
|
||||
* objects in sculpt mode with different sizes at the same time, so now storing that common gpu buffer
|
||||
* in an opaque pointer per pbvh. See T47637. */
|
||||
struct GridCommonGPUBuffer *grid_common_gpu_buffer;
|
||||
/* The ccgdm is required for CD_ORIGINDEX lookup in vertex paint + multires */
|
||||
struct CCGDerivedMesh *ccgdm;
|
||||
|
||||
/* Only used during BVH build and update,
|
||||
* don't need to remain valid after */
|
||||
|
@ -217,16 +217,10 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
|
||||
ToolSettings *ts = sce_dst->toolsettings = MEM_dupallocN(sce_dst->toolsettings);
|
||||
if (ts->vpaint) {
|
||||
ts->vpaint = MEM_dupallocN(ts->vpaint);
|
||||
ts->vpaint->paintcursor = NULL;
|
||||
ts->vpaint->vpaint_prev = NULL;
|
||||
ts->vpaint->wpaint_prev = NULL;
|
||||
BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, flag_subdata);
|
||||
}
|
||||
if (ts->wpaint) {
|
||||
ts->wpaint = MEM_dupallocN(ts->wpaint);
|
||||
ts->wpaint->paintcursor = NULL;
|
||||
ts->wpaint->vpaint_prev = NULL;
|
||||
ts->wpaint->wpaint_prev = NULL;
|
||||
BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, flag_subdata);
|
||||
}
|
||||
if (ts->sculpt) {
|
||||
@ -335,16 +329,10 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
||||
if (ts) {
|
||||
if (ts->vpaint) {
|
||||
ts->vpaint = MEM_dupallocN(ts->vpaint);
|
||||
ts->vpaint->paintcursor = NULL;
|
||||
ts->vpaint->vpaint_prev = NULL;
|
||||
ts->vpaint->wpaint_prev = NULL;
|
||||
BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, 0);
|
||||
}
|
||||
if (ts->wpaint) {
|
||||
ts->wpaint = MEM_dupallocN(ts->wpaint);
|
||||
ts->wpaint->paintcursor = NULL;
|
||||
ts->wpaint->vpaint_prev = NULL;
|
||||
ts->wpaint->wpaint_prev = NULL;
|
||||
BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, 0);
|
||||
}
|
||||
if (ts->sculpt) {
|
||||
|
@ -3683,6 +3683,11 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
|
||||
int gridFaces = gridSize - 1, totface;
|
||||
int prev_mat_nr = -1;
|
||||
|
||||
if (ccgdm->pbvh) {
|
||||
if (G.debug_value == 14)
|
||||
BKE_pbvh_draw_BB(ccgdm->pbvh);
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENSUBDIV
|
||||
if (ccgdm->useGpuBackend) {
|
||||
int new_matnr;
|
||||
@ -4416,7 +4421,8 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
|
||||
if (!ob->sculpt)
|
||||
return NULL;
|
||||
|
||||
grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
|
||||
/* In vwpaint, we always use a grid_pbvh for multires/subsurf */
|
||||
grid_pbvh = (!(ob->mode & OB_MODE_SCULPT) || ccgDM_use_grid_pbvh(ccgdm));
|
||||
|
||||
if (ob->sculpt->pbvh) {
|
||||
if (grid_pbvh) {
|
||||
@ -4432,12 +4438,18 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
|
||||
ccgdm->pbvh = ob->sculpt->pbvh;
|
||||
}
|
||||
|
||||
if (ccgdm->pbvh)
|
||||
if (ccgdm->pbvh) {
|
||||
/* For vertex paint, keep track of ccgdm */
|
||||
if (!(ob->mode & OB_MODE_SCULPT)) {
|
||||
BKE_pbvh_set_ccgdm(ccgdm->pbvh, ccgdm);
|
||||
}
|
||||
return ccgdm->pbvh;
|
||||
}
|
||||
|
||||
/* no pbvh exists yet, we need to create one. only in case of multires
|
||||
* we build a pbvh over the modified mesh, in other cases the base mesh
|
||||
* is being sculpted, so we build a pbvh from that. */
|
||||
/* Note: vwpaint always builds a pbvh over the modified mesh. */
|
||||
if (grid_pbvh) {
|
||||
ccgdm_create_grids(dm);
|
||||
|
||||
@ -4468,6 +4480,10 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
|
||||
if (ccgdm->pbvh)
|
||||
pbvh_show_diffuse_color_set(ccgdm->pbvh, ob->sculpt->show_diffuse_color);
|
||||
|
||||
/* For vertex paint, keep track of ccgdm */
|
||||
if (!(ob->mode & OB_MODE_SCULPT) && ccgdm->pbvh) {
|
||||
BKE_pbvh_set_ccgdm(ccgdm->pbvh, ccgdm);
|
||||
}
|
||||
return ccgdm->pbvh;
|
||||
}
|
||||
|
||||
|
@ -6004,16 +6004,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
sce->toolsettings->particle.object = NULL;
|
||||
sce->toolsettings->gp_sculpt.paintcursor = NULL;
|
||||
|
||||
/* in rare cases this is needed, see [#33806] */
|
||||
if (sce->toolsettings->vpaint) {
|
||||
sce->toolsettings->vpaint->vpaint_prev = NULL;
|
||||
sce->toolsettings->vpaint->tot = 0;
|
||||
}
|
||||
if (sce->toolsettings->wpaint) {
|
||||
sce->toolsettings->wpaint->wpaint_prev = NULL;
|
||||
sce->toolsettings->wpaint->tot = 0;
|
||||
}
|
||||
|
||||
/* relink grease pencil drawing brushes */
|
||||
link_list(fd, &sce->toolsettings->gp_brushes);
|
||||
for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) {
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "DNA_genfile.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
@ -1681,6 +1682,24 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Brush *br;
|
||||
br = (Brush *)BKE_libblock_find_name_ex(main, ID_BR, "Average");
|
||||
if (!br) {
|
||||
br = BKE_brush_add(main, "Average", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT);
|
||||
br->vertexpaint_tool = PAINT_BLEND_AVERAGE;
|
||||
br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT;
|
||||
}
|
||||
|
||||
br = (Brush *)BKE_libblock_find_name_ex(main, ID_BR, "Smear");
|
||||
if (!br) {
|
||||
br = BKE_brush_add(main, "Smear", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT);
|
||||
br->vertexpaint_tool = PAINT_BLEND_SMEAR;
|
||||
br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,16 @@ void BLO_update_defaults_startup_blend(Main *bmain)
|
||||
sculpt->detail_size = 12;
|
||||
}
|
||||
|
||||
if (ts->vpaint) {
|
||||
VPaint *vp = ts->vpaint;
|
||||
vp->radial_symm[0] = vp->radial_symm[1] = vp->radial_symm[2] = 1;
|
||||
}
|
||||
|
||||
if (ts->wpaint) {
|
||||
VPaint *wp = ts->wpaint;
|
||||
wp->radial_symm[0] = wp->radial_symm[1] = wp->radial_symm[2] = 1;
|
||||
}
|
||||
|
||||
if (ts->gp_sculpt.brush[0].size == 0) {
|
||||
GP_BrushEdit_Settings *gset = &ts->gp_sculpt;
|
||||
GP_EditBrush_Data *brush;
|
||||
|
@ -1448,7 +1448,20 @@ void PAINT_OT_texture_paint_toggle(wmOperatorType *ot)
|
||||
static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
|
||||
Brush *br = image_paint_brush(C);
|
||||
|
||||
Brush *br;
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
if (!(ob && (ob->mode & OB_MODE_VERTEX_PAINT))) {
|
||||
br = image_paint_brush(C);
|
||||
}
|
||||
else {
|
||||
/* At the moment, wpaint does not support the color flipper.
|
||||
* So for now we're only handling vpaint */
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
VPaint *vp = ts->vpaint;
|
||||
br = BKE_paint_brush(&vp->paint);
|
||||
}
|
||||
|
||||
if (ups->flag & UNIFIED_PAINT_COLOR) {
|
||||
swap_v3_v3(ups->rgb, ups->secondary_rgb);
|
||||
}
|
||||
@ -1467,7 +1480,12 @@ static int brush_colors_flip_poll(bContext *C)
|
||||
if (br->imagepaint_tool == PAINT_TOOL_DRAW)
|
||||
return 1;
|
||||
}
|
||||
|
||||
else {
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
if (ob && (ob->mode & OB_MODE_VERTEX_PAINT)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ int vertex_paint_poll(struct bContext *C);
|
||||
int vertex_paint_mode_poll(struct bContext *C);
|
||||
|
||||
bool ED_vpaint_fill(struct Object *ob, unsigned int paintcol);
|
||||
bool ED_wpaint_fill(struct VPaint *wp, struct Object *ob, float paintweight);
|
||||
bool ED_wpaint_fill(struct Object *ob, float paintweight);
|
||||
|
||||
bool ED_vpaint_smooth(struct Object *ob);
|
||||
|
||||
|
@ -1613,6 +1613,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
keymap->poll = vertex_paint_mode_poll;
|
||||
|
||||
WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "PAINT_OT_brush_colors_flip", XKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "PAINT_OT_sample_color", SKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,6 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_dial.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
@ -165,111 +164,12 @@ static bool sculpt_brush_needs_rake_rotation(const Brush *brush)
|
||||
return SCULPT_TOOL_HAS_RAKE(brush->sculpt_tool) && (brush->rake_factor != 0.0f);
|
||||
}
|
||||
|
||||
/* Factor of brush to have rake point following behind
|
||||
* (could be configurable but this is reasonable default). */
|
||||
#define SCULPT_RAKE_BRUSH_FACTOR 0.25f
|
||||
|
||||
struct SculptRakeData {
|
||||
float follow_dist;
|
||||
float follow_co[3];
|
||||
};
|
||||
|
||||
typedef enum StrokeFlags {
|
||||
CLIP_X = 1,
|
||||
CLIP_Y = 2,
|
||||
CLIP_Z = 4
|
||||
} StrokeFlags;
|
||||
|
||||
/* Cache stroke properties. Used because
|
||||
* RNA property lookup isn't particularly fast.
|
||||
*
|
||||
* For descriptions of these settings, check the operator properties.
|
||||
*/
|
||||
typedef struct StrokeCache {
|
||||
/* Invariants */
|
||||
float initial_radius;
|
||||
float scale[3];
|
||||
int flag;
|
||||
float clip_tolerance[3];
|
||||
float initial_mouse[2];
|
||||
|
||||
/* Variants */
|
||||
float radius;
|
||||
float radius_squared;
|
||||
float true_location[3];
|
||||
float location[3];
|
||||
|
||||
bool pen_flip;
|
||||
bool invert;
|
||||
float pressure;
|
||||
float mouse[2];
|
||||
float bstrength;
|
||||
float normal_weight; /* from brush (with optional override) */
|
||||
|
||||
/* The rest is temporary storage that isn't saved as a property */
|
||||
|
||||
bool first_time; /* Beginning of stroke may do some things special */
|
||||
|
||||
/* from ED_view3d_ob_project_mat_get() */
|
||||
float projection_mat[4][4];
|
||||
|
||||
/* Clean this up! */
|
||||
ViewContext *vc;
|
||||
Brush *brush;
|
||||
|
||||
float special_rotation;
|
||||
float grab_delta[3], grab_delta_symmetry[3];
|
||||
float old_grab_location[3], orig_grab_location[3];
|
||||
|
||||
/* screen-space rotation defined by mouse motion */
|
||||
float rake_rotation[4], rake_rotation_symmetry[4];
|
||||
bool is_rake_rotation_valid;
|
||||
struct SculptRakeData rake_data;
|
||||
|
||||
int symmetry; /* Symmetry index between 0 and 7 bit combo 0 is Brush only;
|
||||
* 1 is X mirror; 2 is Y mirror; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
|
||||
int mirror_symmetry_pass; /* the symmetry pass we are currently on between 0 and 7*/
|
||||
float true_view_normal[3];
|
||||
float view_normal[3];
|
||||
|
||||
/* sculpt_normal gets calculated by calc_sculpt_normal(), then the
|
||||
* sculpt_normal_symm gets updated quickly with the usual symmetry
|
||||
* transforms */
|
||||
float sculpt_normal[3];
|
||||
float sculpt_normal_symm[3];
|
||||
|
||||
/* Used for area texture mode, local_mat gets calculated by
|
||||
* calc_brush_local_mat() and used in tex_strength(). */
|
||||
float brush_local_mat[4][4];
|
||||
|
||||
float plane_offset[3]; /* used to shift the plane around when doing tiled strokes */
|
||||
int tile_pass;
|
||||
|
||||
float last_center[3];
|
||||
int radial_symmetry_pass;
|
||||
float symm_rot_mat[4][4];
|
||||
float symm_rot_mat_inv[4][4];
|
||||
bool original;
|
||||
float anchored_location[3];
|
||||
|
||||
float vertex_rotation; /* amount to rotate the vertices when using rotate brush */
|
||||
Dial *dial;
|
||||
|
||||
char saved_active_brush_name[MAX_ID_NAME];
|
||||
char saved_mask_brush_tool;
|
||||
int saved_smooth_size; /* smooth tool copies the size of the current tool */
|
||||
bool alt_smooth;
|
||||
|
||||
float plane_trim_squared;
|
||||
|
||||
bool supports_gravity;
|
||||
float true_gravity_direction[3];
|
||||
float gravity_direction[3];
|
||||
|
||||
rcti previous_r; /* previous redraw rectangle */
|
||||
rcti current_r; /* current redraw rectangle */
|
||||
} StrokeCache;
|
||||
|
||||
/************** Access to original unmodified vertex data *************/
|
||||
|
||||
typedef struct {
|
||||
@ -476,41 +376,6 @@ static bool sculpt_stroke_is_dynamic_topology(
|
||||
|
||||
/*** paint mesh ***/
|
||||
|
||||
/* Single struct used by all BLI_task threaded callbacks, let's avoid adding 10's of those... */
|
||||
typedef struct SculptThreadedTaskData {
|
||||
Sculpt *sd;
|
||||
Object *ob;
|
||||
Brush *brush;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
/* Data specific to some callbacks. */
|
||||
/* Note: even if only one or two of those are used at a time, keeping them separated, names help figuring out
|
||||
* what it is, and memory overhead is ridiculous anyway... */
|
||||
float flippedbstrength;
|
||||
float angle;
|
||||
float strength;
|
||||
bool smooth_mask;
|
||||
bool has_bm_orco;
|
||||
|
||||
SculptProjectVector *spvc;
|
||||
float *offset;
|
||||
float *grab_delta;
|
||||
float *cono;
|
||||
float *area_no;
|
||||
float *area_no_sp;
|
||||
float *area_co;
|
||||
float (*mat)[4];
|
||||
float (*vertCos)[3];
|
||||
|
||||
/* 0=towards view, 1=flipped */
|
||||
float (*area_cos)[3];
|
||||
float (*area_nos)[3];
|
||||
int *count;
|
||||
|
||||
ThreadMutex mutex;
|
||||
} SculptThreadedTaskData;
|
||||
|
||||
static void paint_mesh_restore_co_task_cb(void *userdata, const int n)
|
||||
{
|
||||
SculptThreadedTaskData *data = userdata;
|
||||
@ -600,7 +465,7 @@ static void sculpt_extend_redraw_rect_previous(Object *ob, rcti *rect)
|
||||
}
|
||||
|
||||
/* Get a screen-space rectangle of the modified area */
|
||||
static bool sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
|
||||
bool sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
|
||||
Object *ob, rcti *rect)
|
||||
{
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
@ -650,17 +515,7 @@ void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar,
|
||||
|
||||
/************************ Brush Testing *******************/
|
||||
|
||||
typedef struct SculptBrushTest {
|
||||
float radius_squared;
|
||||
float location[3];
|
||||
float dist;
|
||||
int mirror_symmetry_pass;
|
||||
|
||||
/* View3d clipping - only set rv3d for clipping */
|
||||
RegionView3D *clip_rv3d;
|
||||
} SculptBrushTest;
|
||||
|
||||
static void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test)
|
||||
void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test)
|
||||
{
|
||||
RegionView3D *rv3d = ss->cache->vc->rv3d;
|
||||
|
||||
@ -689,7 +544,7 @@ BLI_INLINE bool sculpt_brush_test_clipping(const SculptBrushTest *test, const fl
|
||||
return ED_view3d_clipping_test(rv3d, symm_co, true);
|
||||
}
|
||||
|
||||
static bool sculpt_brush_test(SculptBrushTest *test, const float co[3])
|
||||
bool sculpt_brush_test(SculptBrushTest *test, const float co[3])
|
||||
{
|
||||
float distsq = len_squared_v3v3(co, test->location);
|
||||
|
||||
@ -705,7 +560,7 @@ static bool sculpt_brush_test(SculptBrushTest *test, const float co[3])
|
||||
}
|
||||
}
|
||||
|
||||
static bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
|
||||
bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
|
||||
{
|
||||
float distsq = len_squared_v3v3(co, test->location);
|
||||
|
||||
@ -721,7 +576,7 @@ static bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
|
||||
}
|
||||
}
|
||||
|
||||
static bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3])
|
||||
bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3])
|
||||
{
|
||||
if (sculpt_brush_test_clipping(test, co)) {
|
||||
return 0;
|
||||
@ -729,7 +584,7 @@ static bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3
|
||||
return len_squared_v3v3(co, test->location) <= test->radius_squared;
|
||||
}
|
||||
|
||||
static bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4])
|
||||
bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4])
|
||||
{
|
||||
float side = M_SQRT1_2;
|
||||
float local_co[3];
|
||||
@ -1237,7 +1092,7 @@ static float brush_strength(
|
||||
}
|
||||
|
||||
/* Return a multiplier for brush strength on a particular vertex. */
|
||||
static float tex_strength(SculptSession *ss, Brush *br,
|
||||
float tex_strength(SculptSession *ss, Brush *br,
|
||||
const float brush_point[3],
|
||||
const float len,
|
||||
const short vno[3],
|
||||
@ -1316,15 +1171,8 @@ static float tex_strength(SculptSession *ss, Brush *br,
|
||||
return avg;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Sculpt *sd;
|
||||
SculptSession *ss;
|
||||
float radius_squared;
|
||||
bool original;
|
||||
} SculptSearchSphereData;
|
||||
|
||||
/* Test AABB against sphere */
|
||||
static bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v)
|
||||
bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v)
|
||||
{
|
||||
SculptSearchSphereData *data = data_v;
|
||||
float *center = data->ss->cache->location, nearest[3];
|
||||
@ -1632,6 +1480,22 @@ typedef struct SculptDoBrushSmoothGridDataChunk {
|
||||
size_t tmpgrid_size;
|
||||
} SculptDoBrushSmoothGridDataChunk;
|
||||
|
||||
typedef struct {
|
||||
SculptSession *ss;
|
||||
const float *ray_start, *ray_normal;
|
||||
bool hit;
|
||||
float dist;
|
||||
bool original;
|
||||
PBVHNode* node;
|
||||
} SculptRaycastData;
|
||||
|
||||
typedef struct {
|
||||
const float *ray_start, *ray_normal;
|
||||
bool hit;
|
||||
float dist;
|
||||
float detail;
|
||||
} SculptDetailRaycastData;
|
||||
|
||||
static void do_smooth_brush_mesh_task_cb_ex(
|
||||
void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id)
|
||||
{
|
||||
@ -3948,7 +3812,7 @@ static const char *sculpt_tool_name(Sculpt *sd)
|
||||
* Operator for applying a stroke (various attributes including mouse path)
|
||||
* using the current brush. */
|
||||
|
||||
static void sculpt_cache_free(StrokeCache *cache)
|
||||
void sculpt_cache_free(StrokeCache *cache)
|
||||
{
|
||||
if (cache->dial)
|
||||
MEM_freeN(cache->dial);
|
||||
@ -4398,21 +4262,6 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob)
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
SculptSession *ss;
|
||||
const float *ray_start, *ray_normal;
|
||||
bool hit;
|
||||
float dist;
|
||||
bool original;
|
||||
} SculptRaycastData;
|
||||
|
||||
typedef struct {
|
||||
const float *ray_start, *ray_normal;
|
||||
bool hit;
|
||||
float dist;
|
||||
float detail;
|
||||
} SculptDetailRaycastData;
|
||||
|
||||
static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
|
||||
{
|
||||
if (BKE_pbvh_node_get_tmin(node) < *tmin) {
|
||||
@ -4437,6 +4286,9 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
|
||||
{
|
||||
srd->hit = 1;
|
||||
*tmin = srd->dist;
|
||||
|
||||
//for vwpaint testing
|
||||
srd->node = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4527,6 +4379,11 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
|
||||
mul_v3_fl(out, srd.dist);
|
||||
add_v3_v3(out, ray_start);
|
||||
|
||||
//used in vwpaint
|
||||
if (cache && srd.hit){
|
||||
copy_v3_v3(cache->true_location, out);
|
||||
}
|
||||
|
||||
return srd.hit;
|
||||
}
|
||||
|
||||
|
@ -38,12 +38,15 @@
|
||||
#include "DNA_key_types.h"
|
||||
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "BKE_pbvh.h"
|
||||
|
||||
struct bContext;
|
||||
struct KeyBlock;
|
||||
struct Object;
|
||||
struct SculptUndoNode;
|
||||
struct SculptOrigVertData;
|
||||
|
||||
int sculpt_mode_poll(struct bContext *C);
|
||||
int sculpt_mode_poll_view3d(struct bContext *C);
|
||||
@ -115,6 +118,194 @@ typedef struct SculptUndoNode {
|
||||
char shapeName[sizeof(((KeyBlock *)0))->name];
|
||||
} SculptUndoNode;
|
||||
|
||||
/* Factor of brush to have rake point following behind
|
||||
* (could be configurable but this is reasonable default). */
|
||||
#define SCULPT_RAKE_BRUSH_FACTOR 0.25f
|
||||
|
||||
struct SculptRakeData {
|
||||
float follow_dist;
|
||||
float follow_co[3];
|
||||
};
|
||||
|
||||
/* Single struct used by all BLI_task threaded callbacks, let's avoid adding 10's of those... */
|
||||
typedef struct SculptThreadedTaskData {
|
||||
bContext *C;
|
||||
struct Sculpt *sd;
|
||||
struct Object *ob;
|
||||
struct Brush *brush;
|
||||
struct PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
struct VPaint *vp;
|
||||
struct VPaintData *vpd;
|
||||
struct WPaintData *wpd;
|
||||
struct WeightPaintInfo *wpi;
|
||||
unsigned int *lcol;
|
||||
struct Mesh *me;
|
||||
/* For passing generic params. */
|
||||
void *custom_data;
|
||||
|
||||
|
||||
/* Data specific to some callbacks. */
|
||||
/* Note: even if only one or two of those are used at a time, keeping them separated, names help figuring out
|
||||
* what it is, and memory overhead is ridiculous anyway... */
|
||||
float flippedbstrength;
|
||||
float angle;
|
||||
float strength;
|
||||
bool smooth_mask;
|
||||
bool has_bm_orco;
|
||||
|
||||
struct SculptProjectVector *spvc;
|
||||
float *offset;
|
||||
float *grab_delta;
|
||||
float *cono;
|
||||
float *area_no;
|
||||
float *area_no_sp;
|
||||
float *area_co;
|
||||
float(*mat)[4];
|
||||
float(*vertCos)[3];
|
||||
|
||||
/* 0=towards view, 1=flipped */
|
||||
float(*area_cos)[3];
|
||||
float(*area_nos)[3];
|
||||
int *count;
|
||||
|
||||
ThreadMutex mutex;
|
||||
|
||||
} SculptThreadedTaskData;
|
||||
|
||||
/*************** Brush testing declarations ****************/
|
||||
typedef struct SculptBrushTest {
|
||||
float radius_squared;
|
||||
float location[3];
|
||||
float dist;
|
||||
int mirror_symmetry_pass;
|
||||
|
||||
/* View3d clipping - only set rv3d for clipping */
|
||||
struct RegionView3D *clip_rv3d;
|
||||
} SculptBrushTest;
|
||||
|
||||
typedef struct {
|
||||
struct Sculpt *sd;
|
||||
struct SculptSession *ss;
|
||||
float radius_squared;
|
||||
bool original;
|
||||
} SculptSearchSphereData;
|
||||
|
||||
void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test);
|
||||
bool sculpt_brush_test(SculptBrushTest *test, const float co[3]);
|
||||
bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3]);
|
||||
bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3]);
|
||||
bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4]);
|
||||
bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v);
|
||||
float tex_strength(
|
||||
SculptSession *ss, struct Brush *br,
|
||||
const float point[3],
|
||||
const float len,
|
||||
const short vno[3],
|
||||
const float fno[3],
|
||||
const float mask,
|
||||
const int thread_id);
|
||||
|
||||
|
||||
/* Cache stroke properties. Used because
|
||||
* RNA property lookup isn't particularly fast.
|
||||
*
|
||||
* For descriptions of these settings, check the operator properties.
|
||||
*/
|
||||
|
||||
typedef struct StrokeCache {
|
||||
/* Invariants */
|
||||
float initial_radius;
|
||||
float scale[3];
|
||||
int flag;
|
||||
float clip_tolerance[3];
|
||||
float initial_mouse[2];
|
||||
|
||||
/* Variants */
|
||||
float radius;
|
||||
float radius_squared;
|
||||
float true_location[3];
|
||||
float true_last_location[3];
|
||||
float location[3];
|
||||
float last_location[3];
|
||||
bool is_last_valid;
|
||||
|
||||
bool pen_flip;
|
||||
bool invert;
|
||||
float pressure;
|
||||
float mouse[2];
|
||||
float bstrength;
|
||||
float normal_weight; /* from brush (with optional override) */
|
||||
|
||||
/* The rest is temporary storage that isn't saved as a property */
|
||||
|
||||
bool first_time; /* Beginning of stroke may do some things special */
|
||||
|
||||
/* from ED_view3d_ob_project_mat_get() */
|
||||
float projection_mat[4][4];
|
||||
|
||||
/* Clean this up! */
|
||||
struct ViewContext *vc;
|
||||
struct Brush *brush;
|
||||
|
||||
float special_rotation;
|
||||
float grab_delta[3], grab_delta_symmetry[3];
|
||||
float old_grab_location[3], orig_grab_location[3];
|
||||
|
||||
/* screen-space rotation defined by mouse motion */
|
||||
float rake_rotation[4], rake_rotation_symmetry[4];
|
||||
bool is_rake_rotation_valid;
|
||||
struct SculptRakeData rake_data;
|
||||
|
||||
/* Symmetry index between 0 and 7 bit combo 0 is Brush only;
|
||||
* 1 is X mirror; 2 is Y mirror; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
|
||||
int symmetry;
|
||||
int mirror_symmetry_pass; /* the symmetry pass we are currently on between 0 and 7*/
|
||||
float true_view_normal[3];
|
||||
float view_normal[3];
|
||||
|
||||
/* sculpt_normal gets calculated by calc_sculpt_normal(), then the
|
||||
* sculpt_normal_symm gets updated quickly with the usual symmetry
|
||||
* transforms */
|
||||
float sculpt_normal[3];
|
||||
float sculpt_normal_symm[3];
|
||||
|
||||
/* Used for area texture mode, local_mat gets calculated by
|
||||
* calc_brush_local_mat() and used in tex_strength(). */
|
||||
float brush_local_mat[4][4];
|
||||
|
||||
float plane_offset[3]; /* used to shift the plane around when doing tiled strokes */
|
||||
int tile_pass;
|
||||
|
||||
float last_center[3];
|
||||
int radial_symmetry_pass;
|
||||
float symm_rot_mat[4][4];
|
||||
float symm_rot_mat_inv[4][4];
|
||||
bool original;
|
||||
float anchored_location[3];
|
||||
|
||||
float vertex_rotation; /* amount to rotate the vertices when using rotate brush */
|
||||
struct Dial *dial;
|
||||
|
||||
char saved_active_brush_name[MAX_ID_NAME];
|
||||
char saved_mask_brush_tool;
|
||||
int saved_smooth_size; /* smooth tool copies the size of the current tool */
|
||||
bool alt_smooth;
|
||||
|
||||
float plane_trim_squared;
|
||||
|
||||
bool supports_gravity;
|
||||
float true_gravity_direction[3];
|
||||
float gravity_direction[3];
|
||||
|
||||
rcti previous_r; /* previous redraw rectangle */
|
||||
rcti current_r; /* current redraw rectangle */
|
||||
|
||||
} StrokeCache;
|
||||
|
||||
void sculpt_cache_free(StrokeCache *cache);
|
||||
|
||||
SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type);
|
||||
SculptUndoNode *sculpt_undo_get_node(PBVHNode *node);
|
||||
void sculpt_undo_push_begin(const char *name);
|
||||
@ -124,6 +315,8 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]);
|
||||
|
||||
void sculpt_update_object_bounding_box(struct Object *ob);
|
||||
|
||||
bool sculpt_get_redraw_rect(struct ARegion *ar, struct RegionView3D *rv3d, Object *ob, rcti *rect);
|
||||
|
||||
#define SCULPT_THREADED_LIMIT 4
|
||||
|
||||
#endif
|
||||
|
@ -315,7 +315,9 @@ enum {
|
||||
PAINT_BLEND_MUL = 3,
|
||||
PAINT_BLEND_BLUR = 4,
|
||||
PAINT_BLEND_LIGHTEN = 5,
|
||||
PAINT_BLEND_DARKEN = 6
|
||||
PAINT_BLEND_DARKEN = 6,
|
||||
PAINT_BLEND_AVERAGE = 7,
|
||||
PAINT_BLEND_SMEAR = 8,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
@ -683,6 +683,9 @@ typedef enum ObjectMode {
|
||||
/* any mode where the brush system is used */
|
||||
#define OB_MODE_ALL_PAINT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)
|
||||
|
||||
/* any mode that uses ob->sculpt */
|
||||
#define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)
|
||||
|
||||
#define MAX_DUPLI_RECUR 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1117,13 +1117,8 @@ typedef struct UvSculpt {
|
||||
/* Vertex Paint */
|
||||
typedef struct VPaint {
|
||||
Paint paint;
|
||||
|
||||
short flag, pad;
|
||||
int tot; /* allocation size of prev buffers */
|
||||
unsigned int *vpaint_prev; /* previous mesh colors */
|
||||
struct MDeformVert *wpaint_prev; /* previous vertex weights */
|
||||
|
||||
void *paintcursor; /* wm handle */
|
||||
int radial_symm[3]; /* For mirrored painting */
|
||||
} VPaint;
|
||||
|
||||
/* VPaint.flag */
|
||||
|
@ -94,6 +94,8 @@ EnumPropertyItem rna_enum_brush_vertex_tool_items[] = {
|
||||
{PAINT_BLEND_BLUR, "BLUR", ICON_BRUSH_BLUR, "Blur", "Blur the color with surrounding values"},
|
||||
{PAINT_BLEND_LIGHTEN, "LIGHTEN", ICON_BRUSH_LIGHTEN, "Lighten", "Use lighten blending mode while painting"},
|
||||
{PAINT_BLEND_DARKEN, "DARKEN", ICON_BRUSH_DARKEN, "Darken", "Use darken blending mode while painting"},
|
||||
{PAINT_BLEND_AVERAGE, "AVERAGE", ICON_BRUSH_BLUR, "Average", "Use average blending mode while painting" },
|
||||
{PAINT_BLEND_SMEAR, "SMEAR", ICON_BRUSH_BLUR, "Smear", "Use smear blending mode while painting" },
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -687,6 +687,15 @@ static void rna_def_vertex_paint(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_ONLYVGROUP);
|
||||
RNA_def_property_ui_text(prop, "Restrict", "Restrict painting to vertices in the group");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
/* Mirroring */
|
||||
prop = RNA_def_property(srna, "radial_symmetry", PROP_INT, PROP_XYZ);
|
||||
RNA_def_property_int_sdna(prop, NULL, "radial_symm");
|
||||
RNA_def_property_int_default(prop, 1);
|
||||
RNA_def_property_range(prop, 1, 64);
|
||||
RNA_def_property_ui_range(prop, 1, 32, 1, 1);
|
||||
RNA_def_property_ui_text(prop, "Radial Symmetry Count X Axis",
|
||||
"Number of times to copy strokes across the surface");
|
||||
}
|
||||
|
||||
static void rna_def_image_paint(BlenderRNA *brna)
|
||||
|
Loading…
Reference in New Issue
Block a user