static void
_dxf_DRAW_ARROWHEAD (void* ctx, float ax, float ay)
{
  double angle, hyp, length ;
  float x1, y1 ;
  float p[2] ;
  
  ENTRY(("_dxf_DRAW_ARROWHEAD(0x%x, %f, %f)",ctx, ax, ay));

  hyp = sqrt(ax*ax + ay*ay) ;

  if (hyp == 0.0) {
    EXIT(("hyp == 0.0"));
    return ;
  }
  
  if (hyp < 0.2)
      length = 0.06 ;
  else
      length = 0.12 ;
  
  angle = acos((double)(-ax/hyp)) ;
  if (ay > 0)
      angle = 2*M_PI - angle ;
  
  angle = angle + M_PI/6 ;
  if (angle > 2*M_PI)
      angle = angle - 2*M_PI ;

  x1 = cos(angle) * length ;
  y1 = sin(angle) * length ;
  
  bgnline() ;
  p[0] = ax ;      p[1] = ay ;      v2f(p) ;
  p[0] = ax + x1 ; p[1] = ay + y1 ; v2f(p) ;
  endline() ;
  
  angle = angle - M_PI/3 ;
  if (angle < 0)
      angle = angle + 2*M_PI ;

  x1 = cos(angle) * length ;
  y1 = sin(angle) * length ;
  
  bgnline() ;
  p[0] = ax ;      p[1] = ay ;      v2f(p) ;
  p[0] = ax + x1 ; p[1] = ay + y1 ; v2f(p) ;
  endline() ;

  EXIT((""));
}
Beispiel #2
0
void Edge::Draw(unsigned int stamp)
// This is a recursive drawing routine that uses time stamps to
// determine if the edge has already been drawn. This is given
// here for testing purposes only: it is not efficient, and for
// large triangulations the stack might overflow. A better way
// of doing this (and other traversals of the edges) is to maintain
// a list of edges in the corresponding Subdivision object. This
// list should be updated every time an edge is created or destroyed.
{
	if (Qedge()->TimeStamp(stamp)) {

		// Draw the edge
		Point2d a = Org2d();
		Point2d b = Dest2d();
		bgnline();
		v2d((double*)&a);
		v2d((double*)&b);
		endline();

		// visit neighbors
		Onext()->Draw(stamp);
		Oprev()->Draw(stamp);
		Dnext()->Draw(stamp);
		Dprev()->Draw(stamp);
	}
}
Beispiel #3
0
draw_o() {

    bgntmesh();
	v2f(o_data[0]);
	v2f(o_data[1]);
	v2f(o_data[2]);
	v2f(o_data[3]);
	v2f(o_data[4]);
	v2f(o_data[5]);
	v2f(o_data[6]);
	v2f(o_data[7]);
	v2f(o_data[8]);
	v2f(o_data[9]);
	v2f(o_data[10]);
	v2f(o_data[11]);
	v2f(o_data[12]);
	v2f(o_data[13]);
	v2f(o_data[14]);
	v2f(o_data[15]);
	v2f(o_data[16]);
	v2f(o_data[17]);
	v2f(o_data[18]);
	v2f(o_data[19]);
	v2f(o_data[20]);
	v2f(o_data[21]);
	v2f(o_data[22]);
	v2f(o_data[23]);
	v2f(o_data[24]);
	v2f(o_data[25]);
	v2f(o_data[26]);
	v2f(o_data[27]);
	v2f(o_data[28]);
	v2f(o_data[29]);
	v2f(o_data[30]);
	v2f(o_data[31]);
	v2f(o_data[32]);
    endtmesh();

    bgnline();
	v2f(o_data[0]);
	v2f(o_data[2]);
	v2f(o_data[4]);
	v2f(o_data[6]);
	v2f(o_data[8]);
	v2f(o_data[10]);
	v2f(o_data[12]);
	v2f(o_data[14]);
	v2f(o_data[16]);
	v2f(o_data[18]);
	v2f(o_data[20]);
	v2f(o_data[22]);
	v2f(o_data[24]);
	v2f(o_data[26]);
	v2f(o_data[28]);
	v2f(o_data[30]);
	v2f(o_data[32]);
	v2f(o_data[31]);
	v2f(o_data[29]);
	v2f(o_data[27]);
	v2f(o_data[25]);
	v2f(o_data[23]);
	v2f(o_data[21]);
	v2f(o_data[19]);
	v2f(o_data[17]);
	v2f(o_data[15]);
	v2f(o_data[13]);
	v2f(o_data[11]);
	v2f(o_data[9]);
	v2f(o_data[7]);
	v2f(o_data[5]);
	v2f(o_data[3]);
	v2f(o_data[1]);
    endline();

}
static void 
_dxf_DRAW_GNOMON (tdmInteractor I, void *udata, float rot[4][4], int draw)
{
  /*
   *  draw == 1 to draw gnomon, draw == 0 to undraw.  This is done with
   *  two separate calls in order to support explicit erasure of edges for
   *  some implementations.  A draw is always preceded by an undraw and
   *  the pair of invocations is atomic.
   *
   *  Computations are done in normalized screen coordinates in order to
   *  render arrow heads correctly.
   */

  DEFDATA(I,tdmRotateData) ;
  DEFPORT(I_PORT_HANDLE) ;
  int dummy = 0 ;
  float origin[2] ;
  float xaxis[2],  yaxis[2],  zaxis[2] ;
  float xlabel[2], ylabel[2], zlabel[2] ;

  ENTRY(("_dxf_DRAW_GNOMON (0x%x, 0x%x, 0x%x, %d)",I, udata, rot, draw));

  if (PDATA(font) == -1)
    {
      /* font width for axes labels in normalized coordinates */
      font(0) ;
      PDATA(font) = 0 ;
      PDATA(swidth) = (float)strwidth("Z")/(float)GNOMONRADIUS ;

      /* 1 pixel in normalized coordinates */
      PDATA(nudge) = 1.0/(float)GNOMONRADIUS ;
    }
  else
      font(PDATA(font)) ;
  
  if (draw)
    {
      lmcolor(LMC_COLOR) ;
      cpack(0xffffffff) ;
      linewidth(1) ;
    }
  else
    {
      if (PDATA(redrawmode) != tdmViewEchoMode)
	{
	  /*
	   *  In tdmViewEchoMode (DX's Execute On Change), we are drawing
	   *  the gnomon echo on top of a background image that is redrawn
	   *  with every frame of a direct interaction.
	   *
	   *  If we're not in that mode, the background image is static
	   *  while the gnomon echo rotates in front of it, so erasing the
	   *  gnomon means we have to repair damage to the background.  We
	   *  do this by blitting a portion of the static image to the
	   *  back buffer, drawing the gnomon over that, then blitting the
	   *  combined results back to the front buffer.
	   */
	  
	  /* force graphics output into back buffer */
	  frontbuffer(FALSE) ;
	  backbuffer(TRUE) ;
	  
	  /* erase gnomon background */
	  lrectwrite (PDATA(illx), PDATA(illy),
		      PDATA(iurx), PDATA(iury), PDATA(background)) ;
	}

#ifndef NOSHADOW      
      /* draw wide black lines to ensure visibility against background */
      lmcolor(LMC_COLOR) ;
      cpack(0x0) ;
      linewidth(2) ;
#else
      EXIT(("No shadow"));
      return ;
#endif
    }

  origin[0] = 0 ;
  origin[1] = 0 ;

  xaxis[0] = 0.7 * rot[0][0] ; xaxis[1] = 0.7 * rot[0][1] ;
  yaxis[0] = 0.7 * rot[1][0] ; yaxis[1] = 0.7 * rot[1][1] ;
  zaxis[0] = 0.7 * rot[2][0] ; zaxis[1] = 0.7 * rot[2][1] ;

  xlabel[0] = 0.8 * rot[0][0] ; xlabel[1] = 0.8 * rot[0][1] ;
  ylabel[0] = 0.8 * rot[1][0] ; ylabel[1] = 0.8 * rot[1][1] ;
  zlabel[0] = 0.8 * rot[2][0] ; zlabel[1] = 0.8 * rot[2][1] ;

  pushmatrix() ;
  loadmatrix(identity) ;
  bgnline() ; v2f(origin) ; v2f(xaxis) ; endline() ;
  _dxf_DRAW_ARROWHEAD(PORT_CTX, xaxis[0], xaxis[1]) ;

  bgnline() ; v2f(origin) ; v2f(yaxis) ; endline() ;
  _dxf_DRAW_ARROWHEAD(PORT_CTX, yaxis[0], yaxis[1]) ;

  bgnline() ; v2f(origin) ; v2f(zaxis) ; endline() ;
  _dxf_DRAW_ARROWHEAD(PORT_CTX, zaxis[0], zaxis[1]) ;
  
  if (xlabel[0] <= 0) xlabel[0] -= PDATA(swidth) ;
  if (xlabel[1] <= 0) xlabel[1] -= PDATA(swidth) ;
  
  if (ylabel[0] <= 0) ylabel[0] -= PDATA(swidth) ;
  if (ylabel[1] <= 0) ylabel[1] -= PDATA(swidth) ;
  
  if (zlabel[0] <= 0) zlabel[0] -= PDATA(swidth) ;
  if (zlabel[1] <= 0) zlabel[1] -= PDATA(swidth) ;

#ifndef NOSHADOW  
  if (!draw)
    {
      /* offset text slightly for shadow */
      xlabel[0] += PDATA(nudge) ; xlabel[1] -= PDATA(nudge) ;
      ylabel[0] += PDATA(nudge) ; ylabel[1] -= PDATA(nudge) ;
      zlabel[0] += PDATA(nudge) ; zlabel[1] -= PDATA(nudge) ;
    }
#endif

  font(0) ;
  cmov2 (xlabel[0], xlabel[1]) ;
  charstr ("X") ;
  cmov2 (ylabel[0], ylabel[1]) ;
  charstr ("Y") ;
  cmov2 (zlabel[0], zlabel[1]) ;
  charstr ("Z") ;

  popmatrix() ;

  if (draw && PDATA(redrawmode) != tdmViewEchoMode)
    {
      /* copy rendered gnomon from back buffer to front buffer */
      readsource(SRC_BACK) ;
      frontbuffer(TRUE) ;
      backbuffer(FALSE) ;
      rectcopy (PDATA(illx), PDATA(illy), PDATA(iurx), PDATA(iury),
		PDATA(illx), PDATA(illy)) ;

      /* restore original buffer config from current tdmFrontBufferDraw */
      _dxf_BUFFER_RESTORE_CONFIG
	  (PORT_CTX, dummy, PDATA(buffermode), tdmFrontBufferDraw) ;
    }

  EXIT((""));
} 
static void 
_dxf_DRAW_GLOBE (tdmInteractor I, void *udata, float rot[4][4], int draw)
{
  /*
   *  draw == 1 to draw globe, draw == 0 to undraw.  This is done with two
   *  separate calls in order to support explicit erasure of edges for
   *  some implementations.  A draw is always preceded by an undraw and
   *  the pair of invocations is atomic.
   */

  DEFDATA(I,tdmRotateData) ;
  DEFPORT(I_PORT_HANDLE) ;
  int u, v, on, dummy = 0 ;

  /* globe edge visibility flags.  all globe instance share this data. */
  static struct {
    int latvis, longvis ;
  } edges[LATS][LONGS] ;

  /* globe and globeface defined in tdmGlobeEchoDef.h */
  register const float (*Globe)[LONGS][3] = globe ;
  register const struct Face (*Globeface)[LONGS] = globeface ;

  /* view normal */
  register float z0, z1, z2 ;
  z0 = rot[0][2] ; z1 = rot[1][2] ; z2 = rot[2][2] ;

#define FACEVISIBLE(u,v,z0,z1,z2) \
  (Globeface[u][v].norm[0] * z0 + \
   Globeface[u][v].norm[1] * z1 + \
   Globeface[u][v].norm[2] * z2 > 0.0)

  ENTRY(("_dxf_DRAW_GLOBE (0x%x, 0x%x, 0x%x, %d)",I, udata, rot, draw));

  if (draw)
    {
      lmcolor(LMC_COLOR) ;
      cpack(0xffffffff) ;
      linewidth(1) ;
    }
  else
    {
      if (PDATA(redrawmode) != tdmViewEchoMode)
	{
	  /*
	   *  In tdmViewEchoMode (DX's Execute On Change), we are drawing
	   *  the globe echo on top of a background image that is redrawn
	   *  with every frame of a direct interaction.
	   *
	   *  If we're not in that mode, the background image is static
	   *  while the globe echo rotates in front of it, so erasing the
	   *  globe means we have to repair damage to the background.  We
	   *  do this by blitting a portion of the static image to the
	   *  back buffer, drawing the globe over that, then blitting the
	   *  combined results back to the front buffer.
	   */
	  
	  /* force graphics output into back (draw) buffer */
	  frontbuffer(FALSE) ;
	  backbuffer(TRUE) ;
	  
	  /* erase globe background */
	  lrectwrite (PDATA(illx), PDATA(illy),
		      PDATA(iurx), PDATA(iury), PDATA(background)) ;
	}

#ifndef NOSHADOW      
      /* draw wide black lines to ensure visibility against background */
      lmcolor(LMC_COLOR) ;
      cpack(0x0) ;
      linewidth(2) ;
#else
      EXIT(("No shadow"));
      return ;
#endif
    }

#ifndef FACEVIS
  /*
   *  Compute visible edges explicitly.  This method might be faster and
   *  works in XOR mode but as implemented here is applicable only for a
   *  globe-type object rendered with latitude and longitude lines.
   */
#ifndef NOSHADOW
  if (!draw)
#endif
      for (u=0 ; u<LATS-1 ; u++)
	{
	  if (FACEVISIBLE(u, 0, z0, z1, z2))
	    {
	      edges[u][LONGS-1].latvis++ ;
	      edges[u+1][LONGS-1].latvis++ ;
	      edges[u][0].longvis++ ;
	      edges[u][LONGS-1].longvis++ ;
	    }
	  for (v=1 ; v<LONGS ; v++)
	      if (FACEVISIBLE(u, v, z0, z1, z2))
		{
		  edges[u][v-1].latvis++ ;
		  edges[u+1][v-1].latvis++ ;
		  edges[u][v].longvis++ ;
		  edges[u][v-1].longvis++ ;
		}
	}

  /* north pole */
  if (z1 > 0.0)
      for (v=0 ; v<LONGS ; v++)
	  edges[LATS-1][v].latvis++ ;

  /* south pole */
  if (z1 < 0.0)
      for (v=0 ; v<LONGS ; v++)
	  edges[0][v].latvis++ ;

  /*
   *  Draw each visible edge exactly once.
   */
  for (u=0 ; u<LATS ; u++)
    {
      for (v=0, on=0 ; v<LONGS-1 ; v++)
	  if (edges[u][v].latvis)
	    {
	      if (!on)
		{
		  on = 1 ;
		  bgnline() ;
		  v3f(Globe[u][v]) ;
		}
	      v3f (Globe[u][v+1]) ;
#ifndef NOSHADOW
	      if (draw)
#endif
		  edges[u][v].latvis = 0 ;
	    }
	  else if (on)
	    {
	      on = 0 ;
	      endline() ;
	    }

      /* close latitude line if necessary */
      if (edges[u][LONGS-1].latvis)
	{
	  if (!on)
	    {
	      bgnline() ;
	      v3f(Globe[u][LONGS-1]) ;
	    }
	  v3f (Globe[u][0]) ;
	  endline() ;
#ifndef NOSHADOW
	  if (draw)
#endif
	      edges[u][LONGS-1].latvis = 0 ;
	}
      else if (on)
	  endline() ;
    }
      
  /* longitude lines */
  for (v=0 ; v<LONGS ; v++)
    {
      for (u=0, on=0 ; u<LATS-1 ; u++)
	  if (edges[u][v].longvis)
	    {
	      if (!on)
		{
		  on = 1 ;
		  bgnline() ;
		  v3f(Globe[u][v]) ;
		}
	      v3f(Globe[u+1][v]) ;
#ifndef NOSHADOW
	      if (draw)
#endif
		  edges[u][v].longvis = 0 ;
	    }
	  else if (on)
	    {
	      on = 0 ;
	      endline() ;
	    }
      if (on)
	  endline() ;
    }
#else  
  /*
   *  Do it the easy way:  draw all visible faces regardless of shared
   *  edges.  Most edges are drawn twice, so this is slower and not
   *  compatible with XOR rendering.
   */
  for (u=0 ; u<LATS-1 ; u++)
      for (v=0 ; v<LONGS ; v++)
	  if (FACEVISIBLE(u, v, z0, z1, z2))
	      poly (4, Globeface[u][v].face) ;

  /* north pole */
  if (z1 > 0.0)
      poly (LONGS, Globe[LATS-1]) ;

  /* south pole */
  if (z1 < 0.0)
      poly (LONGS, Globe[0]) ;

#endif /* ifndef FACEVIS */

  if (draw && PDATA(redrawmode) != tdmViewEchoMode)
    {
      /* copy rendered globe from back buffer to front buffer */
      readsource(SRC_BACK) ;
      frontbuffer(TRUE) ;
      backbuffer(FALSE) ;
      rectcopy (PDATA(illx), PDATA(illy), PDATA(iurx), PDATA(iury),
		PDATA(illx), PDATA(illy)) ;

      /* restore original buffer config from current tdmFrontBufferDraw */
      _dxf_BUFFER_RESTORE_CONFIG
	  (PORT_CTX, dummy, PDATA(buffermode), tdmFrontBufferDraw) ;
    }
  EXIT((""));
}