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;
|
zClippingCoef_ = coef;
|
||||||
projectionMatrixIsUpToDate_ = false;
|
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 */
|
/*! @name Scene radius and center */
|
||||||
|
|
@ -463,6 +473,7 @@ private:
|
||||||
mutable bool modelViewMatrixIsUpToDate_;
|
mutable bool modelViewMatrixIsUpToDate_;
|
||||||
mutable GLdouble projectionMatrix_[16]; // Buffered projection matrix.
|
mutable GLdouble projectionMatrix_[16]; // Buffered projection matrix.
|
||||||
mutable bool projectionMatrixIsUpToDate_;
|
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
|
// S t e r e o p a r a m e t e r s
|
||||||
qreal IODistance_; // inter-ocular distance, in meters
|
qreal IODistance_; // inter-ocular distance, in meters
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ CGAL_INLINE_FUNCTION
|
||||||
Camera::Camera(QObject *parent)
|
Camera::Camera(QObject *parent)
|
||||||
: frame_(nullptr), fieldOfView_(CGAL_PI / 4.0), modelViewMatrixIsUpToDate_(false),
|
: frame_(nullptr), fieldOfView_(CGAL_PI / 4.0), modelViewMatrixIsUpToDate_(false),
|
||||||
projectionMatrixIsUpToDate_(false) {
|
projectionMatrixIsUpToDate_(false) {
|
||||||
|
m_zMin = 0;
|
||||||
setParent(parent);
|
setParent(parent);
|
||||||
// #CONNECTION# Camera copy constructor
|
// #CONNECTION# Camera copy constructor
|
||||||
interpolationKfi_ = new KeyFrameInterpolator;
|
interpolationKfi_ = new KeyFrameInterpolator;
|
||||||
|
|
@ -228,7 +229,7 @@ qreal Camera::zNear() const {
|
||||||
z = zMin;
|
z = zMin;
|
||||||
break;
|
break;
|
||||||
case Camera::ORTHOGRAPHIC:
|
case Camera::ORTHOGRAPHIC:
|
||||||
z = 0.0;
|
z = m_zMin;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return z;
|
return z;
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QWidgetAction>
|
#include <QWidgetAction>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
#include <QSequentialIterable>
|
||||||
#ifdef QT_SCRIPT_LIB
|
#ifdef QT_SCRIPT_LIB
|
||||||
# include <QScriptValue>
|
# include <QScriptValue>
|
||||||
# ifdef QT_SCRIPTTOOLS_LIB
|
# ifdef QT_SCRIPTTOOLS_LIB
|
||||||
|
|
@ -790,6 +790,7 @@ bool MainWindow::initIOPlugin(QObject* obj)
|
||||||
CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin =
|
CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin =
|
||||||
qobject_cast<CGAL::Three::Polyhedron_demo_io_plugin_interface*>(obj);
|
qobject_cast<CGAL::Three::Polyhedron_demo_io_plugin_interface*>(obj);
|
||||||
if(plugin) {
|
if(plugin) {
|
||||||
|
plugin->init();
|
||||||
io_plugins << plugin;
|
io_plugins << plugin;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -999,20 +1000,29 @@ void MainWindow::reloadItem() {
|
||||||
|
|
||||||
CGAL::Three::Polyhedron_demo_io_plugin_interface* fileloader = findLoader(loader_name);
|
CGAL::Three::Polyhedron_demo_io_plugin_interface* fileloader = findLoader(loader_name);
|
||||||
QFileInfo fileinfo(filename);
|
QFileInfo fileinfo(filename);
|
||||||
|
bool ok;
|
||||||
CGAL::Three::Scene_item* new_item = loadItem(fileinfo, fileloader);
|
QList<Scene_item*> new_items = loadItem(fileinfo, fileloader, ok, false);
|
||||||
if(!new_item)
|
if(!ok)
|
||||||
return;
|
return;
|
||||||
new_item->setName(item->name());
|
QVariant varian = item->property("load_mates");
|
||||||
new_item->setColor(item->color());
|
QSequentialIterable iterable = varian.value<QSequentialIterable>();
|
||||||
new_item->setRenderingMode(item->renderingMode());
|
// Can use foreach:
|
||||||
new_item->setVisible(item->visible());
|
int mate_id = 0;
|
||||||
Scene_item_with_properties *property_item = dynamic_cast<Scene_item_with_properties*>(new_item);
|
Q_FOREACH(const QVariant &v, iterable)
|
||||||
scene->replaceItem(scene->item_id(item), new_item, true);
|
{
|
||||||
if(property_item)
|
Scene_item* mate = v.value<Scene_item*>();
|
||||||
property_item->copyProperties(item);
|
Scene_item* new_item = new_items[mate_id];
|
||||||
new_item->invalidateOpenGLBuffers();
|
new_item->setName(mate->name());
|
||||||
item->deleteLater();
|
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
|
// 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
|
// 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) {
|
for(CGAL::Three::Polyhedron_demo_io_plugin_interface* io_plugin : io_plugins) {
|
||||||
if ( !io_plugin->canLoad() ) continue;
|
|
||||||
all_items << io_plugin->name();
|
|
||||||
if ( file_matches_filter(io_plugin->loadNameFilters(), filename.toLower()) )
|
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()))
|
if(io_plugin->isDefaultLoader(fileinfo.completeSuffix()))
|
||||||
selected_items.prepend(io_plugin->name());
|
selected_items.prepend(io_plugin->name());
|
||||||
else
|
else
|
||||||
|
|
@ -1149,71 +1159,69 @@ void MainWindow::open(QString filename)
|
||||||
|
|
||||||
settings.setValue("OFF open directory",
|
settings.setValue("OFF open directory",
|
||||||
fileinfo.absoluteDir().absolutePath());
|
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;
|
return;
|
||||||
this->addToRecentFiles(fileinfo.absoluteFilePath());
|
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);
|
updateViewersBboxes(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::open(QString filename, QString loader_name) {
|
bool MainWindow::open(QString filename, QString loader_name) {
|
||||||
QFileInfo fileinfo(filename);
|
QFileInfo fileinfo(filename);
|
||||||
boost::optional<CGAL::Three::Scene_item*> item_opt;
|
boost::optional<bool> item_opt;
|
||||||
CGAL::Three::Scene_item* item = 0;
|
|
||||||
try {
|
try {
|
||||||
item_opt = wrap_a_call_to_cpp
|
item_opt = wrap_a_call_to_cpp
|
||||||
([this, fileinfo, loader_name]()
|
([this, fileinfo, loader_name]()
|
||||||
{
|
{
|
||||||
return loadItem(fileinfo, findLoader(loader_name));
|
bool ok;
|
||||||
|
loadItem(fileinfo, findLoader(loader_name), ok);
|
||||||
|
return ok;
|
||||||
},
|
},
|
||||||
this, __FILE__, __LINE__
|
this, __FILE__, __LINE__
|
||||||
);
|
);
|
||||||
if(!item_opt) return false;
|
if(!item_opt) return false;
|
||||||
else item = *item_opt;
|
|
||||||
}
|
}
|
||||||
catch(std::logic_error& e) {
|
catch(std::logic_error& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CGAL::Three::Scene_item* MainWindow::loadItem(QFileInfo fileinfo, CGAL::Three::Polyhedron_demo_io_plugin_interface* loader) {
|
QList<Scene_item*> MainWindow::loadItem(QFileInfo fileinfo,
|
||||||
CGAL::Three::Scene_item* item = NULL;
|
CGAL::Three::Polyhedron_demo_io_plugin_interface* loader,
|
||||||
|
bool &ok,
|
||||||
|
bool add_to_scene) {
|
||||||
if(!fileinfo.isFile() || !fileinfo.isReadable()) {
|
if(!fileinfo.isFile() || !fileinfo.isReadable()) {
|
||||||
QMessageBox::warning(this, tr("Error"),
|
QMessageBox::warning(this, tr("Error"),
|
||||||
QString("File %1 is not a readable file.")
|
QString("File %1 is not a readable file.")
|
||||||
.arg(fileinfo.absoluteFilePath()));
|
.arg(fileinfo.absoluteFilePath()));
|
||||||
}
|
}
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QCursor tmp_cursor(Qt::WaitCursor);
|
||||||
|
CGAL::Three::Three::CursorScopeGuard guard(tmp_cursor);
|
||||||
item = loader->load(fileinfo);
|
QList<Scene_item*> result = loader->load(fileinfo, ok, add_to_scene);
|
||||||
QApplication::restoreOverrideCursor();
|
if(result.empty() || !ok)
|
||||||
if(!item) {
|
{
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
QMessageBox::warning(this, tr("Error"),
|
QMessageBox::warning(this, tr("Error"),
|
||||||
QString("Could not load item from file %1 using plugin %2")
|
QString("Could not load item from file %1 using plugin %2")
|
||||||
.arg(fileinfo.absoluteFilePath()).arg(loader->name()));
|
.arg(fileinfo.absoluteFilePath()).arg(loader->name()));
|
||||||
return 0;
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
selectSceneItem(scene->item_id(result.back()));
|
||||||
item->setProperty("source filename", fileinfo.absoluteFilePath());
|
for(Scene_item* item : result)
|
||||||
item->setProperty("loader_name", loader->name());
|
{
|
||||||
return item;
|
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;
|
typedef QMap<QString, CGAL::Three::Polyhedron_demo_io_plugin_interface*> FilterPluginMap;
|
||||||
FilterPluginMap 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(";;");
|
QStringList split_filters = plugin->loadNameFilters().split(";;");
|
||||||
Q_FOREACH(const QString& filter, split_filters) {
|
Q_FOREACH(const QString& filter, split_filters) {
|
||||||
FilterPluginMap::iterator it = filterPluginMap.find(filter);
|
FilterPluginMap::iterator it = filterPluginMap.find(filter);
|
||||||
|
|
@ -1878,39 +1886,54 @@ void MainWindow::on_actionLoad_triggered()
|
||||||
std::size_t nb_item = -1;
|
std::size_t nb_item = -1;
|
||||||
|
|
||||||
Q_FOREACH(const QString& filename, dialog.selectedFiles()) {
|
Q_FOREACH(const QString& filename, dialog.selectedFiles()) {
|
||||||
|
|
||||||
CGAL::Three::Scene_item* item = NULL;
|
CGAL::Three::Scene_item* item = NULL;
|
||||||
if(selectedPlugin) {
|
if(selectedPlugin) {
|
||||||
QFileInfo info(filename);
|
QFileInfo info(filename);
|
||||||
item = loadItem(info, selectedPlugin);
|
bool ok;
|
||||||
item->setColor(colors_[++nb_item]);
|
QList<Scene_item*> result = loadItem(info, selectedPlugin, ok);
|
||||||
Scene::Item_id index = scene->addItem(item);
|
if(!ok)
|
||||||
selectSceneItem(index);
|
continue;
|
||||||
CGAL::Three::Scene_group_item* group =
|
for(Scene_item* item : result)
|
||||||
qobject_cast<CGAL::Three::Scene_group_item*>(item);
|
{
|
||||||
if(group)
|
if(!item->property("already_colored").toBool())
|
||||||
scene->redraw_model();
|
{
|
||||||
|
++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);
|
this->addToRecentFiles(filename);
|
||||||
} else {
|
} else {
|
||||||
int scene_size = scene->numberOfEntries();
|
int scene_size = scene->numberOfEntries();
|
||||||
open(filename);
|
open(filename);
|
||||||
if(scene->numberOfEntries() != scene_size)
|
item = scene->item(scene->numberOfEntries()-1);
|
||||||
scene->item(scene->numberOfEntries()-1)->setColor(colors_[++nb_item]);
|
if(scene->numberOfEntries() != scene_size
|
||||||
|
&& !item->property("already_colored").toBool())
|
||||||
|
item->setColor(colors_[++nb_item]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSaveAs_triggered()
|
void MainWindow::on_actionSaveAs_triggered()
|
||||||
{
|
{
|
||||||
Scene_item* item = NULL;
|
QList<Scene_item*> to_save;
|
||||||
|
for(Scene::Item_id id : scene->selectionIndices())
|
||||||
Q_FOREACH(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;
|
QVector<CGAL::Three::Polyhedron_demo_io_plugin_interface*> canSavePlugins;
|
||||||
QStringList filters;
|
QStringList filters;
|
||||||
QString sf;
|
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)) {
|
if(plugin->canSave(item)) {
|
||||||
canSavePlugins << plugin;
|
canSavePlugins << plugin;
|
||||||
filters += plugin->saveNameFilters();
|
filters += plugin->saveNameFilters();
|
||||||
|
|
@ -1926,7 +1949,7 @@ void MainWindow::on_actionSaveAs_triggered()
|
||||||
tr("Cannot save"),
|
tr("Cannot save"),
|
||||||
tr("The selected object %1 cannot be saved.")
|
tr("The selected object %1 cannot be saved.")
|
||||||
.arg(item->name()));
|
.arg(item->name()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_FOREACH(QString string, filters)
|
Q_FOREACH(QString string, filters)
|
||||||
{
|
{
|
||||||
|
|
@ -1962,14 +1985,14 @@ void MainWindow::on_actionSaveAs_triggered()
|
||||||
dir,
|
dir,
|
||||||
filters.join(";;"),
|
filters.join(";;"),
|
||||||
&sf);
|
&sf);
|
||||||
|
|
||||||
if(filename.isEmpty())
|
if(filename.isEmpty())
|
||||||
return;
|
return;
|
||||||
last_saved_dir = QFileInfo(filename).absoluteDir().path();
|
last_saved_dir = QFileInfo(filename).absoluteDir().path();
|
||||||
extensions.indexIn(sf.split(";;").first());
|
extensions.indexIn(sf.split(";;").first());
|
||||||
QString filter_ext, filename_ext;
|
QString filter_ext, filename_ext;
|
||||||
filter_ext = extensions.cap().split(" ").first();// in case of syntax like (*.a *.b)
|
filter_ext = extensions.cap().split(" ").first();// in case of syntax like (*.a *.b)
|
||||||
|
|
||||||
filter_ext.remove(")");
|
filter_ext.remove(")");
|
||||||
filter_ext.remove("(");
|
filter_ext.remove("(");
|
||||||
//remove *
|
//remove *
|
||||||
|
|
@ -2017,18 +2040,18 @@ void MainWindow::on_actionSaveAs_triggered()
|
||||||
}
|
}
|
||||||
for(auto v : CGAL::QGLViewer::QGLViewerPool())
|
for(auto v : CGAL::QGLViewer::QGLViewerPool())
|
||||||
v->update();
|
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);
|
QFileInfo fileinfo(filename);
|
||||||
bool saved = false;
|
bool saved = false;
|
||||||
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) &&
|
if( plugin->canSave(to_save.front()) &&
|
||||||
file_matches_filter(plugin->saveNameFilters(),filename.toLower()) )
|
file_matches_filter(plugin->saveNameFilters(),filename.toLower()) )
|
||||||
{
|
{
|
||||||
if(plugin->save(item, fileinfo))
|
if(plugin->save(fileinfo, to_save))
|
||||||
{
|
{
|
||||||
saved = true;
|
saved = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -2039,7 +2062,7 @@ void MainWindow::save(QString filename, CGAL::Three::Scene_item* item) {
|
||||||
QMessageBox::warning(this,
|
QMessageBox::warning(this,
|
||||||
tr("Cannot save"),
|
tr("Cannot save"),
|
||||||
tr("The selected object %1 was not saved. (Maybe a wrong extension ?)")
|
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()
|
void MainWindow::on_actionSaveSnapshot_triggered()
|
||||||
|
|
@ -2471,7 +2494,7 @@ QString MainWindow::get_item_stats()
|
||||||
for(int i=0; i<items.size(); i++)
|
for(int i=0; i<items.size(); i++)
|
||||||
{
|
{
|
||||||
Scene_item* item = scene->item(id);
|
Scene_item* item = scene->item(id);
|
||||||
QString classname = item->property("classname").toString();
|
QString classname = item->property("classname").toString();
|
||||||
if(classname.isEmpty())
|
if(classname.isEmpty())
|
||||||
classname = item->metaObject()->className();
|
classname = item->metaObject()->className();
|
||||||
if(classnames.at(i).contains(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 ?")
|
if(QMessageBox::question(this, "Save", "Are you sure you want to override these files ?")
|
||||||
== QMessageBox::No)
|
== QMessageBox::No)
|
||||||
return;
|
return;
|
||||||
Scene_item* item = nullptr;
|
QList<Scene_item*> to_save;
|
||||||
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
|
|
||||||
|
for(Scene::Item_id id : scene->selectionIndices())
|
||||||
{
|
{
|
||||||
item = scene->item(id);
|
Scene_item* item = scene->item(id);
|
||||||
if(!item->property("source filename").toString().isEmpty())
|
if(!item->property("source filename").toString().isEmpty())
|
||||||
{
|
{
|
||||||
QString filename = item->property("source filename").toString();
|
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`*/
|
@returns the IO plugin associated with `loader_name`*/
|
||||||
CGAL::Three::Polyhedron_demo_io_plugin_interface* findLoader(const QString& loader_name) const;
|
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
|
* throws `std::logic_error` if loading does not succeed or
|
||||||
* `std::invalid_argument` if `fileinfo` specifies an invalid file*/
|
* `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 computeViewerBBox(CGAL::qglviewer::Vec &min, CGAL::qglviewer::Vec &max);
|
||||||
void updateViewerBbox(Viewer* vi, bool recenter, CGAL::qglviewer::Vec min,
|
void updateViewerBbox(Viewer* vi, bool recenter, CGAL::qglviewer::Vec min,
|
||||||
CGAL::qglviewer::Vec max);
|
CGAL::qglviewer::Vec max);
|
||||||
|
|
@ -346,7 +349,7 @@ protected Q_SLOTS:
|
||||||
//!Opens a dialog to save selected item if able.
|
//!Opens a dialog to save selected item if able.
|
||||||
void on_actionSaveAs_triggered();
|
void on_actionSaveAs_triggered();
|
||||||
//!Calls the function save of the current plugin if able.
|
//!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.
|
//!Calls the function saveSnapShot of the viewer.
|
||||||
void on_actionSaveSnapshot_triggered();
|
void on_actionSaveSnapshot_triggered();
|
||||||
//!Opens a Dialog to choose a color and make it the background color.
|
//!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_plugin_interface)
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_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.PluginInterface/1.0")
|
||||||
|
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Polyhedron_demo_cut_plugin() : QObject(), edges_item(0) {
|
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
|
// returns true if one surface_mesh is in the entries
|
||||||
for (int i=0; i< scene->numberOfEntries(); ++i)
|
for (int i=0; i< scene->numberOfEntries(); ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -808,29 +809,32 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual QString name() const
|
QString name() const Q_DECL_OVERRIDE
|
||||||
{
|
{
|
||||||
return "cut-plugin";
|
return "cut-plugin";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual QString nameFilters() const
|
QString nameFilters() const Q_DECL_OVERRIDE
|
||||||
{
|
{
|
||||||
return "Segment soup file (*.polylines.txt *.cgal)";
|
return "Segment soup file (*.polylines.txt *.cgal)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool canLoad() const
|
bool canLoad(QFileInfo) const Q_DECL_OVERRIDE
|
||||||
{
|
{
|
||||||
return false;
|
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
|
// This plugin supports edges items
|
||||||
bool b = qobject_cast<const Scene_edges_item*>(item) != 0;
|
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)
|
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items) Q_DECL_OVERRIDE
|
||||||
{ // This plugin supports edges items
|
{
|
||||||
|
Scene_item* item = items.front();
|
||||||
|
// This plugin supports edges items
|
||||||
const Scene_edges_item* edges_item =
|
const Scene_edges_item* edges_item =
|
||||||
qobject_cast<const Scene_edges_item*>(item);
|
qobject_cast<const Scene_edges_item*>(item);
|
||||||
|
|
||||||
|
|
@ -848,15 +854,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ofstream out(fileinfo.filePath().toUtf8());
|
std::ofstream out(fileinfo.filePath().toUtf8());
|
||||||
|
bool ok = (out && edges_item->save(out));
|
||||||
return (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,
|
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface,
|
||||||
Messages_interface* m);
|
Messages_interface* m) override;
|
||||||
QList<QAction*> actions() const;
|
QList<QAction*> actions() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
bool eventFilter(QObject *, QEvent *event)
|
bool eventFilter(QObject *, QEvent *event) Q_DECL_OVERRIDE
|
||||||
{
|
{
|
||||||
if(!plane_item)
|
if(!plane_item)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,47 @@
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include "Messages_interface.h"
|
#include "Messages_interface.h"
|
||||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
|
||||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||||
|
|
||||||
#include "Camera_positions_list.h"
|
#include "Camera_positions_list.h"
|
||||||
|
|
||||||
|
#include <CGAL/Three/Three.h>
|
||||||
#include <CGAL/Three/Viewer_interface.h>
|
#include <CGAL/Three/Viewer_interface.h>
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
using namespace CGAL::Three;
|
using namespace CGAL::Three;
|
||||||
class Polyhedron_demo_camera_positions_plugin :
|
class Polyhedron_demo_camera_positions_plugin :
|
||||||
public QObject,
|
public QObject,
|
||||||
public Polyhedron_demo_plugin_interface,
|
|
||||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_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")
|
||||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* );
|
void init() override;
|
||||||
QList<QAction*> actions() const;
|
|
||||||
|
|
||||||
QString name() const { return "camera_positions_plugin"; }
|
QString name() const override { return "camera_positions_plugin"; }
|
||||||
QString nameFilters() const { return "Camera positions (*.camera.txt)"; }
|
QString nameFilters() const override { return "Camera positions (*.camera.txt)"; }
|
||||||
bool canLoad() const { return true; }
|
bool canLoad(QFileInfo) const override { return true; }
|
||||||
Scene_item* load(QFileInfo fileinfo) { cpl->load(fileinfo.filePath()); return 0; }
|
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 canSave(const Scene_item*) override { return false; }
|
||||||
bool save(const Scene_item*, QFileInfo ) {return false; }
|
bool save(QFileInfo,QList<CGAL::Three::Scene_item*>& ) override {return false; }
|
||||||
bool applicable(QAction*) const {return false;}
|
|
||||||
private:
|
private:
|
||||||
Camera_positions_list* cpl;
|
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);
|
cpl = new Camera_positions_list(CGAL::Three::Three::mainWindow());
|
||||||
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, cpl);
|
CGAL::Three::Three::mainWindow()->addDockWidget(Qt::LeftDockWidgetArea, cpl);
|
||||||
}
|
|
||||||
|
|
||||||
QList<QAction*>
|
|
||||||
Polyhedron_demo_camera_positions_plugin::actions() const
|
|
||||||
{
|
|
||||||
return QList<QAction*>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Camera_positions_plugin.moc"
|
#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)
|
list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_variadic_templates has_cxx_variadic)
|
||||||
|
|
||||||
if(has_cxx_rvalues LESS 0 OR has_cxx_variadic LESS 0)
|
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()
|
else()
|
||||||
set(needed_cxx_features cxx_rvalue_references cxx_variadic_templates)
|
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.")
|
message(STATUS "NOTICE : the LAS IO plugin needs LAS libraries and will not be compiled.")
|
||||||
endif()
|
endif()
|
||||||
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 :
|
class Polyhedron_demo_gocad_plugin :
|
||||||
public QObject,
|
public QObject,
|
||||||
public Polyhedron_demo_io_plugin_interface,
|
public Polyhedron_demo_io_plugin_interface
|
||||||
public Polyhedron_demo_plugin_helper
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
Q_INTERFACES(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.90" FILE "gocad_io_plugin.json")
|
||||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" )
|
|
||||||
|
|
||||||
public:
|
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 nameFilters() const;
|
||||||
QString name() const { return "gocad_plugin"; }
|
QString name() const { return "gocad_plugin"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo) const;
|
||||||
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*);
|
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 {
|
QString Polyhedron_demo_gocad_plugin::nameFilters() const {
|
||||||
return "GOCAD files (*.ts)";
|
return "GOCAD files (*.ts)";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Polyhedron_demo_gocad_plugin::canLoad() const {
|
bool Polyhedron_demo_gocad_plugin::canLoad(QFileInfo) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CGAL::Three::Scene_item*
|
QList<Scene_item*>
|
||||||
Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) {
|
Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
std::ifstream in(fileinfo.filePath().toUtf8());
|
std::ifstream in(fileinfo.filePath().toUtf8());
|
||||||
if(!in) {
|
if(!in) {
|
||||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
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)
|
if(fileinfo.size() == 0)
|
||||||
{
|
{
|
||||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
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());
|
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)){
|
if(! read_gocad(P, in, name, color)){
|
||||||
std::cerr << "Error: Invalid polyhedron" << std::endl;
|
std::cerr << "Error: Invalid polyhedron" << std::endl;
|
||||||
delete item;
|
delete item;
|
||||||
return 0;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
t.stop();
|
t.stop();
|
||||||
|
|
@ -98,7 +91,10 @@ Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) {
|
||||||
item->setColor(qcolor);
|
item->setColor(qcolor);
|
||||||
}
|
}
|
||||||
item->invalidateOpenGLBuffers();
|
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)
|
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);
|
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
|
// This plugin supports polyhedrons
|
||||||
const Scene_surface_mesh_item* sm_item =
|
const Scene_surface_mesh_item* sm_item =
|
||||||
qobject_cast<const Scene_surface_mesh_item*>(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);
|
out.precision (std::numeric_limits<double>::digits10 + 2);
|
||||||
SMesh* poly = const_cast<SMesh*>(sm_item->polyhedron());
|
SMesh* poly = const_cast<SMesh*>(sm_item->polyhedron());
|
||||||
write_gocad(*poly, out, qPrintable(fileinfo.baseName()));
|
write_gocad(*poly, out, qPrintable(fileinfo.baseName()));
|
||||||
|
items.pop_front();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@
|
||||||
using namespace CGAL::Three;
|
using namespace CGAL::Three;
|
||||||
class Io_implicit_function_plugin :
|
class Io_implicit_function_plugin :
|
||||||
public QObject,
|
public QObject,
|
||||||
// public Polyhedron_demo_plugin_interface,
|
|
||||||
protected Polyhedron_demo_plugin_helper
|
protected Polyhedron_demo_plugin_helper
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,33 @@
|
||||||
#include "Scene_points_with_normal_item.h"
|
#include "Scene_points_with_normal_item.h"
|
||||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||||
|
#include <CGAL/Three/Three.h>
|
||||||
|
#include <CGAL/Three/Scene_item.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
using namespace CGAL::Three;
|
||||||
class Polyhedron_demo_las_plugin :
|
class Polyhedron_demo_las_plugin :
|
||||||
public QObject,
|
public QObject,
|
||||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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:
|
public:
|
||||||
QString name() const { return "las_plugin"; }
|
QString name() const { return "las_plugin"; }
|
||||||
QString nameFilters() const { return "LAS files (*.las);;Compressed LAS files (*.laz)"; }
|
QString nameFilters() const { return "LAS files (*.las);;Compressed LAS files (*.laz)"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo fileinfo) const;
|
||||||
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*);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::Three::Scene_item*
|
QList<Scene_item*> Polyhedron_demo_las_plugin::
|
||||||
Polyhedron_demo_las_plugin::load(QFileInfo fileinfo) {
|
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::binary);
|
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::binary);
|
||||||
|
|
||||||
if(!in)
|
if(!in)
|
||||||
|
|
@ -37,11 +38,15 @@ Polyhedron_demo_las_plugin::load(QFileInfo fileinfo) {
|
||||||
if(!item->read_las_point_set(in))
|
if(!item->read_las_point_set(in))
|
||||||
{
|
{
|
||||||
delete item;
|
delete item;
|
||||||
return 0;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setName(fileinfo.completeBaseName());
|
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)
|
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);
|
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)
|
// Check extension (quietly)
|
||||||
std::string extension = fileinfo.suffix().toUtf8().data();
|
std::string extension = fileinfo.suffix().toUtf8().data();
|
||||||
if (extension != "las" && extension != "LAS")
|
if (extension != "las" && extension != "LAS")
|
||||||
|
|
@ -63,6 +69,7 @@ bool Polyhedron_demo_las_plugin::save(const CGAL::Three::Scene_item* item, QFile
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::ofstream out(fileinfo.filePath().toUtf8().data());
|
std::ofstream out(fileinfo.filePath().toUtf8().data());
|
||||||
|
items.pop_front();
|
||||||
return point_set_item->write_las_point_set(out);
|
return point_set_item->write_las_point_set(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,32 +17,37 @@ class Polyhedron_demo_io_nef_plugin :
|
||||||
public:
|
public:
|
||||||
QString nameFilters() const;
|
QString nameFilters() const;
|
||||||
QString name() const { return "io_nef_plugin"; }
|
QString name() const { return "io_nef_plugin"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo) const;
|
||||||
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*);
|
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 {
|
QString Polyhedron_demo_io_nef_plugin::nameFilters() const {
|
||||||
return "nef files (*.nef3)";
|
return "nef files (*.nef3)";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Polyhedron_demo_io_nef_plugin::canLoad() const {
|
bool Polyhedron_demo_io_nef_plugin::canLoad(QFileInfo) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CGAL::Three::Scene_item*
|
QList<Scene_item*> Polyhedron_demo_io_nef_plugin::
|
||||||
Polyhedron_demo_io_nef_plugin::load(QFileInfo fileinfo) {
|
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
//do not try file with extension different from nef3
|
//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
|
// Open file
|
||||||
std::ifstream in(fileinfo.filePath().toUtf8());
|
std::ifstream in(fileinfo.filePath().toUtf8());
|
||||||
if(!in) {
|
if(!in) {
|
||||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
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
|
// Try to read .nef3 in a polyhedron
|
||||||
|
|
@ -51,15 +56,22 @@ Polyhedron_demo_io_nef_plugin::load(QFileInfo fileinfo) {
|
||||||
if(fileinfo.size() == 0)
|
if(fileinfo.size() == 0)
|
||||||
{
|
{
|
||||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
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))
|
if(!item->load(in))
|
||||||
{
|
{
|
||||||
delete item;
|
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)
|
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);
|
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
|
// This plugin supports polyhedrons and polygon soups
|
||||||
const Scene_nef_polyhedron_item* nef_item =
|
const Scene_nef_polyhedron_item* nef_item =
|
||||||
qobject_cast<const Scene_nef_polyhedron_item*>(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());
|
std::ofstream out(fileinfo.filePath().toUtf8());
|
||||||
out.precision (std::numeric_limits<double>::digits10 + 2);
|
out.precision (std::numeric_limits<double>::digits10 + 2);
|
||||||
|
items.pop_front();
|
||||||
return (nef_item && nef_item->save(out));
|
return (nef_item && nef_item->save(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class Polyhedron_demo_off_plugin :
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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:
|
public:
|
||||||
bool isDefaultLoader(const Scene_item *item) const
|
bool isDefaultLoader(const Scene_item *item) const
|
||||||
|
|
@ -40,22 +40,21 @@ public:
|
||||||
}
|
}
|
||||||
QString name() const { return "off_plugin"; }
|
QString name() const { return "off_plugin"; }
|
||||||
QString nameFilters() const { return "OFF files (*.off);;Wavefront OBJ (*.obj)"; }
|
QString nameFilters() const { return "OFF files (*.off);;Wavefront OBJ (*.obj)"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo fileinfo) const;
|
||||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
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_off(QFileInfo fileinfo);
|
||||||
CGAL::Three::Scene_item* load_obj(QFileInfo fileinfo);
|
CGAL::Three::Scene_item* load_obj(QFileInfo fileinfo);
|
||||||
|
|
||||||
bool canSave(const CGAL::Three::Scene_item*);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<Scene_item*> Polyhedron_demo_off_plugin::
|
||||||
CGAL::Three::Scene_item*
|
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
Polyhedron_demo_off_plugin::load(QFileInfo fileinfo) {
|
|
||||||
|
|
||||||
if(fileinfo.size() == 0)
|
if(fileinfo.size() == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -63,14 +62,41 @@ Polyhedron_demo_off_plugin::load(QFileInfo fileinfo) {
|
||||||
Scene_surface_mesh_item* item =
|
Scene_surface_mesh_item* item =
|
||||||
new Scene_surface_mesh_item(SMesh());
|
new Scene_surface_mesh_item(SMesh());
|
||||||
item->setName(fileinfo.completeBaseName());
|
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"){
|
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"){
|
} 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);
|
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
|
// This plugin supports point sets, surface_meshes and polygon soups
|
||||||
const Scene_points_with_normal_item* points_item =
|
const Scene_points_with_normal_item* points_item =
|
||||||
qobject_cast<const Scene_points_with_normal_item*>(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);
|
out.precision (std::numeric_limits<double>::digits10 + 2);
|
||||||
|
|
||||||
if(fileinfo.suffix().toLower() == "off"){
|
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)) ||
|
(soup_item && soup_item->save(out)) ||
|
||||||
(points_item && points_item->write_off_point_set(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"){
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,24 +11,24 @@ class Polyhedron_demo_off_to_nef_plugin :
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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:
|
public:
|
||||||
QString name() const { return "off_to_nef_plugin"; }
|
QString name() const { return "off_to_nef_plugin"; }
|
||||||
QString nameFilters() const { return "OFF files, into nef (*.off)"; }
|
QString nameFilters() const { return "OFF files, into nef (*.off)"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo) const;
|
||||||
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*);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::Three::Scene_item*
|
QList<Scene_item*> Polyhedron_demo_off_to_nef_plugin::
|
||||||
Polyhedron_demo_off_to_nef_plugin::load(QFileInfo fileinfo) {
|
load(QFileInfo fileinfo, bool& ok, bool add_to_scene){
|
||||||
std::ifstream in(fileinfo.filePath().toUtf8());
|
std::ifstream in(fileinfo.filePath().toUtf8());
|
||||||
|
|
||||||
if(!in)
|
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."));
|
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||||
item->setName(fileinfo.completeBaseName());
|
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))
|
if(!item->load_from_off(in))
|
||||||
{
|
{
|
||||||
delete item;
|
delete item;
|
||||||
return 0;
|
ok = false;
|
||||||
|
return QList<Scene_item*>()<<item;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setName(fileinfo.baseName());
|
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*)
|
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;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@
|
||||||
#include <CGAL/IO/PLY_writer.h>
|
#include <CGAL/IO/PLY_writer.h>
|
||||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
using namespace CGAL::Three;
|
||||||
class Polyhedron_demo_ply_plugin :
|
class Polyhedron_demo_ply_plugin :
|
||||||
public QObject,
|
public QObject,
|
||||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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:
|
public:
|
||||||
bool isDefaultLoader(const CGAL::Three::Scene_item *item) const
|
bool isDefaultLoader(const CGAL::Three::Scene_item *item) const
|
||||||
|
|
@ -31,20 +31,22 @@ public:
|
||||||
}
|
}
|
||||||
QString name() const { return "ply_plugin"; }
|
QString name() const { return "ply_plugin"; }
|
||||||
QString nameFilters() const { return "PLY files (*.ply)"; }
|
QString nameFilters() const { return "PLY files (*.ply)"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo fileinfo) const;
|
||||||
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*);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::Three::Scene_item*
|
QList<Scene_item*>
|
||||||
Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
Polyhedron_demo_ply_plugin::
|
||||||
|
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::binary);
|
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::binary);
|
||||||
|
|
||||||
if(!in)
|
if(!in)
|
||||||
|
|
@ -55,7 +57,8 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
||||||
if(fileinfo.size() == 0)
|
if(fileinfo.size() == 0)
|
||||||
{
|
{
|
||||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
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
|
// 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->setName(fileinfo.completeBaseName());
|
||||||
sm_item->comments() = comments;
|
sm_item->comments() = comments;
|
||||||
QApplication::restoreOverrideCursor();
|
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();
|
in.clear();
|
||||||
|
|
@ -114,14 +120,18 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
||||||
if (!(CGAL::read_PLY (in, points, polygons, fcolors, vcolors)))
|
if (!(CGAL::read_PLY (in, points, polygons, fcolors, vcolors)))
|
||||||
{
|
{
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item;
|
Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item;
|
||||||
soup_item->setName(fileinfo.completeBaseName());
|
soup_item->setName(fileinfo.completeBaseName());
|
||||||
soup_item->load (points, polygons, fcolors, vcolors);
|
soup_item->load (points, polygons, fcolors, vcolors);
|
||||||
QApplication::restoreOverrideCursor();
|
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
|
else // Open point set
|
||||||
{
|
{
|
||||||
|
|
@ -131,16 +141,21 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
||||||
{
|
{
|
||||||
delete item;
|
delete item;
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
if(item->has_normals())
|
if(item->has_normals())
|
||||||
item->setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode());
|
item->setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode());
|
||||||
item->setName(fileinfo.completeBaseName());
|
item->setName(fileinfo.completeBaseName());
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
return item;
|
ok = true;
|
||||||
|
if(add_to_scene)
|
||||||
|
CGAL::Three::Three::scene()->addItem(item);
|
||||||
|
return QList<Scene_item*>()<<item;
|
||||||
}
|
}
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
return NULL;
|
ok = true;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Polyhedron_demo_ply_plugin::canSave(const CGAL::Three::Scene_item* 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));
|
|| 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)
|
// Check extension (quietly)
|
||||||
std::string extension = fileinfo.suffix().toUtf8().data();
|
std::string extension = fileinfo.suffix().toUtf8().data();
|
||||||
if (extension != "ply" && extension != "PLY")
|
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 =
|
const Scene_points_with_normal_item* point_set_item =
|
||||||
qobject_cast<const Scene_points_with_normal_item*>(item);
|
qobject_cast<const Scene_points_with_normal_item*>(item);
|
||||||
if (point_set_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
|
// This plugin supports polygon soups
|
||||||
const Scene_polygon_soup_item* soup_item =
|
const Scene_polygon_soup_item* soup_item =
|
||||||
qobject_cast<const Scene_polygon_soup_item*>(item);
|
qobject_cast<const Scene_polygon_soup_item*>(item);
|
||||||
if (soup_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
|
// This plugin supports surface meshes
|
||||||
const Scene_surface_mesh_item* sm_item =
|
const Scene_surface_mesh_item* sm_item =
|
||||||
qobject_cast<const Scene_surface_mesh_item*>(item);
|
qobject_cast<const Scene_surface_mesh_item*>(item);
|
||||||
if (sm_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
|
// This plugin supports textured surface meshes
|
||||||
const Scene_textured_surface_mesh_item* stm_item =
|
const Scene_textured_surface_mesh_item* stm_item =
|
||||||
qobject_cast<const Scene_textured_surface_mesh_item*>(item);
|
qobject_cast<const Scene_textured_surface_mesh_item*>(item);
|
||||||
if (stm_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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,17 +17,18 @@ class Polyhedron_demo_polylines_io_plugin :
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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.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:
|
public:
|
||||||
// To silent a warning -Woverloaded-virtual
|
// To silent a warning -Woverloaded-virtual
|
||||||
// See http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings
|
// See http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings
|
||||||
|
|
||||||
|
using Polyhedron_demo_io_plugin_interface::init;
|
||||||
//! Configures the widget
|
//! Configures the widget
|
||||||
void init(QMainWindow* mainWindow,
|
void init(QMainWindow* mainWindow,
|
||||||
CGAL::Three::Scene_interface* scene_interface,
|
CGAL::Three::Scene_interface* scene_interface,
|
||||||
Messages_interface*) {
|
Messages_interface*) override{
|
||||||
//get the references
|
//get the references
|
||||||
this->scene = scene_interface;
|
this->scene = scene_interface;
|
||||||
this->mw = mainWindow;
|
this->mw = mainWindow;
|
||||||
|
|
@ -43,14 +44,14 @@ public:
|
||||||
connect(actionJoin_polylines, &QAction::triggered, this, &Polyhedron_demo_polylines_io_plugin::join);
|
connect(actionJoin_polylines, &QAction::triggered, this, &Polyhedron_demo_polylines_io_plugin::join);
|
||||||
|
|
||||||
}
|
}
|
||||||
QString name() const { return "polylines_io_plugin"; }
|
QString name() const override{ return "polylines_io_plugin"; }
|
||||||
QString nameFilters() const { return "Polylines files (*.polylines.txt *.cgal)"; }
|
QString nameFilters() const override{ return "Polylines files (*.polylines.txt *.cgal)"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo fileinfo) const override;
|
||||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override;
|
||||||
|
|
||||||
bool canSave(const CGAL::Three::Scene_item*);
|
bool canSave(const CGAL::Three::Scene_item*) override;
|
||||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>&) override;
|
||||||
bool applicable(QAction* a) const {
|
bool applicable(QAction* a) const override{
|
||||||
bool all_polylines_selected = true;
|
bool all_polylines_selected = true;
|
||||||
Q_FOREACH(int index, scene->selectionIndices())
|
Q_FOREACH(int index, scene->selectionIndices())
|
||||||
{
|
{
|
||||||
|
|
@ -69,7 +70,7 @@ public:
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QList<QAction*> actions() const {
|
QList<QAction*> actions() const override{
|
||||||
|
|
||||||
return QList<QAction*>()<<actionSplit_polylines
|
return QList<QAction*>()<<actionSplit_polylines
|
||||||
<<actionJoin_polylines;
|
<<actionJoin_polylines;
|
||||||
|
|
@ -85,19 +86,31 @@ private:
|
||||||
QAction* actionJoin_polylines;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CGAL::Three::Scene_item*
|
QList<Scene_item*>
|
||||||
Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) {
|
Polyhedron_demo_polylines_io_plugin::
|
||||||
|
load(QFileInfo fileinfo, bool& ok, bool add_to_scene){
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
std::ifstream ifs(fileinfo.filePath().toUtf8());
|
std::ifstream ifs(fileinfo.filePath().toUtf8());
|
||||||
if(!ifs) {
|
if(!ifs) {
|
||||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
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)
|
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."));
|
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||||
Scene_polylines_item* item = new Scene_polylines_item;
|
Scene_polylines_item* item = new Scene_polylines_item;
|
||||||
item->setName(fileinfo.completeBaseName());
|
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;
|
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;
|
Scene_polylines_item::Point_3 p;
|
||||||
ifs >> p;
|
ifs >> p;
|
||||||
polyline.push_back(p);
|
polyline.push_back(p);
|
||||||
if(!ifs.good()) return 0;
|
if(!ifs.good())
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::string line_remainder;
|
std::string line_remainder;
|
||||||
std::getline(ifs, 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";
|
std::cerr << " (metadata: \"" << qPrintable(metadata) << "\")\n";
|
||||||
} else {
|
} 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;
|
Scene_polylines_item* item = new Scene_polylines_item;
|
||||||
item->polylines = polylines;
|
item->polylines = polylines;
|
||||||
item->setName(fileinfo.baseName());
|
item->setName(fileinfo.baseName());
|
||||||
|
|
@ -146,7 +174,10 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) {
|
||||||
item->setProperty("polylines metadata", polylines_metadata);
|
item->setProperty("polylines metadata", polylines_metadata);
|
||||||
std::cerr << "Number of polylines in item: " << item->polylines.size() << std::endl;
|
std::cerr << "Number of polylines in item: " << item->polylines.size() << std::endl;
|
||||||
item->invalidateOpenGLBuffers();
|
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)
|
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;
|
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 =
|
const Scene_polylines_item* poly_item =
|
||||||
qobject_cast<const Scene_polylines_item*>(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;
|
out << std::endl;
|
||||||
}
|
}
|
||||||
return (bool) out;
|
bool res = (bool) out;
|
||||||
|
if(res)
|
||||||
|
items.pop_front();
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Polyhedron_demo_polylines_io_plugin::split()
|
void Polyhedron_demo_polylines_io_plugin::split()
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
#include "SMesh_type.h"
|
#include "SMesh_type.h"
|
||||||
|
|
||||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.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 <CGAL/Three/Three.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
@ -25,66 +23,60 @@
|
||||||
using namespace CGAL::Three;
|
using namespace CGAL::Three;
|
||||||
class Polyhedron_demo_stl_plugin :
|
class Polyhedron_demo_stl_plugin :
|
||||||
public QObject,
|
public QObject,
|
||||||
public Polyhedron_demo_io_plugin_interface,
|
public Polyhedron_demo_io_plugin_interface
|
||||||
public Polyhedron_demo_plugin_helper
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
Q_INTERFACES(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.90" FILE "stl_io_plugin.json")
|
||||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
|
||||||
|
|
||||||
public:
|
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 nameFilters() const;
|
||||||
QString name() const { return "stl_plugin"; }
|
QString name() const { return "stl_plugin"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo fileinfo) const;
|
||||||
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*);
|
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 {
|
QString Polyhedron_demo_stl_plugin::nameFilters() const {
|
||||||
return "STL files (*.stl)";
|
return "STL files (*.stl)";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Polyhedron_demo_stl_plugin::canLoad() const {
|
bool Polyhedron_demo_stl_plugin::canLoad(QFileInfo) const {
|
||||||
return true;
|
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
|
// Open file
|
||||||
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios::in | std::ios::binary);
|
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios::in | std::ios::binary);
|
||||||
if(!in) {
|
if(!in) {
|
||||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
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)
|
if(fileinfo.size() == 0)
|
||||||
{
|
{
|
||||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||||
Scene_surface_mesh_item* item = new Scene_surface_mesh_item();
|
Scene_surface_mesh_item* item = new Scene_surface_mesh_item();
|
||||||
item->setName(fileinfo.completeBaseName());
|
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<double, 3> > points;
|
||||||
std::vector<std::array<int, 3> > triangles;
|
std::vector<std::array<int, 3> > triangles;
|
||||||
if (!CGAL::read_STL(in, points, triangles))
|
if (!CGAL::read_STL(in, points, triangles))
|
||||||
{
|
{
|
||||||
std::cerr << "Error: invalid STL file" << std::endl;
|
std::cerr << "Error: invalid STL file" << std::endl;
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
@ -98,7 +90,10 @@ Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) {
|
||||||
else{
|
else{
|
||||||
Scene_surface_mesh_item* item = new Scene_surface_mesh_item(SM);
|
Scene_surface_mesh_item* item = new Scene_surface_mesh_item(SM);
|
||||||
item->setName(fileinfo.completeBaseName());
|
item->setName(fileinfo.completeBaseName());
|
||||||
return item;
|
ok = true;
|
||||||
|
if(add_to_scene)
|
||||||
|
CGAL::Three::Three::scene()->addItem(item);
|
||||||
|
return QList<Scene_item*>()<<item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(...){}
|
catch(...){}
|
||||||
|
|
@ -106,7 +101,10 @@ Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) {
|
||||||
Scene_polygon_soup_item* item = new Scene_polygon_soup_item();
|
Scene_polygon_soup_item* item = new Scene_polygon_soup_item();
|
||||||
item->setName(fileinfo.completeBaseName());
|
item->setName(fileinfo.completeBaseName());
|
||||||
item->load(points, triangles);
|
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)
|
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);
|
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 =
|
const Scene_surface_mesh_item* sm_item =
|
||||||
qobject_cast<const Scene_surface_mesh_item*>(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)
|
if (sm_item)
|
||||||
{
|
{
|
||||||
CGAL::write_STL(*sm_item->face_graph(), out);
|
CGAL::write_STL(*sm_item->face_graph(), out);
|
||||||
|
items.pop_front();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.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/Scene_group_item.h>
|
#include <CGAL/Three/Scene_group_item.h>
|
||||||
#include <CGAL/Three/Three.h>
|
#include <CGAL/Three/Three.h>
|
||||||
|
|
||||||
|
|
@ -20,41 +18,44 @@
|
||||||
using namespace CGAL::Three;
|
using namespace CGAL::Three;
|
||||||
class Surf_io_plugin:
|
class Surf_io_plugin:
|
||||||
public QObject,
|
public QObject,
|
||||||
public Polyhedron_demo_io_plugin_interface,
|
public Polyhedron_demo_io_plugin_interface
|
||||||
public Polyhedron_demo_plugin_helper
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
Q_INTERFACES(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.90" FILE "surf_io_plugin.json")
|
||||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
|
||||||
|
|
||||||
public:
|
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 name() const { return "surf_io_plugin"; }
|
||||||
QString nameFilters() const { return "Amira files (*.surf)"; }
|
QString nameFilters() const { return "Amira files (*.surf)"; }
|
||||||
bool canLoad() const{ return true; }
|
bool canLoad(QFileInfo) const{ return true; }
|
||||||
template<class FaceGraphItem>
|
template<class FaceGraphItem>
|
||||||
CGAL::Three::Scene_item* actual_load(QFileInfo fileinfo);
|
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 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>
|
template< class FaceGraphItem>
|
||||||
CGAL::Three::Scene_item* Surf_io_plugin::actual_load(QFileInfo fileinfo)
|
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]);
|
FaceGraphItem *patch = new FaceGraphItem(patches[i]);
|
||||||
patch->setName(QString("Patch #%1").arg(i));
|
patch->setName(QString("Patch #%1").arg(i));
|
||||||
patch->setColor(colors_[i]);
|
patch->setColor(colors_[i]);
|
||||||
scene->addItem(patch);
|
CGAL::Three::Three::scene()->addItem(patch);
|
||||||
scene->changeGroup(patch, group);
|
CGAL::Three::Three::scene()->changeGroup(patch, group);
|
||||||
}
|
}
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ class Polyhedron_demo_vtk_plugin :
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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:
|
public:
|
||||||
typedef boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
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();
|
std::string extension = fileinfo.suffix().toLower().toStdString();
|
||||||
if ( extension != "vtk" && extension != "vtp" && extension != "vtu")
|
if ( extension != "vtk" && extension != "vtp" && extension != "vtu")
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -356,10 +357,11 @@ public:
|
||||||
|
|
||||||
CGAL::output_to_vtu(os, c3t3);
|
CGAL::output_to_vtu(os, c3t3);
|
||||||
}
|
}
|
||||||
|
items.pop_front();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool canLoad() const { return true; }
|
bool canLoad(QFileInfo) const { return true; }
|
||||||
|
|
||||||
template <class vtkReader>
|
template <class vtkReader>
|
||||||
vtkSmartPointer<vtkReader>
|
vtkSmartPointer<vtkReader>
|
||||||
|
|
@ -374,11 +376,14 @@ public:
|
||||||
return reader;
|
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();
|
std::string extension=fileinfo.suffix().toLower().toStdString();
|
||||||
if (extension != "vtk" && extension != "vtp" && extension != "vtu")
|
if (extension != "vtk" && extension != "vtp" && extension != "vtu")
|
||||||
return 0;
|
{
|
||||||
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
|
}
|
||||||
|
|
||||||
std::string fname = fileinfo.absoluteFilePath().toStdString();
|
std::string fname = fileinfo.absoluteFilePath().toStdString();
|
||||||
|
|
||||||
|
|
@ -389,7 +394,10 @@ public:
|
||||||
Scene_facegraph_item* item =
|
Scene_facegraph_item* item =
|
||||||
new Scene_facegraph_item();
|
new Scene_facegraph_item();
|
||||||
item->setName(fileinfo.completeBaseName());
|
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;
|
vtkSmartPointer<vtkPointSet> data;
|
||||||
|
|
@ -421,7 +429,8 @@ public:
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
if (obs->GetWarning())
|
if (obs->GetWarning())
|
||||||
{
|
{
|
||||||
|
|
@ -442,7 +451,8 @@ public:
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
if (obs->GetWarning())
|
if (obs->GetWarning())
|
||||||
{
|
{
|
||||||
|
|
@ -491,7 +501,10 @@ public:
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
poly_item->setName(fileinfo.baseName());
|
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{
|
else{
|
||||||
c3t3_item->setName(fileinfo.baseName());
|
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{
|
else{
|
||||||
polyline_item->setName(fileinfo.baseName());
|
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)
|
if(group){
|
||||||
return group;
|
ok = true;
|
||||||
|
if(add_to_scene)
|
||||||
|
CGAL::Three::Three::scene()->addItem(group);
|
||||||
|
return QList<Scene_item*>()<<group;
|
||||||
|
}
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
QMessageBox::warning(CGAL::Three::Three::mainWindow(),
|
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->point_set()->insert(Point_3(p[0], p[1], p[2]));
|
||||||
}
|
}
|
||||||
point_item->setName(fileinfo.baseName());
|
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
|
}; // end Polyhedron_demo_vtk_plugin
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,32 +15,34 @@ class Polyhedron_demo_xyz_plugin :
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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:
|
public:
|
||||||
|
|
||||||
QString name() const { return "xyz_plugin"; }
|
QString name() const { return "xyz_plugin"; }
|
||||||
QString nameFilters() const { return "XYZ as Point Set (*.xyz);;Point Set with Normal (*.pwn)"; }
|
QString nameFilters() const { return "XYZ as Point Set (*.xyz);;Point Set with Normal (*.pwn)"; }
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo) const;
|
||||||
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*);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CGAL::Three::Scene_item*
|
QList<Scene_item*>
|
||||||
Polyhedron_demo_xyz_plugin::load(QFileInfo fileinfo)
|
Polyhedron_demo_xyz_plugin::
|
||||||
|
load(QFileInfo fileinfo, bool& ok, bool add_to_scene)
|
||||||
{
|
{
|
||||||
// Open file
|
// Open file
|
||||||
std::ifstream in(fileinfo.filePath().toUtf8().data());
|
std::ifstream in(fileinfo.filePath().toUtf8().data());
|
||||||
if(!in) {
|
if(!in) {
|
||||||
std::cerr << "Error! Cannot open file " << fileinfo.filePath().toStdString() << std::endl;
|
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 =
|
Scene_points_with_normal_item* item =
|
||||||
new Scene_points_with_normal_item();
|
new Scene_points_with_normal_item();
|
||||||
item->setName(fileinfo.completeBaseName());
|
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
|
// Read .xyz in a point set
|
||||||
Scene_points_with_normal_item* point_set_item = new Scene_points_with_normal_item;
|
Scene_points_with_normal_item* point_set_item = new Scene_points_with_normal_item;
|
||||||
point_set_item->setName(fileinfo.completeBaseName());
|
point_set_item->setName(fileinfo.completeBaseName());
|
||||||
if(!point_set_item->read_xyz_point_set(in)) {
|
if(!point_set_item->read_xyz_point_set(in)) {
|
||||||
delete point_set_item;
|
delete point_set_item;
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
if(point_set_item->has_normals())
|
if(point_set_item->has_normals())
|
||||||
point_set_item->setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode());
|
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)
|
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);
|
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)
|
// Check extension (quietly)
|
||||||
std::string extension = fileinfo.suffix().toUtf8().data();
|
std::string extension = fileinfo.suffix().toUtf8().data();
|
||||||
if (extension != "xyz" && extension != "XYZ" &&
|
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
|
// Save point set as .xyz
|
||||||
std::ofstream out(fileinfo.filePath().toUtf8().data());
|
std::ofstream out(fileinfo.filePath().toUtf8().data());
|
||||||
out.precision (std::numeric_limits<double>::digits10 + 2);
|
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"
|
#include "XYZ_io_plugin.moc"
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ class LCC_io_plugin :
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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:
|
public:
|
||||||
bool isDefaultLoader(const CGAL::Three::Scene_item *item) const
|
bool isDefaultLoader(const CGAL::Three::Scene_item *item) const
|
||||||
|
|
@ -33,13 +33,14 @@ public:
|
||||||
"3-map files (*.3map)";
|
"3-map files (*.3map)";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool canLoad() const { return true; }
|
bool canLoad(QFileInfo) const { return true; }
|
||||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo){
|
QList<CGAL::Three::Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true){
|
||||||
// Open file
|
// Open file
|
||||||
std::ifstream ifs(fileinfo.filePath().toUtf8());
|
std::ifstream ifs(fileinfo.filePath().toUtf8());
|
||||||
if(!ifs) {
|
if(!ifs) {
|
||||||
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
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;
|
Scene_lcc_item::LCC lcc;
|
||||||
|
|
@ -53,17 +54,21 @@ public:
|
||||||
}
|
}
|
||||||
if(!res)
|
if(!res)
|
||||||
{
|
{
|
||||||
return nullptr;
|
ok = false;
|
||||||
|
return QList<CGAL::Three::Scene_item*>();
|
||||||
}
|
}
|
||||||
Scene_lcc_item* new_item = new Scene_lcc_item(lcc);
|
Scene_lcc_item* new_item = new Scene_lcc_item(lcc);
|
||||||
new_item->setName(fileinfo.fileName());
|
new_item->setName(fileinfo.fileName());
|
||||||
new_item->invalidateOpenGLBuffers();
|
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 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
#include "Scene_c3t3_item.h"
|
#include "Scene_c3t3_item.h"
|
||||||
#include <CGAL/Mesh_3/tet_soup_to_c3t3.h>
|
#include <CGAL/Mesh_3/tet_soup_to_c3t3.h>
|
||||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.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/Three/Three.h>
|
||||||
#include <CGAL/IO/File_avizo.h>
|
#include <CGAL/IO/File_avizo.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
@ -12,59 +11,63 @@
|
||||||
|
|
||||||
class Polyhedron_demo_c3t3_binary_io_plugin :
|
class Polyhedron_demo_c3t3_binary_io_plugin :
|
||||||
public QObject,
|
public QObject,
|
||||||
public CGAL::Three::Polyhedron_demo_io_plugin_interface,
|
public CGAL::Three::Polyhedron_demo_io_plugin_interface
|
||||||
public CGAL::Three::Polyhedron_demo_plugin_interface
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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.90" FILE "c3t3_io_plugin.json")
|
||||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "c3t3_io_plugin.json")
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init(QMainWindow*, CGAL::Three::Scene_interface* sc, Messages_interface*)
|
|
||||||
{
|
|
||||||
this->scene = sc;
|
|
||||||
}
|
|
||||||
QString name() const { return "C3t3_io_plugin"; }
|
QString name() const { return "C3t3_io_plugin"; }
|
||||||
QString nameFilters() const { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma)"; }
|
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 saveNameFilters() const { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma);;avizo (*.am);;OFF files (*.off)"; }
|
||||||
QString loadNameFilters() const { return "binary files (*.cgal);;ascii (*.mesh)"; }
|
QString loadNameFilters() const { return "binary files (*.cgal);;ascii (*.mesh)"; }
|
||||||
QList<QAction*> actions() const
|
bool canLoad(QFileInfo) const;
|
||||||
{
|
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
|
||||||
return QList<QAction*>();
|
|
||||||
}
|
|
||||||
bool applicable(QAction*) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool canLoad() const;
|
|
||||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
|
||||||
|
|
||||||
bool canSave(const CGAL::Three::Scene_item*);
|
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:
|
private:
|
||||||
bool try_load_other_binary_format(std::istream& in, C3t3& c3t3);
|
bool try_load_other_binary_format(std::istream& in, C3t3& c3t3);
|
||||||
bool try_load_a_cdt_3(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 {
|
bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad(QFileInfo fi) const {
|
||||||
return true;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<Scene_item*>
|
||||||
CGAL::Three::Scene_item*
|
Polyhedron_demo_c3t3_binary_io_plugin::load(
|
||||||
Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
|
ok = true;
|
||||||
std::ifstream in(fileinfo.filePath().toUtf8(),
|
std::ifstream in(fileinfo.filePath().toUtf8(),
|
||||||
std::ios_base::in|std::ios_base::binary);
|
std::ios_base::in|std::ios_base::binary);
|
||||||
if(!in) {
|
if(!in) {
|
||||||
std::cerr << "Error! Cannot open file "
|
std::cerr << "Error! Cannot open file "
|
||||||
<< (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
<< (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
Scene_c3t3_item* item = new Scene_c3t3_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."));
|
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||||
item->setName(fileinfo.completeBaseName());
|
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")
|
if(fileinfo.suffix().toLower() == "cgal")
|
||||||
{
|
{
|
||||||
|
|
@ -80,7 +85,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
||||||
|
|
||||||
|
|
||||||
if(item->load_binary(in)) {
|
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();
|
item->c3t3().clear();
|
||||||
|
|
@ -89,7 +96,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
||||||
item->c3t3_changed();
|
item->c3t3_changed();
|
||||||
item->changed();
|
item->changed();
|
||||||
item->resetCutPlane();
|
item->resetCutPlane();
|
||||||
return item;
|
if(add_to_scene)
|
||||||
|
CGAL::Three::Three::scene()->addItem(item);
|
||||||
|
return QList<Scene_item*>()<< item;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->c3t3().clear();
|
item->c3t3().clear();
|
||||||
|
|
@ -98,7 +107,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
||||||
item->c3t3_changed();
|
item->c3t3_changed();
|
||||||
item->changed();
|
item->changed();
|
||||||
item->resetCutPlane();
|
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")
|
else if (fileinfo.suffix().toLower() == "mesh")
|
||||||
|
|
@ -154,7 +165,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
|
||||||
|
|
||||||
item->c3t3_changed();
|
item->c3t3_changed();
|
||||||
item->resetCutPlane();
|
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)
|
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...
|
// if all loading failed...
|
||||||
delete item;
|
delete item;
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Polyhedron_demo_c3t3_binary_io_plugin::canSave(const CGAL::Three::Scene_item* 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
|
bool
|
||||||
Polyhedron_demo_c3t3_binary_io_plugin::
|
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);
|
Scene_item* item = items.front();
|
||||||
if ( NULL == c3t3_item )
|
const Scene_c3t3_item* c3t3_item = qobject_cast<const Scene_c3t3_item*>(item);
|
||||||
{
|
if ( NULL == c3t3_item )
|
||||||
return false;
|
{
|
||||||
}
|
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::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);
|
bool ok = out && c3t3_item->save_binary(out);
|
||||||
}
|
if(!ok)
|
||||||
|
return false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
else
|
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 {
|
struct Fake_mesh_domain {
|
||||||
|
|
|
||||||
|
|
@ -207,16 +207,16 @@ class Io_image_plugin :
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_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:
|
public:
|
||||||
|
|
||||||
bool applicable(QAction*) const {
|
bool applicable(QAction*) const override{
|
||||||
return qobject_cast<Scene_image_item*>(scene->item(scene->mainSelectionIndex()));
|
return qobject_cast<Scene_image_item*>(scene->item(scene->mainSelectionIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using Polyhedron_demo_io_plugin_interface::init;
|
||||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface *mi) {
|
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface *mi) override {
|
||||||
this->message_interface = mi;
|
this->message_interface = mi;
|
||||||
this->scene = scene_interface;
|
this->scene = scene_interface;
|
||||||
this->mw = mainWindow;
|
this->mw = mainWindow;
|
||||||
|
|
@ -270,10 +270,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QList<QAction*> actions() const {
|
QList<QAction*> actions() const override{
|
||||||
return QList<QAction*>() << planeSwitch;
|
return QList<QAction*>() << planeSwitch;
|
||||||
}
|
}
|
||||||
virtual void closure()
|
virtual void closure() override
|
||||||
{
|
{
|
||||||
QDockWidget* controlDockWidget = mw->findChild<QDockWidget*>("volumePlanesControl");
|
QDockWidget* controlDockWidget = mw->findChild<QDockWidget*>("volumePlanesControl");
|
||||||
if(controlDockWidget)
|
if(controlDockWidget)
|
||||||
|
|
@ -281,18 +281,21 @@ public:
|
||||||
}
|
}
|
||||||
Io_image_plugin() : planeSwitch(NULL) {}
|
Io_image_plugin() : planeSwitch(NULL) {}
|
||||||
|
|
||||||
QString nameFilters() const;
|
QString nameFilters() const override;
|
||||||
bool canLoad() const;
|
bool canLoad(QFileInfo) const override;
|
||||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
|
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override;
|
||||||
|
|
||||||
bool canSave(const CGAL::Three::Scene_item*);
|
bool canSave(const CGAL::Three::Scene_item*) override;
|
||||||
bool save(const CGAL::Three::Scene_item* item, QFileInfo fi) {
|
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);
|
const Scene_image_item* im_item = qobject_cast<const Scene_image_item*>(item);
|
||||||
|
|
||||||
point_image p_im = *im_item->image()->image();
|
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:
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -987,8 +990,11 @@ void convert(Image* image)
|
||||||
image->image()->wdim = 4;
|
image->image()->wdim = 4;
|
||||||
image->image()->wordKind = WK_FLOAT;
|
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();
|
QApplication::restoreOverrideCursor();
|
||||||
Image* image = new Image;
|
Image* image = new Image;
|
||||||
if(fileinfo.suffix() != "H" && fileinfo.suffix() != "HH" &&
|
if(fileinfo.suffix() != "H" && fileinfo.suffix() != "HH" &&
|
||||||
|
|
@ -1075,8 +1081,9 @@ Io_image_plugin::load(QFileInfo fileinfo) {
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
if(!success){
|
if(!success){
|
||||||
|
ok = false;
|
||||||
delete image;
|
delete image;
|
||||||
return NULL;
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//read a sep file
|
//read a sep file
|
||||||
|
|
@ -1117,7 +1124,8 @@ Io_image_plugin::load(QFileInfo fileinfo) {
|
||||||
if(return_code != QDialog::Accepted)
|
if(return_code != QDialog::Accepted)
|
||||||
{
|
{
|
||||||
delete image;
|
delete image;
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get selected precision
|
// Get selected precision
|
||||||
|
|
@ -1145,7 +1153,9 @@ Io_image_plugin::load(QFileInfo fileinfo) {
|
||||||
else
|
else
|
||||||
image_item = new Scene_image_item(image,voxel_scale, false);
|
image_item = new Scene_image_item(image,voxel_scale, false);
|
||||||
image_item->setName(fileinfo.baseName());
|
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)
|
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>
|
template<typename T>
|
||||||
bool Volume_plane<T>::eventFilter(QObject *sender, QEvent *event)
|
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)
|
if(!viewer)
|
||||||
return false;
|
return false;
|
||||||
if(event->type() == QEvent::MouseButtonPress)
|
if(event->type() == QEvent::MouseButtonPress)
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,12 @@ class Polyhedron_demo_selection_plugin :
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface)
|
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.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:
|
public:
|
||||||
QString nameFilters() const { return "Selection files(*.selection.txt)"; }
|
QString nameFilters() const override { return "Selection files(*.selection.txt)"; }
|
||||||
QString name() const { return "selection_sm_plugin"; }
|
QString name() const override { return "selection_sm_plugin"; }
|
||||||
|
|
||||||
bool canLoad() const {
|
bool canLoad(QFileInfo) const override {
|
||||||
Scene_item * item = CGAL::Three::Three::scene()->item(
|
Scene_item * item = CGAL::Three::Three::scene()->item(
|
||||||
CGAL::Three::Three::scene()->mainSelectionIndex());
|
CGAL::Three::Three::scene()->mainSelectionIndex());
|
||||||
Scene_facegraph_item* fg_item = qobject_cast<Scene_facegraph_item*>(item);
|
Scene_facegraph_item* fg_item = qobject_cast<Scene_facegraph_item*>(item);
|
||||||
|
|
@ -91,36 +91,48 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::Three::Scene_item* load(QFileInfo fileinfo) {
|
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override {
|
||||||
if(fileinfo.suffix().toLower() != "txt") return 0;
|
if(fileinfo.suffix().toLower() != "txt")
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
|
}
|
||||||
// There will be no actual loading at this step.
|
// There will be no actual loading at this step.
|
||||||
Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item();
|
Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item();
|
||||||
if(!item->load(fileinfo.filePath().toStdString())) {
|
if(!item->load(fileinfo.filePath().toStdString())) {
|
||||||
delete item;
|
delete item;
|
||||||
return NULL;
|
ok = false;
|
||||||
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
item->setName(fileinfo.baseName());
|
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);
|
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);
|
const Scene_polyhedron_selection_item* item = qobject_cast<const Scene_polyhedron_selection_item*>(scene_item);
|
||||||
if(item == NULL) { return false; }
|
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()))
|
return qobject_cast<Scene_face_graph_item*>(scene->item(scene->mainSelectionIndex()))
|
||||||
|| qobject_cast<Scene_polyhedron_selection_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); }
|
void print_message(QString message) { CGAL::Three::Three::information(message); }
|
||||||
QList<QAction*> actions() const { return QList<QAction*>() << actionSelection; }
|
QList<QAction*> actions() const override { return QList<QAction*>() << actionSelection; }
|
||||||
|
using Polyhedron_demo_io_plugin_interface::init;
|
||||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) {
|
virtual void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override{
|
||||||
mw = mainWindow;
|
mw = mainWindow;
|
||||||
scene = scene_interface;
|
scene = scene_interface;
|
||||||
messages = m;
|
messages = m;
|
||||||
|
|
@ -204,7 +216,7 @@ public:
|
||||||
operations_map[operations_strings[8]] = 8;
|
operations_map[operations_strings[8]] = 8;
|
||||||
operations_map[operations_strings[9]] = 9;
|
operations_map[operations_strings[9]] = 9;
|
||||||
}
|
}
|
||||||
virtual void closure()
|
virtual void closure() override
|
||||||
{
|
{
|
||||||
dock_widget->hide();
|
dock_widget->hide();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class Polyhedron_demo_features_detection_plugin :
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
|
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;
|
QAction* actionDetectFeatures;
|
||||||
public:
|
public:
|
||||||
QList<QAction*> actions() const { return QList<QAction*>() << actionDetectFeatures; }
|
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->setName("Intersection tetrahedra");
|
||||||
d->intersection->setRenderingMode(renderingMode());
|
d->intersection->setRenderingMode(renderingMode());
|
||||||
connect(d->intersection, SIGNAL(destroyed()), this, SLOT(reset_intersection_item()));
|
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())
|
BOOST_FOREACH(auto v, CGAL::QGLViewer::QGLViewerPool())
|
||||||
{
|
{
|
||||||
CGAL::Three::Viewer_interface* viewer = static_cast<CGAL::Three::Viewer_interface*>(v);
|
CGAL::Three::Viewer_interface* viewer = static_cast<CGAL::Three::Viewer_interface*>(v);
|
||||||
d->are_intersection_buffers_filled[viewer] = false;
|
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)
|
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();
|
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];
|
GLfloat normal[3];
|
||||||
normal[0] = CGAL::to_double(v.x());
|
normal[0] = CGAL::to_double(v.x());
|
||||||
normal[1] = CGAL::to_double(v.y());
|
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->are_temp_buffers_filled = false;
|
||||||
d->poly = NULL;
|
d->poly = NULL;
|
||||||
d->ready_to_move = false;
|
d->ready_to_move = false;
|
||||||
|
do_process = true;
|
||||||
setProperty("no_picking", true);
|
setProperty("no_picking", true);
|
||||||
|
|
||||||
setPointContainer(3,
|
setPointContainer(3,
|
||||||
|
|
|
||||||
|
|
@ -879,8 +879,13 @@ protected:
|
||||||
if(gen_event->type() == QEvent::Wheel)
|
if(gen_event->type() == QEvent::Wheel)
|
||||||
{
|
{
|
||||||
QWheelEvent *event = static_cast<QWheelEvent*>(gen_event);
|
QWheelEvent *event = static_cast<QWheelEvent*>(gen_event);
|
||||||
int steps = event->delta() / 120;
|
int steps = event->angleDelta().y()/120;
|
||||||
expand_or_reduce(steps);
|
if(do_process)
|
||||||
|
{
|
||||||
|
expand_or_reduce(steps);
|
||||||
|
do_process = false;
|
||||||
|
QTimer::singleShot(0,this, [this](){do_process = true;});
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -997,6 +1002,7 @@ protected:
|
||||||
Scene_facegraph_item_k_ring_selection k_ring_selector;
|
Scene_facegraph_item_k_ring_selection k_ring_selector;
|
||||||
// action state
|
// action state
|
||||||
bool is_insert;
|
bool is_insert;
|
||||||
|
bool do_process;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// selection
|
// selection
|
||||||
|
|
|
||||||
|
|
@ -621,11 +621,23 @@ void Viewer::keyPressEvent(QKeyEvent* e)
|
||||||
}
|
}
|
||||||
else if(e->key() == Qt::Key_M) {
|
else if(e->key() == Qt::Key_M) {
|
||||||
d->macro_mode = ! d->macro_mode;
|
d->macro_mode = ! d->macro_mode;
|
||||||
|
switch(camera()->type()){
|
||||||
if(d->macro_mode) {
|
case CGAL::qglviewer::Camera::PERSPECTIVE:
|
||||||
|
if(d->macro_mode) {
|
||||||
camera()->setZNearCoefficient(0.0005f);
|
camera()->setZNearCoefficient(0.0005f);
|
||||||
} else {
|
} else {
|
||||||
camera()->setZNearCoefficient(0.005f);
|
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").
|
this->displayMessage(tr("Macro mode: %1").
|
||||||
arg(d->macro_mode ? tr("on") : tr("off")));
|
arg(d->macro_mode ? tr("on") : tr("off")));
|
||||||
|
|
@ -1351,19 +1363,39 @@ QOpenGLShaderProgram* Viewer::getShaderProgram(int name) const
|
||||||
|
|
||||||
void Viewer::wheelEvent(QWheelEvent* e)
|
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();
|
switch(camera()->type())
|
||||||
if(delta>0)
|
{
|
||||||
{
|
case CGAL::qglviewer::Camera::ORTHOGRAPHIC:
|
||||||
camera()->setZNearCoefficient(camera()->zNearCoefficient() * 1.01);
|
camera()->setOrthoZNear(camera()->orthoZNear() + 0.01);
|
||||||
}
|
break;
|
||||||
else
|
case CGAL::qglviewer::Camera::PERSPECTIVE:
|
||||||
camera()->setZNearCoefficient(camera()->zNearCoefficient() / 1.01);
|
camera()->setZNearCoefficient(camera()->zNearCoefficient() * 1.01);
|
||||||
update();
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
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)
|
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)
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
|
||||||
find_package(CGAL QUIET)
|
find_package(CGAL QUIET)
|
||||||
|
|
||||||
if ( CGAL_FOUND )
|
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
|
# create a target per cppfile
|
||||||
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||||
foreach(cppfile ${cppfiles})
|
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()
|
endforeach()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
@ -22,3 +36,4 @@ else()
|
||||||
|
|
||||||
endif()
|
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 <QFileInfo>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
|
class QMainWindow;
|
||||||
|
class Messages_interface;
|
||||||
namespace CGAL{
|
namespace CGAL{
|
||||||
namespace Three {
|
namespace Three {
|
||||||
class Scene_item;
|
class Scene_item;
|
||||||
|
class Scene_interface;
|
||||||
/*!
|
/*!
|
||||||
* This class provides a base for creating a new IO plugin.
|
* This class provides a base for creating a new IO plugin.
|
||||||
*/
|
*/
|
||||||
class Polyhedron_demo_io_plugin_interface
|
class Polyhedron_demo_io_plugin_interface
|
||||||
{
|
{
|
||||||
public:
|
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
|
//!Returns the name of the plugin
|
||||||
//!It is used by the loading system.
|
//!It is used by the loading system.
|
||||||
virtual QString name() const = 0;
|
virtual QString name() const = 0;
|
||||||
|
|
@ -58,17 +65,23 @@ public:
|
||||||
|
|
||||||
//! Specifies if the io_plugin is able to load an item or not.
|
//! Specifies if the io_plugin is able to load an item or not.
|
||||||
//! This must be overriden.
|
//! This must be overriden.
|
||||||
virtual bool canLoad() const = 0;
|
virtual bool canLoad(QFileInfo fileinfo) const = 0;
|
||||||
//! Loads an item from a file.
|
//! 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.
|
//! 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.
|
//!Specifies if the io_plugin can save the item or not.
|
||||||
//!This must be overriden.
|
//!This must be overriden.
|
||||||
virtual bool canSave(const Scene_item*) = 0;
|
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.
|
//!contained in fileinfo. Returns false if error.
|
||||||
//! This must be overriden.
|
//! 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
|
//! 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
|
//! 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,
|
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
|
#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)
|
: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);
|
QFontMetrics fm(m_font);
|
||||||
_width = float(fm.width(m_text));
|
_width = float(fm.width(m_text)+2);
|
||||||
_height = float(fm.height());
|
_height = float(fm.height());
|
||||||
}
|
}
|
||||||
//!\brief Accessor for the string
|
//!\brief Accessor for the string
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue