Navigation

    • Register
    • Login
        No matches found
    • Search
    1. Home
    2. AndreAnjos
    A

    AndreAnjos

    @AndreAnjos

    1
    Reputation
    81
    Posts
    232
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups
    AndreAnjos Follow

    Best posts made by AndreAnjos

    RE: Frame selected objects correctly in camera

    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

    posted in Plugin Development with Cinema 4D •

    Latest posts made by AndreAnjos

    RE: ShowPopupDialog Freezes Cinema R21

    @ferdinand
    Hi Ferdinand,

    Thank you for your time and help!
    Will get it sorted with your pointers above.

    All the best!

    Andre

    posted in Plugin Development with Cinema 4D •
    RE: ShowPopupDialog Freezes Cinema R21

    @ferdinand
    I just found what perhaps is the issue...

    The world-container. It seems that it runs without freezing if the data is not saved and load from the world container.
    Quiet odd, but perhaps as you said, it corrupted it somehow?

    Just need to find a way to storing data outside of the document.

    Thank you!

    posted in Plugin Development with Cinema 4D •
    RE: ShowPopupDialog Freezes Cinema R21

    @ferdinand
    Hi Ferdinand,

    Many thanks for your valid points and I appreciate what you are saying :).

    I've made the changes to use a GeDialog instead for the menu and it works.

    Here's are my results, based on your proposals:

    1. Nope, same issue still.
    2. Not tried it, but may have to give it a go just in case.
    3. Yes done this at the start and simplify the code, all code works until I introduce the ShowPopupDialog(), as any code after this does not run. Then again it may be something associated with it.
    4. Yes, the GetTimer() function is not doing anything, so definitely good idea.
    5. Yes, that was one of the ways I was debugging and again runs anything that I add to it, except ShowPopupDialog().
    6. I'm going to give it another go.

    The undo-block is for something I wrote in between, but for simplification removed it to pinpoint the culprit. :)

    The world-container is definitely a good point. I'm not sure if I should be using it to store data. I think the reasoning behind it was to keep data accessible between loading and unloading of documents, which is mainly what this plugin is doing.
    Would you recommend perhaps a different container to store the data?

    What I found most weird is that works perfectly fine with R19, so perhaps as you pointed out on 2, Cinema needs reinstalling.

    It's all learning and I think I know a bit more about it now and even if I cannot find the solution for this, I already have another way of dealing with it. Not elegant, but works with no issues :).

    Thank you very much for your help and time!

    posted in Plugin Development with Cinema 4D •
    RE: ShowPopupDialog Freezes Cinema R21

    @ferdinand
    Hi Ferdinand,

    Thank you for your tips!

    Unfortunately removing the other plugins does not make a difference, from what I can understand.

    I've also run the general popup dialog and it works fine with no freezing.

    Not sure what to do about this except perhaps change the c4d.gui.ShowPopupDialog to a c4d.gui.GeDialog
    and create a simple menu. Any thoughts?

    Thank you in advance!

    posted in Plugin Development with Cinema 4D •
    RE: ShowPopupDialog Freezes Cinema R21

    @m_adam
    Morning Maxime,

    Yes, it freezes with the code I provided.
    I've also tried the way that you mention above by running the c4d.SpecialEventAdd(1055684) and the same happens, as per my video below.

    https://drive.google.com/file/d/1v4A9xXKb79Z1TlMnlSdZ-tk9WJFldsv7/view?usp=sharing

    Let me know if you need any other information.

    Thank you!

    Andre

    posted in Plugin Development with Cinema 4D •
    RE: ShowPopupDialog Freezes Cinema R21

    @m_adam
    Hi Maxime,

    Cinema R21.207 Build RB303831.
    Windows 10 1809

    I'm calling the SpecialEventAdd on an SceneLoaderPlugin.

    # Import modules
    import c4d
    
    plugin_ID = 1055684
    
    
    class AOLoader(c4d.plugins.SceneLoaderData):
        """
        Class for the SceneLoaderData plugin.
        """
    
        def Identify(self, node, name, probe, size):
            """
            Identifies if the format of the custom file captured meets the plugins requirements.
            :param node: BaseContainer for instance.
            :param name: Path and file name of the instance.
            :param probe: The data from the instance.
            :param size: The data size of the instance.
            :return: True if meets object requirements.
            """
    
            file_name = name.lower()
    
            if not file_name.endswith('.ao'):
                return False
    
            return True
    
        @staticmethod
        def clean_path_str(txt, chr_lst):
            """
            This method removes specific characters in a path.
            :param txt: The string to replace character.
            :param chr_lst: The characters list to be replaced.
            :return: Returns the path with removed c characters.
            """
    
            for c in chr_lst:
                txt = txt.replace(c, '')
    
            return txt
    
        def read_lines(self, data_file):
            """
            Iterates throught the data until finds the line with path for .c4d asset.
            :param data_file: The file data returned by Identify method.
            :return: The path string, not formatted.
            """
    
            with open(data_file, 'rU') as data:
    
                ds_file = data.read().splitlines()
                paths = ""
    
                for line in ds_file:
                    if ".c4d" in line:
    
                        remove_chrs = self.clean_path_str(line, [')', '"'])
                        paths += remove_chrs.replace("\\\\", "\\")
    
                return paths
    
        def Load(self, node, name, doc, filterflags, error, bt):
            """
            Loads the data into the active document. In this case, we do not load or merge the file, but
            send a message to CoreMessage when it is catched with a SpecialEventAdd.
            The WorldContainer will save the path to be used later.
            :param node: BaseContainer for the instance.
            :param name: Path and file name of the instance.
            :param doc: The active document.
            :param filterflags: Flags to filter objects to load.
            :param error: Errors brought by Identify Method.
            :param bt: The BaseThread for the document.
            :return: Returns a c4d.FILEERROR_USERBREAK to capture the message.
            """
    
            paths = self.read_lines(name)
    
            world_container = c4d.GetWorldContainerInstance()
            world_container.SetString(plugin_ID, paths)
            c4d.SpecialEventAdd(plugin_ID)
    
            return c4d.FILEERROR_USERBREAK
    
    
    if __name__ == "__main__":
    
        c4d.plugins.RegisterSceneLoaderPlugin(id=plugin_ID,
                                              str="AO Loader",
                                              g=AOLoader,
                                              info=c4d.PLUGINFLAG_SCENELOADER_MERGEORIGINAL,
                                              description="")
    

    It's passing the data correctly, so perhaps the call needs to be done somewhere else?

    Thank you in advance!

    Andre

    posted in Plugin Development with Cinema 4D •
    ShowPopupDialog Freezes Cinema R21

    Hi all,

    Hope you are well in these crazy times!

    I'm having trouble understanding how ShowPopupDialog currently works in R21, if caught by MessageData plugin's CoreMessage. It keeps freezing Cinema, could be thread related (which I don't know a lot of)?

    I manage to get the data across externally fine but when creating the menu it freezes immediately after c4d.gui.ShowPopupDialog is called.

    # Import modules
    import os
    import c4d
    from c4d import documents
    
    plugin_ID = 1055685
    plugin_ID_loader = 1055684
    
    MENU_ADD_ASSETS = c4d.FIRST_POPUP_ID
    MENU_ADD_MATERIALS = c4d.FIRST_POPUP_ID + 1
    MENU_REPLACE_ASSETS = c4d.FIRST_POPUP_ID + 2
    MENU_REPLACE_MATERIALS = c4d.FIRST_POPUP_ID + 3
    MENU_REPLACE_TAG = c4d.FIRST_POPUP_ID + 4
    
    
    class AOMessage(c4d.plugins.MessageData):
        """
        Class for the MessageData plugin.
        """
    
        def GetTimer(self):
            """
            Called to return a time in milliseconds to receive timer messages (MSG_TIMER) with that interval in CoreMessage.
            This method is queried again after each message..
            :return: The time in miliseconds.
            """
            return 0
    
        def CoreMessage(self, id, bc):
            """
            Called to receive core messages.
            :param id: The id of the messages received.
            :param bc: The BaseContainer objects with message data.
            :return: True if Message is received.
            """
    
            if id == plugin_ID_loader:
    
                world_container = c4d.GetWorldContainerInstance()
                doc = documents.GetActiveDocument()
                paths_str = world_container.GetString(plugin_ID_loader)
                paths_lst = paths_str.split(', ')
                active_objs = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)
                active_mat = doc.GetActiveMaterial()
                doc.StartUndo()
    
                # Dialog for importing assets
                menu = c4d.BaseContainer()
    
                if active_objs or active_mat:
                    menu.InsData(MENU_REPLACE_ASSETS, 'Replace Asset(s)')
                    menu.InsData(MENU_REPLACE_MATERIALS, 'Replace Material(s)')
                    menu.InsData(MENU_REPLACE_TAG, 'Replace Texture Tag(s)')
    
                else:
                    menu.InsData(MENU_ADD_ASSETS, 'Add Asset(s)')
                    menu.InsData(MENU_ADD_MATERIALS, 'Add Material(s)')
    
                result = c4d.gui.ShowPopupDialog(cd=None, bc=menu, x=c4d.MOUSEPOS, y=c4d.MOUSEPOS)
    
                doc.EndUndo()
                world_container.RemoveData(plugin_ID_loader)
    
                print("Finished")
    
            return True
    
    
    if __name__ == "__main__":
    
        c4d.plugins.RegisterMessagePlugin(id=plugin_ID,
                                          str="AO Message",
                                          info=0,
                                          dat=AOMessage())
    

    It works perfectly in R19, so I'm not sure what changed since then.
    Apologies if this as been asked before.

    Thank you very much for your help in advance!

    Andre

    posted in Plugin Development with Cinema 4D •
    RE: Add and Remove Edge Loops Poly Object

    Hi @r_gigante,

    Not to worry! I understand! 😃

    Thanks for your help!

    Andre

    posted in Plugin Development with Cinema 4D •
    RE: Add and Remove Edge Loops Poly Object

    Hi @zipit,

    I am somehow even more confused than before, lol. You want the geometry in the screenshot to be subdivided, right? And the geometry is somehow procedurally generated by a Xpresso rig?

    I'm sorry if it made it more confusing! 😄
    The Xpresso just connects the userdata to the generator object. So the subdivisions are controlled by changing the object's number of segments.

    I do not quite understand why you cannot just implement that choice of subdivision in that rig? Doing it after the fact seems incredible cumbersome because this is probably not a static polygon mesh, but some kind of generator object that your rig produces there.

    That's correct! Which leads me to think that having a poly object in the first place is probably the best way.

    I am also just seeing now that you are asking also for a unsubdiving feature in your first post, which is quite a can of worms for an arbitrary mesh. I would go for your LOD-thingy if you see there a solution, because it is probably the fastest solution for you.

    Yes, that's what I currently testing. I agree as that being the best way to switch from different resolutions.
    Hopefully, this will work.

    Will keep you posted!

    Thanks again!

    Andre

    posted in Plugin Development with Cinema 4D •
    RE: Add and Remove Edge Loops Poly Object

    Hi @Cairyn,

    Does your setup react to the global Level of Detail controls?

    I'm afraid not! It's all done by changing the number of segments for the objects.

    If not, could you use a local LOD object with differently subdivided children?

    I'm currently exploring this. I think I will be able to do that. Need to make sure it it does not break with the rest of setup :)
    Will keep you posted!

    Cheers!

    Andre

    posted in Plugin Development with Cinema 4D •