Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    Frame selected objects correctly in camera

    Cinema 4D SDK
    python r19
    2
    13
    2.6k
    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.
    • A
      AndreAnjos
      last edited by AndreAnjos

      Hi all,

      Having trouble rendering objects without being clipped.
      Does anyone got a solution for this?

      Thank you in advance! ☺

      for count, obj in enumerate(objs_lst, start=1):
      
          doc.SetActiveObject(obj)
          c4d.DrawViews(c4d.DRAWFLAGS_NO_THREAD | c4d.DRAWFLAGS_FORCEFULLREDRAW)
          c4d.CallCommand(12151)
          cam.Message(c4d.MSG_UPDATE)
      
          obj.SetLayerObject(layer)
          doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_SET)
      
          render_set = doc.GetFirstRenderData()
          obj_name = doc.GetDocumentName().split('.')[0] + '_' + obj.GetName()
          render_set[c4d.RDATA_PATH] = 'C:/Users/anjosa/Desktop/renders/{0}'.format(obj_name)
      
          rs = doc.GetFirstRenderData().GetData()
          x_res = int(rs[c4d.RDATA_XRES])
          y_res = int(rs[c4d.RDATA_YRES])
      
          bmp = bitmaps.BaseBitmap()
          bmp.Init(x=x_res, y=y_res, depth=24)
          documents.RenderDocument(doc, rs, bmp, c4d.RENDERFLAGS_EXTERNAL)
          c4d.bitmaps.ShowBitmap(bmp)
      
          bd.Message(c4d.MSG_CHANGE)
          obj.SetLayerObject(None)
          print('{0} / {1} - {2} - Render Done!'.format(count, count_total, obj.GetName()))
      
      layer.Remove()
      doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_CLEAR)
      cam.Remove()
      
      c4d.EventAdd()
      
      

      Andre

      1 Reply Last reply Reply Quote 0
      • r_giganteR
        r_gigante
        last edited by

        Hi Andres,

        can you elaborate more on "Having trouble rendering objects without being clipped."? Do you have also a scene to replicate the behavior?

        Cheers, Riccardo

        1 Reply Last reply Reply Quote 0
        • A
          AndreAnjos
          last edited by AndreAnjos

          Hi Riccardo,

          Absolutely! ☺ (and apologies)

          I want to iterate through all of the scene polygon objects and render it to separate images.
          I want the objects to be isolated from the rest and framed into camera before the render is created.

          Now, the problem I'm having is that the camera framing is not working accordingly with the c4d.CallCommand(12151).
          So all of the renders are done with the objects rendered in the same position in relationship to the camera and clipped, as per the render tests below.
          Main.png Glass.png
          It could be something I'm forgetting to add, as I couldn't find an example that can help me.

          Here's my example scene: scene_example.c4d

          Thank you in advance! ☺

          Andre

          1 Reply Last reply Reply Quote 0
          • r_giganteR
            r_gigante
            last edited by

            Hi AndreAnjos, thanks for following up here.

            With regard to your question I forward you to this post inherited in the Legacy forum.

            In the proposed solution from Niklas, it's presented a solution to render just one object (the active object). Extending the code to run over all the scene objects is pretty straightforward.

            Best, Riccardo

            1 Reply Last reply Reply Quote 1
            • A
              AndreAnjos
              last edited by

              @r_gigante
              Thank you for your help! ☺

              To be honest I did follow Niklas code before and was trying to adapt it to mine. It didn't work at the time and I'm going to give it another go just in case I missed something.

              I will add my conclusion or questions along the way.

              Thanks again! 👍

              1 Reply Last reply Reply Quote 0
              • r_giganteR
                r_gigante
                last edited by

                Hi AndreAnjos,

                actually before pointing to Niklas' post I tried it and I tested it and actually worked properly. What issue are experiencing?

                Cheers, Riccardo

                A 2 Replies Last reply Reply Quote 0
                • A
                  AndreAnjos @r_gigante
                  last edited by AndreAnjos

                  @r_gigante
                  Hi Riccardo,
                  Using Niklas script by itself works fine, which it does look like an improvement to mine anyway.
                  But before I can definitely check that it works fine inside my code, I'm going to try and add a few other things.

                  For example: We have a lot of legacy files that I don't have a clue of how it's scenes are organised. The only thing I know is they're messy. In terms of hierarchy and also how the axis for each object are positioned. So, I'm doing a bit of guess work in trying to frame the objects into a temporary camera where it can been seen in a position and be identify for what it is.

                  So Niklas script will help frame the objects, but at the moment is not working well for a position that would show what the object is.
                  That's the reason why I will need more testing and come back with the more information. Perhaps than I can actually tell you if my initial issue is valid.

                  Sorry for the long explanation, but hopefully it will make some sense!

                  Thank you! ☺

                  Andre

                  1 Reply Last reply Reply Quote 0
                  • A
                    AndreAnjos @r_gigante
                    last edited by AndreAnjos

                    @r_gigante
                    I do have a question related more with the way that Niklas is dealing with memory in he's script, if you don't mind.

                    If I'm not mistaken, Niklas isolates the object by creating a context document where he will copy the cloned object to, render it and then kill the document.
                    While at the moment I'm thinking more in the lines of isolating the object by inserting into the layer and solo the layer instead.

                    How would my thinking would differ in efficiency in relationship to Niklas idea, please?
                    This would be great to understand!

                    Thank you in advance! ☺

                    Edit: Found this thread with useful information: https://developers.maxon.net/forum/topic/6903/7745_eventadd-doesnt-update-c4d

                    1 Reply Last reply Reply Quote 0
                    • A
                      AndreAnjos
                      last edited by AndreAnjos

                      Hi again,

                      So I've been trying to make it work and I feel I'm getting closer, but there are still some problems.
                      I have to thank Niklas for providing the majority of it and of course he will be credit appropriately.

                      import c4d
                      
                      class Remember(object) :
                          """ Remembers the hierarchy position of a node and can restore
                          it at a later time. A ``root_routine`` is required when the node
                          was the first and only node in the list. """
                      
                          def __init__(self, node):
                              super(Remember, self).__init__()
                              self.parent = node.GetUp()
                              self.pred = node.GetPred()
                      
                          def restore(self, node, root_routine) :
                              node.Remove()
                              if self.pred:
                                  node.InsertAfter(self.pred)
                              elif self.parent:
                                  node.InsertUnder(self.parent)
                              else:
                                  root_routine(node)
                      
                      
                      class DocumentContext(object):
                          """ Context manager for a temporary document that will be inserted
                          when entering the context and \*killed\* when leaving the context. The
                          document can and must not be used after the context was left.
                      
                          Inside the context, the document is inserted and active. """
                      
                          def __init__(self, doc=None):
                              if not doc:
                                  doc = c4d.documents.BaseDocument()
                              elif not isinstance(doc, c4d.documents.BaseDocument) :
                                  raise TypeError('expected BaseDocument')
                      
                              super(DocumentContext, self).__init__()
                              self.doc = doc
                      
                          def __enter__(self):
                              c4d.documents.InsertBaseDocument(self.doc)
                              c4d.documents.SetActiveDocument(self.doc)
                              return self.doc
                      
                          def __exit__(self, exc_type, exc_value, exc_tb):
                              c4d.documents.KillDocument(self.doc)
                      
                      def get_poly_objs(op, lst):
                      
                          while op:
                      
                              if c4d.GetObjectName(op.GetType()) == 'Polygon':
                      
                                  lst.append(op)
                      
                              get_poly_objs(op.GetDown(), lst)
                              op = op.GetNext()
                      
                          return lst
                      
                      def render_settings():
                      
                          # Global Settings
                          render_set = doc.GetFirstRenderData()
                          render_set[c4d.RDATA_RENDERENGINE] = 300001061  # Hardware OpenGL
                          render_set[c4d.RDATA_LOCKRATIO] = True
                          render_set[c4d.RDATA_FILMASPECT] = 1.0
                          render_set[c4d.RDATA_FRAMERATE] = 24
                          render_set[c4d.RDATA_FRAMESEQUENCE] = 1
                          render_set[c4d.RDATA_GLOBALSAVE] = True
                          render_set[c4d.RDATA_MULTIPASS_ENABLE] = False
                          render_set[c4d.RDATA_SAVEIMAGE] = True
                          render_set[c4d.RDATA_FORMAT] = 1023671  # .PNG format
                      
                          # Hardware OpenGL Settings
                          gl_render = render_set.GetFirstVideoPost()
                          gl_render[c4d.VP_PREVIEWHARDWARE_ANTIALIASING] = 16
                          gl_render[c4d.VP_PREVIEWHARDWARE_SUPERSAMPLING] = 1
                      
                          doc.SetTime(c4d.BaseTime(0, 24))
                          c4d.EventAdd()
                      
                      def force_redraw():
                      
                          flags = c4d.DRAWFLAGS_NO_THREAD | c4d.DRAWFLAGS_FORCEFULLREDRAW
                          c4d.DrawViews(flags)
                      
                      def render_document(doc, op, width, height, depth=24):
                      
                          render_set = doc.GetFirstRenderData()
                          op_name = doc.GetDocumentName().split('.')[0] + '_' + op.GetName()
                          render_set[c4d.RDATA_PATH] = 'C:/Users/anjosa/Desktop/renders/{0}'.format(op_name)
                      
                          bmp = c4d.bitmaps.BaseBitmap()
                          bmp.Init(x=width, y=width, depth=depth)
                      
                          rdc = doc.GetActiveRenderData().GetData()
                          rdc[c4d.RDATA_XRES] = width
                          rdc[c4d.RDATA_YRES] = height
                      
                          c4d.documents.RenderDocument(doc, rdc, bmp, c4d.RENDERFLAGS_EXTERNAL)
                          return bmp
                      
                      def render_object(op, width, height):
                      
                          def test_point_in_frame(pt, frame):
                      
                              return pt.x > frame['cl'] and pt.x < frame['cr'] and \
                                     pt.y > frame['ct'] and pt.y < frame['cb']
                      
                          def check_if_in_view(obj, bd):
                              safe_frame = bd.GetSafeFrame()
                      
                              # Get the active object bounding box center and radius
                              box = [c4d.Vector() for x in xrange(8)]
                              rd = obj.GetRad()
                              mp = obj.GetMp()
                      
                              # Build the active object bouding box
                              box[0].x = mp.x - rd.x
                              box[0].y = mp.y - rd.y
                              box[0].z = mp.z - rd.z
                              box[0] *= obj.GetMgn()
                      
                              box[1].x = mp.x - rd.x
                              box[1].y = mp.y + rd.y
                              box[1].z = mp.y - rd.z
                              box[1] *= obj.GetMgn()
                      
                              box[2].x = mp.x + rd.x
                              box[2].y = mp.y - rd.y
                              box[2].z = mp.y - rd.z
                              box[2] *= obj.GetMgn()
                      
                              box[3].x = mp.x + rd.x
                              box[3].y = mp.y + rd.y
                              box[3].z = mp.y - rd.z
                              box[3] *= obj.GetMgn()
                      
                              box[4].x = mp.x + rd.x
                              box[4].y = mp.y - rd.y
                              box[4].z = mp.z + rd.z
                              box[4] *= obj.GetMgn()
                      
                              box[5].x = mp.x + rd.x
                              box[5].y = mp.y + rd.y
                              box[5].z = mp.y + rd.z
                              box[5] *= obj.GetMgn()
                      
                              box[6].x = mp.x - rd.x
                              box[6].y = mp.y - rd.y
                              box[6].z = mp.y + rd.z
                              box[6] *= obj.GetMgn()
                      
                              box[7].x = mp.x - rd.x
                              box[7].y = mp.y + rd.y
                              box[7].z = mp.y + rd.z
                              box[7] *= obj.GetMgn()
                      
                              # Calculate bouding box coordinates in screen space
                              points = [bd.WS(p) for p in box]
                      
                              # Test if the current object is completely visible in the rendered safe frame
                              for i in xrange(len(points)):
                                  if not test_point_in_frame(points[i], safe_frame):
                                      return False
                      
                              return True
                      
                          def escaped_pressed(bc=None):
                              if bc is None:
                                  bc = c4d.BaseContainer()
                                  c4d.gui.GetInputEvent(c4d.BFM_INPUT_KEYBOARD, bc)
                              return bc[c4d.BFM_INPUT_CHANNEL] == c4d.KEY_ESC
                      
                          def move_object_rel(op, axis, offset):
                      
                              axis = axis.GetNormalized()
                              axis.off = op.GetRelPos()
                              op.SetRelPos(axis * offset)
                      
                          doc = op.GetDocument()
                          if not doc:
                              raise ValueError('op is not in a document')
                      
                          # Remember the original position of \*op\* in the hierarchy and
                          # remove it from the tree.
                          location = Remember(op)
                          op.Remove()
                      
                          # Put all the objects in the document into a Null-Object that
                          # we will keep separate.
                          root_null = c4d.BaseObject(c4d.Onull)
                          for obj in reversed(doc.GetObjects()):
                              obj.Remove()
                              obj.InsertUnder(root_null)
                      
                          # Insert it into the document again. Then we clone it to get a
                          # document with all the materials that the object referenced.
                          doc.InsertObject(op)
                          new_doc = doc.GetClone(c4d.COPYFLAGS_0)
                      
                          # Restore the structure of the original document.
                          for obj in reversed(root_null.GetChildren()):
                              obj.Remove()
                              doc.InsertObject(obj)
                          root_null.Remove()
                          location.restore(op, root_routine=doc.InsertObject)
                      
                          with DocumentContext(new_doc):
                              new_doc.SetActiveObject(new_doc.GetFirstObject())
                              force_redraw()  # Redraw is required to create the Geometry
                              c4d.CallCommand(12151)  # Frame Selected Objects
                              new_doc.SetActiveObject(new_doc.GetFirstObject(), c4d.SELECTION_SUB)
                      
                              bd = new_doc.GetActiveBaseDraw()
                              bd[c4d.BASEDRAW_DISPLAYFILTER_GRID] = False
                              bd[c4d.BASEDRAW_DISPLAYFILTER_HORIZON] = False
                              bd[c4d.BASEDRAW_DISPLAYFILTER_WORLDAXIS] = False
                              bd[c4d.BASEDRAW_DISPLAYFILTER_NULL] = False
                              bd.Message(c4d.MSG_CHANGE)
                      
                              cam = bd.GetSceneCamera(new_doc)
                              cam_pos = cam.GetAbsPos()
                              pos = op.GetAbsPos()
                              axis_cam = cam.GetMg()
                              offset = c4d.Vector(0, 0, 10)
                      
                              # Create an undo-state for the camera because we will offset it.
                              new_doc.AddUndo(c4d.UNDOTYPE_CHANGE, cam)
                              c4d.StatusSetSpin()
                      
                              passes = 0
                              stopped = False
                              while not check_if_in_view(op, bd):
                      
                                  stopped = escaped_pressed()
                                  if stopped:
                                      break
                      
                                  move_object_rel(op, axis_cam, offset)
                                  passes += 1
                      
                              delta = op.GetAbsPos() - pos
                              op.SetAbsPos(pos)
                      
                              if not stopped:
                                  cam_pos -= delta
                              cam.SetAbsPos(cam_pos)
                      
                              c4d.StatusClear()
                              c4d.EventAdd()
                      
                              return render_document(new_doc, op, width, height)
                      
                      def main():
                          render_settings()
                          first_obj = doc.GetFirstObject()
                          objs_lst = []
                          objs_lst = get_poly_objs(first_obj, objs_lst)
                          count_total = len(objs_lst)
                          
                          if not objs_lst:
                              c4d.gui.MessageDialog('No polygon objects in the scene!')
                              c4d.StatusSetText('No polygon objects in the scene!')
                              return False
                          
                          for count, obj in enumerate(objs_lst, start=1):
                          
                              bmp = render_object(obj, 256, 256)
                              c4d.bitmaps.ShowBitmap(bmp)
                          
                              print('{0} / {1} - {2} - Render Done!'.format(count, count_total, obj.GetName()))
                          
                          c4d.StatusClear()
                          c4d.EventAdd()
                          
                          c4d.gui.MessageDialog('Renders Done!')
                          c4d.StatusSetText('Renders Done!')
                      
                      if __name__=='__main__':
                          main()
                      

                      Logically the code makes sense to me in everything is doing, but is still not working accordingly, which lets me to believe that I'm not doing something right that I can't no longer see or understand.

                      If you try this code with the file that I've attached to this thread you will probably see that is not actually showing the full model in the view.
                      The other issue I'm having is the case of the model being outside of the safe frame, he will continue running the check_if_in_view() function for a very long time and at the end the model is not rendered correctly.

                      Thank you again for your help!
                      I hope this can be informative for other people as well ☺

                      Andre

                      1 Reply Last reply Reply Quote 0
                      • r_giganteR
                        r_gigante
                        last edited by

                        Hi AndreAnjos, thanks for following up here.

                        I've tested your scene and I do see the issues you've mentioned but I don't get the need for the additional code (that's actually causing the issue) responsible for zooming out things that are not completely in the camera frustum.

                        But I think that beside moving out on the camera Z-axis, you should consider moving the camera also on X and Y -to re-center the object - otherwise you might get issues with geometry being-clipped since you're simple moving away from the object and zooming back on it to get it in the SafeFrame area.

                        Best, Riccardo

                        PS. With regard the layer approach, if properly delivered I don't see that much difference in the final result.

                        1 Reply Last reply Reply Quote 0
                        • A
                          AndreAnjos
                          last edited by AndreAnjos

                          @r_gigante
                          Hi Riccardo,
                          Thanks for coming back to me!

                          I've tested your scene and I do see the issues you've mentioned but I don't get the need for the additional code (that's actually causing the issue) responsible for zooming out things that are not completely in the camera frustum.

                          The reason I thought about adding the zooming out code, was mainly to do with the fact when frame object command runs, it frames on your frame frustum and not your safe frame frustum (if I'm not missing anything). It will clip the object anyway. So the need to move the camera or object is necessary, I think.

                          But I think that beside moving out on the camera Z-axis, you should consider moving the camera also on X and Y -to re-center the object - otherwise you might get issues with geometry being-clipped since you're simple moving away from the object and zooming back on it to get it in the SafeFrame area.

                          Yes I completely get what you are saying with moving the camera on the other axis. Something i need to learn. ☺

                          PS. With regard the layer approach, if properly delivered I don't see that much difference in the final result.

                          Awesome! Thank you! ☺
                          Will keep this alive until I find the best working solution.

                          Andre

                          1 Reply Last reply Reply Quote 0
                          • A
                            AndreAnjos
                            last edited by AndreAnjos

                            Hi all,

                            Apologies for the delay, but only had time to revisit this issue this week.
                            So I found the solution and thought about posting here for other people. It's probably not the best one, but it works for me and I'm happy with the final results.

                            Like to thank Niklas, Scott and Riccardo for helping with this, as a lot of the information came from them, which I just adapted.
                            So this is developed to render with Octane, but you can change to whatever render settings you need.

                            """
                            The script is a blend of techniques that I found to be working at the end.
                            It starts by getting all of the polygon object in the scene, iterating through each object and soloing it in a layer.
                            Creates the objects, camera, materials and render settings for the environment.
                            Focus the object first before calculating if all of the object is in the scene.
                            Because the camera has a target tag connected to a moving null that sits under each object is rendering, the position reaches a conclusion when object is inside the camera frame.
                            I didn't want to create a new thread to run the script as I prefer the user not be using cinema and let it run. We can't afford to have Cinema crashing at the same time.
                            """
                            
                            import c4d
                            
                            def get_op(op, name):
                            
                                while op:
                                    if op.GetName() == name:
                            
                                        return op
                            
                                    get_op(op.GetDown(), name)
                                    op = op.GetNext()
                                    
                            def get_mat(op, name):
                            
                                while op:
                                    if op.GetName() == name:
                            
                                        return op
                            
                                    get_op(op.GetDown(), name)
                                    op = op.GetNext()
                                    
                            def get_op_type(op, name, lst):
                            
                                while op:
                                    if op.GetTypeName() == name:
                            
                                        lst.append(op)
                            
                                    get_op_type(op.GetDown(), name, lst)
                                    op = op.GetNext()
                            
                                return lst
                                    
                            def get_vp(op, name):
                            
                                while op:
                                    if op.GetName() == name:
                            
                                        return op
                            
                                    op = op.GetNext()
                                    
                            def create_obj(op_type, name):
                                
                                op = c4d.BaseObject(op_type)
                                op.SetName(name)
                                doc.InsertObject(op)
                                
                                return op
                            
                            def create_render(doc):
                                
                                rd = c4d.documents.RenderData()
                                doc.InsertRenderData(rd)
                                doc.SetActiveRenderData(rd) 
                                rd.SetName('Temp_BP')
                                rd[c4d.RDATA_RENDERENGINE] = 1029525
                                oct_render_vp = c4d.documents.BaseVideoPost(1029525)
                                rd.InsertVideoPost(oct_render_vp)
                                rd[c4d.RDATA_XRES] = 540
                                rd[c4d.RDATA_YRES] = 540
                                rd[c4d.RDATA_LOCKRATIO] = True
                                rd[c4d.RDATA_FILMASPECT] = 1.0
                                rd[c4d.RDATA_FRAMESEQUENCE] = 1
                                rd[c4d.RDATA_FRAMERATE] = 24
                            
                                # Save
                                rd[c4d.RDATA_GLOBALSAVE] = True
                                rd[c4d.RDATA_SAVEIMAGE] = True
                                rd[c4d.RDATA_FORMAT] = c4d.FILTER_PNG
                                rd[c4d.RDATA_NAMEFORMAT] = 6
                                rd[c4d.RDATA_FORMATDEPTH] = 1
                                
                                # Octane Renderer
                                oct_render_vp[c4d.SET_PASSES_ENABLED] = False
                                oct_render_vp[c4d.VP_UPDATE_MATERIALS_MODE] = False
                                oct_render_vp[1013] = 0
                                oct_render_vp[c4d.VP_BUFFER_TYPE] = 2
                                
                                oct_render_vp[c4d.VP_KERNEL_ENABLE] = True
                                oct_render_vp[c4d.SET_DIRECT_MAXSAMPLES] = 1000
                                oct_render_vp[c4d.SET_DIRECT_SPECDEPTH] = 3
                                oct_render_vp[c4d.SET_DIRECT_AODIST] = 0.3
                                oct_render_vp[c4d.SET_DIRECT_ALPHACHAN] = True
                                oct_render_vp[c4d.SET_DIRECT_KEEPENV] = False
                                oct_render_vp[c4d.SET_DIRECT_ADAPTIVE_SAMPLING] = True
                                oct_render_vp[c4d.SET_DIRECT_ASAMP_EXP_EXPOSURE] = 1.0
                                
                                # Watermark
                                watermark_vp = c4d.documents.BaseVideoPost(1025462)
                                rd.InsertVideoPostLast(watermark_vp)
                                watermark_vp[c4d.VP_WATERMARK_TEXT_ENABLE] = True
                                watermark_vp[c4d.VP_WATERMARK_TEXT_SHOWLABELS] = False
                                watermark_vp[c4d.VP_WATERMARK_TEXT_RENDERTIME] = False
                                watermark_vp[c4d.VP_WATERMARK_TEXT_DATE] = False
                                watermark_vp[c4d.VP_WATERMARK_TEXT_BG_OPACITY] = 1.0
                                
                                rd.Message(c4d.MSG_UPDATE)
                                
                                return (rd, watermark_vp)
                            
                            def TestPointInFrame(pt, frame):
                                
                                return pt.x > frame['cl'] and pt.x < frame['cr'] and pt.y > frame['ct'] and pt.y < frame['cb']  
                                
                            def CheckIfInView(cam, obj, doc):
                                # Get the current BaseDraw  
                                bd = doc.GetActiveBaseDraw()  
                                safeFrame = bd.GetSafeFrame()  
                                    
                                # Get the active object bouding box center and radius  
                                
                                box = [c4d.Vector() for x in xrange(8)]  
                                points = [c4d.Vector() for x in xrange(8)]          
                                
                                
                                rd = obj.GetRad()  
                                mp = obj.GetMp()  
                                
                                # Build the active object bouding box  
                                
                                box[0] = c4d.Vector()  
                                box[0].x = mp.x - rd.x  
                                box[0].y = mp.y - rd.y  
                                box[0].z = mp.z - rd.z  
                                box[0] *= obj.GetMgn()  
                                
                                box[1] = c4d.Vector()  
                                box[1].x = mp.x - rd.x  
                                box[1].y = mp.y + rd.y  
                                box[1].z = mp.y - rd.z  
                                box[1] *= obj.GetMgn()  
                                
                                box[2] = c4d.Vector()  
                                box[2].x = mp.x + rd.x  
                                box[2].y = mp.y - rd.y  
                                box[2].z = mp.y - rd.z  
                                box[2] *= obj.GetMgn()  
                                
                                box[3] = c4d.Vector()  
                                box[3].x = mp.x + rd.x  
                                box[3].y = mp.y + rd.y  
                                box[3].z = mp.y - rd.z  
                                box[3] *= obj.GetMgn()  
                                
                                box[4] = c4d.Vector()  
                                box[4].x = mp.x + rd.x  
                                box[4].y = mp.y - rd.y  
                                box[4].z = mp.z + rd.z  
                                box[4] *= obj.GetMgn()  
                                
                                box[5] = c4d.Vector()  
                                box[5].x = mp.x + rd.x  
                                box[5].y = mp.y + rd.y  
                                box[5].z = mp.y + rd.z  
                                box[5] *= obj.GetMgn()  
                                
                                box[6] = c4d.Vector()  
                                box[6].x = mp.x - rd.x  
                                box[6].y = mp.y - rd.y
                                box[6].z = mp.y + rd.z
                                box[6] *= obj.GetMgn()  
                                
                                box[7] = c4d.Vector()  
                                box[7].x = mp.x - rd.x
                                box[7].y = mp.y + rd.y
                                box[7].z = mp.y + rd.z
                                box[7] *= obj.GetMgn()
                                
                                # Calculate bouding box coordinates in screen space  
                                
                                for i in xrange(len(box)):
                                  points[i] = bd.WS(box[i])  
                                
                                # Test if the current object is completely visible in the rendered safe frame  
                                
                                for i in xrange(len(points)):
                                  visible = TestPointInFrame(points[i], safeFrame)  
                                  if not visible:
                                      break  
                                    
                                return visible
                            
                            def escaped_pressed(bc=None):
                                if bc is None:
                                    bc = c4d.BaseContainer()
                                    c4d.gui.GetInputEvent(c4d.BFM_INPUT_KEYBOARD, bc)
                                return bc[c4d.BFM_INPUT_CHANNEL] == c4d.KEY_ESC
                            
                            def main():
                                
                                doc = c4d.documents.GetActiveDocument()
                                first_obj = doc.GetFirstObject()
                                first_mat = doc.GetFirstMaterial()
                                sku_layer = first_obj.GetLayerObject(doc)
                                objs_lst = get_op_type(first_obj, 'Polygon', [])
                                count_total = len(objs_lst)
                                
                                rs, water_vp = create_render(doc)
                                
                                cam = get_op(first_obj, 'Temp_Cam')
                                bg = get_op(first_obj, 'BG')
                                mat = get_mat(first_mat, 'BG_Mat')
                                trg_null = get_mat(first_mat, 'Cam_Target')
                                
                                if cam == None:
                                    
                                    cam = create_obj(c4d.Ocamera, 'Temp_Cam')
                                    oct_cam_tag = cam.MakeTag(1029524)  # Octane Camera tag
                                    oct_cam_tag[c4d.OCTANECAMERA_ENABLE_IMAGER] = True
                                    oct_cam_tag[c4d.OCTANECAMERA_PREMALPHA] = True
                                    trg_tag = cam.MakeTag(c4d.Ttargetexpression)
                                    
                                    if trg_null == None:
                                        
                                        trg_null = create_obj(c4d.Onull, 'Cam_Target')
                                        trg_tag[c4d.TARGETEXPRESSIONTAG_LINK] = trg_null
                                    
                                if bg == None:
                                    
                                    bg = create_obj(c4d.Obackground, 'BG')
                                    tex_tag = bg.MakeTag(c4d.Ttexture)
                                    
                                    if mat == None:
                                        
                                        mat = c4d.BaseMaterial(1029501)
                                        mat.SetName('BG_Mat')
                                        shader = c4d.BaseList2D(1011100)
                                        shader[c4d.SLA_GRADIENT_TYPE] = 2002  # Type 2D - Diagonal
                                        grad = shader[c4d.SLA_GRADIENT_GRADIENT]
                                        grad.FlushKnots()
                                        k1 = grad.InsertKnot(col=c4d.Vector(0.5, 0.5, 0.5), pos=0.25, index = 0)
                                        k2 = grad.InsertKnot(col=c4d.Vector(0.25, 0.25, 0.25), pos=0.75, index= 1)
                                        shader[c4d.SLA_GRADIENT_GRADIENT] = grad
                                        mat[c4d.OCT_MATERIAL_DIFFUSE_LINK] = shader
                                        mat.InsertShader(shader)
                                        mat.Message(c4d.MSG_UPDATE)  # Update the material changes  
                                        mat.Update(True, True)  # Update the material's icon image  
                                        doc.InsertMaterial(mat)
                                        tex_tag.SetMaterial(mat)
                                    
                                bd = doc.GetActiveBaseDraw()
                                bd.SetSceneCamera(cam)
                                
                                root_layer = doc.GetLayerObjectRoot()
                                child_layer = root_layer.GetDown()
                                layer = None
                                
                                while child_layer:
                                    
                                    if child_layer.GetName() == 'Temp_Layer':
                                        
                                        layer = child_layer
                                        break
                                            
                                    child_layer = child_layer.GetNext()
                                
                                if not layer:
                                    
                                    layer = c4d.documents.LayerObject()
                                    layer.SetName('Temp_Layer')
                                    layer.InsertUnder(root_layer)
                                
                                cam.SetLayerObject(layer)
                                bg.SetLayerObject(layer)
                                hdri = get_op(first_obj, 'HDRI')
                                hdri.SetLayerObject(layer)
                                
                                subd_lst = get_op_type(first_obj, 'Subdivision Surface', [])
                                
                                for subd in subd_lst:
                                
                                    subd.SetLayerObject(layer)
                            
                                if not objs_lst:
                                    
                                    c4d.gui.MessageDialog('No polygon objects in the scene!')
                                    c4d.StatusSetText('No polygon objects in the scene!')
                                    return False
                                
                                for count, obj in enumerate(objs_lst[:10], start=1):
                                    
                                    rad_x = obj.GetRad().x * 2
                                    rad_y = obj.GetRad().y * 2
                                    rad_z = obj.GetRad().z * 2
                                    
                                    water_vp[c4d.VP_WATERMARK_TEXT_CUSTOM_TEXT] = 'Dimensions(cm): (H){0:.2f} x (W){1:.2f} x (D){2:.2f}'.format(rad_x, rad_y, rad_z)
                                    
                                    trg_null.Remove()
                                    trg_null.InsertUnder(obj)
                                    doc.SetActiveObject(obj)
                                    obj.SetLayerObject(layer)
                                    obj.SetRenderMode(c4d.MODE_ON)
                                    layer_data = layer.GetLayerData(doc)
                                    layer_data['solo'] = True
                                    layer.SetLayerData(doc,layer_data)
                                    doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_SET)
                                    c4d.CallCommand(12151)
                                    doc.SetActiveObject(None)
                                    cam.Message(c4d.MSG_UPDATE)
                                    
                                    scaleFactor = c4d.Vector(15, 15, cam.GetMg().off.z)   # <---- Change the vector values for camera position.
                                    scaleFactor = scaleFactor.__mul__(0.05)
                                    
                                    stopped = False
                                    c4d.StatusSetSpin()
                                
                                    while not CheckIfInView(cam, obj, doc):
                                        
                                        camMg = cam.GetMg()  
                                        camMgOff = camMg.off  
                                        camMgOff += scaleFactor  
                                        camMg.off = camMgOff  
                                        cam.SetMg(camMg)
                                        c4d.DrawViews(c4d.DRAWFLAGS_NO_THREAD | c4d.DRAWFLAGS_FORCEFULLREDRAW)
                                        
                                        stopped = escaped_pressed()
                                        if stopped:
                                            break
                                            
                                    render_set = doc.GetFirstRenderData()
                                    parent_name = obj.GetUp().GetName()
                                    obj_name = '{0}_{1}_{2}'.format(doc.GetDocumentName().split('.')[0], parent_name, obj.GetName())
                                    render_set[c4d.RDATA_PATH] = '../Renders/{0}'.format(obj_name)    # <----- Make sure to correct File Path
                                
                                    rs = render_set.GetData()
                                    x_res = int(rs[c4d.RDATA_XRES])
                                    y_res = int(rs[c4d.RDATA_YRES])
                                
                                    bmp = c4d.bitmaps.BaseBitmap()
                                    bmp.Init(x=x_res, y=y_res, depth=24)
                                    c4d.documents.RenderDocument(doc, rs, bmp, c4d.RENDERFLAGS_EXTERNAL)
                                    
                                    bd.Message(c4d.MSG_CHANGE)
                                    obj.SetRenderMode(c4d.MODE_UNDEF)
                                    obj.SetLayerObject(sku_layer)
                                    cam.SetAbsPos(c4d.Vector(0))
                                    
                                    c4d.StatusClear()
                                    print('{0} / {1} - {2} - Render Done!'.format(count, count_total, obj.GetName()))
                                    c4d.StatusSetText('{0} / {1} - {2} - Render Done!'.format(count, count_total, obj.GetName()))
                                
                                layer.Remove()     
                                doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_CLEAR)
                                cam.Remove()
                                trg_null.Remove()
                                bg.Remove()
                                mat.Remove()
                                doc.GetFirstRenderData().Remove()
                                
                                for subd in subd_lst:
                            
                                    subd.SetLayerObject(sku_layer)
                            
                                c4d.EventAdd()
                                c4d.gui.MessageDialog('Renders Done!')
                                c4d.StatusSetText('Renders Done!')
                              
                            main()
                            

                            Hope this helps and please let me know if we can make this better ☺ . (Which I'm sure we can!)

                            Thank you!

                            Andre

                            1 Reply Last reply Reply Quote 1
                            • r_giganteR
                              r_gigante
                              last edited by

                              Thanks a lot @AndreAnjos for sharing the code.

                              I'll try to have a look at it and maybe contribute if/where needed. For the time being I'm glad to hear that you were able to tackle with it.

                              Cheers, Riccardo

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