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

📄 slicer.cc

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 CC
📖 第 1 页 / 共 2 页
字号:
/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
**
** http://oss.sgi.com/projects/FreeB
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
**
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
*/

/*
 * slicer.c++
 *
 * $Date: 2006-03-11 18:07:02 -0600 (Sat, 11 Mar 2006) $ $Revision: 1.1 $
 * $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/internals/slicer.cc,v 1.1 2004/02/02 16:39:12 navaraf Exp $
 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "glimports.h"
#include "mystdio.h"
#include "myassert.h"
#include "bufpool.h"
#include "slicer.h"
#include "backend.h"
#include "arc.h"
#include "gridtrimvertex.h"
#include "simplemath.h"
#include "trimvertex.h"
#include "varray.h"

#include "polyUtil.h" //for area()

//static int count=0;

/*USE_OPTTT is initiated in trimvertex.h*/

#ifdef USE_OPTTT
	#include <GL/gl.h>
#endif

//#define USE_READ_FLAG //whether to use new or old tesselator
                          //if defined, it reads "flagFile", 
                          // if the number is 1, then use new tess
                          // otherwise, use the old tess.
                         //if not defined, then use new tess.
#ifdef USE_READ_FLAG
static Int read_flag(char* name);
Int newtess_flag = read_flag("flagFile");
#endif

//#define COUNT_TRIANGLES
#ifdef COUNT_TRIANGLES
Int num_triangles = 0;
Int num_quads = 0;
#endif

#define max(a,b) ((a>b)? a:b)
#define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/
#define equalRect(a,b) ((glu_abs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle

/******triangulate a monotone polygon**************/
#include "monoTriangulation.h"

inline int compInY(REAL a[2], REAL b[2])
{
  if(a[1] < b[1])
    return -1;
  else if (a[1] > b[1])
    return 1;
  else if(a[0] > b[0])
    return 1;
  else return -1;
}

void monoTriangulationLoop(Arc_ptr loop, Backend& backend, primStream* pStream)
{
  int i;
  //find the top, bottom, increasing and decreasing chain
  //then call monoTrianulation
  Arc_ptr jarc, temp;
  Arc_ptr top;
  Arc_ptr bot;
  top = bot = loop;
  if(compInY(loop->tail(), loop->prev->tail()) < 0)
    {
      //first find bot
      for(temp = loop->next; temp != loop; temp = temp->next)
	{
	  if(compInY(temp->tail(), temp->prev->tail()) > 0)
	    break;
	}
      bot = temp->prev;
      //then find top
      for(temp=loop->prev; temp != loop; temp = temp->prev)
	{
	  if(compInY(temp->tail(), temp->prev->tail()) > 0)
	    break;
	}
      top = temp;
    }
  else //loop > loop->prev
    {
      for(temp=loop->next; temp != loop; temp = temp->next)
	{
	  if(compInY(temp->tail(), temp->prev->tail()) < 0)
	    break;
	}
      top = temp->prev;
      for(temp=loop->prev; temp != loop; temp = temp->prev)
	{
	  if(compInY(temp->tail(), temp->prev->tail()) < 0)
	    break;
	}
      bot = temp;
    }
  //creat increase and decrease chains
  vertexArray inc_chain(50); //this is a dynamci array
  for(i=1; i<=top->pwlArc->npts-2; i++) 
    {
      //the first vertex is the top which doesn't below to inc_chain
      inc_chain.appendVertex(top->pwlArc->pts[i].param);
    }
  for(jarc=top->next; jarc != bot; jarc = jarc->next)
    {
      for(i=0; i<=jarc->pwlArc->npts-2; i++)
	{
	  inc_chain.appendVertex(jarc->pwlArc->pts[i].param);
	}
      
    }
  vertexArray dec_chain(50);
  for(jarc = top->prev; jarc != bot; jarc = jarc->prev)
    {
      for(i=jarc->pwlArc->npts-2; i>=0; i--)
	{
	  dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
	}
    }
  for(i=bot->pwlArc->npts-2; i>=1; i--)
    {
      dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
    }	  

  monoTriangulationRec(top->tail(), bot->tail(), &inc_chain, 0,
		       &dec_chain, 0, &backend);

}

/********tesselate a rectanlge (OPTIMIZATION**************/
static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend);

