SketchUp / api-issue-tracker

Public issue tracker for the SketchUp and LayOut's APIs
https://developer.sketchup.com/
39 stars 10 forks source link

ComponentDefinition#save_as and #save_copy always generate thumbnail from same angle #765

Closed esterkimx closed 1 year ago

esterkimx commented 2 years ago
  1. SketchUp 22.0.316 64-bit
  2. OS Platform: Windows 10

In previous SketchUp versions component thumbnail angle will change every time user rotates viewport. It was good because user had at least some control over how component preview looks. In SketchUp 22 thumbnail look doesn't depend anymore on viewport position and always rendered from the same angle.

I called ComponentDefinition#refresh_thumbnail every time before saving the component and tried to save it with #save_as and #save_copy.

su22_thumbnail_bug

thomthom commented 2 years ago

hmm... I'm not sure if this was an intended change (internally). From an API point of view it might be best to offer an optional argument with camera data.

DanRathbun commented 2 years ago

There was a Win bug in 2021.0 where component thumbnails were not updating correctly.

Then it was supposedly fixed in 2021.1, viz:

Miscellaneous

(Win) Fixed an issue where the active thumbnail in the component browser did not update when editing a component.

sketchupbot commented 2 years ago

Logged as: SKEXT-3341

flextools commented 2 years ago

Glad to see this logged. Is there possibly a time frame for when this will be fixed and released? (I wish we had found this earlier). It's currently making Sketchup 2022 totally useless for us and countless others who use Component Finder on a daily basis.

thomthom commented 2 years ago

No time frame. We've not fully reviewed it. (And we can never give any promise ahead of time)

thomthom commented 2 years ago

Can you share the (some) sample models related to this?

flextools commented 2 years ago

This happens with any components you do a save_as to.

Below is a video showing it happen with a box I just created and then saved with Component Finder and later by Right Click > Save As.

Attached is the box component too.

