Skip to content
Snippets Groups Projects
Select Git revision
  • 6b9fddae10ca15fa03b711122ce6376d33592ec0
  • master default protected
  • hierarchical-basis
  • alphashapes
  • bl
  • relaying
  • new_export_boris
  • oras_vs_osm
  • reassign_partitions
  • distributed_fwi
  • rename-classes
  • fix/fortran-api-example-t4
  • robust_partitions
  • reducing_files
  • fix_overlaps
  • 3115-issue-fix
  • 3023-Fillet2D-Update
  • convert_fdivs
  • tmp_jcjc24
  • fixedMeshIF
  • save_edges
  • gmsh_4_14_0
  • gmsh_4_13_1
  • gmsh_4_13_0
  • gmsh_4_12_2
  • gmsh_4_12_1
  • gmsh_4_12_0
  • gmsh_4_11_1
  • gmsh_4_11_0
  • gmsh_4_10_5
  • gmsh_4_10_4
  • gmsh_4_10_3
  • gmsh_4_10_2
  • gmsh_4_10_1
  • gmsh_4_10_0
  • gmsh_4_9_5
  • gmsh_4_9_4
  • gmsh_4_9_3
  • gmsh_4_9_2
  • gmsh_4_9_1
  • gmsh_4_9_0
41 results

PView.cpp

Blame
  • PView.cpp 11.40 KiB
    // Gmsh - Copyright (C) 1997-2019 C. Geuzaine, J.-F. Remacle
    //
    // See the LICENSE.txt file for license information. Please report all
    // issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
    
    #include <string.h>
    #include <algorithm>
    #include "PView.h"
    #include "PViewDataList.h"
    #include "PViewDataGModel.h"
    #include "PViewOptions.h"
    #include "VertexArray.h"
    #include "SmoothData.h"
    #include "adaptiveData.h"
    #include "GmshMessage.h"
    
    int PView::_globalTag = 0;
    std::vector<PView *> PView::list;
    
    void PView::_init(int tag)
    {
      if(tag >= 0) {
        _tag = tag;
        _globalTag = std::max(_globalTag, _tag) + 1;
      }
      else {
        _tag = _globalTag++;
      }
    
      _changed = true;
      _aliasOf = -1;
      _eye = SPoint3(0., 0., 0.);
      va_points = va_lines = va_triangles = va_vectors = va_ellipses = 0;
      normals = 0;
    
      for(std::size_t i = 0; i < list.size(); i++) {
        if(list[i]->getTag() == _tag) {
          // in normal operation this should not happen, but we allow it when
          // programmatically forcing view tags (e.g. when using the views from
          // within getdp's post-processing operations); this is dangerous, as it
          // breaks aliases
          Msg::Info("Removing existing View[%d] (tag = %d)", i, _tag);
          delete list[i]; // warning: this changes the list
        }
      }
    
      list.push_back(this);
      for(std::size_t i = 0; i < list.size(); i++) list[i]->setIndex(i);
    }
    
    PView::PView(int tag)
    {
      _init(tag);
      _data = new PViewDataList();
      _options = new PViewOptions(*PViewOptions::reference());
      if(_options->adaptVisualizationGrid)
        _data->initAdaptiveData(_options->timeStep, _options->maxRecursionLevel,
                                _options->targetError);
    }
    
    PView::PView(PViewData *data, int tag)
    {
      _init(tag);
      _data = data;
      _options = new PViewOptions(*PViewOptions::reference());
      if(_options->adaptVisualizationGrid)
        _data->initAdaptiveData(_options->timeStep, _options->maxRecursionLevel,
                                _options->targetError);
    }
    
    PView::PView(PView *ref, bool copyOptions, int tag)
    {
      _init(tag);
    
      if(ref->getAliasOf() >= 0) { // alias of an alias
        PView *orig = getViewByTag(ref->getAliasOf());
        if(orig)
          _aliasOf = orig->getTag();
        else {
          Msg::Warning("Original view for alias does not exist anymore");
          _aliasOf = ref->getTag();
        }
      }
      else
        _aliasOf = ref->getTag();
    
      _data = ref->getData();
      if(copyOptions)
        _options = new PViewOptions(*ref->getOptions());
      else
        _options = new PViewOptions(*PViewOptions::reference());
      if(_options->adaptVisualizationGrid)
        _data->initAdaptiveData(_options->timeStep, _options->maxRecursionLevel,
                                _options->targetError);
    }
    
    PView::PView(const std::string &xname, const std::string &yname,
                 std::vector<double> &x, std::vector<double> &y)
    {
      _init();
      _data = new PViewDataList();
      _data->setXY(x, y);
      _data->setName(yname);
      _data->setFileName(yname + ".pos");
      _options = new PViewOptions(*PViewOptions::reference());
      _options->type = PViewOptions::Plot2D;
      _options->axes = 3;
      _options->lineWidth = 2.;
      _options->pointSize = 4.;
      _options->axesLabel[0] = xname;
    }
    
    PView::PView(const std::string &name, std::vector<double> &x,
                 std::vector<double> &y, std::vector<double> &z,
                 std::vector<double> &v)
    {
      _init();
      _data = new PViewDataList();
      _data->setXYZV(x, y, z, v);
      _data->setName(name);
      _data->setFileName(name + ".pos");
      _options = new PViewOptions(*PViewOptions::reference());
      _options->axes = 3;
      _options->pointSize = 7.;
      _options->pointType = 1.;
    }
    
    PView::PView(const std::string &name, const std::string &type, GModel *model,
                 std::map<int, std::vector<double> > &data, double time,
                 int numComp, int tag)
    {
      _init(tag);
      PViewDataGModel::DataType t;
      if(type == "NodeData")
        t = PViewDataGModel::NodeData;
      else if(type == "ElementData")
        t = PViewDataGModel::ElementData;
      else if(type == "ElementNodeData")
        t = PViewDataGModel::ElementNodeData;
      else if(type == "Beam")
        t = PViewDataGModel::BeamData;
      else {
        Msg::Error("Unknown type of view to create '%s'", type.c_str());
        return;
      }
      PViewDataGModel *d = new PViewDataGModel(t);
      d->addData(model, data, 0, time, 1, numComp);
      d->setName(name);
      d->setFileName(name + ".msh");
      _data = d;
      _options = new PViewOptions(*PViewOptions::reference());
      if(_options->adaptVisualizationGrid)
        _data->initAdaptiveData(_options->timeStep, _options->maxRecursionLevel,
                                _options->targetError);
    }
    
    void PView::addStep(GModel *model,
                        const std::map<int, std::vector<double> > &data,
                        double time, int numComp)
    {
      PViewDataGModel *d = dynamic_cast<PViewDataGModel *>(_data);
      if(d)
        d->addData(model, data, d->getNumTimeSteps(), time, 1, numComp);
      else
        Msg::Error("Can only add step data to mesh-based datasets");
    }
    
    PView::~PView()
    {
      deleteVertexArrays();
      if(normals) delete normals;
      if(_options) delete _options;
    
      std::vector<PView *>::iterator it = std::find(list.begin(), list.end(), this);
      if(it != list.end()) list.erase(it);
      for(std::size_t i = 0; i < list.size(); i++) list[i]->setIndex(i);
    
      if(!_data) return;
    
      // do not delete if another view is an alias of this one
      for(std::size_t i = 0; i < list.size(); i++)
        if(list[i]->getAliasOf() == _tag) return;
    
      // do not delete if this view is an alias and 1) if the original
      // still exists, or 2) if there are other aliases to the same view
      if(_aliasOf >= 0)
        for(std::size_t i = 0; i < list.size(); i++)
          if(list[i]->getTag() == _aliasOf || list[i]->getAliasOf() == _aliasOf)
            return;
    
      Msg::Debug("Deleting data in View[%d] (tag = %d)", _index, _tag);
      delete _data;
    }
    
    int PView::getGlobalTag() { return _globalTag; }
    
    void PView::setGlobalTag(int tag) { _globalTag = tag; }
    
    void PView::deleteVertexArrays()
    {
      if(va_points) delete va_points;
      va_points = 0;
      if(va_lines) delete va_lines;
      va_lines = 0;
      if(va_triangles) delete va_triangles;
      va_triangles = 0;
      if(va_vectors) delete va_vectors;
      va_vectors = 0;
      if(va_ellipses) delete va_ellipses;
      va_ellipses = 0;
    }
    
    void PView::setOptions(PViewOptions *val)
    {
      // deep copy options
      if(val)
        *_options = *val;
      else if(_options)
        *_options = *PViewOptions::reference();
    }
    
    PViewData *PView::getData(bool useAdaptiveIfAvailable)
    {
      if(useAdaptiveIfAvailable && _data->getAdaptiveData() && !_data->isRemote())
        return _data->getAdaptiveData()->getData();
      else
        return _data;
    }
    
    void PView::setChanged(bool val)
    {
      _changed = val;
      // reset the eye position everytime we change the view so that the
      // arrays get resorted for transparency
      if(_changed) _eye = SPoint3(0., 0., 0.);
    }
    
    void PView::combine(bool time, int how, bool remove)
    {
      // time == true: combine the timesteps (oherwise combine the elements)
      // how == 0: try to combine all visible views
      //        1: try to combine all views
      //        2: try to combine all views having identical names
    
      std::vector<nameData> nds;
      for(std::size_t i = 0; i < list.size(); i++) {
        PView *p = list[i];
        PViewData *data = p->getData();
        if(how || p->getOptions()->visible) {
          nameData nd;
          // this will lead to weird results if there are views named
          // "__all__" or "__vis__" :-)
          if(how == 2)
            nd.name = data->getName();
          else if(how == 1)
            nd.name = "__all__";
          else
            nd.name = "__vis__";
          std::size_t j = 0;
          while(j < nds.size()) {
            if(nds[j].name == nd.name) {
              nds[j].data.push_back(data);
              nds[j].indices.push_back(i);
              break;
            }
            j++;
          }
          if(j == nds.size()) {
            nd.data.push_back(data);
            nd.indices.push_back(i);
            nds.push_back(nd);
          }
        }
      }
    
      std::set<PView *> rm;
      for(std::size_t i = 0; i < nds.size(); i++) {
        if(nds[i].data.size() > 1) { // there's potentially something to combine
          // sanity checks:
          bool allListBased = true, allModelBased = true;
          for(std::size_t j = 0; j < nds[i].data.size(); j++) {
            PViewDataList *d1 = dynamic_cast<PViewDataList *>(nds[i].data[j]);
            if(!d1) allListBased = false;
            PViewDataGModel *d2 = dynamic_cast<PViewDataGModel *>(nds[i].data[j]);
            if(!d2) allModelBased = false;
          }
          PViewData *data = 0;
          if(allListBased) {
            data = new PViewDataList();
          }
          else if(allModelBased) {
            PViewDataGModel *d2 = dynamic_cast<PViewDataGModel *>(nds[i].data[0]);
            data = new PViewDataGModel(d2->getType());
          }
          else {
            Msg::Error("Cannot combine hybrid list/mesh-based datasets");
            continue;
          }
          PView *p = new PView(data);
          bool res = time ? data->combineTime(nds[i]) : data->combineSpace(nds[i]);
          if(res) {
            for(std::size_t j = 0; j < nds[i].indices.size(); j++)
              rm.insert(list[nds[i].indices[j]]);
            PViewOptions *opt = p->getOptions();
            if(opt->adaptVisualizationGrid) {
              // the (empty) adaptive data created in PView() must be
              // recreated, since we added some data
              data->destroyAdaptiveData();
              data->initAdaptiveData(opt->timeStep, opt->maxRecursionLevel,
                                     opt->targetError);
            }
          }
          else
            delete p;
        }
      }
      if(remove)
        for(std::set<PView *>::iterator it = rm.begin(); it != rm.end(); it++)
          delete *it;
    }
    
    class PViewLessThanName {
    public:
      bool operator()(PView *v1, PView *v2) const
      {
        return v1->getData()->getName() < v2->getData()->getName();
      }
    };
    
    void PView::sortByName()
    {
      std::sort(list.begin(), list.end(), PViewLessThanName());
      for(std::size_t i = 0; i < list.size(); i++) list[i]->setIndex(i);
    }
    
    PView *PView::getViewByName(const std::string &name, int timeStep,
                                int partition, const std::string &fileName)
    {
      // search views from most recently to least recently added
      for(int i = list.size() - 1; i >= 0; i--) {
        if(list[i]->getData()->getName() == name &&
           ((timeStep < 0 || !list[i]->getData()->hasTimeStep(timeStep)) ||
            (partition < 0 ||
             !list[i]->getData()->hasPartition(timeStep, partition))) &&
           (fileName.empty() || !list[i]->getData()->hasFileName(fileName)))
          return list[i];
      }
      return 0;
    }
    
    PView *PView::getViewByFileName(const std::string &fileName, int timeStep,
                                    int partition)
    {
      // search views from most recently to least recently added
      for(int i = list.size() - 1; i >= 0; i--) {
        if(list[i]->getData()->getFileName() == fileName &&
           ((timeStep < 0 || !list[i]->getData()->hasTimeStep(timeStep)) ||
            (partition < 0 ||
             !list[i]->getData()->hasPartition(timeStep, partition))))
          return list[i];
      }
      return 0;
    }
    
    PView *PView::getViewByTag(int tag, int timeStep, int partition)
    {
      for(std::size_t i = 0; i < list.size(); i++) {
        if(list[i]->getTag() == tag &&
           ((timeStep < 0 || !list[i]->getData()->hasTimeStep(timeStep)) ||
            (partition < 0 ||
             !list[i]->getData()->hasPartition(timeStep, partition))))
          return list[i];
      }
      return 0;
    }
    
    double PView::getMemoryInMb()
    {
      double mem = 0;
      if(va_points) mem += va_points->getMemoryInMb();
      if(va_lines) mem += va_lines->getMemoryInMb();
      if(va_triangles) mem += va_triangles->getMemoryInMb();
      if(va_vectors) mem += va_vectors->getMemoryInMb();
      if(va_ellipses) mem += va_ellipses->getMemoryInMb();
      mem += getData()->getMemoryInMb();
      return mem;
    }