static Int is_rect(Arc_ptr loop)
{
  Int nlines =1;
  for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next)
    {
      nlines++;
      if(nlines == 5)
	break;
    }
  if(nlines != 4)
    return 0;


/*
printf("here1\n");
printf("loop->tail=(%f,%f)\n", loop->tail()[0], loop->tail()[1]);
printf("loop->head=(%f,%f)\n", loop->head()[0], loop->head()[1]);
printf("loop->next->tail=(%f,%f)\n", loop->next->tail()[0], loop->next->tail()[1]);
printf("loop->next->head=(%f,%f)\n", loop->next->head()[0], loop->next->head()[1]);
if(fglu_abs(loop->tail()[0] - loop->head()[0])<0.000001)
	printf("equal 1\n");
if(loop->next->tail()[1] == loop->next->head()[1])
	printf("equal 2\n");
*/

  if( (glu_abs(loop->tail()[0] - loop->head()[0])<=ZERO) && 
      (glu_abs(loop->next->tail()[1] - loop->next->head()[1])<=ZERO) &&
      (glu_abs(loop->prev->tail()[1] - loop->prev->head()[1])<=ZERO) &&
      (glu_abs(loop->prev->prev->tail()[0] - loop->prev->prev->head()[0])<=ZERO)
     )
    return 1;
  else if
    ( (glu_abs(loop->tail()[1] - loop->head()[1]) <= ZERO) && 
      (glu_abs(loop->next->tail()[0] - loop->next->head()[0]) <= ZERO) &&
      (glu_abs(loop->prev->tail()[0] - loop->prev->head()[0]) <= ZERO) &&
      (glu_abs(loop->prev->prev->tail()[1] - loop->prev->prev->head()[1]) <= ZERO)
     )
      return 1;
  else
    return 0;
}

inline void  OPT_OUTVERT(TrimVertex& vv, Backend& backend) 
{

#ifdef USE_OPTTT
  glNormal3fv(vv.cache_normal);                         
  glVertex3fv(vv.cache_point);
#else

  backend.tmeshvert(&vv);

#endif

}

static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend);

static void triangulateRect(Arc_ptr loop, Backend& backend, int TB_or_LR, int ulinear, int vlinear)
{
  //we know the loop is a rectangle, but not sure which is top
  Arc_ptr top, bot, left, right;
  if(loop->tail()[1] == loop->head()[1])
    {
      if(loop->tail()[1] > loop->prev->prev->tail()[1])
	{

	top = loop;
	}
      else{

	top = loop->prev->prev;
	}
    }
  else 
    {
      if(loop->tail()[0] > loop->prev->prev->tail()[0])
	{
	  //loop is the right arc

	  top = loop->next;
	}
      else
	{

	  top = loop->prev;
	}
    }
  left = top->next;
  bot  = left->next;
  right= bot->next;

  //if u, v are both nonlinear, then if the
  //boundary is tessellated dense, we also
  //sample the inside to get a better tesslletant.
  if( (!ulinear) && (!vlinear))
    {
      int nu = top->pwlArc->npts;
      if(nu < bot->pwlArc->npts)
	nu = bot->pwlArc->npts;
      int nv = left->pwlArc->npts;
      if(nv < right->pwlArc->npts)
	nv = right->pwlArc->npts;
/*
      if(nu > 2 && nv > 2)
	{
	  triangulateRectGen(top, nu-2,  nv-2, backend);
	  return;
	}
*/
    }

  if(TB_or_LR == 1)
    triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
  else if(TB_or_LR == -1)
    triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);    
  else
    {
      Int maxPointsTB = top->pwlArc->npts + bot->pwlArc->npts;
      Int maxPointsLR = left->pwlArc->npts + right->pwlArc->npts;
      
      if(maxPointsTB < maxPointsLR)
	triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);    
      else
	triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
    }
}

