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

3243 lines
73 KiB
C++

//------------------------------------------------------------------------+
// Copyright (C), 1998-2011, Beijing Tangent Software Co. Ltd.
// = FileName : TDbBaseWall类
// = Version : ver1.0
// = Author : CET
// = CreateDate : 2011-04-25
// = Description: 抽象墙基线类实现
// = Maintainers:
//
//------------------------------------------------------------------------+
#include "stdafx.h"
#ifdef TASD
#include "TDbBaseWall.h"
#include "TAsdKeyDefine.h"
#include "TBaseWallIntegrateTool.h"
#include "TAsdGlobleDef.h"
#include "TDbStruFloorSlab.h"
#include "TDbStruBeam.h"
#define BASEWALL_AS_OBJ 0 //1作为对象,0抽象基类
extern bool g_bModifyAgain;
extern BOOL g_bSplitFloor;
extern void AddMsg(const TAssocMsg& assocMsg);
#if (BASEWALL_AS_OBJ == 1)
ACRX_DXF_DEFINE_MEMBERS(ATSBaseWall, ATSStruEntityBase, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, ATS_BASEWALL,
"ATS_BASEWALL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
#else
ACRX_NO_CONS_DEFINE_MEMBERS(TDbBaseWall, TDbStruEntityBase);
#endif
IMPLEMENT_TENTBASE(TDbBaseWall);
const Adesk::UInt8 TDbBaseWall::g_nVersion = 1;
TDbBaseWall::TDbBaseWall()
{
}
TDbBaseWall::~TDbBaseWall()
{
}
Acad::ErrorStatus TDbBaseWall::dwgInFields( AcDbDwgFiler* pFiler )
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbCurveEntity::dwgInFields(pFiler);
if(es != Acad::eOk)
{
return es;
}
// 版本号
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
// xy平面关联对象ID数组
Adesk::UInt8 nCount = 0;
pFiler->readItem(&nCount);
AcDbSoftPointerId id;
m_arAssocBWallIds.setLogicalLength(0);
for(Adesk::UInt8 i = 0; i < nCount; i++)
{
pFiler->readItem(&id);
m_arAssocBWallIds.append(id);
}
// z平面关联对象ID数组
nCount = 0;
pFiler->readItem(&nCount);
m_arAssocZIds.setLogicalLength(0);
for(i = 0; i < nCount; i++)
{
pFiler->readItem(&id);
m_arAssocZIds.append(id);
}
// 关联洞对象ID数组
nCount = 0;
pFiler->readItem(&nCount);
m_arHoleIds.setLogicalLength(0);
for(i = 0; i < nCount; i++)
{
pFiler->readItem(&id);
m_arHoleIds.append(id);
}
// 关联板对象ID数组
nCount = 0;
pFiler->readItem(&nCount);
m_arSlabIds.setLogicalLength(0);
for(i = 0; i < nCount; i++)
{
pFiler->readItem(&id);
m_arSlabIds.append(id);
}
// 关联柱子对象ID数组
nCount = 0;
pFiler->readItem(&nCount);
m_arColumnIds.setLogicalLength(0);
for(i = 0; i < nCount; i++)
{
pFiler->readItem(&id);
m_arColumnIds.append(id);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbBaseWall::dwgOutFields( AcDbDwgFiler* pFiler ) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbCurveEntity::dwgOutFields(pFiler);
if(es != Acad::eOk)
{
return es;
}
pFiler->writeItem(g_nVersion);
// xy平面关联对象ID数组
Adesk::UInt8 nCount=(Adesk::UInt8)m_arAssocBWallIds.length();
pFiler->writeItem(nCount);
for (Adesk::UInt8 i = 0; i < nCount; i++)
{
pFiler->writeItem(AcDbSoftPointerId(m_arAssocBWallIds[i]));
}
// z平面关联对象ID数组
nCount=(Adesk::UInt8)m_arAssocZIds.length();
pFiler->writeItem(nCount);
for (i = 0; i < nCount; i++)
{
pFiler->writeItem(AcDbSoftPointerId(m_arAssocZIds[i]));
}
// 关联洞对象ID数组
nCount=(Adesk::UInt8)m_arHoleIds.length();
pFiler->writeItem(nCount);
for ( i = 0; i < nCount; i++)
{
pFiler->writeItem(AcDbSoftPointerId(m_arHoleIds[i]));
}
// 关联板对象ID数组
nCount=(Adesk::UInt8)m_arSlabIds.length();
pFiler->writeItem(nCount);
for (i = 0; i < nCount; i++)
{
pFiler->writeItem(AcDbSoftPointerId(m_arSlabIds[i]));
}
// 关联柱子对象ID数组
nCount=(Adesk::UInt8)m_arColumnIds.length();
pFiler->writeItem(nCount);
for (i = 0; i < nCount; i++)
{
pFiler->writeItem(AcDbSoftPointerId(m_arColumnIds[i]));
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbBaseWall::dxfInFields( AcDbDxfFiler* pFiler )
{
return TDbCurveEntity::dxfInFields(pFiler);
}
Acad::ErrorStatus TDbBaseWall::dxfOutFields( AcDbDxfFiler* pFiler ) const
{
return TDbCurveEntity::dxfOutFields(pFiler);
}
Acad::ErrorStatus TDbBaseWall::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds ) const
{
assertReadEnabled();
return TDbCurveEntity::subGetOsnapPoints(osnapMode,gsSelectionMark,
pickPoint,lastPoint,viewXform,snapPoints,geomIds);
}
Acad::ErrorStatus TDbBaseWall::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds, const AcGeMatrix3d& insertionMat ) const
{
assertReadEnabled();
#if (BASEWALL_AS_OBJ == 1)
if(osnapMode == AcDb::kOsModeIns || osnapMode == AcDb::kOsModeMid
|| osnapMode == AcDb::kOsModeNear || osnapMode == AcDb::kOsModeEnd )
{
AcGePoint3d ptS, ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
snapPoints.append(ptS);
snapPoints.append(ptE);
}
#endif
return TDbCurveEntity::subGetOsnapPoints(osnapMode,gsSelectionMark,
pickPoint,lastPoint,viewXform,snapPoints,geomIds,insertionMat);
}
Acad::ErrorStatus TDbBaseWall::subTransformBy( const AcGeMatrix3d& xform )
{
assertWriteEnabled();
TDbCurveEntity::subTransformBy(xform);
AcGePoint3d ptS, ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
double dBulge = 0.0;
GetAt(KEY_BULGE, dBulge);
if (IsMirrorMatrix(xform) && fabs(dBulge) > g_angleZero) // 镜像
{
TGGeArc arc(ptS, ptE, dBulge);
TADSGePoint3d ptMid = arc.MidPoint();
ptS.transformBy(xform);
ptE.transformBy(xform);
ptMid.TransformBy(xform);
TGGeArc arcNew(ptS, ptMid, ptE);
TADSGePoint3d pt1, pt2;
arcNew.GetStartPoint(pt1);
arcNew.GetEndPoint(pt2);
ptS = pt1;
ptE = pt2;
dBulge = arcNew.Bulge();
SetAt(KEY_START, ptS);
SetAt(KEY_END, ptE);
SetAt(KEY_BULGE, dBulge);
}
else
{
ptS.transformBy(xform);
ptE.transformBy(xform);
SetAt(KEY_START, ptS);
SetAt(KEY_END, ptE);
}
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::subGetGripPoints( AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds ) const
{
assertReadEnabled();
#if (BASEWALL_AS_OBJ == 1)
AcGePoint3d ptS, ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
gripPoints.append(ptS);
gripPoints.append(ptE);
double dBulge = 0.0;
GetAt(KEY_BULGE, dBulge);
TADSGePoint3d ptStart = ptS, ptEnd = ptE, ptMid;
if (fabs(dBulge) < g_fZero) // 直线
{
Midpoint(ptStart, ptE, ptMid);
}
else // 弧线
{
TGGeArc arc(ptStart, ptEnd, dBulge);
ptMid = arc.MidPoint();
}
gripPoints.append(ptMid);
#endif
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::subGetStretchPoints( AcGePoint3dArray& stretchPoints ) const
{
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset )
{
#if (BASEWALL_AS_OBJ == 1)
AcGePoint3d ptS;
GetAt(KEY_START, ptS);
AcGePoint3d ptE;
GetAt(KEY_END, ptE);
int nIndex = indices[0];
if (nIndex == 0) // 起点
{
ptS += offset;
SetAt(KEY_START, ptS);
}
else if (nIndex == 1) // 终点
{
ptE += offset;
SetAt(KEY_END, ptE);
}
else if (nIndex == 2) // 中点
{
double dBulge = 0.0;
GetAt(KEY_BULGE, dBulge);
if (fabs(dBulge) < g_angleZero) // 直线
{
ptS += offset;
SetAt(KEY_START, ptS);
ptE += offset;
SetAt(KEY_END, ptE);
}
else // 弧线
{
TADSGePoint3d ptStart = ptS, ptEnd = ptE, ptMid;
TGGeArc arc(ptStart, ptEnd, dBulge);
ptMid = arc.MidPoint();
ptMid += offset;
TGGeArc arcNew(ptStart, ptMid, ptEnd); // 移动后的新弧
arcNew.GetStartPoint(ptStart);
arcNew.GetEndPoint(ptEnd);
dBulge = arcNew.Bulge();
ptS = ptStart;
ptE = ptEnd;
SetAt(KEY_START, ptS);
SetAt(KEY_END, ptE);
SetAt(KEY_BULGE, dBulge);
}
}
#endif
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::subMoveStretchPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset )
{
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::subGetClassID( CLSID* pClsid ) const
{
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::subDeepClone( AcDbObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary ) const
{
assertReadEnabled();
return TDbStruEntityBase::subDeepClone(pOwner, pClonedObject, idMap, isPrimary);
}
Acad::ErrorStatus TDbBaseWall::subWblockClone( AcRxObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary ) const
{
assertReadEnabled();
return TDbStruEntityBase::subWblockClone(pOwner, pClonedObject, idMap, isPrimary);
}
Acad::ErrorStatus TDbBaseWall::subIntersectWith( const AcDbEntity* ent, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/ ) const
{
AcDbCurve *pCurve = GetBaseCurve();
if (pCurve == NULL)
{
return Acad::eInvalidInput;
}
Acad::ErrorStatus st = pCurve->intersectWith(ent, intType, points, thisGsMarker, otherGsMarker);
delete pCurve;
return st;
}
Acad::ErrorStatus TDbBaseWall::subIntersectWith( const AcDbEntity* ent, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/ ) const
{
AcDbCurve *pCurve = GetBaseCurve();
if (pCurve == NULL)
{
return Acad::eInvalidInput;
}
Acad::ErrorStatus st = pCurve->intersectWith(ent, intType, projPlane, points, thisGsMarker, otherGsMarker);
delete pCurve;
return st;
}
AcDbCurve* TDbBaseWall::GetBaseCurve() const
{
assertReadEnabled();
AcGePoint3d ptS, ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
double dBulge = 0.0;
GetAt(KEY_BULGE, dBulge);
/* dBulge = atan(dBulge) * 4;*/
//AcDbPolyline *pPoly = new AcDbPolyline;
//pPoly->addVertexAt(0, ptS.convert2d(AcGePlane::kXYPlane), tan(dBulge / 4));
//pPoly->addVertexAt(1,ptE.convert2d(AcGePlane::kXYPlane));
TGGeCurveSegment cvSeg(ptS,ptE,dBulge);
return cvSeg.AsAcDbCurve();
}
//用于trim/extent时修改对象
Acad::ErrorStatus TDbBaseWall::SetBaseCurve(AcDbCurve* pCurve)
{
if (pCurve == NULL)
{
return Acad::eInvalidInput;
}
assertWriteEnabled();
AcGePoint3d ptS, ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
AcDbLine *pLine = AcDbLine::cast(pCurve);
AcDbArc *pArc = AcDbArc::cast(pCurve);
if (pLine)
{
SetAt(KEY_START, AcGePoint3d(pLine->startPoint().x, pLine->startPoint().y, ptS.z));
SetAt(KEY_END, AcGePoint3d(pLine->endPoint().x, pLine->endPoint().y, ptE.z));
SetAt(KEY_BULGE, 0.0);
}
else if (pArc)
{
TGGeArc ar(TADSGePoint3d(pArc->center()), pArc->radius(), pArc->startAngle(), pArc->endAngle());
TGGeCurveSegment cvCenter;
cvCenter = ar;
SetAt(KEY_START, AcGePoint3d(cvCenter.StartPoint().x, cvCenter.StartPoint().y, ptS.z));
SetAt(KEY_END, AcGePoint3d(cvCenter.EndPoint().x, cvCenter.EndPoint().y, ptE.z));
SetAt(KEY_BULGE, cvCenter.GetBulge());
}
else
{
return Acad::eInvalidInput;
}
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::GetClipBoundary( TGGePoly2D& poly ) const
{
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::GetGripText( int i, CString &cs ) const
{
Acad::ErrorStatus es=Acad::eOk;
switch(i)
{
case 0:
cs=_T("改变起点");
break;
case 1:
cs=_T("改变终点");
break;
case 2:
{
double dBulge = 0.0;
GetAt(KEY_BULGE, dBulge);
if (fabs(dBulge) < g_angleZero) // 直线
{
cs = _T("平移");
}
else // 弧线
{
cs = _T("改变中点");
}
break;
}
default:
es=Acad::eInvalidInput;
break;
}
return es;
}
Acad::ErrorStatus TDbBaseWall::ExplodeOrDraw3d( TGGiExplodeDrawBase &dc ) const
{
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::ExplodeOrDraw2d( TGGiExplodeDrawBase &dc ) const
{
assertReadEnabled();
#if (BASEWALL_AS_OBJ == 1)
TBaseWallLine bwlThis;
GetThisBaseWallLine(bwlThis);
// 通过融合剪切墙体
TDPtrList<TBaseWallLine> arBaseWallLinesS, arBaseWallLinesM, arBaseWallLinesE;
GetAssocBaseWallLine(arBaseWallLinesS, arBaseWallLinesM, arBaseWallLinesE);
// 起点融合
TBaseWallIntegrateTool::IntegrateAtTail(true, bwlThis, arBaseWallLinesS);
// 终点融合
TBaseWallIntegrateTool::IntegrateAtTail(false, bwlThis, arBaseWallLinesE);
// 墙内融合
for (int i = 0; i < arBaseWallLinesM.Length(); i++)
{
TBaseWallIntegrateTool::Integrate(bwlThis,*arBaseWallLinesM[i]);
}
TGGeVisibilityPoly2D left, right;
left = bwlThis.GetLeftLine();
right = bwlThis.GetRightLine();
DrawBaseWall2d(dc, left, true);
DrawBaseWall2d(dc, right, false);
#endif
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::GetExtents2d( TADSGePoint3d &ptLow, TADSGePoint3d &ptUp ) const
{
return Acad::eOk;
}
Acad::ErrorStatus TDbBaseWall::GetExtents( TADSGePoint3d &ptLow, TADSGePoint3d &ptUp ) const
{
return Acad::eOk;
}
bool TDbBaseWall::UnifyElevation( double dElevation )
{
SetBottomElev(dElevation);
return true;
}
void TDbBaseWall::GetTips( TDPtrList<TObjInfoUnit> & lstInfo ) const
{
#if (BASEWALL_AS_OBJ == 1)
int nWeight = 0;
GetAt(KEY_WEIGHT, nWeight);
lstInfo.Append(new TObjInfoUnit(_T("优先级"), TCString(_T("%d"), nWeight)));
lstInfo.Append(new TObjInfoUnit(_T("关联个数"), TCString(_T("%d"), m_arAssocBWallIds.length())));
#endif
}
const TCHAR * TDbBaseWall::GetDefaultLayer() const
{
return NULL;
}
BOOL TDbBaseWall::IsValid() const
{
return TRUE;
}
void TDbBaseWall::CopyPropertiesFrom( AcDbEntity *pSrcEntity, unsigned gMatchFlag )
{
assertWriteEnabled();
TDbStruEntityBase::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbBaseWall *pBaseWall = TDbBaseWall::cast(pSrcEntity);
if(pBaseWall != NULL)
{
/*double dWidth = 0.0, dHeight = 0.0;
GetAt(KEY_W, dWidth);
GetAt(KEY_H, dHeight);
int nWeight = 0;
GetAt(KEY_WEIGHT, nWeight);
GetSpecialtyData()->Empty();
*GetSpecialtyData() = *pBaseWall->GetSpecialtyData();
SetAt(KEY_W, dWidth);
SetAt(KEY_H, dHeight);
SetAt(KEY_WEIGHT, nWeight);*/
}
}
TEntityBase::DrawType TDbBaseWall::GetDrawType() const
{
assertReadEnabled();
return TEntityBase::k2Dand3D;
}
bool TDbBaseWall::GetStandardFaceBody( AcDbVoidPtrArray& arFacePtrs ) const
{
return false;
}
bool TDbBaseWall::GetSafeProtectedSpace( AcDbVoidPtrArray& arFacePtrs ) const
{
return false;
}
bool TDbBaseWall::GetSection( const AcDbFace &face, const AcGeVector3d& vtPlaneSecDir, std::vector<TObjSectionRecord> &sectionRecords, AcDbVoidPtrArray& arFillPtrs ) const
{
return false;
}
CString TDbBaseWall::GetXml(const AcGeMatrix3d& mat) const
{
return _T("");
}
void TDbBaseWall::PostAssocMsg( TAssocMsg assocMsg ) const
{
}
void TDbBaseWall::ReceiveAssocMsg( TAssocMsg assocMsg )
{
#if (BASEWALL_AS_OBJ == 1)
AcDbObjectId id = assocMsg.GetAssocId();
if (!m_arAssocBWallIds.contains(id))
{
m_arAssocBWallIds.append(id);
}
return;
#endif
assertWriteEnabled();
//不是夹点消息直接返回
if (assocMsg.GetMethod() != TAssocMsg::kMovegrippoint)
{
return;
}
TGGeCurveSegment cvCL = GetCenterLine();
double dElevS = cvCL.GetStartPoint().z;
double dElevE = cvCL.GetEndPoint().z;
cvCL.SetElevation(0);
AcGeVector3d vtDir = (cvCL.GetEndPoint() - cvCL.GetStartPoint()).AsAcGeVector3d();
AcGeVector3d vtOffset = assocMsg.GetOffset();
AcGePoint3d ptTarget = assocMsg.GetTarget();
double dRet = vtOffset.dotProduct(vtDir);
if (fabs(vtOffset.dotProduct(vtDir)) < _DIST_SNAP) //垂直
{
AcGePoint3d ptStart = cvCL.GetStartPoint().AsAcGePoint3d();
AcGePoint3d ptEnd = cvCL.GetEndPoint().AsAcGePoint3d();
ptStart += vtOffset;
ptStart.z = dElevS;
SetAt(KEY_START, ptStart);
ptEnd += vtOffset;
ptEnd.z = dElevE;
SetAt(KEY_END, ptEnd);
TAssocMsg msg;
msg.SetAssocId(objectId());
msg.SetMethod(TAssocMsg::kMovegrippoint);
msg.SetTarget(cvCL.MidPoint().AsAcGePoint3d());
msg.SetOffset(vtOffset);
AddMsg(msg);
}
else //不垂直时只需修改自身起始点,不发送消息
{
TADSGePoint3d pt = ptTarget;
pt.z = 0;
if (vtOffset.isParallelTo(vtDir)) //平行
{
cvCL.ProjectToMe(pt, pt);
}
else //斜交
{
AcGeVector3d vtOrth = vtOffset.perpVector();
vtOrth = vtOffset;
vtOrth.rotateBy(PI*0.5, AcGeVector3d::kZAxis);
TADSGePoint3d ptEnd = ptTarget + vtOrth;
TGGeCurveSegment cv(ptTarget, ptEnd, 0, LS_INFINITE);
cv.SetElevation(0);
cvCL.SetLineFlag(LS_INFINITE);
cv.Intersection(cvCL, pt, TADSGePoint3d());
//求投影向量
double dAng = vtOffset.angleTo(vtDir);
double dLen = vtOffset.length();
dLen /= fabs(cos(dAng)); //偏移向量在线上的投影长度
vtOffset = vtDir.normal();
vtOffset.z = 0;
vtOffset *= dLen;
if (dAng > PI*0.5)
{
vtOffset.negate();
}
}
int nPos = (pt & cvCL); //交点与线的位置关系
if (nPos == PR_ONPT1) //起点
{
AcGePoint3d ptMod = cvCL.GetStartPoint().AsAcGePoint3d();
ptMod += vtOffset;
ptMod.z = dElevS;
SetAt(KEY_START, ptMod);
}
else if (nPos == PR_ONPT2) //终点
{
AcGePoint3d ptMod = cvCL.GetEndPoint().AsAcGePoint3d();
ptMod += vtOffset;
ptMod.z = dElevE;
SetAt(KEY_END, ptMod);
}
else if (nPos == PR_INSIDE) //线内
{
AcGePoint3d ptMod = pt.AsAcGePoint3d();
ptMod += vtOffset;
nPos = (TADSGePoint3d(ptMod) & cvCL);
if (nPos == PR_EXTEND) //新位置交点在线外时需要延长
{
if (vtOffset.angleTo(vtDir) < _DIST_SNAP)//同向
{
ptMod.z = dElevE;
SetAt(KEY_END, ptMod);
}
else
{
ptMod.z = dElevS;
SetAt(KEY_START, ptMod);
}
}
}
}
}
void TDbBaseWall::MakeAssocRelation( AcDbObjectIdArray& ids )
{
#if (BASEWALL_AS_OBJ == 1)
for (int i = 0; i < ids.length(); i++)
{
if (!m_arAssocBWallIds.contains(ids[i]))
{
m_arAssocBWallIds.append(ids[i]);
}
}
#endif
}
// 不验证关系,直接建立关联关系
void TDbBaseWall::MakeAssocRelationDirect(const AcDbObjectId& idObj)
{
assertWriteEnabled();
TPickEntSet ss(SS_FREE);
ss += idObj;
TEntitySet ent;
for (long i = 0; i < ss.Length(); i++)
{
ent = ss[i];
if (ent.Is(_T("ATS_STRUBEAM"))
||ent.Is(_T("ATS_WALL"))) // 梁
{
if (!m_arAssocBWallIds.contains(idObj))
{
m_arAssocBWallIds.append(idObj);
}
}
else if (ent.Is(_T("ATS_COLUMN"))) // 柱子
{
if (!m_arColumnIds.contains(idObj))
{
m_arColumnIds.append(idObj);
}
}
else if (ent.Is(_T("ATS_STRU_FLOORSLAB"))) // 板
{
if (!m_arSlabIds.contains(idObj))
{
m_arSlabIds.append(idObj);
}
}
else if (ent.Is(_T("TCH_STRU_HOLE"))) // 墙洞
{
if (!m_arHoleIds.contains(idObj))
{
m_arHoleIds.append(idObj);
}
}
}
}
void TDbBaseWall::RemoveAssocRelation( AcDbObjectId& id )
{
m_arAssocBWallIds.remove(id);
}
void TDbBaseWall::GetAssocRelation( int nType, AcDbObjectIdArray& ar ) const
{
assertReadEnabled();
switch(nType)
{
case ASSOC_XY: // XY平面关联
{
ar = m_arAssocBWallIds;
break;
}
case ASSOC_Z: // Z平面关联
{
//ar = m_arAssocZIds;
break;
}
case ASSOC_HOLE: // 关联洞
{
ar = m_arHoleIds;
break;
}
case ASSOC_SLAB:// 关联楼板
{
ar = m_arSlabIds;
break;
}
case ASSOC_COLU: // 关联柱
{
ar = m_arColumnIds;
break;
}
case ASSOC_ALL: //所有关联
{
ar.setLogicalLength(0);
if (m_arAssocBWallIds.length() > 0)
{
ar.append(m_arAssocBWallIds);
}
if (m_arColumnIds.length() > 0)
{
ar.append(m_arColumnIds);
}
if (m_arSlabIds.length() > 0)
{
ar.append(m_arSlabIds);
}
if (m_arHoleIds.length() > 0)
{
ar.append(m_arHoleIds);
}
//if (m_arAssocZIds.length() > 0)
//{
// ar.append(m_arAssocZIds);
//}
break;
}
}
}
void TDbBaseWall::GetThisBaseWallLine( TBaseWallLine& baseWall ) const
{
assertReadEnabled();
AcGePoint3d ptS, ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
ptS.z = 0.0;
ptE.z = 0.0;
double dBulge = 0.0, dWidth = 0.0;
GetAt(KEY_BULGE, dBulge);
GetTotalWidth(dWidth);
TGGeVisibilityPoly2D left; // 左线
TGGeVisibilityPoly2D right; // 右线
if (fabs(dBulge) < g_angleZero) // 直线
{
// 偏移向量
AcGeVector3d vt = ptE - ptS;
vt.normalize();
vt.rotateBy(PI/2, AcGeVector3d::kZAxis);
// 墙线1
ptS += vt * dWidth * 0.5;
ptE += vt * dWidth * 0.5;
left.AppendNode(ptS);
left.AppendNode(ptE);
// 墙线2
ptS -= vt * dWidth;
ptE -= vt * dWidth;
right.AppendNode(ptS);
right.AppendNode(ptE);
}
else // 弧线
{
TADSGePoint3d ptStart = ptS, ptEnd = ptE;
// 创建新弧取圆心
TGGeArc arc(ptStart, ptEnd, dBulge);
AcGePoint3d ptCenter = arc.GetCenterPt();
// 创建偏移向量
AcGeVector3d vt1 = ptStart - ptCenter, vt2 = ptEnd - ptCenter;
vt1.normalize();
vt2.normalize();
vt1 *= dWidth * 0.5;
vt2 *= dWidth * 0.5;
// 创建弧墙
ptS = ptStart + vt1;
ptE = ptEnd + vt2;
right.AppendNode(ptS,dBulge);
right.AppendNode(ptE);
ptS = ptStart - vt1;
ptE = ptEnd - vt2;
left.AppendNode(ptS,dBulge);
left.AppendNode(ptE);
}
int nWeight = 0;
GetAt(KEY_WEIGHT, nWeight);
baseWall.SetLeftLine(left);
baseWall.SetRightLine(right);
baseWall.SetWeight(nWeight);
}
void TDbBaseWall::GetAssocBaseWallLine( TDPtrList<TBaseWallLine>& arBaseWallLinesS, TDPtrList<TBaseWallLine>& arBaseWallLinesM, TDPtrList<TBaseWallLine>& arBaseWallLinesE ) const
{
TBaseWallLine bwlThis;
GetThisBaseWallLine(bwlThis);
TDbBaseWall *pBaseWall = NULL;
TBaseWallLine bwlThat;
for (int i = 0; i < m_arAssocBWallIds.length(); i++)
{
acdbOpenObject(pBaseWall, m_arAssocBWallIds[i], AcDb::kForRead);
if (pBaseWall != NULL)
{
pBaseWall->GetThisBaseWallLine(bwlThat);
pBaseWall->close();
// 判断墙线融合方式
TBaseWallLine *pBWLine = new TBaseWallLine;
pBWLine->SetLeftLine(bwlThat.GetLeftLine());
pBWLine->SetRightLine(bwlThat.GetRightLine());
pBWLine->SetWeight(bwlThat.GetWeight());
int nType = TBaseWallIntegrateTool::IsIntegrateAtTail(bwlThis, bwlThat);
if (nType == 1) // 起始端融合
{
arBaseWallLinesS.Append(pBWLine);
}
else if (nType == 2) // 终止端融合
{
arBaseWallLinesE.Append(pBWLine);
}
else if (nType == 3) // 两端融合
{
arBaseWallLinesS.Append(pBWLine);
TBaseWallLine *pbWLineNew = new TBaseWallLine;
pbWLineNew->SetLeftLine(bwlThat.GetLeftLine());
pbWLineNew->SetRightLine(bwlThat.GetRightLine());
pbWLineNew->SetWeight(bwlThat.GetWeight());
arBaseWallLinesE.Append(pbWLineNew);
}
else // 墙体内融合(非墙体起点终点)
{
arBaseWallLinesM.Append(pBWLine);
}
}
}
}
void TDbBaseWall::GetAssocHoleline( TDPtrList<TGGePoly2D> &plHoles ) const
{
plHoles.Reset();
//TGGePoly2D poly;
//TGGeCurveSegment seg;
//TDbStruWallHole *pHole = NULL;
//for (int i = 0; i < m_arHoleIds.length(); i++)
//{
// acdbOpenObject(pHole, m_arHoleIds[i], AcDb::kForRead);
// if (pHole != NULL)
// {
// poly.Reset();
// pHole->GetOutlinePoly2D(pHole->GetBottomElev(), poly, seg);
// pHole->close();
// plHoles.Append(new TGGePoly2D(poly));
// }
//}
}
AcDbFace* TDbBaseWall::GetXYAssocFace( bool bTopOrBottom ) const
{
return NULL;
}
void TDbBaseWall::recordGraphicModified()const
{
}
double TDbBaseWall::GetBottomElev() const
{
assertReadEnabled();
AcGePoint3d ptE;
GetAt(KEY_END, ptE);
return ptE.z;
}
void TDbBaseWall::SetBottomElev( double dElev )
{
assertWriteEnabled();
AcGePoint3d ptS, ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
ptS.z = dElev;
ptE.z = dElev;
SetAt(KEY_START, ptS);
SetAt(KEY_END, ptE);
}
void TDbBaseWall::GetSideCurve(TGGeCurveSegment &lCurve, TGGeCurveSegment &rCurve) const
{
assertReadEnabled();
TGGeCurveSegment cvCenter = GetCenterLine();
double dWidth = 0;
GetTotalWidth(dWidth);
lCurve = cvCenter.Offset(OFFSET_LEFT, dWidth*0.5, LS_FINITE);
rCurve = cvCenter.Offset(OFFSET_RIGHT, dWidth*0.5, LS_FINITE);
}
Acad::ErrorStatus TDbBaseWall::DrawBaseWall2d(TGGiExplodeDrawBase &dc, TGGeVisibilityPoly2D poly, bool bLeft) const
{
// 根据可见性显示各段线段
TGGeLine line;
TGGeArc arc;
AcDb::Visibility eVal;
TADSGePoint3d ptS, ptE;
for(int i = 0; i < poly.Length(); i++)
{
int nrc = poly.Nth(i, line, arc, &eVal);
if (nrc == LINE_SEGMENT && eVal == AcDb::kVisible)
{
dc << line;
}
else if (nrc == ARC_SEGMENT && eVal == AcDb::kVisible)
{
dc << arc;
}
}
return Acad::eOk;
}
void TDbBaseWall::GetWallId(bool bStart, AcDbObjectId &idWall) const
{
TBaseWallLine bwlThis;
GetThisBaseWallLine(bwlThis);
TDbBaseWall *pBaseWall = NULL;
TBaseWallLine bwlThat;
for (int i = 0; i < m_arAssocBWallIds.length(); i++)
{
acdbOpenObject(pBaseWall, m_arAssocBWallIds[i], AcDb::kForRead);
if (pBaseWall != NULL)
{
pBaseWall->GetThisBaseWallLine(bwlThat);
pBaseWall->close();
// 判断墙线融合方式
TBaseWallLine *pBWLine = new TBaseWallLine;
pBWLine->SetLeftLine(bwlThat.GetLeftLine());
pBWLine->SetRightLine(bwlThat.GetRightLine());
pBWLine->SetWeight(bwlThat.GetWeight());
int nType = TBaseWallIntegrateTool::IsIntegrateAtTail(bwlThis, bwlThat);
if ((nType == 1 || nType == 3) && bStart) // 起始端融合 或 两端融合
{
idWall = m_arAssocBWallIds[i];
break;
}
else if ((nType == 2 || nType == 3) && !bStart) // 终止端融合 或 两端融合
{
idWall = m_arAssocBWallIds[i];
break;
}
}
}
}
void TDbBaseWall::GetSegmentForSlab2d(const TGGePoly2D &polySlab, const TGGeCurveSegment &seg, std::vector<TGGeCurveSegment> &vecSeg1, std::vector<TGGeCurveSegment> &vecSeg2) const
{
TGGePoly2D poly(polySlab);
poly.SetElevation(0.0);
AcDbPolyline *pLine = static_cast<AcDbPolyline*>(poly.AsAcDbCurve());
if (pLine == NULL)
{
return;
}
bool bLine = true;
AcDbLine lineTemp;
AcDbArc arcTemp;
if (seg.Is(CURVE_ARC))
{
TGGeArc arc;
arc = seg.GetArc();
bLine = false;
TADSGePoint3d ptCenter = arc.GetCenterPt();
arcTemp.setCenter(ptCenter.AsAcGePoint3d());
arcTemp.setStartAngle(arc.GetStarAngle());
arcTemp.setEndAngle(arc.GetEndAngle());
arcTemp.setRadius(arc.GetRadius());
}
else if (seg.Is(CURVE_LINE))
{
TGGeLine line;
line = seg.GetLine();
line.StartPoint().z = 0.0;
line.EndPoint().z = 0.0;
lineTemp.setStartPoint(line.StartPoint());
lineTemp.setEndPoint(line.EndPoint());
}
else
{
delete pLine;
return;
}
// 是否有交点
AcGePoint3dArray ptArr;
if (bLine)
{
pLine->intersectWith(&lineTemp, AcDb::kOnBothOperands, ptArr);
}
else
{
pLine->intersectWith(&arcTemp, AcDb::kOnBothOperands, ptArr);
}
int nNum = ptArr.length();
if (nNum > 1) // 可能存在重复点, 删除重复点
{
AcGePoint3d pt;
for (int i = 0; i < ptArr.length(); i++)
{
for (int j = i + 1; j < ptArr.length(); j++)
{
if ((ptArr[i]).distanceTo(ptArr[j]) < _DIST_SNAP)
{
ptArr.removeAt(j);
j = i;
}
}
}
nNum = ptArr.length();
}
if (nNum == 0) // 无交点
{
if (bLine)
{
if (IsLineInPoly(poly, &lineTemp)) // 直线在poly外
{
vecSeg1.push_back(seg);
}
else // 直线在poly内
{
vecSeg2.push_back(seg);
}
}
else
{
TADSGePoint3d ptS, ptE;
arcTemp.getStartPoint(ptS);
arcTemp.getEndPoint(ptE);
AcDbLine line(ptS.AsAcGePoint3d(), ptE.AsAcGePoint3d());
if (IsLineInPoly(poly, &line)) // 直线在poly外
{
vecSeg1.push_back(seg);
}
else // 直线在poly内
{
vecSeg2.push_back(seg);
}
}
}
else if (nNum == 1) // 存在一个交点,有部分线段在poly2d
{
if (bLine)
{
TADSGePoint3d pt = poly.GetInsidePoint();
AcGePoint3d ptS = lineTemp.startPoint(), ptE = lineTemp.endPoint();
pt = ptArr[0];
if (!IsLineInPoly(poly, &lineTemp)) // 起点在poly内
{
TGGeLine line1(TADSGePoint3d(ptS), pt);
TGGeCurveSegment segTemp;
segTemp = line1;
vecSeg2.push_back(segTemp); // 虚线
TGGeLine line2(TADSGePoint3d(ptE), pt);
segTemp = line2;
vecSeg1.push_back(segTemp);
}
else
{
TGGeLine line1(TADSGePoint3d(ptE), pt);
TGGeCurveSegment segTemp;
segTemp = line1;
vecSeg2.push_back(segTemp); // 虚线
TGGeLine line2(TADSGePoint3d(ptS), pt);
segTemp = line2;
vecSeg1.push_back(segTemp);
}
}
else
{
TADSGePoint3d pt = poly.GetInsidePoint();
AcGePoint3d ptS, ptE;
arcTemp.getStartPoint(ptS);
arcTemp.getEndPoint(ptE);
AcDbLine line(ptS, pt.AsAcGePoint3d());
pt = ptArr[0];
AcGePoint3d ptCenter = arcTemp.center();
AcGeVector3d vt1 = ptS - ptCenter;
AcGeVector3d vt2 = ptArr[0] - ptCenter;
AcGeVector3d vt3 = ptE - ptCenter;
double dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
double dAngle2 = vt2.angleTo(vt3, AcGeVector3d::kZAxis);
if (!IsLineInPoly(poly, &line)) // 起点在poly内
{
TGGeArc arc1(ptS, pt, dAngle1);
TGGeCurveSegment segTemp;
segTemp = arc1;
vecSeg2.push_back(segTemp);
TGGeArc arc2(pt, ptE, dAngle2);
segTemp = arc2;
vecSeg1.push_back(segTemp);
}
else
{
TGGeArc arc1(pt, ptE, dAngle2);
TGGeCurveSegment segTemp;
segTemp = arc1;
vecSeg2.push_back(segTemp);
TGGeArc arc2(ptS, pt, dAngle1);
segTemp = arc2;
vecSeg1.push_back(segTemp);
}
}
}
else if (nNum == 2) // 存在两个交点,线段被分成三分
{
if (bLine)
{
TADSGePoint3d pt1 = ptArr[0], pt2 = ptArr[1];
TGGeLine line1(pt1, pt2);
TGGeCurveSegment segTemp;
segTemp = line1;
vecSeg2.push_back(segTemp); // 虚线
// 根据两交点的顺序,生成相应线段
TADSGePoint3d pt3 = lineTemp.startPoint(), pt4 = lineTemp.endPoint();
if (pt1.Distance(pt3) < pt2.Distance(pt3))
{
TGGeCurveSegment segTemp;
if (pt1.Distance(pt3) > _DIST_SNAP)
{
TGGeLine line1(pt1, pt3);
segTemp = line1;
vecSeg1.push_back(segTemp);
}
if (pt2.Distance(pt4) > 0)
{
TGGeLine line1(pt2, pt4);
segTemp = line1;
vecSeg1.push_back(segTemp);
}
}
else
{
TGGeCurveSegment segTemp;
if (pt1.Distance(pt4) > _DIST_SNAP)
{
TGGeLine line1(pt1, pt4);
segTemp = line1;
vecSeg1.push_back(segTemp);
}
if (pt2.Distance(pt3) > _DIST_SNAP)
{
TGGeLine line1(pt2, pt3);
segTemp = line1;
vecSeg1.push_back(segTemp);
}
}
}
else
{
double dDist1 = 0.0, dDist2 = 0.0;
arcTemp.getDistAtPoint(ptArr[0], dDist1);
arcTemp.getDistAtPoint(ptArr[1], dDist2);
AcGePoint3d ptS, ptE;
arcTemp.getStartPoint(ptS);
arcTemp.getEndPoint(ptE);
if (dDist1 < dDist2)
{
AcGePoint3d ptCenter = arcTemp.center();
AcGeVector3d vt1 = ptS - ptCenter;
AcGeVector3d vt2 = ptArr[0] - ptCenter;
AcGeVector3d vt3 = ptArr[1] - ptCenter;
AcGeVector3d vt4 = ptE - ptCenter;
double dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
double dAngle2 = vt2.angleTo(vt3, AcGeVector3d::kZAxis);
double dAngle3 = vt3.angleTo(vt4, AcGeVector3d::kZAxis);
TGGeCurveSegment segTemp;
if (ptS.distanceTo(ptArr[0]) > _DIST_SNAP)
{
TGGeArc arc1(ptS, ptArr[0], dAngle1);
segTemp = arc1;
vecSeg1.push_back(segTemp);
}
TGGeArc arc2(ptArr[0], ptArr[1], dAngle2);
segTemp = arc2;
vecSeg2.push_back(segTemp);
if (ptE.distanceTo(ptArr[1]) > _DIST_SNAP)
{
TGGeArc arc1(ptArr[1], ptE, dAngle3);
segTemp = arc1;
vecSeg1.push_back(segTemp);
}
}
else
{
AcGePoint3d ptCenter = arcTemp.center();
AcGeVector3d vt1 = ptS - ptCenter;
AcGeVector3d vt2 = ptArr[1] - ptCenter;
AcGeVector3d vt3 = ptArr[0] - ptCenter;
AcGeVector3d vt4 = ptE - ptCenter;
double dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
double dAngle2 = vt2.angleTo(vt3, AcGeVector3d::kZAxis);
double dAngle3 = vt3.angleTo(vt4, AcGeVector3d::kZAxis);
TGGeCurveSegment segTemp;
if (ptS.distanceTo(ptArr[1]) > _DIST_SNAP)
{
TGGeArc arc1(ptS, ptArr[1], dAngle1);
segTemp = arc1;
vecSeg1.push_back(segTemp);
}
TGGeArc arc2(ptArr[1], ptArr[0], dAngle2);
segTemp = arc2;
vecSeg2.push_back(segTemp);
if (ptE.distanceTo(ptArr[0]) > _DIST_SNAP)
{
TGGeArc arc1(ptArr[0], ptE, dAngle3);
segTemp = arc1;
vecSeg1.push_back(segTemp);
}
}
}
}
delete pLine;
}
// 平面内的线无交点的情况下,线是否在poly内
bool TDbBaseWall::IsLineInPoly(TGGePoly2D &poly, AcDbLine *pLine) const
{
if (pLine == NULL)
{
return false;
}
bool bRet = true;
XPoint pt1 = pLine->startPoint();
XPoint pt2 = pLine->endPoint();
if (((pt1 & poly) == PR_INSIDE) && ((pt2 & poly) == PR_INSIDE))
{
bRet = false;
}
return bRet;
}
void TDbBaseWall::FiltrateSegment(std::vector<TGGeCurveSegment> &vecSeg1, std::vector<TGGeCurveSegment> &vecSeg2) const
{
// 删除重复线
FiltrateSegment(vecSeg1);
FiltrateSegment(vecSeg2);
// 删除与虚线重叠的实线部分
std::vector<TGGeCurveSegment>::iterator it;
for (it = vecSeg2.begin(); it != vecSeg2.end(); it++)
{
FiltrateSegment(*it, vecSeg1);
}
}
void TDbBaseWall::FiltrateSegment(const TGGeCurveSegment &seg, std::vector<TGGeCurveSegment> &vecSeg) const
{
CurveType type = seg.GetCurveType();
TGGeLine line;
TGGeArc arc;
TADSGePoint3d pt1, pt2, ptS, ptE;
ptS = seg.StartPoint();
ptE = seg.EndPoint();
bool bModify = false;
std::vector<TGGeCurveSegment> vecDel, vevNew;
std::vector<TGGeCurveSegment>::iterator it;
for(it = vecSeg.begin(); it != vecSeg.end(); it++)
{
bModify = false;
if(it->GetLength() < _DIST_SNAP)
{
continue;
}
if (type == it->GetCurveType())
{
if (type == CURVE_ARC)
{
arc = it->GetArc();
}
else if (type == CURVE_LINE)
{
line = it->GetLine();
}
else
{
continue;
}
if (type == CURVE_LINE)
{
line.SetLineFlag(1);
AcGeVector3d vt1 = ptS - ptE, vt2 = line.StartPoint() - line.EndPoint();
bool bVal1 = fabs(ptS.Distance(line.StartPoint()) + ptS.Distance(line.EndPoint()) - line.GetLength())< _DIST_SNAP;
bool bVal2 = fabs(ptE.Distance(line.StartPoint()) + ptE.Distance(line.EndPoint()) - line.GetLength())< _DIST_SNAP;
if (vt1.isParallelTo(vt2) && (bVal1 || bVal2)) // 共线有交点
{
if (ptS.Distance(line.StartPoint()) < _DIST_SNAP && ptE.Distance(line.EndPoint()) < _DIST_SNAP
|| ptS.Distance(line.EndPoint()) < _DIST_SNAP && ptE.Distance(line.StartPoint()) < _DIST_SNAP) // 重合
{
bModify = true;
}
else if (bVal1 && bVal2) // 包含关系
{
double dDist1 = ptS.Distance(line.StartPoint());
double dDist2 = ptE.Distance(line.StartPoint());
if (dDist1 < dDist2)
{
if (dDist1 > _DIST_SNAP)
{
TGGeLine lineTemp(ptS, line.StartPoint());
TGGeCurveSegment segTemp;
segTemp = lineTemp;
vevNew.push_back(segTemp);
bModify = true;
}
if (ptE.Distance(line.EndPoint()) > _DIST_SNAP)
{
TGGeLine lineTemp(ptE, line.EndPoint());
TGGeCurveSegment segTemp;
segTemp = lineTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
else
{
if (dDist2 > _DIST_SNAP)
{
TGGeLine lineTemp(ptE, line.StartPoint());
TGGeCurveSegment segTemp;
segTemp = lineTemp;
vevNew.push_back(segTemp);
bModify = true;
}
if (ptS.Distance(line.EndPoint()) > _DIST_SNAP)
{
TGGeLine lineTemp(ptS, line.EndPoint());
TGGeCurveSegment segTemp;
segTemp = lineTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
}
else if (bVal1)
{
double dDist1 = ptE.Distance(line.StartPoint());
double dDist2 = ptE.Distance(line.EndPoint());
if (dDist1 < dDist2)
{
if (ptS.Distance(line.EndPoint()) > _DIST_SNAP)
{
TGGeLine lineTemp(ptS, line.EndPoint());
TGGeCurveSegment segTemp;
segTemp = lineTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
else
{
if (ptS.Distance(line.StartPoint()) > _DIST_SNAP)
{
TGGeLine lineTemp(ptS, line.StartPoint());
TGGeCurveSegment segTemp;
segTemp = lineTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
}
else if (bVal2)
{
double dDist1 = ptS.Distance(line.StartPoint());
double dDist2 = ptS.Distance(line.EndPoint());
if (dDist1 < dDist2)
{
if (ptE.Distance(line.EndPoint()) > _DIST_SNAP)
{
TGGeLine lineTemp(ptE, line.EndPoint());
TGGeCurveSegment segTemp;
segTemp = lineTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
else
{
if (ptE.Distance(line.StartPoint()) > _DIST_SNAP)
{
TGGeLine lineTemp(ptE, line.StartPoint());
TGGeCurveSegment segTemp;
segTemp = lineTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
}
}
}
else
{
TGGeArc arcSeg = seg.GetArc();
double dRadius = arcSeg.GetRadius();
int bVal1 = arc.PtOnArc(ptS);
int bVal2 = arc.PtOnArc(ptE);
if (fabs(dRadius - arc.GetRadius()) < _DIST_SNAP && (arc.GetCenterPt()).Distance(arcSeg.GetCenterPt()) < _DIST_SNAP
&& (bVal1 || bVal2)) // 共弧有交点
{
TADSGePoint3d pt1, pt2, ptCenter;
arc.GetStartPoint(pt1);
arc.GetEndPoint(pt2);
arc.Center(ptCenter);
if (ptS.Distance(pt1) < _DIST_SNAP && ptE.Distance(pt2) < _DIST_SNAP
|| ptS.Distance(pt2) < _DIST_SNAP && ptE.Distance(pt1) < _DIST_SNAP) // 重合
{
bModify = true;
}
else if (bVal1 && bVal1) // 虚线在实线内
{
AcGeVector3d vt1 = pt1 - ptCenter;
AcGeVector3d vt2 = ptS - ptCenter;
AcGeVector3d vt3 = ptE - ptCenter;
AcGeVector3d vt4 = pt2 - ptCenter;
double dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
double dAngle3 = vt3.angleTo(vt4, AcGeVector3d::kZAxis);
TGGeCurveSegment segTemp;
if (pt1.Distance(ptS) > _DIST_SNAP)
{
TGGeArc arcTemp(pt1, ptS, dAngle1);
segTemp = arcTemp;
vevNew.push_back(segTemp);
bModify = true;
}
if (pt2.Distance(ptE) > _DIST_SNAP)
{
TGGeArc arcTemp(ptE, pt2, dAngle3);
segTemp = arcTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
else if (bVal1) // 虚线起点在实线上
{
if (ptS.Distance(pt1) > _DIST_SNAP)
{
AcGeVector3d vt1 = pt1 - ptCenter;
AcGeVector3d vt2 = ptS - ptCenter;
double dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
TGGeArc arcTemp(pt1, ptS, dAngle);
TGGeCurveSegment segTemp;
segTemp = arcTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
else if (bVal2) // 虚线终点在实线上
{
if (ptE.Distance(pt2) > _DIST_SNAP)
{
AcGeVector3d vt1 = ptE - ptCenter;
AcGeVector3d vt2 = pt2 - ptCenter;
double dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
TGGeArc arcTemp(ptE, pt2, dAngle);
TGGeCurveSegment segTemp;
segTemp = arcTemp;
vevNew.push_back(segTemp);
bModify = true;
}
}
}
}
if (bModify)
{
vecDel.push_back(*it);
}
}
}
for (it = vevNew.begin(); it != vevNew.end(); it++)
{
vecSeg.push_back(*it);
}
for (it = vecDel.begin(); it != vecDel.end(); it++)
{
vecSeg.erase(std::find(vecSeg.begin(), vecSeg.end(), *it));
}
}
void TDbBaseWall::FiltrateSegment(std::vector<TGGeCurveSegment> &vecSeg) const
{
std::vector<TGGeCurveSegment>::iterator it1, it2;
TGGeArc arc1, arc2;
TGGeLine line1, line2;
TADSGePoint3d ptS1, ptE1, ptCenter1, ptS2, ptE2, ptCenter2;
int nSize = 0;
for (it1 = vecSeg.begin(); it1 != vecSeg.end(); nSize == vecSeg.size() ? it1++ : it1)
{
nSize = vecSeg.size(); // 记录修改前大小
it2 = it1;
++it2;
for (; it2 != vecSeg.end(); it2++)
{
if ((*it1).Is(CURVE_ARC) && it2->Is(CURVE_ARC))
{
arc1 = it1->GetArc();
arc2 = it2->GetArc();
double dRadius1 = arc1.GetRadius();
double dRadius2 = arc2.GetRadius();
arc1.Center(ptCenter1);
arc2.Center(ptCenter2);
arc1.GetStartPoint(ptS1);
arc1.GetEndPoint(ptE1);
arc2.GetStartPoint(ptS2);
arc2.GetEndPoint(ptE2);
if (fabs(dRadius1 - dRadius2) < _DIST_SNAP && ptCenter1.Distance(ptCenter2) < _DIST_SNAP) // 共圆
{
if ( ptS1.Distance(ptS2) < _DIST_SNAP && ptE1.Distance(ptE2) < _DIST_SNAP
|| ptS1.Distance(ptE2) < _DIST_SNAP && ptE1.Distance(ptS2) < _DIST_SNAP) // 重合
{
vecSeg.erase(it2);
break;
}
int bVal1 = false, bVal2 = false, bVal3 = false, bVal4 = false;
bVal1 = arc1.PtOnArc(ptS2);
bVal2 = arc1.PtOnArc(ptE2);
bVal3 = arc2.PtOnArc(ptS1);
bVal4 = arc2.PtOnArc(ptE1);
if (bVal1 && bVal2)
{
vecSeg.erase(it2);
break;;
}
else if (bVal3 && bVal4)
{
*it1 = *it2;
vecSeg.erase(it2);
break;
}
else if (bVal1)
{
TGGeArc arc(ptS1, ptS2, ptE2);
*it1 = arc;
vecSeg.erase(it2);
break;
}
else if (bVal2)
{
TGGeArc arc(ptS2, ptE2, ptE1);
*it1 = arc;
vecSeg.erase(it2);
break;
}
else if (bVal3)
{
TGGeArc arc(ptS2, ptS1, ptE1);
*it1 = arc;
vecSeg.erase(it2);
break;
}
else if (bVal4)
{
TGGeArc arc(ptS1, ptE1, ptE2);
*it1 = arc;
vecSeg.erase(it2);
break;
}
}
}
else if ((*it1).Is(CURVE_LINE) && it2->Is(CURVE_LINE))
{
line1 = it1->GetLine();
line2 = it2->GetLine();
ptS1 = line1.StartPoint();
ptE1 = line1.EndPoint();
ptS2 = line2.StartPoint();
ptE2 = line2.EndPoint();
if (ptS1.Distance(ptS2) < _DIST_SNAP && ptE1.Distance(ptE2) < _DIST_SNAP
|| ptS1.Distance(ptE2) < _DIST_SNAP && ptE1.Distance(ptS2) < _DIST_SNAP) // 重合
{
vecSeg.erase(it2);
break;
}
AcGeVector3d vt1 = ptE1 - ptS1, vt2 = ptE2 - ptS2;
AcDbLine lineA(ptS1, ptE1), lineB(ptS2, ptE2);
AcGePoint3d pt1;
lineB.getClosestPointTo(ptS1, pt1, Adesk::kTrue);
if (vt1.isParallelTo(vt2) && ptS1.Distance(pt1) < _DIST_SNAP) // 共线
{
AcGePoint3d pt2, pt3, pt4;
lineB.getClosestPointTo(ptS1, pt1);
lineB.getClosestPointTo(ptE1, pt2);
lineA.getClosestPointTo(ptS2, pt3);
lineA.getClosestPointTo(ptE2, pt4);
if (ptS1.Distance(pt1) < _DIST_SNAP || ptE1.Distance(pt2) < _DIST_SNAP
|| ptS2.Distance(pt3) < _DIST_SNAP || ptE2.Distance(pt4) < _DIST_SNAP) // 两直线存在交点
{
double dDist1 = ptS1.Distance(ptE1);
double dDist2 = ptS1.Distance(ptS2);
double dDist3 = ptS1.Distance(ptE2);
double dDist4 = ptE1.Distance(ptS2);
double dDist5 = ptE1.Distance(ptE2);
double dDist6 = ptS2.Distance(ptE2);
std::vector<double> vecDbl;
vecDbl.push_back(dDist1);
vecDbl.push_back(dDist2);
vecDbl.push_back(dDist3);
vecDbl.push_back(dDist4);
vecDbl.push_back(dDist5);
vecDbl.push_back(dDist6);
double dMax = *(std::max_element(vecDbl.begin(), vecDbl.end()));
if (fabs(dMax - dDist1) < _DIST_SNAP)
{
vecSeg.erase(it2);
}
else if (fabs(dMax - dDist2) < _DIST_SNAP)
{
vecSeg.erase(it2);
(*it1).SetEndPoint(ptS2);
}
else if (fabs(dMax - dDist3) < _DIST_SNAP)
{
vecSeg.erase(it2);
(*it1).SetEndPoint(ptE2);
}
else if (fabs(dMax - dDist4) < _DIST_SNAP)
{
vecSeg.erase(it2);
(*it1).SetStartPoint(ptS2);
}
else if (fabs(dMax - dDist5) < _DIST_SNAP)
{
vecSeg.erase(it2);
(*it1).SetStartPoint(ptE2);
}
else if (fabs(dMax - dDist6) < _DIST_SNAP)
{
vecSeg.erase(it2);
(*it1).SetStartPoint(ptS2);
(*it1).SetEndPoint(ptS2);
}
break;
}
}
}
}
}
}
TGGeCurveSegment TDbBaseWall::GetCenterLine()const
{
AcGePoint3d ptS, ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
double dBulge = 0.0;
GetAt(KEY_BULGE, dBulge);
return TGGeCurveSegment(ptS, ptE, dBulge);
}
// 取墙中心线的起点和终点,然后对这根线延伸1个长度
TGGeCurveSegment TDbBaseWall::GetLongBaseLine() const
{
// 转换cvBase
TGGeCurveSegment cvBase = GetCenterLine();
if (!cvBase.Is(CURVE_LINE)) // 只处理直线的情况
{
return cvBase;
}
// 将cvBase延伸一个墙体总宽度
double dWid = 0;
GetTotalWidth(dWid);
TADSGePointDir2d ptExtStart, ptExtEnd;
cvBase.Polar(-dWid, ptExtStart, TRUE);
cvBase.Polar(-dWid, ptExtEnd, FALSE);
cvBase.SetPoints(ptExtStart, ptExtEnd);
return cvBase;
}
// 获得墙体范围内的轴线或墙,梁
// 返回值: 位0x01--左轴线(墙或梁), 位0x02--右轴线(墙或梁)
int TDbBaseWall::GetAxises(int nDivType,const TADSGePoint3d &ptAt, TEntitySet &lEntAxis, TEntitySet &rEntAxis) const
{
TPickEntSet ss(SS_FREE);
//在获得墙体范围内的轴线时,采取扩大搜索范围的算法
TGGeCurveSegment segThis = GetLongBaseLine();
segThis.SetElevation(0.0);
TADSGePointDir2d ptExtStart, ptExtEnd;
segThis.Polar(-_AS_SYS_UNIT(g_nDistPrec), ptExtStart, TRUE);
segThis.Polar(-_AS_SYS_UNIT(g_nDistPrec), ptExtEnd, FALSE);
segThis.SetPoints(ptExtStart, ptExtEnd);
TGGePoly2D poly;
if (nDivType == 0 || nDivType == 3)//搜轴线直接用中心线搜
{
segThis.AsPoly2D(poly);
}
else
{
double dWidth(0);
GetTotalWidth(dWidth);
TGGeCurveSegment cv = segThis;
cv=segThis.Offset(OFFSET_RIGHT,dWidth*0.6,LS_FINITE);
cv.AsPoly2D(poly);
cv = segThis.Offset(OFFSET_LEFT,dWidth*0.6,LS_FINITE);
poly.AppendNode(cv.GetEndPoint(),-cv.GetBulge());
poly.AppendNode(cv.GetStartPoint());
}
TGGePoly poly1;
poly.MapToPolygon(poly1);
switch (nDivType)
{
case 0: //轴线等分加梁
case 3: //轴线等分插洞
if (ss.Get(_T("F"), TRBList(poly1.Fence()), NULL,
TRBList(RTDXF0, _T("LINE,ARC,CIRCLE"), 8, LAY_AXIS, NULL)) != RTNORM)
{
return 0;
}
break;
case 1: //等分梁
if (ss.Get(_T("cp"), TRBList(poly1.Polygon()), NULL,
TRBList(RTDXF0, _T("ATS_STRUBEAM"), NULL)) != RTNORM)
{
return 0;
}
break;
case 2: //等分墙
if (ss.Get(_T("cp"), TRBList(poly1.Polygon()), NULL,
TRBList(RTDXF0, _T("ATS_WALL"), NULL)) != RTNORM)
{
return 0;
}
break;
}
int nRetFlag = 0;
segThis.SetLineFlag(LS_FINITE);
ads_real nDist = segThis.PathDistance(TADSGePoint3d(ptAt.x, ptAt.y));
ads_real nDistLeft = 0.0, nDistRight = segThis.GetLength();
long ssLen = ss.Length();
BOOL bIsArc = segThis.Is(CURVE_ARC); //当前是否为弧梁或墙
for (long i = 0; i < ssLen; i++)
{
TEntitySet ent = ss[i];
TGGeCurveSegment segAxis;
// 根据等分类型获得轴线或墙中心线
switch (nDivType)
{
case 0:
case 3:
{
TGGeCurveSegment cvAxis(ent, LS_FINITE);
segAxis = cvAxis;
}
break;
case 1:
case 2:
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbBaseWall, pEnt);
if (pEnt)
{
segAxis = pEnt->GetLongBaseLine();
}
else
{
continue;
}
OPENOBJ_END();
break;
}
segAxis.SetElevation(0.0);
if (bIsArc)
{
if (!segAxis.Is(CURVE_LINE))
{
continue;
}
TGGeArc ar = segThis.GetArc();
double nDistTo = ar.GetCenterPt().Distance(&segAxis);
if (nDistTo > _DIST_SNAP)
{
continue;
}
}
// 求交
TADSGePoint3d ptInt[2];
int nInt = segThis.Intersection(segAxis, ptInt[0], ptInt[1]);
if (!nInt)
{
continue;
}
TADSGePoint3d ptInters;
if (nInt == 1)
{
ptInters = ptInt[0];
}
else
{
ptInters = TGGeLine(ptInt[0], ptInt[1]).NearPoint(TADSGePoint3d(ptAt.x, ptAt.y));
}
// 确定左右轴线
ads_real nDist0 = segThis.PathDistance(ptInters);
if (nDist0 < nDist)
{
if (nDist0 > nDistLeft)
{
nRetFlag |= 0x01;
nDistLeft = nDist0;
lEntAxis = ent;
}
}
else
{
if (nDist0 < nDistRight)
{
nRetFlag |= 0x02;
nDistRight = nDist0;
rEntAxis = ent;
}
}
}
return nRetFlag;
}
// 取得墙体等分的参数
// 返回值:RTNORM/RTERROR/RTCAN
// [in]nDivType:等分类型:0,轴线等分加梁,1,净跨等分加梁,2,等分加墙,3,等分插洞;
// [in]nOpWidth:插入对象的宽度;ptNew:插入点
// [out]segThis:等分线段;nOpeningCount:等分数目,仅插洞时有意义;nUnitDist:等分长度,仅插洞时有意义
// [out]pSet:插梁或墙时的边界对象,插洞时为空
int TDbBaseWall::GetIsoParameters(int nDivType, double nOpWidth, const TADSGePoint3d &ptNew, TGGeCurveSegment &segThis, int *nOpeningCount, double *nUnitDist, TEntitySet* pSet) const
{
int &nOpNum = *nOpeningCount;
ads_real &nUnitLen = *nUnitDist;
TGGeCurveSegment wall = GetCenterLine();
wall.SetLineFlag(LS_FINITE);
TEntitySet lEntAxis, rEntAxis;
AcGePoint3d ptLeft,ptRight;
GetAt(KEY_START,ptLeft);
GetAt(KEY_END,ptRight);
TADSGePoint3d ptLimLeft = ptLeft, ptLimRight = ptRight;
int nAxisNum = GetAxises(nDivType, ptNew, lEntAxis, rEntAxis);
// 求左右界限点
// 获得墙体范围内的轴线时,采取扩大搜索范围的算法
segThis = GetLongBaseLine();
segThis.SetLineFlag(LS_FINITE);
// 找到左侧轴线
if (nAxisNum & 0x01)
{
BOOL bOk = FALSE;
TGGeCurveSegment segLeft;
if (nDivType == 0 || nDivType == 3) //轴线等分加梁或插洞
{
TGGeCurveSegment cvLeft(lEntAxis, LS_FINITE);
segLeft = cvLeft;
}
else //净跨等分加梁或等分加墙
{
TGGeCurveSegment cvLeft;
OPENOBJ_BEGIN(lEntAxis, AcDb::kForRead, TDbBaseWall, pEnt);
if (pEnt)
{
cvLeft = pEnt->GetCenterLine();
if(nDivType == 1) //梁净跨等分
{
double dWidth = 0;
pEnt->GetTotalWidth(dWidth);
int nSide = cvLeft.OnWhichSide(ptNew);
cvLeft = cvLeft.Offset(nSide, dWidth*0.5, cvLeft.GetLineFlag());
}
segLeft = cvLeft;
}
OPENOBJ_END();
}
segLeft.SetElevation(segThis.StartPoint().z);
if (segThis.Intersection(segLeft, ptLimLeft, TADSGePoint3d()) != 1)
{
ptLimLeft = segThis.StartPoint();
}
lEntAxis.Redraw(3);
}
// 找到右侧轴线
if (nAxisNum & 0x02)
{
BOOL bOk = FALSE;
TGGeCurveSegment segRight;
if (nDivType == 0 || nDivType == 3) //轴线等分加梁或插洞
{
TGGeCurveSegment cvRight(rEntAxis, LS_FINITE);
segRight = cvRight;
}
else //净跨等分加梁或等分加墙
{
TGGeCurveSegment cvRight;
OPENOBJ_BEGIN(rEntAxis, AcDb::kForRead, TDbBaseWall, pEnt);
if (pEnt)
{
cvRight = pEnt->GetCenterLine();
if(nDivType == 1) //梁净跨等分
{
double dWidth = 0;
pEnt->GetTotalWidth(dWidth);
int nSide = cvRight.OnWhichSide(ptNew);
cvRight = cvRight.Offset(nSide, dWidth*0.5, cvRight.GetLineFlag());
}
segRight = cvRight;
}
OPENOBJ_END();
}
segRight.SetElevation(segThis.StartPoint().z);
if (segThis.Intersection(segRight, ptLimRight, TADSGePoint3d()) != 1)
{
ptLimRight = segThis.EndPoint();
}
rEntAxis.Redraw(3);
}
// 构造区间
segThis.SetPoints(ptLimLeft, ptLimRight);
{
int nMaxNum1 = TNumeric(segThis.GetLength() / nOpWidth).AsInt();
if (nOpNum > nMaxNum1 || nOpNum < 1)
{
nOpNum = 1;
}
CString strPrompt;
if (nDivType == 3)
{
strPrompt.Format(_T("\n指定参考轴线[S]/洞口个数(1~%d)<%d>:"), nMaxNum1, nOpNum);
}
else if (nDivType == 0)
{
strPrompt.Format(_T("\n指定参考轴线[S]/选择作为另一边界的梁<退出>:"));
}
else if (nDivType == 1)
{
strPrompt.Format(_T("\n指定参考梁[S]/选择作为另一边界的梁<退出>:"));
}
else if (nDivType == 2)
{
strPrompt.Format(_T("\n指定参考墙[S]/选择作为另一边界的墙<退出>:"));
}
int nCode = 0;
TEntitySet ent;
TCHAR szKeyword[80] = _T("");
if(nDivType == 3)
{
INITGET_BEG(RSG_NONEG | RSG_NOZERO, _T("S"));
nCode = ads_getint(strPrompt, &nOpNum);
INITGET_END();
if (nCode == RTKWORD)
{
ads_getinput(szKeyword);
}
}
else
{
CString strDxf(_T("ATS_STRUBEAM"));
if(nDivType == 2)
{
strDxf = _T("ATS_WALL");
}
TCHAR cKey;
nCode = SelectEntity(strPrompt, ent, TRBList(acutBuildList(RTDXF0, strDxf, NULL)), _T("S"), cKey);
szKeyword[0] = cKey;
}
// 默认轴线取消高亮
if (nAxisNum & 0x01)
{
lEntAxis.Redraw(4);
}
if (nAxisNum & 0x02)
{
rEntAxis.Redraw(4);
}
if (nCode == RTKWORD)
{
if (szKeyword[0] == _T('S'))
{
TEntitySet ent1, ent2;
ads_real nDist1 = 0.0, nDist2 = 0.0;
ads_real nDistPick = segThis.PathDistance(ptNew);
TADSGePointDir2d pt1, pt2;
int nFlag = 0;
if (nDivType == 0 || nDivType == 3)
{
TRBList mask(RTDXF0, _T("LINE,ARC,CIRCLE"), 8, LAY_AXIS, NULL);
if (ent1.FilterSelect(_T("\n第一根轴线:"), mask) == RTCAN)
{
return RTCAN;
}
}
else if (nDivType == 1)
{
TRBList mask(RTDXF0, _T("ATS_STRUBEAM"), NULL);
if (ent1.FilterSelect(_T("\n第一个参考梁:"), mask) == RTCAN)
{
return RTCAN;
}
}
else if (nDivType == 2)
{
TRBList mask(RTDXF0, _T("ATS_WALL"), NULL);
if (ent1.FilterSelect(_T("\n第一个参考墙:"), mask) == RTCAN)
{
return RTCAN;
}
}
double dWidthL = 0,dWidthR = 0;
if (!(!ent1))
{
ent1.Redraw(3);
TGGeCurveSegment cv, cv1 = wall;
if(nDivType == 0 || nDivType == 3)
{
TGGeCurveSegment cv2(ent1, LS_FINITE);
cv = cv2;
}
else
{
OPENOBJ_BEGIN(ent1, AcDb::kForRead, TDbBaseWall, pEnt);
if (pEnt)
{
cv = pEnt->GetCenterLine();
if(nDivType == 1) //梁净跨等分
{
pEnt->GetTotalWidth(dWidthL);
}
}
OPENOBJ_END();
}
if (cv1.Is(CURVE_LINE))
{
cv1.SetLineFlag(LS_INFINITE);
}
if (cv.Is(CURVE_LINE))
{
cv.SetLineFlag(LS_INFINITE);
}
cv.SetElevation(cv1.StartPoint().z);
if (cv1.Intersection(cv, pt1, TADSGePoint3d()) == 1)
{
nDist1 = cv1.PathDistance(pt1);
nFlag |= 0x01;
}
}
if (nDivType == 0 || nDivType == 3)
{
TRBList mask(RTDXF0, _T("LINE,ARC,CIRCLE"), 8, LAY_AXIS, NULL);
if (ent2.FilterSelect(_T("\n第二根轴线:"), mask) == RTCAN)
{
if (!!ent1)
{
ent1.Redraw(4);
}
return RTCAN;
}
}
else if (nDivType == 1)
{
TRBList mask(RTDXF0, _T("ATS_STRUBEAM"), NULL);
if (ent2.FilterSelect(_T("\n第二个参考梁:"), mask) == RTCAN)
{
if (!!ent1)
{
ent1.Redraw(4);
}
return RTCAN;
}
}
else if (nDivType == 2)
{
TRBList mask(RTDXF0, _T("ATS_WALL"), NULL);
if (ent2.FilterSelect(_T("\n第二个参考墙:"), mask) == RTCAN)
{
if (!!ent1)
{
ent1.Redraw(4);
}
return RTCAN;
}
}
if (!(!ent2))
{
ent2.Redraw(3);
TGGeCurveSegment cv, cv1 = wall;
if(nDivType == 0 || nDivType == 3)
{
TGGeCurveSegment cv2(ent2, LS_FINITE);
cv = cv2;
}
else
{
OPENOBJ_BEGIN(ent2, AcDb::kForRead, TDbBaseWall, pEnt);
if (pEnt)
{
cv = pEnt->GetCenterLine();
if(nDivType == 1) //梁净跨等分
{
pEnt->GetTotalWidth(dWidthR);
}
}
OPENOBJ_END();
}
if (cv1.Is(CURVE_LINE))
{
cv1.SetLineFlag(LS_INFINITE);
}
if (cv.Is(CURVE_LINE))
{
cv.SetLineFlag(LS_INFINITE);
}
cv.SetElevation(cv1.StartPoint().z);
if (cv1.Intersection(cv, pt2, TADSGePoint3d()) == 1)
{
nDist2 = cv1.PathDistance(pt2);
nFlag |= 0x02;
}
}
if ((nFlag & 0x01) && (nFlag & 0x02))
{
if (nDist1 < nDist2)
{
segThis.SetPoints(pt1, pt2);
if (nDivType == 1) //梁净跨等分
{
segThis.Polar(dWidthL*0.5, pt1, TRUE);
segThis.Polar(dWidthR*0.5, pt2, FALSE);
segThis.SetPoints(pt1, pt2);
}
}
else
{
segThis.SetPoints(pt2, pt1);
if (nDivType == 1) //梁净跨等分
{
segThis.Polar(dWidthR*0.5, pt2, TRUE);
segThis.Polar(dWidthL*0.5, pt1, FALSE);
segThis.SetPoints(pt2, pt1);
}
}
}
else
{
if (nFlag & 0x01)
{
if (nDistPick < nDist1)
{
segThis.SetPoints(pt1, ptLimRight);
if (nDivType == 1) //梁净跨等分
{
segThis.Polar(dWidthL*0.5, pt1, TRUE);
segThis.SetPoints(pt1, ptLimRight);
}
}
else
{
segThis.SetPoints(ptLimLeft, pt1);
if (nDivType == 1) //梁净跨等分
{
segThis.Polar(dWidthL*0.5, pt1, FALSE);
segThis.SetPoints(ptLimLeft, pt1);
}
}
}
else if (nFlag & 0x02)
{
if (nDistPick < nDist2)
{
segThis.SetPoints(pt2, ptLimRight);
if (nDivType == 1) //梁净跨等分
{
segThis.Polar(dWidthR*0.5, pt2, TRUE);
segThis.SetPoints(pt2, ptLimRight);
}
}
else
{
segThis.SetPoints(ptLimLeft, pt2);
if (nDivType == 1) //梁净跨等分
{
segThis.Polar(dWidthR*0.5, pt2, FALSE);
segThis.SetPoints(ptLimLeft, pt2);
}
}
}
}
if (nDivType == 3)
{
if (!!ent1)
{
ent1.Redraw(4);
}
if (!!ent2)
{
ent2.Redraw(4);
}
int nMaxNum = int(segThis.GetLength() / nOpWidth);
if (nMaxNum < 1)
{
adsout << _T("\n点取位置不能插洞口!");
return RTERROR;
}
adsout << _T("\n洞口个数(1~") << nMaxNum << _T(")<") << nOpNum << _T(">: ");
ads_initget(RSG_NONEG | RSG_NOZERO, NULL);
if (ads_getint(_T(""), &nOpNum) == RTCAN || nOpNum > nMaxNum)
{
return RTCAN;
}
}
else
{
// 取消高亮
if (!!ent1)
{
ent1.Redraw(4);
}
if (!!ent2)
{
ent2.Redraw(4);
}
CString strDxf(_T("ATS_STRUBEAM"));
if(nDivType == 2)
{
strPrompt.Format(_T("\n选择作为另一边界的墙<退出>:"));
strDxf = _T("ATS_WALL");
}
else
{
strPrompt.Format(_T("\n选择作为另一边界的梁<退出>:"));
}
nCode = SelectEntity(strPrompt, ent, TRBList(acutBuildList(RTDXF0, strDxf, NULL)));
if (nCode == RTNORM)
{
*pSet = ent;
}
else
{
return nCode;
}
}
}
}
else
{
if (nDivType == 3) //插洞
{
if (nCode == RTCAN)
{
return nCode;
}
else if (nOpNum > nMaxNum1)
{
adsout << _T("\n不能插入指定个数的洞口!");
return RTERROR;
}
}
else
{
if (nCode == RTNORM)
{
*pSet = ent;
}
else
{
return nCode;
}
}
}
}
ads_real nCurveLen = segThis.GetLength();
nUnitLen = nCurveLen / nOpNum; //单元长度
return RTNORM;
}
void TDbBaseWall::GetTotalWidth(double &dWidth)const
{
}
// 获得总高度
void TDbBaseWall::GetTotalHeight(double &dHeight)const
{
}
// 夹点消息后,更新自己边界
void TDbBaseWall::UpdateMeOnGripMsg(TAssocMsg assocMsg)
{
//不是夹点消息直接返回
if (assocMsg.GetMethod() != TAssocMsg::kMovegrippoint)
{
return;
}
assertWriteEnabled();
TGGeCurveSegment cvBase = GetCenterLine(); //形心线
if (!cvBase.Is(CURVE_LINE)) //仅处理直线情况
{
return;
}
int nLength = m_arAssocBWallIds.length();
if (nLength < 0)
{
return;
}
double dElevS = cvBase.GetStartPoint().z;
double dElevE = cvBase.GetEndPoint().z;
AcGeVector3d vtOffset = assocMsg.GetOffset();
AcGePoint3d ptTarget = assocMsg.GetTarget();
TADSGePoint3d pt = ptTarget;
cvBase.SetElevation(0);
TADSGePoint3d ptStart = cvBase.GetStartPoint();
TADSGePoint3d ptEnd = cvBase.GetEndPoint();
ptStart -= vtOffset;
ptEnd -= vtOffset;
TGGeCurveSegment cvSrc(ptStart, ptEnd, 0);
double dDir = cvBase.TGGeLine::Direction();
double dPrec = sin(PI/36); //同向精度5°
bool bMod = false; //记录是否中心线进行了延长处理
//找出与偏移方向斜交或平行的梁(垂直时梁不需要延伸)
for (int i = 0; i < nLength; i++)
{
OPENOBJ_BEGIN(m_arAssocBWallIds[i], AcDb::kForRead, TDbBaseWall, pEnt);
if (pEnt)
{
TGGeCurveSegment cvCL = pEnt->GetCenterLine();
if (!cvCL.Is(CURVE_LINE))
{
continue;
}
TVector3D vt3d = cvCL.GetEndPoint() - cvCL.GetStartPoint();
AcGeVector3d vtCL = vt3d.AsAcGeVector3d();
double dDirCL = cvCL.TGGeLine::Direction();
bool bStart = false, bEnd = false; //当前修改的端点标志
cvCL.SetElevation(0);
if (fabs(vtCL.dotProduct(vtOffset)) < _DIST_SNAP)
{
continue; //垂直
}
if (vtOffset.isParallelTo(vtCL)) //平行
{
}
else //斜交
{
cvSrc.Intersection(cvCL, pt, TADSGePoint3d());
int nPos = (pt&cvSrc);
if (nPos == PR_ONPT1) //起点
{
bStart = true;
}
else if (nPos == PR_ONPT2) //终点
{
bEnd = true;
}
}
cvCL.SetLineFlag(LS_INFINITE);
cvBase.SetLineFlag(LS_INFINITE);
TADSGePoint3d ptInter;
cvBase.Intersection(cvCL, ptInter, TADSGePoint3d());
cvBase.SetLineFlag(LS_FINITE);
if (bStart) //修改起点
{
bMod = true;
cvBase.SetStartPoint(ptInter);
}
else if (bEnd) //修改终点
{
bMod = true;
cvBase.SetEndPoint(ptInter);
}
else if ((ptInter&cvBase) == PR_EXTEND) //延长线上点
{
bMod = true;
if (ptInter.Distance2d(cvBase.GetStartPoint())
< ptInter.Distance2d(cvBase.GetEndPoint())) //延长起始点
{
cvBase.SetStartPoint(ptInter);
}
else
{
cvBase.SetEndPoint(ptInter);
}
}
}
OPENOBJ_END();
}
// 处理关联普通板
pt.z = 0;
nLength = m_arSlabIds.length();
for (i = 0; i < nLength; i++)
{
OPENOBJ_BEGIN(m_arSlabIds[i], AcDb::kForRead, TDbStruFloorSlab, pEnt);
if (pEnt)
{
int nType = 0;
GetAt(KEY_KIND, nType);
if (nType != 0) //仅处理普通板
{
continue;
}
TGGePoly2D polySrc;
pEnt->GetOutline(polySrc);
TGGePoly2D poly = polySrc;
poly.SetElevation(0);
int nPos = poly.HitTestOnCurve(pt);
if (nPos < 0) //选中边
{
int nLen = poly.TotalSegments();
int nPre = -nPos;
int nNext = -nPos;
if (nPre == 1)
{
nPre = nLen-1;
}
else
{
nPre = nPre-2;
}
if (nNext == nLen)
{
nNext = 0;
}
TGGeCurveSegment cvPre;
TGGeCurveSegment cvNext;
poly.Nth(nPre, cvPre);
poly.Nth(nNext, cvNext);
cvPre.SetLineFlag(LS_INFINITE);
cvNext.SetLineFlag(LS_INFINITE);
cvBase.SetLineFlag(LS_INFINITE);
//求交点
TADSGePoint3d ptVert;
TADSGePoint3d ptInter1,ptInter2;
int nNum = cvBase.Intersection(cvPre, ptInter1, ptInter2);
if (nNum == 1)
{
ptVert = *polySrc[-nPos-1];
ptVert.x = ptInter1.x;
ptVert.y = ptInter1.y;
*polySrc[-nPos-1] = ptVert;
}
else if (nNum == 2)
{
ptVert = *polySrc[-nPos-1];
if (ptVert.Distance2d(ptInter1) < ptVert.Distance2d(ptInter2))
{
ptVert.x = ptInter1.x;
ptVert.y = ptInter1.y;
}
else
{
ptVert.x = ptInter2.x;
ptVert.y = ptInter2.y;
}
*polySrc[-nPos-1] = ptVert;
}
if (-nPos == nLen)
{
nPos = 0;
}
else
{
nPos = -nPos;
}
nNum = cvBase.Intersection(cvNext, ptInter1, ptInter2);
if (nNum == 1)
{
ptVert = *polySrc[nPos];
ptVert.x = ptInter1.x;
ptVert.y = ptInter1.y;
*polySrc[nPos] = ptVert;
}
else if (nNum == 2)
{
ptVert = *polySrc[nPos];
if (ptVert.Distance2d(ptInter1) < ptVert.Distance2d(ptInter2))
{
ptVert.x = ptInter1.x;
ptVert.y = ptInter1.y;
}
else
{
ptVert.x = ptInter2.x;
ptVert.y = ptInter2.y;
}
*polySrc[nPos] = ptVert;
}
//调整楼板
if(pEnt->upgradeOpen() == Acad::eOk)
{
pEnt->SetOutlinePoly(polySrc);
pEnt->downgradeOpen();
}
}
}
OPENOBJ_END();
}
//中心线有修改
if (bMod)
{
//恢复标高
ptStart = cvBase.GetStartPoint();
ptEnd = cvBase.GetEndPoint();
ptStart.z = dElevS;
ptEnd.z = dElevE;
SetAt(KEY_START, ptStart.AsAcGePoint3d());
SetAt(KEY_END, ptEnd.AsAcGePoint3d());
}
}
// 抽象墙外框线
void TDbBaseWall::GetPoly2D(TGGePoly2D &poly2d) const
{
}
Adesk::Boolean TDbBaseWall::BreakAt(const TADSGePoint3d &ptLoc1, const TGGePoly2D *pPolyColu)
{
AcGePoint3d ptS,ptE;
GetAt(KEY_START, ptS);
GetAt(KEY_END, ptE);
//首先判断ptLoc是否在墙基范围内
TADSGePoint3d ptLoc = ptLoc1;
double nElev = ptS.z;
ptLoc.z = nElev;
TGGeCurveSegment cvCenter = GetCenterLine();
TADSGePoint3d ptProject;
if (cvCenter.ProjectToMe(ptLoc, ptProject) != RTNORM)
{
return Adesk::kFalse;
}
TADSGePoint3d ptStart = ptS;
TADSGePoint3d ptEnd = ptE;
if (pPolyColu)
{
TGGePoly2D polyColu = *pPolyColu;
polyColu.SetElevation(nElev);
if ((ptStart & polyColu) != PR_OUTSIDE || (ptEnd & polyColu) != PR_OUTSIDE)
{
return Adesk::kFalse;
}
}
else
{
if (ptLoc.Distance2d(ptProject) > _AS_SYS_UNIT(g_nDistPrec))
{
return Adesk::kFalse;
}
}
{
if ((ptProject & cvCenter) != PR_INSIDE)
{
return Adesk::kFalse;
}
if (ptStart.Distance2d(ptProject) < _AS_SYS_UNIT(g_nDistPrec)
|| ptEnd.Distance2d(ptProject) < _AS_SYS_UNIT(g_nDistPrec))
{
return Adesk::kFalse;
}
}
AcDbObjectIdArray holeIds;
GetAssocRelation(ASSOC_HOLE, holeIds);
//判断位置是否在洞内
Adesk::Boolean bInHole = Adesk::kFalse;
/*int nIdCount = holeIds.length();
for (int j = 0; j < nIdCount; j++)
{
AcDbObjectId id = holeIds[j];
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbStruWallHole, pEnt);
if (pEnt)
{
TGGePoly2D poly2d(1);
pEnt->GetOutlinePoly2D(0.0, poly2d, TGGeCurveSegment());
if ((ptProject & poly2d) == PR_INSIDE)
{
bInHole = Adesk::kTrue;
break;
}
}
OPENOBJ_END();
}*/
Adesk::Boolean bResult;
if (!bInHole) //位置不在门窗之内
{
TGGeCurveSegment segFirst = cvCenter, segSecond = cvCenter;
segFirst.SetPoints(ptStart, ptProject);
segSecond.SetPoints(ptProject, ptEnd);
// 两段的长度合理
if (segFirst.GetLength() > g_nMinLenWall && segSecond.GetLength() > g_nMinLenWall)
{
Acad::ErrorStatus es = upgradeOpen();
if (!(es == Acad::eOk || es == Acad::eWasOpenForWrite))
{
return Adesk::kFalse;
}
assertWriteEnabled();
g_bModifyAgain = false; //打断后需重新建立关联
bool bAdd = false;
double dWidth=0;
GetTotalWidth(dWidth);
//调整端点,有小短墙时不创建新对象
if (ptStart.Distance2d(ptProject) > dWidth)
{
SetAt(KEY_START, AcGePoint3d(ptStart));
SetAt(KEY_END, AcGePoint3d(ptProject));
SetAt(KEY_BULGE, segFirst.GetBulge());
}
else
{
if (ptEnd.Distance2d(ptProject) > dWidth)
{
SetAt(KEY_START, AcGePoint3d(ptProject));
SetAt(KEY_END, AcGePoint3d(ptEnd));
SetAt(KEY_BULGE, segSecond.GetBulge());
bAdd = true;
}
}
bResult = Adesk::kTrue;
downgradeOpen();
TAssocMsg assocMsg;
assocMsg.SetMethod(TAssocMsg::kAppend);
assocMsg.SetAssocId(objectId());
AddMsg(assocMsg);
AcDbObjectIdArray arIds;
GetAssocRelation(ASSOC_XY, arIds);
for(int i = 0; i < arIds.length(); i++)
{
TAssocMsg assocMsg;
assocMsg.SetMethod(TAssocMsg::kEdit);
assocMsg.SetAssocId(arIds[i]);
AddMsg(assocMsg);
}
if ((!bAdd) && (ptEnd.Distance2d(ptProject) > dWidth))
{
g_bModifyAgain = true; //打断后需重新建立关联
TDbBaseWall *pWall = NULL;
pWall = (TDbBaseWall *)clone();
if (pWall)
{
TPushMemVar<BOOL> pushVar(g_bMonitorDbAction, TRUE);
pWall->CopyPropertiesFrom(this, 0);
pWall->SetAt(KEY_START, AcGePoint3d(ptProject));
pWall->SetAt(KEY_END, AcGePoint3d(ptEnd));
pWall->SetAt(KEY_BULGE, segSecond.GetBulge());
pWall->AddToMSpace(Adesk::kTrue);
}
}
}
}
else
{
bResult = Adesk::kFalse;
}
return bResult;
}
//获得端点可以合并的连接墙
//bStart:true,起始端,false,终止端
//idAssoc:连接墙的ID
//返回值:1,成功获得连接墙, 0,不成功
BOOL TDbBaseWall::GetAssocWall(bool bStart, AcDbObjectId& idAssoc)
{
idAssoc.setNull();
if (m_arColumnIds.length() > 1)
{
//柱子个数大于1时,墙两端都有柱子,此时墙体不发生合并
return FALSE;
}
if (m_arAssocBWallIds.length() < 1)
{
return FALSE;
}
AcGePoint3d ptStart;
if (bStart)
{
GetAt(KEY_START, ptStart);
}
else
{
GetAt(KEY_END, ptStart);
}
if (m_arColumnIds.length() == 1)
{
OPENOBJ_BEGIN(m_arColumnIds[0], AcDb::kForRead, TDbColumn, pEnt);
if (pEnt)
{
TGGePoly2D polyout;
pEnt->GetOutline(polyout);
TADSGePoint3d pt(ptStart);
if (polyout.Length() > 0 )
{
pt.z = polyout[0]->z;
}
if ((pt & polyout) != PR_OUTSIDE)
{
//端点在柱子里,不合并
return FALSE;
}
}
OPENOBJ_END();
}
double dDistS = 0, dDistE = 0;
for (int i = 0; i < m_arAssocBWallIds.length(); i++)
{
OPENOBJ_BEGIN(m_arAssocBWallIds[i], AcDb::kForRead, TDbBaseWall, pEnt);
if (pEnt)
{
AcGePoint3d ptS,ptE;
pEnt->GetAt(KEY_START, ptS);
pEnt->GetAt(KEY_END, ptE);
dDistS = ptStart.distanceTo(ptS);
dDistE = ptStart.distanceTo(ptE);
if (dDistE < _DIST_SNAP || dDistS < _DIST_SNAP)
{
if (idAssoc.isNull())
{
idAssoc = m_arAssocBWallIds[i];
}
else
{
//端点处有多个墙时不合并
return FALSE;
}
}
}
OPENOBJ_END();
}
if (idAssoc.isNull())
{
return FALSE;
}
return TRUE;
}
BOOL TDbBaseWall::CanMerge(AcDbObjectId idWall)
{
return FALSE;
}
BOOL TDbBaseWall::MergeWith(AcDbObjectId idWall)
{
TGGeCurveSegment segCenter, segCenterOther;
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbBaseWall, pEnt);
if (pEnt)
{
segCenterOther = pEnt->GetCenterLine();
}
else
{
return FALSE;
}
OPENOBJ_END();
segCenter = GetCenterLine();
int bLineThis = segCenter.Is(CURVE_LINE), bLineOther = segCenterOther.Is(CURVE_LINE);
if (bLineThis != bLineOther)
{
//直线和弧线不合并
return FALSE;
}
if (bLineThis)
{
if (!IsSameDrt(segCenter.TGGeLine::Direction(), segCenterOther.TGGeLine::Direction(), _angSnap))
{ //不平行的不合并
return FALSE;
}
}
else
{
TGGeArc arc1 = segCenter.GetArc(),
arc2 = segCenterOther.GetArc();
if (!(fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt()))
{ //不是同心圆的不合并
return FALSE;
}
}
//比较属性
if (!CanMerge(idWall))
{
return FALSE;
}
int nPosFlag = 0;
if (segCenter.GetStartPoint() == segCenterOther.GetStartPoint())
{
nPosFlag = 1; //合并两个起点
}
else if (segCenter.GetStartPoint() == segCenterOther.GetEndPoint())
{
nPosFlag = 2; //合并自己的起点和另外的终点
}
else if (segCenter.GetEndPoint() == segCenterOther.GetEndPoint())
{
nPosFlag = 3; //合并两个终点
}
else if (segCenter.GetEndPoint() == segCenterOther.GetStartPoint())
{
nPosFlag = 4; //合并自己的终点和另外的起点
}
if (!nPosFlag)
{
return FALSE;
}
BOOL bCanMerge = FALSE;
TGGeCurveSegment seg;
//曲线类型相同
if (bLineThis)
{
if (nPosFlag == 4)
{
seg.SetPoints(segCenter.StartPoint(), segCenterOther.EndPoint());
bCanMerge = TRUE;
}
else if (nPosFlag == 2)
{
seg.SetPoints(segCenterOther.StartPoint(), segCenter.EndPoint());
bCanMerge = TRUE;
}
else if (nPosFlag == 1)
{
seg.SetPoints(segCenterOther.EndPoint(), segCenter.EndPoint());
bCanMerge = TRUE;
}
else if (nPosFlag == 3)
{
seg.SetPoints(segCenter.StartPoint(), segCenterOther.StartPoint());
bCanMerge = TRUE;
}
}
else
{
//TGGeArc arc1 = segCenter.GetArc(),
// arc2 = segCenterOther.GetArc();
if (nPosFlag == 4)
{
if (segCenter.GetStartPoint() == segCenterOther.GetEndPoint())
{
return FALSE;
}
seg = segCenter;
seg.SetPoints(segCenter.StartPoint(), segCenterOther.EndPoint());
bCanMerge = TRUE;
}
else if (nPosFlag == 2)
{
if (segCenterOther.GetStartPoint() == segCenter.GetEndPoint())
{
return FALSE;
}
seg = segCenter;
seg.SetPoints(segCenterOther.StartPoint(), segCenter.EndPoint());
bCanMerge = TRUE;
}
}
if (bCanMerge)
{
Acad::ErrorStatus es = upgradeOpen();
if (es == Acad::eOk)
{
SetAt(KEY_START, seg.StartPoint().AsAcGePoint3d());
SetAt(KEY_END,seg.EndPoint().AsAcGePoint3d());
SetAt(KEY_BULGE, seg.GetBulge());
OPENOBJ_BEGIN(idWall, AcDb::kForWrite, TDbBaseWall, pEnt);
if (pEnt)
{
AcDbObjectIdArray arIds;
pEnt->GetAssocRelation(ASSOC_ALL, arIds);
arIds.remove(objectId());
pEnt->RemoveAssocRelation(objectId());
for (int i=0;i<arIds.length();i++)
{
//关联移到合并后实体上
MakeAssocRelationDirect(arIds[i]);
//解除原有关联
pEnt->RemoveAssocRelation(arIds[i]);
TAssocMsg assocMsg;
assocMsg.SetMethod(TAssocMsg::kEdit);
assocMsg.SetAssocId(arIds[i]);
AddMsg(assocMsg);
}
pEnt->erase();
}
OPENOBJ_END();
return TRUE;
}
}
return FALSE;
}
// 裁剪梁的基础数组操作
void TDbBaseWall::SetBaseIds(const AcDbObjectIdArray& ids)
{
assertWriteEnabled();
m_arAssocZIds.setLogicalLength(0);
m_arAssocZIds = ids;
}
void TDbBaseWall::GetBaseIds(AcDbObjectIdArray& ids)
{
assertReadEnabled();
ids.setLogicalLength(0);
ids = m_arAssocZIds;
}
void TDbBaseWall::RemoveBaseIds(const AcDbObjectId& id)
{
assertWriteEnabled();
m_arAssocZIds.remove(id);
}
int TDbBaseWall::GetFirstVersion()const
{
return 10;
}
bool TDbBaseWall::IsModelEntity() const
{
return true;
}
void InitBaseWall(bool bTrue)
{
if (bTrue)
{
TDbBaseWall::rxInit();
#if (BASEWALL_AS_OBJ == 1)
acrxBuildClassHierarchy();
TDbBaseWall::InitMatchProtocol(TRUE);
#endif
}
else
{
#if (BASEWALL_AS_OBJ == 1)
TDbBaseWall::InitMatchProtocol(FALSE);
#endif
deleteAcRxClass(TDbBaseWall::desc());
}
}
#endif