commit_log.txt

This commit is contained in:
Joseph Eagar 2021-12-11 00:20:33 -08:00
parent 744361a1af
commit 4a1d90ade7
32 changed files with 2953 additions and 2074 deletions

Binary file not shown.

View File

@ -595,6 +595,8 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
else:
col.operator("mesh.customdata_custom_splitnormals_add", icon='ADD')
col.operator("mesh.customdata_ids_clear", icon='X')
col = layout.column(heading="Store")
col.enabled = obj is not None and obj.mode != 'EDIT'

View File

@ -515,6 +515,9 @@ class VIEW3D_PT_tools_persistent_base_channels(Panel, View3DPaintPanel):
@classmethod
def poll(cls, context):
settings = cls.paint_settings(context)
if not settings:
return False
brush = settings.brush
ch = UnifiedPaintPanel.get_channel(context, brush, "use_persistent")

View File

@ -1 +1,89 @@
/*
* 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) Blender Foundation.
* All rights reserved.
*/
#pragma once
/** \file
* \ingroup bke
*/
#include "BKE_bvhutils.h"
#include "BLI_bitmap.h"
#include "BLI_math_matrix.h"
struct Scene;
struct Mesh;
struct BassReliefModifierData;
struct Object;
struct MDeformVert;
struct ModifierEvalContext;
struct MPropCol;
#define MAX_BASSRELIEF_DEBUG_COLORS 7
#ifdef __cplusplus
extern "C" {
#endif
/* Information about a mesh and BVH tree. */
typedef struct BassReliefTreeData {
Mesh *mesh;
BVHTree *bvh;
BVHTreeFromMesh treeData;
struct SpaceTransform transform;
float keepDist;
float (*pnors)[3];
float (*clnors)[3];
} BassReliefTreeData;
void bassReliefModifier_deform(struct BassReliefModifierData *smd,
const struct ModifierEvalContext *ctx,
struct Scene *scene,
struct Object *ob,
struct Mesh *mesh,
struct MDeformVert *dvert,
const int defgrp_index,
float (*vertexCos)[3],
int numVerts,
struct MPropCol *debugColors[MAX_BASSRELIEF_DEBUG_COLORS]);
/*
* NULL initializes to local data
*/
#define NULL_BassReliefCalcData \
{ \
NULL, \
}
#define NULL_BVHTreeFromMesh \
{ \
NULL, \
}
#define NULL_BVHTreeRayHit \
{ \
NULL, \
}
#define NULL_BVHTreeNearest \
{ \
0, \
}
#ifdef __cplusplus
}
#endif

View File

