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

1318 lines
27 KiB
C++

#include "stdafx.h"
#include "AecDb3dRoad.h"
#include "dbgrip.h"
#include "AecGripCback.h"
#include "KTCADUtilityEx.h"
#include "AecComplexCurveDraw.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 bool GetSamplePoints(AcDbCurve* pSubCrv,double dFitLen,AcGePoint3dArray& arSubPts);
extern BOOL Is2DView();
extern AcGeVector3d GetUcsZvt();
extern void PushGripMessage(GripMessage&);
extern double PixelToWcs(int nPixel);
double g_RoadDivLen = 40.0;//毫米
Adesk::UInt32 AecDb3dRoad::kCurrentVersionNumber = 1;
static void FreeBuffer(int n,AcDbVoidPtrArray& arEntPtrs)
{
AcDbEntity* pEnt = NULL;
while(arEntPtrs.length() > n )
{
pEnt = (AcDbEntity*)arEntPtrs.last();
if (pEnt != NULL)
{
pEnt->erase();
pEnt->close();
arEntPtrs.removeLast();
DELETE_PTR(pEnt);
}
}
}
double AsOtherUnit(double dMM)
{
struct resbuf rb;
acedGetVar(_T("INSUNITS"),&rb);
int nOther = rb.resval.rint;
if (nOther == AcDb::kUnitsMillimeters)//毫米
{
}
else if (nOther == AcDb::kUnitsCentimeters)//厘米单位
{
dMM *= 0.1;
}
else if (nOther == AcDb::kUnitsDecimeters)//分米单位
{
dMM *= 0.01;
}
else if (nOther == AcDb::kUnitsUndefined)//无单位
{
}
else if (nOther == AcDb::kUnitsMeters)
{
dMM *= 0.001;
}
return dMM;
}
ACRX_DXF_DEFINE_MEMBERS(AecDb3dRoad, AecDbCurveBase,
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning,
AEC_3DROAD,
"AecDb3dRoad"
"|Product Desc: shanghua earthworm app obj"
"|Company: shanghua inc"
"|WEB Address: www.shanghuasoft.com")
AecDb3dRoad::AecDb3dRoad(void)
{
m_mapSpecXData.SetAt(KEY_NAME,_T("道路"));
m_pGripAppData = new AecGripData[17];
}
AecDb3dRoad::~AecDb3dRoad(void)
{
delete [] m_pGripAppData;
}
void AecDb3dRoad::SetRoadParam(WPipe::RoadParam* pParam)
{
AssertWriteEnabled();
/*
typedef struct RoadParam
{
double dCar2W; //中间2车道宽
double dRRatio; //道路曲率半径,弯头,三四通
double dThick; //路厚度,经验数值
double dGrade; //路面横坡度1.5-2.5%
}ROADPARAM;
*/
if (pParam != NULL)
{
m_mapSpecXData.SetAt(KEY_W,pParam->dSize[0]);
m_mapSpecXData.SetAt(KEY_RAD,pParam->dRRatio);
m_mapSpecXData.SetAt(KEY_THICK,pParam->dThick);
m_mapSpecXData.SetAt(KEY_GRAD,pParam->dGrade);
m_mapSpecXData.SetAt(PIPE_SPEC,pParam->szSpec);
m_mapSpecXData.SetAt(KEY_CENDRAW,pParam->nDrawCen);
}
}
bool AecDb3dRoad::GetRoadParam(WPipe::RoadParam& rp) const
{
assertReadEnabled();
memset(&rp,0,sizeof(WPipe::RoadParam));
BOOL bRelt = m_mapSpecXData.GetAt(KEY_W,rp.dSize[0]);
m_mapSpecXData.GetAt(KEY_RAD,rp.dRRatio);
m_mapSpecXData.GetAt(KEY_THICK,rp.dThick);
m_mapSpecXData.GetAt(KEY_GRAD,rp.dGrade);
m_mapSpecXData.GetAt(KEY_CENDRAW,rp.nDrawCen);
CString sTemp;
m_mapSpecXData.GetAt(PIPE_SPEC,sTemp);
_tcscpy(rp.szSpec,sTemp);
rp.m_dEl = m_elBaseCrv.ptGe[0].z;
rp.m_nAlign = 1;
return bRelt ? true : false;
}
Acad::ErrorStatus AecDb3dRoad::SetCurveSeg(const AecEqui::AecCurveElement& el)
{
AssertWriteEnabled();
memcpy(&m_elBaseCrv,&el,sizeof(AecEqui::AecCurveElement));
return Acad::eOk;
}
bool AecDb3dRoad::GetCurveSeg(AecEqui::AecCurveElement& el) const
{
assertReadEnabled();
memcpy(&el,&m_elBaseCrv,sizeof(AecEqui::AecCurveElement));
return true;
}
Acad::ErrorStatus AecDb3dRoad::SetCurveSeg(const AcGePoint3d& ptS,const AcGePoint3d& ptE)
{
AssertWriteEnabled();
m_elBaseCrv.ptGe[0] = ptS;
m_elBaseCrv.ptGe[1] = ptE;
m_elBaseCrv.ptGe[2] = ptE;
return Acad::eOk;
}
int AecDb3dRoad::GetCurveSegType() const
{
assertReadEnabled();
int nType = AecComplexCurve::GetElementType(m_elBaseCrv);
return nType;
}
AcGePoint3d AecDb3dRoad::EndPoint() const
{
assertReadEnabled();
return m_elBaseCrv.ptGe[2];
}
Acad::ErrorStatus AecDb3dRoad::SetEndPoint(const AcGePoint3d& ptEnd)
{
AssertWriteEnabled();
int nType = AecComplexCurve::GetElementType(m_elBaseCrv);
m_elBaseCrv.ptGe[2] = ptEnd;
if (nType == (int)AecEqui::eLine)
{
m_elBaseCrv.ptGe[1] = ptEnd;
}
return Acad::eOk;
}
//获取首尾切线方向[接口方向]
AcGeVector3d AecDb3dRoad::GetHeadDir() const
{
assertReadEnabled();
AcGeVector3d vtDir = AcGeVector3d::kXAxis;
AcDbCurve* pBase = GetBaseCurve(false);
if (pBase != NULL)
{
double dSta = 0.0;
pBase->getStartParam(dSta);
pBase->getFirstDeriv(dSta,vtDir);
delete pBase;
}
return vtDir;
}
AcGeVector3d AecDb3dRoad::GetTailDir() const
{
assertReadEnabled();
AcGeVector3d vtDir = AcGeVector3d::kXAxis;
AcDbCurve* pBase = GetBaseCurve(false);
if (pBase != NULL)
{
double dSta = 0.0;
pBase->getEndParam(dSta);
pBase->getFirstDeriv(dSta,vtDir);
delete pBase;
}
return vtDir;
}
Acad::ErrorStatus AecDb3dRoad::SetStartPoint(const AcGePoint3d& ptSta)
{
AssertWriteEnabled();
m_elBaseCrv.ptGe[0] = ptSta;
return Acad::eOk;
}
AcGePoint3d AecDb3dRoad::StartPoint() const
{
assertReadEnabled();
return m_elBaseCrv.ptGe[0];
}
Acad::ErrorStatus AecDb3dRoad::dwgInFields(AcDbDwgFiler* pFiler)
{
AssertWriteEnabled();
//----- Read parent class information first.
Acad::ErrorStatus es = AecDbCurveBase::dwgInFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
//----- Object version number needs to be read first
Adesk::UInt32 version =0 ;
if ( (es =pFiler->readUInt32 (&version)) != Acad::eOk )
return (es) ;
if ( version > AecDb3dRoad::kCurrentVersionNumber )
return (Acad::eMakeMeProxy);
m_mapSpecXData.dwgInFields(pFiler);
pFiler->readPoint3d(&m_elBaseCrv.ptGe[0]);
pFiler->readPoint3d(&m_elBaseCrv.ptGe[1]);
pFiler->readPoint3d(&m_elBaseCrv.ptGe[2]);
Adesk::Int16 bHided = 0;
pFiler->readInt16(&bHided);
m_elBaseCrv.bHided = bHided;
Adesk::Int32 nGsmark = 0;
pFiler->readInt32(&nGsmark);
m_elBaseCrv.gsMark = nGsmark;
pFiler->readDouble(&m_elBaseCrv.dWidth);
return pFiler->filerStatus();
}
Acad::ErrorStatus AecDb3dRoad::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
//----- Save parent class information first.
Acad::ErrorStatus es = AecDbCurveBase::dwgOutFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
//----- Object version number needs to be saved first
if ( (es =pFiler->writeUInt32 (AecDb3dRoad::kCurrentVersionNumber)) != Acad::eOk )
return (es) ;
m_mapSpecXData.dwgOutFields(pFiler);
pFiler->writePoint3d(m_elBaseCrv.ptGe[0]);
pFiler->writePoint3d(m_elBaseCrv.ptGe[1]);
pFiler->writePoint3d(m_elBaseCrv.ptGe[2]);
pFiler->writeInt16(m_elBaseCrv.bHided);
pFiler->writeInt32(m_elBaseCrv.gsMark);
pFiler->writeDouble(m_elBaseCrv.dWidth);
return pFiler->filerStatus();
}
Acad::ErrorStatus AecDb3dRoad::dxfInFields(AcDbDxfFiler* pFiler)
{
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoad::dxfOutFields(AcDbDxfFiler* pFiler) const
{
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoad::copyFrom(const AcRxObject* pSrc)
{
AssertWriteEnabled();
AecDb3dRoad* pRoad = AecDb3dRoad::cast(pSrc);
if (pRoad != NULL)
{
m_mapSpecXData.Empty();
m_mapSpecXData.CopyFrom(&pRoad->m_mapSpecXData);
m_elBaseCrv = pRoad->m_elBaseCrv;
}
return Acad::eOk;
}
#if ARX>16
void AecDb3dRoad::subList() const
{
assertReadEnabled();
AecDbCurveBase::subList();
acutPrintf(_T("\n道路样线:"));
AcDbCurve* pBase = GetNativeCurve();
if (pBase != NULL)
{
#ifndef ZWCAD
pBase->list();
#endif
}
m_mapSpecXData.List();
}
bool AecDb3dRoad::GetBimInfoTip(CString& sInfoTip) const
{
assertReadEnabled();
CString sField,sFmt;
WPipe::RoadParam rp;
memset(&rp,0,sizeof(WPipe::RoadParam));
GetRoadParam(rp);
sField = _T("道路:\n");
sInfoTip += sField;
double dE = 0,dL = 0;
AcDbCurve* pBase = GetNativeCurve();
if (pBase != NULL)
{
pBase->getEndParam(dE);
pBase->getDistAtParam(dE,dL);
}
MAKEFIELD(_T("长度"),_T("%.1f 米"),dL/1000.0,sInfoTip);
MAKEFIELD(_T("面积"),_T("%.1f 平方"),GetArea() / 1.e6,sInfoTip);
MAKEFIELD(_T("路宽"),_T("%.1f 米"),rp.dSize[0] / 1000.0,sInfoTip);
MAKEFIELD(_T("曲率"),_T("%.1f "),rp.dRRatio,sInfoTip);
MAKEFIELD(_T("路面横坡度"),_T("%.1f "),rp.dGrade,sInfoTip);
MAKEFIELD(_T("标高"),_T("%.1f 米"),rp.m_dEl / 1000.0,sInfoTip);
return true;
}
Acad::ErrorStatus AecDb3dRoad::subTransformBy(const AcGeMatrix3d& xform)
{
AssertWriteEnabled();
m_elBaseCrv.ptGe[0].transformBy(xform);
m_elBaseCrv.ptGe[1].transformBy(xform);
m_elBaseCrv.ptGe[2].transformBy(xform);
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoad::subGetGripPoints( AcDbGripDataPtrArray& grips,
const double curViewUnitSize,
const int gripSize,
const AcGeVector3d& curViewDir,
const int bitflags) const
{
assertReadEnabled();
AcGePoint3dArray gripPoints;
ImpGetGripPonts(gripPoints,bitflags);
int nColor = kWhite;
AcDbGripData* pGripData = NULL;
CString sCmd = GetGripCmd();//绘制管道
EPosition ePos;
for (int i = 0;i < GRIP_MAXNUM && i < gripPoints.length();i++)
{
ePos = ExplainGripIndex(i);
if (ePos >= eCommand0 && ePos <= eCommand19)
{
memset(&m_pGripAppData[i],0,sizeof(AecGripData));
m_pGripAppData[i].nIndex = i;
m_pGripAppData[i].ePos = ePos;
m_pGripAppData[i].nColor = nColor;
m_pGripAppData[i].ptGrip = gripPoints.at(i);
_tcscpy(m_pGripAppData[i].szTip,sCmd);
_tcscpy(m_pGripAppData[i].szID,_T(""));
m_pGripAppData[i].pOwner = (AcDbEntity*)this;
m_pGripAppData[i].idHost = this->objectId();
pGripData = new AcDbGripData;
pGripData->setGripPoint(gripPoints.at(i));
pGripData->setAppData((void*)&m_pGripAppData[i]);
pGripData->setWorldDraw(AecGripCback::WorldDrawfunc);
pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc);
}
else
{
memset(&m_pGripAppData[i],0,sizeof(AecGripData));
m_pGripAppData[i].nIndex = i;
m_pGripAppData[i].ePos = ePos;
m_pGripAppData[i].nColor = nColor;
m_pGripAppData[i].ptGrip = gripPoints.at(i);
_tcscpy(m_pGripAppData[i].szTip,_T("道路拉伸夹点"));
_tcscpy(m_pGripAppData[i].szID,_T(""));
m_pGripAppData[i].pOwner = (AcDbEntity*)this;
m_pGripAppData[i].idHost = this->objectId();
pGripData = new AcDbGripData;
pGripData->setGripPoint(gripPoints.at(i));
pGripData->setAppData((void*)&m_pGripAppData[i]);
pGripData->setWorldDraw(AecGripCback::WorldDrawfunc);
pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc);
}
grips.append(pGripData);
}
//动态标注
//直线,半径 标注风格
//if (!grips.isEmpty())
//{
// SubAddDimPoints(grips,curViewDir);
//}
return Acad::eOk;
}
EPosition AecDb3dRoad::ExplainGripIndex(int nIndex) const
{
EPosition ePos = eStart;
switch(nIndex)
{
case 0:
{
ePos = eStart;
break;
}
case 1:
{
ePos = eMid;
break;
}
case 2:
{
ePos = eEnd;
break;
}
case 3:
{
ePos = eCommand0;
break;
}
case 4:
{
ePos = eCommand1;
break;
}
case 5:
{
ePos = eCommand2;
break;
}
default:
break;
}
return ePos;
}
Acad::ErrorStatus AecDb3dRoad::ImpGetGripPonts(AcGePoint3dArray& gripPoints,const int bitflags) const
{
assertReadEnabled();
AcDbCurve* pBaseCurve = GetNativeCurve();
if (pBaseCurve != NULL)
{
AcGePoint3d ptSta,ptEnd;
pBaseCurve->getStartPoint(ptSta);
pBaseCurve->getEndPoint(ptEnd);
double dSta = 0.0,dEnd = 0.0;
pBaseCurve->getStartParam(dSta);
pBaseCurve->getEndParam(dEnd);
AcGeVector3d vtDir = ptEnd - ptSta;
vtDir.normalize();
AcGePoint3d ptMid;
pBaseCurve->getPointAtParam((dSta + dEnd) / 2.0,ptMid);
gripPoints.append(ptSta);
gripPoints.append(ptMid);
gripPoints.append(ptEnd);
//按 15 个像素点
double dCmd = PixelToWcs(15);
AcGePoint3d ptCmd[3]; //Cmd 0,1
AcGeVector3d vtS,vtE,vtM;
pBaseCurve->getFirstDeriv(ptSta,vtS);
pBaseCurve->getFirstDeriv(ptEnd,vtE);
pBaseCurve->getFirstDeriv(ptMid,vtM);
vtS.normalize();vtS.negate();
vtE.normalize();
vtM.normalize();
vtM.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
ptCmd[0] = ptSta - dCmd * vtS;
ptCmd[1] = ptEnd + dCmd * vtE;
ptCmd[2] = ptMid + dCmd * vtM;
gripPoints.append(ptCmd[0]);
gripPoints.append(ptCmd[1]);
gripPoints.append(ptCmd[2]);
}
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoad::subMoveGripPointsAt(const AcDbVoidPtrArray& gripAppData, const AcGeVector3d& offset, const int bitflags)
{
AssertWriteEnabled();
AecGripData* pAppData = NULL;
AcDbIntArray arIndex;
if ( !gripAppData.isEmpty() )
{
pAppData = (AecGripData*)gripAppData.first();
arIndex.append(pAppData->nIndex);
}
else
{
return Acad::eOk;
}
int nGripIndex = arIndex.first();
EPosition ePos = ExplainGripIndex(nGripIndex);
AecInterface inf;
GripMessage msg;
memset(&msg,0,sizeof(GripMessage));
//reset
msg.nSegindex = -1;
msg.nType = -1;
msg.idHost.setNull();
msg.pParam = 0;
msg.nData = -1;
_tcscpy(msg.szLockId, _T("0"));//锁定id,如果有
msg.fData = 0;
msg.nSegindex = 0;
msg.nSubSegIndex = 0;
msg.vtOffset.set(0,0,0);
msg.ptGrip.set(0,0,0);
bool bMsgSendToAllInfs = false;
AcGeVector3d vtOffset = offset;
if(Is2DView())//如果是2D视图
{
//投影到XY
vtOffset = offset.orthoProject(GetUcsZvt());
AcDbCurve* pBaseCurve = GetBaseCurve(false);
AcDbLine* pLn = AcDbLine::cast(pBaseCurve);
if (pLn != NULL)
{
//小于10度的按照投影处理
//在夹角小于10度,认为是橡皮筋拉伸
AcGeVector3d vtLn = pLn->endPoint() - pLn->startPoint();
if (ePos == eStart || ePos == eEnd)
{
double dAngle = vtOffset.angleTo(vtLn);
dAngle *= 180.0 / PI;
//acutPrintf(_T("\nAngle = %g"),dAngle);
if ( ( (dAngle - 10.0 ) < 1.e-6 ) ||
( (180.0 - dAngle - 10.0 ) < 1.e-6) )
{
//认为是橡皮筋拉伸
AcGeVector3d vtNorm = vtLn;
vtNorm.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGeVector3d vtOffsetOnLn = vtOffset.orthoProject(vtNorm);
vtOffsetOnLn.normalize();
vtOffsetOnLn *= vtOffset.length();
vtOffset = vtOffsetOnLn;
//仅仅本端口
bMsgSendToAllInfs = false;
}
else
{
bMsgSendToAllInfs = true;
}
}
else if (ePos == eMid)
{
AcGeVector3d vtNorm = vtLn;
vtLn.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
double dAngle = vtOffset.angleTo(vtLn);
dAngle *= 180.0 / PI;
//acutPrintf(_T("\nAngle = %g"),dAngle);
if ( ( (dAngle - 10.0 ) < 1.e-6 ) ||
( (180.0 - dAngle - 10.0 ) < 1.e-6) )
{
//认为是橡皮筋拉伸
AcGeVector3d vtOffsetOnLn = vtOffset.orthoProject(vtNorm);
vtOffsetOnLn.normalize();
vtOffsetOnLn *= vtOffset.length();
vtOffset = vtOffsetOnLn;
}
}
}
if (pBaseCurve != NULL)
delete pBaseCurve;
}
AcGeMatrix3d xformM;
xformM.setToTranslation(vtOffset);
switch (ePos)
{
case eStart:
{
TransformAssocInf(0,xformM);
msg.nType = ePos;
msg.nData = bMsgSendToAllInfs ? -1 : 0;//控制消息源
msg.idHost = pAppData->idHost;
msg.vtOffset = vtOffset;
PushGripMessage(msg);
break;
}
case eEnd:
{
TransformAssocInf(1,xformM);
msg.nType = ePos;
msg.nData = bMsgSendToAllInfs ? -1 : 1;//控制消息源
msg.idHost = pAppData->idHost;
msg.vtOffset = vtOffset;
PushGripMessage(msg);
break;
}
case eMid:
{
TransformBy(xformM);
msg.nType = ePos;
msg.nData = -1;
msg.idHost = pAppData->idHost;
msg.vtOffset = vtOffset;
PushGripMessage(msg);
break;
}
case eCommand0:
{
msg.nType = eCommand0;
msg.nData = 0;
GetInterface(msg.nData,inf);
msg.ptGrip = inf.ptPos;
msg.idHost = pAppData->idHost;
msg.vtOffset = vtOffset;
PushGripMessage(msg);
CString sCmd = GetGripCmd();
if (!sCmd.IsEmpty())
{
acedPostCommand(_T("\x03"));
sCmd += _T("\n");
acedPostCommand(sCmd);
}
break;
}
case eCommand1:
{
msg.nType = eCommand1;
msg.nData = 1;
GetInterface(msg.nData,inf);
msg.ptGrip = inf.ptPos;
msg.idHost = pAppData->idHost;
msg.vtOffset = vtOffset;
PushGripMessage(msg);
CString sCmd = GetGripCmd();
if (!sCmd.IsEmpty())
{
acedPostCommand(_T("\x03"));
sCmd += _T("\n");
acedPostCommand(sCmd);
}
break;
}
case eCommand2:
{
msg.nType = eCommand0;
msg.nData = 0;//按0接口
msg.ptGrip = pAppData->ptGrip;
msg.idHost = pAppData->idHost;
msg.vtOffset = vtOffset;
PushGripMessage(msg);
CString sCmd = GetGripCmd();
if (!sCmd.IsEmpty())
{
acedPostCommand(_T("\x03"));
sCmd += _T("\n");
acedPostCommand(sCmd);
}
break;
}
default:
break;
}
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoad::TransformBy(const AcGeMatrix3d xform)
{
AssertWriteEnabled();
m_elBaseCrv.ptGe[0].transformBy(xform);
m_elBaseCrv.ptGe[1].transformBy(xform);
m_elBaseCrv.ptGe[2].transformBy(xform);
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoad::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const
{
assertReadEnabled();
ImpGetGripPonts(stretchPoints,0);
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoad::subMoveStretchPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset)
{
AssertWriteEnabled();
int nSize = indices.length();
if (nSize == 1)
{
int nIndex = indices.first();
if (nIndex == 0)//Sta
{
m_elBaseCrv.ptGe[0] += offset;
}
else if (nIndex == 1)//Mid
{
m_elBaseCrv.ptGe[0] += offset;
m_elBaseCrv.ptGe[1] += offset;
m_elBaseCrv.ptGe[2] += offset;
}
else
{
m_elBaseCrv.ptGe[2] += offset;
}
}
else if (nSize > 1)
{
m_elBaseCrv.ptGe[0] += offset;
m_elBaseCrv.ptGe[1] += offset;
m_elBaseCrv.ptGe[2] += offset;
}
return Acad::eOk;
}
void AecDb3dRoad::GetGripText(int nPos, CString& sText)
{
sText = _T("夹点");
}
#endif
AcDbCurve* AecDb3dRoad::GetBaseCurve(bool bOrthoProjectToXY/* = false*/) const
{
assertReadEnabled();
AcDbCurve* pBaseCurve = NULL;
if ( AecComplexCurve::MakeCurve(m_elBaseCrv,pBaseCurve) )
{
if (pBaseCurve != NULL)
{
if (bOrthoProjectToXY)
{
AcDbCurve* pProj = NULL;
pBaseCurve->getOrthoProjectedCurve(AcGePlane::kXYPlane,pProj);
delete pBaseCurve;
return pProj;
}
return pBaseCurve;
}
}
return NULL;
}
AcDbCurve* AecDb3dRoad::GetNativeCurve() const
{
assertReadEnabled();
AcDbCurve* pBaseCurve = NULL;
if ( AecComplexCurve::MakeCurve(m_elBaseCrv,pBaseCurve) )
{
//...
}
return pBaseCurve;
}
Acad::ErrorStatus AecDb3dRoad::Draw2d(AcGiDraw &dc) const
{
assertReadEnabled();
//管线系统屏蔽掉
if ( dc.IsDragging() )
{
//return Acad::eOk;
}
AcDbObjectId idCurLay = dc.GetLayerId();
AcDbObjectId idCurLty = dc.GetLineTypeId();
Adesk::UInt16 nCrBk = colorIndex();
AcDbObjectId idLn = linetypeId();
AcDbObjectId idLay = layerId();
if (Has2DBuffer())
{
AcDbEntity* pEnt = NULL;
const AcDbVoidPtrArray &ar2D = Get2DBuffer();
for (int i = 0;i < ar2D.length();i++)
{
pEnt = (AcDbEntity*)ar2D.at(i);
dc.SetLineType(idLn);
dc.SetLayer(idLay);
dc.DrawEntity(*pEnt);
}
dc.SetLayer(idCurLay);
dc.SetLineType(idCurLty);
return Acad::eOk;
}
AcDbCurve* pBaseCurve = GetBaseCurve(false);
if (pBaseCurve != NULL)
{
//submesh
WPipe::RoadParam rp;
memset(&rp,0,sizeof(WPipe::RoadParam));
if ( GetRoadParam(rp) )
{
AcDbVoidPtrArray off1,off2;
pBaseCurve->getOffsetCurves( 0.5 * rp.dSize[0],off1);
pBaseCurve->getOffsetCurves(-0.5 * rp.dSize[0],off2);
if (off1.length() == 1 && off2.length() == 1)
{
AcDbCurve* pLeft = (AcDbCurve*)((AcDbCurve*)off1.first())->clone();
AcDbCurve* pRight = (AcDbCurve*)((AcDbCurve*)off2.first())->clone();
if (pLeft != NULL && pRight != NULL)
{
pLeft->setLayer(idLay);
pRight->setLayer(idLay);
//边线
dc.DrawEntity(pLeft);
dc.DrawEntity(pRight);
Add2DBuffer(pLeft);
Add2DBuffer(pRight);
}
}
else
{
//...
}
FreeBuffer(0,off1);
FreeBuffer(0,off2);
}
if (rp.nDrawCen)
{
pBaseCurve->setLayer(idLay);
pBaseCurve->setLinetype(KTSetting::InitLineStyle(_T("CENTER")));
dc.DrawEntity(pBaseCurve);
Add2DBuffer(pBaseCurve);
}
else
{
delete pBaseCurve;
}
}
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoad::Draw3d(AcGiDraw &dc) const
{
assertReadEnabled();
//管线系统屏蔽掉
if ( dc.IsDragging() )
{
//return Acad::eOk;
}
AcDbObjectId idCurLay = dc.GetLayerId();
AcDbObjectId idCurLty = dc.GetLineTypeId();
Adesk::UInt16 nCrBk = colorIndex();
if (Has3DBuffer())
{
AcDbObjectId idLn = linetypeId();
AcDbObjectId idLay = layerId();
AcDbEntity* pEnt = NULL;
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pEnt = (AcDbEntity*)ar3D.at(i);
dc.SetLineType(idLn);
dc.SetLayer(idLay);
dc.DrawEntity(*pEnt);
}
dc.SetLayer(idCurLay);
dc.SetLineType(idCurLty);
return Acad::eOk;
}
AcDbCurve* pBaseCurve = GetBaseCurve(false);
if (pBaseCurve != NULL)
{
//submesh
WPipe::RoadParam rp;
memset(&rp,0,sizeof(WPipe::RoadParam));
if ( GetRoadParam(rp) )
{
AcDbVoidPtrArray off1,off2;
pBaseCurve->getOffsetCurves( 0.5 * rp.dSize[0],off1);
pBaseCurve->getOffsetCurves(-0.5 * rp.dSize[0],off2);
if (off1.length() == 1 && off2.length() == 1)
{
AcDbCurve* pLeft = (AcDbCurve*)off1.first();
AcDbCurve* pRight = (AcDbCurve*)off2.first();
if (pLeft != NULL && pRight != NULL)
{
AcDbRegion* pReg = NULL;
AcGePoint3d ptS[2],ptE[2];
pLeft->getStartPoint(ptS[0]);
pRight->getStartPoint(ptS[1]);
pLeft->getEndPoint(ptE[0]);
pRight->getEndPoint(ptE[1]);
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
AcDbLine* pLn1 = new AcDbLine(ptS[0],ptS[1]);
arCurPtrs.append(pLn1);
pLn1 = new AcDbLine(ptE[0],ptE[1]);
arCurPtrs.append(pLn1);
arCurPtrs.append(pLeft);
arCurPtrs.append(pRight);
AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (!arRegPtrs.isEmpty())
{
pReg = (AcDbRegion*)arRegPtrs.first();
dc.DrawEntity(pReg);
Add3DBuffer(pReg);
}
DrawRoadBordLine(dc,pLeft,kWhite,0,rp.m_dEl);
DrawRoadBordLine(dc,pRight,kWhite,0,rp.m_dEl);
DrawRoadBordLine(dc,pBaseCurve,kYellow,1,rp.m_dEl);//虚线
}
}
else
{
//...
}
FreeBuffer(0,off1);
FreeBuffer(0,off2);
}
delete pBaseCurve;
}
return Acad::eOk;
}
void AecDb3dRoad::DrawRoadBordLine(AcGiDraw &dc,AcDbCurve* pCurve,int nColor,BOOL bIsDash,double dEl) const
{
double dW = 200.0;//100毫米宽
dW = AsOtherUnit(dW);
if ( pCurve != NULL)
{
AcDbVoidPtrArray arCurPtrs,arRelt;
arCurPtrs.append(pCurve);
AcDbCurve* pPlCr = KTCADUtilityEx::ConvertBoundCurve(arCurPtrs,arRelt);
if (pPlCr != NULL)
{
AcDbPolyline* pPl = AcDbPolyline::cast(pPlCr);
if (pPl != NULL)
{
pPl->setConstantWidth(dW);
pPl->setColorIndex(nColor);
pPl->setElevation(dEl);
if (bIsDash)
{
pPl->setLinetype(KTSetting::InitLineStyle(_T("DASHED")));
pPl->setLinetypeScale(.1);
pPl->setElevation(dEl);
}
dc.DrawEntity(pPl);
Add3DBuffer(pPl);
}
}
}
}
BOOL AecDb3dRoad::DrawMesh(AcGiDraw &mode,const Adesk::UInt32 rows,const Adesk::UInt32 columns,const AcGePoint3d* pVertexList) const
{
AcGePoint3dArray vertexArray;
AcArray<Adesk::Int32> faceArray;
int nV0 = 0,nV1 = 0,nV2 = 0;
int nV3= 0;
int nFaceIndex = 0;
AcGePoint3d ptFace[4];
for (int i = 0;i < rows - 1;i++)
{
for (int j = 0;j < columns - 1;j++)
{
nV0 = i * columns + j;
nV1 = nV0 + 1;
//第二行,第一个
nV2 = (i + 1) * columns + j;
nV3 = nV2 + 1;
//三角:nV0-nV1-nV2
faceArray.append(3);
faceArray.append(nV0);//v0
faceArray.append(nV1);//v1
faceArray.append(nV2);//v2
ptFace[0] = pVertexList[nV0];
ptFace[1] = pVertexList[nV1];
ptFace[2] = pVertexList[nV2];
ptFace[3] = ptFace[0];
//TEST
//mode.DrawFace(ptFace);
//三角:nV2-nV1-nV3
faceArray.append(3);
faceArray.append(nV2);//v2
faceArray.append(nV1);//v1
faceArray.append(nV3);//v3
ptFace[0] = pVertexList[nV2];
ptFace[1] = pVertexList[nV1];
ptFace[2] = pVertexList[nV3];
ptFace[3] = ptFace[0];
//TEST
//mode.DrawFace(ptFace);
}
}
if (!faceArray.isEmpty())
{
int nIndex = 0;
for (int i = 0;i < rows;i++)
{
for (int j = 0;j < columns;j++)
{
nIndex = i * columns + j;
vertexArray.append(pVertexList[nIndex]);
}
}
AcDbSubDMesh* pSubMesh = new AcDbSubDMesh;
if ( Acad::eOk == pSubMesh->setSubDMesh(vertexArray,faceArray,0) )
{
mode.DrawEntity(pSubMesh);
Add3DBuffer(pSubMesh);
return TRUE;
}
delete pSubMesh;
}
return FALSE;
}
bool AecDb3dRoad::TransformAssocInf(int nInf,const AcGeMatrix3d& xform)
{
AssertWriteEnabled();
AcGeVector3d vtL = m_elBaseCrv.ptGe[1] - m_elBaseCrv.ptGe[0];
AcGeVector3d vtL2;
int nType = GetCurveSegType();
if (nInf == 0)
{
m_elBaseCrv.ptGe[0].transformBy(xform);
if (nType == AecEqui::eLine)
{
vtL2 = m_elBaseCrv.ptGe[1] - m_elBaseCrv.ptGe[0];
if (!vtL2.isParallelTo(vtL))
{
m_elBaseCrv.ptGe[1].transformBy(xform);
m_elBaseCrv.ptGe[2] = m_elBaseCrv.ptGe[1];
return true;
}
return false;
}
else
{
return false;//ARC作为截至Fit不发送消息
}
}
else if (nInf == 1)//End
{
if (nType == AecEqui::eLine)
{
m_elBaseCrv.ptGe[1].transformBy(xform);
m_elBaseCrv.ptGe[2].transformBy(xform);
vtL2 = m_elBaseCrv.ptGe[1] - m_elBaseCrv.ptGe[0];
if (!vtL2.isParallelTo(vtL))
{
m_elBaseCrv.ptGe[0].transformBy(xform);
return true;
}
return false;
}
else
{
m_elBaseCrv.ptGe[2].transformBy(xform);
return false;//ARC作为截至Fit不发送消息
}
}
else
{
m_elBaseCrv.ptGe[0].transformBy(xform);
m_elBaseCrv.ptGe[1].transformBy(xform);
m_elBaseCrv.ptGe[2].transformBy(xform);
return true;//继续发消息
}
return false;//不再继续发消息
}
LPCTSTR AecDb3dRoad::GetGripCmd() const
{
assertReadEnabled();
return _T("sp_roadadd");
}
AecDbObjXDataMap* AecDb3dRoad::GetSpecialtyData(AcDb::OpenMode bMode/* = AcDb::kForWrite*/)
{
switch (bMode)
{
case AcDb::kForRead:
{
assertReadEnabled();
break;
}
case AcDb::kForWrite:
{
if (!isWriteEnabled())
{
upgradeOpen();
}
assertWriteEnabled();
break;
}
case AcDb::kForNotify:
{
assertReadEnabled();
}
default:
break;
}
return &m_mapSpecXData;
}
const AecDbObjXDataMap* AecDb3dRoad::GetSpecialtyData() const
{
return &m_mapSpecXData;
}
bool AecDb3dRoad::GetInterface(AcArray<AecInterface>& arInfs) const
{
assertReadEnabled();
AcDbCurve* pBaseCurve = GetBaseCurve();
if (pBaseCurve != NULL)
{
AcGePoint3d ptSta,ptEnd;
ptSta = StartPoint();
ptEnd = EndPoint();
AcGeVector3d vtSta,vtEnd;
pBaseCurve->getFirstDeriv(ptSta,vtSta);
vtSta.negate();//向外
pBaseCurve->getFirstDeriv(ptEnd,vtEnd);
WPipe::RoadParam rp;
GetRoadParam(rp);
AecInterface inf;
inf.idOwner = objectId();
inf.dSize1 = rp.dSize[0];
inf.dSize2 = rp.dSize[0];
inf.ptPos = ptSta;
inf.vtDir = vtSta;
inf.nLevel = 0;
inf.dGasket = 0;
arInfs.append(inf);
inf.ptPos = ptEnd;
inf.vtDir = vtEnd;
inf.nLevel = 1;
inf.dGasket = 0;
arInfs.append(inf);
return true;
}
return false;
}
bool AecDb3dRoad::GetInterface(int nIndex,AecInterface& inf) const
{
assertReadEnabled();
AcArray<AecInterface> arInfs;
GetInterface(arInfs);
if (nIndex > -1 && nIndex < arInfs.length())
{
inf = arInfs.at(nIndex);
return true;
}
return false;
}
int AecDb3dRoad::GetInterfaceCount() const
{
assertReadEnabled();
AcArray<AecInterface> arInfs;
GetInterface(arInfs);
return arInfs.length();
}
int AecDb3dRoad::GetActiveInf() const
{
return 0;
}
void AecDb3dRoad::SetActiveInf(int nIndex)
{
}
void AecDb3dRoad::LockInf(int nInf)
{
}