Skip to content

Commit af7fe11

Browse files
authored
Merge pull request #1449 from ericmehl/serialiseInfinity
`repr` Infinity
2 parents 55eed97 + 3b46e20 commit af7fe11

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

Changes

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
10.5.x.x (relative to 10.5.11.0)
22
========
33

4+
Fixes
5+
-----
6+
7+
- IECore : Fixed bug that was causing imath vectors and colors with values of `inf` / `std::numeric_limits<float>::infinity()` to be serialised in a way that could not be evaluated with `eval()`.
48

59

610
10.5.11.0 (relative to 10.5.10.0)

src/IECorePython/IECoreBinding.cpp

+32-2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ IECORE_POP_DEFAULT_VISIBILITY
5858
using namespace std;
5959
using namespace Imath;
6060

61+
namespace
62+
{
63+
64+
static std::string g_positiveInfString = "float( 'inf' )";
65+
static std::string g_negativeInfString = "-float( 'inf' )";
66+
67+
}
68+
6169
namespace IECorePython
6270
{
6371

@@ -70,7 +78,18 @@ std::string repr<VEC>( VEC &x )\
7078
s << "imath." << #VEC << "( ";\
7179
for( unsigned i=0; i<VEC::dimensions(); i++ )\
7280
{\
73-
s << boost::lexical_cast<string>( x[i] );\
81+
if constexpr( std::numeric_limits<VEC::BaseType>::has_infinity )\
82+
{\
83+
s << (\
84+
x[i] == std::numeric_limits<VEC::BaseType>::infinity() ? g_positiveInfString :\
85+
( x[i] == -std::numeric_limits<VEC::BaseType>::infinity() ? g_negativeInfString :\
86+
boost::lexical_cast<std::string>( x[i] ) ) \
87+
);\
88+
}\
89+
else\
90+
{\
91+
s << boost::lexical_cast<string>( x[i] );\
92+
}\
7493
if( i!=VEC::dimensions()-1 )\
7594
{\
7695
s << ", ";\
@@ -142,7 +161,18 @@ std::string repr<COL>( COL &x )\
142161
s << "imath." << #COL << "( ";\
143162
for( unsigned i=0; i<COL::dimensions(); i++ )\
144163
{\
145-
s << boost::lexical_cast<std::string>( x[i] );\
164+
if constexpr( std::numeric_limits<COL::BaseType>::has_infinity )\
165+
{\
166+
s << (\
167+
x[i] == std::numeric_limits<COL::BaseType>::infinity() ? g_positiveInfString :\
168+
( x[i] == -std::numeric_limits<COL::BaseType>::infinity() ? g_negativeInfString :\
169+
boost::lexical_cast<std::string>( x[i] ) ) \
170+
);\
171+
}\
172+
else\
173+
{\
174+
s << boost::lexical_cast<string>( x[i] );\
175+
}\
146176
if( i!=COL::dimensions()-1 )\
147177
{\
148178
s << ", ";\

test/IECore/ReprTest.py

+22
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,28 @@ def test( self ) :
6060
] :
6161
self.assertTrue( type( v ) is type( eval( IECore.repr( v ) ) ) )
6262
self.assertEqual( v, eval( IECore.repr( v ) ) )
63+
64+
def testInfinity( self ) :
65+
66+
for v in [
67+
# Python raises "OverflowError : bad numeric conversion : positive overflow"
68+
# when passing `float( "inf" )` to `V2f``
69+
imath.V2d( float( "inf" ), float( "inf" ) ),
70+
imath.V3f( float( "inf" ), float( "inf" ), float( "inf" ) ),
71+
imath.V3d( float( "inf" ), float( "inf" ), float( "inf" ) ),
72+
imath.Color3f( float( "inf" ), float( "inf" ), float( "inf" ) ),
73+
imath.Color4f( float( "inf" ), float( "inf" ), float( "inf" ), float( "inf" ) ),
74+
] :
75+
with self.subTest( v = v ) :
76+
self.assertTrue( type( v ) is type( eval( IECore.repr( v ) ) ) )
77+
self.assertEqual( v, eval( IECore.repr( v ) ) )
78+
79+
self.assertTrue( type( -v ) is type( eval( IECore.repr( -v ) ) ) )
80+
self.assertEqual( -v, eval( IECore.repr( -v ) ) )
81+
82+
self.assertEqual( str( v ), "{}({})".format( type( v ).__name__, ", ".join( ["inf"] * v.dimensions() ) ) )
83+
self.assertEqual( str( -v ), "{}({})".format( type( v ).__name__, ", ".join( ["-inf"] * v.dimensions() ) ) )
84+
6385

6486
if __name__ == "__main__":
6587
unittest.main()

0 commit comments

Comments
 (0)