Exemple #1
0
ParticlesDataMutable* readGEO(const char* filename,const bool headersOnly,char** attributes, int percentage)
{
    auto_ptr<istream> input(Gzip_In(filename,ios::in));
    if(!*input){
        cerr<<"Partio: Can't open particle data file: "<<filename<<endl;
        return 0;
    }
    int NPoints=0, NPointAttrib=0;

    ParticlesDataMutable* simple=0;
    if(headersOnly) simple=new ParticleHeaders;
    else simple=create();

    // read NPoints and NPointAttrib
    string word;
    while(input->good()){
        *input>>word;
        if(word=="NPoints") *input>>NPoints;
        else if(word=="NPointAttrib"){*input>>NPointAttrib;break;}
Exemple #2
0
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;
}
Exemple #3
0
ParticlesDataMutable* readPTC(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;
    }

    int magic;
    read<LITEND>(*input,magic);
    if(ptc_magic!=magic){
        std::cerr<<"Partio: Magic number '"<<magic<<"' of '"<<filename<<"' doesn't match pptc magic '"<<ptc_magic<<"'"<<std::endl;
        return 0;
    }

    int version;
    read<LITEND>(*input,version);

    double nPoints;
    read<LITEND>(*input,nPoints);

    // TODO: allow access to this in the headers only mode for times when only bbox is necessary
    float xmin,ymin,zmin,xmax,ymax,zmax;
    read<LITEND>(*input,xmin,ymin,zmin,xmax,ymax,zmax);

    float dummy;
    if (version>=1) for (int d=0;d<4;d++) read<LITEND>(*input,dummy);

    // world-to-eye
    for(int i=0;i<16;i++) read<LITEND>(*input,dummy);
    // eye-to-screen
    for(int i=0;i<16;i++) read<LITEND>(*input,dummy);

    float imgWidth,imgHeight,imgDepth;
    read<LITEND>(*input,imgWidth,imgHeight,imgDepth);

    int nVars,dataSize;
    read<LITEND>(*input,nVars,dataSize);

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

    // PTC files always have something for these items, so allocate the data
    std::vector<ParticleAttribute> attrHandles;
    ParticleAttribute positionHandle=simple->addAttribute("position",VECTOR,3);
    ParticleAttribute normalHandle=simple->addAttribute("normal",VECTOR,3);
    ParticleAttribute radiusHandle=simple->addAttribute("radius",FLOAT,1);
    std::string typeName,name;

    // data types are "float", "point", "vector", "normal", "color", or "matrix"
    int parsedSize=0;
    for(int chanNum=0;chanNum<nVars;chanNum++){
        ParseSpec(GetString(*input,'\n'),typeName,name);

        int dataSize=0;
        ParticleAttributeType dataType;
        if(typeName=="color" || typeName=="vector" || typeName=="point" || typeName=="color"){
            dataType=VECTOR;
            dataSize=3;
        }else if(typeName=="matrix"){
            dataType=FLOAT;
            dataSize=16;
        }else if(typeName=="float"){
            dataType=FLOAT;
            dataSize=1;
        }else{
            std::cerr<<"Partio: "<<filename<<" had unknown attribute spec "<<typeName<<" "<<name<<std::endl;
            simple->release();
            return 0;
        }

        attrHandles.push_back(simple->addAttribute(name.c_str(),dataType,dataSize));
        parsedSize+=dataSize;
    }
    if(dataSize!=parsedSize){
        std::cerr<<"Partio: error with PTC, computed dataSize ("<<dataSize
                 <<") different from read one ("<<parsedSize<<")"<<std::endl;
        simple->release();
        return 0;
    }

    // If all we care about is headers, then return.  
    if(headersOnly){
        return simple;
    }

    // more weird input attributes
    if(version>=1) for(int i=0;i<2;i++) read<LITEND>(*input,dummy);

    for(int pointIndex=0;pointIndex<nPoints;pointIndex++){
        float* pos=simple->dataWrite<float>(positionHandle,pointIndex);
        read<LITEND>(*input,pos[0],pos[1],pos[2]);

        unsigned short phi,z; // normal encoded
        read<LITEND>(*input,phi,z);
        float* norm=simple->dataWrite<float>(normalHandle,pointIndex);

	// Convert unsigned short (phi,nz) to xyz normal
        // This packing code is based on Per Christensen's rman forum post
	if (phi != 65535 || z != 65535) {
	     float nz = (float)z / 65535.0f;
	     norm[2] = 2.0f * nz - 1.0f;
	     float fphi = (float)phi / 65535.0f;
	     fphi = 2.0 * M_PI * (fphi - 0.5);
	     //assert(-M_PI-0.0001 <= fphi && fphi <= M_PI+0.0001);
	     double rxy = sqrt(1.0 - norm[2]*norm[2]);
	     norm[0] = rxy * sin(fphi);
	     norm[1] = rxy * cos(fphi);
	} else {
	     norm[0] = norm[1] = norm[2] = 0.0f;
	}        

        float* radius=simple->dataWrite<float>(radiusHandle,pointIndex);
        read<LITEND>(*input,radius[0]);


        for(unsigned int i=0;i<attrHandles.size();i++){
            float* data=simple->dataWrite<float>(attrHandles[i],pointIndex);
            for(int j=0;j<attrHandles[i].count;j++)
                read<LITEND>(*input,data[j]);
        }

    }

    return simple;
}