注册 登录
开源计算机图形学社区(Open Source Computer Graphics Community) |OpenGPU Forum (2007-2013)| OpenGPU Project 返回首页

ColinKong60的个人空间 http://www.opengpu.org/?41323 [收藏] [复制] [分享] [RSS]

日志

几何体布尔运算的代码实现(DIY)

已有 798 次阅读2016-9-22 14:00 |个人分类:三维几何运算库| 布尔运算, stl模型

开发三维模型布尔运算的图形软件因其难度较大,具挑战性而激发了诸多有志者为之努力不懈,但也让许多尝试者怯步。本文推荐一款几何运算库,调用由(wsxdll)几何运算库提供的库函数可以使开发三维模型布尔运算的图形软件变得相对容易一些。

 

(wsxdll)几何运算库可以提供具有如下功能的库函数

  ▲对(stl)格式和(Obj)格式的三维模型实施布尔运算。

  ▲∵对三维模型实施布尔运算时,需要对二维几何图形和三维几何体实施诸多的几何运算

(wsxdll)几何运算库中还包含了具备如下功能的库函数

▼对二维多边形实施布尔运算

▼三角剖分二维多边形

▼计算二个几何体的交线()

▼计算二个三角形的交线

▼用一个平面或曲面剖切一个几何体

  …………

◆如何使用wsxdll几何运算库的库函数wd0200_BlnOp(…)

  wsxdll库函数需在一个编程环境,VC++,下使用。一份wsxdll几何运算库包含二个文件,(wsxdll.dll)(wsxdll.lib)。下面以VC++6.0为例说明如何使用wsxdll几何运算库提供的布尔运算函数wd0200_BlnOp(…)

 

选择File->New->Project,然后选择MFC AppWizard(exe),选择一个名字(,Demo_wsxdll),然后按OK。选(Single Document),其余的一概选默认,最后选择Finish。这样,一个名为(Demo_wsxdll)MFC工程就被创建好了。接下来就是给此(Demo_wsxdll) 工程加添界面菜单和编写代码。

▲把二个文件,(wsxdll.dll)(wsxdll.lib),拷入到(Demo_wsxdll)文件夹中

    

 ▲创建一个下拉式菜单:DemoBoolean Operation

    

   创建一个由菜单(DemoBln Op)触发的函数:void CDemo_wsxdllView::OnMenuitem_001()

    

▲加添以下代码,为编写函数OnMenuitem_001()的代码作铺垫

▼在文件(stdafx.h)的末尾加上

     #define c_Dim0154a       11//

#define c_Dim0154b       26//

#define c_Dim0106       200//

在文件(Demo_wsxdllView.cpp)头部加上

    #include <locale.h>

#include <fstream.h>//(盘录,装载)硬盘文件需此头文件

在文件(Demo_wsxdllView.cpp)中定义如下(4)个函数

    void CDemo_wsxdllDoc::Save_Path(CString sPath_ck,CString sFileType_ck,CString sPath_stlModel)

{//【函数功能】

     CString FileName=sPath_ck+"Path"+sFileType_ck;

     CString str_Line;//

     CStdioFile File;

     File.Open(FileName,CFile::modeCreate | CFile::modeWrite | CFile::typeText);

 

 

     File.WriteString(sPath_ck);//行写字符串(sPath_ck)(txt)目标文件(FileName),

                             //:字符串(strLine)未带换行符('\n')

     File.WriteString("\n");//

 

     //

     File.WriteString(sFileType_ck);//行写字符串(sPath_ck)(txt)目标文件(FileName),

                             //:字符串(strLine)未带换行符('\n')

     File.WriteString("\n");//

 

     //

     File.WriteString(sPath_stlModel);//行写字符串(sPath_ck)(txt)目标文件(FileName),

                             //:字符串(strLine)未带换行符('\n')

     File.WriteString("\n");//

     //

     File.Close();//关闭源文件()

     // 

     return;//

}

 

 

 

CString CDemo_wsxdllDoc::f006_392i_IntToString(int Value)

{//【函数功能】转整型为字符串

     CString str_Value;

     str_Value.Format("%d",Value);

     return str_Value;

}

 

void CDemo_wsxdllDoc::Save_wsxdll(int gm_wsxdll[c_Dim0154a][c_Dim0154b],CString sPath,CString sFileType)

