gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
VertexArray.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <string.h>
7 #include <algorithm>
8 #include "GmshMessage.h"
9 #include "VertexArray.h"
10 #include "Context.h"
11 #include "Numeric.h"
12 #include "OS.h"
13 
14 template<int N> float ElementDataLessThan<N>::tolerance = 0.0F;
16 
17 VertexArray::VertexArray(int numVerticesPerElement, int numElements)
18  : _numVerticesPerElement(numVerticesPerElement)
19 {
20  int nb = (numElements ? numElements : 1) * _numVerticesPerElement;
21 
22  double memv = (nb * 3. * sizeof(float)) / 1024. / 1024.;
23  double memmax = TotalRam() / 3.;
24  if(memv > memmax){
25  int old = nb;
26  nb = memmax / (3. * sizeof(float)) * 1024 * 1024;
27  Msg::Debug("Reduce preallocation of vertex array (%d -> %d)", old, nb);
28  }
29  _vertices.reserve(nb * 3);
30  _normals.reserve(nb * 3);
31  _colors.reserve(nb * 4);
32 }
33 
35 {
36  int bytes = _vertices.size() * sizeof(float) +
37  _normals.size() * sizeof(normal_type) +
38  _colors.size() * sizeof(unsigned char);
39  return (double)bytes / 1024. / 1024.;
40 }
41 
42 void VertexArray::_addVertex(float x, float y, float z)
43 {
44  _vertices.push_back(x);
45  _vertices.push_back(y);
46  _vertices.push_back(z);
47 }
48 
49 void VertexArray::_addNormal(float nx, float ny, float nz)
50 {
51 #if defined(HAVE_VISUDEV)
52  _normals.push_back(nx);
53  _normals.push_back(ny);
54  _normals.push_back(nz);
55 #else
56  // storing the normals as bytes hurts rendering performance, but it
57  // significantly reduces the memory footprint
58  char cx = float2char(nx);
59  char cy = float2char(ny);
60  char cz = float2char(nz);
61  _normals.push_back(cx);
62  _normals.push_back(cy);
63  _normals.push_back(cz);
64 #endif
65 }
66 
67 void VertexArray::_addColor(unsigned char r, unsigned char g, unsigned char b,
68  unsigned char a)
69 {
70  _colors.push_back(r);
71  _colors.push_back(g);
72  _colors.push_back(b);
73  _colors.push_back(a);
74 }
75 
77 {
78  if(ele && CTX::instance()->pickElements) _elements.push_back(ele);
79 }
80 
81 void VertexArray::add(double *x, double *y, double *z, SVector3 *n,
82  unsigned int *col, MElement *ele, bool unique, bool boundary)
83 {
84  if(col){
85  unsigned char r[100], g[100], b[100], a[100];
86  int npe = getNumVerticesPerElement();
87  for(int i = 0; i < npe; i++){
88  r[i] = CTX::instance()->unpackRed(col[i]);
89  g[i] = CTX::instance()->unpackGreen(col[i]);
90  b[i] = CTX::instance()->unpackBlue(col[i]);
91  a[i] = CTX::instance()->unpackAlpha(col[i]);
92  }
93  add(x, y, z, n, r, g, b, a, ele, unique, boundary);
94  }
95  else
96  add(x, y, z, n, nullptr, nullptr, nullptr, nullptr, ele, unique, boundary);
97 }
98 
99 void VertexArray::add(double *x, double *y, double *z, SVector3 *n, unsigned char *r,
100  unsigned char *g, unsigned char *b, unsigned char *a,
101  MElement *ele, bool unique, bool boundary)
102 {
103  int npe = getNumVerticesPerElement();
104 
105  if(boundary && npe == 3){
106  ElementData<3> e(x, y, z, n, r, g, b, a, ele);
107  ElementDataLessThan<3>::tolerance = (float)(CTX::instance()->lc * 1.e-12);
108  auto it = _data3.find(e);
109  if(it == _data3.end())
110  _data3.insert(e);
111  else
112  _data3.erase(it);
113  return;
114  }
115 
116  // enabling this will reduce memory and rendering time; but will increase the
117  // time it takes to create the vertex array
118 #if 0
119  if(unique){
120  Barycenter pc(0.0F, 0.0F, 0.0F);
121  for(int i = 0; i < npe; i++)
122  pc += Barycenter(x[i], y[i], z[i]);
123  BarycenterLessThan::tolerance = (float)(CTX::instance()->lc * 1.e-12);
124  if(_barycenters.find(pc) != _barycenters.end())
125  return;
126  _barycenters.insert(pc);
127  }
128 #endif
129 
130  for(int i = 0; i < npe; i++){
131  _addVertex((float)x[i], (float)y[i], (float)z[i]);
132  if(n) _addNormal((float)n[i].x(), (float)n[i].y(), (float)n[i].z());
133  if(r && g && b && a) _addColor(r[i], g[i], b[i], a[i]);
134  _addElement(ele);
135  }
136 }
137 
139 {
140  if(_data3.size()){
141  auto it = _data3.begin();
142  for(; it != _data3.end(); it++){
143  for(int i = 0; i < 3; i++){
144  _addVertex(it->x(i), it->y(i), it->z(i));
145  _addNormal(it->nx(i), it->ny(i), it->nz(i));
146  _addColor(it->r(i), it->g(i), it->b(i), it->a(i));
147  _addElement(it->ele());
148  }
149  }
150  _data3.clear();
151  }
152  _barycenters.clear();
153 }
154 
156  public:
157  AlphaElement(float *vp, normal_type *np, unsigned char *cp) : v(vp), n(np), c(cp) {}
158  float *v;
160  unsigned char *c;
161 };
162 
164  public:
165  static int numVertices;
166  static double eye[3];
167  bool operator()(const AlphaElement &e1, const AlphaElement &e2) const
168  {
169  double cg1[3] = { 0., 0., 0. }, cg2[3] = { 0., 0., 0.};
170  for(int i = 0; i < numVertices; i++) {
171  cg1[0] += e1.v[3 * i];
172  cg1[1] += e1.v[3 * i + 1];
173  cg1[2] += e1.v[3 * i + 2];
174  cg2[0] += e2.v[3 * i];
175  cg2[1] += e2.v[3 * i + 1];
176  cg2[2] += e2.v[3 * i + 2];
177  }
178  return prosca(eye, cg1) < prosca(eye, cg2);
179  }
180 };
181 
183 double AlphaElementLessThan::eye[3] = {0., 0., 0.};
184 
185 void VertexArray::sort(double x, double y, double z)
186 {
187  // This simplementation is pretty bad: it copies the whole data
188  // twice. We should think about a more efficient way to sort the
189  // three arrays in place.
190 
191  int npe = getNumVerticesPerElement();
192  int n = getNumVertices() / npe;
193 
198 
199  std::vector<AlphaElement> elements;
200  elements.reserve(n);
201  for(int i = 0; i < n; i++){
202  float *vp = &_vertices[3 * npe * i];
203  normal_type *np = _normals.empty() ? nullptr : &_normals[3 * npe * i];
204  unsigned char *cp = _colors.empty() ? nullptr : &_colors[4 * npe * i];
205  elements.push_back(AlphaElement(vp, np, cp));
206  }
207  std::sort(elements.begin(), elements.end(), AlphaElementLessThan());
208 
209  std::vector<float> sortedVertices;
210  std::vector<normal_type> sortedNormals;
211  std::vector<unsigned char> sortedColors;
212  sortedVertices.reserve(_vertices.size());
213  sortedNormals.reserve(_normals.size());
214  sortedColors.reserve(_colors.size());
215 
216  for(int i = 0; i < n; i++){
217  for(int j = 0; j < npe; j++){
218  for(int k = 0; k < 3; k++)
219  sortedVertices.push_back(elements[i].v[3 * j + k]);
220  if(elements[i].n)
221  for(int k = 0; k < 3; k++)
222  sortedNormals.push_back(elements[i].n[3 * j + k]);
223  if(elements[i].c)
224  for(int k = 0; k < 4; k++)
225  sortedColors.push_back(elements[i].c[4 * j + k]);
226  }
227  }
228 
229  _vertices = sortedVertices;
230  _normals = sortedNormals;
231  _colors = sortedColors;
232 }
233 
234 char *VertexArray::toChar(int num, const std::string &name, int type,
235  double min, double max, int numsteps, double time,
236  const SBoundingBox3d &bbox, int &len)
237 {
238  int vn = _vertices.size(), nn = _normals.size(), cn = _colors.size();
239  int vs = vn * sizeof(float),
240  ns = nn * sizeof(normal_type),
241  cs = cn * sizeof(unsigned char);
242  int is = sizeof(int), ds = sizeof(double);
243  int ss = name.size();
244  double xmin = bbox.min().x(), ymin = bbox.min().y(), zmin = bbox.min().z();
245  double xmax = bbox.max().x(), ymax = bbox.max().y(), zmax = bbox.max().z();
246 
247  len = ss + 7 * is + 9 * ds + vs + ns + cs;
248  char *bytes = new char[len];
249  int index = 0;
250  memcpy(&bytes[index], &num, is); index += is;
251  memcpy(&bytes[index], &ss, is); index += is;
252  memcpy(&bytes[index], name.c_str(), ss); index += ss;
253  memcpy(&bytes[index], &type, is); index += is;
254  memcpy(&bytes[index], &min, ds); index += ds;
255  memcpy(&bytes[index], &max, ds); index += ds;
256  memcpy(&bytes[index], &numsteps, is); index += is;
257  memcpy(&bytes[index], &time, ds); index += ds;
258  memcpy(&bytes[index], &xmin, ds); index += ds;
259  memcpy(&bytes[index], &ymin, ds); index += ds;
260  memcpy(&bytes[index], &zmin, ds); index += ds;
261  memcpy(&bytes[index], &xmax, ds); index += ds;
262  memcpy(&bytes[index], &ymax, ds); index += ds;
263  memcpy(&bytes[index], &zmax, ds); index += ds;
264  memcpy(&bytes[index], &vn, is); index += is;
265  if(vs){ memcpy(&bytes[index], &_vertices[0], vs); index += vs; }
266  memcpy(&bytes[index], &nn, is); index += is;
267  if(ns){ memcpy(&bytes[index], &_normals[0], ns); index += ns; }
268  memcpy(&bytes[index], &cn, is); index += is;
269  if(cs){ memcpy(&bytes[index], &_colors[0], cs); /* index += cs; */ }
270  return bytes;
271 }
272 
273 int VertexArray::decodeHeader(int length, const char *bytes, int swap,
274  std::string &name, int &tag, int &type,
275  double &min, double &max, int &numSteps, double &time,
276  double &xmin, double &ymin, double &zmin,
277  double &xmax, double &ymax, double &zmax)
278 {
279  int is = sizeof(int), ds = sizeof(double);
280 
281  if(length < 4 * is + 9 * ds){
282  Msg::Error("Too few bytes to create vertex array: %d", length);
283  return 0;
284  }
285 
286  if(swap){
287  Msg::Error("Should swap bytes in vertex array--not implemented yet");
288  return 0;
289  }
290 
291  int index = 0;
292  memcpy(&tag, &bytes[index], is); index += is;
293  int ss; memcpy(&ss, &bytes[index], is); index += is;
294  if(ss){
295  std::vector<char> n(ss);
296  memcpy(&n[0], &bytes[index], ss); index += ss;
297  for(std::size_t i = 0; i < n.size(); i++) name += n[i];
298  }
299  memcpy(&type, &bytes[index], is); index += is;
300  memcpy(&min, &bytes[index], ds); index += ds;
301  memcpy(&max, &bytes[index], ds); index += ds;
302  memcpy(&numSteps, &bytes[index], is); index += is;
303  memcpy(&time, &bytes[index], ds); index += ds;
304  memcpy(&xmin, &bytes[index], ds); index += ds;
305  memcpy(&ymin, &bytes[index], ds); index += ds;
306  memcpy(&zmin, &bytes[index], ds); index += ds;
307  memcpy(&xmax, &bytes[index], ds); index += ds;
308  memcpy(&ymax, &bytes[index], ds); index += ds;
309  memcpy(&zmax, &bytes[index], ds); index += ds;
310  return index;
311 }
312 
313 void VertexArray::fromChar(int length, const char *bytes, int swap)
314 {
315  std::string name;
316  int tag, type, numSteps;
317  double min, max, time, xmin, ymin, zmin, xmax, ymax, zmax;
318  int index = decodeHeader(length, bytes, swap, name, tag, type, min, max,
319  numSteps, time, xmin, ymin, zmin, xmax, ymax, zmax);
320  if(!index) return;
321 
322  int is = sizeof(int);
323  int vn; memcpy(&vn, &bytes[index], is); index += is;
324  if(vn){
325  _vertices.resize(vn); int vs = vn * sizeof(float);
326  memcpy(&_vertices[0], &bytes[index], vs); index += vs;
327  }
328 
329  int nn; memcpy(&nn, &bytes[index], is); index += is;
330  if(nn){
331  _normals.resize(nn);
332  int ns = nn * sizeof(normal_type);
333  memcpy(&_normals[0], &bytes[index], ns); index += ns;
334  }
335 
336  int cn; memcpy(&cn, &bytes[index], is); index += is;
337  if(cn){
338  _colors.resize(cn); int cs = cn * sizeof(unsigned char);
339  memcpy(&_colors[0], &bytes[index], cs); /* index += cs; */
340  }
341 }
342 
344 {
345  if(va->getNumVertices() != 0) {
346  _vertices.insert(_vertices.end(), va->firstVertex(), va->lastVertex());
347  _normals.insert(_normals.end(), va->firstNormal(), va->lastNormal());
348  _colors.insert(_colors.end(), va->firstColor(), va->lastColor());
349  _elements.insert(_elements.end(), va->firstElementPointer(),
350  va->lastElementPointer());
351  }
352 }
VertexArray::firstNormal
std::vector< normal_type >::iterator firstNormal()
Definition: VertexArray.h:188
VertexArray::_addColor
void _addColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
Definition: VertexArray.cpp:67
VertexArray::merge
void merge(VertexArray *va)
Definition: VertexArray.cpp:343
VertexArray::fromChar
void fromChar(int length, const char *bytes, int swap)
Definition: VertexArray.cpp:313
VertexArray::getMemoryInMb
double getMemoryInMb()
Definition: VertexArray.cpp:34
CTX::unpackBlue
int unpackBlue(unsigned int X)
Definition: Context.cpp:152
AlphaElement::n
normal_type * n
Definition: VertexArray.cpp:159
VertexArray::toChar
char * toChar(int num, const std::string &name, int type, double min, double max, int numsteps, double time, const SBoundingBox3d &bbox, int &len)
Definition: VertexArray.cpp:234
VertexArray::getNumVerticesPerElement
int getNumVerticesPerElement()
Definition: VertexArray.h:176
F
#define F
Definition: DefaultOptions.h:23
OS.h
float2char
char float2char(float f)
Definition: Numeric.cpp:452
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
VertexArray.h
VertexArray::lastColor
std::vector< unsigned char >::iterator lastColor()
Definition: VertexArray.h:194
SBoundingBox3d::min
SPoint3 min() const
Definition: SBoundingBox3d.h:90
SVector3
Definition: SVector3.h:16
VertexArray::sort
void sort(double x, double y, double z)
Definition: VertexArray.cpp:185
VertexArray
Definition: VertexArray.h:151
VertexArray::lastNormal
std::vector< normal_type >::iterator lastNormal()
Definition: VertexArray.h:189
VertexArray::lastVertex
std::vector< float >::iterator lastVertex()
Definition: VertexArray.h:184
VertexArray::getNumVertices
int getNumVertices()
Definition: VertexArray.h:174
VertexArray::_colors
std::vector< unsigned char > _colors
Definition: VertexArray.h:156
ElementDataLessThan
Definition: VertexArray.h:81
GmshMessage.h
AlphaElement::AlphaElement
AlphaElement(float *vp, normal_type *np, unsigned char *cp)
Definition: VertexArray.cpp:157
VertexArray::_addVertex
void _addVertex(float x, float y, float z)
Definition: VertexArray.cpp:42
VertexArray::firstVertex
std::vector< float >::iterator firstVertex()
Definition: VertexArray.h:183
VertexArray::decodeHeader
static int decodeHeader(int length, const char *bytes, int swap, std::string &name, int &tag, int &type, double &min, double &max, int &numSteps, double &time, double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Definition: VertexArray.cpp:273
AlphaElementLessThan::operator()
bool operator()(const AlphaElement &e1, const AlphaElement &e2) const
Definition: VertexArray.cpp:167
AlphaElementLessThan
Definition: VertexArray.cpp:163
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
VertexArray::_normals
std::vector< normal_type > _normals
Definition: VertexArray.h:155
VertexArray::_elements
std::vector< MElement * > _elements
Definition: VertexArray.h:157
VertexArray::lastElementPointer
std::vector< MElement * >::iterator lastElementPointer()
Definition: VertexArray.h:202
VertexArray::firstColor
std::vector< unsigned char >::iterator firstColor()
Definition: VertexArray.h:193
CTX::lc
double lc
Definition: Context.h:234
AlphaElementLessThan::eye
static double eye[3]
Definition: VertexArray.cpp:166
swap
void swap(double &a, double &b)
Definition: meshTriangulation.cpp:27
AlphaElement::c
unsigned char * c
Definition: VertexArray.cpp:160
Numeric.h
CTX::unpackGreen
int unpackGreen(unsigned int X)
Definition: Context.cpp:144
Barycenter
Definition: VertexArray.h:97
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
normal_type
char normal_type
Definition: VertexArray.h:17
AlphaElementLessThan::numVertices
static int numVertices
Definition: VertexArray.cpp:165
prosca
double prosca(double const a[3], double const b[3])
Definition: Numeric.h:112
MElement
Definition: MElement.h:30
TotalRam
double TotalRam()
Definition: OS.cpp:374
VertexArray::_numVerticesPerElement
int _numVerticesPerElement
Definition: VertexArray.h:153
VertexArray::firstElementPointer
std::vector< MElement * >::iterator firstElementPointer()
Definition: VertexArray.h:198
VertexArray::_addNormal
void _addNormal(float nx, float ny, float nz)
Definition: VertexArray.cpp:49
BarycenterLessThan::tolerance
static float tolerance
Definition: VertexArray.h:119
length
double length(Quaternion &q)
Definition: Camera.cpp:346
CTX::unpackAlpha
int unpackAlpha(unsigned int X)
Definition: Context.cpp:160
VertexArray::_data3
std::set< ElementData< 3 >, ElementDataLessThan< 3 > > _data3
Definition: VertexArray.h:158
Context.h
z
const double z
Definition: GaussQuadratureQuad.cpp:56
VertexArray::_barycenters
std::set< Barycenter, BarycenterLessThan > _barycenters
Definition: VertexArray.h:159
AlphaElement::v
float * v
Definition: VertexArray.cpp:158
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
VertexArray::finalize
void finalize()
Definition: VertexArray.cpp:138
VertexArray::_vertices
std::vector< float > _vertices
Definition: VertexArray.h:154
VertexArray::add
void add(double *x, double *y, double *z, SVector3 *n, unsigned int *col, MElement *ele=nullptr, bool unique=true, bool boundary=false)
Definition: VertexArray.cpp:81
SBoundingBox3d::max
SPoint3 max() const
Definition: SBoundingBox3d.h:91
CTX::unpackRed
int unpackRed(unsigned int X)
Definition: Context.cpp:136
VertexArray::VertexArray
VertexArray(int numVerticesPerElement, int numElements)
Definition: VertexArray.cpp:17
SBoundingBox3d
Definition: SBoundingBox3d.h:21
ElementData
Definition: VertexArray.h:22
AlphaElement
Definition: VertexArray.cpp:155
VertexArray::_addElement
void _addElement(MElement *ele)
Definition: VertexArray.cpp:76