找回密码
 立即注册

QQ登录

只需一步,快速开始

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

object Arx 例 绘制禁止开口带

[复制链接]

1

主题

0

回帖

37

积分

管理员

积分
37
发表于 2024-5-2 22:42:49 | 显示全部楼层 |阅读模式
  1. static AcDbObjectId LoadEntity(AcDbEntity* entity)
  2. {
  3. AcDbBlockTable* pBlockTable;
  4. acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead);
  5. AcDbBlockTableRecord* pBlockTableRecord;
  6. pBlockTable->getAt(ACDB采用MODEL采用SPACE,pBlockTableRecord,AcDb::kForWrite);
  7. AcDbObjectId Id;
  8. pBlockTableRecord->appendAcDbEntity(Id,entity);
  9. pBlockTable->close();
  10. pBlockTableRecord->close();
  11. entity->close();
  12. return Id;
  13. }
  14. static void SetLineWeight(double& weight,bool& isCancel)
  15. {
  16. CString str;
  17. str.Format(采用T("\n禁止开口带线宽: <%.2f>"),weight);
  18. acedInitGet(RSG采用NONEG+RSG采用NOZERO,NULL);
  19. int ret = acedGetReal(str,&weight);
  20. if(ret == RTCAN)
  21. {
  22. isCancel = true;
  23. }
  24. else
  25. {
  26. isCancel = false;
  27. }
  28. }
  29. static void TESTcornercmd()
  30. {
  31. //设置线宽-----------------------------------
  32. bool isCan = false;
  33. ads采用real lineWeight = DEFAULT采用WEIGHT;
  34. SetLineWeight(lineWeight,isCan);
  35. if(isCan)
  36. {
  37. return;
  38. }
  39. //选择一点-----------------------------------
  40. ads采用point ptCorner;
  41. while(true)
  42. {
  43. acedInitGet(RSG采用NONULL,采用T("S"));
  44. int retPt = acedGetPoint(NULL,采用T("\n点选地块转角[设置线宽(S)]:"),ptCorner);
  45. if(retPt == RTNORM)
  46. {
  47. break;
  48. }
  49. else if(retPt == RTKWORD)
  50. {
  51. CString strInput;
  52. acedGetInput(strInput.GetBuffer(10));
  53. strInput.ReleaseBuffer();
  54. if(strInput.CompareNoCase(采用T("S")) == 0)
  55. {
  56. SetLineWeight(lineWeight,isCan);
  57. if(isCan)
  58. {
  59. return;
  60. }
  61. }
  62. }
  63. else
  64. {
  65. return;
  66. }
  67. }
  68. AcGePoint3d ptCorner3d = asPnt3d(ptCorner);
  69. //设置过滤器--------------------------------------
  70. resbuf* strFilter = NULL;
  71. strFilter = acutBuildList(-4,采用T("<and"),
  72. -4,采用T("<or"),
  73. 8,采用T("C1"),//C1层
  74. 8,采用T("C2"),//C2层
  75. 8,采用T("C3"),//C3层
  76. 8,采用T("R2"),//R2层
  77. -4,采用T("or>"),
  78. RTDXF0,采用T("LWPOLYLINE"),///多段线
  79. -4,采用T("and>"),
  80. RTNONE);
  81. ads采用name ssName;
  82. if(acedSSGet(采用T("X"),NULL,NULL,strFilter,ssName) != RTNORM)
  83. {
  84. acutPrintf(采用T("\n未找到符合条件的图形"));
  85. acutRelRb(strFilter);
  86. return;
  87. }
  88. long len = 0;
  89. acedSSLength(ssName,&len);
  90. if(len <=0)
  91. {
  92. acutPrintf(采用T("\n图形数量是0"));
  93. acedSSFree(ssName);
  94. acutRelRb(strFilter);
  95. return;
  96. }
  97. //遍历选择集,找到距离点击位置最近的线段,计算出相邻线段的单位向量----------------------------------
  98. ads采用name en;
  99. AcDbObjectId eId;
  100. AcDbPolyline* plMin = NULL;
  101. int plIndex = 0;
  102. AcDbPolyline::SegType segType;
  103. AcGePoint3d ptClosest;
  104. AcGePoint3d ptMinClose;
  105. double minDist = 0.0;
  106. for(int i = 0;i < len;i++)
  107. {
  108. int rName = acedSSName(ssName,i,en);
  109. if(rName != RTNORM)
  110. {
  111. acutPrintf(采用T("\n获取名称失败"));
  112. continue;
  113. }
  114. Acad::ErrorStatus es = acdbGetObjectId(eId,en);
  115. if(es!=Acad::eOk)
  116. {
  117. acutPrintf(采用T("\n获取ID失败"));
  118. continue;
  119. }
  120. AcDbEntity* pEnt = NULL;
  121. es = acdbOpenObject(pEnt,eId,AcDb::OpenMode::kForRead);
  122. if(es != Acad::eOk)
  123. {
  124. acutPrintf(采用T("\n打开实体失败"));
  125. continue;
  126. }
  127. if(!pEnt->isKindOf(AcDbPolyline::desc()))
  128. {
  129. acutPrintf(采用T("\n第%d个实体不是多段线"),i);
  130. pEnt->close();
  131. continue;
  132. }
  133. AcDbPolyline* pPoly = NULL;
  134. pPoly = (AcDbPolyline*)pEnt;
  135. es = pPoly->getClosestPointTo(ptCorner3d,ptClosest);
  136. if(es != Acad::eOk)
  137. {
  138. acutPrintf(采用T("\n获取最小距离点出错"));
  139. pEnt->close();
  140. continue;
  141. }
  142. double minParam = 0.0;
  143. es = pPoly->getParamAtPoint(ptClosest,minParam);
  144. if(es != Acad::eOk)
  145. {
  146. pEnt->close();
  147. continue;
  148. }
  149. double dist = ptCorner3d.distanceTo(ptClosest);
  150. if(i == 0)
  151. {
  152. minDist = dist;
  153. }
  154. else if(dist >= minDist && i > 0)
  155. {
  156. pEnt->close();
  157. continue;
  158. }
  159. minDist = dist;
  160. AcDbPolyline::SegType st = pPoly->segType(minParam);
  161. if(st == AcDbPolyline::SegType::kArc)
  162. {
  163. AcGeCircArc3d arc3d;
  164. pPoly->getArcSegAt(minParam,arc3d);
  165. segType = st;
  166. plMin = AcDbPolyline::cast(pPoly->clone());
  167. plIndex = minParam;
  168. ptMinClose = ptClosest;
  169. }
  170. else if(st == AcDbPolyline::SegType::kLine)
  171. {
  172. AcGeLineSeg3d line3d;
  173. pPoly->getLineSegAt(minParam,line3d);
  174. segType = st;
  175. plMin = AcDbPolyline::cast(pPoly->clone());
  176. plIndex = minParam;
  177. ptMinClose = ptClosest;
  178. }
  179. pEnt->close();
  180. }
  181. //释放资源-------------------------------------------
  182. //pEnt->close();
  183. acutRelRb(strFilter);
  184. acedSSFree(ssName);
  185. //判断最小距离是否超出了系统允许的最大值
  186. if(minDist >MINDISTANCE)
  187. {
  188. acutPrintf(采用T("\n最小距离至少为%.2f"),MINDISTANCE);
  189. delete plMin;
  190. return;
  191. }
  192. //绘制转角线段-------------------------------------------------
  193. AcDbPolyline * pLine = new AcDbPolyline();
  194. 线段
  195. if(segType == AcDbPolyline::SegType::kLine)
  196. {
  197. AcGeLineSeg2d line2d;
  198. plMin->getLineSegAt(plIndex,line2d);
  199. pLine->addVertexAt(0,line2d.startPoint());
  200. pLine->addVertexAt(1,line2d.endPoint());
  201. }
  202. else if(segType == AcDbPolyline::SegType::kArc)
  203. {
  204. AcGeCircArc2d arc2d;
  205. plMin->getArcSegAt(plIndex,arc2d);
  206. double bulge = 0.0;
  207. plMin->getBulgeAt(plIndex,bulge);
  208. pLine->addVertexAt(0,arc2d.startPoint(),bulge);
  209. pLine->addVertexAt(1,arc2d.endPoint());
  210. }
  211. Acad::ErrorStatus es = pLine->setLayer(strLayer);
  212. if(Acad::eOk != es)
  213. {
  214. acutPrintf(采用T("\n设置层名称出错"));
  215. }
  216. es = pLine->setConstantWidth(lineWeight);
  217. if(Acad::eOk != es)
  218. {
  219. acutPrintf(采用T("\n设置曲线宽度出错"));
  220. }
  221. AcDbObjectIdArray idArr;
  222. AcDbObjectId idLine = LoadEntity(pLine);
  223. idArr.append(idLine);记录ObjId
  224. //绘制禁止开口两边-------------------------
  225. 第一个邻边
  226. //--------------箭头-----------------------
  227. AcGePoint3d pt3dS;
  228. AcGePoint3d pt3dE;
  229. AcGePoint2d pt2dS;
  230. AcGePoint2d pt2dE;
  231. bool gotonext = true;
  232. if(segType == AcDbPolyline::SegType::kArc)
  233. {
  234. AcGeCircArc3d arc3d;
  235. plMin->getArcSegAt(plIndex,arc3d);
  236. AcGeCircArc2d arc2d;
  237. plMin->getArcSegAt(plIndex,arc2d);
  238. pt3dS = arc3d.startPoint();
  239. pt3dE = arc3d.endPoint();
  240. pt2dS = arc2d.startPoint();
  241. pt2dE = arc2d.endPoint();
  242. }
  243. else
  244. {
  245. AcGeLineSeg3d line3d;
  246. plMin->getLineSegAt(plIndex,line3d);
  247. AcGeLineSeg2d line2d;
  248. plMin->getLineSegAt(plIndex,line2d);
  249. pt3dS = line3d.startPoint();
  250. pt3dE = line3d.endPoint();
  251. pt2dS = line2d.startPoint();
  252. pt2dE = line2d.endPoint();
  253. }
  254. AcDbObjectId idPointer1;
  255. DrawPointer(plMin,!gotonext,plIndex,pt3dS,idPointer1);
  256. ads采用real dis=DEFAULT采用LEN;
  257. acedInitGet(RSG采用NOZERO+RSG采用NONEG,采用T("P"));
  258. CString strDis ;
  259. strDis.Format(采用T("\n输入该方向的禁止开口长度[从点击位置算起(P)]<%.2f>:"),dis);
  260. int ret = acedGetReal(strDis,&dis);
  261. int polyIndex = 0;
  262. if(ret == RTCAN)
  263. {
  264. EraseIds(idArr);
  265. RemoveEntity(idPointer1);
  266. delete plMin;
  267. return;
  268. }
  269. else if(ret == RTKWORD)
  270. {
  271. CString str;
  272. acedGetInput(str.GetBuffer(2));
  273. str.ReleaseBuffer();
  274. double length = 0.0;
  275. EraseIds(idArr);
  276. if(str.CompareNoCase(采用T("P")) == 0)
  277. {
  278. AcDbObjectIdArray pIdArr;
  279. strDis.Format(采用T("\n输入该方向的禁止开口长度<%.2f>:"),dis);
  280. acedInitGet(RSG采用NOZERO+RSG采用NONEG,NULL);
  281. ret = acedGetReal(strDis,&dis);
  282. if(ret == RTCAN)
  283. {
  284. RemoveEntity(idPointer1);
  285. delete plMin;
  286. return;
  287. }
  288. double disS = 0.0;
  289. double disE = 0.0;
  290. double disC = 0.0;
  291. plMin->getDistAtPoint(ptMinClose,disC);
  292. plMin->getDistAtPoint(pt3dS,disS);
  293. plMin->getDistAtPoint(pt3dE,disE);
  294. AcGePoint2d ptClose2d;
  295. Pt3dTo2d(ptMinClose,ptClose2d);
  296. double curBulge = 0.0;
  297. plMin->getBulgeAt(plIndex,curBulge);
  298. 向前面画
  299. length = abs(disS - disC);
  300. AcDbPolyline* pl1 = new AcDbPolyline();
  301. pl1->setConstantWidth(lineWeight);
  302. pl1->setLayer(strLayer);
  303. int pl1Index = 0;
  304. StartWithP(plMin,plIndex,dis,length,segType,ptClose2d,!gotonext,pl1,pl1Index);
  305. AcDbObjectId idPl1 = LoadEntity(pl1);
  306. pIdArr.append(idPl1);
  307. 移除第1个箭头
  308. RemoveEntity(idPointer1);
  309. --------------------向后面画--先画箭头------------------------
  310. AcDbObjectId idPointer2;
  311. DrawPointer(plMin,gotonext,plIndex,pt3dE,idPointer2);
  312. int count = plMin->numVerts();
  313. AcDbPolyline* pl2 = new AcDbPolyline();
  314. pl2->setConstantWidth(lineWeight);
  315. pl2->setLayer(strLayer);
  316. int pl2Index = 0;
  317. if(plIndex == count - 1)
  318. {
  319. double total = 0.0;
  320. double endParam = 0.0;
  321. plMin->getEndParam(endParam);
  322. plMin->getDistAtParam(endParam,total);
  323. disE = total;
  324. }
  325. length = abs(disC - disE);
  326. strDis.Format(采用T("\n输入该方向的禁止开口长度<%.2f>:"),dis);
  327. acedInitGet(RSG采用NOZERO+RSG采用NONEG,NULL);
  328. ret = acedGetReal(strDis,&dis);
  329. if(ret == RTCAN)
  330. {
  331. delete plMin;
  332. RemoveEntity(idPointer2);
  333. EraseIds(pIdArr);
  334. return;
  335. }
  336. StartWithP(plMin,plIndex,dis,length,segType,ptClose2d,gotonext,pl2,pl2Index);
  337. AcDbObjectId idPl2 = LoadEntity(pl2);
  338. pIdArr.append(idPl2);
  339. 移除第二个箭头
  340. RemoveEntity(idPointer2);
  341. AcDbPolyline* plAll = new AcDbPolyline();
  342. plAll->setConstantWidth(lineWeight);
  343. plAll->setLayer(strLayer);
  344. int plAllIndex = 0;
  345. AppendPLinePoint(idPl1,!gotonext,plAll,plAllIndex);
  346. AppendPLinePoint(idPl2,gotonext,plAll,plAllIndex);
  347. LoadEntity(plAll);
  348. EraseIds(pIdArr);
  349. }
  350. delete plMin;
  351. return;
  352. }
  353. //不是点击位置开始的情况------------------------------------
  354. //第一条边
  355. AcDbPolyline* pLine1 = new AcDbPolyline();
  356. pLine1->setConstantWidth(lineWeight);
  357. pLine1->setLayer(strLayer);
  358. int pLine1Index = 0;
  359. AcGePoint2d ptNextS;
  360. AcGePoint2d ptNextE;
  361. GetNextPt(plMin,!gotonext,plIndex,ptNextS,ptNextE);
  362. DrawByLen(!gotonext,ptNextE,ptNextS,dis,plMin,pLine1,pLine1Index);
  363. AcDbObjectId idLine1 = LoadEntity(pLine1);
  364. idArr.append(idLine1);
  365. RemoveEntity(idPointer1);
  366. //第二条边
  367. strDis.Format(采用T("\n输入该方向的禁止开口长度<%.2f>:"),dis);
  368. acedInitGet(RSG采用NOZERO+RSG采用NONEG,NULL);
  369. ret = acedGetReal(strDis,&dis);
  370. if(ret == RTCAN)
  371. {
  372. delete plMin;
  373. EraseIds(idArr);
  374. return;
  375. }
  376. AcDbObjectId idPointer2;
  377. DrawPointer(plMin,gotonext,plIndex,pt3dE,idPointer2);
  378. AcDbPolyline* pLine2 = new AcDbPolyline();
  379. pLine2->setConstantWidth(lineWeight);
  380. pLine2->setLayer(strLayer);
  381. int pLine2Index = 0;
  382. GetNextPt(plMin,gotonext,plIndex,ptNextS,ptNextE);
  383. DrawByLen(gotonext,ptNextS,ptNextE,dis,plMin,pLine2,pLine2Index);
  384. AcDbObjectId idLine2 = LoadEntity(pLine2);
  385. idArr.append(idLine2);
  386. RemoveEntity(idPointer2);
  387. delete plMin;
  388. //合并多段线----------------------------------------
  389. AcDbPolyline* pl = new AcDbPolyline();
  390. pl->setConstantWidth(lineWeight);
  391. pl->setLayer(strLayer);
  392. int plIndex1 = 0;
  393. AppendPLinePoint(idLine1,false,pl,plIndex1);
  394. AppendPLinePoint(idLine,true,pl,plIndex1);
  395. AppendPLinePoint(idLine2,true,pl,plIndex1);
  396. LoadEntity(pl);
  397. //移除之前画上去的3条多段线
  398. EraseIds(idArr);
  399. }
  400. static void StartWithP(const AcDbPolyline* plMin,const int& plIndex,const double& dis,
  401. const double& length,const AcDbPolyline::SegType& segType,const AcGePoint2d& ptClose2d,const bool& gotonext,AcDbPolyline* pl1,int& pl1Index)
  402. {
  403. AcGePoint2d ptS;
  404. AcGePoint2d ptE;
  405. double curBulge = 0.0;
  406. plMin->getBulgeAt(plIndex,curBulge);
  407. double thisLen = 0.0;
  408. if(segType == AcDbPolyline::SegType::kArc)
  409. {
  410. AcGeCircArc2d arc2d;
  411. plMin->getArcSegAt(plIndex,arc2d);
  412. ptS = arc2d.startPoint();
  413. ptE = arc2d.endPoint();
  414. thisLen = arc2d.length(arc2d.paramOf(ptS),arc2d.paramOf(ptE));
  415. }
  416. else
  417. {
  418. AcGeLineSeg2d line2d;
  419. plMin->getLineSegAt(plIndex,line2d);
  420. ptS = line2d.startPoint();
  421. ptE = line2d.endPoint();
  422. }
  423. if(dis > length)
  424. {
  425. double bulge1 = 0.0;
  426. if(segType == AcDbPolyline::SegType::kArc)
  427. {
  428. bulge1 = tan(atan(curBulge) * length / thisLen);
  429. }
  430. if(!gotonext)
  431. {
  432. pl1->addVertexAt(pl1Index,ptClose2d,-bulge1);
  433. pl1Index++;
  434. pl1->addVertexAt(pl1Index,ptS);
  435. pl1Index ++;
  436. }
  437. else
  438. {
  439. pl1->addVertexAt(pl1Index,ptClose2d,bulge1);
  440. pl1Index++;
  441. pl1->addVertexAt(pl1Index,ptE);
  442. pl1Index ++;
  443. }
  444. AcGePoint2d ptNextS;
  445. AcGePoint2d ptNextE;
  446. GetNextPt(plMin,gotonext,plIndex,ptNextS,ptNextE);
  447. DrawByLen(gotonext,ptNextS,ptNextE,dis-length,plMin,pl1,pl1Index);
  448. }
  449. else
  450. {
  451. AcGePoint2d ptEnding;
  452. if(segType == AcDbPolyline::SegType::kArc)
  453. {
  454. AcGeCircArc2d arc2d;
  455. plMin->getArcSegAt(plIndex,arc2d);
  456. if(!gotonext)
  457. {
  458. GetPtAtDistOnCurve(&arc2d,ptClose2d,dis,ptEnding,Adesk::kFalse);
  459. }
  460. else
  461. {
  462. GetPtAtDistOnCurve(&arc2d,ptClose2d,dis,ptEnding,Adesk::kTrue);
  463. }
  464. }
  465. else
  466. {
  467. AcGeLineSeg2d line2d;
  468. plMin->getLineSegAt(plIndex,line2d);
  469. if(!gotonext)
  470. {
  471. GetPtAtDistOnCurve(&line2d,ptClose2d,dis,ptEnding,Adesk::kFalse);
  472. }
  473. else
  474. {
  475. GetPtAtDistOnCurve(&line2d,ptClose2d,dis,ptEnding,Adesk::kTrue);
  476. }
  477. }
  478. double bulge1 = 0.0;
  479. if(segType == AcDbPolyline::SegType::kArc)
  480. {
  481. bulge1 = tan(atan(curBulge) * dis / thisLen);
  482. }
  483. if(!gotonext)
  484. {
  485. pl1->addVertexAt(pl1Index,ptClose2d,-bulge1);
  486. }
  487. else
  488. {
  489. pl1->addVertexAt(pl1Index,ptClose2d,bulge1);
  490. }
  491. pl1Index++;
  492. pl1->addVertexAt(pl1Index,ptEnding);
  493. }
  494. }
  495. static void GetNextPt(const AcDbPolyline* plMin,const bool& gotonext,const int& plIndex,AcGePoint2d& ptNextS,AcGePoint2d& ptNextE)
  496. {
  497. int nextIndex = 0;
  498. int count = plMin->numVerts();
  499. if(!gotonext)
  500. {
  501. if(plIndex > 0)
  502. {
  503. nextIndex = plIndex - 1;
  504. }
  505. else
  506. {
  507. nextIndex = count - 1;
  508. }
  509. }
  510. else
  511. {
  512. if(plIndex < count - 1)
  513. {
  514. nextIndex = plIndex + 1;
  515. }
  516. else
  517. {
  518. nextIndex = 0;
  519. }
  520. }
  521. AcDbPolyline::SegType nextType = plMin->segType(nextIndex);
  522. if(nextType == AcDbPolyline::SegType::kArc)
  523. {
  524. AcGeCircArc2d arc2d;
  525. plMin->getArcSegAt(nextIndex,arc2d);
  526. ptNextS = arc2d.startPoint();
  527. ptNextE = arc2d.endPoint();
  528. }
  529. else
  530. {
  531. AcGeLineSeg2d line2d;
  532. plMin->getLineSegAt(nextIndex,line2d);
  533. ptNextS = line2d.startPoint();
  534. ptNextE = line2d.endPoint();
  535. }
  536. }
  537. 合成多段线
  538. static void AppendPLinePoint(const AcDbObjectId& id,const bool& gotoNext,AcDbPolyline* pLine,int& plIndex)
  539. {
  540. AcDbEntity* pEnt = NULL;
  541. Acad::ErrorStatus es = acdbOpenObject(pEnt,id,AcDb::OpenMode::kForRead);
  542. if(es != Acad::eOk)
  543. {
  544. acutPrintf(采用T("open object failed in combine pline"));
  545. return;
  546. }
  547. if(!pEnt->isKindOf(AcDbPolyline::desc()))
  548. {
  549. pEnt->close();
  550. return;
  551. }
  552. AcDbPolyline* pPoly = NULL;
  553. pPoly = (AcDbPolyline*)pEnt;
  554. AcGePoint2dArray ptArr;
  555. int count = pPoly->numVerts();
  556. AcGePoint2d pt ;
  557. double bulge = 0.0;
  558. if(gotoNext)
  559. {
  560. for(int i = 0;i < count ; i++)
  561. {
  562. pPoly->getPointAt(i,pt);
  563. pPoly->getBulgeAt(i,bulge);
  564. pLine->addVertexAt(plIndex,pt,bulge);
  565. plIndex++;
  566. }
  567. }
  568. else
  569. {
  570. for(int i = count - 1;i > 0; i--)
  571. {
  572. pPoly->getPointAt(i,pt);
  573. if(i > 0)
  574. {
  575. pPoly->getBulgeAt(i - 1,bulge);
  576. }
  577. else
  578. {
  579. pPoly->getBulgeAt(0,bulge);
  580. }
  581. pLine->addVertexAt(plIndex,pt,-bulge);
  582. plIndex++;
  583. }
  584. }
  585. pEnt->close();
  586. }
  587. static void EraseIds(AcDbObjectIdArray idArr)
  588. {
  589. if(idArr == NULL || idArr.length() == 0)
  590. {
  591. return;
  592. }
  593. for(int i = 0;i < idArr.length(); i++)
  594. {
  595. AcDbEntity* pDel = NULL;
  596. if(Acad::eOk != acdbOpenObject(pDel,idArr.at(i),AcDb::OpenMode::kForWrite))
  597. {
  598. continue;
  599. }
  600. if(Acad::eOk != pDel->erase())
  601. {
  602. acutPrintf(采用T("\n删除第%d个实体失败"),i);
  603. }
  604. pDel->close();
  605. }
  606. }
  607. 绘制箭头(ptStart 为转角线段的起点)
  608. static void DrawPointer(const AcDbPolyline* pl,bool gotonext,const int& plIndex,const AcGePoint3d& ptDraw,AcDbObjectId& idPointer)
  609. {
  610. //--当前边相关信息
  611. AcGePoint3d ptCurStart;
  612. AcGePoint3d ptCurEnd;
  613. AcGeCircArc3d arc3dCur;
  614. AcGeLineSeg3d line3dCur;
  615. AcDbPolyline::SegType curType = pl->segType(plIndex);
  616. if(curType == AcDbPolyline::SegType::kArc)
  617. {
  618. pl->getArcSegAt(plIndex,arc3dCur);
  619. ptCurStart = arc3dCur.startPoint();
  620. ptCurEnd = arc3dCur.endPoint();
  621. }
  622. else
  623. {
  624. pl->getLineSegAt(plIndex,line3dCur);
  625. ptCurStart = line3dCur.startPoint();
  626. ptCurEnd = line3dCur.endPoint();
  627. }
  628. double paramDraw = 0.0;
  629. if(pl->getParamAtPoint(ptDraw,paramDraw)!=Acad::eOk)
  630. {
  631. return;
  632. }
  633. AcGeVector3d v3d;
  634. pl->getFirstDeriv(paramDraw,v3d);
  635. AcGeVector2d v(v3d[X],v3d[Y]);
  636. AcGePoint2d pt0(ptDraw[X],ptDraw[Y]);
  637. v.normalize();
  638. if(!gotonext)
  639. {
  640. v = -v;
  641. }
  642. AcGeVector2d vVer = v;
  643. 绘制箭头
  644. AcDbPolyline* pLine = new AcDbPolyline();
  645. pLine->addVertexAt(0,pt0);
  646. vVer.rotateBy(PI/2);
  647. AcGePoint2d pt1 = pt0 + vVer *POINTERWIDTH / 2;
  648. pLine->addVertexAt(1,pt1);
  649. vVer.rotateBy(-PI/2);
  650. AcGePoint2d pt2 = pt1 + vVer * POINTERLENGTH;
  651. pLine->addVertexAt(2,pt2);
  652. vVer.rotateBy(PI/2);
  653. AcGePoint2d pt3 = pt2 + vVer * POINTERWIDTH / 2;
  654. pLine->addVertexAt(3,pt3);
  655. vVer.rotateBy(- 3 * PI/4);
  656. AcGePoint2d pt4 = pt3 + vVer * sqrt(2.0) * POINTERWIDTH;
  657. pLine->addVertexAt(4,pt4);
  658. vVer.rotateBy(-PI/2);
  659. AcGePoint2d pt5 = pt4 + vVer * sqrt(2.0) * POINTERWIDTH;
  660. pLine->addVertexAt(5,pt5);
  661. vVer.rotateBy(-3 * PI/4);
  662. AcGePoint2d pt6 = pt5 + vVer * POINTERWIDTH / 2;
  663. pLine->addVertexAt(6,pt6);
  664. vVer.rotateBy(PI/2);
  665. AcGePoint2d pt7 = pt6 + vVer * POINTERLENGTH ;
  666. pLine->addVertexAt(7,pt7);
  667. vVer.rotateBy(-PI/2);
  668. AcGePoint2d pt8 = pt7 + vVer * POINTERWIDTH / 2;
  669. pLine->addVertexAt(8,pt8);
  670. idPointer = LoadEntity(pLine);
  671. }
  672. static void RemoveEntity(AcDbObjectId entId)
  673. {
  674. AcDbEntity* pEnt = NULL;
  675. if(acdbOpenObject(pEnt,entId,AcDb::OpenMode::kForWrite) == Acad::eOk)
  676. {
  677. if(pEnt->erase() != Acad::eOk)
  678. {
  679. acutPrintf(采用T("\n移除对象失败"));
  680. return;
  681. }
  682. }
  683. else
  684. {
  685. acutPrintf(采用T("\n打开对象失败"));
  686. }
  687. pEnt->close();
  688. }
  689. 2d坐标转为3d
  690. static void Pt2dTo3d(AcGePoint2d& pt2d,AcGePoint3d& pt3d)
  691. {
  692. pt3d[X] = pt2d[X];
  693. pt3d[Y] = pt2d[Y];
  694. pt3d[Z] = 0;
  695. }
  696. 3d坐标转化为X,Y轴上的2D坐标
  697. static void Pt3dTo2d(const AcGePoint3d& pt3d,AcGePoint2d& pt2d)
  698. {
  699. pt2d = pt3d.convert2d(AcGePlane(AcGePoint3d::kOrigin, AcGeVector3d(0,0, 1)));
  700. }
  701. //from:起点,to:终点(这两点要相邻)
  702. //paramDis:沿着多段线画多长
  703. //pl:多段线
  704. //pPoly:新的多段线
  705. static void DrawByLen(const bool& gotoNext ,const AcGePoint2d& from,const AcGePoint2d& to,const double& paramDis,const AcDbPolyline* pl,AcDbPolyline* pPoly,int& polyIndex)
  706. {
  707. if(paramDis <= 0)
  708. {
  709. return;
  710. }
  711. int len = pl->numVerts();
  712. AcGeCircArc2d arc2d;
  713. AcGeLineSeg2d line2d;
  714. AcGePoint2d ptS;
  715. AcGePoint2d ptE;
  716. bool isFind = false;
  717. int plIndex = 0;
  718. AcGeCurve2d* pCurve = NULL;
  719. for(int i = 0;i < len;i++)
  720. {
  721. AcDbPolyline::SegType st = pl->segType(i);
  722. if(st == AcDbPolyline::SegType::kArc)
  723. {
  724. pl->getArcSegAt(i,arc2d);
  725. pCurve = &arc2d;
  726. }
  727. else if(st == AcDbPolyline::SegType::kLine)
  728. {
  729. pl->getLineSegAt(i,line2d);
  730. pCurve = &line2d;
  731. }
  732. if(!pCurve->hasStartPoint(ptS) || !pCurve->hasEndPoint(ptE))
  733. {
  734. continue;
  735. }
  736. if(ptS == from && ptE == to || ptS == to && ptE == from)
  737. {
  738. plIndex = i;
  739. isFind = true;
  740. break;
  741. }
  742. }
  743. double sumDis = 0.0;
  744. if(isFind)
  745. {
  746. DrawIt(gotoNext,pl,paramDis,from,polyIndex,plIndex,sumDis,pPoly);
  747. }
  748. else
  749. {
  750. acutPrintf(采用T("\nnot found"));
  751. }
  752. }
  753. //summary
  754. //指定一个起点和一条多段线,沿着多段线画出指定距离,递归执行,每次往后(前)移动一个点,直到画完指定的距离,
  755. //pl:多段线
  756. //paramDis:画多长
  757. //ptStart:起始点
  758. //polyIndex:添加到第几个了
  759. //plIndex,遍历到多段线第几条线
  760. //isSToE,遍历的顺序1:从前向后  0:从后向前
  761. //sumDis,目前画的总长度
  762. //pPoly:画出来的多段线
  763. static void DrawIt(const bool& gotoNext,const AcDbPolyline* pl,const double& paramDis,const AcGePoint2d& ptStart,int& polyIndex,int& plIndex,double& sumDis,AcDbPolyline* pPoly)
  764. {
  765. AcDbPolyline::SegType st = pl->segType(plIndex);
  766. AcGePoint2d ptS;
  767. AcGePoint2d ptE;
  768. double leftDis = 0.0;
  769. double curveDis = 0.0;
  770. double bulge = 0.0;
  771. AcGeCurve2d* pCurve = NULL;
  772. AcGeCircArc2d arc2d;
  773. AcGeLineSeg2d line2d;
  774. int len = pl->numVerts();
  775. if(polyIndex == 2*(len - 2))
  776. {
  777. acutPrintf(采用T("\nend poly is %d"),polyIndex);
  778. return;
  779. }
  780. if(st == AcDbPolyline::SegType::kArc)
  781. {
  782. pl->getArcSegAt(plIndex,arc2d);
  783. pCurve = &arc2d;!!!注意:指针的生命周期一定要大于等于指向的变量的生命周期,否则变量release掉指针就空了,再次使用指针程序直接崩溃!!
  784. }
  785. else if(st == AcDbPolyline::SegType::kLine)
  786. {
  787. pl->getLineSegAt(plIndex,line2d);
  788. pCurve = &line2d;
  789. }
  790. if(!pCurve->hasStartPoint(ptS) || !pCurve->hasEndPoint(ptE))
  791. {
  792. return;
  793. }
  794. curveDis = pCurve->length(pCurve->paramOf(ptS),pCurve->paramOf(ptE));
  795. leftDis = paramDis - sumDis;
  796. pl->getBulgeAt(plIndex,bulge);
  797. if(curveDis > leftDis)
  798. {
  799. double paramEnding = 0.0;
  800. if(gotoNext)
  801. {
  802. AcGePoint2d ptEnding;
  803. AcGePoint2d ptS;
  804. pCurve->hasStartPoint(ptS);
  805. GetPtAtDistOnCurve(pCurve,ptS,leftDis,ptEnding,Adesk::kTrue);
  806. bulge = tan(atan(bulge) * leftDis/curveDis);
  807. pPoly->addVertexAt(polyIndex,ptS,bulge);
  808. polyIndex ++;
  809. pPoly->addVertexAt(polyIndex,ptEnding);
  810. }
  811. else
  812. {
  813. AcGePoint2d ptEnding;
  814. AcGePoint2d ptE;
  815. pCurve->hasEndPoint(ptE);
  816. GetPtAtDistOnCurve(pCurve,ptE,leftDis,ptEnding,Adesk::kFalse);
  817. bulge = tan(atan(bulge) * leftDis/curveDis);
  818. pPoly->addVertexAt(polyIndex,ptE,-bulge);
  819. polyIndex ++;
  820. pPoly->addVertexAt(polyIndex,ptEnding);
  821. }
  822. return;
  823. }
  824. else
  825. {
  826. if(gotoNext)
  827. {
  828. pPoly->addVertexAt(polyIndex,ptS,bulge);
  829. polyIndex ++;
  830. pPoly->addVertexAt(polyIndex,ptE);
  831. polyIndex ++;
  832. //acutPrintf(采用T("\nplIndex is %d,poly is %d。is goto next,bulge is %.2f"),plIndex,polyIndex,bulge);
  833. }
  834. else
  835. {
  836. pPoly->addVertexAt(polyIndex,ptE,-bulge);
  837. polyIndex ++;
  838. pPoly->addVertexAt(polyIndex,ptS);
  839. polyIndex ++;
  840. }
  841. /*acutPrintf(采用T("\nptS[X] :%.2f,ptS[Y]:%.2f,ptE[X]:%.2f,ptE[Y]:%.2f"),ptS[X],ptS[Y],ptE[X],ptE[Y]);*/
  842. sumDis += curveDis;
  843. }
  844. if(gotoNext)
  845. {
  846. plIndex = plIndex < len - 1  ? ++plIndex : 0;
  847. }
  848. else
  849. {
  850. plIndex = plIndex > 0 ? --plIndex : len - 1;
  851. }
  852. DrawIt(gotoNext,pl,paramDis,ptStart,polyIndex,plIndex,sumDis,pPoly);
  853. }
  854. 反回曲线上一定距离的点(默认从起点开始计算)
  855. pCurve:曲线指针,dist:距离,point:要返回的点
  856. Adesk::Boolean isGotoNext  true:沿着正向寻找,false:沿着反方向寻找
  857. static void GetPtAtDistOnCurve(const AcGeCurve2d* pCurve,const AcGePoint2d& ptInput,double dist,AcGePoint2d& point,Adesk::Boolean isGotoNext)
  858. {
  859. if(pCurve == NULL)
  860. {
  861. return;
  862. }
  863. AcGePoint2d ptS;
  864. ptS = ptInput;
  865. double pa = 0.0;
  866. double datumParam = 0.0;
  867. //Adesk::Boolean posParamDir = Adesk::kTrue;
  868. datumParam = pCurve->paramOf(ptS);
  869. pa = pCurve->paramAtLength(datumParam,dist,isGotoNext);
  870. point = pCurve->evalPoint(pa);
  871. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-1-4 12:28 , Processed in 0.128724 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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