{//【函数功能】盘录数据集(gm_wsxdll[][])

     //           

     int i_p,j_p;

     //gm_wsxdll[0][21]

     CString FileName=sPath+"wsxdll"+sFileType;//

     //

     ofstream File(FileName);//

     //

     for(j_p=0;j_p<=c_Dim0154b-1;j_p++)

     {//

      for(i_p=0;i_p<=c_Dim0154a-1;i_p++)

      {//

       File<<gm_wsxdll[i_p][j_p]<<"\n";

      }

     }

     //

     File.close();//

     //

     return;//

}

 

void CDemo_wsxdllDoc::Save_BooleanFormula(int gm_BooleanFormula[c_Dim0106],

CString sPath,CString sFileType)

{//【函数功能】

     CString FileName=sPath+"BooleanFormula"+sFileType;//

     int i_p;

     //

     ofstream File(FileName);//

     //

     for(i_p=0;i_p<=c_Dim0106-1;i_p++){File<<gm_BooleanFormula[i_p]<<"\n";;}

     //

     File.close();//

     //

     return;

}

     【提醒】不要忘了在文件中声明这(4)个函数

              void Save_Path(CString sPath_ck,CString sFileType_ck,CString sPath_stlModel);//      

void Save_wsxdll(int gm_wsxdll[c_Dim0154a][c_Dim0154b],CString sPath,CString sFileType);//

void Save_BooleanFormula(int gm_BooleanFormula[c_Dim0106],CString sPath,CString sFileType);//

CString f006_392i_IntToString(int Value);

 

▲编写布尔运算触发函数OnMenuitem_001()的代码

【略语】本触发函数中调用了wsxdll模块函数wd0200_BlnOp(2,3),其功能就是对几何体实施布尔运算

    void CDemo_wsxdllView::OnMenuitem_001()

