Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Vibe-coding FeatureScript

karl_mochelkarl_mochel Member Posts: 53 ✭✭

Hi all,

I just finished a FeatureScript feature that lets you import an SVG (as a text blob) and convert it into sketch elements.

https://cad.onshape.com/documents/e37c5dc041b343cb6bde607d/w/f7b0bf8a214658dc31c353f6/e/7217f6a6f01abf2583a1d61c?renderMode=0&uiState=69388fdff20ff15b50aa8344

I created the attached guidelines to use with any LLM to improve its ability to generate appropriate FeatureScript.

Most of the work was done in Claude in the browser, with passes through ChatGPT, Gemini, and Grok, depending on how well they resolved issues, how strategically they thought, and how well they handled different aspects of coding. I also used Cursor for some of the work. All the models failed at some point, which is why I switched among them.

I also use Perplexity for general Onshape questions, development questions, and development environment questions. I mostly do this to separate these productivity questions to one place where I can get back to them, if needed.

In each of these LLMs, I create a space or project where I provide an overview of what I am trying to accomplish and…the guidelines. Also, I save every conversation (that I can remember) to feed an LLM at the end of the project to do a post mortem and generate learnings.

An overview from Notebook LLM from saved conversations:

Developing FeatureScript features for Onshape requires developers to master specific aspects of the language, prioritize performance within its constraints, and understand the unique requirements of CAD geometry modeling.

The primary lessons learned from building complex features like the SVG-to-Sketch converter fall into five categories:

1. FeatureScript Language Quirk and Syntax Strictness

FeatureScript operates with strict rules that differ significantly from common scripting languages:

  • Strict Typing and Usage: Explicit parameter and return types are strictly required for all functions. Furthermore, all declarations must be used or removed, otherwise they trigger an error.
  • Unsupported Operations: The language does not support many standard operations. For example, developers must manually implement basic helpers, such as a function to retrieve a character at an index (chAt) and functions for safe digit checking (isDigit), as the core library may lack them.
  • String Comparison Limitations: FeatureScript strictly prohibits comparing strings using range checks like >= or <=. Instead, checks must use explicit equality matching or the find/indexOf function within a defined whitelist string to check for valid characters or commands.
  • Variable Declarations: Follow the rule of one variable declaration per line for both var and const.

2. Performance Optimization: Avoiding O(n²) String Operations

The most significant performance bottleneck identified in FeatureScript parsing is string concatenation:

  • Avoid Concatenation in Loops: Repeatedly building a string inside a loop (result = result ~ c) leads to O(n²) complexity because a new string is created and copied in every iteration. For large inputs (e.g., a 10,000-character file), this translates to tens of millions of operations.
  • Use the Array + Join Pattern: The high-performance solution is to accumulate string fragments into an array (var parts = [];) and then use the built-in join(parts, "") function once at the end. This reduces the total complexity to the efficient O(n). This is critical for frequently called functions like number and path data parsers.

3. Handling CAD Geometry and Units

CAD modeling in FeatureScript introduces unique requirements for geometry creation and coordinate handling:

  • Mandatory Units: Coordinates passed to geometry functions, as well as angles used in trigonometric functions (cos, sin, atan2), must have explicit units (e.g., * millimeter or * radian). Plain numbers cannot be used for trigonometric input.
  • Point Dimensionality: Onshape's sketch functions ultimately expect 3D vectors with a unit definition. The toMM helper function must ensure it creates the geometry point as a 3D vector, typically by adding a z=0 coordinate multiplied by the appropriate unit (vector(x, y, 0) * millimeter).
  • Coordinate System Inversion: SVG defines geometry using a Y-down coordinate system, while Onshape uses a Y-up system. Correct geometry conversion typically requires negating the Y coordinates during translation.

4. Robust SVG Parsing and Data Handling

