Thursday, March 12, 2009

Deleting Unnecessary Edges



Have you ever opened a SketchUp file that you didn’t create, or imported a model from another application, and found that it has hundreds of needless hidden or softened lines separating coplanar faces? Wish you could get rid of them with a simple ruby script? Now you can!

First, set up a few variables:

def variables
@group_list = []
@component_list = []
@delete_these = []
@model_list = Sketchup.active_model.entities
end

Then write a method that determines if an edge is 1) hidden or softened, and 2) bordered by two co-planar faces. If the edge meets each of those requirements, it is added to @delete_these list.

def delete_soft_lines(e)
# Determine if the edge is soft or hidden, and if it is bordered by
# two faces.

if ((e.soft? and e.faces.size == 2) or (e.hidden? and e.faces.size == 2))
# Determine if the two bordering faces are coplanar.
# Note: This will only catch cases where the front faces are pointing
# in the same direction.

if (e.faces[0].normal.dot(e.faces[1].normal) > 0.999999999)
# Add the edge to the list of entities that will be deleted.
@delete_these.push(e)
end
end
end

Now create a method to find all the edges in the model, including edges that are embedded in groups and components:

def traverse_model_entities
# @model_list will not be empty until all of the groups, components
# and edges have been traversed.

while @model_list != []
@model_list.each do |item|
# Determine if the entity is an edge, group, or component.
type = item.typename
case type
when "Edge"
# Determine if the edge should be deleted, and add it to the
# @delete_these list.

delete_soft_lines(item)
when "Group"
# Add each of the entities in the group into the group_list
# array.

item.entities.each do |entity|
@group_list.push entity
end
when "ComponentInstance"
# .entities can be called on a Component Definition, but not on
# a Component Instance.
# Use the .definition method to access the Component Definition
# that the instance belongs to.

item.definition.entities.each do |entity|
# Add each of the entities in the component into the
# component_list array.

@component_list.push entity
end
end
end
# Update the @model_list so it contains only the entities that were
# embedded in groups or components. These entities haven't been
# counted yet.

@model_list = @group_list + @component_list
# Clear out the group and component lists so they're ready for the
# next level of sub-groups/components.

@group_list = []
@component_list =[]
end
# The edges that need to be deleted have all been added to the
# @delete_these list, so erase those entities from the
# active SketchUp model.

Sketchup.active_model.entities.erase_entities(@delete_these)
end


Finally, add a “Delete unnecessary edges” item to Tools menu, and pop a dialog letting you know the edges were deleted:
def delete_edges
variables
traverse_model_entities
UI.messagebox("Edges deleted.")
end

UI.menu("Tools").add_item("Delete unnecessary edges") {delete_edges}

4 comments:

Thomas Thomassen said...

The problem is that is some times causes faces to disappear as well.

For instance, draw a few rectangles that criss-cross over each other, then hide/soften the inner edges. If you run the script on these entities you end up loosing the faces.

Simone (snicolo) said...
This comment has been removed by the author.
Simone (snicolo) said...

Blogger Simone (snicolo) said...

This might be a precision issue, you can try changing the following statement
if (e.faces[0].normal.dot(e.faces[1].normal) > 0.999999999)
to
if (e.faces[0].normal.dot(e.faces[1].normal) > 0.999999999999999999)

this might fix it.

There might also be a bug somewhere, if this does not work I will investigate more.
thanks.
Simone.

Jim Foltz said...

This post may be related:

http://www.sketchucation.com/forums/scf/viewtopic.php?f=180&t=10599&st=0&sk=t&sd=a&start=15#p71314