Skip to content

Commit fb3cf74

Browse files
committed
Point cloud rendering
1 parent 05c0a0a commit fb3cf74

File tree

5 files changed

+106
-15
lines changed

5 files changed

+106
-15
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ endif()
2121

2222
find_package(OpenMP COMPONENTS CXX)
2323

24-
set(SOURCES main.cpp tgaimage.cpp)
24+
set(SOURCES main.cpp model.cpp tgaimage.cpp)
2525

2626
add_executable(${PROJECT_NAME} ${SOURCES})
2727
target_link_libraries(${PROJECT_NAME} PRIVATE $<$<BOOL:${OpenMP_CXX_FOUND}>:OpenMP::OpenMP_CXX>)

geometry.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
#include <cmath>
3+
#include <cassert>
4+
#include <iostream>
5+
6+
template<int n> struct vec {
7+
double data[n] = {0};
8+
double& operator[](const int i) { assert(i>=0 && i<n); return data[i]; }
9+
double operator[](const int i) const { assert(i>=0 && i<n); return data[i]; }
10+
};
11+
12+
template<int n> std::ostream& operator<<(std::ostream& out, const vec<n>& v) {
13+
for (int i=0; i<n; i++) out << v[i] << " ";
14+
return out;
15+
}
16+
17+
template<> struct vec<3> {
18+
double x = 0, y = 0, z = 0;
19+
double& operator[](const int i) { assert(i>=0 && i<3); return i ? (1==i ? y : z) : x; }
20+
double operator[](const int i) const { assert(i>=0 && i<3); return i ? (1==i ? y : z) : x; }
21+
};
22+
23+
typedef vec<3> vec3;
24+

main.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
#include <cmath>
2+
#include <tuple>
3+
#include "geometry.h"
4+
#include "model.h"
25
#include "tgaimage.h"
36

7+
constexpr int width = 800;
8+
constexpr int height = 800;
9+
410
constexpr TGAColor white = {255, 255, 255, 255}; // attention, BGRA order
511
constexpr TGAColor green = { 0, 255, 0, 255};
612
constexpr TGAColor red = { 0, 0, 255, 255};
@@ -32,23 +38,25 @@ void line(int ax, int ay, int bx, int by, TGAImage &framebuffer, TGAColor color)
3238
}
3339
}
3440

35-
int main(int argc, char** argv) {
36-
constexpr int width = 64;
37-
constexpr int height = 64;
38-
TGAImage framebuffer(width, height, TGAImage::RGB);
41+
std::tuple<int,int> project(vec3 v) { // First of all, (x,y) is an orthogonal projection of the vector (x,y,z).
42+
return { (v.x + 1.) * width/2, // Second, since the input models are scaled to have fit in the [-1,1]^3 world coordinates,
43+
(v.y + 1.) * height/2 }; // we want to shift the vector (x,y) and then scale it to span the entire screen.
44+
}
3945

40-
int ax = 7, ay = 3;
41-
int bx = 12, by = 37;
42-
int cx = 62, cy = 53;
46+
int main(int argc, char** argv) {
47+
if (argc != 2) {
48+
std::cerr << "Usage: " << argv[0] << " obj/model.obj" << std::endl;
49+
return 1;
50+
}
4351

44-
line(ax, ay, bx, by, framebuffer, blue);
45-
line(cx, cy, bx, by, framebuffer, green);
46-
line(cx, cy, ax, ay, framebuffer, yellow);
47-
line(ax, ay, cx, cy, framebuffer, red);
52+
Model model(argv[1]);
53+
TGAImage framebuffer(width, height, TGAImage::RGB);
4854

49-
framebuffer.set(ax, ay, white);
50-
framebuffer.set(bx, by, white);
51-
framebuffer.set(cx, cy, white);
55+
for (int i=0; i<model.nverts(); i++) { // iterate through all vertices
56+
vec3 v = model.vert(i); // get i-th vertex
57+
auto [x, y] = project(v); // project it to the screen
58+
framebuffer.set(x, y, white);
59+
}
5260

5361
framebuffer.write_tga_file("framebuffer.tga");
5462
return 0;

model.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <fstream>
2+
#include <sstream>
3+
#include "model.h"
4+
5+
Model::Model(const std::string filename) {
6+
std::ifstream in;
7+
in.open(filename, std::ifstream::in);
8+
if (in.fail()) return;
9+
std::string line;
10+
while (!in.eof()) {
11+
std::getline(in, line);
12+
std::istringstream iss(line.c_str());
13+
char trash;
14+
if (!line.compare(0, 2, "v ")) {
15+
iss >> trash;
16+
vec3 v;
17+
for (int i : {0,1,2}) iss >> v[i];
18+
verts.push_back(v);
19+
} else if (!line.compare(0, 2, "f ")) {
20+
int f,t,n, cnt = 0;
21+
iss >> trash;
22+
while (iss >> f >> trash >> t >> trash >> n) {
23+
facet_vrt.push_back(--f);
24+
cnt++;
25+
}
26+
if (3!=cnt) {
27+
std::cerr << "Error: the obj file is supposed to be triangulated" << std::endl;
28+
return;
29+
}
30+
}
31+
}
32+
std::cerr << "# v# " << nverts() << " f# " << nfaces() << std::endl;
33+
}
34+
35+
int Model::nverts() const { return verts.size(); }
36+
int Model::nfaces() const { return facet_vrt.size()/3; }
37+
38+
vec3 Model::vert(const int i) const {
39+
return verts[i];
40+
}
41+
42+
vec3 Model::vert(const int iface, const int nthvert) const {
43+
return verts[facet_vrt[iface*3+nthvert]];
44+
}
45+

model.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <vector>
2+
#include "geometry.h"
3+
4+
class Model {
5+
std::vector<vec3> verts = {}; // array of vertices
6+
std::vector<int> facet_vrt = {}; // per-triangle index in the above array
7+
public:
8+
Model(const std::string filename);
9+
int nverts() const; // number of vertices
10+
int nfaces() const; // number of triangles
11+
vec3 vert(const int i) const; // 0 <= i < nverts()
12+
vec3 vert(const int iface, const int nthvert) const; // 0 <= iface <= nfaces(), 0 <= nthvert < 3
13+
};
14+

0 commit comments

Comments
 (0)