Hello, I’m developing a plugin and I need a way to round corners. I know there’s a round corner plugin that already does this, I wanted to include it in a simpler way without the user having to purchase round corner, which is very robust and goes beyond what I need. I would appreciate it if someone could guide me in a ruby logic to implement for rounding corners.
You need to be a little more specific about what you want, but don’t expect someone to do it for you. Usually, we can help you here if you are posting some code that you’ve written.
You should also talk about your familiarity with Ruby and the Sketchup Ruby API.
This is an “infinitely” simplified quick code concept (It performs no checks, it just assumes a certain situation…), so that only works in special cases, like this.
def round_corner( radius = 5.mm )
model = Sketchup.active_model
entities = model.active_entities
selection = model.selection
edge = selection.first
face1, face2 = edge.faces
f1_vec = face1.normal.reverse
f2_vec = face2.normal.reverse
angle = f1_vec.angle_between(f2_vec)
pt0 = edge.start.position
pt1 = pt0.offset(f1_vec, radius)
pt2 = pt0.offset(f2_vec, radius)
line1 = [ pt1, f2_vec ]
line2 = [ pt2, f1_vec ]
center = Geom.intersect_line_line(line1, line2)
xaxis = face1.normal
model.start_operation("Round Corner", true)
arc_edges = entities.add_arc(center, xaxis, edge.line[1], radius, 0, angle)
arc_pts = arc_edges.first.curve.vertices.map(&:position)
face_round = entities.add_face(arc_pts<<pt0)
face_round.followme(edge)
model.commit_operation
end
round_corner
I don’t have any code written yet because I’m still very new to Ruby. The code I’ve tried to write doesn’t even come close to what I need. That’s why I haven’t uploaded any code yet.
What I need is something like rounding a corner on a 2D plane, like I show in the video. Rounding the corners and being able to adjust the angle and radius of the rounding, either inward or outward.
Explore the native arc tools.
Well, eider you gave us a wrong video, or you have other meaning of round corner, I do not see any of corner rounded on your animation. What I see you draw a circle using one of the side edge of a rectangle as diameter and deleted the half of the circle as well as the face.
The roundcorner extension mentioned in your first post has nothing to do with this. (Unless, again, you’re talking about something else.)
I concluded that you are not familiar with the Ruby API, but also with Sketchup itself. Like @DanRathbun suggested, explore the usage of SketchUp native tools first, then, when you know it well, you can start to think about programming.
__
You do not need to quote my code right after my post, especially if you are not using or not altered it…
Edit:
Perhaps this is what you need ?!?
https://extensions.sketchup.com/extension/4b1cbca1-5af7-41db-baa0-eb1f6b69ae40/radius-tool
Those error messages are because variable names in Ruby start with lower case letters. Starting with a capital letter indicates a constant. This is Ruby 101.
Sorry to quote your code, I’m still new to the forum and I don’t know how the rules work here. I want to clarify that my goal is not just to round corners, but to work with sides. For example, if I have a straight line and I want to keep the two endpoints intact, but insert intermediate segments that curve the line - so that, if I select two edges in a 2D plane, the script rounds the common vertex, and if I select only one edge, it is curved (where a negative radius value curves ‘inwards’ and a positive value ‘outwards’).
Below is an example of a script that tries to integrate both functionalities:
def round_corner(radius = 5.mm, segments = 12)
model = Sketchup.active_model
entities = model.active_entities
selection = model.selection
if selection.empty?
UI.messagebox("Selecione uma ou duas arestas (em plano 2D).")
return
end
# Caso 1: Duas arestas selecionadas – arredondar o vértice comum
if selection.size == 2 && selection.all? { |e| e.is_a?(Sketchup::Edge) }
edge1, edge2 = selection.to_a
# Procura o vértice comum entre as arestas
common_point = [edge1.start.position, edge1.end.position].find do |pt|
[edge2.start.position, edge2.end.position].include?(pt)
end
unless common_point
UI.messagebox("As arestas selecionadas não compartilham um vértice comum.")
return
end
# Determina os pontos opostos ao vértice comum
pt1 = (edge1.start.position == common_point) ? edge1.end.position : edge1.start.position
pt2 = (edge2.start.position == common_point) ? edge2.end.position : edge2.start.position
vec1 = (pt1 - common_point).normalize
vec2 = (pt2 - common_point).normalize
angle = vec1.angle_between(vec2)
if angle == 0 || angle >= Math::PI
UI.messagebox("Ângulo inválido para arredondamento.")
return
end
# Calcula o deslocamento ao longo de cada aresta
offset = radius / Math.tan(angle / 2.0)
new_pt1 = common_point.offset(vec1, offset)
new_pt2 = common_point.offset(vec2, offset)
# Calcula o centro do arco utilizando a bissetriz
bisector = (vec1 + vec2).normalize
d = radius / Math.sin(angle / 2.0)
arc_center = common_point.offset(bisector, d)
start_vector = (new_pt1 - arc_center).normalize
arc_edges = entities.add_arc(arc_center, start_vector, vec1.cross(vec2).normalize, radius.abs, 0, angle, segments)
if arc_edges.empty?
UI.messagebox("Não foi possível criar o arco para arredondar o vértice.")
return
end
UI.messagebox("Arredondamento do vértice concluído!")
return
# Caso 2: Apenas uma aresta selecionada – encurvar a reta mantendo os pontos finais
elsif selection.size == 1 && selection.first.is_a?(Sketchup::Edge)
edge = selection.first
a = edge.start.position
b = edge.end.position
l = a.distance(b)
if l == 0
UI.messagebox("A aresta possui comprimento zero.")
return
end
if (l / 2.0) > radius.abs
UI.messagebox("Valor de raio insuficiente para curvar a aresta.")
return
end
d = (b - a).normalize
# Define o vetor perpendicular no plano; usa-se Z_AXIS para um plano 2D (XY)
perp = Z_AXIS.cross(d).normalize
# Se o valor do raio for negativo, inverte o sentido da curva
perp = (radius < 0) ? -perp : perp
m = Geom.linear_combination(0.5, a, 0.5, b)
h = Math.sqrt(radius.abs**2 - (l / 2.0)**2)
arc_center = m.offset(perp, h)
start_vector = (a - arc_center).normalize
arc_angle = (a - arc_center).angle_between(b - arc_center)
arc_edges = entities.add_arc(arc_center, start_vector, Z_AXIS, radius.abs, 0, arc_angle, segments)
if arc_edges.empty?
UI.messagebox("Não foi possível criar a curva na aresta.")
return
end
# Remove a aresta original, se desejar que apenas a curva permaneça
edge.erase!
UI.messagebox("Curvatura da aresta concluída!")
return
else
UI.messagebox("Selecione uma ou duas arestas (em plano 2D).")
return
end
end
round_corner