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