Select Git revision
MVertexBoundaryLayerData.cpp
drawAxes.cpp 13.07 KiB
// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
#include <string>
#include <iostream>
#include "Gmsh.h"
#include <string.h>
#include "drawContext.h"
#include "Trackball.h"
#include "GModel.h"
#include "Context.h"
#include "Numeric.h"
#include "gl2ps.h"
static int drawTics(drawContext *ctx, int comp, int n, std::string &format,
std::string &label, double p1[3], double p2[3],
double perp[3], int mikado, double pixelfact)
{
// draws n tic marks (in direction perp) and labels along the line p1->p2
double t[3] = {p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]};
double l = norme(t);
double w = 10 * pixelfact; // big tics 10 pixels
double w2 = 5 * pixelfact; // small tics 5 pixels
glRasterPos3d(p2[0] + t[0] * w * 1.4,
p2[1] + t[1] * w * 1.4,
p2[2] + t[2] * w * 1.4);
ctx->drawString(label);
if(n < 2) return 0;
if(format.empty()) return n;
double lp = norme(perp);
if(!lp){
switch(comp){
case 0: perp[1] = -1.; break;
case 1: perp[0] = -1.; break;
case 2: perp[0] = 1.; break;
default: break;
}
}
double tmp = 2. * CTX::instance()->glFontSize * pixelfact;
if(n * tmp > l) n = 3;
if(n * tmp > l) n = 2;
double step = l / (double)(n - 1);
for(int i = 0; i < n; i++){
double d = i * step;
double p[3] = {p1[0] + t[0] * d, p1[1] + t[1] * d, p1[2] + t[2] * d};
double q[3] = {p[0] + perp[0] * w,
p[1] + perp[1] * w,
p[2] + perp[2] * w};
double r[3] = {p[0] + perp[0] * w * 1.4,
p[1] + perp[1] * w * 1.4,
p[2] + perp[2] * w * 1.4 };
glBegin(GL_LINES);
glVertex3d(p[0], p[1], p[2]);
glVertex3d(q[0], q[1], q[2]);
glEnd();
if(i < n-1 && !mikado){
for(int j = 1; j < 10; j++){
double dd = d + j * step/10.;
double pp[3] = {p1[0] + t[0] * dd,
p1[1] + t[1] * dd,
p1[2] + t[2] * dd};
double qq[3] = {pp[0] + perp[0] * w2,
pp[1] + perp[1] * w2,
pp[2] + perp[2] * w2};
glBegin(GL_LINES);
glVertex3d(pp[0], pp[1], pp[2]);
glVertex3d(qq[0], qq[1], qq[2]);
glEnd();
}
}
char str[256];
if(comp < 0) // display the length (ruler)
sprintf(str, format.c_str(), d);
else // display the coordinate
sprintf(str, format.c_str(), p[comp]);
double winp[3], winr[3];
ctx->world2Viewport(p, winp);
ctx->world2Viewport(r, winr);
drawContext::global()->setFont(CTX::instance()->glFontEnum,
CTX::instance()->glFontSize);
if(fabs(winr[0] - winp[0]) < 2.) // center align
winr[0] -= drawContext::global()->getStringWidth(str) / 2.;
else if(winr[0] < winp[0]) // right align
winr[0] -= drawContext::global()->getStringWidth(str);
if(fabs(winr[1] - winp[1]) < 2.) // center align
winr[1] -= drawContext::global()->getStringHeight() / 3.;
else if(winr[1] < winp[1]) // top align
winr[1] -= drawContext::global()->getStringHeight();
ctx->viewport2World(winr, r);
glRasterPos3d(r[0], r[1], r[2]);
ctx->drawString(str);
}
return n;
}
static void drawGridStipple(int n1, int n2, double p1[3], double p2[3], double p3[3])
{
double t1[3] = {p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]};
double t2[3] = {p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]};
double l1 = norme(t1);
double l2 = norme(t2);
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, 0x1111);
gl2psEnable(GL2PS_LINE_STIPPLE);
glBegin(GL_LINES);
for(int i = 1; i < n1 - 1; i++){
double d = (double)i / (double)(n1 - 1) * l1;
glVertex3d(p1[0] + t1[0] * d,
p1[1] + t1[1] * d,
p1[2] + t1[2] * d);
glVertex3d(p1[0] + t1[0] * d + t2[0] * l2,
p1[1] + t1[1] * d + t2[1] * l2,
p1[2] + t1[2] * d + t2[2] * l2);
}
for(int i = 1; i < n2 - 1; i++){
double d = (double)i/(double)(n2 - 1) * l2;
glVertex3d(p1[0] + t2[0] * d,
p1[1] + t2[1] * d,
p1[2] + t2[2] * d);
glVertex3d(p1[0] + t2[0] * d + t1[0] * l1,
p1[1] + t2[1] * d + t1[1] * l1,
p1[2] + t2[2] * d + t1[2] * l1);
}
glEnd();
glDisable(GL_LINE_STIPPLE);
gl2psDisable(GL2PS_LINE_STIPPLE);
}
void drawContext::drawAxis(double xmin, double ymin, double zmin,
double xmax, double ymax, double zmax,
int nticks, int mikado)
{
if(mikado){
nticks = (nticks - 1) * mikado;
if(nticks < 1) nticks = 1;
double dd[3] = {(xmax - xmin) / nticks,
(ymax - ymin) / nticks,
(zmax - zmin) / nticks};
double axe_color[4];
glGetDoublev(GL_CURRENT_COLOR, axe_color);
for(int i = 1; i <= nticks; i++){
if(i % 2) glColor4dv(axe_color);
else glColor3f(1, 1, 1);
double cx[2] = {xmin + (i - 1) * dd[0], xmin + i * dd[0]};
double cy[2] = {ymin + (i - 1) * dd[1], ymin + i * dd[1]};
double cz[2] = {zmin + (i - 1) * dd[2], zmin + i * dd[2]};
drawCylinder(3.5, cx, cy, cz, 1);
}
glColor4dv(axe_color);
}
else{
glBegin(GL_LINES);
glVertex3d(xmin, ymin, zmin);
glVertex3d(xmax, ymax, zmax);
glEnd();
}
}
void drawContext::drawAxes(int mode, int tics[3], std::string format[3],
std::string label[3], double bb[6], int mikado)
{
// mode 0: nothing
// 1: axes
// 2: box
// 3: full grid
// 4: open grid
// 5: ruler
if((mode < 1) || (bb[0] == bb[1] && bb[2] == bb[3] && bb[4] == bb[5]))
return;
double xmin = bb[0], xmax = bb[1];
double ymin = bb[2], ymax = bb[3];
double zmin = bb[4], zmax = bb[5];
double orig[3] = {xmin, ymin, zmin};
double pixelfact = pixel_equiv_x / s[0];
if(mode == 5){ // draw ruler from xyz_min to xyz_max
double end[3] = {xmax, ymax, zmax};
double dir[3] = {xmax-xmin, ymax-ymin, zmax-zmin};
double perp[3];
if((fabs(dir[0]) >= fabs(dir[1]) && fabs(dir[0]) >= fabs(dir[2])) ||
(fabs(dir[1]) >= fabs(dir[0]) && fabs(dir[1]) >= fabs(dir[2]))){
perp[0] = dir[1]; perp[1] = -dir[0]; perp[2] = 0.;
}
else{
perp[0] = 0.; perp[1] = dir[2]; perp[2] = -dir[1];
}
drawTics(this, -1, tics[0], format[0], label[0], orig, end, perp, mikado, pixelfact);
drawAxis(xmin, ymin, zmin, xmax, ymax, zmax, tics[0], mikado);
return;
}
double xx[3] = {xmax, ymin, zmin};
double yy[3] = {xmin, ymax, zmin};
double zz[3] = {xmin, ymin, zmax};
double dxm[3] = {0., (ymin != ymax) ? -1. : 0., (zmin != zmax) ? -1. : 0.};
double dym[3] = {(xmin != xmax) ? -1. : 0., 0., (zmin != zmax) ? -1. : 0.};
double dzm[3] = {(xmin != xmax) ? -1. : 0., (ymin != ymax) ? -1. : 0., 0.};
int nx = (xmin != xmax) ?
drawTics(this, 0, tics[0], format[0], label[0], orig, xx, dxm, mikado, pixelfact) : 0;
int ny = (ymin != ymax) ?
drawTics(this, 1, tics[1], format[1], label[1], orig, yy, dym, mikado, pixelfact) : 0;
int nz = (zmin != zmax) ?
drawTics(this, 2, tics[2], format[2], label[2], orig, zz, dzm, mikado, pixelfact) : 0;
drawAxis(xmin, ymin, zmin, xmax, ymin, zmin, nx, mikado);
drawAxis(xmin, ymin, zmin, xmin, ymax, zmin, ny, mikado);
drawAxis(xmin, ymin, zmin, xmin, ymin, zmax, nz, mikado);
// open box
if(mode > 1){
drawAxis(xmin, ymax, zmin, xmax, ymax, zmin, nx, mikado);
drawAxis(xmax, ymin, zmin, xmax, ymax, zmin, ny, mikado);
drawAxis(xmax, ymin, zmin, xmax, ymin, zmax, nz, mikado);
drawAxis(xmin, ymin, zmax, xmax, ymin, zmax, nx, mikado);
drawAxis(xmin, ymin, zmax, xmin, ymax, zmax, ny, mikado);
drawAxis(xmin, ymax, zmin, xmin, ymax, zmax, nz, mikado);
}
// closed box
if(mode == 2 || mode == 3){
drawAxis(xmin, ymax, zmax, xmax, ymax, zmax, nx, mikado);
drawAxis(xmax, ymin, zmax, xmax, ymax, zmax, ny, mikado);
drawAxis(xmax, ymax, zmin, xmax, ymax, zmax, nz, mikado);
}
if(mode > 2){
drawGridStipple(nx, ny, orig, xx, yy);
drawGridStipple(ny, nz, orig, yy, zz);
drawGridStipple(nx, nz, orig, xx, zz);
}
if(mode == 3){
double orig2[3] = {xmax, ymax, zmax};
double xy[3] = {xmax, ymax, zmin};
double yz[3] = {xmin, ymax, zmax};
double xz[3] = {xmax, ymin, zmax};
if(zmin != zmax) drawGridStipple(nx, ny, orig2, yz, xz);
if(xmin != xmax) drawGridStipple(ny, nz, orig2, xz, xy);
if(ymin != ymax) drawGridStipple(nx, nz, orig2, yz, xy);
}
}
void drawContext::drawAxes(int mode, int tics[3], std::string format[3],
std::string label[3], SBoundingBox3d &bb, int mikado)
{
double bbox[6] = {bb.min().x(), bb.max().x(),
bb.min().y(), bb.max().y(),
bb.min().z(), bb.max().z()};
drawAxes(mode, tics, format, label, bbox, mikado);
}
void drawContext::drawAxes()
{
bool geometryExists = false;
for(unsigned int i = 0; i < GModel::list.size(); i++){
if(!GModel::list[i]->empty()){
geometryExists = true;
break;
}
}
if(geometryExists && (CTX::instance()->drawBBox || !CTX::instance()->mesh.draw)) {
glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
glLineWidth((float)CTX::instance()->lineWidth);
gl2psLineWidth((float)(CTX::instance()->lineWidth *
CTX::instance()->print.epsLineWidthFactor));
drawBox(CTX::instance()->min[0], CTX::instance()->min[1], CTX::instance()->min[2],
CTX::instance()->max[0], CTX::instance()->max[1], CTX::instance()->max[2]);
glColor3d(1.,0.,0.);
for(int j = 0; j < 6; j++)
if(CTX::instance()->geom.clip & (1 << j) || CTX::instance()->mesh.clip & (1 << j))
drawPlaneInBoundingBox
(CTX::instance()->min[0], CTX::instance()->min[1], CTX::instance()->min[2],
CTX::instance()->max[0], CTX::instance()->max[1], CTX::instance()->max[2],
CTX::instance()->clipPlane[j][0], CTX::instance()->clipPlane[j][1],
CTX::instance()->clipPlane[j][2], CTX::instance()->clipPlane[j][3]);
}
if(CTX::instance()->axes){
glColor4ubv((GLubyte *) & CTX::instance()->color.axes);
glLineWidth((float)CTX::instance()->lineWidth);
gl2psLineWidth((float)(CTX::instance()->lineWidth *
CTX::instance()->print.epsLineWidthFactor));
if(!CTX::instance()->axesAutoPosition){
drawAxes(CTX::instance()->axes, CTX::instance()->axesTics,
CTX::instance()->axesFormat, CTX::instance()->axesLabel,
CTX::instance()->axesPosition, CTX::instance()->axesMikado);
}
else if(geometryExists){
double bb[6] =
{CTX::instance()->min[0], CTX::instance()->max[0], CTX::instance()->min[1],
CTX::instance()->max[1], CTX::instance()->min[2], CTX::instance()->max[2]};
drawAxes(CTX::instance()->axes, CTX::instance()->axesTics,
CTX::instance()->axesFormat, CTX::instance()->axesLabel,
bb, CTX::instance()->axesMikado);
}
}
if(CTX::instance()->drawRotationCenter){
glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
if(CTX::instance()->rotationCenterCg)
drawSphere(CTX::instance()->pointSize, CTX::instance()->cg[0],
CTX::instance()->cg[1], CTX::instance()->cg[2],
CTX::instance()->geom.light);
else
drawSphere(CTX::instance()->pointSize, CTX::instance()->rotationCenter[0],
CTX::instance()->rotationCenter[1], CTX::instance()->rotationCenter[2],
CTX::instance()->geom.light);
}
}
void drawContext::drawSmallAxes()
{
double l = CTX::instance()->smallAxesSize;
double o = CTX::instance()->glFontSize / 5;
double cx = CTX::instance()->smallAxesPos[0];
double cy = CTX::instance()->smallAxesPos[1];
fix2dCoordinates(&cx, &cy);
double xx, xy, yx, yy , zx, zy;
if (CTX::instance()->camera) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camera.position.x,camera.position.y,camera.position.z,
camera.target.x,camera.target.y,camera.target.z,
camera.up.x,camera.up.y,camera.up.z);
glPushMatrix();
glPopMatrix();
float fvViewMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, fvViewMatrix);
glLoadIdentity();
xx = l * fvViewMatrix[0];
xy = l * fvViewMatrix[1];
yx = l * fvViewMatrix[4];
yy = l * fvViewMatrix[5];
zx = l * fvViewMatrix[8];
zy = l * fvViewMatrix[9];
}
else{
xx = l * rot[0];
xy = l * rot[1];
yx = l * rot[4];
yy = l * rot[5];
zx = l * rot[8];
zy = l * rot[9];
}
glLineWidth((float)CTX::instance()->lineWidth);
gl2psLineWidth((float)(CTX::instance()->lineWidth *
CTX::instance()->print.epsLineWidthFactor));
glColor4ubv((GLubyte *) & CTX::instance()->color.smallAxes);
glBegin(GL_LINES);
glVertex2d(cx, cy);
glVertex2d(cx + xx, cy + xy);
glVertex2d(cx, cy);
glVertex2d(cx + yx, cy + yy);
glVertex2d(cx, cy);
glVertex2d(cx + zx, cy + zy);
glEnd();
glRasterPos2d(cx + xx + o, cy + xy + o);
drawString("X");
glRasterPos2d(cx + yx + o, cy + yy + o);
drawString("Y");
glRasterPos2d(cx + zx + o, cy + zy + o);
drawString("Z");
}