Qt&Vtk-020-GraphItem

举报
DreamLife 发表于 2022/04/15 00:51:03 2022/04/15
【摘要】 ​ 摘要 文章目录 1 官方示例展示2 代码搬运2.1 graphitem.h2.2 graphitem.cpp2.3 vtkContextItem.h2.4 vtkContextItem....

头图

​ 摘要

1 官方示例展示

前面有好几个例子有点复杂,现在还搞不到定,先搬运下这个。下图是官方的示例。

在这里插入图片描述

有个比较尴尬的是发生了,就是官方的Demo现在也不能演示了,没有内容了,直接给我白屏了。

2 代码搬运

2.1 graphitem.h

#include "graphitem.h"
#include "ui_graphitem.h"

GraphItem::GraphItem(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::GraphItem)
{
    ui->setupUi(this);

    mview = vtkSmartPointer<vtkContextView>::New();
    mview->GetRenderer()->SetBackground(0.0, 1.0, 1.0);
    mview->GetRenderWindow()->SetSize(800, 600);

    source = vtkSmartPointer<vtkRandomGraphSource>::New();
    source->SetNumberOfVertices(100);
    source->SetNumberOfEdges(0);
    source->StartWithTreeOn();
    source->Update();
    item = vtkSmartPointer<vtkGraphItem>::New();
    item->SetGraph(source->GetOutput());
    mview->GetScene()->AddItem(item);

    anim = vtkSmartPointer<GraphAnimate>::New();

    anim->view = mview;
    anim->GraphItem = item;
    mview->SetRenderWindow(ui->widget->GetRenderWindow());
    mview->GetRenderWindow()->GetInteractor()->Initialize();
    mview->GetRenderWindow()->GetInteractor()->CreateOneShotTimer(10);
    mview->GetRenderWindow()->GetInteractor()->AddObserver(vtkCommand::TimerEvent, anim);



}

GraphItem::~GraphItem()
{
    delete ui;
}

