From 81357fbffe1ce95065217eb0d8be980632bee333 Mon Sep 17 00:00:00 2001 From: Samuel Tallet Date: Thu, 28 Nov 2019 04:51:07 +0100 Subject: [PATCH] Add option: Track all changes. --- source/.rubocop.yml | 2 +- source/pbr.rb | 2 +- source/pbr/Resources/fr/pbr.strings | 6 +- .../Viewport App/assets/sketchup-locale.json | 1 - .../Viewport App/assets/sketchup-model.gltf | 1 - source/pbr/Viewport App/viewport.js | 66 +++++++++++++++++++ source/pbr/app_observer.rb | 17 +++-- source/pbr/entity_observer.rb | 52 --------------- source/pbr/gltf.rb | 15 +++++ source/pbr/light.rb | 5 -- source/pbr/load.rb | 18 +++-- source/pbr/material_editor.rb | 8 +-- source/pbr/menu.rb | 29 +++++++- source/pbr/model_observer.rb | 14 ++++ source/pbr/nil_material_fix.rb | 7 -- source/pbr/toolbar.rb | 4 +- source/pbr/viewport.rb | 12 +++- 17 files changed, 169 insertions(+), 90 deletions(-) delete mode 100644 source/pbr/Viewport App/assets/sketchup-locale.json delete mode 100644 source/pbr/Viewport App/assets/sketchup-model.gltf delete mode 100644 source/pbr/entity_observer.rb diff --git a/source/.rubocop.yml b/source/.rubocop.yml index c2b921d..22ea70b 100644 --- a/source/.rubocop.yml +++ b/source/.rubocop.yml @@ -18,7 +18,7 @@ Metrics/AbcSize: Enabled: false Metrics/MethodLength: - Max: 20 + Max: 25 Metrics/ClassLength: Max: 200 \ No newline at end of file diff --git a/source/pbr.rb b/source/pbr.rb index 98e7009..5199664 100644 --- a/source/pbr.rb +++ b/source/pbr.rb @@ -26,7 +26,7 @@ # PBR plugin namespace. module PBR - VERSION = '1.5.5'.freeze + VERSION = '1.5.6'.freeze # Load translation if it's available for current locale. TRANSLATE = LanguageHandler.new('pbr.strings') diff --git a/source/pbr/Resources/fr/pbr.strings b/source/pbr/Resources/fr/pbr.strings index ee0b677..34ff8bd 100644 --- a/source/pbr/Resources/fr/pbr.strings +++ b/source/pbr/Resources/fr/pbr.strings @@ -34,7 +34,8 @@ "HDR Image"="Image HDR"; "Edit Materials..."="Modifier les matériaux..."; "Add an Artificial Light"="Ajouter une lumière artificielle"; -"Reopen Viewport"="Rouvrir la fenêtre de visualisation"; +"Render scene in Viewport"="Rendre la scène dans la fenêtre de visu."; +"Track all Changes"="Suivre tous les changements"; "Export As 3D Object..."="Exporter en tant qu'objet 3D..."; "Export As glTF"="Exporter en tant que fichier glTF"; "Model well exported here:"="Modèle bien exporté ici :"; @@ -52,7 +53,7 @@ "PBR"="RBP"; "Define if a material is rough, is a metal, etc."="Définissez si un matériau est rugueux, est un métal, etc."; "Move it in space. Change its color."="Déplacez-la dans l'espace. Changez sa couleur."; -"Render scene in real-time."="Rendez la scène en temps réel."; +"This will reopen Viewport."="Ceci réouvrira la fenêtre de visualisation."; "Save 3D model as .gltf."="Enregistrez le modèle 3D en tant que .gltf."; // @@ -117,6 +118,7 @@ // "Untitled"="Sans titre"; +"Export geometry and textures to glTF format"="Export de la géométrie et des textures au format glTF"; "PBR: Exporting geometry and textures... Please wait."="RBP : Export de la géométrie et des textures en cours... Veuillez patienter."; // diff --git a/source/pbr/Viewport App/assets/sketchup-locale.json b/source/pbr/Viewport App/assets/sketchup-locale.json deleted file mode 100644 index 3b57bff..0000000 --- a/source/pbr/Viewport App/assets/sketchup-locale.json +++ /dev/null @@ -1 +0,0 @@ -sketchUpLocale = {"document_title":"","sunlight_intensity":"","help_link_href":"","help_link_text":"","reset_cam_position":""}; \ No newline at end of file diff --git a/source/pbr/Viewport App/assets/sketchup-model.gltf b/source/pbr/Viewport App/assets/sketchup-model.gltf deleted file mode 100644 index 1062adc..0000000 --- a/source/pbr/Viewport App/assets/sketchup-model.gltf +++ /dev/null @@ -1 +0,0 @@ -{"asset":{"version":"2.0","generator":"Sketchup glTF Exporter v1.2.6 by Centaur, SketchUp PBR plugin v1.3.1"},"scene":0,"scenes":[{"nodes":[0]}],"samplers":[{}],"nodes":[{"name":"root"}],"materials":[],"meshes":[],"accessors":[],"bufferViews":[],"buffers":[{"uri":"data:application/octet-stream;base64,","byteLength":0}]} \ No newline at end of file diff --git a/source/pbr/Viewport App/viewport.js b/source/pbr/Viewport App/viewport.js index 0a5c811..c862090 100644 --- a/source/pbr/Viewport App/viewport.js +++ b/source/pbr/Viewport App/viewport.js @@ -100,6 +100,13 @@ PBR.Viewport.naturalLights = {}; */ PBR.Viewport.artificialLights = []; +/** + * Viewport glTF model version. + * + * @type {number} + */ +PBR.Viewport.modelVersion = 0; + /** * Helper function to convert HTML colors. * @@ -375,9 +382,66 @@ PBR.Viewport.listenToCameraReset = function() { }; +/** + * Set model version from URL parameter? + */ +PBR.Viewport.setModelVersion = function() { + + PBR.Viewport.modelVersion = parseInt(document.location.search.replace(/\D/g, '')); + + if ( isNaN(PBR.Viewport.modelVersion) ) { + + PBR.Viewport.modelVersion = parseInt(Date.now() / 1000); + + } + +}; + +/** + * Refresh Viewport if a newer version of model is available. + */ +PBR.Viewport.checkForModelUpdates = function() { + + var request = new XMLHttpRequest(); + + var lastModelVersion = 0; + + request.addEventListener('load', function(event) { + + lastModelVersion = parseInt(event.target.response); + + if ( PBR.Viewport.modelVersion < lastModelVersion ) { + + // Refresh Viewport. + document.location.search = 'model_ver=' + lastModelVersion; + + } + + }); + + request.open('GET', 'assets/sketchup-model.ver'); + + request.send(); + +}; + +/** + * Set Viewport "Check Model Updates" interval. + */ +PBR.Viewport.setCmuInterval = function() { + + window.setInterval( + PBR.Viewport.checkForModelUpdates, + 1000 + ); + +}; + // When document is ready: document.addEventListener('DOMContentLoaded', function() { + PBR.Viewport.setModelVersion(); + PBR.Viewport.translateStrings(); PBR.Viewport.listenToSunlightChange(); @@ -386,6 +450,8 @@ document.addEventListener('DOMContentLoaded', function() { PBR.Viewport.listenToCameraReset(); + PBR.Viewport.setCmuInterval(); + }); // When window is resized: diff --git a/source/pbr/app_observer.rb b/source/pbr/app_observer.rb index 61147db..fd7f67c 100644 --- a/source/pbr/app_observer.rb +++ b/source/pbr/app_observer.rb @@ -22,6 +22,7 @@ require 'sketchup' require 'pbr/viewport' +require 'pbr/model_observer' # PBR plugin namespace. module PBR @@ -32,16 +33,24 @@ class AppObserver < Sketchup::AppObserver # rubocop: disable Naming/MethodName # When SketchUp user creates a new, empty model. - def onNewModel(_model) + def onNewModel(model) - Viewport.reopen if Viewport.update_model + Viewport.close + + SESSION[:track_all_changes?] = false + + model.add_observer(ModelObserver.new) end # When SketchUp user opens an existing model: - def onOpenModel(_model) + def onOpenModel(model) + + Viewport.close + + SESSION[:track_all_changes?] = false - Viewport.reopen if Viewport.update_model + model.add_observer(ModelObserver.new) end diff --git a/source/pbr/entity_observer.rb b/source/pbr/entity_observer.rb deleted file mode 100644 index 15bb0ad..0000000 --- a/source/pbr/entity_observer.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Physically-Based Rendering extension for SketchUp 2017 or newer. -# Copyright: © 2019 Samuel Tallet -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3.0 of the License, or -# (at your option) any later version. -# -# If you release a modified version of this program TO THE PUBLIC, -# the GPL requires you to MAKE THE MODIFIED SOURCE CODE AVAILABLE -# to the program's users, UNDER THE GPL. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# Get a copy of the GPL here: https://www.gnu.org/licenses/gpl.html - -raise 'The PBR plugin requires at least Ruby 2.2.0 or SketchUp 2017.'\ - unless RUBY_VERSION.to_f >= 2.2 # SketchUp 2017 includes Ruby 2.2.4. - -require 'sketchup' -require 'pbr/viewport' - -# PBR plugin namespace. -module PBR - - # Observes SketchUp entity events and reacts. - class EntityObserver < Sketchup::EntityObserver - - # rubocop: disable Naming/MethodName - - # When a SketchUp entity was erased. - def onEraseEntity(entity) - - # If it was a PBR artificial light: - if SESSION[:lights_objects_ids].include?(entity.object_id.to_i) - - Viewport.update_model_and_reopen - - SESSION[:lights_objects_ids].delete(entity.object_id.to_i) - - end - - end - - # rubocop: enable Naming/MethodName - - end - -end diff --git a/source/pbr/gltf.rb b/source/pbr/gltf.rb index 22ab73d..2860acc 100644 --- a/source/pbr/gltf.rb +++ b/source/pbr/gltf.rb @@ -93,6 +93,13 @@ def initialize begin + SESSION[:export_in_progress?] = true + + Sketchup.active_model.start_operation( + TRANSLATE['Export geometry and textures to glTF format'], + true # disable_ui + ) + Sketchup.status_text = TRANSLATE[ 'PBR: Exporting geometry and textures... Please wait.' ] @@ -101,12 +108,20 @@ def initialize complete + Sketchup.active_model.commit_operation + + SESSION[:export_in_progress?] = false + Sketchup.status_text = nil rescue StandardError => _exception @valid = false + Sketchup.active_model.abort_operation + + SESSION[:export_in_progress?] = false + Sketchup.status_text = nil end diff --git a/source/pbr/light.rb b/source/pbr/light.rb index 83acdea..6d3deca 100644 --- a/source/pbr/light.rb +++ b/source/pbr/light.rb @@ -22,7 +22,6 @@ require 'sketchup' require 'pbr/shapes' -require 'pbr/entity_observer' # PBR plugin namespace. module PBR @@ -42,10 +41,6 @@ def initialize @light.name = 'PBR Light' - SESSION[:lights_objects_ids].push(@light.object_id.to_i) - - @light.add_observer(EntityObserver.new) - end end diff --git a/source/pbr/load.rb b/source/pbr/load.rb index 235e4d6..35efc6d 100644 --- a/source/pbr/load.rb +++ b/source/pbr/load.rb @@ -37,23 +37,27 @@ module PBR Sketchup.active_model.add_observer(ModelObserver.new) # Material Editor is not open yet. - SESSION[:mat_editor_open?] = false + SESSION[:material_editor_open?] = false # Storage for Chromium process ID. - SESSION[:viewport_pid] = 0 + SESSION[:viewport_process_id] = 0 - # Memory of artificial lights IDs. - SESSION[:lights_objects_ids] = [] + # Changes are not tracked by default. + SESSION[:track_all_changes?] = false - # Plug PBR menu into SketchUp UI. + # Indicates if exporting to glTF... + SESSION[:export_in_progress?] = false + + # Memory of last Viewport update. + SESSION[:last_viewport_update] = 0 + + # Plugs PBR menu into SketchUp UI. Menu.new( UI.menu('Plugins') # parent_menu ) Toolbar.new.prepare.show - Viewport.open if Viewport.translate - # Load complete. end diff --git a/source/pbr/material_editor.rb b/source/pbr/material_editor.rb index 9dcf2e1..de06a0a 100644 --- a/source/pbr/material_editor.rb +++ b/source/pbr/material_editor.rb @@ -40,7 +40,7 @@ def self.safe_to_open? return false end - if SESSION[:mat_editor_open?] + if SESSION[:material_editor_open?] UI.messagebox(TRANSLATE['PBR Material Editor is already open.']) return false end @@ -83,7 +83,7 @@ def show @dialog.show # Material Editor is open. - SESSION[:mat_editor_open?] = true + SESSION[:material_editor_open?] = true end @@ -160,11 +160,11 @@ def show @dialog.close - Viewport.update_model_and_reopen + Viewport.update_model end - @dialog.set_on_closed { SESSION[:mat_editor_open?] = false } + @dialog.set_on_closed { SESSION[:material_editor_open?] = false } @dialog.center diff --git a/source/pbr/menu.rb b/source/pbr/menu.rb index 1eb101f..e6ab408 100644 --- a/source/pbr/menu.rb +++ b/source/pbr/menu.rb @@ -70,6 +70,8 @@ def initialize(parent_menu) add_reopen_viewport_item + add_track_changes_item + add_export_as_gltf_item add_donate_to_author_item @@ -122,7 +124,7 @@ def initialize(parent_menu) # @return [nil] private def add_reopen_viewport_item - @menu.add_item(TRANSLATE['Reopen Viewport']) do + @menu.add_item(TRANSLATE['Render scene in Viewport']) do return PBR.open_required_plugin_page unless PBR.required_plugin_exist? @@ -134,6 +136,31 @@ def initialize(parent_menu) end + # Adds "Track all Changes" menu item. + # + # @return [nil] + private def add_track_changes_item + + menu_item = @menu.add_item(TRANSLATE['Track all Changes']) do + + SESSION[:track_all_changes?] = !SESSION[:track_all_changes?] + + end + + @menu.set_validation_proc(menu_item) { + + if SESSION[:track_all_changes?] + MF_CHECKED + else + MF_UNCHECKED + end + + } + + nil + + end + # Adds "Export As 3D Object..." menu item. # # @return [void] diff --git a/source/pbr/model_observer.rb b/source/pbr/model_observer.rb index b21ba41..8f835b1 100644 --- a/source/pbr/model_observer.rb +++ b/source/pbr/model_observer.rb @@ -38,6 +38,20 @@ def onPreSaveModel(_model) end + # When a SketchUp transaction is completed. + def onTransactionCommit(_model) + + if SESSION[:track_all_changes?] && !SESSION[:export_in_progress?]\ + && (SESSION[:last_viewport_update] + 3) < Time.now.to_i + + SESSION[:last_viewport_update] = Time.now.to_i + + Viewport.update_model + + end + + end + # rubocop: enable Naming/MethodName end diff --git a/source/pbr/nil_material_fix.rb b/source/pbr/nil_material_fix.rb index 2df219d..e20d573 100644 --- a/source/pbr/nil_material_fix.rb +++ b/source/pbr/nil_material_fix.rb @@ -30,19 +30,12 @@ class NilMaterialFix # Traverses active model tree to fix faces having "nil material" issue. def initialize - - Sketchup.active_model.start_operation( - TRANSLATE['Propagate Materials to Whole Model'], - true # disable_ui - ) create_fallback_material # Start model tree traversal... traverse(Sketchup.active_model) - Sketchup.active_model.commit_operation - end # Creates a fallback material unless it already exists. diff --git a/source/pbr/toolbar.rb b/source/pbr/toolbar.rb index a2b5c70..5149bc6 100644 --- a/source/pbr/toolbar.rb +++ b/source/pbr/toolbar.rb @@ -112,8 +112,8 @@ def initialize command.small_icon = File.join(ICONS_PATH, 'rv'.concat(icon_extension)) command.large_icon = File.join(ICONS_PATH, 'rv'.concat(icon_extension)) - command.tooltip = TRANSLATE['Reopen Viewport'] - command.status_bar_text = TRANSLATE['Render scene in real-time.'] + command.tooltip = TRANSLATE['Render scene in Viewport'] + command.status_bar_text = TRANSLATE['This will reopen Viewport.'] @toolbar.add_item(command) diff --git a/source/pbr/viewport.rb b/source/pbr/viewport.rb index e139391..c5ab946 100644 --- a/source/pbr/viewport.rb +++ b/source/pbr/viewport.rb @@ -71,6 +71,13 @@ def self.update_model # Overwrite glTF model. So, Viewport will display an up-to-date model. File.write(gltf_path, gltf.json) if gltf.valid? + ver_path = File.join(ASSETS_DIR, 'sketchup-model.ver') + + # Overwrite model version, same reason. + File.write(ver_path, Time.now.to_i.to_s) + + translate + gltf.valid? end @@ -103,7 +110,7 @@ def self.open Chromium.make_exec - SESSION[:viewport_pid] = Process.spawn( + SESSION[:viewport_process_id] = Process.spawn( Chromium.executable, @@ -125,8 +132,9 @@ def self.open # @return [Boolean] true on success... def self.close - Process.kill('KILL', SESSION[:viewport_pid]) + Process.kill('KILL', SESSION[:viewport_process_id]) Chromium.simulate_normal_exit + true rescue StandardError => _exception