Jump to content

SOP_PointWave example questions ....


Recommended Posts

Hello guys ,,, I am a beginner at the world of HDK .. I am struggling with the basics and simple examples to understand how things are going here :D

So , I am greatly seeking your help though I might ask some stupid questions (many of them xD)

I have read a lot of examples and have inquiries but let's stick to the example here

 

https://www.sidefx.com/docs/hdk/_s_o_p_2_s_o_p__point_wave_8h-example.html

https://www.sidefx.com/docs/hdk/_s_o_p_2_s_o_p__point_wave_8_c-example.html

 

Firstly , I will describe my problem in the first file

 

  virtual OP_ERROR             cookInputGroups(OP_Context &context, 
                                                int alone = 0);

 

I don't understand what this actually does ... Is it restricting the cooking to a specific group or what??

 

look at its code in the other file , sorry , though it's explained here  , I don't understand ... it's my bad but sorry again for seeking for help for such basics .

 


OP_ERROR
SOP_PointWave::cookInputGroups(OP_Context &context, int alone)
{
    // The SOP_Node::cookInputPointGroups() provides a good default
    // implementation for just handling a point selection.
    return cookInputPointGroups(
        context, // This is needed for cooking the group parameter, and cooking the input if alone.
        myGroup, // The group (or NULL) is written to myGroup if not alone.
        alone,   // This is true iff called outside of cookMySop to update handles.
                 // true means the group will be for the input geometry.
                 // false means the group will be for gdp (the working/output geometry).
        true,    // (default) true means to set the selection to the group if not alone and the highlight flag is on.
        0,       // (default) Parameter index of the group field
        -1,      // (default) Parameter index of the group type field (-1 since there isn't one)
        true,    // (default) true means that a pointer to an existing group is okay; false means group is always new.
        false,   // (default) false means new groups should be unordered; true means new groups should be ordered.
        true,    // (default) true means that all new groups should be detached, so not owned by the detail;
                 //           false means that new point and primitive groups on gdp will be owned by gdp.
        0        // (default) Index of the input whose geometry the group will be made for if alone.
    );
}

________________


private:
    void        getGroups(UT_String &str){ evalString(str, "group", 0, 0); }
    fpreal      AMP(fpreal t)           { return evalFloat("amp", 0, t); }
    fpreal      PHASE(fpreal t)         { return evalFloat("phase", 0, t); }
    fpreal      PERIOD(fpreal t)        { return evalFloat("period", 0, t); }
    /// This is the group of geometry to be manipulated by this SOP and cooked
    /// by the method "cookInputGroups".
    const GA_PointGroup *myGroup;

Here , I don't know what is fpreal ??? Are those a  type of variables or parameters ??? Why do we declare those like that though we just declare parameters in the other .c file ???

Also , why do we declare a group here though we are using OPLockInputs to lock our cooking to the input geo ??

 

_______________

 

In the second file ,,

 

    // Here we determine which groups we have to work on.  We only
    // handle point groups.
    if (cookInputGroups(context) >= UT_ERROR_ABORT)
        return error(

 

Here , I don't understand what this means .

 

 

    // If we've modified P, and we're managing our own data IDs,
    // we must bump the data ID for P.
    if (!myGroup || !myGroup->isEmpty())
        gdp->getP()->bumpDataId();

 

Also this , what is the difference between other data of the sop and our data ?? I think that my words don't actually mean anything ..

 

 

SOP_PointWave::SOP_PointWave(OP_Network *net, const char *name, OP_Operator *op)
    : SOP_Node(net, name, op), myGroup(NULL)
{
    // This indicates that this SOP manually manages its data IDs,
    // so that Houdini can identify what attributes may have changed,
    // e.g. to reduce work for the viewport, or other SOPs that
    // check whether data IDs have changed.
    // By default, (i.e. if this line weren't here), all data IDs
    // would be bumped after the SOP cook, to indicate that
    // everything might have changed.
    // If some data IDs don't get bumped properly, the viewport
    // may not update, or SOPs that check data IDs
    // may not cook correctly, so be *very* careful!
    mySopFlags.setManagesDataIDs(true);
}

here , I think we make the sop able to change its data only without cooking everything in the viewport and also cook only the changed geometry ?? is this right or what ??

 

 

 

This what I have ,, sorry again ,,

IF any of you can help with any of these things even a small information or a quote from the documentation , please help.

 

Thanks in advance , I am trying my best to not ask about many things to not waste ur time .

Link to comment
Share on other sites

I totally understand your feelings of being confused at first, albeit I recommend reading documentation which holds most answers for your questions. For example:

/// This method is created so that it can be called by handles. It only
/// cooks the input group of this SOP. The geometry in this group is
/// the only geometry manipulated by this SOP.
virtual OP_ERROR cookInputGroups(OP_Context &context,
int alone = 0);

Right in the header of the example you're referring to is the explanation. More over, if you look inside its definition (*.C file),you will notice that all it does is calling:

// implementation for just handling a point selection.
105  return cookInputPointGroups(...)

so you click doxygen link again and see...:

its declaration comment:

Quote

See cookInputPrimitiveGroups.

so you scroll or search down to find cookInputPrimitiveGroup and...

Quote

The cookInput.+Groups functions are helper functions that look at your Group Name and Group Type parameters (the offsets for which are passed in parm_index, for Group Name, and group_type_index, for group_type), evaluate them, and then call parse.+Group on that group name. For every method other than cookInputAllGroups, group_type_index is used only to determine whether the parm is dirty. The pointer group is set as a return value. If alone is true, we are cooking for a selector, and can't assume that our gdp is valid (because it might not have been constructed by now). If allow_reference is true, the group returned may not be modified. If fetchgdp is true and alone is true, these new groups will be created on the input_index-th input (because the gdp isn't constructed yet). If fetchgdp is true and alone is false, false, groups will be constructed on the current gdp. If fetchgdp is false, you must supply a gdp to create groups on in the paramerer pgdp.

