using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using Bentley.DgnPlatformNET; using Bentley.DgnPlatformNET.DgnEC; using Bentley.DgnPlatformNET.Elements; using Bentley.ECObjects.Instance; using Bentley.ECObjects.Schema; using Bentley.MstnPlatformNET; namespace ZYJSCSMsAddins { /// /// 专业技术措施,面积:平方米,体积:立方米,长度:米,个数:个 /// /// var models = ZYJSCSHelpers.GetDataByLevelName("JG_ZYJSCS"); public class ZYJSCSHelpers { /// /// 获取元素的图层,如果是一般单元,则按第一个子元素来获取 /// /// /// private static LevelHandle GetLevel(Element element) { ElementPropertiesGetter getter = new ElementPropertiesGetter(element); var lvlcache = Session.Instance.GetActiveDgnFile().GetLevelCache(); //一般单元 if (element.GetChildren().Count() > 0) { foreach (var elem in element.GetChildren()) { if (elem is DisplayableElement && !elem.IsInvisible) { return GetLevel(elem); } } } return lvlcache.GetLevel(getter.Level, true); } /// /// 按图层获取数据 /// /// /// 数据集合 public static List GetDataByLevelName(string levelName) { //获取当前激活的模型 DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); //获取图层 var layer = dgnModel.GetLevelCache().GetLevelByName(levelName); if (layer == null) { Debug.WriteLine("图层为空"); return new List(); } //拿到图层上的元素 var groups = dgnModel.GetGraphicElements() .Where(e => e.LevelId == layer.LevelId || GetLevel(e).LevelId == layer.LevelId) .GroupBy(e => GetJSCSPropertyValue(e, "ID-100-名称")?.ToString()); List models = new List(); foreach (var group in groups) { var li = group.ToList(); var first = GetJSCSPropertyValue(li.FirstOrDefault(), "ID-100-计量方式")?.ToString(); //计量方式都一致 //var b = li.TrueForAll(e => GetJSCSPropertyValue(e, "ID-100-计量方式") == first); JSCSModel model = new JSCSModel(first, li); models.Add(model); } return models; } /// /// 通过属性名获取钢筋的属性值 /// /// 元素 /// 属性名 /// 属性值,可根据情况进行转换数据类型 public static object GetJSCSPropertyValue(Element elem, string propName) { var instances = new CustomItemHost(elem, false).CustomItems; object value = default; foreach (var instance in instances) { if (instance.ClassDefinition.DisplayLabel == "专业技术措施" && instance.ContainsValues) { foreach (var propValue in instance) { if (propValue.Property.DisplayLabel == propName && propValue.TryGetNativeValue(out value)) { break; } } } } return value; } /// /// 获取元素的长度 /// /// 元素 /// 长度值,单位m public static double GetLength(Element elem) { var uorMeter = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter; double length = default; if (elem is LineElement line) { length = line.GetCurveVector().SumOfLengths(); } if (elem is ComplexStringElement complexString) { length = complexString.GetCurveVector().SumOfLengths(); } if (elem is LineStringBaseElement lineStringBase) { length = lineStringBase.GetCurveVector().SumOfLengths(); } if (elem is EllipseElement ellipseElement) { length = ellipseElement.GetCurveVector().SumOfLengths(); } if (elem is ComplexShapeElement complexShape) { length = complexShape.GetCurveVector().SumOfLengths(); } if (elem is BSplineCurveElement bSplineCurve) { length = bSplineCurve.GetCurveVector().SumOfLengths(); } return length / uorMeter; } /// /// 获取属性 /// /// public static List GetProperties(Element element, string propName) { if (null == element) { throw new ArgumentNullException(nameof(element), "所提供ElemId无效"); } List eCProperties = new List(); DgnECManager ecManager = DgnECManager.Manager; int count = 0; DgnECInstanceCollection instCol = ecManager.GetElementProperties(element, ECQueryProcessFlags.SearchAllClasses); foreach (IDgnECInstance inst in instCol) { count++; IEnumerator propertyEnum = inst.ClassDefinition.GetEnumerator(); while (propertyEnum.MoveNext()) { IECPropertyValue propertyValue = inst.GetPropertyValue(propertyEnum.Current.Name); if (propertyValue.IsArray) { IECArrayValue arrayVal = propertyValue as IECArrayValue; if (arrayVal.Count >= 1) propertyValue = arrayVal[0]; } var prop = propertyEnum.Current.Name; ECNameValidation.DecodeFromValidName(ref prop); if (propName == prop) { eCProperties.Add(propertyValue); } } } return eCProperties; } } public class JSCSModel { private readonly double uorMeter = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter; public JSCSModel(string measure, List elements) { Measurement = GetMeasurement(measure); AssociateElements = elements; Name = ZYJSCSHelpers.GetJSCSPropertyValue(elements.FirstOrDefault(), "ID-100-名称")?.ToString(); } public StringBuilder Message { get; private set; } private double GetArea() { //StringBuilder sb = new StringBuilder(); double area = default; foreach (var elem in AssociateElements) { var prop = ZYJSCSHelpers.GetProperties(elem, "SurfaceArea").FirstOrDefault(); if (prop != null) { prop.TryGetNativeValue(out var value); double d = Convert.ToDouble(value) / (uorMeter * uorMeter); //sb.AppendLine($"父元素{elem.ElementId}:{elem.Description};面积:{d}"); area += d; } if (elem is CellHeaderElement cellElem) { foreach (var child in cellElem.GetChildren()) { var childProp = ZYJSCSHelpers.GetProperties(child, "SurfaceArea").FirstOrDefault(); if (childProp != null) { childProp.TryGetNativeValue(out var value); double d = Convert.ToDouble(value) / (uorMeter * uorMeter); //sb.AppendLine($"父元素{elem.ElementId}:{elem.Description}中的子元素{child.ElementId}:{child.Description};面积:{d}"); area += d; } } } if (elem is SharedCellElement sharedCell) { var definition = sharedCell.GetDefinition(Session.Instance.GetActiveDgnFile()); foreach (var child in definition.GetChildren()) { var childProp = ZYJSCSHelpers.GetProperties(child, "SurfaceArea").FirstOrDefault(); if (childProp != null) { childProp.TryGetNativeValue(out var value); double d = Convert.ToDouble(value) / (uorMeter * uorMeter); //sb.AppendLine($"父元素{elem.ElementId}:{elem.Description}中的子元素{child.ElementId}:{child.Description};面积:{d}"); area += d; } } } } //Message = sb; return Math.Round(area, 3, MidpointRounding.AwayFromZero); } private double GetLength() { double length = default; //StringBuilder sb = new StringBuilder(); foreach (var elem in AssociateElements) { //sb.AppendLine($"父元素{elem.ElementId}:{elem.Description};长度:{ZYJSCSHelpers.GetLength(elem)}"); length += ZYJSCSHelpers.GetLength(elem); } //Message = sb; return Math.Round(length, 3, MidpointRounding.AwayFromZero); } private Measurement GetMeasurement(string measure) { if (string.IsNullOrEmpty(measure)) { return Measurement.Unknow; } if (measure == "个数" || measure == "个" || measure == "数量") { return Measurement.Count; } else if (measure == "长度" || measure == "长" || measure == "毫米" || measure == "米" || measure == "厘米") { return Measurement.Length; } else if (measure == "面积" || measure.StartsWith("平方")) { return Measurement.Area; } else if (measure == "体积" || measure.StartsWith("立方")) { return Measurement.Volume; } return Measurement.Unknow; } private double GetVolume() { double volume = default; //StringBuilder sb = new StringBuilder(); foreach (var elem in AssociateElements) { //直接可以读取 var prop = ZYJSCSHelpers.GetProperties(elem, "Volume").FirstOrDefault(); if (prop != null) { prop.TryGetNativeValue(out var value); double d = Convert.ToDouble(value) / (uorMeter * uorMeter * uorMeter); //sb.AppendLine($"父元素{elem.ElementId}:{elem.Description};体积:{d}"); volume += d; } //一般单元,能看到子元素 if (elem.GetChildren().Count() > 0) { foreach (var child in elem.GetChildren()) { var childProp = ZYJSCSHelpers.GetProperties(child, "Volume").FirstOrDefault(); if (childProp != null) { childProp.TryGetNativeValue(out var value); double d = Convert.ToDouble(value) / (uorMeter * uorMeter * uorMeter); //sb.AppendLine($"父元素{elem.ElementId}:{elem.Description}中的子元素{child.ElementId}:{child.Description};体积:{d}"); volume += d; } } } //共享单元看不到子元素 if (elem is SharedCellElement sharedCell) { //var definition = sharedCell.GetDefinition(Session.Instance.GetActiveDgnFile()); DropGeometry geom = new DropGeometry(); geom.SetOptions(DropGeometry.Options.OPTION_SharedCells); geom.SetSharedCellOptions(DropGeometry.SharedCells.SHAREDCELL_Geometry); var status = MstnMixedAssistant.ElementOperation.DropElement(sharedCell, out var agenda, geom); if (status == StatusInt.Success) { for (uint i = 0; i < agenda.GetCount(); i++) { var child = agenda.GetEntry(i); var childProp = ZYJSCSHelpers.GetProperties(child, "Volume").FirstOrDefault(); //第一次打散后,但是还是找不到体积属性,需要二次打散 if (childProp == null) { DropGeometry geomSub = new DropGeometry(); geomSub.SetOptions(DropGeometry.Options.OPTION_AppData); geomSub.SetSolidsOptions(DropGeometry.Solids.SOLID_Surfaces); var statusSub = MstnMixedAssistant.ElementOperation.DropElement(child, out var agendaSub, geomSub); if (statusSub == StatusInt.Success) { for (uint j = 0; j < agendaSub.GetCount(); j++) { var childSub = agendaSub.GetEntry(j); var childPropSub = ZYJSCSHelpers.GetProperties(childSub, "Volume").FirstOrDefault(); if (childPropSub != null) { childPropSub.TryGetNativeValue(out var valueSub); var d = Convert.ToDouble(valueSub) / (uorMeter * uorMeter * uorMeter); volume += d; } } } } else { childProp.TryGetNativeValue(out var value); double d = Convert.ToDouble(value) / (uorMeter * uorMeter * uorMeter); //sb.AppendLine($"父元素{elem.ElementId}:{elem.Description}中的子元素{child.ElementId}:{child.Description};体积:{d}"); volume += d; } } } } } //Message = sb; return Math.Round(volume, 3, MidpointRounding.AwayFromZero); } //private int GetCount() //{ // StringBuilder sb = new StringBuilder(); // foreach (var elem in AssociateElements) // { // sb.AppendLine($"父元素{elem.ElementId}:{elem.Description};个数:1"); // } // Message = sb; // return 1; //} public List AssociateElements { get; } /// /// 计量方式 /// public Measurement Measurement { get; private set; } public string Unit { get; private set; } public string Name { get; } public double Result { get { double result = 0.0; switch (Measurement) { case Measurement.Count: result = AssociateElements.Count; //result = GetCount(); break; case Measurement.Length: result = GetLength(); Unit = "m"; break; case Measurement.Area: result = GetArea(); Unit = "㎡"; break; case Measurement.Volume: result = GetVolume(); Unit = "m³"; break; case Measurement.Unknow: break; } return result; } } } /// /// 计量方式 /// public enum Measurement { Unknow, /// /// 个数 /// Count, /// /// 长度 /// Length, /// /// 面积 /// Area, /// /// 体积 /// Volume } }