注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Mr.Right

不顾一切的去想,于是我们有了梦想。脚踏实地的去做,于是梦想成了现实。

 
 
 

日志

 
 
关于我

人生一年又一年,只要每年都有所积累,有所成长,都有那么一次自己认为满意的花开时刻就好。即使一时不顺,也要敞开胸怀。生命的荣枯并不是简单的重复,一时的得失不是成败的尺度。花开不是荣耀,而是一个美丽的结束,花谢也不是耻辱,而是一个低调的开始。

网易考拉推荐

OpenGL nurbs建模和polygon建模  

2013-01-25 15:15:50|  分类: 编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

现实场景建模原来分为NURBS建模和Polygon建模

曲面建模

也称为NURBS建模,NURBS是Non-Uniform Rational B-Splines的缩写,是“非统一有理B样条”的意思。具体解释是:.Non-Uniform(非统一)——是指一个控制顶点的影响力的范围能够改变。当创建一个不规则曲面的时候这一点非常有用。同样,统一的曲线和曲面在透视投影下也不是无变化的,对于交互的3D建模来说这是一个严重的缺陷;Rational(有理)——是指每个NURBS物体都可以用数学表达式来定义;B-Spline(B样条)——是指用路线来构建一条曲线,在一个或更多的点之间以内插值替换的。
简单地说,NURBS就是专门做曲面物体的一种造型方法。NURBS造型总是由曲线和曲面来定义的,所以要在NURBS表面里生成一条有棱角的边是很困难的。就是因为这一特点,我们可以用它做出各种复杂的曲面造型和表现特殊的效果,如人的皮肤,面貌或流线型的跑车等。
曲面建模既NURBS建模,是由曲线组成曲面,再有曲面组成立体模型,曲线有控制点可以控制曲线曲率、方向、长短。属于目前两大流行建模方式之一,另一种是多边形建模。

多边形建模
就是Polygon建模,翻译成中文是多边形建模,是目前三维软件两大流行建模方法之一,(另一个是曲面建模,)用这种方法创建的物体表面由直线组成。在建筑方面用的多,例如室内设计,环境艺术设计。
Polygon建模是一种常见的建模方式。首先使一个对象转化为可编辑的多边形对象,然后通过对该多边形对象的各种子对像进行编辑和修改来实现建模过程。对于可编辑多边形对象,它包含了Vertex(节点)、Edge(边界)、 Border(边界环)、 Polygon(多边形面)、 Element(元素)5种子对象模式,与可编辑网格相比,可编辑多边形显示了更大的优越性,即多边形对象的面不只可以是三角形面和四边形面,而且可以是具有任何多个节点的多边形面。

1. 多边形就是由多条边围成的一个闭合的路径形成的一个面。
2. 顶点Vertex:线段的端点,构成多边形的最基本元素。
3. 边Edge: 就是一条连接两个多边形顶点的直线段。
4. 面Face: 就是由多边形的边所围成的一个面。 Maya允许由三条以上的边构成一个多边形面。(三角面是所有建模的基础。在渲染前每种几何表面都被转化为三角形面,这个过程称为镶嵌)一般原则,尽量使用三边或四边面。
5. 法线Normal:表示面的方向。法线朝外的是正面,反之是背面。顶点也有法线,均匀和打散顶点法线可以控制多边形的平滑外观。

 

曲面建模的基本原则曲面建模不同于实体建模,其不是完全参数化的特征。在曲面建模时,需要注意以下几个基本原则:
1、创建曲面的边界曲线尽可能简单。一般情况下,曲线阶次不大于3。当需要曲率连续时,可以考虑使用五阶曲线。
2、用于创建曲面的边界曲线要保持光滑连续,避免产生尖角、交叉和重叠。另外在进行创建曲面时,需要对所利用的曲线进行曲率分析,曲率半径尽可能大,否则会造成加工困难和形状复杂。
3、避免创建非参数化曲面特征。
4、曲面要尽量简洁,面尽量做大。对不需要的部分要进行裁剪。曲面的张数要尽量少。
5、根据不同部件的形状特点,合理使用各种曲面特征创建方法。尽量采用实体修剪,再采用挖空方法创建薄壳零件。
6、曲面特征之间的圆角过渡尽可能在实体上进行操作。
7、曲面的曲率半径和内圆角半径不能太小,要略大于标准刀具的半径,否则容易造成加工困难。
编辑本段曲面建模的一般过程一般来说,创建曲面都是从曲线开始的。可以通过点创建曲线来创建曲面,也可以通过抽取或使用视图区已有的特征边缘线创建曲面。其一般的创建过程如下所示。
(1)首先创建曲线。可以用测量得到的云点创建曲线,也可以从光栅图像中勾勒出用户所需曲线。
(2)根据创建的曲线,利用过曲线、直纹、过曲线网格、扫掠等选项,创建产品的主要或者大面积的曲面。
(3)利用桥接面、二次截面、软倒圆、N-边曲面选项,对前面创建的曲面进行过渡接连、编辑或者光顺处理。最终得到完整的产品模型。

 --------------------------------------------------------------------------------------

