1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.potential;
39
40 import ffx.potential.bonded.MSNode;
41 import ffx.potential.bonded.MSRoot;
42 import ffx.potential.bonded.ROLSP;
43 import ffx.potential.bonded.RendererCache;
44 import org.jogamp.java3d.Behavior;
45 import org.jogamp.java3d.Bounds;
46 import org.jogamp.java3d.BranchGroup;
47 import org.jogamp.java3d.WakeupCriterion;
48 import org.jogamp.java3d.WakeupOnBehaviorPost;
49
50 import javax.swing.JLabel;
51 import javax.swing.tree.TreeNode;
52 import java.util.ArrayList;
53 import java.util.Enumeration;
54 import java.util.Iterator;
55 import java.util.logging.Logger;
56
57
58
59
60
61
62
63
64 public class Renderer extends Behavior {
65
66 private static final Logger logger = Logger.getLogger(Renderer.class.getName());
67 private static long frameNumber = 0;
68 private static long frameDuration;
69 private ArrayList<MSNode> nodesToUpdate = null;
70 private ArrayList<MSNode> nodesCache = null;
71 private boolean doTransform, doView, doColor;
72 private boolean doTransformCache, doViewCache, doColorCache;
73 private final JLabel statusBar;
74 private RendererCache.ViewModel viewModel, viewModelCache;
75 private RendererCache.ColorModel colorModel, colorModelCache;
76 private WakeupOnBehaviorPost postid;
77 private boolean timer = false;
78 private boolean gc = false;
79
80
81
82
83
84
85
86 public Renderer(Bounds b, JLabel s) {
87 setSchedulingBounds(b);
88 statusBar = s;
89 }
90
91
92
93
94
95
96
97
98
99
100
101 public void arm(
102 ArrayList<MSNode> nodes,
103 boolean t,
104 boolean v,
105 RendererCache.ViewModel vtype,
106 boolean c,
107 RendererCache.ColorModel ctype) {
108
109
110 if (nodesToUpdate != null) {
111 nodesCache = nodes;
112 doTransformCache = t;
113 doViewCache = v;
114 viewModelCache = vtype;
115 doColorCache = c;
116 colorModelCache = ctype;
117 } else {
118 nodesToUpdate = nodes;
119 doTransform = t;
120 doView = v;
121 viewModel = vtype;
122 doColor = c;
123 colorModel = ctype;
124 postId(1);
125 }
126 }
127
128
129
130
131
132
133
134
135
136
137
138 public void arm(
139 MSNode node,
140 boolean t,
141 boolean v,
142 RendererCache.ViewModel vtype,
143 boolean c,
144 RendererCache.ColorModel ctype) {
145 ArrayList<MSNode> temp = new ArrayList<>();
146 temp.add(node);
147 arm(temp, t, v, vtype, c, ctype);
148 }
149
150
151
152
153
154
155 @Override
156 public void initialize() {
157 postid = new WakeupOnBehaviorPost(this, 1);
158 wakeupOn(postid);
159 }
160
161
162
163
164
165
166 public boolean isArmed() {
167 return nodesToUpdate != null;
168 }
169
170
171
172
173
174
175 public boolean isCacheFull() {
176 return nodesCache != null;
177 }
178
179
180
181
182
183
184
185
186 @Override
187 public void processStimulus(Iterator<WakeupCriterion> parm1) {
188
189 if (getView().getFrameNumber() == frameNumber) {
190 System.out.print(".");
191 wakeupOn(postid);
192 postId(1);
193 return;
194 }
195
196 String viewString = null;
197 String colorString = null;
198 if (viewModel != null) {
199 try {
200 viewString = viewModel.toString();
201 } catch (Exception e) {
202 statusBar.setText("Unknown ViewModel: " + viewModel);
203 return;
204 }
205 }
206 if (colorModel != null) {
207 try {
208 colorString = colorModel.toString();
209 } catch (Exception e) {
210 statusBar.setText("Unknown ColorModel: " + colorModel);
211 return;
212 }
213 }
214 if (timer) {
215 startTimer();
216 if (viewString != null) {
217 logger.info("Applying ViewModel Change: " + viewString);
218 }
219 if (colorString != null) {
220 System.out.println("Applying ColorModel Change: " + colorString);
221 }
222 }
223
224 ArrayList<ArrayList<BranchGroup>> newChildren = new ArrayList<>();
225 for (MSNode nodeToUpdate : nodesToUpdate) {
226 if (nodeToUpdate == null) {
227 continue;
228 }
229 if (doTransform) {
230 nodeToUpdate.update();
231 }
232 if (doColor) {
233 nodeToUpdate.setColor(colorModel, null, null);
234 if (statusBar != null) {
235 statusBar.setText(" Color by \"" + colorString + "\" applied to " + nodeToUpdate);
236 }
237 }
238 if (doView) {
239 ArrayList<BranchGroup> newShapes = new ArrayList<>();
240 newChildren.add(newShapes);
241 nodeToUpdate.setView(viewModel, newShapes);
242 if (statusBar != null) {
243 statusBar.setText(" Style \"" + viewString + "\" applied to " + nodeToUpdate);
244 }
245 }
246 }
247
248 try {
249 if (ROLSP.GO_PARALLEL && ROLSP.parallelNotDone > 0) {
250 logger.info("Renderer waiting for " + ROLSP.parallelNotDone + " processes...");
251 }
252 while (ROLSP.GO_PARALLEL && ROLSP.parallelNotDone > 0) {
253 synchronized (this) {
254 wait(10);
255 }
256 }
257 } catch (Exception e) {
258 System.out.println("Exception Waiting for Parallel MultiScale Methods to Finish");
259 } finally {
260
261
262
263
264
265
266
267
268
269 for (int i = 0; i < nodesToUpdate.size(); i++) {
270 if (newChildren.isEmpty()) {
271 break;
272 }
273 MSNode nodeToUpdate = nodesToUpdate.get(i);
274 if (nodeToUpdate == null) {
275 continue;
276 }
277 if (nodeToUpdate instanceof MolecularAssembly ma) {
278 ma.sceneGraphChange(null);
279 } else if (nodeToUpdate instanceof ROLSP) {
280 MolecularAssembly ma = (MolecularAssembly) nodeToUpdate.getChildAt(0);
281 ma.sceneGraphChange(null);
282 } else if (nodeToUpdate instanceof MSRoot) {
283 for (Enumeration<TreeNode> e = nodeToUpdate.children(); e.hasMoreElements(); ) {
284 MSNode updatedNode = (MSNode) e.nextElement();
285 MolecularAssembly ma;
286 if (updatedNode instanceof ROLSP) {
287 ma = (MolecularAssembly) updatedNode.getChildAt(0);
288 } else {
289 ma = (MolecularAssembly) updatedNode;
290 }
291 ma.sceneGraphChange(null);
292 }
293 } else {
294 ArrayList<BranchGroup> newShapes = newChildren.get(i);
295 if (!newShapes.isEmpty()) {
296 MolecularAssembly ma = nodeToUpdate.getMSNode(MolecularAssembly.class);
297 ma.sceneGraphChange(newShapes);
298 }
299 }
300 }
301 }
302 if (timer) {
303 stopTimer();
304 }
305 nodesToUpdate = null;
306 wakeupOn(postid);
307 if (nodesCache != null) {
308 nodesToUpdate = nodesCache;
309 doTransform = doTransformCache;
310 doView = doViewCache;
311 viewModel = viewModelCache;
312 doColor = doColorCache;
313 colorModel = colorModelCache;
314 nodesCache = null;
315 postId(1);
316 }
317 }
318
319 private void startTimer() {
320 Runtime runtime = Runtime.getRuntime();
321 frameDuration = getView().getLastFrameDuration();
322 if (gc) {
323 logger.info(" Running GC for accurate memory usage.");
324 runtime.gc();
325 logger.info(" Done\n Proceeding with graphics operation...");
326 }
327 }
328
329 private void stopTimer() {
330 Runtime runtime = Runtime.getRuntime();
331 frameNumber = getView().getFrameNumber();
332 frameDuration = getView().getLastFrameDuration();
333 logger.info(" Frame Duration After Op: " + frameDuration / 1000);
334 if (gc) {
335 runtime.gc();
336 logger.info(" Done");
337 }
338 }
339 }