{//【函数功能】由菜单(Demo)(Bln Op)可触发本函数,对选中的二个stl三维模型实施布尔运算

     // TODO: Add your command handler code here

     CDemo_wsxdllDoc* pDoc = GetDocument();

     int gm_wsxdll[c_Dim0154a][ c_Dim0154b];

     int gm_BooleanFormula[c_Dim0106];

     int Qty_BlnShell;

     CString sPath_ck;//

     CString sFileType_ck;//

     CString sPath_stlModel;//

     int i_stlModel;

     CString str_stlModelCd;

     CString sFileName,tFileName;

     DWORD   err;//档录错误的编号

    

     typedef int (* lp_wd0200)(int ,int);//

     //【略语】动态调用链接(.dll)

     HINSTANCE hDll;//句柄 www.2cto.com

     //

     lp_wd0200 wd0200_BlnOp;//函数指针

     hDll=LoadLibrary("D:\\Wessex\\Demo_wsxdll\\wsxdll.dll");//动态加载DLL模块句柄

     //【仰释】(wsxdll)的动态链接文件(wsxdll.dll)的路径:"D:\\Wessex\\Demo_wsxdll\\wsxdll.dll"

     err   =   GetLastError();//获取错误号

     //

     if(hDll)

     {//【略语】

      wd0200_BlnOp=(lp_wd0200) GetProcAddress(hDll,"wd0200_BlnOp");//得到所加载DLL模块中函数的地址

      //【仰释】函数wd0200_BlnOp()wsxdll算法库布尔运算入口函数

      err   =   GetLastError();//获取错误编号(err)

      //

      //【略语】给数组(gm_wsxdll[][])的一些元素赋值

      gm_wsxdll[0][20]=2;//模型群中的3Di模型的数目

      gm_wsxdll[0][21]=2;//模型群中的stl模型的数目

                         //【略语】一个3Di模型可以用多种格式的数据结构来定义

                         //        stl模型是以stl数据格式定义的一类3Di模型

      gm_wsxdll[0][22]=5;//约定值

      gm_wsxdll[0][23]=1;//场景仅含(1)个模型群

 

      //【略语】布尔运算中会出现大量的过程文件,下面定义存储这些过程文件的文件夹

      sPath_ck="D:\\Wessex\\WessexData\\";//放置过程文件的文件夹

      sFileType_ck=".ck";//

      

      //【略语】自然地,参与布尔运算的STL模型是由用户提供的,需将这些STL模型(文件)的路径档录于变量(sPath_stlModel)

      sPath_stlModel="D:\\stlModel Depot\\stlmodel_02\\";//放置stl模型文件的文件夹,出现在布尔算式中的诸stl模型需事先被储置在文件夹(sPath_stlModel)

 

      //【略语】参加布尔运算的stl模型(文件)放在(sPath_stlModel)指向的文件夹中

      pDoc->Save_Path(sPath_ck,sFileType_ck,sPath_stlModel);

      //【略语】盘录数组(gm_wsxdll[0][])

      pDoc->Save_wsxdll(gm_wsxdll,sPath_ck,sFileType_ck);//

      //【略语】定义布尔运算的方案,即布尔运算式(:参与布尔运算的诸STL模型被储置在文件夹(sPath_stlModel))

      //        用数组(gm_BooleanFormula[])档录布尔运算式的布算码符式

      //        :布尔运算式和布算码符式是同一个布尔运算的二种表达,

      //           前者符合阅读习惯,后者便于代码编程

      gm_BooleanFormula[0]=3;//布算码符式(10002, 3, 10001)(3)个整型数

      gm_BooleanFormula[1]=10002;//布算码符式(10002, 3, 10001)之第(1)个整型数(10002)指向stl模型2,

                                 //stl模型由文件"stlModel(2).stlb"定义

      gm_BooleanFormula[2]=3;    //布算码符式(10002, 3, 10001)之第(2)个整型数(3)指向布尔差运算符(-)

      gm_BooleanFormula[3]=10001;//布算码符式(10002, 3, 10001)之第(1)个整型数(10001)指向stl模型1,

      //【略语】上面定义了一个布尔算式:"STL模型(10002) 布尔差 STL模型(10001)",其布算码符式如下

      //        (gm_BooleanFormula[1],gm_BooleanFormula[2],gm_BooleanFormula[3])=(10002,3,10001):

      pDoc->Save_BooleanFormula(gm_BooleanFormula,sPath_ck,sFileType_ck);//盘录用户定义的布尔运算方案,即布算码符式

   //【略语】wd0200_BlnOp(2,3)wsxdll模块提供的布算入口函数,

      //       算程欲调用该函数依布算码符式(gm_BooleanFormula[1],gm_BooleanFormula[2],gm_BooleanFormula[3])实施布算

      //       :出现在布算码符式(gm_BooleanFormula[])中的诸STL模型需事先被储置在文件夹(sPath_stlModel)

      int result=wd0200_BlnOp(2,3);//result=2+3

      //【仰释】觅获了由布尔算式(gm_BooleanFormula[])定义的()个几何体

      //        :该布尔算式由(gm_BooleanFormula[0]=3)个字写成

      FreeLibrary(hDll);//释放已经加载的DLL模块

     }

     Qty_BlnShell=1;//暂置(1)

     //【略语】由经(wsxdll)模块的函数wd0200_BlnOp(...),算程觅获了由布尔算式(gm_BooleanFormula[])定义的(Qty_BlnShell)stl模型

     //        :一个三维布尔运算式实际上定义了(N0)个三维体,(N=0)对应"",(N>1)对应对个几何体

     //        算程欲储置觅获的(Qty_BlnShell)个模型于文件夹(sPath_stlModel)

     //【略语】觅获了由布尔算式(gm_BooleanFormula[])定义的(Qty_BlnShell)stl模型

     //        只是此些模型被档录在过程数据文件夹(sPath_ck),算程欲将其拷到文件夹(sPath_stlModel)

     //(3333333333333333333333333333333

     for(i_stlModel=1;i_stlModel<=Qty_BlnShell;i_stlModel++)

     {//【遍历】由布尔算式(gm_BooleanFormula[])定义的(Qty_BlnShell)stl模型

      //stlModelCd=lm_stlModel[i_stlModel];//

      str_stlModelCd=pDoc->f006_392i_IntToString(i_stlModel);//

      //【略语】把wsx文件夹(sPath_ck)中的(.stlb)文件复制到用户文件夹(sPath_stlModel)

      sFileName=sPath_ck+"BlnStlModel(#"+str_stlModelCd+")"+".stlb";//源文件

      tFileName=sPath_stlModel+"BlnStlModel(#"+str_stlModelCd+")"+".stlb";//目标文件

      //【略语】算程欲复制文件(sFileName),黏贴之为文件(tFileName)

      if(::CopyFile(sFileName,tFileName,FALSE)) {;}

      else

      {//【略语】(黏贴-复制)失败,源文件(sFileName)

       AfxMessageBox("stl模型("+sFileName+")不存在? (2016-08-05 e3010(stlb))!");

      }

      //

      //【略语】把wsx文件夹(sPath_ck)中的(.obj)文件复制到用户文件夹(sPath_stlModel)

      sFileName=sPath_ck+"BlnObjModel(#"+str_stlModelCd+")"+".obj";//源文件

      tFileName=sPath_stlModel+"BlnStlModel(#"+str_stlModelCd+")"+".obj";//目标文件

  

      //【略语】算程欲复制文件(sFileName),黏贴之为文件(tFileName)

      if(::CopyFile(sFileName,tFileName,FALSE)) {;}

      else

      {//【略语】(黏贴-复制)失败,源文件(sFileName)

       AfxMessageBox("stl模型("+sFileName+")不存在? (2016-08-05 e3010(obj))!");

      }

     }

     //)22222222222222222222222222222

     CString str_stlModelQty=pDoc->f006_392i_IntToString(Qty_BlnShell);//

     //【略语】界面提示:成功地实施了布尔运算

     AfxMessageBox("▲依布尔算式,获得了("+str_stlModelQty+")新生stl模型,被储置在文件夹("+sPath_stlModel+"))!");

     //【提醒】wsxdll库函数wd0200_BlnOp(…)(输入/输出)都是数据文件,而非图形

     //        ◆输入是和布尔算式和出现在该布尔算式中的诸stl模型的数据文件

     //        ◆输出是由布尔算式定义的(Qty_BlnShell)个三维模型,(stl)(Obj)二种格式表述

     //        用户可借由Unity3D观赏Obj模型,借由3DMax等观赏stl模型,更可用OpenGL自编显图软件观之

     return;    

}

 

