Files
UnrealEngine/Engine/Source/ThirdParty/Alembic/alembic-1.8.7/prman/Procedural/ArbAttrUtil.h
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

504 lines
17 KiB
C++

//-*****************************************************************************
//
// Copyright (c) 2009-2012,
// Sony Pictures Imageworks Inc. and
// Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Sony Pictures Imageworks, nor
// Industrial Light & Magic, nor the names of their contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//-*****************************************************************************
#ifndef Alembic_Prman_ArbAttrUtil_h
#define Alembic_Prman_ArbAttrUtil_h
#include <ri.h>
#include <Alembic/AbcGeom/All.h>
#include <boost/smart_ptr.hpp>
#include <set>
using namespace Alembic::AbcGeom;
//-*****************************************************************************
class ParamListBuilder
{
public:
~ParamListBuilder();
void add( const std::string & declaration, RtPointer value,
ArraySamplePtr sampleToRetain = ArraySamplePtr() );
// used for conversion of DoubleGeomParams
// NOTE: In addition to performing the conversion, this also makes and
// returns an internal copy of the data. Even in cases in which you're
// starting with float data, this can be usful if you need to manipulate
// the values after-the-fact.
template <typename T>
std::vector<RtFloat> * addAsFloat( const std::string & declaration, const T * length,
size_t numValues );
template <typename T>
std::vector<RtInt> * addAsInt( const std::string & declaration, const T * length,
size_t numValues );
//returns the start of the current vector and pushes a new one
RtPointer finishStringVector();
//If retainLocally is false, it's expected that "value" remain alive
//The common case is out of a StringArraySamplePtr which is provided
//as sampleToRetain in the add method
void addStringValue( const std::string & value,
bool retainLocally = false );
RtInt n();
RtToken* nms();
RtPointer* vals();
private:
std::vector<RtToken> m_outputDeclarations;
std::vector<RtPointer> m_values;
std::vector<ArraySamplePtr> m_retainedSamples;
std::vector<RtString> m_retainedStrings;
typedef boost::shared_ptr<std::vector<RtString> > SharedRtStringVector;
std::vector<SharedRtStringVector> m_convertedStringVectors;
typedef boost::shared_ptr<std::vector<RtFloat> > SharedRtFloatVector;
std::vector<SharedRtFloatVector> m_convertedFloatVectors;
typedef boost::shared_ptr<std::vector<RtInt> > SharedRtIntVector;
std::vector<SharedRtIntVector> m_convertedIntVectors;
};
//-*****************************************************************************
template <typename T>
std::vector<RtFloat> * ParamListBuilder::addAsFloat( const std::string & declaration,
const T * value, size_t length)
{
SharedRtFloatVector convertedValues( new std::vector<RtFloat> );
convertedValues->reserve( length );
convertedValues->insert( convertedValues->end(), value, value + length );
m_convertedFloatVectors.push_back( convertedValues );
add( declaration, &( ( *convertedValues )[0] ) );
return &(*convertedValues);
}
//-*****************************************************************************
template <typename T>
std::vector<RtInt> * ParamListBuilder::addAsInt( const std::string & declaration,
const T * value, size_t length)
{
SharedRtIntVector convertedValues( new std::vector<RtInt> );
convertedValues->reserve( length );
convertedValues->insert( convertedValues->end(), value, value + length );
m_convertedIntVectors.push_back( convertedValues );
add( declaration, &( ( *convertedValues )[0] ) );
return &(*convertedValues);
}
//-*****************************************************************************
std::string GetPrmanScopeString( GeometryScope scope );
//-*****************************************************************************
template <typename T>
void AddGeomParamToParamListBuilder( ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
const std::string &rmanBaseType,
ParamListBuilder &ParamListBuilder,
size_t baseArrayExtent = 1,
const std::string & overrideName = ""
)
{
T param( parent, propHeader.getName() );
if ( !param.valid() )
{
//TODO error message?
return;
}
std::string rmanType = GetPrmanScopeString( param.getScope() ) + " ";
rmanType += rmanBaseType;
size_t arrayExtent = baseArrayExtent * param.getArrayExtent();
if (arrayExtent > 1)
{
std::ostringstream buffer;
buffer << "[" << arrayExtent << "]";
rmanType += buffer.str();
}
rmanType += " " + (
overrideName.empty() ? propHeader.getName() : overrideName );
typename T::prop_type::sample_ptr_type valueSample =
param.getExpandedValue( sampleSelector ).getVals();
ParamListBuilder.add( rmanType, (RtPointer)valueSample->get(),
valueSample );
}
//-*****************************************************************************
// NOTE: In addition to performing the conversion, this also makes and
// returns an internal copy of the data. Even in cases in which you're
// starting with float data, this can be usful if you need to manipulate
// the values after-the-fact. The AddGeomParamToParamListBuilder codepath
// normally avoids a copy of the data as the GeomParam samples can be handed
// to RenderMan directly.
template <typename T, typename podT>
std::vector<RtFloat> * AddGeomParamToParamListBuilderAsFloat( ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
const std::string &rmanBaseType,
ParamListBuilder &ParamListBuilder,
const std::string & overrideName = ""
)
{
T param( parent, propHeader.getName() );
if ( !param.valid() )
{
//TODO error message?
return 0;
}
std::string rmanType = GetPrmanScopeString( param.getScope() ) + " ";
rmanType += rmanBaseType;
size_t dataTypeExtent = T::prop_type::traits_type::dataType().getExtent();
// If rmanBaseType is something other than float, the assumption is that the
// specified rman type is in agreement with the dataTypeExtent -- i.e. color = 3
// If it's just float, we want to make sure that our data footprint matches
// that of the incoming type in RenderMan terms.
size_t baseArrayExtent = (rmanBaseType == "float") ? dataTypeExtent: 1;
size_t arrayExtent = baseArrayExtent * param.getArrayExtent();
if (arrayExtent > 1)
{
std::ostringstream buffer;
buffer << "[" << arrayExtent << "]";
rmanType += buffer.str();
}
rmanType += " " + (
overrideName.empty() ? propHeader.getName() : overrideName );
typename T::prop_type::sample_ptr_type valueSample =
param.getExpandedValue( sampleSelector ).getVals();
//always grab the natural extent of the incoming data for the internal copy
int rawExtent = dataTypeExtent * param.getArrayExtent();
return ParamListBuilder.addAsFloat( rmanType,
reinterpret_cast<const podT *>( valueSample->get() ),
valueSample->size() * rawExtent );
}
//-*****************************************************************************
// NOTE: In addition to performing the conversion, this also makes and
// returns an internal copy of the data. Even in cases in which you're
// starting with int data, this can be usful if you need to manipulate
// the values after-the-fact. The AddGeomParamToParamListBuilder codepath
// normally avoids a copy of the data as the GeomParam samples can be handed
// to RenderMan directly.
template <typename T, typename podT>
std::vector<RtInt> * AddGeomParamToParamListBuilderAsInt( ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
ParamListBuilder &ParamListBuilder,
const std::string & overrideName = ""
)
{
T param( parent, propHeader.getName() );
if ( !param.valid() )
{
//TODO error message?
return 0;
}
//Unlike RtFloat, "int" is the only RenderMan type that takes something
//compatible with RtInt. We can assume anything sent here is intended to be
//written to RenderMan as int[n].
const std::string rmanBaseType("int");
std::string rmanType = GetPrmanScopeString( param.getScope() ) + " ";
rmanType += rmanBaseType;
size_t dataTypeExtent = T::prop_type::traits_type::dataType().getExtent();
size_t arrayExtent = dataTypeExtent * param.getArrayExtent();
if (arrayExtent > 1)
{
std::ostringstream buffer;
buffer << "[" << arrayExtent << "]";
rmanType += buffer.str();
}
rmanType += " " + (
overrideName.empty() ? propHeader.getName() : overrideName );
typename T::prop_type::sample_ptr_type valueSample =
param.getExpandedValue( sampleSelector ).getVals();
return ParamListBuilder.addAsInt( rmanType,
reinterpret_cast<const podT *>( valueSample->get() ),
valueSample->size() * arrayExtent );
}
//-*****************************************************************************
void AddArbitraryGeomParams( ICompoundProperty &parent,
ISampleSelector &sampleSelector,
ParamListBuilder &ParamListBuilder,
const std::set<std::string> * excludeNames = NULL
);
//-*****************************************************************************
//[array, scalar], [as float, as int, as string];
template <typename propT, typename podT>
void AddArrayPropertyAsFloatToParamListBuilder(
ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
const std::string & name,
const std::string & rmanBaseType,
ParamListBuilder & paramListBuilder)
{
propT prop(parent, propHeader.getName());
size_t dataTypeExtent = propT::traits_type::dataType().getExtent();
typename propT::sample_ptr_type sample = prop.getValue(sampleSelector);
std::ostringstream buffer;
buffer << rmanBaseType;
size_t baseArrayExtent = (rmanBaseType == "float") ? dataTypeExtent: 1;
size_t arrayExtent = baseArrayExtent * sample->size();
if (arrayExtent > 1)
{
buffer << "[" << arrayExtent << "]";
}
buffer << " " << name;
paramListBuilder.addAsFloat<podT>(
buffer.str(), reinterpret_cast<const podT *>( sample->get() ),
sample->size() * dataTypeExtent);
}
template <typename propT, typename podT>
void AddScalarPropertyAsFloatToParamListBuilder(
ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
const std::string & name,
const std::string & rmanBaseType,
ParamListBuilder &paramListBuilder)
{
propT prop(parent, propHeader.getName());
typename propT::value_type scalarValue;
prop.get(scalarValue, sampleSelector);
std::ostringstream buffer;
buffer << rmanBaseType;
size_t dataTypeExtent =
propT::traits_type::dataType().getExtent();
if (rmanBaseType == "float" && dataTypeExtent > 1)
{
buffer << "[" << dataTypeExtent << "] ";
}
buffer << " " << name;
paramListBuilder.addAsFloat<podT>(
buffer.str(), reinterpret_cast<const podT *>(&scalarValue),
dataTypeExtent);
}
// template <typename propT, typename podT>
// void AddArrayPropertyAsIntToParamListBuilder(
// ICompoundProperty & parent,
// const PropertyHeader &propHeader,
// ISampleSelector &sampleSelector,
// const std::string & name,
// ParamListBuilder &ParamListBuilder);
template <typename propT, typename podT>
void AddScalarPropertyAsIntToParamListBuilder(
ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
const std::string & name,
ParamListBuilder &paramListBuilder)
{
propT prop(parent, propHeader.getName());
typename propT::value_type scalarValue;
prop.get(scalarValue, sampleSelector);
std::ostringstream buffer;
buffer << "int";
size_t dataTypeExtent =
propT::traits_type::dataType().getExtent();
if (dataTypeExtent > 1)
{
buffer << "[" << dataTypeExtent << "]";
}
buffer << " " << name;
paramListBuilder.addAsInt<podT>(
buffer.str(), reinterpret_cast<const podT *>(&scalarValue),
dataTypeExtent);
}
template <typename propT>
void AddArrayPropertyAsStringToParamListBuilder(
ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
const std::string & name,
ParamListBuilder &paramListBuilder)
{
propT prop(parent, propHeader.getName());
StringArraySamplePtr valueSample = prop.getValue(sampleSelector);
std::ostringstream buffer;
buffer << "string";
if (valueSample->size() > 1)
{
buffer << "[" << valueSample->size() << "]";
}
buffer << " " << name;
for ( size_t i = 0; i < valueSample->size(); ++i )
{
paramListBuilder.addStringValue( (*valueSample)[i] );
}
RtPointer dataStart = paramListBuilder.finishStringVector();
paramListBuilder.add(buffer.str(), dataStart, valueSample);
}
template <typename propT>
void AddScalarPropertyAsStringToParamListBuilder(
ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
const std::string & name,
ParamListBuilder &paramListBuilder)
{
propT prop(parent, propHeader.getName());
typename propT::value_type scalarValue;
prop.get(scalarValue, sampleSelector);
std::ostringstream buffer;
buffer << "string";
size_t dataTypeExtent =
propT::traits_type::dataType().getExtent();
if (dataTypeExtent > 1)
{
buffer << "[" << dataTypeExtent << "]";
}
buffer << " " << name;
for (size_t i = 0; i < dataTypeExtent; ++i)
{
paramListBuilder.addStringValue(
reinterpret_cast<std::string*>(&scalarValue)[i], true);
}
paramListBuilder.add(buffer.str(),
paramListBuilder.finishStringVector());
}
#endif