How to delete a break point of an edge in a face?

Dear Friends, we have a line in a face that break to 2 lines by unwanted point. How can we find this point and delete it?

Please show an image, with code to reference the various objects.

face before pushpull


face after pushpull

You can see unwanted lines. I wish to solve face problem before pushpull. After pushpull following codes solve this problem.

f_grp.entities.grep(Sketchup::Edge) do |e|
  e.erase! if e.faces.first.normal == e.faces.last.normal
end 

This begs the question of how that edge got broken in the first place. If a user did that via the GUI or if it was imported from somewhere, so be it. But this topic is in the Ruby API category, so if it was created using the API, why was it done as 6 pieces rather than one edge? Was there intent to create notches there like in the other edges but chose not to?

My point is that it is often easier to avoid a problem in the first place than to fix it later.

1 Like
2 Likes

For example:
https://bitbucket.org/thomthom/tt-library-2/src/a353ba3dafefe0e2b487b13bea057f97ad185f7b/TT_Lib2/edges.rb#lines-147

__

The
Sketchup::Entities#weld

maybe “visually” will make what you want, but still there will be a same amount of edges “soften inside” a curve. :wink:
However the puspull will give you a “better” result.

1 Like

Unfortunately I cannot avoid it. This problem can come from users of plugin and I cannot limit them.

After pushpull I check all edges and check faces normal of edge. if 2 normal are same I delete edge. Can we do same for face? For example angle of 2 edges are same and edges have common vertex, delete vertex. I can think about some other solution for example pushpull face, delete edges that have same faces normal (as show is codes) then delete faces that added by pushpull but I don’t like this solution.

The vertex can not be deleted. It is not a drawing element like edge or face, but an “abstract” thing.
Just read the linked above example from TomTom:
“To repair a broken edge a temporary edge is placed at their shared vertex. This temporary edge is then later erased which causes the two edges to merge.”

And again, if you weld the edges as Dan suggested, the pushpull will not create the extra edges on a faces.
Your choice!

2 Likes

Just delete all edges that are common between 2 coplanar faces.

model = Sketchup.active_model
entities = model.entities # or maybe the entities instance of a definition...
edges_to_delete = []
entities.each do |edge|
  next if edge.class != Sketchup::Edge
  common_faces = edge.faces
  next if common_faces.length != 2
  next if false == common_faces[0].normal.parallel?(common_faces[1].normal)
  edges_to_delete << edge
end #do

entities.erase_entities(edges_to_delete)

This will also clean up your average import. But, on some models, the new face will not be detected, and thus result in broken geometry…

1 Like

as can be seen here…

And… now I see TS already did this.

1 Like

Quick code snippets
If you just what to avoid unwanted lines:
make_face_soft(my_face)

If you jusst want to remove the brake points:
remove_collinear_vertices(myface, false)

If you want to remove the brake points and make the puspull “soft”:
remove_collinear_vertices(myface)


def make_face_soft(face)
  return unless ( face.is_a?(Sketchup::Face) && face.valid? )
  parent = face.parent.entities
  new_curve = parent.weld(face.edges)
end

def remove_collinear_vertices(face, soften = true)
  return unless ( face.is_a?(Sketchup::Face) && face.valid? )
  #if the face edges are part of curve
  # the below method will fail
  # explode it ( ToDo: add condition)
  face.edges.each{|e| e.explode_curve}
  parent = face.parent.entities
  face.vertices.each{|vertex|
    # To repair a broken edge a temporary edge is placed at their shared vertex.
    # This temporary edge is then later erased which causes the two edges to
    # merge.
    pt1 = vertex.position
    pt2 = pt1.clone
    pt2.x += rand(1000) / 100.0
    pt2.y += rand(1000) / 100.0
    pt2.z += rand(1000) / 100.0
    temp_edge = parent.add_line( pt1, pt2 )
    temp_edge.erase! unless temp_edge.nil?
  }
  new_curve = parent.weld(face.edges) if soften
end

1 Like

As you can see by the example in post 3, the Enumerable#grep method is itself a block form method and much cleaner (more redable) …

entities.grep(Sketchup::Edge) do |edge|
1 Like

But won’t this iterate twice ? :wink:

Edit: I guess not.

Edit2: never used grep myself. I see it as a great replacement for select followed by map in one, but only is able to filter on classes, regex expressions and numbers. I often filter on :respond_to? for example. Regarding it being cleaner or more readable I follow you that it is a clean Ruby way, but just another thing to remember when switching languages often.

I will use it next time I see an opportunity. Thanks for the heads up @DanRathbun

1 Like

Yes it is incredibly fast as a class identity filter.

1 Like