How to output a vertices structure from a custom plugin (with code)

LukeNeo's picture

Hi to all, I'm trying to extend my iniTree plugin with a custom plugin that outputs a structure with vertices position every frame, as suggested by gToledo. To try this kind of output I tried to modify my drawTest plugin so instead of render vertices it outputs vertices position.. but I cannot make it work properly. This is my approach:

  • vertices positions are stored in a float vector
float   v[VSIZE][3];
  • vertices positions are copied every frame in a NSArray (output_struct) made of NSArrays (currVertex) in this way:
   for(int x=0;x<numV;x++){
      [currVertex removeAllObjects];
      [currVertex addObject:[NSNumber numberWithFloat:v[x][0]]];
      [currVertex addObject:[NSNumber numberWithFloat:v[x][1]]];
      [currVertex addObject:[NSNumber numberWithFloat:v[x][2]]];
      [currVertex addObject:[NSNumber numberWithFloat:1.0]];
      [outputVertices addObject:currVertex];
   }
 
      //create output structure
   self.output_struct = [NSArray arrayWithArray:outputVertices];

It seems to output the same kind of result of a mesh importer (you can see it in outputs img), but for some reason my plugin output doesn't work. In the zip you can find xcode project, a composition example and a dae mesh to test it.

I think I don't build the structure in the correct way. For example, in the Apple developer guide I read that we must use NSDictionary to output a structure, but I can't use it in the correct way. Anyone knows the correct way to output a structure from a custom plugin?

PreviewAttachmentSize
outputs.jpg
outputs.jpg191.49 KB
structureTest_00.zip37.06 KB

cybero's picture
Re: How to output a vertices structure from a custom plugin ...

Your plugin is outputting the same set of positions for each and every member, thus you only get one dot rendered , regardless of how many vertices you request. So the plugin works exactly what it is actually, currently programmed to do. It is the programming side that needs a tweak. Just started looking into the underlying code.

You can see the little green dot rendered by feeding your plugin's output to a GL Point Structure patch.

Positions, getting them varied, I'd be thinking of making a patch that takes quite arbitrary structures, the usual 2D geometry, square, triangle, circle and also other structural data to output positionally renderable graphics within QC.

gtoledo3's picture
Re: How to output a vertices structure from a custom plugin ...

I haven't checked the zip, so I'm not sure... there could be a few things wrong, but I notice this:

  [outputVertices addObject:currVertex];

Maybe...

  [outputVertices addObject:currVertex++];

?

...but that doesn't make it look totally right to me still.

I'm more used to a pattern like this:

(pseudocode):

NSMutableArray *blah = [[NSMutableArray alloc] initWithCapacity:objectCount];

for(i=0;i<objectCount; i++) {

addVector(x, y, z); [blah addObject:[NSNumber numberWithInteger:index++]]; }

Then I'd alloc/init the structure, set it, and make sure to release it.

The old particle tools code has a patch called ParticleRenderToStructure, that outputs an NSMutableArray.. you can probably garner some info from that, even though it's a QCPatch, and C++. Another good example of a patch that outputs structure is the Kineme GL Grid - there's old source available for that too, and even though you're making a qcplugin, you should be able to look at another ok pattern.

What you would want to output to be "the same" as what the OpenCL kernel puts out is a GFList, but I don't think it's necessary for what you're doing, and probably more work (and undocumented)? Or, I'd at least figure out the one thing before investigating the other.

LukeNeo's picture
Re: How to output a vertices structure from a custom plugin ...

cybero wrote:
Your plugin is outputting the same set of positions for each and every member, thus you only get one dot rendered , regardless of how many vertices you request.

You're right, there was an error in the code, I fixed it (see the reply to toledo next to this reply to see how I changed the code). Thank you for the hint cybero! :)

LukeNeo's picture
Re: How to output a vertices structure from a custom plugin ...

Ok, I fixed the code and now the output structure contains N vertices with different positions. I use GL structure points to render them all. But the bad news is always performance: in a (previous post)[http://kineme.net/forum/Programming/Renderinghugeamountofverticesagain] I used vertex arrays to render huge amount of vertices (up to 1 million) with good FPS.. but now if I link this plugin with GL structure points I obtain bad performance with >200000 vertices. Instead, if I link this plugin with an image with string patch (to force the execution of the plugin), it will result in smooth FPS. This makes me think that in this new test the weak link is how I render points (maybe GL point structure is not optimized at all), not how I output the structure. Is it right (look at the img in the attachment)? Here it is how I update the structure output to obtain a readable structure from GL structure point:

- (BOOL) startExecution:(id<QCPlugInContext>)context
{
      //Init Vertices positions
   for(int x=0;x<VSIZE;x++){
      v[x][0] = [self randomBetween:-XRANGE and:XRANGE];
      v[x][1] = [self randomBetween:-YRANGE and:YRANGE];
      v[x][2] = [self randomBetween:-ZRANGE and:ZRANGE];
   }
 
   currVertex = [[NSMutableArray alloc] init];
   outputVertices = [[NSMutableArray alloc] init];
 
   return YES;
}
 
- (BOOL) execute:(id<QCPlugInContext>)context atTime:(NSTimeInterval)time withArguments:(NSDictionary*)arguments
{
      //How many vertices does our output structure contain? 
   numV = self.input_numVertices;
   if(numV > VSIZE) numV = VSIZE;
   [outputVertices removeAllObjects];
   for(int x=0;x<numV;x++){
      [currVertex removeAllObjects];
      [currVertex addObject:[NSNumber numberWithFloat:v[x][0]]];
      [currVertex addObject:[NSNumber numberWithFloat:v[x][1]]];
      [currVertex addObject:[NSNumber numberWithFloat:v[x][2]]];
      [currVertex addObject:[NSNumber numberWithFloat:1.0]];
      [outputVertices addObject:[NSArray arrayWithArray:currVertex]];
   }
 
      //create output structure
   self.output_struct = [NSArray arrayWithArray:outputVertices];
 
   return YES;
}
 
- (void) stopExecution:(id<QCPlugInContext>)context
{
   [currVertex removeAllObjects];
   [outputVertices removeAllObjects];
   [currVertex release];
   [outputVertices release];
}

I updated the code and the composition to test it (see the attachment). So.. do you think that the structure is well build up and the performance problem is in the way I render the structure of points?

I downloaded ParticleRenderToStructure source code, thank you for the hint. I can see that it use GFList. Maybe I'll try to use this kind of output.

PreviewAttachmentSize
performances.png
performances.png136.35 KB
structureTest_01.zip50.19 KB

dust's picture
Re: How to output a vertices structure from a custom plugin ...

i would try and do something like this.

   for(int x=0;x<numV;x++)
   {
      [outputVertices addObject:
      [NSArray arrayWithObjects:
      [NSNumber numberWithFloat:v[x][0]],
      [NSNumber numberWithFloat:v[x][1]],
      [NSNumber numberWithFloat:v[x][2]],
      [NSNumber numberWithFloat:1.0],nil];
 
   }
 
   self.output_struct = outputVertices;

there isn't really a need to create the current vertex array. also try using mesh creator points. they may be a bit faster...

LukeNeo's picture
Re: How to output a vertices structure from a custom plugin ...

dust wrote:
i would try and do something like this. there isn't really a need to create the current vertex array. also try using mesh creator points. they may be a bit faster...

Thank you for the hint dust. I used this approach in iniTreeStructure, and it seems to work well!