I’m wondering what are possible use cases for the creation of new boundary boxes via the Ruby API (boundingbox = Geom::BoundingBox.new). As far as I can see, it’s not possible to associate this newly created boundingbox later on to a drawingelement?
It’s only possible to retrieve the bounds of drawingelements, based on their geometry. I can see no mechanism to set the bounds of a drawingelement. So: what’s the purpose of the possibility to create a new boundingbox?
One instance where this is required is from Sketchup::Tool.getExtents
In order to accurately draw things, SketchUp needs to know the extents of what it is drawing. If the tool is doing its own drawing, it may need to implement this method to tell SketchUp the extents of what it will be drawing. If you don’t implement this method, you may find that part of what the tool is drawing gets clipped to the extents of the rest of the model.
Thanks for reply.
I had hoped it could be used to define ‘text boundaries’ for multi-line auto-wrapped text (left/center/right aligned) when creating 3D-Text via the Ruby API. But this seems not possible. Multi-line text is possible via the API, but it’s required to insert the newline (“\n” character) explicitly via code at specific text string positions. This may become quickly quite complex…
If it would be possible to have auto-wrapping (based on the bounding box), this would be much simpler.
Not true. You can add other bounding boxes, arrays or lists of points and vertices to another bounding box object.
# Add the bounds of existing drawingelement:
bbox = Geom::BoundingBox.new
obj = model.entities.first
bbox.add(obj.bounds)
# Add the vertices of existing drawingelement:
bbox = Geom::BoundingBox.new
obj = model.entities.first
bbox.add(obj.vertices) if object.respond_to?(:vertices)
You are not supposed to, as you know, the bounds encompass the object’s geometry.
Bounding boxes are virtual helper objects used by extension code. There can be many uses in addition to tool implementations.
One possibility would be to calculate the gross volume or footprint taken up by multiple geometric model objects.
Another might be to calculate the intersection between two bounding boxes.
Yes it can be complex, but write a method to do it and then reuse it whenever it is needed.
I know you want 3D text, but just as an example, 2D screen text can let the API’s view object calculate text bounds.
The Gemini AI suggested this:
def autowrap_3d_text(
text_string, font_name, text_height_in_inches, max_width_in_inches
)
# A. REQUIRED EMPIRICAL CONSTANT
# ----------------------------------------------------------------------
# This is the most critical part. You must determine the average ratio
# of a character's width to its height (ACWHR) for your chosen font
# at a typical height in SketchUp. This value is font-specific.
#
# A common, though rough, ratio for many proportional fonts is ~0.55 to ~0.7.
# Monospace fonts (like Courier) are often closer to 0.6.
# For this example, a conservative estimate of 0.6 is used.
ACWHR = 0.60
# ----------------------------------------------------------------------
# B. Calculate the maximum number of characters per line (CPL)
char_width = text_height_in_inches * ACWHR
max_cpl = (max_width_in_inches / char_width).floor
# Edge case: If the max_cpl is less than 1, you can't wrap a single character.
return text_string if max_cpl < 1
# C. Process the text to insert newlines ("\n")
wrapped_text = ""
current_line = ""
# Split the text by spaces to process word by word
words = text_string.split(/\s+/)
words.each do |word|
# Check if the current line + a space + the new word fits
if current_line.length + 1 + word.length <= max_cpl
# Add word to the current line
current_line += (current_line.empty? ? "" : " ") + word
else
# Line is full, start a new line
wrapped_text += current_line + "\n" unless current_line.empty?
current_line = word
end
end
# D. Add the final line
wrapped_text += current_line unless current_line.empty?
# E. Call the SketchUp API method (for reference, this is where it would be used)
# --------------------------------------------------------------------------------
# model = Sketchup.active_model
# entities = model.active_entities
#
# # Example placement (adjust as needed)
# pt = Geom::Point3d.new(0, 0, 0)
#
# text_entity = entities.add_3d_text(
# wrapped_text, # The wrapped string
# TextAlignLeft, # Alignment (e.g., left)
# pt, # Insertion point
# font_name, # Font name
# text_height_in_inches, # Text height
# true, # Extrude (makes it 3D)
# 0.0 # Extrusion distance (none here)
# )
# --------------------------------------------------------------------------------
return wrapped_text
end
# Example Usage:
# text_input = "The quick brown fox jumps over the lazy dog a total of twenty-five times."
# font_used = "Arial"
# height = 0.5 # inches
# width = 4.0 # inches
#
# result = autowrap_3d_text(text_input, font_used, height, width)
# puts result
#
# # Expected output (assuming ACWHR = 0.60):
# # Max CPL = floor(4.0 / (0.5 * 0.60)) = floor(13.33) = 13
# #
# # The quick bro
# # wn fox jumps
# # over the lazy
# # dog a total
# # of twenty-fi
# # ve times.
The main problem I see with this snippet is that it breaks words.
It would need to likely employ a regular expression to only break on whitespace.