#include "stdafx.h" #include "TDbInSight.h" #include "symdef.h" #include "dbtext.h" #include "dbhatch.h" // lgd add 140424,增加符号文字导出所在图层设置 extern int g_nSymbTextT3Layer; void InitInSight(BOOL bInit) { if(bInit) { TDbInSight::rxInit(); acrxBuildClassHierarchy(); TDbInSight::InitMatchProtocol(TRUE); } else { TDbInSight::InitMatchProtocol(FALSE); deleteAcRxClass(TDbInSight::desc()); } } ACRX_DXF_DEFINE_MEMBERS(ATSInSight, ATSCurveEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_TDBINSIGHT, "ATS_TDBINSIGHT图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbInSight); TDbInSight::TDbInSight():m_ptIns(AcGePoint3d(0.0,0.0,0.0)),m_dRotation(0),m_InSightStyle(0),m_strTH(_T("")),m_strBH(_T("")), m_dRadius(10), m_dTextRatio(0.0), m_bOldStyle(2) { m_idTextStyle = InitTextStyle(TS_DIM); } TDbInSight::~TDbInSight() {} Acad::ErrorStatus TDbInSight::subTransformBy( const AcGeMatrix3d& xform ) { assertWriteEnabled(); m_ptIns.TransformBy(xform); XVector3D vtRot(cos(m_dRotation), sin(m_dRotation)); ((AcGeVector3d &)vtRot).transformBy(xform); m_dRotation=ads_angle(XPoint(), vtRot); return Acad::eOk; } TSubText* TDbInSight::HitTestText(XPoint pt)const { // sg modify 110209,支持圆圈文字出圈样式 int nTrueStyle = GetTrueTextStyle(); double dScale = (nTrueStyle==1)?0.75:(GetTextRatio()-0.05); XPoint ptCenter(m_ptIns); XPoint ptHit(pt); if (pt.Distance2d(m_ptIns) < m_dRadius *dScale * GetPScale()) // sg modify 081223,字的大小占圆圈的% { if (GetSubTextNum() == 1) return GetSubText(0); XLine line; ads_polar(m_ptIns, m_dRotation, m_dRadius * GetPScale(), line.EndPoint()); ads_polar(m_ptIns, PI+ m_dRotation, m_dRadius * GetPScale(), line.StartPoint()); if (line.HitTest2d(pt) == 2) return GetSubText(1); else return GetSubText(0); } return NULL; } void TDbInSight::SetSubText(long i, CString sText) { assertWriteEnabled(); if (i == 0) { SetNumberText(sText); } // else // sg modify 081218 // SetDrawingLabel(sText); else if (i == 1) { SetMapNoText(sText); } } // sg add 110209,获得圆圈文字样式,考虑了随基本设定的情况 int TDbInSight::GetTrueTextStyle() const { int nOldStyle = m_bOldStyle; if (nOldStyle == 2) // 随基本设定 { nOldStyle = DocGetDrawingIndexStyle(); } return nOldStyle; } // sg add 081222,计算最大的文字宽度、高度 void TDbInSight::GetTextExtends(const TCHAR *sText, double &dX, double &dY, BOOL bDrawingLabel) const { double dWidthFactor(1.0); // 中文字体宽高比 OPENOBJ_BEGIN(m_idTextStyle, AcDb::kForRead, AcDbTextStyleTableRecord, pStyle); if (pStyle != NULL) { dWidthFactor = pStyle->xScale(); } OPENOBJ_END(); CString csTmpText = sText; csTmpText.TrimLeft(); csTmpText.TrimRight(); if (csTmpText.IsEmpty() || _tcscmp(sText, _T("-"))==0) { csTmpText = _T("2"); } // sg add 110209,获得文字高度 double dHeigh = m_nTextHeight * GetPScale(), dRadius = m_dRadius*GetPScale() * GetTextRatio(); int nTrueStyle = GetTrueTextStyle(); if (nTrueStyle != 0) // 出圈样式 { dHeigh = dRadius * 2.0; if (m_InSightStyle != ENormalInsight) { dHeigh *= 0.5; } } AcDbText text; text.setPosition(XPoint(0, 0)); text.setTextStyle(m_idTextStyle); text.setTextString(csTmpText); // text.setHeight(m_nTextHeight*GetPScale()); text.setHeight(dHeigh); text.setRotation(0); text.setWidthFactor(dWidthFactor); AcDbExtents extents; XPoint ptMax, ptMin; if (text.getGeomExtents(extents) == Acad::eOk) // 外包矩形,一般情况下都是eOk { ptMax = extents.maxPoint(); ptMin = extents.minPoint(); } else // sg add 110802,批量转旧时候,获得外包围盒有时候会不成功 { AcGiTextStyle style; fromAcDbTextStyle(style, m_idTextStyle); style.extentsBox(csTmpText, FALSE, csTmpText.GetLength(), FALSE, ptMin, ptMax); } if (nTrueStyle != 0) // sg add 110209,出圈样式 { dX = ptMax.x - ptMin.x; dY = dHeigh; if (m_InSightStyle == ENormalInsight) { dX *= 0.5; dY *= 0.5; } return; } // 8.0起,文字最大不超过圆的比例可设置 double dFactor = (ptMax.x - ptMin.x) / (ptMax.y - ptMin.y); // 宽高比例 dY = dRadius/sqrt(1 + dFactor*dFactor); // 调整大小,圈内只有一行文字时 if (m_InSightStyle != ENormalInsight) { dY = dRadius/sqrt(1.21 + 0.25*dFactor*dFactor); // 圈内有两行文字时 } dX = dY * dFactor; } Acad::ErrorStatus TDbInSight::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet,BOOL *bErase) { // sg add 110621,如果是出圈样式,导出为T3-T8时,全部分解 BOOL bExplode = GetTrueTextStyle()==3; Acad::ErrorStatus es = Acad::eOk; if (bExplode) // sg add 110621,出圈样式,需要分解 { //XPushMemVar vTemp(XExplodeStream::m_bFullExplode, TRUE); // 完全分解 XPushMemVar vTemp2(XExplodeStream::m_bExportTch4, TRUE); XExplodeStream dc(entSet); if (!OnExplodeOrDraw(dc)) return es; dc.SetPropertiesFrom(this); if (nDrawMode == DRAW_2D) es = ExplodeOrDraw2d(dc); else es = ExplodeOrDraw3d(dc); if (bErase) *bErase = TRUE; return es; } return TDbSymbWithText::DownGradeSave(nDrawMode, entSet, bErase); // 其他情况,基类处理 } Acad::ErrorStatus TDbInSight::ExplodeOrDraw2d( TGGiExplodeDrawBase &dc ) const { AcDbObjectId idLayer = dc.GetLayerId(); double dRotation = m_dRotation + GetLayoutRotation(); AcGePoint2d tmpPt, ptCircleLeft, ptCircleRight,ptLineLeft,ptLineRight/*中间的线段*/; AcGeVector2d vtx = AcGeVector2d::kXAxis; AcGeVector2d vty = AcGeVector2d::kYAxis; vtx.rotateBy(dRotation); vtx.normalize(); vty.rotateBy(dRotation); vtx.normalize(); AcGeVector2d vtLX = AcGeVector2d::kXAxis; vtLX.rotateBy(GetLayoutRotation()); vtLX.normalize(); double dRadius = GetPScale() * m_dRadius; //三角形底边长度 double dTransWidth = 2 *dRadius*cos(45*PI/180); AcDbPolyline pline; pline.setConstantWidth(0); tmpPt = m_ptIns - dRadius * vtx; pline.addVertexAt(0, tmpPt, -1.0); tmpPt = m_ptIns + dRadius*vtx; pline.addVertexAt(1, tmpPt, 0); tmpPt = m_ptIns + vtx * dTransWidth; pline.addVertexAt(2, tmpPt, 0); tmpPt = m_ptIns + vty * dTransWidth; pline.addVertexAt(3, tmpPt, 0); tmpPt = m_ptIns - vtx * dTransWidth; pline.addVertexAt(4, tmpPt, 0); pline.setClosed(Adesk::kTrue); pline.setLayer(idLayer); dc.Polyline(pline); //填充 TGGePoly2D poly; poly.SetAcDbCurve(&pline); //判断版本 #if ADS <= 17 dc.DrawSolid(poly); #else AcDbHatch *pHatch = NewHatchFromPoly2D(poly); pHatch->setColorIndex(pline.colorIndex()); pHatch->setLayer(idLayer); dc.DrawEntity(*pHatch); if (pHatch){delete pHatch;} #endif ptCircleLeft = m_ptIns - dRadius*vtx; ptCircleRight = m_ptIns + dRadius*vtx; ptLineLeft = m_ptIns - dRadius*vtLX; ptLineRight = m_ptIns + dRadius*vtLX; pline.reset(Adesk::kFalse, 0); pline.addVertexAt(0, ptCircleLeft, 1.0); pline.addVertexAt(1, ptCircleRight, 1.0); pline.addVertexAt(2, ptCircleLeft, 0); pline.setClosed(Adesk::kFalse); pline.setConstantWidth(0); pline.setLayer(idLayer); dc.Polyline(pline); ads_matrix matRot; m_ptIns.GetRotationMatrix(m_nLayoutRotation, matRot); dc.SetStyle(m_idTextStyle); dc.SetRotation(m_nLayoutRotation); // sg modify 110209,支持圆圈文字出圈样式 // BOOL bOldStyle = IsOldStyle(); int nTrueStyle = GetTrueTextStyle(); if (m_InSightStyle == ENormalInsight) // 圆圈文字内只有一个单行文字的情况 { XPoint pt1, pt2; double nTextHeight(0); // if (bOldStyle) if (nTrueStyle == 1) // 8.0以前样式 { nTextHeight = dRadius/sin(PI/4.0); pt1 = m_ptIns - XPoint(0.8*nTextHeight/2.0, 0.8*nTextHeight/2.0); pt2 = m_ptIns + XPoint(0.8*nTextHeight/2.0, -0.8*nTextHeight/2.0); } else // 8.0新样式,8.5出圈文字样式 { double dX(0); GetTextExtends(m_strBH, dX, nTextHeight, FALSE); // 获取指定文字的最大尺寸 pt1 = m_ptIns - XPoint(dX, nTextHeight); pt2 = m_ptIns + XPoint(dX, -nTextHeight); } if (!m_strBH.IsEmpty() || g_bExplodeSubText) { int nColorOld = dc.GetColor(); if (dc.IsExportTch4()) // 炸开 { // lgd add 140424,分解出来的文字的图层和颜色要随“高级选项”中的设置来处理 if (g_nSymbTextT3Layer==1 && !!m_idTextLayer) { dc.SetLayer(m_idTextLayer); // 文字层 dc.SetColor(256); //颜色随层 } else { dc.SetLayer(idLayer); // 文字和标注放在同一 dc.SetColor(m_colorText); } } else // 绘制 { dc.SetLayer(idLayer); // 文字和标注放在同一 dc.SetColor(m_colorText);//颜色随层 } if (IsLayoutRotated()) { pt1.TransformBy(matRot); pt2.TransformBy(matRot); } if (nTrueStyle == 1) // 旧样式 dc.DrawTextFit(m_strBH, pt1, pt2, nTextHeight*0.8); else // 新样式,出圈文字样式样式 dc.DrawTextFit(m_strBH, pt1, pt2, nTextHeight*2); // 字高为dY的2倍 } } else // 上、下都有文字的情况 { /*绘中间线*/ pline.reset(Adesk::kFalse, 0); pline.addVertexAt(0, ptLineLeft); pline.addVertexAt(1, ptLineRight); pline.setClosed(Adesk::kFalse); pline.setLayer(idLayer); dc.SetLayer(idLayer); dc.Polyline(pline); double nTextHeight(0), dY(0); if (nTrueStyle == 1) // 旧样式 { double nAng = atan(2.0); nTextHeight = dRadius*sin(nAng)*0.9; } else // 新样式,出圈样式 { GetTextExtends(m_strBH, nTextHeight, dY, TRUE); } XPoint pt1 = m_ptIns, pt2 = m_ptIns; pt1.x -= nTextHeight/2; pt2.x += nTextHeight/2; double nSpacer(0); if (nTrueStyle == 1) // 旧样式 nSpacer = nTextHeight/10.0; else // 新样式,出圈样式 { if (GetTextRatio() > 1.0 + 1E-2) // 圆圈文字的系数大于1时 { nSpacer = dY/5.0; } else if (nTrueStyle == 0) // 新样式 { // sg modify 101119,根据8.5需求,修改新样式,将文字远离基线 nSpacer = (sqrt(dRadius*dRadius - 0.25*nTextHeight*nTextHeight) - dY)*0.4; } else // ==3,出圈样式 { nSpacer = (dRadius - dY) * 0.4; } } pt1.y += nSpacer; pt2.y += nSpacer; int nColorOld = dc.GetColor(); if (dc.IsExportTch4()) // 炸开 { // lgd add 140424,分解出来的文字的图层和颜色要随“高级选项”中的设置来处理 if (g_nSymbTextT3Layer==1 && !!m_idTextLayer) { dc.SetLayer(m_idTextLayer); // 文字层 dc.SetColor(256); //颜色随层 } else { dc.SetLayer(idLayer); // 文字和标注放在同一层 dc.SetColor(m_colorText); } } else // 绘制 { dc.SetLayer(idLayer); // 文字和标注放在同一 dc.SetColor(m_colorText); } XPoint ptTextLoc; ptTextLoc = m_ptIns + vty *GetPScale()* m_dRadius/2; if (nTrueStyle == 1) // 旧样式 dc.DrawTextFit(m_strBH, pt1.TransformAs(matRot), pt2.TransformAs(matRot), nTextHeight*0.8); else // 新样式,出圈样式,设置字高为dY dc.DrawTextFit(m_strBH, pt1.TransformAs(matRot), pt2.TransformAs(matRot), dY); if (nTrueStyle == 1) // 旧样式 { pt1.y -= nTextHeight*0.8+2*nSpacer; pt2.y -= nTextHeight*0.8+2*nSpacer; } else // 新样式,出圈样式 { GetTextExtends(m_strTH, nTextHeight, dY, TRUE); // sg modify 101119,根据8.5需求,修改新样式,将文字远离基线 double dTmpNum = dY*1.2; if (GetTextRatio() < 1.0 + 1E-2) { if (nTrueStyle == 0) // 新样式 { dTmpNum = (sqrt(dRadius*dRadius - 0.25*nTextHeight*nTextHeight) - dY)*0.4 + dY; } else // ==3,出圈样式 { dTmpNum = (dRadius - dY) * 0.4 + dY; } } pt1 = m_ptIns - XPoint(nTextHeight/2, dTmpNum); pt2 = m_ptIns + XPoint(nTextHeight/2, -dTmpNum); } if (IsLayoutRotated()) { pt1.TransformBy(matRot); pt2.TransformBy(matRot); } ptTextLoc = m_ptIns - vty * GetPScale()*m_dRadius/2; if (nTrueStyle == 1) // 旧样式 dc.DrawTextFit(m_strTH, pt1, pt2, nTextHeight*0.8); else // 新样式,出圈样式 dc.DrawTextFit(m_strTH, pt1, pt2, dY); } return Acad::eOk; } Acad::ErrorStatus TDbInSight::subGetClassID(CLSID* pClsid) const { #if (ADS >= 17) #endif return Acad::eOk; } // 取夹点说明 Acad::ErrorStatus TDbInSight::GetGripText(int i, CString &cs) const { Acad::ErrorStatus es = Acad::eOk; if( i ==0 ) cs = _T("移动内视符号"); else es = Acad::eInvalidInput; return es; } Acad::ErrorStatus TDbInSight::subGetGripPoints( AcGePoint3dArray&gripPoints,AcDbIntArray&,AcDbIntArray& ) const { assertReadEnabled(); gripPoints.append(m_ptIns); return Acad::eOk; } Acad::ErrorStatus TDbInSight::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset ) { assertWriteEnabled(); int iIndex = indices.at(0); switch (iIndex) { case 0: { m_ptIns+=offset; } break; default: break; } return Acad::eOk; } Acad::ErrorStatus TDbInSight::dwgInFields( AcDbDwgFiler* pFiler ) { assertWriteEnabled(); Acad::ErrorStatus es; if ((es = TDbSymbWithText::dwgInFields(pFiler)) != Acad::eOk) return es; TCHAR* pszStr = NULL; Adesk::Int32 nVt = 0; pFiler->readInt16(&m_InSightStyle); pFiler->readString(&pszStr); m_strTH = pszStr; pFiler->readString(&pszStr); m_strBH = pszStr; pFiler->readPoint3d((AcGePoint3d *)&m_ptIns); pFiler->readDouble(&m_dRadius); pFiler->readDouble(&m_dRotation); pFiler->readDouble(&m_dValue); pFiler->readInt32(&nVt); pFiler->readItem(&m_bOldStyle); pFiler->readItem(&m_dTextRatio); m_nFlag = (int)nVt; return pFiler->filerStatus(); } Acad::ErrorStatus TDbInSight::dwgOutFields( AcDbDwgFiler* pFiler ) const { assertReadEnabled(); Acad::ErrorStatus es; if ((es = TDbSymbWithText::dwgOutFields(pFiler)) != Acad::eOk) return es; pFiler->writeInt16(m_InSightStyle); pFiler->writeString((LPCTSTR)m_strTH); pFiler->writeString((LPCTSTR)m_strBH); pFiler->writePoint3d((const AcGePoint3d &)m_ptIns); pFiler->writeDouble(m_dRadius); pFiler->writeDouble(m_dRotation); pFiler->writeDouble(m_dValue); pFiler->writeInt32(m_nFlag); pFiler->writeItem(m_bOldStyle); pFiler->writeItem(m_dTextRatio); return pFiler->filerStatus(); } // 提供对格式刷的支持 void TDbInSight::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); TDbSymbWithText::CopyPropertiesFrom(pSrcEntity, gMatchFlag); TDbInSight *pSrc = TDbInSight::cast(pSrcEntity); if (pSrc != NULL) { m_nTextHeight = pSrc->m_nTextHeight; //字高 m_idTextStyle = pSrc->m_idTextStyle; //文字样式 m_colorText = pSrc->m_colorText; //文字颜色 m_dRadius = pSrc->m_dRadius; //半径 m_dRotation = pSrc->m_dRotation; //图案旋转角 m_dValue = pSrc->m_dValue; //预留 m_nFlag = pSrc->m_nFlag; //预留 m_dTextRatio = pSrc->m_dTextRatio; } } void TDbInSight::SetAngle( double dRotation ) { m_dRotation = dRotation; } double TDbInSight::GetAngle() { return m_dRotation; } double TDbInSight::GetTextRatio() const { double dRatio = m_dTextRatio; if (fabs(dRatio) < 1.0E-3) { dRatio = DocGetDITextRatio(); } return dRatio; } void TDbInSight::SetTextRatio( double dVal ) { assertWriteEnabled(); m_dTextRatio = dVal; } void TDbInSight::SetOldStyle(int nDraw) { assertWriteEnabled(); m_bOldStyle = nDraw; } int TDbInSight::GetOldStyle() const { return m_bOldStyle; } void TDbInSight::SetRadius( double nRadius ) { assertWriteEnabled(); m_dRadius = nRadius; } void TDbInSight::SetMapNoText( CString str ) { assertWriteEnabled(); m_strTH= str; } void TDbInSight::SetNumberText( CString str ) { assertWriteEnabled(); m_strBH = str; } int TDbInSight::GetFirstVersion() const { // 10 以下版本一概炸碎 return 10; }