static void updateAttributeList(g_global_io &io,GU_Detail *cur_gdp) { fpreal numPt= cur_gdp->getNumPoints(); GA_Iterator iter(cur_gdp->getPointRange()); fpreal start_point_num = *iter; if ( cur_gdp ) { for (GA_AttributeDict::iterator it = cur_gdp->getAttributeDict(GA_ATTRIB_POINT).begin(GA_SCOPE_PUBLIC); !it.atEnd(); ++it) { GA_Attribute *attrib = it.attrib(); UT_String attName( attrib->getName() ); // std::cout<<"the att name is"<<attName<<std::endl; int attSize = attrib->getTupleSize(); GA_StorageClass storage= attrib->getStorageClass(); GA_TypeInfo typeInfo = attrib->getTypeInfo(); //save mata info switch(attSize) { case 1: // per int or float if(storage==GA_STORECLASS_FLOAT) { std::cout<<"the att name is "<<attName<< " and the type is float\n"; g_particles_io t_io; t_io.GIO_SetCurrentAttributeName(attName); t_io.GIO_SetCurrentAttributeType(g_particles_io::FLT_TYPE); std::vector<float> t_value; // create empty stack forkTheFLTData(t_value,attrib,numPt,start_point_num); t_io.GIO_setFLTAttributeList(t_value); io.GIO_installParticleHandle(t_io); // install this attribute into our global IO } if(storage==GA_STORECLASS_INT) { std::cout<<"the att name is "<<attName<< " and the type is int\n"; g_particles_io t_io; t_io.GIO_SetCurrentAttributeName(attName); t_io.GIO_SetCurrentAttributeType(g_particles_io::INT_TYPE); std::vector<int> t_value; // create empty int stack forkTheINTData(t_value,attrib,numPt,start_point_num); t_io.GIO_setINTAttributeList(t_value); io.GIO_installParticleHandle(t_io); } break; case 3: // int vector or float vector if(storage==GA_STORECLASS_FLOAT) { std::cout<<"the att name is "<<attName<< " and the type is float vector\n"; g_particles_io t_io; t_io.GIO_SetCurrentAttributeName(attName); t_io.GIO_SetCurrentAttributeType(g_particles_io::FLT_VEC_TYPE); std::vector<per_float_vector> t_value; // create empty int stack forkTheFLTVectorData(t_value,attrib,numPt,start_point_num); t_io.GIO_setFLTVecAttributeList(t_value); io.GIO_installParticleHandle(t_io); } if(storage==GA_STORECLASS_INT) { std::cout<<"the att name is "<<attName<< " and the type is int vector\n"; g_particles_io t_io; t_io.GIO_SetCurrentAttributeName(attName); t_io.GIO_SetCurrentAttributeType(g_particles_io::INT_VEC_TYPE); std::vector<per_int_vector> t_value; // create empty int stack forkTheINTVectorData(t_value,attrib,numPt,start_point_num); t_io.GIO_setINTVecAttributeList(t_value); io.GIO_installParticleHandle(t_io); } break; case 4: // P attrib { std::cout<<"the att name is "<<attName<< " and the type is float 4 \n"; g_particles_io t_io; t_io.GIO_SetCurrentAttributeName(attName); t_io.GIO_SetCurrentAttributeType(g_particles_io::FLT_VEC_TYPE); std::vector<per_float_vector> t_value; // create empty int stack forkTheFLTVectorData(t_value,it.attrib(),numPt,start_point_num); t_io.GIO_setFLTVecAttributeList(t_value); io.GIO_installParticleHandle(t_io); } break; } } } }
void wendy_GIO_ROP::save_mata_ass(string arDsoPath,string dpCachePath,GU_Detail *gdp ) { //get arnold dso path g_particle_mataAss assROP; ofstream fout; string getCacheDP=dpCachePath; stringstream ss(getCacheDP); string sub_str; vector <string> sp_strPath; sp_strPath.clear(); while(getline(ss,sub_str,'.')) { sp_strPath.push_back(sub_str); } string newAssPathName = sp_strPath[0]+"."+sp_strPath[1]+string(".ass"); fout.open(newAssPathName); assROP.setGioCachePath(getCacheDP); // set Link GIO CACHE for (GA_AttributeDict::iterator it = gdp->getAttributeDict(GA_ATTRIB_POINT).begin(GA_SCOPE_PUBLIC); !it.atEnd(); ++it) { GA_Attribute *attrib = it.attrib(); string attName( attrib->getName() ); assROP.inserExtraMataInfo(attName); } //set ass bbox UT_BoundingBox BBOX; gdp->getBBox(&BBOX); BBOX.expandBounds(2,2,2); float min_x=BBOX.xmin(); float min_y=BBOX.xmin(); float min_z=BBOX.xmin(); float max_x=BBOX.xmax(); float max_y=BBOX.ymax(); float max_z=BBOX.zmax(); assROP.setBBOX(min_x,min_y,min_z,max_x,max_y,max_z); assROP.setDsoPath(arDsoPath); assROP.save(fout); fout.close(); }
static void exportParticlesDetail( const GU_Detail* gdp, const std::string& filePath, const std::map<std::string, channel_type>& desiredChannels ) { prt_ofstream ostream; static std::map<std::string, std::string> s_reservedChannels; if( s_reservedChannels.empty() ) { s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_NORMAL ) ] = "Normal"; s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_TEXTURE ) ] = "TextureCoord"; s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_VELOCITY ) ] = "Velocity"; s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_DIFFUSE ) ] = "Color"; //s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_ALPHA ) ] = "Density"; //s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_MASS ) ] = "Density"; s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_LIFE ) ] = ""; s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_ID ) ] = "ID"; s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_PSCALE ) ] = "Scale"; s_reservedChannels[ "accel" ] = "Acceleration"; } float posVal[3]; float lifeVal[2]; ostream.bind( "Position", posVal, 3 ); //We handle the life channel in a special manner GA_ROAttributeRef lifeAttrib = gdp->findPointAttribute( gdp->getStdAttributeName( GEO_ATTRIBUTE_LIFE ) ); if( lifeAttrib.isValid() ){ std::map<std::string,channel_type>::const_iterator it; it = desiredChannels.find( "Age" ); if( it != desiredChannels.end() && it->second.second == 1 ) ostream.bind( "Age", &lifeVal[0], 1, it->second.first ); else if( desiredChannels.empty() ) ostream.bind( "Age", &lifeVal[0], 1, prtio::data_types::type_float16 ); it = desiredChannels.find( "LifeSpan" ); if( it != desiredChannels.end() && it->second.second == 1 ) ostream.bind( "LifeSpan", &lifeVal[1], 1, it->second.first ); else if( desiredChannels.empty() ) ostream.bind( "LifeSpan", &lifeVal[1], 1, prtio::data_types::type_float16 ); } //Using a deque to prevent the memory from moving around after adding the bound_attribute to the container. std::deque< bound_attribute<int> > m_intAttrs; std::deque< bound_attribute<float> > m_floatAttrs; std::deque< bound_attribute<float> > m_vectorAttrs; for ( GA_AttributeDict::iterator it = gdp->getAttributes().getDict(GA_ATTRIB_POINT).begin(GA_SCOPE_PUBLIC); !it.atEnd(); ++it) { GA_Attribute *node = it.attrib(); std::string channelName = node->getName(); //Translate special names std::map<std::string,std::string>::const_iterator itResChannel = s_reservedChannels.find( channelName ); if( itResChannel != s_reservedChannels.end() ){ //If its empty, that means we reserve some sort of special handling. if( itResChannel->second.empty() ) continue; channelName = itResChannel->second; } //Skip channels that aren't on the list. std::map<std::string,channel_type>::const_iterator itChannel = desiredChannels.find( channelName ); bool channelIsDesired = ( itChannel != desiredChannels.end() ); if( !desiredChannels.empty() && !channelIsDesired ) continue; prtio::data_types::enum_t type; //Only add valid channel names if( detail::is_valid_channel_name( channelName.c_str() ) ) { //I add the new item to the deque, THEN initialize it since a deque will not move the object around and this allows //me to allocate the float array and not have to worry about the object getting deleted too early. switch( node->getStorageClass() ){ case GA_STORECLASS_FLOAT: if( node->getTupleSize()==3 ){ m_vectorAttrs.push_back( bound_attribute<float>() ); m_vectorAttrs.back().attr = gdp->findPointAttribute(node->getName()); m_vectorAttrs.back().count = node->getTupleSize(); m_vectorAttrs.back().data = new float[m_vectorAttrs.back().count]; type = prtio::data_types::type_float16; if( channelIsDesired ){ type = itChannel->second.first; if( itChannel->second.second != m_vectorAttrs.back().count ) continue; } ostream.bind( channelName, m_vectorAttrs.back().data, m_vectorAttrs.back().count, type ); } else { m_floatAttrs.push_back( bound_attribute<float>() ); m_floatAttrs.back().attr = gdp->findPointAttribute( node->getName() ); m_floatAttrs.back().count = node->getTupleSize(); m_floatAttrs.back().data = new float[m_floatAttrs.back().count]; type = prtio::data_types::type_float16; if( channelIsDesired ){ type = itChannel->second.first; if( itChannel->second.second != m_floatAttrs.back().count ) continue; } ostream.bind( channelName, m_floatAttrs.back().data, m_floatAttrs.back().count, type ); } break; case GA_STORECLASS_INT: m_intAttrs.push_back( bound_attribute<int>() ); m_intAttrs.back().attr = gdp->findPointAttribute( node->getName() ); m_intAttrs.back().count = node->getTupleSize(); m_intAttrs.back().data = new int[m_intAttrs.back().count]; type = prtio::data_types::type_int32; if( channelIsDesired ){ type = itChannel->second.first; if( itChannel->second.second != m_intAttrs.back().count ) continue; } ostream.bind( channelName, m_intAttrs.back().data, m_intAttrs.back().count, type ); break; default: break; } } } try{ ostream.open( filePath ); } catch( const std::ios::failure& e ) { std::cerr << e.what() << std::endl; throw HOM_OperationFailed( "Failed to open the file" ); } GA_IndexMap map = gdp->getPointMap(); UT_Vector3 p; GEO_Point* pt; GA_Index indexSize = map.indexSize(); GA_Offset offset; for( int i = 0 ; i < indexSize; i++ ) { offset = map.offsetFromIndex( i ); p = gdp->getPos3( offset ); posVal[0] = p.x(); posVal[1] = p.y(); posVal[2] = -1 * p.z(); //TODO: Remove the GEO_Point object that is now deprecated. pt = ( GEO_Point* )gdp->getGBPoint( offset ); //TODO: Convert this into appropriate time values. Is it seconds or frames or what?! if( lifeAttrib.isValid() ) pt->get( lifeAttrib, lifeVal, 2 ); for( std::deque< bound_attribute<float> >::iterator it = m_floatAttrs.begin(), itEnd = m_floatAttrs.end(); it != itEnd; ++it ) pt->get( it->attr, it->data, it->count ); for( std::deque< bound_attribute<float> >::iterator it = m_vectorAttrs.begin(), itEnd = m_vectorAttrs.end(); it != itEnd; ++it ) { pt->get( it->attr, it->data, it->count ); //TODO: Optionally transform into some consistent world space for PRT files. } for( std::deque< bound_attribute<int> >::iterator it = m_intAttrs.begin(), itEnd = m_intAttrs.end(); it != itEnd; ++it ) pt->get( it->attr, it->data, it->count ); ostream.write_next_particle(); } ostream.close(); }