Search in sources :

Example 1 with Frame

use of au.gov.asd.tac.constellation.utilities.graphics.Frame in project constellation by constellation-app.

the class GatherNodesInGraphPlugin method edit.

@Override
public void edit(final GraphWriteMethods wg, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException {
    final Vector3f xyzp = (Vector3f) parameters.getParameters().get(XYZ_PARAMETER_ID).getObjectValue();
    final BitSet gathers = (BitSet) parameters.getParameters().get(GATHERS_PARAMETER_ID).getObjectValue();
    final int xId = wg.getAttribute(GraphElementType.VERTEX, VisualConcept.VertexAttribute.X.getName());
    final int yId = wg.getAttribute(GraphElementType.VERTEX, VisualConcept.VertexAttribute.Y.getName());
    final int zId = wg.getAttribute(GraphElementType.VERTEX, VisualConcept.VertexAttribute.Z.getName());
    final int cameraAttribute = VisualConcept.GraphAttribute.CAMERA.get(wg);
    final int selectedVertexCount = gathers.cardinality();
    if (selectedVertexCount >= 1) {
        // This is where we want to rotate to: relative to the eye->centre direction.
        final Camera visualState = wg.getObjectValue(cameraAttribute, 0);
        final Vector3f xyz = Vector3f.subtract(visualState.lookAtCentre, visualState.lookAtEye);
        // Create a rotation matrix that will rotate the positions we're about to create.
        final Frame frame = new Frame(xyz, new Vector3f(0, 0, 0), visualState.lookAtUp);
        final Matrix44f rm = new Matrix44f();
        frame.getMatrix(rm, true);
        final Matrix33f rotationMatrix = new Matrix33f();
        rm.getRotationMatrix(rotationMatrix);
        // We want the grid to start at the top left and grow down and right.
        // Choose our up and left vectors accordingly.
        final Vector3f up = new Vector3f();
        up.rotate(new Vector3f(0, -1, 0), rotationMatrix);
        final Vector3f left = new Vector3f();
        left.rotate(new Vector3f(-1, 0, 0), rotationMatrix);
        // If we wanted to be consistent, we'd call the arrange by grid plugin on the selected vertices
        // and rotate the result...
        final int rowLength = (int) Math.ceil(Math.sqrt(selectedVertexCount));
        float x = xyzp.getX();
        float y = xyzp.getY();
        float z = xyzp.getZ();
        int h = 0;
        int v = 0;
        float scalingFactor = 4;
        for (int vxId = gathers.nextSetBit(0); vxId >= 0; vxId = gathers.nextSetBit(vxId + 1)) {
            if (h == 0 && v == 0) {
                // This gathers the selected nodes at the distance the first selected node as measured away from the camera/eye.
                // It does this by using a right hand triangle (hypotenuse = ray to click, adjacent = view from eye to centre,
                // opposite = pane perpendicular to eye) and the approriate triangle properties
                // 
                // Unit vector from eye to click point
                final Vector3f ray = Vector3f.subtract(xyzp, visualState.lookAtEye);
                ray.normalize();
                // Unit vector from eye to centre
                final Vector3f adjacentUnit = Vector3f.subtract(visualState.lookAtCentre, visualState.lookAtEye);
                adjacentUnit.normalize();
                // Vector from eye to node already on graph
                final Vector3f point = new Vector3f(wg.getFloatValue(xId, vxId), wg.getFloatValue(yId, vxId), wg.getFloatValue(zId, vxId));
                point.subtract(visualState.lookAtEye);
                // Determining the distance along the unit vector to the centre that the node will be
                final float adjacentLen = Vector3f.dotProduct(adjacentUnit, point);
                // Determining the length of the hypotenuse of the right hand triangle
                final float cosAngleBetweenVectors = (float) Math.cos(Vector3f.angleBetweenVectors(ray, adjacentUnit));
                // If it does equal 0 we will skip this section and have x,y,z equal the "click point" which was assigned when they were defined
                if (cosAngleBetweenVectors != 0.0) {
                    final float rayScalar = adjacentLen / cosAngleBetweenVectors;
                    ray.scale(rayScalar);
                    final Vector3f destination = Vector3f.add(visualState.lookAtEye, ray);
                    x = destination.getX();
                    y = destination.getY();
                    z = destination.getZ();
                }
            }
            wg.setFloatValue(xId, vxId, x + scalingFactor * (h * left.getX() + v * up.getX()));
            wg.setFloatValue(yId, vxId, y + scalingFactor * (h * left.getY() + v * up.getY()));
            wg.setFloatValue(zId, vxId, z + scalingFactor * (h * left.getZ() + v * up.getZ()));
            if (++h == rowLength) {
                h = 0;
                v++;
            }
        }
    }
}
Also used : Frame(au.gov.asd.tac.constellation.utilities.graphics.Frame) Matrix44f(au.gov.asd.tac.constellation.utilities.graphics.Matrix44f) Matrix33f(au.gov.asd.tac.constellation.utilities.graphics.Matrix33f) Vector3f(au.gov.asd.tac.constellation.utilities.graphics.Vector3f) BitSet(java.util.BitSet) Camera(au.gov.asd.tac.constellation.utilities.camera.Camera)

Example 2 with Frame

use of au.gov.asd.tac.constellation.utilities.graphics.Frame in project constellation by constellation-app.

the class GatherNodesPlugin method edit.

@Override
public void edit(final GraphWriteMethods wg, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException {
    final int vxId = parameters.getParameters().get(VXID_PARAMETER_ID).getIntegerValue();
    final BitSet gathers = (BitSet) parameters.getParameters().get(GATHERS_PARAMETER_ID).getObjectValue();
    gathers.set(vxId);
    final int xId = wg.getAttribute(GraphElementType.VERTEX, VisualConcept.VertexAttribute.X.getName());
    final int yId = wg.getAttribute(GraphElementType.VERTEX, VisualConcept.VertexAttribute.Y.getName());
    final int zId = wg.getAttribute(GraphElementType.VERTEX, VisualConcept.VertexAttribute.Z.getName());
    final int cameraAttribute = VisualConcept.GraphAttribute.CAMERA.get(wg);
    final int selectedVertexCount = gathers.cardinality();
    if (selectedVertexCount > 1) {
        // This is where we want to rotate to: relative to the eye->centre direction.
        final Camera visualState = wg.getObjectValue(cameraAttribute, 0);
        final Vector3f xyz = Vector3f.subtract(visualState.lookAtCentre, visualState.lookAtEye);
        // Create a rotation matrix that will rotate the positions we're about to create.
        final Frame frame = new Frame(xyz, new Vector3f(0, 0, 0), visualState.lookAtUp);
        final Matrix44f rm = new Matrix44f();
        frame.getMatrix(rm, true);
        final Matrix33f rotationMatrix = new Matrix33f();
        rm.getRotationMatrix(rotationMatrix);
        // We want the grid to start at the top left and grow down and right.
        // Choose our up and left vectors accordingly.
        final Vector3f up = new Vector3f();
        up.rotate(new Vector3f(0, -1, 0), rotationMatrix);
        final Vector3f left = new Vector3f();
        left.rotate(new Vector3f(-1, 0, 0), rotationMatrix);
        final float x = wg.getFloatValue(xId, vxId);
        final float y = wg.getFloatValue(yId, vxId);
        final float z = wg.getFloatValue(zId, vxId);
        // If we wanted to be consistent, we'd call the arrange by grid plugin on the selected vertices
        // and rotate the result...
        final int rowLength = (int) Math.ceil(Math.sqrt(selectedVertexCount));
        // Skip the first position: when we get to vxId, we don't change it's position.
        int h = 1;
        int v = 0;
        final float scalingFactor = 4;
        for (int vertex = gathers.nextSetBit(0); vertex >= 0; vertex = gathers.nextSetBit(vertex + 1)) {
            if (vertex != vxId) {
                wg.setFloatValue(xId, vertex, x + scalingFactor * (h * left.getX() + v * up.getX()));
                wg.setFloatValue(yId, vertex, y + scalingFactor * (h * left.getY() + v * up.getY()));
                wg.setFloatValue(zId, vertex, z + scalingFactor * (h * left.getZ() + v * up.getZ()));
                if (++h == rowLength) {
                    h = 0;
                    v++;
                }
            }
        }
    }
}
Also used : Frame(au.gov.asd.tac.constellation.utilities.graphics.Frame) Matrix44f(au.gov.asd.tac.constellation.utilities.graphics.Matrix44f) Matrix33f(au.gov.asd.tac.constellation.utilities.graphics.Matrix33f) Vector3f(au.gov.asd.tac.constellation.utilities.graphics.Vector3f) BitSet(java.util.BitSet) Camera(au.gov.asd.tac.constellation.utilities.camera.Camera)

Example 3 with Frame

use of au.gov.asd.tac.constellation.utilities.graphics.Frame in project constellation by constellation-app.

the class BroccoliArranger method arrangeVertex.

/**
 * Arrange the neighbours of the given vertex with degree 1 into a fan
 * relative to the centre.
 *
 * @param centre
 * @param vid
 */
private void arrangeVertex(final Vector3f centre, final int vxId) {
    float maxRadius = 0;
    final ArrayList<Integer> deg1 = new ArrayList<>();
    final int vncount = wg.getVertexNeighbourCount(vxId);
    for (int i = 0; i < vncount; i++) {
        final int vnId = wg.getVertexNeighbour(vxId, i);
        if (wg.getVertexNeighbourCount(vnId) == 1) {
            deg1.add(vnId);
            final float nradius = nradiusId != Graph.NOT_FOUND ? wg.getFloatValue(nradiusId, vnId) : 1;
            if (nradius > maxRadius) {
                maxRadius = nradius;
            }
        }
    }
    if (!deg1.isEmpty()) {
        final Vector3f xyz = new Vector3f(wg.getFloatValue(xId, vxId), wg.getFloatValue(yId, vxId), wg.getFloatValue(zId, vxId));
        final int size = deg1.size();
        final int sideLen = (int) Math.floor(Math.sqrt(size - 1.0)) + 1;
        final float sideLen1 = sideLen - 1F;
        // Generate a suitable up vector for lookAt.
        final Vector3f tmpv = new Vector3f();
        tmpv.crossProduct(xyz, Y_VECTOR);
        final Vector3f up = new Vector3f();
        up.crossProduct(tmpv, xyz);
        up.normalize();
        // Create a rotation matrix that will rotate the positions we're about to create
        // to the parent vertex.
        final Frame frame = new Frame(xyz, ZERO_VECTOR, up);
        final Matrix44f rm = new Matrix44f();
        frame.getMatrix(rm, true);
        final Matrix33f rotm = new Matrix33f();
        rm.getRotationMatrix(rotm);
        // Layout the degree 1 vertices on the surface of a sphere.
        for (int i = 0; i < size; i++) {
            final int vx1Id = deg1.get(i);
            // A position in the unit square.
            final float xs = sideLen1 > 0 ? (((float) i / sideLen) / sideLen1) * 2 - 1 : 0;
            final float ys = sideLen1 > 0 ? ((i % sideLen) / sideLen1) * 2 - 1 : 0;
            final Vector3f v = new Vector3f(xs, ys, 1);
            // Map the square onto the surface of the unit sphere.
            v.normalize();
            // Rotate the normalized square relative to the centre, resize it,
            // and move it to its parent.
            final Vector3f vrot = new Vector3f();
            vrot.rotate(v, rotm);
            vrot.scale(sideLen * 2 * maxRadius);
            vrot.add(xyz);
            final float x = vrot.getX();
            final float y = vrot.getY();
            final float z = vrot.getZ();
            wg.setFloatValue(xId, vx1Id, x);
            wg.setFloatValue(yId, vx1Id, y);
            wg.setFloatValue(zId, vx1Id, z);
        }
    }
}
Also used : Frame(au.gov.asd.tac.constellation.utilities.graphics.Frame) Matrix44f(au.gov.asd.tac.constellation.utilities.graphics.Matrix44f) Matrix33f(au.gov.asd.tac.constellation.utilities.graphics.Matrix33f) Vector3f(au.gov.asd.tac.constellation.utilities.graphics.Vector3f) ArrayList(java.util.ArrayList)

Example 4 with Frame

use of au.gov.asd.tac.constellation.utilities.graphics.Frame in project constellation by constellation-app.

the class BoxSelectionPlugin method edit.

@Override
public void edit(final GraphWriteMethods graph, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException {
    final float mix = camera.getMix();
    final float inverseMix = 1.0F - mix;
    final Vector3f centre = new Vector3f(camera.lookAtCentre);
    final float left = box[0];
    final float right = box[1];
    final float top = box[2];
    final float bottom = box[3];
    // Look up all the required attributes.
    int xAttr = VisualConcept.VertexAttribute.X.get(graph);
    int yAttr = VisualConcept.VertexAttribute.Y.get(graph);
    int zAttr = VisualConcept.VertexAttribute.Z.get(graph);
    final int x2Attr = VisualConcept.VertexAttribute.X2.get(graph);
    final int y2Attr = VisualConcept.VertexAttribute.Y2.get(graph);
    final int z2Attr = VisualConcept.VertexAttribute.Z2.get(graph);
    final int vxSelectedAttr = VisualConcept.VertexAttribute.SELECTED.get(graph);
    final int txSelectedAttr = VisualConcept.TransactionAttribute.SELECTED.get(graph);
    final int vxVisibilityAttr = VisualConcept.VertexAttribute.VISIBILITY.get(graph);
    final int txVisibilityAttr = VisualConcept.TransactionAttribute.VISIBILITY.get(graph);
    final SetBooleanValuesOperation selectVerticesOperation = new SetBooleanValuesOperation(graph, GraphElementType.VERTEX, vxSelectedAttr);
    final SetBooleanValuesOperation selectTransactionsOperation = new SetBooleanValuesOperation(graph, GraphElementType.TRANSACTION, txSelectedAttr);
    final float visibilityHigh = camera.getVisibilityHigh();
    final float visibilityLow = camera.getVisibilityLow();
    // Get a copy of the current rotation matrix.
    final Vector3f diff = Vector3f.subtract(camera.lookAtEye, camera.lookAtCentre);
    final float cameraDistance = diff.getLength();
    // Get the inverse eye rotation to match the object frame rotation.
    final Frame frame = new Frame(camera.lookAtEye, camera.lookAtCentre, camera.lookAtUp);
    final Matrix44f objectFrameMatrix = new Matrix44f();
    frame.getMatrix(objectFrameMatrix, true);
    final Matrix44f rotationMatrixt = new Matrix44f();
    objectFrameMatrix.getRotationMatrix(rotationMatrixt);
    final Matrix44f rotationMatrixti = new Matrix44f();
    rotationMatrixti.invert(rotationMatrixt);
    final Matrix33f rotationMatrix = new Matrix33f();
    rotationMatrixti.getRotationMatrix(rotationMatrix);
    // Do the vertex positions need mixing?
    boolean requiresMix = x2Attr != Graph.NOT_FOUND && y2Attr != Graph.NOT_FOUND && z2Attr != Graph.NOT_FOUND;
    boolean requiresVertexVisibility = vxVisibilityAttr != Graph.NOT_FOUND;
    boolean requiresTransactionVisibility = txVisibilityAttr != Graph.NOT_FOUND;
    // If the mix value is either 0 or 1 then no mixing is required
    if (requiresMix && mix == 0.0F) {
        requiresMix = false;
    } else if (requiresMix && mix == 1.0F) {
        xAttr = x2Attr;
        yAttr = y2Attr;
        zAttr = z2Attr;
        requiresMix = false;
    } else {
    // Do nothing
    }
    final BitSet vxIncluded = new BitSet();
    final int vxCount = graph.getVertexCount();
    // Select the correct vertices.
    for (int position = 0; position != vxCount; position++) {
        final int vxId = graph.getVertex(position);
        if (requiresVertexVisibility) {
            final float visibility = graph.getFloatValue(vxVisibilityAttr, vxId);
            if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
                continue;
            }
        }
        // Get the main location of the vertex.
        float x = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxId) : VisualGraphDefaults.getDefaultX(vxId);
        float y = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxId) : VisualGraphDefaults.getDefaultY(vxId);
        float z = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxId) : VisualGraphDefaults.getDefaultZ(vxId);
        // If mixing is required then mix the main location with the alternative location.
        if (requiresMix) {
            x = inverseMix * x + mix * graph.getFloatValue(x2Attr, vxId);
            y = inverseMix * y + mix * graph.getFloatValue(y2Attr, vxId);
            z = inverseMix * z + mix * graph.getFloatValue(z2Attr, vxId);
        }
        // Convert world coordinates to camera coordinates.
        final Vector3f sceneLocation = convertWorldToScene(x, y, z, centre, rotationMatrix, cameraDistance);
        final int rAttr = VisualConcept.VertexAttribute.NODE_RADIUS.get(graph);
        final float r = graph.getFloatValue(rAttr, vxId);
        if (sceneLocation.getZ() < 0) {
            final float leftMostPoint = (sceneLocation.getX() - r) / -sceneLocation.getZ();
            final float rightMostPoint = (sceneLocation.getX() + r) / -sceneLocation.getZ();
            final float bottomMostPoint = (sceneLocation.getY() - r) / -sceneLocation.getZ();
            final float topMostPoint = (sceneLocation.getY() + r) / -sceneLocation.getZ();
            final boolean vertexLeftOfBox = rightMostPoint < left;
            final boolean vertexRightOfBox = right < leftMostPoint;
            final boolean vertexBelowBox = topMostPoint < bottom;
            final boolean vertexAboveBox = top < bottomMostPoint;
            if (!vertexLeftOfBox && !vertexRightOfBox && !vertexBelowBox && !vertexAboveBox) {
                vxIncluded.set(vxId);
            }
        }
    }
    final BitSet txIncluded = new BitSet();
    if (vxIncluded.isEmpty()) {
        // There were no vertices in the selection box,
        // so now we check if any lines overlapped. If they do, include the vertices at the ends of
        // those lines.
        // Note: we're checking the actual connections, not what is drawn on the display.
        // This could be confusing for the user, but checking against what is actually displayed would be
        // a very different kettle of lines.
        final int linkCount = graph.getLinkCount();
        for (int position = 0; position < linkCount; position++) {
            final int linkId = graph.getLink(position);
            final int vxLo = graph.getLinkLowVertex(linkId);
            final int vxHi = graph.getLinkHighVertex(linkId);
            // Get the main location of the lo vertex.
            float xLo = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxLo) : VisualGraphDefaults.getDefaultX(vxLo);
            float yLo = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxLo) : VisualGraphDefaults.getDefaultY(vxLo);
            float zLo = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxLo) : VisualGraphDefaults.getDefaultZ(vxLo);
            // Get the main location of the lo vertex.
            float xHi = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxHi) : VisualGraphDefaults.getDefaultX(vxHi);
            float yHi = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxHi) : VisualGraphDefaults.getDefaultY(vxHi);
            float zHi = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxHi) : VisualGraphDefaults.getDefaultZ(vxHi);
            if (requiresMix) {
                xLo = inverseMix * xLo + mix * graph.getFloatValue(x2Attr, vxLo);
                yLo = inverseMix * yLo + mix * graph.getFloatValue(y2Attr, vxLo);
                zLo = inverseMix * zLo + mix * graph.getFloatValue(z2Attr, vxLo);
                xHi = inverseMix * xHi + mix * graph.getFloatValue(x2Attr, vxHi);
                yHi = inverseMix * yHi + mix * graph.getFloatValue(y2Attr, vxHi);
                zHi = inverseMix * zHi + mix * graph.getFloatValue(z2Attr, vxHi);
            }
            // Convert world coordinates to camera coordinates.
            final Vector3f worldLocationLo = new Vector3f(xLo, yLo, zLo);
            worldLocationLo.subtract(centre);
            final Vector3f lo = new Vector3f();
            lo.rotate(worldLocationLo, rotationMatrix);
            lo.setZ(lo.getZ() - cameraDistance);
            final Vector3f worldLocationHi = new Vector3f(xHi, yHi, zHi);
            worldLocationHi.subtract(centre);
            final Vector3f hi = new Vector3f();
            hi.rotate(worldLocationHi, rotationMatrix);
            hi.setZ(hi.getZ() - cameraDistance);
            // If at least one of the end-points is in front of the eye...
            if (lo.getZ() < 0 || hi.getZ() < 0) {
                // Project the 3d eye coordinates of the ends of the line onto the 2D viewing plane.
                // The algorithm to do this depends on where the points are.
                // If a point is in front of the eye (z<0), project to the z==0 plane.
                // See 2.13 Coordinate Transformations in "OpenGL 3.3 (Core Profile)".
                // If a point is behind the eye (z>0), the line connecting the points must be clipped at z==0.
                // Project x,y by using the equation for findnig where a line crosses the plane z==0.
                // See 2.19.1 Clipping Shader Varying Outputs in "OpenGL 3.3 (Core Profile)".
                final float horizontalOffsetLo;
                final float horizontalOffsetHi;
                final float verticalOffsetLo;
                final float verticalOffsetHi;
                if (lo.getZ() < 0) {
                    final float loz = -Math.abs(lo.getZ());
                    horizontalOffsetLo = lo.getX() / -loz;
                    verticalOffsetLo = lo.getY() / -loz;
                } else if (lo.getZ() > 0) {
                    horizontalOffsetLo = lo.getX() + (lo.getZ() * (hi.getX() - lo.getX())) / (lo.getZ() - hi.getZ());
                    verticalOffsetLo = lo.getY() + (lo.getZ() * (hi.getY() - lo.getY()) / (lo.getZ() - hi.getZ()));
                } else {
                    horizontalOffsetLo = lo.getX();
                    verticalOffsetLo = lo.getY();
                }
                if (hi.getZ() < 0) {
                    final float hiz = -Math.abs(hi.getZ());
                    horizontalOffsetHi = hi.getX() / -hiz;
                    verticalOffsetHi = hi.getY() / -hiz;
                } else if (hi.getZ() > 0) {
                    horizontalOffsetHi = lo.getX() + (lo.getZ() * (hi.getX() - lo.getX())) / (lo.getZ() - hi.getZ());
                    verticalOffsetHi = lo.getY() + (lo.getZ() * (hi.getY() - lo.getY()) / (lo.getZ() - hi.getZ()));
                } else {
                    horizontalOffsetHi = hi.getX();
                    verticalOffsetHi = hi.getY();
                }
                final boolean intersects = lineSegmentIntersectsRectangle(horizontalOffsetLo, verticalOffsetLo, horizontalOffsetHi, verticalOffsetHi, left, bottom, right, top);
                if (intersects) {
                    final int linkTxCount = graph.getLinkTransactionCount(linkId);
                    for (int linkPos = 0; linkPos < linkTxCount; linkPos++) {
                        final int txId = graph.getLinkTransaction(linkId, linkPos);
                        txIncluded.set(txId);
                    }
                }
            }
        }
    }
    final int txCount = graph.getTransactionCount();
    if (txIncluded.isEmpty()) {
        if (isAdd) {
            if (vxSelectedAttr != Graph.NOT_FOUND) {
                for (int vxId = vxIncluded.nextSetBit(0); vxId >= 0; vxId = vxIncluded.nextSetBit(vxId + 1)) {
                    if (!graph.getBooleanValue(vxSelectedAttr, vxId)) {
                        selectVerticesOperation.setValue(vxId, true);
                    }
                }
            }
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < txCount; position++) {
                    final int txId = graph.getTransaction(position);
                    if (vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId)) && !graph.getBooleanValue(txSelectedAttr, txId)) {
                        if (requiresTransactionVisibility) {
                            float visibility = graph.getFloatValue(txVisibilityAttr, txId);
                            if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
                                continue;
                            }
                        }
                        selectTransactionsOperation.setValue(txId, true);
                    }
                }
            }
        } else if (isToggle) {
            if (vxSelectedAttr != Graph.NOT_FOUND) {
                for (int vertex = vxIncluded.nextSetBit(0); vertex >= 0; vertex = vxIncluded.nextSetBit(vertex + 1)) {
                    selectVerticesOperation.setValue(vertex, !graph.getBooleanValue(vxSelectedAttr, vertex));
                }
            }
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < txCount; position++) {
                    final int txId = graph.getTransaction(position);
                    if (vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId))) {
                        if (requiresTransactionVisibility) {
                            float visibility = graph.getFloatValue(txVisibilityAttr, txId);
                            if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
                                continue;
                            }
                        }
                        selectTransactionsOperation.setValue(txId, !graph.getBooleanValue(txSelectedAttr, txId));
                    }
                }
            }
        } else {
            if (vxSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < vxCount; position++) {
                    final int vxId = graph.getVertex(position);
                    final boolean included = vxIncluded.get(vxId);
                    if (included != graph.getBooleanValue(vxSelectedAttr, vxId)) {
                        selectVerticesOperation.setValue(vxId, included);
                    }
                }
            }
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < txCount; position++) {
                    final int txId = graph.getTransaction(position);
                    boolean included = vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId));
                    if (requiresTransactionVisibility) {
                        float visibility = graph.getFloatValue(txVisibilityAttr, txId);
                        if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
                            included = false;
                        }
                    }
                    if (included != graph.getBooleanValue(txSelectedAttr, txId)) {
                        selectTransactionsOperation.setValue(txId, included);
                    }
                }
            }
        }
    } else {
        // TODO: figure out if we also want to select the associated vertices.
        if (isAdd) {
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int txId = txIncluded.nextSetBit(0); txId >= 0; txId = txIncluded.nextSetBit(txId + 1)) {
                    if (!graph.getBooleanValue(txSelectedAttr, txId)) {
                        selectTransactionsOperation.setValue(txId, true);
                    }
                }
            }
        } else if (isToggle) {
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int txId = txIncluded.nextSetBit(0); txId >= 0; txId = txIncluded.nextSetBit(txId + 1)) {
                    selectTransactionsOperation.setValue(txId, !graph.getBooleanValue(txSelectedAttr, txId));
                }
            }
        } else {
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < txCount; position++) {
                    final int txId = graph.getTransaction(position);
                    final boolean included = txIncluded.get(txId);
                    if (included != graph.getBooleanValue(txSelectedAttr, txId)) {
                        selectTransactionsOperation.setValue(txId, included);
                    }
                }
            }
            // Deselect any selected vertices.
            if (vxSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < vxCount; position++) {
                    final int vxId = graph.getVertex(position);
                    final boolean selected = graph.getBooleanValue(vxSelectedAttr, vxId);
                    if (selected) {
                        selectVerticesOperation.setValue(vxId, false);
                    }
                }
            }
        }
    }
    graph.executeGraphOperation(selectVerticesOperation);
    graph.executeGraphOperation(selectTransactionsOperation);
}
Also used : SetBooleanValuesOperation(au.gov.asd.tac.constellation.graph.operations.SetBooleanValuesOperation) Frame(au.gov.asd.tac.constellation.utilities.graphics.Frame) Matrix44f(au.gov.asd.tac.constellation.utilities.graphics.Matrix44f) Matrix33f(au.gov.asd.tac.constellation.utilities.graphics.Matrix33f) Vector3f(au.gov.asd.tac.constellation.utilities.graphics.Vector3f) BitSet(java.util.BitSet)

Example 5 with Frame

use of au.gov.asd.tac.constellation.utilities.graphics.Frame in project constellation by constellation-app.

the class FreeformSelectionPlugin method edit.

@Override
public void edit(final GraphWriteMethods graph, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException {
    final float mix = camera.getMix();
    final float inverseMix = 1.0F - mix;
    final Vector3f centre = new Vector3f(camera.lookAtCentre);
    final float left = box[0];
    final float right = box[1];
    final float top = box[2];
    final float bottom = box[3];
    // Look up all the required attributes.
    int xAttr = VisualConcept.VertexAttribute.X.get(graph);
    int yAttr = VisualConcept.VertexAttribute.Y.get(graph);
    int zAttr = VisualConcept.VertexAttribute.Z.get(graph);
    final int x2Attr = VisualConcept.VertexAttribute.X2.get(graph);
    final int y2Attr = VisualConcept.VertexAttribute.Y2.get(graph);
    final int z2Attr = VisualConcept.VertexAttribute.Z2.get(graph);
    final int vxSelectedAttr = VisualConcept.VertexAttribute.SELECTED.get(graph);
    final int txSelectedAttr = VisualConcept.TransactionAttribute.SELECTED.get(graph);
    final int vxVisibilityAttr = VisualConcept.VertexAttribute.VISIBILITY.get(graph);
    final int txVisibilityAttr = VisualConcept.TransactionAttribute.VISIBILITY.get(graph);
    final SetBooleanValuesOperation selectVerticesOperation = new SetBooleanValuesOperation(graph, GraphElementType.VERTEX, vxSelectedAttr);
    final SetBooleanValuesOperation selectTransactionsOperation = new SetBooleanValuesOperation(graph, GraphElementType.TRANSACTION, txSelectedAttr);
    final float visibilityHigh = camera.getVisibilityHigh();
    final float visibilityLow = camera.getVisibilityLow();
    // Get a copy of the current rotation matrix.
    final Vector3f diff = Vector3f.subtract(camera.lookAtEye, camera.lookAtCentre);
    final float cameraDistance = diff.getLength();
    // Get the inverse eye rotation to match the object frame rotation.
    final Frame frame = new Frame(camera.lookAtEye, camera.lookAtCentre, camera.lookAtUp);
    final Matrix44f objectFrameMatrix = new Matrix44f();
    frame.getMatrix(objectFrameMatrix, true);
    final Matrix44f rotationMatrixt = new Matrix44f();
    objectFrameMatrix.getRotationMatrix(rotationMatrixt);
    final Matrix44f rotationMatrixti = new Matrix44f();
    rotationMatrixti.invert(rotationMatrixt);
    final Matrix33f rotationMatrix = new Matrix33f();
    rotationMatrixti.getRotationMatrix(rotationMatrix);
    // Do the vertex positions need mixing?
    boolean requiresMix = x2Attr != Graph.NOT_FOUND && y2Attr != Graph.NOT_FOUND && z2Attr != Graph.NOT_FOUND;
    final boolean requiresVertexVisibility = vxVisibilityAttr != Graph.NOT_FOUND;
    final boolean requiresTransactionVisibility = txVisibilityAttr != Graph.NOT_FOUND;
    // If the mix value is either 0 or 1 then no mixing is required
    if (requiresMix && mix == 0.0F) {
        requiresMix = false;
    } else if (requiresMix && mix == 1.0F) {
        xAttr = x2Attr;
        yAttr = y2Attr;
        zAttr = z2Attr;
        requiresMix = false;
    } else {
    // Do nothing
    }
    final BitSet vxIncluded = new BitSet();
    final int vxCount = graph.getVertexCount();
    // Select the correct vertices.
    for (int position = 0; position != vxCount; position++) {
        final int vxId = graph.getVertex(position);
        if (requiresVertexVisibility) {
            final float visibility = graph.getFloatValue(vxVisibilityAttr, vxId);
            if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
                continue;
            }
        }
        // Get the main location of the vertex.
        float x = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxId) : VisualGraphDefaults.getDefaultX(vxId);
        float y = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxId) : VisualGraphDefaults.getDefaultY(vxId);
        float z = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxId) : VisualGraphDefaults.getDefaultZ(vxId);
        // If mixing is required then mix the main location with the alternative location.
        boolean mixed = false;
        if (requiresMix) {
            x = inverseMix * x + mix * graph.getFloatValue(x2Attr, vxId);
            y = inverseMix * y + mix * graph.getFloatValue(y2Attr, vxId);
            z = inverseMix * z + mix * graph.getFloatValue(z2Attr, vxId);
            mixed = true;
        }
        // Convert world coordinates to camera coordinates.
        final Vector3f sceneLocation = convertWorldToScene(x, y, z, centre, rotationMatrix, cameraDistance);
        final int rAttr = VisualConcept.VertexAttribute.NODE_RADIUS.get(graph);
        final float r = graph.getFloatValue(rAttr, vxId);
        if (sceneLocation.getZ() < 0) {
            final float leftMostPoint = (sceneLocation.getX() - r) / -sceneLocation.getZ();
            final float rightMostPoint = (sceneLocation.getX() + r) / -sceneLocation.getZ();
            final float bottomMostPoint = (sceneLocation.getY() - r) / -sceneLocation.getZ();
            final float topMostPoint = (sceneLocation.getY() + r) / -sceneLocation.getZ();
            final boolean vertexLeftOfFreeform = rightMostPoint < left;
            final boolean vertexRightOfFreeform = right < leftMostPoint;
            final boolean vertexBelowFreeform = topMostPoint < bottom;
            final boolean vertexAboveFreeform = top < bottomMostPoint;
            if (!vertexLeftOfFreeform && !vertexRightOfFreeform && !vertexBelowFreeform && !vertexAboveFreeform && inFreeformPolygons(leftMostPoint, topMostPoint)) {
                vxIncluded.set(vxId);
            }
        }
    }
    final BitSet txIncluded = new BitSet();
    if (vxIncluded.isEmpty()) {
        final int linkCount = graph.getLinkCount();
        for (int position = 0; position < linkCount; position++) {
            final int linkId = graph.getLink(position);
            final int vxLo = graph.getLinkLowVertex(linkId);
            final int vxHi = graph.getLinkHighVertex(linkId);
            // Get the main location of the lo vertex.
            float xLo = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxLo) : VisualGraphDefaults.getDefaultX(vxLo);
            float yLo = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxLo) : VisualGraphDefaults.getDefaultY(vxLo);
            float zLo = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxLo) : VisualGraphDefaults.getDefaultZ(vxLo);
            // Get the main location of the lo vertex.
            float xHi = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxHi) : VisualGraphDefaults.getDefaultX(vxHi);
            float yHi = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxHi) : VisualGraphDefaults.getDefaultY(vxHi);
            float zHi = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxHi) : VisualGraphDefaults.getDefaultZ(vxHi);
            if (requiresMix) {
                xLo = inverseMix * xLo + mix * graph.getFloatValue(x2Attr, vxLo);
                yLo = inverseMix * yLo + mix * graph.getFloatValue(y2Attr, vxLo);
                zLo = inverseMix * zLo + mix * graph.getFloatValue(z2Attr, vxLo);
                xHi = inverseMix * xHi + mix * graph.getFloatValue(x2Attr, vxHi);
                yHi = inverseMix * yHi + mix * graph.getFloatValue(y2Attr, vxHi);
                zHi = inverseMix * zHi + mix * graph.getFloatValue(z2Attr, vxHi);
            }
            // Convert world coordinates to camera coordinates.
            final Vector3f worldLocationLo = new Vector3f(xLo, yLo, zLo);
            worldLocationLo.subtract(centre);
            final Vector3f lo = new Vector3f();
            lo.rotate(worldLocationLo, rotationMatrix);
            lo.setZ(lo.getZ() - cameraDistance);
            final Vector3f worldLocationHi = new Vector3f(xHi, yHi, zHi);
            worldLocationHi.subtract(centre);
            final Vector3f hi = new Vector3f();
            hi.rotate(worldLocationHi, rotationMatrix);
            hi.setZ(hi.getZ() - cameraDistance);
            // If at least one of the end-points is in front of the eye...
            if (lo.getZ() < 0 || hi.getZ() < 0) {
                final float horizontalOffsetLo;
                final float horizontalOffsetHi;
                final float verticalOffsetLo;
                final float verticalOffsetHi;
                if (lo.getZ() < 0) {
                    final float loz = -Math.abs(lo.getZ());
                    horizontalOffsetLo = lo.getX() / -loz;
                    verticalOffsetLo = lo.getY() / -loz;
                } else if (lo.getZ() > 0) {
                    horizontalOffsetLo = lo.getX() + (lo.getZ() * (hi.getX() - lo.getX())) / (lo.getZ() - hi.getZ());
                    verticalOffsetLo = lo.getY() + (lo.getZ() * (hi.getY() - lo.getY()) / (lo.getZ() - hi.getZ()));
                } else {
                    horizontalOffsetLo = lo.getX();
                    verticalOffsetLo = lo.getY();
                }
                if (hi.getZ() < 0) {
                    final float hiz = -Math.abs(hi.getZ());
                    horizontalOffsetHi = hi.getX() / -hiz;
                    verticalOffsetHi = hi.getY() / -hiz;
                } else if (hi.getZ() > 0) {
                    horizontalOffsetHi = lo.getX() + (lo.getZ() * (hi.getX() - lo.getX())) / (lo.getZ() - hi.getZ());
                    verticalOffsetHi = lo.getY() + (lo.getZ() * (hi.getY() - lo.getY()) / (lo.getZ() - hi.getZ()));
                } else {
                    horizontalOffsetHi = hi.getX();
                    verticalOffsetHi = hi.getY();
                }
                final boolean intersects = lineSegmentIntersectsRectangle(horizontalOffsetLo, verticalOffsetLo, horizontalOffsetHi, verticalOffsetHi, left, bottom, right, top);
                if (intersects) {
                    final int linkTxCount = graph.getLinkTransactionCount(linkId);
                    for (int linkPos = 0; linkPos < linkTxCount; linkPos++) {
                        final int txId = graph.getLinkTransaction(linkId, linkPos);
                        txIncluded.set(txId);
                    }
                }
            }
        }
    }
    final int txCount = graph.getTransactionCount();
    if (txIncluded.isEmpty()) {
        if (isAdd) {
            if (vxSelectedAttr != Graph.NOT_FOUND) {
                for (int vxId = vxIncluded.nextSetBit(0); vxId >= 0; vxId = vxIncluded.nextSetBit(vxId + 1)) {
                    if (!graph.getBooleanValue(vxSelectedAttr, vxId)) {
                        selectVerticesOperation.setValue(vxId, true);
                    }
                }
            }
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < txCount; position++) {
                    final int txId = graph.getTransaction(position);
                    if (vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId)) && !graph.getBooleanValue(txSelectedAttr, txId)) {
                        if (requiresTransactionVisibility) {
                            final float visibility = graph.getFloatValue(txVisibilityAttr, txId);
                            if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
                                continue;
                            }
                        }
                        selectTransactionsOperation.setValue(txId, true);
                    }
                }
            }
        } else if (isToggle) {
            if (vxSelectedAttr != Graph.NOT_FOUND) {
                for (int vertex = vxIncluded.nextSetBit(0); vertex >= 0; vertex = vxIncluded.nextSetBit(vertex + 1)) {
                    selectVerticesOperation.setValue(vertex, !graph.getBooleanValue(vxSelectedAttr, vertex));
                }
            }
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < txCount; position++) {
                    final int txId = graph.getTransaction(position);
                    if (vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId))) {
                        if (requiresTransactionVisibility) {
                            final float visibility = graph.getFloatValue(txVisibilityAttr, txId);
                            if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
                                continue;
                            }
                        }
                        selectTransactionsOperation.setValue(txId, !graph.getBooleanValue(txSelectedAttr, txId));
                    }
                }
            }
        } else {
            if (vxSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < vxCount; position++) {
                    final int vxId = graph.getVertex(position);
                    final boolean included = vxIncluded.get(vxId);
                    if (included != graph.getBooleanValue(vxSelectedAttr, vxId)) {
                        selectVerticesOperation.setValue(vxId, included);
                    }
                }
            }
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < txCount; position++) {
                    final int txId = graph.getTransaction(position);
                    boolean included = vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId));
                    if (requiresTransactionVisibility) {
                        final float visibility = graph.getFloatValue(txVisibilityAttr, txId);
                        if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
                            included = false;
                        }
                    }
                    if (included != graph.getBooleanValue(txSelectedAttr, txId)) {
                        selectTransactionsOperation.setValue(txId, included);
                    }
                }
            }
        }
    } else {
        if (isAdd) {
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int txId = txIncluded.nextSetBit(0); txId >= 0; txId = txIncluded.nextSetBit(txId + 1)) {
                    if (!graph.getBooleanValue(txSelectedAttr, txId)) {
                        selectTransactionsOperation.setValue(txId, true);
                    }
                }
            }
        } else if (isToggle) {
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int txId = txIncluded.nextSetBit(0); txId >= 0; txId = txIncluded.nextSetBit(txId + 1)) {
                    selectTransactionsOperation.setValue(txId, !graph.getBooleanValue(txSelectedAttr, txId));
                }
            }
        } else {
            if (txSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < txCount; position++) {
                    final int txId = graph.getTransaction(position);
                    final boolean included = txIncluded.get(txId);
                    if (included != graph.getBooleanValue(txSelectedAttr, txId)) {
                        selectTransactionsOperation.setValue(txId, included);
                    }
                }
            }
            // Deselect any selected vertices.
            if (vxSelectedAttr != Graph.NOT_FOUND) {
                for (int position = 0; position < vxCount; position++) {
                    final int vxId = graph.getVertex(position);
                    final boolean selected = graph.getBooleanValue(vxSelectedAttr, vxId);
                    if (selected) {
                        selectVerticesOperation.setValue(vxId, false);
                    }
                }
            }
        }
    }
    graph.executeGraphOperation(selectVerticesOperation);
    graph.executeGraphOperation(selectTransactionsOperation);
}
Also used : SetBooleanValuesOperation(au.gov.asd.tac.constellation.graph.operations.SetBooleanValuesOperation) Frame(au.gov.asd.tac.constellation.utilities.graphics.Frame) Matrix44f(au.gov.asd.tac.constellation.utilities.graphics.Matrix44f) Matrix33f(au.gov.asd.tac.constellation.utilities.graphics.Matrix33f) Vector3f(au.gov.asd.tac.constellation.utilities.graphics.Vector3f) BitSet(java.util.BitSet)

Aggregations

Frame (au.gov.asd.tac.constellation.utilities.graphics.Frame)19 Vector3f (au.gov.asd.tac.constellation.utilities.graphics.Vector3f)14 Matrix33f (au.gov.asd.tac.constellation.utilities.graphics.Matrix33f)5 Matrix44f (au.gov.asd.tac.constellation.utilities.graphics.Matrix44f)5 Test (org.testng.annotations.Test)5 Camera (au.gov.asd.tac.constellation.utilities.camera.Camera)4 BitSet (java.util.BitSet)4 JsonNode (com.fasterxml.jackson.databind.JsonNode)3 SetBooleanValuesOperation (au.gov.asd.tac.constellation.graph.operations.SetBooleanValuesOperation)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 ArrayList (java.util.ArrayList)1 BeforeClass (org.testng.annotations.BeforeClass)1