sketchucation logo sketchucation
    • Login
    🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    How can I run code on view-change

    Scheduled Pinned Locked Moved Developers' Forum
    8 Posts 4 Posters 330 Views 4 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.
    • onidarbeO Offline
      onidarbe
      last edited by

      Hi,

      Can code keep on running in the background or can plugins only be run from a user command and need to finish before you can continue to work on the model?

      Or how can I write a Ruby plugin that is some event, like changing the viewing-angle?

      thank you

      1 Reply Last reply Reply Quote 0
      • Dan RathbunD Offline
        Dan Rathbun
        last edited by

        Event driven is best for a GUI application. (Responding to what the user is doing.)

        This is done in SketchUp Ruby with observers. Check out all the various observer classes.. which have event callbacks that the SketchUp engine will call.

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • onidarbeO Offline
          onidarbe
          last edited by

          thanks!

          1 Reply Last reply Reply Quote 0
          • onidarbeO Offline
            onidarbe
            last edited by

            I found out how to trigger a method when the viewing angle has changed, but I can't seem to find how to know in which viewing direction the window is.

            `

            class MyViewObserver < Sketchup;;ViewObserver
              def onViewChanged(view)
                puts view.camera.eye.to_s
              end
            end
            
            Sketchup.active_model.active_view.add_observer(MyViewObserver.new)
            

            `

            I would like to know the current viewing angle X, Y, Z and compare this to a face if that face is visible on that side or not.

            Any idea how to do that?

            thanks

            1 Reply Last reply Reply Quote 0
            • jolranJ Offline
              jolran
              last edited by

              Just a sidenote. If you are only after watching orbiting, you could use tool resume(view) method. It fires after orbiting or pan and zoom as well. Then you might not need any observer.
              You could set a methodcall in there instead..

              What do you mean face visible ? Reversed ?

              Havent done any code for checking face reversed, so I'm just speculating.
              I'd reckon it will be unpredictable. Think there are some plugins for this already?
              Maybe TIG's orient faces or such..

              But you could project a ray(view pickray I think?) to the face and compare that vector to the face.normal to within some tolerance. That tolerance would be the hard part, I guess.
              But needed since view ray will not be parallel to the face normal all of the time..
              Then set conditions comparing vector directions.

              1 Reply Last reply Reply Quote 0
              • TIGT Offline
                TIG Moderator
                last edited by

                The camera has a .eye and a .target
                direction = camera.eye.vector_to(camera.target)
                BUT there's also the simpler:
                direction = camera.direction
                Now the face has a a vector 'normal':
                normal = face.normal
                If the angle between the 'direction' and the 'normal' are < 90.degrees then you are either 'behind' the face looking towards it, or 'in front' of it looking away from it. At == 90.degrees you are 'edge on'.
                ` angle = direction.angle_between(normal)
                facing = true if if angle > 90.degrees

                etc`

                If you are checking that the camera is looking 'directly at' the face... then use
                rayt = model.raytest([camera.eye, direction])
                this return nil if no hit at all, or a [point, array_of_objects] - the hit = rayt[1][-1] return what was hit, so:
                ` if hit == face || face.edges.include?(hit)

                etc`

                This tells you if the camera is looking at the face and from the 'angle' if the face is facing the camera or turned away from it...

                Additional raytesting can also check for intervening objects if you want them to be considered 'transparent'...
                ` ### Make a loop...
                rayt = model.raytest([camera.eye, direction])
                while rayt || rayt[1][-1] != face
                rayt = model.raytest([rayt[0], direction])
                end

                after the loop...

                hit = true if rayt && rayt[1][-1] == face This keeps 'mining' through until it hits nothing ' nil' OR ' face' is encountered, THEN if needed check the angle > 90.degrees` etc

                TIG

                1 Reply Last reply Reply Quote 0
                • jolranJ Offline
                  jolran
                  last edited by

                  Nice. I knew someone had done this..
                  That looks like it will be fairly predictable ?

                  1 Reply Last reply Reply Quote 0
                  • onidarbeO Offline
                    onidarbe
                    last edited by

                    thanks!

                    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