dtmf.ca
1. log
1.1. X3DOM iframe test x3d sketchup2018
1.1.1. Context
VRML
has been an ISO standard since 1997, after first being defined in 1994… and it has since been superseded by a new standard called X3D
.1https://www.web3d.org
The first I remembered hearing about VRML
was from very unlikely place: casually mentioned during an interview with a man claiming to have met—and worked with—extra-terrestrial beings [from the future] under the auspices of a clandestine research unit engaged in biological research to bolster intergalactic diplomacy via life-saving cures for their ailing alien allies.
Huh?
Yeah, well… he CLAIMED these things.
I'm not saying they were true. He was. Quite vehemently.
If he was a trained actor or some sort of mental case… his performance was of the utmost calibre.
I found his stories fascinating, and a way of elevating quotidian chores into the realm of imagination and flights-of-fancy.
And in the process of describing some technical detail or another, he said—nonchalantly, before moving on—the acronym VRML
.
This term mystified me.
Alternate timelines, beings that represented our future evolutionary path[s], secret treaties… all were momentarily forgotten.
Amongst the fantastical elements, a concrete term to search.
It spurred a whole line of inquiry, which has culminated in the following:
1.1.2. Materials Used
-
Sketchup 2018
- Ruby export script
-
castle-engine
(forVRML
>X3D
) -
X3DOM
1.1.3. General flow:

# Copyright 2025, Dylan T. Mitchell-Funk # # This software is provided "as is", without warranty of any kind, express or # implied, including but not limited to the warranties of merchantability, # fitness for a particular purpose and noninfringement. In no event shall the # authors or copyright holders be liable for any claim, damages or other # liability, whether in an action of contract, tort or otherwise, arising from, # out of or in connection with the software or the use or other dealings in # the software. require 'sketchup.rb' #============================================================================= # This module encapsulates the exporter functionality to prevent conflicts with # other extensions. # module CGE_X3D_Exporter #=========================================================================== # The core logic for the export and conversion process. # def self.export_to_x3d # --- 1. Get the active model and define file paths --- model = Sketchup.active_model model_path = model.path # The model must be saved first to establish a base path for exports. if model_path.empty? UI.messagebox('Please save your model before exporting to X3D.') return end # Check for SketchUp Pro, as VRML export is a Pro-only feature. unless Sketchup.is_pro? UI.messagebox('VRML export is a SketchUp Pro feature. This extension cannot proceed.') return end # Define paths based on the saved model's location and name. dir = File.dirname(model_path) basename = File.basename(model_path, '.skp') wrl_path = File.join(dir, "#{basename}.wrl") x3d_path = File.join(dir, "#{basename}.x3d") # --- 2. Define the path to the conversion utility --- # This is the hardcoded path to your Castle Game Engine executable. # If you move the engine, you must update this path. converter_path = "/Applications/castle-engine/bin/castle-model-viewer.app/Contents/MacOS/castle-model-viewer" # Verify that the converter executable actually exists at the specified path. unless File.exist?(converter_path) UI.messagebox("Conversion tool not found at:\n#{converter_path}\n\nPlease check your Castle Game Engine installation path.") return end # --- 3. Export the model to VRML (.wrl) --- # SketchUp's export method infers the format from the file extension. # This will create the .wrl file and a folder with textures if they exist. begin puts "Exporting to VRML: #{wrl_path}" export_status = model.export(wrl_path) unless export_status UI.messagebox("Failed to export model to VRML file.") return end rescue => e UI.messagebox("An error occurred during VRML export:\n#{e.message}") return end # --- 4. Construct and execute the conversion command --- # The command is built using the paths defined above. # "castle-model-viewer ... --write --write-encoding xml > output.x3d" # Using %Q{} allows for clean handling of paths that may contain spaces. command = %Q{ "#{converter_path}" "#{wrl_path}" --write --write-encoding xml > "#{x3d_path}" } puts "Executing conversion command:" puts command # Execute the command in the system's shell. # The `system` command returns `true` on success, `false` on failure, # or `nil` if the command could not be executed. conversion_status = system(command) # --- 5. Provide feedback to the user --- if conversion_status UI.messagebox("Successfully exported and converted to:\n#{x3d_path}") # Optional: Open the containing folder after successful export. # system("open \"#{dir}\"") else UI.messagebox("The conversion to X3D failed. Please check the Ruby Console for more details.") puts "Conversion command failed. This could be an issue with Castle Game Engine or the exported VRML file." end # The intermediate .wrl file is kept for debugging purposes. end # def self.export_to_x3d #=========================================================================== # This block runs once when the script is loaded. It creates the menu item. # unless file_loaded?(__FILE__) # Get the "File" menu. You could also use "Extensions". menu = UI.menu('File') # Add a separator and our menu item. menu.add_separator menu.add_item('Export to X3D (via CGE)') { self.export_to_x3d } file_loaded(__FILE__) end end # module CGE_X3D_Exporter
1.1.4. Result
1.2. dtmf.ca org-publish architecture org_mode plantuml org_publish spacemacs emacs

