Skip to content

Commit 42beb16

Browse files
Merge pull request #1042 from Geode-solutions/fix/array_attribute_interpolation
fix(AttributeInterpolation): Added the interpolation of attributes of…
2 parents a49a686 + 8f3d29d commit 42beb16

File tree

4 files changed

+168
-25
lines changed

4 files changed

+168
-25
lines changed

include/geode/basic/attribute_utils.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,34 @@ namespace geode
140140
IMPLICIT_ATTRIBUTE_LINEAR_INTERPOLATION( float );
141141
IMPLICIT_ATTRIBUTE_LINEAR_INTERPOLATION( double );
142142

143+
#define IMPLICIT_ARRAY_ATTRIBUTE_LINEAR_INTERPOLATION( Type ) \
144+
template < size_t array_size > \
145+
struct AttributeLinearInterpolationImpl< std::array< Type, array_size > > \
146+
{ \
147+
template < template < typename > class Attribute > \
148+
[[nodiscard]] static std::array< Type, array_size > compute( \
149+
const AttributeLinearInterpolation& interpolator, \
150+
const Attribute< std::array< Type, array_size > >& attribute ) \
151+
{ \
152+
std::array< Type, array_size > result; \
153+
result.fill( 0 ); \
154+
for( const auto vertex_id : Indices{ interpolator.indices_ } ) \
155+
{ \
156+
const auto& array_value = \
157+
attribute.value( interpolator.indices_[vertex_id] ); \
158+
for( const auto position : Indices{ array_value } ) \
159+
{ \
160+
result[position] += interpolator.lambdas_[vertex_id] \
161+
* array_value[position]; \
162+
} \
163+
} \
164+
return result; \
165+
} \
166+
}
167+
168+
IMPLICIT_ARRAY_ATTRIBUTE_LINEAR_INTERPOLATION( float );
169+
IMPLICIT_ARRAY_ATTRIBUTE_LINEAR_INTERPOLATION( double );
170+
143171
/*!
144172
* Helper struct to convert an Attribute value to generic float.
145173
* This struct may be customized for a given type.

include/geode/geometry/point.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ namespace geode
214214
struct AttributeLinearInterpolationImpl< Point< dimension > >
215215
{
216216
template < template < typename > class Attribute >
217-
static Point< dimension > compute(
217+
[[nodiscard]] static Point< dimension > compute(
218218
const AttributeLinearInterpolation &interpolator,
219219
const Attribute< Point< dimension > > &attribute )
220220
{

tests/basic/test-attribute.cpp

Lines changed: 102 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,14 @@ void test_int_variable_attribute( geode::AttributeManager& manager )
168168
variable_attribute->set_value( 3, 3 );
169169

170170
const auto attribute = manager.find_attribute< int >( "int" );
171-
OPENGEODE_EXCEPTION(
172-
attribute->value( 3 ) == 3, "[Test] Should be equal to 3" );
173-
OPENGEODE_EXCEPTION(
174-
attribute->value( 6 ) == 12, "[Test] Should be equal to 12" );
171+
OPENGEODE_EXCEPTION( attribute->value( 3 ) == 3,
172+
"[Test] Int variable value 3 should be equal to 3" );
173+
OPENGEODE_EXCEPTION( attribute->value( 6 ) == 12,
174+
"[Test] Int variable value 6 should be equal to 12" );
175175

176176
variable_attribute->set_value( 3, 5 );
177-
OPENGEODE_EXCEPTION(
178-
attribute->value( 3 ) == 5, "[Test] Should be equal to 5" );
177+
OPENGEODE_EXCEPTION( attribute->value( 3 ) == 5,
178+
"[Test] Int variable value 3 should be equal to 5" );
179179
}
180180

181181
void test_foo_sparse_attribute( geode::AttributeManager& manager )
@@ -193,8 +193,8 @@ void test_foo_sparse_attribute( geode::AttributeManager& manager )
193193
"[Test] Should be equal to 0" );
194194
OPENGEODE_EXCEPTION( sparse_attribute->value( 3 ).double_ == 12.4,
195195
"[Test] Should be equal to 12.4" );
196-
OPENGEODE_EXCEPTION(
197-
sparse_attribute->value( 3 ).int_ == 3, "[Test] Should be equal to 3" );
196+
OPENGEODE_EXCEPTION( sparse_attribute->value( 3 ).int_ == 3,
197+
"[Test] Foo sparse value should be equal to 3" );
198198
}
199199

200200
void test_double_sparse_attribute( geode::AttributeManager& manager )
@@ -210,10 +210,10 @@ void test_double_sparse_attribute( geode::AttributeManager& manager )
210210
manager.interpolate_attribute_value( { { 1, 7 }, { 0.5, 0.3 } }, 4 );
211211

212212
auto attribute = manager.find_attribute< double >( "double" );
213-
OPENGEODE_EXCEPTION(
214-
attribute->value( 2 ) == 3, "[Test] Should be equal to 3" );
215-
OPENGEODE_EXCEPTION(
216-
attribute->value( 3 ) == 3, "[Test] Should be equal to 3" );
213+
OPENGEODE_EXCEPTION( attribute->value( 2 ) == 3,
214+
"[Test] Double sparse value 2 should be equal to 3" );
215+
OPENGEODE_EXCEPTION( attribute->value( 3 ) == 3,
216+
"[Test] Double sparse value 3 should be equal to 3" );
217217
OPENGEODE_EXCEPTION(
218218
attribute->value( 4 ) == 8.1, "[Test] Should be equal to 8.1" );
219219
OPENGEODE_EXCEPTION(
@@ -226,6 +226,80 @@ void test_double_sparse_attribute( geode::AttributeManager& manager )
226226
attribute->value( 3 ) == 5, "[Test] Should be equal to 5" );
227227
}
228228

229+
void test_double_array_attribute( geode::AttributeManager& manager )
230+
{
231+
auto array_attribute =
232+
manager.find_or_create_attribute< geode::VariableAttribute,
233+
std::array< double, 3 > >(
234+
"array_double_3", { { 10., 11., 12. } }, { true, true } );
235+
OPENGEODE_EXCEPTION( array_attribute->default_value()[0] == 10.,
236+
"[Test] Wrong default value" );
237+
OPENGEODE_EXCEPTION( array_attribute->default_value()[1] == 11.,
238+
"[Test] Wrong default value" );
239+
OPENGEODE_EXCEPTION( array_attribute->default_value()[2] == 12.,
240+
"[Test] Wrong default value" );
241+
array_attribute->set_value( 3, { { 1., 2., 3. } } );
242+
array_attribute->set_value( 7, { { 2., 5., 7. } } );
243+
manager.assign_attribute_value( 3, 2 );
244+
manager.interpolate_attribute_value( { { 1, 7 }, { 0.5, 0.3 } }, 4 );
245+
246+
auto attribute =
247+
manager.find_attribute< std::array< double, 3 > >( "array_double_3" );
248+
OPENGEODE_EXCEPTION( attribute->value( 2 )[0] == 1.,
249+
"[Test] Value [2,0] Should be equal to 1., not ",
250+
attribute->value( 2 )[0] );
251+
OPENGEODE_EXCEPTION( attribute->value( 2 )[1] == 2.,
252+
"[Test] Value [2,1] Should be equal to 2., not ",
253+
attribute->value( 2 )[1] );
254+
OPENGEODE_EXCEPTION( attribute->value( 2 )[2] == 3.,
255+
"[Test] Value [2,2] Should be equal to 3., not ",
256+
attribute->value( 2 )[2] );
257+
OPENGEODE_EXCEPTION( attribute->value( 3 )[0] == 1.,
258+
"[Test] Value [3,0] Should be equal to 1., not ",
259+
attribute->value( 3 )[0] );
260+
OPENGEODE_EXCEPTION( attribute->value( 3 )[1] == 2.,
261+
"[Test] Value [3,1] Should be equal to 2., not ",
262+
attribute->value( 3 )[1] );
263+
OPENGEODE_EXCEPTION( attribute->value( 3 )[2] == 3.,
264+
"[Test] Value [3,2] Should be equal to 3., not ",
265+
attribute->value( 3 )[2] );
266+
OPENGEODE_EXCEPTION( attribute->value( 4 )[0] == 5.6,
267+
"[Test] Value [4,0] Should be equal to 5.6, not ",
268+
attribute->value( 4 )[0] );
269+
OPENGEODE_EXCEPTION( attribute->value( 4 )[1] == 7.,
270+
"[Test] Value [4,1] Should be equal to 7., not ",
271+
attribute->value( 4 )[1] );
272+
OPENGEODE_EXCEPTION( attribute->value( 4 )[2] == 8.1,
273+
"[Test] Value [4,2] Should be equal to 8.1, not ",
274+
attribute->value( 4 )[2] );
275+
OPENGEODE_EXCEPTION( attribute->value( 6 )[0] == 10.,
276+
"[Test] Value [6,0] Should be equal to 10., not ",
277+
attribute->value( 6 )[0] );
278+
OPENGEODE_EXCEPTION( attribute->value( 6 )[1] == 11.,
279+
"[Test] Value [6,1] Should be equal to 11., not ",
280+
attribute->value( 6 )[1] );
281+
OPENGEODE_EXCEPTION( attribute->value( 6 )[2] == 12.,
282+
"[Test] Value [6,2] Should be equal to 12., not ",
283+
attribute->value( 6 )[2] );
284+
OPENGEODE_EXCEPTION( attribute->value( 7 )[0] == 2.,
285+
"[Test] Value [7,0] Should be equal to 2., not ",
286+
attribute->value( 7 )[0] );
287+
OPENGEODE_EXCEPTION( attribute->value( 7 )[1] == 5.,
288+
"[Test] Value [7,1] Should be equal to 5., not ",
289+
attribute->value( 7 )[1] );
290+
OPENGEODE_EXCEPTION( attribute->value( 7 )[2] == 7.,
291+
"[Test] Value [7,2] Should be equal to 7., not ",
292+
attribute->value( 7 )[2] );
293+
294+
array_attribute->set_value( 3, { 2., 5., 5. } );
295+
OPENGEODE_EXCEPTION(
296+
attribute->value( 3 )[0] == 2., "[Test] Should be equal to 2." );
297+
OPENGEODE_EXCEPTION(
298+
attribute->value( 3 )[1] == 5., "[Test] Should be equal to 5." );
299+
OPENGEODE_EXCEPTION(
300+
attribute->value( 3 )[2] == 5., "[Test] Should be equal to 5." );
301+
}
302+
229303
void test_bool_variable_attribute( geode::AttributeManager& manager )
230304
{
231305
auto variable_attribute =
@@ -479,20 +553,23 @@ void test_permutation( geode::AttributeManager& manager )
479553
manager.permute_elements( permutation );
480554

481555
const auto int_attribute = manager.find_attribute< int >( "int" );
482-
OPENGEODE_EXCEPTION(
483-
int_attribute->value( 3 ) == 12, "[Test] Should be equal to 12" );
484-
OPENGEODE_EXCEPTION(
485-
int_attribute->value( 0 ) == 5, "[Test] Should be equal to 5" );
486-
OPENGEODE_EXCEPTION(
487-
int_attribute->value( 8 ) == 5, "[Test] Should be equal to 5" );
556+
OPENGEODE_EXCEPTION( int_attribute->value( 3 ) == 12,
557+
"[Test] Attribute value 3 should be equal to 12" );
558+
OPENGEODE_EXCEPTION( int_attribute->value( 0 ) == 5,
559+
"[Test] Attribute value 0 should be equal to 5" );
560+
OPENGEODE_EXCEPTION( int_attribute->value( 8 ) == 5,
561+
"[Test] Attribute value 8 should be equal to 5" );
488562

489563
auto double_attribute = manager.find_attribute< double >( "double" );
490-
OPENGEODE_EXCEPTION(
491-
double_attribute->value( 2 ) == 12, "[Test] Should be equal to 3" );
492-
OPENGEODE_EXCEPTION(
493-
double_attribute->value( 4 ) == 3, "[Test] Should be equal to 3" );
494-
OPENGEODE_EXCEPTION(
495-
double_attribute->value( 7 ) == 8.1, "[Test] Should be equal to 8.1" );
564+
OPENGEODE_EXCEPTION( double_attribute->value( 2 ) == 12,
565+
"[Test] Attribute value 2 should be equal to 3, not ",
566+
double_attribute->value( 2 ) );
567+
OPENGEODE_EXCEPTION( double_attribute->value( 4 ) == 3,
568+
"[Test] Attribute value 4 should be equal to 3, not ",
569+
double_attribute->value( 4 ) );
570+
OPENGEODE_EXCEPTION( double_attribute->value( 7 ) == 8.1,
571+
"[Test] Attribute value 7 should be equal to 8.1, not ",
572+
double_attribute->value( 7 ) );
496573
}
497574

498575
void test()
@@ -527,6 +604,7 @@ void test()
527604
manager.resize( 10 );
528605
OPENGEODE_EXCEPTION(
529606
manager.nb_elements() == 10, "[Test] Manager should have 10 elements" );
607+
test_double_array_attribute( manager );
530608
manager.clear();
531609
test_number_of_attributes( manager, 0 );
532610
}

tests/geometry/test-point.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*
2222
*/
2323

