Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
Signed-off-by: Jess Frazelle <[email protected]>
  • Loading branch information
jessfraz committed Jun 20, 2024
1 parent e9aed6f commit 4ae7572
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "zoo-kcl"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
repository = "https://github.com/kittycad/kcl.py"

Expand Down
96 changes: 96 additions & 0 deletions files/lego.kcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Lego Brick
// A standard Lego brick. This is a small, plastic construction block toy that can be interlocked with other blocks to build various structures, models, and figures. There are a lot of hacks used in this code.

// Define constants
const lbumps = 5 // number of bumps long
const wbumps = 3 // number of bumps wide
const pitch = 8.0
const clearance = 0.1
const bumpDiam = 4.8
const bumpHeight = 1.8
const height = 3.2
const t = (pitch - (2 * clearance) - bumpDiam) / 2.0
const postDiam = pitch - t // works out to 6.5
const totalLength = lbumps * pitch - (2.0 * clearance)
const totalWidth = wbumps * pitch - (2.0 * clearance)
const throw_lint = 0

const lSegments = totalLength / (lbumps)
const wSegments = totalWidth / (wbumps)

// Create the plane for the pegs. This is a hack so that the pegs can be patterned along the face of the lego base.
const pegFace = {
plane: {
origin: { x: 0, y: 0, z: height },
x_axis: { x: 1, y: 0, z: 0 },
y_axis: { x: 0, y: 1, z: 0 },
z_axis: { x: 0, y: 0, z: 1 }
}
}

// Create the plane for the tubes underneath the lego. This is a hack so that the tubes can be patterned underneath the lego.
const tubeFace = {
plane: {
origin: { x: 0, y: 0, z: height - t },
x_axis: { x: 1, y: 0, z: 0 },
y_axis: { x: 0, y: 1, z: 0 },
z_axis: { x: 0, y: 0, z: 1 }
}
}

// Make the base
const s = startSketchOn('XY')
|> startProfileAt([-totalWidth / 2, -totalLength / 2], %)
|> line([totalWidth, 0], %)
|> line([0, totalLength], %)
|> line([-totalWidth, 0], %)
|> close(%)
|> extrude(height, %)

// Sketch and extrude a rectangular shape to create the shell underneath the lego. This is a hack until we have a shell function.
const shellExtrude = startSketchOn(s, "start")
|> startProfileAt([
-(totalWidth / 2 - t),
-(totalLength / 2 - t)
], %)
|> line([totalWidth - (2 * t), 0], %)
|> line([0, totalLength - (2 * t)], %)
|> line([-(totalWidth - (2 * t)), 0], %)
|> close(%)
|> extrude(-(height - t), %)

// Create the pegs on the top of the base
const peg = startSketchOn(s, 'end')
|> circle([
-(pitch*(wbumps-1)/2),
-(pitch*(lbumps-1)/2)
], bumpDiam / 2, %)
|> patternLinear2d({
axis: [1, 0],
repetitions: wbumps-1,
distance: pitch
}, %)
|> patternLinear2d({
axis: [0, 1],
repetitions: lbumps-1,
distance: pitch
}, %)
|> extrude(bumpHeight, %)

// Create the pegs on the bottom of the base
const tubePattern = startSketchOn(tubeFace)
|> circle([
-(pitch*(wbumps-1)/2-pitch/2),
-(pitch*(lbumps-1)/2-pitch/2)
], bumpDiam/2, %)
|> patternLinear2d({
axis: [1, 0],
repetitions: wbumps-2,
distance: pitch
}, %)
|> patternLinear2d({
axis: [0, 1],
repetitions: lbumps-2,
distance: pitch
}, %)
|> extrude(-bumpHeight, %)
21 changes: 16 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use anyhow::Result;
use kcl_lib::{
ast::types::FormatOptions,
executor::{ExecutorContext, ExecutorSettings},
lint::{checks, Discovered},
settings::types::UnitLength,
};
use pyo3::{pyclass, pyfunction, pymodule, types::PyModule, wrap_pyfunction, Bound, PyErr, PyResult};
use pyo3::{pyclass, pyfunction, pymethods, pymodule, types::PyModule, wrap_pyfunction, Bound, PyErr, PyResult};
use serde::{Deserialize, Serialize};

fn tokio() -> &'static tokio::runtime::Runtime {
Expand Down Expand Up @@ -62,6 +61,19 @@ impl From<kittycad::types::RawFile> for ExportFile {
}
}

#[pymethods]
impl ExportFile {
#[getter]
fn contents(&self) -> Vec<u8> {
self.contents.clone()
}

#[getter]
fn name(&self) -> String {
self.name.clone()
}
}

/// The valid types of output file formats.
#[derive(Serialize, Deserialize, PartialEq, Hash, Debug, Clone)]
#[pyclass]
Expand Down Expand Up @@ -286,11 +298,11 @@ async fn execute_and_export(

/// Format the kcl code.
#[pyfunction]
fn format(code: String, format_options: FormatOptions) -> PyResult<String> {
fn format(code: String) -> PyResult<String> {
let tokens = kcl_lib::token::lexer(&code).map_err(PyErr::from)?;
let parser = kcl_lib::parser::Parser::new(tokens);
let program = parser.ast().map_err(PyErr::from)?;
let recasted = program.recast(&format_options, 0);
let recasted = program.recast(&Default::default(), 0);

Ok(recasted)
}
Expand All @@ -316,7 +328,6 @@ fn kcl(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<ExportFile>()?;
m.add_class::<FileExportFormat>()?;
m.add_class::<UnitLength>()?;
m.add_class::<FormatOptions>()?;
m.add_class::<Discovered>()?;

// Add our functions to the module.
Expand Down
43 changes: 42 additions & 1 deletion tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,50 @@ async def test_kcl_execute_and_snapshot():
# Read from a file.
with open(os.path.join(kcl_dir_file_path, "lego.kcl"), "r") as f:
code = str(f.read())
print(code)
assert code is not None
assert len(code) > 0
image_bytes = await kcl.execute_and_snapshot(
code, kcl.UnitLength.Mm, kcl.ImageFormat.Jpeg
)
assert image_bytes is not None
assert len(image_bytes) > 0

@pytest.mark.asyncio
async def test_kcl_execute_and_export():
# Read from a file.
with open(os.path.join(kcl_dir_file_path, "lego.kcl"), "r") as f:
code = str(f.read())
assert code is not None
assert len(code) > 0
files = await kcl.execute_and_export(
code, kcl.UnitLength.Mm, kcl.FileExportFormat.Step
)
assert files is not None
assert len(files) > 0
assert files[0] is not None
assert files[0].name() is not None
assert len(files[0].name()) > 0
assert files[0].contents() is not None
assert len(files[0].contents()) > 0

def test_kcl_format():
# Read from a file.
with open(os.path.join(kcl_dir_file_path, "lego.kcl"), "r") as f:
code = str(f.read())
assert code is not None
assert len(code) > 0
formatted_code = kcl.format(code)
assert formatted_code is not None
assert len(formatted_code) > 0

def test_kcl_lint():
# Read from a file.
with open(os.path.join(kcl_dir_file_path, "lego.kcl"), "r") as f:
code = str(f.read())
assert code is not None
assert len(code) > 0
lints = kcl.lint(code)
assert lints is not None
assert len(lints) > 0


0 comments on commit 4ae7572

Please sign in to comment.