add unit functions (#3604)
* add unit functions Signed-off-by: Jess Frazelle <github@jessfraz.com> * add tests Signed-off-by: Jess Frazelle <github@jessfraz.com> * update docs Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * empty * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) --------- Signed-off-by: Jess Frazelle <github@jessfraz.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
38
docs/kcl/cm.md
Normal file
38
docs/kcl/ft.md
Normal file
38
docs/kcl/inch.md
Normal file
@ -32,17 +32,20 @@ layout: manual
|
||||
* [`chamfer`](kcl/chamfer)
|
||||
* [`circle`](kcl/circle)
|
||||
* [`close`](kcl/close)
|
||||
* [`cm`](kcl/cm)
|
||||
* [`cos`](kcl/cos)
|
||||
* [`e`](kcl/e)
|
||||
* [`extrude`](kcl/extrude)
|
||||
* [`fillet`](kcl/fillet)
|
||||
* [`floor`](kcl/floor)
|
||||
* [`ft`](kcl/ft)
|
||||
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
||||
* [`helix`](kcl/helix)
|
||||
* [`hole`](kcl/hole)
|
||||
* [`import`](kcl/import)
|
||||
* [`inch`](kcl/inch)
|
||||
* [`int`](kcl/int)
|
||||
* [`lastSegX`](kcl/lastSegX)
|
||||
* [`lastSegY`](kcl/lastSegY)
|
||||
@ -55,8 +58,10 @@ layout: manual
|
||||
* [`log`](kcl/log)
|
||||
* [`log10`](kcl/log10)
|
||||
* [`log2`](kcl/log2)
|
||||
* [`m`](kcl/m)
|
||||
* [`max`](kcl/max)
|
||||
* [`min`](kcl/min)
|
||||
* [`mm`](kcl/mm)
|
||||
* [`patternCircular2d`](kcl/patternCircular2d)
|
||||
* [`patternCircular3d`](kcl/patternCircular3d)
|
||||
* [`patternLinear2d`](kcl/patternLinear2d)
|
||||
@ -89,3 +94,4 @@ layout: manual
|
||||
* [`xLineTo`](kcl/xLineTo)
|
||||
* [`yLine`](kcl/yLine)
|
||||
* [`yLineTo`](kcl/yLineTo)
|
||||
* [`yd`](kcl/yd)
|
||||
|
38
docs/kcl/m.md
Normal file
38
docs/kcl/mm.md
Normal file
@ -55356,7 +55356,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"let n = 1.0285\nlet m = 1.0286\nassertEqual(n, m, 0.01, \"n is within the given tolerance for m\")"
|
||||
"let n = 1.0285\nlet o = 1.0286\nassertEqual(n, o, 0.01, \"n is within the given tolerance for o\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -82255,6 +82255,29 @@
|
||||
"const exampleSketch = startSketchOn('-XZ')\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cm",
|
||||
"summary": "Centimeters conversion factor for current projects units.",
|
||||
"description": "No matter what units the current project uses, this function will always return the conversion factor to centimeters.\nFor example, if the current project uses inches, this function will return `0.393701`. If the current project uses millimeters, this function will return `10`. If the current project uses centimeters, this function will return `1`.\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\nWe merely provide these functions for convenience and readability, as `10 * cm()` is more readable that your intent is \"I want 10 centimeters\" than `10 * 10`, if the project settings are in millimeters.",
|
||||
"tags": [
|
||||
"units"
|
||||
],
|
||||
"args": [],
|
||||
"returnValue": {
|
||||
"name": "",
|
||||
"type": "number",
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const totalWidth = 10 * cm()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cos",
|
||||
"summary": "Compute the cosine of a number (in radians).",
|
||||
@ -98138,6 +98161,29 @@
|
||||
"const sketch001 = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> lineTo([12, 10], %)\n |> line([floor(7.02986), 0], %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst extrude001 = extrude(5, sketch001)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ft",
|
||||
"summary": "Feet conversion factor for current projects units.",
|
||||
"description": "No matter what units the current project uses, this function will always return the conversion factor to feet.\nFor example, if the current project uses inches, this function will return `12`. If the current project uses millimeters, this function will return `304.8`. If the current project uses feet, this function will return `1`.\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\nWe merely provide these functions for convenience and readability, as `10 * ft()` is more readable that your intent is \"I want 10 feet\" than `10 * 304.8`, if the project settings are in millimeters.",
|
||||
"tags": [
|
||||
"units"
|
||||
],
|
||||
"args": [],
|
||||
"returnValue": {
|
||||
"name": "",
|
||||
"type": "number",
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const totalWidth = 10 * ft()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getNextAdjacentEdge",
|
||||
"summary": "Get the next adjacent edge to the edge given.",
|
||||
@ -117499,6 +117545,29 @@
|
||||
"const model = import(\"tests/inputs/cube.step\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inch",
|
||||
"summary": "Inches conversion factor for current projects units.",
|
||||
"description": "No matter what units the current project uses, this function will always return the conversion factor to inches.\nFor example, if the current project uses inches, this function will return `1`. If the current project uses millimeters, this function will return `25.4`.\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\nWe merely provide these functions for convenience and readability, as `10 * inch()` is more readable that your intent is \"I want 10 inches\" than `10 * 25.4`, if the project settings are in millimeters.",
|
||||
"tags": [
|
||||
"units"
|
||||
],
|
||||
"args": [],
|
||||
"returnValue": {
|
||||
"name": "",
|
||||
"type": "number",
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const totalWidth = 10 * inch()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "int",
|
||||
"summary": "Convert a number to an integer.",
|
||||
@ -137886,6 +137955,29 @@
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> line([log2(100), 0], %)\n |> line([5, 8], %)\n |> line([-10, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "m",
|
||||
"summary": "Meters conversion factor for current projects units.",
|
||||
"description": "No matter what units the current project uses, this function will always return the conversion factor to meters.\nFor example, if the current project uses inches, this function will return `39.3701`. If the current project uses millimeters, this function will return `1000`. If the current project uses meters, this function will return `1`.\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\nWe merely provide these functions for convenience and readability, as `10 * m()` is more readable that your intent is \"I want 10 meters\" than `10 * 1000`, if the project settings are in millimeters.",
|
||||
"tags": [
|
||||
"units"
|
||||
],
|
||||
"args": [],
|
||||
"returnValue": {
|
||||
"name": "",
|
||||
"type": "number",
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const totalWidth = 10 * m()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "max",
|
||||
"summary": "Compute the maximum of the given arguments.",
|
||||
@ -137958,6 +138050,29 @@
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle: 70,\n length: min(15, 31, 4, 13, 22)\n }, %)\n |> line([20, 0], %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "mm",
|
||||
"summary": "Millimeters conversion factor for current projects units.",
|
||||
"description": "No matter what units the current project uses, this function will always return the conversion factor to millimeters.\nFor example, if the current project uses inches, this function will return `(1/25.4)`. If the current project uses millimeters, this function will return `1`.\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\nWe merely provide these functions for convenience and readability, as `10 * mm()` is more readable that your intent is \"I want 10 millimeters\" than `10 * (1/25.4)`, if the project settings are in inches.",
|
||||
"tags": [
|
||||
"units"
|
||||
],
|
||||
"args": [],
|
||||
"returnValue": {
|
||||
"name": "",
|
||||
"type": "number",
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const totalWidth = 10 * mm()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "patternCircular2d",
|
||||
"summary": "Repeat a 2-dimensional sketch some number of times along a partial or",
|
||||
@ -252170,5 +252285,28 @@
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 50, length: 45 }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nconst example = extrude(5, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "yd",
|
||||
"summary": "Yards conversion factor for current projects units.",
|
||||
"description": "No matter what units the current project uses, this function will always return the conversion factor to yards.\nFor example, if the current project uses inches, this function will return `36`. If the current project uses millimeters, this function will return `914.4`. If the current project uses yards, this function will return `1`.\n**Caution**: This function is only intended to be used when you absolutely MUST have different units in your code than the project settings. Otherwise, it is a bad pattern to use this function.\nWe merely provide these functions for convenience and readability, as `10 * yd()` is more readable that your intent is \"I want 10 yards\" than `10 * 914.4`, if the project settings are in millimeters.",
|
||||
"tags": [
|
||||
"units"
|
||||
],
|
||||
"args": [],
|
||||
"returnValue": {
|
||||
"name": "",
|
||||
"type": "number",
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const totalWidth = 10 * yd()"
|
||||
]
|
||||
}
|
||||
]
|
38
docs/kcl/yd.md
Normal file
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
10
src/wasm-lib/Cargo.lock
generated
@ -1424,6 +1424,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"kittycad",
|
||||
"lazy_static",
|
||||
"measurements",
|
||||
"mime_guess",
|
||||
"parse-display",
|
||||
"pretty_assertions",
|
||||
@ -1595,6 +1596,15 @@ version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||
|
||||
[[package]]
|
||||
name = "measurements"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5b734b4e8187ea5777bc29c086f0970a27d8de42061b48f5af32cafc0ca904b"
|
||||
dependencies = [
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
|
@ -28,6 +28,7 @@ gltf-json = "1.4.1"
|
||||
image = { version = "0.25.1", default-features = false, features = ["png"] }
|
||||
kittycad = { workspace = true, features = ["clap"] }
|
||||
lazy_static = "1.5.0"
|
||||
measurements = "0.11.0"
|
||||
mime_guess = "2.0.5"
|
||||
parse-display = "0.9.1"
|
||||
pyo3 = { version = "0.22.2", optional = true }
|
||||
|
@ -2114,39 +2114,6 @@ mod tests {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn how_does_sketchgroup_serialize() {
|
||||
let sg = SketchGroup {
|
||||
id: uuid::Uuid::new_v4(),
|
||||
value: vec![],
|
||||
on: SketchSurface::Plane(Box::new(Plane {
|
||||
id: uuid::Uuid::new_v4(),
|
||||
value: PlaneType::XY,
|
||||
origin: Point3d::default(),
|
||||
x_axis: Point3d::default(),
|
||||
y_axis: Point3d::default(),
|
||||
z_axis: Point3d::default(),
|
||||
meta: Vec::new(),
|
||||
})),
|
||||
start: BasePath {
|
||||
from: [0.0, 0.0],
|
||||
to: [0.0, 0.0],
|
||||
tag: None,
|
||||
geo_meta: GeoMeta {
|
||||
id: uuid::Uuid::new_v4(),
|
||||
metadata: Metadata {
|
||||
source_range: SourceRange([0, 0]),
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: HashMap::new(),
|
||||
original_id: uuid::Uuid::new_v4(),
|
||||
meta: Vec::new(),
|
||||
};
|
||||
let jstr = serde_json::to_string_pretty(&sg).unwrap();
|
||||
println!("{jstr}");
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_execute_assign_two_variables() {
|
||||
let ast = r#"const myVar = 5
|
||||
|
@ -1,9 +1,9 @@
|
||||
use std::any::type_name;
|
||||
|
||||
use anyhow::Result;
|
||||
use kittycad::types::OkWebSocketResponseData;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use super::{shapes::SketchSurfaceOrGroup, sketch::FaceTag, FnAsArg};
|
||||
use crate::{
|
||||
ast::types::{parse_json_number_as_f64, TagDeclarator},
|
||||
errors::{KclError, KclErrorDetails},
|
||||
@ -11,6 +11,7 @@ use crate::{
|
||||
DynamicState, ExecutorContext, ExtrudeGroup, ExtrudeGroupSet, ExtrudeSurface, KclValue, Metadata,
|
||||
ProgramMemory, SketchGroup, SketchGroupSet, SketchSurface, SourceRange, TagIdentifier,
|
||||
},
|
||||
std::{shapes::SketchSurfaceOrGroup, sketch::FaceTag, FnAsArg},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -39,6 +40,25 @@ impl Args {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) async fn new_test_args() -> Result<Self> {
|
||||
use std::sync::Arc;
|
||||
|
||||
Ok(Self {
|
||||
args: Vec::new(),
|
||||
source_range: SourceRange::default(),
|
||||
ctx: ExecutorContext {
|
||||
engine: Arc::new(Box::new(crate::engine::conn_mock::EngineConnection::new().await?)),
|
||||
fs: Arc::new(crate::fs::FileManager::new()),
|
||||
stdlib: Arc::new(crate::std::StdLib::new()),
|
||||
settings: Default::default(),
|
||||
is_mock: true,
|
||||
},
|
||||
current_program_memory: ProgramMemory::default(),
|
||||
dynamic_state: DynamicState::default(),
|
||||
})
|
||||
}
|
||||
|
||||
// Add a modeling command to the batch but don't fire it right away.
|
||||
pub(crate) async fn batch_modeling_cmd(
|
||||
&self,
|
||||
|
@ -72,8 +72,8 @@ pub async fn assert_gt(args: Args) -> Result<KclValue, KclError> {
|
||||
///
|
||||
/// ```no_run
|
||||
/// let n = 1.0285
|
||||
/// let m = 1.0286
|
||||
/// assertEqual(n, m, 0.01, "n is within the given tolerance for m")
|
||||
/// let o = 1.0286
|
||||
/// assertEqual(n, o, 0.01, "n is within the given tolerance for o")
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "assertEqual",
|
||||
|
@ -18,6 +18,7 @@ pub mod shapes;
|
||||
pub mod shell;
|
||||
pub mod sketch;
|
||||
pub mod types;
|
||||
pub mod units;
|
||||
pub mod utils;
|
||||
|
||||
use std::collections::HashMap;
|
||||
@ -118,6 +119,12 @@ lazy_static! {
|
||||
Box::new(crate::std::math::Ln),
|
||||
Box::new(crate::std::math::ToDegrees),
|
||||
Box::new(crate::std::math::ToRadians),
|
||||
Box::new(crate::std::units::Mm),
|
||||
Box::new(crate::std::units::Inch),
|
||||
Box::new(crate::std::units::Ft),
|
||||
Box::new(crate::std::units::M),
|
||||
Box::new(crate::std::units::Cm),
|
||||
Box::new(crate::std::units::Yd),
|
||||
Box::new(crate::std::polar::Polar),
|
||||
Box::new(crate::std::assert::Assert),
|
||||
Box::new(crate::std::assert::AssertEqual),
|
||||
|
336
src/wasm-lib/kcl/src/std/units.rs
Normal file
@ -0,0 +1,336 @@
|
||||
//! Functions related to unitsematics.
|
||||
|
||||
use anyhow::Result;
|
||||
use derive_docs::stdlib;
|
||||
use schemars::JsonSchema;
|
||||
|
||||
use crate::{errors::KclError, executor::KclValue, settings::types::UnitLength, std::Args};
|
||||
|
||||
/// Millimeters conversion factor for current projects units.
|
||||
pub async fn mm(args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_mm(&args)?;
|
||||
|
||||
args.make_user_val_from_f64(result)
|
||||
}
|
||||
|
||||
/// Millimeters conversion factor for current projects units.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to millimeters.
|
||||
///
|
||||
/// For example, if the current project uses inches, this function will return `(1/25.4)`.
|
||||
/// If the current project uses millimeters, this function will return `1`.
|
||||
///
|
||||
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
||||
/// have different units in your code than the project settings. Otherwise, it is
|
||||
/// a bad pattern to use this function.
|
||||
///
|
||||
/// We merely provide these functions for convenience and readability, as
|
||||
/// `10 * mm()` is more readable that your intent is "I want 10 millimeters" than
|
||||
/// `10 * (1/25.4)`, if the project settings are in inches.
|
||||
///
|
||||
/// ```no_run
|
||||
/// const totalWidth = 10 * mm()
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "mm",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_mm(args: &Args) -> Result<f64, KclError> {
|
||||
match args.ctx.settings.units {
|
||||
UnitLength::Mm => Ok(1.0),
|
||||
UnitLength::In => Ok(measurements::Length::from_millimeters(1.0).as_inches()),
|
||||
UnitLength::Ft => Ok(measurements::Length::from_millimeters(1.0).as_feet()),
|
||||
UnitLength::M => Ok(measurements::Length::from_millimeters(1.0).as_meters()),
|
||||
UnitLength::Cm => Ok(measurements::Length::from_millimeters(1.0).as_centimeters()),
|
||||
UnitLength::Yd => Ok(measurements::Length::from_millimeters(1.0).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Inches conversion factor for current projects units.
|
||||
pub async fn inch(args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_inch(&args)?;
|
||||
|
||||
args.make_user_val_from_f64(result)
|
||||
}
|
||||
|
||||
/// Inches conversion factor for current projects units.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to inches.
|
||||
///
|
||||
/// For example, if the current project uses inches, this function will return `1`.
|
||||
/// If the current project uses millimeters, this function will return `25.4`.
|
||||
///
|
||||
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
||||
/// have different units in your code than the project settings. Otherwise, it is
|
||||
/// a bad pattern to use this function.
|
||||
///
|
||||
/// We merely provide these functions for convenience and readability, as
|
||||
/// `10 * inch()` is more readable that your intent is "I want 10 inches" than
|
||||
/// `10 * 25.4`, if the project settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// const totalWidth = 10 * inch()
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "inch",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_inch(args: &Args) -> Result<f64, KclError> {
|
||||
match args.ctx.settings.units {
|
||||
UnitLength::Mm => Ok(measurements::Length::from_inches(1.0).as_millimeters()),
|
||||
UnitLength::In => Ok(1.0),
|
||||
UnitLength::Ft => Ok(measurements::Length::from_inches(1.0).as_feet()),
|
||||
UnitLength::M => Ok(measurements::Length::from_inches(1.0).as_meters()),
|
||||
UnitLength::Cm => Ok(measurements::Length::from_inches(1.0).as_centimeters()),
|
||||
UnitLength::Yd => Ok(measurements::Length::from_inches(1.0).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Feet conversion factor for current projects units.
|
||||
pub async fn ft(args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_ft(&args)?;
|
||||
|
||||
args.make_user_val_from_f64(result)
|
||||
}
|
||||
|
||||
/// Feet conversion factor for current projects units.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to feet.
|
||||
///
|
||||
/// For example, if the current project uses inches, this function will return `12`.
|
||||
/// If the current project uses millimeters, this function will return `304.8`.
|
||||
/// If the current project uses feet, this function will return `1`.
|
||||
///
|
||||
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
||||
/// have different units in your code than the project settings. Otherwise, it is
|
||||
/// a bad pattern to use this function.
|
||||
///
|
||||
/// We merely provide these functions for convenience and readability, as
|
||||
/// `10 * ft()` is more readable that your intent is "I want 10 feet" than
|
||||
/// `10 * 304.8`, if the project settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// const totalWidth = 10 * ft()
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "ft",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_ft(args: &Args) -> Result<f64, KclError> {
|
||||
match args.ctx.settings.units {
|
||||
UnitLength::Mm => Ok(measurements::Length::from_feet(1.0).as_millimeters()),
|
||||
UnitLength::In => Ok(measurements::Length::from_feet(1.0).as_inches()),
|
||||
UnitLength::Ft => Ok(1.0),
|
||||
UnitLength::M => Ok(measurements::Length::from_feet(1.0).as_meters()),
|
||||
UnitLength::Cm => Ok(measurements::Length::from_feet(1.0).as_centimeters()),
|
||||
UnitLength::Yd => Ok(measurements::Length::from_feet(1.0).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Meters conversion factor for current projects units.
|
||||
pub async fn m(args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_m(&args)?;
|
||||
|
||||
args.make_user_val_from_f64(result)
|
||||
}
|
||||
|
||||
/// Meters conversion factor for current projects units.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to meters.
|
||||
///
|
||||
/// For example, if the current project uses inches, this function will return `39.3701`.
|
||||
/// If the current project uses millimeters, this function will return `1000`.
|
||||
/// If the current project uses meters, this function will return `1`.
|
||||
///
|
||||
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
||||
/// have different units in your code than the project settings. Otherwise, it is
|
||||
/// a bad pattern to use this function.
|
||||
///
|
||||
/// We merely provide these functions for convenience and readability, as
|
||||
/// `10 * m()` is more readable that your intent is "I want 10 meters" than
|
||||
/// `10 * 1000`, if the project settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// const totalWidth = 10 * m()
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "m",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_m(args: &Args) -> Result<f64, KclError> {
|
||||
match args.ctx.settings.units {
|
||||
UnitLength::Mm => Ok(measurements::Length::from_meters(1.0).as_millimeters()),
|
||||
UnitLength::In => Ok(measurements::Length::from_meters(1.0).as_inches()),
|
||||
UnitLength::Ft => Ok(measurements::Length::from_meters(1.0).as_feet()),
|
||||
UnitLength::M => Ok(1.0),
|
||||
UnitLength::Cm => Ok(measurements::Length::from_meters(1.0).as_centimeters()),
|
||||
UnitLength::Yd => Ok(measurements::Length::from_meters(1.0).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Centimeters conversion factor for current projects units.
|
||||
pub async fn cm(args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_cm(&args)?;
|
||||
|
||||
args.make_user_val_from_f64(result)
|
||||
}
|
||||
|
||||
/// Centimeters conversion factor for current projects units.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to centimeters.
|
||||
///
|
||||
/// For example, if the current project uses inches, this function will return `0.393701`.
|
||||
/// If the current project uses millimeters, this function will return `10`.
|
||||
/// If the current project uses centimeters, this function will return `1`.
|
||||
///
|
||||
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
||||
/// have different units in your code than the project settings. Otherwise, it is
|
||||
/// a bad pattern to use this function.
|
||||
///
|
||||
/// We merely provide these functions for convenience and readability, as
|
||||
/// `10 * cm()` is more readable that your intent is "I want 10 centimeters" than
|
||||
/// `10 * 10`, if the project settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// const totalWidth = 10 * cm()
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "cm",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_cm(args: &Args) -> Result<f64, KclError> {
|
||||
match args.ctx.settings.units {
|
||||
UnitLength::Mm => Ok(measurements::Length::from_centimeters(1.0).as_millimeters()),
|
||||
UnitLength::In => Ok(measurements::Length::from_centimeters(1.0).as_inches()),
|
||||
UnitLength::Ft => Ok(measurements::Length::from_centimeters(1.0).as_feet()),
|
||||
UnitLength::M => Ok(measurements::Length::from_centimeters(1.0).as_meters()),
|
||||
UnitLength::Cm => Ok(1.0),
|
||||
UnitLength::Yd => Ok(measurements::Length::from_centimeters(1.0).as_yards()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Yards conversion factor for current projects units.
|
||||
pub async fn yd(args: Args) -> Result<KclValue, KclError> {
|
||||
let result = inner_yd(&args)?;
|
||||
|
||||
args.make_user_val_from_f64(result)
|
||||
}
|
||||
|
||||
/// Yards conversion factor for current projects units.
|
||||
///
|
||||
/// No matter what units the current project uses, this function will always return the conversion
|
||||
/// factor to yards.
|
||||
///
|
||||
/// For example, if the current project uses inches, this function will return `36`.
|
||||
/// If the current project uses millimeters, this function will return `914.4`.
|
||||
/// If the current project uses yards, this function will return `1`.
|
||||
///
|
||||
/// **Caution**: This function is only intended to be used when you absolutely MUST
|
||||
/// have different units in your code than the project settings. Otherwise, it is
|
||||
/// a bad pattern to use this function.
|
||||
///
|
||||
/// We merely provide these functions for convenience and readability, as
|
||||
/// `10 * yd()` is more readable that your intent is "I want 10 yards" than
|
||||
/// `10 * 914.4`, if the project settings are in millimeters.
|
||||
///
|
||||
/// ```no_run
|
||||
/// const totalWidth = 10 * yd()
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "yd",
|
||||
tags = ["units"],
|
||||
}]
|
||||
fn inner_yd(args: &Args) -> Result<f64, KclError> {
|
||||
match args.ctx.settings.units {
|
||||
UnitLength::Mm => Ok(measurements::Length::from_yards(1.0).as_millimeters()),
|
||||
UnitLength::In => Ok(measurements::Length::from_yards(1.0).as_inches()),
|
||||
UnitLength::Ft => Ok(measurements::Length::from_yards(1.0).as_feet()),
|
||||
UnitLength::M => Ok(measurements::Length::from_yards(1.0).as_meters()),
|
||||
UnitLength::Cm => Ok(measurements::Length::from_yards(1.0).as_centimeters()),
|
||||
UnitLength::Yd => Ok(1.0),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_units_inner_mm() {
|
||||
let mut args = Args::new_test_args().await.unwrap();
|
||||
args.ctx.settings.units = UnitLength::Mm;
|
||||
let result = inner_mm(&args).unwrap();
|
||||
assert_eq!(result, 1.0);
|
||||
|
||||
args.ctx.settings.units = UnitLength::In;
|
||||
let result = inner_mm(&args).unwrap();
|
||||
assert_eq!(result, 1.0 / 25.4);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_units_inner_inch() {
|
||||
let mut args = Args::new_test_args().await.unwrap();
|
||||
args.ctx.settings.units = UnitLength::In;
|
||||
let result = inner_inch(&args).unwrap();
|
||||
assert_eq!(result, 1.0);
|
||||
|
||||
args.ctx.settings.units = UnitLength::Mm;
|
||||
let result = inner_inch(&args).unwrap();
|
||||
assert_eq!(result, 25.4);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_units_inner_ft() {
|
||||
let mut args = Args::new_test_args().await.unwrap();
|
||||
args.ctx.settings.units = UnitLength::Ft;
|
||||
let result = inner_ft(&args).unwrap();
|
||||
assert_eq!(result, 1.0);
|
||||
|
||||
args.ctx.settings.units = UnitLength::Mm;
|
||||
let result = inner_ft(&args).unwrap();
|
||||
assert_eq!(result, 304.8);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_units_inner_m() {
|
||||
let mut args = Args::new_test_args().await.unwrap();
|
||||
args.ctx.settings.units = UnitLength::M;
|
||||
let result = inner_m(&args).unwrap();
|
||||
assert_eq!(result, 1.0);
|
||||
|
||||
args.ctx.settings.units = UnitLength::Mm;
|
||||
let result = inner_m(&args).unwrap();
|
||||
assert_eq!(result, 1000.0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_units_inner_cm() {
|
||||
let mut args = Args::new_test_args().await.unwrap();
|
||||
args.ctx.settings.units = UnitLength::Cm;
|
||||
let result = inner_cm(&args).unwrap();
|
||||
assert_eq!(result, 1.0);
|
||||
|
||||
args.ctx.settings.units = UnitLength::Mm;
|
||||
let result = inner_cm(&args).unwrap();
|
||||
assert_eq!(result, 10.0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_units_inner_yd() {
|
||||
let mut args = Args::new_test_args().await.unwrap();
|
||||
args.ctx.settings.units = UnitLength::Yd;
|
||||
let result = inner_yd(&args).unwrap();
|
||||
assert_eq!(result, 1.0);
|
||||
|
||||
args.ctx.settings.units = UnitLength::Mm;
|
||||
let result = inner_yd(&args).unwrap();
|
||||
assert_eq!(result, 914.4);
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 106 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_cm0.png
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_ft0.png
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 58 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_inch0.png
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 88 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_m0.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_mm0.png
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 150 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 62 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_yd0.png
Normal file
After Width: | Height: | Size: 19 KiB |
@ -1,13 +1,13 @@
|
||||
const ANSWER = 41803
|
||||
|
||||
fn m = (s) => {
|
||||
fn t = (s) => {
|
||||
return (ANSWER * s + 12345) % 214748
|
||||
}
|
||||
|
||||
let xs = 205804
|
||||
let ys = 71816
|
||||
let ox = 35 - (m(xs) % 70)
|
||||
let oy = 35 - (m(ys) % 70)
|
||||
let ox = 35 - (t(xs) % 70)
|
||||
let oy = 35 - (t(ys) % 70)
|
||||
const r = startSketchOn('XZ')
|
||||
|> startProfileAt([ox, oy], %)
|
||||
|> line([1, 0], %)
|
||||
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 150 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |