2441 lines
69 KiB
C++
2441 lines
69 KiB
C++
|
|
//*****************************源程序修改情况记录*****************************
|
|
// 修 改 人: 成志峰
|
|
// 修改时间: 1999/7/27 07:49:15 PM
|
|
// 修改内容: 修改了function ExtendAWall() and function ExtendAndFix(),provide better ability.
|
|
//****************************************************************************
|
|
|
|
#include "stdafx.h"
|
|
#include "resource.h"
|
|
#include "dbxutil.h"
|
|
#include "actrans.h"
|
|
static const TCHAR *sMsgPrompt[] = {
|
|
#include "walledit.hpp"
|
|
};
|
|
|
|
// extern GEOAPI int XGetCorner(const XPoint &ptCorn1, const TCHAR *pszMsg, XPoint &ptCorn2);
|
|
//修墙角
|
|
static void FixTwoWall(TDbWall *&pWall1,TDbWall *&pWall2,ads_real precision);
|
|
static int CanFix(XCurveSegment &seg1,XCurveSegment &seg2,XPoint pt,BOOL flag,ads_real precision);
|
|
static void ExtendAndFix(XCurveSegment &seg1,XCurveSegment &seg2,TDbWall *&pWall1,TDbWall *&pWall2,XPoint ptInt,int result,AcDbObjectId &newId1,AcDbObjectId &newId2);
|
|
static void ExtendAWall(XCurveSegment &seg,TDbWall *&pWall,XPoint ptInt);
|
|
static BOOL ElongateAWall(XCurveSegment &seg,TDbWall *&pWall,XPoint ptInt);
|
|
//static BOOL EraseObj(AcDbObjectId &rId);
|
|
static void FixAllWall(PickSet &ssWalls,ads_real precision);
|
|
static int GetIntPoint(DList<XDbObject> &lstWalls,XPoint &pointInt1,XPoint &pointInt2);
|
|
static void ExtendAndFix(DList<XDbObject> &lstWall,XPoint ptInt);
|
|
//倒墙角
|
|
void FilletWall();
|
|
static BOOL InputFilletWall(TDbWall *&pWalla,TDbWall *&pWallb,ads_real &filletrad,XPoint &pt1,XPoint &pt2);
|
|
static int CanFillet(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pt2,ads_real &filletrad);
|
|
static BOOL FilletSameEntitys(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2);
|
|
//BOOL GetTempLayerId(AcDbObjectId &LayerId);
|
|
//AcDbObjectId createLine(AcGePoint3d startPt,AcGePoint3d endPt,AcDbObjectId &layerId);
|
|
//static AcDbObjectId createArc(TDbWall *&pWall,AcDbObjectId &layerId);
|
|
Adesk::Boolean appendToDb(AcDbEntity* pEntity,AcDbObjectId& rId);
|
|
//BOOL SetLayerOff(AcDbObjectId layerId,BOOL flag);
|
|
//static BOOL GetEndPoint(AcDbObjectId rId,XPoint &startPt,XPoint &endPt);
|
|
static int GetInterPoint(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pi);
|
|
//墙齐柱边
|
|
void AlignWall();
|
|
|
|
void ChamferWall();
|
|
BOOL InputChamferWall(TDbWall *&pWalla,TDbWall *&pWallb,ads_real &chamferDistA,ads_real &chamferDistB,XPoint &pt1,XPoint &pt2);
|
|
BOOL ChamferSameEntitys(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2);
|
|
BOOL ChamferSameEntitys1(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2);
|
|
int CanChamfer(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pt2,ads_real &chamferDistA,ads_real &chamferDistB);
|
|
|
|
|
|
class XSelectSameWalls
|
|
{
|
|
public:
|
|
DList<AcDbObjectId> m_lstWallsId;//返回的相关墙体ID链表
|
|
TDbWall *m_pWall;//选取的墙壁
|
|
XPoint m_ptPick;//选取点
|
|
BOOL m_flag; //当flag=TRUE,墙体指针是自己打开的,必须关闭、释放;
|
|
XPoint m_deviation;
|
|
|
|
protected:
|
|
int AppendWall(const Entity &e, int bMinusDrt, XPoint &ptNext);
|
|
|
|
public:
|
|
XSelectSameWalls()
|
|
{
|
|
m_pWall=NULL;
|
|
m_flag=FALSE;
|
|
};
|
|
|
|
~XSelectSameWalls()
|
|
{
|
|
if (m_flag && m_pWall)
|
|
m_pWall->close();
|
|
};
|
|
|
|
void Close()
|
|
{
|
|
if (m_flag && m_pWall)
|
|
m_pWall->close();
|
|
};
|
|
|
|
BOOL INIT(ads_name ent,ads_point pt);
|
|
BOOL INIT(AcDbObjectId &rId,ads_point pt);
|
|
BOOL INIT(TDbWall *&pWall,ads_point pt);
|
|
int GetWalls();//得到墙壁列表
|
|
XPoint GetDeviation();
|
|
// 设置宽度
|
|
void SetWidth(ads_real nLeftWidth, ads_real nRightWidth);
|
|
void GetCorners(XPointList &lstCorners);
|
|
// 获得曲线段
|
|
XCurveSegment GetCurveSegment() const;
|
|
};
|
|
|
|
XPoint XSelectSameWalls::GetDeviation()
|
|
{
|
|
XPoint pt;
|
|
ads_real size,per;
|
|
xg_getvar(_T("VIEWSIZE"),&size);
|
|
xg_getvar(_T("SCREENSIZE"),pt);
|
|
per=size/pt.y;
|
|
return XPoint(per*20,per*20);//20个像素点
|
|
}
|
|
|
|
BOOL XSelectSameWalls::INIT(AcDbObjectId &rId,ads_point pt)
|
|
{
|
|
AcDbObject *pObj=NULL;
|
|
if (acdbOpenObject(pObj,rId,AcDb::kForRead) != Acad::eOk || !pObj)
|
|
return FALSE;
|
|
|
|
TDbWall *pWall=NULL;
|
|
if ((pWall=TDbWall::cast(pObj)) == NULL)
|
|
{
|
|
pObj->close();
|
|
return FALSE;
|
|
}
|
|
if (pWall->Is(CURVE_LINE) || pWall->Is(CURVE_ARC))
|
|
{
|
|
m_ptPick=pt;
|
|
m_pWall=pWall;
|
|
m_flag=TRUE;
|
|
m_deviation=GetDeviation();
|
|
return TRUE;
|
|
}
|
|
ASSERT(0);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL XSelectSameWalls::INIT(ads_name ent,ads_point pt)
|
|
{
|
|
AcDbObjectId rId;
|
|
if (acdbGetObjectId(rId,ent) != Acad::eOk)
|
|
return FALSE;
|
|
return INIT(rId,pt);
|
|
}
|
|
BOOL XSelectSameWalls::INIT(TDbWall *&pWall,ads_point pt)
|
|
{
|
|
if (pWall->Is(CURVE_LINE) || pWall->Is(CURVE_ARC))
|
|
{
|
|
m_ptPick=pt;
|
|
m_pWall=pWall;
|
|
m_deviation=GetDeviation();
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// 得到墙壁列表并排序,圆墙不包括在内
|
|
int XSelectSameWalls::GetWalls()
|
|
{
|
|
AcDbObjectId rId;
|
|
rId=m_pWall->objectId();
|
|
m_lstWallsId.Append(new AcDbObjectId(rId));
|
|
for (int nDrt=0; nDrt<2; nDrt++) //两个方向
|
|
{
|
|
XPoint ptCorner=nDrt? m_pWall->StartPoint():m_pWall->EndPoint();
|
|
//AssureOnScreen(ptCorner, ptCorner);
|
|
XPoint ptLow=ptCorner-m_deviation, ptUp=ptCorner+m_deviation;
|
|
PickSet ssWallOnCorner(SS_FREE);
|
|
if (GetSafeSelection(ssWallOnCorner, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) == Acad::eOk)
|
|
{
|
|
long ssLen=ssWallOnCorner.Length();
|
|
for (long i=0L; i<ssLen; i++)
|
|
{
|
|
Entity ent=ssWallOnCorner[i];
|
|
if (acdbGetObjectId(rId,ent) != Acad::eOk)
|
|
continue;
|
|
if (rId == m_pWall->objectId())
|
|
continue;
|
|
if (AppendWall(ent, nDrt, ptCorner) == RTNORM)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
//递归
|
|
int XSelectSameWalls::AppendWall(const Entity &ee, int bMinusDrt, XPoint &ptNext)
|
|
{
|
|
if (m_lstWallsId.Length()>150)
|
|
return RTERROR;//堆栈深度最大50
|
|
Entity e=ee;
|
|
int bLine=m_pWall->Is(CURVE_LINE);
|
|
XLine ln,ln1;
|
|
XArc arc,arc1;
|
|
if (bLine)
|
|
ln=m_pWall->GetLine();
|
|
else
|
|
arc=m_pWall->GetArc();
|
|
|
|
TDbWall *pWall=NULL;
|
|
XDbObject obj(e,AcDb::kForRead);
|
|
if ((pWall=TDbWall::cast(obj.m_pObject)) == NULL || pWall->Is(CURVE_CIRCLE) || pWall->Is(CURVE_LINE) != bLine)
|
|
return RTERROR;//如果不是墙、是圆墙、或墙的类型不一致,退出;
|
|
|
|
if (bLine)
|
|
{
|
|
ln1=pWall->GetLine();
|
|
if (!CT_IsSameDrt(ln.Direction(), ln1.Direction(), _angSnap))
|
|
return RTERROR;
|
|
}
|
|
else
|
|
{
|
|
arc1=pWall->GetArc();
|
|
if (fabs(arc1.GetRadius()-arc.GetRadius())>_DIST_SNAP && arc1.GetCenterPt() != arc.GetCenterPt())
|
|
return RTERROR;
|
|
}
|
|
|
|
XCurveSegment seg=*pWall;
|
|
int nPrFlag=(ptNext & seg);
|
|
if (nPrFlag != PR_ONPT1 && nPrFlag != PR_ONPT2)
|
|
return RTERROR;
|
|
|
|
int bOk=0;
|
|
if (!bLine)
|
|
{
|
|
if (fabs(m_pWall->GetWidth(0)-pWall->GetWidth(0))<1.0E-5 && fabs(m_pWall->GetWidth(1)-pWall->GetWidth(1))<1.0E-5)
|
|
bOk=1;
|
|
}
|
|
else
|
|
{
|
|
if (CT_IsExactSameDrt(ln.Direction(), ln1.Direction(),_angSnap) &&
|
|
fabs(m_pWall->GetWidth(0)-pWall->GetWidth(0))<1.0E-5 && fabs(m_pWall->GetWidth(1)-pWall->GetWidth(1))<1.0E-5)
|
|
bOk=1;
|
|
else if (fabs(m_pWall->GetWidth(0)-pWall->GetWidth(0))<1.0E-5 && fabs(m_pWall->GetWidth(1)-pWall->GetWidth(1))<1.0E-5)
|
|
bOk=1;
|
|
}
|
|
|
|
if (bOk)
|
|
{
|
|
ptNext = nPrFlag == PR_ONPT1? pWall->EndPoint():pWall->StartPoint();
|
|
if (!bMinusDrt)
|
|
m_lstWallsId.Append(new AcDbObjectId(pWall->objectId()));
|
|
else
|
|
{
|
|
m_lstWallsId[0];
|
|
m_lstWallsId.Insert(new AcDbObjectId(pWall->objectId()));
|
|
}
|
|
|
|
//AssureOnScreen(ptNext, ptNext);//取下一段
|
|
XPoint ptLow=ptNext-m_deviation, ptUp=ptNext+m_deviation;
|
|
PickSet ssWallOnCorner(SS_FREE);
|
|
if (GetSafeSelection(ssWallOnCorner, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) == Acad::eOk)
|
|
{
|
|
long ssLen=ssWallOnCorner.Length();
|
|
for (long i=0L; i<ssLen; i++)
|
|
{
|
|
Entity ent=ssWallOnCorner[i];
|
|
if (ent == e)
|
|
continue;
|
|
if (AppendWall(ent, bMinusDrt, ptNext) == RTNORM)
|
|
break;
|
|
}
|
|
}
|
|
return RTNORM;
|
|
}
|
|
return RTERROR;
|
|
}
|
|
|
|
void XSelectSameWalls:: SetWidth(ads_real nLeftWidth, ads_real nRightWidth)
|
|
{
|
|
assert(m_pWall != NULL);
|
|
int bLine=m_pWall->Is(CURVE_LINE);
|
|
AcDbObjectId rId;
|
|
TDbWall *pWall;
|
|
for (int i=0; i<m_lstWallsId.Length(); i++)
|
|
{
|
|
rId=*m_lstWallsId[i];
|
|
if (acdbOpenObject((AcDbObject *&)pWall,rId,AcDb::kForWrite) != Acad::eOk)
|
|
continue;
|
|
if (bLine)
|
|
{
|
|
if (CT_IsExactSameDrt(pWall->XLine::Direction(), m_pWall->XLine::Direction(), _angSnap))
|
|
{
|
|
pWall->SetWidth(0,nLeftWidth);
|
|
pWall->SetWidth(1,nRightWidth);
|
|
}
|
|
else
|
|
{
|
|
pWall->SetWidth(0,nRightWidth);
|
|
pWall->SetWidth(1,nLeftWidth);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pWall->SetWidth(0,nLeftWidth);
|
|
pWall->SetWidth(1,nRightWidth);
|
|
}
|
|
pWall->close();
|
|
}
|
|
}
|
|
|
|
void XSelectSameWalls::GetCorners(XPointList &lstCorners)
|
|
{
|
|
AcDbObjectId rId;
|
|
TDbWall *pWall;
|
|
for (int i=0; i<m_lstWallsId.Length(); i++)
|
|
{
|
|
if (acdbOpenObject((AcDbObject *&)pWall,*m_lstWallsId[i],AcDb::kForRead) != Acad::eOk)
|
|
continue;
|
|
lstCorners.NewAppend(pWall->StartPoint());
|
|
lstCorners.NewAppend(pWall->EndPoint());
|
|
pWall->close();
|
|
}
|
|
}
|
|
|
|
XCurveSegment XSelectSameWalls::GetCurveSegment() const
|
|
{
|
|
AcDbObjectId rId,rId1;
|
|
TDbWall *pHead=NULL,*pTail=NULL;
|
|
rId=*m_lstWallsId.Head();
|
|
rId1=*m_lstWallsId.Tail();
|
|
acdbOpenObject((AcDbObject *&)pHead,rId,AcDb::kForRead);
|
|
acdbOpenObject((AcDbObject *&)pTail,rId1,AcDb::kForRead);
|
|
ASSERT(pHead && pTail && m_pWall);
|
|
XCurveSegment curve=*m_pWall;
|
|
assert(!curve.Is(CURVE_CIRCLE));
|
|
|
|
if (curve.Is(CURVE_ARC))
|
|
{
|
|
XArc arc=curve.GetArc();
|
|
if (pHead->objectId() != m_pWall->objectId()) // change startpoint of curve
|
|
{
|
|
// [2010-3-16 10:15 wubo] 移植到新Geo库
|
|
// arc.startAngle = pHead->GetArc().startAngle;
|
|
arc.SetStarAngle(pHead->GetArc().GetStarAngle());
|
|
}
|
|
if (pTail->objectId() != m_pWall->objectId()) // change EndPoint() of curve
|
|
{
|
|
// [2010-3-16 10:16 wubo] 移植到新Geo库
|
|
// arc.endAngle = pTail->GetArc().endAngle;
|
|
arc.SetEndAngle(pTail->GetArc().GetEndAngle());
|
|
}
|
|
curve = arc;
|
|
}
|
|
else if (curve.Is(CURVE_LINE))
|
|
{
|
|
if (pHead->objectId() != m_pWall->objectId())
|
|
curve.StartPoint() = CT_IsExactSameDrt(pHead->XLine::Direction(), curve.XLine::Direction(), _angSnap) ?
|
|
pHead->StartPoint() : pHead->EndPoint();
|
|
if (pTail->objectId() != m_pWall->objectId())
|
|
curve.EndPoint() =CT_IsExactSameDrt(pTail->XLine::Direction(), curve.XLine::Direction(), _angSnap) ?
|
|
pTail->EndPoint() : pTail->StartPoint();
|
|
}
|
|
pHead->close();
|
|
pTail->close();
|
|
return curve;
|
|
}
|
|
|
|
|
|
int CompareWallObjectId(const AcDbObjectId *id1, const void *id2)
|
|
{
|
|
if (*id1 == *(const AcDbObjectId *)id2)
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
void AlignWall()
|
|
{
|
|
XPoint ptPick,ptPick1;
|
|
if (XGetPoint(NULL, _T("\n请点取墙边应通过的点"), ptPick) != RTNORM)
|
|
return;
|
|
|
|
ptPick=Ucs2Wcs(ptPick);
|
|
Entity entWall,entWall1;
|
|
RBList maskWall(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL);
|
|
DList<AcDbObjectId> lstWalls,lstExclude;
|
|
AcDbObjectId rId;
|
|
|
|
{
|
|
//限制XSelectSameWalls的作用域,因为它打开了一个实体
|
|
XSelectSameWalls Walls;
|
|
do
|
|
{
|
|
if (ads_entsel(_T("\n请点取一段墙<退出>:"),entWall,ptPick1) != RTNORM)
|
|
return;
|
|
|
|
ptPick1=Ucs2Wcs(ptPick1);
|
|
if (Walls.INIT (entWall,ptPick1) != TRUE)
|
|
{
|
|
ads_printf(sMsgPrompt[2]);
|
|
continue;
|
|
}
|
|
|
|
XPoint pt;
|
|
XDbObject obj(entWall,AcDb::kForRead);
|
|
TDbWall *pWall=TDbWall::cast(obj.m_pObject);
|
|
if (pWall == NULL)
|
|
{
|
|
ads_printf(sMsgPrompt[2]);
|
|
continue;
|
|
}
|
|
|
|
pWall->ProjectToMe(ptPick,pt);
|
|
if (ads_distance(ptPick,pt)>(pWall->GetWidth(0)+pWall->GetWidth(1)))//if dist > width of wall
|
|
{
|
|
if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[31],sMsgPrompt[25],MB_YESNO) != IDYES)
|
|
{
|
|
//add by whl on 051224
|
|
lstExclude.Append(new AcDbObjectId(pWall->objectId()));
|
|
Walls.Close();
|
|
|
|
continue;
|
|
}
|
|
}
|
|
break;
|
|
}while(1);
|
|
|
|
if (Walls.GetWalls() != RTNORM)
|
|
{
|
|
OPENOBJ_BEGIN(entWall, AcDb::kForWrite, TDbWall, pWall);
|
|
if (pWall)
|
|
pWall->AlignTo(ptPick1, ptPick);
|
|
OPENOBJ_END();
|
|
return;
|
|
}
|
|
|
|
for (int i=0;i<Walls.m_lstWallsId .Length();i++)
|
|
lstWalls.Append(new AcDbObjectId(*(Walls.m_lstWallsId[i])));
|
|
}
|
|
|
|
int len=lstWalls.Length();
|
|
for (int i=0;i<len;i++)
|
|
{
|
|
rId=*lstWalls[i];
|
|
if (lstExclude.FindNode(&rId, CompareWallObjectId) == NULL)//add by whl on 051224
|
|
{
|
|
OPENOBJ_BEGIN(rId,AcDb::kForWrite,TDbWall,pWall);
|
|
if (pWall)
|
|
pWall->AlignTo(ptPick1, ptPick);
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class TWallTree:public WFlag
|
|
{
|
|
public:
|
|
static AcDbObjectIdArray s_idWallArray;
|
|
public:
|
|
AcDbObjectId m_idWall;
|
|
int m_nType;//0,起点与上层相连,1,终点与上层相连,根要区别
|
|
XPoint m_ptNew;
|
|
TWallTree *m_pParent;
|
|
PDList<TWallTree> m_lstStartWallTree;//起点外的所有子树
|
|
PDList<TWallTree> m_lstEndWallTree;//终点处的所有子树
|
|
public:
|
|
TWallTree(TWallTree*pParent):m_pParent(pParent) {};
|
|
TWallTree(AcDbObjectId id);
|
|
void MoveBase(XPoint ptNewBase);
|
|
|
|
void ClearColor()
|
|
{
|
|
TDbWall*pWall=NULL;
|
|
acdbOpenObject(pWall,m_idWall,AcDb::kForWrite);
|
|
if (pWall != NULL)
|
|
{
|
|
pWall->setColorIndex(256);
|
|
pWall->close();
|
|
for (m_lstStartWallTree.MoveToFirst();!m_lstStartWallTree.IsOut();m_lstStartWallTree.MoveToNext())
|
|
m_lstStartWallTree.GetCurData()->ClearColor();
|
|
for (m_lstEndWallTree.MoveToFirst();!m_lstEndWallTree.IsOut();m_lstEndWallTree.MoveToNext())
|
|
m_lstEndWallTree.GetCurData()->ClearColor();
|
|
}
|
|
}
|
|
void TWallTree::GetEndTree(Table<TWallTree*> &lstTree);
|
|
bool IsConnect(TWallTree* pWallTree)const;
|
|
bool GetNewPoint(XPoint&ptNew);//上层提供的新连接点
|
|
bool operator >(const TWallTree&)const { return false; }//ok
|
|
bool operator <(const TWallTree&)const { return false; }//ok
|
|
};
|
|
|
|
bool TWallTree::GetNewPoint(XPoint &ptNew)
|
|
{
|
|
if (m_pParent != NULL)
|
|
{
|
|
bool bStart=m_pParent->m_lstStartWallTree.Find(this) != NOT_FOUND;
|
|
TDbWall*pWall=NULL;
|
|
acdbOpenObject(pWall,m_pParent->m_idWall,AcDb::kForRead);
|
|
if (pWall != NULL)
|
|
{
|
|
ptNew=bStart?pWall->StartPoint():pWall->EndPoint();
|
|
pWall->close();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool TWallTree::IsConnect(TWallTree*pWallTree)const
|
|
{
|
|
DList<TWallData::IdDotStyle> lstStyle;
|
|
TDbWall* pWall=NULL;
|
|
acdbOpenObject(pWall,m_idWall,AcDb::kForRead);
|
|
if (pWall != NULL)
|
|
{
|
|
pWall->GetIdStyles(1-m_nType,lstStyle);
|
|
pWall->close();
|
|
for (long i=0;i<lstStyle.Length();i++)
|
|
if (pWallTree->m_idWall == lstStyle[i]->id)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
AcDbObjectIdArray TWallTree::s_idWallArray;
|
|
TWallTree::TWallTree(AcDbObjectId id):m_nType(-1),m_pParent(NULL)
|
|
{
|
|
ListQuene<TWallTree*> quene;
|
|
quene.EnQuene(this);
|
|
m_idWall=id;
|
|
s_idWallArray.append(id);
|
|
TWallTree *pWallTree;
|
|
while (quene.DeQuene(pWallTree))
|
|
{
|
|
TDbWall* pWall=NULL;
|
|
acdbOpenObject(pWall,pWallTree->m_idWall,AcDb::kForRead);
|
|
if (pWall != NULL)
|
|
{
|
|
DList<TWallData::IdDotStyle> lstStyleStart,lstStyleEnd;
|
|
|
|
pWall->GetIdStyles(0,lstStyleStart);
|
|
for (long i=0;i<lstStyleStart.Length();i++)
|
|
if (!s_idWallArray.contains(lstStyleStart[i]->id))
|
|
{
|
|
TDbWall* pWall1=NULL;
|
|
acdbOpenObject(pWall1,lstStyleStart[i]->id,AcDb::kForRead);
|
|
if (pWall1 != NULL)
|
|
{
|
|
s_idWallArray.append(lstStyleStart[i]->id);
|
|
|
|
TWallTree *pNewChild=new TWallTree(pWallTree);
|
|
if (pWall1->StartPoint().Distance2d(pWall->StartPoint())<pWall1->EndPoint().Distance2d(pWall->StartPoint()))
|
|
pNewChild->m_nType=0;
|
|
else
|
|
pNewChild->m_nType=1;
|
|
pNewChild->m_idWall=lstStyleStart[i]->id;
|
|
pWallTree->m_lstStartWallTree<<pNewChild;
|
|
quene.EnQuene(pNewChild);
|
|
pWall1->close();
|
|
}
|
|
}
|
|
|
|
pWall->GetIdStyles(1,lstStyleEnd);
|
|
for (i=0;i<lstStyleEnd.Length();i++)
|
|
if (!s_idWallArray.contains(lstStyleEnd[i]->id))
|
|
{
|
|
TDbWall* pWall1=NULL;
|
|
acdbOpenObject(pWall1,lstStyleEnd[i]->id,AcDb::kForRead);
|
|
if (pWall1 != NULL)
|
|
{
|
|
s_idWallArray.append(lstStyleEnd[i]->id);
|
|
|
|
TWallTree *pNewChild=new TWallTree(pWallTree);
|
|
if (pWall1->StartPoint().Distance2d(pWall->EndPoint())<pWall1->EndPoint().Distance2d(pWall->EndPoint()))
|
|
pNewChild->m_nType=0;
|
|
else
|
|
pNewChild->m_nType=1;
|
|
pNewChild->m_idWall=lstStyleEnd[i]->id;
|
|
pWallTree->m_lstEndWallTree<<pNewChild;
|
|
quene.EnQuene(pNewChild);
|
|
pWall1->close();
|
|
}
|
|
}
|
|
|
|
pWall->close();
|
|
}
|
|
}
|
|
#if ADS>16
|
|
s_idWallArray.removeAll();
|
|
#else
|
|
while (!s_idWallArray.isEmpty())
|
|
s_idWallArray.removeLast();
|
|
#endif
|
|
}
|
|
|
|
bool operator >(const XPoint&,const XPoint&) { return false; }
|
|
bool operator <(const XPoint&,const XPoint&) { return false; }
|
|
|
|
void TWallTree::MoveBase(XPoint ptNewBase)
|
|
{
|
|
ListQuene<TWallTree*> quene;
|
|
List<TWallTree*> lstOk;
|
|
List<TWallTree*> lstUnconnected;//旧待连接墙,新待连接墙
|
|
quene.EnQuene(this);
|
|
TWallTree*pWallTree;
|
|
while (quene.DeQuene(pWallTree))
|
|
{
|
|
pWallTree->GetNewPoint(ptNewBase);
|
|
TDbWall*pWall=NULL;
|
|
acdbOpenObject(pWall,pWallTree->m_idWall,AcDb::kForWrite);
|
|
if (pWall != NULL)
|
|
{
|
|
XCurveSegment cvOld=*pWall;
|
|
ptNewBase.z=pWall->GetElevation();
|
|
double nOffset=pWall->GetDist2Me(ptNewBase);
|
|
XCurveSegment segBase=pWall->XCurveSegment::Offset(nOffset, LS_FINITE);
|
|
pWall->assertWriteEnabled();
|
|
*(XCurveSegment*)pWall = segBase;
|
|
pWall->SetWidth(0, pWall->GetWidth(0)+nOffset);
|
|
pWall->SetWidth(1, pWall->GetWidth(1)-nOffset);
|
|
|
|
if (pWallTree->m_nType == 0)
|
|
pWall->StartPoint()=ptNewBase;
|
|
else if (pWallTree->m_nType == 1)
|
|
pWall->EndPoint()=ptNewBase;
|
|
else
|
|
{
|
|
if (cvOld.StartPoint().Distance2d(ptNewBase)<cvOld.EndPoint().Distance2d(ptNewBase))
|
|
{
|
|
pWallTree->m_nType=0;
|
|
pWall->StartPoint()=ptNewBase;
|
|
}
|
|
else
|
|
{
|
|
pWallTree->m_nType=1;
|
|
pWall->EndPoint()=ptNewBase;
|
|
}
|
|
}
|
|
|
|
for (pWallTree->m_lstStartWallTree.MoveToFirst();!pWallTree->m_lstStartWallTree.IsOut();pWallTree->m_lstStartWallTree.MoveToNext())
|
|
{
|
|
TWallTree* pChild=pWallTree->m_lstStartWallTree.GetCurData();
|
|
quene.EnQuene(pChild);
|
|
}
|
|
|
|
for (pWallTree->m_lstEndWallTree.MoveToFirst();!pWallTree->m_lstEndWallTree.IsOut();pWallTree->m_lstEndWallTree.MoveToNext())
|
|
{
|
|
TWallTree* pChild=pWallTree->m_lstEndWallTree.GetCurData();
|
|
quene.EnQuene(pChild);
|
|
}
|
|
|
|
BOOL bEnd=pWall->IsTermAt(1-pWallTree->m_nType);
|
|
pWall->close();
|
|
|
|
lstUnconnected.FindAndDel(pWallTree->m_pParent);
|
|
if (pWallTree->m_pParent != NULL)
|
|
lstOk<<pWallTree->m_pParent;
|
|
if (!bEnd)
|
|
{
|
|
bool bOk=false;
|
|
for (long i=0;i<lstUnconnected.GetLength();i++)
|
|
{
|
|
TWallTree *pWallTree1=lstUnconnected[i];
|
|
if (pWallTree->IsConnect(pWallTree1)&&pWallTree1->IsConnect(pWallTree))
|
|
{
|
|
TDbWall*pWall=NULL;
|
|
acdbOpenObject(pWall,pWallTree->m_idWall,AcDb::kForWrite);
|
|
if (pWall != NULL)
|
|
{
|
|
TDbWall* pWall1=NULL;
|
|
acdbOpenObject(pWall1,pWallTree1->m_idWall,AcDb::kForWrite);
|
|
if (pWall1 != NULL)
|
|
{
|
|
pWall->assertWriteEnabled();
|
|
XCurveSegment cv1=*pWall;
|
|
XCurveSegment cv2=*pWall1;
|
|
cv1.SetLineFlag(LS_INFINITE);
|
|
cv2.SetLineFlag(LS_INFINITE);
|
|
XPoint pt1,pt2;
|
|
int nRet=cv1.Intersection(cv2,pt1,pt2);
|
|
if (nRet>0)
|
|
{
|
|
if ((1-pWallTree->m_nType) == 0)
|
|
pWall->StartPoint()=pt1;
|
|
else
|
|
pWall->EndPoint()=pt1;
|
|
|
|
if ((1-pWallTree1->m_nType) == 0)
|
|
pWall1->StartPoint()=pt1;
|
|
else
|
|
pWall1->EndPoint()=pt1;
|
|
}
|
|
|
|
pWall1->close();
|
|
}
|
|
|
|
pWall->close();
|
|
}
|
|
|
|
lstUnconnected.Del(i);
|
|
lstOk<<pWallTree<<pWallTree1;
|
|
bOk=true;
|
|
break;
|
|
}
|
|
}
|
|
if (!bOk)
|
|
lstUnconnected<<pWallTree;
|
|
}
|
|
}
|
|
|
|
//#ifndef NDEBUG
|
|
// ClearColor();
|
|
// if (!quene.IsEmpty())
|
|
// {
|
|
// for (long i=0;i<lstOk.GetLength();i++)
|
|
// {
|
|
// pWallTree=lstOk[i];
|
|
// TDbWall*pWall=NULL;
|
|
// acdbOpenObject(pWall,pWallTree->m_idWall,AcDb::kForWrite);
|
|
// if (pWall != NULL)
|
|
// {
|
|
// pWall->setColorIndex(2);
|
|
// pWall->close();
|
|
// }
|
|
// }
|
|
//
|
|
// for (long i=0;i<lstUnconnected.GetLength();i++)
|
|
// {
|
|
// pWallTree=lstUnconnected[i];
|
|
// TDbWall*pWall=NULL;
|
|
// acdbOpenObject(pWall,pWallTree->m_idWall,AcDb::kForWrite);
|
|
// if (pWall != NULL)
|
|
// {
|
|
// pWall->setColorIndex(3);
|
|
// pWall->close();
|
|
// }
|
|
// }
|
|
// acedGetPoint(NULL,_T("\n确定继续:"),XPoint());
|
|
// }
|
|
//#endif
|
|
}
|
|
}
|
|
|
|
// add by wlw on 150327 修墙角2增强版修墙角使用
|
|
int IsIntersect(AcDbObjectId id1,AcDbObjectId id2)
|
|
{
|
|
OPENOBJ_BEGIN(id1, AcDb::kForRead, TDbWall, pwall1)
|
|
if (pwall1 == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
OPENOBJ_BEGIN(id2, AcDb::kForRead, TDbWall, pwall2)
|
|
if (pwall2 == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
if (pwall1->StartPoint().Distance2d(pwall2->StartPoint()) < _AS_SYS_UNIT(g_nDistPrec)
|
|
|| pwall1->StartPoint().Distance2d(pwall2->EndPoint()) < _AS_SYS_UNIT(g_nDistPrec))
|
|
{
|
|
return 1;//startpt
|
|
}
|
|
|
|
if (pwall1->EndPoint().Distance2d(pwall2->StartPoint()) < _AS_SYS_UNIT(g_nDistPrec)
|
|
|| pwall1->EndPoint().Distance2d(pwall2->EndPoint()) < _AS_SYS_UNIT(g_nDistPrec))
|
|
{
|
|
return 2;//Endpt
|
|
}
|
|
|
|
OPENOBJ_END()
|
|
OPENOBJ_END()
|
|
return 0;
|
|
}
|
|
//add by wlw on 150327修墙角2增强版修墙角使用
|
|
int GetIntersectPt(AcDbObjectId id1,AcDbObjectId id2, TADSGePoint3d& ptInter)
|
|
{
|
|
AcGePoint3dArray points;
|
|
OPENOBJ_BEGIN(id1, AcDb::kForRead, TDbWall, pwall1)
|
|
if (pwall1 == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
OPENOBJ_BEGIN(id2, AcDb::kForRead, TDbWall, pwall2)
|
|
if (pwall2 == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
AcDbLine ln1,ln2;
|
|
ln1.setStartPoint(AcGePoint3d(pwall1->StartPoint().x, pwall1->StartPoint().y,0.0));
|
|
ln1.setEndPoint(AcGePoint3d(pwall1->EndPoint().x, pwall1->EndPoint().y,0.0));
|
|
|
|
ln2.setStartPoint(AcGePoint3d(pwall2->StartPoint().x, pwall2->StartPoint().y,0.0));
|
|
ln2.setEndPoint(AcGePoint3d(pwall2->EndPoint().x, pwall2->EndPoint().y,0.0));
|
|
|
|
ln1.intersectWith(&ln2,AcDb::kExtendBoth,points);
|
|
if (points.length() > 0)
|
|
{
|
|
ptInter = points[0];
|
|
|
|
AcGePoint3d ptinter1,ptinter2;
|
|
ln1.getClosestPointTo(ptInter.AsAcGePoint3d(), ptinter1);
|
|
|
|
ln2.getClosestPointTo(ptInter.AsAcGePoint3d(), ptinter2);
|
|
|
|
if (ptInter.Distance2d(ptinter1) > ptInter.Distance2d(ptinter2))
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
}
|
|
OPENOBJ_END()
|
|
OPENOBJ_END()
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////
|
|
// add by wlw on 150327 修墙角2增强版修墙角使用
|
|
void GoEntFromInPts(AcDbObjectId idwall)
|
|
{
|
|
double dw = 100.0;
|
|
TGGeCurveSegment cvCenter;
|
|
OPENOBJ_BEGIN(idwall, AcDb::kForRead, TDbWall, pwall)
|
|
if (pwall == NULL)
|
|
{
|
|
return;
|
|
}
|
|
cvCenter = pwall->OffsetGeomCenter(LS_FINITE); // 得到墙的中心线
|
|
dw = pwall->GetWidth(4);
|
|
OPENOBJ_END()
|
|
TADSGePoint3d pt;
|
|
|
|
for (int n = 0; n < 2; n++)
|
|
{
|
|
if (n ==0)
|
|
{
|
|
pt = cvCenter.StartPoint();
|
|
}
|
|
else
|
|
{
|
|
pt = cvCenter.EndPoint();
|
|
}
|
|
|
|
RBList rbFilter = acutBuildList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL);
|
|
ads_point pt1, pt2;
|
|
TPickEntSet ssEnts(SS_FREE);
|
|
pt1[X] = pt.x;
|
|
pt1[Y] = pt.y;
|
|
pt1[Z] = pt.z;
|
|
acdbWcs2Ucs(pt1,pt1,false);
|
|
ads_point_set(pt1,pt2);
|
|
pt1[X] -= dw;
|
|
pt1[Y] += dw;
|
|
pt2[X] += dw;
|
|
pt2[Y] -= dw;
|
|
acedSSGet(_T("C"),pt1,pt2,rbFilter,ssEnts);
|
|
long l = 0;
|
|
TADSGePoint3d ptBase;
|
|
AcDbObjectIdArray ids;//没有相交的对象
|
|
|
|
ssEnts.AsIdArray(ids);
|
|
long len = ids.length();
|
|
TADSGePoint3d ptInter;
|
|
int nMod = 0, i = -1;
|
|
switch (len)
|
|
{
|
|
case 2:
|
|
{
|
|
if (IsIntersect(ids[0], ids[1]) == 0)
|
|
{//只有两个墙,并且不想交时才处理
|
|
|
|
nMod = GetIntersectPt(ids[0], ids[1], ptInter);
|
|
if (nMod == 1)
|
|
{
|
|
TWallGraph wGraph(ids[0]);
|
|
wGraph.MoveNode(ids[0], ptInter);
|
|
}
|
|
if (nMod == 2)
|
|
{
|
|
TWallGraph wGraph(ids[1]);
|
|
wGraph.MoveNode(ids[1], ptInter);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
ids.remove(idwall);
|
|
|
|
if (IsIntersect(idwall, ids[0]) == 0 && (IsIntersect(idwall, ids[1]) == 0))
|
|
{//三个墙,和其它两个都没有交点
|
|
|
|
nMod = GetIntersectPt(ids[0], ids[1], ptInter);
|
|
if (nMod > 0)
|
|
{//其它两个墙有交点
|
|
|
|
TWallGraph wGraph(idwall);
|
|
wGraph.MoveNode(idwall, ptInter);
|
|
}
|
|
else
|
|
{//三个墙都没有交点
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 4:
|
|
case 5:
|
|
{
|
|
int k = 0, j = -1;
|
|
if (len == 5)
|
|
{
|
|
for (i = 0; i < ids.length(); i++)
|
|
{
|
|
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, TDbWall, pwallw)
|
|
if (pwallw == NULL)
|
|
{
|
|
break;
|
|
}
|
|
if (pwallw->GetLength() < 200)
|
|
{
|
|
j = i;
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
if (j > -1)
|
|
{
|
|
ids.removeAt(j);
|
|
}
|
|
else
|
|
break;
|
|
|
|
}
|
|
ids.remove(idwall);
|
|
for (i = 0; i < ids.length(); i++)
|
|
{
|
|
if (IsIntersect(idwall, ids[i]) > 0)
|
|
{
|
|
k++;
|
|
j = i;
|
|
}
|
|
}
|
|
|
|
if (k == 1)
|
|
{//4个墙,和其它3个其中一个有交点。
|
|
AcDbObjectId idwall1 = ids[j];
|
|
ids.remove(idwall1);
|
|
|
|
if (IsIntersect(ids[0], ids[1]) > 0)
|
|
{//只有另外两个墙也有交点时才处理
|
|
nMod = GetIntersectPt(ids[0], ids[1], ptInter);
|
|
if (nMod > 0)
|
|
{//其它任意两个墙有交点,即可
|
|
|
|
TWallGraph wGraph(idwall);
|
|
wGraph.MoveNode(idwall, ptInter);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (k == 0)
|
|
{//4个墙,和其它3个都没有交点
|
|
for (i = 0; i < ids.length(); i++)
|
|
{
|
|
j = i+1;
|
|
if (j == 3)
|
|
{
|
|
j = 0;
|
|
}
|
|
if (IsIntersect(ids[i], ids[j]) > 0)
|
|
{
|
|
nMod = GetIntersectPt(ids[i], ids[j], ptInter);
|
|
if (nMod > 0)
|
|
{//其它任意两个墙有交点,即可
|
|
|
|
TWallGraph wGraph(idwall);
|
|
wGraph.MoveNode(idwall, ptInter);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
//////////////////////////////
|
|
// Command: 修墙角2增强版修墙角,但有bug暂时不公开
|
|
// add by wlw on 150327
|
|
void BrkWallEx()
|
|
{
|
|
// //add by xlc on 100520 优化算法
|
|
// EndModelRecordZone();
|
|
BeginModelRecordZone();
|
|
adsout << _T("\n请小范围框选需要处理的墙角、柱子或墙体造型.");
|
|
while (true)
|
|
{
|
|
XPoint pt1, pt2;
|
|
if (XGetPoint(NULL, _T("\n请点取第一个角点"), pt1) != RTNORM || XGetCorner(pt1, _T("\n点取另一个角点<退出>:"), pt2) != RTNORM)
|
|
{
|
|
EndModelRecordZone();
|
|
return;
|
|
}
|
|
|
|
//更新裁剪
|
|
RBList maskClip(RTDXF0, _T("TCH_COLUMN,TCH_WALL_PATCH,TCH_WALL,TCH_OPENING,TCH_CORNER_WINDOW,TCH_CURTAIN_WALL"), NULL);
|
|
PickSet ssClip(SS_FREE);
|
|
if (ssClip.Get(_T("C"), pt1, pt2, maskClip) == RTNORM)
|
|
{
|
|
AcDbObjectIdArray idArray,idwalls;
|
|
ssClip.AsIdArray(idArray);
|
|
long lCount = idArray.length();
|
|
long lwall(0),lother(0);
|
|
|
|
if (lCount != ssClip.Length())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for (long i = 0; i< ssClip.Length(); i++)
|
|
{
|
|
Entity ent = ssClip[i];
|
|
if (i > 100)
|
|
{
|
|
continue;
|
|
}
|
|
//更新裁剪
|
|
if (ent.Is(_T("TCH_WALL")) || ent.Is(_T("TCH_CURTAIN_WALL")))
|
|
{// modify by wlw on 150327 丰富对象裁剪类型
|
|
lwall++;
|
|
if (lwall > 30)
|
|
{
|
|
continue;
|
|
}
|
|
GoEntFromInPts(idArray[i]);
|
|
idwalls.append(idArray[i]);
|
|
|
|
}
|
|
|
|
//更新裁剪
|
|
if (ent.Is(_T("TCH_COLUMN")) || ent.Is(_T("TCH_OPENING")) || ent.Is(_T("TCH_CORNER_WINDOW")))
|
|
{
|
|
lother++;
|
|
if (lother > 20)
|
|
{
|
|
continue;
|
|
}
|
|
TArchCmdReactor::AddModifiedClip(idArray[i]);
|
|
TArchCmdReactor::UpdateClip();
|
|
}
|
|
|
|
//更新造型
|
|
if (ent.Is(_T("TCH_WALL_PATCH")))
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWallPatch, pPatch);
|
|
if (!pPatch)
|
|
continue;
|
|
|
|
XPoly2D polyOut0(1), polyOut(1);
|
|
pPatch->GetOutlinePoly(polyOut0);
|
|
if (!polyOut0)
|
|
continue;
|
|
double nFactor=polyOut0.PathArea()>0? -5.0 : 5.0;
|
|
polyOut0.QuickOffset(nFactor*_DIST_SNAP, polyOut);
|
|
|
|
XPoint ptLow, ptUp;
|
|
polyOut.GetExtend(ptLow, ptUp);
|
|
ptLow.z=ptUp.z=0;
|
|
|
|
pPatch->RemoveAllLinkages();
|
|
PickSet ssWalls(SS_FREE);
|
|
if (GetSafeSelection(ssWalls, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) != Acad::eOk)
|
|
continue;
|
|
|
|
long lWallCount=ssWalls.Length();
|
|
for (long idx=0L; idx<lWallCount; idx++)
|
|
{
|
|
OPENOBJ_BEGIN(ssWalls[idx], AcDb::kForWrite, TDbWall, pWall);
|
|
if (pWall)
|
|
{
|
|
pPatch->AddPatchId(pWall->objectId());
|
|
pWall->AddPatchId(pPatch->objectId());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
TArchCmdReactor::UpdateCorners();
|
|
TArchCmdReactor::ResetAll();
|
|
|
|
}
|
|
|
|
//更新墙角
|
|
std::vector<XCurveSegment> segVector;
|
|
lCount = idwalls.length();
|
|
if (lCount > 20)
|
|
{
|
|
continue;
|
|
}
|
|
for (long i=0; i < lCount; ++i)
|
|
{
|
|
OPENOBJ_BEGIN(idwalls[i], AcDb::kForRead, TDbWall, pWall)
|
|
if (pWall != NULL)
|
|
{
|
|
XCurveSegment curSeg;
|
|
curSeg = *pWall;
|
|
curSeg.SetLineFlag(LS_FINITE);
|
|
segVector.push_back(curSeg);
|
|
}
|
|
else
|
|
{
|
|
idwalls.removeAt(i);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
lCount = idwalls.length();
|
|
if (segVector.size() != lCount)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
XPoint ptInter[2], ptInt;
|
|
for (long m = 0; m < lCount; m++)
|
|
{
|
|
for (long j = 0; j < lCount; j++)
|
|
{
|
|
if (m == j)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
int nIntNum=segVector[m].Intersection(segVector[j], ptInter[0], ptInter[1]);
|
|
if (nIntNum == 0)
|
|
{
|
|
continue;
|
|
}
|
|
if (nIntNum > 0)
|
|
{
|
|
ptInt = ptInter[0];
|
|
}
|
|
OPENOBJ_BEGIN(idArray[m], AcDb::kForWrite, TDbWall, pWall1);
|
|
if (pWall1)
|
|
{
|
|
pWall1->assertWriteEnabled();
|
|
pWall1->BreakAt(ptInt, AcDbObjectId());
|
|
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
OPENOBJ_BEGIN(idArray[j], AcDb::kForWrite, TDbWall, pWall2);
|
|
if (pWall2)
|
|
{
|
|
pWall2->assertWriteEnabled();
|
|
pWall2->BreakAt(ptInt, AcDbObjectId());
|
|
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
TArchCmdReactor::UpdateCorners();
|
|
TArchCmdReactor::ResetAll();
|
|
|
|
}
|
|
}
|
|
EndModelRecordZone();
|
|
}
|
|
// 基线对齐
|
|
void OffsetWallBase()
|
|
{
|
|
TARCH_IMPEXP void ToggleWallBase();
|
|
BOOL bShowBase=DocGetShowBase();
|
|
if (!bShowBase)
|
|
ToggleWallBase();
|
|
|
|
XPoint ptNewBase;
|
|
while (XGetPoint(NULL, _T("\n请点取墙基线的新端点或新连接点"), ptNewBase) == RTNORM)
|
|
{
|
|
ptNewBase=Ucs2Wcs(ptNewBase);
|
|
PickSet ss(SS_FREE);
|
|
if (SelectEntities(_T("\n请选择墙体(注意:相连墙体的基线会自动联动!)<退出>:"), ss, RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL)) == RTNORM)
|
|
{
|
|
AcDbObjectIdArray idArray;
|
|
ss.AsIdArray(idArray);
|
|
for (long i=0;i<idArray.length();i++)
|
|
{
|
|
//TWallTree wTree(idArray[i]);
|
|
//wTree.MoveBase(ptNewBase);
|
|
TWallGraph wGraph(idArray[i]);
|
|
wGraph.MoveNode(idArray[i],ptNewBase);
|
|
}
|
|
|
|
TArchCmdReactor::UpdateCorners();
|
|
TArchCmdReactor::ResetAll();
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
if (!bShowBase)
|
|
ToggleWallBase();
|
|
}
|
|
//////////////////////////////
|
|
// Command: 修墙角
|
|
// Modify by ZJQ on 2001/11/29 解决多个交点时不能修墙角的问题
|
|
// Modify by WHL on 05060701 合并更新造型
|
|
// modify by whl on 050826 连续修理操作
|
|
// modify by whl on 051027 更新对象裁剪功能
|
|
|
|
void BrkWall()
|
|
{
|
|
//注释 by lgy 20111230 修墙角命令要求选择多个时也能同时修改
|
|
//add by xlc on 100520 优化算法
|
|
// BeginModelRecordZone();
|
|
//
|
|
//LABEL1:
|
|
// adsout << sMsgPrompt[4];
|
|
// while (true)
|
|
// {
|
|
// XPoint pt1, pt2;
|
|
// ads_real precision=500;//精度范围为100;
|
|
// if (XGetPoint(NULL, _T("\n请点取第一个角点"), pt1) != RTNORM || XGetCorner(pt1, _T("\n点取另一个角点<退出>:"), pt2) != RTNORM)
|
|
// {
|
|
// //add by xlc on 100520 优化算法
|
|
// EndModelRecordZone();
|
|
// return;
|
|
// }
|
|
//
|
|
// //更新裁剪
|
|
// RBList maskClip(RTDXF0, _T("TCH_COLUMN,TCH_WALL_PATCH,TCH_WALL,TCH_OPENING,TCH_CORNER_WINDOW"), NULL);
|
|
// PickSet ssClip(SS_FREE);
|
|
// if (ssClip.Get(_T("C"), pt1, pt2, maskClip) == RTNORM)
|
|
// {
|
|
// AcDbObjectIdArray idArray;
|
|
// ssClip.AsIdArray(idArray);
|
|
// int count=min(idArray.length(),20);
|
|
// for (long i=0;i<count;i++)
|
|
// TArchCmdReactor::AddModifiedClip(idArray[i]);
|
|
//
|
|
// TArchCmdReactor::UpdateClip();
|
|
// }
|
|
//
|
|
// //更新造型
|
|
// RBList mask1(RTDXF0, _T("TCH_WALL_PATCH"), NULL);
|
|
// PickSet ssPatches(SS_FREE);
|
|
// if (ssPatches.Get(_T("C"), pt1, pt2, mask1) == RTNORM)
|
|
// {
|
|
// long lCount=ssPatches.Length();
|
|
// for (long i=0L; i<lCount; i++)
|
|
// {
|
|
// Entity entPatch=ssPatches[i];
|
|
// OPENOBJ_BEGIN(entPatch, AcDb::kForWrite, TDbWallPatch, pPatch);
|
|
// if (!pPatch)
|
|
// continue;
|
|
//
|
|
// XPoly2D polyOut0(1), polyOut(1);
|
|
// pPatch->GetOutlinePoly(polyOut0);
|
|
// if (!polyOut0)
|
|
// continue;
|
|
// double nFactor=polyOut0.PathArea()>0? -5.0 : 5.0;
|
|
// polyOut0.QuickOffset(nFactor*_DIST_SNAP, polyOut);
|
|
//
|
|
// XPoint ptLow, ptUp;
|
|
// polyOut.GetExtend(ptLow, ptUp);
|
|
// ptLow.z=ptUp.z=0;
|
|
//
|
|
// pPatch->RemoveAllLinkages();
|
|
// PickSet ssWalls(SS_FREE);
|
|
// if (GetSafeSelection(ssWalls, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) != Acad::eOk)
|
|
// continue;
|
|
//
|
|
// long lWallCount=ssWalls.Length();
|
|
// for (long idx=0L; idx<lWallCount; idx++)
|
|
// {
|
|
// Entity entWall=ssWalls[idx];
|
|
// OPENOBJ_BEGIN(entWall, AcDb::kForWrite, TDbWall, pWall);
|
|
// if (pWall)
|
|
// {
|
|
// pPatch->AddPatchId(pWall->objectId());
|
|
// pWall->AddPatchId(pPatch->objectId());
|
|
// }
|
|
// OPENOBJ_END();
|
|
// }
|
|
// OPENOBJ_END();
|
|
// }
|
|
// }
|
|
//
|
|
// //更新墙角
|
|
// RBList mask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL);
|
|
// PickSet ssWalls(SS_FREE);
|
|
// if (ssWalls.Get(_T("C"), pt1, pt2, mask) != RTNORM)
|
|
// continue;
|
|
// XPoint ptMid;
|
|
// Midpoint(pt1, pt2, ptMid);
|
|
// ptMid=Ucs2Wcs(ptMid);
|
|
// long lCount=ssWalls.Length();
|
|
// if (lCount>=2)
|
|
// {
|
|
// //if (lCount == 2)
|
|
// //{
|
|
// // OPENOBJ_BEGIN(ssWalls[0L], AcDb::kForRead, TDbWall, pWall1);
|
|
// // if (pWall1)
|
|
// // {
|
|
// // OPENOBJ_BEGIN(ssWalls[1L], AcDb::kForRead, TDbWall, pWall2);
|
|
// // if (pWall2)
|
|
// // {
|
|
// // }
|
|
// // OPENOBJ_END();
|
|
// // }
|
|
// // OPENOBJ_END();
|
|
// //}
|
|
//
|
|
// XCurveSegment seg[2];
|
|
// for (long i=0L; i<2L; i++)
|
|
// {
|
|
// Entity ent=ssWalls[i];
|
|
// OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall);
|
|
// if (pWall)
|
|
// {
|
|
// pWall->assertWriteEnabled();
|
|
// seg[i]=*pWall;
|
|
// }
|
|
// else
|
|
// goto LABEL1;
|
|
// OPENOBJ_END();
|
|
// }
|
|
// // seg[0].flag=seg[1].flag=LS_FINITE;
|
|
// seg[0].SetLineFlag(LS_FINITE);
|
|
// seg[1].SetLineFlag(LS_FINITE);
|
|
// XPoint ptInter[2], ptInt;
|
|
// int nIntNum=seg[0].Intersection(seg[1], ptInter[0], ptInter[1]);
|
|
// if (nIntNum == 0)
|
|
// {
|
|
// if (lCount>=3)
|
|
// {
|
|
// Entity ent3=ssWalls[2L];
|
|
// OPENOBJ_BEGIN(ent3, AcDb::kForWrite, TDbWall, pWall);
|
|
// pWall->assertWriteEnabled();
|
|
// if (!pWall || pWall->Intersection(seg[0], ptInt, XPoint()) == 0)
|
|
// goto LABEL1;
|
|
// OPENOBJ_END();
|
|
// }
|
|
// else
|
|
// goto LABEL1;
|
|
// }
|
|
// else
|
|
// {
|
|
// if (nIntNum == 1)
|
|
// ptInt=ptInter[0];
|
|
// else
|
|
// ptInt=XLine(ptInter[0], ptInter[1]).NearPoint(ptMid);
|
|
// }
|
|
//
|
|
// for (i=0L; i<lCount; i++)
|
|
// {
|
|
// Entity ent=ssWalls[i];
|
|
// OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall);
|
|
// if (pWall)
|
|
// {
|
|
// pWall->assertWriteEnabled();
|
|
// pWall->BreakAt(ptInt, AcDbObjectId());
|
|
// }
|
|
// OPENOBJ_END();
|
|
// }
|
|
// }
|
|
//
|
|
// TArchCmdReactor::UpdateCorners();
|
|
// TArchCmdReactor::ResetAll();
|
|
// }
|
|
//
|
|
// //add by xlc on 100520 优化算法
|
|
// EndModelRecordZone();
|
|
BeginModelRecordZone();
|
|
adsout << sMsgPrompt[4];
|
|
|
|
while (true)
|
|
{
|
|
XPoint pt1, pt2;
|
|
ads_real precision=500;//精度范围为100;
|
|
if (XGetPoint(NULL, _T("\n请点取第一个角点"), pt1) != RTNORM || XGetCorner(pt1, _T("\n点取另一个角点<退出>:"), pt2) != RTNORM)
|
|
{
|
|
EndModelRecordZone();
|
|
return;
|
|
}
|
|
|
|
//更新裁剪
|
|
RBList maskClip(RTDXF0, _T("TCH_COLUMN,TCH_WALL_PATCH,TCH_WALL,TCH_OPENING,TCH_CORNER_WINDOW"), NULL);
|
|
PickSet ssClip(SS_FREE);
|
|
if (ssClip.Get(_T("C"), pt1, pt2, maskClip) == RTNORM)
|
|
{
|
|
AcDbObjectIdArray idArray;
|
|
ssClip.AsIdArray(idArray);
|
|
int count=min(idArray.length(),20);
|
|
for (long i=0;i<count;i++)
|
|
TArchCmdReactor::AddModifiedClip(idArray[i]);
|
|
|
|
TArchCmdReactor::UpdateClip();
|
|
}
|
|
//更新造型
|
|
RBList mask1(RTDXF0, _T("TCH_WALL_PATCH"), NULL);
|
|
PickSet ssPatches(SS_FREE);
|
|
if (ssPatches.Get(_T("C"), pt1, pt2, mask1) == RTNORM)
|
|
{
|
|
long lCount=ssPatches.Length();
|
|
for (long i=0L; i<lCount; i++)
|
|
{
|
|
Entity entPatch=ssPatches[i];
|
|
OPENOBJ_BEGIN(entPatch, AcDb::kForWrite, TDbWallPatch, pPatch);
|
|
if (!pPatch)
|
|
continue;
|
|
XPoly2D polyOut0(1), polyOut(1);
|
|
pPatch->GetOutlinePoly(polyOut0);
|
|
if (!polyOut0)
|
|
continue;
|
|
double nFactor=polyOut0.PathArea()>0? -5.0 : 5.0;
|
|
polyOut0.QuickOffset(nFactor*_DIST_SNAP, polyOut);
|
|
|
|
XPoint ptLow, ptUp;
|
|
polyOut.GetExtend(ptLow, ptUp);
|
|
ptLow.z=ptUp.z=0;
|
|
pPatch->RemoveAllLinkages();
|
|
PickSet ssWalls(SS_FREE);
|
|
if (GetSafeSelection(ssWalls, TRUE, ptLow, ptUp, _T("TCH_WALL,TCH_CURTAIN_WALL")) != Acad::eOk)
|
|
continue;
|
|
|
|
long lWallCount=ssWalls.Length();
|
|
for (long idx=0L; idx<lWallCount; idx++)
|
|
{
|
|
Entity entWall=ssWalls[idx];
|
|
OPENOBJ_BEGIN(entWall, AcDb::kForWrite, TDbWall, pWall);
|
|
if (pWall)
|
|
{
|
|
pPatch->AddPatchId(pWall->objectId());
|
|
pWall->AddPatchId(pPatch->objectId());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
|
|
//更新墙角
|
|
RBList mask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL);
|
|
PickSet ssWalls(SS_FREE);
|
|
if (ssWalls.Get(_T("C"), pt1, pt2, mask) != RTNORM)
|
|
continue;
|
|
XPoint ptMid;
|
|
Midpoint(pt1, pt2, ptMid);
|
|
ptMid=Ucs2Wcs(ptMid);
|
|
long lCount=ssWalls.Length();
|
|
|
|
if (lCount < 20)
|
|
{
|
|
std::vector<XCurveSegment> segVector;
|
|
for (long i=0L; i<lCount; i++)
|
|
{
|
|
Entity ent=ssWalls[i];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall);
|
|
if (pWall)
|
|
{
|
|
XCurveSegment curSeg;
|
|
pWall->assertWriteEnabled();
|
|
curSeg = *pWall;
|
|
segVector.push_back(curSeg);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
//modify by lgy 20120213 15平台编译不通过
|
|
// for (long i = 0L; i < lCount; i++)
|
|
// {
|
|
// segVector[i].SetLineFlag(LS_FINITE);
|
|
// }
|
|
for (long j = 0L; j < lCount; j++)
|
|
{
|
|
segVector[j].SetLineFlag(LS_FINITE);
|
|
}
|
|
|
|
XPoint ptInter[2], ptInt; //ptInter记录两线交点, ptInt记录要修墙角的点
|
|
//modify by lgy 20120213 15平台编译不通过
|
|
//for (long i = 0L; i < lCount; i++)
|
|
for (long m = 0L; m < lCount; m++)
|
|
{
|
|
for (long j = 0; j < lCount; j++)
|
|
{
|
|
//modify by lgy 20120213 15平台编译不通过
|
|
//if (i == j)
|
|
//{
|
|
// continue;
|
|
//}
|
|
if (m == j)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
int nIntNum=segVector[m].Intersection(segVector[j], ptInter[0], ptInter[1]);
|
|
if (nIntNum == 0)
|
|
{
|
|
continue;
|
|
}
|
|
if (nIntNum > 0)
|
|
{
|
|
ptInt = ptInter[0];
|
|
}
|
|
Entity ent=ssWalls[m];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall);
|
|
if (pWall)
|
|
{
|
|
pWall->assertWriteEnabled();
|
|
pWall->BreakAt(ptInt, AcDbObjectId());
|
|
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
ent=ssWalls[j];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbWall, pWall);
|
|
if (pWall)
|
|
{
|
|
pWall->assertWriteEnabled();
|
|
pWall->BreakAt(ptInt, AcDbObjectId());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
TArchCmdReactor::UpdateCorners();
|
|
TArchCmdReactor::ResetAll();
|
|
}
|
|
EndModelRecordZone();
|
|
}
|
|
|
|
|
|
/* * * * * * * * * * * * * * * 倒 墙 角 的 函 数 * * * * * * * * * * * * * * */
|
|
//使用的方法如下:1:直接计算2:按照给定的墙体填充直线以及圆弧实体,调用Autocad的命令Fillet
|
|
//得到产生的圆弧以后在按照该圆弧生成弧线墙.该方法完全模仿了AUTOCAD的命令.
|
|
void FilletWall()
|
|
{
|
|
TDbWall *pWalla=NULL,*pWallb=NULL;
|
|
ads_real filletrad;
|
|
XPoint pt1,pt2;
|
|
if (InputFilletWall(pWalla,pWallb,filletrad,pt1,pt2) != TRUE)
|
|
return;//输入错误
|
|
|
|
if (!CanFillet(pWalla,pWallb,pt1,pt2,filletrad))//如果不能倒角
|
|
{
|
|
pWalla->close();
|
|
pWallb->close();
|
|
return;
|
|
}
|
|
FilletSameEntitys(pWalla,pWallb,(ads_real *)pt1,(ads_real *)pt2);
|
|
pWalla->close();
|
|
pWallb->close();
|
|
return;
|
|
}
|
|
|
|
BOOL InputFilletWall(TDbWall *&pWalla,TDbWall *&pWallb,ads_real &filletrad,XPoint &pt1,XPoint &pt2)
|
|
{
|
|
Entity en1,en2;
|
|
AcDbEntity *pEnt=NULL;
|
|
AcDbObjectId WallObjId1,WallObjId2;
|
|
do
|
|
{
|
|
int es;
|
|
VERIFY(xg_getvar(_T("FilletRad"),&filletrad) == RTNORM);
|
|
adsout << _T("\n选择第一段墙或 [设圆角半径(R),当前=")<<Dist2Str(filletrad)<<_T("]<退出>: ");
|
|
INITGET_BEG(0, _T("R"));
|
|
es = en1.FilterSelect(_T(""), RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL),pt1);
|
|
INITGET_END();
|
|
|
|
if (es == RTKWORD)
|
|
{
|
|
es = XGetDist(NULL,sMsgPrompt[16],filletrad,RSG_NONEG);
|
|
if (es == RTNORM)
|
|
xg_setvar(_T("FilletRad"),filletrad);
|
|
continue;
|
|
}
|
|
|
|
if (es != RTNORM)
|
|
return FALSE;
|
|
acdbGetObjectId(WallObjId1,en1);
|
|
acdbOpenAcDbEntity(pEnt,WallObjId1,AcDb::kForWrite);
|
|
if (pEnt == NULL)
|
|
return FALSE;
|
|
pWalla = (TDbWall *)pEnt;
|
|
break;
|
|
}while(1);
|
|
|
|
pWalla->highlight();
|
|
do
|
|
{
|
|
VERIFY(pWalla->downgradeOpen() == Acad::eOk);
|
|
int es = en2.FilterSelect(_T("\n选择另一段墙<退出>:"),RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL),pt2);
|
|
VERIFY(pWalla->upgradeOpen() == Acad::eOk);
|
|
if (es != RTNORM)
|
|
{
|
|
pWalla->unhighlight();
|
|
pWalla->close();
|
|
return FALSE;
|
|
}
|
|
|
|
if (en1 == en2)
|
|
{
|
|
adsout << _T("\n请选择不同的两段墙!");
|
|
continue;
|
|
}
|
|
acdbGetObjectId(WallObjId2,en2);
|
|
pEnt=NULL;
|
|
acdbOpenAcDbEntity(pEnt,WallObjId2,AcDb::kForWrite);
|
|
pWalla->unhighlight();
|
|
if (pEnt == NULL)
|
|
return FALSE;
|
|
pWallb = (TDbWall *)pEnt;
|
|
break;
|
|
}while(1);
|
|
|
|
//保证 Undo 成功
|
|
pWalla->assertWriteEnabled();
|
|
pWallb->assertWriteEnabled();
|
|
return TRUE;
|
|
}
|
|
|
|
//判断墙壁能否倒角.所有不偏心的墙都可以;
|
|
//如果墙体偏心,有时可以调节能得到正确的结果
|
|
int CanFillet(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pt2,ads_real &filletrad)
|
|
{
|
|
if (filletrad<1.0E-3)
|
|
return TRUE;
|
|
if (pWalla->GetStyle() != pWallb->GetStyle())
|
|
{
|
|
ads_printf(sMsgPrompt[19]);
|
|
return 0;
|
|
}
|
|
if (fabs(pWalla->GetWidth()-pWallb->GetWidth())>1.0E-3)
|
|
{
|
|
ads_printf(sMsgPrompt[20]);
|
|
return 0;
|
|
}
|
|
if (fabs(pWalla->GetWidth(0)-pWalla->GetWidth (1))<1.0E-3 &&
|
|
fabs(pWallb->GetWidth(0)-pWallb->GetWidth (1))<1.0E-3)//如果不偏心
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
//如果是偏心墙,考虑两段墙壁的偏心情况
|
|
XPoint pi;
|
|
int intn,ret1,ret2;
|
|
if ((intn=GetInterPoint(pWalla,pWallb,pt1,pi)) == 0) //不相交(平行)也可以倒角,但是必须是倒角半径和相差的距离相同
|
|
{
|
|
ads_printf(sMsgPrompt[23]);
|
|
return 0;
|
|
}
|
|
XCurveSegment seg1=*pWalla;
|
|
XCurveSegment seg2=*pWallb;
|
|
ret1=pi&seg1;
|
|
ret2=pi&seg2;
|
|
if (ret1 == 3 || ret2 == 3)//如果交点在墙壁内部
|
|
{
|
|
ads_real temp;
|
|
BOOL flag1=FALSE,flag2=FALSE,flaga=FALSE,flagb=FALSE;
|
|
if (ads_distance(pWalla->StartPoint() ,pt1)<ads_distance(pWalla->StartPoint() ,pi))
|
|
flag1=TRUE;//拾取点在起始点和交点之间;
|
|
if (ads_distance(pWallb->StartPoint() ,pt2)<ads_distance(pWallb->StartPoint() ,pi))
|
|
flag2=TRUE;//拾取点在起始点和交点之间;
|
|
if (pWalla->GetWidth(0)<pWalla->GetWidth(1))
|
|
flaga=TRUE;//左小于右
|
|
if (pWallb->GetWidth(0)<pWallb->GetWidth(1))
|
|
flagb=TRUE;//左小于右
|
|
if (flag1 && flag2 && flaga && flagb || flag1 && flag2 && !flaga && !flagb ||
|
|
flag1 && !flag2 && flaga && !flagb || flag1 && !flag2 && !flaga && flagb ||
|
|
!flag1 && flag2 && flaga && !flagb || !flag1 && flag2 && !flaga && flagb ||
|
|
!flag1 && !flag2 && flaga && flagb || !flag1 && !flag2 && !flaga && !flagb)
|
|
{
|
|
if (filletrad>1E-3)
|
|
{
|
|
if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[24],sMsgPrompt[25],MB_YESNO) != IDYES)
|
|
return 0;
|
|
temp=pWallb->GetWidth(0);
|
|
pWallb->SetWidth(0,pWallb->GetWidth(1));
|
|
pWallb->SetWidth(1,temp);
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
else if (flag1 && flag2 && flaga && !flagb || flag1 && flag2 && !flaga && flagb ||
|
|
flag1 && !flag2 && flaga && flagb || flag1 && !flag2 && !flaga && !flagb ||
|
|
!flag1 && flag2 && flaga && flagb || !flag1 && flag2 && !flaga && !flagb ||
|
|
!flag1 && !flag2 && !flaga && flagb || !flag1 && !flag2 && flaga && !flagb)
|
|
{
|
|
return 1;
|
|
}
|
|
ads_printf(sMsgPrompt[26]);
|
|
return 0;
|
|
}
|
|
|
|
//以下是交点在墙壁外面
|
|
if (fabs(pWalla->GetWidth (0)-pWallb->GetWidth (0))<1.0E-3 && fabs(pWalla->GetWidth (1)-pWallb->GetWidth (1))<1.0E-3)
|
|
{//如果两段墙壁的左右偏心相同:必须进一步考虑交点是否在墙内.
|
|
if (ads_distance(pWalla->EndPoint() ,pi)<ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)<ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段起点、第一段终点、交点、第二段起点、第二段终点的排列顺序,没有问题
|
|
else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序,也没有问题
|
|
else// 否则,不是按顺序的情况:调整?
|
|
{
|
|
if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[24],sMsgPrompt[25],MB_YESNO) != IDYES)
|
|
return 0;
|
|
if (ads_distance(pWalla->StartPoint() ,pi)>ads_distance(pWalla->EndPoint() ,pi))
|
|
{//如果是第一段起点、第一段终点、交点的顺序,把第二段墙换以下顺序;
|
|
XPoint pt=pWallb->StartPoint() ;
|
|
pWallb->StartPoint() =pWallb->EndPoint() ;
|
|
pWallb->EndPoint() =pt;
|
|
}
|
|
else//如果是第一段终点、第一段起点、交点的顺序,把第二段墙换以下顺序;
|
|
{
|
|
XPoint pt=pWallb->EndPoint() ;
|
|
pWallb->EndPoint() =pWallb->StartPoint();
|
|
pWallb->StartPoint() =pt;
|
|
}
|
|
return 2;
|
|
}
|
|
}
|
|
else if (fabs(pWalla->GetWidth (0)-pWallb->GetWidth (1))<1.0E-3 && fabs(pWalla->GetWidth (1)-pWallb->GetWidth (0))<1.0E-3)
|
|
{//如果两段墙壁的左右偏心相刚好相反:必须进一步考虑交点是否在墙内.
|
|
if (ads_distance(pWalla->EndPoint() ,pi)<ads_distance(pWalla->StartPoint() ,pi)
|
|
&& ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段起点、第一段终点、交点、第二段终点、第二段起点的排列顺序,没有问题
|
|
else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi)
|
|
&& ads_distance(pWallb->StartPoint() ,pi)<ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段终点、第一段起点、交点、第二段起点、第二段终点的排列顺序,也没有问题
|
|
else// 否则,不是按顺序的情况:调整?
|
|
{
|
|
AfxMessageBox(sMsgPrompt[21]);
|
|
return 0;
|
|
}
|
|
}
|
|
else //否则:如果两段墙壁的左右偏心不相同
|
|
{
|
|
//del by fxj 090511 偏心不同,不能倒角
|
|
//if (ads_distance(pWalla->EndPoint() ,pi)<ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->EndPoint() ,pi)<ads_distance(pWallb->StartPoint(),pi))
|
|
// return 1;//如果是第一段起点、第一段终点、交点、第二段终点、第二段起点的排列顺序,没有问题;
|
|
//else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi))
|
|
// return 1;//如果是第一段终点、第一段起点、交点、第二段起点、第二段终点的排列顺序,也没有问题
|
|
//else if (filletrad<1E-6 && intn == 1)//If the filletrad=0,we can join these wall.
|
|
//{
|
|
// if (ads_distance(pWalla->EndPoint() ,pi)<ads_distance(pWalla->StartPoint() ,pi))
|
|
// pWalla->EndPoint()=pi;
|
|
// else
|
|
// pWalla->StartPoint()=pi;
|
|
// if (ads_distance(pWallb->EndPoint() ,pi)<ads_distance(pWallb->StartPoint(),pi))
|
|
// pWallb->EndPoint()=pi;
|
|
// else
|
|
// pWallb->StartPoint()=pi;
|
|
// return FALSE;
|
|
//}
|
|
//else// 否则,不是按顺序的情况:调整?
|
|
//{
|
|
AfxMessageBox(sMsgPrompt[21]);
|
|
return 0;
|
|
//}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int GetInterPoint(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pi)
|
|
{
|
|
XCurveSegment seg1=*pWalla;
|
|
XCurveSegment seg2=*pWallb;
|
|
// seg1.flag=seg2.flag=LS_INFINITE;
|
|
seg1.SetLineFlag(LS_INFINITE);
|
|
seg2.SetLineFlag(LS_INFINITE);
|
|
XPoint ptInt[2];
|
|
int intn=seg1.Intersection(seg2, ptInt[0], ptInt[1]);
|
|
if (!intn)
|
|
return 0;
|
|
|
|
if (intn == 1)
|
|
pi=ptInt[0];
|
|
else
|
|
pi=XLine(ptInt[0], ptInt[1]).NearPoint(pt1);
|
|
return 1;
|
|
}
|
|
|
|
BOOL FilletSameEntitys(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2)
|
|
{
|
|
AcDbObjectId tempLayerId,rId1,rId2;
|
|
ads_name ent1,ent2;
|
|
tempLayerId = GetLayerIdFromString(_T("0"));
|
|
if (!tempLayerId)
|
|
return FALSE;
|
|
|
|
double nElevA=pWalla->GetElevation();
|
|
double nElevB=pWallb->GetElevation();
|
|
pWalla->SetElevation(0);
|
|
pWallb->SetElevation(0);
|
|
AcDbCurve *pCurve1=pWalla->AsAcDbCurve();
|
|
AcDbCurve *pCurve2=pWallb->AsAcDbCurve();
|
|
pCurve1->setLayer(tempLayerId);
|
|
pCurve2->setLayer(tempLayerId);
|
|
rId1=AddToModelSpace(pCurve1, Adesk::kTrue);
|
|
rId2=AddToModelSpace(pCurve2, Adesk::kTrue);
|
|
if (!rId1 || !rId2)
|
|
{
|
|
pWalla->SetElevation(nElevA);
|
|
pWallb->SetElevation(nElevB);
|
|
return FALSE;
|
|
}
|
|
|
|
VERIFY(acdbGetAdsName(ent1,rId1) == Acad::eOk &&
|
|
acdbGetAdsName(ent2,rId2) == Acad::eOk);
|
|
|
|
XPushVar<int> vOsMode(_T("OSMODE"), 0);
|
|
ads_name lastent,lastent1;
|
|
ads_entlast(lastent);
|
|
VERIFY(pWalla->downgradeOpen() == Acad::eOk);
|
|
VERIFY(pWallb->downgradeOpen() == Acad::eOk);
|
|
ads_command(RTSTR,_T("FILLET"),
|
|
RTLB,RTENAME,ent1,RTPOINT,pt1,RTLE,
|
|
RTLB,RTENAME,ent2,RTPOINT,pt2,RTLE,RTNONE);
|
|
VERIFY(pWalla->upgradeOpen() == Acad::eOk);
|
|
VERIFY(pWallb->upgradeOpen() == Acad::eOk);
|
|
|
|
ads_entlast(lastent1);
|
|
Entity e1=ent1;
|
|
XCurveSegment seg1(e1);
|
|
pWalla->SetPoints(seg1.StartPoint(), seg1.EndPoint());
|
|
pWalla->SetElevation(nElevA);
|
|
ads_entdel(ent1);
|
|
|
|
Entity e2=ent2;
|
|
XCurveSegment seg2(e2);
|
|
pWallb->SetPoints(seg2.StartPoint(), seg2.EndPoint());
|
|
pWallb->SetElevation(nElevB);
|
|
|
|
ads_entdel(ent2);
|
|
if (lastent[0] == lastent1[0] && lastent[1] == lastent1[1])//如果没有产生新的实体
|
|
;
|
|
else
|
|
{
|
|
XArc arc(lastent1);
|
|
ads_entdel(lastent1);
|
|
|
|
//refreshed by whl on 050822;
|
|
TDbWall*pWall=NULL;
|
|
if (pWalla->isKindOf(TDbCurtainWall::desc()))
|
|
pWall = (TDbWall *)TDbCurtainWall::desc()->create();
|
|
else
|
|
pWall = (TDbWall *)TDbWall::desc()->create();
|
|
|
|
pWall->setPropertiesFrom(pWalla);
|
|
XCurveSegment seg;
|
|
seg=arc;
|
|
*(XCurveSegment *)pWall=seg;
|
|
if (pWalla->EndPoint() == pWall->StartPoint() || pWalla->StartPoint() == pWall->EndPoint())
|
|
{//如果是第一段起点、第一段终点、交点、第二段起点、第二段终点的排列顺序或完全相反
|
|
pWall->SetWidth(0, pWalla->GetWidth(0));
|
|
pWall->SetWidth(1, pWalla->GetWidth(1));
|
|
} else if (pWalla->EndPoint() == pWall->EndPoint() || pWalla->StartPoint() == pWall->StartPoint())
|
|
{//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序或完全相反
|
|
pWall->SetWidth(0, pWalla->GetWidth(1));
|
|
pWall->SetWidth(1, pWalla->GetWidth(0));
|
|
}
|
|
if (pWall->isA() == TDbWall::desc())
|
|
{
|
|
pWall->SetStyle(pWalla->GetStyle());
|
|
int nWallFlag = pWalla->GetWallFlag();
|
|
nWallFlag &= ~WF_POLYSHAPE;
|
|
nWallFlag &= ~WF_SECTTERM;
|
|
pWall->SetWallFlag(nWallFlag);
|
|
}
|
|
pWall->SetHeight(pWalla->GetHeight());
|
|
pWall->AddToMSpace(Adesk::kTrue);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//add by xlc
|
|
void ChamferWall()
|
|
{
|
|
TDbWall *pWalla=NULL,*pWallb=NULL;
|
|
ads_real dChamferDistA,dChamferDistB;
|
|
XPoint pt1,pt2;
|
|
if (InputChamferWall(pWalla,pWallb,dChamferDistA,dChamferDistB,pt1,pt2) != TRUE)
|
|
return;//输入错误
|
|
|
|
//del by fxj 090402
|
|
//if (!CanChamfer(pWalla,pWallb,pt1,pt2,dChamferDistA,dChamferDistB))//如果不能倒角
|
|
//{
|
|
// pWalla->close();
|
|
// pWallb->close();
|
|
// return;
|
|
//}
|
|
|
|
//modified by fxj 090522
|
|
if (dChamferDistA<1E-3 || dChamferDistB<1E-3)
|
|
ChamferSameEntitys(pWalla,pWallb,(ads_real *)pt1,(ads_real *)pt2);
|
|
else
|
|
ChamferSameEntitys1(pWalla,pWallb,(ads_real *)pt1,(ads_real *)pt2);
|
|
pWalla->close();
|
|
pWallb->close();
|
|
return;
|
|
}
|
|
|
|
BOOL InputChamferWall(TDbWall *&pWalla,TDbWall *&pWallb,ads_real &chamferDistA,ads_real &chamferDistB,
|
|
XPoint &pt1,XPoint &pt2)
|
|
{
|
|
Entity en1,en2;
|
|
AcDbEntity *pEnt=NULL;
|
|
AcDbObjectId WallObjId1,WallObjId2;
|
|
|
|
//确定倒角参数及第一段墙
|
|
do
|
|
{
|
|
int es;
|
|
VERIFY(xg_getvar(_T("CHAMFERA"),&chamferDistA) == RTNORM);
|
|
VERIFY(xg_getvar(_T("CHAMFERB"),&chamferDistB) == RTNORM);
|
|
adsout << _T("\n选择第一段直墙或 [设距离(D),当前距离 1=")<<Dist2Str(chamferDistA)<<_T(",距离 2=")<<Dist2Str(chamferDistB)<<_T("]<退出>: ");
|
|
INITGET_BEG(0, _T("D"));
|
|
es = en1.FilterSelect(_T(""), RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL),pt1);
|
|
INITGET_END();
|
|
|
|
if (es == RTKWORD)
|
|
{
|
|
es = XGetDist(NULL,_T("\n指定第一个倒角距离"),chamferDistA,RSG_NONEG);
|
|
if (es == RTNORM ||es == RTNONE)
|
|
{
|
|
xg_setvar(_T("CHAMFERA"),chamferDistA);
|
|
es = XGetDist(NULL,_T("\n指定第二个倒角距离"),chamferDistB,RSG_NONEG);
|
|
if (es == RTNORM)
|
|
{
|
|
xg_setvar(_T("CHAMFERB"),chamferDistB);
|
|
}
|
|
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (es != RTNORM)
|
|
return FALSE;
|
|
|
|
acdbGetObjectId(WallObjId1,en1);
|
|
acdbOpenAcDbEntity(pEnt,WallObjId1,AcDb::kForWrite);
|
|
if (pEnt == NULL)
|
|
return FALSE;
|
|
|
|
pWalla = (TDbWall *)pEnt;
|
|
BOOL bIsArc = pWalla->Is(CURVE_ARC);
|
|
if (bIsArc)
|
|
{
|
|
adsout << _T("\n倒角需要直墙,不能用弧墙!");
|
|
pWalla->close();
|
|
continue;
|
|
|
|
}
|
|
break;
|
|
}while(1);
|
|
|
|
pWalla->highlight();
|
|
//确定第二段墙
|
|
do
|
|
{
|
|
VERIFY(pWalla->downgradeOpen() == Acad::eOk);
|
|
int es = en2.FilterSelect(_T("\n选择另一段直墙<退出>:"),RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL),pt2);
|
|
VERIFY(pWalla->upgradeOpen() == Acad::eOk);
|
|
if (es != RTNORM)
|
|
{
|
|
pWalla->unhighlight();
|
|
pWalla->close();
|
|
return FALSE;
|
|
}
|
|
|
|
if (en1 == en2)
|
|
{
|
|
adsout << _T("\n请选择不同的两段墙!");
|
|
continue;
|
|
}
|
|
acdbGetObjectId(WallObjId2,en2);
|
|
pEnt=NULL;
|
|
acdbOpenAcDbEntity(pEnt,WallObjId2,AcDb::kForWrite);
|
|
pWalla->unhighlight();
|
|
if (pEnt == NULL)
|
|
return FALSE;
|
|
|
|
pWallb = (TDbWall *)pEnt;
|
|
BOOL bIsArc = pWallb->Is(CURVE_ARC);
|
|
if (bIsArc)
|
|
{
|
|
adsout << _T("\n倒角需要直墙,不能用弧墙!");
|
|
pWallb->close();
|
|
continue;
|
|
|
|
}
|
|
break;
|
|
}while(1);
|
|
|
|
//保证 Undo 成功
|
|
pWalla->assertWriteEnabled();
|
|
pWallb->assertWriteEnabled();
|
|
return TRUE;
|
|
}
|
|
|
|
//如果墙体偏心,有时可以调节能得到正确的结果
|
|
int CanChamfer(TDbWall *&pWalla,TDbWall *&pWallb,XPoint &pt1,XPoint &pt2,ads_real &chamferDistA,
|
|
ads_real &chamferDistB)
|
|
{
|
|
if (chamferDistA < 1.0E-3)
|
|
return TRUE;
|
|
if (chamferDistB < 1.0E-3)
|
|
return TRUE;
|
|
|
|
if (pWalla->GetStyle() != pWallb->GetStyle())
|
|
{
|
|
ads_printf(sMsgPrompt[19]);
|
|
return 0;
|
|
}
|
|
if (fabs(pWalla->GetWidth()-pWallb->GetWidth())>1.0E-3)
|
|
{
|
|
ads_printf(sMsgPrompt[20]);
|
|
return 0;
|
|
}
|
|
if (fabs(pWalla->GetWidth(0)-pWalla->GetWidth (1))<1.0E-3 &&
|
|
fabs(pWallb->GetWidth(0)-pWallb->GetWidth (1))<1.0E-3)//如果不偏心
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
//如果是偏心墙,考虑两段墙壁的偏心情况
|
|
XPoint pi;
|
|
int intn,ret1,ret2;
|
|
if ((intn=GetInterPoint(pWalla,pWallb,pt1,pi)) == 0) //不相交(平行)也可以倒角,但是必须是倒角半径和相差的距离相同
|
|
{
|
|
ads_printf(sMsgPrompt[23]);
|
|
return 0;
|
|
}
|
|
|
|
XCurveSegment seg1=*pWalla;
|
|
XCurveSegment seg2=*pWallb;
|
|
ret1=pi&seg1;
|
|
ret2=pi&seg2;
|
|
if (ret1 == 3 || ret2 == 3)//如果交点在墙壁内部
|
|
{
|
|
ads_real temp;
|
|
BOOL flag1=FALSE,flag2=FALSE,flaga=FALSE,flagb=FALSE;
|
|
if (ads_distance(pWalla->StartPoint() ,pt1)<ads_distance(pWalla->StartPoint() ,pi))
|
|
flag1=TRUE;//拾取点在起始点和交点之间;
|
|
if (ads_distance(pWallb->StartPoint() ,pt2)<ads_distance(pWallb->StartPoint() ,pi))
|
|
flag2=TRUE;//拾取点在起始点和交点之间;
|
|
if (pWalla->GetWidth(0)<pWalla->GetWidth(1))
|
|
flaga=TRUE;//左小于右
|
|
if (pWallb->GetWidth(0)<pWallb->GetWidth(1))
|
|
flagb=TRUE;//左小于右
|
|
if (flag1 && flag2 && flaga && flagb || flag1 && flag2 && !flaga && !flagb ||
|
|
flag1 && !flag2 && flaga && !flagb || flag1 && !flag2 && !flaga && flagb ||
|
|
!flag1 && flag2 && flaga && !flagb || !flag1 && flag2 && !flaga && flagb ||
|
|
!flag1 && !flag2 && flaga && flagb || !flag1 && !flag2 && !flaga && !flagb)
|
|
{
|
|
if (chamferDistA>1E-3)
|
|
{
|
|
if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[24],sMsgPrompt[25],MB_YESNO) != IDYES)
|
|
return 0;
|
|
temp=pWallb->GetWidth(0);
|
|
pWallb->SetWidth(0,pWallb->GetWidth(1));
|
|
pWallb->SetWidth(1,temp);
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
else if (flag1 && flag2 && flaga && !flagb || flag1 && flag2 && !flaga && flagb ||
|
|
flag1 && !flag2 && flaga && flagb || flag1 && !flag2 && !flaga && !flagb ||
|
|
!flag1 && flag2 && flaga && flagb || !flag1 && flag2 && !flaga && !flagb ||
|
|
!flag1 && !flag2 && !flaga && flagb || !flag1 && !flag2 && flaga && !flagb)
|
|
{
|
|
return 1;
|
|
}
|
|
ads_printf(sMsgPrompt[26]);
|
|
return 0;
|
|
}
|
|
|
|
//以下是交点在墙壁外面
|
|
if (fabs(pWalla->GetWidth (0)-pWallb->GetWidth (0))<1.0E-3 && fabs(pWalla->GetWidth (1)-pWallb->GetWidth (1))<1.0E-3)
|
|
{
|
|
//如果两段墙壁的左右偏心相同:必须进一步考虑交点是否在墙内.
|
|
if (ads_distance(pWalla->EndPoint() ,pi)<ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)<ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段起点、第一段终点、交点、第二段起点、第二段终点的排列顺序,没有问题
|
|
else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序,也没有问题
|
|
else// 否则,不是按顺序的情况:调整?
|
|
{
|
|
if (MessageBox(acedGetAcadFrame()->m_hWnd,sMsgPrompt[24],sMsgPrompt[25],MB_YESNO) != IDYES)
|
|
return 0;
|
|
if (ads_distance(pWalla->StartPoint() ,pi)>ads_distance(pWalla->EndPoint() ,pi))
|
|
{//如果是第一段起点、第一段终点、交点的顺序,把第二段墙换以下顺序;
|
|
XPoint pt=pWallb->StartPoint() ;
|
|
pWallb->StartPoint() =pWallb->EndPoint() ;
|
|
pWallb->EndPoint() =pt;
|
|
}
|
|
else//如果是第一段终点、第一段起点、交点的顺序,把第二段墙换以下顺序;
|
|
{
|
|
XPoint pt=pWallb->EndPoint() ;
|
|
pWallb->EndPoint() =pWallb->StartPoint();
|
|
pWallb->StartPoint() =pt;
|
|
}
|
|
return 2;
|
|
}
|
|
}
|
|
else if (fabs(pWalla->GetWidth (0)-pWallb->GetWidth (1))<1.0E-3 && fabs(pWalla->GetWidth (1)-pWallb->GetWidth (0))<1.0E-3)
|
|
{//如果两段墙壁的左右偏心相刚好相反:必须进一步考虑交点是否在墙内.
|
|
if (ads_distance(pWalla->EndPoint() ,pi)<ads_distance(pWalla->StartPoint() ,pi)
|
|
&& ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段起点、第一段终点、交点、第二段终点、第二段起点的排列顺序,没有问题
|
|
else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi)
|
|
&& ads_distance(pWallb->StartPoint() ,pi)<ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段终点、第一段起点、交点、第二段起点、第二段终点的排列顺序,也没有问题
|
|
else// 否则,不是按顺序的情况:调整?
|
|
{
|
|
AfxMessageBox(sMsgPrompt[21]);
|
|
return 0;
|
|
}
|
|
}
|
|
else //否则:如果两段墙壁的左右偏心不相同
|
|
{
|
|
if (ads_distance(pWalla->EndPoint() ,pi)<ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->EndPoint() ,pi)<ads_distance(pWallb->StartPoint(),pi))
|
|
return 1;//如果是第一段起点、第一段终点、交点、第二段终点、第二段起点的排列顺序,没有问题;
|
|
else if (ads_distance(pWalla->EndPoint() ,pi)>ads_distance(pWalla->StartPoint() ,pi) && ads_distance(pWallb->StartPoint() ,pi)>ads_distance(pWallb->EndPoint() ,pi))
|
|
return 1;//如果是第一段终点、第一段起点、交点、第二段起点、第二段终点的排列顺序,也没有问题
|
|
else if (chamferDistA<1E-6 && intn == 1)//If the filletrad=0,we can join these wall.
|
|
{
|
|
if (ads_distance(pWalla->EndPoint() ,pi)<ads_distance(pWalla->StartPoint() ,pi))
|
|
pWalla->EndPoint()=pi;
|
|
else
|
|
pWalla->StartPoint()=pi;
|
|
if (ads_distance(pWallb->EndPoint() ,pi)<ads_distance(pWallb->StartPoint(),pi))
|
|
pWallb->EndPoint()=pi;
|
|
else
|
|
pWallb->StartPoint()=pi;
|
|
return FALSE;
|
|
}
|
|
else// 否则,不是按顺序的情况:调整?
|
|
{
|
|
AfxMessageBox(sMsgPrompt[21]);
|
|
return 0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//add by fxj 090507 倒角距离以墙中线为准
|
|
BOOL ChamferSameEntitys1(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2)
|
|
{
|
|
|
|
AcDbObjectId tempLayerId,rId1,rId2;
|
|
ads_name ent1,ent2;
|
|
tempLayerId = GetLayerIdFromString(_T("0"));
|
|
if (!tempLayerId)
|
|
return FALSE;
|
|
|
|
double nElevA=pWalla->GetElevation();
|
|
double nElevB=pWallb->GetElevation();
|
|
pWalla->SetElevation(0);
|
|
pWallb->SetElevation(0);
|
|
|
|
double nBaseDist1=(pWalla->GetWidth(0)-pWalla->GetWidth(1))/2.0;//第一段墙的临时虚拟基线比原基线靠左nBaseDist的距离(可正可负)
|
|
XCurveSegment segBase1=pWalla->XCurveSegment::Offset(OFFSET_LEFT,nBaseDist1, LS_FINITE);
|
|
double nBaseDist2=(pWallb->GetWidth(0)-pWallb->GetWidth(1))/2.0;
|
|
XCurveSegment segBase2=pWallb->XCurveSegment::Offset(OFFSET_LEFT,nBaseDist2, LS_FINITE);//第二段墙的临时虚拟基线比原基线靠左nBaseDist的距离(可正可负)
|
|
AcDbCurve *pCurve1=segBase1.AsAcDbCurve();
|
|
AcDbCurve *pCurve2=segBase2.AsAcDbCurve();
|
|
|
|
pCurve1->setLayer(tempLayerId);
|
|
pCurve2->setLayer(tempLayerId);
|
|
rId1=AddToModelSpace(pCurve1, Adesk::kTrue);
|
|
rId2=AddToModelSpace(pCurve2, Adesk::kTrue);
|
|
if (!rId1 || !rId2)
|
|
{
|
|
pWalla->SetElevation(nElevA);
|
|
pWallb->SetElevation(nElevB);
|
|
return FALSE;
|
|
}
|
|
|
|
VERIFY(acdbGetAdsName(ent1,rId1) == Acad::eOk &&
|
|
acdbGetAdsName(ent2,rId2) == Acad::eOk);
|
|
|
|
XPushVar<int> vOsMode(_T("OSMODE"), 0);
|
|
ads_name lastent,lastent1;
|
|
ads_entlast(lastent);
|
|
|
|
ads_command(RTSTR,_T("CHAMFER"),
|
|
RTLB,RTENAME,ent1,RTPOINT,pt1,RTLE,
|
|
RTLB,RTENAME,ent2,RTPOINT,pt2,RTLE,RTNONE);
|
|
|
|
ads_entlast(lastent1);
|
|
Entity e1=ent1;
|
|
XCurveSegment seg1(e1);
|
|
ads_entdel(ent1);
|
|
|
|
Entity e2=ent2;
|
|
XCurveSegment seg2(e2);
|
|
ads_entdel(ent2);
|
|
|
|
XPoint ptTempS=seg1.StartPoint();
|
|
XPoint ptTempE=seg1.EndPoint();
|
|
|
|
|
|
if (lastent[0] == lastent1[0] && lastent[1] == lastent1[1])//如果没有产生新的实体
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
//modified by fxj 090522 解决两段墙不相接时倒角不正确问题。再次调用了AutoCAD的chamfer命令
|
|
|
|
XCurveSegment seg(lastent1);
|
|
ads_entdel(lastent1);
|
|
|
|
if (ptTempS == seg.StartPoint() || ptTempE == seg.EndPoint())
|
|
seg.Reverse();
|
|
XPoint pta,ptb;
|
|
seg=seg.Offset(OFFSET_RIGHT,nBaseDist1, LS_INFINITE);//向右偏移nBaseDist1的距离, 得到新生成墙的新基线
|
|
XPoint ptStart1,ptEnd1,ptStart2,ptEnd2;
|
|
pWalla->GetBaseCurve()->getStartPoint(ptStart1);
|
|
pWalla->GetBaseCurve()->getEndPoint(ptEnd1);
|
|
pWallb->GetBaseCurve()->getStartPoint(ptStart2);
|
|
pWallb->GetBaseCurve()->getEndPoint(ptEnd2);
|
|
XLine line1(ptStart1,ptEnd1,LS_INFINITE);
|
|
XLine line2(ptStart2,ptEnd2,LS_INFINITE);
|
|
XLine line=seg.GetLine();
|
|
int nIntNumA=line.Intersection(&line1,pta);
|
|
int nIntNumB=line.Intersection(&line2,ptb);
|
|
if (nIntNumA<1||nIntNumB<1)
|
|
{
|
|
//seg1=seg1.Offset(OFFSET_RIGHT,nBaseDist1, LS_FINITE);
|
|
//seg2=seg2.Offset(OFFSET_RIGHT,nBaseDist2, LS_FINITE);
|
|
//pWalla->SetPoints(seg1.StartPoint(), seg1.EndPoint());
|
|
pWalla->SetElevation(nElevA);
|
|
//pWallb->SetPoints(seg2.StartPoint(), seg2.EndPoint());
|
|
pWallb->SetElevation(nElevB);
|
|
return TRUE;
|
|
}
|
|
|
|
if (pta.Distance2d(ptb)<100)
|
|
return FALSE;
|
|
|
|
|
|
//------------------------------用新的距离对基线倒角
|
|
XPoint ptNode;
|
|
line1.Intersection(&line2,ptNode);
|
|
double chamferDistA1=pta.Distance2d(ptNode);
|
|
double chamferDistB1=ptb.Distance2d(ptNode);
|
|
double chamferDistA=0;
|
|
double chamferDistB=0;
|
|
xg_getvar(_T("CHAMFERA"),&chamferDistA);//最初用户输入的距离。(得到系统变量的旧值)
|
|
xg_getvar(_T("CHAMFERB"),&chamferDistB);
|
|
xg_setvar(_T("CHAMFERA"),chamferDistA1);//以基线为考虑对象的倒角距离
|
|
xg_setvar(_T("CHAMFERB"),chamferDistB1);
|
|
AcDbObjectId rIda,rIdb;
|
|
ads_name enta,entb;
|
|
if (!tempLayerId)
|
|
return FALSE;
|
|
|
|
AcDbCurve *pCurvea=pWalla->AsAcDbCurve();
|
|
AcDbCurve *pCurveb=pWallb->AsAcDbCurve();
|
|
pCurvea->setLayer(tempLayerId);
|
|
pCurveb->setLayer(tempLayerId);
|
|
rIda=AddToModelSpace(pCurvea, Adesk::kTrue);
|
|
rIdb=AddToModelSpace(pCurveb, Adesk::kTrue);
|
|
if (!rIda || !rIdb)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
VERIFY(acdbGetAdsName(enta,rIda) == Acad::eOk &&
|
|
acdbGetAdsName(entb,rIdb) == Acad::eOk);
|
|
|
|
XPushVar<int> vOsMode(_T("OSMODE"), 0);
|
|
ads_name lastent,lastent1;
|
|
ads_entlast(lastent);
|
|
|
|
VERIFY(pWalla->downgradeOpen() == Acad::eOk);
|
|
VERIFY(pWallb->downgradeOpen() == Acad::eOk);
|
|
ads_command(RTSTR,_T("CHAMFER"),
|
|
RTLB,RTENAME,enta,RTPOINT,pt1,RTLE,
|
|
RTLB,RTENAME,entb,RTPOINT,pt2,RTLE,RTNONE);//modified 090804
|
|
VERIFY(pWalla->upgradeOpen() == Acad::eOk);
|
|
VERIFY(pWallb->upgradeOpen() == Acad::eOk);
|
|
|
|
xg_setvar(_T("CHAMFERA"),chamferDistA);//最初用户输入的距离再次保存到系统变量
|
|
xg_setvar(_T("CHAMFERB"),chamferDistB);
|
|
ads_entlast(lastent1);
|
|
Entity ent1=enta;
|
|
XCurveSegment s1(ent1);
|
|
pWalla->SetPoints(s1.StartPoint(), s1.EndPoint());
|
|
pWalla->SetElevation(nElevA);
|
|
ads_entdel(enta);
|
|
|
|
Entity ent2=entb;
|
|
XCurveSegment s2(ent2);
|
|
pWallb->SetPoints(s2.StartPoint(), s2.EndPoint());
|
|
pWallb->SetElevation(nElevB);
|
|
ads_entdel(entb);
|
|
|
|
XCurveSegment segNew(lastent1);
|
|
ads_entdel(lastent1);
|
|
TDbWall*pWall=NULL;
|
|
if (pWalla->isKindOf(TDbCurtainWall::desc()))
|
|
pWall = (TDbWall *)TDbCurtainWall::desc()->create();
|
|
else
|
|
pWall = (TDbWall *)TDbWall::desc()->create();
|
|
pWall->setPropertiesFrom(pWalla);
|
|
*(XCurveSegment *)pWall=segNew;
|
|
//---------------------------
|
|
|
|
|
|
//if (pWalla->StartPoint() == pWallb->StartPoint())
|
|
//{
|
|
// pWalla->StartPoint()=pta;
|
|
// pWallb->StartPoint()=ptb;
|
|
//}
|
|
//else if (pWalla->StartPoint() == pWallb->EndPoint())
|
|
//{
|
|
// pWalla->StartPoint()=pta;
|
|
// pWallb->EndPoint()=ptb;
|
|
//}
|
|
//else if (pWalla->EndPoint() == pWallb->StartPoint())
|
|
//{
|
|
// pWalla->EndPoint()=pta;
|
|
// pWallb->StartPoint()=ptb;
|
|
//}
|
|
//else
|
|
//{
|
|
// pWalla->EndPoint()=pta;
|
|
// pWallb->EndPoint()=ptb;
|
|
//}
|
|
|
|
if (pWalla->EndPoint() == pWall->EndPoint() || pWalla->StartPoint() == pWall->StartPoint())
|
|
{//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序或完全相反 新墙首尾反转
|
|
XPoint ptTempt=pWall->StartPoint();
|
|
pWall->StartPoint()=pWall->EndPoint();
|
|
pWall->EndPoint()=ptTempt;
|
|
}
|
|
pWall->SetWidth(0, pWalla->GetWidth(0));
|
|
pWall->SetWidth(1, pWalla->GetWidth(1));
|
|
|
|
if (pWall->isA() == TDbWall::desc())
|
|
{
|
|
pWall->SetStyle(pWalla->GetStyle());
|
|
int nWallFlag = pWalla->GetWallFlag();
|
|
nWallFlag &= ~WF_POLYSHAPE;
|
|
nWallFlag &= ~WF_SECTTERM;
|
|
pWall->SetWallFlag(nWallFlag);
|
|
}
|
|
pWall->SetHeight(pWalla->GetHeight());
|
|
pWall->AddToMSpace(Adesk::kTrue);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// modified by fxj 090522 倒角距离以墙基线为准
|
|
BOOL ChamferSameEntitys(TDbWall *&pWalla,TDbWall *&pWallb,ads_point pt1,ads_point pt2)
|
|
{
|
|
AcDbObjectId tempLayerId,rId1,rId2;
|
|
ads_name ent1,ent2;
|
|
tempLayerId = GetLayerIdFromString(_T("0"));
|
|
if (!tempLayerId)
|
|
return FALSE;
|
|
|
|
double nElevA=pWalla->GetElevation();
|
|
double nElevB=pWallb->GetElevation();
|
|
pWalla->SetElevation(0);
|
|
pWallb->SetElevation(0);
|
|
AcDbCurve *pCurve1=pWalla->AsAcDbCurve();
|
|
AcDbCurve *pCurve2=pWallb->AsAcDbCurve();
|
|
pCurve1->setLayer(tempLayerId);
|
|
pCurve2->setLayer(tempLayerId);
|
|
rId1=AddToModelSpace(pCurve1, Adesk::kTrue);
|
|
rId2=AddToModelSpace(pCurve2, Adesk::kTrue);
|
|
if (!rId1 || !rId2)
|
|
{
|
|
pWalla->SetElevation(nElevA);
|
|
pWallb->SetElevation(nElevB);
|
|
return FALSE;
|
|
}
|
|
|
|
VERIFY(acdbGetAdsName(ent1,rId1) == Acad::eOk &&
|
|
acdbGetAdsName(ent2,rId2) == Acad::eOk);
|
|
|
|
XPushVar<int> vOsMode(_T("OSMODE"), 0);
|
|
ads_name lastent,lastent1;
|
|
ads_entlast(lastent);
|
|
VERIFY(pWalla->downgradeOpen() == Acad::eOk);
|
|
VERIFY(pWallb->downgradeOpen() == Acad::eOk);
|
|
ads_command(RTSTR,_T("CHAMFER"),
|
|
RTLB,RTENAME,ent1,RTPOINT,pt1,RTLE,
|
|
RTLB,RTENAME,ent2,RTPOINT,pt2,RTLE,RTNONE);
|
|
VERIFY(pWalla->upgradeOpen() == Acad::eOk);
|
|
VERIFY(pWallb->upgradeOpen() == Acad::eOk);
|
|
|
|
ads_entlast(lastent1);
|
|
Entity e1=ent1;
|
|
XCurveSegment seg1(e1);
|
|
pWalla->SetPoints(seg1.StartPoint(), seg1.EndPoint());
|
|
pWalla->SetElevation(nElevA);
|
|
ads_entdel(ent1);
|
|
|
|
Entity e2=ent2;
|
|
XCurveSegment seg2(e2);
|
|
pWallb->SetPoints(seg2.StartPoint(), seg2.EndPoint());
|
|
pWallb->SetElevation(nElevB);
|
|
ads_entdel(ent2);
|
|
if (lastent[0] == lastent1[0] && lastent[1] == lastent1[1])//如果没有产生新的实体
|
|
;
|
|
else
|
|
{
|
|
XLine line(lastent1);
|
|
ads_entdel(lastent1);
|
|
|
|
TDbWall*pWall=NULL;
|
|
if (pWalla->isKindOf(TDbCurtainWall::desc()))
|
|
pWall = (TDbWall *)TDbCurtainWall::desc()->create();
|
|
else
|
|
pWall = (TDbWall *)TDbWall::desc()->create();
|
|
|
|
pWall->setPropertiesFrom(pWalla);
|
|
XCurveSegment seg;
|
|
seg=line;
|
|
*(XCurveSegment *)pWall=seg;
|
|
|
|
if (pWalla->EndPoint() == pWall->EndPoint() || pWalla->StartPoint() == pWall->StartPoint())
|
|
{//如果是第一段终点、第一段起点、交点、第二段终点、第二段起点的排列顺序或完全相反 新墙首尾反转
|
|
XPoint ptTempt=pWall->StartPoint();
|
|
pWall->StartPoint()=pWall->EndPoint();
|
|
pWall->EndPoint()=ptTempt;
|
|
}
|
|
pWall->SetWidth(0, pWalla->GetWidth(0));//add by fxj 090401
|
|
pWall->SetWidth(1, pWalla->GetWidth(1));
|
|
//------------------------------------------
|
|
if (pWall->isA() == TDbWall::desc())
|
|
{
|
|
pWall->SetStyle(pWalla->GetStyle());
|
|
int nWallFlag = pWalla->GetWallFlag();
|
|
nWallFlag &= ~WF_POLYSHAPE;
|
|
nWallFlag &= ~WF_SECTTERM;
|
|
pWall->SetWallFlag(nWallFlag);
|
|
}
|
|
pWall->SetHeight(pWalla->GetHeight());
|
|
pWall->AddToMSpace(Adesk::kTrue);
|
|
}
|
|
|
|
return TRUE;
|
|
} |