Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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

Basic Example

Consider the following segment hierarchy;

...

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):

Code Block
languagecpp
void generateKeyPath(SegmentKey& key, KeyPath& kp)
{
	kp += key;
	while (key.Type() == Type::SegmentKey && key.HasOwner())
	{
		SegmentKey segKey = key.Owner();
		kp += segKey;
		key = key.Up();
	}
}

void CHPSView::OnUserCode2()
{
	SegmentKey modelSeg = GetCanvas().GetAttachedLayout().GetAttachedView().GetAttachedModel().GetSegmentKey();

	SegmentKey aSeg = modelSeg.Subsegment("a");
	aSeg.GetMaterialMappingControl().SetFaceColor(HPS::RGBAColor(1, 0, 0));
	aSeg.GetConditionControl().SetCondition("seg a");

	SegmentKey cSeg = aSeg.Subsegment("c");
	SphereKit sphereKit;
	sphereKit.SetCenter(Point(0, 0, 0)).SetRadius(0.5f).SetBasis(Vector(1, 1, 0), Vector(1, 0, 0));
	SphereKey sphereKey = cSeg.InsertSphere(sphereKit);

	SegmentKey bSeg = modelSeg.Subsegment("b");
	bSeg.IncludeSegment(cSeg);
	bSeg.GetModellingMatrixControl().Translate(1.125, 0, 0);
	bSeg.GetConditionControl().SetCondition("seg b");

	KeyPath keyPath;
	SegmentKey myKey;
	SearchResults searchResults;
	SearchOptionsKit sok;
	sok.SetSearchSpace(Search::Space::SubsegmentsAndIncludes)
		.SetCriteria(Search::Type::Sphere)
		.SetBehavior(HPS::Search::Behavior::Exhaustive);
	size_t numResults = modelSeg.Find(sok, searchResults);
	SearchResultsIterator it = searchResults.GetIterator();
	while (it.IsValid())
	{
		Key key = it.GetItem();
		if (key.Type() == Type::SphereKey && key == sphereKey)
		{
			SegmentKey segKey = key.Owner();
			if (segKey.Name() == "c")
				generateKeyPath(segKey, keyPath);
		}
		it.Next();
	}
	// Use the generated KeyPath
	HPS::UTF8Array conditions;
	keyPath.ShowNetConditions(conditions);
	assert(strcmp("seg a", conditions[0].GetBytes()) == 0);

	// Manually define a keypath for the second included instance
	KeyPath keyPathManual;
	keyPathManual.PushBack(cSeg);
	keyPathManual.PushBack(bSeg);
	keyPathManual.PushBack(modelSeg);

	HPS::UTF8Array conditionsManual;
	keyPathManual.ShowNetConditions(conditionsManual);
	assert(strcmp("seg b", conditionsManual[0].GetBytes()) == 0);

	GetCanvas().UpdateWithNotifier().Wait();
}

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

Info

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 KeyPathCheck out an example with sample code in our forum post.