Files
envi-code/SourceCode/Code2026/CoreLibrary/AecWall2DJoin.cpp
T
2026-09-28 15:28:50 +08:00

3394 lines
75 KiB
C++

#include "stdafx.h"
#include "StdArx.h"
#include "AecWall2DJoin.h"
#include "AecCoverBooleanOper.h"
#include "AcDbX3dSolid.h"
#include "AecDbX3dPart.h"
#include "KTCADUtilityEx.h"
const double g_xjoinR = 400.0;
const double g_xjoinCol = 10.0;
static const Adesk::UInt16 kRed = 1;
static const Adesk::UInt16 kYellow = 2;
static const Adesk::UInt16 kGreen = 3;
extern AcGePoint3d GetArcMidPoint(AcDbArc* pArc);
extern AcDbArc* FormatArc(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2,const AcGePoint3d& ptGe3);
extern AcGePoint3d MidPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2);
extern Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt,AcDbDatabase* pDb = NULL,bool bClose = true);
extern void RefreshWallOnOpeningDrawEx(const AcDbObjectId& idWall);
extern void transfromRegion(AcDbRegion *pRegion, const AcGePoint3d &ptOnRegion, const AcGeVector3d &vtNormal, const AcGePoint3d &ptOnPlan);
//weight = 20 - index
const LPCTSTR g_pszWallMaterials[] = { _T("钢筋混凝土"), _T("石材"), _T("砖墙"), _T("填充墙"), _T("玻璃幕墙"),_T("轻质隔墙"),NULL};
AecWall2DJoin::AecWall2DJoin(void)
{
}
AecWall2DJoin::~AecWall2DJoin(void)
{
ClearBuffer();
}
bool AecWall2DJoin::DoStruDraw(bool b3dUnit)
{
int nBoolUnit = b3dUnit ? TRUE : FALSE;
AcDbDatabase* pDb = acdbCurDwg();
if (pDb == NULL)
return false;
//记录有门窗的墙体
AcDbObjectIdArray arWallIds;
Acad::ErrorStatus es;
AcDbBlockTable* pTbl = NULL;
if ( Acad::eOk == (es = pDb->getBlockTable(pTbl,AcDb::kForRead)))
{
AcDbBlockTableRecord* pRec = NULL;
if ( Acad::eOk == (es = pTbl->getAt(ACDB_MODEL_SPACE,pRec,AcDb::kForRead)))
{
AcDbBlockTableRecordIterator* pIt = NULL;
pRec->newIterator(pIt);
if (pIt != NULL)
{
AcDbEntity* pEnt = NULL;
for (pIt->start();!pIt->done();pIt->step())
{
if ( Acad::eOk == (es = pIt->getEntity(pEnt,AcDb::kForWrite) ) )
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
if (!b3dUnit)
{
pWall->RemoveAddtionShow3dPart(0);
pWall->RemoveAddtionShow3dPart(1);
}
//设置三维融合标志
pWall->GetSpecialtyData()->SetAt(KEY_3DSHOW,nBoolUnit);
pWall->ReCreateDraw3d();
if (!b3dUnit)
{
pWall->ClearForDraw2dables();
AecComplexCurve draw2d;
pWall->GetStandardDraw2d(draw2d);
pWall->SetDraw2dables(draw2d);
if (pWall->GetAssocPartCount() > 0)
{
arWallIds.append(pWall->objectId());
}
pWall->ReCreateDraw3d();
}
/*if (nRlt == 0)//不保留
{
pWall->ClearForDraw2dables();
AecComplexCurve draw2d;
pWall->GetStandardDraw2d(draw2d);
pWall->SetDraw2dables(draw2d);
if (pWall->GetAssocPartCount() > 0)
{
arWallIds.append(pWall->objectId());
}
pWall->ReCreateDraw3d();
}
else//三维融合
{
pWall->ReCreateDraw3d();
}*/
}
pEnt->close();
}
}
delete pIt;
}
pRec->close();
}
pTbl->close();
}
//墙上门窗的裁剪
AcDbObjectId idWall;
for (int i = 0;i < arWallIds.length();i++)
{
idWall = arWallIds.at(i);
RefreshWallOnOpeningDrawEx(idWall);
}
return true;
}
bool AecWall2DJoin::DoStruDraw(AcDbObjectIdArray& arIds,bool b3dUnit)
{
int nBoolUnit = b3dUnit ? TRUE : FALSE;
//记录有门窗的墙体
AcDbObjectIdArray arWallIds;
AcDbEntity* pEnt = NULL;
for (int i = 0;i < arIds.length();i++)
{
if ( Acad::eOk == (acdbOpenAcDbEntity(pEnt,arIds.at(i),AcDb::kForWrite) ) )
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
if (!b3dUnit)
{
pWall->RemoveAddtionShow3dPart(0);
pWall->RemoveAddtionShow3dPart(1);
}
//设置三维融合标志
pWall->GetSpecialtyData()->SetAt(KEY_3DSHOW,nBoolUnit);
pWall->ReCreateDraw3d();
if (!b3dUnit)
{
pWall->ClearForDraw2dables();
if (pWall->GetAssocPartCount() > 0)
{
arWallIds.append(arIds.at(i));
}
pWall->ReCreateDraw3d();
}
/*if (nRlt == 0)//不保留
{
pWall->ClearForDraw2dables();
AecComplexCurve draw2d;
pWall->GetStandardDraw2d(draw2d);
pWall->SetDraw2dables(draw2d);
if (pWall->GetAssocPartCount() > 0)
{
arWallIds.append(pWall->objectId());
}
pWall->ReCreateDraw3d();
}
else//三维融合
{
pWall->ReCreateDraw3d();
}*/
}
pEnt->close();
}
}
//墙上门窗的裁剪
AcDbObjectId idWall;
for (int i = 0;i < arWallIds.length();i++)
{
idWall = arWallIds.at(i);
RefreshWallOnOpeningDrawEx(idWall);
}
return true;
}
bool AecWall2DJoin::DoWall2DDraw(AcDbObjectIdArray& arIds)
{
BuildXTJoins(arIds);
DoWall2DJoin();
return true;
}
void AecWall2DJoin::ClearBuffer()
{
m_arXJoins.removeAll();
m_arTJoins.removeAll();
m_arIntJoins.removeAll();
m_arIDsWallHasOpening.removeAll();
m_arWallExtends.removeAll();
for (int i = 0;i < m_arCmplPtrs.length();i++)
{
AecComplexCurve* pCmpl = m_arCmplPtrs.at(i);
if (pCmpl != NULL) delete pCmpl;
}
m_arCmplPtrs.removeAll();
CString sKey;
AcDbCurve* pValue = NULL;
for (POSITION ps = m_mapIdToPtr.GetStartPosition();ps != NULL;)
{
pValue = NULL;
m_mapIdToPtr.GetNextAssoc(ps,sKey,(void*&)pValue);
if (pValue != NULL)
delete pValue;
}
m_mapIdToPtr.RemoveAll();
}
bool AecWall2DJoin::ColumnAssocWall(ColEnd& ce,WallEnd& weT)
{
bool bAssoc = false;
if (ce.pColCmpl != NULL && weT.pWallCmpl != NULL)
{
AcDbCurve* pCurve1 = NULL;
AcDbCurve* pCurve2 = NULL;
AcGePoint3dArray arPts;
for (int i = 0;i < ce.pColCmpl->length();i++)
{
pCurve1 = ce.pColCmpl->segat(i);
for (int j = 0;j < weT.pWallCmpl->length();j++)
{
pCurve2 = weT.pWallCmpl->segat(j);
pCurve1->intersectWith(pCurve2,AcDb::kOnBothOperands,AcGePlane::kXYPlane,arPts);
if ( !arPts.isEmpty() )
{
bAssoc = true;
break;
}
delete pCurve2;
}
if (bAssoc)
{
delete pCurve1;
break;
}
delete pCurve1;
}
}
return bAssoc;
}
bool AecWall2DJoin::ColumnAssocWall(ColEnd& ce,WallLn& weT)
{
bool bAssoc = false;
if (ce.pColCmpl != NULL && weT.pWallCmpl != NULL)
{
AcDbCurve* pCurve1 = NULL;
AcDbCurve* pCurve2 = NULL;
AcGePoint3dArray arPts;
for (int i = 0;i < ce.pColCmpl->length();i++)
{
pCurve1 = ce.pColCmpl->segat(i);
for (int j = 0;j < weT.pWallCmpl->length();j++)
{
pCurve2 = weT.pWallCmpl->segat(j);
pCurve1->intersectWith(pCurve2,AcDb::kOnBothOperands,AcGePlane::kXYPlane,arPts);
if ( !arPts.isEmpty() )
{
bAssoc = true;
break;
}
delete pCurve2;
}
if (bAssoc)
{
delete pCurve1;
break;
}
delete pCurve1;
}
}
return bAssoc;
}
bool AecWall2DJoin::ColumnAssocWall(ColEnd& ce,AcGePoint3d& ptPos)
{
bool bAssoc = false;
if ( ce.pColCmpl != NULL)
{
AcDbCurve* pCurve1 = NULL;
AcDbRay ray;
ray.setBasePoint(ptPos);
ray.setUnitDir(AcGeVector3d::kXAxis);
AcGePoint3dArray arPts;
for (int i = 0;i < ce.pColCmpl->length();i++)
{
pCurve1 = ce.pColCmpl->segat(i);
ray.intersectWith(pCurve1,AcDb::kOnBothOperands,AcGePlane::kXYPlane,arPts);
if (!arPts.isEmpty())
{
bAssoc = true;
}
delete pCurve1;
}
}
return bAssoc;
}
bool AecWall2DJoin::BuildXTJoins(AcDbObjectIdArray& arIds)
{
ClearBuffer();
WallData wdata;
AcGePoint3d ptSta,ptEnd,ptInt;
WallEnd wallEnd;
wallEnd.dParamOnM = 0.0;
wallEnd.pWallCmpl = NULL;
WallLn wallLn;
wallLn.nType = 0;
AcArray<WallLn> arWallLns;
WallIntJoin wallInt;
ColEnd colEnd;
colEnd.pColCmpl = NULL;
AcArray<ColEnd> arColEnds;
AcArray<WallEnd> arWallEnds;
//用于标识id1,id2的标识值
CPoint pt;
AcArray<CPoint> arIdIds;
Adesk::IntDbId nStartRef = 0;//参考最小的ID = BlockTable id
AcDbEntity* pEnt = NULL;
for (int i = 0;i < arIds.length();i++)
{
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,arIds.at(i),AcDb::kForRead))
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
pWall->upgradeOpen();
pWall->GetStandardDraw2d();
pWall->downgradeOpen();
ptSta = GetWallStartPoint(pWall);
ptEnd = GetWallEndPoint(pWall);
pWall->GetWallData(wdata);
if (ptSta.distanceTo(ptEnd) < 100.0)
{
pEnt->close();
continue;
}
wallEnd.pWallCmpl = new AecComplexCurve;
m_arCmplPtrs.append(wallEnd.pWallCmpl);
pWall->GetDraw2dables(*wallEnd.pWallCmpl);
wallEnd.id = pEnt->objectId();
wallEnd.ptEnd = ptSta;
wallEnd.dThick = wdata.dThick;
wallEnd.vtEnd = GetWallFirstDeriv(pWall,ptSta);
wallEnd.vtEnd.negate();//向外
wallEnd.nWallWeight = MaterialWeight(wdata.szMat);
AppendWallEnd(wallEnd,0);
arWallEnds.append(wallEnd);
wallEnd.ptEnd = ptEnd;
wallEnd.vtEnd = GetWallFirstDeriv(pWall,ptEnd);
AppendWallEnd(wallEnd,1);
arWallEnds.append(wallEnd);
wallLn.nType = 0;
wallLn.ptGe[0] = ptSta;
wallLn.ptGe[1] = ptEnd;
wallLn.ptGe[2] = ptEnd;
wallLn.dThick= wdata.dThick;
wallLn.nWallWeight = wallEnd.nWallWeight;
wallLn.id = pEnt->objectId();
if (pWall->IsArcBaseCurve())
{
AcDbArc* pArc = AcDbArc::cast(pWall->GetNativeCurve());
wallLn.nType = 1;
wallLn.ptGe[1] = GetArcMidPoint(pArc);
}
wallLn.pWallCmpl = wallEnd.pWallCmpl;
arWallLns.append(wallLn);
if (pWall->GetAssocPartCount() > 0)
{
m_arIDsWallHasOpening.append(wallLn.id);
}
}
AecDbColumn* pCol = AecDbColumn::cast(pEnt);
if (pCol != NULL)
{
pCol->getStartPoint(ptSta);
ptSta.z = 0.0;//投影
colEnd.pColCmpl = new AecComplexCurve;
m_arCmplPtrs.append(colEnd.pColCmpl);
pCol->GetDraw2dables(*colEnd.pColCmpl);
colEnd.ptPos = ptSta;
colEnd.id = pEnt->objectId();
arColEnds.append(colEnd);
}
pEnt->close();
}
}
//柱子关联墙体
for (int i = 0;i < arColEnds.length();i++)
{
ColEnd& colE = arColEnds.at(i);
for (int j = 0;j < arWallLns.length();j++)
{
WallLn& waL = arWallLns.at(j);
if (ColumnAssocWall(colE,waL))
{
ColOnWall colWall;
colWall.idCol = colE.id;
colWall.ptPos = colE.ptPos;
colWall.idWall = waL.id;
colWall.pColCmpl = colE.pColCmpl;
m_arColOnWall.append(colWall);
}
}
}
//然后构建T结构
for (int i = 0;i < arWallEnds.length();i++)
{
WallEnd we = arWallEnds.at(i);
//找到搭边的实体
for (int ii = 0;ii < arWallLns.length();ii++)
{
WallLn& wl = arWallLns.at(ii);
//判断是否 搭边 T 结构
if (IsTJoin(we,wl))
{
if ( we.idCol.isValid() )
{
AppendWallTJoin(wl.id,we,wl.nWallWeight);
//一端只搭一个墙体,所以去除这个
arWallEnds.removeAt(i);
i -= 1;
break;
}
else
{
if (we.id != wl.id)
{
AppendWallTJoin(wl.id,we,wl.nWallWeight);
//一端只搭一个墙体,所以去除这个
arWallEnds.removeAt(i);
i -= 1;
break;
}
}
}
else//有可能是相交结构
{
if (wl.id != we.id)
{
if (wl.id.asOldId() < we.id.asOldId())
{
pt.x = (LONG)(wl.id.asOldId() - nStartRef);
pt.y = (LONG)(we.id.asOldId() - nStartRef);
}
else
{
pt.x = (LONG)(we.id.asOldId() - nStartRef);
pt.y = (LONG)(wl.id.asOldId() - nStartRef);
}
if (arIdIds.find(pt) == -1)
{
arIdIds.append(pt);//记下,表示处理过
for (int iii = 0;iii < arWallLns.length();iii++)
{
WallLn& wl2 = arWallLns.at(iii);
if (wl2.id == we.id)
{
if (IsIntJoin(wl,wl2,ptInt))
{
wallInt.id1 = wl.id;
wallInt.id2 = we.id;
wallInt.ptInt = ptInt;
m_arIntJoins.append(wallInt);
}
break;
}
}
}
}
}
}
}
if (!m_arIntJoins.isEmpty())
{
acutPrintf(_T("\n墙体有相交,需要断开处理!"));
}
//从X结构中提取==结构
return true;
}
bool AecWall2DJoin::IsIntJoin(WallLn& wl,WallLn& wl2,AcGePoint3d& ptInt) const
{
if (wl2.id == wl.id)//自己不交自己
return false;
AcGePoint3dArray arPts;
if (wl.nType == 0 && wl2.nType == 0)//line
{
AcDbLine ln1(wl.ptGe[0],wl.ptGe[1]);
AcDbLine ln2(wl2.ptGe[0],wl2.ptGe[1]);
ln1.intersectWith(&ln2,AcDb::kOnBothOperands,arPts);
if (!arPts.isEmpty())
{
ptInt = arPts.first();
}
return !arPts.isEmpty();
}
else
{
if (wl.nType == 0)
{
AcDbLine ln1(wl.ptGe[0],wl.ptGe[1]);
AcDbArc* pArc = FormatArc(wl2.ptGe[0],wl2.ptGe[1],wl2.ptGe[2]);
if (pArc != NULL)
{
pArc->intersectWith(&ln1,AcDb::kOnBothOperands,arPts);
delete pArc;
}
}
else
{
AcDbLine ln2(wl2.ptGe[0],wl2.ptGe[1]);
AcDbArc* pArc = FormatArc(wl.ptGe[0],wl.ptGe[1],wl.ptGe[2]);
if (pArc != NULL)
{
pArc->intersectWith(&ln2,AcDb::kOnBothOperands,arPts);
delete pArc;
}
}
if (!arPts.isEmpty())
{
ptInt = arPts.first();
}
}
return !arPts.isEmpty();
}
bool AecWall2DJoin::IsTJoin(WallEnd& we,WallLn& wl) const
{
if (we.id == wl.id)//自己不搭自己
return false;
if (wl.nType == 0)//line
{
AcDbLine ln(wl.ptGe[0],wl.ptGe[1]);
AcGeVector3d vtL = wl.ptGe[1] - wl.ptGe[0];
AcGePoint3d ptOn;
ln.getClosestPointTo(we.ptEnd,ptOn,Adesk::kFalse);
//如果落到端点,则不是T结构
if (ptOn.distanceTo(wl.ptGe[0]) < 1.e-1 ||
ptOn.distanceTo(wl.ptGe[1]) < 1.e-1)
{
return false;
}
double dDis = ptOn.distanceTo(we.ptEnd);
if ( (dDis - __min(wl.dThick,we.dThick)) < 1.e-6)//1个墙厚
{
if (we.vtEnd.isParallelTo(vtL))
return false;
ln.getParamAtPoint(ptOn,we.dParamOnM);
return true;
}
}
else if (wl.nType == 1)
{
AcDbArc* pArc = FormatArc(wl.ptGe[0],wl.ptGe[1],wl.ptGe[2]);
if (pArc != NULL)
{
AcGePoint3d ptOn;
pArc->getClosestPointTo(we.ptEnd,ptOn, Adesk::kFalse);
double dDis = ptOn.distanceTo(we.ptEnd);
if ( (dDis - __min(wl.dThick,we.dThick)) < 1.e-6)//1 个墙厚
{
pArc->getParamAtPoint(ptOn,we.dParamOnM);
delete pArc;
return true;
}
delete pArc;
}
}
return false;
}
void AecWall2DJoin::AppendWallTJoin(AcDbObjectId& idMain,const WallEnd& we,int nMainWeight)
{
//有什么快速方法?
bool bFind = false;
for (int i = 0;i < m_arTJoins.length();i++)
{
WallTJoin& wtOf = m_arTJoins.at(i);
if (wtOf.idMain == idMain)
{
if (wtOf.nValid < MAX_T_STRS)
{
wtOf.wes[wtOf.nValid] = we;
wtOf.nValid += 1;
bFind = true;
return;
}
else
{
acutPrintf(_T("\n某一面墙体超过上限T型结构!"));
}
}
if (bFind)
{
break;
}
}
//没有找到
if (!bFind)
{
WallTJoin wt;
if (we.id.isValid() )
{
wt.idMain = idMain;
wt.nValid = 1;
wt.nWallWeight = nMainWeight;
wt.wes[0] = we;
m_arTJoins.append(wt);
}
}
}
bool GetIntPoint(AcGePoint3d& ptJoin,const AcGeVector3d& vtEnd,const AcGePoint3d& ptEnd,const AcGeVector3d& vtEnd2)
{
AcGeLine3d ln1(ptJoin,vtEnd),ln2(ptEnd,vtEnd2);
AcGePoint3d ptInt;
if ( ln1.intersectWith(ln2,ptInt) )
{
ptJoin = ptInt;
return true;
}
return false;
}
bool RayIntersectRay(WallXJoin& wallXj,const WallEnd& wallEnd,AcGePoint3d& ptInt)
{
//考虑和圆弧相切的情况
//避开自交
for (int ii = 0;ii < wallXj.nValid;ii++)
{
if ( wallXj.ids[ii] == wallEnd.id)
{
return false;
}
}
if ( wallXj.vtEnd[0].isParallelTo(wallEnd.vtEnd) )
{
ptInt = wallEnd.ptEnd;
return true;
}
AcDbRay ray1,ray2;
ray1.setUnitDir(-wallXj.vtEnd[0]);
ray1.setBasePoint(wallXj.ptJoin);
ray2.setUnitDir(-wallEnd.vtEnd);
ray2.setBasePoint(wallEnd.ptEnd);
AcGePoint3dArray arPts;
ray1.intersectWith(&ray2,AcDb::kOnBothOperands,arPts);
//TEST
/*if (!arPts.isEmpty())
{
AddToModelSpace((AcDbEntity*)ray1.clone());
AddToModelSpace((AcDbEntity*)ray2.clone());
}*/
if (!arPts.isEmpty())
{
ptInt = arPts.first();
}
else
{
ray1.intersectWith(&ray2,AcDb::kExtendBoth,arPts);
if (!arPts.isEmpty())
{
ptInt = arPts.first();
double dDis1 = ptInt.distanceTo(wallEnd.ptEnd);
double dDis2 = ptInt.distanceTo(wallXj.ptJoin);
if (dDis1 < __max(wallEnd.dThick,wallXj.dThick) &&
dDis2 < __max(wallEnd.dThick,wallXj.dThick) )
{
return true;
}
else
{
return false;
}
}
}
return !arPts.isEmpty();
}
void AecWall2DJoin::AppendWallEnd(const WallEnd& wallEnd,int nFlag)
{
//有什么快速方法?
bool bFind = false;
bool bSelX = false;
double dDis = 0.0;
if (m_arXJoins.isEmpty())
{
WallXJoin wallXj;
wallXj.nValid = 1;//只有一个
wallXj.nWallWeight[0] = wallEnd.nWallWeight;
wallXj.ids[0] = wallEnd.id;
wallXj.ptJoin = wallEnd.ptEnd;
wallXj.vtEnd[0] = wallEnd.vtEnd;
wallXj.dThick = wallEnd.dThick;
wallXj.dThicks[0] = wallEnd.dThick;
m_arXJoins.append(wallXj);
return;
}
//找到最接近的XJ
AcGePoint3d ptInt;
int nPos = -1;
for(int i = 0;i < m_arXJoins.length();i++)
{
WallXJoin& wallXj = m_arXJoins.at(i);
dDis = wallEnd.ptEnd.distanceTo(wallXj.ptJoin);
if (dDis < __max(wallEnd.dThick,wallXj.dThick) )
{
if (RayIntersectRay(wallXj,wallEnd,ptInt))
{
//避开自交
for (int ii = 0;ii < wallXj.nValid;ii++)
{
if ( wallXj.ids[ii] == wallEnd.id)
{
bSelX = true;
break;
}
}
if (bSelX) continue;
nPos = i;
}
}
}
bSelX = false;
if (nPos > -1 && nPos < m_arXJoins.length())
{
WallXJoin& wallXj = m_arXJoins.at(nPos);
bFind = false;
dDis = wallEnd.ptEnd.distanceTo(wallXj.ptJoin);
if (dDis - __max(wallEnd.dThick,wallXj.dThick) < 1.e-6)//-g_xjoinR
{
//且射线相交,X 结构
//if ( fabs(wallEnd.dThick - wallXj.dThick) < 1.0)//等厚
{
//避开自交
for (int ii = 0;ii < wallXj.nValid;ii++)
{
if ( wallXj.ids[ii] == wallEnd.id)
{
bSelX = true;
break;
}
}
if (!bSelX)
{
for (int ii = 0;ii < 4;ii++)
{
if (!wallXj.ids[ii].isValid() )
{
wallXj.ids[ii] = wallEnd.id;
wallXj.nValid += 1;
wallXj.nWallWeight[ii] = wallEnd.nWallWeight;
wallXj.vtEnd[ii] = wallEnd.vtEnd;
wallXj.dThicks[ii] = wallEnd.dThick;
/*if (ii > 0)
{
if ( !GetIntPoint(wallXj.ptJoin,wallXj.vtEnd[ii-1],wallEnd.ptEnd,wallEnd.vtEnd) )//取交点
{
wallXj.ptJoin = MidPoint(wallXj.ptJoin,wallEnd.ptEnd);//取中点
}
}
else
{
wallXj.ptJoin = MidPoint(wallXj.ptJoin,wallEnd.ptEnd);//取中点
}*/
wallXj.ptJoin = ptInt;
bFind = true;
break;
}
}
}
}
}
}
if (!bFind)//没有找到,也加入
{
WallXJoin wallXj;
wallXj.nValid = 1;//只有一个
wallXj.ids[0] = wallEnd.id;
wallXj.ptJoin = wallEnd.ptEnd;
wallXj.vtEnd[0] = wallEnd.vtEnd;
wallXj.dThick = wallEnd.dThick;
wallXj.dThicks[0] = wallEnd.dThick;
wallXj.nWallWeight[0] = wallEnd.nWallWeight;
m_arXJoins.append(wallXj);
}
}
bool AecWall2DJoin::DoWall2DJoin()
{
//1.处理X结构
for (int i = 0;i < m_arXJoins.length();i++)
{
WallXJoin& wj = m_arXJoins.at(i);
if (wj.idCol.isValid())//有柱子
{
//延伸到柱子
ExtendToColumnRegion(wj);
}
else
{
//逆时针排序裁剪
if (wj.nValid > 1)//有X结构
{
XJoinSortAndTrimByUClock(wj);
}
}
}
//2.处理T结构,同时产生T结构的延伸
for (int i = 0;i < m_arTJoins.length();i++)
{
WallTJoin& wt = m_arTJoins.at(i);
TJoinSortAndTrimByMain(wt);
}
//3.处理T结构的延伸墙体
AcDbEntity* pEntE = NULL;
for (int i = 0;i < m_arWallExtends.length();i++)
{
WallExtend& exd = m_arWallExtends.at(i);
if ( Acad::eOk == acdbOpenAcDbEntity(pEntE,exd.idWall,AcDb::kForWrite))
{
AecDbXWall* pWallE = AecDbXWall::cast(pEntE);
if (pWallE != NULL)
{
for (int j = 0;j < exd.nEnds;j++)
{
Extend(pWallE,exd.bExtendSta[j],exd.ptOn[j],exd.vtEnd[j], exd.idMain, exd.nNearSide);
}
}
pEntE->close();
}
}
//4.门窗裁剪
AcDbObjectId idWall;
for(int i = 0;i < m_arIDsWallHasOpening.length();i++)
{
idWall = m_arIDsWallHasOpening.at(i);
RefreshWallOnOpeningDrawEx(idWall);
}
//5.处理相交结构
IntJoinsBoolSubtract();
//6.墙体裁剪柱子
for (int i = 0;i < m_arColOnWall.length();i++)
{
ColOnWall& colWall = m_arColOnWall.at(i);
ColumnClipWall(colWall);
}
return true;
}
void AecWall2DJoin::ColumnClipWall(ColOnWall& colWall)
{
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,colWall.idWall,AcDb::kForWrite))
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
//进行类似遮挡处理
AecComplexCurve draw2d;
pWall->GetDraw2dables(draw2d);
//区域裁剪
AecComplexCurve cmplOutSide,cmplInSide;
AecCoverBooleanOper::PolyClip(*colWall.pColCmpl,draw2d,cmplOutSide,cmplInSide);
pWall->SetDraw2dables(cmplOutSide);
//移除端部标记
//pWall->RemoveTailDraw2d(colWall.ptPos);
cmplOutSide.removeAll();
cmplInSide.removeAll();
draw2d.removeAll();
pWall->GetDraw2dHideTail(draw2d);
AecCoverBooleanOper::PolyClip(*colWall.pColCmpl,draw2d,cmplOutSide,cmplInSide);
pWall->SetDraw2dHideTail(cmplOutSide);
//墙体关联柱子
// 在这里没有发现关联柱子的必要啊,就是不关联功能也可以实现,
// 暂时不关联,不然deepclone和wblockclone会把柱子复制出来
//pWall->AppendAssocPart(colWall.idCol);
}
pEnt->close();
}
}
AecDbX3dPart* AecWall2DJoin::Create3DSolid(AecComplexCurve& cmplCol,WallData& data1,WallData& data2)
{
AcDbX3dSolid* pXSolid = NULL;
AcDbCurve* pCurve = NULL;
AcDbVoidPtrArray arCurPtrs,arRes;
for (int i = 0;i < cmplCol.length();i++)
{
pCurve = cmplCol.segat(i);
if (pCurve != NULL)
{
arCurPtrs.append(pCurve);
}
}
pCurve = KTCADUtilityEx::ConvertBoundCurve(arCurPtrs,arRes);
if (pCurve != NULL)
{
AcDbPolyline* pPl = AcDbPolyline::cast(pCurve);
if (pPl != NULL)
{
pPl->setElevation(__max(data1.dBomEl,data2.dBomEl));
pPl->setClosed(Adesk::kTrue);
AcDbExtents ext;
pPl->getGeomExtents(ext);
AcGePoint3d ptS = MidPoint(ext.minPoint(),ext.maxPoint());
AcGePoint3d ptE = ptS;
ptE.z = __min(data1.dH,data2.dH);
arCurPtrs.removeAll();
arCurPtrs.append(pPl);
arRes.removeAll();
AcDbRegion::createFromCurves(arCurPtrs,arRes);
delete pPl;
if (!arRes.isEmpty())
{
AcDbRegion* pRegion = (AcDbRegion*)arRes.first();
AcDbLine lnPath;
lnPath.setStartPoint(ptS);
lnPath.setEndPoint(ptE);
pXSolid = new AcDbX3dSolid;
pXSolid->CreateExtrude(pRegion,lnPath);
delete pRegion;
}
}
}
if (pXSolid != NULL)
{
AecDbX3dPart* pPart = new AecDbX3dPart;
pPart->SetName(_T("ExAdd"));
pPart->GetSpecialtyData()->SetAt(KEY_ADDTIONSHOW,TRUE);
pPart->GetSpecialtyData()->SetAt(KEY_POS,0);
pPart->GetSpecialtyData()->SetAt(KEY_FORSLICE,FALSE);
pPart->AddX3dSolid(pXSolid);
return pPart;
}
return NULL;
}
void AecWall2DJoin::IntJoinsBoolSubtract()
{
AcDbEntity* pEnt2 = NULL,*pEnt1 = NULL;
for (int i = 0;i < m_arIntJoins.length();i++)
{
WallIntJoin& wIntJ = m_arIntJoins.at(i);
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt1,wIntJ.id1,AcDb::kForWrite))
{
AecDbXWall* pWall1 = AecDbXWall::cast(pEnt1);
if (pWall1 != NULL)
{
AcGeVector3d vt1,vt2;
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
AecComplexCurve cmplSub,cmplCol;
AecEqui::AecCurveElement eL1 = pWall1->GetLeftElement(true);
AecEqui::AecCurveElement eR1 = pWall1->GetRightElement(true);
AecEqui::AecCurveElement eC1 = pWall1->GetMidElement();
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt2,wIntJ.id2,AcDb::kForWrite))
{
AecDbXWall* pWall2 = AecDbXWall::cast(pEnt2);
if (pWall2 != NULL)
{
AecEqui::AecCurveElement eL2 = pWall2->GetLeftElement(true);
AecEqui::AecCurveElement eR2 = pWall2->GetRightElement(true);
AecEqui::AecCurveElement eC2 = pWall2->GetMidElement();
//墙体在标高上有相交
WallData data1,data2;
pWall1->GetWallData(data1);
pWall2->GetWallData(data2);
int nWallWeight1 = MaterialWeight(data1.szMat);
int nWallWeight2 = MaterialWeight(data2.szMat);
AcGePoint3dArray arPt;
//等标高+H 相交
//不等,部分被裁
//相交结构,墙1=墙2
if ( fabs ( (data1.dBomEl + data1.dH) - ( data2.dBomEl + data2.dH ) ) < 1.e-3)
{
//L1X(L2 R2)
AecComplexCurve::IntersectWith(eL1,eL2,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eL1,eR2,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eL1,eC2,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 3)
{
el.ptGe[0] = arPt.first();//sta
el.ptGe[2] = arPt.last();//mid
el.ptGe[1] = arPt.at(1);//end
vt1 = arPt.last() - arPt.first();
vt2 = arPt.at(1) - arPt.first();
if (vt1.isParallelTo(vt2))
{
el.ptGe[2] = el.ptGe[1];
}
cmplSub.append(el);
}
arPt.removeAll();
//R1X(L2 R2)
AecComplexCurve::IntersectWith(eR1,eL2,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eR1,eR2,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eR1,eC2,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 3)
{
el.ptGe[0] = arPt.first();
el.ptGe[2] = arPt.last();
el.ptGe[1] = arPt.at(1);
vt1 = arPt.last() - arPt.first();
vt2 = arPt.at(1) - arPt.first();
if (vt1.isParallelTo(vt2))
{
el.ptGe[2] = el.ptGe[1];
}
cmplSub.append(el);
}
arPt.removeAll();
//裁剪 墙1材质<=墙2材质
if (nWallWeight1 <= nWallWeight2)
pWall1->SubtractDraw2d(cmplSub);
cmplCol.append(cmplSub);
cmplSub.removeAll();
//L2X(L1 R1)
AecComplexCurve::IntersectWith(eL2,eL1,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eL2,eR1,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eL2,eC1,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 3)
{
el.ptGe[0] = arPt.first();
el.ptGe[2] = arPt.last();
el.ptGe[1] = arPt.at(1);
vt1 = arPt.last() - arPt.first();
vt2 = arPt.at(1) - arPt.first();
if (vt1.isParallelTo(vt2))
{
el.ptGe[2] = el.ptGe[1];
}
cmplSub.append(el);
}
arPt.removeAll();
//R2X(L1 R1)
AecComplexCurve::IntersectWith(eR2,eL1,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eR2,eR1,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eR2,eC1,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 3)
{
el.ptGe[0] = arPt.first();
el.ptGe[2] = arPt.last();
el.ptGe[1] = arPt.at(1);
vt1 = arPt.last() - arPt.first();
vt2 = arPt.at(1) - arPt.first();
if (vt1.isParallelTo(vt2))
{
el.ptGe[2] = el.ptGe[1];
}
cmplSub.append(el);
}
arPt.removeAll();
//裁剪
//裁剪 墙2材质<=墙1材质
if (nWallWeight2 <= nWallWeight1)
pWall2->SubtractDraw2d(cmplSub);
cmplCol.append(cmplSub);
//需要判断重墙体轻重,默认wall1去除
AecDbX3dPart* pCol1 = Create3DSolid(cmplCol,data1,data2);
if (pCol1 != NULL)
{
if (nWallWeight1 <= nWallWeight2)
{
pWall1->AddX3dPart(pCol1, AcDb::kBoolSubtract);
}
else
{
delete pCol1;
}
}
}
else
{
//部分相交非等标高和高度的两个墙体处理
if ( (data1.dBomEl + data1.dH) - ( data2.dBomEl + data2.dH ) < 1.e-3)
{
//wall1 矮于 wall2 wall1 被穿
//L1X(L2 R2)
AcGePoint3dArray arPt;
AecComplexCurve::IntersectWith(eL1,eL2,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eL1,eR2,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eL1,eC2,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 3)
{
el.ptGe[0] = arPt.first();//sta
el.ptGe[2] = arPt.last();//mid
el.ptGe[1] = arPt.at(1);//end
vt1 = arPt.last() - arPt.first();
vt2 = arPt.at(1) - arPt.first();
if (vt1.isParallelTo(vt2))
{
el.ptGe[2] = el.ptGe[1];
}
cmplSub.append(el);
}
arPt.removeAll();
//R1X(L2 R2)
AecComplexCurve::IntersectWith(eR1,eL2,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eR1,eR2,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eR1,eC2,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 3)
{
el.ptGe[0] = arPt.first();
el.ptGe[2] = arPt.last();
el.ptGe[1] = arPt.at(1);
vt1 = arPt.last() - arPt.first();
vt2 = arPt.at(1) - arPt.first();
if (vt1.isParallelTo(vt2))
{
el.ptGe[2] = el.ptGe[1];
}
cmplSub.append(el);
}
arPt.removeAll();
//裁剪
//裁剪 墙1材质<=墙2材质
if (nWallWeight1 <= nWallWeight2)
pWall1->SubtractDraw2d(cmplSub);
cmplCol.append(cmplSub);
cmplSub.removeAll();
}
else
{
//wall2 矮于 wall1 wall2 被穿
//L2X(L1 R1)
AecComplexCurve::IntersectWith(eL2,eL1,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eL2,eR1,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eL2,eC1,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 3)
{
el.ptGe[0] = arPt.first();
el.ptGe[2] = arPt.last();
el.ptGe[1] = arPt.at(1);
vt1 = arPt.last() - arPt.first();
vt2 = arPt.at(1) - arPt.first();
if (vt1.isParallelTo(vt2))
{
el.ptGe[2] = el.ptGe[1];
}
cmplSub.append(el);
}
arPt.removeAll();
//R2X(L1 R1)
AecComplexCurve::IntersectWith(eR2,eL1,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eR2,eR1,AcDb::kOnBothOperands,arPt);
AecComplexCurve::IntersectWith(eR2,eC1,AcDb::kOnBothOperands,arPt);
if (arPt.length() == 3)
{
el.ptGe[0] = arPt.first();
el.ptGe[2] = arPt.last();
el.ptGe[1] = arPt.at(1);
vt1 = arPt.last() - arPt.first();
vt2 = arPt.at(1) - arPt.first();
if (vt1.isParallelTo(vt2))
{
el.ptGe[2] = el.ptGe[1];
}
cmplSub.append(el);
}
arPt.removeAll();
//裁剪
//裁剪 墙2材质<=墙1材质
if (nWallWeight2 <= nWallWeight1)
pWall2->SubtractDraw2d(cmplSub);
cmplCol.append(cmplSub);
}
}
}
pEnt2->close();
}
}
pEnt1->close();
}
}
}
bool SortByParam(IdParamEl& idp1,IdParamEl& idp2)
{
if (idp1.dParam - idp2.dParam < 1.e-10)
return true;
return false;
}
void AecWall2DJoin::GetMidPoint(AecDbXWall* pWall,AcGePoint3d& ptMid)
{
AcDbCurve* pBaseCurve = GetWallBaseCurve(pWall);
if (pBaseCurve != NULL)
{
AcDbLine* pLn = AcDbLine::cast(pBaseCurve);
if (pLn != NULL)
{
ptMid = MidPoint(pLn->startPoint(),pLn->endPoint());
}
AcDbArc* pArc = AcDbArc::cast(pBaseCurve);
if (pArc != NULL)
{
ptMid = GetArcMidPoint(pArc);
}
}
}
void AecWall2DJoin::ExtendToColumnRegion(const WallXJoin& wj)
{
AecDbXWall* pWall = NULL;
AcDbEntity* pEntWall = NULL;
AcDbEntity* pEntCol = NULL;
AecDbColumn* pCol = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEntCol,wj.idCol,AcDb::kForRead))
{
pCol = AecDbColumn::cast(pEntCol);
if (pCol != NULL)
{
//获取闭合的柱子外包线
AecComplexCurve draw2dCol;
pCol->GetDraw2dables(draw2dCol);
AcGePoint3d ptPos = pCol->GetPosition();
ptPos.z = 0.0;
//墙体裁去柱子的线
for (int i = 0;i < wj.nValid;i++)
{
if ( Acad::eOk == acdbOpenAcDbEntity(pEntWall,wj.ids[i],AcDb::kForWrite))
{
pWall = AecDbXWall::cast(pEntWall);
if (pWall != NULL)
{
//进行类似遮挡处理
AecComplexCurve draw2d;
pWall->GetDraw2dables(draw2d);
//区域裁剪
AecComplexCurve cmplOutSide,cmplInSide;
AecCoverBooleanOper::PolyClip(draw2dCol,draw2d,cmplOutSide,cmplInSide);
pWall->SetDraw2dables(cmplOutSide);
//移除端部标记
pWall->RemoveTailDraw2d(ptPos);
}
pEntWall->close();
}
}
}
pEntCol->close();
}
}
bool SortIdAngleElByAngle(IdAngleEl& idael1,IdAngleEl& idael2)
{
if (idael1.dParam < idael2.dParam)
return true;
return false;
}
void AecWall2DJoin::UnClockWiseSortLR(std::vector<IdParamEl>& vtIdParams,const AcGePoint3d& ptOn,std::vector<IdAngleEl>& vtIdAngleEl)
{
double dA1 = 0.0,dA2 = 0.0;
AcGeVector3d vt1,vt2;
AcGePoint3d ptM1,ptM2;
AecEqui::AecCurveElement elT;
memset(&elT,0,sizeof(AecEqui::AecCurveElement));
IdAngleEl ael;
ael.bIsOverParallel = false;
for (int i = 0;i < vtIdParams.size();i++)
{
IdParamEl& idp1 = vtIdParams.at(i);
ptM1 = MidPoint(idp1.eL.ptGe[0],idp1.eL.ptGe[2]);
vt1 = ptM1 - ptOn;
vt1.z = 0.0;
ptM2 = MidPoint(idp1.eR.ptGe[0],idp1.eR.ptGe[2]);
vt2 = ptM2 - ptOn;
vt2.z = 0.0;
//vt1.normalize();
//vt2.normalize();
dA1 = AcGeVector3d::kXAxis.angleTo(vt1,AcGeVector3d::kZAxis);
dA2 = AcGeVector3d::kXAxis.angleTo(vt2,AcGeVector3d::kZAxis);
ael.el = idp1.eL;
ael.id = idp1.id;
ael.dParam = dA1;
ael.nWallWeight = idp1.nWallWeight;
vtIdAngleEl.push_back(ael);
ael.el = idp1.eR;
ael.id = idp1.id;
ael.dParam = dA2;
ael.nWallWeight = idp1.nWallWeight;
vtIdAngleEl.push_back(ael);
}
std::sort(vtIdAngleEl.begin(),vtIdAngleEl.end(),SortIdAngleElByAngle);
}
static void ElementSubtract(AecEqui::AecCurveElement& el1, AecEqui::AecCurveElement& el2, AcArray<AecEqui::AecCurveElement>& elRes1, AcArray<AecEqui::AecCurveElement>& elRes2)
{
//el1,el2均为直线
AecComplexCurve cpl1;
cpl1.append(el1);
el2.bHided = 1;
cpl1.append(el2);
el2.bHided = 0;
cpl1.boolSubtract();
for (int i = 0;i < cpl1.length();i++)
{
elRes1.append(cpl1.at(i));
}
AecComplexCurve cpl2;
cpl2.append(el2);
el1.bHided = 1;
cpl2.append(el1);
el1.bHided = 0;
cpl2.boolSubtract();
for (int i = 0;i < cpl2.length();i++)
{
elRes2.append(cpl2.at(i));
}
}
bool AecWall2DJoin::CalWeightWallEndLine(IdParamEl &idPW, IdParamEl &idPQ, AecEqui::AecCurveElement &elWEnd, AecEqui::AecCurveElement &elWExt)
{
AcGePoint3d ptGe[2],ptGeT;
AcGeVector3d vtDir[2];
AcDbCurve *pCrvL = NULL, *pCrvR = NULL;
AecComplexCurve::MakeCurve(idPW.eL, pCrvL);
AcGePoint3dArray arWPts;
arWPts.append(idPW.eL.ptGe[0]);
arWPts.append(idPW.eL.ptGe[2]);
bool bFind1 = false;
if (!bFind1 && arWPts.find(idPQ.eL.ptGe[0]) != -1)
{
ptGe[0] = idPQ.eL.ptGe[0];
bFind1 = true;
}
if (!bFind1 && arWPts.find(idPQ.eL.ptGe[2]) != -1)
{
ptGe[0] = idPQ.eL.ptGe[2];
bFind1 = true;
}
if (!bFind1 && arWPts.find(idPQ.eR.ptGe[0]) != -1)
{
ptGe[0] = idPQ.eR.ptGe[0];
bFind1 = true;
}
if (!bFind1 && arWPts.find(idPQ.eR.ptGe[2]) != -1)
{
ptGe[0] = idPQ.eR.ptGe[2];
bFind1 = true;
}
if (pCrvL != NULL)
{
pCrvL->getFirstDeriv(ptGe[0], vtDir[0]);
//delete pCrvL;->POS D
}
AecComplexCurve::MakeCurve(idPW.eR, pCrvR);
bool bFind2 = false;
arWPts.removeAll();
arWPts.append(idPW.eR.ptGe[0]);
arWPts.append(idPW.eR.ptGe[2]);
if (!bFind2 &&arWPts.find(idPQ.eL.ptGe[0]) != -1)
{
ptGe[1] = idPQ.eL.ptGe[0];
bFind2 = true;
}
if (!bFind2 && arWPts.find(idPQ.eL.ptGe[2]) != -1)
{
ptGe[1] = idPQ.eL.ptGe[2];
bFind2 = true;
}
if (!bFind2 && arWPts.find(idPQ.eR.ptGe[0]) != -1)
{
ptGe[1] = idPQ.eR.ptGe[0];
bFind2 = true;
}
if (!bFind2 && arWPts.find(idPQ.eR.ptGe[2]) != -1)
{
ptGe[1] = idPQ.eR.ptGe[2];
bFind2 = true;
}
if (pCrvR != NULL)
{
pCrvR->getFirstDeriv(ptGe[1], vtDir[1]);
//delete pCrvR;->POS D
}
vtDir[0].normalize(); vtDir[1].normalize();
AcDbCurve *pCrvW[2];
pCrvW[0] = pCrvL; pCrvW[1] = pCrvR;
//TEST
/*for (int n = 0; n < 2; n++)
{
ptGeT = ptGe[n] + vtDir[n] * 1000;
AcDbLine *pLnT = new AcDbLine(ptGe[n], ptGeT);
pLnT->setColorIndex(2);
AddToModelSpace(pLnT);
}*/
//圆弧墙体不考虑轻重搭接,因为可能圆弧和直线可能不相交
//直接轻重隔开
AcDbArc *pArcW = AcDbArc::cast(pCrvW[0]);
if (pArcW != NULL)
{
delete pCrvL;
delete pCrvR;
elWEnd.ptGe[0] = ptGe[0];
elWEnd.ptGe[1] = ptGe[1];
elWEnd.ptGe[2] = ptGe[1];
elWExt.ptGe[0] = ptGe[0];
elWExt.ptGe[1] = ptGe[0];
elWExt.ptGe[2] = ptGe[0];
return true;
}
bool bFind = false;
if (bFind1 && bFind2)
{
AcDbCurve* pCrv[2];
AecComplexCurve::MakeCurve(idPQ.eL, pCrv[0]);
AecComplexCurve::MakeCurve(idPQ.eR, pCrv[1]);
if (pCrv[0] != NULL && pCrv[1] != NULL)
{
AcGePoint3d ptOn,ptSE[2];
AcGeVector3d vt1, vt2;
for (int i = 0;i < 2;i++)
{
pCrv[i]->getStartPoint(ptSE[0]);
pCrv[i]->getEndPoint(ptSE[1]);
if (!bFind)
{
for (int j = 0;j < 2;j++)
{
pCrv[i]->getClosestPointTo(ptGe[j], vtDir[j], ptOn, Adesk::kFalse);
//判断是否落在曲线内
vt1 = ptOn - ptSE[0];
vt2 = ptOn - ptSE[1];
if (!vt1.isZeroLength() && !vt2.isZeroLength() && vt1.dotProduct(vt2) < -1.e-10)
{
elWEnd.ptGe[0] = ptGe[j];
elWEnd.ptGe[1] = ptOn;
elWEnd.ptGe[2] = ptOn;
elWExt.ptGe[0] = ptGe[1-j];//取另一个
elWExt.ptGe[1] = ptOn;
elWExt.ptGe[2] = ptOn;
bFind = true;
}
if (bFind) break;
}
}
if (bFind) break;
}
delete pCrv[0];
delete pCrv[1];
}
}
delete pCrvL;
delete pCrvR;
return bFind;
}
void AecWall2DJoin::XJoinSortAndTrimByUClock(const WallXJoin& wj)
{
IdParamEl idp;
idp.bIsOverParallel = false;
std::vector<IdParamEl> vtIdParams;
AcGePoint3d ptOn = wj.ptJoin;
AcDbObjectIdArray arIds;
int nFat = -1;
AcGeVector3d vt;
AcGePoint3d ptMid,ptOn2;
AcDbIntArray arWallWeight;
AcDbEntity* pEnt = NULL;
for(int i = 0;i < wj.nValid;i++)
{
idp.id = wj.ids[i];
if (arIds.find(idp.id,nFat) )
{
continue;
}
arIds.append(idp.id);//避开自己和自己处理
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,wj.ids[i],AcDb::kForRead))
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
GetMidPoint(pWall,ptMid);
vt = ptMid - ptOn;
vt.z = 0.0;
idp.dParam = AcGeVector3d::kXAxis.angleTo(vt,AcGeVector3d::kZAxis);
idp.eL = pWall->GetLeftElement();
idp.eR = pWall->GetRightElement();
idp.nWallWeight = wj.nWallWeight[i];
if (arWallWeight.isEmpty())
arWallWeight.append(idp.nWallWeight);
else
{
if (arWallWeight.find(idp.nWallWeight) == -1)
{
arWallWeight.append(idp.nWallWeight);
}
}
vtIdParams.push_back(idp);
}
pEnt->close();
}
}
if (vtIdParams.size() == 1)
return;
std::sort(vtIdParams.begin(),vtIdParams.end(),SortByParam);
//以on为圆心,墙体的左右线按圆的逆时针排序
std::vector<IdAngleEl> vtIdAngleEl;
UnClockWiseSortLR(vtIdParams,ptOn,vtIdAngleEl);
AcGePoint3d ptInt;
AcGePoint3dArray arPtInts;
AcDbObjectIdArray arIdParallel;
for (int i = 0;i < vtIdAngleEl.size() - 1;i++)
{
IdAngleEl& ael1 = vtIdAngleEl.at(i);
IdAngleEl& ael2 = vtIdAngleEl.at(i+1);
if ( TrimCurveElement(ael1,ael2,ptInt) )
{
arPtInts.append(ptInt);
}
if (i == (vtIdAngleEl.size() - 2 ))
{
IdAngleEl& aele = vtIdAngleEl.at(i+1);
IdAngleEl& ael0 = vtIdAngleEl.at(0);
if ( TrimCurveElement(aele,ael0,ptInt) )
{
arPtInts.append(ptInt);
}
}
}
//按照id 合成
vtIdParams.clear();
int nPos = 0;
for(int i = 0;i < wj.nValid;i++)
{
idp.id = wj.ids[i];
idp.bIsOverParallel = false;
idp.nWallWeight = wj.nWallWeight[i];
nPos = 0;
for (int ii = 0;ii < vtIdAngleEl.size();ii++)
{
IdAngleEl& ael1 = vtIdAngleEl.at(ii);
if (ael1.id == idp.id)
{
if (ael1.bIsOverParallel)
{
idp.bIsOverParallel = true;
}
if (nPos == 0)
{
idp.eL = ael1.el;
nPos += 1;
}
else
{
idp.eR = ael1.el;
break;
}
}
}
if (nPos == 1)
{
vtIdParams.push_back(idp);
}
}
//窟窿补柱子
bool bAddCol = false;
AcGeVector3d vt1,vt2;
//写回二维图元
AecComplexCurve cmpl;
for(int i = 0;i < vtIdParams.size();i++)
{
IdParamEl& idp1 = vtIdParams.at(i);
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idp1.id,AcDb::kForWrite))
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
WallData wData;
memset(&wData,0,sizeof(WallData));
pWall->GetWallData(wData);
cmpl.removeAll();
cmpl.append(idp1.eL);
cmpl.append(idp1.eR);
pWall->SetDraw2dables(cmpl);
//AcDbCircle* pCir = new AcDbCircle;
//pCir->setCenter(ptOn);
//pCir->setRadius(10.0);
//AddToModelSpace(pCir);
//移除端部标记
pWall->getClosestPointTo(ptOn,ptOn2,Adesk::kFalse);
//2022-12-21墙体断开的尾部端线去除
if (!idp1.bIsOverParallel)
{
//且等宽
pWall->RemoveTailDraw2d(ptOn2);
}
//判断是否应该补在这个墙体上
//窟窿处补上柱子,确定哪个墙体补
if (!bAddCol)
{
if (arPtInts.length() > 2)
{
arPtInts.append(arPtInts.first());
AddXPart(pWall,arPtInts,ptOn);
bAddCol = true;
}
}
}
pEnt->close();
}
}
//如果两个节点,并且材质不一致
if (vtIdParams.size() == 2 && arWallWeight.length() > 1)
{
IdParamEl &idp1 = vtIdParams.at(0);
IdParamEl &idp2 = vtIdParams.at(1);
if (idp1.bIsOverParallel && idp2.bIsOverParallel)
{
//平行不同材质不处理
}
else
{
IdParamEl idPW, idPQ;
if (idp1.nWallWeight < idp2.nWallWeight)
{
idPW = idp2;
idPQ = idp1;
}
else
{
idPW = idp1;
idPQ = idp2;
}
AecEqui::AecCurveElement elWEnd,elWExt;
memset(&elWEnd, 0, sizeof(AecEqui::AecCurveElement));
memset(&elWExt, 0, sizeof(AecEqui::AecCurveElement));
if (CalWeightWallEndLine(idPW, idPQ, elWEnd,elWExt))
{
//测试TEST
/*AcDbCurve *pCrv = NULL;
AecComplexCurve::MakeCurve(elWEnd, pCrv);
if (pCrv != NULL)
{
pCrv->setColorIndex(1);
AddToModelSpace(pCrv);
}
AecComplexCurve::MakeCurve(elWExt, pCrv);
if (pCrv != NULL)
{
pCrv->setColorIndex(3);
AddToModelSpace(pCrv);
}*/
//重
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, idPW.id, AcDb::kForWrite))
{
AecDbXWall *pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
//增加端线
cmpl.removeAll();
pWall->GetDraw2dables(cmpl);
cmpl.append(elWEnd);
if (!elWExt.ptGe[0].isEqualTo(elWExt.ptGe[2]) )
cmpl.append(elWExt);
pWall->SetDraw2dables(cmpl);
}
pEnt->close();
}
//轻
if (!elWExt.ptGe[0].isEqualTo(elWExt.ptGe[2]))
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, idPQ.id, AcDb::kForWrite))
{
AecDbXWall *pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
//轻延伸到重一侧,并封闭端线
cmpl.removeAll();
pWall->GetDraw2dables(cmpl);
elWExt.bHided = 1;
cmpl.append(elWExt);
cmpl.boolSubtract();
pWall->SetDraw2dables(cmpl);
}
pEnt->close();
}
}
return;
}
}
}
//两平行墙体的端线融合处理,多于两个的墙不处理.
if (vtIdParams.size() == 2)
{
IdParamEl &idp1 = vtIdParams.at(0);
IdParamEl &idp2 = vtIdParams.at(1);
AecEqui::AecCurveElement el1,el2;
memset(&el1, 0, sizeof(AecEqui::AecCurveElement));
memset(&el2, 0, sizeof(AecEqui::AecCurveElement));
//平行连接结构
if (idp1.bIsOverParallel && idp2.bIsOverParallel)
{
AcDbEntity *pEnt1 = NULL;
AcDbEntity *pEnt2 = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt1, idp1.id, AcDb::kForWrite))
{
AecDbXWall *pWall1 = AecDbXWall::cast(pEnt1);
if (pWall1 != NULL)
{
pWall1->getClosestPointTo(ptOn, ptOn2, Adesk::kFalse);
pWall1->GetTailDraw2d(ptOn2, el1);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt2, idp2.id, AcDb::kForWrite))
{
AecDbXWall *pWall2 = AecDbXWall::cast(pEnt2);
if (pWall2 != NULL)
{
pWall2->getClosestPointTo(ptOn, ptOn2, Adesk::kFalse);
pWall2->GetTailDraw2d(ptOn2, el2);
//同等材质,才可以融合端线
if (idp1.nWallWeight == idp2.nWallWeight)
{
AcArray<AecEqui::AecCurveElement> elRes1, elRes2;
ElementSubtract(el1, el2, elRes1, elRes2);
if (elRes1.isEmpty())
{
pWall1->RemoveTailDraw2d(ptOn2);
}
else
{
AecComplexCurve cpl1,cplOn;
for (int i = 0; i < elRes1.length(); i++)
{
cpl1.append(elRes1.at(i));
}
pWall1->RemoveTailDraw2d(ptOn2);
pWall1->GetDraw2dHideTail(cplOn);
cplOn.append(cpl1);
pWall1->SetDraw2dHideTail(cplOn);
}
if (elRes2.isEmpty())
{
pWall2->RemoveTailDraw2d(ptOn2);
}
else
{
AecComplexCurve cpl2, cplOn;
for (int i = 0; i < elRes2.length(); i++)
{
cpl2.append(elRes2.at(i));
}
pWall2->RemoveTailDraw2d(ptOn2);
pWall2->GetDraw2dHideTail(cplOn);
cplOn.append(cpl2);
pWall2->SetDraw2dHideTail(cplOn);
}
}
}
pEnt2->close();
}
}
pEnt1->close();
}
return;
}
}
}
void AecWall2DJoin::AddXPart(AecDbXWall* pWall,AcGePoint3dArray& arPtInts,const AcGePoint3d& ptOn)
{
if (pWall == NULL)
return;
WallData data;
pWall->GetWallData(data);
AcGePoint3d ptSta,ptEnd;
ptSta = arPtInts.first();
ptEnd = ptSta;
ptSta.z = data.dBomEl;
ptEnd.z = ptSta.z + data.dH;
AcDbLine lnPath;
lnPath.setStartPoint(ptSta);
lnPath.setEndPoint(ptEnd);
AcDbRegion* pRegion = AecDbEarthWorm::CreatePolygonRegionOnly(arPtInts.asArrayPtr(),arPtInts.length());
if (pRegion != NULL)
{
int nPos = pWall->GetNearPosition(ptOn);
AecDbX3dPart* pPart = new AecDbX3dPart;
pPart->SetName(_T("ExAdd"));
pPart->GetSpecialtyData()->SetAt(KEY_ADDTIONSHOW,TRUE);
pPart->GetSpecialtyData()->SetAt(KEY_POS,nPos);
pPart->GetSpecialtyData()->SetAt(KEY_FORSLICE,FALSE);
AcGeVector3d vtMove;
vtMove.set(0,0,ptSta.z - arPtInts.first().z);
AcGeMatrix3d xform;
xform.setToTranslation(vtMove);
pRegion->transformBy(xform);
AcDbX3dSolid* pXSolid = new AcDbX3dSolid;
pXSolid->CreateExtrude(pRegion,lnPath);
pPart->AddX3dSolid(pXSolid);
pWall->AddX3dPart(pPart);
delete pRegion;
}
}
bool AecWall2DJoin::TrimLineArcElement(AcDbLine* pLn,AecEqui::AecCurveElement& el1,AcDbArc* pArc,AecEqui::AecCurveElement& el2,AcGePoint3d& ptInt)
{
if (pLn == NULL && pArc == NULL)
return false;
AcGePoint3dArray arPts;
pLn->intersectWith(pArc,AcDb::kOnBothOperands,arPts);
if (!arPts.isEmpty())
{
ptInt = arPts.first();
//L边
double dL1 = ptInt.distanceTo(pLn->startPoint());
double dL2 = ptInt.distanceTo(pLn->endPoint());
if ( (dL1 - dL2) > 1.e-6) // sta+int
{
el1.ptGe[0] = pLn->startPoint();
el1.ptGe[1] = ptInt;
el1.ptGe[2] = ptInt;
}
else//end + int
{
el1.ptGe[0] = ptInt;
el1.ptGe[1] = pLn->endPoint();
el1.ptGe[2] = pLn->endPoint();
}
//ARC
AcGePoint3d ptSta,ptEnd,ptMid,ptMidL;
pArc->getStartPoint(ptSta);
pArc->getEndPoint(ptEnd);
dL1 = ptInt.distanceTo(ptSta);
dL2 = ptInt.distanceTo(ptEnd);
if ( (dL1 - dL2) > 1.e-6) // sta+int
{
//Sta-Int 之间Mid
ptMidL = MidPoint(ptSta,ptInt);
pArc->getClosestPointTo(ptMidL,ptMid);
el2.ptGe[0] = ptSta;
el2.ptGe[1] = ptMid;
el2.ptGe[2] = ptInt;
}
else//end + int
{
//End-Int 之间Mid
ptMidL = MidPoint(ptEnd,ptInt);
pArc->getClosestPointTo(ptMidL,ptMid);
el2.ptGe[0] = ptInt;
el2.ptGe[1] = ptMid;
el2.ptGe[2] = ptEnd;
}
return true;
}
else
{
pLn->intersectWith(pArc,AcDb::kExtendBoth,arPts);
if (!arPts.isEmpty())
{
AcGePoint3d ptSta,ptEnd,ptMid,ptMidL,ptT,ptInt;
double dPa = 0.0;
//取距离Arc最近的点
pArc->getStartPoint(ptSta);
pArc->getEndPoint(ptEnd);
BOOL bFind = FALSE;
double dL1 = 0.0,dL2 = 0.0,dMin = 9999999.0,dTmp = 0.0;
for (int i = 0;i < arPts.length();i++)
{
ptT = arPts.at(i);
dL1 = ptT.distanceTo(ptSta);
dL2 = ptT.distanceTo(ptEnd);
dTmp = __min(dL1,dL2);
if ( (dTmp - dMin) < 1.e-6)
{
ptInt = ptT;
dMin = dTmp;
bFind = TRUE;
}
else//>
{
//...
}
}
if (bFind)
{
//TEST
//AcDbCircle* pCir = new AcDbCircle;
//pCir->setCenter(ptInt);
//pCir->setRadius(10.0);
//pCir->setColorIndex(1);
//AddToModelSpace(pCir);
//L
dL1 = ptInt.distanceTo(pLn->startPoint());
dL2 = ptInt.distanceTo(pLn->endPoint());
if ( (dL1 - dL2) > 1.e-6) // sta+int
{
el1.ptGe[0] = pLn->startPoint();
el1.ptGe[1] = ptInt;
el1.ptGe[2] = ptInt;
}
else//end + int
{
el1.ptGe[0] = ptInt;
el1.ptGe[1] = pLn->endPoint();
el1.ptGe[2] = pLn->endPoint();
}
//ARC
//如果ptInt在Arc上
if ( Acad::eOk == pArc->getParamAtPoint(ptInt,dPa) )
{
pArc->getStartPoint(ptSta);
pArc->getEndPoint(ptEnd);
dL1 = ptInt.distanceTo(ptSta);
dL2 = ptInt.distanceTo(ptEnd);
if ( (dL1 - dL2) > 1.e-6) // sta+int
{
//Sta-Int 之间Mid
ptMidL = MidPoint(ptSta,ptInt);
pArc->getClosestPointTo(ptMidL,ptMid);
el2.ptGe[0] = ptSta;
el2.ptGe[1] = ptMid;
el2.ptGe[2] = ptInt;
}
else//end + int
{
//End-Int 之间Mid
ptMidL = MidPoint(ptEnd,ptInt);
pArc->getClosestPointTo(ptMidL,ptMid);
el2.ptGe[0] = ptInt;
el2.ptGe[1] = ptMid;
el2.ptGe[2] = ptEnd;
}
}
else
{
pArc->getStartPoint(ptSta);
pArc->getEndPoint(ptEnd);
dL1 = ptInt.distanceTo(ptSta);
dL2 = ptInt.distanceTo(ptEnd);
if ( (dL1 - dL2) > 1.e-6) // 距离end近
{
el2.ptGe[0] = ptSta;
el2.ptGe[1] = ptEnd;
el2.ptGe[2] = ptInt;
}
else//距离sta近
{
el2.ptGe[0] = ptInt;
el2.ptGe[1] = ptSta;
el2.ptGe[2] = ptEnd;
}
}
return true;
}
}
else
{
//没有交点,圆弧切线法
//...
}
}
return false;
}
bool AecWall2DJoin::TrimCurveElement(IdAngleEl& ael1,IdAngleEl& ael2,AcGePoint3d& ptInt)
{
if (ael2.id == ael1.id)
return false;
int nType1 = AecComplexCurve::GetElementType(ael1.el);
int nType2 = AecComplexCurve::GetElementType(ael2.el);
if ( nType1 == AecEqui::eLine && nType2 == AecEqui::eLine)
{
AcDbLine* pLn1 = NULL;
AcDbLine* pLn2 = NULL;
AecComplexCurve::MakeLine(ael1.el,pLn1);
AecComplexCurve::MakeLine(ael2.el,pLn2);
if (pLn1 != NULL && pLn2 != NULL)
{
pLn1->setColorIndex(1);
pLn2->setColorIndex(2);
//TEST
//AddToModelSpace(pLnL);
//AddToModelSpace(pLnR);
//return;
AcGePoint3dArray arPts;
pLn2->intersectWith(pLn1,AcDb::kExtendBoth,arPts);
if (arPts.length() == 1)
{
ptInt = arPts.first();
//原则:
//依此点,取最长长度为新元素的长度
//2边
double dL1 = ptInt.distanceTo(pLn2->startPoint());
double dL2 = ptInt.distanceTo(pLn2->endPoint());
if ( (dL1 - dL2) > 1.e-6) // sta+int
{
ael2.el.ptGe[0] = pLn2->startPoint();
ael2.el.ptGe[1] = ptInt;
ael2.el.ptGe[2] = ptInt;
}
else//end + int
{
ael2.el.ptGe[0] = ptInt;
ael2.el.ptGe[1] = pLn2->endPoint();
ael2.el.ptGe[2] = pLn2->endPoint();
}
//1边
dL1 = ptInt.distanceTo(pLn1->startPoint());
dL2 = ptInt.distanceTo(pLn1->endPoint());
if ( (dL1 - dL2) > 1.e-6) // sta+int
{
ael1.el.ptGe[0] = pLn1->startPoint();
ael1.el.ptGe[1] = ptInt;
ael1.el.ptGe[2] = ptInt;
}
else//end + int
{
ael1.el.ptGe[0] = ptInt;
ael1.el.ptGe[1] = pLn1->endPoint();
ael1.el.ptGe[2] = pLn1->endPoint();
}
}
else
{
//平行的情况
//不会有两点
AcGeVector3d vt1 = ael1.el.ptGe[1] - ael1.el.ptGe[0];
AcGeVector3d vt2 = ael2.el.ptGe[1] - ael2.el.ptGe[0];
if (vt1.isParallelTo(vt2))
{
AcGePoint3dArray arPts;
arPts.append(ael1.el.ptGe[0]);
arPts.append(ael1.el.ptGe[1]);
arPts.append(ael2.el.ptGe[0]);
arPts.append(ael2.el.ptGe[1]);
AecCoverBooleanOper::SortPoints(arPts,pLn1,false);
//判断是否共线
vt1 = ael1.el.ptGe[1] - ael2.el.ptGe[0];
vt2 = ael2.el.ptGe[1] - ael1.el.ptGe[0];
if (!vt1.isParallelTo(vt2))
{
ael1.bIsOverParallel = true;
ael2.bIsOverParallel = true;
}
if (arPts.length() == 4)
{
ptInt = MidPoint(arPts.at(1),arPts.at(2));
delete pLn1;
delete pLn2;
return true;
}
}
delete pLn1;
delete pLn2;
return false;
}
delete pLn1;
delete pLn2;
return true;
}
}
else
{
AcDbCurve* pCurve1 = NULL;
AcDbCurve* pCurve2 = NULL;
AecComplexCurve::MakeCurve(ael1.el,pCurve1);
AecComplexCurve::MakeCurve(ael2.el,pCurve2);
pCurve1->setColorIndex(1);
pCurve2->setColorIndex(2);
//TEST
//AddToModelSpace(pCurve1);
//AddToModelSpace(pCurve2);
//return;
//圆弧,取末点的切线相交
bool bSuccess = false;
if (nType1 == AecEqui::eLine && nType2 == AecEqui::eArc)
{
AcDbLine* pLn1 = AcDbLine::cast(pCurve1);
AcDbArc* pArc2 = AcDbArc::cast(pCurve2);
bSuccess = TrimLineArcElement(pLn1,ael1.el,pArc2,ael2.el,ptInt);
}
if (nType1 == AecEqui::eArc && nType2 == AecEqui::eLine)
{
AcDbArc* pArc1 = AcDbArc::cast(pCurve1);
AcDbLine* pLn2 = AcDbLine::cast(pCurve2);
bSuccess = TrimLineArcElement(pLn2,ael2.el,pArc1,ael1.el,ptInt);
}
delete pCurve1;
delete pCurve2;
return bSuccess;
}
return false;
}
bool SortWallEndByParam(WallEnd& we1,WallEnd& we2)
{
if ( (we1.dParamOnM - we2.dParamOnM) < 1.e-6 )
return true;
return false;
}
void GetNearIntPointTo(AcDbCurve* pArcR,AcDbCurve* pArcE,const AcGePoint3d& ptEnd,AcGePoint3d& ptInt)
{
if (pArcE == NULL || pArcR == NULL)
return;
AcGePoint3dArray arPts;
pArcR->intersectWith(pArcE,AcDb::kExtendBoth,arPts);
double dDis = 0.0,dMin = 9999999.0;
AcGePoint3d ptT;
for (int i = 0;i < arPts.length();i++)
{
ptT = arPts.at(i);
dDis = ptT.distanceTo(ptEnd);
if (dDis < dMin)
{
dMin = dDis;
ptInt = ptT;
}
}
}
void AecWall2DJoin::GetBreakPoint(AcDbCurve* pCurE,AcDbCurve* pCutTo,AcGePoint3d& ptEnd,AecEqui::AecCurveElement& el,const AcGeVector3d& vtEnd,double dThick)
{
//------------------------------- --> CutTo Line or Arc
// el
//------------+----+-------------
//
// / +E /
// / /
// / /
// / / ->CurE Line or Arc
//
if (pCutTo == NULL)
return;
AcDbLine* pLineE = AcDbLine::cast(pCurE);// E 线是直线
if (pLineE != NULL)// E 线是直线
{
AcDbArc* pArc = AcDbArc::cast(pCutTo);//主线是圆弧
if (pArc != NULL)
{
//E线是直线vtEnd
AcGeVector3d vtDir = vtEnd;
vtDir.rotateBy(PI/2.0,AcGeVector3d::kZAxis);
vtDir.normalize();
AcGePoint3d pt1 = ptEnd - vtDir * 0.5 * dThick;
AcGePoint3d pt2 = ptEnd + vtDir * 0.5 * dThick;
pCutTo->getClosestPointTo(pt1,vtEnd,el.ptGe[0]);
pCutTo->getClosestPointTo(pt2,vtEnd,el.ptGe[2]);
return;
}
AcDbLine* pLine = AcDbLine::cast(pCutTo);//主线是直线
if (pLine != NULL)//主线是直线
{
//E线是直线vtEnd
AcGeVector3d vtDir = vtEnd;
vtDir.normalize();
vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGePoint3d pt1 = ptEnd - vtDir * 0.5 * dThick;
AcGePoint3d pt2 = ptEnd + vtDir * 0.5 * dThick;
pCutTo->getClosestPointTo(pt1,vtEnd,el.ptGe[0]);
pCutTo->getClosestPointTo(pt2,vtEnd,el.ptGe[1]);
}
return;
}
AcDbArc* pArcE = AcDbArc::cast(pCurE);// E 线是圆弧
if (pArcE != NULL)
{
AcDbArc* pArc = AcDbArc::cast(pCutTo);//主线是圆弧
if (pArc != NULL)
{
//E 线是圆弧
double dRad = pArcE->radius();
double dR = dRad + 0.5 * dThick;
double dr = dRad - 0.5 * dThick;
AcDbArc* pArcR = (AcDbArc*)pArcE->clone();
pArcR->setRadius(dR);
AcDbArc* pArcr = (AcDbArc*)pArcE->clone();
pArcr->setRadius(dr);
GetNearIntPointTo(pArcR,pArc,ptEnd,el.ptGe[0]);
GetNearIntPointTo(pArcr,pArc,ptEnd,el.ptGe[2]);
delete pArcR;delete pArcr;
}
AcDbLine* pLine = AcDbLine::cast(pCutTo);//主线是直线
if (pLine != NULL)//主线是直线
{
//E 线是圆弧
double dRad = pArcE->radius();
double dR = dRad + 0.5 * dThick;
double dr = dRad - 0.5 * dThick;
AcDbArc* pArcR = (AcDbArc*)pArcE->clone();
pArcR->setRadius(dR);
AcDbArc* pArcr = (AcDbArc*)pArcE->clone();
pArcr->setRadius(dr);
GetNearIntPointTo(pArcR,pLine,ptEnd,el.ptGe[0]);
GetNearIntPointTo(pArcr,pLine,ptEnd,el.ptGe[1]);
delete pArcR;delete pArcr;
//TEST
//pArcR->setColorIndex(1);
//pArcr->setColorIndex(2);
//AddToModelSpace(pArcR);
//AddToModelSpace(pArcr);
}
return;
}
}
int AecWall2DJoin::GetNearSideTo(AcDbCurve* pCurE,AcGePoint3d& ptEnd,const AcGeVector3d& vtEnd,AcDbCurve* pCurM,AcDbCurve* pLeft,AcDbCurve* pRight,double dThick)
{
int nNearSide = 0;
AcGePoint3d ptS,ptE,ptT;
pCurE->getStartPoint(ptS);
pCurE->getEndPoint(ptE);
//取远端
double dL1 = ptS.distanceTo(ptEnd);
double dL2 = ptE.distanceTo(ptEnd);
double dMin = 0.0;
if (dL1 < dL2)
{
ptT = ptE;
}
else
{
ptT = ptS;
}
AcGePoint3d ptOn;
pCurM->getClosestPointTo(ptEnd,vtEnd,ptOn,Adesk::kTrue);
//圆弧的getClosestPointTo(ptEnd,vtEnd,ptOn,Adesk::kTrue); 错误!!.ARX接口问题
AcDbArc *pArc = AcDbArc::cast(pCurM);
if (pArc != NULL)
{
pCurM->getClosestPointTo(ptEnd, vtEnd, ptOn, Adesk::kFalse);
}
dMin = ptOn.distanceTo(ptEnd);
if ( ( dMin - 1.5 * dThick) > 1.e-6)
{
//acutPrintf(_T("\nNear side Len = %g"),dMin);
return nNearSide;
}
AcDbLine ln;
ln.setStartPoint(ptT);
ln.setEndPoint(ptOn);
AcGePoint3dArray arPtsL;
ln.intersectWith(pLeft,AcDb::kOnBothOperands,arPtsL);
if (!arPtsL.isEmpty())
{
return -1;
}
AcGePoint3dArray arPtsR;
ln.intersectWith(pRight,AcDb::kOnBothOperands,arPtsR);
if (!arPtsR.isEmpty())
{
return 1;
}
return nNearSide;
}
void AecWall2DJoin::TJoinSortAndTrimByMain(const WallTJoin& wt)
{
//先按.wes 的param排序
if (wt.nValid > 0)
{
std::vector<WallEnd> vtWEs;
for (int i = 0;i < wt.nValid;i++)
{
vtWEs.push_back(wt.wes[i]);
}
std::sort(vtWEs.begin(),vtWEs.end(),SortWallEndByParam);
AecComplexCurve cmplL;
AecComplexCurve cmplR;
AecComplexCurve cmplT;
//主墙体不裁剪,采用隐藏的方式绘制
AcDbEntity* pEntM = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEntM,wt.idMain,AcDb::kForRead))
{
AecDbXWall* pWallM = AecDbXWall::cast(pEntM);
if (pWallM != NULL)
{
AcDbCurve* pLeft = pWallM->GetLeftCurve();
AcDbCurve* pRight = pWallM->GetRightCurve();
AcDbCurve* pCurM = GetWallBaseCurve(pWallM);
if (pLeft == NULL || pRight == NULL || pCurM == NULL)
{
pEntM->close();
return;
}
//关闭主体墙
pEntM->close();
pEntM = NULL;
pWallM = NULL;
WallXJoin xj;
AcGeVector3d vtT,vt1,vt2;
WallData data;
AcGePoint3d ptOn1,ptOn2,ptS,ptE,ptCen,ptMid,ptTmp;
AcDbEntity* pEntE = NULL;
double dDistL = 0.0,dDistR = 0.0;
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
AecEqui::AecCurveElement elT;
memset(&elT,0,sizeof(AecEqui::AecCurveElement));
for (int i = 0;i < vtWEs.size();i++)
{
WallEnd we = vtWEs.at(i);
if (we.idCol.isValid())//延伸到柱子即可
{
xj.idCol = we.idCol;
xj.nValid = 1;
xj.ids[0] = we.id;
xj.ptJoin = we.ptEnd;
ExtendToColumnRegion(xj);
}
else//提取墙体的左右侧
{
Acad::ErrorStatus es;
if ( Acad::eOk == (es = acdbOpenAcDbEntity(pEntE,we.id,AcDb::kForRead)))//forWrite
{
AecDbXWall* pWallE = AecDbXWall::cast(pEntE);
if (pWallE != NULL)
{
pWallE->GetWallData(data);
ptS = GetWallStartPoint(pWallE);
ptE = GetWallEndPoint(pWallE);
AcDbCurve* pCurE = GetWallBaseCurve(pWallE);
pLeft->getClosestPointTo(we.ptEnd,we.vtEnd,ptOn1);
pRight->getClosestPointTo(we.ptEnd,we.vtEnd,ptOn2);
vt1 = we.ptEnd - ptOn1;
vt2 = we.ptEnd - ptOn2;
dDistL = vt1.length();
dDistR = vt2.length();
int nNearSide = GetNearSideTo(pCurE,we.ptEnd,we.vtEnd,pCurM,pLeft,pRight,data.dThick);
if (nNearSide == -1)//靠近左侧
{
AcDbLine* pLnM = AcDbLine::cast(pLeft);
if (pLnM != NULL)
{
vtT = pLnM->endPoint() - pLnM->startPoint();
vtT.normalize();
GetBreakPoint(pCurE,pLeft,we.ptEnd,el,we.vtEnd,we.dThick);
//el.ptGe[0] = ptOn1 - vtT * 0.5 * data.dThick;
//el.ptGe[1] = ptOn1 + vtT * 0.5 * data.dThick;
el.ptGe[2] = el.ptGe[1];
el.gsMark = MaterialWeight(data.szMat);
//材质相同,方可裁剪主墙
if (el.gsMark == wt.nWallWeight)
cmplL.append(el);
}
AcDbArc* pArc = AcDbArc::cast(pLeft);
if (pArc != NULL)//待定
{
//两点定玄,
//el.ptGe[0] = ptOn1 - vtT * 0.5 * data.dThick;
//el.ptGe[2] = ptOn1 + vtT * 0.5 * data.dThick;
GetBreakPoint(pCurE,pLeft,we.ptEnd,el,we.vtEnd,we.dThick);
ptTmp = MidPoint(el.ptGe[0],el.ptGe[2]);
pArc->getClosestPointTo(ptTmp,ptMid);
el.ptGe[1] = ptMid;
el.gsMark = MaterialWeight(data.szMat);
//材质相同,方可裁剪主墙
if (el.gsMark == wt.nWallWeight)
cmplL.append(el);
}
}
else if (nNearSide == 1)//靠近右侧
{
AcDbLine* pLnM = AcDbLine::cast(pRight);
if (pLnM != NULL)
{
vtT = pLnM->endPoint() - pLnM->startPoint();
vtT.normalize();
//el.ptGe[0] = ptOn2 - vtT * 0.5 * data.dThick;
//el.ptGe[1] = ptOn2 + vtT * 0.5 * data.dThick;
GetBreakPoint(pCurE,pRight,we.ptEnd,el,we.vtEnd,we.dThick);
el.ptGe[2] = el.ptGe[1];
el.gsMark = MaterialWeight(data.szMat);
//材质相同,方可裁剪主墙
if (el.gsMark == wt.nWallWeight)
cmplR.append(el);
}
AcDbArc* pArc = AcDbArc::cast(pRight);
if (pArc != NULL)//待定
{
//两点定玄,
//el.ptGe[0] = ptOn1 - vtT * 0.5 * data.dThick;
//el.ptGe[2] = ptOn1 + vtT * 0.5 * data.dThick;
GetBreakPoint(pCurE,pRight,we.ptEnd,el,we.vtEnd,we.dThick);
ptTmp = MidPoint(el.ptGe[0],el.ptGe[2]);
pArc->getClosestPointTo(ptTmp,ptMid);
el.ptGe[1] = ptMid;
el.gsMark = MaterialWeight(data.szMat);
//材质相同,方可裁剪主墙
if (el.gsMark == wt.nWallWeight)
cmplR.append(el);
}
}
else
{
//...
}
Adesk::Boolean bExtendSta = true;
double dDistE = ptE.distanceTo(we.ptEnd);
double dDistS = ptS.distanceTo(we.ptEnd);
if (dDistE < dDistS)
bExtendSta = false;
if (nNearSide == -1)//靠主墙左侧
{
//Extend(pWallE,bExtendSta,ptOn1);
//pWallE->GetStandardDraw2d();
//pWallE->RemoveTailDraw2d(ptOn1);
//TrimEnd(pWallE,el,we.vtEnd);
AppendExtend(we.id,bExtendSta,ptOn1,el,we.vtEnd, nNearSide, wt.idMain);
}
else if (nNearSide == 1)//靠主墙右侧
{
//Extend(pWallE,bExtendSta,ptOn2);
//pWallE->GetStandardDraw2d();
//pWallE->RemoveTailDraw2d(ptOn2);
//TrimEnd(pWallE,el,we.vtEnd);
AppendExtend(we.id,bExtendSta,ptOn2,el,we.vtEnd, nNearSide, wt.idMain);
}
}
pEntE->close();
}
}
}
if (pLeft != NULL || pRight != NULL)
{
delete pLeft;pLeft = NULL;
delete pRight;pRight = NULL;
}
//再次打开主体修改
if ( Acad::eOk == acdbOpenAcDbEntity(pEntM,wt.idMain,AcDb::kForWrite))
{
AecDbXWall* pWallM = AecDbXWall::cast(pEntM);
if (pWallM != NULL)
{
//进行类似遮挡处理
AecComplexCurve draw2d;
pWallM->GetDraw2dables(draw2d);
draw2d.setSubElementGsMark(wt.nWallWeight);
//柱子裁剪墙体的左右侧 考虑墙体的轻重
AecCoverBooleanOper::BoolSubtract(draw2d,cmplL);
AecCoverBooleanOper::BoolSubtract(draw2d,cmplR);
pWallM->SetDraw2dables(draw2d);
}
pEntM->close();
pEntM = NULL;
}
}
//确认关闭
if (pEntM != NULL) pEntM->close();
}
}
}
void AecWall2DJoin::AppendExtend(const AcDbObjectId& id,Adesk::Boolean bExtendSta,const AcGePoint3d& ptOn,AecEqui::AecCurveElement& el,const AcGeVector3d& vtEnd,int nNearSide, const AcDbObjectId& idMain)
{
for (int i = 0;i < m_arWallExtends.length();i++)
{
WallExtend& exd = m_arWallExtends.at(i);
if (exd.idWall == id && exd.nEnds < 2)//1.找到
{
exd.bExtendSta[exd.nEnds] = bExtendSta;
memcpy(&exd.el[exd.nEnds],&el,sizeof(AecEqui::AecCurveElement));
exd.ptOn[exd.nEnds] = ptOn;
exd.vtEnd[exd.nEnds] = vtEnd;
exd.nEnds += 1;
return;
}
}
//2.未找到,添加
WallExtend ext;
ext.idWall = id;
ext.idMain = idMain;
ext.nNearSide = nNearSide;
ext.nEnds = 1;
ext.bExtendSta[0] = bExtendSta;
memcpy(&ext.el[0],&el,sizeof(AecEqui::AecCurveElement));
ext.ptOn[0] = ptOn;
ext.vtEnd[0] = vtEnd;
m_arWallExtends.append(ext);
}
AcGePoint3d AecWall2DJoin::GetWallStartPoint(AecDbXWall* pWall) const
{
AcGePoint3d ptSta = AcGePoint3d::kOrigin;
if (pWall != NULL)
{
if (pWall->IsVViewWall())
{
AcDbCurve* pCurve = pWall->GetAsNativeCurveOfVView();
if (pCurve != NULL)
{
pCurve->getStartPoint(ptSta);
delete pCurve;
}
}
else
{
pWall->getStartPoint(ptSta);
}
}
return ptSta;
}
AcGePoint3d AecWall2DJoin::GetWallEndPoint(AecDbXWall* pWall) const
{
AcGePoint3d ptEnd = AcGePoint3d::kOrigin;
if (pWall != NULL)
{
if (pWall->IsVViewWall())
{
AcDbCurve* pCurve = pWall->GetAsNativeCurveOfVView();
if (pCurve != NULL)
{
pCurve->getEndPoint(ptEnd);
delete pCurve;
}
}
else
{
pWall->GetNativeCurve()->getEndPoint(ptEnd);
}
}
return ptEnd;
}
AcGeVector3d AecWall2DJoin::GetWallFirstDeriv(AecDbXWall* pWall,const AcGePoint3d& ptGeOn) const
{
AcGeVector3d vtDir(0,0,0);
if (pWall != NULL)
{
if (pWall->IsVViewWall())
{
AcDbCurve* pCurve = pWall->GetAsNativeCurveOfVView();
if (pCurve != NULL)
{
pCurve->getFirstDeriv(ptGeOn,vtDir);
delete pCurve;
}
}
else
{
pWall->getFirstDeriv(ptGeOn,vtDir);
//TEST
vtDir.normalize();
AcGePoint3d ptEnd = ptGeOn;
ptEnd += 10.0 * vtDir;
AcDbLine* pLnt = new AcDbLine;
pLnt->setStartPoint(ptGeOn);
pLnt->setEndPoint(ptEnd);
pLnt->setColorIndex(1);
m_arTestEntPtrs.append(pLnt);
}
}
return vtDir;
}
Acad::ErrorStatus AecWall2DJoin::Extend(AecDbXWall*pWall,Adesk::Boolean extendStart,const AcGePoint3d& toPoint,AcGeVector3d& vtEnd,AcDbObjectId& idMain, int nNearSide)
{
Acad::ErrorStatus es = Acad::eOk;
if (pWall->IsVViewWall())
{
//?
}
else
{
AcGePoint3d ptE;
if (extendStart)
pWall->getStartPoint(ptE);
else
pWall->getEndPoint(ptE);
AcGePoint3d ptOn;
es = pWall->getClosestPointTo(toPoint,ptOn,Adesk::kTrue);
pWall->RemoveTailDraw2d(ptE);
AcDbCurve* pCrv = pWall->GetNativeCurve();
//T分支延伸到主墙
es = pWall->extend(extendStart,ptOn);
//T分两侧边线延伸到主墙的边线
AecComplexCurve draw2d;
pWall->GetDraw2dables(draw2d);
AcGeVector3d vtTan;
AcDbEntity *pEntM = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEntM, idMain, AcDb::kForRead))
{
AecDbXWall *pWallM = AecDbXWall::cast(pEntM);
if (pWallM != NULL)
{
AcDbCurve *pCurve = NULL;
if ( nNearSide == -1)
pCurve = pWallM->GetLeftCurve();
else
pCurve = pWallM->GetRightCurve();
pCurve->getFirstDeriv(toPoint, vtTan);
if (vtTan.isPerpendicularTo(vtEnd))
{
//垂直不需要裁剪和延伸 T
}
else
{
//需要处理两侧 7
AecEqui::AecCurveElement el;
memset(&el, 0, sizeof(AecEqui::AecCurveElement));
pWall->GetTailDraw2d(ptOn, el);
//找到两侧最近的el
int nGsMk = 0;
AcArray<AecEqui::AecCurveElement> arExEl;
for (int i = 0;i < draw2d.length();i++)
{
AecEqui::AecCurveElement &elT = draw2d.atByRef(i);
if (el.ptGe[0].distanceTo(elT.ptGe[0]) < 1.e-2 ||
el.ptGe[0].distanceTo(elT.ptGe[2]) < 1.e-2)
{
nGsMk = elT.gsMark;
elT.gsMark = i;
arExEl.append(elT);
elT.gsMark = nGsMk;
continue;
}
if (el.ptGe[1].distanceTo(elT.ptGe[0]) < 1.e-2 ||
el.ptGe[1].distanceTo(elT.ptGe[2]) < 1.e-2)
{
nGsMk = elT.gsMark;
elT.gsMark = i;
arExEl.append(elT);
elT.gsMark = nGsMk;
}
}
//两边线
AcGePoint3dArray arPts;
for (int j = 0;j < arExEl.length();j++)
{
AecEqui::AecCurveElement &elE = arExEl.at(j);
AcDbCurve *pCrvE = NULL;
AecComplexCurve::MakeCurve(elE, pCrvE);
arPts.removeAll();
pCrvE->intersectWith(pCurve, AcDb::kOnBothOperands, arPts);
if (arPts.length() == 1)//相交裁剪
{
//
AcGeVector3d vt = elE.ptGe[0] - arPts.first();
if (vt.isCodirectionalTo(vtEnd))
{
elE.ptGe[0] = arPts.first();
}
vt = elE.ptGe[2] - arPts.first();
if (vt.isCodirectionalTo(vtEnd))
{
elE.ptGe[2] = arPts.first();
AcDbLine *pLn = AcDbLine::cast(pCrvE);
if (pLn != NULL)
{
elE.ptGe[1] = arPts.first();
}
}
AecEqui::AecCurveElement& elT = draw2d.atByRef(elE.gsMark);
memcpy(elT.ptGe, elE.ptGe, sizeof(AcGePoint3d) * 3);
draw2d.setAt(elE.gsMark, elT);
}
else//不相交,延长
{
pCrvE->intersectWith(pCurve, AcDb::kExtendThis, arPts);
if (arPts.length() == 1)
{
//取最近 arPts.first();
double dL1 = elE.ptGe[0].distanceTo(arPts.first());
double dL2 = elE.ptGe[2].distanceTo(arPts.first());
if (dL1 < dL2)
{
elE.ptGe[0] = arPts.first();
}
else
{
elE.ptGe[2] = arPts.first();
AcDbLine *pLn = AcDbLine::cast(pCrvE);
if (pLn != NULL)
{
elE.ptGe[1] = arPts.first();
}
}
AecEqui::AecCurveElement &elT = draw2d.atByRef(elE.gsMark);
memcpy(elT.ptGe, elE.ptGe, sizeof(AcGePoint3d) * 3);
draw2d.setAt(elE.gsMark, elT);
}
}
delete pCrvE;
}
pWall->SetDraw2dables(draw2d);
}
delete pCurve;
}
pEntM->close();
}
}
return es;
}
int FindNearPoint(const AcGePoint3d& pt,AecEqui::AecCurveElement& eT,AcGePoint3d& ptNear,const AcGeVector3d& vtEnd)
{
AcDbCurve* pCurve = NULL;
AecComplexCurve::MakeCurve(eT,pCurve);
if (pCurve == NULL)
return 0;
AcGePoint3d ptOn;
pCurve->getClosestPointTo(pt,ptOn,Adesk::kTrue);
if (pt.distanceTo(ptOn) - 10.0 > 1.e-3)
return 0;
double dPa = 0.0,dS = 0.0,dE = 0.0;
Acad::ErrorStatus es = pCurve->getParamAtPoint(ptOn,dPa);
if (es == Acad::eOk)
{
//落在上面
AcGePoint3d ptS,ptE;
pCurve->getStartPoint(ptS);
pCurve->getEndPoint(ptE);
dS = ptS.distanceTo(ptOn);
dE = ptE.distanceTo(ptOn);
if (dS < dE)//靠近Start端
{
ptNear = ptS;
}
else
{
ptNear = ptE;
}
AcGeVector3d vtF;
pCurve->getFirstDeriv(ptNear,vtF);
if (vtF.isParallelTo(vtEnd))
{
delete pCurve;
return 1;
}
}
else
{
//不落在上面
pCurve->getClosestPointTo(pt,ptOn,Adesk::kFalse);
AcGeVector3d vtF;
pCurve->getFirstDeriv(ptOn,vtF);
if (vtF.isParallelTo(vtEnd))
{
ptNear = ptOn;
delete pCurve;
return 2;
}
}
delete pCurve;
return 0;
}
void CopyElementSeg(AecEqui::AecCurveElement& eT,AcGePoint3d& pt,AcGePoint3d& ptNear,AecEqui::AecCurveElement& elNew)
{
//
AcDbCurve* pCurve = NULL;
AecComplexCurve::MakeCurve(eT,pCurve);
if (pCurve == NULL)
return;
AcDbLine* pLn = AcDbLine::cast(pCurve);
if (pLn != NULL)
{
elNew.ptGe[0] = pt;
elNew.ptGe[1] = ptNear;
elNew.ptGe[2] = ptNear;
}
AcDbArc* pArc = AcDbArc::cast(pCurve);
if (pArc != NULL)
{
elNew.ptGe[0] = pt;
elNew.ptGe[2] = ptNear;
elNew.ptGe[1] = MidPoint(pt,ptNear);
AcDbCircle cir;
cir.setCenter(pArc->center());
cir.setRadius(pArc->radius());
cir.setNormal(AcGeVector3d::kZAxis);
AcGePoint3d ptMid;
cir.getClosestPointTo(elNew.ptGe[1],ptMid);
elNew.ptGe[1] = ptMid;
}
delete pCurve;
}
Acad::ErrorStatus AecWall2DJoin::TrimEnd(AecDbXWall* pWallE,AecEqui::AecCurveElement& el,const AcGeVector3d& vtEnd)
{
AecComplexCurve draw2d;
pWallE->GetDraw2dables(draw2d);
AcGePoint3dArray arPts;
arPts.append(el.ptGe[0]);
if (arPts.find(el.ptGe[1]) == -1)
arPts.append(el.ptGe[1]);
AcGePoint3d ptTo;
int nOnType = 0;
AecEqui::AecCurveElement elSub,elAdd0,elAdd2;
memset(&elSub,0,sizeof(AecEqui::AecCurveElement));
memset(&elAdd0,0,sizeof(AecEqui::AecCurveElement));
memset(&elAdd2,0,sizeof(AecEqui::AecCurveElement));
AecComplexCurve cmSub,cmAdd;
double dDisMin0 = 999999999.0,dDisMin2 = 999999999.0;
double dDis0 = 0.0,dDis2 = 0.0;
AcGePoint3d ptTo0,ptTo2;
AcGePoint3dArray arPt0,arPt2;
AecEqui::AecCurveElement eT0,eT2;
for (int i = 0;i < draw2d.length();i++)
{
AecEqui::AecCurveElement& eT = draw2d.atByRef(i);
//找距离el的两端最近的点,如果在元素eT上,则取两端最近的点,返回实减
//找距离el的两端最近的点,如果不在元素eT上,则取两端最近的点返回实加
nOnType = FindNearPoint(el.ptGe[0],eT,ptTo,vtEnd);
if (nOnType == 1)//落在上面,返回点为最近的端点
{
CopyElementSeg(eT,el.ptGe[0],ptTo,elSub);
cmSub.append(elSub);
}
if (nOnType == 2)//落在延长线上
{
dDis0 = ptTo.distanceTo(el.ptGe[0]);
if (dDis0 < dDisMin0)
{
dDisMin0 = dDis0;
ptTo0 = ptTo;
arPt0.removeAll();
arPt0.append(ptTo0);
eT0 = eT;
}
}
nOnType = FindNearPoint(el.ptGe[2],eT,ptTo,vtEnd);
if (nOnType == 1)//落在上面,返回点为最近的端点
{
CopyElementSeg(eT,el.ptGe[2],ptTo,elSub);
cmSub.append(elSub);
}
if (nOnType == 2)//落在延长线上
{
dDis2 = ptTo.distanceTo(el.ptGe[2]);
if (dDis2 < dDisMin2)
{
dDisMin2 = dDis2;
ptTo2 = ptTo;
arPt2.removeAll();
arPt2.append(ptTo2);
eT2 = eT;
}
}
}
if (!arPt0.isEmpty())
{
CopyElementSeg(eT0,el.ptGe[0],arPt0.first(),elAdd0);
cmAdd.append(elAdd0);
}
if (!arPt2.isEmpty())
{
CopyElementSeg(eT2,el.ptGe[2],arPt2.first(),elAdd2);
cmAdd.append(elAdd2);
}
AecCoverBooleanOper::BoolSubtract(draw2d,cmSub);
//没有交集加入
if (!AecCoverBooleanOper::HasIntersection(draw2d,cmAdd))
{
AecCoverBooleanOper::BoolUnite(draw2d,cmAdd);
}
if (!cmAdd.isEmpty() || !cmSub.isEmpty() )
{
pWallE->SetDraw2dables(draw2d);
}
return Acad::eOk;
}
void AecWall2DJoin::AddXPart(AecDbXWall* pWallE,const AcGePoint3d& ptEnd,const AcGeVector3d& vtEnd,Adesk::Boolean bExtendSta,const AecEqui::AecCurveElement& el)
{
if (pWallE == NULL)
return;
WallData data;
pWallE->GetWallData(data);
AcDbCurve* pCurveEl = NULL;
AecComplexCurve::MakeCurve((AecEqui::AecCurveElement&)el,pCurveEl);
if (pCurveEl != NULL)
{
AcGeVector3d vt = vtEnd;
vt.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vt.normalize();
AcGePoint3d pt1,pt2;
pt1 = ptEnd + vt * 0.5 * data.dThick;
pt2 = ptEnd - vt * 0.5 * data.dThick;
double dDis = data.dThick;
AecDbX3dPart* pPart = NULL;
AcDbX3dSolid* pXSolid = NULL;
if (!pWallE->IsVViewWall())
{
//常规截面墙体
vt = vtEnd;
vt.normalize();
AcDbLine lnPath;
pt1 = ptEnd;
pt2 = ptEnd + vt * dDis;
pt1.z = data.dBomEl;
pt2.z = data.dBomEl;
lnPath.setStartPoint(pt1);
lnPath.setEndPoint(pt2);
AcDbRegion* pRegion = pWallE->GetSection();
if (pRegion != NULL)
{
//1.创建整体Solid
AcGePoint3d ptOnRegion;
pWallE->GetSpecialtyData()->GetAt(KEY_SECCEN,ptOnRegion);
transfromRegion(pRegion,ptOnRegion,vt,pt1);
int nPos = pWallE->GetNearPosition(ptEnd);
pPart = new AecDbX3dPart;
pPart->SetName(_T("ExAdd"));
pPart->GetSpecialtyData()->SetAt(KEY_ADDTIONSHOW,TRUE);
pPart->GetSpecialtyData()->SetAt(KEY_POS,nPos);
pPart->GetSpecialtyData()->SetAt(KEY_FORSLICE,TRUE);
pXSolid = new AcDbX3dSolid;
if ( pXSolid->CreateExtrude(pRegion,lnPath) )
{
pPart->AddX3dSolid(pXSolid);
pPart->Create();
//pWallE->AddX3dPart(pPart,AcDb::kBoolUnite);//????
//TEST
/*AcDb3dSolid* pSolid = pXSolid->GetDraw3dSolid();
pSolid->setColorIndex(3);
AddToModelSpace(pSolid);
*/
}
else
{
delete pPart;
delete pXSolid;
}
delete pRegion;
}
}
else
{
//...是立面拉伸墙体
}
}
}
//获取统一的墙体基线,用完需要删除
AcDbCurve* AecWall2DJoin::GetWallBaseCurve(AecDbXWall* pWall)
{
AcDbObjectId id = pWall->objectId();
TCHAR tmpStr[256];
id.handle().getIntoAsciiBuffer(tmpStr);
AcDbCurve* pBaseCurve = NULL;
if (m_mapIdToPtr.Lookup(tmpStr,(void*&)pBaseCurve))
{
return pBaseCurve;
}
if (pWall->IsVViewWall())
{
pBaseCurve = pWall->GetAsNativeCurveOfVView();
}
else
{
pBaseCurve = pWall->GetBaseCurve();
}
m_mapIdToPtr.SetAt(tmpStr,(void*)pBaseCurve);
return pBaseCurve;
}
//最多20种由重到轻材质的比重
int AecWall2DJoin::MaterialWeight(LPCTSTR pszMaterial)
{
//最多20种由重到轻材质
static int nMaxWallWeight = 20;
for (int i = 0;i < 20;i++)
{
if (g_pszWallMaterials[i] == NULL)
return 0;
if (_tcscmp(g_pszWallMaterials[i], pszMaterial) == 0)
{
return (nMaxWallWeight - i);
}
}
return 0;
}