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

623 lines
16 KiB
C++

#include "StdAfx.h"
#include "TDbSection.h"
#include "TDbSectionPathSign.h"
#include "SectionUtility.h"
#include "TCoverVisibleRelationCal.h"
ACRX_DXF_DEFINE_MEMBERS(ATSSection, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_Section, "ATS_Section图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbSection);
namespace
{
void SetLineType(TGGiExplodeDrawBase &dc, const CString &sLine)
{
if (dc.SetLineType(sLine) != Acad::eOk)
{
InitLineType(sLine, NULL);
dc.SetLineType(sLine);
}
}
void DeleteSectionFills(std::vector<AcDbVoidPtrArray> &fills)
{
for (size_t i = 0; i < fills.size(); ++i)
{
AcDbVoidPtrArray array = fills[i];
for (int j = 0; j < array.length(); ++j)
{
void *p = array[j];
if (p)
{
delete p;
p = NULL;
}
}
}
fills.clear();
}
Acad::ErrorStatus DwgInFields_For_TDbSection(std::vector<AcDbVoidPtrArray> &arObj, AcDbDwgFiler *pFiler)
{
if (!arObj.empty())
DeleteSectionFills(arObj);
Adesk::Int32 nVecCount = 0;
pFiler->readInt32(&nVecCount);
for (int i = 0; i < nVecCount; ++i)
{
Adesk::Int32 nArrCount = 0;
pFiler->readInt32(&nArrCount);
AcDbVoidPtrArray array;
for (int j = 0; j < nArrCount; ++j)
{
TSectionFill *pFill = new TSectionFill();
pFill->dwgInFields(pFiler);
array.append(pFill);
}
arObj.push_back(array);
}
return Acad::eOk;
}
Acad::ErrorStatus DwgOutFields_For_TDbSection(const std::vector<AcDbVoidPtrArray> &arObj, AcDbDwgFiler *pFiler)
{
pFiler->writeInt32((int)arObj.size());
for (size_t i = 0; i < arObj.size(); ++i)
{
AcDbVoidPtrArray array = arObj[i];
pFiler->writeInt32(array.length());
for (int j = 0; j < array.length(); ++j)
{
TSectionFill *pFill = (TSectionFill*)array[j];
pFill->dwgOutFields(pFiler);
}
}
return Acad::eOk;
}
AcGePoint2d GetTextStyleExtent(const CString &sName, const double dScale)
{
AcGiTextStyle style;
toAcDbTextStyle(style, _T("STANDARD"));
AcGePoint2d ext = style.extents((LPCTSTR)sName, FALSE, sName.GetLength(), FALSE);
ext.y *= dScale;
ext.x *= dScale;
return ext;
}
void ClearARXArray(AcGePoint3dArray ar)
{
if (ar.isEmpty())
return;
#if (ADS < 17) // FUCK
{
ar.removeSubArray(0, ar.length()-1);
return;
}
#endif
ar.setLogicalLength(0);
return;
}
void AppendOsapPt(const AcGePoint3dArray &ar, const TGGeLine &line)
{
AcGePoint3dArray &arr = const_cast<AcGePoint3dArray&>(ar);
arr.append(line.GetStartPoint());
arr.append(line.GetEndPoint());
}
void AppendOsapPt(const AcGePoint3dArray &ar, const AcDbPolyline &poly)
{
AcGePoint3dArray &arr = const_cast<AcGePoint3dArray&>(ar);
for (unsigned int i = 0; i < poly.numVerts(); ++i)
{
AcGePoint3d pt;
poly.getPointAt(i, pt);
arr.append(pt);
}
}
}
Acad::ErrorStatus TDbSection::dwgInFields( AcDbDwgFiler *pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es;
if ((es = TDbEntity::dwgInFields(pFiler)) != Acad::eOk)
return es;
Adesk::Int32 nVer = 0;
pFiler->readInt32(&nVer); // read version
if (nVer >= 1)
{
XString str;
ReadString(pFiler, str);
m_sName = CString(str);
pFiler->readDouble(&m_dLineWidth);
pFiler->readDouble(&m_dWordHeight);
pFiler->readPoint3d(&m_ptPosition);
Adesk::Int32 nCount = 0;
pFiler->readInt32(&nCount);
std::vector<TObjSectionRecord> arTmp(nCount);
for (size_t i = 0; i < arTmp.size(); ++i)
arTmp[i].dwgInFields(pFiler);
m_arSectionCurve.swap(arTmp);
DwgInFields_For_TDbSection(m_arFills, pFiler);
pFiler->readBool(&m_bShowCoverCurve);
pFiler->readBool(&m_bShowFill);
ReadString(pFiler, str);
m_sLineType = CString(str);
pFiler->readBool(&m_bShowBorder);
pFiler->readItem(&m_ptMax);
pFiler->readItem(&m_ptMin);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSection::dwgOutFields( AcDbDwgFiler *pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
if ((es = TDbEntity::dwgOutFields(pFiler)) != Acad::eOk)
return es;
Adesk::Int32 nVer = 1;
pFiler->writeInt32(nVer); // write version
pFiler->writeItem((LPCTSTR)m_sName);
pFiler->writeDouble(m_dLineWidth);
pFiler->writeDouble(m_dWordHeight);
pFiler->writePoint3d(m_ptPosition);
pFiler->writeInt32((int)m_arSectionCurve.size());
for (size_t i = 0; i < m_arSectionCurve.size(); ++i)
{
m_arSectionCurve[i].dwgOutFields(pFiler);
}
DwgOutFields_For_TDbSection(m_arFills, pFiler);
pFiler->writeBool(m_bShowCoverCurve);
pFiler->writeBool(m_bShowFill);
pFiler->writeItem((LPCTSTR)m_sLineType);
pFiler->writeBool(m_bShowBorder);
pFiler->writeItem(m_ptMax);
pFiler->writeItem(m_ptMin);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSection::dxfInFields( AcDbDxfFiler *pFiler)
{
assertWriteEnabled();
if (TDbEntity::dxfInFields(pFiler) != Acad::eOk || !pFiler->atSubclassData(_T("TDbSection")))
return pFiler->filerStatus();
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSection::dxfOutFields( AcDbDxfFiler *pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
if ((es = TDbEntity::dxfOutFields(pFiler)) != Acad::eOk)
return es;
if ((es = pFiler->writeItem(AcDb::kDxfSubclass, _T("TDbSection"))) != Acad::eOk)
return pFiler->filerStatus();
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSection::ExplodeOrDraw3d( TGGiExplodeDrawBase &dc ) const
{
ExplodeOrDraw2d(dc);
return Acad::eOk;
}
Acad::ErrorStatus TDbSection::ExplodeOrDraw2d( TGGiExplodeDrawBase &dc ) const
{
// 清空 捕捉点
ClearARXArray(m_ptOsaps);
// 画字
TDbText text;
text.setPropertiesFrom(this);
text.SetAlignment(XExplodeDraw::kMiddleCenter);
// sg modify 120106,给“TS_SECTION”独立出来一个文字样式
// text.SetStyleId(InitTextStyle(TS_LABEL));
text.SetStyleId(InitTextStyle(TS_SECTION));
text.SetHeight(WORD_HEIGHT);
text.SetText(m_sName);
double width, height;
text.GetExtents(&width, &height);
AcGePoint3d ptTxt(m_ptMin.x + (m_ptMax.x - m_ptMin.x)*.5, m_ptMin.y - height, 0.);
text.SetLocation(ptTxt);
text.setColorIndex(7);
if(dc.IsFullExplode())
text.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(text);
// 字下面画条线
ptTxt.y -= (height*.7);
AcGePoint2d pt1(ptTxt.x - width*.5, ptTxt.y), pt2(ptTxt.x + width*.5, ptTxt.y);
AcDbPolyline poly;
poly.setPropertiesFrom(this);
dc.SetLineType(_T("BYLAYER"));
poly.setColorIndex(7);
poly.addVertexAt(0, pt1);
poly.addVertexAt(1, pt2);
poly.setConstantWidth(LINE_WIDTH * GetPScale());
dc.Polyline(poly);
if (m_bShowBorder)
{
AcDbPolyline polyLine;
AcGePoint3d pt0(m_ptMax), pt1(m_ptMin.x, m_ptMax.y, 0), pt2(m_ptMin), pt3(m_ptMax.x, m_ptMin.y, 0);
polyLine.addVertexAt(0, PT3DTOPT2D(pt0));
polyLine.addVertexAt(0, PT3DTOPT2D(pt1));
polyLine.addVertexAt(0, PT3DTOPT2D(pt2));
polyLine.addVertexAt(0, PT3DTOPT2D(pt3));
polyLine.addVertexAt(0, PT3DTOPT2D(pt0));
polyLine.setColorIndex(7);
SetLineType(dc, m_sLineType);
dc.Polyline(polyLine);
AppendOsapPt(m_ptOsaps, polyLine);
}
dc.SetColor(256);
// 画计算出的剖面
for (size_t i = 0; i < m_arSectionCurve.size(); ++i)
{
TObjSectionRecord record = m_arSectionCurve[i];
if (record.GetEntityType() == TObjSectionRecord::eTCH_ELEVTION) // 地面线
{
TGGePoly2D poly = record.GetOriginalPoly();
if (poly.Length() != 2)
continue;
TADSGePoint3d pt1 = *poly[0], pt2 = *poly[1];
pt1.x = (pt1.x > pt2.x) ? m_ptMax.x : m_ptMin.x;
pt2.x = (pt1.x > pt2.x) ? m_ptMin.x : m_ptMax.x;
dc.SetLayer(record.GetLayerID());
SetLineType(dc, _T("CONTINUOUS"));
TGGeLine _line(pt1, pt2, LS_FINITE);
dc.DrawLine(_line);
AppendOsapPt(m_ptOsaps, _line);
continue;
}
LONG_PTR lID = record.GetID().asOldId();
std::vector<std::pair<int, TGGeLine> > &lines = record.GetSectionLines();
for (size_t j = 0; j < lines.size(); ++j)
{
SetLineType(dc, _T("CONTINUOUS"));
dc.SetLayer(record.GetLayerID());
dc.SetSelectionMarker(lID);
dc.DrawLine(lines[j].second);
AppendOsapPt(m_ptOsaps, lines[j].second);
}
if (m_bShowCoverCurve)
{
std::vector<std::pair<int, TGGeLine> > &hide_lines = record.GetHideSectionLines();
for (size_t k = 0; k < hide_lines.size(); ++k)
{
dc.SetLayer(record.GetLayerID());
SetLineType(dc, _T("DASH"));
dc.SetSelectionMarker(lID);
dc.DrawLine(hide_lines[k].second);
}
}
}
if (m_bShowFill)
{
for (size_t j = 0; j < m_arFills.size(); ++j)
{
AcDbVoidPtrArray arFills = m_arFills[j];
for (int k = 0; k < arFills.length(); ++k)
{
TSectionFill *pFill = (TSectionFill*)arFills[k];
AcDbObjectId layerId = pFill->GetLayer();
if (pFill->IsBlockRef())
{
BlockRefInfo block;
pFill->GetBlockRefInfo(block);
OPENOBJ_BEGIN(pFill->GetBlockRefID(), AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if(pBlock)
{
dc.SetLayer(layerId);
dc.DrawBlock(*pBlock, block.m_ptPos, block.m_Scale, 0., TRUE);
}
OPENOBJ_END();
}
else
{
std::vector<TGGeLine> showlines = pFill->GetSegments();
for (size_t jj = 0; jj < showlines.size(); ++jj)
{
dc.SetLayer(layerId);
dc.DrawLine(showlines[jj]);
}
if (m_bShowCoverCurve)
{
std::vector<TGGeLine> hidelines = pFill->GetHideSegments();
for (size_t kk = 0; kk < hidelines.size(); ++kk)
{
dc.SetLayer(layerId);
SetLineType(dc, _T("DASH"));
dc.DrawLine(hidelines[kk]);
}
}
}
}
}
}
return Acad::eOk;
}
Acad::ErrorStatus TDbSection::subTransformBy( const AcGeMatrix3d& xform )
{
TDbEntity::subTransformBy(xform);
m_ptPosition.transformBy(xform);
for (size_t i = 0; i < m_arSectionCurve.size(); ++i)
m_arSectionCurve[i].TransFormBy(xform);
for (i = 0; i < m_arFills.size(); ++i)
for (int j = 0; j < m_arFills[i].length(); ++j)
((TSectionFill*)m_arFills[i][j])->TransformBy(xform);
m_ptMax.transformBy(xform);
m_ptMin.transformBy(xform);
return Acad::eOk;
}
Acad::ErrorStatus TDbSection::subGetGripPoints( AcGePoint3dArray&gripPoints,AcDbIntArray&,AcDbIntArray& ) const
{
gripPoints.append(m_ptMin);
return Acad::eOk;
}
Acad::ErrorStatus TDbSection::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset )
{
assertWriteEnabled();
subTransformBy(offset);
return Acad::eOk;
}
TDbSection::TDbSection()
: m_sName(_T("SECTION")), m_dLineWidth(150),
m_dWordHeight(250), m_sLineType(_T("DASH")), m_bShowBorder(true)
{
m_pathID.setNull();
m_ptPosition = AcGePoint3d::kOrigin;
}
bool TDbSection::UpdateSection(const SectionInfo & secInfo)
{
// 旋转到 XOY 面
AcGeMatrix3d mat_coordinate = SectionUtility::GetCoordSystem(secInfo.m_vecDir);
m_sName.Format(_T("%s-%s SECTION"), secInfo.m_sName, secInfo.m_sName);
// 处理 各个实体的剖面
ProcessSection(secInfo); // 添充 m_arSectionCurve
if (m_arSectionCurve.empty() && m_arFills.empty())
return false;
AcGeMatrix3d mat_position;
AcGePoint3d ptOri = secInfo.m_ptS;
ptOri.transformBy(mat_coordinate);
AcGeVector3d vec = m_ptPosition - ptOri;
mat_position.setToTranslation(vec);
AcDbExtents ext;
for (size_t i = 0; i < m_arSectionCurve.size(); ++i)
{
TObjSectionRecord &record = m_arSectionCurve[i];
record.TransFormBy(mat_coordinate);
record.TransFormBy(mat_position);
record.SetSectionLinesElevation(0.);
record.SetOriginalPolyElevation(0.);
AcGePoint3d max = record.GetMaxPt(), min = record.GetMinPt();
if (record.GetEntityType() != TObjSectionRecord::eTCH_ELEVTION) // 保留 0 标高线的 Z 值
{
max.x = max.y = 0.;
min.x = min.y = 0.;
}
ext.addPoint(record.GetMaxPt());
ext.addPoint(record.GetMinPt());
}
for (i = 0; i < m_arFills.size(); ++i)
{
AcDbVoidPtrArray array = m_arFills[i];
for (int j = 0; j < array.length(); ++j)
{
TSectionFill *pFill = (TSectionFill*)array[j];
pFill->TransformBy(mat_coordinate);
pFill->TransformBy(mat_position);
if (pFill->IsBlockRef())
{
BlockRefInfo info;
pFill->GetBlockRefInfo(info);
ext.addPoint(info.m_ptMax);
ext.addPoint(info.m_ptMin);
}
}
}
m_ptMin = ext.minPoint();
m_ptMax = ext.maxPoint();
m_ptMax.z = m_ptMin.z = 0;
double dW = abs(m_ptMax.x - m_ptMin.x);
(dW < 1000.) ? dW = 1000. : dW;
m_ptMin.x -= dW*.1, m_ptMax.x += dW*.1;
double dH = abs(m_ptMax.y - m_ptMin.y);
(dH < 1000.) ? dH = 1000. : dH;
m_ptMin.y -= dH*.1, m_ptMax.y += dH*.1;
if (m_bCover)
{
TCoverVisibleRelationCal::CoverMultipleRecordCal(m_arSectionCurve);
// for (size_t i = 0; i < m_arSectionCurve.size(); ++i)
// m_arSectionCurve[i].ConverPolyLine2CoverPoly();
/*注意 m_arSectionCurve 已经在 CoverMultipleRecordCal() 函数内排好序*/
TCoverVisibleRelationCal::PorcessCoverForFill(m_arSectionCurve, m_arFills);
}
return true;
}
// 首先得到准备投影的 AcDbObjectId 列表
// 调用各个实体的GetSection()对象进行投影
// 将得到的投影面进行排序
// 对排好序的投影进行遮挡运算
void TDbSection::ProcessSection(const SectionInfo & secInfo)
{
m_arSectionCurve.clear();
if (!m_arFills.empty())
DeleteSectionFills(m_arFills);
for (size_t i = 0; i < secInfo.m_arObjID.size(); ++i)
{
AcDbEntity *pTangent = NULL;
acdbOpenObject(pTangent, secInfo.m_arObjID[i], AcDb::kForRead);
AcDbVoidPtrArray arFills;
if (pTangent)
{
TEntityBase *pTEntBase = NULL;
TDbEntity *pTEnt = TDbEntity::cast(pTangent);
if (pTEnt)
pTEntBase = (TEntityBase *)pTEnt;
TDbCurveEntity *pTCurve = TDbCurveEntity::cast(pTangent);
if (pTCurve)
pTEntBase = (TEntityBase *)pTCurve;
// 注意 GetSection内不应将std::vector<TObjSectionRecord>参数清空
if (pTEntBase)
{
AcDbFace face;
secInfo.m_SectionFace.AsAcDbFace(face);
pTEntBase->GetSection(face, secInfo.m_vecDir, m_arSectionCurve, arFills);
for (int j = 0; j < arFills.length(); ++j)
{
TSectionFill *pFill = (TSectionFill*)arFills[j];
pFill->InitBlockCoverId();
}
if (arFills.length())
m_arFills.push_back(arFills);
}
pTangent->close();
}
}
// 在剖面对象内添加一条标高为 0 的直线,其长度为投影面的宽
if (!m_arSectionCurve.empty() || !m_arFills.empty())
{
TGGePoly2D poly;
poly.AppendNode(secInfo.m_ptS);
poly.AppendNode(secInfo.m_ptE);
m_arSectionCurve.push_back(TObjSectionRecord(objectId(), layerId(),
TObjSectionRecord::eTCH_ELEVTION, 0., poly));
}
}
TDbSection::~TDbSection()
{
DeleteSectionFills(m_arFills);
}
void TDbSection::SetPathID( const AcDbObjectId &id )
{
m_pathID = id;
addPersistentReactor(id);
}
Acad::ErrorStatus TDbSection::subGetClassID( CLSID* pClsid ) const
{
return Acad::eOk;
}
Acad::ErrorStatus TDbSection::GetGripText( int i, CString &cs ) const
{
Acad::ErrorStatus es = Acad::eOk;
switch(i)
{
case 0:
cs = _T("移动剖切结果");
break;
default:
es = Acad::eInvalidInput;
}
return es;
}
Acad::ErrorStatus TDbSection::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick, const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds, const AcGeMatrix3d& insertionMat ) const
{
snapPoints = m_ptOsaps;
return Acad::eOk;
}
Acad::ErrorStatus TDbSection::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick, const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds ) const
{
snapPoints = m_ptOsaps;
return Acad::eOk;
}
Acad::ErrorStatus TDbSection::subIntersectWith( const AcDbEntity* ent, AcDb::Intersect intType,
AcGePoint3dArray& points, INT_PTR thisGsMarker,
INT_PTR otherGsMarker ) const
{
return Acad::eOk;
}
Acad::ErrorStatus TDbSection::subIntersectWith( const AcDbEntity* ent, AcDb::Intersect intType,
const AcGePlane& projPlane, AcGePoint3dArray& points,
INT_PTR thisGsMarker, INT_PTR otherGsMarker ) const
{
return Acad::eOk;
}