▲储置参与布尔运算的stl模型文件

至此,一个调用wsxdll库函数wd0200_BlnOp(…),对几何体实施布尔运算的演示工程(Demo_wsxdell)被建成了。通过编译也不成问题。但在运行工程(Demo_wsxdell)之前还需把出现在布尔算式(gm_BooleanFormula[])中的(2)stl模型"stlModel(1)","stlModel(2)"放置在文件夹(sPath_stlModel="D:\\stlModel Depot\\stlmodel_02\\")

【略语】下图示出现在布尔算式(stl模型(10002) 布尔差 stl模型(10001))中的(2)stl模型

 

▲运行工程(Demo_wsxdell)

    选中(Demo)(Bln Op),程序开始运行,若干(毫秒||||)后会弹出提示框,显示新生布算模型(文件)的储存位置。

    

    

    正如提示框所提示的,布生新几何体(文件)被储存在文件夹(sPath_stlModel="D:\\stlModel Depot\\stlmodel_02\\"), "BlnStlModel(#1).obj""BlnStlModel(#1).stlb"分别是该布生新几何体的(obj)格式和(stl)格式数据文件。

     


【略语】下图示由布尔算式(stl模型(10002) 布尔差 stl模型(10001))定义的新生几何体

    

wsxdll库函数wd0200_BlnOp(…)(输入/输出)都是数据文件,而非图形

    ◆输入是布尔算式()和出现在该布尔算式中的诸stl模型的数据文件

    ◆输出是由布尔算式()定义的(Qty_BlnShell)个三维模型,(stl)(Obj)二种格式表述

      用户可借由Unity3D观赏Obj模型,借由3DMax等观赏stl模型,更可用OpenGL自编显图软件观之

 

 

【关键词】模型布尔运算,STL模型布尔运算,三维布尔运算,

微信号:wessex2020

邮箱:wessex2010@qq.com

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

‹‹
我的工具栏

关于我们|手机版|Archiver|开源计算机图形学社区(Open Source Computer Graphics Community) | OpenGPU Project | OpenGPU Forum (2007-2013)

GMT+8, 2017-7-22 20:37 , Processed in 0.046062 second(s), 15 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部