Su 2023 script - height tag for every vertex in active context - overlay used - performance issues

hi there,

for a running project in our office, where we need to make a surface drainage plan for a large area with lots of constraints, we are now using sketchup instead of our normal cad solution :slight_smile: what is good in many ways because, for example, there are already lots of plugins that help for example colorize the slope and altitude etc…

but one thing was missing, a dynamic “height tag” for all vertices

so i have, with the help of chat gpt, made a small ruby script that implements a overlay, which once activated, looks for all active entities in the context and then iterates through all vertices and draws on screen the height of each individual vert over model 0.00 …

so far so good - but the plugin is pretty heavy on the performance.

so i am wondering if it can be optimised or fi there is a better way to accomplish this goal…

before messing with my own code, i was trying to play with the height by datum plugin but there is a problem that the text tags loose interactivity when they are not in the same context as the “entities” plus some other problems like not being able to automaticly “tag” all vertices at once etc…

also i was looking into tak2hatas really great draw slope on face…
its great, performs great, does what is needed, but - there are also 2 features missing for making it perfect …
1 - select if both height and slope should be drawn, or only slope,
2 - slope in % not as fractal :slight_smile:

anyway - i would be super happy if someone could help me develope this plugin to have better performance and maybe even bring it so far as to being able to publish it in the extension store for free

i think the idea is quite handy for landscaping :slight_smile: + there are several featues that could be incrementally added …

here is my script for you to play with

class HeightOverlay < Sketchup::Overlay
def initialize
description = “draw height over model zero zero on screen as overlay for each vertice in the active model context”
super(‘unique_identifier_for_your_overlay’, ‘dyn. height tags for vertices’, description: description)
@height_cache = {} # Cache initialisieren
end

def draw(view)
model = Sketchup.active_model
active_entities = model.active_entities
active_entities.grep(Sketchup::Edge).each do |edge|
edge.vertices.each do |vertex|
unless @height_cache[vertex]
height = vertex.position.z.to_l.to_s
@height_cache[vertex] = height
end
screen_pos = view.screen_coords(vertex.position)
draw_text_with_size(view, screen_pos, @height_cache[vertex], size: 16)
end
end
end

private

def draw_text_with_size(view, position, text, size: 14)
view.draw_text(position, text, size: size)
end

class ExampleAppObserver < Sketchup::AppObserver
def expectsStartupModelNotifications
true
end

def register_overlay(model)
overlay = HeightOverlay.new
model.overlays.add(overlay)
end

alias_method :onNewModel, :register_overlay
alias_method :onOpenModel, :register_overlay
end

observer = ExampleAppObserver.new
Sketchup.add_observer(observer)
end

I think you should at least include “your” code in a more readable way, according to the coding conventions.
As an example here is a screenshot of what ChatGTP came up with as an answer to my question about heights of vertices. (I haven’t read it yet but that isn’t the point. You can read at least it)

User

You

Write a ruby script for SketchUp that iterates trough the entire active model entity and find the Z (= height) value for each vertex. And write that as text near these vertices.

ChatGPT

ChatGPT

To achieve this in SketchUp using Ruby, you can create a script that iterates …


ChatGPT does not follow correct coding etiquette for a shared Ruby environment.

All of your various codings should be within an unique top level namespace module. Each one of your “plugins” (aka extensions) should be within a submodule of your namespace module.

Ie, it is not proper to be defining classes globally. They should be defined within the extension’s submodule.


Oh yes. Definitely. Unnecessary method calls and assignments take time.

Also, the overlay class documentation warns us to not do heavy calculation within it’s draw() method.
Your code repeatedly recalculates the entire cache in each draw cycle. This really is not the general purpose of a cache mechanism.

Another thing was that you were treating the vertices twice (or more). I called #uniq! upon the vertex array so this would not happen (ie, each vertex handled once during the iteration.) I also skipped vertices whose #z was not > 0.

Try this … it will be version 1.0.0, but it does not yet have observers to update the cache when changes are made to the vertices of the geometry within context. It does separate the cache manipulation from the draw cycles.

You’ll need to control the cache via the extension submenu commands (see bottom of file).

BsFranza_VertexHeightOverlay_1.0.0.rbz (2.7 KB) — See revised edition below (next post)


P.S. - I’ll be on jury duty starting tomorrow so I may be offline for a few days, minimum.

And here is the first second revision already.

Added a method to update the cache values when the precision is changed in the options dialog.
Then revised again to invalidate the model view when precision is changed.

BsFranza_VertexHeightOverlay_1.0.2.rbz (2.8 KB)

2 Likes

Notice how I changed it to use Sketchup::format_length so that the markers display in the User’s model units ?