2773 lines
69 KiB
C++
2773 lines
69 KiB
C++
#include "stdafx.h"
|
|
#include "AcGiViewDraw.h"
|
|
#include "AecDbCamera.h"
|
|
#include "dbgrip.h"
|
|
#include "MFCDbDwgFiler.h"
|
|
#include "CoreTools.h"
|
|
#include "HlrCutOption.h"
|
|
#include "aecdbewpipebase.h"
|
|
#include "compare_double.h"
|
|
#include "simpleproperty.h"
|
|
#include "hlrcommands.h"
|
|
|
|
IMP_XDATA_KEY(AecDbXCamera, _ptEye_);
|
|
IMP_XDATA_KEY(AecDbXCamera, _vtEye_);
|
|
IMP_XDATA_KEY(AecDbXCamera, _width_);
|
|
IMP_XDATA_KEY(AecDbXCamera, _height_);
|
|
IMP_XDATA_KEY(AecDbXCamera, _ptOutput_);
|
|
IMP_XDATA_KEY(AecDbXCamera, _horiztop_);
|
|
IMP_XDATA_KEY(AecDbXCamera, _horizbottom_);
|
|
IMP_XDATA_KEY(AecDbXCamera, _usagemode_);
|
|
|
|
typedef AecDbXCamera::AcDbEntityArray AcDbEntityArray;
|
|
typedef AecDbXCamera::IDMapEntities IDMapEntities;
|
|
typedef AecDbXCamera::EntMapEntities EntMapEntities;
|
|
|
|
namespace
|
|
{
|
|
// 从母实体上拷贝属性
|
|
void copyProperty(AcDbEntity *pSrc, AcDbEntity *pDes)
|
|
{
|
|
pDes->setLayer(pSrc->layerId());
|
|
pDes->setLinetype(pSrc->linetypeId());
|
|
pDes->setColorIndex(pSrc->colorIndex());
|
|
|
|
AecDbObjXDataMap xdata;
|
|
if (xdata.Read(pSrc, BIMDATA_APP))
|
|
xdata.Write(pDes, BIMDATA_APP);
|
|
|
|
AcDbPolyline *pPlSrc(AcDbPolyline::cast(pSrc)), *pPlDes(AcDbPolyline::cast(pDes));
|
|
if (pPlSrc && pPlDes)
|
|
{
|
|
double dW;
|
|
if (pPlSrc->getConstantWidth(dW) == Acad::eOk)
|
|
pPlDes->setConstantWidth(dW);
|
|
}
|
|
}
|
|
|
|
// 辅助函数:使用射线法判断一个点是否在闭合曲线上
|
|
bool IsPointInsideBoundary(AcDbCurve *pBoundary, const AcGePoint3d &testPt)
|
|
{
|
|
if (pBoundary == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 1. 优先判定:点是否在边界曲线上
|
|
AcGePoint3d closestPt;
|
|
if (pBoundary->getClosestPointTo(testPt, closestPt) == Acad::eOk)
|
|
{
|
|
// 如果测试点到边界最近点的距离小于容差,认为点在边界上
|
|
if (testPt.distanceTo(closestPt) < 1e-6)
|
|
{
|
|
return true; // 视为在内部,予以保留
|
|
}
|
|
}
|
|
|
|
// 2. 获取边界的外包围盒,用于快速排除并构建射线长度
|
|
AcDbExtents extents;
|
|
if (pBoundary->getGeomExtents(extents) != Acad::eOk)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 粗略判断:如果点在外包围盒之外,肯定在外部
|
|
if (testPt.x < extents.minPoint().x || testPt.x > extents.maxPoint().x ||
|
|
testPt.y < extents.minPoint().y || testPt.y > extents.maxPoint().y)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 3. 构造一条射线,从测试点射向包围盒外的一个极远点
|
|
// 使用非标准角度的向量,尽量避免穿过顶点或与边重合
|
|
AcGeVector3d rayDir(1.0, 0.314159, 0.0);
|
|
double dist = extents.maxPoint().distanceTo(extents.minPoint()) * 2.0;
|
|
AcGePoint3d farPt = testPt + rayDir * dist;
|
|
|
|
AcDbLine rayLine(testPt, farPt);
|
|
AcGePoint3dArray intPts;
|
|
|
|
// 4. 求交
|
|
if (pBoundary->intersectWith(&rayLine, AcDb::kOnBothOperands, intPts) != Acad::eOk)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 5. 过滤重复交点 (容差处理,防止同一个交点被重复计算)
|
|
int validIntersectionCount = 0;
|
|
for (int i = 0; i < intPts.length(); ++i)
|
|
{
|
|
bool isDuplicate = false;
|
|
for (int j = 0; j < i; ++j)
|
|
{
|
|
if (intPts[i].distanceTo(intPts[j]) < 1e-6)
|
|
{
|
|
isDuplicate = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isDuplicate)
|
|
{
|
|
validIntersectionCount++;
|
|
}
|
|
}
|
|
|
|
// 6. 射线法核心:交点个数为奇数则在内部,偶数则在外部
|
|
return (validIntersectionCount % 2) != 0;
|
|
}
|
|
|
|
// 辅助函数 2:曲线内外判定
|
|
bool IsCurveInsideBoundary(AcDbCurve *pBoundary, AcDbCurve *pCurve)
|
|
{
|
|
if (!pBoundary || !pCurve) return false;
|
|
|
|
double startParam(.0), endParam(.0);
|
|
AcGePoint3d midPt;
|
|
|
|
if (pCurve->getStartParam(startParam) == Acad::eOk &&
|
|
pCurve->getEndParam(endParam) == Acad::eOk &&
|
|
pCurve->getPointAtParam((startParam + endParam) * 0.5, midPt) == Acad::eOk)
|
|
{
|
|
return IsPointInsideBoundary(pBoundary, midPt);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 辅助函数 3:按需克隆
|
|
void CloneIfInside(AcDbCurve *pBoundary, AcDbCurve *pTarget, AcDbEntityArray &output)
|
|
{
|
|
if (IsCurveInsideBoundary(pBoundary, pTarget))
|
|
{
|
|
AcDbEntity *pClone = static_cast<AcDbEntity *>(pTarget->clone());
|
|
if (pClone)
|
|
{
|
|
copyProperty(pTarget, pClone);
|
|
output.append(pClone);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 主控裁剪函数
|
|
void ClipCurvesByBoundary(AcDbCurve *pBoundary, const AcDbEntityArray &ptrs, AcDbEntityArray &output)
|
|
{
|
|
if (!pBoundary) return;
|
|
if (ptrs.isEmpty()) return;
|
|
|
|
double param(.0);
|
|
AcGePoint3d projPt(AcGePoint3d::kOrigin);
|
|
AcGePoint3dArray intPts;
|
|
AcGeDoubleArray splitParams;
|
|
std::vector<double> vecParams;
|
|
AcDbVoidPtrArray curveFragments;
|
|
|
|
for (int i = 0; i < ptrs.length(); ++i)
|
|
{
|
|
AcDbCurve *pTargetCurve = AcDbCurve::cast(ptrs[i]);
|
|
if (!pTargetCurve) continue;
|
|
|
|
intPts.removeAll();
|
|
// 1. 获取交点
|
|
if (pTargetCurve->intersectWith(pBoundary, AcDb::kOnBothOperands, intPts) != Acad::eOk) continue;
|
|
|
|
// 2. 无交点处理
|
|
if (intPts.length() < 1)
|
|
{
|
|
CloneIfInside(pBoundary, pTargetCurve, output);
|
|
continue;
|
|
}
|
|
|
|
splitParams.removeAll();
|
|
vecParams.clear();
|
|
|
|
// 3. 交点转参数
|
|
for (int j = 0; j < intPts.length(); ++j)
|
|
{
|
|
if (pTargetCurve->getClosestPointTo(intPts[j], projPt) != Acad::eOk) continue;
|
|
if (pTargetCurve->getParamAtPoint(projPt, param) != Acad::eOk) continue;
|
|
vecParams.push_back(param);
|
|
}
|
|
|
|
// 4. 参数排序去重与容错
|
|
if (vecParams.empty())
|
|
{
|
|
CloneIfInside(pBoundary, pTargetCurve, output);
|
|
continue;
|
|
}
|
|
|
|
std::sort(vecParams.begin(), vecParams.end());
|
|
vecParams.erase(std::unique(vecParams.begin(), vecParams.end()), vecParams.end());
|
|
|
|
for (size_t k = 0; k < vecParams.size(); ++k)
|
|
{
|
|
splitParams.append(vecParams[k]);
|
|
}
|
|
|
|
// 5. 打断曲线与容错
|
|
curveFragments.removeAll();
|
|
if (pTargetCurve->getSplitCurves(splitParams, curveFragments) != Acad::eOk)
|
|
{
|
|
CloneIfInside(pBoundary, pTargetCurve, output);
|
|
continue;
|
|
}
|
|
|
|
// 6. 遍历碎片(经过重构,这里现在犹如散文般清晰)
|
|
for (int f = 0; f < curveFragments.length(); ++f)
|
|
{
|
|
AcDbCurve *pFragment = AcDbCurve::cast((AcDbEntity *)curveFragments[f]);
|
|
if (!pFragment) continue;
|
|
|
|
// 直接复用逻辑判定
|
|
if (IsCurveInsideBoundary(pBoundary, pFragment))
|
|
{
|
|
// 内部保留,转移控制权
|
|
copyProperty(pTargetCurve, pFragment);
|
|
output.append(pFragment);
|
|
}
|
|
else
|
|
{
|
|
// 外部剔除,或底层参数异常,统一就地销毁
|
|
delete pFragment;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void clipResultBySection(IDMapEntities &result, EntMapEntities &result2, AcDbCurve *pSection)
|
|
{
|
|
if (!pSection) return;
|
|
|
|
AcDbEntityArray output;
|
|
IDMapEntities::iterator it(result.begin());
|
|
for (; it != result.end(); ++it)
|
|
{
|
|
// output的内容会转移到it->second内,
|
|
// 会在外部清理,这里removeall即可
|
|
output.removeAll();
|
|
// 取出每个id关联的结果,和pSection进行clip运算
|
|
ClipCurvesByBoundary(pSection, it->second, output);
|
|
|
|
// 清理 it->second 的内容,置换为 output
|
|
deleteContainerOfArx<AcDbEntity>(it->second);
|
|
if (!output.isEmpty())
|
|
it->second.append(output);
|
|
}
|
|
|
|
EntMapEntities::iterator it2(result2.begin());
|
|
for (; it2 != result2.end(); ++it2)
|
|
{
|
|
output.removeAll();
|
|
ClipCurvesByBoundary(pSection, it2->second, output);
|
|
|
|
deleteContainerOfArx<AcDbEntity>(it2->second);
|
|
if (!output.isEmpty())
|
|
it2->second.append(output);
|
|
}
|
|
}
|
|
|
|
|
|
// 删除一个实体,如果是块引用,则尽量删除其块
|
|
void eraseEnt(AcDbObjectId &id, Adesk::Boolean erasing = Adesk::kTrue)
|
|
{
|
|
AcDbObjectPointer<AcDbBlockReference> entRef(id, AcDb::kForWrite);
|
|
if (entRef.openStatus() == Acad::eOk)
|
|
{
|
|
AcDbObjectId idBlk = entRef->blockTableRecord();
|
|
if (entRef->erase(erasing) == Acad::eOk)
|
|
{
|
|
AcDbBlockTableRecordPointer entTblRec(idBlk, AcDb::kForWrite);
|
|
if (entTblRec.openStatus() == Acad::eOk)
|
|
{
|
|
AcDbObjectIdArray ar;
|
|
entTblRec->getBlockReferenceIds(ar);
|
|
if (ar.isEmpty())
|
|
entTblRec->erase(erasing);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AcDbEntityPointer ent(id, AcDb::kForWrite);
|
|
if (ent.openStatus() == Acad::eOk)
|
|
ent->erase(erasing);
|
|
}
|
|
}
|
|
|
|
AcGeVector3d getViewDir()
|
|
{
|
|
AcGePoint3dArray pts;
|
|
struct resbuf rb;
|
|
acedGetVar(_T("viewdir"), &rb);
|
|
ads_point dirPt;
|
|
acdbUcs2Wcs(rb.resval.rpoint, dirPt, Adesk::kTrue);
|
|
return asVec3d(dirPt);
|
|
}
|
|
|
|
bool Grip_WorldDrawfunc(AcDbGripData *pThis,
|
|
AcGiWorldDraw *pWd,
|
|
const AcDbObjectId &entId,
|
|
AcDbGripOperations::DrawType type,
|
|
AcGePoint3d *cursor,
|
|
double dGripSize)
|
|
{
|
|
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 -= 4 * dOne;
|
|
ptGe[1] = ptGrip;
|
|
ptGe[1].x += 4 * dOne;
|
|
|
|
ptBox[0] = ptGe[0];
|
|
ptBox[0].y -= 4 * dOne;
|
|
ptBox[1] = ptGe[0];
|
|
ptBox[1].y += 4 * dOne;
|
|
ptBox[2] = ptGe[1];
|
|
ptBox[2].y += 4 * dOne;
|
|
ptBox[3] = ptGe[1];
|
|
ptBox[3].y -= 4 * dOne;
|
|
|
|
AcGeVector3d vtNow(getViewDir());
|
|
if (!vtNow.isCodirectionalTo(AcGeVector3d::kZAxis))
|
|
{
|
|
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);
|
|
|
|
// 有frame数据就画线
|
|
if (pGrip->m_mode == AecDbXCamera::eVerti && pGrip->m_arSelectFrame.length() > 3)
|
|
{
|
|
AcGePoint3d arFrame1[] = { pGrip->m_arSelectFrame[1]
|
|
, pGrip->m_arSelectFrame[2]
|
|
, pGrip->m_arSelectFrame[3]
|
|
, pGrip->m_arSelectFrame[0] };
|
|
pWd->subEntityTraits().setColor(9);
|
|
pWd->geometry().polyline(4, arFrame1);
|
|
|
|
if (pGrip->m_arSelectFrame.length() > 7)
|
|
{
|
|
// 画下层线
|
|
AcGePoint3d arFrame2[] = { pGrip->m_arSelectFrame[4]
|
|
, pGrip->m_arSelectFrame[5]
|
|
, pGrip->m_arSelectFrame[6]
|
|
, pGrip->m_arSelectFrame[7]
|
|
, pGrip->m_arSelectFrame[4] };
|
|
pWd->geometry().polyline(5, arFrame2);
|
|
|
|
AcGePoint3d arFrame3[2] = { pGrip->m_arSelectFrame[0], pGrip->m_arSelectFrame[4] };
|
|
pWd->geometry().polyline(2, arFrame3);
|
|
|
|
arFrame3[0] = pGrip->m_arSelectFrame[1];
|
|
arFrame3[1] = pGrip->m_arSelectFrame[5];
|
|
pWd->geometry().polyline(2, arFrame3);
|
|
|
|
arFrame3[0] = pGrip->m_arSelectFrame[2];
|
|
arFrame3[1] = pGrip->m_arSelectFrame[6];
|
|
pWd->geometry().polyline(2, arFrame3);
|
|
|
|
arFrame3[0] = pGrip->m_arSelectFrame[3];
|
|
arFrame3[1] = pGrip->m_arSelectFrame[7];
|
|
pWd->geometry().polyline(2, arFrame3);
|
|
}
|
|
pWd->subEntityTraits().setColor(nOldColor);
|
|
}
|
|
else if (pGrip->m_mode == AecDbXCamera::eHoriz && pGrip->m_arSelectFrame.length() > 7)
|
|
{
|
|
pWd->subEntityTraits().setColor(9);
|
|
AcGePoint3d ar[] = { pGrip->m_arSelectFrame[5]
|
|
, pGrip->m_arSelectFrame[6]
|
|
, pGrip->m_arSelectFrame[7]
|
|
, pGrip->m_arSelectFrame[4]
|
|
, pGrip->m_arSelectFrame[5] };
|
|
pWd->geometry().polyline(5, ar);
|
|
|
|
AcGePoint3d arFrame[2] = { pGrip->m_arSelectFrame[1], pGrip->m_arSelectFrame[5] };
|
|
pWd->geometry().polyline(2, arFrame);
|
|
|
|
arFrame[0] = pGrip->m_arSelectFrame[0];
|
|
arFrame[1] = pGrip->m_arSelectFrame[4];
|
|
pWd->geometry().polyline(2, arFrame);
|
|
|
|
arFrame[0] = pGrip->m_arSelectFrame[2];
|
|
arFrame[1] = pGrip->m_arSelectFrame[6];
|
|
pWd->geometry().polyline(2, arFrame);
|
|
|
|
arFrame[0] = pGrip->m_arSelectFrame[3];
|
|
arFrame[1] = pGrip->m_arSelectFrame[7];
|
|
pWd->geometry().polyline(2, arFrame);
|
|
|
|
pWd->subEntityTraits().setColor(nOldColor);
|
|
}
|
|
|
|
if (pGrip->m_bDrawResultFrame)
|
|
{
|
|
AcGePoint3d arFrame[] = { pGrip->m_arResultFrame[1]
|
|
, pGrip->m_arResultFrame[2]
|
|
, pGrip->m_arResultFrame[3]
|
|
, pGrip->m_arResultFrame[0]
|
|
, pGrip->m_arResultFrame[1] };
|
|
pWd->subEntityTraits().setColor(6);
|
|
pWd->geometry().polyline(5, arFrame);
|
|
pWd->subEntityTraits().setColor(nOldColor);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
AcDbViewport *makeViewPort(const AcGePoint3d &ptVp // 视口起始点
|
|
, const AcGeVector3d &vtVp) // 视口方向和长度
|
|
{
|
|
AcDbViewport *pVp = new AcDbViewport;
|
|
pVp->setViewTarget(ptVp - vtVp);
|
|
pVp->setViewDirection(vtVp);
|
|
pVp->setFrontClipDistance(vtVp.length());
|
|
pVp->setBackClipDistance(0);
|
|
pVp->setFrontClipOn();
|
|
pVp->setBackClipOn();
|
|
return pVp;
|
|
}
|
|
|
|
//HINSTANCE _getHLRInstance()
|
|
//{
|
|
// DWORD dRes = 0;
|
|
// CString sSHHLrDll, sDbx;
|
|
// if (!CoreTools::FindSHHLrDll(sSHHLrDll, sDbx))
|
|
// {
|
|
// acutPrintf(_T("\n没有找到 SHHLr.dll 或 AsdkHlrApi.lib 文件!"));
|
|
// return NULL;
|
|
// }
|
|
|
|
// HINSTANCE hDllInst(NULL);
|
|
// if (hDllInst == NULL)
|
|
// {
|
|
// DWORD dw = ::GetCurrentDirectory(0, NULL);
|
|
// CString wkd;
|
|
// ::GetCurrentDirectory(dw + 1, wkd.GetBuffer(dw + 1));
|
|
// wkd.ReleaseBuffer();
|
|
// ::SetCurrentDirectory(sDbx);
|
|
|
|
// hDllInst = ::GetModuleHandle(sSHHLrDll);
|
|
// if (!hDllInst)
|
|
// hDllInst = ::LoadLibrary(sSHHLrDll);
|
|
// dRes = GetLastError();
|
|
// ::SetCurrentDirectory(wkd);
|
|
// }
|
|
|
|
// return hDllInst;
|
|
//}
|
|
|
|
//typedef void(_cdecl *hlr_collect_all)(AcDbObjectIdArray & // 原始实体
|
|
// , AcDbEntityArray & // 原始实体的指针,如果实体没有ID的情况下,用此参数传入
|
|
// , const int & // 控制参数
|
|
// , AcDbViewport * // 视口
|
|
// , IDMapEntities & // 结果,first-原实体 second-生成的消隐实体
|
|
// , EntMapEntities &); // 结果,first-原实体 second-生成的消隐实体
|
|
|
|
//typedef void(_cdecl *hlr_collect_simple)(AcDbObjectIdArray &
|
|
// , const int &
|
|
// , AcDbViewport *
|
|
// , IDMapEntities &);
|
|
|
|
void HlrCalc_simple(AcDbObjectIdArray &arIds
|
|
, AcDbViewport *pVp
|
|
, const int &control
|
|
, IDMapEntities &result)
|
|
{
|
|
HLR::hlr_collect(arIds, control, pVp, result);
|
|
// HINSTANCE hDllInst(getHLRInstance());
|
|
// if (!hDllInst)
|
|
// {
|
|
// acutPrintf(_T("\n加载 HLR 失败"));
|
|
// return;
|
|
// }
|
|
|
|
// hlr_collect_simple ptrFunc = (hlr_collect_simple)GetProcAddress(hDllInst, "hlr_collect");
|
|
// if (ptrFunc != NULL)
|
|
// ptrFunc(arIds, control, pVp, result);
|
|
|
|
//#ifndef ZWCAD
|
|
// if (::FreeLibrary(hDllInst))
|
|
// hDllInst = NULL;
|
|
//#endif
|
|
}
|
|
|
|
void HlrCalc(AcDbObjectIdArray &arIds
|
|
, AcDbEntityArray & arPtrs
|
|
, AcDbViewport *pVp
|
|
, const int &control
|
|
, IDMapEntities &result
|
|
, EntMapEntities& result2)
|
|
{
|
|
HLR::hlr_collect_all(arIds, arPtrs, control, pVp, result, result2);
|
|
// HINSTANCE hDllInst(getHLRInstance());
|
|
// if (!hDllInst)
|
|
// {
|
|
// acutPrintf(_T("\n加载 HLR 失败"));
|
|
// return;
|
|
// }
|
|
|
|
// hlr_collect_all ptrFunc = (hlr_collect_all)GetProcAddress(hDllInst, "hlr_collect_all");
|
|
// if (ptrFunc != NULL)
|
|
// ptrFunc(arIds, arPtrs, control, pVp, result, result2);
|
|
|
|
//#ifndef ZWCAD
|
|
// if (::FreeLibrary(hDllInst))
|
|
// hDllInst = NULL;
|
|
//#endif
|
|
}
|
|
|
|
bool zeroLength(AcDbCurve *pCrv, const double &tol)
|
|
{
|
|
double dPEnd(.0), dDist(.0);
|
|
pCrv->getEndParam(dPEnd);
|
|
pCrv->getDistAtParam(dPEnd, dDist);
|
|
return COMPARE_DOUBLE::equal_zero(dDist, tol);
|
|
}
|
|
|
|
void rollback(const AcDbObjectIdArray &arids)
|
|
{
|
|
AcDbEntityArray ar, output;
|
|
EntMapEntities eme;
|
|
for (int i(0); i < arids.length(); ++i)
|
|
{
|
|
AcDbEntityPointer ent(arids[i], AcDb::kForRead);
|
|
if (ent.openStatus() != Acad::eOk) continue;
|
|
|
|
AecDbEntityBase *pEnt(AecDbEntityBase::cast(ent));
|
|
AecDbCurveBase *pCrv(AecDbCurveBase::cast(ent));
|
|
if (pEnt)
|
|
pEnt->ProcessHlrResult(ar, eme, output);
|
|
if (pCrv)
|
|
pCrv->ProcessHlrResult(ar, eme, output);
|
|
}
|
|
}
|
|
|
|
bool isEnvelope(AcDbObjectId id)
|
|
{
|
|
AcDbEntityPointer ent(id, AcDb::kForRead);
|
|
if (ent.openStatus() != Acad::eOk) return false;
|
|
|
|
CString sDXF(ent->isA()->dxfName());
|
|
if (HlrCutOption::isEnvelopeEntity(sDXF))
|
|
{
|
|
// 板需要判断一下,如果有填充,不属于构筑物
|
|
if (sDXF == _T("AEC_DBSLAB"))
|
|
{
|
|
AecDbEwPipeBase *p(AecDbEwPipeBase::cast(ent));
|
|
PipeHatch ph;
|
|
if (p)
|
|
return !p->GetHatch(ph);
|
|
else
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool isValidSolid(AcDb3dSolid *pSolid)
|
|
{
|
|
AcDbExtents ext;
|
|
if (pSolid->isNull()) return false;
|
|
if (pSolid->getGeomExtents(ext) == Acad::eOk)
|
|
{
|
|
double dL = ext.maxPoint().distanceTo(ext.minPoint());
|
|
if (COMPARE_DOUBLE::equal_zero(dL)) return false;
|
|
}
|
|
else
|
|
return false;
|
|
|
|
double volume;
|
|
AcGePoint3d centroid;
|
|
double momInertia[3], prodInertia[3], prinMoments[3], radiiGyration[3];
|
|
AcGeVector3d prinAxes[3];
|
|
if (pSolid->getMassProp(volume
|
|
, centroid
|
|
, momInertia
|
|
, prodInertia
|
|
, prinMoments
|
|
, prinAxes
|
|
, radiiGyration
|
|
, ext) == Acad::eOk)
|
|
{
|
|
double dL = ext.maxPoint().distanceTo(ext.minPoint());
|
|
if (COMPARE_DOUBLE::equal_zero(dL)) return false;
|
|
if (COMPARE_DOUBLE::equal_zero(volume)) return false;
|
|
}
|
|
else
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
AcDbEntity* mergeEnvelope(AcDbObjectIdArray &arids)
|
|
{
|
|
std::map<void *, AcDbHandle> debugMM;
|
|
AcDbVoidPtrArray arptrs;
|
|
AcDbVoidPtrArray _ar;
|
|
AecDbObjXDataMap *pXDataMap(NULL);
|
|
for (int i(0); i < arids.length(); ++i)
|
|
{
|
|
AcDbEntityPointer ent(arids[i], AcDb::kForRead);
|
|
if (ent.openStatus() != Acad::eOk) continue;
|
|
|
|
_ar.removeAll();
|
|
|
|
AecDbEntityBase *pEnt(AecDbEntityBase::cast(ent));
|
|
AecDbCurveBase *pCrv(AecDbCurveBase::cast(ent));
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetDraw3dables(_ar, true);
|
|
for (int i(0); i < _ar.length(); ++i)
|
|
debugMM.insert(std::make_pair(_ar[i], ent->id().handle()));
|
|
arptrs.append(_ar);
|
|
|
|
pXDataMap = pEnt->GetSpecialtyData(AcDb::kForRead);
|
|
}
|
|
if (pCrv)
|
|
{
|
|
pCrv->GetDraw3dables(_ar, true);
|
|
for (int i(0); i < _ar.length(); ++i)
|
|
debugMM.insert(std::make_pair(_ar[i], ent->id().handle()));
|
|
arptrs.append(_ar);
|
|
pXDataMap = pCrv->GetSpecialtyData(AcDb::kForRead);
|
|
}
|
|
}
|
|
|
|
if (arptrs.isEmpty()) return NULL;
|
|
|
|
// 找到第一个 3dsolid
|
|
AcDb3dSolid *pSolidAll(NULL);
|
|
for (int i(0); i < arptrs.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt((AcDbEntity *)arptrs[i]);
|
|
if (!pEnt) continue;
|
|
|
|
pSolidAll = AcDb3dSolid::cast(pEnt);
|
|
if (!pSolidAll) continue;
|
|
if (pSolidAll->isNull())
|
|
{
|
|
#ifndef NDEBUG
|
|
acutPrintf(_T("\nThe 3DSOLID does not have a ShapeManager object. "));
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
arptrs.removeAt(i);
|
|
break;
|
|
}
|
|
|
|
if (!pSolidAll) return NULL;
|
|
|
|
if (arptrs.isEmpty()) return pSolidAll;
|
|
|
|
std::map<void *, AcDbHandle>::const_iterator debugIt(debugMM.end());
|
|
TCHAR szHand[19];
|
|
for (int i(0); i < arptrs.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt((AcDbEntity *)arptrs[i]);
|
|
if (!pEnt) continue;
|
|
AcDb3dSolid *pSolid(AcDb3dSolid::cast(pEnt));
|
|
if (!pSolid) continue;
|
|
if (pSolid->isNull())
|
|
{
|
|
#ifndef NDEBUG
|
|
acutPrintf(_T("\nThe 3DSOLID does not have a ShapeManager object. "));
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
if (!isValidSolid(pSolid)) continue;
|
|
|
|
if (pSolidAll->booleanOper(AcDb::kBoolUnite, pSolid) != Acad::eOk)
|
|
{
|
|
debugIt = debugMM.find((void*)pSolid);
|
|
if (debugIt == debugMM.end())
|
|
acutPrintf(_T("\n 融合出现错误,构筑物将按照不融和处理。%d"), i);
|
|
else
|
|
{
|
|
memset(szHand,0,sizeof(szHand) );
|
|
debugIt->second.getIntoAsciiBuffer(szHand);
|
|
acutPrintf(_T("\n 融合出现错误,构筑物将按照不融和处理。%s"), szHand);
|
|
}
|
|
|
|
deleteArrayVoidPtrs<AcDbEntity>(arptrs);
|
|
DELETE_PTR(pSolidAll);
|
|
return NULL;
|
|
|
|
}
|
|
}
|
|
|
|
deleteArrayVoidPtrs<AcDbEntity>(arptrs);
|
|
|
|
return pSolidAll;
|
|
}
|
|
|
|
// 处理一下构筑物的结果
|
|
// 1. 重复线
|
|
// 2. 争取处理一下融合构筑物,在二维条件下
|
|
void fixEnvelopeResult(AcDbEntityArray &arEnve)
|
|
{
|
|
|
|
}
|
|
|
|
// 给出中心点及长宽,得到一个矩形,左下角点开始,逆时针方向
|
|
AcDbRegion* getRect(const AcGePoint3d &ptCenter
|
|
, const double &W
|
|
, const double &H
|
|
, const AcGeVector3d &vtX = AcGeVector3d::kXAxis
|
|
, const AcGeVector3d &vtZ = AcGeVector3d::kZAxis)
|
|
{
|
|
AcGeVector3d Y(vtX), X(vtX);
|
|
Y.rotateBy(PI * .5, vtZ);
|
|
Y.normalize();
|
|
X.normalize();
|
|
|
|
AcGePoint3d pt0 = ptCenter - X * (W * .5);
|
|
pt0 -= Y * (H * .5);
|
|
AcGePoint3d pt1 = pt0 + X * W;
|
|
AcGePoint3d pt2 = pt1 + Y * H;
|
|
AcGePoint3d pt3 = pt2 - X * W;
|
|
|
|
AcDbVoidPtrArray ar;
|
|
ar.append(new AcDbLine(pt0, pt1));
|
|
ar.append(new AcDbLine(pt1, pt2));
|
|
ar.append(new AcDbLine(pt2, pt3));
|
|
ar.append(new AcDbLine(pt3, pt0));
|
|
AcDbRegion *pReg(CoreTools::createRegion(ar));
|
|
deleteArrayVoidPtrs<AcDbLine>(ar);
|
|
return pReg;
|
|
}
|
|
|
|
void processEnvelope(AcDbEntityArray &arEnve)
|
|
{
|
|
if (HlrCutOption::getHlrMERGE_Envelope())
|
|
{ // 构筑物融合后的数据
|
|
// 处理一下重复线,设置一下属性
|
|
fixEnvelopeResult(arEnve);
|
|
|
|
double dW(.0);
|
|
if (HlrCutOption::getHlrLW_Envelope(dW))
|
|
{
|
|
for (int i(0); i < arEnve.length(); ++i)
|
|
{
|
|
AcDbCurve *pCrv((AcDbCurve*)arEnve[i]);
|
|
AcDbPolyline *pL(CoreTools::MakePolyline(pCrv));
|
|
if (pL)
|
|
{
|
|
pL->setConstantWidth(dW);
|
|
DELETE_PTR(pCrv);
|
|
arEnve[i] = pL;
|
|
}
|
|
}
|
|
}
|
|
|
|
int nClr(256);
|
|
AcDbObjectId idLayer(AcDbObjectId::kNull), idLinetype(AcDbObjectId::kNull);
|
|
BOOL bLayer = HlrCutOption::getHlrLY_Envelope(idLayer);
|
|
BOOL bLinetype = HlrCutOption::getHlrLT_Envelope(idLinetype);
|
|
BOOL bClr = HlrCutOption::getHlrCL_Envelope(nClr);
|
|
|
|
for (int i(0); i < arEnve.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt(arEnve[i]);
|
|
if (bLayer && idLayer.isValid())
|
|
pEnt->setLayer(idLayer);
|
|
if (bLinetype && idLinetype.isValid())
|
|
pEnt->setLinetype(idLinetype);
|
|
if (bClr)
|
|
pEnt->setColorIndex(nClr);
|
|
}
|
|
}
|
|
else
|
|
{ // 构筑物未融合,每个实体都带有信息,不需要额外操作
|
|
// 处理一下重复线
|
|
fixEnvelopeResult(arEnve);
|
|
}
|
|
}
|
|
|
|
void preprocess(AcDbObjectIdArray &arids // 这个集合会被挑选修改
|
|
, const AcGePoint3d &ptPlnO
|
|
, const AcGeVector3d &vtPlnN
|
|
, IDMapEntities &preID2Ent // 由 “数据库实体” 产生的补充实体
|
|
, AcDbEntityArray &preEnt // 由 “非数据库实体” 产生的补充实体(没有ID与之对应)
|
|
, AcDbEntityArray &arAll )
|
|
{
|
|
AcDbObjectIdArray arOther;
|
|
|
|
// 目前只有构筑物融合需要
|
|
if (HlrCutOption::getHlrMERGE_Envelope())
|
|
{
|
|
AcDbObjectIdArray arEnev;
|
|
AecDbXCamera::collectEnvelope(arids, arOther, arEnev);
|
|
AcDbEntity *pEnvelope = mergeEnvelope(arEnev);
|
|
if (pEnvelope)
|
|
{
|
|
arids = arOther;
|
|
{// 暂时标记一下
|
|
AecDbObjXDataMap xData;
|
|
xData.SetAt(_T("TYPE"), _T("ENVELOPE"));
|
|
xData.Write(pEnvelope, _T("_ENVELOPE_"));
|
|
}
|
|
arAll.append(pEnvelope);
|
|
preEnt.append(pEnvelope);
|
|
}
|
|
else
|
|
{
|
|
arOther = arids;
|
|
}
|
|
}
|
|
else
|
|
arOther.append(arids);
|
|
|
|
AcDbEntityArray ar;
|
|
for (int i(0); i < arOther.length(); ++i)
|
|
{
|
|
AcDbEntityPointer ent(arids[i], AcDb::kForRead);
|
|
if (ent.openStatus() != Acad::eOk) continue;
|
|
|
|
ar.removeAll();
|
|
|
|
AecDbEntityBase *pEnt(AecDbEntityBase::cast(ent));
|
|
AecDbCurveBase *pCrv(AecDbCurveBase::cast(ent));
|
|
if (pEnt)
|
|
pEnt->PreprocessForHlr(ptPlnO, vtPlnN, ar);
|
|
if (pCrv)
|
|
pCrv->PreprocessForHlr(ptPlnO, vtPlnN, ar);
|
|
|
|
if (!ar.isEmpty())
|
|
{
|
|
preID2Ent.insert(std::make_pair(arids[i], ar));
|
|
arAll.append(ar);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void process_result( const IDMapEntities &result1
|
|
, const EntMapEntities &result2
|
|
, const IDMapEntities &mpAdditional
|
|
, const AcDbEntityArray &arAdditional
|
|
, IDMapEntities &outputWithID
|
|
, AcDbEntityArray &outputWithoutID )
|
|
{
|
|
AcDbEntityArray entAr;
|
|
EntMapEntities mpAddi;
|
|
#if ARX > 23
|
|
std::pair<EntMapEntities::iterator, bool> prAddi;
|
|
std::pair<IDMapEntities::iterator, bool> prOutput;
|
|
#else
|
|
EntMapEntities::_Pairib prAddi;
|
|
IDMapEntities::_Pairib prOutput;
|
|
#endif
|
|
|
|
|
|
// 构筑物产生的结果
|
|
AcDbEntityArray arEnvelope;
|
|
|
|
// 先处理 arAdditional 里面的数据
|
|
// arAdditional 里面是不在数据库里面的实体
|
|
// 把它的结果从 result2 里面挑出来
|
|
AecDbObjXDataMap xData;
|
|
for (int i(0); i < arAdditional.length(); ++i)
|
|
{
|
|
EntMapEntities::const_iterator it(result2.begin());
|
|
for (; it != result2.end(); ++it)
|
|
{
|
|
if (it->first == arAdditional[i])
|
|
{
|
|
AcDbEntity *pSrc(it->first);
|
|
const AcDbEntityArray &arResult(it->second); // 计算结果
|
|
if (xData.Read(pSrc, _T("_ENVELOPE_")))
|
|
{ // 说明是构筑物,统一处理,这个分支一般是选择了构筑物融合后参与计算
|
|
for (int i(0); i != arResult.length(); ++i)
|
|
arEnvelope.append((AcDbEntity*)arResult[i]->clone());
|
|
continue;
|
|
}
|
|
|
|
for (int i(0); i != arResult.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt = (AcDbEntity *)arResult[i]->clone();
|
|
if (!pEnt) continue;
|
|
pEnt->setLayer(pSrc->layerId());
|
|
pEnt->setLinetype(pSrc->linetypeId());
|
|
pEnt->setColorIndex(pSrc->colorIndex());
|
|
entAr.append(pEnt);
|
|
|
|
outputWithoutID.append(entAr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 不能只查找 result1 的结果
|
|
// 因为,如果一个实体的araw3d没有画出任何内容时,result1 里面没有其ID
|
|
// 但是,result2 却有可能存在它的补充实体
|
|
// 下面,对 result1 进行补充
|
|
IDMapEntities __result1(result1);
|
|
IDMapEntities::const_iterator _itAdd(mpAdditional.begin());
|
|
for (; _itAdd != mpAdditional.end(); ++_itAdd)
|
|
{
|
|
const AcDbObjectId &id(_itAdd->first);
|
|
const AcDbEntityArray &ar(_itAdd->second);
|
|
for (int i(0); i < ar.length(); ++i)
|
|
{
|
|
EntMapEntities::const_iterator it(result2.begin());
|
|
for (; it != result2.end(); ++it)
|
|
{
|
|
if (ar.find(it->first) != -1) // it->first 是 id 的补充实体
|
|
{
|
|
// 如果,此时,result1 里面没有这个 id 的话
|
|
// 说明 这个实体的draw3d没有结果,但是有补充实体
|
|
// 需要把这个id放到result1中。
|
|
// 不需要判断,直接插入,如果result1里面有这个id,插会失败
|
|
__result1.insert(std::make_pair(id, AcDbEntityArray()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
AcDbVoidPtrArray subAr;
|
|
IDMapEntities::const_iterator it1(__result1.begin());
|
|
for (; it1 != __result1.end(); ++it1)
|
|
{
|
|
entAr.removeAll();
|
|
mpAddi.clear();
|
|
const AcDbObjectId &id(it1->first);
|
|
const AcDbEntityArray &arDraw3d(it1->second);
|
|
|
|
AcDbEntityPointer ent(id, AcDb::kForRead);
|
|
if (ent.openStatus() != Acad::eOk)
|
|
{ // 如果 ent 无效,但是还存在结果,将结果复制到 output
|
|
// 目前只有水平轴网
|
|
for (int i(0); i < arDraw3d.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt = AecDbXCamera::cloneObject(arDraw3d[i]);
|
|
if (!pEnt) continue;
|
|
entAr.append(pEnt);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 查询这个 id 有没有补充实体
|
|
IDMapEntities::const_iterator itAddi(mpAdditional.find(id));
|
|
if (itAddi != mpAdditional.end())
|
|
{ // 有补充实体,在 result2 里面找到补充实体的结果
|
|
for (int i(0); i < itAddi->second.length(); ++i)
|
|
{
|
|
// 补充实体
|
|
AcDbEntity *pAddi(itAddi->second[i]);
|
|
|
|
EntMapEntities::const_iterator it2 = result2.find(pAddi);
|
|
if (it2 != result2.end())
|
|
{ // 补充实体 的 结果
|
|
const AcDbEntityArray &ar(it2->second);
|
|
prAddi = mpAddi.insert(std::make_pair(pAddi, ar));
|
|
if (!prAddi.second)
|
|
prAddi.first->second.append(ar);
|
|
}
|
|
}
|
|
}
|
|
|
|
AecDbEntityBase *pEnt(AecDbEntityBase::cast(ent));
|
|
AecDbCurveBase *pCrv(AecDbCurveBase::cast(ent));
|
|
if (pEnt)
|
|
pEnt->ProcessHlrResult(arDraw3d, mpAddi, entAr);
|
|
else if (pCrv)
|
|
pCrv->ProcessHlrResult(arDraw3d, mpAddi, entAr);
|
|
else // 非上华实体
|
|
{
|
|
AcDbBlockReference *pRef(AcDbBlockReference::cast(ent));
|
|
|
|
AcDbObjectId layerID(ent->layerId()), linetypeID(ent->linetypeId());
|
|
int color(ent->colorIndex());
|
|
for (int i(0); i < arDraw3d.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt = (AcDbEntity *)arDraw3d[i]->clone();
|
|
if (!pEnt) continue;
|
|
|
|
if (pRef)
|
|
{ // 如果被剖切的实体是块,收集结果,方便后面再打成块
|
|
subAr.append(pEnt);
|
|
}
|
|
else
|
|
{
|
|
pEnt->setLayer(layerID);
|
|
pEnt->setLinetype(linetypeID);
|
|
pEnt->setColorIndex(color);
|
|
entAr.append(pEnt);
|
|
}
|
|
}
|
|
if (pRef && !subAr.isEmpty())
|
|
{ // 如果 ent 是 块参照,它不会有补充实体,结果需要打成块
|
|
// 块的属性和 pRef 一样
|
|
AcDbBlockReference *pSubRef = CoreTools::makeBlockReference(subAr, NULL);
|
|
subAr.removeAll();
|
|
if (pSubRef)
|
|
{
|
|
pSubRef->setLayer(layerID);
|
|
pSubRef->setLinetype(linetypeID);
|
|
pSubRef->setColorIndex(color);
|
|
entAr.append(pSubRef);
|
|
}
|
|
}
|
|
EntMapEntities::const_iterator it(mpAddi.begin());
|
|
for (; it != mpAddi.end(); ++it)
|
|
{
|
|
layerID = it->first->layerId();
|
|
linetypeID = it->first->linetypeId();
|
|
color = it->first->colorIndex();
|
|
for (int i(0); i < it->second.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt = (AcDbEntity *)it->second[i]->clone();
|
|
if (!pEnt) continue;
|
|
pEnt->setLayer(layerID);
|
|
pEnt->setLinetype(linetypeID);
|
|
pEnt->setColorIndex(color);
|
|
entAr.append(pEnt);
|
|
}
|
|
}
|
|
}
|
|
if (entAr.isEmpty()) continue;
|
|
}
|
|
prOutput = outputWithID.insert(std::make_pair(id, entAr));
|
|
if (!prOutput.second)
|
|
prOutput.first->second.append(entAr);
|
|
}
|
|
|
|
// 收集构筑物产生的结果(一般是不对构筑物进行融合的情况下)
|
|
IDMapEntities::iterator it(outputWithID.begin());
|
|
for (; it != outputWithID.end(); ++it)
|
|
{
|
|
if (!isEnvelope(it->first)) continue;
|
|
// 是构筑物结果,复制出来,并且删掉outputWithID里面的内容
|
|
for (int i(0); i < it->second.length(); ++i)
|
|
arEnvelope.append((AcDbEntity*)(it->second[i]->clone()));
|
|
deleteContainerOfArx<AcDbEntity>(it->second);
|
|
outputWithID.erase(it);
|
|
it = outputWithID.begin();
|
|
}
|
|
|
|
// 处理构筑物
|
|
processEnvelope(arEnvelope);
|
|
outputWithoutID.append(arEnvelope);
|
|
}
|
|
|
|
}
|
|
|
|
ACRX_DXF_DEFINE_MEMBERS(AecDbXCamera, AecDbEntityBase,
|
|
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
|
|
AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning,
|
|
AEC_XCAMERA,
|
|
"AecXDbCamera"
|
|
"|Product Desc: shanghua earthworm app obj"
|
|
"|Company: shanghua inc"
|
|
"|WEB Address: www.shanghuasoft.com")
|
|
|
|
// kCurrentVersionNumber->2 --- 增加 m_arSelectionSet
|
|
Adesk::UInt32 AecDbXCamera::kCurrentVersionNumber = 2;
|
|
static const Adesk::UInt16 kBlue = 5;
|
|
|
|
AecDbXCamera::AecDbXCamera(void) { }
|
|
|
|
AecDbXCamera::~AecDbXCamera(void)
|
|
{
|
|
deleteContainerOfArx<GripData>(m_GripDatas);
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::subErase(Adesk::Boolean erasing)
|
|
{
|
|
//for (int i(0); i < m_arResults.length(); ++i)
|
|
// eraseEnt(m_arResults[i], erasing);
|
|
return AecDbEntityBase::subErase(erasing);
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::copyFrom(const AcRxObject *pSrc)
|
|
{
|
|
AssertWriteEnabled();
|
|
AecDbXCamera *pCamera = AecDbXCamera::cast(pSrc);
|
|
if (pCamera != NULL)
|
|
{
|
|
m_mapSpecXData.CopyFrom(pCamera->GetSpecialtyData(AcDb::kForRead));
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
|
|
void AecDbXCamera::subList() const
|
|
{
|
|
assertReadEnabled();
|
|
AecDbEntityBase::subList();
|
|
m_mapSpecXData.List();
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::subTransformBy(const AcGeMatrix3d &xform)
|
|
{
|
|
AssertWriteEnabled();
|
|
SetEyePoint(GetEyePoint().transformBy(xform));
|
|
SetEyeDirect(GetEyeDirect().transformBy(xform));
|
|
SetOutputPoint(GetOutputPoint().transformBy(xform));
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::subGetGripPoints(AcDbGripDataPtrArray &grips,
|
|
const double curViewUnitSize,
|
|
const int gripSize,
|
|
const AcGeVector3d &curViewDir,
|
|
const int bitflags) const
|
|
{
|
|
assertReadEnabled();
|
|
|
|
AcGePoint3dArray ar;
|
|
getGripPoints(ar);
|
|
|
|
deleteContainerOfArx<GripData>(m_GripDatas);
|
|
|
|
AcGeVector3d vtZ(getViewDir());
|
|
AcGePoint3dArray pts;
|
|
if (GetUsageMode() == eVerti)
|
|
{
|
|
if (vtZ.isParallelTo(AcGeVector3d::kZAxis))
|
|
{
|
|
// 水平
|
|
pts.append(ar[0]);
|
|
pts.append(ar[1]);
|
|
pts.append(ar[2]);
|
|
pts.append(ar[3]);
|
|
pts.append(ar[4]);
|
|
pts.append(ar[5]);
|
|
pts.append(ar.last());
|
|
}
|
|
else
|
|
{ // 非水平
|
|
pts.append(ar[4]);
|
|
pts.append(ar[10]);
|
|
}
|
|
// 先把 grippoints 里的点都绘制出来
|
|
for (int i(0); i < pts.length(); ++i)
|
|
{
|
|
GripData *gpd = new GripData;
|
|
gpd->m_idx = i;
|
|
gpd->m_pt = pts.at(i);
|
|
AcDbGripData *pGripData = new AcDbGripData;
|
|
pGripData->setGripPoint(pts.at(i));
|
|
pGripData->setWorldDraw(Grip_WorldDrawfunc);
|
|
m_GripDatas.append(gpd);
|
|
pGripData->setAppData(gpd);
|
|
grips.append(pGripData);
|
|
}
|
|
|
|
// 第1个点作为绘制点,绘制虚框
|
|
GripData &first = *m_GripDatas.first();
|
|
first.m_mode = eVerti;
|
|
first.m_arSelectFrame.append(ar[0]);
|
|
first.m_arSelectFrame.append(ar[2]);
|
|
first.m_arSelectFrame.append(ar[3]);
|
|
first.m_arSelectFrame.append(ar[5]);
|
|
if (!vtZ.isParallelTo(AcGeVector3d::kZAxis)) // 非水平,绘制范围框
|
|
{
|
|
first.m_arSelectFrame.append(ar[6]);
|
|
first.m_arSelectFrame.append(ar[7]);
|
|
first.m_arSelectFrame.append(ar[8]);
|
|
first.m_arSelectFrame.append(ar[9]);
|
|
}
|
|
}
|
|
else if (GetUsageMode() == eHoriz)
|
|
{
|
|
if (vtZ.isParallelTo(AcGeVector3d::kZAxis))
|
|
{
|
|
pts.append(ar[0]);
|
|
pts.append(ar[1]);
|
|
pts.append(ar[2]);
|
|
pts.append(ar[3]);
|
|
pts.append(ar[4]);
|
|
pts.append(ar.last());
|
|
}
|
|
else // 非水平,放入 9-10
|
|
{
|
|
pts.append(ar[9]);
|
|
pts.append(ar[10]);
|
|
}
|
|
|
|
for (int i(0); i < pts.length(); ++i)
|
|
{
|
|
GripData *gpd = new GripData;
|
|
gpd->m_idx = i;
|
|
gpd->m_pt = pts.at(i);
|
|
AcDbGripData *pGripData = new AcDbGripData;
|
|
pGripData->setGripPoint(pts.at(i));
|
|
pGripData->setWorldDraw(Grip_WorldDrawfunc);
|
|
m_GripDatas.append(gpd);
|
|
pGripData->setAppData(gpd);
|
|
grips.append(pGripData);
|
|
}
|
|
|
|
if (!vtZ.isParallelTo(AcGeVector3d::kZAxis)) // 非水平,绘制范围框
|
|
{
|
|
// 第1个点作为绘制点,绘制虚框
|
|
GripData &first = *m_GripDatas.first();
|
|
first.m_mode = eHoriz;
|
|
first.m_arSelectFrame.append(ar[0]);
|
|
first.m_arSelectFrame.append(ar[1]);
|
|
first.m_arSelectFrame.append(ar[2]);
|
|
first.m_arSelectFrame.append(ar[3]);
|
|
first.m_arSelectFrame.append(ar[5]);
|
|
first.m_arSelectFrame.append(ar[6]);
|
|
first.m_arSelectFrame.append(ar[7]);
|
|
first.m_arSelectFrame.append(ar[8]);
|
|
}
|
|
}
|
|
else // eStatic
|
|
{
|
|
if (ar.isEmpty()) return Acad::eOk;
|
|
|
|
GripData *gpd = new GripData;
|
|
gpd->m_idx = 0;
|
|
gpd->m_pt = ar.last();
|
|
AcDbGripData *pGripData = new AcDbGripData;
|
|
pGripData->setGripPoint(ar.last());
|
|
pGripData->setWorldDraw(Grip_WorldDrawfunc);
|
|
m_GripDatas.append(gpd);
|
|
pGripData->setAppData(gpd);
|
|
grips.append(pGripData);
|
|
}
|
|
|
|
// 显示结果范围
|
|
AcGePoint3d ptLT, ptRT, ptRB, ptLB;
|
|
if (getResultBox(ptLT, ptRT, ptRB, ptLB))
|
|
{
|
|
GripData &first = *m_GripDatas.first();
|
|
first.m_bDrawResultFrame = true;
|
|
first.m_arResultFrame.append(ptLT);
|
|
first.m_arResultFrame.append(ptRT);
|
|
first.m_arResultFrame.append(ptRB);
|
|
first.m_arResultFrame.append(ptLB);
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::subGetOsnapPoints(AcDb::OsnapMode osnapMode
|
|
, INT_PTR gsSelectionMark
|
|
, const AcGePoint3d &pickPoint
|
|
, const AcGePoint3d &lastPoint
|
|
, const AcGeMatrix3d &viewXform
|
|
, AcGePoint3dArray &snapPoints
|
|
, AcDbIntArray &geomIds) const
|
|
{
|
|
AcGePoint3dArray ar;
|
|
getGripPoints(ar);
|
|
|
|
if (GetUsageMode() != eStatic)
|
|
{
|
|
if (GetUsageMode() == eVerti)
|
|
{
|
|
snapPoints.append(ar[0]);
|
|
snapPoints.append(ar[1]);
|
|
snapPoints.append(ar[2]);
|
|
snapPoints.append(ar[3]);
|
|
snapPoints.append(ar[4]);
|
|
snapPoints.append(ar[5]);
|
|
snapPoints.append(ar[10]);
|
|
}
|
|
else
|
|
{
|
|
snapPoints.append(ar[0]);
|
|
snapPoints.append(ar[1]);
|
|
snapPoints.append(ar[2]);
|
|
snapPoints.append(ar[3]);
|
|
snapPoints.append(ar[4]);
|
|
}
|
|
}
|
|
|
|
AcGePoint3d ptLT, ptRT, ptRB, ptLB;
|
|
if (getResultBox(ptLT, ptRT, ptRB, ptLB))
|
|
{
|
|
snapPoints.append(ptLT);
|
|
snapPoints.append(ptRT);
|
|
snapPoints.append(ptRB);
|
|
snapPoints.append(ptLB);
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::subMoveGripPointsAt(const AcDbVoidPtrArray &appData
|
|
, const AcGeVector3d &offset
|
|
, const int bitflags)
|
|
{
|
|
AssertWriteEnabled();
|
|
if (appData.isEmpty()) return Acad::eOk;
|
|
|
|
bool bFresh(false);
|
|
|
|
GripData *pAppData = (GripData *)appData.first();
|
|
|
|
AcGePoint3dArray ar;
|
|
getGripPoints(ar);
|
|
if (GetUsageMode() == eVerti)
|
|
{
|
|
AcGePoint3d ptOffset(pAppData->m_pt + offset)
|
|
, ptOrig(pAppData->m_pt)
|
|
, pt0(ar[0])
|
|
, pt1(ar[1])
|
|
, pt2(ar[2])
|
|
, pt3(ar[3])
|
|
, pt4(ar[4])
|
|
, pt5(ar[5])
|
|
, pt6(ar[6]);
|
|
|
|
AcGeVector3d vt(getViewDir());
|
|
if (vt.isCodirectionalTo(AcGeVector3d::kZAxis))
|
|
{
|
|
switch (pAppData->m_idx)
|
|
{
|
|
case 3: // 修改视口宽度
|
|
case 5:
|
|
{
|
|
AcDbLine seg(pt3, pt5);
|
|
AcGePoint3d ptNew;
|
|
seg.getClosestPointTo(ptOffset, ptNew, Adesk::kTrue);
|
|
AcGeVector3d vtOld(pt4 - ptOrig);
|
|
AcGeVector3d vtNew(pt4 - ptNew);
|
|
if (vtOld.isCodirectionalTo(vtNew) && vtNew.length() > 100)
|
|
{
|
|
SetWidth(vtNew.length() * 2);
|
|
bFresh = true;
|
|
}
|
|
}
|
|
break;
|
|
case 1: // 移动眼睛位置
|
|
SetEyePoint(GetEyePoint() + offset);
|
|
bFresh = true;
|
|
break;
|
|
case 0: // 旋转 m_vtEye 的方向
|
|
{
|
|
AcGeVector3d vtOld(pt0 - pt2);
|
|
AcGeVector3d vtNew(ptOffset - pt1);
|
|
double dAngle = vtOld.angleTo(vtNew, AcGeVector3d::kZAxis);
|
|
vtNew = GetEyeDirect();
|
|
vtNew.rotateBy(dAngle, AcGeVector3d::kZAxis);
|
|
SetEyeDirect(vtNew);
|
|
bFresh = true;
|
|
}
|
|
break;
|
|
case 2: // 旋转 m_vtEye 的方向
|
|
{
|
|
AcGeVector3d vtOld(pt2 - pt0);
|
|
AcGeVector3d vtNew(ptOffset - pt1);
|
|
double dAngle = vtOld.angleTo(vtNew, AcGeVector3d::kZAxis);
|
|
vtNew = GetEyeDirect();
|
|
vtNew.rotateBy(dAngle, AcGeVector3d::kZAxis);
|
|
SetEyeDirect(vtNew);
|
|
bFresh = true;
|
|
}
|
|
break;
|
|
case 4: // 修改 视口的纵深 既 m_vtEye 的长度
|
|
{
|
|
AcDbLine seg(pt0, pt2);
|
|
AcGePoint3d ptClosed;
|
|
seg.getClosestPointTo(ptOffset, ptClosed, Adesk::kTrue);
|
|
|
|
AcGeVector3d vtNew(ptOffset - ptClosed);
|
|
double dist(ptOffset.distanceTo(ptClosed));
|
|
if (dist > 100)
|
|
{
|
|
SetEyeDirect(vtNew);
|
|
bFresh = true;
|
|
}
|
|
}
|
|
break;
|
|
case 6: // 移动输出结果的位置
|
|
{
|
|
moveOutput(offset);
|
|
bFresh = false;
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (pAppData->m_idx)
|
|
{
|
|
case 0:
|
|
SetHorizTop((pAppData->m_pt + offset).z);
|
|
break;
|
|
case 1:
|
|
SetHorizBottom((pAppData->m_pt + offset).z);
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if (GetUsageMode() == eHoriz)
|
|
{
|
|
AcGePoint3d ptOld, pt2, ptNew, ptClosed, ptEye;
|
|
AcDbLine lineH, lineV;
|
|
AcGeVector3d vtEye;
|
|
AcGeMatrix3d mat;
|
|
bFresh = true;
|
|
AcGeVector3d vtZ(getViewDir());
|
|
ptOld = pAppData->m_pt;
|
|
ptNew = ptOld + offset;
|
|
if (vtZ.isParallelTo(AcGeVector3d::kZAxis))
|
|
{
|
|
switch (pAppData->m_idx)
|
|
{
|
|
case 0:
|
|
pt2 = ar[2];
|
|
SetEyePoint(CoreTools::MidPt(ptNew, pt2));
|
|
lineH.setStartPoint(ar[2]);
|
|
lineH.setEndPoint(ar[3]);
|
|
lineH.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue);
|
|
SetHeight(ptNew.distanceTo(ptClosed));
|
|
lineV.setStartPoint(ar[1]);
|
|
lineV.setEndPoint(ar[2]);
|
|
lineV.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue);
|
|
SetWidth(ptNew.distanceTo(ptClosed));
|
|
break;
|
|
case 1:
|
|
pt2 = ar[3];
|
|
SetEyePoint(CoreTools::MidPt(ptNew, pt2));
|
|
lineH.setStartPoint(ar[2]);
|
|
lineH.setEndPoint(ar[3]);
|
|
lineH.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue);
|
|
SetHeight(ptNew.distanceTo(ptClosed));
|
|
lineV.setStartPoint(ar[0]);
|
|
lineV.setEndPoint(ar[3]);
|
|
lineV.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue);
|
|
SetWidth(ptNew.distanceTo(ptClosed));
|
|
break;
|
|
case 2:
|
|
pt2 = ar[0];
|
|
SetEyePoint(CoreTools::MidPt(ptNew, pt2));
|
|
lineH.setStartPoint(ar[0]);
|
|
lineH.setEndPoint(ar[1]);
|
|
lineH.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue);
|
|
SetHeight(ptNew.distanceTo(ptClosed));
|
|
lineV.setStartPoint(ar[0]);
|
|
lineV.setEndPoint(ar[3]);
|
|
lineV.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue);
|
|
SetWidth(ptNew.distanceTo(ptClosed));
|
|
break;
|
|
case 3:
|
|
pt2 = ar[1];
|
|
SetEyePoint(CoreTools::MidPt(ptNew, pt2));
|
|
lineH.setStartPoint(ar[0]);
|
|
lineH.setEndPoint(ar[1]);
|
|
lineH.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue);
|
|
SetHeight(ptNew.distanceTo(ptClosed));
|
|
lineV.setStartPoint(ar[2]);
|
|
lineV.setEndPoint(ar[1]);
|
|
lineV.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue);
|
|
SetWidth(ptNew.distanceTo(ptClosed));
|
|
break;
|
|
case 4: // eye
|
|
SetEyePoint(ptNew);
|
|
break;
|
|
case 5: // output
|
|
moveOutput(offset);
|
|
bFresh = false;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (pAppData->m_idx)
|
|
{
|
|
case 0: // top
|
|
ptEye = GetEyePoint();
|
|
ptEye.z = ptNew.z;
|
|
SetEyePoint(ptEye);
|
|
SetHorizTop(ptNew.z);
|
|
vtEye = GetEyeDirect();
|
|
vtEye = -AcGeVector3d::kZAxis * (GetHorizTop() - GetHorizBottom());
|
|
SetEyeDirect(vtEye);
|
|
break;
|
|
case 1: // bottom
|
|
SetHorizBottom(ptNew.z);
|
|
vtEye = GetEyeDirect();
|
|
vtEye = -AcGeVector3d::kZAxis * (GetHorizTop() - GetHorizBottom());
|
|
SetEyeDirect(vtEye);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else // eStatic
|
|
{
|
|
moveOutput(offset);
|
|
bFresh = false;
|
|
}
|
|
|
|
// 当松开夹点时,database() 不为空,可以刷新。
|
|
if (database() && bFresh)
|
|
{
|
|
refresh(true);
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::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 > AecDbXCamera::kCurrentVersionNumber)
|
|
return (Acad::eMakeMeProxy);
|
|
|
|
m_mapSpecXData.dwgInFields(pFiler);
|
|
|
|
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);
|
|
}
|
|
|
|
if (version > 1)
|
|
{
|
|
pFiler->readInt32(&num);
|
|
for (int i(0); i < num; ++i)
|
|
{
|
|
pFiler->readSoftPointerId((AcDbSoftPointerId *)&id);
|
|
if (id.isValid())
|
|
m_arSelectionSet.append(id);
|
|
}
|
|
}
|
|
|
|
return (pFiler->filerStatus());
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::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(AecDbXCamera::kCurrentVersionNumber)) != Acad::eOk)
|
|
return (es);
|
|
|
|
m_mapSpecXData.dwgOutFields(pFiler);
|
|
|
|
pFiler->writeInt32(m_arResults.length());
|
|
for (int i(0); i < m_arResults.length(); ++i)
|
|
pFiler->writeSoftPointerId(m_arResults[i]);
|
|
|
|
if (AecDbXCamera::kCurrentVersionNumber > 1)
|
|
{
|
|
pFiler->writeInt32(m_arSelectionSet.length());
|
|
for (int i(0); i < m_arSelectionSet.length(); ++i)
|
|
pFiler->writeSoftPointerId(m_arSelectionSet[i]);
|
|
}
|
|
|
|
return (pFiler->filerStatus());
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::Draw2d(AcGiDraw &dc) const
|
|
{
|
|
assertReadEnabled();
|
|
|
|
AcGePoint3dArray ar;
|
|
getGripPoints(ar);
|
|
|
|
Adesk::UInt16 oldClr = dc.GetColor();
|
|
dc.SetColor(6);
|
|
|
|
if (GetUsageMode() != eStatic)
|
|
{
|
|
int prec(0);
|
|
CString sTop;
|
|
sTop.Format(_T("%s , %s"), TypeConvert::d2s(GetHorizTop(), &prec)
|
|
, TypeConvert::d2s(GetHorizBottom(), &prec));
|
|
|
|
double dH;
|
|
AcGePoint3d ptIns;
|
|
double dRotation(.0);
|
|
AcGeVector3d X(AcGeVector3d::kXAxis);
|
|
if (GetUsageMode() == eVerti)
|
|
{
|
|
dc.DrawLine(AcGeLineSeg3d(ar[0], ar[2]));
|
|
|
|
dH = (ar[2].distanceTo(ar[3]) * .025);
|
|
ptIns = (CoreTools::MidPt(ar[0], ar[2]) - GetEyeDirect().normalize() * dH);
|
|
X = (ar[2] - ar[0]).normalize();
|
|
dRotation = AcGeVector3d::kXAxis.angleTo(X, AcGeVector3d::kZAxis);
|
|
}
|
|
else
|
|
{
|
|
dc.DrawLine(AcGeLineSeg3d(ar[0], ar[1]));
|
|
dc.DrawLine(AcGeLineSeg3d(ar[1], ar[2]));
|
|
dc.DrawLine(AcGeLineSeg3d(ar[2], ar[3]));
|
|
dc.DrawLine(AcGeLineSeg3d(ar[3], ar[0]));
|
|
|
|
dH = (ar[1].distanceTo(ar[2]) * .025);
|
|
ptIns = (CoreTools::MidPt(ar[3], ar[2]) - AcGeVector3d::kYAxis * dH);
|
|
|
|
}
|
|
|
|
AcDbText txt1;
|
|
txt1.setTextString(sTop);
|
|
txt1.setPosition(ptIns);
|
|
txt1.setHeight(dH);
|
|
AcDbExtents ext;
|
|
txt1.getGeomExtents(ext);
|
|
double dW(ext.maxPoint().x - ext.minPoint().x);
|
|
ptIns -= X * (dW * .5);
|
|
txt1.setPosition(ptIns);
|
|
txt1.setRotation(dRotation);
|
|
|
|
dc.DrawEntity(txt1);
|
|
}
|
|
|
|
dc.SetColor(oldClr);
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus AecDbXCamera::Draw3d(AcGiDraw &dc) const
|
|
{
|
|
return Draw2d(dc);
|
|
}
|
|
|
|
void AecDbXCamera::cloneObjects(AcDbObjectIdArray &arids, AcDbEntityArray &ents)
|
|
{
|
|
for (int i(0); i < arids.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt = cloneObject(arids[i]);
|
|
if (!pEnt) continue;
|
|
ents.append(pEnt);
|
|
}
|
|
}
|
|
|
|
AcDbEntity *AecDbXCamera::cloneObject(AcDbEntity *p)
|
|
{
|
|
if (!p) return NULL;
|
|
|
|
AcDbEntity *pEnt = (AcDbEntity *)p->clone();
|
|
if (!pEnt) return NULL;
|
|
|
|
pEnt->setLayer(p->layerId());
|
|
pEnt->setLinetype(p->linetypeId());
|
|
pEnt->setColorIndex(p->colorIndex());
|
|
|
|
AecDbObjXDataMap xdata;
|
|
if (xdata.Read(p, BIMDATA_APP))
|
|
xdata.Write(pEnt, BIMDATA_APP);
|
|
|
|
return pEnt;
|
|
}
|
|
|
|
AcDbEntity *AecDbXCamera::cloneObject(AcDbObjectId &id)
|
|
{
|
|
AcDbEntityPointer ent(id, AcDb::kForRead);
|
|
if (ent.openStatus() != Acad::eOk) return NULL;
|
|
return cloneObject(ent);
|
|
}
|
|
|
|
void AecDbXCamera::collectEnities(resbuf *selType, resbuf *selArea, AcDbObjectIdArray &arIds)
|
|
{
|
|
ads_name ss, ent;
|
|
int nRes = acedSSGet(_T("CP"), selArea, NULL, selType, ss);
|
|
if (nRes != RTNORM) return;
|
|
|
|
Adesk::Int32 lLen = 0;
|
|
acedSSLength(ss, &lLen);
|
|
AcDbObjectId id;
|
|
for (int i = 0; i < lLen; i++)
|
|
{
|
|
acedSSName(ss, i, ent);
|
|
acdbGetObjectId(id, ent);
|
|
if (id.isValid())
|
|
arIds.append(id);
|
|
}
|
|
acedSSFree(ss);
|
|
}
|
|
|
|
resbuf *AecDbXCamera::getCollectArea() const
|
|
{
|
|
assertReadEnabled();
|
|
AcGePoint3dArray arPts;
|
|
getGripPoints(arPts);
|
|
|
|
struct resbuf *pointlist(NULL);
|
|
if (GetUsageMode() == eVerti)
|
|
{
|
|
pointlist = acutBuildList(RTPOINT, arPts[0], RTPOINT, arPts[2],
|
|
RTPOINT, arPts[3], RTPOINT, arPts[5], RTPOINT, arPts[0], 0);
|
|
}
|
|
else if (GetUsageMode() == eHoriz)
|
|
{
|
|
pointlist = acutBuildList(RTPOINT, arPts[0], RTPOINT, arPts[1],
|
|
RTPOINT, arPts[2], RTPOINT, arPts[3], RTPOINT, arPts[0], 0);
|
|
}
|
|
return pointlist;
|
|
}
|
|
|
|
void AecDbXCamera::calcRangeOfElev(double &dMax, double &dMin)
|
|
{
|
|
AcDbObjectIdArray ar;
|
|
collectEnities(ar);
|
|
AcGePoint3d ptmax, ptmin;
|
|
AcDbExtents ext, all;
|
|
for (int i(0); i < ar.length(); ++i)
|
|
{
|
|
AcDbEntityPointer ent(ar[i], AcDb::kForRead);
|
|
if (ent.openStatus() != Acad::eOk) continue;
|
|
if (ent->getGeomExtents(ext) != Acad::eOk) continue;
|
|
ptmax = ext.maxPoint();
|
|
ptmin = ext.minPoint();
|
|
if (ptmax.x < ptmin.x
|
|
|| ptmax.y < ptmin.y
|
|
|| ptmax.z < ptmin.z) continue;
|
|
all.addExt(ext);
|
|
}
|
|
dMax = all.maxPoint().z;
|
|
dMin = all.minPoint().z;
|
|
if (dMax < dMin)
|
|
{
|
|
dMax = 0.;
|
|
dMin = 0.;
|
|
}
|
|
}
|
|
|
|
void AecDbXCamera::collectEnities(AcDbObjectIdArray &arIds) const
|
|
{
|
|
assertReadEnabled();
|
|
|
|
/*
|
|
struct resbuf *pRb = acutBuildList(
|
|
-4, _T("<or")
|
|
, RTDXF0, _T("AEC_*")
|
|
, -4, _T("<or")
|
|
, -4, _T("<and"), RTDXF0, _T("LINE"), 8, _T("Dote"), -4, _T("and>")
|
|
, -4, _T("<and"), RTDXF0, _T("LINE"), 8, _T("Axis"), -4, _T("and>")
|
|
, -4, _T("or>")
|
|
, -4, _T("or>")
|
|
|
|
, -4, _T("<not")
|
|
, -4, _T("<or")
|
|
, RTDXF0, _T("AEC_XCAMERA")
|
|
, RTDXF0, _T("AEC_ZUOBIAOBIAOZHU")
|
|
, RTDXF0, _T("AEC_BIAOGAOBIAOZHU")
|
|
, RTDXF0, _T("AEC_JIANTOUYINZHU")
|
|
, RTDXF0, _T("AEC_YINCHUBIAOZU")
|
|
, RTDXF0, _T("AEC_ZUOFABIAOZHU")
|
|
, RTDXF0, _T("AEC_SUOYINTUMING")
|
|
, RTDXF0, _T("AEC_POQIE")
|
|
, RTDXF0, _T("AEC_YUNXIAN")
|
|
, RTDXF0, _T("AEC_ZHEDUANXIAN")
|
|
, RTDXF0, _T("AEC_DUICHENZHOU")
|
|
, RTDXF0, _T("AEC_ZHIBEIZHEN")
|
|
, RTDXF0, _T("AEC_TUMINGBIAOZHU")
|
|
, RTDXF0, _T("AEC_CHICUNBIAOZHU")
|
|
, RTDXF0, _T("AEC_BANJINGBIAOZHU")
|
|
, RTDXF0, _T("AEC_EWPIPEDIM")
|
|
, -4, _T("or>")
|
|
, -4, _T("not>")
|
|
, 0);
|
|
*/
|
|
|
|
struct resbuf *selArea(getCollectArea());
|
|
struct resbuf *typelist(getSelectTypeResbuf());
|
|
collectEnities(typelist, selArea, arIds);
|
|
|
|
acutRelRb(selArea);
|
|
acutRelRb(typelist);
|
|
}
|
|
|
|
void AecDbXCamera::transfromHlrResult(const AcGePoint3d &_ptEye
|
|
, const AcGeVector3d &vtEye
|
|
, const AcGeVector3d &vtX
|
|
, const AcGePoint3d &_ptOutput
|
|
, IDMapEntities &result
|
|
, EntMapEntities &result2
|
|
, AcDbEntity *pSection)
|
|
{
|
|
if (!pSection) return;
|
|
AcDbEntityArray ptrs;
|
|
IDMapEntities::const_iterator it(result.begin());
|
|
for (; it != result.end(); ++it)
|
|
ptrs.append(it->second);
|
|
|
|
EntMapEntities::const_iterator it2(result2.begin());
|
|
for (; it2 != result2.end(); ++it2)
|
|
ptrs.append(it2->second);
|
|
|
|
ptrs.append(pSection);
|
|
|
|
if (ptrs.isEmpty()) return;
|
|
AcGeMatrix3d mat;
|
|
AcGePoint3d ptEye(_ptEye);
|
|
ptEye.z = .0;
|
|
|
|
mat.setToAlignCoordSys(ptEye
|
|
, vtX.normal()
|
|
, vtEye.crossProduct(vtX).normal()
|
|
, vtEye.normal()
|
|
, AcGePoint3d::kOrigin
|
|
, AcGeVector3d::kXAxis
|
|
, AcGeVector3d::kYAxis
|
|
, AcGeVector3d::kZAxis);
|
|
|
|
AcGeMatrix3d matVerti;
|
|
AcGePoint3d ptStart(AcGePoint3d::kOrigin);
|
|
for (int i(0); i < ptrs.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt((AcDbEntity *)ptrs[i]);
|
|
if (pEnt)
|
|
pEnt->transformBy(mat);
|
|
AcDbCurve *pCrv(AcDbCurve::cast(pEnt));
|
|
if (pCrv)
|
|
{ // 拉到0标高
|
|
pCrv->getStartPoint(ptStart);
|
|
matVerti.setTranslation(ptStart.z * -AcGeVector3d::kZAxis);
|
|
pCrv->transformBy(matVerti);
|
|
}
|
|
}
|
|
|
|
// 只需要pSection的中点做移动点
|
|
AcDbExtents ext;
|
|
pSection->getGeomExtents(ext);
|
|
|
|
AcGePoint3d ptResultCenter(CoreTools::MidPt(ext.maxPoint(), ext.minPoint()));
|
|
|
|
AcGePoint3d ptOutput(_ptOutput);
|
|
ptOutput.z = .0;
|
|
|
|
mat.setToIdentity();
|
|
mat.setToTranslation(ptOutput - ptResultCenter);
|
|
|
|
for (int i(0); i < ptrs.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt((AcDbEntity *)ptrs[i]);
|
|
if (pEnt)
|
|
pEnt->transformBy(mat);
|
|
}
|
|
}
|
|
|
|
void AecDbXCamera::transfromHlrResult(IDMapEntities &result
|
|
, EntMapEntities &result2
|
|
, AcDbEntity *pSection) const
|
|
{
|
|
assertReadEnabled();
|
|
|
|
if (!pSection) return;
|
|
|
|
AcGePoint3dArray arPts;
|
|
getGripPoints(arPts);
|
|
|
|
AcGeVector3d X(AcGeVector3d::kXAxis);
|
|
if (GetUsageMode() == eVerti)
|
|
{
|
|
if (arPts.length() < 2)
|
|
return;
|
|
X = arPts[0] - arPts[1];
|
|
}
|
|
|
|
AcGeVector3d Z(-GetEyeDirect());
|
|
AcGeVector3d Y(Z.crossProduct(X));
|
|
transfromHlrResult(GetEyePoint(), Z, X, GetOutputPoint(), result, result2, pSection);
|
|
|
|
}
|
|
|
|
void AecDbXCamera::hlrCalc(AcDbObjectIdArray &arIds
|
|
, const AcGePoint3d &ptEye
|
|
, const AcGeVector3d &vtEye
|
|
, const AcGeVector3d &vtX
|
|
, const AcGePoint3d &ptOutput
|
|
, AcDbPolyline *pSection
|
|
, IDMapEntities &outputWithID
|
|
, AcDbEntityArray &outputWithoutID
|
|
, AcDbEntityArray &arAxisPtrs)
|
|
{
|
|
// 在数据库中的实体所生成的补充实体
|
|
// first-数据库中实体id second-选中实体产生的补充实体
|
|
IDMapEntities mpAdditional;
|
|
|
|
// 不在数据库中的实体生成的补充实体
|
|
AcDbEntityArray arAdditional;
|
|
|
|
|
|
/*
|
|
HlrCalc 处理三种类型的数据
|
|
1.数据库内的实体
|
|
2.数据库内的实体产生的补充实体(管线、管件的中心线,阀门的2D表示 etc.)
|
|
3.非数据库内的实体产生的补充实体(构筑物融合之后的实体就属于这种类型)
|
|
2、3两个数据都放入arAdditional_all里面进行计算
|
|
*/
|
|
|
|
// 所有的补充实体
|
|
AcDbEntityArray arAdditional_all;
|
|
|
|
// 预处理,得到选中实体的补充实体
|
|
preprocess(arIds
|
|
, ptEye
|
|
, vtEye
|
|
, mpAdditional
|
|
, arAdditional
|
|
, arAdditional_all);
|
|
|
|
// 获取hlr原始结果
|
|
std::shared_ptr<AcDbViewport> pVp(makeViewPort(ptEye, -vtEye));
|
|
IDMapEntities result1;
|
|
EntMapEntities result2;
|
|
int control = kEntity|kProgress|kHideTangents|kProject/*|kShowAll|kBlock|kHonorInternals*/;
|
|
|
|
HlrCalc(arIds, arAdditional_all, pVp.get(), control, result1, result2);
|
|
|
|
if (result1.empty() && result2.empty())
|
|
{
|
|
// 如果实体的PreprocessForHlr函数内,设置了 HLR_CALC,从而影响实体的 Draw3d 函数的返回
|
|
// 那么,其PreprocessForHlr函数一定要无条件设置回来
|
|
// rollback 回调用其内部的PreprocessForHlr函数
|
|
rollback(arIds);
|
|
return;
|
|
}
|
|
|
|
if (!arAxisPtrs.isEmpty())
|
|
result1.insert(std::make_pair(AcDbObjectId::kNull, arAxisPtrs));
|
|
|
|
// 调整结果位置
|
|
transfromHlrResult(ptEye, -vtEye, vtX, ptOutput, result1, result2, pSection);
|
|
|
|
// 截面裁剪
|
|
clipResultBySection(result1, result2, pSection);
|
|
|
|
// 如果裁剪之后,没有结果了,回退实体状态
|
|
if (result1.empty() && result2.empty())
|
|
{
|
|
rollback(arIds);
|
|
return;
|
|
}
|
|
|
|
// 设置属性
|
|
process_result(result1, result2, mpAdditional, arAdditional, outputWithID, outputWithoutID);
|
|
|
|
// 最后把section复制一份放到结果里面
|
|
//outputWithoutID.append((AcDbEntity*)pSection->clone());
|
|
|
|
// 释放draw3d的计算结果
|
|
IDMapEntities::iterator it(result1.begin());
|
|
for (; it != result1.end(); ++it)
|
|
deleteContainerOfArx<AcDbEntity>(it->second);
|
|
|
|
// 释放补充实体的计算结果
|
|
EntMapEntities::iterator it2(result2.begin());
|
|
for (; it2 != result2.end(); ++it2)
|
|
deleteContainerOfArx<AcDbEntity>(it2->second);
|
|
|
|
// 释放 所有补充实体
|
|
deleteContainerOfArx<AcDbEntity>(arAdditional_all);
|
|
|
|
rollback(arIds);
|
|
}
|
|
|
|
void AecDbXCamera::refresh(const bool &bRefreshEntity)
|
|
{
|
|
assertWriteEnabled();
|
|
if (!bRefreshEntity) return;
|
|
|
|
// 清空输出结果实体
|
|
eraseEnts(m_arResults);
|
|
|
|
// 收集实体
|
|
AcDbObjectIdArray arIds;
|
|
// 收集轴网
|
|
AcDbObjectIdArray arAxis;
|
|
// 收集围护结构
|
|
|
|
if (GetUsageMode() != eStatic)
|
|
{
|
|
collectEnities(arIds);
|
|
collectAxisObject(arAxis);
|
|
}
|
|
else
|
|
{
|
|
arIds.append(m_arSelectionSet);
|
|
}
|
|
|
|
if (arIds.isEmpty()) return;
|
|
|
|
AcGeVector3d X(AcGeVector3d::kXAxis);
|
|
if (GetUsageMode() == eVerti)
|
|
{
|
|
AcGePoint3dArray arPts;
|
|
getGripPoints(arPts);
|
|
if (arPts.length() < 2)
|
|
return;
|
|
X = arPts[0] - arPts[1];
|
|
}
|
|
// 截面
|
|
AcDbPolyline *pSection = getSectionPolygon();
|
|
|
|
IDMapEntities outputWithID; // 可以与数据库实体相关联的结果
|
|
AcDbEntityArray outputWithoutID;// 不能与数据库实体相关联的结果
|
|
|
|
AcDbEntityArray entAxis;
|
|
// 计算轴网
|
|
if (!arAxis.isEmpty())
|
|
{
|
|
if (GetUsageMode() == eVerti) // 垂直剖切,轴网自己遮挡一下
|
|
{
|
|
AcDbExtents extAll;
|
|
pSection->getGeomExtents(extAll);
|
|
double dMaxZ(extAll.maxPoint().z), dMinZ(extAll.minPoint().z);
|
|
double dH(dMaxZ - dMinZ);
|
|
// 最高点向上延长30%
|
|
dMaxZ += dH * (3. / 10);
|
|
// 最低点向上提长度的一半
|
|
dMinZ += dH * .5;
|
|
|
|
// 得到特征点
|
|
AcGePoint3dArray arPts;
|
|
getGripPoints(arPts);
|
|
|
|
// 找到和剖切线垂直的,其它的不要
|
|
AcGeLineSeg3d cutLine(arPts[1], arPts[0]), axisLine;
|
|
for (int i(0); i < arAxis.length(); ++i)
|
|
{
|
|
AcDbObjectPointer<AcDbLine> line(arAxis[i], AcDb::kForRead);
|
|
if (line.openStatus() != Acad::eOk) continue;
|
|
axisLine.set(line->startPoint(), line->endPoint());
|
|
if (axisLine.isPerpendicularTo(cutLine))
|
|
entAxis.append(cloneObject(arAxis[i]));
|
|
}
|
|
|
|
// 将轴网变换到剖切面上
|
|
// 以剖切线为轴,翻转轴网
|
|
AcGeMatrix3d mat;
|
|
mat.setToRotation(-PI * .5 , arPts[2] - arPts[1]);
|
|
|
|
AcGePoint3d ptS, ptE;
|
|
for (int i(0); i < entAxis.length(); ++i)
|
|
{
|
|
AcDbLine *pL(AcDbLine::cast(entAxis[i]));
|
|
if (pL)
|
|
{
|
|
pL->transformBy(mat);
|
|
ptS = pL->startPoint();
|
|
ptE = pL->endPoint();
|
|
// 修改变换后的标高
|
|
pL->setStartPoint(AcGePoint3d(ptS.x, ptS.y, dMinZ));
|
|
pL->setEndPoint(AcGePoint3d(ptE.x, ptE.y, dMaxZ));
|
|
}
|
|
}
|
|
}
|
|
else if (GetUsageMode() == eHoriz) // 水平剖切,直接复制出来
|
|
{
|
|
// 拷贝轴网
|
|
cloneObjects(arAxis, entAxis);
|
|
}
|
|
}
|
|
|
|
hlrCalc(arIds
|
|
, GetEyePoint()
|
|
, GetEyeDirect()
|
|
, X
|
|
, GetOutputPoint()
|
|
, pSection
|
|
, outputWithID
|
|
, outputWithoutID
|
|
, entAxis );
|
|
|
|
DELETE_PTR(pSection);
|
|
|
|
// 输出
|
|
IDMapEntities::iterator it;
|
|
AcDbObjectId id;
|
|
for (it = outputWithID.begin(); 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);
|
|
}
|
|
|
|
// 保险起见,再还原一次
|
|
rollback(arIds);
|
|
}
|
|
|
|
void AecDbXCamera::getGripPoints(AcGePoint3dArray &ar) const
|
|
{
|
|
ar.removeAll();
|
|
if (GetUsageMode() == eVerti)
|
|
{
|
|
/*
|
|
垂直剖切
|
|
上层
|
|
pt0-----------pt1-----------pt2
|
|
V V
|
|
V V
|
|
V V
|
|
V V
|
|
V V
|
|
pt5-----------pt4-----------pt3
|
|
|
|
pt1 移动眼睛位置
|
|
pt0,pt2 修改视口宽度
|
|
pt4 修改 视口的纵深 既 m_vtEye 的长度
|
|
pt5,pt3 旋转 m_vtEye 的方向
|
|
|
|
最后一个 pt10 是输出结果的位置点
|
|
|
|
下层
|
|
pt6-------------------------pt7
|
|
V V
|
|
V V
|
|
V V
|
|
V V
|
|
V V
|
|
pt9-----------pt10----------pt8
|
|
*/
|
|
AcGeVector3d vtEye(GetEyeDirect());
|
|
AcGeVector3d vt(vtEye);
|
|
vt.rotateBy(PI * .5, AcGeVector3d::kZAxis);
|
|
vt.normalize();
|
|
vt *= GetWidth() * .5;
|
|
AcGePoint3d ptEye(GetEyePoint());
|
|
AcGePoint3d pt1(ptEye), pt0(ptEye - vt), pt2(ptEye + vt);
|
|
AcGePoint3d pt3 = pt2 + vtEye, pt5 = pt0 + vtEye, pt4 = pt1 + vtEye;
|
|
|
|
pt0.z = pt1.z = pt2.z = pt3.z = pt4.z = pt5.z = GetHorizTop();
|
|
ar.append(pt0);
|
|
ar.append(pt1);
|
|
ar.append(pt2);
|
|
ar.append(pt3);
|
|
ar.append(pt4);
|
|
ar.append(pt5);
|
|
|
|
AcGePoint3d pt6(pt0), pt7(pt2), pt8(pt3), pt9(pt5), pt10(pt4);
|
|
pt6.z = pt7.z = pt8.z = pt9.z = pt10.z = GetHorizBottom();
|
|
ar.append(pt6);
|
|
ar.append(pt7);
|
|
ar.append(pt8);
|
|
ar.append(pt9);
|
|
ar.append(pt10);
|
|
}
|
|
else if (GetUsageMode() == eHoriz)
|
|
{
|
|
/*
|
|
水平剖切
|
|
上层
|
|
pt0-------------------------pt1
|
|
| |
|
|
| |
|
|
| pt4 |
|
|
| |
|
|
| |
|
|
pt3---------pt9-------------pt2
|
|
|
|
下层
|
|
pt5-------------------------pt6
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
| |
|
|
pt8---------pt10------------pt7
|
|
|
|
上层是 pt0 ,pt1, pt2, pt3, pt4(pt0, pt1中点, 既是eye点)
|
|
下层是 pt5 ,pt6, pt7, pt8
|
|
|
|
pt9(pt3, pt2 中点)
|
|
pt10(pt8, pt7 中点)
|
|
pt11(输出结果的位置点)
|
|
|
|
功能:
|
|
pt0-pt3,改变矩形框大小
|
|
当不是水平俯视图的时候 pt9,pt10 改变视口深度
|
|
*/
|
|
AcGePoint3d pt4(GetEyePoint());
|
|
double dW(GetWidth()), dH(GetHeight());
|
|
AcGePoint3d pt0(pt4);
|
|
pt0.x -= dW * .5;
|
|
pt0.y += dH * .5;
|
|
AcGePoint3d pt1(pt0);
|
|
pt1.x += dW;
|
|
AcGePoint3d pt2(pt1);
|
|
pt2.y -= dH;
|
|
AcGePoint3d pt3(pt2);
|
|
pt3.x -= dW;
|
|
|
|
AcGePoint3d pt9(CoreTools::MidPt(pt3, pt2));
|
|
pt0.z = pt1.z = pt2.z = pt3.z = pt4.z = pt9.z = GetHorizTop();
|
|
|
|
AcGePoint3d pt5(pt0), pt6(pt1), pt7(pt2), pt8(pt3), pt10(pt9);
|
|
pt5.z = pt6.z = pt7.z = pt8.z = pt10.z = GetHorizBottom();
|
|
|
|
ar.append(pt0);
|
|
ar.append(pt1);
|
|
ar.append(pt2);
|
|
ar.append(pt3);
|
|
ar.append(pt4);
|
|
ar.append(pt5);
|
|
ar.append(pt6);
|
|
ar.append(pt7);
|
|
ar.append(pt8);
|
|
ar.append(pt9);
|
|
ar.append(pt10);
|
|
}
|
|
|
|
AcGePoint3d ptLT, ptRT, ptRB, ptLB;
|
|
if (getResultBox(ptLT, ptRT, ptRB, ptLB))
|
|
{
|
|
ar.append(CoreTools::MidPt(ptLB, ptRB));
|
|
}
|
|
else
|
|
ar.append(GetOutputPoint());
|
|
}
|
|
|
|
AcDbExtents AecDbXCamera::getResultExtent() const
|
|
{
|
|
AcDbExtents ext, _ext;
|
|
for (int i(0); i < m_arResults.length(); ++i)
|
|
{
|
|
AcDbEntityPointer ent(m_arResults[i], AcDb::kForRead);
|
|
if (ent.openStatus() == Acad::eOk)
|
|
{
|
|
ent->getGeomExtents(_ext);
|
|
ext.addExt(_ext);
|
|
}
|
|
}
|
|
return ext;
|
|
}
|
|
|
|
bool AecDbXCamera::getResultBox(AcGePoint3d &ptLT
|
|
, AcGePoint3d &ptRT
|
|
, AcGePoint3d &ptRB
|
|
, AcGePoint3d &ptLB) const
|
|
{
|
|
if (m_arResults.isEmpty()) return false;
|
|
|
|
AcDbExtents ext(getResultExtent());
|
|
|
|
AcGePoint3d ptIns(CoreTools::MidPt(ext.maxPoint(), ext.minPoint()));
|
|
double dX(ext.maxPoint().x - ext.minPoint().x)
|
|
, dY(ext.maxPoint().y - ext.minPoint().y);
|
|
|
|
double dDelta(dX > dY ? dY * .1 : dX * .1);
|
|
dX += dDelta;
|
|
dY += dDelta;
|
|
|
|
ptLB = ptIns;
|
|
ptRB = ptIns;
|
|
ptLB.x -= dX * .5;
|
|
ptLB.y -= dY * .5;
|
|
ptRB.x += dX * .5;
|
|
ptRB.y -= dY * .5;
|
|
|
|
ptRT = ptRB;
|
|
ptLT = ptLB;
|
|
ptRT.y += dY;
|
|
ptLT.y += dY;
|
|
|
|
return true;
|
|
}
|
|
|
|
AecDbObjXDataMap *AecDbXCamera::GetSpecialtyData(AcDb::OpenMode bMode)
|
|
{
|
|
if (bMode == AcDb::kForWrite)
|
|
AssertWriteEnabled();
|
|
else
|
|
assertReadEnabled();
|
|
|
|
return &m_mapSpecXData;
|
|
}
|
|
|
|
const AecDbObjXDataMap *AecDbXCamera::GetSpecialtyData() const
|
|
{
|
|
assertReadEnabled();
|
|
return &m_mapSpecXData;
|
|
}
|
|
|
|
void AecDbXCamera::eraseEnt(AcDbObjectId & id, Adesk::Boolean erasing)
|
|
{
|
|
::eraseEnt(id, erasing);
|
|
}
|
|
|
|
void AecDbXCamera::eraseEnts(AcDbObjectIdArray & ids, Adesk::Boolean erasing)
|
|
{
|
|
for (int i(0); i < ids.length(); ++i)
|
|
eraseEnt(ids[i]);
|
|
ids.removeAll();
|
|
}
|
|
|
|
resbuf* AecDbXCamera::getSelectTypeResbuf()
|
|
{
|
|
// 构筑物单独处理
|
|
return acutBuildList(
|
|
RTDXF0, _T("AEC_*,INSERT")
|
|
, -4, _T("<not")
|
|
, -4, _T("<or")
|
|
, RTDXF0, _T("AEC_XCAMERA")
|
|
, RTDXF0, _T("AEC_JOGGEDCAMERA")
|
|
, RTDXF0, _T("AEC_PFDIM")
|
|
, RTDXF0, _T("AEC_ZUOBIAOBIAOZHU")
|
|
, RTDXF0, _T("AEC_BIAOGAOBIAOZHU")
|
|
, RTDXF0, _T("AEC_JIANTOUYINZHU")
|
|
, RTDXF0, _T("AEC_YINCHUBIAOZU")
|
|
, RTDXF0, _T("AEC_ZUOFABIAOZHU")
|
|
, RTDXF0, _T("AEC_SUOYINTUMING")
|
|
, RTDXF0, _T("AEC_POQIE")
|
|
, RTDXF0, _T("AEC_YUNXIAN")
|
|
, RTDXF0, _T("AEC_ZHEDUANXIAN")
|
|
, RTDXF0, _T("AEC_DUICHENZHOU")
|
|
, RTDXF0, _T("AEC_ZHIBEIZHEN")
|
|
, RTDXF0, _T("AEC_TUMINGBIAOZHU")
|
|
, RTDXF0, _T("AEC_CHICUNBIAOZHU")
|
|
, RTDXF0, _T("AEC_BANJINGBIAOZHU")
|
|
, RTDXF0, _T("AEC_EWPIPEDIM")
|
|
, RTDXF0, _T("AEC_DIRPS")
|
|
, -4, _T("or>")
|
|
, -4, _T("not>")
|
|
, 0);
|
|
}
|
|
|
|
void AecDbXCamera::updateSelecttionSet(const AcDbObjectIdArray &ids)
|
|
{
|
|
AssertWriteEnabled();
|
|
m_arSelectionSet.removeAll();
|
|
m_arSelectionSet.append(ids);
|
|
|
|
if (m_arSelectionSet.isEmpty()) return;
|
|
|
|
AcDbExtents ext, _ext;
|
|
for (int i(0); i < m_arSelectionSet.length(); ++i)
|
|
{
|
|
AcDbEntityPointer ent(m_arSelectionSet[i], AcDb::kForRead);
|
|
if (ent.openStatus() != Acad::eOk) continue;
|
|
|
|
ent->getGeomExtents(_ext);
|
|
ext.addExt(_ext);
|
|
}
|
|
|
|
AcGePoint3d ptMax(ext.maxPoint()), ptMin(ext.minPoint());
|
|
|
|
double dW(ptMax.x - ptMin.x), dH(ptMax.y - ptMin.y);
|
|
AcGeVector3d vtEye(-AcGeVector3d::kZAxis * (ptMax.z - ptMin.z));
|
|
AcGePoint3d ptEye(CoreTools::MidPt(ptMax, ptMin));
|
|
SetEyePoint(ptEye);
|
|
SetEyeDirect(vtEye);
|
|
SetHorizTop(ptMax.z);
|
|
SetHorizBottom(ptMin.z);
|
|
SetWidth(dW);
|
|
SetHeight(dH);
|
|
|
|
refresh(true);
|
|
}
|
|
|
|
|
|
void AecDbXCamera::collectEnvelope(const AcDbObjectIdArray &arids
|
|
, AcDbObjectIdArray &arOther
|
|
, AcDbObjectIdArray &arEnve)
|
|
{
|
|
for (int i(0); i < arids.length(); ++i)
|
|
{
|
|
const AcDbObjectId &id(arids[i]);
|
|
if (isEnvelope(id))
|
|
arEnve.append(id);
|
|
else
|
|
arOther.append(id);
|
|
}
|
|
}
|
|
|
|
void AecDbXCamera::collectEnvelope(AcDbObjectIdArray &arids) const
|
|
{
|
|
assertReadEnabled();
|
|
struct resbuf *pointlist(getCollectArea());
|
|
if (pointlist)
|
|
{
|
|
struct resbuf *pRb = HlrCutOption::getEnvelopeFilter();
|
|
if (pRb)
|
|
{
|
|
collectEnities(pRb, pointlist, arids);
|
|
acutRelRb(pRb);
|
|
}
|
|
acutRelRb(pointlist);
|
|
}
|
|
}
|
|
|
|
void AecDbXCamera::collectAxisObject(AcDbObjectIdArray &arids) const
|
|
{
|
|
assertReadEnabled();
|
|
struct resbuf *pointlist(getCollectArea());
|
|
struct resbuf *pRb(NULL);
|
|
if (GetUsageMode() == eHoriz) // 水平
|
|
{ // 水平,需要 轴号,标注,轴网
|
|
pRb = acutBuildList(
|
|
-4, _T("<or")
|
|
, -4, _T("<and"), RTDXF0, _T("LINE"), 8, _T("Dote"), -4, _T("and>")
|
|
, -4, _T("<and"), RTDXF0, _T("LINE"), 8, _T("AXISTXT"), -4, _T("and>")
|
|
, -4, _T("<and"), RTDXF0, _T("INSERT"), 8, _T("AXISTXT"), 2 , _T("_AXISO"), -4, _T("and>")
|
|
, -4, _T("<and"), RTDXF0, _T("DIMENSION"), 8, _T("AXISTXT"), -4, _T("and>")
|
|
, -4, _T("or>")
|
|
, 0);
|
|
|
|
}
|
|
else if ((GetUsageMode() == eVerti))
|
|
{ // 垂直,需要 轴号,轴网
|
|
pRb = acutBuildList(
|
|
-4, _T("<or")
|
|
, -4, _T("<and"), RTDXF0, _T("LINE"), 8, _T("Dote"), 62, 256, -4, _T("and>")
|
|
, -4, _T("or>")
|
|
, 0);
|
|
}
|
|
|
|
collectEnities(pRb, pointlist, arids);
|
|
acutRelRb(pRb);
|
|
acutRelRb(pointlist);
|
|
}
|
|
|
|
void AecDbXCamera::moveOutput(const AcGeVector3d &vtOffset)
|
|
{
|
|
SetOutputPoint(GetOutputPoint() + 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);
|
|
}
|
|
}
|
|
|
|
AcDbPolyline* AecDbXCamera::getSectionPolygon()
|
|
{
|
|
AcGePoint3d ptEye(GetEyePoint())
|
|
, pt1(AcGePoint3d::kOrigin)
|
|
, pt2(AcGePoint3d::kOrigin)
|
|
, pt3(AcGePoint3d::kOrigin)
|
|
, pt4(AcGePoint3d::kOrigin);
|
|
ptEye.z = .0;
|
|
AcGeVector3d X(AcGeVector3d::kXAxis), Y(AcGeVector3d::kYAxis), Z(AcGeVector3d::kZAxis);
|
|
|
|
AcGePoint3dArray ar;
|
|
getGripPoints(ar);
|
|
|
|
AcDbPolyline *pPoly = new AcDbPolyline;
|
|
if (GetUsageMode() == eVerti && ar.length() > 7)
|
|
{
|
|
// 前面应该调用 getEelevRange() 分析出最大最小标高
|
|
double dTop(GetHorizTop()), dBottom(GetHorizBottom());
|
|
pt1 = ar[0];
|
|
pt2 = ar[2];
|
|
pt3 = ar[7];
|
|
pt4 = ar[6];
|
|
|
|
AcGeVector3d vecNormal(GetEyeDirect().normal());
|
|
|
|
AcGeMatrix3d matWcs2Ocs;
|
|
matWcs2Ocs.setToWorldToPlane(vecNormal);
|
|
pt1.transformBy(matWcs2Ocs);
|
|
pt2.transformBy(matWcs2Ocs);
|
|
pt3.transformBy(matWcs2Ocs);
|
|
pt4.transformBy(matWcs2Ocs);
|
|
|
|
pPoly->setNormal(vecNormal);
|
|
pPoly->setElevation(pt1.z);
|
|
pPoly->addVertexAt(0, AcGePoint2d(pt1.x, pt1.y));
|
|
pPoly->addVertexAt(1, AcGePoint2d(pt2.x, pt2.y));
|
|
pPoly->addVertexAt(2, AcGePoint2d(pt3.x, pt3.y));
|
|
pPoly->addVertexAt(3, AcGePoint2d(pt4.x, pt4.y));
|
|
pPoly->setClosed(Adesk::kTrue);
|
|
}
|
|
else if (GetUsageMode() == eHoriz)
|
|
{
|
|
pt1 = ar[0];
|
|
pt2 = ar[1];
|
|
pt3 = ar[2];
|
|
pt4 = ar[3];
|
|
pPoly->setNormal(Z);
|
|
pPoly->setElevation(.0);
|
|
pPoly->addVertexAt(0, pt1.convert2d(AcGePlane::kXYPlane));
|
|
pPoly->addVertexAt(1, pt2.convert2d(AcGePlane::kXYPlane));
|
|
pPoly->addVertexAt(2, pt3.convert2d(AcGePlane::kXYPlane));
|
|
pPoly->addVertexAt(3, pt4.convert2d(AcGePlane::kXYPlane));
|
|
pPoly->setClosed(Adesk::kTrue);
|
|
}
|
|
|
|
return pPoly;
|
|
}
|
|
|
|
bool AecDbXCamera::GetProperties(SimpleProperty::PropertySetByIndex &properties) const
|
|
{
|
|
AecDbEntityBase::GetProperties(properties);
|
|
CoreTools::setLayerPorperty(properties);
|
|
|
|
SimpleProperty::makeAndInsert(properties, _T("剖面上标高"), GetHorizTop(), true);
|
|
SimpleProperty::makeAndInsert(properties, _T("剖面下标高"), GetHorizBottom(), true);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool AecDbXCamera::SetProperties(SimpleProperty::PropertySetByName &properties)
|
|
{
|
|
if (properties.m_set.empty())
|
|
return false;
|
|
|
|
AecDbEntityBase::SetProperties(properties);
|
|
|
|
double dVal(.0);
|
|
if (properties.findAndSet(_T("剖面上标高"), dVal))
|
|
SetHorizTop(dVal);
|
|
if (properties.findAndSet(_T("剖面下标高"), dVal))
|
|
SetHorizBottom(dVal);
|
|
|
|
return true;
|
|
}
|
|
|
|
#pragma region JIG
|
|
XCameraJig_V::XCameraJig_V(void): m_pPolyline(NULL)
|
|
{
|
|
m_pPolyline = new AcDbPolyline;
|
|
}
|
|
|
|
XCameraJig_V::~XCameraJig_V(void)
|
|
{
|
|
DELETE_PTR(m_pPolyline);
|
|
}
|
|
|
|
AcEdJig::DragStatus XCameraJig_V::DoIt()
|
|
{
|
|
AcEdJig::DragStatus eStat;
|
|
if (m_nStep == 0)
|
|
{
|
|
setDispPrompt(_T("\n指定第二点:"));
|
|
eStat = drag();
|
|
}
|
|
else if (m_nStep == 1)
|
|
{
|
|
setDispPrompt(_T("\n指定剖切范围和方向:"));
|
|
eStat = drag();
|
|
}
|
|
else
|
|
{
|
|
setDispPrompt(_T("\n指定生成结果的位置:"));
|
|
eStat = drag();
|
|
}
|
|
return eStat;
|
|
}
|
|
|
|
AcEdJig::DragStatus XCameraJig_V::sampler()
|
|
{
|
|
setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted));
|
|
m_pPolyline->reset(false, 0);
|
|
AcEdJig::DragStatus eStat;
|
|
if (m_nStep == 0)
|
|
{
|
|
eStat = acquirePoint(m_ptEnd, m_ptStart);
|
|
if (eStat == AcEdJig::kNormal)
|
|
{
|
|
if (m_ptEnd == m_ptStart)
|
|
return AcEdJig::kNoChange;
|
|
|
|
m_ptEnd.z = .0;
|
|
|
|
m_ptEye = CoreTools::MidPt(m_ptEnd, m_ptStart);
|
|
}
|
|
}
|
|
else if (m_nStep == 1)
|
|
{
|
|
eStat = acquirePoint(m_ptDir, m_ptEye);
|
|
if (eStat == AcEdJig::kNormal)
|
|
{
|
|
if (m_ptDir == m_ptEye)
|
|
return AcEdJig::kNoChange;
|
|
m_ptDir.z = .0;
|
|
AcDbLine line(m_ptStart, m_ptEnd);
|
|
AcGePoint3d ptClosed;
|
|
line.getClosestPointTo(m_ptDir, ptClosed, Adesk::kTrue);
|
|
m_vtEye = m_ptDir - ptClosed;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eStat = acquirePoint(m_ptOutput, m_ptEye);
|
|
m_ptOutput.z = .0;
|
|
}
|
|
return eStat;
|
|
}
|
|
|
|
AcDbEntity *XCameraJig_V::entity() const
|
|
{
|
|
return m_pPolyline;
|
|
}
|
|
|
|
Adesk::Boolean XCameraJig_V::update()
|
|
{
|
|
if (m_nStep >= 0)
|
|
{
|
|
double dw = CoreTools::PixelToWcs(10);
|
|
m_pPolyline->addVertexAt(0, m_ptStart.convert2d(AcGePlane::kXYPlane));
|
|
m_pPolyline->addVertexAt(1, m_ptEnd.convert2d(AcGePlane::kXYPlane));
|
|
m_pPolyline->setWidthsAt(0, dw, dw);
|
|
}
|
|
if (m_nStep >= 1)
|
|
{
|
|
AcGePoint3d ptS2(m_ptStart + m_vtEye), ptE2(m_ptEnd + m_vtEye);
|
|
m_pPolyline->addVertexAt(2, ptE2.convert2d(AcGePlane::kXYPlane));
|
|
m_pPolyline->addVertexAt(3, ptS2.convert2d(AcGePlane::kXYPlane));
|
|
m_pPolyline->setClosed(Adesk::kTrue);
|
|
}
|
|
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
XCameraJig_H::XCameraJig_H(void): m_pPolyline(NULL)
|
|
{
|
|
m_pPolyline = new AcDbPolyline;
|
|
}
|
|
|
|
XCameraJig_H::~XCameraJig_H(void)
|
|
{
|
|
DELETE_PTR(m_pPolyline);
|
|
}
|
|
|
|
AcEdJig::DragStatus XCameraJig_H::DoIt()
|
|
{
|
|
AcEdJig::DragStatus eStat;
|
|
if (m_nStep == 0)
|
|
{
|
|
setDispPrompt(_T("\n指定切面范围第二点:"));
|
|
eStat = drag();
|
|
}
|
|
else if (m_nStep == 1)
|
|
{
|
|
setDispPrompt(_T("\n指定生成结果的位置:"));
|
|
eStat = drag();
|
|
}
|
|
return eStat;
|
|
}
|
|
|
|
AcEdJig::DragStatus XCameraJig_H::sampler()
|
|
{
|
|
setUserInputControls((UserInputControls)(AcEdJig::kAccept3dCoordinates
|
|
| AcEdJig::kNullResponseAccepted));
|
|
AcEdJig::DragStatus eStat;
|
|
if (m_nStep == 0)
|
|
{
|
|
eStat = acquirePoint(m_ptRB, m_ptLT);
|
|
if (eStat == AcEdJig::kNormal)
|
|
{
|
|
if (m_ptRB == m_ptLT)
|
|
return AcEdJig::kNoChange;
|
|
|
|
m_ptRB.z = .0;
|
|
|
|
m_ptEye = CoreTools::MidPt(m_ptRB, m_ptLT);
|
|
|
|
m_ptLB = m_ptLT;
|
|
m_ptLB.y = m_ptRB.y;
|
|
|
|
m_ptRT = m_ptRB;
|
|
m_ptRT.y = m_ptLT.y;
|
|
}
|
|
}
|
|
else if (m_nStep == 1)
|
|
{
|
|
eStat = acquirePoint(m_ptOutput, m_ptEye);
|
|
m_ptOutput.z = .0;
|
|
}
|
|
return eStat;
|
|
}
|
|
|
|
AcDbEntity *XCameraJig_H::entity() const
|
|
{
|
|
return m_pPolyline;
|
|
}
|
|
|
|
Adesk::Boolean XCameraJig_H::update()
|
|
{
|
|
if (m_nStep >= 0)
|
|
{
|
|
m_pPolyline->reset(false, 0);
|
|
double dw = CoreTools::PixelToWcs(10);
|
|
m_pPolyline->addVertexAt(0, m_ptLT.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
|
|
m_pPolyline->addVertexAt(1, m_ptRT.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
|
|
m_pPolyline->addVertexAt(2, m_ptRB.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
|
|
m_pPolyline->addVertexAt(3, m_ptLB.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
|
|
m_pPolyline->addVertexAt(4, m_ptLT.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
|
|
}
|
|
//if (m_nStep >= 1)
|
|
//{
|
|
// AcGePoint3d ptS2(m_ptStart + m_vtEye), ptE2(m_ptEnd + m_vtEye);
|
|
// m_pPolyline->addVertexAt(2, ptE2.convert2d(AcGePlane::kXYPlane));
|
|
// m_pPolyline->addVertexAt(3, ptS2.convert2d(AcGePlane::kXYPlane));
|
|
// m_pPolyline->setClosed(Adesk::kTrue);
|
|
//}
|
|
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
#pragma endregion
|
|
|