Tamis Posted June 12, 2008 Share Posted June 12, 2008 I have a few questions about a few things : I don't completely understand the logic behind the include files. How exactly do you you know what file to include when using a class. Is there some relationship between them? Another question: *gdp pointer in my cook method dose it represents the geometry of the SOP_Node? Is this the way to access all the points and attributes of a node? And yet another question: When i create a SOP_Node and manipulate the geometry in the cook method how do i return that geometry back to the node? And yet another question: Can i find a list some were were i can find Macro's? Srry if i asked any sorts of idiotic questions, i have been using C++ now for a month Quote Link to comment Share on other sites More sharing options...
malexander Posted June 13, 2008 Share Posted June 13, 2008 I don't completely understand the logic behind the include files.How exactly do you you know what file to include when using a class. Is there some relationship between them? Well, C++ doesn't apply any sort of standard to this, but most software development companies adopt one. We have our headers structured so that the class is the same name as the header. So, UT_String is found in UT_String.h (the prefix is the library the file belongs to, so you'll be including <UT/UT_String.h> or <GEO/GEO_Point.h>) gdp pointer in my cook method dose it represents the geometry of the SOP_Node?Is this the way to access all the points and attributes of a node? Yes, and yes. There are various accessors and methods in GU_Detail (the type of the gdb pointer) that allow you to manipulate them. There are many other classes in the GU, GQ, TS, GEO, GDT and GD libraries for specific operations (like skinning or extruding). This is a pretty large topic in itself to address in a forum post. When i create a SOP_Node and manipulate the geometry in the cook method how do i return that geometry back to the node? Well, I'd advise you to check out some of the example nodes ($HFS/toolkit/samples/SOP), but basically the geometry in the gdp pointer is the geometry attached to the node, so affecting that will affect that node's geometry. Can i find a list some were were i can find Macro's? Macros for doing what? We don't really have a giant list of all available macros. Quote Link to comment Share on other sites More sharing options...
sibarrick Posted June 13, 2008 Share Posted June 13, 2008 The most useful macros are in GB_ExtraMacros.h These loop through prims and points in various ways. This thread has some more useful info in it about them GB_Extramacros Also make sure you check out GQ_Detail if you are working with polys a lot. Quote Link to comment Share on other sites More sharing options...
Tamis Posted June 14, 2008 Author Share Posted June 14, 2008 thnx for the help sibarrick and malexander! Mind if i throw one more question out there? So oke, i can understand that gdp is the geometry. But by reading the documentation and looking at samples i managed to write my own operator. the thing is when i start Houdini and place my sop_node it doesn't show geometry. So now in the example SOP_Flatten i found cookInputGroups i can Imagen that this method is responsible for loading the node with geometry? Or am i talking rubbish here? Or did i do something wrong in the first place? The thing is i haven't found this method anywhere in the documentation? thanks allot for all the help! Quote Link to comment Share on other sites More sharing options...
sibarrick Posted June 15, 2008 Share Posted June 15, 2008 you call CookInputGroups from cookMySop in order to process the input group if you have a group parameter on your node. You might want to start with a node that doesn't use groups and then all you need to write is the cookMySop function. To modify geometry inside a cookMySop function you use the gdp to get the existing geometry and write back over it to change it. The gdp is a pointer and you use it to access points and prims etc. So in the flatten sop example it is used to get a pointer to the geometry points using the macro FOR_ALL_OPT_GROUP_POINTS(gdp, myGroup, ppt) then the point position is updated and written back over using the same point pointer ppt->getPos()(0) = p.x(); ppt->getPos()(1) = p.y(); ppt->getPos()(2) = p.z(); Also notice cookInputGroups gets called by this line if (error() < UT_ERROR_ABORT && cookInputGroups(context) < UT_ERROR_ABORT) but the gdp already exists, all this is doing is setting up myGroup which gets passed to the FOR_ALL_OPT_GROUP_POINTS macro. So the answer is no cookInputGroups doesn't get the geometry only the groups, cookMySop always has access to the geometry via the gdp pointer. Hope this helps. Quote Link to comment Share on other sites More sharing options...
Tamis Posted June 16, 2008 Author Share Posted June 16, 2008 Thnx for the help i think i got it. gdp->clearAndDestroy(); duplicateSource(0, context); Quote Link to comment Share on other sites More sharing options...
sibarrick Posted June 16, 2008 Share Posted June 16, 2008 Thnx for the help i think i got it. gdp->clearAndDestroy(); duplicateSource(0, context); yup. 2 pretty handy functions... Quote Link to comment Share on other sites More sharing options...
Tamis Posted June 17, 2008 Author Share Posted June 17, 2008 (edited) Here is my code for any one starting out. I hope this will make other beginning peoples life more easier. note: some statements in the comments i made might be false, i have assumed a lot of stuff that might not necessarily be true. .H #ifndef SOP_BLOWUP_H_ #define SOP_BLOWUP_H_ /*BASE class for all nodes*/ #include <SOP/SOP_Node.h> class SOP_BlowUp : public SOP_Node { public: SOP_BlowUp(OP_Network *net, const char *name, OP_Operator *op); ~SOP_BlowUp(); static OP_Node *MyConstructor(OP_Network*, const char *,OP_Operator *); static PRM_Template MyTemplatelist[]; private: const GB_PointGroup *myGroup; protected: virtual OP_ERROR cookMySop(OP_Context &context); }; #endif /*SOP_BLOWUP_H_*/ .CPP /*--------------------------------------------------*/ /*This macro and include files have methods in them to "trace"debug the node while houdini is running*/ #ifdef HDK_DEBUG #define UT_DEBUG #define UT_ASSERT_LEVEL 2 #endif #include <UT/UT_Debug.h> #include <UT/UT_Assert.h> /*--------------------------------------------------*/ /*Types in this case Matrix types that we can use to create/modifie houdini data*/ #include <UT/UT_Matrix3.h> #include <UT/UT_Matrix4.h> #include <UT/UT_Vector.h> #include <GB/GB_Element.h> /*Base class for geometry that comes from a node for example gdp or the return value of inputGeo which is the conetent of the connected node to the node we ar building */ #include <GU/GU_Detail.h> //Attribute Libary #include <GB/GB_Attribute.h> #include <GU/GU_PrimPoly.h> /*Math Module for doing math with known value types within houdini*/ #include <UT/UT_Math.h> /*Include file that makes houdini understand parameters*/ #include <PRM/PRM_Include.h> /* Operator type defenition include file.*/ #include <OP/OP_Operator.h> /*This is include has information about the version of houdini in it*/ #include <UT/UT_DSOVersion.h> /*The operator table that is needed to ad your own operator to*/ #include <OP/OP_OperatorTable.h> /*Main class that defines the node*/ #include "SOP_BlowUp.h" #include <iostream> /*Entry point for the compiler/Houdini its like the Main() Function in regular C++, each type of node you create has a diffrent entry point*/ void newSopOperator(OP_OperatorTable *table) { table->addOperator(new OP_Operator("SOP_BlowUp","SOP_BlowUp",SOP_BlowUp::MyConstructor,SOP_BlowUp::MyTemplatelist,1,1,0)); } /*By returning the contructor this dude becomes the constructor, this way houdini can ensure that things work out.*/ OP_Node *SOP_BlowUp::MyConstructor(OP_Network *net, const char *name, OP_Operator *op) { return new SOP_BlowUp(net, name, op); } /*The contructor inherits from the SOP_Node, so its the same as the constructor of SOP_Node this constructor altho you can't see it automaticly looks for the CookMySop Method*/ /*To my understanding this function it completly automated by inheariting from SOP_Node but i have seen that you can do call a few functions in here and set stuff up*/ SOP_BlowUp::SOP_BlowUp(OP_Network *net, const char *name, OP_Operator *op) : SOP_Node(net, name, op), myGroup(0) { } SOP_BlowUp::~SOP_BlowUp(void) {/*void*/} /*With the class PRM_Name it is posseble to create names for things that houdini API understands*/ static PRM_Name names[] = { PRM_Name("inv", "Inflate"), PRM_Name("gerlg", "wklg"), }; /*A list of Parameters -It's using PRM_Name to look up the name of the parameter-&names[] */ PRM_Template SOP_BlowUp::MyTemplatelist[]= { PRM_Template(PRM_FLT_J,1, &names[0]), PRM_Template(PRM_FLT_J,1, &names[1]), }; /*The cook method is the method that gets Executed once the node it activated or updated in other words -COOKED-*/ OP_ERROR SOP_BlowUp::cookMySop(OP_Context &context) { /*this function locks the node so no one can tutch it untill the function unlock input is called. this prevents the user from tampering with the node.*/ if (lockInputs(context) >= UT_ERROR_ABORT) return error(); /*-------------------------------------------------------------------------------------------------------------------*/ /*Lest first make sure that gdp has clean content*/ // gdp->clearAndDestroy(); /*First things first what we want is take the geometry from the nodes input and give it to our gdp(Geometry Detail Pointer) wich is our output.*/ /* inputGeo(INDEX,CONTEXT) will return the geometry of any input needed*/ duplicateSource(0,context,gdp,1); /*Printing to the console is easy:(standart iostream libary)*/ std::cout << "hello Houdini" << std::endl; /*Context is general variable for houdini*/ std::cout << "the time is: " << context.getTime() << std::endl; /*Here we use the macro FOR_ALL_PRIMITIVES to loop thrue the primitives*/ GEO_Primitive *prim; FOR_ALL_PRIMITIVES(gdp, prim) { std::cout << prim->getNum()<< std::endl; } /*Same example as a above but this time manually*/ /*This time we are going to move out geometry based on our Vector4*/ for(int i=0; i <= (gdp->primitives().entries()-1); i++) { std::cout << gdp->primitives()[i]->getNum() << std::endl; } /*using the evalFloat,evalInt,evalString function we can get the value of a parameter*/ float PARM = evalFloat(0, 0,context.myTime); /*A simple Decleration of a vector4(Point in space) left the last input default by not specifing it*/ UT_Vector4 offset(PARM,PARM,PARM); /*Compute normals*/ gdp->normal(); /*Here we will go into the points and offset the points by our Vector4 above*/ /*First we will locate the index of the attribute N*/ int Point_Attribute_Index = gdp->findPointAttrib("N",GB_ATTRIB_VECTOR); std::cout << "Normal Attribute Index: " << Point_Attribute_Index << std::endl; /*Here we start the loop thrue the points*/ for(int i=0; i <= (gdp->points().entries()-1);i++) { std::cout << gdp->points()[i]->getNum() << std::endl; /*Here we pick up the attribute data, we have to cast the return of getAttribData into a float because it is never serten what type it is.*/ float *Point_Normal = (float *)gdp->points()[i]->getAttribData(Point_Attribute_Index); /*Then we do the simple math*/ gdp->points()[i]->setPos(gdp->points()[i]->getPos() + (Point_Normal * offset)); } /*-------------------------------------------------------------------------------------------------------------------*/ // Here we unlock the node again. unlockInputs(); return error(); } Edited June 19, 2008 by Tamis added codebox Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.