Notices
This section contains notices pertinent to mesh-makers.
Release of Entity-Inspector for Desktop Platforms
The quick-mesh entity-inspector (a portable graphical front-end to the command-line-kernel) is now available for beta-testing on the project's homepage and via the project's tool-repository.
The entity-inspector (codenamed QMSH:EI) provides facilities similar to the mobile-editor (under Android) for desktop platforms (Linux, Mac-OSX, Windows and the Raspberry-Pi).
Positively: the entity-inspector bridges the usability gap that previously existed between/amongst QMSH under mobiles and on workstations. In-particular the entity-inspector provides native hardware-accelerated visualisation and examination of monolith and parallel, static and parametric arrangements out-of-the-box. Indeed the entity-inspector actually offers slightly more adept exploitation of the kernel in that (unlike the mobile-editor - which only allows one script to be assembled at any one point in time) - the entity-inspector allows multiple scripts to loaded into an environment (each supporting individual control) - and further: multiple environments! As a rough analogy - if one considers browsers: one can rationalise the scope of the mobile-editor as managing (i.e. assembling and displaying) a single section of a page. The entity-inspector on the other hand manages (assembles and displays) multiple sections of a page and multiple pages (or tabs - which we tend to term environments in quick-mesh). In essence both entity-inspector and mobile-editor support exactly the same scripting-language and grammatical constructs - it is simply the scale of the arrangements that can be handled by each that varies. Therefore if you are already familiar with the mobile-editor then the transition to the entity-inspector should be relatively smooth.
Negatively: the entity-inspector does not (by-design) include a script-editing component - nor does it bundle embedded documentation of the scripting language. The reasons for these decisions are many and varied however at their heart they are driven by practicality. For example (for most desktop-platforms) excellent text-editors already exist - and often individuals have preferences as to how they compose their logic that means no single IDE or development environment can meet the needs of all. In essence - it did/does not make a lot of sense to reinvent the wheel - especially when there are already very good wheels available. Do not misunderstand - writing text-editors is an awful lot of fun and much the simplest way to construct a tool that behaves exactly as one desires - however (in the context of procedural mesh-making on a workstation) - there are already numerous tools that tend to the problem. On mobiles the situation is slightly different - in that (generally) one can not depend on there being a suitable text-editor built-in natively and so it makes sense to bootstrap and bundle a basic grammar-centric implementation to ease use. The lack of embedded documentation (on the other hand) boils down to seeking to simplify the process of localisation relative to (and based upon the still on-going experience in localising) the mobile-editor. The rationale is that by limiting the number of strings that require translating it should be simpler to adapt the entity-inspector for use in different parts of the world. Nonetheless - in spite of their intentional nature - it is fair to state that these limitations may/likely-shall require revisiting in the future.
The emergence of the entity-inspector should help improve the workflow when wielding the kernel natively - just bear in mind that (as a fresh construction) - there may be behavioural issues that still require addressing. If you encounter any such issues - report them such that they may be fixed.
Presently QMSH-EI has been tested under Linux, Mac-OS, Windows and the RPi-OS - and though the initial results seem positive (i.e. largely consistent functionality across platforms) - it is worthwhile remembering that lower-power machines may not scale to very large arrangements as well as more powerful machines. The key example in this case being the Raspberry-Pi - in the sense that it works, and is quite useful, but is not as fast as when run on more capable machines.
Note: the entity-inspector's PDF documentation is in preparation and shall be added to the distribution once most of the outstanding issues have been satisfactorily resolved. Presently you can track the progress of the implementation by referring to the notes accompanying the beta releases and/or the development section's functionality tracker 'Entity-Inspector: Functionality Tracking'.
Eco-System Tool-Repository
A simple multi-platform tool-repository is now in beta-testing to help improve access to the QMSH tool-chain for mesh-makers around the world. The quick-mesh tool-repository acts as a complement to the homepage's download section by providing more in-depth information for the publicly accessible suite of experimental applications designed, developed and distributed by Codemine.
→ QMSH Tool-RepositoryBy collating the eco-system tooling the aim is to support mesh-makers in exercising control over the manner in which they adopt extensions and revisions to the kernel and scripting language - and to remove potential barriers to access that might otherwise hinder the community's endeavours.
In particular: the tool-repository enables one to choose, if, when and how application updates are applied - which can be beneficial in cases where the kernel is used to support longer term research, development and experimentation - wherein the ability to maintain a stable (i.e. consistent) build environment over time is often key.
Note: the tool-repository's creation has also been driven by the logistical challenges inherent to coordinating the release and maintenance of cross-platform technical software using conventional (typically mono-platform) store-fronts and distribution channels.
As a clarifying example: whilst the Play-Store offers established facilities for the distribution of Android applications and the Asset-Store analogous options for Unity packages and extensions - sadly neither provides the infrastructural basis for distributing (as examples) Raspberry-Pi applications or standalone web applications. Indeed the challenges that have arisen in managing multiple distribution channels go beyond simply technical shortcomings and include (most critically) avoidable delays to the implementation itinerary resulting from lost development time.
Fortunately though, the introduction of the tool-repo does not preclude the use of prior distribution channels - rather it extends, expands and augments the access options available to mesh-makers.
In other words (as they are not mutually-exclusive) Codemine aims to marry the benefits of third-party distribution whenever possible (and practical) with the complementary advantages of efficiency, mesh-maker control and uniformity across platforms resulting from self-distribution.
For reference the primary benefits of the tool-repository include:
- Multi-Platform Support: is the key practical benefit of the tool-repo relative to options such as the Play-Store, Asset-Store, App-Store, Windows-Store, Snap-Store and similar. Essentially although each provides comprehensive facilities for their target-platform none currently provides support for the full range of targets supported by quick-mesh - which renders the duplication of labour (required to support each) an ineffectual strategy.
- Multi-Version Support: ensures that the tool-repository affords mesh-makers the wherewithal to run the version(s) of the kernel they require as and when required. Note: this is also rather useful for benchmarking and tracking/verifying performance improvements prior to upgrading as newer versions of the kernel are released.
- Uniform Global Access: which is particularly important for mesh-makers in regions and territories for which certain commercial entities may be barred or prohibited from operating. The obvious example in this instance being enabling technicians in the far-east to benefit from QMSH Android applications without having to violate their governments' prohibitions to market-places such as the Play-Store. In other words researchers and engineers need not risk violating the laws imposed by their countries' leaders (i.e. by using VPNs or similar) in order to access QMSH as they can now simply avoid troublesome distribution channels and problematic intermediaries and instead source their QMSH-wares directly from Codemine.
- Privacy-Friendly Distribution Channel: removes the requirement for creators to divulge any sensitive information in order to access quick-mesh. Although this is also true of the flagship applications on the project's homepage, the tool-repo ensures that the supplementary applications (such as the QMSH Launcher and QMSH Visual) also offer access options that conform to Codemine's online privacy policy. Note: incidentally - this should also ensure that in parts of the world where data-privacy laws grow in scope (such as general data protection regulations in Europe) the project can steer well clear of potential violations.
- Suitability to Use in Secure Contexts: as system-adminstrators gain the ability to examine the pre-compiled binaries prior to installation (for example via malware detection suites and anti-virus tests). This can be quite handy in institutional contexts where strict security protocols govern the types of software that may be installed. Additionally it affords security analysts and researchers the ability to scrutinise the builds in order to verify the validity of the statements pertaining to the absence of user-tracking and data-collection.
- Neutrality: serves to insulate fellow mesh-makers from the turbulence that has arisen in recent times surrounding the abuse of technology by so called 'gate-keepers'.
- Capacity for Growth: stands as a subtler benefit in that it ensures that moving forward the process of exploring new procedural contexts and compute environments need not be constrained by the ancillary complications imposed by third-party distribution channels.
The anticipation is that the long-term growth and vitality of the kernel, grammar and indeed entire project shall benefit from the presence of a persistent canonical non-partisan access point.
In other words the tool-repository offers a means to deal with project-centric tool-distribution concerns in a project-centric manner - ensuring that features, constructs and facilities that are pertinent to mesh-makers can be implemented and added efficiently - free of the latency and friction that delays releases that can (in some instances) be introduced by third-party channels.
In contrast - the main limitations and shortcomings of the tool-repository include:
- Automatic Updates: which admittedly are incredibly useful in some contexts - yet traditionally require invasive methods to implement. The current thinking is that some form of 'check-for-updates' option will benefit mesh-makers but will need to be implemented in such a manner that it places mesh-makers in control of any network communication.
- Limited Exposure: stands as another limitation of self-distribution channels such as the tool-repo relative to larger market-places. Fortunately though - as the tool-repo acts as a project-local complement to larger distribution channels - this is not a critical issue.
- Reviews and Feedback: are also presently missing from the tool-repo. This area is under investigation. The current thinking is that publicly visible display of concrete user experiences is an important pre-requisite of community growth (and hence on the TODO list). However how to do this effectively - given the potential complications that can arise in any attempt to moderate others - is not yet clear. The likely first step is the introduction of some form of user-gallery that enables mesh-makers to show-case their creativity and skill in wielding the kernel and in doing so raise their profile. This seems the least risky starting point in that (by and large) creative individuals and communities tend to be quite good at self-regulating and hence would/should not require much governance - whilst affording members of the community a means to start collating collective knowledge and exchanging practical insights.
These limitations shall invariably take time to resolve. Fortunately though - given that the benefits and advantages largely out-weigh the limitations it seems reasonable to enter beta-testing.
To recap: moving forward the multi-platform tool-repository shall act as the canonical access method for the suite of quick-mesh applications, with third-party channels utilised whenever it is practical.
For further information (on topics such as versioning and the state of tools that are yet to be added) - refer to the repo's notes section - and do not hesitate to report any issues you encounter.
Experimental Sub-Division-Solid Support
Preliminary support for generating sub-division-solid surfaces has been added to the kernel (from version 0.2.3) to enable fellow mesh-makers to begin experimenting with the portable construction of alternative types of high-level purely-procedural polyhedral entity.
These new operators manifest as the post-processing kernel directives: #OSDS, #TSDS and #QSDS - which stand-for (respectively) [O]rthogonal, [T]riangle and [Q]uadrilateral [S]ub-[D]ivision-[S]olids.
Positively: sub-division offers a relatively efficient means to construct smoothly undulating surfaces from low-poly-count cages (relative to other generative approaches such as the application of boolean operators) - and yields feature-preserving mesh that may be monotone or coloured.
Negatively: sub-division modelling tends to work best for quadrilateral mesh (as opposed to triangle or n-gonal-mesh) and as such may not be directly applicable to all arrangements. Further more (due to the increased memory requirements - relative to the kernel's minimal-vertex-meshing) - the current incarnation is restricted to application post-execution rather than as a standard language-symbol. Additionally you may find that (again relative to the boolean-operators) sub-division is less script-friendly - in the sense that controlling the yield is not always as intuitive as one might like - requiring an amount of trial and error in some cases to achieve the desired result.
Indeed one of the primary observations that has arisen from these early-stage explorations is the requirement for additional automatic-retopology operators to be added to the kernel in order to fully capitalise on the expressive possibilities offered by sub-division-solids in quick-mesh. Specifically the current thinking is that it would be rather useful to be able to automatically construct reasonable quality pure quad-mesh from general n-gon-mesh rather than having to coordinate the creation of quad-mesh manually. For: although manual construction of quad-mesh offers the greatest level of control - it can also be somewhat fiddly (less forgiving) and demand a greater level of care.
Nonetheless - as a well-established generative paradigm for procedural content creation it does no harm to explore the limits of scripted sub-division-solid modelling. In essence presently these new operators should be considered exploratory rather than as constituting a shift in ideological focus - given that it is too early to say definitively whether or not they are suitable candidates for integration into the core of the scripting language. In some instances they can prove surprisingly useful in enabling the expression of entities that might otherwise be impractical to describe via other means - however the issues inherent to coordinating effective programmatic control are not yet resolved.
For a clearer indication of the current behaviour refer to the development section's notes 'Post-Processing: Sub-Division-Solids' which includes concrete examples to help you get started.
Parallel-Assembly Kernel-Directive Support
Preliminary support for the parallel-assembly kernel-directive (#PARALLEL) has been added to the quick-mesh editor and kernel under Android - as well as to the command-line kernel under Linux, Mac-OS and Windows operating systems - and to the experimental Raspberry-Pi build.
The parallel-assembly kernel-directive offers a means to coordinate the construction of larger environments, composite arrangements and scenes within a single quick-mesh source-file.
Note: presently support for simultaneous execution is bound to (i.e. is exclusive to) the quick-mesh editor as is parallel assembly culling. This means that although the command-line and mobile kernels are able to parse and assemble scripts that use the parallel-directive they do so sequentially.
Note: the experimental web-assembly sandbox and entity-exchange also support the parallel directive via sequential-execution (as for the command-line-kernel and mobile-kernel).
In line with the introduction of support for compound assembly, a number of tools have been added to the quick-mesh editor to help fellow mesh-makers capitalise upon this new capability.
Additionally an extended-usage guide has also been added to the Android editor to provide more in-depth treatment of the topic of parallel-assembly in quick-mesh. For more refer to: Parallel-Assembly for Larger-Scale and Environment Modelling Tasks in the editor's Library-Reference.
Note: support for parallel-assembly is very much a fresh (new and emerging) feature of the kernel and grammar - and as such may be subject to a larger number of usability issues relative to more mature aspects of quick-mesh. In light of this if you encounter any behaviours that seem awry - do not hesitate to report them - such that they may be resolved, fixed and/or clarified.
Update: V:0.2.2 added support for simultaneous execution across Linux, Mac-OS, Windows and the RPi-OS using a side-along multi-process kernel front-end 'qmshp' included in each distribution.
This new multi-core parallel assembler brings functional parity between desktops and mobiles ensuring that researchers and engineers who are invoking the kernel at the command-line also have the ability to distribute the workload for larger arrangements across multiple CPU-cores.
If you are accustomed to invoking the kernel at the command-line you should find the use of qmshp relatively intuitive - in that it is designed to act as a drop-in replacement for the mono-core kernel.
Note: the experimental web-assembly sandbox and entity-exchange are still awaiting support for simultaneous execution however presently they are not the priority. Put simply: experiments with browser-based parallelism strategies - such as the use of web-workers - are underway however there are improvements to the native parallel-assemblers that have been deemed of greater importance and that are scheduled to surface before focussing on parallelism for the web.
Update: most aspects of the parallel-execution-model in quick-mesh have now been implemented and the scripting-language section of the project's homepage has been updated to reflect this.
Yet - in spite of the fact that portable parallelism works reasonably well - there are a number of areas warranting further investigation. In-particular one of the observations that the construction of the parallel-assembler has surfaced is that there is further scope for concurrency beyond merely task-level parallelism across individual entity-scripts. In-essence - by placing the responsibility for coordinating parallelism in the hands of the mesh-maker - the kernel essentially side-steps the requirement to undertake domain-decomposition. However in some instances - for example when one has a single large or complex object that cannot be easily broken down intuitively (rather than multiple largely distinct entities that one can partition easily) - the current approach misses out on valuable opportunities to further juice the assembly runtime. In other words - although it is beneficial to be able to exercise explicit/absolute control over the manner in which parallel-assembly occurs and actively assign individual entities and batches of entities to different processing cores - it would also be quite nice (and indeed extremely useful) if the kernel provided some assistance in cases where a mesh-maker may not know how best to decompose an arrangement.
To put it another way: currently we have to tell the kernel in an unambiguous manner how to parallelise a script for simultaneous execution - whereas one could imagine a setup within which the kernel partially (or potentially fully) automates the process for us - such that even in the case of a monolithic script we can still gain the benefits of multi-core evaluation (beyond the intrinsic vectorisation that occurs at a lower-level). As such this is the topic currently being explored with the aim of complementing the functional offerings of the parallel-assembler.
It's also worth noting that there are a number of anticipated limitations in automatic domain-decomposition relative to the current approach - the most prominent of which is the inability to match the efficiency inherent to parallelism driven by mesh-maker spatial-awareness. Nonetheless the benefits in terms of ease-of-use and the ability to deal with monolithics are sufficient to justify exploring this area in-spite of its open-ended nature. Ultimately the expectation is that automatic parallelisation is unlikely to provide the same level of efficiency as parallelisation driven by human insight - still in some instances it is better to have some strategy in place rather than nothing at all.
Fortunately certain aspects of the kernel's operation (such as its minimal-vertex-optimiser) are already ripe for parallelisation - however other components such as its boolean module will require some finesse to parallelise well and hence may take more time to mature.
So to synopsise: you can consider the support for the parallel-assembly kernel-directive in quick-mesh as quasi-complete - in that (with the exception of out-of-core parallel-writes, lower-latency IPC, cluster-compute and pre-emptive optimisation - which still require refining) most of the originally planned mesh-maker-facing facilities have now been implemented are are functioning to a reasonable standard. However in opening the door to parallelism within the grammar we have also (inadvertently) stumbled into a realm of open-ended kernel-internal performance improvements for which there is no clear or definitive end-point. Luckily though, most (if not all) of these enhancements can (and shall) occur silently in the background without affecting the way in which we express our parallel entities. In short if you've been holding fire in terms of constructing parallel-scripts then you can now dive in - and (as always) if you notice anything that seems off or any gaping holes in the approach or architectural omissions do not hesitate to report them.
Experimental Web-Assembly Editor
An experimental client-side editor enabling sandboxed use of QMSH in web-browsers is now in beta testing and can be found on the project's homepage (see the Tools & Resources section).
The QMSH-Sandbox is a basic script-editor and mesh-assembler for the quick-mesh grammar that runs in browser's supporting web-assembly. The sandbox aims to make it easier for you to try quick-mesh safely - i.e. without having to install additional software - at near-native speed.
Note: the sandbox emerged from experiments into supporting parametric entity-dynamics for the kernel's auto-generated monolithic Web-GL bundles. In many ways the sandbox is an off-shoot/spin-off derived from the investigative process. In plain-terms: it is not a production-grade system - rather it is a preliminary proof-of-concept (demonstrating the capacity to execute quick-mesh client-side in a browser) - which is turning out to be surprisingly useful for a number of unexpected reasons.
Note: to provide further background and context - the construction of a browser-based IDE was initially scheduled for shortly after the construction of cross-platform desktop IDEs. However due to unforeseen challenges in development - the testing and deployment of the desktop IDEs has taken longer than anticipated. This has led to an unfortunate state in which desktop mesh-makers are essentially left at a disadvantage relative to the use of the kernel on Android via the mobile-editor. This experimental sandbox aims to help remedy this state during the interim period within which the native desktop editors undergo finalisation and preparation for release.
Compiled for the web with the aid of emscripten - the sandbox offers a means to side-step the current limited CPU-architecture options for the native binaries - and the pending desktop IDEs.
The current plan is to use the sandbox to support exposition of the scripting-language. In particular: moving forward - the sandbox shall play a key role in the creation of video tutorials exposing core aspects of the grammar. This is mainly because it currently offers the simplest setup process for prospective and first-time mesh-makers to further experiment with the tutorial content.
Release of Visual-Editor for Android
A simple visual-editor for a subset of the QMSH-Grammar is now available for Android devices.
QMSH-Visual is a node-based graphical-editing tool for elementary 3D polyhedral entities written in the quick-mesh scripting-language. It is designed primarily to provide a stepping-stone for new mesh-makers who may not yet be confident scripting 3D entities directly.
Crucially: QMSH-Visual is not a replacement for the QMSH-Editor nor QMSH-Kernel. It is simply a tool to help you find your feet and get to grips with the QMSH-Grammar. Essentially QMSH-Visual is an assistive tool that introduces you to core features of the grammar in a more intuitive manner if you are a visually-inclined learner. A good analogy for QMSH-Visual is as training-wheels (or stabilisers) used by young cyclists. Another is as akin to a metronome for young musicians.
Vitally remember that QMSH-Visual is not designed to be (nor intended as) a fully-fledged 3D-editor - it is simply a tool to help you learn how to use key functions in the quick-mesh grammar such that you can progress to scripting with confidence.
→
QMSH-Visual on Google's Play-Store→
QMSH-Visual (Tool-Repository)Note: QMSH-Visual depends upon the QMSH-Kernel - therefore remember to also install the QMSH-Kernel for Android (also available in the tool-repo). You'll also need to ensure you've granted both apps storage permission as they use a device's storage to marshal 3D mesh data.
Note: if you are already using the QMSH-Editor you will find QMSH-Visual to be a far less powerful interface to the QMSH-Kernel. However (even for advanced mesh-makers) you may still find some modicum of utility in its use as a basic visual debug tool for spatial logic.
Additionally as an incidental - if you like fiddling with interactive generative tools then you might also find the process of creating node-graphs using QMSH-Visual to be quite fun.
Experimental Web-GL Support
Work is underway to bring Web-GL support to QMSH.
Presently this manifests as experimental support for emitting Web-GL compatible stand-alone static 3D entity-bundles.
Note: if you are using the command-line kernel you can try this out by adding the [-webgl] flag to your terminal invocations or makefiles. If you are using the mobile kernel you can simply select the stand-alone HTML, embeddable JSON or portable GLTF options.
Positively: this provides a relatively portable means to quickly view the 3D entities you create on machines and devices that may not have a 3D-mesh viewer installed. It is also quite handy for quickly sharing ideas with fellow mesh-makers (i.e. you can send entities - that can be viewed directly in a browser - as email attachments without external dependencies).
Negatively: the current support is limited to statics only - meaning parametric control is not exposed in the auto-generated Web-GL entity bundles.
Investigations into supporting dynamic entities in Web-GL are on-going - however there is not a definitive timeline yet for inclusion.
In terms of the current development track: enhancing support for GLTF outputs and exposing/handling user-interaction in WebGL - are the immediate priorities.
Experimental Raspberry-Pi Support
Work is underway to bring QMSH to the Raspberry-Pi.
An experimental 32-bit build of the kernel for the Raspberry-Pi operating system is available on the project's homepage to enable researchers, engineers, educators and hobbyists to start playing with low-overhead purely-procedural polyhedral-programming on the popular single-board computer.
Note: that the 32-bit build has been tested on the Raspberry-Pi Model-2 and Model-4. It should also run on the Zero (albeit at a much slower pace) - however if you encounter any problems - send an email to: support@qmsh.org.
Positively: this provides a means to create moderately complex 3D entities directly on the Raspberry-Pi without the added overhead associated with running traditional interactive modelling packages with an OpenGL GUI. Additionally - if you use the Raspberry-Pi in educational contexts (for example to tutor students in practical computer-science) then you can now also introduce them to 3D procedural modelling using the Pi.
Negatively: although you can now script 3D entities on the Pi - presently the options for viewing, examining and interacting with your creations on the Pi are limited - relative to desktop or mobile use of the kernel. In particular: most open-source 3D packages that are capable of running on the Pi (i.e. FreeCAD, Blender...) that might otherwise function as general-purpose viewers, are noticeably slower (interaction-lag-wise) than their desktop equivalents.
Note: that to side-step the limited 3D-viewer options for the Pi - you can use the kernel's experimental Web-GL output to view your creations directly in the Pi's browser. However note that on older versions of the Pi there may be perceptible rendering and shading issues in the WebGL display. Additionally at HD resolution (i.e. 1920x1080) the Pi's framerate for WebGL interactions (rotating and zooming) drops significantly.
The current development track is focussed on addressing the limited viewing options that hinder/impair the usability of the kernel on the Pi.
Although initial experiments look positive - it is worth noting that the decision as to whether to promote the Raspberry-Pi to an officially supported target platform is yet to be made.
Update: you can improve the rendering framerate for the kernel's experimental Web-GL outputs at HD-resolution by adding the no-MSAA configuration flag to each bundle's URL's hash. This disables multi-sampling anti-aliasing and should result in a noticeable increase in framerate on the Pi during entity orbiting and zoom events. For example: file:///home/pi/a.html#nomsaa
Update: with the advent of the entity-inspector it seems likely that the Raspberry-Pi shall be promoted to the state of officially supported target platform. However whilst the entity-inspector certainly improves the limited viewing options on the RPi for our procedural creations (effectively enabling more serious use of the kernel in both creative pursuits and educational contexts) - there are still a number of refinements and practical improvements to be made in order to enhance the mesh-maker experience further on the RPi. Additionally it will take some time to verify the operation of the inspector on the latest version of the Pi and (if need be) optimise/refactor for its new OS.
Experimental 3D Interchange-Format Support
Work is underway to extend the interoperability of the kernel's output geometries and their suitability to varying use-cases.
Practically this means experimental support for generating the following interchange formats has been added to the command-line kernel for beta testing. Simply add the corresponding flags to each kernel invocation command to test the output produced for each format.
-3mf → 3MF: 3D Manufacturing Format (Un-Compressed)
-amf → AMF: Additive Manufacturing Format (Un-Compressed)
-gts → GTS: GNU Tessellated Surfaces
-json → JSON: JavaScript Object Notation
-webgl → HTML: Standalone-WebGL-Bundle (html+css+js+glsl)
-gltf → GLTF: Open-GL Transmission-Format
-glb → GLB: Open-GL Transmission-Format (Binary)
-dae → DAE: COLLADA Digital-Asset-Exchange
-rib → RIB: RenderMan Interface Bytestream
-usd → USD: Universal Scene Description
Note: that as experimentally supported output formats - the manner is which the kernel emits these 3D interchange files is subject to change - hence always double check the output.
Update: V:0.1.9 added the -glb flag to support emitting GLBs without the (less intuitive) flag combination -gltf -b required in earier versions. The benefit of the revision is that it enables you to generate both ASCII GLTF and binary GLB simultaneously as simply: -gtlf -glb (in a single invocation) rather than necessitating two invocations to accomplish the same. Note: if you are used to the pre-V:0.1.9 way of doing things - do not worry. You can continue to use the old -gltf -b flag combination until you are ready to transition. For as long as you do not add the GLB flag to your invocations - the kernel will honour the prior behaviour. If the GLB flag is present then adding the binary flag (-b) is unnecessary - unless you are also generating formats (such as PLY and STL) which support both ASCII and binary variants that cannot be discriminated by file-extension alone.
Note: if you are working with formats designed for fabrication (specifically: 3MF and AMF) make sure to double-check that the yield is suitable before initiating a print. Vitally: given that the kernel supports the emission of manifold and non-manifold mesh it is possible to emit invalid 3MF and AMF if you utilise functionality that invalidates the watertightness of entities in a script. In simple terms - it is the invoker's (i.e. the mesh-maker's) responsibility to ensure a topologically, volumetrically and geometrically valid yield if you wish to feed your creations into additive and/or subtractive manufacturing devices and machines. Although many/most consumer-level and industrial-grade fabricators include verification and appropriate warnings for invalid inputs it is worth being aware of this if (for example) you roll-your-own hardware and/or software utilities.
Update: V:0.2.4 revised the manner in which parallel-entities are emitted in order to add support for hierarchical yields in GLTF and GLB. The primary advantage is that it enables each sub-element in a parallel script to be mapped to a distinct node within the popular transmission format. This ensures that in instances where one wishes to access each sub-element independently (within a receiving application or target executing context) the structure and partitioning of an arrangement is preserved. Currently this applies to GLTF and GLB, however OBJ outputs also support a similar form of grouping/partitioning via the object ('o [name]') adornment - as do DAE and JSON outputs. Given that this revision may not be desirable to all - i.e. in some cases treating a parallel entity as a monolith entity may still be preferable (for example when one wishes to minimise the number of draw-calls in rendering or visualisation) - the revised hierarchical write is guarded by the (currently experimental) -modular (or -nodes|-nodular|-modularise|-nodularise) command-line argument. Plainly: if the -modular flag is not present in an invocation then the prior concatenated parallel write occurs. Note: adding the -modular flag to an invocation only has an effect for parallel scripts.
Note: V:0.2.4 revised the name-literal propagation method on output to ensure that parallel and monolith interchange files internally use the names you specify (either as script file-names or parallel-sub-element name-literals) - rather than the previous default generic 'entity' tag.
Note: support for RIB and USD exports (added in V:0.2.5) is currently limited to mesh-data - primarily to facilitate injecting entities into scene-wrappers for high-fidelity rendering. For emitted RIB assets you can use ReadArchive to insert entities into your scene files, whilst for USD you can use your preferred/pipeline-specific layering or referencing strategy for including geometric assets.
Note: for USD the current implementation provides support for the ASCII USDA format with some constraints in terms of the attributes that can be marshalled. Specifically - given that USD does not provide a clean means to embed per-vertex colours - the default behaviour is to omit colours even if the -rgb command-line flag is present in an invocation. There is a workaround that allows partial support for coloured USD assets however it relies upon out-of-order emission of mesh elements. In essence: it is possible to automatically partition each entity mesh into sub-mesh such that each sub-mesh uses a single coloured shader with uniform diffuse colour and opacity. The tricky aspect is that if this partitioning is performed in a manner that adheres to the DOIEO principle there is potential for non-contiguous groups of mesh-elements to induce an explosion in the number of sub-mesh required to represent a RGBA USD entity. The simplest way to avoid this undesirable result - and minimise the number of sub-mesh required for RGBA USDs - is to automatically group mesh-elements by colour prior to export (that is to re-order the yield). The practical downside of out-of-order emission - is that it still requires a greater number of draw-calls/rendering-passes than are strictly necessary - even when the re-ordering minimises the count of sub-mesh required. The end result is that lossless colour-representation for texture-free geometric assets in USD (at least at the per-vertex-level) induces storage and runtime inefficiency that the kernel cannot currently circumvent. Although USD's GeomSubsets could conceivably help address the multi-material mesh problem - the implications for other parts of pipelines (e.g. in physical simulation) - coupled with the fact they still only address per-face (rather than true per-vertex) materials is why they are (currently) omitted. In spite of these limitations - if you find you need colours in your USDs - you can add the (currently USD-specific) out-of-order: --ooo command-line argument to your kernel-invocations that include the -usd export flag. Additionally bear in mind that you can reduce the storage space required for ASCII USDA (i.e. convert to-and-from USDC binary-crates) using tools such as usdcat.
Note: functionality is added regularly so check back for progress updates.
Issue-Tracker
This section lists known issues and corresponding work-arounds.
Kernel: Linux CPU-Architecture Support
Issue: only x86_64 binaries are presently available for the command-line kernel on Linux.
Resolution: currently - unless you have access to a machine that supports the x86_64 instruction set - you should use the command line kernel on Mac-OS or Windows operating systems.
Note: binaries for alternative CPU architectures (notably arm) shall be added to the project's homepage in due course - subject to hardware availability and testing.
Additionally: investigations are on-going to establish the benefits, limitations and trade-offs inherent to alternative Linux distribution methods for the kernel's binaries. Essentially trials of Snap, Flatpak and AppImage are underway - however a firm decision is yet to be made. Presently AppImage is looking like the most suitable distribution method however this is subject to change.
***
Update: experiments with AppImages have proven largely successful in that it they have confirmed that AppImages offer an excellent means to package Linux applications for execution across a myriad of distributions. Yet - whilst the trials of AppImage have yielded largely positive results - it has also become apparent that: in the case of dependency-free tools (such as the kernel) - they are not strictly necessary. Indeed most of the benefits offered by AppImages are already intrinsic to the kernel's monolithic architecture. Specifically: the kernel already conforms to the 'one-app-one-file' paradigm. Further: as a self-contained application it does not require installation or modification to a mesh-maker's system and can be run from anywhere - with or without administrative privileges (i.e. it supports the 'ready-to-roll' approach to power-tool-distribution popularised by languages such as Zig). As such - the current thinking is that it does not necessarily add much value to the mesh-maker workflow under Linux to wrap the command-line kernel superfluously. Instead the use of AppImages seems more appropriate for dependency-laden tools such as the entity-inspector - which (unlike the kernel) make use of system-level utilities that are not guaranteed to be present across all distributions - such as GTK's OpenGL helper types and classes. In simple terms: AppImages are (for any Linux-lover) a supremely cool technology - however as they do not intrinsically solve the multi-CPU-architecture problem (to the same extent that fat-APKs do/once-did under Android) their adoption is not currently a priority. Instead the current focus is supporting i386 builds (for older machines) alongside arm and risc-V builds (for newer machines) so to complement the current x64 builds and provide better coverage across the dominant and emerging CPU architectures.
Note: that (incidentally) although QEMU helps massively in terms of emulation - changes to the kernel's officially supported CPU-architectures (for each target platform) shall not be made prior to concrete testing upon physical hardware. In other words the anticipation is that BSD support (i.e. OpenBSD, FreeBSD...) shall drop before i386, arm and risc-V support.
It's also worth being aware that - from a technical perspective (depending upon one's take) - the use of system-level libraries such as glibc could be construed as a form of dependency given that the kernel's current binaries are not statically linked. This aspect represents a practical trade-off made in favour of reducing the distribution's size at the expense of (potentially) introducing incompatibility with very old machines. So whilst the vast majority of Linux users - with access to the x64 architecture - should have no problem getting up and running with the current beta-releases - there is still scope for lack of support across certain versions of the OS that will also require addressing.
Entity-Inspector: Functional-Parity Across Platforms
Issue: certain aspects of the inspector's user-interface - such as the fixed-function/programmable rendering-pipeline toggle option - behave differently (i.e. in a non-uniform manner) upon certain OS - most notably Windows. In particular there is a known bug on older Windows machines that can cause segmentation faults when one attempts to switch the rendering backend at runtime.
Resolution: currently - if functional-parity and error-free operation are paramount to you (and if it is possible and practical) then you should opt to use the entity-inspector and command-line kernel upon Unix-like/derived/compatible operating systems such as Linux, Mac-OS and the Raspberry-Pi.
Note: if you are in the unfortunate state of being bound solely to Windows you can still make use of the entity-inspector - just bear in mind that the rendering-pipeline toggle has been disabled (via a compile-time-guard) for Win32 builds in order to prevent the application from crashing unexpectedly.
It is not currently clear how best to resolve this issue as it has (so far) not been possible to reproduce under other operating systems. To further complicate matters, the issue is not present under all versions of Windows. Specifically some instances of the OS simply fail to render when one switches from programmable to fixed-function but do not segfault - whilst others crash immediately.
Entity-Inspector: Native-IO
Issue: use of the native input-output file-browsers (for open and save operations) under Linux has the potential to trigger a crash when displayed repeatedly in quick succession.
Resolution: at the moment you can use the default inline-IO option or drag-and-drop input to avoid/side-step the sporadic native-IO bug until the fix has been added.
Note: preliminary diagnosis has determined that this particular issue stems from the use of a procedurally-generated runtime-assigned application icon - which under certain circumstances seems to cause an invalid read when one displays a GTK file-chooser. However whilst the problem has been pin-pointed - further investigation is required to identify the underlying root-cause and a stable fix. At the moment a stop-gap/band-aid work-around has been applied to mitigate the risk of application crashes - however this will not suffice as a long-term solution.
Mobile-Editor: Play-Store Policy Changes
Issue: the latest version of the mobile-editor is not yet available on the Play-Store.
Resolution: presently - you can download the official release APK for the latest version of the mobile-editor directly from the project's homepage or the quick-mesh tool-repository.
Note: unfortunately the structural revisions (to the application's architecture) - required to remove the dependence on the storage permission (in-line with Android-11's mandate of scoped-storage) - can not currently be implemented without the loss of (or substantial detriment to) core functionality - such as opening and saving scripts, assembling monolith or parallel mesh, exporting 3D interchange files, supporting session-persistence over power-cycles, editing-environment management and other core functions. Whilst the increasing frequency with which breaking changes are introduced to Android certainly poses challenges for developers under the platform - as mesh-makers you need not fear! Updates to the mobile-editor shall continue (according to the implementation itinerary) - with releases made available in-sync with the kernel through (at the very least) a direct download.
Note: investigation into restructuring the application to enable it to function with or without the use of the storage permission is underway - however the time-frame for completion is not yet known.
From a practical perspective - what this means is that the mobile-editor shall (for the time being) continue to target Android-10 and hence be unsuitable for updating on the Play-Store.
Update: fortunately (policy changes aside) the latest versions of the mobile-editor (V:0.2.2+) have been tested and verified as functional under both Android-11 and Android-12.
Note: testing under Android-13 and Android-14 is scheduled for later this year.
Mobile-Editor: Localisation/Translations
Issue: the mobile-editor currently only supports English locales.
Resolution: unfortunately (presently) the only sure-fire resolution is to learn English - or at the very least to gain greater proficiency reading English. Sadly (for the foreseeable future) the mobile-editor may not be suitable for non-English-speakers.
Note: if you are not comfortable reading English but still wish to make use of QMSH immediately - you are advised to ask a friend (who is comfortable with English) to help you get started. Indeed pair-programming with a buddy/friend/colleague/comrade has the potential to be an excellent way to side-step the language-barrier issue. The expectation is that: once you have found your feet (i.e. understood the basics) - the abstract/transcendental nature of geometry and programming should enable you to be procedurally-productive in-spite of the absence of localised documentation.
Note: effective localisation is on the TODO list, and as time progresses (and the grammar, kernel and documentation mature) - localisations shall be added for French, Spanish, Russian, German, Indonesian and Portuguese. However due to the volume (i.e. the sheer scope) of the content that must be localised - and given the frequency with which the grammar and kernel are revised - this process may take several years to fully complete.
Update: localisation investigations are now underway and are expected to begin to manifest first in beta form within the mobile-editor's library-reference in the coming year.
Update: localisation investigations are now underway - however with the advent of the entity-inspector the schedule for localising the mobile-editor has been revised. Put simply: official translations for the graphical-interface and the logic for additional user-defined language packs shall appear first in the entity-inspector - then later in the mobile-editor - due largely to the fact that the entity-inspector contains far fewer strings to translate and hence should be ready sooner.
Mobile-Editor: Tablet-Support
Issue: usability issues in the mobile-editor on tablets, chromebooks and similar devices.
Resolution: report any issues you encounter such that they can be fixed.
Note: although (in principle) the mobile-editor should function out-of-the-box on tablets (i.e. it has been designed to work agnostically independent of device type) - practically unfortunately (due to logistical hardware-access constraints) it has not yet been possible to perform thorough usability testing of the mobile-editor (for quality-assurance purposes) on such devices.
Official support for such devices shall be added incrementally - starting with 7-inch and 10-inch tablets. You can refer to the release notes accompanying the mobile-editor for progress.
Update: adapting the mobile-editor for use on tablets is nearing completion. Presently it has been tested on 10-inch and 7-inch tablets. Positively: the editor's back-end (i.e. the kernel) functions out-of-the-box just as for mobiles. The main adjustments that have been made are to its front-end - in particular resizing and adjusting the interface-components to make better use of the larger displays and exposing auxiliary components to support toggling between mobile and tablet layouts. This process is still on-going, however the adjustments have already begun to appear in the mobile editor. For example you may have noticed that the geometry-viewer now also supports both vertical and horizontal split-layouts with the parametric-controller which vastly improves overall usability when in landscape device-orientation on larger screens. Although the changes have helped there are still a number of components (such as the Procedural-Editor, Library-Reference and Console-Trace) that could benefit from further revision prior to official tablet support.
Note: supporting chromebooks, netbooks and notebooks shall be addressed next.
Note: with the release of the quick-mesh entity-inspector (which already offers facilities above the features offered by the mobile-editor) - it seems a cleaner and more efficient strategy is to simply use the entity-inspector directly on notebooks and laptops rather than bloating the mobile-editor with non-touch-screen capabilities. In this manner the aim is to retain the light-and-tight nature of the mobile-editor whilst offering a richer user-experience on more capable machines.
Mobile-Editor: Undo-Redo Support
Issue: no undo-redo support in mobile-editor when writing scripts.
Resolution: be careful editing your scripts - for example rather than deleting a block of statements - simply comment them out instead. Additionally: remember to save your scripts! Alternatively - if undo-redo support is a must for you - then you can use the mobile-kernel with a third-party text-editor. If you opt for the external editor option - and the editor you choose to use supports source syntax-highlighting - then you can select C, C++ or Java language settings for your scripts.
Note: undo-redo support is in development.
Update: preliminary undo-redo support has been added to the mobile-editor in order to help improve the editing experience for fellow mesh-makers. Presently the ability to undo and redo the editing stack is bound to the grammar-centric IME - meaning that if you are are using the standard platform IME or an external keyboard undo-redo functionality remains inaccessible. All things being equal, full undo-redo support (i.e. for all supported input methods) should appear later this year.
Unity-Plugin: Missing Parametrics
Issue: the plugin for Unity does not (presently) expose inspector widgets to interactively modify the parameters defined in scripts - however the mobile-editor does.
Resolution: pending.
Note: parametric-control in the Unity-Editor (ahead-of-time) is in development - however it is unclear yet whether support shall be added for parametric-control in the Unity-Player (at runtime).
You can refer to the plugin's Unity Asset-Store listing for progress.
Kernel: Minimal-Vertex-Optimisation
Issue: minimal-vertex optimisation may fail for certain polyhedral arrangements in spite of their grammatical validity and structural and spatial coherence - typically manifesting as visible topological errors in an entity (such as a hole in a surface that should be manifold).
Resolution: presently you will have to modify your entity to avoid/side-step the troublesome elements of the arrangement - using your own awareness of the spatial relations amongst the components that define your entity. This is somewhat of an art - yet comes with practise. Often reducing a script's boolean-logic assembly complexity will be your first port of call in this regard.
Note: if you are sure that there are no subtle spatial oversight bugs in your script - then the error may be the result of a bug in the MVO routine. You can determine this by running the script as a basic-CSG-mesh (i.e. with no optimisation: -no_op). If the artefact is resolved (i.e. no longer manifests) as a product of the change in execution mode then it indicates an MVO bug - else it indicates an assembly error possibly resulting from the application of boolean-logic - or from a malformed entity.
Update: V:0.2.5 introduced improvements to the kernel's MVO implementation that essentially automatically detect and fix fail-case arrangements such that the kernel does not panic and discard elements as it did in previous versions. These revisions should help stabilise the workflow and reduce the requirement for you to side-step issues for entities that are grammatically and spatially valid - however there may still be edge-cases that are yet to be encountered - therefore it is still advisable to double-check the yield. In practical terms this means that (generally) there should be far fewer (if any) instances in which the kernel emits polyhedra with missing elements. However there is a caveat to this in that the kernel now treats quasi-degenerate elements slightly differently - which may have a bearing on subsequent external use of MVO'ed entities. Positively the revised MVO does not rely upon ad-hoc tricks such as symbolic-perturbation or vertex-jittering and hence should work in all instances of kernel panic. Negatively though it is not currently clear whether it is possible to formally prove the validity of the MVO method. This area is still under investigation.
Kernel: Non-Linear-Modifiers
Issue: applying certain non-linear modifiers (such as the twist operator) has the potential to induce unstable polyhedral arrangements - especially when applied to compound entities - which can spoil subsequent boolean-logic operations and minimal-vertex optimisation.
Resolution: pending.
Grammar: Automatic-Argument-Linearisation
Issue: automatic-argument-linearisation is only currently supported for the grammar's native (built-in) 2D and 3D geometry-generator functions.
Resolution: pending.
Note: AAL support for the grammar's remaining natives (transforms, instancers, utilities...) is in development. AAL for user-defined functions may take more time to mature.
Update: most of the currently supported built-in routines now respond to AAL however some require further revision in order to fully take advantage of the dynamism offered by the grammatical construct. Although these tweaks are underway - it is worth being aware that support for the associative-map entity-type will have to mature before the current AAL formulation is considered complete. Keep an eye on the release notes accompanying each updated version to track progress.
Note: if you encounter an issue using the kernel or grammar that is not documented above, then you can report it by messaging: feedback@qmsh.org
If you need assistance working around these issues contact: support@qmsh.org
Trouble-Shoot
This section outlines a number of debugging and trouble-shooting strategies for scripts written in the quick-mesh scripting-language.
Missing Return Statement
scripting
Issue: missing return statement - typically resulting from scripting oversight.
Resolution: add a suitable return statement to your script and re-assemble.
Remember: all quick-mesh scripts require a return statement to be considered grammatically valid.
Failure to Terminate Statement
scripting
Issue: failure to terminate statement - often the result of omitted (typically forgotten) semi-colons at the end of a line.
Resolution: make sure each script statement is terminated by a semi-colon.
Remember: in quick-mesh statements are terminated explicitly as in C, C++, C# and Java - rather than implicitly as in Python.
Invalid Use of Commas and Dots
scripting
Issue: invalid use of commas instead of dots (and vice-versa) typically resulting from input typing errors.
Resolution: ensure that these punctuation symbols are used appropriately in a script.
Remember: in the quick-mesh grammar dots (periods) are used for decimal numbers and post-fix function notation - whilst commas are used to separate elements in argument lists and arrays.
Invalid Input Argument(s) to Built-In Function
scripting
Issue: invalid input arguments supplied to a built-in function typically as a result of unfamiliarity with the native function signatures.
Resolution: check and then revise the input arguments in the offending function invocation.
Remember: if you get stuck the grammar's documentation details the set of overload signatures supported for each language symbol. There are also examples that provide practical clarification of how to invoke many of the native functions.
Note: it is natural to be unsure of a language's standard-library as a new-user. As time progresses and you use the native functions more frequently you should find that it becomes easier and easier to express yourself in quick-mesh without having to continually check the arguments to the built-in functions - largely as a product of you beginning to imbibe and remember them more intuitively.
Unbalanced Operative Scope
scripting
Issue: unbalanced operative scopes caused by either missing (too few) or superfluous (too many) brackets, parenthesis and braces in a script.
Resolution: add (or remove) brackets, parenthesis and braces to ensure that each operative scope that is opened (pushed) in a script is also closed (popped) appropriately.
Remember: in quick-mesh (as often in life) - balance is key.
Note: if you are using the mobile-editor under Android - you can use the 'Highlight-Scoping-Operators' display toggle (in the Procedural-Editor's tri-dot action-bar drop-down-menu) in order to distinguish scoping characters from other parts of a script for greater clarity in debugging.
Extremely Large Mesh
geometry
Issue: out-of-memory errors resulting from attempts to instantiate and/or manipulate very large mesh on devices or machines with limited RAM.
Resolution: reduce the number of vertices in the offending entity's mesh by lowering the discretisation resolution of curved regions and/or reducing the CSG boolean-logic complexity.
Remember: that quick-mesh is optimised for low-polygon-count 3D modelling. In particular minimalistic use of vertices is key to getting the most out of the kernel on devices with limited RAM.
Careless Instancing
geometry
Issue: failure-to-converge errors (i.e. scripts running indefinitely) and/or out-of-memory errors resulting from reckless use of the native instancing functions.
Resolution: check and then revise the input cardinality arguments to the instancing function or functions that cause the non-convergence. Additionally make sure to capitalise on the fast (F) instancing-mode prefix-modifier whenever the elements being instanced are spatially disjoint.
Remember: that instancing in quick-mesh is a memory-intensive class of operation because it involves explicitly duplicating the geometric elements in a mesh and potentially retopologising the instanced-set (with the union boolean-operator) in the presence of overlap.
Note: in quick-mesh effective instancing is somewhat of an art - yet (as most things) comes with practise. The key is that when instancing less-is-more. Specifically: the less work you instruct the kernel to undertake - the more you can express. Therefore take advantage of the fast-instancing-mode prefix-specifier (F) whenever you can - and remember to think-before-you-mesh.
Topologically Invalid Entities
geometry
Issue: undefined-behaviour errors (i.e. unexpected or seemingly bizarre meshing results) as a result of geometric entities with topological issues and inconsistencies.
Resolution: first find (locate) and secondly resolve (correct) the entity or entities exhibiting topological inconsistency - by altering the script statements corresponding to their definitions.
Note: common causes of topological issues (to watch out for) include: validity-condition violations in parametric primitive instantiation (for example double-check the rounding and beveling arguments to variant natives), incoherent numerical values in arrays supplied as input to data-driven primitives (for example defining a polygon vertex-list array that contains self-intersecting edges) and invalid use of generalised cylinders (which can also exhibit as volumetric issues).
Volumetrically Invalid Entities
geometry
Issue: failure-to-converge errors and/or undefined-behaviour errors resulting from geometric entities with ill-defined or invalid volume.
Resolution: as for topologically invalid entities - first find (locate) and secondly resolve (correct) the entity definition(s) that cause(s) the volumetric inconsistency (if it is unintentional).
Remember: that quick-mesh is (in some regards) much like the C programming-language in its relaxed attitude towards the enforcement of constraints and policing of potentially dangerous or unsafe operations. In particular in quick-mesh one assumes that the human mesh-maker is smarter than the kernel - and hence is smart enough to know what they are doing to the extent that they do not require their hand-holding. In layman's terms: the implicit expectation is that if you define a volumetrically invalid entity it is because you want a volumetrically invalid entity for a purpose that may not be obvious to, apparent to or trivially determinable by the kernel.
Note: generally speaking (in quick-mesh) volumetric-issues in an entity go hand-in-hand with the presence of topological-issues - in the sense that they both manifest as similarly incorrect meshing results - and that (often) one causes or further exacerbates the other - i.e. an entity exhibiting volumetric issues will typically (though not always) yield topologically invalid results when used in subsequent operations (if it does not already) and vice-versa.
Rendering & Shading Artefacts
geometry
Issue: perceptible shading discontinuities and rendering artefacts near the boundaries of polygon contours - especially between adjacent surface smoothing-groups - typically resulting from low-quality (skinny/sliver/near-degenerate) triangles in minimal-vertex tessellations.
Resolution: the simplest way to resolve such issues is to retopologise the offending portions of an entity's surface - by replacing the corresponding native primitives with alternatives that limit the scope of the appearance of these skinny sliver triangles. For example opting for bi-linearly sub-divided variants is a common approach, as is explicit break-line clipping to manually enforce artefact minimising topological contours.
Remember: when combating shading artefacts resulting from minimal-vertex-meshing try to balance the introduction of (technically) superfluous vertices relative to the improvement that results. Admittedly - this will require good judgement on your part - however as with most things quick-mesh - this comes with practise.
Note: the mobile-editor's extended-usage-guides contain a short outline of strategies for combating shading artefacts that result from low-quality triangles. For more detail refer to the guide - 'Advanced Techniques: Combating Shading Artefacts using Sub-Divided Variants'.
Malformed Generalised Cylinders
geometry
Issue: invalid meshing results (i.e. topological and/or volumetric issues) present in entities that exploit the data-driven generalised-cylinder functions: revolution, toroid, extrusion, and the cyclic and open profile-rails.
Resolution: double-check and then revise the input shape or shapes used to generate the GC. For example for the toroid and revolution functions you may need to move the input-shape away from the origin - such that the shape vertices are either all +X or -X but never a mix of +X and -X - as this will yield a malformed self-intersecting surface with ill-defined volume. As another example (for the profile-rail functions) check that the corresponding AABB-span (either along the X-axis or Y-axis depending on the GC's axis combination) for the profile-shape is less than roughly half of the minimum edge-length of the rail-shape - or more accurately that the profile-shape does not yield intersecting rail-segments. You can also modify the size and/or position of the profile-shape and/or the rail-shape to avoid the malformed result.
Remember: that the generalised-cylinders exposed by quick-mesh are considered constrained-GCs in the sense that they exhibit behavioural constraints relative to free-form MRF (minimal-rotation-frame) 3D sweeps. Whilst some of these behavioural constraints are explicitly enforced by the kernel (for example the shape cyclicality constraint which governs the support for open and closed profile-rails), the enforcement of other informal constraints rests upon the shoulders of the mesh-maker. As an example: the maximum-projective-distance constraint (which governs the suitability of input shape pairs) may be justly violated in certain situations (for example for aesthetic or artistic reasons) as long as the resulting GC is not used in subsequent boolean-operations. In plain terms: the prevention of malformed GCs relies largely upon you (the mesh-maker) selecting appropriate input shapes.
Note: effective use of the generalised-cylinders exposed by quick-mesh requires a fair amount of experience with the kernel and grammar. In particular: relative to the vast majority of the native-geometries (which expose relatively simple parametric interfaces) the behaviour of the GCs can be harder to intuit for new mesh-makers. Therefore do not become disheartened if at first you struggle - for the more you practise creating GCs in your scripts the easier the process will become.
Self Referencing Functions
scripting
Issue: failure-to-converge errors (i.e. scripts running indefinitely) and/or segmentation-faults causing immediate termination without error emission - typically resulting from invalid attempts to use recursion and/or accidental invocation of a function within its own body (for example when one actually intended to invoke a related or alternative overload).
Resolution: remove the self-reference from the offending function's body.
Note: take extra care coordinating the definition and invocation of function overloads in your scripts as this is most often the cause of self-referencing function issues.
Self Referencing Arrays
scripting
Issue: failure-to-converge errors and/or segmentation-faults causing immediate termination without error emission - stemming from improper use of a generic array in the form of any self-nesting arrangement that results in an infinite-cyclical-evaluation loop.
Resolution: break the cyclical-evaluation loop by removing the self-reference from the offending array's elements.
Note: although it is not strictly an error to define a generic array that contains a reference to itself - it is a critical error to attempt to access such an array in any auto-linearising context - for example when invoking a native AAL-supporting function or in a return statement.
Cyclic Function Dependencies
scripting
Issue: failure-to-converge errors (i.e. scripts running indefinitely) and/or segmentation-faults causing immediate termination without error emission - typically resulting from invalid attempts to use recursive constructs and/or accidental indirect invocation of a function within a descendent function's scope.
Resolution: as for the direct self-referencing function error case - remove the indirect cyclic reference(s) from your script to correct this type of issue.
Note: cyclic function dependency issues typically indicate the presence of malformed or invalid generative logic in a script.
Note: that this is not an exhaustive list of methods to debug scripts - rather these are commonly encountered issues that tend to crop up most when one is first getting to grips with the kernel and grammar. Hence by highlighting them - the aim is to help you better find your feet by clarifying some of the issues to watch out for.
***
Additionally: the following debugging strategies are applicable to trouble-shooting the tools and applications in the quick-mesh eco-system.
Aggressive Device-Manufacturer Battery-Life Management Utilities
android visual
Issue: foreground service initiation failure under certain vendor-specific variants of the Android operating-system (most notably those developed by HMD-Global) - which can interfere with and prevent the valid execution of mesh-generating operations in auxiliary applications that depend upon the mobile-kernel - such as the assembly tasks undertaken by the visual-editor.
Resolution: the simplest way to side-step this issue is to launch the mobile-kernel before the visual-editor and then to keep the mobile-kernel on the back-stack whilst you use the visual-editor. An alternative approach (for those with the wherewithal) is to add the mobile-kernel and the visual-editor to the device's whitelist.
Note: that (in the strictest sense) this is not an issue with the kernel's interop per se - but rather a problem stemming from the manner in which some vendors have implemented battery-life preservation utilities on certain versions of the platform and for certain devices. Fortunately this issue should (in principle at least) only affect a small fraction of mesh-makers - given that the vast majority of vendors (indeed almost all) implement Android variants that do not exhibit this issue.
Storage-Permission Not Taking Effect
android editor
Issue: the mobile-editor continues to display the 'build-error: unable to read kernel output data' error message even after granting the storage permission.
Resolution: restart the mobile-editor (i.e. close it and re-open it) in order to ensure the permission change has fully taken effect. You will be able to tell whether the restart has worked by selecting the Geometry-Viewer tab - which will display the default monotone Q-tile icon if the storage permission has been granted - or the fallback tri-tone cuboidal-triplet if not granted.
Note: that this behaviour varies from device to device and amongst different versions of the platform. For example certain devices will work immediately after the change in permission (without having to restart) whilst others may not register the configuration change within the app's context immediately.
Note: as for the grammar-centric debugging methods - the tool debugging methods outlined above are non-exhaustive and largely apply to new mesh-makers.
Development
This section collates supplementary notes related to the development of quick-mesh.
This includes implementation progress trackers for the kernel, scripting language and eco-system tooling - alongside computational and geometric performance traits.
Parallel-Assembly Support across Eco-System Tooling
This note clarifies the current state of parallel-assembly feature-support across the quick-mesh eco-system. For each feature (related to the use of the parallel directive in scripts) a short description is provided to clarify the functionality - followed by a summary of support for each tool.
Sequential-Execution
→ 'assembling parallel sub-elements one after another - i.e. fallback evaluation'
Supported: Kernel, Inspector, Editor, Sandbox, Exchange
TODO: -
Multi-Core Simultaneous-Execution
→ 'assembling parallel sub-elements in-tandem/concurrently using multiple CPU-cores - so to reduce the overall runtime by roughly a factor of the number of cores used'
Supported: Kernel, Inspector, Editor
TODO: Sandbox, Exchange
Re-Assembly Culling
→ 'skipping the re-assembly of parallel sub-elements whose source remains the same between successive invocations - within interactive executing environments'
Supported: Inspector, Editor
TODO: Sandbox
Distributed-Execution
→ 'assembling parallel sub-elements concurrently on a cluster of heterogeneous devices or machines connected over a wired or wireless network'
Supported: -
TODO: Kernel, Inspector, Editor
Parameter Binding & Mutation
→ 'handling parametric control independently for each sub-element in a parallel assembly'
Supported: Inspector, Editor
TODO: Sandbox, Exchange
Variant Binding & Selection
→ 'handling parametric variants independently for each sub-element in a parallel assembly'
Supported: Inspector, Editor
TODO: Sandbox, Exchange
Public (External) Directives
→ 'applying public directives (such as #unit) for each parallel element'
Supported: Kernel, Inspector, Editor, Sandbox, Exchange
TODO: -
Private (Internal) Directives
→ 'applying private directives (such as #execmode) for each parallel element'
Supported: Kernel, Inspector, Editor, Sandbox, Exchange
TODO: -
Experimental Directives
→ 'handling experimental directives (such as #osds) correctly for parallel elements'
Supported: Kernel, Inspector, Editor, Sandbox, Exchange
TODO: -
Batching|Invocation-Grouping
→ 'batching (or grouped invocation) for sub-elements to reduce the overhead associated with parallel-assembly - specifically the process creation cost'
Supported: Kernel, Inspector, Editor
TODO: Sandbox, Exchange
CCPP: Constant-Cost-Parallel-Prefix
→ 're-cycling global parallel-prefix execution state across sub-elements to reduce the cost - by guaranteeing (at most) a single invocation of the precursory block irrespective of how many sub-elements are defined'
Supported: Kernel, Inspector
TODO: Editor, Sandbox, Exchange
Remember that parallelism in quick-mesh is relatively fresh and subject to revision.
Mesh Assembly Stability by Target Platform
This note outlines the current state of the kernel's mesh-assembly stability across the supported platforms. Specifically this highlights the disparity between platforms for which the kernel achieves mesh-assembly-equivalence relative to those for which the kernel currently fails to guarantee such.
→ Linux ✓
→ Mac-OSX ✓
→ Windows ✓*
→ Android ✓*
→ Web (WASM|ASM.js) ✓*
→ Raspberry-Pi ✓
Note: * = Provisional/Tentative (V:0.2.3+)
In other words, on Linux, Mac-OSX and the RPi-OS the kernel functions as intended - such that entities that can be assembled on any one of these stable platforms are essentially portable amongst the other stable platforms (subject to hardware-constraints such as sufficient memory).
However on Windows, Android and the Web (WASM|ASM.js) - the kernel is known to fail in certain cases for which it succeeds under the stable platforms.
Update: recent revisions to the kernel's operation (circa V:0.2.3) have improved mesh-assembly stability particularly for the trouble-case platforms (namely Windows, Android and the Web) - such that they now perform as the stable platforms for the prior known error-trigger test-cases.
Bear in mind though, given that there have previously been unexpected issues under these OS, the assignment of the stable classification for Windows, Android and the Web should be considered provisional or tentative (i.e. subject to change in the event that any further issues arise).
Development Stack: Compilers
This note lists the compilers used to build the reference implementations of the quick-mesh kernel.
→ Linux | gcc
→ Mac-OSX | clang
→ Windows | msvc
→ Android | ndk
→ Web (WASM|ASM.js) | emscripten
→ Raspberry-Pi | gcc
Mesh Compression for Pre-Assembled Procedural Entities
Version 0.1.9 introduced a number of simple lossless polyhedral compression schemes in order to reduce the size of the kernel's experimental stand-alone Web-GL outputs - so to minimise their network retrieval latency. These simple compression schemes have been applied to the preview mesh for 2
8-QMSH-Scripts with relative success - yielding a roughly 40-50% reduction in file-size for the mesh displayed - vitally without the introduction of external decoding dependencies.
You can take advantage of this immediately whenever you add the
-webgl flag to your kernel invocations - just bear in mind that it is a work in progress - and hence double check the yield.
Simply add the
-compress flag to your kernel invocations (that also include the experimental
-webgl flag) - as demonstrated in the following example:
→
./qmsh -rgb -nxyz -tess -webgl -compress a.qmsh...which should yield a compacted Web-GL bundle named 'a.html' whose file-size is smaller than an equivalent uncompressed bundle - whilst representing the same geometry.
Note: that for very small entities the overhead associated with inlining the functions to unpack the compressed geometry can actually have an adverse effect and bloat a bundle's size instead of shrinking it. As such the kernel currently makes an exception for entities with less than or equal to 64 vertices - and never applies compression in such cases. The 64 vertex limit is simply an empirically derived threshold value that aims to ensure that the inline compression never does more harm than good. Bear in mind additionally that compression takes time proportional to the number of vertices and triangles - hence if you are using the Web-GL bundles as ad-hoc viewers in contexts and environments lacking native 3D-viewers (such as on the R-Pi) - you may find disabling compression helps to speed up editing iterations. You can then enable compression once your entity is complete.
Although further investigation is required (to improve the compressive capabilities of the kernel) - the anticipation is that at some point this functionality shall transition from an ancillary feature to a standard mesh output channel. The logistical challenge in expediting this transition lies in the fact that (save for GLTF and GLB) the standard output interchange formats supported lack the expressive scope to directly carry/convey the kernel's compacted mesh without substantial revision.
In other words - it is unclear at present how best to expose the compression schemes beyond the kernel's stand-alone Web-GL exports. This may signal the requirement for a native kernel export format enabling portable interchange of compressed pre-assembled content and for longer-term storage or archiving purposes. However counter to this is the timeless adage: 'do we really need yet another 3D interchange format...?' - to which there is no simple answer. For some the answer is (and shall always be) yes, yes, yes, (a thousand times) yes! For others - it's generally preferable to take advantage of pre-existing, already well-established formats whenever possible.
Practically - the current rationale is that whilst we shall (as a community of creators) definitely require some form of native interchange format at some point - the technical merit of such a format (in terms of compression, expressive-scope, read-speed...) would have to unambiguously outweigh that of alternative formats in order to prove useful. To put it another way - until the kernel's compression capabilities surpass that of state-of-the-art mesh-compression algorithms - specifically for procedurally-defined (i.e. largely-structured) polyhedral-arrangements - it does not make sense to drive/push the adoption of a new static representation. However at the point at which the kernel can store its polyhedral yield more concisely than state-of-the-art compressors then it would make practical sense to expose the compressive schemes via a portable native interchange format.
To quantify the current state - the following measures indicate the typical behaviour of the preliminary inline compressors relative to equivalent GLTF and GLB. See the links for each entities' source.
Test-Entity:
armchair.qmsh→ Web-GL Bundle : 60,387 bytes (≈ 61 KB)
→ GLB : 128,552 bytes (≈ 129 KB)
→ GLTF : 171,462 bytes (≈ 172 KB)
→ OBJ (Baseline) : 330,261 bytes (≈ 332 KB)
Test-Entity:
menger_sponge_fractal_depth_3.qmsh→ Web-GL Bundle : 190,053 bytes (≈ 0.2 MB)
→ GLB : 1,483,712 bytes (≈ 1.5 MB)
→ GLTF : 1,978,360 bytes (≈ 2.0 MB)
→ OBJ (Baseline) : 2,322,030 bytes (≈ 2.3 MB)
Test-Entity:
parametric_interface_billboard_paddle_round_box.qmsh→ Web-GL Bundle : 24,327 bytes (≈ 25 KB)
→ GLB : 12,752 bytes (≈ 13 KB)
→ GLTF : 17,060 bytes (≈ 18 KB)
→ OBJ (Baseline) : 19,753 bytes (≈ 20 KB)
Test-Entity:
mechanical_gear_B.qmsh→ Web-GL Bundle : 62,855 bytes (≈ 63 KB)
→ GLB : 149,368 bytes (≈ 150 KB)
→ GLTF : 199,222 bytes (≈ 200 KB)
→ OBJ (Baseline) : 350,689 bytes (≈ 351 KB)
Observe that for very small entities the 20 KB overhead associated with the Web-GL bundles' HTML, CSS, JS and GLSL can be quite costly. Conversely - as the size of an entity grows - so to do the compression gains exhibited by the Web-GL bundles relative to the alternative formats.
Note: you should be able to reproduce these measures on your machines and devices both for the test entities above and for your own scripts. Generally - you should find that the Web-GL bundles are smaller than analogous GLBs - whilst carrying the same payload (4-byte vertices, normals, colours and 2-byte triangles-indices). However in some instances you may find that further compression with tools such as
zip can yield compressed GLBs that slightly out-perform the Web-GL bundles.
Note: this does not take into account GLTF|GLB format extensions or external dependencies - such as lossless and/or lossy compression with operators such as
draco. Rather this indicates the 'out-of-the-box' performance (so-to-speak) for the kernel's supported interchange formats relative to the preliminary inline lossless-compression applied to its Web-GL bundles.
Geometric Primitives: Beveled & Rounded Platonic Solids
Version 0.2.0 added support for generating beveled (chamfered) platonics and rounded platonics - using the B-Tetrahedron, B-Octahedron, B-Dodecahedron, B-Icosahedron, R-Tetrahedron, R-Octahedron, R-Dodecahedron and R-Icosahedron functions.
Note: these new platonic variants expose the same invocation overloads as the prior fixed-form variant primitives - as such, if you are already used to invoking the B-Gable or R-Wedge functions (for instance) you should find these new primitives relatively easy to work with.
The primary reason for this note is to clarify/shed-light-upon a subtle distinction between the beveled-platonics - which are guaranteed to be composed of planar polygons - and the rounded-platonics - which can also use quadrilaterals for corner-elements that may be non-planar.
The critical point is that when these non-planar quadrilateral elements are emitted they are only evident in raw-primitive state - as in if the rounded-platonics are not used in CSG boolean operations (which require planar elements only) - and are silently tessellated otherwise. In other words the kernel takes steps to ensure that any subsequent (post-instantiation) use of the rounded-platonics does not introduce inconsistencies or instabilities that might hinder further assembly operations - however this auto-correcting behaviour may not be immediately apparent to a casual observer.
To put this in even simpler terms: if you return a rounded-platonic variant directly its element counts will mirror the vertex-count and polygon-count expressions in its language-symbol documentation entry - however if a rounded-platonic is subsequently involved in any operation that induces a validity check (including CSG operations, instancing operations and even utility operations such as the NMM fast merge) - then although the vertex-count will/may remain the same the polygon-count will/may increase as any non-planar quadrilaterals are triangulated.
Note: this behaviour depends upon the discretisation steps applied to each rounded-platonic. For example if a single rounding-step is used then all elements shall be planar and the result shall be analogous to an equivalent beveled-platonic with a single smoothing-group.
Note: that for the sake of consistency auxiliary language-symbols have also been introduced to handle the uniform hexahedral cases. Vitally: whilst the Hexahedron, M-Hexahedron and B-Hexahedron functions mirror the yield of the prior Cuboid, M-Cuboid and B-Cuboid functions (when invoked with a uniform-scale factor) - the R-Hexahedron function differs from the R-Cuboid function both in terms of the manner in which it is constructed and in the scope for volumetric and topological variance. Specifically the volume of the R-Hexahedron differs slightly from the volume of the R-Cuboid whenever the number of discretisation steps is greater than one - due to the change in vertex emission. This subtle difference ensures that there is a direct hexahedral analogue/equivalent to the other/alternative uniform rounded platonics.
In simple terms: the placement of vertices and the generation of indices for the R-Hexahedron differs slightly from that of the R-Cuboid - in order to ensure that there is a one-to-one mapping between the logic used to construct the R-Hexahedron and the other rounded platonics.
In particular: without the introduction of the R-Hexahedron there would be disparity between the hexahedral case and all other rounded platonics. However it would not make sense to expose the R-Hexahedron without also exposing the B-Hexahedron (or the M-Hexahedron for example) hence the supplementary introduction of the (technically superfluous) synonymous symbols.
Note: a quick way to check/inspect/confirm the difference between the R-Hexahedron and R-Cuboid is simply subtracting one from the other - e.g. return rhexahedron - rcube;
Update: V:0.2.5 includes fixes for the issues exhibited by the R-Dodecahedron when used in boolean operations. Specifically - the handling of non-planar corner quad elements has been altered to ensure that spatially-invalidity is not inadvertently introduced.
Additionally V:0.2.5 now correctly preserves/restores quad-topology as part of minimal-vertex optimisation for all rounded-platonics (and indeed all quasi-planar elements). This change does not affect the internal handling of these variants (i.e. the kernel must still tesselate non-planar elements to ensure CSG convergence) however it ensures that vital topological information is not needlessly lost when the rounded-platonics are used in constructive operations.
Runtime Optimisation for Boolean Operators
Version 0.2.0 introduced preliminary support for dynamic acceleration to improve the performance of the kernel's boolean operations in terms of reducing the memory requirements and increasing execution speed, whilst fully preserving the fidelity of geometry.
Unlike the bulk of the kernel's lower-level optimisations (which tend to be compile-time techniques) the revisions target runtime mutations to an entity that (under amortised analysis) typically reduce the overall workload associated with performing these heavyweight constructive-solid operations upon polyhedra - without altering or deviating from the Optimal-CSG return. Indeed for the vast majority of the entity scripts you assemble - you should notice a slight improvement in runtime relative to executing exactly the same scripts with an earlier version of the kernel.
However it is vital to point out that in a small number of cases - an entity may exhibit atypical behaviour and exceed the runtime associated with a prior version of the kernel. This note aims to clarify why this may occur and outline a resolution for those that encounter such behaviour.
Essentially during the process of implementing and testing the preliminary dynamic accelerants - a subtle behavioural anomaly in the kernel's prior logic came to light that led to the discovery of a critical invalidity bug for certain polyhedral configurations. This prior error had the potential to cause gross topological and volumetric issues that were hard to pre-emptively detect efficiently largely due to how infrequently they occurred. In essence the prior issue (unearthed by the optimisation process) occurred so rarely that it proved rather expensive to detect and correct programmatically retroactively. Fortunately repeated investigation eventually shed light upon the underlying cause and a potential fix. The main downside of the currently employed fix being that it involved replacing an efficient algorithmic component with a less efficient (but more robust and stable) variant. This fix led to a perceptible dip in performance in the order of a roughly 5%-10% increase in runtime.
Note: that for the vast majority of entities - the cost of this alteration is eclipsed by the gains inherent to the new dynamic accelerants - however in a small number of cases the new runtime optimisations are not alone sufficient to counteract the cost of the algorithmic change. As such although the new methods offer greater robustness and typically execute more efficiently it is worth being aware that there are edge-cases where the speed gains do not hold (or rather are dwarfed by the fix).
As an interim measure (if you encounter one of these edge-case entities) you can use the (currently experimental) acceleration kernel-directive (#JUICE; or #BOOST;) to circumvent the fix and signal your desire for prioritising execution speed. This should enable you to consistently mirror and/or exceed the performance of earlier versions. Note: most scripts do not require the acceleration kernel-directive to be explicitly stated. It is currently only for scripts for which the runtime-optimisations are not alone sufficient to surpass the prior performance resulting from the faster less-stable logic.
Note: investigation is underway to improve the efficacy of the runtime optimisations applied to the kernel's booleans - such that the need for this work-around shall naturally diminish. The thinking is that as the kernel matures, the stable (i.e. safe, zero/negligible-cost) runtime-optimisations shall be applied silently and automatically to all entities - whilst the aggressive (i.e. potentially dangerous, costly or destructive) runtime-optimisations shall remain hidden behind the accelerate kernel-directive such that their application must be explicitly requested by the mesh-maker.
Update: Version 0.2.2 refined the accelerants applied to the kernel's booleans in order to reduce their memory-use and extend their applicability. Whilst there are still a number of avenues that are yet to be explored the current improvements should yield a perceptible boost in performance for the vast majority of entities. As before there are edge-cases for which the gains may not hold - nonetheless the drive towards realtime-friendly portable polyhedral booleans is picking up pace. Specifically you should be able to reproduce a roughly 25%-30% reduction in runtime for your scripts - across all supported platforms (using V:0.2.2+) - relative to older versions of the kernel.
Note: that the less-stable accelerants are still guarded by the experimental #juice/#boost kernel-directive such that they do not compromise stable arrangements - however (as envisioned) as the kernel's primary boolean execution path improves the need for these extreme optimisations decreases. Notably the standard behaviour should now (generally) out-perform the older approach. In other words if you have previously used the accelerate directive to match or exceed the kernel's prior performance - you should be able to remove it safely from your scripts in V:0.2.2+ whilst still gaining a measurable improvement (beyond that previously attainable).
One additional aspect to be aware of is that although V:0.2.2 and above now also take active steps to ensure stable derivatives are fed to the boolean module (so to prevent spatial-invalidity based non-convergence) - the kernel still explicitly prevents/guards-against instances in which a boolean-op exhibits explosive growth in memory-use. This means you may still see the 'memory-exhaustion-triggered-abort' error from time-to-time for any arrangements that require a single-shot allocation greater-than-or-equal-to the max-memory/memory-limit-class kernel argument set.
Update: Version 0.2.5 added further refinements to the accelerants applied to the kernel's booleans in order to reduce their memory-use and to shave off roughly 5%-15% of their runtime.
Positively these latest improvements can be applied safely (that is - without the loss of character and without compromising geometric-stability) and hence are enabled by default post V:0.2.5 (rather than guarded by the experimental accelerate directive).
In spite of this - bear in mind that the same constraints still apply for pathological cases in the sense that there are arrangements that do not respond-to/benefit-from the newest accelerants - which may marginally exceed their prior runtime due to the cost of attempting to dynamically optimise in vein.
Note: given that on-going improvements to the kernel's boolean modules tend to have a disproportionally large effect on the kernel's overall performance (relative to enhancing other generative modules) the current plan is to continue attacking the boolean problem incrementally - i.e. reducing the runtime and memory-use whilst simultaneously increasing stability and robustness.
In lay terms: the kernel's booleans contribute the most to the overall runtime of most scripts and so it makes sense to devote time to improving them. Indeed it is not yet clear how far there is still to go in terms of quasi-optimal fixed-precision polyhedral CSG. It is relatively clear that (at present) we have far from exhausted the options (or fully-traversed the space of possibility) regarding optimisations - however whilst there remain numerous areas under investigation - the expectation is that at some point in the (distant) future - there may come a time where changes to the kernel's algorithms yield ever diminishing returns in terms of performance. However fortunately (at present/currently) we are a long way away from reaching such a state and so it seems prudent to plough ahead.
Post-Processing: Sub-Division-Solids
Version 0.2.3 added a number of experimental post-processing kernel-directives to support exploration of sub-division-solid modelling in quick-mesh.
This note aims to clarify the current state of development for the OSDS, TSDS and QSDS operators, along with their behavioural traits and limitations.
As a primer: a brief outline of each operator follows:
#TSDS → Triangle-Sub-Division-Solid
The TSDS operator constructs a weighted sub-division of a triangle-mesh using a simple half-edge mesh data-structure. Note: the TSDS is (arguably) the most general form of sub-division solid - yet in practice tends to result in the worst yields when applied to the minimal-vertex mesh that the kernel emits. Less tactfully: the TSDS operator generally performs poorly in quick-mesh due to the low-quality tessellations that result from minimal-vertex optimisation - which constitute/are-effectively poor sub-division cages. Note: you can always improve the quality of the tessellations produced by the kernel manually (i.e. by bi-linearly sub-dividing primitives or applying active-contouring/topological-breakline strategies) within the body of a script - however it is fair to say that having to augment an entity's description by hand in order to improve the yield of the TSDS operator is far from a desirable state of affairs - and contravenes the desire for automation and flexibility (inducing representations that may be brittle/less-transposable). Note: investigations are underway to determine effective (i.e. memory-efficient) means to automatically construct higher-quality triangulations that may be used as input cages for the TSDS operator - however given the open ended nature of the problem - conventional wisdom indicates that such avenues alone may not provide the class of solution sought. Hence (within the context of quick-mesh - at least for the time-being) you can consider the TSDS operator a baseline sub-division method. For better feature-preserving results the QSDS and OSDS operators are recommended.
#QSDS → Quadrilateral-Sub-Division-Solid
The QSDS operator constructs a weighted sub-division of a quadrilateral-mesh using an augmented half-edge mesh data-structure that preserves colours and topological features in the output. Vitally the QSDS operator mandates pure-quadrilateral inputs in order to guarantee pure-quadrilateral yields - which (generally-speaking) are preferable in sub-division modelling as they produce better looking (and better behaving) results. The key caveat with the QSDS operator is the requirement for pure-quad inputs - which currently must be enforced by the mesh-maker. Essentially - if an entity is composed solely of quads then the QSDS operator should work reasonably well - however given that most entities emitted by the kernel tend to include concave and complex non-quad elements you may find the applicability of the QSDS is limited. Note: there are some cases in which automatic quadrangulation can be addressed optimally in a closed form manner (see the OSDS for an example) - however generally use of the QSDS operator requires a measure of care on the part of the mesh-maker that it is not currently practical to completely remove.
#OSDS → Orthogonal-Sub-Division-Solid
The OSDS operator constructs a weighted sub-division of an orthogonal (ortho-aligned) N-gonal mesh using a two-step process which (first) quadrangulates the ngon-inputs and (secondly) feeds the result into the QSDS operator to preserve colours and topological features in the output. Unlike the QSDS - the OSDS does not mandate quads as input (as the quadrangulation process handles this) however it does require the input to be composed solely of axis-aligned elements - so to guarantee the operation of the quad-generation process. The OSDS stands as a rough template/archetype of the class of sub-division operator that is desired in that its operation does not call for fiddling with mesh-elements directly - but delegates the heavy-lifting/grunt-work to an algorithm. The main limitation of the OSDS operator is the orthogonality constraint - in that it demands axis-aligned mesh as input. Essentially - even though the input can be concave or complex - the angular constraints means that the OSDS operator is typically of most benefit when dealing with structured grids - though unstructured grids are also viable - for as long as they are ortho-aligned. Note: an example of a common arrangement suitable for the OSDS operator is the Menger-sponge.
To help clarify the functionality described above - the following example scripts demonstrate the construction of sub-division-solids in quick-mesh. Tip: you can comment out the directive in each of these examples in order to see the raw/unprocessed input cage to the sub-division process.
Observe in these examples that the actual interface to sub-division-solid modelling in quick-mesh is exactly the same - irrespective of the operator. Essentially each of the TSDS, QSDS and OSDS operators expects a single integer digit to follow its directive-head-token - typically (though not always) wrapped in a pair of parenthesis. This single integer argument dictates the sub-division depth or iterations and must be greater-than-or-equal to one (+1) in order to ensure valid operation.
Bear in mind that each iteration of sub-division (using these operators) results in an roughly four-fold (4x) increase in the number of elements (in the worst case) - so be careful in terms of the digits you supply as larger values will result in near instantaneous out-of-memory errors. In practice it can help to model with lower values (i.e. 1, 2, or 3 sub-division iterations) and increase to higher-values (i.e. 4 or 5-ish) when an entity is complete. As guidance (other than in extreme circumstances) you should aim to use the lowest number of sub-division iterations that yields an artefact free result. For in sub-division-solid generation (at least in the context of quick-mesh) - less is more - and a needlessly verbose sub-division-solid will likely cause issues later down the line if such an entity is used in a realtime-application or automated-processing-pipeline. It's also worth considering that in some contexts (i.e. when one does not actually require the mesh for analysis or querying spatial-structure) - such as visualisation and interactive rendering - it may be desirable to defer the actual sub-division for GPU-side processing - so it is not always prudent to ramp up the number of iterations requested. It can sometimes make more sense to apply one or two iterations and defer the further detail generating iterations until after injection into executing, recipient or target environment.
One additional practical consideration to factor in when constructing sub-division-solids is the kernel's fail-safe behaviour - in that (for the constrained operators QSDS and OSDS) the kernel returns the input if the pure-quad or orthogonality pre-conditions are not met. In other words if the output has not changed (post-application of the QSDS and OSDS operators) it is a product of the fact that the kernel has detected non-quad, or non-axis-aligned elements and skipped the sub-division as a result. This guarding simply helps to prevent catastrophic errors emerging.
So to briefly recap on the strengths and limitations of these experimental operators:
- #TSDS: Triangles
- Input: Triangles → Output: Quads
- ✓ Works with Just-About Any-Input
- ✗ Produces Poor/Un-Satisfactory Sub-Division Results
- #QSDS: Quadrilaterals
- Input: Quads → Output: Quads
- ✗ Works with Pure-Quad-Mesh-Only
- ✓ Produces Good/Satisfactory Sub-Division Results
- #OSDS: Orthogonals
- Input: N-Gons → Output: Quads
- ✗ Works with Orthogonal-N-Gon-Mesh-Only
- ✓ Produces Good/Satisfactory Sub-Division Results
Remember that (presently) these experimental operators are exposed as post-processing kernel-directives rather than as standard language symbols. Depending upon how the exploration of sub-division-solids unfolds over time this may change such that these handy operators act as conventional language symbols. However there are numerous issues to address before reaching such a state. Two of the key hold-ups (or currently missing functional-pre-requisites) are (grammatically) constructs/patterns for effective lower-level programmatic control and (algorithmically/geometrically) generalisation to arbitrary inputs.
Note: if you need to quadrangulate an orthogonal arrangement - without applying sub-division subsequently - there is also the experimental #OQ directive - which tends to the task.
#OQ → Orthogonal-Quadrangulator. The OQ operator constructs an orthogonal-quadrangulation of an ortho-aligned N-gonal mesh. This is essentially the quadrangulator implemented by the OSDS operator exposed such that it can be used directly as a Manhattan-world retopology agent.
Post-Processing: RTJ, MMV, SSV
This note seeks to shed light on the current state of the post-processing operators: RTJ (Resolve-T-Junctions), MMV (Merge-Manifold-Vertex) and SSV (Strip-Shared-Vertex).
Note: that prior to V:0.2.2 the primary method of invoking these post-processors involved adding command-line-flags to one's kernel-invocations. However with the advent of parallelism it became clear that the approach required augmenting to enable more granular control of the application of these finalisers - particularly in instances when one wishes to treat a subset of a parallel-yield.
The big issue with the original command-line argument approach is that (as a global-option) it applies to every entity emitted for an invocation. Although this is often one's desire when modelling a monolith entity - it quickly becomes inadequate when dealing with multiple entities. For example: the command-line argument approach does not provide the option to toggle each operator on-or-off at the script-level let alone the sub-script parallel-element level - resulting in either the requirement to partition arrangements into separate scripts or the loss of the ability to apply each operator.
The introduction of the #RTJ, #MMV, and #SSV kernel-directives helps to combat this issue - by enabling selective application of each operator at the level of each script or parallel-element.
Note: the kernel still respects/honours the command-line argument post-processing approach (in contexts where terminal-access is the norm - i.e. under Linux, Mac-OSX, RPi-OS,...) - essentially adding another avenue via which to coordinate post-processing that benefits contexts that may restrict terminal-access (i.e. in sandboxed environments). The core benefit of the revision is that it enables one to restrict the application of these potentially heavy-weight operators (RTJ and MMV in particular) to only the subset of entities that require them. Just remember that kernel-directives (as parameter-definitions) occur exclusively at root-operative-scope within the body of a script - so no trying to nest #RTJ or #MMV directives in functions (for example) - as such will have no effect.
RTJ → Resolve-T-Junctions
- Kernel-Directive: #RTJ
- Command-Line-Flag: -rtj
The RTJ operator finds and fixes non-manifold(-able) edges between/amongst neighbouring Gouraud smooth-shading group boundaries (*subject-to-constraints). By non-manifold(-able) we mean edges that cannot be welded (essentially made manifold) without first being refactored. The RTJ operator has the effect of adding vertices along offending boundary edges to enable subsequent weld (or MMV) operations to proceed successfully. Note: the RTJ operator (whether invoked in kernel-directive or command-line-argument form) applies primarily to mesh assembled using the Optimal-CSG execution-mode (i.e. the kernel's internal default). As such if you also add the -nobo (no-boolean-ops - i.e. pure-union) or -noop (no-optimisation - i.e. basic-CSG) command-line arguments - then a warning is typically emitted indicating the RTJ's dependence on minimal-vertex optimisation. Note: further that the current implementation of RTJ (V:0.2.2+) should function as expected for most inputs though be aware it has not yet been optimised for performance (speed) or robustness - this is still todo. Additionally although the tessellations that result post-RTJ should be free of degeneracy (if the operator succeeds) - the polygonal-loops (or N-gons) that result post-RTJ may contain degeneracy - specifically colinear elements which are added to maintain the strict-mapping between polygon and triangle representations of an entity.
MMV → Merge-Manifold-Vertex
- Kernel-Directive: #MMV
- Command-Line-Flag: -mmv
- In-Script-Symbol*: .mmv()
The MMV operator finds and welds (i.e. merges) duplicate vertex in pursuit of a watertight 2-manifold suitable for use-cases such as 3D-printing or generally other forms of additive or subtractive manufacturing or fabrication (*subject-to-constraints). As the RTJ operator - the MMV operator is targeted at mesh produced in Optimal-CSG mode - however unlike the RTJ operator - the MMV will interfere with an entity's colour representation - replacing crisp boundaries with blended (fuzzy) regions. Note: that unless an entity is already trivially manifold-able - the application of the MMV operator is typically preceded by an RTJ. The MMV should function as intended for most entities - however there are edge-cases yet to be resolved - hence double-check the yield post-MMV.
SSV → Strip-Shared-Vertex
- Kernel-Directive: #SSV
- Command-Line-Flag: -ssv
- In-Script-Symbol*: .ssv()
The SSV operator disassociates (strips-away) shared elements between/amongst neighbouring polygonal boundaries (*subject-to-constraints). The SSV operator can be thought of (loosely) as the inverse or the opposite of the MMV operator. The aspect to bear in mind is that SSV will bloat an entity mesh in order to forcibly induce crisp/faceted elements - however the process applies primarily to polygonal boundaries. In other words - co-planar tessellated elements derived from the same N-gon are still allowed to share vertices. Indeed this is not an accident but a fundamental requirement in order to maintain the mapping between polygons and triangles. By and large you may/should not need to worry about this - however if you have applied the SSV operator to an entity and are curious-as-to/wondering-why the number of vertices in the tessellation is shy of three-times the raw triangle count - then this should hopefully help clarify the reason.
Bear in mind that when you use these operators in kernel-directive form (i.e. at root-operative-scope within a script) DOIEO applies. Therefore the statements: #RTJ; #MMV; - are not the same as #MMV; #RTJ; - with the former being the correct operator ordering for manifold-mesh construction. Put simply: when applied as command-line arguments - the kernel takes steps to ensure that these operators are applied in a coherent order - guarding against invalid combinations. However as kernel-directives (which offer a greater level of control) no such auto-correcting action is taken.
One additional point that follows on from this is that in some instances (for example when emitting surface-normals) you may wish (or find it beneficial) to add the NXYZ kernel-directive after your RTJ, MMV or SSV directives - as (again) the command-line argument post-processing approach handles this automatically for you - whilst the kernel-directive approach (which affords you the ability to determine when to synchronise-normals) does not.
NXYZ → Compute-Surface-Normals
So to wrap up with a practical example - if you wanted to (say) construct a single 2-manifold entity within a parallel assembly containing other non-manifold entities - you could add the #RTJ; #MMV; #NXYZ; directives to the single entity's sub-element source-definition in your parallel-script.
Development Stack: Validators
This note lists the tools used to verify the validity of entities emitted by the quick-mesh kernel.
→ meshlab [ .obj, .off, .ply, .stl, .gts, .dae ]
→ blender [ .obj, .ply, .stl, .dae, .gltf, .glb, .usd ]
→ glTF-Validator [ .gltf, .glb ]
→ firefox [ .json, .html ]
The file extensions adjacent to each tool indicate the interchange formats each validates.
Note: that .3mf, .amf and .rib are not currently validated across target platforms during development so take care using them and always double-check the yield.
Entity-Inspector: Functionality Tracking
This note enumerates the development state of core features of the entity-inspector.
This note is primarily intended to help track and monitor the inspector's functionality.
Note: a tick next to an item indicates it is implemented and functional - whilst an exclamation mark next to an item indicates a partial implementation with the requirement for revision or the presence of a known (but currently unresolved) issue. A hyphen (or dash/minus) indicates still TODO.
Note: this list is not exhaustive.
Setup/Launch/Run
✓ Interactive (via OS App-Launcher/Double-Click)
✓ Command-Line (via Shell/Terminal/Console)
Input
✓ Open-Script (Inline-IO)
✓ Open-Script (Native-IO)
✓ Open-Script (Drag-and-Drop)
✓ Parse-Script
✓ Assemble-Mesh
Output
✓ Capture-Image-Snapshot
✓ Application-Screenshot
✓ Export-Environment-Mesh (OBJ,OFF,PLY,STL)
Environment
✓ New-Environment
✓ Goto-Environment
✓ Close-Environment
Geometry-Viewer
✓ FBO+VBO+IBO
✓ Anti-Aliasing
✓ Legacy-Renderer (Fixed-Function)
✓ GLSL-Renderer (Programmable)
- Vulkan-Renderer (Advanced)
✓ Viewport-Control (Configurable-Split-Screens)
✓ Unlit
✓ Ambient
✓ Diffuse
✓ Specular
- Occlusion
- Emission
- Reflection
✓ Object-Orbit
✓ Free-Roam
✓ First-Person
✓ Camera-Lock
✓ LL-Inspector
Entity-Inspection-Tools
✓ Topology (Polygons, Triangles, Gouraud, Points)
✓ Colour (RGBA, Light, Dark, Functional)
✓ Shading (Flat, Smooth, Transparent, Brighten, Silhouette, X-Ray, Negative)
! Orbit (Euler-Gimbal, Quaternion, About-Center)
! Projection (Orthographic, Perspective)
! State (Attribute-Trace, Fit-Viewport, Reset-Transform)
✓ Widgets (Axes, Grids, Rings, Bounds)
✓ View (Top, Base, Left, Right, Front, Back)
Parallelism
✓ Sequential-Executor (Mono-Core)
✓ Simultaneous-Executor (Multi-Core)
✓ Re-Assembly-Culling
✓ Invocation-Grouping (Batching)
✓ Constant-Cost Parallel-Prefix (CCPP)
- Pre-Emptive Optimisation (P.Op.)
User-Interface
✓ Keyboard/Mouse-Control
! Touchscreen/Trackpad-Control
✓ Main-Control-Bar
✓ Environment-Tab-Bar
! Console-Trace
✓ Entity-Inspector
✓ Parameter-Controller
✓ Options-and-Settings
! Performance-Profiler
✓ Camera-Directive-Selector
✓ Parametric-Variant-Selector
- Parametric-Variant-Control (Creator/Generator)
- Animation-Control
! Fullscreen (all-but-Windows)
✓ Theme/Colour-Scheme-Selection
- Multi-Language (Embedded Localisations)
- Language-Packs (User-Defined Localisations)
✓ Slider-Bar
! Interface-Animations
! Minimal-Mode
Testing
✓ Linux
✓ Mac-OS (Intel)
- Mac-OS (arm)
✓ Windows
✓ Raspberry-Pi (2,3,4)
- Raspberry-Pi (5)
Documentation
! Quick-Start User-Guide (PDF)
- Video-Tutorial
- Trouble-Shooting Guide
- Showcase Media
LL-IPC: Lower-Latency Inter-Process-Communication
This note outlines the current state of experimental constructs designed to reduce the kernel-to-executing-environment 3D entity injection-overhead - particularly for the benefit of latency-sensitive interactive front-ends (such as the entity-inspector and mobile-editor).
Version 0.2.4 and 0.2.5 (respectively) added and exposed preliminary support for lower-latency inter-process-communication (LL-IPC) to/in the mobile-editor as a means to explore methods of minimising the IO-cost associated with marshalling mesh across the native-to-VM boundary.
This revision emerged as the product of investigations into removing the requirement for file-IO in assembly - initially for the purpose of enabling the editor to function without the storage-permission, but more recently as a means to address the limitations of the file-IO interop for fast-to-assemble but large-in-size entities such as those resulting from the application of sub-division-solid operators.
Although the approach comes with certain limitations (and is still being improved) the current formulation provides sufficient advantage to warrant its inclusion in the public release-builds.
For reference the key benefits of the mobile-editor's LL-IPC strategy to date include:
- More Stable/Consistent Interop-Runtime
(by removing variability in file-write and file-read runtime) - Generally Marginally Faster Overall-Runtime
(benefits increase as the number of elements in a mesh grows) - Removes Dependence on SD-Card/Flash Storage
(for mesh-element marshalling - but not for IDE management)
Conversely the main draw-backs of the current strategy are:
- Invalidates/Prevents 3D Persistence Across App-Restarts and Power-Cycles
(as there is no longer a permanent/non-volatile cache to restore on launch) - Does Not Support Multi-Core Parallel-Assembly
(current implementation only works well for monolith-scripts/single-core-executors) - Harder to Debug Interop using External-Tools
(since mesh data exists in volatile memory that cannot be read by other processes)
In essence the pro-and-cons of LL-IPC in the mobile-editor at present are roughly balanced - in the sense that there are certainly instances in which it is advantageous - however it also compromises behaviours (such as persistence) that many of us have come to rely upon and indeed take for granted. For this reason LL-IPC is not enabled by default in the editor - but rather guarded by an optional-setting such that its application must be explicitly requested by a mesh-maker.
Support for LL-IPC in the entity-inspector is in development in order to provide similar benefits for desktops and workstations. The current plan is to hold fire on its addition until parallel-LL-IPC is implemented since (though it is handy for monolithic scripts) its impact on parallel scripts is far more important as it directly contributes to addressing the
parallel-overhead problem.
Note: for more information on the current state of development you can also check the public-working-draft of the scripting-language's reference-manual. Additionally keep an eye on the release-notes accompanying each tool.
Questions & Answers
This section provides answers to questions related to QMSH.
What is Quick-Mesh?
A tool (a computer program) for creating 3D-mesh - or more precisely - a hardware, platform and framework agnostic general-purpose polyhedral procedural modelling kernel which exposes a high-level imperative geometric scripting language. Essentially Quick-Mesh provides a means to create geometric models using simple scripts. In-particular it strives to provide a standardised mechanism for the interchange of functional geometric descriptors. Quick-Mesh (.qmsh) also denotes the human-readable geometric file-format.
What is a Quick-Mesh Kernel?
Software that implements Quick-Mesh. Typically formed of a language-parser and a mesh-assembler.
What is the Quick-Mesh Grammar?
The high-level, imperative, entity-oriented, general-purpose scripting language that is used to define (specify the process of constructing) polyhedral mesh within Quick-Mesh. The grammar's principal syntactic construct is the post-fix, dot-notation, sequential-expression-chain (PF-DN-SEC).
What are the key limitations of Quick-Mesh?
QMSH is by design a purely-procedural kernel - meaning that the only way to describe a 3D entity is in a script. QMSH does not provide a back-door to mixed-procedural modelling wherein one couples automatically generated geometry with manually or interactively created geometry as is common in many pre-existing solutions. Whilst this brings numerous technical advantages - it can be both daunting and off-putting to some mesh-makers at first. Further the expressive scope of the QMSH grammar favours man-made structures and devices (that exhibit symmetry and structural-regularity) - more so than organic structures. In other words QMSH is not recommended for entities such as trees, plants or terrains. Additionally QMSH does not currently provide texture-mapping facilities.
Which platforms and environments are supported by Quick-Mesh?
Presently (as of V0): Android, Linux, Mac-OS, Windows and Unity.
Which pre-existing languages influenced the Quick-Mesh Grammar?
Several. Firstly the C-family of programming languages (C, C++, C# and Java). Secondly higher-level languages such as Groovy, Python, Javascript. Thirdly domain-specific languages like LATEX and vitally prior procedural shape-grammars such as CGA-Shape, GML and Open-SCAD.
What differentiates Quick-Mesh from pre-existing shape-grammars?
QMSH's main distinguishing features are its simplicity, brevity and flexibility. You can download and run quick-mesh literally in minutes. There are no third-dependencies so setup is exceedingly easy. Furthermore - not only is the scripting-language designed to minimise symbolic-redundancy (whilst simultaneously increasing script legibility) - but the physical reference implementations also exhibit an unprecedented level of compactification relative to traditional 3D kernels and procedural modelling tools. This makes it possible to use QMSH in contexts and environments for which pre-existing systems and generative abstractions struggle - for example on low-power mobile devices and single-board computers. Further still - in spite of its simplicity the general-purpose nature of QMSH renders it a surprisingly versatile tool capable of expressing a wide range of highly varied entities - which vitally (and unlike typical CAD-system generated mesh) are suited to use in realtime systems such as games, interactive architectural visualisations, virtual environments and augmented reality applications.
How stable is the reference implementation of the Quick-Mesh Kernel?
Relatively stable. By and large it functions as expected - however certain aspects are being improved - in terms of robustness, computational efficiency and usability. Additionally some features - though originally planned for inclusion in the beta release - have been postponed and are being added incrementally. In short the kernel is a work in progress - but a functioning work in progress.
How much does registration as an industrial user cost?
Presently there is no charge to register as an industrial user of QMSH:V0 - however the process requires formal agreement to - and compliance with the terms of - Codemine's Industrial Partner Agreement. Crucially your organisation must be willing to indemnify Codemine against any legal and/or economic liability pertaining to and/or arising from your organisation's use of QMSH. This includes agreement to the restriction imposed preventing redistribution of QMSH's reference implementations and preventing its use in safely-critical systems and environments.
Does registration as an industrial user grant source-access?
No. Registration as an industrial user is (presently) largely a formality for organisations that must ensure their use of third-party software complies with Copyright and Intellectual-Property laws. However industrial registration also provides a means for organisations, enterprises and commercially inclined individuals to establish a formal channel of communication with Codemine. Note: whilst QMSH shall offer a free-to-use option perpetually - the cost of registration as an industrial user of future versions of QMSH is subject to change - specifically inflation in line with the logistical cost associated with provisioning for industrial users.
Does registration as an industrial user grant redistribution-rights?
Generally - no. However under certain circumstances - Codemine may (solely at its own discretion) authorise certain parties to redistribute specific tools. Note: this does not in any way affect your rights to redistribute the original content (scripts and models) that you create using QMSH under the terms you deem appropriate (FOSS or proprietary). If you are interested in integrating QMSH into an application or system you are developing and wish to discuss this matter further - get in touch.
Why is redistribution currently forbidden?
Primarily - safety. Essentially QMSH is in beta - meaning that whilst it may be safe to use it directly - as long as one is present to visually check and verify the output mesh - it may not be safe to bundle the kernel into commercial applications for which the polyhedra generated may not have been verified ahead-of-time on all potential target devices and platforms. Such stability shall come over time as the kernel matures and undergoes wider scale testing by a larger array of mesh-makers. Whilst one might argue that a mere warning or disclaimer of liability might suffice - instead, in order to guard against any potential, indirect or incidental legal culpability, a uniform no-redistribution policy has been adopted to simplify the matter. In short: it would not be wise nor prudent to encourage embedding or bundling the kernel in commercial and industrial applications at present given that it is in active development. Therefore the terms of use forbid any form of unauthorised resale or redistribution of the reference implementations such that there is no doubt or ambiguity.
When will redistributable versions of Quick-Mesh be available?
In due course. As the kernel develops - redistribution options shall be added for industrial users - potentially for a fee. Note: there is not a definitive timeline for the transition to permissible industrial redistribution of the reference implementations. However if it becomes apparent that such options are in high demand amongst industrial users then coordinating the transition shall be prioritised.
Which aspects of Quick-Mesh are non-procedural?
None! QMSH's ethos is pure proceduralism! Note: this extends beyond the kernel and grammar. Every aspect of Quick-Mesh is effected procedurally.
Note: if you can not find the answer to a question you have - get in touch.
For general enquiries message: info@qmsh.org
For technical queries message: support@qmsh.org