Steven, You are passing siPolygonFilter to the pickbuffer so you can call GetComponentIndexAtPosition on the pick buffer to get the polygon under the cursor directly so you don't need to call Snap.
In other words the pickbuffer has both object *and* polygon information for
each pixel.
m_pBuffer = in_ctxt.GetPickBuffer(x, y, 1, 1, siPolygonFilter, m_targets,
siShaded);
CRef l_obj = m_pBuffer.GetObjectAtPosition(x, y);
m_hit = l_obj.IsValid();
if (m_hit)
{
LONG polyIndex = m_pBuffer.GetComponentIndexAtPosition(x, y);
if (polyIndex >= 0)
{
// Get normal for polygon etc....
Snap is good enough for many tools but it searches through all the
objects/components so you lose the constant time performance of the pickbuffer.
For things like painting where you might be generating a lot of brush stamps it
can make a big difference.
In your code below the overhead of calling Snap completely eliminates any
benefit gained from the pickbuffer. In fact, you would get the same performance
if you removed the PickBuffer calls and just called Snap.
--
Brent
From: [email protected]
[mailto:[email protected]] On Behalf Of Steven Caron
Sent: 30 July 2012 18:45
To: [email protected]
Subject: Re: SDK : caching the tool context pick buffer
aah... too bad it was never exposed to the SDK so it could earn its name ;)
while i have you, how is the GAP/XSI Brush Tool querying normals for brush
orientation? i am doing something like this, excuse the assumption about
getting a single node normal...
m_pBuffer = in_ctxt.GetPickBuffer(x, y, 1, 1, siPolygonFilter, m_targets,
siShaded);
CRef l_obj = m_pBuffer.GetObjectAtPosition(x, y);
m_hit = l_obj.IsValid();
if (m_hit)
{
CStringArray families;
families.Add(siMeshFamily);
in_ctxt.Snap(x, y, 1, siSnapFace, families, m_targets, m_pos);
LONG l_compIdx = m_pBuffer.GetComponentIndexAtPosition(x, y);
X3DObject l_xObj(l_obj);
PolygonMesh l_polymesh = l_xObj.GetActivePrimitive().GetGeometry();
PolygonFace face = l_polymesh.GetPolygons().GetItem(l_compIdx);
PolygonNode node(face.GetNodes().GetItem(0));
bool validN;
m_normal = node.GetNormal(validN);
m_normal *=
l_xObj.GetKinematics().GetGlobal().GetTransform().GetRotationMatrix3();
m_normal.NormalizeInPlace();
}
and also in the above code is Snap() fast enough to use for my collision test
to place my brush position on?
steven
On Mon, Jul 30, 2012 at 10:15 AM, Brent McPherson
<[email protected]<mailto:[email protected]>> wrote:
I though you guys knew all our code names. ;-)
GAP (Generic Attribute Painter) is what we call the XSI Brush tool. It uses the
pickbuffer to lookup surface info for objects.
--
Brent
From:
[email protected]<mailto:[email protected]>
[mailto:[email protected]<mailto:[email protected]>]
On Behalf Of Steven Caron
Sent: 30 July 2012 17:54
To: [email protected]<mailto:[email protected]>
Subject: Re: SDK : caching the tool context pick buffer
thanks for the reply Brent!
using a dirty flag is totally fine, i think it was just late and i couldn't
think of such a obvious answer. i dont think an IsValid method is needed for
the PickBuffer, i can use IsNavigating() or use the activate callback to set
the flag.
i am not at the point where i am thinking about caching multiple views but
thanks for the reminder :)
i am not familiar with the term 'GAP-like', care to elaborate?
steven
On Mon, Jul 30, 2012 at 5:13 AM, Brent McPherson
<[email protected]<mailto:[email protected]><mailto:[email protected]<mailto:[email protected]>>>
wrote:
Hi Steven,
Why don't you keep a dirty flag for the pickbuffer and simply set that in
Activate and then the next time you ask for the pickbuffer (in mouse move or
mouse down) recompute it if it is dirty.
The pickbuffer is specific to a particular view so you can't generate it is a
callback like Activate which is not tied to any particular view. The same holds
for methods like GetMousePosition. It will return CStatus::Fail when called
from Activate. I guess we should have added an IsValid method to the pickbuffer
but as a workaround you can assume that if GetViewIndex returns a value greater
or equal to zero then it is safe to call GetPickBuffer. You will also need to
decide if you are going to cache a pickbuffer for each view or just keep one
for the last view etc...
The pickbuffer stuff was designed with this purpose in mind and one of our
consulting devs used it to do a real-time (GAP-like) sculpting tool for a
client.
--
Brent
From:
[email protected]<mailto:[email protected]><mailto:[email protected]<mailto:[email protected]>>
[mailto:[email protected]<mailto:[email protected]><mailto:[email protected]<mailto:[email protected]>>]
On Behalf Of Steven Caron
Sent: 30 July 2012 04:43
To:
[email protected]<mailto:[email protected]><mailto:[email protected]<mailto:[email protected]>>
Subject: SDK : caching the tool context pick buffer
hey guys... (read brent)
i am trying to cache the PickBuffer each time the user activates this custom
tool (this happens on camera navigation, which is my primary concern) but not
having much luck. the doc suggests if i pass an empty region i will get the
whole view but any subsequent calls i am making to
PickBuffer.GetObjectAtPosition() has returned an invalid reference. is this
doable in the Activate calback? the docs say..."if unavailable in the current
callback or any arguments are invalid then the resulting PickBuffer will be
invalid."
so, are my arguments incorrect or is this not valid in the this callback?
// activate callback, called each time the tool comes active again
CStatus Activate(ToolContext& in_ctxt)
{
// get a list of selected meshes
const CString empty;
CStringArray families;
families.Add(siMeshFamily);
Application().GetSelection().GetArray().Filter(empty, families, empty,
m_targets);
// cache a pick buffer, m_pBuffer is a class member variable where i am
caching it
m_pBuffer = in_ctxt.GetPickBuffer(x, y, width, height, siPolygonFilter,
m_targets, siShaded);
LONG x,y;
in_ctxt.GetMousePosition(x, y);
CRef l_obj = m_pBuffer.GetObjectAtPosition(x, y);
Application().LogMessage(L"Activate : " + l_obj.GetAsText());
return CStatus::OK;
};
any other tips on caching the PickBuffer each time the camera changes?
steven
<<attachment: winmail.dat>>

