找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 5599|回复: 16

[求助] 如何提高C# 在CAD中绘图大量图形的效率(高手来啊)

[复制链接]
发表于 2014-12-24 21:47:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
下面的代码是C#在CAD中绘制20万个三角形网格,尝试了在AcadBlock中绘制再插入到模型空间,时间都差不多,太耗时了,求帮忙!!!

          //下面绘制网格单元  
            double[] pttri = new double[3 * 3];
            double[] pt = new double[3];             //保存三角形重心的坐标,其坐标为((X1+X2+X3)/3,(Y1+Y2+Y3)/3;
            int item = -1;
            for (i = 0; i < eleNodeIndex.Count; ++i)  //遍历所有单元
            {
                for (j = 0; j < 3; ++j)
                {
                    for (k = 0; k < nodeData.Count; ++k)
                    {
                        if ((int)nodeData[k][0] == eleNodeIndex[i][j])
                        { item = k; break; }
                    }
                    pttri[j * 3 + 0] = nodeData[item][1];   //x
                    pttri[j * 3 + 1] = nodeData[item][2];   //y
                    pttri[j * 3 + 2] = nodeData[item][3];   //z
                }
                CadCom.AcadPolyline pline = caddoc.ModelSpace.AddPolyline(pttri);
                //CadCom.AcadPolyline pline = bl.AddPolyline(pttri);
                //pline.Closed = true;
                //下面写入单元编号
                pt[0] = (pttri[0] + pttri[3] + pttri[6]) / 3; pt[1] = (pttri[1] + pttri[4] + pttri[7]) / 3; pt[2] = 0.0;
                caddoc.ModelSpace.AddText((i + 1).ToString(), pt, 20);            
            }

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-12-24 22:04:36 来自手机 | 显示全部楼层
主要是显示出来费时,这个只能Autodesk解决
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2014-12-24 22:23:08 | 显示全部楼层
循环里面的类型定义拿到循环外面去。
代码放到事务处理里面。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-24 22:35:15 | 显示全部楼层
代码放到事务处理里面。   ?这个是什么意思呢

我尝试把坐标赋值放在绘图循环体的外面,对速度影响甚微

点评

速度的瓶颈主要是在显示的速度上,这个没办法。 我们讨论的是在循环体生成实体的过程中,尽量提高效率,因此把不需要在循环体内的东西放到循环体外,你想,循环体内增加一行语句,20万实体就多20万条指令。 你  详情 回复 发表于 2014-12-24 23:43
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2014-12-24 23:43:05 | 显示全部楼层
skywinlake 发表于 2014-12-24 22:35
代码放到事务处理里面。   ?这个是什么意思呢

我尝试把坐标赋值放在绘图循环体的外面,对速度影响甚微

速度的瓶颈主要是在显示的速度上,这个没办法。

我们讨论的是在循环体生成实体的过程中,尽量提高效率,因此把不需要在循环体内的东西放到循环体外,你想,循环体内增加一行语句,20万实体就多20万条指令。

你试试把 CadCom.AcadPolyline pline 这个类型定义放到循环体外, 循环体内只赋值,不声明对象,因为声明对象要有内存分配等等这些,要很多指令。
循环体内只有 pline = xxxxxxx;

没用C#写过代码,我说的都是通用的程序处理方法,你试试,我说的事物处理,好像C#都有吧,在 transAction里面。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2014-12-25 09:49:41 | 显示全部楼层
飘过,纯当看客。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-25 10:26:17 | 显示全部楼层
transAction ?没有用过,现在做的是基于.net的  模式

transACtion能够独立于cad么,不在CAD中加载执行,而是独立程序?

点评

把完整的代码贴上来吧。  详情 回复 发表于 2014-12-25 10:36
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2014-12-25 10:36:39 | 显示全部楼层
skywinlake 发表于 2014-12-25 10:26
transAction ?没有用过,现在做的是基于.net的  模式

transACtion能够独立于cad么,不在CAD中加载执行 ...

把完整的代码贴上来吧。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

发表于 2014-12-25 10:45:44 来自手机 | 显示全部楼层
skywinlake 发表于 2014-12-25 10:26
transAction ?没有用过,现在做的是基于.net的  模式

transACtion能够独立于cad么,不在CAD中加载执行 ...

