diff --git a/Gui/opensim/view/src/org/opensim/threejs/ExportSceneToThreeJsAction.java b/Gui/opensim/view/src/org/opensim/threejs/ExportSceneToThreeJsAction.java index 7e764882c..5b2008b4f 100644 --- a/Gui/opensim/view/src/org/opensim/threejs/ExportSceneToThreeJsAction.java +++ b/Gui/opensim/view/src/org/opensim/threejs/ExportSceneToThreeJsAction.java @@ -20,6 +20,7 @@ import org.opensim.modeling.Model; import org.opensim.view.pub.OpenSimDB; import org.opensim.utils.FileUtils; +import org.opensim.view.pub.ViewDB; @ActionID( category = "File", @@ -29,34 +30,33 @@ displayName = "#CTL_ExportSceneToThreeJsAction" ) @ActionReference(path = "Menu/File", position = 1429) -@Messages("CTL_ExportSceneToThreeJsAction=Export model to json") +@Messages("CTL_ExportSceneToThreeJsAction=Export all models to json format") public final class ExportSceneToThreeJsAction implements ActionListener { @Override public void actionPerformed(ActionEvent e) { Model model = OpenSimDB.getInstance().getCurrentModel(); + if (model == null) return; // Nothing to export String fileName = FileUtils.getInstance().browseForFilenameToSave( FileUtils.getFileFilter(".json", "Threejs scene file"), true, model.getInputFileName().replace(".osim", ".json")); - exportCurrentModelToJson(fileName, model); + exportAllModelsToJson(fileName); } - public static VisualizationJson exportCurrentModelToJson(String fileName, Model model) { + public static ModelVisualizationJson exportAllModelsToJson(String fileName) { BufferedWriter out = null; - VisualizationJson vizJson = null; + ModelVisualizationJson vizJson = null; try { - + JSONObject jsonTop = ViewDB.getInstance().getJsondb(); + int numModels = OpenSimDB.getInstance().getNumModels(); // Create Json rep for model - vizJson = new VisualizationJson(model); - JSONObject jsonTop = vizJson.getJson(); - StringWriter outString = new JSONWriter(); - jsonTop.writeJSONString(outString); - String jsonText = outString.toString(); - out = new BufferedWriter(new FileWriter(fileName, false)); - out.write(jsonText); - out.flush(); - out.close(); + for (int i=0; i mapBodyIndicesToFrames = new HashMap(); private final HashMap mapBodyIndicesToJson = new HashMap(); private final static double visScaleFactor = 1000.0; @@ -59,39 +55,41 @@ public class VisualizationJson { private ModelDisplayHints mdh; private DecorativeGeometryImplementationJS dgimp = null; private static String boneSuffix = "_Bone"; + private JSONArray json_geometries; + private JSONArray json_materials; + private JSONObject model_object; + private UUID modelUUID; - public VisualizationJson(Model model) { - topJson = createJsonForModel(model); + public ModelVisualizationJson(JSONObject jsonTopIn, Model model) { + // implicit super() + createModelJsonNode(); // Model node + createJsonForModel(model); } - private JSONObject createJsonForModel(Model model) { + private void createJsonForModel(Model model) { state = model.getWorkingState(); mdh = model.getDisplayHints(); ComponentsList mcList = model.getComponentsList(); muscleList = model.getMuscleList(); ComponentIterator mcIter = mcList.begin(); - // Load template - JSONObject jsonTop = createTopLevelJson(model); + BodyList bodies = model.getBodyList(); BodyIterator body = bodies.begin(); mapBodyIndicesToFrames.put(0, model.getGround()); - JSONArray json_geometries = (JSONArray) jsonTop.get("geometries"); - JSONArray json_materials = (JSONArray) jsonTop.get("materials"); - JSONObject sceneObject = (JSONObject) jsonTop.get("object"); - JSONArray json_scene_children = (JSONArray) sceneObject.get("children"); + JSONArray json_model_children = (JSONArray) ((JSONObject) get("object")).get("children"); - JSONObject model_json = new JSONObject(); - json_scene_children.add(model_json); + JSONObject model_ground_json = new JSONObject(); // create model node - model_json.put("uuid", UUID.randomUUID().toString()); - model_json.put("type", "Group"); - model_json.put("opensimtype", "Frame"); - model_json.put("name", model.getGround().getAbsolutePathName()); - model_json.put("model_ground", true); + model_ground_json.put("uuid", UUID.randomUUID().toString()); + model_ground_json.put("type", "Group"); + model_ground_json.put("opensimtype", "Frame"); + model_ground_json.put("name", model.getGround().getAbsolutePathName()); + model_ground_json.put("model_ground", true); + json_model_children.add(model_ground_json); //System.out.println(model_json.toJSONString()); JSONArray bodies_json = new JSONArray(); - model_json.put("children", bodies_json); - mapBodyIndicesToJson.put(0, model_json); + model_ground_json.put("children", bodies_json); + mapBodyIndicesToJson.put(0, model_ground_json); while (!body.equals(bodies.end())) { int id = body.getMobilizedBodyIndex(); mapBodyIndicesToFrames.put(id, body.__deref__()); @@ -124,7 +122,6 @@ private JSONObject createJsonForModel(Model model) { } mcIter.next(); } - return jsonTop; } private void processDecorativeGeometry(ArrayDecorativeGeometry adg, Component comp, @@ -162,23 +159,21 @@ private void processDecorativeGeometry(ArrayDecorativeGeometry adg, Component co } - private JSONObject createTopLevelJson(Model model) { - JSONObject topLevelJson = new JSONObject(); - JSONObject modelJson = new JSONObject(); - createOneModelJson(modelJson, model); - topLevelJson.put("object", modelJson); - topLevelJson.put("geometries", new JSONArray()); - topLevelJson.put("materials", new JSONArray()); - return topLevelJson; - } + private void createModelJsonNode() { + modelUUID = UUID.randomUUID(); + model_object = new JSONObject(); + model_object.put("uuid", modelUUID.toString()); + model_object.put("type", "Group"); + model_object.put("opensimtype", "Model"); + model_object.put("name", "OpenSimModel"); + model_object.put("children", new JSONArray()); + model_object.put("matrix", JSONUtilities.createMatrixFromTransform(new Transform(), new Vec3(1.), 1.0)); + put("object", model_object); + json_geometries = new JSONArray(); + put("geometries", json_geometries); + json_materials = new JSONArray(); + put("materials", json_materials); - private void createOneModelJson(JSONObject modelJson, Model model) { - modelJson.put("uuid", UUID.randomUUID().toString()); - modelJson.put("type", "Model"); - modelJson.put("opensimtype", "Model"); - modelJson.put("name", "OpenSimModel"); - modelJson.put("matrix", JSONUtilities.createMatrixFromTransform(new Transform(), new Vec3(1.), 1.0)); - modelJson.put("children", new JSONArray()); } private UUID addtoFrameJsonObject(DecorativeGeometry dg, String geomName, UUID uuid, UUID uuid_mat, JSONArray mobody_objects) { @@ -193,15 +188,7 @@ private UUID addtoFrameJsonObject(DecorativeGeometry dg, String geomName, UUID u obj_json.put("castShadow", false); mobody_objects.add(obj_json); return mesh_uuid; - } - - - /** - * @return the topJson - */ - public JSONObject getJson() { - return topJson; - } + } private JSONObject createBodyJson(Body body){ JSONObject bdyJson = new JSONObject(); @@ -285,12 +272,18 @@ public static double getVisScaleFactor() { return visScaleFactor; } - public JSONObject createCloseModelJson(Model model) { + public JSONObject createCloseModelJson() { + JSONObject guiJson = new JSONObject(); + guiJson.put("UUID", modelUUID.toString()); + guiJson.put("Op", "CloseModel"); + return guiJson; + } + + + public JSONObject createOpenModelJson() { JSONObject guiJson = new JSONObject(); - /* - UUID obj_uuid = findUUIDForObject(model); - guiJson.put("UUID", obj_uuid.toString()); - guiJson.put("Op", "CloseModel"); */ + guiJson.put("UUID", modelUUID.toString()); + guiJson.put("Op", "OpenModel"); return guiJson; } @@ -427,4 +420,18 @@ private UUID addPathPointGeometryToParent(PathPoint pathPoint, JSONArray json_ge children.add(bpptInBodyJson); return ppoint_uuid; } + + /** + * @return the modelUUID + */ + public UUID getModelUUID() { + return modelUUID; + } + + public JSONObject createSetCurrentModelJson() { + JSONObject guiJson = new JSONObject(); + guiJson.put("UUID", modelUUID.toString()); + guiJson.put("Op", "SetCurrentModel"); + return guiJson; + } } diff --git a/Gui/opensim/view/src/org/opensim/threejs/VisualizerWindowAction.java b/Gui/opensim/view/src/org/opensim/threejs/VisualizerWindowAction.java index 8f36c833a..81a99432e 100644 --- a/Gui/opensim/view/src/org/opensim/threejs/VisualizerWindowAction.java +++ b/Gui/opensim/view/src/org/opensim/threejs/VisualizerWindowAction.java @@ -30,11 +30,13 @@ public final class VisualizerWindowAction implements ActionListener { @Override public void actionPerformed(ActionEvent e) { - // launch server and open page in fixed location to be used as a view - - VisualizationJson json = ExportSceneToThreeJsAction.exportCurrentModelToJson(JettyMain.getServerRootDir()+"/threejs/editor/model.json", OpenSimDB.getInstance().getCurrentModel()); - ViewDB.getInstance().startVisualizationServer(); - BrowserLauncher.openURL("http://localhost:"+JettyMain.getServerPort()+JettyMain.getPathToStartPage()+"index.html"); - ViewDB.getInstance().setJson(json); + // launch server and open page in fixed location to be used as a view + openVisualizerWindow(); } + + public static void openVisualizerWindow() { + ViewDB.getInstance().startVisualizationServer(); + BrowserLauncher.openURL("http://localhost:"+JettyMain.getServerPort()+JettyMain.getPathToStartPage()+"index.html"); + } + } diff --git a/Gui/opensim/view/src/org/opensim/view/pub/OpenSimDB.java b/Gui/opensim/view/src/org/opensim/view/pub/OpenSimDB.java index 136df7bc5..edcb82a40 100644 --- a/Gui/opensim/view/src/org/opensim/view/pub/OpenSimDB.java +++ b/Gui/opensim/view/src/org/opensim/view/pub/OpenSimDB.java @@ -102,6 +102,10 @@ else if (currentCloseModelDefaultAction ==CloseModelDefaultAction.SAVE) closeAction="save"; Preferences.userNodeForPackage(TheApp.class).put("DefaultCloseAction", closeAction); } + + public Model getModelByIndex(int i) { + return models.get(i); + } public enum CloseModelDefaultAction { SAVE, DISCARD, diff --git a/Gui/opensim/view/src/org/opensim/view/pub/ViewDB.java b/Gui/opensim/view/src/org/opensim/view/pub/ViewDB.java index a26ae40c7..b188b0585 100644 --- a/Gui/opensim/view/src/org/opensim/view/pub/ViewDB.java +++ b/Gui/opensim/view/src/org/opensim/view/pub/ViewDB.java @@ -28,6 +28,7 @@ */ package org.opensim.view.pub; +import java.io.IOException; import java.text.NumberFormat; import java.text.ParseException; import java.util.ArrayList; @@ -38,6 +39,7 @@ import java.util.Observable; import java.util.Observer; import java.util.Set; +import java.util.UUID; import java.util.Vector; import java.util.prefs.Preferences; import javax.swing.SwingUtilities; @@ -45,9 +47,11 @@ import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import org.eclipse.jetty.JettyMain; +import org.eclipse.jetty.VisWebSocket; import org.eclipse.jetty.WebSocketDB; import org.json.simple.JSONObject; import org.openide.awt.StatusDisplayer; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.LookupEvent; import org.openide.util.LookupListener; @@ -57,12 +61,16 @@ import org.opensim.modeling.*; import org.opensim.view.experimentaldata.ModelForExperimentalData; import org.opensim.swingui.SwingWorker; +import org.opensim.threejs.ExportSceneToThreeJsAction; import org.opensim.threejs.JSONMessageHandler; -import org.opensim.threejs.VisualizationJson; +import org.opensim.threejs.JSONUtilities; +import org.opensim.threejs.ModelVisualizationJson; +import org.opensim.threejs.VisualizerWindowAction; import org.opensim.utils.Prefs; import org.opensim.utils.TheApp; import org.opensim.view.*; import org.opensim.view.experimentaldata.ExperimentalDataVisuals; +import static org.opensim.view.pub.ViewDB.isVtkGraphicsAvailable; import vtk.AxesActor; import vtk.FrameActor; import vtk.vtkActor; @@ -99,6 +107,7 @@ public final class ViewDB extends Observable implements Observer, LookupListener // One single vtAssemby for the whole Scene private static vtkAssembly sceneAssembly; private static WebSocketDB websocketdb; + private static JSONObject jsondb; /** * @return the myLookup */ @@ -106,10 +115,20 @@ public static Lookup getLookup() { return myLookup; } + /** + * @return the jsondb + */ + public static JSONObject getJsondb() { + return jsondb; + } + // Map models to visuals private Hashtable mapModelsToVisuals = new Hashtable(); + private Hashtable mapModelsToJsons = + new Hashtable(); + private Hashtable mapModelsToSettings = new Hashtable(); private Hashtable modelOpacities = new Hashtable(); @@ -145,11 +164,12 @@ public static Lookup getLookup() { private final static Lookup myLookup = new AbstractLookup (lookupContents); Lookup.Result r; - private VisualizationJson visJson; + private ModelVisualizationJson currentJson; /** Creates a new instance of ViewDB */ private ViewDB() { applyPreferences(); r = myLookup.lookupResult(OpenSimObject.class); + jsondb = JSONUtilities.createTopLevelJson(); } public void applyPreferences() { @@ -205,10 +225,15 @@ public static void setCurrentModelWindow(ModelWindowVTKTopComponent aCurrentMode * Observable should be of type OpenSimDB. */ public void update(Observable o, Object arg) { - if (!isGraphicsAvailable()) return; + //if (!isVtkGraphicsAvailable()) return; if (arg instanceof JSONObject){ handleJson((JSONObject) arg); } + if (o instanceof VisWebSocket){ + // Sync. socket with current ViweDB + getInstance().sync((VisWebSocket) o); + return; + } if (o instanceof OpenSimDB){ if (arg instanceof ObjectsAddedEvent) { ObjectsAddedEvent ev = (ObjectsAddedEvent)arg; @@ -249,6 +274,7 @@ public void update(Observable o, Object arg) { vis.setPickable(false); } } + setCurrentJson(); break; } } @@ -285,27 +311,37 @@ public void update(Observable o, Object arg) { } catch(UnsatisfiedLinkError e){ setGraphicsAvailable(false); - return; } - // Create visuals for the model - SingleModelVisuals newModelVisual = (model instanceof ModelForExperimentalData)? - new ExperimentalDataVisuals(model): - new SingleModelVisuals(model); - // add to map from models to modelVisuals so that it's accesisble - // thru tree picks - mapModelsToVisuals.put(model, newModelVisual); - // add to list of models - getModelVisuals().add(newModelVisual); //Too late?? - modelOpacities.put(model, 1.0); - addVisObjectToAllViews(); - // Compute placement so that model does not intersect others - vtkMatrix4x4 m= (model instanceof ModelForExperimentalData)? - new vtkMatrix4x4(): - getInitialTransform(newModelVisual); - newModelVisual.getModelDisplayAssembly().SetUserMatrix(m); - - sceneAssembly.AddPart(newModelVisual.getModelDisplayAssembly()); - + if (isVtkGraphicsAvailable()){ + // Create visuals for the model + SingleModelVisuals newModelVisual = (model instanceof ModelForExperimentalData)? + new ExperimentalDataVisuals(model): + new SingleModelVisuals(model); + // add to map from models to modelVisuals so that it's accesisble + // thru tree picks + mapModelsToVisuals.put(model, newModelVisual); + // add to list of models + getModelVisuals().add(newModelVisual); //Too late?? + modelOpacities.put(model, 1.0); + addVisObjectToAllViews(); + // Compute placement so that model does not intersect others + vtkMatrix4x4 m= (model instanceof ModelForExperimentalData)? + new vtkMatrix4x4(): + getInitialTransform(newModelVisual); + newModelVisual.getModelDisplayAssembly().SetUserMatrix(m); + + sceneAssembly.AddPart(newModelVisual.getModelDisplayAssembly()); + } + if (websocketdb!=null){ + // create Json for model + ModelVisualizationJson vizJson = new ModelVisualizationJson(jsondb, model); + getInstance().addModelVisuals(model, vizJson); + exportModelJsonToVisualizer(vizJson, null); + } + else { + // Same as open visualizer window + VisualizerWindowAction.openVisualizerWindow(); + } // Check if this refits scene into window // int rc = newModelVisual.getModelDisplayAssembly().GetReferenceCount(); if(OpenSimDB.getInstance().getNumModels()==1) { @@ -345,7 +381,12 @@ public void update(Observable o, Object arg) { //rc = visModel.getModelDisplayAssembly().GetReferenceCount(); if (visModel != null) visModel.cleanup(); if (websocketdb != null){ - websocketdb.broadcastMessageJson(visJson.createCloseModelJson(dModel)); + ModelVisualizationJson dJson = mapModelsToJsons.get(dModel); + JSONObject msg = dJson.createCloseModelJson(); + websocketdb.broadcastMessageJson(msg, null); + System.out.println(msg.toJSONString()); + UUID modelUUID = dJson.getModelUUID(); + mapModelsToJsons.remove(dModel); } } else if (ev.getOperation()==ModelEvent.Operation.SetCurrent) { @@ -365,6 +406,14 @@ public void update(Observable o, Object arg) { setObjectOpacity(next, getNonCurrentModelOpacity()*nominalOpacity); } } + if (websocketdb != null){ + Model cModel = ev.getModel(); + currentJson = mapModelsToJsons.get(cModel); + JSONObject msg = currentJson.createSetCurrentModelJson(); + websocketdb.broadcastMessageJson(msg, null); + System.out.println(msg.toJSONString()); + } + } else if (ev.getOperation()==ModelEvent.Operation.Save) { // If a model is saved then its document filename has changed and we should update the settings file accordingly updateSettingsSerializer(ev.getModel()); @@ -373,6 +422,18 @@ public void update(Observable o, Object arg) { } } + public void exportModelJsonToVisualizer(ModelVisualizationJson vizJson, VisWebSocket socket) { + String fileName = JettyMain.getServerWorkingDir()+vizJson.getModelUUID().toString().substring(0, 8)+".json"; + try { + // Write vizJson to file and send message to visualizer to open it + JSONUtilities.writeJsonFile(vizJson, fileName); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + // send message to visualizer to load model from file + websocketdb.broadcastMessageJson(vizJson.createOpenModelJson(), socket); + } + private void handleObjectsDeletedEvent(final Object arg) { ObjectsDeletedEvent ev = (ObjectsDeletedEvent)arg; Vector objs = ev.getObjects(); @@ -453,7 +514,7 @@ OpenSimObject getObjectForVtkRep(vtkAssembly prop) { * Get the vtk object corresponding to passed in opensim object **/ public vtkProp3D getVtkRepForObject(OpenSimObject obj) { - if (!isGraphicsAvailable()) return null; + if (!isVtkGraphicsAvailable()) return null; Iterator iter = modelVisuals.iterator(); while(iter.hasNext()){ SingleModelVisuals nextModel = iter.next(); @@ -553,29 +614,35 @@ else if (modelVis.isVisible() && !onOff) { private void createNewViewWindowIfNeeded() { if (openModelInNewWindow){ boolean evt = SwingUtilities.isEventDispatchThread(); - // The following line has the side effect of loading VTK libraries, can't move it to another thread' - final ModelWindowVTKTopComponent win = new ModelWindowVTKTopComponent(); - openWindows.add(win); - openModelInNewWindow=false; - setCurrentModelWindow(win); - // open window later rather than now to avoid having a rectangular blank patch appearing over the GUI while - // the model is loading and the scene is set up - if (SwingUtilities.isEventDispatchThread()){ - win.requestActive(); - win.open(); + if (isVtkGraphicsAvailable()){ + // The following line has the side effect of loading VTK libraries, can't move it to another thread' + final ModelWindowVTKTopComponent win = new ModelWindowVTKTopComponent(); + openWindows.add(win); + openModelInNewWindow=false; + setCurrentModelWindow(win); + // open window later rather than now to avoid having a rectangular blank patch appearing over the GUI while + // the model is loading and the scene is set up + if (SwingUtilities.isEventDispatchThread()){ + win.requestActive(); + win.open(); + } + else + { + SwingUtilities.invokeLater(new Runnable(){ // Should change to WindowManager.getDefault().invokeWhenUIReady if/when we upgrade NB + public void run(){ + win.open(); + win.requestActive(); + }}); + } + } + if (websocketdb == null){ + // Try to open a visualizer window + VisualizerWindowAction.openVisualizerWindow(); } - else - { - SwingUtilities.invokeLater(new Runnable(){ // Should change to WindowManager.getDefault().invokeWhenUIReady if/when we upgrade NB - public void run(){ - win.open(); - win.requestActive(); - }}); - } } } /** - * Add an arbirary Object to the scene (all views) + * Add an arbitrary Object to the scene (all views) */ public void addObjectToScene(vtkProp3D aProp) { sceneAssembly.AddPart(aProp); @@ -917,7 +984,7 @@ public void setSelectedObject(OpenSimObject obj) { markSelected(selectedObject, true, true, true); ExplorerTopComponent.getDefault().selectNodeForSelectedObject(selectedObject); if (websocketdb != null){ - websocketdb.broadcastMessageJson(visJson.createSelectionJson(obj)); + websocketdb.broadcastMessageJson(currentJson.createSelectionJson(obj), null); } } else { // this function should never be called with obj = null ClearSelectedObjectsEvent evnt = new ClearSelectedObjectsEvent(this); @@ -1151,27 +1218,29 @@ public void updateModelDisplay(Model aModel) { * This excludes transforms since these are obtained from the system on the fly. */ public void updateModelDisplay(Model aModel, OpenSimObject specificObject) { - if (!isGraphicsAvailable()) return; - lockDrawingSurfaces(true); - if (specificObject!=null) - mapModelsToVisuals.get(aModel).updateObjectDisplay(specificObject); - mapModelsToVisuals.get(aModel).updateModelDisplay(aModel); - lockDrawingSurfaces(false); - repaintAll(); - if (websocketdb != null){ + if (isVtkGraphicsAvailable()){ + lockDrawingSurfaces(true); + if (specificObject!=null) + mapModelsToVisuals.get(aModel).updateObjectDisplay(specificObject); + mapModelsToVisuals.get(aModel).updateModelDisplay(aModel); + lockDrawingSurfaces(false); + repaintAll(); + } + if (websocketdb != null && currentJson != null){ // Make xforms JSON - websocketdb.broadcastMessageJson(visJson.createFrameMessageJson()); + websocketdb.broadcastMessageJson(currentJson.createFrameMessageJson(), null); } } public void updateModelDisplayNoRepaint(Model aModel) { - if (!isGraphicsAvailable()) return; - lockDrawingSurfaces(true); - mapModelsToVisuals.get(aModel).updateModelDisplay(aModel); - lockDrawingSurfaces(false); + if (isVtkGraphicsAvailable()){ + lockDrawingSurfaces(true); + mapModelsToVisuals.get(aModel).updateModelDisplay(aModel); + lockDrawingSurfaces(false); + } if (websocketdb != null){ // Make xforms JSON - websocketdb.broadcastMessageJson(visJson.createFrameMessageJson()); + websocketdb.broadcastMessageJson(currentJson.createFrameMessageJson(), null); } } @@ -1509,6 +1578,34 @@ public void updateDisplay(Model model, Component ownerModelComponent) { getModelVisuals(model).upateDisplay(ownerModelComponent); } + /** + * @return the currentJson + */ + public ModelVisualizationJson getCurrentJson() { + return currentJson; + } + + public void exportAllModelsToJson(VisWebSocket socket) { + // if no models, then nothing to exportex + Object[] models = OpenSimDB.getInstance().getAllModels(); + for (int i=0; i< models.length; i++){ + Model model = (Model) models[i]; + ModelVisualizationJson vizJson = null; + if (getInstance().mapModelsToJsons.containsKey(model)){ + vizJson = getInstance().mapModelsToJsons.get(model); + } + else{ + vizJson = new ModelVisualizationJson(jsondb, model); + getInstance().addModelVisuals(model, vizJson); + } + exportModelJsonToVisualizer(vizJson, socket); + } + } + + private void sync(VisWebSocket visWebSocket) { + ViewDB.getInstance().exportAllModelsToJson(visWebSocket); + } + /** * Utility: apply a function to given actor, or to all actors in assembly. */ @@ -1664,7 +1761,12 @@ public void addModelVisuals(Model model, SingleModelVisuals dataVisuals) { modelVisuals.add(dataVisuals); mapModelsToVisuals.put(model, dataVisuals); sceneAssembly.AddPart(dataVisuals.getModelDisplayAssembly()); -} + } + + public void addModelVisuals(Model model, ModelVisualizationJson modelJson) { + if (!mapModelsToJsons.containsKey(model)) + mapModelsToJsons.put(model, modelJson); + } public void displayText(String text, int forntSize){ textActor.SetInput(text); @@ -1878,7 +1980,7 @@ public void removeObjectAnnotationFromViews(vtkCaptionActor2D caption) { } } - public static boolean isGraphicsAvailable() { + public static boolean isVtkGraphicsAvailable() { return graphicsAvailable; } @@ -1906,15 +2008,22 @@ public Object construct() { websocketdb.setObserver(instance); } - public void setJson(VisualizationJson json) { - visJson = json; + public void setCurrentJson() { + Model cModel = getCurrentModel(); + if (cModel != null && mapModelsToJsons.containsKey(cModel)){ + currentJson = mapModelsToJsons.get(cModel); + JSONObject msg = currentJson.createSetCurrentModelJson(); + websocketdb.broadcastMessageJson(msg, null); + System.out.println(msg.toJSONString()); + } } private void handleJson(JSONObject jsonObject) { Object uuid = jsonObject.get("uuid"); String uuidString = (String) uuid; if (uuidString.length()==0) return; - final OpenSimObject selectedObject = visJson.findObjectForUUID(uuidString); + final OpenSimObject selectedObject = currentJson.findObjectForUUID(uuidString); + if (selectedObject == null) return; // Not OpenSim Object, not interested JSONMessageHandler.handleJSON(getCurrentModel(), selectedObject, jsonObject); } } diff --git a/Gui/opensim/visResources/templateScene.json b/Gui/opensim/visResources/templateScene.json deleted file mode 100644 index e84e31a19..000000000 --- a/Gui/opensim/visResources/templateScene.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "object": { - "uuid": "48EA0291-024E-47E6-9ACE-C6B3B5BED3D0", - "type": "Model", - "name": "OpenSimModel", - "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1], - "children": [ - ] - }, - "metadata": { - "version": 4.4, - "type": "Object", - "generator": "Object3D.toJSON" - }, - "geometries": [ - ], - "materials": [ - ] -} \ No newline at end of file diff --git a/Gui/opensim/visualizationServer/src/org/eclipse/jetty/JettyMain.java b/Gui/opensim/visualizationServer/src/org/eclipse/jetty/JettyMain.java index f2f38b3db..adebb3f06 100644 --- a/Gui/opensim/visualizationServer/src/org/eclipse/jetty/JettyMain.java +++ b/Gui/opensim/visualizationServer/src/org/eclipse/jetty/JettyMain.java @@ -25,6 +25,7 @@ public class JettyMain { private static final String serverRootDir = TheApp.getInstallDir(); private static final String pathToStartPage = "/threejs/editor/"; private static final int serverPort = 8000; + private static final String serverWorkingDir = serverRootDir+"/threejs/editor/"; /** * @param args the command line arguments */ @@ -88,4 +89,11 @@ public static boolean isServerup() { return serverup; } + /** + * @return the serverWorkingDir + */ + public static String getServerWorkingDir() { + return serverWorkingDir; + } + } diff --git a/Gui/opensim/visualizationServer/src/org/eclipse/jetty/VisWebSocket.java b/Gui/opensim/visualizationServer/src/org/eclipse/jetty/VisWebSocket.java index 66bc9f060..fecfbf5b2 100644 --- a/Gui/opensim/visualizationServer/src/org/eclipse/jetty/VisWebSocket.java +++ b/Gui/opensim/visualizationServer/src/org/eclipse/jetty/VisWebSocket.java @@ -33,7 +33,7 @@ public class VisWebSocket extends Observable { // Socket to handle incoming traf public VisWebSocket(){ // Register socket with WebSocketDB so it can be called back - WebSocketDB.registerNewSocket(this); + WebSocketDB.getInstance().registerNewSocket(this); } @OnWebSocketConnect @@ -48,12 +48,14 @@ public void onOpen (Session peer) { public void onClose (Session peer, int in, String cause) { peers.remove(peer); System.out.println("onClose"); + WebSocketDB.getInstance().unRegisterSocket(this); } @OnWebSocketError public void onError (Session peer, Throwable er) { System.out.println("onError"); } + // Receive message from Visualizer @OnWebSocketMessage public void visMessage(String stringToParse) { try { @@ -71,7 +73,7 @@ void sendVisualizerMessage(JSONObject selected) { for (Session peer:peers){ try { peer.getRemote().sendString(selected.toJSONString()); - break; + } catch (IOException ex) { Logger.getLogger(VisWebSocket.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/Gui/opensim/visualizationServer/src/org/eclipse/jetty/WebSocketDB.java b/Gui/opensim/visualizationServer/src/org/eclipse/jetty/WebSocketDB.java index af58653e3..a6beab75b 100644 --- a/Gui/opensim/visualizationServer/src/org/eclipse/jetty/WebSocketDB.java +++ b/Gui/opensim/visualizationServer/src/org/eclipse/jetty/WebSocketDB.java @@ -17,22 +17,28 @@ */ public class WebSocketDB { static WebSocketDB instance; - private static Set sockets = Collections.synchronizedSet(new HashSet()); - private static Observer observer; + private Set sockets = Collections.synchronizedSet(new HashSet()); + private Observer observer; /** Creates a new instance of WebSocketDB */ private WebSocketDB() { instance = this; } - static void registerNewSocket(VisWebSocket socket) { - sockets.add(socket); + public void registerNewSocket(VisWebSocket socket) { + System.out.println("Register new Socket"); + if (!sockets.contains(socket)) + sockets.add(socket); + System.out.println("Socket count ="+sockets.size()); socket.addObserver(observer); + observer.update(socket, null); } - static void unRegisterSocket(VisWebSocket socket) { + public void unRegisterSocket(VisWebSocket socket) { + System.out.println("unRegister Socket"); sockets.remove(socket); - } + System.out.println("Socket count ="+sockets.size()); + } static public WebSocketDB getInstance() { if (instance == null) @@ -45,12 +51,17 @@ static public WebSocketDB getInstance() { * @param observer the observer to set */ public void setObserver(Observer observer) { - this.observer = observer; + this.observer = observer; // ViewDB } - public void broadcastMessageJson(JSONObject msg) + public void broadcastMessageJson(JSONObject msg, VisWebSocket specificSocket) { + if (specificSocket != null){ + specificSocket.sendVisualizerMessage(msg); + return; + } for (VisWebSocket sock : sockets){ + System.out.println("Broadcast:"+msg.toJSONString()+"\n"); sock.sendVisualizerMessage(msg); } //sockets.iterator().next().sendVisualizerMessage(msg);