annotate native/Falcon/CollectionsManager.cpp @ 8:ea7885bd9bff tip

fixed bug : render solid line as dotted/dashed when moving the stylus from dotted/dashed to solid
author ccmi-guest
date Thu, 03 Jul 2014 16:12:20 +0100
parents d66dd5880081
children
rev   line source
fiore@5 1 /*
fiore@5 2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
fiore@5 3
fiore@5 4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
fiore@5 5
fiore@5 6 This program is free software: you can redistribute it and/or modify
fiore@5 7 it under the terms of the GNU General Public License as published by
fiore@5 8 the Free Software Foundation, either version 3 of the License, or
fiore@5 9 (at your option) any later version.
fiore@5 10
fiore@5 11 This program is distributed in the hope that it will be useful,
fiore@5 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
fiore@5 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fiore@5 14 GNU General Public License for more details.
fiore@5 15
fiore@5 16 You should have received a copy of the GNU General Public License
fiore@5 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
fiore@5 18 */
fiore@5 19
fiore@5 20 #include "CollectionsManager.h"
fiore@5 21
fiore@5 22 using namespace H3DUtil::ArithmeticTypes;
fiore@5 23
fiore@5 24 void CollectionsManager::init(void){
fiore@5 25 /**************** init jni variables **********************/
fiore@5 26 // --- classes ---
fiore@5 27 // get the java haptics class
fiore@5 28 hapticClass = env->GetObjectClass(*haptics);
fiore@5 29 if(hapticClass == NULL){
fiore@5 30 stopExecution("Could not find the Haptics class");
fiore@5 31 }
fiore@5 32
fiore@5 33 bitsetClass = env->FindClass("Ljava/util/BitSet;");
fiore@5 34 if(bitsetClass == NULL)
fiore@5 35 stopExecution("failed to find bitset class");
fiore@5 36
fiore@5 37 //get the node list class
fiore@5 38 listClass = env->FindClass("Ljava/util/ArrayList;");
fiore@5 39 if(listClass == NULL)
fiore@5 40 stopExecution("failed to find list class");
fiore@5 41
fiore@5 42 // get the Node class to call the get method on the node list
fiore@5 43 hapticNodeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Node;");
fiore@5 44 if(hapticNodeClass == NULL){
fiore@5 45 stopExecution("Could not find the Node class");
fiore@5 46 }
fiore@5 47
fiore@5 48 // get the Edge class to call the get method on the edge list
fiore@5 49 hapticEdgeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Edge;");
fiore@5 50 if(hapticEdgeClass == NULL){
fiore@5 51 stopExecution("Could not find the Edge class");
fiore@5 52 }
fiore@5 53 // --- methods ---
fiore@5 54 // "get" method id
fiore@5 55 getMethodId = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;");
fiore@5 56 if(getMethodId == NULL)
fiore@5 57 stopExecution("Could not retrieve the get method id");
fiore@5 58
fiore@5 59 //size method id
fiore@5 60 sizeMethodId = env->GetMethodID(listClass, "size", "()I");
fiore@5 61 if(sizeMethodId == NULL)
fiore@5 62 stopExecution("failed to get size method id");
fiore@5 63
fiore@5 64 //get method of the BitSet class
fiore@5 65 getBitMethodId = env->GetMethodID(bitsetClass, "get","(I)Z");
fiore@5 66 if(getBitMethodId == NULL)
fiore@5 67 stopExecution("failed to get the get method id of the BitSet class");
fiore@5 68
fiore@5 69 // -- field id's --
fiore@5 70 //retrieve edgeList field id
fiore@5 71 edgeListfieldId = env->GetFieldID(hapticClass,"currentEdges", "Ljava/util/ArrayList;");
fiore@5 72 if(edgeListfieldId == NULL){
fiore@5 73 stopExecution("failed to find the edge list field id");
fiore@5 74 }
fiore@5 75
fiore@5 76 //retrieve nodeList field id
fiore@5 77 nodeListfieldId = env->GetFieldID(hapticClass,"currentNodes", "Ljava/util/ArrayList;");
fiore@5 78 if(nodeListfieldId == NULL){
fiore@5 79 stopExecution("failed to find the node list field id");
fiore@5 80 }
fiore@5 81
fiore@5 82 // Node fields id's
fiore@5 83 xFieldId = env->GetFieldID(hapticNodeClass,"x","D");
fiore@5 84 if(xFieldId == NULL)
fiore@5 85 stopExecution("Could not find the x field ID");
fiore@5 86
fiore@5 87
fiore@5 88 yFieldId = env->GetFieldID(hapticNodeClass,"y","D");
fiore@5 89 if(yFieldId == NULL)
fiore@5 90 stopExecution("Could not find the y field ID");
fiore@5 91
fiore@5 92 nodeHapticIdFieldId = env->GetFieldID(hapticNodeClass, "hapticId", "I");
fiore@5 93 if(nodeHapticIdFieldId == NULL)
fiore@5 94 stopExecution("Could not find the node hapticId field ID");
fiore@5 95
fiore@5 96 nodeDiagramIdFieldId = env->GetFieldID(hapticNodeClass, "diagramId", "I");
fiore@5 97 if(nodeDiagramIdFieldId == NULL)
fiore@5 98 stopExecution("Could not find the node diagramId field ID");
fiore@5 99
fiore@5 100 // Edge field id's
fiore@5 101 // edge.hapticId
fiore@5 102 edgeHapticIdFieldId = env->GetFieldID(hapticEdgeClass, "hapticId", "I");
fiore@5 103 if(edgeHapticIdFieldId == NULL)
fiore@5 104 stopExecution("Could not find the edge hapticId field ID");
fiore@5 105
fiore@5 106 edgeDiagramIdFieldId = env->GetFieldID(hapticEdgeClass, "diagramId", "I");
fiore@5 107 if(edgeDiagramIdFieldId == NULL)
fiore@5 108 stopExecution("Could not find the edge diagramId field ID");
fiore@5 109
fiore@5 110 // stipplePattern
fiore@5 111 stipplePatternfieldId = env->GetFieldID(hapticEdgeClass, "stipplePattern", "I");
fiore@5 112 if(stipplePatternfieldId == NULL){
fiore@5 113 stopExecution("Could not find the stipplePattern field ID");
fiore@5 114 }
fiore@5 115
fiore@5 116 edgeSizefieldId = env->GetFieldID(hapticEdgeClass, "size", "I");
fiore@5 117 if(edgeSizefieldId == NULL)
fiore@5 118 stopExecution("Could not find edge size field ID");
fiore@5 119
fiore@5 120 edgeXsFieldId = env->GetFieldID(hapticEdgeClass,"xs", "[D");
fiore@5 121 if(edgeXsFieldId == NULL)
fiore@5 122 stopExecution("Could not find edge xs field ID");
fiore@5 123
fiore@5 124 edgeYsFieldId = env->GetFieldID(hapticEdgeClass,"ys", "[D");
fiore@5 125 if(edgeYsFieldId == NULL)
fiore@5 126 stopExecution("Could not find edge ys field ID");
fiore@5 127
fiore@5 128 edgeAdjMatrixFieldId = env->GetFieldID(hapticEdgeClass,"adjMatrix", "[Ljava/util/BitSet;");
fiore@5 129 if(edgeAdjMatrixFieldId == NULL)
fiore@5 130 stopExecution("Could not find edge adjMatrix field ID");
fiore@5 131
fiore@5 132 attractPointXFieldId = env->GetFieldID(hapticEdgeClass, "attractPointX", "D");
fiore@5 133 if(attractPointXFieldId == NULL)
fiore@5 134 stopExecution("Could not find the edge attractPointX field ID");
fiore@5 135
fiore@5 136 attractPointYFieldId = env->GetFieldID(hapticEdgeClass, "attractPointY", "D");
fiore@5 137 if(attractPointYFieldId == NULL)
fiore@5 138 stopExecution("Could not find the edge attractPointY field ID");
fiore@5 139
fiore@5 140 edgeNodeStartFieldId = env->GetFieldID(hapticEdgeClass, "nodeStart", "I");
fiore@5 141 if(edgeNodeStartFieldId == NULL)
fiore@5 142 stopExecution("Could not find the edge nodeStart field ID");
fiore@5 143 }
fiore@5 144
fiore@5 145 const jint CollectionsManager::getNodesNum() {
fiore@5 146 /* to read the node list field into the nodeList variable each time we get the size is *
fiore@5 147 * needed as, when the tab is switched the nodeList variables still points to the previuos *
fiore@5 148 * tab's node list. We do it only here and not in getNodeData because getNodesData *
fiore@5 149 * follows this call before releasing the monitor, therefore data integrity is granted. */
fiore@5 150 env->DeleteLocalRef(nodeList);
fiore@5 151 nodeList = env->GetObjectField(*haptics, nodeListfieldId);
fiore@5 152 if(nodeList == NULL){
fiore@5 153 stopExecution("could not get the node list field of Haptic Class");
fiore@5 154 }
fiore@5 155 jint size = env->CallIntMethod( nodeList, sizeMethodId);
fiore@5 156 checkExceptions(env,"Could not call ArrayList<Node>.size()");
fiore@5 157 return size;
fiore@5 158 }
fiore@5 159
fiore@5 160 const jint CollectionsManager::getEdgesNum(){
fiore@5 161 env->DeleteLocalRef(edgeList);
fiore@5 162 edgeList = env->GetObjectField(*haptics, edgeListfieldId);
fiore@5 163 if(edgeList == NULL){
fiore@5 164 stopExecution("could not get the edge list field of Haptic Class");
fiore@5 165 }
fiore@5 166
fiore@5 167 jint size = env->CallIntMethod( edgeList, sizeMethodId);
fiore@5 168 checkExceptions(env, "Could not call ArrayList<Edge>.size()");
fiore@5 169 return size;
fiore@5 170 }
fiore@5 171
fiore@5 172 CollectionsManager::NodeData & CollectionsManager::getNodeData(const int i){
fiore@5 173 /* get the i-th node */
fiore@5 174 jobject currentNode = env->CallObjectMethod(nodeList,getMethodId,i);
fiore@5 175 checkExceptions(env,"Could not call ArrayList<Node>.size()");
fiore@5 176 fillupNodeData(nd,currentNode);
fiore@5 177 env->DeleteLocalRef(currentNode);
fiore@5 178 return nd;
fiore@5 179 }
fiore@5 180
fiore@5 181 CollectionsManager::EdgeData & CollectionsManager::getEdgeData(const int i){
fiore@5 182 /* first we look for the i-th edge in the Haptics java class. Once we get it, *
fiore@5 183 * we need all the coordinates of the node this edge is connecting, so that we *
fiore@5 184 * can draw it. The edge mantains a list of references to such nodes. */
fiore@5 185
fiore@5 186 /* get the i-th edge */
fiore@5 187 jobject currentEdge = env->CallObjectMethod(edgeList,getMethodId,i);
fiore@5 188 checkExceptions(env, "Could not call ArrayList<Edge>.get(int) in the haptics edges");
fiore@5 189 if(currentEdge == NULL)
fiore@5 190 stopExecution("Could not find get current Edge");
fiore@5 191 jint size = env->GetIntField(currentEdge, edgeSizefieldId);
fiore@5 192 ed.setSize(size);
fiore@5 193 fillupEdgeData(ed,currentEdge);
fiore@5 194 env->DeleteLocalRef(currentEdge);
fiore@5 195 return ed;
fiore@5 196 }
fiore@5 197
fiore@5 198 void CollectionsManager::fillupNodeData(NodeData & nd, jobject & currentNode){
fiore@5 199 //reads the fields of the current node
fiore@5 200 nd.x = env->GetDoubleField(currentNode,xFieldId);
fiore@5 201 nd.y = env->GetDoubleField(currentNode,yFieldId);
fiore@5 202 // takes coordinates from the screen. Needs to convert the y axis as in openGL (0,0) = bottom left corner
fiore@5 203 Vec3d & glCoordinatePosition = screenToHapticSpace(Vec3d(nd.x, nd.y, 0),screenWidth,screenHeight);
fiore@5 204 nd.x = glCoordinatePosition[0];
fiore@5 205 nd.y = glCoordinatePosition[1];
fiore@5 206 nd.hapticId = env->GetIntField(currentNode, nodeHapticIdFieldId);
fiore@5 207 nd.diagramId = env->GetIntField(currentNode, nodeDiagramIdFieldId);
fiore@5 208 }
fiore@5 209
fiore@5 210 void CollectionsManager::fillupEdgeData(EdgeData & ed, jobject & currentEdge){
fiore@5 211 /* get the array of x coordinates */
fiore@5 212 jobject xsAsObj = env->GetObjectField(currentEdge,edgeXsFieldId);
fiore@5 213 if(xsAsObj == NULL)
fiore@5 214 stopExecution("Cannot get the xs field");
fiore@5 215 jdoubleArray *jxs = reinterpret_cast<jdoubleArray*>(&xsAsObj);
fiore@5 216 double * xs = env->GetDoubleArrayElements(*jxs, NULL);
fiore@5 217 if(xs == NULL)
fiore@5 218 stopExecution("Cannot get the xs field array of double");
fiore@5 219
fiore@5 220 /* get the array of y coordinates */
fiore@5 221 jobject ysAsObj = env->GetObjectField(currentEdge,edgeYsFieldId);
fiore@5 222 if(ysAsObj == NULL)
fiore@5 223 stopExecution("Cannot get the xs field");
fiore@5 224
fiore@5 225 jdoubleArray *jys = reinterpret_cast<jdoubleArray*>(&ysAsObj);
fiore@5 226 double * ys = env->GetDoubleArrayElements(*jys, NULL);
fiore@5 227 if(ys == NULL)
fiore@5 228 stopExecution("Cannot get the ys field array of double");
fiore@5 229 // copy the data into the edgeData object
fiore@5 230 for(unsigned int i=0; i<ed.getSize(); i++){
fiore@5 231 ed.x[i] = xs[i];
fiore@5 232 ed.y[i] = ys[i];
fiore@5 233 // takes coordinates from the screen (needs to convert the y axis as in openGL 0 = bottom left corner
fiore@5 234 Vec3d & glCoordinatePosition = screenToHapticSpace(Vec3d(ed.x[i], ed.y[i], 0),screenWidth,screenHeight);
fiore@5 235 ed.x[i] = glCoordinatePosition[0];
fiore@5 236 ed.y[i] = glCoordinatePosition[1];
fiore@5 237 }
fiore@5 238 env->ReleaseDoubleArrayElements(*jxs, xs, 0);
fiore@5 239 env->ReleaseDoubleArrayElements(*jys, ys, 0);
fiore@5 240 env->DeleteLocalRef(xsAsObj);
fiore@5 241 env->DeleteLocalRef(ysAsObj);
fiore@5 242 jobject adjMatrixAsObj = env->GetObjectField(currentEdge, edgeAdjMatrixFieldId);
fiore@5 243 if(adjMatrixAsObj == NULL)
fiore@5 244 stopExecution("Cannot get the adjMatrix field");
fiore@5 245 jobjectArray *jadjMatrix = reinterpret_cast<jobjectArray*>(&adjMatrixAsObj);
fiore@5 246
fiore@5 247 for(unsigned int i=0; i<ed.getSize(); i++){
fiore@5 248 jobject adjMatrixBitSet = env->GetObjectArrayElement(*jadjMatrix,i);
fiore@5 249 if(adjMatrixBitSet == NULL)
fiore@5 250 stopExecution("Cannot get the adjMatrix field array element");
fiore@5 251 for(unsigned int j=0;j<ed.getSize(); j++){
fiore@5 252 jboolean b = env->CallBooleanMethod(adjMatrixBitSet,getBitMethodId,j);
fiore@5 253 checkExceptions(env,"Could not call BitSet.get()");
fiore@5 254 if(b == JNI_TRUE)
fiore@5 255 ed.adjMatrix[i][j] = true;
fiore@5 256 else
fiore@5 257 ed.adjMatrix[i][j] = false;
fiore@5 258 }
fiore@5 259 env->DeleteLocalRef(adjMatrixBitSet);
fiore@5 260 }
fiore@5 261 env->DeleteLocalRef(adjMatrixAsObj);
fiore@5 262
fiore@5 263 // set the haptic id used by the haptic device
fiore@5 264 ed.hapticId = env->GetIntField(currentEdge, edgeHapticIdFieldId);
fiore@5 265 // set the diagram id used in the java thread
fiore@5 266 ed.diagramId = env->GetIntField(currentEdge, edgeDiagramIdFieldId);
fiore@5 267 // set the stipple pattern
fiore@5 268 ed.stipplePattern = env->GetIntField(currentEdge, stipplePatternfieldId);
fiore@5 269 // set the attract point
fiore@5 270 ed.attractPoint[0] = env->GetDoubleField(currentEdge, attractPointXFieldId);
fiore@5 271 ed.attractPoint[1] = env->GetDoubleField(currentEdge, attractPointYFieldId);
fiore@5 272 Vec3d & glCoordinatePosition = screenToHapticSpace(Vec3d(ed.attractPoint[0], ed.attractPoint[1], 0),screenWidth,screenHeight);
fiore@5 273 ed.attractPoint[0] = glCoordinatePosition[0];
fiore@5 274 ed.attractPoint[1] = glCoordinatePosition[1];
fiore@5 275 //set the index from which the nodes start in the adjMatrix
fiore@5 276 ed.nodeStart = env->GetIntField(currentEdge, edgeNodeStartFieldId);
fiore@5 277 }