forked from bartvdbraak/blender
Fix simple subsurf on wire edges
Subsurf on wire edges gave smooth results even if set to simple subdiv. Added a field to the CCG meshIFC to flag simple subdivision, then when syncing vertices simply skip moving vertices if in simple-subdiv mode. This change affects two places, the level-1 build in sync and the subdivision up to other levels. Fixes bug [#32268] Simple Subsurf Modifier gives unexpected results on edges without faces projects.blender.org/tracker/index.php?func=detail&aid=32268&group_id=9&atid=498
This commit is contained in:
parent
e30ed91b90
commit
12425588f2
@ -1798,7 +1798,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
|
|||||||
if (seamEdges < 2 || seamEdges != v->numEdges)
|
if (seamEdges < 2 || seamEdges != v->numEdges)
|
||||||
seam = 0;
|
seam = 0;
|
||||||
|
|
||||||
if (!v->numEdges) {
|
if (!v->numEdges || ss->meshIFC.simpleSubdiv) {
|
||||||
VertDataCopy(nCo, co, ss);
|
VertDataCopy(nCo, co, ss);
|
||||||
}
|
}
|
||||||
else if (_vert_isBoundary(v)) {
|
else if (_vert_isBoundary(v)) {
|
||||||
@ -2246,7 +2246,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
|
|||||||
if (seamEdges < 2 || seamEdges != v->numEdges)
|
if (seamEdges < 2 || seamEdges != v->numEdges)
|
||||||
seam = 0;
|
seam = 0;
|
||||||
|
|
||||||
if (!v->numEdges) {
|
if (!v->numEdges || ss->meshIFC.simpleSubdiv) {
|
||||||
VertDataCopy(nCo, co, ss);
|
VertDataCopy(nCo, co, ss);
|
||||||
}
|
}
|
||||||
else if (_vert_isBoundary(v)) {
|
else if (_vert_isBoundary(v)) {
|
||||||
@ -2827,6 +2827,11 @@ int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss)
|
||||||
|
{
|
||||||
|
return ss->meshIFC.simpleSubdiv;
|
||||||
|
}
|
||||||
|
|
||||||
/* Vert accessors */
|
/* Vert accessors */
|
||||||
|
|
||||||
CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v)
|
CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v)
|
||||||
|
@ -17,6 +17,7 @@ typedef struct CCGMeshIFC {
|
|||||||
int vertUserSize, edgeUserSize, faceUserSize;
|
int vertUserSize, edgeUserSize, faceUserSize;
|
||||||
int numLayers;
|
int numLayers;
|
||||||
int vertDataSize;
|
int vertDataSize;
|
||||||
|
int simpleSubdiv;
|
||||||
} CCGMeshIFC;
|
} CCGMeshIFC;
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
@ -91,6 +92,7 @@ int ccgSubSurf_getEdgeSize (const CCGSubSurf *ss);
|
|||||||
int ccgSubSurf_getEdgeLevelSize (const CCGSubSurf *ss, int level);
|
int ccgSubSurf_getEdgeLevelSize (const CCGSubSurf *ss, int level);
|
||||||
int ccgSubSurf_getGridSize (const CCGSubSurf *ss);
|
int ccgSubSurf_getGridSize (const CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getGridLevelSize (const CCGSubSurf *ss, int level);
|
int ccgSubSurf_getGridLevelSize (const CCGSubSurf *ss, int level);
|
||||||
|
int ccgSubSurf_getSimpleSubdiv (const CCGSubSurf *ss);
|
||||||
|
|
||||||
CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v);
|
CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v);
|
||||||
CCGVertHDL ccgSubSurf_getVertVertHandle (CCGVert *v);
|
CCGVertHDL ccgSubSurf_getVertVertHandle (CCGVert *v);
|
||||||
|
@ -113,7 +113,8 @@ typedef enum {
|
|||||||
CCG_USE_ARENA = 2,
|
CCG_USE_ARENA = 2,
|
||||||
CCG_CALC_NORMALS = 4,
|
CCG_CALC_NORMALS = 4,
|
||||||
/* add an extra four bytes for a mask layer */
|
/* add an extra four bytes for a mask layer */
|
||||||
CCG_ALLOC_MASK = 8
|
CCG_ALLOC_MASK = 8,
|
||||||
|
CCG_SIMPLE_SUBDIV = 16
|
||||||
} CCGFlags;
|
} CCGFlags;
|
||||||
|
|
||||||
static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
|
static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
|
||||||
@ -133,7 +134,10 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
|
|||||||
|
|
||||||
ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
|
ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
|
||||||
|
|
||||||
if (oldUseAging != useAging) {
|
if ((oldUseAging != useAging) ||
|
||||||
|
(ccgSubSurf_getSimpleSubdiv(prevSS) !=
|
||||||
|
!!(flags & CCG_SIMPLE_SUBDIV)))
|
||||||
|
{
|
||||||
ccgSubSurf_free(prevSS);
|
ccgSubSurf_free(prevSS);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -156,6 +160,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
|
|||||||
ifc.vertDataSize += sizeof(float) * 3;
|
ifc.vertDataSize += sizeof(float) * 3;
|
||||||
if (flags & CCG_ALLOC_MASK)
|
if (flags & CCG_ALLOC_MASK)
|
||||||
ifc.vertDataSize += sizeof(float);
|
ifc.vertDataSize += sizeof(float);
|
||||||
|
ifc.simpleSubdiv = !!(flags & CCG_SIMPLE_SUBDIV);
|
||||||
|
|
||||||
if (useArena) {
|
if (useArena) {
|
||||||
CCGAllocatorIFC allocatorIFC;
|
CCGAllocatorIFC allocatorIFC;
|
||||||
@ -3474,7 +3479,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
|
|||||||
float (*vertCos)[3],
|
float (*vertCos)[3],
|
||||||
SubsurfFlags flags)
|
SubsurfFlags flags)
|
||||||
{
|
{
|
||||||
int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
|
int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0;
|
||||||
CCGFlags useAging = smd->flags & eSubsurfModifierFlag_DebugIncr ? CCG_USE_AGING : 0;
|
CCGFlags useAging = smd->flags & eSubsurfModifierFlag_DebugIncr ? CCG_USE_AGING : 0;
|
||||||
int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
|
int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
|
||||||
int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
|
int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
|
||||||
@ -3483,7 +3488,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
|
|||||||
if (flags & SUBSURF_FOR_EDIT_MODE) {
|
if (flags & SUBSURF_FOR_EDIT_MODE) {
|
||||||
int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels) : smd->levels;
|
int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels) : smd->levels;
|
||||||
|
|
||||||
smd->emCache = _getSubSurf(smd->emCache, levels, 3, useAging | CCG_CALC_NORMALS);
|
smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
|
||||||
ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
|
ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
|
||||||
|
|
||||||
result = getCCGDerivedMesh(smd->emCache,
|
result = getCCGDerivedMesh(smd->emCache,
|
||||||
@ -3498,7 +3503,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
|
|||||||
if (levels == 0)
|
if (levels == 0)
|
||||||
return dm;
|
return dm;
|
||||||
|
|
||||||
ss = _getSubSurf(NULL, levels, 3, CCG_USE_ARENA | CCG_CALC_NORMALS);
|
ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS);
|
||||||
|
|
||||||
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
|
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
|
||||||
|
|
||||||
@ -3529,7 +3534,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) {
|
if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) {
|
||||||
smd->mCache = ss = _getSubSurf(smd->mCache, levels, 3, useAging | CCG_CALC_NORMALS);
|
smd->mCache = ss = _getSubSurf(smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
|
||||||
|
|
||||||
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
|
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
|
||||||
|
|
||||||
@ -3538,7 +3543,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
|
|||||||
useSubsurfUv, dm);
|
useSubsurfUv, dm);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CCGFlags ccg_flags = CCG_USE_ARENA | CCG_CALC_NORMALS;
|
CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS;
|
||||||
|
|
||||||
if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
|
if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
|
||||||
ccgSubSurf_free(smd->mCache);
|
ccgSubSurf_free(smd->mCache);
|
||||||
|
Loading…
Reference in New Issue
Block a user