mirror of https://github.com/CGAL/cgal
Merge pull request #3919 from maxGimeno/Add_3mf_wrapper-GF
Stream_support: Add a 3mf wrapper
This commit is contained in:
commit
33e7de45e9
|
|
@ -299,6 +299,16 @@ public Q_SLOTS:
|
|||
zClippingCoef_ = coef;
|
||||
projectionMatrixIsUpToDate_ = false;
|
||||
}
|
||||
/*! Sets the zNear value in orthographic mode. */
|
||||
void setOrthoZNear(qreal z)
|
||||
{
|
||||
m_zMin = z;
|
||||
}
|
||||
/*! Returns the zNear value in orthographic mode*/
|
||||
qreal orthoZNear()
|
||||
{
|
||||
return m_zMin;
|
||||
}
|
||||
//@}
|
||||
|
||||
/*! @name Scene radius and center */
|
||||
|
|
@ -463,6 +473,7 @@ private:
|
|||
mutable bool modelViewMatrixIsUpToDate_;
|
||||
mutable GLdouble projectionMatrix_[16]; // Buffered projection matrix.
|
||||
mutable bool projectionMatrixIsUpToDate_;
|
||||
qreal m_zMin; //USed for near plane in orthographic projection.
|
||||
|
||||
// S t e r e o p a r a m e t e r s
|
||||
qreal IODistance_; // inter-ocular distance, in meters
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ CGAL_INLINE_FUNCTION
|
|||
Camera::Camera(QObject *parent)
|
||||
: frame_(nullptr), fieldOfView_(CGAL_PI / 4.0), modelViewMatrixIsUpToDate_(false),
|
||||
projectionMatrixIsUpToDate_(false) {
|
||||
m_zMin = 0;
|
||||
setParent(parent);
|
||||
// #CONNECTION# Camera copy constructor
|
||||
interpolationKfi_ = new KeyFrameInterpolator;
|
||||
|
|
@ -228,7 +229,7 @@ qreal Camera::zNear() const {
|
|||
z = zMin;
|
||||
break;
|
||||
case Camera::ORTHOGRAPHIC:
|
||||
z = 0.0;
|
||||
z = m_zMin;
|
||||
break;
|
||||
}
|
||||
return z;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#include <QTime>
|
||||
#include <QWidgetAction>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include <QSequentialIterable>
|
||||
#ifdef QT_SCRIPT_LIB
|
||||
# include <QScriptValue>
|
||||
# ifdef QT_SCRIPTTOOLS_LIB
|
||||
|
|
@ -790,6 +790,7 @@ bool MainWindow::initIOPlugin(QObject* obj)
|
|||
CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin =
|
||||
qobject_cast<CGAL::Three::Polyhedron_demo_io_plugin_interface*>(obj);
|
||||
if(plugin) {
|
||||
plugin->init();
|
||||
io_plugins << plugin;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -999,20 +1000,29 @@ void MainWindow::reloadItem() {
|
|||
|
||||
CGAL::Three::Polyhedron_demo_io_plugin_interface* fileloader = findLoader(loader_name);
|
||||
QFileInfo fileinfo(filename);
|
||||
|
||||
CGAL::Three::Scene_item* new_item = loadItem(fileinfo, fileloader);
|
||||
if(!new_item)
|
||||
bool ok;
|
||||
QList<Scene_item*> new_items = loadItem(fileinfo, fileloader, ok, false);
|
||||
if(!ok)
|
||||
return;
|
||||
new_item->setName(item->name());
|
||||
new_item->setColor(item->color());
|
||||
new_item->setRenderingMode(item->renderingMode());
|
||||
new_item->setVisible(item->visible());
|
||||
Scene_item_with_properties *property_item = dynamic_cast<Scene_item_with_properties*>(new_item);
|
||||
scene->replaceItem(scene->item_id(item), new_item, true);
|
||||
if(property_item)
|
||||
property_item->copyProperties(item);
|
||||
new_item->invalidateOpenGLBuffers();
|
||||
item->deleteLater();
|
||||
QVariant varian = item->property("load_mates");
|
||||
QSequentialIterable iterable = varian.value<QSequentialIterable>();
|
||||
// Can use foreach:
|
||||
int mate_id = 0;
|
||||
Q_FOREACH(const QVariant &v, iterable)
|
||||
{
|
||||
Scene_item* mate = v.value<Scene_item*>();
|
||||
Scene_item* new_item = new_items[mate_id];
|
||||
new_item->setName(mate->name());
|
||||
new_item->setColor(mate->color());
|
||||
new_item->setRenderingMode(mate->renderingMode());
|
||||
new_item->setVisible(mate->visible());
|
||||
Scene_item_with_properties *property_item = dynamic_cast<Scene_item_with_properties*>(new_item);
|
||||
scene->replaceItem(scene->item_id(mate), new_item, true);
|
||||
if(property_item)
|
||||
property_item->copyProperties(mate);
|
||||
new_item->invalidateOpenGLBuffers();
|
||||
mate->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1105,11 +1115,11 @@ void MainWindow::open(QString filename)
|
|||
{
|
||||
// collect all io_plugins and offer them to load if the file extension match one name filter
|
||||
// also collect all available plugin in case of a no extension match
|
||||
Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* io_plugin, io_plugins) {
|
||||
if ( !io_plugin->canLoad() ) continue;
|
||||
all_items << io_plugin->name();
|
||||
for(CGAL::Three::Polyhedron_demo_io_plugin_interface* io_plugin : io_plugins) {
|
||||
if ( file_matches_filter(io_plugin->loadNameFilters(), filename.toLower()) )
|
||||
{
|
||||
if ( !io_plugin->canLoad(fileinfo) ) continue;
|
||||
all_items << io_plugin->name();
|
||||
if(io_plugin->isDefaultLoader(fileinfo.completeSuffix()))
|
||||
selected_items.prepend(io_plugin->name());
|
||||
else
|
||||
|
|
@ -1149,71 +1159,69 @@ void MainWindow::open(QString filename)
|
|||
|
||||
settings.setValue("OFF open directory",
|
||||
fileinfo.absoluteDir().absolutePath());
|
||||
CGAL::Three::Scene_item* scene_item = loadItem(fileinfo, findLoader(load_pair.first));
|
||||
loadItem(fileinfo, findLoader(load_pair.first), ok);
|
||||
|
||||
if(!scene_item)
|
||||
if(!ok)
|
||||
return;
|
||||
this->addToRecentFiles(fileinfo.absoluteFilePath());
|
||||
selectSceneItem(scene->addItem(scene_item));
|
||||
|
||||
CGAL::Three::Scene_group_item* group =
|
||||
qobject_cast<CGAL::Three::Scene_group_item*>(scene_item);
|
||||
if(group)
|
||||
scene->redraw_model();
|
||||
updateViewersBboxes(true);
|
||||
}
|
||||
|
||||
bool MainWindow::open(QString filename, QString loader_name) {
|
||||
QFileInfo fileinfo(filename);
|
||||
boost::optional<CGAL::Three::Scene_item*> item_opt;
|
||||
CGAL::Three::Scene_item* item = 0;
|
||||
boost::optional<bool> item_opt;
|
||||
try {
|
||||
item_opt = wrap_a_call_to_cpp
|
||||
([this, fileinfo, loader_name]()
|
||||
{
|
||||
return loadItem(fileinfo, findLoader(loader_name));
|
||||
bool ok;
|
||||
loadItem(fileinfo, findLoader(loader_name), ok);
|
||||
return ok;
|
||||
},
|
||||
this, __FILE__, __LINE__
|
||||
);
|
||||
if(!item_opt) return false;
|
||||
else item = *item_opt;
|
||||
}
|
||||
catch(std::logic_error& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
selectSceneItem(scene->addItem(item));
|
||||
|
||||
CGAL::Three::Scene_group_item* group =
|
||||
qobject_cast<CGAL::Three::Scene_group_item*>(item);
|
||||
if(group)
|
||||
scene->redraw_model();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CGAL::Three::Scene_item* MainWindow::loadItem(QFileInfo fileinfo, CGAL::Three::Polyhedron_demo_io_plugin_interface* loader) {
|
||||
CGAL::Three::Scene_item* item = NULL;
|
||||
QList<Scene_item*> MainWindow::loadItem(QFileInfo fileinfo,
|
||||
CGAL::Three::Polyhedron_demo_io_plugin_interface* loader,
|
||||
bool &ok,
|
||||
bool add_to_scene) {
|
||||
if(!fileinfo.isFile() || !fileinfo.isReadable()) {
|
||||
QMessageBox::warning(this, tr("Error"),
|
||||
QString("File %1 is not a readable file.")
|
||||
.arg(fileinfo.absoluteFilePath()));
|
||||
}
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
item = loader->load(fileinfo);
|
||||
QApplication::restoreOverrideCursor();
|
||||
if(!item) {
|
||||
QCursor tmp_cursor(Qt::WaitCursor);
|
||||
CGAL::Three::Three::CursorScopeGuard guard(tmp_cursor);
|
||||
QList<Scene_item*> result = loader->load(fileinfo, ok, add_to_scene);
|
||||
if(result.empty() || !ok)
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
QMessageBox::warning(this, tr("Error"),
|
||||
QString("Could not load item from file %1 using plugin %2")
|
||||
.arg(fileinfo.absoluteFilePath()).arg(loader->name()));
|
||||
return 0;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
item->setProperty("source filename", fileinfo.absoluteFilePath());
|
||||
item->setProperty("loader_name", loader->name());
|
||||
return item;
|
||||
selectSceneItem(scene->item_id(result.back()));
|
||||
for(Scene_item* item : result)
|
||||
{
|
||||
CGAL::Three::Scene_group_item* group =
|
||||
qobject_cast<CGAL::Three::Scene_group_item*>(item);
|
||||
if(group)
|
||||
scene->redraw_model();
|
||||
item->setProperty("source filename", fileinfo.absoluteFilePath());
|
||||
item->setProperty("loader_name", loader->name());
|
||||
item->setProperty("load_mates",QVariant::fromValue(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1832,7 +1840,7 @@ void MainWindow::on_actionLoad_triggered()
|
|||
typedef QMap<QString, CGAL::Three::Polyhedron_demo_io_plugin_interface*> FilterPluginMap;
|
||||
FilterPluginMap filterPluginMap;
|
||||
|
||||
Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin, io_plugins) {
|
||||
for(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin : io_plugins) {
|
||||
QStringList split_filters = plugin->loadNameFilters().split(";;");
|
||||
Q_FOREACH(const QString& filter, split_filters) {
|
||||
FilterPluginMap::iterator it = filterPluginMap.find(filter);
|
||||
|
|
@ -1878,39 +1886,54 @@ void MainWindow::on_actionLoad_triggered()
|
|||
std::size_t nb_item = -1;
|
||||
|
||||
Q_FOREACH(const QString& filename, dialog.selectedFiles()) {
|
||||
|
||||
|
||||
CGAL::Three::Scene_item* item = NULL;
|
||||
if(selectedPlugin) {
|
||||
QFileInfo info(filename);
|
||||
item = loadItem(info, selectedPlugin);
|
||||
item->setColor(colors_[++nb_item]);
|
||||
Scene::Item_id index = scene->addItem(item);
|
||||
selectSceneItem(index);
|
||||
CGAL::Three::Scene_group_item* group =
|
||||
qobject_cast<CGAL::Three::Scene_group_item*>(item);
|
||||
if(group)
|
||||
scene->redraw_model();
|
||||
bool ok;
|
||||
QList<Scene_item*> result = loadItem(info, selectedPlugin, ok);
|
||||
if(!ok)
|
||||
continue;
|
||||
for(Scene_item* item : result)
|
||||
{
|
||||
if(!item->property("already_colored").toBool())
|
||||
{
|
||||
++nb_item;
|
||||
item->setColor(colors_[nb_item]);
|
||||
}
|
||||
selectSceneItem(scene->item_id(item));
|
||||
CGAL::Three::Scene_group_item* group =
|
||||
qobject_cast<CGAL::Three::Scene_group_item*>(item);
|
||||
if(group)
|
||||
scene->redraw_model();
|
||||
}
|
||||
this->addToRecentFiles(filename);
|
||||
} else {
|
||||
int scene_size = scene->numberOfEntries();
|
||||
open(filename);
|
||||
if(scene->numberOfEntries() != scene_size)
|
||||
scene->item(scene->numberOfEntries()-1)->setColor(colors_[++nb_item]);
|
||||
item = scene->item(scene->numberOfEntries()-1);
|
||||
if(scene->numberOfEntries() != scene_size
|
||||
&& !item->property("already_colored").toBool())
|
||||
item->setColor(colors_[++nb_item]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSaveAs_triggered()
|
||||
{
|
||||
Scene_item* item = NULL;
|
||||
|
||||
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
|
||||
QList<Scene_item*> to_save;
|
||||
for(Scene::Item_id id : scene->selectionIndices())
|
||||
{
|
||||
item = scene->item(id);
|
||||
Scene_item* item = scene->item(id);
|
||||
to_save.append(item);
|
||||
}
|
||||
while(!to_save.empty())
|
||||
{
|
||||
Scene_item* item = to_save.front();
|
||||
QVector<CGAL::Three::Polyhedron_demo_io_plugin_interface*> canSavePlugins;
|
||||
QStringList filters;
|
||||
QString sf;
|
||||
Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin, io_plugins) {
|
||||
for(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin : io_plugins) {
|
||||
if(plugin->canSave(item)) {
|
||||
canSavePlugins << plugin;
|
||||
filters += plugin->saveNameFilters();
|
||||
|
|
@ -1926,7 +1949,7 @@ void MainWindow::on_actionSaveAs_triggered()
|
|||
tr("Cannot save"),
|
||||
tr("The selected object %1 cannot be saved.")
|
||||
.arg(item->name()));
|
||||
return;
|
||||
return;
|
||||
}
|
||||
Q_FOREACH(QString string, filters)
|
||||
{
|
||||
|
|
@ -1962,14 +1985,14 @@ void MainWindow::on_actionSaveAs_triggered()
|
|||
dir,
|
||||
filters.join(";;"),
|
||||
&sf);
|
||||
|
||||
|
||||
if(filename.isEmpty())
|
||||
return;
|
||||
last_saved_dir = QFileInfo(filename).absoluteDir().path();
|
||||
extensions.indexIn(sf.split(";;").first());
|
||||
QString filter_ext, filename_ext;
|
||||
filter_ext = extensions.cap().split(" ").first();// in case of syntax like (*.a *.b)
|
||||
|
||||
|
||||
filter_ext.remove(")");
|
||||
filter_ext.remove("(");
|
||||
//remove *
|
||||
|
|
@ -2017,18 +2040,18 @@ void MainWindow::on_actionSaveAs_triggered()
|
|||
}
|
||||
for(auto v : CGAL::QGLViewer::QGLViewerPool())
|
||||
v->update();
|
||||
save(filename, item);
|
||||
save(filename, to_save);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::save(QString filename, CGAL::Three::Scene_item* item) {
|
||||
void MainWindow::save(QString filename, QList<CGAL::Three::Scene_item*>& to_save) {
|
||||
QFileInfo fileinfo(filename);
|
||||
bool saved = false;
|
||||
Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin, io_plugins) {
|
||||
if( plugin->canSave(item) &&
|
||||
for(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin : io_plugins) {
|
||||
if( plugin->canSave(to_save.front()) &&
|
||||
file_matches_filter(plugin->saveNameFilters(),filename.toLower()) )
|
||||
{
|
||||
if(plugin->save(item, fileinfo))
|
||||
if(plugin->save(fileinfo, to_save))
|
||||
{
|
||||
saved = true;
|
||||
break;
|
||||
|
|
@ -2039,7 +2062,7 @@ void MainWindow::save(QString filename, CGAL::Three::Scene_item* item) {
|
|||
QMessageBox::warning(this,
|
||||
tr("Cannot save"),
|
||||
tr("The selected object %1 was not saved. (Maybe a wrong extension ?)")
|
||||
.arg(item->name()));
|
||||
.arg(to_save.front()->name()));
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSaveSnapshot_triggered()
|
||||
|
|
@ -2471,7 +2494,7 @@ QString MainWindow::get_item_stats()
|
|||
for(int i=0; i<items.size(); i++)
|
||||
{
|
||||
Scene_item* item = scene->item(id);
|
||||
QString classname = item->property("classname").toString();
|
||||
QString classname = item->property("classname").toString();
|
||||
if(classname.isEmpty())
|
||||
classname = item->metaObject()->className();
|
||||
if(classnames.at(i).contains(classname))
|
||||
|
|
@ -3132,14 +3155,16 @@ void MainWindow::on_action_Save_triggered()
|
|||
if(QMessageBox::question(this, "Save", "Are you sure you want to override these files ?")
|
||||
== QMessageBox::No)
|
||||
return;
|
||||
Scene_item* item = nullptr;
|
||||
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
|
||||
QList<Scene_item*> to_save;
|
||||
|
||||
for(Scene::Item_id id : scene->selectionIndices())
|
||||
{
|
||||
item = scene->item(id);
|
||||
Scene_item* item = scene->item(id);
|
||||
if(!item->property("source filename").toString().isEmpty())
|
||||
{
|
||||
QString filename = item->property("source filename").toString();
|
||||
save(filename, item);
|
||||
to_save.append(item);
|
||||
save(filename, to_save);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,11 +87,14 @@ public:
|
|||
@returns the IO plugin associated with `loader_name`*/
|
||||
CGAL::Three::Polyhedron_demo_io_plugin_interface* findLoader(const QString& loader_name) const;
|
||||
|
||||
/*! \brief Loads an item with a given loader.
|
||||
/*! \brief Loads on or more item with a given loader.
|
||||
*
|
||||
* throws `std::logic_error` if loading does not succeed or
|
||||
* `std::invalid_argument` if `fileinfo` specifies an invalid file*/
|
||||
CGAL::Three::Scene_item* loadItem(QFileInfo fileinfo, CGAL::Three::Polyhedron_demo_io_plugin_interface*);
|
||||
QList<CGAL::Three::Scene_item *> loadItem(QFileInfo fileinfo,
|
||||
CGAL::Three::Polyhedron_demo_io_plugin_interface*,
|
||||
bool& ok,
|
||||
bool add_to_scene=true);
|
||||
void computeViewerBBox(CGAL::qglviewer::Vec &min, CGAL::qglviewer::Vec &max);
|
||||
void updateViewerBbox(Viewer* vi, bool recenter, CGAL::qglviewer::Vec min,
|
||||
CGAL::qglviewer::Vec max);
|
||||
|
|
@ -346,7 +349,7 @@ protected Q_SLOTS:
|
|||
//!Opens a dialog to save selected item if able.
|
||||
void on_actionSaveAs_triggered();
|
||||
//!Calls the function save of the current plugin if able.
|
||||
void save(QString filename, CGAL::Three::Scene_item* item);
|
||||
void save(QString filename, QList<CGAL::Three::Scene_item*>& to_save);
|
||||
//!Calls the function saveSnapShot of the viewer.
|
||||
void on_actionSaveSnapshot_triggered();
|
||||
//!Opens a Dialog to choose a color and make it the background color.
|
||||
|
|
|
|||
|
|
@ -791,14 +791,15 @@ class Polyhedron_demo_cut_plugin :
|
|||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90")
|
||||
|
||||
public:
|
||||
Polyhedron_demo_cut_plugin() : QObject(), edges_item(0) {
|
||||
}
|
||||
|
||||
virtual ~Polyhedron_demo_cut_plugin();
|
||||
~Polyhedron_demo_cut_plugin();
|
||||
|
||||
bool applicable(QAction*) const {
|
||||
bool applicable(QAction*) const Q_DECL_OVERRIDE{
|
||||
// returns true if one surface_mesh is in the entries
|
||||
for (int i=0; i< scene->numberOfEntries(); ++i)
|
||||
{
|
||||
|
|
@ -808,29 +809,32 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual QString name() const
|
||||
QString name() const Q_DECL_OVERRIDE
|
||||
{
|
||||
return "cut-plugin";
|
||||
}
|
||||
|
||||
|
||||
virtual QString nameFilters() const
|
||||
QString nameFilters() const Q_DECL_OVERRIDE
|
||||
{
|
||||
return "Segment soup file (*.polylines.txt *.cgal)";
|
||||
}
|
||||
|
||||
|
||||
bool canLoad() const
|
||||
bool canLoad(QFileInfo) const Q_DECL_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual CGAL::Three::Scene_item* load(QFileInfo /* fileinfo */)
|
||||
QList<Scene_item*> load(QFileInfo , bool& ok, bool add_to_scene=true) Q_DECL_OVERRIDE
|
||||
|
||||
{
|
||||
return 0;
|
||||
Q_UNUSED(add_to_scene);
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
virtual bool canSave(const CGAL::Three::Scene_item* item)
|
||||
bool canSave(const CGAL::Three::Scene_item* item) Q_DECL_OVERRIDE
|
||||
{
|
||||
// This plugin supports edges items
|
||||
bool b = qobject_cast<const Scene_edges_item*>(item) != 0;
|
||||
|
|
@ -838,8 +842,10 @@ public:
|
|||
}
|
||||
|
||||
|
||||
virtual bool save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
{ // This plugin supports edges items
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items) Q_DECL_OVERRIDE
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
// This plugin supports edges items
|
||||
const Scene_edges_item* edges_item =
|
||||
qobject_cast<const Scene_edges_item*>(item);
|
||||
|
||||
|
|
@ -848,15 +854,18 @@ public:
|
|||
}
|
||||
|
||||
std::ofstream out(fileinfo.filePath().toUtf8());
|
||||
|
||||
return (out && edges_item->save(out));
|
||||
bool ok = (out && edges_item->save(out));
|
||||
if(ok)
|
||||
items.pop_front();
|
||||
return ok;
|
||||
}
|
||||
|
||||
using Polyhedron_demo_io_plugin_interface::init;
|
||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface,
|
||||
Messages_interface* m);
|
||||
QList<QAction*> actions() const;
|
||||
Messages_interface* m) override;
|
||||
QList<QAction*> actions() const Q_DECL_OVERRIDE;
|
||||
|
||||
bool eventFilter(QObject *, QEvent *event)
|
||||
bool eventFilter(QObject *, QEvent *event) Q_DECL_OVERRIDE
|
||||
{
|
||||
if(!plane_item)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,50 +1,47 @@
|
|||
#include <QtCore/qglobal.h>
|
||||
#include "Messages_interface.h"
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||
|
||||
#include "Camera_positions_list.h"
|
||||
|
||||
#include <CGAL/Three/Three.h>
|
||||
#include <CGAL/Three/Viewer_interface.h>
|
||||
|
||||
#include <QMainWindow>
|
||||
using namespace CGAL::Three;
|
||||
class Polyhedron_demo_camera_positions_plugin :
|
||||
public QObject,
|
||||
public Polyhedron_demo_plugin_interface,
|
||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90")
|
||||
|
||||
public:
|
||||
void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* );
|
||||
QList<QAction*> actions() const;
|
||||
void init() override;
|
||||
|
||||
QString name() const { return "camera_positions_plugin"; }
|
||||
QString nameFilters() const { return "Camera positions (*.camera.txt)"; }
|
||||
bool canLoad() const { return true; }
|
||||
Scene_item* load(QFileInfo fileinfo) { cpl->load(fileinfo.filePath()); return 0; }
|
||||
QString name() const override { return "camera_positions_plugin"; }
|
||||
QString nameFilters() const override { return "Camera positions (*.camera.txt)"; }
|
||||
bool canLoad(QFileInfo) const override { return true; }
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override
|
||||
{
|
||||
Q_UNUSED(add_to_scene);
|
||||
ok = true;
|
||||
cpl->load(fileinfo.filePath());
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
bool canSave(const Scene_item*) { return false; }
|
||||
bool save(const Scene_item*, QFileInfo ) {return false; }
|
||||
bool applicable(QAction*) const {return false;}
|
||||
bool canSave(const Scene_item*) override { return false; }
|
||||
bool save(QFileInfo,QList<CGAL::Three::Scene_item*>& ) override {return false; }
|
||||
private:
|
||||
Camera_positions_list* cpl;
|
||||
};
|
||||
|
||||
void Polyhedron_demo_camera_positions_plugin::init(QMainWindow* mainWindow, Scene_interface*, Messages_interface *)
|
||||
void Polyhedron_demo_camera_positions_plugin::init()
|
||||
{
|
||||
|
||||
cpl = new Camera_positions_list(mainWindow);
|
||||
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, cpl);
|
||||
}
|
||||
|
||||
QList<QAction*>
|
||||
Polyhedron_demo_camera_positions_plugin::actions() const
|
||||
{
|
||||
return QList<QAction*>();
|
||||
cpl = new Camera_positions_list(CGAL::Three::Three::mainWindow());
|
||||
CGAL::Three::Three::mainWindow()->addDockWidget(Qt::LeftDockWidgetArea, cpl);
|
||||
}
|
||||
|
||||
#include "Camera_positions_plugin.moc"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,327 @@
|
|||
#include <CGAL/Three/Three.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
|
||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||
|
||||
#include <CGAL/IO/read_3mf.h>
|
||||
#include <CGAL/IO/write_3mf.h>
|
||||
|
||||
#include "Scene_surface_mesh_item.h"
|
||||
#include "Scene_points_with_normal_item.h"
|
||||
#include "Scene_polylines_item.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace NMR;
|
||||
|
||||
class Io_3mf_plugin:
|
||||
public QObject,
|
||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "3mf_io_plugin.json")
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
typedef std::vector<Kernel::Point_3> PointRange;
|
||||
typedef std::vector<std::size_t> Polygon;
|
||||
typedef std::vector<Polygon> PolygonRange;
|
||||
typedef std::list<PointRange> PolylineRange;
|
||||
typedef std::vector<CGAL::Color> ColorRange;
|
||||
void init() Q_DECL_OVERRIDE
|
||||
{
|
||||
QMenu* menuFile = CGAL::Three::Three::mainWindow()->findChild<QMenu*>("menuFile");
|
||||
|
||||
QAction* actionSaveSceneTo3mf = new QAction("Save the Scene as a 3mf File...");
|
||||
connect(actionSaveSceneTo3mf, &QAction::triggered, this,
|
||||
[this](){
|
||||
|
||||
QString filename =
|
||||
QFileDialog::getSaveFileName(CGAL::Three::Three::mainWindow(),
|
||||
tr("Save Scene to File..."),
|
||||
QString(),
|
||||
"*.3mf");
|
||||
|
||||
if(filename.isEmpty())
|
||||
return;
|
||||
if(!filename.endsWith(".3mf"))
|
||||
filename.append(".3mf");
|
||||
QList<Scene_item*> all_items;
|
||||
for(int i = 0; i< CGAL::Three::Three::scene()->numberOfEntries(); ++i)
|
||||
all_items.push_back(CGAL::Three::Three::scene()->item(i));
|
||||
save(filename, all_items);
|
||||
});
|
||||
menuFile->insertAction(CGAL::Three::Three::mainWindow()->findChild<QAction*>("actionSa_ve_Scene_as_Script"), actionSaveSceneTo3mf);
|
||||
}
|
||||
QString name() const { return "3mf_io_plugin"; }
|
||||
|
||||
|
||||
QString nameFilters() const { return
|
||||
"3mf files (*.3mf)"; }
|
||||
|
||||
|
||||
bool canLoad(QFileInfo) const Q_DECL_OVERRIDE { return true; }
|
||||
|
||||
|
||||
QList<CGAL::Three::Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) Q_DECL_OVERRIDE {
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
// Open file
|
||||
ok = true;
|
||||
std::vector<PointRange> all_points;
|
||||
std::vector<PolygonRange> all_polygons;
|
||||
std::vector<std::string> names;
|
||||
QList<Scene_item*> result;
|
||||
std::vector<std::vector<CGAL::Color> > all_colors;
|
||||
int nb_polylines =
|
||||
CGAL::read_polylines_from_3mf(fileinfo.filePath().toUtf8().toStdString(),
|
||||
all_points, all_colors, names);
|
||||
if(nb_polylines < 0 )
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "Error in reading of meshes."<<std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
for(int i=0; i< nb_polylines; ++i)
|
||||
{
|
||||
Scene_polylines_item* pol_item = new Scene_polylines_item();
|
||||
PolylineRange& polylines = pol_item->polylines;
|
||||
polylines.push_back(all_points[i]);
|
||||
pol_item->setName(names[i].data());
|
||||
pol_item->invalidateOpenGLBuffers();
|
||||
CGAL::Color c = all_colors[i].front();
|
||||
pol_item->setColor(QColor(c.red(), c.green(), c.blue()));
|
||||
pol_item->setProperty("already_colord", true);
|
||||
result << pol_item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(pol_item);
|
||||
}
|
||||
all_points.clear();
|
||||
all_colors.clear();
|
||||
names.clear();
|
||||
int nb_point_sets =
|
||||
CGAL::read_point_clouds_from_3mf(fileinfo.filePath().toUtf8().toStdString(),
|
||||
all_points, all_colors, names);
|
||||
if(nb_point_sets < 0 )
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "Error in reading of meshes."<<std::endl;
|
||||
return result;
|
||||
}
|
||||
for(int i=0; i< nb_point_sets; ++i)
|
||||
{
|
||||
Scene_points_with_normal_item* pts_item = new Scene_points_with_normal_item();
|
||||
for(std::size_t j = 0; j < all_points[i].size(); ++j)
|
||||
{
|
||||
pts_item->point_set()->insert(all_points[i][j]);
|
||||
}
|
||||
pts_item->setName(names[i].data());
|
||||
pts_item->invalidateOpenGLBuffers();
|
||||
CGAL::Color c = all_colors[i].front();
|
||||
pts_item->setColor(QColor(c.red(), c.green(), c.blue()));
|
||||
pts_item->setProperty("already_colord", true);
|
||||
result << pts_item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(pts_item);
|
||||
}
|
||||
all_points.clear();
|
||||
names.clear();
|
||||
all_colors.clear();
|
||||
int nb_meshes =
|
||||
CGAL::read_triangle_soups_from_3mf(fileinfo.filePath().toUtf8().toStdString(),
|
||||
all_points, all_polygons, all_colors, names);
|
||||
if(nb_meshes <0 )
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "Error in reading of meshes."<<std::endl;
|
||||
return result;
|
||||
}
|
||||
for(int i = 0; i< nb_meshes; ++i)
|
||||
{
|
||||
PolygonRange triangles = all_polygons[i];
|
||||
PointRange points = all_points[i];
|
||||
ColorRange colors = all_colors[i];
|
||||
bool ok = true;
|
||||
if(!PMP::is_polygon_soup_a_polygon_mesh(triangles))
|
||||
ok = PMP::orient_polygon_soup(points, triangles);
|
||||
if(!ok)
|
||||
{
|
||||
std::cerr<<"Object was not directly orientable, some vertices have been duplicated."<<std::endl;
|
||||
}
|
||||
SMesh mesh;
|
||||
PMP::polygon_soup_to_polygon_mesh(points, triangles, mesh);
|
||||
CGAL::Color first = colors.front();
|
||||
bool need_pmap = false;
|
||||
for(auto color : colors)
|
||||
{
|
||||
if (color != first)
|
||||
{
|
||||
need_pmap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(need_pmap)
|
||||
{
|
||||
SMesh::Property_map<face_descriptor,CGAL::Color> fcolor =
|
||||
mesh.add_property_map<face_descriptor,CGAL::Color>("f:color",first).first;
|
||||
for(std::size_t pid = 0; pid < colors.size(); ++pid)
|
||||
{
|
||||
put(fcolor, face_descriptor(pid), colors[pid]);//should work bc mesh is just created and shouldn't have any destroyed face. Not so sure bc of orientation though.
|
||||
}
|
||||
}
|
||||
Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(mesh);
|
||||
if(first == CGAL::Color(0,0,0,0))
|
||||
first = CGAL::Color(50,80,120,255);
|
||||
sm_item->setColor(QColor(first.red(), first.green(), first.blue()));
|
||||
sm_item->setProperty("already_colored", true);
|
||||
sm_item->setName(names[i].data());
|
||||
sm_item->invalidateOpenGLBuffers();
|
||||
result << sm_item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(sm_item);
|
||||
}
|
||||
ok = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*) Q_DECL_OVERRIDE {return false;}
|
||||
|
||||
|
||||
bool save(QFileInfo fi, QList<CGAL::Three::Scene_item*>& items) Q_DECL_OVERRIDE {
|
||||
|
||||
QList<CGAL::Three::Scene_item*> to_return;
|
||||
std::vector<Scene_surface_mesh_item*> sm_items;
|
||||
std::vector<Scene_points_with_normal_item*> pts_items;
|
||||
std::vector<Scene_polylines_item*> pol_items;
|
||||
for(Scene_item* item : items)
|
||||
{
|
||||
Scene_surface_mesh_item* sm_item =
|
||||
qobject_cast<Scene_surface_mesh_item*>(item);
|
||||
if(sm_item)
|
||||
{
|
||||
sm_items.push_back(sm_item);
|
||||
continue;
|
||||
}
|
||||
|
||||
Scene_points_with_normal_item* pts_item =
|
||||
qobject_cast<Scene_points_with_normal_item*>(item);
|
||||
if(pts_item)
|
||||
{
|
||||
pts_items.push_back(pts_item);
|
||||
continue;
|
||||
}
|
||||
|
||||
Scene_polylines_item* pol_item =
|
||||
qobject_cast<Scene_polylines_item*>(item);
|
||||
if(pol_item)
|
||||
{
|
||||
pol_items.push_back(pol_item);
|
||||
continue;
|
||||
}
|
||||
qDebug()<<item->name()<<" will not be saved.";
|
||||
to_return.push_back(item);
|
||||
}
|
||||
|
||||
HRESULT hResult;
|
||||
NMR::PLib3MFModel * pModel;
|
||||
hResult = NMR::lib3mf_createmodel(&pModel);
|
||||
NMR::PLib3MFModelMeshObject* pMeshObject;
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not create model: " << std::hex << hResult << std::endl;
|
||||
return false;
|
||||
}
|
||||
for(Scene_surface_mesh_item* sm_item : sm_items)
|
||||
{
|
||||
SMesh &mesh = *sm_item->polyhedron();
|
||||
PointRange points;
|
||||
PolygonRange triangles;
|
||||
typedef boost::property_map<SMesh, boost::vertex_point_t>::type VPMap;
|
||||
VPMap vpm = get(boost::vertex_point, mesh);
|
||||
std::unordered_map<boost::graph_traits<SMesh>::vertex_descriptor,
|
||||
std::size_t> vertex_id_map;
|
||||
std::size_t i = 0;
|
||||
for(auto v : mesh.vertices())
|
||||
{
|
||||
points.push_back(get(vpm, v));
|
||||
vertex_id_map[v] = i++;
|
||||
}
|
||||
for(auto f : mesh.faces())
|
||||
{
|
||||
Polygon triangle;
|
||||
for(auto vert : CGAL::vertices_around_face(halfedge(f, mesh), mesh))
|
||||
{
|
||||
triangle.push_back(vertex_id_map[vert]);
|
||||
}
|
||||
triangles.push_back(triangle);
|
||||
}
|
||||
|
||||
std::vector<CGAL::Color> colors;
|
||||
//if item is multicolor, fill colors with f:color
|
||||
if(sm_item->isItemMulticolor())
|
||||
{
|
||||
colors.reserve(triangles.size());
|
||||
SMesh::Property_map<face_descriptor, CGAL::Color> fcolors =
|
||||
mesh.property_map<face_descriptor, CGAL::Color >("f:color").first;
|
||||
for(auto fd : mesh.faces())
|
||||
{
|
||||
colors.push_back(get(fcolors, fd));
|
||||
}
|
||||
}
|
||||
else if(sm_item->hasPatchIds())
|
||||
{
|
||||
colors.reserve(triangles.size());
|
||||
SMesh::Property_map<face_descriptor, int> fpid =
|
||||
mesh.property_map<face_descriptor, int >("f:patch_id").first;
|
||||
for(auto fd : mesh.faces())
|
||||
{
|
||||
int pid = get(fpid, fd);
|
||||
QColor q_color = sm_item->color_vector()[pid];
|
||||
colors.push_back(CGAL::Color(q_color.red(), q_color.green(),
|
||||
q_color.blue(), q_color.alpha()));
|
||||
}
|
||||
}
|
||||
//else fill it with item->color()
|
||||
else
|
||||
{
|
||||
colors.resize(triangles.size());
|
||||
const QColor& c = sm_item->color();
|
||||
for(auto& color : colors)
|
||||
color.set_rgb(c.red(), c.green(), c.blue());
|
||||
}
|
||||
|
||||
CGAL::write_mesh_to_model(points, triangles, colors,
|
||||
sm_item->name().toStdString(), &pMeshObject, pModel);
|
||||
}
|
||||
for(Scene_points_with_normal_item* pts_item : pts_items)
|
||||
{
|
||||
QColor qc = pts_item->color();
|
||||
CGAL::Color color(qc.red(), qc.green(), qc.blue());
|
||||
CGAL::write_point_cloud_to_model(pts_item->point_set()->points(), color,
|
||||
pts_item->name().toStdString(),
|
||||
&pMeshObject, pModel);
|
||||
}
|
||||
for(Scene_polylines_item* pol_item : pol_items)
|
||||
{
|
||||
for(auto pol_it = pol_item->polylines.begin();
|
||||
pol_it != pol_item->polylines.end(); ++pol_it)
|
||||
{
|
||||
QColor qc = pol_item->color();
|
||||
CGAL::Color color(qc.red(), qc.green(), qc.blue());
|
||||
CGAL::write_polyline_to_model(*pol_it,color,
|
||||
pol_item->name().toStdString(),
|
||||
&pMeshObject, pModel);
|
||||
}
|
||||
}
|
||||
CGAL::export_model_to_file(fi.filePath().toUtf8().toStdString(), pModel);
|
||||
items = to_return;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#include "3mf_io_plugin.moc"
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_rvalue_references has_cxx_rvalues)
|
|||
list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_variadic_templates has_cxx_variadic)
|
||||
|
||||
if(has_cxx_rvalues LESS 0 OR has_cxx_variadic LESS 0)
|
||||
message(STATUS "NOTICE: LAS/PLY IO examples require a C++11 compiler and will not be compiled.")
|
||||
message(STATUS "NOTICE : LAS/PLY IO examples require a C++11 compiler and will not be compiled.")
|
||||
else()
|
||||
set(needed_cxx_features cxx_rvalue_references cxx_variadic_templates)
|
||||
|
||||
|
|
@ -73,3 +73,17 @@ else()
|
|||
message(STATUS "NOTICE : the LAS IO plugin needs LAS libraries and will not be compiled.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_path(3MF_INCLUDE_DIR
|
||||
NAMES Model/COM/NMR_DLLInterfaces.h
|
||||
DOC "Path to lib3MF headers"
|
||||
)
|
||||
find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library")
|
||||
|
||||
if(3MF_LIBRARIES AND 3MF_INCLUDE_DIR)
|
||||
include_directories(${3MF_INCLUDE_DIR})
|
||||
polyhedron_demo_plugin(3mf_io_plugin 3mf_io_plugin KEYWORDS IO)
|
||||
target_link_libraries(3mf_io_plugin PRIVATE scene_surface_mesh_item scene_points_with_normal_item scene_polylines_item ${3MF_LIBRARIES})
|
||||
else()
|
||||
message(STATUS "NOTICE : The 3mf_io_plugin requires the lib3MF library, and will not be compiled.")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -17,53 +17,42 @@ using namespace CGAL::Three;
|
|||
|
||||
class Polyhedron_demo_gocad_plugin :
|
||||
public QObject,
|
||||
public Polyhedron_demo_io_plugin_interface,
|
||||
public Polyhedron_demo_plugin_helper
|
||||
public Polyhedron_demo_io_plugin_interface
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "gocad_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" )
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "gocad_io_plugin.json")
|
||||
|
||||
public:
|
||||
void init(QMainWindow* mainWindow,
|
||||
CGAL::Three::Scene_interface* scene_interface,
|
||||
Messages_interface*) {
|
||||
//get the references
|
||||
this->scene = scene_interface;
|
||||
this->mw = mainWindow;
|
||||
}
|
||||
QList<QAction*> actions() const {
|
||||
return QList<QAction*>();
|
||||
}
|
||||
bool applicable(QAction*) const { return false;}
|
||||
|
||||
QString nameFilters() const;
|
||||
QString name() const { return "gocad_plugin"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo, QList<CGAL::Three::Scene_item*>& );
|
||||
};
|
||||
|
||||
QString Polyhedron_demo_gocad_plugin::nameFilters() const {
|
||||
return "GOCAD files (*.ts)";
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_gocad_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_gocad_plugin::canLoad(QFileInfo) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) {
|
||||
QList<Scene_item*>
|
||||
Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||
|
||||
// Open file
|
||||
std::ifstream in(fileinfo.filePath().toUtf8());
|
||||
if(!in) {
|
||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -74,7 +63,10 @@ Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) {
|
|||
if(fileinfo.size() == 0)
|
||||
{
|
||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
SMesh& P = * const_cast<SMesh*>(item->polyhedron());
|
||||
|
||||
|
|
@ -82,7 +74,8 @@ Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) {
|
|||
if(! read_gocad(P, in, name, color)){
|
||||
std::cerr << "Error: Invalid polyhedron" << std::endl;
|
||||
delete item;
|
||||
return 0;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
t.stop();
|
||||
|
|
@ -98,7 +91,10 @@ Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) {
|
|||
item->setColor(qcolor);
|
||||
}
|
||||
item->invalidateOpenGLBuffers();
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_gocad_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
@ -107,8 +103,10 @@ bool Polyhedron_demo_gocad_plugin::canSave(const CGAL::Three::Scene_item* item)
|
|||
return qobject_cast<const Scene_surface_mesh_item*>(item);
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_gocad_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
bool Polyhedron_demo_gocad_plugin::
|
||||
save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
// This plugin supports polyhedrons
|
||||
const Scene_surface_mesh_item* sm_item =
|
||||
qobject_cast<const Scene_surface_mesh_item*>(item);
|
||||
|
|
@ -120,6 +118,7 @@ bool Polyhedron_demo_gocad_plugin::save(const CGAL::Three::Scene_item* item, QFi
|
|||
out.precision (std::numeric_limits<double>::digits10 + 2);
|
||||
SMesh* poly = const_cast<SMesh*>(sm_item->polyhedron());
|
||||
write_gocad(*poly, out, qPrintable(fileinfo.baseName()));
|
||||
items.pop_front();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
using namespace CGAL::Three;
|
||||
class Io_implicit_function_plugin :
|
||||
public QObject,
|
||||
// public Polyhedron_demo_plugin_interface,
|
||||
protected Polyhedron_demo_plugin_helper
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
|||
|
|
@ -1,32 +1,33 @@
|
|||
#include "Scene_points_with_normal_item.h"
|
||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||
|
||||
#include <CGAL/Three/Three.h>
|
||||
#include <CGAL/Three/Scene_item.h>
|
||||
#include <fstream>
|
||||
|
||||
using namespace CGAL::Three;
|
||||
class Polyhedron_demo_las_plugin :
|
||||
public QObject,
|
||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "las_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "las_io_plugin.json")
|
||||
|
||||
public:
|
||||
QString name() const { return "las_plugin"; }
|
||||
QString nameFilters() const { return "LAS files (*.las);;Compressed LAS files (*.laz)"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo fileinfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& );
|
||||
};
|
||||
|
||||
bool Polyhedron_demo_las_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_las_plugin::canLoad(QFileInfo ) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_las_plugin::load(QFileInfo fileinfo) {
|
||||
QList<Scene_item*> Polyhedron_demo_las_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::binary);
|
||||
|
||||
if(!in)
|
||||
|
|
@ -37,11 +38,15 @@ Polyhedron_demo_las_plugin::load(QFileInfo fileinfo) {
|
|||
if(!item->read_las_point_set(in))
|
||||
{
|
||||
delete item;
|
||||
return 0;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_las_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
@ -49,8 +54,9 @@ bool Polyhedron_demo_las_plugin::canSave(const CGAL::Three::Scene_item* item)
|
|||
return qobject_cast<const Scene_points_with_normal_item*>(item);
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_las_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
bool Polyhedron_demo_las_plugin::save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
// Check extension (quietly)
|
||||
std::string extension = fileinfo.suffix().toUtf8().data();
|
||||
if (extension != "las" && extension != "LAS")
|
||||
|
|
@ -63,6 +69,7 @@ bool Polyhedron_demo_las_plugin::save(const CGAL::Three::Scene_item* item, QFile
|
|||
return false;
|
||||
|
||||
std::ofstream out(fileinfo.filePath().toUtf8().data());
|
||||
items.pop_front();
|
||||
return point_set_item->write_las_point_set(out);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,32 +17,37 @@ class Polyhedron_demo_io_nef_plugin :
|
|||
public:
|
||||
QString nameFilters() const;
|
||||
QString name() const { return "io_nef_plugin"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items);
|
||||
};
|
||||
|
||||
QString Polyhedron_demo_io_nef_plugin::nameFilters() const {
|
||||
return "nef files (*.nef3)";
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_io_nef_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_io_nef_plugin::canLoad(QFileInfo) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_io_nef_plugin::load(QFileInfo fileinfo) {
|
||||
QList<Scene_item*> Polyhedron_demo_io_nef_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||
//do not try file with extension different from nef3
|
||||
if (fileinfo.suffix() != "nef3") return 0;
|
||||
if (fileinfo.suffix() != "nef3")
|
||||
{
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
// Open file
|
||||
std::ifstream in(fileinfo.filePath().toUtf8());
|
||||
if(!in) {
|
||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
// Try to read .nef3 in a polyhedron
|
||||
|
|
@ -51,15 +56,22 @@ Polyhedron_demo_io_nef_plugin::load(QFileInfo fileinfo) {
|
|||
if(fileinfo.size() == 0)
|
||||
{
|
||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
if(!item->load(in))
|
||||
{
|
||||
delete item;
|
||||
return 0;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_io_nef_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
@ -68,8 +80,9 @@ bool Polyhedron_demo_io_nef_plugin::canSave(const CGAL::Three::Scene_item* item)
|
|||
return qobject_cast<const Scene_nef_polyhedron_item*>(item);
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_io_nef_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
bool Polyhedron_demo_io_nef_plugin::save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
// This plugin supports polyhedrons and polygon soups
|
||||
const Scene_nef_polyhedron_item* nef_item =
|
||||
qobject_cast<const Scene_nef_polyhedron_item*>(item);
|
||||
|
|
@ -79,6 +92,7 @@ bool Polyhedron_demo_io_nef_plugin::save(const CGAL::Three::Scene_item* item, QF
|
|||
|
||||
std::ofstream out(fileinfo.filePath().toUtf8());
|
||||
out.precision (std::numeric_limits<double>::digits10 + 2);
|
||||
items.pop_front();
|
||||
return (nef_item && nef_item->save(out));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class Polyhedron_demo_off_plugin :
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "off_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "off_io_plugin.json")
|
||||
|
||||
public:
|
||||
bool isDefaultLoader(const Scene_item *item) const
|
||||
|
|
@ -40,22 +40,21 @@ public:
|
|||
}
|
||||
QString name() const { return "off_plugin"; }
|
||||
QString nameFilters() const { return "OFF files (*.off);;Wavefront OBJ (*.obj)"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
CGAL::Three::Scene_item* load_off(QFileInfo fileinfo);
|
||||
CGAL::Three::Scene_item* load_obj(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo fileinfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
CGAL::Three::Scene_item* load_off(QFileInfo fileinfo);
|
||||
CGAL::Three::Scene_item* load_obj(QFileInfo fileinfo);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& );
|
||||
};
|
||||
|
||||
bool Polyhedron_demo_off_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_off_plugin::canLoad(QFileInfo) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_off_plugin::load(QFileInfo fileinfo) {
|
||||
QList<Scene_item*> Polyhedron_demo_off_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||
|
||||
if(fileinfo.size() == 0)
|
||||
{
|
||||
|
|
@ -63,14 +62,41 @@ Polyhedron_demo_off_plugin::load(QFileInfo fileinfo) {
|
|||
Scene_surface_mesh_item* item =
|
||||
new Scene_surface_mesh_item(SMesh());
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
if(fileinfo.suffix().toLower() == "off"){
|
||||
return load_off(fileinfo);
|
||||
Scene_item* item = load_off(fileinfo);
|
||||
if(item){
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
} else if(fileinfo.suffix().toLower() == "obj"){
|
||||
return load_obj(fileinfo);
|
||||
|
||||
Scene_item* item = load_obj(fileinfo);
|
||||
if(item)
|
||||
{
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = true;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -183,8 +209,12 @@ bool Polyhedron_demo_off_plugin::canSave(const CGAL::Three::Scene_item* item)
|
|||
qobject_cast<const Scene_points_with_normal_item*>(item);
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_off_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
|
||||
bool
|
||||
Polyhedron_demo_off_plugin::
|
||||
save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
// This plugin supports point sets, surface_meshes and polygon soups
|
||||
const Scene_points_with_normal_item* points_item =
|
||||
qobject_cast<const Scene_points_with_normal_item*>(item);
|
||||
|
|
@ -200,12 +230,26 @@ bool Polyhedron_demo_off_plugin::save(const CGAL::Three::Scene_item* item, QFile
|
|||
out.precision (std::numeric_limits<double>::digits10 + 2);
|
||||
|
||||
if(fileinfo.suffix().toLower() == "off"){
|
||||
return (sm_item && sm_item->save(out)) ||
|
||||
bool res = (sm_item && sm_item->save(out)) ||
|
||||
(soup_item && soup_item->save(out)) ||
|
||||
(points_item && points_item->write_off_point_set(out));
|
||||
if(res){
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(fileinfo.suffix().toLower() == "obj"){
|
||||
return (sm_item && sm_item->save_obj(out));
|
||||
bool res = (sm_item && sm_item->save_obj(out));
|
||||
if(res)
|
||||
{
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,24 +11,24 @@ class Polyhedron_demo_off_to_nef_plugin :
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "off_to_nef_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "off_to_nef_io_plugin.json")
|
||||
|
||||
public:
|
||||
QString name() const { return "off_to_nef_plugin"; }
|
||||
QString nameFilters() const { return "OFF files, into nef (*.off)"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& );
|
||||
};
|
||||
|
||||
bool Polyhedron_demo_off_to_nef_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_off_to_nef_plugin::canLoad(QFileInfo) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_off_to_nef_plugin::load(QFileInfo fileinfo) {
|
||||
QList<Scene_item*> Polyhedron_demo_off_to_nef_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene){
|
||||
std::ifstream in(fileinfo.filePath().toUtf8());
|
||||
|
||||
if(!in)
|
||||
|
|
@ -38,16 +38,23 @@ Polyhedron_demo_off_to_nef_plugin::load(QFileInfo fileinfo) {
|
|||
{
|
||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
if(!item->load_from_off(in))
|
||||
{
|
||||
delete item;
|
||||
return 0;
|
||||
ok = false;
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
item->setName(fileinfo.baseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_off_to_nef_plugin::canSave(const CGAL::Three::Scene_item*)
|
||||
|
|
@ -55,7 +62,8 @@ bool Polyhedron_demo_off_to_nef_plugin::canSave(const CGAL::Three::Scene_item*)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_off_to_nef_plugin::save(const CGAL::Three::Scene_item*, QFileInfo)
|
||||
bool Polyhedron_demo_off_to_nef_plugin::
|
||||
save(QFileInfo ,QList<CGAL::Three::Scene_item*>&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@
|
|||
#include <CGAL/IO/PLY_writer.h>
|
||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace CGAL::Three;
|
||||
class Polyhedron_demo_ply_plugin :
|
||||
public QObject,
|
||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "ply_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "ply_io_plugin.json")
|
||||
|
||||
public:
|
||||
bool isDefaultLoader(const CGAL::Three::Scene_item *item) const
|
||||
|
|
@ -31,20 +31,22 @@ public:
|
|||
}
|
||||
QString name() const { return "ply_plugin"; }
|
||||
QString nameFilters() const { return "PLY files (*.ply)"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo fileinfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>&);
|
||||
|
||||
};
|
||||
|
||||
bool Polyhedron_demo_ply_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_ply_plugin::
|
||||
canLoad(QFileInfo) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
||||
QList<Scene_item*>
|
||||
Polyhedron_demo_ply_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::binary);
|
||||
|
||||
if(!in)
|
||||
|
|
@ -55,7 +57,8 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
|||
if(fileinfo.size() == 0)
|
||||
{
|
||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||
return 0;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
// Test if input is mesh or point set
|
||||
|
|
@ -99,7 +102,10 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
|||
sm_item->setName(fileinfo.completeBaseName());
|
||||
sm_item->comments() = comments;
|
||||
QApplication::restoreOverrideCursor();
|
||||
return sm_item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(sm_item);
|
||||
return QList<Scene_item*>()<<sm_item;
|
||||
}
|
||||
|
||||
in.clear();
|
||||
|
|
@ -114,14 +120,18 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
|||
if (!(CGAL::read_PLY (in, points, polygons, fcolors, vcolors)))
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item;
|
||||
soup_item->setName(fileinfo.completeBaseName());
|
||||
soup_item->load (points, polygons, fcolors, vcolors);
|
||||
QApplication::restoreOverrideCursor();
|
||||
return soup_item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(soup_item);
|
||||
return QList<Scene_item*>()<<soup_item;
|
||||
}
|
||||
else // Open point set
|
||||
{
|
||||
|
|
@ -131,16 +141,21 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
|||
{
|
||||
delete item;
|
||||
QApplication::restoreOverrideCursor();
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
if(item->has_normals())
|
||||
item->setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode());
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
QApplication::restoreOverrideCursor();
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
QApplication::restoreOverrideCursor();
|
||||
return NULL;
|
||||
ok = true;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_ply_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
@ -152,8 +167,10 @@ bool Polyhedron_demo_ply_plugin::canSave(const CGAL::Three::Scene_item* item)
|
|||
|| qobject_cast<const Scene_textured_surface_mesh_item*>(item));
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_ply_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
bool Polyhedron_demo_ply_plugin::
|
||||
save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
// Check extension (quietly)
|
||||
std::string extension = fileinfo.suffix().toUtf8().data();
|
||||
if (extension != "ply" && extension != "PLY")
|
||||
|
|
@ -179,25 +196,49 @@ bool Polyhedron_demo_ply_plugin::save(const CGAL::Three::Scene_item* item, QFile
|
|||
const Scene_points_with_normal_item* point_set_item =
|
||||
qobject_cast<const Scene_points_with_normal_item*>(item);
|
||||
if (point_set_item)
|
||||
return point_set_item->write_ply_point_set(out, (choice == tr("Binary")));
|
||||
{
|
||||
bool res =
|
||||
point_set_item->write_ply_point_set(out, (choice == tr("Binary")));
|
||||
if(res)
|
||||
items.pop_front();
|
||||
return res;
|
||||
}
|
||||
|
||||
// This plugin supports polygon soups
|
||||
const Scene_polygon_soup_item* soup_item =
|
||||
qobject_cast<const Scene_polygon_soup_item*>(item);
|
||||
if (soup_item)
|
||||
return CGAL::write_PLY (out, soup_item->points(), soup_item->polygons());
|
||||
{
|
||||
bool res =
|
||||
CGAL::write_PLY (out, soup_item->points(), soup_item->polygons());
|
||||
if(res)
|
||||
items.pop_front();
|
||||
return res;
|
||||
}
|
||||
|
||||
// This plugin supports surface meshes
|
||||
const Scene_surface_mesh_item* sm_item =
|
||||
qobject_cast<const Scene_surface_mesh_item*>(item);
|
||||
if (sm_item)
|
||||
return CGAL::write_ply (out, *(sm_item->polyhedron()), sm_item->comments());
|
||||
{
|
||||
bool res =
|
||||
CGAL::write_ply (out, *(sm_item->polyhedron()), sm_item->comments());
|
||||
if(res)
|
||||
items.pop_front();
|
||||
return res;
|
||||
}
|
||||
|
||||
// This plugin supports textured surface meshes
|
||||
const Scene_textured_surface_mesh_item* stm_item =
|
||||
qobject_cast<const Scene_textured_surface_mesh_item*>(item);
|
||||
if (stm_item)
|
||||
return CGAL::write_ply (out, *(stm_item->textured_face_graph()));
|
||||
{
|
||||
bool res =
|
||||
CGAL::write_ply (out, *(stm_item->textured_face_graph()));
|
||||
if(res)
|
||||
items.pop_front();
|
||||
return res;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,17 +17,18 @@ class Polyhedron_demo_polylines_io_plugin :
|
|||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "polylines_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90")
|
||||
|
||||
|
||||
public:
|
||||
// To silent a warning -Woverloaded-virtual
|
||||
// See http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings
|
||||
|
||||
using Polyhedron_demo_io_plugin_interface::init;
|
||||
//! Configures the widget
|
||||
void init(QMainWindow* mainWindow,
|
||||
CGAL::Three::Scene_interface* scene_interface,
|
||||
Messages_interface*) {
|
||||
Messages_interface*) override{
|
||||
//get the references
|
||||
this->scene = scene_interface;
|
||||
this->mw = mainWindow;
|
||||
|
|
@ -43,14 +44,14 @@ public:
|
|||
connect(actionJoin_polylines, &QAction::triggered, this, &Polyhedron_demo_polylines_io_plugin::join);
|
||||
|
||||
}
|
||||
QString name() const { return "polylines_io_plugin"; }
|
||||
QString nameFilters() const { return "Polylines files (*.polylines.txt *.cgal)"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
QString name() const override{ return "polylines_io_plugin"; }
|
||||
QString nameFilters() const override{ return "Polylines files (*.polylines.txt *.cgal)"; }
|
||||
bool canLoad(QFileInfo fileinfo) const override;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override;
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool applicable(QAction* a) const {
|
||||
bool canSave(const CGAL::Three::Scene_item*) override;
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>&) override;
|
||||
bool applicable(QAction* a) const override{
|
||||
bool all_polylines_selected = true;
|
||||
Q_FOREACH(int index, scene->selectionIndices())
|
||||
{
|
||||
|
|
@ -69,7 +70,7 @@ public:
|
|||
else
|
||||
return false;
|
||||
}
|
||||
QList<QAction*> actions() const {
|
||||
QList<QAction*> actions() const override{
|
||||
|
||||
return QList<QAction*>()<<actionSplit_polylines
|
||||
<<actionJoin_polylines;
|
||||
|
|
@ -85,19 +86,31 @@ private:
|
|||
QAction* actionJoin_polylines;
|
||||
};
|
||||
|
||||
bool Polyhedron_demo_polylines_io_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_polylines_io_plugin::canLoad(QFileInfo fileinfo) const{
|
||||
if(!fileinfo.suffix().contains("cgal"))
|
||||
return true;
|
||||
std::ifstream in(fileinfo.filePath().toUtf8());
|
||||
if(!in) {
|
||||
return false;
|
||||
}
|
||||
int first;
|
||||
if(!(in >> first)
|
||||
|| first <= 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) {
|
||||
QList<Scene_item*>
|
||||
Polyhedron_demo_polylines_io_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene){
|
||||
|
||||
// Open file
|
||||
std::ifstream ifs(fileinfo.filePath().toUtf8());
|
||||
if(!ifs) {
|
||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
if(fileinfo.size() == 0)
|
||||
|
|
@ -105,7 +118,10 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) {
|
|||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||
Scene_polylines_item* item = new Scene_polylines_item;
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
std::list<std::vector<Scene_polylines_item::Point_3> > polylines;
|
||||
|
|
@ -123,7 +139,11 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) {
|
|||
Scene_polylines_item::Point_3 p;
|
||||
ifs >> p;
|
||||
polyline.push_back(p);
|
||||
if(!ifs.good()) return 0;
|
||||
if(!ifs.good())
|
||||
{
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
}
|
||||
std::string line_remainder;
|
||||
std::getline(ifs, line_remainder);
|
||||
|
|
@ -136,9 +156,17 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) {
|
|||
std::cerr << " (metadata: \"" << qPrintable(metadata) << "\")\n";
|
||||
} else {
|
||||
}
|
||||
if(ifs.bad() || ifs.fail()) return 0;
|
||||
if(ifs.bad() || ifs.fail())
|
||||
{
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
}
|
||||
if(counter == 0)
|
||||
{
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
if(counter == 0) return 0;
|
||||
Scene_polylines_item* item = new Scene_polylines_item;
|
||||
item->polylines = polylines;
|
||||
item->setName(fileinfo.baseName());
|
||||
|
|
@ -146,7 +174,10 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) {
|
|||
item->setProperty("polylines metadata", polylines_metadata);
|
||||
std::cerr << "Number of polylines in item: " << item->polylines.size() << std::endl;
|
||||
item->invalidateOpenGLBuffers();
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_polylines_io_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
@ -154,8 +185,10 @@ bool Polyhedron_demo_polylines_io_plugin::canSave(const CGAL::Three::Scene_item*
|
|||
return qobject_cast<const Scene_polylines_item*>(item) != 0;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_polylines_io_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
bool Polyhedron_demo_polylines_io_plugin::
|
||||
save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
const Scene_polylines_item* poly_item =
|
||||
qobject_cast<const Scene_polylines_item*>(item);
|
||||
|
||||
|
|
@ -188,7 +221,10 @@ bool Polyhedron_demo_polylines_io_plugin::save(const CGAL::Three::Scene_item* it
|
|||
}
|
||||
out << std::endl;
|
||||
}
|
||||
return (bool) out;
|
||||
bool res = (bool) out;
|
||||
if(res)
|
||||
items.pop_front();
|
||||
return res;
|
||||
}
|
||||
|
||||
void Polyhedron_demo_polylines_io_plugin::split()
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
#include "SMesh_type.h"
|
||||
|
||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
|
||||
#include <CGAL/Three/Three.h>
|
||||
#include <fstream>
|
||||
|
||||
|
|
@ -25,66 +23,60 @@
|
|||
using namespace CGAL::Three;
|
||||
class Polyhedron_demo_stl_plugin :
|
||||
public QObject,
|
||||
public Polyhedron_demo_io_plugin_interface,
|
||||
public Polyhedron_demo_plugin_helper
|
||||
public Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "stl_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "stl_io_plugin.json")
|
||||
|
||||
public:
|
||||
void init(QMainWindow* mainWindow,
|
||||
CGAL::Three::Scene_interface* scene_interface,
|
||||
Messages_interface*) {
|
||||
//get the references
|
||||
this->scene = scene_interface;
|
||||
this->mw = mainWindow;
|
||||
}
|
||||
QList<QAction*> actions() const {
|
||||
return QList<QAction*>();
|
||||
}
|
||||
bool applicable(QAction*) const { return false;}
|
||||
QString nameFilters() const;
|
||||
QString name() const { return "stl_plugin"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo fileinfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>&);
|
||||
};
|
||||
|
||||
QString Polyhedron_demo_stl_plugin::nameFilters() const {
|
||||
return "STL files (*.stl)";
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_stl_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_stl_plugin::canLoad(QFileInfo) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) {
|
||||
|
||||
QList<Scene_item*>
|
||||
Polyhedron_demo_stl_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene){
|
||||
|
||||
// Open file
|
||||
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios::in | std::ios::binary);
|
||||
if(!in) {
|
||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
if(fileinfo.size() == 0)
|
||||
{
|
||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||
Scene_surface_mesh_item* item = new Scene_surface_mesh_item();
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
std::vector<std::array<double, 3> > points;
|
||||
std::vector<std::array<int, 3> > triangles;
|
||||
if (!CGAL::read_STL(in, points, triangles))
|
||||
{
|
||||
std::cerr << "Error: invalid STL file" << std::endl;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
try{
|
||||
|
|
@ -98,7 +90,10 @@ Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) {
|
|||
else{
|
||||
Scene_surface_mesh_item* item = new Scene_surface_mesh_item(SM);
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
}
|
||||
catch(...){}
|
||||
|
|
@ -106,7 +101,10 @@ Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) {
|
|||
Scene_polygon_soup_item* item = new Scene_polygon_soup_item();
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
item->load(points, triangles);
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_stl_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
@ -114,8 +112,10 @@ bool Polyhedron_demo_stl_plugin::canSave(const CGAL::Three::Scene_item* item)
|
|||
return qobject_cast<const Scene_surface_mesh_item*>(item);
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_stl_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
bool Polyhedron_demo_stl_plugin::
|
||||
save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
const Scene_surface_mesh_item* sm_item =
|
||||
qobject_cast<const Scene_surface_mesh_item*>(item);
|
||||
|
||||
|
|
@ -144,6 +144,7 @@ bool Polyhedron_demo_stl_plugin::save(const CGAL::Three::Scene_item* item, QFile
|
|||
if (sm_item)
|
||||
{
|
||||
CGAL::write_STL(*sm_item->face_graph(), out);
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
#include <QMainWindow>
|
||||
#include <QObject>
|
||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
|
||||
#include <CGAL/Three/Scene_group_item.h>
|
||||
#include <CGAL/Three/Three.h>
|
||||
|
||||
|
|
@ -20,41 +18,44 @@
|
|||
using namespace CGAL::Three;
|
||||
class Surf_io_plugin:
|
||||
public QObject,
|
||||
public Polyhedron_demo_io_plugin_interface,
|
||||
public Polyhedron_demo_plugin_helper
|
||||
public Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "surf_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "surf_io_plugin.json")
|
||||
|
||||
public:
|
||||
void init(QMainWindow* mainWindow,
|
||||
CGAL::Three::Scene_interface* scene_interface,
|
||||
Messages_interface*) {
|
||||
//get the references
|
||||
this->scene = scene_interface;
|
||||
this->mw = mainWindow;
|
||||
}
|
||||
QList<QAction*> actions() const {
|
||||
return QList<QAction*>();
|
||||
}
|
||||
bool applicable(QAction*) const { return false;}
|
||||
|
||||
QString name() const { return "surf_io_plugin"; }
|
||||
QString nameFilters() const { return "Amira files (*.surf)"; }
|
||||
bool canLoad() const{ return true; }
|
||||
bool canLoad(QFileInfo) const{ return true; }
|
||||
template<class FaceGraphItem>
|
||||
CGAL::Three::Scene_item* actual_load(QFileInfo fileinfo);
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*) { return false; }
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo) { return false; }
|
||||
bool save(QFileInfo ,QList<CGAL::Three::Scene_item*>& ) { return false; }
|
||||
};
|
||||
|
||||
|
||||
CGAL::Three::Scene_item* Surf_io_plugin::load(QFileInfo fileinfo)
|
||||
QList<Scene_item*>
|
||||
Surf_io_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene)
|
||||
{
|
||||
return actual_load<Scene_surface_mesh_item>(fileinfo);
|
||||
Scene_item* item =
|
||||
actual_load<Scene_surface_mesh_item>(fileinfo);
|
||||
if(item)
|
||||
{
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
}
|
||||
template< class FaceGraphItem>
|
||||
CGAL::Three::Scene_item* Surf_io_plugin::actual_load(QFileInfo fileinfo)
|
||||
|
|
@ -103,8 +104,8 @@ CGAL::Three::Scene_item* Surf_io_plugin::actual_load(QFileInfo fileinfo)
|
|||
FaceGraphItem *patch = new FaceGraphItem(patches[i]);
|
||||
patch->setName(QString("Patch #%1").arg(i));
|
||||
patch->setColor(colors_[i]);
|
||||
scene->addItem(patch);
|
||||
scene->changeGroup(patch, group);
|
||||
CGAL::Three::Three::scene()->addItem(patch);
|
||||
CGAL::Three::Three::scene()->changeGroup(patch, group);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ class Polyhedron_demo_vtk_plugin :
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "vtk_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "vtk_io_plugin.json")
|
||||
|
||||
public:
|
||||
typedef boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||
|
|
@ -308,8 +308,9 @@ public:
|
|||
}
|
||||
|
||||
|
||||
bool save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
std::string extension = fileinfo.suffix().toLower().toStdString();
|
||||
if ( extension != "vtk" && extension != "vtp" && extension != "vtu")
|
||||
return false;
|
||||
|
|
@ -356,10 +357,11 @@ public:
|
|||
|
||||
CGAL::output_to_vtu(os, c3t3);
|
||||
}
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canLoad() const { return true; }
|
||||
bool canLoad(QFileInfo) const { return true; }
|
||||
|
||||
template <class vtkReader>
|
||||
vtkSmartPointer<vtkReader>
|
||||
|
|
@ -374,11 +376,14 @@ public:
|
|||
return reader;
|
||||
}
|
||||
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo)
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene)
|
||||
{
|
||||
std::string extension=fileinfo.suffix().toLower().toStdString();
|
||||
if (extension != "vtk" && extension != "vtp" && extension != "vtu")
|
||||
return 0;
|
||||
{
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
std::string fname = fileinfo.absoluteFilePath().toStdString();
|
||||
|
||||
|
|
@ -389,7 +394,10 @@ public:
|
|||
Scene_facegraph_item* item =
|
||||
new Scene_facegraph_item();
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkPointSet> data;
|
||||
|
|
@ -421,7 +429,8 @@ public:
|
|||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.exec();
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
if (obs->GetWarning())
|
||||
{
|
||||
|
|
@ -442,7 +451,8 @@ public:
|
|||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.exec();
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
if (obs->GetWarning())
|
||||
{
|
||||
|
|
@ -491,7 +501,10 @@ public:
|
|||
}
|
||||
else{
|
||||
poly_item->setName(fileinfo.baseName());
|
||||
return poly_item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(poly_item);
|
||||
return QList<Scene_item*>()<<poly_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -592,7 +605,10 @@ public:
|
|||
}
|
||||
else{
|
||||
c3t3_item->setName(fileinfo.baseName());
|
||||
return c3t3_item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(c3t3_item);
|
||||
return QList<Scene_item*>()<<c3t3_item;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -611,12 +627,19 @@ public:
|
|||
}
|
||||
else{
|
||||
polyline_item->setName(fileinfo.baseName());
|
||||
return polyline_item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(polyline_item);
|
||||
return QList<Scene_item*>()<<polyline_item;
|
||||
}
|
||||
}
|
||||
|
||||
if(group)
|
||||
return group;
|
||||
if(group){
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(group);
|
||||
return QList<Scene_item*>()<<group;
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
QMessageBox::warning(CGAL::Three::Three::mainWindow(),
|
||||
|
|
@ -630,7 +653,10 @@ public:
|
|||
point_item->point_set()->insert(Point_3(p[0], p[1], p[2]));
|
||||
}
|
||||
point_item->setName(fileinfo.baseName());
|
||||
return point_item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(point_item);
|
||||
return QList<Scene_item*>()<<point_item;
|
||||
}
|
||||
}; // end Polyhedron_demo_vtk_plugin
|
||||
|
||||
|
|
|
|||
|
|
@ -15,32 +15,34 @@ class Polyhedron_demo_xyz_plugin :
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "xyz_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "xyz_io_plugin.json")
|
||||
|
||||
public:
|
||||
|
||||
QString name() const { return "xyz_plugin"; }
|
||||
QString nameFilters() const { return "XYZ as Point Set (*.xyz);;Point Set with Normal (*.pwn)"; }
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>&);
|
||||
};
|
||||
|
||||
bool Polyhedron_demo_xyz_plugin::canLoad() const {
|
||||
bool Polyhedron_demo_xyz_plugin::canLoad(QFileInfo) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_xyz_plugin::load(QFileInfo fileinfo)
|
||||
QList<Scene_item*>
|
||||
Polyhedron_demo_xyz_plugin::
|
||||
load(QFileInfo fileinfo, bool& ok, bool add_to_scene)
|
||||
{
|
||||
// Open file
|
||||
std::ifstream in(fileinfo.filePath().toUtf8().data());
|
||||
if(!in) {
|
||||
std::cerr << "Error! Cannot open file " << fileinfo.filePath().toStdString() << std::endl;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -50,19 +52,26 @@ Polyhedron_demo_xyz_plugin::load(QFileInfo fileinfo)
|
|||
Scene_points_with_normal_item* item =
|
||||
new Scene_points_with_normal_item();
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
// Read .xyz in a point set
|
||||
Scene_points_with_normal_item* point_set_item = new Scene_points_with_normal_item;
|
||||
point_set_item->setName(fileinfo.completeBaseName());
|
||||
if(!point_set_item->read_xyz_point_set(in)) {
|
||||
delete point_set_item;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
if(point_set_item->has_normals())
|
||||
point_set_item->setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode());
|
||||
|
||||
return point_set_item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(point_set_item);
|
||||
return QList<Scene_item*>()<<point_set_item;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_xyz_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
@ -71,8 +80,10 @@ bool Polyhedron_demo_xyz_plugin::canSave(const CGAL::Three::Scene_item* item)
|
|||
return qobject_cast<const Scene_points_with_normal_item*>(item);
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_xyz_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
bool Polyhedron_demo_xyz_plugin::
|
||||
save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_item* item = items.front();
|
||||
// Check extension (quietly)
|
||||
std::string extension = fileinfo.suffix().toUtf8().data();
|
||||
if (extension != "xyz" && extension != "XYZ" &&
|
||||
|
|
@ -88,7 +99,10 @@ bool Polyhedron_demo_xyz_plugin::save(const CGAL::Three::Scene_item* item, QFile
|
|||
// Save point set as .xyz
|
||||
std::ofstream out(fileinfo.filePath().toUtf8().data());
|
||||
out.precision (std::numeric_limits<double>::digits10 + 2);
|
||||
return point_set_item->write_xyz_point_set(out);
|
||||
bool res = point_set_item->write_xyz_point_set(out);
|
||||
if(res)
|
||||
items.pop_front();
|
||||
return res;
|
||||
}
|
||||
|
||||
#include "XYZ_io_plugin.moc"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class LCC_io_plugin :
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "lcc_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "lcc_io_plugin.json")
|
||||
|
||||
public:
|
||||
bool isDefaultLoader(const CGAL::Three::Scene_item *item) const
|
||||
|
|
@ -33,13 +33,14 @@ public:
|
|||
"3-map files (*.3map)";
|
||||
}
|
||||
|
||||
bool canLoad() const { return true; }
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo){
|
||||
bool canLoad(QFileInfo) const { return true; }
|
||||
QList<CGAL::Three::Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true){
|
||||
// Open file
|
||||
std::ifstream ifs(fileinfo.filePath().toUtf8());
|
||||
if(!ifs) {
|
||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
||||
return nullptr;
|
||||
ok = false;
|
||||
return QList<CGAL::Three::Scene_item*>();
|
||||
}
|
||||
|
||||
Scene_lcc_item::LCC lcc;
|
||||
|
|
@ -53,17 +54,21 @@ public:
|
|||
}
|
||||
if(!res)
|
||||
{
|
||||
return nullptr;
|
||||
ok = false;
|
||||
return QList<CGAL::Three::Scene_item*>();
|
||||
}
|
||||
Scene_lcc_item* new_item = new Scene_lcc_item(lcc);
|
||||
new_item->setName(fileinfo.fileName());
|
||||
new_item->invalidateOpenGLBuffers();
|
||||
return new_item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(new_item);
|
||||
ok = true;
|
||||
return QList<CGAL::Three::Scene_item*>()<<new_item;
|
||||
}
|
||||
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*){return false;}
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo){
|
||||
bool save(QFileInfo, QList<CGAL::Three::Scene_item*>& ){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#include "Scene_c3t3_item.h"
|
||||
#include <CGAL/Mesh_3/tet_soup_to_c3t3.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
||||
#include <CGAL/Three/Three.h>
|
||||
#include <CGAL/IO/File_avizo.h>
|
||||
#include <iostream>
|
||||
|
|
@ -12,59 +11,63 @@
|
|||
|
||||
class Polyhedron_demo_c3t3_binary_io_plugin :
|
||||
public QObject,
|
||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface,
|
||||
public CGAL::Three::Polyhedron_demo_plugin_interface
|
||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "c3t3_io_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "c3t3_io_plugin.json")
|
||||
|
||||
public:
|
||||
void init(QMainWindow*, CGAL::Three::Scene_interface* sc, Messages_interface*)
|
||||
{
|
||||
this->scene = sc;
|
||||
}
|
||||
QString name() const { return "C3t3_io_plugin"; }
|
||||
QString nameFilters() const { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma)"; }
|
||||
QString saveNameFilters() const { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma);;avizo (*.am);;OFF files (*.off)"; }
|
||||
QString loadNameFilters() const { return "binary files (*.cgal);;ascii (*.mesh)"; }
|
||||
QList<QAction*> actions() const
|
||||
{
|
||||
return QList<QAction*>();
|
||||
}
|
||||
bool applicable(QAction*) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
bool canLoad(QFileInfo) const;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& );
|
||||
|
||||
private:
|
||||
bool try_load_other_binary_format(std::istream& in, C3t3& c3t3);
|
||||
bool try_load_a_cdt_3(std::istream& in, C3t3& c3t3);
|
||||
CGAL::Three::Scene_interface* scene;
|
||||
};
|
||||
|
||||
|
||||
bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad() const {
|
||||
return true;
|
||||
bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad(QFileInfo fi) const {
|
||||
if(!fi.suffix().contains("cgal"))
|
||||
return true;
|
||||
std::ifstream in(fi.filePath().toUtf8(),
|
||||
std::ios_base::in|std::ios_base::binary);
|
||||
if(!in) {
|
||||
std::cerr << "Error! Cannot open file "
|
||||
<< (const char*)fi.filePath().toUtf8() << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::string line;
|
||||
std::istringstream iss;
|
||||
std::getline (in,line);
|
||||
iss.str(line);
|
||||
std::string keyword;
|
||||
if (iss >> keyword)
|
||||
if (keyword == "binary")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
||||
QList<Scene_item*>
|
||||
Polyhedron_demo_c3t3_binary_io_plugin::load(
|
||||
QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||
|
||||
// Open file
|
||||
ok = true;
|
||||
std::ifstream in(fileinfo.filePath().toUtf8(),
|
||||
std::ios_base::in|std::ios_base::binary);
|
||||
if(!in) {
|
||||
std::cerr << "Error! Cannot open file "
|
||||
<< (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
Scene_c3t3_item* item = new Scene_c3t3_item();
|
||||
|
||||
|
|
@ -72,7 +75,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
|||
{
|
||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
return item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<< item;
|
||||
}
|
||||
if(fileinfo.suffix().toLower() == "cgal")
|
||||
{
|
||||
|
|
@ -80,7 +85,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
|||
|
||||
|
||||
if(item->load_binary(in)) {
|
||||
return item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>() << item;
|
||||
}
|
||||
|
||||
item->c3t3().clear();
|
||||
|
|
@ -89,7 +96,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
|||
item->c3t3_changed();
|
||||
item->changed();
|
||||
item->resetCutPlane();
|
||||
return item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<< item;
|
||||
}
|
||||
|
||||
item->c3t3().clear();
|
||||
|
|
@ -98,7 +107,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
|||
item->c3t3_changed();
|
||||
item->changed();
|
||||
item->resetCutPlane();
|
||||
return item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
}
|
||||
else if (fileinfo.suffix().toLower() == "mesh")
|
||||
|
|
@ -154,7 +165,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
|||
|
||||
item->c3t3_changed();
|
||||
item->resetCutPlane();
|
||||
return item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
else if(item->c3t3().triangulation().number_of_finite_cells() == 0)
|
||||
{
|
||||
|
|
@ -168,7 +181,8 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
|||
|
||||
// if all loading failed...
|
||||
delete item;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_c3t3_binary_io_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
@ -179,51 +193,63 @@ bool Polyhedron_demo_c3t3_binary_io_plugin::canSave(const CGAL::Three::Scene_ite
|
|||
|
||||
bool
|
||||
Polyhedron_demo_c3t3_binary_io_plugin::
|
||||
save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo)
|
||||
save(QFileInfo fileinfo, QList<Scene_item *> &items)
|
||||
{
|
||||
const Scene_c3t3_item* c3t3_item = qobject_cast<const Scene_c3t3_item*>(item);
|
||||
if ( NULL == c3t3_item )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Scene_item* item = items.front();
|
||||
const Scene_c3t3_item* c3t3_item = qobject_cast<const Scene_c3t3_item*>(item);
|
||||
if ( NULL == c3t3_item )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QString path = fileinfo.absoluteFilePath();
|
||||
QString path = fileinfo.absoluteFilePath();
|
||||
|
||||
if(path.endsWith(".cgal"))
|
||||
{
|
||||
if(path.endsWith(".cgal"))
|
||||
{
|
||||
std::ofstream out(fileinfo.filePath().toUtf8(),
|
||||
std::ios_base::out|std::ios_base::binary);
|
||||
std::ios_base::out|std::ios_base::binary);
|
||||
|
||||
return out && c3t3_item->save_binary(out);
|
||||
}
|
||||
|
||||
else if (fileinfo.suffix() == "mesh")
|
||||
{
|
||||
std::ofstream medit_file (qPrintable(path));
|
||||
c3t3_item->c3t3().output_to_medit(medit_file,true,true);
|
||||
return true;
|
||||
}
|
||||
else if (fileinfo.suffix() == "ma")
|
||||
{
|
||||
std::ofstream maya_file (qPrintable(path));
|
||||
c3t3_item->c3t3().output_to_maya(
|
||||
maya_file,true);
|
||||
return true;
|
||||
}
|
||||
else if (fileinfo.suffix() == "am")
|
||||
{
|
||||
std::ofstream avizo_file (qPrintable(path));
|
||||
CGAL::output_to_avizo(avizo_file, c3t3_item->c3t3());
|
||||
return true;
|
||||
}
|
||||
else if (fileinfo.suffix() == "off")
|
||||
{
|
||||
std::ofstream off_file(qPrintable(path));
|
||||
c3t3_item->c3t3().output_facets_in_complex_to_off(off_file);
|
||||
return true;
|
||||
}
|
||||
bool ok = out && c3t3_item->save_binary(out);
|
||||
if(!ok)
|
||||
return false;
|
||||
else
|
||||
return false;
|
||||
{
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (fileinfo.suffix() == "mesh")
|
||||
{
|
||||
std::ofstream medit_file (qPrintable(path));
|
||||
c3t3_item->c3t3().output_to_medit(medit_file,true,true);
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
else if (fileinfo.suffix() == "ma")
|
||||
{
|
||||
std::ofstream maya_file (qPrintable(path));
|
||||
c3t3_item->c3t3().output_to_maya(
|
||||
maya_file,true);
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
else if (fileinfo.suffix() == "am")
|
||||
{
|
||||
std::ofstream avizo_file (qPrintable(path));
|
||||
CGAL::output_to_avizo(avizo_file, c3t3_item->c3t3());
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
else if (fileinfo.suffix() == "off")
|
||||
{
|
||||
std::ofstream off_file(qPrintable(path));
|
||||
c3t3_item->c3t3().output_facets_in_complex_to_off(off_file);
|
||||
items.pop_front();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
struct Fake_mesh_domain {
|
||||
|
|
|
|||
|
|
@ -207,16 +207,16 @@ class Io_image_plugin :
|
|||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "io_image_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "io_image_plugin.json")
|
||||
|
||||
public:
|
||||
|
||||
bool applicable(QAction*) const {
|
||||
bool applicable(QAction*) const override{
|
||||
return qobject_cast<Scene_image_item*>(scene->item(scene->mainSelectionIndex()));
|
||||
}
|
||||
|
||||
|
||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface *mi) {
|
||||
using Polyhedron_demo_io_plugin_interface::init;
|
||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface *mi) override {
|
||||
this->message_interface = mi;
|
||||
this->scene = scene_interface;
|
||||
this->mw = mainWindow;
|
||||
|
|
@ -270,10 +270,10 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
QList<QAction*> actions() const {
|
||||
QList<QAction*> actions() const override{
|
||||
return QList<QAction*>() << planeSwitch;
|
||||
}
|
||||
virtual void closure()
|
||||
virtual void closure() override
|
||||
{
|
||||
QDockWidget* controlDockWidget = mw->findChild<QDockWidget*>("volumePlanesControl");
|
||||
if(controlDockWidget)
|
||||
|
|
@ -281,18 +281,21 @@ public:
|
|||
}
|
||||
Io_image_plugin() : planeSwitch(NULL) {}
|
||||
|
||||
QString nameFilters() const;
|
||||
bool canLoad() const;
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
||||
QString nameFilters() const override;
|
||||
bool canLoad(QFileInfo) const override;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override;
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item*);
|
||||
bool save(const CGAL::Three::Scene_item* item, QFileInfo fi) {
|
||||
bool canSave(const CGAL::Three::Scene_item*) override;
|
||||
bool save(QFileInfo fileinfo, QList<CGAL::Three::Scene_item*>& items ) override{
|
||||
Scene_item* item = items.front();
|
||||
const Scene_image_item* im_item = qobject_cast<const Scene_image_item*>(item);
|
||||
|
||||
point_image p_im = *im_item->image()->image();
|
||||
return _writeImage(&p_im, fi.filePath().toUtf8()) == 0;
|
||||
bool ok = _writeImage(&p_im, fileinfo.filePath().toUtf8()) == 0;
|
||||
items.pop_front();
|
||||
return ok;
|
||||
}
|
||||
QString name() const { return "segmented images"; }
|
||||
QString name() const override{ return "segmented images"; }
|
||||
|
||||
|
||||
public Q_SLOTS:
|
||||
|
|
@ -965,7 +968,7 @@ QString Io_image_plugin::nameFilters() const {
|
|||
}
|
||||
|
||||
|
||||
bool Io_image_plugin::canLoad() const {
|
||||
bool Io_image_plugin::canLoad(QFileInfo) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -987,8 +990,11 @@ void convert(Image* image)
|
|||
image->image()->wdim = 4;
|
||||
image->image()->wordKind = WK_FLOAT;
|
||||
}
|
||||
CGAL::Three::Scene_item*
|
||||
Io_image_plugin::load(QFileInfo fileinfo) {
|
||||
|
||||
QList<Scene_item*>
|
||||
Io_image_plugin::load(QFileInfo fileinfo, bool& ok, bool add_to_scene)
|
||||
{
|
||||
ok = true;
|
||||
QApplication::restoreOverrideCursor();
|
||||
Image* image = new Image;
|
||||
if(fileinfo.suffix() != "H" && fileinfo.suffix() != "HH" &&
|
||||
|
|
@ -1075,8 +1081,9 @@ Io_image_plugin::load(QFileInfo fileinfo) {
|
|||
success = false;
|
||||
}
|
||||
if(!success){
|
||||
ok = false;
|
||||
delete image;
|
||||
return NULL;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
}
|
||||
//read a sep file
|
||||
|
|
@ -1117,7 +1124,8 @@ Io_image_plugin::load(QFileInfo fileinfo) {
|
|||
if(return_code != QDialog::Accepted)
|
||||
{
|
||||
delete image;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
// Get selected precision
|
||||
|
|
@ -1145,7 +1153,9 @@ Io_image_plugin::load(QFileInfo fileinfo) {
|
|||
else
|
||||
image_item = new Scene_image_item(image,voxel_scale, false);
|
||||
image_item->setName(fileinfo.baseName());
|
||||
return image_item;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(image_item);
|
||||
return QList<Scene_item*>() << image_item;
|
||||
}
|
||||
|
||||
bool Io_image_plugin::canSave(const CGAL::Three::Scene_item* item)
|
||||
|
|
|
|||
|
|
@ -560,7 +560,7 @@ void Volume_plane<T>::draw(Viewer_interface *viewer) const {
|
|||
template<typename T>
|
||||
bool Volume_plane<T>::eventFilter(QObject *sender, QEvent *event)
|
||||
{
|
||||
CGAL::QGLViewer* viewer = qobject_cast<CGAL::QGLViewer*>(sender);
|
||||
CGAL::Three::Viewer_interface* viewer = qobject_cast<CGAL::Three::Viewer_interface*>(sender);
|
||||
if(!viewer)
|
||||
return false;
|
||||
if(event->type() == QEvent::MouseButtonPress)
|
||||
|
|
|
|||
|
|
@ -73,12 +73,12 @@ class Polyhedron_demo_selection_plugin :
|
|||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "selection_plugin.json")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90")
|
||||
public:
|
||||
QString nameFilters() const { return "Selection files(*.selection.txt)"; }
|
||||
QString name() const { return "selection_sm_plugin"; }
|
||||
QString nameFilters() const override { return "Selection files(*.selection.txt)"; }
|
||||
QString name() const override { return "selection_sm_plugin"; }
|
||||
|
||||
bool canLoad() const {
|
||||
bool canLoad(QFileInfo) const override {
|
||||
Scene_item * item = CGAL::Three::Three::scene()->item(
|
||||
CGAL::Three::Three::scene()->mainSelectionIndex());
|
||||
Scene_facegraph_item* fg_item = qobject_cast<Scene_facegraph_item*>(item);
|
||||
|
|
@ -91,36 +91,48 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo) {
|
||||
if(fileinfo.suffix().toLower() != "txt") return 0;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override {
|
||||
if(fileinfo.suffix().toLower() != "txt")
|
||||
{
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
// There will be no actual loading at this step.
|
||||
Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item();
|
||||
if(!item->load(fileinfo.filePath().toStdString())) {
|
||||
delete item;
|
||||
return NULL;
|
||||
ok = false;
|
||||
return QList<Scene_item*>();
|
||||
}
|
||||
item->setName(fileinfo.baseName());
|
||||
return item;
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>()<<item;
|
||||
}
|
||||
|
||||
bool canSave(const CGAL::Three::Scene_item* scene_item) {
|
||||
bool canSave(const CGAL::Three::Scene_item* scene_item) override {
|
||||
return qobject_cast<const Scene_polyhedron_selection_item*>(scene_item);
|
||||
}
|
||||
bool save(const CGAL::Three::Scene_item* scene_item, QFileInfo fileinfo) {
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items) override {
|
||||
Scene_item* scene_item = items.front();
|
||||
const Scene_polyhedron_selection_item* item = qobject_cast<const Scene_polyhedron_selection_item*>(scene_item);
|
||||
if(item == NULL) { return false; }
|
||||
|
||||
return item->save(fileinfo.filePath().toStdString());
|
||||
bool res = item->save(fileinfo.filePath().toStdString());
|
||||
if(res)
|
||||
items.pop_front();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool applicable(QAction*) const {
|
||||
bool applicable(QAction*) const override {
|
||||
return qobject_cast<Scene_face_graph_item*>(scene->item(scene->mainSelectionIndex()))
|
||||
|| qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex()));
|
||||
}
|
||||
void print_message(QString message) { CGAL::Three::Three::information(message); }
|
||||
QList<QAction*> actions() const { return QList<QAction*>() << actionSelection; }
|
||||
|
||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) {
|
||||
QList<QAction*> actions() const override { return QList<QAction*>() << actionSelection; }
|
||||
using Polyhedron_demo_io_plugin_interface::init;
|
||||
virtual void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override{
|
||||
mw = mainWindow;
|
||||
scene = scene_interface;
|
||||
messages = m;
|
||||
|
|
@ -204,7 +216,7 @@ public:
|
|||
operations_map[operations_strings[8]] = 8;
|
||||
operations_map[operations_strings[9]] = 9;
|
||||
}
|
||||
virtual void closure()
|
||||
virtual void closure() override
|
||||
{
|
||||
dock_widget->hide();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class Polyhedron_demo_features_detection_plugin :
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
|
||||
QAction* actionDetectFeatures;
|
||||
public:
|
||||
QList<QAction*> actions() const { return QList<QAction*>() << actionDetectFeatures; }
|
||||
|
|
|
|||
|
|
@ -1633,14 +1633,23 @@ void Scene_c3t3_item::show_intersection(bool b)
|
|||
d->intersection->setName("Intersection tetrahedra");
|
||||
d->intersection->setRenderingMode(renderingMode());
|
||||
connect(d->intersection, SIGNAL(destroyed()), this, SLOT(reset_intersection_item()));
|
||||
scene->addItem(d->intersection);
|
||||
scene->changeGroup(d->intersection, this);
|
||||
lockChild(d->intersection);
|
||||
|
||||
BOOST_FOREACH(auto v, CGAL::QGLViewer::QGLViewerPool())
|
||||
{
|
||||
CGAL::Three::Viewer_interface* viewer = static_cast<CGAL::Three::Viewer_interface*>(v);
|
||||
d->are_intersection_buffers_filled[viewer] = false;
|
||||
if(!d->areInterBufFilled(viewer))
|
||||
{
|
||||
//initGL
|
||||
Scene_c3t3_item* ncthis = const_cast<Scene_c3t3_item*>(this);
|
||||
ncthis->d->computeIntersections(viewer);
|
||||
d->are_intersection_buffers_filled[viewer] = true;
|
||||
ncthis->show_intersection(true);
|
||||
}
|
||||
}
|
||||
scene->addItem(d->intersection);
|
||||
scene->changeGroup(d->intersection, this);
|
||||
lockChild(d->intersection);
|
||||
}
|
||||
else if (!b && d->intersection!=NULL)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -286,6 +286,14 @@ void Scene_nef_polyhedron_item_priv::compute_normals_and_vertices(void) const
|
|||
|
||||
|
||||
Nef_polyhedron::Vector_3 v = f->plane().orthogonal_vector();
|
||||
if(f->plane().a() != 0)
|
||||
v /= f->plane().a();
|
||||
else if(f->plane().b() != 0)
|
||||
v /= f->plane().b();
|
||||
else if(f->plane().c() != 0)
|
||||
v /= f->plane().c();
|
||||
else if(f->plane().d() != 0)
|
||||
v /= f->plane().d();
|
||||
GLfloat normal[3];
|
||||
normal[0] = CGAL::to_double(v.x());
|
||||
normal[1] = CGAL::to_double(v.y());
|
||||
|
|
|
|||
|
|
@ -1779,6 +1779,7 @@ void Scene_polyhedron_selection_item::common_constructor()
|
|||
d->are_temp_buffers_filled = false;
|
||||
d->poly = NULL;
|
||||
d->ready_to_move = false;
|
||||
do_process = true;
|
||||
setProperty("no_picking", true);
|
||||
|
||||
setPointContainer(3,
|
||||
|
|
|
|||
|
|
@ -879,8 +879,13 @@ protected:
|
|||
if(gen_event->type() == QEvent::Wheel)
|
||||
{
|
||||
QWheelEvent *event = static_cast<QWheelEvent*>(gen_event);
|
||||
int steps = event->delta() / 120;
|
||||
expand_or_reduce(steps);
|
||||
int steps = event->angleDelta().y()/120;
|
||||
if(do_process)
|
||||
{
|
||||
expand_or_reduce(steps);
|
||||
do_process = false;
|
||||
QTimer::singleShot(0,this, [this](){do_process = true;});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -997,6 +1002,7 @@ protected:
|
|||
Scene_facegraph_item_k_ring_selection k_ring_selector;
|
||||
// action state
|
||||
bool is_insert;
|
||||
bool do_process;
|
||||
|
||||
public:
|
||||
// selection
|
||||
|
|
|
|||
|
|
@ -621,11 +621,23 @@ void Viewer::keyPressEvent(QKeyEvent* e)
|
|||
}
|
||||
else if(e->key() == Qt::Key_M) {
|
||||
d->macro_mode = ! d->macro_mode;
|
||||
|
||||
if(d->macro_mode) {
|
||||
switch(camera()->type()){
|
||||
case CGAL::qglviewer::Camera::PERSPECTIVE:
|
||||
if(d->macro_mode) {
|
||||
camera()->setZNearCoefficient(0.0005f);
|
||||
} else {
|
||||
camera()->setZNearCoefficient(0.005f);
|
||||
} else {
|
||||
camera()->setZNearCoefficient(0.005f);
|
||||
}
|
||||
break;
|
||||
case CGAL::qglviewer::Camera::ORTHOGRAPHIC:
|
||||
if(d->macro_mode) {
|
||||
camera()->setOrthoZNear(-0.5f);
|
||||
} else {
|
||||
camera()->setOrthoZNear(0.0f);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->displayMessage(tr("Macro mode: %1").
|
||||
arg(d->macro_mode ? tr("on") : tr("off")));
|
||||
|
|
@ -1351,19 +1363,39 @@ QOpenGLShaderProgram* Viewer::getShaderProgram(int name) const
|
|||
|
||||
void Viewer::wheelEvent(QWheelEvent* e)
|
||||
{
|
||||
if(e->modifiers().testFlag(Qt::ShiftModifier))
|
||||
if(e->modifiers().testFlag(Qt::ShiftModifier))
|
||||
{
|
||||
double delta = e->delta();
|
||||
if(delta>0)
|
||||
{
|
||||
double delta = e->delta();
|
||||
if(delta>0)
|
||||
{
|
||||
camera()->setZNearCoefficient(camera()->zNearCoefficient() * 1.01);
|
||||
}
|
||||
else
|
||||
camera()->setZNearCoefficient(camera()->zNearCoefficient() / 1.01);
|
||||
update();
|
||||
switch(camera()->type())
|
||||
{
|
||||
case CGAL::qglviewer::Camera::ORTHOGRAPHIC:
|
||||
camera()->setOrthoZNear(camera()->orthoZNear() + 0.01);
|
||||
break;
|
||||
case CGAL::qglviewer::Camera::PERSPECTIVE:
|
||||
camera()->setZNearCoefficient(camera()->zNearCoefficient() * 1.01);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
CGAL::QGLViewer::wheelEvent(e);
|
||||
switch(camera()->type())
|
||||
{
|
||||
case CGAL::qglviewer::Camera::ORTHOGRAPHIC:
|
||||
camera()->setOrthoZNear(camera()->orthoZNear() - 0.01);
|
||||
break;
|
||||
case CGAL::qglviewer::Camera::PERSPECTIVE:
|
||||
camera()->setZNearCoefficient(camera()->zNearCoefficient() / 1.01);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
update();
|
||||
}
|
||||
else
|
||||
CGAL::QGLViewer::wheelEvent(e);
|
||||
}
|
||||
|
||||
bool Viewer::testDisplayId(double x, double y, double z)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,657 @@
|
|||
// Copyright (c) 2019 Geometry Factory
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0+
|
||||
//
|
||||
// Author(s) : Maxime Gimeno
|
||||
|
||||
#ifndef CGAL_IO_READ_3MF_H
|
||||
#define CGAL_IO_READ_3MF_H
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <CGAL/IO/Color.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
#include <Model/COM/NMR_DLLInterfaces.h>
|
||||
namespace CGAL{
|
||||
|
||||
namespace transform_nmr_internal{
|
||||
NMR::MODELTRANSFORM initMatrix()
|
||||
{
|
||||
NMR::MODELTRANSFORM mMatrix;
|
||||
int i, j;
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
mMatrix.m_fFields[j][i] = (i == j) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return mMatrix;
|
||||
}
|
||||
}//end transform_nmr_internal
|
||||
|
||||
template<typename PointRange,
|
||||
typename PolygonRange,
|
||||
typename ColorRange>
|
||||
bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject,
|
||||
const NMR::MODELTRANSFORM& transform,
|
||||
PointRange& points,
|
||||
PolygonRange& triangles,
|
||||
ColorRange& colors,
|
||||
std::string& name) {
|
||||
typedef typename PointRange::value_type Point_3;
|
||||
typedef typename PolygonRange::value_type Polygon;
|
||||
typedef typename Kernel_traits<Point_3>::Kernel Kernel;
|
||||
HRESULT hResult;
|
||||
DWORD nNeededChars;
|
||||
std::vector<char> pBuffer;
|
||||
|
||||
// Retrieve Mesh Name Length
|
||||
hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars);
|
||||
if (hResult != LIB3MF_OK)
|
||||
{
|
||||
std::cerr<<"Error during name extraction.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve Mesh Name
|
||||
if (nNeededChars > 0) {
|
||||
pBuffer.resize(nNeededChars + 1);
|
||||
hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, &pBuffer[0], nNeededChars + 1, NULL);
|
||||
pBuffer[nNeededChars] = 0;
|
||||
std::string temp(&pBuffer[0]);
|
||||
if(temp.find("_cgal_pc") != std::string::npos
|
||||
|| temp.find("_cgal_pl")!= std::string::npos) //ignore point clouds and polylines
|
||||
{
|
||||
return false;
|
||||
}
|
||||
name = std::string(&pBuffer[0]);
|
||||
}
|
||||
else
|
||||
name = std::string("Unknown Mesh");
|
||||
|
||||
typename Kernel::Aff_transformation_3 t(
|
||||
transform.m_fFields[0][0], transform.m_fFields[0][1], transform.m_fFields[0][2], transform.m_fFields[0][3],
|
||||
transform.m_fFields[1][0], transform.m_fFields[1][1], transform.m_fFields[1][2], transform.m_fFields[1][3],
|
||||
transform.m_fFields[2][0], transform.m_fFields[2][1], transform.m_fFields[2][2], transform.m_fFields[2][3]
|
||||
);
|
||||
|
||||
NMR::PLib3MFPropertyHandler * pPropertyHandler;
|
||||
hResult = NMR::lib3mf_meshobject_createpropertyhandler(pMeshObject, &pPropertyHandler);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
std::cerr << "could not create property handler: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(pMeshObject);
|
||||
return false;
|
||||
}
|
||||
|
||||
for(DWORD vid = 0; vid < points.size(); ++vid)
|
||||
{
|
||||
NMR::MODELMESHVERTEX pVertex;
|
||||
NMR::lib3mf_meshobject_getvertex(pMeshObject, vid, &pVertex);
|
||||
Point_3 p(pVertex.m_fPosition[0],
|
||||
pVertex.m_fPosition[1],
|
||||
pVertex.m_fPosition[2]);
|
||||
points[vid] = t.transform(p);
|
||||
}
|
||||
for(DWORD pid = 0; pid < triangles.size(); ++pid)
|
||||
{
|
||||
NMR::MODELMESHTRIANGLE pTriangle;
|
||||
NMR::lib3mf_meshobject_gettriangle(pMeshObject, pid, &pTriangle);
|
||||
Polygon triangle(3);
|
||||
for(DWORD i = 0; i< 3; ++i)
|
||||
triangle[i] = pTriangle.m_nIndices[i];
|
||||
triangles[pid] = triangle;
|
||||
NMR::MODELMESH_TRIANGLECOLOR_SRGB pColor;
|
||||
NMR::lib3mf_propertyhandler_getcolor(pPropertyHandler, pid, &pColor);
|
||||
NMR::MODELMESHCOLOR_SRGB mColor = pColor.m_Colors[0];
|
||||
colors[pid]=CGAL::Color(mColor.m_Red, mColor.m_Green,
|
||||
mColor.m_Blue, mColor.m_Alpha);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename PointRange,
|
||||
typename PolygonRange,
|
||||
typename ColorRange>
|
||||
bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject,
|
||||
const NMR::MODELTRANSFORM& ,
|
||||
PointRange& points,
|
||||
PolygonRange&,
|
||||
ColorRange& colors,
|
||||
std::string& name) {
|
||||
typedef typename PointRange::value_type Point_3;
|
||||
|
||||
HRESULT hResult;
|
||||
DWORD nNeededChars;
|
||||
std::vector<char> pBuffer;
|
||||
// Retrieve Mesh Name Length
|
||||
hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars);
|
||||
if (hResult != LIB3MF_OK)
|
||||
{
|
||||
points.resize(0);
|
||||
std::cerr<<"Error during name extraction.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve Mesh Name
|
||||
if (nNeededChars > 0) {
|
||||
pBuffer.resize(nNeededChars + 1);
|
||||
hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, &pBuffer[0], nNeededChars + 1, NULL);
|
||||
pBuffer[nNeededChars] = 0;
|
||||
std::string temp(&pBuffer[0]);
|
||||
if(temp.find("_cgal_pl")== std::string::npos) //ignore not polylines
|
||||
{
|
||||
points.resize(0);
|
||||
return false;
|
||||
}
|
||||
name = std::string(&pBuffer[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
points.resize(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
NMR::PLib3MFPropertyHandler * pPropertyHandler;
|
||||
hResult = NMR::lib3mf_meshobject_createpropertyhandler(pMeshObject, &pPropertyHandler);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
std::cerr << "could not create property handler: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(pMeshObject);
|
||||
return false;
|
||||
}
|
||||
|
||||
points.resize(points.size()-3);//ignore dummy_vertices
|
||||
for(DWORD vid = 0; vid < points.size(); ++vid)
|
||||
{
|
||||
NMR::MODELMESHVERTEX pVertex;
|
||||
NMR::lib3mf_meshobject_getvertex(pMeshObject, vid+3, &pVertex);
|
||||
points[vid] =
|
||||
Point_3(pVertex.m_fPosition[0],
|
||||
pVertex.m_fPosition[1],
|
||||
pVertex.m_fPosition[2]);
|
||||
}
|
||||
|
||||
NMR::MODELMESH_TRIANGLECOLOR_SRGB pColor;
|
||||
NMR::lib3mf_propertyhandler_getcolor(pPropertyHandler, 0, &pColor);//get color of the dummy triangle
|
||||
NMR::MODELMESHCOLOR_SRGB mColor = pColor.m_Colors[0];
|
||||
colors[0]=CGAL::Color(mColor.m_Red, mColor.m_Green,
|
||||
mColor.m_Blue, mColor.m_Alpha);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename PointRange,
|
||||
typename PolygonRange,
|
||||
typename ColorRange>
|
||||
bool extract_point_clouds (NMR::PLib3MFModelMeshObject *pMeshObject,
|
||||
const NMR::MODELTRANSFORM&,
|
||||
PointRange& points,
|
||||
PolygonRange&,
|
||||
ColorRange& colors,
|
||||
std::string& name) {
|
||||
typedef typename PointRange::value_type Point_3;
|
||||
|
||||
HRESULT hResult;
|
||||
DWORD nNeededChars;
|
||||
std::vector<char> pBuffer;
|
||||
// Retrieve Mesh Name Length
|
||||
hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars);
|
||||
if (hResult != LIB3MF_OK)
|
||||
{
|
||||
std::cerr<<"Error during name extraction.";
|
||||
points.resize(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve Mesh Name
|
||||
if (nNeededChars > 0) {
|
||||
pBuffer.resize(nNeededChars + 1);
|
||||
hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, &pBuffer[0], nNeededChars + 1, NULL);
|
||||
pBuffer[nNeededChars] = 0;
|
||||
std::string temp(&pBuffer[0]);
|
||||
if(temp.find("_cgal_pc")== std::string::npos) //ignore not point_cloud
|
||||
{
|
||||
points.resize(0);
|
||||
return false;
|
||||
}
|
||||
name = std::string(&pBuffer[0]);
|
||||
}
|
||||
else{
|
||||
points.resize(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
NMR::PLib3MFPropertyHandler * pPropertyHandler;
|
||||
hResult = NMR::lib3mf_meshobject_createpropertyhandler(pMeshObject, &pPropertyHandler);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
std::cerr << "could not create property handler: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(pMeshObject);
|
||||
return -1;
|
||||
}
|
||||
|
||||
points.resize(points.size()-3);//ignore dummy_vertices
|
||||
for(DWORD vid = 0; vid < points.size(); ++vid)
|
||||
{
|
||||
NMR::MODELMESHVERTEX pVertex;
|
||||
NMR::lib3mf_meshobject_getvertex(pMeshObject, vid+3, &pVertex);
|
||||
points[vid] =
|
||||
Point_3(pVertex.m_fPosition[0],
|
||||
pVertex.m_fPosition[1],
|
||||
pVertex.m_fPosition[2]);
|
||||
}
|
||||
|
||||
NMR::MODELMESH_TRIANGLECOLOR_SRGB pColor;
|
||||
NMR::lib3mf_propertyhandler_getcolor(pPropertyHandler, 0, &pColor);//get color of the dummy triangle
|
||||
NMR::MODELMESHCOLOR_SRGB mColor = pColor.m_Colors[0];
|
||||
colors[0]=CGAL::Color(mColor.m_Red, mColor.m_Green,
|
||||
mColor.m_Blue, mColor.m_Alpha);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename PointRanges, typename PolygonRanges, typename ColorRanges,
|
||||
typename PointRange, typename PolygonRange, typename ColorRange>
|
||||
int read_from_3mf(const std::string& file_name, PointRanges& all_points,
|
||||
PolygonRanges& all_polygons, ColorRanges& all_colors,
|
||||
std::vector<std::string>& names,
|
||||
std::function<bool(NMR::PLib3MFModelMeshObject*,
|
||||
const NMR::MODELTRANSFORM&,
|
||||
PointRange&,
|
||||
PolygonRange&,
|
||||
ColorRange&,
|
||||
std::string&)> func
|
||||
)
|
||||
{
|
||||
DWORD nInterfaceVersionMajor, nInterfaceVersionMinor, nInterfaceVersionMicro, nbVertices, nbPolygons;
|
||||
HRESULT hResult;
|
||||
NMR::PLib3MFModel * pModel;
|
||||
NMR::PLib3MFModelReader * pReader;
|
||||
// Extract Extension of filename
|
||||
std::string sReaderName("3mf");
|
||||
|
||||
hResult = NMR::lib3mf_getinterfaceversion(&nInterfaceVersionMajor, &nInterfaceVersionMinor, &nInterfaceVersionMicro);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not get 3MF Library version: " << std::hex << hResult << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create Model Instance
|
||||
hResult = NMR::lib3mf_createmodel(&pModel);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not create model: " << std::hex << hResult << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create Model Reader
|
||||
hResult = NMR::lib3mf_model_queryreader(pModel, sReaderName.c_str(), &pReader);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not create model reader: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Import Model from File
|
||||
hResult = NMR::lib3mf_reader_readfromfileutf8(pReader, file_name.c_str());
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not parse file: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pReader);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Release Model Reader
|
||||
NMR::lib3mf_release(pReader);
|
||||
|
||||
//Iterate Model
|
||||
|
||||
BOOL pbHasNext;
|
||||
NMR::PLib3MFModelResourceIterator * pResourceIterator;
|
||||
|
||||
hResult = NMR::lib3mf_model_getobjects(pModel, &pResourceIterator);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not get object: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
hResult = NMR::lib3mf_resourceiterator_movenext(pResourceIterator, &pbHasNext);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not get next object: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pResourceIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
**** Iterate Resources To Find Meshes ************
|
||||
**************************************************/
|
||||
|
||||
while (pbHasNext) {
|
||||
NMR::PLib3MFModelResource * pResource;
|
||||
NMR::PLib3MFModelMeshObject * pMeshObject;
|
||||
NMR::PLib3MFModelComponentsObject * pComponentsObject;
|
||||
NMR::ModelResourceID ResourceID;
|
||||
|
||||
// get current resource
|
||||
hResult = NMR::lib3mf_resourceiterator_getcurrent(pResourceIterator, &pResource);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not get resource: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pResourceIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get resource ID
|
||||
hResult = NMR::lib3mf_resource_getresourceid(pResource, &ResourceID);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not get resource id: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pResource);
|
||||
NMR::lib3mf_release(pResourceIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
// Query mesh interface
|
||||
BOOL bIsMeshObject;
|
||||
hResult = NMR::lib3mf_object_ismeshobject(pResource, &bIsMeshObject);
|
||||
if (hResult == LIB3MF_OK)
|
||||
{
|
||||
if(bIsMeshObject) {
|
||||
//skip it. Only get it through the components and buildItems.
|
||||
}
|
||||
else {
|
||||
BOOL bIsComponentsObject;
|
||||
hResult = NMR::lib3mf_object_iscomponentsobject(pResource, &bIsComponentsObject);
|
||||
if ((hResult == LIB3MF_OK) && (bIsComponentsObject)) {
|
||||
pComponentsObject = (NMR::PLib3MFModelComponentsObject*)pResource;
|
||||
DWORD nComponentCount;
|
||||
hResult = NMR::lib3mf_componentsobject_getcomponentcount(pComponentsObject, &nComponentCount);
|
||||
if (hResult != LIB3MF_OK)
|
||||
return -1;
|
||||
//for each component
|
||||
DWORD nIndex;
|
||||
for (nIndex = 0; nIndex < nComponentCount; ++nIndex) {
|
||||
NMR::PLib3MFModelResource * compResource;
|
||||
NMR::PLib3MFModelComponent * pComponent;
|
||||
hResult = NMR::lib3mf_componentsobject_getcomponent(pComponentsObject, nIndex, &pComponent);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
hResult = NMR::lib3mf_component_getobjectresource(pComponent, &compResource);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
NMR::lib3mf_release(pComponent);
|
||||
return -1;
|
||||
}
|
||||
hResult = NMR::lib3mf_object_ismeshobject(compResource, &bIsMeshObject);
|
||||
if (hResult == LIB3MF_OK)
|
||||
{
|
||||
if(bIsMeshObject) {
|
||||
BOOL bHasTransform;
|
||||
NMR::MODELTRANSFORM Transform;
|
||||
hResult = NMR::lib3mf_component_hastransform(pComponent, &bHasTransform);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
NMR::lib3mf_release(pComponent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bHasTransform) {
|
||||
// Retrieve Transform
|
||||
hResult = NMR::lib3mf_component_gettransform(pComponent, &Transform);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
NMR::lib3mf_release(pComponent);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Transform = transform_nmr_internal::initMatrix();
|
||||
}
|
||||
pMeshObject = compResource;
|
||||
NMR::lib3mf_meshobject_getvertexcount(pMeshObject, &nbVertices);
|
||||
NMR::lib3mf_meshobject_gettrianglecount(pMeshObject, &nbPolygons);
|
||||
PointRange points (nbVertices);
|
||||
PolygonRange triangles(nbPolygons);
|
||||
ColorRange colors(nbPolygons);
|
||||
std::string name;
|
||||
|
||||
if(func(pMeshObject, Transform, points, triangles, colors, name)){
|
||||
all_points.push_back(points);
|
||||
all_polygons.push_back(triangles);
|
||||
all_colors.push_back(colors);
|
||||
names.push_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//end component
|
||||
}
|
||||
}
|
||||
}
|
||||
// free instances
|
||||
NMR::lib3mf_release(pResource);
|
||||
hResult = NMR::lib3mf_resourceiterator_movenext(pResourceIterator, &pbHasNext);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not get next object: " << std::hex << hResult << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
**** Iterate Build items To Find Transformed Meshes ****
|
||||
********************************************************/
|
||||
|
||||
// Iterate through all the Build items
|
||||
NMR::PLib3MFModelBuildItemIterator * pBuildItemIterator;
|
||||
hResult = NMR::lib3mf_model_getbuilditems(pModel, &pBuildItemIterator);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cout << "could not get build items: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pBuildItemIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hResult = NMR::lib3mf_builditemiterator_movenext(pBuildItemIterator, &pbHasNext);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cout << "could not get next build item: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pBuildItemIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (pbHasNext) {
|
||||
NMR::PLib3MFModelMeshObject * pMeshObject;
|
||||
NMR::MODELTRANSFORM Transform;
|
||||
NMR::PLib3MFModelBuildItem * pBuildItem;
|
||||
// Retrieve Build Item
|
||||
hResult = NMR::lib3mf_builditemiterator_getcurrent(pBuildItemIterator, &pBuildItem);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cout << "could not get build item: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pBuildItemIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Retrieve Resource
|
||||
NMR::PLib3MFModelObjectResource * pObjectResource;
|
||||
hResult = NMR::lib3mf_builditem_getobjectresource(pBuildItem, &pObjectResource);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cout << "could not get build item resource: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_release(pBuildItem);
|
||||
NMR::lib3mf_release(pBuildItemIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL bIsMeshObject;
|
||||
hResult = NMR::lib3mf_object_ismeshobject(pObjectResource, &bIsMeshObject);
|
||||
if (hResult == LIB3MF_OK)
|
||||
{
|
||||
if(bIsMeshObject) {
|
||||
pMeshObject = pObjectResource;
|
||||
NMR::lib3mf_meshobject_getvertexcount(pMeshObject, &nbVertices);
|
||||
NMR::lib3mf_meshobject_gettrianglecount(pMeshObject, &nbPolygons);
|
||||
PointRange points (nbVertices);
|
||||
PolygonRange triangles(nbPolygons);
|
||||
ColorRange colors(nbPolygons);
|
||||
std::string name;
|
||||
|
||||
|
||||
// Check Object Transform
|
||||
BOOL bHasTransform;
|
||||
hResult = NMR::lib3mf_builditem_hasobjecttransform(pBuildItem, &bHasTransform);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
NMR::lib3mf_release(pBuildItem);
|
||||
NMR::lib3mf_release(pBuildItemIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
std::cerr << "could not check object transform: " << std::hex << hResult << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bHasTransform) {
|
||||
// Retrieve Transform
|
||||
hResult = NMR::lib3mf_builditem_getobjecttransform(pBuildItem, &Transform);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
NMR::lib3mf_release(pBuildItem);
|
||||
NMR::lib3mf_release(pBuildItemIterator);
|
||||
NMR::lib3mf_release(pModel);
|
||||
std::cerr << "could not get object transform: " << std::hex << hResult << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Transform = transform_nmr_internal::initMatrix();
|
||||
}
|
||||
|
||||
if(func(pMeshObject, Transform, points, triangles, colors, name)){
|
||||
all_points.push_back(points);
|
||||
all_polygons.push_back(triangles);
|
||||
all_colors.push_back(colors);
|
||||
names.push_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Release Object Resource ID
|
||||
NMR::lib3mf_release(pObjectResource);
|
||||
// Release Build Item
|
||||
NMR::lib3mf_release(pBuildItem);
|
||||
|
||||
// Move to next Item
|
||||
hResult = NMR::lib3mf_builditemiterator_movenext(pBuildItemIterator, &pbHasNext);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not get next build item: " << std::hex << hResult << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Release Build Item Iterator
|
||||
NMR::lib3mf_release(pBuildItemIterator);
|
||||
return all_points.size();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief extracts ranges of points and triangles from a 3mf file.
|
||||
* \tparam PointRanges a model of the concepts `RandomAccessContainer` and
|
||||
* `BackInsertionSequence` whose `value type` is
|
||||
* a model of the concepts `RandomAccessContainer` and `BackInsertionSequence`
|
||||
* whose `value type` is the point type.
|
||||
* \tparam PolygonRanges a model of the concept `RandomAccessContainer` whose
|
||||
* `value_type` is a model of the concept `RandomAccessContainer`
|
||||
* whose `value_type` is a model of the concept `RandomAccessContainer` whose
|
||||
* `value_type` is std::size_t.
|
||||
* \tparam ColorRanges a model of the concepts `RandomAccessContainer` and
|
||||
* `BackInsertionSequence` whose `value type` is
|
||||
* a model of the concepts `RandomAccessContainer` and `BackInsertionSequence`
|
||||
* whose `value type` is `CGAL::Color`.
|
||||
* \param file_name the name of the 3mf file to read.
|
||||
* \param all_points a `PointRanges` that will contain the points of the meshes
|
||||
* in `file_name`.
|
||||
* Each of these meshes will add a range of its points.
|
||||
* \param all_polygons a `PolygonRanges` that will contain the triangles of the
|
||||
* meshes in `file_name`.
|
||||
* Each of these meshes will add a range of its triangles. A `triangle` of
|
||||
* `all_polygons[i]` contains the indices of its points in `all_points[i]`.
|
||||
* \param all_colors will contain the color of each triangle for each soup.
|
||||
* \param names will contain the name of each mesh in `file_name` if any.
|
||||
* If the i'th mesh has no name, it will be called "Unknown Mesh" in names.
|
||||
* \return the number of soups read.
|
||||
*/
|
||||
template<typename PointRanges, typename PolygonRanges, typename ColorRanges>
|
||||
int read_triangle_soups_from_3mf(const std::string& file_name, PointRanges& all_points,
|
||||
PolygonRanges& all_polygons, ColorRanges& all_colors,
|
||||
std::vector<std::string>& names
|
||||
)
|
||||
{
|
||||
typedef typename PointRanges::value_type PointRange;
|
||||
typedef typename PolygonRanges::value_type PolygonRange;
|
||||
typedef typename ColorRanges::value_type ColorRange;
|
||||
return read_from_3mf<PointRanges,PolygonRanges,ColorRanges,
|
||||
PointRange, PolygonRange, ColorRange>
|
||||
(file_name, all_points, all_polygons,
|
||||
all_colors, names, extract_soups<PointRange, PolygonRange, ColorRange>);
|
||||
}
|
||||
|
||||
|
||||
template<typename PointRanges, typename ColorRanges>
|
||||
int read_polylines_from_3mf(const std::string& file_name,
|
||||
PointRanges& all_points,
|
||||
ColorRanges& all_colors,
|
||||
std::vector<std::string>& names
|
||||
)
|
||||
{
|
||||
typedef typename PointRanges::value_type PointRange;
|
||||
typedef std::vector<std::size_t> Polygon;
|
||||
typedef std::vector<Polygon> PolygonRange;
|
||||
typedef std::vector<CGAL::Color> ColorRange;
|
||||
std::vector<PolygonRange> all_polygons;
|
||||
return read_from_3mf<PointRanges,std::vector<PolygonRange>,
|
||||
std::vector<ColorRange>, PointRange, PolygonRange, ColorRange>
|
||||
(file_name, all_points, all_polygons, all_colors, names,
|
||||
extract_polylines<PointRange, PolygonRange, ColorRange>);
|
||||
}
|
||||
|
||||
|
||||
template<typename PointRanges, typename ColorRanges>
|
||||
int read_point_clouds_from_3mf(const std::string& file_name,
|
||||
PointRanges& all_points,
|
||||
ColorRanges& all_colors,
|
||||
std::vector<std::string>& names
|
||||
)
|
||||
{
|
||||
typedef typename PointRanges::value_type PointRange;
|
||||
typedef std::vector<std::size_t> Polygon;
|
||||
typedef std::vector<Polygon> PolygonRange;
|
||||
typedef std::vector<CGAL::Color> ColorRange;
|
||||
std::vector<PolygonRange> all_polygons;
|
||||
return read_from_3mf<PointRanges,std::vector<PolygonRange>,
|
||||
std::vector<ColorRange>, PointRange, PolygonRange, ColorRange>
|
||||
(file_name, all_points, all_polygons, all_colors, names,
|
||||
extract_point_clouds<PointRange, PolygonRange, ColorRange>);
|
||||
}
|
||||
}//end CGAL
|
||||
|
||||
#endif // CGAL_IO_READ_3MF_H
|
||||
|
||||
|
|
@ -0,0 +1,468 @@
|
|||
// Copyright (c) 2019 Geometry Factory
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0+
|
||||
//
|
||||
// Author(s) : Maxime Gimeno
|
||||
|
||||
#ifndef CGAL_IO_WRITE_3MF_H
|
||||
#define CGAL_IO_WRITE_3MF_H
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <CGAL/IO/Color.h>
|
||||
|
||||
#include <Model/COM/NMR_DLLInterfaces.h>
|
||||
|
||||
namespace CGAL{
|
||||
namespace tmf_internal{
|
||||
// Utility functions to create vertices and triangles
|
||||
NMR::MODELMESHVERTEX fnCreateVertex(float x, float y, float z)
|
||||
{
|
||||
NMR::MODELMESHVERTEX result;
|
||||
result.m_fPosition[0] = x;
|
||||
result.m_fPosition[1] = y;
|
||||
result.m_fPosition[2] = z;
|
||||
return result;
|
||||
}
|
||||
NMR::MODELMESHTRIANGLE fnCreateTriangle(int v0, int v1, int v2)
|
||||
{
|
||||
NMR::MODELMESHTRIANGLE result;
|
||||
result.m_nIndices[0] = v0;
|
||||
result.m_nIndices[1] = v1;
|
||||
result.m_nIndices[2] = v2;
|
||||
return result;
|
||||
}
|
||||
NMR::MODELMESHCOLOR_SRGB fnCreateColor(unsigned char red, unsigned char green,
|
||||
unsigned char blue, unsigned char alpha=255)
|
||||
{
|
||||
NMR::MODELMESHCOLOR_SRGB result;
|
||||
result.m_Red = red;
|
||||
result.m_Green = green;
|
||||
result.m_Blue = blue;
|
||||
result.m_Alpha = alpha;
|
||||
return result;
|
||||
|
||||
|
||||
}
|
||||
} //end internal
|
||||
|
||||
bool add_build_item(NMR::PLib3MFModel * pModel,
|
||||
NMR::PLib3MFModelMeshObject* pMeshObject)
|
||||
{
|
||||
HRESULT hResult;
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
// Add Build Item for Mesh
|
||||
NMR::PLib3MFModelBuildItem * pBuildItem;
|
||||
hResult = NMR::lib3mf_model_addbuilditem(pModel, pMeshObject, NULL, &pBuildItem);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not create build item: "
|
||||
<< std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage
|
||||
<< ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
// Release BuildItem and Mesh
|
||||
NMR::lib3mf_release(pMeshObject);
|
||||
NMR::lib3mf_release(pBuildItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool export_model_to_file(const std::string& file_name,
|
||||
NMR::PLib3MFModel * pModel)
|
||||
{
|
||||
HRESULT hResult;
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
// Output mesh as 3MF
|
||||
// Create Model Writer for 3MF
|
||||
NMR::PLib3MFModelWriter * p3MFWriter;
|
||||
hResult = NMR::lib3mf_model_querywriter(pModel, "3mf", &p3MFWriter);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not create model reader: "
|
||||
<< std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage
|
||||
<< ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
// Export Model into File
|
||||
hResult = NMR::lib3mf_writer_writetofileutf8(p3MFWriter, file_name.c_str());
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not write file: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(p3MFWriter, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": "
|
||||
<< pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(pModel);
|
||||
NMR::lib3mf_release(p3MFWriter);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Release Model Writer
|
||||
NMR::lib3mf_release(p3MFWriter);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename PointRange, typename PolygonRange, typename ColorRange>
|
||||
bool write_mesh_to_model( const PointRange& points,
|
||||
const PolygonRange& polygons,
|
||||
const ColorRange& colors,
|
||||
const std::string& name,
|
||||
NMR::PLib3MFModelMeshObject** pMeshObject,
|
||||
NMR::PLib3MFModel * pModel
|
||||
)
|
||||
{
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
HRESULT hResult;
|
||||
// Create mesh structure
|
||||
std::vector<NMR::MODELMESHVERTEX> pVertices;
|
||||
std::vector<NMR::MODELMESHTRIANGLE> pTriangles;
|
||||
// Create Mesh Object
|
||||
hResult = NMR::lib3mf_model_addmeshobject(pModel, pMeshObject);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not add mesh object: " << std::hex
|
||||
<< hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": "
|
||||
<< pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
for( auto point : points)
|
||||
{
|
||||
pVertices.push_back(tmf_internal::fnCreateVertex(point.x(), point.y(), point.z()));
|
||||
}
|
||||
|
||||
for( auto triangle : polygons)
|
||||
{
|
||||
pTriangles.push_back(tmf_internal::fnCreateTriangle(triangle[0], triangle[1], triangle[2]));
|
||||
}
|
||||
|
||||
hResult = NMR::lib3mf_meshobject_setgeometry(*pMeshObject, pVertices.data(),
|
||||
pVertices.size(), pTriangles.data(),
|
||||
pTriangles.size());
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not set mesh geometry: "
|
||||
<< std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage
|
||||
<< ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(*pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
// Create color entries
|
||||
NMR::PLib3MFPropertyHandler * pPropertyHandler;
|
||||
hResult = NMR::lib3mf_meshobject_createpropertyhandler(*pMeshObject, &pPropertyHandler);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not create property handler: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(*pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
|
||||
// define colors
|
||||
for(std::size_t pid = 0; pid<colors.size(); ++pid)
|
||||
{
|
||||
NMR::MODELMESHCOLOR_SRGB sColor = tmf_internal::fnCreateColor (colors[pid].red(),
|
||||
colors[pid].green(),
|
||||
colors[pid].blue(),
|
||||
colors[pid].alpha());
|
||||
// One-colored Triangles
|
||||
NMR::lib3mf_propertyhandler_setsinglecolor(pPropertyHandler, pid, &sColor);
|
||||
}
|
||||
|
||||
// make sure to define a default property
|
||||
NMR::PLib3MFDefaultPropertyHandler * pDefaultPropertyHandler;
|
||||
hResult = NMR::lib3mf_object_createdefaultpropertyhandler(*pMeshObject, &pDefaultPropertyHandler);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr<< "could not create default property handler: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr<< "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(*pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
NMR::MODELMESHCOLOR_SRGB default_color = tmf_internal::fnCreateColor(0,0,0,0);
|
||||
NMR::lib3mf_defaultpropertyhandler_setcolor(pDefaultPropertyHandler,
|
||||
&default_color);
|
||||
|
||||
// release default property handler
|
||||
NMR::lib3mf_release(pDefaultPropertyHandler);
|
||||
|
||||
// Set name
|
||||
hResult = NMR::lib3mf_object_setnameutf8(*pMeshObject, name.c_str());
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not set object name: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(*pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
|
||||
//add a builditem to finish
|
||||
return add_build_item(pModel, *pMeshObject);
|
||||
}
|
||||
|
||||
//remember that it adds 3 demmy vertices in the beginning, and a dummy triangle to be ignored.
|
||||
template<typename PointRange, typename Color>
|
||||
bool write_points(const PointRange& points,
|
||||
const Color& color,
|
||||
const std::string& name,
|
||||
NMR::PLib3MFModelMeshObject** pMeshObject,
|
||||
NMR::PLib3MFModel * pModel
|
||||
)
|
||||
{
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
HRESULT hResult;
|
||||
// Create mesh structure
|
||||
std::vector<NMR::MODELMESHVERTEX> pVertices;
|
||||
// Create Mesh Object
|
||||
hResult = NMR::lib3mf_model_addmeshobject(pModel, pMeshObject);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not add mesh object: " << std::hex
|
||||
<< hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": "
|
||||
<< pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
//add 3 demmy vertices to be sure to have a valid triangle and accept point sets with less than 3 vertices.
|
||||
for(int i = 0; i< 3; ++i)
|
||||
pVertices.push_back(tmf_internal::fnCreateVertex(0,0,0));
|
||||
for( auto point : points)
|
||||
{
|
||||
pVertices.push_back(tmf_internal::fnCreateVertex(point.x(), point.y(), point.z()));
|
||||
}
|
||||
NMR::MODELMESHTRIANGLE dummy_triangle = tmf_internal::fnCreateTriangle(0,1,2); //add a triangle to avoid lib error.
|
||||
hResult = NMR::lib3mf_meshobject_setgeometry(*pMeshObject, pVertices.data(),
|
||||
pVertices.size(), &dummy_triangle, 1);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not set mesh geometry: "
|
||||
<< std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage
|
||||
<< ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(*pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create color entries
|
||||
NMR::PLib3MFPropertyHandler * pPropertyHandler;
|
||||
hResult = NMR::lib3mf_meshobject_createpropertyhandler(*pMeshObject, &pPropertyHandler);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not create property handler: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(*pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
|
||||
// define colors
|
||||
NMR::MODELMESHCOLOR_SRGB sColor = tmf_internal::fnCreateColor (color.red(),
|
||||
color.green(),
|
||||
color.blue(),
|
||||
color.alpha());
|
||||
// One-colored Triangles
|
||||
NMR::lib3mf_propertyhandler_setsinglecolor(pPropertyHandler, 0, &sColor);
|
||||
|
||||
// make sure to define a default property
|
||||
NMR::PLib3MFDefaultPropertyHandler * pDefaultPropertyHandler;
|
||||
hResult = NMR::lib3mf_object_createdefaultpropertyhandler(*pMeshObject, &pDefaultPropertyHandler);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr<< "could not create default property handler: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr<< "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(*pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
NMR::MODELMESHCOLOR_SRGB default_color = tmf_internal::fnCreateColor(0,0,0,0);
|
||||
NMR::lib3mf_defaultpropertyhandler_setcolor(pDefaultPropertyHandler,
|
||||
&default_color);
|
||||
|
||||
// release default property handler
|
||||
NMR::lib3mf_release(pDefaultPropertyHandler);
|
||||
|
||||
// Set name
|
||||
hResult = NMR::lib3mf_object_setnameutf8(*pMeshObject, name.c_str());
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not set object name: " << std::hex << hResult << std::endl;
|
||||
NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage);
|
||||
std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl;
|
||||
NMR::lib3mf_release(*pMeshObject);
|
||||
NMR::lib3mf_release(pModel);
|
||||
return false;
|
||||
}
|
||||
return add_build_item(pModel, *pMeshObject);
|
||||
}
|
||||
|
||||
template<typename PointRange, typename Color>
|
||||
bool write_point_cloud_to_model(const PointRange& points,
|
||||
const Color& color,
|
||||
const std::string& name,
|
||||
NMR::PLib3MFModelMeshObject** pMeshObject,
|
||||
NMR::PLib3MFModel * pModel
|
||||
)
|
||||
{
|
||||
std::string pc_name = name;
|
||||
pc_name.append("_cgal_pc");
|
||||
return write_points(points, color, pc_name, pMeshObject, pModel);
|
||||
}
|
||||
|
||||
template<typename PointRange, typename Color>
|
||||
bool write_polyline_to_model(const PointRange& points,
|
||||
const Color& color,
|
||||
const std::string& name,
|
||||
NMR::PLib3MFModelMeshObject** pMeshObject,
|
||||
NMR::PLib3MFModel * pModel
|
||||
)
|
||||
{
|
||||
std::string pc_name = name;
|
||||
pc_name.append("_cgal_pl");
|
||||
return write_points(points, color, pc_name, pMeshObject, pModel);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief writes the triangle soups contained in `all_points` and
|
||||
* `all_polygons` into the 3mf file `file_name`.
|
||||
* \tparam PointRanges a model of the concepts `RandomAccessContainer` and
|
||||
* `BackInsertionSequence` whose `value type` is
|
||||
* a model of the concepts `RandomAccessContainer` and `BackInsertionSequence`
|
||||
* whose `value type` is the point type.
|
||||
* \tparam PolygonRanges a model of the concept `RandomAccessContainer` whose
|
||||
* `value_type` is a model of the concept `RandomAccessContainer`
|
||||
* whose `value_type` is a model of the concept `RandomAccessContainer` whose
|
||||
* `value_type` is std::size_t.
|
||||
* \param file_name the name of the 3mf file to write.
|
||||
* \param all_points a `PointRanges` that contains the points of the soups
|
||||
* to write.
|
||||
* \param all_polygons a `PolygonRanges` that contains the triangles of the
|
||||
* soups in `file_name`.
|
||||
* \param names will contains the name of each mesh in `file_name`.
|
||||
* \return `true` if the writing is successful, `false` otherwise.
|
||||
*/
|
||||
template<typename PointRanges, typename PolygonRanges>
|
||||
bool write_triangle_soups_to_3mf(const std::string& file_name,
|
||||
const PointRanges& all_points,
|
||||
const PolygonRanges& all_polygons,
|
||||
const std::vector<std::string>& names)
|
||||
{
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
HRESULT hResult;
|
||||
|
||||
// Create Model Instance
|
||||
NMR::PLib3MFModel * pModel;
|
||||
hResult = NMR::lib3mf_createmodel(&pModel);
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cerr << "could not create model: " << std::hex << hResult << std::endl;
|
||||
return false;
|
||||
}
|
||||
for(std::size_t id = 0; id < all_points.size(); ++id)
|
||||
{
|
||||
NMR::PLib3MFModelMeshObject* pMeshObject;
|
||||
std::string name;
|
||||
if(names.size() > id
|
||||
&& ! names[id].empty())
|
||||
{
|
||||
name=names[id];
|
||||
}
|
||||
else
|
||||
name = std::string("");
|
||||
std::vector<CGAL::Color> colors(all_polygons[id].size());
|
||||
write_mesh_to_model(all_points[id], all_polygons[id], colors, name, &pMeshObject, pModel);
|
||||
}
|
||||
return export_model_to_file(file_name, pModel);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief writes the triangle meshes contained in `tms`
|
||||
* into the 3mf file `file_name`.
|
||||
* \tparam TriangleMeshRange a model of the concepts `RandomAccessContainer`
|
||||
* and `BackInsertionSequence` whose `value type` is
|
||||
* a model of the concepts `FaceListGraph` and `HalfedgeListGraph`
|
||||
* that has only triangle faces.
|
||||
* \param file_name the name of the 3mf file to write.
|
||||
* \param tms a `TriangleMeshRange` that contains the meshes
|
||||
* to write. An internal property map for `CGAL::vertex_point_t`
|
||||
* must be available for each mesh.
|
||||
* \param names will contains the name of each mesh in `file_name`.
|
||||
* \return `true` if the writing is successful, `false` otherwise.
|
||||
*/
|
||||
template<typename TriangleMeshRange>
|
||||
bool write_triangle_meshes_to_3mf(const std::string& file_name,
|
||||
const TriangleMeshRange& tms,
|
||||
const std::vector<std::string>& names)
|
||||
{
|
||||
typedef typename TriangleMeshRange::value_type Mesh;
|
||||
typedef typename boost::property_map<Mesh, boost::vertex_point_t>::type VPMap;
|
||||
typedef typename boost::property_traits<VPMap>::value_type Point_3;
|
||||
|
||||
typedef std::vector<std::size_t> Polygon;
|
||||
typedef std::vector<Polygon> PolygonRange;
|
||||
|
||||
typedef std::vector<Point_3> PointRange;
|
||||
|
||||
std::vector<PointRange> all_points;
|
||||
std::vector<PolygonRange> all_polygons;
|
||||
|
||||
|
||||
for(auto tm : tms)
|
||||
{
|
||||
PointRange points;
|
||||
PolygonRange triangles;
|
||||
VPMap vpm = get(boost::vertex_point, tm);
|
||||
std::unordered_map<typename boost::graph_traits<Mesh>::vertex_descriptor,
|
||||
std::size_t> vertex_id_map;
|
||||
std::size_t i = 0;
|
||||
for(auto v : vertices(tm))
|
||||
{
|
||||
points.push_back(get(vpm, v));
|
||||
vertex_id_map[v] = i++;
|
||||
}
|
||||
all_points.push_back(points);
|
||||
for(auto f : faces(tm))
|
||||
{
|
||||
Polygon triangle;
|
||||
for(auto vert : CGAL::vertices_around_face(halfedge(f, tm), tm))
|
||||
{
|
||||
triangle.push_back(vertex_id_map[vert]);
|
||||
}
|
||||
triangles.push_back(triangle);
|
||||
}
|
||||
all_polygons.push_back(triangles);
|
||||
}
|
||||
|
||||
return write_triangle_soups_to_3mf(file_name, all_points, all_polygons, names);
|
||||
}
|
||||
}//end CGAL
|
||||
#endif // CGAL_IO_WRITE_3MF_H
|
||||
|
|
@ -7,13 +7,27 @@ project( Stream_support_Tests )
|
|||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
find_package(CGAL QUIET)
|
||||
|
||||
if ( CGAL_FOUND )
|
||||
find_path(3MF_INCLUDE_DIR
|
||||
NAMES Model/COM/NMR_DLLInterfaces.h
|
||||
DOC "Path to lib3MF headers"
|
||||
)
|
||||
find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library")
|
||||
|
||||
# create a target per cppfile
|
||||
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
foreach(cppfile ${cppfiles})
|
||||
create_single_source_cgal_program( "${cppfile}" )
|
||||
if ( "${cppfile}" STREQUAL "test_3mf_to_sm.cpp" )
|
||||
if(3MF_LIBRARIES AND 3MF_INCLUDE_DIR)
|
||||
include_directories(${3MF_INCLUDE_DIR})
|
||||
create_single_source_cgal_program( "${cppfile}" )
|
||||
target_link_libraries(test_3mf_to_sm PRIVATE ${3MF_LIBRARIES})
|
||||
else()
|
||||
message(STATUS "NOTICE : This program requires the lib3MF library, and will not be compiled.")
|
||||
endif()
|
||||
else()
|
||||
create_single_source_cgal_program( "${cppfile}" )
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
else()
|
||||
|
|
@ -22,3 +36,4 @@ else()
|
|||
|
||||
endif()
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,179 @@
|
|||
//needed by functions
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "Model/COM/NMR_DLLInterfaces.h"
|
||||
//needed by example
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <fstream>
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
#include <CGAL/Surface_mesh/IO/3mf.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
|
||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||
#include <unordered_map>
|
||||
#include <CGAL/IO/read_3mf.h>
|
||||
#include <CGAL/IO/write_3mf.h>
|
||||
// Use NMR namespace for the interfaces
|
||||
using namespace NMR;
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
typedef Kernel::Point_3 Point_3;
|
||||
typedef CGAL::Surface_mesh<Point_3> Mesh;
|
||||
typedef std::vector<Point_3> PointRange;
|
||||
typedef std::vector<std::size_t> Polygon;
|
||||
typedef std::vector<Polygon> PolygonRange;
|
||||
typedef std::vector<CGAL::Color> ColorRange;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* file_name=(argc == 2) ? argv[1] : "data/test.3mf";
|
||||
|
||||
std::vector<PointRange> all_points;
|
||||
std::vector<PolygonRange> all_polygons;
|
||||
std::vector<ColorRange> all_colors;
|
||||
std::vector<std::string> names;
|
||||
std::vector<Mesh> meshes;
|
||||
//testing reading functions.
|
||||
int nb_meshes =
|
||||
CGAL::read_3mf(file_name, meshes);
|
||||
if(nb_meshes <0)
|
||||
return 1;
|
||||
for(std::size_t i = 0; i< nb_meshes; ++i)
|
||||
{
|
||||
Mesh mesh = meshes[i];
|
||||
std::cout<<names[i]<<" is valid: "<<mesh.is_valid()<<std::endl;
|
||||
std::string outputName("output");
|
||||
outputName.append(std::to_string(i));
|
||||
outputName.append(".off");
|
||||
std::ofstream ofs(outputName);
|
||||
ofs << mesh;
|
||||
ofs.close();
|
||||
}
|
||||
int nb_polylines =
|
||||
CGAL::read_polylines_from_3mf(file_name, all_points, all_colors, names);
|
||||
|
||||
if(nb_polylines == 0)
|
||||
std::cout<<"No polyline found."<<std::endl;
|
||||
else
|
||||
{
|
||||
std::cout<<nb_polylines<<" polylines found, of ";
|
||||
for(std::size_t i = 0; i< nb_polylines-1; ++i){
|
||||
std::cout<<all_points[i].size()<<", ";
|
||||
}
|
||||
std::cout<<all_points.back().size()<<" points."<<std::endl;
|
||||
}
|
||||
all_points.clear();
|
||||
all_colors.clear();
|
||||
int nb_point_sets =
|
||||
CGAL::read_point_clouds_from_3mf(file_name, all_points, all_colors, names);
|
||||
if(nb_point_sets == 0)
|
||||
std::cout<<"No point cloud found."<<std::endl;
|
||||
else
|
||||
{
|
||||
std::cout<<nb_point_sets<<" point clouds found, of ";
|
||||
for(std::size_t i = 0; i< nb_point_sets-1; ++i){
|
||||
std::cout<<all_points[i].size()<<", ";
|
||||
}
|
||||
std::cout<<all_points.back().size()<<" points."<<std::endl;
|
||||
}
|
||||
|
||||
// testing writing functions
|
||||
Mesh sphere, tube;
|
||||
CGAL::make_icosahedron<Mesh, Point_3>(sphere);
|
||||
CGAL::make_regular_prism(10, tube, Point_3(0,-10,0), 10);
|
||||
all_points.clear();
|
||||
all_polygons.clear();
|
||||
all_colors.clear();
|
||||
names.clear();
|
||||
PointRange points;
|
||||
PolygonRange triangles;
|
||||
ColorRange colors;
|
||||
typedef boost::property_map<Mesh, boost::vertex_point_t>::type VPMap;
|
||||
VPMap vpm = get(boost::vertex_point, sphere);
|
||||
std::unordered_map<boost::graph_traits<Mesh>::vertex_descriptor,
|
||||
std::size_t> vertex_id_map;
|
||||
std::size_t i = 0;
|
||||
for(auto v : sphere.vertices())
|
||||
{
|
||||
points.push_back(get(vpm, v));
|
||||
vertex_id_map[v] = i++;
|
||||
}
|
||||
all_points.push_back(points);
|
||||
for(auto f : sphere.faces())
|
||||
{
|
||||
Polygon triangle;
|
||||
for(auto vert : CGAL::vertices_around_face(halfedge(f, sphere), sphere))
|
||||
{
|
||||
triangle.push_back(vertex_id_map[vert]);
|
||||
}
|
||||
triangles.push_back(triangle);
|
||||
colors.push_back(CGAL::Color(255,0,0,255));
|
||||
}
|
||||
all_polygons.push_back(triangles);
|
||||
all_colors.push_back(colors);
|
||||
points.clear();
|
||||
triangles.clear();
|
||||
colors.clear();
|
||||
vertex_id_map.clear();
|
||||
i = 0;
|
||||
|
||||
vpm = get(boost::vertex_point, tube);
|
||||
for(auto v : tube.vertices())
|
||||
{
|
||||
points.push_back(get(vpm, v));
|
||||
vertex_id_map[v] = i++;
|
||||
}
|
||||
all_points.push_back(points);
|
||||
for(auto f : tube.faces())
|
||||
{
|
||||
Polygon triangle;
|
||||
for(auto vert : CGAL::vertices_around_face(halfedge(f, tube), tube))
|
||||
{
|
||||
triangle.push_back(vertex_id_map[vert]);
|
||||
}
|
||||
triangles.push_back(triangle);
|
||||
colors.push_back(CGAL::Color(0,0,255,255));
|
||||
|
||||
}
|
||||
all_polygons.push_back(triangles);
|
||||
all_colors.push_back(colors);
|
||||
names.push_back(std::string("sphere"));
|
||||
names.push_back(std::string("tube"));
|
||||
|
||||
meshes.resize(2);
|
||||
meshes[0] = sphere;
|
||||
meshes[1] = tube;
|
||||
CGAL::write_triangle_meshes_to_3mf("meshes.3mf", meshes, names);
|
||||
|
||||
|
||||
//testing of point clouds
|
||||
DWORD nErrorMessage;
|
||||
LPCSTR pszErrorMessage;
|
||||
HRESULT hResult;
|
||||
NMR::PLib3MFModel * pModel;
|
||||
hResult = NMR::lib3mf_createmodel(&pModel);
|
||||
NMR::PLib3MFModelMeshObject* pMeshObject;
|
||||
if (hResult != LIB3MF_OK) {
|
||||
std::cout << "could not create model: " << std::hex << hResult << std::endl;
|
||||
return false;
|
||||
}
|
||||
for(int i=0; i< names.size(); ++i)
|
||||
{
|
||||
CGAL::write_mesh_to_model(all_points[i], all_polygons[i],
|
||||
all_colors[i], names[i], &pMeshObject, pModel);
|
||||
}
|
||||
CGAL::Color color(255,0,0);
|
||||
CGAL::write_point_cloud_to_model(all_points.front(),
|
||||
color, names.front(), &pMeshObject, pModel);
|
||||
CGAL::export_model_to_file("micro.3mf", pModel);
|
||||
//testing of polylines
|
||||
CGAL::write_polyline_to_model(all_points.back(),
|
||||
color, names.back(), &pMeshObject, pModel);
|
||||
CGAL::export_model_to_file("micro.3mf", pModel);
|
||||
|
||||
std::cout<<"OK."<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright (c) 2019 Geometry Factory
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0+
|
||||
//
|
||||
// Author(s) : Maxime Gimeno
|
||||
|
||||
|
||||
#ifndef CGAL_SURFACE_MESH_IO_3MF_H
|
||||
#define CGAL_SURFACE_MESH_IO_3MF_H
|
||||
|
||||
#include <iostream>
|
||||
#include <CGAL/IO/read_3mf.h>
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
|
||||
namespace CGAL{
|
||||
/*!
|
||||
* Extracts the surface meshes from an input 3mf file and appends it to `output`.
|
||||
*\tparam Point the Point type of the output meshes.
|
||||
* \param file_name the path to the 3mf file.
|
||||
* \param output a `std::vector` containing the `CGAL::Surface_mesh`s that will be filled by this function.
|
||||
* \return the number of extracted meshes.
|
||||
*/
|
||||
|
||||
template<typename Point>
|
||||
int read_3mf(const std::string& file_name,
|
||||
std::vector<CGAL::Surface_mesh<Point> >& output)
|
||||
{
|
||||
typedef std::vector<Point> PointRange;
|
||||
typedef std::vector<std::size_t> Polygon;
|
||||
typedef std::vector<Polygon> PolygonRange;
|
||||
typedef CGAL::Surface_mesh<Point> SMesh;
|
||||
typedef typename SMesh::Vertex_index Vertex_index;
|
||||
typedef typename SMesh::Face_index Face_index;
|
||||
|
||||
std::vector<PointRange> all_points;
|
||||
std::vector<PolygonRange> all_polygons;
|
||||
std::vector<std::string> names;
|
||||
std::vector<std::vector<CGAL::Color> > all_colors;
|
||||
int result = 0;
|
||||
int nb_meshes =
|
||||
CGAL::read_triangle_soups_from_3mf(file_name,
|
||||
all_points, all_polygons, all_colors, names);
|
||||
if(nb_meshes < 0 )
|
||||
{
|
||||
std::cerr << "Error in reading meshes."<<std::endl;
|
||||
return -1;
|
||||
}
|
||||
output.reserve(nb_meshes);
|
||||
for(int i = 0; i< nb_meshes; ++i)
|
||||
{
|
||||
bool skip = false;
|
||||
SMesh sm;
|
||||
PolygonRange triangles = all_polygons[i];
|
||||
PointRange points = all_points[i];
|
||||
std::vector<CGAL::Color> colors = all_colors[i];
|
||||
//Create the surface mesh from scratch
|
||||
std::size_t n(points.size());
|
||||
sm.reserve(n,0, triangles.size());
|
||||
for(const Point& p : points)
|
||||
{
|
||||
sm.add_vertex(p);
|
||||
}
|
||||
|
||||
for(Polygon& triangle : triangles)
|
||||
{
|
||||
std::vector<Vertex_index> face;
|
||||
face.reserve(triangle.size());
|
||||
for(auto index : triangle)
|
||||
{
|
||||
face.push_back(Vertex_index(index));
|
||||
}
|
||||
Face_index fi = sm.add_face(face);
|
||||
if(fi == sm.null_face())
|
||||
{
|
||||
skip = true;
|
||||
sm.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(skip)
|
||||
continue;
|
||||
//end constructin the surface mesh from scratch
|
||||
|
||||
CGAL::Color first = colors.front();
|
||||
bool need_pmap = false;
|
||||
for(auto color : colors)
|
||||
{
|
||||
if (color != first)
|
||||
{
|
||||
need_pmap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(need_pmap)
|
||||
{
|
||||
typename SMesh::template Property_map<Face_index, CGAL::Color> fcolor =
|
||||
sm.template add_property_map<Face_index,CGAL::Color>("f:color",first).first;
|
||||
for(std::size_t pid = 0; pid < colors.size(); ++pid)
|
||||
{
|
||||
put(fcolor, Face_index(pid), colors[pid]);//should work bc mesh is just created and shouldn't have any destroyed face.
|
||||
}
|
||||
}
|
||||
output.push_back(sm);
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}//end CGAL
|
||||
#endif // CGAL_SURFACE_MESH_3MF_H
|
||||
|
|
@ -28,16 +28,23 @@
|
|||
#include <QFileInfo>
|
||||
#include <QStringList>
|
||||
#include <QtPlugin>
|
||||
|
||||
class QMainWindow;
|
||||
class Messages_interface;
|
||||
namespace CGAL{
|
||||
namespace Three {
|
||||
class Scene_item;
|
||||
class Scene_interface;
|
||||
/*!
|
||||
* This class provides a base for creating a new IO plugin.
|
||||
*/
|
||||
class Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
public:
|
||||
//! \brief Initializes the plugin
|
||||
//! This function is called in the constructor of the MainWindow.
|
||||
//! Whatever initialization the plugin needs can be done here. Default
|
||||
//! behavior is to do nothing.
|
||||
virtual void init(){}
|
||||
//!Returns the name of the plugin
|
||||
//!It is used by the loading system.
|
||||
virtual QString name() const = 0;
|
||||
|
|
@ -58,17 +65,23 @@ public:
|
|||
|
||||
//! Specifies if the io_plugin is able to load an item or not.
|
||||
//! This must be overriden.
|
||||
virtual bool canLoad() const = 0;
|
||||
//! Loads an item from a file.
|
||||
virtual bool canLoad(QFileInfo fileinfo) const = 0;
|
||||
//! Loads one or more item(s) from a file. `ok` is `true` if the loading
|
||||
//! was successful, `false` otherwise.
|
||||
//! New items will be added to the scene if `add_to_scene` is `true`.
|
||||
//! You don't want that when you reload an item, for example,
|
||||
//! as it will be added at some other point of the process.
|
||||
//! This must be overriden.
|
||||
virtual Scene_item* load(QFileInfo fileinfo) = 0;
|
||||
virtual QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) = 0;
|
||||
//!Specifies if the io_plugin can save the item or not.
|
||||
//!This must be overriden.
|
||||
virtual bool canSave(const Scene_item*) = 0;
|
||||
//!Saves the item in the file corresponding to the path
|
||||
//!Saves one or more items in the file corresponding to the path
|
||||
//!contained in fileinfo. Returns false if error.
|
||||
//! This must be overriden.
|
||||
virtual bool save(const Scene_item*, QFileInfo fileinfo) = 0;
|
||||
//! @attention When a file is successfully saved, it must be removed from the
|
||||
//! list.
|
||||
virtual bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& ) = 0;
|
||||
|
||||
//! If this returns `true`, then the loader will be chosen as default in the
|
||||
//! list of available loaders when saving a file, which means it will be the
|
||||
|
|
@ -83,6 +96,6 @@ public:
|
|||
}
|
||||
}
|
||||
Q_DECLARE_INTERFACE(CGAL::Three::Polyhedron_demo_io_plugin_interface,
|
||||
"com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
||||
"com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90")
|
||||
|
||||
#endif // POLYHEDRON_DEMO_IO_PLUGIN_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public :
|
|||
:x(p_x), y(p_y), z(p_z),_3D(p_3D), _is_always_visible(always_visible), m_text(p_text), m_font(font), m_color(p_color)
|
||||
{
|
||||
QFontMetrics fm(m_font);
|
||||
_width = float(fm.width(m_text));
|
||||
_width = float(fm.width(m_text)+2);
|
||||
_height = float(fm.height());
|
||||
}
|
||||
//!\brief Accessor for the string
|
||||
|
|
|
|||
Loading…
Reference in New Issue