Creating a reliable parser requires defensive coding against real-world file formats and FeatureScript's type system:

  • Handling Metadata/Tags: Implement robust attribute parsing logic that does not rely on the attribute order. This prevents errors when attributes like style="..." or other extraneous data appear before critical attributes like d="...".
  • XML Cleanliness: The parser must explicitly skip XML comments (<!--...-->) and processing instructions, as the data inside them can otherwise be misinterpreted as elements, causing unexpected behavior.
  • Line Ending Compatibility: Since FeatureScript's string escape sequences ("\r") may not reliably recognize Windows carriage return characters (\r), a robust solution involves using a whitelist approach to keep only valid characters (printable ASCII, newline, tab) and drop all other control characters during input preprocessing.
  • Relative Path Commands: To correctly parse SVG paths using lowercase (relative) commands (e.g., m, l, c), the parser must constantly calculate and update the "current position" (cur) based on the previous segment's endpoint.

5. CAD Topological Closure Paradox

Achieving reliably closed profiles in Onshape sketches is notoriously difficult and requires careful handling of the SVG Z command:

  • Geometric vs. Topological Closure: Although an SVG path may be geometrically closed (the last point is mathematically identical to the first point), Onshape's sketch solver requires an explicit topological closing entity (a line segment) to recognize the profile as a closed loop.
  • The Snapping/Hint Fix: The ideal solution to maintain the highest quality geometry (G1/G2 continuity) is to re-enable "snapping" logic for the final curve/line segment, ensuring the endpoint is mathematically identical to the starting point. Crucially, the script must then always emit a line segment for the Z command, even if it has zero length. This zero-length line acts as the necessary "hint" for the solver to recognize the loop without creating microscopic, non-coincident gaps that lead to continuity errors.
  • State Management is Key: Because FeatureScript passes the mutable Sketch object by value, any function that adds geometry (emitPath) must return the updated sketch object, and the calling feature logic must reassign this object (sk = result.sketch;). Failure to do this means the final skSolve() function runs on an incomplete sketch, which remains an open profile.

Comments

  • S1monS1mon Member Posts: 3,758 PRO
    edited December 10

    I'm impressed that you've been able to get this to work.

    I am a little confused by your guide that you're using. For example, your notes say "No regex", but there is support in FeatureScript for regex. I would think there would be good ways to simplify the code a lot using some regex functions.

    image.png

    Here are some sample functions which use regExp in FeatureScript:

    image.png image.png

    I am surprised that there's no built in way to do toLowerAscii. The if/then/else if/then/else if… in the code seems unfortunate. Seems like there has to be a better way to do that. But it works, which is much better than not having a solution to importing SVG.

    Simon Gatrall | Product Development Specialist | Open For Work

  • Derek_Van_Allen_BDDerek_Van_Allen_BD Member Posts: 394 PRO

    The other thing I noticed AI doing a lot is cross products and dot products on vectors. Claude loves some clever vector logic. Unfortunately there are already queries and comparison operations baked into the standard library functions that cover the intended use case that they're reaching for so I've got it baked into my instructions that if they think about using either of those vector comparisons they should crack open the query.fs module and go find the appropriate operation instead.

  • ry_gbry_gb Member, csevp, pcbaevp Posts: 79 PRO

    Dude. That led me down a terrible rabbit hole that could've been solved if only ChatGPT knew what WorldToPlane was… It makes up some many damn functions, but the real ones though... Where's that Drake meme when you need it?

    Ramon Yip | glassboard.com

  • EvanReeseEvanReese Member, Mentor Posts: 2,686 PRO

    Thanks for sharing the writeup! I've been experimenting with some vibe coding FS too and have gotten things to work, but it's certainly not a panacea, and the code it creates can be quite verbose because it's creating a ton of helper functions and workarounds for things that FS can already handle cleanly. I did a test to see how little code I could actually write myself (or even read and review), and I was able to get something done, but it was fairly painful and solidified to me that this is the wrong approach. The way I'll be using it is more about brainstorming a big-picture logical flow, then helping to create one function at a time that I fully audit, understand, and edit before moving on. That way I can still actually "own" the code if edits are needed. The way I did it in my test means that troubleshooting looks like telling ChatGPT it's still not working and hoping for the best, which takes a lot of iteration and accrues even more complexity as the result can sometimes be a series of band-aids on top of band-aids.

    Evan Reese
    The Onsherpa | Reach peak Onshape productivity
    www.theonsherpa.com
Sign In or Register to comment.