chijin 0.4.2

DEPRECATED: Use `cadrum` instead. Minimal Rust bindings for OpenCASCADE.
docs.rs failed to build chijin-0.4.2
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

Chijin

This crate has been renamed to cadrum. Please use cadrum for all new projects.

GitHub License Crates.io

Minimal Rust bindings for OpenCASCADE (OCCT 7.9.3) — a solid modeling kernel used in CAD/CAM software.

Usage

Add this to your Cargo.toml:

[dependencies]
chijin = "^0.4"
use chijin::Solid;
use glam::DVec3;

fn main() {
    let shape = Solid::box_from_corners(DVec3::ZERO, DVec3::new(10.0, 20.0, 30.0));
    let mut f = std::fs::File::create("box.step").expect("failed to create file");
    chijin::write_step(&[shape], &mut f).expect("failed to write STEP");
}

Provides safe, ergonomic wrappers around the OCC C++ kernel for:

  • Reading/writing STEP and BRep formats (stream-based, no temp files)
  • Constructing primitive shapes (box, cylinder, half-space)
  • Boolean operations (union, subtract, intersect)
  • Face/edge topology traversal
  • Meshing with customizable tolerance
  • SVG export with hidden-line removal and face colors (color feature)

Requirements

  • A C++17 compiler (GCC, Clang, or MSVC)
  • CMake (bundled feature only)

Tested with GCC 15.2.0 (MinGW-w64) and CMake 3.31.11 on Windows.

Features

  • bundled (default): Downloads and builds OCCT 7.9.3 from source during cargo build. The built library is installed into target/occt/ inside the crate directory.

  • prebuilt: Use a pre-built OCCT pointed to by the OCCT_ROOT environment variable. OCCT_ROOT can be any directory that contains OCCT headers and static libraries — including the target/occt/ generated by a previous bundled build.

    # Cargo.toml
    chijin = { version = "0.2", features = ["prebuilt"], default-features = false }
    
    # Shell (point to the bundled build output, or any other OCCT installation)
    export OCCT_ROOT=/path/to/occt
    cargo build
    
  • color (default): Colored STEP I/O via XDE (STEPCAFControl). Enables write_step_with_colors, read_step_with_colors, and per-face color on Solid. Colors are preserved through boolean operations and other transformations.

Examples

Full: build a chijin drum with colors, boolean ops, and SVG export (examples/chijin.rs)

This produces the image shown at the top of this page.

cargo run --example chijin
use chijin::{Boolean, Face, Rgb, Shape, Solid};
use glam::DVec3;
use std::f64::consts::PI;

fn chijin() -> Solid {
    // Body (cylinder): r=15, h=8, centered at origin (z=-4..+4)
    let cylinder: Solid = Solid::cylinder(DVec3::new(0.0, 0.0, -4.0), 15.0, DVec3::Z, 8.0)
        .color_paint(Rgb::from_hex("#999").unwrap());

    // Rim: cross-section polygon revolved 360° around Z,
    // mirrored across z=0 to create rims on both top and bottom.
    let cross_section = Face::from_polygon(&[
        DVec3::new(0.0, 0.0, 5.0),
        DVec3::new(0.0, 15.0, 5.0),
        DVec3::new(0.0, 17.0, 3.0),
        DVec3::new(0.0, 15.0, 4.0),
        DVec3::new(0.0, 0.0, 4.0),
        DVec3::new(0.0, 0.0, 5.0),
    ])
    .unwrap();
    let sheet = cross_section
        .revolve(DVec3::ZERO, DVec3::Z, 2.0 * PI)
        .unwrap()
        .color_paint(Rgb::from_hex("#fff").unwrap());
    let sheets = [sheet.mirrored(DVec3::ZERO, DVec3::Z), sheet];

    // Lacing blocks: 2x8x1, rotated 60° around Z, placed at y=15
    let block_proto =
        Solid::box_from_corners(DVec3::new(-1.0, -4.0, -0.5), DVec3::new(1.0, 4.0, 0.5))
            .rotate(DVec3::ZERO, DVec3::Z, 60.0_f64.to_radians())
            .translate(DVec3::new(0.0, 15.0, 0.0));

    // Lacing holes: thin cylinders through each block
    let hole_proto = Solid::cylinder(
        DVec3::new(-5.0, 16.0, -15.0), 0.7, DVec3::new(10.0, 0.0, 30.0), 30.0,
    );

    // Distribute 20 blocks and holes evenly around Z, each block in a rainbow color
    let n = 20usize;
    let mut blocks: Vec<Solid> = Vec::with_capacity(n);
    let mut holes: Vec<Solid> = Vec::with_capacity(n);
    for i in 0..n {
        let angle = 2.0 * PI * (i as f64) / (n as f64);
        let color = Rgb::from_hsv(i as f32 / n as f32, 1.0, 1.0);
        blocks.push(block_proto.clone().rotate(DVec3::ZERO, DVec3::Z, angle).color_paint(color));
        holes.push(hole_proto.clone().rotate(DVec3::ZERO, DVec3::Z, angle));
    }
    let blocks = blocks.into_iter().map(|v| vec![v])
        .reduce(|a, b| Boolean::union(&a, &b).unwrap().solids).unwrap();
    let holes = holes.into_iter().map(|v| vec![v])
        .reduce(|a, b| Boolean::union(&a, &b).unwrap().solids).unwrap();

    // Assemble with boolean operations: union, subtract, union
    let combined: Vec<Solid> = Boolean::union(&[cylinder], &sheets).unwrap().into();
    let result: Vec<Solid> = Boolean::subtract(&combined, &holes).unwrap().into();
    let result: Vec<Solid> = Boolean::union(&result, &blocks).unwrap().into();
    result.into_iter().next().unwrap()
}

fn main() {
    let result = vec![chijin()];
    std::fs::create_dir_all("out").unwrap();

    let mut f = std::fs::File::create("out/chijin.step").unwrap();
    chijin::write_step_with_colors(&result, &mut f).unwrap();

    let svg = result.to_svg(DVec3::new(1.0, 1.0, 1.0), 0.5).unwrap();
    let mut f = std::fs::File::create("out/chijin.svg").unwrap();
    std::io::Write::write_all(&mut f, svg.as_bytes()).unwrap();
}

Name

The library is named after the チヂン (chijin), a hand drum traditional to Amami Oshima, a subtropical island of southern Japan. Its form — a cylindrical body bound with a ring of wooden blocks — makes for a good test of boolean operations and revolve, which is why it serves as the library's example model. The 3D figure at the top of this page is generated entirely with chijin itself: examples/chijin.rs.

License

This project is licensed under the MIT License.