FAQ FAQ      Search Search      Memberlist Memberlist      Usergroups Usergroups      Register Register      Profile Profile      Check private messages Check private messages      Log in Log in     

[HDK] Any GUI_PrimitiveHook example?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Houdini Forum Index -> Technical Discussion
View previous topic :: View next topic  
Author Message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Fri Aug 23, 2013 10:39 pm GMT    Post subject: [HDK] Any GUI_PrimitiveHook example? Reply with quote

Does anyone have working example? Can it be added to HDK help for reference?

Thanks

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
twod
Developer


Joined: 16 Aug 2002
Posts: 2969
Location: Side Effects

canada.gif
PostPosted: Sat Aug 24, 2013 8:59 am GMT    Post subject: Reply with quote

The prim tetra example in toolkit/samples has an example of how to use GUI_PrimitiveHook (and GR_Primitive).
Back to top
View user's profile Send private message Visit poster's website
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Sat Aug 24, 2013 9:17 am GMT    Post subject: Reply with quote

I'm on it! Thanks!
_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Mon Aug 26, 2013 7:12 pm GMT    Post subject: Reply with quote

I stripped all the code that I think I don't need from Tetra example but it seems that I'm missing something because it doesn't want to even register itself (and it doesn't show any errors too).

GR_GUIPrimitiveHook_template.h
Code:

#ifndef __GR_GUI_PRIMITIVE_HOOK_H_
#define __GR_GUI_PRIMITIVE_HOOK_H_

#include <GUI/GUI_PrimitiveHook.h>
#include <GR/GR_Primitive.h>

#include <GT/GT_GEOPrimitive.h>
#include <DM/DM_RenderTable.h>
#include <RE/RE_ElementArray.h>
#include <RE/RE_Geometry.h>
#include <RE/RE_LightList.h>
#include <RE/RE_ShaderHandle.h>
#include <RE/RE_VertexArray.h>

#define THIS_HOOK_NAME "GR_GUIPrimitiveHook_Template"
#define THIS_PRIMITIVE_NAME "GR_Primitive_Template"

namespace Mantragora
{
   namespace Viewport
   {
      // primitive
      class GR_Primitive_Template : public GR_Primitive
      {
      public:
         GR_Primitive_Template(const GR_RenderInfo* info, const char* cache_name, const GEO_Primitive* prim);
         virtual   ~GR_Primitive_Template();
         virtual const char* className() const;

         virtual GR_PrimAcceptResult   acceptPrimitive(GT_PrimitiveType t, int geo_type, const GT_PrimitiveHandle& ph, const GEO_Primitive* prim);
         virtual void resetPrimitives();

         virtual void update(RE_Render* r, const GT_PrimitiveHandle& primh, const GR_UpdateParms& p);
         virtual void render(RE_Render* r, GR_RenderMode render_mode, GR_RenderFlags   flags, const GR_DisplayOption* opt, const RE_MaterialList* materials);

      private:
         int   _myID;
         RE_Geometry* _myGeo;

         bool _ogl3;
      };

      // hook
      class GR_GUIPrimitiveHook_Template : public GUI_PrimitiveHook
      {
      public:
         GR_GUIPrimitiveHook_Template();
         virtual ~GR_GUIPrimitiveHook_Template();
         virtual GR_Primitive* createPrimitive(const GT_PrimitiveHandle& gt_prim, const GEO_Primitive* geo_prim, const GR_RenderInfo* info, const char* cache_name, GR_PrimAcceptResult& processed);
      };
   }
}

#endif


GR_GUIPrimitiveHook_template.cpp
Code:

#include "GR_GUIPrimitiveHook_template.h"
#include <ostream>

using namespace Mantragora::Viewport;
using std::cout;
using std::endl;

// hook registration ------------------------------------------------------------------------
void newRenderHook(DM_RenderTable *table)
{
   cout << "registering!" << endl;
   const int prim_hook_priority = 0;

   table->registerGEOHook(new GR_GUIPrimitiveHook_Template,
                     GA_PrimitiveTypeId(GA_PRIMPOLYSOUP),
                     prim_hook_priority);
}

// hook initialization ------------------------------------------------------------------------
GR_GUIPrimitiveHook_Template::GR_GUIPrimitiveHook_Template(): GUI_PrimitiveHook(THIS_HOOK_NAME)
{
   cout << "constructor!" << endl;
}
GR_GUIPrimitiveHook_Template::~GR_GUIPrimitiveHook_Template() {}
GR_Primitive* GR_GUIPrimitiveHook_Template::createPrimitive(const GT_PrimitiveHandle& gt_prim, const GEO_Primitive* geo_prim, const GR_RenderInfo* info, const char* cache_name, GR_PrimAcceptResult& processed)
{
   cout << "creating primitive!" << endl;
   return new GR_Primitive_Template(info, cache_name, geo_prim);
}

