Example #1
0
/* nurb:EndSurface() -> nurb */
static int luaglu_end_surface(lua_State *L) 
{ 
  LuaGLUnurb *lnurb=luaglu_checknurb(L,1);
  gluEndSurface(lnurb->nurb);
  lua_pushvalue(L,1);
  return 1;
}
Example #2
0
void drawGrass()
{
    int i, j, k;
    int num = 0;
    glPushMatrix();
    glTranslatef(0.0, -5.0, 0.0);
    glColor3f(0.0, grasscolor, 0.0);
    for (i = -GRASSAREA; i<GRASSAREA; ++i){
        for (j = -GRASSAREA; j<GRASSAREA; ++j){
            glPushMatrix();
            glTranslatef((0.5 + i + ((randx[num] % (100 + 1)) / 100.0 - 0.5)) / 4.0, 0.0, (0.5 + j + ((randz[num] % (100 + 1)) / 100.0 - 0.5)) / 4.0);
            glRotatef(90 * (randrotation[num] % 101) / 100, 0.0, 1.0, 0.0);
            for (k = 0; k<4; ++k) {
                cpoint[3][k][2] = 0.2*sin(2 * PI*(randrotation[num] % 100 + 1) / 100 + thetagrass*PI / 180.0)*(1 - wind) + (0.5*sin(90 * (randrotation[num] % 101) / 100 * PI / 180.0))*wind;
                cpoint[3][k][0] = 0.5*cos(90 * (randrotation[num] % 101) / 100 * PI / 180.0)*wind;
                cpoint[3][k][1] = 0.5 + 0.05*sin(2 * PI*(randrotation[num] % 100 + 1) / 100 + thetawind*PI / 180.0)*wind;
            }
            gluBeginSurface(nrb_obj);
            gluNurbsSurface(nrb_obj,
                            8, knotvec_u,
                            8, knotvec_v,
                            3,
                            3 * 4,
                            &cpoint[0][0][0],
                            4, 4,
                            GL_MAP2_VERTEX_3
                            );
            gluEndSurface(nrb_obj);
            glPopMatrix();
            ++num;
        }
    }
    glPopMatrix();
}
Example #3
0
void display(void)
{
   GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
   int i, j;

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glPushMatrix();
   glRotatef(330.0, 1.,0.,0.);
   glScalef (0.5, 0.5, 0.5);

   gluBeginSurface(theNurb);
   gluNurbsSurface(theNurb, 
                   8, knots, 8, knots,
                   4 * 3, 3, &ctlpoints[0][0][0], 
                   4, 4, GL_MAP2_VERTEX_3);
   gluEndSurface(theNurb);

   if (showPoints) {
      glPointSize(5.0);
      glDisable(GL_LIGHTING);
      glColor3f(1.0, 1.0, 0.0);
      glBegin(GL_POINTS);
      for (i = 0; i < 4; i++) {
         for (j = 0; j < 4; j++) {
            glVertex3f(ctlpoints[i][j][0], 
                       ctlpoints[i][j][1], ctlpoints[i][j][2]);
         }
      }
      glEnd();
      glEnable(GL_LIGHTING);
   }
   glPopMatrix();
   glFlush();
}
Example #4
0
void display(void)
{
   GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
   GLfloat edgePt[5][2] = /* counter clockwise */
      {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}};
   GLfloat curvePt[4][2] = /* clockwise */ 
      {{0.25, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.5}};
   GLfloat curveKnots[8] = 
      {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
   GLfloat pwlPt[4][2] = /* clockwise */ 
      {{0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}};

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glPushMatrix();
   glRotatef(330.0, 1.,0.,0.);
   glScalef (0.5, 0.5, 0.5);

   gluBeginSurface(theNurb);
   gluNurbsSurface(theNurb, 8, knots, 8, knots,
                   4 * 3, 3, &ctlpoints[0][0][0], 
                   4, 4, GL_MAP2_VERTEX_3);
   gluBeginTrim (theNurb);
      gluPwlCurve (theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2);
   gluEndTrim (theNurb);
   gluBeginTrim (theNurb);
      gluNurbsCurve (theNurb, 8, curveKnots, 2, 
                     &curvePt[0][0], 4, GLU_MAP1_TRIM_2);
      gluPwlCurve (theNurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2);
   gluEndTrim (theNurb);
   gluEndSurface(theNurb);
        
   glPopMatrix();
   glFlush();
}
Example #5
0
//-*****************************************************************************
void INuPatchDrw::draw( const DrawContext &iCtx )
{

    const V3f * points = m_positions -> get();

    const float *u_knot = m_uKnot -> get();
    const float *v_knot = m_vKnot -> get();
    size_t nknotu = m_uKnot -> size();
    size_t nknotv = m_vKnot -> size();

    glColor3f(1.0, 1.0, 1.0);

    gluBeginSurface(nurb);

        gluNurbsSurface( nurb,
                        nknotu, (GLfloat *) &u_knot[0],
                        nknotv, (GLfloat *) &v_knot[0],
                        3, m_nu*3, // stride
                        (GLfloat *)&points[0][0],
                        m_uOrder, m_vOrder, //orders
                        GL_MAP2_VERTEX_3
                        );

    gluEndSurface(nurb);


    IObjectDrw::draw( iCtx );
}
Example #6
0
static void Draw(void)
{

    glClear(GL_COLOR_BUFFER_BIT);

    glPushMatrix();

    glTranslatef(4.0, 4.5, 2.5);
    glRotatef(rotY, 1, 0, 0);
    glRotatef(rotX, 0, 1, 0);
    glTranslatef(-4.0, -4.5, -2.5);

    gluBeginSurface(theNurbs);
    gluNurbsSurface(theNurbs, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots,
		    4*T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER,
		    T_ORDER, GL_MAP2_VERTEX_4);
    gluEndSurface(theNurbs);

    glPopMatrix();

    glFlush();

    if (doubleBuffer) {
	glutSwapBuffers();
    }
}
Example #7
0
void myDisplayObject( const ON_Object& geometry, const ON_Material& material, GLUnurbsObj* nobj )
{
  // Called from myDisplay() to show geometry.
  // Uses ON_GL() functions found in rhinoio_gl.cpp.
  const ON_Point* point=0;
  const ON_PointCloud* cloud=0;
  const ON_Brep* brep=0;
  const ON_Mesh* mesh=0;
  const ON_Curve* curve=0;
  const ON_Surface* surface=0;

  // specify rendering material
  ON_GL( material );

  brep = ON_Brep::Cast(&geometry);
  if ( brep ) 
  {
    ON_GL(*brep, nobj);
    return;
  }

  mesh = ON_Mesh::Cast(&geometry);
  if ( mesh ) 
  {
    ON_GL(*mesh);
    return;
  }

  curve = ON_Curve::Cast(&geometry);
  if ( curve ) 
  {
    ON_GL( *curve, nobj );
    return;
  }

  surface = ON_Surface::Cast(&geometry);
  if ( surface ) 
  {
    gluBeginSurface( nobj );
    ON_GL( *surface, nobj );
    gluEndSurface( nobj );
    return;
  }

  point = ON_Point::Cast(&geometry);
  if ( point ) 
  {
    ON_GL(*point);
    return;
  }

  cloud = ON_PointCloud::Cast(&geometry);
  if ( cloud ) 
  {
    ON_GL(*cloud);
    return;
  }

}
Example #8
0
void display(void)
{
   GLfloat knots1[12] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
                        , 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
   GLfloat knots2[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
   int i, j;
      
   GLfloat edgePt[5][2] =
        {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, 
        {0.0, 0.0}};

    GLfloat pwlPt[42][2];
    for(unsigned int k = 0; k < 42; ++k)
    {
        pwlPt[k][0] = 0.5 + 0.3 * cos(2.0*PI*k/41.0);
        pwlPt[k][1] = 0.5 + 0.3 * sin(-2.0*PI*k/41.0);
    }

        
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glPushMatrix();
   glRotatef(330.0, 1.,0.,0.);
   glScalef (0.3, 0.3, 0.3);

   gluBeginSurface(theNurb);
   gluNurbsSurface(theNurb, 
                   12, knots1, 8, knots2,
                   4 * 3, 3, &ctlpoints[0][0][0], 
                   6, 4, GL_MAP2_VERTEX_3);
    // trim               
    gluBeginTrim (theNurb);
    gluPwlCurve(theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2);
    gluEndTrim (theNurb);
    
    gluBeginTrim (theNurb);
    gluPwlCurve (theNurb, 42, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2);
    gluEndTrim (theNurb);

   gluEndSurface(theNurb);

   if (showPoints) {
      glPointSize(5.0);
      glDisable(GL_LIGHTING);
      glColor3f(1.0, 1.0, 0.0);
      glBegin(GL_POINTS);
      for (i = 0; i < 8; i++) {
         for (j = 0; j < 4; j++) {
            glVertex3f(ctlpoints[i][j][0], 
                       ctlpoints[i][j][1], ctlpoints[i][j][2]);
         }
      }
      glEnd();
      glEnable(GL_LIGHTING);
   }
   glPopMatrix();
   glFlush();
}
Example #9
0
void GraphicsPainter::drawNurbsSurface(const QVector<Point3f> &controlPoints, const QVector<float> &uKnots, const QVector<float> &vKnots, int uOrder, int vOrder)
{
    // nurbs control points
    QVector<float> points(controlPoints.size() * 3);
    for(int i = 0; i < controlPoints.size(); i++){
        points[i*3+0] = controlPoints[i].x();
        points[i*3+1] = controlPoints[i].y();
        points[i*3+2] = controlPoints[i].z();
    }

    // nurbs knot vectors
    QVector<float> uKnotVector(uKnots.size());
    for(int i = 0; i < uKnots.size(); i++)
        uKnotVector[i] = uKnots[i];

    QVector<float> vKnotVector(vKnots.size());
    for(int i = 0; i < vKnots.size(); i++)
        vKnotVector[i] = vKnots[i];

    int uStride = 3 * (vKnotVector.size() - vOrder);
    int vStride = 3;

    glEnable(GL_AUTO_NORMAL);
    GLUnurbsObj *nurb = gluNewNurbsRenderer();
    gluNurbsProperty(nurb, GLU_CULLING, GL_TRUE); // only render visible parts of the surface
    gluNurbsProperty(nurb, GLU_V_STEP, 4);
    gluNurbsProperty(nurb, GLU_U_STEP, 10);
    gluNurbsProperty(nurb, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE);

#ifdef Q_OS_WIN
    gluNurbsCallback(nurb, GLU_ERROR, (void (__stdcall *)()) nurbsErrorCallback);
#else
    gluNurbsCallback(nurb, GLU_ERROR, (void (*)()) nurbsErrorCallback);
#endif

    gluBeginSurface(nurb);

    gluNurbsSurface(nurb,
                    uKnotVector.size(),
                    uKnotVector.data(),
                    vKnotVector.size(),
                    vKnotVector.data(),
                    uStride,
                    vStride,
                    points.data(),
                    uOrder,
                    vOrder,
                    GL_MAP2_VERTEX_3);

    gluEndSurface(nurb);
    gluDeleteNurbsRenderer(nurb);
    glDisable(GL_AUTO_NORMAL);
}
Example #10
0
// Called to draw scene
void RenderScene(void)
	{
	// Draw in Blue
	glColor3ub(0,0,220);

	// Clear the window with current clearing color
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Save the modelview matrix stack
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	// Rotate the mesh around to make it easier to see
	glRotatef(330.0f, 1.0f,0.0f,0.0f);
	
	// Render the NURB
	// Begin the NURB definition
    gluBeginSurface(pNurb);
	
// Evaluate the surface
    gluNurbsSurface(pNurb,	// pointer to NURBS renderer
        8, Knots,			// No. of knots and knot array u direction	
        8, Knots,			// No. of knots and knot array v direction
        4 * 3,				// Distance between control points in u dir.
        3,					// Distance between control points in v dir.
        &ctrlPoints[0][0][0], // Control points
        4, 4,					// u and v order of surface
        GL_MAP2_VERTEX_3);		// Type of surface
	
	// Outer area, include entire curve
    gluBeginTrim (pNurb);
    gluPwlCurve (pNurb, 5, &outsidePts[0][0], 2, GLU_MAP1_TRIM_2);
    gluEndTrim (pNurb);

	// Inner triangluar area
    gluBeginTrim (pNurb);
	gluPwlCurve (pNurb, 4, &insidePts[0][0], 2, GLU_MAP1_TRIM_2);
    gluEndTrim (pNurb);


	// Done with surface
	gluEndSurface(pNurb);
	
	// Restore the modelview matrix
	glPopMatrix();


	// Dispalay the image
	glutSwapBuffers();
	}
Example #11
0
/* drawing ghost with NURBS spline */
void DrawGhost(void)
{

  // control points for bezier curve
  GLfloat ctlpoints[4][4][3] = { 
    { {-3., -5., 0.}, {-5., -2., -5.}, {-5., 2., -5.}, {-3., 3., 0.} },
    { {-2., -3., 0.}, {-2., -2., 5.},  {-2., 2., 5.}, {-2., 5., 0.} },
    { {2., -3., 0.}, {2., -2., -5.},  {2., 2., -5.}, {2., 5., 0.} },
    { {3., -5., 0.}, {5., -2., 5.}, {5., 2., 5.}, {3., 3., 0.} }
  };

  GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
  gluBeginSurface(theGhostNurb);
  gluNurbsSurface(theGhostNurb, 
		  8, knots, 8, knots,
		  4 * 3, 3, &ctlpoints[0][0][0], 
		  4, 4, GL_MAP2_VERTEX_3);
  // map the vertices
  gluNurbsSurface(theGhostNurb, 
		  8, knots, 8, knots,
		  4 * 3, 3, &ctlpoints[0][0][0], 
		  4, 4, GL_MAP2_NORMAL);
  // map the normals
  gluEndSurface(theGhostNurb);

  // draw eyes with two white spheres
  glPushMatrix();
  glColor3f(1.0f, 1.0f, 1.0f);
  glTranslatef(1.5, 1.5, 0.);
  glutSolidSphere(0.5, 5, 5);
  glTranslatef(-3., 0., 0.);
  glutSolidSphere(0.5, 5, 5);
  glPopMatrix();

  /* for testing the points of bezier curve
     glPointSize(5.0);
     glColor3f(1.0, 0.0, 0.0);
     glBegin(GL_POINTS);
     for (i = 0; i < 4; i++) {
     for (j = 0; j < 4; j++) {
     glVertex3f(ctlpoints[i][j][0], 
     ctlpoints[i][j][1], ctlpoints[i][j][2]);
     printf("point: %lf %lf %lf", ctlpoints[i][j][0], 
     ctlpoints[i][j][1], ctlpoints[i][j][2]);
     }
     }
     glEnd();
  */
}
Example #12
0
void Sample_12_8::draw()
{
	int i, j;

	GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
	GLfloat edgePt[5][2] = /* counter clockwise */
	{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}};
	GLfloat curvePt[4][2] = /* clockwise */
	{{0.25, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.5}};
	GLfloat curveKnots[8] =
	{0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
	GLfloat pwlPt[4][2] = /* clockwise */
	{{0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}};

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	glRotatef(330.0, 1.,0.,0.);
	glScalef (0.5, 0.5, 0.5);

	gluBeginSurface(m_theNurb);
	gluNurbsSurface(m_theNurb, 8, knots, 8, knots,
			4 * 3, 3, &m_ctlpoints[0][0][0],
			4, 4, GL_MAP2_VERTEX_3);
	gluBeginTrim (m_theNurb);
	gluPwlCurve (m_theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2);
	gluEndTrim (m_theNurb);
	gluBeginTrim (m_theNurb);
	gluNurbsCurve (m_theNurb, 8, curveKnots, 2,
			&curvePt[0][0], 4, GLU_MAP1_TRIM_2);
	gluPwlCurve (m_theNurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2);
	gluEndTrim (m_theNurb);
	gluEndSurface(m_theNurb);

	if (m_showPoints) {
		glPointSize(5.0);
		glDisable(GL_LIGHTING);
		glColor3f(1.0, 1.0, 0.0);
		glBegin(GL_POINTS);
		for (i = 0; i < 4; i++) {
			for (j = 0; j < 4; j++) {
				glVertex3f(m_ctlpoints[i][j][0],
						m_ctlpoints[i][j][1], m_ctlpoints[i][j][2]);
			}
		}
		glEnd();
		glEnable(GL_LIGHTING);
	}
	glPopMatrix();
}
Example #13
0
void RenderScene(void)
{
  glColor3ub(0,0,220);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();

  glRotatef(330.0f, 1.0f, 0.0f, 0.0f);
  //修剪框是一个闭合的环
  //外修剪框
  GLfloat outSidePts[5][2] = 
  {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}};
  //内修剪框
  GLfloat inSidePts[4][2] =
  {{0.25f, 0.25f}, { 0.5f, 0.5f}, {0.75f, 0.25f},{0.25f, 0.25f} };

  gluBeginSurface(pNurb);
  //定义NURBS表面
  gluNurbsSurface(pNurb,
    8, Knots, //u定义域内的结点个数,以及结点序列
    8, Knots,//v定义域内的结点个数,以及结点序列
    4 * 3,  //u方向上的控制点间隔
    3,  //v方向上的控制点间隔
    &ctrlPoints[0][0][0], //控制点数组
    4, 4, //u v的次数
    GL_MAP2_VERTEX_3);//产生的类型

  //开始修剪
  gluBeginTrim(pNurb);
  gluPwlCurve(pNurb,
    5,  //修剪点的个数
    &outSidePts[0][0], //修剪点数组
    2, //点之间的间隔
    GLU_MAP1_TRIM_2);//修剪的类型
  gluEndTrim(pNurb);

  gluBeginTrim(pNurb);
  gluPwlCurve(pNurb, 4, &inSidePts[0][0], 2, GLU_MAP1_TRIM_2);
  gluEndTrim(pNurb);
  gluEndSurface(pNurb);

  DrawPoints();
  glPopMatrix();

  glutSwapBuffers();
}
Example #14
0
	void draw_solid(const k3d::gl::render_state& State, const k3d::double_t Height, const k3d::double_t Radius, const k3d::double_t SweepAngle)
	{
		if(!Radius)
			return;

		k3d::mesh::knots_t knots;
		k3d::mesh::weights_t weights;
		k3d::mesh::points_t arc_points;
		k3d::nurbs_curve::circular_arc(k3d::vector3(1, 0, 0), k3d::vector3(0, 1, 0), 0, SweepAngle, 4, knots, weights, arc_points);

		std::vector<GLfloat> gl_u_knot_vector(knots.begin(), knots.end());
		std::vector<GLfloat> gl_v_knot_vector;
		std::vector<GLfloat> gl_control_points;

		gl_v_knot_vector.insert(gl_v_knot_vector.end(), 2, 0);
		gl_v_knot_vector.insert(gl_v_knot_vector.end(), 1);
		gl_v_knot_vector.insert(gl_v_knot_vector.end(), 2, 2);

		const k3d::point3 offset = Height * k3d::point3(0, 0, 1);

		for(k3d::uint_t i = 0; i <= 2; ++i)
		{
			const k3d::double_t radius2 = k3d::mix(Radius, 0.001 * Radius, static_cast<k3d::double_t>(i) / static_cast<k3d::double_t>(2));
			for(k3d::uint_t j = 0; j != arc_points.size(); ++j)
			{
				gl_control_points.push_back(weights[j] * (radius2 * arc_points[j][0] + offset[0]));
				gl_control_points.push_back(weights[j] * (radius2 * arc_points[j][1] + offset[1]));
				gl_control_points.push_back(weights[j] * (radius2 * arc_points[j][2] + offset[2]));
				gl_control_points.push_back(weights[j]);
			}
		}

		GLUnurbsObj* const nurbs_renderer = gluNewNurbsRenderer();

		// Important!  We load our own matrices for efficiency (saves round-trips to the server) and to prevent problems with selection
		gluNurbsProperty(nurbs_renderer, GLU_AUTO_LOAD_MATRIX, GL_FALSE);
		gluNurbsProperty(nurbs_renderer, GLU_CULLING, GL_TRUE);
		GLfloat gl_modelview_matrix[16];
		glGetFloatv(GL_MODELVIEW_MATRIX, gl_modelview_matrix);
		gluLoadSamplingMatrices(nurbs_renderer, gl_modelview_matrix, State.gl_projection_matrix, State.gl_viewport);

		gluBeginSurface(nurbs_renderer);
		gluNurbsSurface(nurbs_renderer, gl_u_knot_vector.size(), &gl_u_knot_vector[0], gl_v_knot_vector.size(), &gl_v_knot_vector[0], 4, 36, &gl_control_points[0], 3, 2, GL_MAP2_VERTEX_4);
		gluEndSurface(nurbs_renderer);

		gluDeleteNurbsRenderer(nurbs_renderer);
	}
