File: Point_set_upsampling_plugin.cpp

package info (click to toggle)
cgal 6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,912 kB
  • sloc: cpp: 810,858; ansic: 208,477; sh: 493; python: 411; makefile: 286; javascript: 174
file content (151 lines) | stat: -rw-r--r-- 5,250 bytes parent folder | download | duplicates (2)
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
#include "config.h"
#include "Scene_points_with_normal_item.h"
#include "Messages_interface.h"
#include <CGAL/Three/CGAL_Lab_plugin_helper.h>
#include <CGAL/Three/CGAL_Lab_plugin_interface.h>
#include <CGAL/Three/Three.h>

#include <CGAL/compute_average_spacing.h>
#include <CGAL/edge_aware_upsample_point_set.h>
#include <CGAL/Timer.h>
#include <CGAL/Memory_sizer.h>

#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QMessageBox>

#include "ui_Point_set_upsampling_plugin.h"
// Concurrency
typedef CGAL::Parallel_if_available_tag Concurrency_tag;

using namespace CGAL::Three;
class CGAL_Lab_point_set_upsampling_plugin :
  public QObject,
  public CGAL_Lab_plugin_helper
{
  Q_OBJECT
  Q_INTERFACES(CGAL::Three::CGAL_Lab_plugin_interface)
  Q_PLUGIN_METADATA(IID "com.geometryfactory.CGALLab.PluginInterface/1.0")

  QAction* actionEdgeAwareUpsampling;
  Messages_interface* message_interface;
public:
  void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* mi) {
    message_interface = mi;
    scene = scene_interface;
    actionEdgeAwareUpsampling = new QAction(tr("Edge Aware Upsampling"), mainWindow);
    actionEdgeAwareUpsampling->setProperty("subMenuName","Point Set Processing");
    actionEdgeAwareUpsampling->setObjectName("actionEdgeAwareUpsampling");
    autoConnectActions();
  }

  bool applicable(QAction*) const {
    return qobject_cast<Scene_points_with_normal_item*>(scene->item(scene->mainSelectionIndex()));
  }

  QList<QAction*> actions() const {
    return QList<QAction*>() << actionEdgeAwareUpsampling;
  }

public Q_SLOTS:
  void on_actionEdgeAwareUpsampling_triggered();

}; // end CGAL_Lab_point_set_upsampling_plugin

class Point_set_demo_point_set_upsampling_dialog : public QDialog, private Ui::PointSetUpsamplingDialog
{

  Q_OBJECT
public:
  Point_set_demo_point_set_upsampling_dialog(QWidget * /*parent*/ = nullptr)
  {
    setupUi(this);
    m_edgeSensitivity->setMaximum(1.0);
    m_neighborhoodRadius->setRange(0.1, 10.0);


  }

  unsigned int sharpness_angle () const { return m_sharpnessAngle->value(); }
  double edge_sensitivity() const { return m_edgeSensitivity->value(); }
  double neighborhood_radius () const { return m_neighborhoodRadius->value(); }
  double output_size () const { return m_outputSize->value(); }

};

void CGAL_Lab_point_set_upsampling_plugin::on_actionEdgeAwareUpsampling_triggered()
{
  const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();

  Scene_points_with_normal_item* item =
    qobject_cast<Scene_points_with_normal_item*>(scene->item(index));

  if(item)
    {
      if (!(item->has_normals ()))
        {
          CGAL::Three::Three::error("Error: upsampling algorithm requires point set with normals.");
          return;
        }

      // Gets point set
      Point_set* points = item->point_set();
      if(points == nullptr)
        return;

      // Gets options
      Point_set_demo_point_set_upsampling_dialog dialog;
      if(!dialog.exec())
        return;

      unsigned int output_size = static_cast<unsigned int>(dialog.output_size ()
                                                           * points->size ());
      std::cerr << "Edge aware upsampling (sharpness angle = "
                << dialog.sharpness_angle () << ", edge sensitivity = "
                << dialog.edge_sensitivity () << ", neighborhood radius = "
                << dialog.neighborhood_radius () << " * average spacing, output size = "
                << output_size << "...\n";

      QApplication::setOverrideCursor(Qt::WaitCursor);

      CGAL::Timer task_timer; task_timer.start();

      // Computes average spacing
      double average_spacing = CGAL::compute_average_spacing<Concurrency_tag>(*points, 6);

      std::size_t nb_selected = points->nb_selected_points();

      std::vector<std::pair<Point_set::Point, Point_set::Vector> > new_points;
      CGAL::edge_aware_upsample_point_set<Concurrency_tag>(points->all_or_selection_if_not_empty(),
                                          std::back_inserter(new_points),
                                          points->parameters().
                                          sharpness_angle (dialog.sharpness_angle()).
                                          edge_sensitivity (dialog.edge_sensitivity()).
                                          neighbor_radius (dialog.neighborhood_radius() * average_spacing).
                                          number_of_output_points (output_size));
      nb_selected += new_points.size();

      for (unsigned int i = 0; i < new_points.size (); ++ i)
        points->insert (new_points[i].first, new_points[i].second);

      if (nb_selected != new_points.size())
        points->set_first_selected (points->end() - nb_selected);

      std::size_t memory = CGAL::Memory_sizer().virtual_size();
      std::cerr << task_timer.time() << " seconds, "
                << (memory>>20) << " Mb allocated)"
                << std::endl;

      // Updates scene
      item->invalidateOpenGLBuffers();
      scene->itemChanged(index);

      QApplication::restoreOverrideCursor();

    }
}

#include "Point_set_upsampling_plugin.moc"