// primitive initialization ------------------------------------------------------------------------
GR_Primitive_Template::GR_Primitive_Template(const GR_RenderInfo* info, const char* cache_name, const GEO_Primitive* prim): GR_Primitive(info, cache_name, GA_PrimCompat::TypeMask(0))
{
   cout << "primitive initialization!" << endl;
   _myID = prim->getTypeId().get();
   _myGeo = NULL;
}
GR_Primitive_Template::~GR_Primitive_Template() { delete _myGeo; }
const char* GR_Primitive_Template::className() const { return THIS_PRIMITIVE_NAME; }

GR_PrimAcceptResult GR_Primitive_Template::acceptPrimitive(GT_PrimitiveType t, int geo_type, const GT_PrimitiveHandle& ph, const GEO_Primitive* prim)
{
   cout << "accept primitive!" << endl;

   if (geo_type == _myID)
   {
      cout << "processing!" << endl;
      return GR_PROCESSED;
   }

   return GR_NOT_PROCESSED;
}

void GR_Primitive_Template::resetPrimitives() {}

// main() ------------------------------------------------------------------------
void GR_Primitive_Template::update(RE_Render* r, const GT_PrimitiveHandle& primh, const GR_UpdateParms& p)
{
   cout << "update!" << endl;
}
void
GR_Primitive_Template::render(RE_Render* r, GR_RenderMode render_mode, GR_RenderFlags flags, const GR_DisplayOption* opt, const RE_MaterialList* materials)
{
   cout << "render!" << endl;
}


I checked it with HDK documentation and it looks that it should work, so what am I missing ?

Can you guys give us a little smaller example than Tertra that also uses newRenderHook() directly instead of registerMyself()? You know, something that uses native primitives and have less than 11 files Wink

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
twod
Developer


Joined: 16 Aug 2002
Posts: 2969
Location: Side Effects

canada.gif
PostPosted: Fri Aug 30, 2013 1:38 pm GMT    Post subject: Reply with quote

I'm not in front of a system with Houdini on it this week, so I'm afraid I can't test your code. When you say it isn't registering, do you mean that newRenderHook isn't being called? Try including UT_Version.h and see if that helps. Also set the env variable HOUDINI_DSO_ERROR to 1 to see if any errors are being generated when Houdini starts.

If it is registering but not creating a primitive, I suspect that the iterative detail refinement process is somehow not reaching the GEO_PrimPolySoup point, somehow being caught befoby a native primitive before your hook has processed it. I'll take a look when I'm back in the office next week.

Adding a simple example or two would be a good idea. There are a lot of DM scene hooks, but the primitive hooks are a bit sparse.
Back to top
View user's profile Send private message Visit poster's website
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Fri Aug 30, 2013 3:06 pm GMT    Post subject: Reply with quote

twod wrote:
Try including UT_Version.h and see if that helps. Also set the env variable HOUDINI_DSO_ERROR to 1 to see if any errors are being generated when Houdini starts.


UT_Version.h didn't help but HOUDINI_DSO_ERROR did and told me that it should be UT_DSOVersion.h Wink. Thank you.

twod wrote:

If it is registering but not creating a primitive, I suspect that the iterative detail refinement process is somehow not reaching the GEO_PrimPolySoup point, somehow being caught befoby a native primitive before your hook has processed it. I'll take a look when I'm back in the office next week.


After adding UT_DSOVersion.h I still don't get any output from it on any stage. It doesn't cout from newRenderHook() or any other place.

twod wrote:

Adding a simple example or two would be a good idea. There are a lot of DM scene hooks, but the primitive hooks are a bit sparse.


Yeah. Example how to replace rendering of native primitive or how to add decorations/extend rendering of native primitive would be great.

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Fri Sep 06, 2013 5:15 am GMT    Post subject: Reply with quote

twod wrote:

...I'll take a look when I'm back in the office next week.

Adding a simple example or two would be a good idea. There are a lot of DM scene hooks, but the primitive hooks are a bit sparse.


Any news on this topic?

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
twod
Developer


Joined: 16 Aug 2002
Posts: 2969
Location: Side Effects

canada.gif
PostPosted: Mon Sep 09, 2013 11:21 am GMT    Post subject: Reply with quote

The reason that your hook is not registering is because the newRenderHook() function takes a GR_RenderHook * parameter, not a DM_RenderHook *. In order to support both H11 and the GL viewports, the GR_RenderHook * parameter was maintained. However, it will always be a DM_RenderHook object passed, so you can safely cast it to a DM_RenderHook.

Currently it is not possible to hook on a polysoup, as this is running into problems with polygon collection, which combines all polygon-based primitives into a large soup for rendering. We'll look into patching this for the next major version of Houdini (a backport might be possible).
Back to top
View user's profile Send private message Visit poster's website
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Mon Sep 09, 2013 2:49 pm GMT    Post subject: Reply with quote

twod wrote:
The reason that your hook is not registering is because the newRenderHook() function takes a GR_RenderHook * parameter, not a DM_RenderHook *. In order to support both H11 and the GL viewports, the GR_RenderHook * parameter was maintained. However, it will always be a DM_RenderHook object passed, so you can safely cast it to a DM_RenderHook.


OK. I'm soo totally lost after what you said here.

There are two versions of "newRenderHook()" function, one takes "GR_RenderTable*" and second "DM_RenderTable*". I don't see any overloaded version that takes "GR_RenderHook*" or "DM_RenderHook*" so I suppose I'm missing some very important part here.

BTW. Is there "DM_RenderHook" class at all anywhere in HDK? Are you guys have part there Wink

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me


Last edited by mantragora on Mon Sep 09, 2013 3:02 pm GMT; edited 1 time in total
Back to top
View user's profile Send private message
twod
Developer


Joined: 16 Aug 2002
Posts: 2969
Location: Side Effects

canada.gif
PostPosted: Mon Sep 09, 2013 3:01 pm GMT    Post subject: Reply with quote

Sorry, brain apparently took awhile to get moving this morning. Instead of "_RenderHook", I meant "_RenderTable". Corrected:
Quote:
The reason that your hook is not registering is because the newRenderHook() function takes a GR_RenderTable * parameter, not a DM_RenderTable *. In order to support both H11 and the GL viewports, the GR_RenderTable * parameter was maintained. However, it will always be a DM_RenderTable object passed, so you can safely cast it to a DM_RenderTable.


So, just change your newRenderHook() method to:
Code:
void newRenderHook(GR_RenderTable *table)
{
   cout << "registering!" << endl;
   const int prim_hook_priority = 0;

   static_cast<DM_RenderTable *>(table)->registerGEOHook(new GR_GUIPrimitiveHook_Template,
                     GA_PrimitiveTypeId(GA_PRIMPOLYSOUP),
                     prim_hook_priority);
}
Back to top
View user's profile Send private message Visit poster's website
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Mon Sep 09, 2013 3:14 pm GMT    Post subject: Reply with quote



Thank you and have a good day.

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Mon Sep 09, 2013 4:13 pm GMT    Post subject: Reply with quote

It's alive... well, partially.

It does register but doesn't call "createPrimitive()" and since it's the only virtual method (beside destructor) that I can mess with inside the hook and it only returns "new GR_Primitive_Template", I suppose "priority" parameter may have something to do with lack of any other sign from the hook. I tried setting it from 0 to 10 but nothing changed. Should I set it to something else ?

twod wrote:

If it is registering but not creating a primitive, I suspect that the iterative detail refinement process is somehow not reaching the GEO_PrimPolySoup point, somehow being caught befoby a native primitive before your hook has processed it. I'll take a look when I'm back in the office next week.


Yup, this is what I got.

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Tue Sep 10, 2013 5:27 pm GMT    Post subject: Reply with quote

twod wrote:

If it is registering but not creating a primitive, I suspect that the iterative detail refinement process is somehow not reaching the GEO_PrimPolySoup point, somehow being caught befoby a native primitive before your hook has processed it. I'll take a look when I'm back in the office next week.


I think that without working example that shows how to replace shading of native primitive I will not move this rock. It doesn't even touch createPrimitive() method.

It would be good to update documentation also because it still shows newRenderHook() version of the code that doesn't work, so if someone would like to follow (and doesn't know this topic) will hit the same wall as me.

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Fri Sep 13, 2013 7:46 pm GMT    Post subject: Reply with quote

I made couple more tests with Tetra example.
1. Modified GU_PrimTetra::registerMyself() method by moving DM_RenderTable::getTable()->registerGEOHook() to newRenderHook() that I added to GR_PrimTetra.C.
2. Instead of PrimTetra id I passed GA_PrimitiveTypeId(GEO_PRIMPOLY) to registerGEOHook()

Questions:
As I understand, by passing different ID to registerGEOHook(), it should now react to any polygonal geometry that I place because of GEO_PRIMPOLY passed instead of PrimTetra ID, but it still reacts only when I place PrimTetra node. Why is that?

I uncommented TETRA_GR_PRIMITIVE and TETRA_GR_PRIM_COLLECTION in tetra example so it should use Hook for rendering and creating primitive, but it doesn't look like it because it also never reaches createPrimitive() method and after primitive detection jumps to GU_PrimTetra::build() method. Why?

I really would be very grateful for native primitive example.

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
twod
Developer


Joined: 16 Aug 2002
Posts: 2969
Location: Side Effects

canada.gif
PostPosted: Tue Sep 24, 2013 3:16 pm GMT    Post subject: Reply with quote

