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

    Material tag not rendering to picture viewer

    Scheduled Pinned Locked Moved PYTHON Development
    6 Posts 0 Posters 534 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      On 10/04/2013 at 10:14, xxxxxxxx wrote:

      After taking time off from Python because of complaints from work that I was not simply acting busy when no 3D work was available, I've started sneaking time back into programming (there isn't enough 3D work to keep me busy).

      I'm creating an object plugin that creates lights and applies texture tags to image planes for GI lighting.

      Problem: When I preview render my scene in the scene frame it renders correctly with the materials showing as they should, but when I render to the picture viewer, my materials don't render.  When I break my plugin (press C), the materials render fine in the picture viewer.

      Here are snippets of my code that hopefully will show what I am doing wrong:

        
          def __init__(self) :
              self.SetOptimizeCache(True)
        
          def GetVirtualObjects(self, op, hierarchyhelp) :
              doc = c4d.documents.GetActiveDocument()
              myData = op.GetDataInstance()
              baseNull = c4d.BaseObject(c4d.Onull)
              giPlaneTop = c4d.BaseObject(c4d.Oplane)
              giPlaneTop.InsertUnder(baseNull)
        
              textureTagTop = giPlaneTop.MakeTag(c4d.Ttexture)
              giMatTop = c4d.BaseMaterial(5703)
              giMatTop[c4d.ID_BASELIST_NAME] = "GI Top"
        
              textureLinkTop = myData.GetData(11010) #Link to image FILENAME
        
              if textureLinkTop != None and textureLinkTop != "":
                  bsbitTop = c4d.BaseList2D(c4d.Xbitmap)  #create a bitmap baseshader
                  bsbitTop[c4d.BITMAPSHADER_FILENAME] = textureLinkTop
                  giMatTop[c4d.MATERIAL_LUMINANCE_SHADER] = bsbitTop
                  giMatTop.InsertShader(bsbitTop)#insert the shaders under the shader that uses it
                  giMatTop.Message(c4d.MSG_UPDATE)#update
                  giMatTop.Update(True, True)
                  giMatTop[c4d.MATERIAL_USE_LUMINANCE] = 1
                  textureTagTop[c4d.TEXTURETAG_MATERIAL] = giMatTop
                  matList = doc.GetMaterials()
                  for i in range(len(matList)) :
                      if matList[i].GetName() == "GI Top":
                          xTop = 1
                          myData = op.GetDataInstance()
                          giMatTop = matList[i]
                          textureTagTop[c4d.TEXTURETAG_MATERIAL] = giMatTop
                  try:
                      if xTop != 1:
                          doc.InsertMaterial(giMatTop)
                  except:
                      doc.InsertMaterial(giMatTop)
        
      
      

      For the coding god who decides to help me, let me know if you need any more of my completed code to make sense of this, or if you have any more questions that will help solve this for me.  I will also supply the code and a sample scene if needed.
      Thanks!
      -Dave

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

        On 10/04/2013 at 10:51, xxxxxxxx wrote:

        i cannot pinpoint it 100% but the problem lies within using the object name as an identifier
        (generally a really bad idea) and rendering the document in the picture viewer which does
        rebuild the caches.

        possible solutions :

        1. boolean compare the basecontainers of your material. this approach is also a bit flawed, as
        __eq__ does not always work like you would expect it for basecontainers (nested gelistnodes).

        2. simply store a refererence to your material as a class member.

         def __init__(self) :
                self.SetOptimizeCache(True)
            	self.myMaterial = c4d.BaseMaterial(c4d.Mmaterial)
          
            def Init(self, node) :
                node.GetDocument().InsertMaterial(self.myMaterial)
          
            def GetVirtualObjects(self, op, hierarchyhelp) :
                giPlaneTop = c4d.BaseObject(c4d.Oplane)
                ttag       = c4d.TextureTag()
          
                ttag.SetMaterial(self.myMaterial)
                giPlaneTop.InsertTag(ttag)
                return giPlaneTop
        

        edit : you would have to add a method / some code to modify your material based on the
        node settings in GVO of course. you could also hide the material form the users view in the
        material manager, using the NBIT_OHIDE flag and prevent unwanted modifications of the 
        material by the user.

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

          On 10/04/2013 at 11:14, xxxxxxxx wrote:

          Thanks a lot for your reply and suggestions Ferdinand!  This should get me on the right track... but to be greedy, and if it's not too much trouble, would you please point me to an example of storing a reference to a material as a class member, or something similar?  I haven't gotten my head completely wrapped around writing plugins yet. (I'm picturing my head actually wrapping around the word "plugin")

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

            On 10/04/2013 at 11:48, xxxxxxxx wrote:

            my snippet was an example for that. here a commented version.

             def __init__(self) :
                    self.SetOptimizeCache(True)
            	# the reference to your material
                	self.myMaterial = c4d.BaseMaterial(c4d.Mmaterial)
            # the gelistnode attached to your plugin class has been created.
            # we can now grab the bd to insert the material.
                def Init(self, node) :
                    node.GetDocument().InsertMaterial(self.myMaterial)
            	
                def GetVirtualObjects(self, op, hierarchyhelp) :
                    giPlaneTop = c4d.BaseObject(c4d.Oplane)
                    ttag       = c4d.TextureTag()
            	# insert the material using the reference
                    ttag.SetMaterial(self.myMaterial)
                    giPlaneTop.InsertTag(ttag)
                    return giPlaneTop
            

            one thing i forgot here is duplicating the document. __init__ and init() will be 
            executed each time the document is loaded/duplicated. while it would not change
            visually anything for you, a new material would be created and inserted into the 
            document each time.

            so when your object is initialized you have do basically the same as you were trying
            in gvo, but in init. i would hve to try this for myself, as this is a rather special subject.
            as i wrote comparing basecontainers could be a solution. another way could be to
            stoe some sort of hash-value with the material and object container. you have to try 
            here what does work best for you.

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

              On 10/04/2013 at 11:49, xxxxxxxx wrote:

              _not sure if this is browser specific, but chrome does cut of half of my previous posting,  _
              so there is the rest:

              one thing i forgot here is duplicating the document. __init__ and init() will be 
              executed each time the document is loaded/duplicated. while it would not change
              visually anything for you, a new material would be created and inserted into the 
              document each time.

              so when your object is initialized you have do basically the same as you were trying
              in gvo, but in init. i would have to try this for myself, as this is a rather special subject.
              as i wrote comparing basecontainers could be a solution. another way could be to
              store some sort of hash-value with the material and object container. you have to try 
              here what does work best for you.

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

                On 10/04/2013 at 12:11, xxxxxxxx wrote:

                Doh! (insert favorite image of someone covering face in embarrassment).  I glanced over your code snippet too fast thinking that you had just quoted mine.  This should give me what I need.  I'll also try storing a hash-value with the material.  Thanks!

                Also, thanks for the tip on hiding materials from the use with NBIT_OHIDE.

                -Dave

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