How do I clear the active model using ruby API?

I can interactively close the model window but how can I do the equivalent with the API? Nothing I try seems to work including:

model = Sketchup.active_model
model.close( true )
model.close_active()
entities = model.active_entities
entities.erase_entities( entities )
model.selection.remove( entities )

I just can’t get back to a clean window to redraw my model without using the UI.

you can use Sketchup.undo if it take less then 100 steps to get back…

or maybe one of these…

  Sketchup.send_action('newDocument:')  ## New  ### ⌘N
  Sketchup.send_action('revertDocumentToSaved:')  ## Revert
  Sketchup.send_action('performClose:')  ## Close  ### ⌘W

what GUI steps are you trying to emulate?

john

This will get you back to the top level model entities collection:

model.close_active() until model.active_entities == model.entities

(Moved to the Ruby API category.)

Re you trying to close the application or empty the model? It’s not clear from your post.

To empty the model, run “Sketchup.active_model.entities.clear!”

Thanks but,

Doesn’t seem to work. I still can’t clear the view from my API.

Bob Rice

I just want to clear the previous drawing and redraw everything from my API with different parameters, but I can’t seem to do that without quitting the application.

Bob Rice

What eneroth said, or …

a. Keep references to everything your draw in an array, and then afterward iterate the array deleting those objects.

objs.each {|o| o.erase! }

b. Draw inside a group, and then afterward, delete the group instance and then clear it’s definition’s entities collection & reuse, or …

c. Draw inside an undo operation, and call Sketchup::undo() afterward, or …

d. some combination of the above.

Can you explain how yo do whatever yo are trying to do from the UI?

Hi Dan,

Great suggestions! Thus far I haven’t done anything with definitions or Undo operations. Are definitions automatically created for a group? If so, then I haven’t bee deleting them. I have no problem deleting groups except for my top level group, i.e., my model.

Thanks,
Bob Rice

Hi Christina,

Closing the view for the model and creating a new view seems to do the trick. I assume that Sketchup is deleting all of the model entities when its view is closed.

Bob Rice

Groups are implemented as a special case of Components, and every active Group has a corresponding ComponentDefinition created when the Group is created. Unmodified copies of a Group all tie to the same ComponentDefinition. An independent copy of the CD is created the moment you edit one of the Group copies, much like “make unique” on a ComponentInstance. But when you erase the last copy of a Group, the corresponding ComponentDefinition is also deleted, unlike Components whose CD is retained in the model’s definitions collection until explicitly purged.

Bob, you seem to have some misunderstanding of how a ‘multi document app’ works on your mac…

each model you open has a view displaying the model content in the document…

when you “Close” the ‘document’ and you have no unsaved changes, it will just close, nothing gets deleted by SU…

if there are ‘unsaved changes’ SU will produce a save dialog asking if you want to discard them…

when you use ‘New’, SU ‘opens’ a new ‘Untiled’ document containing a copy of your default ‘Template’ skp file…

it’s a fresh document and has no bearing on any other documents…

john

What do you mean by closing a view and creating a new view?

Hi John,

I do undestand Apple mult-document apps - I have a couple on the iTunes store. But thus far I have only been using Sketchup with a single document (model) view. So can I assume that all of the model’s entities are released when I close the view?

BTW, Because of the complexity of my models, I do all of my drawing using the Ruby API. Being prompted to save changes is merely an annoyance for me. I would like a preference to skip the prompt to save changes when quitting the app.

Thanks,
Bob Rice

Hi Dan,

Thanks for the clarification of Component Definitions.

Bob Rice

That was Steve who clarified.

The team will likely never implement a dangerous shutdown, and it took at least 4 years for the API to get the safe shutdown method I had requested.

There are workarounds, such as:

(a) saving the model to a temp model file, then call Sketchup::send_action("terminiate:") or Sketchup::quit, then deleting the temp model file in a startup script.

(b) wrap all your drawing in one undo operation (as I said above,) and then either call Sketchup::undo or just abort the operation.
See the API documentation for:

Hi Dan,

All shutdowns are safe if the model is populated using only the API… You could set a flag if any objects are created or edited using the UI, otherwise the document could be considered unmodified.

Thanks for the tips. I will try using the undo feature.

Bob Rice

hi Bob, didn’t intend to sound disparaging, if that’s how it came across…

being ‘multi document’ is a real bonus for running ruby code on a mac…

