Unusual "NoneType" Error for GetDeformCache()
-
Hi,
I'm having an unusual "NoneType" Error for GetDeformCache().
For the most part, it works. But there are times where it throws an error.
I can't replicate the other methods but it always happens when I hit undo.You can see the problem here:
https://www.dropbox.com/s/ybwoy0p403qxprr/c4d306_python_getdeformcache_nonetype_error.mp4?dl=0You can check the file here:
https://www.dropbox.com/s/obngch2rx6dseqn/c4d306_python_getdeformcache_nonetype_error.c4d?dl=0Regards,
Ben -
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 -
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 isNone
, but the module attributeop
. Invoking an undo seems to clear the selection as you can see in your video. Which in turn means thatop
, the current primary object selection, is going to beNone
.However,
GetDeformCache
can beNone
, 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 ofnode
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 -
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 togenerator +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 thedeformer[c4d.ID_CA_SKIN_OBJECT_PRIORITY]
but it gives meNone
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? -
@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()
-
@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!
-
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
Cheers,
Manuel -
@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 toGenerator -100
orGenerator +100
This is so I can stack them properly.As mentioned, I tried the following
deformer[c4d.EXPRESSION_PRIORITY]
or even thedeformer[c4d.ID_CA_SKIN_OBJECT_PRIORITY]
but it gives me None type. -
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 useModifyObject
(the GVO for deformer). The priority of this call can't be changed.Cheers,
Manuel -
@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. -
Not all modifier use the
Execution
function.
Even on those that use it, not all allow to change the priority.Cheers,
Manuel -
Hi @m_magalhaes
Ah gotcha. I guess I can't change the deformer's priority.
Anyhow. Thanks for the confirmation. -
-