本论坛搜索下" 读取文件绘制三角网"
和你这个类似

点评

在本轮胎找了下“读取文件绘制三角网” ,可是找不到啊  详情 回复 发表于 2014-12-26 17:48
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-26 17:48:13 | 显示全部楼层
st788796 发表于 2014-12-25 10:45
本论坛搜索下" 读取文件绘制三角网"
和你这个类似

在本轮胎找了下“读取文件绘制三角网” ,可是找不到啊

点评

百度上第一个就是 http://bbs.xdcad.net/forum.php?mod=viewthread&tid=674195&extra=page%3D1%26filter%3Dtypeid%26typeid%3D35  详情 回复 发表于 2014-12-26 18:26
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-26 17:51:36 | 显示全部楼层
这两天尝试用多线程将数据分块写入到多个临时文档,再合并的方法,但是等待多线程执行完成,也消耗不少时间,正在进一步测试中国
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-12-26 18:26:45 来自手机 | 显示全部楼层
skywinlake 发表于 2014-12-26 17:48
在本轮胎找了下“读取文件绘制三角网” ,可是找不到啊

百度上第一个就是
http://bbs.xdcad.net/forum.php?mod=viewthread&tid=674195&extra=page%3D1%26filter%3Dtypeid%26typeid%3D35
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-26 19:58:05 | 显示全部楼层
多线程操作可以行的通,但是效率并没有提高,目前新开的文档全部在一个CADapplication下,如果给每一个指定一个单独的application不知道速度是否会快一点,没有时间尝试了。代码献上,有空大家可以试试:

//由于单元网格数量往往很多,所以尝试用多线程开启多文档分块绘制,虽然可行,但实际速度反而有些慢,故放弃
        private void Mesh2CADByMultiThread()
        {
            if(tboxOpenFile.Text == "" || tboxSaveFile.Text == ""||               
               (cboxCulverts.Checked==false && cboxDikes.Checked==false && cboxWeirs.Checked==false && cboxGates.Checked==false))
            {
                MessageBox.Show("请检查输入、输出文件及绘制开关设置!", "提示:", MessageBoxButtons.OK);
                MainForm.progBarWorker.ReportProgress(100);
                return;
            }

            int i, j;
            int proValue = 0;
            //读取网格数据,获取网格数据
            List<double[]> nodeData = new List<double[]>();      //保存网格全部节点的数据信息(节点编号(有时是有空缺的),x,y,z,节点特性)
            List<int[]> eleNodeIndex = new List<int[]>();      //保存每个单元的三个节点编号信息
            string projcs = "";                                     //保存投影坐标信息

            if (Mike21.ReadFmMeshData(tboxOpenFile.Text, ref nodeData, ref eleNodeIndex, ref projcs) == false)
            {
                MessageBox.Show("读取网格mesh文件失败!", "警告:", MessageBoxButtons.OK);
                MainForm.progBarWorker.ReportProgress(100);
                return;
            }

            //打开所选择的的CAD文件,绘制网格图形
            if (cadcontrol == null)
            {
                cadcontrol = new CCadControl();
                cadcontrol.openandinit(tboxSaveFile.Text);
            }

            DateTime dtold = DateTime.Now;
            //根据网格数量决定是否创建多线程,如创建多线程,给每个新建线程指定一个新建CAD文档
            int bcount;  //分块绘制的数量,当前线程1块,另外再开bcount-1个子线程
            Thread[] sonThread = null;
            MeshSonThreadData[] sonThrData = null;
            Cad.AcadDocuments docs = cadcontrol.GetAppDocs();
            if (eleNodeIndex.Count < 5000)
            {
                bcount = 1;
                sonThrData = new MeshSonThreadData[1];
                sonThrData[0].curdoc=cadcontrol.GetActiveDoc();   //获取初始化cadcontrol时的文档对象
            }
            else
            {
                bcount = 5;   //分多块进行计算,此值必须大于等于2
                sonThrData = new MeshSonThreadData[bcount];
                for (i = 0; i < bcount; ++i)
                { sonThrData[i] = new MeshSonThreadData(); }
                sonThread = new Thread[bcount - 1];
                sonThrData[0].curdoc = cadcontrol.GetActiveDoc();   //获取初始化cadcontrol时的文档对象
                for (i = 0; i < bcount - 1; i++)
                {
                    sonThread[i] = new Thread(new ParameterizedThreadStart(sonMesh2CAD));
                    sonThread[i].Priority = ThreadPriority.AboveNormal;
                    sonThrData[i+1].curdoc = (Cad.AcadDocument)(docs.Add(System.Reflection.Missing.Value));  
                    //给新建的子线程在cadcontrol的CadApp中新建一个cad文档                    
                }
            }                           
            proValue += 10;
            MainForm.progBarWorker.ReportProgress(proValue);

            //下面设置相关变量  
            double[] pttri = null;// new double[3 * 3];         
            bool[] isExport = new bool[4]; //0-->网格边线,1--》节点编号,2--》网格高程,3--》单元编号
            { isExport[0] = cboxCulverts.Checked; isExport[1] = cboxDikes.Checked; }
            { isExport[2] = cboxWeirs.Checked; isExport[3] = cboxGates.Checked; }

            List<double[]> sonMeshNodeCoords = null;  //double[3],分别为网格节点x、y、z
            List<double[]> sonNodeIndexTxt = null;     //double[4],分别为节点编号,节点编号输出在CAD中的坐标(x、y、z)
            List<double[]> sonEleIndexTxt = null;        //double[4] 分别为单元编号,单元编号输出在CAD中的坐标(x、y、z)
            double[] aIndexTxtData = null;              //double[4] 分别为编号,编号输出在CAD中的坐标(x、y、z)

            //////////////////////////////////////////////////////////////////////////////////////////////////////
            //下面将给每个线程(如果没有子线程就只当前backgroundworker线程),设置绘制参数sonThrData[i]
            //首先设置每个单元网格的节点数据
            if (isExport[0] == true)
            {
                if (bcount == 1)   //说明网格数量较少不需要,开分线程
                {
                    sonMeshNodeCoords = new List<double[]>();
                    for (i = 0; i < eleNodeIndex.Count; ++i)  //遍历所有单元
                    {
                        pttri = new double[3 * 3];
                        for (j = 0; j < 3; ++j)
                        {
                            //三角形重心的坐标,其坐标为((X1+X2+X3)/3,(Y1+Y2+Y3)/3;   
                            pttri[j * 3 + 0] = nodeData[eleNodeIndex[i][j] - 1][1];   //x
                            pttri[j * 3 + 1] = nodeData[eleNodeIndex[i][j] - 1][2];   //y
                            pttri[j * 3 + 2] = nodeData[eleNodeIndex[i][j] - 1][3];   //z
                        }
                        sonMeshNodeCoords.Add(pttri);
                    }
                    sonThrData[0].sonMeshNodeCoords = sonMeshNodeCoords;
                }
                else if (bcount > 1) //说明网格数量较多,需开子线程
                {
                    for (i = 0; i < eleNodeIndex.Count; ++i)  //遍历所有单元
                    {
                        if (i % (eleNodeIndex.Count / bcount) == 0 && i / (eleNodeIndex.Count / bcount) < bcount-1 )
                        {
                            sonMeshNodeCoords = new List<double[]>();
                            sonThrData[i / (eleNodeIndex.Count / bcount)].sonMeshNodeCoords = sonMeshNodeCoords;
                        }

                        pttri = new double[3 * 3];
                        for (j = 0; j < 3; ++j)
                        {
                            pttri[j * 3 + 0] = nodeData[eleNodeIndex[i][j] - 1][1];   //x
                            pttri[j * 3 + 1] = nodeData[eleNodeIndex[i][j] - 1][2];   //y
                            pttri[j * 3 + 2] = nodeData[eleNodeIndex[i][j] - 1][3];   //z
                        }
                        sonMeshNodeCoords.Add(pttri);
                    }//end for
                }//end else
            }
            else
            {
                if (bcount == 1)   //说明网格数量较少不需要,开分线程
                {  sonThrData[0].sonMeshNodeCoords = null; }
                else if (bcount > 1) //说明网格数量较多,需开子线程
                {
                    for (i = 0; i < bcount; ++i)  //遍历所有计算分块
                    {  sonThrData[i / (eleNodeIndex.Count / bcount)].sonMeshNodeCoords = null; }//end for
                }//end else
            }//end if (isExport[0] == true)

            //设置绘制单元编号文本的数据
            if (isExport[3] == true)
            {
                pttri = new double[3*3];
                if (bcount == 1)   //说明网格数量较少不需要,开分线程
                {
                    sonEleIndexTxt = new List<double[]>();
                    for (i = 0; i < eleNodeIndex.Count; ++i)  //遍历所有单元
                    {
                        aIndexTxtData = new double[4];
                        aIndexTxtData[0] =(double)( i + 1);   //单元编号
                        for (j = 0; j < 3; ++j)
                        {
                            pttri[j * 3 + 0] = nodeData[eleNodeIndex[i][j] - 1][1];   //x
                            pttri[j * 3 + 1] = nodeData[eleNodeIndex[i][j] - 1][2];   //y
                            pttri[j * 3 + 2] = nodeData[eleNodeIndex[i][j] - 1][3];   //z
                        }
                        aIndexTxtData[1] = (pttri[0] + pttri[3] + pttri[6]) / 3;                           //单元编号文本绘制点x
                        aIndexTxtData[2] = (pttri[1] + pttri[4] + pttri[7]) / 3; aIndexTxtData[3] = 0.0;   //单元编号文本绘制点y、z
                        sonEleIndexTxt.Add(aIndexTxtData);
                    }
                    sonThrData[0].sonEleIndexTxt = sonEleIndexTxt;
                }
                else if (bcount > 1) //说明网格数量较多,需开子线程
                {
                    for (i = 0; i < eleNodeIndex.Count; ++i)  //遍历所有单元
                    {
                        if (i % (eleNodeIndex.Count / bcount) == 0 && i /(eleNodeIndex.Count / bcount) < bcount-1)
                        {
                            sonEleIndexTxt = new List<double[]>();
                            sonThrData[i / (eleNodeIndex.Count / bcount)].sonEleIndexTxt = sonEleIndexTxt;
                        }

                        aIndexTxtData = new double[4];
                        aIndexTxtData[0] = (double)(i + 1);   //单元编号
                        for (j = 0; j < 3; ++j)
                        {
                            pttri[j * 3 + 0] = nodeData[eleNodeIndex[i][j] - 1][1];   //x
                            pttri[j * 3 + 1] = nodeData[eleNodeIndex[i][j] - 1][2];   //y
                            pttri[j * 3 + 2] = nodeData[eleNodeIndex[i][j] - 1][3];   //z
                        }
                        aIndexTxtData[1] = (pttri[0] + pttri[3] + pttri[6]) / 3;                           //单元编号文本绘制点x
                        aIndexTxtData[2] = (pttri[1] + pttri[4] + pttri[7]) / 3; aIndexTxtData[3] = 0.0;   //单元编号文本绘制点y、z
                        sonEleIndexTxt.Add(aIndexTxtData);                       
                    }//end for
                }//end else              
            }
            else
            {
                if (bcount == 1)   //说明网格数量较少不需要,开分线程
                { sonThrData[0].sonEleIndexTxt= null; }
                else if (bcount > 1) //说明网格数量较多,需开子线程
                {
                    for (i = 0; i < bcount; ++i)  //遍历所有计算分块
                    { sonThrData[i / (eleNodeIndex.Count / bcount)].sonEleIndexTxt = null; }//end for
                }//end else
            }//end if (isExport[3] == true)

            //设置绘制节点编号文本的数据
            if (isExport[1] == true)
            {
                if (bcount == 1)   //说明网格数量较少不需要,开分线程
                {
                    sonNodeIndexTxt = new List<double[]>();
                    for (i = 0; i < nodeData.Count; ++i)  //遍历所有节点
                    {
                        aIndexTxtData = new double[4];
                        aIndexTxtData[0] = (double)(i + 1);   //节点编号                        
                        aIndexTxtData[1] = nodeData[i][1]; aIndexTxtData[2] = nodeData[i][2]; aIndexTxtData[3] = 0.0;  //节点编号文本绘制点x、y、z
                        sonNodeIndexTxt.Add(aIndexTxtData);
                    }
                    sonThrData[0].sonNodeIndexTxt = sonNodeIndexTxt;
                }
                else if (bcount > 1) //说明网格数量较多,需开子线程
                {
                    for (i = 0; i < nodeData.Count; ++i)  //遍历所有节点
                    {
                        if (i % (nodeData.Count / bcount) == 0 && i/(nodeData.Count / bcount) < bcount-1)
                        {
                            sonNodeIndexTxt = new List<double[]>();
                            sonThrData[i / (eleNodeIndex.Count / bcount)].sonNodeIndexTxt = sonNodeIndexTxt;
                        }

                        aIndexTxtData = new double[4];
                        aIndexTxtData[0] = (double)(i + 1);   //节点编号                        
                        aIndexTxtData[1] = nodeData[i][1]; aIndexTxtData[2] = nodeData[i][2]; aIndexTxtData[3] = 0.0;  //节点编号文本绘制点x、y、z
                        sonNodeIndexTxt.Add(aIndexTxtData);
                    }//end for
                }//end else              
            }
            else
            {
                if (bcount == 1)   //说明网格数量较少不需要,开分线程
                { sonThrData[0].sonNodeIndexTxt = null; }
                else if (bcount > 1) //说明网格数量较多,需开子线程
                {
                    for (i = 0; i < bcount; ++i)  //遍历所有计算分块
                    { sonThrData[i / (eleNodeIndex.Count / bcount)].sonNodeIndexTxt = null; }//end for
                }//end else
            }//end if (isExport[1] == true)
            proValue += 10;
            MainForm.progBarWorker.ReportProgress(proValue);
            //所有的数据全部准备好
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //下面开始绘制网格
            if (bcount == 1)   //说明网格数量较少不需要,开分线程
            {
                sonMesh2CAD((object)sonThrData[0]);     //网格数量少。在当前线程绘制全部网格      
            }
            else if (bcount > 1) //说明网格数量较多,需开子线程
            {               
                //其余网格在子线程中绘制
                for (i = 0; i < bcount-1; ++i)  //遍历所有子线程,并启动他们
                {
                    sonThread[i].Start((object)sonThrData[i+1]);
                }
                sonMesh2CAD((object)sonThrData[0]);     //在当前线程绘制一部分网格
            }//end else
            proValue += 50;
            MainForm.progBarWorker.ReportProgress(proValue);

            //将子线程中绘制的网格图形全部复制到当前文档中
            List<int> UnCompletedThrIndex = new List<int>();
            for (i = 0; i < sonThread.GetLength(0); i++)
            { UnCompletedThrIndex.Add(i); }
            i = 0;
            while (true)
            {
                if (UnCompletedThrIndex.Count ==0) { break; }
                for (i = UnCompletedThrIndex.Count-1; i >=0; --i)
                {
                    if (sonThread[i].IsAlive == false)
                    {
                        cadcontrol.CopyFileAll2ms(sonThrData[UnCompletedThrIndex[i] + 1].curdoc);   //将线程中的图形对象拷贝到当前文档
                        sonThrData[UnCompletedThrIndex[i] + 1].curdoc.Close(DialogResult.No, System.Reflection.Missing.Value);
                        sonThread[UnCompletedThrIndex[i]].Abort();
                        UnCompletedThrIndex.RemoveAt(i);
                    }                    
                }
                Thread.Sleep(200);
            }
            proValue += 20;
            MainForm.progBarWorker.ReportProgress(proValue);

            //将图形缩放到合适区间         
            cadcontrol.GetActiveDoc().SendCommand("_.ZOOM _A ");  //显示全部
            //缩放图形至显示全部网格
            //保存文件,并提示写入文件成功
            cadcontrol.SaveFile(tboxSaveFile.Text);
            cadcontrol.Close(); cadcontrol = null;
            DateTime dt = DateTime.Now;
            MessageBox.Show(string.Format("耗时{0}分",dt.ToOADate()-dtold.ToOADate()), "", MessageBoxButtons.OK);
            proValue = 100;
            MainForm.progBarWorker.ReportProgress(proValue);
            Thread.Sleep(1000);
        }

        //由于在CAD中写入大量图形时速度特别慢,所以考虑将需要绘制的图形数据分拆为几个部分,在不同的子线程中执行绘制,最后将各个绘制部分合并到一个图形中
        //sonMeshData 为MeshSonThreadData类型,保存需要绘制的单元网格、节点编号、单元编号的数据
        private void sonMesh2CAD(object sonMeshData)  
        {
            if(sonMeshData==null)   {return;}
            MeshSonThreadData sonData=sonMeshData as MeshSonThreadData;

            Cad.AcadDocument curdoc=sonData.curdoc;                    //当前绘制的CAD文档               
            List<double[]> sonMeshNodeCoords=sonData.sonMeshNodeCoords;  //double[3],分别为网格节点x、y、z
            List<double[]> sonNodeIndexTxt =sonData.sonNodeIndexTxt;     //double[4],分别为节点编号,节点编号输出在CAD中的坐标(x、y、z)
            List<double[]> sonEleIndexTxt=sonData.sonEleIndexTxt;        //double 分别为单元编号,单元编号输出在CAD中的坐标(x、y、z)
           
            //创建新图层
            CadCom.AcadAcCmColor cmcolor = (CadCom.AcadAcCmColor)cadcontrol.GetInterfaceObject("AutoCAD.AcCmColor.17"); //注意CAD2007 中是.17,不同版本不一样
            CadCom.AcadLineType linetype = null;
            CadCom.ACAD_LWEIGHT linewei;
            linetype =CCadControl.AddLinetype(curdoc,"Continuous");
            linewei = CadCom.ACAD_LWEIGHT.acLnWt025;
            cmcolor.ColorIndex = CadCom.AcColor.acWhite;
            CadCom.AcadLayer meshLay = CCadControl.AddLayer(curdoc,"m21_mesh", cmcolor, linetype, linewei);
            cmcolor.ColorIndex = CadCom.AcColor.acYellow;
            CadCom.AcadLayer nodeIndexLay =CCadControl.AddLayer(curdoc,"m21_NodeIndex", cmcolor, linetype, linewei);
            cmcolor.ColorIndex = CadCom.AcColor.acGreen;
            CadCom.AcadLayer eleIndexLay = CCadControl.AddLayer(curdoc, "m21_ElementIndex", cmcolor, linetype, linewei);
           
            //下面绘制网格单元边线
            int i;
            double[] pt = new double[3];
            if (sonMeshNodeCoords!=null)
            {
                curdoc.ActiveLayer=meshLay;
                for (i = 0; i < sonMeshNodeCoords.Count; ++i)  //遍历当前子线程给定的所有单元
                {                    
                    curdoc.ModelSpace.AddPolyline(sonMeshNodeCoords[i]).Closed = true;
                }               
            }

            //下面绘制网格单元编号
            if (sonEleIndexTxt != null)
            {
                curdoc.ActiveLayer = eleIndexLay;
                for (i = 0; i < sonEleIndexTxt.Count; ++i)  //遍历所有单元
                {
                    pt[0] = sonEleIndexTxt[i][1]; pt[1] = sonEleIndexTxt[i][2]; pt[2] = sonEleIndexTxt[i][3];
                    curdoc.ModelSpace.AddText(((int)sonEleIndexTxt[i][0]).ToString(), pt, 10);
                }               
            }

            //下面写入节点编号
            if (sonNodeIndexTxt != null)
            {
                curdoc.ActiveLayer = nodeIndexLay;
                for (i = 0; i < sonNodeIndexTxt.Count; ++i)  //遍历所有节点
                {
                    pt[0] = sonNodeIndexTxt[i][1]; pt[1] = sonNodeIndexTxt[i][2]; pt[2] = sonNodeIndexTxt[i][3];
                    curdoc.ModelSpace.AddText(((int)sonNodeIndexTxt[i][0]).ToString(), pt, 10);
                }
            }//end if           
        }

最后说明下:代码中cadcontrol 是我自己编的一个类对象,用于打开、绘制、选择、保存和关闭CAD图形
不影响整个代码。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

发表于 2014-12-26 20:58:02 | 显示全部楼层
skywinlake 发表于 2014-12-26 19:58
多线程操作可以行的通,但是效率并没有提高,目前新开的文档全部在一个CADapplication下,如果给每一个指定 ...

你这是在外部操作 CAD 吧!

点评

在外部启动CAD,通过控制CAD application及document等对象,向CAD发送操作指令。  详情 回复 发表于 2014-12-27 10:29
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-27 10:29:52 | 显示全部楼层
st788796 发表于 2014-12-26 20:58
你这是在外部操作 CAD 吧!

在外部启动CAD,通过控制CAD application及document等对象,向CAD发送操作指令。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-17 20:32 , Processed in 0.252388 second(s), 60 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表