qmsh
RESEARCHERS--
All Rights Reserved. © Codemine-Ind. → Last Updated: 2023-06-06
beta

QMSH

Researchers


Overview



This page collates technical resources for engineers and researchers - which aim to simplify experimentation with the quick-mesh kernel and grammar.

Note: QMSH is currently in the beta testing phase of development - and is therefore subject to frequent revision. Bear this in mind as you engage in experiments.

Entity Resources



This section includes resources to assist in the use of the 3D polyhedral entities generated by the kernel. Specifically it provides practical examples of some of the methods via which you can embed the 3D entities you define using quick-mesh into web-pages so to enable you to set your procedural creations free.

Note: an automatic documentation system for the scripting-language is currently in development to ease the process of entity exposition. However: until it is complete the following are all viable methods of sharing your entities in a portable manner.

  • Embedding Entities using Three-JS
  • Embedding Entities using Babylon-JS
  • Embedding Entities using <model-viewer>
  • Embedding Entities using the Kernel's Experimental Web-GL Outputs
  • Uploading Entities to a Content Hosting Service
  • Embedding Entities in Portable Direct-Share 3D URLs


Embedding Entities using Three-JS

The kernel's experimental GLTF outputs offer a relatively easy route to embedding your creations in Three.js scenes. You can opt for either ASCII (.gltf) or binary (.glb) output by adding the following flags to your kernel invocations:

→ GLTF (ASCII): -gltf
→ GLB (Binary): -gltf -b

Note: the kernel also supports the emission of JSON interchange files which can sometimes be helpful in experimentation since they simplify programmatic access to an entity's geometric elements relative to GLTF and GLB. To experiment with the JSON outputs add the -json flag to your kernel invocations.

If you are using the mobile kernel (rather than the command-line kernel) you should instead select the embeddable-JSON and/or portable-GLTF options.

Note: the kernel's GLTF and GLB outputs are always triangles whilst the JSON outputs may be either triangles (..._TESS.json) or polygons (..._NGON.json).



Embedding Entities using Babylon-JS

As Babylon-JS also supports GLTF interchange files you can apply exactly the same steps (applicable to Three.js) to embed your creations in Babylon-JS scenes.



Embedding Entities using <model-viewer>

You can also use <model-viewer> in a similar manner to Three.js and Babylon-JS by embedding the kernel's GLTF and GLB outputs. This can be handy if you are interested in virtual-reality and or augmented-reality - given that <model-viewer>'s support for various types of head-mounted-displays is relatively comprehensive.



Embedding Entities using the Kernel's Experimental Web-GL Outputs

The quick-mesh kernel also provides basic support for generating monolithic (self-contained/stand-alone) Web-GL bundles for individual entities that can be used independently and/or embedded in web-pages using the HTML <iframe> tag.

To generate Web-GL bundles simply add the -webgl flag to your kernel invocations.

Alternatively (if using the mobile kernel) - select the standalone-HTML option.

You can then embed the generated HTML file in a page as follows:

{↓}
-
+
<!-- ROOT-DIV: THIS DIV SHALL HOLD THE IFRAME COMPONENT THAT DISPLAYS THE ENTITY -->
<div id="entity0" style="position:relative; width:320px; height:320px; box-shadow:0px 0px 4px rgb(64,64,64);">
  <!-- LOAD-SCRIPT: THIS INLINE SCRIPT ELEMENT IS RESPONSIBLE FOR DYNAMICALLY GENERATING THE IFRAME COMPONENT IN RESPONSE TO A USER SELECTING THE CENTRAL ICON -->
  <script>function load_entity_0() { document.getElementById('entity0').innerHTML = '<iframe src="webgl/examples/armchair.html" width="100%" height="100%" style="position:absolute; left:0px; right 0px; top:0px; bottom:0px; border:none;"></iframe>'; }</script> 
  <!-- LOAD-BUTTON: THIS DIV INVOKES THE LOAD-SCRIPT'S FUNCTION WHEN A USER SELECTS IT (I.E. CLICKS IT OR TAPS IT) -->
  <div onclick="load_entity_0();" style="position:absolute; left:128px; top:128px; width:64px; height:64px; border-radius:32px; box-shadow:0px 0px 4px rgb(64,64,64); cursor:pointer;">
    <!-- LOGO|ICON: THIS IMG ELEMENT COULD BE USED TO PROVIDE AN INDICATOR FOR THE ENTITY -->
    <img src="cube_octahedron.png" style="position:absolute; width:48px; height:48px; left:8px; top:8px;"/>
  </div>
