前言:
此时姐妹们对“多边形的扫描线连贯算法”都比较珍视,咱们都需要学习一些“多边形的扫描线连贯算法”的相关知识。那么小编同时在网摘上网罗了一些关于“多边形的扫描线连贯算法””的相关内容,希望咱们能喜欢,朋友们快快来学习一下吧!数据结构:
CPoint3D: 3维点类
CPolygon: 多边形类
CEdge: 边类
CActiveEdge: 活化边类
CScanLineZbufferProcess: 扫描线ZBuffer算法实现类,包括3ds文件加载,旋转,扫描过程,显示等。
CPoint3D
class CPoint3D{public: CPoint3D(void); CPoint3D(double a,double b,double c); ~CPoint3D(void); CPoint3D(CPoint3D&rth); CPoint3D&operator=(CPoint3D&rth); CPoint GetPoint2D();public: double x; double y; double z; };CPoint3D::CPoint3D(void){ x=y=z=0;}CPoint3D::CPoint3D(double a,double b,double c){ x=a;y=b;z=c;}CPoint3D::CPoint3D(CPoint3D&rth){ x=rth.x; y=rth.y; z=rth.z;}CPoint3D& CPoint3D::operator=(CPoint3D&rth){ x=rth.x; y=rth.y; z=rth.z; return *this;}CPoint CPoint3D::GetPoint2D(){ CPoint p(x,y); return p;}CPoint3D::~CPoint3D(void){}CEdge 类
class CEdge{public: CEdge(void); CEdge(CEdge &rth); ~CEdge(void);public: CEdge&operator=(CEdge &rth); void Points2Edge(CPoint3D p1, CPoint3D p2);public: double x;//边的上端点x的坐标 double dx;//相邻两条扫描线交点的x坐标差dx (-1/k) int dy;//边跨越的扫描线数目 int id;//边所属多边形的编号 int yMax;// CEdge *next;};CEdge::CEdge(void){ x =0; dx = 0; dy = 0; id =-1; next = NULL; yMax = -100000;} CEdge::CEdge(CEdge &rth){ x = rth.x; dx = rth.dx; dy = rth.dy; id = rth.id; next = rth.next; yMax = rth.yMax;}CEdge& CEdge::operator=(CEdge &rth){ x = rth.x; dx = rth.dx; dy = rth.dy; id = rth.id; next = rth.next; yMax = rth.yMax; return *this;}CEdge::~CEdge(void){ if(next) delete next;}void CEdge::Points2Edge(CPoint3D p1, CPoint3D p2){ /*CPoint3D topPoint = p1; yMax = p1.y; dy = abs(p1.y-p2.y);*/ dy = abs(p1.y-p2.y); if(p1.y>p2.y) {//p1是TOP point yMax = p1.y; x = p1.x; if(dy!=0) { dx = (p2.x-p1.x)/(p1.y-p2.y); } } else { //p2是TOP point yMax = p2.y; x = p2.x; if(dy!=0) { dx = (p1.x-p2.x)/(p2.y-p1.y); } } dy+=1;}CEdgeList
class CEdgeList{public: CEdgeList(void); ~CEdgeList(void);public: int ymax; CEdge *head;};CEdgeList::CEdgeList(void){ ymax = -1; head= NULL;}CEdgeList::~CEdgeList(void){}CActiveEdge
class CActiveEdge{public: CActiveEdge(void); ~CActiveEdge(void);public: double xl;//左交点的x坐标 double dxl;//(左交点边上)两相邻扫描线交点的x坐标之差 int dyl;//以和左交点所在边相交的扫描线数为初值, double xr;//右交点的x坐标 double dxr;//(右交点边上)两相邻扫描线交点的x坐标之差 int dyr;//以和右交点所在边相交的扫描线数为初值, double zl;//左交点处多边形所在平面的深度值; double dzx;//沿扫描线向右走过一个像素时,多边形所在平面的深度增量。对于平面方程,dzx=-a/c(c≠0); double dzy;//沿y方向向下移过一根扫描线时,多边形所在平面的深度增量。对于平面方程,dzy=b/c(c≠0); int id;//交点对所在的多边形的编号; CActiveEdge *next;};CActiveEdge::CActiveEdge(void){ dxl =0; dxr=0; dyl=0; dyr=0; dzx=0; dzy=0; xl=0; xr=0; zl=0; next =NULL; id =-1;}CActiveEdge::~CActiveEdge(void){}CPolygon
//这里的多边形都是三角形,方便计算class CPolygon{public: CPolygon(void); CPolygon(CPolygon &rth); void Point2Face(CPoint3D p1, CPoint3D p2, CPoint3D p3); void Point2Face(CPoint3D *p,int npoints); void get_dy(); CEdge* getEdgeList();//获取边表 void ClearHorizontalEdge();//清除水平边.平行X的边 ~CPolygon(void);public: CPolygon&operator=(CPolygon &rth);public: double a,b,c,d;//多边形所在平面的方程系数ax+by+cz+d=0 int id;//多边形的编号 int dy;//多边形跨越的扫描线数目 COLORREF color;//多边形的颜色 int yMax; int nPoints;//点数 CPolygon *next; CPoint3D *point;//按顺序的点,要求前三个不能是共线的点};#include "StdAfx.h"#include "Polygon.h"CPolygon::CPolygon(void){ a = 0; b = 0; c = 0; d = 0; id =-1; dy = 0; color = RGB(255,255,255);//默认底色为白 next = NULL; nPoints = 0; yMax = -100000;}CPolygon::CPolygon(CPolygon &rth){ a = rth.a; b = rth.b; c = rth.c; d = rth.d; id = rth.id; dy = rth.dy; color = rth.color; next = rth.next;}CPolygon& CPolygon::operator=(CPolygon &rth){ a =rth.a; b =rth.b; c =rth.c; d = rth.d; id = rth.id; dy = rth.dy; color = rth.color; point = rth.point; nPoints = rth.nPoints; next = rth.next; return *this;}//三点不共线下求平面方程参数void CPolygon::Point2Face(CPoint3D p1, CPoint3D p2, CPoint3D p3){ double x1 = p1.x, y1 = p1.y, z1 = p1.z; double x2 = p2.x, y2 = p2.y, z2 = p2.z; double x3 = p3.x, y3 = p3.y, z3 = p3.z; a = (y2-y1)*(z3-z1)-(y3-y1)*(z2-z1); b = (x3-x1)*(z2-z1)-(x2-x1)*(z3-z1); c = (x2-x1)*(y3-y1)-(x3-x1)*(y2-y1); d = -(a*x1+b*y1+c*z1);}//void CPolygon::Point2Face(CPoint3D *p,int npoints){ point = p; nPoints = npoints; Point2Face(p[0],p[1],p[2]);}//求出dyvoid CPolygon::get_dy(){ CPoint3D *p = point; int yMin = 100000; for(int i=0;i<nPoints;i++) { CPoint3D *tp = p++; if(yMax < tp->y) yMax = tp->y; if(yMin>tp->y) yMin = tp->y; } dy = yMax - yMin + 1;}//获取边表CEdge* CPolygon::getEdgeList(){ CEdge* pHead = NULL;// = new CEdge(); /*pHead->Points2Edge(point[0], point[1]); pHead->id = id;*/ CEdge* pOld = NULL;// = pHead; for(int i=0;i<nPoints;i++) { int j = (i+1)%nPoints; if(point[i].y== point[j].y)//水平边不加入边表 continue; CEdge* pt = new CEdge(); pt->Points2Edge(point[i], point[j]); pt->id = id; pt->next = NULL; if(pHead==NULL) { pHead = pt; pOld = pt; } else { pOld->next = pt; pOld = pt; } } return pHead;}void CPolygon::ClearHorizontalEdge(){}CPolygon::~CPolygon(void){ if(next) delete next;}
CPolygonList
#pragma once#include "Polygon.h"class CPolygonList{public: CPolygonList(void); ~CPolygonList(void);public: int yMax;//多边形的最大y坐标 CPolygon *head;};CPolygonList::CPolygonList(void){ yMax = -1; head = NULL;}CPolygonList::~CPolygonList(void){}CScanLineZbufferProcess
class CScanLineZbufferProcess{public: CScanLineZbufferProcess(void); ~CScanLineZbufferProcess(void);public: int nWidth,nHeight;//显示屏幕的尺寸 CPaintDC *pDC; CPolygonList *PolygonList;//分类的多边形表 CEdgeList *EdgeList;//分类边表 CPolygonList *ActivePolygonList;//活化分类的多边形表 CActiveEdge *ActiveEdgeList;//活化分类边表 COLORREF *FrameBuffer;//帧缓冲器 double *ZBuffer;//z缓冲器 COLORREF BackGroundColor;//背景色 double minZ;//最小z值public: void InitBuffer(int width,int height,CPaintDC *pdc); //void InitPolygonListEdgeList(); void SortEdge(CEdge* pEdge); bool AddActivePolygonList(int y);//添加新多边形进活化多边形表 void UpdateActivePolygonList();//更新多边形进活化多边形表 bool AddActiveEdgeList(int y);//添加新边堆到活化边表 void UpdateActiveEdgeList( int y);//更新新边对中的一边,由于一边结束,而多边形还在扫描区域,删除一条边,加入新边 bool IsInActivePolygonList(int id);//指定的多边形是否在活化多边形表中 COLORREF GetPolygonColor(int id);//获取多边形的颜色 void UpdateZBufferColor(int y); void Scan(); void Show(); void OnX(double angle, CPoint3D *p); void OnY(double angle, CPoint3D *p); void AddFace(CPoint3D *pFacePoint,int npoints, COLORREF faceColor);//增加面 int faceid;public: Lib3dsFile *model; bool Load3ds(char *argv);//加载3ds文件 void render_node(Lib3dsNode *node); bool bInit; float m_Scale;//缩放比例 float m_Max; void getScalFor3dsFile(char *argv); void get_nodeMax(Lib3dsNode *node) ; void Clear();//清除所有数据 bool m_bYZ; bool m_EdgeShow; double angle_x;//绕x轴旋转角度 double angle_y;//绕y轴旋转角度
#include "StdAfx.h"#include "ScanLineZbufferProcess.h"#include <math.h>CScanLineZbufferProcess::CScanLineZbufferProcess(void){ faceid = -1; BackGroundColor = RGB(255,255,255);//背景为白色 minZ = -100000; bInit = false; m_bYZ = false;//false:Y轴在上,Z轴为深度 true:Z轴在上,Y轴为深度 angle_x = 0.0; angle_y = 0.0; m_EdgeShow = false;}CScanLineZbufferProcess::~CScanLineZbufferProcess(void){ Clear();}//清除所有数据void CScanLineZbufferProcess::Clear(){ for(int y = nHeight/2; y>-nHeight/2;y--)//从上往下扫描 { try { //删除多边形表 CPolygon *oldPolygon = PolygonList[y+nHeight/2].head;//y是当前的扫描线y值 if(oldPolygon) delete oldPolygon; PolygonList[y+nHeight/2].head = NULL; CEdge* tpEdge = EdgeList[y+nHeight/2].head;//删除边表 if(tpEdge) delete tpEdge; EdgeList[y+nHeight/2].head = NULL; } catch(...) { } } //清除FrameBuffer、ZBuffer int nCount = nWidth*nHeight; for(int i=0;i<nCount;i++) { FrameBuffer[i] = BackGroundColor; ZBuffer[i] = minZ; } faceid = -1; angle_x = 0.0; angle_y = 0.0;}//初始化buffervoid CScanLineZbufferProcess::InitBuffer(int width,int height,CPaintDC *pdc){ faceid = -1; nWidth = width; nHeight = height; pDC = pdc; int nCount = nWidth*nHeight; FrameBuffer = new COLORREF[nCount]; ZBuffer = new double[nCount]; for(int i=0;i<nCount;i++) { FrameBuffer[i] = BackGroundColor; ZBuffer[i] = minZ; } PolygonList = new CPolygonList[nHeight+1]; EdgeList = new CEdgeList[nHeight+1]; bInit = true;}//增加面void CScanLineZbufferProcess::AddFace(CPoint3D *pFacePoint,int npoints, COLORREF faceColor){ CPolygon *face = new CPolygon(); face->Point2Face(pFacePoint, 3); face->id = ++faceid; face->color = faceColor; face->get_dy(); if(face->c!=0) {//与xoy面没有投影的面去掉 face->next = PolygonList[face->yMax+nHeight/2].head; PolygonList[face->yMax+nHeight/2].head = face;//多边形表 CEdge *pEdge = face->getEdgeList();//边表 SortEdge(pEdge); }}//将边按照yMax存入相应的边表void CScanLineZbufferProcess::SortEdge(CEdge* pEdge){ CEdge* tpEdge = pEdge; do { CEdge* tOldpEdge = tpEdge->next; if(tpEdge->yMax+nHeight/2<=nHeight)//去除Ymax超过边界的值 { tpEdge->next = EdgeList[tpEdge->yMax+nHeight/2].head; EdgeList[tpEdge->yMax+nHeight/2].head = tpEdge;//坐标原点在画板中心 EdgeList[tpEdge->yMax+nHeight/2].ymax = tpEdge->yMax; } tpEdge = tOldpEdge; }while(tpEdge);}//step1 添加活化多边形表bool CScanLineZbufferProcess::AddActivePolygonList(int y){ if(PolygonList[y+nHeight/2].head!=NULL) { CPolygon *tPolygon = ActivePolygonList->head; while(tPolygon && tPolygon->next) { tPolygon = tPolygon->next; } CPolygon *oldPolygon = PolygonList[y+nHeight/2].head;//y是当前的扫描线y值 while(oldPolygon) { if(oldPolygon->c!=0) { CPolygon *tnewPolygon = new CPolygon(); *tnewPolygon = *oldPolygon; if(ActivePolygonList->head==NULL) { ActivePolygonList->head = tnewPolygon; } else { tPolygon->next = tnewPolygon; } tPolygon = tnewPolygon; } oldPolygon = oldPolygon->next; } return true;//有新多边形加入 } return false;}//更新活化多边形表,删除不再扫描区域的多边形void CScanLineZbufferProcess::UpdateActivePolygonList(){ //活化多边形表中的元素修改 CPolygon *tPolygon = ActivePolygonList->head; CPolygon *tOldPolygon = tPolygon; while(tPolygon) { tPolygon->dy -=1;//每一个多边形的dy:dy = dy-1 if(tPolygon->dy<=0)//当dy <=0时,该多边形要从多边形活化表中删除 { if(ActivePolygonList->head==tPolygon) ActivePolygonList->head = tPolygon->next;//删除第一个节点 else { tOldPolygon->next = tPolygon->next; } } else {//不删除,才需更新上一个指针 tOldPolygon = tPolygon; } tPolygon = tPolygon->next; }}//有新多边形加入时添加新边对到活化边表bool CScanLineZbufferProcess::AddActiveEdgeList(int y){ CPolygon* tPolygon = PolygonList[y+nHeight/2].head; while(tPolygon) { int i=0; CEdge* tpEdge = EdgeList[y+nHeight/2].head;//这里的多边形都是三角形,方便计算 CActiveEdge* tActiveEdge = new CActiveEdge(); while(tpEdge) { if(tpEdge->id==tPolygon->id) { if(tpEdge->dy<=1)//是水平线 { tpEdge = tpEdge->next; continue; } if(i==0) { tActiveEdge->id = tPolygon->id; tActiveEdge->dxl = tpEdge->dx; tActiveEdge->dyl = tpEdge->dy; tActiveEdge->xl = tpEdge->x; tActiveEdge->dzx = -(tPolygon->a / tPolygon->c); tActiveEdge->dzy = tPolygon->b / tPolygon->c; tActiveEdge->zl = -( tPolygon->a * tpEdge->x + tPolygon->b*y +tPolygon->d )/tPolygon->c; i++; } else { if((tActiveEdge->xl + tActiveEdge->dxl) > (tpEdge->x+tpEdge->dx)) {//左右两边交换 tActiveEdge->dxr = tActiveEdge->dxl; tActiveEdge->dyr = tActiveEdge->dyl; tActiveEdge->xr = tActiveEdge->xl; tActiveEdge->dxl = tpEdge->dx; tActiveEdge->dyl = tpEdge->dy; tActiveEdge->xl = tpEdge->x; } else { tActiveEdge->dxr = tpEdge->dx; tActiveEdge->dyr = tpEdge->dy; tActiveEdge->xr = tpEdge->x; } /******************加入活化表*****************************/ if(ActiveEdgeList==NULL||ActiveEdgeList->id==-1) ActiveEdgeList = tActiveEdge; else { tActiveEdge->next = ActiveEdgeList;//插入表头 ActiveEdgeList = tActiveEdge; } /*******************end 加入活化表**************************/ i = 0; break;//寻找下一个多边形 } } tpEdge = tpEdge->next; } tPolygon = tPolygon->next; } return true;}//更新活化边表void CScanLineZbufferProcess::UpdateActiveEdgeList(int y){ CActiveEdge *tActiveEdgeList = ActiveEdgeList; CActiveEdge *tOldActiveEdgeList = tActiveEdgeList; while(tActiveEdgeList&&tActiveEdgeList->id!=-1) { tActiveEdgeList->dyl -=1; tActiveEdgeList->dyr -=1; tActiveEdgeList->xl +=tActiveEdgeList->dxl; tActiveEdgeList->xr +=tActiveEdgeList->dxr;//边和下一条扫描线交点的x值 tActiveEdgeList->zl += tActiveEdgeList->dzx * tActiveEdgeList->dxl + tActiveEdgeList->dzy; //若dyl或dyr小于0,相应的边就要从一个边对 if(tActiveEdgeList->dyl<=0||tActiveEdgeList->dyr<=0) { if(IsInActivePolygonList(tActiveEdgeList->id)) { tOldActiveEdgeList = tActiveEdgeList;//保存为前向节点 //还在活化多边形表中,选择修改边对,删除原来的,加入新边 CEdge *tpEdge = EdgeList[y+nHeight/2].head; while(tpEdge) { if(tpEdge->id==tActiveEdgeList->id) { if(tActiveEdgeList->dyl<=0) { //更新左边 tActiveEdgeList->dxl = tpEdge->dx; tActiveEdgeList->dyl = tpEdge->dy; tActiveEdgeList->xl = tpEdge->x; } else {//更新右边 tActiveEdgeList->dxr = tpEdge->dx; tActiveEdgeList->dyr = tpEdge->dy; tActiveEdgeList->xr = tpEdge->x; } break; } tpEdge = tpEdge->next; } } else { //删除该边对 if(tActiveEdgeList == ActiveEdgeList) { //表头 ActiveEdgeList = tActiveEdgeList->next; tOldActiveEdgeList = ActiveEdgeList; } else { tOldActiveEdgeList->next = tActiveEdgeList->next; } } } else { tOldActiveEdgeList = tActiveEdgeList;//保存为前向节点 } tActiveEdgeList = tActiveEdgeList->next;//下一个边对 }}//获取多边形颜色值COLORREF CScanLineZbufferProcess::GetPolygonColor(int id){ CPolygon *tPolygon = ActivePolygonList->head; while(tPolygon) { if(tPolygon->id == id) { return tPolygon->color; } tPolygon = tPolygon->next; } return this->BackGroundColor;//没找到返回背景色}//指定的多边形是否在活化多边形表中bool CScanLineZbufferProcess::IsInActivePolygonList(int id){ CPolygon *tPolygon = ActivePolygonList->head; while(tPolygon) { if(tPolygon->id == id) { return true; } tPolygon = tPolygon->next; } return false;}//step2 增量式的深度更新void CScanLineZbufferProcess::UpdateZBufferColor(int y){ CActiveEdge *tActiveEdgeList = ActiveEdgeList; while(tActiveEdgeList && tActiveEdgeList->id!=-1) { double Zx = tActiveEdgeList->zl; for(int x = tActiveEdgeList->xl;x<=tActiveEdgeList->xr;x++) { if(abs(x)>nWidth/2) { Zx += tActiveEdgeList->dzx; continue; } int index = (nHeight/2-y)*nWidth + nWidth/2+x; if(Zx > ZBuffer[index]) { ZBuffer[index] = Zx;//更新深度值 if(m_EdgeShow) { if( x == (int)tActiveEdgeList->xl || x==(int)tActiveEdgeList->xr) FrameBuffer[index] = RGB(255,255,255);//边界线都是白色 else { FrameBuffer[index] = GetPolygonColor(tActiveEdgeList->id);//更新颜色 } } else { FrameBuffer[index] = GetPolygonColor(tActiveEdgeList->id);//更新颜色 } } Zx += tActiveEdgeList->dzx; } tActiveEdgeList = tActiveEdgeList->next;//下一个边对 }}//扫描void CScanLineZbufferProcess::Scan(){ ActivePolygonList = new CPolygonList();//活化多边形表 ActiveEdgeList = new CActiveEdge();//活化边表 for(int y = nHeight/2; y>-nHeight/2;y--)//从上往下扫描 { try { //step1 添加新的多边形进活化多边形表,有新多变形加入时添加边对进活化边表 AddActivePolygonList(y); AddActiveEdgeList(y); //step2 增量式的深度更新 UpdateZBufferColor(y); //活化多边形表中的元素修改 UpdateActivePolygonList(); //step3 活化边表中的元素修改:修改后的活化边表是下一条扫描线的活化边表 UpdateActiveEdgeList(y); } catch(...) { AfxMessageBox(_T("出错!")); } }}//显示FrameBuffer图形void CScanLineZbufferProcess::Show(){//dc 的原点在(nWidth/2,nHeight/2)] for(int y=nHeight/2; y>-nHeight/2; y--) { for(int x=-nWidth/2; x<nWidth/2; x++) { int index = (nHeight/2-y)*nWidth + nWidth/2+x; pDC->SetPixel(x,y,FrameBuffer[index]); } } }void CScanLineZbufferProcess::OnX(double angle, CPoint3D *p){ float x=p->x; float y=cos(angle)*p->y-sin(angle)*p->z; float z=sin(angle)*p->y+cos(angle)*p->z; *p = CPoint3D((int)x,(int)y,(int)z); }void CScanLineZbufferProcess::OnY(double angle, CPoint3D *p){ float y=p->y; float x=cos(angle)*p->x-sin(angle)*p->z; float z=sin(angle)*p->x+cos(angle)*p->z; *p = CPoint3D((int)x,(int)y,(int)z);}/***************************************load 3ds********************************************/void CScanLineZbufferProcess::render_node(Lib3dsNode *node) { Lib3dsNode *p; Lib3dsMesh *mesh; Lib3dsFace *face; Lib3dsMaterial *mat; Lib3dsMeshInstanceNode *meshData; // 递归 for (p=node->childs; p!=0; p=p->next) { render_node(p); } if (strcmp(node->name,"$$$DUMMY")==0)//检查是否是mesh { return; } if (!node->user_id) { mesh = lib3ds_file_mesh_for_node(model, node); if (!mesh || !mesh->vertices) return; COLORREF faceColor = BackGroundColor; for (int fi=0; fi<mesh->nfaces; ++fi) { face = &(mesh->faces[fi]); mat = 0; CPoint3D pFacePoint[3]; for(int i=0;i<3;i++) { float a = mesh->vertices[face->index[i]][0]/m_Scale; float b = mesh->vertices[face->index[i]][1]/m_Scale; float c = mesh->vertices[face->index[i]][2]/m_Scale; if(abs(a)>=nWidth/2||abs(b)>=nHeight/2) goto next; if(!this->m_bYZ) { pFacePoint[i] = CPoint3D(a,b,c); } else { pFacePoint[i] = CPoint3D(a,c,b);//YZ轴对调 } OnX(this->angle_x, &pFacePoint[i]);//绕x轴旋转 OnY(this->angle_y, &pFacePoint[i]);//绕y轴旋转 } if (face->material>=0 && face->material<model->nmaterials) { mat=model->materials[face->material]; faceColor = RGB(mat->diffuse[0]*255, mat->diffuse[1]*255, mat->diffuse[2]*255); } else { faceColor = BackGroundColor; } AddFace(pFacePoint,3, faceColor);next: continue; } }}//加载3ds文件bool CScanLineZbufferProcess::Load3ds(char *argv){ getScalFor3dsFile(argv);//计算缩放比例 model = lib3ds_file_open(argv);//加载点位 if (!model) { //fprintf(stderr, "***ERROR***\nLoading file failed: \n"); //exit(1); AfxMessageBox(_T("打开3ds文件出错\n")); return false; } Lib3dsNode *nod; for (nod=model->nodes; nod!=NULL; nod=nod->next) { if(nod->type==LIB3DS_NODE_MESH_INSTANCE) { render_node(nod); } } lib3ds_file_free(model); return true;}/*************************************end load3ds****************************************//***************************************获取3ds文件的缩放比例**********************************************/void CScanLineZbufferProcess::getScalFor3dsFile(char *argv){ m_Scale = 1.0;//默认是1 m_Max = 0; model = lib3ds_file_open(argv); if (!model) { //fprintf(stderr, "***ERROR***\nLoading file failed: \n"); //exit(1); AfxMessageBox(_T("打开3ds文件出错\n")); return; } Lib3dsNode *nod; for (nod=model->nodes; nod!=NULL; nod=nod->next) { if(nod->type==LIB3DS_NODE_MESH_INSTANCE) { get_nodeMax(nod); } } lib3ds_file_free(model); if(m_Max!=0) { m_Scale = 2*m_Max / (nHeight-5); }}void CScanLineZbufferProcess::get_nodeMax(Lib3dsNode *node) { Lib3dsNode *p; Lib3dsMesh *mesh; Lib3dsFace *face; Lib3dsMaterial *mat; Lib3dsMeshInstanceNode *meshData; // 递归 for (p=node->childs; p!=0; p=p->next) { get_nodeMax(p); } if (strcmp(node->name,"$$$DUMMY")==0)//检查是否是mesh { return; } if (!node->user_id) { mesh = lib3ds_file_mesh_for_node(model, node); if (!mesh || !mesh->vertices) return; COLORREF faceColor = BackGroundColor; for (int fi=0; fi<mesh->nfaces; ++fi) { face = &(mesh->faces[fi]); mat = 0; CPoint3D pFacePoint[3]; for(int i=0;i<3;i++) { float a = mesh->vertices[face->index[i]][0]; float b = mesh->vertices[face->index[i]][1]; float c = mesh->vertices[face->index[i]][2]; if(abs(a)>m_Max) m_Max = abs(a); if(abs(b)>m_Max) m_Max = abs(b); if(abs(c)>m_Max) m_Max = abs(c); } } }}/*****************************************end********************************************/
0人点赞
图形学
版权声明:
本站文章均来自互联网搜集,如有侵犯您的权益,请联系我们删除,谢谢。
标签: #多边形的扫描线连贯算法