@ -519,6 +519,7 @@ bool BKE_pbvh_bmesh_update_topology_nodes(PBVH *pbvh,
/* Node Access */
void BKE_pbvh_check_tri_areas(PBVH *pbvh, PBVHNode *node);
void BKE_pbvh_face_areas_begin(PBVH *pbvh);
// updates boundaries and valences for whole mesh
void BKE_pbvh_bmesh_on_mesh_change(PBVH *pbvh);

View File

@ -63,6 +63,8 @@ set(INC_SYS
# For `vfontdata_freetype.c`.
${FREETYPE_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIRS}
)
set(SRC
@ -95,6 +97,7 @@ set(SRC
intern/attribute_access.cc
intern/attribute_math.cc
intern/autoexec.c
intern/bassrelief.cc
intern/blender.c
intern/blender_copybuffer.c
intern/blender_undo.c
@ -327,6 +330,7 @@ set(SRC
BKE_attribute_access.hh
BKE_attribute_math.hh
BKE_autoexec.h
BKE_bassrelief.h
BKE_blender.h
BKE_blender_copybuffer.h
BKE_blender_undo.h

File diff suppressed because it is too large Load Diff

View File

@ -331,7 +331,7 @@ MAKE_ENUM(blend,"Blending Mode","Brush blending mode",IMB_BLEND_MIX,{\
MAKE_BOOL(original_normal,"Original Normal","When locked keep using normal of surface where stroke was initiated",false)
MAKE_BOOL(original_plane,"Original Plane","When locked keep using the plane origin of surface where stroke was initiated",false)
MAKE_BOOL(use_weighted_smooth,"Weight By Area","Weight by face area to get a smoother result",true)
MAKE_BOOL_EX(preserve_faceset_boundary,"Preserve Faceset Boundary","Preserve face set boundaries",true,BRUSH_CHANNEL_INHERIT)
MAKE_BOOL_EX(preserve_faceset_boundary,"Preserve Faceset Boundary","Preserve face set boundaries",true,0)
MAKE_BOOL_EX(hard_edge_mode,"Hard Edge Mode","Treat face set boundaries as hard edges",false,BRUSH_CHANNEL_INHERIT)
MAKE_BOOL(grab_silhouette,"Grab Silhouette","Grabs trying to automask the silhouette of the object",false)
MAKE_BOOL(use_grab_active_vertex,"Grab Active Vertex",

View File

@ -2665,6 +2665,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
.create_shapekey_layers = true,
.ignore_id_layers = false,
.copy_temp_cdlayers = true,
.cd_mask_extra = CD_MASK_DYNTOPO_VERT}));
BKE_sculptsession_bmesh_add_layers(ob);

File diff suppressed because it is too large Load Diff

View File

@ -1825,7 +1825,7 @@ static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *nod
return max_fff(t1x, t1y, t1z);
}
static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
ATTR_NO_OPT static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
{
int i;

View File

@ -84,6 +84,17 @@
static CLG_LogRef LOG = {"blo.readfile.doversion"};
static void _brush_channel_transfer(BrushChannelSet *dst, BrushChannelSet *src, const char *idname)
{
BrushChannel *ch_dst = BKE_brush_channelset_lookup(dst, idname);
BrushChannel *ch_src = BKE_brush_channelset_lookup(src, idname);
BKE_brush_channel_copy_data(ch_dst, ch_src, false, false);
}
#define brush_channel_transfer(dst, src, idname) \
_brush_channel_transfer(dst, src, MAKE_BUILTIN_CH_NAME(idname))
static IDProperty *idproperty_find_ui_container(IDProperty *idprop_group)
{
LISTBASE_FOREACH (IDProperty *, prop, &idprop_group->data.group) {
@ -2952,6 +2963,59 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
ch->flag |= BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU | BRUSH_CHANNEL_SHOW_IN_WORKSPACE;
}
}
if (!DNA_struct_elem_find(fd->filesdna, "Brush", "BrushChannelSet", "*channels")) {
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
if (!brush->sculpt_tool) {
continue;
}
if (!brush->channels) {
brush->channels = BKE_brush_channelset_create(__func__);
}
BKE_brush_builtin_patch(brush, brush->sculpt_tool);
BKE_brush_channelset_compat_load(brush->channels, brush, true);
Brush temp = *brush;
temp.channels = NULL;
BKE_brush_builtin_create(&temp, brush->sculpt_tool);
/* set dyntopo settings */
LISTBASE_FOREACH (BrushChannel *, ch, &temp.channels->channels) {
if (BLI_str_startswith(ch->idname, "dyntopo_")) {
BrushChannel *dst = BKE_brush_channelset_lookup(brush->channels, ch->idname);
BKE_brush_channel_copy_data(dst, ch, false, false);
}
}
brush_channel_transfer(brush->channels, temp.channels, use_weighted_smooth);
brush_channel_transfer(brush->channels, temp.channels, preserve_faceset_boundary);
brush_channel_transfer(brush->channels, temp.channels, hard_edge_mode);
brush_channel_transfer(brush->channels, temp.channels, fset_slide);
brush_channel_transfer(brush->channels, temp.channels, topology_rake_mode);
brush_channel_transfer(brush->channels, temp.channels, topology_rake_use_spacing);
brush_channel_transfer(brush->channels, temp.channels, autosmooth_use_spacing);
brush_channel_transfer(brush->channels, temp.channels, topology_rake_spacing);
brush_channel_transfer(brush->channels, temp.channels, autosmooth_spacing);
brush_channel_transfer(brush->channels, temp.channels, topology_rake_mode);
/* set defaults that have changed */
switch (brush->sculpt_tool) {
case SCULPT_TOOL_SIMPLIFY:
brush_channel_transfer(brush->channels, temp.channels, topology_rake);
brush_channel_transfer(brush->channels, temp.channels, autosmooth);
brush_channel_transfer(brush->channels, temp.channels, projection);
brush_channel_transfer(brush->channels, temp.channels, smooth_deform_type);
break;
}
BKE_brush_channelset_free(temp.channels);
}
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@ -27,10 +27,11 @@ typedef enum eBMCreateFlag {
BM_CREATE_NOP = 0,
/** Faces and edges only. */
BM_CREATE_NO_DOUBLE = (1 << 1),
<<<<<<< HEAD
/* Skip CustomData - for all element types data,
* use if we immediately write customdata into the element so this skips copying from 'example'
* args or setting defaults, speeds up conversion when data is converted all at once. */
/**
* Skip custom-data - for all element types data,
* use if we immediately write custom-data into the element so this skips copying from 'example'
* arguments or setting defaults, speeds up conversion when data is converted all at once.
*/
BM_CREATE_SKIP_CD = (1 << 2), /* if true, you must call bm_elem_check_toolflags(bm, elem) later
if toolflags are on */
BM_CREATE_SKIP_ID = (1 << 3)
@ -39,19 +40,9 @@ typedef enum eBMCreateFlag {
/* if toolflags are enabled, checks that internal pointer to toolflags it not null */
void bm_elem_check_toolflags(BMesh *bm, BMElem *elem);
=======
/**
* Skip custom-data - for all element types data,
* use if we immediately write custom-data into the element so this skips copying from 'example'
* arguments or setting defaults, speeds up conversion when data is converted all at once.
*/
BM_CREATE_SKIP_CD = (1 << 2),
} eBMCreateFlag;
/**
* \brief Main function for creating a new vertex.
*/
>>>>>>> master
BMVert *BM_vert_create(BMesh *bm,
const float co[3],
const BMVert *v_example,
@ -119,9 +110,6 @@ void BM_edge_kill(BMesh *bm, BMEdge *e);
*/
void BM_vert_kill(BMesh *bm, BMVert *v);
<<<<<<< HEAD
bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src, bool combine_flags);
=======
/**
* \brief Splice Edge
*
@ -132,7 +120,8 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src, bool combine_flags)
*
* \note Edges must already have the same vertices.
*/
bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src);
bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src, bool combine_flags);
/**
* \brief Splice Vert
*
@ -145,7 +134,6 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src);
* where \a v and \a vtarget are connected by an edge
* (assert checks for this case).
*/
>>>>>>> master
bool BM_vert_splice(BMesh *bm, BMVert *v_dst, BMVert *v_src);
/**
* Check if splicing vertices would create any double edges.
@ -348,17 +336,6 @@ BMEdge *bmesh_kernel_join_edge_kill_vert(BMesh *bm,
const bool check_edge_exists,
const bool kill_degenerate_faces,
const bool kill_duplicate_faces);
<<<<<<< HEAD
BMVert *bmesh_kernel_join_vert_kill_edge(
BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool combine_flags);
BMVert *bmesh_kernel_join_vert_kill_edge_fast(BMesh *bm,
BMEdge *e_kill,
BMVert *v_kill,
const bool do_del,
const bool check_edge_exists,
const bool kill_degenerate_faces,
const bool combine_flags);
=======
/**
* \brief Join Vert Kill Edge (JVKE)
*
@ -377,12 +354,16 @@ BMVert *bmesh_kernel_join_vert_kill_edge_fast(BMesh *bm,
* +-+-+-+ +-+-+-+
* </pre>
*/
BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
BMEdge *e_kill,
BMVert *v_kill,
const bool do_del,
const bool check_edge_exists,
const bool kill_degenerate_faces);
BMVert *bmesh_kernel_join_vert_kill_edge(
BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool combine_flags);
BMVert *bmesh_kernel_join_vert_kill_edge_fast(BMesh *bm,
BMEdge *e_kill,
BMVert *v_kill,
const bool do_del,
const bool check_edge_exists,
const bool kill_degenerate_faces,
const bool combine_flags);
/**
* \brief Join Face Kill Edge (JFKE)
*
@ -414,7 +395,6 @@ BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
*
* \return A BMFace pointer
*/
>>>>>>> master
BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
/**

View File

@ -731,6 +731,8 @@ void BM_mesh_bm_from_me(Object *ob,
}
if (check_id_unqiue) {
bm_update_idmap_cdlayers(bm);
// validate IDs
// first clear idmap, we want it to have the first elements
@ -846,6 +848,7 @@ void BM_mesh_bm_from_me(Object *ob,
#ifdef WITH_BM_ID_FREELIST
/*ensure correct id freelist*/
if (bm->idmap.flag & BM_HAS_IDS) {
bm_update_idmap_cdlayers(bm);
bm_free_ids_check(bm, bm->idmap.maxid);
MEM_SAFE_FREE(bm->idmap.freelist);
@ -867,10 +870,24 @@ void BM_mesh_bm_from_me(Object *ob,
BLI_mempool_iternew(pool, &miter);
BMElem *elem = (BMElem *)BLI_mempool_iterstep(&miter);
# if 0
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&miter)) {
uint id = (uint)BM_ELEM_GET_ID(bm, elem);
BLI_BITMAP_SET(bm->idmap.free_ids, id, true);
if (id > bm->idmap.maxid) {
printf("%s: corrupted id: %d > maxid(%d)\n", __func__, (int)id, (int)bm->idmap.maxid);
//BM_ELEM_CD_SET_INT(elem, bm->idmap.cd_id_off[elem->head.htype], 0);
bm_alloc_id(bm, elem);
}
}
# endif
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&miter)) {
uint id = (uint)BM_ELEM_GET_ID(bm, elem);
if ((id >> 2UL) < bm->idmap.free_ids_size) {
BLI_BITMAP_SET(bm->idmap.free_ids, id, true);
}
}
}