Example #15
0
static void Init(void)
{

    theNurbs = gluNewNurbsRenderer();
    gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback);

    gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0);
    gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);

    expectedError = GLU_INVALID_ENUM;
    gluNurbsProperty(theNurbs, ~0, 15.0);
    expectedError = GLU_NURBS_ERROR13;
    gluEndSurface(theNurbs);
    expectedError = 0;

    glColor3f(1.0, 1.0, 1.0);
}
Example #16
0
void nurbsInit(void)
{
    theNurbs = gluNewNurbsRenderer();
    gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback);
    gluNurbsProperty(theNurbs,GLU_NURBS_MODE,GLU_NURBS_TESSELLATOR);
    gluNurbsCallback(theNurbs,GLU_NURBS_BEGIN,beginCallback);
    gluNurbsCallback(theNurbs,GLU_NURBS_END,endCallback);
    gluNurbsCallback(theNurbs,GLU_NURBS_VERTEX,vertexCallback);
    gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0);
    gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);
    expectedError = GLU_INVALID_ENUM;
    gluNurbsProperty(theNurbs, ~0, 15.0);
    expectedError = GLU_NURBS_ERROR13;
    gluEndSurface(theNurbs);
    expectedError = 0;

}
Example #17
0
    void draw_local()
    {
        int i,j;
        GLfloat knots[8] = {0,1,2,3,4,5,6,7};

        GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
        GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
        GLfloat mat_shininess[] = { 100.0 };

        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

        theNurb = gluNewNurbsRenderer();
        gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0);
        gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
        gluNurbsCallback(theNurb, GLU_ERROR, (GLvoid (*)()) nurbsError);

        gluBeginSurface(theNurb);
        gluNurbsSurface(theNurb,
                        8, knots, 8, knots,
                        3*6, 3, &ctlpoints[0][0][0],
                        2, 2, GL_MAP2_VERTEX_3);
        gluEndSurface(theNurb);

        if (showPoints) {
            glPointSize(5.0);
            glDisable(GL_LIGHTING);
            glColor3f(1.0, 1.0, 0.0);
            glBegin(GL_POINTS);

            for (i=0; i<6; i++) {
                for (j=0; j<6; j++) {
                    glVertex3f(ctlpoints[i][j][0],
                               ctlpoints[i][j][1],
                               ctlpoints[i][j][2]);
                }
            }
            glEnd();
            glEnable(GL_LIGHTING);
        }

        gluDeleteNurbsRenderer(theNurb);
    }
