⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lasview.cpp

📁 Lidar数据处理时
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
===============================================================================

  FILE:  lasview.cpp
  
  CONTENTS:
  
    This little tool is just a quick little hack to visualize an LAS files.
  
  PROGRAMMERS:
  
    martin isenburg@cs.unc.edu
  
  COPYRIGHT:
  
    copyright (C) 2005  martin isenburg@cs.unc.edu
    
    This software is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  
  CHANGE HISTORY:
  
    9 May 2007 -- adapted from my streaming point viewer
  
===============================================================================
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>

#include "lasreader.h"

#ifdef _WIN32
extern "C" FILE* fopenGzipped(const char* filename, const char* mode);
#endif

// MOUSE INTERFACE

static int LeftButtonDown=0;
static int MiddleButtonDown=0;
static int RightButtonDown=0;
static int OldX,OldY;
static float Elevation=0;
static float Azimuth=0;
static float DistX=0;
static float DistY=0;
static float DistZ=2;

// VISUALIZATION SETTINGS

static float boundingBoxMin[3];
static float boundingBoxMax[3];
static float boundingBoxHeight;
static float boundingBoxScale=1.0f;
static float boundingBoxTranslateX = 0.0f;
static float boundingBoxTranslateY = 0.0f;
static float boundingBoxTranslateZ = 0.0f;

// GLOBAL CONTROL VARIABLES

static int WindowW=1024, WindowH=768;
static int InteractionMode=0;
static int AnimationOn=0;
static int WorkingOn=0;

// COLORS

static float colours_diffuse[10][4];
static float colours_white[4];
static float colours_light_blue[4];

// DATA STORAGE FOR STREAM VISUALIZER OUTPUT

static FILE* file = 0;
static char* file_name = 0;
static LASreader* lasreader = 0;

static int p_count = 0;
static int npoints = 0;
static float* point_buffer = 0;
static int point_buffer_alloc = 0;

static bool only_first = false;
static bool only_last = false;

static int EXACTLY_N_STEPS = 100;
static int EVERY_NTH_STEP = -1;
static int NEXT_STEP;

static int EXACTLY_N_POINTS = 1000000;
static int EVERY_NTH_POINT = 0;
static int NEXT_POINT;

static int DIRTY_POINTS=1;
static int REPLAY_IT=0;
static int REPLAY_COUNT=0;
static int STREAM_COLORING = 3;
static int POINT_SIZE = 2;
static int RENDER_BOUNDINGBOX = 1;
static int EXTRA_Z_SCALE = 1;

static void InitColors()
{
  colours_diffuse[0][0] = 0.0f; colours_diffuse[0][1] = 0.0f; colours_diffuse[0][2] = 0.0f; colours_diffuse[0][3] = 1.0f; // black
  colours_diffuse[1][0] = 0.6f; colours_diffuse[1][1] = 0.0f; colours_diffuse[1][2] = 0.0f; colours_diffuse[1][3] = 1.0f; // red
  colours_diffuse[2][0] = 0.0f; colours_diffuse[2][1] = 0.8f; colours_diffuse[2][2] = 0.0f; colours_diffuse[2][3] = 1.0f; // green
  colours_diffuse[3][0] = 0.0f; colours_diffuse[3][1] = 0.0f; colours_diffuse[3][2] = 0.6f; colours_diffuse[3][3] = 1.0f; // blue
  colours_diffuse[4][0] = 0.6f; colours_diffuse[4][1] = 0.6f; colours_diffuse[4][2] = 0.0f; colours_diffuse[4][3] = 1.0f; // yellow
  colours_diffuse[5][0] = 0.6f; colours_diffuse[5][1] = 0.0f; colours_diffuse[5][2] = 0.6f; colours_diffuse[5][3] = 1.0f; // purple
  colours_diffuse[6][0] = 0.0f; colours_diffuse[6][1] = 0.6f; colours_diffuse[6][2] = 0.6f; colours_diffuse[6][3] = 0.3f; // cyan (tranparent)
  colours_diffuse[7][0] = 0.7f; colours_diffuse[7][1] = 0.7f; colours_diffuse[7][2] = 0.7f; colours_diffuse[7][3] = 1.0f; // white
  colours_diffuse[8][0] = 0.2f; colours_diffuse[8][1] = 0.2f; colours_diffuse[8][2] = 0.6f; colours_diffuse[8][3] = 1.0f; // light blue
  colours_diffuse[9][0] = 0.9f; colours_diffuse[9][1] = 0.4f; colours_diffuse[9][2] = 0.7f; colours_diffuse[9][3] = 0.5f; // violett
  
  colours_white[0] = 0.7f; colours_white[1] = 0.7f; colours_white[2] = 0.7f; colours_white[3] = 1.0f; // white
  colours_light_blue[0] = 0.2f; colours_light_blue[1] = 0.2f; colours_light_blue[2] = 0.6f; colours_light_blue[3] = 1.0f; // light blue
}

