Beispiel #1
0
//-*****************************************************************************
void IObjectDrw::draw( const DrawContext &iCtx )
{
    if ( !m_object ) { return; }

    // Skip objects with "visible" property set to 0
    if ( iCtx.getVisibleOnly() ) {
        Abc::ICompoundProperty props = m_object.getProperties();
        const Abc::PropertyHeader* header = props.getPropertyHeader( "visible" );
        if ( header != NULL ) {
            Abc::IScalarProperty visible( props, "visible" );
            Abc::ISampleSelector iss( m_currentTime );
            int8_t val = 1;
            visible.get( reinterpret_cast<void*>( &val ), iss );
            if ( val == 0 ) 
                return;
        }
    }

    for ( DrawablePtrVec::iterator iter = m_children.begin();
          iter != m_children.end(); ++iter )
    {
        DrawablePtr dptr = (*iter);
        if ( dptr )
        {
            dptr->draw( iCtx );
        }
    }
}
Abc::FloatArraySamplePtr getKnotVector(AbcG::ICurves& obj)
{
  ESS_PROFILE_FUNC();

  Abc::ICompoundProperty arbGeom = obj.getSchema().getArbGeomParams();

  if (!arbGeom.valid()) {
    return Abc::FloatArraySamplePtr();
  }

  if (arbGeom.getPropertyHeader(".knot_vectors") != NULL) {
    Abc::IFloatArrayProperty knotProp =
        Abc::IFloatArrayProperty(arbGeom, ".knot_vectors");
    if (knotProp.valid() && knotProp.getNumSamples() != 0) {
      return knotProp.getValue(0);
    }
  }
  if (arbGeom.getPropertyHeader(".knot_vector") != NULL) {
    Abc::IFloatArrayProperty knotProp =
        Abc::IFloatArrayProperty(arbGeom, ".knot_vector");
    if (knotProp.valid() && knotProp.getNumSamples() != 0) {
      return knotProp.getValue(0);
    }
  }

  return Abc::FloatArraySamplePtr();
}
//-*****************************************************************************
void IObjectDrw::draw( const DrawContext &iCtx )
{
    if ( !m_object ) { return; }

    // Skip objects with "visible" property set to 0
    if ( iCtx.visibleOnly() ) {
        Abc::ICompoundProperty props = m_object.getProperties();
        const Abc::PropertyHeader* header = props.getPropertyHeader( "visible" );
        if ( header != NULL ) {
            Abc::IScalarProperty visible( props, "visible" );
            Abc::ISampleSelector iss( m_currentTime );
            int8_t val = 1;
            visible.get( reinterpret_cast<void*>( &val ), iss );
            if ( val == 0 ) 
                return;
        }
    }

    // GL picking, add to global selection index
    int i = 0;
    for ( DrawablePtrVec::iterator iter = m_children.begin();
          iter != m_children.end(); ++iter, i++ )
    {
        Abc::IObject iChild = m_object.getChild( i );
        int index = pushName( iChild );
        DrawablePtr dptr = (*iter);
        if ( dptr )
        {
            dptr->draw( iCtx );
        }
        if ( index >= 0 )
            popName( m_object );
    }
    
}
void setupPropertyModifiers( AbcG::IObject& iObj, INode* pMaxNode, const std::string& file, const std::string& identifier, alembic_importoptions &options, const std::string prefix )
{

   Abc::ICompoundProperty userProps = AbcNodeUtils::getUserProperties(iObj);
   if(userProps.valid()){
      std::vector<AbcProp> propsVec;
      readInputProperties(userProps, propsVec);

      if(!propsVec.empty())
      {
         std::sort(propsVec.begin(), propsVec.end(), sortFunc);
         std::string name = prefix + " User Properties";
         createDisplayModifier(name, name, propsVec, pMaxNode);

         addControllersToModifierV2(name, name, propsVec, file, identifier, "userProperties", options, pMaxNode);
      }
   }

   //Abc::ICompoundProperty geomProps = AbcNodeUtils::getArbGeomParams(iObj);
   //if(geomProps.valid()){
   //   std::vector<AbcProp> propsVec;
   //   readInputProperties(geomProps, propsVec);

   //   if(!propsVec.empty())
   //   {
   //      std::sort(propsVec.begin(), propsVec.end(), sortFunc);
   //      std::string name = prefix + "ArbGeom Properties";
   //      createDisplayModifier(name, name, propsVec, pMaxNode);

   //      //addControllersToModifierV2("ArbGeom Properties", "ArbGeom Properties", propsVec, file, iObjXform.getFullName(), options, pMaxNode);
   //   }
   //}

}
static PyObject * iCompoundProperty_getPropertyNames(PyObject * self, PyObject * args)
{
   ALEMBIC_TRY_STATEMENT
      Abc::ICompoundProperty *icprop = ((iCompoundProperty*)self)->mBaseCompoundProperty;
      const int nb_prop = icprop->getNumProperties();

      PyObject *tuple = PyTuple_New(nb_prop);
      for (int i = 0; i < nb_prop; ++i)
         PyTuple_SetItem(tuple,i,Py_BuildValue("s",icprop->getPropertyHeader(i).getName().c_str()));

      return tuple;
   ALEMBIC_PYOBJECT_CATCH_STATEMENT
}
AbcM::IMaterialSchema getMatSchema(AbcG::ILight& objLight)
{
   Abc::ICompoundProperty props = objLight.getProperties();

   for(int i=0; i<props.getNumProperties(); i++){
      Abc::PropertyHeader propHeader = props.getPropertyHeader(i);
      if(AbcM::IMaterialSchema::matches(propHeader)){
         return AbcM::IMaterialSchema(props, propHeader.getName());
      }
   }

   return AbcM::IMaterialSchema();
}
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"));


   }
}
Abc::UInt16ArraySamplePtr getCurveOrders(AbcG::ICurves& obj)
{
   ESS_PROFILE_FUNC();

   Abc::ICompoundProperty arbGeom = obj.getSchema().getArbGeomParams();

   if(!arbGeom.valid()){
      return Abc::UInt16ArraySamplePtr();
   }

   if ( arbGeom.getPropertyHeader( ".orders" ) != NULL ){
      Abc::IUInt16ArrayProperty orders = Abc::IUInt16ArrayProperty( arbGeom, ".orders" );
      if(orders.valid() && orders.getNumSamples() != 0){
         return orders.getValue(0);
      }
   }

   return Abc::UInt16ArraySamplePtr();
}
Beispiel #9
0
XSI_XformTypes::xte getXformType(AbcG::IXform& obj)
{
   Abc::ICompoundProperty arbGeom = obj.getSchema().getArbGeomParams();

   if(!arbGeom.valid()){
      return XSI_XformTypes::UNKNOWN;
   }

   if ( arbGeom.getPropertyHeader( ".xsiNodeType" ) != NULL ){

      Abc::IUcharProperty types = Abc::IUcharProperty( arbGeom, ".xsiNodeType" );
      if(types.valid() && types.getNumSamples() != 0){
         return (XSI_XformTypes::xte)types.getValue(0);
      }
   }

   return XSI_XformTypes::UNKNOWN;

}
int AlembicImport_Light(const std::string &path, AbcG::IObject& iObj, alembic_importoptions &options, INode** pMaxNode)
{
//#define OMNI_LIGHT_CLASS_ID  		0x1011
//#define SPOT_LIGHT_CLASS_ID  		0x1012
//#define DIR_LIGHT_CLASS_ID  		0x1013
//#define FSPOT_LIGHT_CLASS_ID  		0x1014
//#define TDIR_LIGHT_CLASS_ID  		0x1015

//#define OMNI_LIGHT		0	// Omnidirectional
//#define TSPOT_LIGHT		1	// Targeted
//#define DIR_LIGHT		2	// Directional
//#define FSPOT_LIGHT		3	// Free
//#define TDIR_LIGHT		4   // Targeted directional

   if(options.attachToExisting){
      ESS_LOG_WARNING("Attach to existing for lights is not yet supported. Could not attach "<<iObj.getFullName());
      return alembic_success;
   }

   std::vector<matShader> shaders;

   AbcG::ILight objLight = AbcG::ILight(iObj, Alembic::Abc::kWrapExisting);

   std::string identifier = objLight.getFullName();

   //CompoundPropertyReaderPtr propReader = objLight.getProperties();

   Abc::ICompoundProperty props = objLight.getProperties();

   InputLightType::enumt lightType = InputLightType::NUM_INPUT_LIGHT_TYPES;

   for(int i=0; i<props.getNumProperties(); i++){
      Abc::PropertyHeader propHeader = props.getPropertyHeader(i);
      if(AbcM::IMaterialSchema::matches(propHeader)){
         AbcM::IMaterialSchema matSchema(props, propHeader.getName());
   
         //ESS_LOG_WARNING("MaterialSchema present on light.");

         lightType = readShader(matSchema, shaders);
      }

      //ESS_LOG_WARNING("name: "<<propHeader.getName());

      //if( AbcG::ICameraSchema::matches(propHeader) ){
      //   ESS_LOG_WARNING("Found light camera.");
      //   //AbcG::ICameraSchema camSchema(props, propHeader.getName());

      //}
   }



   bool bReplaceExisting = false;
   int nodeRes = alembic_failure;
   if(lightType == InputLightType::AMBIENT_LIGHT){
      nodeRes = createNode(iObj, LIGHT_CLASS_ID, Class_ID(OMNI_LIGHT_CLASS_ID, 0), pMaxNode, bReplaceExisting);

      //Modifier* pModifier = FindModifier(*pMaxNode, Class_ID(OMNI_LIGHT_CLASS_ID, 0));

      //if(pModifier){
      //   ESS_LOG_WARNING("NumParamBlocks: "<<pModifier->NumParamBlocks());
      //}
   
      //printControllers(*pMaxNode);

      //pMaxNode>GetParamBlockByID( 0 )->SetValue( GetParamIdByName( pModifier, 0, "muted" ), zero, FALSE );


      GET_MAX_INTERFACE()->SelectNode(*pMaxNode);

      //set the ambient check box, intensity controller, and light colour controller (not sure how to this in C++)
      std::stringstream evalStream;
      std::string modkey("");

      for(int s=0; s<shaders.size(); s++){
         std::string target = shaders[s].target;
         std::string type = shaders[s].type;

         for(int i=0; i<shaders[s].props.size(); i++){
            std::string propName = shaders[s].props[i].name;
            std::string& val = shaders[s].props[i].displayVal;
            bool& bConstant = shaders[s].props[i].bConstant;

            const AbcA::DataType& datatype = shaders[s].props[i].propHeader.getDataType();
            const AbcA::MetaData& metadata = shaders[s].props[i].propHeader.getMetaData();

            if(datatype.getPod() == AbcA::kFloat32POD){

               std::stringstream propStream;
               propStream<<target<<"."<<type<<"."<<propName;
               if(datatype.getExtent() == 1 && propName.find("intensity") != std::string::npos ){ //intensity property found, so attach controller
                  addFloatController(evalStream, options, modkey, std::string("multiplier"), path, iObj.getFullName(), propStream.str());
               }
               else if(datatype.getExtent() == 3 && propName.find("lightcolor") != std::string::npos ){ //color property found, so attach controller

                  std::stringstream xStream, yStream, zStream;

                  xStream<<propStream.str()<<"."<<metadata.get("interpretation")<<".x";
                  yStream<<propStream.str()<<"."<<metadata.get("interpretation")<<".y";
                  zStream<<propStream.str()<<"."<<metadata.get("interpretation")<<".z";

                  evalStream<<"$.rgb.controller = Color_RGB()\n";

                  addFloatController(evalStream, options, modkey, std::string("rgb.controller.r"), path, iObj.getFullName(), xStream.str());
                  addFloatController(evalStream, options, modkey, std::string("rgb.controller.g"), path, iObj.getFullName(), yStream.str());
                  addFloatController(evalStream, options, modkey, std::string("rgb.controller.b"), path, iObj.getFullName(), zStream.str());
               }
            }
            else{
               
            }
            evalStream<<"\n";
         }
      }

      evalStream<<"$.ambientOnly = true\n";
      ExecuteMAXScriptScript( EC_UTF8_to_TCHAR((char*)evalStream.str().c_str()));
   }
   else{//create a null, if we don't know what type of light this is
      nodeRes = createNode(iObj, HELPER_CLASS_ID, Class_ID(DUMMY_CLASS_ID,0), pMaxNode, bReplaceExisting);
   }

   if(nodeRes == alembic_failure){
      return nodeRes;
   }


   GET_MAX_INTERFACE()->SelectNode(*pMaxNode);

   for(int i=0; i<shaders.size(); i++){

      std::sort(shaders[i].props.begin(), shaders[i].props.end(), sortFunc);

      Modifier* pMod = createDisplayModifier("Shader Properties", shaders[i].name, shaders[i].props);

      std::string target = shaders[i].target;
      std::string type = shaders[i].type;

      addControllersToModifier("Shader Properties", shaders[i].name, shaders[i].props, target, type, path, iObj.getFullName(), options);
   }

   // ----- TODO: add camera modifier
   //createCameraModifier(path, identifier, *pMaxNode);


   // ----- TODO: don't attach controllers for constant parameters


   //TODO: make the spinners read only



   return alembic_success;
}
//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());
      }

   }
}
void AlembicFloatController::GetValueLocalTime(TimeValue t, void* ptr,
                                               Interval& valid,
                                               GetSetMethod method)
{
  ESS_CPP_EXCEPTION_REPORTING_START

  Interval interval = FOREVER;

  MCHAR const* strPath = NULL;
  this->pblock->GetValue(AlembicFloatController::ID_PATH, t, strPath, interval);

  MCHAR const* strIdentifier = NULL;
  this->pblock->GetValue(AlembicFloatController::ID_IDENTIFIER, t,
                         strIdentifier, interval);

  MCHAR const* strCategory = NULL;
  this->pblock->GetValue(AlembicFloatController::ID_CATEGORY, t, strCategory,
                         interval);

  MCHAR const* strProperty = NULL;
  this->pblock->GetValue(AlembicFloatController::ID_PROPERTY, t, strProperty,
                         interval);

  float fTime;
  this->pblock->GetValue(AlembicFloatController::ID_TIME, t, fTime, interval);

  BOOL bMuted;
  this->pblock->GetValue(AlembicFloatController::ID_MUTED, t, bMuted, interval);

  extern bool g_bVerboseLogging;

  if (g_bVerboseLogging) {
    ESS_LOG_WARNING("Param block at tick " << t << "-----------------------");
    ESS_LOG_WARNING("PATH: " << strPath);
    ESS_LOG_WARNING("IDENTIFIER: " << strIdentifier);
    ESS_LOG_WARNING("PROPERTY: " << strProperty);
    ESS_LOG_WARNING("TIME: " << fTime);
    ESS_LOG_WARNING("MUTED: " << bMuted);
    ESS_LOG_WARNING("Param block end -------------");
  }

  const float fDefaultVal = -1.0;

  std::string szPath = EC_MCHAR_to_UTF8(strPath);
  std::string szIdentifier = EC_MCHAR_to_UTF8(strIdentifier);
  std::string szProperty = EC_MCHAR_to_UTF8(strProperty);
  std::string szCategory = EC_MCHAR_to_UTF8(strCategory);

  if (szCategory.empty()) {  // default to standard properties for backwards
    // compatibility
    szCategory = std::string("standardProperties");
  }

  if (!strProperty || !strPath || !strIdentifier /*|| !strCategory*/) {
    return setController("1", szProperty, valid, interval, method, ptr,
                         fDefaultVal);
  }

  if (bMuted) {
    return setController("2", szProperty, valid, interval, method, ptr,
                         fDefaultVal);
  }

  // if( szCategory.size() == 0 ) {
  //   ESS_LOG_ERROR( "No category specified." );
  //   return setController("3a", szProperty, valid, interval,   method,   ptr,
  //   fDefaultVal);
  //}

  if (szProperty.size() == 0) {
    ESS_LOG_ERROR("No property specified.");
    return setController("3b", szProperty, valid, interval, method, ptr,
                         fDefaultVal);
  }

  AbcG::IObject iObj = getObjectFromArchive(szPath, szIdentifier);

  if (!iObj.valid()) {
    return setController("4", szProperty, valid, interval, method, ptr,
                         fDefaultVal);
  }

  TimeValue dTicks = GetTimeValueFromSeconds(fTime);
  double sampleTime = GetSecondsFromTimeValue(dTicks);

  float fSampleVal = fDefaultVal;

  if (boost::iequals(szCategory, "standardProperties")) {
    if (Alembic::AbcGeom::ICamera::matches(
            iObj.getMetaData())) {  // standard camera properties

      Alembic::AbcGeom::ICamera objCamera =
          Alembic::AbcGeom::ICamera(iObj, Alembic::Abc::kWrapExisting);

      SampleInfo sampleInfo =
          getSampleInfo(sampleTime, objCamera.getSchema().getTimeSampling(),
                        objCamera.getSchema().getNumSamples());
      Alembic::AbcGeom::CameraSample sample;
      objCamera.getSchema().get(sample, sampleInfo.floorIndex);

      double sampleVal;
      if (!getCameraSampleVal(objCamera, sampleInfo, sample, szProperty,
                              sampleVal)) {
        return setController("5", szProperty, valid, interval, method, ptr,
                             fDefaultVal);
      }

      // Blend the camera values, if necessary
      if (sampleInfo.alpha != 0.0) {
        objCamera.getSchema().get(sample, sampleInfo.ceilIndex);
        double sampleVal2 = 0.0;
        if (getCameraSampleVal(objCamera, sampleInfo, sample, szProperty,
                               sampleVal2)) {
          sampleVal = (1.0 - sampleInfo.alpha) * sampleVal +
                      sampleInfo.alpha * sampleVal2;
        }
      }

      fSampleVal = (float)sampleVal;
    }
    else if (Alembic::AbcGeom::ILight::matches(
                 iObj.getMetaData())) {  // ILight material properties

      ESS_PROFILE_SCOPE(
          "AlembicFloatController::GetValueLocalTime - read ILight shader "
          "parameter");

      Alembic::AbcGeom::ILight objLight =
          Alembic::AbcGeom::ILight(iObj, Alembic::Abc::kWrapExisting);

      SampleInfo sampleInfo =
          getSampleInfo(sampleTime, objLight.getSchema().getTimeSampling(),
                        objLight.getSchema().getNumSamples());

      AbcM::IMaterialSchema matSchema = getMatSchema(objLight);

      std::string strProp = szProperty;

      std::vector<std::string> parts;
      boost::split(parts, strProp, boost::is_any_of("."));

      if (parts.size() == 3) {
        const std::string& target = parts[0];
        const std::string& type = parts[1];
        const std::string& prop = parts[2];

        Abc::IFloatProperty fProp = readShaderScalerProp<Abc::IFloatProperty>(
            matSchema, target, type, prop);
        if (fProp.valid()) {
          fProp.get(fSampleVal, sampleInfo.floorIndex);
        }
        else {
          ESS_LOG_WARNING("Float Controller Error: could find shader parameter "
                          << strProp);
        }
      }
      else if (parts.size() == 5) {
        const std::string& target = parts[0];
        const std::string& type = parts[1];
        const std::string& prop = parts[2];
        const std::string& propInterp = parts[3];
        const std::string& propComp = parts[4];

        // ESS_LOG_WARNING("propInterp: "<<propInterp);

        if (propInterp == "rgb") {
          Abc::IC3fProperty fProp = readShaderScalerProp<Abc::IC3fProperty>(
              matSchema, target, type, prop);
          if (fProp.valid()) {
            Abc::C3f v3f;
            fProp.get(v3f, sampleInfo.floorIndex);
            if (propComp == "x") {
              fSampleVal = v3f.x;
            }
            else if (propComp == "y") {
              fSampleVal = v3f.y;
            }
            else if (propComp == "z") {
              fSampleVal = v3f.z;
            }
            else {
              ESS_LOG_WARNING(
                  "Float Controller Error: invalid component: " << propComp);
            }
          }
          else {
            ESS_LOG_WARNING(
                "Float Controller Error: could find shader parameter "
                << strProp);
          }
        }
        else {
          ESS_LOG_WARNING(
              "Float Controller Error: unrecognized parameter interpretation: "
              << propInterp);
        }
      }
      else {
        ESS_LOG_WARNING(
            "Float Controller Error: could not parse property field: "
            << strProperty);
      }
    }
  }
  else if (boost::iequals(szCategory, "userProperties")) {
    // AbcA::TimeSamplingPtr timeSampling = obj.getSchema().getTimeSampling();
    // int nSamples = (int)obj.getSchema().getNumSamples();

    AbcA::TimeSamplingPtr timeSampling;
    int nSamples = 0;
    Abc::ICompoundProperty propk =
        AbcNodeUtils::getUserProperties(iObj, timeSampling, nSamples);

    if (propk.valid()) {
      SampleInfo sampleInfo = getSampleInfo(sampleTime, timeSampling, nSamples);

      std::vector<std::string> parts;
      boost::split(parts, szProperty, boost::is_any_of("."));

      if (parts.size() == 1) {
        Abc::IFloatProperty fProp =
            readScalarProperty<Abc::IFloatProperty>(propk, szProperty);
        if (fProp.valid()) {
          fProp.get(fSampleVal, sampleInfo.floorIndex);
        }
        else {
          Abc::IInt32Property intProp =
              readScalarProperty<Abc::IInt32Property>(propk, szProperty);
          if (intProp.valid()) {
            int intVal;
            intProp.get(intVal, sampleInfo.floorIndex);
            fSampleVal = (float)intVal;
          }
          else {
            ESS_LOG_WARNING(
                "Float Controller Error: could not read user property "
                << szProperty);
          }
        }
      }
      else if (parts.size() == 3) {
        const std::string& prop = parts[0];
        const std::string& propInterp = parts[1];
        const std::string& propComp = parts[2];

        // ESS_LOG_WARNING("interpretation: "<<propInterp);

        if (propInterp == "rgb") {
          fSampleVal = readScalarPropertyExt3<Abc::IC3fProperty, Abc::C3f>(
              propk, sampleInfo, prop, propComp);
        }
        else if (propInterp == "vector") {
          fSampleVal = readScalarPropertyExt3<Abc::IV3fProperty, Abc::V3f>(
              propk, sampleInfo, prop, propComp);
        }
        else {
          ESS_LOG_WARNING(
              "Float Controller Error: unrecognized parameter interpretation: "
              << propInterp);
        }
      }
    }
  }
  // else if( boost::iequals(szCategory, "arbGeomParams") ){

  //}

  return setController("6", szProperty, valid, interval, method, ptr,
                       fSampleVal);

  ESS_CPP_EXCEPTION_REPORTING_END
}