diff --git a/Apps/Examples/Tests/CMakeLists.txt b/Apps/Examples/Tests/CMakeLists.txt index e22e213882f0248565036d3763658691329e8e64..d28323b63ca8cb74de45ebc27bbb9a52da82f11a 100644 --- a/Apps/Examples/Tests/CMakeLists.txt +++ b/Apps/Examples/Tests/CMakeLists.txt @@ -25,6 +25,7 @@ include_directories( ${CGoGN_ROOT_DIR}/ThirdParty/AntTweakBar/include ${CGoGN_ROOT_DIR}/ThirdParty/OpenCTM ${CGoGN_ROOT_DIR}/ThirdParty/Assimp/include + ${CGoGN_ROOT_DIR}/ThirdParty/glm ) # define libs path @@ -46,3 +47,9 @@ target_link_libraries( Geom_inclusionD add_executable( Geom_intersectionD ./Geom_intersection.cpp) target_link_libraries( Geom_intersectionD ${CGoGN_LIBS_D} ${COMMON_LIBS} ) + + +QT4_WRAP_CPP(concave_rendering_moc concave_rendering.h) +add_executable( concave_renderingD concave_rendering.cpp ${concave_rendering_moc}) +target_link_libraries( concave_renderingD + ${CGoGN_LIBS_D} ${COMMON_LIBS} ${QT_LIBRARIES} ) diff --git a/Apps/Examples/Tests/concave_rendering.cpp b/Apps/Examples/Tests/concave_rendering.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6bf2f89b2d0011459a4de9f58d9705aef782bcc --- /dev/null +++ b/Apps/Examples/Tests/concave_rendering.cpp @@ -0,0 +1,426 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2011, 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.u-strasbg.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "concave_rendering.h" + +#include + +#include "Topology/generic/parameters.h" +#include "Topology/map/map2.h" +#include "Topology/generic/embeddedMap2.h" +#include "Geometry/vector_gen.h" + +#include "Algo/Import/import.h" +#include "Algo/Geometry/boundingbox.h" + +#include "Algo/Render/GL2/mapRender.h" +#include "Utils/Shaders/shaderSimpleColor.h" + +#include + +#include "Algo/Render/SVG/mapSVGRender.h" + + +using namespace CGoGN ; + + + +float Ifont[74*2]={ +0.145434,0.126469, 0.141475,0.096252, 0.133621,0.0730446, 0.120846,0.0558913, +0.0764256,0.0359233, 0,0.028701, 0,0.0215257, 0,0.0143506, 0,0.00717529, 0,0, + +0.0560801,0, 0.11216,0, 0.16824,0, 0.22432,0, 0.2804,0, 0.33648,0, 0.39256,0, +0.448641,0, 0.448641,0.00717529, 0.448641,0.0143506, 0.448641,0.0215257, 0.448641,0.028701, +0.406716,0.0313208, 0.373254,0.0363483, 0.347367,0.0446329, 0.328172,0.0570242, +0.314784,0.0743722, 0.306316,0.0975264, 0.301885,0.127337, 0.300604,0.164653, +0.300604,0.248489, 0.300604,0.332326, 0.300604,0.416163, 0.300604,0.5, +0.300604,0.583837, 0.300604,0.667674, 0.300604,0.751511, 0.300604,0.835347, +0.301761,0.872601, 0.305891,0.902261, 0.313987,0.925229, 0.327039,0.942409, +0.371979,0.963015, 0.448641,0.971299, 0.448641,0.978474, 0.448641,0.98565, + 0.448641,0.992825, 0.448641,1, 0.39256,1, 0.33648,1, 0.2804,1, 0.22432,1, +0.11216,1, 0,1, 0,0.992825, 0,0.98565, 0,0.978474, 0,0.971299, +0.0431605,0.967874, 0.0770629,0.96259, 0.102787,0.954438, 0.121412,0.942409, +0.134019,0.925495, 0.141687,0.902686, 0.145496,0.872973, 0.146526,0.835347, +0.146526,0.751511, 0.146526,0.667674, 0.146526,0.583837, 0.146526,0.5, +0.146526,0.416163, 0.146526,0.332326, 0.146526,0.248489, 0.146526,0.164653}; + + +float Gfont[174*2]={ +0.934964,0.533333, 0.888768,0.533333, 0.842572,0.533333, 0.796377,0.533333, + 0.703986,0.533333, 0.611594,0.533333, + 0.611594,0.526812, 0.611594,0.52029, +0.611594,0.513768, 0.611594,0.507246, +0.632945,0.505602, 0.650611,0.503872, 0.665118,0.501973, 0.676993,0.499819, +0.686761,0.497325, 0.69495,0.494407, 0.702086,0.490979, 0.708696,0.486957, +0.716245,0.481097, 0.722622,0.473234, 0.727879,0.463264, 0.732065,0.451087, +0.735233,0.4366, 0.737432,0.419701, 0.738714,0.400289, 0.73913,0.378261, +0.73913,0.348913, 0.73913,0.319565, 0.73913,0.290217, 0.73913,0.26087, +0.73913,0.231522, 0.73913,0.202174, 0.73913,0.172826, 0.73913,0.143478, +0.735128,0.126489, 0.723686,0.110553, 0.705656,0.0960427, 0.681884,0.0833333, +0.653221,0.0727978, 0.620516,0.0648098, 0.584618,0.0597429, 0.546377,0.057971, +0.462175,0.0655967, 0.38716,0.0879982, 0.321963,0.124462, 0.26721,0.174275, +0.223531,0.236725, 0.191553,0.311096, 0.171906,0.396677, 0.165217,0.492754, +0.167085,0.543526, 0.172554,0.593229, 0.18142,0.641199, 0.193478,0.686775, +0.208526,0.729294, 0.226359,0.768093, 0.246773,0.802511, 0.269565,0.831884, +0.294667,0.857006, 0.322011,0.879053, 0.351393,0.897942, 0.382609,0.913587, +0.415455,0.925903, 0.449728,0.934805, 0.485224,0.940209, 0.521739,0.942029, +0.55169,0.940744, 0.580639,0.936911, 0.608534,0.930565, 0.635326,0.921739, +0.660963,0.910468, 0.685394,0.896784, 0.708568,0.880723, 0.730435,0.862319, +0.745853,0.84707, 0.75976,0.831363, 0.772546,0.814603, 0.784601,0.796196, +0.796317,0.775546, 0.808084,0.752061, 0.820293,0.725144, 0.833333,0.694203, + 0.841667,0.694203, 0.85,0.694203, + 0.858333,0.694203, 0.866667,0.694203, +0.865217,0.732428, 0.863768,0.770652, 0.862319,0.808877, 0.86087,0.847101, +0.85942,0.885326, 0.857971,0.923551, 0.856522,0.961775, 0.855072,1, + 0.847101,1, 0.83913,1, + 0.831159,1, 0.823188,1, +0.819138,0.990039, 0.813609,0.98091, 0.806757,0.972767, 0.798732,0.965761, +0.789688,0.960046, 0.779778,0.955774, 0.769155,0.953099, 0.757971,0.952174, +0.75214,0.95238, 0.745562,0.953012, 0.738304,0.954085, 0.730435,0.955616, +0.722022,0.957623, 0.713134,0.960122, 0.703838,0.963131, 0.694203,0.966667, +0.669684,0.97434, 0.645063,0.981046, 0.620375,0.986767, 0.595652,0.991485, +0.570929,0.995185, 0.546241,0.997849, 0.52162,0.999459, 0.497101,1, +0.392522,0.990268, 0.297147,0.962092, 0.212438,0.917001, 0.139855,0.856522, +0.0808595,0.782184, 0.0369112,0.695516, 0.00947117,0.598047, 0,0.491304, +0.00183978,0.439586, 0.00738215,0.390874, 0.016661,0.345049, 0.0297101,0.301993, +0.0465636,0.261586, 0.0672554,0.223709, 0.0918195,0.188244, 0.12029,0.155072, +0.15863,0.119698, 0.200657,0.0886549, 0.246114,0.0620613, 0.294746,0.0400362, +0.3463,0.0226987, 0.400521,0.0101675, 0.457153,0.00256171, 0.515942,0, +0.56498,0.00227868, 0.61721,0.00871821, 0.670527,0.0187244, 0.722826,0.0317028, +0.771999,0.047059, 0.815942,0.0641983, 0.852548,0.0825265, 0.87971,0.101449, +0.87971,0.138225, 0.87971,0.175, 0.87971,0.211775, 0.87971,0.248551, +0.87971,0.285326, 0.87971,0.322101, 0.87971,0.358877, 0.87971,0.395652, +0.880621,0.4247, 0.883741,0.448143, 0.889646,0.466627, 0.898913,0.480797, +0.912121,0.491299, 0.929846,0.498777, 0.952666,0.503878, 0.981159,0.507246, + 0.981159,0.513768, 0.981159,0.52029, + 0.981159,0.526812, 0.981159,0.533333}; + +/** + * 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 + typedef EmbeddedMap2 MAP; +}; + +// declaration of the map +PFP::MAP myMap; +// and attribute of position +AttributeHandler position; + +unsigned int nb_ears; + +void MyQT::cb_initGL() +{ + // choose to use GL version 2 + Utils::GLSLShader::setCurrentOGLVersion(2); + + // create the render + m_render = new Algo::Render::GL2::MapRender(); + + // create VBO for position + m_positionVBO = new Utils::VBO(); + + // using simple shader with color + m_shader = new Utils::ShaderSimpleColor(); + m_shader->setAttributePosition(m_positionVBO); + m_shader->setColor(Geom::Vec4f(0.0f, 1.0f, 0.0f, 0.0f)); + registerShader(m_shader); + + nb_ears = 0; +} + +void MyQT::cb_redraw() +{ + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + if (m_shader) + { + glPointSize(3.0f); + m_shader->setColor(Geom::Vec4f(0.,1.,1.,0.)); + m_render->draw(m_shader, Algo::Render::GL2::POINTS); + glEnable(GL_POLYGON_OFFSET_FILL); + glLineWidth(2.0f); + glPolygonOffset(0.6f, 0.6f); + m_shader->setColor(Geom::Vec4f(1.,1.,0.,0.)); + m_render->draw(m_shader, Algo::Render::GL2::LINES); + + glPolygonOffset(0.8f, 0.8f); + m_shader->setColor(Geom::Vec4f(1.0,0.,0.,0.)); + glLineWidth(1.0f); + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + m_render->drawSub(m_shader, Algo::Render::GL2::TRIANGLES, nb_ears); + + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + m_shader->setColor(Geom::Vec4f(0.,1.,0.,0.)); + nb_ears = m_render->drawSub(m_shader, Algo::Render::GL2::TRIANGLES, nb_ears); + + glDisable(GL_POLYGON_OFFSET_FILL); + } +} + +void MyQT::cb_keyPress(int code) +{ + if (code == '+') + { + nb_ears++; + // born sup dans drawing + updateGL(); + } + + if (code == '-') + { + if (nb_ears>=1) + nb_ears--; + updateGL(); + } + + if (code == 'n') + { + nb_ears=0; + updateGL(); + } + + if (code == 'a') + { + nb_ears=99999999; + updateGL(); + } + +} + +int main(int argc, char **argv) +{ + + position = myMap.addAttribute(VERTEX, "position"); + + + Dart d0 = myMap.newFace(12); + position[d0] = PFP::VEC3(0, 20, 0); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(10, 20, 0); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(10, 30, 0); + Dart dx = myMap.phi1(d0); + d0 = myMap.phi<11>(dx); + position[d0] = PFP::VEC3(8, 27, 0); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(8, 22, 0); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(2, 22, 0); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(2, 27, 0); + d0 = myMap.phi1(d0); + myMap.sewFaces(d0,dx); + position[d0] = PFP::VEC3(5, 27, 0); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(5, 30, 0); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(0, 30, 0); + d0 = myMap.phi1(d0); + + + d0 = myMap.newFace(4); + position[d0] = PFP::VEC3(-5, 14, -5); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(0, 18, -5); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(5, 14, -5); + d0 = myMap.phi1(d0); + position[d0] = PFP::VEC3(0, 20, -5); + d0 = myMap.phi1(d0); + + + + Dart d1 = myMap.newFace(10); + + position[d1] = PFP::VEC3(0, 0, 0); + d1 = myMap.phi1(d1); + + position[d1] = PFP::VEC3(2, 4, 0); + d1 = myMap.phi1(d1); + position[d1] = PFP::VEC3(4, 0, 0); + d1 = myMap.phi1(d1); + + position[d1] = PFP::VEC3(10, 0, 0); + d1 = myMap.phi1(d1); + + position[d1] = PFP::VEC3(4, 2, 0); + d1 = myMap.phi1(d1); + position[d1] = PFP::VEC3(14, 6, 0); + d1 = myMap.phi1(d1); + position[d1] = PFP::VEC3(6, 16, 0); + d1 = myMap.phi1(d1); + + position[d1] = PFP::VEC3(8, 8, 0); + d1 = myMap.phi1(d1); + position[d1] = PFP::VEC3(4, 4, 0); + d1 = myMap.phi1(d1); + position[d1] = PFP::VEC3(0, 8, 0); + + + Dart d2 = myMap.newFace(12); + + position[d2] = PFP::VEC3(0, -20, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(4, -20, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(8, -20, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(12, -20, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(12, -16, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(12, -12, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(12, -8, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(8, -8, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(4, -8, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(0, -8, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(0, -12, 0); + d2 = myMap.phi1(d2); + position[d2] = PFP::VEC3(0, -16, 0); + d2 = myMap.phi1(d2); + + + +#define NB 32 + + //SPIRAL + + Dart d3 = myMap.newFace(NB*2); + + for (int i = 0; i=0; --i) + { + float z = 3.0f*float(rand()-RAND_MAX/2)/float(RAND_MAX); + float alpha = (4.0f*6.283f / NB)*i; + float radius = (NB-i); + position[d3] = PFP::VEC3(radius*cos(alpha) - 2*NB+8, radius*sin(alpha), z); + d3 = myMap.phi1(d3); + } + + + //CIRCLE + + Dart d6 = myMap.newFace(NB); + for (int i = 0; i bb = Algo::Geometry::computeBoundingBox(myMap, position); + float lWidthObj = std::max(std::max(bb.size(0), bb.size(1)), bb.size(2)); + Geom::Vec3f lPosObj = (bb.min() + bb.max()) / PFP::REAL(2); + + // envoit info BB a l'interface + sqt.setParamObject(lWidthObj, lPosObj.data()); + + // show 1 pour GL context + sqt.show(); + + // update du VBO position (context GL necessaire) + sqt.m_positionVBO->updateData(position); + + // update des primitives du renderer + SelectorTrue allDarts; + sqt.m_render->initPrimitives(myMap, allDarts, Algo::Render::GL2::TRIANGLES); + sqt.m_render->initPrimitives(myMap, allDarts, Algo::Render::GL2::LINES); + + // show final pour premier redraw + sqt.show(); + + // et on attend la fin. + return app.exec(); +} diff --git a/Apps/Examples/Tests/concave_rendering.h b/Apps/Examples/Tests/concave_rendering.h new file mode 100644 index 0000000000000000000000000000000000000000..73f3d63f6f75cb184d843e89e024e484efa86244 --- /dev/null +++ b/Apps/Examples/Tests/concave_rendering.h @@ -0,0 +1,75 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2011, 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.u-strasbg.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef _TUTO1_ +#define _TUTO1_ + +#include + +#include "Utils/qtSimple.h" +#include "Utils/cgognStream.h" + +// forward definitions (minimize includes) +namespace CGoGN { namespace Algo { namespace Render { namespace GL2 { class MapRender; } } } } +namespace CGoGN { namespace Utils { class VBO; } } +namespace CGoGN { namespace Utils { class ShaderSimpleColor; } } + +using namespace CGoGN ; + +/** + * A class for a little interface and rendering + */ +class MyQT : public Utils::QT::SimpleQT +{ + Q_OBJECT + +public: + // render + Algo::Render::GL2::MapRender* m_render; + + // VBO + Utils::VBO* m_positionVBO; + + // shader basic + Utils::ShaderSimpleColor* m_shader; + + MyQT() : m_render(NULL), m_positionVBO(NULL), m_shader(NULL) + {} + + // callbacks of simpleQT to overdefine: + void cb_initGL(); + + void cb_redraw(); + + void cb_keyPress(int code); + + void cb_New() { CGoGNout << "New ..." << CGoGNendl; } + void cb_Save() { CGoGNout << "Rien a sauver ..." << CGoGNendl; } + + // callbacks (slots) locally defined +public slots: + void menu_slot1() { CGoGNout << "Exemple de menu" << CGoGNendl; } +}; + +#endif diff --git a/include/Algo/Geometry/normal.hpp b/include/Algo/Geometry/normal.hpp index f8c24bd2eab3f104e568671d8b53ac9bc37e07d3..97924cfa7a84a1afdbba3b831200f85851bb6e38 100644 --- a/include/Algo/Geometry/normal.hpp +++ b/include/Algo/Geometry/normal.hpp @@ -50,6 +50,27 @@ typename PFP::VEC3 triangleNormal(typename PFP::MAP& map, Dart d, const typename return N ; } + +template +typename PFP::VEC3 newellNormal(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position) +{ + Dart e=d; + typename PFP::VEC3 normal(0); + do + { + const typename PFP::VEC3& P = position[e]; + e = map.phi1(e); + const typename PFP::VEC3& Q = position[e]; + normal[0] += (P[1]-Q[1])*(P[2]+Q[2]); + normal[1] += (P[2]-Q[2])*(P[0]+Q[0]); + normal[2] += (P[0]-Q[0])*(P[1]+Q[1]); + }while (e !=d); + + normal.normalize(); + + return normal; +} + template typename PFP::VEC3 faceNormal(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position) { diff --git a/include/Algo/Render/GL2/mapRender.h b/include/Algo/Render/GL2/mapRender.h index df8ed8155d66d0653d383f94794537b45ac18973..d31a0413db14c0c72ccdcc2778391e5751097caa 100644 --- a/include/Algo/Render/GL2/mapRender.h +++ b/include/Algo/Render/GL2/mapRender.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "Topology/generic/dart.h" @@ -89,6 +90,50 @@ protected: typedef std::pair buffer_array; + // forward declaration + class VertexPoly; + + // comparaison function for multiset + static bool cmpVP(VertexPoly* lhs, VertexPoly* rhs); + + // multiset typedef for simple writing + typedef std::multiset< VertexPoly*,bool(*)(VertexPoly*,VertexPoly*)> VPMS; + + class VertexPoly + { + public: + int id; + float value; + VertexPoly* prev; + VertexPoly* next; + VPMS::iterator ear; + + VertexPoly(int i, float v, VertexPoly* p=NULL): id(i),value(v), prev(p), next(NULL) + { + if (prev!=NULL) + prev->next = this; + } + + static void close(VertexPoly* first, VertexPoly* last) + { + last->next = first; + first->prev = last; + } + + static VertexPoly* erase(VertexPoly* vp) + { + VertexPoly* tmp = vp->prev; + tmp->next = vp->next; + vp->next->prev = tmp; + vp->value = 20.0f; //?? + delete vp; + return tmp; + } + + }; + + + public: /** * Constructor @@ -109,6 +154,7 @@ public: buffer_array get_nb_index_buffer() { return std::make_pair(m_nbIndices, SIZE_BUFFER); } protected: + /** * addition of indices table of one triangle * @param d a dart of the triangle @@ -117,6 +163,22 @@ protected: template void addTri(typename PFP::MAP& map, Dart d, std::vector& tableIndices) ; + template + inline void addEarTri(typename PFP::MAP& map, Dart d, std::vector& tableIndices); + +// template +// float computeEarAngle(AttributeHandler& position, const typename PFP::VEC3& normalPoly, unsigned int i, unsigned int j, unsigned int k); + + template + float computeEarAngle(const typename PFP::VEC3& P1, const typename PFP::VEC3& P2, const typename PFP::VEC3& P3, const typename PFP::VEC3& normalPoly); + + template + bool computeEarIntersection(AttributeHandler& position, VertexPoly* vp, const typename PFP::VEC3& normalPoly); + + template + void recompute2Ears( AttributeHandler& position, VertexPoly* vp, const typename PFP::VEC3& normalPoly, VPMS& ears, bool convex); + + public: /** * creation of indices table of triangles (optimized order) @@ -162,6 +224,8 @@ public: * draw the VBO (function to call in the drawing callback) */ void draw(Utils::GLSLShader* sh, int prim) ; + + unsigned int drawSub(Utils::GLSLShader* sh, int prim, unsigned int nb_elm); } ; } // namespace GL2 diff --git a/include/Algo/Render/GL2/mapRender.hpp b/include/Algo/Render/GL2/mapRender.hpp index b3d6eb57977fa50cbb290c642cbbfe2726fd0847..754fd8bd20d44b69b5b5dc9f6cf8394d318586f1 100644 --- a/include/Algo/Render/GL2/mapRender.hpp +++ b/include/Algo/Render/GL2/mapRender.hpp @@ -26,6 +26,10 @@ #include "Topology/generic/cellmarker.h" #include "Utils/vbo.h" +#include "Topology/generic/attributeHandler.h" +#include "Geometry/intersection.h" +#include "Algo/Geometry/normal.h" + namespace CGoGN { @@ -38,6 +42,230 @@ namespace Render namespace GL2 { + +inline bool MapRender::cmpVP(VertexPoly* lhs, VertexPoly* rhs) +{ + return lhs->value < rhs->value; +} + + +template +void MapRender::recompute2Ears( AttributeHandler& position, VertexPoly* vp, const typename PFP::VEC3& normalPoly, VPMS& ears, bool convex) +{ + VertexPoly* vprev = vp->prev; + VertexPoly* vp2 = vp->next; + VertexPoly* vnext = vp2->next; + const typename PFP::VEC3& Ta = position[vp->id]; + const typename PFP::VEC3& Tb = position[vp2->id]; + const typename PFP::VEC3& Tc = position[vprev->id]; + const typename PFP::VEC3& Td = position[vnext->id]; + + // compute angle + typename PFP::VEC3 v1= Tb - Ta; + typename PFP::VEC3 v2= Tc - Ta; + typename PFP::VEC3 v3= Td - Tb; + + v1.normalize(); + v2.normalize(); + v3.normalize(); + + float dotpr1 = 1.0f - (v1*v2); + float dotpr2 = 1.0f + (v1*v3); + + if (!convex) // if convex no need to test if vertex is an ear (yes) + { + typename PFP::VEC3 nv1 = v1^v2; + typename PFP::VEC3 nv2 = v1^v3; + + if (nv1*normalPoly < 0.0) + dotpr1 = 10.0f - dotpr1;// not an ears (concave) + if (nv2*normalPoly < 0.0) + dotpr2 = 10.0f - dotpr2;// not an ears (concave) + + bool finished = false; + for (VPMS::reverse_iterator it = ears.rbegin(); (!finished)&&(it != ears.rend())&&((*it)->value > 5.0f); ++it) + { + int id = (*it)->id; + const typename PFP::VEC3& P = position[id]; +// typename PFP::VEC3 inter; + + if ((dotpr1 != 5.0f) && (id !=vprev->id)) + if (Geom::intersectionRayTriangleOpt(P, normalPoly, Ta,Tb,Tc) > Geom::VERTEX_INTERSECTION) + + + dotpr1 = 5.0f;// not an ears ! + + if ((dotpr2 != 5.0f) && (id !=vnext->id) ) + if (Geom::intersectionRayTriangleOpt(P, normalPoly, Tb,Td,Ta) > Geom::VERTEX_INTERSECTION) + dotpr2 = 5.0f;// not an ears ! + + finished = ((dotpr1 == 5.0f)&&(dotpr2 == 5.0f)); + } + } + + vp->value = dotpr1; + vp->ear = ears.insert(vp); + vp2->value = dotpr2; + vp2->ear = ears.insert(vp2); +} + + +template +float MapRender::computeEarAngle(const typename PFP::VEC3& P1, const typename PFP::VEC3& P2, const typename PFP::VEC3& P3, const typename PFP::VEC3& normalPoly) +{ + typename PFP::VEC3 v1 = P1-P2; + typename PFP::VEC3 v2 = P3-P2; + v1.normalize(); + v2.normalize(); + + float dotpr = 1.0f - (v1*v2); + + typename PFP::VEC3 vn = v1^v2; + if (vn*normalPoly > 0.0f) + dotpr = 10.0f - dotpr; // not an ears (concave, store at the end for optimized use for intersections) + + return dotpr; +} + + +template +bool MapRender::computeEarIntersection(AttributeHandler& position, VertexPoly* vp, const typename PFP::VEC3& normalPoly) +{ + VertexPoly* endV = vp->prev; + VertexPoly* curr = vp->next; + const typename PFP::VEC3& Ta = position[vp->id]; + const typename PFP::VEC3& Tb = position[curr->id]; + const typename PFP::VEC3& Tc = position[endV->id]; + curr = curr->next; + + while (curr != endV) + { +// typename PFP::VEC3 inter; + Geom::Intersection res = Geom::intersectionRayTriangleOpt(position[curr->id], normalPoly, Ta,Tb,Tc); + if (res > Geom::VERTEX_INTERSECTION) + { + vp->value = 5.0f;// not an ears ! + return false; + } + curr = curr->next; + } + + return true; +} + + +template +inline void MapRender::addEarTri(typename PFP::MAP& map, Dart d, std::vector& tableIndices) +{ + + bool(*fn_pt)(VertexPoly*,VertexPoly*) = &(MapRender::cmpVP); + VPMS ears(fn_pt); + + AttributeHandler position = map.template getAttribute(VERTEX,"position"); + + // compute normal to polygon + typename PFP::VEC3 normalPoly = Algo::Geometry::newellNormal(map, d, position); + + // first pass create polygon in chained list witht angle computation + VertexPoly* vpp=NULL; + VertexPoly* prem=NULL; + unsigned int nbv = 0; + unsigned int nbe = 0; + Dart a = d; + Dart b = map.phi1(a); + Dart c = map.phi1(b); + do + { +// typename PFP::VEC3 v1= position[map.getEmbedding(VERTEX,a)]-position[map.getEmbedding(VERTEX,b)]; +// typename PFP::VEC3 v2= position[map.getEmbedding(VERTEX,c)]-position[map.getEmbedding(VERTEX,b)]; +// typename PFP::VEC3 v3= position[map.getEmbedding(VERTEX,c)]-position[map.getEmbedding(VERTEX,a)]; + typename PFP::VEC3 P1= position[map.getEmbedding(VERTEX,a)]; + typename PFP::VEC3 P2= position[map.getEmbedding(VERTEX,b)]; + typename PFP::VEC3 P3= position[map.getEmbedding(VERTEX,c)]; + + float val = computeEarAngle(P1,P2,P3,normalPoly); + VertexPoly* vp = new VertexPoly(map.getEmbedding(VERTEX,b),val,vpp); + if (vp->value <5.0f) + nbe++; + if (vpp==NULL) + prem = vp; + vpp = vp; + a = b; + b = c; + c = map.phi1(c); + nbv++; + }while (a!=d); + + VertexPoly::close(prem,vpp); + +// bool convex = nbe==nbv; + bool convex = false; + if (convex) + { + // second pass with no test of intersections with polygons + vpp = prem; + for (unsigned int i=0; i< nbv; ++i) + { + vpp->ear = ears.insert(vpp); + vpp = vpp->next; + } + } + else + { + // second pass test intersections with polygons + vpp = prem; + for (unsigned int i=0; i< nbv; ++i) + { + if (vpp->value <5.0f) + { + computeEarIntersection(position,vpp,normalPoly); + } + vpp->ear = ears.insert(vpp); + vpp = vpp->next; + } + } + +// DBG: AFF ears +// for (std::multimap< float, VertexPoly* >::iterator it = ears.begin(); it != ears.end(); ++it ) +// std::cout << it->first <<" , "<< it->second->id<<" , "<< it->second->value<< " / "; +// std::cout << std::endl; + + // NO WE HAVE THE POLYGON AND EARS + // LET'S REMOVE THEM + while (nbv>3) + { + // take best (and valid!) ear + VPMS::iterator be_it = ears.begin(); // best ear is big value cos -> last in map + VertexPoly* be = *be_it; + + tableIndices.push_back(be->id); + tableIndices.push_back(be->next->id); + tableIndices.push_back(be->prev->id); + + //remove 3 ears + ears.erase(be_it); // from map of ears + ears.erase(be->next->ear); + ears.erase(be->prev->ear); + + be = VertexPoly::erase(be); // and remove ear vertex from polygon + nbv--; + + if (nbv>3) // do not recompute if only one triangle left + recompute2Ears(position,be,normalPoly,ears,convex); + else // finish + { + tableIndices.push_back(be->id); + tableIndices.push_back(be->next->id); // last triangle + tableIndices.push_back(be->prev->id); + // release memory of last triangle in polygon + delete be->next; + delete be->prev; + delete be; + } + } +} + + template inline void MapRender::addTri(typename PFP::MAP& map, Dart d, std::vector& tableIndices) { @@ -45,6 +273,12 @@ inline void MapRender::addTri(typename PFP::MAP& map, Dart d, std::vector(map, d, tableIndices); //TODO version optimisee pour 4 cotes ? + return; + } + // loop to cut a polygon in triangle on the fly (works only with convex faces) do { diff --git a/include/Geometry/intersection.h b/include/Geometry/intersection.h index de6105e60b8df5d1842ade534cbb7805173b799b..c0b593c47c0c260e91235106cb74051b728d0736 100644 --- a/include/Geometry/intersection.h +++ b/include/Geometry/intersection.h @@ -59,11 +59,59 @@ Intersection intersectionLinePlane(const VEC3& P, const VEC3& Dir, const VEC3& P /** - * test the intersection between a ray and a triangle + * test the intersection between a ray and a triangle (optimized version with triple product + * @param P a point on the line + * @param Dir line direction + * @param Ta triangle point 1 + * @param Tb triangle point 2 + * @param Tc triangle point 3 + * @param Inter store the intersection point + * @return the intersection ( FACE_INTERSECTION / EDGE_INTERSECTION / VERTEX_INTERSECTION / NO_INTERSECTION) */ template Intersection intersectionRayTriangle(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter) ; +/** + * test the intersection between a ray and a triangle (optimized version with triple product + * @param P a point on the line + * @param Dir line direction + * @param Ta triangle point 1 + * @param Tb triangle point 2 + * @param Tc triangle point 3 + * @param Inter store the intersection point + * @return the intersection ( FACE_INTERSECTION / EDGE_INTERSECTION / VERTEX_INTERSECTION / NO_INTERSECTION) + */ +template +Intersection intersectionRayTriangleOpt(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter); + + + +/** + * test the intersection between a ray and a triangle (optimized version with triple product + * @param P a point on the line + * @param Dir line direction + * @param Ta triangle point 1 + * @param Tb triangle point 2 + * @param Tc triangle point 3 + * @return the intersection ( FACE_INTERSECTION / EDGE_INTERSECTION / VERTEX_INTERSECTION / NO_INTERSECTION) + */ +template +Intersection intersectionRayTriangleOpt(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc); + + +/** + * test the intersection between a ray and a triangle, but test only face intersection and + * @param P a point on the line + * @param Dir line direction + * @param Ta triangle point 1 + * @param Tb triangle point 2 + * @param Tc triangle point 3 + * @param Inter store the intersection point + * @return the intersection ( FACE_INTERSECTION / EDGE_INTERSECTION / VERTEX_INTERSECTION / NO_INTERSECTION) + */ +//template +//Intersection intersectionRayTriangleFaceOnly(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc) + /** * test the intersection between a line and a triangle * @param P a point on the line diff --git a/include/Geometry/intersection.hpp b/include/Geometry/intersection.hpp index 97f55a4ce133adfe8b874acbd7f9d3b067e62434..785b641a19991a4e283ca0b19b03c172e1a8b404 100644 --- a/include/Geometry/intersection.hpp +++ b/include/Geometry/intersection.hpp @@ -52,6 +52,146 @@ Intersection intersectionLinePlane(const VEC3& P, const VEC3& Dir, const VEC3& P } +//template +//Intersection intersectionRayTriangleFaceOnly(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc) +//{ +// typedef typename VEC3::DATA_TYPE T ; +// +// VEC3 u = Ta - P ; +// VEC3 v = Tb - P ; +// VEC3 w = Tc - P ; +// T x = tripleProduct(Dir, u, v) ; +// T y = tripleProduct(Dir, v, w) ; +// T z = tripleProduct(Dir, w, u) ; +// if((x < T(0) && y < T(0) && z < T(0)) || (x > T(0) && y > T(0) && z > T(0))) +// return FACE_INTERSECTION ; +// return NO_INTERSECTION ; +//} + + +template +Intersection intersectionRayTriangleOpt(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter) +{ + typedef typename VEC3::DATA_TYPE T ; + + VEC3 u = Ta - P ; + VEC3 v = Tb - P ; + VEC3 w = Tc - P ; + + T x = tripleProduct(Dir, u, v) ; + T y = tripleProduct(Dir, v, w) ; + T z = tripleProduct(Dir, w, u) ; + + unsigned int np=0; + unsigned int nn=0; + unsigned int nz=0; + + if (x>T(0)) + ++np; + else + if (xT(0)) + ++np; + else + if (yT(0)) + ++np; + else + if (z +Intersection intersectionRayTriangleOpt(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc) +{ + typedef typename VEC3::DATA_TYPE T ; + + VEC3 u = Ta - P ; + VEC3 v = Tb - P ; + VEC3 w = Tc - P ; + + T x = tripleProduct(Dir, u, v) ; + T y = tripleProduct(Dir, v, w) ; + T z = tripleProduct(Dir, w, u) ; + + unsigned int np=0; + unsigned int nn=0; + unsigned int nz=0; + + if (x>T(0)) + ++np; + else + if (xT(0)) + ++np; + else + if (yT(0)) + ++np; + else + if (z Intersection intersectionRayTriangle(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter) diff --git a/include/Utils/pickables.h b/include/Utils/pickables.h index e700c2a51bd07837bf67d90f9f32da8d34acab54..4df92b4d6291a4b8ff3b4eee2df1ba1a637ac7e8 100644 --- a/include/Utils/pickables.h +++ b/include/Utils/pickables.h @@ -104,10 +104,11 @@ public: * picking * @param P camera point * @param V vector ray direction + * @param I intersection point (out) for Z sorting * @param epsilon distance epsilon for picking * @return code picking (0: nothing picked / != 0 something picked) */ - virtual unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon=0.0f) = 0; + virtual unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon=0.0f) = 0; /** * update the precision of drawing @@ -153,10 +154,11 @@ public: * picking * @param P camera point * @param V vector ray direction + * @param I intersection point (out) for Z sorting * @param epsilon distance epsilon for picking -// * @return picked ? + * @return picked */ - bool pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon=0.0f); + bool pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon=0.0f); /** * apply inverse transfo on picking ray @@ -280,7 +282,7 @@ public: /** * picking */ - unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon=0.0f); + unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon=0.0f); /** * return a string with shape of object @@ -323,7 +325,7 @@ public: /** * picking */ - unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon=0.0f); + unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon=0.0f); /** * return a string with shape of object @@ -360,7 +362,7 @@ public: /** * picking */ - unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon=0.0f); + unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon=0.0f); /** * return a string with shape of object @@ -397,7 +399,7 @@ public: /** * picking */ - unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon=0.0f); + unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon=0.0f); /** * return a string with shape of object @@ -441,7 +443,7 @@ public: /** * picking */ - unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon=0.0f); + unsigned int pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon=0.0f); /** * return a string with shape of object diff --git a/include/Utils/qtInputs.h b/include/Utils/qtInputs.h index be655d09e3d2012d953f7227d6dba3b836abdd7e..d5021d968eec70634d19ec82586da5098219054c 100644 --- a/include/Utils/qtInputs.h +++ b/include/Utils/qtInputs.h @@ -114,6 +114,26 @@ public: void updateFrom(QWidget* widg) const; }; + +/** + * Class for double input in dialog window (with spinbox) + * Use: VarBool(min,max,ref_to_val, "label" [,nextVar]) + */ +class VarFloat: public Var +{ +public: + float m_min; + float m_max; + float& m_val; + +public: + VarFloat(float min, float max, float& val, const std::string& label); + VarFloat(float min, float max, float& val, const std::string& label, const Var& var); + QWidget* createInput() const; + void updateFrom(QWidget* widg) const; +}; + + /** * Class for integer input in dialog window (with slider) * Use: VarBool(min,max,ref_to_val, "label" [,nextVar]) diff --git a/include/Utils/text3d.frag b/include/Utils/text3d.frag index 658a2ae763732b657aec70e639702fd3976ce9cc..98d0ed5d4acf2b31f53f92502bdfc0320a45d641 100644 --- a/include/Utils/text3d.frag +++ b/include/Utils/text3d.frag @@ -7,4 +7,4 @@ FRAG_OUT_DEF; void main (void) { float lum = texture2D(FontTexture, tex_coord).s;; -// no "}" because it is added in the shader class code (with other things) +// no } because it is added in the shader class code (with other things) diff --git a/src/Algo/Render/mapRender.cpp b/src/Algo/Render/mapRender.cpp index 2467598a3c23daa7e4eb32bf4c9cc52fbf2be4c6..a6418fdad551c00ccd6024606398bd4743d59b59 100644 --- a/src/Algo/Render/mapRender.cpp +++ b/src/Algo/Render/mapRender.cpp @@ -37,6 +37,7 @@ namespace Render namespace GL2 { + MapRender::MapRender() { glGenBuffersARB(4, m_indexBuffers) ; @@ -103,6 +104,40 @@ void MapRender::draw(Utils::GLSLShader* sh, int prim) sh->disableVertexAttribs(); } + +unsigned int MapRender::drawSub(Utils::GLSLShader* sh, int prim, unsigned int nb_elm) +{ + sh->enableVertexAttribs(); + switch(prim) + { + case POINTS: + if (nb_elm > m_nbIndices[POINT_INDICES]) + nb_elm = m_nbIndices[POINT_INDICES]; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[POINT_INDICES]); + glDrawElements(GL_POINTS, nb_elm, GL_UNSIGNED_INT, 0) ; + + break; + case LINES: + if (2*nb_elm > m_nbIndices[LINE_INDICES]) + nb_elm = m_nbIndices[LINE_INDICES]/2; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[LINE_INDICES]); + glDrawElements(GL_LINES, 2*nb_elm, GL_UNSIGNED_INT, 0); + break; + case TRIANGLES: + if (3*nb_elm > m_nbIndices[TRIANGLE_INDICES]) + nb_elm = m_nbIndices[TRIANGLE_INDICES]/3; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[TRIANGLE_INDICES]); + glDrawElements(GL_TRIANGLES, 3*nb_elm, GL_UNSIGNED_INT, 0); + break; + default: + break; + } + + sh->disableVertexAttribs(); + return nb_elm; +} + + } // namespace GL2 } // namespace Render diff --git a/src/Utils/pickables.cpp b/src/Utils/pickables.cpp index 618ca68de6b816b002474ac266084e1e7ed7a53c..0f819d3d171c1543c9b134eef2af1a712fdd46f5 100644 --- a/src/Utils/pickables.cpp +++ b/src/Utils/pickables.cpp @@ -24,6 +24,7 @@ #include "Utils/pickables.h" #include "glm/gtc/matrix_transform.hpp" +#include "glm/gtx/norm.hpp" #include "Geometry/distances.h" #include "Geometry/intersection.h" #include @@ -106,13 +107,13 @@ void Pickable::invertPV(const Geom::Vec3f& P, const Geom::Vec3f& V, const glm::m -bool Pickable::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon) +bool Pickable::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon) { Geom::Vec3f PP; Geom::Vec3f VV; invertPV(P,V,m_transfo,PP,VV); - return m_drawable->pick(PP,VV,epsilon) != 0; + return m_drawable->pick(PP,VV,I,epsilon) != 0; } @@ -207,12 +208,21 @@ Pickable* Pickable::pick(const std::vector& picks,const Geom::Vec3f& { float mdist = std::numeric_limits::max(); Pickable* res=NULL; + Geom::Vec3f I; for (std::vector::const_iterator it=picks.begin(); it != picks.end(); ++it) { - if ((*it)->pick(P,V)) + if ((*it)->pick(P,V,I)) { - float dist = (*it)->distancefrom(P); + std::cout << "I="<distancefrom(P); + glm::mat4 tr = (*it)->transfo(); + glm::vec4 ii(I[0],I[1],I[2],1.0f); + glm::vec4 IWglm = tr*ii; + Geom::Vec3f IW(IWglm[0]/IWglm[3],IWglm[1]/IWglm[3],IWglm[2]/IWglm[3]); + IW -= P; + float dist = IW.norm(); if (dist < mdist) { res = *it; @@ -231,15 +241,21 @@ bool Pickable::distOrder(const std::pair& e1, const std::pair< std::vector Pickable::sortedPick(std::vector& picks, const Geom::Vec3f& P, const Geom::Vec3f& V) { - + Geom::Vec3f I; std::vector< std::pair > sorted; sorted.reserve(picks.size()); for (std::vector::const_iterator it=picks.begin(); it != picks.end(); ++it) { - if ((*it)->pick(P,V)) + if ((*it)->pick(P,V,I)) { - float dist = (*it)->distancefrom(P); +// float dist = (*it)->distancefrom(P); + glm::mat4 tr = (*it)->transfo(); + glm::vec4 ii(I[0],I[1],I[2],1.0f); + glm::vec4 IWglm = tr*ii; + Geom::Vec3f IW(IWglm[0]/IWglm[3],IWglm[1]/IWglm[3],IWglm[2]/IWglm[3]); + IW -= P; + float dist = IW.norm(); sorted.push_back(std::pair(dist,*it)); } } @@ -307,14 +323,14 @@ void Grid::updatePrecisionDrawing(unsigned int sub, unsigned int sub2) } -unsigned int Grid::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon) +unsigned int Grid::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon) { if (fabs(V[2])>=0.0000001f) { float a = -1.0f*P[2]/V[2]; - Geom::Vec3f Q = Geom::Vec3f(P+a*V); // intersection with plane z=0 + I = Geom::Vec3f(P+a*V); // intersection with plane z=0 - if ( (fabs(Q[0])<=1.0f) && (fabs(Q[1])<=1.0f) ) + if ( (fabs(I[0])<=1.0f) && (fabs(I[1])<=1.0f) ) return 1; } @@ -447,14 +463,18 @@ void Sphere::draw() } -unsigned int Sphere::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon) +unsigned int Sphere::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon) { float dist = Geom::squaredDistanceLine2Point(P,V,V*V, Geom::Vec3f(0.0f,0.0f,0.0f)); - if (dist <= 1.0f) - return 1; + if (dist > 1.0f) + return 0; - return 0; + + I=P; + I.normalize(); // grossiere approximation TODO amelioerer approxim ? + + return 1; } @@ -555,7 +575,7 @@ void Cone::updatePrecisionDrawing(unsigned int sub, unsigned int sub2) -unsigned int Cone::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon) +unsigned int Cone::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon) { Geom::Vec3f Z,Q; if (Geom::lineLineClosestPoints(P, V, Geom::Vec3f(0.0f,0.0f,0.0f), Geom::Vec3f(0.0f,0.0f,1.0f), Q, Z)) @@ -565,25 +585,29 @@ unsigned int Cone::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilo float dist = Q[0]*Q[0] + Q[1]*Q[1]; float cdist = (1.0f - Q[2])/2.0f; if (dist <= cdist*cdist) // squared !! + { + I = Q; // WARNING VERY BAD APPROXIMATON : TODO better approxim. return 1; + } + } // else check inter with base // Z=-1 float a = (-1.0f - P[2]) / V[2]; - Q = Geom::Vec3f(P+a*V); - float dist = Q[0]*Q[0] + Q[1]*Q[1]; - if (dist <= 1.0f) - return 1; - //else no inter - return 0; + I = Geom::Vec3f(P+a*V); + float dist = I[0]*I[0] + I[1]*I[1]; + if (dist > 1.0f) + return 0; + return 1; } // ray in Z direction float dist = P[0]*P[0] + P[1]*P[1]; - if (dist <= 1.0f) - return 1; - - return 0; + if (dist > 1.0f) + return 0; + I=P; + I[2]=-1.0f; + return 1; } @@ -684,7 +708,7 @@ void Cylinder::updatePrecisionDrawing(unsigned int sub, unsigned int sub2) -unsigned int Cylinder::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon) +unsigned int Cylinder::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon) { Geom::Vec3f Z,Q; if (Geom::lineLineClosestPoints(P, V, Geom::Vec3f(0.0f,0.0f,0.0f), Geom::Vec3f(0.0f,0.0f,1.0f), Q, Z)) @@ -693,19 +717,23 @@ unsigned int Cylinder::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float ep { float dist = Q[0]*Q[0] + Q[1]*Q[1]; if (dist < 1.0f) + { + I = Q; // WARNING VERY BAD APPROXIMATON : TODO better approxim. return 1; + } + } // else check inter with bases // Z=1 float a = (1.0f - P[2]) / V[2]; - Q = Geom::Vec3f(P+a*V); - float dist = Q[0]*Q[0] + Q[1]*Q[1]; + I = Geom::Vec3f(P+a*V); + float dist = I[0]*I[0] + I[1]*I[1]; if (dist < 1.0f) return 1; // Z=-1 a = (-1.0f - P[2]) / V[2]; - Q = Geom::Vec3f(P+a*V); - dist = Q[0]*Q[0] + Q[1]*Q[1]; + I = Geom::Vec3f(P+a*V); + dist = I[0]*I[0] + I[1]*I[1]; if (dist < 1.0f) return 1; //else no inter @@ -714,10 +742,14 @@ unsigned int Cylinder::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float ep // ray in Z direction float dist = P[0]*P[0] + P[1]*P[1]; - if (dist <= 1.0f) - return 1; - - return 0; + if (dist > 1.0f) + return 0; + I=P; + if (V[2]<0.0f) + I[2]=-1.0f; + else + I[2]=1.0f; + return 1; } @@ -820,7 +852,7 @@ void Cube::draw() } -unsigned int Cube::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilon) +unsigned int Cube::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, Geom::Vec3f& I, float epsilon) { // // firs quick picking with bounding sphere @@ -828,22 +860,23 @@ unsigned int Cube::pick(const Geom::Vec3f& P, const Geom::Vec3f& V, float epsilo if (dist2 > 3.0f) return 0; + I=P; + I.normalize(); // grossiere approximation TODO amelioerer approxim ? + + std::vector intersections; + for (unsigned int i=0; i<3; ++i) { - if (fabsf(V[i])>=0.0000001f) + if (fabs(V[i])>=0.0000001f) { float a = (-1.0f-P[i])/V[i]; Geom::Vec3f Q = Geom::Vec3f(P+a*V); // intersection with plane z=0 - if ( (fabsf(Q[(i+1)%3])<=1.0f) && (fabsf(Q[(i+2)%3])<=1.0f) ) - { + if ( (fabs(Q[(i+1)%3])<=1.0f) && (fabs(Q[(i+2)%3])<=1.0f) ) return 1; - } a = (1.0f-P[i])/V[i]; Q = Geom::Vec3f(P+a*V); // intersection with plane z=0 - if ( (fabsf(Q[(i+1)%3])<=1.0f) && (fabsf(Q[(i+2)%3])<=1.0f) ) - { + if ( (fabs(Q[(i+1)%3])<=1.0f) && (fabs(Q[(i+2)%3])<=1.0f) ) return 1; - } } } diff --git a/src/Utils/qtinputs.cpp b/src/Utils/qtinputs.cpp index 3e409d0c4394a77bd40cdfb32618f22ba61b09f7..3c2f71a9de646c6b70e9e2a5534aec89bc2224ce 100644 --- a/src/Utils/qtinputs.cpp +++ b/src/Utils/qtinputs.cpp @@ -192,6 +192,36 @@ void VarDbl::updateFrom( QWidget* widg) const } + +// class VarFloat + +VarFloat::VarFloat(float min, float max, float& val, const std::string& label) : + m_min(min), m_max(max), m_val(val) +{ + m_label = label; +} + +VarFloat::VarFloat(float min, float max, float& val, const std::string& label, const Var& var) : + Var(var), m_min(min), m_max(max), m_val(val) +{ + m_label = label; +} + +QWidget* VarFloat::createInput() const +{ + QDoubleSpinBox *spin = new QDoubleSpinBox(); + spin->setRange(double(m_min), double(m_max)); + spin->setValue(double(m_val)); + return spin; +} + +void VarFloat::updateFrom( QWidget* widg) const +{ + QDoubleSpinBox* spin = dynamic_cast(widg); + m_val = float(spin->value()); +} + + // class VarSlider VarSlider::VarSlider(int min, int max, int& val, const std::string& label): @@ -281,9 +311,12 @@ bool inputValues(const Var& v1, const std::string& title) CGoGNDialog dialog(params, title); int ret = dialog.exec(); - if (ret != 0) + if (ret == QDialog::Accepted) + { dialog.getResults(params); - return true; + return true; + } + return false; } } // namespace QT