There are now two examples and a template GUI class with documentation in H13. It's also now possible to hook on GEO primitives which the GT refinement classes would otherwise consume. It doesn't look like it can be backported to 12.5, but let me know if this is a showstopper and I'll see what can be done.
Back to top
View user's profile Send private message Visit poster's website
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Tue Sep 24, 2013 8:23 pm GMT    Post subject: Reply with quote

Thank you. I'm not in Houdini last two weeks at all so I will check it when I have opportunity to come back to it.
_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Sun Nov 03, 2013 8:12 pm GMT    Post subject: Reply with quote

Ok, we are back in game. I didn't checked examples yet but even the code above reported correctly from update() and render() in H13. Thanks.
_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Mon Nov 04, 2013 9:50 pm GMT    Post subject: Reply with quote

Couple questions.

1. Lets start from registration. If I don't want to modify my geometry but just change its color, should I pass GUI_HOOK_FLAG_AUGMENT_PRIM? Will it be sufficient?

2. Now we are in update(). Is there a way to process copy of geometry there without building array of points and rebuilding everything again?

3. If I want to have different color on each of my polygon, can I send multiple primitives from update in a group and then shade each differently in my custom shade function (by accessing my RE_Geometry* and comparing some stuff there) before they will get shaded, or should I just send each polygon separately and process one by one?

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
twod
Developer


Joined: 16 Aug 2002
Posts: 2969
Location: Side Effects

canada.gif
PostPosted: Mon Nov 04, 2013 10:45 pm GMT    Post subject: Reply with quote

Quote:
1. Lets start from registration. If I don't want to modify my geometry but just change its color, should I pass GUI_HOOK_FLAG_AUGMENT_PRIM? Will it be sufficient?

"Augment Prim" is meant to add additional custom rendering on top of a native Houdini primitive that is already rendering in the viewport. For example, if you wanted to add custom rendering to a volume primitive, such as a vector field, while letting Houdini render the volume.

If you're doing all the rendering yourself, you don't want AUGMENT_PRIM.

Quote:
2. Now we are in update(). Is there a way to process copy of geometry there without building array of points and rebuilding everything again?

Currently no, though certain update reasons can allow you to keep a good chunk of your vertex arrays intact (GR_GEO_SELECTION_CHANGED, GR_INSTANCE_PARMS_CHANGED). Generally on GR_GEO_CHANGED and GR_GEO_TOPOLOGY_CHANGED (which you will currently always get together), you'll have to rebuild your geometry.

There is some infrastructure in place in GEO/GR to determine if a given attribute has changed (GA_Attribute::getDataId()/assignNewDataId()/bumpDataId()). However, this requires SOP support, which wasn't able to be addressed before the H13 release buzzer went off. This will be hopefully be addressed soon. If you have a custom SOP and can figure out which attributes need updating, you can program this into the SOP itself (which is a topic unto itself).

Alembic primitives currently use this DataID system (via GT_DataArray::getDataId()). However, because Alembic primitives do not create GU_Details (they directly create GT_Primitives), any custom hooks that hook on GEO_Primitives won't be called.

Quote:
3. If I want to have different color on each of my polygon, can I send multiple primitives from update in a group and then shade each differently in my custom shade function (by accessing my RE_Geometry* and comparing some stuff there) before they will get shaded, or should I just send each polygon separately and process one by one?

You really don't want to draw polygons one by one. GL will hate you Smile The way our stuff handles multiple materials is to partition the polygons into different connection groups (see RE_Geometry::connect*PrimsI() methods). Then the draw code cycles through the materials and draws group-by-group. If you have a small palette of colors, that might be an acceptable solution (push color, draw group, push next color, draw group, etc).

If your polygon colors are instead essentially random, you can also send the polygon color to the shader directly. It's important to note that OpenGL does not support primitive attributes directly, nor can you easily look up a gl_PrimitiveID for a polygon (GL likes triangles). So, you can go the GL2 route and send the position/color pair for every vertex in the polygon, which adds up quickly for large meshes.

Or, you can go the GL3 route and use a textureBuffer and index it with gl_PrimitiveID. The trick there is that you need to first convert your polygons to triangles. If they're already triangles, you're in luck - you just need to do a texelFetch(attrCd, gl_PrimitiveID) in the shader. If they're quads tessellated to triangles, it's texelFetch(attrCd, gl_PrimitiveID/2). Variable-sided polygons are the most tricky, as you then need to tessellate each one to triangles and repeat the color for each triangle in the polygon, then index with gl_PrimitiveID.

You can create a primitive attribute in RE_Geometry:

Code:
(RE_Geometry*)->setNumPrimitives( num_color_entries );
Cd = (RE_Geometry*)->createAttribute(r, "Cd", RE_GPU_FLOAT32, 3, col_data, RE_ARRAY_PRIMITIVE);

where col_data is sizeof(float)*3*num_color_entries long, and then access this in the fragment shader via:
Code:

uniform samplerBuffer attrCd;
....
vec3 Cd = texelFetch(attrCd, gl_PrimitiveID).rgb;

You'll need to use at least #version 140 or #extension GL_EXT_gpu_shader4 : enable for that shader to compile correctly.

Vertex attributes can be index in a similar fashion (gl_PrimitiveIDIn*3), but you need a geometry shader to process the triangle and emit each vertex with a different color. Point and Detail attributes are definitely the easiest to work with.
Back to top
View user's profile Send private message Visit poster's website
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Thu Nov 07, 2013 12:59 am GMT    Post subject: Reply with quote

There are three overloaded versions of connectIndexedPrimsI().

I'm recreating geometry and switch()-ing based on how many points my polygon have to add it to correct group.
I don't have problem with specifying how my prims should be connected for knows polygons. I know that I may have quads so I pass how they should be connected ({0,1, 1,2, 2,3, 3,0}). The problem starts when I get N-gons. I can construct array automatically but this method needs const array so I can't compile because size of this array is unknown on runtime.

Two other versions of this function takes RE_ElementArray and RE_VertexArray, but I don't know how to use them.

So how to approach reconstruction of N-gons?

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
twod
Developer


Joined: 16 Aug 2002
Posts: 2969
Location: Side Effects

canada.gif
PostPosted: Thu Nov 07, 2013 1:56 pm GMT    Post subject: Reply with quote

RE_ElementArray gives you the ability to add primitive connectivity indices in a fairly easy way:

Code:
RE_ElementArray *elem = new RE_ElementArray();

elem->setPrimitiveType(RE_PRIM_POLYGONS);
elem->tessellateToTriangles(true);  // basically creates a trifan, no complex convexing

elem->beginPrims(r, true, num_vertices_hint);

elem->addPrim(r, num_points_in_polygon, point_indices);
// add more polygons...

elem->endPrims(r);

regeometry->connectIndexedPrimsI(r, 0, elem);


The RE_Geometry class takes ownership of the element array. If you have a set of constant sided-polygons, you can call addPrims() instead with the entire list of vertices (say, for RE_PRIM_QUADS), and that's a bit faster.

Also, by "point indices" I mean the index of the point in your vertex array, not a Houdini GA_Index of a point in the detail.
Back to top
View user's profile Send private message Visit poster's website
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Fri Nov 08, 2013 5:20 pm GMT    Post subject: Reply with quote

Thanks for answers. This ElementArray looks tasty Smile.

I should have some time this weekend so I will sit to this again.

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Mon Nov 11, 2013 2:46 pm GMT    Post subject: Reply with quote

Couple problems:

1. My geometry doesn't update when it changes. If I bump up amount of points it's still shaded in the same way as it was when I turned on hook first time. I thought that GR_GEO_TOPOLOGY_CHANGED should force it to update, no?

2. Another thing is, when I turn on the hook it changes colors of persp and cam options in viewport, why? (see attached pic)

3. I thought that when the hook is not turned on, Houdini will create geometry as always, but instead it doesn't create any geometry and I get empty viewport. Is there a way to force it to use standard way of rendering when hook is not ON?

4. Also, if there is more than one OBJ node in scene, only geometry from one of them is shaded and second one is not, why?

Below is updated code:

DEFINE_GUI_ColorTopology.h
Code:

#ifndef _DEFINE_GUI_COLOR_TOPOLOGY_
#define _DEFINE_GUI_COLOR_TOPOLOGY_

// ------------------ INCLUDES ------------------ //

#include <GUI/GUI_PrimitiveHook.h>
#include <UT/UT_DSOVersion.h>
#include <GR/GR_Primitive.h>
#include <GR/GR_GeoRender.h>
#include <GR/GR_DisplayOption.h>
#include <GR/GR_OptionTable.h>
#include <GR/GR_UserOption.h>
#include <GR/GR_UtilsGL3.h>
#include <GEO/GEO_PrimPoly.h>
#include <GT/GT_GEOPrimitive.h>
#include <DM/DM_RenderTable.h>
#include <RE/RE_Geometry.h>
#include <RE/RE_ElementArray.h>

#include <vector>
#include <ostream>

// ------------------ SETTINGS ------------------ //

// hook and primitive class names
#define THIS_HOOK_NAME "GUI_ColorTopology"
#define THIS_PRIMITIVE_NAME "GR_ColoredPrimitive"

// option settings
#define TOPOLOGY_COLOR_OPTION_NAME "color_topology"
#define TOPOLOGY_COLOR_OPTION_LABEL "Color Topology"

// topology groups
enum TOPOLOGY_POLYGON_GROUP_OF
{
   TWO = 2,
   THREE,
   FOUR,
   FIVE,
   SIX,
   MORE_THAN_SIX
};

// ------------------ DEBUG ------------------
//#define PRINT_REPORT
#define REPORT(what, report) std::cout << what << report << std::endl;

#endif


GUI_ColorTopology.h
Code:

#ifndef _GUI_COLOR_TOPOLOGY_
#define _GUI_COLOR_TOPOLOGY_

#include "DEFINE_GUI_ColorTopology.h"

namespace Mantragora
{
    namespace Viewport
   {   
      // hook ------------------------------------------------------------------
      class GUI_ColorTopologyHook : public GUI_PrimitiveHook
      {
      public:
         GUI_ColorTopologyHook();

         virtual
         ~GUI_ColorTopologyHook();

         virtual auto
         createPrimitive(const GT_PrimitiveHandle& gt_prim, const GEO_Primitive* geo_prim, const GR_RenderInfo* info, const char* cache_name, GR_PrimAcceptResult& processed)
         -> GR_Primitive*;
      };

      // primitive -------------------------------------------------------------
      class GR_ColoredPrimitive : public GR_Primitive
      {
      public:
         // STANDARD CLASS METHODS -------------------------------------------------
         GR_ColoredPrimitive(const GR_RenderInfo* info, const char* cache_name, const GEO_Primitive* prim);

         virtual   
         ~GR_ColoredPrimitive();

         virtual auto
         className() const
         -> const char*;

         virtual auto
         acceptPrimitive(GT_PrimitiveType t, int geo_type, const GT_PrimitiveHandle& ph, const GEO_Primitive* prim)
         -> GR_PrimAcceptResult;

         // GEOMETRY PROCESSING -------------------------------------------------
         virtual auto
         update(RE_Render* r, const GT_PrimitiveHandle& primh, const GR_UpdateParms& p)
         -> void;

         virtual auto
         render(RE_Render* r, GR_RenderMode render_mode, GR_RenderFlags flags, const GR_DisplayOption* opt, const RE_MaterialList* materials)
         -> void;
   
         // HOOK ON/OFF -------------------------------------------------       
         virtual auto
         renderDecoration(RE_Render* r, GR_Decoration decor, const GR_DecorationParms& p)
         -> void;
         
      private:
         // CUSTOM SHADING -------------------------------------------------
         auto
         _ColorTopology(RE_Render*r, const GR_DisplayOption* opts)
         -> void;

         // HELPERS & OTHER -------------------------------------------------
         auto
         _RecreatePolygon(RE_Render* r, const GEO_PrimPoly* polygon, int npts, RE_Geometry* geo, int group, RE_PrimType type)
         -> void;

         auto
         _MakeIndices(unsigned int howmany)
         -> std::vector<int>;

         RE_Geometry* _myGeo;
      };
   }
}

#endif



GUI_ColorTopology.cpp
Code:

#include "GUI_ColorTopology.h"
using namespace Mantragora::Viewport;

// HOOK_REGISTRATION ------------------------------------------------------------------------
void newRenderHook(GR_RenderTable *table)
{
    DM_RenderTable* dm_table = static_cast<DM_RenderTable*>(table);
    const int priority = 0;

    // register hook
    dm_table->registerGEOHook(new GUI_ColorTopologyHook(), GA_PrimitiveTypeId(GA_PRIMPOLY), priority, GUI_HOOK_FLAG_NONE);
    // register custom display option
    dm_table->installGeometryOption(TOPOLOGY_COLOR_OPTION_NAME, TOPOLOGY_COLOR_OPTION_LABEL);
}

// HOOK_INITIALIZATION ------------------------------------------------------------------------
GUI_ColorTopologyHook::GUI_ColorTopologyHook() : GUI_PrimitiveHook(THIS_HOOK_NAME){}
GUI_ColorTopologyHook::~GUI_ColorTopologyHook(){}

auto
GUI_ColorTopologyHook::createPrimitive(const GT_PrimitiveHandle& gt_prim, const GEO_Primitive* geo_prim, const GR_RenderInfo* info, const char* cache_name, GR_PrimAcceptResult& processed)
-> GR_Primitive*
{
   // catch our primitive to prevent other hooks from taking over it
    if(geo_prim->getTypeId().get() == GA_PRIMPOLY)
    {
      processed = GR_PROCESSED;
      return new GR_ColoredPrimitive(info, cache_name, geo_prim);
    }
   
    return NULL;
}

// PRIMITIVE INITIALIZATION ------------------------------------------------------------------------
GR_ColoredPrimitive::GR_ColoredPrimitive(const GR_RenderInfo* info, const char* cache_name, const GEO_Primitive* prim) : GR_Primitive(info, cache_name, GA_PrimCompat::TypeMask(0)) { _myGeo = NULL; }
GR_ColoredPrimitive::~GR_ColoredPrimitive() { delete _myGeo; }