(I also tried uninstalling FlexTools Component Finder to make sure it's not related, and it still happens).

https://user-images.githubusercontent.com/11962851/154338778-9e1f94de-c8a1-4ded-b235-65a6744dfba5.mp4

Component#1.zip

thomthom commented 2 years ago

Can you also elaborate on how your extension relied on this behaviour? What made the previous behaviour important for you?

flextools commented 2 years ago

For example, I'm modeling a table. I'll save many versions of the table as I work on it - Each version with progress, different shapes, different materials, different dynamic attributes etc. Versions I can get back to later if needed, and also in case a crash happens.

Since it's a table, that I will eventually want to place in a model (with drag and drop or with #place_component with a click in Component Finder), it doesn't make sense to save the whole model (File > Save), but rather to save the component aside (with Right Click > Save As or with #save_as with a click in Component Finder).

The thumbnail is very important for knowing what I'm going to place later. Sometimes I want to change the color... sometimes I want to change the angle for a better view and I'll overwrite the last table with a better one... saving a file out with a correct thumbnail is the most basic operation of a 3D software package.

Another example - you download a window from the 3D warehouse, but that window is in the wrong size and with the wrong materials, and you need it for 5 different projects. Make the changes you need once - save it aside with #save_as - and you have it all set for quick retrieval. No need to open multiple sessions of sketchup for copying between models.

flextools commented 2 years ago

About your suggestion Thomthom for an optional argument with camera data - that could be useful. For example if one would like to save from a front view only of from a predetermined angle.

DanRathbun commented 2 years ago

saving a file out with a correct thumbnail is the most basic operation of a 3D software package.

Agreed. Often flat cutting components like windows have better thumbnails looking straight down from the top (as they are modeled laying on the XY cutting plane.) It would be a real PITB to have to rotate the component or it's geometry just to get the right thumbnail view.

Myself, I don't usually finish components in a larger file. I'll directly open them and normally I'll add a dedicated "Thumbnail" scene and always switch to that before saving any edits. This I must always do especially for cutting components.

RELATED ISSUES:

thomthom commented 2 years ago

I'm still investigating. Need to compare with older SU build to get an idea of what was going on then. But looking at the current code the logic seems to match what internal comments claim should happen: The camera is generated from the current viewport camera when the first thumbnail is generated - this would occur when the component is created. After that the component stores that camera and will reuse that when the thumbnail is generated.

If older versions picked up the viewport camera upon every save that was something that went against what the original code intended (going by the historical comments in the source). And the resetting of the camera was probably a bug in that regard. (As mentioned, I need to build older SU to figure out exactly what happened.)

Though all of that is really internal details, I think the best option for the API is to have explicit getter/setter for this.

thomthom commented 2 years ago

I'm testing this on SU2021, and I'm not seeing the thumbnails updating when I do I Save As on the components.

Can we get a small snippet of code the replicate the behaviour in an automated manner please? Saving out copies of a component where the thumbnail used to update? It'd eliminate any guesses in trying to interpret the instructions here.

DanRathbun commented 2 years ago

The camera is generated from the current viewport camera when the first thumbnail is generated - this would occur when the component is created. After that the component stores that camera and will reuse that when the thumbnail is generated.

Wondering then what happens when ComponentDefinition#refresh_thumbnail() gets called and it's afterward saved out ?

esterkimx commented 2 years ago

Try to reproduce it with this:

def thumbnail_bug_test(try_count)
  dir_parent = UI.select_directory title: 'Select a directory for test SKP files'
  return unless dir_parent

  model = Sketchup.active_model
  view = model.active_view
  pages = model.pages
  definitions = model.definitions

  # Make a test cube component
  vertices = [
    [-1 ,-1, 0], [1 ,-1, 0], [1 ,1, 0], [-1 ,1, 0],
    [-1 ,-1, 2], [1 ,-1, 2], [1 ,1, 2], [-1 ,1, 2]
  ]
  faces = [
    [3, 2, 1, 0], [0, 1, 5, 4], [2, 3, 7, 6],
    [4, 5, 6, 7], [4, 7, 3, 0], [6, 5, 1, 2]
  ]
  defn = definitions.add
  faces.each do |idxs|
    vts = idxs.map { |idx| vertices[idx] }
    f = defn.entities.add_face vts
    f.material = f.normal.to_a.reverse.reduce(0) do |acc, n| 
      (acc << 8) + (n.abs * 0xFF).to_i
    end
  end

  # Trying to reproduce the bug
  dir = File.join dir_parent, "SU-#{Sketchup.version}-thumb-test-#{Time.now.to_i}"
  Dir.mkdir dir
  try_count.times do |i|
    view.camera = Sketchup::Camera.new(3.times.map { rand - 0.5 }, [0] * 3, Z_AXIS)
    # To reproduce the bug manually, I rotated the viewport with the `Orbit` tool. 
    # However, with Ruby API, changing view.camera isn't enough to get the thumbnail refreshed.
    # Moving to a new scene forces the thumbnail to update, just like with the `Orbit` tool:
    pages.selected_page = pages.add "Test Scene #{i}"
    skp = File.join dir, "#{i}.skp"
    defn.save_as skp
  end

  UI.openURL dir
end

thumbnail_bug_test(5)

This is what I get with SU2021 and SU2022:

SharedScreenshot

The thumbnail changes in SU2021 even without calling ComponentDefinition#refresh_thumbnail.

thomthom commented 2 years ago

Thank you, I'm able to reproduce with ease with that example. 👍👍

DanRathbun commented 2 years ago

FYI - I'd tried actually placing an instance of the definition into the model, zooming to the instance after each scene page is created, then updating the page, and refreshing the definition thumbnail before each component file written ... but still no joy with SU2022.

def thumbnail_bug_test_2(try_count)
  dir_parent = UI.select_directory title: 'Select a directory for test SKP files'
  return unless dir_parent

  model = Sketchup.active_model
  view = model.active_view
  pages = model.pages
  definitions = model.definitions

  # Make a test cube component
  vertices = [
    [-1 ,-1, 0], [1 ,-1, 0], [1 ,1, 0], [-1 ,1, 0],
    [-1 ,-1, 2], [1 ,-1, 2], [1 ,1, 2], [-1 ,1, 2]
  ]
  faces = [
    [3, 2, 1, 0], [0, 1, 5, 4], [2, 3, 7, 6],
    [4, 5, 6, 7], [4, 7, 3, 0], [6, 5, 1, 2]
  ]
  defn = definitions.add
  faces.each do |idxs|
    vts = idxs.map { |idx| vertices[idx] }
    f = defn.entities.add_face vts
    f.material = f.normal.to_a.reverse.reduce(0) do |acc, n| 
      (acc << 8) + (n.abs * 0xFF).to_i
    end
  end

  inst = model.entities.add_instance(defn, IDENTITY)

  # Trying to reproduce the bug
  dir = File.join dir_parent, "SU-#{Sketchup.version}-thumb-test-#{Time.now.to_i}"
  Dir.mkdir dir
  try_count.times do |i|
    view.camera = Sketchup::Camera.new(3.times.map { rand - 0.5 }, [0] * 3, Z_AXIS)
    # To reproduce the bug manually, I rotated the viewport with the `Orbit` tool. 
    # However, with Ruby API, changing view.camera isn't enough to get the thumbnail refreshed.
    # Moving to a new scene forces the thumbnail to update, just like with the `Orbit` tool:
    page = pages.add "Test Scene #{i}"
    pages.selected_page = page
    view.zoom(inst)
    page.update(PAGE_USE_ALL)
    defn.refresh_thumbnail
    skp = File.join dir, "#{i}.skp"
    defn.save_as skp
  end

  UI.openURL dir
end
Matherone commented 2 years ago

Yes, please.

Our studio also needs components to be able to set the current view as file thumbnail when saved, and having this as an option is ideal. This would facilitate automation and save many work hours.

Use case: Our Sketchup clients, often in the design and construction lines of business, often require us to design and model hundreds, sometimes a thousand components, or more. Such components may differ only by small details.

When the end user is searching for the right component, the user browses a folder visually. A relevant asset thumbnail is sometimes the best way to quickly find the desired component.

Some assets need to be seen from front, others from top in order to be differentiated visually. In practice, this means that we intially need to manually set camera properties per each individual component.

Later on, we often need to update parts of a large component library. Say batch-swapping materials or a subcomponent in say 352 out of 800 components. Now, 352 thumbnails need to be updated.

Here, having an option to update only geometry but not camera properties would be valuable.

DanRathbun commented 1 year ago

Not exactly fixed, but new API features added to directly control definition thumbnails:

This means there may not be any easy workaround for clients running v22.