// NURBS曲面 OPENGL程序
#include <windows.h>
#include <GL/glut.h>
GLUnurbsObj *theNurb1;
GLUnurbsObj *theNurb2;

GLfloat ctrlpoints[5][5][3] =
{
 {{-3,0.5,0},{-1,1.5,0},{-2,2,0},{1,-1,0},{-5,0,0}},
 {{-3,0.5,-1},{-1,1.5,-1},{-2,2,-1},{1,-1,-1},{-5,0,-1}},
 {{-3,0.5,-2},{-1,1.5,-2},{-2,2,-2},{1,-1,-2},{-5,0,-2}},
 {{-3,0.5,-3},{-1,1.5,-3},{-2,2,-3},{1,-1,-3},{-5,0,-3}},
 {{-3,0.5,-4},{-1,1.5,-4},{-2,2,-4},{1,-1,-4},{-5,0,-4}}
};//控制点
GLfloat mat_diffuse[] = {1.0,0.5,0.1,1.0};
GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
GLfloat mat_shininess[] = {100.0};
GLfloat light_position[] = {0.0,-10.0,0.0,1.0};
void myInit(void)
{
 glClearColor(1.0,1.0,1.0,0.0);//设置背景色
 
 glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
 glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
 glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
 glLightfv(GL_FRONT,GL_POSITION,light_position);//设置光源参数
 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//设置光照模型参数
 
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glDepthFunc(GL_LEQUAL);
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_LEQUAL);
 glEnable(GL_AUTO_NORMAL);
 glEnable(GL_NORMALIZE);
 
 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
 glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);
 glEnable(GL_BLEND);
 glFrontFace(GL_CW);
 glShadeModel(GL_SMOOTH);
 glEnable(GL_LINE_SMOOTH);
 theNurb1 = gluNewNurbsRenderer();//创建NURBS对象theNurb1
 gluNurbsProperty(theNurb1,GLU_SAMPLING_TOLERANCE,25.0);
 gluNurbsProperty(theNurb1,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON);
 theNurb2 = gluNewNurbsRenderer();//创建NURBS对象theNurb2
 gluNurbsProperty(theNurb2,GLU_SAMPLING_TOLERANCE,25.0);
 gluNurbsProperty(theNurb2,GLU_DISPLAY_MODE,GLU_FILL);
}
int spin = 0;

static void myKey(unsigned char key,int x,int y)
{
 switch(key)
 {
  case'd':
   spin = spin + 1;
   glRotatef(spin,1.0,1.0,0.0);
   glutPostRedisplay();
   break;
  case 27:
   exit(0);
  default:
   break;
 }
}

void myDisplay(void)
{
 GLfloat knots[10] = {0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0};
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 glRotatef(50.0,1.0,1.0,0.0);
 
 glPushMatrix();
 glTranslatef(1.0,0.0,0.0);
 gluBeginSurface(theNurb1);
 
 gluNurbsSurface(theNurb1,10,knots,10,knots,5*3,3,&ctrlpoints[0][0][0],5,5,GL_MAP2_VERTEX_3);
 gluEndSurface(theNurb1);
 glPopMatrix();
 
 glPushMatrix();
 glTranslatef(7.0,0.0,0.0);
 gluBeginSurface(theNurb2);
 
 gluNurbsSurface(theNurb2,10,knots,10,knots,5*3,3,&ctrlpoints[0][0][0],5,5,GL_MAP2_VERTEX_3);
 gluEndSurface(theNurb2);
 glPopMatrix();
 glutSwapBuffers();
}
void myReshape(GLsizei w,GLsizei h)
{
 glViewport(0,0,w,h);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluPerspective(50.0,(GLfloat)w/(GLfloat)h,1.0,15.0);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glTranslatef(0.0,0.0,-9.0);
}
int main(int argc,char ** argv)
{
 
 glutInit(&argc,argv);
 glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
 glutInitWindowSize(600,400);
 glutInitWindowPosition(200,200);
 
 glutCreateWindow("NURBS surface");
 
 myInit();
 glutKeyboardFunc(myKey);
 glutReshapeFunc(myReshape);
 glutDisplayFunc(myDisplay);
 
 glutMainLoop();
 return(0);
}

GLUnurbsObj* glNewNurbsRenderer()创建一个NURBS对象,并返回一个指向该对象的指针。如果没有足够的内存分配给该对象,则返回值为0。


void gluNurbsProperty(GLUnurbsObj* nobj, GLenum property, GLfloat value)设置NURBS属性。
nobj 指向NURBS对象的指针,property需设置的属性,value 设置指定属性的值。


glBeginSurface及gluEndSurface两个函数一起限定一个NURBS面的定义。返回值均为void,参数均为GLUnurbsObj* nobj,为指向NURBS对象的指针。


