zoukankan      html  css  js  c++  java
  • 简单得Revit二次开发-波导线拆分

    波导线拆分(基于Revit2019 API)

    `using Autodesk.Revit.Attributes;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI;
    using Autodesk.Revit.UI.Selection;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.Windows.Forms;
    using Form = System.Windows.Forms.Form;

    namespace Boundary
    {
    [Transaction(TransactionMode.Manual)]
    public class LoopBoundary : IExternalCommand
    {
    private UIDocument uidoc;
    private Document currentDocument;
    private Material currentMat;
    private PartMaker partMaker;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            uidoc = commandData.Application.ActiveUIDocument;
            currentDocument = uidoc.Document;
            partMaker = null;
            currentMat = null;
            message =
            Trans("boundary",
                          () =>
                          {
                              var frm = new DataInput(GetMaterials());
                              var dr = frm.ShowDialog();
                              if (dr != System.Windows.Forms.DialogResult.OK) return null;
                              currentMat = frm.Material;
                              var floor = GetFloor();
                              if (floor == null) return null;
                              var face = GetFace(floor);
                              if (face == null) return "获取 波导线错误";
    
                              if (!PartUtils.AreElementsValidForCreateParts(currentDocument, new[] { floor.Id }))
                                  return "无法为对象创建零件";
                              PartUtils.CreateParts(currentDocument, new[] { floor.Id });
                              currentDocument.Regenerate();
    
                              var parts = PartUtils.GetAssociatedParts(currentDocument, floor.Id, false, false);
                              if (!PartUtils.ArePartsValidForDivide(currentDocument, parts))
                                  return "无法为对象拆分零件";
    
                              //拆分线 
                              var cvs = GetCurves(face, MmToFt(frm.Length));
    
                              //拆分平面
                              var p = Plane.CreateByNormalAndOrigin(face.FaceNormal, face.Origin);
                              var sp = SketchPlane.Create(currentDocument, p);
                             
                              partMaker = PartUtils.DivideParts(
                                    currentDocument,
                                    parts,
                                    new List<ElementId>(0),
                                    cvs,
                                    sp.Id);
                        
                              currentDocument.ActiveView.PartsVisibility = PartsVisibility.ShowPartsOnly;
                              return null;
    
                          });
    
            if (!string.IsNullOrEmpty(message)) return Result.Failed;
    
            SetPartsMat(partMaker);
    
            return Result.Succeeded;
        }
    
        private void SetPartsMat(PartMaker pk)
        {
            var filter = new ElementClassFilter(typeof(Part));
            var parts = new FilteredElementCollector(currentDocument)
                 .WherePasses(filter)
                 .OfType<Part>();
    
            foreach (var part in parts)
            {
                if (part.PartMaker.Id != pk.Id) continue;
                SetPartMatNoReadOnly(part);
                SetPartMat(part);
            }
    
        }
    
        private void SetPartMatNoReadOnly(Part part)
        {
            var original = part.get_Parameter(BuiltInParameter.DPART_MATERIAL_BY_ORIGINAL);
            if (!original.IsReadOnly)
                Trans("original", () => { original.Set(0); });
        }
    
        private void SetPartMat(Part part)
        {
            var mat = part.get_Parameter(BuiltInParameter.DPART_MATERIAL_ID_PARAM);
            if (!mat.IsReadOnly)
                Trans("mat set", () => { mat.Set(currentMat.Id); });
        }
    
    
        private XYZ PointProjectLine(XYZ pt, Line line)
        {
            line.MakeUnbound();
            return line.Project(pt).XYZPoint;
        }
    
    
        private string Trans(string tranName, Func<string> func)
        {
            var r = "";
            var trn = new Transaction(currentDocument, tranName);
            using (trn)
            {
                trn.Start();
                r = func();
                trn.Commit();
            }
            return r;
        }
    
        private void Trans(string tranName, Action action)
        {
            var trn = new Transaction(currentDocument, tranName);
            using (trn)
            {
                trn.Start();
                action();
                trn.Commit();
            }
        }
    
        private List<Material> GetMaterials()
        {
            var filterByMaterial = new ElementCategoryFilter(BuiltInCategory.OST_Materials);
            var col = new FilteredElementCollector(currentDocument);
            var mats = col.WherePasses(filterByMaterial)
                .OfType<Material>()
                .ToList();
            if (mats.Count > 0)
            {
                return mats;
            }
            throw new ArgumentNullException("无法获取材质!");
        }
    
        private Floor GetFloor()
        {
            try
            {
                var fid = uidoc.Selection.PickObject(ObjectType.Element, new FloorSelectionFilter());
                var floor = currentDocument.GetElement(fid.ElementId) as Floor;
    
                return floor;
            }
            catch
            {
                return null;
            }
        }
    
        private PlanarFace GetFace(Floor floor)
        {
            var refer = HostObjectUtils.GetTopFaces(floor).FirstOrDefault();
            var planer = floor.GetGeometryObjectFromReference(refer) as PlanarFace;
    
            return planer;
    		}
    
        private double MmToFt(double mm)
        {
            return UnitUtils.Convert(mm, DisplayUnitType.DUT_MILLIMETERS, DisplayUnitType.DUT_DECIMAL_FEET);
        }
    
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="floor"></param>
        public List<Curve> GetCurves(PlanarFace planer, double divLen)
        {
            var pts = planer.Triangulate().Vertices;
            foreach (XYZ pt in pts)
            {
                Debug.Print(@"{0},{1}", pt.X, pt.Y);
            }
            var pts1 = pts.Take(pts.Count / 2);
            var pts2 = pts.Skip(pts.Count / 2).Reverse();
            var lst2 = pts2.ToList();
            var lst1 = pts1.ToList();
    
            var last = pts2.Last();
            lst2.Insert(0, last);
            lst2.RemoveAt(lst2.Count - 1);
            last = lst2.Last();
            lst2.Insert(0, last);
            lst2.RemoveAt(lst2.Count - 1);
    
            var outs = OrderXyzListByBottomLeft(lst1);
            var inners = OrderXyzListByBottomLeft(lst2);
            var loops = FenChai(inners, outs, divLen);
    		
            return Combine(loops, pts);
        }
    
        private List<XYZ> OrderXyzListByBottomLeft(List<XYZ> pts)
        {
            var r = new List<XYZ>();
            Debug.Print("OrderXyzList");
            var minY = pts.Min(p => p.Y);
            var minX = pts.Where(p => p.Y == minY).Min(pt => pt.X);
            var index = pts.FindIndex(p => p.X == minX && p.Y == minY);
            r = pts.Skip(index).ToList();
            r.AddRange(pts.Take(index));
            return r;
        }
    
        private List<List<XYZ>> FenChai(List<XYZ> inners, List<XYZ> outers, double divlen)
        {
            var r_inner = new List<XYZ>();
            var r_out = new List<XYZ>();
            inners.Add(inners.First());
            outers.Add(outers.First());
            for (int i = 0; i < inners.Count - 1; i++)
            {
                var p1 = inners[i];
                var p2 = inners[i + 1];
                var outp1 = outers[i];
                var outp2 = outers[i + 1];
    
                var line_in = Line.CreateBound(p1, p2);
                var line_out = Line.CreateBound(outp1, outp2);
    
                var direction_in = line_in.Direction;
                var direction_out = line_out.Direction;
    
                var half = line_in.Length / 2.0;
                var count = (int)(half / divlen);
                count = count * 2;
                var rem_in = half % divlen;
    
                r_inner.Add(p1);
                r_out.Add(outp1);
                if (rem_in > 1e-9)
                {
                    var pt = p1 + direction_in * rem_in;
                    r_inner.Add(pt);
                    r_out.Add(PointProjectLine(pt, line_out));
                }
    
                for (int j = 0; j < count; j++)
                {
                    var pt = p1 + direction_in * (rem_in + (j + 1) * divlen);
                    r_inner.Add(pt);
                    r_out.Add(PointProjectLine(pt, line_out));
                }
            }
    
            r_inner.Add(inners.First());
            r_out.Add(outers.First());
            return new List<List<XYZ>> { r_inner, r_out };
        }
    
        private List<Curve> Combine(List<List<XYZ>> loops, IList<XYZ> pts)
        {
    
            var r = new List<Curve>();
            foreach (var loop in loops)
            {
                for (int i = 0; i < loop.Count - 1; i++)
                {
                    r.Add(Line.CreateBound(loop[i], loop[i + 1]));
                }
            }
    
            var loop1 = loops[0];
            var loop2 = loops[1];
            for (int i = 0; i < loop1.Count - 1; i++)
            {
                if (pts.Contains(loop1[i])) continue;
                r.Add(Line.CreateBound(loop1[i], loop2[i]));
            }
    
            return r;
        }
    
      
    
     
    
        public class FloorSelectionFilter : ISelectionFilter
        {
            public bool AllowElement(Element element)
            {
                if (element.Category == null) return false;
                if (element.Category.Id.IntegerValue != (int)BuiltInCategory.OST_Floors)
                    return false;
    
                var floor = element as Floor;
                if (floor == null) return false;
    
                var openings = floor.GetDependentElements(new ElementClassFilter(typeof(Opening)));
    
                return openings.Count > 0;
            }
    
    
            public bool AllowReference(Reference reference, XYZ position)
                => false;
    
        }
    
        public class DataInput : Form
        {
    
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.length_lab = new System.Windows.Forms.Label();
                this.mat_lab = new System.Windows.Forms.Label();
                this.btn_pickFloor = new System.Windows.Forms.Button();
                this.btn_cancel = new System.Windows.Forms.Button();
                this.textBox1 = new System.Windows.Forms.TextBox();
                this.cbox_mats = new System.Windows.Forms.ComboBox();
                this.SuspendLayout();
                // 
                // length_lab
                // 
                this.length_lab.AutoSize = true;
                this.length_lab.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.length_lab.Location = new System.Drawing.Point(19, 39);
                this.length_lab.Name = "length_lab";
                this.length_lab.Size = new System.Drawing.Size(147, 14);
                this.length_lab.TabIndex = 0;
                this.length_lab.Text = "指定波导线长度(mm):";
                // 
                // mat_lab
                // 
                this.mat_lab.AutoSize = true;
                this.mat_lab.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.mat_lab.Location = new System.Drawing.Point(43, 96);
                this.mat_lab.Name = "mat_lab";
                this.mat_lab.Size = new System.Drawing.Size(119, 14);
                this.mat_lab.TabIndex = 0;
                this.mat_lab.Text = "选择波导线材质:";
                // 
                // btn_pickFloor
                // 
                this.btn_pickFloor.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.btn_pickFloor.Location = new System.Drawing.Point(146, 191);
                this.btn_pickFloor.Name = "btn_pickFloor";
                this.btn_pickFloor.Size = new System.Drawing.Size(108, 37);
                this.btn_pickFloor.TabIndex = 1;
                this.btn_pickFloor.Text = "选择楼板";
                this.btn_pickFloor.UseVisualStyleBackColor = true;
                this.btn_pickFloor.Click += new System.EventHandler(this.btn_pickFloor_Click);
                // 
                // btn_cancel
                // 
                this.btn_cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
                this.btn_cancel.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.btn_cancel.Location = new System.Drawing.Point(271, 191);
                this.btn_cancel.Name = "btn_cancel";
                this.btn_cancel.Size = new System.Drawing.Size(75, 37);
                this.btn_cancel.TabIndex = 1;
                this.btn_cancel.Text = "取消";
                this.btn_cancel.UseVisualStyleBackColor = true;
                // 
                // textBox1
                // 
                this.textBox1.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.textBox1.Location = new System.Drawing.Point(166, 36);
                this.textBox1.Name = "textBox1";
                this.textBox1.Size = new System.Drawing.Size(180, 23);
                this.textBox1.TabIndex = 2;
                this.textBox1.Text = "500";
                this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
                // 
                // cbox_mats
                // 
                this.cbox_mats.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
                this.cbox_mats.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.cbox_mats.FormattingEnabled = true;
                this.cbox_mats.ItemHeight = 14;
                this.cbox_mats.Location = new System.Drawing.Point(166, 93);
                this.cbox_mats.Name = "cbox_mats";
                this.cbox_mats.Size = new System.Drawing.Size(180, 22);
                this.cbox_mats.TabIndex = 3;
                // 
                // DataInput
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.CancelButton = this.btn_cancel;
                this.ClientSize = new System.Drawing.Size(383, 264);
                this.Controls.Add(this.cbox_mats);
                this.Controls.Add(this.textBox1);
                this.Controls.Add(this.btn_cancel);
                this.Controls.Add(this.btn_pickFloor);
                this.Controls.Add(this.mat_lab);
                this.Controls.Add(this.length_lab);
                this.MaximizeBox = false;
                this.MinimizeBox = false;
                this.Name = "DataInput";
                this.Text = "环形波导线";
                this.Load += new System.EventHandler(this.DataInput_Load);
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
    
            #endregion
    
            private System.Windows.Forms.Label length_lab;
            private System.Windows.Forms.Label mat_lab;
            private System.Windows.Forms.Button btn_pickFloor;
            private System.Windows.Forms.Button btn_cancel;
            private System.Windows.Forms.TextBox textBox1;
            private System.Windows.Forms.ComboBox cbox_mats;
    
    
            public int Length => string.IsNullOrEmpty(textBox1.Text) ? 0 : int.Parse(textBox1.Text);
            public Material Material => cbox_mats.SelectedItem as Material;
            public DataInput(List<Material> lists)
            {
                InitializeComponent();
                cbox_mats.DataSource = lists;
                cbox_mats.DisplayMember = "Name";
            }
    
            private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
            {
    
                e.Handled = !(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar));
    
            }
    
            private void DataInput_Load(object sender, EventArgs e)
            {
    
            }
    
            private void btn_pickFloor_Click(object sender, EventArgs e)
            {
                DialogResult = DialogResult.OK;
                this.Close();
            }
        }
    }
    

    }
    `

    原创代码,未经许可,请勿商用
    本人有多年的CAD开发经验,独立完成多个CAD二次开发及Revit二次开发项目。熟悉.net及Asp.net开发技术,和Lisp开发技术。

    现在成立了工作室,承接开发项目。结项后提供源码及开发文档,有需要的话可以提供发票.

    有需求的可以 qilongliao@qq.com 联系开发事宜.

  • 相关阅读:
    2021/6/17学期总结
    2021/6/16申请加分
    2021/6/15
    2021/6/14
    2021/6/11
    2021/6/10
    2021/6/9
    2021/6/8
    2021/6/7
    2021/6/5读书笔记
  • 原文地址:https://www.cnblogs.com/DaLiao/p/15018688.html
Copyright © 2011-2022 走看看