3 điểm bởi GN⁺ 2025-01-09 | 1 bình luận | Chia sẻ qua WhatsApp
  • Fidget là thư viện Rust để biểu diễn, biên dịch và đánh giá các biểu thức toán học gồm hàng trăm đến hàng nghìn mệnh đề số học, với mục đích sử dụng chính là backend cho bề mặt ẩn
  • Bề mặt ẩn dùng hàm khoảng cách dạng $f(x,y,z) \rightarrow d$ để phân biệt bên trong và bên ngoài, đồng thời rất phù hợp với phép toán CSG và đánh giá song song
  • Frontend cung cấp pipeline đi từ script Rhai xuống cây toán học, DAG, băng SSA, rồi đến bytecode dựa trên thanh ghi tái sử dụng
  • Backend cung cấp interpreter và trình biên dịch JIT, hỗ trợ đánh giá tại một điểm, mảng SIMD, vi phân tự động thuận và số học khoảng
  • Trong phép đánh giá brute force 1024² của 7867 biểu thức, JIT giảm thời gian từ 5,8 giây xuống 182ms, nhưng ở render tối ưu hóa thì chênh lệch thu hẹp còn khoảng 25%, với 6ms và 4,6ms

Mục tiêu của Fidget và bề mặt ẩn

  • Fidget là thư viện để biểu diễn, biên dịch và đánh giá các biểu thức toán học quy mô lớn
    • Nhắm tới các biểu thức xử lý từ hàng trăm đến hàng nghìn mệnh đề số học
    • Mục đích sử dụng chính là backend cho bề mặt ẩn, nhưng cũng có thể dùng cho mục đích khác
  • Bề mặt ẩn là biểu thức có dạng $f(x, y, z) \rightarrow d$, trả về một giá trị khoảng cách duy nhất là $d$
    • Nếu $d$ dương thì điểm $(x,y,z)$ nằm ngoài mô hình
    • Nếu $d$ âm thì điểm nằm bên trong mô hình
    • Hình cầu bán kính 1 có thể được biểu diễn là $\sqrt{x^2 + y^2 + z^2} - 1$
  • Fidget tập trung vào bề mặt ẩn dạng đóng được cấu thành từ các phép toán số học cơ bản
    • Tương phản với cách tính giá trị khoảng cách bằng chương trình Turing-complete như GLSL của pixel shader
    • Các hàm kiểu này gần giống “assembly language của shape” mà biểu diễn cấp cao dễ nhắm tới hơn là con người viết tay trực tiếp

Điểm mạnh của bề mặt ẩn

  • Bề mặt ẩn ngắn gọn và phù hợp với đánh giá song song
    • Phù hợp với đánh giá song song quy mô lớn bằng lệnh SIMD hoặc GPU
  • Các phép toán CSG trở nên đơn giản
    • Những phép như union hay intersection vốn khó với mesh hoặc NURBS có thể được biểu diễn dễ dàng
    • Hợp của hai hình trụ chồng khít chính xác được biểu diễn bằng min(a, b)
  • Phương trình dạng đóng tạo ra cơ hội tối ưu hóa
    • Fidget có thể ghi lại trace thực thi cho biết nhánh nào đã được chọn trong lúc đánh giá
    • Dùng trace này để đơn giản hóa biểu thức và giảm chi phí cho các lần đánh giá sau

Vì sao được viết mới sau libfive

  • Fidget là thư viện được viết mới để thay thế kernel libfive hiện có
    • libfive gồm khoảng 40K dòng mã, phần lớn là C++
    • Ngay cả với tác giả gốc, việc chỉnh sửa cũng khó; sau vài tháng biên dịch lại thì build thường hỏng và phải chỉnh CMake
  • Triển khai mới là nền tảng để thử nghiệm các câu hỏi đang thú vị hiện nay
    • Tìm API phù hợp cho implicit kernel và chấp nhận cả khả năng phá vỡ tương thích
    • Thử nghiệm biên dịch JIT native để tăng hiệu năng mà không cần chuyển sang GPU
    • Có thể cross-compile sang WebAssembly và tạo demo web dễ tiếp cận
  • Fidget được viết bằng Rust
    • Có thể biên dịch chỉ với cargo build
    • Cross-compile sang WebAssembly một cách tự nhiên
    • Hệ thống kiểu mạnh và tính an toàn bộ nhớ của Rust giúp việc refactor đáng tin cậy hơn

