#include "StdAfx.h" #include "StdArx.h" #include "dbhatch.h" #include "dbelipse.h" #include "TDbEquWorldDraw.h" ////////////////////////////////////////////////////////////////////////// // TDbEquWorldGeometry ACRX_DEFINE_MEMBERS(TDbEquWorldGeometry); TDbEquWorldGeometry::TDbEquWorldGeometry(TDbEquWorldDraw* pMode) { m_pMode = pMode; m_nPart = 8; } TDbEquWorldGeometry::~TDbEquWorldGeometry() { } void TDbEquWorldGeometry::setExtents(AcGePoint3d *pNewExtents) const { } void TDbEquWorldGeometry::startAttributesSegment() { } void TDbEquWorldGeometry::getModelToWorldTransform(AcGeMatrix3d&) const { } void TDbEquWorldGeometry::getWorldToModelTransform(AcGeMatrix3d&) const { } Adesk::Boolean TDbEquWorldGeometry::pushModelTransform(const AcGeVector3d & vNormal) { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::pushModelTransform(const AcGeMatrix3d & xMat) { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::popModelTransform() { return Adesk::kFalse; } #if ADS > 19 Adesk::Boolean TDbEquWorldGeometry::edge(const AcArray& edges) const { return Adesk::kFalse; } #endif Adesk::Boolean TDbEquWorldGeometry::circle(const AcGePoint3d& center, const double radius, const AcGeVector3d& normal ) const { if(AcGeVector3d::kZAxis == normal) { // 圆形以多条直线进行模拟 int nPart = m_nPart * 4; AcGePoint3d* ptBase = new AcGePoint3d[nPart]; // 牺牲内存以提高效率 AcGeVector3d vtCal = AcGeVector3d::kXAxis; // 计算第一个点 *ptBase = center + vtCal * radius; // 依次计算余下的点 double dAngPart = (PI * 2) / nPart; for(int i = 1; i < m_nPart * 4; i++) { vtCal.rotateBy(dAngPart, normal); vtCal.normalize(); *(ptBase + i) = center + vtCal * radius; m_pMode->AddCurveElement(*(ptBase + i - 1), *(ptBase + i)); } m_pMode->AddCurveElement(*(ptBase + nPart - 1), *ptBase); delete []ptBase; return Adesk::kTrue; } return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::circle(const AcGePoint3d& first, const AcGePoint3d& second, const AcGePoint3d& third ) const { AcGeCircArc3d cir(first, second, third); return circle(cir.center(), cir.radius(), cir.normal()); } Adesk::Boolean TDbEquWorldGeometry::circularArc(const AcGePoint3d& center, const double radius, const AcGeVector3d& normal, const AcGeVector3d& startVector, const double sweepAngle, const AcGiArcType arcType) const { if(AcGeVector3d::kZAxis == normal) { // 圆弧在进行非等比变化时不够精确 以多条直线进行模拟 int iPart = m_nPart * 2; AcGePoint3d* ptBase = new AcGePoint3d[iPart + 1]; // 牺牲内存以提高效率 AcGeVector3d vtCal = startVector; vtCal.normalize(); // 计算第一个点 *ptBase = center + vtCal * radius; // 依次计算余下的点 double dAngPart = sweepAngle / iPart; for(int i = 1; i < iPart + 1; i++) { vtCal.rotateBy(dAngPart, normal); vtCal.normalize(); *(ptBase + i) = center + vtCal * radius; m_pMode->AddCurveElement(*(ptBase + i - 1), *(ptBase + i)); } if(kAcGiArcSector == arcType) { m_pMode->AddCurveElement(center, *ptBase); m_pMode->AddCurveElement(center, *(ptBase + iPart)); } else if(kAcGiArcChord == arcType) { m_pMode->AddCurveElement(*ptBase, *(ptBase + iPart)); } delete []ptBase; return Adesk::kTrue; } return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::circularArc(const AcGePoint3d& start, const AcGePoint3d& point, const AcGePoint3d& end, const AcGiArcType arcType) const { AcGeCircArc3d cir(start, point, end); AcGePoint3d cent = cir.center(); AcGeVector3d vtStart = start - cent; AcGeVector3d vtEnd = end - cent; double dAng = vtStart.angleTo(vtEnd, cir.normal()); return circularArc(cent, cir.radius(), cir.normal(), vtStart, dAng, arcType); } #ifdef _WIN64 Adesk::Boolean TDbEquWorldGeometry::polyline(const Adesk::UInt32 nbPoints, const AcGePoint3d* pVertexList, const AcGeVector3d* pNormal, Adesk::LongPtr lBaseSubEntMarker) const #else Adesk::Boolean TDbEquWorldGeometry::polyline(const Adesk::UInt32 nbPoints, const AcGePoint3d* pVertexList, const AcGeVector3d* pNormal, Adesk::Int32 lBaseSubEntMarker) const #endif { for(Adesk::UInt32 i = 0; i < nbPoints - 1; i++) { m_pMode->AddCurveElement(*(pVertexList + i), *(pVertexList + i + 1)); } return Adesk::kTrue; } Adesk::Boolean TDbEquWorldGeometry::polygon(const Adesk::UInt32 nbPoints, const AcGePoint3d* pVertexList) const { Adesk::UInt32 iNext = 0; for(Adesk::UInt32 i = 0; i < nbPoints; i++) { iNext = i + 1; if(iNext == nbPoints) iNext = 0; m_pMode->AddCurveElement(pVertexList[i], pVertexList[iNext]); } return Adesk::kTrue; } Adesk::Boolean TDbEquWorldGeometry::mesh(const Adesk::UInt32 rows, const Adesk::UInt32 columns, const AcGePoint3d* pVertexList, const AcGiEdgeData* pEdgeData, const AcGiFaceData* pFaceData, const AcGiVertexData* pVertexData) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::mesh(const Adesk::UInt32 rows, const Adesk::UInt32 columns, const AcGePoint3d* pVertexList, const AcGiEdgeData* pEdgeData, const AcGiFaceData* pFaceData, const AcGiVertexData* pVertexData, const bool bAutoGenerateNormals) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::shell(const Adesk::UInt32 nbVertex, const AcGePoint3d* pVertexList, const Adesk::UInt32 faceListSize, const Adesk::Int32* pFaceList, const AcGiEdgeData* pEdgeData, const AcGiFaceData* pFaceData, const AcGiVertexData* pVertexData, const struct resbuf* pResBuf) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::shell(const Adesk::UInt32 nbVertex, const AcGePoint3d* pVertexList, const Adesk::UInt32 faceListSize, const Adesk::Int32* pFaceList, const AcGiEdgeData* pEdgeData, const AcGiFaceData* pFaceData, const AcGiVertexData* pVertexData, const struct resbuf* pResBuf, const bool bAutoGenerateNormals) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::text(const AcGePoint3d& position, const AcGeVector3d& normal, const AcGeVector3d& direction, const double height, const double width, const double oblique, const TCHAR* pMsg) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::text(const AcGePoint3d& position, const AcGeVector3d& normal, const AcGeVector3d& direction, const TCHAR* pMsg, const Adesk::Int32 length, const Adesk::Boolean raw, const AcGiTextStyle &pTextStyle ) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::xline(const AcGePoint3d&, const AcGePoint3d& ) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::ray(const AcGePoint3d&, const AcGePoint3d&) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::pline(const AcDbPolyline& lwBuf, Adesk::UInt32 fromIndex, Adesk::UInt32 numSegs) const { if(AcGeVector3d::kZAxis == lwBuf.normal()) { AcGePoint3d ptLast, ptCurr; lwBuf.getPointAt(0, ptLast); int nNumVerts = lwBuf.numVerts(); double dWidthStr = 0, dWidthEnd = 0; for(int i = 1; i < nNumVerts; i++) { lwBuf.getPointAt(i, ptCurr); lwBuf.getWidthsAt(i, dWidthStr, dWidthEnd); m_pMode->AddCurveElement(ptLast, ptCurr, dWidthStr); ptLast = ptCurr; } if(lwBuf.isClosed()) { lwBuf.getPointAt(0, ptLast); lwBuf.getPointAt(nNumVerts - 1, ptCurr); lwBuf.getWidthsAt(nNumVerts - 1, dWidthStr, dWidthEnd); m_pMode->AddCurveElement(ptLast, ptCurr, dWidthStr); } return Adesk::kTrue; } return Adesk::kTrue; } Adesk::Boolean TDbEquWorldGeometry::draw(AcGiDrawable* pDrawable) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::pushClipBoundary(AcGiClipBoundary * pBoundary) { return Adesk::kTrue; } void TDbEquWorldGeometry::popClipBoundary() { return; } #if ADS>17 AcGeMatrix3d TDbEquWorldGeometry::pushPositionTransform (AcGiPositionTransformBehavior behavior, const AcGePoint3d& offset) { return AcGeMatrix3d::kIdentity; } AcGeMatrix3d TDbEquWorldGeometry::pushPositionTransform (AcGiPositionTransformBehavior behavior, const AcGePoint2d& offset) { return AcGeMatrix3d::kIdentity; } AcGeMatrix3d TDbEquWorldGeometry::pushScaleTransform (AcGiScaleTransformBehavior behavior, const AcGePoint3d& extents) { return AcGeMatrix3d::kIdentity; } AcGeMatrix3d TDbEquWorldGeometry::pushScaleTransform (AcGiScaleTransformBehavior behavior, const AcGePoint2d& extents) { return AcGeMatrix3d::kIdentity; } AcGeMatrix3d TDbEquWorldGeometry::pushOrientationTransform (AcGiOrientationTransformBehavior behavior) { return AcGeMatrix3d::kIdentity; } Adesk::Boolean TDbEquWorldGeometry::polyline(const AcGiPolyline& polylineObj) const { return polyline(polylineObj.points(), polylineObj.vertexList(), polylineObj.normal(), polylineObj.baseSubEntMarker()); } Adesk::Boolean TDbEquWorldGeometry::polyPolyline (Adesk::UInt32 nbPolylines,const AcGiPolyline* pPolylines) const { Adesk::Boolean bAborting = false; for (Adesk::UInt32 i = 0; i < nbPolylines && !bAborting; ++i) { bAborting = polyline(pPolylines[i]); } return bAborting; } Adesk::Boolean TDbEquWorldGeometry::polyPolygon(const Adesk::UInt32 numPolygonIndices, const Adesk::UInt32* numPolygonPositions, const AcGePoint3d* polygonPositions, const Adesk::UInt32* numPolygonPoints, const AcGePoint3d* polygonPoints, const AcCmEntityColor* outlineColors, const AcGiLineType* outlineTypes, const AcCmEntityColor* fillColors, const AcCmTransparency* fillOpacities) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::image(const AcGiImageBGRA32& imageSource, const AcGePoint3d& position, const AcGeVector3d& u, const AcGeVector3d& v, TransparencyMode transparencyMode )const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::rowOfDots(int count,const AcGePoint3d& start,const AcGeVector3d& step) const { return Adesk::kFalse; } Adesk::Boolean TDbEquWorldGeometry::ellipticalArc(const AcGePoint3d& center, const AcGeVector3d& normal, double majorAxisLength, double minorAxisLength, double startDegreeInRads, double endDegreeInRads, double tiltDegreeInRads, AcGiArcType arcType) const { #if ADS > 19 if(AcGeVector3d::kZAxis == normal || -AcGeVector3d::kZAxis == normal) { if (fabs(majorAxisLength - minorAxisLength) < g_fZero) {// add by cq 2016-09-13 椭圆按照圆弧处理 double dStartAngle = startDegreeInRads + tiltDegreeInRads; AcGeVector3d startVector(cos(dStartAngle), sin(dStartAngle), 0); return circularArc(center, majorAxisLength, AcGeVector3d::kZAxis, startVector, endDegreeInRads - startDegreeInRads, arcType); /* double dRadius = majorAxisLength; int iPart = m_nPart * 2; AcGePoint3d* ptBase = new AcGePoint3d[iPart + 1]; double dStart = AngleRangeTo2PI(startDegreeInRads); AcGeVector3d vtCal(cos(dStart), sin(dStart), 0); vtCal.rotateBy(tiltDegreeInRads, normal); // 计算第一个点 *ptBase = center + vtCal.normalize() * dRadius; // 依次计算余下的点 double dAngPart = (endDegreeInRads-startDegreeInRads) / iPart; for(int i = 1; i < iPart + 1; i++) { vtCal.rotateBy(dAngPart, normal); *(ptBase + i) = center + vtCal.normalize() * dRadius; m_pMode->AddCurveElement(*(ptBase + i - 1), *(ptBase + i)); } if(kAcGiArcSector == arcType) { m_pMode->AddCurveElement(center, *ptBase); m_pMode->AddCurveElement(center, *(ptBase + iPart)); } else if(kAcGiArcChord == arcType) { m_pMode->AddCurveElement(*ptBase, *(ptBase + iPart)); } delete []ptBase; */ } else {// 绘制椭圆 if (-AcGeVector3d::kZAxis == normal) { tiltDegreeInRads = PI - tiltDegreeInRads; } AcGeVector3d majorAxis(cos(tiltDegreeInRads), sin(tiltDegreeInRads), 0); AcDbEllipse elps(center, normal, majorAxis, minorAxisLength / majorAxisLength); elps.setMajorRadius(majorAxisLength); elps.setMinorRadius(minorAxisLength); AcGeDoubleArray arPara; double dStartPara = AngleRangeTo2PI(startDegreeInRads); double dEndPara = AngleRangeTo2PI(endDegreeInRads); int iPart = m_nPart * 5; if (dStartPara - dEndPara < g_fZero) { arPara.append(dStartPara); double dAngPart = (dEndPara-dStartPara) / iPart; for(int i = 1; i < iPart; i++) { arPara.append(dStartPara + dAngPart * i); } arPara.append(dEndPara); } else { arPara.append(0); double dAngPart = dEndPara / iPart; for(int i = 1; i < iPart; i++) { arPara.append(dAngPart * i); } arPara.append(dEndPara); arPara.append(dStartPara); dAngPart = (PI * 2 - dStartPara) / iPart; for(int i = 1; i < iPart; i++) { arPara.append(dStartPara + dAngPart * i); } arPara.append(PI * 2); } AcDbVoidPtrArray arSplit; elps.getSplitCurves(arPara, arSplit); int iLen = arSplit.length(); AcDbCurve *pCurve = NULL; AcGePoint3d ptStart, ptEnd; for (int i = 0; i < iLen; ++i) { pCurve = (AcDbCurve*)arSplit[i]; if (NULL != pCurve) { pCurve->getStartPoint(ptStart); pCurve->getEndPoint(ptEnd); if (ptStart.distanceTo(ptEnd) - majorAxisLength / 2 < g_fZero) { m_pMode->AddCurveElement(ptStart, ptEnd); } } delete pCurve; } } return Adesk::kTrue; } #endif return Adesk::kFalse; } #endif ////////////////////////////////////////////////////////////////////////// // TDbEquWorldDraw ACRX_DEFINE_MEMBERS(TDbEquWorldDraw); TDbEquWorldDraw::TDbEquWorldDraw() { memset(&m_elemCurve, 0, sizeof(TDb::TCurveElement)); m_pGeometry = new TDbEquWorldGeometry(this); m_pSubEntityTraits = new TGGiCustomSubEntityTraits; m_pCompCuve = NULL; m_pLstCurSegs = NULL; m_dPScale = DocGetPScale(); if(EQUAL_ZERO(m_dPScale)) m_dPScale = 1; } TDbEquWorldDraw::~TDbEquWorldDraw() { delete m_pGeometry; delete m_pSubEntityTraits; } void TDbEquWorldDraw::VirtualWordDraw(AcDbEntity* pEnt) { if(NULL == pEnt) return; if(pEnt->isKindOf(AcDbBlockReference::desc()) || pEnt->isKindOf(AcDbAttributeDefinition::desc()) || pEnt->isKindOf(AcDbFace::desc()) || pEnt->isKindOf(AcDbSolid::desc()) || pEnt->isKindOf(AcDbPoint::desc()) || pEnt->isKindOf(AcDbText::desc())) { return; } #if (ADS > 19) if (pEnt->isKindOf(AcDbHatch::desc())) {// add by cq 2016-07-15 2015以上 AcdbHatch绘制崩溃 TFS17651 return ; } #endif pEnt->worldDraw(this); } void TDbEquWorldDraw::SetTransMatrix(const AcGeMatrix3d& mat) { m_matTrans = mat; } void TDbEquWorldDraw::SetComplexCurvePtr(TComplexCurve* pCompCurve) { m_pCompCuve = pCompCurve; } void TDbEquWorldDraw::SetCurveSegmentPtr(TDPtrList* pLstCurSegs) { m_pLstCurSegs = pLstCurSegs; } void TDbEquWorldDraw::SetExcluding(const TComplexCurve& comCurve) { m_curExclude = comCurve; } void TDbEquWorldDraw::ClearExcluding() { m_curExclude.setLogicalLength(0); } AcGiRegenType TDbEquWorldDraw::regenType() const { return kAcGiRenderCommand; } Adesk::Boolean TDbEquWorldDraw::regenAbort() const { return Adesk::kFalse; } AcGiSubEntityTraits& TDbEquWorldDraw::subEntityTraits() const { return *m_pSubEntityTraits; } AcGiGeometry* TDbEquWorldDraw::rawGeometry() const { return m_pGeometry; } AcGiContext* TDbEquWorldDraw::context() { return NULL; } AcGiWorldGeometry& TDbEquWorldDraw::geometry() const { return *m_pGeometry; } Adesk::Boolean TDbEquWorldDraw::isDragging() const { return Adesk::kFalse; } double TDbEquWorldDraw::deviation(const AcGiDeviationType, const AcGePoint3d&) const { return 0.1; } Adesk::UInt32 TDbEquWorldDraw::numberOfIsolines() const { int isolines = 4; TGGetVar(_T("ISOLINES"), &isolines); return isolines; } inline void TDbEquWorldDraw::AddCurveElement(AcGePoint3d pt1, AcGePoint3d pt2, AcGePoint3d pt3, double nWidth) { if(NULL == m_pCompCuve && NULL == m_pLstCurSegs) return; pt1.transformBy(m_matTrans); pt2.transformBy(m_matTrans); pt3.transformBy(m_matTrans); if(NULL != m_pCompCuve) { m_elemCurve.ptGe[0] = pt1; m_elemCurve.ptGe[1] = pt2; m_elemCurve.ptGe[2] = pt3; m_elemCurve.dWidth = nWidth / m_dPScale; if(!Excluding(m_elemCurve)) m_pCompCuve->append(m_elemCurve); } if(NULL != m_pLstCurSegs) { m_pLstCurSegs->Append(new TGGeCurveSegment(pt1, pt2, 0)); } } inline void TDbEquWorldDraw::AddCurveElement(AcGePoint3d ptS, AcGePoint3d ptE, double nWidth) { if(NULL == m_pCompCuve && NULL == m_pLstCurSegs) return; ptS.transformBy(m_matTrans); ptE.transformBy(m_matTrans); if(NULL != m_pCompCuve) { m_elemCurve.ptGe[0] = ptS; m_elemCurve.ptGe[1] = ptE; m_elemCurve.ptGe[2] = ptE; m_elemCurve.dWidth = nWidth / m_dPScale; if(!Excluding(m_elemCurve)) m_pCompCuve->append(m_elemCurve); } if(NULL != m_pLstCurSegs) { m_pLstCurSegs->Append(new TGGeCurveSegment(ptS, ptE, 0)); } } // 排除实体,为提高效率 BOOL TDbEquWorldDraw::Excluding(const TCurveElement elem) { int nSize = m_curExclude.length(); if(0 == nSize) return FALSE; double dLen = 0; for(int i = 0; i < nSize; i++) { // change by hh 2012-06-25 仅判断长度的话 绘制阀门时 出现中线丢失的情况 改为判断点 // dLen = elem.ptGe[0].distanceTo(elem.ptGe[2]) // - m_curExclude[i].ptGe[0].distanceTo(m_curExclude[i].ptGe[2]); // if(EQUAL_ZERO(dLen)) // return TRUE; if((elem.ptGe[0] == m_curExclude[i].ptGe[0] && elem.ptGe[2] == m_curExclude[i].ptGe[2]) || (elem.ptGe[0] == m_curExclude[i].ptGe[2] && elem.ptGe[2] == m_curExclude[i].ptGe[0])) { return TRUE; } } return FALSE; }