static void InitLight()
{
  float intensity[] = {1,1,1,1};
  float position[] = {1,1,5,0}; // directional behind the viewer
  glLightfv(GL_LIGHT0,GL_DIFFUSE,intensity);
  glLightfv(GL_LIGHT0,GL_SPECULAR,intensity);
  glLightfv(GL_LIGHT0,GL_POSITION,position);
  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_FALSE);
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
}

static void usage()
{
  fprintf(stderr,"usage:\n");
  fprintf(stderr,"lasview -i terrain.las\n");
  fprintf(stderr,"lasview -i terrain.las -win 1600 1200 -steps 10 -points 200000\n");
  fprintf(stderr,"lasview -h\n");
  fprintf(stderr,"\n");
}

static void vizBegin()
{
  REPLAY_IT = 0; // just making sure
  DIRTY_POINTS = 1;

  if (file_name)
  {
    fprintf(stderr,"loading '%s'...\n",file_name);
    if (strstr(file_name, ".gz"))
    {
#ifdef _WIN32
      file = fopenGzipped(file_name, "rb");
#else
      fprintf(stderr,"ERROR: cannot open gzipped file %s\n",file_name);
      exit(1);
#endif
    }
    else
    {
      file = fopen(file_name, "rb");
    }
    if (file == 0)
    {
      fprintf(stderr,"ERROR: cannot open %s\n",file_name);
      exit(1);
    }
    lasreader = new LASreader();
    if (lasreader->open(file) == false)
    {
      fprintf(stderr,"ERROR: no input\n");
      exit(1);
    }
  }
  else
  {
    fprintf(stderr,"ERROR: no input\n");
    exit(1);
  }
  
  // scale and translate bounding box for rendering

  boundingBoxMin[0] = lasreader->header.min_x;
  boundingBoxMin[1] = lasreader->header.min_y;
  boundingBoxMin[2] = lasreader->header.min_z;

  boundingBoxMax[0] = lasreader->header.max_x;
  boundingBoxMax[1] = lasreader->header.max_y;
  boundingBoxMax[2] = lasreader->header.max_z;

  boundingBoxHeight = boundingBoxMax[2]-boundingBoxMin[2];

  if ((boundingBoxMax[1]-boundingBoxMin[1]) > (boundingBoxMax[0]-boundingBoxMin[0]))
  {
    if ((boundingBoxMax[1]-boundingBoxMin[1]) > (boundingBoxMax[2]-boundingBoxMin[2]))
    {
      boundingBoxScale = 1.0f/(boundingBoxMax[1]-boundingBoxMin[1]);
    }
    else
    {
      boundingBoxScale = 1.0f/(boundingBoxMax[2]-boundingBoxMin[2]);
    }
  }
  else
  {
    if ((boundingBoxMax[0]-boundingBoxMin[0]) > (boundingBoxMax[2]-boundingBoxMin[2]))
    {
      boundingBoxScale = 1.0f/(boundingBoxMax[0]-boundingBoxMin[0]);
    }
    else
    {
      boundingBoxScale = 1.0f/(boundingBoxMax[2]-boundingBoxMin[2]);
    }
  }
  boundingBoxTranslateX = - boundingBoxScale * (boundingBoxMin[0] + 0.5f * (boundingBoxMax[0]-boundingBoxMin[0]));
  boundingBoxTranslateY = - boundingBoxScale * (boundingBoxMin[1] + 0.5f * (boundingBoxMax[1]-boundingBoxMin[1]));
  boundingBoxTranslateZ = - boundingBoxScale * (boundingBoxMin[2] + 0.5f * (boundingBoxMax[2]-boundingBoxMin[2]));

  p_count = 0;
  npoints = lasreader->npoints;

  fprintf(stderr,"number of points in file %d\n", npoints);

  if (EVERY_NTH_STEP == -1)
  {
    EVERY_NTH_STEP = npoints / EXACTLY_N_STEPS;
  }
  if (EVERY_NTH_STEP == 0)
  {
    EVERY_NTH_STEP = 1;
  }
  NEXT_STEP = EVERY_NTH_STEP;

  if (EXACTLY_N_POINTS)
  {
    EVERY_NTH_POINT = npoints/EXACTLY_N_POINTS;
  }
  if (EVERY_NTH_POINT == 0)
  {
    EVERY_NTH_POINT = 1;
  }
  NEXT_POINT = 0;

  // make sure we have enough memory

  if (point_buffer_alloc < ((npoints / EVERY_NTH_POINT) + 500))
  {
    if (point_buffer) free(point_buffer);
    point_buffer_alloc = ((npoints / EVERY_NTH_POINT) + 500);
    point_buffer = (float*)malloc(sizeof(float)*3*point_buffer_alloc);
  }
}

