1
#if defined(_MSC_VER) /* MSVC Compiler */
2
#pragma warning ( disable : 4305 )
3
#pragma warning ( disable : 4786 )
6
#include "qwt3d_surfaceplot.h"
7
#include "qwt3d_enrichment_std.h"
10
using namespace Qwt3D;
14
void SurfacePlot::createDataG()
18
if (plotStyle() == NOPLOT)
23
int step = resolution();
25
if (plotStyle() == Qwt3D::POINTS)
30
else if (plotStyle() == Qwt3D::USER)
33
createEnrichment(*userplotstyle_p);
37
setDeviceLineWidth(meshLineWidth());
39
GLStateBewarer sb(GL_POLYGON_OFFSET_FILL,true);
40
setDevicePolygonOffset(polygonOffset(),1.0);
42
GLStateBewarer sb2(GL_LINE_SMOOTH, smoothDataMesh());
43
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
46
int lastcol = actualDataG_->columns();
47
int lastrow = actualDataG_->rows();
49
if (plotStyle() != WIREFRAME)
51
glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS);
53
bool hl = (plotStyle() == HIDDENLINE);
56
col = backgroundRGBAColor();
57
glColor4d(col.r, col.g, col.b, col.a);
60
for (i = 0; i < lastcol - step; i += step)
62
glBegin(GL_TRIANGLE_STRIP);
63
setColorFromVertexG(i, 0, hl);
64
glNormal3dv(actualDataG_->normals[i][0]);
65
glVertex3dv(actualDataG_->vertices[i][0]);
67
setColorFromVertexG(i+step, 0, hl);
68
glNormal3dv(actualDataG_->normals[i+step][0]);
69
glVertex3dv(actualDataG_->vertices[i+step][0]);
71
for (j = 0; j < lastrow - step; j += step)
73
setColorFromVertexG(i,j+step, hl);
74
glNormal3dv(actualDataG_->normals[i][j+step]);
75
glVertex3dv(actualDataG_->vertices[i][j+step]);
77
setColorFromVertexG(i+step, j+step, hl);
78
glNormal3dv(actualDataG_->normals[i+step][j+step]);
79
glVertex3dv(actualDataG_->vertices[i+step][j+step]);
85
if (plotStyle() == FILLEDMESH || plotStyle() == WIREFRAME || plotStyle() == HIDDENLINE)
87
glColor4d(meshColor().r, meshColor().g, meshColor().b, meshColor().a);
89
if (step < actualDataG_->columns() && step < actualDataG_->rows())
91
glBegin(GL_LINE_LOOP);
92
for (i = 0; i < actualDataG_->columns() - step; i += step)
93
glVertex3dv(actualDataG_->vertices[i][0]);
94
for (j = 0; j < actualDataG_->rows() - step; j += step)
95
glVertex3dv(actualDataG_->vertices[i][j]);
96
for (; i >= 0; i -= step)
97
glVertex3dv(actualDataG_->vertices[i][j]);
98
for (; j >= 0; j -= step)
99
glVertex3dv(actualDataG_->vertices[0][j]);
104
for (i = step; i < actualDataG_->columns() - step; i += step)
106
glBegin(GL_LINE_STRIP);
107
for (j = 0; j < actualDataG_->rows(); j += step)
108
glVertex3dv(actualDataG_->vertices[i][j]);
111
for (j = step; j < actualDataG_->rows() - step; j += step)
113
glBegin(GL_LINE_STRIP);
114
for (i = 0; i < actualDataG_->columns(); i += step)
115
glVertex3dv(actualDataG_->vertices[i][j]);
121
void SurfacePlot::setColorFromVertexG(int ix, int iy, bool skip)
126
RGBA col = (*datacolor_p)(
127
actualDataG_->vertices[ix][iy][0],
128
actualDataG_->vertices[ix][iy][1],
129
actualDataG_->vertices[ix][iy][2]);
131
glColor4d(col.r, col.g, col.b, col.a);
135
void SurfacePlot::createNormalsG()
137
if (!normals() || actualDataG_->empty())
141
arrow.setQuality(normalQuality());
143
Triple basev, topv, norm;
145
int step = resolution();
147
double diag = (actualDataG_->hull().maxVertex-actualDataG_->hull().minVertex).length() * normalLength();
151
for (int i = 0; i <= actualDataG_->columns() - step; i += step)
153
for (int j = 0; j <= actualDataG_->rows() - step; j += step)
155
basev = Triple(actualDataG_->vertices[i][j][0],actualDataG_->vertices[i][j][1],actualDataG_->vertices[i][j][2]);
156
topv = Triple(actualDataG_->vertices[i][j][0]+actualDataG_->normals[i][j][0],
157
actualDataG_->vertices[i][j][1]+actualDataG_->normals[i][j][1],
158
actualDataG_->vertices[i][j][2]+actualDataG_->normals[i][j][2]);
164
arrow.setTop(basev+norm);
165
arrow.setColor((*datacolor_p)(basev.x,basev.y,basev.z));
172
void SurfacePlot::readIn(GridData& gdata, Triple** data, unsigned int columns, unsigned int rows)
174
gdata.setSize(columns,rows);
176
ParallelEpiped range(Triple(DBL_MAX,DBL_MAX,DBL_MAX),Triple(-DBL_MAX,-DBL_MAX,-DBL_MAX));
178
/* fill out the vertex array for the mesh. */
179
for (unsigned i = 0; i != columns; ++i)
181
for (unsigned j = 0; j != rows; ++j)
183
gdata.vertices[i][j][0] = data[i][j].x;
184
gdata.vertices[i][j][1] = data[i][j].y;
185
gdata.vertices[i][j][2] = data[i][j].z;
187
if (data[i][j].x > range.maxVertex.x)
188
range.maxVertex.x = data[i][j].x;
189
if (data[i][j].y > range.maxVertex.y)
190
range.maxVertex.y = data[i][j].y;
191
if (data[i][j].z > range.maxVertex.z)
192
range.maxVertex.z = data[i][j].z;
193
if (data[i][j].x < range.minVertex.x)
194
range.minVertex.x = data[i][j].x;
195
if (data[i][j].y < range.minVertex.y)
196
range.minVertex.y = data[i][j].y;
197
if (data[i][j].z < range.minVertex.z)
198
range.minVertex.z = data[i][j].z;
201
gdata.setHull(range);
205
void SurfacePlot::readIn(GridData& gdata, double** data, unsigned int columns, unsigned int rows
206
, double minx, double maxx, double miny, double maxy)
208
gdata.setPeriodic(false,false);
209
gdata.setSize(columns,rows);
211
double dx = (maxx - minx) / (gdata.columns() - 1);
212
double dy = (maxy - miny) / (gdata.rows() - 1);
214
double tmin = DBL_MAX;
215
double tmax = -DBL_MAX;
217
/* fill out the vertex array for the mesh. */
218
for (unsigned i = 0; i != columns; ++i)
220
for (unsigned j = 0; j != rows; ++j)
222
gdata.vertices[i][j][0] = minx + i*dx;
223
gdata.vertices[i][j][1] = miny + j*dy;
224
gdata.vertices[i][j][2] = data[i][j];
226
if (data[i][j] > tmax)
228
if (data[i][j] < tmin)
232
ParallelEpiped hull =
235
gdata.vertices[0][0][0],
236
gdata.vertices[0][0][1],
240
gdata.vertices[gdata.columns()-1][gdata.rows()-1][0],
241
gdata.vertices[gdata.columns()-1][gdata.rows()-1][1],
250
void SurfacePlot::calcNormals(GridData& gdata)
253
unsigned int rows = gdata.rows();
254
unsigned int columns = gdata.columns();
258
Triple u, v, n; // for cross product
260
for (unsigned i = 0; i != columns; ++i)
262
for (unsigned j = 0; j != rows; ++j)
267
if (i<columns-1 && j<rows-1)
269
/* get two vectors to cross */
271
gdata.vertices[i+1][j][0] - gdata.vertices[i][j][0],
272
gdata.vertices[i+1][j][1] - gdata.vertices[i][j][1],
273
gdata.vertices[i+1][j][2] - gdata.vertices[i][j][2]
277
gdata.vertices[i][j+1][0] - gdata.vertices[i][j][0],
278
gdata.vertices[i][j+1][1] - gdata.vertices[i][j][1],
279
gdata.vertices[i][j+1][2] - gdata.vertices[i][j][2]
281
/* get the normalized cross product */
282
n += normalizedcross(u,v); // right hand system here !
288
gdata.vertices[i][j+1][0] - gdata.vertices[i][j][0],
289
gdata.vertices[i][j+1][1] - gdata.vertices[i][j][1],
290
gdata.vertices[i][j+1][2] - gdata.vertices[i][j][2]
293
gdata.vertices[i-1][j][0] - gdata.vertices[i][j][0],
294
gdata.vertices[i-1][j][1] - gdata.vertices[i][j][1],
295
gdata.vertices[i-1][j][2] - gdata.vertices[i][j][2]
297
n += normalizedcross(u,v);
303
gdata.vertices[i-1][j][0] - gdata.vertices[i][j][0],
304
gdata.vertices[i-1][j][1] - gdata.vertices[i][j][1],
305
gdata.vertices[i-1][j][2] - gdata.vertices[i][j][2]
309
gdata.vertices[i][j-1][0] - gdata.vertices[i][j][0],
310
gdata.vertices[i][j-1][1] - gdata.vertices[i][j][1],
311
gdata.vertices[i][j-1][2] - gdata.vertices[i][j][2]
313
n += normalizedcross(u,v);
316
if (i<columns-1 && j>0)
319
gdata.vertices[i][j-1][0] - gdata.vertices[i][j][0],
320
gdata.vertices[i][j-1][1] - gdata.vertices[i][j][1],
321
gdata.vertices[i][j-1][2] - gdata.vertices[i][j][2]
325
gdata.vertices[i+1][j][0] - gdata.vertices[i][j][0],
326
gdata.vertices[i+1][j][1] - gdata.vertices[i][j][1],
327
gdata.vertices[i+1][j][2] - gdata.vertices[i][j][2]
329
n += normalizedcross(u,v);
333
gdata.normals[i][j][0] = n.x;
334
gdata.normals[i][j][1] = n.y;
335
gdata.normals[i][j][2] = n.z;
341
void SurfacePlot::sewPeriodic(GridData& gdata)
347
unsigned int columns = gdata.columns();
348
unsigned int rows = gdata.rows();
350
if (gdata.uperiodic())
352
for (unsigned i = 0; i != columns; ++i)
355
gdata.normals[i][0][0] + gdata.normals[i][rows-1][0],
356
gdata.normals[i][0][1] + gdata.normals[i][rows-1][1],
357
gdata.normals[i][0][2] + gdata.normals[i][rows-1][2]
361
gdata.normals[i][0][0] = gdata.normals[i][rows-1][0] = n.x;
362
gdata.normals[i][0][1] = gdata.normals[i][rows-1][1] = n.y;
363
gdata.normals[i][0][2] = gdata.normals[i][rows-1][2] = n.z;
366
if (gdata.vperiodic())
368
for (unsigned j = 0; j != rows; ++j)
371
gdata.normals[0][j][0] + gdata.normals[columns-1][j][0],
372
gdata.normals[0][j][1] + gdata.normals[columns-1][j][1],
373
gdata.normals[0][j][2] + gdata.normals[columns-1][j][2]
377
gdata.normals[0][j][0] = gdata.normals[columns-1][j][0] = n.x;
378
gdata.normals[0][j][1] = gdata.normals[columns-1][j][1] = n.y;
379
gdata.normals[0][j][2] = gdata.normals[columns-1][j][2] = n.z;
385
Convert user grid data to internal vertex structure.
386
See also NativeReader::read() and Function::create()
388
bool SurfacePlot::loadFromData(Triple** data, unsigned int columns, unsigned int rows, bool uperiodic, bool vperiodic)
390
actualDataC_->clear();
391
actualData_p = actualDataG_;
393
readIn(*actualDataG_, data, columns, rows);
394
calcNormals(*actualDataG_);
395
actualDataG_->setPeriodic(uperiodic,vperiodic);
396
sewPeriodic(*actualDataG_);
400
createCoordinateSystem();
406
Convert user grid data to internal vertex structure.
407
See also NativeReader::read() and Function::create()
409
bool SurfacePlot::loadFromData(double** data, unsigned int columns, unsigned int rows
410
, double minx, double maxx, double miny, double maxy)
412
actualDataC_->clear();
413
actualData_p = actualDataG_;
415
actualDataG_->setPeriodic(false,false);
416
actualDataG_->setSize(columns,rows);
417
readIn(*actualDataG_,data,columns,rows,minx,maxx,miny,maxy);
418
calcNormals(*actualDataG_);
422
createCoordinateSystem();
428
void SurfacePlot::createFloorDataG()
430
switch (floorStyle())
443
void SurfacePlot::Data2FloorG()
445
if (actualData_p->empty())
448
int step = resolution();
450
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
451
glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS);
453
double zshift = actualData_p->hull().minVertex.z;
454
for (int i = 0; i < actualDataG_->columns() - step; i += step)
456
glBegin(GL_TRIANGLE_STRIP);
457
setColorFromVertexG(i, 0);
458
glVertex3d(actualDataG_->vertices[i][0][0], actualDataG_->vertices[i][0][1], zshift);
460
setColorFromVertexG(i+step, 0);
461
glVertex3d(actualDataG_->vertices[i+step][0][0],actualDataG_->vertices[i+step][0][1], zshift);
462
for (int j = 0; j < actualDataG_->rows() - step; j += step)
464
setColorFromVertexG(i, j+step);
465
glVertex3d(actualDataG_->vertices[i][j+step][0],actualDataG_->vertices[i][j+step][1], zshift);
467
setColorFromVertexG(i+step, j+step);
468
glVertex3d(actualDataG_->vertices[i+step][j+step][0],actualDataG_->vertices[i+step][j+step][1], zshift);
474
void SurfacePlot::Isolines2FloorG()
476
if (isolines() <= 0 || actualData_p->empty())
479
double count = (actualData_p->hull().maxVertex.z - actualData_p->hull().minVertex.z) / isolines();
483
int step = resolution();
485
double zshift = actualData_p->hull().minVertex.z;
487
int cols = actualDataG_->columns();
488
int rows = actualDataG_->rows();
491
vector<Triple> intersection;
495
GLStateBewarer sb2(GL_LINE_SMOOTH, false);
497
for (int k = 0; k != isolines(); ++k)
499
double val = zshift + k * count;
501
for (int i = 0; i < cols-step; i += step)
503
for (int j = 0; j < rows-step; j += step)
505
t[0] = Triple( actualDataG_->vertices[i][j][0],
506
actualDataG_->vertices[i][j][1],
507
actualDataG_->vertices[i][j][2]);
509
col = (*datacolor_p)(t[0].x,t[0].y,t[0].z);
510
glColor4d(col.r, col.g, col.b, col.a);
511
// glColor4d(0,0,0,1);
513
t[1] = Triple( actualDataG_->vertices[i+step][j][0],
514
actualDataG_->vertices[i+step][j][1],
515
actualDataG_->vertices[i+step][j][2]);
516
t[2] = Triple( actualDataG_->vertices[i+step][j+step][0],
517
actualDataG_->vertices[i+step][j+step][1],
518
actualDataG_->vertices[i+step][j+step][2]);
519
t[3] = Triple( actualDataG_->vertices[i][j+step][0],
520
actualDataG_->vertices[i][j+step][1],
521
actualDataG_->vertices[i][j+step][2]);
524
for (int m = 0; m!=4; ++m)
527
if ((val>=t[m].z && val<=t[mm].z) || (val>=t[mm].z && val<=t[m].z))
529
diff = t[mm].z - t[m].z;
531
if (isPracticallyZero(diff)) // degenerated
533
intersection.push_back(t[m]);
534
intersection.push_back(t[mm]);
538
lambda = (val - t[m].z) / diff;
539
intersection.push_back(Triple(t[m].x + lambda * (t[mm].x-t[m].x), t[m].y + lambda * (t[mm].y-t[m].y), val));
543
if (!intersection.empty())
545
if (intersection.size()>2)
547
glBegin(GL_LINE_STRIP);
548
for (unsigned dd = 0; dd!=intersection.size(); ++dd)
550
glVertex3d(intersection[dd].x, intersection[dd].y, zshift);
554
glVertex3d(intersection[0].x,intersection[0].y,zshift);
557
else if (intersection.size() == 2)
560
glVertex3d(intersection[0].x,intersection[0].y,zshift);
561
glVertex3d(intersection[1].x,intersection[1].y,zshift);
563
// small pixel gap problem (see OpenGL spec.)
564
glVertex3d(intersection[1].x,intersection[1].y,zshift);
565
glVertex3d(intersection[0].x,intersection[0].y,zshift);
569
intersection.clear();
579
void SurfacePlot::calcLowResolution()
584
int res = resolution();
587
lowresData_p = *actualDataG_;
591
GridData const& src = *actualDataG_;