Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
InclusionActor.cpp
Go to the documentation of this file.
1/* This file is part of MODEL, the Mechanics Of Defect Evolution Library.
2 *
3 * Copyright (C) 2011 by Giacomo Po <gpo@ucla.edu>.
4 *
5 * model is distributed without any warranty under the
6 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
7 */
8
9#ifndef model_InclusionActor_cpp_
10#define model_InclusionActor_cpp_
11
12#include <Eigen/Dense>
13
14#include <QWidget>
15#include <QGridLayout>
16#include <QCheckBox>
17
18
19#include <vtkVersion.h>
20#include <vtkSmartPointer.h>
21#include <vtkPoints.h>
22#include <vtkPointData.h>
23#include <vtkDoubleArray.h>
24#include <vtkPolyData.h>
25#include <vtkSphereSource.h>
26#include <vtkGlyph3D.h>
27#include <vtkPolyDataMapper.h>
28#include <vtkActor.h>
29#include <vtkUnstructuredGrid.h>
30#include <vtkLookupTable.h>
31#include <vtkPolyhedron.h>
32#include <vtkIdList.h>
33//#include <vtkXMLUnstructuredGridWriter.h>
34#include <InclusionActor.h>
37#include <vtkAppendPolyData.h>
38
39
40// VTK documentation
41// http://vtk.1045678.n5.nabble.com/VTK-slow-to-display-300-vtkSphereSource-in-real-time-td5740730.html
42// http://www.vtk.org/Wiki/VTK/Examples/Cxx/Visualization/Scaleglyph3D
43// http://hiraku0n.blogspot.com/2012/10/writing-scalar-and-vector-field-in-vtk.html
44// http://vtk.1045678.n5.nabble.com/Glyphing-vtkImageData-scalars-3D-as-arrows-td3199837.html
45
46#include <DDqtControls.h>
47
48namespace model
49{
50
52 {
53 std::cout<<"Updating inclusions..."<<std::flush;
54 const auto t0= std::chrono::system_clock::now();
55
56 // Replace the previous frame, including when no ellipsoids remain.
57 vtkNew<vtkPolyData> emptyEllipsoids;
58 ellipsoidalMapper->SetInputData(emptyEllipsoids);
59 vtkNew<vtkAppendPolyData> ellipsoids;
60
61 if(inclusions)
62 {
63
64
65 vtkSmartPointer<vtkPoints> points(vtkSmartPointer<vtkPoints>::New());
66 vtkSmartPointer<vtkFloatArray> diameters(vtkSmartPointer<vtkFloatArray>::New());
67 vtkSmartPointer<vtkFloatArray> colors(vtkSmartPointer<vtkFloatArray>::New());
68 diameters->SetName("diameters");
69 colors->SetName("colors");
70
71 vtkNew<vtkUnstructuredGrid> ugrid;
72 vtkNew<vtkPoints> polyhedronPoints;
73// vtkIdType polyhedronPointsIDs[inclusions->polyhedronInclusionNodes().size()];
74 std::vector<vtkIdType> polyhedronPointsIDs(inclusions->polyhedronInclusionNodes().size());
75 long long k=0;
76 for(const auto& node : inclusions->polyhedronInclusionNodes())
77 {
78 polyhedronPoints->InsertNextPoint(node.second.P.data());
79 polyhedronPointsIDs[k]=k;
80 k++;
81 }
82 ugrid->SetPoints(polyhedronPoints);
83
84
85 for(const auto& inclusion : inclusions->eshelbyInclusions())
86 {
87
88 auto* sphericalDerived = dynamic_cast<SphericalInclusion<dim>*>(inclusion.second.get());
89 if (sphericalDerived)
90 {
91 points->InsertNextPoint(sphericalDerived->C(0), sphericalDerived->C(1), sphericalDerived->C(2));
92 diameters->InsertNextValue(2.0*sphericalDerived->a); // origin of arrow
93 colors->InsertNextValue(sphericalDerived->phaseID);
94 }
95
96 auto* ellipsoidalDerived = dynamic_cast<EllipsoidalInclusion<dim>*>(inclusion.second.get());
97 if(ellipsoidalDerived)
98 {
99 ellipsoids->AddInputData(ellipsoidalInclusionPolyData(
100 ellipsoidalDerived->C,ellipsoidalDerived->axes));
101 }
102
103 auto* polyhedronDerived = dynamic_cast<PolyhedronInclusion<dim>*>(inclusion.second.get());
104 if (polyhedronDerived)
105 {
106// configIO.polyhedronInclusions().emplace_back(*polyhedronDerived);
107
108 vtkNew<vtkIdList> faces;
109// for(const auto& pair2 : pair1.second)
110// {
111// faces->InsertNextId(pair2.second.size());
112// for(const auto& nID : pair2.second)
113// {
114// faces->InsertNextId(nID);
115// }
116// }
117// ugrid->InsertNextCell(VTK_POLYHEDRON, inclusions->polyhedronInclusionNodes().size(), polyhedronPointsIDs, pair1.second.size(), faces->GetPointer(0));
118
119 for(const auto& facePair : polyhedronDerived->faces)
120 {
121 faces->InsertNextId(facePair.second.size());
122
123 for(const auto& vertexPair : facePair.second)
124 {
125 faces->InsertNextId(vertexPair.first);
126 }
127 }
128 ugrid->InsertNextCell(VTK_POLYHEDRON, inclusions->polyhedronInclusionNodes().size(), polyhedronPointsIDs.data(), polyhedronDerived->faces.size(), faces->GetPointer(0));
129
130 }
131 }
132
133// for(const auto& inclusion : configFields.configIO.sphericalInclusions())
134// {
135// points->InsertNextPoint(inclusion.C(0), inclusion.C(1), inclusion.C(2));
136// diameters->InsertNextValue(2.0*inclusion.a); // origin of arrow
137// colors->InsertNextValue(inclusion.phaseID);
138// }
139
140 grid->SetPoints(points);
141 grid->GetPointData()->AddArray(diameters);
142 grid->GetPointData()->SetActiveScalars("diameters"); // to set radius first
143 grid->GetPointData()->AddArray(colors);
144
145// vtkNew<vtkUnstructuredGrid> ugrid;
146// vtkNew<vtkPoints> polyhedronPoints;
147// vtkIdType polyhedronPointsIDs[inclusions->polyhedronInclusionNodes().size()];
148// long long k=0;
149// for(const auto& node : inclusions->polyhedronInclusionNodes())
150// {
151// polyhedronPoints->InsertNextPoint(node.second.P.data());
152// polyhedronPointsIDs[k]=k;
153// k++;
154// }
155// ugrid->SetPoints(polyhedronPoints);
156
157// std::map<size_t,std::map<size_t,std::vector<size_t>>> faces;
158// for(const auto& edge : inclusions->polyhedronInclusionEdges())
159// {
160// const size_t& iID(edge.inclusionID);
161// const size_t& fID(edge.faceID);
162// const size_t& sourceID(edge.sourceID);
163// faces[iID][fID].push_back(sourceID);
164// }
165//
166// for(const auto& pair1 : faces)
167// {
168// vtkNew<vtkIdList> faces;
169// for(const auto& pair2 : pair1.second)
170// {
171// faces->InsertNextId(pair2.second.size());
172// for(const auto& nID : pair2.second)
173// {
174// faces->InsertNextId(nID);
175// }
176// }
177// ugrid->InsertNextCell(VTK_POLYHEDRON, inclusions->polyhedronInclusionNodes().size(), polyhedronPointsIDs, pair1.second.size(), faces->GetPointer(0));
178// }
179
180// polyhedronMapper->SetInputData(polyhedronPoints->GetOutputPort());
181 polyhedronMapper->SetInputData(ugrid);
182 if(ellipsoids->GetNumberOfInputConnections(0)>0)
183 {
184 ellipsoids->Update();
185 ellipsoidalMapper->SetInputData(ellipsoids->GetOutput());
186 }
187
188 }
189 std::cout<<magentaColor<<" ["<<(std::chrono::duration<double>(std::chrono::system_clock::now()-t0)).count()<<" sec]"<<defaultColor<<std::endl;
190 }
191
192 InclusionActor::InclusionActor(vtkGenericOpenGLRenderWindow* const renWin,vtkRenderer* const renderer,const DefectiveCrystal<3>& defectiveCrystal_in) :
193 /* init */ renderWindow(renWin)
194 /* init */,mainLayout(new QGridLayout(this))
195 /* init */,showInclusions(new QCheckBox(this))
196 /* init */,sliderInclusionOpacity(new QSlider(this))
197 /* init */,grid(vtkSmartPointer<vtkUnstructuredGrid>::New())
198 /* init */,sphereSource(vtkSmartPointer<vtkSphereSource>::New())
199 /* init */,glyph3D(vtkSmartPointer<vtkGlyph3D>::New())
200 /* init */,mapper(vtkSmartPointer<vtkPolyDataMapper>::New())
201 /* init */,actor(vtkSmartPointer<vtkActor>::New())
202 /* init */,lookUpColors(vtkSmartPointer<vtkLookupTable>::New())
203 /* init */,ellipsoidalMapper(vtkSmartPointer<vtkPolyDataMapper>::New())
204 /* init */,ellipsoidalActor(vtkSmartPointer<vtkActor>::New())
205 /* init */,polyhedronMapper(vtkSmartPointer<vtkDataSetMapper>::New())
206 /* init */,polyhedronActor(vtkSmartPointer<vtkActor>::New())
207 /* init */,defectiveCrystal(defectiveCrystal_in)
208 /* init */,inclusions(defectiveCrystal.template getUniqueTypedMicrostructure<InclusionMicrostructure<3>>())
209 {
210 showInclusions->setChecked(true);
211 showInclusions->setText("show inclusions");
212 auto *inclusionBox =
213 controls::box("Inclusions", this, "Show spherical, ellipsoidal and polyhedral inclusions.", showInclusions);
214 mainLayout->addWidget(inclusionBox, 0, 0);
215 mainLayout->setRowStretch(1, 1);
216 this->setLayout(mainLayout);
217 connect(showInclusions,SIGNAL(stateChanged(int)), this, SLOT(modify()));
218
219 sliderInclusionOpacity->setMinimum(0);
220 sliderInclusionOpacity->setMaximum(10);
221 sliderInclusionOpacity->setValue(5);
222 sliderInclusionOpacity->setOrientation(Qt::Horizontal);
223 connect(sliderInclusionOpacity,SIGNAL(valueChanged(int)), this, SLOT(modify()));
224 controls::field(controls::grid(inclusionBox), 0, "Opacity", sliderInclusionOpacity,
225 "Set inclusion opacity from transparent (0) to opaque (10).");
226
227 sphereSource->SetPhiResolution(20);
228 sphereSource->SetThetaResolution(20);
229 glyph3D->SetInputData(grid);
230 glyph3D->SetSourceConnection(sphereSource->GetOutputPort());
231 mapper->SetInputConnection(glyph3D->GetOutputPort());
232 mapper->ScalarVisibilityOff();
233 actor->GetProperty()->SetColor(0.5,0.5,0.5); // Give some color to the mesh. (1,1,1) is white
234 actor->GetProperty()->SetOpacity(0.4); // Give some color to the mesh. (1,1,1) is white
235 actor->SetMapper(mapper);
236
237 ellipsoidalMapper->ScalarVisibilityOff();
238 vtkNew<vtkPolyData> emptyEllipsoids;
239 ellipsoidalMapper->SetInputData(emptyEllipsoids);
240 ellipsoidalActor->SetMapper(ellipsoidalMapper);
241 ellipsoidalActor->GetProperty()->SetColor(0.5,0.5,0.5);
242 ellipsoidalActor->GetProperty()->SetOpacity(0.4);
243
244 // The actor also exists when inclusion physics is absent. VTK requires
245 // a dataset even when there is no geometry to display.
246 vtkNew<vtkUnstructuredGrid> emptyPolyhedra;
247 polyhedronMapper->SetInputData(emptyPolyhedra);
248 polyhedronActor->SetMapper(polyhedronMapper);
249 polyhedronActor->GetProperty()->SetColor(0.5,0.5,0.5); // Give some color to the mesh. (1,1,1) is white
250 polyhedronActor->GetProperty()->SetOpacity(0.4); // Give some color to the mesh. (1,1,1) is white
251
252 renderer->AddActor(actor);
253 renderer->AddActor(ellipsoidalActor);
254 renderer->AddActor(polyhedronActor);
255 }
256
257 void InclusionActor::modify()
258 {
259 actor->SetVisibility(showInclusions->isChecked());
260 actor->GetProperty()->SetOpacity(sliderInclusionOpacity->value()/10.0);
261
262 ellipsoidalActor->SetVisibility(showInclusions->isChecked());
263 ellipsoidalActor->GetProperty()->SetOpacity(sliderInclusionOpacity->value()/10.0);
264
265 polyhedronActor->SetVisibility(showInclusions->isChecked());
266 polyhedronActor->GetProperty()->SetOpacity(sliderInclusionOpacity->value()/10.0);
267
268
269 renderWindow->Render();
270 }
271
272}
273#endif
QGridLayout * grid(QGroupBox *group)
QGroupBox * box(const QString &title, QWidget *parent, const QString &description, QCheckBox *toggle=nullptr)
void field(QGridLayout *layout, int row, const QString &title, QWidget *input, const QString &description)
size_t InstanceCount< Derived >::count
static std::string magentaColor
vtkSmartPointer< vtkPolyData > ellipsoidalInclusionPolyData(const Eigen::Vector3d &center, const Eigen::Matrix3d &axes)
static std::string defaultColor
const std::shared_ptr< InclusionMicrostructure< 3 > > inclusions
InclusionActor(vtkGenericOpenGLRenderWindow *const, vtkRenderer *const, const DefectiveCrystal< 3 > &configFields_in)
const DefectiveCrystal< 3 > & defectiveCrystal
REAL t0
int k