void GraphItem::startinteractor()
{
    //    view->GetRenderWindow()->GetInteractor()->Start();
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

2.2 graphitem.cpp

#include "graphitem.h"
#include "ui_graphitem.h"

GraphItem::GraphItem(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::GraphItem)
{
    ui->setupUi(this);

    mview = vtkSmartPointer<vtkContextView>::New();
    mview->GetRenderer()->SetBackground(0.0, 1.0, 1.0);
    mview->GetRenderWindow()->SetSize(800, 600);

    source = vtkSmartPointer<vtkRandomGraphSource>::New();
    source->SetNumberOfVertices(100);
    source->SetNumberOfEdges(0);
    source->StartWithTreeOn();
    source->Update();
    item = vtkSmartPointer<vtkGraphItem>::New();
    item->SetGraph(source->GetOutput());
    mview->GetScene()->AddItem(item);

    anim = vtkSmartPointer<GraphAnimate>::New();

    anim->view = mview;
    anim->GraphItem = item;
    mview->SetRenderWindow(ui->widget->GetRenderWindow());
    mview->GetRenderWindow()->GetInteractor()->Initialize();
    mview->GetRenderWindow()->GetInteractor()->CreateOneShotTimer(10);
    mview->GetRenderWindow()->GetInteractor()->AddObserver(vtkCommand::TimerEvent, anim);



}

GraphItem::~GraphItem()
{
    delete ui;
}

void GraphItem::startinteractor()
{
    //    view->GetRenderWindow()->GetInteractor()->Start();
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

2.3 vtkContextItem.h

#ifndef VTKGRAPHITEM_H
#define VTKGRAPHITEM_H


#include "vtkContextItem.h"

#include "vtkEdgeListIterator.h"
#include "vtkOutEdgeIterator.h"
#include "vtkGraph.h"
#include "vtkMinimalStandardRandomSequence.h"
#include "vtkVariant.h"

#include "vtkContext2D.h"
#include "vtkContextScene.h"
#include "vtkContextMouseEvent.h"
#include "vtkPen.h"
#include "vtkBrush.h"
#include "vtkTextProperty.h"
#include "vtkTransform2D.h"


#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"

#include "utility"
#include "vector"

class vtkContext2D;
class vtkGraph;


class vtkGraphItem : public vtkContextItem
{

public:
    vtkTypeMacro(vtkGraphItem,vtkContextItem);
    void PrintSelf(ostream &os, vtkIndent indent) override;
    static vtkGraphItem *New();
    vtkGetObjectMacro(Graph,vtkGraph);
    virtual void SetGraph(vtkGraph* g);


    bool Paint(vtkContext2D *painter) override;

    bool Hit(const vtkContextMouseEvent &mouse)override;

    bool MouseEnterEvent(const vtkContextMouseEvent &mouse)override;

    bool MouseMoveEvent(const vtkContextMouseEvent &mouse)override;

    bool MouseLeaveEvent(const vtkContextMouseEvent &mouse)override;

    bool MouseButtonPressEvent(const vtkContextMouseEvent &mouse)override;

    bool MouseButtonReleaseEvent(const vtkContextMouseEvent &mouse)override;

    void UpdatePositions();



protected:

    vtkGraphItem();
    ~vtkGraphItem() override;

    float LastPosition[2];
    bool MouseOver;
    int MouseButtonPressed;


    vtkGraph *Graph;
    vtkIdType HitVertex;

    class Implementation;

    Implementation *Impl;

private:
    vtkGraphItem(const vtkGraphItem &) = delete;
    void operator =(const vtkGraphItem &) = delete;

};

#endif // VTKGRAPHITEM_H


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

2.4 vtkContextItem.cpp

这段代码偷懒了,直接把Demo中的代码复制过来了

#include "vtkgraphitem.h"

vtkCxxSetObjectMacro(vtkGraphItem, Graph, vtkGraph);
vtkStandardNewMacro(vtkGraphItem);

class vtkGraphItem::Implementation
{
public:
  Implementation()
  {
    Random = vtkSmartPointer<vtkMinimalStandardRandomSequence>::New();
  }

  void CheckPositionSize(vtkIdType i)
  {
    while (i >= static_cast<vtkIdType>(this->Position.size()))
    {
      int size[2] = {100, 100};
      if (this->Item->GetScene())
      {
        this->Item->GetScene()->GetGeometry(size);
      }
      this->Random->Next();
      float x = static_cast<int>(this->Random->GetValue()*size[0]);
      this->Random->Next();
      float y = static_cast<int>(this->Random->GetValue()*size[1]);
      this->Position.push_back(std::make_pair(x, y));
    }
  }

  void GetPosition(vtkIdType i, float x[2])
  {
    this->CheckPositionSize(i);
    x[0] = this->Position[i].first;
    x[1] = this->Position[i].second;
  }

  void SetPosition(vtkIdType i, float x[2])
  {
    this->CheckPositionSize(i);
    this->Position[i] = std::make_pair(x[0], x[1]);
  }

  void CheckVelocitySize(vtkIdType i)
  {
    while (i >= static_cast<vtkIdType>(this->Velocity.size()))
    {
      this->Velocity.push_back(std::make_pair(0.0f, 0.0f));
    }
  }

  void GetVelocity(vtkIdType i, float x[2])
  {
    this->CheckVelocitySize(i);
    x[0] = this->Velocity[i].first;
    x[1] = this->Velocity[i].second;
  }

  void SetVelocity(vtkIdType i, float x[2])
  {
    this->CheckVelocitySize(i);
    this->Velocity[i] = std::make_pair(x[0], x[1]);
  }

  vtkSmartPointer<vtkMinimalStandardRandomSequence> Random;
  vtkGraphItem* Item;

  std::vector<std::pair<float, float> > Position;
  std::vector<std::pair<float, float> > Velocity;
};

//-----------------------------------------------------------------------------
vtkGraphItem::vtkGraphItem()
{
  this->Impl = new Implementation();
  this->Impl->Item = this;
  this->Graph = nullptr;
  this->MouseOver = false;
  this->MouseButtonPressed = -1;
  this->HitVertex = 0;
}

//-----------------------------------------------------------------------------
vtkGraphItem::~vtkGraphItem()
{
  delete this->Impl;
  this->SetGraph(nullptr);
}

//-----------------------------------------------------------------------------
bool vtkGraphItem::Paint(vtkContext2D *painter)
{
  painter->GetTextProp()->SetVerticalJustificationToCentered();
  painter->GetTextProp()->SetJustificationToCentered();
  painter->GetTextProp()->SetColor(0.0, 0.0, 0.0);
  painter->GetTextProp()->SetFontSize(12);
  painter->GetPen()->SetColorF(0.0f, 0.0f, 0.0f);
  painter->GetBrush()->SetColorF(0.8f, 0.8f, 1.0f, 0.5f);

  vtkSmartPointer<vtkEdgeListIterator> it = vtkSmartPointer<vtkEdgeListIterator>::New();
  this->Graph->GetEdges(it);
  float line[4] = {0.0f, 0.0f, 0.0f, 0.0f};
  while (it->HasNext())
  {
    vtkEdgeType e = it->Next();
    this->Impl->GetPosition(e.Source, line);
    this->Impl->GetPosition(e.Target, line+2);
    for (int i = 0; i < 4; ++i)
    {
      line[i] += 10.0f;
    }
    painter->DrawLine(line);
  }

  float dims[4] = {0.0f, 0.0f, 20.0f, 20.0f};
  for (vtkIdType i = 0; i < this->Graph->GetNumberOfVertices(); ++i)
  {
    this->Impl->GetPosition(i, dims);
    painter->DrawRect(dims[0], dims[1], dims[2], dims[3]);
    float x = dims[0] + 0.5 * dims[2];
    float y = dims[1] + 0.5 * dims[3];
    painter->DrawString(x, y, vtkVariant(i).ToString());
  }

  return true;
}

//-----------------------------------------------------------------------------
bool vtkGraphItem::Hit(const vtkContextMouseEvent &mouse)
{
  float pos[2] = {0.0f, 0.0f};
  for (vtkIdType i = this->Graph->GetNumberOfVertices()-1; i >= 0; --i)
  {
    this->Impl->GetPosition(i, pos);
    if (mouse.GetPos()[0] > pos[0] &&
        mouse.GetPos()[0] < pos[0] + 20.0f &&
        mouse.GetPos()[1] > pos[1] &&
        mouse.GetPos()[1] < pos[1] + 20.0f)
    {
      this->HitVertex = i;
      return true;
    }
  }
  return false;
}

//-----------------------------------------------------------------------------
bool vtkGraphItem::MouseEnterEvent(const vtkContextMouseEvent &)
{
  this->MouseOver = true;
  return true;
}

//-----------------------------------------------------------------------------
bool vtkGraphItem::MouseMoveEvent(const vtkContextMouseEvent &mouse)
{
  int deltaX = static_cast<int>(mouse.GetPos()[0] - this->LastPosition[0]);
  int deltaY = static_cast<int>(mouse.GetPos()[1] - this->LastPosition[1]);
  this->LastPosition[0] = mouse.GetPos()[0];
  this->LastPosition[1] = mouse.GetPos()[1];

  if (this->MouseButtonPressed == 0)
  {
    // Move the vertex by this amount
    float pos[2];
    this->Impl->GetPosition(this->HitVertex, pos);
    pos[0] += deltaX;
    pos[1] += deltaY;
    this->Impl->SetPosition(this->HitVertex, pos);

    return true;
  }
#if 0
  if (this->MouseButtonPressed == 1)
  {
    if (deltaX > 0.0)
    {
      if (!this->GetTransform())
      {
        vtkSmartPointer<vtkTransform2D> t = vtkSmartPointer<vtkTransform2D>::New();
        t->Identity();
        this->SetTransform(t);
      }
      this->GetTransform()->Scale(deltaX/50.0f, deltaX/50.0f);
    }
    return true;
  }
#endif

  return false;
}

//-----------------------------------------------------------------------------
bool vtkGraphItem::MouseLeaveEvent(const vtkContextMouseEvent &)
{
  this->MouseOver = false;
  return true;
}

//-----------------------------------------------------------------------------
bool vtkGraphItem::MouseButtonPressEvent(const vtkContextMouseEvent &mouse)
{
  this->MouseButtonPressed = mouse.GetButton();
  this->LastPosition[0] = mouse.GetPos()[0];
  this->LastPosition[1] = mouse.GetPos()[1];
  return true;
}

//-----------------------------------------------------------------------------
bool vtkGraphItem::MouseButtonReleaseEvent(const vtkContextMouseEvent &)
{
  this->MouseButtonPressed = -1;
  return true;
}

//-----------------------------------------------------------------------------
void vtkGraphItem::UpdatePositions()
{
  vtkIdType numVerts = this->Graph->GetNumberOfVertices();
  float restDistance = 40.0f;
  float dampenLast = 0.5f;
  float springConstant = 0.3f;
  float repulseConstant = 1.0f;
  //float restDistance = 40.0f;
  //float dampenLast = 0.5f;
  //float springConstant = 0.1f;
  //float repulseConstant = 2.0f;
  float epsilon = 0.0000001f;
  float border = 20.0f;
  vtkSmartPointer<vtkOutEdgeIterator> it = vtkSmartPointer<vtkOutEdgeIterator>::New();
  float uPos[2];
  float vPos[2];
  float uVel[2];
  int geom[2] = {100, 100};
  if (this->GetScene())
  {
    this->GetScene()->GetGeometry(geom);
  }
  for (vtkIdType u = 0; u < numVerts; ++u)
  {
    if (this->MouseButtonPressed == 0 && u == this->HitVertex)
    {
      continue;
    }
    this->Impl->GetPosition(u, uPos);
    float fx = 0.0;
    float fy = 0.0;
    for (vtkIdType v = 0; v < numVerts; ++v)
    {
      this->Impl->GetPosition(v, vPos);
      float deltaX = uPos[0] - vPos[0];
      float deltaY = uPos[1] - vPos[1];
      float distSquared = deltaX*deltaX + deltaY*deltaY;
      // Avoid divide by zero
      distSquared += epsilon;
      fx += repulseConstant * deltaX / distSquared;
      fy += repulseConstant * deltaY / distSquared;
    }
    this->Graph->GetOutEdges(u, it);
    while (it->HasNext())
    {
      vtkOutEdgeType e = it->Next();
      vtkIdType v = e.Target;
      if (u == v)
      {
        continue;
      }
      this->Impl->GetPosition(v, vPos);
      float deltaX = uPos[0] - vPos[0];
      float deltaY = uPos[1] - vPos[1];
      float dist = sqrt(deltaX*deltaX + deltaY*deltaY);
      float force = springConstant*(dist - restDistance);
      fx -= force * deltaX / dist;
      fy -= force * deltaY / dist;
    }
    float center[2] = {uPos[0] + 10.0f, uPos[1] + 10.0f};
    // Change the force if it is near the edge
    if (center[0] < border)
    {
      fx += -(center[0] - border);
    }
    else if (center[0] > geom[0] - border)
    {
      fx += -(center[0] - (geom[0] - border));
    }
    if (center[1] < border)
    {
      fy += -(center[1] - border);
    }
    else if (center[1] > geom[1] - border)
    {
      fy += -(center[1] - (geom[1] - border));
    }
    // Update velocity and position
    this->Impl->GetVelocity(u, uVel);
    uVel[0] = dampenLast*uVel[0] + fx;
    uVel[1] = dampenLast*uVel[1] + fy;
    uPos[0] += uVel[0];
    uPos[1] += uVel[1];
    this->Impl->SetPosition(u, uPos);
    this->Impl->SetVelocity(u, uVel);
  }
}

//-----------------------------------------------------------------------------
void vtkGraphItem::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310

3 运行效果

这个就尴尬了,目前在的这台电脑上市出不来效果了,包括官方的Demo也是白屏状态,目前还不知道啥情况。留坑。

4 错误解决方法

Error: no override found for ‘vtkContextDevice2D’.

在main中加入VTK_MODULE_INIT(vtkRenderingContextOpenGL);

在加入上面的语句后,会出现如下错误

image-20210629092943328

​ 老鸟一看这应该就是丢库了,我这二货还不知道,搞了好久,网上找了半天,终于找到了提示,需要看下库有没有包含进去

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Kj3nzL5-1628730592619)(https://raw.githubusercontent.com/DreamLife-Jianwei/CSDNResources/master/20210629093058.png)]

​ 如上图所示,在检查了我包含的库文件后,修改代码为

VTK_MODULE_INIT(vtkRenderingContextOpenGL2);

​ 搞定!!!

源码

源码分享一时爽,一直分享一直爽, 链接如下:

自取:https://github.com/DreamLife-Jianwei/Qt-Vtk

在这里插入图片描述


博客签名2021

文章来源: dreamlife.blog.csdn.net,作者:DreamLife.,版权归原作者所有,如需转载,请联系作者。

原文链接:dreamlife.blog.csdn.net/article/details/119633046

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。