particularly when testing new code…

i.e. when loaded from ‘Ruby Console’ code can run on numerous documents in a single session by changing documents and hitting the up arrow in RC and return…

I’m afraid this isn’t the case, the API relies on Ruby, where a simple error can Crash SU or completely lockout OSX, requiring a hard shutdown…

there is Sketchup.active_model.modified? and when it returns false you can close the document containing the ‘active_model’, but to be ‘safe’ you may also want to do some extra things…

      # an edge case when using with "plugin's tool" active would crash SU...
      Sketchup.active_model.select_tool(nil)

      # an edge case when using with "deeply nested component" would crash SU...
      Sketchup.active_model.close_active

      # an edge case when using with "Version Warning" active would crash SU...
      Sketchup.send_action('closeDocument:')

I have a couple of mac dev tools that make my scripting life easier, but it depends on what your trying to achieve…

john

Hi John,

I occasionally get an endless loop in my code where I have to force quit Sketchup, but I’ve never had a problem with Sketchup hanging the OS such that I needed a system restart. There are programming a few errors that will always crash Sketchup, but I can track them down.

I tried using Sketchup 2017 but went back to using Sketchup 2016. Sketchup 2016 plays nice with other apps. I can be watching a live video stream in a window while Sketchup 2016 is drawing or animating via ruby script. Sketchup 2017 does not cooperate so well and will interrupt my video stream playback.

By “safe shutdown”, I assume that Dan was referring to accidentally losing a lot of work from drawing with the UI. When drawing using the API, the model can always be recreated by rerunning the script. However, when my model becomes so complex that the script takes more than a couple of minutes to render, I can save intermediate versions of the model to disk. I have logic in my script to find objects by name and then continue drawing from the intermediate version.

P.S., I am modeling and animating machines having lots of gears.

Best regards,
Bob Rice

Yes, partly. If the model’s modified flag is set (true) then SketchUp will ask the user if they wish to save the work. (The modified flag can be cleared by saving the model via the API to a temporary file in the TEMP folder for example.)
But it can also be cleared by returning the model to the “start state” by wrapping all your drawing within an undo operation (which you should be doing as it is best practice anyway.)

But, the “safe” in shutdown, really comes from the fact that batch coders used to purposely crash SketchUp in an unsafe manner, by purposely crashing Ruby. This means that SketchUp cannot go through it’s normal shutdown and saving of it’s environment settings (in the registry on Windows, or a .plist file on Mac,) and perhaps some .dat files.
SketchUp will save some settings during runtime, and others only during shutdown. If it is shutdown unsafely, there exists the chance that settings get into a bad state, which means the user needs to manually delete settings files, or repair using the installer.


A few examples of doing what you wish. Each assume you have a method named draw_geometry() to do the work.

Using an abort operation:

  def draw_op(
    op_name, # also used for the SKP filename
    dirname= File.join(ENV['Home'],"Documents/SketchUp/"),
    model=Sketchup::active_model
  )
  ###
    model.start_operation(op_name,true)
      draw_geometry(model)
    model.commit_operation
  rescue => err
    puts err.inspect
    puts err.backtrace
  else # no errors
    model.save( File.join(dirname,op_name) )
  ensure
    model.abort_operation
  end

But after the overhaul of observers, they have suggested everyone attach their operations to the previous one, so you may wish to switch off as many extensions as possible.

Or, just draw within a group, and reuse that group:

  @grp = model.entities.add_group
  # Immediately add a cpt to prevent GC of group
  @grp.entities.add_cpoint([0,0,0])
  draw_using_group(@grp,"GearBox")
  # Reuse @grp for other drawing loops,
  # then when done with @grp
  @grp.clear!
  model.definitions.purge_unused
  model.materials.purge_unused
  model.layers.purge_unused

  def draw_using_group(
    grp, # a reference to a valid group
    op_name, # also used for the SKP filename
    dirname = File.join(ENV['Home'],"Documents/SketchUp/"),
    model = Sketchup::active_model
  )
  ###
    model.start_operation(op_name)
      draw_geometry(model,grp)
    model.commit_operation
  rescue => err
    puts err.inspect
    puts err.backtrace
  else # no errors
    model.save( File.join(dirname,op_name) )
  ensure
    grp.clear!
    # Immediately add a cpt to prevent GC of group
    grp.entities.add_cpoint([0,0,0])
    GC.start
  end