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")); } }
//-***************************************************************************** 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()); }
//-***************************************************************************** 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()); } } }