XYZPointReader(string file, string format, vector<double> colorRange, vector<double> intensityRange)
	: stream(file, std::ios::in | std::ios::binary)
	{
		this->format = format;
		pointsRead = 0;
		linesSkipped = 0;
		pointCount = 0;
		colorScale = -1;

		if(intensityRange.size() == 2){
			intensityOffset = (float)intensityRange[0];
			intensityScale = (float)intensityRange[1]-(float)intensityRange[0];
		}else if(intensityRange.size() == 1){
			intensityOffset = 0.0f;
			intensityScale = (float)intensityRange[0];
		}else{
			intensityOffset = 0.0f;
			intensityScale = 1.0f;
		}

		if(colorRange.size() == 2){
			colorOffset = (float)colorRange[0];
			colorScale = (float)colorRange[1];
		}else if(colorRange.size() == 1){
			colorOffset = 0.0f;
			colorScale = (float)colorRange[0];
		}else if(colorRange.size() == 0){
			colorOffset = 0.0f;

			// try to find color range by evaluating the first x points.
			float max = 0;
			int j = 0; 
			string line;
			while(getline(stream, line) && j < 1000){
				trim(line);
				vector<string> tokens = split(line, { '\t', ' ', ',' });

				if(this->format == "" && tokens.size() >= 3){
					string f(tokens.size(), 's');
					f.replace(0, 3, "xyz");

					if(tokens.size() >= 6){
						f.replace(tokens.size() - 3, 3, "rgb");
					}

					this->format = f;
					cout << "using format: '" << this->format << "'" << endl;
				}

				if(tokens.size() < this->format.size()){
					continue;
				}

				int i = 0;
				for(const auto &f : format) {
					string token = tokens[i++];
					if(f == 'r'){
						max = std::max(max, stof(token));
					}else if(f == 'g'){
						max = std::max(max, stof(token));
					}else if(f == 'b'){
						max = std::max(max, stof(token));
					}
				}

				

				j++;
			}

			if(max <= 1.0f){
				colorScale = 1.0f;
			} else if(max <= 255){
				colorScale = 255.0f;
			}else if(max <= pow(2, 16) - 1){
				colorScale =(float)pow(2, 16) - 1;
			}else{
				colorScale = (float)max;
			}

			stream.clear();
			stream.seekg(0, stream.beg);

		}

		// read through once to calculate aabb and number of points
		while(readNextPoint()){
			Point p = getPoint();
			aabb.update(p.position);
			pointCount++;
		}
		stream.clear();
		stream.seekg(0, stream.beg);
	}
Example #2
0
int main(int argc, char* argv[])
{
    if (argc < 3) {
        return 1;
    }

    std::string inFile(argv[1]);
    std::string outFile(argv[2]);

    auto reader = (Potree::LASPointReader*)Proxy::createPointReader(inFile);

    if (!reader) {
        // TODO
        return 1;
    }

    auto aabb = reader->getAABB();

    aabb.size = aabb.max - aabb.min;

    aabb.makeCubic();

    uint64_t pointNum = 0;
    uint64_t flushNum = 0;

    FILE* fp = nullptr;
    fopen_s(&fp, outFile.c_str(), "wb");

    fseek(fp, sizeof(TMPHeader), SEEK_SET);

    std::vector<Point> points;
    points.reserve(reader->numPoints());

    static const uint32_t FLUSH_NUM = 10000;

    while (reader->readNextPoint()) {
        auto point = reader->getPoint();

        pointNum++;
        flushNum++;

        Point pt;

        pt.pos[0] = point.position.x;
        pt.pos[1] = point.position.y;
        pt.pos[2] = point.position.z;

        pt.rgba[0] = point.color.x;
        pt.rgba[1] = point.color.y;
        pt.rgba[2] = point.color.z;
        pt.rgba[3] = 0xff;

        points.push_back(pt);

        if (flushNum == FLUSH_NUM) {
            printf("%d\n", pointNum);
            fwrite(&points[0], sizeof(Point), flushNum, fp);
            points.clear();
            flushNum = 0;
        }
    }

    if (flushNum > 0) {
        printf("%d\n", pointNum);
        fwrite(&points[0], sizeof(Point), flushNum, fp);
        points.clear();
        flushNum = 0;
    }

    // Write header.
    {
        TMPHeader header;
        header.fileSize = ftell(fp);
        header.vtxFormat = VtxFormat::Position | VtxFormat::Color;
        header.vtxNum = pointNum;
        
        auto& aabbMin = aabb.min;
        auto& aabbMax = aabb.max;

        header.aabbMin[0] = aabbMin.x;
        header.aabbMin[1] = aabbMin.y;
        header.aabbMin[2] = aabbMin.z;

        header.aabbMax[0] = aabbMax.x;
        header.aabbMax[1] = aabbMax.y;
        header.aabbMax[2] = aabbMax.z;

        fseek(fp, 0, SEEK_SET);
        fwrite(&header, sizeof(header), 1, fp);
    }

    fclose(fp);

	return 0;
}