you have the explanation. It's vague, true, because the subject is complicated, but gathering all comments to this point you at least have a picture of what is going on here. Afaik you shouldn't worry about it at this point, just implement your cookInputGroup along this example.

22 hours ago, Anas Alaa said:

private:
    void        getGroups(UT_String &str){ evalString(str, "group", 0, 0); }
    fpreal      AMP(fpreal t)           { return evalFloat("amp", 0, t); }
    fpreal      PHASE(fpreal t)         { return evalFloat("phase", 0, t); }
    fpreal      PERIOD(fpreal t)        { return evalFloat("period", 0, t); }
    /// This is the group of geometry to be manipulated by this SOP and cooked
    /// by the method "cookInputGroups".
    const GA_PointGroup *myGroup;

 

Quote

Here , I don't know what is fpreal ???

fpreal is Houdini's alias for floating point numbers (floats or doubles). By aliasing them (giving them custom name), SESI can control implementation and platform specific details. For example switch size of fpreal from 8byts to 4 bytes on some platform.

Quote

Are those a  type of variables or parameters ???

They are the type of the value returned by the parameter.

The way it is implemented in examples are just convention used by Houdini. You can use evalFloat() inside cookMySop() method too. Important consideration is multi-threading and locking of the node.

Quote

Also , why do we declare a group here though we are using OPLockInputs to lock our cooking to the input geo ??

Sorry, I don't understand that question.

22 hours ago, Anas Alaa said:

    // Here we determine which groups we have to work on.  We only
    // handle point groups.
    if (cookInputGroups(context) >= UT_ERROR_ABORT)
        return error(

Here , I don't understand what this means .

It means that  cookInputGroups(context)  can return one of error signals - most probably because node before your plugin returned error itself. Those errors signals are sorted in such a way, that those which are critical or invalidate further execution have greater values then those not so important. So in that case if error value is equal or greater than UT_ERROR_ABORT you know you should not go any further and return immediately. Again, just click doxygen link and see other options.

22 hours ago, Anas Alaa said:

    // If we've modified P, and we're managing our own data IDs,
    // we must bump the data ID for P.
    if (!myGroup || !myGroup->isEmpty())
        gdp->getP()->bumpDataId();

 

Also this , what is the difference between other data of the sop and our data ?? I think that my words don't actually mean anything ..

gdp collects information about geometry. Most of this is contained in multiply attributes objects (which are vector-like  underneath). "our own data" refers to those objects, because they are owned by gdp.

Attributes have IDs modified every time attribute's data is modified. This way Houdini can track changes in geometry (this technique is similar to generating hashes from values, but cheaper). bumpDataId() informs Houdini, that attribute (P in that case) was modified by the user. This information is available for other nodes and viewport, and triggers recooking of their output. A commend above the code just clarifies that we have an option to not to worry about updating ID by ourself. Houdini can do this automatically. From the constructor of this class:

// This indicates that this SOP manually manages its data IDs,
86  // so that Houdini can identify what attributes may have changed,
87  // e.g. to reduce work for the viewport, or other SOPs that
88  // check whether data IDs have changed.
89  // By default, (i.e. if this line weren't here), all data IDs
90  // would be bumped after the SOP cook, to indicate that
91  // everything might have changed.
92  // If some data IDs don't get bumped properly, the viewport
93  // may not update, or SOPs that check data IDs
94  // may not cook correctly, so be *very* careful!
95  mySopFlags.setManagesDataIDs(true);

so above comment simply states that we will inform Houdini about changes in geometry attributes by ourself (using bunbDataId())

 

 

 

Link to comment
Share on other sites

43 minutes ago, Anas Alaa said:

Wow man thanks for this very much.. 

What chapters are important in yhe documentation to start? As i don't find what I need to understand always.

That pretty much depends on what you're trying to do with HDK, but chapter about operators and geometry are the must. Also note that if I say read documentation I don't only mean reading introduction to HDK, but above all the docstrings of the classes and methods from HDK headers. They are not perfect source of informations, but they carry a lot of crucial details about HDK. 

I'm far from being an expert, but the way I do it, is by first finding an example which does the most similar thing to what I'm trying to do. Then reading its source couple of time. Then follow doxygen link of methods used by the example. Read its docstrings and those which are linked to them. If you encounger appendPointBlock in the code, read its docstring along with other similar functions (like appendPrimitiveBlock). If case of doubt I first create a simple command line app to test particular lines, and I carry on from that point.

Also note, that some of the older docstring are not in doxygen format, and you can't see them in docs' html page. You have to click headers' name at the very top of the page to open code preview, so you can read code along with docstring directly in the sources.

Some of the most commonly used headers you should read from top to bottom many times (like GA/GEO/GU_Detail.h - if you deal a lot with geometry).

HDK: Table Of Contents

 

Another important chapter:

GA Using Guide: Table Of Contents

 

Good luck!

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...