Navigation

    • Register
    • Login
    • Search
    1. Home
    2. jenandesign
    jenandesign

    jenandesign

    @jenandesign

    2
    Reputation
    22
    Posts
    137
    Profile views
    1
    Followers
    0
    Following
    Joined Last Online

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

    Best posts made by jenandesign

    RE: Issues with the C4D to Unity Import python plugin - missing some types of objects

    @m_adam Shoot, tried calling it 3X and still nothing on the cloner (spline mode) object.

    (failing) test file attached
    fbxtest_v04.c4d

    posted in Cinema 4D SDK •
    Feature request: Quaternion Matrix Mix to XPresso "Mix" Node

    Hello, I would use it quite often if it could be added: a Quaternion rotation setting to the XPresso Mix node... much like there is in the c4d.BaseObject class as it is accessible through the GUI

    Attributes of a regular Null object showing Quaternion setting:
    Screen Shot 2020-11-17 at 11.07.11 AM.png

    Attributes of a Mix node in XPresso, where a boolean checkbox like above could live:
    Screen Shot 2020-11-17 at 11.08.59 AM.png

    I have constructed a Quaternion Matrix Mix using an XPresso Python node myself, but thought this would be a useful feature to be added in the default XPresso API for users who have not yet learned how to implement Quaternions in Python. Alternatively, perhaps other users will find the following code useful anyway 😁

    import c4d
    from c4d import utils
    #Welcome to the world of Python
    
    
    def main():
        global MatrixMix
    
        q1 = c4d.Quaternion()
        q1.SetMatrix(MatrixA)
    
        q2 = c4d.Quaternion()
        q2.SetMatrix(MatrixB)
    
        q = c4d.utils.QSlerp(q1, q2, Mix)
    
        MatrixMix = q.GetMatrix()
        MatrixMix.off = c4d.utils.MixVec(MatrixA.off, MatrixB.off, Mix)
    

    Screen Shot 2020-11-17 at 11.12.44 AM.png

    Cheers!
    -Leah

    Edit: also I am sorry if this is posted incorrectly. This seemed like the best place to put this post since there is usable Python code included 🙆

    posted in General Talk •

    Latest posts made by jenandesign

    RE: baking material channel and applying result to another material from python tag

    Hello @ferdinand. I realized there is no need to create a new shader in the material, simply updating/maintaining the Xbitmap file path should suffice.

    Thankfully tempfile is giving me no issues with the farm.

    However the problem I am having now is that the material does not update with the texture as it changes. I tried everything from BaseMaterial.GetPreview() to BaseMaterial.Message(c4d.MSG_UPDATE) to BaseMaterial.Update() at no avail. If you have any recommendations how I can force a reload of the Xbitmap's file, I am all ears.

    import c4d
    import tempfile
    import os
    #Welcome to the world of Python
    
    def main():
        baking = op[c4d.ID_USERDATA,4] # a boolean flag
        if baking == True:
            return
    
        # Set some variables
        texTags = [op[c4d.ID_USERDATA,1]]    # source texture tag
        texUVWs = [op[c4d.ID_USERDATA,2]]
        destUVWs = [op[c4d.ID_USERDATA,3]]
        destMat = op[c4d.ID_USERDATA,5]      # destination material
    
        # Bake texture setup
        bc = c4d.BaseContainer()
        bc[c4d.BAKE_TEX_SURFACECOLOR] = True
        bc[c4d.BAKE_TEX_PIXELBORDER] = 3
        bc[c4d.BAKE_TEX_WIDTH] = 1024
        bc[c4d.BAKE_TEX_HEIGHT] = 1024
    
        # Init bake texture, prevent recursion
        op[c4d.ID_USERDATA,4] = baking = True
        bakeInfo = c4d.utils.InitBakeTexture(doc, texTags, texUVWs, destUVWs, bc, None)
        op[c4d.ID_USERDATA,4] = baking = False
    
        # Create new bitmap and bake texture
        newBitmap = c4d.bitmaps.MultipassBitmap(1024, 1024, c4d.COLORMODE_RGBw)
        bakeTextureInfo = c4d.utils.BakeTexture(bakeInfo[0], bc, newBitmap, None, None)
    
        # Store bitmap to file
        tempFilePath = os.path.join(tempfile.gettempdir(), "tempBitmap.png")
        newBitmap.Save(tempFilePath, c4d.FILTER_PNG)
    
        # Update the destination material
        shader = destMat[c4d.MATERIAL_LUMINANCE_SHADER]
        shader[c4d.BITMAPSHADER_FILENAME] = tempFilePath
        # Nothing seems to be working after this to update the material
        destMat.GetPreview()
        destMat.Message(c4d.MSG_UPDATE)
        destMat.Update(True, True)
        c4d.EventAdd()
    
        return None
    
    posted in Cinema 4D SDK •
    RE: baking material channel and applying result to another material from python tag

    Hi @ferdinand- thanks again for the guidance. Do you have any suggestions about how to avoid the issues you've pointed out?

    posted in Cinema 4D SDK •
    RE: baking material channel and applying result to another material from python tag

    One thing I still have yet to figure out is how to get the destination material to update its texture in the viewport/editor.

    How to run c4d.BITMAPSHADER_RELOADIMAGE?

    https://developers.maxon.net/docs/Cinema4DPythonSDK/html/classic_resource/shader/xbitmap.html

    Thank you,
    Leah

    posted in Cinema 4D SDK •
    RE: baking material channel and applying result to another material from python tag

    Hello @ferdinand! Thank you for your incredibly well thought out and detailed response! I really appreciate it. The amount of information you have come back with from my hodgepodge posting is illuminating to say the least.

    • Why does it have to be a Python Programming Tag? Why not just some Script Manger script with GeDialog for example? Which would lend itself much better for this.

    The reason for a Python Tag is threefold:

    • My task requires that the operation updates on every frame so that other systems can be built upon it. This rules out a Script Manager script which would need to be executed manually and does not work at render time. Specifically in my case, I am trying to achieve particle emission via texture luminance that is baked from lights / surface color.
    • The setup is to be shared across a team of remote workers, and requiring other team members to manage/update a plugin or script file along with a scene file adds undue complexity to an otherwise simple tool. It is much easier to have every bit of kit live in the scene file alone.
    • As mentioned earlier, this will be rendered on a farm [remotely], and this is another reason to keep everything contained within the scene file (as opposed to a plugin which would require the farm admin to manage installations and updates).

    At the recommendation of a very smart and dear friend, I am using a bit of user data to store a baking state/flag. With this, I was able to hack my way through the recursion issue. Things are now working as intended.

    import c4d
    import tempfile
    import os
    #Welcome to the world of Python
    
    def main():
        baking = op[c4d.ID_USERDATA,4] # a boolean flag
        if baking == True:
            return
    
        # Set some variables
        texTags = [op[c4d.ID_USERDATA,1]]    # source texture tag 
        texUVWs = [op[c4d.ID_USERDATA,2]]
        destUVWs = [op[c4d.ID_USERDATA,3]]
        destMat = op[c4d.ID_USERDATA,5]      # destination material
    
        # Bake texture setup
        bc = c4d.BaseContainer()
        bc[c4d.BAKE_TEX_SURFACECOLOR] = True
        bc[c4d.BAKE_TEX_PIXELBORDER] = 3
        bc[c4d.BAKE_TEX_WIDTH] = 1024
        bc[c4d.BAKE_TEX_HEIGHT] = 1024
    
        # Init bake texture, prevent recursion
        op[c4d.ID_USERDATA,4] = baking = True
        bakeInfo = c4d.utils.InitBakeTexture(doc, texTags, texUVWs, destUVWs, bc, None)
        op[c4d.ID_USERDATA,4] = baking = False
    
        # Create new bitmap and bake texture
        newBitmap = c4d.bitmaps.MultipassBitmap(1024, 1024, c4d.COLORMODE_RGBw)
        bakeTextureInfo = c4d.utils.BakeTexture(bakeInfo[0], bc, newBitmap, None, None)
    
        # Store bitmap to file
        tempFilePath = os.path.join(tempfile.gettempdir(), "tempBitmap.png")
        newBitmap.Save(tempFilePath, c4d.FILTER_PNG)
    
        # Update the destination material
        shader = c4d.BaseList2D(c4d.Xbitmap)
        shader[c4d.BITMAPSHADER_FILENAME] = tempFilePath
        destMat.InsertShader(shader)
        destMat[c4d.MATERIAL_LUMINANCE_SHADER] = shader
        destMat.Message(c4d.MSG_UPDATE)
        destMat.Update(True, True)
        c4d.EventAdd()
    
        return None
    
    if __name__=='__main__':
        main()
    
    posted in Cinema 4D SDK •
    baking material channel and applying result to another material from python tag

    Hello, perhaps it is pretty self explanatory from the title what I am seeking to do.

    I am avoiding making a plugin at all costs due to the added complexity (both from a developmental standpoint as well as having to ask IT to install a plugin across a massive farm for a single job).

    So, I am trying to do everything from a Python Tag which I know carries caveats in terms of what is possible. But in a nutshell, I am trying to render a material channel on one object and then apply the result in an xbitmap shader in another material.

    So far I have tried a few things, but with no success because I can't find examples of other people doing this so far.

    I have tried:

    • creating a bake texture tag and using CallButton on the bake button, using a frame checker to make sure it runs only once when the frame is changed. This should work, but then the file that is generated and written to disk tries to overwrite itself which displays a dialog asking "Yes or No" and I have yet to figure out how to "click" one of these buttons to get through this dialog.
    • creating a new bitmap and using c4d.utils.BakeTexture, but I am running into issues getting this set up as there are no examples running it from a Python Tag (nor do I know if it's even feasible)

    Thanks for any and all help / recommendations!

    Follow up postings (edited by @ferdinand):

    Hello again, checking back in. I have made some progress using an example I found:
    http://www.plugincafe.com/forum/forum_posts.asp?TID=13606

    My code so far is as follows:

    import c4d
    import tempfile
    import os
    #Welcome to the world of Python
    
    def main():
    
        # Set some variables
        obj = op.GetObject()
        texTags = [obj.GetTag(c4d.Ttexture)]
        texUVWs = [obj.GetTag(c4d.Tuvw)]
        destUVWs = [obj.GetTag(c4d.Tuvw)]
    
        # Bake texture setup
        bc = c4d.BaseContainer()
        bc[c4d.BAKE_TEX_WIDTH] = 512
        bc[c4d.BAKE_TEX_HEIGHT] = 512
        bc[c4d.BAKE_TEX_CONTINUE_UV] = False
        bc[c4d.BAKE_TEX_SUPERSAMPLING] = 0
        bc[c4d.BAKE_TEX_FILL_COLOR] = c4d.Vector(1)
        bc[c4d.BAKE_TEX_USE_BUMP] = False
        bc[c4d.BAKE_TEX_USE_CAMERA_VECTOR] = False
        bc[c4d.BAKE_TEX_AUTO_SIZE] = False
        bc[c4d.BAKE_TEX_NO_GI] = False
        bc[c4d.BAKE_TEX_GENERATE_UNDO] = False
        bc[c4d.BAKE_TEX_PREVIEW] = False
        bc[c4d.BAKE_TEX_SURFACECOLOR] = True
        bc[c4d.BAKE_TEX_UV_LEFT] = 0.0
        bc[c4d.BAKE_TEX_UV_RIGHT] = 1.0
        bc[c4d.BAKE_TEX_UV_TOP] = 0.0
        bc[c4d.BAKE_TEX_UV_BOTTOM] = 1.0
        bc[c4d.BAKE_TEX_NORMAL_METHOD] = c4d.BAKE_TEX_NORMAL_METHOD_OBJECT
    
        # Initialize bake texture
        bakeInfo = c4d.utils.InitBakeTexture(doc, texTags, texUVWs, destUVWs, bc, None)
    
        # Create new bitmap and bake texture
        newBitmap = c4d.bitmaps.MultipassBitmap(512, 512, c4d.COLORMODE_RGB)
        bakeTextureInfo = c4d.utils.BakeTexture(bakeInfo[0], bc, newBitmap, None, None)
    
        # Store bitmap to file
        tempFilePath = os.path.join(tempfile.gettempdir(), "tempBitmap.png")
        newBitmap.Save(tempFilePath, c4d.FILTER_PNG)
        print(tempFilePath)
    
        return None
    
    if __name__=='__main__':
        main()
    

    However I am getting crashes immediately after running the InitBakeTexture command. Any idea what I'm doing wrong?

    Also for some reason the tag script will run over 300 times upon file save even if the tag is disabled when InitBakeTexture exists in the script. Assuming this has something to do with thread = None and running on the main thread?

    R25.010

    I tried print(texTags, texUVWs) in the Set some variables section and then got the following error after doing 334 logs for the above issue:

    RecursionError: maximum recursion depth exceeded while getting the repr of an object

    Seems like when I do InitBakeTexture and save the file, it's opening another thread recursively and running the script again. Not sure why this is happening, but I'm pretty sure this is why I am getting crashes when I actually enable the tag.

    EDIT: looks like InitBakeTexture is causing a stack overflow, but I have no idea why.

    EDIT2: just realized it's creating a new doc. Ah ha

    EDIT3: okay not sure if it's a new doc or what, but it's definitely looking like a stack overflow. Any ideas why this is happening?

    Simplified test code (applied to Python Tag):

    import c4d
    #Welcome to the world of Python

    def main():
    
        # Set some variables
        obj = op.GetObject()
        texTags = [obj.GetTag(c4d.Ttexture)]
        texUVWs = [obj.GetTag(c4d.Tuvw)]
        destUVWs = [obj.GetTag(c4d.Tuvw)]
    
        print(texTags, texUVWs)
    
        # Bake texture setup
        bc = c4d.BaseContainer()
        bc[c4d.BAKE_TEX_COLOR] = True
        bc[c4d.BAKE_TEX_COLOR_ILLUM] = True
        bc[c4d.BAKE_TEX_NO_INIT_BITMAP] = True
        bc[c4d.BAKE_TEX_WIDTH] = 512
        bc[c4d.BAKE_TEX_HEIGHT] = 512
    
        bakeInfo = c4d.utils.InitBakeTexture(doc, texTags, texUVWs, destUVWs, bc, None)
    
        return None
    
    if __name__=='__main__':
        main()
    I believe InitBakeTexture causing a stack overflow
    

    I should mention this only happens when making a change to the Python Tag script and then saving the file.

    posted in Cinema 4D SDK •
    Generating a usable spline with a Python Generator

    This topic has been broached before over the years, but I think it should be mentioned again.

    There is no easy way to make a spline generated with a python generator that is usable in other parts of the program due to the internal hierarchy within c4d python and caching / generating "contours" as noted with the Python Generator object etc.

    The only solution available to generate procedural splines (usable in other generator objects) is that users are expected to make full ObjectData plugins.. which is unnecessarily time consuming, and places a much larger mountain to climb in front of new users of c4d python. I think this feature would be incredibly powerful and time saving if it was easier, even as someone who knows how to write ObjectData plugins.

    I hope you will please consider adding this functionality to return usable splines in the Python Generator in a future release or update to c4d python. Thanks for your consideration!

    posted in Cinema 4D SDK •
    Feature request: Quaternion Matrix Mix to XPresso "Mix" Node

    Hello, I would use it quite often if it could be added: a Quaternion rotation setting to the XPresso Mix node... much like there is in the c4d.BaseObject class as it is accessible through the GUI

    Attributes of a regular Null object showing Quaternion setting:
    Screen Shot 2020-11-17 at 11.07.11 AM.png

    Attributes of a Mix node in XPresso, where a boolean checkbox like above could live:
    Screen Shot 2020-11-17 at 11.08.59 AM.png

    I have constructed a Quaternion Matrix Mix using an XPresso Python node myself, but thought this would be a useful feature to be added in the default XPresso API for users who have not yet learned how to implement Quaternions in Python. Alternatively, perhaps other users will find the following code useful anyway 😁

    import c4d
    from c4d import utils
    #Welcome to the world of Python
    
    
    def main():
        global MatrixMix
    
        q1 = c4d.Quaternion()
        q1.SetMatrix(MatrixA)
    
        q2 = c4d.Quaternion()
        q2.SetMatrix(MatrixB)
    
        q = c4d.utils.QSlerp(q1, q2, Mix)
    
        MatrixMix = q.GetMatrix()
        MatrixMix.off = c4d.utils.MixVec(MatrixA.off, MatrixB.off, Mix)
    

    Screen Shot 2020-11-17 at 11.12.44 AM.png

    Cheers!
    -Leah

    Edit: also I am sorry if this is posted incorrectly. This seemed like the best place to put this post since there is usable Python code included 🙆

    posted in General Talk •
    RE: Issues with the C4D to Unity Import python plugin - missing some types of objects

    Hi Maxime! Thanks for the suggestion, though I don't quite understand what you mean by your example... I don't see any use of SendCoreMessage in your snippet?

    SaveDocument is already present in the original code in the extended threading class "ExportThread" under definition Main(). How are you suggesting I change this?

    Thank you for the continued help ☺

    posted in Cinema 4D SDK •
    RE: Issues with the C4D to Unity Import python plugin - missing some types of objects

    I forgot to mention, Instances also fail to cache into Unity as well.

    I am thinking these are all related and to do with the cache being unavailable unless the script is being run within the C4D gui

    posted in Cinema 4D SDK •
    RE: Issues with the C4D to Unity Import python plugin - missing some types of objects

    @m_adam Then maybe the issue is that the command line fbx export is being executed from within Unity and not through C4D itself?

    Is there some kind of document referencing error that could happen if another program (other than C4D) were to call this script? Would caches behave differently?

    To answer your question, yes, I have FBXEXPORT_SPLINES set to True

    posted in Cinema 4D SDK •