Wed, 29 Jun 2022 16:33:49 +0300
Fixed ModelId being used to identify both models and elements, added ElementId to identify elements
264
76a025db4948
Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
259
diff
changeset
|
1 | #include "src/vertexmap.h" |
76a025db4948
Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
259
diff
changeset
|
2 | #include "src/gl/common.h" |
117 | 3 | |
259
c27612f0eac0
- Made it build under Qt6
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
250
diff
changeset
|
4 | hash_t hashVertex(const glm::vec3& vec) |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
5 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
6 | return qHash(glm::ivec3{ |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
7 | int(vec.x * 10000), |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
8 | int(vec.y * 10000), |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
9 | int(vec.z * 10000), |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
10 | }); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
11 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
12 | |
117 | 13 | VertexMap::VertexMap(const Model *model) : |
14 | model{model} | |
15 | { | |
16 | connect( | |
17 | model, | |
18 | &Model::dataChanged, | |
19 | this, | |
20 | &VertexMap::build | |
21 | ); | |
22 | connect( | |
23 | model, | |
24 | &Model::rowsInserted, | |
25 | this, | |
26 | &VertexMap::build | |
27 | ); | |
28 | connect( | |
29 | model, | |
30 | &Model::rowsRemoved, | |
31 | this, | |
32 | &VertexMap::build | |
33 | ); | |
34 | this->build(); | |
35 | } | |
36 | ||
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
37 | struct Edge |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
38 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
39 | const glm::vec3& a; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
40 | const glm::vec3& b; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
41 | }; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
42 | |
200 | 43 | inline void edges(const ModelElement& element, std::function<void(Edge&&)> fn) |
44 | { | |
45 | std::visit<void>(overloaded{ | |
46 | [fn](const Colored<LineSegment>& edge) { | |
47 | fn(Edge{edge.p1, edge.p2}); | |
48 | }, | |
49 | [fn](const Colored<Triangle>& triangle) { | |
50 | fn(Edge{triangle.p1, triangle.p2}); | |
51 | fn(Edge{triangle.p2, triangle.p3}); | |
52 | fn(Edge{triangle.p3, triangle.p1}); | |
53 | }, | |
54 | [fn](const Colored<Quadrilateral>& quad) { | |
55 | fn(Edge{quad.p1, quad.p2}); | |
56 | fn(Edge{quad.p2, quad.p3}); | |
57 | fn(Edge{quad.p3, quad.p4}); | |
58 | fn(Edge{quad.p4, quad.p1}); | |
59 | }, | |
60 | [fn](const Colored<ConditionalEdge>& cedge) { | |
61 | fn(Edge{cedge.p1, cedge.p2}); | |
62 | }, | |
63 | [](const ModelElement&&){} | |
64 | }, element); | |
65 | } | |
66 | ||
67 | inline void points( | |
68 | const ModelElement& element, | |
69 | std::function<void(const glm::vec3&)> fn) | |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
70 | { |
200 | 71 | std::visit<void>(overloaded{ |
72 | [fn](const Colored<LineSegment>& edge) { | |
73 | fn(edge.p1); | |
74 | fn(edge.p2); | |
75 | }, | |
76 | [fn](const Colored<Triangle>& triangle) { | |
77 | fn(triangle.p1); | |
78 | fn(triangle.p2); | |
79 | fn(triangle.p3); | |
80 | }, | |
81 | [fn](const Colored<Quadrilateral>& quad) { | |
82 | fn(quad.p1); | |
83 | fn(quad.p2); | |
84 | fn(quad.p3); | |
85 | fn(quad.p4); | |
86 | }, | |
87 | [fn](const Colored<ConditionalEdge>& cedge) { | |
88 | fn(cedge.p1); | |
89 | fn(cedge.p2); | |
90 | fn(cedge.c1); | |
91 | fn(cedge.c2); | |
92 | }, | |
93 | [](const ModelElement&&){} | |
94 | }, element); | |
95 | } | |
96 | ||
97 | template<typename R> | |
98 | auto ifplanar( | |
99 | const ModelElement& element, | |
100 | std::function<R(const glm::vec3&, const glm::vec3&, const glm::vec3&)> fn | |
101 | ) | |
102 | { | |
103 | return std::visit(overloaded{ | |
104 | [fn](const Triangle& triangle) -> std::optional<R> { | |
105 | return fn(triangle.p1, triangle.p2, triangle.p3); | |
106 | }, | |
107 | [fn](const Quadrilateral quad) -> std::optional<R> { | |
108 | return fn(quad.p1, quad.p2, quad.p3); | |
109 | }, | |
110 | [](const ModelElement&&) -> std::optional<R> {return {};} | |
111 | }, element); | |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
112 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
113 | |
117 | 114 | void VertexMap::build() |
115 | { | |
116 | this->map.clear(); | |
118 | 117 | this->vertices.clear(); |
119 | 118 | this->vertexHashes.clear(); |
250
2837b549e616
I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
200
diff
changeset
|
119 | for (std::size_t i = 0; i < this->model->size(); ++i) |
117 | 120 | { |
200 | 121 | const ModelElement& element = this->model->at(i); |
122 | std::optional<glm::mat4> matrix = ifplanar<glm::mat4>( | |
123 | element, | |
124 | [](const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3) | |
125 | { | |
126 | const glm::vec3 a = glm::normalize(p2 - p1); | |
127 | const glm::vec3 b = glm::normalize(p3 - p1); | |
128 | const glm::vec3 c = glm::normalize(glm::cross(a, b)); | |
129 | const glm::vec3 d = glm::normalize(glm::cross(a, c)); | |
130 | return glm::mat4{{a, 0}, {-c, 0}, {d, 0}, {}}; | |
131 | }); | |
132 | points(element, [&](const glm::vec3 point) { | |
259
c27612f0eac0
- Made it build under Qt6
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
250
diff
changeset
|
133 | const hash_t hash = hashVertex(point); |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
134 | VertexInfo& info = this->map[hash]; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
135 | info.point = point; |
200 | 136 | info.objects.insert(this->model->idAt(i)); |
137 | if (matrix.has_value() and not info.transformSet) | |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
138 | { |
200 | 139 | info.transform = matrix.value(); |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
140 | info.transform[3] = {point, 1}; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
141 | info.transformSet = true; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
142 | } |
119 | 143 | if (not this->vertexHashes.contains(hash)) |
144 | { | |
145 | this->vertexHashes.insert(hash); | |
146 | this->vertices.push_back(point); | |
147 | } | |
200 | 148 | }); |
149 | } | |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
150 | for (auto& pair : this->map) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
151 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
152 | auto& info = pair.second; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
153 | // If there's no transformation calculated yet, make up a simple one that at least |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
154 | // contains translation. |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
155 | if (not info.transformSet) |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
156 | { |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
157 | info.transform = glm::translate(glm::identity<glm::mat4>(), info.point); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
158 | info.transformSet = true; |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
159 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
160 | float scale = 1.0f; |
309
d862721d19a3
Fixed ModelId being used to identify both models and elements, added ElementId to identify elements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
264
diff
changeset
|
161 | for (const ElementId objectId : info.objects) |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
162 | { |
200 | 163 | const std::optional<int> index = model->find(objectId); |
164 | if (index.has_value()) { | |
250
2837b549e616
I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents:
200
diff
changeset
|
165 | edges(this->model->at(unsigned_cast(index.value())), [&](Edge&& edge) |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
166 | { |
200 | 167 | if (hashVertex(edge.a) == pair.first or hashVertex(edge.b) == pair.first) |
168 | { | |
169 | scale = std::min(scale, glm::length(edge.b - edge.a) / 3); | |
170 | } | |
171 | }); | |
172 | } | |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
173 | } |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
174 | info.transform = glm::scale(info.transform, glm::vec3{scale, scale, scale}); |
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
175 | } |
118 | 176 | Q_EMIT this->verticesChanged(); |
117 | 177 | } |
118 | 178 | |
179 | /** | |
180 | * @brief Apply \c fn for all vertices in the map. | |
181 | * @param fn | |
182 | */ | |
183 | void VertexMap::apply(ApplyFunction fn) const | |
184 | { | |
119 | 185 | for (unsigned int i = 0; i < this->vertices.size(); i += 1) |
118 | 186 | { |
119 | 187 | const glm::vec3& point = this->vertices[i]; |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
188 | fn(point, this->map.at(hashVertex(point))); |
118 | 189 | } |
190 | } |