I have been told to repost this thread with changes for the current _DG set of interfaces. Unfortunately, I could not find the original question. It should be useful anyway
This post is preliminary. I need to check the code below. It is correct up to the opposite. If it is urgent and something does not work, try swapping ToGlobal/ToLocal. I always mix this up.
Rob,
I see. Looks like you need a way to combine many transformations into one and apply it to an object.
In DGK the most generic transformation is a frame, represented in code by IFrame_DG: Given a frame F point with global coordinates (x,y,z) is transformed into point which has same local (x,y,z) coordinates relative to F. So that global coordinates of the transformed point are obtained by F.ToGlobal(x,y,z). More precisely by IFrame3.ToGlobal()
Note: Historically IFrame* contained 4 interfaces. In v6 they have been merged into a single IFrame_DG, which is the most convenient one
Creating basic transforms
To obtain transformation of a translation by (vx,vy,vz) you do:
Code: Select all
iFrame.Reset();
iFrame.Translate(vx,vy,vz);
Code: Select all
iFrame.Reset();
iFrame.Rotate(angle, xAxis, yAxis, zAxis, vxDirAxis, vyDirAxis, vzDirAxis);
Multiplication of transforms
Returning to your very appropriate suggestion, when you have a sequence of transformations F0,...,F7, instead of applying them one by one you can calculate their product F = F7*F6*...*F1*F0 instead and apply it once
To multiply two frames: F = F1*F0 you need to:
Use IFrame_DG of each frame, like F0, F1
Execute F0.ToGlobal(F1); after which F1 becomes the product of the two.
To make it cleaner, or if you want to keep F0 unchanged, create a new F:
Code: Select all
IObjectGenerator_DG iGener = m_iModel.As<IObjectGenerator_DG>();
IFrame_DG F = iGener.Create<IFrame_DG>();
F.Copy(F1);
F0.ToGlobal(F);
Applying transforms to objects
There are two significantly different ways of applying transforms to entities:
a) Moving the object as whole without geometry change
b) Transforming internal surface of the object
Moving the object as whole
This is the preferred way of moving objects around when the surface does not need to be modified in any way, only position and orientation has to be adjusted. This method is very fast and does not depend on geometry size as only the local frame is modified.
To do this type of transformation, execute:
Code: Select all
IFrame_DG fr = iEntity.GetLocation();
F.ToGlobal(fr);
IGeometricObject_DG is designed exactly for that. Use:
Code: Select all
IFrame_DG F = iEntity.GetLocation();
IGeometricObject_DG iTransf = iEntity.As<IGeometricObject_DG>();
iTransf.Transform(F);
Transforming surface involves modifications of all elements of the geometry.
Internal transformation is not always possible for some types of geometries. Like rotation of a surface of revolution is OK only around its axis. It always works for Mesh geometries.
If you need something like aligning objects by moving them around the first method is fast and I do not believe multiplying transforms will make any difference. The second method is another matter. You can accelerate the operation 8 times in your case by preparing the cumulative transform.
Transforming surface is inevitable when you need to modify location of the local frame relative to the surface for more convenient rotations etc. For example translating local frame by a vector v means translating the whole object by v and translating the surface by -v (opposite direction).
If you need something like aligning objects by moving them around moving as a whole (see the topic) method is fast and I do not believe multiplying transforms will make any difference. The surface modification method is another matter. You can accelerate the operation in your case by preparing the cumulative transform first.
Regards