@ -27,6 +27,7 @@
# include <sstream>
# include <sstream>
# include <Corrade/Containers/BitArray.h>
# include <Corrade/Containers/BitArray.h>
# include <Corrade/Containers/BitArrayView.h>
# include <Corrade/Containers/BitArrayView.h>
# include <Corrade/Containers/Optional.h>
# include <Corrade/TestSuite/Tester.h>
# include <Corrade/TestSuite/Tester.h>
# include <Corrade/Utility/DebugStl.h>
# include <Corrade/Utility/DebugStl.h>
@ -46,11 +47,13 @@ struct FilterTest: TestSuite::Tester {
void attributes ( ) ;
void attributes ( ) ;
void attributesNoIndexData ( ) ;
void attributesNoIndexData ( ) ;
void attributesRvalue ( ) ;
void attributesWrongBitCount ( ) ;
void attributesWrongBitCount ( ) ;
void onlyAttributes ( ) ;
void onlyAttributes ( ) ;
void onlyAttributesNoIndexData ( ) ;
void onlyAttributesNoIndexData ( ) ;
void onlyAttributesNoAttributeData ( ) ;
void onlyAttributesNoAttributeData ( ) ;
void onlyAttributesRvalue ( ) ;
# ifdef MAGNUM_BUILD_DEPRECATED
# ifdef MAGNUM_BUILD_DEPRECATED
void onlyAttributeIds ( ) ;
void onlyAttributeIds ( ) ;
@ -62,6 +65,7 @@ struct FilterTest: TestSuite::Tester {
void exceptAttributes ( ) ;
void exceptAttributes ( ) ;
void exceptAttributesNoIndexData ( ) ;
void exceptAttributesNoIndexData ( ) ;
void exceptAttributesNoAttributeData ( ) ;
void exceptAttributesNoAttributeData ( ) ;
void exceptAttributesRvalue ( ) ;
# ifdef MAGNUM_BUILD_DEPRECATED
# ifdef MAGNUM_BUILD_DEPRECATED
void exceptAttributeIds ( ) ;
void exceptAttributeIds ( ) ;
@ -79,18 +83,44 @@ const struct {
{ " implementation-specific index type " , meshIndexTypeWrap ( 0xcaca ) }
{ " implementation-specific index type " , meshIndexTypeWrap ( 0xcaca ) }
} ;
} ;
const struct {
const char * name ;
Trade : : DataFlags indexDataFlags , vertexDataFlags ;
Trade : : DataFlags expectedIndexDataFlags , expectedVertexDataFlags ;
} AttributesRvalueData [ ] {
/* The Global or ExternallyOwned flags are not preserved, because
reference ( ) doesn ' t preserve them either */
{ " neither owned " ,
{ } , Trade : : DataFlag : : Global ,
{ } , { } } ,
{ " index data owned " ,
Trade : : DataFlag : : Owned , { } ,
Trade : : DataFlag : : Owned | Trade : : DataFlag : : Mutable , { } } ,
{ " vertex data owned " ,
Trade : : DataFlag : : ExternallyOwned , Trade : : DataFlag : : Owned | Trade : : DataFlag : : Mutable ,
{ } , Trade : : DataFlag : : Owned | Trade : : DataFlag : : Mutable } ,
{ " both owned " ,
Trade : : DataFlag : : Owned , Trade : : DataFlag : : Owned ,
Trade : : DataFlag : : Owned | Trade : : DataFlag : : Mutable , Trade : : DataFlag : : Owned | Trade : : DataFlag : : Mutable } ,
} ;
FilterTest : : FilterTest ( ) {
FilterTest : : FilterTest ( ) {
addInstancedTests ( { & FilterTest : : attributes } ,
addInstancedTests ( { & FilterTest : : attributes } ,
Containers : : arraySize ( ImplementationSpecificIndexTypeData ) ) ;
Containers : : arraySize ( ImplementationSpecificIndexTypeData ) ) ;
addTests ( { & FilterTest : : attributesNoIndexData ,
addTests ( { & FilterTest : : attributesNoIndexData } ) ;
& FilterTest : : attributesWrongBitCount } ) ;
addInstancedTests ( { & FilterTest : : attributesRvalue } ,
Containers : : arraySize ( AttributesRvalueData ) ) ;
addTests ( { & FilterTest : : attributesWrongBitCount } ) ;
addInstancedTests ( { & FilterTest : : onlyAttributes } ,
addInstancedTests ( { & FilterTest : : onlyAttributes } ,
Containers : : arraySize ( ImplementationSpecificIndexTypeData ) ) ;
Containers : : arraySize ( ImplementationSpecificIndexTypeData ) ) ;
addTests ( { & FilterTest : : onlyAttributesNoIndexData ,
addTests ( { & FilterTest : : onlyAttributesNoIndexData ,
& FilterTest : : onlyAttributesNoAttributeData } ) ;
& FilterTest : : onlyAttributesNoAttributeData ,
& FilterTest : : onlyAttributesRvalue } ) ;
# ifdef MAGNUM_BUILD_DEPRECATED
# ifdef MAGNUM_BUILD_DEPRECATED
addInstancedTests ( { & FilterTest : : onlyAttributeIds } ,
addInstancedTests ( { & FilterTest : : onlyAttributeIds } ,
@ -105,7 +135,8 @@ FilterTest::FilterTest() {
Containers : : arraySize ( ImplementationSpecificIndexTypeData ) ) ;
Containers : : arraySize ( ImplementationSpecificIndexTypeData ) ) ;
addTests ( { & FilterTest : : exceptAttributesNoIndexData ,
addTests ( { & FilterTest : : exceptAttributesNoIndexData ,
& FilterTest : : exceptAttributesNoAttributeData } ) ;
& FilterTest : : exceptAttributesNoAttributeData ,
& FilterTest : : exceptAttributesRvalue } ) ;
# ifdef MAGNUM_BUILD_DEPRECATED
# ifdef MAGNUM_BUILD_DEPRECATED
addInstancedTests ( { & FilterTest : : exceptAttributeIds } ,
addInstancedTests ( { & FilterTest : : exceptAttributeIds } ,
@ -202,6 +233,66 @@ void FilterTest::attributesNoIndexData() {
CORRADE_COMPARE ( filtered . attributeOffset ( 0 ) , offsetof ( Vertex , textureCoordinates1 ) ) ;
CORRADE_COMPARE ( filtered . attributeOffset ( 0 ) , offsetof ( Vertex , textureCoordinates1 ) ) ;
}
}
void FilterTest : : attributesRvalue ( ) {
auto & & data = AttributesRvalueData [ testCaseInstanceId ( ) ] ;
setTestCaseDescription ( data . name ) ;
/* Subset of attributes() verifying data ownership transfer behavior */
Containers : : Array < char > indexData { 5 * sizeof ( UnsignedShort ) } ;
Containers : : StridedArrayView1D < UnsignedShort > indices = Containers : : arrayCast < UnsignedShort > ( indexData ) ;
Containers : : Array < char > vertexData { 3 * sizeof ( Vertex ) } ;
Containers : : StridedArrayView1D < Vertex > vertices = Containers : : arrayCast < Vertex > ( vertexData ) ;
Containers : : Array < Trade : : MeshAttributeData > attributes { InPlaceInit , {
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , vertices . slice ( & Vertex : : position ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Tangent , vertices . slice ( & Vertex : : tangent ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , vertices . slice ( & Vertex : : textureCoordinates1 ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , vertices . slice ( & Vertex : : textureCoordinates2 ) } ,
} } ;
Containers : : Optional < Trade : : MeshData > mesh ;
if ( data . indexDataFlags > = Trade : : DataFlag : : Owned & &
data . vertexDataFlags > = Trade : : DataFlag : : Owned )
mesh = Trade : : MeshData { MeshPrimitive : : Triangles ,
Utility : : move ( indexData ) , Trade : : MeshIndexData { indices } ,
Utility : : move ( vertexData ) , Utility : : move ( attributes ) } ;
else if ( data . indexDataFlags > = Trade : : DataFlag : : Owned )
mesh = Trade : : MeshData { MeshPrimitive : : Triangles ,
Utility : : move ( indexData ) , Trade : : MeshIndexData { indices } ,
data . vertexDataFlags , vertexData , Utility : : move ( attributes ) } ;
else if ( data . vertexDataFlags > = Trade : : DataFlag : : Owned )
mesh = Trade : : MeshData { MeshPrimitive : : Triangles ,
data . indexDataFlags , indexData , Trade : : MeshIndexData { indices } ,
Utility : : move ( vertexData ) , Utility : : move ( attributes ) } ;
else
mesh = Trade : : MeshData { MeshPrimitive : : Triangles ,
data . indexDataFlags , indexData , Trade : : MeshIndexData { indices } ,
data . vertexDataFlags , vertexData , Utility : : move ( attributes ) } ;
Containers : : BitArray attributesToKeep { ValueInit , mesh - > attributeCount ( ) } ;
attributesToKeep . set ( 1 ) ;
attributesToKeep . set ( 3 ) ;
Trade : : MeshData filtered = filterAttributes ( Utility : : move ( * mesh ) , attributesToKeep ) ;
/* The data ownership should be transferred if possible */
CORRADE_VERIFY ( filtered . isIndexed ( ) ) ;
CORRADE_COMPARE ( filtered . indexCount ( ) , 5 ) ;
CORRADE_COMPARE ( filtered . indexData ( ) . data ( ) , indices . data ( ) ) ;
CORRADE_COMPARE ( filtered . indexDataFlags ( ) , data . expectedIndexDataFlags ) ;
CORRADE_COMPARE ( filtered . vertexCount ( ) , 3 ) ;
CORRADE_COMPARE ( filtered . vertexData ( ) . data ( ) , vertices . data ( ) ) ;
CORRADE_COMPARE ( filtered . vertexDataFlags ( ) , data . expectedVertexDataFlags ) ;
/* Just checking that the attributes get actually filtered instead of being
passed through verbatim , the actual verification is done in attributes ( )
above */
CORRADE_COMPARE ( filtered . attributeCount ( ) , 2 ) ;
CORRADE_COMPARE ( filtered . attributeName ( 0 ) , Trade : : MeshAttribute : : Tangent ) ;
}
void FilterTest : : attributesWrongBitCount ( ) {
void FilterTest : : attributesWrongBitCount ( ) {
CORRADE_SKIP_IF_NO_ASSERT ( ) ;
CORRADE_SKIP_IF_NO_ASSERT ( ) ;
@ -332,6 +423,45 @@ void FilterTest::onlyAttributesNoAttributeData() {
CORRADE_COMPARE ( filtered . attributeCount ( ) , 0 ) ;
CORRADE_COMPARE ( filtered . attributeCount ( ) , 0 ) ;
}
}
void FilterTest : : onlyAttributesRvalue ( ) {
/* Subset of onlyAttributes() verifying data ownership transfer behavior.
All cases of ownership transfer are verified in attributesRvalue ( ) , this
only checks that the r - value gets correctly passed through all overloads
to keep the index data owned and vertex data not . */
Containers : : Array < char > indexData { 5 * sizeof ( UnsignedShort ) } ;
Containers : : StridedArrayView1D < UnsignedShort > indices = Containers : : arrayCast < UnsignedShort > ( indexData ) ;
Vertex vertexData [ 3 ] ;
Containers : : StridedArrayView1D < Vertex > vertices = vertexData ;
Trade : : MeshData mesh { MeshPrimitive : : TriangleStrip ,
Utility : : move ( indexData ) , Trade : : MeshIndexData { indices } ,
{ } , vertexData , {
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , vertices . slice ( & Vertex : : position ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Tangent , vertices . slice ( & Vertex : : tangent ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , vertices . slice ( & Vertex : : textureCoordinates1 ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , vertices . slice ( & Vertex : : textureCoordinates2 ) } ,
} } ;
Trade : : MeshData filtered = filterOnlyAttributes ( Utility : : move ( mesh ) , {
Trade : : MeshAttribute : : TextureCoordinates ,
Trade : : MeshAttribute : : Position
} ) ;
CORRADE_COMPARE ( filtered . primitive ( ) , MeshPrimitive : : TriangleStrip ) ;
CORRADE_VERIFY ( filtered . isIndexed ( ) ) ;
CORRADE_COMPARE ( filtered . indexCount ( ) , 5 ) ;
CORRADE_COMPARE ( filtered . indexData ( ) . data ( ) , indices . data ( ) ) ;
CORRADE_COMPARE ( filtered . indexDataFlags ( ) , Trade : : DataFlag : : Owned | Trade : : DataFlag : : Mutable ) ;
CORRADE_COMPARE ( filtered . vertexCount ( ) , 3 ) ;
CORRADE_COMPARE ( filtered . vertexData ( ) . data ( ) , vertices . data ( ) ) ;
CORRADE_COMPARE ( filtered . vertexDataFlags ( ) , Trade : : DataFlags { } ) ;
CORRADE_COMPARE ( filtered . attributeCount ( ) , 3 ) ;
CORRADE_COMPARE ( filtered . attributeName ( 0 ) , Trade : : MeshAttribute : : Position ) ;
}
# ifdef MAGNUM_BUILD_DEPRECATED
# ifdef MAGNUM_BUILD_DEPRECATED
void FilterTest : : onlyAttributeIds ( ) {
void FilterTest : : onlyAttributeIds ( ) {
auto & & data = ImplementationSpecificIndexTypeData [ testCaseInstanceId ( ) ] ;
auto & & data = ImplementationSpecificIndexTypeData [ testCaseInstanceId ( ) ] ;
@ -576,6 +706,46 @@ void FilterTest::exceptAttributesNoAttributeData() {
CORRADE_COMPARE ( filtered . attributeCount ( ) , 0 ) ;
CORRADE_COMPARE ( filtered . attributeCount ( ) , 0 ) ;
}
}
void FilterTest : : exceptAttributesRvalue ( ) {
/* Subset of onlyAttributes() verifying data ownership transfer behavior.
All cases of ownership transfer are verified in attributesRvalue ( ) , this
only checks that the r - value gets correctly passed through all overloads
to keep the vertex data owned and index data not . */
UnsignedShort indices [ 5 ] ;
Containers : : Array < char > vertexData { 3 * sizeof ( Vertex ) } ;
Containers : : StridedArrayView1D < Vertex > vertices = Containers : : arrayCast < Vertex > ( vertexData ) ;
Trade : : MeshData mesh { MeshPrimitive : : TriangleStrip ,
{ } , indices , Trade : : MeshIndexData { indices } ,
Utility : : move ( vertexData ) , {
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , vertices . slice ( & Vertex : : position ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Tangent , vertices . slice ( & Vertex : : tangent ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , vertices . slice ( & Vertex : : textureCoordinates1 ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , vertices . slice ( & Vertex : : textureCoordinates2 ) } ,
/* Positions again, just under a different name. Should be kept. */
Trade : : MeshAttributeData { Trade : : meshAttributeCustom ( 0xbaf ) , vertices . slice ( & Vertex : : position ) } ,
} } ;
Trade : : MeshData filtered = filterExceptAttributes ( Utility : : move ( mesh ) , {
Trade : : MeshAttribute : : Position ,
Trade : : MeshAttribute : : TextureCoordinates
} ) ;
CORRADE_COMPARE ( filtered . primitive ( ) , MeshPrimitive : : TriangleStrip ) ;
CORRADE_VERIFY ( filtered . isIndexed ( ) ) ;
CORRADE_COMPARE ( filtered . indexCount ( ) , 5 ) ;
CORRADE_COMPARE ( filtered . indexData ( ) . data ( ) , static_cast < void * > ( indices ) ) ;
CORRADE_COMPARE ( filtered . indexDataFlags ( ) , Trade : : DataFlags { } ) ;
CORRADE_COMPARE ( filtered . vertexCount ( ) , 3 ) ;
CORRADE_COMPARE ( filtered . vertexData ( ) . data ( ) , vertices . data ( ) ) ;
CORRADE_COMPARE ( filtered . vertexDataFlags ( ) , Trade : : DataFlag : : Owned | Trade : : DataFlag : : Mutable ) ;
CORRADE_COMPARE ( filtered . attributeCount ( ) , 2 ) ;
CORRADE_COMPARE ( filtered . attributeName ( 0 ) , Trade : : MeshAttribute : : Tangent ) ;
}
# ifdef MAGNUM_BUILD_DEPRECATED
# ifdef MAGNUM_BUILD_DEPRECATED
void FilterTest : : exceptAttributeIds ( ) {
void FilterTest : : exceptAttributeIds ( ) {
auto & & data = ImplementationSpecificIndexTypeData [ testCaseInstanceId ( ) ] ;
auto & & data = ImplementationSpecificIndexTypeData [ testCaseInstanceId ( ) ] ;