MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/dem/visualise.h
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines