Esempio n. 1
0
void
print(const ParticlesData* particles)
{
    std::cout<<"Particle count "<<particles->numParticles()<<std::endl;
    std::cout<<"Attribute count "<<particles->numAttributes()<<std::endl;

    std::vector<ParticleAttribute> attrs;
    for(int i=0;i<particles->numAttributes();i++){
        ParticleAttribute attr;
        particles->attributeInfo(i,attr);
        attrs.push_back(attr);
        std::cout<<"attribute "<<attr.name<<" "<<int(attr.type)<<" "<<attr.count<<std::endl;
    }

    int numToPrint=std::min(10,particles->numParticles());
    std::cout<<"num to print "<<numToPrint<<std::endl;

    ParticlesData::const_iterator it=particles->begin(),end=particles->end();
    std::vector<ParticleAccessor> accessors;
    for(size_t k=0;k<attrs.size();k++) accessors.push_back(ParticleAccessor(attrs[k]));
    for(size_t k=0;k<attrs.size();k++) it.addAccessor(accessors[k]);

    for(int i=0;i<numToPrint && it != end;i++){
        std::cout<<i<<": ";
        for(unsigned int k=0;k<attrs.size();k++){
            switch(attrs[k].type){
            case NONE:break;
            case FLOAT:
            case VECTOR:
                for(int c=0;c<attrs[k].count;c++) std::cout<<accessors[k].raw<float>(it)[c] << " ";
                break;
            case INT:
                for(int c=0;c<attrs[k].count;c++) std::cout<<accessors[k].raw<int>(it)[c] << " ";
                break;
            case INDEXEDSTR:
                for(int c=0;c<attrs[k].count;c++) std::cout<<accessors[k].raw<int>(it)[c] << " ";
                break;
            }
        }
        std::cout<<std::endl;
		it++;
    }
}
Esempio n. 2
0
File: BGEO.cpp Progetto: K240/partio
ParticlesDataMutable* readBGEO(const char* filename,const bool headersOnly)
{
    std::auto_ptr<std::istream> input(Gzip_In(filename,std::ios::in|std::ios::binary));
    if(!*input){
        std::cerr<<"Partio: Unable to open file "<<filename<<std::endl;
        return 0;
    }

    // header values
    int magic;
    char versionChar;
    int version;
    int nPoints;
    int nPrims;
    int nPointGroups;
    int nPrimGroups;
    int nPointAttrib;
    int nVertexAttrib;
    int nPrimAttrib;
    int nAttrib;
    read<BIGEND>(*input,magic,versionChar,version,nPoints,nPrims,nPointGroups);
    read<BIGEND>(*input,nPrimGroups,nPointAttrib,nVertexAttrib,nPrimAttrib,nAttrib);


    // Check header magic and version
    const int bgeo_magic=((((('B'<<8)|'g')<<8)|'e')<<8)|'o';
    if(magic!=bgeo_magic){
        std::cerr<<"Partio: Magic number '"<<magic<<" of '"<<filename<<"' doesn't match bgeo magic '"<<bgeo_magic<<std::endl;
        return 0;
    }
    if(version!=5){
        std::cerr<<"Partio: BGEO must be version 5"<<std::endl;
        return 0;
    }

    // Allocate a simple particle with the appropriate number of points
    ParticlesDataMutable* simple=0;
    if(headersOnly) simple=new ParticleHeaders;
    else simple=create();

    simple->addParticles(nPoints);


    // Read attribute definitions
    int particleSize=4; // Size in # of 32 bit primitives 
    std::vector<int> attrOffsets; // offsets in # of 32 bit offsets
    std::vector<ParticleAttribute> attrHandles;
    std::vector<ParticleAccessor> accessors;
    attrOffsets.push_back(0); // pull values from byte offset
    attrHandles.push_back(simple->addAttribute("position",VECTOR,3)); // we always have one
    accessors.push_back(ParticleAccessor(attrHandles[0]));
    
    for(int i=0;i<nPointAttrib;i++){
        unsigned short nameLength;
        read<BIGEND>(*input,nameLength);
        char* name=new char[nameLength+1];
        input->read(name,nameLength);name[nameLength]=0;
        unsigned short size;
        int houdiniType;
        read<BIGEND>(*input,size,houdiniType);
        if(houdiniType==0 || houdiniType==1 || houdiniType==5){
            // read default values. don't do anything with them
            for(int i=0;i<size;i++) {
                int defaultValue;
                input->read((char*)&defaultValue,sizeof(int));
            }
            ParticleAttributeType type=NONE;
            if(houdiniType==0) type=FLOAT;
            else if(houdiniType==1) type=INT;
            else if(houdiniType==5) type=VECTOR;
            attrHandles.push_back(simple->addAttribute(name,type,size));
            accessors.push_back(ParticleAccessor(attrHandles.back()));
            attrOffsets.push_back(particleSize);
            particleSize+=size;
        }else if(houdiniType==4){
            std::cerr<<"Partio: attr '"<<name<<"' of type index (string) found, treating as integer"<<std::endl;
            int numIndices=0;
            read<BIGEND>(*input,numIndices);
            for(int ii=0;ii<numIndices;ii++){
                unsigned short indexNameLength;
                read<BIGEND>(*input,indexNameLength);
                char* indexName=new char[indexNameLength+1];;
                input->read(indexName,indexNameLength);
                indexName[indexNameLength]=0;
                std::cerr<<"Partio:    index "<<ii<<" is "<<indexName<<std::endl;
                delete [] indexName;
            }
            attrHandles.push_back(simple->addAttribute(name,INT,size));
            accessors.push_back(ParticleAccessor(attrHandles.back()));
            attrOffsets.push_back(particleSize);
            particleSize+=size;
        }else if(houdiniType==2){
            std::cerr<<"Partio: found attr of type 'string', aborting"<<std::endl;
            delete [] name;
            simple->release();
            return 0;
        }else{
            std::cerr<<"Partio: unknown attribute "<<houdiniType<<" type... aborting"<<std::endl;
            delete [] name;
            simple->release();
            return 0;
        }
        delete[] name;
    }

    if(headersOnly) return simple; // escape before we try to edit data

    // Read the points
    int *buffer=new int[particleSize];

    // make iterator and register accessors
    ParticlesDataMutable::iterator iterator=simple->begin();
    for(size_t i=0;i<accessors.size();i++) iterator.addAccessor(accessors[i]);

    for(ParticlesDataMutable::iterator end=simple->end();iterator!=end;++iterator){
        //for(int i=0;i<nPoints;i++){
        input->read((char*)buffer,particleSize*sizeof(int));
        for(unsigned int attrIndex=0;attrIndex<attrHandles.size();attrIndex++){
            ParticleAttribute& handle=attrHandles[attrIndex];
            ParticleAccessor& accessor=accessors[attrIndex];
            // TODO: this violates strict aliasing, we could just go to char* and make
            // a different endian swapper
            int* data=accessor.raw<int>(iterator);
            for(int k=0;k<handle.count;k++){
                BIGEND::swap(buffer[attrOffsets[attrIndex]+k]);
                data[k]=buffer[attrOffsets[attrIndex]+k];
            }
        }
    }
    delete [] buffer;

    // return the populated simpleParticle
    return simple;
}
Esempio n. 3
0
File: BGEO.cpp Progetto: K240/partio
bool writeBGEO(const char* filename,const ParticlesData& p,const bool compressed)
{
    std::auto_ptr<std::ostream> output(
        compressed ? 
        Gzip_Out(filename,std::ios::out|std::ios::binary)
        :new std::ofstream(filename,std::ios::out|std::ios::binary));

    if(!*output){
        std::cerr<<"Partio Unable to open file "<<filename<<std::endl;
        return false;
    }

    int magic=((((('B'<<8)|'g')<<8)|'e')<<8)|'o';
    char versionChar='V';
    int version=5;
    int nPoints=p.numParticles();
    int nPrims=1;
    int nPointGroups=0;
    int nPrimGroups=0;
    int nPointAttrib=p.numAttributes()-1;
    int nVertexAttrib=0;
    int nPrimAttrib=1;
    int nAttrib=0;

    write<BIGEND>(*output,magic,versionChar,version,nPoints,nPrims,nPointGroups);
    write<BIGEND>(*output,nPrimGroups,nPointAttrib,nVertexAttrib,nPrimAttrib,nAttrib);

    std::vector<ParticleAttribute> handles;
    std::vector<ParticleAccessor> accessors;
    std::vector<int> attrOffsets;
    bool foundPosition=false;
    int particleSize=4;
    for(int i=0;i<p.numAttributes();i++){
        ParticleAttribute attr;
        p.attributeInfo(i,attr);
        if(attr.name=="position"){
            attrOffsets.push_back(0);
            foundPosition=true;
        }else{
            writeHoudiniStr(*output,attr.name);
            int houdiniType=0;
            switch(attr.type){
                case FLOAT: houdiniType=0;break;
                case INT: houdiniType=1;break;
                case VECTOR: houdiniType=5;break;
                case NONE: assert(false);houdiniType=0;break;
            }
            unsigned short size=attr.count;
            write<BIGEND>(*output,size,houdiniType);
            for(int i=0;i<attr.count;i++){
                int defaultValue=0;
                write<BIGEND>(*output,defaultValue);
            }
            attrOffsets.push_back(particleSize);
            particleSize+=attr.count;
        }
        handles.push_back(attr);
        accessors.push_back(ParticleAccessor(handles.back()));
    }
    if(!foundPosition){
        std::cerr<<"Partio: didn't find attr 'position' while trying to write GEO"<<std::endl;
        return false;
    }

    ParticlesData::const_iterator iterator=p.begin();
    for(size_t i=0;i<accessors.size();i++) iterator.addAccessor(accessors[i]);

    int *buffer=new int[particleSize];
    for(ParticlesData::const_iterator end=p.end();iterator!=end;++iterator){
        for(unsigned int attrIndex=0;attrIndex<handles.size();attrIndex++){
            ParticleAttribute& handle=handles[attrIndex];
            ParticleAccessor& accessor=accessors[attrIndex];
            // TODO: this violates strict aliasing, we could just go to char* and make
            // a different endian swapper
            const int* data=accessor.raw<int>(iterator);
            for(int k=0;k<handle.count;k++){
                buffer[attrOffsets[attrIndex]+k]=data[k];
                BIGEND::swap(buffer[attrOffsets[attrIndex]+k]);
            }
        }        
        // set homogeneous coordinate
        float *w=(float*)&buffer[3];
        *w=1.;
        BIGEND::swap(*w);
        output->write((char*)buffer,particleSize*sizeof(int));
    }
    delete [] buffer;

    // Write primitive attribs
    writeHoudiniStr(*output,"generator");
    write<BIGEND>(*output,(short)0x1); // count 1
    write<BIGEND>(*output,(int)0x4); // type 4 index
    write<BIGEND>(*output,(int)0x1); // type 4 index
    writeHoudiniStr(*output,"papi");

    // Write the primitive
    write<BIGEND>(*output,(int)0x8000);
    write<BIGEND>(*output,(int)nPoints);
    if(nPoints>(int)1<<16)
        for(int i=0;i<nPoints;i++) write<BIGEND>(*output,(int)i);
    else
        for(int i=0;i<nPoints;i++) write<BIGEND>(*output,(unsigned short)i);
    write<BIGEND>(*output,(int)0);

    // Write extra
    write<BIGEND>(*output,(char)0x00);
    write<BIGEND>(*output,(char)0xff);

    // success
    return true;
}