• Login
sketchucation logo sketchucation
  • Login
⚠️ Libfredo 15.4b | Minor release with bugfixes and improvements Update

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.
  • O Offline
    onidarbe
    last edited by 29 Dec 2013, 22:28

    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
    • D Offline
      Dan Rathbun
      last edited by 30 Dec 2013, 09:19

      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
      • O Offline
        onidarbe
        last edited by 31 Dec 2013, 17:25

        thanks!

        1 Reply Last reply Reply Quote 0
        • O Offline
          onidarbe
          last edited by 1 Jan 2014, 17:56

          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
          • J Offline
            jolran
            last edited by 2 Jan 2014, 13:46

            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
            • T Online
              TIG Moderator
              last edited by 2 Jan 2014, 15:00

              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
              • J Offline
                jolran
                last edited by 2 Jan 2014, 15:11

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

                1 Reply Last reply Reply Quote 0
                • O Offline
                  onidarbe
                  last edited by 3 Jan 2014, 12:06

                  thanks!

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

                  Advertisement