#include "stdafx.h" //自定义函数 extern int GetContourDivNum(double dPerimeter); extern XPoint GetWeightCenter(const XPoly2D& poly); const Adesk::UInt8 TDbPolyMesh::g_nVersion = 1; ACRX_DXF_DEFINE_MEMBERS(ATSPolyMesh, ATSCurveMesh, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_POLYMESH, "ATS_POLYMESH图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbPolyMesh); TDbPolyMesh::TDbPolyMesh() { } TDbPolyMesh::~TDbPolyMesh() { } //三点的夹角 double TDbPolyMesh:: Angle(const XPoint& from,const XPoint& to1,const XPoint& to2) const { XVector3D vt1 = to1 - from; XVector3D vt2 = to2 - from; AcGeVector3d v1 = vt1; AcGeVector3d v2 = vt2; AcGeVector3d vRef = v1.crossProduct(v2); return v1.angleTo(v2, vRef); } //二次插值(Z2、R2为中间的值) double TDbPolyMesh::Parabola(double Z,double Z1,double Z2, double Z3,double R1,double R2,double R3) const { if (fabs(Z1-Z2)<1.0E-9) return Z1; if (fabs(Z1-Z3)<1.0E-9) return (Z1+Z3)/2.0; if (fabs(Z2-Z3)<1.9E-9) return Z3; double a = R1 / ( (Z1-Z2) * (Z1-Z3) ) + R2 / ( (Z2-Z1) * (Z2-Z3) ) + R3 / ( (Z3-Z1) * (Z3-Z2) ); double b = (R1-R2) / (Z1-Z2) - (Z1+Z2) * a; double c = R1 - a*Z1*Z1 - b*Z1; double dRadius = a*Z*Z + b*Z + c; return dRadius; } BOOL TDbPolyMesh::AppendToMesh(const XContour3D& shape, const int nTotalVertex, XVector3D& vtAlignment, XPoint*& pPtArray, int& nPtArrayIndex) const { XContour3D shapeTemp = shape; int nCount = shapeTemp.Length(); if (nCount <= 0) return FALSE; XVector3D vtStartVert = *shapeTemp[0] - shapeTemp.m_ptCenter; AcGeVector3d vtAlignmentProjectOnContour = ((AcGeVector3d)vtAlignment).orthoProject((AcGeVector3d)shapeTemp.m_vtNormal); double angle = ((AcGeVector3d)vtStartVert).angleTo(vtAlignmentProjectOnContour, ((AcGeVector3d)shapeTemp.m_vtNormal)); //shapeTemp.RotateBy(angle, shapeTemp.m_vtNormal, shapeTemp.m_ptCenter); vtAlignment = *shapeTemp[0] - shapeTemp.m_ptCenter; for (int i=0; i& lstAngle,double dAngle) { int nCount = lstAngle.Length(); for (int i=0; i& lstShape, DList& lstAngle) { int nCount = lstShape.Length(); for (int i=0; i *p2) return 1; return -1; } //取得网格参数(行、列和点链表) BOOL TDbPolyMesh:: GetSurfaceMesh(int &nRows,int &nCols,XPoint* &pPtArray) const { if (pPtArray) delete [] pPtArray; //截面、基点和位置(距离) DList lstShape; DList lstBase; DList lstDistScale; XPoly2D polyPath(m_polyBase); GetAllShapeBases(lstBase); GetAllShapePolys(lstShape); GetDistScales(lstDistScale); int nShapeNum = lstShape.Length(); if (nShapeNum<2 || polyPath.Length()<1 || lstBase.Length()!=nShapeNum || lstDistScale.Length()!=nShapeNum-2) { nRows = 0, nCols = 0; return FALSE; } //截面顶点数 int nVertexNum = 90; double dPolyDisance = (*lstShape[0]).Distance3d(); for (int k=1; k lstOtherAngle; GetShapeAngle(lstShape,lstOtherAngle); //排序(有小到大) lstOtherAngle.QuickSort(CompareSize); //路径在两个截面时不用离散直线 TPolyPath pathExtrude(polyPath,(nShapeNum!=2?TRUE:FALSE)); XContour2D contourStart(*lstShape[0],*lstBase[0],nVertexNum,lstOtherAngle); XContour2D contourEnd(*lstShape[nShapeNum-1],*lstBase[nShapeNum-1],nVertexNum,lstOtherAngle); const XContour3D shapeStart(contourStart,XVector3D(0,0,1)); const XContour3D shapeEnd(contourEnd,XVector3D(0,0,1)); if (shapeStart.Length()!=shapeEnd.Length() || pathExtrude.Length() lstAngle, lstRadiusStart, lstRadiusEnd; contourStart.GetAngles(lstAngle); contourStart.GetRadius(lstRadiusStart); contourEnd.GetRadius(lstRadiusEnd); double dBaseAngleStart = contourStart.GetBaseAngle(); double dBaseAngleEnd = contourEnd.GetBaseAngle(); double dBaseScaleStart = contourStart.GetBaseScale(); double dBaseScaleEnd = contourEnd.GetBaseScale(); int nNumOnPath = pathExtrude.Length(); int nNumOnContour = contourStart.Length(); int nVertNumOnMesh = nNumOnPath*(nNumOnContour+1); nRows = nNumOnPath; nCols = nNumOnContour+1; double dPathLength = pathExtrude.GetDistAtVertex(nNumOnPath-1); if ( dPathLength <= 0 ) { nRows = 0, nCols = 0; return FALSE; } pPtArray = new XPoint[nVertNumOnMesh]; int nPtArrayIndex = 0; XVector3D vtAlignment; XPoint pt0, pt1, pt2, pt3; XContour3D shapeThis = shapeStart; vtAlignment = *shapeThis[0] - shapeThis.m_ptCenter; pt0 = *pathExtrude[0]; pt1 = *pathExtrude[1]; // sg add 080902,解决变截面体首、末截面没有垂直的问题(论坛问题1017) AcDbPolyline pline; PolyConvert(polyPath, pline); AcGeVector3d vec; pline.getFirstDeriv(pt0.AsAcGePoint3d(), vec); // 求切线向量 // shapeThis.AttachOn(pt0, pt1-pt0); // sg modify 080902 shapeThis.AttachOn(pt0, XVector3D(vec)); AppendToMesh(shapeThis, nVertNumOnMesh, vtAlignment, pPtArray, nPtArrayIndex); //构造中间截面的步数 int nStep = nNumOnPath-1; //两个截面时,采用线性插值 if (nShapeNum == 2) { for (int j=1; j lstRadiusShape2; contourShape2.GetRadius(lstRadiusShape2); double dBaseRadiusShape2 = contourShape2.GetBaseRadius(); double dBaseAngleShape2 = contourShape2.GetBaseAngle(); double dBaseScaleShape2 = contourShape2.GetBaseScale(); double Z2 = dPathLength * (*lstDistScale[0]); for (int j=1; j 1) assert(nShapeNum-2 == nDistNum); nShapeNum--; for (int i=0; i 0); } return TRUE; } Acad::ErrorStatus TDbPolyMesh::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } // 输入来自于DWG文件的文档数据: Acad::ErrorStatus TDbPolyMesh::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; es = TDbCurveMesh::dwgInFields(pFiler); if(es != Acad::eOk) return es; Adesk::UInt8 nVer; pFiler->readItem(&nVer); if(nVer > g_nVersion) return Acad::eMakeMeProxy; //截面链表 m_lstShapePoly.Reset(); Adesk::UInt16 nShapeCount=0; pFiler->readItem(&nShapeCount); for(Adesk::UInt16 i = 0; i < nShapeCount; i++) { XPoly2D polyShape(1); Adesk::UInt16 nLength=0; pFiler->readItem(&nLength); for(Adesk::UInt16 j = 0; j < nLength; j++) { AcGePoint3d ptOnShape; double dBulge=0.0; pFiler->readItem(&ptOnShape); pFiler->readItem(&dBulge); polyShape.AppendNode(XPoint(ptOnShape), dBulge); } m_lstShapePoly.Append(new XPoly2D(polyShape)); } //截面位置 m_lstDistScale.Reset(); Adesk::UInt16 nDistCount=0; pFiler->readItem(&nDistCount); for(i = 0; i < nDistCount; i++) { double dTemp=0; pFiler->readItem(&dTemp); m_lstDistScale.Append(new double(dTemp)); } //基点链表 m_lstShapeBase.Reset(); Adesk::UInt16 nBaseCount=0; pFiler->readItem(&nBaseCount); for(i = 0; i < nBaseCount; i++) { AcGePoint3d ptShapeBase; pFiler->readItem(&ptShapeBase); m_lstShapeBase.Append(new XPoint(ptShapeBase)); } return pFiler->filerStatus(); } // 文档数据输出到一个DWG文件: Acad::ErrorStatus TDbPolyMesh::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); if (!IsValid()) return Acad::eInvalidInput; Acad::ErrorStatus es = Acad::eOk; es = TDbCurveMesh::dwgOutFields(pFiler); if(es != Acad::eOk) return es; pFiler->writeItem(g_nVersion); //截面链表 Adesk::UInt16 nShapeCount = m_lstShapePoly.Length(); pFiler->writeItem(nShapeCount); for(Adesk::UInt16 i = 0; i < nShapeCount; i++) { XPoly2D polyShape = m_lstShapePoly[i]; Adesk::UInt16 nLength = polyShape.Length(); pFiler->writeItem(nLength); for(Adesk::UInt16 j = 0; j < nLength; j++) { pFiler->writeItem((AcGePoint3d &)*polyShape[j]); pFiler->writeItem(polyShape.GetBulge(j)); } } //截面位置 Adesk::UInt16 nDistCount = m_lstDistScale.Length(); pFiler->writeItem(nDistCount); for(i = 0; i < nDistCount; i++) { pFiler->writeItem(m_lstDistScale[i]); } //基点链表 Adesk::UInt16 nBaseCount = m_lstShapeBase.Length(); pFiler->writeItem(nBaseCount); for(i = 0; i < nBaseCount; i++) { pFiler->writeItem((AcGePoint3d &)m_lstShapeBase[i]); } return pFiler->filerStatus(); } // 从DXF文件读入文档数据: Acad::ErrorStatus TDbPolyMesh::dxfInFields (AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; es = TDbCurveMesh::dxfInFields(pFiler); if(es != Acad::eOk) return es; if (!pFiler->atSubclassData(_T("TDbPolyMesh"))) return Acad::eBadDxfSequence; /* m_lstShapePoly.Reset(); m_lstShapeBase.Reset(); m_lstDistScale.Reset(); DList lstVertexNum; DList lstVertexPt; DList lstBulge; resbuf rb; while ((es == Acad::eOk) && ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) { switch (rb.restype) { case AcDb::kDxfInt16://截面顶点数链表 lstVertexNum.Append(new Adesk::UInt16(rb.resval.rint)); break; case AcDb::kDxfXCoord://截面链表 lstVertexPt.Append(new XPoint(rb.resval.rpoint)); break; case AcDb::kDxfYCoord://基点链表 m_lstShapeBase.Append(new XPoint(rb.resval.rpoint)); break; case AcDb::kDxfAngle://截面Bulge lstBulge.Append(new double(rb.resval.rreal)); break; case AcDb::kDxfReal://截面位置 m_lstDistScale.Append(new double(rb.resval.rreal)); break; default: pFiler->pushBackItem(); es = Acad::eEndOfFile; break; } } if (es != Acad::eEndOfFile) return Acad::eInvalidResBuf; //截面链表 Adesk::UInt16 nShapeCount = lstVertexNum.Length(); Adesk::UInt16 nTotalVertex=0; for(Adesk::UInt16 i = 0; i < nShapeCount; i++) { Adesk::UInt16 nVertex = *lstVertexNum[i]; if (nVertex < 2) { pFiler->setError(_T("\nError DXF group code: 10, 50")); return Acad::eMissingDxfField; } nTotalVertex += nVertex; } if(nTotalVertex!=lstVertexPt.Length() || nTotalVertex!=lstBulge.Length()) { pFiler->setError(_T("\nError DXF group code: 10, 50")); return Acad::eMissingDxfField; } int nVertexBefore = 0; for(i = 0; i < nShapeCount; i++) { Adesk::UInt16 nVertex = *lstVertexNum[i]; XPoly2D polyShape(1); for (Adesk::UInt16 j = 0; j < nVertex; j++) { polyShape.AppendNode(*lstVertexPt[nVertexBefore+j], *lstBulge[nVertexBefore+j]); } m_lstShapePoly.Append(new XPoly2D(polyShape)); nVertexBefore += nVertex; } */ return pFiler->filerStatus(); } // 保存文档数据,输出到一个DXF文件: Acad::ErrorStatus TDbPolyMesh::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); //if (!IsValid()) return Acad::eInvalidInput; Acad::ErrorStatus es = Acad::eOk; es = TDbCurveMesh::dxfOutFields(pFiler); if (es != Acad::eOk) return es; es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbPolyMesh")); if (es != Acad::eOk) return es; /* //截面链表 int nShapeLength = m_lstShapePoly.Length(); for(int i=0; iwriteInt16(AcDb::kDxfInt16,nLength); for (int j=0; jwritePoint3d(AcDb::kDxfXCoord,(AcGePoint3d&)*polyShape[j]); pFiler->writeDouble(AcDb::kDxfAngle,*polyShape.bulges[j]); } } //截面位置 int nDistNum = m_lstDistScale.Length(); for(i=0; iwriteDouble(AcDb::kDxfReal,m_lstDistScale[i]); } //基点链表 int nBaseCount = m_lstShapeBase.Length(); for(i=0; iwritePoint3d(AcDb::kDxfYCoord,(AcGePoint3d&)m_lstShapeBase[i]); } */ return es; } // Active when being rotated, scaled, moved, etc. Acad::ErrorStatus TDbPolyMesh::subTransformBy(const AcGeMatrix3d& xform) { extern XString GetCurCommand(); assertWriteEnabled(); if(IsBind()) { TDbEntity::subTransformBy(xform); return Acad::eOk; } ads_matrix mat; GetLocalMatrix(xform, mat); XVector3D vtNormalOld=GetNormal(); TDbCurveMesh::subTransformBy(xform); XVector3D vtNormalNew=GetNormal(); int nShapeNum = m_lstShapePoly.Length(); if (nShapeNum != m_lstShapeBase.Length()) return Acad::eNotApplicable; for (int i = 0; i < nShapeNum; i++) { XPoly2D &polyShape = *m_lstShapePoly[i]; XPoint &ptShapeBase = *m_lstShapeBase[i]; //基点变换 XPoint ptOldBase = ptShapeBase; ptShapeBase.TransformBy(mat); ptShapeBase.z=0; //截面变换 if(vtNormalNew.AsAcGeVector3d()==vtNormalOld.AsAcGeVector3d() && _tcsicmp(GetCurCommand(), _T("ROTATE"))==0) { XVector3D vt = ptShapeBase - ptOldBase; int nVertexNum = polyShape.Length(); for(int i=0; i= 0 && idx < nBaseNum) { *m_lstShapeBase[idx] += vtOffset; } else { idx -= nBaseNum; //截面顶点 int nShapeNum = m_lstShapePoly.Length(); for (int i = 0; i < nShapeNum; i++) { XPoly2D& polyShape = *m_lstShapePoly[i]; int nShapeNum = polyShape.Length(); if (idx >= 0 && idx < nShapeNum) { *polyShape[idx] += vtOffset; break; } idx -= nShapeNum; } } } return Acad::eOk; } Acad::ErrorStatus TDbPolyMesh::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); Acad::ErrorStatus es = Acad::eOk; es = TDbCurveMesh::subGetGripPoints(gripPoints, osnapModes, geomIds); if (es != Acad::eOk) return es; //截面的夹点 if(IsShapeShow()) { //截面基点 int nBaseNum = m_lstShapeBase.Length(); for (int i = 0; i < nBaseNum; i++) { XPoint ptWcs = Ecs2Wcs(m_lstShapeBase[i], m_vtNormal); gripPoints.append(ptWcs); } //截面顶点 int nShapeNum = m_lstShapePoly.Length(); for (i = 0; i < nShapeNum; i++) { XPoly2D polyShape = m_lstShapePoly[i]; int nVertexNum = polyShape.Length(); for(int i = 0; i < nVertexNum; i++){ XPoint ptWcs = Ecs2Wcs(*polyShape[i], m_vtNormal); gripPoints.append(ptWcs); } } } return Acad::eOk; } // 取得夹点说明 Acad::ErrorStatus TDbPolyMesh::GetGripText(int idx, CString &cs) const { Acad::ErrorStatus es = Acad::eOk; es = TDbCurveMesh::GetGripText(idx, cs); if(es != Acad::eOk) return es; //当前指数 int nIndex = 0; int nCurveMesh = m_polyShape.Length()+1; if(!IsBind()) nCurveMesh += m_polyBase.Length()+m_polyBase.TotalSegments(); nIndex += idx - nCurveMesh; //截面基点数 int nBaseNum = m_lstShapeBase.Length(); if (nIndex >= 0 && nIndex < nBaseNum) { cs = _T("改变形状基点"); } else { nIndex -= nBaseNum; //截面顶点数 int nShapeVertex=0; int nShapeNum = m_lstShapePoly.Length(); for (int i = 0; i < nShapeNum; i++) { nShapeVertex += (m_lstShapePoly[i]).Length(); } if (nIndex >= 0 && nIndex < nShapeVertex) cs = _T("改变断面形状线"); } return Acad::eOk; } // 取动态属性显示数据的函数 void TDbPolyMesh::GetTips(DList &lstInfo) const { int nShapeNum = m_lstShapePoly.Length(); if (nShapeNum < 1) { TDbCurveMesh::GetTips(lstInfo); return; } DList lstArea,lstPerimeter; GetAllShapeArea(lstArea); //截面面积 GetAllShapePerimeter(lstPerimeter);//截面周长 int nAreaNum = lstArea.Length(); lstInfo.Append(new TObjInfoUnit(_T("对象类型"), XString(_T("%d截面变截面体"),nShapeNum+1))); lstInfo.Append(new TObjInfoUnit(_T("路径长度"), Dist2Str(GetPathLength()))); if (nAreaNum == lstPerimeter.Length()) { for (int i=0; i lstShapeBase; GetAllShapeBases(lstShapeBase); int nBaseNum = lstShapeBase.Length(); for (int i=0; i lstShapePoly; DList lstShapeBase; GetAllShapePolys(lstShapePoly); GetAllShapeBases(lstShapeBase); int nShapeNum = lstShapePoly.Length(); if (lstShapeBase.Length() != nShapeNum) return Acad::eNotApplicable; for (int i = 0; i < nShapeNum; i++) { AcDbPolyline pline; PolyConvert(*lstShapePoly[i], pline); pline.setElevation((*lstShapeBase[i]).z); pline.setNormal(m_vtNormal); if(viewDraw.m_pWd) pline.worldDraw(viewDraw.m_pWd); else pline.viewportDraw(viewDraw.m_pVd); } return Acad::eOk; } // 绘制2D的显示, 二维显示网格 Acad::ErrorStatus TDbPolyMesh::ExplodeOrDraw2d(XExplodeDraw &dc) const { assertReadEnabled(); if (!IsValid()) return Acad::eInvalidInput; if (!Has2D() || m_vtNormal!=AcGeVector3d(0,0,1)) return ExplodeOrDraw3d(dc); int nShapeNum = m_lstShapePoly.Length(); if (nShapeNum<1) return TDbCurveMesh::ExplodeOrDraw2d(dc); XPoly2D polyOutline; GetOutlinePoly(0,polyOutline); dc << polyOutline; // 绘制断面形状 if(IsShapeShow() && _tcsicmp(dc.Desc(),XAcGiViewDraw::Descriptor())==0) { Adesk::UInt16 nColor=dc.GetColor(); dc.SetColor(1); DrawShapeBases(dc); DrawShapePolys(dc); dc.SetColor(nColor); } return Acad::eOk; } // 绘制3d的显示 Acad::ErrorStatus TDbPolyMesh::ExplodeOrDraw3d(XExplodeDraw &dc) const { assertReadEnabled(); if (!IsValid()) return Acad::eInvalidInput; int nShapeNum = m_lstShapePoly.Length(); if (nShapeNum < 1) return TDbCurveMesh::ExplodeOrDraw3d(dc); XPoint *pPtArray=NULL; //Mesh顶点 int nRows=0, nCols=0; //行数和列数 if (GetSurfaceMesh(nRows,nCols,pPtArray)) { //设置向量 int nVertexNum=nCols*nRows; for(int k=0; k()); dc.DrawShell(polyEnd, DList()); } if (pPtArray) delete []pPtArray; // 绘制断面形状 if(IsShapeShow() && _tcsicmp(dc.Desc(),XAcGiViewDraw::Descriptor())==0) { Adesk::UInt16 nColor=dc.GetColor(); dc.SetColor(1); DrawShapeBases(dc); DrawShapePolys(dc); dc.SetColor(nColor); } return Acad::eOk; } int TDbPolyMesh::GetShapeNum() const { assertReadEnabled(); return m_lstShapePoly.Length()+1; } //在XY平面上的轮廓 void TDbPolyMesh::GetOutlinePoly(ads_real dZ, XPoly2D &poly) const { assertReadEnabled(); poly.Reset(); if (m_vtNormal!=AcGeVector3d(0,0,1)) return; //截面、路径 DList lstShape; GetAllShapePolys(lstShape); XPoly2D polyPath(m_polyBase); polyPath.SetElevation(0); int nShapeNum = lstShape.Length(); if (nShapeNum <= 0) return; //一个截面时,即路径曲面 if (nShapeNum == 1) { if (m_polyShape.Length() > 0) { XPoint ptLow, ptUp; m_polyShape.GetExtend(ptLow, ptUp); double nOffset1 = ptLow.x - m_ptShapeBase.x; double nOffset2 = ptUp.x - m_ptShapeBase.x; polyPath.SetElevation(0.0); XPoly2D poly1, poly2; polyPath.QuickOffset(nOffset1, poly1); polyPath.QuickOffset(nOffset2, poly2); if (m_polyBase.IsClosed()) { if (poly1.Distance2d()>=poly2.Distance2d()) poly = poly1; else poly = poly2; } else { poly = poly1; poly.SetBulge(poly.Length() - 1, 0); poly2.Reverse(); int nCount = poly2.Length(); for (int i=0; i lstLeftPoint(FALSE),lstRightPoint(FALSE); //基点和位置(距离) DList lstBase; DList lstDistScale; GetAllShapeBases(lstBase); GetDistScales(lstDistScale); //路径在两个截面时不用离散直线 TPolyPath pathExtrude(polyPath,(nShapeNum!=2?TRUE:FALSE)); if (pathExtrude.Length()=0; i--) poly.AppendNode(*lstRightPoint[i]); poly.SetFlag(1); poly.SetElevation(dZ); } //********************* Methos ***********************// //除第一个截面以外的截面(截面要封闭) void TDbPolyMesh:: SetShapePolys(const DList& lstShapePoly) { assertWriteEnabled(); m_lstShapePoly.Reset(); int nShapeNum = lstShapePoly.Length(); for (int i = 0; i < nShapeNum; i++) { m_lstShapePoly.Append(new XPoly2D(lstShapePoly[i])); } } void TDbPolyMesh:: GetShapePolys(DList& lstShapePoly) const { assertReadEnabled(); lstShapePoly.Reset(); int nShapeNum = m_lstShapePoly.Length(); for (int i = 0; i < nShapeNum; i++) { lstShapePoly.Append(new XPoly2D(m_lstShapePoly[i])); } } void TDbPolyMesh:: SetAllShapePolys(const DList& lstShapePoly) { assertWriteEnabled(); m_lstShapePoly.Reset(); int nShapeNum = lstShapePoly.Length(); if (nShapeNum > 0) m_polyShape = lstShapePoly[0]; for (int i = 1; i < nShapeNum; i++) { m_lstShapePoly.Append(new XPoly2D(lstShapePoly[i])); } } //所有的的截面(截面要封闭) void TDbPolyMesh:: GetAllShapePolys(DList& lstShapePoly) const { assertReadEnabled(); lstShapePoly.Reset(); lstShapePoly.Append(new XPoly2D(m_polyShape)); int nShapeNum = m_lstShapePoly.Length(); for (int i = 0; i < nShapeNum; i++) { lstShapePoly.Append(new XPoly2D(m_lstShapePoly[i])); } } //设置重心为截面基点 void TDbPolyMesh::SetWeightCenterAsShapeBases() { assertWriteEnabled(); m_lstShapeBase.Reset(); //第一个基点 m_ptShapeBase = GetWeightCenter(m_polyShape); //基点链表 int nShapeNum = m_lstShapePoly.Length(); for (int i = 0; i < nShapeNum; i++) { XPoint ptCenter = GetWeightCenter(*m_lstShapePoly[i]); m_lstShapeBase.Append(new XPoint(ptCenter)); } } //设置形心(GetExtend的中点)为截面的基点 void TDbPolyMesh::SetCenterAsShapeBases() { assertWriteEnabled(); m_lstShapeBase.Reset(); XPoint ptLow,ptUp,ptCenter; //用XPoly2D::Center()不行,采用GetExtend() //第一个基点 m_polyShape.GetExtend(ptLow,ptUp); Midpoint(ptLow,ptUp,m_ptShapeBase); //基点链表 int nShapeNum = m_lstShapePoly.Length(); for (int i = 0; i < nShapeNum; i++) { XPoly2D& polyShape = *m_lstShapePoly[i]; polyShape.GetExtend(ptLow,ptUp); Midpoint(ptLow,ptUp,ptCenter); m_lstShapeBase.Append(new XPoint(ptCenter)); } } void TDbPolyMesh:: SetShapeBases(const DList& lstShapeBase) { assertWriteEnabled(); m_lstShapeBase.Reset(); int nBaseNum = lstShapeBase.Length(); for (int i = 0; i < nBaseNum; i++) { m_lstShapeBase.Append(new XPoint(lstShapeBase[i])); } } void TDbPolyMesh:: GetShapeBases(DList& lstShapeBase) const { assertReadEnabled(); lstShapeBase.Reset(); int nBaseNum = m_lstShapeBase.Length(); for (int i = 0; i < nBaseNum; i++) { lstShapeBase.Append(new XPoint(m_lstShapeBase[i])); } } void TDbPolyMesh:: SetAllShapeBases(const DList& lstShapeBase) { assertWriteEnabled(); m_lstShapeBase.Reset(); int nBaseNum = lstShapeBase.Length(); if (nBaseNum > 0) m_ptShapeBase = lstShapeBase[0]; for (int i = 1; i < nBaseNum; i++) { m_lstShapeBase.Append(new XPoint(lstShapeBase[i])); } } void TDbPolyMesh:: GetAllShapeBases(DList& lstShapeBase) const { assertReadEnabled(); lstShapeBase.Reset(); lstShapeBase.Append(new XPoint(m_ptShapeBase)); int nBaseNum = m_lstShapeBase.Length(); for (int i = 0; i < nBaseNum; i++) { lstShapeBase.Append(new XPoint(m_lstShapeBase[i])); } } //除第一个截面和最后一个截面以外的其他截面在路径上的位置 void TDbPolyMesh:: SetDistScales(const DList& lstDist) { assertWriteEnabled(); m_lstDistScale.Reset(); int nCount = lstDist.Length(); for (int i = 0; i < nCount; i++) { m_lstDistScale.Append(new double(lstDist[i])); } } void TDbPolyMesh:: GetDistScales(DList& lstDist) const { assertReadEnabled(); lstDist.Reset(); int nCount = m_lstDistScale.Length(); for (int i = 0; i < nCount; i++) { lstDist.Append(new double(m_lstDistScale[i])); } } // 工程量 void TDbPolyMesh:: GetAllShapeArea(DList& lstArea) const { assertReadEnabled(); lstArea.Reset(); double dArea = TDbCurveMesh::GetShapeArea(); lstArea.Append(new double(dArea)); int nShapeNum = m_lstShapePoly.Length(); for (int i=0; i& lstArea) const { assertReadEnabled(); lstArea.Reset(); int nShapeNum = m_lstShapePoly.Length(); for (int i=0; i& lstPerimeter) const { assertReadEnabled(); lstPerimeter.Reset(); double dPerimeter = TDbCurveMesh::GetShapePerimeter(); lstPerimeter.Append(new double(dPerimeter)); int nShapeNum = m_lstShapePoly.Length(); for (int i=0; i& lstPerimeter) const { assertReadEnabled(); lstPerimeter.Reset(); int nShapeNum = m_lstShapePoly.Length(); for (int i=0; i listPoint; GetAllShapeBases(listPoint); return *listPoint[idx]; } double TDbPolyMesh::GetAllShapePerimeterByIndex(int idx) { DList listLen; GetAllShapePerimeter(listLen); return *listLen[idx]; } double TDbPolyMesh::GetAllShapeAreaByIndex(int idx) { DList listArea; GetAllShapeArea(listArea); return *listArea[idx]; } void TDbPolyMesh::SetAllShapeBasesByIndex(int idx, XPoint pt) { DList listPoint; GetAllShapeBases(listPoint); listPoint[idx]->x=pt.x; listPoint[idx]->y=pt.y; SetAllShapeBases(listPoint); } #endif /* double TDbPolyMesh::GetSideArea() const { assertReadEnabled(); double dSideArea=0; return dSideArea; } double TDbPolyMesh::GetVolume() const { assertReadEnabled(); double dVolume=0; return dVolume; } */ // 编辑TDbPolyMesh实体 int EditPolyMesh0(AcDbObjectId id) { XVector3D vtNormal=Ucs2Wcs(XVector3D(0,0,1), TRUE); ((AcGeVector3d &)vtNormal).normalize(); OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPolyMesh, pStep); if(!pStep) return RTERROR; while(1) { int bBind=FALSE; //pStep->IsBind(); XString sPrompts, sKeywords; if(bBind) { sPrompts << _T("\n选择 [解除绊定(B)/截面显示(W)"); sKeywords << _T("B W G C"); } else { sPrompts << _T("\n选择 [加顶点(A)/减顶点(D)/设置顶点(S)/截面显示(W)"); sKeywords << _T("A D S W G C"); } if(pStep->Has2D()) sPrompts << _T("/关闭二维(G)/设置重心为截面基点(C)]<退出>:"); else sPrompts << _T("/开启二维(G)/设置重心为截面基点(C)]<退出>:"); XString sKeyword; int nRet=0; INITGET_BEG(0, sKeywords); nRet=ads_getkword(sPrompts, sKeyword); INITGET_END(); if(nRet!=RTNORM) break; TCHAR cKey=sKeyword[0]; if(cKey==_T('A') || cKey==_T('D') || cKey==_T('S')) { if(vtNormal.AsAcGeVector3d()!=pStep->GetNormal().AsAcGeVector3d()) { adsout << _T("\n当前构造平面与对象的构造平面不一致!"); continue; } } if(sKeyword[0]==_T('A')) { XPoint ptAdd; if(XGetPoint(NULL, _T("\n点取新的顶点位置"), ptAdd)==RTNORM) { ptAdd = Ucs2Ecs(ptAdd, vtNormal); if(pStep->upgradeOpen()!=Acad::eOk) return RTERROR; if(!pStep->AddVertex(ptAdd)) { adsout << _T("\n请正确点取!"); } pStep->downgradeOpen(); } } else if(sKeyword[0]==_T('D')) { XPushVar osmode(_T("OSMODE"), OS_NOD); XPoint ptVert; while(ads_getpoint(NULL, _T("\n选取顶点: "), ptVert)==RTNORM) { ptVert=Ucs2Ecs(ptVert, vtNormal); int nPos=pStep->HitTestOnBase2d(ptVert); if(nPos>0) { nPos--; if(pStep->upgradeOpen()!=Acad::eOk) return RTERROR; pStep->RemoveVertexAt(nPos); pStep->downgradeOpen(); } } } else if(sKeyword[0]==_T('S')) { XPushVar osmode(_T("OSMODE"), OS_NOD); XPoint ptVert; while(ads_getpoint(NULL, _T("\n选取顶点: "), ptVert)==RTNORM) { int nPos=pStep->HitTestOnBase2d(ptVert); if(nPos>0) { nPos--; double nElev=pStep->GetElevationAt(nPos); adsout << _T("\n改夹角[A]/点取[P]/输入顶点标高<") << Dist2Str(nElev) << _T(">: "); int nCode; INITGET_BEG(0, _T("A P")); nCode=ads_getreal(_T(""), &nElev); INITGET_END(); if(nCode==RTKWORD) { TCHAR szKey[80]=_T(""); ads_getinput(szKey); if(szKey[0]==_T('P')) { XPushVar osMode(_T("OSMODE"), OS_NEA); XPoint ptElev; nCode=ads_getpoint(NULL, _T("\n点取参照物:"), ptElev); if(nCode==RTNORM) { ptElev = Ucs2Ecs(ptElev, vtNormal); nElev=ptElev.z; if(pStep->upgradeOpen()!=Acad::eOk) return RTERROR; pStep->SetElevationAt(nPos, nElev); pStep->downgradeOpen(); } } else if(szKey[0]==_T('A')) { double nOldAng=pStep->GetSweepAngleAt(nPos)*180.0/PI; nCode=GetReal(_T("\n输入夹角"), nOldAng); if(nCode==RTNORM) { nOldAng *= PI/180.0; if(pStep->upgradeOpen()!=Acad::eOk) return RTERROR; pStep->SetSweepAngleAt(nPos, nOldAng); pStep->downgradeOpen(); } } } else if(nCode==RTNORM) { if(pStep->upgradeOpen()!=Acad::eOk) return RTERROR; pStep->SetElevationAt(nPos, nElev); pStep->downgradeOpen(); } } else { adsout << _T("\n请正确点取!"); } } } else if(sKeyword[0]==_T('W')) { if(pStep->upgradeOpen()!=Acad::eOk) return RTERROR; pStep->ShowShape(!pStep->IsShapeShow()); pStep->downgradeOpen(); } else if(sKeyword[0]==_T('B')) { if(pStep->IsBind()) { if(pStep->upgradeOpen()!=Acad::eOk) return RTERROR; pStep->UnBind(); pStep->downgradeOpen(); } } else if(sKeyword[0]==_T('G')) { if(pStep->upgradeOpen()==Acad::eOk) { pStep->SetHas2D(!pStep->Has2D()); pStep->downgradeOpen(); } } else if (sKeyword[0]==_T('C')) { if(pStep->upgradeOpen()==Acad::eOk) { pStep->SetWeightCenterAsShapeBases(); pStep->downgradeOpen(); } } } OPENOBJ_END(); return RTNORM; } void InitDbPolyMesh(BOOL bTrue) { if(bTrue) { TDbPolyMesh::rxInit(); TDbPolyMesh::SetEditMethod(EditPolyMesh0); acrxBuildClassHierarchy(); TDbPolyMesh::InitMatchProtocol(TRUE); } else { TDbPolyMesh::InitMatchProtocol(FALSE); deleteAcRxClass(TDbPolyMesh::desc()); } } void CreatePolyMesh() { //截面和截面基点和截面位置 DList lstShapePloy; DList lstShapeBase; DList lstDistScale; RBList rbPathMask(RTDXF0, _T("POLYLINE,LWPOLYLINE,CIRCLE"), NULL); RBList rbShapeMask=ads_buildlist(-4, _T(""), RTDXF0, _T("CIRCLE"), -4, _T("or>"), NULL); Entity entPath,entShape; PickSet m_ssSelect(SS_FREE); XPoint ptPick; if (SelectEntity(_T("\n请选取路径曲线(点取位置作为起始端)<退出>:"),entPath, ptPick, rbPathMask) != RTNORM) { adsout << _T("\n选取路径曲线失败"); return; } entPath.Redraw(3); m_ssSelect += entPath; XPoly2D polyPath(entPath);//路径 XVector3D vtEcs(0,0,1); entPath.GetData(210, &vtEcs); if(vtEcs.AsAcGeVector3d()!=Ucs2Wcs(XVector3D(0,0,1), TRUE).AsAcGeVector3d()) { adsout << _T("\n路径的法向和当前UCS的Z向不一致!"); return; } XPoint ptPickEcs=Ucs2Ecs(ptPick, vtEcs); if(polyPath.Head()->Distance(ptPickEcs) > polyPath.Tail()->Distance(ptPickEcs)) polyPath.Reverse(); int nShapeNum=0; while (nShapeNum<3) { XString sShapePrompt(_T("\n请选择第%d个封闭曲线<%s>:"), nShapeNum+1,(nShapeNum>=2?_T("结束"):_T("退出"))); XString sShapeFail(_T("\n选取第%d个封闭曲线失败!"),nShapeNum+1); int nCode = SelectEntity(sShapePrompt,entShape,rbShapeMask); if (nCode == RTCAN) { m_ssSelect.Redraw(4); return; } else if(nCode!=RTNORM) { if(nShapeNum<2) { adsout << sShapeFail; m_ssSelect.Redraw(4); return; } else break; } XPoly2D *polyShape=new XPoly2D(entShape); if(polyShape->IsSelfIntersect()) { adsout << _T("\n曲线不能自己相交,请重新选择:"); delete polyShape; continue; } else { nShapeNum++; entShape.Redraw(3); m_ssSelect += entShape; lstShapePloy.Append(polyShape); XString sPrompts, sKeywords,sKeyword; XPoint ptWeightCenter,ptBase, ptCen; //截面基点 ptWeightCenter = GetWeightCenter(*polyShape); //adsout << _T("\nWeight Cen=") << ptWeightCenter; polyShape->Center(ptCen); XString sBasePrompt(_T("\n请指定第%d个截面基点或 [重心(W)/退出(X)]<形心>:"),nShapeNum); XString sBaseFail(_T("\n指定第%d个截面基点失败!"),nShapeNum); INITGET_BEG(0, _T("W X C")); nCode = ads_getpoint(ptCen, sBasePrompt, ptBase); INITGET_END(); if(nCode==RTNONE) { nCode=RTKWORD; sKeyword=_T("C"); } else if(nCode==RTKWORD) { ads_getinput(sKeyword); } if (nCode!=RTKWORD && nCode!=RTNORM) { adsout << sBaseFail; m_ssSelect.Redraw(4); return; } else if (nCode==RTKWORD) { if (sKeyword[0] == _T('W')) { ptBase = ptWeightCenter; } else if (sKeyword[0] == _T('C')) { ptBase=ptCen; } } lstShapeBase.Append(new XPoint(ptBase)); } } //截面位置 nShapeNum = lstShapePloy.Length(); if (nShapeNum<2 /*|| nShapeNum>3*/ || nShapeNum!=lstShapeBase.Length()) return; for (int i=1; i tVar(_T("OSMODE"), OS_NEA); XString sPrompt(_T("\n指定第%d个截面在路径曲线的位置:"),i+1); while (1 ) { XPoint ptSelect; if (ads_getpoint(NULL, sPrompt, ptSelect) != RTNORM) { m_ssSelect.Redraw(4); return; } ptSelect = /*Ucs2Wcs*/(ptSelect); //BOOL bOnPath = (ptSelect&polyPath)==PR_EDGE; if (polyPath.HitTestOnCurve(ptSelect)) { double dDist = 0.5; double dDistAll = polyPath.Distance3d(); if (dDistAll > 0) { double dDistThis = 0; int nLength = polyPath.TotalSegments(); for (int j=0; j 0) { dDist = dDistThis/dDistAll; } } lstDistScale.Append(new double(dDist)); break; } else { sPrompt = _T("\n所指定点不在路径曲线上,请重新指定:"); } } } if ((nShapeNum >= 2 /*&& nShapeNum <= 3*/) && nShapeNum == lstShapeBase.Length() && nShapeNum-2 == lstDistScale.Length()) { TDbPolyMesh *pMesh = new TDbPolyMesh; pMesh->SetNormal(Ucs2Wcs(XVector3D(0,0,1), TRUE)); pMesh->SetBasePoly(polyPath); pMesh->SetAllShapePolys(lstShapePloy); //pMesh->SetWeightCenterAsShapeBases(); //重心为基点 //pMesh->SetCenterAsShapeBases(); //中心基点 pMesh->SetAllShapeBases(lstShapeBase); //指定基点 pMesh->SetDistScales(lstDistScale); pMesh->AddToMSpace(Adesk::kTrue); pMesh->close(); } m_ssSelect.Redraw(4);//还原 }