void gluNurbsSurface(GLUnurbsObj *nobj, Glint knot_count, GLfloat tknot_count, GLfloat *tknot, Glint s_stride, Glint t_stride, GLfloat *ctlarry, GLint sorder, GLint torder,GLenum type) 定义NURBS曲面形状。

nobj 指向NURBS对象的指针,sknot_count 参数化u方向上的节点数,sknot 参数化u方向上的非递减节点值,tknot_count 参数化v方向上的节点数,tknot 参数化v方向上的非递减节点值,s_stride在ctlarry中参数化u方向上相邻控制点的偏移量,t_stride在ctlarry中参数化v方向上相邻控制点的偏移量,ctlarryNURBS的控制点数组,sorder参数化u方向上NURBS的阶数,阶数比维数大1,torder参数化v方向上NURBS的阶数,阶数比维数大1,type曲面类型。
glutSwapBuffers函数交换了前后缓冲区,函数原型如下:void glutSwapBuffers();


 

 

 

-------------------------------------------------------

OpenGL使用glBegin(GL_POLYGON);语句来启动画多边形,而且只能是凸多边形。

绘制多边形,调用glEnable(GL_POLYGON_STIPPLE)来启动多边形绘制模式,可以调用函数glPolygonStipple()来设置多边形绘制模式。该函数的声明如下:

WINGDIAPI void APIENTRY glPolygonStipple (const GLubyte *mask);

参数mask是一个指向32x32位图的指针。与虚线绘制的道理一样,某位为1时绘制,为0时什么也不绘。注意,不用时用glDisable(GL_POLYGON_STIPPLE)关闭。

函数glPolygonMode()可以设置多边形的填充模式,声明如下:

WINGDIAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode);

参数face用来指定要填充的是多变形的哪一个面,可以取值:

GL_FRONT    正面(前面)
GL_BACK      反面(背面)
GL_FRONT_AND_BACK   正面和反面

参数mode用来指定要对多边形进行填充的模式,可以取值:

GL_POINT    轮廓点式多边形
GL_LINE     轮廓线式多边形
GL_FILL     全填充式多边形

下面是一个使用位图填充多边形的例子,代码如下所示:

include <windows.h>
#include <GL/glut.h>

void drawPolygon(void) {
glClear(GL_COLOR_BUFFER_BIT);
GLubyte pattern[128] = {  // 定义填充位图数组
        0x00,0x01,0x80,0x00,
        0x00,0x03,0xc0,0x00,
        0x00,0x07,0xe0,0x00,
        0x00,0x0f,0xf0,0x00,
        0x00,0x1f,0xf8,0x00,
        0x00,0x3f,0xfc,0x00,
        0x00,0x7f,0xfe,0x00,
        0x00,0xff,0xff,0x00,
        0x01,0xff,0xff,0x80,
        0x03,0xff,0xff,0xc0,
        0x07,0xff,0xff,0xe0,
        0x0f,0xff,0xff,0xf0,
        0x1f,0xff,0xff,0xf8,
        0x3f,0xff,0xff,0xfc,
        0x7f,0xff,0xff,0xfe,
        0xff,0xff,0xff,0xff,
        0xff,0xff,0xff,0xff,
        0x7f,0xff,0xff,0xfe,
        0x3f,0xff,0xff,0xfc,
        0x1f,0xff,0xff,0xf8,
        0x0f,0xff,0xff,0xf0,
        0x07,0xff,0xff,0xe0,
        0x03,0xff,0xff,0xc0,
        0x01,0xff,0xff,0x80,
        0x00,0xff,0xff,0x00,
        0x00,0x7f,0xfe,0x00,
        0x00,0x3f,0xfc,0x00,
        0x00,0x1f,0xf8,0x00,
        0x00,0x0f,0xf0,0x00,
        0x00,0x07,0xe0,0x00,
        0x00,0x03,0xc0,0x00,
        0x00,0x01,0x80,0x00
       };
glEnable(GL_POLYGON_STIPPLE); // 启动多边形填充模式
glPolygonStipple(pattern); //   指定填充位图数组
glPolygonMode(GL_BACK,GL_FILL);   // 设置正面填充模式
glPolygonMode(GL_FRONT,GL_POINT); // 设置反面填充模式
glBegin(GL_POLYGON);
glColor3f(1.0f,1.0f,1.0f);
glVertex3f(-0.3f,0.5f,0.0f);
glVertex3f(0.3f,0.5f,0.0f);
glVertex3f(0.5f,0.0f,0.0f);
glVertex3f(0.3f,-0.5f,0.0f);
glVertex3f(-0.3f,-0.5f,0.0f);
glVertex3f(-0.5f,0.0f,0.0f);
glEnd();
glDisable(GL_POLYGON_STIPPLE);

glFlush();
}

int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("OpenGL基本图元:多边形");
glutDisplayFunc(&drawPolygon);
glutMainLoop();
return 0;
}

  评论这张
 
阅读(1653)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016