</div>

...which (when loaded) will produce something similar to the following:


Observe that by dynamically generating the iframe component in response to an explicit user-action (i.e. selecting the central icon) - one can minimise the page-load overhead associated with the 3D entity by only retrieving it when actually requested rather than immediately. This also helps to side-step the undesirable behaviour of some browsers - which will restrict automatic iframe content loading.

Note: the example above assumes that the monolithic WebGL entity bundle (in this instance for the armchair entity) is located in the folder webgl/examples/ relative to the embedding page - essentially same-origin - and that the indicative logo/icon (here cube_octahedron.png) is located adjacent to the embedding page.

If you prefer to separate HTML, CSS and JS then the above could be expressed as:

{↓}
-
+
<!-- CSS: STYLE CLASSES FOR THE ROOT-DIV, BUTTON-DIV, ICON-IMG AND ENTITY-IFRAME -->
<style>
  .abs { position:absolute; }
  .rel { position:relative; }
  .root { width:320px; height:320px; box-shadow:0px 0px 4px rgb(64,64,64); }
  .button { left:128px; top:128px; width:64px; height:64px; border-radius:32px; box-shadow:0px 0px 4px rgb(64,64,64); cursor:pointer; } 
  .icon { width:48px; height:48px; left:8px; top:8px; }
  .frame { left:0px; top:0px right:0px; bottom:0px; border:none; }
</style>

<!-- JS: THIS SCRIPT IS RESPONSIBLE FOR DYNAMICALLY GENERATING THE IFRAME
     COMPONENT IN RESPONSE TO A USER SELECTING THE CENTRAL ICON -->

<script>
  function load_entity_0() {
    document.getElementById('entity0').innerHTML =
      '<iframe src="webgl/examples/armchair.html" width="100%" height="100%;" class="abs frame"></iframe>';
  }
</script>

<!-- HTML: THIS DIV SHALL HOLD THE IFRAME
     COMPONENT THAT DISPLAYS THE ENTITY -->

<div class="rel root" id="entity0" >
  <div class="abs button" onclick="load_entity_0();">
    <img class="abs icon" src="cube_octahedron.png"/>
  </div>
</div>

Note: that by injecting the iframe dynamically using the root-div's inner-HTML one replaces the load-triggering indicative logo-icon - and anything else that is present in the root-div. Essentially remember that any additional elements that you add to the root-div will be removed when the iframe is retrieved and injected. This is ideal if you want to add a poster-image or similar indicator in place of the logo-icon.

Additionally: you can control the start-up behaviour of the embedded monolithic entity-controller bundle (i.e. its initial state) by adding URL argument tokens to the iframe's src attribute's path. The supported URL arguments for bundles are:

URL-Token
Behaviour
nomax
none-maximisable (i.e. hide fullscreen button)
notheme
none-themeable (i.e. hide theme buttons)
nomsaa
no-msaa (i.e. disable multi-sampling-anti-aliasing)
dark
apply dark theme on-page-load
silver
apply silver theme on-page-load (default)
light
apply light theme on-page-load
animate
play rotary carousel animation on-page-load

There are some caveats to remain aware of when embedding entities using iframes. One such issue is that certain features behave differently when inlined relative to when present in the root page. For example toggling fullscreen typically will not function when embedding an entity - but will work if the bundle is opened directly.

To help clarify - a typical URL for embedding an entity bundle in an iframe is:

{↓}
-
+
...').innerHTML = '<iframe src="webgl/examples/armchair.html#nomax-notheme-animate" width="...

...which will hide the redundant fullscreen toggle-button, the theme setting buttons and start animating the entity when the page loads - as in the following:


Note: that the arguments used above to configure the embedded entity bundle are not in the strictest sense the same as conventional or traditional URL/URI query arguments. Rather the example simply appends the configuration tokens to the page's hash attribute to communicate start-up behaviour.

Another consideration worth mentioning is the behaviour of multiple embedded entity bundles. Essentially you can safely include more than one 3D entity in the same page (each using a separate iframe and root-div with unique id) - however due to the monolithic nature of each bundle - there is not currently a standard (kernel-provided) means of communicating between separate embedded entity bundles.

As an additional note: take care in the manner in which you coordinate iframe navigation if you are interested in re-using the same root-div to display multiple entities in sequence. The recommended strategy is to explicitly clear the root-div completely between entity switches rather than simply setting the src attribute dynamically after initial construction. The reason for this recommendation is that most browsers will bind forward and back global page navigation actions based on changes to an iframe element's src attribute - which often yields undesirable embedding-page usability artefacts - such as the back button not behaving as one might expect. However - be aware that there is a subtle price to be paid for employing such a strategy - which is that by re-creating the iframe for each entity switch one actively prevents the browser from caching the content as it might otherwise usually do to enable faster back operations. Although it is possible to work around this - by coordinating content caching and forward-back navigation between entities at a local level in the embedding-page (i.e. with javascript variables and elements with on-click listeners) - it is fair to say that this can complicate matters somewhat relative to the case of displaying a single entity. This is particularly true if you are not (for whatever reason) auto-generating your embedding-page's content.

In spite of these issues - it is well worth having a play with the kernel's Web-GL outputs to familiarise yourself with them and to evaluate their potential utility in helping you address expositional tasks in 3D research and development.

For a concrete example of how one might utilise them - have a look at the Preview section for 28 QMSH Scripts - which provides a clear demonstration of their use in the portable display of 3D entities generated by the kernel.

Remember that the kernel's monolith Web-GL bundles aim to offer a low overhead method of handling the basic display of 3D entities in a browser. In-particular the storage overhead associated with bundling a 3D entity this way is roughly 20 kb minified which encompasses HTML, CSS, JS and GLSL. Although this can be great for quickly sharing ideas - the bundles are currently (objectively) not as feature-rich as some of the alternative approaches discussed.



Uploading Entities to a Content Hosting Service

If you do not have access to a dedicated server to host your own content an alternative way to coordinate exposition of your creations is via 3D hosting services such as SketchFab. Note: special credit is due to Not_A for demonstrating this.

Alternatives such as p3d.in also provide managed content hosting services.

Note: for services such as SketchFab and p3d.in you can use the kernel's GLTF and GLB outputs - as for Three.js and model-viewer.



Embedding Entities in Portable Direct-Share 3D URLs

If you are unable to use a content hosting service - an alternative way to coordinate basic exposition of your procedural creations is using the experimental direct-share entity exchange and exposition system developed by Codemine which provides facilities for packing 3D quick-mesh entities into portable web-safe URLs which can be instantly added to online-posts and emails as standard links, as well as inlined in comments or chat messages without the requirement for registration.

Quick-Mesh Entity-Exchange

To help clarify the following URL embeds a portable version of a 3D entity which can be viewed directly in browsers supporting Web-GL and Web-Assembly.


Note: the entity embedded in the URL above does not actually exist until it is retrieved and assembled. That is to say that the 3D entity is not actually hosted anywhere on the web - rather the URL represents a request for the program: qmsh.io/share.html which is capable of constructing the entity encoded in the URL's supplementary page-hash attribute - which (in turn) contains the input quick-mesh script that defines the 3D mesh that you can view and download.

In other words one can conceptualise this content exchange approach as somewhat akin to the use of an imaginary-drive or an imaginary-storage-device - in the sense that, although our 3D-URLs loosely appear to be paths indexing into some form of database or storage-infrastructure - in reality no such physical machinery exists.

3D-URLs are targeted primarily at supporting teams of makers working in a geo-spatially distributed manner - who require the ability to frequently transmit 3D procedural entities amongst team members as a means to share ideas regarding implementation strategies, potential solutions, drafts or initial designs.

3D-URLs may also be of assistance to content-creators in digital-media and researchers in computer-graphics and computer-vision as they provide a vehicle for instantly sharing 3D spatial arrangements and representations of abstract concepts without the conventional overhead of managing content storage requirements.

As further clarification and to help ground and contextualise these ideas - the following 3D-URLs provide various practical examples of just some of the types of procedural entity that you might wish to share and/or transmit as direct paths.


