Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions rust/kcl-lib/src/execution/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,30 @@
}
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS)]
#[ts(export_to = "Artifact.ts")]
#[serde(rename_all = "camelCase")]
pub struct CompositeSolid {
pub id: ArtifactId,
pub sub_type: CompositeSolidSubType,
/// Constituent solids of the composite solid.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub solid_ids: Vec<ArtifactId>,
/// Tool solids used for asymmetric operations like subtract.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tool_ids: Vec<ArtifactId>,
pub code_ref: CodeRef,
}

#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS)]
#[ts(export_to = "Artifact.ts")]
#[serde(rename_all = "camelCase")]
pub enum CompositeSolidSubType {
Intersect,
Subtract,
Union,
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS)]
#[ts(export_to = "Artifact.ts")]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -318,6 +342,7 @@
#[ts(export_to = "Artifact.ts")]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum Artifact {
CompositeSolid(CompositeSolid),
Plane(Plane),
Path(Path),
Segment(Segment),
Expand All @@ -336,6 +361,7 @@
impl Artifact {
pub(crate) fn id(&self) -> ArtifactId {
match self {
Artifact::CompositeSolid(a) => a.id,
Artifact::Plane(a) => a.id,
Artifact::Path(a) => a.id,
Artifact::Segment(a) => a.id,
Expand All @@ -355,6 +381,7 @@
#[expect(dead_code)]
pub(crate) fn code_ref(&self) -> Option<&CodeRef> {
match self {
Artifact::CompositeSolid(a) => Some(&a.code_ref),

Check warning on line 384 in rust/kcl-lib/src/execution/artifact.rs

View check run for this annotation

Codecov / codecov/patch

rust/kcl-lib/src/execution/artifact.rs#L384

Added line #L384 was not covered by tests
Artifact::Plane(a) => Some(&a.code_ref),
Artifact::Path(a) => Some(&a.code_ref),
Artifact::Segment(a) => Some(&a.code_ref),
Expand All @@ -375,6 +402,7 @@
/// type, return the new artifact which should be used as a replacement.
fn merge(&mut self, new: Artifact) -> Option<Artifact> {
match self {
Artifact::CompositeSolid(a) => a.merge(new),

Check warning on line 405 in rust/kcl-lib/src/execution/artifact.rs

View check run for this annotation

Codecov / codecov/patch

rust/kcl-lib/src/execution/artifact.rs#L405

Added line #L405 was not covered by tests
Artifact::Plane(a) => a.merge(new),
Artifact::Path(a) => a.merge(new),
Artifact::Segment(a) => a.merge(new),
Expand All @@ -392,6 +420,18 @@
}
}

impl CompositeSolid {
fn merge(&mut self, new: Artifact) -> Option<Artifact> {
let Artifact::CompositeSolid(new) = new else {
return Some(new);

Check warning on line 426 in rust/kcl-lib/src/execution/artifact.rs

View check run for this annotation

Codecov / codecov/patch

rust/kcl-lib/src/execution/artifact.rs#L424-L426

Added lines #L424 - L426 were not covered by tests
};
merge_ids(&mut self.solid_ids, new.solid_ids);
merge_ids(&mut self.tool_ids, new.tool_ids);

None
}

Check warning on line 432 in rust/kcl-lib/src/execution/artifact.rs

View check run for this annotation

Codecov / codecov/patch

rust/kcl-lib/src/execution/artifact.rs#L428-L432

Added lines #L428 - L432 were not covered by tests
}

impl Plane {
fn merge(&mut self, new: Artifact) -> Option<Artifact> {
let Artifact::Plane(new) = new else {
Expand Down Expand Up @@ -1047,6 +1087,85 @@
// the helix here, but it's not useful right now.
return Ok(return_arr);
}
ModelingCmd::BooleanIntersection(_) | ModelingCmd::BooleanSubtract(_) | ModelingCmd::BooleanUnion(_) => {
let (sub_type, solid_ids, tool_ids) = match cmd {
ModelingCmd::BooleanIntersection(intersection) => {
let solid_ids = intersection
.solid_ids
.iter()
.copied()
.map(ArtifactId::new)
.collect::<Vec<_>>();
(CompositeSolidSubType::Intersect, solid_ids, Vec::new())
}
ModelingCmd::BooleanSubtract(subtract) => {
let solid_ids = subtract
.target_ids
.iter()
.copied()
.map(ArtifactId::new)
.collect::<Vec<_>>();
let tool_ids = subtract
.tool_ids
.iter()
.copied()
.map(ArtifactId::new)
.collect::<Vec<_>>();
(CompositeSolidSubType::Subtract, solid_ids, tool_ids)
}
ModelingCmd::BooleanUnion(union) => {
let solid_ids = union.solid_ids.iter().copied().map(ArtifactId::new).collect::<Vec<_>>();
(CompositeSolidSubType::Union, solid_ids, Vec::new())
}
_ => unreachable!(),

Check warning on line 1120 in rust/kcl-lib/src/execution/artifact.rs

View check run for this annotation

Codecov / codecov/patch

rust/kcl-lib/src/execution/artifact.rs#L1120

Added line #L1120 was not covered by tests
};

let mut new_solid_ids = vec![id];

match response {
OkModelingCmdResponse::BooleanIntersection(intersection) => intersection
.extra_solid_ids
.iter()
.copied()
.map(ArtifactId::new)
.for_each(|id| new_solid_ids.push(id)),
OkModelingCmdResponse::BooleanSubtract(subtract) => subtract
.extra_solid_ids
.iter()
.copied()
.map(ArtifactId::new)
.for_each(|id| new_solid_ids.push(id)),
OkModelingCmdResponse::BooleanUnion(union) => union
.extra_solid_ids
.iter()
.copied()
.map(ArtifactId::new)
.for_each(|id| new_solid_ids.push(id)),
_ => {}

Check warning on line 1144 in rust/kcl-lib/src/execution/artifact.rs

View check run for this annotation

Codecov / codecov/patch

rust/kcl-lib/src/execution/artifact.rs#L1144

Added line #L1144 was not covered by tests
}
let return_arr = new_solid_ids
.into_iter()
// Extra solid IDs may include the command's ID. Make sure we
// don't create a duplicate.
.filter(|solid_id| *solid_id != id)
.map(|solid_id| {
Artifact::CompositeSolid(CompositeSolid {
id: solid_id,
sub_type,
solid_ids: solid_ids.clone(),
tool_ids: tool_ids.clone(),
code_ref: CodeRef {
range,
path_to_node: path_to_node.clone(),
},
})
})
.collect::<Vec<_>>();

// TODO: Should we add the reverse graph edges?

return Ok(return_arr);
}
_ => {}
}

Expand Down
20 changes: 20 additions & 0 deletions rust/kcl-lib/src/execution/artifact/mermaid_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ impl Artifact {
/// the graph. This should be disjoint with `child_ids`.
pub(crate) fn back_edges(&self) -> Vec<ArtifactId> {
match self {
Artifact::CompositeSolid(a) => {
let mut ids = a.solid_ids.clone();
ids.extend(a.tool_ids.iter());
ids
}
Artifact::Plane(_) => Vec::new(),
Artifact::Path(a) => vec![a.plane_id],
Artifact::Segment(a) => vec![a.path_id],
Expand All @@ -87,6 +92,11 @@ impl Artifact {
/// the graph.
pub(crate) fn child_ids(&self) -> Vec<ArtifactId> {
match self {
Artifact::CompositeSolid(_) => {
// Note: Don't include these since they're parents: solid_ids,
// tool_ids.
Vec::new()
}
Artifact::Plane(a) => a.path_ids.clone(),
Artifact::Path(a) => {
// Note: Don't include these since they're parents: plane_id.
Expand Down Expand Up @@ -213,6 +223,7 @@ impl ArtifactGraph {
let id = artifact.id();

let grouped = match artifact {
Artifact::CompositeSolid(_) => false,
Artifact::Plane(_) => false,
Artifact::Path(_) => {
groups.entry(id).or_insert_with(Vec::new).push(id);
Expand Down Expand Up @@ -278,6 +289,15 @@ impl ArtifactGraph {
}

match artifact {
Artifact::CompositeSolid(composite_solid) => {
writeln!(
output,
"{prefix}{}[\"CompositeSolid {:?}<br>{:?}\"]",
id,
composite_solid.sub_type,
code_ref_display(&composite_solid.code_ref)
)?;
}
Artifact::Plane(plane) => {
writeln!(
output,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ flowchart LR
42["SweepEdge Adjacent"]
43["SweepEdge Opposite"]
44["SweepEdge Adjacent"]
45["CompositeSolid Intersect<br>[448, 477, 0]"]
1 --- 2
2 --- 3
2 --- 4
Expand Down Expand Up @@ -114,4 +115,6 @@ flowchart LR
30 --- 42
30 --- 43
30 --- 44
2 <--x 45
24 <--x 45
```
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ flowchart LR
30["Cap End"]
31["SweepEdge Opposite"]
32["SweepEdge Adjacent"]
33["CompositeSolid Subtract<br>[461, 497, 0]"]
1 --- 2
2 --- 3
2 --- 4
Expand Down Expand Up @@ -81,4 +82,6 @@ flowchart LR
27 --- 30
27 --- 31
27 --- 32
2 <--x 33
24 <--x 33
```
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ flowchart LR
42["SweepEdge Adjacent"]
43["SweepEdge Opposite"]
44["SweepEdge Adjacent"]
45["CompositeSolid Union<br>[448, 473, 0]"]
1 --- 2
2 --- 3
2 --- 4
Expand Down Expand Up @@ -114,4 +115,6 @@ flowchart LR
30 --- 42
30 --- 43
30 --- 44
2 <--x 45
24 <--x 45
```
4 changes: 3 additions & 1 deletion src/lang/std/artifactGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,9 @@ export function getCodeRefsByArtifactId(
artifactGraph: ArtifactGraph
): Array<CodeRef> | null {
const artifact = artifactGraph.get(id)
if (artifact?.type === 'solid2d') {
if (artifact?.type === 'compositeSolid') {
return [artifact.codeRef]
} else if (artifact?.type === 'solid2d') {
const codeRef = getSolid2dCodeRef(artifact, artifactGraph)
if (err(codeRef)) return null
return [codeRef]
Expand Down
1 change: 1 addition & 0 deletions src/lang/wasm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export type {
ArtifactId,
Cap as CapArtifact,
CodeRef,
CompositeSolid as CompositeSolidArtifact,
EdgeCut,
Path as PathArtifact,
Plane as PlaneArtifact,
Expand Down
Loading