#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 &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 &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 &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(ar); arr.append(line.GetStartPoint()); arr.append(line.GetEndPoint()); } void AppendOsapPt(const AcGePoint3dArray &ar, const AcDbPolyline &poly) { AcGePoint3dArray &arr = const_cast(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 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 > &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 > &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 showlines = pFill->GetSegments(); for (size_t jj = 0; jj < showlines.size(); ++jj) { dc.SetLayer(layerId); dc.DrawLine(showlines[jj]); } if (m_bShowCoverCurve) { std::vector 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参数清空 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; }