Loading...
Searching...
No Matches
element.tpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#ifndef __BITPIT_ELEMENT_TPP__
26#define __BITPIT_ELEMENT_TPP__
27
28namespace bitpit {
29
48template<class DerivedElement>
49ElementHalfItem<DerivedElement>::ElementHalfItem(DerivedElement &element, ConstProxyVector<long> &&vertexIds, Winding winding)
50 : m_element(element), m_vertexIds(std::move(vertexIds)), m_winding(winding)
51{
52 // Find the vertex with the lowest id, this will be used as first vertex
53 // when iterating over the ids.
54 std::size_t nVertices = m_vertexIds.size();
55
56 m_firstVertexId = 0;
57 if (nVertices > 0) {
58 long smallestVertexId = m_vertexIds[m_firstVertexId];
59 for (std::size_t i = 1; i < nVertices; ++i) {
60 long vertexId = m_vertexIds[i];
61 if (vertexId < smallestVertexId) {
62 m_firstVertexId = i;
63 smallestVertexId = vertexId;
64 }
65 }
66 }
67}
68
74template<class DerivedElement>
76{
77 return m_element;
78}
79
85template<class DerivedElement>
87{
88 return m_vertexIds;
89}
90
96template<class DerivedElement>
97typename ElementHalfItem<DerivedElement>::Winding ElementHalfItem<DerivedElement>::getWinding() const
98{
99 return m_winding;
100}
101
107template<class DerivedElement>
109{
110 m_winding = winding;
111}
112
120template<class DerivedElement>
122{
123 const bitpit::ConstProxyVector<long> &vertexIds_1 = m_vertexIds;
124 const bitpit::ConstProxyVector<long> &vertexIds_2 = other.m_vertexIds;
125
126 std::size_t nVertices = vertexIds_1.size();
127 if (nVertices != vertexIds_2.size()) {
128 return false;
129 }
130
131 int winding = m_winding * other.m_winding;
132 std::size_t offset = other.m_firstVertexId - winding * m_firstVertexId + 2 * nVertices;
133 for (std::size_t i = 0; i < nVertices; ++i) {
134 std::size_t k1 = i;
135 std::size_t k2 = (offset + winding * i) % nVertices;
136 if (vertexIds_1[k1] != vertexIds_2[k2]) {
137 return false;
138 }
139 }
140
141 return true;
142}
143
151template<class DerivedElement>
153{
154 return !((*this) == other);
155}
156
171template<class DerivedElement>
173{
174 const ConstProxyVector<long> &vertexIds = item.m_vertexIds;
175 std::size_t nVertices = vertexIds.size();
176
177 std::size_t hash = nVertices;
178 if (item.m_winding == ElementHalfItem::WINDING_NATURAL) {
179 for (std::size_t i = 0; i < nVertices; ++i) {
180 std::size_t k = (item.m_firstVertexId + i) % nVertices;
181 utils::hashing::hash_combine(hash, vertexIds[k]);
182 }
183 } else {
184 // Reversing the winding of pixel elements needs special handling. In
185 // pixel elements, vertices are ordered using the Z-order, whereas in
186 // all other elements vertices are ordered counter-clockwise.
187 if (item.m_element.getType() != ElementType::PIXEL) {
188 for (std::size_t i = nVertices; i > 0; --i) {
189 std::size_t k = (item.m_firstVertexId + i) % nVertices;
190 utils::hashing::hash_combine(hash, vertexIds[k]);
191 }
192 } else {
193 utils::hashing::hash_combine(hash, vertexIds[(item.m_firstVertexId + 1) % nVertices]);
194 utils::hashing::hash_combine(hash, vertexIds[(item.m_firstVertexId + 0) % nVertices]);
195 utils::hashing::hash_combine(hash, vertexIds[(item.m_firstVertexId + 3) % nVertices]);
196 utils::hashing::hash_combine(hash, vertexIds[(item.m_firstVertexId + 2) % nVertices]);
197 }
198 }
199
200 return hash;
201}
202
219template<class DerivedElement>
220ElementHalfEdge<DerivedElement>::ElementHalfEdge(DerivedElement &element, int edge, Winding winding)
221 : ElementHalfItem<DerivedElement>(element, element.getEdgeVertexIds(edge), winding),
222 m_edge(edge)
223{
224}
225
231template<class DerivedElement>
233{
234 return m_edge;
235}
256template<class DerivedElement>
257ElementHalfFace<DerivedElement>::ElementHalfFace(DerivedElement &element, int face, Winding winding)
258 : ElementHalfItem<DerivedElement>(element, element.getFaceVertexIds(face), winding),
259 m_face(face)
260{
261}
268template<class DerivedElement>
270{
271 return m_face;
272}
273
274}
275
276#endif
ElementHalfEdge(DerivedElement &element, int edge, Winding winding)
Definition element.tpp:220
ElementHalfFace(DerivedElement &element, int face, Winding winding)
Definition element.tpp:257
The ElementHalfItem class is the base calss for defining element half-edge and half-faces.
Definition element.hpp:222
bool operator!=(const ElementHalfItem &other) const
Definition element.tpp:152
ElementHalfItem(DerivedElement &element, ConstProxyVector< long > &&vertexIds, ElementHalfItem< DerivedElement >::Winding winding)
Definition element.tpp:49
const ConstProxyVector< long > & getVertexIds() const
Definition element.tpp:86
DerivedElement & getElement() const
Definition element.tpp:75
bool operator==(const ElementHalfItem &other) const
Definition element.tpp:121
void setWinding(Winding winding)
Definition element.tpp:108
Winding getWinding() const
Definition element.tpp:97
Metafunction for generating a list of elements that can be either stored in an external vectror or,...
std::size_t size() const
std::size_t operator()(const ElementHalfItem &item) const
Definition element.tpp:172
--- layout: doxygen_footer ---