it is fierce mate. Thanks . lets hope for positive changes.. and a lasting peace in world.
Posts
-
RE: Merry Christmas
-
RE: Rayscaper New Releases
I guess it is bkz I use SU 2023... and RS does not support it
-
RE: Rayscaper New Releases
Thanks for the update, though I have issues with it. Here is what I get:
Error: #<LoadError: 126: The specified module could not be found. - c:/users/magic/appdata/roaming/sketchup/sketchup 2023/sketchup/plugins/rayscaper/installed/Windows/2023/0.9.82 Beta/resources/SUEX_Rayscaper_LoadLibs.so>
E:/Program Files/SketchUp/Sketchup 2023/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:83:inrequire' E:/Program Files/SketchUp/Sketchup 2023/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:83:inrequire'
c:/users/magic/appdata/roaming/sketchup/sketchup 2023/sketchup/plugins/rayscaper/main.rbe:174:in<module:Rayscaper>' c:/users/magic/appdata/roaming/sketchup/sketchup 2023/sketchup/plugins/rayscaper/main.rbe:8:in<main>'
E:/Program Files/SketchUp/Sketchup 2023/Tools/extensions.rb:197:ineval' E:/Program Files/SketchUp/Sketchup 2023/Tools/extensions.rb:197:inrequire'
E:/Program Files/SketchUp/Sketchup 2023/Tools/extensions.rb:197:inload' C:/Users/Magic/AppData/Roaming/SketchUp/SketchUp 2023/SketchUp/Plugins/rayscaper.rb:18:inregister_extension'
C:/Users/Magic/AppData/Roaming/SketchUp/SketchUp 2023/SketchUp/Plugins/rayscaper.rb:18:in<module:Rayscaper>' C:/Users/Magic/AppData/Roaming/SketchUp/SketchUp 2023/SketchUp/Plugins/rayscaper.rb:6:in<top (required)>'I uninstalled the previous version, then removed the entire plugin and its loader and reinstalled it, yet the issue persists.
-
RE: SketchVault
Thanks TIG, I am honored that my hero is commenting on the path I am going.
Okay I will add more guidance on each section.
Also will try to make it "dynamic" before finalizing.
Color coding is meant to show the pressure forces on each part of the mesh.It meant to generate the best "compressure-only" structure out of the given input.
will update it soon. -
RE: SketchVault
Using Gemini, the code is now better, though it generates numerous materials. To make it work: Select the "anchors (face/edge) color it in pure red. Select desired mesh, run the plugin
Here is the file
Majid_FoldingVaults.rbz -
RE: Beauties of Iran (other face of Iran)
We, ordinary people, are living our lives and are changing /bending the rules despite all politics!
-
RE: A,B, Sketches
Maybe sharing the progress process could be more interesting so here are samples:


-
RE: A,B, Sketches
Let's proceed with the letter "J".
I wish I could share more of each letter.

-
RE: Beauties of Iran (other face of Iran)
Fascinating photos reveal life in Iran before the revolution
The stunning photos of life across vibrant Iran in the 60s and 70s portray a seemingly cosmopolitan kingdom on the brink of change.
Mail Online (www.dailymail.co.uk)
-
RE: Rayscaper New Releases
I have a question regarding material libraries. I have prepared a Carpaint collection and am also going to prepare a water material pack. The question is that if the same name materials will be replaced? i.e. a car paint in my library is called 001red. Imagine there is another material in the Sketchup model by user and called 001red, I am wondering if RS will replace the same name with my material? To be more precise: How do material libraries in RS work?
-
RE: A,B, Sketches
@L-i-am I got a diploma in mathematics and was into algorithmic thinking. Then tried to learn architecture during university with my analytic mindset. So I see it like a procedure, not like those who do magic out of a black box. For some years, I had this chance to teach architecture, and after years, sometimes students call me to thank my way of teaching. I hope I have the chance again; this is the most satisfying job for me.
-
SketchVault
I have been developing a vault generator add-on for Blender 3D that is aimed to mimic RhinoVault (considering Blender cons/pros vs Rhino).
It tries to find the best compression-only form for the given input mesh. Recently, I used Gemini to translate it to work with SketchUp. It is in its early stages and would be fine if anyone helps me to improve it.# ============================================================ # SKETCHUP FOLDING VAULTS V4 (Robust Non-Flat Mesh + Red Anchors) | By Majid Yeganegi AI optimization -2025 Nov. # ============================================================ require 'sketchup.rb' module VaultPlugin # --- 1. Math Helper Classes (Unchanged for performance) --- class SparseMatrix attr_reader :n_rows def initialize(n_rows) @n_rows = n_rows @rows = Hash.new { |h, k| h[k] = {} } end def add(r, c, val) return if r >= @n_rows || c >= @n_rows @rows[r][c] ||= 0.0 @rows[r][c] += val end def dot(vec) result = Array.new(@n_rows, 0.0) @rows.each do |r_idx, col_data| sum = 0.0 col_data.each { |c_idx, val| sum += val * vec[c_idx] } result[r_idx] = sum end result end end class VectorMath def self.sub(a, b); a.zip(b).map { |x, y| x - y }; end def self.add(a, b); a.zip(b).map { |x, y| x + y }; end def self.scale(vec, s); vec.map { |x| x * s }; end def self.dot(a, b); a.each_with_index.reduce(0) { |sum, (val, i)| sum + val * b[i] }; end end # --- 2. CG Solver --- def self.cg_solve(matrix, b, x0, max_iter, tol) x = x0.dup r = VectorMath.sub(b, matrix.dot(x)) p = r.dup rsold = VectorMath.dot(r, r) max_iter.times do ap = matrix.dot(p) p_ap = VectorMath.dot(p, ap) break if p_ap.abs < 1e-15 alpha = rsold / p_ap x = VectorMath.add(x, VectorMath.scale(p, alpha)) r = VectorMath.sub(r, VectorMath.scale(ap, alpha)) rsnew = VectorMath.dot(r, r) break if Math.sqrt(rsnew) < tol p = VectorMath.add(r, VectorMath.scale(p, rsnew / rsold)) rsold = rsnew end return x end # --- 3. Helper: Check if Material is RED --- def self.is_red?(entity) return false unless entity.material c = entity.material.color # Check for Pure Red (255, 0, 0) or close to it return true if c.red > 200 && c.green < 50 && c.blue < 50 return false end # --- 4. Main Process --- def self.process_mesh(selection_mesh, density_input, load_input, scale_factor, iterations) model = Sketchup.active_model entities = model.active_entities # A. Topology Extraction verts = [] v_to_id = {} faces = selection_mesh.grep(Sketchup::Face) if faces.empty? UI.messagebox("Please select a Mesh (Faces) first.") return end faces.each do |f| f.vertices.each do |v| unless v_to_id.key?(v.entityID) v_to_id[v.entityID] = verts.length verts << v end end end n = verts.length # B. Explicit Anchor Detection (THE "RED" RULE ONLY) anchors = [] # Check 1: Red Faces faces.each { |f| anchors.concat(f.vertices.map { |v| v_to_id[v.entityID] }) if is_red?(f) } # Check 2: Red Edges edges = faces.map { |f| f.edges }.flatten.uniq edges.each do |e| if is_red?(e) anchors << v_to_id[e.start.entityID] anchors << v_to_id[e.end.entityID] end end anchors = anchors.uniq if anchors.empty? UI.messagebox("Error: No RED anchors found! The mesh will float freely.\nPlease paint at least one edge or face RED.") return end # C. Index Mapping free_map = [] global_to_free = {} free_count = 0 (0...n).each do |i| unless anchors.include?(i) free_map << i global_to_free[i] = free_count free_count += 1 end end n_free = free_map.length if n_free == 0 UI.messagebox("Error: All selected vertices are anchors. Nothing to calculate.") return end # D. Build Edges Index edges_idx = edges.map do |e| id1 = v_to_id[e.start.entityID] id2 = v_to_id[e.end.entityID] [id1, id2] if id1 && id2 end.compact # E. TNA Setup & Matrix Assembly q_val = density_input l_ff = SparseMatrix.new(n_free) d = Array.new(n, 0.0) # Build Laplacian (L_ff) and Diagonal (d) edges_idx.each do |u, v| w = q_val d[u] += w d[v] += w u_free = !anchors.include?(u) v_free = !anchors.include?(v) if u_free && v_free uf, vf = global_to_free[u], global_to_free[v] l_ff.add(uf, vf, -w) l_ff.add(vf, uf, -w) end end free_map.each { |i_glob| l_ff.add(global_to_free[i_glob], global_to_free[i_glob], d[i_glob]) } # F. Vertical Equilibrium (Solve for Final Z: Z_f) # Initial Z-positions of free nodes (used as the initial guess and for calculating Delta Z later) z_orig_free = Array.new(n_free) free_map.each_with_index { |glob_idx, i| z_orig_free[i] = verts[glob_idx].position.z } z_current = z_orig_free.dup # Iterative Solve for Z_f iterations.times do rhs = Array.new(n_free, -load_input) # -Pf edges_idx.each do |u, v| w = q_val u_free = !anchors.include?(u) v_free = !anchors.include?(v) # Contribution of fixed anchors to the RHS (-Lfa * Za) if u_free && !v_free rhs[global_to_free[u]] += w * verts[v].position.z elsif !u_free && v_free rhs[global_to_free[v]] += w * verts[u].position.z end end z_current = cg_solve(l_ff, rhs, z_current, 200, 1e-5) end # G. Calculate and Apply Displacement (Delta Z) # Delta Z = Z_final - Z_original. This is the displacement vector. # It will be negative for a hanging form (since Z_f < Z_orig_f). delta_z = VectorMath.sub(z_current, z_orig_free) model.start_operation("Generate Vault", true) group = entities.add_group mesh_out = Geom::PolygonMesh.new final_pts = [] # Use the sign of the scale factor to determine the flip # scale_factor = -5.0 means: flip the negative displacement (to positive) and scale by 5.0 scale = scale_factor (0...n).each do |i| v_orig = verts[i].position if anchors.include?(i) final_pts << v_orig # Anchors stay at their original Z else dz_calc = delta_z[global_to_free[i]] # Z_final = Z_original + (Delta Z * Scale) # If Delta Z is negative (hanging form) and Scale is negative (-5.0), # the result is positive displacement, creating the arch/vault. z_final = v_orig.z + (dz_calc * scale) final_pts << [v_orig.x, v_orig.y, z_final] end end # Reconstruct faces faces.each do |f| idxs = f.vertices.map { |v| v_to_id[v.entityID] } mesh_out.add_polygon(idxs.map { |k| final_pts[k] }) end group.entities.add_faces_from_mesh(mesh_out) group.name = "Vault_Result" group.material = "White" group.entities.grep(Sketchup::Edge).each { |e| e.soft = true; e.smooth = true } model.commit_operation end # --- 5. UI Dialog --- def self.show_dialog prompts = ["Force Density (Stiffness)", "Load", "Height Scale (Multiplier)", "Iterations"] # Default Scale set to 5.0, as requested. defaults = [1.0, 1.0, 5.0, 30] input = UI.inputbox(prompts, defaults, "TNA Settings") return unless input sel = Sketchup.active_model.selection self.process_mesh(sel, input[0], input[1], input[2], input[3]) end unless file_loaded?(__FILE__) menu = UI.menu('Plugins') menu.add_item('Create Vault (TNA)') { self.show_dialog } file_loaded(__FILE__) end end




