diff --git a/AddinDeployer/CustomActionClass.cs b/AddinDeployer/CustomActionClass.cs index 8259212..f06d944 100644 --- a/AddinDeployer/CustomActionClass.cs +++ b/AddinDeployer/CustomActionClass.cs @@ -20,6 +20,7 @@ namespace AddinDeployer { //public static void Main(string[] args) //{ + // ProcessEvent(); //} private string path; @@ -32,7 +33,8 @@ namespace AddinDeployer { this.BeforeInstall += CustomActionClass_BeforeInstall; this.BeforeUninstall += CustomActionClass_BeforeUninstall; - this.AfterInstall += CustomActionClass_AfterInstall; + //this.AfterInstall += CustomActionClass_AfterInstall; + //this.AfterUninstall += CustomActionClass_AfterUninstall; } //private string revitvernum = "2020"; @@ -50,17 +52,17 @@ namespace AddinDeployer } catch (Win32Exception e) { - MessageBox.Show(e.Message.ToString()); // process was terminating or can't be terminated - deal with it + MessageBox.Show(e.Message.ToString()); } catch (InvalidOperationException e) { - MessageBox.Show(e.Message.ToString()); // process has already exited - might be able to let this one go + MessageBox.Show(e.Message.ToString()); } } } } - private void CustomActionClass_BeforeUninstall(object sender, InstallEventArgs e) + private static void CustomActionClass_BeforeUninstall(object sender, InstallEventArgs e) { KillProcess("REVIT"); @@ -84,9 +86,18 @@ namespace AddinDeployer //} } - private void CustomActionClass_BeforeInstall(object sender, InstallEventArgs e) + private static void CustomActionClass_BeforeInstall(object sender, InstallEventArgs e) { KillProcess("REVIT"); + try + { + var path = @"C:\ProgramData\Autodesk\Revit\Addins\2020"; + //DelAddinFromPath(path); + DeleteFolder(path + "\\RsTools"); + } + catch (Exception) + { + } //var dialogResult = System.Windows.Forms.MessageBox.Show("是否关闭Revit以安装插件", "提示", System.Windows.Forms.MessageBoxButtons.YesNo); diff --git a/RookieStation/Construction/ExecuteCmd/AutoGenerateModels.cs b/RookieStation/Construction/ExecuteCmd/AutoGenerateModels.cs new file mode 100644 index 0000000..f817177 --- /dev/null +++ b/RookieStation/Construction/ExecuteCmd/AutoGenerateModels.cs @@ -0,0 +1,478 @@ +using Autodesk.Revit.UI; +using Autodesk.Revit.DB; +using Autodesk.Revit.UI.Selection; +using System; +using RookieStation.Utils; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Collections.ObjectModel; +using Autodesk.Revit.DB.Architecture; +using System.Security.Cryptography; +using RookieStation.Construction.Views; +using System.Windows.Media.Media3D; + +namespace RookieStation.Construction.ExecuteCmd +{ + [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] + [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)] + internal class AutoGenerateModels : IExternalCommand + { + public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) + { + UIApplication uiapp = commandData.Application; + UIDocument uidoc = commandData.Application.ActiveUIDocument; + Document doc = uidoc.Document; + double length = 25000.0 / 304.8; + double width = 15000.0 / 304.8; + double interval = 10000 / 304.8; + WpfAutoModeling settings = CommonUtils.ShowDialog(); + if (settings.DialogResult == true) + { + length = settings.Length / 304.8; + width = settings.Width / 304.8; + } + else + { + return Result.Cancelled; + } + + var pointsCorner = new List(); + //边界 + IList edges = new List(); + + var p1 = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "请选择定位点"); + var p2 = p1.Add(width * XYZ.BasisY); + var p3 = p1.Add(new XYZ(length, width, 0)); + var p4 = p1.Add(length * XYZ.BasisX); + + pointsCorner.Add(p1); + pointsCorner.Add(p2); + pointsCorner.Add(p3); + pointsCorner.Add(p4); + + for (int i = 0; i <= 3; i++) + { + Line line = null; + if (i == 3) + { + line = Line.CreateBound(pointsCorner[i], pointsCorner[0]); + } + else + { + line = Line.CreateBound(pointsCorner[i], pointsCorner[i + 1]); + } + + edges.Add(line); + } + CurveLoop loop = CurveLoop.Create(edges); + try + { + doc.InvokeGroup(tg => + { + doc.Invoke(ts => + { + //边界组 + CreateFloor(doc, edges); + }); + doc.Invoke(ts => + { + CreateColumnAndFoundation(doc, edges, interval); + }, "创建基础和柱"); + doc.Invoke(ts => + { + CreateFramings(doc, edges, interval); + }, "创建地梁"); + doc.Invoke(ts => + { + var roof = CreateRoof(doc, loop, 125 / 304.8, 160 / 304.8); + + #region MyRegion + + //Options options = new Options(); + //options.ComputeReferences = true; + //var x = roof.get_Geometry(options); + //var gutterType = new FilteredElementCollector(doc).OfClass(typeof(GutterType)).OfCategory(BuiltInCategory.OST_Gutter).Cast().FirstOrDefault(); + //foreach (var item in x) + //{ + // if (item is Solid) + // { + // Solid solid = (Solid)item; + // var es = solid.Edges; + // var references = new ReferenceArray(); + + // foreach (Edge e in es) + // { + // var line = e.AsCurve() as Line; + // if (line != null) + + // //references.Append(e.Reference); + // try + // { + // doc.Create.NewGutter(gutterType, e.Reference); + // } + // catch (Exception) + // { + // continue; + // } + // } + // } + //} + + #endregion MyRegion + }, "创建屋面"); + doc.Invoke(ts => + { + CreateGutter(doc, loop, 100.0 / 304.8, 180 / 304.8); + }, "创建檐沟"); + doc.Invoke(ts => + { + CreateOuterWallList(doc, loop, 200 / 304.8); + }); + doc.Invoke(ts => + { + CreatePWallList(doc, loop, 400 / 304.8, 0.0); + }, "创建铝塑板"); + }, "自动创建模型"); + } + catch (Autodesk.Revit.Exceptions.OperationCanceledException) + { + return Result.Cancelled; + } + catch (Exception e) + { + throw; + //System.Windows.Forms.MessageBox.Show(e.InnerException.ToString()); + } + return Result.Succeeded; + } + + private static void CreateFloor(Document doc, IList edges) + { + var floorCurveArray = new CurveArray(); + for (int i = 0; i < edges.Count; i++) + { + floorCurveArray.Append(edges[i]); + } + doc.Create.NewFloor(floorCurveArray, true); + } + + /// + ///创建门头铝塑板 + /// + /// + /// + /// 水平向外偏移距离 + /// + private void CreatePWallList(Document doc, CurveLoop loop, double horizontalOffest, double verticalOffest) + { + var wallType = new FilteredElementCollector(doc).OfClass(typeof(WallType)).OfCategory(BuiltInCategory.OST_Walls).Cast().Where(w => w.Name.Contains("外墙 - 灰色铝塑板")).FirstOrDefault(); + //var wallType = new FilteredElementCollector(doc).OfClass(typeof(WallType)).OfCategory(BuiltInCategory.OST_Walls).Cast().Where(w => w.Name.Contains("铝合金玻璃幕墙")).FirstOrDefault(); + var wallSweepType = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Reveals).WhereElementIsElementType().Where(w => w.Name.Contains("3mm")).FirstOrDefault(); + var currentLevel = doc.ActiveView.GenLevel; + var topLevel = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).Cast().Where(l => l.Elevation > doc.ActiveView.GenLevel.Elevation).FirstOrDefault(); + + double heightOffest = topLevel.Elevation + verticalOffest; + var offestCurveLoop = CurveLoop.CreateViaOffset(loop, horizontalOffest, -XYZ.BasisZ); + Transform transform = Transform.CreateTranslation(XYZ.BasisZ * heightOffest); + var translateCurveLoop = CurveLoop.CreateViaTransform(offestCurveLoop, transform); + + var pheight = 1220 / 304.8; + foreach (var curve in translateCurveLoop) + { + Wall wall = null; + doc.InvokeSub(ts => + { + wall = Wall.Create(doc, curve, wallType.Id, topLevel.Id, pheight, 0, false, false); + }); + if (wall != null) + { + WallSweepInfo info = new WallSweepInfo(WallSweepType.Reveal, true) + { + WallOffset = 100 / 304.8, + Distance = 100 / 304.8, + WallSide = WallSide.Exterior, + DistanceMeasuredFrom = DistanceMeasuredFrom.Base, + }; + if (WallSweep.WallAllowsWallSweep(wall)) + { + var wallsweep = WallSweep.Create(wall, wallSweepType.Id, info); + } + } + } + } + + /// + /// 创建外墙 + /// + /// + /// + private void CreateOuterWallList(Document doc, CurveLoop loop, double horizontalOffest) + { + var offestCurve = CurveLoop.CreateViaOffset(loop, horizontalOffest, -XYZ.BasisZ); + var wallType = new FilteredElementCollector(doc).OfClass(typeof(WallType)).OfCategory(BuiltInCategory.OST_Walls).Cast().Where(w => w.Name.Contains("铝合金玻璃幕墙")).FirstOrDefault(); + var wallSweepType = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Reveals).WhereElementIsElementType().Where(w => w.Name.Contains("3mm")).FirstOrDefault(); + var topLevel = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).Cast().Where(l => l.Elevation > doc.ActiveView.GenLevel.Elevation).FirstOrDefault(); + var currentLevel = doc.ActiveView.GenLevel; + var height = topLevel.Elevation - currentLevel.Elevation; + foreach (var curve in offestCurve) + { + var wall = Wall.Create(doc, curve, wallType.Id, currentLevel.Id, height, 0, false, false); + } + } + + /// + ///创建檐沟 + /// + /// + /// 边界线 + /// 水平向外偏移距离 + /// 相对于当前视图标高以上的默认标高的偏移 + private void CreateGutter(Document doc, CurveLoop loop, double horizontalOffest, double verticalOffest) + { + ReferenceArray references = new ReferenceArray(); + var level = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).Cast().Where(l => l.Elevation > doc.ActiveView.GenLevel.Elevation).FirstOrDefault(); + double heightOffest = level.Elevation + verticalOffest; + var offestCurveLoop = CurveLoop.CreateViaOffset(loop, horizontalOffest, -XYZ.BasisZ); + Transform transform = Transform.CreateTranslation(XYZ.BasisZ * heightOffest); + var translateCurveLoop = CurveLoop.CreateViaTransform(offestCurveLoop, transform); + for (int i = 0; i < translateCurveLoop.Count(); i++) + { + var curve = translateCurveLoop.ElementAt(i); + var mc = doc.Create.NewModelCurve(curve, SketchPlane.Create(doc, Plane.CreateByNormalAndOrigin(XYZ.BasisZ, heightOffest * XYZ.BasisZ))); + references.Append(mc.GeometryCurve.Reference); + } + var gutterType = new FilteredElementCollector(doc).OfClass(typeof(GutterType)).OfCategory(BuiltInCategory.OST_Gutter).Cast().FirstOrDefault(); + var gutters = doc.Create.NewGutter(gutterType, references); + if (!gutters.HorizontalFlipped) + { + gutters.HorizontalFlip(); + } + } + + private static void NewMethod1(UIDocument uidoc) + { + double length = 50000.0 / 304.8; + double width = 30000.0 / 304.8; + double intervalColumn = 10000 / 304.8; + var p1 = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "请选择定位点"); + //NewMethod2(uidoc, length, width); + var m = Math.Floor(length / intervalColumn) + 2; + List ls = new List(); + for (int i = 0; i < m; i++) + { + var pl = i / (m - 1) * length * XYZ.BasisX + p1; + var pw = i / (m - 1) * length * XYZ.BasisX + p1 + width * XYZ.BasisY; + Line line = Line.CreateBound(pl, pw); + ls.Add(line); + } + } + + /// + /// 创建屋顶 + /// + /// + /// + /// 屋顶相对于轮廓向外水平偏移 + /// 相对当前标高以上默认标高的偏移 + /// + public FootPrintRoof CreateRoof(Document doc, CurveLoop loop, double horizontalOffest, double verticalOffest) + { + var roofType = new FilteredElementCollector(doc).OfClass(typeof(RoofType)).OfCategory(BuiltInCategory.OST_Roofs).Cast().Where(symbol => symbol.Name.Contains("彩钢板")).FirstOrDefault(); + var level = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).Cast().Where(l => l.Elevation > doc.ActiveView.GenLevel.Elevation).FirstOrDefault(); + + var roofCurveArray = new CurveArray(); + var offestCurve = CurveLoop.CreateViaOffset(loop, horizontalOffest, -XYZ.BasisZ); + for (int i = 0; i < offestCurve.Count(); i++) + { + roofCurveArray.Append(offestCurve.ElementAt(i)); + } + + ModelCurveArray modelCurveArray = new ModelCurveArray(); + FootPrintRoof roof = doc.Create.NewFootPrintRoof(roofCurveArray, level, roofType, out modelCurveArray); + var line1 = modelCurveArray.get_Item(1); + var line2 = modelCurveArray.get_Item(3); + roof.set_DefinesSlope(line1, true); + roof.set_SlopeAngle(line1, 0.2); + roof.set_DefinesSlope(line2, true); + roof.set_SlopeAngle(line2, 0.2); + roof.get_Parameter(BuiltInParameter.ROOF_LEVEL_OFFSET_PARAM).Set(verticalOffest); + return roof; + } + + /// + ///创建梁 + /// + /// + /// + /// + private void CreateFramings(Document doc, IList edges, double interval) + { + List> pointsOnLines = new List>(); + var lines = CreateGridLine(interval, edges); + foreach (Line c in lines) + { + List pointsOnLine = new List(); + var m = (int)Math.Floor(c.Length / interval); + for (int i = 1; i <= m; i++) + { + var p = c.Evaluate(i / (m + 1.0), true); + pointsOnLine.Add(p); + } + pointsOnLine.Add(c.GetEndPoint(0)); + pointsOnLine.Add(c.GetEndPoint(1)); + pointsOnLines.Add(pointsOnLine); + } + var frameSymbol = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralFraming).Cast().Where(s => s.Name.Contains("250*500")).FirstOrDefault(); + if (!frameSymbol.IsActive) + { + frameSymbol.Activate(); + } + foreach (var pointsOnLine in pointsOnLines) + { + for (int i = 0; i < pointsOnLine.Count - 1; i++) + { + Line line = Line.CreateBound(pointsOnLine[i], pointsOnLine[i + 1]); + doc.Create.NewFamilyInstance(line, frameSymbol, doc.ActiveView.GenLevel, Autodesk.Revit.DB.Structure.StructuralType.Beam); + } + } + } + + /// + ///创建柱和基础 + /// + /// + /// 边界 + /// 间距 + private void CreateColumnAndFoundation(Document doc, IList edges, double interval) + { + List pointColumnFoundation = new List(); + var columnSymbol = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralColumns).Cast().Where(cs => cs.FamilyName.Contains("方形")).FirstOrDefault(); + var foundationSymbol = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_StructuralFoundation).Cast().FirstOrDefault(); + if (!columnSymbol.IsActive) + { + columnSymbol.Activate(); + } + if (!foundationSymbol.IsActive) + { + foundationSymbol.Activate(); + } + + var lines = CreateGridLine(interval, edges).Cast().Where(l => l.Direction.Normalize().IsAlmostEqualTo(XYZ.BasisY) || l.Direction.Normalize().IsAlmostEqualTo(-XYZ.BasisY)); + //var lines = CreateGridLine(intervalColumn, curves).Where(l => l.Direction.Normalize().IsAlmostEqualTo(XYZ.BasisX) || l.Direction.Normalize().IsAlmostEqualTo(-XYZ.BasisX)); + //var lines = CreateGridLine(intervalColumn, curves); + //foreach (var l in lines) + //{ + // doc.Create.NewModelCurve(l, SketchPlane.Create(doc, Plane.CreateByNormalAndOrigin(XYZ.BasisZ, XYZ.Zero))); + //} + foreach (Line c in lines) + { + var m = (int)Math.Floor(c.Length / interval); + for (int i = 1; i <= m; i++) + { + var p = c.Evaluate(i / (m + 1.0), true); + pointColumnFoundation.Add(p); + } + pointColumnFoundation.Add(c.GetEndPoint(0)); + pointColumnFoundation.Add(c.GetEndPoint(1)); + } + foreach (var p in pointColumnFoundation) + { + doc.Create.NewFamilyInstance(p, columnSymbol, doc.ActiveView.GenLevel, Autodesk.Revit.DB.Structure.StructuralType.Column); + } + foreach (var p in pointColumnFoundation) + { + var pt = p - XYZ.BasisZ * 450 / 304.8; + doc.Create.NewFamilyInstance(pt, foundationSymbol, doc.ActiveView.GenLevel, Autodesk.Revit.DB.Structure.StructuralType.Footing); + } + } + + /// + /// 创建网格线 + /// + /// + /// + /// + private List CreateGridLine(double maxCellSize, IList edges) + { + var pointsOnLines = new List>(); + var gridLines = new List(); + gridLines.AddRange(edges); + //将边界线按跨数分割, + foreach (Curve c in edges) + { + pointsOnLines.Add(PointsOnCurve(c, maxCellSize)); + } + if (pointsOnLines.Count == 2) + { + var li1 = pointsOnLines[0];//水平下 + var li2 = pointsOnLines[1];//水平上 + for (int i = 0; i < li1.Count; i++) + { + var line = Line.CreateBound(li1[i], li2[i]); + gridLines.Add(line); + } + } + else if (pointsOnLines.Count == 4) + { + var li1 = pointsOnLines[0];//水平下 + var li3 = pointsOnLines[2];//水平上 + var li2 = pointsOnLines[1];//垂直右 + var li4 = pointsOnLines[3];//垂直左 + for (int i = 0; i < li1.Count; i++) + { + var line = Line.CreateBound(li1[i], li3[i]); + gridLines.Add(line); + } + for (int i = 0; i < li2.Count; i++) + { + var line = Line.CreateBound(li2[i], li4[i]); + gridLines.Add(line); + } + } + + return gridLines; + } + + private List PointsOnCurve(Curve c, double maxCellSize) + { + List ordered = new List(); + var m = (int)Math.Floor(c.Length / maxCellSize); + if (m > 0) + { + List pts = new List(); + for (int i = 1; i <= m; i++) + { + var p = c.Evaluate(i / (m + 1.0), true); + pts.Add(p); + } + ordered = pts.OrderBy(p => p.X).ThenBy(p => p.Y).ToList(); + } + return ordered; + } + + private int GetSegmentCount(Curve curve) + { + double interval = 10000 / 304.8; + double l = curve.Length; + if (l < interval) + { + return 1; + } + else if (l >= interval && l < 2 * interval) + { + return 2; + } + else if (l >= 2 * interval && l < 3 * interval) + { + return 3; + } + else + { + return 0; + } + } + } +} \ No newline at end of file diff --git a/RookieStation/Construction/Views/WpfAutoModeling.xaml b/RookieStation/Construction/Views/WpfAutoModeling.xaml new file mode 100644 index 0000000..4ee44b8 --- /dev/null +++ b/RookieStation/Construction/Views/WpfAutoModeling.xaml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + +