I’ve been working with Seamly2D for a while now and recently started exploring .sm2d files in more depth to better understand how patterns are structured under the hood.
I’m currently trying to build some tools for personal learning and would like to better grasp how Seamly2D interprets and organizes pattern data in the .sm2d format.
I’ve looked through the forum, wiki, and GitHub repo, but I couldn’t find:
Any official XML schema (.xsd) or similar specification
A reference for what tags and attributes are required/optional
Clarification on the order/structure of elements like <draw>, <details>, <point>, <spline>, etc.
How measurements and formulas are connected in the XML
Is there any internal documentation or reference you could share about the .sm2d structure, or even a minimal example that reflects best practices?
Also, if someone knows where the XML parsing happens in the codebase, that would be super helpful to look into as well.
I have no idea about the behind the scenes workings of Seamly2D, however, perhaps someone will be by to help you.
I just wanted to mention that we no longer work with .val, although those file extensions will open in Seamly if they were created in Seamly. Our files are now .sm2d files and I suggest that you save your patterns as such.
Well as @Grace mentioned the extensions for Seamly are now *.sm2d, *.smis, and *.smms. There is also a schema for the label templates, but it’s simply been left as *.xml… which in itself is odd as it’s an xsd file.
That being said…
That’s a big ask. First you need to have a grasp on C++, the Qt framework, and now since we’re building with Qt6 - the Xerces xml library.
There is no official spec.. plus the schemas can and do change at any time.
Reading the xsd files will tell you that. You have to a basic understanding of xsd… but the order in the xsd is the order in which elements appear in the file. Also to note we no longer use <draw>, <details>, but rather <draftBlock>, <pieces>. Which brings up another point… you will need to understand the conversion process between schema versions.
Again… the xsd file IS the structure. for example:
draft block
calculation // definition of tools
modeling // undo cache section for nodes used in pieces
pieces // pattern pieces
If you have a specific question I may be able to help, but there are even some elements the orginal dev coded that I’m not 100% sure of even after working with the code for 8+ years. The union tool gets real murky.
Parsing happens in various places in the codebase. But before a file can be parsed it has to be validated… and that happens in conjunction with the conversion process. Which is a daisy chain process… load file, validate, check if current if not convert to next ver, validate, check if current, etc, until reaching current ver. Again since switching to Qt6 we had to use the Xerces lib to validate the xml’s as Qt removed the xmlpatterns module in Qt6.
The main initial parsing when loading a pattern happens in pattern.cpp… in which case you have to know the Qt QDomDocument api, how to parse down through, and reading / writing the Dom doc. There are many other areas where the Dom Doc (the in memory representation of the xml) is read or written - often in undo commands. So without being specific it’s hard to answer where in the code any one element w/ attributes is written. Also due to the formulaic nature of the application, a full parse of the pattern may be perfomed at times, where at other times a lite parse is performed. So it’s not always a question “where”, but “when” is parse performed.
Measurement files (if a pattern uses one) also have to then be loaded, converted, validated, and parsed after the pattern file is loaded, converted, and validated. Also if a label template is edited the label template has to be loaded, converted (although currently there is only 1 ver so there is no conversion), and validated against the schema.
I should also note that reading a Seamly pattern file on it’s own is more or less useless without using the tools in the libs to build a pattern. With the formulas Seamly patterns are dynamic in that each tool is built upon others, and thus all sorts of formulas are resolved and dependencies created. The only tool that has any relevance outside of Seamly is a basepoint - where it’s the only tool with an X:Y coordinate. For ex: x and y are the coordinates of the basepoint (“single” type point tool)