@startuml !theme spacelab skinparam backgroundColor #FFFFFE ' Define actors and components actor "Author (dtmf)" as Author actor "Visitor (you)" as Visitor package "Emacs Environment" { ' The previous multi-line component syntax was causing a parse error. ' This version uses a single quoted string with newlines, which is more robust. component "==.spacemacs\n--\norg-publish-project-alist\ndtfm/new-log-post()" as SpacemacsConfig Author -- SpacemacsConfig } package "Source Directory" { node "~/org/dtmf.ca-src-tufte/" as SrcDir { artifact "<b>setup.org</b>\n<size:10>#+OPTIONS: publish:nil" as Setup artifact "<b>header.org</b>\n<size:10>#+OPTIONS: publish:nil" as Header artifact "<b>footer.org</b>\n<size:10>#+OPTIONS: publish:nil" as Footer artifact "<b>index.org</b>" as Index artifact "<b>log.org</b>" as Log folder "logs/" { artifact "<b>post-1.org</b>" as Post1 artifact "<b>post-2.org</b>" as Post2 } folder "assets/" { artifact "<b>model.x3d</b>" as Model artifact "<b>x3d-viewer.html</b>" as Viewer } artifact "<b>Static Files</b>\n<size:10>.css, .js" as Static } } package "Publishing & Deployment" { queue "<b>org-publish</b>\n<size:10>M-x org-publish" as OrgPublish node "~/dtmf.ca/" as PubDir node "Local Test Server" as LocalServer cloud "Live Web Server" as LiveServer } ' Define relationships SpacemacsConfig -> OrgPublish : "configures" OrgPublish -> SrcDir : "reads from" ' Source file relationships Index ..> Setup : "<<include>>" Index ..> Header : "<<include>>" Index ..> Footer : "<<include>>" Log ..> Setup Log ..> Header Log ..> Footer Post1 ..> Setup Post2 ..> Setup ' Log.org now transcludes the individual posts instead of linking to them. Log ..> Post1 : "<<transclude>>" Log ..> Post2 : "<<transclude>>" ' The custom function now just creates the post file. SpacemacsConfig ..> Post2 : "dtmf/new-log-post()\ncreates" ' Publishing flow OrgPublish -> PubDir : "writes to" PubDir -> LocalServer : "serves" PubDir -> LiveServer : "is deployed to" ' Visitor interaction LocalServer -- Author : "for testing" LiveServer -- Visitor : "serves site to" Visitor -> Index : "views" Visitor -> Post1 Visitor -> Viewer Viewer ..> Model : "<<loads>>" @enduml
1.3. domains in the membrane domains
Domain Name | Expiry |
moneyshirt.shop | Apr 26, 2026 |
superordinate.space | Apr 24, 2026 |
ph-dj.net | Apr 21, 2026 |
escarpment.media | Apr 20, 2026 |
concerted.systems | Apr 18, 2026 |
dreammachine.icu | Apr 18, 2026 |
touchdesigner.icu | Apr 18, 2026 |
goldenhorseshoe.live | Apr 18, 2026 |
selfreflectron.me | Apr 18, 2026 |
didact.digital | Apr 18, 2026 |
niagara.lol | Dec 21, 2025 |
dingushead.com | Dec 21, 2025 |
concrete.foundation | Dec 21, 2025 |