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

1488 lines
36 KiB
C++

//------------------------------------------------------------------------+
// Copyright (C), 1998-2012, Beijing Tangent Software Co. Ltd.
// = FileName : TDbStruBarBase类
// = Version : ver1.0
// = Author : zyc
// = CreateDate : 2012-11-02
// = Description: 条形基础平面图类定义
// = Maintainers:
//
//------------------------------------------------------------------------+
#include "stdafx.h"
#ifdef TASD
#include "TDbStruBarBase.h"
#include "TAsdKeyDefine.h"
#include "TConfigInfo.h"
#include "TBaseWallIntegrateTool.h"
extern void AddMsg(const TAssocMsg& assocMsg);
extern bool g_bModifyAgain;
const Adesk::UInt8 TDbStruBarBase::g_nVersion = 1;
ACRX_DXF_DEFINE_MEMBERS(ATSStruBarBase, ATSBaseWall, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, ATS_STRUBARBASE,
"ATS_STRUBARBASE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbStruBarBase);
TDbStruBarBase::TDbStruBarBase()
{
SetAt(KEY_WEIGHT, 1);
SetAt(KEY_H, 1000);
SetAt(KEY_BULGE, 0.0);
}
TDbStruBarBase::~TDbStruBarBase()
{
}
Acad::ErrorStatus TDbStruBarBase::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbBaseWall::dwgInFields(pFiler);
if (es != Acad::eOk)
{
return es;
}
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if (nVer > g_nVersion)
{
return Acad::eMakeMeProxy;
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbStruBarBase::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbBaseWall::dwgOutFields(pFiler);
if (es != Acad::eOk)
{
return es;
}
pFiler->writeItem(g_nVersion);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbStruBarBase::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
return TDbBaseWall::subGetOsnapPoints(osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds);
}
Acad::ErrorStatus TDbStruBarBase::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbBaseWall::subTransformBy(xform);
// 拖拽结束时发送消息
if (objectId() && g_bMonitorDbAction)
{
TAssocMsg msg;
msg.SetMethod(TAssocMsg::kTransform);
msg.SetMatrix(xform);
msg.SetAssocId(objectId());
AddMsg(msg);
}
return es;
}
Acad::ErrorStatus TDbStruBarBase::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
AcGePoint3d ptStart, ptEnd, ptMid;
GetAt(KEY_START, ptStart);
GetAt(KEY_END, ptEnd);
double dBulge = 0.0;
GetAt(KEY_BULGE, dBulge);
if (fabs(dBulge) < g_fZero) // 直线
{
Midpoint(ptStart, ptEnd, ptMid);
}
else // 弧线
{
TGGeArc arc(ptStart, ptEnd, dBulge);
ptMid = arc.MidPoint().AsAcGePoint3d();
}
gripPoints.append(ptStart);
gripPoints.append(ptEnd);
gripPoints.append(ptMid);
return Acad::eOk;
}
Acad::ErrorStatus TDbStruBarBase::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const
{
assertReadEnabled();
AcDbIntArray osnapModes;
AcDbIntArray geomIds;
return subGetGripPoints(stretchPoints, osnapModes, geomIds);
}
// 独立移动
void TDbStruBarBase::SingleMove(const AcDbIntArray& indices, const AcGeVector3d& offset)
{
double dBulge = 0.0;
AcGePoint3d ptStart, ptEnd;
GetAt(KEY_START, ptStart);
GetAt(KEY_END, ptEnd);
GetAt(KEY_BULGE, dBulge);
int nIndex = indices[0];
AcGeVector3d vtOffset = offset;
vtOffset.z = 0;
switch (nIndex)
{
case 0: // 起点
ptStart += vtOffset;
SetAt(KEY_START, ptStart);
break;
case 1: // 终点
ptEnd += vtOffset;
SetAt(KEY_END, ptEnd);
break;
case 2: // 中点
default:
if (fabs(dBulge) < g_fZero) // 直线
{
ptStart += vtOffset;
ptEnd += vtOffset;
SetAt(KEY_START, ptStart);
SetAt(KEY_END, ptEnd);
}
else // 弧线
{
TADSGePoint3d ptMid;
TGGeArc arc(ptStart, ptEnd, dBulge);
ptMid = arc.MidPoint();
ptMid += vtOffset;
TGGeArc arcNew(ptStart, ptMid, ptEnd); // 移动后的新弧
TADSGePoint3d ptS, ptE;
arcNew.GetStartPoint(ptS);
arcNew.GetEndPoint(ptE);
SetAt(KEY_START, ptS.AsAcGePoint3d());
SetAt(KEY_END, ptE.AsAcGePoint3d());
SetAt(KEY_BULGE, (double)arcNew.Bulge());
}
break;
}
}
// 关联移动
void TDbStruBarBase::AssociateMove(const AcDbIntArray& indices, const AcGeVector3d& offset)
{
double dBulge;
AcGePoint3d ptStart, ptEnd;
GetAt(KEY_START, ptStart);
GetAt(KEY_END, ptEnd);
GetAt(KEY_BULGE, dBulge);
// 是否是直线
bool bIsStraight = false;
if (fabs(dBulge) < g_fZero)
{
bIsStraight = true;
}
AcGeVector3d vtOffset = offset;
vtOffset.z = 0.0;
int nIndex = indices[0];
switch (nIndex)
{
case 0: // 起点
if (bIsStraight)
{
TGGeLine line(asDblArray(ptStart), asDblArray(ptEnd));
TADSGePoint3d ptMoved(ptStart);
ptMoved += vtOffset;
ptMoved.Project(&line, ptMoved);
SetAt(KEY_START, ptMoved.AsAcGePoint3d());
}
else
{
TADSGePoint3d ptMid;
TGGeArc arc(ptStart, ptEnd, dBulge);
ptMid = arc.MidPoint();
TADSGePoint3d ptCenter;
arc.Center(ptCenter);
TGGeCircle circle(ptCenter, arc.GetRadius());
ptStart += vtOffset;
TADSGePoint3d ptTemp;
TADSGePoint3d(ptStart).Project(&circle, ptTemp);
ptStart = ptTemp.AsAcGePoint3d();
arc.Set(ptStart, ptMid, ptEnd);
SetAt(KEY_START, ptStart);
SetAt(KEY_BULGE, arc.Bulge());
}
break;
case 1: // 终点
if (bIsStraight)
{
TGGeLine line(asDblArray(ptStart), asDblArray(ptEnd));
TADSGePoint3d ptMoved(ptEnd);
ptMoved += vtOffset;
ptMoved.Project(&line, ptMoved);
SetAt(KEY_END, ptMoved.AsAcGePoint3d());
}
else
{
TADSGePoint3d ptMid;
TGGeArc arc(ptStart, ptEnd, dBulge);
ptMid = arc.MidPoint();
TADSGePoint3d ptCenter;
arc.Center(ptCenter);
TGGeCircle circle(ptCenter, arc.GetRadius());
ptEnd += vtOffset;
TADSGePoint3d ptTemp;
TADSGePoint3d(ptEnd).Project(&circle, ptTemp);
ptEnd = ptTemp.AsAcGePoint3d();
arc.Set(ptStart, ptMid, ptEnd);
SetAt(KEY_END, ptEnd);
SetAt(KEY_BULGE, arc.Bulge());
}
break;
case 2: // 中点
default:
if (bIsStraight)
{
TGGeLine line(asDblArray(ptStart), asDblArray(ptEnd));
TADSGePoint3d pt = ptStart + vtOffset, pt2;
pt.Project(&line, pt2);
vtOffset = pt - pt2;
ptStart += vtOffset;
ptEnd += vtOffset;
SetAt(KEY_START, ptStart);
SetAt(KEY_END, ptEnd);
// 拖拽结束时发送消息
if (objectId())
{
TAssocMsg msg;
msg.SetMethod(TAssocMsg::kMovegrippoint);
msg.SetTarget(line.MidPoint());
msg.SetOffset(vtOffset);
msg.SetAssocId(objectId());
AddMsg(msg);
}
}
else //弧线 改变半径
{
TADSGePoint3d ptMid;
TGGeArc arc(ptStart, ptEnd, dBulge);
ptMid = arc.MidPoint();
TADSGePoint3d ptCenter;
arc.Center(ptCenter);
TGGeLine line(ptCenter, ptMid);
ptMid += vtOffset;
ptMid.Project(&line, ptMid);
if (ptMid.Distance(ptCenter) > _DIST_SNAP)
{
AcGeVector3d vt1 = ptStart - ptCenter.AsAcGePoint3d(), vt2 = ptEnd - ptCenter.AsAcGePoint3d();
double dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
vt1 = ptMid - ptCenter;
ptStart = ptCenter + vt1.rotateBy(-dAngle * 0.5, AcGeVector3d::kZAxis);
ptEnd = ptCenter + vt1.rotateBy(dAngle, AcGeVector3d::kZAxis);
arc.Set(ptStart, ptMid, ptEnd);
SetAt(KEY_START, ptStart);
SetAt(KEY_END, ptEnd);
SetAt(KEY_BULGE, arc.Bulge());
}
}
break;
}
}
Acad::ErrorStatus TDbStruBarBase::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
if (GetCtrlToggle())
{
SingleMove(indices, offset); // 单独移动
}
else
{
AssociateMove(indices, offset);
}
return Acad::eOk;
}
Acad::ErrorStatus TDbStruBarBase::subMoveStretchPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
return subMoveGripPointsAt(indices, offset);
}
Acad::ErrorStatus TDbStruBarBase::subGetClassID(CLSID* pClsid) const
{
#if (ADS >= 17)
assertReadEnabled();
#endif
return Acad::eOk;
}
Acad::ErrorStatus TDbStruBarBase::subDeepClone(AcDbObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
assertReadEnabled();
return TDbBaseWall::subDeepClone(pOwner, pClonedObject, idMap, isPrimary);
}
Acad::ErrorStatus TDbStruBarBase::subWblockClone(AcRxObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
assertReadEnabled();
return TDbBaseWall::subWblockClone(pOwner, pClonedObject, idMap, isPrimary);
}
Acad::ErrorStatus TDbStruBarBase::subIntersectWith(const AcDbEntity* ent,
AcDb::Intersect intType,
AcGePoint3dArray& points,
INT_PTR thisGsMarker,
INT_PTR otherGsMarker) const
{
assertReadEnabled();
return TDbBaseWall::subIntersectWith(ent, intType, points, thisGsMarker, otherGsMarker);
}
Acad::ErrorStatus TDbStruBarBase::subIntersectWith(const AcDbEntity* ent,
AcDb::Intersect intType,
const AcGePlane& projPlane,
AcGePoint3dArray& points,
INT_PTR thisGsMarker,
INT_PTR otherGsMarker) const
{
assertReadEnabled();
return TDbBaseWall::subIntersectWith(ent, intType, projPlane, points, thisGsMarker, otherGsMarker);
}
// TEntityBase
// 夹点提示
Acad::ErrorStatus TDbStruBarBase::GetGripText(int i, CString &cs) const
{
bool bIsArc = true;
double dBulge = 0.0;
GetAt(KEY_BULGE, dBulge);
if (fabs(dBulge) < g_fZero) // 直线
{
bIsArc = false;
}
Acad::ErrorStatus es=Acad::eOk;
if (GetCtrlToggle()) // 单独移动
{
switch(i)
{
case 0:
case 1:
cs=_T("改变位置");
break;
case 2:
if (bIsArc)
{
cs=_T("改变位置");
}
else
{
cs=_T("独立平行移动");
}
break;
default:
es=Acad::eInvalidInput;
break;
}
}
else
{
switch(i)
{
case 0:
case 1:
if (bIsArc)
{
cs=_T("沿弧伸缩");
}
else
{
cs=_T("沿条基方向拉伸缩短");
}
break;
case 2:
if (bIsArc)
{
cs=_T("改变半径");
}
else
{
cs=_T("关联平行移动");
}
break;
default:
es=Acad::eInvalidInput;
break;
}
}
return es;
}
Acad::ErrorStatus TDbStruBarBase::ExplodeOrDraw3d(TGGiExplodeDrawBase &dc) const
{
assertReadEnabled();
return Acad::eOk;
}
// 基础平行时,获得封口线,poly的0索引点与左条形基础线起点或终点重合
void TDbStruBarBase::GetSideLine2d(bool bStart, const AcDbObjectId &idWall, const TBaseWallLine &wallLine, TGGeVisibilityPoly2D &poly) const
{
poly.Reset();
TDbStruBarBase *pWall = NULL;
acdbOpenObject(pWall, idWall, AcDb::kForRead);
if (pWall != NULL)
{
TBaseWallLine bwlThat;
pWall->GetThisBaseWallLine(bwlThat);
int nThatWeight = 0;
pWall->GetAt(KEY_WEIGHT, nThatWeight);
pWall->close();
// 判断基础融合方式
TADSGePoint3d ptThat1,ptThat2;
TBaseWallLine bwlThis;
GetThisBaseWallLine(bwlThis);
int nType = TBaseWallIntegrateTool::IsIntegrateAtTail(bwlThat, bwlThis);
if (nType == 1) // 起始端相交
{
TGGeVisibilityPoly2D leftThat = bwlThat.GetLeftLine();
TGGeVisibilityPoly2D rightThat = bwlThat.GetRightLine();
ptThat1 = *leftThat[0];
ptThat2 = *rightThat[0];
}
else if (nType == 2) // 终止端相交
{
TGGeVisibilityPoly2D leftThat = bwlThat.GetLeftLine();
TGGeVisibilityPoly2D rightThat = bwlThat.GetRightLine();
ptThat1 = *leftThat[leftThat.Length() - 1];
ptThat2 = *rightThat[leftThat.Length() - 1];
}
else
{
return;
}
if (!!ptThat1 && !!ptThat2)
{
TADSGePoint3d ptThis1,ptThis2;
TGGeVisibilityPoly2D leftThis = bwlThis.GetLeftLine();
TGGeVisibilityPoly2D rightThis = bwlThis.GetRightLine();
if (bStart)
{
ptThis1 = *leftThis[0];
ptThis2 = *rightThis[0];
}
else
{
ptThis1 = *leftThis[leftThis.Length() - 1];
ptThis2 = *rightThis[rightThis.Length() - 1];
}
AcGeVector3d vtThat = ptThat1 - ptThat2;
AcGeVector3d vtThis = ptThis1 - ptThis2;
int nThisWeight = 0;
GetAt(KEY_WEIGHT, nThisWeight);
if (vtThis.isParallelTo(vtThat)) // 端点连线平行
{
if (nThisWeight < nThatWeight) // 比较优先级
{
poly.AppendNode(ptThis1);
poly.AppendNode(ptThis2);
}
else
{
bool bSuperposition = (ptThat1.Distance(ptThis1) < _DIST_SNAP && ptThat2.Distance(ptThis2) < _DIST_SNAP)
|| (ptThat1.Distance(ptThis2) < _DIST_SNAP && ptThat2.Distance(ptThis1) < _DIST_SNAP); // 融合端点两两重合
if (!bSuperposition)
{
// 将that的融合端点投影到this融合端点连线的直线上
std::vector<TADSGePoint3d> vecPt;
vecPt.push_back(ptThis1);
vecPt.push_back(ptThis2);
TADSGePoint3d pt;
TGGeLine line(ptThis1, ptThis2);
ptThat1.Project(&line, pt);
vecPt.push_back(pt);
ptThat2.Project(&line, pt);
vecPt.push_back(pt);
// 求两点间的距离
std::map<double, std::vector<TADSGePoint3d> > mapData;
std::vector<TADSGePoint3d> vecTemp;
std::vector<TADSGePoint3d>::iterator it1, it2;
for (it1 = vecPt.begin(); it1 != vecPt.end(); it1++)
{
it2 = it1;
++it2;
for (; it2 != vecPt.end(); it2++)
{
vecTemp.clear();
vecTemp.push_back(*it1);
vecTemp.push_back(*it2);
mapData.insert(std::make_pair((*it1).Distance(*it2), vecTemp));
}
}
// 获取距离最远的点
std::map<double, std::vector<TADSGePoint3d> >::iterator it;
it = mapData.end();
--it;
vecTemp.clear();
vecTemp.push_back((*it).second[0]);
vecTemp.push_back((*it).second[1]);
// 从vecPt中删除最远的两点
for (it1 = vecTemp.begin(); it1 != vecTemp.end(); it1++)
{
for (it2 = vecPt.begin(); it2 != vecPt.end(); it2++)
{
if ((*it1).Distance(*it2) < _DIST_SNAP)
{
vecPt.erase(it2);
break;;
}
}
}
// this的融合端点是否与最远点重合
if (ptThis1.Distance(vecTemp[0]) < _DIST_SNAP || ptThis1.Distance(vecTemp[1]) < _DIST_SNAP)
{
double dDist1 = ptThis1.Distance(vecPt[0]);
double dDist2 = ptThis1.Distance(vecPt[1]);
if (dDist1 < dDist2)
{
poly.AppendNode(ptThis1);
poly.AppendNode(vecPt[0], 0.0, AcDb::kInvisible);
}
else
{
poly.AppendNode(ptThis1);
poly.AppendNode(vecPt[1], 0.0, AcDb::kInvisible);
}
}
if (ptThis2.Distance(vecTemp[0]) < _DIST_SNAP || ptThis2.Distance(vecTemp[1]) < _DIST_SNAP)
{
double dDist1 = ptThis2.Distance(vecPt[0]);
double dDist2 = ptThis2.Distance(vecPt[1]);
if (dDist1 < dDist2)
{
poly.AppendNode(vecPt[0]);
poly.AppendNode(ptThis2);
}
else
{
poly.AppendNode(vecPt[1]);
poly.AppendNode(ptThis2);
}
}
if (poly.Length() == 0)
{
poly.AppendNode(ptThis1, 0.0, AcDb::kInvisible);
poly.AppendNode(ptThis2, 0.0, AcDb::kInvisible);
}
}
}
}
else if (nThatWeight != nThisWeight) // 优先级不同
{
TGGeVisibilityPoly2D left = wallLine.GetLeftLine();
TGGeVisibilityPoly2D right = wallLine.GetRightLine();
if (bStart)
{
poly.AppendNode(*left[0]);
poly.AppendNode(*right[0]);
}
else
{
poly.AppendNode(*left[left.Length() - 1]);
poly.AppendNode(*right[right.Length() - 1]);
}
}
}
}
}
// 融合后生成的TGGeVisibilityPoly2D
void TDbStruBarBase::GetIntegratedPoly2d(TGGeVisibilityPoly2D &poly) const
{
// 双线绘制样式
TBaseWallLine bwlThis;
GetThisBaseWallLine(bwlThis);
// 融合基础
TDPtrList<TBaseWallLine> arBaseWallLinesS, arBaseWallLinesM, arBaseWallLinesE;
GetAssocBaseWallLine(arBaseWallLinesS, arBaseWallLinesM, arBaseWallLinesE);
// 起点融合
TBaseWallIntegrateTool::IntegrateAtTail(true, bwlThis, arBaseWallLinesS);
// 终点融合
TBaseWallIntegrateTool::IntegrateAtTail(false, bwlThis, arBaseWallLinesE);
// 基础内融合
int i;
for (i = 0; i < arBaseWallLinesM.Length(); i++)
{
TBaseWallIntegrateTool::Integrate(bwlThis,*arBaseWallLinesM[i]);
}
// 生成poly2d
// 添加左线
TGGeVisibilityPoly2D left, right;
left = bwlThis.GetLeftLine();
right = bwlThis.GetRightLine();
for (i = 0; i < left.Length(); i++)
{
poly.AppendNode(*left[i], *(left.m_ardbulges[i]), left.GetVisibleAt(i));
}
// 添加终点封口线
int nLen = arBaseWallLinesE.Length();
if (nLen == 0) // 终点封口
{
if (!(left.GetVisibleAt(left.Length() - 2) == AcDb::kInvisible && right.GetVisibleAt(right.Length() - 2) == AcDb::kInvisible))
{
poly.AppendNode(*left[left.Length() - 1]);
poly.AppendNode(*right[right.Length() - 1]);
}
}
else if (nLen == 1) // 处理终点处有一个融合基础时,基础端点两点连线平行的情况
{
AcDbObjectId id;
GetWallId(false, id);
TGGeVisibilityPoly2D polyNew;
GetSideLine2d(false, id, bwlThis, polyNew);
polyNew.Compress();
for (int i = 0; i < polyNew.Length(); i++)
{
poly.AppendNode(*polyNew[i], *(polyNew.m_ardbulges[i]), polyNew.GetVisibleAt(i));
}
if (polyNew.Length() == 0)
{
poly.InsertNodeAt(*left[left.Length() - 1], AcDb::kInvisible); // 改变点的可见性
}
}
else
{
poly.InsertNodeAt(*left[left.Length() - 1], AcDb::kInvisible); // 改变点的可见性
}
// 添加右线
right.Reverse();
for (i = 0; i < right.Length(); i++)
{
poly.AppendNode(*right[i], *(right.m_ardbulges[i]), right.GetVisibleAt(i));
}
// 添加起点封口线
nLen = arBaseWallLinesS.Length();
if (nLen == 0) // 起点封口
{
if (!(left.GetVisibleAt(0) == AcDb::kInvisible && right.GetVisibleAt(0) == AcDb::kInvisible))
{
poly.AppendNode(*right[right.Length() - 1]); // right 已逆转方向
poly.AppendNode(*left[0]);
}
}
else if (nLen == 1) // 处理起点处有一个融合基础时,基础端点两点连线平行的情况
{
AcDbObjectId id;
GetWallId(true, id);
TGGeVisibilityPoly2D polyNew;
GetSideLine2d(true, id, bwlThis, polyNew);
polyNew.Compress();
polyNew.Reverse();
for (int i = 0; i < polyNew.Length(); i++)
{
poly.AppendNode(*polyNew[i], *(polyNew.m_ardbulges[i]), polyNew.GetVisibleAt(i));
}
if (polyNew.Length() == 0)
{
poly.InsertNodeAt(*right[right.Length() - 1], AcDb::kInvisible); // 改变点的可见性
}
}
else
{
poly.InsertNodeAt(*right[right.Length() - 1], AcDb::kInvisible); // 改变点的可见性
}
poly.SetClosed();
}
// 绘制加粗的线
Acad::ErrorStatus TDbStruBarBase::DrawWeightLine2d(TGGiExplodeDrawBase &dc) const
{
// 获取融合后的poly2d
TGGeVisibilityPoly2D poly;
GetIntegratedPoly2d(poly);
poly.Compress();
DrawWeightLine2d(dc, poly, true);
return Acad::eOk;
}
Acad::ErrorStatus TDbStruBarBase::DrawWeightLine2d(TGGiExplodeDrawBase &dc, TGGeVisibilityPoly2D &poly, bool bVal) const
{
int nNum = 1;
if (!bVal)
{
nNum = -1;
}
double dLineWidth = DocGetConWallLWeight()*GetPScale();
TGGePoly2D polyDest;
if (poly.PathArea() > 0) // 顺时针
{
poly.Offset(dLineWidth * nNum, polyDest);
}
else
{
poly.Offset(dLineWidth * (-1) * nNum, polyDest);
}
if (poly.Length() != polyDest.Length())
{
return Acad::eInvalidInput;
}
TGGePoly2D poly2dNew;
for (int i = 0; i < poly.Length() - 1; i++)
{
if (poly.GetVisibleAt(i) == AcDb::kInvisible)
{
continue;
}
poly2dNew.Reset();
poly2dNew.AppendNode(*poly[i], *(poly.m_ardbulges[i]));
poly2dNew.AppendNode(*poly[i+1]);
poly2dNew.AppendNode(*polyDest[i+1], *(polyDest.m_ardbulges[i]) * (-1));
poly2dNew.AppendNode(*polyDest[i]);
poly2dNew.SetClosed();
dc << TGGeSolid(poly2dNew);
}
if (poly.GetVisibleAt(poly.Length() - 1) == AcDb::kVisible)
{
poly2dNew.Reset();
poly2dNew.AppendNode(*poly[poly.Length() - 1], *(poly.m_ardbulges[poly.Length() - 1]));
poly2dNew.AppendNode(*poly[0]);
poly2dNew.AppendNode(*polyDest[0], *(polyDest.m_ardbulges[polyDest.Length() - 1]) * (-1));
poly2dNew.AppendNode(*polyDest[polyDest.Length() - 1]);
poly2dNew.SetClosed();
dc << TGGeSolid(poly2dNew);
}
return Acad::eOk;
}
Acad::ErrorStatus TDbStruBarBase::ExplodeOrDraw2d(TGGiExplodeDrawBase &dc) const
{
assertReadEnabled();
// 加粗
if (DocGetIsLineWeight() && DocGetWallIsLW())
{
DrawWeightLine2d(dc);
}
// 绘制线
TBaseWallLine bwlThis;
GetThisBaseWallLine(bwlThis);
TDPtrList<TBaseWallLine> arBaseWallLinesStart, arBaseWallLinesMid, arBaseWallLinesEnd;
GetAssocBaseWallLine(arBaseWallLinesStart, arBaseWallLinesMid, arBaseWallLinesEnd);
TBaseWallIntegrateTool::IntegrateAtTail(true, bwlThis, arBaseWallLinesStart);
TBaseWallIntegrateTool::IntegrateAtTail(false, bwlThis, arBaseWallLinesEnd);
int i;
for (i=0; i<arBaseWallLinesMid.Length(); i++)
{
TBaseWallIntegrateTool::Integrate(bwlThis, *arBaseWallLinesMid[i]);
}
TGGeVisibilityPoly2D left, right;
left = bwlThis.GetLeftLine();
right = bwlThis.GetRightLine();
DrawBaseWall2d(dc, left, true);
DrawBaseWall2d(dc, right, false);
// 封闭基础端点处封口
int nLen = arBaseWallLinesStart.Length();
if (nLen == 0)
{
if (!(left.GetVisibleAt(0) == AcDb::kInvisible &&
right.GetVisibleAt(0) == AcDb::kInvisible))
{
dc << TGGeLine(*left[0], *right[0]);
}
}
else if (nLen == 1)
{
AcDbObjectId idWall;
GetWallId(true, idWall);
DrawSideLine2d(true, idWall, bwlThis, dc);
}
nLen = arBaseWallLinesEnd.Length();
if (nLen == 0)
{
if (!(left.GetVisibleAt(left.Length() - 2) == AcDb::kInvisible &&
right.GetVisibleAt(right.Length() - 2) == AcDb::kInvisible))
{
dc << TGGeLine(*left[left.Length() - 1], *right[right.Length() - 1]);
}
}
else if (nLen == 1)
{
AcDbObjectId idWall;
GetWallId(false, idWall);
DrawSideLine2d(false, idWall, bwlThis, dc);
}
// 编号
CString sNumber;
if (GetAt(KEY_CLAB, sNumber) && !sNumber.IsEmpty())
{
TDbText text;
double dTextHeight = 3.5; // 字高
double dAngle; // 文本旋转角度
TADSGePoint3d ptTextPos; // 文本位置
AcGePoint3d ptStart, ptEnd; // 条基起点和终点
double dWidth, dBulge; // 条基宽度, 条基的凸度
AcGeVector3d vtDir; // 文本偏移方向
AcGePoint3d ptMidPt; // 条基条基起点终点连线的中点
GetAt(KEY_START, ptStart);
GetAt(KEY_END, ptEnd);
GetAt(KEY_W, dWidth);
GetAt(KEY_BULGE, dBulge);
vtDir = ptEnd - ptStart;
if (Wcs2Ucs(ptStart) > Wcs2Ucs(ptEnd) + g_fZero)
{
vtDir = ptStart - ptEnd;
}
dAngle = TADSGePoint3d(vtDir).AsAcGeVector2d().angle(); // 文本的旋转角度
vtDir.rotateBy(PI / 2.0, AcGeVector3d(0, 0, 1)); // 文本的偏移方向
vtDir.normalize();
if (abs(dBulge) < g_fZero)
{
// 条基为直线
Midpoint(ptStart, ptEnd, ptMidPt);
}
else
{
// 条基为弧
TGGeArc arc(ptStart, ptEnd, dBulge);
ptMidPt = arc.MidPoint();
}
// 文本位置
ptTextPos = ptMidPt + vtDir * (dWidth / 2.0 + dTextHeight * DocGetPScale() / 3.0);
text.SetText(sNumber);
text.SetAlignment(TGGiExplodeDrawBase::kBottomCenter);
text.SetHeight(dTextHeight);
text.setPropertiesFrom(this);
text.SetRotation(dAngle);
text.SetStyleId(GetTextStyleId(_T("Standard")));
text.SetLocation(ptTextPos);
dc.DrawEntity(text);
}
return Acad::eOk;
}
// 绘制端点的封口线
Acad::ErrorStatus TDbStruBarBase::DrawSideLine2d(bool bStart, const AcDbObjectId &idWall, const TBaseWallLine &wallLine, TGGiExplodeDrawBase &dc) const
{
TDbStruBarBase *pWall = NULL;
acdbOpenObject(pWall, idWall, AcDb::kForRead);
if (pWall != NULL)
{
TBaseWallLine bwlThat;
pWall->GetThisBaseWallLine(bwlThat);
int nThatWeight = 0;
pWall->GetAt(KEY_WEIGHT, nThatWeight);
pWall->close();
// 判断基础线融合方式
TADSGePoint3d ptThat1,ptThat2;
TBaseWallLine bwlThis;
GetThisBaseWallLine(bwlThis);
int nType = TBaseWallIntegrateTool::IsIntegrateAtTail(bwlThat, bwlThis);
if (nType == 1) // 起始端相交
{
TGGeVisibilityPoly2D leftThat = bwlThat.GetLeftLine();
TGGeVisibilityPoly2D rightThat = bwlThat.GetRightLine();
ptThat1 = *leftThat[0];
ptThat2 = *rightThat[0];
}
else if (nType == 2) // 终止端相交
{
TGGeVisibilityPoly2D leftThat = bwlThat.GetLeftLine();
TGGeVisibilityPoly2D rightThat = bwlThat.GetRightLine();
ptThat1 = *leftThat[leftThat.Length() - 1];
ptThat2 = *rightThat[leftThat.Length() - 1];
}
else
{
return Acad::eOk;
}
if (!!ptThat1 && !!ptThat2)
{
TADSGePoint3d ptThis1,ptThis2;
TGGeVisibilityPoly2D leftThis = bwlThis.GetLeftLine();
TGGeVisibilityPoly2D rightThis = bwlThis.GetRightLine();
if (bStart)
{
ptThis1 = *leftThis[0];
ptThis2 = *rightThis[0];
}
else
{
ptThis1 = *leftThis[leftThis.Length() - 1];
ptThis2 = *rightThis[rightThis.Length() - 1];
}
AcGeVector3d vtThat = ptThat1 - ptThat2;
AcGeVector3d vtThis = ptThis1 - ptThis2;
int nThisWeight = 0;
GetAt(KEY_WEIGHT, nThisWeight);
if (vtThis.isParallelTo(vtThat)) // 端点连线平行
{
if (nThisWeight < nThatWeight) // 比较优先级
{
dc << TGGeLine(ptThis1, ptThis2);
}
else
{
bool bSuperposition = (ptThat1.Distance(ptThis1) < _DIST_SNAP && ptThat2.Distance(ptThis2) < _DIST_SNAP)
|| (ptThat1.Distance(ptThis2) < _DIST_SNAP && ptThat2.Distance(ptThis1) < _DIST_SNAP); // 融合端点两两重合
if (!bSuperposition)
{
// 将that的融合端点投影到this融合端点连线的直线上
std::vector<TADSGePoint3d> vecPt;
vecPt.push_back(ptThis1);
vecPt.push_back(ptThis2);
TADSGePoint3d pt;
TGGeLine line(ptThis1, ptThis2);
ptThat1.Project(&line, pt);
vecPt.push_back(pt);
ptThat2.Project(&line, pt);
vecPt.push_back(pt);
// 求两点间的距离
std::map<double, std::vector<TADSGePoint3d> > mapData;
std::vector<TADSGePoint3d> vecTemp;
std::vector<TADSGePoint3d>::iterator it1, it2;
for (it1 = vecPt.begin(); it1 != vecPt.end(); it1++)
{
it2 = it1;
++it2;
for (; it2 != vecPt.end(); it2++)
{
vecTemp.clear();
vecTemp.push_back(*it1);
vecTemp.push_back(*it2);
mapData.insert(std::make_pair((*it1).Distance(*it2), vecTemp));
}
}
// 获取距离最远的点
std::map<double, std::vector<TADSGePoint3d> >::iterator it;
it = mapData.end();
--it;
vecTemp.clear();
vecTemp.push_back((*it).second[0]);
vecTemp.push_back((*it).second[1]);
// 从vecPt中删除最远的两点
for (it1 = vecTemp.begin(); it1 != vecTemp.end(); it1++)
{
for (it2 = vecPt.begin(); it2 != vecPt.end(); it2++)
{
if ((*it1).Distance(*it2) < _DIST_SNAP)
{
vecPt.erase(it2);
break;;
}
}
}
// this的融合端点是否与最远点重合
if (ptThis1.Distance(vecTemp[0]) < _DIST_SNAP || ptThis1.Distance(vecTemp[1]) < _DIST_SNAP)
{
double dDist1 = ptThis1.Distance(vecPt[0]);
double dDist2 = ptThis1.Distance(vecPt[1]);
if (dDist1 < dDist2)
{
dc << TGGeLine(ptThis1, vecPt[0]);
}
else
{
dc << TGGeLine(ptThis1, vecPt[1]);
}
}
if (ptThis2.Distance(vecTemp[0]) < _DIST_SNAP || ptThis2.Distance(vecTemp[1]) < _DIST_SNAP)
{
double dDist1 = ptThis2.Distance(vecPt[0]);
double dDist2 = ptThis2.Distance(vecPt[1]);
if (dDist1 < dDist2)
{
dc << TGGeLine(ptThis2, vecPt[0]);
}
else
{
dc << TGGeLine(ptThis2, vecPt[1]);
}
}
}
}
}
else if (nThatWeight != nThisWeight) // 优先级不同
{
TGGeVisibilityPoly2D left = wallLine.GetLeftLine();
TGGeVisibilityPoly2D right = wallLine.GetRightLine();
if (bStart)
{
dc << TGGeLine(*left[0], *right[0]);
}
else
{
dc << TGGeLine(*left[left.Length() - 1], *right[right.Length() - 1]);
}
}
}
}
return Acad::eOk;
}
Acad::ErrorStatus TDbStruBarBase::GetExtents2d(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp) const
{
TGGePoly2D poly2d;
GetPoly2D(poly2d);
poly2d.GetExtend(ptLow, ptUp);
ptLow.z = 0.0;
ptUp.z = 0.0;
return Acad::eOk;
}
Acad::ErrorStatus TDbStruBarBase::GetExtents(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp) const
{
GetExtents2d(ptLow, ptUp);
double dH = 0.0;
GetAt(KEY_H, dH);
AcGePoint3d ptStart;
GetAt(KEY_START, ptStart);
ptLow.z = ptStart.z - dH;
ptUp.z = ptStart.z;
return Acad::eOk;
}
//取动态属性显示数据
void TDbStruBarBase::GetTips(TDPtrList<TObjInfoUnit> &lstInfo) const
{
}
const TCHAR *TDbStruBarBase::GetDefaultLayer() const
{
return LAY_S_BASE_STRIP_LINE;
}
BOOL TDbStruBarBase::IsValid() const
{
assertReadEnabled();
AcGePoint3d ptStart, ptEnd;
double dBulge;
int iWeight;
double dWidth, dHeight;
if (GetAt(KEY_START, ptStart) &&
GetAt(KEY_END, ptEnd) &&
GetAt(KEY_BULGE, dBulge) &&
GetAt(KEY_WEIGHT, iWeight) &&
GetAt(KEY_W, dWidth) &&
GetAt(KEY_H, dHeight))
{
return TRUE;
}
return FALSE;
}
// 支持夹点ctrl功能切换
int TDbStruBarBase::GetCtrlToggleIndex()const
{
return 11;
}
void TDbStruBarBase::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbBaseWall::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbStruBarBase* pEnt = TDbStruBarBase::cast(pSrcEntity);
if (pEnt != NULL)
{
AcGePoint3d ptStart, ptEnd;
double dBulge;
GetAt(KEY_START, ptStart);
GetAt(KEY_END, ptEnd);
GetAt(KEY_BULGE, dBulge);
GetSpecialtyData()->Empty();
*GetSpecialtyData() = *pEnt->GetSpecialtyData();
SetAt(KEY_START, ptStart);
SetAt(KEY_END, ptEnd);
SetAt(KEY_BULGE, dBulge);
}
}
TEntityBase::DrawType TDbStruBarBase::GetDrawType() const
{
assertReadEnabled();
return TEntityBase::k2DOnly;
}
bool TDbStruBarBase::GetStandardFaceBody(AcDbVoidPtrArray& arFacePtrs) const
{
return false;
}
bool TDbStruBarBase::GetSafeProtectedSpace(AcDbVoidPtrArray& arFacePtrs) const
{
return false;
}
bool TDbStruBarBase::GetSection(const AcDbFace &face,
const AcGeVector3d &vtPlaneSecDir,
std::vector<TObjSectionRecord> &sectionRecords,
AcDbVoidPtrArray &arFillPtrs) const
{
return false;
}
CString TDbStruBarBase::GetXml(const AcGeMatrix3d& mat) const
{
return _T("");
}
// 对象修改发出关联更改消息
void TDbStruBarBase::PostAssocMsg(TAssocMsg assocMsg)const
{
}
// 对象接收到更改消息
void TDbStruBarBase::ReceiveAssocMsg(TAssocMsg assocMsg)
{
assertWriteEnabled();
TDbBaseWall::ReceiveAssocMsg(assocMsg);
}
// 建立关联关系
void TDbStruBarBase::MakeAssocRelation(AcDbObjectIdArray& ids)
{
assertWriteEnabled();
if(ids.length() < 1)
{
return;
}
TPickEntSet ss(SS_FREE);
ads_name eName;
for (int i = 0; i < ids.length(); i++)
{
if (acdbGetAdsName(eName, ids[i]) == Acad::eOk)
{
ss += ids[i];
}
}
TGGePoly2D poly; //基础闭合平面
GetPoly2D(poly);
double dWidth = 0; //基础平面宽
GetTotalWidth(dWidth);
TGGeCurveSegment cvCL = GetCenterLine();
cvCL.SetLineFlag(LS_INFINITE);
double dElevS = cvCL.StartPoint().z;
double dElevE = cvCL.EndPoint().z;
bool bModFlg = false; //记录基础的中心线是否调整
double dGap(0);
AcDbObjectId idObj = AcDbObjectId::kNull;
TEntitySet ent;
for (long j = 0; j < ss.Length(); j++)
{
ent = ss[j];
if (ent.Is(_T("ATS_STRUBARBASE")))
{
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbStruBarBase, pEnt);
if (!pEnt)
{
continue;
}
TGGePoly2D polyDest;
pEnt->GetPoly2D(polyDest);
double dWidthDest(0);
pEnt->GetTotalWidth(dWidthDest);
bool bRet = TBaseWallIntegrateTool::GetMinGap(poly, polyDest, dGap);
//间隙小于基础宽一半时,当作关联处理
if(bRet && (dGap < dWidth*0.5 || dGap < dWidthDest*0.5))
{
if (cvCL.Is(CURVE_LINE))
{
//建立关联时对基础的中心线进行校验,相交
TGGeCurveSegment cvCLDest = pEnt->GetCenterLine();
cvCLDest.SetLineFlag(LS_INFINITE);
TADSGePoint3d ptInter1,ptInter2;
int nNum = cvCL.Intersection(cvCLDest,ptInter1,ptInter2);
if (nNum != 0) // 有交点
{
//两个交点时取离cvCL中点近的
if (nNum == 2)
{
TADSGePoint3d ptMid = cvCL.MidPoint();
ptInter1 = TGGeLine(ptInter1, ptInter2).NearPoint(ptMid);
}
bool bModBreak = false;
int nHitFlag = cvCL.HitTest2d(ptInter1);
if (nHitFlag == 6) //起始侧延长线
{
bModFlg = true;
bModBreak = true;
cvCL.SetStartPoint(ptInter1);
}
else if (nHitFlag == 7) //终止侧延长线
{
bModFlg = true;
bModBreak = true;
cvCL.SetEndPoint(ptInter1);
}
//add by xlc on 120417 基础自动打断
if (g_bAutoBreak)
{
if (bModBreak)
{
Acad::ErrorStatus es = upgradeOpen();
if ((es == Acad::eOk || es == Acad::eWasOpenForWrite))
{
AcGePoint3d pt = cvCL.StartPoint();
pt.z = dElevS;
SetAt(KEY_START, pt);
pt = cvCL.EndPoint();
pt.z = dElevE;
SetAt(KEY_END, pt);
if (es == Acad::eOk)
{
downgradeOpen();
}
}
}
bool bBreak = false;
if(nHitFlag == 5) //交点在线内时对自己进行打断
{
if(BreakAt(ptInter1,NULL))
{
bModFlg = false;
bBreak = true;
}
}
bool bModifyOld = g_bModifyAgain;
pEnt->BreakAt(ptInter1, NULL);
g_bModifyAgain = bModifyOld;
if (bBreak)
{
break;
}
}
}
}
idObj = pEnt->objectId();
}
else
{
continue;
}
OPENOBJ_END();
if (!m_arAssocBWallIds.contains(idObj))
{
m_arAssocBWallIds.append(idObj);
}
}
}
// 修改条形基础的端点
if (bModFlg)
{
Acad::ErrorStatus es = upgradeOpen();
if ((es == Acad::eOk || es == Acad::eWasOpenForWrite))
{
AcGePoint3d pt = cvCL.StartPoint();
pt.z = dElevS;
SetAt(KEY_START, pt);
pt = cvCL.EndPoint();
pt.z = dElevE;
SetAt(KEY_END, pt);
if (es == Acad::eOk)
{
downgradeOpen();
}
}
}
}
// 移除关联关系
void TDbStruBarBase::RemoveAssocRelation(AcDbObjectId& id)
{
m_arAssocBWallIds.remove(id);
}
// 获得条形基础总宽度
void TDbStruBarBase::GetTotalWidth(double &dWidth)const
{
dWidth = 0;
GetAt(KEY_W, dWidth);
}
// 获得条形基础总高度
void TDbStruBarBase::GetTotalHeight(double &dHeight)const
{
dHeight = 0;
GetAt(KEY_H, dHeight);
}
// 基础外围poly2d
void TDbStruBarBase::GetPoly2D(TGGePoly2D &poly2d) const
{
TBaseWallLine wallLine;
GetThisBaseWallLine(wallLine);
TGGeVisibilityPoly2D left, right;
left = wallLine.GetLeftLine();
right = wallLine.GetRightLine();
AcDbPolyline* pLwPoly = new AcDbPolyline();
double dBuge = 0.0;
int nIndex = 0;
int i;
for (i = 0; i < left.Length(); i++)
{
dBuge = tan(*(left.m_ardbulges[i]) / 4.0);
pLwPoly->addVertexAt(nIndex, (*left[i]).AsAcGePoint2d(), dBuge);
++nIndex;
}
for (i=left.Length()-1; i >= 0; i--)
{
if (i > 0)
{
dBuge = tan(*(right.m_ardbulges[i-1]) / 4.0) * (-1);
}
else
{
dBuge = 0.0;
}
pLwPoly->addVertexAt(nIndex, (*right[i]).AsAcGePoint2d(), dBuge);
++nIndex;
}
pLwPoly->setClosed(Adesk::kTrue);
poly2d.SetAcDbCurve(pLwPoly);
delete pLwPoly;
}
BOOL TDbStruBarBase::CanMerge(AcDbObjectId idWall)
{
return TRUE;
}
int TDbStruBarBase::GetFirstVersion()const
{
return 10;
}
bool TDbStruBarBase::IsModelEntity() const
{
return true;
}
void InitDbStruBarBase(BOOL bInit)
{
if (bInit)
{
TDbStruBarBase::rxInit();
acrxBuildClassHierarchy();
TDbStruBarBase::InitMatchProtocol(TRUE);
}
else
{
TDbStruBarBase::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbStruBarBase::desc());
}
}
#endif