auto
GR_ColoredPrimitive::className() const
-> const char*
{ return THIS_PRIMITIVE_NAME; }

auto
GR_ColoredPrimitive::acceptPrimitive(GT_PrimitiveType t, int geo_type, const GT_PrimitiveHandle& ph, const GEO_Primitive* prim)
-> GR_PrimAcceptResult
{
    if(geo_type == GA_PRIMPOLY)
   return GR_PROCESSED;
   
    return GR_NOT_PROCESSED;
}

// HOOK ON/OFF -------------------------------------------------       
auto
GR_ColoredPrimitive::renderDecoration(RE_Render* r, GR_Decoration decor, const GR_DecorationParms& p)
-> void
{   
   if(decor >= GR_USER_DECORATION)
   {
      // find what option is selected
      int index = decor - GR_USER_DECORATION;
      const GR_UserOption* option = GRgetOptionTable()->getOption(index);

      // set rendering based on selected option
      if(!strcmp(option->getName(), TOPOLOGY_COLOR_OPTION_NAME)) _ColorTopology(r, p.opts);
   }
}

// CUSTOM SHADING -------------------------------------------------
auto
GR_ColoredPrimitive::_ColorTopology(RE_Render* r, const GR_DisplayOption* opts)
-> void
{      
   // enable smooth lines if the option is on
   if(opts->common().antiAliasedLines())
   {
      r->pushSmoothLines();
      r->smoothBlendLines(RE_SMOOTH_ON);
   }
   
   if(getRenderVersion() >= GR_RENDER_GL3)
   {      
      r->pushShader(GR_UtilsGL3::getWireShader(r));
         
      // TODO: color for OGL3
   
      r->popShader();   
   }
   else
   {
      r->pushColor((UT_Color(UT_RGB, 0.9, 0.45, 0.0)));
      _myGeo->draw(r, TWO);

      r->pushColor(UT_Color(UT_RGB, 0.9, 0.9, 0.3));
      _myGeo->draw(r, THREE);

      r->pushColor((UT_Color(UT_RGB, 0.15, 0.9, 0.15)));
      _myGeo->draw(r, FOUR);

      r->pushColor((UT_Color(UT_RGB, 0.23, 0.9, 0.9)));
      _myGeo->draw(r, FIVE);

      r->pushColor((UT_Color(UT_RGB, 0.12, 0.5, 0.9)));
      _myGeo->draw(r, SIX);

      r->pushColor((UT_Color(UT_RGB, 0.56, 0.22, 0.9)));
      _myGeo->draw(r, MORE_THAN_SIX);

      r->popColor();
   }

   r->popLineWidth();
   r->popPointSize();

   //r->popLineStyle();
   if(opts->common().antiAliasedLines()) r->popSmoothLines();
}

// GEOMETRY PROCESSING -------------------------------------------------
auto
GR_ColoredPrimitive::update(RE_Render* r, const GT_PrimitiveHandle& primh, const GR_UpdateParms& p)
-> void
{
    if(p.reason & (GR_GEO_CHANGED |
               GR_GEO_TOPOLOGY_CHANGED))
    {            
      // get polygon
      auto prim = static_cast<const GT_GEOPrimitive*>(primh.get());
      auto poly = static_cast<const GEO_PrimPoly*>(prim->getPrimitive(0));

#ifdef PRINT_REPORT
      REPORT("VTX count: ", poly->getVertexCount());
      REPORT("Prim number: ", poly->getNum());
#endif // PRINT_REPORT
   
      // create new geo based on polygon point count
      auto points = poly->getPointRange();
      auto npts = points.getEntries();
      auto new_geo = false;      
      if(!_myGeo)
      {
         _myGeo = new RE_Geometry(npts);
         new_geo = true;
      }

      // create position array and populate it   
      UT_Vector3FArray positions;
      for(GA_Iterator pointIt(points); !pointIt.atEnd(); pointIt.advance())
      {
         // get point position
         auto currentPosition = poly->getDetail().getPos3(*pointIt);
               
         // add position to array
         positions.append(currentPosition);
      }
            
      if(getRenderVersion() >= GR_RENDER_GL3) _myGeo->createAttribute(r, "P", RE_GPU_FLOAT32, 3, positions.array()->data());
      else _myGeo->createArray(r, RE_BUFFER_POSITION, 0, RE_GPU_FLOAT32, 3, positions.array()->data());
      
      if(new_geo)
      {            
         // connect and add to correct group based on point count            
         switch(npts)
         {
         case TWO:
            _RecreatePolygon(r, poly, npts, _myGeo, TWO, RE_PRIM_LINES);
            break;
         case THREE:
            _RecreatePolygon(r, poly, npts, _myGeo, THREE, RE_PRIM_TRIANGLES);
            break;
         case FOUR:
            _RecreatePolygon(r, poly, npts, _myGeo, FOUR, RE_PRIM_QUADS);
            break;
         case FIVE:
            _RecreatePolygon(r, poly, npts, _myGeo, FIVE, RE_PRIM_POLYGONS);
            break;
         case SIX:
            _RecreatePolygon(r, poly, npts, _myGeo, SIX, RE_PRIM_POLYGONS);
            break;
         }

         if (npts >= MORE_THAN_SIX) _RecreatePolygon(r, poly, npts, _myGeo, MORE_THAN_SIX, RE_PRIM_POLYGONS);
      }
    }
}

