diff --git a/CGoGN/include/Algo/Modelisation/subdivision.hpp b/CGoGN/include/Algo/Modelisation/subdivision.hpp index 3b39031836a3b95a28601645b45190343b36ce00..7554a09c1948b2f979872d39d21221eba65dada2 100644 --- a/CGoGN/include/Algo/Modelisation/subdivision.hpp +++ b/CGoGN/include/Algo/Modelisation/subdivision.hpp @@ -442,7 +442,7 @@ void CatmullClarkInterpolSubdivision(typename PFP::MAP& map, EMBV& attributs) typedef typename PFP::MAP MAP; typedef typename EMBV::DATA_TYPE EMB; - VertexAutoAttribute facesAverage(map); + VertexAutoAttribute facesAverage(map); std::vector l_vertices; std::vector l_edges; diff --git a/SCHNApps/Plugins/surface_subdivision/forms/dialog_surface_subdivision.ui b/SCHNApps/Plugins/surface_subdivision/forms/dialog_surface_subdivision.ui index 292db6d811751142c599e33f10e9a2837c7e3370..90d448f89c50ba4aafde78a013e0300bf21d2c8d 100644 --- a/SCHNApps/Plugins/surface_subdivision/forms/dialog_surface_subdivision.ui +++ b/SCHNApps/Plugins/surface_subdivision/forms/dialog_surface_subdivision.ui @@ -6,25 +6,18 @@ 0 0 - 327 - 230 + 282 + 334 Subdivide surface - + - - - - Position attribute : - - - - + @@ -34,45 +27,66 @@ - - + + - Loop + Triangule - - + + - Catmull-Clark + Loop - - + + - Triangule faces + Quadrangule - - + + - Cancel + Position attribute : - + Apply - + - OK + Close + + + + + + + Do-Sabin + + + + + + + Catmull-Clark + + + + + + + Interp diff --git a/SCHNApps/Plugins/surface_subdivision/include/surface_subdivision.h b/SCHNApps/Plugins/surface_subdivision/include/surface_subdivision.h index 1696710ae44da7ad607d53e1fafdd90c9b3d69fe..760b5335802ed3a5889b8f1a5d31d62fe389da0e 100644 --- a/SCHNApps/Plugins/surface_subdivision/include/surface_subdivision.h +++ b/SCHNApps/Plugins/surface_subdivision/include/surface_subdivision.h @@ -36,16 +36,24 @@ private slots: public slots: void loopSubdivision( const QString& mapName, - const QString& positionAttributeName = "position" - ); + const QString& positionAttributeName = "position"); + void CCSubdivision( const QString& mapName, - const QString& positionAttributeName = "position" - ); + const QString& positionAttributeName = "position", + bool interp = false ); + + void DoSabinSubdivision( + const QString& mapName, + const QString& positionAttributeName = "position"); + void trianguleFaces( const QString& mapName, - const QString& positionAttributeName = "position" - ); + const QString& positionAttributeName = "position"); + + void quadranguleFaces( + const QString& mapName, + const QString& positionAttributeName = "position"); private: Dialog_Surface_Subdivision* m_subdivisionDialog; diff --git a/SCHNApps/Plugins/surface_subdivision/src/surface_subdivision.cpp b/SCHNApps/Plugins/surface_subdivision/src/surface_subdivision.cpp index 27898d71867dee3e0d82cd63cb8b98b1aea96a82..c441949df4847884b3980528eb53e25c587a39fa 100644 --- a/SCHNApps/Plugins/surface_subdivision/src/surface_subdivision.cpp +++ b/SCHNApps/Plugins/surface_subdivision/src/surface_subdivision.cpp @@ -26,6 +26,7 @@ bool Surface_Subdivision_Plugin::enable() connect(m_subdivisionDialog, SIGNAL(accepted()), this, SLOT(subdivideFromDialog())); connect(m_subdivisionDialog->button_apply, SIGNAL(clicked()), this, SLOT(subdivideFromDialog())); + connect(m_subdivisionDialog->button_ok, SIGNAL(clicked()), this, SLOT(schnappsClosing())); connect(m_schnapps, SIGNAL(schnappsClosing()), this, SLOT(schnappsClosing())); return true; @@ -56,10 +57,20 @@ void Surface_Subdivision_Plugin::subdivideFromDialog() if(m_subdivisionDialog->radio_Loop->isChecked()) loopSubdivision(mapName, positionName); - else if(m_subdivisionDialog->radio_CC->isChecked()) - CCSubdivision(mapName, positionName); + else if (m_subdivisionDialog->radio_CC->isChecked()) + { + if (m_subdivisionDialog->check_interp->isChecked()) + CCSubdivision(mapName, positionName, true); + else + CCSubdivision(mapName, positionName, false); + } + else if (m_subdivisionDialog->radio_DoSabin->isChecked()) + DoSabinSubdivision(mapName, positionName); else if(m_subdivisionDialog->radio_trianguleFaces->isChecked()) trianguleFaces(mapName, positionName); + else if (m_subdivisionDialog->radio_quadranguleFaces->isChecked()) + quadranguleFaces(mapName, positionName); + } } @@ -89,7 +100,7 @@ void Surface_Subdivision_Plugin::loopSubdivision( void Surface_Subdivision_Plugin::CCSubdivision( const QString& mapName, - const QString& positionAttributeName) + const QString& positionAttributeName, bool interp) { MapHandler* mh = static_cast*>(m_schnapps->getMap(mapName)); if(mh == NULL) @@ -99,10 +110,38 @@ void Surface_Subdivision_Plugin::CCSubdivision( if(!position.isValid()) return; - pythonRecording("CCSubdivision", "", mapName, positionAttributeName); + pythonRecording("CCSubdivision", "", mapName, positionAttributeName,interp); + + PFP2::MAP* map = mh->getMap(); + if (interp) + Algo::Surface::Modelisation::CatmullClarkInterpolSubdivision(*map, position); + else + Algo::Surface::Modelisation::CatmullClarkSubdivision(*map, position); + + mh->notifyAttributeModification(position); + mh->notifyConnectivityModification(); + + foreach(View* view, mh->getLinkedViews()) + view->updateGL(); +} + + +void Surface_Subdivision_Plugin::DoSabinSubdivision( + const QString& mapName, + const QString& positionAttributeName) +{ + MapHandler* mh = static_cast*>(m_schnapps->getMap(mapName)); + if (mh == NULL) + return; + + VertexAttribute position = mh->getAttribute(positionAttributeName); + if (!position.isValid()) + return; + + pythonRecording("DoSabinSubdivision", "", mapName, positionAttributeName); PFP2::MAP* map = mh->getMap(); - Algo::Surface::Modelisation::CatmullClarkSubdivision(*map, position); + Algo::Surface::Modelisation::DooSabin(*map, position); mh->notifyAttributeModification(position); mh->notifyConnectivityModification(); @@ -111,6 +150,7 @@ void Surface_Subdivision_Plugin::CCSubdivision( view->updateGL(); } + void Surface_Subdivision_Plugin::trianguleFaces( const QString& mapName, const QString& positionAttributeName) @@ -135,6 +175,32 @@ void Surface_Subdivision_Plugin::trianguleFaces( view->updateGL(); } +void Surface_Subdivision_Plugin::quadranguleFaces( + const QString& mapName, + const QString& positionAttributeName) +{ + MapHandler* mh = static_cast*>(m_schnapps->getMap(mapName)); + if (mh == NULL) + return; + + VertexAttribute position = mh->getAttribute(positionAttributeName); + if (!position.isValid()) + return; + + pythonRecording("quadranguleFaces", "", mapName, positionAttributeName); + + PFP2::MAP* map = mh->getMap(); + Algo::Surface::Modelisation::quadranguleFaces(*map, position); + + mh->notifyAttributeModification(position); + mh->notifyConnectivityModification(); + + foreach(View* view, mh->getLinkedViews()) + view->updateGL(); +} + + + void Surface_Subdivision_Plugin::schnappsClosing() { m_subdivisionDialog->close(); diff --git a/SCHNApps/forms/controlDock_MapTabWidget.ui b/SCHNApps/forms/controlDock_MapTabWidget.ui index bf48ec7c8f4a7d215d63439a0c74ec21359e5932..617a0cdbf0adad30d174d62df0d70da7e835545f 100644 --- a/SCHNApps/forms/controlDock_MapTabWidget.ui +++ b/SCHNApps/forms/controlDock_MapTabWidget.ui @@ -44,6 +44,16 @@ + + + + + + + true + + + @@ -63,6 +73,24 @@ + + + + + + remove + + + + + + + duplicate + + + + + diff --git a/SCHNApps/include/controlDock_mapTab.h b/SCHNApps/include/controlDock_mapTab.h index 488f132526b2e905a8c21b05e5aed31c153a7002..004bf4b2238e02b4d3a7c57a63d29d9c76cee550 100644 --- a/SCHNApps/include/controlDock_mapTab.h +++ b/SCHNApps/include/controlDock_mapTab.h @@ -40,6 +40,10 @@ private slots: // slots called from UI actions void selectedMapChanged(); + void duplicateCurrentMap(); + void removeCurrentMap(); + + void showBBChanged(bool b); void bbVertexAttributeChanged(int index); void vertexAttributeCheckStateChanged(QListWidgetItem* item); diff --git a/SCHNApps/include/mapHandler.h b/SCHNApps/include/mapHandler.h index 03e4695c0e6c5c148b81a9fdeecf650548ee93ce..b5e870a9b23c33135f6992c8dd9c0db4a0dfc9f0 100644 --- a/SCHNApps/include/mapHandler.h +++ b/SCHNApps/include/mapHandler.h @@ -82,6 +82,19 @@ private slots: *********************************************************/ public slots: + + void showBB(bool b) + { + m_showBB = b; + foreach(View* view, l_views) + view->updateGL(); + } + + bool isBBshown() const + { + return m_showBB; + } + void setBBVertexAttribute(const QString& name) { m_bbVertexAttribute = m_map->getAttributeVectorGen(VERTEX, name.toStdString()); @@ -118,6 +131,7 @@ public slots: virtual bool transformedBB(qglviewer::Vec& bbMin, qglviewer::Vec& bbMax) = 0; protected: + bool m_showBB; virtual void updateBB() = 0; /********************************************************* diff --git a/SCHNApps/include/mapHandler.hpp b/SCHNApps/include/mapHandler.hpp index fab72b93a876d974b0c97fe61e3f8c7cf38e81b3..989d6378093bb1778bbf607ed707c9e4bfd6ccb4 100644 --- a/SCHNApps/include/mapHandler.hpp +++ b/SCHNApps/include/mapHandler.hpp @@ -87,7 +87,7 @@ void MapHandler::draw(Utils::GLSLShader* shader, int primitive) template void MapHandler::drawBB() { - if (m_bbDrawer) + if (m_showBB && m_bbDrawer) m_bbDrawer->callList(); } diff --git a/SCHNApps/include/schnapps.h b/SCHNApps/include/schnapps.h index b7a91d3e78604c4e9871f071da3aa2ee2392d779..712916f73040b6a3cd000d0a23c8224f1c435427 100644 --- a/SCHNApps/include/schnapps.h +++ b/SCHNApps/include/schnapps.h @@ -99,6 +99,9 @@ private slots: public slots: MapHandlerGen* addMap(const QString& name, unsigned int dim); void removeMap(const QString& name); + MapHandlerGen* duplicateMap(const QString& name, bool properties); + + void setSelectedMap(const QString& mapName); MapHandlerGen* getMap(const QString& name) const; diff --git a/SCHNApps/src/controlDock_mapTab.cpp b/SCHNApps/src/controlDock_mapTab.cpp index 2c72ae15da002968901f39221a97b0e576cf2c18..2e00048daaba017c94dfe5de317c2a1d25f6f538 100644 --- a/SCHNApps/src/controlDock_mapTab.cpp +++ b/SCHNApps/src/controlDock_mapTab.cpp @@ -21,6 +21,10 @@ ControlDock_MapTab::ControlDock_MapTab(SCHNApps* s) : connect(list_maps, SIGNAL(itemSelectionChanged()), this, SLOT(selectedMapChanged())); + connect(button_duplicate, SIGNAL(clicked()), this, SLOT(duplicateCurrentMap())); + connect(button_remove, SIGNAL(clicked()), this, SLOT(removeCurrentMap())); + + connect(check_drawBB, SIGNAL(toggled(bool)), this, SLOT(showBBChanged(bool))); connect(combo_bbVertexAttribute, SIGNAL(currentIndexChanged(int)), this, SLOT(bbVertexAttributeChanged(int))); connect(list_vertexAttributes, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(vertexAttributeCheckStateChanged(QListWidgetItem*))); @@ -79,6 +83,7 @@ void ControlDock_MapTab::setSelectedMap(const QString& mapName) items[0]->setSelected(false); m_selectedMap = NULL; } + updateSelectedMapInfo(); return; } @@ -133,6 +138,57 @@ void ControlDock_MapTab::selectedMapChanged() } } +void ControlDock_MapTab::showBBChanged(bool b) +{ + if (!b_updatingUI) + { + + if (m_selectedMap) + { + m_selectedMap->showBB(b); + // RECORDING + QTextStream* rec = m_schnapps->pythonStreamRecorder(); + if (rec) + *rec << m_selectedMap->getName() << ".showBB(\"" << b << "\");" << endl; + } + + } +} + + +void ControlDock_MapTab::duplicateCurrentMap() +{ + if (!b_updatingUI) + { + if (m_selectedMap) + { + m_schnapps->duplicateMap(m_selectedMap->getName(),true); + // RECORDING + QTextStream* rec = m_schnapps->pythonStreamRecorder(); + if (rec) + *rec << "schnapps.duplicateMap(" << m_selectedMap->getName() << ".getName(),1);" << endl; + } + } +} + +void ControlDock_MapTab::removeCurrentMap() +{ + if (!b_updatingUI) + { + if (m_selectedMap) + { + m_schnapps->removeMap(m_selectedMap->getName()); + // RECORDING + QTextStream* rec = m_schnapps->pythonStreamRecorder(); + if (rec) + *rec << "schnapps.removeMap(" << m_selectedMap->getName() << ".getName());" << endl; + setSelectedMap("NONE"); + } + } +} + + + void ControlDock_MapTab::bbVertexAttributeChanged(int index) { if (!b_updatingUI) @@ -319,6 +375,8 @@ void ControlDock_MapTab::updateSelectedMapInfo() for (unsigned int orbit = DART; orbit <= VOLUME; ++orbit) { + check_drawBB->setChecked(m_selectedMap->isBBshown()); + unsigned int nbc = m->getNbCells(orbit); QListWidget* selectorList = NULL; diff --git a/SCHNApps/src/mapHandler.cpp b/SCHNApps/src/mapHandler.cpp index 7423d4691132db60f62496825c439fd088cbc9de..50fdf2add894ee4fff532218de5d7527954f90b4 100644 --- a/SCHNApps/src/mapHandler.cpp +++ b/SCHNApps/src/mapHandler.cpp @@ -7,6 +7,7 @@ namespace SCHNApps { MapHandlerGen::MapHandlerGen(const QString& name, SCHNApps* s, GenericMap* map) : + m_showBB(true), m_name(name), m_schnapps(s), m_map(map), diff --git a/SCHNApps/src/schnapps.cpp b/SCHNApps/src/schnapps.cpp index 74e57c5081a5bbcd28289e992f2b15107e6a3d71..786740c437d495c134794d5bd25431d15de1489d 100644 --- a/SCHNApps/src/schnapps.cpp +++ b/SCHNApps/src/schnapps.cpp @@ -543,6 +543,60 @@ void SCHNApps::disablePluginTabWidgets(PluginInteraction* plugin) * MANAGE MAPS *********************************************************/ +MapHandlerGen* SCHNApps::duplicateMap(const QString& name, bool properties) +{ + if (! m_maps.contains(name)) + return NULL; + + QString newName = name + "_copy"; + + if (m_maps.contains(newName)) + return NULL; + + MapHandlerGen* maph = m_maps[name]; + MapHandlerGen* new_mh; + + unsigned int dim = maph->getGenericMap()->dimension(); + + switch (dim) + { + case 2: { + PFP2::MAP* map = new PFP2::MAP(); + map->copyFrom(*(maph->getGenericMap())); + new_mh = new MapHandler(newName, this, map); + break; + } + case 3: { + PFP3::MAP* map = new PFP3::MAP(); + map->copyFrom(*(maph->getGenericMap())); + new_mh = new MapHandler(newName, this, map); + break; + } + } + + m_maps.insert(newName, new_mh); + DEBUG_EMIT("mapAdded"); + emit(mapAdded(new_mh)); + + if (properties) + { + // BB + new_mh->setBBVertexAttribute(maph->getBBVertexAttributeName()); + + //VBOs + const VBOSet& vbos = maph->getVBOSet(); + foreach(QString s, vbos.keys()) + { + new_mh->createVBO(s); + } + } + + return new_mh; +} + + + + MapHandlerGen* SCHNApps::addMap(const QString& name, unsigned int dim) { if (m_maps.contains(name))