Chamfer is just a fancy fillet so easy to add (#2681)
* add chamfer Signed-off-by: Jess Frazelle <github@jessfraz.com> * generate docs Signed-off-by: Jess Frazelle <github@jessfraz.com> * generate docs Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
323
docs/kcl/chamfer.md
Normal file
323
docs/kcl/chamfer.md
Normal file
File diff suppressed because one or more lines are too long
@ -23,6 +23,7 @@ layout: manual
|
||||
* [`atan`](kcl/atan)
|
||||
* [`bezierCurve`](kcl/bezierCurve)
|
||||
* [`ceil`](kcl/ceil)
|
||||
* [`chamfer`](kcl/chamfer)
|
||||
* [`circle`](kcl/circle)
|
||||
* [`close`](kcl/close)
|
||||
* [`cos`](kcl/cos)
|
||||
|
1563
docs/kcl/std.json
1563
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
2
src/wasm-lib/Cargo.lock
generated
2
src/wasm-lib/Cargo.lock
generated
@ -1369,7 +1369,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-lib"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"approx",
|
||||
|
126
src/wasm-lib/kcl/src/std/chamfer.rs
Normal file
126
src/wasm-lib/kcl/src/std/chamfer.rs
Normal file
@ -0,0 +1,126 @@
|
||||
//! Standard library chamfers.
|
||||
|
||||
use anyhow::Result;
|
||||
use derive_docs::stdlib;
|
||||
use kittycad::types::ModelingCmd;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
executor::{ExtrudeGroup, MemoryItem},
|
||||
std::Args,
|
||||
};
|
||||
|
||||
pub(crate) const DEFAULT_TOLERANCE: f64 = 0.0000001;
|
||||
|
||||
/// Data for chamfers.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ChamferData {
|
||||
/// The radius of the chamfer.
|
||||
pub radius: f64,
|
||||
/// The tags of the paths you want to chamfer.
|
||||
pub tags: Vec<EdgeReference>,
|
||||
}
|
||||
|
||||
/// A string or a uuid.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Ord, PartialOrd, Eq, Hash)]
|
||||
#[ts(export)]
|
||||
#[serde(untagged)]
|
||||
pub enum EdgeReference {
|
||||
/// A uuid of an edge.
|
||||
Uuid(uuid::Uuid),
|
||||
/// A tag name of an edge.
|
||||
Tag(String),
|
||||
}
|
||||
|
||||
/// Create chamfers on tagged paths.
|
||||
pub async fn chamfer(args: Args) -> Result<MemoryItem, KclError> {
|
||||
let (data, extrude_group): (ChamferData, Box<ExtrudeGroup>) = args.get_data_and_extrude_group()?;
|
||||
|
||||
let extrude_group = inner_chamfer(data, extrude_group, args).await?;
|
||||
Ok(MemoryItem::ExtrudeGroup(extrude_group))
|
||||
}
|
||||
|
||||
/// Create chamfers on tagged paths.
|
||||
///
|
||||
/// ```no_run
|
||||
/// const width = 20
|
||||
/// const length = 10
|
||||
/// const thickness = 1
|
||||
/// const chamferRadius = 2
|
||||
///
|
||||
/// const mountingPlateSketch = startSketchOn("XY")
|
||||
/// |> startProfileAt([-width/2, -length/2], %)
|
||||
/// |> lineTo([width/2, -length/2], %, 'edge1')
|
||||
/// |> lineTo([width/2, length/2], %, 'edge2')
|
||||
/// |> lineTo([-width/2, length/2], %, 'edge3')
|
||||
/// |> close(%, 'edge4')
|
||||
///
|
||||
/// const mountingPlate = extrude(thickness, mountingPlateSketch)
|
||||
/// |> chamfer({
|
||||
/// radius: chamferRadius,
|
||||
/// tags: [
|
||||
/// getNextAdjacentEdge('edge1', %),
|
||||
/// getNextAdjacentEdge('edge2', %),
|
||||
/// getNextAdjacentEdge('edge3', %),
|
||||
/// getNextAdjacentEdge('edge4', %)
|
||||
/// ],
|
||||
/// }, %)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "chamfer",
|
||||
}]
|
||||
async fn inner_chamfer(
|
||||
data: ChamferData,
|
||||
extrude_group: Box<ExtrudeGroup>,
|
||||
args: Args,
|
||||
) -> Result<Box<ExtrudeGroup>, KclError> {
|
||||
// Check if tags contains any duplicate values.
|
||||
let mut tags = data.tags.clone();
|
||||
tags.sort();
|
||||
tags.dedup();
|
||||
if tags.len() != data.tags.len() {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: "Duplicate tags are not allowed.".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
|
||||
for tag in data.tags {
|
||||
let edge_id = match tag {
|
||||
EdgeReference::Uuid(uuid) => uuid,
|
||||
EdgeReference::Tag(tag) => {
|
||||
extrude_group
|
||||
.sketch_group_values
|
||||
.iter()
|
||||
.find(|p| p.get_name() == tag)
|
||||
.ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("No edge found with tag: `{}`", tag),
|
||||
source_ranges: vec![args.source_range],
|
||||
})
|
||||
})?
|
||||
.get_base()
|
||||
.geo_meta
|
||||
.id
|
||||
}
|
||||
};
|
||||
|
||||
args.send_modeling_cmd(
|
||||
uuid::Uuid::new_v4(),
|
||||
ModelingCmd::Solid3DFilletEdge {
|
||||
edge_id,
|
||||
object_id: extrude_group.id,
|
||||
radius: data.radius,
|
||||
tolerance: DEFAULT_TOLERANCE, // We can let the user set this in the future.
|
||||
cut_type: Some(kittycad::types::CutType::Chamfer),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(extrude_group)
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
//! Functions implemented for language execution.
|
||||
|
||||
pub mod chamfer;
|
||||
pub mod extrude;
|
||||
pub mod fillet;
|
||||
pub mod helix;
|
||||
@ -81,6 +82,7 @@ lazy_static! {
|
||||
Box::new(crate::std::patterns::PatternLinear3D),
|
||||
Box::new(crate::std::patterns::PatternCircular2D),
|
||||
Box::new(crate::std::patterns::PatternCircular3D),
|
||||
Box::new(crate::std::chamfer::Chamfer),
|
||||
Box::new(crate::std::fillet::Fillet),
|
||||
Box::new(crate::std::fillet::GetOppositeEdge),
|
||||
Box::new(crate::std::fillet::GetNextAdjacentEdge),
|
||||
|
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_chamfer0.png
Normal file
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_chamfer0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 98 KiB |
Reference in New Issue
Block a user