Package org.gephi.visualization.opengl.compatibility

Source Code of org.gephi.visualization.opengl.compatibility.CompatibilityEngine

/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org

This file is part of Gephi.

Gephi is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Gephi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Gephi.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.gephi.visualization.opengl.compatibility;

import com.sun.opengl.util.BufferUtil;
import java.awt.Color;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import org.gephi.graph.api.EdgeData;
import org.gephi.graph.api.Model;
import org.gephi.graph.api.NodeData;
import org.gephi.visualization.VizController;
import org.gephi.visualization.VizModel;
import org.gephi.visualization.api.objects.ModelClass;
import org.gephi.visualization.opengl.AbstractEngine;
import org.gephi.visualization.apiimpl.ModelImpl;
import org.gephi.visualization.api.initializer.CompatibilityModeler;
import org.gephi.visualization.opengl.octree.Octree;
import org.gephi.visualization.apiimpl.Scheduler;
import org.gephi.visualization.api.objects.CompatibilityModelClass;
import org.gephi.visualization.selection.Cylinder;
import org.gephi.visualization.selection.Rectangle;

/**
*
* @author Mathieu Bastian
*/
public class CompatibilityEngine extends AbstractEngine {

    private CompatibilityScheduler scheduler;
    private long markTime = 0;
    private long markTime2 = 0;
    //User config
    protected CompatibilityModelClass[] modelClasses;
    protected CompatibilityModelClass[] lodClasses;
    protected CompatibilityModelClass[] selectableClasses;
    protected CompatibilityModelClass[] clickableClasses;
    //Selection
    private ConcurrentLinkedQueue<ModelImpl>[] selectedObjects;
    private boolean anySelected = false;

    public CompatibilityEngine() {
        super();
    }

    @Override
    public void initArchitecture() {
        super.initArchitecture();
        scheduler = (CompatibilityScheduler) VizController.getInstance().getScheduler();
        vizEventManager = VizController.getInstance().getVizEventManager();

        //Init
        octree = new Octree(vizConfig.getOctreeDepth(), vizConfig.getOctreeWidth(), modelClasses.length);
        octree.initArchitecture();
    }

    public void updateSelection(GL gl, GLU glu) {
        if (vizConfig.isSelectionEnable() && currentSelectionArea != null && currentSelectionArea.isEnabled()) {
            VizModel vizModel = VizController.getInstance().getVizModel();
            float[] mp = Arrays.copyOf(graphIO.getMousePosition(), 2);
            float[] cent = currentSelectionArea.getSelectionAreaCenter();
            if (cent != null) {
                mp[0] += cent[0];
                mp[1] += cent[1];
            }
            octree.updateSelectedOctant(gl, glu, mp, currentSelectionArea.getSelectionAreaRectancle());

            for (int i = 0; i < selectableClasses.length; i++) {
                CompatibilityModelClass modelClass = selectableClasses[i];

                if (modelClass.isEnabled() && modelClass.isGlSelection()) {
                    int objectCount = octree.countSelectedObjects(modelClass.getClassId());

                    float[] mousePosition = Arrays.copyOf(graphIO.getMousePosition(), 2);
                    float[] pickRectangle = currentSelectionArea.getSelectionAreaRectancle();
                    float[] center = currentSelectionArea.getSelectionAreaCenter();
                    if (center != null) {
                        mousePosition[0] += center[0];
                        mousePosition[1] += center[1];
                    }
                    int capacity = 1 * 4 * objectCount;      //Each object take in maximium : 4 * name stack depth
                    IntBuffer hitsBuffer = BufferUtil.newIntBuffer(capacity);

                    gl.glSelectBuffer(hitsBuffer.capacity(), hitsBuffer);
                    gl.glRenderMode(GL.GL_SELECT);

                    gl.glInitNames();
                    gl.glPushName(0);

                    gl.glMatrixMode(GL.GL_PROJECTION);
                    gl.glPushMatrix();
                    gl.glLoadIdentity();

                    glu.gluPickMatrix(mousePosition[0], mousePosition[1], pickRectangle[0], pickRectangle[1], graphDrawable.getViewport());
                    gl.glMultMatrixd(graphDrawable.getProjectionMatrix());

                    gl.glMatrixMode(GL.GL_MODELVIEW);

                    int hitName = 1;
                    ModelImpl[] array = new ModelImpl[objectCount];
                    for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(modelClass.getClassId()); itr.hasNext();) {
                        ModelImpl obj = itr.next();
                        obj.setAutoSelect(false);

                        array[hitName - 1] = obj;
                        gl.glLoadName(hitName);
                        obj.display(gl, glu, vizModel);
                        hitName++;

                    }

                    //Restoring the original projection matrix
                    gl.glMatrixMode(GL.GL_PROJECTION);
                    gl.glPopMatrix();
                    gl.glMatrixMode(GL.GL_MODELVIEW);
                    gl.glFlush();

                    //Returning to normal rendering mode
                    int nbRecords = gl.glRenderMode(GL.GL_RENDER);

                    //Get the hits and put the node under selection in the selectionArray
                    for (int j = 0; j < nbRecords; j++) {
                        int hit = hitsBuffer.get(j * 4 + 3) - 1;     //-1 Because of the glPushName(0)
                        ModelImpl obj = array[hit];
                        obj.setAutoSelect(true);
                    }
                }
            }
        }
    }

    @Override
    public boolean updateWorld() {
        boolean res = false;
        boolean changeMode = modeManager.requireModeChange();
        boolean newConfig = configChanged;
        if (changeMode) {
            modeManager.unload();
        }
        if (newConfig) {
            dataBridge.reset();
            if (!vizConfig.isCustomSelection()) {
                //Reset model classes
                for (ModelClass objClass : getModelClasses()) {
                    if (objClass.isEnabled()) {
                        objClass.swapModelers();
                        resetObjectClass(objClass);
                    }
                }
            }

            initSelection();

        }
        if (dataBridge.requireUpdate() || changeMode || newConfig) {
            dataBridge.updateWorld();
            res = true;
        }
        if (changeMode) {
            modeManager.changeMode();
        }
        if (newConfig) {

            configChanged = false;
        }
        return res;
    }

    @Override
    public void worldUpdated(int cacheMarker) {
        octree.setCacheMarker(cacheMarker);
        for (ModelClass objClass : modelClasses) {
            if (objClass.getCacheMarker() == cacheMarker) {
                octree.cleanDeletedObjects(objClass.getClassId());
            }
        }
    }

    @Override
    public void beforeDisplay(GL gl, GLU glu) {
        //Lighten delta
        if (lightenAnimationDelta != 0) {
            float factor = vizConfig.getLightenNonSelectedFactor();
            factor += lightenAnimationDelta;
            if (factor >= 0.5f && factor <= 0.98f) {
                vizConfig.setLightenNonSelectedFactor(factor);
            } else {
                lightenAnimationDelta = 0;
                vizConfig.setLightenNonSelected(anySelected);
            }
        }

        if (backgroundChanged) {
            Color backgroundColor = vizController.getVizModel().getBackgroundColor();
            gl.glClearColor(backgroundColor.getRed() / 255f, backgroundColor.getGreen() / 255f, backgroundColor.getBlue() / 255f, 1f);
            gl.glClear(GL.GL_COLOR_BUFFER_BIT);
            backgroundChanged = false;
        }

        if (reinit) {
            VizController.getInstance().refreshWorkspace();
            dataBridge.reset();
            graphDrawable.initConfig(gl);
            graphDrawable.setCameraLocation(vizController.getVizModel().getCameraPosition());
            graphDrawable.setCameraTarget(vizController.getVizModel().getCameraTarget());
            vizConfig.setCustomSelection(false);
            reinit = false;
        }
    }

    @Override
    public void display(GL gl, GLU glu) {
        for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_NODE); itr.hasNext();) {       //TODO Move this
            ModelImpl obj = itr.next();
            modelClasses[AbstractEngine.CLASS_NODE].getCurrentModeler().chooseModel(obj);
            setViewportPosition(obj);
        }

        markTime++;

        CompatibilityModelClass edgeClass = modelClasses[AbstractEngine.CLASS_EDGE];
        CompatibilityModelClass nodeClass = modelClasses[AbstractEngine.CLASS_NODE];
        CompatibilityModelClass arrowClass = modelClasses[AbstractEngine.CLASS_ARROW];
        CompatibilityModelClass potatoClass = modelClasses[AbstractEngine.CLASS_POTATO];

        VizModel vizModel = VizController.getInstance().getVizModel();

        //Potato
        if (potatoClass.isEnabled()) {
            potatoClass.beforeDisplay(gl, glu);
            for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_POTATO); itr.hasNext();) {
                ModelImpl obj = itr.next();

                if (obj.markTime != markTime) {
                    obj.display(gl, glu, vizModel);
                    obj.markTime = markTime;
                }

            }
            potatoClass.afterDisplay(gl, glu);
        }

        //Edges
        if (edgeClass.isEnabled()) {
            edgeClass.beforeDisplay(gl, glu);
            for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_EDGE); itr.hasNext();) {
                ModelImpl obj = itr.next();
                //Renderable renderable = obj.getObj();

                if (obj.markTime != markTime) {
                    obj.display(gl, glu, vizModel);
                    obj.markTime = markTime;
                }

            }
            edgeClass.afterDisplay(gl, glu);
        }

        //Arrows
        if (arrowClass.isEnabled()) {
            arrowClass.beforeDisplay(gl, glu);
            for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_ARROW); itr.hasNext();) {
                ModelImpl obj = itr.next();
                if (obj.markTime != markTime) {
                    obj.display(gl, glu, vizModel);
                    obj.markTime = markTime;
                }
            }
            arrowClass.afterDisplay(gl, glu);
        }

        //Nodes
        if (nodeClass.isEnabled()) {
            nodeClass.beforeDisplay(gl, glu);
            for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_NODE); itr.hasNext();) {
                ModelImpl obj = itr.next();
                if (obj.markTime != markTime) {
                    obj.display(gl, glu, vizModel);
                    obj.markTime = markTime;
                }
            }
            nodeClass.afterDisplay(gl, glu);
        }

        //Labels
        if (vizModel.getTextModel().isShowNodeLabels() || vizModel.getTextModel().isShowEdgeLabels()) {
            markTime++;
            if (nodeClass.isEnabled() && vizModel.getTextModel().isShowNodeLabels()) {
                textManager.getNodeRenderer().beginRendering();
                textManager.defaultNodeColor();
                if (textManager.isSelectedOnly()) {
                    for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_NODE); itr.hasNext();) {
                        ModelImpl obj = itr.next();
                        if (obj.markTime != markTime) {
                            if ((obj.isSelected() || obj.isHighlight()) && obj.getObj().getTextData().isVisible()) {
                                textManager.getNodeRenderer().drawTextNode(obj);
                            }
                            obj.markTime = markTime;
                        }
                    }
                } else {
                    for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_NODE); itr.hasNext();) {
                        ModelImpl obj = itr.next();
                        if (obj.markTime != markTime) {
                            if (obj.getObj().getTextData().isVisible()) {
                                textManager.getNodeRenderer().drawTextNode(obj);
                            }
                            obj.markTime = markTime;
                        }
                    }
                }
                textManager.getNodeRenderer().endRendering();
            }
            if (edgeClass.isEnabled() && vizModel.getTextModel().isShowEdgeLabels()) {
                textManager.getEdgeRenderer().beginRendering();
                textManager.defaultEdgeColor();
                if (textManager.isSelectedOnly()) {
                    for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_EDGE); itr.hasNext();) {
                        ModelImpl obj = itr.next();
                        if (obj.markTime != markTime) {
                            if ((obj.isSelected() || obj.isHighlight()) && obj.getObj().getTextData().isVisible()) {
                                textManager.getEdgeRenderer().drawTextEdge(obj);
                            }
                            obj.markTime = markTime;
                        }
                    }
                } else {
                    for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_EDGE); itr.hasNext();) {
                        ModelImpl obj = itr.next();
                        if (obj.markTime != markTime) {
                            if (obj.getObj().getTextData().isVisible()) {
                                textManager.getEdgeRenderer().drawTextEdge(obj);
                            }
                            obj.markTime = markTime;
                        }
                    }
                }
                textManager.getEdgeRenderer().endRendering();
            }

        }


        //octree.displayOctree(gl, glu);
    }

    @Override
    public void afterDisplay(GL gl, GLU glu) {
        if (vizConfig.isSelectionEnable() && currentSelectionArea != null) {
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glPushMatrix();
            gl.glLoadIdentity();
            gl.glOrtho(0, graphDrawable.getViewportWidth(), 0, graphDrawable.getViewportHeight(), -1, 1);
            gl.glMatrixMode(GL.GL_MODELVIEW);
            gl.glPushMatrix();
            gl.glLoadIdentity();
            currentSelectionArea.drawArea(gl, glu);
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glPopMatrix();
            gl.glMatrixMode(GL.GL_MODELVIEW);
            gl.glPopMatrix();
        }
        graphIO.trigger();
    }

    @Override
    public void cameraHasBeenMoved(GL gl, GLU glu) {
    }

    @Override
    public void initEngine(final GL gl, final GLU glu) {
        initDisplayLists(gl, glu);
        scheduler.cameraMoved.set(true);
        scheduler.mouseMoved.set(true);
        lifeCycle.setInited();
    }

    @Override
    public void initScreenshot(GL gl, GLU glu) {
        initDisplayLists(gl, glu);
        textManager.getNodeRenderer().reinitRenderer();
        textManager.getEdgeRenderer().reinitRenderer();
        scheduler.cameraMoved.set(true);
    }

    @Override
    public void addObject(int classID, ModelImpl obj) {
        octree.addObject(classID, obj);
    }

    @Override
    public void removeObject(int classID, ModelImpl obj) {
        octree.removeObject(classID, obj);
    }

    @Override
    public void resetObjectClass(ModelClass object3dClass) {
        octree.resetObjectClass(object3dClass.getClassId());
    }

    @Override
    public void mouseClick() {
        for (ModelClass objClass : clickableClasses) {
            ModelImpl[] objArray = selectedObjects[objClass.getSelectionId()].toArray(new ModelImpl[0]);
            if (objArray.length > 0) {
                eventBridge.mouseClick(objClass, objArray);
            }
        }

        if (vizConfig.isSelectionEnable() && rectangleSelection && !customSelection) {
            Rectangle rectangle = (Rectangle) currentSelectionArea;
            //rectangle.setBlocking(false);
            //Clean opengl picking
            for (ModelClass objClass : selectableClasses) {
                if (objClass.isEnabled() && objClass.isGlSelection()) {
                    for (ModelImpl obj : selectedObjects[objClass.getSelectionId()]) {
                        obj.setAutoSelect(false);
                    }
                }
            }

            //Select with click
            int i = 0;
            boolean someSelection = false;
            for (ModelClass objClass : selectableClasses) {
                markTime2++;
                for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(objClass.getClassId()); itr.hasNext();) {
                    ModelImpl obj = itr.next();
                    if (isUnderMouse(obj) && currentSelectionArea.select(obj.getObj())) {
                        if (!obj.isSelected()) {
                            //New selected
                            obj.setSelected(true);
                            /*if (vizEventManager.hasSelectionListeners()) {
                            newSelectedObjects.add(obj);
                            }*/
                            selectedObjects[i].add(obj);
                        }
                        someSelection = true;
                        obj.selectionMark = markTime2;
                    }
                }
                if (!(rectangle.isCtrl() && someSelection)) {
                    for (Iterator<ModelImpl> itr = selectedObjects[i].iterator(); itr.hasNext();) {
                        ModelImpl o = itr.next();
                        if (o.selectionMark != markTime2) {
                            itr.remove();
                            o.setSelected(false);
                        }
                    }
                }

                i++;
            }
            rectangle.setBlocking(someSelection);

            if (vizController.getVizModel().isLightenNonSelectedAuto()) {

                if (vizConfig.isLightenNonSelectedAnimation()) {
                    if (!anySelected && someSelection) {
                        //Start animation
                        lightenAnimationDelta = 0.07f;
                    } else if (anySelected && !someSelection) {
                        //Stop animation
                        lightenAnimationDelta = -0.07f;
                    }

                    vizConfig.setLightenNonSelected(someSelection || lightenAnimationDelta != 0);
                } else {
                    vizConfig.setLightenNonSelected(someSelection);
                }
            }

            anySelected = someSelection;

            scheduler.requireUpdateSelection();
        }
    }

    @Override
    public void mouseDrag() {
        if (vizConfig.isMouseSelectionUpdateWhileDragging()) {
            mouseMove();
        } else {
            float[] drag = graphIO.getMouseDrag3d();
            for (ModelImpl obj : selectedObjects[0]) {
                float[] mouseDistance = obj.getDragDistanceFromMouse();
                obj.getObj().setX(drag[0] + mouseDistance[0]);
                obj.getObj().setY(drag[1] + mouseDistance[1]);
            }
        }
    }

    @Override
    public void mouseMove() {

        //Selection
        if (vizConfig.isSelectionEnable() && rectangleSelection) {
            Rectangle rectangle = (Rectangle) currentSelectionArea;
            rectangle.setMousePosition(graphIO.getMousePosition());
            if (rectangle.isStop()) {
                return;
            }
        }

        if (customSelection || currentSelectionArea.blockSelection()) {
            return;
        }


        /*List<ModelImpl> newSelectedObjects = null;
        List<ModelImpl> unSelectedObjects = null;

        if (vizEventManager.hasSelectionListeners()) {
        newSelectedObjects = new ArrayList<ModelImpl>();
        unSelectedObjects = new ArrayList<ModelImpl>();
        }*/

        markTime2++;
        int i = 0;
        boolean someSelection = false;
        boolean forceUnselect = false;
        for (ModelClass objClass : selectableClasses) {
            forceUnselect = objClass.isAloneSelection() && someSelection;
            for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(objClass.getClassId()); itr.hasNext();) {
                ModelImpl obj = itr.next();
                if (!forceUnselect && isUnderMouse(obj) && currentSelectionArea.select(obj.getObj())) {
                    if (!objClass.isAloneSelection()) {  //avoid potatoes to select
                        someSelection = true;
                    }
                    if (!obj.isSelected()) {
                        //New selected
                        obj.setSelected(true);
                        /*if (vizEventManager.hasSelectionListeners()) {
                        newSelectedObjects.add(obj);
                        }*/
                        selectedObjects[i].add(obj);
                    }
                    obj.selectionMark = markTime2;
                } else if (currentSelectionArea.unselect(obj.getObj())) {
                    if (forceUnselect) {
                        obj.setAutoSelect(false);
                    } /*else if (vizEventManager.hasSelectionListeners() && obj.isSelected()) {
                    unSelectedObjects.add(obj);
                    }*/
                }
            }

            for (Iterator<ModelImpl> itr = selectedObjects[i].iterator(); itr.hasNext();) {
                ModelImpl o = itr.next();
                if (o.selectionMark != markTime2) {
                    itr.remove();
                    o.setSelected(false);
                }
            }
            i++;
        }

        if (vizController.getVizModel().isLightenNonSelectedAuto()) {

            if (vizConfig.isLightenNonSelectedAnimation()) {
                if (!anySelected && someSelection) {
                    //Start animation
                    lightenAnimationDelta = 0.07f;
                } else if (anySelected && !someSelection) {
                    //Stop animation
                    lightenAnimationDelta = -0.07f;
                }

                vizConfig.setLightenNonSelected(someSelection || lightenAnimationDelta != 0);
            } else {
                vizConfig.setLightenNonSelected(someSelection);
            }
        }

        anySelected = someSelection;
    }

    @Override
    public void refreshGraphLimits() {
    }

    @Override
    public void startDrag() {
        float x = graphIO.getMouseDrag3d()[0];
        float y = graphIO.getMouseDrag3d()[1];

        for (Iterator<ModelImpl> itr = selectedObjects[0].iterator(); itr.hasNext();) {
            ModelImpl o = itr.next();
            float[] tab = o.getDragDistanceFromMouse();
            tab[0] = o.getObj().x() - x;
            tab[1] = o.getObj().y() - y;
        }
    }

    @Override
    public void stopDrag() {
        scheduler.requireUpdatePosition();

        //Selection
        if (vizConfig.isSelectionEnable() && rectangleSelection) {
            Rectangle rectangle = (Rectangle) currentSelectionArea;
            rectangle.stop();
            scheduler.requireUpdateSelection();
        }
    }

    @Override
    public void updateObjectsPosition() {
        for (ModelClass objClass : modelClasses) {
            if (objClass.isEnabled()) {
                octree.updateObjectsPosition(objClass.getClassId());
            }
        }
    }

    @Override
    public ModelImpl[] getSelectedObjects(int modelClass) {
        return selectedObjects[modelClasses[modelClass].getSelectionId()].toArray(new ModelImpl[0]);
    }

    @Override
    public void selectObject(Model obj) {
        ModelImpl modl = (ModelImpl) obj;
        if (!customSelection) {
            vizConfig.setRectangleSelection(false);
            customSelection = true;
            configChanged = true;
            //Reset
            for (ModelClass objClass : selectableClasses) {
                for (Iterator<ModelImpl> itr = selectedObjects[objClass.getSelectionId()].iterator(); itr.hasNext();) {
                    ModelImpl o = itr.next();
                    itr.remove();
                    o.setSelected(false);
                }
            }
            anySelected = true;
            //Force highlight
            if (vizController.getVizModel().isLightenNonSelectedAuto()) {

                if (vizConfig.isLightenNonSelectedAnimation()) {
                    //Start animation
                    lightenAnimationDelta = 0.07f;
                    vizConfig.setLightenNonSelected(true);
                } else {
                    vizConfig.setLightenNonSelected(true);
                }
            }
        }
        modl.setSelected(true);
        if (modl.getObj() instanceof NodeData) {
            selectedObjects[modelClasses[AbstractEngine.CLASS_NODE].getSelectionId()].add(modl);
        }

        forceSelectRefresh(modelClasses[AbstractEngine.CLASS_EDGE].getClassId());
    }

    @Override
    public void selectObject(Model[] objs) {
        if (!customSelection) {
            vizConfig.setRectangleSelection(false);
            customSelection = true;
            configChanged = true;
            //Reset
            for (ModelClass objClass : selectableClasses) {
                for (Iterator<ModelImpl> itr = selectedObjects[objClass.getSelectionId()].iterator(); itr.hasNext();) {
                    ModelImpl o = itr.next();
                    itr.remove();
                    o.setSelected(false);
                }
            }
            anySelected = true;
            //Force highlight
            if (vizController.getVizModel().isLightenNonSelectedAuto()) {

                if (vizConfig.isLightenNonSelectedAnimation()) {
                    //Start animation
                    lightenAnimationDelta = 0.07f;
                    vizConfig.setLightenNonSelected(true);
                } else {
                    vizConfig.setLightenNonSelected(true);
                }
            }
        } else {
            //Reset
            for (ModelClass objClass : selectableClasses) {
                for (Iterator<ModelImpl> itr = selectedObjects[objClass.getSelectionId()].iterator(); itr.hasNext();) {
                    ModelImpl o = itr.next();
                    itr.remove();
                    o.setSelected(false);
                }
            }

            for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(modelClasses[AbstractEngine.CLASS_EDGE].getClassId()); itr.hasNext();) {
                ModelImpl obj = itr.next();
                obj.setSelected(false);
            }
        }
        for (Model r : objs) {
            if (r != null) {
                ModelImpl mdl = (ModelImpl) r;
                mdl.setSelected(true);
                if (mdl.getObj() instanceof NodeData) {
                    selectedObjects[modelClasses[AbstractEngine.CLASS_NODE].getSelectionId()].add(mdl);
                } else if (mdl.getObj() instanceof EdgeData) {
                    selectedObjects[modelClasses[AbstractEngine.CLASS_EDGE].getSelectionId()].add(mdl);
                }
            }
        }

        //forceSelectRefresh(modelClasses[AbstractEngine.CLASS_EDGE].getClassId());
    }

    public void forceSelectRefresh(int selectedClass) {
        for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(selectedClass); itr.hasNext();) {
            ModelImpl obj = itr.next();
            if (isUnderMouse(obj)) {
                if (!obj.isSelected()) {
                    //New selected
                    obj.setSelected(true);
                    /*if (vizEventManager.hasSelectionListeners()) {
                    newSelectedObjects.add(obj);
                    }*/
                    selectedObjects[selectedClass].add(obj);
                }
            }
        }
    }

    @Override
    public void resetSelection() {
        customSelection = false;
        configChanged = true;
        anySelected = false;
        for (ModelClass objClass : selectableClasses) {
            selectedObjects[objClass.getSelectionId()].clear();
        }
    }

    private void initDisplayLists(GL gl, GLU glu) {
        //Constants
        float blancCasse[] = {(float) 213 / 255, (float) 208 / 255, (float) 188 / 255, 1.0f};
        float noirCasse[] = {(float) 39 / 255, (float) 25 / 255, (float) 99 / 255, 1.0f};
        float noir[] = {(float) 0 / 255, (float) 0 / 255, (float) 0 / 255, 0.0f};
        float[] shine_low = {10.0f, 0.0f, 0.0f, 0.0f};
        FloatBuffer ambient_metal = FloatBuffer.wrap(noir);
        FloatBuffer diffuse_metal = FloatBuffer.wrap(noirCasse);
        FloatBuffer specular_metal = FloatBuffer.wrap(blancCasse);
        FloatBuffer shininess_metal = FloatBuffer.wrap(shine_low);

        //End

        //Quadric for all the glu models
        GLUquadric quadric = glu.gluNewQuadric();
        int ptr = gl.glGenLists(4);

        // Metal material display list
        int MATTER_METAL = ptr;
        gl.glNewList(MATTER_METAL, GL.GL_COMPILE);
        gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, ambient_metal);
        gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, diffuse_metal);
        gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, specular_metal);
        gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, shininess_metal);
        gl.glEndList();
        //Fin

        for (CompatibilityModeler cis : modelClasses[CLASS_NODE].getModelers()) {
            int newPtr = cis.initDisplayLists(gl, glu, quadric, ptr);
            ptr = newPtr;
        }

        //modelClasses[CLASS_POTATO].getCurrentModeler().initDisplayLists(gl, glu, quadric, ptr);

        //Fin

        // Sphere with a texture
        //SHAPE_BILLBOARD = SHAPE_SPHERE32 + 1;
    /*gl.glNewList(SHAPE_BILLBOARD,GL.GL_COMPILE);
        textures[0].bind();
        gl.glBegin(GL.GL_TRIANGLE_STRIP);
        // Map the texture and create the vertices for the particle.
        gl.glTexCoord2d(1, 1);
        gl.glVertex3f(0.5f, 0.5f, 0);
        gl.glTexCoord2d(0, 1);
        gl.glVertex3f(-0.5f, 0.5f,0);
        gl.glTexCoord2d(1, 0);
        gl.glVertex3f(0.5f, -0.5f, 0);
        gl.glTexCoord2d(0, 0);
        gl.glVertex3f(-0.5f,-0.5f, 0);
        gl.glEnd();

        gl.glBindTexture(GL.GL_TEXTURE_2D,0);
        gl.glEndList();*/
        //Fin

        glu.gluDeleteQuadric(quadric);
    }

    public void initObject3dClass() {
        modelClasses = modelClassLibrary.createModelClassesCompatibility(this);
        lodClasses = new CompatibilityModelClass[0];
        selectableClasses = new CompatibilityModelClass[0];
        clickableClasses = new CompatibilityModelClass[0];


        modelClasses[CLASS_NODE].setEnabled(true);
        modelClasses[CLASS_EDGE].setEnabled(vizController.getVizModel().isShowEdges());
        modelClasses[CLASS_ARROW].setEnabled(vizConfig.isShowArrows());
        modelClasses[CLASS_POTATO].setEnabled(vizController.getVizModel().isShowHulls());

        //LOD
        ArrayList<ModelClass> classList = new ArrayList<ModelClass>();
        for (ModelClass objClass : modelClasses) {
            if (objClass.isLod()) {
                classList.add(objClass);
            }
        }
        lodClasses = classList.toArray(lodClasses);

        //Selectable
        classList.clear();
        for (ModelClass objClass : modelClasses) {
            if (objClass.isSelectable()) {
                classList.add(objClass);
            }
        }
        selectableClasses = classList.toArray(selectableClasses);

        //Clickable
        classList.clear();
        for (ModelClass objClass : modelClasses) {
            if (objClass.isClickable()) {
                classList.add(objClass);
            }
        }
        clickableClasses = classList.toArray(clickableClasses);

        //Init selection lists
        selectedObjects = new ConcurrentLinkedQueue[selectableClasses.length];
        int i = 0;
        for (ModelClass objClass : selectableClasses) {
            objClass.setSelectionId(i);
            selectedObjects[i] = new ConcurrentLinkedQueue<ModelImpl>();
            i++;
        }
    }

    @Override
    public void initSelection() {
        if (vizConfig.isCustomSelection()) {
            //System.out.println("CustomSelection");
            rectangleSelection = false;
            currentSelectionArea = null;
        } else if (vizConfig.isRectangleSelection()) {
            currentSelectionArea = new Rectangle();
            rectangleSelection = true;
            customSelection = false;
        } else {
            currentSelectionArea = new Cylinder();
            rectangleSelection = false;
            customSelection = false;
        }
    }

    @Override
    public void startAnimating() {
        if (!scheduler.isAnimating()) {
            //System.out.println("start animating");
            scheduler.start();
            graphIO.startMouseListening();
        }
    }

    @Override
    public void stopAnimating() {
        if (scheduler.isAnimating()) {
            //System.out.println("stop animating");
            scheduler.stop();
            graphIO.stopMouseListening();
        }

    }

    public CompatibilityModelClass[] getModelClasses() {
        return modelClasses;
    }

    public Scheduler getScheduler() {
        return scheduler;
    }
}
TOP

Related Classes of org.gephi.visualization.opengl.compatibility.CompatibilityEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.