1718 lines
49 KiB
C++
1718 lines
49 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);//还原
|
|
}
|