24+
#include <geode/basic/attribute_manager.hpp>
2425
#include <geode/basic/logger.hpp>
2526

2627
#include <geode/geometry/point.hpp>
@@ -54,10 +55,46 @@ void test_operators()
5455
OPENGEODE_EXCEPTION( answer / 2 == p, "[Test] Points should be equal" );
5556
}
5657

58+
void test_interpolation()
59+
{
60+
geode::AttributeManager manager;
61+
manager.resize( 10 );
62+
auto attribute = manager.find_or_create_attribute< geode::VariableAttribute,
63+
geode::Point< 3 > >(
64+
"point_3", geode::Point3D{ { 10., 11., 12. } }, { false, true } );
65+
OPENGEODE_EXCEPTION( attribute->default_value().value( 0 ) == 10.,
66+
"[Test] Wrong default value" );
67+
OPENGEODE_EXCEPTION( attribute->default_value().value( 1 ) == 11.,
68+
"[Test] Wrong default value" );
69+
OPENGEODE_EXCEPTION( attribute->default_value().value( 2 ) == 12.,
70+
"[Test] Wrong default value" );
71+
attribute->set_value( 3, geode::Point3D{ { 1., 2., 3. } } );
72+
attribute->set_value( 7, geode::Point3D{ { 2., 5., 7. } } );
73+
manager.interpolate_attribute_value( { { 1, 7 }, { 0.5, 0.3 } }, 4 );
74+
75+
OPENGEODE_EXCEPTION(
76+
attribute->value( 3 ).inexact_equal( geode::Point3D{ { 1., 2., 3. } } ),
77+
"[Test] Value 3 Should be equal to [ 1., 2., 3. ], not ",
78+
attribute->value( 3 ).string() );
79+
OPENGEODE_EXCEPTION( attribute->value( 4 ).inexact_equal(
80+
geode::Point3D{ { 5.6, 7., 8.1 } } ),
81+
"[Test] Value 4 Should be equal to [ 5.6, 7., 8.1 ], not ",
82+
attribute->value( 4 ).string() );
83+
OPENGEODE_EXCEPTION(
84+
attribute->value( 6 ).inexact_equal( geode::Point3D{ { 10, 11, 12 } } ),
85+
"[Test] Value 6 Should be equal to [ 10, 11, 12 ], not ",
86+
attribute->value( 6 ).string() );
87+
OPENGEODE_EXCEPTION(
88+
attribute->value( 7 ).inexact_equal( geode::Point3D{ { 2., 5., 7. } } ),
89+
"[Test] Value 7 Should be equal to [ 2., 5., 7. ], not ",
90+
attribute->value( 7 ).string() );
91+
}
92+
5793
void test()
5894
{
5995
test_comparison();
6096
test_operators();
97+
test_interpolation();
6198
}
6299

63100
OPENGEODE_TEST( "point" )

0 commit comments

Comments
 (0)