![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raúl D. D. Farfan * 00004 * * 00005 * This program is free software: you can redistribute it and/or modify * 00006 * it under the terms of the GNU General Public License as published by * 00007 * the Free Software Foundation, either version 3 of the License, or * 00008 * any later version. * 00009 * * 00010 * This program is distributed in the hope that it will be useful, * 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00013 * GNU General Public License for more details. * 00014 * * 00015 * You should have received a copy of the GNU General Public License * 00016 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00017 ************************************************************************/ 00018 00019 // VTK 00020 #include <vtkPolygon.h> 00021 00022 // MechSys 00023 #include <mechsys/dem/domain.h> 00024 #include <mechsys/vtk/sphere.h> 00025 #include <mechsys/vtk/cylinder.h> 00026 #include <mechsys/vtk/ugrid.h> 00027 #include <mechsys/vtk/win.h> 00028 00029 class Visualise 00030 { 00031 public: 00032 // Constuctor & Destructor 00033 Visualise (DEM::Domain const & Dom, Array<int> const & TagParts, Array<int> const & TagWalls, bool ShowVert=false, bool ShowEdge=false, int ThRes=12, int PhiRes=12, int CylRes=12); 00034 ~Visualise (); 00035 00036 // Methods 00037 void Update (); 00038 void AddTo (VTK::Win & win); 00039 00040 // Data 00041 DEM::Domain const & Dom; // domain 00042 Array<int> TagParts; // tag of particles 00043 Array<int> TagWalls; // tag of walls 00044 bool ShowVert; // show all vertices of particles 00045 bool ShowEdge; // show all edges of particles 00046 String PartColor; // color of particles 00047 String WallColor; // color of walls 00048 double PartOpacity; // opacity of particles 00049 double WallOpacity; // opacity of walls 00050 00051 // Spherical particles 00052 Array<VTK::Sphere*> SphParts; // spherical particles 00053 00054 // Complex particles 00055 Array<VTK::Sphere*> PartVerts; // particles: spheres 00056 Array<VTK::Cylinder*> PartEdges; // particles: cylinders 00057 UGrid PartFaces; // particles: all faces of particles (inner/outer) 00058 00059 // Walls 00060 Array<VTK::Sphere*> WallVerts; // walls: spheres 00061 Array<VTK::Cylinder*> WallEdges; // walls: cylinders 00062 UGrid WallFaces; // walls: faces 00063 }; 00064 00065 00067 00068 00069 inline Visualise::Visualise (DEM::Domain const & D, Array<int> const & TPs, Array<int> const & TWs, bool SV, bool SE, int ThRes, int PhiRes, int CylRes) 00070 : Dom (D), 00071 ShowVert (SV), 00072 ShowEdge (SE), 00073 PartColor ("brown"), 00074 WallColor ("peacock"), 00075 PartOpacity (1.0), 00076 WallOpacity (0.1) 00077 { 00078 TagParts = TPs; 00079 TagWalls = TWs; 00080 00081 PartFaces.SetColor (PartColor.CStr(), PartOpacity); 00082 WallFaces.SetColor (WallColor.CStr(), WallOpacity); 00083 00084 for (size_t i=0; i<Dom.Particles.Size(); ++i) 00085 { 00086 Particle & p = (*Dom.Particles[i]); 00087 00088 // spherical particles 00089 if (p.Edges.Size()==0 && p.Faces.Size()==0) 00090 { 00091 SphParts.Push (new VTK::Sphere(p.x, p.Props.R, ThRes, PhiRes)); 00092 SphParts[SphParts.Size()-1]->SetColor (PartColor.CStr(), PartOpacity); 00093 } 00094 00095 else 00096 { 00097 // complex particles 00098 if (TagParts.Has(p.Tag)) 00099 { 00100 // spheres 00101 if (ShowVert) 00102 { 00103 for (size_t j=0; j<p.Verts.Size(); ++j) 00104 { 00105 PartVerts.Push (new VTK::Sphere((*p.Verts[j]), p.Props.R, ThRes, PhiRes)); 00106 PartVerts.Last () -> SetColor (PartColor.CStr(), PartOpacity); 00107 } 00108 } 00109 00110 // only edges 00111 if (p.Faces.Size()==0 || ShowEdge) 00112 { 00113 for (size_t j=0; j<p.Edges.Size(); ++j) 00114 { 00115 PartEdges.Push (new VTK::Cylinder((*p.Edges[j]->X0), (*p.Edges[j]->X1), p.Props.R, /*cap*/true, CylRes)); 00116 PartEdges.Last () -> SetColor (PartColor.CStr(), PartOpacity); 00117 } 00118 } 00119 00120 // faces 00121 for (size_t j=0; j<p.Faces.Size(); ++j) 00122 { 00123 Face & f = (*p.Faces[j]); 00124 vtkPolygon * pl = vtkPolygon::New(); 00125 pl->GetPointIds()->SetNumberOfIds (f.Edges.Size()); 00126 for (size_t k=0; k<f.Edges.Size(); ++k) 00127 { 00128 Edge & e = (*f.Edges[k]); 00129 int idx = PartFaces.InsertNextPoint ((*e.X0)(0), (*e.X0)(1), (*e.X0)(2)); 00130 pl->GetPointIds()->SetId (k, idx); 00131 } 00132 PartFaces.InsertNextCell (pl->GetCellType(), pl->GetPointIds()); 00133 pl->Delete(); 00134 } 00135 } 00136 00137 // walls 00138 else if (TagWalls.Has(p.Tag)) 00139 { 00140 /* 00141 for (size_t j=0; j<p.Verts.Size(); ++j) 00142 { 00143 WallVerts.Push (new VTK::Sphere((*p.Verts[j]), p.Props.R, ThRes, PhiRes)); 00144 WallVerts.Last () -> SetColor (WallColor.CStr(), WallOpacity); 00145 } 00146 00147 for (size_t j=0; j<p.Edges.Size(); ++j) 00148 { 00149 WallEdges.Push (new VTK::Cylinder((*p.Edges[j]->X0), (*p.Edges[j]->X1), p.Props.R, false, CylRes)); 00150 WallEdges.Last () -> SetColor (WallColor.CStr(), WallOpacity); 00151 } 00152 */ 00153 00154 for (size_t j=0; j<p.Faces.Size(); ++j) 00155 { 00156 Face & f = (*p.Faces[j]); 00157 Vec3_t n = cross(f.Edges[0]->dL, f.Edges[1]->dL); 00158 n = n/norm(n); 00159 vtkPolygon * pi = vtkPolygon::New(); 00160 vtkPolygon * po = vtkPolygon::New(); 00161 pi->GetPointIds()->SetNumberOfIds (f.Edges.Size()); 00162 po->GetPointIds()->SetNumberOfIds (f.Edges.Size()); 00163 for (size_t k=0; k<f.Edges.Size(); ++k) 00164 { 00165 Edge & e = (*f.Edges[k]); 00166 Vec3_t vi((*e.X0) - p.Props.R*n); 00167 Vec3_t vo((*e.X0) + p.Props.R*n); 00168 int idx_i = WallFaces.InsertNextPoint (vi(0), vi(1), vi(2)); 00169 int idx_o = WallFaces.InsertNextPoint (vo(0), vo(1), vo(2)); 00170 pi->GetPointIds()->SetId (k, idx_i); 00171 po->GetPointIds()->SetId (k, idx_o); 00172 } 00173 WallFaces.InsertNextCell (pi->GetCellType(), pi->GetPointIds()); 00174 WallFaces.InsertNextCell (po->GetCellType(), po->GetPointIds()); 00175 pi->Delete(); 00176 po->Delete(); 00177 } 00178 } 00179 00180 // unknown particle 00181 else throw new Fatal("Visualise::Visualise: Unknow particle: Tag = %d",p.Tag); 00182 } 00183 } 00184 } 00185 00186 inline void Visualise::Update () 00187 { 00188 //Array<VTK::Sphere*> * vts; // current vertices 00189 //Array<VTK::Cylinder*> * eds; // current edges 00190 //UGrid * fcs; // current faces 00191 00192 // spherical particles 00193 size_t i_sph_part = 0; // index of spherical particle 00194 00195 // complex particles 00196 size_t i_part_vert = 0; // index of particle vertex 00197 size_t i_part_edge = 0; // index of particle edge 00198 size_t i_part_face_point = 0; // index of particle point at face 00199 00200 // walls 00201 //size_t i_wall_vert = 0; // index of wall vertex 00202 //size_t i_wall_edge = 0; // index of wall edge 00203 size_t i_wall_face_point = 0; // index of wall point at face 00204 00205 for (size_t i=0; i<Dom.Particles.Size(); ++i) 00206 { 00207 Particle & p = (*Dom.Particles[i]); 00208 00209 // spherical particles 00210 if (p.Edges.Size()==0 && p.Faces.Size()==0) 00211 { 00212 SphParts[i_sph_part]->SetCenter (p.x); 00213 i_sph_part++; 00214 } 00215 00216 else 00217 { 00218 // complex particles 00219 if (TagParts.Has(p.Tag)) 00220 { 00221 // spheres 00222 if (ShowVert) 00223 { 00224 for (size_t j=0; j<p.Verts.Size(); ++j) 00225 { 00226 PartVerts[i_part_vert]->SetCenter ((*p.Verts[j])); 00227 i_part_vert++; 00228 } 00229 } 00230 00231 // only edges 00232 if (p.Faces.Size()==0 || ShowEdge) 00233 { 00234 for (size_t j=0; j<p.Edges.Size(); ++j) 00235 { 00236 PartEdges[i_part_edge]->SetPoints ((*p.Edges[j]->X0), (*p.Edges[j]->X1)); 00237 i_part_edge++; 00238 } 00239 } 00240 00241 // faces 00242 for (size_t j=0; j<p.Faces.Size(); ++j) 00243 { 00244 Face & f = (*p.Faces[j]); 00245 for (size_t k=0; k<f.Edges.Size(); ++k) 00246 { 00247 Edge & e = (*f.Edges[k]); 00248 PartFaces.SetPoint (i_part_face_point, (*e.X0)(0), (*e.X0)(1), (*e.X0)(2)); 00249 i_part_face_point++; 00250 } 00251 } 00252 } 00253 00254 // walls 00255 else if (TagWalls.Has(p.Tag)) 00256 { 00257 /* 00258 for (size_t j=0; j<p.Verts.Size(); ++j) 00259 { 00260 WallVerts[i_wall_vert]->SetCenter ((*p.Verts[j])); 00261 i_wall_vert++; 00262 } 00263 00264 for (size_t j=0; j<p.Edges.Size(); ++j) 00265 { 00266 WallEdges[i_wall_edge]->SetPoints ((*p.Edges[j]->X0), (*p.Edges[j]->X1)); 00267 i_wall_edge++; 00268 } 00269 */ 00270 00271 for (size_t j=0; j<p.Faces.Size(); ++j) 00272 { 00273 Face & f = (*p.Faces[j]); 00274 Vec3_t n = cross(f.Edges[0]->dL, f.Edges[1]->dL); 00275 n = n/norm(n); 00276 for (size_t k=0; k<f.Edges.Size(); ++k) 00277 { 00278 Edge & e = (*f.Edges[k]); 00279 Vec3_t vi((*e.X0) - p.Props.R*n); 00280 Vec3_t vo((*e.X0) + p.Props.R*n); 00281 WallFaces.SetPoint (i_wall_face_point++, vi(0), vi(1), vi(2)); 00282 WallFaces.SetPoint (i_wall_face_point++, vo(0), vo(1), vo(2)); 00283 } 00284 } 00285 } 00286 } 00287 } 00288 00289 PartFaces.Modified(); 00290 WallFaces.Modified(); 00291 } 00292 00293 inline Visualise::~Visualise () 00294 { 00295 for (size_t i=0; i<SphParts .Size(); ++i) delete SphParts [i]; 00296 for (size_t i=0; i<PartVerts.Size(); ++i) delete PartVerts[i]; 00297 for (size_t i=0; i<PartEdges.Size(); ++i) delete PartEdges[i]; 00298 for (size_t i=0; i<WallVerts.Size(); ++i) delete WallVerts[i]; 00299 for (size_t i=0; i<WallEdges.Size(); ++i) delete WallEdges[i]; 00300 } 00301 00302 inline void Visualise::AddTo (VTK::Win & win) 00303 { 00304 PartFaces.AddTo (win); 00305 WallFaces.AddTo (win); 00306 for (size_t i=0; i<SphParts .Size(); ++i) SphParts [i]->AddTo (win); 00307 for (size_t i=0; i<PartVerts.Size(); ++i) PartVerts[i]->AddTo (win); 00308 for (size_t i=0; i<PartEdges.Size(); ++i) PartEdges[i]->AddTo (win); 00309 for (size_t i=0; i<WallVerts.Size(); ++i) WallVerts[i]->AddTo (win); 00310 for (size_t i=0; i<WallEdges.Size(); ++i) WallEdges[i]->AddTo (win); 00311 }