I’m trying to create a script to apply offset to 2D shapes of undefined shape. I created a script in ruby that “fakes” the offset, and is also limited to square and rectangular shapes.
model = Sketchup.active_model
model.start_operation("Inner Offset + Remove Outer Border", true)
selection = model.selection
group = selection[0]
unless group.is_a?(Sketchup::Group)
UI.messagebox("Please select the group that contains the face before running the script.")
model.abort_operation
return
end
entities = group.entities
# Assume there is only one face in the group
face = entities.grep(Sketchup::Face).first
unless face
UI.messagebox("No face found inside the group.")
model.abort_operation
return
end
# Define the offset distance (50 cm, for example)
offset_distance = 50.cm
# Identify the outer and inner loops
outer_loop = face.loops.find(&:outer?)
inner_loop = face.loops.find { |loop| !loop.outer? }
unless inner_loop
UI.messagebox("Inner loop (hole) not found.")
model.abort_operation
return
end
# Get the vertices (points) of the inner loop
inner_points = inner_loop.vertices.map(&:position)
# Compute the bounding box of these points to expand by 50 cm
bbox = Geom::BoundingBox.new
inner_points.each { |pt| bbox.add(pt) }
min_x = bbox.min.x - offset_distance
min_y = bbox.min.y - offset_distance
max_x = bbox.max.x + offset_distance
max_y = bbox.max.y + offset_distance
z_plane = bbox.min.z # Assuming all points lie in the same Z plane
# Construct the 4 points of a new, larger rectangle based on the bounding box
outer_points = [
[min_x, min_y, z_plane],
[max_x, min_y, z_plane],
[max_x, max_y, z_plane],
[min_x, max_y, z_plane]
]
# Store the edges of the outer loop for later removal
outer_edges = outer_loop.edges
# Erase the original face
face.erase!
# Remove the original outer loop edges
outer_edges.each do |edge|
edge.erase! if edge.valid?
end
# Create the new outer face (larger) and the inner face (hole)
new_face = entities.add_face(outer_points)
hole_face = entities.add_face(inner_points)
# If the inner face was created successfully, erase it to leave the "hole"
hole_face.erase! if hole_face.valid?
model.commit_operation
I’ll leave two videos trying to better explain what I need. One shows the functionality of my script and the other shows what I want to optimize with the script.
Problem Description:
I have a flat face that contains an internal hole (an internal loop) and does not have a defined shape – it could be an irregular polygon, a circle, a triangle, etc. What I want to do is apply an offset from the internal hole, so that all the edges that form this hole are displaced outwards by 50 centimeters to the outer edges. In other words, I want to create a new external edge that is 50 cm away from the internal hole, removing the original external edge of the face.
My idea for solving this problem is:
1. Geometry Selection and Validation:
- Select the group that contains the face with the hole.
- Verify that the group actually contains a face and that this face has at least one internal loop (the hole).
2. Identify the Loops:
- Identify the external loop (the original edge of the face) and the internal loop (the outline of the hole).
- Confirm that the internal loop is present, as it will be the basis for the offset.
3. Offset Calculation:
- From the inner loop, extract the vertices (points) that form the outline of the hole.
- Calculate a new set of points that represent a polygon offset outwards by 50 centimeters from the hole.
- This process should work for any face shape, even if it is irregular (not just based on a bounding box for rectangles, but applying an offset algorithm for polygons).
4.Removing the Original Geometry:
- After generating the new set of offset points, delete the original face and remove the edges of the outer loop (the original edge of the face).
5. Rebuilding the New Face:
- Create a new face using the points of the offset polygon as the new outer edge.
- Recreate the inner hole (using the original points of the hole) on the new face, so that SketchUp understands that this area should remain empty.
- If an internal face is automatically created, erase it to leave only the edges that define the hole.
6. End Goal:
- Expected Result: Have a new face that has an external edge offset 50 cm outward from the internal hole contour, removing the original external edge.
This operation should be valid for faces with undefined shapes, that is, it will work for any polygon, circle, triangle or irregular shape that contains an internal hole.