#include "StdAfx.h" #include "AecDbJoggedCamera.h" #include "MFCDbDwgFiler.h" #include "CoreTools.h" #include "simpleProperty.h" #include "dbgrip.h" #include "COMPARE_DOUBLE.h" #include "hlrcutoption.h" #define PIXEL_SIZE 4 namespace { struct sort_jogged { sort_jogged(const AcGeVector3d &vt) : m_vt(vt){} AcGeVector3d m_vt; bool operator()(const AecDbJoggedCamera::Camera *pCam1, const AecDbJoggedCamera::Camera *pCam2) const { AcGeLine3d line(AcGePoint3d::kOrigin, m_vt); AcGePoint3d pt1 = line.closestPointTo(pCam1->getMidPoint()); AcGePoint3d pt2 = line.closestPointTo(pCam2->getMidPoint()); if ((pt1 - pt2).isCodirectionalTo(m_vt)) return false; else return true; } }; // 检查ptChk点,在直线(ptOrg, vt)上的投影点ptClosed在ptOrg的后方 bool checkPoint(const AcGePoint3d &ptOrg , const AcGeVector3d &vt , const AcGePoint3d &ptChk , AcGePoint3d &ptClosed , const bool &bAllowSame) { /* ->vt-> OK: ptOrg->->->ptClosed->->-> NO: ptClosed->->->ptOrg->->-> */ AcGeLine3d line(ptOrg, vt); ptClosed = line.closestPointTo(ptChk); if (ptClosed.isEqualTo(ptOrg)) { if (bAllowSame) return true; else return false; } return (ptClosed - ptOrg).isCodirectionalTo(vt); } bool ptInnerSegment(const AcGePoint3d &pt, const AcGeLineSeg3d &seg) { double dParam; double dStart = seg.paramOf(seg.startPoint()); double dEnd = seg.paramOf(seg.endPoint()); if (seg.isOn(pt, dParam)) { if (dParam < dEnd && dParam > dStart) return true; } return false; } bool isColinearAndOverlapping(AcGeLineSeg3d &seg1, AcGeLineSeg3d &seg2) { // 不共线,一定不重叠 if (!seg1.isColinearTo(seg2)) return false; // 已经共线 // 如果seg2的起点或终点在seg1上,并且不在端点上,则认为两线段重叠 if (ptInnerSegment(seg2.startPoint(), seg1) || ptInnerSegment(seg2.endPoint(), seg1)) { return true; } // 同上 if (ptInnerSegment(seg1.startPoint(), seg2) || ptInnerSegment(seg1.endPoint(), seg2)) { return true; } // 再判断两个线段完全重合 if (seg1.startPoint().isEqualTo(seg2.startPoint()) && seg1.endPoint().isEqualTo(seg2.endPoint())) { return true; } if (seg1.startPoint().isEqualTo(seg2.endPoint()) && seg1.endPoint().isEqualTo(seg2.startPoint())) { return true; } return false; } bool isRegionOverlapping(AcGeLineSeg3d &seg1, AcGeLineSeg3d &seg2) { // 如果不平行,则认为区域一定重叠 if (!seg1.isParallelTo(seg2)) return true; // 如果共线,则用isColinearAndOverlapping来判断 if (seg1.isColinearTo(seg2)) return isColinearAndOverlapping(seg1, seg2); // 已经平行,但不共线,则判断两线段所在的区域是否重叠 // 让seg1两个端点seg2所在无限直线上投影,得到seg3 // 如果seg3与seg2重叠,则认为两线段所在的区域重叠 AcGeLine3d line(seg2.startPoint(), seg2.direction()); AcGePoint3d pt1 = line.closestPointTo(seg1.startPoint()); AcGePoint3d pt2 = line.closestPointTo(seg1.endPoint()); AcGeLineSeg3d seg3(pt1, pt2); return isColinearAndOverlapping(seg2, seg3); } AcGeVector3d getViewDir() { AcGePoint3dArray pts; struct resbuf rb; acedGetVar(_T("viewdir"), &rb); ads_point dirPt; acdbUcs2Wcs(rb.resval.rpoint, dirPt, Adesk::kTrue); return asVec3d(dirPt); } AcDbExtents getResultExtent(const AcDbObjectIdArray &ar) { AcDbExtents ext, _ext; for (int i(0); i < ar.length(); ++i) { AcDbEntityPointer ent(ar[i], AcDb::kForRead); if (ent.openStatus() == Acad::eOk) { ent->getGeomExtents(_ext); ext.addExt(_ext); } } return ext; } bool Grip_WorldDrawfunc(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId &entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize) { bool bHori(false); AcGeVector3d vtNow(getViewDir()); if (vtNow.isCodirectionalTo(AcGeVector3d::kZAxis)) bHori = true; // 画夹点 AcGiFillType eOldFill = pWd->subEntityTraits().fillType(); int nOldColor = pWd->subEntityTraits().color(); AecDbXCamera::GripData *pGrip = (AecDbXCamera::GripData *)pThis->appData(); AcGePoint3d ptGe[5], ptBox[5]; AcGePoint3d ptGrip = pThis->gripPoint(); double dOne = CoreTools::PixelToWcs(1); ptGe[0] = ptGrip; ptGe[0].x -= PIXEL_SIZE * dOne; ptGe[1] = ptGrip; ptGe[1].x += PIXEL_SIZE * dOne; ptBox[0] = ptGe[0]; ptBox[0].y -= PIXEL_SIZE * dOne; ptBox[1] = ptGe[0]; ptBox[1].y += PIXEL_SIZE * dOne; ptBox[2] = ptGe[1]; ptBox[2].y += PIXEL_SIZE * dOne; ptBox[3] = ptGe[1]; ptBox[3].y -= PIXEL_SIZE * dOne; if (!bHori) { AcGePlane pln(ptGrip, vtNow); AcGeVector3d X, Y; pln.getCoordSystem(ptGrip, X, Y); AcGeMatrix3d mat; mat.setToAlignCoordSys(ptGrip, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis , ptGrip, X, Y, vtNow); ptBox[0].transformBy(mat); ptBox[1].transformBy(mat); ptBox[2].transformBy(mat); ptBox[3].transformBy(mat); } pWd->subEntityTraits().setFillType(kAcGiFillAlways); pWd->geometry().polygon(4, ptBox); pWd->subEntityTraits().setFillType(eOldFill); //// // 每次取4个点 AcGePoint3d arFrame[5] = {}; pWd->subEntityTraits().setColor(9); if (bHori) { for (int i(3); i < pGrip->m_arSelectFrame.length(); i += 4) { arFrame[0] = pGrip->m_arSelectFrame[i - 3]; arFrame[1] = pGrip->m_arSelectFrame[i - 2]; arFrame[2] = pGrip->m_arSelectFrame[i - 1]; arFrame[3] = pGrip->m_arSelectFrame[i]; pWd->geometry().polyline(4, arFrame); } } else { // 8个一组,4个低点在前,4个高点在后 AcGePoint3d ptT1, ptT2, ptT3, ptT4, ptB1, ptB2, ptB3, ptB4; // 8个点一起取 for (int i(7); i < pGrip->m_arSelectFrame.length(); i += 8) { // 4-7 ptT1 = pGrip->m_arSelectFrame[i - 3]; ptT2 = pGrip->m_arSelectFrame[i - 2]; ptT3 = pGrip->m_arSelectFrame[i - 1]; ptT4 = pGrip->m_arSelectFrame[i - 0]; // 0-3 ptB1 = pGrip->m_arSelectFrame[i - 7]; ptB2 = pGrip->m_arSelectFrame[i - 6]; ptB3 = pGrip->m_arSelectFrame[i - 5]; ptB4 = pGrip->m_arSelectFrame[i - 4]; arFrame[0] = ptT1; arFrame[1] = ptT2; arFrame[2] = ptT3; arFrame[3] = ptT4; arFrame[4] = ptT1; pWd->geometry().polyline(5, arFrame); arFrame[0] = ptB1; arFrame[1] = ptB2; arFrame[2] = ptB3; arFrame[3] = ptB4; pWd->geometry().polyline(4, arFrame); arFrame[0] = ptT1; arFrame[1] = ptB1; pWd->geometry().polyline(2, arFrame); arFrame[0] = ptT2; arFrame[1] = ptB2; pWd->geometry().polyline(2, arFrame); arFrame[0] = ptT3; arFrame[1] = ptB3; pWd->geometry().polyline(2, arFrame); arFrame[0] = ptT4; arFrame[1] = ptB4; pWd->geometry().polyline(2, arFrame); } } // 画结果范围 if (pGrip->m_bDrawResultFrame && !pGrip->m_arResultFrame.isEmpty()) { // 每次取4个点 for (int i(3), clr = 1; i < pGrip->m_arResultFrame.length(); i += 4, ++clr) { arFrame[0] = pGrip->m_arResultFrame[i - 3]; arFrame[1] = pGrip->m_arResultFrame[i - 2]; arFrame[2] = pGrip->m_arResultFrame[i - 1]; arFrame[3] = pGrip->m_arResultFrame[i]; arFrame[4] = arFrame[0]; // 颜色9保留 if (clr == 9) ++clr; pWd->subEntityTraits().setColor(clr); pWd->geometry().polyline(5, arFrame); } pWd->subEntityTraits().setColor(nOldColor); } return true; } void addGripData( const int &idxCamera , const int &idxPoint , const AcGePoint3d &pt , AcArray &gripDatas , AcDbGripDataPtrArray &grips) { AecDbXCamera::GripData *gpd = new AecDbXCamera::GripData; gpd->m_idx = idxCamera; gpd->m_subIdx = idxPoint; gpd->m_pt = pt; AcDbGripData *pGripData = new AcDbGripData; pGripData->setGripPoint(pt); pGripData->setWorldDraw(Grip_WorldDrawfunc); gripDatas.append(gpd); pGripData->setAppData(gpd); grips.append(pGripData); } } #pragma region AecDbJoggedCamera::Camera void AecDbJoggedCamera::Camera::getGripPoints(AcGePoint3dArray &ar) const { // 顺时针获取Grip点 /* 0-----1-----| | | 5 6 2 | | 4-----3-----| */ AcGePoint3d pt0 = m_ptStart; AcGePoint3d pt1 = pt0 + m_vtDir * .5; AcGePoint3d pt5 = CoreTools::MidPt(m_ptStart, m_ptEnd); AcGePoint3d pt2 = pt5 + m_vtDir; AcGePoint3d pt3 = m_ptEnd + m_vtDir * .5; AcGePoint3d pt4 = m_ptEnd; AcGePoint3d pt6 = CoreTools::MidPt(pt5, pt2); pt0.z = pt1.z = pt2.z = pt3.z = pt4.z = pt5.z = pt6.z = .0; ar.append(pt0); ar.append(pt1); ar.append(pt2); ar.append(pt3); ar.append(pt4); ar.append(pt5); ar.append(pt6); } Acad::ErrorStatus AecDbJoggedCamera::Camera::dwgOutFields(AcDbDwgFiler * pFiler) const { Acad::ErrorStatus es; es = pFiler->writeUInt32(AecDbJoggedCamera::Camera::kCurrentVersionNumber); if (es != Acad::eOk) return (es); pFiler->writePoint3d(m_ptStart); pFiler->writePoint3d(m_ptEnd); pFiler->writeDouble(m_dMinElev); pFiler->writeDouble(m_dMaxElev); pFiler->writeVector3d(m_vtDir); pFiler->writeInt16(m_iColor); pFiler->writePoint3d(m_ptOutput); pFiler->writeInt32(m_arResults.length()); for (int i(0); i < m_arResults.length(); ++i) pFiler->writeSoftPointerId(m_arResults[i]); return (pFiler->filerStatus()); } Acad::ErrorStatus AecDbJoggedCamera::Camera::dwgInFields(AcDbDwgFiler * pFiler) { Acad::ErrorStatus es; Adesk::UInt32 version = 0; es = pFiler->readUInt32(&version); if (es != Acad::eOk) return (es); if (version > AecDbJoggedCamera::Camera::kCurrentVersionNumber) return (Acad::eMakeMeProxy); pFiler->readPoint3d(&m_ptStart); pFiler->readPoint3d(&m_ptEnd); pFiler->readDouble(&m_dMinElev); pFiler->readDouble(&m_dMaxElev); pFiler->readVector3d(&m_vtDir); pFiler->readInt16(&m_iColor); pFiler->readPoint3d(&m_ptOutput); if (version > 1) { m_arResults.removeAll(); Adesk::Int32 num(0); pFiler->readInt32(&num); AcDbObjectId id; for (int i(0); i < num; ++i) { pFiler->readSoftPointerId((AcDbSoftPointerId *)&id); if (id.isValid()) m_arResults.append(id); } } return (pFiler->filerStatus()); } AcDbPolyline* AecDbJoggedCamera::Camera::getSectionPolygon() const { AcGePoint3dArray ar; AcGePoint3d pt0(m_ptStart), pt1(m_ptEnd), pt2(m_ptEnd), pt3(m_ptStart); pt0.z = pt1.z = m_dMinElev; pt2.z = pt3.z = m_dMaxElev; AcDbPolyline *pPoly = new AcDbPolyline(); AcGeVector3d vecNormal(m_vtDir.normal()); AcGeMatrix3d matWcs2Ocs; matWcs2Ocs.setToWorldToPlane(vecNormal); pt0.transformBy(matWcs2Ocs); pt1.transformBy(matWcs2Ocs); pt2.transformBy(matWcs2Ocs); pt3.transformBy(matWcs2Ocs); pPoly->setNormal(vecNormal); pPoly->setElevation(pt0.z); pPoly->addVertexAt(0, AcGePoint2d(pt0.x, pt0.y)); pPoly->addVertexAt(1, AcGePoint2d(pt1.x, pt1.y)); pPoly->addVertexAt(2, AcGePoint2d(pt2.x, pt2.y)); pPoly->addVertexAt(3, AcGePoint2d(pt3.x, pt3.y)); pPoly->addVertexAt(4, AcGePoint2d(pt0.x, pt0.y)); return pPoly; } void AecDbJoggedCamera::Camera::moveGripPointsAt(const int &_idx, const AcGeVector3d &offset) { AcGePoint3dArray arPts; getGripPoints(arPts); if (arPts.length() < 7) return; int idx(_idx); if (idx >= 100) idx -= 100; if (idx < 0 || idx >= arPts.length()) return; AcGeVector3d X((arPts[1] - arPts[0]).normal()); AcGeVector3d Y((arPts[0] - arPts[4]).normal()); AcGePoint3d ptNew(arPts[idx] + offset), ptOnLine; if (COMPARE_DOUBLE::equal_zero(ptNew.distanceTo(arPts[idx]))) return; AcGeLine3d lineTop(arPts[0], arPts[0] + m_vtDir); AcGeLine3d lineBottom(arPts[4], arPts[4] + m_vtDir); AcGeLine3d lineLeft(arPts[0], arPts[4]); AcGeLine3d lineRight(arPts[0] + m_vtDir, arPts[4] + m_vtDir); AcGeVector3d vtNew, vtOld; AcGeMatrix3d mat; double dDist(.0), dAngle; vtNew = ptNew - arPts[5]; switch (_idx) { case 0: vtOld = -getJoggedDir(); dAngle = vtOld.angleTo(vtNew, AcGeVector3d::kZAxis); m_vtDir.rotateBy(dAngle, AcGeVector3d::kZAxis); dDist = m_ptStart.distanceTo(m_ptEnd) * .5; m_ptStart = arPts[5] + vtNew.normal() * dDist; m_ptEnd = arPts[5] - vtNew.normal() * dDist; break; case 4: vtOld = getJoggedDir(); dAngle = vtOld.angleTo(vtNew, AcGeVector3d::kZAxis); m_vtDir.rotateBy(dAngle, AcGeVector3d::kZAxis); dDist = m_ptStart.distanceTo(m_ptEnd) * .5; m_ptEnd = arPts[5] + vtNew.normal() * dDist; m_ptStart = arPts[5] - vtNew.normal() * dDist; break; case 1: // 移动上端范围 if (offset.isParallelTo(X)) return; ptOnLine = lineTop.closestPointTo(ptNew); dDist = ptOnLine.distanceTo(ptNew); vtNew = ptNew - ptOnLine; if (!vtNew.isCodirectionalTo(Y)) dDist *= -1; m_ptStart += Y * dDist; break; case 2: // 右侧范围左右移动 if (offset.isParallelTo(Y)) return; ptOnLine = lineRight.closestPointTo(ptNew); dDist = ptOnLine.distanceTo(ptNew); vtNew = ptNew - ptOnLine; if (!vtNew.isCodirectionalTo(X)) dDist *= -1; m_vtDir = m_vtDir.normal() * (m_vtDir.length() + dDist); break; case 3: // 移动下端范围 if (offset.isParallelTo(X)) return; ptOnLine = lineBottom.closestPointTo(ptNew); dDist = ptOnLine.distanceTo(ptNew); vtNew = ptNew - ptOnLine; if (!vtNew.isCodirectionalTo(Y)) dDist *= -1; m_ptEnd += Y * dDist; break; case 5: // 左侧范围左右移动 if (offset.isParallelTo(Y)) return; ptOnLine = lineLeft.closestPointTo(ptNew); dDist = ptOnLine.distanceTo(ptNew); vtNew = ptNew - ptOnLine; if (!vtNew.isCodirectionalTo(X)) dDist *= -1; m_ptStart += X * dDist; m_ptEnd += X * dDist; m_vtDir = m_vtDir.normal() * (m_vtDir.length() - dDist); break; case 6: // 移动中点, 负责平移 mat.setToTranslation(offset); m_ptStart.transformBy(mat); m_ptEnd.transformBy(mat); break; case 101: // 移动顶点 ptNew = arPts[idx]; ptNew.z = m_dMaxElev; ptNew += offset; m_dMaxElev = ptNew.z; if (m_dMinElev > m_dMaxElev) std::swap(m_dMinElev, m_dMaxElev); break; case 100: // 移动底点 ptNew = arPts[idx]; ptNew.z = m_dMinElev; ptNew += offset; m_dMinElev = ptNew.z; if (m_dMinElev > m_dMaxElev) std::swap(m_dMinElev, m_dMaxElev); break; default: break; } } void AecDbJoggedCamera::Camera::collectEntities(AcDbObjectIdArray & ar) { struct resbuf *typelist = AecDbXCamera::getSelectTypeResbuf(); struct resbuf *pointlist = acutBuildList(RTPOINT, m_ptStart, RTPOINT, m_ptEnd, RTPOINT, m_ptEnd + m_vtDir, RTPOINT, m_ptStart + m_vtDir, RTPOINT, m_ptStart, 0); AecDbXCamera::collectEnities(typelist, pointlist, ar); acutRelRb(pointlist); acutRelRb(typelist); } void AecDbJoggedCamera::Camera::moveOutput(const AcGeVector3d &vtOffset) { AcGeMatrix3d mat; mat.setToTranslation(vtOffset); for (int i(0); i < m_arResults.length(); ++i) { AcDbEntityPointer ent(m_arResults[i], AcDb::kForWrite); if (ent.openStatus() == Acad::eOk && !ent->isErased()) ent->transformBy(mat); } } void AecDbJoggedCamera::Camera::hlrCalc() { AecDbXCamera::eraseEnts(m_arResults); AcDbObjectIdArray ar; collectEntities(ar); if (ar.isEmpty()) return; AcDbPolyline *pSection(getSectionPolygon()); if (!pSection) return; AecDbXCamera::AcDbEntityArray entAxis; AecDbXCamera::IDMapEntities outputWithID; // 可以与数据库实体相关联的结果 AecDbXCamera::AcDbEntityArray outputWithoutID;// 不能与数据库实体相关联的结果 AecDbXCamera::hlrCalc(ar , getMidPoint() , m_vtDir , getXDir() , m_ptOutput , pSection , outputWithID , outputWithoutID , entAxis); DELETE_PTR(pSection); // 输出 AecDbXCamera::IDMapEntities::iterator it(outputWithID.begin()); AcDbObjectId id; for (; it != outputWithID.end(); ++it) { for (int i(0); i < it->second.length(); ++i) { AcDbEntity *pEnt(it->second[i]); if (!pEnt) continue; id = CoreTools::AddToModelSpace(pEnt); if (id.isValid()) m_arResults.append(id); else DELETE_PTR(pEnt); } } for (int i(0); i < outputWithoutID.length(); ++i) { AcDbEntity *pEnt(outputWithoutID[i]); if (!pEnt) continue; id = CoreTools::AddToModelSpace(pEnt); if (id.isValid()) m_arResults.append(id); else DELETE_PTR(pEnt); } } #pragma endregion #pragma region AecDbJoggedCamera ACRX_DXF_DEFINE_MEMBERS(AecDbJoggedCamera, AecDbEntityBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_JOGGEDCAMERA, "AecDbJoggedCamera" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") Adesk::UInt32 AecDbJoggedCamera::kCurrentVersionNumber = 2; Adesk::UInt32 AecDbJoggedCamera::Camera::kCurrentVersionNumber = 2; AecDbJoggedCamera::AecDbJoggedCamera(): m_bSameSectionDir(false), m_bForcedParallel(false) { m_bSameSectionDir = HlrCutOption::getHlrZX_SameDir() == FALSE ? false : true; m_bForcedParallel = HlrCutOption::getHlrZX_Parallel() == FALSE ? false : true; } AecDbJoggedCamera::AecDbJoggedCamera(AecDbJoggedCamera * pSrc) { copyFrom(pSrc); } AecDbJoggedCamera::~AecDbJoggedCamera() { deleteContainerOfArx(m_GripDatas); } AecDbObjXDataMap * AecDbJoggedCamera::GetSpecialtyData(AcDb::OpenMode bMode) { if (bMode == AcDb::kForWrite) AssertWriteEnabled(); else assertReadEnabled(); return &m_mapSpecXData; } const AecDbObjXDataMap * AecDbJoggedCamera::GetSpecialtyData() const { assertReadEnabled(); return &m_mapSpecXData; } void AecDbJoggedCamera::subList() const { assertReadEnabled(); AecDbEntityBase::subList(); m_mapSpecXData.List(); } Acad::ErrorStatus AecDbJoggedCamera::copyFrom(const AcRxObject * pSrc) { AssertWriteEnabled(); AecDbJoggedCamera *pCamera = AecDbJoggedCamera::cast(pSrc); if (pCamera == NULL) return Acad::eInvalidInput; m_mapSpecXData.CopyFrom(pCamera->GetSpecialtyData(AcDb::kForRead)); m_cameras = pCamera->m_cameras; m_ptOutput = pCamera->m_ptOutput; m_bSameSectionDir = pCamera->m_bSameSectionDir; m_bForcedParallel = pCamera->m_bForcedParallel; return Acad::eOk; } Acad::ErrorStatus AecDbJoggedCamera::subTransformBy(const AcGeMatrix3d & xform) { AssertWriteEnabled(); AecDbEntityBase::subTransformBy(xform); for (size_t i(0); i < m_cameras.size(); ++i) { Camera &cam = m_cameras[i]; cam.m_ptStart.transformBy(xform); cam.m_ptEnd.transformBy(xform); cam.m_vtDir.transformBy(xform); } // 剖切结果对齐点不移动 return Acad::eOk; } Acad::ErrorStatus AecDbJoggedCamera::subGetGripPoints(AcDbGripDataPtrArray & grips , const double curViewUnitSize , const int gripSize , const AcGeVector3d & curViewDir , const int bitflags) const { assertReadEnabled(); AcGeVector3d vtZ(curViewDir); bool bHori = vtZ.isParallelTo(AcGeVector3d::kZAxis) == Adesk::kFalse ? false : true; deleteContainerOfArx(m_GripDatas); getGripPoints(bHori, grips); getVirtualLine(bHori); return Acad::eOk; } Acad::ErrorStatus AecDbJoggedCamera::subMoveGripPointsAt(const AcDbVoidPtrArray & appData, const AcGeVector3d & offset, const int bitflags) { // 如果能进到这个函数,说明至少有一个Camera AssertWriteEnabled(); if (appData.isEmpty()) return Acad::eOk; GripData *pAppData = (GripData *)appData.first(); if (pAppData->m_idx == -1 && pAppData->m_subIdx == -1) { // 结果点 if (database()) moveOutput(offset); } else if ((pAppData->m_idx >= 0 && pAppData->m_idx < m_cameras.size())) { switch (pAppData->m_subIdx) { case 0: // 移动第一个点, 统一旋转 case 4: { AcGePoint3d ptNew = pAppData->m_pt + offset; AcGeVector3d vtOld = m_cameras.begin()->getJoggedDir(); AcGePoint3d ptOther; if (pAppData->m_subIdx == 0) { ptOther = m_cameras.begin()->getMidPoint(); vtOld *= -1; } else if (pAppData->m_subIdx == 4) { ptOther = m_cameras.rbegin()->getMidPoint(); } AcGeVector3d vtNew = ptNew - ptOther; double dA = vtOld.angleTo(vtNew, AcGeVector3d::kZAxis); AcGeMatrix3d mat(AcGeMatrix3d::rotation(dA, AcGeVector3d::kZAxis, ptOther)); for (size_t i(0); i < m_cameras.size(); ++i) m_cameras[i].transformBy(mat); break; } case 101: // 顶点 { for (size_t i(0); i < m_cameras.size(); ++i) m_cameras[i].moveGripPointsAt(101, offset); } break; case 100: // 底点 { for (size_t i(0); i < m_cameras.size(); ++i) m_cameras[i].moveGripPointsAt(100, offset); } break; default: { AcGeVector3d vtOld(m_cameras[pAppData->m_idx].m_vtDir); // 如果调整了1、6、3夹点,需要判断一下调整后的折线会不会和其他的相交 if (pAppData->m_subIdx == 1 || pAppData->m_subIdx == 3 || pAppData->m_subIdx == 6) { Camera cam = m_cameras[pAppData->m_idx]; cam.moveGripPointsAt(pAppData->m_subIdx, offset); AcGeLineSeg3d seg1(cam.m_ptStart, cam.m_ptEnd), seg2; for (size_t i(0); i < m_cameras.size(); ++i) { if (i == pAppData->m_idx) continue; seg2.set(m_cameras[i].m_ptStart, m_cameras[i].m_ptEnd); if (isRegionOverlapping(seg1, seg2)) return Acad::eInvalidInput; } m_cameras[pAppData->m_idx] = cam; if (pAppData->m_subIdx == 1 || pAppData->m_subIdx == 3) refreshOutputPoint(); } else { m_cameras[pAppData->m_idx].moveGripPointsAt(pAppData->m_subIdx, offset); } // 新需求,各个剖切线的方向不需要统一 // 一个折线改变了方向,其他一起改变 if (database() && !vtOld.isCodirectionalTo(m_cameras[pAppData->m_idx].m_vtDir) && m_bSameSectionDir) { for (size_t i(0); i < m_cameras.size(); ++i) { if (i == pAppData->m_idx) continue; m_cameras[i].m_vtDir *= -1; } refreshOutputPoint(); } } break; } } return Acad::eOk; } Acad::ErrorStatus AecDbJoggedCamera::dwgInFields(AcDbDwgFiler * pFiler) { AssertWriteEnabled(); //----- Read parent class information first. Acad::ErrorStatus es = Acad::eOk; if (!pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbEntityBase::dwgInFields(pFiler); if (es != Acad::eOk) return (es); } //----- Object version number needs to be read first Adesk::UInt32 version = 0; if ((es = pFiler->readUInt32(&version)) != Acad::eOk) return (es); if (version > AecDbJoggedCamera::kCurrentVersionNumber) return (Acad::eMakeMeProxy); m_mapSpecXData.dwgInFields(pFiler); pFiler->readPoint3d(&m_ptOutput); int countOfCameras(0); pFiler->readInt32((Adesk::Int32 *)&countOfCameras); m_cameras.resize(countOfCameras); for (size_t i(0); i < m_cameras.size(); ++i) { if (m_cameras[i].dwgInFields(pFiler) != Acad::eOk) return (es); } if (version > 1) { pFiler->readBool(&m_bSameSectionDir); pFiler->readBool(&m_bForcedParallel); } return (pFiler->filerStatus()); } Acad::ErrorStatus AecDbJoggedCamera::dwgOutFields(AcDbDwgFiler * pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = Acad::eOk; if (!pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbEntityBase::dwgOutFields(pFiler); if (es != Acad::eOk) return (es); } //----- Object version number needs to be saved first if ((es = pFiler->writeUInt32(AecDbJoggedCamera::kCurrentVersionNumber)) != Acad::eOk) return (es); m_mapSpecXData.dwgOutFields(pFiler); pFiler->writePoint3d(m_ptOutput); pFiler->writeInt32((Adesk::Int32)m_cameras.size()); for (size_t i(0); i < m_cameras.size(); ++i) { if (m_cameras[i].dwgOutFields(pFiler) != Acad::eOk) return (es); } pFiler->writeBool(m_bSameSectionDir); pFiler->writeBool(m_bForcedParallel); return (pFiler->filerStatus()); } Acad::ErrorStatus AecDbJoggedCamera::subGetGeomExtents(AcDbExtents & extents) const { for (size_t i(0); i < m_cameras.size(); ++i) { extents.addPoint(m_cameras[i].m_ptStart); extents.addPoint(m_cameras[i].m_ptEnd); } return Acad::eOk; } Acad::ErrorStatus AecDbJoggedCamera::subGetOsnapPoints(AcDb::OsnapMode osnapMode , INT_PTR gsSelectionMark , const AcGePoint3d & pickPoint , const AcGePoint3d & lastPoint , const AcGeMatrix3d & viewXform , AcGePoint3dArray & snapPoints , AcDbIntArray & geomIds) const { assertReadEnabled(); AcGePoint3dArray ar; for (size_t i(0); i < m_cameras.size(); ++i) { ar.removeAll(); m_cameras[i].getGripPoints(ar); if (!ar.isEmpty()) snapPoints.append(ar); } return Acad::eOk; } Acad::ErrorStatus AecDbJoggedCamera::Draw2d(AcGiDraw & dc) const { assertReadEnabled(); // 颜色随层 Adesk::UInt16 oldClr = dc.GetColor(); AcDbObjectId oldLinetype = dc.GetLineTypeId(); double oldLineWidth = dc.GetLineWidth(); AcDbObjectId lTContinuous = CoreTools::GetLTypeId(_T("Continuous")); AcDbObjectId lTCenter2 = CoreTools::GetLTypeId(_T("CENTER2")); if (!lTContinuous.isValid()) lTContinuous = oldLinetype; if (!lTCenter2.isValid()) lTCenter2 = lTContinuous; dc.SetColor(256); int iClr(0); // 绘制剖切线 AcGePoint3d pt1, pt2; for (size_t i(0); i < m_cameras.size(); ++i) { const Camera &cam = m_cameras[i]; pt1 = cam.m_ptStart; pt2 = cam.m_ptEnd; //pt1.z = pt2.z = (cam.m_ptStart.z + cam.m_ptEnd.z) * 0.5; pt1.z = pt2.z = cam.m_dMinElev; // 颜色随着索引变化, 方便在属性中对应修改 dc.SetColor(cam.m_iColor); dc.SetLineType(lTContinuous); dc.SetLineWidth(5.); dc.DrawLine(AcGeLineSeg3d(pt1, pt2)); DrawElev(dc, cam, cam.m_iColor); } dc.SetColor(9); for (size_t i(1); i < m_cameras.size(); ++i) { const Camera &cam0 = m_cameras[i-1]; const Camera &cam1 = m_cameras[i]; pt1 = cam0.m_ptEnd; pt2 = cam1.m_ptStart; pt1.z = cam0.m_dMinElev; pt2.z = cam1.m_dMinElev; dc.SetLineType(lTCenter2); dc.SetLineWidth(1.); dc.DrawLine(AcGeLineSeg3d(pt1, pt2)); } dc.SetColor(oldClr); dc.SetLineType(oldLinetype); dc.SetLineWidth(oldLineWidth); return Acad::eOk; } void AecDbJoggedCamera::DrawElev(AcGiDraw &dc, const Camera &cam, const int &iClr) const { assertReadEnabled(); int oldClr = dc.GetColor(); dc.SetColor(iClr); const AcGePoint3d &pt1 = cam.m_ptStart; const AcGePoint3d &pt2 = cam.m_ptEnd; double dH(pt1.distanceTo(pt2) * .025); AcGePoint3d ptIns = CoreTools::MidPt(pt1, pt2) - cam.m_vtDir.normal() * dH; AcGeVector3d X = (pt2 - pt1).normalize(); double dRotation = AcGeVector3d::kXAxis.angleTo(X, AcGeVector3d::kZAxis); CString sTop; int prec(0); sTop.Format(_T("%s , %s") , TypeConvert::d2s(cam.m_dMaxElev, &prec) , TypeConvert::d2s(cam.m_dMinElev, &prec)); AcDbText txt1; AcDbExtents ext; txt1.setTextString(sTop); txt1.setPosition(ptIns); txt1.setHeight(dH); txt1.getGeomExtents(ext); double dW = ext.maxPoint().x - ext.minPoint().x; ptIns -= X * (dW * .5); ptIns.z = cam.m_dMinElev; txt1.setPosition(ptIns); txt1.setRotation(dRotation); dc.DrawEntity(txt1); dc.SetColor(oldClr); } Acad::ErrorStatus AecDbJoggedCamera::Draw3d(AcGiDraw &dc) const { assertReadEnabled(); return Draw2d(dc); } void AecDbJoggedCamera::moveOutput(const AcGeVector3d & vtOffset) { assertWriteEnabled(); m_ptOutput += vtOffset; refreshOutputPoint(); for (size_t i(0); i < m_cameras.size(); ++i) m_cameras[i].moveOutput(vtOffset); } void AecDbJoggedCamera::getVirtualLine(const bool &bHori) const { assertReadEnabled(); // 第1个点作为绘制点,绘制虚框 GripData &first = *m_GripDatas.first(); first.m_mode = AecDbXCamera::eVerti; first.m_arSelectFrame.removeAll(); AcGePoint3d pt1, pt2, pt3, pt4; for (size_t i(0); i < m_cameras.size(); ++i) { const Camera &cam = m_cameras[i]; pt1 = cam.m_ptStart; pt2 = cam.m_ptStart + cam.m_vtDir; pt3 = cam.m_ptEnd + cam.m_vtDir; pt4 = cam.m_ptEnd; if (bHori) { pt1.z = pt2.z = pt3.z = pt4.z = .0; // 4个点为一组 first.m_arSelectFrame.append(pt1); first.m_arSelectFrame.append(pt2); first.m_arSelectFrame.append(pt3); first.m_arSelectFrame.append(pt4); } else { pt1.z = pt2.z = pt3.z = pt4.z = cam.m_dMinElev; // 4个点为一组,低点在前,高点在后 first.m_arSelectFrame.append(pt1); first.m_arSelectFrame.append(pt2); first.m_arSelectFrame.append(pt3); first.m_arSelectFrame.append(pt4); pt1.z = pt2.z = pt3.z = pt4.z = cam.m_dMaxElev; first.m_arSelectFrame.append(pt1); first.m_arSelectFrame.append(pt2); first.m_arSelectFrame.append(pt3); first.m_arSelectFrame.append(pt4); } } // 显示结果范围 AcGePoint3dArray ar; if (getResultBox(ar)) { GripData &first = *m_GripDatas.first(); first.m_bDrawResultFrame = true; first.m_arResultFrame.append(ar); } } bool AecDbJoggedCamera::getResultBox(AcGePoint3dArray &ar) const { assertReadEnabled(); AecDbXCamera::IDMapEntities result1; AecDbXCamera::EntMapEntities result2; AcGePoint3d pt; int numVerts; for (size_t i(0); i < m_cameras.size(); ++i) { const Camera *pCam(&m_cameras[i]); AcDbPolyline *pPoly(pCam->getSectionPolygon()); if (!pPoly) continue; AecDbXCamera::transfromHlrResult(pCam->getMidPoint() , pCam->m_vtDir , pCam->getXDir() , pCam->m_ptOutput , result1 , result2 , pPoly); numVerts = pPoly->numVerts(); if (numVerts < 4) { DELETE_PTR(pPoly); continue; } for (int j(0); j < 4; ++j) { pPoly->getPointAt(j, pt); ar.append(pt); } DELETE_PTR(pPoly); } return ar.length() >= 4; } void AecDbJoggedCamera::refreshOutputPoint() { // 不重新计算 assertReadEnabled(); if (m_cameras.empty()) return; // 得到 折线 排序的方向 "左" -> "右" // 各个折线的中点沿着 vtSort 排序, 得到在m_ptOutput点沿水平方向展开的顺序 std::vector cameras; for (size_t i(0); i < m_cameras.size(); ++i) cameras.push_back(&m_cameras[i]); std::sort(cameras.begin(), cameras.end(), sort_jogged(m_cameras.begin()->getXDir())); double dAllLen(.0); for (size_t i(0); i < m_cameras.size(); ++i) dAllLen += m_cameras[i].getJoggedLength(); AcGePoint3d ptS(m_ptOutput - AcGeVector3d::kXAxis * dAllLen * .5); AcGeVector3d vt; double dLen(.0); for (size_t i(0); i < cameras.size(); ++i) { vt = cameras[i]->getJoggedLength() * .5 * AcGeVector3d::kXAxis; cameras[i]->m_ptOutput = ptS + vt; ptS += 2 * vt; } } void AecDbJoggedCamera::getGripPoints(const bool &bHori, AcDbGripDataPtrArray &grips) const { assertReadEnabled(); if (m_cameras.empty()) return; if (bHori) { // 第一段起点,和第二段终点,其他段的中点 addGripData(0, 0, m_cameras.begin()->m_ptStart, m_GripDatas, grips); int idx3(0);//上一个camera的第3个点的索引 AcGePoint3dArray pts; double dOnePixel = CoreTools::PixelToWcs(1); for (size_t i(0); i < m_cameras.size(); ++i) { const Camera &cam = m_cameras[i]; pts.removeAll(); cam.getGripPoints(pts); // 共6个点 if (pts.length() < 7) continue; // 每个camera的第pts[1]点可能和上一个camera的第pts[3]点重合 // 此时,应该把当前camera的第二个点向折线绘制方向移动一个夹点的距离 // 没插入pts[1]之前,m_GripDatas的最后一个点是上个camera的第pts[6]点 // 那么再上2个点就是需要比较的第pts[3]点 // 得到上个camera的第6个点 idx3 = m_GripDatas.length() - 3; // 重合,移动一下pts[1],然后插入ar if (idx3 > 0 && COMPARE_DOUBLE::equal_zero(m_GripDatas[idx3]->m_pt.distanceTo(pts[1]))) pts[1] += (cam.getJoggedDir()).normal() * PIXEL_SIZE * dOnePixel; addGripData((int)i, 1, pts[1], m_GripDatas, grips); addGripData((int)i, 2, pts[2], m_GripDatas, grips); addGripData((int)i, 3, pts[3], m_GripDatas, grips); addGripData((int)i, 5, pts[5], m_GripDatas, grips); addGripData((int)i, 6, pts[6], m_GripDatas, grips); } addGripData((int)(m_cameras.size() - 1), 4, m_cameras.rbegin()->m_ptEnd, m_GripDatas, grips); } else { // 每段上中点和下中点,序号从100开始 // 改为只显示一个,用来统一修改标高 AcGePoint3d pt; if (!m_cameras.empty()) { const Camera &cam = *m_cameras.begin(); pt = CoreTools::MidPt(cam.m_ptStart, cam.m_ptEnd); pt.z = cam.m_dMinElev; addGripData((int)0, 100 + 0, pt, m_GripDatas, grips); pt.z = cam.m_dMaxElev; // 如果m_dMinElev == m_dMaxElev,说明没有高度差 // 上中点需要向上移动一个夹点的距离,避免和下中点重合 if (cam.m_dMinElev == cam.m_dMaxElev) pt.z += PIXEL_SIZE * CoreTools::PixelToWcs(1); addGripData((int)0, 100 + 1, pt, m_GripDatas, grips); } } // 对齐点在最后一个 addGripData(-1, -1, m_ptOutput, m_GripDatas, grips); } AcGePoint3d AecDbJoggedCamera::getLastPoint() const { assertReadEnabled(); if (m_cameras.empty()) return AcGePoint3d::kOrigin; return m_cameras.rbegin()->m_ptEnd; } AcGeVector3d AecDbJoggedCamera::getJoggedDir() const { assertReadEnabled(); AcGeVector3d vt(AcGeVector3d::kIdentity); if (m_cameras.empty()) return vt; return m_cameras[0].getJoggedDir(); } AcGeVector3d AecDbJoggedCamera::getSectionDir() const { assertReadEnabled(); AcGeVector3d vt(AcGeVector3d::kIdentity); if (m_cameras.empty()) return vt; return m_cameras[0].m_vtDir; } void AecDbJoggedCamera::delCamera(const int & idx) { AssertWriteEnabled(); if (idx < 0 || idx >= m_cameras.size()) return; Cameras::iterator it(m_cameras.begin()); std::advance(it, idx); m_cameras.erase(it); } const AecDbJoggedCamera::Camera* AecDbJoggedCamera::getCamera(const int & idx) const { assertReadEnabled(); if (idx < 0 || idx >= m_cameras.size()) return NULL; return &m_cameras[idx]; } void AecDbJoggedCamera::setCameraHeight(const int & idx, const double & dMax, const double & dMin) { AssertWriteEnabled(); if (idx < 0 || idx >= m_cameras.size()) return; Camera &cam(m_cameras[idx]); if (COMPARE_DOUBLE::equal(dMax, dMin)) { cam.setElev(1000., 0.); return; } cam.setElev(dMax, dMin); if (cam.m_dMaxElev < cam.m_dMinElev) std::swap(cam.m_dMaxElev, cam.m_dMinElev); } void AecDbJoggedCamera::setCameraWidth(const int & idx, const AcGePoint3d &ptOut) { AssertWriteEnabled(); if (idx < 0 || idx >= m_cameras.size()) return; Camera &cam(m_cameras[idx]); AcGePoint3d ptOn = getClosestPoint(cam.m_ptStart, cam.m_ptEnd, ptOut); double dist(ptOn.distanceTo(ptOut)); if (COMPARE_DOUBLE::equal_zero(dist)) dist = 1000.; else { if (!(ptOut - ptOn).isCodirectionalTo(cam.m_vtDir)) dist *= -1; } cam.m_vtDir.normalize(); cam.m_vtDir *= dist; // 如果不是第一段折线,那么其他的剖切方向都要和第一段一致 if (idx != 0 && !cam.m_vtDir.isCodirectionalTo(m_cameras.begin()->m_vtDir)) cam.m_vtDir *= -1; } bool AecDbJoggedCamera::isOverlappingCamera(const int & idx) const { assertReadEnabled(); return false; } AcGePoint3d AecDbJoggedCamera::getClosestPoint(const AcGePoint3d & ptOn1, const AcGePoint3d & ptOn2, const AcGePoint3d & ptOut) { AcGeLine3d line(ptOn1, ptOn2); return line.closestPointTo(ptOut); } AcGePoint3d AecDbJoggedCamera::getClosestPoint(const AcGePoint3d & ptOn, const AcGeVector3d & vt, const AcGePoint3d & ptOut) { AcGeLine3d line(ptOn, vt); return line.closestPointTo(ptOut); } void AecDbJoggedCamera::setOutputPoint(const AcGePoint3d & pt) { moveOutput(pt - m_ptOutput); } bool AecDbJoggedCamera::judgeSegmentCanInsert(const AcGePoint3d &pt1, const AcGePoint3d &pt2, AcGePoint3d &ptClosed) const { // 这些子折线,都互相平行, // 可以共线,不能重合 // 也就是说,这些Camera的m_vtDir方向都相同 if (m_cameras.empty()) return true; const Camera LastCam = *m_cameras.rbegin(); AcGeVector3d vtDir(LastCam.getJoggedDir()); // 检查第1个点 if (!checkPoint(LastCam.m_ptEnd, vtDir, pt1, ptClosed, true)) return false; // 检查第2个点 if (!checkPoint(pt1, vtDir, pt2, ptClosed, false)) return false; return true; } bool AecDbJoggedCamera::addCamera(const AcGePoint3d &_pt1 , const AcGePoint3d &_pt2 , const AcGeVector3d &vt) { AssertWriteEnabled(); if (m_cameras.empty()) { m_cameras.push_back(Camera(_pt1, _pt2)); m_cameras.rbegin()->m_vtDir = vt; m_cameras.rbegin()->m_iColor = 1; return true; } AcGePoint3d ptClosed; if (!judgeSegmentCanInsert(_pt1, _pt2, ptClosed)) return false; Camera &lastCam = m_cameras.back(); // 通过judgeSegmentCanInsert检查后,如果pt1-pt2的方向与 // 其他Camera的m_ptStart-m_ptEnd方向不一致,改变方向即可插入 AcGePoint3d pt1 = _pt1, pt2 = _pt2; if (!lastCam.getJoggedDir().isCodirectionalTo(pt2 - pt1)) std::swap(pt1, pt2); // 以上条件都满足,不需要判断方向,使用统一的方向,但要得到矢量的长度 m_cameras.push_back(Camera(pt1, pt2)); // 方向改为任意,不需要统一 //m_cameras.rbegin()->m_vtDir = m_cameras.begin()->m_vtDir.normal() * vt.length(); m_cameras.rbegin()->m_vtDir = vt; // 根据索引设置颜色 if (lastCam.m_iColor == 8) m_cameras.rbegin()->m_iColor = 10; // 颜色9保留 else m_cameras.rbegin()->m_iColor = lastCam.m_iColor + 1; return true; } bool AecDbJoggedCamera::GetProperties(SimpleProperty::PropertySetByIndex & properties) const { assertReadEnabled(); CString sIndex; // 上下标高永远用第一段剖切线的 if (m_cameras.empty()) return false; const Camera &cam = *m_cameras.begin(); SimpleProperty::makeAndInsert(properties, _T("剖切范围上标高"), cam.m_dMaxElev, true); SimpleProperty::makeAndInsert(properties, _T("剖切范围下标高"), cam.m_dMinElev, true); for (size_t i(0); i < m_cameras.size(); ++i) { const Camera &cam = m_cameras[i]; sIndex.Format(_T("折线%d-剖切宽度"), i + 1); SimpleProperty::makeAndInsert(properties, sIndex, cam.m_vtDir.length(), true, cam.m_iColor); } return true; } bool AecDbJoggedCamera::SetProperties(SimpleProperty::PropertySetByName & properties) { AssertWriteEnabled(); // 处理 上下标高 if (m_cameras.empty()) return false; // 按照原始值初始化,哪怕界面上没有修改数值,也能保证数据的正确性 double dMax(m_cameras.begin()->m_dMaxElev), dMin(m_cameras.begin()->m_dMinElev); properties.findAndSet(_T("剖切范围上标高"), dMax); properties.findAndSet(_T("剖切范围下标高"), dMin); if (dMax < dMin) { // 交换 std::swap(dMax, dMin); } double dVal; CString sPropertyName(_T("")); for (size_t i(0); i < m_cameras.size(); ++i) { sPropertyName.Format(_T("折线%d-剖切宽度"), i + 1); if (properties.findAndSet(sPropertyName, dVal)) { if (dVal < 10.) { acutPrintf(_T("\n剖切宽度不能小于10,已自动调整为10。")); dVal = 10.; } m_cameras[i].m_vtDir = m_cameras[i].m_vtDir.normal() * dVal; } m_cameras[i].m_dMaxElev = dMax; m_cameras[i].m_dMinElev = dMin; } return true; } void AecDbJoggedCamera::refresh() { for (size_t i(0); i < m_cameras.size(); ++i) { m_cameras[i].hlrCalc(); } } #pragma endregion #pragma region JoggedJig AcEdJig::DragStatus CJoggedCameraJig::DoIt() { m_pPolyline = new AcDbPolyline(); m_pPolyline->setNormal(AcGeVector3d::kZAxis); m_pPolyline->setElevation(.0); AcEdJig::DragStatus stat; AcGePoint3d ptClosest; AcDbObjectId subid; while (true) { setDispPrompt(_T("\n选取第%d段剖切线的起点:"), m_numOfSeg + 1); stat = drag(); if (stat == AcEdJig::kNull || stat == AcEdJig::kCancel) { deleteSupportLine(); return stat; } if (m_pJogged->getCameraCount() == 0) { ++m_nStep; break; } else { if (m_pJogged->judgeSegmentCanInsert(m_ptStart, m_ptStart + m_pJogged->getJoggedDir().normal() * 10, ptClosest)) { ++m_nStep; deleteSupportLine(); AcDbLine *pLine = new AcDbLine(m_ptStart, m_pJogged->getLastPoint()); pLine->setColorIndex(9); m_supportLineID = CoreTools::AddToModelSpace(pLine, true); break; } acutPrintf(_T("\n剖切线的起点不能和已有的剖切线区域重叠,请重新拾取!")); } } while (true) { setDispPrompt(_T("\n选取第%d段剖切线的终点:"), m_numOfSeg + 1); stat = drag(); if (stat == AcEdJig::kNull || stat == AcEdJig::kCancel) { deleteSupportLine(); return stat; } if (m_pJogged->getCameraCount() == 0) { ++m_nStep; break; } else { if (m_pJogged->judgeSegmentCanInsert(m_ptStart, m_ptEnd, ptClosest)) { if (m_pJogged->isForcedParallel()) m_ptEnd = ptClosest; ++m_nStep; break; } acutPrintf(_T("\n剖切线的终点必须在上个剖切线终点和当前剖切线起点的延长线上,请重新拾取!")); } } setDispPrompt(_T("\n选取第%d段剖切线的方向和范围:"), m_numOfSeg + 1); stat = drag(); deleteSupportLine(); if (stat == AcEdJig::kNull || stat == AcEdJig::kCancel) return stat; ++m_nStep; return stat; } AcEdJig::DragStatus CJoggedCameraJig::sampler() { AcEdJig::DragStatus stat; setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted )); m_pPolyline->reset(false, 0); if (m_nStep == 0) { if (m_numOfSeg != 0) { static AcGePoint3d pt0; AcGePoint3d ptPrev(m_pJogged->getLastPoint()); stat = acquirePoint(m_ptStart, ptPrev); if (m_ptStart != pt0) pt0 = m_ptStart; else if (stat == AcEdJig::kNormal) return AcEdJig::kNoChange; } else stat = acquirePoint(m_ptStart); } else if (m_nStep == 1) { static AcGePoint3d pt1; stat = acquirePoint(m_ptEnd, m_ptStart); // 当shfit按下时,或者"强制平行"被设置时 bool bShiftPressed = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0 || m_pJogged->isForcedParallel(); if (m_ptEnd != pt1) pt1 = m_ptEnd; else if (stat == AcEdJig::kNormal) return AcEdJig::kNoChange; if (m_ptEnd.isEqualTo(m_ptStart)) return AcEdJig::kNoChange; if (bShiftPressed && m_numOfSeg != 0) { AcGeVector3d vt = m_pJogged->getJoggedDir(); AcGeLine3d ln(m_ptStart, vt.normal()); m_ptEnd = ln.closestPointTo(m_ptEnd); } } else { double dDist(.0); AcGePoint3d ptMid(CoreTools::MidPt(m_ptStart, m_ptEnd)); if (m_numOfSeg == 0 || !m_pJogged->isSameSectionDir()) { static AcGePoint3d pt2; AcGePoint3d ptDir; stat = acquirePoint(ptDir, ptMid); if (ptDir != pt2) pt2 = ptDir; else if (stat == AcEdJig::kNormal) return AcEdJig::kNoChange; AcGeLine3d line(m_ptStart, m_ptEnd); AcGePoint3d ptOnLine(line.closestPointTo(ptDir)); dDist = ptOnLine.distanceTo(ptDir); m_vtEye = ptDir - ptOnLine; } else { stat = acquireDist(dDist, ptMid); m_vtEye = m_vtEye.normal() * dDist; } } return stat; } AcDbEntity *CJoggedCameraJig::entity() const { return m_pPolyline; } Adesk::Boolean CJoggedCameraJig::update() { double dw = CoreTools::PixelToWcs(10); switch (m_nStep) { case 0: break; case 1: { m_pPolyline->addVertexAt(0, m_ptStart.convert2d(AcGePlane::kXYPlane), .0, dw, dw); m_pPolyline->addVertexAt(1, m_ptEnd.convert2d(AcGePlane::kXYPlane)); } break; case 2: { AcGePoint3d ptCloset; m_pPolyline->addVertexAt(0, m_ptStart.convert2d(AcGePlane::kXYPlane), .0, dw, dw); m_pPolyline->addVertexAt(1, m_ptEnd.convert2d(AcGePlane::kXYPlane)); m_pPolyline->addVertexAt(2, (m_ptEnd + m_vtEye).convert2d(AcGePlane::kXYPlane)); m_pPolyline->addVertexAt(3, (m_ptStart + m_vtEye).convert2d(AcGePlane::kXYPlane)); m_pPolyline->setClosed(Adesk::kTrue); } break; case 3: break; default: break; } return Adesk::kTrue; } void CJoggedCameraJig::deleteSupportLine() { AcDbEntityPointer entLine(m_supportLineID, AcDb::kForWrite); if (entLine.openStatus() == Acad::eOk) entLine->erase(); } #pragma endregion