View File

@ -1302,26 +1302,6 @@ void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4])
r_verts[3] = l->v;
}
<<<<<<< HEAD
/**
* faster alternative to:
* BM_iter_as_array(bm, BM_LOOPS_OF_FACE, f, (void **)l, 4);
*/
=======
void BM_face_as_array_loop_tri(BMFace *f, BMLoop *r_loops[3])
{
BMLoop *l = BM_FACE_FIRST_LOOP(f);
BLI_assert(f->len == 3);
r_loops[0] = l;
l = l->next;
r_loops[1] = l;
l = l->next;
r_loops[2] = l;
}
>>>>>>> master
void BM_face_as_array_loop_quad(BMFace *f, BMLoop *r_loops[4])
{
BMLoop *l = BM_FACE_FIRST_LOOP(f);

View File

@ -254,7 +254,7 @@ void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_
* faster alternative to:
* BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void **)v, 3);
*/
BLI_INLINE void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3]) ATTR_NONNULL();
BLI_INLINE void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3]) ATTR_NONNULL()
{
BMLoop *l = BM_FACE_FIRST_LOOP(f);
@ -291,19 +291,10 @@ BLI_INLINE void BM_face_as_array_loop_tri(BMFace *f, BMLoop *r_loops[3])
* BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void **)v, 4);
*/
void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4]) ATTR_NONNULL();
/**
* Small utility functions for fast access
*
* faster alternative to:
* BM_iter_as_array(bm, BM_LOOPS_OF_FACE, f, (void **)l, 3);
*/
void BM_face_as_array_loop_tri(BMFace *f, BMLoop *r_loops[3]) ATTR_NONNULL();
/**
* faster alternative to:
* BM_iter_as_array(bm, BM_LOOPS_OF_FACE, f, (void **)l, 4);
*/
>>>>>>> master
void BM_face_as_array_loop_quad(BMFace *f, BMLoop *r_loops[4]) ATTR_NONNULL();
/**

View File

@ -153,6 +153,7 @@ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace
if (r_f_new) {
*r_f_new = f_new;
}
return l_new ? l_new->e : NULL;
}
@ -861,6 +862,11 @@ static void tri_3edge_subdivide(BMesh *bm,
for (j = 0; j < i; j++) {
e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &f_new);
if (!e) {
printf("%s: subdivide error;\n", __func__);
continue;
}
BMO_edge_flag_enable(bm, e, ELE_INNER);
BMO_face_flag_enable(bm, f_new, ELE_INNER);

View File

@ -874,6 +874,66 @@ static int mesh_customdata_clear_exec__internal(bContext *C, char htype, int typ
return OPERATOR_CANCELLED;
}
/* Clear Mask */
static bool mesh_customdata_ids_clear_poll(bContext *C)
{
Object *ob = ED_object_context(C);
if (ob && ob->type == OB_MESH) {
Mesh *me = ob->data;
if (me->edit_mesh) {
return false;
}
/* special case - can't run this if we're in sculpt mode */
if (ob->mode & OB_MODE_SCULPT) {
return false;
}
if (!ID_IS_LINKED(me)) {
bool ret = CustomData_has_layer(GET_CD_DATA(me, vdata), CD_MESH_ID);
ret |= CustomData_has_layer(GET_CD_DATA(me, edata), CD_MESH_ID);
ret |= CustomData_has_layer(GET_CD_DATA(me, ldata), CD_MESH_ID);
ret |= CustomData_has_layer(GET_CD_DATA(me, pdata), CD_MESH_ID);
return ret;
}
}
return false;
}
static int mesh_customdata_ids_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
bool ret = false;
for (int i = 0; i < 4; i++) {
int type = 1 << i;
ret |= mesh_customdata_clear_exec__internal(C, type, CD_MESH_ID);
}
if (ret) {
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
void MESH_OT_customdata_ids_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clear Element ID Data";
ot->idname = "MESH_OT_customdata_ids_clear";
ot->description = "Clear element ID layers";
/* api callbacks */
ot->exec = mesh_customdata_ids_clear_exec;
ot->poll = mesh_customdata_ids_clear_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* Clear Mask */
static bool mesh_customdata_mask_clear_poll(bContext *C)
{

View File

@ -294,3 +294,4 @@ void MESH_OT_customdata_skin_clear(struct wmOperatorType *ot);
void MESH_OT_customdata_custom_splitnormals_add(struct wmOperatorType *ot);
void MESH_OT_customdata_custom_splitnormals_clear(struct wmOperatorType *ot);
void MESH_OT_dump_mres_grids(struct wmOperatorType *ot);
void MESH_OT_customdata_ids_clear(struct wmOperatorType *ot);

View File

@ -155,6 +155,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_sculpt_vertex_color_add);
WM_operatortype_append(MESH_OT_sculpt_vertex_color_remove);
WM_operatortype_append(MESH_OT_customdata_mask_clear);
WM_operatortype_append(MESH_OT_customdata_ids_clear);
WM_operatortype_append(MESH_OT_customdata_skin_add);
WM_operatortype_append(MESH_OT_customdata_skin_clear);
WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_add);

View File

