The Problem

Design‑automation researchers need a reproducible pipeline to train a deep generative model that can synthesize CAD construction sequences and evaluate them against point‑cloud metrics. Existing open‑source CAD generators are either fragmented or lack the end‑to‑end training/evaluation scripts required for rapid experimentation.

What This Does

The repository implements the DeepCAD pipeline described in ICCV 2021. Core components are:

  • model/ – autoencoder (autoencoder.py), latent GAN (latentGAN.py) and a collection of transformer‑style layers (layers/).
  • cadlib/ – geometric primitives and conversion helpers (curves.py, extrude.py, macro.py, visualize.py).
  • trainer/ – training loops for the autoencoder (trainerAE.py) and the latent GAN (trainerLGAN.py), plus loss utilities and a learning‑rate scheduler.
  • dataset/ – parsers that turn Onshape JSON files into point clouds (json2pc.py) or vectorized CAD sequences (json2vec.py).
  • evaluation/ – Chamfer‑distance, COV, MMD, JSD calculations (evaluate_ae_cd.py, evaluate_gen_torch.py) and a wrapper script (run_eval_gen.sh).

Configuration lives in config/ (e.g. configAE.py, configLGAN.py). The top‑level scripts train.py, test.py and lgan.py orchestrate the workflow.

How It Is Wired

Entry points

  • evaluation/evaluate_gen_torch.py::main – reaches 52 functions, invoked by the shell script run_eval_gen.sh.
  • evaluation/evaluate_ae_cd.py::run – reaches 36 functions, called directly from the CLI.

Typical auto‑encoding run

  1. train.py parses --exp_name and builds an TrainerAE (trainer/trainerAE.py).
  2. TrainerAE.__init__ calls build_net (in trainer/base.py) which constructs the autoencoder (model/autoencoder.py).
  3. During each epoch TrainerAE.step invokes forward on the autoencoder, then the loss functions in trainer/loss.py.
  4. Checkpoints are saved via TrainerAE.save_ckpt, which uses utils/file_utils.py::ensure_dir.

Typical random‑generation run

  1. lgan.py builds a latent‑GAN (model/latentGAN.py) through TrainerLGAN.
  2. After training, test.py --mode dec loads the saved autoencoder checkpoint (model/autoencoder.py::load_ckpt) and decodes latent vectors produced by the GAN.
  3. The decoded CAD sequence is handed to cadlib/visualize.py::create_CAD, which ultimately calls an external OpenCASCADE command (via pythonocc).

Hot‑spot functions (most distinct callers) – eval, load_ckpt, ensure_dir, get_dataloader, angle_from_vector_to_x, transform, normalize, read_ply, forward, step, TrainerAE. Each appears in ≥ 3 call sites, so changes here have a wide blast radius.

Internal call graph – 216 resolved intra‑repo edges, no circular dependencies. The most connected module is utils/__init__ (imported by 11 modules). The deepest nesting (6 levels) occurs in cadlib/macro.py, cadlib/extrude.py, and cadlib/curves.py, making those files hard to follow.

External touch points – file I/O (utils/file_utils.py), external CAD kernel (cadlib/visualize.py invokes OpenCASCADE), and model inference (test.py calls self.net.train / self.net.eval). No database or network interaction is present.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/DeepCAD
cd DeepCAD

# Install Python deps
pip install -r requirements.txt

# Install OpenCASCADE via conda (required for cadlib.visualize)
conda install -c conda-forge pythonocc-core=7.5.1

# Download and unpack data as described in README
# (expects data/ with cad_json/ and cad_vec/)

# Train the autoencoder
python train.py --exp_name myDeepCAD -g 0

# Encode the whole training set (needed before latent GAN)
python test.py --exp_name myDeepCAD --mode enc --ckpt 1000 -g 0

# Train the latent GAN
python lgan.py --exp_name myDeepCAD --ae_ckpt 1000 -g 0

# Generate samples and decode them
python test.py --exp_name myDeepCAD --mode dec \
    --ckpt 1000 \
    --z_path proj_log/myDeepCAD/lgan_1000/results/fake_z_ckpt200000_num9000.h5 -g 0

# Evaluate generated point clouds
cd evaluation
sh run_eval_gen.sh ../proj_log/myDeepCAD/lgan_1000/results/fake_z_ckpt200000_num9000_dec 1000 0

All configuration flags are defined in config/configAE.py and config/configLGAN.py. Adjust learning rates, batch sizes, or GPU IDs there.

Real‑World Use

A CAD‑research team can plug their own Onshape‑derived JSON files into dataset/json2vec.py to produce the vector representation expected by the autoencoder. After training, they call test.py to synthesize new CAD sequences, then feed the resulting .h5 files to a downstream renderer or downstream downstream downstream (e.g., a mechanical simulation pipeline).

Code Health & Issues

  • High – Add a test suite – 46 source files, only a single test.py that is a script, not a unit‑test framework.
  • High – Add CI workflow – No .github/ CI configuration; builds and tests are never gated.
  • Medium – Enable Dependabot – Only requirements.txt is present; no automated dependency updates.

Additional hygiene notes: a LICENSE file exists, but there is no lockfile (e.g., requirements.txt without a requirements.lock), and no Dockerfile.

The Bottom Line

DeepCAD supplies a complete research‑grade pipeline for learning generative CAD models, with clearly separated model, data‑processing, and evaluation modules. The code is functional but suffers from deep nesting, duplicated boiler‑plate, and a lack of automated testing or CI, which raises maintenance risk for production use. It is best suited for academic experimentation where the existing scripts can be run as‑is and the code can be refactored incrementally.