Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/TGKatana.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

925 lines
24 KiB
C++

#include "StdAfx.h"
#include "TGKatana.h"
#include "TArchPerDocData.h"
#include "TArchDocReactor.h"
#include "TArchAppDocGlobals.h"
static std::vector<AcDbObjectId> g_deepCloneKatanas;
namespace
{
enum KAFLAG
{
eEndKatana = 0,
eBegKatana,
eLeftWall,
eRightWall,
};
// 判断两墙共线 true 共线
bool _JudgeCollinear(const TDbWall *pLeft, const TDbWall *pRight)
{
if (!pLeft || !pRight) return false;
if (pLeft->GetWidth() != pRight->GetWidth()) return false;
if (pLeft->GetMaterialIndex() != pRight->GetMaterialIndex()) return false;
if (pLeft->GetCurveType() != pRight->GetCurveType()) return false;
if (pLeft->EndPoint() != pRight->StartPoint()) return false;
if (pLeft->Is(CURVE_LINE))
{
TGGeCurveSegment seg = *pLeft;
seg.SetPoints(pLeft->StartPoint(), pRight->EndPoint());
double dist = seg.GetDist2Me(pLeft->EndPoint());
if (!EQUAL_ZERO(dist)) return false;
}
else if (pLeft->Is(CURVE_ARC))
{
// 上面算法,理论上可以兼容 直墙和弧墙,不过,TGGeCurveSegment 的 SetPoints()应该有BUG.
// 导致弧墙结果不正确. 现在用判断圆心法
TGGeArc arcLeft = pLeft->GetArc();
TGGeArc arcRight = pRight->GetArc();
if (arcLeft.GetCenterPt() != arcRight.GetCenterPt())
return false;
}
return true;
}
// 取曲线上的一点, offset 是 此点与 起点 或 终点 的距离. bstart 为真时, 是起点
AcGePoint3d _GetCurvePoint(TGGeCurveSegment &curve, bool bstart, double &offset )
{
TADSGePointDir2d res;
curve.Polar(offset, res, bstart ? 1 : 0);
return AcGePoint3d(res.x, res.y, res.z);
}
// 取实体外包框最 大/小 点 在 base 上的投影
void _GetEntLimtPtInBase(TDbEntity *pEnt, TGGeCurveSegment &base, TADSGePoint3d &ptLow, TADSGePoint3d &ptUP)
{
pEnt->GetExtents(ptLow, ptUP);
TDbOpening *pOpening = TDbOpening::cast(pEnt);
if (pOpening)
{
pOpening->GetSidePointsOnBase(ptUP, ptLow);
}
else
{
base.ProjectToMe(ptLow, ptLow);
base.ProjectToMe(ptUP, ptUP);
}
}
// 判断点是否在 门窗/pathc 上, 如果在,则返回离其最近的一点
// true - 在 门窗/patch 上
bool _JudgePtInOpeningAndPatch(TDbWall *pWall, const TADSGePoint3d &pt, TADSGePoint3d &ptNew)
{
TDPtrList<AcDbSoftPointerId>* plstO = const_cast< TDPtrList<AcDbSoftPointerId>* >(&(pWall->GetOpeningIdList()));
TDPtrList<AcDbSoftPointerId>* plstP = const_cast< TDPtrList<AcDbSoftPointerId>* >(&(pWall->GetPatchIdList()));
TDPtrList<AcDbSoftPointerId> lstO, lstP;
lstO.copyFrom(*plstO);
lstP.copyFrom(*plstP);
lstO << lstP;
TGGeCurveSegment seg(*pWall);
for (int i = 0; i < lstO.Length(); ++i)
{
OPENOBJ_BEGIN(*lstO[i], AcDb::kForWrite, TDbEntity, pO)
if (pO)
{
TADSGePoint3d pt1, pt2, ptMid;
_GetEntLimtPtInBase(pO, seg, pt1, pt2);
if (seg.PathDistance(pt1, 1) < seg.PathDistance(pt2, 1))
seg.SetPoints(pt1, pt2);
else
seg.SetPoints(pt2, pt1);
int flag = pt & seg;
if (flag == PR_INSIDE || flag == PR_ONPT1 || flag == PR_ONPT2) // 如果点在门窗内
{
if (seg.PathDistance(pt, 1) <= seg.PathDistance(pt, 0)) // 离起点近,返回起点
ptNew = seg.StartPoint();
else
ptNew = seg.EndPoint();
return true;
}
}
OPENOBJ_END()
}
return false;
}
// 将 pSrc 墙上 seg 曲线 上的 门窗 patch 实体,移动到 pDesc 墙上
// 算法不考虑seg的起/始点跨 门窗 patch 的情况.
void _ProcessOpeningAndPatch(TDbWall *pSrc, TDbWall *pDesc, TGGeCurveSegment &seg)
{
TDPtrList<AcDbSoftPointerId>* plstO = const_cast< TDPtrList<AcDbSoftPointerId>* >(&(pSrc->GetOpeningIdList()));
TDPtrList<AcDbSoftPointerId>* plstP = const_cast< TDPtrList<AcDbSoftPointerId>* >(&(pSrc->GetPatchIdList()));
TDPtrList<AcDbSoftPointerId> lstO, lstP;
lstO.copyFrom(*plstO);
lstP.copyFrom(*plstP);
lstO << lstP;
std::vector<AcDbObjectId> ids;
TGGeCurveSegment segTmp(seg);
for (int i = 0; i < lstO.Length(); ++i)
{
AcDbObjectId id = *lstO[i];
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbEntity, pO)
if (pO)
{
TADSGePoint3d pt1, pt2, ptMid;
_GetEntLimtPtInBase(pO, seg, pt1, pt2);
if (seg.PathDistance(pt1, 1) < seg.PathDistance(pt2, 1))
segTmp.SetPoints(pt1, pt2);
else
segTmp.SetPoints(pt2, pt1);
ptMid = segTmp.MidPoint();
if ((ptMid & seg) == PR_INSIDE) // 点在seg上,说明门窗也在
ids.push_back(id);
}
OPENOBJ_END()
}
AcDbEntity *pEnt(NULL);
for (size_t i = 0; i < ids.size(); ++i)
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, ids[i], AcDb::kForRead))
{
if (pEnt->cast(TDbWallPatch::desc()))
{
pEnt->close();
pSrc->MoveOnePatchTo(*pDesc, ids[i]);
}
else
{
pEnt->close();
pSrc->MoveOneOpeningTo(*pDesc, ids[i]);
}
}
}
}
// 判断点否在墙外,如在墙外,则给出离墙距离 dOffset 的一点
// 如果点在墙内,但与 起/终 点距离小于 dOffset 也返回离墙距离 dOffset 的一点
// bLeft 是否是左墙
// true ptNew 有新值
bool _JudgePtInWall(TDbWall *pWall, const TADSGePoint3d &pt, TADSGePoint3d &ptNew, double &dOffset, bool bLeft)
{
TGGeCurveSegment segL, segR, seg;
pWall->GetSideCurve(segL, segR);
if (UPEQUAL_ZERO(segL.GetLength() - segR.GetLength())) // 取最短一条边,要求pt不能超过
seg = segR;
else
seg = segL;
TADSGePoint3d ptOn;
seg.ProjectToMe(pt, ptOn);
int flag = ptOn & seg;
if (flag != PR_INSIDE)
{
if (seg.PathDistance(ptOn, 1) < seg.PathDistance(ptOn, 0))
ptNew = _GetCurvePoint(seg, true, dOffset);
else
ptNew = _GetCurvePoint(seg, false, dOffset);
return true;
}
else
{
if (bLeft && seg.PathDistance(ptOn, 1) < dOffset)
ptNew = _GetCurvePoint(seg, true, dOffset);
else if (!bLeft && seg.PathDistance(ptOn, 0) < dOffset)
ptNew = _GetCurvePoint(seg, false, dOffset);
else
return false;
return true;
}
return false;
}
AcDbObjectId _GetOtherWallId(TDbWall *pWall, bool bStart)
{
AcDbObjectId kaID = bStart ? pWall->GetStartKatanaID() : pWall->GetEndKatanaID();
OPENOBJ_BEGIN(kaID, AcDb::kForRead, CGlwKatana, pKa)
if (pKa)
{
if (pKa->GetLeftWallID() == pWall->objectId())
return pKa->GetRightWallID();
else if (pKa->GetRightWallID() == pWall->objectId())
return pKa->GetLeftWallID();
}
OPENOBJ_END()
return AcDbObjectId::kNull;
}
void _UnRegisterReactor(/*CGlwKatana *pKa, */TDbWall *pLeft, TDbWall *pRight)
{
if (/*!pKa || */!pLeft || !pRight) return;
if (/*!pKa->isWriteEnabled() || */!pLeft->isWriteEnabled() || !pRight->isWriteEnabled()) return;
// pKa->removePersistentReactor(pLeft->objectId());
// pKa->removePersistentReactor(pRight->objectId());
pLeft->removePersistentReactor(pRight->objectId());
pRight->removePersistentReactor(pLeft->objectId());
}
void _UnRegisterReactor(CGlwKatana *pK)
{
if (pK && pK->isWriteEnabled())
{
OPENOBJ_BEGIN(pK->GetLeftWallID(), AcDb::kForWrite, TDbWall, pLeft)
OPENOBJ_BEGIN(pK->GetRightWallID(), AcDb::kForWrite, TDbWall, pRight)
if (pLeft && pRight)
_UnRegisterReactor(/*pK, */pLeft, pRight);
OPENOBJ_END()
OPENOBJ_END()
}
}
void _UnRegisterReactor(AcDbObjectId &kaID)
{
OPENOBJ_BEGIN(kaID, AcDb::kForWrite, CGlwKatana, pK)
if (pK)
_UnRegisterReactor(pK);
OPENOBJ_END()
}
void _RegisterReactor(/*CGlwKatana *pKa, */TDbWall *pLeft, TDbWall *pRight)
{
if (/*!pKa || */!pLeft || !pRight) return;
if (/*!pKa->isWriteEnabled() || */!pLeft->isWriteEnabled() || !pRight->isWriteEnabled()) return;
// pKa->addPersistentReactor(pLeft->objectId());
// pKa->addPersistentReactor(pRight->objectId());
pLeft->addPersistentReactor(pRight->objectId());
pRight->addPersistentReactor(pLeft->objectId());
}
void _RegisterReactor(CGlwKatana *pK)
{
if (pK && pK->isWriteEnabled())
{
OPENOBJ_BEGIN(pK->GetLeftWallID(), AcDb::kForWrite, TDbWall, pLeft)
OPENOBJ_BEGIN(pK->GetRightWallID(), AcDb::kForWrite, TDbWall, pRight)
if (pLeft && pRight)
_RegisterReactor(/*pK, */pLeft, pRight);
OPENOBJ_END()
OPENOBJ_END()
}
}
void _RegisterReactor(AcDbObjectId &kaID)
{
OPENOBJ_BEGIN(kaID, AcDb::kForWrite, CGlwKatana, pK)
if (pK)
_RegisterReactor(pK);
OPENOBJ_END()
}
AcDbObjectId _GetKatanaByWall(TDbWall *pWall, KAFLAG flag)
{
if (pWall)
{
switch (flag)
{
case eBegKatana:
return pWall->GetStartKatanaID();
case eEndKatana:
return pWall->GetEndKatanaID();
default:
return AcDbObjectId::kNull;
}
}
return AcDbObjectId::kNull;
}
AcDbObjectId _GetKatanaByWall(const AcDbObjectId &WallID, KAFLAG flag)
{
OPENOBJ_BEGIN(WallID, AcDb::kForWrite, TDbWall, pWall)
if (pWall)
return _GetKatanaByWall(pWall, flag);
OPENOBJ_END()
return AcDbObjectId::kNull;
}
void _SetKatanaForWall(TDbWall *pWall, const AcDbObjectId &KaID, KAFLAG flag)
{
if (pWall)
{
switch (flag)
{
case eBegKatana:
pWall->SetStartKatanaID(KaID);
break;
case eEndKatana:
pWall->SetEndKatanaID(KaID);
break;
default:
break;
}
}
}
void _SetKatanaForWall(const AcDbObjectId & WallID, const AcDbObjectId &KaID, KAFLAG flag)
{
OPENOBJ_BEGIN(WallID, AcDb::kForWrite, TDbWall, pWall)
if (pWall)
_SetKatanaForWall(pWall, KaID, flag);
OPENOBJ_END()
}
AcDbObjectId _GetWallByKatana(CGlwKatana *pKa, KAFLAG flag)
{
if (pKa)
{
switch (flag)
{
case eLeftWall:
return pKa->GetLeftWallID();
case eRightWall:
return pKa->GetRightWallID();
default:
return AcDbObjectId::kNull;
}
}
return AcDbObjectId::kNull;
}
AcDbObjectId _GetWallByKatana(AcDbObjectId &KaID, KAFLAG flag)
{
OPENOBJ_BEGIN(KaID, AcDb::kForWrite, CGlwKatana, pK)
if (pK)
return _GetWallByKatana(pK, flag);
OPENOBJ_END()
return AcDbObjectId::kNull;
}
void _SetWallForKatana(CGlwKatana *pK, AcDbObjectId & WallID, KAFLAG flag)
{
if (pK)
{
switch (flag)
{
case eLeftWall:
pK->SetLeftWallID(WallID);
break;
case eRightWall:
pK->SetRightWallID(WallID);
break;
default:
break;
}
}
}
void _SetWallForKatana(AcDbObjectId & WallID, AcDbObjectId &KaID, KAFLAG flag)
{
OPENOBJ_BEGIN(KaID, AcDb::kForWrite, CGlwKatana, pK)
if (pK)
_SetWallForKatana(pK, WallID, flag);
OPENOBJ_END()
}
void _ModifyKatana(CGlwKatana *pK)
{
if (!pK) return;
if (!pK->IsDragGripPt())
return;
else
pK->SetIsDragGripPt(false);
_UnRegisterReactor(pK);
OPENOBJ_BEGIN(pK->GetLeftWallID(), AcDb::kForWrite,TDbWall, pLWall)
OPENOBJ_BEGIN(pK->GetRightWallID(), AcDb::kForWrite,TDbWall, pRWall)
if (pRWall && pLWall)
{
AcDbLine line(pK->GetLeftPt(), pK->GetRightPt());
AcGePoint3dArray pts;
Acad::ErrorStatus es;
es = pLWall->intersectWith(&line, AcDb::kExtendThis, AcGePlane::kXYPlane, pts);
if (es != Acad::eOk) return;
if (pts.isEmpty()) return;
// 在 修改墙体长度之前,应把移动范围内的门窗与墙附件进行移动
TGGeCurveSegment segL(*pLWall), segR(*pRWall);
segL.SetPoints(segL.StartPoint(), pts[0]);
segR.SetPoints(pts[0], segR.EndPoint());
if (DOWN_ZERO(segL.GetLength() - pLWall->GetLength())) // 左墙变短,其上门窗移动到右墙上
{
TGGeCurveSegment seg(segL);
seg.SetPoints(pts[0], pLWall->EndPoint());
_ProcessOpeningAndPatch(pLWall, pRWall, seg);
}
else if (DOWN_ZERO(segR.GetLength() - pRWall->GetLength())) // 右墙变短,其上门窗移动到左墙上
{
TGGeCurveSegment seg(segR);
seg.SetPoints(pRWall->StartPoint(), pts[0]);
_ProcessOpeningAndPatch(pRWall, pLWall, seg);
}
else // 都未改变,则退出
return;
// end
pLWall->SetPoints(pLWall->StartPoint(), pts[0]);
pRWall->SetPoints(pts[0], pRWall->EndPoint());
}
OPENOBJ_END()
OPENOBJ_END()
_RegisterReactor(pK);
}
}
extern void InitGlwKatana(BOOL bInit)
{
if (bInit)
{
CGlwKatana::rxInit();
}
else
{
deleteAcRxClass(CGlwKatana::desc());
}
}
ACRX_DXF_DEFINE_MEMBERS(CGlwKatana, ATSCurveEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_KATANA, "ATS_KATANA,图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(CGlwKatana);
/*
.ptLeft
|---------------------------|
| .m_ptCenter |
|---------------------------|
.ptRight
*/
bool CGlwKatana::CalcTraitPtByWall(const AcGePoint3d &pt)
{
OPENOBJ_BEGIN(m_objLeftWall, AcDb::kForRead, TDbWall, pWall)
if (pWall)
{
TGGeCurveSegment lSide, rSide;
pWall->GetStandardCurve(lSide, rSide);
if (rSide.Is(CURVE_LINE))
{
TADSGePoint3d ptL, ptR;
lSide.ProjectToMe(pt, ptL);
rSide.ProjectToMe(pt, ptR);
m_ptRight = asPnt3d(ptR);
m_ptLeft = asPnt3d(ptL);
}
else if (rSide.Is(CURVE_ARC))
{
TGGeArc rArc = rSide.GetArc();
TGGeArc lArc = lSide.GetArc();
double rR = rArc.GetRadius();
double lR = lArc.GetRadius();
ads_point center;
rArc.Center(center);
AcGePoint3d ptCir = asPnt3d(center);
m_ptLeft = m_ptRight = ptCir;
AcGeVector3d v = pt - ptCir;
v.normalize();
v *= lR;
m_ptLeft += v;
v.normalize();
v *= rR;
m_ptRight += v;
}
m_ptCenter.x = (m_ptLeft.x + m_ptRight.x)*.5;
m_ptCenter.y = (m_ptLeft.y + m_ptRight.y)*.5;
m_ptCenter.z = (m_ptLeft.z + m_ptRight.z)*.5;
return true;
}
OPENOBJ_END()
return true;
}
Acad::ErrorStatus CGlwKatana::dwgInFields( AcDbDwgFiler* pFiler )
{
assertWriteEnabled();
Acad::ErrorStatus es;
if ((es = TDbCurveEntity::dwgInFields(pFiler)) != Acad::eOk)
return es;
pFiler->readPoint3d(&m_ptCenter);
pFiler->readPoint3d(&m_ptLeft);
pFiler->readPoint3d(&m_ptRight);
pFiler->readItem(&m_objLeftWall);
pFiler->readItem(&m_objRightWall);
pFiler->readDouble(&m_dWallLessLength);
_RegisterReactor(this);
return pFiler->filerStatus();
}
Acad::ErrorStatus CGlwKatana::dwgOutFields( AcDbDwgFiler* pFiler ) const
{
assertReadEnabled();
Acad::ErrorStatus es;
if ((es = TDbCurveEntity::dwgOutFields(pFiler)) != Acad::eOk)
return es;
pFiler->writePoint3d(m_ptCenter);
pFiler->writePoint3d(m_ptLeft);
pFiler->writePoint3d(m_ptRight);
pFiler->writeItem(m_objLeftWall);
pFiler->writeItem(m_objRightWall);
pFiler->writeDouble(m_dWallLessLength);
return pFiler->filerStatus();
}
Acad::ErrorStatus CGlwKatana::ExplodeOrDraw2d( TGGiExplodeDrawBase &dc ) const
{
// 取左墙宽做为刀的长度
dc.DrawLine(TGGeLine(asDblArray(m_ptLeft), asDblArray(m_ptRight)));
return Acad::eOk;
}
Acad::ErrorStatus CGlwKatana::ExplodeOrDraw3d( TGGiExplodeDrawBase &dc ) const
{
return ExplodeOrDraw2d(dc);
}
Acad::ErrorStatus CGlwKatana::subTransformBy( const AcGeMatrix3d& xform )
{
assertWriteEnabled();
TDbCurveEntity::subTransformBy(xform);
m_ptCenter.transformBy(xform);
m_ptLeft.transformBy(xform);
m_ptRight.transformBy(xform);
return Acad::eOk;
}
Acad::ErrorStatus CGlwKatana::subGetGripPoints( AcGePoint3dArray&gripPoints,AcDbIntArray&,AcDbIntArray& ) const
{
assertReadEnabled();
gripPoints.append(m_ptCenter);
gripPoints.append(m_ptLeft);
gripPoints.append(m_ptRight);
return Acad::eOk;
}
Acad::ErrorStatus CGlwKatana::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset )
{
assertWriteEnabled();
//subTransformBy(offset);
m_ptCenter.transformBy(offset);
m_ptLeft.transformBy(offset);
m_ptRight.transformBy(offset);
double dOffset(m_dWallLessLength);
TADSGePoint3d ptNew; // 投影到墙基线上的点
static bool bLeft(false);
OPENOBJ_BEGIN(m_objLeftWall, AcDb::kForRead, TDbWall, pLWall)
if (pLWall)
{
OPENOBJ_BEGIN(m_objRightWall, AcDb::kForRead, TDbWall, pRWall)
if (pRWall)
{
bool bStartPt(false);
bool bResetPt(false);
TGGeCurveSegment segL(*pLWall), segR(*pRWall), segAll(*pLWall);
segAll.SetPoints(segL.StartPoint(), segR.EndPoint());
segAll.ProjectToMe(m_ptCenter, ptNew);
do
{
if ((ptNew & segL) == PR_INSIDE) // 左侧墙上
{
bLeft = true;
// 先判断是否在门窗或patch上
if (_JudgePtInOpeningAndPatch(pLWall, ptNew, ptNew))
break;
// 再判断是否越界
if (_JudgePtInWall(pLWall, ptNew, ptNew, dOffset, true))
break;
}
else if ((ptNew & segR) == PR_INSIDE) // 右侧墙上
{
bLeft = false;
// 先判断是否在门窗或patch上
if (_JudgePtInOpeningAndPatch(pRWall, ptNew, ptNew))
break;
// 再判断是否越界
if (_JudgePtInWall(pRWall, ptNew, ptNew, dOffset, false))
break;
}
else if ((ptNew & segL) == PR_ONPT2 || (ptNew & segR) == PR_ONPT1)
{
break;
}
else // 不在墙上
{
if (bLeft)
_JudgePtInWall(pLWall, ptNew, ptNew, dOffset, true);
else
_JudgePtInWall(pRWall, ptNew, ptNew, dOffset, false);
break;
}
} while (false);
CalcTraitPtByWall(asPnt3d(ptNew));
m_bDragGripPt = true;
}
OPENOBJ_END()
}
OPENOBJ_END()
return Acad::eOk;
}
Acad::ErrorStatus CGlwKatana::subDeepClone( AcDbObject *pOwner,
AcDbObject *&pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary ) const
{
Acad::ErrorStatus es = TDbCurveEntity::subDeepClone(pOwner, pClonedObject, idMap, isPrimary);
if (es != Acad::eOk) return es;
AcDb::DeepCloneType dt = idMap.deepCloneContext();
if (dt != AcDb::kDcCopy/* && dt != AcDb::kDcExplode*/) return es;
if (m_objLeftWall.isNull() || m_objRightWall.isNull()) return Acad::eNullHandle;
AcDbObjectId id_newLeft = FindCloneId(m_objLeftWall, pOwner, idMap, isPrimary, true);
AcDbObjectId id_newRight = FindCloneId(m_objRightWall, pOwner, idMap, isPrimary, true);
if (UpdateNewKatana((CGlwKatana*)pClonedObject, id_newLeft, id_newRight))
g_deepCloneKatanas.push_back(pClonedObject->objectId());
return Acad::eOk;
}
Acad::ErrorStatus CGlwKatana::subWblockClone( AcRxObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary ) const
{
Acad::ErrorStatus es = TDbCurveEntity::subWblockClone(pOwner, pClonedObject, idMap, isPrimary);
if (Acad::eOk != es) return es;
if (!m_objLeftWall || !m_objRightWall) return Acad::eNullHandle;
AcDbObjectId id_newLeft = FindCloneId(m_objLeftWall, pOwner, idMap, isPrimary, false);
AcDbObjectId id_newRight = FindCloneId(m_objRightWall, pOwner, idMap, isPrimary, false);
UpdateNewKatana((CGlwKatana*)pClonedObject, id_newLeft, id_newRight);
return Acad::eOk;
}
AcDbObjectId CGlwKatana::FindCloneId( AcDbObjectId id,
AcRxObject* pOwner,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary,
bool bIsDeepClone) const
{
AcDbIdPair idPair(id, AcDbObjectId::kNull, false, isPrimary ? true : false);
if (!idMap.compute(idPair))
{
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbObject, pObj)
if (pObj)
{
AcDbObject *pCloned(NULL);
Acad::ErrorStatus es = Acad::eOk;
if (bIsDeepClone)
es = pObj->deepClone((AcDbObject*)pOwner, pCloned, idMap, isPrimary);
else
es = pObj->wblockClone(pOwner, pCloned, idMap, isPrimary);
if (es == Acad::eOk)
{
AcDbObjectId id = pCloned->objectId();
pCloned->close();
return id;
}
}
OPENOBJ_END()
}
else
return idPair.value();
return AcDbObjectId::kNull;
}
bool CGlwKatana::UpdateNewKatana(CGlwKatana *pNewKa, AcDbObjectId idLeft, AcDbObjectId idRight ) const
{
if (!pNewKa || !idLeft.isValid() || !idRight.isValid()) return false;
pNewKa->m_objLeftWall = idLeft;
pNewKa->m_objRightWall = idRight;
OPENOBJ_BEGIN(idLeft, AcDb::kForWrite, TDbWall, pWall)
if (pWall)
pWall->SetEndKatanaID(pNewKa->objectId());
OPENOBJ_END()
OPENOBJ_BEGIN(idRight, AcDb::kForWrite, TDbWall, pWall)
if (pWall)
pWall->SetStartKatanaID(pNewKa->objectId());
OPENOBJ_END()
_RegisterReactor(pNewKa);
return true;
}
Acad::ErrorStatus CGlwKatana::GetExtents2d( TADSGePoint3d &ptLow, TADSGePoint3d &ptUp ) const
{
GetExtents(ptLow, ptUp);
ptLow.z = ptUp.z = 0;
return Acad::eOk;
}
Acad::ErrorStatus CGlwKatana::GetExtents( TADSGePoint3d &ptLow, TADSGePoint3d &ptUp ) const
{
AcDbExtents ext;
ext.addPoint(m_ptRight);
ext.addPoint(m_ptLeft);
ptLow = ext.minPoint();
ptUp = ext.maxPoint();
return Acad::eOk;
}
Acad::ErrorStatus CGlwKatana::subErase( Adesk::Boolean erasing )
{
if (erasing) // 删除
{
AcDbObjectId idNull(AcDbObjectId::kNull);
_UnRegisterReactor(this);
_SetKatanaForWall(_GetWallByKatana(this, eLeftWall), idNull, eEndKatana);
_SetKatanaForWall(_GetWallByKatana(this, eRightWall), idNull, eBegKatana);
}
else // 恢复
{
_RegisterReactor(this);
_SetKatanaForWall(_GetWallByKatana(this, eLeftWall), objectId(), eEndKatana);
_SetKatanaForWall(_GetWallByKatana(this, eRightWall), objectId(), eBegKatana);
}
return Acad::eOk;
}
void CGlwKatana::Init( AcDbObjectId &idNew, AcDbObjectId &idOld )
{
AcGePoint3d ptCnt(AcGePoint3d::kOrigin);
AcDbObjectId idLeft(AcDbObjectId::kNull), idRight(AcDbObjectId::kNull);
OPENOBJ_BEGIN(idNew, AcDb::kForWrite, TDbWall, pNew)
OPENOBJ_BEGIN(idOld, AcDb::kForWrite, TDbWall, pOld)
if (pNew && pOld)
{
if (pNew->EndPoint() == pOld->StartPoint())
{
ptCnt = pNew->EndPoint();
idLeft = pNew->objectId();
idRight = pOld->objectId();
}
else if (pNew->StartPoint() == pOld->EndPoint())
{
ptCnt = pOld->EndPoint();
idLeft = pOld->objectId();
idRight = pNew->objectId();
}
else
return;
}
OPENOBJ_END()
OPENOBJ_END()
SetLeftWallID(idLeft);
SetRightWallID(idRight);
_SetKatanaForWall(idLeft, objectId(), eEndKatana);
_SetKatanaForWall(idRight, objectId(), eBegKatana);
_RegisterReactor(this);
CalcTraitPtByWall(ptCnt);
}
double CGlwKatana::GetLessLength()
{
return m_dWallLessLength;
}
int CGlwKatana::GetFirstVersion() const
{
return 10;
}
double CGlwKatana::m_dWallLessLength = 100;
AcDbObjectId KatanaToolkit::GetKatanaByTwoWalls( TDbWall *pWall1, TDbWall *pWall2 )
{
if (!pWall2 || !pWall1) return AcDbObjectId::kNull;
if (pWall1->GetStartKatanaID() == pWall2->GetEndKatanaID() && !pWall1->GetStartKatanaID().isNull())
return pWall1->GetStartKatanaID();
else if (pWall1->GetEndKatanaID() == pWall2->GetStartKatanaID() && !pWall1->GetEndKatanaID().isNull())
return pWall1->GetEndKatanaID();
else
return AcDbObjectId::kNull;
}
bool KatanaToolkit::JudgeCollinearByWalls( TDbWall *pWall1, TDbWall *pWall2 )
{
if (!pWall2 || !pWall1) return false;
return _JudgeCollinear(pWall1, pWall2);
}
void KatanaToolkit::Erase( AcDbObjectId id )
{
OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbEntity, pEnt)
if (pEnt)
pEnt->erase();
OPENOBJ_END()
}
void KatanaToolkit::ModifyKatana( CGlwKatana *pKa )
{
_ModifyKatana(pKa);
}
void KatanaToolkit::SetBegKatanaIdForWall( TWallData *pWall, AcDbObjectId KaID )
{
if (pWall)
pWall->SetStartKatanaID(KaID);
}
void KatanaToolkit::SetEndKatanaIdForWall( TWallData *pWall, AcDbObjectId KaID )
{
if (pWall)
pWall->SetEndKatanaID(KaID);
}
AcDbObjectId KatanaToolkit::GetBegKatanaIdByWall( TDbWall *pWall )
{
if (pWall)
return pWall->GetStartKatanaID();
return AcDbObjectId::kNull;
}
AcDbObjectId KatanaToolkit::GetEndKatanaIdByWall( TDbWall *pWall )
{
if (pWall)
return pWall->GetEndKatanaID();
return AcDbObjectId::kNull;
}
void KatanaToolkit::SetLeftWallIdForKatana( AcDbObjectId wallID, AcDbObjectId KaID )
{
OPENOBJ_BEGIN(KaID, AcDb::kForWrite, CGlwKatana, pKa)
if (pKa)
pKa->SetLeftWallID(wallID);
OPENOBJ_END()
}
void KatanaToolkit::SetRightWallIdForKatana( AcDbObjectId wallID, AcDbObjectId KaID )
{
OPENOBJ_BEGIN(KaID, AcDb::kForWrite, CGlwKatana, pKa)
if (pKa)
pKa->SetRightWallID(wallID);
OPENOBJ_END()
}
AcDbObjectId KatanaToolkit::GetLeftWallIdByKatana( AcDbObjectId KaID )
{
OPENOBJ_BEGIN(KaID, AcDb::kForWrite, CGlwKatana, pKa)
if (pKa)
return pKa->GetLeftWallID();
OPENOBJ_END()
return AcDbObjectId::kNull;
}
AcDbObjectId KatanaToolkit::GetRightWallIdByKatana( AcDbObjectId KaID )
{
OPENOBJ_BEGIN(KaID, AcDb::kForWrite, CGlwKatana, pKa)
if (pKa)
return pKa->GetRightWallID();
OPENOBJ_END()
return AcDbObjectId::kNull;
}
void KatanaToolkit::UnRegister( TDbWall *pWall, AcDbObjectId idOther )
{
OPENOBJ_BEGIN(idOther, AcDb::kForWrite, TDbWall, pOther)
if (pOther)
_UnRegisterReactor(pWall, pOther);
OPENOBJ_END()
}
void KatanaToolkit::Register( TDbWall *pWall, AcDbObjectId idOther )
{
OPENOBJ_BEGIN(idOther, AcDb::kForWrite, TDbWall, pOther)
if (pOther)
_RegisterReactor(pWall, pOther);
OPENOBJ_END()
}
AcDbObjectId KatanaToolkit::GetOtherWallByKatana( TDbWall *pWall, AcDbObjectId KaID )
{
if (!pWall || KaID.isNull()) return AcDbObjectId::kNull;
if (pWall->GetEndKatanaID() == KaID)
{
OPENOBJ_BEGIN(KaID, AcDb::kForRead, CGlwKatana, pKa)
if (pKa)
return pKa->GetRightWallID();
OPENOBJ_END()
}
else if (pWall->GetStartKatanaID() == KaID)
{
OPENOBJ_BEGIN(KaID, AcDb::kForRead, CGlwKatana, pKa)
if (pKa)
return pKa->GetLeftWallID();
OPENOBJ_END()
}
return AcDbObjectId::kNull;
}
CString KatanaToolkit::GetCMDName()
{
TCString sCmd;
TGGetVar(_T("CMDNAMES"), sCmd);
return sCmd.cs();
}