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

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