Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

1035287 views
1
//
2
// face.cpp
3
// Bistellar
4
//
5
// Created by Alexander Thumm on 07.10.11.
6
// Copyright 2011 -. All rights reserved.
7
//
8
9
#include "face.h"
10
#include <iostream>
11
#include <vector>
12
#include <string.h>
13
#include <stdlib.h>
14
#include "util.h"
15
16
17
Face::Face() : _vertices(0), _dimension(-1)
18
{
19
20
}
21
22
Face::Face(const vertex_t * vertices, int dimension) : _vertices(0), _dimension(dimension)
23
{
24
if (_dimension < 0)
25
{
26
_dimension = -1;
27
}
28
else
29
{
30
_vertices = new vertex_t[dimension+1];
31
memcpy(_vertices, vertices, (dimension+1)*sizeof(vertex_t));
32
qsort(_vertices, dimension+1, sizeof(vertex_t), vertex_t_compare);
33
}
34
}
35
36
Face::Face(const Face & cpy) : _vertices(0), _dimension(cpy._dimension)
37
{
38
if (cpy._vertices != 0)
39
{
40
_vertices = new vertex_t[cpy._dimension+1];
41
memcpy(_vertices, cpy._vertices, (cpy._dimension+1)*sizeof(vertex_t));
42
}
43
}
44
45
Face::~Face()
46
{
47
if (_vertices != 0)
48
{
49
delete[] _vertices;
50
}
51
}
52
53
Face & Face::operator=(const Face & cpy)
54
{
55
if (this == &cpy)
56
return *this;
57
58
if (_vertices != 0)
59
{
60
delete[] _vertices;
61
_vertices = 0;
62
}
63
if (cpy._vertices != 0)
64
{
65
_vertices = new vertex_t[cpy._dimension+1];
66
memcpy(_vertices, cpy._vertices, (cpy._dimension+1)*sizeof(vertex_t));
67
}
68
69
_dimension = cpy._dimension;
70
71
return *this;
72
}
73
74
bool Face::operator==(const Face & cmp) const
75
{
76
if (cmp._dimension != _dimension)
77
return false;
78
79
if (_vertices == 0 && cmp._vertices == 0)
80
return true;
81
if (_vertices == 0 || cmp._vertices == 0)
82
return false;
83
84
for (int i = 0; i < _dimension+1; i++)
85
{
86
if (vertex_t_compare(&cmp._vertices[i], &_vertices[i]) != 0)
87
return false;
88
}
89
90
return true;
91
}
92
93
bool Face::operator!=(const Face & cmp) const
94
{
95
return !(*this == cmp);
96
}
97
98
int Face::dimension() const
99
{
100
return _dimension;
101
}
102
103
const vertex_t & Face::vertex(unsigned int i) const
104
{
105
return _vertices[i];
106
}
107
108
Face * Face::createBoundaryFace( unsigned int i ) const
109
{
110
if (i > _dimension || _vertices == 0)
111
return 0;
112
113
if (_dimension == 0)
114
std::cout << "ERROR: tried to create boundary of a vertex." << std::endl;
115
116
Face * boundaryFace = new Face;
117
boundaryFace->_dimension = _dimension-1;
118
boundaryFace->_vertices = new vertex_t[_dimension];
119
if (i != 0)
120
memcpy(&(boundaryFace->_vertices[0]), &(_vertices[0]), i*sizeof(vertex_t));
121
if (i != _dimension)
122
memcpy(&(boundaryFace->_vertices[i]), &(_vertices[i+1]), (_dimension-i)*sizeof(vertex_t));
123
124
return boundaryFace;
125
}
126
127
bool Face::isSubfaceOf(const Face & face) const
128
{
129
if (face._dimension < _dimension || _dimension == -1)
130
return false;
131
132
/*int j = 0;
133
for (int i = 0; i < _dimension+1; i++)
134
{
135
while (j < face._dimension+1 && vertex_t_compare(&(_vertices[i]), &(face._vertices[j])) != 0)
136
j++;
137
}
138
139
if (j > face._dimension)
140
return false;*/
141
142
int i = 0;
143
int j = 0;
144
while (i < _dimension+1 && j < face._dimension+1)
145
{
146
const int comparison = vertex_t_compare(&(_vertices[i]), &(face._vertices[j]));
147
if (comparison == 0)
148
{
149
i++;
150
}
151
else if (comparison < 0)
152
{
153
return false;
154
}
155
j++;
156
}
157
158
if (i < _dimension+1)
159
return false;
160
161
return true;
162
}
163
164
// serialization methods
165
std::ostream & operator<< (std::ostream & os, const Face & face)
166
{
167
if (face._vertices == 0)
168
{
169
os<<"[]";
170
}
171
else
172
{
173
list_print(os, &(face._vertices[0]), &(face._vertices[face._dimension+1]));
174
}
175
176
return os;
177
}
178
std::istream & operator>> (std::istream & is, Face & face)
179
{
180
std::vector< vertex_t > vertices;
181
list_read(is, vertices);
182
183
if (vertices.empty())
184
{
185
face = Face();
186
}
187
else
188
{
189
face = Face(&vertices[0], static_cast<int>(vertices.size() - 1));
190
}
191
192
return is;
193
}
194
195
Face Face::linkFace(const Face & face, const face_list_t & linkFacets)
196
{
197
size_t size = 0;
198
for (face_list_t::const_iterator it = linkFacets.begin(); it != linkFacets.end(); it++)
199
{
200
size += it->_dimension+1;
201
}
202
203
vertex_t * linkVertices = new vertex_t[size];
204
205
size_t pos = 0;
206
for (face_list_t::const_iterator it = linkFacets.begin(); it != linkFacets.end(); it++)
207
{
208
memcpy(&(linkVertices[pos]), it->_vertices, (it->_dimension+1)*sizeof(vertex_t));
209
pos += (it->_dimension+1);
210
}
211
212
qsort(linkVertices, size, sizeof(vertex_t), &vertex_t_compare);
213
size = remove_duplicates(linkVertices, size, sizeof(vertex_t), &vertex_t_compare);
214
size = remove_from_set(linkVertices, size, face._vertices, face._dimension+1, sizeof(vertex_t), &vertex_t_compare);
215
216
Face linkFace(linkVertices, static_cast< int >(size)-1);
217
delete[] linkVertices;
218
219
return linkFace;
220
}
221
222
Face Face::unite(const Face & face1, const Face & face2)
223
{
224
if (face1.dimension() == -1)
225
return face2;
226
if (face2.dimension() == -1)
227
return face1;
228
229
vertex_t * vertices = new vertex_t[face1._dimension + face2._dimension + 2];
230
memcpy(vertices, face1._vertices, (face1._dimension+1)*sizeof(vertex_t));
231
memcpy(&(vertices[face1._dimension+1]), face2._vertices, (face2._dimension+1)*sizeof(vertex_t));
232
233
qsort(vertices, face1._dimension + face2._dimension + 2, sizeof(vertex_t), &vertex_t_compare);
234
size_t size = remove_duplicates(vertices, face1._dimension + face2._dimension + 2, sizeof(vertex_t), &vertex_t_compare);
235
236
Face unionFace(vertices, static_cast< int >(size)-1);
237
delete[] vertices;
238
239
return unionFace;
240
}
241
242
243
void addBoundaryfacesOfFace(const Face & face, face_list_t & listOfBoundaryfaces)
244
{
245
vertex_t * boundaryfaceVertices = (face.dimension() < 1 ? 0 : new vertex_t[face.dimension()]);
246
247
for (unsigned int i = 0; i < face.dimension(); i++)
248
boundaryfaceVertices[i] = face.vertex(i+1);
249
250
if (face.dimension() > 0)
251
listOfBoundaryfaces.push_back(Face(boundaryfaceVertices, face.dimension()-1));
252
for (unsigned int i = 0; i < face.dimension(); i++)
253
{
254
boundaryfaceVertices[i] = face.vertex(i);
255
listOfBoundaryfaces.push_back(Face(boundaryfaceVertices, face.dimension()-1));
256
}
257
258
if (boundaryfaceVertices != 0)
259
delete[] boundaryfaceVertices;
260
}
261
262
void incrementBitmask(std::vector< bool > & bitmask);
263
264
void addSubfacesOfFace(const Face & face, face_list_t & listOfSubfaces)
265
{
266
vertex_t * subfaceVertices = (face.dimension() < 1 ? 0 : new vertex_t[face.dimension()]);
267
268
std::vector< bool > bitmask(face.dimension()+1, false);
269
for (unsigned long long int i = 0; i < (face.dimension() < 0 ? 0 : (1<<(face.dimension()+1))-2); i++)
270
{
271
incrementBitmask(bitmask);
272
273
unsigned int subfaceSize = 0;
274
std::vector< bool >::const_iterator it;
275
unsigned int index;
276
277
for (it = bitmask.begin(), index = 0; it != bitmask.end(); it++, index++)
278
{
279
if (*it)
280
{
281
subfaceVertices[subfaceSize] = face.vertex(index);
282
subfaceSize++;
283
}
284
}
285
286
listOfSubfaces.push_back(Face(subfaceVertices, subfaceSize-1));
287
}
288
289
if (subfaceVertices != 0)
290
delete[] subfaceVertices;
291
}
292
293
void incrementBitmask(std::vector< bool > & bitmask)
294
{
295
std::vector< bool >::iterator it = bitmask.begin();
296
while (it != bitmask.end())
297
{
298
if ((*it = !*it))
299
break;
300
it++;
301
}
302
}
303