SwiftCAD is a streamlined Transformer architecture for parametric CAD generation from vector engineering drawings, building on the SVG-based pipeline of Drawing2CAD. By removing redundant MLP layers in the embedding stage and unifying command and parameter prediction into a single weight-shared decoder with task-specific heads, SwiftCAD achieves a 64.74% reduction in parameters (from 10.1M to 3.6M) and faster inference, while maintaining accuracy within 0.5% (command) and 0.9% (parameter) of the Drawing2CAD baseline on the CAD-VGDrawing benchmark.
- Python 3.9
- Cuda 11.8+
Install python package dependencies through pip:
pip install -r requirements.txtWe use the CAD-VGDrawing dataset from Drawing2CAD. Download data from here and extract them under the data folder.
-
svg_rawcontains the engineering drawings of each CAD model in SVG format, including four views:Front,Top,Right, andFrontTopRight. Each SVG file has been preprocessed through path simplification and deduplication, path reordering, and viewbox normalization. To obtain engineering drawings in PNG format, you can simply convert them using CairoSVG with a single line of code:import cairosvg cairosvg.svg2png(url=svg_path, write_to=png_path, output_width=224, output_height=224, background_color='white')
-
svg_veccontains vectorized representations of SVG drawing sequences. Each file stores the stacked drawing sequences for the four views (Front,Top,Right, andFrontTopRight), saved in.npyformat to enable fast data loading. -
cad_veccontains the vectorized representation for CAD sequences, saved in.h5format to enable fast data loading.
The main SwiftCAD configuration (Shared Decoder + no MLP embedding, d_model=144) can be trained with:
python train.py --input_option 4x --d_model 144 --exp_name swiftcad_mainTo reproduce all five rows of Table 2, use the following commands. The relevant flags are:
--use_shared_decoder(default: on) — shared decoder architecture (paper main). Pass--no-use_shared_decoderto use the dual-decoder baseline.--use_mlp_embedding(default: off) — pass to enable the legacy MLP embedding layer (Drawing2CAD baseline).--d_model(default:144, choices:144/192/256) — Transformer embedding dimension.
# (1) Baseline (Drawing2CAD): dual decoder + MLP embedding
python train.py --input_option 4x --no-use_shared_decoder --use_mlp_embedding --d_model 256 --exp_name baseline
# (2) Shared Decoder only (with MLP embedding)
python train.py --input_option 4x --use_mlp_embedding --d_model 256 --exp_name shared_decoder
# (3) Shared + w/o MLP, d_model = 144 (main config)
python train.py --input_option 4x --d_model 144 --exp_name shared_nomlp_144
# (4) Shared + w/o MLP, d_model = 192
python train.py --input_option 4x --d_model 192 --exp_name shared_nomlp_192
# (5) Shared + w/o MLP, d_model = 256
python train.py --input_option 4x --d_model 256 --exp_name shared_nomlp_256Since different configurations produce different model checkpoints, it is recommended to specify a unique --exp_name for each run. For more configurable parameters, please refer to config/config.py.
After training, run inference on all test data with the corresponding configuration. Make sure the inference flags match the training flags.
# (1) Baseline (Drawing2CAD)
python test.py --input_option 4x --no-use_shared_decoder --use_mlp_embedding --d_model 256 --exp_name baseline
# (2) Shared Decoder only
python test.py --input_option 4x --use_mlp_embedding --d_model 256 --exp_name shared_decoder
# (3) Shared + w/o MLP, d_model = 144 (main config)
python test.py --input_option 4x --d_model 144 --exp_name shared_nomlp_144
# (4) Shared + w/o MLP, d_model = 192
python test.py --input_option 4x --d_model 192 --exp_name shared_nomlp_192
# (5) Shared + w/o MLP, d_model = 256
python test.py --input_option 4x --d_model 256 --exp_name shared_nomlp_256After inference, the final results will be saved under proj/your_exp_name/test_results. To evaluate the model inference results and to export and visualize the final CAD models, please refer to the code from DeepCAD.
Quantitative evaluation following the Drawing2CAD protocol — Mean Chamfer Distance (MCD = mean CD × 10²) and Invalidity Ratio (IR, %) — uses pythonocc-core (not in requirements.txt):
conda install -c conda-forge pythonocc-core=7.7.0After running test.py for each of the five paper configs (baseline, shared_decoder, shared_nomlp_{144,192,256}):
# (1) Precompute GT point clouds — one-time
python evaluate/precompute_pc.py \
--src_test_results proj_log/baseline/test_results \
--output data/cad_vec_pc --n_points 2000 --n_jobs 8
# (2) Evaluate all five paper configs
python evaluate/eval_paper_models.py --gt_pc_root data/cad_vec_pc --n_jobs 8 --seed 0Step (1) reconstructs each GT CAD vector via OCC and freezes a 2,000-point cloud per sample to data/cad_vec_pc/. The --src_test_results path reads gt_vec from test.py outputs (byte-equivalent to cad_vec/<id>.h5 after EOS truncation) and avoids requiring the full CAD-VGDrawing dataset locally; --src data/cad_vec --split_json ... --phase test is also supported when the dataset is available.
Step (2) writes per-config proj_log/<exp_name>/cd_ir.txt (per-sample TSV) and cd_ir.txt.json (machine-readable summary), plus a combined proj_log/cd_ir_summary.md. Re-running skips configs whose JSON already matches the requested settings; pass --force to recompute, or --only <a>,<b> to run a subset. For ad-hoc single-experiment evaluation, call evaluate/eval_cd_ir.py directly (see --help).
Quantitative comparison on CAD-VGDrawing (Table 2 of the paper). All entries use the 4x input option.
| Method | Parameters | File Size (MB) | Inf. Time (s) | ACCcmd ↑ | ACCparam ↑ | IR ↓ | MCD ↓ |
|---|---|---|---|---|---|---|---|
| Baseline (Drawing2CAD) | 10,109,894 | 38.57 | 8.4815 | 82.76 | 79.23 | 20.44 | 11.16 |
| Shared Decoder | 7,722,438 | 29.46 | 8.4329 | 82.42 | 79.13 | 21.52 | 11.29 |
| Shared + w/o MLP (256) | 7,745,850 | 29.55 | 8.3925 | 82.20 | 79.21 | 21.55 | 11.30 |
| Shared + w/o MLP (192) | 5,204,234 | 19.85 | 8.4447 | 82.17 | 78.87 | 21.75 | 11.66 |
| Shared + w/o MLP (144) | 3,564,806 | 13.60 | 7.7575 | 82.37 | 78.55 | 21.89 | 11.90 |
The two contributions are complementary. The shared decoder alone removes ~24% of the parameters by replacing the dual command/parameter decoders with a single weight-shared decoder and task-specific output heads. Stacking the streamlined encoding (removing the embedding-stage MLP, letting Transformer self-attention alone capture cross-field interactions between view, command, and parameter tokens) and reducing d_model to 144 yields the main config: a 64.74% parameter reduction, the smallest file size, and the fastest inference, while staying within 0.5% of the baseline on command accuracy and 0.9% on parameter accuracy.
This repository builds upon the following awesome datasets and projects:
- Drawing2CAD (Qin et al., 2025)
- DeepCAD
- FreeCAD
- CairoSVG
If you find this project useful for your research, please use the following BibTeX entry.
@inproceedings{kim2026swiftcad,
title={SwiftCAD: Efficient Parametric CAD Generation with Shared Decoder Transformers},
author={Juyoung Kim and Seongjun Choi and Jiyeon Lim and Soomok Lee},
booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition Workshops (CVPRW)},
year={2026}
}
(BibTeX will be updated once camera-ready proceedings are published.)