@ -5851,6 +5851,9 @@ static void SCULPT_run_command(
if (cmd->tool == SCULPT_TOOL_SMOOTH) {
ss->cache->bstrength = BRUSHSET_GET_FLOAT(cmd->params_mapped, strength, NULL);
if (ss->cache->invert) {
ss->cache->bstrength = -ss->cache->bstrength;
}
}
else {
ss->cache->bstrength = brush_strength(

View File

@ -1149,19 +1149,24 @@ void SCULPT_neighbor_coords_average(SculptSession *ss,
bool weighted)
{
if (check_fsets) {
sculpt_neighbor_coords_average_fset(ss, result, vertex, projection, weighted);
return;
// sculpt_neighbor_coords_average_fset(ss, result, vertex, projection, weighted);
// return;
}
float avg[3] = {0.0f, 0.0f, 0.0f};
float *co, no[3];
float total = 0.0f;
int bound_mask = SCULPT_BOUNDARY_ALL;
if (projection > 0.0f) {
co = (float *)SCULPT_vertex_co_get(ss, vertex);
SCULPT_vertex_normal_get(ss, vertex, no);
if (!check_fsets) {
bound_mask &= ~SCULPT_BOUNDARY_FACE_SET;
}
bool boundary = SCULPT_vertex_is_boundary(ss, vertex, bound_mask);
co = (float *)SCULPT_vertex_co_get(ss, vertex);
SCULPT_vertex_normal_get(ss, vertex, no);
float *areas;
if (weighted) {
@ -1183,6 +1188,22 @@ void SCULPT_neighbor_coords_average(SculptSession *ss,
w = 1.0f;
}
if (boundary) {
bool boundary2 = SCULPT_vertex_is_boundary(ss, ni.vertex, bound_mask);
if (!boundary2 && (boundary & SCULPT_BOUNDARY_FACE_SET)) {
float tmp[3];
sub_v3_v3v3(tmp, co2, co);
madd_v3_v3fl(avg, no, dot_v3v3(tmp, no) * w);
total += w;
continue;
}
else if (!boundary2) {
continue;
}
}
if (projection > 0.0f) {
float tmp[3];
@ -1232,20 +1253,24 @@ float SCULPT_neighbor_mask_average(SculptSession *ss, SculptVertRef index)
void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], SculptVertRef vertex)
{
float avg[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int total = 0;
float total = 0.0f;
AutomaskingCache *automasking = SCULPT_automasking_active_cache_get(ss);
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
float tmp[4] = {0};
float w = automasking ? SCULPT_automasking_factor_get(automasking, ss, ni.vertex) : 1.0f;
SCULPT_vertex_color_get(ss, ni.vertex, tmp);
add_v4_v4(avg, tmp);
total++;
madd_v4_v4fl(avg, tmp, w);
total += w;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (total > 0) {
if (total > 0.0f) {
mul_v4_v4fl(result, avg, 1.0f / total);
}
else {
@ -1308,6 +1333,27 @@ static void SCULPT_enhance_details_brush(Sculpt *sd,
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
bool use_area_weights = (ss->cache->brush->flag2 & BRUSH_SMOOTH_USE_AREA_WEIGHT);
if (use_area_weights) {
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
BKE_pbvh_update_all_tri_areas(ss->pbvh);
PBVHNode **nodes;
int totnode;
BKE_pbvh_get_nodes(ss->pbvh, PBVH_Leaf, &nodes, &totnode);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_check_tri_areas(ss->pbvh, nodes[i]);
}
}
else {
BKE_pbvh_face_areas_begin(ss->pbvh);
}
}
SCULPT_vertex_random_access_ensure(ss);
SCULPT_boundary_info_ensure(ob);
SculptCustomLayer scl;
SculptLayerParams params = {.permanent = false, .simple_array = false};
bool weighted = SCULPT_get_int(ss, use_weighted_smooth, sd, brush);
@ -1317,14 +1363,6 @@ static void SCULPT_enhance_details_brush(Sculpt *sd,
SCULPT_temp_customlayer_get(
ss, ob, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, "__dyntopo_detail_dir", &scl, &params);
if (SCULPT_stroke_is_first_brush_step(ss->cache) &&
(ss->cache->brush->flag2 & BRUSH_SMOOTH_USE_AREA_WEIGHT)) {
BKE_pbvh_update_all_tri_areas(ss->pbvh);
}
SCULPT_vertex_random_access_ensure(ss);
SCULPT_boundary_info_ensure(ob);
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
const int totvert = SCULPT_vertex_count_get(ss);
@ -1332,10 +1370,65 @@ static void SCULPT_enhance_details_brush(Sculpt *sd,
float avg[3];
SculptVertRef vertex = BKE_pbvh_table_index_to_vertex(ss->pbvh, i);
float *dir = SCULPT_temp_cdata_get(vertex, &scl);
float no[3];
SCULPT_vertex_normal_get(ss, vertex, no);
SCULPT_neighbor_coords_average(ss, avg, vertex, 0.0f, false, weighted);
sub_v3_v3v3(dir, avg, SCULPT_vertex_co_get(ss, vertex));
/* get rid of tangential displacement */
float fac = dot_v3v3(dir, no);
copy_v3_v3(dir, no);
mul_v3_fl(dir, fac);
}
int lastvalence = 5;
float *areas = MEM_malloc_arrayN(lastvalence, sizeof(float), __func__);
/* smooth offsets */
for (int i = 0; i < totvert; i++) {
float avg[3] = {0.0f, 0.0f, 0.0f};
SculptVertRef vertex = BKE_pbvh_table_index_to_vertex(ss->pbvh, i);
float *dir = SCULPT_temp_cdata_get(vertex, &scl);
float tot = 0.0f;
float *areas = NULL;
int valence;
if (use_area_weights) {
valence = SCULPT_vertex_valence_get(ss, vertex);
if (valence > lastvalence) {
areas = MEM_reallocN(areas, sizeof(float) * valence);
}
areas = MEM_callocN(sizeof(float) * valence * 4, "sdaf");
// BLI_array_alloca(areas, valence * 4);
BKE_pbvh_get_vert_face_areas(ss->pbvh, vertex, areas, valence);
}
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
float *dir2 = SCULPT_temp_cdata_get(ni.vertex, &scl);
float w = 1.0f;
if (use_area_weights) {
w = areas[ni.i];
}
madd_v3_v3fl(avg, dir2, w);
tot += w;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (tot > 0.0f) {
mul_v3_fl(avg, 1.0f / tot);
interp_v3_v3v3(dir, dir, avg, 0.5f);
}
}
MEM_freeN(areas);
}
SculptThreadedTaskData data = {.sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .scl = &scl};
@ -1661,7 +1754,6 @@ void SCULPT_smooth(Sculpt *sd,
BKE_pbvh_update_all_tri_areas(ss->pbvh);
}
else {
void BKE_pbvh_face_areas_begin(PBVH * pbvh);
BKE_pbvh_face_areas_begin(ss->pbvh);
}
}

View File

@ -559,6 +559,12 @@
.projLimit = 0.0f, \
.projAxis = 0, \
.subsurfLevels = 0, \
.optimizeNormalSteps = 8,\
.optimizeNormals = 0,\
.rayShrinkRatio = 1.0f,\
.boundSmoothSteps = 8,\
.boundSmoothScale = 3.0f,\
.optimizeNormalsScale = 1.5f\
}
#define _DNA_DEFAULT_SimpleDeformModifierData \
@ -817,4 +823,23 @@
.mat_ofs = 0, \
}
#define _DNA_DEFAULT_BassReliefModifierData \
{ \
.target = NULL, \
.collection = NULL, \
.vgroup_name = "", \
.keepDist = 0.0f, \
.shrinkOpts =\
MOD_BASSRELIEF_CULL_TARGET_FRONTFACE|\
MOD_BASSRELIEF_PROJECT_ALLOW_POS_DIR|\
MOD_BASSRELIEF_OPTIMIZE, \
.projLimit = 0.0f, \
.projAxis = 0, \
.optimizeSteps = 8,\
.rayShrinkRatio = 1.0f,\
.boundSmoothSteps = 8,\
.boundSmoothFalloff = 3.0f,\
.detailScale = 1.5f\
}
/* clang-format off */

View File

@ -98,6 +98,7 @@ typedef enum ModifierType {
eModifierType_MeshToVolume = 58,
eModifierType_VolumeDisplace = 59,
eModifierType_VolumeToMesh = 60,
eModifierType_BassRelief = 61,
NUM_MODIFIER_TYPES,
} ModifierType;
@ -1147,7 +1148,16 @@ typedef struct ShrinkwrapModifierData {
*/
char subsurfLevels;
char _pad[2];
char optimizeNormalSteps;
char optimizeNormals;
float rayShrinkRatio;
char boundSmoothSteps;
char _pad2[3];
float boundSmoothScale; /* width of smoothed boundary is divided by this */
float optimizeNormalsScale;
} ShrinkwrapModifierData;
/* Shrinkwrap->shrinkType */
@ -1205,6 +1215,66 @@ enum {
MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS = (1 << 2),
};
typedef struct BassReliefModifierData {
ModifierData modifier;
/** Shrink target. */
struct Object *target;
/** Shrink target collection */
struct Collection *collection;
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
char vgroup_name[64];
/** Distance offset to keep from mesh/projection point. */
float keepDist;
/** Shrink options. */
char shrinkOpts;
/** Axis to project over. */
char projAxis;
char optimizeSteps;
char boundSmoothSteps;
float boundSmoothFalloff; /* width of smoothed boundary is divided by this */
float detailScale;
/** Limit the projection ray cast. */
float projLimit;
float rayShrinkRatio;
} BassReliefModifierData;
/* BassReliefModifier->shrinkOpts */
enum {
/** allow shrinkwrap to move the vertex in the positive direction of axis */
MOD_BASSRELIEF_PROJECT_ALLOW_POS_DIR = (1 << 0),
/** allow shrinkwrap to move the vertex in the negative direction of axis */
MOD_BASSRELIEF_PROJECT_ALLOW_NEG_DIR = (1 << 1),
/** ignore vertex moves if a vertex ends projected on a front face of the target */
MOD_BASSRELIEF_CULL_TARGET_FRONTFACE = (1 << 3),
/** ignore vertex moves if a vertex ends projected on a back face of the target */
MOD_BASSRELIEF_CULL_TARGET_BACKFACE = (1 << 4),
MOD_BASSRELIEF_INVERT_VGROUP = (1 << 5),
MOD_BASSRELIEF_INVERT_CULL_TARGET = (1 << 6),
MOD_BASSRELIEF_OPTIMIZE = (1<<7)
};
#define MOD_BASSRELIEF_CULL_TARGET_MASK \
(MOD_BASSRELIEF_CULL_TARGET_FRONTFACE | MOD_BASSRELIEF_CULL_TARGET_BACKFACE)
/* Shrinkwrap->projAxis */
enum {
/** projection over normal is used if no axis is selected */
MOD_BASSRELIEF_PROJECT_OVER_NORMAL = 0,
MOD_BASSRELIEF_PROJECT_OVER_X_AXIS = (1 << 0),
MOD_BASSRELIEF_PROJECT_OVER_Y_AXIS = (1 << 1),
MOD_BASSRELIEF_PROJECT_OVER_Z_AXIS = (1 << 2),
};
typedef struct SimpleDeformModifierData {
ModifierData modifier;

View File

@ -243,6 +243,7 @@ SDNA_DEFAULT_DECL_STRUCT(World);
/* DNA_modifier_defaults.h */
SDNA_DEFAULT_DECL_STRUCT(ArmatureModifierData);
SDNA_DEFAULT_DECL_STRUCT(ArrayModifierData);
SDNA_DEFAULT_DECL_STRUCT(BassReliefModifierData);
SDNA_DEFAULT_DECL_STRUCT(BevelModifierData);
SDNA_DEFAULT_DECL_STRUCT(BooleanModifierData);
SDNA_DEFAULT_DECL_STRUCT(BuildModifierData);
@ -474,6 +475,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
/* DNA_modifier_defaults.h */
SDNA_DEFAULT_DECL(ArmatureModifierData),
SDNA_DEFAULT_DECL(ArrayModifierData),
SDNA_DEFAULT_DECL(BassReliefModifierData),
SDNA_DEFAULT_DECL(BevelModifierData),
SDNA_DEFAULT_DECL(BooleanModifierData),
SDNA_DEFAULT_DECL(BuildModifierData),

View File

@ -76,6 +76,7 @@ extern StructRNA RNA_AssetLibraryReference;
extern StructRNA RNA_AssetMetaData;
extern StructRNA RNA_AssetTag;
extern StructRNA RNA_BackgroundImage;
extern StructRNA RNA_BassReliefModifier;
extern StructRNA RNA_BevelModifier;
extern StructRNA RNA_BezierSplinePoint;
extern StructRNA RNA_BlendData;

View File

@ -212,6 +212,11 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
ICON_MOD_ARMATURE,
"Armature",
"Deform the shape using an armature object"},
{eModifierType_BassRelief,
"BASS_RELIEF",
ICON_MOD_SHRINKWRAP,
"Bass Relief",
""},
{eModifierType_Cast,
"CAST",
ICON_MOD_CAST,
@ -1081,6 +1086,18 @@ static void rna_ShrinkwrapModifier_face_cull_set(struct PointerRNA *ptr, int val
swm->shrinkOpts = (swm->shrinkOpts & ~MOD_SHRINKWRAP_CULL_TARGET_MASK) | value;
}
static int rna_BassReliefModifier_face_cull_get(PointerRNA *ptr)
{
BassReliefModifierData *swm = (BassReliefModifierData *)ptr->data;
return swm->shrinkOpts & MOD_BASSRELIEF_CULL_TARGET_MASK;
}
static void rna_BassReliefModifier_face_cull_set(struct PointerRNA *ptr, int value)
{
BassReliefModifierData *swm = (BassReliefModifierData *)ptr->data;
swm->shrinkOpts = (swm->shrinkOpts & ~MOD_BASSRELIEF_CULL_TARGET_MASK) | value;
}
static bool rna_MeshDeformModifier_is_bound_get(PointerRNA *ptr)
{
return (((MeshDeformModifierData *)ptr->data)->bindcagecos != NULL);
@ -4349,9 +4366,217 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "ray_shrink_ratio", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rayShrinkRatio");
RNA_def_property_ui_text(prop, "Shrink Ratio", "Compress shrinkwrap result by this ratio; useful for reliefs");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_normal_optimizer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "optimizeNormals", 1);
RNA_def_property_ui_text(prop,
"Optimize Normals",
"Try to optimize normals to match original mesh; useful for making "
"reliefs when combined with Shrink Ratio");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "normal_optimizer_steps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "optimizeNormalSteps");
RNA_def_property_ui_text(prop, "Exaggeration Filter", "");
RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_range(prop, 0, 10, 1, 1);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "boundary_smooth_steps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "boundSmoothSteps");
RNA_def_property_ui_text(prop, "Boundary Smooth", "Boundary smooth steps");
RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_range(prop, 0, 10, 1, 1);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "boundary_smooth_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "boundSmoothScale");
RNA_def_property_ui_range(prop, 0.001, 4.0, 0.01, 3);
RNA_def_property_ui_text(prop, "Boundary Scale", "Boundary width");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "normal_optimizer_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "optimizeNormalsScale");
RNA_def_property_ui_range(prop, 0.001, 4.0, 0.01, 3);
RNA_def_property_ui_text(prop, "Exaggeration Scale", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
/*
uiItemR(col, ptr, "normal_optimizer_scale", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "normal_optimizer_steps", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "boundary_smooth_scale", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "boundary_smooth_steps", 0, NULL, ICON_NONE);
*/
RNA_define_lib_overridable(false);
}
static void rna_def_modifier_bassrelief(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
static const EnumPropertyItem bassrelief_face_cull_items[] = {
//{0, "OFF", 0, "Off", "No culling"},
{MOD_BASSRELIEF_CULL_TARGET_FRONTFACE,
"FRONT",
0,
"Front",
"No projection when in front of the face"},
{MOD_BASSRELIEF_CULL_TARGET_BACKFACE,
"BACK",
0,
"Back",
"No projection when behind the face"},
{0, NULL, 0, NULL, NULL},
};
srna = RNA_def_struct(brna, "BassReliefModifier", "Modifier");
RNA_def_struct_ui_text(srna,
"Bass Relief Modifier",
"Create bass reliefs");
RNA_def_struct_sdna(srna, "BassReliefModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_SHRINKWRAP);
RNA_define_lib_overridable(true);
prop = RNA_def_property(srna, "cull_face", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shrinkOpts");
RNA_def_property_enum_items(prop, bassrelief_face_cull_items);
RNA_def_property_enum_funcs(
prop, "rna_BassReliefModifier_face_cull_get", "rna_BassReliefModifier_face_cull_set", NULL);
RNA_def_property_ui_text(
prop,
"Face Cull",
"Stop vertices from projecting to a face on the target when facing towards/away");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Target", "Mesh target to shrink to");
RNA_def_property_pointer_funcs(
prop, NULL, "rna_ShrinkwrapModifier_target_set", NULL, "rna_Mesh_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "collection", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "collection");
RNA_def_property_ui_text(prop, "Collection Target", "Use meshes in this collection as targets");
//RNA_def_property_pointer_funcs(
// prop, NULL, "rna_ShrinkwrapModifier_auxTarget_set", NULL, "rna_Mesh_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "vgroup_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
//RNA_def_property_string_funcs(prop, NULL, NULL, "rna_BassReliefModifier_vgroup_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "keepDist");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, -100, 100, 1, 2);
RNA_def_property_ui_text(prop, "Offset", "Distance to keep from the target");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "project_limit", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "projLimit");
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 100, 1, 2);
RNA_def_property_ui_text(
prop, "Project Limit", "Limit the distance used for projection (zero disables)");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_project_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "projAxis", MOD_BASSRELIEF_PROJECT_OVER_X_AXIS);
RNA_def_property_ui_text(prop, "X", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_project_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "projAxis", MOD_BASSRELIEF_PROJECT_OVER_Y_AXIS);
RNA_def_property_ui_text(prop, "Y", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_project_z", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "projAxis", MOD_BASSRELIEF_PROJECT_OVER_Z_AXIS);
RNA_def_property_ui_text(prop, "Z", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_negative_direction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_BASSRELIEF_PROJECT_ALLOW_NEG_DIR);
RNA_def_property_ui_text(
prop, "Negative", "Allow vertices to move in the negative direction of axis");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_positive_direction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_BASSRELIEF_PROJECT_ALLOW_POS_DIR);
RNA_def_property_ui_text(
prop, "Positive", "Allow vertices to move in the positive direction of axis");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_invert_cull", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_BASSRELIEF_INVERT_CULL_TARGET);
RNA_def_property_ui_text(
prop, "Invert Cull", "When projecting in the negative direction invert the face cull mode");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_BASSRELIEF_INVERT_VGROUP);
RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "ray_shrink_ratio", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rayShrinkRatio");
RNA_def_property_ui_text(
prop, "Shrink Ratio", "Compress shrinkwrap result by this ratio; useful for reliefs");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_normal_optimizer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_BASSRELIEF_OPTIMIZE);
RNA_def_property_ui_text(prop,
"Optimize",
"Try to optimize shading to match original mesh; useful for making "
"reliefs when combined with Shrink Ratio");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "optimizer_steps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "optimizeSteps");
RNA_def_property_ui_text(prop, "Exaggeration Filter", "");
RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_range(prop, 0, 10, 1, 1);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "boundary_smooth_steps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "boundSmoothSteps");
RNA_def_property_ui_text(prop, "Boundary Smooth", "Boundary smooth steps");
RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_range(prop, 0, 10, 1, 1);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "boundary_smooth_falloff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "boundSmoothFalloff");
RNA_def_property_ui_range(prop, 0.001, 4.0, 0.01, 3);
RNA_def_property_ui_text(prop, "Boundary Falloff", "Boundary width");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "detail_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "detailScale");
RNA_def_property_ui_range(prop, 0.001, 4.0, 0.01, 3);
RNA_def_property_ui_text(prop, "Exaggeration Scale", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
/*
uiItemR(col, ptr, "normal_optimizer_scale", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "normal_optimizer_steps", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "boundary_smooth_scale", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "boundary_smooth_steps", 0, NULL, ICON_NONE);
*/
RNA_define_lib_overridable(false);
}
static void rna_def_modifier_mask(BlenderRNA *brna)
{
StructRNA *srna;
@ -7359,6 +7584,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_mesh_to_volume(brna);
rna_def_modifier_volume_displace(brna);
rna_def_modifier_volume_to_mesh(brna);
rna_def_modifier_bassrelief(brna);
}
#endif

View File

@ -50,6 +50,7 @@ set(INC_SYS
set(SRC
intern/MOD_armature.c
intern/MOD_array.c
intern/MOD_bassrelief.c
intern/MOD_bevel.c
intern/MOD_boolean.cc
intern/MOD_build.c

View File

@ -89,6 +89,7 @@ extern ModifierTypeInfo modifierType_Nodes;
extern ModifierTypeInfo modifierType_MeshToVolume;
extern ModifierTypeInfo modifierType_VolumeDisplace;
extern ModifierTypeInfo modifierType_VolumeToMesh;
extern ModifierTypeInfo modifierType_BassRelief;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);

View File

@ -32,6 +32,7 @@
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "BKE_bassrelief.h"
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_lib_id.h"
@ -40,7 +41,6 @@
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_screen.h"
#include "BKE_shrinkwrap.h"
#include "BLI_math.h"
@ -62,57 +62,49 @@ static bool dependsOnNormals(ModifierData *md);
static void initData(ModifierData *md)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
BassReliefModifierData *smd = (BassReliefModifierData *)md;
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(ShrinkwrapModifierData), modifier);
MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(BassReliefModifierData), modifier);
}
static void requiredDataMask(Object *UNUSED(ob),
ModifierData *md,
CustomData_MeshMasks *r_cddata_masks)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
BassReliefModifierData *smd = (BassReliefModifierData *)md;
/* ask for vertexgroups if we need them */
if (smd->vgroup_name[0] != '\0') {
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
if ((smd->shrinkType == MOD_SHRINKWRAP_PROJECT) &&
(smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)) {
/* XXX Really? These should always be present, always... */
r_cddata_masks->vmask |= CD_MASK_MVERT;
}
}
static bool isDisabled(const struct Scene *UNUSED(scene),
ModifierData *md,
bool UNUSED(useRenderParams))
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
BassReliefModifierData *smd = (BassReliefModifierData *)md;
/* The object type check is only needed here in case we have a placeholder
* object assigned (because the library containing the mesh is missing).
*
* In other cases it should be impossible to have a type mismatch.
*/
if (!smd->target || smd->target->type != OB_MESH) {
return true;
}
if (smd->auxTarget && smd->auxTarget->type != OB_MESH) {
return true;
}
return false;
bool ok = smd->target && smd->target->type == OB_MESH;
ok = ok || smd->collection;
return !ok;
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
BassReliefModifierData *smd = (BassReliefModifierData *)md;
walk(userData, ob, (ID **)&smd->target, IDWALK_CB_NOP);
walk(userData, ob, (ID **)&smd->auxTarget, IDWALK_CB_NOP);
walk(userData, ob, (ID **)&smd->collection, IDWALK_CB_NOP);
}
#ifndef DEBUG_VIS_COLORS
@ -122,7 +114,7 @@ static void deformVerts(ModifierData *md,
float (*vertexCos)[3],
int numVerts)
{
ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
BassReliefModifierData *swmd = (BassReliefModifierData *)md;
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
Mesh *mesh_src = NULL;
@ -156,7 +148,7 @@ static void deformVertsEM(ModifierData *md,
float (*vertexCos)[3],
int numVerts)
{
ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
BassReliefModifierData *swmd = (BassReliefModifierData *)md;
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
Mesh *mesh_src = NULL;
@ -187,22 +179,22 @@ static void deformVertsEM(ModifierData *md,
}
}
#else
ATTR_NO_OPT static Mesh *modifyMeshDebug(struct ModifierData *md,
const struct ModifierEvalContext *ctx,
struct Mesh *mesh)
static Mesh *modifyMeshDebug(struct ModifierData *md,
const struct ModifierEvalContext *ctx,
struct Mesh *mesh)
{
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
CustomData_duplicate_referenced_layers(&mesh->vdata, mesh->totvert);
BKE_mesh_update_customdata_pointers(mesh, false);
//mesh = BKE_mesh_copy_for_eval(mesh, false);
// mesh = BKE_mesh_copy_for_eval(mesh, false);
BKE_mesh_ensure_normals(mesh);
MPropCol *colors[MAX_SHRINKWRAP_DEBUG_COLORS];
MPropCol *colors[MAX_BASSRELIEF_DEBUG_COLORS];
char name[MAX_CUSTOMDATA_LAYER_NAME];
for (int i = 0; i < MAX_SHRINKWRAP_DEBUG_COLORS; i++) {
for (int i = 0; i < MAX_BASSRELIEF_DEBUG_COLORS; i++) {
sprintf(name, "debug%d", i + 1);
colors[i] = CustomData_get_layer_named(&mesh->vdata, CD_PROP_COLOR, name);
}
@ -213,27 +205,19 @@ ATTR_NO_OPT static Mesh *modifyMeshDebug(struct ModifierData *md,
copy_v3_v3(cos[i], mesh->mvert[i].co);
}
ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
BassReliefModifierData *swmd = (BassReliefModifierData *)md;
if (swmd->rayShrinkRatio == 0.0f) {
swmd->rayShrinkRatio = 1.0f;
}
if (swmd->optimizeNormalsScale == 0.0f) {
swmd->optimizeNormalsScale = 1.5f;
}
if (swmd->boundSmoothScale == 0.0f) {
swmd->boundSmoothScale = 3.0f;
}
struct MDeformVert *dvert = NULL;
int defgrp_index = -1;
if (swmd->vgroup_name[0] != '\0') {
MOD_get_vgroup(ctx->object, mesh, swmd->vgroup_name, &dvert, &defgrp_index);
}
shrinkwrapModifier_deform(
bassReliefModifier_deform(
swmd, ctx, scene, ctx->object, mesh, dvert, defgrp_index, cos, mesh->totvert, colors);
for (int i = 0; i < mesh->totvert; i++) {
@ -250,44 +234,29 @@ ATTR_NO_OPT static Mesh *modifyMeshDebug(struct ModifierData *md,
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
BassReliefModifierData *smd = (BassReliefModifierData *)md;
CustomData_MeshMasks mask = {0};
if (BKE_shrinkwrap_needs_normals(smd->shrinkType, smd->shrinkMode)) {
mask.vmask |= CD_MASK_NORMAL;
mask.lmask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
}
mask.vmask |= CD_MASK_NORMAL;
mask.lmask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
if (smd->target != NULL) {
DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_TRANSFORM, "Bass Relief Modifier");
DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Bass Relief Modifier");
DEG_add_customdata_mask(ctx->node, smd->target, &mask);
if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
}
DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
}
if (smd->auxTarget != NULL) {
DEG_add_object_relation(
ctx->node, smd->auxTarget, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
DEG_add_object_relation(
ctx->node, smd->auxTarget, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
DEG_add_customdata_mask(ctx->node, smd->auxTarget, &mask);
if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
DEG_add_special_eval_flag(ctx->node, &smd->auxTarget->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
}
if (smd->collection != NULL) {
DEG_add_collection_geometry_relation(ctx->node, smd->collection, "Bass Relief Modifier");
}
DEG_add_modifier_to_transform_relation(ctx->node, "Shrinkwrap Modifier");
DEG_add_modifier_to_transform_relation(ctx->node, "Bass Relief Modifier");
}
static bool dependsOnNormals(ModifierData *md)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
if (smd->target && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
return (smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL);
}
return false;
return true;
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
@ -301,69 +270,49 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
int wrap_method = RNA_enum_get(ptr, "wrap_method");
uiItemR(layout, ptr, "project_limit", 0, IFACE_("Limit"), ICON_NONE);
uiItemR(layout, ptr, "wrap_method", 0, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
row = uiLayoutRowWithHeading(col, true, IFACE_("Axis"));
uiItemR(row, ptr, "use_project_x", toggles_flag, NULL, ICON_NONE);
uiItemR(row, ptr, "use_project_y", toggles_flag, NULL, ICON_NONE);
uiItemR(row, ptr, "use_project_z", toggles_flag, NULL, ICON_NONE);
if (ELEM(wrap_method,
MOD_SHRINKWRAP_PROJECT,
MOD_SHRINKWRAP_NEAREST_SURFACE,
MOD_SHRINKWRAP_TARGET_PROJECT)) {
uiItemR(layout, ptr, "wrap_mode", 0, NULL, ICON_NONE);
}
uiItemR(col, ptr, "use_negative_direction", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_positive_direction", 0, NULL, ICON_NONE);
if (wrap_method == MOD_SHRINKWRAP_PROJECT) {
uiItemR(layout, ptr, "project_limit", 0, IFACE_("Limit"), ICON_NONE);
uiItemR(layout, ptr, "subsurf_levels", 0, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
row = uiLayoutRowWithHeading(col, true, IFACE_("Axis"));
uiItemR(row, ptr, "use_project_x", toggles_flag, NULL, ICON_NONE);
uiItemR(row, ptr, "use_project_y", toggles_flag, NULL, ICON_NONE);
uiItemR(row, ptr, "use_project_z", toggles_flag, NULL, ICON_NONE);
uiItemR(col, ptr, "use_negative_direction", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_positive_direction", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "cull_face", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col,
RNA_boolean_get(ptr, "use_negative_direction") &&
RNA_enum_get(ptr, "cull_face") != 0);
uiItemR(col, ptr, "use_invert_cull", 0, NULL, ICON_NONE);
}
uiItemR(layout, ptr, "cull_face", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(
col, RNA_boolean_get(ptr, "use_negative_direction") && RNA_enum_get(ptr, "cull_face") != 0);
uiItemR(col, ptr, "use_invert_cull", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
if (wrap_method == MOD_SHRINKWRAP_PROJECT) {
uiItemR(layout, ptr, "auxiliary_target", 0, NULL, ICON_NONE);
}
uiItemR(layout, ptr, "collection", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE);
#if 1
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "ray_shrink_ratio", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_normal_optimizer", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "normal_optimizer_scale", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "normal_optimizer_steps", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "boundary_smooth_scale", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "detail_scale", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "optimizer_steps", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "boundary_smooth_falloff", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "boundary_smooth_steps", 0, NULL, ICON_NONE);
#endif
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
modifier_panel_end(layout, ptr);
}
static void panelRegister(ARegionType *region_type)
{
modifier_panel_register(region_type, eModifierType_Shrinkwrap, panel_draw);
modifier_panel_register(region_type, eModifierType_BassRelief, panel_draw);
}
ModifierTypeInfo modifierType_Shrinkwrap = {
/* name */ "Shrinkwrap",
/* structName */ "ShrinkwrapModifierData",
/* structSize */ sizeof(ShrinkwrapModifierData),
/* srna */ &RNA_ShrinkwrapModifier,
ModifierTypeInfo modifierType_BassRelief = {
/* name */ "Bass Relief",
/* structName */ "BassReliefModifierData",
/* structSize */ sizeof(BassReliefModifierData),
/* srna */ &RNA_BassReliefModifier,
#ifndef DEBUG_VIS_COLORS
/* type */ eModifierTypeType_OnlyDeform,
/* flags */

View File

@ -351,5 +351,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(VolumeDisplace);
INIT_TYPE(VolumeToMesh);
INIT_TYPE(Nodes);
INIT_TYPE(BassRelief);
#undef INIT_TYPE
}

View File

@ -31,6 +31,10 @@ struct ModifierData;
struct ModifierEvalContext;
struct Object;
#ifdef _cplusplus
extern "C" {
#endif
void MOD_init_texture(struct MappingInfoModifierData *dmd, const struct ModifierEvalContext *ctx);
void MOD_get_texture_coords(struct MappingInfoModifierData *dmd,
const struct ModifierEvalContext *ctx,
@ -59,3 +63,6 @@ void MOD_depsgraph_update_object_bone_relation(struct DepsNodeHandle *node,
struct Object *object,
const char *bonename,
const char *description);
#ifdef _cplusplus
};
#endif