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

1410 lines
31 KiB
C++

#include "stdafx.h"
#include "AcISOPolylineJig.h"
#include "AcISOCrdWatch.h"
#include "AECStatusRecord.h"
#include "AecDb3dRoadAxisLine.h"
#include "KTCadUtility.h"
#include "ReducerDlg.h"
#include "CoreTools.h"
#include "ktsetting.h"
static const Adesk::UInt16 kColorByBlock = 0;
static const Adesk::UInt16 kRed = 1;
static const Adesk::UInt16 kYellow = 2;
static const Adesk::UInt16 kGreen = 3;
static const Adesk::UInt16 kCyan = 4;
static const Adesk::UInt16 kBlue = 5;
static const Adesk::UInt16 kMagenta = 6;
static const Adesk::UInt16 kWhite = 7;
static const Adesk::UInt16 kColorByLayer = 256;
extern AcDbPolyline *FormatPolyline(AcGePoint3d *ppPts, int nCount);
extern AcDbObjectId AddToModelSpace(AcDbEntity *pEnt, bool bClose = true);
AcGePoint3d MidPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2)
{
return AcGePoint3d((pt1.x + pt2.x) / 2.0,
(pt1.y + pt2.y) / 2.0,
(pt1.z + pt2.z) / 2.0);
}
DLLIMPEXP AcDbArc *FormatArc(const AcGePoint3d &ptGe1, const AcGePoint3d &ptGe2, const AcGePoint3d &ptGe3);
AcISOPolyline::AcISOPolyline()
{
m_pCurve = NULL;
m_pISOCrdWatch = NULL;
m_bDblLine = false;
m_dW = 0.0;
m_dLW = 0.5 * m_dW;
m_pCurve1 = NULL;
m_pCurve2 = NULL;
m_bAngleWatchDraw = false;
m_eAlign = kMid;
}
AcISOPolyline::~AcISOPolyline()
{
}
Acad::ErrorStatus AcISOPolyline::Draw2d(AcGiDraw &mode) const
{
if (m_pCurve != NULL)
{
if (m_bDblLine)
{
AcDbLine* pLn = AcDbLine::cast(m_pCurve);
if (pLn != NULL)
{
AcGeVector3d vtL = pLn->endPoint() - pLn->startPoint();
vtL.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtL.normalize();
AcGeVector3d vtR = vtL;
vtR.negate();
switch (m_eAlign)
{
case kMid:
{
//vtL *= 0.5 * m_dW;
//vtR *= 0.5 * m_dW;
//有左宽要求
vtL *= m_dLW;
vtR *= m_dW - m_dLW;
break;
}
case kLeft:
{
vtL *= m_dW;
break;
}
case kRight:
{
vtR *= m_dW;
break;
}
default:
break;
}
if (m_pCurve1 == NULL)
m_pCurve1 = new AcDbLine;
AcDbLine* pLn1 = AcDbLine::cast(m_pCurve1);
if (pLn1 == NULL)
{
delete m_pCurve1;
m_pCurve1 = new AcDbLine;
}
//Left
AcGePoint3d ptSta = pLn->startPoint();
AcGePoint3d ptEnd = pLn->endPoint();
pLn1 = AcDbLine::cast(m_pCurve1);
if (pLn1 != NULL)
{
ptSta += vtL;
ptEnd += vtL;
pLn1->setStartPoint( ptSta );
pLn1->setEndPoint( ptEnd );
}
if (m_pCurve2 == NULL)
m_pCurve2 = new AcDbLine;
AcDbLine* pLn2 = AcDbLine::cast(m_pCurve2);
if (pLn2 == NULL)
{
delete m_pCurve2;
m_pCurve2 = new AcDbLine;
}
//Right
ptSta = pLn->startPoint();
ptEnd = pLn->endPoint();
pLn2 = AcDbLine::cast(m_pCurve2);
if (pLn2 != NULL)
{
ptSta += vtR;
ptEnd += vtR;
pLn2->setStartPoint( ptSta );
pLn2->setEndPoint( ptEnd );
}
mode.DrawEntity((AcDbEntity*)m_pCurve1);
mode.DrawEntity((AcDbEntity*)m_pCurve2);
}
AcDbArc* pArc = AcDbArc::cast(m_pCurve);
if (pArc != NULL)
{
if (m_pCurve1 == NULL)
m_pCurve1 = new AcDbArc;
AcDbArc* pArc1 = AcDbArc::cast(m_pCurve1);
if (pArc1 == NULL)
{
delete m_pCurve1;
pArc1 = new AcDbArc;
m_pCurve1 = pArc1;
}
if (m_pCurve2 == NULL)
m_pCurve2 = new AcDbArc;
AcDbArc* pArc2 = AcDbArc::cast(m_pCurve2);
if (pArc2 == NULL)
{
delete m_pCurve2;
pArc2 = new AcDbArc;
m_pCurve2 = pArc2;
}
double dR = pArc->radius();
AcGePoint3d ptCen = pArc->center();
double dSta = pArc->startAngle();
double dEnd = pArc->endAngle();
double dLr = 0.0, dRr = 0.0;
switch (m_eAlign)
{
case kMid:
{
//dLr = 0.5 * m_dW;
//dRr = -0.5 * m_dW;
dLr = m_dLW;
dRr = -(m_dW - m_dLW);
break;
}
case kLeft:
{
dLr = 0.0;
dRr = -m_dW;
break;
}
case kRight:
{
dLr = m_dW;
dRr = 0.0;
break;
}
default:
break;
}
//Left
pArc1->setRadius(dR + dLr);
pArc1->setStartAngle(dSta);
pArc1->setEndAngle(dEnd);
pArc1->setCenter(ptCen);
pArc1->setNormal(AcGeVector3d::kZAxis);
//Right
pArc2->setRadius(dR + dRr);
pArc2->setStartAngle(dSta);
pArc2->setEndAngle(dEnd);
pArc2->setCenter(ptCen);
pArc2->setNormal(AcGeVector3d::kZAxis);
mode.DrawEntity((AcDbEntity*)m_pCurve1);
mode.DrawEntity((AcDbEntity*)m_pCurve2);
}
}
else
{
mode.DrawEntity((AcDbEntity*)m_pCurve);
}
}
if (m_pISOCrdWatch != NULL && m_bAngleWatchDraw)
{
m_pISOCrdWatch->Draw2d(mode);
}
return Acad::eOk;
}
AcISOPolylineJig::AcISOPolylineJig(void)
{
m_pCurStaRec = NULL;
m_pLine = new AcDbLine;
m_pArc = new AcDbArc;
m_pCurve = m_pLine;
m_pDb = NULL;
m_pPipeParam = NULL;
m_nUndoGoupid = 0;
m_pRoadAxisLine = new AecDb3dRoadAxisLine;
m_pISOCrdWatch = new AecISOCrdWatch(TRUE);
m_pPolylineProxy = new AcISOPolyline();
m_pPolylineProxy->m_pISOCrdWatch = m_pISOCrdWatch;
m_pPolylineProxy->m_pCurve = m_pCurve;
m_pPolylineProxy->setColorIndex(kMagenta);//默认红色
InitStatusRecsFor2DISOLineSegs();
}
AcISOPolylineJig::~AcISOPolylineJig(void)
{
if (m_pLine != NULL)
delete m_pLine;
if (m_pArc != NULL)
delete m_pArc;
if ( m_pISOCrdWatch != NULL)
delete m_pISOCrdWatch;
}
void AcISOPolylineJig::PushBackStatusRec(AECStatusRecord* pRec)
{
pRec->SetUndoGroupId(m_nUndoGoupid);
m_lstStaPtrsBack.AddTail(pRec);
}
void AcISOPolylineJig::SetUndoGroupBegin()
{
m_nUndoGoupid += 1;
}
void AcISOPolylineJig::SetUndoGroupEnd()
{
}
void AcISOPolylineJig::PopUpStatusRec()
{
//按 id 回退一次,调整当前状态
if (m_lstStaPtrsBack.GetCount() > 0)
{
AECStatusRecord* pLast = (AECStatusRecord*)m_lstStaPtrsBack.GetTail();
int nID = pLast->GetUndoGroupId();
while(m_lstStaPtrsBack.GetCount() > 0)
{
m_lstStaPtrsBack.RemoveTail();
DELETE_PTR(pLast);
pLast = NULL;
if (m_lstStaPtrsBack.GetCount() == 0)
{
break;
}
pLast = (AECStatusRecord*)m_lstStaPtrsBack.GetTail();
if (nID != pLast->GetUndoGroupId())
{
break;
}
}
//roadline 回退一次,调整接口记录
if (m_pRoadAxisLine != NULL)
{
m_pRoadAxisLine->RemoveLast();
}
MoveAngWatchPosition();
}
}
void AcISOPolylineJig::FreeBuffer()
{
AECStatusRecord* pRec = NULL;
while(!m_arStaPtrs.IsEmpty())
{
pRec = (AECStatusRecord* )m_arStaPtrs.GetAt(0);
m_arStaPtrs.RemoveAt(0);
delete pRec;
}
}
void AcISOPolylineJig::InitStatusRecsFor2DISOLineSegs()
{
FreeBuffer();
AECStatusRecord *pRec1 = NULL;
pRec1 = new AECStatusRecord;
pRec1->SetPrompt(_T("\n指定起点<退出>:"));
pRec1->SetStatusType(AECStatusRecord::kPoint);
pRec1->SetPlanPosition(0);
pRec1->SetPos(0);
m_arStaPtrs.Add(pRec1);
AECStatusRecord *pRec2 = NULL;
pRec2 = new AECStatusRecord;
pRec2->SetPrompt(_T("\n指定下一个点或 [变径(A)]:<退出>:"));
pRec2->SetStatusType(AECStatusRecord::kPoint);
pRec2->SetKeywordList(_T("A E U J"));
m_arStaPtrs.Add(pRec2);
pRec1->SetNextStatus(pRec2);
pRec2->SetPlanPosition(1);
pRec2->SetNextStatus(pRec2, 1);
pRec2->SetPos(1);
m_pCurStaRec = pRec1;
SetAngleWatchDraw(true);
}
void AcISOPolylineJig::SetAngleWatchDraw(bool bAngleWatchDraw)
{
m_pPolylineProxy->m_bAngleWatchDraw = bAngleWatchDraw;
}
void AcISOPolylineJig::CalReferencePoint()
{
AcGePoint3d ptWcs;
ads_point ptBase,pt22,pt33;
acedInitGet(RSG_NONULL,_T("R"));
int nRes = acedGetPoint(NULL,_T("\n指定起点或[参考点(R)]<退出>:"),ptBase);
switch(nRes)
{
case RTNORM:
{
acdbUcs2Wcs(ptBase,pt22,false);
ptWcs = asPnt3d(pt22);
m_pCurStaRec->SetAcquirePoint(ptWcs);
AECStatusRecord * pRec = new AECStatusRecord;
pRec->CopyFrom(m_pCurStaRec);
pRec->SetUndoGroupId(0);
PushBackStatusRec(pRec);
MoveAngWatchPosition();
m_pCurStaRec = m_pCurStaRec->GetNextStatus(m_pCurStaRec->GetPos());
m_pCurStaRec->SetAcquirePoint(ptWcs);
break;
}
case RTKWORD:
{
TCHAR szKey[2];
szKey[0] = '0';
acedGetInput(szKey);
switch(szKey[0])
{
case _T('R'):
case _T('r'):
{
//参考点<退出>:
nRes = acedGetPoint(NULL,_T("\n参考点<退出>:"),ptBase);
if (nRes == RTNORM)
{
//起点<退出>:
nRes = acedGetPoint(ptBase,_T("\n指定起点<退出>:"),pt22);
if (nRes == RTNORM)
{
acdbUcs2Wcs(pt22,pt33,false);
ptWcs = asPnt3d(pt33);
m_pCurStaRec->SetAcquirePoint(ptWcs);
AECStatusRecord * pRec = new AECStatusRecord;
pRec->CopyFrom(m_pCurStaRec);
pRec->SetUndoGroupId(0);
PushBackStatusRec(pRec);
MoveAngWatchPosition();
m_pCurStaRec = m_pCurStaRec->GetNextStatus(m_pCurStaRec->GetPos());
m_pCurStaRec->SetAcquirePoint(ptWcs);
}
}
break;
}
default:
break;
}
}
default:
{
break;
}
}
}
bool AcISOPolylineJig::DoItISO(int nAngMode, int nAngle, ISODrawCfg &soDrwCfg)
{
m_pISOCrdWatch->SetISOMode(nAngMode,nAngle);
memcpy(&m_IsoDrwCfg, &soDrwCfg, sizeof(ISODrawCfg));
AcEdJig::DragStatus eStat;
int nPlanPos = 0;
CString sPrompt = _T("");
AcGePoint3d ptGe;
//参考
CalReferencePoint();
while (TRUE)
{
sPrompt = m_pCurStaRec->Prompt();
setDispPrompt(sPrompt);
eStat = drag();
if (m_pCurStaRec == NULL)
return false;
nPlanPos = m_pCurStaRec->GetPlanPosition();
switch (eStat)
{
case AcEdJig::kNormal:
{
if (nPlanPos == 1 || nPlanPos == 2) //Create line,Arc
{
if (AddRoadNode(WPipe::eToCreate))
{
//设置回退记录
SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("BE"), RTNONE);
SetUndoGroupBegin();
m_pCurStaRec->SetRefDblValue(0);//归0
AECStatusRecord *pRec = new AECStatusRecord;
pRec->CopyFrom(m_pCurStaRec);
PushBackStatusRec(pRec);
SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("E"), RTNONE);
SetUndoGroupEnd();
if (m_pCurStaRec->IsCommand2Stop())
{
return m_idRoadLine.isValid();
}
}
m_pCurve = m_pLine;//回归直线
m_pCurve->setColorIndex(1);
m_pPolylineProxy->m_pCurve = m_pCurve;
}
break;
}
case AcEdJig::kCancel:
case AcEdJig::kNull:// 退出
{
acutPrintf(_T("\n"));
return m_idRoadLine.isValid();
}
case AcEdJig::kKW1://圆弧 A 或 W 或 R
{
//变径
CReducerDlg redDLg;
WPipe::PipeParam param;
memset(&param, 0, sizeof(WPipe::PipeParam));
memcpy(&param, m_pPipeParam, sizeof(WPipe::PipeParam));
param.m_vtECCen.set(0.0, 0.0, 0.0);
redDLg.Set(m_pDb, &param);
int nRes = redDLg.DoModal();
if (nRes == IDOK)
{
AddReducer(param);
//中断,开始新的ISO线
Commit(FALSE);
m_idRoadLine.setNull();
}
break;
}
case AcEdJig::kKW2://标高 E 或 W
{
break;
}
case AcEdJig::kKW3://放弃 U
{
break;
}
case AcEdJig::kKW4://精度 J
{
break;
}
case AcEdJig::kKW5://宽度 W
{
break;
}
case AcEdJig::kKW6://坡度 P
{
break;
}
default:
break;
}
AcGePoint3d ptGe = m_pCurStaRec->GetAcquirePoint();
//获取下个状态,plane判断是?
if (m_pCurStaRec->GetPlanPosition() == 0 ||
m_pCurStaRec->GetPlanPosition() == 1 ||
m_pCurStaRec->GetPlanPosition() == 2)
{
AECStatusRecord *pRec = new AECStatusRecord;
pRec->CopyFrom(m_pCurStaRec);
pRec->SetUndoGroupId(0);
PushBackStatusRec(pRec);
MoveAngWatchPosition();
m_pCurStaRec = m_pCurStaRec->GetNextStatus(m_pCurStaRec->GetPos());
m_pCurStaRec->SetAcquirePoint(ptGe);
}
}
return m_idRoadLine.isValid();
}
BOOL AcISOPolylineJig::Commit(BOOL bElbowFit)
{
AcDbObjectId id = GetRoadAxisLineId();
CString sDocScale = m_IsoDrwCfg.m_sScale;
int nIndex = sDocScale.Find(_T(':'), 0);
double dPScale = 100.0;
if (nIndex != -1)
{
dPScale = _ttof(sDocScale.Mid(nIndex + 1)) / _ttof(sDocScale.Mid(0, nIndex));
}
AcDbObjectId idCurSys = CoreTools::getLyForPipe(m_IsoDrwCfg.m_sCurrSys);
AcDbObjectId idLineType = KTSetting::InitLineStyle(_T("CONTINUOUS"));
//埋ISO参数
AcDbEntity *pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite))
{
//设置桥架图层
AecDb3dRoadAxisLine *pRd = AecDb3dRoadAxisLine::cast(pEnt);
if (pRd != NULL)
{
if (!m_IsoDrwCfg.m_bElbowLine && bElbowFit)
{
pRd->ReCreate3dRoadAxisLine(m_IsoDrwCfg.m_dDn, m_IsoDrwCfg.m_dRadio);
}
AcDbPolyline *pPl = pRd->ConvertTo2dPline();
if (pPl != NULL)
{
pPl->setConstantWidth(m_IsoDrwCfg.m_dPipeW * dPScale);
pPl->setLayer(idCurSys);
pPl->setLinetype(idLineType);
AcISOPolyline::WriteISOXData(pPl, m_IsoDrwCfg);
AddToModelSpace(pPl);
}
}
pEnt->erase();
pEnt->close();
}
return TRUE;
}
BOOL AcISOPolylineJig::AddReducer(WPipe::PipeParam& param)
{
//LAST DIR
AcGeVector3d vtInf = GetLastInterface();
if (vtInf.isZeroLength())
return FALSE;
AcGePoint3d ptPos;
//绘制变径
//获取当前坐标系
AcGeVector3d vtX, vtY, vtZ;
GetISOCrd(ptPos,vtX,vtY,vtZ);
vtInf.normalize();
AcGePoint3d ptGe[13],ptL[2];
AcGeVector3d vtDir[2];
ptL[0] = ptPos;
ptL[1] = ptPos + vtInf * param.m_dInterfaceL3;
vtDir[0] = vtInf;
vtDir[0].negate();
vtDir[1] = vtInf;
//绘制在 vtInf + vtZ 面
ptGe[0] = ptL[0] + vtZ * 0.5 * m_pPipeParam->m_dDN;
ptGe[3] = ptL[0] - vtZ * 0.5 * m_pPipeParam->m_dDN;
ptGe[1] = ptL[1] + vtZ * 0.5 * param.m_dDN;
ptGe[2] = ptL[1] - vtZ * 0.5 * param.m_dDN;
ptGe[4] = ptGe[0];
AcDbPolyline *pPl = FormatPolyline(ptGe, 5);
if (pPl != NULL)
{
AcDbObjectId idSingle = CoreTools::getLyByPipeSys(m_pPipeParam->szSys, true);
pPl->setLayer(idSingle);
AddToModelSpace(pPl);
m_pCurStaRec->SetAcquirePoint(ptL[1]);
return TRUE;
}
return FALSE;
}
AcDbObjectId AcISOPolylineJig::GetRoadAxisLineId() const
{
return m_idRoadLine;
}
AcEdJig::DragStatus AcISOPolylineJig::sampler()
{
setUserInputControls( ( UserInputControls)
( AcEdJig::kAccept3dCoordinates |
AcEdJig::kNullResponseAccepted ) );
if (m_pCurStaRec == NULL)
return AcEdJig::kCancel;
CString sKeywordsList;
sKeywordsList = m_pCurStaRec->KeywordList();
if (!sKeywordsList.IsEmpty())
{
setKeywordList(sKeywordsList);
}
AcEdJig::DragStatus eStat = AcEdJig::kNormal;
AcGePoint3d ptGe,ptGeBase,ptGe2;
ptGeBase = AcGePoint3d::kOrigin;
AECStatusRecord::EAcquire eAcquire = m_pCurStaRec->GetStatusType();
switch(eAcquire)
{
case AECStatusRecord::kPoint:
{
int nPos = m_pCurStaRec->GetPlanPosition();
if (nPos == 0)//指定起点
{
eStat = acquirePoint(ptGe);
}
else
{
GetLastStatusAquire(ptGeBase);
eStat = acquirePoint(ptGe,ptGeBase);
ptGe.z = ptGeBase.z;
double dDist = ptGeBase.distanceTo(ptGe);
if ( dDist < 1.e-6)
{
return AcEdJig::kNoChange;
}
else
{
ptGe2 = m_pCurStaRec->GetAcquirePoint();
m_pCurStaRec->SetAcquirePoint(ptGe);
}
}
if (eStat == AcEdJig::kNormal)
{
if (m_pCurStaRec->IsValSeted())
{
double dDis = ptGe2.distanceTo(ptGe);
if (dDis < 1.e-6)
{
//鼠标原地不动
return AcEdJig::kNoChange;
}
}
ptGe2 = m_pCurStaRec->GetAcquirePoint();
ptGe.z = ptGeBase.z;
//m_pCurStaRec->SetAcquirePoint(ptGe);
//acutPrintf(_T("\nGetPt: Y= %.3f"), ptGe.y);
if (m_pCurStaRec->GetPlanPosition() > 0 && m_lstStaPtrsBack.GetCount() > 0)
{
if (m_pCurStaRec->GetPlanPosition() == 1394 ||
m_pCurStaRec->GetPlanPosition() == 1395)
{
AddArcRoadNode(WPipe::eToPreView);
}
else
{
AddRoadNode(WPipe::eToPreView);
}
ptGe = m_pCurStaRec->GetAcquirePoint();
if (ptGe.distanceTo(ptGe2) < 1.e-6)
{
return AcEdJig::kNoChange;
}
return AcEdJig::kNormal;
}
}
else if (eStat == AcEdJig::kOther)
{
int nn = 0;
}
break;
}
default:
break;
}
return eStat;
}
BOOL AcISOPolylineJig::MakeLine()
{
if (m_lstStaPtrsBack.IsEmpty())
return FALSE;
AECStatusRecord* pRecLast = (AECStatusRecord* )m_lstStaPtrsBack.GetTail();
AcGePoint3d ptFr;
ptFr = pRecLast->GetAcquirePoint();
m_pLine->setStartPoint(ptFr);
AcGePoint3d ptCur;
ptCur = m_pCurStaRec->GetAcquirePoint();
//如果上次是圆弧,则计算切线
if (pRecLast->GetPlanPosition() == 2)
{
AcGeVector3d vtLast(0,0,0);
m_pArc->getFirstDeriv(ptFr,vtLast);
if (vtLast.isZeroLength())
{
AcGePoint3d ptFr2;
m_pArc->getClosestPointTo(ptFr, ptFr2);
m_pArc->getFirstDeriv(ptFr2, vtLast);
ptFr = ptFr2;
}
AcDbXline xLn;
xLn.setBasePoint(ptFr);
xLn.setUnitDir(vtLast);
AcGePoint3d ptEnd;
xLn.getClosestPointTo(ptCur,ptEnd);
ptCur = ptEnd;
}
//坡度
double dP = m_pCurStaRec->GetRefDblValue();
double dZBk = ptCur.z;
AcGeVector3d vt = ptCur - ptFr;
if (vt.isParallelTo(AcGeVector3d::kZAxis))
{
}
else
{
if (fabs(dP) > 1.e-3)
{
double dDist = ptCur.distanceTo(ptFr);
//dP = 100.0 * (pt2.z - pt1.z) / dDist;//计算坡度
ptCur.z = ptFr.z + dP * 0.01 * dDist;
}
}
//投影校正
m_pLine->setEndPoint(ptCur);
m_pCurStaRec->SetAcquirePoint(ptCur);
m_pCurve = m_pLine;
m_pCurve->setColorIndex(1);
return TRUE;
}
//切线弧
BOOL AcISOPolylineJig::MakeArc()
{
if (m_lstStaPtrsBack.IsEmpty())
return FALSE;
if (m_pRoadAxisLine->GetCurveSegCount() > 0)
{
AECStatusRecord* pRecLast = (AECStatusRecord* )m_lstStaPtrsBack.GetTail();
AcDbCurve* pLast = m_pRoadAxisLine->GetCurveSeg(m_pRoadAxisLine->GetCurveSegCount() - 1);
AcGePoint3d ptLast = pRecLast->GetAcquirePoint();
AcGePoint3d ptThis = m_pCurStaRec->GetAcquirePoint();
AcGeVector3d vtLast,vtLastBk;
pLast->getFirstDeriv(ptLast,vtLast);
vtLastBk = vtLast;
vtLastBk.normalize();
vtLast.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGeVector3d vtThis = ptThis - ptLast;
AcGePoint3d ptMid = MidPoint(ptLast,ptThis);
vtThis.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGeLine3d ln1(ptLast,vtLast);
AcGeLine3d ln2(ptMid,vtThis);
AcGePoint3d ptCen;
if (vtLast.isParallelTo(vtThis))
{
vtLast.normalize();
ptCen = ptMid;
ptMid = ptCen + 0.5 * ptLast.distanceTo(ptThis) * vtLast;
}
else
{
ln1.intersectWith(ln2, ptCen);
}
double dR = ptCen.distanceTo(ptLast);
vtThis = ptMid - ptCen;
vtThis.normalize();
if (vtThis.isZeroLength())
{
ptMid = ptCen + 0.5 * ptLast.distanceTo(ptThis) * vtLastBk;
vtThis = ptMid - ptCen;
}
else
{
ptMid = ptCen + dR * vtThis;
}
AcDbArc* pArc = FormatArc(ptLast,ptMid,ptThis);
if (pArc != NULL)
{
double dSta = pArc->startAngle();
double dEnd = pArc->endAngle();
m_pArc->setCenter(pArc->center());
m_pArc->setRadius(pArc->radius());
m_pArc->setNormal(pArc->normal());
m_pArc->setStartAngle(pArc->startAngle());
m_pArc->setEndAngle(pArc->endAngle());
//acutPrintf(_T("\nsta,end = %g,%g"),pArc->startAngle(),pArc->endAngle());
m_pCurve = m_pArc;
m_pCurve->setColorIndex(1);
m_pPolylineProxy->m_pCurve = m_pCurve;
delete pArc;
m_pCurStaRec->SetAcquirePoint(ptThis);
//TEST
return TRUE;
}
}
return FALSE;
}
BOOL AcISOPolylineJig::AddRoadNode(WPipe::PipeDraw ePipe)
{
switch(ePipe)
{
case WPipe::eToPreView:
{
AcGePoint3d ptEnd = m_pCurStaRec->GetAcquirePoint();
if ( !m_lstStaPtrsBack.IsEmpty() )
{
if (m_pCurStaRec->GetPlanPosition() <= 1)
{
//前后标高一致
MakeLine();
}
else
{
MakeArc();
}
AcGePoint3d ptGe,ptGe1;
ptGe1 = GetTailStatusRec()->GetAcquirePoint();
ptGe = m_pCurStaRec->GetAcquirePoint();
AcGeVector3d vtDir = m_pISOCrdWatch->m_vtDir;
m_pPolylineProxy->m_pISOCrdWatch->m_bFallInSnap = FALSE;
if (m_pPolylineProxy->m_bAngleWatchDraw && m_pPolylineProxy->m_pISOCrdWatch->snapWatch(ptGe1,ptGe,vtDir))
m_pCurStaRec->SetAcquirePoint(ptGe);//???2024-11-25
m_pPolylineProxy->m_pISOCrdWatch->m_bFallInSnap = TRUE;
return TRUE;
}
break;
}
case WPipe::eToCreate:
{
if (m_pCurve != NULL)
{
AecDb3dRoadAxisLine* pAxisLine = NULL;
if (m_idRoadLine.isValid())
{
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,m_idRoadLine,AcDb::kForWrite))
{
pAxisLine = AecDb3dRoadAxisLine::cast(pEnt);
if (pAxisLine != NULL)
{
pAxisLine->setColorIndex(kMagenta);
pAxisLine->AppendCurveSeg(m_pCurve);
}
pEnt->close();
}
}
else
{
pAxisLine = new AecDb3dRoadAxisLine;
pAxisLine->setColorIndex(kMagenta);
pAxisLine->AppendCurveSeg(m_pCurve);
CKTCadUtility::AddToBlockTableRecord(pAxisLine);
m_idRoadLine = pAxisLine->objectId();
pAxisLine->close();
}
//缓存添加本段
m_pRoadAxisLine->setColorIndex(kMagenta);
m_pRoadAxisLine->AppendCurveSeg(m_pCurve);
MoveAngWatchPosition();
AcGePoint3d ptGe,ptGe1;
ptGe1 = GetTailStatusRec()->GetAcquirePoint();
ptGe = m_pCurStaRec->GetAcquirePoint();
AcGeVector3d vtDir = m_pISOCrdWatch->m_vtDir;
m_pPolylineProxy->m_pISOCrdWatch->m_bFallInSnap = FALSE;
if (m_pPolylineProxy->m_bAngleWatchDraw && m_pPolylineProxy->m_pISOCrdWatch->snapWatch(ptGe1,ptGe,vtDir))
m_pCurStaRec->SetAcquirePoint(ptGe);
m_pPolylineProxy->m_pISOCrdWatch->m_bFallInSnap = TRUE;
return TRUE;
}
break;
}
default:
break;
}
return FALSE;
}
BOOL AcISOPolylineJig::AddArcRoadNode(WPipe::PipeDraw ePipe)
{
if (m_lstStaPtrsBack.IsEmpty())
return FALSE;
CPtrList listPtrs;
listPtrs.AddTail(&m_lstStaPtrsBack);
//
BOOL bSuccess = FALSE;
if (ePipe == WPipe::eToPreView)
{
listPtrs.AddTail(m_pCurStaRec);
}
AcGePoint3dArray arPts;
if (listPtrs.GetSize() == 3)
{
POSITION ps = listPtrs.GetHeadPosition();
AECStatusRecord* pRec0 = (AECStatusRecord*)listPtrs.GetNext(ps);
AECStatusRecord* pRec1 = (AECStatusRecord*)listPtrs.GetNext(ps);
AECStatusRecord* pRec2 = (AECStatusRecord*)listPtrs.GetNext(ps);
if (pRec2->GetPlanPosition() == 1394)//三点圆弧
{
AcDbArc* pArc = FormatArc(pRec0->GetAcquirePoint(),pRec2->GetAcquirePoint(),pRec1->GetAcquirePoint());
if (pArc != NULL)
{
double dSta = pArc->startAngle();
double dEnd = pArc->endAngle();
m_pArc->setCenter(pArc->center());
m_pArc->setRadius(pArc->radius());
m_pArc->setNormal(pArc->normal());
m_pArc->setStartAngle(pArc->startAngle());
m_pArc->setEndAngle(pArc->endAngle());
//acutPrintf(_T("\nsta,end = %g,%g"),pArc->startAngle(),pArc->endAngle());
m_pCurve = m_pArc;
m_pCurve->setColorIndex(kMagenta);
m_pPolylineProxy->m_pCurve = m_pCurve;
delete pArc;
bSuccess = TRUE;
}
}
else//两点,方向半径
{
AcGePoint3d ptS = pRec0->GetAcquirePoint();
AcGePoint3d ptE = pRec1->GetAcquirePoint();
AcGePoint3d ptV = pRec2->GetAcquirePoint();
AcGeVector3d vtDir(ptV.x,ptV.y,ptV.z);
AcGePoint3d ptM = MidPoint(ptS,ptE);
double dR = vtDir.length();
double dL = ptS.distanceTo(ptE);
double dhh = dR * dR - 0.25 * dL * dL;
if (dhh < 1.e-3)
{
acutPrintf(_T("\n输入的半径国小!创建圆弧失败!"));
return FALSE;
}
double dh = sqrt(dhh);
AcGeVector3d vtN = ptE - ptS;
AcGeVector3d vtDir2 = vtDir.orthoProject(vtN);
vtDir2.normalize();
vtDir2.negate();
vtDir2 *= dh;
AcGePoint3d ptCen = ptM + vtDir2;
vtDir2.normalize();
ptM = ptCen - vtDir2 * dR;
AcDbArc* pArc = FormatArc(ptS,ptM,ptE);
if (pArc != NULL)
{
double dSta = pArc->startAngle();
double dEnd = pArc->endAngle();
m_pArc->setCenter(pArc->center());
m_pArc->setRadius(pArc->radius());
m_pArc->setNormal(pArc->normal());
m_pArc->setStartAngle(pArc->startAngle());
m_pArc->setEndAngle(pArc->endAngle());
//acutPrintf(_T("\nsta,end = %g,%g"),pArc->startAngle(),pArc->endAngle());
m_pCurve = m_pArc;
m_pCurve->setColorIndex(kMagenta);
m_pPolylineProxy->m_pCurve = m_pCurve;
delete pArc;
//TEST
bSuccess = TRUE;
}
}
}
//缓存添加本段
if (ePipe == WPipe::eToCreate)
{
AecDb3dRoadAxisLine* pAxisLine = NULL;
if (m_idRoadLine.isValid())
{
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,m_idRoadLine,AcDb::kForWrite))
{
pAxisLine = AecDb3dRoadAxisLine::cast(pEnt);
if (pAxisLine != NULL)
{
pAxisLine->AppendCurveSeg(m_pCurve);
}
pEnt->close();
}
}
else
{
pAxisLine = new AecDb3dRoadAxisLine;
pAxisLine->setColorIndex(kMagenta);
pAxisLine->AppendCurveSeg(m_pCurve);
CKTCadUtility::AddToBlockTableRecord(pAxisLine);
m_idRoadLine = pAxisLine->objectId();
pAxisLine->close();
}
m_pRoadAxisLine->AppendCurveSeg(m_pCurve);
}
return bSuccess;
}
AECStatusRecord* AcISOPolylineJig::GetTailStatusRec() const
{
if (!m_lstStaPtrsBack.IsEmpty())
{
return (AECStatusRecord*)m_lstStaPtrsBack.GetTail();
}
return m_pCurStaRec;
}
AcGeVector3d AcISOPolylineJig::GetLastInterface() const
{
if (m_pRoadAxisLine->GetCurveSegCount() > 0)
{
AECStatusRecord* pRecLast = (AECStatusRecord* )m_lstStaPtrsBack.GetTail();
AcDbCurve* pLast = m_pRoadAxisLine->GetCurveSeg(m_pRoadAxisLine->GetCurveSegCount() - 1);
AcGePoint3d ptLast = pRecLast->GetAcquirePoint();
pLast->getClosestPointTo(ptLast, ptLast);
AcGeVector3d vtLast;
pLast->getFirstDeriv(ptLast,vtLast);
return vtLast;
}
return AcGeVector3d(0, 0, 0);
}
void AcISOPolylineJig::MoveAngWatchPosition()
{
AECStatusRecord* pRec = NULL;
if (m_lstStaPtrsBack.IsEmpty())
return;
pRec = (AECStatusRecord* )m_lstStaPtrsBack.GetTail();
//导航表盘
if (pRec->GetStatusType() >= AECStatusRecord::kAngle &&
pRec->GetStatusType() <= AECStatusRecord::kPoint)
{
AcGePoint3d ptGe,ptGe1;
ptGe = pRec->GetAcquirePoint();
ptGe1 = m_pCurStaRec->GetAcquirePoint();
AcGeVector3d vtDir;
vtDir = m_pISOCrdWatch->m_vtDir;
vtDir = GetLastInterface();
m_pISOCrdWatch->SetAngleWath(ptGe1,ptGe,vtDir);
}
}
BOOL AcISOPolylineJig::AddRoadNode(double dAngle,double dR)
{
if (m_lstStaPtrsBack.IsEmpty())
return FALSE;
if (m_pRoadAxisLine->GetCurveSegCount() > 0)
{
AECStatusRecord* pRecLast = (AECStatusRecord* )m_lstStaPtrsBack.GetTail();
AcDbCurve* pLast = m_pRoadAxisLine->GetCurveSeg(m_pRoadAxisLine->GetCurveSegCount() - 1);
AcGePoint3d ptLast = pRecLast->GetAcquirePoint();
double dB = 0.5 * dAngle;
AcGePoint3d ptSta,ptEnd;
pLast->getStartPoint(ptSta);
pLast->getEndPoint(ptEnd);
AcGePoint3d ptMid = MidPoint(ptSta,ptEnd);
AcGeVector3d vtLast = ptLast - ptMid;
AcGeVector3d vtLast2;
pLast->getFirstDeriv(ptLast,vtLast2);
if (vtLast2.dotProduct(vtLast) < 1.e-10)//反向
vtLast.negate();
AcGeVector3d vtThis = vtLast;
vtThis.rotateBy(dB,AcGeVector3d::kZAxis);
vtThis.normalize();
double dL = 2 * dR * fabs(sin(dB));
AcGePoint3d ptThis = ptLast + vtThis * dL;
if (dB < 1.e-10)
{vtThis.rotateBy(-PI / 2.0 - dB,AcGeVector3d::kZAxis);}
else
{vtThis.rotateBy(PI / 2.0 - dB,AcGeVector3d::kZAxis);}
AcGePoint3d ptCen = ptLast + vtThis * dR;
ptMid = MidPoint(ptLast,ptThis);
AcGeVector3d vtMid = ptMid - ptCen;
vtMid.normalize();
ptMid = ptCen + vtMid * dR;
AcDbArc* pArc = FormatArc(ptLast,ptMid,ptThis);
if (pArc != NULL)
{
m_pArc->setCenter(pArc->center());
m_pArc->setStartAngle(pArc->startAngle());
m_pArc->setEndAngle(pArc->endAngle());
m_pArc->setRadius(pArc->radius());
m_pArc->setNormal(pArc->normal());
m_pCurve = m_pArc;
m_pCurve->setColorIndex(kMagenta);
m_pPolylineProxy->m_pCurve = m_pCurve;
delete pArc;
AecDb3dRoadAxisLine* pAxisLine = NULL;
if (m_idRoadLine.isValid())
{
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,m_idRoadLine,AcDb::kForWrite))
{
pAxisLine = AecDb3dRoadAxisLine::cast(pEnt);
if (pAxisLine != NULL)
{
pAxisLine->AppendCurveSeg(m_pCurve);
}
pEnt->close();
}
}
else
{
pAxisLine = new AecDb3dRoadAxisLine;
pAxisLine->AppendCurveSeg(m_pCurve);
CKTCadUtility::AddToBlockTableRecord(pAxisLine);
m_idRoadLine = pAxisLine->objectId();
pAxisLine->close();
}
//缓存添加本段
m_pRoadAxisLine->AppendCurveSeg(m_pCurve);
return TRUE;
}
}
return FALSE;
}
bool AcISOPolylineJig::GetLastStatusAquire(AcGePoint3d& ptGe)
{
int nSize = (int)m_lstStaPtrsBack.GetCount();
if (nSize > 0)
{
AECStatusRecord* pRecLast = (AECStatusRecord*)m_lstStaPtrsBack.GetTail();
if (pRecLast != NULL)
ptGe = pRecLast->GetAcquirePoint();
return true;
}
return false;
}
AcDbEntity* AcISOPolylineJig::entity() const
{
if (m_lstStaPtrsBack.IsEmpty())
return m_pCurve;
return m_pPolylineProxy;
}
Adesk::Boolean AcISOPolylineJig::update()
{
return Adesk::kTrue;
}
const AecDbObjXDataMap*AcISOPolyline::GetSpecialtyData() const
{
assertReadEnabled();
return &m_mapSpecXData;
}
AecDbObjXDataMap*AcISOPolyline::GetSpecialtyData(AcDb::OpenMode bMode)
{
switch (bMode)
{
case AcDb::kForRead:
{
assertReadEnabled();
break;
}
case AcDb::kForWrite:
{
if (!isWriteEnabled())
{
upgradeOpen();
}
AssertWriteEnabled();
break;
}
case AcDb::kForNotify:
{
assertReadEnabled();
}
default:
break;
}
return &m_mapSpecXData;
}
void AcISOPolylineJig::GetISOCrd(AcGePoint3d &ptPos, AcGeVector3d &vtX, AcGeVector3d &vtY, AcGeVector3d &vtZ)
{
//LAST DIR
GetLastStatusAquire(ptPos);
if (m_pPolylineProxy != NULL)
m_pPolylineProxy->GetISOCrd(vtX, vtY, vtZ);
}
void AcISOPolyline::GetISOCrd(AcGeVector3d &vtX, AcGeVector3d &vtY, AcGeVector3d &vtZ)
{
if (m_pISOCrdWatch != NULL)
{
m_pISOCrdWatch->GetISOCrd(vtX, vtY, vtZ);
}
}
BOOL AcISOPolyline::WriteISOXData(AcDbEntity *pEnt, ISODrawCfg &isodrcfg)
{
/*
typedef struct ISODrawCfg
{
TCHAR m_sODSn[17];
TCHAR m_sMaterial[256];
TCHAR m_sCurrSys[256];
TCHAR m_sScale[17];
TCHAR m_szShtNo[17];
TCHAR m_sStd[256];
double m_dDn;
double m_dOD;
double m_dThk;
double m_dRadio;
double m_dDotWD;
int m_nRadioOn;
int m_nView;
int m_nAngle;
double m_dPipeW;
BOOL m_bElbowLine;
}ISODRAWCFG;
*/
AecDbObjXDataMap xMp;
xMp.SetAt(_T("m_sODSn"), isodrcfg.m_sODSn);
xMp.SetAt(_T("m_sMaterial"), isodrcfg.m_sMaterial);
xMp.SetAt(_T("m_sCurrSys"), isodrcfg.m_sCurrSys);
xMp.SetAt(_T("m_sScale"), isodrcfg.m_sScale);
xMp.SetAt(_T("m_szShtNo"), isodrcfg.m_szShtNo);
xMp.SetAt(_T("m_sStd"), isodrcfg.m_sStd);
xMp.SetAt(_T("m_dDn"), isodrcfg.m_dDn);
xMp.SetAt(_T("m_dOD"), isodrcfg.m_dOD);
xMp.SetAt(_T("m_dThk"), isodrcfg.m_dThk);
xMp.SetAt(_T("m_dRadio"), isodrcfg.m_dRadio);
xMp.SetAt(_T("m_nRadioOn"), isodrcfg.m_nRadioOn);
xMp.SetAt(_T("m_dDotWD"), isodrcfg.m_dDotWD);
xMp.SetAt(_T("m_nView"), isodrcfg.m_nView);
xMp.SetAt(_T("m_nAngle"), isodrcfg.m_nAngle);
xMp.SetAt(_T("m_dPipeW"), isodrcfg.m_dPipeW);
xMp.SetAt(_T("m_bElbowLine"), isodrcfg.m_bElbowLine);
return xMp.Write(pEnt, _T("ISODRCFG"));
}
BOOL AcISOPolyline::ReadISOXData(AcDbEntity *pEnt, ISODrawCfg &isodrcfg)
{
AecDbObjXDataMap xMp;
if (xMp.Read(pEnt, _T("ISODRCFG")))
{
xMp.GetAt(_T("m_sODSn"), isodrcfg.m_sODSn);
xMp.GetAt(_T("m_sMaterial"), isodrcfg.m_sMaterial);
xMp.GetAt(_T("m_sCurrSys"), isodrcfg.m_sCurrSys);
xMp.GetAt(_T("m_sScale"), isodrcfg.m_sScale);
xMp.GetAt(_T("m_szShtNo"), isodrcfg.m_szShtNo);
xMp.GetAt(_T("m_sStd"), isodrcfg.m_sStd);
xMp.GetAt(_T("m_dDn"), isodrcfg.m_dDn);
xMp.GetAt(_T("m_dOD"), isodrcfg.m_dOD);
xMp.GetAt(_T("m_dThk"), isodrcfg.m_dThk);
xMp.GetAt(_T("m_dRadio"), isodrcfg.m_dRadio);
xMp.GetAt(_T("m_nRadioOn"), isodrcfg.m_nRadioOn);
xMp.GetAt(_T("m_nView"), isodrcfg.m_nView);
xMp.GetAt(_T("m_nAngle"), isodrcfg.m_nAngle);
xMp.GetAt(_T("m_dPipeW"), isodrcfg.m_dPipeW);
xMp.GetAt(_T("m_dDotWD"), isodrcfg.m_dDotWD);
xMp.GetAt(_T("m_bElbowLine"), isodrcfg.m_bElbowLine);
return TRUE;
}
return FALSE;
}