找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 171|回复: 0

OBJECT ARX 源码

[复制链接]

0

主题

0

回帖

26

积分

管理员

积分
26
发表于 2024-2-28 09:00:34 | 显示全部楼层 |阅读模式
  1. /加载一个实体到数据库,返回实体ID
  2. static AcDbObjectId LoadEntity(AcDbEntity* entity)
  3. {
  4. AcDbBlockTable* pBlockTable;
  5. acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead);
  6. AcDbBlockTableRecord* pBlockTableRecord;
  7. pBlockTable->getAt(ACDB采用MODEL采用SPACE,pBlockTableRecord,AcDb::kForWrite);
  8. AcDbObjectId Id;
  9. pBlockTableRecord->appendAcDbEntity(Id,entity);
  10. pBlockTable->close();
  11. pBlockTableRecord->close();
  12. entity->close();
  13. return Id;
  14. }
  15. //弹出颜色选择对话框,让用户选择颜色,默认选择的是当前层的颜色
  16. static int SelColor()
  17. {
  18. ////先获得当前层的ID
  19. AcDbObjectId layerId = acdbHostApplicationServices()->workingDatabase()->clayer();
  20. ////然后获得当前层指针
  21. AcDbLayerTableRecordPointer ptLayer(layerId,AcDb::OpenMode::kForRead);
  22. ////获得当前层的颜色
  23. AcCmColor oldColor = ptLayer->color();
  24. int nCurColor = oldColor.colorIndex();//当前层的颜色
  25. int nNewColor = oldColor.colorIndex();//用户选择的颜色
  26. if (acedSetColorDialog(nNewColor,Adesk::kFalse,nCurColor))
  27. {
  28. return nNewColor;
  29. }
  30. else
  31. {
  32. return nCurColor;
  33. }
  34. }
  35. //第一题:定义一个全局命令,功能:使用全局函数创建一个简单实体-直线,顶点由用户输入;
  36. static void TESTlineCmd()
  37. {
  38. ads采用point inputStart;
  39. ads采用point inputEnd;
  40. AcGePoint3d ptStart;
  41. AcGePoint3d ptEnd;
  42. ////用户输入要画的坐标
  43. if (acedGetPoint(NULL,采用T("\nstart point"),inputStart) != RTNORM)
  44. {
  45. return;
  46. }
  47. ptStart[X] = inputStart[X];
  48. ptStart[Y] = inputStart[Y];
  49. ptStart[Z] = inputStart[Z];
  50. if (acedGetPoint(NULL,采用T("\nend point"),inputEnd) != RTNORM)
  51. {
  52. return;
  53. }
  54. ptEnd[X] = inputEnd[X];
  55. ptEnd[Y] = inputEnd[Y];
  56. ptEnd[Z] = inputEnd[Z];
  57. AcDbLine* pLine = new AcDbLine(ptStart,ptEnd);
  58. int colorIndex = SelColor();
  59. AcCmColor color;
  60. color.setColorIndex(colorIndex);
  61. pLine->setColor(color);
  62. LoadEntity(pLine);
  63. }
  64. //第二题:定义一个LISP函数,功能:使用全局函数创建一个简单实体-圆,返回圆的实体数据链表,圆心和半径由用户输入;
  65. static int ads采用circle()
  66. {
  67. ads采用point pt;
  68. if(acedGetPoint(NULL,采用T("\n选择圆心"),pt) != RTNORM)
  69. {
  70. return 0;
  71. }
  72. ads采用real realNum;
  73. if(acedGetReal(采用T("\n输入半径"),&realNum)!= RTNORM)
  74. {
  75. return 0;
  76. }
  77. ////垂直平面法向量
  78. AcGeVector3d vec(0,0,1);
  79. ////圆心
  80. AcGePoint3d ptCenter(pt[X],pt[Y],pt[Z]);
  81. AcDbCircle* pCircle = new AcDbCircle(ptCenter,vec,realNum);
  82. LoadEntity(pCircle);
  83. ////打印出类型为字符串的接收参数
  84. resbuf* pInput = acedGetArgs();
  85. CString str;
  86. while (pInput != NULL)
  87. {
  88. if (pInput->resval.rstring != NULL)
  89. {
  90. acutPrintf(pInput->resval.rstring);
  91. acutPrintf(采用T("\n"));
  92. }
  93. pInput = pInput->rbnext;
  94. }
  95. ////构造圆形实体
  96. struct resbuf* rb ;
  97. rb = acutBuildList(
  98. RTDXF0,采用T("CIRCLE"),
  99. 62,1,//1 == RED
  100. 10,ptCenter,
  101. 40,realNum,//radius
  102. 0);
  103. acedRetList(rb);
  104. return RTNORM;
  105. }////函数在调用的时候需要加上括号 (func "param")
  106. //第三题;输入三点,以中间点为顶点,把旁边两条线做圆角,半径用户输入
  107. static void TESTcomplexentcmd()
  108. {
  109. ads采用point pt1;
  110. ads采用point pt2;
  111. ads采用point pt3;
  112. ads采用real r;
  113. if (acedGetPoint(NULL,采用T("\n输入第一点"),pt1) != RTNORM)
  114. {
  115. return;
  116. }
  117. if (acedGetPoint(NULL,采用T("\n输入第二点"),pt2) != RTNORM)
  118. {
  119. return;
  120. }
  121. if (acedGetPoint(NULL,采用T("\n输入第三点"),pt3) != RTNORM)
  122. {
  123. return;
  124. }
  125. if (acedGetReal(采用T("\n输入内切圆半径"),&r) != RTNORM)
  126. {
  127. return;
  128. }
  129. ////坐标维度转化
  130. AcGePoint3d pt3d1 = asPnt3d(pt1);
  131. AcGePoint3d pt3d2 = asPnt3d(pt2);
  132. AcGePoint3d pt3d3 = asPnt3d(pt3);
  133. ////构造两条直线计算顶点到切点的距离
  134. AcDbLine line1(pt3d2,pt3d1);
  135. AcDbLine line2(pt3d2,pt3d3);
  136. ////得到以PT2为顶点的两个向量
  137. AcGeVector3d v1(pt1[X]-pt2[X],pt1[Y]-pt2[Y],pt1[Z] - pt2[Z]);
  138. AcGeVector3d v2(pt3[X]-pt2[X],pt3[Y] - pt2[Y],pt3[Z] - pt2[Z]);
  139. AcGeVector3d v3(0,0,1);
  140. double PI = 3.1415926536;
  141. ////计算两个向量的夹角
  142. double angle = v1.angleTo(v2,v3);
  143. double angle1 = angle > PI ? 2 * PI - angle : angle;
  144. ////计算切点到顶点距离
  145. double dist = r / tan(angle1 / 2);
  146. ////切点1
  147. AcGePoint3d ptQ1;
  148. ////切点2
  149. AcGePoint3d ptQ2;
  150. ////找到切点
  151. line1.getPointAtDist(dist,ptQ1);
  152. line2.getPointAtDist(dist,ptQ2);
  153. ////求出bulge值(是圆心角1/4的正切值 - - ,之前当成正切值的四分之一了 - -!!!)
  154. double bulge;
  155. bulge = tan((PI - angle1) / 4);
  156. if(angle > 0 && angle <= PI)
  157. {
  158. bulge = - bulge;
  159. }
  160. AcDbPolyline* pl = new AcDbPolyline();
  161. AcGePoint2d pt2d1(pt3d1[X],pt3d1[Y]);
  162. AcGePoint2d pt2dq1(ptQ1[X],ptQ1[Y]);
  163. AcGePoint2d pt2dq2(ptQ2[X],ptQ2[Y]);
  164. AcGePoint2d pt2d3(pt3d3[X],pt3d3[Y]);
  165. pl->addVertexAt(0,pt2d1,0);
  166. pl->addVertexAt(1,pt2dq1,bulge);
  167. pl->addVertexAt(2,pt2dq2,0);
  168. pl->addVertexAt(3,pt2d3,0);
  169. LoadEntity(pl);
  170. CString out;
  171. out.Format(采用T("\nangle:%.2f,bulge:%.2f,\ndist:%.2f\n,pt[z]:%.2f,%.2f,%.2f"),angle,bulge,dist,pt1[Z],pt2[Z],pt3[Z]);
  172. acutPrintf(out);
  173. }
  174. //第四题:定义一个全局命令,功能:使用类库创建一个块表记录,并插入块;
  175. static void TESTaddblkcmd()
  176. {
  177. ////根据用户的输入设置块表记录的名称
  178. CString blkName;
  179. if (acedGetString(Adesk::kFalse,采用T("\n输入块名称"),blkName.GetBuffer(20)) != RTNORM)
  180. {
  181. return;
  182. }
  183. ////用完getBuffer要及时release
  184. blkName.ReleaseBuffer();
  185. AcDbBlockTable* pBlkTbl;
  186. acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl,AcDb::kForWrite);
  187. AcDbObjectId rcdId ;
  188. ////如果没有,添加新的
  189. if (!pBlkTbl->has(blkName))
  190. {
  191. ////创建新块
  192. AcDbBlockTableRecord* pBlkTblRcd;
  193. pBlkTblRcd = new AcDbBlockTableRecord();
  194. pBlkTblRcd->setName(blkName);
  195. ////将块表记录添加到块表中,设置ID
  196. pBlkTbl->add(rcdId,pBlkTblRcd);
  197. ////向块表记录中添加实体
  198. AcGePoint3d ptStart(-10,0,0),ptEnd(10,0,0);
  199. AcDbLine* pLine1 = new AcDbLine(ptStart,ptEnd);
  200. ptStart.set(0,-10,0);
  201. ptEnd.set(0,10,0);
  202. AcDbLine *pLine2 = new AcDbLine(ptStart,ptEnd);
  203. AcGeVector3d vecNormal(0,0,1);
  204. AcDbCircle *pCircle = new AcDbCircle(AcGePoint3d::kOrigin,vecNormal,6);
  205. AcDbObjectId entId;
  206. pBlkTblRcd->appendAcDbEntity(entId,pLine1);
  207. pBlkTblRcd->appendAcDbEntity(entId,pLine2);
  208. pBlkTblRcd->appendAcDbEntity(entId,pCircle);
  209. ////关闭实体块表记录
  210. pLine1->close();
  211. pLine2->close();
  212. pCircle->close();
  213. pBlkTblRcd->close();
  214. }////如果已经有了,那就根据名字读出RECORDID,插入块参照时会用到
  215. else
  216. {
  217. pBlkTbl->getAt(blkName,rcdId,false);////以读的方式获取
  218. }
  219. ////在和用户交互之前,需要关闭块表,否则容易出错
  220. pBlkTbl->close();
  221. ////插入块
  222. ////获得用户输入的块参照的插入点
  223. ads采用point pt;
  224. if(acedGetPoint(NULL,采用T("\n输入块参照的插入点"),pt) != RTNORM)
  225. {
  226. pBlkTbl->close();
  227. return;
  228. }
  229. AcGePoint3d ptInsert = asPnt3d(pt);
  230. ////创建块参照
  231. AcDbBlockReference* pBlkRef = new AcDbBlockReference(ptInsert,rcdId);
  232. ////将块参照添加到模型空间
  233. AcDbBlockTableRecord* pBlkTblRcd2;
  234. pBlkTbl->getAt(ACDB采用MODEL采用SPACE,pBlkTblRcd2,AcDb::kForWrite);
  235. pBlkTblRcd2->appendAcDbEntity(pBlkRef);
  236. ////关闭数据库对象
  237. pBlkRef->close();
  238. pBlkTblRcd2->close();
  239. pBlkTbl->close();
  240. }
  241. //第五题:定义一个命令,功能:让用户选择界面上的直线实体,然后修改所有选中实体的颜色;
  242. static void TESTchangecolorcmd()
  243. {
  244. ads采用name ssname;
  245. resbuf strFilter;
  246. ////只能选择直线对象,构造选择集过滤器,只能选直线
  247. strFilter.resval.rstring = 采用T("LINE");
  248. strFilter.rbnext = NULL;
  249. strFilter.restype = 0;
  250. ////选择多个实体,传递NULL,让用户自己来选
  251. if(acedSSGet(NULL,NULL,NULL,&strFilter,ssname) != RTNORM)
  252. {
  253. return;
  254. }
  255. long len;
  256. acedSSLength(ssname,&len);
  257. CString ss;
  258. ss.Format(采用T("已选中%d个实体"),len);
  259. acutPrintf(ss);
  260. ads采用name entname;
  261. AcDbObjectId id;
  262. AcDbEntity* ent = NULL;
  263. CString strName;
  264. ////弹出颜色选择对话框,选中一个颜色,默认是当前层的颜色
  265. int nNewColor = SelColor();
  266. for (int i=0;i<len;i++)
  267. {
  268. if (acedSSName(ssname, i, entname) == RTNORM)
  269. {
  270. ////根据名称得到ID
  271. acdbGetObjectId(id,entname);
  272. ////以写模式,根据ID索引到对象,并打开ENTITY
  273. acdbOpenObject(ent,id,AcDb::OpenMode::kForWrite);
  274. strName.Format(采用T("%d"),ent->colorIndex());
  275. acutPrintf(采用T("\n"));
  276. acutPrintf(strName);
  277. ent->setColorIndex(nNewColor);
  278. ent->close();
  279. }
  280. }
  281. acedSSFree(ssname);
  282. }
  283. //-----------------------------------------------------------------------------
  284. IMPLEMENT采用ARX采用ENTRYPOINT(CArxProject2App)
  285. ACED采用ARXCOMMAND采用ENTRY采用AUTO(CArxProject2App, TEST, lineCmd, lineCmd, ACRX采用CMD采用MODAL, NULL)
  286. //ACED采用ARXCOMMAND采用ENTRY采用AUTO(CArxProject2App, TEST, circlecmd, circlecmd, ACRX采用CMD采用MODAL, NULL)
  287. ACED采用ADSSYMBOL采用ENTRY采用AUTO(CArxProject2App, circle, false)
  288. ACED采用ARXCOMMAND采用ENTRY采用AUTO(CArxProject2App, TEST, changecolorcmd, changecolorcmd, ACRX采用CMD采用MODAL, NULL)
  289. ACED采用ARXCOMMAND采用ENTRY采用AUTO(CArxProject2App, TEST, addblkcmd, addblkcmd, ACRX采用CMD采用MODAL, NULL)
  290. ACED采用ARXCOMMAND采用ENTRY采用AUTO(CArxProject2App, TEST, complexentcmd, complexentcmd, ACRX采用CMD采用MODAL, NULL)
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2024-12-28 14:20 , Processed in 0.121983 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表