Example #18
0
void render_scene()
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   /* Render trimmed surface */
   gluBeginSurface(nurb);
      gluNurbsSurface(nurb, 8, knots, 8, knots, 4*3, 3, &ctlpoints[0][0][0], 4, 4, GLU_MAP2_VERTEX_3);
      gluBeginTrim(nurb);
         gluPwlCurve(nurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2);
      gluEndTrim(nurb);
      gluBeginTrim(nurb);
         gluNurbsCurve(nurb, 8, curveKnots, 2, &curvePt[0][0], 4, GLU_MAP1_TRIM_2);
         gluPwlCurve (nurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2);
      gluEndTrim(nurb);
   gluEndSurface(nurb);

   /* Flush all drawings */
   glFlush();
}
Example #19
0
/* Draw the nurb, possibly with trimming */
void draw_nurb(GLboolean trimming) {

    static GLfloat angle = 0.0;
    int i,j;


	/* wave the flag by rotating Z coords though a sine wave */
    for (i=1; i<4; i++)
        for (j=0; j<4; j++)
            ctlpoints[i][j][2] = sin((GLfloat)i+angle);

    angle += 0.1;
    
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glPushMatrix();

        glTranslatef(2.5,-1.0,0.0);
        glScalef(1.5,1.0,1.0);
        glRotatef(90,0.,0.,1.);
        glRotatef(mousey/10.,1.,0.,0.);
        glRotatef(mousex/10.,0.,1.,0.);
        
	gluBeginSurface(nurbsflag);
            gluNurbsSurface(nurbsflag,S_NUMKNOTS, sknots, T_NUMKNOTS, tknots,
                          3 * T_NUMPOINTS, 3,
                          &ctlpoints[0][0][0], T_ORDER, S_ORDER, GL_MAP2_VERTEX_3);
            if (trimming) {
                dotrim(whole);
                dotrim(path[0]);
                dotrim(path[1]);
                dotrim(path[2]);
            }
        gluEndSurface(nurbsflag);
        
	if (hull) draw_hull(ctlpoints);
    
    glPopMatrix();
    
}
Example #20
0
static int tolua_glu_gluEndSurface00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
     !tolua_isusertype(tolua_S,1,"GLUnurbsObj",0,&tolua_err) ||
     !tolua_isnoobj(tolua_S,2,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  GLUnurbsObj* nobj = ((GLUnurbsObj*)  tolua_tousertype(tolua_S,1,0));
  {
   gluEndSurface(nobj);
  }
 }
 return 0;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'gluEndSurface'.",&tolua_err);
 return 0;
#endif
}
Example #21
0
/***************************************************
 * 用NURBS工具渲染水波纹
 **************************************************/
void drawWave(void)
{
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glMaterialfv(GL_FRONT, GL_DIFFUSE, wave_diffuse);
  glMaterialfv(GL_FRONT, GL_SPECULAR, wave_specular);
  glMaterialfv(GL_FRONT, GL_SHININESS, wave_shininess);
  gluBeginSurface(waveSur);
  if (du % 2 == 0) {
    gluNurbsSurface(waveSur,
		    ORDER * 4,
		    knots,
		    ORDER * 4,
		    knots,
		    ORDER * 2 * 3,
		    3,
		    &ctlPoints[0][0][0],
		    ORDER * 2,
		    ORDER * 2,
		    GL_MAP2_VERTEX_3);
  } else {
    gluNurbsSurface(waveSur,
		    ORDER * 4,
		    knots,
		    ORDER * 4,
		    knots,
		    ORDER * 2 * 3,
		    3,
		    &ctlPoints1[0][0][0],
		    ORDER * 2,
		    ORDER * 2,
		    GL_MAP2_VERTEX_3);
  }
  gluEndSurface(waveSur);
  glPopMatrix();
}
Example #22
0
/* drawing fruit with NURBS spline */
void DrawFruit(void)
{
  // control points for bezier curve
  GLfloat fruit_ctlpoints[4][4][3] = { 
    { {-3., -2., 0.}, {-5., -1., -3.}, {-5., 2., -3.}, {-3., 5., -3.} },
    { {-1., -4., 0.}, {-2., -2., 3.},  {-2., 1., 3.}, {-1., 2., -3.} },
    { {1., -4., 0.}, {2., -3., 3.},  {2., -2., 3.}, {1., -1., -3.} },
    { {3., -2., 0.}, {5., 0., -3.}, {5., -1., -3.}, {3., 1., -3.} }
  };

  GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
  gluBeginSurface(theFruitNurb);
  // map the vertices
  gluNurbsSurface(theFruitNurb, 
		  8, knots, 8, knots,
		  4 * 3, 3, &fruit_ctlpoints[0][0][0], 
		  4, 4, GL_MAP2_VERTEX_3);
  // map the normals
  gluNurbsSurface(theFruitNurb, 
		  8, knots, 8, knots,
		  4 * 3, 3, &fruit_ctlpoints[0][0][0], 
		  4, 4, GL_MAP2_NORMAL);
  gluEndSurface(theFruitNurb);
}
Example #23
0
static void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    glTranslatef (4., 4.5, 2.5);
    glRotatef (220.0, 1., 0., 0.);
    glRotatef (115.0, 0., 1., 0.);
    glTranslatef (-4., -4.5, -2.5);

    gluBeginSurface(theNurb);
    gluNurbsSurface(theNurb,
	    S_NUMKNOTS, sknots,
	    T_NUMKNOTS, tknots,
	    4 * T_NUMPOINTS,
	    4,
	    &ctlpoints[0][0][0],
	    S_ORDER, T_ORDER,
	    GL_MAP2_VERTEX_4);
    gluEndSurface(theNurb);

    glPopMatrix();
    glFlush();
}
Example #24
0
void display (void) {
    
    glClearColor (0.0,0.0,0.0,1.0); //clear the screen to black
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the color buffer and the depth buffer
    glMatrixMode( GL_MODELVIEW );
    glColor4f(1.0f,0.0f,0.0f,1.0f);
    
    glEnable(GL_SCISSOR_TEST);
    glMatrixMode (GL_PROJECTION); //set the matrix to projection
    
    // Draw the primary view
    glViewport (0, 0, (GLsizei)screen_width, (GLsizei)screen_height); //set the viewport to the current window specifications
    glScissor(0, 0, (GLsizei)screen_width, (GLsizei)screen_height);
    glLoadIdentity ();
    
    if (lighting) {
        GLfloat AmbientLight[] = {0.1, 0.1, 0.2};
        glLightfv (GL_LIGHT0, GL_AMBIENT, AmbientLight);
        GLfloat DiffuseLight[] = {1, 1, 1};
        glLightfv (GL_LIGHT1, GL_DIFFUSE, DiffuseLight);
        GLfloat LightPosition[] = {xpos, ypos, zpos, 1};
        glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
    }
    gluPerspective (60, (GLfloat)screen_width / (GLfloat)screen_height, 1.0, 100.0);
    gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //camera position, x,y,z, looking at x,y,z, Up Positions of the camera
    camera();
    glPushMatrix();
    if (lighting) {
        texture1 = LoadTexture( "texture.raw", 256, 256 );
        texture2 = LoadTexture( "/dev/urandom", 256, 256 );
        texture3 = LoadTexture( "water.raw", 500, 375 );
        texture4 = LoadTexture( "bubbles.raw", 200, 200 );
        glEnable( GL_TEXTURE_2D ); //enable 2D texturing
        glEnable(GL_TEXTURE_GEN_S); //enable texture coordinate generation
        glEnable(GL_TEXTURE_GEN_T);
        
        if (fog) {
            GLfloat fogColor[4]= {0.5f, 1.0f, 0.5f, 1};  // Fog Color
            glFogi(GL_FOG_MODE, GL_EXP);        // Fog Mode
            glFogfv(GL_FOG_COLOR, fogColor);    // Set Fog Color
            glFogf(GL_FOG_DENSITY, 1.0f);       // How Dense Will The Fog Be
            glHint(GL_FOG_HINT, GL_DONT_CARE);  // Fog Hint Value
            glFogf(GL_FOG_START, n*space);      // Fog Start Depth
            glFogf(GL_FOG_END,-n*space);          // Fog End Depth
        }
        
        if (nurb) {
            glPushMatrix();
            glRotatef(270,0.0,1.0,0.0);
            glTranslated(n*space/2,n*space/2,-n*space);
            GLfloat ctlpoints[4][4][3];
            GLUnurbsObj *theNurb;
            GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
            int u, v;
            for (u = 0; u < 4; u++) {
               for (v = 0; v < 4; v++) {
                  ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
                  ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);

                  if ( (u == 1 || u == 2) && (v == 1 || v == 2))
                     ctlpoints[u][v][2] = 3.0;
                  else
                     ctlpoints[u][v][2] = -3.0;
               }
            }

            theNurb = gluNewNurbsRenderer();
            gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0);
            gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
            gluBeginSurface(theNurb);
            gluNurbsSurface(theNurb, 
                               8, knots, 8, knots,
                               4 * 3, 3, &ctlpoints[0][0][0], 
                               4, 4, GL_MAP2_VERTEX_3);
            gluEndSurface(theNurb);
            glPopMatrix();
        }
    }
    cube(); //call the cube drawing function
    glPopMatrix();
    if (lighting) {
        FreeTexture( texture1 );
        FreeTexture( texture2 );
        FreeTexture( texture3 );
        FreeTexture( texture4 );
    }
    glPushMatrix();
    glTranslated(space*((n/2)+1),space*(n/2),space*(n/2));
    glutWireCube(space*n);
    glPopMatrix();
    
    // Draw the secondary view
    glViewport (3*(screen_width/4), 3*(screen_height/4), screen_width/4, screen_width/4); //set the viewport to the current window specifications
    glScissor(3*(screen_width/4), 3*(screen_height/4), screen_width/4, screen_width/4);
    glLoadIdentity();
    glOrtho(-1, 13, -1, 13, -1, 13);
    glRotatef(90,0.0,1.0,0.0); 
    cube();
    glDisable(GL_SCISSOR_TEST);
    glutSwapBuffers(); //swap the buffers
}
Example #25
0
void display(void) {
    int i,j;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    glRotatef(eixox, 1 ,0 ,0);
    glRotatef(eixoy, 0 ,1 ,0);
    glRotatef(eixoz, 0 ,0 ,1);
    glScalef(0.25, 0.25, 0.25);

    glPushMatrix();
    glGetDoublev (GL_MODELVIEW_MATRIX, matrizModelview);
    glGetDoublev (GL_PROJECTION_MATRIX, matrizProjecao);
    glGetIntegerv (GL_VIEWPORT, matrizViewport);
    glPopMatrix();

    glDisable(GL_LIGHTING);
    glPushMatrix();
    glTranslatef(-5,-5,-5);
    glColor3f(1,1,1);
    glBegin(GL_LINES);
    glVertex3f(0,0,0);
    glVertex3f(1,0,0);
    glEnd();
    glRasterPos3f(1.5,0,0);
    glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, 'x');

    glBegin(GL_LINES);
    glVertex3f(0,0,0);
    glVertex3f(0,1,0);
    glEnd();
    glRasterPos3f(0,1.5,0);
    glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, 'y');

    glBegin(GL_LINES);
    glVertex3f(0,0,0);
    glVertex3f(0,0,1);
    glEnd();
    glRasterPos3f(0,0,1.5);
    glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, 'z');

    glPopMatrix();

    glEnable(GL_LIGHTING);

    switch(spline) {
    case BEZIER:
        glEnable(GL_AUTO_NORMAL);
        glMap2f(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0, 1, 3*nVertices, 4, &vertices[0][0][0]);
        glMapGrid2f(20, 0, 1.0, 20, 0, 1.0);
        glEvalMesh2(GL_FILL, 0, 20, 0, 20);
        glEnd();
        break;
    case NURBS:
        gluBeginSurface(nc);
        gluNurbsSurface(nc, nNosx, nosx, nNosy, nosy, 4*3, 3, &vertices[0][0][0], ordemx, ordemy, GL_MAP2_VERTEX_3);
        gluEndSurface(nc);
        break;
    }
    glPointSize(5.0);
    glColor3f(1.0, 0.0, 0.0);
    glDisable(GL_LIGHTING);
    glBegin(GL_POINTS);
    for(i=0; i<4; i++) {
        for(j=0; j<4; j++) {
            if((vcx==i)&&(vcy==j)) {
                glColor3f(1.0,1.0,0.0);
                glVertex3fv(&vertices[i][j][0]);
                glColor3f(1.0,0.0,0.0);
            }
            else {
                glVertex3fv(&vertices[i][j][0]);
            }
        }
    }
    glEnable(GL_LIGHTING);
    glEnd();
    glColor3f(1.0, 1.0, 1.0);

    glPopMatrix();

    glFlush();

    glutSwapBuffers();
}
Example #26
0
void ON_GL( const ON_BrepFace& face,
            GLUnurbsObj* nobj     // created with gluNewNurbsRenderer )
          )
{
  bool bSkipTrims = false;

  const ON_Mesh* mesh;
  mesh = face.Mesh(ON::render_mesh);
  if ( mesh ) 
  {
    // use saved render mesh
    ON_GL(*mesh);
  }
  else 
  {
    // use (slow and buggy) glu trimmed NURBS rendering
    double knot_scale[2][2] = {{0.0,1.0},{0.0,1.0}};
    const ON_Brep* brep = face.Brep();
    if ( !brep )
      return;

    // untrimmed surface
    {
      ON_NurbsSurface tmp_nurbssrf;
      const ON_Surface* srf = brep->m_S[face.m_si];
      const ON_NurbsSurface* nurbs_srf = ON_NurbsSurface::Cast(srf);
      if ( !nurbs_srf ) 
      {
        // attempt to get NURBS form of this surface
        if ( srf->GetNurbForm( tmp_nurbssrf ) )
          nurbs_srf = &tmp_nurbssrf;
      }
      if ( !nurbs_srf )
        return;
      gluBeginSurface( nobj );
      ON_GL( *nurbs_srf,
             nobj, 
             (nurbs_srf->IsRational()) ? GL_MAP2_VERTEX_4 : GL_MAP2_VERTEX_3,
             true, knot_scale[0], knot_scale[1]
            );
    }

    if ( bSkipTrims || brep->FaceIsSurface( face.m_face_index ) ) {
      gluEndSurface( nobj );
      return; // face is trivially trimmed
    }

    int fli, li, lti, ti;

    // any knot scaling applied to the surface must also be applied to
    // the parameter space trimming geometry
    double xform[4][4] 
      = {{knot_scale[0][1], 0.0, 0.0, -knot_scale[0][0]*knot_scale[0][1] },
         {0.0, knot_scale[1][1], 0.0, -knot_scale[1][0]*knot_scale[1][1] },
         {0.0, 0.0, 1.0, 0.0},
         {0.0, 0.0, 0.0, 1.0}};

    // Add face's 2d trimming loop(s)
    const int face_loop_count = face.m_li.Count();
    for ( fli = 0; fli < face_loop_count; fli++ ) 
    {
      gluBeginTrim( nobj );

      li = face.m_li[fli];
      const ON_BrepLoop& loop = brep->m_L[li];
      const int loop_trim_count = loop.m_ti.Count();
      for ( lti = 0; lti < loop_trim_count; lti++ )
      {
        ti = loop.m_ti[lti];
        const ON_BrepTrim& trim = brep->m_T[ti];
        ON_GL( trim,
               nobj, 
               GLU_MAP1_TRIM_2,
               xform
              );
      }

      gluEndTrim( nobj );
    }
    gluEndSurface( nobj );
  }
}
Example #27
0
int
NurbsSurface (Tcl_Interp *interp, int argc, char* argv [])
{
    int result = TCL_OK;
    GLint uOrder = 4;
    GLint vOrder = 4;
    GLenum type = GL_MAP2_VERTEX_3;
    int nCoords = 3;
    FloatArray uKnot = NewFloatArray ();
    FloatArray vKnot = NewFloatArray ();
    FloatArray cPoint = NewFloatArray ();
    GLfloat samplingTolerance = 50.0;
    GLfloat displayMode = GLU_FILL;
    GLfloat culling = GL_FALSE;
    int iarg;
    int dlist = 0;

    for (iarg = 2; iarg < argc; iarg++) {
        int len = (int)strlen (argv [iarg]);
        if (strncmp (argv [iarg], "-uorder", len) == 0) {
            int val;
            iarg++;
            if (iarg >= argc) ERRMSG ("No value given for -uorder");
            if (Tcl_GetInt (interp, argv [iarg], &val) != TCL_OK ||
                    val < 2 || val > 8)
                ERRMSG2 ("\nInvalid value for -uorder:", argv [iarg]);
            uOrder = val;
        }
        else if (strncmp (argv [iarg], "-vorder", len) == 0) {
            int val;
            iarg++;
            if (iarg >= argc) ERRMSG ("No value given for -vorder");
            if (Tcl_GetInt (interp, argv [iarg], &val) != TCL_OK ||
                    val < 2 || val > 8)
                ERRMSG2 ("\nInvalid value for -vorder:", argv [iarg]);
            vOrder = val;
        }
        else if (strncmp (argv [iarg], "-uknots", len) == 0) {
            if (uKnot->count != 0) ERRMSG ("uknot values already given");
            iarg++;
            while (iarg < argc &&
                    !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) {
                double val;
                if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK)
                    ERRMSG ("\nError parsing uknot value");
                if (uKnot->count > 0 &&
                        uKnot->value [uKnot->count-1] > val)
                    ERRMSG ("uknot values not in non-descending order");
                AddFloat (uKnot, (GLfloat)val);
                iarg++;
            }
            iarg--;
        }
        else if (strncmp (argv [iarg], "-vknots", len) == 0) {
            if (vKnot->count != 0) ERRMSG ("vknot values already given");
            iarg++;
            while (iarg < argc &&
                    !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) {
                double val;
                if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK)
                    ERRMSG ("\nError parsing uknot value");
                if (vKnot->count > 0 &&
                        vKnot->value [vKnot->count-1] > val)
                    ERRMSG ("vknot values not in non-descending order");
                AddFloat (vKnot, (GLfloat)val);
                iarg++;
            }
            iarg--;
        }
        else if (strncmp (argv [iarg], "-controlpoints", len) == 0) {
            if (cPoint->count != 0) ERRMSG ("controlpoint values already given");
            iarg++;
            while (iarg < argc &&
                    !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) {
                double val;
                if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK)
                    ERRMSG ("\nError parsing uknot value");
                AddFloat (cPoint, (GLfloat)val);
                iarg++;
            }
            iarg--;
        }
        else if (strncmp (argv [iarg], "-type", len) == 0) {
            iarg++;
            if (iarg >= argc) ERRMSG ("No -type value given");
            if (strcmp (argv [iarg], "map2vertex3") ==0) {
                type = GL_MAP2_VERTEX_3;
                nCoords = 3;
            } else if (strcmp (argv [iarg], "map2vertex4") == 0) {
                type = GL_MAP2_VERTEX_4;
                nCoords = 4;
            } else if (strcmp (argv [iarg], "map2color4") == 0) {
                type = GL_MAP2_COLOR_4;
                nCoords = 4;
            } else if (strcmp (argv [iarg], "map2normal") == 0) {
                type = GL_MAP2_NORMAL;
                nCoords = 3;
            } else if (strcmp (argv [iarg], "map2texturecoord1") == 0) {
                type = GL_MAP2_TEXTURE_COORD_1;
                nCoords = 1;
            } else if (strcmp (argv [iarg], "map2texturecoord2") == 0) {
                type = GL_MAP2_TEXTURE_COORD_2;
                nCoords = 2;
            } else if (strcmp (argv [iarg], "map2texturecoord3") == 0) {
                type = GL_MAP2_TEXTURE_COORD_3;
                nCoords = 3;
            } else if (strcmp (argv [iarg], "map2texturecoord4") == 0) {
                type = GL_MAP2_TEXTURE_COORD_4;
                nCoords = 4;
            } else
                ERRMSG2 ("not a valid type:", argv [iarg]);
        }
        else if (strncmp (argv [iarg], "-samplingtolerance", len) == 0) {
            double val;
            iarg++;
            if (iarg >= argc) ERRMSG ("No -samplingtolerance value given");
            if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK)
                ERRMSG ("\nError parsing sampling tolerance");
            samplingTolerance = (GLfloat)val;
        }
        else if (strncmp (argv [iarg], "-displaymode", len) == 0) {
            iarg++;
            if (iarg >= argc) ERRMSG ("No -displaymode value given");
            if (strcmp (argv [iarg], "fill") == 0) {
                displayMode = GLU_FILL;
            } else if (strcmp (argv [iarg], "outlinepolygon") == 0) {
                displayMode = GLU_OUTLINE_POLYGON;
            } else if (strcmp (argv [iarg], "outlinepatch") == 0) {
                displayMode = GLU_OUTLINE_PATCH;
            } else {
                ERRMSG2 ("not a valid display mode:", argv [iarg]);
            }
        }
        else if (strncmp (argv [iarg], "-culling", len) == 0) {
            int val;
            iarg++;
            if (iarg >= argc) ERRMSG ("No -culling value given");
            if (Tcl_GetBoolean (interp, argv [iarg], &val) != TCL_OK)
                ERRMSG ("\nError parsing culling value");
            culling = (GLfloat)val;
        }
        else {
            ERRMSG2 ("invalid option:", argv [iarg]);
        }
    }

    if (vKnot->count == 0 || uKnot->count == 0 || cPoint->count == 0)
        ERRMSG ("All of -uknot, -vknot and -cpoint options must be specified");

    /* Now try to guess the remaining arguments and call gluNurbsSurface */
    {
        GLint uKnotCount = uKnot->count;
        GLint vKnotCount = vKnot->count;
        GLint vStride = nCoords;
        GLint uStride = nCoords * (vKnotCount - vOrder);
        static GLUnurbsObj* obj = NULL;
        if (uStride * (uKnotCount - uOrder) != cPoint->count) {
            char buf [80];
            sprintf (buf, "%d", uStride * (uKnotCount - uOrder));
            ERRMSG2 ("Incorrect number of controlpoint coordinates. Expected ",
                     buf);
        }
        /* Theoretically, a nurbs object could be allocated for each
        invocation of NurbsSurface and then freed after the creation
         of the display list. However, this produces a segmentation
         violation on AIX OpenGL 1.0. Thus, only one nurbs object is
         ever allocated and never freed.
            */
        if (obj == NULL) obj = gluNewNurbsRenderer();
        dlist = glGenLists (1);
        gluNurbsProperty (obj, GLU_SAMPLING_TOLERANCE, samplingTolerance);
        gluNurbsProperty (obj, GLU_DISPLAY_MODE, displayMode);
        gluNurbsProperty (obj, GLU_CULLING, culling);
        glNewList (dlist, GL_COMPILE);
        gluBeginSurface (obj);
        gluNurbsSurface (obj, uKnotCount, uKnot->value,
                         vKnotCount, vKnot->value,
                         uStride, vStride, cPoint->value,
                         uOrder, vOrder, type);
        gluEndSurface (obj);
        /* This is never used because of a bug in AIX OpenGL 1.0.
        gluDeleteNurbsObj (obj);
            */
        glEndList();
        glFlush();
    }

