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

    Unusual "NoneType" Error for GetDeformCache()

    Cinema 4D SDK
    r21 python
    3
    12
    1.8k
    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.
    • ManuelM
      Manuel
      last edited by

      hi,

      sounds pretty logical to me.
      Your deformer is below the object where your tag is. Your tag is at priority expression +0. So it is executed before the deformer.
      If you retrieve the cache you should retrieve the cache build on the previous execute pass.

      That's why you got the message when you load the document and when you press the a key to force the recalculation of the scene.
      If you set the tag's priority to generator +1 you will not have the message anymore.

      the a key is your best friend when you want to deal with priorities.

      Cheers,
      Manuel

      MAXON SDK Specialist

      MAXON Registered Developer

      1 Reply Last reply Reply Quote 1
      • ferdinandF
        ferdinand
        last edited by ferdinand

        Hi,

        I do not want to be rude, but please put up your code next time and a console dump. You always making these little videos is very nice of you and helps, but cannot replace the mentioned. In this case I could take a glimpse at the code in the video.

        To your problem is is actually not GetDeformCache which is None, but the module attribute op. Invoking an undo seems to clear the selection as you can see in your video. Which in turn means that op, the current primary object selection, is going to be None.

        However, GetDeformCache can be None, as there is no guarantee that the deformation cache is populated at any time (assuming there is some kind of deformer). Invoking undo might produce such scenario (haven't tested it, I am on my iPad). When retrieving caches, it is good practice to so something like this.

        cache = node.GetDeformCache() or node.GetCache()
        node = cache or node
        

        This will replace the reference of the symbol node with the a reference to the deformed cache, the cache or the node itself in decreasing order. After that you can evaluate the type of node to determine how to proceed.

        if not isinstance(node, c4d.PointObject):
            msg = "Could not access point data in {}."
            raise TypeError(msg.format(node))
        

        Edit: It is also worth mentioning that caches can contain caches. So you are not guaranteed to have directly some point data at the top level of the cache. My mentioned snippet therefore only "works" in cases of such "flat" caches.

        Cheers,
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 1
        • B
          bentraje
          last edited by

          Thanks for the response:

          @m_magalhaes

          RE: Your tag is at priority expression +0. So it is executed before the deformer.
          It seems like you're talking as if the Shrink Wrap Deformer has a "priority", but its basic tab doesn't show anything.
          Interestingly, when I set the tag to generator +1 as suggested, it seems to fix the problem.

          So, indeed, there is an inherent priority for the deformers.
          How do I change them?

          I tried the following deformer[c4d.EXPRESSION_PRIORITY] or even the deformer[c4d.ID_CA_SKIN_OBJECT_PRIORITY] but it gives me None type.

          @zipit

          RE: but please put up your code next time and a console dump
          Gotcha. Noted.

          RE: Code
          The code works as expected.

          RE: caches can contain caches.
          Just want to clarify.
          Cache (GetCache()) can contain Caches and Deform Caches (GetDeformCache)
          But Deform Cache can't contain Caches or othe Deform Caches.

          Is this assessment correct? I'm basing this on a sample image in this documentation.

          RE: "flat" caches.
          Just to clarify, by flat caches, I guess you meant objects with no stacking parent/child hierarchies?

          ferdinandF 1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand @bentraje
            last edited by ferdinand

            @bentraje said in [Unusual "NoneType" Error for GetDeformCache()]

            RE: caches can contain caches.
            Just want to clarify.
            Cache (GetCache()) can contain Caches and Deform Caches (GetDeformCache)
            But Deform Cache can't contain Caches or othe Deform Caches.

            Is this assessment correct? I'm basing this on a sample image in this documentation.

            Yeah, deform caches are sort of flat. But they are often (when the deformer does not directly act on a PointObject) imbedded within a cache. It will look something like the tree below which represents the example of the docs, but with only one cloned cube. The problem is that this is not a monohierarchical structure which cannot be described very well with a (monohierarchical) taxonomy (i.e. the image in the docs or what I have done below). You can test this yourself with [1].

            # The actual array node.
            Array/Array
                Array/Array returns for GetCache:
                    # The null object holding all parametric cubes in the cache
                    Null/Array
                        # A null object has no cache
                        Null/Array returns 'None' for GetCache.
                        # And also no deform cache
                        Null/Array returns 'None' for GetDeformCache.
                        # But some children
                        children of Null/Array:
                            # A parametric cube as child of the cache.
                            Cube/Cube.1
                                # The cache of that part of the cache of the node :o
                                Cube/Cube.1 returns for GetCache:
                                    # The actual polygonal data created by the GVO of the
                                    # parametric cube object.
                                    Polygon/Cube.1
                                        Polygon/Cube.1 returns 'None' for GetCache.
                                        Polygon/Cube.1 returns for GetDeformCache:
                                            # The deformed polygonal data generated by
                                            # the deformer reaching deep into the cache
                                            # of the array object.
                                            Polygon/Cube.1
                                                Polygon/Cube.1 returns 'None' for GetCache.
                                                Polygon/Cube.1 returns 'None' for GetDeformCache.
                                                Polygon/Cube.1 has no children.
                                        Polygon/Cube.1 has no children.
                                # No deform cache here, since this is the paramteric cube
                                # not its polygonal cache.
                                Cube/Cube.1 returns 'None' for GetDeformCache.
                                Cube/Cube.1 has no children.
                # Has no deformed cache since its cache is a null object (which has
                # stuff attached to it.)
                Array/Array returns 'None' for GetDeformCache.
            
                # The actual children of the actual array object.
                children of Array/Array:
                    Cube/Cube
                        # This one is quite surprising I didn't know either, it seems
                        # like that at least the array object *mutes* its input objects
                        # to avoid overhead. 
                        Cube/Cube returns 'None' for GetCache.
                        Cube/Cube returns 'None' for GetDeformCache.
                        Cube/Cube has no children.
                    Bend/Bend
                        Bend/Bend returns 'None' for GetCache.
                        Bend/Bend returns 'None' for GetDeformCache.
                        Bend/Bend has no children.
            

            RE: "flat" caches.
            Just to clarify, by flat caches, I guess you meant objects with no stacking parent/child hierarchies?

            I meant caches that do not contain caches. A cache that is a null to which multiple other nulls are parented would be flat in this sense, as the nulls will have no further caches. If it were parametric cubes parented instead, it would not be no longer flat, since each cube had its own cache.

            Cheers,
            zipit

            [1]

            """Prints the cache hierarchy of a selected object.
            """
            import c4d
            
            
            def walk_cache(node, indent=0):
                """
                """
                if node is None:
                    return
            
                node_name = node.GetTypeName() + "/" + node.GetName()
                is_controlobject = node.GetBit(c4d.BIT_CONTROLOBJECT)
                print("{}{} (BIT_CONTROLOBJECT: {})".format("\t" * indent,
                                                            node_name,
                                                            is_controlobject))
                for f in [node.GetCache, node.GetDeformCache]:
                    cache = f()
                    msg = ("{}{} returns for {}:" if cache else
                           "{}{} returns 'None' for {}.")
                    print(msg.format("\t" * (indent + 1), node_name, f.__name__))
                    if cache:
                        walk_cache(cache, indent + 2)
            
                children = node.GetChildren()
                no_children = len(children) == 0
                msg = "{}{} has no children." if no_children else "{}children of {}:"
                print(msg.format("\t" * (indent + 1), node_name))
                for child in children:
                    walk_cache(child, indent + 2)
            
            
            def main():
                """
                """
                if op is None:
                    raise ValueError("Please select an object.")
                walk_cache(op)
            
            
            if __name__ == "__main__":
                main()
            
            

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 2
            • B
              bentraje
              last edited by

              @zipit

              Thanks for the detailed answer! The walk_cache code really clarifies a lot of what I've been having trouble understanding. Although, I still have to remain the thread open as I'm waiting for @m_magalhaes on my priorities on deformers.

              Thanks again! Have a great day ahead! 🙂

              1 Reply Last reply Reply Quote 0
              • ManuelM
                Manuel
                last edited by

                hi,

                A deformer is a generator. So it's priority is Generator.

                You can see in our documentation the sequence of calculation
                Of course there are some exceptions
                alt text

                Cheers,
                Manuel

                MAXON SDK Specialist

                MAXON Registered Developer

                1 Reply Last reply Reply Quote 0
                • B
                  bentraje
                  last edited by

                  @m_magalhaes

                  Ah gotcha. I totally missed this one out:
                  A deformer is a generator. So it's priority is Generator.

                  That said, since it has a priority, can I change it's order. I believe its in Generator -1.
                  I want to change it say to Generator -100 or Generator +100
                  This is so I can stack them properly.

                  As mentioned, I tried the following deformer[c4d.EXPRESSION_PRIORITY] or even the deformer[c4d.ID_CA_SKIN_OBJECT_PRIORITY] but it gives me None type.

                  1 Reply Last reply Reply Quote 0
                  • ManuelM
                    Manuel
                    last edited by

                    hi,

                    the skin deformer is a really particular case. The priority only change the moment where Execute will be called. (like any other Generator where you can use AddToExecution and Execute).
                    But in all case it will still use ModifyObject (the GVO for deformer). The priority of this call can't be changed.

                    Cheers,
                    Manuel

                    MAXON SDK Specialist

                    MAXON Registered Developer

                    1 Reply Last reply Reply Quote 0
                    • B
                      bentraje
                      last edited by

                      @m_magalhaes
                      Ah gotcha. Thanks for the clarification.
                      But I'm asking for "Deformer" in general in changing their priority since it's not available in the interface.

                      1 Reply Last reply Reply Quote 0
                      • ManuelM
                        Manuel
                        last edited by

                        Not all modifier use the Execution function.
                        Even on those that use it, not all allow to change the priority.

                        Cheers,
                        Manuel

                        MAXON SDK Specialist

                        MAXON Registered Developer

                        1 Reply Last reply Reply Quote 1
                        • B
                          bentraje
                          last edited by

                          Hi @m_magalhaes

                          Ah gotcha. I guess I can't change the deformer's priority.
                          Anyhow. Thanks for the confirmation.

                          1 Reply Last reply Reply Quote 0
                          • ferdinandF ferdinand referenced this topic on
                          • ferdinandF ferdinand referenced this topic on
                          • First post
                            Last post