//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, SH Software Co. Ltd. // = FileName : XExplodeStream 类 // = Version : ver2.0 // = Author : zjq // = CreateDate : 2002-09-09 // = Description: XExplodeStream 定义 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "XExplodeStream.h" #include "XDbObject.h" #include "XPathParser.h" #include "dbsol3d.h" #include "dbregion.h" #include "XTrianglePface.h" #include "XHoleModel.h" #include "DList.h" #include "XPolygonEx.h" #include "dbhatch.h" #include "XGlobalFunc.h" #include "XGlobalCurveFunc.h" BOOL XExplodeStream::m_bFullExplode = FALSE; BOOL XExplodeStream::m_bExportTch4 = FALSE; XExplodeStream::XExplodeStream(AcDbVoidPtrArray &entArray) { m_pEntSet = &entArray; m_nColor = 256; m_bIsDragging = Adesk::kFalse; //add by zjq on 100629 TArch8.5 m_crColor = AcCmColor(); } XExplodeStream::~XExplodeStream() { } BOOL XExplodeStream::IsFullExplode() const { return m_bFullExplode; } BOOL XExplodeStream::IsExportTch4() const { return m_bExportTch4; } AcDbVoidPtrArray * XExplodeStream::GetEntitySet() { return m_pEntSet; } Adesk::UInt16 XExplodeStream::GetColor() const { return m_nColor; } void XExplodeStream::SetColor(Adesk::UInt16 nColor) { m_nColor = nColor; } //add by zjq on 100629 TArch8.5 //COLORREF XExplodeStream::GetTrueColor() const AcCmColor XExplodeStream::GetTrueColor() const { return m_crColor; } //void XExplodeStream::SetTrueColor(COLORREF crRef) void XExplodeStream::SetTrueColor(AcCmColor crRef) { m_crColor = crRef; } // 设置图层,线型,颜色 void XExplodeStream::SetPropertiesFrom(const AcDbEntity *pEnt) { ASSERT(pEnt); m_idLinetype = pEnt->linetypeId(); m_idLayer = pEnt->layerId(); m_nColor = pEnt->colorIndex(); #if ARX > 17 m_idMaterial = pEnt->materialId(); #endif } // 往集合加入实体, 并设置通用的三个属性 void XExplodeStream::Append(AcDbEntity *pEnt, BOOL bUseAutoProp) { ASSERT(m_pEntSet); if (bUseAutoProp && IsAutoProp()) { if (!!m_idLayer) { pEnt->setLayer(m_idLayer); } if (!!m_idLinetype) { pEnt->setLinetype(m_idLinetype); } #if ARX > 17 if (!!m_idMaterial) { pEnt->setMaterial(m_idMaterial); } #endif //modify by zjq on 100629 //pEnt->setColorIndex(m_nColor); if (m_crColor == AcCmColor()) { pEnt->setColorIndex(m_nColor); } else { pEnt->setColor(m_crColor); } } m_pEntSet->append(pEnt); } BOOL XExplodeStream::MakeBlockInsert(const XPoint &ptBase) { if (m_pEntSet->isEmpty()) { return FALSE; } AcDbBlockTableRecord *pBlockTableRec; AcDbObjectId blockTableRecordId,EntId; AcDbBlockTable *pBlockTable = NULL; AcDbBlockReference *pBlk; AcDbEntity *pEnt; int i; pBlockTableRec = new AcDbBlockTableRecord(); pBlockTableRec->setName(_T("*U")); acdbCurDwg()->getBlockTable(pBlockTable,AcDb::kForWrite); pBlockTable->add(blockTableRecordId, pBlockTableRec); pBlockTable->close(); pBlockTableRec->setOrigin(ptBase); for (i = 0;i < m_pEntSet->length();i++) { pEnt = (AcDbEntity *)(*m_pEntSet)[i]; pBlockTableRec->appendAcDbEntity(EntId,pEnt); pEnt->close(); } pBlockTableRec->close(); //insert block pBlk = new AcDbBlockReference(ptBase,blockTableRecordId); if (!!m_idLayer) { pBlk ->setLayer(m_idLayer); } #if ARX > 17 if (!!m_idMaterial) { pBlk->setMaterial(m_idMaterial); } #endif while (!m_pEntSet->isEmpty()) { m_pEntSet->removeAt(0); } m_pEntSet->append(pBlk); pBlockTable = NULL; return TRUE; } void XExplodeStream::DrawEntity(const AcDbEntity &ent) { AcDbEntity *pEnt = (AcDbEntity *)ent.clone(); ASSERT(pEnt); m_pEntSet->append(pEnt); } void XExplodeStream::Polyline(AcDbPolyline &pline) { Append((AcDbEntity *)pline.clone()); } void XExplodeStream::DrawLine(const XLine &ln, double nThickness) { AcDbLine *line = new AcDbLine(ln.GetStartPoint(), ln.GetEndPoint()); line->setThickness(nThickness); Append(line); } void XExplodeStream::DrawArc(const XArc &ar, double nThickness) { AcDbArc *pArc = new AcDbArc(ar.GetCenterPt(), ar.GetRadius(), ar.GetStarAngle(), ar.GetEndAngle()); pArc->setThickness(nThickness); Append(pArc); } void XExplodeStream::DrawCircle(const XCircle &cir, double nThickness) { AcDbCircle *pCir = new AcDbCircle(cir.GetCenterPt(), AcGeVector3d(0,0,1), cir.GetRadius()); pCir->setThickness(nThickness); Append(pCir); } void XExplodeStream::DrawXPoly(const XPoly2D &poly,double nThickness) { AcDbPolyline *pline = new AcDbPolyline; PolyConvert(poly, *pline); pline->setThickness(nThickness); Append(pline); } const TCHAR * XExplodeStream::Descriptor() { return _T("XExplodeStream"); } const TCHAR * XExplodeStream::Desc() { return Descriptor(); } Adesk::Boolean XExplodeStream::IsDragging() const { return m_bIsDragging; } void XExplodeStream::SetIsDragging(Adesk::Boolean bDragging) { m_bIsDragging = bDragging; } AcDbObjectId XExplodeStream::GetLineTypeId() const { return m_idLinetype; } AcDbObjectId XExplodeStream::GetMaterialId()const { return m_idMaterial; } Acad::ErrorStatus XExplodeStream::SetLineType(const TCHAR *pltype) { AcDbObjectId idLineType = GetLinetypeIdFromString(pltype); if (!idLineType) { return Acad::eInvalidInput; } m_idLinetype = idLineType; return Acad::eOk; } Acad::ErrorStatus XExplodeStream::SetLineType(AcDbObjectId idLineType) { m_idLinetype = idLineType; return Acad::eOk; } Acad::ErrorStatus XExplodeStream::SetMaterial(AcDbObjectId idMaterial) { if (idMaterial.isValid()) { m_idMaterial = idMaterial; } return Acad::eOk; } // 对polyOutline的方向没有规定 void XExplodeStream::DrawSolid(const XPoly2D &polyOutline) { if (polyOutline.Area() < 1E-6)//add by W on 070306 { return; } AcDbHatch *pHatch = NewHatchFromPoly2D(polyOutline, _T("SOLID"), 1.0); ASSERT(pHatch); Append(pHatch); } void XExplodeStream::DrawHatch(const XPoly2D &polyOutline, const TCHAR *pszPattern, double nScale) { if (!pszPattern) { return; } if (polyOutline.Area() < 1E-6)//add by W on 070306 { return; } AcDbHatch *pHatch = NewHatchFromPoly2D(polyOutline, pszPattern, nScale); if (!pHatch) { return; } Append(pHatch); } void XExplodeStream::DrawHatchEx(const XPoly2D &polyOutline, const TCHAR *pszPattern, double nScale,double rotation) { if (!pszPattern) { return; } if (polyOutline.Area() < 1E-6)//add by W on 070306 { return; } AcDbHatch *pHatch = NewHatchFromPoly2D(polyOutline, pszPattern, nScale,rotation); if (!pHatch) { return; } Append(pHatch); } void XExplodeStream::DrawShell(Adesk::UInt32 nbVertex, const AcGePoint3d* pVertexList, Adesk::UInt32 faceListSize, const Adesk::Int32* pFaceList, const AcGiEdgeData* pEdgeData) { XPolygonEx *pLast = NULL; XVector3D vtEcs; Adesk::UInt8* visibleArray = pEdgeData ? pEdgeData->visibility() : NULL; Adesk::UInt32 j = 0; //面索引 int nEdgeIndex = 0; DList lstPolygons; XHoleModel *pHoleModel = NULL; while (j < faceListSize) { Adesk::Int32 nFaceNum = pFaceList[j]; if (nFaceNum > 0) //外轮廓 { pHoleModel = new XHoleModel; lstPolygons.Append(pHoleModel); //XPolygonEx &polyEx1 = pHoleModel->m_outline; XPolygonEx &polyEx1 = pHoleModel->GetOutLine(); for (Adesk::Int32 i = 1; i <= abs(nFaceNum); i++) { int nVertNum = pFaceList[j + i]; XPoint ptVert = pVertexList[nVertNum]; BOOL bVis = TRUE; if (visibleArray) { if (visibleArray[nEdgeIndex] == kAcGiInvisible || visibleArray[nEdgeIndex] == kAcGiSilhouette) { bVis = FALSE; } } polyEx1.AppendNode(ptVert, bVis); nEdgeIndex++; } ASSERT(pHoleModel->IsValid()); } else //洞口 { ASSERT(pHoleModel->IsValid()); XPolygonEx *pHole = new XPolygonEx; for (Adesk::Int32 i = 1; i <= abs(nFaceNum); i++) { int nVertNum = pFaceList[j + i]; XPoint ptVert = pVertexList[nVertNum]; BOOL bVis = TRUE; if (visibleArray) { if (visibleArray[nEdgeIndex] == kAcGiInvisible || visibleArray[nEdgeIndex] == kAcGiSilhouette) { bVis = FALSE; } } pHole->AppendNode(ptVert, bVis); nEdgeIndex++; } ASSERT(pHole->Length() >= 3); //pHoleModel->m_holes.Append(pHole); pHoleModel->AppendHoleList(pHole); } j += abs(nFaceNum) + 1; } for (int k = 0; k < lstPolygons.Length(); k++) { XHoleModel *pModel = lstPolygons[k]; DList lstTris; if (!pModel->Triangulate(FALSE, lstTris)) { } else { for (int n = 0; n < lstTris.Length(); n++) { XTriangle *triangle = lstTris[n]; Adesk::Boolean bSide1 = !(triangle->m_nFlag&SIDE1_INVISIBLE); Adesk::Boolean bSide2 = !(triangle->m_nFlag&SIDE2_INVISIBLE); Adesk::Boolean bSide3 = !(triangle->m_nFlag&SIDE3_INVISIBLE); AcDbFace *pFace = new AcDbFace(triangle->vertex1, triangle->vertex2,triangle->vertex3, triangle->vertex1, bSide1, bSide2, bSide3); Append(pFace); } } } } // 根据给定的内外边界, 绘制三维外壳 // 如果有圆弧边界,则必须平行于XY平面 void XExplodeStream::DrawShell(const XPoly2D &polyOut1, const DList &lstPolyIn1) { int i = 0; if (g_bEnableAcis) { XPoly poly1, poly2; ((XPoly2D &)polyOut1).MapToPolygon1(poly1, _AS_SYS_UNIT(g_nCirDeviation)); ASSERT(poly1.Length() > 2); XHoleModel model; for (int k = 0; k < poly1.Length(); k++) { //model.m_outline.AppendNode(*poly1[k], TRUE); model.GetOutLine().AppendNode(*poly1[k], TRUE); } for (i = 0; i < lstPolyIn1.Length(); i++) { ((XPoly2D &)lstPolyIn1[i]).MapToPolygon1(poly2, _AS_SYS_UNIT(g_nCirDeviation)); XPolygonEx *polyEx2 = new XPolygonEx(poly2); //model.m_holes.Append(polyEx2); model.AppendHoleList(polyEx2); } XTrianglePface lstTris; if (model.Triangulate(FALSE, lstTris)) { for (int n = 0; n < lstTris.Length(); n++) { XTriangle *triangle = lstTris[n]; Adesk::Boolean bSide1 = !(triangle->m_nFlag&SIDE1_INVISIBLE); Adesk::Boolean bSide2 = !(triangle->m_nFlag&SIDE2_INVISIBLE); Adesk::Boolean bSide3 = !(triangle->m_nFlag&SIDE3_INVISIBLE); AcDbFace *pFace = new AcDbFace(triangle->vertex1, triangle->vertex2, triangle->vertex3, triangle->vertex1, bSide1, bSide2, bSide3); Append(pFace); } } } else { DList lstSegs; ExplodePoly2D(polyOut1, lstSegs); for (i = 0; i < lstPolyIn1.Length(); i++) { ExplodePoly2D(polyOut1, lstSegs); } for (i = 0; i < lstSegs.Length(); i++) { Append(lstSegs[i]->AsAcDbCurve()); } } } // make a 3DSolid void XExplodeStream::DrawBody(const XPoly2D &polySrc, const XVector3D &vtOffset) { DList lstPoly; DrawBody(polySrc, lstPoly, vtOffset); } void XExplodeStream::DrawBody(const XPoly2D &polyOut, const DList &lstHoles, const XVector3D &vtOffset) { if (g_bEnableAcis) { if (g_bExplodeMesh) { // 绘制侧面 for (int i = 0; i < lstHoles.Length(); i++) { DrawMesh(lstHoles[i], vtOffset); } DrawMesh(polyOut, vtOffset); //绘制前台面 DrawShell(polyOut, lstHoles); //绘制后台面 XPoly2D polyUp(polyOut); for (int i = 0; i < polyUp.Length(); i++) { *polyUp[i] += vtOffset; } DList lstHoleUp; for (int n = 0; n < lstHoles.Length(); n++) { XPoly2D *pHole = new XPoly2D(lstHoles[n]); for (int j = 0; j < pHole->Length(); j++) { *(*pHole)[j] += vtOffset; } lstHoleUp.Append(pHole); } DrawShell(polyUp, lstHoleUp); } else { AcDbRegion *regioni = AsRegion(polyOut); if (!regioni) { return; } AcGeVector3d vtNormalI; VERIFY(regioni->getNormal(vtNormalI) == Acad::eOk); double dThickI = vtOffset.Length(); if (vtNormalI.angleTo(vtOffset) > PI / 2.0) { dThickI = -dThickI; } AcDb3dSolid *solid3di = new AcDb3dSolid(); VERIFY(solid3di->extrude(regioni, dThickI,0.0) == Acad::eOk); delete regioni; for (int n = 0; n < lstHoles.Length(); n++) { const XPoly2D polyIn = lstHoles[n]; AcDbRegion *regionj = AsRegion(polyIn); if (!regionj) { continue; } AcGeVector3d vtNormalJ; VERIFY(regionj->getNormal(vtNormalJ) == Acad::eOk); AcDb3dSolid *solid3dj = new AcDb3dSolid(); double dThickJ = vtOffset.Length(); if (vtNormalJ.angleTo(vtOffset) > PI / 2.0) { dThickJ = -dThickJ; } VERIFY(solid3dj->extrude(regionj,dThickJ,0.0) == Acad::eOk); delete regionj; if (solid3di->booleanOper(AcDb::kBoolSubtract,solid3dj) != Acad::eOk) { delete solid3di; delete solid3dj; return; } delete solid3dj; } if (solid3di->isNull()) { delete solid3di; } else { Append(solid3di); } } } else { XPoly2D polyOffsetOut(polyOut); DList lstSegs; for (int i = 0; i < polyOffsetOut.Length(); i++) { *polyOffsetOut[i] += vtOffset; lstSegs.Append(new XCurveSegment(polyOut[i], *polyOffsetOut[i], 0.0)); } ExplodePoly2D(polyOut, lstSegs); ExplodePoly2D(polyOffsetOut, lstSegs); for (int n = 0; n < lstHoles.Length(); n++) { XPoly2D polyIn(lstHoles[n]); XPoly2D polyOffsetIn(polyIn); for (int i = 0; i < polyOffsetIn.Length(); i++) { *polyOffsetIn[i] += vtOffset; lstSegs.Append(new XCurveSegment(*polyIn[i], *polyOffsetIn[i], 0.0)); } ExplodePoly2D(polyIn, lstSegs); ExplodePoly2D(polyOffsetIn, lstSegs); } for (int i = 0; i < lstSegs.Length(); i++) { Append(lstSegs[i]->AsAcDbCurve()); } } } void XExplodeStream::DrawBody(const XPoly2D &polyOut, const XPoly2D &polyIn, const XVector3D &vtOffset) { DList lstHoles; lstHoles.Append(new XPoly2D(polyIn)); DrawBody(polyOut, lstHoles, vtOffset); } void XExplodeStream::DrawMesh( const Adesk::UInt32 rows, const Adesk::UInt32 columns, const AcGePoint3d* pVertexList, const AcGiEdgeData* pEdgeData) { for (Adesk::UInt32 m = 0; m < rows - 1; m++) { for (Adesk::UInt32 n = 0; n < columns - 1; n++) { int idVertex1 = m * columns + n; int idVertex2 = m * columns + n + 1; int idVertex3 = (m + 1) * columns + n + 1; int idVertex4 = (m + 1) * columns + n; Adesk::Boolean bVis1 = Adesk::kTrue, bVis2 = Adesk::kTrue, bVis3 = Adesk::kTrue, bVis4 = Adesk::kTrue; if (pEdgeData) { Adesk::UInt8 *pVisArray = pEdgeData->visibility(); if (pVisArray) { bVis1 = pVisArray[m * (columns - 1) + n]; bVis2 = pVisArray[rows * (columns - 1) + m * columns + n + 1]; bVis3 = pVisArray[(m + 1) * (columns - 1) + n]; bVis4 = pVisArray[rows * (columns - 1) + m * columns + n]; } } AcDbFace *pFace = new AcDbFace(pVertexList[idVertex1], pVertexList[idVertex2], pVertexList[idVertex3], pVertexList[idVertex4], bVis1, bVis2, bVis3, bVis4); Append(pFace); } } } // 根据给定的边界和凸起方向, 绘制三维外壳 void XExplodeStream::DrawMesh(const XPoly2D &polyOut, const XVector3D &vtOffset) { XPoly poly; polyOut.AsOpenPoly1(poly, _AS_SYS_UNIT(g_nCirDeviation)); //变成开口的poly, 如果原先封闭, 则起点复制为终点 int nColumn = poly.Length(); //+1; int nRow = 2; XPoint *ptArray = new XPoint[nColumn*nRow]; for (int m = 0; m < nRow; m++) { for (int n = 0; n < nColumn; n++) { int nBase = m * nColumn; ptArray[nBase + n] = *poly[n]; if (m == 1) { ptArray[nBase + n] += vtOffset; } } } AcGePoint3dArray vertexArray; for (int i = 0; i < nColumn * nRow; i++) { vertexArray.append(ptArray[i]); } AcDbPolygonMesh mesh(AcDb::kSimpleMesh, nRow, nColumn, vertexArray, Adesk::kFalse, Adesk::kFalse); AcDbVoidPtrArray entSet; mesh.explode(entSet); int nCount = entSet.length(); for (int idx = 0; idx < nCount; idx++) { Append((AcDbEntity *)entSet[idx]); } delete [] ptArray; } // 显示分别连接两个区域的边缘构成的侧面 void XExplodeStream::DrawMesh(const XPoly2D &polyRegion1, const XPoly2D &polyRegion2) { XPoly poly1, poly2; polyRegion1.AsOpenPoly(poly1); //变成开口的poly, 如果原先封闭, 则起点复制为终点 polyRegion2.AsOpenPoly(poly2); if (poly1.Length() != poly2.Length()) { return; } int nColumn = poly1.Length(); //+1; int nRow = 2; XPoint *ptArray = new XPoint[nColumn * nRow]; for (int m = 0; m < nRow; m++) { for (int n = 0; n < nColumn; n++) { int nBase = m * nColumn; if (!m) { ptArray[nBase + n] = *poly1[n]; } else { ptArray[nBase + n] = *poly2[n]; } } } AcGePoint3dArray vertexArray; for (int i = 0; i < nColumn*nRow; i++) { vertexArray.append(ptArray[i]); } AcDbPolygonMesh mesh(AcDb::kSimpleMesh, nRow, nColumn, vertexArray, Adesk::kFalse, Adesk::kFalse); AcDbVoidPtrArray entSet; mesh.explode(entSet); int nCount = entSet.length(); for (int idx = 0; idx < nCount; idx++) { Append((AcDbEntity *)entSet[idx]); } delete [] ptArray; } void XExplodeStream::DrawFace(const X3DFace &face0) { if (face0.IsPoint() || face0.IsLinear()) { #ifndef NDEBUG XGeLib::adsout << _T("\nXExplodeStream: Bad 3dface is skipped!"); #endif } else { X3DFace face(face0); if (face.IsTriangle(2)) { if (face.GetVertex(0).Distance(face.GetVertex(1)) < _DIST_SNAP) { face.MoveShift(FALSE); } else if (face.GetVertex(1).Distance(face.GetVertex(2)) < _DIST_SNAP) { face.MoveShift(FALSE); face.MoveShift(FALSE); } else if (face.GetVertex(2).Distance(face.GetVertex(3)) < _DIST_SNAP) { face.MoveShift(TRUE); } ASSERT(face.IsTriangle(1)); } AcDbFace *pDbFace = new AcDbFace(face.GetVertex(0), face.GetVertex(1), face.GetVertex(2), face.GetVertex(3), ((face.GetFlag() & 0x01) == 0), ((face.GetFlag() & 0x02) == 0), ((face.GetFlag() & 0x04) == 0), ((face.GetFlag() & 0x08) == 0)); Append(pDbFace); } } void XExplodeStream::DrawText(const TCHAR *pszContent) { AcDbObjectId idTextStyle = m_idTextStyle; if (!idTextStyle) { XString sTextStyle; xg_getvar(_T("TEXTSTYLE"), sTextStyle); idTextStyle = GetTextStyleId(sTextStyle); } if (!idTextStyle || !pszContent) { return; } XDbObject obj(idTextStyle, AcDb::kForRead); if (!obj) { return; } AcDbTextStyleTableRecord *newStyle = AcDbTextStyleTableRecord::cast(obj.m_pObject); if (!newStyle) { return; } double nTextSize = m_nHeight; if (nTextSize < 1.0E-5) { nTextSize = newStyle->textSize(); } if (nTextSize < 1.0E-5) { xg_getvar(_T("TEXTSIZE"), &nTextSize); if (nTextSize < 1.0E-5) { return; } } double nWidthFactor = newStyle->xScale(); if (m_nControlFlag & EDF_XSCALE) //Modify on 2002/10/13 { nWidthFactor = m_nWidthFactor; } //refreshed by W on 050424,原错误:PI/2到3PI/2转角的文字被强制修改为(-PI/2,PI/2)区间 //AcDbText *pAttrib = new AcDbText(m_ptLocation, pszContent, idTextStyle, nTextSize, XExport::xg_angle(m_nRotation)); AcDbText *pAttrib = new AcDbText(m_ptLocation, pszContent, idTextStyle, nTextSize, m_nRotation); pAttrib->setHeight(nTextSize); pAttrib->setWidthFactor(nWidthFactor); AcDb::TextHorzMode nHMode; AcDb::TextVertMode nVMode; Adesk::UInt16 nAlignMode = GetTextAlignment(m_align); nHMode = (AcDb::TextHorzMode)LOBYTE(nAlignMode); nVMode = (AcDb::TextVertMode)HIBYTE(nAlignMode); pAttrib->setHorizontalMode(nHMode); pAttrib->setVerticalMode(nVMode); pAttrib->setAlignmentPoint(m_ptLocation); Append(pAttrib); } void XExplodeStream::DrawTextFit(const TCHAR *pszText, XPoint pt1, XPoint pt2, double nTextHeight) { ASSERT(m_bInitStyle); double nTextSize = nTextHeight; if (nTextSize < 1.0E-5) { return; } double nOldSize = m_textStyle.textSize(); m_textStyle.setTextSize(nTextSize); Adesk::Boolean bIncludeSpace = Adesk::kTrue; TCHAR *pTypeface = NULL; Adesk::Boolean bBold, bItalic; #if ARX < 21 int tmp0, tmp1; BOOL bWinFont = (m_textStyle.font(pTypeface, bBold, bItalic, tmp0, tmp1) == Acad::eOk); #else Autodesk::AutoCAD::PAL::FontUtils::FontPitch tmp0; Autodesk::AutoCAD::PAL::FontUtils::FontFamily tmp1; Charset charset; BOOL bWinFont = (m_textStyle.font(pTypeface, bBold, bItalic, charset, tmp0, tmp1) == Acad::eOk); #endif if (bWinFont) { if (!pTypeface || !pTypeface[0]) { bWinFont = FALSE; } } if (pTypeface) { delete[] pTypeface; } if (bWinFont) { bIncludeSpace = Adesk::kTrue; } else { bIncludeSpace = Adesk::kFalse; const TCHAR *pShxFile = m_textStyle.fileName(); if (pShxFile) { XPathParser paser(pShxFile); _tcsupr(paser.m_sFileName); TCHAR sFilter[] = _T("GBE*,GOTH*,ISO*,SCRIPT*,ROMAN*"); if (ads_wcmatch(paser.m_sFileName, sFilter) == RTNORM) { bIncludeSpace = Adesk::kTrue; } } } AcGePoint2d ptExt = m_textStyle.extents(pszText, bIncludeSpace, -1, Adesk::kFalse); double nWidth = ptExt[0]; double nWidthFactor = pt1.Distance2d(pt2) / nWidth; m_textStyle.setTextSize(nOldSize); AcDbObjectId idTextStyle = m_idTextStyle;; if (!idTextStyle) { XString sTextStyle; xg_getvar(_T("TEXTSTYLE"), sTextStyle); idTextStyle = GetTextStyleId(sTextStyle); } AcDbText *pAttrib = new AcDbText; pAttrib->setHorizontalMode(AcDb::kTextFit); pAttrib->setVerticalMode(AcDb::kTextBase); pAttrib->setTextStyle(idTextStyle); pAttrib->setTextString(pszText); pAttrib->setPosition(pt1); pAttrib->setAlignmentPoint(pt2); pAttrib->setHeight(nTextHeight); //modified by W 051023 pAttrib->setWidthFactor(nWidthFactor); pAttrib->setHorizontalMode(AcDb::kTextFit); //add by W on 060218 XPoint vt = pt2 - pt1; pAttrib->setRotation(vt.AsAcGeVector2d().angle()); Append(pAttrib); } // 增加一图块 void XExplodeStream::DrawBlock(const AcDbBlockTableRecord &blockRec, const XPoint &ptInsert, const AcGeScale3d &scales, double nRot, BOOL bMakeBlock) { AcDbObjectId idBlock = blockRec.objectId(); if (!idBlock) { return; } AcDbBlockReference * pInsert = new AcDbBlockReference(ptInsert, idBlock); pInsert->setScaleFactors(scales); pInsert->setRotation(nRot); if (bMakeBlock) { Append(pInsert); } else { XMasterProperties prop; InitModel(prop, pInsert, NULL, *m_pEntSet); delete pInsert; } } void XExplodeStream::DrawAtomicEntSet(const AcDbVoidPtrArray &entSet, const AcGeMatrix3d &matTrans) { TCHAR szMatch[256] = _T("AEC_*"); int nCount = entSet.length(); for (int i = 0; i < nCount; i++) { AcDbEntity *pEntity = (AcDbEntity *)entSet[i]; AcDbPolyline *pline = AsPolyline(pEntity); if (pline) { XPoly2D poly2d; PolyConvert(*pline, poly2d); XVector3D vtNormal; (AcGeVector3d &)vtNormal = pline->normal(); double nElev = 0.0; AcGeMatrix2d xform2d(matTrans.convertToLocal(vtNormal,nElev)); ads_matrix mat0 = { {xform2d(0,0), xform2d(0,1), 0, xform2d(0,2)}, {xform2d(1,0), xform2d(1,1), 0, xform2d(1,2)}, {0,0,1, nElev}, {0,0,0,1} }; poly2d.TransUCS(mat0); PolyConvert(poly2d, *pline); ((AcGeVector3d &)vtNormal).normalize(); pline->setNormal(vtNormal); Append(pline); } else { AcDbEntity *pEntCloned = NULL; // ARC,CIRCLE Transform后丢失厚度信息 Acad::ErrorStatus es = pEntity->getTransformedCopy(matTrans, pEntCloned); if (es == Acad::eOk && pEntCloned) { XString sDxfName; sDxfName = pEntCloned->isA()->dxfName(); if (ads_wcmatch(sDxfName, szMatch) == RTNORM && IsFullExplode()) { pEntCloned->explode(*m_pEntSet); delete pEntCloned; } else { Append(pEntCloned); } } } } } AcDbObjectId XExplodeStream::GetLayerId() const { return m_idLayer; } Acad::ErrorStatus XExplodeStream::SetLayer(const AcDbObjectId &id) { m_idLayer = id; return Acad::eOk; } Acad::ErrorStatus XExplodeStream::SetLayer(const TCHAR *pszLayer) { AcDbObjectId id = GetLayerIdFromString(pszLayer); if (!id) { return Acad::eInvalidInput; } return SetLayer(id); }