元素分解
提取元素中多面体几何(Polyface)
该方法主要用于对分解元素为Polyface,它的优势在于无论是什么元素,只要元素中几何部分具有Polyface,他就可以成功获取。
//参考文章:https://communities.bentley.com/communities/other_communities/bdn_other_communities/b/bdn-blog/posts/mesh
public static void BreakElementIntoPolyface(string unparsed)//Case:BreakSolidExample
{
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获取当前的模型空间
double uorPerMas = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster;//分辨率单位转换为主单位
#region Create Solid
#region Create profile
DPoint3d p1 = new DPoint3d(-uorPerMas, uorPerMas, 0);//声明体元素端点
DPoint3d p2 = new DPoint3d(uorPerMas, uorPerMas, 0);
DPoint3d p3 = new DPoint3d(uorPerMas, -uorPerMas, 0);
DPoint3d p4 = new DPoint3d(-uorPerMas, -uorPerMas, 0);
DPoint3d[] pos = { p1, p2, p3, p4 };//将面元素端点添加到面元素端点数组中
ShapeElement shape = new ShapeElement(dgnModel, null, pos);//声明形元素
#endregion
DPoint3d origin = DPoint3d.Zero;//声明拉伸基点
DVector3d extrudeVector = new DVector3d(uorPerMas, uorPerMas, 10* uorPerMas);//声明拉伸向量
SurfaceOrSolidElement solid = SurfaceOrSolidElement.CreateProjectionElement(dgnModel, null, shape, origin, extrudeVector, DTransform3d.Identity, true);//声明实体元素
solid.AddToModel();//将拉伸体写入模型
#endregion
IList<PolyfaceHeader> polyfaces = new List<PolyfaceHeader>();//声明多面体几何列表
FacetOptions facetOptions = new FacetOptions();//曲面属性,用于设置生成曲面或曲线弦的属性声明
facetOptions.SetDefaults();//属性设置为默认
PolyfaceProcessor polyfaceProcessor = new PolyfaceProcessor(ref polyfaces, facetOptions);//声明用于分解多面体几何的处理器
polyfaceProcessor.Process(solid); //将需要分解的元素输入处理器中
for (int i=0;i<polyfaces.Count;i++)//遍历元素中分解后的多面体几何
{
List<uint> colorIndex = new List<uint>();//声明颜色索引
foreach(DPoint3d po in polyfaces[i].Point)//为了获得该多面体几何的端点个数,对端点进行遍历
{
if(po.Z<5*uorPerMas)//Z坐标小于5为红色,否则则为蓝色
{
colorIndex.Add(0x00ff0000);//红色
}
else
{
colorIndex.Add(0x000000ff);//蓝色
}
//关于16进制颜色对照请参考:http://each.sinaapp.com/tools/color.html 格式为:0x00+(去掉#)16进制颜色
}
polyfaces[i].IntColor = colorIndex;//设置多面体几何的颜色索引值
polyfaces[i].ActivateVectorsForIndexing(polyfaces[i]);//设置为激活状态,以便携带所有的数据及索引信息
MeshHeaderElement meshElem = new MeshHeaderElement(dgnModel, null, polyfaces[i]);//使用修改后的多面体几何建立网格元素
TransformInfo trans = new TransformInfo(DTransform3d.FromTranslation(new DPoint3d(5*uorPerMas,0,0)));//声明变换信息
meshElem.ApplyTransform(trans);//对网格元素应用变换
meshElem.AddToModel();//将网格元素写入模型
}
}
在本案例中,首先创建了一个拉伸实体,然后从拉伸实体中获取到其对应的Polyface,然后对Polyface执行端点渐变填充的操作,最后使用Polyface创建出新的元素。
提取元素中曲线(CurveVector)
该方法主要用于对分解元素为CurveVector,它的优势在于无论是什么元素,只要元素中几何部分具有CurveVector,他就可以成功获取。
public static void BreakElementIntoCurves(string unparsed)//Case:BreakSolidExample
{
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获取当前的模型空间
double uorPerMas = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster;//分辨率单位转换为主单位
#region Create Solid
#region Create profile
DPoint3d p1 = new DPoint3d(-uorPerMas, uorPerMas, 0);//声明体元素端点
DPoint3d p2 = new DPoint3d(uorPerMas, uorPerMas, 0);
DPoint3d p3 = new DPoint3d(uorPerMas, -uorPerMas, 0);
DPoint3d p4 = new DPoint3d(-uorPerMas, -uorPerMas, 0);
DPoint3d[] pos = { p1, p2, p3, p4 };//将面元素端点添加到面元素端点数组中
ShapeElement shape = new ShapeElement(dgnModel, null, pos);//声明形元素
#endregion
DPoint3d origin = DPoint3d.Zero;//声明拉伸基点
DVector3d extrudeVector = new DVector3d(uorPerMas, uorPerMas, 10 * uorPerMas);//声明拉伸向量
SurfaceOrSolidElement solid = SurfaceOrSolidElement.CreateProjectionElement(dgnModel, null, shape, origin, extrudeVector, DTransform3d.Identity, true);//声明实体元素
solid.AddToModel();//将拉伸体写入模型
#endregion
IList<CurveVector> curves = new List<CurveVector>();//声明多面体几何列表
CurveProcessor curveProcessor = new CurveProcessor(ref curves);//声明用于分解曲线几何的处理器
curveProcessor.Process(solid); //将需要分解的元素输入处理器中
List<CurveVector> curvesList = new List<CurveVector>();//声明几何图元列表
for (int i = 0; i < curves.Count; i++)//遍历元素中分解后的曲线几何
{
Element subElem = DraftingElementSchema.ToElement(dgnModel, curves[i], null);//将几何转换成对应的元素
subElem.AddToModel();//将元素写入模型
if (subElem.ElementType==MSElementType.LineString)//判断转换后的元素是否为线串
{
ComplexShapeElement complexShape = new ComplexShapeElement(dgnModel,null);//声明复杂形元素(因为对于线串元素不一定为闭合,有可能无法围城封闭图形,故使用建立shape的形式闭合几何图形)
complexShape.AddComponentElement(subElem);//将线串元素添加到shape元素中
complexShape.AddComponentComplete();//添加元素完成
CurveVector shapeCurve = complexShape.GetCurveVector();//获得shape的封闭图形
CurveVector curveWithFillets = shapeCurve.CloneWithFillets(0.1 * uorPerMas);//对获得的几何图元做倒角处理
curvesList.Add(curveWithFillets);//将几何图元添加到列表中
}
}
BentleyStatus result = Create.BodyFromLoft(out SolidKernelEntity entityOut, curvesList.ToArray(), curvesList.Count, curvesList.ToArray(), 0, dgnModel, false, false);//声明扫掠体
Convert1.BodyToElement(out Element solidElem, entityOut, null, dgnModel);//将实体转换为元素
solidElem.AddToModel();//将元素写入模型空间
}
在本案例中,首先创建了一个拉伸实体,然后从拉伸实体中获取到其对应的CurveVector,然后对拉伸体上部轮廓线执行倒角处理,最后使用扫掠的方式基于修改后的线创建出新的元素。需要注意的是,要想使拉伸图形为封闭图形,则拉伸轮廓要求为封闭图形,而分解获取到的CurveVector得到的为LineString,导致拉伸实体无法闭合,因此在本案例中使用LineString创建ComplexShape,保证其为封闭图形,从而使实体成功闭合。
扫描使用方法介绍
若我们需要根据元素自身或工程属性进行遍历检索,随着模型中元素数量的增多往往会大幅度增加遍历所需要的时间。而扫描工具不仅可以规定扫描区域,也可以指定遍历元素的类型,从而将原本模型中的全部元素的检索变为指定区域,指定元素类型的检索,大幅度提高效率。
public static void FilterByScanCriteria(string unparsed)//Case:ScanCriteriaCase
{
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();//获得当前激活的模型
double uorPerMas = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster;//分辨率单位转换为主单位
ScanCriteria sc = new ScanCriteria();//声明扫描标准
sc.SetModelRef(dgnModel);//设置扫描目标模型
sc.SetModelSections(DgnModelSections.GraphicElements);//设置扫描部分(本案例中仅扫描图形元素)
BitMask elemTypeMask = new BitMask(false);//声明可变位数组
elemTypeMask.Capacity = 128;//设置数组容量
elemTypeMask.ClearAll();
// Element Type Number - 1 = BitMask Index
elemTypeMask.SetBit(18, true); // Element Type = Solid (Not SmartSolid), or (int)MSElementType.Solid - 1 设置筛选元素类型
sc.SetElementTypeTest(elemTypeMask);//将可变位数组应用于扫描标准
ScanRange range = new ScanRange((long)(99439.621 * uorPerMas), (long)(79738.341 * uorPerMas), 0, (long)(99701.215 * uorPerMas), (long)(79946.173 * uorPerMas), 0);//设置扫描范围
sc.SetRangeTest(range);//将扫描范围应用于扫描标准 注:若无范围要求不进行该项设置即可
string result = "The result of scan is:\n";//声明字符串
ScanDelegate scanDelegate = (Element elem, DgnModelRef modelRef) =>//声明扫描委托
{
//若扫描到符合条件的目标后执行的操作
result = result + "ElmentId = " + elem.ElementId + ", element type = " + elem.TypeName + '\n';
return StatusInt.Success;//返回成功
};
sc.Scan(scanDelegate);//执行扫描
MessageBox.Show(result);//将字符串结果输出到对话框
}
代码中首先声明了扫描标准,并设置扫描模型中图形元素,设置扫描元素类型及扫描区域后声明扫描委托,获得符合条件的元素。在本案例中,我们扫描的是图中Shape元素围城的区域,从最终的输出结果表明,扫描会在设置的范围框中针对元素属性条件为普通实体进行元素的过滤,最终获得指定区域内属性为普通实体的元素集合。