Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/DbPolyMesh.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1718 lines
50 KiB
C++

#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<nCount; i++,nPtArrayIndex++) {
if (nPtArrayIndex < nTotalVertex) {
pPtArray[nPtArrayIndex] = *shapeTemp[i];
}
else return FALSE;
}
pPtArray[nPtArrayIndex++] = *shapeTemp[0];
return TRUE;
}
static BOOL IsExit(const DList<double>& lstAngle,double dAngle)
{
int nCount = lstAngle.Length();
for (int i=0; i<nCount; i++) {
double dTemp = fabs(lstAngle[i]-dAngle);
if (dTemp<1.0E-3)
return TRUE;
}
return FALSE;
}
static void GetShapeAngle(const DList<XPoly2D>& lstShape,
DList<double>& lstAngle)
{
int nCount = lstShape.Length();
for (int i=0; i<nCount; i++) {
XPoly2D polyTemp = lstShape[i];
XPoint ptWeightCenter=GetWeightCenter(polyTemp);
int nVertex = polyTemp.Length();
for (int j=0; j<nVertex; j++) {
XPoint& ptVertex = *polyTemp[j];
double dAngle = ads_angle(ptWeightCenter,ptVertex);
if (!IsExit(lstAngle,dAngle))
lstAngle.Append(new double(dAngle));
}
}
}
static int CompareSize(const double *p1, const double *p2)
{
if(*p1 > *p2)
return 1;
return -1;
}
//取得网格参数(行、列和点链表)
BOOL TDbPolyMesh::
GetSurfaceMesh(int &nRows,int &nCols,XPoint* &pPtArray) const
{
if (pPtArray) delete [] pPtArray;
//截面、基点和位置(距离)
DList<XPoly2D> lstShape;
DList<XPoint> lstBase;
DList<double> 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<nShapeNum; k++) {
dPolyDisance += (*lstShape[k]).Distance3d();
}
nVertexNum = GetContourDivNum(dPolyDisance/nShapeNum);
if (nVertexNum < 3) {
adsout << _T("\n顶点数太少!请重新设置参数或者增大该实体。");
return FALSE;
}
//所有截面的的顶点的角度
DList<double> 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()<nShapeNum || shapeStart.Length()<3) {
nRows = 0, nCols = 0;
return FALSE;
}
//截面半径,和相应的角度,基点半径和角度
DList<double> 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<nStep; j++ ) {
XContour2D contourThis = contourStart;
//构造截面顶点
double dAngle=0, dRadius=0;
double dDist = pathExtrude.GetDistAtVertex(j);
double dDistScale = dDist/dPathLength;
XPoint ptCenter = contourThis.GetWeightCenter();
for (int i=0; i<nNumOnContour; i++ ) {
dAngle = *lstAngle[i];
dRadius = *lstRadiusStart[i] +
(*lstRadiusEnd[i] - *lstRadiusStart[i])*dDistScale;
XPoint& ptTemp = *contourThis[i];
ptTemp.x = ptCenter.x + dRadius*cos(dAngle);
ptTemp.y = ptCenter.y + dRadius*sin(dAngle);
}
//构造截面基点
dAngle = dBaseAngleStart +
(dBaseAngleEnd-dBaseAngleStart)*dDistScale;
double dBaseScale = dBaseScaleStart +
(dBaseScaleEnd-dBaseScaleStart)*dDistScale;
dRadius = contourThis.GetRadius(dAngle);
dRadius *= dBaseScale;
XPoint& ptTemp = contourThis.m_ptBase;
ptTemp.x = ptCenter.x + dRadius*cos(dAngle);
ptTemp.y = ptCenter.y + dRadius*sin(dAngle);
pt1 = *pathExtrude[j-1];
pt2 = *pathExtrude[j];
pt3 = *pathExtrude[j+1];
shapeThis = XContour3D(contourThis,XVector3D(0,0,1));
double dEdgeHalfAngle = 0.5*Angle(pt2, pt1, pt3);
double dScale = sin(dEdgeHalfAngle);
if (fabs(dScale)<1.0E-9) // ZJQ Modify here
continue;
dScale = 1/dScale;
shapeThis.ScaleBy(dScale, shapeThis.m_ptCenter);
XVector3D vt3Sub1 = pt3-pt1;
XVector3D vt2Sub1 = pt2-pt1;
XVector3D vt3Sub2 = pt3-pt2;
XVector3D vtRotateAxis = ((AcGeVector3d)vt3Sub1).crossProduct((AcGeVector3d)vt2Sub1);
double dRotateAngle = 0.5*PI - dEdgeHalfAngle;
AcGeVector3d vtContourNormal = vt3Sub2;
vtContourNormal.rotateBy(dRotateAngle, (AcGeVector3d)vtRotateAxis);
shapeThis.AttachOn(pt2, vtContourNormal);
AppendToMesh(shapeThis, nVertNumOnMesh, vtAlignment, pPtArray, nPtArrayIndex);
}
}
//三个截面时,采用二次插值
else if (nShapeNum == 3) {
//第二个截面
XContour2D contourShape2(*lstShape[1],*lstBase[1],nVertexNum,lstOtherAngle);
if (contourStart.Length() != contourShape2.Length()) {
if (pPtArray) delete [] pPtArray;
nRows = 0, nCols = 0;
return FALSE;
}
DList<double> 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<nStep; j++ ) {
XContour2D contourThis = contourStart;
//构造截面顶点
double dAngle=0, dRadius=0;
double dDist = pathExtrude.GetDistAtVertex(j);
XPoint ptCenter = contourThis.GetWeightCenter();
for (int i=0; i<nNumOnContour; i++ ) {
dAngle = *lstAngle[i];
dRadius = Parabola(dDist,0,Z2,dPathLength,
*lstRadiusStart[i],*lstRadiusShape2[i],*lstRadiusEnd[i]);
XPoint& ptTemp = *contourThis[i];
ptTemp.x = ptCenter.x + dRadius*cos(dAngle);
ptTemp.y = ptCenter.y + dRadius*sin(dAngle);
}
//构造截面基点
dAngle = Parabola(dDist,0,Z2,dPathLength,
dBaseAngleStart,dBaseAngleShape2,dBaseAngleEnd);
double dBaseScale = Parabola(dDist,0,Z2,dPathLength,
dBaseScaleStart,dBaseScaleShape2,dBaseScaleEnd);
dRadius = contourThis.GetRadius(dAngle);
dRadius *= dBaseScale;
XPoint& ptTemp = contourThis.m_ptBase;
ptTemp.x = ptCenter.x + dRadius*cos(dAngle);
ptTemp.y = ptCenter.y + dRadius*sin(dAngle);
pt1 = *pathExtrude[j-1];
pt2 = *pathExtrude[j];
pt3 = *pathExtrude[j+1];
shapeThis = XContour3D(contourThis,XVector3D(0,0,1));
//转角处由转角决定截面的放大或缩小
double dEdgeHalfAngle = 0.5*Angle(pt2, pt1, pt3);
double dScale = sin(dEdgeHalfAngle);
if (fabs(dScale)<1.0E-9) // ZJQ Modify here
continue;
dScale = 1/dScale;
shapeThis.ScaleBy(dScale, shapeThis.m_ptCenter);
XVector3D vt3Sub1 = pt3-pt1;
XVector3D vt2Sub1 = pt2-pt1;
XVector3D vt3Sub2 = pt3-pt2;
XVector3D vtRotateAxis = ((AcGeVector3d)vt3Sub1).crossProduct((AcGeVector3d)vt2Sub1);
double dRotateAngle = 0.5*PI - dEdgeHalfAngle;
//截面法线向量
AcGeVector3d vtContourNormal = vt3Sub2;
vtContourNormal.rotateBy(dRotateAngle, (AcGeVector3d)vtRotateAxis);
shapeThis.AttachOn(pt2, vtContourNormal);
AppendToMesh(shapeThis, nVertNumOnMesh, vtAlignment, pPtArray, nPtArrayIndex);
}
}
//三个以上截面时
else {
;
}
shapeThis = shapeEnd;
pt0 = *pathExtrude[nStep-1];
pt1 = *pathExtrude[nStep];
// sg add 080902,解决变截面体首、末截面没有垂直的问题(论坛问题1017)
pline.getFirstDeriv(pt1.AsAcGePoint3d(), vec); // 求切线向量
// shapeThis.AttachOn(pt1, pt1-pt0); // sg modify 080902
shapeThis.AttachOn(pt1, XVector3D(vec));
AppendToMesh(shapeThis, nVertNumOnMesh, vtAlignment, pPtArray, nPtArrayIndex);
return TRUE;
}
//是否正确(有效)
BOOL TDbPolyMesh::IsValid() const
{
assertReadEnabled();
if (!TDbCurveMesh::IsValid()) return FALSE;
assert(m_polyShape.IsClosed());
if (m_polyShape.Length() <= 0) return FALSE;
int nShapeNum = m_lstShapePoly.Length();
int nBaseNum = m_lstShapeBase.Length();
int nDistNum = m_lstDistScale.Length();
assert(nShapeNum == nBaseNum);
nShapeNum++;
if (nShapeNum > 1)
assert(nShapeNum-2 == nDistNum);
nShapeNum--;
for (int i=0; i<nShapeNum; i++) {
XPoly2D polyShape = m_lstShapePoly[i];
assert(polyShape.IsClosed());
if (polyShape.Length() <= 0) return FALSE;
}
for (i=0; i<nDistNum; i++) {
assert(m_lstDistScale[i] < 1);
assert(m_lstDistScale[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<Adesk::UInt16> lstVertexNum;
DList<XPoint> lstVertexPt;
DList<double> 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; i<nShapeLength; i++) {
XPoly2D polyShape = m_lstShapePoly[i];
int nLength = polyShape.Length();
pFiler->writeInt16(AcDb::kDxfInt16,nLength);
for (int j=0; j<nLength; j++) {
pFiler->writePoint3d(AcDb::kDxfXCoord,(AcGePoint3d&)*polyShape[j]);
pFiler->writeDouble(AcDb::kDxfAngle,*polyShape.bulges[j]);
}
}
//截面位置
int nDistNum = m_lstDistScale.Length();
for(i=0; i<nDistNum; i++) {
pFiler->writeDouble(AcDb::kDxfReal,m_lstDistScale[i]);
}
//基点链表
int nBaseCount = m_lstShapeBase.Length();
for(i=0; i<nBaseCount; i++) {
pFiler->writePoint3d(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<nVertexNum; i++) {
XPoint& ptShape = *polyShape[i];
ptShape += vt;
}
polyShape.SetElevation(0.0);
} else {
int nVertexNum = polyShape.Length();
for(int i=0; i<nVertexNum; i++) {
XPoint& ptShape = *polyShape[i];
ptShape.TransformBy(mat);
}
polyShape.SetElevation(0.0);
}
}
return Acad::eOk;
}
// 功能: 夹点操作
Acad::ErrorStatus
TDbPolyMesh::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = TDbCurveMesh::subMoveGripPointsAt(indices, offset);
if (es != Acad::eOk) return es;
if (!IsShapeShow()) return Acad::eOk;
XPoint vtOffset=Wcs2Ecs(*(XPoint *)&offset, m_vtNormal);
//vtOffset.z=0;
int nIndexNum = indices.length();
int nCurveMesh = m_polyShape.Length() + 1;
if(!IsBind())
nCurveMesh += m_polyBase.Length()+m_polyBase.TotalSegments();
for (int i = 0; i < nIndexNum; i++) {
//当前指数
int idx = indices[i] - nCurveMesh;
//截面基点
int nBaseNum = m_lstShapeBase.Length();
if (idx >= 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<TObjInfoUnit> &lstInfo) const
{
int nShapeNum = m_lstShapePoly.Length();
if (nShapeNum < 1) {
TDbCurveMesh::GetTips(lstInfo);
return;
}
DList<double> 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<nAreaNum; i++) {
lstInfo.Append(new TObjInfoUnit(XString(_T("截面%d周长"),i+1),
Dist2Str(*lstPerimeter[i])));
lstInfo.Append(new TObjInfoUnit(_T("面积"),
XString(_T("%.2f"), _AS_SQMETER(*lstArea[i]))));
}
}
// lstInfo.Append(new TObjInfoUnit(_T("侧面面积"),
// XString(_T("%.2f"), _AS_SQMETER(GetSideArea()))));
// lstInfo.Append(new TObjInfoUnit(_T("体积"),
// XString(_T("%.3f"), AS_CUMETER(GetVolume()))));
}
Acad::ErrorStatus TDbPolyMesh::DrawShapeBases(XExplodeDraw &dc) const
{
double dSize = m_polyShape.Distance2d()/30.0;
DList<XPoint> lstShapeBase;
GetAllShapeBases(lstShapeBase);
int nBaseNum = lstShapeBase.Length();
for (int i=0; i<nBaseNum; i++) {
XPoint ptStart, ptEnd;
XLine lineBase1,lineBase2;
XPoint ptShapeBase = *lstShapeBase[i];
ptStart = Ecs2Wcs(ptShapeBase+XPoint(dSize, dSize), m_vtNormal);
ptEnd = Ecs2Wcs(ptShapeBase-XPoint(dSize, dSize), m_vtNormal);
lineBase1.SetPoints(ptStart,ptEnd);
ptStart = Ecs2Wcs(ptShapeBase+XPoint(dSize, -dSize), m_vtNormal);
ptEnd = Ecs2Wcs(ptShapeBase+XPoint(-dSize, dSize), m_vtNormal);
lineBase2.SetPoints(ptStart,ptEnd);
dc << lineBase1 << lineBase2;
}
return Acad::eOk;
}
Acad::ErrorStatus TDbPolyMesh::DrawShapePolys(XExplodeDraw &dc) const
{
XAcGiViewDraw &viewDraw = (XAcGiViewDraw &)dc;
DList<XPoly2D> lstShapePoly;
DList<XPoint> 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<nVertexNum; k++)
pPtArray[k]=Ecs2Wcs(pPtArray[k], m_vtNormal);
//显示网格
dc.DrawMesh(nRows, nCols, (AcGePoint3d *)pPtArray);
//显示两端面
XPoly2D polyStart(1), polyEnd(1);
int nIncrease = nRows*nCols - nCols;
for(int col=0; col<nCols-1; col++) {
polyStart.AppendNode(pPtArray[col]);
polyEnd.AppendNode(pPtArray[nIncrease+col]);
}
dc.DrawShell(polyStart, DList<XPoly2D>());
dc.DrawShell(polyEnd, DList<XPoly2D>());
}
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<XPoly2D> 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<nCount; i++)
poly.AppendNode(*poly2[i],poly2.GetBulge(i));
poly.SetBulge(poly.Length() - 1, 0);
}
}
poly.SetFlag(1);
poly.SetElevation(dZ);
return;//返回
}
//二维边界点链表
DList<XPoint> lstLeftPoint(FALSE),lstRightPoint(FALSE);
//基点和位置(距离)
DList<XPoint> lstBase;
DList<double> lstDistScale;
GetAllShapeBases(lstBase);
GetDistScales(lstDistScale);
//路径在两个截面时不用离散直线
TPolyPath pathExtrude(polyPath,(nShapeNum!=2?TRUE:FALSE));
if (pathExtrude.Length()<nShapeNum)
return;
XExtendEnd endStart(*lstShape[0],*lstBase[0]);
XExtendEnd endEnd(*lstShape[nShapeNum-1],*lstBase[nShapeNum-1]);
const XPoint ptCenterStart = endStart.GetCenter();
const XPoint ptCenterEnd = endEnd.GetCenter();
double dBaseDistStart = endStart.m_ptBase.x-ptCenterStart.x;
double dBaseDistEnd = endEnd.m_ptBase.x-ptCenterEnd.x;
double dDistanceEnd = endEnd.GetDistance();
double dDistanceStart = endStart.GetDistance();
int nNumOnPath = pathExtrude.Length();
endStart.RotateBy(-PI/2,AcGeVector3d(0,0,1),ptCenterStart);
endEnd.RotateBy(-PI/2,AcGeVector3d(0,0,1),ptCenterEnd);
XPoint pt0, pt1, pt2, pt3;
double dPathLength = pathExtrude.GetDistAtVertex(nNumOnPath-1);
if (dPathLength<=0 || dDistanceEnd<=0 || dDistanceStart<=0)
return;
XExtendEnd endThis = endStart;
pt0 = *pathExtrude[0];
pt1 = *pathExtrude[1];
// sg add 080902,解决变截面体首、末截面没有垂直的问题(论坛问题1017)
AcDbPolyline pline;
PolyConvert(polyPath, pline);
AcGeVector3d vec;
pline.getFirstDeriv(pt0.AsAcGePoint3d(), vec); // 求切线向量
// endThis.AttachOn(pt0, pt1-pt0); // sg modify 080902
endThis.AttachOn(pt0, XVector3D(vec));
lstLeftPoint.Append(new XPoint(endThis.m_ptLeft));
lstRightPoint.Append(new XPoint(endThis.m_ptRight));
//构造中间截面的步数
int nStep = nNumOnPath-1;
//两个截面时,采用线性插值
if (nShapeNum == 2) {
for (int j=1; j<nStep; j++ ) {
endThis = endStart;
double dLength = pathExtrude.GetDistAtVertex(j);
double dLengthScale = dLength/dPathLength;
double dDistance = dDistanceStart +
(dDistanceEnd-dDistanceStart)*dLengthScale;
endThis.ScaleBy(dDistance/dDistanceStart,endThis.GetCenter(),FALSE);
double dBaseDist = dBaseDistStart +
(dBaseDistEnd-dBaseDistStart)*dLengthScale;
endThis.m_ptBase.y = ptCenterStart.y - dBaseDist;
pt1 = *pathExtrude[j-1];
pt2 = *pathExtrude[j];
pt3 = *pathExtrude[j+1];
double dEdgeHalfAngle = 0.5*Angle(pt2, pt1, pt3);
double dScale = sin(dEdgeHalfAngle);
if (fabs(dScale)<1.0E-9) // ZJQ Modify here
continue;
dScale = 1/dScale;
endThis.ScaleBy(dScale, endThis.GetCenter());
XVector3D vt3Sub1 = pt3-pt1;
XVector3D vt2Sub1 = pt2-pt1;
XVector3D vt3Sub2 = pt3-pt2;
XVector3D vtRotateAxis = ((AcGeVector3d)vt3Sub1).crossProduct((AcGeVector3d)vt2Sub1);
double dRotateAngle = 0.5*PI - dEdgeHalfAngle;
AcGeVector3d vtContourNormal = vt3Sub2;
vtContourNormal.rotateBy(dRotateAngle, (AcGeVector3d)vtRotateAxis);
endThis.AttachOn(pt2, vtContourNormal);
lstLeftPoint.Append(new XPoint(endThis.m_ptLeft));
lstRightPoint.Append(new XPoint(endThis.m_ptRight));
}
}
//三个截面时,采用二次插值
else if (nShapeNum == 3) {
//第二个截面
XExtendEnd endShape2(*lstShape[1],*lstBase[1]);
double dBaseDistShape2 = endShape2.m_ptBase.x-endShape2.GetCenter().x;
double dDistanceShape2 = endShape2.GetDistance();
double Z2 = dPathLength * (*lstDistScale[0]);
endShape2.RotateBy(PI/2,AcGeVector3d(0,0,1),endShape2.GetCenter());
for (int j=1; j<nStep; j++ ) {
endThis = endStart;
double dLength = pathExtrude.GetDistAtVertex(j);
double dDistance = Parabola(dLength,0,Z2,dPathLength,
dDistanceStart,dDistanceShape2,dDistanceEnd);
endThis.ScaleBy(dDistance/dDistanceStart,endThis.GetCenter(),FALSE);
double dBaseDist = Parabola(dLength,0,Z2,dPathLength,
dBaseDistStart,dBaseDistShape2,dBaseDistEnd);
endThis.m_ptBase.y = ptCenterStart.y - dBaseDist;
pt1 = *pathExtrude[j-1];
pt2 = *pathExtrude[j];
pt3 = *pathExtrude[j+1];
//转角处由转角决定截面的放大或缩小
double dEdgeHalfAngle = 0.5*Angle(pt2, pt1, pt3);
double dScale = sin(dEdgeHalfAngle);
if (fabs(dScale)<1.0E-9) // ZJQ Modify here
continue;
dScale = 1/dScale;
endThis.ScaleBy(dScale, endThis.GetCenter());
XVector3D vt3Sub1 = pt3-pt1;
XVector3D vt2Sub1 = pt2-pt1;
XVector3D vt3Sub2 = pt3-pt2;
XVector3D vtRotateAxis = ((AcGeVector3d)vt3Sub1).crossProduct((AcGeVector3d)vt2Sub1);
double dRotateAngle = 0.5*PI - dEdgeHalfAngle;
AcGeVector3d vtContourNormal = vt3Sub2;
vtContourNormal.rotateBy(dRotateAngle, (AcGeVector3d)vtRotateAxis);
endThis.AttachOn(pt2, vtContourNormal);
lstLeftPoint.Append(new XPoint(endThis.m_ptLeft));
lstRightPoint.Append(new XPoint(endThis.m_ptRight));
}
}
//三个以上截面时
else {
;
}
endThis = endEnd;
pt0 = *pathExtrude[nStep-1];
pt1 = *pathExtrude[nStep];
// sg add 080902,解决变截面体首、末截面没有垂直的问题(论坛问题1017)
pline.getFirstDeriv(pt1.AsAcGePoint3d(), vec); // 求切线向量
// endThis.AttachOn(pt1, pt1-pt0); // sg modify 080902
endThis.AttachOn(pt1, XVector3D(vec));
lstLeftPoint.Append(new XPoint(endThis.m_ptLeft));
lstRightPoint.Append(new XPoint(endThis.m_ptRight));
int nLeftCount = lstLeftPoint.Length();
int nRightCount = lstRightPoint.Length();
for (int i=0; i<nLeftCount; i++)
poly.AppendNode(*lstLeftPoint[i]);
for (i=nRightCount-1; i>=0; i--)
poly.AppendNode(*lstRightPoint[i]);
poly.SetFlag(1);
poly.SetElevation(dZ);
}
//********************* Methos ***********************//
//除第一个截面以外的截面(截面要封闭)
void TDbPolyMesh::
SetShapePolys(const DList<XPoly2D>& 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<XPoly2D>& 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<XPoly2D>& 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<XPoly2D>& 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<XPoint>& 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<XPoint>& 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<XPoint>& 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<XPoint>& 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<double>& 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<double>& 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<double>& lstArea) const
{
assertReadEnabled();
lstArea.Reset();
double dArea = TDbCurveMesh::GetShapeArea();
lstArea.Append(new double(dArea));
int nShapeNum = m_lstShapePoly.Length();
for (int i=0; i<nShapeNum; i++) {
dArea = (m_lstShapePoly[i]).Area();
lstArea.Append(new double(dArea));
}
}
void TDbPolyMesh::
GetShapeArea(DList<double>& lstArea) const
{
assertReadEnabled();
lstArea.Reset();
int nShapeNum = m_lstShapePoly.Length();
for (int i=0; i<nShapeNum; i++) {
double dArea = (m_lstShapePoly[i]).Area();
lstArea.Append(new double(dArea));
}
}
void TDbPolyMesh::
GetAllShapePerimeter(DList<double>& lstPerimeter) const
{
assertReadEnabled();
lstPerimeter.Reset();
double dPerimeter = TDbCurveMesh::GetShapePerimeter();
lstPerimeter.Append(new double(dPerimeter));
int nShapeNum = m_lstShapePoly.Length();
for (int i=0; i<nShapeNum; i++) {
dPerimeter = (m_lstShapePoly[i]).Distance2d();
lstPerimeter.Append(new double(dPerimeter));
}
}
void TDbPolyMesh::
GetShapePerimeter(DList<double>& lstPerimeter) const
{
assertReadEnabled();
lstPerimeter.Reset();
int nShapeNum = m_lstShapePoly.Length();
for (int i=0; i<nShapeNum; i++) {
double dPerimeter = (m_lstShapePoly[i]).Distance2d();
lstPerimeter.Append(new double(dPerimeter));
}
}
#if (ADS == 17)
XPoint TDbPolyMesh::GetAllShapeBasesByIndex(int idx)
{
DList<XPoint> listPoint;
GetAllShapeBases(listPoint);
return *listPoint[idx];
}
double TDbPolyMesh::GetAllShapePerimeterByIndex(int idx)
{
DList<double> listLen;
GetAllShapePerimeter(listLen);
return *listLen[idx];
}
double TDbPolyMesh::GetAllShapeAreaByIndex(int idx)
{
DList<double> listArea;
GetAllShapeArea(listArea);
return *listArea[idx];
}
void TDbPolyMesh::SetAllShapeBasesByIndex(int idx, XPoint pt)
{
DList<XPoint> 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<int> 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<int> 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<int> 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<XPoly2D> lstShapePloy;
DList<XPoint> lstShapeBase;
DList<double> lstDistScale;
RBList rbPathMask(RTDXF0, _T("POLYLINE,LWPOLYLINE,CIRCLE"), NULL);
RBList rbShapeMask=ads_buildlist(-4, _T("<or"),
-4, _T("<and"),
RTDXF0, _T("POLYLINE,LWPOLYLINE"),
70, 1,
-4, _T("and>"),
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<nShapeNum-1; i++) {
XPushVar<int> 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<nLength; j++) {
XCurveSegment cvTemp;
polyPath.Nth(j,cvTemp);
BOOL bOnCurve=(ptSelect&cvTemp)==PR_EDGE ||
(ptSelect&cvTemp)==PR_INSIDE;
if (bOnCurve) {
dDistThis += cvTemp.PathDistance(ptSelect);
break;
} else {
dDistThis += cvTemp.PathDistance(cvTemp.EndPoint());
}
}
if (dDistThis < dDistAll && dDistThis > 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);//还原
}