List ptsA = null;
Point3f[] points = new Point3f[2];
Vector3f rotAxis = new Vector3f(0, 1, 0);
Vector3f translation = null;
Matrix4f m4 = null;
Matrix3f m3 = null;
int direction = 1;
int tok;
Quaternion q = null;
boolean helicalPath = false;
List ptsB = null;
BitSet bsCompare = null;
Point3f invPoint = null;
Point4f invPlane = null;
boolean axesOrientationRasmol = viewer.getAxesOrientationRasmol();
for (int i = 1; i < statementLength; ++i) {
switch (tok = getToken(i).tok) {
case Token.bitset:
case Token.expressionBegin:
case Token.leftbrace:
case Token.point3f:
case Token.dollarsign:
if (tok == Token.bitset || tok == Token.expressionBegin) {
if (translation != null || q != null || nPoints == 2) {
bsAtoms = atomExpression(i);
ptsB = null;
isSelected = true;
break;
}
}
haveRotation = true;
if (nPoints == 2)
nPoints = 0;
// {X, Y, Z}
// $drawObject[n]
Point3f pt1 = centerParameter(i, viewer.getCurrentModelIndex());
if (!isSyntaxCheck && tok == Token.dollarsign
&& tokAt(i + 2) != Token.leftsquare) {
// rotation about an axis such as $line1
isMolecular = true;
rotAxis = getDrawObjectAxis(objectNameParameter(++i), viewer
.getCurrentModelIndex());
}
points[nPoints++] = pt1;
break;
case Token.spin:
isSpin = true;
continue;
case Token.internal:
case Token.molecular:
isMolecular = true;
continue;
case Token.selected:
isSelected = true;
break;
case Token.comma:
continue;
case Token.integer:
case Token.decimal:
if (endDegrees == Float.MAX_VALUE) {
endDegrees = floatParameter(i);
} else {
degreesPerSecond = floatParameter(i);
isSpin = (degreesPerSecond != 0);
}
continue;
case Token.minus:
direction = -1;
continue;
case Token.x:
haveRotation = true;
rotAxis.set(direction, 0, 0);
continue;
case Token.y:
haveRotation = true;
rotAxis.set(0, (axesOrientationRasmol && !isMolecular ? -direction
: direction), 0);
continue;
case Token.z:
haveRotation = true;
rotAxis.set(0, 0, direction);
continue;
// 11.6 options
case Token.point4f:
case Token.quaternion:
if (tok == Token.quaternion)
i++;
haveRotation = true;
q = getQuaternionParameter(i);
rotAxis.set(q.getNormal());
endDegrees = q.getTheta();
break;
case Token.axisangle:
haveRotation = true;
if (isPoint3f(++i)) {
rotAxis.set(centerParameter(i));
break;
}
Point4f p4 = getPoint4f(i);
rotAxis.set(p4.x, p4.y, p4.z);
endDegrees = p4.w;
q = new Quaternion(rotAxis, endDegrees);
break;
case Token.branch:
haveRotation = true;
int iAtom1 = atomExpression(++i).nextSetBit(0);
int iAtom2 = atomExpression(++iToken).nextSetBit(0);
if (iAtom1 < 0 || iAtom2 < 0)
return;
bsAtoms = viewer.getBranchBitSet(iAtom2, iAtom1);
isSelected = true;
isMolecular = true;
points[0] = viewer.getAtomPoint3f(iAtom1);
points[1] = viewer.getAtomPoint3f(iAtom2);
nPoints = 2;
break;
// 12.0 options
case Token.translate:
translation = new Vector3f(centerParameter(++i));
isMolecular = isSelected = true;
break;
case Token.helix:
// screw motion, for quaternion-based operations
helicalPath = true;
continue;
case Token.symop:
int symop = intParameter(++i);
if (isSyntaxCheck)
continue;
Hashtable info = viewer.getSpaceGroupInfo(null);
Object[] op = (info == null ? null : (Object[]) info.get("operations"));
if (symop == 0 || op == null || op.length < Math.abs(symop))
error(ERROR_invalidArgument);
op = (Object[]) op[Math.abs(symop) - 1];
translation = (Vector3f) op[5];
invPoint = (Point3f) op[6];
points[0] = (Point3f) op[7];
if (op[8] != null)
rotAxis = (Vector3f) op[8];
endDegrees = ((Integer) op[9]).intValue();
if (symop < 0) {
endDegrees = -endDegrees;
if (translation != null)
translation.scale(-1);
}
if (endDegrees == 0 && points[0] != null) {
// glide plane
invPlane = Measure.getPlaneThroughPoint(points[0], rotAxis);
}
q = new Quaternion(rotAxis, endDegrees);
nPoints = (points[0] == null ? 0 : 1);
isMolecular = true;
haveRotation = true;
isSelected = true;
continue;
case Token.compare:
case Token.matrix4f:
case Token.matrix3f:
haveRotation = true;
if (tok == Token.compare) {
bsCompare = atomExpression(++i);
ptsA = viewer.getAtomPointVector(bsCompare);
if (ptsA == null)
error(ERROR_invalidArgument, i);
i = iToken;
ptsB = getPointVector(getToken(++i), i);
if (ptsB == null || ptsA.size() != ptsB.size())
error(ERROR_invalidArgument, i);
m4 = new Matrix4f();
points[0] = new Point3f();
nPoints = 1;
float stddev = (isSyntaxCheck ? 0 : Measure.getTransformMatrix4(ptsA,
ptsB, m4, points[0]));
// if the standard deviation is very small, we leave ptsB
// because it will be used to set the absolute final positions
if (stddev > 0.001)
ptsB = null;
} else if (tok == Token.matrix4f) {
m4 = (Matrix4f) theToken.value;
}
m3 = new Matrix3f();
if (m4 != null) {
translation = new Vector3f();
m4.get(translation);
m4.get(m3);
} else {