static void vizEnd()
{
  REPLAY_IT = 0; // just making sure
  REPLAY_COUNT = p_count;
  DIRTY_POINTS = 0;

  fprintf(stderr,"number of points sampled %d\n",p_count);

  lasreader->close();
  fclose(file);
  delete lasreader;
  lasreader = 0;
}

static int vizContinue()
{
  int more;
  REPLAY_IT = 0; // just making sure

  while (more = lasreader->read_point(&(point_buffer[p_count*3])))
  {
    if (lasreader->p_count > NEXT_POINT)
    {
      p_count++;
      NEXT_POINT += ((EVERY_NTH_POINT/2) + (rand()%EVERY_NTH_POINT) + 1);
    }

    if (lasreader->p_count > NEXT_STEP)
    {
      NEXT_STEP += EVERY_NTH_STEP;
      break;
    }
  }

  return more;
}

static void myReshape(int w, int h)
{
  glutReshapeWindow(WindowW,WindowH);
}

static void myIdle()
{
  if (AnimationOn)
  {
    AnimationOn = vizContinue();
    if (!AnimationOn)
    {
      WorkingOn = 0;
      vizEnd();
    }
    glutPostRedisplay();
  }
  else if (REPLAY_IT)
  {
    REPLAY_COUNT += NEXT_STEP;
    glutPostRedisplay();
  }
}

static void full_resolution_rendering()
{
  if (file_name == 0)
  {
    fprintf(stderr,"ERROR: no input file\n");
  }

  int p_count;

  if (lasreader)
  {
    p_count = lasreader->p_count;
    fprintf(stderr,"out-of-core rendering of %d points ... \n",p_count);
    lasreader->close();
    fclose(file);
    delete lasreader;
    lasreader = 0;
  }
  else
  {
    p_count = 2000000000;
    fprintf(stderr,"out-of-core rendering of all points ... \n");
  }

  if (strstr(file_name, ".gz"))
  {
#ifdef _WIN32
    file = fopenGzipped(file_name, "rb");
#else
    fprintf(stderr,"ERROR: cannot open gzipped file %s\n",file_name);
    exit(1);
#endif
  }
  else
  {
    file = fopen(file_name, "rb");
  }
  if (file == 0)
  {
    fprintf(stderr,"ERROR: cannot open %s\n",file_name);
    exit(1);
  }
  lasreader = new LASreader();
  if (lasreader->open(file) == false)
  {
    fprintf(stderr,"ERROR: no input\n");
    exit(1);
  }

  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
  glViewport(0,0,WindowW,WindowH);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(30.0f,(float)WindowW/WindowH,0.0625f,5.0f);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(DistX,DistY,DistZ, DistX,DistY,0, 0,1,0);

  glRotatef(Elevation,1,0,0);
  glRotatef(Azimuth,0,1,0);

  glTranslatef(boundingBoxTranslateX,boundingBoxTranslateY,boundingBoxTranslateZ*EXTRA_Z_SCALE);
  glScalef(boundingBoxScale,boundingBoxScale,boundingBoxScale*EXTRA_Z_SCALE);

  glEnable(GL_DEPTH_TEST);

  if (p_count == 0)
  {
    p_count = lasreader->npoints;
  }

  double point[3];
  glBegin(GL_POINTS);
  glColor3f(0,0,0);
  while (lasreader->p_count < p_count)
  {
    if (lasreader->read_point(point))
    {
      glVertex3dv(point);
    }
    else
    {
      glEnd();
      lasreader->close();
      fclose(file);
      delete lasreader;
      lasreader = 0;
      glutSwapBuffers();
      return;
    }
  }
  glEnd();

  glDisable(GL_DEPTH_TEST);

  glutSwapBuffers();
}

