-
Notifications
You must be signed in to change notification settings - Fork 84
/
Copy pathhcloud.cpp
110 lines (103 loc) · 3.82 KB
/
hcloud.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2015, Christopher J. Foster and the other displaz contributors.
// Use of this code is governed by the BSD-style license found in LICENSE.txt
#include "hcloud.h"
#include <sstream>
#include <stdexcept>
#include "tinyformat.h"
#include "util.h"
void HCloudHeader::write(std::ostream& out) const
{
// Construct header in memory buffer so we can easily get the size and seek
// as required.
std::stringstream headerBytes;
headerBytes.write(HCLOUD_MAGIC, HCLOUD_MAGIC_SIZE);
writeLE<uint16_t>(headerBytes, version);
std::streampos headerSizePos = headerBytes.tellp();
writeLE<uint32_t>(headerBytes, headerSize);
writeLE<uint64_t>(headerBytes, numPoints);
writeLE<uint64_t>(headerBytes, numVoxels);
writeLE<uint64_t>(headerBytes, indexOffset);
writeLE<uint64_t>(headerBytes, dataOffset);
writeLE<double>(headerBytes, offset.x);
writeLE<double>(headerBytes, offset.y);
writeLE<double>(headerBytes, offset.z);
writeLE<double>(headerBytes, boundingBox.min.x);
writeLE<double>(headerBytes, boundingBox.min.y);
writeLE<double>(headerBytes, boundingBox.min.z);
writeLE<double>(headerBytes, boundingBox.max.x);
writeLE<double>(headerBytes, boundingBox.max.y);
writeLE<double>(headerBytes, boundingBox.max.z);
writeLE<double>(headerBytes, treeBoundingBox.min.x);
writeLE<double>(headerBytes, treeBoundingBox.min.y);
writeLE<double>(headerBytes, treeBoundingBox.min.z);
writeLE<double>(headerBytes, treeBoundingBox.max.x);
writeLE<double>(headerBytes, treeBoundingBox.max.y);
writeLE<double>(headerBytes, treeBoundingBox.max.z);
writeLE<uint16_t>(headerBytes, brickSize);
headerSize = (uint32_t)headerBytes.tellp();
headerBytes.seekp(headerSizePos);
writeLE<uint32_t>(headerBytes, headerSize);
out << headerBytes.rdbuf();
}
void HCloudHeader::read(std::istream& in)
{
char magic[HCLOUD_MAGIC_SIZE] = {0};
in.read(magic, HCLOUD_MAGIC_SIZE);
if (in.gcount() != HCLOUD_MAGIC_SIZE ||
memcmp(magic, HCLOUD_MAGIC, HCLOUD_MAGIC_SIZE) != 0)
{
throw DisplazError("Bad magic number: not a hierarchical point cloud");
}
version = readLE<uint16_t>(in);
if (version != HCLOUD_VERSION)
throw DisplazError("Unknown hcloud version: %d", version);
headerSize = readLE<uint32_t>(in);
numPoints = readLE<uint64_t>(in);
numVoxels = readLE<uint64_t>(in);
indexOffset = readLE<uint64_t>(in);
dataOffset = readLE<uint64_t>(in);
offset.x = readLE<double>(in);
offset.y = readLE<double>(in);
offset.z = readLE<double>(in);
boundingBox.min.x = readLE<double>(in);
boundingBox.min.y = readLE<double>(in);
boundingBox.min.z = readLE<double>(in);
boundingBox.max.x = readLE<double>(in);
boundingBox.max.y = readLE<double>(in);
boundingBox.max.z = readLE<double>(in);
treeBoundingBox.min.x = readLE<double>(in);
treeBoundingBox.min.y = readLE<double>(in);
treeBoundingBox.min.z = readLE<double>(in);
treeBoundingBox.max.x = readLE<double>(in);
treeBoundingBox.max.y = readLE<double>(in);
treeBoundingBox.max.z = readLE<double>(in);
brickSize = readLE<uint16_t>(in);
}
std::ostream& operator<<(std::ostream& out, const HCloudHeader& h)
{
tfm::format(out,
"version = %d\n"
"headerSize = %d\n"
"numPoints = %d\n"
"numVoxels = %d\n"
"indexOffset = %d\n"
"dataOffset = %d\n"
"offset = %.3f\n"
"boundingBox = [%.3f -- %.3f]\n"
"treeBoundingBox = [%.3f -- %.3f]\n"
"brickSize = %d",
h.version,
h.headerSize,
h.numPoints,
h.numVoxels,
h.indexOffset,
h.dataOffset,
h.offset,
h.boundingBox.min,
h.boundingBox.max,
h.treeBoundingBox.min,
h.treeBoundingBox.max,
h.brickSize
);
return out;
}