void AbcNodeUtils::printCompoundProperty( Abc::ICompoundProperty prop )
{
   if(!prop){
      return;
   }

   for(size_t i=0; i<prop.getNumProperties(); i++){
      AbcA::PropertyHeader pheader = prop.getPropertyHeader(i);
      AbcA::PropertyType propType = pheader.getPropertyType();

      ESS_LOG_WARNING("PropertyType: "<<AbcNodeUtils::getTypeStr(propType));
      ESS_LOG_WARNING("PropertyName: "<<pheader.getName()<<", pod: "<<AbcNodeUtils::getPodStr(pheader.getDataType().getPod()) \
       <<", extent: "<<(int)pheader.getDataType().getExtent()<<", interpretation: "<<pheader.getMetaData().get("interpretation"));


   }
}
EAbcResult CreatePropFromHeader( const Alembic::Abc::ICompoundProperty& in_Parent, const AbcA::PropertyHeader &l_header, IAbcIPropertyAccessor** out_ppProp )
{
	*out_ppProp = NULL;
	if ( l_header.isArray() )
	{
		IArrayProperty l_arrProp( in_Parent, l_header.getName() );
		*out_ppProp = new CAbcIArrayPropertyAccessor( l_arrProp.getPtr() );
	}
	else if ( l_header.isScalar() )
	{
		IScalarProperty l_scProp( in_Parent, l_header.getName() );
		*out_ppProp = new CAbcIScalarPropertyAccessor( l_scProp.getPtr() );
	}
	else if ( l_header.isCompound() )
	{
		ICompoundProperty l_cmpProp( in_Parent, l_header.getName() );
		*out_ppProp = new CAbcICompoundPropertyAccessor( l_cmpProp.getPtr() );
	}

	if (*out_ppProp)
	{
		(*out_ppProp)->AddRef();
		return EResult_Success;
	}
	else
		return EResult_OutOfMemory;
}
template<class PT, class FT> bool readPropExt3(const Abc::ICompoundProperty& prop, const AbcA::PropertyHeader& pheader, std::string& val, bool& isConstant)
{
   if(PT::matches(pheader))
   {
      PT aProp(prop, pheader.getName());
      if(!aProp.valid()){
         return false;
      }

      FT val3;
      aProp.get(val3);//TODO: crashes here if property has no samples

      std::stringstream valStream;
      valStream<<val3.x<<","<<val3.y<<","<<val3.z;
      val = valStream.str();

      return true;
   }
   return false;
}
示例#4
0
//-*****************************************************************************
void WritePropertyInfo( hid_t iGroup,
                    const AbcA::PropertyHeader &iHeader,
                    bool isScalarLike,
                    uint32_t iTimeSamplingIndex,
                    uint32_t iNumSamples,
                    uint32_t iFirstChangedIndex,
                    uint32_t iLastChangedIndex )
{

    uint32_t info[5] = {0, 0, 0, 0, 0};
    uint32_t numFields = 1;

    // 0000 0000 0000 0000 0000 0000 0000 0011
    static const uint32_t ptypeMask = 0x0003;

    // 0000 0000 0000 0000 0000 0000 0011 1100
    static const uint32_t podMask = 0x003c;

    // 0000 0000 0000 0000 0000 0000 0100 0000
    static const uint32_t hasTsidxMask = 0x0040;

    // 0000 0000 0000 0000 0000 0000 1000 0000
    static const uint32_t noRepeatsMask = 0x0080;

    // 0000 0000 0000 0000 1111 1111 0000 0000
    static const uint32_t extentMask = 0xff00;

    // compounds are treated differently
    if ( iHeader.getPropertyType() != AbcA::kCompoundProperty )
    {
        // Slam the property type in there.
        info[0] |= ptypeMask & ( uint32_t )iHeader.getPropertyType();

        // arrays may be scalar like, scalars are already scalar like
        info[0] |= ( uint32_t ) isScalarLike;

        uint32_t pod = ( uint32_t )iHeader.getDataType().getPod();
        info[0] |= podMask & ( pod << 2 );

        if (iTimeSamplingIndex != 0)
        {
            info[0] |= hasTsidxMask;
        }

        if (iFirstChangedIndex == 1 && iLastChangedIndex == iNumSamples - 1)
        {
            info[0] |= noRepeatsMask;
        }

        uint32_t extent = ( uint32_t )iHeader.getDataType().getExtent();
        info[0] |= extentMask & ( extent << 8 );

        ABCA_ASSERT( iFirstChangedIndex <= iNumSamples &&
            iLastChangedIndex <= iNumSamples &&
            iFirstChangedIndex <= iLastChangedIndex,
            "Illegal Sampling!" << std::endl <<
            "Num Samples: " << iNumSamples << std::endl <<
            "First Changed Index: " << iFirstChangedIndex << std::endl <<
            "Last Changed Index: " << iLastChangedIndex << std::endl );

        // Write the num samples. Only bother writing if
        // the num samples is greater than 1.  Existence of name.smp0
        // is used by the reader to determine if 0 or 1 sample.
        if ( iNumSamples > 1 )
        {
            info[1] = iNumSamples;
            numFields ++;
            if ( iFirstChangedIndex > 1 || ( iLastChangedIndex != 0 &&
                iLastChangedIndex != iNumSamples - 1 ) )
            {
                info[2] = iFirstChangedIndex;
                info[3] = iLastChangedIndex;
                numFields += 2;
            }
        }

        // finally set time sampling index on the end if necessary
        if (iTimeSamplingIndex != 0)
        {
            info[numFields] = iTimeSamplingIndex;
            numFields ++;
        }

    }

    WriteSmallArray( iGroup, iHeader.getName() + ".info",
        H5T_STD_U32LE, H5T_NATIVE_UINT32, numFields,
        ( const void * ) info );

    WriteMetaData( iGroup, iHeader.getName() + ".meta", iHeader.getMetaData());
}
示例#5
0
//-*****************************************************************************
void
ReadPropertyHeader( H5Node & iParent,
                    const std::string & iPropName,
                    AbcA::PropertyHeader & oHeader,
                    bool & oIsScalarLike,
                    uint32_t & oNumSamples,
                    uint32_t & oFirstChangedIndex,
                    uint32_t & oLastChangedIndex,
                    uint32_t & oTimeSamplingIndex )
{
    uint32_t info[5] = {0, 0, 0, 0, 0};
    size_t numFields = 0;
    size_t fieldsUsed = 1;

    // 0000 0000 0000 0000 0000 0000 0000 0011
    static const uint32_t ptypeMask = 0x0003;

    // 0000 0000 0000 0000 0000 0000 0011 1100
    static const uint32_t podMask = 0x003c;

    // 0000 0000 0000 0000 0000 0000 0100 0000
    static const uint32_t hasTsidxMask = 0x0040;

    // 0000 0000 0000 0000 0000 0000 1000 0000
    static const uint32_t noRepeatsMask = 0x0080;

    // 0000 0000 0000 0000 1111 1111 0000 0000
    static const uint32_t extentMask = 0xff00;

    ReadSmallArray(iParent.getObject(), iPropName + ".info", H5T_STD_U32LE,
                   H5T_NATIVE_UINT32, 5, numFields, (void *) info );

    AbcA::MetaData metaData;
    ReadMetaData( iParent, iPropName + ".meta", metaData );

    if ( numFields == 1 && info[0] == 0 )
    {
        oHeader = AbcA::PropertyHeader( iPropName, metaData );
    }
    else
    {
        // low two bits are the property type
        char ipt = info[0] & ptypeMask;

        // first bit is either scalar, or scalar like
        oIsScalarLike = ipt & 1;

        // is scalar like is set for this array attribute
        if (ipt == 3)
        {
            oHeader.setPropertyType( AbcA::kArrayProperty );
        }
        else
        {
            oHeader.setPropertyType( ( AbcA::PropertyType )ipt );
        }

        // Read the pod type out of bits 2-5
        char podt = ( char )( ( info[0] & podMask ) >> 2 );
        if ( podt != ( char )kBooleanPOD &&

             podt != ( char )kUint8POD &&
             podt != ( char )kInt8POD &&

             podt != ( char )kUint16POD &&
             podt != ( char )kInt16POD &&

             podt != ( char )kUint32POD &&
             podt != ( char )kInt32POD &&

             podt != ( char )kUint64POD &&
             podt != ( char )kInt64POD &&

             podt != ( char )kFloat16POD &&
             podt != ( char )kFloat32POD &&
             podt != ( char )kFloat64POD &&

             podt != ( char )kStringPOD &&
             podt != ( char )kWstringPOD )
        {
            ABCA_THROW( "Read invalid POD type: " << ( int )podt );
        }

        // bit 6 is the hint about whether time sampling index was written
        // at the end
        bool hasTsidx = ( (info[0] & hasTsidxMask ) >> 6 ) == 1;
        oTimeSamplingIndex = 0;

        if ( hasTsidx && numFields > 1 )
        {
            oTimeSamplingIndex = info[numFields - 1];
            fieldsUsed ++;
        }

        // bit 7 is a hint about whether first and last changed index
        // are intrinsically 1, and numSamples - 1
        // (no repeated data from the start or the end)
        bool noRepeats = ( (info[0] & noRepeatsMask ) >> 7 ) == 1;

        // Time Sampling Index could be written, but the number of samples
        // may not be.
        if ( numFields > fieldsUsed )
        {
            oNumSamples = info[1];

            if ( numFields >= 4 )
            {
                oFirstChangedIndex = info[2];
                oLastChangedIndex = info[3];
            }
            else if ( noRepeats )
            {
                oFirstChangedIndex = 1;
                oLastChangedIndex = oNumSamples - 1;
            }
            else
            {
                oFirstChangedIndex = 0;
                oLastChangedIndex = 0;
            }
        }
        else
        {
            oNumSamples = 0;
            oFirstChangedIndex = 0;
            oLastChangedIndex = 0;

            // if smp0 exists then we have 1 sample
            std::string smpName = iPropName + ".smp0";
            if ( oHeader.getPropertyType() == AbcA::kArrayProperty &&
                 ObjectExists( iParent, smpName ) )
            {
                oNumSamples = 1;
            }
            else if ( oHeader.getPropertyType() == AbcA::kScalarProperty &&
                      AttrExists( iParent, smpName ) )
            {
                oNumSamples = 1;
            }
        }

        // Read the extent out of bits 8-15
        uint8_t extent = ( uint8_t )( ( info[0] & extentMask ) >> 8 );
        if ( extent == 0 )
        {
            ABCA_THROW( "Degenerate extent 0" );
        }

        // bits 16-31 are currently not being used

        // the time sampling will be set on oHeader by the calling function
        // since we don't have access to the archive here.
        oHeader.setName( iPropName );
        oHeader.setMetaData( metaData );
        oHeader.setDataType(
            AbcA::DataType( ( Util::PlainOldDataType ) podt, extent ) );
    }
}
//TODO: out at maximum one warning per unsupported type
void readInputProperties( Abc::ICompoundProperty prop, std::vector<AbcProp>& props )
{
   if(!prop){
      return;
   }

   for(size_t i=0; i<prop.getNumProperties(); i++){
      AbcA::PropertyHeader pheader = prop.getPropertyHeader(i);
      AbcA::PropertyType propType = pheader.getPropertyType();

      //ESS_LOG_WARNING("Property, propName: "<<pheader.getName()<<", pod: "<<getPodStr(pheader.getDataType().getPod()) \
      // <<", extent: "<<(int)pheader.getDataType().getExtent()<<", interpretation: "<<pheader.getMetaData().get("interpretation"));
      
      int invalidStrIndex = containsInvalidString(pheader.getName());
      if( invalidStrIndex > 0 ){
         ESS_LOG_WARNING("Skipping property "<<pheader.getName()<<" because it contains an invalid character: "<<invalidStrTable[invalidStrIndex]);
         continue;
      }

      if( propType == AbcA::kCompoundProperty ){
         //printInputProperties(Abc::ICompoundProperty(prop, pheader.getName()));
         //ESS_LOG_WARNING("Unsupported compound property: "<<pheader.getName());
      }
      else if( propType == AbcA::kScalarProperty ){

         //ESS_LOG_WARNING("Scaler property: "<<pheader.getName());
         //

         std::string displayVal;
         bool bConstant = true;
         int sortId = 0;
         int size = 0;

         if(Abc::IBoolProperty::matches(pheader)){

            //I need to know the name and type only if animated; an appropriate controller will handle reading the data.
            //If not animated, the value will set directly on the light and/or display modifier

            Abc::IBoolProperty boolProp(prop, pheader.getName());
            /*if(boolProp.isConstant()){*/
               AbcU::bool_t bVal = false;
               boolProp.get(bVal);
               if(bVal == true) displayVal = "true";
               else displayVal = "false";
            //}
            //else{
            //  
            //}

         }
         else if(readPropExt1<Abc::IInt32Property, int>(prop, pheader, displayVal, bConstant));
         else if(readPropExt1<Abc::IFloatProperty, float>(prop, pheader, displayVal, bConstant));
         else if(readPropExt3<Abc::IC3fProperty, Abc::C3f>(prop, pheader, displayVal, bConstant));
         else if(readPropExt3<Abc::IV3fProperty, Abc::V3f>(prop, pheader, displayVal, bConstant));
         else if(readPropExt3<Abc::IN3fProperty, Abc::N3f>(prop, pheader, displayVal, bConstant));
         else if(Abc::IStringProperty::matches(pheader)){
            
            Abc::IStringProperty stringProp(prop, pheader.getName());
            stringProp.get(displayVal);
            sortId = 1000000000;
         }
         else{
      //   Abc::PropertyHeader propHeader = props.getPropertyHeader(i);
      //   AbcA::PropertyType propType = propHeader.getPropertyType();

            ESS_LOG_WARNING("Unsupported property, propName: "<<pheader.getName()<<", pod: "<<getPodStr(pheader.getDataType().getPod()) \
             <<", extent: "<<(int)pheader.getDataType().getExtent()<<", interpretation: "<<pheader.getMetaData().get("interpretation"));

         }

         props.push_back(AbcProp(pheader.getName(), displayVal, pheader, bConstant, sortId));
      }
      else if( propType == AbcA::kArrayProperty ){
         //ESS_LOG_WARNING("Unsupported array property: "<<pheader.getName());

         //it the moment is unlikely we will support array properties in 3DS Max. They won't work so well with our display modifier system.

         //ESS_LOG_WARNING("Unsupported array property, propName: "<<pheader.getName()<<", pod: "<<getPodStr(pheader.getDataType().getPod()) \
         //<<", extent: "<<(int)pheader.getDataType().getExtent()<<", interpretation: "<<pheader.getMetaData().get("interpretation"));
      }
      else{
         ESS_LOG_WARNING("Unsupported input property: "<<pheader.getName());
      }

   }
}