Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    How to get horizontal field of view angle?

    Scheduled Pinned Locked Moved PYTHON Development
    5 Posts 0 Posters 675 Views
    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.
    • H Offline
      Helper
      last edited by

      On 05/07/2017 at 03:57, xxxxxxxx wrote:

      How do I get the horizontal field of view angle of the current view?

      My first attempt looks like this:

      import c4d
        
      def main() :
          doc = c4d.documents.GetActiveDocument()
          rbd = doc.GetRenderBaseDraw()
          cameraObject = rbd.GetSceneCamera(doc)
        
          print("cameraObject[c4d.CAMERAOBJECT_FOV] = " + str(cameraObject[c4d.CAMERAOBJECT_FOV]))
          print("cameraObject[c4d.CAMERAOBJECT_FOV_VERTICAL] = " + str(cameraObject[c4d.CAMERAOBJECT_FOV_VERTICAL]))
          fov2 = (360.0 / (2 * 3.1415926535897932384626433832795)) * cameraObject[c4d.CAMERAOBJECT_FOV]
          print("Horizontal fov in deg: " + str(fov2))
          
        
      if __name__=='__main__':
          main()
      

      _<_img src="http://vertexwahn.de/c4dfov.png" height="1400" width="2560" border="0" /_>_

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 05/07/2017 at 07:20, xxxxxxxx wrote:

        First attempt to compute the "big" fov:

        import c4d
        import math
          
        def main() :
            doc = c4d.documents.GetActiveDocument()
            rbd = doc.GetRenderBaseDraw()
            cameraObject = rbd.GetSceneCamera(doc)
            
            bd = doc.GetRenderBaseDraw()
            frame = bd.GetFrame()
            xresolution = frame["cr"] - frame["cl"] + 1
            yresolution = frame["cb"] - frame["ct"] +1
                
            renderData = doc.GetActiveRenderData()
            renderDataBc = renderData.GetDataInstance()
            
            smallFov = cameraObject[c4d.CAMERAOBJECT_FOV]
            print("SmallFov = " + str(c4d.utils.Deg(smallFov)))
          
            bigFov = (smallFov / renderDataBc[c4d.RDATA_XRES]) * xresolution
            print("BigFov = " + str(c4d.utils.Deg(bigFov)))
          
        if __name__=='__main__':
            main()
        

        Situation is better now, but it does not fit perfectly

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 05/07/2017 at 07:26, xxxxxxxx wrote:

          _<_img src="http://vertexwahn.de/c4dbigfov.png" height="1388" width="1772" border="0" /_>_

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 05/07/2017 at 08:08, xxxxxxxx wrote:

            Changed my computation - see bigFov2

            import c4d
            import math
              
            def main() :
                doc = c4d.documents.GetActiveDocument()
                rbd = doc.GetRenderBaseDraw()
                cameraObject = rbd.GetSceneCamera(doc)
                
                bd = doc.GetRenderBaseDraw()
                frame = bd.GetFrame()
                xresolution = frame["cr"] - frame["cl"] + 1
                yresolution = frame["cb"] - frame["ct"] +1
                    
                renderData = doc.GetActiveRenderData()
                renderDataBc = renderData.GetDataInstance()
                
                smallFov = cameraObject[c4d.CAMERAOBJECT_FOV]
                print("SmallFov = " + str(c4d.utils.Deg(smallFov)))
              
                bigFov = (smallFov / renderDataBc[c4d.RDATA_XRES]) * xresolution
                print("BigFov = " + str(c4d.utils.Deg(bigFov)))
                
                imagePlaneDistance = (renderDataBc[c4d.RDATA_XRES]*0.5) / math.tan(smallFov * 0.5)
                print(imagePlaneDistance)
                
                bigFov2 = math.atan( (xresolution*0.5) / (imagePlaneDistance) ) * 2
                print("BigFov2 = " + str(c4d.utils.Deg(bigFov2)))
                
            if __name__=='__main__':
                main()
            

            no everything looks better:

            Is there maybe a better/more clean way to find out the "Big" fov. I am a bit confused by the different image plane sizes ( renderDataBc[c4d.RDATA_XRES] vs. xresolution = frame["cr"] - frame["cl"] + 1

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 06/07/2017 at 09:19, xxxxxxxx wrote:

              Hi,

              welcome to the Plugin Café forums 🙂

              Your very last question first:
              The sizes are different, because in render settings (RenderData) it is the actual size of the final render. The view port on the other hand may have completely different aspect ratio, that's why there are the grey areas on the left and right (or top and bottom). And of course the resolution of the view port is also completely different (in most cases) from the final render resolution. The part of the view port which matches the final render (the non grey part) is returned by GetSafeFrame() instead of GetFrame().

              In order to get the FOV for the of the entire view port (yellow line in your first screenshot), I'd actually cheat by cloning the current render settings, setting its resolution to the size returned by GetFrame() and making it active. Then you could use your first code snippet. Afterwards throw away the extra render settings and make the previous one active again.

              1 Reply Last reply Reply Quote 0
              • First post
                Last post