3394 lines
75 KiB
C++
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;
|
|
} |