From 924c5ab5a797e4502cad879ec2b83f595104685f Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Tue, 20 Mar 2012 14:58:25 +0100 Subject: [PATCH] add tuto for 3D base operator debug of collapseEdge of 3Map debug of splitVolume of 3Map --- Apps/Tuto/CMakeLists.txt | 7 + Apps/Tuto/tuto_oper3.cpp | 466 ++++++++++++++++++++++++ Apps/Tuto/tuto_oper3.h | 122 +++++++ Apps/Tuto/tuto_oper3.ui | 140 +++++++ include/Algo/MC/marchingcube.hpp | 26 +- include/Algo/Render/GL2/topo3Render.hpp | 12 +- include/Algo/Render/GL2/topoRender.hpp | 7 +- include/Topology/map/embeddedMap3.h | 2 +- include/Topology/map/map3.h | 22 +- src/Topology/map/embeddedMap3.cpp | 8 +- src/Topology/map/map2.cpp | 4 +- src/Topology/map/map3.cpp | 193 +++++++--- 12 files changed, 929 insertions(+), 80 deletions(-) create mode 100644 Apps/Tuto/tuto_oper3.cpp create mode 100644 Apps/Tuto/tuto_oper3.h create mode 100644 Apps/Tuto/tuto_oper3.ui diff --git a/Apps/Tuto/CMakeLists.txt b/Apps/Tuto/CMakeLists.txt index bc4d7231..520bdcf2 100644 --- a/Apps/Tuto/CMakeLists.txt +++ b/Apps/Tuto/CMakeLists.txt @@ -58,6 +58,13 @@ QT4_WRAP_CPP(tuto_oper2_moc tuto_oper2.h) add_executable( tuto_oper2 tuto_oper2.cpp ${tuto_oper2_ui} ${tuto_oper2_moc}) target_link_libraries( tuto_oper2 ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS} ) + +QT4_WRAP_UI( tuto_oper3_ui tuto_oper3.ui ) +QT4_WRAP_CPP(tuto_oper3_moc tuto_oper3.h) +add_executable( tuto_oper3 tuto_oper3.cpp ${tuto_oper3_ui} ${tuto_oper3_moc}) +target_link_libraries( tuto_oper3 + ${CGoGN_LIBS_D} ${CGoGN_EXT_LIBS} ) + QT4_WRAP_UI( tuto_orbits_ui tuto_orbits.ui ) QT4_WRAP_CPP(tuto_orbits_moc tuto_orbits.h) diff --git a/Apps/Tuto/tuto_oper3.cpp b/Apps/Tuto/tuto_oper3.cpp new file mode 100644 index 00000000..d36514c5 --- /dev/null +++ b/Apps/Tuto/tuto_oper3.cpp @@ -0,0 +1,466 @@ +/******************************************************************************* +* 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 "tuto_oper3.h" +#include "Algo/Geometry/boundingbox.h" +#include "Algo/Modelisation/polyhedron.h" +#include "Algo/Modelisation/primitives3d.h" +#include "Algo/Geometry/centroid.h" +#include "Algo/Import/import.h" +#include "Algo/Export/export.h" + +using namespace CGoGN ; + + +int main(int argc, char **argv) +{ + // // interface + QApplication app(argc, argv); + MyQT sqt; + + + sqt.setDock(& sqt.dock); + sqt.setCallBack( sqt.dock.listOper, SIGNAL(currentRowChanged(int)), SLOT(operation(int)) ); + sqt.setCallBack( sqt.dock.svg, SIGNAL(clicked()), SLOT(svg()) ); + sqt.setCallBack( sqt.dock.widthSlider, SIGNAL(valueChanged(int)), SLOT(width(int)) ); + int n=3; + if (argc==2) + n = atoi(argv[1]); + + // example code itself + sqt.createMap(n); + + sqt.width(5); + + // set help message in menu + sqt.setHelpMsg("First Tuto: \nCreate two faces\nsew them\nand affect positions"); + // final show for redraw + sqt.show(); + // and wait for the end + return app.exec(); +} + + +void MyQT::operation(int x) +{ + switch(x) + { + case 0: + CGoGNout <<"delete vertex"<setCurrentRow(-1); +} + +void MyQT::createMap(int n) +{ + myMap.clear(true); + position = myMap.getAttribute(VERTEX, "position"); + if (!position.isValid()) + position = myMap.addAttribute(VERTEX, "position"); + Algo::Modelisation::Primitive3D prim(myMap, position); + prim.hexaGrid_topo(n,n,n); + prim.embedHexaGrid(1.0f,1.0f,1.0f); + + // bounding box of scene + Geom::BoundingBox bb = Algo::Geometry::computeBoundingBox(myMap, position) ; + setParamObject(bb.maxSize(), bb.center().data()) ; + m_shift = bb.maxSize()/200.0f; + + // first show for be sure that GL context is binded + show(); + + // render the topo of the map without boundary darts + + m_render_topo->setDartWidth(3.0f); + m_render_topo->setInitialDartsColor(0.0f,0.0f,0.0f); + m_render_topo->updateData(myMap, position, m_ex1,m_ex2,m_ex3, nb); + + +} + + + +void MyQT::updateMap() +{ + m_render_topo->updateData(myMap, position, m_ex1,m_ex2,m_ex3, nb); +} + +// initialization GL callback +void MyQT::cb_initGL() +{ + glClearColor(1.0f,1.0f,1.0f,1.0f); + m_render_topo = new Algo::Render::GL2::Topo3Render() ; +} + +// redraw GL callback (clear and swap already done) +void MyQT::cb_redraw() +{ + glEnable( GL_POLYGON_OFFSET_FILL ); + glPolygonOffset( 1.0f, 1.0f ); + + m_render_topo->drawTopo(); + + glDisable( GL_POLYGON_OFFSET_FILL ); + + if (m_selected != NIL) + m_render_topo->overdrawDart(m_selected, 11, 1.0f, 0.0f, 0.0f); + + if (m_selected2 != NIL) + m_render_topo->overdrawDart(m_selected2, 11, 0.0f, 1.0f, 0.0f); + + for (std::vector::iterator it = m_selecteds.begin(); it != m_selecteds.end(); ++it) + { + m_render_topo->overdrawDart(*it, 11, 0.0f, 0.0f, 1.0f); + } +} + +void MyQT::cb_mousePress(int button, int x, int y) +{ + if (Shift()) + { + Dart d = m_render_topo->picking(myMap, x,y, nb); + if (button == Qt::LeftButton) + { + if (d != Dart::nil()) + m_selected = d; + } + if (button == Qt::RightButton) + { + if (d != Dart::nil()) + m_selected2 = d; + } + updateGL(); + } + + if (Control()) + { + Dart d = m_render_topo->picking(myMap, x,y, nb); + if (button == Qt::LeftButton) + { + if (d != Dart::nil()) + m_selecteds.push_back(d); + } + updateGL(); + } + +} + +void MyQT::cb_keyPress(int keycode) +{ + switch(keycode) + { + + case ' ': + m_selecteds.clear(); + m_selected=NIL; + m_selected2=NIL; + updateGL(); + break; + case '2': + createMap(2); + updateMap(); + updateGL(); + break; + case '3': + createMap(3); + updateMap(); + updateGL(); + break; + case '4': + createMap(4); + updateMap(); + updateGL(); + break; + + + case 'a': + m_selected = myMap.phi1(m_selected); + updateGL(); + break; + case 'z': + m_selected = myMap.phi_1(m_selected); + updateGL(); + break; + case 'e': + m_selected = myMap.phi2(m_selected); + updateGL(); + break; + case 'r': + m_selected = myMap.phi3(m_selected); + updateGL(); + break; + + case 'q': + m_selected2 = myMap.phi1(m_selected2); + updateGL(); + break; + case 's': + m_selected2 = myMap.phi_1(m_selected2); + updateGL(); + break; + case 'd': + m_selected2 = myMap.phi2(m_selected2); + updateGL(); + break; + case 'f': + m_selected2 = myMap.phi3(m_selected2); + updateGL(); + break; + + case 'w': + m_ex1 = 0.99f; + m_ex2 = 0.99f; + m_render_topo->updateData(myMap, position, m_ex1,m_ex2,m_ex3, nb); + updateGL(); + break; + case 'W': + m_ex1 = 0.9f; + m_ex2 = 0.9f; + m_render_topo->updateData(myMap, position, m_ex1,m_ex2,m_ex3, nb); + updateGL(); + break; + +// case 'c': +// for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d)) +// { +// if (!myMap.isBoundaryMarked(d)) +// { +// int n = random(); +// float r = float(n&0x7f)/255.0f + 0.25f; +// float g = float((n>>8)&0x7f)/255.0f + 0.25f; +// float b = float((n>>16)&0x7f)/255.0 + 0.25f; +// colorDarts[d] = Geom::Vec3f(r,g,b); +// m_render_topo->setDartColor(d,r,g,b); +// } +// } +// break; +// case 'g': +// for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d)) +// { +// if (!myMap.isBoundaryMarked(d)) +// { +// colorDarts[d] = Geom::Vec3f(0.5f,0.5f,0.5f); +// m_render_topo->setDartColor(d,0.5f,0.5f,0.5f); +// } +// } +// break; +// +// case 'b': +// for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d)) +// { +// if (!myMap.isBoundaryMarked(d)) +// { +// colorDarts[d] = Geom::Vec3f(0.0f,0.0f,0.0f); +// m_render_topo->setDartColor(d,0.0f,0.0f,0.0f); +// } +// } +// break; + case Qt::Key_Up: + if (m_selected!=NIL) + position[m_selected][1] +=m_shift; + updateMap(); + updateGL(); + break; + case Qt::Key_Down: + if (m_selected!=NIL) + position[m_selected][1] -= m_shift; + updateMap(); + updateGL(); + break; + case Qt::Key_Left: + if (m_selected!=NIL) + position[m_selected][0] -= m_shift; + updateMap(); + updateGL(); + break; + case Qt::Key_Right: + if (m_selected!=NIL) + position[m_selected][0] += m_shift; + updateMap(); + updateGL(); + break; + } + updateGL(); +} + +void MyQT::svg() +{ + if (m_selected!=NIL) + m_render_topo->setDartColor(m_selected,0.8f,0.0f,0.0f); + if (m_selected2!=NIL) + m_render_topo->setDartColor(m_selected2,0.0f,0.8f,0.0f); + + std::string filename = selectFileSave("snapshot file", ".", "(*.svg)"); + m_render_topo->svgout2D(filename, modelViewMatrix(),projectionMatrix()); +} + +void MyQT::cb_Open() +{ + std::string filters("all (*.*);; trian (*.trian);; off (*.off);; ply (*.ply);; map (*.map)") ; + std::string filename = selectFile("Open Mesh", "", filters) ; + if (!filename.empty()) + importMesh(filename); + updateGL(); +} + +void MyQT::cb_Save() +{ + std::string filename = selectFileSave("Export SVG file ",".","(*.off)"); + Algo::Export::exportOFF(myMap,position,filename.c_str()); +} + +void MyQT::importMesh(std::string& filename) +{ + myMap.clear(true) ; + + size_t pos = filename.rfind("."); // position of "." in filename + std::string extension = filename.substr(pos); + + if (extension == std::string(".map")) + { + myMap.loadMapBin(filename); + position = myMap.getAttribute(VERTEX, "position") ; + } + else + { + std::vector attrNames ; + if(!Algo::Import::importMesh(myMap, filename.c_str(), attrNames)) + { + CGoGNerr << "could not import " << filename << CGoGNendl ; + return; + } + position = myMap.getAttribute(VERTEX, attrNames[0]) ; + } + + m_selected = NIL; + m_selected2 = NIL; + + Geom::BoundingBox bb = Algo::Geometry::computeBoundingBox(myMap, position) ; + setParamObject(bb.maxSize(), bb.center().data()) ; + m_shift = bb.maxSize()/200.0f; + + updateMap(); + updateGLMatrices() ; +} + + +void MyQT::width(int w) +{ + m_ex3 = 0.9f - 0.025f*w; + m_render_topo->updateData(myMap, position, m_ex1,m_ex2,m_ex3, nb); + updateGL(); +} + diff --git a/Apps/Tuto/tuto_oper3.h b/Apps/Tuto/tuto_oper3.h new file mode 100644 index 00000000..5d491a5d --- /dev/null +++ b/Apps/Tuto/tuto_oper3.h @@ -0,0 +1,122 @@ +/******************************************************************************* +* 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 _TUTO_OPER3_ +#define _TUTO_OPER3_ + +//#define USE_GMAP + + +#include "Topology/generic/parameters.h" + +#ifdef USE_GMAP + #include "Topology/gmap/embeddedGMap3.h" +#else + #include "Topology/map/embeddedMap3.h" +#endif + +#include "Algo/Render/GL2/topo3Render.h" + + +#include "ui_tuto_oper3.h" +#include "Utils/Qt/qtui.h" +#include "Utils/Qt/qtSimple.h" +#include "Utils/cgognStream.h" + + +using namespace CGoGN ; + +/** + * Struct that contains some informations about the types of the manipulated objects + * Mainly here to be used by the algorithms that are parameterized by it + */ +struct PFP: public PFP_STANDARD +{ + // definition of the type of the map +#ifdef USE_GMAP + typedef EmbeddedGMap3 MAP; +#else + typedef EmbeddedMap3 MAP; +#endif +}; + + + +class MyQT: public Utils::QT::SimpleQT +{ + Q_OBJECT +public: + MyQT():nb(myMap),m_render_topo(NULL),m_selected(NIL),m_selected2(NIL),dm(myMap),m_shift(0.01f),m_ex1(0.9f),m_ex2(0.9f),m_ex3(0.9f) {} + + void cb_redraw(); + void cb_initGL(); + void cb_mousePress(int button, int x, int y); + void cb_keyPress(int code); + void cb_Open(); + void cb_Save(); + + Utils::QT::uiDockInterface dock; + +protected: + // declaration of the map + PFP::MAP myMap; + + PFP::TVEC3 position; +// AttributeHandler colorDarts; + + SelectorDartNoBoundary nb; + + // render (for the topo) + Algo::Render::GL2::Topo3Render* m_render_topo; + Dart m_selected; + Dart m_selected2; + std::vector m_selecteds; + DartMarker dm; + float m_shift; + + float m_ex1,m_ex2,m_ex3; + + // just for more compact writing + inline Dart PHI1(Dart d) {return myMap.phi1(d);} + inline Dart PHI_1(Dart d) {return myMap.phi_1(d);} + inline Dart PHI2(Dart d) {return myMap.phi2(d);} + inline Dart PHI3(Dart d) {return myMap.phi3(d);} + template + Dart PHI(Dart d) {return myMap.phi(d);} + +public: + // example of simple map creation + void createMap(int n); + void updateMap(); + void importMesh(std::string& filename); + +public slots: + void operation(int x); + void svg(); + void width(int w); +}; + + + +#endif diff --git a/Apps/Tuto/tuto_oper3.ui b/Apps/Tuto/tuto_oper3.ui new file mode 100644 index 00000000..b76aa1bf --- /dev/null +++ b/Apps/Tuto/tuto_oper3.ui @@ -0,0 +1,140 @@ + + + DockWidget + + + + 0 + 0 + 227 + 369 + + + + + 150 + 250 + + + + Interface + + + + true + + + + 0 + 0 + + + + + 150 + 200 + + + + + 2 + + + 4 + + + + + + + Qt::NoFocus + + + + deleteVertex + + + + + cutEdge + + + + + uncutEdge + + + + + deleteEdge + + + + + collapsedge + + + + + splitFace + + + + + mergeVolume + + + + + splitVolume + + + + + + + + 0 + + + 10 + + + 2 + + + 1 + + + Qt::Horizontal + + + + + + + SnapshotSVG + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + diff --git a/include/Algo/MC/marchingcube.hpp b/include/Algo/MC/marchingcube.hpp index 13884286..b8279fb6 100644 --- a/include/Algo/MC/marchingcube.hpp +++ b/include/Algo/MC/marchingcube.hpp @@ -105,20 +105,16 @@ template< typename DataType, template < typename D2 > class Windowing, typename Dart MarchingCube::createTriEmb(unsigned int e1, unsigned int e2, unsigned int e3) { L_DART d = m_map->newFace(3,false); - //TODO change this which work only with 2-maps -// m_map->setDartEmbedding(VERTEX,d,e1); d = m_map->phi1(d); -// m_map->setDartEmbedding(VERTEX,d,e2); d = m_map->phi1(d); -// m_map->setDartEmbedding(VERTEX,d,e3); d = m_map->phi1(d); - FunctorSetEmb fsetemb(*m_map, VERTEX, e1); - m_map->foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb); - d = m_map->phi1(d); - fsetemb.changeEmb(e2); - m_map->foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb); - d = m_map->phi1(d); - fsetemb.changeEmb(e3); - m_map->foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb); - d = m_map->phi1(d); + FunctorSetEmb fsetemb(*m_map, VERTEX, e1); + m_map->foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb); + d = m_map->phi1(d); + fsetemb.changeEmb(e2); + m_map->foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb); + d = m_map->phi1(d); + fsetemb.changeEmb(e3); + m_map->foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb); + d = m_map->phi1(d); return d; } @@ -220,11 +216,11 @@ void MarchingCube::simpleMeshing() ucData = m_Image->getVoxelPtr(lX,lY,lZ); createFaces_7(ucData++,lX++,lY,lZ,16); // TAG - while (lX < lTxm) + while (lX < lTxm-1) { createFaces_8(ucData++,lX++,lY,lZ,0); } - createFaces_8(ucData++,lX++,lY,lZ,32); //TAG + createFaces_8(ucData++,lX,lY,lZ,32); //TAG lY++; } diff --git a/include/Algo/Render/GL2/topo3Render.hpp b/include/Algo/Render/GL2/topo3Render.hpp index 318e739c..95542075 100644 --- a/include/Algo/Render/GL2/topo3Render.hpp +++ b/include/Algo/Render/GL2/topo3Render.hpp @@ -69,11 +69,10 @@ void Topo3Render::updateDataMap3(typename PFP::MAP& mapx, const typename PFP::TV if (m_attIndex.map() != &mapx) - { m_attIndex = mapx.template getAttribute(DART, "dart_index"); - if (!m_attIndex.isValid()) - m_attIndex = mapx.template addAttribute(DART, "dart_index"); - } + + if (!m_attIndex.isValid()) + m_attIndex = mapx.template addAttribute(DART, "dart_index"); m_nbDarts = 0; for (Dart d = mapx.begin(); d != mapx.end(); mapx.next(d)) @@ -332,13 +331,10 @@ void Topo3Render::updateDataGMap3(typename PFP::MAP& mapx, const typename PFP::T typedef typename PFP::VEC3 VEC3; typedef typename PFP::REAL REAL; - if (m_attIndex.map() != &mapx) - { m_attIndex = mapx.template getAttribute(DART, "dart_index"); - if (!m_attIndex.isValid()) + if (!m_attIndex.isValid()) m_attIndex = mapx.template addAttribute(DART, "dart_index"); - } m_nbDarts = 0; for (Dart d = mapx.begin(); d != mapx.end(); mapx.next(d)) diff --git a/include/Algo/Render/GL2/topoRender.hpp b/include/Algo/Render/GL2/topoRender.hpp index acc43b60..03ad1408 100644 --- a/include/Algo/Render/GL2/topoRender.hpp +++ b/include/Algo/Render/GL2/topoRender.hpp @@ -67,7 +67,8 @@ void TopoRender::updateDataMap(typename PFP::MAP& mapx, const typename PFP::TVEC std::vector vecDarts; vecDarts.reserve(map.getNbDarts()); // no problem dart is int: no problem of memory - m_attIndex = map.template getAttribute(DART, "dart_index"); + if (m_attIndex.map() != &map) + m_attIndex = map.template getAttribute(DART, "dart_index"); if (!m_attIndex.isValid()) m_attIndex = map.template addAttribute(DART, "dart_index"); @@ -212,7 +213,9 @@ void TopoRender::updateDataGMap(typename PFP::MAP& mapx, const typename PFP::TVE std::vector vecDarts; vecDarts.reserve(map.getNbDarts()); // no problem dart is int: no problem of memory - m_attIndex = map.template getAttribute(DART, "dart_index"); + if (m_attIndex.map() != &map) + m_attIndex = map.template getAttribute(DART, "dart_index"); + if (!m_attIndex.isValid()) m_attIndex = map.template addAttribute(DART, "dart_index"); diff --git a/include/Topology/map/embeddedMap3.h b/include/Topology/map/embeddedMap3.h index 01433560..416edeaa 100644 --- a/include/Topology/map/embeddedMap3.h +++ b/include/Topology/map/embeddedMap3.h @@ -71,7 +71,7 @@ public: //! /*! */ - virtual bool collapseDegeneratedFace(Dart d); +// virtual bool collapseDegeneratedFace(Dart d); //! /*! diff --git a/include/Topology/map/map3.h b/include/Topology/map/map3.h index 01c135fc..13c139d8 100644 --- a/include/Topology/map/map3.h +++ b/include/Topology/map/map3.h @@ -155,6 +155,12 @@ public: */ virtual bool uncutEdge(Dart d); + + /** + * Precondition for deleting edge + */ + bool deleteEdgePreCond(Dart d); + //! Delete the edge of d /*! All the volumes around the edge are merged into one volume * @param d a dart of the edge to delete @@ -176,7 +182,14 @@ public: * @param d a dart of the face * @return true if the collapse has been executed, false otherwise */ - virtual bool collapseDegeneratedFace(Dart d); +// virtual bool collapseDegeneratedFace(Dart d); + + //! Split Face Pre-condition + /*! + * @param d dart of first vertex + * @param e dart of second vertex + */ + bool splitFacePreCond(Dart d, Dart e); //! Split a face inserting an edge between two vertices /*! \pre Dart d and e should belong to the same face and be distinct @@ -193,6 +206,10 @@ public: */ bool collapseDegeneretedVolume(Dart d); + //!! sewVolumes Pre-condition + bool sewVolumesPreCond(Dart d, Dart e); + + //! Sew two oriented volumes along their faces. /*! The oriented faces should not be phi3-linked and have the same degree * @param d a dart of the first volume @@ -201,6 +218,9 @@ public: */ virtual void sewVolumes(Dart d, Dart e, bool withBoundary = true); + //! Unsew volumes pre-condition + bool unsewVolumesPreCond(Dart d); + //! Unsew two oriented volumes along their faces. /*! @param d a dart of one volume */ diff --git a/src/Topology/map/embeddedMap3.cpp b/src/Topology/map/embeddedMap3.cpp index d94e527a..c46fb742 100644 --- a/src/Topology/map/embeddedMap3.cpp +++ b/src/Topology/map/embeddedMap3.cpp @@ -154,10 +154,10 @@ Dart EmbeddedMap3::collapseEdge(Dart d, bool delDegenerateVolumes) return resV; } -bool EmbeddedMap3::collapseDegeneratedFace(Dart d) -{ - return Map3::collapseDegeneratedFace(d); -} +//bool EmbeddedMap3::collapseDegeneratedFace(Dart d) +//{ +// return Map3::collapseDegeneratedFace(d); +//} void EmbeddedMap3::splitFace(Dart d, Dart e) { diff --git a/src/Topology/map/map2.cpp b/src/Topology/map/map2.cpp index 84794e44..de49a817 100644 --- a/src/Topology/map/map2.cpp +++ b/src/Topology/map/map2.cpp @@ -538,10 +538,10 @@ void Map2::splitSurface(std::vector& vd, bool firstSideClosed, bool second unsewFaces(*it) ; if(firstSideClosed) - fillHole(e) ; + Map2::fillHole(e) ; if(secondSideClosed) - fillHole(e2) ; + Map2::fillHole(e2) ; } /*! @name Topological Queries diff --git a/src/Topology/map/map3.cpp b/src/Topology/map/map3.cpp index efeab657..fb65d452 100644 --- a/src/Topology/map/map3.cpp +++ b/src/Topology/map/map3.cpp @@ -234,8 +234,17 @@ bool Map3::uncutEdge(Dart d) return false; } +bool Map3::deleteEdgePreCond(Dart d) +{ + unsigned int nb1 = vertexDegree(d); + unsigned int nb2 = vertexDegree(phi1(d)); + return (nb1!=2) && (nb2!=2); +} + Dart Map3::deleteEdge(Dart d) { + assert(deleteEdgePreCond(d)); + if(isBoundaryEdge(d)) return NIL ; @@ -270,41 +279,65 @@ Dart Map3::deleteEdge(Dart d) return res ; } +//Dart Map3::collapseEdge(Dart d, bool delDegenerateVolumes) +//{ +// Dart resV = NIL; +// +// Dart dit = d; +// +// do +// { +// Dart e = dit; +// dit = alpha2(dit); +// +// //test si un seul polyedre autour de l'arete +// if(e == dit) +// resV == phi3(phi2(phi1(e))); +// +// if(delDegenerateVolumes) +// { +// Map2::collapseEdge(e, true); +// collapseDegeneretedVolume(e); +// } +// else +// Map2::collapseEdge(e, false); +// +// if(resV == NIL) +// { +// +// } +// +// }while(d != dit); +// +// return resV; +//} + Dart Map3::collapseEdge(Dart d, bool delDegenerateVolumes) { Dart resV = NIL; - Dart dit = d; + std::vector darts; do { - Dart e = dit; + darts.push_back(dit); dit = alpha2(dit); + }while(dit != d); - //test si un seul polyedre autour de l'arete - if(e == dit) - resV == phi3(phi2(phi1(e))); - - if(delDegenerateVolumes) - { - Map2::collapseEdge(e, true); - collapseDegeneretedVolume(e); - } - else - Map2::collapseEdge(e, false); - - if(resV == NIL) - { - - } - - }while(d != dit); + for (std::vector::iterator it = darts.begin(); it != darts.end(); ++it) + { + Dart x = phi2(phi_1(*it)); + resV = Map2::collapseEdge(*it, true); + if (delDegenerateVolumes) + collapseDegeneretedVolume(x); + } return resV; } + // Dart e = d; // // // stocke un brin par volume autour de l'arete @@ -355,22 +388,44 @@ Dart Map3::collapseEdge(Dart d, bool delDegenerateVolumes) // } // } -bool Map3::collapseDegeneratedFace(Dart d) +//bool Map3::collapseDegeneratedFace(Dart d) +//{ +// Dart d3 = phi3(d); +// +// std::cout << "Map3::collapseDegeneratedFace"<< std::endl; +// +// if (!isDartValid(d)) +// Map2::collapseDegeneratedFace(d); +// else +// std::cout << "Warning Coll1 invalid"<< std::endl; +// +// +// if (isDartValid(d3)) +// Map2::collapseDegeneratedFace(d3); +// else +// std::cout << "Warning coll2 invalid"<< std::endl; +// +// +// +///* +// Map3::unsewVolumes(d); +// +// std::cout << Map2::collapseDegeneratedFace(d) << std::endl; +// std::cout << Map2::collapseDegeneratedFace(d3) << std::endl; +// std::cout << std::endl; +//*/ +// return true; +//} + +bool Map3::splitFacePreCond(Dart d, Dart e) { - Dart d3 = phi3(d); - - Map3::unsewVolumes(d); - - std::cout << Map2::collapseDegeneratedFace(d) << std::endl; - std::cout << Map2::collapseDegeneratedFace(d3) << std::endl; - std::cout << std::endl; - - return true; + return (d != e && sameOrientedFace(d, e)) ; } void Map3::splitFace(Dart d, Dart e) { - assert(d != e && sameOrientedFace(d, e)) ; +// assert(d != e && sameOrientedFace(d, e)) ; + assert(splitFacePreCond(d,e)); Dart dd = phi1(phi3(d)); Dart ee = phi1(phi3(e)); @@ -382,31 +437,69 @@ void Map3::splitFace(Dart d, Dart e) phi3sew(phi_1(e), phi_1(dd)); } +//bool Map3::collapseDegeneretedVolume(Dart d) +//{ +// Dart e1 = phi2(d); +// Dart e2 = phi2(phi1(d)); +// +// //Si les deux faces ne sont pas du bord +// if(!isBoundaryFace(e1) && !isBoundaryFace(e2)) +// { +// sewVolumes(phi3(e1),phi3(e2)); +// deleteVolume(d); +// return true; +// } +// else +// { +// //alors simple suppression du volume degenere +// deleteVolume(d); +// return true; +// } +// +// return false; +//} + bool Map3::collapseDegeneretedVolume(Dart d) { - Dart e1 = phi2(d); - Dart e2 = phi2(phi1(d)); + Dart e1 = d; + Dart e2 = phi2(d); - //Si les deux faces ne sont pas du bord - if(!isBoundaryFace(e1) && !isBoundaryFace(e2)) + do { - sewVolumes(phi3(e1),phi3(e2)); - deleteVolume(d); - return true; - } - else + if (e1 != phi2(e2)) + return false; + e1 = phi1(e1); + e2 = phi_1(e2); + }while (e1 != d); + + if (e2 != phi2(d)) + return false; + + // degenerated: + do { - //alors simple suppression du volume degenere - deleteVolume(d); - return true; - } + Dart f1 = phi3(e1); + Dart f2 = phi3(e2); + phi3unsew(e1); + phi3unsew(e2); + phi3sew(f1,f2); + e1 = phi1(e1); + e2 = phi_1(e2); + }while (e1 != d); - return false; + Map2::deleteCC(d) ; + return true; +} + + +bool Map3::sewVolumesPreCond(Dart d, Dart e) +{ + return (faceDegree(d) == faceDegree(e)); } void Map3::sewVolumes(Dart d, Dart e, bool withBoundary) { - assert(faceDegree(d) == faceDegree(e)); + assert(sewVolumesPreCond(d,e)); // if sewing with fixed points if (!withBoundary) @@ -456,9 +549,15 @@ void Map3::sewVolumes(Dart d, Dart e, bool withBoundary) } while(fitD != d) ; } +bool Map3::unsewVolumesPreCond(Dart d) +{ + return (!isBoundaryFace(d)) ; +} + + void Map3::unsewVolumes(Dart d) { - assert(!isBoundaryFace(d)) ; + assert(unsewVolumesPreCond(d)) ; unsigned int nbE = faceDegree(d) ; Dart d3 = phi3(d); -- GitLab