admin 发表于 2024-3-14 19:30:20

[每日一码] 由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]
查看完整版本: [每日一码] 由CAD截面图形得到其节线数据