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

    Pausing for Sketchup to update

    Scheduled Pinned Locked Moved Developers' Forum
    11 Posts 5 Posters 1.0k Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D Offline
      designforlife
      last edited by

      I am trying to use Ruby to automate a tour through my model but I have hit a wall trying to get my script to wait for the view to update. I want the script to step through the model and find each entity that matches a particular criteria, perform some action and only then go to the next matching entity and repeat. Every structure I try, like 'array.each do|x|' or 'while' or 'if n<number_of_entities', steps through the whole model but perform the desired action only on the last matching entity.

      Searching this forum, I have found several posts on similar issues but none of the given solutions work for me and I just cannot figure out why. One solution is 'view.invalidate'. As far as I can see, this has absolutely no visible effect on the model or view or script execution. The other suggestion is 'UI.start_timer'. Yes, execution pauses for the set interval but then acts on the last match as above. The only thing that works - sort of - is 'UI.messagebox' This allows the action to be performed on each chosen entity in turn but of course the box pops up with that irritating noise and requires user intervention to cancel so the script can continue. I have searched in vain for a work around, like repositioning the box off screen and setting a timeout to automatically close the box (plus silencing the beep). Sadly, no such options appear to exist. (It seems Visual Basic and the Windows API can do it but that's way beyond me.)

      Can anyone explain the correct use of view.invalidate and/or start_timer? Or direct me to some existing tutorial on these? The usual newbie disclaimer and apologies apply... Thank you.

      Mike

      1 Reply Last reply Reply Quote 0
      • Chris FullmerC Offline
        Chris Fullmer
        last edited by

        Hi Mike, to undesratnd better, you say you are trying to make tour through your model. Do you want ruby to move the camera through the model from object to object, and so it will be a regular looking animation? Is that the goal?

        If so, you will need to make a camera and animate it, using the object locations to guide the location of the camera. I'm not sure exactly what you do to do that, but I think it is the animation class, and you just animate the camera.

        Is that sort of the right idea?

        Chris

        Lately you've been tan, suspicious for the winter.
        All my Plugins I've written

        1 Reply Last reply Reply Quote 0
        • D Offline
          designforlife
          last edited by

          Hi Chris, thanks for the reply and yes, I have got the camera to move without using the animation class or pages. So the step I can't solve is how to avoid the need for user intervention.

          I began with some code I found on the Google blog here: http://sketchupapi.blogspot.com/2008/11/storing-and-retrieving-with.html. This creates a simple group with attributes attached. The group is placed at the current view and takes the current camera parameters as its attributes. A context menu item allows you to go to that view with a few clicks.

          I use the reveal_view method to first set up the views I want but the go_to_view method is not convenient for viewing in a particular sequence - you may not be able to see the next location to click on it. An advantage of my idea is you can even hide the cameras or turn off the layer they are on so the model is not cluttered with camera groups.

          I also made a modified version of reveal_view so that I don't have to go to each location to create the camera for that view. With this version, a context menu becomes available when an edge is selected and its start and end point become the eye and target of the camera.

          Since these 'cameras' are all placed on their own layer, I can use layer.name=="cameras" to store them in an array. It should then be a simple matter of extracting the attributes from each in turn (with info=cam.attribute_dictionary("is_a_camera")) and sending the view to that location (with view.camera=Sketchup::Camera.new(info["eye"]...etc) but Ruby doesn't have the good grace to wait unless I use messageboxes, which is a bit self defeating.

          Anyway, here is my code:

          def do_tour
          	ents=Sketchup.active_model.entities
          	cams=[]
          	e=0
          	num=ents.length
          	while e < num
          		if ents[e].layer.name=="cameras"
          			cams.push(ents[e])
          		end
          		e+=1
          	end
          	cam_no=0
          	cam_indx=cams.length
          #	while cam_no<cam_indx
          	cams.each do |cam|
          		info=cam.attribute_dictionary("is_a_camera")
          		m=Sketchup.active_model
          		view=m.active_view
          		UI.start_timer(3, false) {puts cam_no, cam} 
          		### For some reason this timer now does not pause, but it did previously. The view moves 
          		### immediately to the last camera position and halts. It does verify in the console that
          		### the script is stepping through the camera group list. Only the last camera number is 
          		### displayed (cam_indx times).  If the flag is set to true instead of false, you can see 
          		### in the console it is looping endlessly but the view remains the same.
          		view.camera=Sketchup;;Camera.new(info["eye"],info["target"],info["up"],info["persp"],info["fov"]), 3
          		# UI.messagebox("camera no.; " + cam_no.to_s)   ### uncomment this line to see how the script
          								### (almost) should work.
          		 view.invalidate ### I read somewhere that if this is placed after the messagebox call, the
          				 ### box won't appear. But it does.
          		cam_no += 1 
          ### I also tried the following snippet but it merely behaves like start_timer
          #		time_mark = ( Time.now + 3 ) 
          #		while time_mark > Time.now
          #		end
          	end
          end
          

          This would be activated by a Plugin menu item.

          I've attached a Sketchup file with some cameras already created. It is not pretty but should save time for you.

          test_anim.skp
          If the problem is a simple bug or wrong syntax, it eludes me. My conceptual understanding of Ruby is weak (hence my wholesale copying of Google's code). But if I can get past this, I can think about different transition times, changing attributes (to pan maybe), and maybe allowing a user to pause whenever they want.

          Mike

          1 Reply Last reply Reply Quote 0
          • T Offline
            tomasz
            last edited by

            Mike,

            Check the SU2KT exporter. There is a class called 'AnimCamera' (now I realise I should have given it more unique name).

            
            class AnimCamera
            def initialize
            	@frame=0
            	@slide_time=0.0
            end
            
            def nextFrame(view)
            
            	@slide_time=@frame/@frame_per_sec
            
            	model=Sketchup.active_model
            	model.pages.show_frame_at @slide_time
            
            	@frame+=1
            end
            
            def stop
            	Sketchup;;set_status_text("", 1)
            	Sketchup;;set_status_text("", 2)
            end
            
            end # class AnimCamera
            

            This way you can start an animation:
            Sketchup.active_model.active_view.animation = AnimCamera.new
            Check Ruby API for more info.

            Tomasz

            Author of [Thea Render for SketchUp](http://www.thearender.com/sketchup)

            1 Reply Last reply Reply Quote 0
            • chrisglasierC Offline
              chrisglasier
              last edited by

              I have used a shuttle method in javascript that might be useful for you. I will try and explain it in javascript but I am sure it is easy to transpose into ruby. The idea is to shuttle from one function to another, but here I use a controller function.

              There is a global variable - pass.

              The controller function has this statement eval("fun"+pass)() in a timer like setInterval.

              Each fun+pass function has two parts - conditional stop and go (or wait in your case I guess).

              If the condition is satisfied, stop timer, pass++ and call controller .... and on and on.

              I hope this is helpful.

              Chris

              With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

              1 Reply Last reply Reply Quote 0
              • D Offline
                designforlife
                last edited by

                ...so the answer is that I am barking up the wrong program tree? Damn! So near, yet so far.

                1 Reply Last reply Reply Quote 0
                • chrisglasierC Offline
                  chrisglasier
                  last edited by

                  @designforlife said:

                  ...so the answer is that I am barking up the wrong program tree? Damn! So near, yet so far.

                  Not necessarily, but web dialogs are very good if you want flexibility and interoperability including human interaction. Why not give them a try?

                  Chris

                  With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

                  1 Reply Last reply Reply Quote 0
                  • D Offline
                    designforlife
                    last edited by

                    @chrisglasier said:

                    @designforlife said:

                    ...so the answer is that I am barking up the wrong program tree? Damn! So near, yet so far.

                    Not necessarily, but web dialogs are very good if you want flexibility and interoperability including human interaction. Why not give them a try?

                    Chris

                    Could you explain a bit about web dialogs? How do they relate? I tried a few of the methods from the API page to display a web page in Sketchup. Beyond that, I am trying to imagine the potential.

                    Actually, the name initially suggested to me they might work the other way round - to display sketchup in a web page but I believe that requires the web user to download and install a browser add-on.

                    Mike

                    1 Reply Last reply Reply Quote 0
                    • Chris FullmerC Offline
                      Chris Fullmer
                      last edited by

                      Hi Mike, sorry if I'm being dense, but to make sure I'm understanding....

                      The only thing you want is to make it so the user can pause/cancel the animation while the animation is in process? Is that the only thing that you are asking about?

                      Chris

                      Lately you've been tan, suspicious for the winter.
                      All my Plugins I've written

                      1 Reply Last reply Reply Quote 0
                      • chrisglasierC Offline
                        chrisglasier
                        last edited by

                        @designforlife said:

                        Beyond that, I am trying to imagine the potential.

                        Well you could have a look at this plugin and, as you have a PC, download it. The ruby file shows you how to open a web dialog window and sit an html file in it. You can also find how to pass strings back and forth between JavaScript and Ruby.

                        Let me know if you find this helpful but need more info.

                        Chris

                        @chris fullmer said:

                        The only thing you want is to make it so the user can pause/cancel the animation while the animation is in process? Is that the only thing that you are asking about?

                        Just saw your note Chris ... what I understood was that Mike wants to stop the script outrunning the animation, so I suggested using two functions, one substituting his messagebox suggestion.

                        cg

                        With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

                        1 Reply Last reply Reply Quote 0
                        • K Offline
                          kirill2008
                          last edited by

                          @designforlife said:

                          Can anyone explain the correct use of view.invalidate and/or start_timer?

                          You may try to substitute "while...end" or "for...end" etc control structures by timer. The funny thing is that maybe it is not necessary to put 'Sketchup.active_model.active_view.invalidate' line inside the timer.

                          ` wait_time=(<suspend period>)
                          times=(how many times you want to repeat <some code>)
                          timer_id=UI.start_timer(wait_time,true) {
                          <some code> # put some geometry to active_model
                          times -=1 # decrement times to be able to stop timer
                          Sketchup.active_model.active_view.invalidate

                          do not forget to stop timer

                          timer_id=UI.stop_timer timer_id if times==0
                          }`

                          I noticed, that visual results of <some code> processing appears even without view.invalidate. Note, that <some code> appears to work a kind of 'transparent' way (you may zoom, pan, rotate view and even launch other commands during the timer processing).Such behaviour indicates, that during <suspend period> all possible events (mouse events, key stroke events and so on) rise and you can handle them.
                          Hope that helps.

                          1 Reply Last reply Reply Quote 0
                          • 1 / 1
                          • First post
                            Last post
                          Buy SketchPlus
                          Buy SUbD
                          Buy WrapR
                          Buy eBook
                          Buy Modelur
                          Buy Vertex Tools
                          Buy SketchCuisine
                          Buy FormFonts

                          Advertisement