auto
GR_ColoredPrimitive::render(RE_Render* r, GR_RenderMode render_mode, GR_RenderFlags flags, const GR_DisplayOption* opt, const RE_MaterialList* materials)
-> void

   // The native Houdini primitive for primpoly will do the rendering.
}

// HELPERS & OTHER -------------------------------------------------
auto
GR_ColoredPrimitive::_RecreatePolygon(RE_Render* r, const GEO_PrimPoly* polygon, int npts, RE_Geometry* geo, int group, RE_PrimType type)
-> void
{
   auto elements = new RE_ElementArray();

   elements->setPrimitiveType(type);
   elements->tessellateToTriangles(true);

   elements->beginPrims(r, true, npts);
   elements->addPrim(r, npts, &_MakeIndices(npts)[0]);
   elements->endPrims(r);

   _myGeo->connectIndexedPrimsI(r, group, elements);    
}

auto
GR_ColoredPrimitive::_MakeIndices(unsigned int howmany)
-> std::vector<int>
{   
   std::vector<int> indices;
   for(unsigned i = 0; i < howmany; i++) indices.push_back(i);

   return indices;
}



wtf.jpg
 Description:
 Filesize:  25.17 KB
 Viewed:  2305 Time(s)

wtf.jpg



_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
twod
Developer


Joined: 16 Aug 2002
Posts: 2969
Location: Side Effects

canada.gif
PostPosted: Mon Nov 11, 2013 4:34 pm GMT    Post subject: Reply with quote

Quote:
1. My geometry doesn't update when it changes. If I bump up amount of points it's still shaded in the same way as it was when I turned on hook first time. I thought that GR_GEO_TOPOLOGY_CHANGED should force it to update, no?

Is your update method not being called when you alter the geometry? (how are you changing the #points?)

Quote:
2. Another thing is, when I turn on the hook it changes colors of persp and cam options in viewport, why? (see attached pic)

You've pushed the color 6x, and only popped it once. Try pushColor(), setColor() x5, popColor() instead. The RE push/pop methods are stack-based and need to be paired.

Quote:
3. I thought that when the hook is not turned on, Houdini will create geometry as always, but instead it doesn't create any geometry and I get empty viewport. Is there a way to force it to use standard way of rendering when hook is not ON?

If you return GR_PROCESSED from your hook, it assumes your hook is entirely taking care of the rendering. Return GR_PROCESSED_NON_EXCLUSIVE instead if you still want the Houdini geometry to appear. There is currently no way to have the Houdini geometry update but not render while your hook is active (nor can I really think of a way that this could be done).

I would enable polygon offset and render your polygons with negative offsets so that they appear in front of the Houdini geometry, possibly with blending so that you can see the underlying shading.

Quote:
4. Also, if there is more than one OBJ node in scene, only geometry from one of them is shaded and second one is not, why?

I'm not sure what you mean by 'shaded'. Perhaps try fixing the color bug above,as that's going to cause some problems.

Also, this hook isn't going to scale well with thousands of polygons. Do you have plans to collect multiple polygons and process them all in one hook?
Back to top
View user's profile Send private message Visit poster's website
mantragora
Houdini Adept


Joined: 08 Dec 2011
Posts: 197

blank.gif
PostPosted: Mon Nov 11, 2013 4:44 pm GMT    Post subject: Reply with quote

twod wrote:

Also, this hook isn't going to scale well with thousands of polygons. Do you have plans to collect multiple polygons and process them all in one hook?


Yes I do, but first I want to get comfortable with what's happening there.

twod wrote:

Is your update method not being called when you alter the geometry? (how are you changing the #points?)


If I place circle and start changing amount of points, color stays the same and geometry is redrawed like if it had still the same amount of points.

twod wrote:

I'm not sure what you mean by 'shaded'. Perhaps try fixing the color bug above,as that's going to cause some problems.


I'm mean colored.

Thanks.

_________________
magic happens here... sometimes

Vimeo
Twitter

"If it's not real-time, it's a piece of shit not a state of the art technology" - me
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Houdini Forum Index -> Technical Discussion All times are GMT - 5 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


phpBB component v1.2.4 RC3 by Adam van Dongen. Based on phpBB © 2001, 2002 phpBB Group