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

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;
}