How to retrieve last transformation applied to custom grips?

grips

#1

Hello,

I’m using the commands EnableGetGripPointXform(bool bEnable) and GetGripPointXform(ON_Xform& xform) to record the transformation applied by Translate, Rotate and Scale.

I need this transformation to be applied to an ON_3dPointArray points, member of my CRhinoObjectGrips class, to draw a mesh in CRhinoObjectGrips::Draw() and return it in CRhinoObjectGrips::NewObject().

The problem is that it seems that the transformations are being subsequently accumulated, thus the mesh blows away after some translation/rotation.
Ideally, the transform xform should forget about past transforms and just become the new one applied between last time the mesh was drawn and the most recent one (i.e. between subsequent calls of Draw()).

In my code so far, only when I create the grips m_grips[i] I call m_grips[i].EnableGetGripPointXform(true). Then, in Draw() and NewObject() (or inside my UpdateMesh() method) I write

m_grips[i].GetGripPointXform(xform);

and, for an index k depending on i, I update my mesh points

points[k].Transform(xform);

What am I missing?

Thanks for any help,
Pablo


(Dale Fugier) #2

Then you should maintain a read-only copy of your point array. Upon a transformation, make a copy of your point array and transform it.

– Dae


#3

Hi Dale,

I’ve tried different ways of doing as you suggest but I don’t get it. To be clear about the problem, I’ve made a simple example:

SampleCustomGripsTransform.zip (12.0 MB)

In this plugin I create a horizontal line in x-y with 4 grips. When the grips are modified, the red line is drawn, and a green line shifted by one unit in y direction is drawn. I want the green line to keep a distance of 1 from the red one when all grips are moved at once. At a first time I just updated the green line by adding (0,1,0) to the grips. This works well for translations as you see:

However, when I rotate the grips it doesn’t behave as I’d like. You see in the below screenshot that every point in the green line keeps a distance of 1 in y direction, but I’d actually want it to rotate like the red one, with the same center and angle of rotation, so that the black segments joining the lines are orthogonal to both of them.

In the sample I tried to keep a copy of the offset(0,1,0) and transform it at every iteration, like this:

ON_Xform xform;
ON_3dPoint offset(0,1,0);
for ( i = 0; i < 4; i++) {
	m_Line[i] = m_Line_grips[i].GripLocation();
	m_Line_grips[i].GetGripPointXform(xform);
	offset.Transform(xform);
	m_Shifted_Line[i] = m_Line_grips[i].GripLocation() + offset;
}

But it gives weird results:

Thanks for any help!
Pablo


(Dale Fugier) #4

This isn’t going to work. You’ll want to offset the “shifted_line” perpendicular to the “line”.


#5

Hi Dale,

Yeah, I see… Though, this is only an example, no real need to keep a line parallel to the other.

The actual question is: if I transform a grip at a time, how to get that transform and apply it to another point at the same time? I followed your advice of keeping a read-only copy of the point in the attached sample, but doesn’t work.
I’m not sure what’s really happening, when using Transform(xform) on a 3d point, xform coming from the grip. What is actually this xform?

Many thanks,
Pablo