done:

    DestroyFloatArray (uKnot);
    DestroyFloatArray (vKnot);
    DestroyFloatArray (cPoint);

    if (result == TCL_OK) {
        char tmp[128];
        sprintf (tmp, "%d", dlist);
        Tcl_SetResult(interp, tmp, TCL_VOLATILE);
    }

    return result;
}
/***************************************************************************
 DrawRibbon
 ****************************************************************************/
static void DrawRibbon(int snum){
    int i = 0;
    float comx = 0.0,
	comy = 0.0,
	comz = 0.0;
    struct coord *c = state->coords[snum];
	
    for (i=0; i<c->size; i++){
        comx += c->rp_ca[i].x;
        comy += c->rp_ca[i].y;
        comz += c->rp_ca[i].z;
    }
    comx /= c->size;
    comy /= c->size;
    comz /= c->size;
    
    GLUnurbsObj *nurbs = gluNewNurbsRenderer();
    
    GLfloat* ctrlpts = E_MALLOC(6*sizeof(GLfloat)*c->size);
    for(i=0; i < c->size*6; i+=6){
        
		ctrlpts[i]   = c->rp_n[i/6].x - comx;
		ctrlpts[i+1] = c->rp_n[i/6].y - comy;
		ctrlpts[i+2] = c->rp_n[i/6].z - comz;
        
		ctrlpts[i+3] = c->rp_c[i/6].x - comx;
		ctrlpts[i+4] = c->rp_c[i/6].y - comy;
		ctrlpts[i+5] = c->rp_c[i/6].z - comz;
		
    }
    
    GLfloat* uknots = E_MALLOC(sizeof(GLfloat)*(2*c->size+4));
    
    for(i=0; i < 2*c->size+4; i++){
        if(i>c->size*2+3){
            uknots[i]=uknots[c->size*2+3];
        }
        else{
            uknots[i]=i/1.0; 
        }
    }
	
	GLfloat vknots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
	
	glColor3f(0.0, 0.0, 1.0);
	glLineWidth(2);
	glEnable(GL_AUTO_NORMAL);
	glShadeModel(GL_SMOOTH);
	
	glPushMatrix();
	
	gluNurbsCallback(nurbs, GLU_ERROR, (GLvoid(*)())nurbsError);
	gluNurbsProperty(nurbs, GLU_V_STEP, 4);
	gluNurbsProperty(nurbs, GLU_U_STEP, 4);
	gluNurbsProperty(nurbs, GLU_CULLING, GL_TRUE);
	gluNurbsProperty(nurbs, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE);
	
	glShadeModel(GL_SMOOTH);
	
	gluBeginSurface(nurbs);
	
	
	if(snum%3 == 1){
		glColor3f(1.0, 0.0, 0.0);
	}
	else if(snum%3 == 2){
		glColor3f(0.0, 1.0, 0.0);
		
	}
	else{
		glColor3f(0.0, 1.0, 0.0);
	}
	
	gluNurbsSurface(nurbs,              //context object
					c->size*2+4,          //number of u-knots
					uknots,                //u-knot pointer
					8,                  //number of v-knots
					vknots,               //v-knot ptr
					3,                  //width of u-control points (u-stride)
					3,                  //width of v-control points (v-stride)
					ctrlpts,  //control point pointer
					4,                  // u-order of the curve (degree+1)
					4,                  // v-order of the curve (degree+1)
					GL_MAP2_TEXTURE_COORD_2    //type
					);
	
	gluNurbsSurface(nurbs,              //context object
					c->size*2+4,          //number of u-knots
					uknots,                //u-knot pointer
					8,                  //number of v-knots
					vknots,               //v-knot ptr
					3,                  //width of u-control points (u-stride)
					3,                  //width of v-control points (v-stride)
					ctrlpts,  //control point pointer
					4,                  // u-order of the curve (degree+1)
					4,                  // v-order of the curve (degree+1)
					GL_MAP2_VERTEX_3    //type
					);
	
	gluEndSurface(nurbs);
	
	glPopMatrix();
}
Example #29
0
void
SoNurbsSurface::GLRender(SoGLRenderAction *action)
//
////////////////////////////////////////////////////////////////////////
{
    // First see if the object is visible and should be rendered now
    if (! shouldGLRender(action))
	return;

    const SoCoordinateElement   *ce =
            SoCoordinateElement::getInstance(action->getState());
    GLfloat			*sKnots, *tKnots, *dstCoords;
    GLenum                      type;
    float                       *fKnots;
    int32_t                        nCoords, uOffset, vOffset;
    int32_t			nsKnots, ntKnots, nsCoords, ntCoords;
    int32_t			nDstCoords;
    int32_t                        sOffset, tOffset;
    int                         i, j;

    // Check for 0 control points
    nCoords = ce->getNum();
    if (nCoords == 0)
        return;
        
    // Make sure the first current material is sent to GL
    SoMaterialBundle	mb(action);
    mb.sendFirst();

    //
    // Find the number of steps required for object space tessellation and
    // the pixel tolerance used for screen space tessellation.
    //
    float val = SoComplexityElement::get(action->getState());
    if (val < 0.0) val = 0.0;
    if (val > 1.0) val = 1.0;
    int   steps;

    if      (val < 0.10) steps = 2;
    else if (val < 0.25) steps = 3;
    else if (val < 0.40) steps = 4;
    else if (val < 0.55) steps = 5;
    else                 steps = (int)(powf(val, 3.32)*28) + 2;

    float pixTolerance = 104.0*val*val - 252.0*val + 150;

    //
    // If the surface is being cached, or if the tessellation is in object
    // space, use the software NURBS library.  Create a software NURBS
    // rendering class and use it to make nurbs rendering calls.  Since
    // the software NURBS library generates triangles, texture mapping
    // will happen automatically without having to render a separate
    // texture surface.
    //
    if (SoComplexityTypeElement::get(action->getState()) ==
        SoComplexityTypeElement::OBJECT_SPACE)
    {
        _SoNurbsGLRender *GLRender = new _SoNurbsGLRender();

        //
        // Set the sampling to be constant across the surface with the
        // tessellation to be 'steps' across the S and T parameters
        //
        GLRender->setnurbsproperty( N_T2D,  N_SAMPLINGMETHOD,
                N_FIXEDRATE );
        GLRender->setnurbsproperty( N_V3D,  N_SAMPLINGMETHOD,
                N_FIXEDRATE );
        GLRender->setnurbsproperty( N_V3DR, N_SAMPLINGMETHOD,
                N_FIXEDRATE );
        GLRender->setnurbsproperty( N_T2D,  N_S_STEPS, steps);
        GLRender->setnurbsproperty( N_T2D,  N_T_STEPS, steps);
        GLRender->setnurbsproperty( N_V3D,  N_S_STEPS, steps);
        GLRender->setnurbsproperty( N_V3D,  N_T_STEPS, steps);
        GLRender->setnurbsproperty( N_V3DR, N_S_STEPS, steps);
        GLRender->setnurbsproperty( N_V3DR, N_T_STEPS, steps);

        // Determine whether a texture coordinate surface must be generated
        SbBool doTextures = SoGLTextureEnabledElement::get(action->getState());

        // Draw the surface
        drawNURBS (GLRender, action->getState(), doTextures);
        delete GLRender;

        return;
    }
    
    if (SoDrawStyleElement::get(action->getState()) ==
        SoDrawStyleElement::POINTS) {
        //
        // Render the control points of the surface.  Rendering the points
        // of the surface would be very slow, as the Software NURBS library
        // would have to be used, and because of the view dependent 
        // tessellation, points would not necessarily remain visible.
        //
        glBegin(GL_POINTS);
        if (ce->is3D()) {
            for (i=0; i<nCoords; i++) {
                const SbVec3f & coords3 = ce->get3((int)i);
                glVertex3f ((GLfloat)(coords3[0]),
                            (GLfloat)(coords3[1]),
                            (GLfloat)(coords3[2]));
            }
        }
        else {
            for (i=0; i<nCoords; i++) {
                const SbVec4f & coords4 = ce->get4((int)i);
                glVertex4f ((GLfloat)(coords4[0]),
                            (GLfloat)(coords4[1]),
                            (GLfloat)(coords4[2]),
                            (GLfloat)(coords4[3]));
            }
        }
        glEnd();
        return;
    }


    //
    // Render the NURBS surface using the GLU.
    //
    GLUnurbsObj *nurbsObj = gluNewNurbsRenderer();

    switch (SoDrawStyleElement::get(action->getState())) {
        case SoDrawStyleElement::FILLED:
            gluNurbsProperty (nurbsObj, (GLenum)GLU_DISPLAY_MODE, GLU_FILL);
            break;
        case SoDrawStyleElement::LINES:
            gluNurbsProperty (nurbsObj, (GLenum)GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
            break;
    }

    gluNurbsProperty (nurbsObj, (GLenum)GLU_SAMPLING_TOLERANCE, (GLfloat)pixTolerance);

    //
    // Collect the control points and knot vectors into an array suitable
    // for sending to the GL.  The control points and knot vectors must be
    // converted to double precision so that they can be passed to the
    // GL NURBS routines.
    //
    GLfloat *dCoords, *duKnots, *dvKnots;
    if (ce->is3D()) {
        dCoords = (GLfloat *)new GLfloat[3*nCoords];
        for (i=0; i<nCoords; i++) {
            const SbVec3f &c3 = ce->get3((int)i);
            dCoords[3*i]   = (GLfloat)c3[0];
            dCoords[3*i+1] = (GLfloat)c3[1];
            dCoords[3*i+2] = (GLfloat)c3[2];
        }
        uOffset = 3;
        type = GL_MAP2_VERTEX_3;
    }
    else {
        dCoords = (GLfloat *)new GLfloat[4*nCoords];
        for (i=0; i<nCoords; i++) {
            const SbVec4f &c4 = ce->get4((int)i);
            dCoords[4*i]   = (GLfloat)c4[0];
            dCoords[4*i+1] = (GLfloat)c4[1];
            dCoords[4*i+2] = (GLfloat)c4[2];
            dCoords[4*i+3] = (GLfloat)c4[3];
        }
        uOffset = 4;
        type = GL_MAP2_VERTEX_4;
    }
    vOffset = uOffset * numUControlPoints.getValue();

    fKnots = (float *)uKnotVector.getValues(0);
    duKnots = (GLfloat *)new GLfloat[uKnotVector.getNum()];
    for (i=0; i<uKnotVector.getNum(); i++)
        duKnots[i] = (GLfloat)fKnots[i];
    fKnots = (GLfloat *)vKnotVector.getValues(0);
    dvKnots = (GLfloat *)new GLfloat[vKnotVector.getNum()];
    for (i=0; i<vKnotVector.getNum(); i++)
        dvKnots[i] = (GLfloat)fKnots[i];

    // Texture mapping.  If doTextures == TRUE
    // we are drawing textures.  If the textureCoordinateBinding is
    // DEFAULT, we have to build a default NURBS surface for the texture
    // coordinates, otherwise we use the texture coordinates in the texture
    // element.
    // If there is a software texture function defined, then we have to
    // create a texture nurb surface with the same number of points and
    // knots as the original surface, and call the texture coordinate function
    // at each vertex.
    SbBool doTextures = SoGLTextureEnabledElement::get(action->getState());
    if(doTextures) {

	switch (SoTextureCoordinateElement::getType(action->getState())) {

          // software texture functions
	  case SoTextureCoordinateElement::FUNCTION:
          {
	    // generate S and T coords from U and V coords
	    SbVec3f	coord;
	    SbVec2f	stCoord;
	    int		offset;
            SoTextureCoordinateBundle tb(action, TRUE);

	    nsCoords = numUControlPoints.getValue();
	    ntCoords = numVControlPoints.getValue();

	    sKnots = duKnots;
	    tKnots = dvKnots;
	    nsKnots = uKnotVector.getNum();
	    ntKnots = vKnotVector.getNum();

	    nDstCoords = nsCoords * ntCoords;
	    dstCoords = (GLfloat *)new GLfloat[nDstCoords * 2];

	    for(int v = 0; v < ntCoords; v++) {
		for(int u = 0; u < nsCoords; u++) {
		    if (ce->is3D()) {
			offset = 3 * (v * (int)nsCoords + u);
			coord[0] = dCoords[offset + 0];
			coord[1] = dCoords[offset + 1];
			coord[2] = dCoords[offset + 2];
		    }
		    else {
			offset = 4 * (v * (int)nsCoords + u);
			coord[0] = dCoords[offset + 0] / dCoords[offset + 3];
			coord[1] = dCoords[offset + 1] / dCoords[offset + 3];
			coord[2] = dCoords[offset + 2] / dCoords[offset + 3];
		    }
                    const SbVec4f &tc = tb.get(coord, SbVec3f(0.0, 1.0, 0.0));
		    dstCoords[(v * (int)nsCoords  + u) * 2 + 0] = tc[0];
		    dstCoords[(v * (int)nsCoords  + u) * 2 + 1] = tc[1];
		}
	    }
            break;
  	  }

	  // texture coordinates defined from texture node
	case SoTextureCoordinateElement::EXPLICIT:
	  // get texture coordinates from texture node
	  const SoTextureCoordinateElement *te = 
	      SoTextureCoordinateElement::getInstance(action->getState());
	  int32_t		nstCoords = te->getNum();
	  if (nstCoords < 1) {
	      // Default texture coordinates are computed by defining
	      // a bezier surface that is defined in the same valid
	      // parameter space as the geometric surface.  The valid
	      // parameter space is defined based on the order and knot
	      // vector.  The coordinates go from 0 to one and the knot
	      // vectors span the valid range of the geometric surface.
	      // The knot vectors default to 0 and 1 in the event of bogus
	      // input data.
	      int uOrder, vOrder;
	      GLfloat sKnotVal1, sKnotVal2, tKnotVal1, tKnotVal2;

	      uOrder = uKnotVector.getNum() - numUControlPoints.getValue();
	      vOrder = vKnotVector.getNum() - numVControlPoints.getValue();
	      if ((uOrder > 0) && (uOrder < uKnotVector.getNum()))
		  sKnotVal1 = duKnots[uOrder-1];
	      else
		  sKnotVal1 = 0;
	      if ((uOrder > 0) && (uOrder < uKnotVector.getNum()))
		  sKnotVal2 = duKnots[uKnotVector.getNum()-uOrder];
	      else
		  sKnotVal2 = 1;
	      if ((vOrder > 0) && (vOrder < vKnotVector.getNum()))
		  tKnotVal1 = dvKnots[vOrder-1];
	      else
		  tKnotVal1 = 0;
	      if ((vOrder > 0) && (vOrder < vKnotVector.getNum()))
		  tKnotVal2 = dvKnots[vKnotVector.getNum()-vOrder];
	      else
		  tKnotVal2 = 1;

	      // do a linear 2x2 array
	      nsKnots = 4;
	      ntKnots = 4;

	      sKnots = (GLfloat *)new GLfloat[4];
	      tKnots = (GLfloat *)new GLfloat[4];
		
	      sKnots[0] = sKnots[1] = sKnotVal1;
	      tKnots[0] = tKnots[1] = tKnotVal1;
	      sKnots[2] = sKnots[3] = sKnotVal2;
	      tKnots[2] = tKnots[3] = tKnotVal2;

	      // allocate a 2 x 2 array of GLfloat[2]'s
	      nsCoords = 2;
	      ntCoords = 2;
	      nDstCoords = nsCoords * ntCoords * 2;
	      dstCoords = (GLfloat *)new GLfloat[nDstCoords];
	      for(i = 0; i < 2; i++) {
		  for(j = 0; j < 2; j++) {
		      dstCoords[(i * 2 + j) * 2 + 0] = j;
		      dstCoords[(i * 2 + j) * 2 + 1] = i;
		  }
	      } 
	  }
	  else {
	      // get knot vectors from this node
	      nsKnots = sKnotVector.getNum();
	      fKnots = (float *)sKnotVector.getValues(0);
	      sKnots = (GLfloat *)new GLfloat[nsKnots];
	      for (i=0; i < nsKnots; i++)
		  sKnots[i] = (GLfloat)fKnots[i];

	      ntKnots = tKnotVector.getNum();
	      fKnots = (float *)tKnotVector.getValues(0);
	      tKnots = (GLfloat *)new GLfloat[ntKnots];
	      for (i=0; i < ntKnots; i++)
		  tKnots[i] = (GLfloat)fKnots[i];

	      nsCoords = numSControlPoints.getValue();
	      ntCoords = numTControlPoints.getValue();

	      nDstCoords = 2 * nstCoords;
	      dstCoords = (GLfloat *)new GLfloat[nDstCoords];
	      for(i = 0; i < nstCoords; i++) {
		  const SbVec2f &tc2 = te->get2(i);
		  dstCoords[2*i]   = (GLfloat)tc2[0];
		  dstCoords[2*i+1] = (GLfloat)tc2[1];
	      }
	  }
	  break;
      }
	sOffset = 2;
	tOffset = sOffset * nsCoords;
    }


    //
    // Draw the NURBS surface.  Begin the surface.  Then load the texture
    // map as a nurbs surface.  Then, draw the geometric surface followed
    // by all of its trim curves.  Then, end the surface.
    //
    glEnable(GL_AUTO_NORMAL);

    // Get one camera based element so that this node will be registered
    // with the cache.  If the camera changes, this element will cause
    // the cache to be blown for this node and the nurbs surface will be
    // regenerated.
    SbMatrix vMat = SoViewingMatrixElement::get (action->getState());
    SbMatrix mMat = SoModelMatrixElement::get (action->getState());

    // Begin the surface.
    gluBeginSurface(nurbsObj);

    // Draw the texture surface
    if(doTextures) {
	// send down nurbs surface, then free memory
	gluNurbsSurface(nurbsObj, (GLint)nsKnots, sKnots,
                     (GLint)ntKnots, tKnots,
		     (GLint)sOffset, (GLint)tOffset, dstCoords,
		     (GLint)(nsKnots - nsCoords),
                     (GLint)(ntKnots - ntCoords),
                     GL_MAP2_TEXTURE_COORD_2);

	// delete knots if not sharing them with the surface description
	// (in the case of software texture coordinates only)
	if(sKnots != duKnots) {
	    delete [] sKnots;
	    delete [] tKnots;
	}
	delete [] dstCoords;
    }

    gluNurbsSurface (nurbsObj, (GLint)(uKnotVector.getNum()), duKnots,
                    (GLint)(vKnotVector.getNum()), dvKnots,
                    (GLint)uOffset, (GLint)vOffset, dCoords,
                    (GLint)(uKnotVector.getNum() -
                        numUControlPoints.getValue()),
                    (GLint)(vKnotVector.getNum() -
                        numVControlPoints.getValue()),
                    type);

    //
    // Get all of the trim curves and use them to trim the surface.
    //
    SoProfile        *profile;
    const SoNodeList &trimNodes = SoProfileElement::get(action->getState());
    SbBool           haveTrim = FALSE;
    float            *trimCoords, *trimKnots;
    int32_t             numTrimCoords, numKnots, offset;
    int              numTrims = trimNodes.getLength();
    int              floatsPerVec;

    //
    // For each trim curve, check its linkage to find out if it should be
    // continued on to the previous trim curve or if it should begin a
    // new trim curve.  Then, send the trim to the NURBS library.
    //
    for (i=0; i<numTrims; i++)
    {
        GLfloat *dTrimCoords;
        GLfloat *dtmp;
        float   *ftmp;

        // Get the trim curve.
        profile = (SoProfile *)trimNodes[(int) i];
    	profile->getTrimCurve (action->getState(), numTrimCoords,
                               trimCoords, floatsPerVec,
                               numKnots, trimKnots);

        // Check for degenerate trim curves
        if (numTrimCoords == 0)
            continue;

        // Check the linkage.
        if ((profile->linkage.getValue() == SoProfileElement::START_FIRST) ||
            (profile->linkage.getValue() == SoProfileElement::START_NEW))
        {
            if (haveTrim)
               gluEndTrim(nurbsObj);
            gluBeginTrim(nurbsObj);
            haveTrim = TRUE;
        }

        // Set the data type of the control points to non-rational or rational
        if (floatsPerVec == 2)
            type = (GLenum)GLU_MAP1_TRIM_2;
        else
            type = (GLenum)GLU_MAP1_TRIM_3;
        offset = floatsPerVec;

        dTrimCoords = new GLfloat[numTrimCoords*floatsPerVec];
        dtmp = dTrimCoords;
        ftmp = trimCoords;
        for (j=0; j<floatsPerVec*numTrimCoords; j++)
            *dtmp++ = (GLfloat)(*ftmp++);
            
        if (numKnots == 0)
        {
            // Send down a Piecewise Linear Trim Curve
            gluPwlCurve (nurbsObj, (GLint)numTrimCoords, dTrimCoords,
                    (GLint)offset, type);
         }
        else
        {
            // Send down a NURBS Trim Curve
            GLfloat *dTrimKnots = new GLfloat[numKnots];

            dtmp = dTrimKnots;
            ftmp = trimKnots;
            for (j=0; j<numKnots; j++)
                *dtmp++ = (GLfloat)(*ftmp++);
            
            gluNurbsCurve (nurbsObj, (GLint)numKnots, dTrimKnots,
                    (GLint)offset, dTrimCoords,
                    (GLint)(numKnots - numTrimCoords), type);
            delete[] dTrimKnots;
            delete[] trimKnots;
        }
        delete[] dTrimCoords;
        delete[] trimCoords;
    }
    if (haveTrim)
        gluEndTrim(nurbsObj);

    gluEndSurface(nurbsObj);
    gluDeleteNurbsRenderer(nurbsObj);
    glDisable(GL_AUTO_NORMAL);

    delete[] dvKnots;
    delete[] duKnots;
    delete[] dCoords;
}
/***************************************************************************
 Draw3dRibbon
 ****************************************************************************/
static void Draw3dRibbon(int snum){
    int i = 0;
    float comx = 0.0,
	comy = 0.0,
	comz = 0.0;
    float *cp = E_MALLOC(3*sizeof(float));
    float *inA = E_MALLOC(3*sizeof(float));
    float *inB = E_MALLOC(3*sizeof(float));
    float *inC = E_MALLOC(3*sizeof(float));
    float *out = E_MALLOC(3*sizeof(float));
	
    struct coord *c = state->coords[snum];
	
    for (i=0; i<c->size; i++){
        comx += c->rp_ca[i].x;
        comy += c->rp_ca[i].y;
        comz += c->rp_ca[i].z;
    }
    comx /= c->size;
    comy /= c->size;
    comz /= c->size;
    
    GLUnurbsObj *nurbs = gluNewNurbsRenderer();
    
    GLfloat* ctrlpts = E_MALLOC(12*sizeof(GLfloat)*(c->size-1));
    
    GLfloat* tracepts = E_MALLOC(3*sizeof(GLfloat)*c->size-1);
    
    for(i=0; i < c->size-1; i++){
        if((i) %2){
            ctrlpts[i*12]   = c->rp_c[i].x - comx;
            ctrlpts[i*12+1] = c->rp_c[i].y - comy;
            ctrlpts[i*12+2] = c->rp_c[i].z - comz;
        }
        else{
            ctrlpts[i*12]   = c->rp_o[i].x - comx;
            ctrlpts[i*12+1] = c->rp_o[i].y - comy;
            ctrlpts[i*12+2] = c->rp_o[i].z - comz;
        }
        
        inA[0] = c->rp_c[i].x - c->rp_ca[i].x;
        inA[1] = c->rp_c[i].y - c->rp_ca[i].y;
        inA[2] = c->rp_c[i].z - c->rp_ca[i].z;
        inB[0] = c->rp_c[i].x - c->rp_o[i].x;
        inB[1] = c->rp_c[i].y - c->rp_o[i].y;
        inB[2] = c->rp_c[i].z - c->rp_o[i].z;
        
        cross(cp, inA, inB);
        normalize(cp);
        
        inC[0] = ((c->rp_c[i].x + c->rp_ca[i].x) / 2) - comx;
        inC[1] = ((c->rp_c[i].y + c->rp_ca[i].y) / 2) - comy;
        inC[2] = ((c->rp_c[i].z + c->rp_ca[i].z) / 2) - comz;
        
        //cross(out, cp, inC);
        //normalize(out);
		
        ctrlpts[i*12+3] = inC[0] + cp[0];
        ctrlpts[i*12+4] = inC[1] + cp[1];
        ctrlpts[i*12+5] = inC[2] + cp[2];
        
        if((i) %2){
            ctrlpts[i*12+6] = c->rp_o[i].x - comx;
            ctrlpts[i*12+7] = c->rp_o[i].y - comy;
            ctrlpts[i*12+8] = c->rp_o[i].z - comz;
        }
        else{
            ctrlpts[i*12+6]   = c->rp_c[i].x - comx;
            ctrlpts[i*12+7] = c->rp_c[i].y - comy;
            ctrlpts[i*12+8] = c->rp_c[i].z - comz;
        }
        
        
		ctrlpts[i*12+9]  = inC[0] - cp[0];
		ctrlpts[i*12+10] = inC[1] - cp[1];
		ctrlpts[i*12+11] = inC[2] - cp[2];
		
		tracepts[i] = inC[0];
		tracepts[i+1] = inC[1];
		tracepts[i+2] = inC[2];
		
		//                printf("[%f, %f, %f], [%f, %f, %f] \n", 
		//                       cp[0], cp[1], cp[2],
		//                       inC[0], inC[1], inC[2]);
        
		//        printf("[%f, %f, %f], [%f, %f, %f], [%f, %f, %f], [%f, %f, %f] \n",
		//               ctrlpts[i], ctrlpts[i+1] ,ctrlpts[i+2], ctrlpts[i+3], ctrlpts[i+4],
		//               ctrlpts[i+5], ctrlpts[i+6], ctrlpts[i+7], ctrlpts[i+8], ctrlpts[i+9], 
		//               ctrlpts[i+10], ctrlpts[i+11]);
        
    }
	
    free(cp);
    free(inA);
    free(inB);
    free(inC);
    free(out);
    
	GLfloat* uknots = E_MALLOC(sizeof(GLfloat)*(c->size+3));
	
	for(i=0; i < c->size+3; i++){
		if(i<c->size+1 && i>2){
			uknots[i] = uknots[i-1]+1.0;
		}
		else if(i<3){
			uknots[i] = 0.0;
		}
		else{
			uknots[i] = uknots[i-1]; 
		}
	}
	
	
	GLfloat vknots[8] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
	
	GLfloat* knots = E_MALLOC(sizeof(GLfloat)*(c->size+4));
	
	for(i=0; i < c->size+4; i++){
		
		if(i>c->size+2){
			knots[i]=knots[c->size+2];
		}
		else{
			knots[i]=i/1.0-i%1; 
		}
	}
	
	
	
	glColor3f(0.0, 0.0, 1.0);
	glEnable(GL_AUTO_NORMAL);
	glShadeModel(GL_SMOOTH);
	
	glPushMatrix();
	
	gluNurbsCallback(nurbs, GLU_ERROR, (GLvoid(*)())nurbsError);
	gluNurbsProperty(nurbs, GLU_V_STEP, 4);
	gluNurbsProperty(nurbs, GLU_U_STEP, 4);
	gluNurbsProperty(nurbs, GLU_CULLING, GL_TRUE);
	gluNurbsProperty(nurbs, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE);
	
	glShadeModel(GL_SMOOTH);
	
	gluBeginSurface(nurbs);
	
	gluNurbsSurface(nurbs,              //context object
					c->size+3,          //number of u-knots
					uknots,             //u-knot pointer
					8,                  //number of v-knots
					vknots,             //v-knot ptr
					3,                  //width of u-control points (u-stride)
					3,                  //width of v-control points (v-stride)
					ctrlpts,            //control point pointer
					4,                  // u-order of the curve (degree+1)
					4,                  // v-order of the curve (degree+1)
					GL_MAP2_TEXTURE_COORD_2    //type
					);
	
	gluNurbsSurface(nurbs,              //context object
					c->size+3,          //number of u-knots
					uknots,             //u-knot pointer
					8,                  //number of v-knots
					vknots,             //v-knot ptr
					3,                  //width of u-control points (u-stride)
					3,                  //width of v-control points (v-stride)
					ctrlpts,            //control point pointer
					4,                  // u-order of the curve (degree+1)
					4,                  // v-order of the curve (degree+1)
					GL_MAP2_NORMAL      //type
					);
	
	
	gluNurbsSurface(nurbs,              //context object
					c->size+3,          //number of u-knots
					uknots,             //u-knot pointer
					8,                  //number of v-knots
					vknots,             //v-knot ptr
					3,                  //width of u-control points (u-stride)
					3,                  //width of v-control points (v-stride)
					ctrlpts,            //control point pointer
					4,                  // u-order of the curve (degree+1)
					4,                  // v-order of the curve (degree+1)
					GL_MAP2_VERTEX_3    //type
					);
	
	
	gluEndSurface(nurbs);
	/*
	 gluBeginCurve(nurbs);
	 gluNurbsCurve(nurbs,              //context object
	 c->size+4,          //number of knots
	 knots,              //knot pointer
	 3,                  //width of control points
	 tracepts,  //control point pointer
	 4,                  //order of the curve (degree+1)
	 GL_MAP1_VERTEX_3    //type
	 );
	 
	 gluEndCurve(nurbs);
	 */
	glPopMatrix();
}