Frontend: từ script đến bytecode

  • Frontend của Fidget cung cấp pipeline đi từ script đầu vào xuống bytecode
    • Người dùng không bắt buộc phải đi qua toàn bộ luồng này; có thể dùng thư viện ở bất kỳ giai đoạn trung gian nào
  • Rhai scripting

    • Fidget bao gồm binding cho Rhai, ngôn ngữ scripting nhúng dành cho Rust
    • Có thể xây dựng biểu thức toán học trong script bằng operator overloading
    • Giá trị được truyền vào drawcây toán học biểu diễn biểu thức do script tạo ra
  • Cây, đồ thị, băng SSA

    • Cây toán học được khử trùng lặp rồi chuyển thành đồ thị có hướng không chu trình (DAG)
    • Đồ thị được làm phẳng thành mã tuyến tính thông qua sắp xếp topo
    • Mã này có dạng SSA (single static assignment)
    • Có số lượng tùy ý các pseudo-register rX, và mỗi thanh ghi chỉ được ghi đúng một lần
    • Băng SSA cũng có thể được đánh giá, nhưng khả năng mở rộng kém vì mỗi phép toán cần một vị trí bộ nhớ
    • Nguyên nhân là pseudo-register không được tái sử dụng
  • Bytecode và cấp phát thanh ghi

    • Để tăng hiệu quả đánh giá, các pseudo-register được ánh xạ sang thanh ghi vật lý có thể tái sử dụng
    • Băng SSA ví dụ có thể được nén xuống còn 6 thanh ghi tái sử dụng
    • Việc cấp phát thanh ghi sử dụng simple algorithm đã được giới thiệu trước đó
    • Đây là thuật toán một lượt, ưu tiên tốc độ và tính xác định hơn là hiệu quả tối đa
    • Trình thông dịch bytecode dùng 256 thanh ghi
    • Chỉ số thanh ghi được lưu trong u8
    • Nếu thiếu thanh ghi, bộ cấp phát sẽ chèn LOADSTORE để ghi vào bộ nhớ phụ với chỉ số u32

Backend: cách đánh giá và đơn giản hóa

  • Backend của Fidget được tách khỏi frontend thông qua các trait Function, TracingEvaluator, BulkEvaluator
    • Thuật toán không bị kết dính chặt với triển khai cây toán học mà có thể hoạt động trên Function tổng quát
    • Hiện chưa có triển khai không phải cây toán học nào cho trait Function
  • Hiện có hai cách đánh giá cây toán học
    • Trình thông dịch bytecode
    • Hàm biên dịch JIT
  • Chế độ đánh giá

    • Fidget cung cấp bốn chế độ đánh giá
      • Đánh giá tại một điểm
      • Đánh giá SIMD dựa trên mảng
      • Vi phân tự động thuận
      • Số học khoảng
    • Trong đánh giá bulk, người dùng cung cấp mảng đầu vào và nhận mảng đầu ra
    • Backend JIT sinh mã SIMD để xử lý 4 phần tử mỗi lần trên AArch64 và 8 phần tử mỗi lần trên x86-64
  • Vi phân tự động thuận

    • Bộ đánh giá vi phân tính giá trị và tối đa 3 đạo hàm riêng
    • Với bề mặt ẩn, thông thường sẽ tính $(f, \partial f/\partial x, \partial f/\partial y, \partial f/\partial z)(x,y,z)$
    • Trên bề mặt khi $f(x,y,z)=0$, các đạo hàm riêng là xấp xỉ tốt cho pháp tuyến bề mặt
    • Giá trị này có thể dùng cho shading
    • Việc đánh giá được thực hiện bằng vi phân tự động thuận
    • Giá trị thanh ghi được gắn kèm giá trị vi phân và áp dụng quy tắc dây chuyền ở mỗi bước
    • Bộ đánh giá JIT đặt giá trị và 3 đạo hàm vào một thanh ghi 4 x f32
  • Số học khoảng

    • Số học khoảng đánh giá một khoảng giá trị đầu vào thay vì một giá trị đơn lẻ
    • Ví dụ, có thể dùng $1 \le x \le 5$ thay cho $x=1$
    • Đầu ra cũng sẽ là một khoảng như $2 \le f(x,y,z) \le 20$
    • Kết quả số học khoảng có tính bảo toàn
      • Có thể không ôm sát phạm vi thực của hàm
      • Nhưng sẽ bao gồm mọi đầu ra có thể có trong khoảng đầu vào đã cho
    • Trong đánh giá bề mặt ẩn, số học khoảng là thành phần cốt lõi
    • Khi đánh giá một vùng không gian dưới dạng các khoảng $x,y,z$, nếu khoảng đầu ra chắc chắn lớn hơn 0 thì toàn bộ vùng đó nằm ngoài hình và không cần xem tiếp
  • Đơn giản hóa dựa trên trace

    • Bộ đánh giá số học khoảng cũng ghi lại trace thực thi
    • Với min(a,b), nếu $0 \le a \le 1$, $4 \le b \le 5$ thì a luôn nhỏ hơn, nên biểu thức có thể được đơn giản hóa thành a
    • Mỗi phép minmax ghi lại đối số nào ảnh hưởng đến kết quả
    • Nó lưu lựa chọn là bên trái, bên phải hoặc cả hai
    • Các lựa chọn này được dùng để đơn giản hóa hàm gốc
    • Fidget hỗ trợ đơn giản hóa min·max dùng trong CSG và các phép logic and·or
    • Các shape không có CSG hay logic sẽ không hưởng lợi từ tối ưu hóa đơn giản hóa
    • Dù vậy, vẫn còn lợi ích từ việc bỏ qua các vùng rỗng hoặc vùng đặc hoàn toàn dựa trên số học khoảng

