Fix lazy fillet (#3176)

* WIP: Fix lazy fillet

* cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
This commit is contained in:
Jonathan Tran
2024-07-29 23:22:52 -04:00
committed by GitHub
parent 789fb83a5d
commit 1c44b01d16
9 changed files with 253 additions and 57 deletions

View File

@ -23,8 +23,8 @@ use crate::{
docs::StdLibFn,
errors::{KclError, KclErrorDetails},
executor::{
BodyType, ExecutorContext, MemoryItem, Metadata, PipeInfo, ProgramMemory, SourceRange, StatementKind,
TagEngineInfo, TagIdentifier, UserVal,
BodyType, DynamicState, ExecutorContext, MemoryItem, Metadata, PipeInfo, ProgramMemory, SourceRange,
StatementKind, TagEngineInfo, TagIdentifier, UserVal,
},
parser::PIPE_OPERATOR,
std::{kcl_stdlib::KclStdLibFn, FunctionKind},
@ -918,6 +918,7 @@ impl BinaryPart {
pub async fn get_result(
&self,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
@ -928,10 +929,16 @@ impl BinaryPart {
Ok(value.clone())
}
BinaryPart::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, pipe_info, ctx).await
binary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await
}
BinaryPart::CallExpression(call_expression) => {
call_expression.execute(memory, dynamic_state, pipe_info, ctx).await
}
BinaryPart::UnaryExpression(unary_expression) => {
unary_expression.get_result(memory, dynamic_state, pipe_info, ctx).await
}
BinaryPart::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, ctx).await,
BinaryPart::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, ctx).await,
BinaryPart::MemberExpression(member_expression) => member_expression.get_result(memory),
}
}
@ -1311,6 +1318,7 @@ impl CallExpression {
pub async fn execute(
&self,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
@ -1323,7 +1331,14 @@ impl CallExpression {
source_range: SourceRange([arg.start(), arg.end()]),
};
let result = ctx
.arg_into_mem_item(arg, memory, pipe_info, &metadata, StatementKind::Expression)
.arg_into_mem_item(
arg,
memory,
dynamic_state,
pipe_info,
&metadata,
StatementKind::Expression,
)
.await?;
fn_args.push(result);
}
@ -1331,7 +1346,8 @@ impl CallExpression {
match ctx.stdlib.get_either(&self.callee.name) {
FunctionKind::Core(func) => {
// Attempt to call the function.
let args = crate::std::Args::new(fn_args, self.into(), ctx.clone(), memory.clone());
let args =
crate::std::Args::new(fn_args, self.into(), ctx.clone(), memory.clone(), dynamic_state.clone());
let mut result = func.std_lib_fn()(args).await?;
// If the return result is a sketch group or extrude group, we want to update the
@ -1433,9 +1449,14 @@ impl CallExpression {
}
}
let mut fn_dynamic_state = dynamic_state.clone();
// Call the stdlib function
let p = func.function().clone().body;
let results = match ctx.inner_execute(&p, &mut fn_memory, BodyType::Block).await {
let results = match ctx
.inner_execute(&p, &mut fn_memory, &mut fn_dynamic_state, BodyType::Block)
.await
{
Ok(results) => results,
Err(err) => {
// We need to override the source ranges so we don't get the embedded kcl
@ -1456,10 +1477,14 @@ impl CallExpression {
}
FunctionKind::UserDefined => {
let func = memory.get(&fn_name, self.into())?;
let result = func.call_fn(fn_args, ctx.clone()).await.map_err(|e| {
// Add the call expression to the source ranges.
e.add_source_ranges(vec![self.into()])
})?;
let fn_dynamic_state = dynamic_state.merge(memory);
let result = func
.call_fn(fn_args, &fn_dynamic_state, ctx.clone())
.await
.map_err(|e| {
// Add the call expression to the source ranges.
e.add_source_ranges(vec![self.into()])
})?;
let result = result.ok_or_else(|| {
KclError::UndefinedValue(KclErrorDetails {
@ -2295,6 +2320,7 @@ impl ArrayExpression {
pub async fn execute(
&self,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
@ -2310,13 +2336,29 @@ impl ArrayExpression {
value.clone()
}
Value::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, pipe_info, ctx).await?
binary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => {
call_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::UnaryExpression(unary_expression) => {
unary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::ObjectExpression(object_expression) => {
object_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::ArrayExpression(array_expression) => {
array_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::PipeExpression(pipe_expression) => {
pipe_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, ctx).await?,
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, ctx).await?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, ctx).await?,
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, ctx).await?,
Value::PipeExpression(pipe_expression) => pipe_expression.get_result(memory, pipe_info, ctx).await?,
Value::PipeSubstitution(pipe_substitution) => {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("PipeSubstitution not implemented here: {:?}", pipe_substitution),
@ -2465,6 +2507,7 @@ impl ObjectExpression {
pub async fn execute(
&self,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
@ -2479,13 +2522,29 @@ impl ObjectExpression {
value.clone()
}
Value::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, pipe_info, ctx).await?
binary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => {
call_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::UnaryExpression(unary_expression) => {
unary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::ObjectExpression(object_expression) => {
object_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::ArrayExpression(array_expression) => {
array_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::PipeExpression(pipe_expression) => {
pipe_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, ctx).await?,
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, ctx).await?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, ctx).await?,
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, ctx).await?,
Value::PipeExpression(pipe_expression) => pipe_expression.get_result(memory, pipe_info, ctx).await?,
Value::MemberExpression(member_expression) => member_expression.get_result(memory)?,
Value::PipeSubstitution(pipe_substitution) => {
return Err(KclError::Semantic(KclErrorDetails {
@ -2947,11 +3006,20 @@ impl BinaryExpression {
pub async fn get_result(
&self,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
let left_json_value = self.left.get_result(memory, pipe_info, ctx).await?.get_json_value()?;
let right_json_value = self.right.get_result(memory, pipe_info, ctx).await?.get_json_value()?;
let left_json_value = self
.left
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
.get_json_value()?;
let right_json_value = self
.right
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
.get_json_value()?;
// First check if we are doing string concatenation.
if self.operator == BinaryOperator::Add {
@ -3156,13 +3224,14 @@ impl UnaryExpression {
pub async fn get_result(
&self,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
let num = parse_json_number_as_f64(
&self
.argument
.get_result(memory, pipe_info, ctx)
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
.get_json_value()?,
self.into(),
@ -3333,10 +3402,11 @@ impl PipeExpression {
pub async fn get_result(
&self,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
execute_pipe_body(memory, &self.body, pipe_info, self.into(), ctx).await
execute_pipe_body(memory, dynamic_state, &self.body, pipe_info, self.into(), ctx).await
}
/// Rename all identifiers that have the old name to the new given name.
@ -3350,6 +3420,7 @@ impl PipeExpression {
#[async_recursion::async_recursion]
async fn execute_pipe_body(
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
body: &[Value],
pipe_info: &PipeInfo,
source_range: SourceRange,
@ -3370,7 +3441,14 @@ async fn execute_pipe_body(
source_range: SourceRange([first.start(), first.end()]),
};
let output = ctx
.arg_into_mem_item(first, memory, pipe_info, &meta, StatementKind::Expression)
.arg_into_mem_item(
first,
memory,
dynamic_state,
pipe_info,
&meta,
StatementKind::Expression,
)
.await?;
// Now that we've evaluated the first child expression in the pipeline, following child expressions
// should use the previous child expression for %.
@ -3381,9 +3459,15 @@ async fn execute_pipe_body(
for expression in body {
let output = match expression {
Value::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, &new_pipe_info, ctx).await?
binary_expression
.get_result(memory, dynamic_state, &new_pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => {
call_expression
.execute(memory, dynamic_state, &new_pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => call_expression.execute(memory, &new_pipe_info, ctx).await?,
Value::Identifier(identifier) => memory.get(&identifier.name, identifier.into())?.clone(),
_ => {
// Return an error this should not happen.

View File

@ -195,6 +195,50 @@ impl Environment {
}
}
/// Dynamic state that depends on the dynamic flow of the program, like the call
/// stack. If the language had exceptions, for example, you could store the
/// stack of exception handlers here.
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, ts_rs::TS, JsonSchema)]
pub struct DynamicState {
pub extrude_group_ids: Vec<ExtrudeGroupLazyIds>,
}
impl DynamicState {
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn merge(&self, memory: &ProgramMemory) -> Self {
let mut merged = self.clone();
merged.append(memory);
merged
}
pub fn append(&mut self, memory: &ProgramMemory) {
for env in &memory.environments {
for item in env.bindings.values() {
if let MemoryItem::ExtrudeGroup(eg) = item {
self.extrude_group_ids.push(ExtrudeGroupLazyIds::from(eg.as_ref()));
}
}
}
}
pub fn fillet_or_chamfer_ids_on_sketch_group(&self, sketch_group_id: uuid::Uuid) -> Vec<uuid::Uuid> {
self.extrude_group_ids
.iter()
.flat_map(|eg| {
if eg.sketch_group_id == sketch_group_id {
eg.fillet_or_chamfers.clone()
} else {
Vec::new()
}
})
.collect::<Vec<_>>()
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase", untagged)]
@ -623,6 +667,7 @@ pub type MemoryFunction =
memory: ProgramMemory,
expression: Box<FunctionExpression>,
metadata: Vec<Metadata>,
dynamic_state: DynamicState,
ctx: ExecutorContext,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<ProgramReturn>, KclError>> + Send>>;
@ -632,6 +677,7 @@ fn force_memory_function<
ProgramMemory,
Box<FunctionExpression>,
Vec<Metadata>,
DynamicState,
ExecutorContext,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<ProgramReturn>, KclError>> + Send>>,
>(
@ -800,6 +846,7 @@ impl MemoryItem {
pub async fn call_fn(
&self,
args: Vec<MemoryItem>,
dynamic_state: &DynamicState,
ctx: ExecutorContext,
) -> Result<Option<ProgramReturn>, KclError> {
let MemoryItem::Function {
@ -825,6 +872,7 @@ impl MemoryItem {
closure_memory.as_ref().clone(),
expression.clone(),
meta.clone(),
dynamic_state.clone(),
ctx,
)
.await
@ -997,6 +1045,27 @@ impl ExtrudeGroup {
}
}
/// An extrude group ID and its fillet and chamfer IDs. This is needed for lazy
/// fillet evaluation.
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, ts_rs::TS, JsonSchema)]
pub struct ExtrudeGroupLazyIds {
pub extrude_group_id: uuid::Uuid,
pub sketch_group_id: uuid::Uuid,
/// Chamfers or fillets on this extrude group.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub fillet_or_chamfers: Vec<uuid::Uuid>,
}
impl From<&ExtrudeGroup> for ExtrudeGroupLazyIds {
fn from(eg: &ExtrudeGroup) -> Self {
Self {
extrude_group_id: eg.id,
sketch_group_id: eg.sketch_group.id,
fillet_or_chamfers: eg.fillet_or_chamfers.iter().map(|foc| foc.id()).collect(),
}
}
}
/// A fillet or a chamfer.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
@ -1621,8 +1690,14 @@ impl ExecutorContext {
} else {
Default::default()
};
self.inner_execute(program, &mut memory, crate::executor::BodyType::Root)
.await
let mut dynamic_state = DynamicState::default();
self.inner_execute(
program,
&mut memory,
&mut dynamic_state,
crate::executor::BodyType::Root,
)
.await
}
/// Execute an AST's program.
@ -1631,6 +1706,7 @@ impl ExecutorContext {
&self,
program: &crate::ast::types::Program,
memory: &mut ProgramMemory,
dynamic_state: &mut DynamicState,
body_type: BodyType,
) -> Result<ProgramMemory, KclError> {
let pipe_info = PipeInfo::default();
@ -1640,9 +1716,9 @@ impl ExecutorContext {
match statement {
BodyItem::ExpressionStatement(expression_statement) => {
if let Value::PipeExpression(pipe_expr) = &expression_statement.expression {
pipe_expr.get_result(memory, &pipe_info, self).await?;
pipe_expr.get_result(memory, dynamic_state, &pipe_info, self).await?;
} else if let Value::CallExpression(call_expr) = &expression_statement.expression {
call_expr.execute(memory, &pipe_info, self).await?;
call_expr.execute(memory, dynamic_state, &pipe_info, self).await?;
}
}
BodyItem::VariableDeclaration(variable_declaration) => {
@ -1655,6 +1731,7 @@ impl ExecutorContext {
.arg_into_mem_item(
&declaration.init,
memory,
dynamic_state,
&pipe_info,
&metadata,
StatementKind::Declaration { name: &var_name },
@ -1665,11 +1742,11 @@ impl ExecutorContext {
}
BodyItem::ReturnStatement(return_statement) => match &return_statement.argument {
Value::BinaryExpression(bin_expr) => {
let result = bin_expr.get_result(memory, &pipe_info, self).await?;
let result = bin_expr.get_result(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::UnaryExpression(unary_expr) => {
let result = unary_expr.get_result(memory, &pipe_info, self).await?;
let result = unary_expr.get_result(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::Identifier(identifier) => {
@ -1683,15 +1760,15 @@ impl ExecutorContext {
memory.return_ = Some(ProgramReturn::Value(tag.into()));
}
Value::ArrayExpression(array_expr) => {
let result = array_expr.execute(memory, &pipe_info, self).await?;
let result = array_expr.execute(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::ObjectExpression(obj_expr) => {
let result = obj_expr.execute(memory, &pipe_info, self).await?;
let result = obj_expr.execute(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::CallExpression(call_expr) => {
let result = call_expr.execute(memory, &pipe_info, self).await?;
let result = call_expr.execute(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::MemberExpression(member_expr) => {
@ -1699,7 +1776,7 @@ impl ExecutorContext {
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::PipeExpression(pipe_expr) => {
let result = pipe_expr.get_result(memory, &pipe_info, self).await?;
let result = pipe_expr.get_result(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::PipeSubstitution(_) => {}
@ -1730,6 +1807,7 @@ impl ExecutorContext {
&self,
init: &Value,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
metadata: &Metadata,
statement_kind: StatementKind<'a>,
@ -1742,13 +1820,18 @@ impl ExecutorContext {
let value = memory.get(&identifier.name, identifier.into())?;
value.clone()
}
Value::BinaryExpression(binary_expression) => binary_expression.get_result(memory, pipe_info, self).await?,
Value::BinaryExpression(binary_expression) => {
binary_expression
.get_result(memory, dynamic_state, pipe_info, self)
.await?
}
Value::FunctionExpression(function_expression) => {
let mem_func = force_memory_function(
|args: Vec<MemoryItem>,
memory: ProgramMemory,
function_expression: Box<FunctionExpression>,
_metadata: Vec<Metadata>,
mut dynamic_state: DynamicState,
ctx: ExecutorContext| {
Box::pin(async move {
// Create a new environment to execute the function
@ -1762,7 +1845,12 @@ impl ExecutorContext {
let mut fn_memory = assign_args_to_params(&function_expression, args, body_memory)?;
let result = ctx
.inner_execute(&function_expression.body, &mut fn_memory, BodyType::Block)
.inner_execute(
&function_expression.body,
&mut fn_memory,
&mut dynamic_state,
BodyType::Block,
)
.await?;
Ok(result.return_)
@ -1779,8 +1867,14 @@ impl ExecutorContext {
memory: Box::new(memory.clone()),
}
}
Value::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, self).await?,
Value::PipeExpression(pipe_expression) => pipe_expression.get_result(memory, pipe_info, self).await?,
Value::CallExpression(call_expression) => {
call_expression.execute(memory, dynamic_state, pipe_info, self).await?
}
Value::PipeExpression(pipe_expression) => {
pipe_expression
.get_result(memory, dynamic_state, pipe_info, self)
.await?
}
Value::PipeSubstitution(pipe_substitution) => match statement_kind {
StatementKind::Declaration { name } => {
let message = format!(
@ -1802,10 +1896,20 @@ impl ExecutorContext {
}
},
},
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, self).await?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, self).await?,
Value::ArrayExpression(array_expression) => {
array_expression.execute(memory, dynamic_state, pipe_info, self).await?
}
Value::ObjectExpression(object_expression) => {
object_expression
.execute(memory, dynamic_state, pipe_info, self)
.await?
}
Value::MemberExpression(member_expression) => member_expression.get_result(memory)?,
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, self).await?,
Value::UnaryExpression(unary_expression) => {
unary_expression
.get_result(memory, dynamic_state, pipe_info, self)
.await?
}
};
Ok(item)
}

View File

@ -3,13 +3,14 @@ use schemars::JsonSchema;
use crate::{
ast::types::FunctionExpression,
errors::KclError,
executor::{ExecutorContext, MemoryFunction, MemoryItem, Metadata, ProgramMemory, ProgramReturn},
executor::{DynamicState, ExecutorContext, MemoryFunction, MemoryItem, Metadata, ProgramMemory, ProgramReturn},
};
/// A function being used as a parameter into a stdlib function.
pub struct FunctionParam<'a> {
pub inner: &'a MemoryFunction,
pub memory: ProgramMemory,
pub dynamic_state: DynamicState,
pub fn_expr: Box<FunctionExpression>,
pub meta: Vec<Metadata>,
pub ctx: ExecutorContext,
@ -22,6 +23,7 @@ impl<'a> FunctionParam<'a> {
self.memory.clone(),
self.fn_expr.clone(),
self.meta.clone(),
self.dynamic_state.clone(),
self.ctx.clone(),
)
.await

View File

@ -8,8 +8,8 @@ use crate::{
ast::types::{parse_json_number_as_f64, TagDeclarator},
errors::{KclError, KclErrorDetails},
executor::{
ExecutorContext, ExtrudeGroup, ExtrudeGroupSet, ExtrudeSurface, MemoryItem, Metadata, ProgramMemory,
SketchGroup, SketchGroupSet, SketchSurface, SourceRange, TagIdentifier,
DynamicState, ExecutorContext, ExtrudeGroup, ExtrudeGroupSet, ExtrudeSurface, MemoryItem, Metadata,
ProgramMemory, SketchGroup, SketchGroupSet, SketchSurface, SourceRange, TagIdentifier,
},
};
@ -19,6 +19,7 @@ pub struct Args {
pub source_range: SourceRange,
pub ctx: ExecutorContext,
pub current_program_memory: ProgramMemory,
pub dynamic_state: DynamicState,
}
impl Args {
@ -27,12 +28,14 @@ impl Args {
source_range: SourceRange,
ctx: ExecutorContext,
current_program_memory: ProgramMemory,
dynamic_state: DynamicState,
) -> Self {
Self {
args,
source_range,
ctx,
current_program_memory,
dynamic_state,
}
}
@ -130,6 +133,10 @@ impl Args {
.iter()
.flat_map(|eg| eg.get_all_fillet_or_chamfer_ids()),
);
ids.extend(
self.dynamic_state
.fillet_or_chamfer_ids_on_sketch_group(sketch_group_id),
);
traversed_sketch_groups.push(sketch_group_id);
}

View File

@ -88,6 +88,7 @@ pub async fn pattern_transform(args: Args) -> Result<MemoryItem, KclError> {
meta: vec![args.source_range.into()],
ctx: args.ctx.clone(),
memory: *transform.memory,
dynamic_state: args.dynamic_state.clone(),
},
extr,
&args,

View File

@ -24,7 +24,7 @@ const plumbus1 =
|> extrude(plumbusLen, %)
|> fillet({
radius: 5,
tags: [c1.tags.arc_tag, getOppositeEdge(c1.tags.arc_tag)]
tags: [c1.tags.arc_tag]
}, %)
const c2 = circl(200, a)
const plumbus0 =
@ -32,7 +32,7 @@ const plumbus0 =
|> extrude(plumbusLen, %)
|> fillet({
radius: 5,
tags: [c2.tags.arc_tag, getOppositeEdge(c2.tags.arc_tag)]
tags: [c2.tags.arc_tag]
}, %)

View File

@ -97,7 +97,6 @@ async fn serial_test_pipe_as_arg() {
}
#[tokio::test(flavor = "multi_thread")]
#[ignore] // We need to figure out why this broke even using scoped tags isn't working.
async fn serial_test_pentagon_fillet_sugar() {
let code = include_str!("inputs/pentagon_fillet_sugar.kcl");
let result = execute_and_snapshot(code, UnitLength::Cm).await.unwrap();
@ -1701,7 +1700,6 @@ const part002 = startSketchOn(part001, 'end')
}
#[tokio::test(flavor = "multi_thread")]
#[ignore] // We need to figure out why this broke even using scoped tags isn't working.
async fn serial_test_plumbus_fillets() {
let code = r#"fn make_circle = (ext, face, pos, radius) => {
const sg = startSketchOn(ext, face)
@ -1748,7 +1746,7 @@ const plumbus0 = circle0
|> extrude(10, %)
|> fillet({
radius: 0.5,
tags: [circle0.tags.arc1, getOppositeEdge(circle0.tags.arc1)]
tags: [circle0.tags.arc1]
}, %)
const circle1 = make_circle(p, p.sketchGroup.tags.b, [0, 0], 2.5)
@ -1756,7 +1754,7 @@ const plumbus1 = circle1
|> extrude(10, %)
|> fillet({
radius: 0.5,
tags: [circle1.tags.arc1, getOppositeEdge(circle1.tags.arc1)]
tags: [circle1.tags.arc1]
}, %)
"#;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 131 KiB