[REVIT API Task] Tạo Addin RebarBeam - Phần 4: Truy xuất tọa độ tiết diện | Vietbimcoder.com
C# căn bản Revit API Revit structure 

[REVIT API TASK] TẠO ADD-IN REBAR BEAM – TẠO THÉP DẦM TỰ ĐỘNG (PHẦN 4: TRUY XUẤT TỌA ĐỘ TIẾT DIỆN)

Tiếp tục series add-in Rebar Beam, ở phần 4 mình sẽ hướng dẫn cách truy xuất các điểm tọa độ của dầm.

Các bài còn lại trong series:

Phần 1: Chọn đối tượng

Phần 2: Truy xuất hình học

Phần 3: Truy xuất trục tọa độ

Kích thước hình học:

Width, Heigth, Length đại hiện cho chiều rộng, chiều cao và chiều dài của dầm.

Hệ tọa độ địa phương:

Kiểu dữ liệu XYZ chứa 3 giá trị X, Y, Z đại diện cho giá trị tọa độ một điểm, hoặc xác định một vector chỉ phương trong không gian ba chiều.

Origin: Gốc tọa độ của dầm

VectorX: Vector chỉ phương từ gốc tọa độ, song song với chiều dài dầm, có chiều dài là 1 đơn vị.

VectorY: Vector chỉ phương từ gốc tọa độ, song song với chiều rộng dầm, có chiều dài là 1 đơn vị.

VectorZ: Vector chỉ phương từ gốc tọa độ, song song với chiều cao dầm, có chiều dài là 1 đơn vị.

Ở phần 4, ta tìm hiểu cách để truy xuất các điểm tọa độ địa phương đối tượng.

XYZ

XYZ là kiểu dữ liệu định nghĩa một điểm hoặc một vector chỉ phương trong không gian mô hình Revit. Kiểu dữ liệu XYZ dùng để định nghĩa các thông tin tọa độ, vector chỉ phương của các đối tượng hình học trong Revit.

Định nghĩa XYZ trong thư viện Revit API:

namespace Autodesk.Revit.DB 
{  
    public class XYZ 
    {  
        public XYZ();  
        public XYZ(double x, double y, double z);  
        public double this[int idx] {  get;  }  
        public static XYZ Zero {  get;  }  
        public static XYZ BasisX {  get;  }  
        public static XYZ BasisY {  get;  }  
        public static XYZ BasisZ {  get;  }  
        public double Z {  get;  }  
        public double Y {  get;  }  
        public double X {  get;  }  
    }  
}

Các thuộc tính tĩnh đại diện cho kiễu dữ liệu XYZ có thể truy xuất để lấy thông tin hệ tọa độ gốc của mô hình dự án.

XYZ origin = XYZ.Zero; // Gốc tọa độ, có giá trị là {0; 0; 0}  
XYZ vecX = XYZ.BasisX; // Vector chỉ phương trục X, có giá trị là {1; 0; 0}  
XYZ vecY = XYZ.BasisY; // Vector chỉ phương trục Y, có giá trị là {0; 1; 0}  
XYZ vecZ = XYZ.BasisZ; // Vector chỉ phương trục Z, có giá trị là {0; 1; 0}

Ngoài ra, thư viện Revit API còn cung cấp các toán tử và phương thức để hỗ trợ việc tính toán các đối tượng XYZ như:

Truy xuất các giá trị tọa độ X, Y, Z theo các phương trong hệ trục XYZ:

double x = point.X;  
double y = point.Y;  
double z = point.Z;

Truy xuất chiều dài Vector:

double length = vec.GetLength();

Di chuyển một điểm theo (hoặc ngược chiều) vector cho trước:

XYZ endPnt1 = startPnt + vector;  
XYZ endPnt2 = startPnt - vector;

Phóng to, thu nhỏ độ lớn của một vector với một số:

XYZ multiVector = vector * factor;  
XYZ divideVector = vector / factor;

Tích vô hướng, tích có hướng giữa hai vector:

double d = vector1.DotProduct(vector2);  
XYZ vector3 = vector1.CrossProduct(vector2));

StartPoint

Ở phần 3, ta đã truy xuất được đường dóng của dầm bằng thuộc tính Curve có trong LocationCurve.

Đường dóng của dầm thẳng là một đường thẳng gồm 2 điểm đầu và cuối. Truy xuất điểm đầu của Line bằng phường thức GetEndPoint(), truyền vào tham số giá trị là 0. (Lưu ý: giá trị là 1 sẽ trả về điểm cuối của Line).

Location loc = elem.Location;  
LocationCurve locCur = loc as LocationCurve;  
Curve curve = locCur.Curve;  
Line line = curve as Line;  
XYZ pnt = line.GetEndPoint(0);

zJustification

Tham biến zJustification quy định vị trí thực tế của dầm so với đường dầm.

Các giá trị của tham biến và giải thích:

–  Top: đường dóng nằm ở mặt trên dầm.

