Getting back to original object

On 30/11/2016 at 02:44, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R14 
Platform:   Windows  ;   
Language(s) :     C++  ;

Hi folks,

two questions!

First, I have a tool that tests object and polygon hits in the viewport. The objects drawn could be in any hierarchy arrangement (under nulls, hypernurbs, generators etc) and include caches. How do I get from the viewport drawn object hit back to the original object? There's no "get original object" function anywhere (that I know of).

Second, following the above, polygon hits seem to return objects not drawn in the viewport, for example, a cube under a hypernurbs. I can hit the cube, despite also getting a hit on the subdivided draw (via the cache) and the hypernurbs. ViewportSelect::Init()'s "visible only" flag doesn't work as I expect. Is there a native way to ignore objects not actually drawn in the viewport?


On 01/12/2016 at 08:39, xxxxxxxx wrote:


What do you mean by "original object"?

ViewportSelect::PickObject()/GetPixelInfoPolygon() return the real objects, not their cache.
ViewportSelect::Init(..., BaseObject *op, ...) returns false  for objects that aren't polygons so this discards hypernurbs for instance.

On 05/12/2016 at 02:41, xxxxxxxx wrote:

Hi Yannick,

I'm still trying to think my way through this, but just for response's sake, here's my current state of thought. I'll deal with just the poly hits first, we'll come back to the non-drawn objects later.

By "original object", I mean the original object sitting in the AM. Here's an example screen cap of my AM setup:

My object plugin (third down) takes the child object (fourth down) and puts it under a hypernurbs, and returns the HN in GVO. When I test the hits in the viewport, I get this:

The yellow triangle and the yellow dot are where the hits occurred. The GePrints show there are three hits, one hit on polygon 19 of the polygon mesh in the viewport (yellow text "CORRECT"), and two hits on identical looking objects on polygon 4 (yellow text "HIT - NOT DRAWN") neither of which are drawn in the viewport. Technically, the index for all hits is correct.

So my first query, how do I get from the "correct" hit on poly 19, back to the original object source (which is a cube with 6 polygons)? I ask this because my hierarchy recursive function tests for caches, eg:

// psuedo code
BaseObject* MyObject::Find_Match(...)
		ViewportSelect *v = ViewportSelect::Alloc();
			int Hit = Test_Polygon(obj,ix,iy,v);  // function to test polygon hit, returns index or -1
			if(Hit >= 0)
				GePrint("HIT found on obj " + obj->GetName() + ", poly " + LongToString(Hit));
		if(obj->GetCache() != nullptr)  // **THE "CORRECT" HIT COMES FROM THIS**
		if(obj->GetDeformCache() != nullptr)
	return obj;

The correct hit comes from part of the recursive function when the getcache() statement is met. So how do I know if/when an object has been used in another generator etc and there could be caches all over the place etc that need to be taken into account? How do I get back to the original source?

Hope that explains it somewhat. Let me know if you need any more info/code/something else!


On 05/12/2016 at 10:41, xxxxxxxx wrote:


Thanks for the detailed explanation, screenshots and the code snippet. This helped me to reproduce the behavior you described.

I've investigated your issue but I need more time and feedback from the development team.

I'll get back to you on Wednesday.

On 07/12/2016 at 03:49, xxxxxxxx wrote:


Originally posted by xxxxxxxx

So my first query, how do I get from the "correct" hit on poly 19, back to the original object source (which is a cube with 6 polygons)?

This question isn't directly related to ViewportSelect but to generators and input objects.
Retrieving the original object for a generator can be tricky and also makes no sense in several situations. For instance, how would you handle generators with a variable number of input objects?

So how do I know if/when an object has been used in another generator etc and there could be caches all over the place etc that need to be taken into account? How do I get back to the original source?

To filter generators, check objects for OBJECT_GENERATOR and OBJECT_INPUT. To filter both generators and input objects check for BIT_CONTROLOBJECT BaseList2D bit. For more information on generators dependencies and BIT_CONTROLOBJECT see this post.

I'm still confused by your questions in this topic:
Are you interested in only the drawn object (generator's cache) or the source/input object hit test? Or both objects?

On 10/12/2016 at 03:24, xxxxxxxx wrote:

Thanks for taking the time Yannick.

I have a reference to the original polygon object. If the original object isn't a polygon object, it won't count. So multi-input objects and multi-viewport hits won't matter, so long as I can trace all the viewport hits back to their original polygon source(s). That way I can test the original source(s) against the stored reference, and if there's a true test, then other processes will follow. But these further processes also rely on the original object data (to do with original poly counts and other tags etc).

With regards to your second question - I'm interested in both. I can get the first one (the initial viewport and poly index hits), but can't do the object trace back. The filtering of the objects in a sense probably doesn't matter, so long as I can get back to the original object.


On 13/12/2016 at 03:24, xxxxxxxx wrote:


It shouldn't be too hard to get back to the original object(s) using the hierarchy and cache functions.

Your hierarchy recursive function should check the child objects of generators (GetDown()).
This way you could associate the source(s) (GetDown()) and cache of generators (GetCache()).
The children objects would be hit tested twice but you can discard them using an AtomArray for instance.

On 19/12/2016 at 02:32, xxxxxxxx wrote:

I'm playing around with an alternative solution to this one. It's using a tag and storing a pointer to the original there. I've tried with a standard BaseObject pointer and a BaseLink reference at the tag's class level but both seem to crash Cinema.

// psuedo code
class MyTag : public TagData
	BaseObject* obj_ref;  // also tried BaseLink*
	Bool CopyTo(NodeData* dest,GeListNode* snode,GeListNode* dnode,COPYFLAGS flags, AliasTrans* trn)
		MyTag *my_dest = (MyTag* )dest;
		my_dest->obj_ref = obj_ref;
	void SetReference(BaseObject* obj)
		BaseTag *tag = (BaseTag* )(this);
		obj_ref = tag->GetObject();  // can only set this once

Should something like this work?


On 20/12/2016 at 09:24, xxxxxxxx wrote:

The cast from TagData* to BaseTag* in SetReference() is not safe. Why don't you just assign the passed BaseObject* obj to obj_ref?

Note using a BaseLink* is recommended and safer.