summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CGAL_renderer.h762
-rw-r--r--src/GLView.h22
-rw-r--r--src/MainWindow.h9
-rw-r--r--src/OGL_helper.h687
-rw-r--r--src/cgalrenderer.cc126
-rw-r--r--src/cgalrenderer.h20
-rw-r--r--src/glview.cc219
-rw-r--r--src/mainwin.cc356
-rw-r--r--src/opencsgrenderer.cc (renamed from src/render-opencsg.cc)58
-rw-r--r--src/opencsgrenderer.h24
-rw-r--r--src/polyset.h5
-rw-r--r--src/render-opencsg.h8
-rw-r--r--src/renderer.h11
-rw-r--r--src/throwntogetherrenderer.cc120
-rw-r--r--src/throwntogetherrenderer.h21
15 files changed, 1346 insertions, 1102 deletions
diff --git a/src/CGAL_renderer.h b/src/CGAL_renderer.h
index 0758339..acc902f 100644
--- a/src/CGAL_renderer.h
+++ b/src/CGAL_renderer.h
@@ -1,660 +1,104 @@
-// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany).
-// All rights reserved.
-//
-// This file is part of CGAL (www.cgal.org); you may redistribute it under
-// the terms of the Q Public License version 1.0.
-// See the file LICENSE.QPL distributed with CGAL.
-//
-// 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: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Nef_3/include/CGAL/Nef_3/OGL_helper.h $
-// $Id: OGL_helper.h 44713 2008-08-01 15:38:58Z hachenb $
-//
-//
-// Author(s) : Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
-
-#ifndef CGAL_NEF_OPENGL_HELPER_H
-#define CGAL_NEF_OPENGL_HELPER_H
-
-#include <CGAL/Nef_S2/OGL_base_object.h>
-#include <CGAL/Simple_cartesian.h>
-#include <CGAL/Nef_3/SNC_decorator.h>
-#include <qgl.h>
-#include <cstdlib>
-
-#ifdef _WIN32
-#define CGAL_GLU_TESS_CALLBACK CALLBACK
-#else
-#define CGAL_GLU_TESS_CALLBACK
-#endif
-
-#ifdef __APPLE__
-# include <AvailabilityMacros.h>
-#endif
-
-#if defined __APPLE__ && !defined MAC_OS_X_VERSION_10_5
-#define CGAL_GLU_TESS_DOTS ...
-#else
-#define CGAL_GLU_TESS_DOTS
-#endif
-
-using namespace CGAL;
-using namespace CGAL::OGL;
-
-namespace OpenSCAD {
-
- namespace OGL {
-
-// ----------------------------------------------------------------------------
-// Drawable double types:
-// ----------------------------------------------------------------------------
-
- typedef CGAL::Simple_cartesian<double> DKernel;
- typedef DKernel::Point_3 Double_point;
- typedef DKernel::Vector_3 Double_vector;
- typedef DKernel::Segment_3 Double_segment;
- typedef DKernel::Aff_transformation_3 Affine_3;
-
- // DPoint = a double point including a mark
- class DPoint : public Double_point {
- bool m_;
- public:
- DPoint() {}
- DPoint(const Double_point& p, bool m) : Double_point(p) { m_ = m; }
- DPoint(const DPoint& p) : Double_point(p) { m_ = p.m_; }
- DPoint& operator=(const DPoint& p)
- { Double_point::operator=(p); m_ = p.m_; return *this; }
- bool mark() const { return m_; }
- };
-
- // DSegment = a double segment including a mark
- class DSegment : public Double_segment {
- bool m_;
- public:
- DSegment() {}
- DSegment(const Double_segment& s, bool m) : Double_segment(s) { m_ = m; }
- DSegment(const DSegment& s) : Double_segment(s) { m_ = s.m_; }
- DSegment& operator=(const DSegment& s)
- { Double_segment::operator=(s); m_ = s.m_; return *this; }
- bool mark() const { return m_; }
- };
-
- // Double_triple = a class that stores a triple of double
- // coordinates; we need a pointer to the coordinates in a C array
- // for OpenGL
- class Double_triple {
- typedef double* double_ptr;
- typedef const double* const_double_ptr;
- double coords_[3];
- public:
- Double_triple()
- { coords_[0]=coords_[1]=coords_[2]=0.0; }
- Double_triple(double x, double y, double z)
- { coords_[0]=x; coords_[1]=y; coords_[2]=z; }
- Double_triple(const Double_triple& t)
- { coords_[0]=t.coords_[0];
- coords_[1]=t.coords_[1];
- coords_[2]=t.coords_[2];
- }
- Double_triple& operator=(const Double_triple& t)
- { coords_[0]=t.coords_[0];
- coords_[1]=t.coords_[1];
- coords_[2]=t.coords_[2];
- return *this; }
- operator double_ptr() const
- { return const_cast<Double_triple&>(*this).coords_; }
- double operator[](unsigned i)
- { CGAL_assertion(i<3); return coords_[i]; }
- }; // Double_triple
-
- static std::ostream& operator << (std::ostream& os,
- const Double_triple& t)
- { os << "(" << t[0] << "," << t[1] << "," << t[2] << ")";
- return os; }
-
-
- // DFacet stores the facet cycle vertices in a continuus C array
- // of three double components, this is necessary due to the OpenGL
- // tesselator input format !
- class DFacet {
- typedef std::vector<Double_triple> Coord_vector;
- typedef std::vector<unsigned> Cycle_vector;
- Coord_vector coords_; // stores all vertex coordinates
- Cycle_vector fc_ends_; // stores entry points of facet cycles
- Double_triple normal_; // stores normal and mark of facet
- bool mark_;
-
- public:
- typedef Coord_vector::iterator Coord_iterator;
- typedef Coord_vector::const_iterator Coord_const_iterator;
-
- DFacet() {}
-
- void push_back_vertex(double x, double y, double z)
- { coords_.push_back(Double_triple(x,y,z)); }
-
- DFacet(const DFacet& f)
- { coords_ = f.coords_;
- fc_ends_ = f.fc_ends_;
- normal_ = f.normal_;
- mark_ = f.mark_;
- }
-
- DFacet& operator=(const DFacet& f)
- { coords_ = f.coords_;
- fc_ends_ = f.fc_ends_;
- normal_ = f.normal_;
- mark_ = f.mark_;
- return *this;
- }
-
- ~DFacet()
- { coords_.clear(); fc_ends_.clear(); }
-
- void push_back_vertex(const Double_point& p)
- { push_back_vertex(p.x(),p.y(),p.z()); }
-
- void set_normal(double x, double y, double z, bool m)
- { double l = sqrt(x*x + y*y + z*z);
- normal_ = Double_triple(x/l,y/l,z/l); mark_ = m; }
-
- double dx() const { return normal_[0]; }
- double dy() const { return normal_[1]; }
- double dz() const { return normal_[2]; }
- bool mark() const { return mark_; }
- double* normal() const
- { return static_cast<double*>(normal_); }
-
- void new_facet_cycle()
- { fc_ends_.push_back(coords_.size()); }
-
- unsigned number_of_facet_cycles() const
- { return fc_ends_.size(); }
-
- Coord_iterator facet_cycle_begin(unsigned i)
- { CGAL_assertion(i<number_of_facet_cycles());
- if (i==0) return coords_.begin();
- else return coords_.begin()+fc_ends_[i]; }
-
- Coord_iterator facet_cycle_end(unsigned i)
- { CGAL_assertion(i<number_of_facet_cycles());
- if (i<fc_ends_.size()-1) return coords_.begin()+fc_ends_[i+1];
- else return coords_.end(); }
-
- Coord_const_iterator facet_cycle_begin(unsigned i) const
- { CGAL_assertion(i<number_of_facet_cycles());
- if (i==0) return coords_.begin();
- else return coords_.begin()+fc_ends_[i]; }
-
- Coord_const_iterator facet_cycle_end(unsigned i) const
- { CGAL_assertion(i<number_of_facet_cycles());
- if (i<fc_ends_.size()-1) return coords_.begin()+fc_ends_[i+1];
- else return coords_.end(); }
-
- void debug(std::ostream& os = std::cerr) const
- { os << "DFacet, normal=" << normal_ << ", mark=" << mark() << std::endl;
- for(unsigned i=0; i<number_of_facet_cycles(); ++i) {
- os << " facet cycle ";
- // put all vertices in facet cycle into contour:
- Coord_const_iterator cit;
- for(cit = facet_cycle_begin(i); cit != facet_cycle_end(i); ++cit)
- os << *cit;
- os << std::endl;
- }
- }
-
- }; // DFacet
-
-
-// ----------------------------------------------------------------------------
-// OGL Drawable Polyhedron:
-// ----------------------------------------------------------------------------
-
- inline void CGAL_GLU_TESS_CALLBACK beginCallback(GLenum which)
- { glBegin(which); }
-
- inline void CGAL_GLU_TESS_CALLBACK endCallback(void)
- { glEnd(); }
-
- inline void CGAL_GLU_TESS_CALLBACK errorCallback(GLenum errorCode)
- { const GLubyte *estring;
- estring = gluErrorString(errorCode);
- fprintf(stderr, "Tessellation Error: %s\n", estring);
- std::exit (0);
- }
-
- inline void CGAL_GLU_TESS_CALLBACK vertexCallback(GLvoid* vertex,
- GLvoid* user)
- { GLdouble* pc(static_cast<GLdouble*>(vertex));
- GLdouble* pu(static_cast<GLdouble*>(user));
- // CGAL_NEF_TRACEN("vertexCallback coord "<<pc[0]<<","<<pc[1]<<","<<pc[2]);
- // CGAL_NEF_TRACEN("vertexCallback normal "<<pu[0]<<","<<pu[1]<<","<<pu[2]);
- glNormal3dv(pu);
- glVertex3dv(pc);
+/*
+ * OpenSCAD (www.openscad.org)
+ * Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
+ * Marius Kintel <marius@kintel.net>
+ *
+ * This program is free software; 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * As a special exception, you have permission to link this program
+ * with the CGAL library and distribute executables, as long as you
+ * follow the requirements of the GNU GPL in regard to all of the
+ * software in the executable aside from CGAL.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef CGAL_RENDERER_H
+#define CGAL_RENDERER_H
+
+#include "OGL_helper.h"
+#undef CGAL_NEF3_MARKED_VERTEX_COLOR
+#undef CGAL_NEF3_MARKED_EDGE_COLOR
+#undef CGAL_NEF3_MARKED_FACET_COLOR
+
+#undef CGAL_NEF3_UNMARKED_VERTEX_COLOR
+#undef CGAL_NEF3_UNMARKED_EDGE_COLOR
+#undef CGAL_NEF3_UNMARKED_FACET_COLOR
+
+using CGAL::OGL::SNC_BOUNDARY;
+using CGAL::OGL::SNC_SKELETON;
+
+class Polyhedron : public CGAL::OGL::Polyhedron
+{
+public:
+
+ enum RenderColor {
+ CGAL_NEF3_MARKED_VERTEX_COLOR,
+ CGAL_NEF3_MARKED_EDGE_COLOR,
+ CGAL_NEF3_MARKED_FACET_COLOR,
+ CGAL_NEF3_UNMARKED_VERTEX_COLOR,
+ CGAL_NEF3_UNMARKED_EDGE_COLOR,
+ CGAL_NEF3_UNMARKED_FACET_COLOR,
+ NUM_COLORS
+ };
+
+ Polyhedron() {
+ setColor(CGAL_NEF3_MARKED_VERTEX_COLOR,0xb7,0xe8,0x5c);
+ setColor(CGAL_NEF3_MARKED_EDGE_COLOR,0xab,0xd8,0x56);
+ setColor(CGAL_NEF3_MARKED_FACET_COLOR,0x9d,0xcb,0x51);
+ setColor(CGAL_NEF3_UNMARKED_VERTEX_COLOR,0xff,0xf6,0x7c);
+ setColor(CGAL_NEF3_UNMARKED_EDGE_COLOR,0xff,0xec,0x5e);
+ setColor(CGAL_NEF3_UNMARKED_FACET_COLOR,0xf9,0xd7,0x2c);
+ }
+
+ void draw(bool showedges) const {
+ if(this->style == SNC_BOUNDARY) {
+ glCallList(this->object_list_+2);
+ if(showedges) {
+ glDisable(GL_LIGHTING);
+ glCallList(this->object_list_+1);
+ glCallList(this->object_list_);
+ }
+ } else {
+ glDisable(GL_LIGHTING);
+ glCallList(this->object_list_+1);
+ glCallList(this->object_list_);
}
-
- inline void CGAL_GLU_TESS_CALLBACK combineCallback(GLdouble coords[3], GLvoid *[4], GLfloat [4], GLvoid **dataOut)
- {
- static std::list<GLdouble*> pcache;
- if (dataOut) {
- GLdouble *n = new GLdouble[3];
- n[0] = coords[0];
- n[1] = coords[1];
- n[2] = coords[2];
- pcache.push_back(n);
- *dataOut = n;
- } else {
- for (std::list<GLdouble*>::const_iterator i = pcache.begin(); i != pcache.end(); i++)
- delete[] *i;
- pcache.clear();
- }
- }
-
-
- enum { SNC_AXES};
- enum { SNC_BOUNDARY, SNC_SKELETON };
-
- class Polyhedron : public CGAL::OGL::OGL_base_object {
- public:
- std::list<DPoint> vertices_;
- std::list<DSegment> edges_;
- std::list<DFacet> halffacets_;
-
- GLuint object_list_;
- bool init_;
-
- Bbox_3 bbox_;
-
- int style;
- std::vector<bool> switches;
-
- typedef std::list<DPoint>::const_iterator Vertex_iterator;
- typedef std::list<DSegment>::const_iterator Edge_iterator;
- typedef std::list<DFacet>::const_iterator Halffacet_iterator;
-
- enum RenderColor {
- CGAL_NEF3_MARKED_VERTEX_COLOR,
- CGAL_NEF3_MARKED_EDGE_COLOR,
- CGAL_NEF3_MARKED_FACET_COLOR,
- CGAL_NEF3_UNMARKED_VERTEX_COLOR,
- CGAL_NEF3_UNMARKED_EDGE_COLOR,
- CGAL_NEF3_UNMARKED_FACET_COLOR,
- NUM_COLORS
- };
- static unsigned char colors[NUM_COLORS][3];
- public:
- Polyhedron() : bbox_(-1,-1,-1,1,1,1), switches(1) {
- object_list_ = 0;
- init_ = false;
- style = SNC_BOUNDARY;
- switches[SNC_AXES] = false;
- }
-
- ~Polyhedron()
- { if (object_list_) glDeleteLists(object_list_, 4); }
-
- void push_back(const Double_point& p, bool m) {
- vertices_.push_back(DPoint(p,m));
- }
- void push_back(const Double_segment& s, bool m)
- { edges_.push_back(DSegment(s,m)); }
- void push_back(const DFacet& f)
- { halffacets_.push_back(f); }
-
- void toggle(int index) {
- switches[index] = !switches[index];
- }
-
- void set_style(int index) {
- style = index;
- }
-
- bool is_initialized() const { return init_; }
-
- Bbox_3 bbox() const { return bbox_; }
- Bbox_3& bbox() { return bbox_; }
-
- void draw(Vertex_iterator v) const {
- // CGAL_NEF_TRACEN("drawing vertex "<<*v);
- unsigned char *c = v->mark() ? colors[CGAL_NEF3_UNMARKED_VERTEX_COLOR] : colors[CGAL_NEF3_MARKED_VERTEX_COLOR];
- glPointSize(10);
- glColor3ubv(c);
- glBegin(GL_POINTS);
- glVertex3d(v->x(),v->y(),v->z());
-#ifdef CGAL_NEF_EMPHASIZE_VERTEX
- glColor3ub(255,0,0);
- glVertex3d(CGAL_NEF_EMPHASIZE_VERTEX);
-#endif
- glEnd();
- }
-
- void draw(Edge_iterator e) const {
- // CGAL_NEF_TRACEN("drawing edge "<<*e);
- Double_point p = e->source(), q = e->target();
- unsigned char *c = e->mark() ? colors[CGAL_NEF3_UNMARKED_EDGE_COLOR] : colors[CGAL_NEF3_MARKED_EDGE_COLOR];
- glLineWidth(5);
- glColor3ubv(c);
- glBegin(GL_LINE_STRIP);
- glVertex3d(p.x(), p.y(), p.z());
- glVertex3d(q.x(), q.y(), q.z());
- glEnd();
- }
-
- void draw(Halffacet_iterator f) const {
- // CGAL_NEF_TRACEN("drawing facet "<<(f->debug(),""));
- GLUtesselator* tess_ = gluNewTess();
- gluTessCallback(tess_, GLenum(GLU_TESS_VERTEX_DATA),
- (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &vertexCallback);
- gluTessCallback(tess_, GLenum(GLU_TESS_COMBINE),
- (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &combineCallback);
- gluTessCallback(tess_, GLenum(GLU_TESS_BEGIN),
- (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &beginCallback);
- gluTessCallback(tess_, GLenum(GLU_TESS_END),
- (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &endCallback);
- gluTessCallback(tess_, GLenum(GLU_TESS_ERROR),
- (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &errorCallback);
- gluTessProperty(tess_, GLenum(GLU_TESS_WINDING_RULE),
- GLU_TESS_WINDING_POSITIVE);
-
- DFacet::Coord_const_iterator cit;
- unsigned char *c = f->mark() ? colors[CGAL_NEF3_UNMARKED_FACET_COLOR] : colors[CGAL_NEF3_MARKED_FACET_COLOR];
- glColor3ubv(c);
- gluTessBeginPolygon(tess_,f->normal());
- // CGAL_NEF_TRACEN(" ");
- // CGAL_NEF_TRACEN("Begin Polygon");
- gluTessNormal(tess_,f->dx(),f->dy(),f->dz());
- // forall facet cycles of f:
- for(unsigned i = 0; i < f->number_of_facet_cycles(); ++i) {
- gluTessBeginContour(tess_);
- // CGAL_NEF_TRACEN(" Begin Contour");
- // put all vertices in facet cycle into contour:
- for(cit = f->facet_cycle_begin(i);
- cit != f->facet_cycle_end(i); ++cit) {
- gluTessVertex(tess_, *cit, *cit);
- // CGAL_NEF_TRACEN(" add Vertex");
- }
- gluTessEndContour(tess_);
- // CGAL_NEF_TRACEN(" End Contour");
- }
- gluTessEndPolygon(tess_);
- // CGAL_NEF_TRACEN("End Polygon");
- gluDeleteTess(tess_);
- combineCallback(NULL, NULL, NULL, NULL);
- }
-
- void construct_axes() const
- {
- glLineWidth(2.0);
- // red x-axis
- glColor3f(1.0,0.0,0.0);
- glBegin(GL_LINES);
- glVertex3f(0.0,0.0,0.0);
- glVertex3f(5000.0,0.0,0.0);
- glEnd();
- // green y-axis
- glColor3f(0.0,1.0,0.0);
- glBegin(GL_LINES);
- glVertex3f(0.0,0.0,0.0);
- glVertex3f(0.0,5000.0,0.0);
- glEnd();
- // blue z-axis and equator
- glColor3f(0.0,0.0,1.0);
- glBegin(GL_LINES);
- glVertex3f(0.0,0.0,0.0);
- glVertex3f(0.0,0.0,5000.0);
- glEnd();
- // six coordinate points in pink:
- glPointSize(10);
- glBegin(GL_POINTS);
- glColor3f(1.0,0.0,0.0);
- glVertex3d(5,0,0);
- glColor3f(0.0,1.0,0.0);
- glVertex3d(0,5,0);
- glColor3f(0.0,0.0,1.0);
- glVertex3d(0,0,5);
- glEnd();
- }
-
-
- void fill_display_lists() {
- glNewList(object_list_, GL_COMPILE);
- Vertex_iterator v;
- for(v=vertices_.begin();v!=vertices_.end();++v)
- draw(v);
- glEndList();
-
- glNewList(object_list_+1, GL_COMPILE);
- Edge_iterator e;
- for(e=edges_.begin();e!=edges_.end();++e)
- draw(e);
- glEndList();
-
- glNewList(object_list_+2, GL_COMPILE);
- Halffacet_iterator f;
- for(f=halffacets_.begin();f!=halffacets_.end();++f)
- draw(f);
- glEndList();
-
- glNewList(object_list_+3, GL_COMPILE); // axes:
- construct_axes();
- glEndList();
-
- }
-
- void init() {
- if (init_) return;
- init_ = true;
- switches[SNC_AXES] = false;
- style = SNC_BOUNDARY;
- object_list_ = glGenLists(4);
- CGAL_assertion(object_list_);
- fill_display_lists();
- }
-
-
- void draw() const
- {
- if (!is_initialized()) const_cast<Polyhedron&>(*this).init();
- double l = (std::max)( (std::max)( bbox().xmax() - bbox().xmin(),
- bbox().ymax() - bbox().ymin()),
- bbox().zmax() - bbox().zmin());
- if ( l < 1) // make sure that a single point doesn't screw up here
- l = 1;
- glScaled( 4.0/l, 4.0/l, 4.0/l);
- glTranslated( -(bbox().xmax() + bbox().xmin()) / 2.0,
- -(bbox().ymax() + bbox().ymin()) / 2.0,
- -(bbox().zmax() + bbox().zmin()) / 2.0);
- if (style == SNC_BOUNDARY) {
- //glEnable(GL_LIGHTING);
- glCallList(object_list_+2); // facets
- //glDisable(GL_LIGHTING);
- }
- // move edges and vertices a bit towards the view-point,
- // i.e., 1/100th of the unit vector in camera space
- // double f = l / 4.0 / 100.0;
- // glTranslated( z_vec[0] * f, z_vec[1] * f, z_vec[2] * f);
- glCallList(object_list_+1); // edges
- glCallList(object_list_); // vertices
- if (switches[SNC_AXES]) glCallList(object_list_+3); // axis
- }
-
- void debug(std::ostream& os = std::cerr) const
- {
- os << "OGL::Polyhedron" << std::endl;
- os << "Vertices:" << std::endl;
- Vertex_iterator v;
- for(v=vertices_.begin();v!=vertices_.end();++v)
- os << " "<<*v<<", mark="<<v->mark()<<std::endl;
- os << "Edges:" << std::endl;
- Edge_iterator e;
- for(e=edges_.begin();e!=edges_.end();++e)
- os << " "<<*e<<", mark="<<e->mark()<<std::endl;
- os << "Facets:" << std::endl;
- Halffacet_iterator f;
- for(f=halffacets_.begin();f!=halffacets_.end();++f)
- f->debug(); os << std::endl;
- os << std::endl;
- }
-
- }; // Polyhedron
- unsigned char Polyhedron::colors[][3] = {
- {0xb7, 0xe8, 0x5c},
- {0xab, 0xd8, 0x56},
- {0x9d, 0xcb, 0x51},
- {0xff, 0xf6, 0x7c},
- {0xff, 0xec, 0x5e},
- {0xf9, 0xd7, 0x2c}
- };
-
- template<typename Nef_polyhedron>
- class Nef3_Converter {
- typedef typename Nef_polyhedron::SNC_structure SNC_structure;
- typedef CGAL::SNC_decorator<SNC_structure> Base;
- typedef CGAL::SNC_FM_decorator<SNC_structure> FM_decorator;
-
- public:
- typedef typename SNC_structure::Vertex_const_iterator Vertex_const_iterator;
- typedef typename SNC_structure::Halfedge_const_iterator Halfedge_const_iterator;
- typedef typename SNC_structure::Halffacet_const_iterator Halffacet_const_iterator;
- typedef typename SNC_structure::Halffacet_cycle_const_iterator Halffacet_cycle_const_iterator;
-
- typedef typename SNC_structure::Object_const_handle Object_const_handle;
- typedef typename SNC_structure::SHalfedge_const_handle SHalfedge_const_handle;
- typedef typename SNC_structure::SHalfloop_const_handle SHalfloop_const_handle;
-
- typedef typename SNC_structure::Vertex_const_handle Vertex_const_handle;
- typedef typename SNC_structure::Halfedge_const_handle Halfedge_const_handle;
- typedef typename SNC_structure::Halffacet_const_handle Halffacet_const_handle;
-
- typedef typename SNC_structure::Point_3 Point_3;
- typedef typename SNC_structure::Vector_3 Vector_3;
- typedef typename SNC_structure::Segment_3 Segment_3;
- typedef typename SNC_structure::Plane_3 Plane_3;
- typedef typename SNC_structure::Mark Mark;
- typedef typename SNC_structure::SHalfedge_around_facet_const_circulator
- SHalfedge_around_facet_const_circulator;
-
- private:
- static OGL::Double_point double_point(const Point_3& p)
- { return OGL::Double_point(CGAL::to_double(p.x()),
- CGAL::to_double(p.y()),
- CGAL::to_double(p.z())); }
-
- static OGL::Double_segment double_segment(const Segment_3& s)
- { return OGL::Double_segment(double_point(s.source()),
- double_point(s.target())); }
-
- static void draw(Vertex_const_handle v, const Nef_polyhedron& ,
- Polyhedron& P) {
- Point_3 bp = v->point();
- // CGAL_NEF_TRACEN("vertex " << bp);
- P.push_back(double_point(bp), v->mark());
- }
-
- static void draw(Halfedge_const_handle e, const Nef_polyhedron& ,
- Polyhedron& P) {
- Vertex_const_handle s = e->source();
- Vertex_const_handle t = e->twin()->source();
- Segment_3 seg(s->point(),t->point());
- // CGAL_NEF_TRACEN("edge " << seg);
- P.push_back(double_segment(seg), e->mark());
- }
-
- static void draw(Halffacet_const_handle f, const Nef_polyhedron& ,
- Polyhedron& P) {
- OGL::DFacet g;
- Halffacet_cycle_const_iterator fc; // all facet cycles:
- CGAL_forall_facet_cycles_of(fc,f)
- if ( fc.is_shalfedge() ) { // non-trivial facet cycle
- g.new_facet_cycle();
- SHalfedge_const_handle h = fc;
- SHalfedge_around_facet_const_circulator hc(h), he(hc);
- CGAL_For_all(hc,he){ // all vertex coordinates in facet cycle
- Point_3 sp = hc->source()->source()->point();
- // CGAL_NEF_TRACEN(" ");CGAL_NEF_TRACEN("facet" << sp);
- g.push_back_vertex(double_point(sp));
- }
- }
- Vector_3 v = f->plane().orthogonal_vector();
- g.set_normal(CGAL::to_double(v.x()),
- CGAL::to_double(v.y()),
- CGAL::to_double(v.z()),
- f->mark());
- P.push_back(g);
- }
-
- // Returns the bounding box of the finite vertices of the polyhedron.
- // Returns $[-1,+1]^3$ as bounding box if no finite vertex exists.
-
- static Bbox_3 bounded_bbox(const Nef_polyhedron& N) {
- bool first_vertex = true;
- Bbox_3 bbox( -1.0, -1.0, -1.0, 1.0, 1.0, 1.0);
- Vertex_const_iterator vi;
- CGAL_forall_vertices(vi, N) {
- Point_3 p = vi->point();
- double x = CGAL::to_double(p.hx());
- double y = CGAL::to_double(p.hy());
- double z = CGAL::to_double(p.hz());
- double w = CGAL::to_double(p.hw());
- if (N.is_standard(vi)) {
- if(first_vertex) {
- bbox = Bbox_3(x/w, y/w, z/w, x/w, y/w, z/w);
- first_vertex = false;
- } else {
- bbox = bbox + Bbox_3(x/w, y/w, z/w, x/w, y/w, z/w);
- first_vertex = false;
- }
- }
- }
- return bbox;
- }
-
- static void set_R(Bbox_3& bbox, const Nef_polyhedron& N) {
- if(N.is_standard_kernel()) return;
- double size = abs(bbox.xmin());
- if(size < bbox.xmax()) size = bbox.xmax();
- if(size < bbox.ymin()) size = bbox.ymin();
- if(size < bbox.ymax()) size = bbox.ymax();
- if(size < bbox.zmin()) size = bbox.zmin();
- if(size < bbox.zmax()) size = bbox.zmax();
- N.set_size_of_infimaximal_box(size*50);
- // CGAL_NEF_TRACEN("set infi box size to " << size);
- Vertex_const_iterator vi;
- CGAL_forall_vertices(vi, N)
- if(N.is_standard(vi))
- return;
- bbox = Bbox_3(bbox.xmin()*10,bbox.ymin()*10,bbox.zmin()*10,
- bbox.xmax()*10,bbox.ymax()*10,bbox.zmax()*10);
- }
- public:
- static void setColor(Polyhedron::RenderColor color_index,
- unsigned char r, unsigned char g, unsigned char b) {
- assert(color_index < Polyhedron::NUM_COLORS);
- Polyhedron::colors[color_index][0] = r;
- Polyhedron::colors[color_index][1] = g;
- Polyhedron::colors[color_index][2] = b;
- }
-
- static void convert_to_OGLPolyhedron(const Nef_polyhedron& N, Polyhedron* P) {
- Bbox_3 bbox(bounded_bbox(N));
- set_R(bbox,N);
- P->bbox() = bbox;
- Vertex_const_iterator v;
- CGAL_forall_vertices(v,*N.sncp()) draw(v,N,*P);
- Halfedge_const_iterator e;
- CGAL_forall_edges(e,*N.sncp()) draw(e,N,*P);
- Halffacet_const_iterator f;
- CGAL_forall_facets(f,*N.sncp()) draw(f,N,*P);
- }
-
- }; // Nef3_Converter
-
- } // namespace OGL
-
-} // namespace OpenSCAD
-
-#endif // CGAL_NEF_OPENGL_HELPER_H
+ }
+ CGAL::Color getVertexColor(Vertex_iterator v) const {
+ CGAL::Color c = v->mark() ? colors[CGAL_NEF3_UNMARKED_VERTEX_COLOR] : colors[CGAL_NEF3_MARKED_VERTEX_COLOR];
+ return c;
+ }
+
+ CGAL::Color getEdgeColor(Edge_iterator e) const {
+ CGAL::Color c = e->mark() ? colors[CGAL_NEF3_UNMARKED_EDGE_COLOR] : colors[CGAL_NEF3_MARKED_EDGE_COLOR];
+ return c;
+ }
+
+ CGAL::Color getFacetColor(Halffacet_iterator f) const {
+ CGAL::Color c = f->mark() ? colors[CGAL_NEF3_UNMARKED_FACET_COLOR] : colors[CGAL_NEF3_MARKED_FACET_COLOR];
+ return c;
+ }
+
+ void setColor(Polyhedron::RenderColor color_index,
+ unsigned char r, unsigned char g, unsigned char b) {
+ assert(color_index < Polyhedron::NUM_COLORS);
+ this->colors[color_index] = CGAL::Color(r,g,b);
+ }
+private:
+ CGAL::Color colors[NUM_COLORS];
+
+}; // Polyhedron
+
+#endif // CGAL_RENDERER_H
diff --git a/src/GLView.h b/src/GLView.h
index 7516894..764b23b 100644
--- a/src/GLView.h
+++ b/src/GLView.h
@@ -12,24 +12,31 @@
class GLView : public QGLWidget
{
Q_OBJECT
+ Q_PROPERTY(bool showFaces READ showFaces WRITE setShowFaces);
+ Q_PROPERTY(bool showEdges READ showEdges WRITE setShowEdges);
Q_PROPERTY(bool showAxes READ showAxes WRITE setShowAxes);
Q_PROPERTY(bool showCrosshairs READ showCrosshairs WRITE setShowCrosshairs);
Q_PROPERTY(bool orthoMode READ orthoMode WRITE setOrthoMode);
public:
GLView(QWidget *parent = NULL);
- void setRenderFunc(void (*func)(void*), void *userdata);
+ void setRenderer(class Renderer* r);
#ifdef ENABLE_OPENCSG
bool hasOpenCSGSupport() { return this->opencsg_support; }
#endif
// Properties
+ bool showFaces() const { return this->showfaces; }
+ void setShowFaces(bool enabled) { this->showfaces = enabled; }
+ bool showEdges() const { return this->showedges; }
+ void setShowEdges(bool enabled) { this->showedges = enabled; }
bool showAxes() const { return this->showaxes; }
void setShowAxes(bool enabled) { this->showaxes = enabled; }
bool showCrosshairs() const { return this->showcrosshairs; }
void setShowCrosshairs(bool enabled) { this->showcrosshairs = enabled; }
bool orthoMode() const { return this->orthomode; }
void setOrthoMode(bool enabled) { this->orthomode = enabled; }
-
+
+public:
QLabel *statusLabel;
double object_rot_x;
double object_rot_y;
@@ -45,9 +52,10 @@ public:
#endif
private:
- void (*renderfunc)(void*);
- void *renderfunc_vp;
+ Renderer *renderer;
+ bool showfaces;
+ bool showedges;
bool showaxes;
bool showcrosshairs;
bool orthomode;
@@ -57,8 +65,7 @@ private:
double w_h_ratio;
bool mouse_drag_active;
- int last_mouse_x;
- int last_mouse_y;
+ QPoint last_mouse;
void keyPressEvent(QKeyEvent *event);
void wheelEvent(QWheelEvent *event);
@@ -68,7 +75,10 @@ private:
void initializeGL();
void resizeGL(int w, int h);
+ void setupPerspective();
+ void setupOrtho(double distance,bool offset=false);
void paintGL();
+ void normalizeAngle(GLdouble& angle);
#ifdef ENABLE_OPENCSG
private slots:
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 43ab273..243a5ad 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -38,17 +38,18 @@ public:
class CSGChain *root_chain;
#ifdef ENABLE_CGAL
class CGAL_Nef_polyhedron *root_N;
- bool recreate_cgal_ogl_p;
- void *cgal_ogl_p;
- PolySet *cgal_ogl_ps;
+ class CGALRenderer *cgalRenderer;
#endif
+#ifdef ENABLE_OPENCSG
+ class OpenCSGRenderer *opencsgRenderer;
+#endif
+ class ThrownTogetherRenderer *thrownTogetherRenderer;
QVector<CSGTerm*> highlight_terms;
CSGChain *highlights_chain;
QVector<CSGTerm*> background_terms;
CSGChain *background_chain;
QString last_compiled_doc;
- bool enableOpenCSG;
static const int maxRecentFiles = 10;
QAction *actionRecentFile[maxRecentFiles];
diff --git a/src/OGL_helper.h b/src/OGL_helper.h
new file mode 100644
index 0000000..2aae31b
--- /dev/null
+++ b/src/OGL_helper.h
@@ -0,0 +1,687 @@
+// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org); you may redistribute it under
+// the terms of the Q Public License version 1.0.
+// See the file LICENSE.QPL distributed with CGAL.
+//
+// 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: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.7-branch/Nef_3/include/CGAL/Nef_3/OGL_helper.h $
+// $Id: OGL_helper.h 56667 2010-06-09 07:37:13Z sloriot $
+//
+//
+// Author(s) : Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
+
+#ifndef CGAL_NEF_OPENGL_HELPER_H
+#define CGAL_NEF_OPENGL_HELPER_H
+
+#include <CGAL/Nef_S2/OGL_base_object.h>
+#include <CGAL/Simple_cartesian.h>
+#include <CGAL/Nef_3/SNC_decorator.h>
+#include <qgl.h>
+#include <cstdlib>
+
+#define CGAL_NEF3_MARKED_VERTEX_COLOR 183,232,92
+#define CGAL_NEF3_MARKED_EDGE_COLOR 171,216,86
+#define CGAL_NEF3_MARKED_FACET_COLOR 157,203,81
+
+#define CGAL_NEF3_UNMARKED_VERTEX_COLOR 255,246,124
+#define CGAL_NEF3_UNMARKED_EDGE_COLOR 255,236,94
+#define CGAL_NEF3_UNMARKED_FACET_COLOR 249,215,44
+
+#ifdef _WIN32
+#define CGAL_GLU_TESS_CALLBACK CALLBACK
+#else
+#define CGAL_GLU_TESS_CALLBACK
+#endif
+
+#ifdef __APPLE__
+# include <AvailabilityMacros.h>
+#endif
+
+#if defined __APPLE__ && !defined MAC_OS_X_VERSION_10_5
+ #define CGAL_GLU_TESS_DOTS ...
+#else
+ #define CGAL_GLU_TESS_DOTS
+#endif
+
+
+namespace CGAL {
+
+namespace OGL {
+
+// ----------------------------------------------------------------------------
+// Drawable double types:
+// ----------------------------------------------------------------------------
+
+ typedef CGAL::Simple_cartesian<double> DKernel;
+ typedef DKernel::Point_3 Double_point;
+ typedef DKernel::Vector_3 Double_vector;
+ typedef DKernel::Segment_3 Double_segment;
+ typedef DKernel::Aff_transformation_3 Affine_3;
+
+ // DPoint = a double point including a mark
+ class DPoint : public Double_point {
+ bool m_;
+ public:
+ DPoint() {}
+ DPoint(const Double_point& p, bool m) : Double_point(p) { m_ = m; }
+ DPoint(const DPoint& p) : Double_point(p) { m_ = p.m_; }
+ DPoint& operator=(const DPoint& p)
+ { Double_point::operator=(p); m_ = p.m_; return *this; }
+ bool mark() const { return m_; }
+ };
+
+ // DSegment = a double segment including a mark
+ class DSegment : public Double_segment {
+ bool m_;
+ public:
+ DSegment() {}
+ DSegment(const Double_segment& s, bool m) : Double_segment(s) { m_ = m; }
+ DSegment(const DSegment& s) : Double_segment(s) { m_ = s.m_; }
+ DSegment& operator=(const DSegment& s)
+ { Double_segment::operator=(s); m_ = s.m_; return *this; }
+ bool mark() const { return m_; }
+ };
+
+ // Double_triple = a class that stores a triple of double
+ // coordinates; we need a pointer to the coordinates in a C array
+ // for OpenGL
+ class Double_triple {
+ typedef double* double_ptr;
+ typedef const double* const_double_ptr;
+ double coords_[3];
+ public:
+ Double_triple()
+ { coords_[0]=coords_[1]=coords_[2]=0.0; }
+ Double_triple(double x, double y, double z)
+ { coords_[0]=x; coords_[1]=y; coords_[2]=z; }
+ Double_triple(const Double_triple& t)
+ { coords_[0]=t.coords_[0];
+ coords_[1]=t.coords_[1];
+ coords_[2]=t.coords_[2];
+ }
+ Double_triple& operator=(const Double_triple& t)
+ { coords_[0]=t.coords_[0];
+ coords_[1]=t.coords_[1];
+ coords_[2]=t.coords_[2];
+ return *this; }
+ operator double_ptr() const
+ { return const_cast<Double_triple&>(*this).coords_; }
+ double operator[](unsigned i)
+ { CGAL_assertion(i<3); return coords_[i]; }
+ }; // Double_triple
+
+ static std::ostream& operator << (std::ostream& os,
+ const Double_triple& t)
+ { os << "(" << t[0] << "," << t[1] << "," << t[2] << ")";
+ return os; }
+
+
+ // DFacet stores the facet cycle vertices in a continuus C array
+ // of three double components, this is necessary due to the OpenGL
+ // tesselator input format !
+ class DFacet {
+ typedef std::vector<Double_triple> Coord_vector;
+ typedef std::vector<unsigned> Cycle_vector;
+ Coord_vector coords_; // stores all vertex coordinates
+ Cycle_vector fc_ends_; // stores entry points of facet cycles
+ Double_triple normal_; // stores normal and mark of facet
+ bool mark_;
+
+ public:
+ typedef Coord_vector::iterator Coord_iterator;
+ typedef Coord_vector::const_iterator Coord_const_iterator;
+
+ DFacet() {}
+
+ void push_back_vertex(double x, double y, double z)
+ { coords_.push_back(Double_triple(x,y,z)); }
+
+ DFacet(const DFacet& f)
+ { coords_ = f.coords_;
+ fc_ends_ = f.fc_ends_;
+ normal_ = f.normal_;
+ mark_ = f.mark_;
+ }
+
+ DFacet& operator=(const DFacet& f)
+ { coords_ = f.coords_;
+ fc_ends_ = f.fc_ends_;
+ normal_ = f.normal_;
+ mark_ = f.mark_;
+ return *this;
+ }
+
+ ~DFacet()
+ { coords_.clear(); fc_ends_.clear(); }
+
+ void push_back_vertex(const Double_point& p)
+ { push_back_vertex(p.x(),p.y(),p.z()); }
+
+ void set_normal(double x, double y, double z, bool m)
+ { double l = sqrt(x*x + y*y + z*z);
+ normal_ = Double_triple(x/l,y/l,z/l); mark_ = m; }
+
+ double dx() const { return normal_[0]; }
+ double dy() const { return normal_[1]; }
+ double dz() const { return normal_[2]; }
+ bool mark() const { return mark_; }
+ double* normal() const
+ { return static_cast<double*>(normal_); }
+
+ void new_facet_cycle()
+ { fc_ends_.push_back(coords_.size()); }
+
+ unsigned number_of_facet_cycles() const
+ { return fc_ends_.size(); }
+
+ Coord_iterator facet_cycle_begin(unsigned i)
+ { CGAL_assertion(i<number_of_facet_cycles());
+ if (i==0) return coords_.begin();
+ else return coords_.begin()+fc_ends_[i]; }
+
+ Coord_iterator facet_cycle_end(unsigned i)
+ { CGAL_assertion(i<number_of_facet_cycles());
+ if (i<fc_ends_.size()-1) return coords_.begin()+fc_ends_[i+1];
+ else return coords_.end(); }
+
+ Coord_const_iterator facet_cycle_begin(unsigned i) const
+ { CGAL_assertion(i<number_of_facet_cycles());
+ if (i==0) return coords_.begin();
+ else return coords_.begin()+fc_ends_[i]; }
+
+ Coord_const_iterator facet_cycle_end(unsigned i) const
+ { CGAL_assertion(i<number_of_facet_cycles());
+ if (i<fc_ends_.size()-1) return coords_.begin()+fc_ends_[i+1];
+ else return coords_.end(); }
+
+ void debug(std::ostream& os = std::cerr) const
+ { os << "DFacet, normal=" << normal_ << ", mark=" << mark() << std::endl;
+ for(unsigned i=0; i<number_of_facet_cycles(); ++i) {
+ os << " facet cycle ";
+ // put all vertices in facet cycle into contour:
+ Coord_const_iterator cit;
+ for(cit = facet_cycle_begin(i); cit != facet_cycle_end(i); ++cit)
+ os << *cit;
+ os << std::endl;
+ }
+ }
+
+ }; // DFacet
+
+
+// ----------------------------------------------------------------------------
+// OGL Drawable Polyhedron:
+// ----------------------------------------------------------------------------
+
+ inline void CGAL_GLU_TESS_CALLBACK beginCallback(GLenum which)
+ { glBegin(which); }
+
+ inline void CGAL_GLU_TESS_CALLBACK endCallback(void)
+ { glEnd(); }
+
+ inline void CGAL_GLU_TESS_CALLBACK errorCallback(GLenum errorCode)
+ { const GLubyte *estring;
+ estring = gluErrorString(errorCode);
+ fprintf(stderr, "Tessellation Error: %s\n", estring);
+ std::exit (0);
+ }
+
+ inline void CGAL_GLU_TESS_CALLBACK vertexCallback(GLvoid* vertex,
+ GLvoid* user)
+ { GLdouble* pc(static_cast<GLdouble*>(vertex));
+ GLdouble* pu(static_cast<GLdouble*>(user));
+ // CGAL_NEF_TRACEN("vertexCallback coord "<<pc[0]<<","<<pc[1]<<","<<pc[2]);
+ // CGAL_NEF_TRACEN("vertexCallback normal "<<pu[0]<<","<<pu[1]<<","<<pu[2]);
+ glNormal3dv(pu);
+ glVertex3dv(pc);
+ }
+
+
+ enum { SNC_AXES};
+ enum { SNC_BOUNDARY, SNC_SKELETON };
+
+ class Polyhedron : public OGL_base_object {
+ protected:
+ std::list<DPoint> vertices_;
+ std::list<DSegment> edges_;
+ std::list<DFacet> halffacets_;
+
+ GLuint object_list_;
+ bool init_;
+
+ Bbox_3 bbox_;
+
+ int style;
+ std::vector<bool> switches;
+
+ typedef std::list<DPoint>::const_iterator Vertex_iterator;
+ typedef std::list<DSegment>::const_iterator Edge_iterator;
+ typedef std::list<DFacet>::const_iterator Halffacet_iterator;
+
+ public:
+ Polyhedron() : bbox_(-1,-1,-1,1,1,1), switches(1) {
+ object_list_ = 0;
+ init_ = false;
+ style = SNC_BOUNDARY;
+ switches[SNC_AXES] = false;
+ }
+
+ /*
+ Polyhedron(const Polyhedron& P) :
+ object_list_(0),
+ init_(false),
+ bbox_(P.bbox_),
+ style(P.style),
+ switches(2) {
+
+ switches[SNC_AXES] = P.switches[SNC_AXES];
+
+ Vertex_iterator v;
+ for(v=P.vertices_.begin();v!=P.vertices_.end();++v)
+ vertices_.push_back(*v);
+ Edge_iterator e;
+ for(e=P.edges_.begin();e!=P.edges_.end();++e)
+ edges_.push_back(*e);
+ Halffacet_iterator f;
+ for(f=P.halffacets_.begin();f!=P.halffacets_.end();++f)
+ halffacets_.push_back(*f);
+ }
+
+ Polyhedron& operator=(const Polyhedron& P) {
+ if (object_list_) glDeleteLists(object_list_, 4);
+ object_list_ = 0;
+ init_ = false;
+ style = P.style;
+ switches[SNC_AXES] = P.switches[SNC_AXES];
+
+ Vertex_iterator v;
+ vertices_.clear();
+ for(v=P.vertices_.begin();v!=P.vertices_.end();++v)
+ vertices_.push_back(*v);
+ Edge_iterator e;
+ edges_.clear();
+ for(e=P.edges_.begin();e!=P.edges_.end();++e)
+ edges_.push_back(*e);
+ Halffacet_iterator f;
+ halffacets_.clear();
+ for(f=P.halffacets_.begin();f!=P.halffacets_.end();++f)
+ halffacets_.push_back(*f);
+ init();
+ return *this;
+ }
+ */
+ ~Polyhedron()
+ { if (object_list_) glDeleteLists(object_list_, 4); }
+
+ void push_back(const Double_point& p, bool m) {
+ vertices_.push_back(DPoint(p,m));
+ }
+ void push_back(const Double_segment& s, bool m)
+ { edges_.push_back(DSegment(s,m)); }
+ void push_back(const DFacet& f)
+ { halffacets_.push_back(f); }
+
+ void toggle(int index) {
+ switches[index] = !switches[index];
+ }
+
+ void set_style(int index) {
+ style = index;
+ }
+
+ bool is_initialized() const { return init_; }
+
+ Bbox_3 bbox() const { return bbox_; }
+ Bbox_3& bbox() { return bbox_; }
+
+ virtual CGAL::Color getVertexColor(Vertex_iterator v) const
+ {
+ CGAL::Color cf(CGAL_NEF3_MARKED_VERTEX_COLOR),
+ ct(CGAL_NEF3_UNMARKED_VERTEX_COLOR); // more blue-ish
+ CGAL::Color c = v->mark() ? ct : cf;
+ return c;
+ }
+
+ void draw(Vertex_iterator v) const {
+ // CGAL_NEF_TRACEN("drawing vertex "<<*v);
+ CGAL::Color c = getVertexColor(v);
+ glPointSize(10);
+ glColor3ub(c.red(), c.green(), c.blue());
+ glBegin(GL_POINTS);
+ glVertex3d(v->x(),v->y(),v->z());
+#ifdef CGAL_NEF_EMPHASIZE_VERTEX
+ glColor3ub(255,0,0);
+ glVertex3d(CGAL_NEF_EMPHASIZE_VERTEX);
+#endif
+ glEnd();
+ }
+
+ virtual CGAL::Color getEdgeColor(Edge_iterator e) const
+ {
+ CGAL::Color cf(CGAL_NEF3_MARKED_EDGE_COLOR),
+ ct(CGAL_NEF3_UNMARKED_EDGE_COLOR); // more blue-ish
+ CGAL::Color c = e->mark() ? ct : cf;
+ return c;
+ }
+
+ void draw(Edge_iterator e) const {
+ // CGAL_NEF_TRACEN("drawing edge "<<*e);
+ Double_point p = e->source(), q = e->target();
+ CGAL::Color c = getEdgeColor(e);
+ glLineWidth(5);
+ glColor3ub(c.red(),c.green(),c.blue());
+ glBegin(GL_LINE_STRIP);
+ glVertex3d(p.x(), p.y(), p.z());
+ glVertex3d(q.x(), q.y(), q.z());
+ glEnd();
+ }
+
+ virtual CGAL::Color getFacetColor(Halffacet_iterator f) const
+ {
+ CGAL::Color cf(CGAL_NEF3_MARKED_FACET_COLOR),
+ ct(CGAL_NEF3_UNMARKED_FACET_COLOR); // more blue-ish
+ CGAL::Color c = (f->mark() ? ct : cf);
+ return c;
+ }
+
+ void draw(Halffacet_iterator f) const {
+ // CGAL_NEF_TRACEN("drawing facet "<<(f->debug(),""));
+ GLUtesselator* tess_ = gluNewTess();
+ gluTessCallback(tess_, GLenum(GLU_TESS_VERTEX_DATA),
+ (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &vertexCallback);
+ gluTessCallback(tess_, GLenum(GLU_TESS_BEGIN),
+ (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &beginCallback);
+ gluTessCallback(tess_, GLenum(GLU_TESS_END),
+ (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &endCallback);
+ gluTessCallback(tess_, GLenum(GLU_TESS_ERROR),
+ (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &errorCallback);
+ gluTessProperty(tess_, GLenum(GLU_TESS_WINDING_RULE),
+ GLU_TESS_WINDING_POSITIVE);
+
+ DFacet::Coord_const_iterator cit;
+ CGAL::Color c = getFacetColor(f);
+ glColor3ub(c.red(),c.green(),c.blue());
+ gluTessBeginPolygon(tess_,f->normal());
+ // CGAL_NEF_TRACEN(" ");
+ // CGAL_NEF_TRACEN("Begin Polygon");
+ gluTessNormal(tess_,f->dx(),f->dy(),f->dz());
+ // forall facet cycles of f:
+ for(unsigned i = 0; i < f->number_of_facet_cycles(); ++i) {
+ gluTessBeginContour(tess_);
+ // CGAL_NEF_TRACEN(" Begin Contour");
+ // put all vertices in facet cycle into contour:
+ for(cit = f->facet_cycle_begin(i);
+ cit != f->facet_cycle_end(i); ++cit) {
+ gluTessVertex(tess_, *cit, *cit);
+ // CGAL_NEF_TRACEN(" add Vertex");
+ }
+ gluTessEndContour(tess_);
+ // CGAL_NEF_TRACEN(" End Contour");
+ }
+ gluTessEndPolygon(tess_);
+ // CGAL_NEF_TRACEN("End Polygon");
+ gluDeleteTess(tess_);
+ }
+
+ void construct_axes() const
+ {
+ glLineWidth(2.0);
+ // red x-axis
+ glColor3f(1.0,0.0,0.0);
+ glBegin(GL_LINES);
+ glVertex3f(0.0,0.0,0.0);
+ glVertex3f(5000.0,0.0,0.0);
+ glEnd();
+ // green y-axis
+ glColor3f(0.0,1.0,0.0);
+ glBegin(GL_LINES);
+ glVertex3f(0.0,0.0,0.0);
+ glVertex3f(0.0,5000.0,0.0);
+ glEnd();
+ // blue z-axis and equator
+ glColor3f(0.0,0.0,1.0);
+ glBegin(GL_LINES);
+ glVertex3f(0.0,0.0,0.0);
+ glVertex3f(0.0,0.0,5000.0);
+ glEnd();
+ // six coordinate points in pink:
+ glPointSize(10);
+ glBegin(GL_POINTS);
+ glColor3f(1.0,0.0,0.0);
+ glVertex3d(5,0,0);
+ glColor3f(0.0,1.0,0.0);
+ glVertex3d(0,5,0);
+ glColor3f(0.0,0.0,1.0);
+ glVertex3d(0,0,5);
+ glEnd();
+ }
+
+
+ void fill_display_lists() {
+ glNewList(object_list_, GL_COMPILE);
+ Vertex_iterator v;
+ for(v=vertices_.begin();v!=vertices_.end();++v)
+ draw(v);
+ glEndList();
+
+ glNewList(object_list_+1, GL_COMPILE);
+ Edge_iterator e;
+ for(e=edges_.begin();e!=edges_.end();++e)
+ draw(e);
+ glEndList();
+
+ glNewList(object_list_+2, GL_COMPILE);
+ Halffacet_iterator f;
+ for(f=halffacets_.begin();f!=halffacets_.end();++f)
+ draw(f);
+ glEndList();
+
+ glNewList(object_list_+3, GL_COMPILE); // axes:
+ construct_axes();
+ glEndList();
+
+ }
+
+ void init() {
+ if (init_) return;
+ init_ = true;
+ switches[SNC_AXES] = false;
+ style = SNC_BOUNDARY;
+ object_list_ = glGenLists(4);
+ CGAL_assertion(object_list_);
+ fill_display_lists();
+ }
+
+
+ void draw() const
+ {
+ if (!is_initialized()) const_cast<Polyhedron&>(*this).init();
+ double l = (std::max)( (std::max)( bbox().xmax() - bbox().xmin(),
+ bbox().ymax() - bbox().ymin()),
+ bbox().zmax() - bbox().zmin());
+ if ( l < 1) // make sure that a single point doesn't screw up here
+ l = 1;
+ glScaled( 4.0/l, 4.0/l, 4.0/l);
+ glTranslated( -(bbox().xmax() + bbox().xmin()) / 2.0,
+ -(bbox().ymax() + bbox().ymin()) / 2.0,
+ -(bbox().zmax() + bbox().zmin()) / 2.0);
+ if (style == SNC_BOUNDARY) {
+ //glEnable(GL_LIGHTING);
+ glCallList(object_list_+2); // facets
+ //glDisable(GL_LIGHTING);
+ }
+ // move edges and vertices a bit towards the view-point,
+ // i.e., 1/100th of the unit vector in camera space
+ // double f = l / 4.0 / 100.0;
+ // glTranslated( z_vec[0] * f, z_vec[1] * f, z_vec[2] * f);
+ glCallList(object_list_+1); // edges
+ glCallList(object_list_); // vertices
+ if (switches[SNC_AXES]) glCallList(object_list_+3); // axis
+ }
+
+ void debug(std::ostream& os = std::cerr) const
+ {
+ os << "OGL::Polyhedron" << std::endl;
+ os << "Vertices:" << std::endl;
+ Vertex_iterator v;
+ for(v=vertices_.begin();v!=vertices_.end();++v)
+ os << " "<<*v<<", mark="<<v->mark()<<std::endl;
+ os << "Edges:" << std::endl;
+ Edge_iterator e;
+ for(e=edges_.begin();e!=edges_.end();++e)
+ os << " "<<*e<<", mark="<<e->mark()<<std::endl;
+ os << "Facets:" << std::endl;
+ Halffacet_iterator f;
+ for(f=halffacets_.begin();f!=halffacets_.end();++f)
+ f->debug(); os << std::endl;
+ os << std::endl;
+ }
+
+ }; // Polyhedron
+
+ template<typename Nef_polyhedron>
+ class Nef3_Converter {
+ typedef typename Nef_polyhedron::SNC_structure SNC_structure;
+ typedef CGAL::SNC_decorator<SNC_structure> Base;
+ typedef CGAL::SNC_FM_decorator<SNC_structure> FM_decorator;
+
+ public:
+ typedef typename SNC_structure::Vertex_const_iterator Vertex_const_iterator;
+ typedef typename SNC_structure::Halfedge_const_iterator Halfedge_const_iterator;
+ typedef typename SNC_structure::Halffacet_const_iterator Halffacet_const_iterator;
+ typedef typename SNC_structure::Halffacet_cycle_const_iterator Halffacet_cycle_const_iterator;
+
+ typedef typename SNC_structure::Object_const_handle Object_const_handle;
+ typedef typename SNC_structure::SHalfedge_const_handle SHalfedge_const_handle;
+ typedef typename SNC_structure::SHalfloop_const_handle SHalfloop_const_handle;
+
+ typedef typename SNC_structure::Vertex_const_handle Vertex_const_handle;
+ typedef typename SNC_structure::Halfedge_const_handle Halfedge_const_handle;
+ typedef typename SNC_structure::Halffacet_const_handle Halffacet_const_handle;
+
+ typedef typename SNC_structure::Point_3 Point_3;
+ typedef typename SNC_structure::Vector_3 Vector_3;
+ typedef typename SNC_structure::Segment_3 Segment_3;
+ typedef typename SNC_structure::Plane_3 Plane_3;
+ typedef typename SNC_structure::Mark Mark;
+ typedef typename SNC_structure::SHalfedge_around_facet_const_circulator
+ SHalfedge_around_facet_const_circulator;
+
+ private:
+ static OGL::Double_point double_point(const Point_3& p)
+ { return OGL::Double_point(CGAL::to_double(p.x()),
+ CGAL::to_double(p.y()),
+ CGAL::to_double(p.z())); }
+
+ static OGL::Double_segment double_segment(const Segment_3& s)
+ { return OGL::Double_segment(double_point(s.source()),
+ double_point(s.target())); }
+
+ static void draw(Vertex_const_handle v, const Nef_polyhedron& ,
+ CGAL::OGL::Polyhedron& P) {
+ Point_3 bp = v->point();
+ // CGAL_NEF_TRACEN("vertex " << bp);
+ P.push_back(double_point(bp), v->mark());
+ }
+
+ static void draw(Halfedge_const_handle e, const Nef_polyhedron& ,
+ CGAL::OGL::Polyhedron& P) {
+ Vertex_const_handle s = e->source();
+ Vertex_const_handle t = e->twin()->source();
+ Segment_3 seg(s->point(),t->point());
+ // CGAL_NEF_TRACEN("edge " << seg);
+ P.push_back(double_segment(seg), e->mark());
+ }
+
+ static void draw(Halffacet_const_handle f, const Nef_polyhedron& ,
+ CGAL::OGL::Polyhedron& P) {
+ OGL::DFacet g;
+ Halffacet_cycle_const_iterator fc; // all facet cycles:
+ CGAL_forall_facet_cycles_of(fc,f)
+ if ( fc.is_shalfedge() ) { // non-trivial facet cycle
+ g.new_facet_cycle();
+ SHalfedge_const_handle h = fc;
+ SHalfedge_around_facet_const_circulator hc(h), he(hc);
+ CGAL_For_all(hc,he){ // all vertex coordinates in facet cycle
+ Point_3 sp = hc->source()->source()->point();
+ // CGAL_NEF_TRACEN(" ");CGAL_NEF_TRACEN("facet" << sp);
+ g.push_back_vertex(double_point(sp));
+ }
+ }
+ Vector_3 v = f->plane().orthogonal_vector();
+ g.set_normal(CGAL::to_double(v.x()),
+ CGAL::to_double(v.y()),
+ CGAL::to_double(v.z()),
+ f->mark());
+ P.push_back(g);
+ }
+
+ // Returns the bounding box of the finite vertices of the polyhedron.
+ // Returns $[-1,+1]^3$ as bounding box if no finite vertex exists.
+
+ static Bbox_3 bounded_bbox(const Nef_polyhedron& N) {
+ bool first_vertex = true;
+ Bbox_3 bbox( -1.0, -1.0, -1.0, 1.0, 1.0, 1.0);
+ Vertex_const_iterator vi;
+ CGAL_forall_vertices(vi, N) {
+ Point_3 p = vi->point();
+ double x = CGAL::to_double(p.hx());
+ double y = CGAL::to_double(p.hy());
+ double z = CGAL::to_double(p.hz());
+ double w = CGAL::to_double(p.hw());
+ if (N.is_standard(vi)) {
+ if(first_vertex) {
+ bbox = Bbox_3(x/w, y/w, z/w, x/w, y/w, z/w);
+ first_vertex = false;
+ } else {
+ bbox = bbox + Bbox_3(x/w, y/w, z/w, x/w, y/w, z/w);
+ first_vertex = false;
+ }
+ }
+ }
+ return bbox;
+ }
+
+ static void set_R(Bbox_3& bbox, const Nef_polyhedron& N) {
+ if(N.is_standard_kernel()) return;
+ double size = abs(bbox.xmin());
+ if(size < bbox.xmax()) size = bbox.xmax();
+ if(size < bbox.ymin()) size = bbox.ymin();
+ if(size < bbox.ymax()) size = bbox.ymax();
+ if(size < bbox.zmin()) size = bbox.zmin();
+ if(size < bbox.zmax()) size = bbox.zmax();
+ N.set_size_of_infimaximal_box(size*50);
+ // CGAL_NEF_TRACEN("set infi box size to " << size);
+ Vertex_const_iterator vi;
+ CGAL_forall_vertices(vi, N)
+ if(N.is_standard(vi))
+ return;
+ bbox = Bbox_3(bbox.xmin()*10,bbox.ymin()*10,bbox.zmin()*10,
+ bbox.xmax()*10,bbox.ymax()*10,bbox.zmax()*10);
+ }
+ public:
+ static void convert_to_OGLPolyhedron(const Nef_polyhedron& N, CGAL::OGL::Polyhedron* P) {
+ Bbox_3 bbox(bounded_bbox(N));
+ set_R(bbox,N);
+ P->bbox() = bbox;
+ Vertex_const_iterator v;
+ CGAL_forall_vertices(v,*N.sncp()) draw(v,N,*P);
+ Halfedge_const_iterator e;
+ CGAL_forall_edges(e,*N.sncp()) draw(e,N,*P);
+ Halffacet_const_iterator f;
+ CGAL_forall_facets(f,*N.sncp()) draw(f,N,*P);
+ }
+
+ }; // Nef3_Converter
+
+} // namespace OGL
+
+} //namespace CGAL
+#endif // CGAL_NEF_OPENGL_HELPER_H
diff --git a/src/cgalrenderer.cc b/src/cgalrenderer.cc
new file mode 100644
index 0000000..551c061
--- /dev/null
+++ b/src/cgalrenderer.cc
@@ -0,0 +1,126 @@
+/*
+ * OpenSCAD (www.openscad.org)
+ * Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
+ * Marius Kintel <marius@kintel.net>
+ *
+ * This program is free software; 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * As a special exception, you have permission to link this program
+ * with the CGAL library and distribute executables, as long as you
+ * follow the requirements of the GNU GPL in regard to all of the
+ * software in the executable aside from CGAL.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "cgalrenderer.h"
+#include "polyset.h"
+#include "CGAL_renderer.h"
+#include "dxfdata.h"
+#include "dxftess.h"
+
+#include "Preferences.h"
+
+CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root)
+{
+ if (root.dim == 2) {
+ DxfData dd(root);
+ this->polyset = new PolySet();
+ this->polyset->is2d = true;
+ dxf_tesselate(this->polyset, &dd, 0, true, false, 0);
+ }
+ else if (root.dim == 3) {
+ this->polyhedron = new Polyhedron();
+ // FIXME: Make independent of Preferences
+ this->polyhedron->setColor(Polyhedron::CGAL_NEF3_MARKED_FACET_COLOR,
+ Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).red(),
+ Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).green(),
+ Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).blue());
+ this->polyhedron->setColor(Polyhedron::CGAL_NEF3_UNMARKED_FACET_COLOR,
+ Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).red(),
+ Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).green(),
+ Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).blue());
+
+ CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron3>::convert_to_OGLPolyhedron(this->root.p3, this->polyhedron);
+ this->polyhedron->init();
+ }
+}
+
+CGALRenderer::~CGALRenderer()
+{
+ if (this->polyset) this->polyset->unlink();
+}
+
+void CGALRenderer::draw(bool showfaces, bool showedges) const
+{
+ if (this->root.dim == 2) {
+ // Draw 2D polygons
+ glDisable(GL_LIGHTING);
+ const QColor &col = Preferences::inst()->color(Preferences::CGAL_FACE_2D_COLOR);
+ glColor3f(col.redF(), col.greenF(), col.blueF());
+
+ for (int i=0; i < this->polyset->polygons.size(); i++) {
+ glBegin(GL_POLYGON);
+ for (int j=0; j < this->polyset->polygons[i].size(); j++) {
+ PolySet::Point p = this->polyset->polygons[i][j];
+ glVertex3d(p.x, p.y, -0.1);
+ }
+ glEnd();
+ }
+
+ typedef CGAL_Nef_polyhedron2::Explorer Explorer;
+ typedef Explorer::Face_const_iterator fci_t;
+ typedef Explorer::Halfedge_around_face_const_circulator heafcc_t;
+ typedef Explorer::Point Point;
+ Explorer E = this->root.p2.explorer();
+
+ // Draw 2D edges
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glLineWidth(2);
+ const QColor &col2 = Preferences::inst()->color(Preferences::CGAL_EDGE_2D_COLOR);
+ glColor3f(col2.redF(), col2.greenF(), col2.blueF());
+
+ // Extract the boundary, including inner boundaries of the polygons
+ for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit) {
+ bool fset = false;
+ double fx = 0.0, fy = 0.0;
+ heafcc_t fcirc(E.halfedge(fit)), fend(fcirc);
+ CGAL_For_all(fcirc, fend) {
+ if(E.is_standard(E.target(fcirc))) {
+ Point p = E.point(E.target(fcirc));
+ double x = to_double(p.x()), y = to_double(p.y());
+ if (!fset) {
+ glBegin(GL_LINE_STRIP);
+ fx = x, fy = y;
+ fset = true;
+ }
+ glVertex3d(x, y, -0.1);
+ }
+ }
+ if (fset) {
+ glVertex3d(fx, fy, -0.1);
+ glEnd();
+ }
+ }
+
+ glEnable(GL_DEPTH_TEST);
+ }
+ else if (this->root.dim == 3) {
+ if (showfaces) this->polyhedron->set_style(SNC_BOUNDARY);
+ else this->polyhedron->set_style(SNC_SKELETON);
+
+ this->polyhedron->draw(showfaces && showedges);
+ }
+}
diff --git a/src/cgalrenderer.h b/src/cgalrenderer.h
new file mode 100644
index 0000000..b3c1638
--- /dev/null
+++ b/src/cgalrenderer.h
@@ -0,0 +1,20 @@
+#ifndef CGALRENDERER_H_
+#define CGALRENDERER_H_
+
+#include "renderer.h"
+#include "cgal.h"
+
+class CGALRenderer : public Renderer
+{
+public:
+ CGALRenderer(const CGAL_Nef_polyhedron &root);
+ ~CGALRenderer();
+ void draw(bool showfaces, bool showedges) const;
+
+private:
+ const CGAL_Nef_polyhedron &root;
+ class Polyhedron *polyhedron;
+ class PolySet *polyset;
+};
+
+#endif
diff --git a/src/glview.cc b/src/glview.cc
index ef023f2..9d82443 100644
--- a/src/glview.cc
+++ b/src/glview.cc
@@ -26,6 +26,7 @@
#include "GLView.h"
#include "Preferences.h"
+#include "renderer.h"
#include <QApplication>
#include <QWheelEvent>
@@ -41,9 +42,13 @@
#include "mathc99.h"
#include <stdio.h>
+#ifdef ENABLE_OPENCSG
+# include <opencsg.h>
+#endif
+
#define FAR_FAR_AWAY 100000.0
-GLView::GLView(QWidget *parent) : QGLWidget(parent)
+GLView::GLView(QWidget *parent) : QGLWidget(parent), renderer(NULL)
{
viewer_distance = 500;
object_rot_x = 35;
@@ -54,15 +59,12 @@ GLView::GLView(QWidget *parent) : QGLWidget(parent)
object_trans_z = 0;
mouse_drag_active = false;
- last_mouse_x = 0;
- last_mouse_y = 0;
orthomode = false;
showaxes = false;
showcrosshairs = false;
-
- renderfunc = NULL;
- renderfunc_vp = NULL;
+ showedges = false;
+ showfaces = true;
for (int i = 0; i < 10; i++)
shaderinfo[i] = 0;
@@ -77,10 +79,10 @@ GLView::GLView(QWidget *parent) : QGLWidget(parent)
#endif
}
-void GLView::setRenderFunc(void (*func)(void*), void *userdata)
+void GLView::setRenderer(Renderer *r)
{
- this->renderfunc = func;
- this->renderfunc_vp = userdata;
+ this->renderer = r;
+ updateGL();
}
void GLView::initializeGL()
@@ -91,6 +93,22 @@ void GLView::initializeGL()
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
+ GLfloat light_position0[] = {-1.0, -1.0, +1.0, 0.0};
+ GLfloat light_position1[] = {+1.0, +1.0, -1.0, 0.0};
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
+ glEnable(GL_LIGHT0);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
+ glEnable(GL_LIGHT1);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_NORMALIZE);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+
#ifdef ENABLE_OPENCSG
GLenum err = glewInit();
if (GLEW_OK != err) {
@@ -256,43 +274,47 @@ void GLView::resizeGL(int w, int h)
#endif
glViewport(0, 0, w, h);
w_h_ratio = sqrt((double)w / (double)h);
+
+ setupPerspective();
}
-void GLView::paintGL()
+void GLView::setupPerspective()
{
- const QColor &bgcol = Preferences::inst()->color(Preferences::BACKGROUND_COLOR);
- glClearColor(bgcol.redF(), bgcol.greenF(), bgcol.blueF(), 0.0);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-w_h_ratio, +w_h_ratio, -(1/w_h_ratio), +(1/w_h_ratio), +10.0, +FAR_FAR_AWAY);
+}
+void GLView::setupOrtho(double distance, bool offset)
+{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
+ if(offset)
+ glTranslated(-0.8, -0.8, 0);
+ double l = distance/10;
+ glOrtho(-w_h_ratio*l, +w_h_ratio*l,
+ -(1/w_h_ratio)*l, +(1/w_h_ratio)*l,
+ -FAR_FAR_AWAY, +FAR_FAR_AWAY);
+}
+
+void GLView::paintGL()
+{
+ glEnable(GL_LIGHTING);
+
if (orthomode)
- glOrtho(-w_h_ratio*viewer_distance/10, +w_h_ratio*viewer_distance/10,
- -(1/w_h_ratio)*viewer_distance/10, +(1/w_h_ratio)*viewer_distance/10,
- -FAR_FAR_AWAY, +FAR_FAR_AWAY);
- else
- glFrustum(-w_h_ratio, +w_h_ratio, -(1/w_h_ratio), +(1/w_h_ratio), +10.0, +FAR_FAR_AWAY);
- gluLookAt(0.0, -viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
+ setupOrtho(viewer_distance);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
- GLfloat light_position0[] = {-1.0, -1.0, +1.0, 0.0};
- GLfloat light_position1[] = {+1.0, +1.0, -1.0, 0.0};
+ const QColor &bgcol = Preferences::inst()->color(Preferences::BACKGROUND_COLOR);
+ glClearColor(bgcol.redF(), bgcol.greenF(), bgcol.blueF(), 0.0);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
- glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
- glEnable(GL_LIGHT0);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
- glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
- glEnable(GL_LIGHT1);
- glEnable(GL_LIGHTING);
- glEnable(GL_NORMALIZE);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
+ gluLookAt(0.0, -viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
+
+ glTranslated(object_trans_x, object_trans_y, object_trans_z);
glRotated(object_rot_x, 1.0, 0.0, 0.0);
glRotated(object_rot_y, 0.0, 1.0, 0.0);
@@ -315,8 +337,6 @@ void GLView::paintGL()
glEnd();
}
- glTranslated(object_trans_x, object_trans_y, object_trans_z);
-
// Large gray axis cross inline with the model
// FIXME: This is always gray - adjust color to keep contrast with background
if (showaxes)
@@ -324,12 +344,13 @@ void GLView::paintGL()
glLineWidth(1);
glColor3d(0.5, 0.5, 0.5);
glBegin(GL_LINES);
- glVertex3d(-viewer_distance/10, 0, 0);
- glVertex3d(+viewer_distance/10, 0, 0);
- glVertex3d(0, -viewer_distance/10, 0);
- glVertex3d(0, +viewer_distance/10, 0);
- glVertex3d(0, 0, -viewer_distance/10);
- glVertex3d(0, 0, +viewer_distance/10);
+ double l = viewer_distance/10;
+ glVertex3d(-l, 0, 0);
+ glVertex3d(+l, 0, 0);
+ glVertex3d(0, -l, 0);
+ glVertex3d(0, +l, 0);
+ glVertex3d(0, 0, -l);
+ glVertex3d(0, 0, +l);
glEnd();
}
@@ -340,20 +361,21 @@ void GLView::paintGL()
glLineWidth(2);
glColor3d(1.0, 0.0, 0.0);
- if (renderfunc)
- renderfunc(renderfunc_vp);
+ if (this->renderer) {
+#if defined(ENABLE_MDI) && defined(ENABLE_OPENCSG)
+ // FIXME: This belongs in the OpenCSG renderer, but it doesn't know about this ID yet
+ OpenCSG::setContext(this->opencsg_id);
+#endif
+ this->renderer->draw(showfaces, showedges);
+ }
// Small axis cross in the lower left corner
if (showaxes)
{
glDepthFunc(GL_ALWAYS);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glTranslated(-0.8, -0.8, 0);
- glOrtho(-w_h_ratio*1000/10, +w_h_ratio*1000/10,
- -(1/w_h_ratio)*1000/10, +(1/w_h_ratio)*1000/10,
- -FAR_FAR_AWAY, +FAR_FAR_AWAY);
+ setupOrtho(1000,true);
+
gluLookAt(0.0, -1000, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
@@ -418,6 +440,10 @@ void GLView::paintGL()
glVertex3d(zlabel_x-3, zlabel_y+3, 0); glVertex3d(zlabel_x+3, zlabel_y+3, 0);
glVertex3d(zlabel_x-3, zlabel_y-3, 0); glVertex3d(zlabel_x+3, zlabel_y+3, 0);
glEnd();
+
+ //Restore perspective for next paint
+ if(!orthomode)
+ setupPerspective();
}
if (statusLabel) {
@@ -452,101 +478,48 @@ void GLView::wheelEvent(QWheelEvent *event)
void GLView::mousePressEvent(QMouseEvent *event)
{
mouse_drag_active = true;
- last_mouse_x = event->globalX();
- last_mouse_y = event->globalY();
+ last_mouse = event->globalPos();
grabMouse();
setFocus();
}
-static void mat_id(double *trg)
-{
- for (int i = 0; i < 16; i++)
- trg[i] = i%5 == 0;
-}
-static void mat_mul(double *trg, const double *m1, const double *m2)
+void GLView::normalizeAngle(GLdouble& angle)
{
- double m[16];
- for (int x = 0; x < 4; x++)
- for (int y = 0; y < 4; y++)
- {
- m[x+y*4] = 0;
- for (int i = 0; i < 4; i++)
- m[x+y*4] += m1[i+y*4] * m2[x+i*4];
- }
- for (int i = 0; i < 16; i++)
- trg[i] = m[i];
-}
-
-static void mat_rot(double *trg, double angle, double x, double y, double z)
-{
- double s = sin(M_PI*angle/180), c = cos(M_PI*angle/180);
- double cc = 1 - c;
- double m[16] = {
- x*x*cc+c, x*y*cc-z*s, x*z*cc+y*s, 0,
- y*x*cc+z*s, y*y*cc+c, y*z*cc-x*s, 0,
- x*z*cc-y*s, y*z*cc+x*s, z*z*cc+c, 0,
- 0, 0, 0, 1
- };
- for (int i = 0; i < 16; i++)
- trg[i] = m[i];
+ while(angle < 0)
+ angle += 360;
+ while(angle > 360)
+ angle -= 360;
}
void GLView::mouseMoveEvent(QMouseEvent *event)
{
- int this_mouse_x = event->globalX();
- int this_mouse_y = event->globalY();
+ QPoint this_mouse = event->globalPos();
+ double dx = (this_mouse.x()-last_mouse.x()) * 0.7;
+ double dy = (this_mouse.y()-last_mouse.y()) * 0.7;
if (mouse_drag_active) {
if ((event->buttons() & Qt::LeftButton) != 0) {
- object_rot_x += (this_mouse_y-last_mouse_y) * 0.7;
+ object_rot_x += dy;
if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0)
- object_rot_y += (this_mouse_x-last_mouse_x) * 0.7;
+ object_rot_y += dx;
else
- object_rot_z += (this_mouse_x-last_mouse_x) * 0.7;
- while (object_rot_x < 0)
- object_rot_x += 360;
- while (object_rot_x >= 360)
- object_rot_x -= 360;
- while (object_rot_y < 0)
- object_rot_y += 360;
- while (object_rot_y >= 360)
- object_rot_y -= 360;
- while (object_rot_z < 0)
- object_rot_z += 360;
- while (object_rot_z >= 360)
- object_rot_z -= 360;
+ object_rot_z += dx;
+
+ normalizeAngle(object_rot_x);
+ normalizeAngle(object_rot_y);
+ normalizeAngle(object_rot_z);
} else {
- double mx = +(this_mouse_x-last_mouse_x) * viewer_distance/1000;
- double my = -(this_mouse_y-last_mouse_y) * viewer_distance/1000;
- double rx[16], ry[16], rz[16], tm[16];
- mat_rot(rx, -object_rot_x, 1.0, 0.0, 0.0);
- mat_rot(ry, -object_rot_y, 0.0, 1.0, 0.0);
- mat_rot(rz, -object_rot_z, 0.0, 0.0, 1.0);
- mat_id(tm);
- mat_mul(tm, rx, tm);
- mat_mul(tm, ry, tm);
- mat_mul(tm, rz, tm);
- double vec[16] = {
- 0, 0, 0, mx,
- 0, 0, 0, 0,
- 0, 0, 0, my,
- 0, 0, 0, 1
- };
if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0) {
- vec[3] = 0;
- vec[7] = my;
- vec[11] = 0;
+ viewer_distance += (GLdouble)dy;
+ } else {
+ object_trans_x += dx;
+ object_trans_z -= dy;
}
- mat_mul(tm, tm, vec);
- object_trans_x += tm[3];
- object_trans_y += tm[7];
- object_trans_z += tm[11];
}
updateGL();
emit doAnimateUpdate();
}
- last_mouse_x = this_mouse_x;
- last_mouse_y = this_mouse_y;
+ last_mouse = this_mouse;
}
void GLView::mouseReleaseEvent(QMouseEvent*)
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 0492dac..3453b1c 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -40,11 +40,12 @@
#include "dxftess.h"
#include "progress.h"
#ifdef ENABLE_OPENCSG
-#include "render-opencsg.h"
+#include "opencsgRenderer.h"
#endif
#ifdef USE_PROGRESSWIDGET
#include "ProgressWidget.h"
#endif
+#include "thrownTogetherRenderer.h"
#include <QMenu>
#include <QTime>
@@ -75,32 +76,8 @@
#ifdef ENABLE_CGAL
-#if 1
-#include "CGAL_renderer.h"
-using OpenSCAD::OGL::Polyhedron;
-using OpenSCAD::OGL::SNC_BOUNDARY;
-using OpenSCAD::OGL::SNC_SKELETON;
-using OpenSCAD::OGL::Nef3_Converter;
-#else
-// a little hackish: we need access to default-private members of
-// CGAL::OGL::Nef3_Converter so we can implement our own draw function
-// that does not scale the model. so we define 'class' to 'struct'
-// for this header..
-//
-// theoretically there could be two problems:
-// 1.) defining language keyword with the pre processor is illegal afair
-// 2.) the compiler could use a different memory layout or name mangling for structs
-//
-// both does not seam to be the case with todays compilers...
-//
-#define class struct
-#include <CGAL/Nef_3/OGL_helper.h>
-#undef class
-using CGAL::OGL::Polyhedron;
-using CGAL::OGL::SNC_BOUNDARY;
-using CGAL::OGL::SNC_SKELETON;
-using CGAL::OGL::Nef3_Converter;
-#endif
+#include "cgalrenderer.h"
+
#endif // ENABLE_CGAL
#define QUOTE(x__) # x__
@@ -175,15 +152,16 @@ MainWindow::MainWindow(const QString &filename)
root_chain = NULL;
#ifdef ENABLE_CGAL
this->root_N = NULL;
- this->recreate_cgal_ogl_p = false;
- cgal_ogl_p = NULL;
- cgal_ogl_ps = NULL;
+ this->cgalRenderer = NULL;
#endif
+#ifdef ENABLE_OPENCSG
+ this->opencsgRenderer = NULL;
+#endif
+ this->thrownTogetherRenderer = NULL;
highlights_chain = NULL;
background_chain = NULL;
root_node = NULL;
- enableOpenCSG = false;
tval = 0;
fps = 0;
@@ -327,11 +305,6 @@ MainWindow::MainWindow(const QString &filename)
connect(this->viewActionOrthogonal, SIGNAL(triggered()), this, SLOT(viewOrthogonal()));
connect(this->viewActionHide, SIGNAL(triggered()), this, SLOT(hideConsole()));
-// #ifdef ENABLE_CGAL
-// viewActionCGALSurface = menu->addAction("CGAL Surfaces", this, SLOT(viewModeCGALSurface()), QKeySequence(Qt::Key_F10));
-// viewActionCGALGrid = menu->addAction("CGAL Grid Only", this, SLOT(viewModeCGALGrid()), QKeySequence(Qt::Key_F11));
-// #endif
-
// Help menu
connect(this->helpActionAbout, SIGNAL(triggered()), this, SLOT(helpAbout()));
connect(this->helpActionHomepage, SIGNAL(triggered()), this, SLOT(helpHomepage()));
@@ -431,19 +404,14 @@ MainWindow::loadDesignSettings()
MainWindow::~MainWindow()
{
- if (root_module)
- delete root_module;
- if (root_node)
- delete root_node;
+ if (root_module) delete root_module;
+ if (root_node) delete root_node;
#ifdef ENABLE_CGAL
- if (this->root_N)
- delete this->root_N;
- if (cgal_ogl_p) {
- Polyhedron *p = (Polyhedron*)cgal_ogl_p;
- delete p;
- }
- if (cgal_ogl_ps)
- cgal_ogl_ps->unlink();
+ if (this->root_N) delete this->root_N;
+ delete this->cgalRenderer;
+#endif
+#ifdef ENABLE_OPENCSG
+ delete this->opencsgRenderer;
#endif
}
@@ -612,6 +580,16 @@ void MainWindow::compile(bool procevents)
if (procevents)
QApplication::processEvents();
+ // Invalidate renderers before we kill the CSG tree
+ screen->setRenderer(NULL);
+ if (this->opencsgRenderer) {
+ delete this->opencsgRenderer;
+ this->opencsgRenderer = NULL;
+ }
+ if (this->thrownTogetherRenderer) {
+ delete this->thrownTogetherRenderer;
+ this->thrownTogetherRenderer = NULL;
+ }
// Remove previous CSG tree
if (root_module) {
@@ -656,7 +634,6 @@ void MainWindow::compile(bool procevents)
background_chain = NULL;
}
root_node = NULL;
- enableOpenCSG = false;
// Initialize special variables
root_ctx.set_variable("$t", Value(e_tval->text().toDouble()));
@@ -822,13 +799,6 @@ void MainWindow::compileCSG(bool procevents)
root_chain = new CSGChain();
root_chain->import(root_norm_term);
- if (root_chain->polysets.size() > 1000) {
- PRINTF("WARNING: Normalized tree has %d elements!", root_chain->polysets.size());
- PRINTF("WARNING: OpenCSG rendering has been disabled.");
- } else {
- enableOpenCSG = true;
- }
-
if (highlight_terms.size() > 0)
{
PRINTF("Compiling highlights (%d CSG Trees)...", highlight_terms.size());
@@ -866,6 +836,20 @@ void MainWindow::compileCSG(bool procevents)
background_chain->import(background_terms[i]);
}
}
+
+ if (root_chain->polysets.size() > 1000) {
+ PRINTF("WARNING: Normalized tree has %d elements!", root_chain->polysets.size());
+ PRINTF("WARNING: OpenCSG rendering has been disabled.");
+ }
+ else {
+ this->opencsgRenderer = new OpenCSGRenderer(this->root_chain,
+ this->highlights_chain,
+ this->background_chain,
+ this->screen->shaderinfo);
+ }
+ this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain,
+ this->highlights_chain,
+ this->background_chain);
PRINT("CSG generation finished.");
int s = t.elapsed() / 1000;
@@ -1132,16 +1116,16 @@ void MainWindow::actionCompile()
if (this->root_node) compileCSG(!viewActionAnimate->isChecked());
// Go to non-CGAL view mode
- if (!viewActionOpenCSG->isChecked() && !viewActionThrownTogether->isChecked()) {
+ if (viewActionThrownTogether->isChecked()) {
+ viewModeThrownTogether();
+ }
+ else {
#ifdef ENABLE_OPENCSG
viewModeOpenCSG();
#else
viewModeThrownTogether();
#endif
}
- else {
- screen->updateGL();
- }
if (viewActionAnimate->isChecked() && e_dump->isChecked()) {
QImage img = screen->grabFrameBuffer();
@@ -1167,10 +1151,12 @@ void MainWindow::actionRenderCGAL()
if (!root_module || !root_node)
return;
+ this->screen->setRenderer(NULL);
+ delete this->cgalRenderer;
+ this->cgalRenderer = NULL;
if (this->root_N) {
delete this->root_N;
this->root_N = NULL;
- this->recreate_cgal_ogl_p = true;
}
PRINT("Rendering Polygon Mesh using CGAL...");
@@ -1254,10 +1240,13 @@ void MainWindow::actionRenderCGAL()
int s = t.elapsed() / 1000;
PRINTF("Total rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
- if (!viewActionCGALSurfaces->isChecked() && !viewActionCGALGrid->isChecked()) {
+ this->cgalRenderer = new CGALRenderer(*this->root_N);
+ // Go to CGAL view mode
+ if (viewActionCGALGrid->isChecked()) {
+ viewModeCGALGrid();
+ }
+ else {
viewModeCGALSurface();
- } else {
- screen->updateGL();
}
PRINT("Rendering finished.");
@@ -1461,37 +1450,6 @@ void MainWindow::viewModeActionsUncheck()
#ifdef ENABLE_OPENCSG
-static void renderGLThrownTogether(void *vp);
-
-static void renderGLviaOpenCSG(void *vp)
-{
- MainWindow *m = (MainWindow*)vp;
- if (!m->enableOpenCSG) {
- renderGLThrownTogether(vp);
- return;
- }
- static int glew_initialized = 0;
- if (!glew_initialized) {
- glew_initialized = 1;
- glewInit();
- }
-#ifdef ENABLE_MDI
- OpenCSG::setContext(m->screen->opencsg_id);
-#endif
- if (m->root_chain) {
- GLint *shaderinfo = m->screen->shaderinfo;
- if (!shaderinfo[0])
- shaderinfo = NULL;
- renderCSGChainviaOpenCSG(m->root_chain, m->viewActionShowEdges->isChecked() ? shaderinfo : NULL, false, false);
- if (m->background_chain) {
- renderCSGChainviaOpenCSG(m->background_chain, m->viewActionShowEdges->isChecked() ? shaderinfo : NULL, false, true);
- }
- if (m->highlights_chain) {
- renderCSGChainviaOpenCSG(m->highlights_chain, m->viewActionShowEdges->isChecked() ? shaderinfo : NULL, true, false);
- }
- }
-}
-
/*!
Go to the OpenCSG view mode.
Falls back to thrown together mode if OpenCSG is not available
@@ -1501,8 +1459,7 @@ void MainWindow::viewModeOpenCSG()
if (screen->hasOpenCSGSupport()) {
viewModeActionsUncheck();
viewActionOpenCSG->setChecked(true);
- screen->setRenderFunc(renderGLviaOpenCSG, this);
- screen->updateGL();
+ screen->setRenderer(this->opencsgRenderer ? (Renderer *)this->opencsgRenderer : (Renderer *)this->thrownTogetherRenderer);
} else {
viewModeThrownTogether();
}
@@ -1512,125 +1469,12 @@ void MainWindow::viewModeOpenCSG()
#ifdef ENABLE_CGAL
-static void renderGLviaCGAL(void *vp)
-{
- MainWindow *m = (MainWindow*)vp;
- if (m->recreate_cgal_ogl_p) {
- m->recreate_cgal_ogl_p = false;
- Polyhedron *p = (Polyhedron*)m->cgal_ogl_p;
- delete p;
- m->cgal_ogl_p = NULL;
- if (m->cgal_ogl_ps)
- m->cgal_ogl_ps->unlink();
- m->cgal_ogl_ps = NULL;
- }
- if (!m->root_N) return;
- if (m->root_N->dim == 2)
- {
- if (m->cgal_ogl_ps == NULL) {
- DxfData dd(*m->root_N);
- m->cgal_ogl_ps = new PolySet();
- m->cgal_ogl_ps->is2d = true;
- dxf_tesselate(m->cgal_ogl_ps, &dd, 0, true, false, 0);
- }
-
- // Draw 2D polygons
- glDisable(GL_LIGHTING);
- const QColor &col = Preferences::inst()->color(Preferences::CGAL_FACE_2D_COLOR);
- glColor3f(col.redF(), col.greenF(), col.blueF());
-
- for (int i=0; i < m->cgal_ogl_ps->polygons.size(); i++) {
- glBegin(GL_POLYGON);
- for (int j=0; j < m->cgal_ogl_ps->polygons[i].size(); j++) {
- PolySet::Point p = m->cgal_ogl_ps->polygons[i][j];
- glVertex3d(p.x, p.y, -0.1);
- }
- glEnd();
- }
-
- typedef CGAL_Nef_polyhedron2::Explorer Explorer;
- typedef Explorer::Face_const_iterator fci_t;
- typedef Explorer::Halfedge_around_face_const_circulator heafcc_t;
- typedef Explorer::Point Point;
- Explorer E = m->root_N->p2.explorer();
-
- // Draw 2D edges
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_LIGHTING);
- glLineWidth(2);
- const QColor &col2 = Preferences::inst()->color(Preferences::CGAL_EDGE_2D_COLOR);
- glColor3f(col2.redF(), col2.greenF(), col2.blueF());
-
- // Extract the boundary, including inner boundaries of the polygons
- for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit)
- {
- bool fset = false;
- double fx = 0.0, fy = 0.0;
- heafcc_t fcirc(E.halfedge(fit)), fend(fcirc);
- CGAL_For_all(fcirc, fend) {
- if(E.is_standard(E.target(fcirc))) {
- Point p = E.point(E.target(fcirc));
- double x = to_double(p.x()), y = to_double(p.y());
- if (!fset) {
- glBegin(GL_LINE_STRIP);
- fx = x, fy = y;
- fset = true;
- }
- glVertex3d(x, y, -0.1);
- }
- }
- if (fset) {
- glVertex3d(fx, fy, -0.1);
- glEnd();
- }
- }
-
- glEnable(GL_DEPTH_TEST);
- }
- else if (m->root_N->dim == 3)
- {
- Polyhedron *p = (Polyhedron*)m->cgal_ogl_p;
- if (!p) {
- Nef3_Converter<CGAL_Nef_polyhedron3>::setColor(Polyhedron::CGAL_NEF3_MARKED_FACET_COLOR,
- Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).red(),
- Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).green(),
- Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).blue());
- Nef3_Converter<CGAL_Nef_polyhedron3>::setColor(Polyhedron::CGAL_NEF3_UNMARKED_FACET_COLOR,
- Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).red(),
- Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).green(),
- Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).blue());
- m->cgal_ogl_p = p = new Polyhedron();
- Nef3_Converter<CGAL_Nef_polyhedron3>::convert_to_OGLPolyhedron(m->root_N->p3, p);
- p->init();
- }
- if (m->viewActionCGALSurfaces->isChecked())
- p->set_style(SNC_BOUNDARY);
- if (m->viewActionCGALGrid->isChecked())
- p->set_style(SNC_SKELETON);
-#if 0
- p->draw();
-#else
- if (p->style == SNC_BOUNDARY) {
- glCallList(p->object_list_+2);
- if (m->viewActionShowEdges->isChecked()) {
- glDisable(GL_LIGHTING);
- glCallList(p->object_list_+1);
- glCallList(p->object_list_);
- }
- } else {
- glDisable(GL_LIGHTING);
- glCallList(p->object_list_+1);
- glCallList(p->object_list_);
- }
-#endif
- }
-}
-
void MainWindow::viewModeCGALSurface()
{
viewModeActionsUncheck();
viewActionCGALSurfaces->setChecked(true);
- screen->setRenderFunc(renderGLviaCGAL, this);
+ screen->setShowFaces(true);
+ screen->setRenderer(this->cgalRenderer);
screen->updateGL();
}
@@ -1638,104 +1482,24 @@ void MainWindow::viewModeCGALGrid()
{
viewModeActionsUncheck();
viewActionCGALGrid->setChecked(true);
- screen->setRenderFunc(renderGLviaCGAL, this);
- screen->updateGL();
+ screen->setShowFaces(false);
+ screen->setRenderer(this->cgalRenderer);
}
#endif /* ENABLE_CGAL */
-static void renderGLThrownTogetherChain(MainWindow *m, CSGChain *chain, bool highlight, bool background, bool fberror)
-{
- glDepthFunc(GL_LEQUAL);
- QHash<QPair<PolySet*,double*>,int> polySetVisitMark;
- bool showEdges = m->viewActionShowEdges->isChecked();
- for (int i = 0; i < chain->polysets.size(); i++) {
- if (polySetVisitMark[QPair<PolySet*,double*>(chain->polysets[i], chain->matrices[i])]++ > 0)
- continue;
- double *m = chain->matrices[i];
- glPushMatrix();
- glMultMatrixd(m);
- int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
- if (highlight) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m);
- if (showEdges) {
- glDisable(GL_LIGHTING);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20));
- glEnable(GL_LIGHTING);
- }
- } else if (background) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m);
- if (showEdges) {
- glDisable(GL_LIGHTING);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10));
- glEnable(GL_LIGHTING);
- }
- } else if (fberror) {
- if (highlight) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 20), m);
- } else if (background) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 10), m);
- } else {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
- }
- } else if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0 || m[19] >= 0) {
- glColor4d(m[16], m[17], m[18], m[19]);
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
- if (showEdges) {
- glDisable(GL_LIGHTING);
- glColor4d((m[16]+1)/2, (m[17]+1)/2, (m[18]+1)/2, 1.0);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode));
- glEnable(GL_LIGHTING);
- }
- } else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m);
- if (showEdges) {
- glDisable(GL_LIGHTING);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode));
- glEnable(GL_LIGHTING);
- }
- } else {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m);
- if (showEdges) {
- glDisable(GL_LIGHTING);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode));
- glEnable(GL_LIGHTING);
- }
- }
- glPopMatrix();
- }
-}
-
-static void renderGLThrownTogether(void *vp)
-{
- MainWindow *m = (MainWindow*)vp;
- if (m->root_chain) {
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- renderGLThrownTogetherChain(m, m->root_chain, false, false, false);
- glCullFace(GL_FRONT);
- glColor3ub(255, 0, 255);
- renderGLThrownTogetherChain(m, m->root_chain, false, false, true);
- glDisable(GL_CULL_FACE);
- }
- if (m->background_chain)
- renderGLThrownTogetherChain(m, m->background_chain, false, true, false);
- if (m->highlights_chain)
- renderGLThrownTogetherChain(m, m->highlights_chain, true, false, false);
-}
-
void MainWindow::viewModeThrownTogether()
{
viewModeActionsUncheck();
viewActionThrownTogether->setChecked(true);
- screen->setRenderFunc(renderGLThrownTogether, this);
- screen->updateGL();
+ screen->setRenderer(this->thrownTogetherRenderer);
}
void MainWindow::viewModeShowEdges()
{
QSettings settings;
settings.setValue("view/showEdges",viewActionShowEdges->isChecked());
+ screen->setShowEdges(viewActionShowEdges->isChecked());
screen->updateGL();
}
diff --git a/src/render-opencsg.cc b/src/opencsgrenderer.cc
index f6d26ac..768176c 100644
--- a/src/render-opencsg.cc
+++ b/src/opencsgrenderer.cc
@@ -1,4 +1,30 @@
-#include "render-opencsg.h"
+/*
+ * OpenSCAD (www.openscad.org)
+ * Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
+ * Marius Kintel <marius@kintel.net>
+ *
+ * This program is free software; 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * As a special exception, you have permission to link this program
+ * with the CGAL library and distribute executables, as long as you
+ * follow the requirements of the GNU GPL in regard to all of the
+ * software in the executable aside from CGAL.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "opencsgrenderer.h"
#include "polyset.h"
#include "csgterm.h"
@@ -18,7 +44,35 @@ public:
}
};
-void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool highlight, bool background)
+OpenCSGRenderer::OpenCSGRenderer(CSGChain *root_chain, CSGChain *highlights_chain,
+ CSGChain *background_chain, GLint *shaderinfo)
+ : root_chain(root_chain), highlights_chain(highlights_chain),
+ background_chain(background_chain), shaderinfo(shaderinfo)
+{
+}
+
+void OpenCSGRenderer::draw(bool showfaces, bool showedges) const
+{
+ static int glew_initialized = 0;
+ if (!glew_initialized) {
+ glew_initialized = 1;
+ glewInit();
+ }
+ if (this->root_chain) {
+ GLint *shaderinfo = this->shaderinfo;
+ if (!shaderinfo[0]) shaderinfo = NULL;
+ renderCSGChain(this->root_chain, showedges ? shaderinfo : NULL, false, false);
+ if (this->background_chain) {
+ renderCSGChain(this->background_chain, showedges ? shaderinfo : NULL, false, true);
+ }
+ if (this->highlights_chain) {
+ renderCSGChain(this->highlights_chain, showedges ? shaderinfo : NULL, true, false);
+ }
+ }
+}
+
+void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
+ bool highlight, bool background) const
{
std::vector<OpenCSG::Primitive*> primitives;
int j = 0;
diff --git a/src/opencsgrenderer.h b/src/opencsgrenderer.h
new file mode 100644
index 0000000..95ffc8e
--- /dev/null
+++ b/src/opencsgrenderer.h
@@ -0,0 +1,24 @@
+#ifndef OPENCSGRENDERER_H_
+#define OPENCSGRENDERER_H_
+
+#include "renderer.h"
+#include <GL/glew.h> // this must be included before the GL headers
+#include <qgl.h>
+
+class OpenCSGRenderer : public Renderer
+{
+public:
+ OpenCSGRenderer(class CSGChain *root_chain, CSGChain *highlights_chain,
+ CSGChain *background_chain, GLint *shaderinfo);
+ void draw(bool showfaces, bool showedges) const;
+private:
+ void renderCSGChain(class CSGChain *chain, GLint *shaderinfo,
+ bool highlight, bool background) const;
+
+ CSGChain *root_chain;
+ CSGChain *highlights_chain;
+ CSGChain *background_chain;
+ GLint *shaderinfo;
+};
+
+#endif
diff --git a/src/polyset.h b/src/polyset.h
index 0914e91..8712ff2 100644
--- a/src/polyset.h
+++ b/src/polyset.h
@@ -1,10 +1,7 @@
#ifndef POLYSET_H_
#define POLYSET_H_
-#ifdef ENABLE_OPENCSG
-// this must be included before the GL headers
-# include <GL/glew.h>
-#endif
+#include <GL/glew.h> // this must be included before the GL headers
#include <qgl.h>
#include "grid.h"
diff --git a/src/render-opencsg.h b/src/render-opencsg.h
deleted file mode 100644
index 9433cbe..0000000
--- a/src/render-opencsg.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef RENDER_OPENCSG_H_
-#define RENDER_OPENCSG_H_
-
-#include <GL/glew.h>
-
-void renderCSGChainviaOpenCSG(class CSGChain *chain, GLint *shaderinfo, bool highlight, bool background);
-
-#endif
diff --git a/src/renderer.h b/src/renderer.h
new file mode 100644
index 0000000..3c25e98
--- /dev/null
+++ b/src/renderer.h
@@ -0,0 +1,11 @@
+#ifndef RENDERER_H_
+#define RENDERER_H_
+
+class Renderer
+{
+public:
+ virtual ~Renderer() {}
+ virtual void draw(bool showfaces, bool showedges) const = 0;
+};
+
+#endif // RENDERER_H
diff --git a/src/throwntogetherrenderer.cc b/src/throwntogetherrenderer.cc
new file mode 100644
index 0000000..0a0c9c8
--- /dev/null
+++ b/src/throwntogetherrenderer.cc
@@ -0,0 +1,120 @@
+/*
+ * OpenSCAD (www.openscad.org)
+ * Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
+ * Marius Kintel <marius@kintel.net>
+ *
+ * This program is free software; 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * As a special exception, you have permission to link this program
+ * with the CGAL library and distribute executables, as long as you
+ * follow the requirements of the GNU GPL in regard to all of the
+ * software in the executable aside from CGAL.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "ThrownTogetherRenderer.h"
+#include "polyset.h"
+#include "csgterm.h"
+
+#include <GL/glew.h> // this must be included before the GL headers
+#include <qgl.h>
+
+ThrownTogetherRenderer::ThrownTogetherRenderer(CSGChain *root_chain,
+ CSGChain *highlights_chain,
+ CSGChain *background_chain)
+ : root_chain(root_chain), highlights_chain(highlights_chain),
+ background_chain(background_chain)
+{
+}
+
+void ThrownTogetherRenderer::draw(bool showfaces, bool showedges) const
+{
+ if (this->root_chain) {
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ renderCSGChain(this->root_chain, false, false, showedges, false);
+ glCullFace(GL_FRONT);
+ glColor3ub(255, 0, 255);
+ renderCSGChain(this->root_chain, false, false, showedges, true);
+ glDisable(GL_CULL_FACE);
+ }
+ if (this->background_chain)
+ renderCSGChain(this->background_chain, false, true, showedges, false);
+ if (this->highlights_chain)
+ renderCSGChain(this->highlights_chain, true, false, showedges, false);
+}
+
+void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,
+ bool background, bool showedges,
+ bool fberror) const
+{
+ glDepthFunc(GL_LEQUAL);
+ QHash<QPair<PolySet*,double*>,int> polySetVisitMark;
+ for (int i = 0; i < chain->polysets.size(); i++) {
+ if (polySetVisitMark[QPair<PolySet*,double*>(chain->polysets[i], chain->matrices[i])]++ > 0)
+ continue;
+ double *m = chain->matrices[i];
+ glPushMatrix();
+ glMultMatrixd(m);
+ int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
+ if (highlight) {
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m);
+ if (showedges) {
+ glDisable(GL_LIGHTING);
+ chain->polysets[i]->render_edges(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20));
+ glEnable(GL_LIGHTING);
+ }
+ } else if (background) {
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m);
+ if (showedges) {
+ glDisable(GL_LIGHTING);
+ chain->polysets[i]->render_edges(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10));
+ glEnable(GL_LIGHTING);
+ }
+ } else if (fberror) {
+ if (highlight) {
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 20), m);
+ } else if (background) {
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 10), m);
+ } else {
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
+ }
+ } else if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0 || m[19] >= 0) {
+ glColor4d(m[16], m[17], m[18], m[19]);
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
+ if (showedges) {
+ glDisable(GL_LIGHTING);
+ glColor4d((m[16]+1)/2, (m[17]+1)/2, (m[18]+1)/2, 1.0);
+ chain->polysets[i]->render_edges(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode));
+ glEnable(GL_LIGHTING);
+ }
+ } else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) {
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m);
+ if (showedges) {
+ glDisable(GL_LIGHTING);
+ chain->polysets[i]->render_edges(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode));
+ glEnable(GL_LIGHTING);
+ }
+ } else {
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m);
+ if (showedges) {
+ glDisable(GL_LIGHTING);
+ chain->polysets[i]->render_edges(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode));
+ glEnable(GL_LIGHTING);
+ }
+ }
+ glPopMatrix();
+ }
+}
diff --git a/src/throwntogetherrenderer.h b/src/throwntogetherrenderer.h
new file mode 100644
index 0000000..09d13f3
--- /dev/null
+++ b/src/throwntogetherrenderer.h
@@ -0,0 +1,21 @@
+#ifndef THROWNTOGETHERRENDERER_H_
+#define THROWNTOGETHERRENDERER_H_
+
+#include "renderer.h"
+
+class ThrownTogetherRenderer : public Renderer
+{
+public:
+ ThrownTogetherRenderer(class CSGChain *root_chain,
+ CSGChain *highlights_chain, CSGChain *background_chain);
+ void draw(bool showfaces, bool showedges) const;
+private:
+ void renderCSGChain(CSGChain *chain, bool highlight, bool background, bool showedges,
+ bool fberror) const;
+
+ CSGChain *root_chain;
+ CSGChain *highlights_chain;
+ CSGChain *background_chain;
+};
+
+#endif
contact: Jan Huwald // Impressum