I am working on a method to calculate the area of the projection of a group or component (in this example, only for the selected elements), and I have written this method for that purpose. test caras.skp (205.9 KB)
# Selection footprint
def drop_faces_to_zero(faces)
model = Sketchup.active_model
entities = model.active_entities
# Group as a container
common_group = entities.add_group
common_group_entities = common_group.entities
faces.each_with_index do |face, index|
# groups for each face
individual_group = common_group_entities.add_group
begin
# outer loop vertex z to 0
outer_loop_vertices = face.outer_loop.vertices.map do |vertex|
position = vertex.position
Geom::Point3d.new(position.x, position.y, 0.0) # Forzar Z a 0
end
# outer loop face
new_face = individual_group.entities.add_face(outer_loop_vertices)
if new_face.nil?
individual_group.erase!
next
end
# Inner lop faces substraction
face.loops.each do |loop|
next if loop == face.outer_loop # avoid outer loop
# inner loop vertex z to 0
inner_loop_points = loop.vertices.map do |vertex|
position = vertex.position
Geom::Point3d.new(position.x, position.y, 0.0) # Forzar Z a 0
end
# inner loop faces
inner_face = individual_group.entities.add_face(inner_loop_points)
if inner_face
# delete face and maintain edges
inner_face.erase!
end
end
rescue StandardError => e
puts "Error not able to generate faces in group"
individual_group.erase!
end
end
# Explode individual groups inside common group
common_group_entities.grep(Sketchup::Group).each do |group|
group.explode
end
# Select interior edges in order to delete them.
model.selection.clear
common_group_entities.grep(Sketchup::Edge).each do |edge|
if edge.faces.length == 2
model.selection.add(edge)
end
end
end
model = Sketchup.active_model
selection = model.selection
selected_faces = selection.grep(Sketchup::Face)
if selected_faces.empty?
UI.messagebox("Please select almost one face")
else
drop_faces_to_zero(selected_faces)
end
The goal is to delete the interior edges, but in the test I conducted, overlapping faces are generated, and some exterior edges seem to belong to two faces.
How can I avoid this? I’ve noticed that if I select everything and perform an intersection of the selection with itself, the problem is solved. Does such a method exist?
Sorry for the bad lead. I thought that break_edges was the source of problem but I see now that the order in which the faces are selected changes the result of the operation.
The two overlapping faces would best be kept inside a group.
Overlap them as you wish…
Then use the Class: Sketchup::Entities — SketchUp Ruby API Documentation as explained by @dezmo - to ‘merge’ their faces and edges.
It’s the most convoluted method around but is capable of doing what you want…
After the ‘merging’ you might then wish to remove any coplanar edges that result between two created faces - tip: collect all of the available edges and check in turn if they support two or more faces - if so, then keep a record of them, and at the end delete those edges… Now you have a combination of the two original faces with any unwanted edges removed…
Merge faces as @dezmo said was successful. I could obtain the footprin face required to obtain the area and outer perimeter.
This is the final script.
# Selection footprint area and perimeter
def drop_faces_to_zero(faces)
model = Sketchup.active_model
entities = model.active_entities
# Group as a container
common_group = entities.add_group
common_group_entities = common_group.entities
faces.each_with_index do |face, index|
# groups for each face
individual_group = common_group_entities.add_group
begin
# outer loop vertex z to 0
outer_loop_vertices = face.outer_loop.vertices.map do |vertex|
position = vertex.position
Geom::Point3d.new(position.x, position.y, 0.0) # Forzar Z a 0
end
# outer loop face
new_face = individual_group.entities.add_face(outer_loop_vertices)
if new_face.nil?
individual_group.erase!
next
end
# Inner lop faces substraction
face.loops.each do |loop|
next if loop == face.outer_loop # avoid outer loop
# inner loop vertex z to 0
inner_loop_points = loop.vertices.map do |vertex|
position = vertex.position
Geom::Point3d.new(position.x, position.y, 0.0) # Forzar Z a 0
end
# inner loop faces
inner_face = individual_group.entities.add_face(inner_loop_points)
if inner_face
# delete face and maintain edges
inner_face.erase!
end
end
rescue StandardError => e
puts "Error not able to generate faces in group"
individual_group.erase!
end
end
# Explode individual groups inside common group
common_group_entities.grep(Sketchup::Group).each do |group|
group.explode
end
#intersec with selection
model = Sketchup.active_model
# temporary group
temp_group = common_group_entities
temp_group.intersect_with(
false, # avoid hiden geometry
Geom::Transformation.new, # entities transformation
temp_group, # target entities
Geom::Transformation.new, # result transformation
true, # all tags
temp_group.to_a # entities to intersect
)
#delete useless edges
temp_group.grep(Sketchup::Edge).each do |edge|
next if edge.deleted?
if edge.faces.length == 2
edge.erase!
end
end
temp_group.grep(Sketchup::Edge).each do |edge|
next if edge.deleted?
if edge.faces.length == 0
edge.erase!
end
end
#Resulted area and outer perimeter
puts "Footprint Area " + Sketchup.format_area(temp_group.grep(Sketchup::Face).first.area)
perimeter = 0
temp_group.grep(Sketchup::Face).first.outer_loop.edges.each do |e|
perimeter += e.length
end
puts "Footprint Outer Perimter" + Sketchup.format_length(perimeter)
model = Sketchup.active_model
entities = model.active_entities
entities.erase_entities(temp_group.to_a)
end
model = Sketchup.active_model
selection = model.selection
selected_faces = selection.grep(Sketchup::Face)
if selected_faces.empty?
UI.messagebox("Please select almost one face")
else
drop_faces_to_zero(selected_faces)
end