Sculpt-dev: Code cleanup
This commit is contained in:
parent
5f631ca7c8
commit
a5cc113c7b
|
@ -489,7 +489,7 @@ class MESH_UL_color_attributes(UIList):
|
|||
|
||||
|
||||
class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
|
||||
bl_label = "Vertex Colors"
|
||||
bl_label = "Color Attributes"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
|
||||
|
|
|
@ -457,8 +457,8 @@ void BKE_brush_channelset_foreach_id(void *userdata,
|
|||
|
||||
/******** brush mapping stuff *******/
|
||||
void BKE_brush_mapping_copy_data(BrushMapping *dst, BrushMapping *src);
|
||||
const char *BKE_brush_mapping_type_to_str(BrushMappingType mapping);
|
||||
const char *BKE_brush_mapping_type_to_typename(BrushMappingType mapping);
|
||||
const char *BKE_brush_mapping_type_to_str(eBrushMappingType mapping);
|
||||
const char *BKE_brush_mapping_type_to_typename(eBrushMappingType mapping);
|
||||
|
||||
/********* misc utility functions *********/
|
||||
|
||||
|
|
|
@ -261,9 +261,9 @@ template<typename T> class BrushChannelIF {
|
|||
continue;
|
||||
}
|
||||
|
||||
float inputf = (reinterpret_cast<float *>(mapping))[i] * mp->premultiply;
|
||||
float inputf = (reinterpret_cast<float *>(mapping))[i] * mp->premultiply_factor;
|
||||
|
||||
switch ((BrushMappingFunc)mp->mapfunc) {
|
||||
switch ((eBrushMappingFunc)mp->mapfunc) {
|
||||
case BRUSH_MAPFUNC_NONE:
|
||||
break;
|
||||
case BRUSH_MAPFUNC_SAW:
|
||||
|
@ -361,8 +361,8 @@ class BrushChannelSetIF {
|
|||
void destroy()
|
||||
{
|
||||
if (_chset) {
|
||||
if (_chset->namemap) {
|
||||
BLI_ghash_free(_chset->namemap, nullptr, nullptr);
|
||||
if (_chset->channelmap) {
|
||||
BLI_ghash_free(_chset->channelmap, nullptr, nullptr);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (BrushChannel *, ch, &_chset->channels) {
|
||||
|
@ -385,7 +385,7 @@ class BrushChannelSetIF {
|
|||
template<typename T> BrushChannelIF<T> lookup(const char *idname)
|
||||
{
|
||||
BrushChannel *ch = static_cast<BrushChannel *>(
|
||||
BLI_ghash_lookup(_chset->namemap, static_cast<const void *>(idname)));
|
||||
BLI_ghash_lookup(_chset->channelmap, static_cast<const void *>(idname)));
|
||||
BrushChannelIF<T> chif(ch);
|
||||
|
||||
return chif;
|
||||
|
|
|
@ -538,7 +538,7 @@ void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def)
|
|||
|
||||
mp->blendmode = !mdef->no_default ? MA_RAMP_MULT : mdef->blendmode;
|
||||
mp->factor = mdef->factor == 0.0f ? 1.0f : mdef->factor;
|
||||
mp->premultiply = 1.0f;
|
||||
mp->premultiply_factor = 1.0f;
|
||||
mp->func_cutoff = mdef->func_cutoff != 0.0f ? mdef->func_cutoff : 0.5f;
|
||||
|
||||
if (i == BRUSH_MAPPING_STROKE_T) {
|
||||
|
@ -616,7 +616,7 @@ BrushChannelSet *BKE_brush_channelset_create(const char *info)
|
|||
BrushChannelSet *chset = (BrushChannelSet *)MEM_callocN(sizeof(BrushChannelSet),
|
||||
info ? tag : "BrushChannelSet");
|
||||
|
||||
chset->namemap = BLI_ghash_str_new("BrushChannelSet ghash");
|
||||
chset->channelmap = BLI_ghash_str_new("BrushChannelSet ghash");
|
||||
|
||||
return chset;
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ void BKE_brush_channelset_free(BrushChannelSet *chset)
|
|||
{
|
||||
BrushChannel *ch, *next;
|
||||
|
||||
BLI_ghash_free(chset->namemap, NULL, NULL);
|
||||
BLI_ghash_free(chset->channelmap, NULL, NULL);
|
||||
|
||||
for (ch = chset->channels.first; ch; ch = next) {
|
||||
next = ch->next;
|
||||
|
@ -692,22 +692,22 @@ void BKE_brush_channelset_add(BrushChannelSet *chset, BrushChannel *ch)
|
|||
BKE_brush_channel_ensure_unque_name(chset, ch);
|
||||
|
||||
BLI_addtail(&chset->channels, ch);
|
||||
BLI_ghash_insert(chset->namemap, ch->idname, ch);
|
||||
BLI_ghash_insert(chset->channelmap, ch->idname, ch);
|
||||
|
||||
chset->totchannel++;
|
||||
}
|
||||
|
||||
void BKE_brush_channel_rename(BrushChannelSet *chset, BrushChannel *ch, const char *newname)
|
||||
{
|
||||
BLI_ghash_remove(chset->namemap, ch->idname, NULL, NULL);
|
||||
BLI_ghash_remove(chset->channelmap, ch->idname, NULL, NULL);
|
||||
BLI_strncpy(ch->idname, newname, sizeof(ch->idname));
|
||||
BKE_brush_channel_ensure_unque_name(chset, ch);
|
||||
BLI_ghash_insert(chset->namemap, ch->idname, ch);
|
||||
BLI_ghash_insert(chset->channelmap, ch->idname, ch);
|
||||
}
|
||||
|
||||
void BKE_brush_channelset_remove(BrushChannelSet *chset, BrushChannel *ch)
|
||||
{
|
||||
BLI_ghash_remove(chset->namemap, ch->idname, NULL, NULL);
|
||||
BLI_ghash_remove(chset->channelmap, ch->idname, NULL, NULL);
|
||||
BLI_remlink(&chset->channels, ch);
|
||||
|
||||
chset->totchannel--;
|
||||
|
@ -742,7 +742,7 @@ void BKE_brush_channelset_add_duplicate(BrushChannelSet *chset, BrushChannel *ch
|
|||
|
||||
BrushChannel *BKE_brush_channelset_lookup(BrushChannelSet *chset, const char *idname)
|
||||
{
|
||||
return BLI_ghash_lookup(chset->namemap, idname);
|
||||
return BLI_ghash_lookup(chset->channelmap, idname);
|
||||
}
|
||||
|
||||
BrushChannel *BKE_brush_channelset_lookup_final(BrushChannelSet *child,
|
||||
|
@ -1060,9 +1060,9 @@ double BKE_brush_channel_eval_mappings(BrushChannel *ch,
|
|||
continue;
|
||||
}
|
||||
|
||||
float inputf = ((float *)mapdata)[i] * mp->premultiply;
|
||||
float inputf = ((float *)mapdata)[i] * mp->premultiply_factor;
|
||||
|
||||
switch ((BrushMappingFunc)mp->mapfunc) {
|
||||
switch ((eBrushMappingFunc)mp->mapfunc) {
|
||||
case BRUSH_MAPFUNC_NONE:
|
||||
break;
|
||||
case BRUSH_MAPFUNC_SAW:
|
||||
|
@ -1085,7 +1085,7 @@ double BKE_brush_channel_eval_mappings(BrushChannel *ch,
|
|||
break;
|
||||
case BRUSH_MAPFUNC_SQUARE:
|
||||
inputf -= floorf(inputf);
|
||||
inputf = inputf > mp->func_cutoff ? 1.0f : 0.0f; //(float)(inputf > 0.5f);
|
||||
inputf = inputf > mp->func_cutoff ? 1.0f : 0.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1988,7 +1988,7 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
|||
{
|
||||
BLO_read_list(reader, &chset->channels);
|
||||
|
||||
chset->namemap = BLI_ghash_str_new("BrushChannelSet");
|
||||
chset->channelmap = BLI_ghash_str_new("BrushChannelSet");
|
||||
|
||||
BrushChannel *ch;
|
||||
// regenerate chset->totchannel just to be safe
|
||||
|
@ -1997,7 +1997,7 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
|||
for (ch = chset->channels.first; ch; ch = ch->next) {
|
||||
chset->totchannel++;
|
||||
|
||||
BLI_ghash_insert(chset->namemap, ch->idname, ch);
|
||||
BLI_ghash_insert(chset->channelmap, ch->idname, ch);
|
||||
|
||||
BLO_read_data_address(reader, &ch->curve.curve);
|
||||
if (ch->curve.curve) {
|
||||
|
@ -2012,8 +2012,8 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
|||
|
||||
CurveMapping *curve = mp->curve;
|
||||
|
||||
if (mp->premultiply == 0.0f) {
|
||||
mp->premultiply = 1.0f;
|
||||
if (mp->premultiply_factor == 0.0f) {
|
||||
mp->premultiply_factor = 1.0f;
|
||||
}
|
||||
|
||||
if (mp->func_cutoff == 0.0f) {
|
||||
|
@ -2084,7 +2084,7 @@ void BKE_brush_channelset_write(BlendWriter *writer, BrushChannelSet *chset)
|
|||
}
|
||||
}
|
||||
|
||||
const char *BKE_brush_mapping_type_to_str(BrushMappingType mapping)
|
||||
const char *BKE_brush_mapping_type_to_str(eBrushMappingType mapping)
|
||||
{
|
||||
switch (mapping) {
|
||||
case BRUSH_MAPPING_PRESSURE:
|
||||
|
@ -2108,7 +2108,7 @@ const char *BKE_brush_mapping_type_to_str(BrushMappingType mapping)
|
|||
return "Error";
|
||||
}
|
||||
|
||||
const char *BKE_brush_mapping_type_to_typename(BrushMappingType mapping)
|
||||
const char *BKE_brush_mapping_type_to_typename(eBrushMappingType mapping)
|
||||
{
|
||||
switch (mapping) {
|
||||
case BRUSH_MAPPING_PRESSURE:
|
||||
|
@ -2153,13 +2153,10 @@ void BKE_brush_mapping_copy_data(BrushMapping *dst, BrushMapping *src)
|
|||
dst->max = src->max;
|
||||
dst->factor = src->factor;
|
||||
dst->flag = src->flag;
|
||||
dst->input_channel = src->input_channel;
|
||||
dst->blendmode = src->blendmode;
|
||||
dst->func_cutoff = src->func_cutoff;
|
||||
dst->mapfunc = src->mapfunc;
|
||||
dst->premultiply = src->premultiply;
|
||||
|
||||
memcpy(dst->name, src->name, sizeof(dst->name));
|
||||
dst->premultiply_factor = src->premultiply_factor;
|
||||
}
|
||||
|
||||
void BKE_brush_channelset_to_unified_settings(BrushChannelSet *chset, UnifiedPaintSettings *ups)
|
||||
|
|
|
@ -228,7 +228,7 @@ static void fix_mesh(PBVH *pbvh, BMesh *bm)
|
|||
// rebuild disk cycles
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_edge_exists(e->v1, e->v2)) {
|
||||
printf("duplicate edge %p!", e);
|
||||
printf("duplicate edge %p!\n", e);
|
||||
bm_kill_only_edge(bm, e);
|
||||
|
||||
continue;
|
||||
|
@ -333,6 +333,8 @@ CHECKMESH_ATTR static bool check_face_is_manifold(PBVH *pbvh, BMesh *bm, BMFace
|
|||
continue;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
if (!e) {
|
||||
break;
|
||||
|
@ -340,8 +342,14 @@ CHECKMESH_ATTR static bool check_face_is_manifold(PBVH *pbvh, BMesh *bm, BMFace
|
|||
|
||||
bool same = e->v1 == v1 && e->v2 == v2;
|
||||
same = same || (e->v1 == v2 && e->v2 == v1);
|
||||
|
||||
if (same && e != l->e) {
|
||||
printf("duplicate edges!");
|
||||
// printf("duplicate edges in face!\n");
|
||||
}
|
||||
|
||||
if (i++ > 5000) {
|
||||
printf("infinite loop in edge disk cycle! v: %p, e: %p\n", v, e);
|
||||
break;
|
||||
}
|
||||
} while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
|
||||
}
|
||||
|
@ -450,6 +458,35 @@ static bool validate_edge(PBVH *pbvh, BMesh *bm, BMEdge *e, bool autofix, bool c
|
|||
return ret;
|
||||
}
|
||||
|
||||
CHECKMESH_ATTR bool face_verts_are_same(PBVH *pbvh, BMesh *bm, BMFace *f1, BMFace *f2)
|
||||
{
|
||||
BMLoop *l1 = f1->l_first;
|
||||
BMLoop *l2 = f2->l_first;
|
||||
|
||||
int count1 = 0;
|
||||
|
||||
do {
|
||||
count1++;
|
||||
} while ((l1 = l1->next) != f1->l_first);
|
||||
|
||||
do {
|
||||
bool ok = false;
|
||||
|
||||
do {
|
||||
if (l2->v == l1->v) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
} while ((l2 = l2->next) != f2->l_first);
|
||||
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
} while ((l1 = l1->next) != f1->l_first);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CHECKMESH_ATTR
|
||||
static bool validate_face(PBVH *pbvh, BMesh *bm, BMFace *f, bool autofix, bool check_manifold)
|
||||
{
|
||||
|
@ -475,6 +512,14 @@ static bool validate_face(PBVH *pbvh, BMesh *bm, BMFace *f, bool autofix, bool c
|
|||
goto error;
|
||||
}
|
||||
|
||||
BMLoop *l2 = l->radial_next;
|
||||
do {
|
||||
if (l2->f != f && face_verts_are_same(pbvh, bm, l2->f, f)) {
|
||||
_debugprint("Duplicate faces!\n");
|
||||
goto error;
|
||||
}
|
||||
} while ((l2 = l2->radial_next) != l);
|
||||
|
||||
BLI_array_append(ls, l);
|
||||
} while ((l = l->next) != f->l_first);
|
||||
|
||||
|
@ -1420,9 +1465,9 @@ static float maskcb_get(EdgeQueueContext *eq_ctx, BMVert *v1, BMVert *v2)
|
|||
float w1 = eq_ctx->mask_cb(sv1, eq_ctx->mask_cb_data);
|
||||
float w2 = eq_ctx->mask_cb(sv2, eq_ctx->mask_cb_data);
|
||||
|
||||
//float limit = 0.5;
|
||||
//if (w1 > limit || w2 > limit) {
|
||||
return min_ff(w1, w2);
|
||||
// float limit = 0.5;
|
||||
// if (w1 > limit || w2 > limit) {
|
||||
return min_ff(w1, w2);
|
||||
//}
|
||||
|
||||
return (w1 + w2) * 0.5f;
|
||||
|
@ -1441,15 +1486,14 @@ BLI_INLINE float calc_weighted_length(EdgeQueueContext *eq_ctx, BMVert *v1, BMVe
|
|||
float w = 1.0 - maskcb_get(eq_ctx, v1, v2);
|
||||
float len = len_squared_v3v3(v1->co, v2->co);
|
||||
|
||||
w = 1.0 + w*sign;
|
||||
w = 1.0 + w * sign;
|
||||
|
||||
return len * w;
|
||||
}
|
||||
|
||||
static void edge_queue_insert_unified(EdgeQueueContext *eq_ctx, BMEdge *e)
|
||||
{
|
||||
if (/*BLI_mm_heap_len(eq_ctx->heap_mm) < eq_ctx->max_heap_mm &&*/ !(e->head.hflag &
|
||||
BM_ELEM_TAG)) {
|
||||
if (/*BLI_mm_heap_len(eq_ctx->heap_mm) < eq_ctx->max_heap_mm &&*/ !(e->head.hflag & BM_ELEM_TAG)) {
|
||||
float len = len_squared_v3v3(e->v1->co, e->v2->co);
|
||||
|
||||
len += (BLI_thread_frand(0) - 0.5f) * 0.1 * eq_ctx->limit_mid;
|
||||
|
@ -1461,14 +1505,6 @@ static void edge_queue_insert_unified(EdgeQueueContext *eq_ctx, BMEdge *e)
|
|||
|
||||
static void edge_queue_insert_val34_vert(EdgeQueueContext *eq_ctx, BMVert *v)
|
||||
{
|
||||
MSculptVert *mv = BKE_PBVH_SCULPTVERT(eq_ctx->cd_sculpt_vert, v);
|
||||
// prevent double adding
|
||||
|
||||
if (mv->flag & SCULPTVERT_VALENCE_TEMP) {
|
||||
return;
|
||||
}
|
||||
|
||||
mv->flag |= SCULPTVERT_VALENCE_TEMP;
|
||||
BLI_table_gset_add(eq_ctx->used_verts, v);
|
||||
}
|
||||
|
||||
|
@ -1927,6 +1963,15 @@ static void unified_edge_queue_task_cb(void *__restrict userdata,
|
|||
}
|
||||
# endif
|
||||
do {
|
||||
/* kind of tricky to atomicly update flags here. . . */
|
||||
BMEdge edge = *l->e;
|
||||
edge.head.hflag &= ~BM_ELEM_TAG;
|
||||
|
||||
intptr_t *t1 = (uintptr_t*) &edge.head.index;
|
||||
intptr_t *t2 = (uintptr_t *) &l->e->head.index;
|
||||
|
||||
atomic_cas_int64(t2, *t2, *t1);
|
||||
|
||||
l->e->head.hflag &= ~BM_ELEM_TAG;
|
||||
l = l->next;
|
||||
} while (l != f->l_first);
|
||||
|
@ -2135,7 +2180,6 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
|
|||
|
||||
static bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
|
||||
{
|
||||
// return;
|
||||
bm_logstack_push();
|
||||
|
||||
static int max_faces = 64;
|
||||
|
@ -2427,7 +2471,17 @@ static bool edge_queue_test(EdgeQueueContext *eq_ctx, PBVH *pbvh, BMEdge *e)
|
|||
float min = pbvh->bm_min_edge_len * pbvh->bm_min_edge_len;
|
||||
float max = pbvh->bm_max_edge_len * pbvh->bm_max_edge_len;
|
||||
|
||||
return len < min || len > max;
|
||||
bool ret = false;
|
||||
|
||||
if (eq_ctx->mode & PBVH_Subdivide) {
|
||||
ret |= len > max;
|
||||
}
|
||||
|
||||
if (eq_ctx->mode & PBVH_Collapse) {
|
||||
ret |= len < min;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create a priority queue containing vertex pairs connected by a long
|
||||
|
@ -2965,13 +3019,13 @@ static bool bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
|
|||
return false;
|
||||
}
|
||||
|
||||
static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
||||
BMEdge *e,
|
||||
BMVert *v1,
|
||||
BMVert *v2,
|
||||
GHash *deleted_verts,
|
||||
BLI_Buffer *deleted_faces,
|
||||
EdgeQueueContext *eq_ctx)
|
||||
ATTR_NO_OPT static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
||||
BMEdge *e,
|
||||
BMVert *v1,
|
||||
BMVert *v2,
|
||||
GHash *deleted_verts,
|
||||
BLI_Buffer *deleted_faces,
|
||||
EdgeQueueContext *eq_ctx)
|
||||
{
|
||||
bm_logstack_push();
|
||||
|
||||
|
@ -3217,6 +3271,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
}
|
||||
|
||||
pbvh_bmesh_check_nodes(pbvh);
|
||||
validate_vert_faces(pbvh, pbvh->bm, v_conn, false, true);
|
||||
|
||||
if (!snap) {
|
||||
float co[3];
|
||||
|
@ -3225,7 +3280,6 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
|
||||
// full non-manifold collapse
|
||||
BM_edge_collapse(pbvh->bm, e, v_del, true, true, true, true);
|
||||
// non_manifold_collapse(pbvh->bm, e, v_conn);
|
||||
copy_v3_v3(v_conn->co, co);
|
||||
}
|
||||
else {
|
||||
|
@ -3236,7 +3290,6 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
|
||||
// full non-manifold collapse
|
||||
BM_edge_collapse(pbvh->bm, e, v_del, true, true, true, true);
|
||||
// non_manifold_collapse(pbvh->bm, e, v_conn);
|
||||
copy_v3_v3(v_conn->co, co);
|
||||
}
|
||||
|
||||
|
@ -3245,6 +3298,8 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
return v_conn;
|
||||
}
|
||||
|
||||
validate_vert_faces(pbvh, pbvh->bm, v_conn, false, true);
|
||||
|
||||
e2 = v_conn->e;
|
||||
do {
|
||||
BMLoop *l = e2->l;
|
||||
|
@ -3343,6 +3398,19 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
MSculptVert *mv3 = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, v_conn);
|
||||
MV_ADD_FLAG(mv3, mupdateflag);
|
||||
|
||||
if (!v_conn->e) {
|
||||
// delete isolated vertex
|
||||
if (BM_ELEM_CD_GET_INT(v_conn, pbvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
||||
pbvh_bmesh_vert_remove(pbvh, v_conn);
|
||||
}
|
||||
|
||||
BM_log_vert_removed(pbvh->bm_log, v_conn, 0);
|
||||
BM_vert_kill(pbvh->bm, v_conn);
|
||||
|
||||
bm_logstack_pop();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (BM_ELEM_CD_GET_INT(v_conn, pbvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
|
||||
printf("%s: error: failed to remove vert from pbvh?\n", __func__);
|
||||
}
|
||||
|
@ -3389,8 +3457,6 @@ cleanup_valence_3_4(EdgeQueueContext *ectx,
|
|||
const bool use_frontface,
|
||||
const bool use_projected)
|
||||
{
|
||||
return false;
|
||||
|
||||
bool modified = false;
|
||||
|
||||
bm_logstack_push();
|
||||
|
@ -3422,15 +3488,13 @@ cleanup_valence_3_4(EdgeQueueContext *ectx,
|
|||
|
||||
SculptVertRef sv = {.i = (intptr_t)v};
|
||||
|
||||
if (len_squared_v3v3(v->co, center) >= rsqr || !v->e || ectx->mask_cb(sv, ectx->mask_cb_data) < 0.5f) {
|
||||
if (len_squared_v3v3(v->co, center) >= rsqr || !v->e ||
|
||||
ectx->mask_cb(sv, ectx->mask_cb_data) < 0.5f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
MSculptVert *mv = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, v);
|
||||
|
||||
mv->flag &= ~SCULPTVERT_VALENCE_TEMP;
|
||||
|
||||
validate_vert(pbvh, pbvh->bm, v, false, true);
|
||||
check_vert_fan_are_tris(pbvh, v);
|
||||
validate_vert(pbvh, pbvh->bm, v, true, true);
|
||||
|
@ -3972,7 +4036,7 @@ ATTR_NO_OPT bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
|
|||
#ifdef DYNTOPO_USE_MINMAX_HEAP
|
||||
eq_ctx.heap_mm = BLI_mm_heap_new_ex(max_ii(DYNTOPO_MAX_ITER, custom_max_steps));
|
||||
eq_ctx.used_verts = BLI_table_gset_new(__func__);
|
||||
eq_ctx.max_heap_mm = DYNTOPO_MAX_ITER << 2;
|
||||
eq_ctx.max_heap_mm = DYNTOPO_MAX_ITER << 8;
|
||||
eq_ctx.limit_min = pbvh->bm_min_edge_len;
|
||||
eq_ctx.limit_max = pbvh->bm_max_edge_len;
|
||||
eq_ctx.limit_mid = eq_ctx.limit_max * 0.5f + eq_ctx.limit_min * 0.5f;
|
||||
|
@ -3991,6 +4055,9 @@ ATTR_NO_OPT bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
|
|||
use_projected,
|
||||
mode & PBVH_LocalSubdivide);
|
||||
}
|
||||
else {
|
||||
edge_queue_init(&eq_ctx, use_projected, use_frontface, center, view_normal, radius);
|
||||
}
|
||||
|
||||
#ifdef SKINNY_EDGE_FIX
|
||||
// prevent remesher thrashing by throttling edge splitting in pathological case of skinny
|
||||
|
@ -4115,6 +4182,11 @@ ATTR_NO_OPT bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
|
|||
|
||||
MEM_SAFE_FREE(edges);
|
||||
|
||||
if (mode & PBVH_Cleanup) {
|
||||
modified |= do_cleanup_3_4(
|
||||
&eq_ctx, pbvh, center, view_normal, radius, use_frontface, use_projected);
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
// avoid potential infinite loops
|
||||
const int totnode = pbvh->totnode;
|
||||
|
@ -4136,11 +4208,6 @@ ATTR_NO_OPT bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
|
|||
}
|
||||
}
|
||||
|
||||
if (mode & PBVH_Cleanup) {
|
||||
modified |= do_cleanup_3_4(
|
||||
&eq_ctx, pbvh, center, view_normal, radius, use_frontface, use_projected);
|
||||
}
|
||||
|
||||
/* clear PBVH_UpdateTopology flags */
|
||||
for (int i = 0; i < pbvh->totnode; i++) {
|
||||
PBVHNode *node = pbvh->nodes + i;
|
||||
|
@ -4296,12 +4363,12 @@ static const int splitmap[43][16] = {
|
|||
{6, -1, 3, -1, 5, -1, 1, -1}, // 42
|
||||
};
|
||||
|
||||
static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
||||
PBVH *pbvh,
|
||||
BMesh *bm,
|
||||
BMEdge **edges1,
|
||||
int totedge,
|
||||
bool ignore_isolated_edges)
|
||||
ATTR_NO_OPT static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
||||
PBVH *pbvh,
|
||||
BMesh *bm,
|
||||
BMEdge **edges1,
|
||||
int totedge,
|
||||
bool ignore_isolated_edges)
|
||||
{
|
||||
bm_logstack_push();
|
||||
|
||||
|
@ -4384,24 +4451,6 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
BMEdge *e = edges[i];
|
||||
BMLoop *l = e->l;
|
||||
|
||||
#if 0
|
||||
int ni = BM_ELEM_CD_GET_INT(e->v1, pbvh->cd_vert_node_offset);
|
||||
if (ni >= 0) {
|
||||
PBVHNode *node = pbvh->nodes + ni;
|
||||
|
||||
BLI_table_gset_remove(node->bm_unique_verts, e->v1, NULL);
|
||||
BM_ELEM_CD_SET_INT(e->v1, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
||||
}
|
||||
|
||||
ni = BM_ELEM_CD_GET_INT(e->v2, pbvh->cd_vert_node_offset);
|
||||
if (ni >= 0) {
|
||||
PBVHNode *node = pbvh->nodes + ni;
|
||||
|
||||
BLI_table_gset_remove(node->bm_unique_verts, e->v2, NULL);
|
||||
BM_ELEM_CD_SET_INT(e->v2, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
check_vert_fan_are_tris(pbvh, e->v1);
|
||||
check_vert_fan_are_tris(pbvh, e->v2);
|
||||
|
||||
|
@ -4599,7 +4648,6 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
|
||||
MV_ADD_FLAG(mv,
|
||||
SCULPTVERT_NEED_DISK_SORT | SCULPTVERT_NEED_VALENCE | SCULPTVERT_NEED_BOUNDARY);
|
||||
mv->flag &= ~SCULPTVERT_VALENCE_TEMP;
|
||||
|
||||
BM_ELEM_CD_SET_INT(newv, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
||||
|
||||
|
@ -4772,9 +4820,29 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
continue;
|
||||
}
|
||||
|
||||
bool log_edge = !BM_edge_exists(v1, v2);
|
||||
validate_face(pbvh, bm, f2, false, true);
|
||||
|
||||
bool log_edge = true;
|
||||
BMFace *newf = NULL;
|
||||
BMEdge *exist_e;
|
||||
|
||||
if ((exist_e = BM_edge_exists(v1, v2))) {
|
||||
log_edge = false;
|
||||
|
||||
BMLoop *l1 = exist_e->l;
|
||||
|
||||
if (l1 && l1->f == f2) {
|
||||
l1 = l1->radial_next;
|
||||
}
|
||||
|
||||
if (l1 && l1->f != f2) {
|
||||
// newf = l1->f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
newf = BM_face_split(bm, f2, l1, l2, &rl, NULL, false);
|
||||
}
|
||||
|
||||
BMFace *newf = BM_face_split(bm, f2, l1, l2, &rl, NULL, false);
|
||||
if (newf) {
|
||||
// rl->e->head.hflag &= ~BM_ELEM_TAG;
|
||||
// edge_queue_insert_unified(eq_ctx, rl->e);
|
||||
|
@ -4818,12 +4886,12 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
newfaces[count++] = newf;
|
||||
}
|
||||
else {
|
||||
printf("error!\n");
|
||||
printf("%s: error 4!\n", __func__);
|
||||
}
|
||||
f2 = newf;
|
||||
}
|
||||
else {
|
||||
printf("error!\n");
|
||||
// printf("%s: error 2!\n", __func__);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -722,7 +722,10 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
|
|||
if ((p1_nv == p2_nv) && (memcmp(p1_v, p2_v, p1_nv * sizeof(*p1_v)) == 0)) {
|
||||
if (do_verbose) {
|
||||
/* TODO: convert list to string */
|
||||
PRINT_ERR("\tPolys %u and %u use same vertices (%d", prev_sp->index, sp->index, *p1_v);
|
||||
PRINT_ERR("\tPolys %u(len=%d) and %u use same vertices (%d",
|
||||
prev_sp->index,
|
||||
p1_nv, sp->index,
|
||||
*p1_v);
|
||||
for (j = 1; j < p1_nv; j++) {
|
||||
PRINT_ERR(", %d", p1_v[j]);
|
||||
}
|
||||
|
|
|
@ -2752,8 +2752,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
|
||||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
if (ch->mappings[i].premultiply == 0.0f) {
|
||||
ch->mappings[i].premultiply = 1.0f;
|
||||
if (ch->mappings[i].premultiply_factor == 0.0f) {
|
||||
ch->mappings[i].premultiply_factor = 1.0f;
|
||||
}
|
||||
|
||||
if (ch->mappings[i].blendmode == MA_RAMP_BLEND) {
|
||||
|
@ -2788,7 +2788,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
|
||||
LISTBASE_FOREACH (BrushChannel *, ch, &brush->channels->channels) {
|
||||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
ch->mappings[i].premultiply = 1.0f;
|
||||
ch->mappings[i].premultiply_factor = 1.0f;
|
||||
}
|
||||
|
||||
BrushMapping *mp = ch->mappings + BRUSH_MAPPING_STROKE_T;
|
||||
|
|
|
@ -788,8 +788,6 @@ int bmesh_elem_check(void *element, const char htype)
|
|||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
int bleh = 0;
|
||||
|
||||
/**
|
||||
* low level function, only frees the vert,
|
||||
* doesn't change or adjust surrounding geometry
|
||||
|
@ -811,10 +809,6 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
|
|||
|
||||
BLI_mempool_free(bm->vtoolflagpool, flags->flag);
|
||||
flags->flag = NULL;
|
||||
|
||||
if (bleh) {
|
||||
printf("eek\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (v->head.data) {
|
||||
|
@ -926,6 +920,8 @@ void bm_kill_only_edge(BMesh *bm, BMEdge *e)
|
|||
CustomData_bmesh_free_block(&bm->edata, &e->head.data);
|
||||
}
|
||||
|
||||
e->l = NULL;
|
||||
|
||||
BLI_mempool_free(bm->epool, e);
|
||||
}
|
||||
|
||||
|
@ -2085,8 +2081,8 @@ static char *obj_append_line(char *line, char *str, char *fixed, int *size, int
|
|||
{
|
||||
int len = (int)strlen(line);
|
||||
|
||||
if (*i + len >= *size) {
|
||||
*size += *size >> 1;
|
||||
if (*i + len + 1 >= *size) {
|
||||
*size += len + ((*size) >> 1);
|
||||
|
||||
if (str == fixed) {
|
||||
str = MEM_mallocN(*size, "buf");
|
||||
|
@ -2113,14 +2109,18 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
|
||||
buf[0] = 0;
|
||||
|
||||
BMVert **vs = NULL;
|
||||
BMEdge **es = NULL;
|
||||
BMFace **fs = NULL;
|
||||
BMVert **vs = NULL, **initial_vs = NULL;
|
||||
BMEdge **es = NULL, **initial_es = NULL;
|
||||
BMFace **fs = NULL, **initial_fs = NULL;
|
||||
|
||||
BLI_array_staticdeclare(vs, 64);
|
||||
BLI_array_staticdeclare(es, 64);
|
||||
BLI_array_staticdeclare(fs, 64);
|
||||
|
||||
BLI_array_staticdeclare(initial_vs, 8);
|
||||
BLI_array_staticdeclare(initial_es, 8);
|
||||
BLI_array_staticdeclare(initial_fs, 8);
|
||||
|
||||
SmallHash visit;
|
||||
BLI_smallhash_init(&visit);
|
||||
|
||||
|
@ -2136,12 +2136,15 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
switch (*c) {
|
||||
case 'v':
|
||||
BLI_array_append(vs, (BMVert *)ptr);
|
||||
BLI_array_append(initial_vs, (BMVert *)ptr);
|
||||
break;
|
||||
case 'e':
|
||||
BLI_array_append(es, (BMEdge *)ptr);
|
||||
BLI_array_append(initial_es, (BMEdge *)ptr);
|
||||
break;
|
||||
case 'f':
|
||||
BLI_array_append(fs, (BMFace *)ptr);
|
||||
BLI_array_append(initial_fs, (BMFace *)ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2204,10 +2207,11 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
} while ((l = l->next) != f->l_first);
|
||||
}
|
||||
|
||||
struct {
|
||||
struct stack {
|
||||
BMVert *v;
|
||||
int depth;
|
||||
} stack[256];
|
||||
} *stack = NULL;
|
||||
BLI_array_staticdeclare(stack, 256);
|
||||
|
||||
SmallHash elemset;
|
||||
BLI_smallhash_init(&elemset);
|
||||
|
@ -2225,16 +2229,26 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
for (int i = 0; i < BLI_array_len(vs); i++) {
|
||||
int si = 0;
|
||||
|
||||
BLI_array_clear(stack);
|
||||
|
||||
// connected islands only
|
||||
if (i > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
BLI_array_grow_one(stack);
|
||||
|
||||
stack[si].v = vs[i];
|
||||
stack[si].depth = 0;
|
||||
si++;
|
||||
|
||||
while (si > 0) {
|
||||
BLI_array_len_set(stack, BLI_array_len(stack) - 1);
|
||||
|
||||
if (si >= 8192) {
|
||||
printf("%s: stack error\n", __func__);
|
||||
}
|
||||
|
||||
si--;
|
||||
|
||||
BMVert *v = stack[si].v;
|
||||
|
@ -2254,11 +2268,15 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
BMEdge *e = v->e;
|
||||
do {
|
||||
if (!BLI_smallhash_ensure_p(&visit, (uintptr_t)e, &val)) {
|
||||
BLI_array_grow_one(stack);
|
||||
|
||||
*val = NULL;
|
||||
stack[si].v = e->v1;
|
||||
stack[si].depth = startdepth + 1;
|
||||
si++;
|
||||
|
||||
BLI_array_grow_one(stack);
|
||||
|
||||
stack[si].v = e->v2;
|
||||
stack[si].depth = startdepth + 1;
|
||||
si++;
|
||||
|
@ -2279,6 +2297,8 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
BMLoop *l2 = l;
|
||||
do {
|
||||
if (!BLI_smallhash_ensure_p(&visit, (uintptr_t)l->v, &val)) {
|
||||
BLI_array_grow_one(stack);
|
||||
|
||||
*val = NULL;
|
||||
stack[si].v = l->v;
|
||||
stack[si].depth = startdepth + 1;
|
||||
|
@ -2299,11 +2319,48 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
es[i]->head.api_flag &= ~tag;
|
||||
}
|
||||
|
||||
char line[256];
|
||||
char line[128];
|
||||
line[0] = 0;
|
||||
|
||||
for (int i = 0; i < BLI_array_len(vs); i++) {
|
||||
vs[i]->head.api_flag &= ~tag;
|
||||
}
|
||||
for (int i = 0; i < BLI_array_len(es); i++) {
|
||||
es[i]->head.api_flag &= ~tag;
|
||||
}
|
||||
for (int i = 0; i < BLI_array_len(fs); i++) {
|
||||
fs[i]->head.api_flag &= ~tag;
|
||||
}
|
||||
|
||||
for (int i = 0; i < BLI_array_len(initial_vs); i++) {
|
||||
initial_vs[i]->head.api_flag |= tag;
|
||||
}
|
||||
|
||||
for (int i = 0; i < BLI_array_len(initial_es); i++) {
|
||||
initial_es[i]->head.api_flag |= tag;
|
||||
initial_es[i]->v1->head.api_flag |= tag;
|
||||
initial_es[i]->v2->head.api_flag |= tag;
|
||||
}
|
||||
|
||||
for (int i = 0; i < BLI_array_len(initial_fs); i++) {
|
||||
BMFace *f = initial_fs[i];
|
||||
|
||||
f->head.api_flag |= tag;
|
||||
BMLoop *l = f->l_first;
|
||||
|
||||
do {
|
||||
l->v->head.api_flag |= tag;
|
||||
} while ((l = l->next) != f->l_first);
|
||||
}
|
||||
|
||||
for (int i = 0; i < BLI_array_len(vs); i++) {
|
||||
BMVert *v = vs[i];
|
||||
|
||||
if (v->head.api_flag & tag) {
|
||||
sprintf(line, "#select\n");
|
||||
str = obj_append_line(line, str, buf, &size, &stri);
|
||||
}
|
||||
|
||||
v->head.index = i + 1;
|
||||
sprintf(line, "v %.4f %.4f %.4f\n", v->co[0], v->co[1], v->co[2]);
|
||||
|
||||
|
@ -2319,6 +2376,7 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
|
||||
do {
|
||||
sprintf(line, " %d", l->v->head.index);
|
||||
|
||||
str = obj_append_line(line, str, buf, &size, &stri);
|
||||
} while ((l = l->next) != f->l_first);
|
||||
|
||||
|
@ -2331,6 +2389,11 @@ ATTR_NO_OPT static char *bm_save_local_obj_text(
|
|||
BLI_array_free(vs);
|
||||
BLI_array_free(es);
|
||||
BLI_array_free(fs);
|
||||
BLI_array_free(stack);
|
||||
|
||||
BLI_array_free(initial_vs);
|
||||
BLI_array_free(initial_es);
|
||||
BLI_array_free(initial_fs);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
@ -2374,14 +2437,21 @@ char *_last_local_obj = NULL;
|
|||
# define JVKE_CHECK_ELEMENT(elem)
|
||||
#endif
|
||||
|
||||
BMVert *bmesh_kernel_join_vert_kill_edge(
|
||||
ATTR_NO_OPT BMVert *bmesh_kernel_join_vert_kill_edge(
|
||||
BMesh *bm, BMEdge *e, BMVert *v_kill, const bool do_del, const bool combine_flags)
|
||||
{
|
||||
BMVert *v_conn = BM_edge_other_vert(e, v_kill);
|
||||
|
||||
#ifdef JVKE_DEBUG
|
||||
char buf[LOCAL_OBJ_SIZE];
|
||||
char *saved_obj = _last_local_obj = bm_save_local_obj_text(bm, 2, buf, "e", e);
|
||||
|
||||
if (_last_local_obj) {
|
||||
free(_last_local_obj);
|
||||
}
|
||||
|
||||
char *saved_obj = bm_save_local_obj_text(bm, 2, buf, "e", e);
|
||||
_last_local_obj = strdup(saved_obj);
|
||||
|
||||
bm_local_obj_free(saved_obj, buf);
|
||||
#endif
|
||||
|
||||
|
@ -2392,6 +2462,7 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
|
|||
|
||||
BMVert *v_del = BM_edge_other_vert(e, v_conn);
|
||||
const int tag = _FLAG_WALK_ALT; // using bmhead.api_flag here
|
||||
const int dup_tag = _FLAG_OVERLAP;
|
||||
|
||||
JVKE_CHECK_ELEMENT(v_conn);
|
||||
JVKE_CHECK_ELEMENT(v_del);
|
||||
|
@ -2408,6 +2479,10 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
|
|||
BMLoop *l = e2->l;
|
||||
do {
|
||||
BM_ELEM_API_FLAG_DISABLE(l->f, tag);
|
||||
|
||||
BM_ELEM_API_FLAG_DISABLE(l->f, dup_tag);
|
||||
BM_ELEM_API_FLAG_DISABLE(l->e, dup_tag);
|
||||
BM_ELEM_API_FLAG_DISABLE(l->v, dup_tag);
|
||||
} while ((l = l->radial_next) != e2->l);
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
}
|
||||
|
@ -2605,6 +2680,10 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
|
|||
}
|
||||
|
||||
bmesh_radial_loop_append(l->e, l);
|
||||
|
||||
BM_ELEM_API_FLAG_DISABLE(l->e, dup_tag);
|
||||
BM_ELEM_API_FLAG_DISABLE(l->v, dup_tag);
|
||||
BM_ELEM_API_FLAG_DISABLE(l->f, dup_tag);
|
||||
} while ((l = l->next) != f->l_first);
|
||||
}
|
||||
|
||||
|
@ -2635,6 +2714,89 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
|
|||
}
|
||||
#endif
|
||||
|
||||
/* use euler criteria to check for duplicate faces */
|
||||
if (do_del && v_conn->e) {
|
||||
int tote = 0, totv = 0, totf = 0;
|
||||
|
||||
BMVert *v = v_conn;
|
||||
BMEdge *e2 = v->e;
|
||||
|
||||
if (!BM_ELEM_API_FLAG_TEST(v, dup_tag)) {
|
||||
BM_ELEM_API_FLAG_ENABLE(v, dup_tag);
|
||||
totv++;
|
||||
}
|
||||
|
||||
do {
|
||||
BMVert *v2 = BM_edge_other_vert(e2, v);
|
||||
|
||||
if (!BM_ELEM_API_FLAG_TEST(e2, dup_tag)) {
|
||||
BM_ELEM_API_FLAG_ENABLE(e2, dup_tag);
|
||||
tote++;
|
||||
}
|
||||
if (!BM_ELEM_API_FLAG_TEST(v2, dup_tag)) {
|
||||
BM_ELEM_API_FLAG_ENABLE(v2, dup_tag);
|
||||
totv++;
|
||||
}
|
||||
|
||||
if (e2->l) {
|
||||
BMLoop *l_radial = e2->l;
|
||||
do {
|
||||
if (BM_ELEM_API_FLAG_TEST(l_radial->f, dup_tag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
totf++;
|
||||
|
||||
BM_ELEM_API_FLAG_ENABLE(l_radial->f, dup_tag);
|
||||
BMLoop *l = l_radial;
|
||||
|
||||
do {
|
||||
if (!BM_ELEM_API_FLAG_TEST(l->v, dup_tag)) {
|
||||
BM_ELEM_API_FLAG_ENABLE(l->v, dup_tag);
|
||||
totv++;
|
||||
}
|
||||
|
||||
if (!BM_ELEM_API_FLAG_TEST(l->e, dup_tag)) {
|
||||
BM_ELEM_API_FLAG_ENABLE(l->e, dup_tag);
|
||||
tote++;
|
||||
}
|
||||
} while ((l = l->next) != l_radial);
|
||||
} while ((l_radial = l_radial->radial_next) != e2->l);
|
||||
}
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
|
||||
int eul = totv - tote + totf;
|
||||
if (eul != 1) {
|
||||
//printf("%s: possible duplicate geometry! %d\n", __func__, eul);
|
||||
e2 = v->e;
|
||||
|
||||
do {
|
||||
BMLoop *l = e2->l;
|
||||
|
||||
if (!l) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BMLoop *l_next = l;
|
||||
|
||||
do {
|
||||
/* no guarantee each face has only one loop in radial
|
||||
list */
|
||||
l_next = l->radial_next;
|
||||
|
||||
while (l_next != l && l_next->f == l->f) {
|
||||
l_next = l->radial_next;
|
||||
}
|
||||
|
||||
BMFace *f;
|
||||
|
||||
if ((f = BM_face_find_double(l->f))) {
|
||||
BM_face_kill(bm, l->f);
|
||||
}
|
||||
} while (e2->l && (l = l_next) != e2->l);
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
}
|
||||
}
|
||||
// printf("v_del: %p, v_conn: %p\n", v_del->e, v_conn->e);
|
||||
if (do_del) {
|
||||
JVKE_CHECK_ELEMENT(v_del);
|
||||
|
@ -2648,13 +2810,13 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
|
|||
}
|
||||
|
||||
/*original version of bmesh_kernel_join_vert_kill_edge*/
|
||||
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)
|
||||
ATTR_NO_OPT 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)
|
||||
{
|
||||
BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
|
||||
BMVert *v_target = BM_edge_other_vert(e_kill, v_kill);
|
||||
|
@ -2735,7 +2897,7 @@ BMVert *bmesh_kernel_join_vert_kill_edge_fast(BMesh *bm,
|
|||
return v_target;
|
||||
}
|
||||
|
||||
BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
|
||||
ATTR_NO_OPT BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
|
||||
{
|
||||
BMLoop *l_iter, *l_f1 = NULL, *l_f2 = NULL;
|
||||
int newlen = 0, i, f1len = 0, f2len = 0;
|
||||
|
|
|
@ -464,7 +464,7 @@ BMVert *BM_edge_collapse(BMesh *bm,
|
|||
const bool combine_flags,
|
||||
const bool full_non_manifold_collapse)
|
||||
{
|
||||
if (full_non_manifold_collapse) {
|
||||
if (full_non_manifold_collapse||true) {
|
||||
return bmesh_kernel_join_vert_kill_edge(bm, e_kill, v_kill, do_del, combine_flags);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -413,7 +413,7 @@ void bmesh_radial_loop_append(BMEdge *e, BMLoop *l)
|
|||
l->e = e;
|
||||
}
|
||||
|
||||
void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l)
|
||||
ATTR_NO_OPT void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l)
|
||||
{
|
||||
/* if e is non-NULL, l must be in the radial cycle of e */
|
||||
if (UNLIKELY(e != l->e)) {
|
||||
|
|
|
@ -455,7 +455,9 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
|
|||
BMO_op_finish(bm, &weldop);
|
||||
}
|
||||
|
||||
void bmo_collapse_exec(BMesh *bm, BMOperator *op)
|
||||
#define USE_BM_EDGE_COLLAPSE
|
||||
|
||||
ATTR_NO_OPT void bmo_collapse_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOperator weldop;
|
||||
BMWalker walker;
|
||||
|
@ -521,6 +523,12 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
|
|||
uint j;
|
||||
BLI_stack_pop(edge_stack, &e);
|
||||
|
||||
#ifdef USE_BM_EDGE_COLLAPSE
|
||||
if (e->head.htype != BM_EDGE) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
BMVert *v_src = *((&e->v1) + j);
|
||||
|
||||
|
@ -528,6 +536,11 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
|
|||
if ((v_src != v_tar) && !BM_elem_flag_test(v_src, BM_ELEM_TAG)) {
|
||||
BM_elem_flag_enable(v_src, BM_ELEM_TAG);
|
||||
BMO_slot_map_elem_insert(&weldop, slot_targetmap, v_src, v_tar);
|
||||
|
||||
#ifdef USE_BM_EDGE_COLLAPSE
|
||||
BM_edge_collapse(bm, e, v_src, true, true, true, true);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -536,7 +549,10 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
|
|||
|
||||
BLI_stack_free(edge_stack);
|
||||
|
||||
#ifndef USE_BM_EDGE_COLLAPSE
|
||||
BMO_op_exec(bm, &weldop);
|
||||
#endif
|
||||
|
||||
BMO_op_finish(bm, &weldop);
|
||||
|
||||
BMW_end(&walker);
|
||||
|
|
|
@ -29,26 +29,48 @@
|
|||
|
||||
struct GHash;
|
||||
|
||||
typedef struct BrushMapping {
|
||||
char name[64];
|
||||
/* Input mapping struct. An input mapping transform
|
||||
stroke inputs intos outputs. Inputs can be device
|
||||
events (like pen pressure/tilt) or synethesize
|
||||
(cumulative stroke distance, random, etc).
|
||||
|
||||
/*reference to a cached curve, see BKE_curvemapping_cache*/
|
||||
Inspired by Krita.
|
||||
*/
|
||||
typedef struct BrushMapping {
|
||||
/* note that we use a curve cache (see BKE_curvemapping_cache)
|
||||
and copy on write semantics. BrushChannels are copied
|
||||
extensively (mostly to cache input mappings and resolve
|
||||
channel inheritance), to the point that copying the
|
||||
channel curves was a problem.
|
||||
|
||||
*/
|
||||
CurveMapping *curve;
|
||||
|
||||
float factor;
|
||||
short blendmode;
|
||||
short input_channel;
|
||||
int blendmode; /* blendmode, a subset of the MA_BLEND_XXX enums*/
|
||||
|
||||
int flag, type;
|
||||
|
||||
float min, max;
|
||||
float premultiply; // premultiply input data
|
||||
int mapfunc;
|
||||
float premultiply_factor; /** factor to premultiply input data with */
|
||||
|
||||
int mapfunc; /** mapping function, see eBrushMappingFunc. Most are periodic. */
|
||||
|
||||
/** threshold for BRUSH_MAPFUNC_CUTOFF and BRUSH_MAPFUNC_SQUARE mapping functions */
|
||||
float func_cutoff;
|
||||
|
||||
/** controls whether this channel should inherit from scene defaults,
|
||||
* see eBrushMappingInheritMode */
|
||||
char inherit_mode, _pad[3];
|
||||
} BrushMapping;
|
||||
|
||||
typedef struct BrushCurve {
|
||||
CurveMapping *curve;
|
||||
int preset; // see eBrushCurvePreset, this differs from the one in BrushMappingDef
|
||||
|
||||
/** curve preset, see eBrushCurvePreset.
|
||||
Note: this differs from BrushMappingDef's preset field
|
||||
*/
|
||||
int preset;
|
||||
char preset_slope_negative;
|
||||
char _pad[3];
|
||||
} BrushCurve;
|
||||
|
@ -56,60 +78,78 @@ typedef struct BrushCurve {
|
|||
typedef struct BrushChannel {
|
||||
struct BrushChannel *next, *prev;
|
||||
|
||||
char idname[64];
|
||||
char name[64];
|
||||
char *category; // if NULL, def->category will be used
|
||||
/** Channel id. Avoid calling API methods that take strings directly.
|
||||
There are API facilities to check channel idnames at compile time:
|
||||
the BRUSHSET_XXX macros, SCULPT_get_XXX, etc. On the C++ side
|
||||
BrushChannelSetIF has accessor methods, e.g. BrushChannelSet::radius.
|
||||
*/
|
||||
char idname[64];
|
||||
char name[64]; /** user-friendly name */
|
||||
char *category; /** category; if NULL, def->category will be used */
|
||||
|
||||
struct BrushChannelType *def;
|
||||
struct BrushChannelType *def; /* Brush channel definition */
|
||||
|
||||
float fvalue;
|
||||
int ivalue;
|
||||
float vector[4];
|
||||
/*
|
||||
Need to investigate whether we
|
||||
can use ID properties here. ID properties
|
||||
don't support CurveMappings and do support
|
||||
things we don't want, like groups, strings and
|
||||
ID pointer properties.
|
||||
|
||||
We could implement an ID property CurveMapping
|
||||
type and prevent the creation of group properties
|
||||
at the API level though.
|
||||
*/
|
||||
float fvalue; /** floating point value */
|
||||
int ivalue; /** stores integer, boolean, enum and bitmasks */
|
||||
float vector[4]; /* stores 3 and 4 component vectors */
|
||||
BrushCurve curve;
|
||||
|
||||
BrushMapping mappings[7]; // should always be BRUSH_MAPPING_MAX
|
||||
BrushMapping mappings[7]; /* dimension should always be BRUSH_MAPPING_MAX */
|
||||
|
||||
short type, ui_order;
|
||||
int flag;
|
||||
short type; /** eBrushChannelType */
|
||||
short ui_order;
|
||||
int flag; /** eBrushChannelFlag */
|
||||
} BrushChannel;
|
||||
|
||||
typedef struct BrushChannelSet {
|
||||
ListBase channels;
|
||||
int totchannel, _pad[1];
|
||||
struct GHash *namemap;
|
||||
|
||||
struct GHash *channelmap; /** quick lookup ghash, maps idnames to brush channels */
|
||||
} BrushChannelSet;
|
||||
|
||||
#define BRUSH_CHANNEL_MAX_IDNAME sizeof(((BrushChannel){0}).idname)
|
||||
|
||||
/* BrushMapping->flag */
|
||||
enum {
|
||||
typedef enum eBrushMappingFlags {
|
||||
BRUSH_MAPPING_ENABLED = 1 << 0,
|
||||
BRUSH_MAPPING_INVERT = 1 << 1,
|
||||
BRUSH_MAPPING_UI_EXPANDED = 1 << 2,
|
||||
};
|
||||
} eBrushMappingFlags;
|
||||
|
||||
/* BrushMapping->inherit_mode */
|
||||
enum {
|
||||
typedef enum eBrushMappingInheritMode {
|
||||
/* never inherit */
|
||||
BRUSH_MAPPING_INHERIT_NEVER,
|
||||
/* always inherit */
|
||||
BRUSH_MAPPING_INHERIT_ALWAYS,
|
||||
/* use channel's inheritance mode */
|
||||
BRUSH_MAPPING_INHERIT_CHANNEL
|
||||
};
|
||||
} eBrushMappingInheritMode;
|
||||
|
||||
/* BrushMapping->mapfunc */
|
||||
typedef enum {
|
||||
typedef enum eBrushMappingFunc {
|
||||
BRUSH_MAPFUNC_NONE,
|
||||
BRUSH_MAPFUNC_SAW,
|
||||
BRUSH_MAPFUNC_TENT,
|
||||
BRUSH_MAPFUNC_COS,
|
||||
BRUSH_MAPFUNC_CUTOFF,
|
||||
BRUSH_MAPFUNC_SQUARE,
|
||||
} BrushMappingFunc;
|
||||
BRUSH_MAPFUNC_SQUARE, /* square wave */
|
||||
} eBrushMappingFunc;
|
||||
|
||||
// mapping types
|
||||
typedef enum {
|
||||
typedef enum eBrushMappingType {
|
||||
BRUSH_MAPPING_PRESSURE = 0,
|
||||
BRUSH_MAPPING_XTILT = 1,
|
||||
BRUSH_MAPPING_YTILT = 2,
|
||||
|
@ -118,7 +158,7 @@ typedef enum {
|
|||
BRUSH_MAPPING_RANDOM = 5,
|
||||
BRUSH_MAPPING_STROKE_T = 6,
|
||||
BRUSH_MAPPING_MAX = 7 // see BrushChannel.mappings
|
||||
} BrushMappingType;
|
||||
} eBrushMappingType;
|
||||
|
||||
#ifndef __GNUC__
|
||||
static_assert(offsetof(BrushChannel, type) - offsetof(BrushChannel, mappings) ==
|
||||
|
@ -127,7 +167,7 @@ static_assert(offsetof(BrushChannel, type) - offsetof(BrushChannel, mappings) ==
|
|||
#endif
|
||||
|
||||
// BrushChannel->flag
|
||||
typedef enum {
|
||||
typedef enum eBrushChannelFlag {
|
||||
BRUSH_CHANNEL_INHERIT = 1 << 0,
|
||||
BRUSH_CHANNEL_INHERIT_IF_UNSET = 1 << 1,
|
||||
BRUSH_CHANNEL_NO_MAPPINGS = 1 << 2,
|
||||
|
@ -139,7 +179,7 @@ typedef enum {
|
|||
} eBrushChannelFlag;
|
||||
|
||||
// BrushChannelType->type
|
||||
enum {
|
||||
typedef enum eBrushChannelType {
|
||||
BRUSH_CHANNEL_TYPE_FLOAT = 1 << 0,
|
||||
BRUSH_CHANNEL_TYPE_INT = 1 << 1,
|
||||
BRUSH_CHANNEL_TYPE_ENUM = 1 << 2,
|
||||
|
@ -148,15 +188,15 @@ enum {
|
|||
BRUSH_CHANNEL_TYPE_VEC3 = 1 << 5,
|
||||
BRUSH_CHANNEL_TYPE_VEC4 = 1 << 6,
|
||||
BRUSH_CHANNEL_TYPE_CURVE = 1 << 7
|
||||
};
|
||||
} eBrushChannelType;
|
||||
|
||||
/* clang-format off */
|
||||
enum {
|
||||
typedef enum eBrushChannelSubType {
|
||||
BRUSH_CHANNEL_NONE,
|
||||
BRUSH_CHANNEL_COLOR,
|
||||
BRUSH_CHANNEL_FACTOR,
|
||||
BRUSH_CHANNEL_PERCENT,
|
||||
BRUSH_CHANNEL_PIXEL,
|
||||
BRUSH_CHANNEL_ANGLE
|
||||
};
|
||||
} eBrushChannelSubType;
|
||||
/* clang-format on */
|
||||
|
|
|
@ -689,7 +689,7 @@ void RNA_def_brush_mapping(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Factor", "Mapping factor");
|
||||
|
||||
prop = RNA_def_property(srna, "premultiply", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "premultiply");
|
||||
RNA_def_property_float_sdna(prop, NULL, "premultiply_factor");
|
||||
RNA_def_property_range(prop, -100000, 100000);
|
||||
RNA_def_property_ui_range(prop, -100, 100, 0.01, 3);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
|
|
Loading…
Reference in New Issue