How-To: Build a KeyPath

KeyPaths are explained in our documentation. When correctly formed, a key path unambiguously describes the location of a leaf segment in the scene graph hierarchy. A key to the leaf node itself is insufficient because it could theoretically be included in multiple locations in the scene graph.

A key path is needed to correctly take into account cameras and matrix transforms when converting coordinates between systems. The key path is a collection of keys, going from the leaf to the root of the scene graph. The key path can omit some of the keys between the leaf and the root, but MUST contain all the include link between leaf and root.

If you are using Sprockets, consider using a function called GetKeyPath().

Basic Example

Consider the following segment hierarchy;

d3f7da0e-50f2-41e4-8599-e09debaf219f

The model segment contains two child segments β€œa” and β€œb”. Segment β€œb” includes segment β€œc” which exists under segment β€œa”. Segment β€œc” contains a sphere.

Here’s the sample code (from our HPS mfc_sandbox):


1 void generateKeyPath(SegmentKey& key, KeyPath& kp)
2 {
3	kp += key;
4	while (key.Type() == Type::SegmentKey && key.HasOwner())
5	{
6		SegmentKey segKey = key.Owner();
7		kp += segKey;
8		key = key.Up();
9	}
10 }
11
12void CHPSView::OnUserCode2()
13 {
14	SegmentKey modelSeg = GetCanvas().GetAttachedLayout().GetAttachedView().GetAttachedModel().GetSegmentKey();
15
16	SegmentKey aSeg = modelSeg.Subsegment("a");
17	aSeg.GetMaterialMappingControl().SetFaceColor(HPS::RGBAColor(1, 0, 0));
18	aSeg.GetConditionControl().SetCondition("seg a");
19
20	SegmentKey cSeg = aSeg.Subsegment("c");
21	SphereKit sphereKit;
22	sphereKit.SetCenter(Point(0, 0, 0)).SetRadius(0.5f).SetBasis(Vector(1, 1, 0), Vector(1, 0, 0));
23	SphereKey sphereKey = cSeg.InsertSphere(sphereKit);
24
25	SegmentKey bSeg = modelSeg.Subsegment("b");
26	bSeg.IncludeSegment(cSeg);
27	bSeg.GetModellingMatrixControl().Translate(1.125, 0, 0);
28	bSeg.GetConditionControl().SetCondition("seg b");
29
30	KeyPath keyPath;
31	SegmentKey myKey;
32	SearchResults searchResults;
33	SearchOptionsKit sok;
34	sok.SetSearchSpace(Search::Space::SubsegmentsAndIncludes)
35		.SetCriteria(Search::Type::Sphere)
36		.SetBehavior(HPS::Search::Behavior::Exhaustive);
37	size_t numResults = modelSeg.Find(sok, searchResults);
38	SearchResultsIterator it = searchResults.GetIterator();
39	while (it.IsValid())
40	{
41		Key key = it.GetItem();
42		if (key.Type() == Type::SphereKey && key == sphereKey)
43		{
44			SegmentKey segKey = key.Owner();
45			if (segKey.Name() == "c")
46				generateKeyPath(segKey, keyPath);
47		}
48		it.Next();
49	}
50	// Use the generated KeyPath
51	HPS::UTF8Array conditions;
52	keyPath.ShowNetConditions(conditions);
53	assert(strcmp("seg a", conditions[0].GetBytes()) == 0);
54
55	// Manually define a keypath for the second included instance
56	KeyPath keyPathManual;
57	keyPathManual.PushBack(cSeg);
58	keyPathManual.PushBack(bSeg);
59	keyPathManual.PushBack(modelSeg);
60
61	HPS::UTF8Array conditionsManual;
62	keyPathManual.ShowNetConditions(conditionsManual);
63	assert(strcmp("seg b", conditionsManual[0].GetBytes()) == 0);
64
65	GetCanvas().UpdateWithNotifier().Wait();
66}

The beginning of OnUserCode2() creates the diagrammed scene including a couple conditions used to illustrate different results based on two KeyPaths.

A condition called β€œseg a” is defined in segment β€œa”.

Similarly, a condition called β€œseg b” is defined in segment β€œb”.

The application creates the following simple rendering;

A basic search (modelSeg.Find()) looks for all spheres under the model in child and include segments. You will notice that numResults returns 1. There are two instances of the sphere in the scene but they have the same key.

The function generateKeyPath() walks up the hierarchy building a KeyPath using key.Owner(). The resulting KeyPath includes segment β€œc”, segment β€œa” and the model segment. Calling ShowNetConditions() with this key path returns β€œseg a”.

Finally, another KeyPath is built manually with the knowledge that segment β€œb” includes segment β€œc”. Calling ShowNetConditions() with this key path (i.e. segment β€œc”, segment β€œb” and the model segment) returns β€œseg b”. This type of knowledge about the scene graph is often required to build the appropriate KeyPath for a particular application.

This example illustrates different results depending on the KeyPath.

1 Like