Observe in the examples above that in cases where an entity exposes control-parameters one retains the ability to mutate their values and remesh directly in browser. This is similar in many ways to the experimental web-assembly editor.

Note: the ability to effect this class of 3D content-sharing mechanism is predicated on the purely-procedural nature of quick-mesh's portable 3D descriptors. To be clear: this capacity is not unique to quick-mesh and indeed any portable 3D kernel that supports the purely-procedural generative approach can also (in principle at least) be used in a similar manner to coordinate direct-share interchange of 3D entities.

Interestingly - one of the key benefits of the direct-share approach is its scalability to an arbitrary number of entity exchanges given that it does not intrinsically require any server-side processing. As the actual geometric unpacking process is handled client-side the administrative costs associated with supporting the direct-share approach are surprisingly low. In practical terms - this means that as engineers and researchers - we can create, host, post and share as many 3D-URLs as we require without usage limits or restrictive caps - which can be particularly handy during the ideation phase - wherein the ability to iterate quickly and instantly communicate initial/early/draft solutions directly to peers and colleagues is advantageous.

To round-out this outline of quick-mesh 3D-URLs the following blocks discuss some of the key auxiliary considerations related to this approach. Specifically they cover safety, privacy, security, usability and technical performance considerations.

Safety | Generally speaking - executing code of unknown origin and/or clicking arbitrary links can be a bad idea - therefore exercise the same care and attention to verifying 3D-URL links as you would to any other type of URL. For example you should look at the exact path to which you are navigating in your browser's base-bar (if possible) prior to clicking a 3D-URL link. Specifically observe that all quick-mesh 3D-URLs begin with the prefix: https://www.qmsh.io/share.html - or with the prefix: https://qmsh.io/share.html - therefore 3D-URLs that do not begin with either of these prefixes should be treated with a wary disposition. In other words practise web safety and constant vigilance exactly as you would for other types of content.

Privacy | Positively the decentralised nature of the direct-share approach - coupled with its low maintenance cost - results in handy gains to user-privacy. In particular as the system does not require registration there is no need to supply any personal information in order to use it. This can be particularly helpful for events such as game-jams, code-jams, summer-schools and similar community centered creative collaborative activities - largely by side-stepping any privacy or data-protection obligations that organisers might otherwise be required to manage in order to coordinate similar functionality. Furthermore: by favouring client-side processing the logistical cost of this exchange approach is reduced to the point that it is practical to offer the service without ad-based revenue support or similar modern monetisation schemes. This is vital because it enables the experimental entity-exchange to conform to Codemine's online policy of cookie-free and tracker-free operation.

Security | By-design - the entity-exchange (as the experimental web-assembly editor) operates in isolation (i.e. sandboxed) without access to typical web APIs - or device sensors or peripherals (such as cameras, microphones, geo-location or positional sensors). This has the benefit of removing many of the security risks that one might otherwise associate with browser-based utilities. Specifically: by supporting solely the assembly of quick-mesh scripts - the entity-exchange minimises its attack surface and its susceptibility to code-injection styled attacks. Further by operating client-side - without transmitting 3D mesh data back and forth - we can also reduce the risk associated with DDoS (distributed denial-of-service style) attacks. Remember though that whilst a security-conscious system-architecture helps to protect us whilst using the entity-exchange - no security approach is infallible - hence always exercise care and attention to detail.

Usability/Utility | The core usability benefit of 3D-URLs is that they increase the accessibility of our procedural entities - particularly when one wishes to communicate an idea with those who may not have quick-mesh installed on their machines or devices. However as for the sandboxed web-editor - this accessibility comes at the cost of efficiency and feature support. In other words although we gain a measure of usability by by-passing the need to install software - we sacrifice mesh-assembly performance in order to gain this easy-access pattern. This trade-off currently also includes the loss of features such as intermediary progress notifications, non-blocking mesh-assembly and user-abort-support - which are available out-of-the-box using native tools such as the mobile-editor.

