Duplicate persistent id not fixed by 'Fix Problems' in Sketchup 2017

The attached file is a simplified version of a large model. It contains two faces which have same persistent id. Usually duplicate ids are fixed when doing’ Fix Problems’. We save the ids with the model or on file and rely on these to get the faces back using Ruby api. In this case, it is impossible to get one of the face as Sketchup.active_model.find_entity_by_persistent_id always returns the same face. The issue occurs on Sketchup 2017 and the issue was raised by one of plugin user. It happened after some objects are copied from another Sketchup model.

My questions are

  1. Why is not the issue fixed with Fix Problems.
  2. Is there any other way to fix the issue or workaround in ruby api to get the correct face?

Many thanks in advance
Jiva

Duplicate Persistent Id.skp (75.0 KB)

Only known issues can be fixed. Those that are not known and coded for are likely unknown issues (edge cases, etc.)

Are they within the same geometric context ?
You can use Enumerable block form search methods to find entities …

face = my_ents.grep(Sketchup::Face).find {|face| face.persistent_id == target_id }

If found, face will be non-nil.

1 Like

Note that Enumerable#find will find the first object that the block returns true for, and then stop, returning that object.(If no matches are found, it returns nil.)

To get an array of multiple matches, instead use the Enumerable#find_all method.
This method always returns an array, which will be empty if no matches were found.

1 Like

Hi,
I’m seeing ‘Fix Problems’ does fix the issue in the latest version of SketchUp (2020.2). What are you seeing that leads you to think that it isn’t? Also, how was this duplicate id situation created?
Thanks.

2 Likes

Hi Dan,

Thank you for the reply.

After Bugra suggested the issue doesn’t affect 2020 version, I tried on 2018 and 2019 versions and both versions detect and fix the issue. So it seems to be a 2017 version problem.

Is it a known issue on 2017 version of Sketchup?

The issue is reported by one of our plugin user so it is not always possible to suggest them to use another Sketchup version. They are thinking our plugin is not good because of this issue.

The solution for question 2 works if the duplicate ids are used on objects of different types. e.g. face and line. We can loop through the all the entities and get the object with the persistent id and the expected type. However, the attached model has two faces with same persistent id. So even when we loop through all the entities there is no guarantee to get the correct face as expected type is same for both.

Any other suggestions what can be done to get the face correctly over different sessions.

Many thanks
Jiva

Hi Bugra,

Thank you for the reply.

I forgot to mention on the original post. The Sketchup version is 2017 and the issue is raised by one of our plugin user and they do not want/can switch Sketchup version even if the issue is solved. Interesting to know that issue doesn’t affect Sketchup 2020. I tried to Fix problem on Sketchup 2018 and 2019 too and both version detect the duplicate issue and fix it. So it seems to be 2017 version issue. The duplicate id situation was created after the users copied objects from another Sketchup model.

Many thanks
Jiva

Well, SketchUp 2017 is no longer supported. (Trimble only supports the latest 3 versions.)

Have you tried loading the problem model into the web edition and see if it fixes the duplicate ids ?
If this works, this would be the only “free” path for your plugin user to fix problem model files manually.

You might try to erase one of the faces (with the duplicate ID) and recreate it.
Find one of the faces as explained above …

# Where face is the face to recreate ...
edge = face.edges[0]
ents = edge.parent.entities
face.erase!
before = ents.grep(Sketchup::Face)
edge.find_faces
after = ents.grep(Sketchup::Face) - before
new_face = after.first

Hi Dan,

Thank you for the reply.

The Sketchup web doesn’t detect/fix the duplicate persistent id for Sketchup 2017 version models.
The idea of deleting the face and recreate should work for that version. Many thanks for your help in this issue.

Regards
Jiva

1 Like

Hi Dan,

The face creation method works nicely.

It is not working when the face has a hole inside.
I tried to create from all the edges. edges.each{|edge| edge.find_faces }
It creates one face with a hole correctly but also creates a second face for the hole itself.

Is the main face always guaranteed to be the first face? If so, I could check if more than one face is created and then deleted the others.

What is the reliable way to just get the main face with a hole?

Many thanks in advance
Jiva

What about edges.first.find_faces ?

That behaves same as edge.find_faces. It create a single face covering the hole.
The below code leaves the correct face even for multiple holes but I wanted be sure it is a reliable method.

Regards
Jiva

edges = f.edges
ents = edges[0].parent.entities
f.erase! # delete the old face
before = ents.grep(Sketchup::Face)
edges.each {|edge| edge.find_faces}
after = ents.grep(Sketchup::Face) - before
n = 0
after.each {|new_face|
if (n == 0)
    new_face # correct face
else
    new_face.erase!
end
n += 1
}

Please post code correctly on the forum:

What about this …

loops = f.loops
if loops.size > 1
  # get an inner loop, one of it's edges and do a find_faces
  inners = loops - [f.outer_loop]
  inners.first.edges.first.find_faces
else
  # face has no inner loops just use one of the outer loop edges
  f.edges.first.find_faces
end

Hi Dan,

The inners loop logic only creates a face for the hole. It doesn’t create the main face at all.

The only logic which works for me so far is to create all faces with ruby edges.each {|edge| edge.find_faces} and keep the first face and delete all other faces.

It seems to work but wanted to be sure it works in most cases. If there is no other way I will finalise this method. I really appreciate your help on solving the issue.

Many thanks
Jiva

1 Like