1 
2 /*=========================================================================
3 
4   Program:   Visualization Toolkit
5   Module:    vtkRAdapter.cxx
6 
7   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
8   All rights reserved.
9   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
10 
11      This software is distributed WITHOUT ANY WARRANTY; without even
12      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13      PURPOSE.  See the above copyright notice for more information.
14 
15 =========================================================================*/
16 /*-------------------------------------------------------------------------
17   Copyright 2009 Sandia Corporation.
18   Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
19   the U.S. Government retains certain rights in this software.
20 -------------------------------------------------------------------------*/
21 
22 #include "vtkObjectFactory.h"
23 #include "vtkRAdapter.h"
24 #include "vtkAbstractArray.h"
25 #include "vtkStdString.h"
26 #include "vtkStringArray.h"
27 #include "vtkTable.h"
28 #include "vtkTree.h"
29 #include "vtkArray.h"
30 #include "vtkArrayExtents.h"
31 #include "vtkArrayCoordinates.h"
32 #include "vtkTypedArray.h"
33 #include "vtkVariantArray.h"
34 #include "vtkDoubleArray.h"
35 #include "vtkIntArray.h"
36 #include "vtkDataArrayCollection.h"
37 #include "vtkArrayData.h"
38 #include "vtkDataObjectCollection.h"
39 #include "vtkTreeDFSIterator.h"
40 #include "vtkSmartPointer.h"
41 #include "vtkNew.h"
42 #include "vtkEdgeListIterator.h"
43 #include "vtkDataSetAttributes.h"
44 #include "vtkMutableDirectedGraph.h"
45 
46 #include <map>
47 
48 #include <stdio.h>
49 #include <cassert>
50 
51 #define R_NO_REMAP /* AVOID SOME SERIOUS STUPIDITY. DO NOT REMOVE. */
52 
53 #include "R.h"
54 #include "Rdefines.h"
55 #include "R_ext/Parse.h"
56 #include "R_ext/Rdynload.h"
57 
58 
59 vtkStandardNewMacro(vtkRAdapter);
60 
61 namespace
62 {
63 
R_FindArrayIndex(vtkArrayCoordinates & coordinates,const vtkArrayExtents & extents)64 int R_FindArrayIndex(vtkArrayCoordinates& coordinates, const vtkArrayExtents& extents)
65 {
66 
67   vtkIdType i;
68   int ret = 0;
69   vtkIdType divisor = 1;
70   vtkIdType d = coordinates.GetDimensions();
71 
72   for(i = 0; i < d; ++i)
73     {
74     ret = ret + coordinates[i]*divisor;
75     divisor *= extents[i].GetSize();
76     }
77 
78   return(ret);
79 
80 }
81 
82 } // End anonymous namespace
83 
84 //----------------------------------------------------------------------------
vtkRAdapter()85 vtkRAdapter::vtkRAdapter()
86 {
87 
88   this->vad =  vtkArrayData::New();
89   this->vdoc = vtkDataObjectCollection::New();
90   this->vdac = vtkDataArrayCollection::New();
91 
92 }
93 
94 //----------------------------------------------------------------------------
~vtkRAdapter()95 vtkRAdapter::~vtkRAdapter()
96 {
97 
98   if(this->vad)
99     {
100     this->vad->Delete();
101     }
102 
103   if(this->vdoc)
104     {
105     this->vdoc->Delete();
106     }
107 
108   if(this->vdac)
109     {
110     this->vdac->Delete();
111     }
112 
113 }
114 
RToVTKDataArray(SEXP variable)115 vtkDataArray* vtkRAdapter::RToVTKDataArray(SEXP variable)
116 {
117 
118   int i;
119   int j;
120   int nr;
121   int nc;
122   vtkDoubleArray * result;
123   double * data;
124 
125 
126   if( Rf_isMatrix(variable) || Rf_isVector(variable) )
127     {
128     nc = Rf_ncols(variable);
129     nr = Rf_nrows(variable);
130 
131     result = vtkDoubleArray::New();
132 
133     result->SetNumberOfTuples(nr);
134     result->SetNumberOfComponents(nc);
135 
136     data = new double[nc];
137 
138     for(i=0;i<nr;i++)
139       {
140       for(j=0;j<nc;j++)
141         {
142         if ( isReal(variable) )
143           {
144           data[j] = REAL(variable)[j*nr + i];
145           }
146         else if ( isInteger(variable) )
147           {
148           data[j] = static_cast<double>(INTEGER(variable)[j*nr + i]);
149           }
150         else
151           {
152           vtkErrorMacro(<< "Bad return variable, tried REAL and INTEGER.");
153           }
154         result->InsertTuple(i,data);
155         }
156       }
157 
158     delete [] data;
159     this->vdac->AddItem(result);
160     result->Delete();
161     return(result);
162     }
163   else
164     {
165     return(0);
166     }
167 
168 }
169 
170 
VTKDataArrayToR(vtkDataArray * da)171 SEXP vtkRAdapter::VTKDataArrayToR(vtkDataArray* da)
172 {
173 
174   SEXP a;
175   int nr;
176   int nc;
177   int i;
178   int j;
179   double* data;
180 
181   nr = da->GetNumberOfTuples();
182   nc = da->GetNumberOfComponents();
183 
184   PROTECT(a = Rf_allocMatrix(REALSXP,nr,nc));
185 
186   for(i=0;i<nr;i++)
187     {
188     for(j=0;j<nc;j++)
189       {
190       data = da->GetTuple(i);
191       REAL(a)[j*nr + i] = data[j];
192       }
193     }
194 
195   return(a);
196 
197 }
198 
RToVTKArray(SEXP variable)199 vtkArray* vtkRAdapter::RToVTKArray(SEXP variable)
200 {
201 
202   vtkArray::SizeT i;
203   vtkArray::DimensionT j;
204   vtkArray::DimensionT ndim;
205   SEXP dims;
206   vtkArrayExtents extents;
207   vtkTypedArray<double>* da;
208   da = vtkTypedArray<double>::SafeDownCast(vtkArray::CreateArray(vtkArray::DENSE, VTK_DOUBLE));
209 
210   dims = getAttrib(variable, R_DimSymbol);
211   ndim = static_cast<vtkArray::DimensionT>(length(dims));
212 
213   if (!isMatrix(variable)&&!isArray(variable)&&isVector(variable))
214     {
215     ndim = 1;
216     }
217 
218   extents.SetDimensions(ndim);
219 
220   if (isMatrix(variable)||isArray(variable))
221     {
222     for(j=0;j<ndim;j++)
223       {
224       extents[j] = vtkArrayRange(0,INTEGER(dims)[j]);
225       }
226     }
227   else
228     {
229     extents[0] = vtkArrayRange(0,length(variable));
230     }
231 
232   da->Resize(extents);
233 
234   vtkArrayCoordinates index;
235 
236   index.SetDimensions(ndim);
237 
238   for(i=0;i<da->GetSize();i++)
239     {
240     da->GetCoordinatesN(i,index);
241     if ( isReal(variable) )
242       {
243       da->SetVariantValue(index,REAL(variable)[i]);
244       }
245     else if ( isInteger(variable) )
246       {
247       da->SetVariantValue(index,static_cast<double>(INTEGER(variable)[i]));
248       }
249     else
250       {
251       vtkErrorMacro(<< "Bad return variable, tried REAL and INTEGER.");
252       }
253     }
254 
255   this->vad->AddArray(da);
256   da->Delete();
257   return(da);
258 
259 }
260 
VTKArrayToR(vtkArray * da)261 SEXP vtkRAdapter::VTKArrayToR(vtkArray* da)
262 {
263 
264   SEXP a;
265   SEXP dim;
266   vtkArray::SizeT i;
267   vtkArray::DimensionT j;
268   vtkArrayCoordinates coords;
269 
270   PROTECT(dim = Rf_allocVector(INTSXP, da->GetDimensions()));
271 
272   assert(da->GetExtents().ZeroBased());
273   for(j=0;j<da->GetDimensions();j++)
274     {
275     INTEGER(dim)[j] = da->GetExtents()[j].GetSize();
276     }
277 
278   PROTECT(a = Rf_allocArray(REALSXP, dim));
279 
280   for(i=0;i<da->GetSize();i++)
281     {
282     REAL(a)[i] = 0.0;
283     }
284 
285   assert(da->GetExtents().ZeroBased());
286   for(i=0;i<da->GetNonNullSize();i++)
287     {
288     da->GetCoordinatesN(i,coords);
289     REAL(a)[R_FindArrayIndex(coords,da->GetExtents())] = da->GetVariantValue(coords).ToDouble();
290     }
291 
292   UNPROTECT(1);
293 
294   return(a);
295 
296 }
297 
VTKTableToR(vtkTable * table)298 SEXP vtkRAdapter::VTKTableToR(vtkTable* table)
299 {
300 
301   SEXP a;
302   SEXP b;
303   SEXP names;
304   int i;
305   int j;
306   int nr = table->GetNumberOfRows();
307   int nc = table->GetNumberOfColumns();
308   vtkVariant data;
309 
310   PROTECT(a = allocVector(VECSXP, nc));
311   PROTECT(names = allocVector(STRSXP, nc));
312 
313   for(j=0;j<nc;j++)
314     {
315     SET_STRING_ELT(names,j,mkChar(table->GetColumn(j)->GetName()));
316     if(vtkDataArray::SafeDownCast(table->GetColumn(j)))
317       {
318       PROTECT(b = allocVector(REALSXP,nr));
319       SET_VECTOR_ELT(a,j,b);
320       for(i=0;i<nr;i++)
321         {
322         data = table->GetValue(i,j);
323         REAL(b)[i] = data.ToDouble();
324         }
325       }
326     else
327       {
328       PROTECT(b = allocVector(STRSXP,nr));
329       SET_VECTOR_ELT(a,j,b);
330       for(i=0;i<nr;i++)
331         {
332         data = table->GetValue(i,j);
333         SET_STRING_ELT(b,i,mkChar(data.ToString().c_str()));
334         }
335       }
336     }
337 
338   setAttrib(a,R_NamesSymbol,names);
339 
340   return(a);
341 
342 }
343 
RToVTKTable(SEXP variable)344 vtkTable* vtkRAdapter::RToVTKTable(SEXP variable)
345 {
346 
347   int i;
348   int j;
349   int nr;
350   int nc;
351   SEXP names;
352   vtkVariant v;
353   vtkTable* result;
354 
355   if( isMatrix(variable) )
356     {
357     nc = Rf_ncols(variable);
358     nr = Rf_nrows(variable);
359     result = vtkTable::New();
360     names = getAttrib(variable, R_DimNamesSymbol);
361     if(!isNull(names))
362      {
363        vtkStringArray* rowNames = vtkStringArray::New();
364        for (i = 0; i < nr; ++i)
365          {
366          std::string rowName = CHAR(STRING_ELT(VECTOR_ELT(names,0),i));
367          rowNames->InsertNextValue(rowName);
368          }
369        result->AddColumn(rowNames);
370        rowNames->Delete();
371      }
372 
373     for(j=0;j<nc;j++)
374       {
375       vtkDoubleArray* da = vtkDoubleArray::New();
376       da->SetNumberOfComponents(1);
377       if(!isNull(names))
378         {
379         da->SetName(CHAR(STRING_ELT(VECTOR_ELT(names,1),j)));
380         }
381       else
382         {
383         v = j;
384         da->SetName(v.ToString().c_str());
385         }
386       for(i=0;i<nr;i++)
387         {
388         da->InsertNextValue(REAL(variable)[j*nr + i]);
389         }
390       result->AddColumn(da);
391       da->Delete();
392       }
393     }
394   else if( isNewList(variable) )
395     {
396     nc = length(variable);
397     nr = length(VECTOR_ELT(variable,0));
398     for(j=1;j<nc;j++)
399       {
400       if(isReal(VECTOR_ELT(variable,j)) ||
401          isInteger(VECTOR_ELT(variable,j)) ||
402          isString(VECTOR_ELT(variable,j)) )
403         {
404         if(length(VECTOR_ELT(variable,j)) != nr)
405           {
406           vtkGenericWarningMacro(<<"Cannot convert R data type to vtkTable");
407           return(0);
408           }
409         }
410       else
411         {
412         vtkGenericWarningMacro(<<"Cannot convert R data type to vtkTable");
413         return(0);
414         }
415       }
416 
417     result = vtkTable::New();
418     names = getAttrib(variable, R_NamesSymbol);
419     SEXP names2 = getAttrib(variable, R_RowNamesSymbol);
420     if (!isNull(names2))
421       {
422        vtkStringArray* rowNames = vtkStringArray::New();
423        for (i = 0; i < nr; ++i)
424          {
425          std::string rowName = CHAR(STRING_ELT(names2, i));
426          rowNames->InsertNextValue(rowName);
427          }
428        result->AddColumn(rowNames);
429        rowNames->Delete();
430       }
431 
432     vtkAbstractArray *aa;
433     for(j=0;j<nc;j++)
434       {
435       if(isReal(VECTOR_ELT(variable,j)))
436         {
437         vtkDoubleArray* da = vtkDoubleArray::New();
438         da->SetNumberOfComponents(1);
439         aa = da;
440         for(i=0;i<nr;i++)
441           {
442           da->InsertNextValue(REAL(VECTOR_ELT(variable,j))[i]);
443           }
444         }
445       else if(isInteger(VECTOR_ELT(variable,j)))
446         {
447         vtkIntArray* da = vtkIntArray::New();
448         da->SetNumberOfComponents(1);
449         aa = da;
450         for(i=0;i<nr;i++)
451           {
452           da->InsertNextValue(INTEGER(VECTOR_ELT(variable,j))[i]);
453           }
454         }
455       else
456         {
457         vtkStringArray* da = vtkStringArray::New();
458         da->SetNumberOfComponents(1);
459         aa = da;
460         for(i=0;i<nr;i++)
461           {
462           da->InsertNextValue(CHAR(STRING_ELT(VECTOR_ELT(variable,j),i)));
463           }
464         }
465 
466       if(!isNull(names))
467         {
468         aa->SetName(CHAR(STRING_ELT(names,j)));
469         }
470       else
471         {
472         v = j;
473         aa->SetName(v.ToString().c_str());
474         }
475       result->AddColumn(aa);
476       aa->Delete();
477       }
478     }
479   else
480     {
481     vtkGenericWarningMacro(<<"Cannot convert R data type to vtkTable");
482     return(0);
483     }
484 
485   this->vdoc->AddItem(result);
486   result->Delete();
487   return(result);
488 
489 }
490 
VTKTreeToR(vtkTree * tree)491 SEXP vtkRAdapter::VTKTreeToR(vtkTree* tree)
492 {
493   SEXP r_tree;
494   SEXP names;
495   SEXP edge;
496   SEXP edge_length;
497   SEXP Nnode;
498   SEXP node_label;
499   SEXP tip_label;
500   SEXP classname;
501 
502 
503   int nedge, nnode, ntip;
504 
505   // R phylo tree is a list of 5 elements
506   PROTECT(r_tree = allocVector(VECSXP, 5));
507   PROTECT(names = allocVector(STRSXP, 5));
508 
509   // traverse the tree to reorder the leaf vertices according to the
510   // phylo tree numbering rule;
511   // newNodeId is the checkup table that maps a vertexId(starting from 0)
512   // to its corresponding R tree point id (starting from 1)
513   vtkIdType leafCount = 0;
514   vtkTreeDFSIterator* iter = vtkTreeDFSIterator::New();
515   iter->SetTree(tree);
516   int nVerts = tree->GetNumberOfVertices();
517   int *newNodeId = new int[nVerts];//including root vertex 0
518   while (iter->HasNext())
519     {// find out all the leaf nodes, and number them sequentially
520     vtkIdType vertexId = iter->Next();
521     newNodeId[vertexId] = 0;//initialize
522     if (tree->IsLeaf(vertexId))
523       {
524       leafCount++;
525       newNodeId[vertexId] = leafCount;
526       }
527     }
528 
529   // second tree traverse to reorder the node vertices
530   int nodeId = leafCount;
531   iter->Restart();
532   vtkIdType vertexId;
533   while (iter->HasNext())
534     {
535     vertexId = iter->Next();
536     if (!tree->IsLeaf(vertexId))
537       {
538       nodeId++;
539       newNodeId[vertexId] = nodeId;
540       }
541     }
542 
543   nedge = tree->GetNumberOfEdges();
544   ntip  = leafCount;
545   nnode = nedge - ntip + 1;
546 
547   // fill in R variables
548   PROTECT(edge = allocMatrix(INTSXP, nedge,2));
549   PROTECT(Nnode = allocVector(INTSXP, 1));
550   PROTECT(tip_label = allocVector(STRSXP, ntip));
551   PROTECT(edge_length = allocVector(REALSXP, nedge));
552   PROTECT(node_label = allocVector(STRSXP, nnode));
553   INTEGER(Nnode)[0] = nnode;
554 
555   int * e = INTEGER(edge);
556   double * e_len = REAL(edge_length);
557 
558   // fill in e and e_len
559   vtkSmartPointer<vtkEdgeListIterator> edgeIterator = vtkSmartPointer<vtkEdgeListIterator>::New();
560   tree->GetEdges(edgeIterator);
561   vtkEdgeType vEdge;
562   int i = 0;
563   vtkDoubleArray * weights = vtkDoubleArray::SafeDownCast((tree->GetEdgeData())->GetArray("weight"));
564   while(edgeIterator->HasNext())
565     {
566     vEdge = edgeIterator->Next();
567     e[i]  = newNodeId[vEdge.Source] ;
568     e[i + nedge] = newNodeId[vEdge.Target];
569 
570     int eNum = tree->GetEdgeId(vEdge.Source, vEdge.Target);
571     e_len[i] = weights->GetValue(eNum);
572     i++;
573     }
574 
575   // fill in  Nnode , tip_label and  node_label
576   // use GetAbstractArray() instead of GetArray()
577   vtkStringArray * labels = vtkStringArray::SafeDownCast((tree->GetVertexData())->GetAbstractArray("node name"));
578   iter->Restart();
579   while (iter->HasNext())
580     {// find out all the leaf nodes, and number them sequentially
581     vertexId = iter->Next();
582     if (tree->IsLeaf(vertexId))
583       {
584       vtkStdString lab = labels->GetValue(vertexId);
585       SET_STRING_ELT(tip_label, newNodeId[vertexId]-1, mkChar(lab.c_str()));
586       }
587     else
588       {
589       vtkStdString lab = labels->GetValue(vertexId);
590       SET_STRING_ELT(node_label,newNodeId[vertexId]- ntip - 1, mkChar(lab.c_str())); //the starting id of the internal nodes is (ntip + 1)
591       }
592     }
593   iter->Delete();
594 
595   // set all elements
596   SET_VECTOR_ELT(r_tree, 0, edge);
597   SET_VECTOR_ELT(r_tree, 1, Nnode);
598   SET_VECTOR_ELT(r_tree, 2, tip_label);
599   SET_VECTOR_ELT(r_tree, 3, edge_length);
600   SET_VECTOR_ELT(r_tree, 4, node_label);
601 
602   SET_STRING_ELT(names, 0, mkChar("edge"));
603   SET_STRING_ELT(names, 1, mkChar("Nnode"));
604   SET_STRING_ELT(names, 2, mkChar("tip.label"));
605   SET_STRING_ELT(names, 3, mkChar("edge.length"));
606   SET_STRING_ELT(names, 4, mkChar("node.label"));
607 
608   setAttrib(r_tree,R_NamesSymbol,names);
609 
610   PROTECT(classname = allocVector(STRSXP, 1));
611   SET_STRING_ELT(classname, 0, mkChar("phylo"));
612   setAttrib(r_tree, R_ClassSymbol, classname);
613 
614   delete [] newNodeId;
615 
616   UNPROTECT(8);
617   return r_tree;
618 }
619 
620 
621 
RToVTKTree(SEXP variable)622 vtkTree* vtkRAdapter::RToVTKTree(SEXP variable)
623 {
624   int numEdges = 0, numEdgeLengths = 0, numNodes = 0, numNodeLabels = 0;
625   int *edge = NULL;
626   double *edgeLength = NULL;
627   bool haveNodeLabels = false;
628   vtkTree * tree = vtkTree::New();
629 
630   if (isNewList(variable))
631     {
632     int nELT = length(variable);
633     if (nELT < 4)
634       {
635       vtkErrorMacro(<<"RToVTKTree(): R tree list does not contain required four elements!");
636       return NULL;
637       }
638 
639     vtkNew<vtkStringArray> nodeLabels;
640     vtkNew<vtkStringArray> tipLabels;
641     SEXP listNames = getAttrib(variable, R_NamesSymbol);
642     SEXP rTipLabels = NULL;
643     SEXP rNodeLabels = NULL;
644 
645     // collect data from R.  The elements of the tree list are apparently not
646     // guaranteed to be in any specific order.
647     for (int i = 0; i < nELT; ++i)
648       {
649       const char *name = CHAR(STRING_ELT(listNames, i));
650 
651       if (strcmp(name, "edge") == 0)
652         {
653         SEXP rEdge = VECTOR_ELT(variable, i);
654         if (isInteger(rEdge))
655           {
656           edge = INTEGER(rEdge);
657           numEdges = length(rEdge)/2;
658           }
659         else
660           {
661           vtkErrorMacro(<<"RToVTKTree(): \"edge\" array is not integer type. ");
662           return NULL;
663           }
664         }
665 
666       else if (strcmp(name, "Nnode") == 0)
667         {
668         SEXP rNnode = VECTOR_ELT(variable, i);
669         if (isInteger(rNnode))
670           {
671           numNodes =  INTEGER(rNnode)[0];
672           if (length(rNnode) != 1)
673             {
674             vtkErrorMacro(<<"RToVTKTree(): Expect a single scalar of \"Nnode\". ");
675             return NULL;
676             }
677           }
678         else
679           {
680           vtkErrorMacro(<<"RToVTKTree(): \"Nnode\" is not integer type. ");
681           return NULL;
682           }
683         }
684 
685       else if (strcmp(name, "tip.label") == 0)
686         {
687         rTipLabels = VECTOR_ELT(variable, i);
688         }
689 
690       else if (strcmp(name, "edge.length") == 0)
691         {
692         SEXP rEdgeLength = VECTOR_ELT(variable, i);
693         numEdgeLengths = length(rEdgeLength);
694         if (isReal(rEdgeLength))
695           {
696           edgeLength = REAL(rEdgeLength);
697           }
698         }
699 
700       else if (strcmp(name, "node.label") == 0)
701         {
702         // optional node labels
703         rNodeLabels = VECTOR_ELT(variable, i);
704         haveNodeLabels = true;
705         numNodeLabels = length(rNodeLabels);
706         }
707 
708       else
709         {
710         vtkWarningMacro(<<"Unexpected tree element encountered: " << name);
711         }
712       }
713 
714     // Perform some safety checks to make sure that the data extracted from R
715     // is sane.
716     if (numEdges != numEdgeLengths)
717       {
718       vtkErrorMacro(<<"RToVTKTree(): "
719                     << "edgeLength's size does not match up with numEdges.");
720       return NULL;
721       }
722 
723     if (haveNodeLabels && numNodeLabels != numNodes)
724       {
725       vtkErrorMacro(<<"RToVTKTree(): node.label's size does not match numNodes.");
726       return NULL;
727       }
728 
729     // Populate node & tip label arrays.  If no such labels were specified by R
730     // do so with empty strings.
731     nodeLabels->SetNumberOfValues(numNodes);
732     if (rNodeLabels != NULL && isString(rNodeLabels))
733       {
734       for (int i = 0; i < numNodes; i++)
735         {
736         nodeLabels->SetValue(i, CHAR(STRING_ELT(rNodeLabels, i)));
737         }
738       }
739     else
740       {
741       for (int i = 0; i < numNodes; i++)
742         {
743         nodeLabels->SetValue(i, "");
744         }
745       }
746 
747     int numTips = numEdges - numNodes + 1;
748     tipLabels->SetNumberOfValues(numTips);
749     if (rTipLabels != NULL && isString(rTipLabels))
750       {
751       for (int i = 0; i < numTips; i++)
752         {
753         tipLabels->SetValue(i, CHAR(STRING_ELT(rTipLabels, i)));
754         }
755       }
756     else
757       {
758       for (int i = 0; i < numTips; i++)
759         {
760         tipLabels->SetValue(i, "");
761         }
762       }
763 
764     //------------  Build the VTKTree -----------
765     vtkNew<vtkMutableDirectedGraph> builder;
766 
767     // Create all of the tree vertices (number of edges +1)
768     for(int i = 0; i <= numEdges; i++)
769       {
770       builder->AddVertex();
771       }
772 
773     for(int i = 0; i < numEdges; i++)
774       {
775       // -1 because R vertices begin with 1, whereas VTK vertices begin with 0.
776       vtkIdType source = edge[i] - 1;
777       vtkIdType target = edge[i+numEdges] - 1;
778       builder->AddEdge(source, target);
779       }
780 
781     // Create the edge weight array
782     vtkNew<vtkDoubleArray> weights;
783     weights->SetNumberOfComponents(1);
784     weights->SetName("weight");
785     weights->SetNumberOfValues(numEdges);
786     for (int i = 0; i < numEdges; i++)
787       {
788       weights->SetValue(i, edgeLength[i]);
789       }
790     builder->GetEdgeData()->AddArray(weights.GetPointer());
791 
792     // Create the names array
793     // In R tree, the numeric id of the vertice is ordered such that the tips
794     // are listed first followed by the internal nodes. Match up this order
795     // with the label arrays (tip.label and node.label).
796     vtkNew<vtkStringArray> names;
797     names->SetNumberOfComponents(1);
798     names->SetName("node name");
799     names->SetNumberOfValues(numTips + numNodes);
800     for (int i = 0; i < numTips; i++)
801       {
802       names->SetValue(i, tipLabels->GetValue(i));
803       }
804     for (int i = 0; i < numNodes; i++)
805       {
806       names->SetValue(i + numTips, nodeLabels->GetValue(i));
807       }
808     builder->GetVertexData()->AddArray(names.GetPointer());
809 
810     if (!tree->CheckedShallowCopy(builder.GetPointer()))
811       {
812       vtkErrorMacro(<<"Edges do not create a valid tree.");
813       return NULL;
814       }
815 
816     // Create the "node weight" array for the Vertices, in order to use
817     // vtkTreeLayoutStrategy for visualizing the tree using vtkTreeHeatmapItem
818     vtkNew<vtkDoubleArray> nodeWeights;
819     nodeWeights->SetNumberOfTuples(tree->GetNumberOfVertices());
820 
821     vtkNew<vtkTreeDFSIterator> treeIterator;
822     treeIterator->SetStartVertex(tree->GetRoot());
823     treeIterator->SetTree(tree);
824     while (treeIterator->HasNext())
825       {
826       vtkIdType vertex = treeIterator->Next();
827       vtkIdType parent = tree->GetParent(vertex);
828       double weight = 0.0;
829       if (parent >= 0)
830         {
831         weight = weights->GetValue(tree->GetEdgeId(parent, vertex));
832         weight += nodeWeights->GetValue(parent);
833         }
834       nodeWeights->SetValue(vertex, weight);
835       }
836 
837     nodeWeights->SetName("node weight");
838     tree->GetVertexData()->AddArray(nodeWeights.GetPointer());
839 
840     this->vdoc->AddItem(tree);
841     tree->Delete();
842     return tree;
843     }
844   else
845     {
846     vtkErrorMacro(<<"RToVTKTree(): R variable is not a list. ");
847     return NULL;
848     }
849 }
850 
851 
PrintSelf(ostream & os,vtkIndent indent)852 void vtkRAdapter::PrintSelf(ostream& os, vtkIndent indent)
853 {
854 
855   this->Superclass::PrintSelf(os,indent);
856 
857   if(this->vad)
858     {
859     this->vad->PrintSelf(os,indent);
860     }
861 
862   if(this->vdoc)
863     {
864     this->vdoc->PrintSelf(os,indent);
865     }
866 
867   if(this->vdac)
868     {
869     this->vdac->PrintSelf(os,indent);
870     }
871 
872 
873 }
874 
875