NX Lab

Tìm mặt phẳng lớn nhất và các mặt song song với XY, XZ, YZ của chi tiết

#Python#Hình học#Mặt1 lượt xem

  1. Quản trị viênQuản trị· 0 điểm

    Câu hỏi ·

    Chọn mặt chuẩn gá, mặt đặt lỗ, mặt cần phay thường bắt đầu từ việc tìm mặt phẳng phù hợp. Bài này phân loại mặt phẳng theo hướng pháp tuyến và diện tích.

    Tìm mặt phẳng lớn nhất và các mặt song… Tìm mặt phẳng lớn nhất và các mặt song…

    Các bước thực hiện

    1. Lấy mặt phẳng. Mặt có SolidFaceType là Planar.
    2. Lấy pháp tuyến. Dùng UF AskFaceData hoặc tính từ ba đỉnh.
    3. Phân loại hướng. So sánh pháp tuyến với ±X, ±Y, ±Z.
    4. Tính diện tích. MeasureManager.NewFaceProperties.
    5. Chọn mặt lớn nhất. Theo từng hướng.

    Code tham khảo (Python)

    import NXOpen
    
    def phap_tuyen_mat_phang(face):
        """Tính pháp tuyến từ ba đỉnh không thẳng hàng của mặt phẳng."""
        diem = []
        for e in face.GetEdges():
            a, b = e.GetVertices()
            for p in (a, b):
                if all(abs(p.X - q.X) + abs(p.Y - q.Y) + abs(p.Z - q.Z) > 1e-6 for q in diem):
                    diem.append(p)
            if len(diem) >= 3:
                break
        if len(diem) < 3:
            return None
        p0, p1, p2 = diem[:3]
        u = (p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z)
        v = (p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z)
        n = (u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0])
        dai = (n[0] ** 2 + n[1] ** 2 + n[2] ** 2) ** 0.5
        return None if dai < 1e-9 else (n[0] / dai, n[1] / dai, n[2] / dai)
    
    def huong_chinh(n, dung_sai=0.999):
        for ten, vec in (("X", (1, 0, 0)), ("Y", (0, 1, 0)), ("Z", (0, 0, 1))):
            d = abs(n[0] * vec[0] + n[1] * vec[1] + n[2] * vec[2])
            if d >= dung_sai:
                return ten
        return None
    
    def dien_tich(part, face):
        uc = part.UnitCollection
        kq = part.MeasureManager.NewFaceProperties(uc.FindObject("SquareMilliMeter"),
                                                   uc.FindObject("MilliMeter"), 0.99, [face])
        return kq.Area
    
    def main():
        session = NXOpen.Session.GetSession()
        lw = session.ListingWindow
        lw.Open()
        part = session.Parts.Work
        if part is None:
            return
        tot = {}
        for b in part.Bodies:
            if not b.IsSolidBody:
                continue
            for f in b.GetFaces():
                if f.SolidFaceType != NXOpen.Face.FaceType.Planar:
                    continue
                n = phap_tuyen_mat_phang(f)
                h = huong_chinh(n) if n else None
                if h is None:
                    continue
                s = dien_tich(part, f)
                if h not in tot or s > tot[h][0]:
                    tot[h] = (s, f)
        for h, (s, f) in sorted(tot.items()):
            lw.WriteLine("Mặt phẳng vuông góc trục %s lớn nhất: %.1f mm2" % (h, s))
    
    if __name__ == "__main__":
        main()
    

    Giải thích code

    • Pháp tuyến tính bằng tích có hướng của hai vectơ nằm trên mặt (ba đỉnh không thẳng hàng).
    • abs(dot) >= 0.999 coi mặt là vuông góc với trục (song song với mặt phẳng tọa độ tương ứng).
    • Từ điển tot giữ mặt có diện tích lớn nhất theo từng trục.

    Lỗi thường gặp

    • Mặt phẳng có lỗ bên trong vẫn lấy đỉnh từ vòng ngoài trước; thứ tự cạnh không đảm bảo, nên dùng ba điểm không thẳng hàng như trên.
    • Dấu của pháp tuyến phụ thuộc hướng cạnh; chỉ dùng giá trị tuyệt đối khi chỉ cần hướng trục.

    Code mang tính tham khảo, viết cho NX 12 trở lên (Python journal). Tên menu và một số lớp có thể khác theo phiên bản NX; hãy chạy thử trên bản sao của chi tiết trước khi dùng cho dữ liệu thật.

    Điểm: 0

Trả lời

Đăng nhập để tham gia thảo luận.