测试结果:
主要思路:拾取一个点作为矩形的插入点,分别以该点进行两次jig操作,就能得到白色的两个相交的polyline,之后需要变成红色的封闭多段线。做法就是:求出两个白色矩形的面域,然后通过bool操作的并集,使得两个面域合并成一个面域。最后就把这个面域在转换成polyline就完成了。其中要注意, 要想在使用向导创建的工程里使用面域的类,需要在头文件:StdAfx.h 中写上这句宏命令#define _BREP_SUPPORT_,就不需要引用库文件了。下面给出详细代码:
拖动矩形的jig操作:
DrawRecJig::DrawRecJig() { pl = NULL; } DrawRecJig::~DrawRecJig() { } AcEdJig::DragStatus DrawRecJig::sampler() { setUserInputControls((AcEdJig::UserInputControls)( AcEdJig::kAccept3dCoordinates | AcEdJig::kNoNegativeResponseAccepted | AcEdJig::kNullResponseAccepted )); AcGePoint3d ptTemp; AcEdJig::DragStatus status = acquirePoint(ptTemp); if (ptTemp != ptCurrent) { ptCurrent= ptTemp; } else if (status == DragStatus::kNormal) { return AcEdJig::kNoChange; } return status; } bool DrawRecJig::update() { double dist = CConvertUtil::ToPoint2d(ptCenter).distanceTo(CConvertUtil::ToPoint2d(ptCurrent)); // 提取两个角点的坐标值 double x1 = ptCenter.x, x2 = ptCurrent.x; double y1 = ptCenter.y, y2 = ptCurrent.y; // 计算矩形的角点 AcGePoint2d ptLeftBottom(min(x1, x2), min(y1, y2)); AcGePoint2d ptRightBottom(max(x1, x2), min(y1, y2)); AcGePoint2d ptRightTop(max(x1, x2), max(y1, y2)); AcGePoint2d ptLeftTop(min(x1, x2), max(y1, y2)); pl->setPointAt(0, ptLeftBottom); pl->setPointAt(1, ptLeftTop); pl->setPointAt(2, ptRightTop); pl->setPointAt(3, ptRightBottom); return true; } AcDbEntity * DrawRecJig::entity() const { return pl; } bool DrawRecJig::DoIt(AcGePoint3d & ptCenter, AcDbObjectId &plId) { this->ptCenter = ptCenter; pl = new AcDbPolyline(); for (int i = 0; i < 4; i++) { pl->addVertexAt(i, CConvertUtil::ToPoint2d(ptCenter)); } pl->setClosed(true); setDispPrompt(L"请拖动鼠标:"); if (drag()==kNormal) { //加入到模型空间的封装 plId=CDwgDataBaseUtil::PostToModelSpace(pl); return true; } else { delete pl; return false; } }
命令类:
static void ECDMyGroupEUnion() { DrawRecJig recJig = DrawRecJig(); ads_point pt; AcDbPolyline *pl1 = NULL, *pl2 = NULL; if (acedGetPoint(NULL, L" 请选择插入点:", pt) == RTNORM) { AcDbObjectId oId1, oId2; if (recJig.DoIt(asPnt3d(pt), oId1)) { pl1 = AcDbPolyline::cast(recJig.entity()); } if (recJig.DoIt(asPnt3d(pt), oId2)) { pl2 = AcDbPolyline::cast(recJig.entity()); } AcDbVoidPtrArray curveSegments; AcDbVoidPtrArray regions; curveSegments.append(pl1); curveSegments.append(pl2); if (AcDbRegion::createFromCurves(curveSegments, regions) == Acad::eOk) { AcDbRegion *region =(AcDbRegion *)regions[0]; region->booleanOper(AcDb::BoolOperType::kBoolUnite, (AcDbRegion *)regions[1]); AcGePoint3dArray ptArr; CRegionUtil::GetRegionPoints(region, ptArr); for (int i = 0; i < regions.length (); i++) { AcDbRegion *regionTemp = (AcDbRegion *)regions[i]; regionTemp->erase(); regionTemp->close(); } region->close(); AcDbPolyline *plTemp1 = new AcDbPolyline(); for (int i = 0; i <ptArr.length(); i++) { plTemp1->addVertexAt(plTemp1->numVerts(), CConvertUtil::ToPoint2d(ptArr.at(i)), 0, 0, 0); } plTemp1->setClosed(Adesk::kTrue); plTemp1->setColorIndex(1); CDwgDataBaseUtil::PostToModelSpace(plTemp1); plTemp1->close(); } pl1->close(); pl2->close(); } }
面域转AcGePoint3d:
void CRegionUtil::GetRegionPoints(AcDbRegion* pRegion,AcGePoint3dArray &points) { AcBrBrep*pBrep = new AcBrBrep; pBrep->set(*pRegion); AcBrBrepFaceTraverser brFaTrav; for (brFaTrav.setBrep(*pBrep); !brFaTrav.done(); brFaTrav.next()) { AcBrFaceLoopTraverser faLoTrav; AcBrFace face; brFaTrav.getFace(face); for (faLoTrav.setFace(face); !faLoTrav.done(); faLoTrav.next()) { AcBrLoopEdgeTraverser loEdTrav; if (loEdTrav.setLoop(faLoTrav) == AcBr::eOk) { for (; !loEdTrav.done(); loEdTrav.next()) { AcBrEdge edge; loEdTrav.getEdge(edge); AcBrVertex start; edge.getVertex1(start); AcGePoint3d pt; start.getPoint(pt); points.append(pt); } } // else its an isolated loop } } delete pBrep; }