static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend)
{ //if(maxPointsTB >= maxPointsLR)
    {

      Int d, topd_left, topd_right, botd_left, botd_right, i,j;
      d = left->npts /2;

#ifdef USE_OPTTT
      evalLineNOGE(top->pts, top->npts, backend);
      evalLineNOGE(bot->pts, bot->npts, backend);
      evalLineNOGE(left->pts, left->npts, backend);
      evalLineNOGE(right->pts, right->npts, backend);
#endif

      if(top->npts == 2) {
	backend.bgntfan();
	OPT_OUTVERT(top->pts[0], backend);//the root
	for(i=0; i<left->npts; i++){
	  OPT_OUTVERT(left->pts[i], backend);
	}
	for(i=1; i<= bot->npts-2; i++){
	  OPT_OUTVERT(bot->pts[i], backend);
	}
	backend.endtfan();
	
	backend.bgntfan();
	OPT_OUTVERT(bot->pts[bot->npts-2], backend);
	for(i=0; i<right->npts; i++){
	  OPT_OUTVERT(right->pts[i], backend);
	}
	backend.endtfan();
      }
      else if(bot->npts == 2) {
	backend.bgntfan();
	OPT_OUTVERT(bot->pts[0], backend);//the root
	for(i=0; i<right->npts; i++){
	  OPT_OUTVERT(right->pts[i], backend);
	}
	for(i=1; i<= top->npts-2; i++){
	  OPT_OUTVERT(top->pts[i], backend);
	}
	backend.endtfan();
	
	backend.bgntfan();
	OPT_OUTVERT(top->pts[top->npts-2], backend);
	for(i=0; i<left->npts; i++){
	  OPT_OUTVERT(left->pts[i], backend);
	}
	backend.endtfan();
      }
      else { //both top and bot have >=3 points
	
	backend.bgntfan();
	
	OPT_OUTVERT(top->pts[top->npts-2], backend);
	
	for(i=0; i<=d; i++)
	  {
	    OPT_OUTVERT(left->pts[i], backend);	  
	  }
	backend.endtfan();
	
	backend.bgntfan();
	
	OPT_OUTVERT(bot->pts[1], backend);
	
	OPT_OUTVERT(top->pts[top->npts-2], backend);
	
	for(i=d; i< left->npts; i++)
	  {      
	    OPT_OUTVERT(left->pts[i], backend);      
	  }
	backend.endtfan();

	d = right->npts/2;
	//output only when d<right->npts-1 and
	//
	if(d<right->npts-1)
	  {	
	    backend.bgntfan();
	    //      backend.tmeshvert(& top->pts[1]);
	    OPT_OUTVERT(top->pts[1], backend);
	    for(i=d; i< right->npts; i++)
	      {
		//	  backend.tmeshvert(& right->pts[i]);
		
		OPT_OUTVERT(right->pts[i], backend);
		
	      }
	    backend.endtfan();
	  }
	
	backend.bgntfan();
	//      backend.tmeshvert(& bot->pts[bot->npts-2]);
	OPT_OUTVERT( bot->pts[bot->npts-2], backend);
	for(i=0; i<=d; i++)
	  {
	    //	  backend.tmeshvert(& right->pts[i]);
	    OPT_OUTVERT(right->pts[i], backend);
	    
	  }
	
	//      backend.tmeshvert(& top->pts[1]);
	OPT_OUTVERT(top->pts[1], backend);      
	
	backend.endtfan();


	topd_left = top->npts-2;
	topd_right = 1; //topd_left>= topd_right

	botd_left = 1;
	botd_right = bot->npts-2; //botd_left<= bot_dright

	
	if(top->npts < bot->npts)
	  {
	    int delta=bot->npts - top->npts;
	    int u = delta/2;
	    botd_left = 1+ u;
	    botd_right = bot->npts-2-( delta-u);	    
	
	    if(botd_left >1)
	      {
		backend.bgntfan();
		//	  backend.tmeshvert(& top->pts[top->npts-2]);
		OPT_OUTVERT(top->pts[top->npts-2], backend);
		for(i=1; i<= botd_left; i++)
		  {
		    //	      backend.tmeshvert(& bot->pts[i]);
		    OPT_OUTVERT(bot->pts[i] , backend);
		  }
		backend.endtfan();
	      }
	    if(botd_right < bot->npts-2)
	      {
		backend.bgntfan();
		OPT_OUTVERT(top->pts[1], backend);
		for(i=botd_right; i<= bot->npts-2; i++)
		  OPT_OUTVERT(bot->pts[i], backend);
		backend.endtfan();
	      }
	  }
	else if(top->npts> bot->npts)
	  {
	    int delta=top->npts-bot->npts;
	    int u = delta/2;
	    topd_left = top->npts-2 - u;
	    topd_right = 1+delta-u;
	    
	    if(topd_left < top->npts-2)
	      {
		backend.bgntfan();
		//	  backend.tmeshvert(& bot->pts[1]);
		OPT_OUTVERT(bot->pts[1], backend);
		for(i=topd_left; i<= top->npts-2; i++)
		  {
		    //	      backend.tmeshvert(& top->pts[i]);
		    OPT_OUTVERT(top->pts[i], backend);
		  }
		backend.endtfan();
	      }
	    if(topd_right > 1)
	      {
		backend.bgntfan();
		OPT_OUTVERT(bot->pts[bot->npts-2], backend);
		for(i=1; i<= topd_right; i++)
		  OPT_OUTVERT(top->pts[i], backend);
		backend.endtfan();
	      }
	  }
	
	if(topd_left <= topd_right) 
	  return;

	backend.bgnqstrip();
	for(j=botd_left, i=topd_left; i>=topd_right; i--,j++)
	  {
	    //	  backend.tmeshvert(& top->pts[i]);
	    //	  backend.tmeshvert(& bot->pts[j]);
	    OPT_OUTVERT(top->pts[i], backend);
	    OPT_OUTVERT(bot->pts[j], backend);
	  }
	backend.endqstrip();
	
      }
    }
}

  
static void triangulateRectCenter(int n_ulines, REAL* u_val, 
				  int n_vlines, REAL* v_val,
				  Backend& backend)
{

  // XXX this code was patched by Diego Santa Cruz <Diego.SantaCruz@epfl.ch>
  // to fix a problem in which glMapGrid2f() was called with bad parameters.
  // This has beens submitted to SGI but not integrated as of May 1, 2001.
  if(n_ulines>1 && n_vlines>1) {
    backend.surfgrid(u_val[0], u_val[n_ulines-1], n_ulines-1, 
                     v_val[n_vlines-1], v_val[0], n_vlines-1);
    backend.surfmesh(0,0,n_ulines-1,n_vlines-1);
  }

  return;

  /*
  for(i=0; i<n_vlines-1; i++)
    {

      backend.bgnqstrip();
      for(j=0; j<n_ulines; j++)
	{
	  trimVert.param[0] = u_val[j];
	  trimVert.param[1] = v_val[i+1];
	  backend.tmeshvert(& trimVert);	  

	  trimVert.param[1] = v_val[i];
	  backend.tmeshvert(& trimVert);	  
	}
      backend.endqstrip();

    }
    */
}

