1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkTreeRingToPolyData.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 /*-------------------------------------------------------------------------
16 Copyright 2008 Sandia Corporation.
17 Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18 the U.S. Government retains certain rights in this software.
19 -------------------------------------------------------------------------*/
20 #include "vtkTreeRingToPolyData.h"
21
22 #include "vtkCellArray.h"
23 #include "vtkCellData.h"
24 #include "vtkCommand.h"
25 #include "vtkFloatArray.h"
26 #include "vtkMath.h"
27 #include "vtkIdTypeArray.h"
28 #include "vtkInformation.h"
29 #include "vtkInformationVector.h"
30 #include "vtkObjectFactory.h"
31 #include "vtkPointData.h"
32 #include "vtkTimerLog.h"
33 #include "vtkTree.h"
34 #include "vtkStripper.h"
35 #include "vtkSectorSource.h"
36 #include "vtkAppendPolyData.h"
37
38 #include "vtkSmartPointer.h"
39 #define VTK_CREATE(type, name) \
40 vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
41
42 vtkStandardNewMacro(vtkTreeRingToPolyData);
43
vtkTreeRingToPolyData()44 vtkTreeRingToPolyData::vtkTreeRingToPolyData()
45 {
46 this->SetSectorsArrayName("sectors");
47 this->ShrinkPercentage = 0.0;
48 }
49
50 vtkTreeRingToPolyData::~vtkTreeRingToPolyData() = default;
51
FillInputPortInformation(int vtkNotUsed (port),vtkInformation * info)52 int vtkTreeRingToPolyData::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info)
53 {
54 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTree");
55 return 1;
56 }
57
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)58 int vtkTreeRingToPolyData::RequestData(
59 vtkInformation *vtkNotUsed(request),
60 vtkInformationVector **inputVector,
61 vtkInformationVector *outputVector)
62 {
63 // get the info objects
64 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
65 vtkInformation *outInfo = outputVector->GetInformationObject(0);
66
67 // get the input and output
68 vtkTree *inputTree = vtkTree::SafeDownCast(
69 inInfo->Get(vtkDataObject::DATA_OBJECT()));
70 vtkPolyData *outputPoly = vtkPolyData::SafeDownCast(
71 outInfo->Get(vtkDataObject::DATA_OBJECT()));
72
73 if( inputTree->GetNumberOfVertices() == 0 )
74 {
75 return 1;
76 }
77
78 // Now set the point coordinates, normals, and insert the cell
79 vtkDataArray* coordArray = this->GetInputArrayToProcess(0, inputTree);
80 if (!coordArray)
81 {
82 vtkErrorMacro("Sectors array not found.");
83 return 0;
84 }
85
86 double pt1x[3] = {0.0, 0.0, 0.0};
87 double pt2x[3] = {0.0, 0.0, 0.0};
88 double ang = 0.0;
89 double cos_ang = 0.0;
90 double sin_ang = 0.0;
91 vtkIdType pt1 = 0;
92 vtkIdType pt2 = 0;
93 vtkIdType rootId = inputTree->GetRoot();
94 VTK_CREATE(vtkCellArray, strips);
95 VTK_CREATE(vtkPoints, pts);
96 double progress = 0.0;
97 this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
98
99 for( int i = 0; i < inputTree->GetNumberOfVertices(); i++ )
100 {
101 // Grab coords from the input
102 double coords[4];
103 if( i == rootId )
104 {
105 //don't draw the root node...
106 coords[0] = 0.0;
107 coords[1] = 0.0;
108 coords[2] = 1.0;
109 coords[3] = 1.0;
110 }
111 else
112 {
113 coordArray->GetTuple(i,coords);
114 }
115
116 double radial_length = coords[3] - coords[2];
117
118 // Calculate the amount of change in the arcs based on the shrink
119 // percentage of the arc_length
120 double conversion = vtkMath::Pi()/180.;
121 double arc_length = (conversion*(coords[1] - coords[0])*coords[3]);
122 double radial_shrink = radial_length*this->ShrinkPercentage;
123 double arc_length_shrink;
124 if( radial_shrink > 0.25*arc_length )
125 {
126 arc_length_shrink = 0.25*arc_length;
127 }
128 else
129 {
130 arc_length_shrink = radial_shrink;
131 }
132
133 double arc_length_new = arc_length - arc_length_shrink;
134 double angle_change = ((arc_length_new/coords[3])/conversion);
135 double delta_change_each = 0.5*((coords[1]-coords[0]) - angle_change);
136
137 double inner_radius = coords[2] + (0.5*(radial_length*this->ShrinkPercentage));
138 double outer_radius = coords[3] - (0.5*(radial_length*this->ShrinkPercentage));
139 double start_angle;
140 double end_angle;
141 if( coords[1] - coords[0] == 360. )
142 {
143 start_angle = coords[0];
144 end_angle = coords[1];
145 }
146 else
147 {
148 start_angle = coords[0] + delta_change_each;
149 end_angle = coords[1] - delta_change_each;
150 }
151
152 int num_angles = static_cast<int>(end_angle - start_angle);
153 if ( num_angles < 1 )
154 {
155 num_angles = 1;
156 }
157 int num_points = 2*num_angles + 2;
158 strips->InsertNextCell(num_points);
159 for ( int j = 0; j < num_angles; ++j )
160 {
161 ang = start_angle + j;
162 cos_ang = cos(vtkMath::RadiansFromDegrees(ang));
163 sin_ang = sin(vtkMath::RadiansFromDegrees(ang));
164 pt1x[0] = cos_ang*inner_radius;
165 pt1x[1] = sin_ang*inner_radius;
166 pt2x[0] = cos_ang*outer_radius;
167 pt2x[1] = sin_ang*outer_radius;
168 pt1 = pts->InsertNextPoint(pt1x);
169 pt2 = pts->InsertNextPoint(pt2x);
170 strips->InsertCellPoint(pt1);
171 strips->InsertCellPoint(pt2);
172 }
173 ang = end_angle;
174 cos_ang = cos(vtkMath::RadiansFromDegrees(ang));
175 sin_ang = sin(vtkMath::RadiansFromDegrees(ang));
176 pt1x[0] = cos_ang*inner_radius;
177 pt1x[1] = sin_ang*inner_radius;
178 pt2x[0] = cos_ang*outer_radius;
179 pt2x[1] = sin_ang*outer_radius;
180 pt1 = pts->InsertNextPoint(pt1x);
181 pt2 = pts->InsertNextPoint(pt2x);
182 strips->InsertCellPoint(pt1);
183 strips->InsertCellPoint(pt2);
184
185 if ( i%1000 == 0 )
186 {
187 progress = static_cast<double>(i) / inputTree->GetNumberOfVertices() * 0.8;
188 this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
189 }
190 }
191
192 outputPoly->SetPoints(pts);
193 outputPoly->SetStrips(strips);
194
195 // Pass the input vertex data to the output cell data :)
196 vtkDataSetAttributes* const input_vertex_data = inputTree->GetVertexData();
197 vtkDataSetAttributes* const output_cell_data = outputPoly->GetCellData();
198 output_cell_data->PassData(input_vertex_data);
199
200 return 1;
201 }
202
PrintSelf(ostream & os,vtkIndent indent)203 void vtkTreeRingToPolyData::PrintSelf(ostream& os, vtkIndent indent)
204 {
205 this->Superclass::PrintSelf(os,indent);
206 os << indent << "ShrinkPercentage: " << this->ShrinkPercentage << endl;
207 }
208