using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Electrical; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Plumbing; using Nice3point.Revit.Toolkit.External; namespace ShrlAlgoToolkit.RevitAddins.RvMEP; [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class CorrectMEPCurveSlopeCmd : ExternalCommand { public override void Execute() { var mepCurves = UiDocument.SelectObjectsByRectangle(); if (mepCurves == null) { return; } Document.Invoke(_ => { foreach (var mepCurve in mepCurves) { if (!IsErrorMEPCurve(mepCurve)) { continue; } var loc = mepCurve.Location as LocationCurve; var line = loc.Curve as Line; var endPoint = line.GetEndPoint(0); var endPoint1 = line.GetEndPoint(1); Line unboundLine; Line l; var xoy1 = endPoint.Flatten(); var xoy2 = endPoint1.Flatten(); var tan = Math.Abs(endPoint.Z - endPoint1.Z) / xoy1.DistanceTo(xoy2); var dir = -XYZ.BasisZ; if (endPoint.Z > endPoint1.Z)//以高点作为基准,修改低点 { if (tan > 1) { unboundLine = Line.CreateUnbound(endPoint, dir); var startPoint = unboundLine.Project(endPoint1).XYZPoint; l = Line.CreateBound(endPoint, startPoint); } else { dir = xoy2 - xoy1; unboundLine = Line.CreateUnbound(endPoint, dir); var startPoint = unboundLine.Project(endPoint1).XYZPoint; l = Line.CreateBound(endPoint, startPoint); } } else { if (tan > 1) { unboundLine = Line.CreateUnbound(endPoint1, dir); var startPoint = unboundLine.Project(endPoint).XYZPoint; l = Line.CreateBound(startPoint, endPoint1); } else { dir = xoy2 - xoy1; unboundLine = Line.CreateUnbound(endPoint1, dir); var startPoint = unboundLine.Project(endPoint).XYZPoint; l = Line.CreateBound(startPoint, endPoint1); } } loc.Curve = l; } }, "修正坡度"); } private void CorrectSlope() { var ids = UiDocument.Selection.GetElementIds(); Document.Invoke(_ => { foreach (var id in ids) { var elem = Document.GetElement(id); if (elem is MEPCurve mep) { var loc = mep.GetCurve() as Line; var x = Math.Round(loc.Direction.X); var y = Math.Round(loc.Direction.Y); var z = Math.Round(loc.Direction.Z); //if (Math.Abs(x) < 10E-5) //{ // x = 0; //} //if (Math.Abs(y) < 10E-5) //{ // y = 0; //} //if (Math.Abs(z) < 10E-5) //{ // z = 0; //} var dir = new XYZ(x, y, z); var endPoint = loc.Origin + dir * loc.Length; var li = Line.CreateBound(loc.Origin, endPoint); var locx = mep.GetLocationCurve(); locx.Curve = li; } } },"修正坡度"); } private void ModifyMEPCurve(MEPCurve mepCurve) { var loc = mepCurve.Location as LocationCurve; var line = loc.Curve as Line; var dir = line.Direction; var newDir = new XYZ(dir.X.Rounding(), dir.Y.Rounding(), dir.Z.Rounding()); var conns = mepCurve.ConnectorManager.Connectors.OfType().ToList(); //全部连接 var allConnector = conns.All(conn => conn.IsConnected); //全部未连接 var allNotConnector = conns.All(conn => !conn.IsConnected); Line newLine = null; if (allConnector || conns.ElementAt(0).IsConnected || allNotConnector) { var end = line.GetEndPoint(0) + newDir * line.Length; newLine = Line.CreateBound(line.GetEndPoint(0), end); } else { var start = line.GetEndPoint(1) - newDir * line.Length; newLine = Line.CreateBound(start, line.GetEndPoint(1)); } Document.Invoke( _ => { loc.Curve = newLine; }, "修正定位线"); } private static bool IsErrorMEPCurve(MEPCurve mepCurve) { var isError = false; switch (mepCurve) { case Pipe: { var param = mepCurve.get_Parameter(BuiltInParameter.RBS_PIPE_SLOPE); isError = param.HasValue && ((param.AsDouble() < 0.025 && param.AsDouble() > 0) || param.AsDouble() > 0.055); //坡度过大或过小时 break; } case Duct: { var param = mepCurve.get_Parameter(BuiltInParameter.RBS_DUCT_SLOPE); var loc = mepCurve.GetCurve() as Line; isError = param.HasValue && ((param.AsDouble() < 0.025 && param.AsDouble() > 0) || param.AsDouble() > 0.055); //坡度过大或过小时 break; } case Conduit or CableTray: { var p1 = mepCurve.get_Parameter(BuiltInParameter.RBS_START_OFFSET_PARAM).AsDouble(); var p2 = mepCurve.get_Parameter(BuiltInParameter.RBS_END_OFFSET_PARAM).AsDouble(); var l = mepCurve.get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH).AsDouble(); var sin = Math.Abs(p1 - p2) / l; var radian = Math.Asin(sin); var slope = Math.Tan(radian); isError = slope is (> 0 and < 0.025) or > 0.055; break; } } return isError; } }