diff --git a/Apps/Examples/simpleMap3.cpp b/Apps/Examples/simpleMap3.cpp index 0b3652d6ab52332b0b40c6810257decbcdd5e2fd..9eb6d3f68303e93decc85f809555bf4163e998a7 100644 --- a/Apps/Examples/simpleMap3.cpp +++ b/Apps/Examples/simpleMap3.cpp @@ -91,7 +91,7 @@ void SimpleMap3::cb_redraw() { glDisable(GL_LIGHTING); glLineWidth(1.0f); - Algo::Render::GL1::renderTopoMD3(myMap, position, true, true, true, 0.9f, 0.9f, 0.9f); + Algo::Render::GL1::renderTopoMD3(myMap, position, true, true, true, 0.9f, 0.9f, 0.9f,allDarts); } /********************************************************************************************** diff --git a/Apps/Examples/simpleMap3.h b/Apps/Examples/simpleMap3.h index c4a8f8d98eb7fde7f75967bda5c21f0856794340..1d3389b5663fbc897d6c186e00c964a0eeeffd28 100644 --- a/Apps/Examples/simpleMap3.h +++ b/Apps/Examples/simpleMap3.h @@ -17,7 +17,7 @@ * along with this library; if not, write to the Free Software Foundation, * * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * -* Web site: http://cgogn.unistra.fr/ * +* Web site: http://cgogn.unistra.fr/ * * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ @@ -26,6 +26,7 @@ #include "Utils/Qt/qtSimple.h" +#include "Topology/generic/functor.h" #include "Topology/generic/parameters.h" #include "Topology/map/embeddedMap3.h" diff --git a/Apps/Tuto/tuto_dual2.cpp b/Apps/Tuto/tuto_dual2.cpp index 1ded7488f16be2a8b1d9e4b71f34a89ce1c572f0..480080154e8855f2bce37f1351b507ddc11b1852 100644 --- a/Apps/Tuto/tuto_dual2.cpp +++ b/Apps/Tuto/tuto_dual2.cpp @@ -31,7 +31,6 @@ #include "Algo/Import/import.h" #include "Algo/Export/export.h" -#include #include "Algo/Modelisation/subdivision.h" @@ -66,7 +65,6 @@ int main(int argc, char **argv) // get a handler to the 3D vector attribute created by the import VertexAttribute position = myMap.getAttribute(attrNames[0]); - FaceAttribute positionF = myMap.getAttribute("position") ; if(!positionF.isValid()) positionF = myMap.addAttribute("position") ; diff --git a/SCHNApps/Plugins/CMakeLists.txt b/SCHNApps/Plugins/CMakeLists.txt index 512bc2e23f9fb81b339e88325a04cd1c4878a580..c196b91abfeb084cb3d074be35eff222fa84620c 100644 --- a/SCHNApps/Plugins/CMakeLists.txt +++ b/SCHNApps/Plugins/CMakeLists.txt @@ -5,4 +5,5 @@ ADD_SUBDIRECTORY(importVolume) ADD_SUBDIRECTORY(differentialProperties) ADD_SUBDIRECTORY(render) ADD_SUBDIRECTORY(renderVector) +ADD_SUBDIRECTORY(renderExplod) ADD_SUBDIRECTORY(subdivideSurface) diff --git a/SCHNApps/Plugins/renderExplod/CMakeLists.txt b/SCHNApps/Plugins/renderExplod/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3ec46aecf86bb8e0385669899f269cdec6330027 --- /dev/null +++ b/SCHNApps/Plugins/renderExplod/CMakeLists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 2.8) + +INCLUDE_DIRECTORIES( + ${SCHNApps_ROOT_DIR}/include + ${SCHNApps_ROOT_DIR}/Plugins/renderExplod + ${CMAKE_CURRENT_BINARY_DIR} +) + +SET( PLUGIN_SRC + ${SCHNApps_ROOT_DIR}/Plugins/renderExplod/renderExplod.cpp +) + +SET( PLUGIN_H + ${SCHNApps_ROOT_DIR}/Plugins/renderExplod/renderExplod.h +) + +SET( PLUGIN_FORM + ${SCHNApps_ROOT_DIR}/Plugins/renderExplod/renderExplod.ui +) + +IF( ${CMAKE_BUILD_TYPE} STREQUAL Debug ) + + ADD_DEFINITIONS(-DDEBUG) + + IF(WIN32) + link_directories( ${CGoGN_ROOT_DIR}/lib/Release ) + ELSE (WIN32) + link_directories( ${CGoGN_ROOT_DIR}/lib/Debug ${CGoGN_ROOT_DIR}/lib/Release ) + ENDIF (WIN32) + + QT4_WRAP_UI( PLUGIN_UI ${PLUGIN_FORM} ) + QT4_WRAP_CPP( PLUGIN_MOC ${PLUGIN_H} ) + + ADD_LIBRARY( RenderExplodPluginD SHARED + ${PLUGIN_SRC} + ${PLUGIN_UI} + ${PLUGIN_MOC} + ) + + TARGET_LINK_LIBRARIES( RenderExplodPluginD + ${CGoGN_LIBS_D} + ${COMMON_LIBS} + ${QGLVIEWER_LIBRARIES} + ) + + ADD_DEPENDENCIES( RenderExplodPluginD SCHNAppsD ) + + SET_TARGET_PROPERTIES( RenderExplodPluginD PROPERTIES COMPILE_DEFINITIONS "DEBUG" ) + +ELSE ( ${CMAKE_BUILD_TYPE} STREQUAL Debug ) + + IF(WIN32) + link_directories( ${CGoGN_ROOT_DIR}/lib/Release ) + ELSE (WIN32) + link_directories( ${CGoGN_ROOT_DIR}/lib/Release ) + ENDIF (WIN32) + + QT4_WRAP_UI( PLUGIN_UI ${PLUGIN_FORM} ) + QT4_WRAP_CPP( PLUGIN_MOC ${PLUGIN_H} ) + + ADD_LIBRARY( RenderExplodPlugin SHARED + ${PLUGIN_SRC} + ${PLUGIN_UI} + ${PLUGIN_MOC} + ) + + TARGET_LINK_LIBRARIES( RenderExplodPlugin + ${CGoGN_LIBS_R} + ${COMMON_LIBS} + ${QGLVIEWER_LIBRARIES} + ) + + ADD_DEPENDENCIES( RenderExplodPlugin SCHNApps ) + +ENDIF ( ${CMAKE_BUILD_TYPE} STREQUAL Debug ) diff --git a/SCHNApps/Plugins/renderExplod/renderExplod.cpp b/SCHNApps/Plugins/renderExplod/renderExplod.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a5f22bac7106da2f3318ce348b392002e1ee0df3 --- /dev/null +++ b/SCHNApps/Plugins/renderExplod/renderExplod.cpp @@ -0,0 +1,327 @@ +#include "renderExplod.h" + +#include "mapHandler.h" + +#include "Algo/Import/import.h" + + +PerMapParameterSet::PerMapParameterSet(MapHandlerGen* map) : + positionVBO(NULL), + colorVBO(NULL), + facesScaleFactor(1.0f), + volumesScaleFactor(1.0f), + renderEdges(false), + renderFaces(true) +{ + QList vbos = map->getVBOList(); + for(int i = 0; i < vbos.count(); ++i) + { + if(vbos[i]->name() == "position") // try to select a VBO named "position" + positionVBO = vbos[i]; + if(vbos[i]->name() == "color") // try to select a VBO named "color" + colorVBO = vbos[i]; + } + + if(positionVBO == NULL && vbos.count() > 0) + positionVBO = vbos[0]; + if(colorVBO == NULL && vbos.count() > 0) + colorVBO = vbos[0]; +} + + +bool RenderExplodPlugin::enable() +{ + m_dockTab = new RenderExplodDockTab(this); + addTabInDock(m_dockTab, "RenderExplod"); + +// m_renderExplod = new Algo::Render::GL2::ExplodeVolumeRender(true); +// +// m_renderExplod->setNoClippingPlane(); +// m_renderExplod->setExplodeVolumes(0.9f); +// m_renderExplod->setExplodeFaces(1.0f); +// +// //m_renderExplod->setAmbiant(Geom::Vec4f(0.1f,0.1f,0.1f,0.0f)); +// //m_renderExplod->setBackColor(Geom::Vec4f(0.1f,1.0f,0.1f,0.0f)); +// //m_renderExplod->setColorLine(Geom::Vec4f(0.1f,0.1f,0.1f,0.0f)); +// //m_renderExplod->setAmbiant(Geom::Vec4f(0.9f, 0.5f, 0.0f, 0.0f)); +// m_renderExplod->setBackColor(Geom::Vec4f(0.9f, 0.5f, 0.0f, 0.0f)); +// //m_renderExplod->setColorLine(Geom::Vec4f(0.9f, 0.5f, 0.0f, 0.0f)); +// m_renderExplod->setColorLine(Geom::Vec4f(0.0f, 0.0f, 0.0f, 0.0f)); +// +// registerShader(m_renderExplod->shaderFaces()); +// registerShader(m_renderExplod->shaderLines()); + + connect(m_dockTab->mapList, SIGNAL(itemSelectionChanged()), this, SLOT(cb_selectedMapChanged())); + connect(m_dockTab->combo_positionVBO, SIGNAL(currentIndexChanged(int)), this, SLOT(cb_positionVBOChanged(int))); + connect(m_dockTab->combo_colorVBO, SIGNAL(currentIndexChanged(int)), this, SLOT(cb_colorVBOChanged(int))); + connect(m_dockTab->button_refreshVBOs, SIGNAL(clicked()), this, SLOT(cb_refreshVBOs())); + connect(m_dockTab->check_renderEdges, SIGNAL(toggled(bool)), this, SLOT(cb_renderEdgesChanged(bool))); + connect(m_dockTab->check_renderFaces, SIGNAL(toggled(bool)), this, SLOT(cb_renderFacesChanged(bool))); + connect(m_dockTab->slider_facesScaleFactor, SIGNAL(valueChanged(int)), this, SLOT(cb_facesScaleFactorChanged(int))); + connect(m_dockTab->slider_volumesScaleFactor, SIGNAL(valueChanged(int)), this, SLOT(cb_volumesScaleFactorChanged(int))); + + return true; +} + +void RenderExplodPlugin::disable() +{ + +} + +void RenderExplodPlugin::redraw(View* view) +{ + ParameterSet* params = h_viewParams[view]; + + const QList& maps = view->getLinkedMaps(); + foreach(MapHandlerGen* m, maps) + { + const PerMapParameterSet& p = params->perMap[m->getName()]; + if(p.positionVBO != NULL) + { + if(p.renderEdges) + { +// m_renderExplod->drawEdges(); + } + if(p.renderFaces) + { +// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +// glEnable(GL_LIGHTING); +// glEnable(GL_POLYGON_OFFSET_FILL); +// glPolygonOffset(1.0f, 1.0f) ; +// m_renderExplod->drawFaces(); +// glDisable(GL_POLYGON_OFFSET_FILL); + } + } + } +} + +void RenderExplodPlugin::viewLinked(View* view) +{ + ParameterSet* params = new ParameterSet(); + h_viewParams.insert(view, params); + const QList& maps = view->getLinkedMaps(); + foreach(MapHandlerGen* map, maps) + { + PerMapParameterSet p(map); + params->perMap.insert(map->getName(), p); + } + if (!maps.empty()) + params->selectedMap = maps[0]; + + m_dockTab->refreshUI(params); +} + +void RenderExplodPlugin::viewUnlinked(View* view) +{ + h_viewParams.remove(view); + + View* current = m_window->getCurrentView(); + if(isLinkedToView(current)) + m_dockTab->refreshUI(h_viewParams[current]); +} + +void RenderExplodPlugin::currentViewChanged(View* view) +{ + assert(isLinkedToView(view)); + m_dockTab->refreshUI(h_viewParams[view]); +} + +void RenderExplodPlugin::mapLinked(View* view, MapHandlerGen* m) +{ + assert(isLinkedToView(view)); + ParameterSet* params = h_viewParams[view]; + PerMapParameterSet p(m); + params->perMap.insert(m->getName(), p); + if(params->perMap.count() == 1) + params->selectedMap = m; + + m_dockTab->refreshUI(params); +} + +void RenderExplodPlugin::mapUnlinked(View* view, MapHandlerGen* m) +{ + assert(isLinkedToView(view)); + ParameterSet* params = h_viewParams[view]; + params->perMap.remove(m->getName()); + + if(params->selectedMap == m) + { + if(!params->perMap.empty()) + params->selectedMap = m_window->getMap(params->perMap.begin().key()); + else + params->selectedMap = NULL; + m_dockTab->refreshUI(params); + } +} + +void RenderExplodPlugin::cb_selectedMapChanged() +{ + if(!b_refreshingUI) + { + View* view = m_window->getCurrentView(); + ParameterSet* params = h_viewParams[view]; + QList currentItems = m_dockTab->mapList->selectedItems(); + if(!currentItems.empty()) + { + const QString& mapname = currentItems[0]->text(); + params->selectedMap = m_window->getMap(mapname); + m_dockTab->refreshUI(params); + view->updateGL(); + } + } +} + +void RenderExplodPlugin::cb_positionVBOChanged(int index) +{ + if(!b_refreshingUI) + { + View* current = m_window->getCurrentView(); + ParameterSet* params = h_viewParams[current]; + MapHandlerGen* map = params->selectedMap; + params->perMap[map->getName()].positionVBO = map->getVBO(m_dockTab->combo_positionVBO->currentText()); + current->updateGL(); + } +} + +void RenderExplodPlugin::cb_colorVBOChanged(int index) +{ + if(!b_refreshingUI) + { + + } +} + +void RenderExplodPlugin::cb_refreshVBOs() +{ + View* current = m_window->getCurrentView(); + if(isLinkedToView(current)) + m_dockTab->refreshUI(h_viewParams[current]); +} + +void RenderExplodPlugin::cb_renderEdgesChanged(bool b) +{ + if(!b_refreshingUI) + { + View* current = m_window->getCurrentView(); + ParameterSet* params = h_viewParams[current]; + MapHandlerGen* m = params->selectedMap; + params->perMap[m->getName()].renderEdges = b; + current->updateGL(); + } +} + +void RenderExplodPlugin::cb_renderFacesChanged(bool b) +{ + if(!b_refreshingUI) + { + View* current = m_window->getCurrentView(); + ParameterSet* params = h_viewParams[current]; + MapHandlerGen* m = params->selectedMap; + params->perMap[m->getName()].renderFaces = b; + current->updateGL(); + } +} + +void RenderExplodPlugin::cb_facesScaleFactorChanged(int i) +{ + if(!b_refreshingUI) + { + View* current = m_window->getCurrentView(); + ParameterSet* params = h_viewParams[current]; + MapHandlerGen* m = params->selectedMap; + params->perMap[m->getName()].facesScaleFactor = i / 50.0; + current->updateGL(); + } +} + +void RenderExplodPlugin::cb_volumesScaleFactorChanged(int i) +{ + if(!b_refreshingUI) + { + View* current = m_window->getCurrentView(); + ParameterSet* params = h_viewParams[current]; + MapHandlerGen* m = params->selectedMap; + params->perMap[m->getName()].volumesScaleFactor = i / 50.0; + current->updateGL(); + } +} + + +void RenderExplodDockTab::refreshUI(ParameterSet* params) +{ + plugin->setRefreshingUI(true); + + mapList->clear(); + combo_positionVBO->clear(); + combo_colorVBO->clear(); + + MapHandlerGen* map = params->selectedMap; + + QHash::const_iterator i = params->perMap.constBegin(); + while (i != params->perMap.constEnd()) + { + mapList->addItem(i.key()); + if(map != NULL && i.key() == map->getName()) + { + QList item = mapList->findItems(map->getName(), Qt::MatchExactly); + item[0]->setSelected(true); + + PerMapParameterSet& p = params->perMap[map->getName()]; +// +// QList vbos = map->getVBOList(); +// for(int i = 0; i < vbos.count(); ++i) +// { +// combo_positionVBO->addItem(QString::fromStdString(vbos[i]->name())); +// if(p.positionVBO == NULL) +// { // if nothing is specified in the parameter set +// if(vbos[i]->name() == "position") // try to select a VBO named "position" +// { +// p.positionVBO = vbos[i]; +// combo_positionVBO->setCurrentIndex(i); +// } +// } +// else if(vbos[i] == p.positionVBO) +// combo_positionVBO->setCurrentIndex(i); +// +// combo_normalVBO->addItem(QString::fromStdString(vbos[i]->name())); +// if(p.normalVBO == NULL) +// { // if nothing is specified in the parameter set +// if(vbos[i]->name() == "normal") // try to select a VBO named "normal" +// { +// p.normalVBO = vbos[i]; +// combo_normalVBO->setCurrentIndex(i); +// } +// } +// else if(vbos[i] == p.normalVBO) +// combo_normalVBO->setCurrentIndex(i); +// } +// +// if(p.positionVBO == NULL && vbos.count() > 0) +// { +// p.positionVBO = vbos[0]; +// combo_positionVBO->setCurrentIndex(0); +// } +// if(p.normalVBO == NULL && vbos.count() > 0) +// { +// p.normalVBO = vbos[0]; +// combo_normalVBO->setCurrentIndex(0); +// } + + check_renderEdges->setChecked(p.renderEdges); + check_renderFaces->setChecked(p.renderFaces); + slider_facesScaleFactor->setSliderPosition(p.facesScaleFactor * 50.0); + slider_volumesScaleFactor->setSliderPosition(p.volumesScaleFactor * 50.0); + } + ++i; + } + + plugin->setRefreshingUI(false); +} + + + +#ifndef DEBUG +Q_EXPORT_PLUGIN2(RenderExplodPlugin, RenderExplodPlugin) +#else +Q_EXPORT_PLUGIN2(RenderExplodPluginD, RenderExplodPlugin) +#endif diff --git a/SCHNApps/Plugins/renderExplod/renderExplod.h b/SCHNApps/Plugins/renderExplod/renderExplod.h new file mode 100644 index 0000000000000000000000000000000000000000..f35451bbc168db51050e608eac04636bd9b6f336 --- /dev/null +++ b/SCHNApps/Plugins/renderExplod/renderExplod.h @@ -0,0 +1,113 @@ +#ifndef _RENDER_PLUGIN_H_ +#define _RENDER_PLUGIN_H_ + +#include "plugin.h" +#include "ui_renderExplod.h" + +#include "Algo/Render/GL2/explodeVolumeRender.h" + +using namespace CGoGN; +using namespace SCHNApps; + + +struct PerMapParameterSet +{ + PerMapParameterSet() : + positionVBO(NULL), + colorVBO(NULL), + facesScaleFactor(1.0f), + volumesScaleFactor(1.0f), + renderEdges(false), + renderFaces(true) + {} + + PerMapParameterSet(MapHandlerGen* map); + + Utils::VBO* positionVBO; + Utils::VBO* colorVBO; + float facesScaleFactor; + float volumesScaleFactor; + bool renderEdges; + bool renderFaces; +}; + +struct ParameterSet +{ + ParameterSet() : selectedMap(NULL) + {} + + QHash perMap; + MapHandlerGen* selectedMap; +}; + + +class RenderExplodPlugin; + +class RenderExplodDockTab : public QWidget, public Ui::RenderExplodWidget +{ +public: + RenderExplodDockTab(RenderExplodPlugin* p) : plugin(p) + { + setupUi(this); + } + + void refreshUI(ParameterSet* params); + +private: + RenderExplodPlugin* plugin; +}; + + +class RenderExplodPlugin : public Plugin +{ + Q_OBJECT + Q_INTERFACES(CGoGN::SCHNApps::Plugin) + +public: + RenderExplodPlugin() : b_refreshingUI(false) + { + setProvidesRendering(true); + } + + ~RenderExplodPlugin() + {} + + virtual bool enable(); + virtual void disable(); + + virtual void redraw(View *view); + + virtual void keyPress(View* view, int key) {} + virtual void keyRelease(View* view, int key) {} + virtual void mousePress(View* view, int button, int x, int y) {} + virtual void mouseRelease(View* view, int button, int x, int y) {} + virtual void mouseMove(View* view, int buttons, int x, int y) {} + virtual void wheelEvent(View* view, int delta, int x, int y) {} + + virtual void viewLinked(View* view); + virtual void viewUnlinked(View* view); + virtual void currentViewChanged(View* view); + + virtual void mapLinked(View* view, MapHandlerGen* m); + virtual void mapUnlinked(View* view, MapHandlerGen* m); + + void setRefreshingUI(bool b) { b_refreshingUI = b; } + +protected: + RenderExplodDockTab* m_dockTab; + QHash h_viewParams; + + bool b_refreshingUI; + +public slots: + void cb_selectedMapChanged(); + void cb_positionVBOChanged(int index); + void cb_colorVBOChanged(int index); + void cb_refreshVBOs(); + void cb_renderEdgesChanged(bool b); + void cb_renderFacesChanged(bool b); + void cb_facesScaleFactorChanged(int i); + void cb_volumesScaleFactorChanged(int i); +}; + +#endif diff --git a/SCHNApps/Plugins/renderExplod/renderExplod.ui b/SCHNApps/Plugins/renderExplod/renderExplod.ui new file mode 100644 index 0000000000000000000000000000000000000000..4464dab69612bde5b1bd37591cffa89785427f5b --- /dev/null +++ b/SCHNApps/Plugins/renderExplod/renderExplod.ui @@ -0,0 +1,163 @@ + + + RenderExplodWidget + + + + 0 + 0 + 174 + 553 + + + + Form + + + + + + + + + QLayout::SetDefaultConstraint + + + + + Position : + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + Refresh + + + + + + + cColor : + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Horizontal + + + + + + + render edges + + + + + + + render faces + + + true + + + + + + + + + Explod + + + + + + + faces : + + + + + + + 50 + + + Qt::Horizontal + + + + + + + volumes : + + + + + + + 50 + + + Qt::Horizontal + + + + + + + + + Qt::Vertical + + + + 156 + 161 + + + + + + + + + diff --git a/include/Algo/Geometry/inclusion.hpp b/include/Algo/Geometry/inclusion.hpp index d7ca1315d7e0a8492cd28f93d014b79cc5788744..e6d79a61be053d6524ed420fb43192b7d1d7ad87 100644 --- a/include/Algo/Geometry/inclusion.hpp +++ b/include/Algo/Geometry/inclusion.hpp @@ -307,7 +307,7 @@ bool isConvexFaceInOrIntersectingTetrahedron(typename PFP::MAP& map, Dart d, con } // namespace Geometry -} +} // namespace Surface } // namspace Algo diff --git a/include/Algo/Geometry/normal.h b/include/Algo/Geometry/normal.h index bda90a06e01fcd345422796f1f896d5fa480fe27..8f267c9b64be7286f1992ca0bc315c8a3069477c 100644 --- a/include/Algo/Geometry/normal.h +++ b/include/Algo/Geometry/normal.h @@ -92,7 +92,7 @@ void computeAnglesBetweenNormalsOnEdges(typename PFP::MAP& map, const VertexAttr } // namespace Geometry -} +} // namespace Surface } // namespace Algo diff --git a/include/Algo/Geometry/orientation.h b/include/Algo/Geometry/orientation.h index d432fe6308106635e5f2ecc1d5a6ba36609765da..b473740193b85d8d5bc1a1f0772f617b99ce3edf 100644 --- a/include/Algo/Geometry/orientation.h +++ b/include/Algo/Geometry/orientation.h @@ -34,6 +34,9 @@ namespace CGoGN namespace Algo { +namespace Surface +{ + namespace Geometry { @@ -53,6 +56,8 @@ bool isTetrahedronWellOriented(typename PFP::MAP& map, Dart d, const VertexAttri } // namespace Geometry +} // namespace Surface + } // namespace Algo } // namespace CGoGN diff --git a/include/Algo/Geometry/plane.h b/include/Algo/Geometry/plane.h index 99908e74077c0a7c6bf1a2d97e00f8c39a5b9a9c..dc683b41200965546eae93c6527ebc5389d6e4c2 100644 --- a/include/Algo/Geometry/plane.h +++ b/include/Algo/Geometry/plane.h @@ -35,6 +35,9 @@ namespace CGoGN namespace Algo { +namespace Surface +{ + namespace Geometry { @@ -61,6 +64,8 @@ Geom::Plane3D vertexTangentPlane(typename PFP::MAP& map, Dar } // namespace Geometry +} // namespace Surface + } // namespace Algo } // namespace CGoGN diff --git a/include/Algo/Modelisation/polyhedron.hpp b/include/Algo/Modelisation/polyhedron.hpp index d245595bf03ba127d20a6670410ef7ab65d3e558..2151048bde33fa9bac4b1344bb2ad548df9fe91e 100644 --- a/include/Algo/Modelisation/polyhedron.hpp +++ b/include/Algo/Modelisation/polyhedron.hpp @@ -140,10 +140,8 @@ Dart createPrism(typename PFP::MAP& map, unsigned int n, bool withBoundary) template Dart createDiamond(typename PFP::MAP& map, unsigned int nbSides, bool withBoundary) { - std::vector m_tableVertDarts; - - unsigned int nbt = 2*nbSides -1 ; // -1 for computation optimization + std::vector m_tableVertDarts; m_tableVertDarts.reserve(nbSides); @@ -166,7 +164,7 @@ Dart createDiamond(typename PFP::MAP& map, unsigned int nbSides, bool withBounda //sewing the last with the first map.sewFaces(map.phi1(m_tableVertDarts[0]), map.phi_1(m_tableVertDarts[nbSides-1]), false); - for (unsigned int i = nbSides; i <= nbt; ++i) + for (unsigned int i = nbSides; i < nbt; ++i) { Dart d = m_tableVertDarts[i]; d = map.phi_1(d); @@ -183,6 +181,9 @@ Dart createDiamond(typename PFP::MAP& map, unsigned int nbSides, bool withBounda map.sewFaces(m_tableVertDarts[i], m_tableVertDarts[nbt-i], false); } + if(map.dimension() == 3 && withBoundary) + map.closeMap(); + //return a dart from the base return m_tableVertDarts[0]; } diff --git a/include/Algo/Modelisation/subdivision.h b/include/Algo/Modelisation/subdivision.h index 78300b2808d4dc0c071a61b4d67115e0824472df..4dfff7259b220c3c31402c350502703e58329a84 100644 --- a/include/Algo/Modelisation/subdivision.h +++ b/include/Algo/Modelisation/subdivision.h @@ -115,22 +115,13 @@ void TwoNPlusOneSubdivision(typename PFP::MAP& map, EMBV& attributs, const Funct template void DooSabin(typename PFP::MAP& map, VertexAttribute& position); -///** -// * Reverse the orientation of the map -// * NOW IN THE MAP -// */ -//template -//void reverseOrientation(typename PFP::MAP& map) ; -// -///** -// * Sqrt(3) subdivision scheme +//** // */ //template //void Sqrt3Subdivision(typename PFP::MAP& map, typename PFP::TVEC3& position, const FunctorSelect& selected = allDarts) ; - } // namespace Modelisation } diff --git a/include/Algo/Modelisation/subdivision.hpp b/include/Algo/Modelisation/subdivision.hpp index b5577d79dada7c328698263a479cfc67aee6540a..2011c3af1e5f853d1efeb590d42aecc166c527ff 100644 --- a/include/Algo/Modelisation/subdivision.hpp +++ b/include/Algo/Modelisation/subdivision.hpp @@ -629,7 +629,6 @@ void DooSabin(typename PFP::MAP& map, VertexAttribute& posit } - inline double sqrt3_K(unsigned int n) { switch(n) @@ -699,6 +698,7 @@ inline double sqrt3_K(unsigned int n) // } //} + } // namespace Modelisation } diff --git a/include/Algo/Multiresolution/IHM2/ihm2_PrimalAdapt.h b/include/Algo/Multiresolution/IHM2/ihm2_PrimalAdapt.h new file mode 100644 index 0000000000000000000000000000000000000000..cf49ff9994234208242339bec24465a78d9a44d8 --- /dev/null +++ b/include/Algo/Multiresolution/IHM2/ihm2_PrimalAdapt.h @@ -0,0 +1,121 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; 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 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __MAP2MR_PRIMAL_ADAPT__ +#define __MAP2MR_PRIMAL_ADAPT__ + +#include "Topology/map/embeddedMap2.h" +#include "Topology/generic/traversorCell.h" +#include "Topology/generic/traversor2.h" + +#include + +namespace CGoGN +{ + +namespace Algo +{ + +namespace MR +{ + +namespace Primal +{ + +namespace Adaptive +{ + +template +class IHM2 +{ + +public: + typedef typename PFP::MAP MAP ; + typedef typename PFP::VEC3 VEC3 ; + typedef typename PFP::REAL REAL ; + +protected: + MAP& m_map; + bool shareVertexEmbeddings ; + + FunctorType* vertexVertexFunctor ; + FunctorType* edgeVertexFunctor ; + FunctorType* faceVertexFunctor ; + +public: + IHM2(MAP& map) ; + + +protected: + /*************************************************** + * SUBDIVISION * + ***************************************************/ + + /** + * subdivide the edge of d to the next level + */ + void subdivideEdge(Dart d) ; + + /** + * coarsen the edge of d from the next level + */ + void coarsenEdge(Dart d) ; + +public: + /** + * subdivide the face of d to the next level + */ + unsigned int subdivideFace(Dart d, bool triQuad = true, bool OneLevelDifference = true); + + /** + * + */ + unsigned int subdivideFaceSqrt3(Dart d); + + /** + * coarsen the face of d from the next level + */ + void coarsenFace(Dart d) ; + + /** + * vertices attributes management + */ + void setVertexVertexFunctor(FunctorType* f) { vertexVertexFunctor = f ; } + void setEdgeVertexFunctor(FunctorType* f) { edgeVertexFunctor = f ; } + void setFaceVertexFunctor(FunctorType* f) { faceVertexFunctor = f ; } +} ; + +} // namespace Adaptive + +} // namespace Primal + +} // namespace MR + +} // namespace Algo + +} // namespace CGoGN + +#include "Algo/Multiresolution/IHM2/ihm2_PrimalAdapt.hpp" + +#endif diff --git a/include/Algo/Multiresolution/IHM2/ihm2_PrimalAdapt.hpp b/include/Algo/Multiresolution/IHM2/ihm2_PrimalAdapt.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3b8bb8cfa3f2db3932639a4ea0cc532042f507ce --- /dev/null +++ b/include/Algo/Multiresolution/IHM2/ihm2_PrimalAdapt.hpp @@ -0,0 +1,254 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; 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 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "Algo/Multiresolution/IHM2/ihm2_PrimalAdapt.h" + +namespace CGoGN +{ + +namespace Algo +{ + +namespace MR +{ + +namespace Primal +{ + +namespace Adaptive +{ + +template +IHM2::IHM2(typename PFP::MAP& map) : + m_map(map), + shareVertexEmbeddings(true), + vertexVertexFunctor(NULL), + edgeVertexFunctor(NULL), + faceVertexFunctor(NULL) +{ + +} + + +template +void IHM2::subdivideEdge(Dart d) +{ + assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"subdivideEdge : called with a dart inserted after current level") ; + assert(!m_map.edgeIsSubdivided(d) || !"Trying to subdivide an already subdivided edge") ; + + unsigned int eLevel = m_map.edgeLevel(d) ; + + unsigned int cur = m_map.getCurrentLevel() ; + m_map.setCurrentLevel(eLevel) ; + + m_map.setCurrentLevel(eLevel + 1) ; + + Dart nd = m_map.cutEdge(d) ; + unsigned int eId = m_map.getEdgeId(d) ; + m_map.setEdgeId(nd, eId) ; + m_map.setEdgeId(m_map.phi2(d), eId) ; + (*edgeVertexFunctor)(nd) ; + + m_map.setCurrentLevel(cur) ; +} + +template +void IHM2::coarsenEdge(Dart d) +{ + assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"coarsenEdge : called with a dart inserted after current level") ; + assert(m_map.edgeCanBeCoarsened(d) || !"Trying to coarsen an edge that can not be coarsened") ; + + + unsigned int cur = m_map.getCurrentLevel() ; +// Dart e = m_map.phi2(d) ; + m_map.setCurrentLevel(cur + 1) ; +// unsigned int dl = m_map.getDartLevel(e) ; +// m_map.setDartLevel(m_map.phi1(e), dl) ; +// m_map.collapseEdge(e) ; + m_map.uncutEdge(d) ; + m_map.setCurrentLevel(cur) ; +} + +template +unsigned int IHM2::subdivideFace(Dart d, bool triQuad, bool OneLevelDifference) +{ + assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"subdivideFace : called with a dart inserted after current level") ; + assert(!m_map.faceIsSubdivided(d) || !"Trying to subdivide an already subdivided face") ; + + unsigned int fLevel = m_map.faceLevel(d) ; + Dart old = m_map.faceOldestDart(d) ; + + unsigned int cur = m_map.getCurrentLevel() ; + m_map.setCurrentLevel(fLevel) ; // go to the level of the face to subdivide its edges + + unsigned int degree = 0 ; + Dart it = old ; + do + { + ++degree ; // compute the degree of the face + + //if(OneLevelDifference) + //{ + // Dart nf = m_map.phi2(it) ; + // if(m_map.faceLevel(nf) == fLevel - 1) // check if neighboring faces have to be subdivided first + // subdivideFace(nf) ; + //} + + if(!m_map.edgeIsSubdivided(it)) + subdivideEdge(it) ; // and cut the edges (if they are not already) + it = m_map.phi1(it) ; + } while(it != old) ; + + m_map.setCurrentLevel(fLevel + 1) ; // go to the next level to perform face subdivision + + + if(triQuad && degree == 3) // if subdividing a triangle + { + Dart dd = m_map.phi1(old) ; + Dart e = m_map.phi1(dd) ; + //(*vertexVertexFunctor)(e) ; + + e = m_map.phi1(e) ; + m_map.splitFace(dd, e) ; // insert a new edge + unsigned int id = m_map.getNewEdgeId() ; + m_map.setEdgeId(m_map.phi_1(dd), id) ; // set the edge id of the inserted + m_map.setEdgeId(m_map.phi_1(e), id) ; // edge to the next available id + + dd = e ; + e = m_map.phi1(dd) ; + //(*vertexVertexFunctor)(e) ; + e = m_map.phi1(e) ; + m_map.splitFace(dd, e) ; + id = m_map.getNewEdgeId() ; + m_map.setEdgeId(m_map.phi_1(dd), id) ; + m_map.setEdgeId(m_map.phi_1(e), id) ; + + dd = e ; + e = m_map.phi1(dd) ; + //(*vertexVertexFunctor)(e) ; + e = m_map.phi1(e) ; + m_map.splitFace(dd, e) ; + id = m_map.getNewEdgeId() ; + m_map.setEdgeId(m_map.phi_1(dd), id) ; + m_map.setEdgeId(m_map.phi_1(e), id) ; + } + else // if subdividing a polygonal face + { + Dart dd = m_map.phi1(old) ; + Dart next = m_map.phi1(dd) ; + //(*vertexVertexFunctor)(next) ; + next = m_map.phi1(next) ; + m_map.splitFace(dd, next) ; // insert a first edge + Dart ne = m_map.alpha1(dd) ; + Dart ne2 = m_map.phi2(ne) ; + + m_map.cutEdge(ne) ; // cut the new edge to insert the central vertex + unsigned int id = m_map.getNewEdgeId() ; + m_map.setEdgeId(ne, id) ; + m_map.setEdgeId(m_map.phi2(ne), id) ; // set the edge id of the inserted + id = m_map.getNewEdgeId() ; + m_map.setEdgeId(ne2, id) ; // edges to the next available ids + m_map.setEdgeId(m_map.phi2(ne2), id) ; + + dd = m_map.phi1(next) ; + (*vertexVertexFunctor)(dd) ; + dd = m_map.phi1(dd) ; + while(dd != ne) // turn around the face and insert new edges + { // linked to the central vertex + m_map.splitFace(m_map.phi1(ne), dd) ; + Dart nne = m_map.alpha1(dd) ; + id = m_map.getNewEdgeId() ; + m_map.setEdgeId(nne, id) ; + m_map.setEdgeId(m_map.phi2(nne), id) ; + dd = m_map.phi1(dd) ; + //(*vertexVertexFunctor)(dd) ; + dd = m_map.phi1(dd) ; + } + + (*faceVertexFunctor)(m_map.phi1(ne)) ; + } + + + m_map.setCurrentLevel(cur) ; + + return fLevel ; +} + +template +void IHM2::coarsenFace(Dart d) +{ + assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"coarsenFace : called with a dart inserted after current level") ; + assert(m_map.faceIsSubdividedOnce(d) || !"Trying to coarsen a non-subdivided face or a more than once subdivided face") ; + + unsigned int cur = m_map.getCurrentLevel() ; + + unsigned int degree = 0 ; + Dart fit = d ; + do + { + ++degree ; + fit = m_map.phi1(fit) ; + } while(fit != d) ; + + if(degree == 3) + { + fit = d ; + do + { + m_map.setCurrentLevel(cur + 1) ; + Dart innerEdge = m_map.phi1(fit) ; + m_map.setCurrentLevel(m_map.getMaxLevel()) ; + m_map.mergeFaces(innerEdge) ; + m_map.setCurrentLevel(cur) ; + fit = m_map.phi1(fit) ; + } while(fit != d) ; + } + else + { + m_map.setCurrentLevel(cur + 1) ; + Dart centralV = m_map.phi1(m_map.phi1(d)) ; + m_map.setCurrentLevel(m_map.getMaxLevel()) ; + m_map.deleteVertex(centralV) ; + m_map.setCurrentLevel(cur) ; + } + + fit = d ; + do + { + if(m_map.edgeCanBeCoarsened(fit)) + coarsenEdge(fit) ; + fit = m_map.phi1(fit) ; + } while(fit != d) ; +} + + +} // namespace Adaptive + +} // namespace Primal + +} // namespace MR + +} // namespace Algo + +} // namespace CGoGN diff --git a/include/Algo/Multiresolution/Map3MR/Filters/bertram.h b/include/Algo/Multiresolution/Map3MR/Filters/bertram.h index 23d2d0d1c9e558d7c1d95ced66374709241732cd..8a8df1a7d9f1f879c9c99feb91de86c2ea8c48c2 100644 --- a/include/Algo/Multiresolution/Map3MR/Filters/bertram.h +++ b/include/Algo/Multiresolution/Map3MR/Filters/bertram.h @@ -181,7 +181,6 @@ public: // Dart dit = db; // do // { -// std::cout << "dit = " << dit << std::endl; // m_map.incCurrentLevel() ; // // Dart midEdgeV = m_map.phi1(dit); @@ -196,7 +195,7 @@ public: // }while(dit != db); //TODO Replace do--while with a Traversor2 on Boundary - ClosedMap::Traversor2VF travVF(m_map,db); + Traversor2VF travVF(m_map,db); for(Dart dit = travVF.begin(); dit != travVF.end() ; dit = travVF.next()) { m_map.incCurrentLevel() ; @@ -275,6 +274,7 @@ public: Dart db = m_map.findBoundaryFaceOfEdge(d); typename PFP::VEC3 fe(0.0); +// unsigned int count = 2; // m_map.incCurrentLevel() ; // Dart midV = m_map.phi1(m_map.phi1(db)); // fe += m_position[midV]; @@ -284,7 +284,7 @@ public: //TODO Replace do--while with a Traversor2 on Boundary unsigned int count = 0; - ClosedMap::Traversor2EF travEF(m_map, db); + Traversor2EF travEF(m_map, db); for(Dart dit = travEF.begin() ; dit != travEF.end() ; dit = travEF.next()) { m_map.incCurrentLevel() ; @@ -569,6 +569,7 @@ public: Dart db = m_map.findBoundaryFaceOfEdge(d); typename PFP::VEC3 fe(0.0); +// unsigned int count = 2; // m_map.incCurrentLevel() ; // Dart midV = m_map.phi1(m_map.phi1(db)); // fe += m_position[midV]; @@ -578,7 +579,7 @@ public: //TODO Replace do--while with a Traversor2 on Boundary unsigned int count = 0; - ClosedMap::Traversor2EF travEF(m_map, db); + Traversor2EF travEF(m_map, db); for(Dart dit = travEF.begin() ; dit != travEF.end() ; dit = travEF.next()) { m_map.incCurrentLevel() ; @@ -648,7 +649,6 @@ public: // Dart dit = db; // do // { -// std::cout << "dit = " << dit << std::endl; // m_map.incCurrentLevel() ; // // Dart midEdgeV = m_map.phi1(dit); @@ -662,7 +662,7 @@ public: // // }while(dit != db); - ClosedMap::Traversor2VF travVF(m_map,db); + Traversor2VF travVF(m_map,db); for(Dart dit = travVF.begin(); dit != travVF.end() ; dit = travVF.next()) { std::cout << "dit = " << dit << std::endl; diff --git a/include/Algo/Multiresolution/Map3MR/Filters/lerp.h b/include/Algo/Multiresolution/Map3MR/Filters/lerp.h index ef914bfe805c721db617ed21a1b7b5201918b218..4e93703200db035baf256f72854694f1bd8f2661 100644 --- a/include/Algo/Multiresolution/Map3MR/Filters/lerp.h +++ b/include/Algo/Multiresolution/Map3MR/Filters/lerp.h @@ -290,7 +290,7 @@ public: TraversorE trav(m_map) ; for (Dart d = trav.begin(); d != trav.end(); d = trav.next()) { - typename PFP::VEC3 p = (m_position[d] + m_position[m_map.phi2(d)]) * typename PFP::REAL(0.5); + typename PFP::VEC3 p = (m_position[d] + m_position[m_map.phi1(d)]) * typename PFP::REAL(0.5); m_map.incCurrentLevel() ; @@ -322,7 +322,7 @@ public: m_map.incCurrentLevel() ; - Dart midF = m_map.phi2(m_map.phi1(d)); + Dart midF = m_map.phi1(m_map.phi1(d)); m_position[midF] = p ; m_map.decCurrentLevel() ; @@ -353,7 +353,7 @@ public: m_map.incCurrentLevel() ; - Dart midF = m_map.phi2(m_map.phi1(d)); + Dart midF = m_map.phi1(m_map.phi1(d)); m_position[midF] = p ; m_map.decCurrentLevel() ; @@ -362,7 +362,6 @@ public: } } ; - template class LerpVolumeSynthesisFilter : public Algo::MR::Filter { @@ -374,6 +373,35 @@ public: LerpVolumeSynthesisFilter(typename PFP::MAP& m, VertexAttribute& p) : m_map(m), m_position(p) {} + void operator() () + { + TraversorW trav(m_map) ; + for (Dart d = trav.begin(); d != trav.end(); d = trav.next()) + { + typename PFP::VEC3 p = Algo::Surface::Geometry::volumeCentroid(m_map, d, m_position); + + m_map.incCurrentLevel() ; + + Dart midV = m_map.phi_1(m_map.phi2(m_map.phi1(d))); + m_position[midV] = p ; + + m_map.decCurrentLevel() ; + + } + } +} ; + +template +class LerpTriQuadVolumeSynthesisFilter : public Algo::MR::Filter +{ +protected: + typename PFP::MAP& m_map ; + VertexAttribute& m_position ; + +public: + LerpTriQuadVolumeSynthesisFilter(typename PFP::MAP& m, VertexAttribute& p) : m_map(m), m_position(p) + {} + void operator() () { TraversorW trav(m_map) ; diff --git a/include/Algo/Multiresolution/Map3MR/Filters/mcCrackenJoy.h b/include/Algo/Multiresolution/Map3MR/Filters/mcCrackenJoy.h index fb88f03d51af3f0319fb652a16f794e1296e9a00..43564e9f0a242f532da88402cb0a769921ef9a84 100644 --- a/include/Algo/Multiresolution/Map3MR/Filters/mcCrackenJoy.h +++ b/include/Algo/Multiresolution/Map3MR/Filters/mcCrackenJoy.h @@ -325,13 +325,8 @@ public: typename PFP::VEC3 p = Algo::Surface::Geometry::volumeCentroid(m_map, d, m_position); m_map.incCurrentLevel() ; - - if(!Algo::Volume::Modelisation::Tetrahedralization::isTetrahedron(m_map,d)) - { - Dart midV = m_map.phi_1(m_map.phi2(m_map.phi1(d))); - m_position[midV] = p ; - } - + Dart midV = m_map.phi_1(m_map.phi2(m_map.phi1(d))); + m_position[midV] = p ; m_map.decCurrentLevel() ; } diff --git a/include/Algo/Multiresolution/Map3MR/Masks/mcCrackenJoy.h b/include/Algo/Multiresolution/Map3MR/Masks/mcCrackenJoy.h index a21f3e748ad6b26b4b1a04ab0c70b718b414ecd8..72fc4c6f36901ac271bc3aa2a9004a6c97073d51 100644 --- a/include/Algo/Multiresolution/Map3MR/Masks/mcCrackenJoy.h +++ b/include/Algo/Multiresolution/Map3MR/Masks/mcCrackenJoy.h @@ -46,27 +46,28 @@ namespace Primal namespace Masks { -/* MJ96 basic functions : polyhedral meshes - *********************************************************************************/ + template class MJ96VertexVertexFunctor : public FunctorType { protected: typename PFP::MAP& m_map ; - AttributeHandler& m_position ; + VertexAttribute& m_position ; public: - MJ96VertexVertexFunctor(typename PFP::MAP& m, AttributeHandler& p) : m_map(m), m_position(p) + MJ96VertexVertexFunctor(typename PFP::MAP& m, VertexAttribute& p) : m_map(m), m_position(p) {} bool operator() (Dart d) { if(m_map.isBoundaryVertex(d)) { - Dart db = m_map.findBoundaryFaceOfVertex(d); + std::cout << "boundary" << std::endl; m_map.decCurrentLevel() ; + Dart db = m_map.findBoundaryFaceOfVertex(d); + typename PFP::VEC3 np1(0) ; typename PFP::VEC3 np2(0) ; unsigned int degree1 = 0 ; @@ -103,62 +104,157 @@ public: } else { + m_map.decCurrentLevel() ; + typename PFP::VEC3 P = m_position[d]; - m_map.decCurrentLevel() ; //vertex points typename PFP::VEC3 Cavg = typename PFP::VEC3(0); - unsigned int degree = 0; - Traversor3VW travVW(m_map, d); - for(Dart dit = travVW.begin() ; dit != travVW.end() ; dit = travVW.next()) - { - Cavg += Algo::Surface::Geometry::volumeCentroid(m_map, dit, m_position); - ++degree; - } + unsigned int degree = m_map.template degree(d); + Cavg = Algo::Surface::Geometry::volumeCentroid(m_map, d, m_position); Cavg /= degree; + //P /= degree; + typename PFP::VEC3 Aavg = typename PFP::VEC3(0); - degree = 0; - Traversor3VF travVF(m_map, d); - for(Dart dit = travVF.begin() ; dit != travVF.end() ; dit = travVF.next()) - { - Aavg += Algo::Surface::Geometry::faceCentroid(m_map, dit, m_position); - ++degree; - } + degree = m_map.template degree(d); + Aavg = Algo::Surface::Geometry::faceCentroid(m_map, d, m_position); Aavg /= degree; typename PFP::VEC3 Mavg = typename PFP::VEC3(0); - degree = 0; - Traversor3VE travVE(m_map, d); - for(Dart dit = travVE.begin() ; dit != travVE.end() ; dit = travVE.next()) - { - Dart d2 = m_map.phi2(dit); - Aavg += (m_position[dit] + m_position[d2]) * typename PFP::REAL(0.5); - ++degree; - } - Aavg /= degree; + degree = m_map.template degree(d); + Dart d2 = m_map.phi2(d); + Mavg = (m_position[d] + m_position[d2]) * typename PFP::REAL(0.5); + Mavg /= degree; typename PFP::VEC3 vp = Cavg + Aavg * 3 + Mavg * 3 + P; vp /= 8; m_map.incCurrentLevel() ; - m_position[d] = vp; + m_position[d] = P; // += vp; //P; } return false; } }; + + +///* MJ96 basic functions : polyhedral meshes +// *********************************************************************************/ +//template +//class MJ96VertexVertexFunctor : public FunctorType +//{ +//protected: +// typename PFP::MAP& m_map ; +// VertexAttribute& m_position ; +// +//public: +// MJ96VertexVertexFunctor(typename PFP::MAP& m, VertexAttribute& p) : m_map(m), m_position(p) +// {} +// +// bool operator() (Dart d) +// { +// if(m_map.isBoundaryVertex(d)) +// { +// m_map.decCurrentLevel() ; +// +// Dart db = m_map.findBoundaryFaceOfVertex(d); +// +// typename PFP::VEC3 np1(0) ; +// typename PFP::VEC3 np2(0) ; +// unsigned int degree1 = 0 ; +// unsigned int degree2 = 0 ; +// Dart it = db ; +// do +// { +// ++degree1 ; +// Dart dd = m_map.phi1(it) ; +// np1 += m_position[dd] ; +// Dart end = m_map.phi_1(it) ; +// dd = m_map.phi1(dd) ; +// do +// { +// ++degree2 ; +// np2 += m_position[dd] ; +// dd = m_map.phi1(dd) ; +// } while(dd != end) ; +// it = m_map.phi2(m_map.phi_1(it)) ; +// } while(it != db) ; +// +// float beta = 3.0 / (2.0 * degree1) ; +// float gamma = 1.0 / (4.0 * degree2) ; +// np1 *= beta / degree1 ; +// np2 *= gamma / degree2 ; +// +// typename PFP::VEC3 vp = m_position[db] ; +// vp *= 1.0 - beta - gamma ; +// +// m_map.incCurrentLevel() ; +// +// m_position[d] = np1 + np2 + vp ; +// +// } +// else +// { +// m_map.decCurrentLevel() ; +// +// typename PFP::VEC3 P = m_position[d]; +// +// //vertex points +// typename PFP::VEC3 Cavg = typename PFP::VEC3(0); +// unsigned int degree = 0; +// Traversor3VW travVW(m_map, d); +// for(Dart dit = travVW.begin() ; dit != travVW.end() ; dit = travVW.next()) +// { +// Cavg += Algo::Surface::Geometry::volumeCentroid(m_map, dit, m_position); +// ++degree; +// } +// Cavg /= degree; +// +// typename PFP::VEC3 Aavg = typename PFP::VEC3(0); +// degree = 0; +// Traversor3VF travVF(m_map, d); +// for(Dart dit = travVF.begin() ; dit != travVF.end() ; dit = travVF.next()) +// { +// Aavg += Algo::Surface::Geometry::faceCentroid(m_map, dit, m_position); +// ++degree; +// } +// Aavg /= degree; +// +// typename PFP::VEC3 Mavg = typename PFP::VEC3(0); +// degree = 0; +// Traversor3VE travVE(m_map, d); +// for(Dart dit = travVE.begin() ; dit != travVE.end() ; dit = travVE.next()) +// { +// Dart d2 = m_map.phi2(dit); +// Mavg += (m_position[dit] + m_position[d2]) * typename PFP::REAL(0.5); +// ++degree; +// } +// Mavg /= degree; +// +// typename PFP::VEC3 vp = Cavg + Aavg * 3 + Mavg * 3 + P; +// vp /= 8; +// +// m_map.incCurrentLevel() ; +// +// m_position[d] = vp; +// } +// +// return false; +// } +//}; + template class MJ96EdgeVertexFunctor : public FunctorType { protected: typename PFP::MAP& m_map ; - AttributeHandler& m_position ; + VertexAttribute& m_position ; public: - MJ96EdgeVertexFunctor(typename PFP::MAP& m, AttributeHandler& p) : m_map(m), m_position(p) + MJ96EdgeVertexFunctor(typename PFP::MAP& m, VertexAttribute& p) : m_map(m), m_position(p) {} bool operator() (Dart d) @@ -169,7 +265,7 @@ public: Dart d1 = m_map.phi2(db) ; - //m_map.decCurrentLevel() ; + m_map.decCurrentLevel() ; Dart d2 = m_map.phi2(d1) ; Dart d3 = m_map.phi_1(d1) ; @@ -191,7 +287,7 @@ public: p5 *= 1.0 / 16.0 ; p6 *= 1.0 / 16.0 ; - //m_map.incCurrentLevel() ; + m_map.incCurrentLevel() ; m_position[d] = p1 + p2 + p3 + p4 + p5 + p6 ; } @@ -199,7 +295,8 @@ public: { Dart d2 = m_map.phi2(d); - //m_map.decCurrentLevel() ; + m_map.decCurrentLevel() ; + //edge points typename PFP::VEC3 Cavg = typename PFP::VEC3(0); unsigned int degree = 0; @@ -227,7 +324,7 @@ public: typename PFP::VEC3 ep = Cavg + Aavg * 2 + M * (degree - 3); ep /= degree; - //m_map.incCurrentLevel() ; + m_map.incCurrentLevel() ; m_position[d] = ep; } @@ -241,25 +338,23 @@ class MJ96FaceVertexFunctor : public FunctorType { protected: typename PFP::MAP& m_map ; - AttributeHandler& m_position ; + VertexAttribute& m_position ; public: - MJ96FaceVertexFunctor(typename PFP::MAP& m, AttributeHandler& p) : m_map(m), m_position(p) + MJ96FaceVertexFunctor(typename PFP::MAP& m, VertexAttribute& p) : m_map(m), m_position(p) {} bool operator() (Dart d) { - if(m_map.isBoundaryVertex(d)) + if(m_map.isBoundaryFace(d)) { - Dart db = m_map.findBoundaryFaceOfVertex(d); - - Dart df = m_map.phi1(m_map.phi1(db)) ; + Dart db = m_map.phi_1(m_map.phi3(d)); - //m_map.decCurrentLevel() ; + m_map.decCurrentLevel() ; typename PFP::VEC3 p(0) ; unsigned int degree = 0 ; - Traversor2FV trav(m_map, df) ; + Traversor2FV trav(m_map, db) ; for(Dart it = trav.begin(); it != trav.end(); it = trav.next()) { ++degree ; @@ -267,24 +362,26 @@ public: } p /= degree ; - //m_map.incCurrentLevel() ; + m_map.incCurrentLevel() ; m_position[d] = p ; } else { - Dart df = m_map.phi1(m_map.phi1(d)) ; - //m_map.decCurrentLevel() ; + Dart df = m_map.phi_1(m_map.phi_1(d)) ; + + m_map.decCurrentLevel() ; + //face points typename PFP::VEC3 C0 = Algo::Surface::Geometry::volumeCentroid(m_map, df, m_position); typename PFP::VEC3 C1 = Algo::Surface::Geometry::volumeCentroid(m_map, m_map.phi3(df), m_position); - typename PFP::VEC3 A = Algo::Surface::Geometry::volumeCentroid(m_map, m_map.phi3(df), m_position); + typename PFP::VEC3 A = Algo::Surface::Geometry::faceCentroid(m_map, m_map.phi3(df), m_position); typename PFP::VEC3 fp = C0 + A * 2 + C1; fp /= 4; - //m_map.incCurrentLevel() ; + m_map.incCurrentLevel() ; m_position[d] = fp; } @@ -299,10 +396,10 @@ class MJ96VolumeVertexFunctor : public FunctorType { protected: typename PFP::MAP& m_map ; - AttributeHandler& m_position ; + VertexAttribute& m_position ; public: - MJ96VolumeVertexFunctor(typename PFP::MAP& m, AttributeHandler& p) : m_map(m), m_position(p) + MJ96VolumeVertexFunctor(typename PFP::MAP& m, VertexAttribute& p) : m_map(m), m_position(p) {} bool operator() (Dart d) @@ -310,9 +407,11 @@ public: Dart df = m_map.phi_1(m_map.phi2(m_map.phi1(d))) ; m_map.decCurrentLevel() ; + //cell points : these points are the average of the //vertices of the lattice that bound the cell typename PFP::VEC3 p = Algo::Surface::Geometry::volumeCentroid(m_map,df,m_position); + m_map.incCurrentLevel() ; m_position[d] = p; diff --git a/include/Algo/Multiresolution/Map3MR/map3MR_PrimalAdapt.h b/include/Algo/Multiresolution/Map3MR/map3MR_PrimalAdapt.h index 6d3ddfea8efeace3283de401fb334bfba0597490..fe5025453b788caff3820de4b9499e33a428e752 100644 --- a/include/Algo/Multiresolution/Map3MR/map3MR_PrimalAdapt.h +++ b/include/Algo/Multiresolution/Map3MR/map3MR_PrimalAdapt.h @@ -28,6 +28,7 @@ #include "Topology/map/embeddedMap3.h" #include "Topology/generic/traversorCell.h" #include "Topology/generic/traversor3.h" +#include "Algo/Modelisation/tetrahedralization.h" #include namespace CGoGN diff --git a/include/Algo/Multiresolution/Map3MR/map3MR_PrimalAdapt.hpp b/include/Algo/Multiresolution/Map3MR/map3MR_PrimalAdapt.hpp index 974377ba701b2958e72675bfc416a7447c0df0f2..21583fac90bc80b11837cae2ca618a6fdd7e6e10 100644 --- a/include/Algo/Multiresolution/Map3MR/map3MR_PrimalAdapt.hpp +++ b/include/Algo/Multiresolution/Map3MR/map3MR_PrimalAdapt.hpp @@ -489,19 +489,19 @@ void Map3MR::subdivideFace(Dart d, bool triQuad) { Dart dd = m_map.phi1(old) ; Dart e = m_map.phi1(dd) ; - (*vertexVertexFunctor)(e) ; + //(*vertexVertexFunctor)(e) ; e = m_map.phi1(e) ; splitFace(dd, e) ; dd = e ; e = m_map.phi1(dd) ; - (*vertexVertexFunctor)(e) ; + //(*vertexVertexFunctor)(e) ; e = m_map.phi1(e) ; splitFace(dd, e) ; dd = e ; e = m_map.phi1(dd) ; - (*vertexVertexFunctor)(e) ; + //(*vertexVertexFunctor)(e) ; e = m_map.phi1(e) ; splitFace(dd, e) ; } @@ -509,7 +509,7 @@ void Map3MR::subdivideFace(Dart d, bool triQuad) { Dart dd = m_map.phi1(old) ; Dart next = m_map.phi1(dd) ; - (*vertexVertexFunctor)(next) ; + //(*vertexVertexFunctor)(next) ; next = m_map.phi1(next) ; splitFace(dd, next) ; // insert a first edge Dart ne = m_map.phi2(m_map.phi_1(dd)); @@ -517,13 +517,13 @@ void Map3MR::subdivideFace(Dart d, bool triQuad) cutEdge(ne) ; // cut the new edge to insert the central vertex dd = m_map.phi1(next) ; - (*vertexVertexFunctor)(dd) ; + //(*vertexVertexFunctor)(dd) ; dd = m_map.phi1(dd) ; while(dd != ne) // turn around the face and insert new edges { // linked to the central vertex splitFace(m_map.phi1(ne), dd) ; dd = m_map.phi1(dd) ; - (*vertexVertexFunctor)(dd) ; + //(*vertexVertexFunctor)(dd) ; dd = m_map.phi1(dd) ; } @@ -562,15 +562,19 @@ unsigned int Map3MR::subdivideVolume(Dart d, bool triQuad, bool OneLevelDif // // Create inside volumes // - Dart centralDart = NIL; std::vector > subdividedFaces; subdividedFaces.reserve(128); + bool isocta = false; + bool ishex = false; + bool isprism = false; + bool ispyra = false; + + Dart centralDart = NIL; Traversor3WV traWV(m_map, d); for(Dart ditWV = traWV.begin(); ditWV != traWV.end(); ditWV = traWV.next()) { - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - (*vertexVertexFunctor)(ditWV) ; + m_map.incCurrentLevel() ; Dart e = ditWV; std::vector v ; @@ -578,85 +582,361 @@ unsigned int Map3MR::subdivideVolume(Dart d, bool triQuad, bool OneLevelDif do { v.push_back(m_map.phi1(e)); - v.push_back(m_map.phi1(m_map.phi1(e))); + + if(m_map.phi1(m_map.phi1(m_map.phi1(e))) != e) + v.push_back(m_map.phi1(m_map.phi1(e))); if(!m_map.PFP::MAP::ParentMap::isBoundaryEdge(m_map.phi1(e))) subdividedFaces.push_back(std::pair(m_map.phi1(e),m_map.phi2(m_map.phi1(e)))); - if(!m_map.PFP::MAP::ParentMap::isBoundaryEdge(m_map.phi1(m_map.phi1(e)))) - subdividedFaces.push_back(std::pair(m_map.phi1(m_map.phi1(e)),m_map.phi2(m_map.phi1(m_map.phi1(e))))); + if(m_map.phi1(m_map.phi1(m_map.phi1(e))) != e) + if(!m_map.PFP::MAP::ParentMap::isBoundaryEdge(m_map.phi1(m_map.phi1(e)))) + subdividedFaces.push_back(std::pair(m_map.phi1(m_map.phi1(e)),m_map.phi2(m_map.phi1(m_map.phi1(e))))); e = m_map.phi2(m_map.phi_1(e)); } while(e != ditWV); - splitSurfaceInVolume(v); + m_map.splitVolume(v); - Dart dd = m_map.phi2(m_map.phi1(ditWV)); - Dart next = m_map.phi1(m_map.phi1(dd)) ; - m_map.PFP::MAP::ParentMap::splitFace(dd, next) ; + unsigned int fdeg = m_map.faceDegree(m_map.phi2(m_map.phi1(ditWV))); - Dart ne = m_map.phi2(m_map.phi_1(dd)); - m_map.PFP::MAP::ParentMap::cutEdge(ne) ; - centralDart = m_map.phi1(ne); + if(fdeg == 4) + { + if(m_map.PFP::MAP::ParentMap::vertexDegree(ditWV) == 3) + { + isocta = false; + ispyra = true; + + Dart it = ditWV; + if((m_map.faceDegree(it) == 3) && (m_map.faceDegree(m_map.phi2(it))) == 3) + { + it = m_map.phi2(m_map.phi_1(it)); + } + else if((m_map.faceDegree(it) == 3) && (m_map.faceDegree(m_map.phi2(it)) == 4)) + { + it = m_map.phi1(m_map.phi2(it)); + } + + Dart old = m_map.phi2(m_map.phi1(it)); + Dart dd = m_map.phi1(m_map.phi1(old)); + + m_map.splitFace(old,dd) ; + centralDart = old; + } + else + { + isocta = true; + + Dart old = m_map.phi2(m_map.phi1(ditWV)); + Dart dd = m_map.phi1(old) ; + m_map.splitFace(old,dd) ; - dd = m_map.phi1(m_map.phi1(next)) ; - while(dd != ne) + Dart ne = m_map.phi1(old); + + m_map.cutEdge(ne); + centralDart = m_map.phi1(ne); + + Dart stop = m_map.phi2(m_map.phi1(ne)); + ne = m_map.phi2(ne); + do + { + dd = m_map.phi1(m_map.phi1(ne)); + + m_map.splitFace(ne, dd) ; + + ne = m_map.phi2(m_map.phi_1(ne)); + dd = m_map.phi1(dd); + } + while(dd != stop); + } + } + else if(fdeg == 5) { - Dart tmp = m_map.phi1(ne) ; - m_map.PFP::MAP::ParentMap::splitFace(tmp, dd) ; - dd = m_map.phi1(m_map.phi1(dd)) ; + isprism = true; + + Dart it = ditWV; + if(m_map.faceDegree(it) == 3) + { + it = m_map.phi2(m_map.phi_1(it)); + } + else if(m_map.faceDegree(m_map.phi2(m_map.phi_1(ditWV))) == 3) + { + it = m_map.phi2(m_map.phi_1(m_map.phi2(m_map.phi_1(it)))); + } + + Dart old = m_map.phi2(m_map.phi1(it)); + Dart dd = m_map.phi_1(m_map.phi_1(old)); + + m_map.splitFace(old,dd) ; } + if(fdeg == 6) + { + ishex = true; - m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ; //Utile ? - } + Dart dd = m_map.phi2(m_map.phi1(ditWV));; + Dart next = m_map.phi1(m_map.phi1(dd)) ; + m_map.splitFace(dd, next) ; // insert a first edge - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - DartMarkerNoUnmark mf(m_map); + Dart ne = m_map.phi2(m_map.phi_1(dd)) ; + m_map.cutEdge(ne) ; // cut the new edge to insert the central vertex + centralDart = m_map.phi1(ne); - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - //4 couture des relations precedemment sauvegarde - for (std::vector >::iterator it = subdividedFaces.begin(); it != subdividedFaces.end(); ++it) + dd = m_map.phi1(m_map.phi1(next)) ; + while(dd != ne) // turn around the face and insert new edges + { // linked to the central vertex + Dart tmp = m_map.phi1(ne) ; + m_map.splitFace(tmp, dd) ; + dd = m_map.phi1(m_map.phi1(dd)) ; + } + } + + m_map.decCurrentLevel() ; + } + + if(ishex) { - Dart f1 = m_map.phi2((*it).first); - Dart f2 = m_map.phi2((*it).second); + m_map.incCurrentLevel(); + + m_map.deleteVolume(m_map.phi3(m_map.phi2(m_map.phi1(d)))); + + for (std::vector >::iterator it = subdividedFaces.begin(); it != subdividedFaces.end(); ++it) + { + Dart f1 = m_map.phi2((*it).first); + Dart f2 = m_map.phi2((*it).second); - //if(isBoundaryFace(f1) && isBoundaryFace(f2)) - if(m_map.phi3(f1) == f1 && m_map.phi3(f2) == f2) - m_map.sewVolumes(f1, f2, false); + if(m_map.isBoundaryFace(f1) && m_map.isBoundaryFace(f2)) + { + m_map.sewVolumes(f1, f2);//, false); + } + } + + //replonger l'orbit de ditV. + //m_map.template setOrbitEmbedding(x, m_map.template getEmbedding(d)); + + (*volumeVertexFunctor)(centralDart) ; + + m_map.decCurrentLevel() ; } - m_map.template setOrbitEmbedding(centralDart, m_map.template getEmbedding(centralDart)); - (*volumeVertexFunctor)(centralDart) ; + if(ispyra) + { + isocta = false; + + Dart ditV = d; + + Traversor3WV traWV(m_map, d); + for(Dart ditWV = traWV.begin(); ditWV != traWV.end(); ditWV = traWV.next()) + { + if(m_map.PFP::MAP::ParentMap::vertexDegree(ditWV) == 4) + ditV = ditWV; + } + + m_map.incCurrentLevel(); + Dart x = m_map.phi_1(m_map.phi2(m_map.phi1(ditV))); + + Dart f = x; + do + { + Dart f3 = m_map.phi3(f); + Dart tmp = m_map.phi_1(m_map.phi2(m_map.phi_1(m_map.phi2(m_map.phi_1(f3))))); //future voisin par phi2 + swapEdges(f3, tmp); + + f = m_map.phi2(m_map.phi_1(f)); + }while(f != x); - //A optimiser - m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; - TraversorE travE2(m_map); - for (Dart d = travE2.begin(); d != travE2.end(); d = travE2.next()) + //replonger l'orbit de ditV. + m_map.template setOrbitEmbedding(x, m_map.template getEmbedding(x)); + + m_map.decCurrentLevel() ; + } + + if(isocta) { - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; - m_map.template setOrbitEmbedding(m_map.phi1(d), m_map.template getEmbedding(m_map.phi1(d))); + Traversor3WV traWV(m_map, d); + + for(Dart ditWV = traWV.begin(); ditWV != traWV.end(); ditWV = traWV.next()) + { + m_map.incCurrentLevel(); + Dart x = m_map.phi_1(m_map.phi2(m_map.phi1(ditWV))); + + if(!Algo::Volume::Modelisation::Tetrahedralization::isTetrahedron(m_map,x)) + { + DartMarkerStore me(m_map); + + Dart f = x; + + do + { + Dart f3 = m_map.phi3(f); + + if(!me.isMarked(f3)) + { + Dart tmp = m_map.phi_1(m_map.phi2(m_map.phi_1(m_map.phi2(m_map.phi_1(f3))))); //future voisin par phi2 + + Dart f32 = m_map.phi2(f3); + swapEdges(f3, tmp); + + me.markOrbit(f3); + me.markOrbit(f32); + } + + f = m_map.phi2(m_map.phi_1(f)); + }while(f != x); + + } + + m_map.template setOrbitEmbedding(centralDart, m_map.template getEmbedding(centralDart)); + (*volumeVertexFunctor)(centralDart) ; + + m_map.decCurrentLevel() ; + } } - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; - TraversorF travF2(m_map) ; - for (Dart d = travF2.begin(); d != travF2.end(); d = travF2.next()) + if(isprism) { - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - m_map.template setOrbitEmbedding(m_map.phi2(m_map.phi1(d)), m_map.template getEmbedding(m_map.phi2(m_map.phi1(d)))); - m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; + m_map.incCurrentLevel(); + + Dart ditWV = d; + if(m_map.faceDegree(d) == 3) + { + ditWV = m_map.phi2(m_map.phi_1(d)); + } + else if(m_map.faceDegree(m_map.phi2(m_map.phi_1(d))) == 3) + { + ditWV = m_map.phi1(m_map.phi2(d)); + } + + ditWV = m_map.phi3(m_map.phi_1(m_map.phi2(m_map.phi1(ditWV)))); + + + std::vector path; + + Dart dtemp = ditWV; + do + { + //future voisin par phi2 + Dart sF1 = m_map.phi1(m_map.phi2(m_map.phi3(dtemp))); + Dart wrongVolume = m_map.phi3(sF1); + Dart sF2 = m_map.phi3(m_map.phi2(wrongVolume)); + Dart tmp = m_map.phi3(m_map.phi2(m_map.phi1(sF2))); + swapEdges(dtemp, tmp); + + m_map.deleteVolume(wrongVolume); + m_map.sewVolumes(sF1,sF2); + + path.push_back(dtemp); + dtemp = m_map.phi_1(m_map.phi2(m_map.phi_1(dtemp))); + + + }while(dtemp != ditWV); + + m_map.splitVolume(path); + + m_map.decCurrentLevel() ; } - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - std::cout << std::endl; - m_map.popLevel(); + m_map.incCurrentLevel(); + m_map.popLevel() ; return vLevel; } + + + + +// Traversor3WV traWV(m_map, d); +// for(Dart ditWV = traWV.begin(); ditWV != traWV.end(); ditWV = traWV.next()) +// { +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// +// Dart e = ditWV; +// std::vector v ; +// +// do +// { +// v.push_back(m_map.phi1(e)); +// v.push_back(m_map.phi1(m_map.phi1(e))); +// +// if(!m_map.PFP::MAP::ParentMap::isBoundaryEdge(m_map.phi1(e))) +// subdividedFaces.push_back(std::pair(m_map.phi1(e),m_map.phi2(m_map.phi1(e)))); +// +// if(!m_map.PFP::MAP::ParentMap::isBoundaryEdge(m_map.phi1(m_map.phi1(e)))) +// subdividedFaces.push_back(std::pair(m_map.phi1(m_map.phi1(e)),m_map.phi2(m_map.phi1(m_map.phi1(e))))); +// +// e = m_map.phi2(m_map.phi_1(e)); +// } +// while(e != ditWV); +// +// splitSurfaceInVolume(v); +// +// Dart dd = m_map.phi2(m_map.phi1(ditWV)); +// Dart next = m_map.phi1(m_map.phi1(dd)) ; +// m_map.PFP::MAP::ParentMap::splitFace(dd, next) ; +// +// Dart ne = m_map.phi2(m_map.phi_1(dd)); +// m_map.PFP::MAP::ParentMap::cutEdge(ne) ; +// centralDart = m_map.phi1(ne); +// +// dd = m_map.phi1(m_map.phi1(next)) ; +// while(dd != ne) +// { +// Dart tmp = m_map.phi1(ne) ; +// m_map.PFP::MAP::ParentMap::splitFace(tmp, dd) ; +// dd = m_map.phi1(m_map.phi1(dd)) ; +// } +// +// (*vertexVertexFunctor)(ditWV) ; +// +// m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ; //Utile ? +// } +// +// //m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// //DartMarkerNoUnmark mf(m_map); +// +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// //4 couture des relations precedemment sauvegarde +// for (std::vector >::iterator it = subdividedFaces.begin(); it != subdividedFaces.end(); ++it) +// { +// Dart f1 = m_map.phi2((*it).first); +// Dart f2 = m_map.phi2((*it).second); +// +// //if(isBoundaryFace(f1) && isBoundaryFace(f2)) +// if(m_map.phi3(f1) == f1 && m_map.phi3(f2) == f2) +// m_map.sewVolumes(f1, f2, false); +// } +// +// m_map.template setOrbitEmbedding(centralDart, m_map.template getEmbedding(centralDart)); +// (*volumeVertexFunctor)(centralDart) ; +// +// //A optimiser +// m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// TraversorE travE2(m_map); +// for (Dart d = travE2.begin(); d != travE2.end(); d = travE2.next()) +// { +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// m_map.template setOrbitEmbedding(m_map.phi1(d), m_map.template getEmbedding(m_map.phi1(d))); +// } +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// +// m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// TraversorF travF2(m_map) ; +// for (Dart d = travF2.begin(); d != travF2.end(); d = travF2.next()) +// { +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// m_map.template setOrbitEmbedding(m_map.phi2(m_map.phi1(d)), m_map.template getEmbedding(m_map.phi2(m_map.phi1(d)))); +// m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// } +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// +// std::cout << std::endl; +// +// m_map.popLevel(); + + template void Map3MR::subdivideVolumeTetOcta(Dart d) { diff --git a/include/Algo/Multiresolution/Map3MR/map3MR_PrimalRegular.hpp b/include/Algo/Multiresolution/Map3MR/map3MR_PrimalRegular.hpp index 9318632511932193736ee97ef05a5f5b391e2279..32aec2f6b17bd5a89c0f838561ba337b2b089361 100644 --- a/include/Algo/Multiresolution/Map3MR/map3MR_PrimalRegular.hpp +++ b/include/Algo/Multiresolution/Map3MR/map3MR_PrimalRegular.hpp @@ -415,7 +415,7 @@ void Map3MR::addNewLevelHexa() } //3. create inside volumes - m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ; + m_map.decCurrentLevel(); TraversorW traW(m_map); for(Dart dit = traW.begin(); dit != traW.end(); dit = traW.next()) { @@ -426,7 +426,7 @@ void Map3MR::addNewLevelHexa() Traversor3WV traWV(m_map, dit); for(Dart ditWV = traWV.begin(); ditWV != traWV.end(); ditWV = traWV.next()) { - m_map.setCurrentLevel(m_map.getMaxLevel()) ; //Utile ? + m_map.incCurrentLevel() ; Dart e = ditWV; std::vector v ; @@ -446,65 +446,106 @@ void Map3MR::addNewLevelHexa() } while(e != ditWV); - splitSurfaceInVolume(v); + //splitSurfaceInVolume(v); + m_map.splitVolume(v); - Dart dd = m_map.phi2(m_map.phi1(ditWV)); + Dart dd = m_map.phi2(m_map.phi1(ditWV));; Dart next = m_map.phi1(m_map.phi1(dd)) ; - m_map.PFP::MAP::ParentMap::splitFace(dd, next) ; + m_map.splitFace(dd, next) ; // insert a first edge - Dart ne = m_map.phi2(m_map.phi_1(dd)); - m_map.PFP::MAP::ParentMap::cutEdge(ne) ; + Dart ne = m_map.phi2(m_map.phi_1(dd)) ; + m_map.cutEdge(ne) ; // cut the new edge to insert the central vertex centralDart = m_map.phi1(ne); dd = m_map.phi1(m_map.phi1(next)) ; - while(dd != ne) - { + while(dd != ne) // turn around the face and insert new edges + { // linked to the central vertex Dart tmp = m_map.phi1(ne) ; - m_map.PFP::MAP::ParentMap::splitFace(tmp, dd) ; + m_map.splitFace(tmp, dd) ; dd = m_map.phi1(m_map.phi1(dd)) ; } - m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ; //Utile ? + m_map.decCurrentLevel() ; + + // Dart dd = m_map.phi2(m_map.phi1(ditWV)); + // Dart next = m_map.phi1(m_map.phi1(dd)) ; + // m_map.PFP::MAP::ParentMap::splitFace(dd, next) ; + // + // Dart ne = m_map.phi2(m_map.phi_1(dd)); + // m_map.PFP::MAP::ParentMap::cutEdge(ne) ; + // centralDart = m_map.phi1(ne); + // + // dd = m_map.phi1(m_map.phi1(next)) ; + // while(dd != ne) + // { + // Dart tmp = m_map.phi1(ne) ; + // m_map.PFP::MAP::ParentMap::splitFace(tmp, dd) ; + // dd = m_map.phi1(m_map.phi1(dd)) ; + // } + // + // m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ; //Utile ? } - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - //4 couture des relations precedemment sauvegarde + m_map.incCurrentLevel(); + + m_map.deleteVolume(m_map.phi3(m_map.phi2(m_map.phi1(dit)))); + for (std::vector >::iterator it = subdividedFaces.begin(); it != subdividedFaces.end(); ++it) { Dart f1 = m_map.phi2((*it).first); Dart f2 = m_map.phi2((*it).second); - //if(isBoundaryFace(f1) && isBoundaryFace(f2)) - if(m_map.phi3(f1) == f1 && m_map.phi3(f2) == f2) - m_map.sewVolumes(f1, f2, false); + if(m_map.isBoundaryFace(f1) && m_map.isBoundaryFace(f2)) + { + m_map.sewVolumes(f1, f2);//, false); + } } - m_map.template setOrbitEmbedding(centralDart, m_map.template getEmbedding(centralDart)); - m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ; - } + //m_map.template setOrbitEmbedding(centralDart, m_map.template getEmbedding(centralDart)); - //A optimiser - m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; - TraversorE travE2(m_map); - for (Dart d = travE2.begin(); d != travE2.end(); d = travE2.next()) - { - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - m_map.template setOrbitEmbedding(m_map.phi1(d), m_map.template getEmbedding(m_map.phi1(d))); - m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; - } - m_map.setCurrentLevel(m_map.getMaxLevel()) ; + m_map.decCurrentLevel() ; - m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; - TraversorF travF2(m_map) ; - for (Dart d = travF2.begin(); d != travF2.end(); d = travF2.next()) - { - m_map.setCurrentLevel(m_map.getMaxLevel()) ; - m_map.template setOrbitEmbedding(m_map.phi2(m_map.phi1(d)), m_map.template getEmbedding(m_map.phi2(m_map.phi1(d)))); - m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// //4 couture des relations precedemment sauvegarde +// for (std::vector >::iterator it = subdividedFaces.begin(); it != subdividedFaces.end(); ++it) +// { +// Dart f1 = m_map.phi2((*it).first); +// Dart f2 = m_map.phi2((*it).second); +// +// //if(isBoundaryFace(f1) && isBoundaryFace(f2)) +// if(m_map.phi3(f1) == f1 && m_map.phi3(f2) == f2) +// m_map.sewVolumes(f1, f2, false); +// } +// m_map.template setOrbitEmbedding(centralDart, m_map.template getEmbedding(centralDart)); +// +// m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ; } - m_map.setCurrentLevel(m_map.getMaxLevel()) ; + m_map.incCurrentLevel(); m_map.popLevel() ; + +// //A optimiser +// m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// TraversorE travE2(m_map); +// for (Dart d = travE2.begin(); d != travE2.end(); d = travE2.next()) +// { +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// m_map.template setOrbitEmbedding(m_map.phi1(d), m_map.template getEmbedding(m_map.phi1(d))); +// m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// } +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// +// m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// TraversorF travF2(m_map) ; +// for (Dart d = travF2.begin(); d != travF2.end(); d = travF2.next()) +// { +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// m_map.template setOrbitEmbedding(m_map.phi2(m_map.phi1(d)), m_map.template getEmbedding(m_map.phi2(m_map.phi1(d)))); +// m_map.setCurrentLevel(m_map.getMaxLevel()-1) ; +// } +// m_map.setCurrentLevel(m_map.getMaxLevel()) ; +// +// m_map.popLevel() ; } diff --git a/include/Algo/Render/GL1/topo_render.h b/include/Algo/Render/GL1/topo_render.h index 4dd483a961533cacd1d70692bf3246406d6c5810..effba42bbccb6ae40ab201cd54996a1d5fb209f9 100644 --- a/include/Algo/Render/GL1/topo_render.h +++ b/include/Algo/Render/GL1/topo_render.h @@ -77,11 +77,7 @@ void renderTopoMD2(typename PFP::MAP& the_map, const VertexAttribute -void renderTopoMD3(typename PFP::MAP& map, const VertexAttribute& positions, bool drawPhi1, bool drawPhi2, bool drawPhi3, float ke, float kf, float kv, FunctorType& good); - -template -void renderTopoMD3(typename PFP::MAP& map, VertexAttribute& positions, bool drawPhi1, bool drawPhi2, bool drawPhi3, float ke, float kf, float kv); - +void renderTopoMD3(typename PFP::MAP& map, const VertexAttribute& positions, bool drawPhi1, bool drawPhi2, bool drawPhi3, float ke, float kf, float kv, const FunctorSelect& good=allDarts); /** * Render darts of g-map diff --git a/include/Algo/Render/GL1/topo_render.hpp b/include/Algo/Render/GL1/topo_render.hpp index 388b9d54003576def8486a73664d957e06f0b745..ad093a0c73055081532ad0d392595e85dd692ff6 100644 --- a/include/Algo/Render/GL1/topo_render.hpp +++ b/include/Algo/Render/GL1/topo_render.hpp @@ -138,7 +138,7 @@ void renderTopoMD2(typename PFP::MAP& map, const VertexAttribute -void renderTopoMD3(typename PFP::MAP& map, VertexAttribute& positions, bool drawPhi1, bool drawPhi2, bool drawPhi3, float ke, float kf, float kv) +void renderTopoMD3(typename PFP::MAP& map, VertexAttribute& positions, bool drawPhi1, bool drawPhi2, bool drawPhi3, float ke, float kf, float kv, const FunctorSelect& good) { typedef typename PFP::VEC3 VEC3; typedef typename PFP::REAL REAL; @@ -164,6 +164,8 @@ void renderTopoMD3(typename PFP::MAP& map, VertexAttribute& DartMarker mark(map); // marker for darts for (Dart d = map.begin(); d != map.end(); map.next(d)) { + if(good(d)) + { CellMarkerStore markVert(map); //marker for vertices VEC3 center(0, 0, 0); unsigned int nbv = 0; @@ -200,6 +202,7 @@ void renderTopoMD3(typename PFP::MAP& map, VertexAttribute& center /= typename PFP::REAL(nbv); vecCenters.push_back(center); vecNbFaces.push_back(nbf); + } } glLineWidth(1.0f); @@ -275,12 +278,15 @@ void renderTopoMD3(typename PFP::MAP& map, VertexAttribute& } e = map.phi3(d); + if(fv2[d] != VEC3(0.0f) && fv2[e] != VEC3(0.0f)) + { if ((d +#include "Utils/convertType.h" + namespace CGoGN { @@ -128,23 +131,18 @@ bool isPointInTetrahedron(VEC3 points[4], VEC3& point, bool CCW) VEC3 AB = points[1] - points[0] ; VEC3 AC = points[2] - points[0] ; VEC3 AD = points[3] - points[0] ; - VEC3 BD = points[3] - points[1] ; - VEC3 BC = points[2] - points[1] ; - - VEC3 nABC = AB ^ AC ; - VEC3 nACD = AC ^ AD ; - VEC3 nADB = AD ^ AB ; - VEC3 nBDC = BD ^ BC ; - - T d0 = nABC * (point - points[0]) ; - T d1 = nACD * (point - points[0]) ; - T d2 = nADB * (point - points[0]) ; - T d3 = nBDC * (point - points[1]) ; - - if(CCW) - return (d0 < 0 && d1 < 0 && d2 < 0 && d3 < 0) ; - else - return (d0 > 0 && d1 > 0 && d2 > 0 && d3 > 0) ; + + Eigen::Matrix3f A; + A << AB[0], AB[1], AB[2], + AC[0], AC[1], AC[2], + AD[0], AD[1], AD[2]; + + Eigen::Matrix3f AInv = A.inverse(); + + VEC3 v1(point-points[0]); + Eigen::Vector3f& v = Utils::convertRef(v1); + Eigen::Vector3f beta = AInv* v; + return (beta[0] >= 0.0f && beta[1] >= 0.0f && beta[2] >= 0.0f && beta[0]+beta[1]+beta[2]<=1.0f); } template diff --git a/include/Topology/generic/dartmarker.h b/include/Topology/generic/dartmarker.h index 49a3f18e0a1572062d11731b9c41abfd1bba3c07..db9857f5ff380ca0fc428c638b783b62a2030510 100644 --- a/include/Topology/generic/dartmarker.h +++ b/include/Topology/generic/dartmarker.h @@ -312,8 +312,7 @@ public: void unmarkAll() { assert(m_map.getMarkerSet(m_thread).testMark(m_mark)); - for (std::vector::iterator it = m_markedDarts.begin(); - it != m_markedDarts.end(); ++it) + for (std::vector::iterator it = m_markedDarts.begin(); it != m_markedDarts.end(); ++it) m_markVector->operator[](*it).unsetMark(m_mark) ; } } ; diff --git a/include/Topology/ihmap/ihm2.h b/include/Topology/ihmap/ihm2.h new file mode 100644 index 0000000000000000000000000000000000000000..db5167f1dd0baa1eb500a99e447d853c68cdf592 --- /dev/null +++ b/include/Topology/ihmap/ihm2.h @@ -0,0 +1,269 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; 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 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __IMPLICIT_HIERARCHICAL_MAP2__ +#define __IMPLICIT_HIERARCHICAL_MAP2__ + +#include "Topology/map/embeddedMap2.h" + +namespace CGoGN +{ + +template class AttributeHandler_IHM ; + +class ImplicitHierarchicalMap2 : public EmbeddedMap2 +{ + template friend class AttributeHandler_IHM ; + +private: + unsigned int m_curLevel ; + unsigned int m_maxLevel ; + unsigned int m_idCount ; + + DartAttribute m_dartLevel ; + DartAttribute m_edgeId ; + + AttributeMultiVector* m_nextLevelCell[NB_ORBITS] ; + +public: + ImplicitHierarchicalMap2() ; + + ~ImplicitHierarchicalMap2() ; + + //! + /*! + * + */ + void update_topo_shortcuts(); + + //! + /*! + * + */ + void initImplicitProperties() ; + + /** + * clear the map + * @param remove attrib remove attribute (not only clear the content) + */ + void clear(bool removeAttrib); + + /*************************************************** + * ATTRIBUTES MANAGEMENT * + ***************************************************/ + + template + AttributeHandler_IHM addAttribute(const std::string& nameAttr) ; + + template + AttributeHandler_IHM getAttribute(const std::string& nameAttr) ; + + /*************************************************** + * MAP TRAVERSAL * + ***************************************************/ + + virtual Dart newDart() ; + + Dart phi1(Dart d) ; + + Dart phi_1(Dart d) ; + + Dart phi2(Dart d) ; + + Dart alpha0(Dart d) ; + + Dart alpha1(Dart d) ; + + Dart alpha_1(Dart d) ; + + virtual Dart begin() const ; + + virtual Dart end() const ; + + virtual void next(Dart& d) const ; + + virtual bool foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int thread = 0) ; + + virtual bool foreach_dart_of_edge(Dart d, FunctorType& f, unsigned int thread = 0) ; + + virtual bool foreach_dart_of_oriented_face(Dart d, FunctorType& f, unsigned int thread = 0) ; + virtual bool foreach_dart_of_face(Dart d, FunctorType& f, unsigned int thread = 0) ; + + virtual bool foreach_dart_of_oriented_volume(Dart d, FunctorType& f, unsigned int thread = 0) ; + virtual bool foreach_dart_of_volume(Dart d, FunctorType& f, unsigned int thread = 0) ; + + virtual bool foreach_dart_of_cc(Dart d, FunctorType& f, unsigned int thread = 0) ; + + /*************************************************** + * MAP MANIPULATION * + ***************************************************/ + + void splitFace(Dart d, Dart e) ; + + /*************************************************** + * LEVELS MANAGEMENT * + ***************************************************/ + + unsigned int getCurrentLevel() ; + + void setCurrentLevel(unsigned int l) ; + + void incCurrentLevel(); + + void decCurrentLevel(); + + unsigned int getMaxLevel() ; + + unsigned int getDartLevel(Dart d) ; + + void setDartLevel(Dart d, unsigned int i) ; + + /*************************************************** + * EDGE ID MANAGEMENT * + ***************************************************/ + + /** + * Give a new unique id to all the edges of the map + */ + void initEdgeId() ; + + /** + * Return the next available edge id + */ + unsigned int getNewEdgeId() ; + + unsigned int getEdgeId(Dart d) ; + + void setEdgeId(Dart d, unsigned int i) ; + + /*************************************************** + * CELLS INFORMATION * + ***************************************************/ + + /** + * Return the level of insertion of the vertex of d + */ + unsigned int vertexInsertionLevel(Dart d) ; + + /** + * Return the level of the edge of d in the current level map + */ + unsigned int edgeLevel(Dart d) ; + + /** + * Return the level of the face of d in the current level map + */ + unsigned int faceLevel(Dart d) ; + + /** + * Given the face of d in the current level map, + * return a level 0 dart of its origin face + */ + Dart faceOrigin(Dart d) ; + + /** + * Return the oldest dart of the face of d in the current level map + */ + Dart faceOldestDart(Dart d) ; + + /** + * Return true if the edge of d in the current level map + * has already been subdivided to the next level + */ + bool edgeIsSubdivided(Dart d) ; + + /** + * Return true if the edge of d in the current level map + * is subdivided to the next level, + * none of its resulting edges is in turn subdivided to the next level + * and the middle vertex is of degree 2 + */ + bool edgeCanBeCoarsened(Dart d) ; + + /** + * Return true if the face of d in the current level map + * has already been subdivided to the next level + */ + bool faceIsSubdivided(Dart d) ; + + /** + * Return true if the face of d in the current level map + * is subdivided to the next level + * and none of its resulting faces is in turn subdivided to the next level + */ + bool faceIsSubdividedOnce(Dart d) ; +} ; + +template +class AttributeHandler_IHM : public AttributeHandler +{ +public: + typedef T DATA_TYPE ; + + AttributeHandler_IHM() : AttributeHandler() + {} + + AttributeHandler_IHM(GenericMap* m, AttributeMultiVector* amv) : AttributeHandler(m, amv) + {} + + AttributeMultiVector* getDataVector() const + { + return AttributeHandler::getDataVector() ; + } + + bool isValid() const + { + return AttributeHandler::isValid() ; + } + + T& operator[](Dart d) ; + + const T& operator[](Dart d) const ; + + T& operator[](unsigned int a) + { + return AttributeHandler::operator[](a) ; + } + + const T& operator[](unsigned int a) const + { + return AttributeHandler::operator[](a) ; + } +} ; + +template +class VertexAttribute_IHM : public AttributeHandler_IHM +{ +public: + VertexAttribute_IHM() : AttributeHandler_IHM() {} + VertexAttribute_IHM(const AttributeHandler_IHM& ah) : AttributeHandler_IHM(ah) {} + VertexAttribute_IHM& operator=(const AttributeHandler_IHM& ah) { this->AttributeHandler_IHM::operator=(ah); return *this; } +}; + + +} //namespace CGoGN + +#include "Topology/ihmap/ihm2.hpp" + +#endif diff --git a/include/Topology/ihmap/ihm2.hpp b/include/Topology/ihmap/ihm2.hpp new file mode 100644 index 0000000000000000000000000000000000000000..85310fca969b79f46e02fe4fed5a1795244041ec --- /dev/null +++ b/include/Topology/ihmap/ihm2.hpp @@ -0,0 +1,419 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; 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 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +namespace CGoGN +{ + +/*************************************************** + * ATTRIBUTES MANAGEMENT * + ***************************************************/ + +template +AttributeHandler_IHM ImplicitHierarchicalMap2::addAttribute(const std::string& nameAttr) +{ + bool addNextLevelCell = false ; + if(!isOrbitEmbedded()) + addNextLevelCell = true ; + + AttributeHandler h = Map2::addAttribute(nameAttr) ; + + if(addNextLevelCell) + { + AttributeContainer& cellCont = m_attribs[ORBIT] ; + AttributeMultiVector* amv = cellCont.addAttribute("nextLevelCell") ; + m_nextLevelCell[ORBIT] = amv ; + for(unsigned int i = cellCont.begin(); i < cellCont.end(); cellCont.next(i)) + amv->operator[](i) = EMBNULL ; + } + + return AttributeHandler_IHM(this, h.getDataVector()) ; +} + +template +AttributeHandler_IHM ImplicitHierarchicalMap2::getAttribute(const std::string& nameAttr) +{ + AttributeHandler h = Map2::getAttribute(nameAttr) ; + return AttributeHandler_IHM(this, h.getDataVector()) ; +} + + +inline void ImplicitHierarchicalMap2::update_topo_shortcuts() +{ + Map2::update_topo_shortcuts(); + m_dartLevel = Map2::getAttribute("dartLevel") ; + m_edgeId = Map2::getAttribute("edgeId") ; + + //AttributeContainer& cont = m_attribs[DART] ; + //m_nextLevelCell = cont.getDataVector(cont.getAttributeIndex("nextLevelCell")) ; +} + +/*************************************************** + * MAP TRAVERSAL * + ***************************************************/ + +inline Dart ImplicitHierarchicalMap2::newDart() +{ + Dart d = Map2::newDart() ; + m_dartLevel[d] = m_curLevel ; + if(m_curLevel > m_maxLevel) // update max level + m_maxLevel = m_curLevel ; // if needed + return d ; +} + +inline Dart ImplicitHierarchicalMap2::phi1(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + bool finished = false ; + unsigned int edgeId = m_edgeId[d] ; + Dart it = d ; + do + { + it = Map2::phi1(it) ; + if(m_dartLevel[it] <= m_curLevel) + finished = true ; + else + { + while(m_edgeId[it] != edgeId) + it = Map2::alpha_1(it) ; + } + } while(!finished) ; + return it ; +} + +inline Dart ImplicitHierarchicalMap2::phi_1(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + bool finished = false ; + Dart it = Map2::phi_1(d) ; + unsigned int edgeId = m_edgeId[it] ; + do + { + if(m_dartLevel[it] <= m_curLevel) + finished = true ; + else + { + it = Map2::phi_1(it) ; + while(m_edgeId[it] != edgeId) + it = Map2::phi_1(Map2::phi2(it)) ; + } + } while(!finished) ; + return it ; +} + +inline Dart ImplicitHierarchicalMap2::phi2(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + if(Map2::phi2(d) == d) + return d ; + return Map2::alpha1(phi1(d)) ; +} + +inline Dart ImplicitHierarchicalMap2::alpha0(Dart d) +{ + return phi2(d) ; +} + +inline Dart ImplicitHierarchicalMap2::alpha1(Dart d) +{ + return Map2::alpha1(d) ; +} + +inline Dart ImplicitHierarchicalMap2::alpha_1(Dart d) +{ + return Map2::alpha_1(d) ; +} + +inline Dart ImplicitHierarchicalMap2::begin() const +{ + Dart d = Map2::begin() ; + while(d != Map2::end() && m_dartLevel[d] > m_curLevel) + Map2::next(d) ; + return d ; +} + +inline Dart ImplicitHierarchicalMap2::end() const +{ + return Map2::end() ; +} + +inline void ImplicitHierarchicalMap2::next(Dart& d) const +{ + do + { + Map2::next(d) ; + } while(d != Map2::end() && m_dartLevel[d] > m_curLevel) ; +} + +inline bool ImplicitHierarchicalMap2::foreach_dart_of_vertex(Dart d, FunctorType& f, unsigned int thread) +{ + Dart dNext = d; + do + { + if (f(dNext)) + return true; + dNext = alpha1(dNext); + } while (dNext != d); + return false; +} + +inline bool ImplicitHierarchicalMap2::foreach_dart_of_edge(Dart d, FunctorType& f, unsigned int thread) +{ + if (f(d)) + return true; + + Dart d2 = phi2(d); + if (d2 != d) + return f(d2); + else + return false; +} + +inline bool ImplicitHierarchicalMap2::foreach_dart_of_oriented_face(Dart d, FunctorType& f, unsigned int thread) +{ + Dart dNext = d ; + do + { + if (f(dNext)) + return true ; + dNext = phi1(dNext) ; + } while (dNext != d) ; + return false ; +} + +inline bool ImplicitHierarchicalMap2::foreach_dart_of_face(Dart d, FunctorType& f, unsigned int thread) +{ + return foreach_dart_of_oriented_face(d, f) ; +} + +inline bool ImplicitHierarchicalMap2::foreach_dart_of_oriented_volume(Dart d, FunctorType& f, unsigned int thread) +{ + DartMarkerStore mark(*this); // Lock a marker + bool found = false; // Last functor return value + + std::list visitedFaces; // Faces that are traversed + visitedFaces.push_back(d); // Start with the face of d + std::list::iterator face; + + // For every face added to the list + for (face = visitedFaces.begin(); !found && face != visitedFaces.end(); ++face) + { + if (!mark.isMarked(*face)) // Face has not been visited yet + { + // Apply functor to the darts of the face + found = foreach_dart_of_oriented_face(*face, f); + + // If functor returns false then mark visited darts (current face) + // and add non visited adjacent faces to the list of face + if (!found) + { + Dart dNext = *face ; + do + { + mark.mark(dNext); // Mark + Dart adj = phi2(dNext); // Get adjacent face + if (adj != dNext && !mark.isMarked(adj)) + visitedFaces.push_back(adj); // Add it + dNext = phi1(dNext); + } while(dNext != *face); + } + } + } + return found; +} + +inline bool ImplicitHierarchicalMap2::foreach_dart_of_volume(Dart d, FunctorType& f, unsigned int thread) +{ + return foreach_dart_of_oriented_volume(d, f) ; +} + +inline bool ImplicitHierarchicalMap2::foreach_dart_of_cc(Dart d, FunctorType& f, unsigned int thread) +{ + return foreach_dart_of_oriented_volume(d, f) ; +} + +/*************************************************** + * MAP MANIPULATION * + ***************************************************/ + +inline void ImplicitHierarchicalMap2::splitFace(Dart d, Dart e) +{ + EmbeddedMap2::splitFace(d, e) ; + if(isOrbitEmbedded()) + { + unsigned int cur = m_curLevel ; + m_curLevel = m_maxLevel ; + this->setOrbitEmbedding(d, this->getEmbedding(d)) ; + this->setOrbitEmbedding(e, this->getEmbedding(e)) ; + m_curLevel = cur ; + } +} + +/*************************************************** + * LEVELS MANAGEMENT * + ***************************************************/ + +inline unsigned int ImplicitHierarchicalMap2::getCurrentLevel() +{ + return m_curLevel ; +} + +inline void ImplicitHierarchicalMap2::setCurrentLevel(unsigned int l) +{ + assert(l >= 0 || !"Trying to set current level to a negative value") ; + m_curLevel = l ; +} + +inline void ImplicitHierarchicalMap2::incCurrentLevel() +{ + if(m_curLevel < m_maxLevel) + ++m_curLevel ; + else + CGoGNout << "incCurrentLevel : already at maximum resolution level" << CGoGNendl ; +} + +inline void ImplicitHierarchicalMap2::decCurrentLevel() +{ + if(m_curLevel > 0) + --m_curLevel ; + else + CGoGNout << "decCurrentLevel : already at minimum resolution level" << CGoGNendl ; +} + +inline unsigned int ImplicitHierarchicalMap2::getMaxLevel() +{ + return m_maxLevel ; +} + +inline unsigned int ImplicitHierarchicalMap2::getDartLevel(Dart d) +{ + return m_dartLevel[d] ; +} + +inline void ImplicitHierarchicalMap2::setDartLevel(Dart d, unsigned int l) +{ + m_dartLevel[d] = l ; +} + +/*************************************************** + * EDGE ID MANAGEMENT * + ***************************************************/ + +inline unsigned int ImplicitHierarchicalMap2::getNewEdgeId() +{ + return m_idCount++ ; +} + +inline unsigned int ImplicitHierarchicalMap2::getEdgeId(Dart d) +{ + return m_edgeId[d] ; +} + +inline void ImplicitHierarchicalMap2::setEdgeId(Dart d, unsigned int i) +{ + m_edgeId[d] = i ; +} + +/*************************************************** + * CELLS INFORMATION * + ***************************************************/ + +inline unsigned int ImplicitHierarchicalMap2::vertexInsertionLevel(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + return m_dartLevel[d] ; +} + +inline unsigned int ImplicitHierarchicalMap2::edgeLevel(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + unsigned int ld = m_dartLevel[d] ; +// unsigned int ldd = m_dartLevel[phi2(d)] ; // the level of an edge is the maximum of the + unsigned int ldd = m_dartLevel[phi1(d)] ; + return ld < ldd ? ldd : ld ; // insertion levels of its two darts +} + +/*************************************************** + * ATTRIBUTE HANDLER * + ***************************************************/ + +template +T& AttributeHandler_IHM::operator[](Dart d) +{ + ImplicitHierarchicalMap2* m = reinterpret_cast(this->m_map) ; + assert(m->m_dartLevel[d] <= m->m_curLevel || !"Access to a dart introduced after current level") ; + assert(m->vertexInsertionLevel(d) <= m->m_curLevel || !"Access to the embedding of a vertex inserted after current level") ; + + unsigned int orbit = this->getOrbit() ; + unsigned int nbSteps = m->m_curLevel - m->vertexInsertionLevel(d) ; + unsigned int index = m->getEmbedding(d) ; + + if(index == EMBNULL) + { + index = m->setOrbitEmbeddingOnNewCell(d) ; + m->m_nextLevelCell[orbit]->operator[](index) = EMBNULL ; + } + + AttributeContainer& cont = m->getAttributeContainer() ; + unsigned int step = 0 ; + while(step < nbSteps) + { + step++ ; + unsigned int nextIdx = m->m_nextLevelCell[orbit]->operator[](index) ; + if (nextIdx == EMBNULL) + { + nextIdx = m->newCell() ; + m->copyCell(nextIdx, index) ; + m->m_nextLevelCell[orbit]->operator[](index) = nextIdx ; + m->m_nextLevelCell[orbit]->operator[](nextIdx) = EMBNULL ; + cont.refLine(index) ; + } + index = nextIdx ; + } + return this->m_attrib->operator[](index); +} + +template +const T& AttributeHandler_IHM::operator[](Dart d) const +{ + ImplicitHierarchicalMap2* m = reinterpret_cast(this->m_map) ; + assert(m->m_dartLevel[d] <= m->m_curLevel || !"Access to a dart introduced after current level") ; + assert(m->vertexInsertionLevel(d) <= m->m_curLevel || !"Access to the embedding of a vertex inserted after current level") ; + + unsigned int orbit = this->getOrbit() ; + unsigned int nbSteps = m->m_curLevel - m->vertexInsertionLevel(d) ; + unsigned int index = m->getEmbedding(d) ; + + unsigned int step = 0 ; + while(step < nbSteps) + { + step++ ; + unsigned int next = m->m_nextLevelCell[orbit]->operator[](index) ; + if(next != EMBNULL) index = next ; + else break ; + } + return this->m_attrib->operator[](index); +} + + +} //namespace CGoGN diff --git a/include/Topology/map/map3.h b/include/Topology/map/map3.h index 4349cbe087aa544852e2f0b87cdd642afd54c96e..d03aba562de4c9a4722a44bedbf616b45f2a2953 100644 --- a/include/Topology/map/map3.h +++ b/include/Topology/map/map3.h @@ -470,6 +470,8 @@ public: /*! */ void computeDual(); + + void computeDualTest(); //@} }; diff --git a/src/Topology/ihmap/ihm2.cpp b/src/Topology/ihmap/ihm2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d162698a619602b9bfb1865c30590f885e9dfa8e --- /dev/null +++ b/src/Topology/ihmap/ihm2.cpp @@ -0,0 +1,306 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; 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 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "Topology/ihmap/ihm2.h" +#include + +namespace CGoGN +{ + +ImplicitHierarchicalMap2::ImplicitHierarchicalMap2() : m_curLevel(0), m_maxLevel(0), m_idCount(0) +{ + m_dartLevel = Map2::addAttribute("dartLevel") ; + m_edgeId = Map2::addAttribute("edgeId") ; + for(unsigned int i = 0; i < NB_ORBITS; ++i) + m_nextLevelCell[i] = NULL ; +} + +ImplicitHierarchicalMap2::~ImplicitHierarchicalMap2() +{ + removeAttribute(m_edgeId) ; + removeAttribute(m_dartLevel) ; +} + +void ImplicitHierarchicalMap2::clear(bool removeAttrib) +{ + Map2::clear(removeAttrib) ; + if (removeAttrib) + { + m_dartLevel = Map2::addAttribute("dartLevel") ; + m_edgeId = Map2::addAttribute("edgeId") ; + + for(unsigned int i = 0; i < NB_ORBITS; ++i) + m_nextLevelCell[i] = NULL ; + } +} + +void ImplicitHierarchicalMap2::initImplicitProperties() +{ + initEdgeId() ; + + for(unsigned int orbit = 0; orbit < NB_ORBITS; ++orbit) + { + if(m_nextLevelCell[orbit] != NULL) + { + AttributeContainer& cellCont = m_attribs[orbit] ; + for(unsigned int i = cellCont.begin(); i < cellCont.end(); cellCont.next(i)) + m_nextLevelCell[orbit]->operator[](i) = EMBNULL ; + } + } +} + +void ImplicitHierarchicalMap2::initEdgeId() +{ + m_idCount = 0 ; + DartMarker edgeMark(*this) ; + for(Dart d = Map2::begin(); d != Map2::end(); Map2::next(d)) + { + if(!edgeMark.isMarked(d)) + { + edgeMark.markOrbit(d) ; + m_edgeId[d] = m_idCount ; + m_edgeId[Map2::phi2(d)] = m_idCount++ ; + } + } +} + +unsigned int ImplicitHierarchicalMap2::faceLevel(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + + if(m_curLevel == 0) + return 0 ; + +// unsigned int cur = m_curLevel ; +// Dart it = d ; +// Dart end = d ; +// bool resetEnd = true ; +// bool firstEdge = true ; +// do +// { +// if(!resetEnd) +// firstEdge = false ; +// +// unsigned int eId = m_edgeId[it] ; +// Dart next = it ; +// do +// { +// unsigned int l = edgeLevel(next) ; +// if(l < m_curLevel) +// m_curLevel = l ; +// else // l == curLevel +// { +// if(!firstEdge) +// { +// --m_curLevel ; +// next = it ; +// } +// } +// next = phi1(next) ; +// } while(m_edgeId[next] == eId) ; +// it = next ; +// +// if(resetEnd) +// { +// end = it ; +// resetEnd = false ; +// } +// +// } while(!firstEdge && it != end) ; +// +// unsigned int fLevel = m_curLevel ; +// m_curLevel = cur ; + + Dart it = d ; + Dart old = it ; + unsigned int l_old = m_dartLevel[old] ; + unsigned int fLevel = edgeLevel(it) ; + do + { + it = phi1(it) ; + unsigned int dl = m_dartLevel[it] ; + if(dl < l_old) // compute the oldest dart of the face + { // in the same time + old = it ; + l_old = dl ; + } // in a first time, the level of a face + unsigned int l = edgeLevel(it) ; // is the minimum of the levels + fLevel = l < fLevel ? l : fLevel ; // of its edges + } while(it != d) ; + + unsigned int cur = m_curLevel ; + m_curLevel = fLevel ; + + unsigned int nbSubd = 0 ; + it = old ; + unsigned int eId = m_edgeId[old] ; // the particular case of a face + do // with all neighboring faces regularly subdivided + { // but not the face itself + ++nbSubd ; // is treated here + it = phi1(it) ; + } while(m_edgeId[it] == eId) ; + + while(nbSubd > 1) + { + nbSubd /= 2 ; + --fLevel ; + } + + m_curLevel = cur ; + + return fLevel ; +} + +Dart ImplicitHierarchicalMap2::faceOrigin(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + unsigned int cur = m_curLevel ; + Dart p = d ; + unsigned int pLevel = m_dartLevel[p] ; + while(pLevel > 0) + { + p = faceOldestDart(p) ; + pLevel = m_dartLevel[p] ; + m_curLevel = pLevel ; + } + m_curLevel = cur ; + return p ; +} + +Dart ImplicitHierarchicalMap2::faceOldestDart(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + Dart it = d ; + Dart oldest = it ; + unsigned int l_old = m_dartLevel[oldest] ; + do + { + unsigned int l = m_dartLevel[it] ; + if(l == 0) + return it ; + if(l < l_old) +// if(l < l_old || (l == l_old && it < oldest)) + { + oldest = it ; + l_old = l ; + } + it = phi1(it) ; + } while(it != d) ; + return oldest ; +} + +bool ImplicitHierarchicalMap2::edgeIsSubdivided(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; +// Dart d2 = phi2(d) ; + Dart d1 = phi1(d) ; + ++m_curLevel ; +// Dart d2_l = phi2(d) ; + Dart d1_l = phi1(d) ; + --m_curLevel ; + if(d1 != d1_l) + return true ; + else + return false ; +} + +bool ImplicitHierarchicalMap2::edgeCanBeCoarsened(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + bool subd = false ; + bool subdOnce = true ; + bool degree2 = false ; + if(edgeIsSubdivided(d)) + { + subd = true ; + Dart d2 = phi2(d) ; + ++m_curLevel ; + if(vertexDegree(phi1(d)) == 2) + { + degree2 = true ; + if(edgeIsSubdivided(d) || edgeIsSubdivided(d2)) + subdOnce = false ; + } + --m_curLevel ; + } + return subd && degree2 && subdOnce ; +} + +bool ImplicitHierarchicalMap2::faceIsSubdivided(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + unsigned int fLevel = faceLevel(d) ; + if(fLevel < m_curLevel) + return false ; + + bool subd = false ; + ++m_curLevel ; + if(m_dartLevel[phi1(d)] == m_curLevel && m_edgeId[phi1(d)] != m_edgeId[d]) + subd = true ; + --m_curLevel ; + return subd ; +} + +bool ImplicitHierarchicalMap2::faceIsSubdividedOnce(Dart d) +{ + assert(m_dartLevel[d] <= m_curLevel || !"Access to a dart introduced after current level") ; + unsigned int fLevel = faceLevel(d) ; + if(fLevel < m_curLevel) // a face whose level in the current level map is lower than + return false ; // the current level can not be subdivided to higher levels + + unsigned int degree = 0 ; + bool subd = false ; + bool subdOnce = true ; + Dart fit = d ; + do + { + ++m_curLevel ; + if(m_dartLevel[phi1(fit)] == m_curLevel && m_edgeId[phi1(fit)] != m_edgeId[fit]) + { + subd = true ; + ++m_curLevel ; + if(m_dartLevel[phi1(fit)] == m_curLevel && m_edgeId[phi1(fit)] != m_edgeId[fit]) + subdOnce = false ; + --m_curLevel ; + } + --m_curLevel ; + ++degree ; + fit = phi1(fit) ; + } while(subd && subdOnce && fit != d) ; + + if(degree == 3 && subd) + { + ++m_curLevel ; + Dart cf = phi2(phi1(d)) ; + ++m_curLevel ; + if(m_dartLevel[phi1(cf)] == m_curLevel && m_edgeId[phi1(cf)] != m_edgeId[cf]) + subdOnce = false ; + --m_curLevel ; + --m_curLevel ; + } + + return subd && subdOnce ; +} + +} //namespace CGoGN diff --git a/src/Topology/map/map3.cpp b/src/Topology/map/map3.cpp index 8a808014aa8037666eaf8a6eeb414720e3f7040e..c9c13515a26c3a9b6aa741e6b1944917af0d0183 100644 --- a/src/Topology/map/map3.cpp +++ b/src/Topology/map/map3.cpp @@ -1234,40 +1234,171 @@ unsigned int Map3::closeMap() void Map3::reverseOrientation() { - DartAttribute emb0(this, getEmbeddingAttributeVector()) ; - if(emb0.isValid()) - { - DartAttribute new_emb0 = addAttribute("new_EMB_0") ; - for(Dart d = begin(); d != end(); next(d)) - new_emb0[d] = emb0[phi1(d)] ; - - swapAttributes(emb0, new_emb0) ; - removeAttribute(new_emb0) ; - } - DartAttribute n_phi1 = getAttribute("phi1") ; - DartAttribute n_phi_1 = getAttribute("phi_1") ; - swapAttributes(n_phi1, n_phi_1) ; } void Map3::computeDual() { - unsigned int count = 0; - CellMarkerNoUnmark cv(*this); - std::vector v; - for(Dart d = begin(); d != end(); next(d)) - { - if(!cv.isMarked(d) && isBoundaryMarked3(d)) + DartAttribute old_phi1 = getAttribute("phi1") ; + DartAttribute old_phi_1 = getAttribute("phi_1") ; + DartAttribute new_phi1 = addAttribute("new_phi1") ; + DartAttribute new_phi_1 = addAttribute("new_phi_1") ; + + DartAttribute old_phi2 = getAttribute("phi2") ; + DartAttribute new_phi2 = addAttribute("new_phi2") ; + + for(Dart d = begin(); d != end(); next(d)) + { + Dart dd = phi2(phi3(d)) ; + new_phi1[d] = dd ; + new_phi_1[dd] = d ; + + Dart ddd = phi1(phi3(d)); + new_phi2[d] = ddd; + new_phi2[ddd] = d; + } + + swapAttributes(old_phi1, new_phi1) ; + swapAttributes(old_phi_1, new_phi_1) ; + swapAttributes(old_phi2, new_phi2) ; + + removeAttribute(new_phi1) ; + removeAttribute(new_phi_1) ; + removeAttribute(new_phi2) ; + + swapEmbeddingContainers(VERTEX, VOLUME) ; + + unsigned int count = 0; + + for(Dart d = begin(); d != end(); next(d)) + { + if(isBoundaryMarked3(d)) + boundaryUnmark<3>(d); + + + if(d == 1569) { - ++count; - v.push_back(d); - cv.mark(d); + std::cout << "d " << std::endl; + + Traversor3WE t(*this,d); + for(Dart dit = t.begin() ; dit != t.end() ; dit = t.next()) + { + Dart temp = dit; + do + { + if(isBoundaryMarked3(d)) + std::cout << "d boundary " << std::endl; + + temp = alpha2(temp); + }while(temp != dit); + } + + if(isBoundaryMarked3(d)) + std::cout << "d boundary " << std::endl; + + if(isBoundaryMarked3(phi1(d))) + std::cout << "phi1(d) boundary " << std::endl; + + if(isBoundaryMarked3(phi_1(d))) + std::cout << "phi_1(d) boundary " << std::endl; + + if(isBoundaryMarked3(phi2(d))) + std::cout << "phi2(d) boundary " << std::endl; + + if(isBoundaryMarked3(phi3(d))) + std::cout << "phi3(d) boundary " << std::endl; + + if(isBoundaryMarked3(phi2(phi3(d)))) + std::cout << "phi2(phi3(d)) boundary " << std::endl; + + if(isBoundaryMarked3(phi3(phi2(d)))) + std::cout << "phi3(phi2(d)) boundary " << std::endl; + + if(isBoundaryMarked3(phi1(phi3(d)))) + std::cout << "phi1(phi3(d)) boundary " << std::endl; + + if(isBoundaryMarked3(phi3(phi1(d)))) + std::cout << "phi3(phi1(d)) boundary " << std::endl; } + + if(isBoundaryMarked3(d)) + { + +// if(isBoundaryMarked3(d)) +// std::cout << "d = " << d << std::endl; +// +// if(isBoundaryMarked3(phi3(d))) +// std::cout << "phi3(d) = " << phi3(d) << std::endl; +// +// if(isBoundaryMarked3(phi2(d))) +// std::cout << "phi2(d) = " << phi2(d) << std::endl; +// +// Dart dit = deleteVertex(phi3(d)); +// +// if(dit == NIL) +// std::cout << "NILLLLLLLLLLLLLLL" << std::endl; +// +// ++count; +// +// if(count == 5) +// return; } + } - cv.unmarkAll(); - std::cout << "boundary vertices : " << count << std::endl; +// TraversorW tW(*this); +// for(Dart d = tW.begin(); d != tW.end(); d = tW.next()) +// { +// if(isBoundaryMarked3(d)) +// { +// boundaryMarkOrbit(d); +// } +// } + +// unsigned int count = 0; +// for(Dart d = begin(); d != end(); next(d)) +// { +// if(isBoundaryMarked3(d)) +// { +// ++count; +// } +// } +// std::cout << "nb boundar marked = " << count << std::endl; +// +// count = 0; +// for(Dart d = begin(); d != end(); next(d)) +// { +// if(isBoundaryMarked3(d)) +// { +// ++count; +// std::cout << count << std::endl; +// //Map3::deleteVolume(d,false); +// //deleteVolume(d,false); +// } +// } + + + //std::cout << "Map closed (" << closeMap() <<" boundary faces)" << std::endl; +} + +void Map3::computeDualTest() +{ +// unsigned int count = 0; +// CellMarkerNoUnmark cv(*this); +// std::vector v; +// for(Dart d = begin(); d != end(); next(d)) +// { +// if(!cv.isMarked(d) && isBoundaryMarked3(d)) +// { +// ++count; +// v.push_back(d); +// cv.mark(d); +// } +// } +// +// cv.unmarkAll(); + +// std::cout << "boundary vertices : " << count << std::endl; DartAttribute old_phi1 = getAttribute("phi1") ; DartAttribute old_phi_1 = getAttribute("phi_1") ; @@ -1299,18 +1430,28 @@ void Map3::computeDual() swapEmbeddingContainers(VERTEX, VOLUME) ; -// reverseOrientation(); - - for(std::vector::iterator it = v.begin() ; it != v.end() ; ++it) + for(Dart d = begin(); d != end(); next(d)) + { + if(isBoundaryMarked3(d)) { - boundaryUnmarkOrbit(*it); + Map3::deleteVolume(d,false); } + } - for(std::vector::iterator it = v.begin() ; it != v.end() ; ++it) - { - deleteVolume(*it); - } + closeMap(); +// reverseOrientation(); +// +// for(std::vector::iterator it = v.begin() ; it != v.end() ; ++it) +// { +// boundaryUnmarkOrbit(*it); +// } +// +// for(std::vector::iterator it = v.begin() ; it != v.end() ; ++it) +// { +// Map3::deleteVolume(*it); +// } +// // std::cout << "boundary faces : " << closeMap() << std::endl; // //boundary management