sketchucation logo sketchucation
    • 登入
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    New to Ruby - I want to write a script to...

    已排程 已置頂 已鎖定 已移動 Developers' Forum
    26 貼文 5 Posters 924 瀏覽 5 Watching
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • K 離線
      keithswd
      最後由 編輯

      Thanks for the correction - I see my mistake now. However, the corrected syntax doesn't fix the crash. The folder selection works as it did before and populates the array with all the .skp files in the folder (about 200 for testing purposes), and my message box pops up and correctly reports the number to be processed.

      However it stops on the 33rd or 34th file no matter what that file is. Each time I run the script, I move the 33/34 successfully modified files out of the folder, so I am never processing the same files twice. I don't know what might be special about the 33/34 mark, but it bails at that point.

      Some kind of limit appears to be reached? Memory? I've no clue!

      1 條回覆 最後回覆 回覆 引用 0
      • D 離線
        driven
        最後由 編輯

        not sure how to do it in ruby but in the osascript/applescript/bash I tend to use, if you don't add a distinct delay point, the process reaches some limit and errors. [That's what happening with the one I posted earlier]

        maybe adding a puts "done" after definitions.purge_unused will allow a break before opening the next?

        total stab in the dark
        john

        learn from the mistakes of others, you may not live long enough to make them all yourself...

        1 條回覆 最後回覆 回覆 引用 0
        • Dan RathbunD 離線
          Dan Rathbun
          最後由 編輯

          (1) The iterator block.. use curly braces instead of do ... end
          So the block can have access to external references, such as definitions

          (2) Make sure the loading is done before proceeding.

          (3) perhaps use undo operations ?

          Try an iterator like:

            i = 0
            puts()
            #
            skpFiles.each { |compFile|
              ###
              model.operation( "Update '#{File.basename(compFile)}'", true )
              ###
              compDefinition = definitions.load compFile
              begin
                if compDefinition.internal?
                  behavior = compDefinition.behavior
                  behavior.always_face_camera = true
                  behavior.shadows_face_sun = true
                  compDefinition.save_as compFile
                else
                  putc(46) # period char
                  redo
                end
              rescue => e
                ###
                model.abort_operation()
                ###
                puts()
                puts "ERROR saving component file;"
                puts "  #{compFile}\n"
                puts e.message
                puts e.backtrace if $VERBOSE
                puts()
              else
                i += 1
                if i >= 10
                  definitions.purge_unused
                  i = 0
                end
                ###
                model.commit_operation()
                ###
              end
              # each skp file
            }
            definitions.purge_unused if definitions.length > 0
          
          

          I'm not here much anymore.

          1 條回覆 最後回覆 回覆 引用 0
          • K 離線
            keithswd
            最後由 編輯

            Thanks again for your help and suggested code. As it stands it does not modify any components. I discovered this is because it seems that even when the component file is loaded successfully, compDefinition.internal? returns false. I can only imagine that this is actually testing whether the component was created within the model or loaded from a file - in which case we are getting the expected result. I commented it out and it runs but... sadly it still bombs out at around 33 components.

            I really don't want to take up any more of anyone's time - this was just a little project for me to play with but it seems rather trickier than I could have forseen. But I thought you might like an update!

            def setcompfm
            
            model = Sketchup.active_model
            # set folder and get array of filenames
            folder = UI.openpanel("Choose a skp file to set folder","*.skp")
            
            return unless folder && folder = File.dirname(folder)
            
            skpFiles = Dir[File.join(folder, "*.skp")]
            
            length = skpFiles.length
            
            result = UI.messagebox "Process " + length.to_s + " files?", MB_YESNO
            
            return unless result == 6 # Yes
            
            # Returns a DefinitionList
            definitions = model.definitions
            
            # iterate through files
            i = 0
              puts()
              #
              skpFiles.each { |compFile|
                ###
                model.start_operation( "Update '#{File.basename(compFile)}'", true )
                ###
                compDefinition = definitions.load compFile
                begin
                  #if compDefinition.internal?
                    behavior = compDefinition.behavior
                    behavior.always_face_camera = true
                    behavior.shadows_face_sun = true
                    compDefinition.save_as compFile
                  #else
                  #  putc(46) # period char
                  #  redo
                  #end
                rescue => e
                  ###
                  model.abort_operation()
                  ###
                  puts()
                  puts "ERROR saving component file;"
                  puts "  #{compFile}\n"
                  puts e.message
                  puts e.backtrace if $VERBOSE
                  puts()
                else
                  i += 1
                  if i >= 10
                    definitions.purge_unused
                    i = 0
                  end
                  ###
                  model.commit_operation()
                  ###
                end
                # each skp file
              }
              definitions.purge_unused if definitions.length > 0
            
            
            end #end def
            
            1 條回覆 最後回覆 回覆 引用 0
            • D 離線
              driven
              最後由 編輯

              Hi Keith,

              I'm sitting at home recovering from having my ear cut off [and put back on] on Friday.
              So, glad for the distraction...
              Anyhow, heres an Automator script that has a safe test action, so won't hurt any files...
              I missed a filter function, in the first...

              1. opens each .skp in a 'pre-selected' folder in SU v2013 [should use your version if not]
              2. opens 'Ruby Console' and 'types' some safe for testing code Sketchup.send_action('viewIso:');Sketchup.send_action('viewZoomExtents:')clicks return
              3. 'Saves' the changes
              4. closes 'RC'
              5. closes the .skp
              6. loops to the next skp in folder... and repeats

              You need to open SU first with an empty new drawing... this just saves hassle.
              Pre-Sellect skps in a Folder.
              Open the workflow in 'Automator.app' by double clicking after unzipping it.

              Click Run, watch the show [I like the way it types for me, rather than just inserting it en-masse]

              If your not using v2013 you'll may need replace the SketchUp.app shown with the one on your path [I know it looks right but I did a trick to avoid using v8, so just swap it if you need to, run it once to see if it fails...]

              Once your happy the safe version works, edit the applescript with your SU [a 'one-liner' is probably best]

              try it on a subset, if it runs those, it will run hundreds as long as you adjust the timeout [in loop field] to cover it...

              Let me know if it works

              john

              learn from the mistakes of others, you may not live long enough to make them all yourself...

              1 條回覆 最後回覆 回覆 引用 0
              • K 離線
                keithswd
                最後由 編輯

                Hi John,
                The ear sounds painful! I hope you are recuperating well.
                Thanks for the workflow. I have got it to work, with SU loading a script automatically (which defines a function to set the current model behavior as I want it) and I call that function in console. It runs slowly compared to the all-Ruby solution - but at least it processes without crash. So I can send lots of files and leave it to run over lunch, or night!
                Many thanks again,
                Keith

                1 條回覆 最後回覆 回覆 引用 0
                • 1
                • 2
                • 2 / 2
                • 第一個貼文
                  最後的貼文
                Buy SketchPlus
                Buy SUbD
                Buy WrapR
                Buy eBook
                Buy Modelur
                Buy Vertex Tools
                Buy SketchCuisine
                Buy FormFonts

                Advertisement