|
34 | 34 |
|
35 | 35 | #include "GeometryAlgo.h" |
36 | 36 |
|
| 37 | +#include "Loader.h" |
37 | 38 | #include "ParamListAlgo.h" |
38 | 39 |
|
39 | 40 | #include "IECore/DataAlgo.h" |
@@ -273,7 +274,7 @@ struct PrimitiveVariableConverter |
273 | 274 | IECore::msg( |
274 | 275 | IECore::Msg::Warning, |
275 | 276 | m_messageContext, |
276 | | - fmt::format( "Unsupported primitive variable of type \"{}\"", data->typeName() ) |
| 277 | + fmt::format( "Unsupported primitive variable \"{}\" of type \"{}\"", name.CStr(), data->typeName() ) |
277 | 278 | ); |
278 | 279 | } |
279 | 280 |
|
@@ -311,6 +312,83 @@ struct PrimitiveVariableConverter |
311 | 312 |
|
312 | 313 | }; |
313 | 314 |
|
| 315 | +void convertDetail( const IECoreScene::Primitive *primitive, RtPrimVarList &primVarList ) |
| 316 | +{ |
| 317 | + primVarList.SetDetail( |
| 318 | + primitive->variableSize( PrimitiveVariable::Uniform ), |
| 319 | + primitive->variableSize( PrimitiveVariable::Vertex ), |
| 320 | + primitive->variableSize( PrimitiveVariable::Varying ), |
| 321 | + primitive->variableSize( PrimitiveVariable::FaceVarying ) |
| 322 | + ); |
| 323 | +} |
| 324 | + |
| 325 | +const std::string g_p( "P" ); |
| 326 | + |
| 327 | +void convertP( const IECoreScene::Primitive *primitive, RtPrimVarList &primVarList, const std::string &messageContext ) |
| 328 | +{ |
| 329 | + auto it = primitive->variables.find( g_p ); |
| 330 | + if( it != primitive->variables.end() ) |
| 331 | + { |
| 332 | + const PrimitiveVariableConverter converter( messageContext ); |
| 333 | + dispatch( it->second.data.get(), converter, Loader::strings().k_P, it->second, primVarList ); |
| 334 | + } |
| 335 | +} |
| 336 | + |
| 337 | +void convertP( const std::vector<const IECoreScene::Primitive *> &samples, const std::vector<float> &sampleTimes, RtPrimVarList &primVarList, const std::string &messageContext ) |
| 338 | +{ |
| 339 | + const auto firstSampleIt = samples[0]->variables.find( g_p ); |
| 340 | + if( firstSampleIt == samples[0]->variables.end() ) |
| 341 | + { |
| 342 | + return; |
| 343 | + } |
| 344 | + |
| 345 | + bool animated = false; |
| 346 | + for( size_t i = 1; i < samples.size(); ++i ) |
| 347 | + { |
| 348 | + auto it = samples[i]->variables.find( g_p ); |
| 349 | + if( it == samples[i]->variables.end() ) |
| 350 | + { |
| 351 | + animated = false; |
| 352 | + break; |
| 353 | + } |
| 354 | + else if( it->second != firstSampleIt->second ) |
| 355 | + { |
| 356 | + animated = true; |
| 357 | + } |
| 358 | + } |
| 359 | + |
| 360 | + const PrimitiveVariableConverter converter( messageContext ); |
| 361 | + if( animated ) |
| 362 | + { |
| 363 | + primVarList.SetTimes( sampleTimes.size(), sampleTimes.data() ); |
| 364 | + for( size_t i = 0; i < samples.size(); ++i ) |
| 365 | + { |
| 366 | + auto it = samples[i]->variables.find( g_p ); |
| 367 | + assert( it != samples[i]->variables.end() ); |
| 368 | + dispatch( it->second.data.get(), converter, Loader::strings().k_P, it->second, primVarList, i ); |
| 369 | + } |
| 370 | + } |
| 371 | + else |
| 372 | + { |
| 373 | + dispatch( firstSampleIt->second.data.get(), converter, Loader::strings().k_P, firstSampleIt->second, primVarList ); |
| 374 | + } |
| 375 | +} |
| 376 | + |
| 377 | +void convertPrimitiveVariables( const IECoreScene::Primitive *primitive, RtPrimVarList &primVarList, const std::string &messageContext ) |
| 378 | +{ |
| 379 | + const PrimitiveVariableConverter converter( messageContext ); |
| 380 | + for( const auto &[name, primitiveVariable] : primitive->variables ) |
| 381 | + { |
| 382 | + if( name == g_p ) |
| 383 | + { |
| 384 | + // Dealt with in `convertP()` |
| 385 | + continue; |
| 386 | + } |
| 387 | + const RtUString convertedName( name == "uv" ? "st" : name.c_str() ); |
| 388 | + dispatch( primitiveVariable.data.get(), converter, convertedName, primitiveVariable, primVarList ); |
| 389 | + } |
| 390 | +} |
| 391 | + |
314 | 392 | } // namespace |
315 | 393 |
|
316 | 394 | ////////////////////////////////////////////////////////////////////////// |
@@ -351,57 +429,21 @@ void IECoreRenderMan::GeometryAlgo::registerConverter( IECore::TypeId fromType, |
351 | 429 | registry()[fromType] = { converter, motionConverter }; |
352 | 430 | } |
353 | 431 |
|
354 | | -void IECoreRenderMan::GeometryAlgo::convertPrimitiveVariables( const IECoreScene::Primitive *primitive, RtPrimVarList &primVarList, const std::string &messageContext ) |
| 432 | +void IECoreRenderMan::GeometryAlgo::convertPrimitive( const IECoreScene::Primitive *primitive, RtPrimVarList &primVarList, const std::string &messageContext ) |
355 | 433 | { |
356 | | - const PrimitiveVariableConverter converter( messageContext ); |
357 | | - for( const auto &[name, primitiveVariable] : primitive->variables ) |
358 | | - { |
359 | | - const RtUString convertedName( name == "uv" ? "st" : name.c_str() ); |
360 | | - dispatch( primitiveVariable.data.get(), converter, convertedName, primitiveVariable, primVarList ); |
361 | | - } |
| 434 | + convertDetail( primitive, primVarList ); |
| 435 | + convertP( primitive, primVarList, messageContext ); |
| 436 | + convertPrimitiveVariables( primitive, primVarList, messageContext ); |
362 | 437 | } |
363 | 438 |
|
364 | | -void IECoreRenderMan::GeometryAlgo::convertPrimitiveVariables( const std::vector<const IECoreScene::Primitive *> &samples, const std::vector<float> &sampleTimes, RtPrimVarList &primVarList, const std::string &messageContext ) |
| 439 | +void IECoreRenderMan::GeometryAlgo::convertPrimitive( const std::vector<const IECoreScene::Primitive *> &samples, const std::vector<float> &sampleTimes, RtPrimVarList &primVarList, const std::string &messageContext = "GeometryAlgo::convertPrimitive" ) |
365 | 440 | { |
366 | | - const PrimitiveVariableConverter converter( messageContext ); |
367 | | - |
368 | | - bool haveSetTimes = false; |
369 | | - for( const auto &[name, primitiveVariable] : samples[0]->variables ) |
370 | | - { |
371 | | - bool animated = false; |
372 | | - for( size_t i = 1; i < samples.size(); ++i ) |
373 | | - { |
374 | | - auto it = samples[i]->variables.find( name ); |
375 | | - if( it == samples[i]->variables.end() ) |
376 | | - { |
377 | | - animated = false; |
378 | | - break; |
379 | | - } |
380 | | - else if( it->second != primitiveVariable ) |
381 | | - { |
382 | | - animated = true; |
383 | | - } |
384 | | - } |
385 | | - |
386 | | - const RtUString convertedName( name == "uv" ? "st" : name.c_str() ); |
387 | | - if( animated ) |
388 | | - { |
389 | | - if( !haveSetTimes ) |
390 | | - { |
391 | | - primVarList.SetTimes( sampleTimes.size(), sampleTimes.data() ); |
392 | | - haveSetTimes = true; |
393 | | - } |
394 | | - |
395 | | - for( size_t i = 0; i < samples.size(); ++i ) |
396 | | - { |
397 | | - auto it = samples[i]->variables.find( name ); |
398 | | - assert( it != samples[i]->variables.end() ); |
399 | | - dispatch( it->second.data.get(), converter, convertedName, primitiveVariable, primVarList, i ); |
400 | | - } |
401 | | - } |
402 | | - else |
403 | | - { |
404 | | - dispatch( primitiveVariable.data.get(), converter, convertedName, primitiveVariable, primVarList ); |
405 | | - } |
406 | | - } |
| 441 | + convertDetail( samples[0], primVarList ); |
| 442 | + // "P" is the only primitive variable that RenderMan allows to be animated |
| 443 | + // so we deal with it separately. When it is animated, `convertP()` will |
| 444 | + // call `primVarList.SetTimes()` appropriately. It seems we need to call |
| 445 | + // this before adding any primitive variables, animated or not, or we get |
| 446 | + // crashes in RenderMan. |
| 447 | + convertP( samples, sampleTimes, primVarList, messageContext ); |
| 448 | + convertPrimitiveVariables( samples[0], primVarList, messageContext ); |
407 | 449 | } |
0 commit comments