1 #include "PVGUI_Trace.h"
2 #include "PVGUI_Module.h"
4 #include <vtkSMPythonTraceObserver.h>
5 #include <vtkSMSourceProxy.h>
6 #include <vtkSMViewProxy.h>
7 #include <vtkSMProxy.h>
8 #include <vtkSMProperty.h>
9 #include <vtkSMProxyProperty.h>
10 #include <vtkSMProxyIterator.h>
12 #include <vtkSMProxyManager.h>
13 #include <vtkSMDomain.h>
14 #include <vtkSMProxyListDomain.h>
15 #include <vtkSMProxyGroupDomain.h>
16 #include <vtkSMPropertyIterator.h>
17 #include <vtkCallbackCommand.h>
18 #include <vtkSMStringVectorProperty.h>
19 #include <vtkSMIntVectorProperty.h>
20 #include <vtkSMIdTypeVectorProperty.h>
21 #include <vtkSMDoubleVectorProperty.h>
22 #include <vtkSMEnumerationDomain.h>
23 #include <vtkSMDomainIterator.h>
24 #include <vtkSMInputProperty.h>
27 #include <QTextStream>
29 extern PVGUI_Module* ParavisModule;
31 static trace_globals globals;
32 static bool myInitialised = false;
35 //********************************************************************
36 QString pyvariable_from_proxy_name(const QString& proxy_name)
38 QString aName = proxy_name;
39 return make_name_valid(aName.replace(".", "_"));
42 //********************************************************************
43 proxy_trace_info::proxy_trace_info(vtkSMProxy* proxy,
44 const QString& proxyGroup,
45 const QString& proxyName)
49 ProxyName = proxyName;
50 PyVariable = pyvariable_from_proxy_name(proxyName);
51 ignore_next_unregister = false;
54 //********************************************************************
55 prop_trace_info::prop_trace_info(const proxy_trace_info_ptr proxyTraceInfo, vtkSMProperty* prop)
58 // Determine python variable name
59 PyVariable = prop->GetXMLLabel();
60 // For non-self properties, use the xml name instead of xml label:
61 if (prop->GetParent() != proxyTraceInfo->Proxy)
62 PyVariable = proxyTraceInfo->Proxy->GetPropertyName(prop);
63 PyVariable = make_name_valid(PyVariable);
67 //********************************************************************
68 QString make_name_valid(const QString& theName)
70 QString name = theName;
73 if ((name.indexOf('(') >= 0) || (name.indexOf(')') >=0))
75 name = name.replace(" ","");
76 name = name.replace("-","");
77 name = name.replace(":","");
78 name = name.replace(".","");
79 if (!name.at(0).isLetter())
84 //********************************************************************
85 vtkSMPythonTraceObserver* trace_observer()
87 return globals.observer;
90 //********************************************************************
91 QStringList ignoredViewProperties()
93 return globals.ignored_view_properties;
96 //********************************************************************
97 QStringList ignoredRepresentationProperties()
99 return globals.ignored_representation_properties;
102 //********************************************************************
103 bool propIsIgnored(const proxy_trace_info_ptr info, const QString& propName)
105 QStringList aIgnoredList = ignoredViewProperties();
106 if ((info->Group == "views") && (aIgnoredList.contains(propName)))
108 aIgnoredList = ignoredRepresentationProperties();
109 if ((info->Group == "representations") && (aIgnoredList.contains(propName)))
114 //********************************************************************
115 bool operator < (const QStringList& list1, const QStringList& list2) {
116 QString s1 = list1.join(":");
117 QString s2 = list2.join(":");
121 //********************************************************************
122 void GetProxiesInGroup(const char* theName, QMap<QStringList,vtkSMProxy*>& proxies)
124 pqServer* aServer = ParavisModule->getActiveServer();
126 vtkSMProxyIterator* aIt = vtkSMProxyIterator::New();
127 aIt->SetConnectionID(aServer->GetConnectionID());
128 aIt->SetModeToOneGroup();
129 for (aIt->Begin(theName); !aIt->IsAtEnd(); aIt->Next()) {
130 vtkSMProxy* aProxy = aIt->GetProxy();
132 aKey << aIt->GetKey() << aProxy->GetSelfIDAsString();
133 proxies[aKey] = aProxy;
138 //********************************************************************
139 void track_existing_sources()
141 QMap<QStringList, vtkSMProxy*> existing_sources;
142 GetProxiesInGroup("sources", existing_sources);
144 QMap<QStringList, vtkSMProxy*>::const_iterator aIt;
145 for (aIt = existing_sources.constBegin(); aIt!=existing_sources.constEnd(); ++aIt) {
146 QStringList aKey = aIt.key();
147 vtkSMProxy* aProxy = aIt.value();
148 track_existing_source_proxy(aProxy, "");
152 //********************************************************************
153 proxy_trace_info_ptr track_existing_source_proxy(vtkSMProxy* proxy, const QString& proxy_name)
155 proxy_trace_info_ptr proxy_info(new proxy_trace_info(proxy, "sources", proxy_name));
156 globals.registered_proxies.append(proxy_info);
157 if ((!globals.last_active_source) && (proxy == globals.active_source_at_start)) {
158 globals.last_active_source = proxy;
159 globals.trace_output.append(QString("%1 = GetActiveSource()").arg(proxy_info->PyVariable));
161 globals.trace_output.append(QString("%1 = FindSource(\"%2\")").arg(proxy_info->PyVariable).arg(proxy_name));
166 //********************************************************************
167 QList<vtkSMProxy*> GetRenderViews()
169 QList<vtkSMProxy*> render_modules;
171 pqServer* aServer = ParavisModule->getActiveServer();
173 vtkSMProxyIterator* aIt = vtkSMProxyIterator::New();
174 aIt->SetConnectionID(aServer->GetConnectionID());
175 for (aIt->Begin(); !aIt->IsAtEnd(); aIt->Next()) {
176 vtkSMProxy* aProxy = aIt->GetProxy();
177 if (aProxy->IsA("vtkSMRenderViewProxy"))
178 render_modules.append(aProxy);
181 return render_modules;
184 //********************************************************************
185 proxy_trace_info_ptr track_existing_view_proxy(vtkSMProxy* proxy, const QString& proxy_name)
187 proxy_trace_info_ptr proxy_info(new proxy_trace_info(proxy, "views", proxy_name));
188 globals.registered_proxies.append(proxy_info);
189 if ((!globals.last_active_view) && (proxy == globals.active_view_at_start)) {
190 globals.last_active_view = proxy;
191 globals.trace_output.append(QString("%1 = GetRenderView()").arg(proxy_info->PyVariable));
193 QList<vtkSMProxy*> all_views = GetRenderViews();
194 if (all_views.contains(proxy)) {
195 int view_index = all_views.indexOf(proxy);
196 if (view_index != -1)
197 globals.trace_output.append(QString("%1 = GetRenderViews()[%2]").arg(proxy_info->PyVariable).arg(view_index));
203 //********************************************************************
204 proxy_trace_info_ptr track_existing_representation_proxy(vtkSMProxy* proxy,
205 const QString& proxy_name)
207 vtkSMProxyProperty* input_property = dynamic_cast<vtkSMProxyProperty*>(proxy->GetProperty("Input"));
208 if (!input_property) return proxy_trace_info_ptr();
210 if (input_property->GetNumberOfProxies() > 0) {
211 vtkSMProxy* input_proxy = input_property->GetProxy(0);
212 proxy_trace_info_ptr input_proxy_info = get_proxy_info(input_proxy);
213 if (input_proxy_info.get()) {
214 proxy_trace_info_ptr proxy_info(new proxy_trace_info(proxy, "representations", proxy_name));
215 globals.registered_proxies.append(proxy_info);
216 globals.trace_output.append(QString("%1 = GetDisplayProperties(%2)").arg(proxy_info->PyVariable).arg(input_proxy_info->PyVariable));
220 return proxy_trace_info_ptr();
223 //********************************************************************
224 proxy_trace_info_ptr track_existing_proxy(vtkSMProxy* proxy)
226 QString proxy_name = get_source_proxy_registration_name(proxy);
227 if (!proxy_name.isNull())
228 return track_existing_source_proxy(proxy, proxy_name);
230 proxy_name = get_representation_proxy_registration_name(proxy);
231 if (!proxy_name.isNull())
232 return track_existing_representation_proxy(proxy, proxy_name);
234 proxy_name = get_view_proxy_registration_name(proxy);
235 if (!proxy_name.isNull())
236 return track_existing_view_proxy(proxy, proxy_name);
237 return proxy_trace_info_ptr();
240 //********************************************************************
241 proxy_trace_info_ptr get_proxy_info(const QString& p, bool search_existing)
243 foreach(proxy_trace_info_ptr info, globals.last_registered_proxies) {
244 if (info->PyVariable == p) return info;
246 foreach(proxy_trace_info_ptr info, globals.registered_proxies) {
247 if (info->PyVariable == p) return info;
250 if(search_existing) return proxy_trace_info_ptr();
252 return proxy_trace_info_ptr();
255 //********************************************************************
256 proxy_trace_info_ptr get_proxy_info(vtkSMProxy* p, bool search_existing)
258 foreach(proxy_trace_info_ptr info, globals.last_registered_proxies) {
259 if (info->Proxy == p) return info;
261 foreach(proxy_trace_info_ptr info, globals.registered_proxies) {
262 if (info->Proxy == p) return info;
264 // It must be a proxy that existed before trace started
265 if (search_existing) return track_existing_proxy(p);
267 return proxy_trace_info_ptr();
270 //********************************************************************
271 void ensure_active_source(const proxy_trace_info_ptr proxy_info)
273 if (proxy_info && (proxy_info->Proxy != globals.last_active_source)) {
274 globals.trace_output.append(QString("SetActiveSource(%1)").arg(proxy_info->PyVariable));
275 globals.last_active_source = proxy_info->Proxy;
279 //********************************************************************
280 void ensure_active_view(const proxy_trace_info_ptr proxy_info)
282 if (proxy_info && (proxy_info->Proxy != globals.last_active_view)) {
283 globals.trace_output.append(QString("SetActiveView(%1)").arg(proxy_info->PyVariable));
284 globals.last_active_view = proxy_info->Proxy;
288 //********************************************************************
289 proxy_trace_info_ptr get_input_proxy_info_for_rep(const proxy_trace_info_ptr rep_info)
291 if (rep_info->CurrentProps.contains("Input")) {
292 QString input_proxy_pyvariable = rep_info->CurrentProps["Input"];
293 return get_proxy_info(input_proxy_pyvariable);
295 return proxy_trace_info_ptr();
298 //********************************************************************
299 proxy_trace_info_ptr get_view_proxy_info_for_rep(const proxy_trace_info_ptr rep_info)
301 QList<proxy_trace_info_ptr> aTmpList;
302 aTmpList.append(globals.registered_proxies);
303 aTmpList.append(globals.last_registered_proxies);
304 foreach (proxy_trace_info_ptr p, aTmpList) {
305 // If the proxy is a view, check for rep_info.Proxy in the
306 // view's 'Representation' property
307 if (p->Group == "views") {
308 vtkSMProxyProperty* rep_prop =
309 dynamic_cast<vtkSMProxyProperty*>(p->Proxy->GetProperty("Representations"));
311 for (int i = 0; i < rep_prop->GetNumberOfProxies(); i++) {
312 if (rep_info->Proxy == rep_prop->GetProxy(i))
318 return proxy_trace_info_ptr();
321 //********************************************************************
322 QString get_source_proxy_registration_name(vtkSMProxy* proxy)
324 return vtkSMObject::GetProxyManager()->GetProxyName("sources", proxy);
327 //********************************************************************
328 QString get_view_proxy_registration_name(vtkSMProxy* proxy)
330 return vtkSMObject::GetProxyManager()->GetProxyName("views", proxy);
333 //********************************************************************
334 QString get_representation_proxy_registration_name(vtkSMProxy* proxy)
336 return vtkSMObject::GetProxyManager()->GetProxyName("representations", proxy);
339 //********************************************************************
340 QString make_comma_separated_string(QStringList values)
342 QString ret=values.join(", ");
344 ret = QString(" %1 ").arg(ret);
348 QStringList wrap_property(vtkSMProxy* proxy, vtkSMProperty* smproperty)
350 QStringList propertyList;
351 if(smproperty->IsA("vtkSMVectorProperty")) {
352 vtkSMVectorProperty* property = dynamic_cast<vtkSMVectorProperty*>(smproperty);
353 int nElem = property->GetNumberOfElements();
355 vtkSMDomain* dom = NULL;
356 if(property->IsA("vtkSMStringVectorProperty")) {
357 dom = property->GetDomain("array_list");
358 if(dom!=NULL && dom->IsA("vtkSMArraySelectionDomain") && property->GetRepeatable()) {
360 cerr << "!!!Error: The SMProperty with XML label" << smproperty->GetXMLLabel() << "has a size that is not a multiple of 2." << endl;
366 } else if(property->IsA("vtkSMIntVectorProperty")) {
367 dom = property->GetDomain("enum");
369 for(int i = 0; i < nElem; i+=di) {
372 if(dynamic_cast<vtkSMStringVectorProperty*>(property)->GetElement(i+1) == "0") {
377 if(property->IsA("vtkSMStringVectorProperty"))
378 propertyList.append(QString("'%1'").arg(dynamic_cast<vtkSMStringVectorProperty*>(property)->GetElement(i)));
379 if(property->IsA("vtkSMIntVectorProperty")) {
381 propertyList.append(QString("%1").arg(dynamic_cast<vtkSMIntVectorProperty*>(property)->GetElement(i)));
383 for(int j = 0; j < dynamic_cast<vtkSMEnumerationDomain*>(dom)->GetNumberOfEntries(); j++) {
384 if(dynamic_cast<vtkSMEnumerationDomain*>(dom)->GetEntryValue(j) == dynamic_cast<vtkSMIntVectorProperty*>(property)->GetElement(i)) {
385 propertyList.append(QString("'%1'").arg(dynamic_cast<vtkSMEnumerationDomain*>(dom)->GetEntryText(j)));
391 if(property->IsA("vtkSMIdTypeVectorProperty"))
392 propertyList.append(QString("%1").arg(dynamic_cast<vtkSMIdTypeVectorProperty*>(property)->GetElement(i)));
393 if(property->IsA("vtkSMDoubleVectorProperty"))
394 propertyList.append(QString("%1").arg(dynamic_cast<vtkSMDoubleVectorProperty*>(property)->GetElement(i)));
401 //********************************************************************
402 QString vector_smproperty_tostring(const proxy_trace_info_ptr proxyInfo,
403 const prop_trace_info_ptr propInfo)
405 vtkSMProxy* proxy = proxyInfo->Proxy;
406 vtkSMProperty* prop = propInfo->Prop;
407 QStringList propList = wrap_property(proxy, prop);
409 if (propList.size() == 0)
411 if (propList.size() == 1)
412 return propList.first();
413 if (propList.size() > 1) {
414 pythonProp = make_comma_separated_string(propList);
415 pythonProp = QString("[%1]").arg(pythonProp);
420 //********************************************************************
421 QString get_property_value_from_list_domain(const proxy_trace_info_ptr proxyInfo,
422 const prop_trace_info_ptr propInfo)
424 vtkSMProxy* proxy = proxyInfo->Proxy;
425 vtkSMProxyProperty* prop = dynamic_cast<vtkSMProxyProperty*>(propInfo->Prop);
426 vtkSMProxyListDomain* listdomain = dynamic_cast<vtkSMProxyListDomain*>(prop->GetDomain("proxy_list"));
427 if (listdomain != NULL && prop->GetNumberOfProxies() == 1) {
428 vtkSMProxy* proxyPropertyValue = prop->GetProxy(0);
429 for (int i = 0; i < listdomain->GetNumberOfProxies(); i++) {
430 if (listdomain->GetProxy(i) == proxyPropertyValue) {
431 proxy_trace_info_ptr info = get_proxy_info(proxyPropertyValue);
433 proxy_trace_info_ptr infotmp(new proxy_trace_info(proxyPropertyValue, "helpers", listdomain->GetProxy(i)->GetXMLLabel()));
436 info->PyVariable = QString("%1.%2").arg(proxyInfo->PyVariable).arg(propInfo->PyVariable);
437 globals.registered_proxies.append(info);
438 return QString("\"%1\"").arg(listdomain->GetProxy(i)->GetXMLLabel());
445 //********************************************************************
446 QString proxy_smproperty_tostring(const proxy_trace_info_ptr proxyInfo,
447 const prop_trace_info_ptr propInfo)
449 QString strValue = get_property_value_from_list_domain(proxyInfo, propInfo);
450 if (!strValue.isNull())
452 vtkSMProxy* proxy = proxyInfo->Proxy;
453 vtkSMProxyProperty* prop = dynamic_cast<vtkSMProxyProperty*>(propInfo->Prop);
454 // Create a list of the python variables for each proxy in the property vector
455 QStringList nameList;
456 for (int i = 0; i < prop->GetNumberOfProxies(); i++) {
457 vtkSMProxy* inputProxy = prop->GetProxy(i);
458 proxy_trace_info_ptr info = get_proxy_info(inputProxy);
459 if (info && (!info->PyVariable.isNull()))
460 nameList.append(info->PyVariable);
462 if (nameList.size() == 0)
464 if (nameList.size() == 1)
465 return nameList.first();
466 if (nameList.size() > 1) {
467 QString nameListStr = make_comma_separated_string(nameList);
468 return QString("[%1]").arg(nameListStr);
472 //********************************************************************
473 QString input_smproperty_tostring(const proxy_trace_info_ptr proxyInfo,
474 const prop_trace_info_ptr propInfo)
476 return proxy_smproperty_tostring(proxyInfo, propInfo);
479 //********************************************************************
480 void trace_proxy_rename(const proxy_trace_info_ptr proxy_info, const char* new_name)
482 if ((!proxy_info) || (proxy_info->Group != "sources"))
484 QString old_pyvariable = proxy_info->PyVariable;
485 proxy_info->PyVariable = pyvariable_from_proxy_name(new_name);
486 proxy_info->ignore_next_unregister = true;
487 QString newName(new_name);
488 QString name_to_set = newName.replace("\"", "");
489 globals.trace_output.append(QString("RenameSource(\"%1\", %2)").arg(name_to_set).arg(old_pyvariable));
490 globals.trace_output.append(QString("%1 = %2").arg(proxy_info->PyVariable).arg(old_pyvariable));
491 globals.trace_output.append(QString("del %1").arg(old_pyvariable));
494 //********************************************************************
495 proxy_trace_info_ptr trace_proxy_registered(vtkSMProxy* proxy,
496 const QString& proxyGroup,
497 const char* proxyName)
499 //if trace_globals.verbose:
500 // print "Proxy '%s' registered in group '%s'" % (proxyName, proxyGroup)
501 if (!globals.traced_proxy_groups.contains(proxyGroup))
502 return proxy_trace_info_ptr();
504 proxy_trace_info_ptr info(new proxy_trace_info(proxy, proxyGroup, proxyName));
505 globals.last_registered_proxies.append(info);
506 if (globals.capture_all_properties) {
507 vtkSMPropertyIterator* itr = proxy->NewPropertyIterator();
508 for (itr->Begin(); !itr->IsAtEnd(); itr->Next()) {
509 vtkSMProperty* prop = itr->GetProperty();
510 if (prop->GetInformationOnly() || prop->GetIsInternal()) continue;
511 trace_property_modified(info, prop);
517 //********************************************************************
518 prop_trace_info_ptr trace_property_modified(proxy_trace_info_ptr info, vtkSMProperty* prop)
520 prop_trace_info_ptr propInfo(new prop_trace_info(info, prop));
521 //if (globals.verbose)
522 // print "Property '%s' modifed on proxy '%s'" % (propInfo.PyVariable, info.ProxyName)
524 if (prop->IsA("vtkSMVectorProperty"))
525 propValue = vector_smproperty_tostring(info, propInfo);
526 else if (prop->IsA("vtkSMInputProperty"))
527 propValue = input_smproperty_tostring(info, propInfo);
528 else if (prop->IsA("vtkSMProxyProperty"))
529 propValue = proxy_smproperty_tostring(info, propInfo);
530 if (!propValue.isNull()) {
531 info->Props[prop] = propValue;
532 info->ModifiedProps[propInfo->PyVariable] = propValue;
533 info->CurrentProps[propInfo->PyVariable] = propValue;
538 //********************************************************************
539 QList<proxy_trace_info_ptr> sort_proxy_info_by_group(const QList<proxy_trace_info_ptr>& infoList)
541 QList<proxy_trace_info_ptr> views;
542 QList<proxy_trace_info_ptr> sources;
543 QList<proxy_trace_info_ptr> representations;
544 QList<proxy_trace_info_ptr> other;
545 foreach (proxy_trace_info_ptr i, infoList) {
546 if (i->Group == "views") views.append(i);
547 else if (i->Group == "sources") sources.append(i);
548 else if (i->Group == "representations") representations.append(i);
549 else other.append(i);
551 views.append(sources);
553 views.append(representations);
557 //********************************************************************
560 // Get the list of last registered proxies in sorted order
561 QList<proxy_trace_info_ptr> modified_proxies =
562 sort_proxy_info_by_group(globals.last_registered_proxies);
564 // Now append the existing proxies to the list
565 foreach (proxy_trace_info_ptr p, globals.registered_proxies)
566 modified_proxies.append(p);
568 foreach(proxy_trace_info_ptr info, modified_proxies) {
569 QString traceOutput = "";
571 // Generate list of tuples : (propName, propValue)
572 QMap<QString, QString> propNameValues;
573 QMap<QString, QString>::const_iterator aIt;
574 for (aIt = info->ModifiedProps.constBegin(); aIt!=info->ModifiedProps.constEnd(); ++aIt) {
575 QString propName = aIt.key();
576 QString propValue = aIt.value();
577 if (propIsIgnored(info, propName))
580 // Note, the 'Input' property is ignored for representations, so we are
581 // only dealing with filter proxies here. If the 'Input' property is a
582 // single value (not a multi-input filter), then ensure the input is
583 // the active source and leave the 'Input' property out of the
584 // propNameValues list.
585 if ((propName == "Input") && (!propValue.contains("["))) {
586 proxy_trace_info_ptr inputProxyInfo = get_proxy_info(propValue);
587 ensure_active_source(inputProxyInfo);
590 propNameValues[propName] = propValue;
593 // Clear the modified prop list
594 info->ModifiedProps.clear();
596 // If info is in the last_registered_proxies list, then we need to add the
597 // proxy's constructor call to the trace
598 if(globals.last_registered_proxies.contains(info)) {
599 // Determine the function call to construct the proxy
600 bool setPropertiesInCtor = true;
601 QStringList ctorArgs;
602 QString extraCtorCommands = "";
603 QString ctorMethod = make_name_valid(info->Proxy->GetXMLLabel());
604 if (info->Group == "sources") {
605 // track it as the last active source now
606 globals.last_active_source = info->Proxy;
607 // maybe append the guiName property
608 if (globals.use_gui_name)
609 ctorArgs.append(QString("guiName=\"%1\"").arg(info->ProxyName));
611 if (info->Group == "representations") {
613 setPropertiesInCtor = false;
614 // Ensure the input proxy is the active source:
615 proxy_trace_info_ptr input_proxy_info = get_input_proxy_info_for_rep(info);
616 if (input_proxy_info)
617 ensure_active_source(input_proxy_info);
619 // Ensure the view is the active view:
620 proxy_trace_info_ptr view_proxy_info = get_view_proxy_info_for_rep(info);
621 if (view_proxy_info) {
622 ensure_active_view(view_proxy_info);
625 if (info->Group == "scalar_bars") {
626 ctorMethod = "CreateScalarBar";
628 QString("GetRenderView().Representations.append(%1)").arg(info->PyVariable);
630 if (info->Group == "views") {
631 ctorMethod = "CreateRenderView";
632 // Now track it as the last active view
633 globals.last_active_view = info->Proxy;
634 setPropertiesInCtor = false;
636 if (info->Group == "lookup_tables")
637 ctorMethod = "CreateLookupTable";
640 if (setPropertiesInCtor) {
641 QMap<QString, QString>::const_iterator aIt1;
642 for (aIt1 = propNameValues.constBegin(); aIt1!=propNameValues.constEnd(); ++aIt1) {
643 QString propName = aIt1.key();
644 QString propValue = aIt1.value();
645 ctorArgs.append(QString("%1=%2").arg(propName).arg(propValue));
647 propNameValues.clear();
649 QString ctorArgString = make_comma_separated_string(ctorArgs);
651 QString("%1 = %2(%3)\n%4").arg(info->PyVariable).arg(ctorMethod).arg(ctorArgString).arg(extraCtorCommands);
653 // Set properties on the proxy
655 QMap<QString, QString>::const_iterator aIt2;
656 for (aIt2 = propNameValues.constBegin(); aIt2!=propNameValues.constEnd(); ++aIt2) {
657 QString propName = aIt2.key();
658 QString propValue = aIt2.value();
659 traceOutput += QString("%1.%2 = %3\n").arg(info->PyVariable).arg(propName).arg(propValue);
661 if (traceOutput.length() > 0){
662 globals.trace_output.append(traceOutput);
665 foreach (proxy_trace_info_ptr p, globals.last_registered_proxies) {
666 globals.registered_proxies.append(p);
668 while (globals.last_registered_proxies.size() > 0)
669 globals.last_registered_proxies.removeLast();
672 //********************************************************************
673 QString get_trace_string()
676 QString s = globals.trace_output.join("\n");
677 s += globals.trace_output_endblock + "\n";
682 //********************************************************************
683 void save_trace(const QString& fileName)
685 QFile file(fileName);
686 if(!file.open(QFile::WriteOnly))
689 QString trace = get_trace_string();
690 QTextStream out(&file);
695 //********************************************************************
696 //QString print_trace()
698 //********************************************************************
699 void on_proxy_registered(vtkObject* obj, unsigned long , void* , void *)
701 vtkSMPythonTraceObserver* o = dynamic_cast<vtkSMPythonTraceObserver*>(obj);
704 vtkSMProxy* p = o->GetLastProxyRegistered();
705 const char* pGroup = o->GetLastProxyRegisteredGroup();
706 const char* pName = o->GetLastProxyRegisteredName();
707 if (p && pGroup && pName) {
708 proxy_trace_info_ptr proxy_info = get_proxy_info(p, false);
709 // handle source proxy rename, no-op if proxy isn't a source
711 trace_proxy_rename(proxy_info, pName);
713 trace_proxy_registered(p, pGroup, pName);
717 //********************************************************************
718 void on_proxy_unregistered(vtkObject* obj, unsigned long , void* , void*)
720 vtkSMPythonTraceObserver* o = dynamic_cast<vtkSMPythonTraceObserver*>(obj);
723 vtkSMProxy* p = o->GetLastProxyUnRegistered();
724 const char* pGroup = o->GetLastProxyUnRegisteredGroup();
725 const char* pName = o->GetLastProxyUnRegisteredName();
726 if (p && pGroup && pName) {
727 proxy_trace_info_ptr proxy_info = get_proxy_info(p);
728 if (proxy_info != NULL && proxy_info->Proxy != NULL) {
729 if (proxy_info->ignore_next_unregister) {
730 proxy_info->ignore_next_unregister = false;
733 globals.trace_output.append(QString("Delete(%1)").arg(proxy_info->PyVariable));
734 if (globals.last_registered_proxies.contains(proxy_info)) {
735 int aInd = globals.last_registered_proxies.indexOf(proxy_info);
736 globals.last_registered_proxies.removeAt(aInd);
738 if (globals.registered_proxies.contains(proxy_info)) {
739 int aInd = globals.registered_proxies.indexOf(proxy_info);
740 globals.registered_proxies.removeAt(aInd);
746 //********************************************************************
747 void on_property_modified(vtkObject* obj, unsigned long , void* , void*)
749 vtkSMPythonTraceObserver* o = dynamic_cast<vtkSMPythonTraceObserver*>(obj);
752 const char* propName = o->GetLastPropertyModifiedName();
753 vtkSMProxy* proxy = o->GetLastPropertyModifiedProxy();
754 if ((propName != NULL) && (proxy != NULL)) {
755 vtkSMProperty* prop = proxy->GetProperty(propName);
756 if (prop->GetInformationOnly() || prop->GetIsInternal()) return;
758 // small hack here: some view properties are modified before the view
759 // is registered. We don't want to call get_proxy_info until after
760 // the view is registered, so for now lets ignore these properties:
761 QStringList ignoredViewProp = ignoredViewProperties();
762 if (ignoredViewProp.contains(propName)) return;
764 proxy_trace_info_ptr info = get_proxy_info(proxy);
765 if ((info != NULL && info->Proxy != NULL) && (prop != NULL))
766 trace_property_modified(info, prop);
770 //********************************************************************
771 void on_update_information(vtkObject*, unsigned long , void* , void*)
776 //********************************************************************
779 vtkCallbackCommand *aCommand = NULL;
780 vtkSMPythonTraceObserver* o = trace_observer();
781 aCommand = vtkCallbackCommand::New();
782 aCommand->SetCallback(on_proxy_registered);
783 o->AddObserver("RegisterEvent", aCommand);
785 aCommand = vtkCallbackCommand::New();
786 aCommand->SetCallback(on_proxy_unregistered);
787 o->AddObserver("UnRegisterEvent", aCommand);
789 aCommand = vtkCallbackCommand::New();
790 aCommand->SetCallback(on_property_modified);
791 o->AddObserver("PropertyModifiedEvent", aCommand);
793 aCommand = vtkCallbackCommand::New();
794 aCommand->SetCallback(on_update_information);
795 o->AddObserver("UpdateInformationEvent", aCommand);
797 globals.observer_active = true;
800 //********************************************************************
801 void reset_trace_observer()
804 globals.observer->Delete();
805 globals.observer = vtkSMPythonTraceObserver::New();
806 globals.observer_active = false;
807 myInitialised = true;
810 //********************************************************************
811 void reset_trace_globals()
813 globals.capture_all_properties = false;
814 globals.use_gui_name = false;
815 globals.verbose = false;
816 globals.active_source_at_start = 0;
817 globals.active_view_at_start = 0;
818 globals.last_active_view = 0;
819 globals.last_active_source = 0;
820 globals.last_registered_proxies.clear();
821 globals.registered_proxies.clear();
822 globals.trace_output.clear();
823 globals.trace_output << "try: pvsimple\nexcept: from pvsimple import *\n";
824 globals.trace_output_endblock = "Render()";
825 globals.traced_proxy_groups.clear();
826 globals.traced_proxy_groups << "sources"<<"representations"<<"views"<<"lookup_tables"<<"scalar_bars";
827 globals.ignored_view_properties.clear();
828 globals.ignored_view_properties << "ViewSize"<<"GUISize"<<"ViewPosition"<<"ViewTime"<<"Representations";
829 globals.ignored_representation_properties.clear();
830 globals.ignored_representation_properties << "Input";
831 reset_trace_observer();
834 //********************************************************************
837 reset_trace_globals();
840 //********************************************************************
843 reset_trace_observer();
846 //********************************************************************
847 void start_trace(bool CaptureAllProperties, bool UseGuiName, bool Verbose)
851 // VSV: Has to be defined
852 //globals.active_source_at_start = simple.GetActiveSource()
853 //globals.active_view_at_start = simple.GetActiveView()
854 //globals.capture_all_properties = CaptureAllProperties
855 //globals.use_gui_name = UseGuiName
856 //globals.verbose = Verbose