Skip to content

Draft API for assembly blocks - #1362

Draft
adamchalmers wants to merge 2 commits into
mainfrom
achalmers/assembly
Draft

Draft API for assembly blocks#1362
adamchalmers wants to merge 2 commits into
mainfrom
achalmers/assembly

Conversation

@adamchalmers

Copy link
Copy Markdown
Collaborator

Assembly block MVP needs 3 things:

  • Moving bodies into the assembly
  • Creating mate connectors
  • Applying constraints to mate connectors

One nice-to-have that I've called out in a TODO:

  • Translate/rotate calls where the engine persists its solutions into the KCL AST, ensuring warm solves.
  • I don't know how the engine would send this back to KCL -- presumably a translate + rotate for each body in solved system, but what coordinate system would it be in? Scene global, or relative to something? Currently KCL translate has two coordinate frames available, the global scene, and the body's sketch's local system.

@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@001252d). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1362   +/-   ##
=======================================
  Coverage        ?   34.09%           
=======================================
  Files           ?       37           
  Lines           ?     1833           
  Branches        ?        0           
=======================================
  Hits            ?      625           
  Misses          ?     1208           
  Partials        ?        0           
Flag Coverage Δ
unittests 34.09% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

pub struct MateFrameCreate {
/// What to create the mate frame on.
pub on: MateFrameOn,
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add options here to reorient the mate frame, e.g. translating it, rotating it, flipping the major/minor axes. WDYT David?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that sounds good.

pub struct MateFrameCreate {
/// What to create the mate frame on.
pub on: MateFrameOn,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that sounds good.

Comment on lines +2280 to +2292
/// Makes two entities occupy the same line/plane or places a point on a surface.
Coincident {
/// IDs of two mate frames in the assembly.
targets: [Uuid; 2],
},
/// Aligns cylindrical, conical, or spherical surfaces to a common center.
Concentric {
/// Which edge?
/// IDs of two mate frames in the assembly.
/// Must be >= 2 items.
#[schemars(range(min = 2))]
targets: Vec<Uuid>,
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll need to revise the constraint catalogue if we're using mate-based constraints. Concentric, for example, sounds like it'd be ~equivalent to a cylindrical joint (i.e. two bodies share a common axis that they're free to move along/rotate around). Here's the joint catalogue I have on the solver side so far (comments are common alternative names):

struct Joint
{
    enum struct Type : u8
    {
        Undefined = 0,
        Spherical, // Ball
        Distance,
        Revolute, // Hinge
        Cylindrical,
        Weld, // Fixed, Fastened
        Prismatic, // Slider
        Universal, // Hooke
        Planar,
        PointOnPlane,
        _Count,
    };

    // ...
};

This mostly overlaps with the OnShape catalogue with the exception of their Tangent mate which doesn't make use of mate connectors. Would suggest we ignore that one for now though as it'd involve solving the general contact problem between a pair of solids which is a ways off on the geometry kernel side.

Comment on lines +2261 to +2269
FaceCentroid {
/// The face's ID
face_id: Uuid,
},
/// Mate frame along this edge.
Edge {
/// Which edge?
specifier: EdgeSpecifier,
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's likely to be quite a few ways of deriving a mate frame from faces, edges, or other elements. Wondering if we should split this up so the top level enum expresses what we're deriving the frame from and then use a second set of enums to describe how the frame is derived e.g.

pub enum MateFrameOn {
    /// Mate frame derived from a face
    Face {
        /// The face's ID
        face_id: Uuid,
        /// How to derive the frame from that face
        derivation: FaceDerivation,
    },
    /// Mate frame derived from an edge
    Edge {
        /// The edge's ID
        edge_id: Uuid,
        /// How to derive the frame from that edge
        derivation: EdgeDerivation,
    },
    /// Mate frame derived from a vertex
    Vertex { /* ... */ },
    // ...
    // ...
    // ...
}

enum FaceDerivation { Centroid, AtParameter{ u: f64, v: f64 }, /* ... */ }
enum EdgeDerivation { Midpoint, AtParameter{ t: f64 }, /* ... */ }

@davreev

davreev commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

presumably a translate + rotate for each body in solved system, but what coordinate system would it be in?

Yep, was thinking the same. Still mulling this over a bit but seems to make sense for each assembly to have its own transform, defining a local space in which the solve happens. In this case, it'd be the transform of each child in the local space of its parent assembly that gets sent back to KCL.

The key benefit here is that it'd let us use nested assemblies to break large problems down into smaller ones that can be solved concurrently e.g. solving for transforms of parent assembly A can be done independently of solving for transforms of child assemblies B and C. This separation relies on expressing the transforms of each child in the space of its parent. What I'm still unsure about though is whether this transform hierarchy is something we want to persist or if it makes more sense as a transient thing that's constructed before the solve and then torn down/flattened out afterwards. Might be good to get @benjamaan476's thoughts on this as he's more familiar with how transform hierarchies currently work in engine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants