fiore@5: /* fiore@5: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool fiore@5: fiore@5: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) fiore@5: fiore@5: This program is free software: you can redistribute it and/or modify fiore@5: it under the terms of the GNU General Public License as published by fiore@5: the Free Software Foundation, either version 3 of the License, or fiore@5: (at your option) any later version. fiore@5: fiore@5: This program is distributed in the hope that it will be useful, fiore@5: but WITHOUT ANY WARRANTY; without even the implied warranty of fiore@5: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the fiore@5: GNU General Public License for more details. fiore@5: fiore@5: You should have received a copy of the GNU General Public License fiore@5: along with this program. If not, see . fiore@5: */ fiore@5: fiore@5: #include "CollectionsManager.h" fiore@5: fiore@5: using namespace H3DUtil::ArithmeticTypes; fiore@5: fiore@5: void CollectionsManager::init(void){ fiore@5: /**************** init jni variables **********************/ fiore@5: // --- classes --- fiore@5: // get the java haptics class fiore@5: hapticClass = env->GetObjectClass(*haptics); fiore@5: if(hapticClass == NULL){ fiore@5: stopExecution("Could not find the Haptics class"); fiore@5: } fiore@5: fiore@5: bitsetClass = env->FindClass("Ljava/util/BitSet;"); fiore@5: if(bitsetClass == NULL) fiore@5: stopExecution("failed to find bitset class"); fiore@5: fiore@5: //get the node list class fiore@5: listClass = env->FindClass("Ljava/util/ArrayList;"); fiore@5: if(listClass == NULL) fiore@5: stopExecution("failed to find list class"); fiore@5: fiore@5: // get the Node class to call the get method on the node list fiore@5: hapticNodeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Node;"); fiore@5: if(hapticNodeClass == NULL){ fiore@5: stopExecution("Could not find the Node class"); fiore@5: } fiore@5: fiore@5: // get the Edge class to call the get method on the edge list fiore@5: hapticEdgeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Edge;"); fiore@5: if(hapticEdgeClass == NULL){ fiore@5: stopExecution("Could not find the Edge class"); fiore@5: } fiore@5: // --- methods --- fiore@5: // "get" method id fiore@5: getMethodId = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;"); fiore@5: if(getMethodId == NULL) fiore@5: stopExecution("Could not retrieve the get method id"); fiore@5: fiore@5: //size method id fiore@5: sizeMethodId = env->GetMethodID(listClass, "size", "()I"); fiore@5: if(sizeMethodId == NULL) fiore@5: stopExecution("failed to get size method id"); fiore@5: fiore@5: //get method of the BitSet class fiore@5: getBitMethodId = env->GetMethodID(bitsetClass, "get","(I)Z"); fiore@5: if(getBitMethodId == NULL) fiore@5: stopExecution("failed to get the get method id of the BitSet class"); fiore@5: fiore@5: // -- field id's -- fiore@5: //retrieve edgeList field id fiore@5: edgeListfieldId = env->GetFieldID(hapticClass,"currentEdges", "Ljava/util/ArrayList;"); fiore@5: if(edgeListfieldId == NULL){ fiore@5: stopExecution("failed to find the edge list field id"); fiore@5: } fiore@5: fiore@5: //retrieve nodeList field id fiore@5: nodeListfieldId = env->GetFieldID(hapticClass,"currentNodes", "Ljava/util/ArrayList;"); fiore@5: if(nodeListfieldId == NULL){ fiore@5: stopExecution("failed to find the node list field id"); fiore@5: } fiore@5: fiore@5: // Node fields id's fiore@5: xFieldId = env->GetFieldID(hapticNodeClass,"x","D"); fiore@5: if(xFieldId == NULL) fiore@5: stopExecution("Could not find the x field ID"); fiore@5: fiore@5: fiore@5: yFieldId = env->GetFieldID(hapticNodeClass,"y","D"); fiore@5: if(yFieldId == NULL) fiore@5: stopExecution("Could not find the y field ID"); fiore@5: fiore@5: nodeHapticIdFieldId = env->GetFieldID(hapticNodeClass, "hapticId", "I"); fiore@5: if(nodeHapticIdFieldId == NULL) fiore@5: stopExecution("Could not find the node hapticId field ID"); fiore@5: fiore@5: nodeDiagramIdFieldId = env->GetFieldID(hapticNodeClass, "diagramId", "I"); fiore@5: if(nodeDiagramIdFieldId == NULL) fiore@5: stopExecution("Could not find the node diagramId field ID"); fiore@5: fiore@5: // Edge field id's fiore@5: // edge.hapticId fiore@5: edgeHapticIdFieldId = env->GetFieldID(hapticEdgeClass, "hapticId", "I"); fiore@5: if(edgeHapticIdFieldId == NULL) fiore@5: stopExecution("Could not find the edge hapticId field ID"); fiore@5: fiore@5: edgeDiagramIdFieldId = env->GetFieldID(hapticEdgeClass, "diagramId", "I"); fiore@5: if(edgeDiagramIdFieldId == NULL) fiore@5: stopExecution("Could not find the edge diagramId field ID"); fiore@5: fiore@5: // stipplePattern fiore@5: stipplePatternfieldId = env->GetFieldID(hapticEdgeClass, "stipplePattern", "I"); fiore@5: if(stipplePatternfieldId == NULL){ fiore@5: stopExecution("Could not find the stipplePattern field ID"); fiore@5: } fiore@5: fiore@5: edgeSizefieldId = env->GetFieldID(hapticEdgeClass, "size", "I"); fiore@5: if(edgeSizefieldId == NULL) fiore@5: stopExecution("Could not find edge size field ID"); fiore@5: fiore@5: edgeXsFieldId = env->GetFieldID(hapticEdgeClass,"xs", "[D"); fiore@5: if(edgeXsFieldId == NULL) fiore@5: stopExecution("Could not find edge xs field ID"); fiore@5: fiore@5: edgeYsFieldId = env->GetFieldID(hapticEdgeClass,"ys", "[D"); fiore@5: if(edgeYsFieldId == NULL) fiore@5: stopExecution("Could not find edge ys field ID"); fiore@5: fiore@5: edgeAdjMatrixFieldId = env->GetFieldID(hapticEdgeClass,"adjMatrix", "[Ljava/util/BitSet;"); fiore@5: if(edgeAdjMatrixFieldId == NULL) fiore@5: stopExecution("Could not find edge adjMatrix field ID"); fiore@5: fiore@5: attractPointXFieldId = env->GetFieldID(hapticEdgeClass, "attractPointX", "D"); fiore@5: if(attractPointXFieldId == NULL) fiore@5: stopExecution("Could not find the edge attractPointX field ID"); fiore@5: fiore@5: attractPointYFieldId = env->GetFieldID(hapticEdgeClass, "attractPointY", "D"); fiore@5: if(attractPointYFieldId == NULL) fiore@5: stopExecution("Could not find the edge attractPointY field ID"); fiore@5: fiore@5: edgeNodeStartFieldId = env->GetFieldID(hapticEdgeClass, "nodeStart", "I"); fiore@5: if(edgeNodeStartFieldId == NULL) fiore@5: stopExecution("Could not find the edge nodeStart field ID"); fiore@5: } fiore@5: fiore@5: const jint CollectionsManager::getNodesNum() { fiore@5: /* to read the node list field into the nodeList variable each time we get the size is * fiore@5: * needed as, when the tab is switched the nodeList variables still points to the previuos * fiore@5: * tab's node list. We do it only here and not in getNodeData because getNodesData * fiore@5: * follows this call before releasing the monitor, therefore data integrity is granted. */ fiore@5: env->DeleteLocalRef(nodeList); fiore@5: nodeList = env->GetObjectField(*haptics, nodeListfieldId); fiore@5: if(nodeList == NULL){ fiore@5: stopExecution("could not get the node list field of Haptic Class"); fiore@5: } fiore@5: jint size = env->CallIntMethod( nodeList, sizeMethodId); fiore@5: checkExceptions(env,"Could not call ArrayList.size()"); fiore@5: return size; fiore@5: } fiore@5: fiore@5: const jint CollectionsManager::getEdgesNum(){ fiore@5: env->DeleteLocalRef(edgeList); fiore@5: edgeList = env->GetObjectField(*haptics, edgeListfieldId); fiore@5: if(edgeList == NULL){ fiore@5: stopExecution("could not get the edge list field of Haptic Class"); fiore@5: } fiore@5: fiore@5: jint size = env->CallIntMethod( edgeList, sizeMethodId); fiore@5: checkExceptions(env, "Could not call ArrayList.size()"); fiore@5: return size; fiore@5: } fiore@5: fiore@5: CollectionsManager::NodeData & CollectionsManager::getNodeData(const int i){ fiore@5: /* get the i-th node */ fiore@5: jobject currentNode = env->CallObjectMethod(nodeList,getMethodId,i); fiore@5: checkExceptions(env,"Could not call ArrayList.size()"); fiore@5: fillupNodeData(nd,currentNode); fiore@5: env->DeleteLocalRef(currentNode); fiore@5: return nd; fiore@5: } fiore@5: fiore@5: CollectionsManager::EdgeData & CollectionsManager::getEdgeData(const int i){ fiore@5: /* first we look for the i-th edge in the Haptics java class. Once we get it, * fiore@5: * we need all the coordinates of the node this edge is connecting, so that we * fiore@5: * can draw it. The edge mantains a list of references to such nodes. */ fiore@5: fiore@5: /* get the i-th edge */ fiore@5: jobject currentEdge = env->CallObjectMethod(edgeList,getMethodId,i); fiore@5: checkExceptions(env, "Could not call ArrayList.get(int) in the haptics edges"); fiore@5: if(currentEdge == NULL) fiore@5: stopExecution("Could not find get current Edge"); fiore@5: jint size = env->GetIntField(currentEdge, edgeSizefieldId); fiore@5: ed.setSize(size); fiore@5: fillupEdgeData(ed,currentEdge); fiore@5: env->DeleteLocalRef(currentEdge); fiore@5: return ed; fiore@5: } fiore@5: fiore@5: void CollectionsManager::fillupNodeData(NodeData & nd, jobject & currentNode){ fiore@5: //reads the fields of the current node fiore@5: nd.x = env->GetDoubleField(currentNode,xFieldId); fiore@5: nd.y = env->GetDoubleField(currentNode,yFieldId); fiore@5: // takes coordinates from the screen. Needs to convert the y axis as in openGL (0,0) = bottom left corner fiore@5: Vec3d & glCoordinatePosition = screenToHapticSpace(Vec3d(nd.x, nd.y, 0),screenWidth,screenHeight); fiore@5: nd.x = glCoordinatePosition[0]; fiore@5: nd.y = glCoordinatePosition[1]; fiore@5: nd.hapticId = env->GetIntField(currentNode, nodeHapticIdFieldId); fiore@5: nd.diagramId = env->GetIntField(currentNode, nodeDiagramIdFieldId); fiore@5: } fiore@5: fiore@5: void CollectionsManager::fillupEdgeData(EdgeData & ed, jobject & currentEdge){ fiore@5: /* get the array of x coordinates */ fiore@5: jobject xsAsObj = env->GetObjectField(currentEdge,edgeXsFieldId); fiore@5: if(xsAsObj == NULL) fiore@5: stopExecution("Cannot get the xs field"); fiore@5: jdoubleArray *jxs = reinterpret_cast(&xsAsObj); fiore@5: double * xs = env->GetDoubleArrayElements(*jxs, NULL); fiore@5: if(xs == NULL) fiore@5: stopExecution("Cannot get the xs field array of double"); fiore@5: fiore@5: /* get the array of y coordinates */ fiore@5: jobject ysAsObj = env->GetObjectField(currentEdge,edgeYsFieldId); fiore@5: if(ysAsObj == NULL) fiore@5: stopExecution("Cannot get the xs field"); fiore@5: fiore@5: jdoubleArray *jys = reinterpret_cast(&ysAsObj); fiore@5: double * ys = env->GetDoubleArrayElements(*jys, NULL); fiore@5: if(ys == NULL) fiore@5: stopExecution("Cannot get the ys field array of double"); fiore@5: // copy the data into the edgeData object fiore@5: for(unsigned int i=0; iReleaseDoubleArrayElements(*jxs, xs, 0); fiore@5: env->ReleaseDoubleArrayElements(*jys, ys, 0); fiore@5: env->DeleteLocalRef(xsAsObj); fiore@5: env->DeleteLocalRef(ysAsObj); fiore@5: jobject adjMatrixAsObj = env->GetObjectField(currentEdge, edgeAdjMatrixFieldId); fiore@5: if(adjMatrixAsObj == NULL) fiore@5: stopExecution("Cannot get the adjMatrix field"); fiore@5: jobjectArray *jadjMatrix = reinterpret_cast(&adjMatrixAsObj); fiore@5: fiore@5: for(unsigned int i=0; iGetObjectArrayElement(*jadjMatrix,i); fiore@5: if(adjMatrixBitSet == NULL) fiore@5: stopExecution("Cannot get the adjMatrix field array element"); fiore@5: for(unsigned int j=0;jCallBooleanMethod(adjMatrixBitSet,getBitMethodId,j); fiore@5: checkExceptions(env,"Could not call BitSet.get()"); fiore@5: if(b == JNI_TRUE) fiore@5: ed.adjMatrix[i][j] = true; fiore@5: else fiore@5: ed.adjMatrix[i][j] = false; fiore@5: } fiore@5: env->DeleteLocalRef(adjMatrixBitSet); fiore@5: } fiore@5: env->DeleteLocalRef(adjMatrixAsObj); fiore@5: fiore@5: // set the haptic id used by the haptic device fiore@5: ed.hapticId = env->GetIntField(currentEdge, edgeHapticIdFieldId); fiore@5: // set the diagram id used in the java thread fiore@5: ed.diagramId = env->GetIntField(currentEdge, edgeDiagramIdFieldId); fiore@5: // set the stipple pattern fiore@5: ed.stipplePattern = env->GetIntField(currentEdge, stipplePatternfieldId); fiore@5: // set the attract point fiore@5: ed.attractPoint[0] = env->GetDoubleField(currentEdge, attractPointXFieldId); fiore@5: ed.attractPoint[1] = env->GetDoubleField(currentEdge, attractPointYFieldId); fiore@5: Vec3d & glCoordinatePosition = screenToHapticSpace(Vec3d(ed.attractPoint[0], ed.attractPoint[1], 0),screenWidth,screenHeight); fiore@5: ed.attractPoint[0] = glCoordinatePosition[0]; fiore@5: ed.attractPoint[1] = glCoordinatePosition[1]; fiore@5: //set the index from which the nodes start in the adjMatrix fiore@5: ed.nodeStart = env->GetIntField(currentEdge, edgeNodeStartFieldId); fiore@5: }