Greetings. Welcome to the QMSH forum - a collection of auxiliary support resources for users of the QMSH procedural modelling kernel and scripting language.
NOTE: THIS PAGE IS IN DEVELOPMENT.
Presently this page acts as a placeholder for the QMSH Forum and as a notice board for early-adopters of the kernel and grammar. This is primarily to support dissemination of QMSH-centric news and updates. As time progresses features shall be added to this page to reflect the evolving needs of the community.
This section contains notices pertinent to mesh-makers.
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.
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.
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.
Note: QMSH-Visual depends upon the QMSH-Kernel - therefore remember to also install the QMSH-Kernel for Android (also available on the Play-Store). 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.
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.
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: firstname.lastname@example.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
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)
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 neccessitating 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 transistion. 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: functionality is added regularly so check back for progress updates.
This section lists known issues and corresponding work-arounds.
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 (ia64, 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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'.
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.
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.
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.
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.
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.
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.
If you like QMSH and want to get more actively involved in the project there are many ways in which you can contribute. This section outlines some of things you can do to help shape and drive the development of the kernel and grammar.
Foremost: Create Awesome 3D Content!
As with all new technologies the-early-bird-gets-the-worm. Therefore take advantage of the beta incubation period to get to grips with high-level polyhedral-programming and start reining down awesome 3D entities! By creating and sharing high-quality 3D content you are not only helping to entice new mesh-makers into the fold but are also helping to establish the expressive-scope of the kernel and grammar.
Secondly: Provide Feedback on your Experiences
Your insights and observations are highly valued - and your feedback is welcomed. If you have thoughts on geometric-behaviour or performance, usability, efficiency or any aspect of the kernel or grammar then get it touch: email@example.com
Thirdly: Report Bugs and Issues
By reporting any undocumented problems you encounter using the kernel and grammar you help to improve the stability and robustness of QMSH and the user-experience for future mesh-makers. Note: make sure to check the issue-tracker first though - just in case there are already known work-arounds.
Fourthly: Suggest and Request New Features
If you have ideas to improve quick-mesh or if there is functionality you would like to see added to the kernel and grammar - get in touch: firstname.lastname@example.org
Fifthly: Spread the Word Hummingbird!
One of the best ways you can contribute to the growth and adoption of QMSH is to champion the kernel and grammar by spreading the word to fellow mesh-makers.
Many many thanks to those of you who have already begun sharing your procedural creations, experimenting with quick-mesh and spreading the word. Your on-going support and engagement is very much appreciated! Additionally: thank you to the vocal early-adopters amongst you for your feedback and feature requests. Individually and collectively your insights are helping to shape the kernel and grammar and direct implementation focus - so keep your thoughts coming!
Note: to further support those engaged in the creation and utilisation of quick-mesh entities - a link to an experimental 3D procedural entity exchange has been added to the project homepage's - in order to provide a simpler route to entity exposition for those without access to a dedicated server or content hosting service.
The experimental entity-exchange system is free-to-use for all mesh-makers and can be helpful in quickly sharing ephemeral procedural entities particularly when one is seeking help or assistance with the scripting-language and the kernel.
Note: for further information (on the various ways in which you can set your 3D procedural creations free) - you can also refer to the Researcher-Resources available on the homepage - specifically the Entity-Resources section.
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.
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: Editor, Kernel, 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: Editor TODO: Kernel, 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: 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: Editor, Kernel
Parameter Binding & Mutation → 'handling parametric control independently for each sub-element in a parallel assembly' Supported: Editor TODO: Sandbox, Exchange
Variant Binding & Selection → 'handling parametric variants independently for each sub-element in a parallel assembly' Supported: Editor TODO: Sandbox, Exchange
Public (External) Directives → 'applying public directives (such as #unit) for each parallel element' Supported: Editor, Kernel, Sandbox, Exchange TODO: -
Private (Internal) Directives → 'applying private directives (such as #execmode) for each parallel element' Supported: Editor, Kernel, Sandbox, Exchange TODO: -
Experimental Directives → 'handling experimental directives (such as #osds) correctly for parallel elements' Supported: Editor, Kernel, 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: - TODO: Editor, Kernel, 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: - TODO: Editor, Kernel, Sandbox, Exchange
Remember that parallelism in quick-mesh is relatively fresh and subject to revision.
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 ✓
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.
The resolution to this issue is being investigated.
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 28-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.
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.
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 on 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-Hexehedron 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;
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.
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.
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.
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).
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.
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.
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.
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.
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.
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 contact Codemine: email@example.com.
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.
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: firstname.lastname@example.org For technical queries message: email@example.com
Help & Support
If you require any technical assistance using the Quick-Mesh Kernel, Editor, Plugin or Grammar feel free to contact support at: firstname.lastname@example.org
Codemine will attempt to respond to all enquiries promptly however be aware that presently Codemine prioritises help and support requests and the resolution of bugs, errors and issues over speculative, solicitous or ambiguous messages.
As further clarification: Codemine endeavours to respond to all written feedback and queries from mesh-makers (both positive and negative) within 72 hours.
Note: presently only messages written in English can be responded to.
As guidance: the easier it is to understand your message - the easier it is for your query to be answered or your request addressed or your issue resolved.