kcl_api/
sketch.rs

1#![allow(async_fn_in_trait)]
2
3use serde::{Deserialize, Serialize};
4
5use crate::*;
6
7pub trait SketchApi {
8    async fn new_sketch(
9        &self,
10        project: ProjectId,
11        file: FileId,
12        version: Version,
13        args: SketchArgs,
14    ) -> Result<(SourceDelta, SceneGraphDelta, ObjectId)>;
15
16    // Enters sketch mode
17    async fn edit_sketch(
18        &self,
19        project: ProjectId,
20        file: FileId,
21        version: Version,
22        sketch: ObjectId,
23    ) -> Result<SceneGraphDelta>;
24
25    async fn exit_sketch(&self, version: Version, sketch: ObjectId) -> Result<SceneGraph>;
26
27    async fn add_segment(
28        &self,
29        version: Version,
30        sketch: ObjectId,
31        segment: SegmentCtor,
32        label: Option<String>,
33    ) -> Result<(SourceDelta, SceneGraphDelta)>;
34
35    async fn edit_segment(
36        &self,
37        version: Version,
38        sketch: ObjectId,
39        segment_id: ObjectId,
40        segment: SegmentCtor,
41    ) -> Result<(SourceDelta, SceneGraphDelta)>;
42
43    async fn delete_segment(
44        &self,
45        version: Version,
46        sketch: ObjectId,
47        segment_id: ObjectId,
48    ) -> Result<(SourceDelta, SceneGraphDelta)>;
49
50    async fn add_constraint(
51        &self,
52        version: Version,
53        sketch: ObjectId,
54        constraint: Constraint,
55    ) -> Result<(SourceDelta, SceneGraphDelta)>;
56
57    async fn edit_constraint(
58        &self,
59        version: Version,
60        sketch: ObjectId,
61        constraint_id: ObjectId,
62        constraint: Constraint,
63    ) -> Result<(SourceDelta, SceneGraphDelta)>;
64
65    async fn delete_constraint(
66        &self,
67        version: Version,
68        sketch: ObjectId,
69        constraint_id: ObjectId,
70    ) -> Result<(SourceDelta, SceneGraphDelta)>;
71}
72
73#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
74#[ts(export, rename = "ApiSketch")]
75pub struct Sketch {
76    pub args: SketchArgs,
77    pub segments: Vec<ObjectId>,
78    pub constraints: Vec<ObjectId>,
79}
80
81#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
82#[ts(export)]
83pub struct SketchArgs {
84    pub on: Plane,
85}
86
87#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
88#[ts(export, rename = "ApiPoint")]
89pub struct Point {
90    pub position: Point2d<Number>,
91    pub ctor: Option<Point2d<Expr>>,
92    pub owner: Option<ObjectId>,
93    pub freedom: Freedom,
94    pub constraints: Vec<ObjectId>,
95}
96
97#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
98#[ts(export)]
99pub enum Freedom {
100    Free,
101    Partial,
102    Fixed,
103}
104
105#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
106#[ts(export, rename = "ApiSegment")]
107pub enum Segment {
108    Point(Point),
109    Line(Line),
110    Arc(Arc),
111    Circle(Circle),
112}
113
114#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
115#[ts(export)]
116pub enum SegmentCtor {
117    Point(Point2d<Expr>),
118    Line(LineCtor),
119    MidPointLine(MidPointLineCtor),
120    Arc(ArcCtor),
121    ThreePointArc(ThreePointArcCtor),
122    TangentArc(TangentArcCtor),
123    Circle(CircleCtor),
124    ThreePointCircle(ThreePointCircleCtor),
125}
126
127#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
128#[ts(export, rename = "ApiPoint2d")]
129pub struct Point2d<U: std::fmt::Debug + Clone + ts_rs::TS> {
130    pub x: U,
131    pub y: U,
132}
133
134#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
135#[ts(export, rename = "ApiLine")]
136pub struct Line {
137    pub start: ObjectId,
138    pub end: ObjectId,
139    // Invariant: Line or MidPointLine
140    pub ctor: SegmentCtor,
141    // The constructor is applicable if changing the values of the constructor will change the rendering
142    // of the segment (modulo multiple valid solutions). I.e., whether the object is constrained with
143    // respect to the constructor inputs.
144    // The frontend should only display handles for the constructor inputs if the ctor is applicable.
145    // (Or because they are the (locked) start/end of the segment).
146    pub ctor_applicable: bool,
147}
148
149#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
150#[ts(export)]
151pub struct LineCtor {
152    pub start: Point2d<Expr>,
153    pub end: Point2d<Expr>,
154}
155
156#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
157#[ts(export)]
158pub struct MidPointLineCtor {
159    pub midpoint: Point2d<Expr>,
160    pub start_or_end: StartOrEnd<Point2d<Expr>>,
161}
162
163#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
164#[ts(export, rename = "ApiStartOrEnd")]
165pub enum StartOrEnd<T> {
166    Start(T),
167    End(T),
168}
169
170#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
171#[ts(export, rename = "ApiArc")]
172pub struct Arc {
173    pub start: ObjectId,
174    pub end: ObjectId,
175    pub center: ObjectId,
176    // Invariant: Arc or ThreePointArc or TangentArc
177    pub ctor: SegmentCtor,
178    pub ctor_applicable: bool,
179}
180
181#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
182#[ts(export)]
183pub struct ArcCtor {
184    pub start: Point2d<Expr>,
185    pub end: Point2d<Expr>,
186    pub center: Point2d<Expr>,
187}
188
189#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
190#[ts(export)]
191pub struct ThreePointArcCtor {
192    pub start: Point2d<Expr>,
193    pub end: Point2d<Expr>,
194    pub interior: Point2d<Expr>,
195}
196
197#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
198#[ts(export)]
199pub struct TangentArcCtor {
200    pub start: Point2d<Expr>,
201    pub end: Point2d<Expr>,
202    pub tangent: StartOrEnd<ObjectId>,
203}
204
205#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
206#[ts(export, rename = "ApiCircle")]
207pub struct Circle {
208    pub start: ObjectId,
209    pub radius: Number,
210    // Invariant: Circle or ThreePointCircle
211    pub ctor: SegmentCtor,
212    pub ctor_applicable: bool,
213}
214
215#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
216#[ts(export)]
217pub struct CircleCtor {
218    pub center: Point2d<Expr>,
219    pub radius: Expr,
220}
221
222#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
223#[ts(export)]
224pub struct ThreePointCircleCtor {
225    pub p1: Point2d<Expr>,
226    pub p2: Point2d<Expr>,
227    pub p3: Point2d<Expr>,
228}
229
230#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
231#[ts(export, rename = "ApiConstraint")]
232pub enum Constraint {
233    Coincident(Coincident),
234    Parallel(Parallel),
235}
236
237#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
238#[ts(export)]
239pub struct Coincident {
240    points: Vec<ObjectId>,
241}
242
243#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS)]
244#[ts(export, optional_fields)]
245pub struct Parallel {
246    lines: Vec<ObjectId>,
247    distance: Option<Number>,
248}