Kết hợp số học khoảng và đơn giản hóa tape

  • Việc kết hợp số học khoảng và đơn giản hóa tape là kỹ thuật cốt lõi giúp dễ xử lý các biểu thức quy mô lớn
    • Bỏ qua các vùng không gian không hoạt động, đồng thời làm cho việc đánh giá trên phần vùng hoạt động còn lại rẻ hơn
  • Đơn giản hóa tape là cách tính toán biểu thức đã đơn giản hóa chỉ hợp lệ trong một vùng không gian cụ thể
    • Không giống các cấu trúc tăng tốc ray tracing thông thường, về bản chất đây là việc tạo cấu trúc tăng tốc động trong lúc đánh giá
  • Trong rasterization, chi phí đánh giá khoảng được phân bổ trên nhiều pixel
    • Đánh giá khoảng cho vùng pixel $N \times N$ có độ phức tạp $O(T)$, tỷ lệ với độ dài tape $T$
    • Không phụ thuộc vào số lượng pixel
  • Khi đi xuống đến các vùng nhỏ rồi đánh giá theo từng pixel, hệ thống dùng tape đã được rút ngắn đi đáng kể
    • Với vùng $M \times M$, chi phí là $O(T' \times M \times M)$
    • Trong đó $T' < T$
  • Trong ví dụ render hello, world 2D ở độ phân giải 256×256, tape gốc có 254 mệnh đề
    • Thực hiện đánh giá khoảng trên 64 tile 32×32 pixel
      • Bỏ qua các vùng rỗng và còn lại 47 tile hoạt động
      • Độ dài tape trung bình của các tile hoạt động giảm xuống còn 73 mệnh đề
    • Mỗi tile tiếp tục được chia nhỏ thành 16 tile 8×8 pixel
    • Thực hiện đánh giá khoảng trên 752 tile 8×8 pixel
      • Bỏ qua các vùng rỗng và còn lại 351 tile hoạt động
      • Độ dài tape trung bình của các tile hoạt động giảm xuống còn 20 mệnh đề
    • 351 tile 8×8 còn lại được đánh giá theo từng pixel
  • Đến thời điểm đánh giá từng pixel, tape đã ngắn hơn hơn 10 lần so với độ dài ban đầu

Biên dịch JIT

  • Trình thông dịch bytecode là một vòng lặp chặt nhưng vẫn có overhead không thể tránh khỏi
    • Phân phối lệnh là một nhánh đơn khó dự đoán
    • Mỗi lệnh đọc và ghi bộ nhớ thông qua các ô thanh ghi của bộ đánh giá VM
  • Fidget bao gồm một trình biên dịch JIT hạ bytecode xuống mã máy để đạt hiệu năng tối đa
    • Lệnh máy là mã tuyến tính không cần dispatch
    • Do dùng trực tiếp thanh ghi vật lý nên giảm số lần đọc/ghi bộ nhớ
  • Đầu vào của JIT là cùng tape bytecode như trước
    • Thay vì 255 thanh ghi mặc định của VM, hệ thống lập kế hoạch theo 12 thanh ghi vật lý trên x86-64 và 24 trên AArch64
    • Trên AArch64 ánh xạ vào v8-31, còn trên x86-64 ánh xạ vào xmm4-15
  • Với từng tổ hợp opcode × kiểu dữ liệu × kiến trúc, tác giả viết thủ công các đoạn assembly
    • Sau đó vá thanh ghi vật lý mong muốn vào snippet và sao chép vào vùng nhớ được mmap
  • Ở cấp độ Rust, vùng nhớ được tạo ra sẽ được ép kiểu thành con trỏ hàm để gọi
    • Đầu vào và đầu ra được truyền bằng cách ép Rust slice thành raw pointer
  • Số liệu hiệu năng

    • Trong một ví dụ phức tạp gồm 7.867 biểu thức, đánh giá brute force ở độ phân giải 1024² pixel cho thấy hiệu quả của JIT rất lớn
    • Trình thông dịch bytecode: 5,8 giây
    • Backend JIT: 182ms
    • Tăng tốc: 31 lần
    • brute force không tận dụng số học khoảng hay đơn giản hóa tape
    • Nếu dùng thuật toán thông minh hơn thì chênh lệch sẽ giảm
    • Triển khai render tối ưu của Fidget vẽ cùng hình ảnh đó trong 6ms với trình thông dịch bytecode và 4,6ms với backend JIT
    • Trong trường hợp này, mức cải thiện vào khoảng 25%

Render và tạo mesh

  • Render

    • Mọi quá trình render mô hình đều dùng thuật toán trong fidget::render
    • Render sử dụng thuật toán cốt lõi từ bài báo SIGGRAPH
    • Các vùng không gian lớn được render bằng số học khoảng
    • Hệ thống tạo tape đã được rút ngắn dựa trên quá trình truy vết
    • Các vùng mơ hồ được chia nhỏ rồi xử lý đệ quy
    • Trong render 3D, pháp tuyến được tính bằng đạo hàm riêng
    • Mô hình được biến đổi bằng ma trận thuần nhất 4×4 trong quá trình render
    • Hỗ trợ phép biến đổi phối cảnh
    • Kết quả render thường là hai ảnh: heightmap và pháp tuyến theo từng pixel
    • Kết quả có thể được vẽ bằng các kỹ thuật deferred rendering tiêu chuẩn như SSAO
  • Tạo mesh

    • Fidget triển khai Manifold Dual Contouring để tạo mesh
    • Triển khai này hướng tới việc luôn tạo ra mesh có các đặc tính sau
      • watertight
      • manifold
      • bảo toàn edge và corner sắc nét
      • có tính thích ứng, với mật độ tam giác thấp hơn ở các vùng phần lớn là phẳng
    • Cũng có những khiếm khuyết đã biết
      • không nhất thiết bảo toàn được các đặc trưng mỏng
      • mesh kết quả có thể chứa tự giao cắt
      • cách đặt đỉnh dễ bị tổn thương trong các trường hợp đối kháng
    • Việc tạo mesh tốt cho các bề mặt ẩn tùy ý vẫn là một bài toán chưa được giải quyết
    • Manifold Dual Contouring không hoàn hảo, nhưng là điểm cân bằng giữa tính đơn giản và hiệu năng

Demo và web GUI

  • Fidget repository bao gồm nhiều demo
    • Web GUI được giới thiệu là demo thú vị nhất
    • Ngoài ra còn có fidget-cli dạng CLI đơn giản và trình xem script native fidget-viewer
  • Demo web kết hợp nhiều công nghệ web khác nhau
    • GUI được viết bằng TypeScript
    • Fidget crate không điều khiển event loop mà được dùng như một thư viện
    • Trình soạn thảo văn bản dùng CodeMirror
    • Cần một bundler để dùng các module Node, và tác giả đã chọn webpack
    • Việc đánh giá script và render được thực hiện trong web worker để không chặn event loop chính
    • Để обход sự thiếu vắng std::thread trong trình duyệt, quá trình render được song song hóa bằng wasm-bindgen-rayon
    • worker và event loop chính chia sẻ bộ nhớ
    • Khi người dùng nhập mới, có thể hủy các tác vụ render kéo dài bằng cờ Arc<AtomicBool> được chia sẻ với worker
  • Việc làm cho nhiều thành phần hoạt động cùng nhau là khá khó khăn
    • Mỗi thành phần đều có ví dụ hoạt động, nhưng bundler, cấu hình và server của chúng lại khác nhau
    • Một bản sửa lỗi gần đây của wasm-bindgen đã thay đổi hành vi mà wasm-bindgen-rayon cần, nên phải ghim phiên bản cũ hơn
  • Demo web cũng chạy được trên điện thoại
    • Do đang dùng sự kiện chuột nên không hỗ trợ điều khiển camera

Sự căng thẳng giữa demo và thư viện

  • Fidget trước hết là một thư viện
    • Cách dùng được nhắm tới là người dùng nhúng nó làm hạ tầng trong dự án của mình, thay vì dùng demo như một công cụ CAD thực thụ
  • Tuy vậy, số người nghịch demo lại nhiều hơn hẳn số người xây công cụ bằng thư viện
    • Một số người thậm chí dùng demo cho công việc thiết kế
    • Có sự căng thẳng giữa việc cải thiện demo cho nhóm người dùng đông hơn này hay cải thiện thư viện cho nhóm nhà phát triển công cụ nhỏ hơn
  • Việc duy trì đồng thời kernel và một UI CAD hoàn chỉnh là khó, nên phạm vi demo ngày càng bị thu hẹp
    • Ngay cả một demo “tối thiểu” như web editor cũng đã là một dự án đáng kể
  • Kế hoạch là đi theo ba hướng
    • Tiếp tục theo đuổi những gì bản thân thấy hứng thú để duy trì động lực và sự tập trung
    • Tiếp nhận đề xuất từ người dùng công cụ nhưng giữ kỳ vọng ở mức hợp lý
    • Lý tưởng nhất là ưu tiên phản hồi từ các nhà phát triển công cụ, những người có thể giúp giảm gánh nặng demo

Khả năng trong tương lai

  • Backend GPU

    • Backend GPU là một hướng mở rộng tự nhiên
    • Đã có sẵn các bài báo SIGGRAPH liên quan
    • Đã được triển khai trên nhánh wgpu-bytecode
    • Hiệu năng trên laptop Apple M1 Max không đặc biệt hấp dẫn
    • Vòng lặp thông dịch bytecode có vẻ rất kém hiệu quả
    • Hiện vẫn đang tiếp tục điều tra nguyên nhân gốc rễ
  • Tạo mesh tốt hơn

    • Với những người dùng thư viện một cách nghiêm túc, việc tạo mesh là một vấn đề lớn
    • Fidget sử dụng chiến lược tạo mesh giống libfive, nhưng không có nhiều tinh chỉnh tỉ mỉ giúp tạo nên hành vi vững chắc hơn của libfive
    • Do không hài lòng với các lựa chọn hiện có, tác giả chưa dành nhiều thời gian cho phần này
    • Tác giả muốn triển khai một thuật toán mesh thật sự bulletproof hơn là chắp vá thêm lên dual contouring
    • Hiện vẫn chưa có phương pháp nào trong tài liệu hoặc phương án tự xây dựng đáp ứng được các yêu cầu
    • Có thể sẽ thực hiện một số tinh chỉnh tùy theo nhu cầu người dùng, nhưng cũng dự định tiếp tục tìm kiếm các lựa chọn tốt hơn
  • Thư viện shape và transform tiêu chuẩn

    • Qua nhiều thế hệ phần mềm, tác giả đã chuyển thư viện shape tiêu chuẩn của Fab Modules sang các công cụ mới
    • Công việc này khá tẻ nhạt, nhưng cung cấp một nền tảng phần nào mang tính tiêu chuẩn cho mô hình hóa cấp cao
    • Trong libfive, mỗi shape được viết bằng C++ và các binding C, Python, Scheme được tự động tạo từ file header
    • README giải thích rằng libfive_stdlib.h vừa là header C vừa là tài liệu có cấu trúc để helper script phân tích
    • Cách tiếp cận của Fidget hiện vẫn đang được thảo luận
    • Thảo luận đang diễn ra tại fidget#145
    • Có thể đưa thư viện Fab shapes sang Rust
    • Mã thanh lịch hơn tận dụng vector GLSL như thư viện primitives của Inigo Quilez cũng là một điểm tham chiếu
  • Binding ngôn ngữ cấp cao

    • Hiện tại Fidget chỉ cung cấp binding Rhai
    • Rhai được chọn vì đây là một trong những ngôn ngữ scripting trưởng thành theo hướng Rust-first
    • Nó dễ tích hợp và có lợi thế là biên dịch được sang WebAssembly
    • Nhiều người dùng có thể sẽ thích binding Python hoặc Node hơn
    • Cách thức binding cũng vẫn là một câu hỏi còn bỏ ngỏ
    • C API cho phép tận dụng thư viện FFI của từng ngôn ngữ, nhưng với thiết kế Rust-first thì điều này tạo cảm giác như phải hạ xuống một tầng
    • Nếu có thư viện tiêu chuẩn, sẽ tốt hơn nếu nó có thể được tự động lộ ra trong mỗi binding với khả năng sử dụng phù hợp như docstring, đối số mặc định, v.v.

Trạng thái công khai và cách sử dụng

  • README của Fidget từ sau lần công khai ban đầu đã mô tả trạng thái này là “quietly public”
    • 19 phiên bản đã được phát hành trên crates.io
    • Một số người dùng đã bắt đầu xây dựng thứ gì đó trên nền Fidget
  • Giờ đây Fidget đã chuyển sang giai đoạn “loudly public”
  • Mã nguồn có tại Github
    • Có thể thêm vào dự án Rust bằng cargo add fidget
    • Giấy phép là MPL 2.0, một giấy phép copyleft yếu
    • Đây được giới thiệu là giấy phép thân thiện với cả OSS lẫn sử dụng thương mại

1 bình luận

 
GN⁺ 2025-01-09
Ý kiến trên Hacker News
  • Xin chào, đây là dự án của tôi :)
    Điều đặc biệt hay ở mảng này của khoa học máy tính là nó có thứ phù hợp với mọi người. Nó bao gồm cấu trúc dữ liệu và thuật toán, tối ưu hiệu năng mức thấp, trình biên dịch, dựng hình/đồ họa máy tính, UI/UX cho công cụ thiết kế, lập trình GPGPU, v.v.
    Tôi sẽ trả lời các câu hỏi trong chủ đề này, nhưng bạn cũng có thể theo dõi các cập nhật thêm qua mạng xã hội(https://mattkeeter.com/links/) hoặc RSS blog(https://mattkeeter.com/atom.xml)

    • Tôi tình cờ thấy cái này khi đọc blog và thấy nó rất hay: https://www.mattkeeter.com/projects/machined-pen/the_plan.jp...
      Nó thể hiện rất rõ một ý tưởng tôi đã ấp ủ từ lâu trong đầu. Điều gì sẽ xảy ra nếu chính quá trình thiết kế kế hoạch chế tạo này trở thành CAD API hướng đến người dùng? Khi xử lý các bài toán “chế tạo” như mộc, ống nước, gia công kim loại hay cơ khí, ta tự nhiên sẽ nghĩ về nguyên vật liệu, công cụ đang có, và trình tự công việc để đạt được kết quả mong muốn
      Nhưng CAD API hiện nay, dù là công cụ CAD viết bằng code hay giao diện truyền thống dựa trên chuột, lại không hoạt động theo cách đó; thay vào đó, chúng khiến bạn tập trung vào cách biểu diễn hình dạng hoàn thiện hơn là cách thực sự tạo ra nó. Rốt cuộc điều quan trọng là làm ra món đồ, còn mô hình hóa chỉ là công cụ để hỗ trợ việc đó, nhưng công cụ lại xuất hiện quá nổi bật ở tiền cảnh
      Một luồng mô hình hóa dựa trên thực tế hơn dường như có rất nhiều ưu điểm; với góc nhìn của người có kinh nghiệm CAD nhiều hơn hẳn, bạn có nghĩ khái niệm này có tiềm năng phát triển không, hay nó là ngõ cụt?
      Nói thêm một chút về cây bút, nếu kẹp thanh vật liệu trong 3-jaw chuck, tiện nó về kích thước phù hợp với collet, rồi cắt từ thanh đã tiện ra 1 blank cho nắp và 2 blank cho thân, sau đó cố định phần còn lại bằng collet, bạn có thể giữ được độ đồng tâm. Tuy vậy, nếu kích thước cuối cùng không trùng với kích thước collet thì sẽ hơi lãng phí vật liệu
    • Matt, tôi có một câu hỏi nhanh. Tôi chưa tìm hiểu đủ kỹ, nên xin lỗi nếu đây là câu hỏi quá chung chung hoặc ngớ ngẩn
      Về mặt tính năng, Fidget khác libfive hay Ao như thế nào?
    • Tuyệt thật! Tôi nhớ mình từng đóng góp vào mã parser biểu thức cho công trình Knoll et al. 2009 được trích dẫn trong bài báo SIGGRAPH
      Đoạn mã đó chỉ đơn giản chuyển một biểu thức đơn thân thiện với người dùng thành các lời gọi hàm lồng nhau cho thư viện IA trong GLSL, hoàn toàn không có tối ưu hóa. Cái này đi xa hơn rất nhiều rồi
  • Tình cờ là tôi vừa đọc một bài viết tuyệt vời khác của tác giả: https://www.mattkeeter.com/projects/constraints/

  • Chà, nếu tôi biết đến thứ này khi tự làm trình dựng hình bề mặt ẩn của riêng mình thì nó đã cực kỳ hữu ích
    Cách tiếp cận của tôi ở vài khía cạnh cũng tương tự (interval arithmetic), nhưng ở vài khía cạnh thì khác. Nó ít được tối ưu hơn và tôi đã tự sinh GLSL cho fragment shader
    Thành thật mà nói, tôi còn muốn vứt hết đi và triển khai lại thứ này để thay thế. Không biết nên vui hay nên buồn nữa

    • Bạn có thể vui mà! Dù sao thì bạn cũng đang làm việc trong một lĩnh vực nơi bạn có thể tự làm công cụ hoặc dùng công cụ do người khác làm
      Bạn có thể lấy ý tưởng để dùng, hoặc dùng cái này rồi đóng góp cho dự án. Dù theo cách nào thì cũng rất tuyệt
  • Thật ấn tượng khi có một CAD kernel mã nguồn mở mới xuất hiện! Chỉ đọc bài viết thì tôi không rõ nó có hỗ trợ xuất sang các định dạng phổ biến như STEP hay không
    Nếu có, hoặc sau này có, thì nó có vẻ sẽ là nền tảng rất tốt cho nhiều thư viện CAD mã nguồn mở

    • Rất tiếc là không hỗ trợ xuất STEP. STEP dùng một biểu diễn nội bộ hoàn toàn khác
      Phần lớn file STEP biểu diễn hình dạng dưới dạng tập hợp các bề mặt, ví dụ như trimmed NURBS. Các bề mặt này phải tạo thành một đa tạp kín không có khe hở, khi đó mới có thể được coi là thể tích khối rắn
      Để thứ này thực sự hoạt động, bạn cần một kernel biểu diễn biên (b-reps) chứ không phải biểu diễn hàm (f-reps) của Fidget. Viết một kernel như vậy là một bài toán khó hơn nhiều. Ví dụ, giao của hai bề mặt NURBS không phải lúc nào cũng có biểu diễn dạng đóng
      Khi tôi nói chuyện với người trong ngành, họ ước tính rằng ngay cả với một nhóm đã từng làm việc này trước đó, để tạo ra một b-rep kernel tử tế cũng sẽ cần khoảng 6 kỹ sư trong 1 năm
      Nếu muốn tìm hiểu thêm, tình cờ là tôi cũng từng viết một trình xem file STEP, trong đó có kèm một b-rep kernel còn rất xa mới đạt cấp độ công nghiệp: https://www.mattkeeter.com/projects/foxtrot/
  • “Nếu đánh giá brute-force trên ảnh 1024² pixel thì trình thông dịch bytecode mất 5,8 giây, còn backend JIT mất 182ms, nhanh hơn 31 lần.”
    “Nếu dùng thuật toán thông minh hơn thì mức tăng tốc sẽ bớt ấn tượng hơn. Cách brute-force không tận dụng interval arithmetic hay tape simplification. Phần triển khai render được tối ưu hóa của Fidget vẽ hình ảnh này trong 6ms bằng trình thông dịch bytecode và 4,6ms bằng backend JIT, nên mức cải thiện chỉ còn khoảng 25%.”
    Tôi thích việc ở đây tập trung vào chỗ backend JIT trở nên kém quan trọng hơn sau khi tối ưu hóa thuật toán, thay vì tập trung vào việc tối ưu hóa thuật toán mang lại cải thiện 1000 lần với bytecode và 40 lần với JIT

  • Vài năm trước ở đại học tôi từng làm một chút về trình mô phỏng vật lý hạt nhân nguyên tử, kiểu như mô hình hóa lò phản ứng
    Mô hình hình học của nó dựa trên bề mặt ẩn, đặc biệt là R-functions. min(x,y) cũng là một ví dụ, và chúng có những tính chất thú vị như khả vi ở mọi nơi
    Tài liệu nhập môn tốt là cái này. Có lẽ đây cũng là tài liệu duy nhất bằng tiếng Anh: https://ecommons.cornell.edu/items/35ae0f68-1af5-4f28-8b8b-7...
    Tôi đã rời lĩnh vực hạt nhân nguyên tử khá lâu rồi, nhưng có lẽ họ vẫn còn dùng nhiều mã Fortran cũ cho việc mô hình hóa. Fidget có tiềm năng thú vị như một kernel cho các gói mô phỏng mới

  • Hơi lạc đề một chút, nhưng tôi đang tìm phần mềm CAD tốt nhất theo hướng viết mã
    Tôi đã thử CadQuery nhưng gặp một vài vấn đề. Có gì đáng khuyên dùng cho mục đích in 3D không?

    • Tôi từng làm một bài nói về CAD theo hướng viết mã và đã đề cập khá nhiều lựa chọn
      https://youtu.be/0wn7vUmWQgg?si=9Rc1tvbiQgQDgQzd&t=2766
      Tôi cũng đang phát triển một cái bằng Rust, nhưng còn chưa thể nói là nó đã sẵn sàng
    • Cũng có build123d
      https://github.com/gumyr/build123d
    • Với những ai không muốn mở video, danh sách được nêu trong bình luận/video khác là như sau
      OpenSCAD, DSLCAD, CadQuery, Build123d, Cascade Studio, Declaracad, Replicad
    • replicad
  • Thú vị đấy. Trước đây tôi cũng từng xem các bài báo và bản demo về loại bề mặt ẩn này. Có thể đó cũng là công trình của tác giả
    Thật ấn tượng khi tưởng tượng xem có thể tạo ra những mô hình gì, nhưng tôi muốn thấy thứ gì đó lớn hơn các ví dụ đồ chơi
    Ví dụ, liệu có thể extrude bề mặt như trong kernel b-rep, hoặc nhập SVG/phông chữ để tạo thành khối rắn không?
    Tôi rất muốn thấy một kernel mã nguồn mở nhanh, hỗ trợ những tính năng như vậy mà vẫn song song hóa tốt

  • Nó làm tôi nhớ khá nhiều đến https://bauble.studio/ của Ian Henry

  • Tôi cũng từng muốn thử làm thứ gì đó tương tự, dùng SDF để xử lý cây trừu tượng cho việc tạo bề mặt
    Ý tưởng là có một mesh hoặc point cloud mục tiêu, rồi dùng hill climbing/annealing để tìm ra cái cây khớp tốt với hình dạng mong muốn

    • “A Unified Differentiable Boolean Operator with Fuzzy Logic” có vẻ sẽ thú vị
      https://arxiv.org/abs/2407.10954
      Nó tạo cây CSG bằng cách kết hợp các leaf khả vi (mặt bậc hai) bằng các phép toán kiểu Boolean khả vi, để có thể hill-climbing trên toàn bộ hình dạng