static void myMouseFunc(int button, int state, int x, int y)
{
  OldX=x;
  OldY=y;        
  if (button == GLUT_LEFT_BUTTON)
  {
    LeftButtonDown = !state;
    MiddleButtonDown = 0;
    RightButtonDown = 0;
  }
  else if (button == GLUT_RIGHT_BUTTON)
  {
    LeftButtonDown = 0;
    MiddleButtonDown = 0;
    RightButtonDown = !state;
  }
  else if (button == GLUT_MIDDLE_BUTTON)
  {
    LeftButtonDown = 0;
    MiddleButtonDown = !state;
    RightButtonDown = 0;
  }
}

static void myMotionFunc(int x, int y)
{
  float RelX = (x-OldX) / (float)glutGet((GLenum)GLUT_WINDOW_WIDTH);
  float RelY = (y-OldY) / (float)glutGet((GLenum)GLUT_WINDOW_HEIGHT);
  OldX=x;
  OldY=y;
  if (LeftButtonDown) 
  { 
    if (InteractionMode == 0)
    {
      Azimuth += (RelX*180);
      Elevation += (RelY*180);
    }
    else if (InteractionMode == 1)
    {
      DistX-=RelX;
      DistY+=RelY;
    }
    else if (InteractionMode == 2)
    {
      DistZ-=RelY*DistZ;
    }
  }
  else if (MiddleButtonDown)
  {
    DistX-=RelX*1.0f;
    DistY+=RelY*1.0f;
  }
  glutPostRedisplay();
}

static void MyMenuFunc(int value);

static void myKeyboard(unsigned char Key, int x, int y)
{
  switch(Key)
  {
  case 'Q':
  case 'q':
  case 27:
    exit(0);
    break;
  case ' ': // rotate, translate, or zoom
    if (InteractionMode == 2)
    {
      InteractionMode = 0;
    }
    else
    {
      InteractionMode += 1;
    }
    glutPostRedisplay();
    break;
  case '>': //zoom in
    DistZ-=0.1f;
    break;
  case '<': //zoom out
    DistZ+=0.1f;
    break;
  case '_':
    break;
  case '+':
    break;
  case '-':
    POINT_SIZE -= 1;
    if (POINT_SIZE < 0) POINT_SIZE = 0;
    fprintf(stderr,"POINT_SIZE %d\n",POINT_SIZE);
    glutPostRedisplay();
    break;
  case '=':
    POINT_SIZE += 1;
    fprintf(stderr,"POINT_SIZE %d\n",POINT_SIZE);
    glutPostRedisplay();
    break;
  case '[':
    if (EXTRA_Z_SCALE > 1)
    {
      EXTRA_Z_SCALE = EXTRA_Z_SCALE >> 1;
      glutPostRedisplay();
    }
    fprintf(stderr,"EXTRA_Z_SCALE %d\n",EXTRA_Z_SCALE);
    break;
  case ']':
    EXTRA_Z_SCALE = EXTRA_Z_SCALE << 1;
    fprintf(stderr,"EXTRA_Z_SCALE %d\n",EXTRA_Z_SCALE);
    glutPostRedisplay();
    break;
  case 'O':
  case 'o':
    AnimationOn = 0;
    REPLAY_IT = 0;
    break;
  case 'B':
  case 'b':
    RENDER_BOUNDINGBOX = !RENDER_BOUNDINGBOX;
    fprintf(stderr,"RENDER_BOUNDINGBOX %d\n",RENDER_BOUNDINGBOX);
    break;
  case 'R':
  case 'r':
    if (file_name)
    {
      full_resolution_rendering();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -