[每日一码] 由CAD截面图形得到其节线数据
void varyL(){
ArxDbgUiPrEntity prEnt(采用T("请选择截面外轮廓"), NULL);
prEnt.addAllowedClass(AcDbPolyline::desc());
if (prEnt.go() != ArxDbgUiPrBase::kOk)
{
return;
}
AcDbEntity* pEnt1 = NULL;
acdbOpenObject(pEnt1,prEnt.objectId(),AcDb::kForRead);
//获得封闭形顶点
AcDbPolyline *Polygon = NULL ;
Polygon = AcDbPolyline::cast(pEnt1);
ASSERT( Polygon != NULL );
if (Polygon == NULL)
{
AfxMessageBox(采用T("线型不为多义线"));
pEnt1->close();
return;
}
if( !Polygon->isClosed() )
{
Polygon->close();
AfxMessageBox(采用T("外轮廓不封闭"));
return;
}
AcGePoint3dArray PtArray;//记录外轮廓上的点
AcGePoint3dArray keyPtArray; //记录 “任一高度” 所有的 点(最后节线高度值)
int VertNum = (int)Polygon->numVerts() ;
int i;
for( i = 0; i < VertNum; i ++ )
{
AcGePoint3d Temp;
Polygon->getPointAt(i,Temp);
PtArray.append(Temp);//外轮廓上的点
//如果此点与之前所有点的Y值不同,则增加为 关键点
BOOL bAdd = TRUE;
for (int k = 0; k < keyPtArray.length(); k ++)
{
if (fabs(keyPtArray.y - Temp.y) < 1e-6)
{
bAdd = FALSE;
Temp.y += 1e-4;
keyPtArray.append(Temp);
break;
}
}
if (bAdd == TRUE)
{
keyPtArray.append(Temp);//高度 关键点
}
}
pEnt1->close();
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//获得空腔个数
int nHoll;
ArxDbgUiPrIntDef prInt(采用T("输入空腔个数"), NULL,ArxDbgUiPrInt::kRange, 0);
prInt.setRange(0, 10);
if(prInt.go() != ArxDbgUiPrBase::kOk)
return;
else
nHoll = prInt.value();
AcGePoint3dArray ptHollArray;
//依次选择全部空腔
for (i = 0; i < nHoll; i ++)
{
CString strTemp;
strTemp.Format(采用T("选择第个 %d 内腔"), i + 1);
prEnt.setMessage(strTemp);
if (prEnt.go() != ArxDbgUiPrBase::kOk)
return;
AcDbEntity* pEnt1 = NULL;
acdbOpenObject(pEnt1, prEnt.objectId(), AcDb::kForRead);
//获得封闭形顶点
AcDbPolyline *Polygon = NULL ;
Polygon = AcDbPolyline::cast(pEnt1);
ASSERT( Polygon != NULL );
if (Polygon == NULL)
{
AfxMessageBox(采用T("线型不为多义线"));
pEnt1->close();
return;
}
if( !Polygon->isClosed() )
{
Polygon->close();
AfxMessageBox(采用T("内腔不封闭"));
return;
}
int VertNum = (int)Polygon->numVerts();
int k;
for( k=0; k<VertNum; k++ )
{
AcGePoint3d Temp;
Polygon->getPointAt(k,Temp);
if(PointIsInPolygon(Temp,PtArray) != 1)
{
AfxMessageBox(采用T("内腔不在外内轮廓内!"));
pEnt1->close();
return;
}
ptHollArray<i>.append(Temp);
//如果此点与之前所有点的Y值不同, 则加入到高度关键点中(多个内腔时)
BOOL bAdd = TRUE;
for (int j = 0; j < keyPtArray.length(); j ++)
{
if (fabs(keyPtArray.y - Temp.y) < 1e-6)//精度控制
{
bAdd = FALSE;
//精度控制
Temp.y += 1e-4;
keyPtArray.append(Temp);
break;
}
}
if (bAdd == TRUE)
{
keyPtArray.append(Temp);//高度 关键点
}
}
pEnt1->close();
}
CArray <varyLine, varyLine> varyLineArray;
AcGePoint3dArray sortedkeyPtArray;
arrangePointArray(keyPtArray, sortedkeyPtArray, FALSE);//高度关键点数组 Y值升序排列
sortedkeyPtArray.y += 1e-5;
sortedkeyPtArray.y -= 1e-5;
AcGePoint3d tempPt;
varyLine tempVaryLine;//节线结构体
//节线结构体中的节线编号,但是其中有很多重合的节线,故不予输出
int nVaryIndex = 1;//添加一条节线后,就加1
int wk = sortedkeyPtArray.length();
if (nHoll == 0)
{
for (i = 0; i < sortedkeyPtArray.length();i ++)
{
AcGePoint3d temp1 = sortedkeyPtArray<i>, temp2 = sortedkeyPtArray<i>;
temp1.x -= 50000;
temp2.x += 50000;
double length = 0;
CAD采用POINT *tempPt = NULL;//外、内轮廓线所有点的另一种存储方式
tempPt = new AcGePoint3d;
for (int k = 0; k<PtArray.length(); k ++)
{
tempPt=PtArray;
}
length = lengthThroughRegion(tempPt, PtArray.length(), temp1,temp2);
tempVaryLine.N = nVaryIndex;
nVaryIndex ++;
tempVaryLine.Y = sortedkeyPtArray<i>.y ;
tempVaryLine.relativeY = sortedkeyPtArray<i>.y - sortedkeyPtArray.y ;
tempVaryLine.Length = length;
varyLineArray.Add(tempVaryLine);
delete []tempPt;
}
}
//空腔个数不为0
else
{
for (i = 0; i < sortedkeyPtArray.length(); i ++)
{
AcGePoint3d temp1 = sortedkeyPtArray<i>, temp2 = sortedkeyPtArray<i>;
temp1.x -= 5000;
temp2.x += 5000;
double length = 0;
CAD采用POINT *tempPt = NULL;
tempPt = new AcGePoint3d;
int k;
for (k = 0; k<PtArray.length(); k ++)
{
tempPt=PtArray;
}
//得到总长
length = lengthThroughRegion(tempPt, PtArray.length(), temp1,temp2);
delete []tempPt;
//////////////////////////////////////////////////////////////////////////
//减去所有空腔
for (k = 0; k < nHoll; k ++)
{
tempPt = new AcGePoint3d.length()];
int wk = ptHollArray.length();
for (int j = 0; j<ptHollArray.length(); j ++)
{
tempPt=ptHollArray;
}
length -= lengthThroughRegion(tempPt, ptHollArray.length(), temp1,temp2);
}
tempVaryLine.N = nVaryIndex;
nVaryIndex ++;
tempVaryLine.Y = sortedkeyPtArray<i>.y ;
tempVaryLine.relativeY = sortedkeyPtArray<i>.y - sortedkeyPtArray.y ;
tempVaryLine.Length = length;
varyLineArray.Add(tempVaryLine);
delete []tempPt;
}
}
//去掉节线宽度一样的节线
for (i = 0; i < varyLineArray.GetSize() - 1; i ++)
{
for (int j = varyLineArray.GetSize() - 1; j >= i + 1 ; j --)
{
if (fabs(varyLineArray<i>.Length - varyLineArray.Length) < 1e-2 &&
fabs(varyLineArray<i>.relativeY - varyLineArray.relativeY) < 1e-2)
{
varyLineArray.RemoveAt(j);
}
}
}
//对于上下边界,如果是水平线,则应去掉一条宽度高度均为0的节线
if ( fabs(varyLineArray.Y - varyLineArray.Y) < 1e-3 )
{
varyLineArray.RemoveAt(0);
}
if ( fabs(varyLineArray[ varyLineArray.GetSize() -1 ].Y - varyLineArray[ varyLineArray.GetSize() - 2 ].Y) < 1e-3 )
{
varyLineArray.RemoveAt( varyLineArray.GetSize() - 1);
}
//因为上面几行删除掉了相同的节线,因而varyLineArray<i>.N就有间隔了
//所以不能输出varyLineArray的N值了
CFileDialog OpenFile(FALSE,采用T(".txt"),采用T("节线数据.txt"),
OFN采用HIDEREADONLY | OFN采用OVERWRITEPROMPT,
采用T("文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*||"));
OpenFile.m采用ofn.lpstrTitle=采用T("新建数据文件");
if (OpenFile.DoModal() == IDCANCEL)
return ;
CString pathName=OpenFile.GetPathName();
ofstream ofile(pathName);
ofile<<"节线编号\t"<<"宽度\t\t" <<"高度\n";
for (i = 0; i < varyLineArray.GetSize(); i ++)
{
TCHAR outStr;
采用stprintf(outStr,采用T("%d\t\t%.2f\t\t%.2f\n"), i+1,varyLineArray<i>.Length,varyLineArray<i>.relativeY);
ofile << outStr;
}
ofile.close();
//询问用户是否要打开已生成的文本
bool bOpen = true;
if (ArxDbgUtils::yesNoPromptDef(采用T("是否要打开生成的内容"), bOpen, true) != ArxDbgUiPrBase::kOk)
return;
if(bOpen)
ShellExecute(::GetDesktopWindow(), 采用T("open"), pathName, NULL, NULL, SW采用SHOWNORMAL);
}
页:
[1]