Custom priorities like the Hair object? [SOLVED]

  • On 11/01/2015 at 04:44, xxxxxxxx wrote:

    Is it possible to set custom priorities on a Python ObjectData plugin, similar to how the Hair object does it?

    The SDK documentation says that the default for AddToExecution() returns false, and that if this occurs then the priority dictated by EXPRESSION_PRIORITY on the object container is used instead. I can see that EXPRESSION_PRIORITY is normally defined by Texpression.res (presumably by including that file in your own *.res). What I'm getting lost on is that neither the Hair object nor anything else that allows priority overrides (like the joint objects) seems to do it this way. They all define their own priorities in their *.res file, and presumably set them manually somehow via code.

    So what I'm wondering is this: should I be including Texpression in my res file, or should I be setting up the priority field manually then overriding AddToExecution() and feeding that data through by hand?


  • On 13/01/2015 at 16:24, xxxxxxxx wrote:

    Hi CMPX,

    I'm confused by your statements, since I found that the hair resource files do include Texpression.res in their res files: thairsdkrendering.res and thairsdkstyling.res.  No matter what, so do various other modules in Cinema 4D, both in the SDK and internally, include Texpression.res.

    However, several do add in an overridden version of AddToExecution() to the PriorityList object a specific priority value.

    Therefore, I don't know how it was determined to use one or the other priority specifying approach (the .res or with code).

    What is the underlying reason you are debating the approach anyway?  Perhaps stating it could make the choice clear (or confirm it's a dilemma 😉 ).


    Joey Gaspe
    SDK Support Engineer

  • On 13/01/2015 at 17:45, xxxxxxxx wrote:

    Uh, I'm guessing those are from the SDK. I'm talking about the actual hair object (Ohair.res), which is located in modules/hair/res/description/ohair.res.

    If you look at that file, you'll see the following lines:

    GROUP Obaselist

    Ohair doesn't import Texpression, neither do the Joint objects. They both declare their own priority fields (as above) and then set the priority by code somehow.

    I suppose, what I'm trying to ask is why the hair and joint objects set their expressions internally rather then just including Texpression (which then sets EXPRESSION_PRIORITY).

    Also, I'm a bit confused as to how AddToExecution() translates to the priority data returned by a Priority field. There doesn't seem to be any place to add the actual priority integer in AddToExecution- just the "standard value" defines which match up to the priority groups. How do you override AddToExecution and say something like "set the priority to Expression groups, priority 250"?


  • On 14/01/2015 at 11:27, xxxxxxxx wrote:

    Hi CMPX,

    Question 1:

    I suppose, what I'm trying to ask is why the hair and joint objects set their expressions internally rather then just including Texpression (which then sets EXPRESSION_PRIORITY).


    On close inspection of ohair.res and texpression.res, the NOCAMERA sticks out as a difference.  When I look at the code that loads HAIRSTYLE_PRIORITY, I see that the settings data {ANIM OFF; NOCAMERA;} is treated as one entity.  So, it must be due to setting NOCAMERA that made including texpression.res not sufficient.  As for the joint objects, it's either for the same reason or perhaps to leave out the INCLUDEs that come in with Texpression, which is Tbase directly, and Obaselist from Tbase list, indirectly.  The only other explanation is that texpression.res could have been used for those only setting ANIM OFF but simply wasn't.

    When I look at how code that uses texpression.res is written, there really isn't a difference with using any other priority resource label.  The same kind of code that handles HAIRSTYLE_PRIORITY is written for EXPRESSION_PRIORITY, so it's not like the latter is special.  I think it was to put some data and code in common to simplify reuse.

    Question 2:

    How do you override AddToExecution and say something like "set the priority to Expression groups, priority 250"?


    Some technical clarifications:

    - When you call Add(), it adds to the end of a BaseArray, so it really is a list, not several.

    - The execution flags indicate execution points in the pipeline.  Those points appear to have an ordering relatively to each other, but not a way to order anything within them.

    - The Execute() calls that have (..., Int32 priority, EXECUTIONFLAGS flags) as parameters receive the values set in the list.  They use the values, especially of priority, as a conditional check to execute code.  That's all, so it's not for a centralized 'priority execution' mechanism per se, so being as precise as specifying a priority like 'expression groups, 250' would not be relevant.

    Considering the above, it's really a way to communicate to various Execute() calls made to objects based off of either the EffectorData, ObjectData, SceneHookData, or TagData classes a priority condition, with a rarely used flag for added precision.  By using it as a conditional check, you'll get a general ordering by category, as the Execute() calls would have to be called multiple times for any of this to be relevant, once per category.  In practice, I found despite a lot of Add() calls being used to set the various execution priority values, it is barely used in the actual Execute() calls.  I'm sure it could still be useful to you, if the way it works allows you to solve your priority problem.

    I hope the above helps.  Let me know if you need the code that handles loading and using any of the *_PRIORITY data, as I see there isn't an example so such in the C4D SDK.

    Joey Gaspe
    SDK Support Engineer

  • On 26/01/2015 at 10:30, xxxxxxxx wrote:

    Hi CMPX,

    Since this topic has been dormant for about two weeks, I consider it solved.

    Joey Gaspe
    SDK Support Engineer

Log in to reply