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

1.1.3. General flow:

sketchup-cge-workflow.png
# 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

architecture.png
@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