1686 lines
42 KiB
C++
1686 lines
42 KiB
C++
#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<AecDbXCamera::GripData *> &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<GripData>(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<GripData>(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<Camera*> 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
|