diff --git a/Nef_S2/examples/Nef_S2/CMakeLists.txt b/Nef_S2/examples/Nef_S2/CMakeLists.txt index 7b698fa8636a..ea217bfe275f 100644 --- a/Nef_S2/examples/Nef_S2/CMakeLists.txt +++ b/Nef_S2/examples/Nef_S2/CMakeLists.txt @@ -6,17 +6,76 @@ project( Nef_S2_Examples ) cmake_minimum_required(VERSION 3.1) -find_package(CGAL QUIET) +if(POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + if(NOT POLICY CMP0070) + cmake_policy(SET CMP0053 OLD) + else() + cmake_policy(SET CMP0053 NEW) + endif() +endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + +find_package(CGAL) +find_package(Qt5 COMPONENTS Widgets OpenGL) if ( CGAL_FOUND ) include_directories (BEFORE "include") - # create a target per cppfile - file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) - foreach(cppfile ${cppfiles}) - create_single_source_cgal_program( "${cppfile}" ) - endforeach() + create_single_source_cgal_program("nef_s2_construction.cpp") + create_single_source_cgal_program("nef_s2_exploration.cpp") + create_single_source_cgal_program("nef_s2_point_location.cpp") + create_single_source_cgal_program("nef_s2_simple.cpp") + + if(Qt5_FOUND) + # The Qt5Widgets_INCLUDES also includes the include directories for + # dependencies QtCore and QtGui + include_directories(${Qt5Widgets_INCLUDE_DIRS} ${Qt5OpenGL_INCLUDE_DIRS}) + + # We need add -DQT_WIDGETS_LIB when using QtWidgets in Qt 5. + add_definitions(${Qt5Widgets_DEFINITIONS} ${Qt5OpenGL_DEFINITIONS}) + + # Tell CMake to run moc when necessary: + set(CMAKE_AUTOMOC ON) + # As moc files are generated in the binary dir, tell CMake + # to always look for includes there: + set(CMAKE_INCLUDE_CURRENT_DIR ON) + + # qt5_wrap_cpp(mocfiles include/CGAL/Nef_S2/Qt_widget_OpenGL.h + # include/CGAL/Nef_S2/Qt_widget_Nef_S2.h) + + qt5_generate_moc(include/CGAL/Nef_S2/Qt_widget_OpenGL.h Qt_widget_OpenGL.h.moc.cpp) + qt5_generate_moc(include/CGAL/Nef_S2/Qt_widget_Nef_S2.h Qt_widget_Nef_S2.h.moc.cpp) + + + add_executable(nef_S2 + "nef_S2.cpp" + "Qt_widget_OpenGL.h.moc.cpp" + "Qt_widget_Nef_S2.h.moc.cpp" + "Qt_widget_Nef_S2.cpp" + "Qt_widget_OpenGL.cpp" ) + target_link_libraries(nef_S2 PRIVATE CGAL::CGAL) + if(CGAL_3RD_PARTY_LIBRARIES) + target_link_libraries(nef_S2 PRIVATE ${CGAL_3RD_PARTY_LIBRARIES}) + endif() + target_link_libraries(nef_S2 PRIVATE ${CGAL_LIBRARIES} Qt5::Widgets Qt5::OpenGL glut GLU GL ) + + + add_executable(draw_nef_s2 + "draw_nef_s2.cpp" + "Qt_widget_OpenGL.h.moc.cpp" + "Qt_widget_Nef_S2.h.moc.cpp" + "Qt_widget_Nef_S2.cpp" + "Qt_widget_OpenGL.cpp") + target_link_libraries(draw_nef_s2 PRIVATE CGAL::CGAL) + if(CGAL_3RD_PARTY_LIBRARIES) + target_link_libraries(draw_nef_s2 PRIVATE ${CGAL_3RD_PARTY_LIBRARIES}) + endif() + target_link_libraries(draw_nef_s2 PRIVATE ${CGAL_LIBRARIES} Qt5::Widgets Qt5::OpenGL glut GLU GL ) + endif() else() diff --git a/Nef_S2/examples/Nef_S2/Qt_widget_Nef_S2.cpp b/Nef_S2/examples/Nef_S2/Qt_widget_Nef_S2.cpp new file mode 100644 index 000000000000..e1d32860fd22 --- /dev/null +++ b/Nef_S2/examples/Nef_S2/Qt_widget_Nef_S2.cpp @@ -0,0 +1,91 @@ +#include "CGAL/Nef_S2/Qt_widget_Nef_S2.h" + +namespace CGAL { + Qt_widget_Nef_S2::~Qt_widget_Nef_S2() { + for (size_t i=0;isetContextMenuPolicy(Qt::ActionsContextMenu); + + main = new QMenu; + sub1 = main->addMenu("&Control"); + sub2 = main->addMenu("&Render"); + sub3 = main->addMenu("&Options"); + + QAction * qa; + qa = sub1->addAction("Reset"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotControlMenuReset())); + qa = sub1->addAction("Rotate"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotControlMenuRotate())); + qa = sub1->addAction("Scale"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotControlMenuScale())); + qa = sub1->addAction("Translate in XY"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotControlMenuTranslate())); + + qa = sub2->addAction("Faces"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotRenderMenuFaces())); + qa = sub2->addAction("Skeleton"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotRenderMenuSkeleton())); + qa = sub2->addAction("Triangulation"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotRenderMenuTriangulation())); + + qa = sub3->addAction("Toggle Axes"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotOptionsMenuAxes())); + qa = sub3->addAction("Toggle Unity Cube"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotOptionsMenuUnityCube())); + + qa = main->addAction("&Next"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotNextObject())); + qa = main->addAction("&Previous"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotPrevObject())); + qa = main->addAction("&Toggle Fullscreen"); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotFullscreen())); + qa = main->addAction("&Quit"); + QObject::connect(qa, SIGNAL(triggered()), qApp, SLOT(quit())); + + qa = new QAction("Reset",this); + qa->setShortcut(Qt::Key_R); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotControlMenuReset())); + this->addAction(qa); + + qa = new QAction("Toggle Axes",this); + qa->setShortcut(Qt::Key_A); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotOptionsMenuAxes())); + this->addAction(qa); + + qa = new QAction("Toggle Unity Cube",this); + qa->setShortcut(Qt::Key_C); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotOptionsMenuUnityCube())); + this->addAction(qa); + + qa = new QAction("Next",this); + qa->setShortcut(Qt::Key_Right); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotNextObject())); + this->addAction(qa); + + qa = new QAction("Previous",this); + qa->setShortcut(Qt::Key_Left); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotPrevObject())); + this->addAction(qa); + + qa = new QAction("Toggle Fullscreen",this); + qa->setShortcut(Qt::Key_F); + QObject::connect(qa, SIGNAL(triggered()), this, SLOT(slotFullscreen())); + this->addAction(qa); + + qa = new QAction("Quit",this); + qa->setShortcut(Qt::Key_Q); + QObject::connect(qa, SIGNAL(triggered()), qApp, SLOT(quit())); + this->addAction(qa); + } + + +} //namespace CGAL + diff --git a/Nef_S2/examples/Nef_S2/Qt_widget_OpenGL.cpp b/Nef_S2/examples/Nef_S2/Qt_widget_OpenGL.cpp new file mode 100644 index 000000000000..ca3e3cd8a884 --- /dev/null +++ b/Nef_S2/examples/Nef_S2/Qt_widget_OpenGL.cpp @@ -0,0 +1,281 @@ +// Copyright (c) 1999 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Michael Seel +// Peter Hachenberger + +#include + +#include +#include "CGAL/Nef_S2/Qt_widget_OpenGL.h" + +namespace CGAL { + + Qt_widget_OpenGL::Qt_widget_OpenGL(int width, int height, double scale) : + object_index_(0), + window_width(width), + window_height(height), + motion_mode(ROTATE), + dx(0), + dy(0), + dz(0), + s(scale), + init_s(scale), + rotation(CGAL::IDENTITY){} + + Qt_widget_OpenGL::~Qt_widget_OpenGL() {} + + CGAL::OGL::OGL_base_object::Affine_3 + Qt_widget_OpenGL::virtual_sphere_transformation( double old_x, double old_y, + double new_x, double new_y) { + + if ( old_x == new_x && old_y == new_y)// zero rotation. + return Affine_3( CGAL::IDENTITY); + // Determine the projected vectors on the `sphere'. + double dd = old_x * old_x + old_y * old_y; + Double_vector v_old( old_x, old_y, + ((dd < 0.5) ? std::sqrt(1-dd) : 0.5 / std::sqrt(dd))); + dd = new_x * new_x + new_y * new_y; + Double_vector v_new( new_x, new_y, + ((dd < 0.5) ? std::sqrt(1-dd) : 0.5 / std::sqrt(dd))); + Double_vector axis = cross_product( v_old, v_new); + double angle = 0.0; + double norm = std::sqrt( (v_old*v_old)*(v_new*v_new)); + if ( norm != 0) { + double x = v_old*v_new/ norm; + if ( x <= -1) + angle = CGAL_PI; + if ( x < 1) + angle = std::acos(x); + } + double len = std::sqrt( double(axis * axis)); + double s = std::sin( angle / 2.0) / len; + double q1 = axis.x() * s; // quaternion + double q2 = axis.y() * s; + double q3 = axis.z() * s; + double q0 = std::cos( angle / 2.0); + double a = q1 * q2; + double b = q0 * q3; + double c = q1 * q3; + double d = q0 * q2; + double e = q2 * q3; + double f = q0 * q1; + double qq0 = q0 * q0; + double qq1 = q1 * q1; + double qq2 = q2 * q2; + double qq3 = q3 * q3; + return Affine_3( qq0 + qq1 - qq2 - qq3, 2 * (a-b), 2 * (c+d), + 2 * (a+b), qq0 - qq1 + qq2 - qq3, 2 * (e-f), + 2 * (c-d), 2 * (e+f), qq0 - qq1 - qq2 + qq3); + } + + void Qt_widget_OpenGL::mouseMoveEvent(QMouseEvent* event) { + int x = event->x(); + int y = event->y(); + switch ( interaction) { + case SCALE: + s *= std::exp( (x - mouse_x + mouse_y -y) * factor_s ); + break; + case ROTATE: { + double old_x = 1.2 * (mouse_x - window_width/2) / window_radius; + double old_y = - 1.2 * (mouse_y - window_height/2) / window_radius; + double new_x = 1.2 * (x - window_width/2) / window_radius; + double new_y = - 1.2 * (y - window_height/2) / window_radius; + rotation = virtual_sphere_transformation( old_x, old_y, new_x, new_y) + * rotation; + } + break; + case TRANSLATE: + dx += (x - mouse_x) * 2.0 / window_radius; + dy -= (y - mouse_y) * 2.0 / window_radius; + break; + case TRANS_Z: + dz += (x - mouse_x + mouse_y -y) * 2.0 / window_radius; + break; + default: + break; + } + mouse_x = x; + mouse_y = y; + + updateGL(); + } + + void Qt_widget_OpenGL::mousePressEvent(QMouseEvent* event) { + mouse_x = event->x(); + mouse_y = event->y(); + interaction = 0; + if(event->button() == ::Qt::LeftButton) { + if (event->modifiers() == ::Qt::ShiftModifier) { + interaction = SCALE; + } else { + interaction = motion_mode; + } + } + if(event->button() == ::Qt::MidButton) { + if( event->modifiers() == ::Qt::ShiftModifier) { + interaction = TRANS_Z; + } else { + interaction = TRANSLATE; + } + } + if(event->button() == ::Qt::RightButton) { + main->exec(QPoint(event->globalX(),event->globalY())); + } + } + + void Qt_widget_OpenGL::mouseReleaseEvent(QMouseEvent* event) { + mousePressEvent(event); + } + + void Qt_widget_OpenGL::paintGL() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glPushMatrix(); + glTranslated(dx,dy,dz); + // glTranslated(0,0,1); + GLdouble M[16] = { rotation.m(0,0), rotation.m(1,0), rotation.m(2,0), 0.0, + rotation.m(0,1), rotation.m(1,1), rotation.m(2,1), 0.0, + rotation.m(0,2), rotation.m(1,2), rotation.m(2,2), 0.0, + rotation.m(0,3), rotation.m(1,3), rotation.m(2,3), 1.0}; + glMultMatrixd( M); + glScaled(s,s,s); + object_[object_index_]->draw(); + glPopMatrix(); + } + + void Qt_widget_OpenGL::initializeGL() { + GLfloat mat_diffuse[4] = { 0.7f, 0.7f, 0.7f, 1.0f }; + GLfloat mat_specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat mat_shininess[] = { 100.0f }; + GLfloat ambient_light[] = { 0.2f, 0.2f, 0.2f, 1.0f }; + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse ); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular ); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess ); +#ifdef SCREENSHOTS + GLfloat mat_emission[] = { 0.1, 0.1, 0.2, 0.0 }; + glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission); + //for screenshots enable this section +#endif + + GLfloat light0[4] = { 4.0, 4.0, 10.0, 1.0 }; + glLightfv (GL_LIGHT0, GL_POSITION, light0); + glEnable (GL_LIGHT0); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + } + + void Qt_widget_OpenGL::resizeGL(int width, int height) { + window_width = width; + window_height = height; + window_radius = (std::min)( width, height) / 2; + + glViewport(0, 0, (GLint)width, (GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + if (width>height) + { + long double w = (long double) width / (long double) height; + glOrtho( -2*w, 2*w, -w, w, -4.0, 4.0 ); + factor_d = 2.0 / (height/2.0); + // halbe Fensterhoehe soll 2 LE entsprechen + factor_w = 90.0 / (height/2.0); + // halbe Fensterhoehe soll 90 Grad entsprechen + factor_s = std::log(4.0) / (height/2.0); + // halbe Fensterhoehe soll Faktor 4 entsprechen + } + else + { + long double h = (long double) height / (long double) width; + glOrtho( -2.0, 2.0, -2*h, 2*h, -4.0, 4.0 ); + factor_d = 2.0 / (width/2.0); + // halbe Fensterbreite soll 2 LE entsprechen + factor_w = 90.0 / (width/2.0); + // halbe Fensterbreite soll 90 Grad entsprechen + factor_s = std::log(4.0) / (height/2.0); + // halbe Fensterhoehe soll Faktor 4 entsprechen + } + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } + + void Qt_widget_OpenGL::slotNextObject() { + if (object_.size() < 2) return; + object_index_ = (object_index_+1) % object_.size(); + if (!label_[object_index_].empty()) { + std::cout << "Displaying: '" << label_[object_index_] <<"'\n"; + } + // controlMenu(RESET_CONTROL); + object_[object_index_]->init(); + updateGL(); + } + + void Qt_widget_OpenGL::slotPrevObject() { + if (object_.size() < 2) return; + object_index_ = (object_index_+object_.size()-1) % object_.size(); + if (!label_[object_index_].empty()) { + std::cout << "Displaying: '" << label_[object_index_] <<'\n'; + } + // controlMenu(RESET_CONTROL); + object_[object_index_]->init(); + updateGL(); + } + + void Qt_widget_OpenGL::controlMenu(int index) { + if(index == RESET_CONTROL) { + dx = dy = dz = 0.0; + s = init_s; + rotation = Affine_3(CGAL::IDENTITY); + motion_mode = ROTATE; + object_[object_index_]->init(); + updateGL(); + } else { + motion_mode = index; + } + } + + void Qt_widget_OpenGL::renderMenu(int index) { + object_[object_index_]->set_style(index); + updateGL(); + } + + void Qt_widget_OpenGL::optionsMenu(int index) { + object_[object_index_]->toggle(index); + updateGL(); + } + + void Qt_widget_OpenGL::slotFullscreen() { + if(fullscreen) { + showNormal(); + } else { + showMaximized(); + } + fullscreen = !fullscreen; + } + + void Qt_widget_OpenGL::slotPerspective() { + perspective = !perspective; + } + +} // namespace CGAL +#include "Qt_widget_OpenGL.moc" diff --git a/Nef_S2/examples/Nef_S2/draw_nef_s2.cpp b/Nef_S2/examples/Nef_S2/draw_nef_s2.cpp new file mode 100644 index 000000000000..42b9c27483f0 --- /dev/null +++ b/Nef_S2/examples/Nef_S2/draw_nef_s2.cpp @@ -0,0 +1,23 @@ + +#include +#include +#include +#include +#include "CGAL/Nef_S2/create_random_Nef_S2.h" +#include "CGAL/Nef_S2/draw_nef_S2.h" + +typedef CGAL::Exact_rational FT; +typedef CGAL::Simple_cartesian Kernel; // No reference counting, i.e. thread-safe! +typedef CGAL::Nef_polyhedron_S2 Nef_polyhedron_S2; + +int main(int argc, char* argv[]) +{ + Nef_polyhedron_S2 S[3]; + create_random_Nef_S2(S[0],5); + create_random_Nef_S2(S[1],5); + create_random_Nef_S2(S[2],5); + + CGAL::draw(S,S+3); + + return EXIT_SUCCESS; +} diff --git a/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/Qt_widget_Nef_S2.h b/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/Qt_widget_Nef_S2.h new file mode 100644 index 000000000000..5c5db2d007ef --- /dev/null +++ b/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/Qt_widget_Nef_S2.h @@ -0,0 +1,53 @@ +// Copyright (c) 1997-2000 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Peter Hachenberger + +#ifndef CGAL_QT_WIDGET_NEF_S2_H +#define CGAL_QT_WIDGET_NEF_S2_H + +#include +#include "CGAL/Nef_S2/Qt_widget_OpenGL.h" +#include + +namespace CGAL { + +class Qt_widget_Nef_S2 : public Qt_widget_OpenGL { + Q_OBJECT + + public: + template + void addObject(const typename Nef_polyhedron::Const_decorator& N, const std::string & label=std::string()) { + CGAL::OGL::OGL_base_object* O = new CGAL::OGL::Unit_sphere(CGAL::OGL::NefS2_to_UnitSphere::convert(N)); + mutex.lock(); + object_.push_back(O); + label_.push_back(label); + mutex.unlock(); + } + + Qt_widget_Nef_S2(); + + virtual ~Qt_widget_Nef_S2(); + + protected: + CGAL_MUTEX mutex; + +}; + +} //namespace CGAL +#endif // CGAL_QT_WIDGET_NEF_S2_H diff --git a/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/Qt_widget_OpenGL.h b/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/Qt_widget_OpenGL.h new file mode 100644 index 000000000000..3668e16bcb69 --- /dev/null +++ b/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/Qt_widget_OpenGL.h @@ -0,0 +1,116 @@ +// Copyright (c) 1997-2000 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Peter Hachenberger + +#ifndef CGAL_QT_WIDGET_OPENGL_H +#define CGAL_QT_WIDGET_OPENGL_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace CGAL { + + class Qt_widget_OpenGL : public QGLWidget { + Q_OBJECT + + typedef CGAL::OGL::OGL_base_object::Affine_3 Affine_3; + typedef CGAL::OGL::OGL_base_object::Double_vector Double_vector; + // typedef CGAL::Simple_cartesian::Aff_transformation_3 Affine_3; + + protected: + enum MenuEntriesS2 { ROTATE, SCALE, TRANSLATE, TRANS_Z, RESET_CONTROL, + PERSP, FULLSCREEN, QUIT }; + + size_t object_index_; + std::vector object_; + std::vector label_; + + int window_width; // Breite und + int window_height; // Hoehe des Fensters + int window_radius; // min(width,height) / 2 + + bool perspective; + bool fullscreen; + + int mouse_x, mouse_y; // Mauskoordinaten linker button + int interaction; // type of interaction in motion fct. + int motion_mode; // Bewegen der Maus bei Mouse1 gedrueckt + int submenu1, submenu2; + long double dx; // Translation + long double dy; // Translation + long double dz; // Translation in Z + long double s; // Skalierung + long double init_s; + + Affine_3 rotation; // Rotation + + long double factor_s; // Umrechnungsfaktor fuer Skalierung + long double factor_w; + long double factor_d; + + QMenu* main; + QMenu* sub1; + QMenu* sub2; + QMenu* sub3; + + protected: + Affine_3 virtual_sphere_transformation( double old_x, double old_y, + double new_x, double new_y); + void controlMenu(int index); + void renderMenu(int index); + void optionsMenu(int index); + + protected slots: + void slotControlMenuReset() {controlMenu(RESET_CONTROL);} + void slotControlMenuRotate() {controlMenu(ROTATE);} + void slotControlMenuScale() {controlMenu(SCALE);} + void slotControlMenuTranslate() {controlMenu(TRANSLATE);} + void slotRenderMenuFaces() {renderMenu(CGAL::OGL::SM_FACES);} + void slotRenderMenuSkeleton() {renderMenu(CGAL::OGL::SM_SKELETON);} + void slotRenderMenuTriangulation() {renderMenu(CGAL::OGL::SM_TRIANGULATION);} + void slotOptionsMenuAxes() {optionsMenu(CGAL::OGL::SM_AXES);} + void slotOptionsMenuUnityCube() {optionsMenu(CGAL::OGL::SM_CUBE);} + void slotFullscreen(); + void slotPerspective(); + void slotNextObject(); + void slotPrevObject(); + + protected: + virtual void mouseMoveEvent( QMouseEvent* event); + virtual void mousePressEvent( QMouseEvent* event); + virtual void mouseReleaseEvent( QMouseEvent* event); + + public: + Qt_widget_OpenGL(int width, int height, double scale); + virtual ~Qt_widget_OpenGL(); + virtual void paintGL(); + virtual void initializeGL(); + virtual void resizeGL(int w, int h); + }; + +} // namespace CGAL +#endif // CGAL_QT_WIDGET_OPENGL_H diff --git a/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/draw_nef_S2.h b/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/draw_nef_S2.h new file mode 100644 index 000000000000..042eb721583b --- /dev/null +++ b/Nef_S2/examples/Nef_S2/include/CGAL/Nef_S2/draw_nef_S2.h @@ -0,0 +1,110 @@ +// Copyright (c) 2018 GeometryFactory (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_SURFACE_MESH_H +#define CGAL_DRAW_SURFACE_MESH_H + +#ifdef DOXYGEN_RUNNING + +/*! +\ingroup PkgDrawNefS2 + +Open a new window and draw `asm`, an instance of the `CGAL::Nef_polyhedron_S2` class. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam SM an instance of the `CGAL::Nef_polyhedron_S2` class. +\param asm the surface mesh to draw. + +*/ +template +void draw(const Nef_polyhedron& asm); + +/*! +\ingroup PkgDrawNefS2 + +Open a new window and draw a set of instances of the `CGAL::Nef_polyhedron_S2` class. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam SM an instance of the `CGAL::Nef_polyhedron_S2` class. +\param asm the surface mesh to draw. + +*/ +template +void draw(iterator start, iterator end); +#else // DOXYGEN_RUNNING + +#include + +#include + +namespace CGAL +{ + + + template + void draw(iterator start, iterator end) + { +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"Nef_S2 viewer","\0"}; + QApplication app(argc,const_cast(argv)); + CGAL::Qt_widget_Nef_S2 mainwindow; + unsigned int i=0; + for (iterator it=start;it!=end;it++,i++) { + char lbl[128]; + sprintf(lbl,"NefS2 %d",i); + mainwindow.addObject(*it,lbl); + } + mainwindow.show(); + app.exec(); + } + + } + + template + void draw(const Nef_polyhedron& S) + { +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"Nef_S2 viewer","\0"}; + QApplication app(argc,const_cast(argv)); + CGAL::Qt_widget_Nef_S2 mainwindow; + mainwindow.addObject(S); + mainwindow.show(); + app.exec(); + } + + } +} // End namespace CGAL + + +#endif // DOXYGEN_RUNNING + +#endif // CGAL_DRAW_SURFACE_MESH_H diff --git a/Nef_S2/examples/Nef_S2/nef_S2.cpp b/Nef_S2/examples/Nef_S2/nef_S2.cpp new file mode 100644 index 000000000000..72559d19c7e5 --- /dev/null +++ b/Nef_S2/examples/Nef_S2/nef_S2.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2004 Max-Planck-Institute Saarbruecken (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Peter Hachenberger +#include +#include +#include +#include +#include +#include "CGAL/Nef_S2/create_random_Nef_S2.h" +#include "CGAL/Nef_S2/Qt_widget_Nef_S2.h" + +typedef CGAL::Exact_rational FT; +typedef CGAL::Simple_cartesian Kernel; // No reference counting, i.e. thread-safe! +typedef CGAL::Nef_polyhedron_S2 Nef_polyhedron_S2; + +int main(int argc, char* argv[]) { + Nef_polyhedron_S2 S1,S2,S3; + create_random_Nef_S2(S1,5); + create_random_Nef_S2(S2,5); + create_random_Nef_S2(S3,5); + QApplication a(argc, argv); + CGAL::Qt_widget_Nef_S2* w = new CGAL::Qt_widget_Nef_S2(); + w->addObject(S1,"S1"); + w->addObject(S2,"S2"); + w->addObject(S3,"S3"); + // a.setMainWidget(w); + w->show(); + return a.exec(); +} diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h index e7904529787c..8cefbbf4515d 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h @@ -72,6 +72,24 @@ VVector convert(const CGAL::Vector_3& v) CGAL::to_double(v.z())); } +template +VVector normalize_and_convert(const CGAL::Vector_3& v) +{ + typename R::FT xa = CGAL::abs(v.x()); + typename R::FT ya = CGAL::abs(v.y()); + typename R::FT za = CGAL::abs(v.z()); + typename R::FT m = std::max(std::max(xa,ya),za); + if (m==0) { + return VVector(0,0,0); + } else { + double xd = CGAL::to_double(v.x()/m); + double yd = CGAL::to_double(v.y()/m); + double zd = CGAL::to_double(v.z()/m); + VVector u(xd,yd,zd); + return u / CGAL_NTS sqrt(u*u) ; // normalize + } +} + const double refinement_angle = 0.1; const double shrink_fac = 0.995; @@ -80,8 +98,7 @@ class Approximator { public: static VPoint approximate(const CGAL::Sphere_point& p) { - VVector v = convert(p-CGAL::ORIGIN); - v = v / CGAL_NTS sqrt(v*v) ; // normalize + VVector v = normalize_and_convert(p-CGAL::ORIGIN); return CGAL::ORIGIN+v; } @@ -185,6 +202,8 @@ class Approximator { angle[1] = std::acos((t[1]-CGAL::ORIGIN)*(t[2]-CGAL::ORIGIN)); angle[2] = std::acos((t[2]-CGAL::ORIGIN)*(t[0]-CGAL::ORIGIN)); CGAL_NEF_TRACEN("refine "< angle[0] ) { if ( angle[2] > angle[1] ) i=2; else i=1;