using System.Diagnostics; using ACadSharp.Entities; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.UI.Selection; using Nice3point.Revit.Toolkit.External; namespace Sai.RvKits.RvCommon; [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class ModifyModelParams : ExternalCommand { public override void Execute() { var elems = UiDocument.SelectObjects(); if (elems == null) { return; } var textRefer = UiDocument.Selection.PickObject(ObjectType.PointOnElement, "请选择管线标注文字"); var dwg = Document.GetElement(textRefer) as ImportInstance; var textLayerName = dwg.GetLayerName(textRefer); var path = dwg.GetDwgPath(); var dwgTransform = dwg!.GetTransform(); Document.Invoke(_ => { using ACadSharp.IO.DwgReader reader = new(path); var cadDocument = reader.Read(); var textEntities = cadDocument.Entities.OfType().Where(e => e.Layer.Name == textLayerName).ToList(); double topOffset = default; double bottomOffset = default; foreach (var familyInstance in elems) { string str1 = default; string str2 = default; //XYZ p1 = default; //XYZ p2 = default; var loc = familyInstance.GetLocXYZ(); var smallest = double.MaxValue; var secondSmallest = double.MaxValue; foreach (var entity in textEntities) { if (!double.TryParse(entity.Value, out var _)) { continue; } var xyz = new XYZ(entity.InsertPoint.X, entity.InsertPoint.Y, entity.InsertPoint.Z) / 304.8; var ofPoint = dwgTransform.OfPoint(xyz); //同一平面 var point = new XYZ(ofPoint.X, ofPoint.Y, loc.Z); var temp = point.DistanceTo(loc); if (temp < smallest) { str2 = str1; str1 = entity.Value; //p2 = p1; //p1 = point; secondSmallest = smallest; smallest = temp; } else if (temp < secondSmallest) { //p2 = point; str2 = entity.Value; secondSmallest = temp; } } var b1 = double.TryParse(str1, out var d1); var b2 = double.TryParse(str2, out var d2); if (b1 && b2) { if (d1 > d2) { topOffset = d1; bottomOffset = d2; } else { topOffset = d2; bottomOffset = d1; } } //Debug.WriteLine(topOffset * 1000 / 304.8); //Debug.WriteLine(bottomOffset * 1000 / 304.8); if ((topOffset - bottomOffset) * 1000 / 304.8 < Application.ShortCurveTolerance) { Debug.WriteLine(familyInstance.Id); } else { familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(topOffset * 1000 / 304.8); familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(bottomOffset * 1000 / 304.8); } } }); } }