InsertTag() - Error



  • On 27/11/2016 at 20:34, xxxxxxxx wrote:

    Hello there, **

    Error message :**

    A problem with this project has been detected: Object "Platonic" - Tag 5671 not in sync. Please save and contact MAXON Support with a description of the last used commands, actions or plugins.

    I made a video to better explain this error message.

    https://www.youtube.com/watch?v=Uz8MOycSTf4&feature=youtu.be

    I want to obtain the same result as in the method 01 using python.

    Python code :

    import c4d  
    from c4d import gui  
      
    def main() :      
      ObjToAddTag = doc.GetActiveObjects(False)[0]  
      OTag = doc.SearchObject("Cube")  
      ObjToAddTag.InsertTag(OTag.GetFirstTag().GetNext())      
      c4d.EventAdd()  
    if __name__=='__main__':  
      main()  
    

    Thanks!



  • On 28/11/2016 at 06:45, xxxxxxxx wrote:

    Hi Mustapha,

    the reason for your problem is, that you try to insert a tag, which is already inserted on another object, for a second time.
    Here:

      ObjToAddTag.InsertTag(OTag.GetFirstTag().GetNext())
    

    A tag (actually any GeListNode derived entity) can (and must) only be member of one single list at any given time.

    So in your case there are two options:

    Either you want to copy the tag from object A onto object B, then you need to clone the tag first (GetClone()) :

    # ...
    if OTag is None or OTag.GetFirstTag() is None:
        return
    tagSrc = OTag.GetFirstTag().GetNext()
    if tagSrc is None:
        return
    tagClone = tagSrc.GetClone(c4d.COPYFLAGS_0)
    if tagClone is None:
        return
    ObjToAddTag.InsertTag(tagClone)
    # ...
    

    Or you want to move the tag from one object to the other, then you need to Remove() it from source object, first:

    # ...
    if OTag is None or OTag.GetFirstTag() is None:
        return
    tag = OTag.GetFirstTag().GetNext()
    if tag is None:
        return
    tag.Remove()
    ObjToAddTag.InsertTag(tag)
    # ...
    

    One final note, I hope you don't mind. As long as a topic is not too complicated, we prefer to not need to watch any video. Usually a text explanation is enough and the need to watch a video only costs extra time. Also video are rarely helpful on programming questions, as you can't easily copy code from them.



  • On 28/11/2016 at 11:21, xxxxxxxx wrote:

    Hi Andreas,

    Thank you very much for your assistance, I tested your scripte and I obtained the same result.

    I will explain you what I want to do exactly, I want to apply my material on etch faces of Platonic object for example, to obtain a wireframe texture. (fit the texure on etch faces) see the images below.

    when I move manualy the UVW tag from the Cube object to the Platonic then I add my material (preview material below) I obtain a wireframe texure as the image above.

    Material :

    but when i use python to move or clone the UVW tag I obtain the result below and a error message when I run the render.

    Result when I move the UVW tag using Python :

    Thanks.



  • On 29/11/2016 at 03:37, xxxxxxxx wrote:

    Hi Mustapha,

    I'm sorry in so many ways...

    First of all i'm sorry, for being triggered by the most obvious error in your script, that I didn't look into your actual problem. Terribly sorry!

    The actual reason for your issue: You copy/move a UVW Tag from one object to another object with a different polygon count. Resulting in the UVW tag not being "in sync" with the host object, as the polygon count differs from the number of UV polygons in the tag.

    Now, I'm sorry for the second time, because internally this is handled via a MSG_POLYGONS_CHANGED/VariableChanged (links into C++ docs), unfortunately this message is not correctly supported via Python, yet. I have put it on our list and hopefully we will be able to address this with one of our future updates.

    Depending on your needs you can manually work around these limitations.
    For example like so:

        tagUVW = platonic.GetTag(c4d.Tuvw) # platonic is the source object in this example
      
        cntPlatonic = platonic.GetPolygonCount()
        cntSphere = sphere.GetPolygonCount() # sphere is the destination object in this example
      
        tagDst = sphere.MakeVariableTag(c4d.Tuvw, cntSphere, None)
        for idxPoly in range(0, cntSphere) :
            uvwdict = tagUVW.GetSlow(idxPoly % cntPlatonic)
            tagDst.SetSlow(idxPoly, uvwdict["a"], uvwdict["b"], uvwdict["c"], uvwdict["d"])
      
        c4d.EventAdd()
    

    Notes:
    - The above example works only for copying the tag from a lower poly count object to a higher polygon count object. But you get the idea, I guess.
    - Also repeating the coordinates for the additional polygons, might not be what you want. But at least it comes close to, what was shown in the screenshots.

    And then the above example might look overly complicated with a CpySlow() function being available in the UVWTag class. Well, this is where I'm sorry for the third time. There's a bug in the index range checking of CpySlow(), so it can't be used in this case. This will be most likely addressed in one of the next service packs.

    No, my back hurts from apologizing so much. But it was due.



  • On 29/11/2016 at 07:23, xxxxxxxx wrote:

    Hi Andreas,

    Thank you very much again for your assistance.

    No problem, no need to apologize for that. We recognize the huge job you are doing to help the Cinema 4D Community.

    And a big thanks for the proposed solution in the above example that works perfectly.


Log in to reply