//it works for top, bot, left ad right, you need ot select correct arguments
static void triangulateRectTopGen(Arc_ptr arc, int n_ulines, REAL* u_val, Real v, int dir, int is_u, Backend& backend)
{

  if(is_u)
    {
      int i,k;
      REAL* upper_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
      assert(upper_val);
      if(dir)
	{
	  for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
	    {
	      upper_val[k] = arc->pwlArc->pts[i].param[0];
	    }	
	  backend.evalUStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[1],
			     upper_val,
			     n_ulines, v, u_val);
	}
      else
	{
	  for(k=0,i=0;  i<arc->pwlArc->npts; i++,k++)
	    {
	      upper_val[k] = arc->pwlArc->pts[i].param[0];

	    }		  

	  backend.evalUStrip(
			     n_ulines, v, u_val,
			     arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], upper_val
			     );	 
	}

      free(upper_val);
      return;
    }
  else //is_v
    {
      int i,k;
      REAL* left_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
      assert(left_val);   
      if(dir)
	{
	  for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
	    {
	      left_val[k] = arc->pwlArc->pts[i].param[1];
	    }
	  backend.evalVStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[0],
			     left_val,
			     n_ulines, v, u_val);
	}
      else 
	{
	  for(k=0,i=0;  i<arc->pwlArc->npts; i++,k++)
	    {
	      left_val[k] = arc->pwlArc->pts[i].param[1];
	    }
	   backend.evalVStrip(
			     n_ulines, v, u_val,
			     arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], left_val
			     );	
	}
      free(left_val);
      return;
    }
	
  //the following is a different version of the above code. If you comment
  //the above code, the following code will still work. The reason to leave

⌨️ 快捷键说明

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