– Center, Origin: đường dóng nằm giữa dầm.

– Bottom: đường dóng nằm ở mặt dưới dầm.

Lấy giá trị của tham biến zJustification của đối tượng dầm:

Parameter zJus = elem.LookupParameter("z Justification");  
int zPos = zJus.AsInteger();

Origin

Để di chuyển điểm đầu của đường dóng về gốc tọa độ địa phương được định nghĩa, ta cần di chuyển điểm ngược phương Y một đoạn bằng nửa chiều rộng, ngược phương Z một đoạn bằng chiều cao nhận với x (nếu giá trị tham biến zJustification là Top – x = 1; Center hoặc Origin – x=1/2; Bottom – x=0)

Tính toán hệ số x:

double x = 0;  
switch (zPos) 
{  
    case 0: // Top   
        x = height;  
        break;  
    case 1: // Center  
    case 2: // Origin  
        x = 0.5;  
        break;  
    case 3: // Bottom  
        x = 0;  
        break;  
}

Tính toán gốc tọa độ:

XYZ origin = pnt - vectorY * width / 2 - vectorZ * height * x;

Tọa độ tiết diện dầm

Từ hệ tọa độ, và kích thước các phương, ta có thể xác định tọa độ các tiết diện dầm như sau:

List<XYZ> sectionPnts = new List<XYZ> 
{  
    origin, 
    origin + vectorY * width, 
    origin + vectorY * width + vectorZ * height, 
    origin + vectorZ * height  
};

Kết quả

Sử dụng TaskDialog.Show() để xuất kết quả qua hộp thoại trong giao diện Revit, tương tự các phần trước.

TaskDialog.Show("Revit", $Tọa độ cấu kiện:
      \nP1: {sectionPnts[0]},\nP2: {sectionPnts[1]}
      \nP3: {sectionPnts[2]}\nP4: {sectionPnts[3]}");

 

Phần tiếp theo bắt đầu vẽ thép rồi nhé, các bạn nhớ theo dõi và ủng hộ series nhé.

Đoạn code hoàn chỉnh:

using Autodesk.Revit.ApplicationServices;  
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.Linq;  
using System.Text;  
using System.Threading.Tasks;  
namespace RebarBeam_Example 
{  
    [Transaction(TransactionMode.Manual)] 
    public class Command: IExternalCommand 
    {  
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) 
        {  
            UIApplication uiapp = commandData.Application;  
            Application app = uiapp.Application;  
            UIDocument uidoc = uiapp.ActiveUIDocument;  
            Document doc = uidoc.Document;  
            Selection sel = uidoc.Selection;  
            Reference rf = sel.PickObject(ObjectType.Element, new BeamSelectionFilter());  
            Element elem = doc.GetElement(rf);  
            ElementId elemTypeId = elem.GetTypeId();  
            Element elemType = doc.GetElement(elemTypeId);  
            Parameter bParam = elemType.LookupParameter("b");  
            double width = bParam.AsDouble();  
            Parameter hParam = elemType.LookupParameter("h");  
            double height = hParam.AsDouble();  
            Parameter lParam = elem.LookupParameter("Length");  
            double length = lParam.AsDouble();  
            Location loc = elem.Location;  
            LocationCurve locCur = loc as LocationCurve;  
            Curve curve = locCur.Curve;  
            Line line = curve as Line;  
            XYZ vectorX = line.Direction;  
            XYZ vectorZ = XYZ.BasisZ;  
            XYZ vectorY = vectorZ.CrossProduct(vectorX);  
            XYZ pnt = line.GetEndPoint(0);  
            Parameter zJus = elem.LookupParameter("z Justification");  
            int zPos = zJus.AsInteger();  
            double x = 0;  
            switch (zPos) 
            {  
                case 0: // Top   
                    x = height;  
                    break;  
                case 1: // Center  
                case 2: // Origin  
                    x = 0.5;  
                    break;  
                case 3: // Bottom  
                    x = 0;  
                    break;  
            }  
            XYZ origin = pnt - vectorY * width / 2 - vectorZ * height * x;  
            List<XYZ> sectionPnts = newList<XYZ> 
            {  
                origin, 
                origin + vectorY * width, 
                origin + vectorY * width + vectorZ * height, 
                origin + vectorZ * height  
            };  
            TaskDialog.Show("Revit", $"Tọa độ cấu kiện:
                  \nP1: {sectionPnts[0]},\nP2: {sectionPnts[1]}
                  \nP3: {sectionPnts[2]}\nP4: {sectionPnts[3]}");  
            return Result.Succeeded;  
        }  
    }  
    public class BeamSelectionFilter: ISelectionFilter 
    {  
        public bool AllowElement(Element elem) 
        {  
            if (elem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_StructuralFraming) 
                   return true;  
            return false;  
        }  
        public bool AllowReference(Reference reference, XYZ position) 
        {  
            return false;  
        }  
    }  
}

 

Bài viết liên quan