BINPointWriter(string file, AABB aabb, double scale) {
		this->file = file;
		this->aabb = aabb;
		this->scale = scale;
		numPoints = 0;
		attributes.add(PointAttribute::POSITION_CARTESIAN);
		attributes.add(PointAttribute::COLOR_PACKED);

		writer = new ofstream(file, ios::out | ios::binary);
	}
AttributeSubject *
ThreeSliceAttributes::CreateCompatible(const std::string &tname) const
{
    AttributeSubject *retval = 0;
    if(TypeName() == tname)
        retval = new ThreeSliceAttributes(*this);
    if(tname == "PointAttributes" && interactive)
    {
        PointAttributes *p = new PointAttributes;
        double pt[3];
        pt[0] = GetX();
        pt[1] = GetY();
        pt[2] = GetZ();
        p->SetPoint(pt);    
        retval = p;
    }

    return retval;
}
void
avtPointToolInterface::SetPoint(double x, double y, double z)
{
    PointAttributes *p = (PointAttributes *)atts;
    double d[3] = {x, y, z};
    if (const_cast<VisWindow*>(visWindow)->GetFullFrameMode())
    {
        //
        // If in full-frame mode, the point was computed in the scaled 
        // full-frame space.  Reverse the scaling to get the correct point. 
        //
        double scale;
        int type;
        const_cast<VisWindow*>(visWindow)->GetScaleFactorAndType(scale, type);
        if ( type == 0 && scale > 0.)
            d[0] /= scale;
        else if ( type == 1 && scale > 0.)
            d[1] /= scale;
    }
    p->SetPoint(d);
}
	void write(const Point &point){
		for(int i = 0; i < attributes.size(); i++){
			PointAttribute attribute = attributes[i];
			if(attribute == PointAttribute::POSITION_CARTESIAN){
				//float pos[3] = {(float) point.x,(float)  point.y,(float)  point.z};
				int x = (point.x - aabb.min.x) / scale;
				int y = (point.y - aabb.min.y) / scale;
				int z = (point.z - aabb.min.z) / scale;
				int pos[3] = {x, y, z};
				writer->write((const char*)pos, 3*sizeof(int));
			}else if(attribute == PointAttribute::COLOR_PACKED){
				unsigned char rgba[4] = {point.r, point.g, point.b, 255};
				writer->write((const char*)rgba, 4*sizeof(unsigned char));
			}
		}

		numPoints++;
	}
	void write(const Point &point){
		for(int i = 0; i < attributes.size(); i++){
			PointAttribute attribute = attributes[i];
			if(attribute == PointAttribute::POSITION_CARTESIAN){
				//float pos[3] = {(float) point.x,(float)  point.y,(float)  point.z};
				int x = (int)((point.position.x - aabb.min.x) / scale);
				int y = (int)((point.position.y - aabb.min.y) / scale);
				int z = (int)((point.position.z - aabb.min.z) / scale);
				int pos[3] = {x, y, z};
				writer->write((const char*)pos, 3*sizeof(int));
			}else if(attribute == PointAttribute::COLOR_PACKED){
				unsigned char rgba[4] = {point.color.x, point.color.y, point.color.z, 255};
				writer->write((const char*)rgba, 4*sizeof(unsigned char));
			}else if(attribute == PointAttribute::INTENSITY){
				writer->write((const char*)&point.intensity, sizeof(unsigned short));
			}else if(attribute == PointAttribute::CLASSIFICATION){
				writer->write((const char*)&point.classification, sizeof(unsigned char));
			}else if(attribute == PointAttribute::NORMAL_SPHEREMAPPED){
				// see http://aras-p.info/texts/CompactNormalStorage.html
				float nx = point.normal.x;
				float ny = point.normal.y;
				float nz = point.normal.z;
				float lengthxy = sqrt(nx * nx + ny * ny);

				float ex = 0.5f * (nx / lengthxy) * sqrt(-nz * 0.5f + 0.5f) + 0.5f;
				float ey = 0.5f * (ny / lengthxy) * sqrt(-nz * 0.5f + 0.5f) + 0.5f;

				unsigned char bx = (unsigned char)(ex * 255);
				unsigned char by = (unsigned char)(ey * 255);

				writer->write((const char*)&bx, 1);
				writer->write((const char*)&by, 1);
			}else if(attribute == PointAttribute::NORMAL_OCT16){
				// see http://lgdv.cs.fau.de/get/1602

				float nx = point.normal.x;
				float ny = point.normal.y;
				float nz = point.normal.z;
				
				float norm1 = abs(nx) + abs(ny) + abs(nz);

				nx = nx / norm1;
				ny = ny / norm1;
				nz = nz / norm1;

				float u = 0;
				float v = 0;

				if(nz >= 0){
					u = nx;
					v = ny;
				}else{
					u = psign(nx)*(1-psign(ny)*ny);
					v = psign(ny)*(1-psign(nx)*nx);
				}

				unsigned char bx = (unsigned char)(min((u + 1) * 128, 255.0f));
				unsigned char by = (unsigned char)(min((v + 1) * 128, 255.0f));

				writer->write((const char*)&bx, 1);
				writer->write((const char*)&by, 1);
			}else if(attribute == PointAttribute::NORMAL){
				writer->write((const char*)&point.normal.x, sizeof(float));
				writer->write((const char*)&point.normal.y, sizeof(float));
				writer->write((const char*)&point.normal.z, sizeof(float));
			}
		}

		numPoints++;
	}
const double *
avtPointToolInterface::GetPoint() const
{
    PointAttributes *p = (PointAttributes *)atts;
    return p->GetPoint();
}