第五期视频回放
第五期代码及课件下载地址
第五期直播内容文字版
模拟输入调用命令
对于目前使用C#在Addin框架编程来说,对于某些方法可能封装的并不是十分完全,或者说目前的MicroStation软件中的原生功能可以完美的实现业务需求,但是需要对其进行参数化,自动化并进行重复工作,那么模拟输入调用命令的方法便必须掌握。它可以实现在编程情况下采用模拟输入key-in的方式实现命令的调用。<br />关于如何获得模拟输入的key-in方法:<br />1.点击MicroStation软件中Modeling中的Utilities中的Record录制宏<br />![key-in.jpg](https://cdn.nlark.com/yuque/0/2022/jpeg/21640708/1645061620838-519644f6-850f-4c21-add5-6e8400f57586.jpeg#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=drop&id=u7646eabb&margin=%5Bobject%20Object%5D&name=key-in.jpg&originHeight=182&originWidth=1917&originalType=binary&ratio=1&rotation=0&showTitle=false&size=113679&status=done&style=none&taskId=uba6ac44a-b087-4886-a154-67884ff4dbb&title=)<br />**图2 MicroStation宏模块**<br />2.执行操作,完成后点击Stop,对宏进行命名<br />![key-in-1.jpg](https://cdn.nlark.com/yuque/0/2022/jpeg/21640708/1645061838137-e8607fdc-0fd4-4234-ad2b-8b7482b10667.jpeg#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=drop&id=u1e5ed36b&margin=%5Bobject%20Object%5D&name=key-in-1.jpg&originHeight=182&originWidth=1917&originalType=binary&ratio=1&rotation=0&showTitle=false&size=111112&status=done&style=none&taskId=ufd6d85ae-3b2b-465c-91b4-403a0cd7de0&title=)<br />**图3 MicroStation宏启动录制按钮**<br />3.在下方下拉框中选取刚刚命名的宏,点击右边的铅笔按钮,此时会弹出界面显示宏所调用的命令<br />![key-in-2.jpg](https://cdn.nlark.com/yuque/0/2022/jpeg/21640708/1645061985975-073db729-713f-4b7f-b68e-ee7747bbd8bf.jpeg#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=drop&id=ub60a07be&margin=%5Bobject%20Object%5D&name=key-in-2.jpg&originHeight=182&originWidth=1917&originalType=binary&ratio=1&rotation=0&showTitle=false&size=110358&status=done&style=none&taskId=u174235de-1e5b-450f-851d-345217ec853&title=)<br />**图3 MicroStation宏停止录制按钮**<br /> 在这里我们需要注意:在模拟输入坐标时,Relative是坐标增量值,Fixed是坐标固定值,前者是指该点与上一个点之间坐标值的增量,后者指的是绝对坐标值,在模拟输入过程中需要确定输入的方式。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645062365625-d9e1da6a-d025-45af-8b23-ab12a24a2822.png#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=339&id=u0a27d234&margin=%5Bobject%20Object%5D&name=image.png&originHeight=424&originWidth=539&originalType=binary&ratio=1&rotation=0&showTitle=false&size=60201&status=done&style=none&taskId=u300c4f66-05cb-446b-b02a-de997945e40&title=&width=431.2)<br />**图4 宏信息界面**<br /> 在本案例中,根据宏中录制的命令及模拟输入坐标值,重现了宏执行的过程。若需直接使用MicroStation软件中的既有工作流,可以采用该方法实现既定目标。
public static void CreateByKeyin(string unparsed)//Case:CreateByKeyin
{
Session.Instance.Keyin("PLACE SPHERE ICON;" +
"Point absolute 4.656,-0.087,0.000;" +
"Point absolute 5.523,0.864,0.341"
); //模拟输入Key-in
Session.Instance.Keyin("PLACE SLAB ICON");
Session.Instance.Keyin("Point absolute 5.351,2.928,0.000");
Session.Instance.Keyin("Point absolute 6.778,2.818,-0.936");
Session.Instance.Keyin("Point absolute 6.205,4.712,1.093");
Session.Instance.Keyin("Point absolute 0.895,9.718,-7.598");
}
模型操作
模型创建
当我们需要创建模型时,需要使用CreateNewModel( )来对模型进行创建,在此过程中需要输入新建模型名称,模型类别以及确定模型类别是2D还是3D的。完成后即生成指定模型。
public static void CreateDgnModel(string unparsed)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件信息
dgnFile.CreateNewModel(out DgnModelStatus status,"test",DgnModelType.Normal,true,null);
/*
* 声明新模型
* error:(输出)若声明失败,则返回error
* name:新声明模型的名称
* type:声明模型类型(Normal,Sheet,Drawing,DgnComponentDefinition)
* is3D:声明模型是三维还是二维模型
* seedModel:声明模型所使用的种子文件
*/
MessageBox.Show("Create status:\n "+status.ToString());//将声明模型结果以文本的形式输出到对话框中
}
模型删除
当我们需要删除模型时,需要使用DeleteModel( )删除模型,执行删除模型的流程为首先根据模型名称找到模型ID,然后通过模型ID获取对应的模型空间,最后执行模型删除操作。
public static void DeleteDgnModel(string unparsed)
{
CreateDgnModel(unparsed);//调用上方声明模型的方法
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的文件信息
ModelId id= dgnFile.FindModelIdByName("test");//获得名为“test”的模型ID
DgnModel dgnModel = dgnFile.LoadRootModelById(out StatusInt status,id);//使用ID读取获得对应的模型空间
if(status==StatusInt.Success)//判断是否获得名为“test”的模型
{
StatusInt statusInt= dgnFile.DeleteModel(dgnModel);//从文件中删除该模型
if(statusInt== StatusInt.Success)//判断是否删除成功
{
MessageBox.Show("Delete status:\nSuccess");//对话框输出删除成功
}
}
}
private static DgnModel CreateDgnModelTest(string modelName)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件信息
ModelId id = dgnFile.FindModelIdByName(modelName);//检索文件中是否存在名为modelname引用字符串的模型
if(id!= ModelId.InvalidModel)//判断模型ID是否有效
{
DgnModel existModel = dgnFile.LoadRootModelById(out StatusInt status, id);//使用ID读取获得对应的模型空间
dgnFile.DeleteModel(existModel);
}
DgnModel dgnModel = dgnFile.CreateNewModel(out DgnModelStatus createStatus, modelName, DgnModelType.Normal, true, null);//声明新模型
return dgnModel;//返回新建模型
}
在本案例中我们对名为test的模型执行删除操作,执行代码后指定模型被成功删除。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645065404386-489aef27-9768-4481-bc0e-d27d12fcfaf6.png#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=97&id=qLVFN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=121&originWidth=1032&originalType=binary&ratio=1&rotation=0&showTitle=false&size=14803&status=done&style=none&taskId=u323d52fc-78d0-4d94-a753-94ca089ad5c&title=&width=825.6)<br />**图7 执行代码前**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645066139385-d61eebbc-c969-401c-be36-31a80365afd5.png#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=104&id=ub7d59e17&margin=%5Bobject%20Object%5D&name=image.png&originHeight=130&originWidth=1036&originalType=binary&ratio=1&rotation=0&showTitle=false&size=11964&status=done&style=none&taskId=u157bf51e-905f-4df0-8979-0bfc3c5741f&title=&width=828.8)<br />**图8 模型删除结果**
模型整体复制
当我们需要对模型整体复制时,需要使用CopyModelContents( )方法实现既定目标,实现的步骤为首先找到复制的目标模型,然后获取被复制的模型,最后使用上述方法执行模型数据的复制。
public static void CopyDgnModelWithAllData(string unparsed)
{
CreateDgnModelTest("test");//声明名为“test”的模型
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的文件信息
#region Create elements in dgnmodel
ModelId id = dgnFile.FindModelIdByName("test");//获得名为“test”的模型ID
#region Create Smart Solid
DgnModel dgnModel = dgnFile.LoadRootModelById(out StatusInt status, id);//使用ID读取获得对应的模型空间
DPoint3d profilePo1 = new DPoint3d(1000, 1000, -10000);//声明截面轮廓线端点
DPoint3d profilePo2 = new DPoint3d(1000, -1000, -10000);
DPoint3d profilePo3 = new DPoint3d(-1000, -1000, -10000);
DPoint3d profilePo4 = new DPoint3d(-1000, 1000, -10000);
DPoint3d[] profilePos = { profilePo1, profilePo2, profilePo3, profilePo4 };//声明截面轮廓线端点集
ShapeElement shape = new ShapeElement(dgnModel, null, profilePos);//声明形元素
CurveVector curve = CurvePathQuery.ElementToCurveVector(shape);//使用形元素获得轮廓线
DPoint3d pathPo1 = new DPoint3d(0, 0, -10000);//声明扫掠轨迹线端点
DPoint3d pathPo2 = new DPoint3d(0, 0, 0);
DPoint3d pathPo3 = new DPoint3d(10000, 10000, 10000);
DPoint3d pathPo4 = new DPoint3d(-10000, -10000, 20000);
DPoint3d pathPo5 = new DPoint3d(0, 0, 30000);
DPoint3d pathPo6 = new DPoint3d(0, 0, 40000);
DPoint3d[] pathPos = { pathPo1, pathPo2, pathPo3, pathPo4, pathPo5, pathPo6 };//声明扫掠轨迹端点集
LineStringElement lineString = new LineStringElement(dgnModel, null, pathPos);//声明线串元素
CurveVector pathCurve = lineString.GetCurveVector();//使用线串元素获得扫掠轨迹点
Create.BodyFromSweep(out SolidKernelEntity entityOut, curve, pathCurve, dgnModel, false, true, false,
null, null, null, null);//使用横截面扫掠路径声明实体
BentleyStatus result = Convert1.BodyToElement(out Element eeh, entityOut, null, dgnModel);//将SolidKernelEntity转换为元素
eeh.AddToModel();//将元素写入模型
#endregion
#endregion
DgnModel newModel= CreateDgnModelTest("test2");//声明名为“test2”的模型
BentleyStatus copyStatus= DgnFile.CopyModelContents(newModel, dgnModel);//将test1中的所有信息复制到test2中
MessageBox.Show("Copy result:\n"+copyStatus);//在对话框中输出复制结果
}
private static DgnModel CreateDgnModelTest(string modelName)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件信息
ModelId id = dgnFile.FindModelIdByName(modelName);//检索文件中是否存在名为modelname引用字符串的模型
if(id!= ModelId.InvalidModel)//判断模型ID是否有效
{
DgnModel existModel = dgnFile.LoadRootModelById(out StatusInt status, id);//使用ID读取获得对应的模型空间
dgnFile.DeleteModel(existModel);
}
DgnModel dgnModel = dgnFile.CreateNewModel(out DgnModelStatus createStatus, modelName, DgnModelType.Normal, true, null);//声明新模型
return dgnModel;//返回新建模型
}
在本案例中,首先创建了一个名为"test"的被复制模型,为了体现效果,在被复制模型中创建智能实体,然后又创建了一个名为"test2"的模型,最后将模型为"test"的模型数据复制到名为"test2"模型中。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645068101053-63e5b1b8-6234-491d-90ee-0db605b5877b.png#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=169&id=u4cce7266&margin=%5Bobject%20Object%5D&name=image.png&originHeight=169&originWidth=1034&originalType=binary&ratio=1&rotation=0&showTitle=false&size=16673&status=done&style=none&taskId=ud754f57a-60f3-444e-b457-a19c0924e9d&title=&width=1034)<br />**图9 模型创建结果**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645068172042-c253dd97-3f0c-4e84-a3de-b916e787d040.png#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1026&id=uf18599cc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1026&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=383492&status=done&style=none&taskId=ua8d5ea72-e180-4fe8-abe6-e77be374863&title=&width=1920)<br />**图10 被复制模型数据**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645068141384-5abb15b2-7bfb-4dbe-b0ec-c7294d668cad.png#clientId=uec29db71-42a8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1030&id=uf4867f19&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1030&originWidth=1919&originalType=binary&ratio=1&rotation=0&showTitle=false&size=381737&status=done&style=none&taskId=u29f63728-815b-4f15-a1ee-b76302553e9&title=&width=1919)<br />**图11 生成模型数据**
模型部分复制
当我们在复制过程中只需要对部分元素进行复制操作时,使用上述方法便无法满足既定要求,这里我们使用ElementCopyContext( )执行数据的复制,该方法使用的步骤为遍历模型中的元素,然后对元素进行筛选,最后将指定的模型复制到指定模型空间中。
public static void CopyDgnModelWithPartialData(string unparsed)
{
DgnModel dgnModel = CreateDgnModelTest("test");//声明名为“test”的模型
#region Create elements in dgnmodel
#region Create Smart Solid
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件信息
DPoint3d profilePo1 = new DPoint3d(1000, 1000, -10000);//声明截面轮廓线端点
DPoint3d profilePo2 = new DPoint3d(1000, -1000, -10000);
DPoint3d profilePo3 = new DPoint3d(-1000, -1000, -10000);
DPoint3d profilePo4 = new DPoint3d(-1000, 1000, -10000);
DPoint3d[] profilePos = { profilePo1, profilePo2, profilePo3, profilePo4 };//声明截面轮廓线端点集
ShapeElement shape = new ShapeElement(dgnModel, null, profilePos);//声明形元素
CurveVector curve = CurvePathQuery.ElementToCurveVector(shape);//使用形元素获得轮廓线
DPoint3d pathPo1 = new DPoint3d(0, 0, -10000);//声明扫掠轨迹线端点
DPoint3d pathPo2 = new DPoint3d(0, 0, 0);
DPoint3d pathPo3 = new DPoint3d(10000, 10000, 10000);
DPoint3d pathPo4 = new DPoint3d(-10000, -10000, 20000);
DPoint3d pathPo5 = new DPoint3d(0, 0, 30000);
DPoint3d pathPo6 = new DPoint3d(0, 0, 40000);
DPoint3d[] pathPos = { pathPo1, pathPo2, pathPo3, pathPo4, pathPo5, pathPo6 };//声明扫掠轨迹端点集
LineStringElement lineString = new LineStringElement(dgnModel, null, pathPos);//声明线串元素
CurveVector pathCurve = lineString.GetCurveVector();//使用线串元素获得扫掠轨迹点
Create.BodyFromSweep(out SolidKernelEntity entityOut, curve, pathCurve, dgnModel, false, true, false,
null, null, null, null);//使用横截面扫掠路径声明实体
BentleyStatus result = Convert1.BodyToElement(out Element eeh, entityOut, null, dgnModel);//将SolidKernelEntity转换为元素
eeh.AddToModel();//将元素写入模型
#endregion
#region
DPoint3d centerPo = DPoint3d.Zero;//声明圆心坐标
EllipseElement ellipseElem = new EllipseElement(dgnModel, null, centerPo, 20000, 10000, DMatrix3d.Identity);//声明椭圆元素
ellipseElem.AddToModel();//将椭圆元素写入模型空间
#endregion
#endregion
DgnModel newModel = CreateDgnModelTest("test2");//声明名为“test2”的模型
ModelElementsCollection elements= dgnModel.GetGraphicElements();//获得模型中的所有图形元素
foreach (Element elem in elements)//遍历元素容器中的元素
{
using (ElementCopyContext copyContext = new ElementCopyContext(newModel))//复制元素
{
if(elem.ElementType==MSElementType.Ellipse)//判断元素类型是否为椭圆
{
copyContext.DoCopy(elem);//将元素复制到指定模型中
}
}
}
}
private static DgnModel CreateDgnModelTest(string modelName)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件信息
ModelId id = dgnFile.FindModelIdByName(modelName);//检索文件中是否存在名为modelname引用字符串的模型
if(id!= ModelId.InvalidModel)//判断模型ID是否有效
{
DgnModel existModel = dgnFile.LoadRootModelById(out StatusInt status, id);//使用ID读取获得对应的模型空间
dgnFile.DeleteModel(existModel);
}
DgnModel dgnModel = dgnFile.CreateNewModel(out DgnModelStatus createStatus, modelName, DgnModelType.Normal, true, null);//声明新模型
return dgnModel;//返回新建模型
}
在本案例中,首先新建了一个名为"test"的模型,然后在该模型中创建了一个智能实体和一个椭圆元素,然后又创建了一个名为"test2"的模型,最后遍历"test"模型中的元素,将模形中元素类型是椭圆的元素复制到"test2"模型中。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645077167034-d538461c-8942-4a8f-9867-0e4ab6527781.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=152&id=u045114af&margin=%5Bobject%20Object%5D&name=image.png&originHeight=152&originWidth=1033&originalType=binary&ratio=1&rotation=0&showTitle=false&size=16451&status=done&style=none&taskId=u0a6d0131-fd39-4a40-b54f-7c9b0ae28a0&title=&width=1033)<br />**图12 模型创建结果**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645077213965-0a5e3fb8-715a-4ed6-84a7-9ec58caa96d2.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1028&id=udfedb509&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1028&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=399540&status=done&style=none&taskId=u48e4220e-4624-44c9-8557-904cb05e63e&title=&width=1920)<br />**图13 被复制模型数据**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645077236364-a6ff232d-ae25-42d4-8d48-a7a1ffc2379e.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1031&id=u2113042d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1031&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=396057&status=done&style=none&taskId=ue7df086f-5533-4c20-8667-d300071aeca&title=&width=1920)<br />**图14 生成模型数据**
参照操作
模型参照(*.dgn)
当我们需要与同专业,或者跨专业协同配合时,总是无可避免的需要参照他人的模型。若想通过编程的方式提前将参照模型与指定场景绑定起来,那么就需要掌握模型参照的方法。关于该方法大致的使用流程为首先确定参照引用的目标模型,然后通过参照文件的储存路径获取对应的文件,最后将文件中指定模型参照到目标模型中,写入模型即引用模型成功。
public static void AttachDgnModel(string unparsed)
{
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的模型空间
string strDgn = "E:\\工作相关\\20211213MS案例直播\\直播资料\\Part4\\FileManage - Copy.dgn";//文件储存路径
DgnDocumentMoniker moniker = DgnDocumentMoniker.CreateFromFileName(strDgn,null);//声明引用文件系统的DgnDocumentMoniker对象
DgnAttachment attach=dgnModel.CreateDgnAttachment(moniker,"test");//将指定模型引用到当前模型空间中
StatusInt status= attach.WriteToModel(false);//将引用写入模型
if(status==StatusInt.Success)//判断写入是否成功
{
MessageBox.Show("Attach DgnModel:\nSuccess");//对话框输出成功提示
}
}
在本案例中,执行上述代码后可以发现,名为FileManage - Copy.dgn的文件中的"test"模型中的数据被成功参照到当前模型空间中。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645077972746-c4b94d31-9ba2-4ef4-9d48-f026dfd2e22e.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=202&id=u5647276a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=202&originWidth=931&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15970&status=done&style=none&taskId=u64733da7-73fe-419c-8688-9257c8154f7&title=&width=931)<br />**图15 命令执行前**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645078265711-72b90408-ae7a-42fa-9f49-2615cac4a71e.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1025&id=u345ebd5a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1025&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=391321&status=done&style=none&taskId=ud3d98357-3169-4591-aa7f-c8c0ff4b6bc&title=&width=1920)<br />**图16 命令执行结果**
CAD图纸参照(*.dwg)
当我们需要使用CAD图纸进行参考时,对应的也可以使用参考的方式实现CAD图纸的参考,采用的方法与模型参照一致。
public static void AttachDWGFile(string unparsed)
{
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的模型空间
string strDgn = "E:\\工作相关\\20211213MS案例直播\\直播资料\\Part4\\111.dwg";//文件储存路径
DgnDocumentMoniker moniker = DgnDocumentMoniker.CreateFromFileName(strDgn, null);//声明引用文件系统的DgnDocumentMoniker对象
DgnAttachment attach = dgnModel.CreateDgnAttachment(moniker, null);//将指定模型引用到当前模型空间中
StatusInt status = attach.WriteToModel(false);//将引用写入模型
if (status == StatusInt.Success)//判断写入是否成功
{
MessageBox.Show("Attach DWG File:\nSuccess");//对话框输出成功提示
}
}
在本案例中,执行上述代码后,名为111.dwg的图纸被成功参考到当前的模型空间中。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645078916381-8ff7227e-0b43-4284-af60-bd6007d4cf94.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=196&id=uccee6461&margin=%5Bobject%20Object%5D&name=image.png&originHeight=196&originWidth=906&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33622&status=done&style=none&taskId=u2a8b7959-dd48-4bd3-8246-f4ab057f37c&title=&width=906)<br />**图17 命令执行前**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645078900628-e2c9b204-2c18-45aa-9148-43ad7c802ebd.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1028&id=ua17a3b83&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1028&originWidth=1918&originalType=binary&ratio=1&rotation=0&showTitle=false&size=387066&status=done&style=none&taskId=u16fb184e-2bb8-4468-a8f9-74db56e25f2&title=&width=1918)<br />**图18 命令执行结果**
取消模型参照
当我们需要取消模型中的指定参照时,需要使用到DeleteDgnAttachment( )。大致的流程为遍历模型中的参照模型,根据名称找到需要取消参照的指定参照模型,使用上述方法执行取消参照的操作。
public static void DetachDgnModel(string unparsed)
{
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的模型空间
DgnAttachmentCollection attachments = dgnModel.GetDgnAttachments();//获得该模型空间中所有的参照
foreach(DgnAttachment attachment in attachments)//遍历模型空间中的所有参照
{
if(attachment.AttachModelName== "test")//判断参照的模型名称是否为test
{
StatusInt status = dgnModel.DeleteDgnAttachment(attachment);//删除模型中的指定参照
if (status == StatusInt.Success)//判断写入是否成功
{
MessageBox.Show("Detach DgnModel:\nSuccess");//对话框输出成功提示
}
}
}
}
文件操作
文件读取
当我们希望对非当前文件执行读取操作时,就需要使用该方法实现跨文件的数据读取。关于文件读取的大致流程为首先确定需要操作文件的路径,然后通过DgnDocument获得对应的DgnFile,通过DgnFile即可读取文件中信息。
public static void ReadDgnFile(string unparsed)
{
string strDgn = "E:\\工作相关\\20211213MS案例直播\\直播资料\\Part4\\ReadFile.dgn";//文件储存路径
DgnDocument dgnDoc = DgnDocument.CreateForLocalFile(strDgn);//声明DgnDocument对象
DgnFileOwner dgnFileOwner = DgnFile.Create(dgnDoc, DgnFileOpenMode.ReadOnly);//声明一个用于加载部分文件的DgnFile,控制DgnFile的生存期
DgnFile dgnFile = dgnFileOwner.DgnFile;//获得已加载的DgnFile
dgnFile.LoadDgnFile(out StatusInt errorStatus);//读取加载DgnFile
dgnFile.FillDictionaryModel();//确定已填充模型字典(非模型区,保存各种内置对象,如图层、样式等)
DgnModel dgnModel = dgnFile.LoadRootModelById(out errorStatus, dgnFile.DefaultModelId);//根据模型ID读取文件中的指定模型
ModelElementsCollection elems=dgnModel.GetGraphicElements();//获得模型中的所有图形元素
string result = "The result is:\n";//声明字符串
foreach(Element elem in elems)//遍历图形元素
{
result = result + "ElementId = " + elem.ElementId + " Element Type = " + elem.ElementType+'\n';//输出模型中的元素ID及元素类型
}
MessageBox.Show(result);//输出结果
}
在本案例中,通过指定文件路径获取到对应文件中的信息,而后找到文件的默认模型,获取模型中的图形元素信息并进行输出,通过查看对应文件中的模型可以看出,输出结果与文件中实际存在的模型信息一一对应。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645079978584-48dd96aa-59e4-462b-b3c0-1ca7be832978.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=202&id=uad5748c6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=202&originWidth=309&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17305&status=done&style=none&taskId=ud1c47f2d-6228-415d-bf49-a9350237d5e&title=&width=309)<br />**图21 命令输出结果**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645080069229-de5b02a3-3bc8-47f8-8c8d-b26c8906ac1d.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1031&id=u8f01a291&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1031&originWidth=1915&originalType=binary&ratio=1&rotation=0&showTitle=false&size=435490&status=done&style=none&taskId=ue5f58903-df38-46ad-884e-baa62d8f059&title=&width=1915)<br />**图22 读取文件默认模型**
文件另存为
当我们需要使用代码的方式实现文件的另存为时,就需要使用到DoSaveAs( )这个方法。实现另存为的功能流程为:首先在指定位置创建文件,创建完成后将需要另存的文件保存至刚才创建文件中。
public static void SaveAsDgnFile(string unparsed)//Case:test
{
string filePath = "E:\\工作相关\\20211213MS案例直播\\直播资料\\Part4\\NewFileBySaveAs.dgn";//文件储存路径
DgnDocument dgnDoc = DgnDocument.CreateForNewFile(out DgnFileStatus status, filePath, "", 0, "",DgnDocument.OverwriteMode.Always,DgnDocument.CreateOptions.Default);
/*
* 用DgnDocument对象表示在文件中声明的新文件
* status:若返回空,则有可能为:文件已存在,但未指定覆盖或无法覆盖
* documentName:声明文件的文件名称
* searchPath:用于设置搜索的基本路径,可为空,他包含一个或多个配置变量,目录路径或文件路径
* defFileId:表示声明的文件类型
* wDefaultFileName:指定根据名称查找现有文件时使用的默认驱动器,路径,文件名或扩展名
* overwriteMode:指定当文件存在时要执行的操作
* options:声明类型
*/
if (dgnDoc!=null)//判断文件是否声明成功
{
StatusInt statusInt = dgnDoc.OnNewFileCreated();//声明文件后调用,允许文档管理器将文件添加到储存库中,若该文件只是临时文件则无需调用
if (statusInt == StatusInt.Success)//判断是否成功
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的文件信息
statusInt = dgnFile.DoSaveAs(dgnDoc, DgnFileFormatType.V8, true, false);//将本文件另存到新建文件中
}
}
}
在本案例中,首先在指定路径下创建了一个名为NewFileBySaveAs的dgn文件,然后将当前的文件信息另存至刚才创建的文件中。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645080756494-9f320c49-c28e-4fdc-b973-1e991109b080.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1031&id=ue49e4d7b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1031&originWidth=1918&originalType=binary&ratio=1&rotation=0&showTitle=false&size=461433&status=done&style=none&taskId=u0b009c94-2cf6-42f2-8a12-a6eced2253c&title=&width=1918)<br />**图23 当前文件中的模型**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645080808058-120b9a2f-dbf2-4753-a8e5-4560d552aafb.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=617&id=u190dca1a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=617&originWidth=1018&originalType=binary&ratio=1&rotation=0&showTitle=false&size=85975&status=done&style=none&taskId=u7a14e62e-0c7a-48d0-bcd2-19b396f9a58&title=&width=1018)<br />**图24 命令执行后生成NewFileBySaveAs文件**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645080822648-2992dd06-4866-4526-9848-db9e0048b9b1.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1030&id=ua73f3c5a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1030&originWidth=1919&originalType=binary&ratio=1&rotation=0&showTitle=false&size=462407&status=done&style=none&taskId=ubd041b49-b390-44c3-a5ae-886764212ff&title=&width=1919)<br />**图24 NewFileBySaveAs文件中的模型**
文件创建
当我们需要创建一个新的文件时,需要使用CreateNew( )实现。实现该功能的大致流程为首先确定文件储存地址,然后使用种子文件,文件打开模式等信息创建文件。
public static void CreateDgnFile(string unparsed)
{
string filePath = "E:\\工作相关\\20211213MS案例直播\\直播资料\\Part4\\NewCreateFile.dgn";//文件储存路径
DgnDocument dgnDoc = DgnDocument.CreateForNewFile(out DgnFileStatus status, filePath, "", 0, "", DgnDocument.OverwriteMode.Always, DgnDocument.CreateOptions.Default);//用DgnDocument对象表示在文件中声明的新文件
if (dgnDoc != null)//判断文件是否声明成功
{
StatusInt statusInt = dgnDoc.OnNewFileCreated();//声明文件后调用,允许文档管理器将文件添加到储存库中,若该文件只是临时文件则无需调用
if (statusInt == StatusInt.Success)//判断是否成功
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的文件信息
SeedData seed = new SeedData(dgnFile, dgnFile.DefaultModelId, SeedCopyFlags.AllData, false);//获得当前文中默认模型的种子信息
DgnFileOwner owner = DgnFile.CreateNew(out DgnFileStatus fileStatus, dgnDoc, DgnFileOpenMode.ReadWrite, seed, DgnFileFormatType.V8, true);//基于种子文件(可选),声明一个dgn文件
owner.Dispose();//在内存中释放该文件
}
}
}
在本案例中,命令执行之后在指定的路径下生成了一个名为NewCreateFile的文件。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645081593704-c73ba829-df84-468d-8139-0f07d65b6d0e.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=616&id=u7e33e0b2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=616&originWidth=1023&originalType=binary&ratio=1&rotation=0&showTitle=false&size=85918&status=done&style=none&taskId=u4d060484-a81f-4c3f-a242-8f43ead3db4&title=&width=1023)<br />**图25 命令执行后生成NewCreateFile文件**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645081663277-b56bfeb2-e21e-49c9-af65-c422d7242e61.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1030&id=u8d8ffbdf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1030&originWidth=1917&originalType=binary&ratio=1&rotation=0&showTitle=false&size=417347&status=done&style=none&taskId=ud4f07f32-8f1d-4b28-93c2-2b30066d577&title=&width=1917)<br />**图26 生成NewCreateFile文件**
NamedGroup介绍
当我们需要对模型中的元素分组时,就需要使用NamedGroup功能,不同于单元,他们的元素并没有那么强的组合关系,同时,组与组之间可以实现嵌套,体现元素间的层级关系。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645083595903-e5177319-50d3-4c0b-982e-35d8cbc0070c.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=378&id=u7df51720&margin=%5Bobject%20Object%5D&name=image.png&originHeight=378&originWidth=597&originalType=binary&ratio=1&rotation=0&showTitle=false&size=25596&status=done&style=none&taskId=u1057d6d0-1573-41f3-a527-efb86a3e35b&title=&width=597)<br />**图27 NamedGroups界面**
创建NamedGroup
NamedGroup的创建流程为声明NamedGroup后添加成员,然后将NamedGroup写入模型。
public static void CreateNamedGroup(string unparsed)
{
DgnModelRef dgnmodelRef = Session.Instance.GetActiveDgnModelRef();//获得当前激活的dgn模型
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的dgn模型
double uorMeter = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter;//获得当前模型中的单位
#region
DPoint3d[] ptArr = new DPoint3d[5];//声明面片元素端点集
ptArr[0] = new DPoint3d(-15 * uorMeter, -5 * uorMeter, 0 * uorMeter);//声明端点坐标
ptArr[1] = new DPoint3d(-15 * uorMeter, 5 * uorMeter, 0 * uorMeter);
ptArr[2] = new DPoint3d(-5 * uorMeter, 5 * uorMeter, 0 * uorMeter);
ptArr[3] = new DPoint3d(-5 * uorMeter, -5 * uorMeter, 0 * uorMeter);
ptArr[4] = new DPoint3d(-15 * uorMeter, -5 * uorMeter, 0 * uorMeter);
ShapeElement shapeEle = new ShapeElement(dgnModel, null, ptArr);//声明形元素
shapeEle.AddToModel();//将形元素写入模型
DPlacementZX dPlaceZX = DPlacementZX.Identity;//声明椭圆放置平面
dPlaceZX.Origin = new DPoint3d(-10 * 10000, 0, 0);//设置平面原点
DEllipse3d ellipse = new DEllipse3d(dPlaceZX, 5 * uorMeter, 5 * uorMeter, Angle.Zero, Angle.TWOPI);//声明几何椭圆
EllipseElement elliElem = new EllipseElement(dgnModel, null, ellipse);//声明椭圆元素
elliElem.AddToModel();//将椭圆元素写入模型
#endregion
string groupName = "TestGroupName";//设置NamedGroup名称
string groupDescription = "TestGroupDescription";//设置NamedGroup描述
NamedGroupFlags flags = new NamedGroupFlags();//声明NamedGroup设置
NamedGroup group = new NamedGroup(groupName,groupDescription, flags, dgnmodelRef);//声明NamedGroup
NamedGroupMemberFlags memberFlags1 = new NamedGroupMemberFlags();//声明NamedGroup成员设置
memberFlags1.GroupPropagate = NamedGroupPropagationFlags.Always;//当此元素属于其他组时,是否遍历这些组
group.AddMember(shapeEle.ElementId,dgnmodelRef, memberFlags1);//将NamedGroup成员添加到NamedGroup中
NamedGroupMemberFlags memberFlags2 = new NamedGroupMemberFlags();//声明NamedGroup成员设置
memberFlags2.GroupPropagate = NamedGroupPropagationFlags.Always;//当此元素属于其他组时,是否遍历这些组
group.AddMember(elliElem.ElementId, dgnmodelRef, memberFlags2);//将NamedGroup成员添加到NamedGroup中
NamedGroupStatus status= group.WriteToFile(true);//将NamedGroup写入文件
MessageBox.Show("Name Group Create Status:\n"+status);//输出写入结果
}
本案例中,首先在文件中创建了一个形元素和一个椭圆元素,然后创建了一个NamedGroup,并将刚才创建的两个元素加入到NamedGroup中。当我们删除NamedGroup中的元素时NamedGroup中的信息也会同步更新。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645082841030-f0b30660-1b9e-4cf1-ba2a-37717e06e333.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1031&id=u47808830&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1031&originWidth=1919&originalType=binary&ratio=1&rotation=0&showTitle=false&size=424209&status=done&style=none&taskId=ud3d1c30a-f5f5-4f37-8a69-43bf3536496&title=&width=1919)<br />**图28 命令执行结果**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645083541209-b64677db-60fd-4ec7-a856-dd3c07b418b1.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=374&id=ub678d43f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=374&originWidth=602&originalType=binary&ratio=1&rotation=0&showTitle=false&size=34259&status=done&style=none&taskId=u86c3818f-c90e-407a-95ee-dc8c15076e4&title=&width=602)<br />**图29 NamedGroups界面**
创建带有层级关系的NamedGroup
当我们需要对模型中的元素进行从属关系分类管理时,可能会使用到具有层级关系表达功能的NamedGroup。在NamedGroup中进行添加时,我们不仅可以添加元素,同时也可以添加NamedGroup,以便对元素或元素集进行管理。
public static void CreateNamedGroupWithHierarchy(string unparsed)
{
DgnModelRef dgnmodelRef = Session.Instance.GetActiveDgnModelRef();//获得当前激活的dgn模型
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的dgn模型
double uorMeter = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter;//获得当前模型中的单位
#region
DPoint3d[] ptArr = new DPoint3d[5];//声明面片元素端点集
ptArr[0] = new DPoint3d(-15 * uorMeter, -5 * uorMeter, 0 * uorMeter);//声明端点坐标
ptArr[1] = new DPoint3d(-15 * uorMeter, 5 * uorMeter, 0 * uorMeter);
ptArr[2] = new DPoint3d(-5 * uorMeter, 5 * uorMeter, 0 * uorMeter);
ptArr[3] = new DPoint3d(-5 * uorMeter, -5 * uorMeter, 0 * uorMeter);
ptArr[4] = new DPoint3d(-15 * uorMeter, -5 * uorMeter, 0 * uorMeter);
ShapeElement shapeEle = new ShapeElement(dgnModel, null, ptArr);//声明形元素
shapeEle.AddToModel();//将面片元素写入模型
DPlacementZX dPlaceZX = DPlacementZX.Identity;//声明椭圆放置平面
dPlaceZX.Origin = new DPoint3d(-10 * 10000, 0, 0);//设置平面原点
DEllipse3d ellipse = new DEllipse3d(dPlaceZX, 5 * uorMeter, 5 * uorMeter, Angle.Zero, Angle.TWOPI);//声明几何椭圆
EllipseElement elliElem = new EllipseElement(dgnModel, null, ellipse);//声明椭圆元素
elliElem.AddToModel();//将椭圆元素写入模型
#endregion
string groupName1 = "TestGroupName1";//设置NamedGroup名称
string groupDescription1 = "TestGroupDescription1";//设置NamedGroup描述
NamedGroupFlags flags1 = new NamedGroupFlags();//声明NamedGroup设置
NamedGroup group1 = new NamedGroup(groupName1, groupDescription1, flags1, dgnmodelRef);//声明NamedGroup
NamedGroupMemberFlags memberFlags1 = new NamedGroupMemberFlags();//当此元素属于其他组时,是否遍历这些组
memberFlags1.GroupPropagate = NamedGroupPropagationFlags.Always;//当此元素属于其他组时,是否遍历这些组
group1.AddMember(shapeEle.ElementId, dgnmodelRef, memberFlags1);//将NamedGroup成员添加到NamedGroup中
group1.WriteToFile(true);//将NamedGroup写入文件
string groupName2 = "TestGroupName2";//设置NamedGroup名称
string groupDescription2 = "TestGroupDescription2";//设置NamedGroup描述
NamedGroupFlags flags2 = new NamedGroupFlags();//声明NamedGroup设置
NamedGroup group2 = new NamedGroup(groupName2, groupDescription2, flags2, dgnmodelRef);//声明NamedGroup
NamedGroupMemberFlags memberFlags2 = new NamedGroupMemberFlags();//当此元素属于其他组时,是否遍历这些组
memberFlags2.GroupPropagate = NamedGroupPropagationFlags.Always;//当此元素属于其他组时,是否遍历这些组
group2.AddMember(elliElem.ElementId, dgnmodelRef, memberFlags2);//将NamedGroup成员添加到NamedGroup中(元素)
group2.AddMember(group1.GetElement().ElementId, dgnmodelRef, memberFlags2);//将NamedGroup成员添加到NamedGroup中(NamedGroup)
group2.WriteToFile(true);//将NamedGroup写入文件
}
在本案例中,首先在模型空间中创建了一个形元素与一个椭圆元素,将形元素添加到名为"TestGroupName1"的NamedGroup中,与上面的方法不同,本案例中将椭圆元素和名为"TestGroupName1"的NamedGroup添加到名为"TestGroupName2"的NamedGroup中,从而实现了对具有层级关系的元素进行管理。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645084488198-70de7978-df6a-4d15-bc1e-c6bd8e8c1cf8.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1027&id=u5c3a23d8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1027&originWidth=1919&originalType=binary&ratio=1&rotation=0&showTitle=false&size=432738&status=done&style=none&taskId=u793ac944-c57e-4f9d-9e77-296e944d045&title=&width=1919)<br />**图30 命令执行结果**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645084517939-ec1dc428-3115-479b-affe-2763c6d207c7.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=376&id=uf8a93ec6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=376&originWidth=606&originalType=binary&ratio=1&rotation=0&showTitle=false&size=41633&status=done&style=none&taskId=u68339799-8f02-4fc6-96f2-80608352efc&title=&width=606)<br />**图31 NamedGroups界面**
删除NamedGroup
当我们需要删除NamedGroup,需要使用DeleteFromFile( )。大致的流程为遍历模型中的NamedGroup集合,找到指定名称的NamedGroup,然后调用方法删除NamedGroup。
public static void DeleteNamedGroup(string unparsed)
{
DgnModelRef dgnModelRef= Session.Instance.GetActiveDgnModelRef();//获得当前激活的dgn模型
NamedGroupCollection groups = new NamedGroupCollection(dgnModelRef);//获得模型中的NamedGroup集
NamedGroup group= groups.FindByName("TestGroupName");//根据名称获取对应的NamedGroup
if (group!=null)//判断是否成功获得指定NamedGroup
{
NamedGroupStatus status= group.DeleteFromFile();//将指定NamedGroup删除
MessageBox.Show("Name Group Delete Status:\n" + status);//输出结果
}
}
本案例中采用上方创建NamedGroup命令,生成了带有NamedGroup属性的元素,使用删除NamedGroup命令后,名为"TestGroupName"的NamedGroup被删除,元素上的NamedGroup属性被移除。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645085045398-2d5ed430-4221-4b15-a879-c895287fa8f2.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1031&id=u68fff224&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1031&originWidth=1919&originalType=binary&ratio=1&rotation=0&showTitle=false&size=432700&status=done&style=none&taskId=u299846f6-998d-411e-9178-a1e090f9ab4&title=&width=1919)<br />**图32 命令执行前**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645085178239-5e3f08e0-52cd-41c0-ac71-40ea05640296.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1031&id=u5e9aa595&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1031&originWidth=1915&originalType=binary&ratio=1&rotation=0&showTitle=false&size=417017&status=done&style=none&taskId=u80418818-0c9a-4aa5-8dbf-e7da7325c7d&title=&width=1915)<br />**图33 命令执行结果**
材质
材质主要用于对元素进行材质贴图,以表现实际的材料样式。材质表中包含材质表,材质面板以及材质。而其属性记录了反射等多种属性以表达实际材质效果。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645085366286-ef7f7b39-a78c-4a38-a105-370f16add857.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=857&id=uf29fdc03&margin=%5Bobject%20Object%5D&name=image.png&originHeight=857&originWidth=927&originalType=binary&ratio=1&rotation=0&showTitle=false&size=124257&status=done&style=none&taskId=u30496566-bc66-4af1-a635-a75748d5db7&title=&width=927)<br />**图34 材质编辑器界面**
创建材质
当我们需要创建自定义的材质时,对应的,需要依次创建材质表,材质面板以及材质。
public static void CreateMaterial(string unparsed)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的dgn模型
MaterialTable createdTable = new MaterialTable(dgnFile);//声明材料表
createdTable.Name = "Table1";//设置材料表名称
createdTable.Description = "Description1";//设置材料表描述信息
Material savedMaterial1 = new Material(dgnModel);//声明材料
savedMaterial1.Name = "Material5";//设置材料名称
PaletteInfo pInfo1 = savedMaterial1.GetPalette();//设置材料所在面板信息
pInfo1.Name = "SavedPalette";//设置材料所在面板名称
pInfo1.SetSource(dgnFile.GetDocument().GetMoniker());//设置面板源文件域
pInfo1.Type = PaletteInfo.PaletteType.Dgn;//设置面板类型
MaterialManager.SaveMaterial(null, savedMaterial1, dgnFile);//保存材料信息
Material savedMaterial2 = new Material(dgnModel);//声明材料
savedMaterial2.Name = "Material7";//设置材料名称
PaletteInfo pInfo2 = savedMaterial2.GetPalette();//设置材料所在面板信息
pInfo2.Name = "SavedPalette";//设置材料所在面板名称
pInfo2.SetSource(dgnFile.GetDocument().GetMoniker());//设置面板源文件域
pInfo2.Type = PaletteInfo.PaletteType.Dgn;//设置面板类型
MaterialManager.SaveMaterial(null, savedMaterial2, dgnFile);//保存材料信息
MaterialId materialId = new MaterialId("Material5");//声明材料ID
createdTable.AddAssignment(new MaterialAssignment(materialId, "Level 1", 0, createdTable.GetRenderDgn()));//将材料分配信息添加到表中
createdTable.AddAssignment(new MaterialAssignment(new MaterialId("Material7"), "Level 10", 4, createdTable.GetRenderDgn()));//将材料分配信息添加到表中
MaterialManager.SaveTable(createdTable);//保存材料表
}
本案例中,首先创建了一个名为"Table1"的材质表,然后创建了一个名为"SavedPalette"的材质面板,最后分别创建了名为"Material7"与"Material5",并将材质与图层绑定。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645085602721-89e431a4-f2bf-47f5-80fa-93c1516a0fd6.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=856&id=u50cc48fc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=856&originWidth=924&originalType=binary&ratio=1&rotation=0&showTitle=false&size=95405&status=done&style=none&taskId=ud959cafc-9127-4fc0-9b67-5c0c215e7ec&title=&width=924)<br />**图35 材质编辑器界面**
图层
图层材质赋予
使用材质的方式一般来说主要是将材质赋予元素,该方法即可将材质与图层绑定后赋予元素。主要的步骤为在文件中创建指定名称的图层,完成后创建材料,并将材料与图层绑定。命令执行完毕后当给元素赋予该图层后,其材质即为创建的材质。
public static void CreateLevelWithMaterial(string unparsed)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的dgn模型
string levelName = "Level 1 :0";//声明字符串指代图层名称
FileLevelCache flc = dgnModel.GetFileLevelCache();//获得模型中的图层文件缓存
flc.Write();//将文件写入缓存
LevelHandle level = flc.GetLevelByName(levelName);//根据图层名称获得图层句柄
if (!level.IsValid)//判断图层是否有效(若图层无效在则为真)
{
EditLevelHandle elh = flc.CreateLevel(levelName);//声明名为levelName的图层
CreateMaterial(unparsed);//声明材料
}
}
public static void CreateMaterial(string unparsed)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的dgn模型
MaterialTable createdTable = new MaterialTable(dgnFile);//声明材料表
createdTable.Name = "Table1";//设置材料表名称
createdTable.Description = "Description1";//设置材料表描述信息
Material savedMaterial1 = new Material(dgnModel);//声明材料
savedMaterial1.Name = "Material5";//设置材料名称
PaletteInfo pInfo1 = savedMaterial1.GetPalette();//设置材料所在面板信息
pInfo1.Name = "SavedPalette";//设置材料所在面板名称
pInfo1.SetSource(dgnFile.GetDocument().GetMoniker());//设置面板源文件域
pInfo1.Type = PaletteInfo.PaletteType.Dgn;//设置面板类型
MaterialManager.SaveMaterial(null, savedMaterial1, dgnFile);//保存材料信息
Material savedMaterial2 = new Material(dgnModel);//声明材料
savedMaterial2.Name = "Material7";//设置材料名称
PaletteInfo pInfo2 = savedMaterial2.GetPalette();//设置材料所在面板信息
pInfo2.Name = "SavedPalette";//设置材料所在面板名称
pInfo2.SetSource(dgnFile.GetDocument().GetMoniker());//设置面板源文件域
pInfo2.Type = PaletteInfo.PaletteType.Dgn;//设置面板类型
MaterialManager.SaveMaterial(null, savedMaterial2, dgnFile);//保存材料信息
MaterialId materialId = new MaterialId("Material5");//声明材料ID
createdTable.AddAssignment(new MaterialAssignment(materialId, "Level 1", 0, createdTable.GetRenderDgn()));//将材料分配信息添加到表中
createdTable.AddAssignment(new MaterialAssignment(new MaterialId("Material7"), "Level 10", 4, createdTable.GetRenderDgn()));//将材料分配信息添加到表中
MaterialManager.SaveTable(createdTable);//保存材料表
}
图层颜色及线形样式赋予
若我们需要创建一个颜色及线形样式的图层时,需要使用LevelDefinitionLineStyle( )的构造函数实现。大致的流程为:创建图层后对图层的颜色与线形样式进行设置并应用于指定名称的图层上。
public static void CreateLevelWithColorAndLineStyle(string unparsed)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的dgn模型
string levelName = "TestLevel";//声明字符串指代图层名称
FileLevelCache flc = dgnModel.GetFileLevelCache();//获得模型中的图层文件缓存
flc.Write();//将文件写入缓存
LevelHandle level = flc.GetLevelByName(levelName);//根据图层名称获得图层句柄
if (!level.IsValid)//判断图层是否有效(若图层无效在则为真)
{
EditLevelHandle elh = flc.CreateLevel(levelName);//声明名为levelName的图层
LevelDefinitionColor color = new LevelDefinitionColor(4, dgnFile);//声明图层颜色定义
elh.SetByLevelColor(color);//设置图层颜色
elh.ByLevelWeight = 2;//设置图层线宽
int num = LineStyleManager.GetNumberFromName("Simple 05 V2", dgnFile, true, true);//获得名为Simple 05 V2的线样式索引值
LevelDefinitionLineStyle lineStyle = new LevelDefinitionLineStyle(num, null, dgnFile);//声明图层线样式索引
elh.SetByLevelLineStyle(lineStyle);//设置图层线样式
}
}
在本案例中,首先创建了一个名为"TestLevel"的图层,然后设置图层颜色为颜色索引值为4的黄色,设置名为"Simple 05 V2"的样式为该图层的线形样式。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645086888910-8dccd3a4-515d-4013-886b-fb14ec916afc.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=392&id=uf07ba38a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=392&originWidth=779&originalType=binary&ratio=1&rotation=0&showTitle=false&size=25567&status=done&style=none&taskId=u34f30d59-2d91-49de-8416-bd9188a2b0c&title=&width=779)<br />**图38 图层管理器界面**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645086936465-981db5b4-7150-4f63-8362-2579970f61df.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1030&id=u5dbf1326&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1030&originWidth=1919&originalType=binary&ratio=1&rotation=0&showTitle=false&size=449272&status=done&style=none&taskId=u696af31f-c701-4a59-81db-55a86ae6cd3&title=&width=1919)<br />**图39 材质应用于元素后效果**
文字样式
创建文字样式
该方法用于创建自定义的文字样式,大致的流程为声明文字样式后设置文字样式中文字的字体,字体宽度,高度等属性。
public static void CreateTextStyle(string unparsed)
{
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获得当前激活的dgn文件1
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得声明文本元素的模型空间
double uorMeter = dgnModel.GetModelInfo().UorPerMeter;//获得当前模型中的单位
DgnTextStyle textStyle = new DgnTextStyle("TestTextStyle", dgnFile);//声明文本样式
DgnFont font = DgnFontManager.FindSystemFont("KaiTi",DgnFontFilterFlags.All);//获得名为"KaiTi"的字体
textStyle.SetFontProperty(TextStyleProperty.Font, font);//设置字体
textStyle.SetProperty(TextStyleProperty.Width,20* uorMeter);//设置文本宽度
textStyle.SetProperty(TextStyleProperty.Height, 20 * uorMeter);//设置文本高度
textStyle.Add(dgnFile);//将文本样式添加到文件中
#region Create text element
TextBlockProperties txtBlockProp = new TextBlockProperties(dgnModel);//声明文本属性
txtBlockProp.IsViewIndependent = false;//设置文本非独立于视图
ParagraphProperties paraProp = new ParagraphProperties(dgnModel);//声明段落属性
RunProperties runProp = new RunProperties(textStyle, dgnModel);//声明运行属性
TextBlock txtBlock = new TextBlock(txtBlockProp, paraProp, runProp, dgnModel);//声明文本块
txtBlock.AppendText("试验");//设置文本块文字内容
TextElement text = (TextElement)TextElement.CreateElement(null, txtBlock);//声明文本元素
text.AddToModel();//将生成的文本元素写入模型
#endregion
}
本案例中,首先创建了一个名为"TestTextStyle"的文字样式,并设置字体为楷体,文字宽度及高度均为20个单位长,然后创建文本块,设置文本内容后创建文本元素,最后将文本元素写入模型。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645087683181-75ccaeb3-d0d8-4706-b652-06e2b6bd33ce.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=617&id=u55de761c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=617&originWidth=796&originalType=binary&ratio=1&rotation=0&showTitle=false&size=116249&status=done&style=none&taskId=u46cd1c3f-ca06-4a9d-b79f-9aa20c2d691&title=&width=796)<br />**图40 文本样式创建结果**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21640708/1645087703863-24167824-81fd-4cfc-97db-b8b90ae67bcf.png#clientId=u9ec56ae6-d60d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1028&id=uf237a909&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1028&originWidth=1917&originalType=binary&ratio=1&rotation=0&showTitle=false&size=535989&status=done&style=none&taskId=uf44cfebd-7ea7-45be-9f6a-c5ae2848bb6&title=&width=1917)<br />**图41 命令执行结果**
单元导入
参数化单元导入
参数化单元的导入方法为获得参数化单元存放地址后读取参数化文件中的信息,找到指定名称的模型。使用找到的模型在需要导入单元的文件中定义参数化单元定义元素,此时参数化单元即导入成功。
public static void ImportParametricCellElement(string unparsed)
{
const string cellName = "灯坑";//设置需要获取的单元名称
string filePath = "E:\\工作相关\\20211213MS案例直播\\直播资料\\Part4\\dengkeng.cel";//设置单元库路径
DgnDocument document = DgnDocument.CreateForLocalFile(filePath);//根据路径获取单元库文件
DgnFileOwner owner = DgnFile.Create(document,DgnFileOpenMode.ReadOnly);//声明可读取文件信息的DgnFile对象
DgnFile cellFile = owner.DgnFile;//获得读取文件信息的对象
cellFile.LoadDgnFile(out StatusInt fileLoadStatus);//读取文件信息
if(fileLoadStatus==StatusInt.Error)//若读取失败则返回
{
return;
}
ModelId id= cellFile.FindModelIdByName(cellName);//根据单元名称获取对应单元的模型ID
DgnModel cellModel = cellFile.LoadRootModelById(out StatusInt modelLoadStatus,id);//根据模型ID获取对应的模型空间
if (modelLoadStatus == StatusInt.Error)// 若读取失败则返回
{
return;
}
DgnFile dgnFile = Session.Instance.GetActiveDgnFile();//获取当前激活的文件
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获取当前激活的模型
ParametricCellDefinitionElement pcDef = ParametricCellDefinitionElement.FindByName(cellName, dgnFile);//根据名称在文件中获取对应的参数化定义元素
if (null == pcDef)//判断是否存在指定的参数化模型定义
{
DgnComponentDefinitionHandler hdlr = DgnComponentDefinitionHandler.GetForModel(cellModel);//获得模型中的定义句柄
ParameterStatus status = hdlr.DefinitionModelHandler.CreateCellDefinition(dgnFile);//声明单元定义
if (ParameterStatus.Success == status)//判断是否声明成功
{
pcDef = ParametricCellDefinitionElement.FindByName(cellName, dgnFile);//根据名称在文件中获取对应的参数化定义元素
}
else
{
MessageCenter.Instance.ShowErrorMessage("Error Creating cellDef", null, true);//输出参数化单元定义声明失败的提示
return;
}
}
if (pcDef!=null)//判断参数化单元定义是否成功声明
{
ParametricCellElement pcElem = ParametricCellElement.Create(pcDef, null, dgnModel);//使用参数化定义声明参数化元素
DTransform3d trans = DTransform3d.Identity;//声明变换几何
TransformInfo transInfo = new TransformInfo(trans);//声明变换信息
pcElem.ApplyTransform(transInfo);//对参数化单元进行变换
pcElem.AddToModel();//将参数化单元元素写入模型
}
}
普通单元导入
与参数化单元导入的方法类似,大致的流程未首先将指定位置的单元模型文件读取到内存中,然后根据名称获取指定模型,读取模型中的元素,在目标模型中使用所得模型中的元素对普通单元进行定义。
public static void ImportCellElement(string unparsed)
{
const string cellName = "服务车道平缝加拉杆直径14mm";//设置需要获取的单元名称
string filePath = "E:\\工作相关\\20211213MS案例直播\\直播资料\\Part4\\拉杆 (1).cel";//设置单元库路径
DgnDocument document = DgnDocument.CreateForLocalFile(filePath);//根据路径获取单元库文件
DgnFileOwner owner = DgnFile.Create(document, DgnFileOpenMode.ReadOnly);//声明可读取文件信息的DgnFile对象
DgnFile cellFile = owner.DgnFile;//获得读取文件信息的对象
cellFile.LoadDgnFile(out StatusInt fileLoadStatus);//读取文件信息
if (fileLoadStatus == StatusInt.Error)//若读取失败则返回
{
return;
}
ModelId id = cellFile.FindModelIdByName(cellName);//根据单元名称获取对应单元的模型ID
DgnModel cellModel = cellFile.LoadRootModelById(out StatusInt modelLoadStatus, id);//根据模型ID获取对应的模型空间
if (modelLoadStatus == StatusInt.Error)// 若读取失败则返回
{
return;
}
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获取当前激活的模型
List<Element> elems = new List<Element>();//声明单元子元素列表
foreach (Element elem in cellModel.GetElements())//对普通单元的模型进行遍历
{
if (elem.IsGraphics)//将单元中的子元素添加到列表中
{
elems.Add(elem);
}
}
CellHeaderElement cellHeaderElem = CellHeaderElement.CreateOrphanCellElement(dgnModel, cellName, elems);//使用子元素声明普通单元
DTransform3d trans = DTransform3d.FromMatrixAndFixedPoint(DMatrix3d.Identity, DPoint3d.Zero);//声明几何变换
TransformInfo transform = new TransformInfo(trans);//声明变换信息
cellHeaderElem.ApplyTransform(transform);//对普通单元应用变换
cellHeaderElem.AddToModel();//将普通单元写入模型
}
图43 命令执行结果