390 likes | 913 Views
第十八章 ACIS 的实例代码. 18.1 用 Scheme 语言生成 ACIS 程序 18.2 用 Windows 控制台环境编译 ACIS 程序 18.3 用 ACIS AppWizard 生成应用程序框架. 18.1 用Scheme语言生成ACIS程序. ACIS 从实用角度而言(不准确地说),是一个大型的专门用于几何造型的类库,而它的运行环境正如上一章所述,是 Scheme 和 C++ ;本章将就 ACIS 的 Scheme 程序、 C++ 的 Windows 控制台程序和 C++ 的 AppWizard 应用程序,进行实例讲解。.
E N D
第十八章 ACIS的实例代码 • 18.1 用Scheme语言生成ACIS程序 • 18.2 用Windows控制台环境编译ACIS程序 • 18.3 用ACIS AppWizard生成应用程序框架
18.1 用Scheme语言生成ACIS程序 • ACIS从实用角度而言(不准确地说),是一个大型的专门用于几何造型的类库,而它的运行环境正如上一章所述,是Scheme和C++;本章将就ACIS的Scheme程序、C++的Windows控制台程序和C++的AppWizard应用程序,进行实例讲解。
用Scheme语言生成ACIS程序 • 本节主要介绍Scheme语言的使用规则,简要讲解其基本概念如表达式、变量、函数、简单几何造型功能等,并附有可以直接运行的例程代码。
Scheme语言基础语法 • ACIS中的Scheme解释器是用C++设计的,ACIS中的几何造型功能通过对标准Scheme命令的扩展实现,这些扩展命令也是用C++设计的,它们支持ACIS中的高级造型功能,如模型着色和零件管理功能。 • 与C++相比,Scheme是一种快速程序设计语言,而且简洁易学。Scheme语言的语法规则很少,总结如下: • 通过交互地调用Scheme过程来执行程序; • Scheme过程及其参数都被包含在一对圆括号里; • 圆括号里的部分被称为Scheme表达式; • 表达式中包含过程名称和过程参数,具体格式如下: • (过程名称〈参数1,参数2,…〉) • 分号“;”引导的部分为程序注释。 • (如何运行ACIS Scheme解释器,请参看17.3.1节)
表达式 • 由于Scheme是一种解释型的程序开发语言,其表达式只能在解释器中执行。运行ACIS的Scheme AIDE解释程序后,就可以在它的“acis〉”提示符下输入表达式,在表达式的结束处按回车就可以执行该表达式。以下是几个典型的算术表达式: • acis〉输入:(* 5 6) • 回车输出:30 • acis〉(* 5 6 7) • 210 • 在Scheme的表达式中,操作符(如*)后面可以跟任意多个参数,但是其间一定要用‘空格’隔开;并且一个表达式里可以包含一个或者多个表达式,如: • acis〉(*(+ 1 2)(* 5 6)) • 90
理论上,表达式之间互相嵌套的层数是没有限制的,程序员只要匹配好括号就行了。理论上,表达式之间互相嵌套的层数是没有限制的,程序员只要匹配好括号就行了。 • 上面表达式的例子中使用了两个标准的Scheme内部过程进行乘法和加法运算,而ACIS Scheme还扩充了ACIS造型器专用的过程,用户可以按照上述标准Scheme过程方法调用这些造型过程,如下面命令可产生立方体: • acis〉输入:(solid:block(position 0 0 0)(position 10 10 10)) • 回车输出:#[entity 1 0] • 上述命令产生了一个正方体,如图17.1.1,共调用了两个ACIS Scheme过程(position和solid:block),#[entity 1 0]是该正方体的默认名称。
Scheme表达式产生的每个对象都有一个外部描述符和一个内部描述符。虽然外部描述符看上去比较简单,它在与用户交互过程中有重要作用。它会将一个过程的执行结果反馈给用户,例如我们前面举的一些例子中,如果表达式的计算结果不被用作其他表达式的参数,也就是说该表达式未被嵌套在其他表达式中,则Scheme解释器自动将表达式执行结果的外部描述符输出,对于算术运算来说其外部描述符只是一些简单的数字,如30,210,90等。Scheme表达式产生的每个对象都有一个外部描述符和一个内部描述符。虽然外部描述符看上去比较简单,它在与用户交互过程中有重要作用。它会将一个过程的执行结果反馈给用户,例如我们前面举的一些例子中,如果表达式的计算结果不被用作其他表达式的参数,也就是说该表达式未被嵌套在其他表达式中,则Scheme解释器自动将表达式执行结果的外部描述符输出,对于算术运算来说其外部描述符只是一些简单的数字,如30,210,90等。 ACIS的对象也具有外部描述符,当一个含有ACIS造型功能的过程被调用后,它所产生的ACIS对象的描述符就会被解释器输出,其一般格式如下: #[type_of_object<参数>] 下面,我们看一个关于ACIS对象的例子: ;产生一个position对象 acis〉(position 10,20,30) #[position 10,20,30] 这个position对象的外部描述符表示了一个x=10,y=20,z=30的坐标点。 从ACIS的ENTITY类派生的对象的外部描述符与position对象的外部描述符类似,稍微复杂之处就是,这些东西被组织到所谓的零件(PART)单元中。在ACIS Scheme解释器开始运行时,它会自动产生一个编号为1的默认零件。下面就是关于ACIS的ENTITY对象的Scheme例子: ;产生一个长方体 acis〉(solid:block(position 0 0 0)(position 10 10 10)) #[entity 1 0] 过程solid:block产生了一个ACIS实体对象,#[entity 1 0]是它的外部描述符,该描述符由两部分组成,即实体号(1)和零件号(0),实体号可以作为其他过程的参数。下面就是一个使用实体号的例子: ;删除一个实体 acis〉(entity:delete(entity 1)) () 注意:“()”表示空元素,Scheme语言的列表结构中会自动地在列表末尾增加它。 外部描述符
变量 • 在Scheme语言中可以用变量名称记录变量的数值,如17.1.1节中的例子所示,一个过程的返回值,如果不保存在一个变量中,没有多大用途。Scheme语言中的变量和过程都可以用一个符号表示,定义变量和过程的操作符是define,它可以命名一个表达式,语法如下: • (define〈名称〉〈表达式〉) • 下面是两个变量定义的例子: • ;定义数值变量p • acis〉(define p(* 10 10 10)) • p • acis〉p ;调用变量p • 1000 • ;定义ACIS变量p1 • acis〉(define p1(position 10 10 10)) • p1 • acis〉p1 ;调用变量p1 • #[position 10 10 10] • 上述例子中p是一个数值变量,p1是一个position对象变量。
函数 • Scheme语言中的函数定义也是通过define命令实现的,语法如下所示。在这个例子中,函数参数x是一个局部变量,即只有在定义它的函数中有意义。 • ;定义函数“square” • acis〉(defiine (square x)(* x x)) • square • acis〉(square 6) • 36 • 用define命令产生的函数以及变量是全局性的,对于一些简单的任务(用30到50行程序即可以完成的任务),完全可以使用这个命令进行处理。而从程序的可读性和避免变量名的冲突来说,还需要其他一些更复杂的处理。
Scheme中的读写操作 • 在ACIS Scheme解释器里进行SAT文件的读写操作要比C++中的操作简单得多,下面就是一个完整的SAT文件的读写过程: • ;产生一个BODY对象 • (solid: block (position 0 0 0)(position 10 10 10)) • ;将它保存到save.sat文件中 • (part: save “E:/save.sat”) • ;将BODY删除 • (part: clear) • ;从文件save.sat中读入刚保存的实体 • (part: load “E:/save.sat”)
用Scheme产生基本几何体 • 用ACIS Scheme可以很快捷地产生基本几何体,如,在ACIS Scheme解释器里输入如下命令就可以产生一个球体: • acis>(view: gl) ;生成一个视图窗口 • acis>(solid: sphere(position(0 0 0 ) 20) • #[entity 1 1] ;零件0中的第一个实体 • 下面是几个产生基本几何体的函数: • solid: block (position 左下角顶点坐标) (position 右上角顶点坐标) ;立方体 • solid: sphere (position 圆心坐标) 半径 ;球体 • solid:cylinder (position下圆心坐标) (position上圆心坐标) 20 ;圆柱体 • solid: cone (position 下圆心坐标) (position 顶点坐标) 25 0 ;圆锥体
ACIS Scheme中的集合运算 • ACIS Scheme中的集合运算与C++中的集合运算基本一样,惟一不同的是它可以将多个实体一起进行运算,这要比C++中的一次只能计算两个实体方便。下面是一个例子,为了与C++进行比较,这里仍然对两个圆柱进行求并运算。 • ;两个正交的圆柱 • (define c1 (solid:cylinder (position 0 0 -50) (position 0 0 50) 20)) • (define c2 (solid:cylinder (position 0 0 -50) (position 0 0 50) 20)) • ;t1是将实体沿与x轴垂直的方向旋转90度的函数 • (define t1 (transform: rotation (position 0 0 0) (gvector 1 0 0) 90)) • (entity: transform c1 t1) ;把c1旋转90度 • (define cross (solid: unite c1 c2)) ;c1和c2两个圆柱将被删除
ACIS Scheme中的布尔运算 • ACIS Scheme中提供了强大的布尔运算功能,不仅有效实体之间可以进行布尔运算,其他的一些几何实体之间也可以进行布尔运算。下面是一个平面与双圆锥体之间的布尔运算: • ;生成两个顶点重合的圆锥,即顶对顶,并将它们进行求并运算,然后将其结果与一个平面进行差运算 • (define c1 (solid: cone (position 40 0 0) (position 0 0 0) 25 0)) ;产生圆锥c1 • (define c2 (solid: cone (position -40 0 0) (position 0 0 0) 25 0)) ;产生圆锥c2 • (define c3 (solid: unite c1 c2)) ;求并 • (define plane(face:plane (position -100 100 5) 200 200 (gvector 0 0 -1))) ;产生平面plane • (define cut(sheet: face plane)) ;生成平面片 • (bool: subtract c3 cut) ;求差 • 在上述例子中为了在一个三维实体和一个二维平面片之间进行布尔差运算,没有使用适用于三维实体的solid:subtract函数,而是使用了更通用的bool:subtract函数。
Scheme语言总结 • 一个完整的Scheme程序由表达式和定义组成。这里,我们总结一下Scheme语言中的定义格式。 • 定义可以出现在程序的顶部,这时的定义被称为声明。定义也可以作为一个主程序的开始,如一个函数或者过程的开始。定义的格式有如下4种: • (1)(define〈变量〉〈表达式〉),这是一种基本定义格式,一般变量的定义就是这种格式; • (2)(define(〈变量〉〈形式参数〉〈程序体〉)),如定义局部函数的lambda语句就是这种定义格式,下面计算阶乘的数值函数的定义就采用了这种定义方式: • (define factorial(lambda(num) • (if(= num 0)1(* num(factorial(- num 1)))))) • 注意:(define(〈变量〉〈形式参数〉)〈程序体〉),这种格式也是一种常用的函数定义的格式方法。以这种格式定义上面例子里的factorial函数,程序如下: • (define (factorial num) • (if(= num 0)1(* num(factorial(- num 1)))))) • (3)(begin(〈定义1〉〈定义2〉…),这也是一种基本的定义格式。它可以同时定义多个变量。 • 本节主要介绍了Scheme语言的一些基本编程常识和几个基本几何造型的生成,在利用该语言进行系统开发时需要注意如下几个Scheme编程的特点: • (1)变量与表达式的执行顺序,如果要让程序严格按照编写顺序执行,必须使用let*或者begin函数; • (2)圆括号的数量既不能多也不能少。如(newline)是正确的,而((newline))则是一个错误表达式; • (3)由于Scheme解释器对程序语句进行的检查不能返回出错程序所在的行号,所以一个函数或者过程不能太长,否则就会给程序的调试带来麻烦; • (4)在let表达式中产生的BODY对象,在函数或者过程结束后不能被自动删除。
第十八章 ACIS的实例代码 • 18.1 用Scheme语言生成ACIS程序 • 18.2 用Windows控制台环境编译ACIS程序 • 18.3 用ACIS AppWizard生成应用程序框架
18.2 用Windows控制台环境编译ACIS程序 • 本节主要通过几个实例程序讲解在C++中如何用Windows控制台环境编译和运行ACIS程序,同时给出几个在此环境下的简单几何造型的例程。
ACIS C++程序基本结构 • 在上一节中介绍了ACIS平台上用Scheme语言进行系统开发的一些常识,而利用C++在ACIS平台上进行系统开发时,除了遵循C++语言的规定之外,还要注意ACIS的一些特点,下面是一个典型的ACIS C++程序结构: • #include <系统头文件> //含有系统函数的声明 • #include “ACIS头文件” //含有ACIS API函数和类的声明 • void main() • { • api_start_modeller(0); //生成内部数据结构 • api_initialisze_”组件”; • //API函数和直接函数调用 • api_terminate_”组件”; • api_stop_modeller(); //删除内部数据结构 • } • 关于如何用Visual C++进行ACIS程序的编译和连接,在第十七章的第三节中已有详细讲解,这里不再赘述。
ACIS一共提供了生成7种基本形状的方法,包括4种旋转曲面体(球体、圆锥体、圆环以及圆柱)和3种多面体(立方体、棱柱以及棱锥)。ACIS一共提供了生成7种基本形状的方法,包括4种旋转曲面体(球体、圆锥体、圆环以及圆柱)和3种多面体(立方体、棱柱以及棱锥)。 下面是用API函数生成一个立方体的C++程序,该程序首先生成一个立方体,而后用ACIS中的调试功能将这个立方体的数据写入磁盘文件中。 #include <stdio.h> #include “construct/kernapi/api/cstrapi.hxx” //声明了构造API函数 #include “kernel/kernapi/api/api.hxx” //声明了start和stopAPI函数 #include “kernel/kerndata/top/body.hxx” //声明了BODY类 #include “kernel/kerndata/data/debug.hxx” //声明了一些调试函数 void main() { api_start_modeller(0); //生成内部数据结构 api_initialisze_constructors(); BODY *block; //定义一个BODY实体 api_make_cuboid(100,50,200,block); //造出一个立方体 FILE *output=fopen(“cube.dbg”,”w”); //生成cube.dbg同时打开一个文件 debug_size(block.output); //用debug_size把block写入打开的文件 fclose(output); //关闭文件 //API函数和直接函数调用 api_terminate_constructors(); api_stop_modeller(); //删除内部数据结构 } 用API函数生成基本几何体
启动造型器,它将产生一些基本的ACIS数据结构,在调用其他任何ACIS功能之前必须进行这个处理;启动造型器,它将产生一些基本的ACIS数据结构,在调用其他任何ACIS功能之前必须进行这个处理; 初始化应用到的组件,由于ACIS组件之间存在一定的依赖关系,如果程序中使用两个组件,而其中一个组件是建立在另一个组件之上的,那么只需要初始化这个组件,ACIS会自动将另一个组件初始化; 声明一个指针,该指针被指向将生成的BODY对象; 调用ACIS的API函数构造几何体; 打开一个文件; 调用调试功能中的函数debug_size将block的数据结构以及其中每一部分所占的内存空间写入(5)中打开的文件中; 关闭文件; 中断组件,释放组件所占用的资源; 停止造型器。 运行该程序后将生成cube.dbg文件,用一个文本编辑器打开此文件,其内容如下: 1 body record, 32 bytes 1 lump record, 32 bytes 1 shell record, 40 bytes 6 face records, 264 bytes 6 loop records, 192 bytes 24 coedge records, 1056 bytes 12 edge records, 864 bytes 8 vertex records, 192 bytes 12 curve records, 1344 bytes 8 point records, 384 bytes Total storage 5360 bytes 可见函数api_make_cuboid至少产生了85个对象,每个对象都需要一定的内存和一个指针来表示它们。 程序的执行过程分析
模型文件的读写 • 因为一个单一的几何造型系统不可能提供所有用户需要的功能,这时会出现下述情况,用户在一个造型系统中生成零件的模型,而在另一个系统(如有限元分析系统)进行模型分析,当这两个系统之间交换模型数据时,就需要一个可以被两个系统都接受的文件格式;而目前,一般以ACIS文件格式为标准;ACIS的模型文件一般被称为SAT文件,它包括文本文件(.sat)和二进制文件(.sab),ACIS的API函数api_save_entity_list可以生成SAT文件。
//该程序生成一个棱柱并将其保存到一个文件里//该程序生成一个棱柱并将其保存到一个文件里 #include <stdio.h> //含有函数printf的声明 #include “construct/kernapi/api/cstrapi.hxx” //声明了构造API函数 #include “kernel/kernapi/api/api.hxx” //声明了start和stopAPI函数 #include “kernel/kerndata/top/alltop.hxx” //声明了BODY类 #include “kernel/kerndata/lists/lists.hxx” //声明了一些调试函数 #include “kernel/kerndata/savres/fileinfo.hxx” //声明了fileinfo类 void save_ent(char*,ENTITY*); //声明子函数 void main() { api_start_modeller(0); //生成内部数据结构 api_initialisze_constructors(); BODY *pris; //定义一个BODY实体 api_make_prism(100,150,200,7,pris); //造出一个7棱柱 save_ent(“E:/save.sat”,pris); //调用save_ent函数把pris写入磁盘文件 api_terminate_constructors(); api_stop_modeller(); //删除内部数据结构 } void save_ent(char* filename,ENTITY* ent) { FileInfo info; Info.set_product_id(“shanshi-sdnu”); Info.set_unite(1.0); //设置尺寸单位为毫米 api_set_file_info(File|FileUnits,info); FILE *fp=fopen(filename,”w”); if(fp!=NULL) { ENTITY_LIST* savelist=new ENTITY_LIST; savelist->add(ent); api_save_entity_list(fp,TRUE,*savelist); //TRUE:sat, FALSE:sab delete savelist; } else printf(“不能打开文件\n”); fclose(fp); } 写SAT文件
上述程序中有5个关键步骤: • 产生一个实体,此处为一个BODY对象; • 将实体加入实体列表ENTITY_LIST中,可以加入多个实体对象; • 产生FileInfo对象,该对象定义了文件的头部信息; • 调用api_set_file_info设置文件头部信息,在生成模型文件时这些信息会被自动加入到文件的头部; • 调用api_save_entity_list将实体的ASCII信息写入文件。 • 注意:函数set_units是设置尺寸单位的函数,不同的参数对应不同的单位,如下所示: • -1.0=未定义 1.0=mm 10.0=cm 1000.0=m 1000000.0=km 25.4=英尺 304.8=英寸 914.4=码 1609344.0=英里
读SAT文件 • 将磁盘上的SAT文件读入到内存中的操作是由api_restore_entity_list函数完成的。该函数的使用与写SAT文件的api_save_entity_list函数完全一致: • //读SAT文件 • ENTITY_LIST new_bits; • FILE *save_file=fopen(“save_file”,”r”); • api_restore_entity_list(save_file,TRUE,new_bits); • BODY bod=(BODY*)new_bits[0]; //列表中的第一个实体 • 对于一个ACIS开发的入门者来说,经常犯的错误是忽略从文件恢复的模型中通常会含有变换矩阵这一ACIS常识。为了避免对BODY对象进行复杂的矩阵变换,可以使用api_change_body_trans(BODY*,NULL)函数根据BODY对象的变换矩阵来更新对象中的几何体同时将BODY对象所包含的TRANSFORM对象设置为0矩阵。
ACIS C++程序小结 • C++环境是ACIS程序的主要编译和运行的平台,而ACIS的AMFC类库提供了丰富的几何造型函数库,同时ACIS自身具有蒙面、富贵、网格面、扫掠一句昏话等多种实体造型和变形造型技术,由于本书的目的只是为广大C++爱好者指出一条通向ACIS殿堂之门的大路,就不再介绍这些技术,有兴趣的读者,可以仔细查阅ACIS HELP帮助文件,相信会受益匪浅的。下面给出ACIS的7种基本几何体的函数。
;立方体 api_make_cuboid(length(x),width(y),height(z),BODY) api_solid_block(position(左上角顶点坐标), position(右下角顶点坐标),BODY) ;球体 api_make_sphere(半径,BODY) api_solid_sphere(position(圆心坐标),半径,) ;圆环体 api_make_torus(外环半径,环宽,BODY) api_solid_torus(position(环心坐标), 外环半径,环宽,BODY) ;圆锥体 api_make_frustum(height(z), length(x),width(y),顶部半径,BODY) api_solid_cylinder_cone(position(顶部圆心坐标), position(底部圆心坐标), m*M_PI(底部长轴),n*M_PI(底部短轴), 0(顶部半径), NULL,BODY) ;圆柱体 api_make_frustum(height(z), length(x),width(y),顶部半径,BODY) api_solid_cylinder_cone(position(顶部圆心坐标), position(底部圆心坐标), m*M_PI(底部长轴),n*M_PI(底部短轴), 0(顶部半径), NULL,BODY) ;棱柱 api_make_prism(height(z), length(x),width(y),棱数,BODY) ;棱锥 api_make_pyramid(height(z),length(x),width(y),顶部半径,棱数,BODY) 基本几何造型函数:
从上述函数形式可以看到,ACIS中产生基本几何体的API函数有两种,它们的前缀分别是“make”(如api_make_cuboid)和“solid”(如api_solid_block),这两种函数的不同点在于前者产生的几何体位于原点,而后者产生的几何体可以在任何位置。函数api_solid_cylinder_cone是一个典型的“solid”型函数,它将两个位置点(position对象)作为输入参数,几何体的具体尺寸由这两个参数得出,而“make”型函数api_make_frustum需要一个明确的尺寸数值作为输入参数。ACIS之所以设计这两种函数,主要是为了将有数不胜任的位置作为几何造型函数的参数而直接产生几何体。这种功能可以提高几何造型系统的交互性能,这一点在进行系统开发时会体会到的。从上述函数形式可以看到,ACIS中产生基本几何体的API函数有两种,它们的前缀分别是“make”(如api_make_cuboid)和“solid”(如api_solid_block),这两种函数的不同点在于前者产生的几何体位于原点,而后者产生的几何体可以在任何位置。函数api_solid_cylinder_cone是一个典型的“solid”型函数,它将两个位置点(position对象)作为输入参数,几何体的具体尺寸由这两个参数得出,而“make”型函数api_make_frustum需要一个明确的尺寸数值作为输入参数。ACIS之所以设计这两种函数,主要是为了将有数不胜任的位置作为几何造型函数的参数而直接产生几何体。这种功能可以提高几何造型系统的交互性能,这一点在进行系统开发时会体会到的。
第十八章 ACIS的实例代码 • 18.1 用Scheme语言生成ACIS程序 • 18.2 用Windows控制台环境编译ACIS程序 • 18.3 用ACIS AppWizard生成应用程序框架
18.3 用ACIS AppWizard生成应用程序框架 • ACIS AppWizard可以产生一个应用程序框架,这在上一章第三节有详细的讲解,本节主要是通过几个简单的实例程序,引领读者迅速掌握用ACIS AppWizard编写简单应用程序的方法。
用ACIS AppWizard生成第一个可视化几何造型 • 按照第17.3.3节的讲解,一步一步地操作,就可以得到一个可执行文件my.exe,用这个文件我们就可以打开任何SAT文件,而本节的内容是在这个文件中添加一些函数,从而构造出一些简单的可视化的几何体。 • 首先,在myView.h文件顶部添加如下头文件:
#include "acismfc/acisview.hxx" #include "baseutil/vector/acistol.hxx" #include "baseutil/option/option.hxx" #include "baseutil/vector/vector.hxx" #include "baseutil/vector/unitvec.hxx" #include "baseutil/vector/transf.hxx" #include "blend/kernapi/api/blendapi.hxx" #include "boolean/kernapi/api/boolapi.hxx" #include "constrct/kernapi/api/cstrapi.hxx" #include "gihusk/api/gi_api.hxx" #include "gihusk/cam_ent.hxx" #include "gihusk/dl_ctx.hxx" #include "gihusk/dsp_utl.hxx" #include "gihusk/view_mgr.hxx" #include "part/pmhusk/api/part_api.hxx" #include "part/pmhusk/actpart.hxx" #include "part/pmhusk/hashpart.hxx" #include "part/pmhusk/part.hxx" #include "part/pmhusk/roll_utl.hxx" #include "kernel/acis.hxx" #include "kernel/geomhusk/acistype.hxx" #include "kernel/geomhusk/entwray.hxx" #include "kernel/geomhusk/getowner.hxx" #include "kernel/geomhusk/efilter.hxx" #include "kernel/geomhusk/wcs_utl.hxx" #include "kernel/kernapi/api/api.hxx" #include "kernel/kernapi/api/api.err" #include "intersct/kernapi/api/intrapi.hxx" #include "constrct/kernapi/api/cstrapi.hxx" #include "cover/kernapi/api/coverapi.hxx" #include "skin/kernapi/api/skinapi.hxx" #include "operator/kernapi/api/operapi.hxx" #include "offset/kernapi/api/ofstapi.hxx" #include "kernel/kernapi/api/kernapi.hxx" #include "kernel/kerndata/data/entity.hxx" #include "kernel/kerndata/lists/lists.hxx" #include "kernel/kernutil/law/law.hxx" #include "kernel/kernapi/api/api.err" #include "kernel/kerndata/top/face.hxx" #include "kernel/kerndata/geom/transfrm.hxx" #include "kernel/kerndata/top/alltop.hxx" #include "kernel/kerndata/top/edge.hxx" #include "kernel/kerndata/top/body.hxx" #include "kernel/kerndata/top/wire.hxx" #include "kernel/spline/api/spl_api.hxx" #include "kernel/kerndata/geometry/getbox.hxx"
#include "kernel/kerndata/geom/curve.hxx" • #include "kernel/kerngeom/curve/curdef.hxx" • #include "kernel/kerndata/geom/plane.hxx" • #include "kernel/kerndata/geom/point.hxx" • #include "kernel/kerndata/geom/straight.hxx" • #include "faceter/api/af_api.hxx" • #include "faceter/meshmgr/ppmeshmg.hxx" • #include "faceter/attribs/refine.hxx" • #include "faceter/attribs/af_enum.hxx" • #include "sweep/sg_husk/sweep/swp_opts.hxx" • #include "sweep/kernapi/api/sweepapi.hxx" • #include "acismfc/tools/sldtools.hxx" • #include "acismfc/tools/crvtools.hxx" • #include "euler/kernapi/api/eulerapi.hxx" • #include "rnd_husk/api/rnd_api.hxx" • #include "acismfc/tools/geom_if.hxx"
1.启动Visual C++ 6.0。 2.打开File菜单,选择打开工作区间菜单项,出现打开工作区间对话框。 3.在该对话框中选择My文件夹下的my.dsw,打开它。 4.在my –Microsoft Visual C++中,选择左下方的第二项ResourceView选项卡,双击my resource—Menu下的IDR_MAINFRAME。, 5.在右边编辑框的菜单栏中添加Test菜单项,并创建其下拉子菜单项cylinder,将它的标识符(ID)设置为ID_TEST_CYLINDER。 6.保存并关闭所有窗口。 7.打开VC++主菜单中的View菜单,选择ClassWizard命令,出现MFC ClassWizard对话框。 8.选择Message Maps选项卡。 9.从Class Name下拉列表框中选择CmyView(因为工程名称为“My”)。 10.在Object Ids列表框中选择ID_TEST_CYLINDER。 11.单击COMMAND,再单击Add Founction按钮,然后点击弹出对话框的OK按钮,最后点击Edit Code按钮,系统就自动转到Void Cmy::OnTestCylinder函数的编辑界面。 12.加入如下代码: // TODO: Add your command handler code here BODY *cyli; //圆柱体的BODY对象 api_make_frustum(20,5,5,5,cyli);//height,x,y,顶部半径,BODY Save(cyli); //调用保存子函数 Invalidate(); //显示新画的图形 此时如果按Ctrl+F5,程序会显示Save()函数未曾定义的错误,下面我们就添加该保存子函数: 选择ClassView选项,打开my classes—CMyView文件夹,右键单击CMyView,选择Add member Founction,函数类型为void,函数描述是Save(void *item)。 系统自动转入此函数编辑界面,加入如下代码: if(item==NULL) return; PART* pPart = GetDocument()->GetAcisDocument()->Part(); pPart->add((ENTITY*)item); 13.这样最终完成了该程序的全部编写,可以点击“!”号,执行了,其结果是一个长20mm(默认单位),半径为5mm,以坐标原点为圆心的绿色(默认色)圆柱体。 注意:运行后出现文档界面,点击Test下拉菜单的Cylinder,开始出现的图形只是一个绿色的圆面,这是因为程序默认的是实体的俯视图(Top);只要点击View下拉菜单的Orbit就可以旋转实体,点击Pan就可以拖拉等等(读者可以试用其他的菜单选项,看有什么功能)。 编程详细步骤
对可视化几何造型进行简单操作 • 上一节我们造出了一个简单的几何造型,但是它的颜色和位置都是默认或固定的,那么我们如何根据自己的意愿来操作它呢;这一节我们就学习,怎样给几何体着色,移位和旋转。 • 着色 • 选择ClassView选项,打开my classes—CMyView文件夹,右键单击CMyView,选择Add member Founction,函数类型为void,函数描述是SetColor(void *body, double r, double g, double b)。 • 系统自动转入此函数编辑界面,加入如下代码: • if(body==NULL)return; • api_gi_set_entity_rgb((ENTITY*&)body,rgb_color(r,g,b)); • 其中,api_gi_set_entity_rgb是着色函数,(ENTITY*&)body指定实体,body,rgb_color(r,g,b)进行着色。 • 在Void Cmy::OnTestCylinder函数中Save()调用上面,添加如下: • SetColor(cylinder,0,0,0); • 运行后,圆柱体将变黑色;如果用(1,1,1),则会成为与背景色相同的白色;用(0.9,0.9,0.9)就是银灰色等等,读者不妨自行调试,这里不再赘述。
移位 • 选择ClassView选项,打开my classes—CMyView文件夹,右键单击CMyView,选择Add member Founction,函数类型为ENTITY *,函数描述是MoveEntity(ENTITY *&pre, vector trass)。 • 系统自动转入此函数编辑界面,加入如下代码: • ENTITY* new_body=NULL; • api_copy_entity((ENTITY *&)pre,(ENTITY *&)new_body); • transf movee=translate_transf(trass); • api_transform_entity((ENTITY *&)new_body,movee); • return new_body; • 其中,api_copy_entity是复制函数,(ENTITY*&)pre原实体,(ENTITY *&)new_body新实体;transf movee=translate_transf(trass)是定义移方向和大小的函数;api_ transform _entity是移位函数,把(ENTITY *&)new_body按movee规则平移。 • 在Void Cmy::OnTestCylinder函数中Save()调用上面,添加如下: • cyli =(BODY *)MoveEntity((ENTITY *&) cyli, vector(-26,0,0)); • //vector(-26,0,0)表示沿x轴向负方向平移26个单位 • 运行后,原圆柱体就会被平移至底面圆心在(-26,0,0)位置。
旋转 • 选择ClassView选项,打开my classes—CMyView文件夹,右键单击CMyView,选择Add member Founction,函数类型为ENTITY *,函数描述是RotateEntity(ENTITY *&pre, vector acis, double arc)。 • 系统自动转入此函数编辑界面,加入如下代码: • ENTITY* new_body=NULL; • api_copy_entity((ENTITY *&)pre,(ENTITY *&)new_body); • transf roti=rotate_transf(arc,acis); • api_transform_entity((ENTITY *&)new_body,roti); • return new_body; • 其中,api_copy_entity是复制函数,(ENTITY*&)pre原实体,(ENTITY *&)new_body新实体;transf roti=rotate_transf(arc,acis)是定义旋转方向和度数的函数;api_ transform _entity是旋转函数,把(ENTITY *&)new_body按roti规则旋转。 • 在Void Cmy::OnTestCylinder函数中Save()调用上面,添加如下: • cyli =(BODY *)RotateEntity((ENTITY *&) cyli,vector(0,1,0),M_PI/2); • //vector(0,1,0)表示沿与y轴垂直的平面,1指按顺时针方向,M_PI/2旋转90度 • 运行后,原圆柱体就会以原点为中心被顺时针旋转90度。
对可视化几何造型进行布尔运算操作 • 在这千奇百怪的大千世界里,充满了各式各样的几何体,单靠ACIS提供的这7种基本几何造型是远远不能满足需要的;于是,ACIS也提供了将简单实体经过剪切和连接形成小实体的方法,这种方法用数学概念描述为集合运算,通常称为布尔运算。下面将简要介绍三种基本的布尔运算:求并、求交及求差。 • 求并 • 在Void Cmy::OnTestCylinder函数的编辑界面中,再Save()前加入如下代码: • BODY *cyli1; //定义另一个圆柱体的BODY对象 • api_make_frustum(100,5,5,5,cyli1); //height,x,y,顶部半径,BODY • api_unite(cyli,cyli1); //求两圆柱的并集,结果保存在cyli1中 • Save(cyli1); //调用保存子函数 • 求交 • 将上述代码中的api_unite(cyli,cyli1); 换成api_intersect(cyli,cyli1); 即可。 • 求差 • 将上述代码中的api_unite(cyli,cyli1); 换成api_subtract(cyli,cyli1); 即可
总结 • 通过本小节的学习,大家不难发现,其实C++控制台程序和AppWziard应用程序是相通的,基本几何造型函数、布尔运算函数以及其他的API函数在这两种环境下是通用的(这也没什么奇怪的,都是C++平台嘛),不过AppWziard应用程序能可视化,更友好些。 • ACIS的几何造型技术丰富多样,提供的方法、函数也纷繁复杂,本书因为篇幅和笔者水平所限,仅仅为读者指出其路,打开其门而已;有兴趣的读者,可以沿着这条路继续深入其境,相信定能大开眼界,满载而归。
总结 • 18.1 用Scheme语言生成ACIS程序 • 18.2 用Windows控制台环境编译ACIS程序 • 18.3 用ACIS AppWizard生成应用程序框架