513 lines
9.9 KiB
C++
513 lines
9.9 KiB
C++
#include "stdafx.h"
|
|
#include "TThunderSectionJig.h"
|
|
#include "dbsol3d.h"
|
|
|
|
#include <list>
|
|
#include <algorithm>
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
TThunderSectionJig::TThunderSectionJig(AecDbSymbSection* pSec)
|
|
{
|
|
m_pDrawEnt = pSec;
|
|
m_pVirDrawEnt = new TVirtualSection(pSec);
|
|
}
|
|
|
|
TThunderSectionJig::~TThunderSectionJig()
|
|
{
|
|
if (m_pVirDrawEnt)
|
|
{
|
|
delete m_pVirDrawEnt;
|
|
m_pVirDrawEnt = NULL;
|
|
}
|
|
}
|
|
|
|
// 开始执行拖动
|
|
int TThunderSectionJig::DoIt(int *keyIndex)
|
|
{
|
|
//保持当前捕捉
|
|
//XPushVar<int> osmode(_T("OSMODE"), 0);
|
|
|
|
if(m_nOperCode==kSectPoint || m_nOperCode==kViewDirection)
|
|
{
|
|
XPoly2D poly;
|
|
if (m_pDrawEnt != NULL)
|
|
{
|
|
m_pDrawEnt->GetPoly2D(poly);
|
|
if (poly.Length() >= 2)
|
|
{
|
|
m_ptResult=*poly.Tail();
|
|
}
|
|
}
|
|
}
|
|
|
|
int nRet = TSymbEdJigEx::DoIt(keyIndex);
|
|
|
|
return nRet;
|
|
}
|
|
|
|
AcEdJig::DragStatus TThunderSectionJig::GetPoint(XPoint &pt)
|
|
{
|
|
XPoint ptBase;
|
|
XPoly2D poly;
|
|
DragStatus stat;
|
|
m_pDrawEnt->GetPoly2D(poly);
|
|
if(m_nOperCode == kSectPoint)
|
|
{
|
|
ASSERT(poly.Length() == 2);
|
|
ptBase = *poly.Head();
|
|
stat = acquirePoint(pt, ptBase);
|
|
}
|
|
else
|
|
{
|
|
stat = acquirePoint(pt);
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
// 更新实体数据
|
|
Adesk::Boolean TThunderSectionJig::update()
|
|
{
|
|
if(m_nOperCode == TThunderSectionJig::kSectPoint)
|
|
{
|
|
XPoly2D poly;
|
|
m_pDrawEnt->GetPoly2D(poly);
|
|
if (poly.Length() == 2)
|
|
{
|
|
XPoint pt1 = *poly[0];
|
|
*poly[1] = m_ptResult;
|
|
|
|
double dViewDir = ads_angle(pt1, m_ptResult) - PI/2.0;
|
|
m_pDrawEnt->SetPoly2D(poly);
|
|
m_pDrawEnt->SetViewDirection(dViewDir);
|
|
m_pDrawEnt->SetTextLocation(0, m_pDrawEnt->GetDefaultTextLocation(0));
|
|
m_pDrawEnt->SetTextLocation(1, m_pDrawEnt->GetDefaultTextLocation(1));
|
|
}
|
|
}
|
|
else if(m_nOperCode == TThunderSectionJig::kViewDirection)
|
|
{
|
|
XPoly2D poly;
|
|
m_pDrawEnt->GetPoly2D(poly);
|
|
if (poly.Length() == 2)
|
|
{
|
|
XLine ln(*poly[0], *poly[1]);
|
|
|
|
int nSide=ln.OnWhichSide(m_ptResult);
|
|
double dAngle = 0.0;
|
|
if(nSide == OFFSET_LEFT)
|
|
{
|
|
dAngle = CT_std_angle(ln.Direction()+PI/2);
|
|
}
|
|
else
|
|
{
|
|
dAngle = CT_std_angle(ln.Direction()-PI/2);
|
|
}
|
|
|
|
m_pDrawEnt->SetViewDirection(dAngle);
|
|
m_pDrawEnt->SetTextLocation(0, m_pDrawEnt->GetDefaultTextLocation(0));
|
|
m_pDrawEnt->SetTextLocation(1, m_pDrawEnt->GetDefaultTextLocation(1));
|
|
|
|
if (m_pVirDrawEnt)
|
|
{
|
|
m_pVirDrawEnt->SetCurrentPos(m_ptResult);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcGePoint3d TThunderSectionJig::GetDirPosition()
|
|
{
|
|
return m_ptResult.AsAcGePoint3d();
|
|
}
|
|
|
|
AcDbEntity* TThunderSectionJig::entity() const
|
|
{
|
|
return (AcDbEntity*)m_pVirDrawEnt;
|
|
}
|
|
|
|
void TThunderSectionJig::SetOperCode(TSectionOper opCode)
|
|
{
|
|
m_nOperCode = opCode;
|
|
}
|
|
|
|
// 刨切线类
|
|
TVirtualSection::TVirtualSection(AecDbSymbSection* pSec)
|
|
{
|
|
m_bDrawLine = FALSE;
|
|
m_pDrawEnt = pSec;
|
|
}
|
|
|
|
TVirtualSection::~TVirtualSection()
|
|
{
|
|
|
|
}
|
|
|
|
Acad::ErrorStatus TVirtualSection::ExplodeOrDraw2d(XExplodeDraw& dc) const
|
|
{
|
|
Acad::ErrorStatus stat;
|
|
if (m_pDrawEnt)
|
|
{
|
|
stat = m_pDrawEnt->ExplodeOrDraw2d(dc);
|
|
}
|
|
|
|
stat = ExplodeOrDraw2dLineBox(dc);
|
|
|
|
return stat;
|
|
}
|
|
|
|
void TVirtualSection::SetCurrentPos(const AcGePoint3d& pt)
|
|
{
|
|
m_bDrawLine = TRUE;
|
|
m_ptPos = pt;
|
|
}
|
|
|
|
Acad::ErrorStatus TVirtualSection::ExplodeOrDraw2dLineBox(XExplodeDraw& dc) const
|
|
{
|
|
XAcGiViewDraw* pXDraw = (XAcGiViewDraw*)&dc;
|
|
AcGiCommonDraw* pCDraw = pXDraw->GetCommonDraw();
|
|
if (pCDraw == NULL)
|
|
{
|
|
return Acad::eInvalidInput;
|
|
}
|
|
|
|
if (m_bDrawLine && m_pDrawEnt != NULL)
|
|
{
|
|
XPoly2D poly;
|
|
m_pDrawEnt->GetPoly2D(poly);
|
|
if (poly.Length() == 2)
|
|
{
|
|
AcGePoint3d ptFir,ptScd,ptT;
|
|
ptFir = *poly[0];
|
|
ptScd = *poly[1];
|
|
|
|
AcDbLine line(ptFir, ptScd);
|
|
line.getClosestPointTo(m_ptPos,ptT,Adesk::kTrue);
|
|
AcGeVector3d vtT = m_ptPos - ptT;
|
|
AcGePoint3d arPt[2];
|
|
|
|
// 设置颜色
|
|
dc.SetColor(3);
|
|
arPt[0] = ptFir;
|
|
arPt[1] = ptFir + vtT;
|
|
pCDraw->rawGeometry()->worldLine(arPt);
|
|
|
|
arPt[0] = ptScd;
|
|
arPt[1] = ptScd + vtT;
|
|
pCDraw->rawGeometry()->worldLine(arPt);
|
|
|
|
arPt[0] = ptFir + vtT;
|
|
arPt[1] = ptScd + vtT;
|
|
pCDraw->rawGeometry()->worldLine(arPt);
|
|
|
|
return Acad::eOk;
|
|
}
|
|
}
|
|
|
|
return Acad::eInvalidInput;
|
|
}
|
|
|
|
TCreateThunderSection::TCreateThunderSection(const AcGePoint3d& ptS, const AcGePoint3d& ptE, const AcGeVector3d& vtDir, PickSet& ss3d)
|
|
{
|
|
// 构建剖切平面
|
|
if (ss3d.Length() < 1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 剖切边界实体
|
|
AcDbVoidPtrArray arNewPtr;
|
|
SplitSuit3DSolid(ss3d, ptS, ptE, arNewPtr);
|
|
|
|
// 构建剖切平面
|
|
AcGePlane plan;
|
|
plan.set(ptS, vtDir);
|
|
|
|
CString sLayer;
|
|
AcArray<AcDbRegion*> arReg;
|
|
AcDbRegion *pUnReg = NULL, *pReg = NULL;
|
|
|
|
for (long i = 0;i < ss3d.Length();++i)
|
|
{
|
|
OPENOBJ_BEGIN(ss3d[i],AcDb::kForWrite,AcDb3dSolid,pSd);
|
|
if (pSd != NULL)
|
|
{
|
|
sLayer = pSd->layer();
|
|
|
|
if (sLayer.CompareNoCase(LAY_EL_THUNDER_3D) == 0)
|
|
{
|
|
if (pUnReg == NULL)
|
|
{
|
|
pSd->getSection(plan, pUnReg);
|
|
if (pUnReg != NULL)
|
|
{
|
|
pUnReg->setColorIndex(pSd->colorIndex());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pSd->getSection(plan, pReg);
|
|
if (pReg != NULL)
|
|
{
|
|
pReg->setColorIndex(pSd->colorIndex());
|
|
pUnReg->booleanOper(AcDb::kBoolUnite,pReg);
|
|
delete pReg;
|
|
}
|
|
}
|
|
}
|
|
else // 非避雷对象(建筑物)
|
|
{
|
|
pSd->getSection(plan, pReg);
|
|
if (pReg != NULL)
|
|
{
|
|
pReg->setColorIndex(pSd->colorIndex());
|
|
arReg.append(pReg);
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
AcDb3dSolid* pSd = NULL;
|
|
for (int j = 0;j < arNewPtr.length();++j)
|
|
{
|
|
pSd = AcDb3dSolid::cast((AcRxObject*)arNewPtr[j]);
|
|
if (pSd != NULL)
|
|
{
|
|
sLayer = pSd->layer();
|
|
|
|
if (sLayer.CompareNoCase(LAY_EL_THUNDER_3D) == 0)
|
|
{
|
|
if (pUnReg == NULL)
|
|
{
|
|
pSd->getSection(plan, pUnReg);
|
|
if (pUnReg != NULL)
|
|
{
|
|
pUnReg->setColorIndex(pSd->colorIndex());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pSd->getSection(plan, pReg);
|
|
if (pReg != NULL)
|
|
{
|
|
pReg->setColorIndex(pSd->colorIndex());
|
|
pUnReg->booleanOper(AcDb::kBoolUnite,pReg);
|
|
delete pReg;
|
|
}
|
|
}
|
|
}
|
|
else // 非避雷对象(建筑物)
|
|
{
|
|
pSd->getSection(plan, pReg);
|
|
if (pReg != NULL)
|
|
{
|
|
pReg->setColorIndex(pSd->colorIndex());
|
|
arReg.append(pReg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ReleasePtrArray(arNewPtr);
|
|
|
|
if (pUnReg != NULL)
|
|
{
|
|
arReg.append(pUnReg);
|
|
}
|
|
|
|
if (arReg.length() > 0)
|
|
{
|
|
PickSet ssNew(SS_FREE);
|
|
|
|
AcGeVector3d vtToX = AcGeVector3d::kXAxis;
|
|
AcGeVector3d vtToY = AcGeVector3d::kYAxis;
|
|
AcGeVector3d vtNormal = AcGeVector3d::kZAxis;
|
|
AcGeVector3d vtFromX = vtDir.crossProduct(vtNormal);
|
|
|
|
AcGeMatrix3d mat,mat2;
|
|
mat.setToAlignCoordSys(ptS,vtFromX.normal(),vtDir.normal(),vtNormal,ptS,vtToX,vtToY,vtNormal);
|
|
mat2.setToRotation(-PI/2, vtToX);
|
|
|
|
for (int i = 0;i < arReg.length();++i)
|
|
{
|
|
pUnReg = arReg[i];
|
|
|
|
if (pUnReg != NULL)
|
|
{
|
|
pUnReg->transformBy(mat);
|
|
pUnReg->transformBy(mat2);
|
|
|
|
ssNew.IncludeBegin();
|
|
AddToCurrentSpace(pUnReg, Adesk::kTrue);
|
|
ssNew.IncludeEnd();
|
|
}
|
|
}
|
|
|
|
XPoint xp;
|
|
int nRet = DragMovePickSet(ssNew, _T("\n 请点取剖面放置位置<退出>: "), GetDragPoint(ssNew), xp);
|
|
}
|
|
}
|
|
|
|
TCreateThunderSection::~TCreateThunderSection()
|
|
{
|
|
|
|
}
|
|
|
|
void TCreateThunderSection::ReleasePtrArray(AcDbVoidPtrArray& arPtr)
|
|
{
|
|
for (int i = 0;i < arPtr.length();++i)
|
|
{
|
|
delete (AcDbEntity*)arPtr[i];
|
|
}
|
|
|
|
arPtr.setLogicalLength(0);
|
|
}
|
|
|
|
AcGePoint3d TCreateThunderSection::Mid2Point(const AcGePoint3d& pt1, const AcGePoint3d& pt2)
|
|
{
|
|
return AcGePoint3d((pt1.x+pt2.x)/2,(pt1.y+pt2.y)/2,(pt1.z+pt2.z)/2);
|
|
}
|
|
|
|
void TCreateThunderSection::SplitSuit3DSolid(PickSet& ssIn, const AcGePoint3d& ptS, const AcGePoint3d& ptE, AcDbVoidPtrArray& arPtr)
|
|
{
|
|
if (ssIn.Length() > 0)
|
|
{
|
|
AcGePoint3d ptMid = Mid2Point(ptS, ptE);
|
|
AcGeVector3d vtNor1 = ptMid - ptS;
|
|
AcGeVector3d vtNor2 = ptMid - ptE;
|
|
|
|
AcGePlane planS,planE;
|
|
planS.set(ptS, vtNor1);
|
|
planE.set(ptE, vtNor2);
|
|
|
|
PickSet ssRemove(SS_FREE);
|
|
|
|
BOOL bOpt = FALSE;
|
|
AcDb3dSolid* pSolidTmp = NULL;
|
|
AcDb3dSolid* pSolidNew = NULL;
|
|
for (long i = 0;i < ssIn.Length();++i)
|
|
{
|
|
bOpt = FALSE;
|
|
OPENOBJ_BEGIN(ssIn[i], AcDb::kForRead, AcDb3dSolid, pSoid);
|
|
if (pSoid != NULL)
|
|
{
|
|
pSolidTmp = new AcDb3dSolid;
|
|
pSolidTmp->copyFrom(pSoid);
|
|
|
|
if (Acad::eOk == pSolidTmp->getSlice(planS, Adesk::kFalse, pSolidNew))
|
|
{
|
|
bOpt = TRUE;
|
|
}
|
|
|
|
if (Acad::eOk == pSolidTmp->getSlice(planE, Adesk::kFalse, pSolidNew))
|
|
{
|
|
bOpt = TRUE;
|
|
}
|
|
|
|
if (bOpt)
|
|
{
|
|
arPtr.append(pSolidTmp);
|
|
ssRemove += ssIn[i];
|
|
}
|
|
else
|
|
{
|
|
delete pSolidTmp;
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
ssIn -= ssRemove;
|
|
}
|
|
}
|
|
|
|
AcGePoint3d TCreateThunderSection::GetDragPoint(PickSet& ssEnt)
|
|
{
|
|
AcGePoint3d pt;
|
|
AcDbExtents ext;
|
|
std::list<double> lstX,lstY,lstZ;
|
|
|
|
for (long i = 0;i < ssEnt.Length();++i)
|
|
{
|
|
OPENOBJ_BEGIN(ssEnt[i],AcDb::kForRead,AcDbEntity,pEnt);
|
|
if (pEnt != NULL)
|
|
{
|
|
pEnt->getGeomExtents(ext);
|
|
lstX.push_back(ext.minPoint().x);
|
|
lstY.push_back(ext.minPoint().y);
|
|
lstZ.push_back(ext.minPoint().z);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
if (lstX.size() > 0 && lstY.size() > 0 && lstY.size() > 0)
|
|
{
|
|
lstX.sort();
|
|
lstY.sort();
|
|
lstZ.sort();
|
|
|
|
pt.x = *std::min_element(lstX.begin(), lstX.end());
|
|
pt.y = *std::min_element(lstY.begin(), lstY.end());
|
|
pt.z = *std::min_element(lstZ.begin(), lstZ.end());
|
|
}
|
|
|
|
return pt;
|
|
}
|
|
|
|
AcDbObjectId TCreateThunderSection::CopyEnt(AcDbEntity* pEnt)
|
|
{
|
|
AcDbObjectId id;
|
|
if (pEnt)
|
|
{
|
|
AcDbEntity* pNew = CopyEntPtr(pEnt);
|
|
if (pNew)
|
|
{
|
|
id = AddToCurrentSpace(pNew,Adesk::kTrue);
|
|
}
|
|
}
|
|
return id;
|
|
}
|
|
|
|
AcDbEntity* TCreateThunderSection::CopyEntPtr(AcDbEntity* pEnt)
|
|
{
|
|
AcDbEntity* pLoc = NULL;
|
|
if (pEnt)
|
|
{
|
|
AcDb3dSolid* pp = AcDb3dSolid::cast(pEnt);
|
|
if (pp)
|
|
{
|
|
pLoc = new AcDb3dSolid;
|
|
pLoc->copyFrom(pEnt);
|
|
}
|
|
|
|
AcDbLine* p2 = AcDbLine::cast(pEnt);
|
|
if (p2)
|
|
{
|
|
pLoc = new AcDbLine;
|
|
pLoc->copyFrom(pEnt);
|
|
}
|
|
|
|
AcDbArc* p3 = AcDbArc::cast(pEnt);
|
|
if (p3)
|
|
{
|
|
pLoc = new AcDbArc;
|
|
pLoc->copyFrom(pEnt);
|
|
}
|
|
AcDbRegion* pReg = AcDbRegion::cast(pEnt);
|
|
if (pReg)
|
|
{
|
|
pLoc = new AcDbRegion;
|
|
pLoc->copyFrom(pEnt);
|
|
}
|
|
}
|
|
return pLoc;
|
|
}
|
|
|