Files
envi-code/SourceCode/Code2026/CoreLibrary/AecDbPortRoom.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1749 lines
41 KiB
C++

#include "stdafx.h"
#include "AecDbPortRoom.h"
#include "AecDbEarthWorm.h"
#include "AcGiViewDraw.h"
#include "AcGiExplodeDraw.h"
#include "KTCADUtilityEx.h"
#include "KTCadUtility.h"
#include "AecUnknownWorldDraw.h"
#include <vector>
#include <algorithm>
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 AcGePoint3d MidPoint(const AcGePoint3d& pt1,const AcGePoint3d& pt2);
extern Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt,AcDbDatabase* pDb = NULL,bool bClose = true);
extern bool WriteXData(AcDbEntity* pEnt,const EWFnctNode* pNode);
Adesk::UInt32 AecDbPortRoom::kCurrentVersionNumber = 1;
ACRX_DXF_DEFINE_MEMBERS (AecDbPortRoom, AecDbEntityBase,
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning,
AEC_PORTROOM,
"AecDbPortRoom"
"|Product Desc: shanghua earthworm app obj"
"|Company: shanghua inc"
"|WEB Address: www.shanghuasoft.com")
AecDbPortRoom::AecDbPortRoom(void)
{
m_nSegIndex = -1; //所在seg位置
m_nOnFncNodeIndex = -1; //子节点位置
memset(&m_fncNode,0,sizeof(EWFnctNode));
m_bShareDoubleHouse = false;
}
AecDbPortRoom::~AecDbPortRoom(void)
{
}
Acad::ErrorStatus AecDbPortRoom::SetEWFnctNode(EWFnctNode& node,int nSegIndex,int OnFncNodeIndex)
{
assertWriteEnabled();
if ( nSegIndex != -1 && OnFncNodeIndex != -1)
{
memcpy(&m_fncNode,&node,sizeof(EWFnctNode));
m_nSegIndex = nSegIndex;
m_nOnFncNodeIndex = OnFncNodeIndex;
return Acad::eOk;
}
return Acad::eInvalidInput;
}
void AecDbPortRoom::SetPosIndex(int nSegIndex,int OnFncNodeIndex)
{
assertWriteEnabled();
m_nSegIndex = nSegIndex;
m_nOnFncNodeIndex = OnFncNodeIndex;
}
bool AecDbPortRoom::UpdateFncNode(const EWFnctNode* pData)
{
assertWriteEnabled();
if (pData != NULL)
{
memcpy(&m_fncNode,pData,sizeof(EWFnctNode));
// FreeBuffer(0,m_ar3DDrableBufPtrs);
// m_ar3DDrableBufPtrs.removeAll();
Clean3DBuffer();
// FreeBuffer(0,m_ar2DDrableBufPtrs);
// m_ar2DDrableBufPtrs.removeAll();
Clean2DBuffer();
return true;
}
return false;
}
bool AecDbPortRoom::UpdateDraw( ) const
{
assertReadEnabled();
// FreeBuffer(0,m_ar3DDrableBufPtrs);
// m_ar3DDrableBufPtrs.removeAll();
Clean3DBuffer();
// FreeBuffer(0,m_ar2DDrableBufPtrs);
// m_ar2DDrableBufPtrs.removeAll();
Clean2DBuffer();
return true;
}
bool AecDbPortRoom::UpdateDraw( )
{
assertWriteEnabled();
// FreeBuffer(0,m_ar3DDrableBufPtrs);
// m_ar3DDrableBufPtrs.removeAll();
Clean3DBuffer();
// FreeBuffer(0,m_ar2DDrableBufPtrs);
// m_ar2DDrableBufPtrs.removeAll();
Clean2DBuffer();
return true;
}
EWFnctNode AecDbPortRoom::GetEWFnctNode() const
{
assertReadEnabled();
return m_fncNode;
}
void AecDbPortRoom::GetEWFnctNode(EWFnctNode* pFn) const
{
assertReadEnabled();
if (pFn != NULL)
memcpy(pFn,&m_fncNode,sizeof(EWFnctNode));
}
void AecDbPortRoom::SetShareDoubleHouse(bool bShareWall)
{
assertWriteEnabled();
m_bShareDoubleHouse = bShareWall;
}
bool AecDbPortRoom::IsShareDoubleHouse() const
{
assertReadEnabled();
return m_bShareDoubleHouse;
}
bool AecDbPortRoom::FindESignRecord(AcDbDatabase* pDb,LPCTSTR pszName,AcDbObjectId& idRec)
{
if (pDb == NULL) return false;
AcDbBlockTable* pTbl = NULL;
if ( Acad::eOk == pDb->getBlockTable(pTbl,AcDb::kForRead) )
{
if ( Acad::eOk == pTbl->getAt(pszName,idRec) )
{
pTbl->close();
return true;
}
pTbl->close();
}
return false;
}
bool AecDbPortRoom::LoadESignRecord(AcDbDatabase* pDb,LPCTSTR pszName,AcDbObjectId& idRec)
{
CString sTempFile;
TCHAR szfileName[MAX_PATH],szFullPath[MAX_PATH];
GetModuleFileName(_hdllInstance,szfileName,MAX_PATH);
TCHAR drive[_MAX_DRIVE] = _T(""),
dir[_MAX_DIR] = _T(""),
fname[_MAX_FNAME] = _T(""),
ext[_MAX_EXT] = _T("");
//e:\,program files\autodesk\,myarx,exe
_tsplitpath(szfileName, drive, dir, fname, ext);
_tcscpy(szFullPath, drive);
_tcscat(szFullPath, dir);
CString sFullPath = szFullPath;
sFullPath.TrimRight(_T('\\'));
//上一级目录
int nPos = sFullPath.ReverseFind(_T('\\'));
CString sPath = sFullPath.Mid(0,nPos + 1);
sFullPath = sPath + _T("nodedwgs\\");
sTempFile.Format(_T("%s%s.dwg"),sFullPath,pszName);
AcDbDatabase db(Adesk::kFalse);
if (Acad::eOk == db.readDwgFile(sTempFile))
{
db.setInsbase(AcGePoint3d::kOrigin);
if ( Acad::eOk == acdbCurDwg()->insert(idRec,pszName,&db) )
{
return true;
}
}
return false;
}
Acad::ErrorStatus AecDbPortRoom::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
//----- Read parent class information first.
Acad::ErrorStatus es = AecDbEntityBase::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 > AecDbPortRoom::kCurrentVersionNumber )
return (Acad::eMakeMeProxy) ;
pFiler->readSoftPointerId(&m_idEW);
pFiler->readUInt32(&m_nSegIndex);
pFiler->readUInt32(&m_nOnFncNodeIndex);
Adesk::Int32 nByteLen = 0;
pFiler->readInt32(&nByteLen);
pFiler->readBytes(&m_fncNode,nByteLen);
pFiler->readBool(&m_bShareDoubleHouse);
UpdateDraw();
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbPortRoom::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled () ;
//----- Save parent class information first.
Acad::ErrorStatus es = AecDbEntityBase::dwgOutFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
//----- Object version number needs to be saved first
if ( (es =pFiler->writeUInt32 (AecDbPortRoom::kCurrentVersionNumber)) != Acad::eOk )
return (es) ;
pFiler->writeSoftPointerId(m_idEW);
pFiler->writeUInt32(m_nSegIndex);
pFiler->writeUInt32(m_nOnFncNodeIndex);
Adesk::Int32 nByteLen = sizeof(EWFnctNode);
pFiler->writeUInt32(nByteLen);
pFiler->writeBytes(&m_fncNode,nByteLen);
pFiler->writeBool(m_bShareDoubleHouse);
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbPortRoom::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
//----- Read parent class information first.
Acad::ErrorStatus es = AecDbEntityBase::dxfInFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbPortRoom::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled () ;
//----- Save parent class information first.
Acad::ErrorStatus es = AecDbEntityBase::dxfOutFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbPortRoom::subTransformBy(const AcGeMatrix3d& xform)
{
return Acad::eOk;
}
void AecDbPortRoom::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);
}
}
}
//AEC 派生
Acad::ErrorStatus AecDbPortRoom::Draw2d(AcGiDraw &dc) const
{
assertReadEnabled();
//默认俯视
if (!Has2DBuffer())
{
UpdateDraw();
AcGiExplodeDraw dc2;
Draw3d(dc2);
const AcDbVoidPtrArray &ar2D = Get2DBuffer();
for (int i = 0; i < ar2D.length(); ++i)
{
EWDimData::writeXDataMap((AcDbEntity*)ar2D[i], m_fncNode);
}
}
if (!m_idEW.isValid())
return Acad::eOk;
//图层
AcDbObjectId idLay = dc.GetLayerId();
dc.SetLayer(layerId());
//dc.SetSelectionMarker(1);
AcGePoint3d ptCen,ptVFr;
AcGePoint2d ptVPortOut;
AcGePoint2d ptSize,ptVSta,ptSta;
AcGeVector2d vtDir;
AcArray<ERoom> arRooms;
AcGeVector3d vtDirSeg3d;
double dGAngle = 0.0;
int nSectionDrawStyle = -1;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,m_idEW,AcDb::kForRead))
{
AecDbEarthWorm* pEW = AecDbEarthWorm::cast(pEnt);
if (pEW != NULL)
{
nSectionDrawStyle = pEW->GetSectionDrawStyle();
}
pEnt->close();
}
vtDir.normalize();
int nOld = dc.GetColor();
dc.SetColor(nSectionDrawStyle == 0 ? kMagenta : nSectionDrawStyle);
Adesk::UInt16 nCor = 0;
if (Has2DBuffer())
{
const AcDbVoidPtrArray &ar2D = Get2DBuffer();
for (int i = 0;i < ar2D.length();i++)
{
pEnt = (AcDbEntity*)ar2D.at(i);
nCor = pEnt->colorIndex();
//nCor 0 主视图的 1 纵断视图的
if (nSectionDrawStyle == nCor)//对应视图显示图元 1
{
if (nSectionDrawStyle > 0)
{
//改为和族显示一致,纵段绘制
//pEnt->transformBy(xformM);
//pEnt->transformBy(xformZ);
//pEnt->transformBy(xformR);
//dc.DrawEntity(*pEnt);//按照视图
//pEnt->transformBy(xformRV);
//pEnt->transformBy(xformZV);
//pEnt->transformBy(xformMV);
}
else
{
//俯视图图
int nOld2 = dc.GetColor();
dc.SetColor( kMagenta );
pEnt->setColorIndex(kMagenta);
dc.DrawEntity(*pEnt);//按照视图
pEnt->setColorIndex(nCor);
dc.SetColor( nOld2 );
}
}
else //其他视图的
{
if (nSectionDrawStyle > 0)//纵断视图请求下,主视图的也显示
{
//俯视图图
int nOld2 = dc.GetColor();
dc.SetColor( kMagenta );
dc.DrawEntity(*pEnt);//按照视图
dc.SetColor( nOld2 );
}
}
}
dc.SetLayer(idLay);
}
dc.SetColor(nOld);
return Acad::eOk;
}
Adesk::Boolean AecDbPortRoom::IsDraw2dByBlock() const
{
return Adesk::kFalse;
}
Adesk::Boolean AecDbPortRoom::GetDraw2d(AcDbVoidPtrArray& arEntPtrs,int nSectionDrawStyle) const
{
assertReadEnabled();
Adesk::UInt16 nCor = 0;
AcDbEntity* pEnt = NULL;
AcDbEntity* pEntClone = NULL;
const AcDbVoidPtrArray &ar2D = Get2DBuffer();
for (int i = 0;i < ar2D.length();i++)
{
pEnt = (AcDbEntity*)ar2D.at(i);
nCor = pEnt->colorIndex();
pEntClone = (AcDbEntity*)pEnt->clone();
if (nSectionDrawStyle == nCor)
{
if (nSectionDrawStyle > 0)
{
pEntClone->setColorIndex(nSectionDrawStyle);
arEntPtrs.append(pEntClone);
}
else
{
//总图直接俯视图上视口输出
pEntClone->setColorIndex(nSectionDrawStyle);
arEntPtrs.append(pEntClone);
}
}
}
return arEntPtrs.isEmpty() ? Adesk::kFalse : Adesk::kTrue;
}
Adesk::Boolean AecDbPortRoom::GetDraw3d(AcDbVoidPtrArray& arEntPtrs,bool bWriteBimInfo) const
{
assertReadEnabled();
if (!Has3DBuffer())
{
AcGiViewDraw dc(NULL,NULL);
Draw3d(dc);
}
AcDbEntity* pEnt = NULL;
AcDbEntity* pEntClone = NULL;
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pEnt = (AcDbEntity*)ar3D.at(i);
pEntClone = (AcDbEntity*)pEnt->clone();
if (bWriteBimInfo != NULL)
{
WriteXData(pEntClone,&m_fncNode);
}
arEntPtrs.append(pEntClone);
}
return Adesk::kTrue;
}
AecDbObjXDataMap* AecDbPortRoom::GetSpecialtyData(AcDb::OpenMode bMode)
{
assertReadEnabled();
return NULL;
}
const AecDbObjXDataMap* AecDbPortRoom::GetSpecialtyData() const
{
assertReadEnabled();
return NULL;
}
int AecDbPortRoom::GetDoghouseDraw2d(AcGePoint3d& ptPos,AcGeVector2d& vtDir,AcGeVector3d& vtDir3dSeg,AcGePoint2d& ptSize,AcGePoint2d& ptSta,AcGePoint2d& ptVSta,AcGePoint2d& ptVPortOut,AcGePoint3d& ptVFr,AcArray<ERoom>& arRooms,double& dGAngle) const
{
assertReadEnabled();
//图层
int nSectionDrawStyle = -1;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,m_idEW,AcDb::kForRead))
{
AecDbEarthWorm* pEW = AecDbEarthWorm::cast(pEnt);
if (pEW != NULL)
{
ptVSta = pEW->VStartPoint();
AcGeVector3d vtUCSXDir = acdbCurDwg()->ucsxdir();
AcGeVector3d vtUCSYDir = acdbCurDwg()->ucsydir();
vtUCSXDir.normalize();
vtUCSYDir.normalize();
//
ptVPortOut = ptVSta;
pEW->GetFncNodeVSection(m_fncNode.szLockId,ptVPortOut);
//1.提取截面尺寸
AcGePoint2dArray arSizeDatas;
ESection eSecType = pEW->ExtractEarthWormScr(arSizeDatas);
AcGePoint2d ptThick;
double dAngle = 0.0;
pEW->GetSectionRooms(eSecType,arSizeDatas,arRooms,ptThick,dAngle);
nSectionDrawStyle = pEW->GetSectionDrawStyle();
EWSegment seg;
pEW->GetSegment(m_nSegIndex,seg);
AcGePoint2d ptEnd;
ptSta = pEW->StartPoint();
ptEnd = pEW->EndPoint();
AcGeVector2d vtOffset2d = pEW->GetOffsetDir();
AcGeVector3d vtOffset3d(vtOffset2d.x,vtOffset2d.y,0.0);
double dStaEl = pEW->StartElevation();
AcGePoint3d ptFr,ptLast;
ptFr.set(ptSta.x,ptSta.y,dStaEl);
ptVFr.set(ptVSta.x,ptVSta.y,0.0);
ptFr += vtOffset3d;
ptLast = ptFr;
//XY面方向
vtDir = ptEnd - ptSta;
vtDir.normalize();
AcGeVector3d vtDir3d(vtDir.x,vtDir.y,0.0);
AcGeLineSeg3d ln;
ln.set(ptFr,ptFr + vtDir3d * 100.0);
pEW->TransformRegionPerpToLine(arRooms,ln);
ptSize = pEW->GetSize();
int nSegCount = pEW->GetSegmentCount();
for (int i = 0;i < nSegCount;i++)
{
EWSegment seg;
pEW->GetSegment(i,seg);
dGAngle = atan(seg.dGradient * 0.01);
if (i == m_nSegIndex)
{
ptPos = GetDoghouseDrawPos(pEW,i,seg,ptFr,eSecType,arSizeDatas);
ptFr += seg.dDistLen * vtDir3d;
ptFr.z += seg.dGradient * 0.01 * seg.dDistLen;//%
vtDir3dSeg = ptFr - ptLast;
vtDir3dSeg.normalize();
break;
}
ptLast = ptFr;
ptFr += seg.dDistLen * vtDir3d;
ptFr.z += seg.dGradient * 0.01 * seg.dDistLen;//%
ptVFr += seg.dDistLen * vtUCSXDir;
ptVFr += seg.dGradient * 0.01 * seg.dDistLen * vtUCSYDir;
}
}
pEnt->close();
}
return nSectionDrawStyle;
}
AcGePoint3d AecDbPortRoom::GetDoghouseDrawPos(AecDbEarthWorm* pEW,int iColor,const EWSegment& seg,const AcGePoint3d& ptFr,ESection eSecType,const AcGePoint2dArray& arSizeDatas) const
{
assertReadEnabled();
AcGePoint3d ptPos = ptFr;
//连个节点之间为一个 segment 一个 segment按20米制造, 中间有伸缩缝
//
// node 缝 node 缝 node 缝
//+-----------------+-------------------------+----------------------+--------
// | | |
// | | |
// --*--*--*.. --*--*... ---*--*--*
// 附属口 附属口 附属口
AcGeVector2d vtDir2d;
int nSectionDrawStyle = pEW->GetSectionDrawStyle();
vtDir2d = pEW->EndPoint() - pEW->StartPoint();
vtDir2d.normalize();
AcGeVector3d vtDir3d(vtDir2d.x,vtDir2d.y,0.0);
AcGePoint3d ptTo = ptFr;
ptTo += vtDir3d * seg.dDistLen;
ptTo.z += seg.dGradient * 0.01 * seg.dDistLen;
AcGeVector3d vtDir = ptTo - ptFr;
vtDir.normalize();
if (iColor > -1)
{
AcGePoint3d ptFr1 = ptFr;
double dDistFrom = 0;
for (int i = 0;i < seg.nDeformationJoints;i++)
{
if (i == m_nOnFncNodeIndex)
{
//当前LN 上的节点,如通风口
ptPos = ptFr1;
EWFnctNode& node = seg.pDeformationJoints[i];
EWFnctNode* pNext = node.pFncNodeNext;
while(pNext != NULL)
{
if (_tcscmp(pNext->szLockId,m_fncNode.szLockId) == 0)
{
ptPos += pNext->dDistFromPre * vtDir;
return ptPos;
}
pNext = pNext->pFncNodeNext;
}
return ptPos;
}
ptFr1 += vtDir * seg.pDeformationJoints[i].dDistFromPre;
}
}
return ptFr;
}
Acad::ErrorStatus AecDbPortRoom::Draw3d(AcGiDraw &dc) const
{
assertReadEnabled();
//图层
AcDbObjectId idLay = dc.GetLayerId();
dc.SetLayer(layerId());
//dc.SetSelectionMarker(1);
if (Has3DBuffer())
{
AcDbEntity* pEnt = NULL;
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pEnt = (AcDbEntity*)ar3D.at(i);
dc.DrawEntity(*pEnt);
}
dc.SetLayer(idLay);
return Acad::eOk;
}
//
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,m_idEW,AcDb::kForRead))
{
AecDbEarthWorm* pEW = AecDbEarthWorm::cast(pEnt);
if (pEW != NULL)
{
EWSegment seg;
pEW->GetSegment(m_nSegIndex,seg);
AcGePoint2d ptSta = pEW->StartPoint();
AcGePoint2d ptEnd = pEW->EndPoint();
double dStaEl = pEW->StartElevation();
AcGeVector2d vtOffset = pEW->GetOffsetDir();
AcGeVector3d vtOffset3d(vtOffset.x,vtOffset.y,0.0);
AcGePoint3d ptFr;
ptFr.set(ptSta.x,ptSta.y,dStaEl);
ptFr += vtOffset3d;
//XY面方向
AcGeVector2d vtDir = ptEnd - ptSta;
vtDir.normalize();
AcGeVector3d vtDir3d(vtDir.x,vtDir.y,0.0);
//1.提取截面尺寸
AcGePoint2dArray arSizeDatas;
ESection eSecType = pEW->ExtractEarthWormScr(arSizeDatas);
int nSegCount = pEW->GetSegmentCount();
for (int i = 0;i < nSegCount;i++)
{
EWSegment seg;
pEW->GetSegment(i,seg);
if (i == m_nSegIndex)
{
DrawDoghouse(pEW,i,seg,ptFr,eSecType,arSizeDatas,dc);
break;
}
ptFr += seg.dDistLen * vtDir3d;
ptFr.z += seg.dGradient * 0.01 * seg.dDistLen;//%
}
}
pEnt->close();
}
dc.SetLayer(idLay);
//dc.SetSelectionMarker(0);
return Acad::eOk;
}
double AecDbPortRoom::GetOutSideArea() const
{
assertReadEnabled();
double dArea = 0.0,dArea1 = 0.0;
if (!Has3DBuffer())
{
AcGiViewDraw dc(NULL,NULL);
Draw3d(dc);
//大约获取
AcDbEntity* pEnt = NULL;
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pEnt = (AcDbEntity*)ar3D.at(i);
AcDb3dSolid* pSolid = AcDb3dSolid::cast(pEnt);
if (pSolid != NULL)
{
pSolid->getArea(dArea1);
dArea += fabs(dArea1);
}
}
}
return dArea;
}
Acad::ErrorStatus AecDbPortRoom::DrawDoghouse(AecDbEarthWorm* pEW,int iColor,const EWSegment& seg,const AcGePoint3d& ptFr,ESection eSecType,const AcGePoint2dArray& arSizeDatas,AcGiDraw& dc) const
{
//连个节点之间为一个 segment 一个 segment按20米制造, 中间有伸缩缝
//
// node 缝 node 缝 node 缝
//+-----------------+-------------------------+----------------------+--------
// | | |
// | | |
// --*--*--*.. --*--*... ---*--*--*
// 附属口 附属口 附属口
AcGeVector2d vtDir2d = pEW->EndPoint() - pEW->StartPoint();
vtDir2d.normalize();
AcGeVector3d vtDir3d(vtDir2d.x,vtDir2d.y,0.0);
AcGePoint3d ptTo = ptFr;
ptTo += vtDir3d * seg.dDistLen;
ptTo.z += seg.dGradient * 0.01 * seg.dDistLen;
AcGeLineSeg3d ln;
ln.set(ptFr,ptTo);
AcGeVector3d vtDir = ptTo - ptFr;
vtDir.normalize();
AcGeVector3d vtMove;
AcGeMatrix3d xformMove;
AcDbVoidPtrArray arUnionSolidPtrs,arSubSolidPtrs, arOther3dPtrs;
if (iColor > -1)
{
//EWSegment 段再分,缝隙,防火墙
AcGePoint3d ptFr1 = ptFr1,ptTo1;
double dDistFrom = 0;
for (int i = 0;i < seg.nDeformationJoints;i++)
{
//seg 的 pFnctNodes 类型为 变形缝分段,实际分段个
if (seg.pDeformationJoints[i].eFnType == kEspJoint) //变形缝
{
//seg.pDeformationJoints[k].dDistLen = dLen;
//seg.pDeformationJoints[k].fNodeDef[0] = 100.0;//100mm伸缩缝隙
dDistFrom += seg.pDeformationJoints[i].dDistFromPre;//
//第n子节末端伸缩缝
ptFr1 = ptFr + vtDir * (dDistFrom - 0.5 * seg.pDeformationJoints[i].fNodeDef[0]);
ptTo1 = ptFr1 + vtDir * seg.pDeformationJoints[i].fNodeDef[0];
ln.set(ptFr1,ptTo1);
//子节点绘制
if (i == 0 )
{
ptFr1 = ptFr;
ptTo1 = ptFr1 + vtDir * seg.dDistLen;
ln.set(ptFr1,ptTo1);
}
else
{
ptFr1 = ptFr + vtDir * (dDistFrom - seg.pDeformationJoints[i].dDistFromPre);
ptTo1 = ptFr1 + vtDir* seg.pDeformationJoints[i].dDistFromPre;
ln.set(ptFr1,ptTo1);
}
if (i == m_nOnFncNodeIndex)
{
//当前LN 上的节点,如通风口
CreateDoghouse(eSecType,arSizeDatas,ln,pEW);
break;
}
}
}
AcDb3dSolid* pEWSolid = NULL;
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pEWSolid = (AcDb3dSolid*)ar3D.at(i);
dc.DrawEntity(*pEWSolid);
}
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbPortRoom::CreateDoghouse(ESection eSecType,const AcGePoint2dArray& arSizeDatas,AcGeLineSeg3d& ln,AecDbEarthWorm* pEW) const
{
return Acad::eOk;
}
void AecDbPortRoom::MakeVerSection2d(AcDb3dSolid* pSolid,int nSectionDrawStyle) const
{
assertReadEnabled();
//通风口符号
AcGePoint3d ptPos,ptVFr;
AcGeVector2d vtDir2d = AcGeVector2d::kXAxis;
AcGePoint2d ptSize,ptVSta,ptSta,ptVPortOut(0,0);
AcGeVector3d vtDirSeg3d;
AcArray<ERoom> arRooms;
double dGAngle = 0.0;
GetDoghouseDraw2d(ptPos,vtDir2d,vtDirSeg3d,ptSize,ptSta,ptVSta,ptVPortOut,ptVFr,arRooms,dGAngle);
AcGeVector3d vtDir3d(vtDir2d.x,vtDir2d.y,0.0);
double dGradient = 0.0;
double dVol = 0.0,momInertia[3],prodInertia[3],prinMoments[3],radiiGyration[3];
AcGePoint3d ptCen;
AcGeVector3d prinAxes[3];
AcDbExtents extents;
int nSectionDrawStyleEw = 0;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,m_idEW,AcDb::kForRead))
{
AecDbEarthWorm* pEW = AecDbEarthWorm::cast(pEnt);
if (pEW != NULL)
{
nSectionDrawStyleEw = pEW->GetSectionDrawStyle();
dGradient = pEW->GetGradientAt(m_fncNode.szLockId);
}
pEnt->close();
}
//如下注释掉,保证一次俯视和纵段预先都生成
//if ( nSectionDrawStyle == 1 ||
// nSectionDrawStyleEw == 1 )//纵断 1
{
AcGeVector3d vtDir3dv = vtDir3d;
vtDir3dv.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGeVector3d vtUCSY = acdbCurDwg()->ucsydir();
AcGeVector2d vtUcsy2d = vtUCSY.convert2d(AcGePlane::kXYPlane);
vtUcsy2d.normalize();
ptVPortOut -= vtUcsy2d * 0.5 * ptSize.y;
AcGePoint3d ptCen2,ptCen1;
AcGeVector3d vtMove;
AcGeMatrix3d xformV,xformM,xformR;
vtDir3dv.normalize();
vtDir3dv *= 0.5 * ptSize.y;
xformV.setToTranslation(vtDir3dv);//考虑有坡度
if (pSolid != NULL)
{
pSolid->getMassProp(dVol,ptCen1,momInertia,prodInertia,prinMoments,prinAxes,radiiGyration,extents);
AcGePlane plan;
plan.set(ptCen1,vtDir3dv);
AcDbRegion* pRegion = NULL;
pSolid->getSection(plan,pRegion);
if (pRegion != NULL)
{
//投影到中心面
AcGePlane planV;
planV.set(ptPos,vtDir3dv);
ptCen2 = ptCen1.orthoProject(planV);
vtMove = ptCen2 - ptCen1;
xformM.setToTranslation(vtMove);
pRegion->transformBy(xformM);
//AddToModelSpace((AcDbEntity*)pRegion->clone());
//移动到最外边
pRegion->transformBy(xformV);
//翻转到XY面
xformR.setToRotation(-PI / 2.0,vtDirSeg3d,ptPos);
pRegion->transformBy(xformR);
//AddToModelSpace((AcDbEntity*)pRegion->clone());
//添加切面
AddToSection2dDraw(pRegion,1);
DELETE_PTR(pRegion);
}
}
}
if (nSectionDrawStyle == 0)
{
if (pSolid != NULL)
{
MakeHorSection2d(pSolid);
}
}
}
void AecDbPortRoom::MakeVerSection2d(AcDb3dSolid* pSolid,const AcGePoint3d& ptCen,int nSectionDrawStyle) const
{
assertReadEnabled();
//通风口符号
AcGePoint3d ptPos,ptVFr;
AcGeVector2d vtDir2d = AcGeVector2d::kXAxis;
AcGePoint2d ptSize,ptVSta,ptSta,ptVPortOut(0,0);
AcGeVector3d vtDirSeg3d;
AcArray<ERoom> arRooms;
double dGAngle = 0.0;
GetDoghouseDraw2d(ptPos,vtDir2d,vtDirSeg3d,ptSize,ptSta,ptVSta,ptVPortOut,ptVFr,arRooms,dGAngle);
AcGeVector3d vtDir3d(vtDir2d.x,vtDir2d.y,0.0);
double dGradient = 0.0;
double dVol = 0.0,momInertia[3],prodInertia[3],prinMoments[3],radiiGyration[3];
AcGeVector3d prinAxes[3];
AcDbExtents extents;
AcGePoint3d ptCen1;
int nSectionDrawStyleEw = 0;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,m_idEW,AcDb::kForRead))
{
AecDbEarthWorm* pEW = AecDbEarthWorm::cast(pEnt);
if (pEW != NULL)
{
nSectionDrawStyleEw = pEW->GetSectionDrawStyle();
dGradient = pEW->GetGradientAt(m_fncNode.szLockId);
}
pEnt->close();
}
//如下注释掉,保证一次俯视和纵段预先都生成
//if ( nSectionDrawStyle == 1 ||
// nSectionDrawStyleEw == 1 )//纵断 1
{
AcGeVector3d vtDir3dv = vtDir3d;
vtDir3dv.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGeVector3d vtUCSY = acdbCurDwg()->ucsydir();
AcGeVector2d vtUcsy2d = vtUCSY.convert2d(AcGePlane::kXYPlane);
vtUcsy2d.normalize();
ptVPortOut -= vtUcsy2d * 0.5 * ptSize.y;
AcGePoint3d ptCen2;
AcGeVector3d vtMove;
AcGeMatrix3d xformV,xformM,xformR;
vtDir3dv.normalize();
vtDir3dv *= 0.5 * ptSize.y;
xformV.setToTranslation(vtDir3dv);//考虑有坡度
if (pSolid != NULL)
{
pSolid->getMassProp(dVol,ptCen1,momInertia,prodInertia,prinMoments,prinAxes,radiiGyration,extents);
AcGePlane plan;
plan.set(ptCen,vtDir3dv);
AcDbRegion* pRegion = NULL;
pSolid->getSection(plan,pRegion);
if (pRegion != NULL)
{
//投影到中心面
AcGePlane planV;
planV.set(ptPos,vtDir3dv);
ptCen2 = ptCen.orthoProject(planV);
vtMove = ptCen2 - ptCen;
xformM.setToTranslation(vtMove);
pRegion->transformBy(xformM);
//AddToModelSpace((AcDbEntity*)pRegion->clone());
//移动到最外边
pRegion->transformBy(xformV);
//翻转到XY面
xformR.setToRotation(-PI / 2.0,vtDirSeg3d,ptPos);
pRegion->transformBy(xformR);
//AddToModelSpace((AcDbEntity*)pRegion->clone());
//添加切面
AddToSection2dDraw(pRegion,1);
DELETE_PTR(pRegion);
}
}
}
if (nSectionDrawStyle == 0)
{
if (pSolid != NULL)
{
MakeHorSection2d(pSolid);
}
}
}
void AecDbPortRoom::MakeHorSection2d(AcDb3dSolid* pSolid) const
{
assertReadEnabled();
if (pSolid == NULL)
return;
AcDbVoidPtrArray arSubEnts;
pSolid->explode(arSubEnts);
AcGePoint3d ptSta,ptEnd;
AcGeLineSeg3d ln;
AcDbEntity* pSub = NULL;
AcDbVoidPtrArray arLnPtrs;
for (int i = 0;i < arSubEnts.length();i++)
{
pSub = (AcDbEntity*)arSubEnts.at(i);
AcDbRegion* pReg = AcDbRegion::cast(pSub);
if (pReg != NULL)
{
pReg->explode(arLnPtrs);
DELETE_PTR(pReg);
}
}
for (int i = 0;i < arLnPtrs.length();i++)
{
pSub = (AcDbEntity*)arLnPtrs.at(i);
AcDbPolyline* pL = AcDbPolyline::cast(pSub);
if ( pL != NULL)
{
pL->getStartPoint(ptSta);
pL->getEndPoint(ptEnd);
ln.set(ptSta,ptEnd);
if (AcGePlane::kXYPlane.isParallelTo(ln) && ln.length() > 0.1)
{
AddToSection2dDraw(pSub,0);
pSub = NULL;
}
}
AcDbLine* pLn = AcDbLine::cast(pSub);
if (pLn != NULL)
{
ptSta = pLn->startPoint();
ptEnd = pLn->endPoint();
ln.set(ptSta,ptEnd);
if (AcGePlane::kXYPlane.isParallelTo(ln) && ln.length() > 0.1)
{
AddToSection2dDraw(pSub,0);
pSub = NULL;
}
}
if (pSub != NULL)
DELETE_PTR(pSub);
}
return;
//旧算法
AcDbVoidPtrArray arRegPtrs;
pSolid->explode(arRegPtrs);
AcGeVector3d vtNorm;
AcDbEntity* pEnt = NULL;
AcDbRegion* pRegAll = NULL;
Acad::ErrorStatus es;
for(int i = 0;i < arRegPtrs.length();i++)
{
pEnt = (AcDbEntity*)arRegPtrs.at(i);
AcDbRegion* pReg = AcDbRegion::cast(pEnt);
if (pReg != NULL)
{
pReg->getNormal(vtNorm);
if (vtNorm.isParallelTo(AcGeVector3d::kZAxis))
{
//投影到XY 面
AcGePlane plan;
pReg->getPlane(plan);
AcGePoint3d ptOnNN = plan.pointOnPlane();
AcGePoint3d ptOnXY = AcGePlane::kXYPlane.closestPointTo(ptOnNN);
AcGeVector3d vtMove = ptOnXY - ptOnNN;
AcGeMatrix3d xform;
xform.setToTranslation(vtMove);
pReg->transformBy(xform);
if (pRegAll == NULL)
{
pRegAll = pReg;
}
else
{
if ( Acad::eOk == (es = pRegAll->booleanOper(AcDb::kBoolUnite,pReg) ) )
{
}
else
{
acutPrintf(_T("\nError %d AcDbRegion::booleanOper"),es);
}
}
}
else
{
DELETE_PTR(pReg);
}
}
}
if (pRegAll != NULL)
{
AddToSection2dDraw(pRegAll,0);
DELETE_PTR(pRegAll);
}
}
void AecDbPortRoom::AddToSection2dDraw(AcDbEntity* pComEnt,int nSectionDrawtyle) const
{
if (pComEnt == NULL)
return;
//assertWriteEnabled();
AcDbRegion* pRegAll = AcDbRegion::cast(pComEnt);
if (pRegAll != NULL)
{
AcDbVoidPtrArray arSubEntPtrs;
pRegAll->explode(arSubEntPtrs);
AcDbEntity* pEnt = NULL;
AcDbCurve* pCrv = NULL;
for (int i = 0;i < arSubEntPtrs.length();i++)
{
pEnt = (AcDbEntity*)arSubEntPtrs.at(i);
pCrv = AcDbCurve::cast(pEnt);
if (pCrv != NULL)
{
pEnt->setColorIndex( nSectionDrawtyle);
Add2DBuffer(pEnt);
//m_ar2DDrableBufPtrs.append(pEnt);
}
else
{
AcDbVoidPtrArray arSubEntPtrs2;
pEnt->explode(arSubEntPtrs2);
for(int j = 0;j < arSubEntPtrs2.length();j++)
{
AcDbEntity* pSubEnt = (AcDbEntity*)arSubEntPtrs2.at(j);
if (pSubEnt != NULL)
{
AcDbCurve* pSubCrv = AcDbCurve::cast(pSubEnt);
if (pSubCrv != NULL)
{
pSubCrv->setColorIndex(nSectionDrawtyle);
Add2DBuffer(pSubCrv);
//m_ar2DDrableBufPtrs.append(pSubCrv);
}
}
}
//acutPrintf(_T("\nclass = %s"),pEnt->isA()->name());
DELETE_PTR(pEnt);
}
}
}
else
{
pComEnt->setColorIndex( nSectionDrawtyle);
Add2DBuffer(pComEnt);
//m_ar2DDrableBufPtrs.append(pComEnt);
}
}
void AecDbPortRoom::AddToSection2dDraw(AcDbVoidPtrArray& arEntPtrs,int nSectionDrawtyle) const
{
AcDbEntity* pComEnt = NULL;
for (int kk = 0;kk < arEntPtrs.length();kk++)
{
pComEnt = (AcDbEntity*)arEntPtrs.at(kk);
AddToSection2dDraw(pComEnt,nSectionDrawtyle);
AcDbRegion* pRegAll = AcDbRegion::cast(pComEnt);
if (pRegAll != NULL)
{
DELETE_PTR(pRegAll);
}
}
}
bool AecDbPortRoom::TransformRegionPerpToLine(AcDbRegion* pRegion,AcGeLineSeg3d& lnNormal) const
{
AcGeVector3d vtNormal = lnNormal.endPoint() - lnNormal.startPoint();
vtNormal = vtNormal.orthoProject(AcGeVector3d::kZAxis);
vtNormal.negate();
AcGePoint3d ptOrg = lnNormal.startPoint();
AcGePlane plan;
plan.set(ptOrg,vtNormal);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
pRegion->transformBy(xform);
return true;
}
int AecDbPortRoom::GetSectionDraw(const AcGePoint3d& ptFr,const AcGePoint3d& ptTo,const AcGeVector3d& vtViewDir,const AcGeVector3d& vtTo, AcDbVoidPtrArray& arRegionPtrs) const
{
assertReadEnabled();
if (!Has3DBuffer())
{
AcGiViewDraw dc(NULL,NULL);
Draw3d(dc);
}
int nCount = 0;
AcGePlane plan;
AcGeVector3d vtU = ptTo - ptFr;
Acad::ErrorStatus es;
plan.set(ptFr,vtU,vtViewDir);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
xform.invert();
AcDb3dSolid* pSolid = NULL;
AcDbRegion* pRegion = NULL;
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pSolid = (AcDb3dSolid*)ar3D.at(i);
if (pSolid != NULL)
{
es = pSolid->getSection(plan,pRegion);
if (pRegion != NULL)
{
pRegion->transformBy(xform);
arRegionPtrs.append(pRegion);
nCount += 1;
}
}
}
return nCount;
}
int AecDbPortRoom::GetKernelSolids(AcDbVoidPtrArray& arSolidPtrs) const
{
assertReadEnabled();
if (!Has3DBuffer())
{
AcGiViewDraw dc(NULL,NULL);
Draw3d(dc);
}
AcDb3dSolid* pSolid = NULL;
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pSolid = (AcDb3dSolid*)ar3D.at(i);
if (pSolid != NULL)
{
arSolidPtrs.append(pSolid);
}
}
return arSolidPtrs.length();
}
//vtDirX 梯子踏脚钢管方向 vtDirXY 踏脚凸起方向
AcDb3dSolid* AecDbPortRoom::DrawCatLadder(const AcGePoint3d& ptGe,const AcGeVector3d& vtDirX,const AcGeVector3d& vtDirXY,double dTH,double dTW,AcDbVoidPtrArray& arOther3dPtrs)
{
AcGeVector3d vtDirHor = vtDirX.orthoProject(AcGeVector3d::kZAxis);
AcGeVector3d vtDirDep = -vtDirXY;
//@20钢管 间距 300 梯宽度 500 踏脚 180
double dRad = 0.5 * AS_MUNIT(20.0);
double dSpace = AS_MUNIT(300.0);
double dWidth = AS_MUNIT(500.0);
double dFootH = AS_MUNIT(180.0);
double dDeepWallD = AS_MUNIT(120.0);
double dDeepWallW = AS_MUNIT(250.0);
//----------------------------------------------
//
//--250-----+ +-----250------- @20
// | |
// 120 | |
//----------+---------------+-------------------
// | |
// | 500 |
// 180 | |
// +---------------+
//
//总高
double dH = dTH;//m_fncNode.fNodeDef[14];
if (dTW > 0.1) dWidth = dTW;
//中心
AcGePoint3d ptPos = ptGe;
ptPos -= (dDeepWallW + 0.5 * dWidth) * vtDirHor;
ptPos += dDeepWallD * vtDirDep;
ptPos.z += dSpace; //上一个台阶
//层数
int nLayers = (int)(dH / dSpace + 0.5 - dSpace);
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
AcDbCircle cir(ptPos, vtDirHor, dRad);
AcGePlane plane(AcGePoint3d(0,0,ptPos.z),AcGeVector3d::kZAxis);
AcGePoint3d ptHCen,ptHCen2;
AcDbVoidPtrArray ar3DDrableBufPtrs;
arCurPtrs.append(&cir);
if ( Acad::eOk == AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs) )
{
AcDbRegion* pReg = (AcDbRegion*)arRegPtrs.first();
AcGePoint3d ptTmp = ptPos;
AcGePoint3d pt1,pt2;
AcDbPolyline pl;
pl.addVertexAt(0,ptTmp.convert2d(plane));
ptTmp += dDeepWallW * vtDirHor;
pl.addVertexAt(1,ptTmp.convert2d(plane));
pt1 = ptTmp;
ptTmp -= (dFootH + dDeepWallD) * vtDirDep;
pl.addVertexAt(2,ptTmp.convert2d(plane));
ptTmp += dWidth * vtDirHor;
pl.addVertexAt(3,ptTmp.convert2d(plane));
ptTmp += (dFootH + dDeepWallD) * vtDirDep;
pl.addVertexAt(4,ptTmp.convert2d(plane));
pt2 = ptTmp;
ptHCen = MidPoint(pt1,pt2);
ptTmp += dDeepWallW * vtDirHor;
pl.addVertexAt(5,ptTmp.convert2d(plane));
AcDb3dSolid* pSolid = new AcDb3dSolid;
if ( Acad::eOk == pSolid->extrudeAlongPath(pReg,&pl) )
{
AcGeVector3d vtZ(0,0,dSpace);
AcGeMatrix3d xform;
xform.setToTranslation(vtZ);
AcDbVoidPtrArray arSolidPtrs;
AcDb3dSolid* pSolidT = pSolid;
ptHCen2 = ptHCen;
ar3DDrableBufPtrs.append(pSolid);
for (int i = 1;i < nLayers - 1;i++)
{
ptHCen2.transformBy(xform);
AcDb3dSolid* pSolid2 = NULL;
if ( Acad::eOk == pSolidT->getTransformedCopy(xform,(AcDbEntity*&)pSolid2) )
{
arSolidPtrs.append(pSolid2);
pSolidT = pSolid2;
ar3DDrableBufPtrs.append(pSolid2);
}
}
}
DELETE_PTR(pReg);
}
//创建一个板把各层连接起来
AcDb3dSolid* pSolidBox = new AcDb3dSolid;
double dBoxW = 2.0 * dDeepWallW + dWidth;
double dBoxT = dRad;
double dBoxH = (nLayers - 2) * dSpace;
pSolidBox->createBox(dBoxW,dBoxT,dBoxH);
AcGeMatrix3d xformM;
// 先旋转角度与扶手一至
double dAngle = AcGeVector3d::kXAxis.angleTo(vtDirX, AcGeVector3d::kZAxis);
xformM.setToRotation(dAngle, AcGeVector3d::kZAxis);
pSolidBox->transformBy(xformM);
// 再位移到扶手位置
AcGePoint3d ptCen = MidPoint(ptHCen2,ptHCen);
xformM.setToTranslation(ptCen.asVector());
pSolidBox->transformBy(xformM);
ar3DDrableBufPtrs.append(pSolidBox);
AcDb3dSolid* pPart = NULL;
if (ar3DDrableBufPtrs.length() > 0)
{
pPart = (AcDb3dSolid*)ar3DDrableBufPtrs.first();
Acad::ErrorStatus es = Acad::eOk;
for (int i = 1;i < ar3DDrableBufPtrs.length();i++)
{
AcDb3dSolid* pSolid = (AcDb3dSolid*)ar3DDrableBufPtrs.at(i);
assert(pSolid != NULL);
es = pPart->booleanOper(AcDb::kBoolUnite,pSolid);
if (es == Acad::eGeneralModelingFailure )//失败
{
FreeBuffer(i+1,ar3DDrableBufPtrs);
return NULL;
}
}
arOther3dPtrs.append(pPart);
}
return pPart;
}
//vtDirX 梯子踏脚横水平方向 vtDirXY 踏脚凸起Y方向,dTH 梯子总高度, ptGe 开始中点
AcDb3dSolid* AecDbPortRoom::DrawCatLadderH(const AcGePoint3d& ptGe,const AcGeVector3d& vtDirX,const AcGeVector3d& vtDirXY,double dTH,double dW,AcDbVoidPtrArray& arOther3dPtrs)
{
AcGeVector3d vtDirHor = vtDirX.orthoProject(AcGeVector3d::kZAxis);
vtDirHor.normalize();
AcGeVector3d vtDirDep = -vtDirXY;
// |
// | 角钢 dTL
// |
// |_________
//梯子标准 GB4053.1-2009
//角钢
double dTL = AS_MUNIT(40.0);//40毫米 40X40角钢
double dTt = AS_MUNITF(5.0f);//5毫米厚度
double dTW = AS_MUNIT(500.0);;//梯子宽度
double dSpace = AS_MUNIT(300.0);
double dSlide = AS_MUNIT(80.0);//80x80扶手 矩形钢
if (dW > 0.1) dTW = dW;
int nLayers = (int)(dTH / dSpace + 0.5 - dSpace);//层数
AcGePoint3d ptHFr = ptGe - 0.5 * dTW * vtDirHor;
AcGePoint3d ptHBt = ptHFr;
ptHFr += (dSlide - dTL) * 0.5 * vtDirDep;
AcGePoint3d ptGeX[7];
//截面
ptGeX[0] = ptHFr + dTL * vtDirDep;
ptGeX[1] = ptHFr;
ptGeX[2] = ptHFr - AcGeVector3d::kZAxis * dTL;
ptGeX[3] = ptGeX[2] + dTt * vtDirDep;
ptGeX[4] = ptGeX[3] + (dTL - dTt) * AcGeVector3d::kZAxis;
ptGeX[5] = ptGeX[4] + (dTL - dTt) * vtDirDep;
ptGeX[6] = ptGeX[0];
AcDbLine* pLine = NULL;
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
for (int i = 0;i < 6;i++)
{
pLine = new AcDbLine(ptGeX[i],ptGeX[i+1]);
arCurPtrs.append(pLine);
}
AcDbVoidPtrArray ar3DDrableBufPtrs;
if ( Acad::eOk == AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs) )
{
AcDbRegion* pReg = (AcDbRegion*)arRegPtrs.first();
AcDbLine lnPath;
lnPath.setStartPoint(ptHFr);
lnPath.setEndPoint(ptHFr + dTW * vtDirHor);
AcGeVector3d vtZ(0,0,dSpace);
AcGeMatrix3d xform;
xform.setToTranslation(vtZ);
AcDb3dSolid* pSolid = new AcDb3dSolid;
if ( Acad::eOk == pSolid->extrudeAlongPath(pReg,&lnPath) )
{
AcDbVoidPtrArray arSolidPtrs;
AcDb3dSolid* pSolidT = pSolid;
//m_ar3DDrableBufPtrs.append(pSolid); 第一层去掉
for (int i = 1;i < nLayers - 1;i++)
{
AcDb3dSolid* pSolid2 = NULL;
if ( Acad::eOk == pSolidT->getTransformedCopy(xform,(AcDbEntity*&)pSolid2) )
{
arSolidPtrs.append(pSolid2);
pSolidT = pSolid2;
ar3DDrableBufPtrs.append(pSolid2);
}
}
DELETE_PTR(pSolid);
}
//两边扶手,矩形钢
AcGePoint3d ptHTp = ptHBt + dTH * AcGeVector3d::kZAxis;
AcGePoint3d ptCen = MidPoint(ptHTp,ptHBt);
xform.setToTranslation(ptCen.asVector());
pSolid = new AcDb3dSolid;
if ( Acad::eOk == pSolid->createBox(dSlide,dSlide,dTH) )
{
pSolid->transformBy(xform);
ar3DDrableBufPtrs.append(pSolid);
vtDirHor *= dTW;
xform.setToTranslation(vtDirHor);
AcDb3dSolid* pSolid2 = NULL;
if ( Acad::eOk == pSolid->getTransformedCopy(xform,(AcDbEntity*&)pSolid2) )
{
ar3DDrableBufPtrs.append(pSolid2);
}
}
DELETE_PTR(pReg);
}
AcDb3dSolid* pPart = NULL;
if (ar3DDrableBufPtrs.length() > 0)
{
pPart = (AcDb3dSolid*)ar3DDrableBufPtrs.first();
Acad::ErrorStatus es = Acad::eOk;
for (int i = 1;i < ar3DDrableBufPtrs.length();i++)
{
AcDb3dSolid* pSolid = (AcDb3dSolid*)ar3DDrableBufPtrs.at(i);
assert(pSolid != NULL);
es = pPart->booleanOper(AcDb::kBoolUnite,pSolid);
if (es == Acad::eGeneralModelingFailure )//失败
{
FreeBuffer(i+1,ar3DDrableBufPtrs);
return NULL;
}
}
arOther3dPtrs.append(pPart);
}
return pPart;
}
bool SorFunc(PointDir& ptdir1,PointDir& ptdir2)
{
AcGeVector3d vt = ptdir2.pt - ptdir1.pt;
if (vt.dotProduct(ptdir1.vt) > 0)
{
return true;
}
return false;
}
void SortPoints(std::vector<AcGePoint3d>& arPts,AcGeVector3d& vtDir)
{
PointDir ptDir;
std::vector<PointDir> vtPtDir;
for (int i = 0;i < arPts.size();i++)
{
ptDir.pt = arPts.at(i);
ptDir.vt = vtDir;
vtPtDir.push_back(ptDir);
}
std::sort(vtPtDir.begin(),vtPtDir.end(),SorFunc);
arPts.clear();
for (int i = 0;i < vtPtDir.size();i++)
{
arPts.push_back( vtPtDir.at(i).pt );
}
}
bool AecDbPortRoom::getExtentInEarthworm(AcGePoint3d &ptMin, AcGePoint3d &ptMax) const
{
assertReadEnabled();
OPENOBJ_BEGIN(m_idEW, AcDb::kForWrite, AecDbEarthWorm, pEW)
{
if (!pEW) return false;
AcGeVector2d vtDir = pEW->EndPoint() - pEW->StartPoint();
AcGePoint3d ptSta, ptEnd;
AcGeVector3d vtNormal(vtDir.x, vtDir.y, 0.0);
vtNormal.rotateBy(PI / 2.0, AcGeVector3d::kZAxis);
AcGePoint2d ptSta2d = pEW->StartPoint();
AcGePlane plan;
plan.set(AcGePoint3d(ptSta2d.x, ptSta2d.y, 0.0), vtNormal);
std::vector<AcGePoint3d> arPts;
AcDbEntity* pEnt = NULL;
const AcDbVoidPtrArray &ar2D = Get2DBuffer();
for (int i = 0; i < ar2D.length(); i++)
{
pEnt = (AcDbEntity*)ar2D.at(i);
if (pEnt->colorIndex() != 0) continue;
//主视图
AcDbCurve* pCrv = AcDbCurve::cast(pEnt);
if (!pCrv) continue;
pCrv->getStartPoint(ptSta);
pCrv->getEndPoint(ptEnd);
ptSta = ptSta.orthoProject(plan);
ptEnd = ptEnd.orthoProject(plan);
arPts.push_back(ptSta);
arPts.push_back(ptEnd);
}
if (arPts.size() <= 1) return false;
AcGeVector3d vtDir3d(vtDir.x, vtDir.y, 0.0);
SortPoints(arPts, vtDir3d);
ptMin = *arPts.begin();
ptMax = *arPts.rbegin();
}
OPENOBJ_END()
return true;
}
Acad::ErrorStatus AecDbPortRoom::subErase(Adesk::Boolean erasing)
{
AcGePoint3d pt1, pt2;
getExtentInEarthworm(pt1, pt2);
OPENOBJ_BEGIN(m_idEW, AcDb::kForWrite, AecDbEarthWorm, pEW)
{
if (pEW != NULL)
{
pEW->RemoveFncNodeAtByLn(pt1, pt2);
}
}
OPENOBJ_END()
return AecDbEntityBase::subErase(erasing);
}
Acad::ErrorStatus AecDbPortRoom::subExplode(AcDbVoidPtrArray& arEntPtrs) const
{
return Acad::eOk;
}
bool AecDbPortRoom::IsXXXDoghouse() const
{
return false;
}
void AecDbPortRoom::subList() const
{
assertReadEnabled();
switch(m_fncNode.eFnType)
{
case kPipeDoghouse:
{
acutPrintf(_T("\n类型: 管类投料口"));
break;
}
case kCableDoghouse:
{
acutPrintf(_T("\n类型: 线缆类投料口"));
break;
}
case kHeatDoghouse:
{
acutPrintf(_T("\n类型: 热力投料口"));
break;
}
case kVenDoghouse:
{
acutPrintf(_T("\n类型: 通风口"));
break;
}
case kEscapeHatch:
{
acutPrintf(_T("\n类型: 逃生口"));
break;
}
case kFireOutlet:
{
acutPrintf(_T("\n类型: 消防引出口"));
break;
}
case kEWOutLethouse:
{
acutPrintf(_T("\n类型: 水电管廊引出口"));
break;
}
case kHTOutLetHouse:
{
acutPrintf(_T("\n类型: 热力舱引出口"));
break;
}
case kBDOutLetHouse:
{
acutPrintf(_T("\n类型: 直埋引出"));
break;
}
default:
break;
}
acutPrintf(_T("\n定位位置: %g 米"),m_fncNode.dDistFromPre);
acutPrintf(_T("\n桩号: %s"),m_fncNode.szStake);
acutPrintf(_T("\n说明: %s"),m_fncNode.szNodeSpec);
acutPrintf(_T("\n舱室: 第%d室"),m_fncNode.nRoomIndex + 1);
}