Performance | Performance-wise the key implication of the direct-share approach (backed by a purely-procedural descriptor) is that one essentially offloads the computational-workload associated with assembling a 3D entity from the content-creator or distributor to the content-consumer. In essence when we assemble 3D-mesh client-side the characteristics of the target-device will factor into the assembly runtime. Whereas pre-assembled content tends to favour content-availability over content storage-requirements - purely-procedural content tends to favour compact storage-requirements over content-availability. Practically (for our particular use-case) the main performance consideration is the disparity between entity-assembly runtime in browsers that support Web-Assembly relative to those that fallback to using ASM.js. The point is that with Web-Assembly we gain near native-speed meshing - whilst without Web-Assembly the assembly process can be (sometimes unacceptably) slow by comparison. Sadly there is no-quick-fix for this performance limitation. However fortunately - as time progresses and Web-Assembly continues to grow in its support within modern browsers - the impact of this issue shall naturally decrease. Note: whilst direct-share entity-exchange can be helpful for sharing entities (especially when away from one's main machine) - for handling larger scale projects the quick-mesh native toolchain should always be the preferred route primarily for the performance gains and feature-support.

So whilst 3D-URLs and the direct-share entity-exchange are by no means silver-bullets - they do provide a handy utility for those interested in pure-procedural 3D.

Note: as an incidental - one of the less obvious logistical benefits of 3D-URLs is that they enable individuals to interchange procedural entities without having to redistribute the kernel's reference-implementations. Although a subtle point - it is worthwhile noting - because it ensures that use of the entity-exchange does not violate the (admittedly overly-cautious) terms of use - which currently prohibit third-party redistribution of the reference-implementations. In many ways the advent of the entity-exchange constitutes an important step towards relaxing this (and similar) constraints in that it provides a safe context within which to explore the manner in which purely-procedural geometric constructs can be utilised to serve the collaborative needs of researchers, engineers and creators the world over.

In other words: stable, scalable 3D exchange is a necessary component of many technical pursuits - yet the overhead associated with implementing the necessary machinery (especially for procedural-entities which involve dynamic-re-evaluation) can often act as a barrier to productivity. The entity-exchange aims to help combat this issue and enable innovative use of purely-procedural 3D-geometry.

Finally: this section closes with insights drawn from the investigative/development process that aim to help you get the most out of 3D-URLs. This is mainly to help steer your use of 3D-URLs and to supplement your decision making during script-authoring in instances when you intend to share an entity as a direct-share path.
  • Prioritise Execution-Speed over Script-Length
  • Only Exchange 3D-URLs with People and Parties you Trust
  • Remember that 3D-URLs are an Experimental Technology
'Prioritise Execution-Speed over Script-Length' → although it may to tempting to spend time minifying your scripts in order to squeeze them into ever-shorter 3D-URL paths - you may be better served by focussing on reducing the execution-time before worrying about script length. The reason being that for purely-procedural entities the assembly runtime is the key factor governing the perception of latency in retrieval. The faster your scripts run the smoother and more satisfying the experience for those who engage with your creations. This is particularly important when Web-Assembly is not supported - and ASM.js is used instead. Indeed prioritising speed over length can often be the difference between an entity that fallbacks gracefully (i.e. graceful degradation on older hardware) and an entity that is abandoned prior to completing assembly due to the perception of an unacceptable delay. Note: this is not to say that linting and minification of scripts is not useful - however it should be clear that for web-based direct-share entity-exchange, speed takes priority - especially in the case of parametric entity exchanges.

'Only Exchange 3D-URLs with People and Parties you Trust' → this may/should already be obvious - nonetheless it is worth reiterating explicitly. 3D-URLs are technically no different from other types of URL - hence treat them as you would other links. Additionally bear in mind that if you share a 3D-URL - any one with the direct-share path can view your entity - therefore (once again) only exchange 3D-URLs with people and parties you trust.

'Remember that 3D-URLs are an Experimental Technology' → as such (and as all things) - 3D-URLs are subject to change. Therefore if you use them in perma-links make sure to check them once in a while to verify they are still working and (if necessary) update/regenerate them using your quick-mesh scripts as input.

Kernel Resources



This section provides resources to assist in experimentation with the kernel at a lower-level. This includes tools and references to ease the integration of the kernel in prototypes and to support development of proof-of-concepts.

NOTE: THIS SECTION'S CONTENT IS PENDING

Language Resources



This section includes resources to assist in experiments related to the formation of grammar-centric tools and utilities. These resources may also be of use to developers of text-editors and integrated-development-environments.

NOTE: THIS SECTION'S CONTENT IS PENDING

Page End.