Skip to content

Commit 4ce5680

Browse files
MeshAlgo::deleteFaces : Fix crease handling
1 parent 0746e8c commit 4ce5680

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

src/IECoreScene/MeshAlgoDeleteFaces.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,25 +111,35 @@ void deleteCreases( MeshPrimitive *out, const MeshPrimitive *in, const std::vect
111111
Canceller::check( canceller );
112112
}
113113

114-
int outLength = 0;
115-
for( int j = 0; j < lengths[i]; ++j )
114+
int j = 0;
115+
while( j < lengths[i] )
116116
{
117-
int id = remapping[ ids[creaseIdOffset + j] ];
118-
if( id != -1 )
117+
// Skip non included verts
118+
while( j < lengths[i] && remapping[ ids[ creaseIdOffset + j ] ] == -1 )
119119
{
120-
// \todo: This is not strictly correct. We might be adding creases
121-
// for edges that no longer exist (ie when a particular creased face
122-
// was deleted, but all of its original vertices remain).
123-
outIds.push_back( id );
124-
++outLength;
120+
j++;
125121
}
122+
int startCrease = j;
126123

127-
}
124+
// Scan until we reach the end, or a vert that isn't included.
125+
// If there in a non-included vert in the middle of a crease of length 5 or more,
126+
// we may need to output more than one crease per input crease.
127+
while( j < lengths[i] && remapping[ ids[ creaseIdOffset + j ] ] != -1 )
128+
{
129+
j++;
130+
}
128131

129-
if( outLength > 0 )
130-
{
131-
outLengths.push_back( outLength );
132-
outSharpnesses.push_back( sharpnesses[i] );
132+
// We've either reached the end, or a non-included vert - output a crease
133+
if( j - startCrease >= 2 )
134+
{
135+
for( int k = startCrease; k < j; k++ )
136+
{
137+
// \todo - a little wasteful here, should be caching these lookups in the remapping map
138+
outIds.push_back( remapping[ ids[ creaseIdOffset + k ] ] );
139+
}
140+
outLengths.push_back( j - startCrease );
141+
outSharpnesses.push_back( sharpnesses[i] );
142+
}
133143
}
134144

135145
creaseIdOffset += lengths[i];

test/IECoreScene/MeshAlgoDeleteFacesTest.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,10 @@ def testCornersAndCreases( self ) :
328328
cornerIds = [ 1, 2 ]
329329
cornerSharpnesses = [ 1.0, 2.0 ]
330330
mesh.setCorners( IECore.IntVectorData( cornerIds ), IECore.FloatVectorData( cornerSharpnesses ) )
331+
332+
# First test - the first 3 vertex crease include two edges through vertex 1, which is not
333+
# used in the second triangle, and is getting deleted. This whole crease will be deleted, since
334+
# neither edge is in the final mesh
331335
creaseLengths = [ 3, 2 ]
332336
creaseIds = [ 0, 1, 2, 2, 3 ] # note that these are vertex ids
333337
creaseSharpnesses = [ 1.0, 2.0 ]
@@ -345,10 +349,35 @@ def testCornersAndCreases( self ) :
345349

346350
self.assertEqual( facesDeletedMesh.cornerIds(), IECore.IntVectorData( [ 1 ] ) )
347351
self.assertEqual( facesDeletedMesh.cornerSharpnesses(), IECore.FloatVectorData( [ 2.0 ] ) )
352+
self.assertEqual( facesDeletedMesh.creaseLengths(), IECore.IntVectorData( [ 2 ] ) )
353+
self.assertEqual( facesDeletedMesh.creaseIds(), IECore.IntVectorData( [ 1, 2 ] ) )
354+
self.assertEqual( facesDeletedMesh.creaseSharpnesses(), IECore.FloatVectorData( [ 2.0 ] ) )
355+
356+
# Second test - the first crease includes two edges, one is deleted, the other is left
357+
creaseLengths = [ 3, 2 ]
358+
creaseIds = [ 0, 2, 1, 2, 3 ] # note that these are vertex ids
359+
creaseSharpnesses = [ 1.0, 2.0 ]
360+
mesh.setCreases( IECore.IntVectorData( creaseLengths ), IECore.IntVectorData( creaseIds ), IECore.FloatVectorData( creaseSharpnesses ) )
361+
362+
facesDeletedMesh = IECoreScene.MeshAlgo.deleteFaces( mesh, mesh["delete"] )
363+
348364
self.assertEqual( facesDeletedMesh.creaseLengths(), IECore.IntVectorData( [ 2, 2 ] ) )
349365
self.assertEqual( facesDeletedMesh.creaseIds(), IECore.IntVectorData( [ 0, 1, 1, 2 ] ) )
350366
self.assertEqual( facesDeletedMesh.creaseSharpnesses(), IECore.FloatVectorData( [ 1.0, 2.0 ] ) )
351367

368+
#Third test - one long crease of 4 edges, where the middle vertex is removed, resulting in two 1
369+
# edge creases
370+
creaseLengths = [ 5 ]
371+
creaseIds = [ 3, 0, 1, 2, 3 ] # note that these are vertex ids
372+
creaseSharpnesses = [ 3.0 ]
373+
mesh.setCreases( IECore.IntVectorData( creaseLengths ), IECore.IntVectorData( creaseIds ), IECore.FloatVectorData( creaseSharpnesses ) )
374+
375+
facesDeletedMesh = IECoreScene.MeshAlgo.deleteFaces( mesh, mesh["delete"] )
376+
377+
self.assertEqual( facesDeletedMesh.creaseLengths(), IECore.IntVectorData( [ 2, 2 ] ) )
378+
self.assertEqual( facesDeletedMesh.creaseIds(), IECore.IntVectorData( [ 2, 0, 1, 2 ] ) )
379+
self.assertEqual( facesDeletedMesh.creaseSharpnesses(), IECore.FloatVectorData( [ 3.0, 3.0 ] ) )
380+
352381
def testBadPrimitiveVariables( self ):
353382

354383
planeMesh = IECoreScene.MeshPrimitive.createPlane( imath.Box2f( imath.V2f( 0 ), imath.V2f( 2 ) ), imath.V2i( 1, 1 ) )

0 commit comments

Comments
 (0)