summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c>2010-01-15 01:00:41 (GMT)
committerkintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c>2010-01-15 01:00:41 (GMT)
commitf2bad69cf51c6e5b278bf38a2bd7eca2163aff9b (patch)
treedb30b829f246fd8e0e1b9a261c43d2eb531a7ccb
parent812e8064aa99abd168e45a7b14ec533bb30823b6 (diff)
Started collecting GL colors in one place; added Preferences class which will become a preferences dialog, forked CGAL OGL_Helper to make colors configurable
git-svn-id: http://svn.clifford.at/openscad/trunk@301 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r--CGAL_renderer.h660
-rw-r--r--MainWindow.ui10
-rw-r--r--Preferences.h39
-rw-r--r--Preferences.ui199
-rw-r--r--mainwin.cc132
-rw-r--r--openscad.pro13
-rw-r--r--polyset.cc9
7 files changed, 1003 insertions, 59 deletions
diff --git a/CGAL_renderer.h b/CGAL_renderer.h
new file mode 100644
index 0000000..3c36db4
--- /dev/null
+++ b/CGAL_renderer.h
@@ -0,0 +1,660 @@
+// 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);
+ }
+
+ inline void CGAL_GLU_TESS_CALLBACK combineCallback(GLdouble coords[3], GLvoid *d[4], GLfloat w[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
diff --git a/MainWindow.ui b/MainWindow.ui
index a85859a..afdb61c 100644
--- a/MainWindow.ui
+++ b/MainWindow.ui
@@ -142,6 +142,7 @@
<addaction name="separator"/>
<addaction name="editActionZoomIn"/>
<addaction name="editActionZoomOut"/>
+ <addaction name="editActionPreferences"/>
</widget>
<widget class="QMenu" name="menu_Design">
<property name="title">
@@ -605,6 +606,11 @@
<string>Ctrl+W</string>
</property>
</action>
+ <action name="editActionPreferences">
+ <property name="text">
+ <string>Preferences</string>
+ </property>
+ </action>
<action name="designActionFlushCaches">
<property name="text">
<string>Flush Caches</string>
@@ -619,7 +625,9 @@
<container>1</container>
</customwidget>
</customwidgets>
- <resources/>
+ <resources>
+ <include location="openscad.qrc"/>
+ </resources>
<connections>
<connection>
<sender>fileActionQuit</sender>
diff --git a/Preferences.h b/Preferences.h
new file mode 100644
index 0000000..88cd590
--- /dev/null
+++ b/Preferences.h
@@ -0,0 +1,39 @@
+#ifndef PREFERENCES_H_
+#define PREFERENCES_H_
+
+#include <QMainWindow>
+#include "ui_Preferences.h"
+
+class Preferences : public QMainWindow, public Ui::Preferences
+{
+ Q_OBJECT;
+
+public:
+ ~Preferences();
+ static Preferences *inst() { if (!instance) instance = new Preferences(); return instance; }
+
+ enum RenderColor {
+ BACKGROUND_COLOR,
+ OPENCSG_FACE_FRONT_COLOR,
+ OPENCSG_FACE_BACK_COLOR,
+ CGAL_FACE_FRONT_COLOR,
+ CGAL_FACE_2D_COLOR,
+ CGAL_FACE_BACK_COLOR,
+ CGAL_EDGE_FRONT_COLOR,
+ CGAL_EDGE_BACK_COLOR,
+ CGAL_EDGE_2D_COLOR
+ };
+ void setColor(RenderColor idx, const QColor &color) { this->colormap[idx] = color; }
+ const QColor &color(RenderColor idx) { return this->colormap[idx]; }
+
+public slots:
+ void actionTriggered(class QAction *);
+
+private:
+ Preferences(QWidget *parent = NULL);
+ QMap<RenderColor, QColor> colormap;
+
+ static Preferences *instance;
+};
+
+#endif
diff --git a/Preferences.ui b/Preferences.ui
new file mode 100644
index 0000000..3a2f127
--- /dev/null
+++ b/Preferences.ui
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Preferences</class>
+ <widget class="QMainWindow" name="Preferences">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>435</width>
+ <height>362</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Preferences</string>
+ </property>
+ <property name="unifiedTitleAndToolBarOnMac">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="page3DView">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Background color:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>241</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="pageAdvanced">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>120</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>advanced</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>120</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QToolBar" name="toolBar">
+ <property name="windowTitle">
+ <string>toolBar</string>
+ </property>
+ <property name="movable">
+ <bool>false</bool>
+ </property>
+ <property name="allowedAreas">
+ <set>Qt::TopToolBarArea</set>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextUnderIcon</enum>
+ </property>
+ <property name="floatable">
+ <bool>false</bool>
+ </property>
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ <addaction name="prefsAction3DView"/>
+ <addaction name="prefsActionAdvanced"/>
+ </widget>
+ <action name="prefsAction3DView">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="icon">
+ <iconset resource="openscad.qrc">
+ <normaloff>:/prefs3DView.png</normaloff>
+ <normalon>:/openscad.ico</normalon>:/prefs3DView.png</iconset>
+ </property>
+ <property name="text">
+ <string>3D View</string>
+ </property>
+ </action>
+ <action name="prefsActionAdvanced">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="icon">
+ <iconset resource="openscad.qrc">
+ <normaloff>:/prefsAdvanced.png</normaloff>:/prefsAdvanced.png</iconset>
+ </property>
+ <property name="text">
+ <string>Advanced</string>
+ </property>
+ </action>
+ </widget>
+ <resources>
+ <include location="openscad.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/mainwin.cc b/mainwin.cc
index 62f42b5..ef47008 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -22,6 +22,7 @@
#include "openscad.h"
#include "MainWindow.h"
+#include "Preferences.h"
#include "printutils.h"
#include <QMenu>
@@ -50,6 +51,13 @@
#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'
@@ -64,8 +72,12 @@
#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
+#endif // ENABLE_CGAL
#define QUOTE(x__) # x__
#define QUOTED(x__) QUOTE(x__)
@@ -88,7 +100,6 @@ MainWindow::MainWindow(const char *filename)
{
setupUi(this);
-
root_ctx.functions_p = &builtin_functions;
root_ctx.modules_p = &builtin_modules;
root_ctx.set_variable("$fn", Value(0.0));
@@ -110,8 +121,8 @@ MainWindow::MainWindow(const char *filename)
root_norm_term = NULL;
root_chain = NULL;
#ifdef ENABLE_CGAL
- root_N = NULL;
- recreate_cgal_ogl_p = false;
+ this->root_N = NULL;
+ this->recreate_cgal_ogl_p = false;
cgal_ogl_p = NULL;
cgal_ogl_ps = NULL;
#endif
@@ -180,6 +191,7 @@ MainWindow::MainWindow(const char *filename)
connect(this->editActionZoomIn, SIGNAL(triggered()), editor, SLOT(zoomIn()));
connect(this->editActionZoomOut, SIGNAL(triggered()), editor, SLOT(zoomOut()));
connect(this->editActionHide, SIGNAL(triggered()), this, SLOT(hideEditor()));
+ connect(this->editActionPreferences, SIGNAL(triggered()), this, SLOT(preferences()));
// Design menu
connect(this->designActionReloadAndCompile, SIGNAL(triggered()), this, SLOT(actionReloadCompile()));
@@ -288,10 +300,10 @@ MainWindow::~MainWindow()
if (root_node)
delete root_node;
#ifdef ENABLE_CGAL
- if (root_N)
- delete root_N;
+ if (this->root_N)
+ delete this->root_N;
if (cgal_ogl_p) {
- CGAL::OGL::Polyhedron *p = (CGAL::OGL::Polyhedron*)cgal_ogl_p;
+ Polyhedron *p = (Polyhedron*)cgal_ogl_p;
delete p;
}
if (cgal_ogl_ps)
@@ -916,10 +928,10 @@ void MainWindow::actionRenderCGAL()
if (!root_module || !root_node)
return;
- if (root_N) {
- delete root_N;
- root_N = NULL;
- recreate_cgal_ogl_p = true;
+ if (this->root_N) {
+ delete this->root_N;
+ this->root_N = NULL;
+ this->recreate_cgal_ogl_p = true;
}
PRINT("Rendering Polygon Mesh using CGAL...");
@@ -935,51 +947,51 @@ void MainWindow::actionRenderCGAL()
QApplication::processEvents();
progress_report_prep(root_node, report_func, pd);
- root_N = new CGAL_Nef_polyhedron(root_node->render_cgal_nef_polyhedron());
+ this->root_N = new CGAL_Nef_polyhedron(root_node->render_cgal_nef_polyhedron());
progress_report_fin();
PRINTF("Number of vertices currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.totalCost());
PRINTF("Number of objects currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.size());
QApplication::processEvents();
- if (root_N->dim == 2) {
+ if (this->root_N->dim == 2) {
PRINTF(" Top level object is a 2D object:");
QApplication::processEvents();
- PRINTF(" Empty: %6s", root_N->p2.is_empty() ? "yes" : "no");
+ PRINTF(" Empty: %6s", this->root_N->p2.is_empty() ? "yes" : "no");
QApplication::processEvents();
- PRINTF(" Plane: %6s", root_N->p2.is_plane() ? "yes" : "no");
+ PRINTF(" Plane: %6s", this->root_N->p2.is_plane() ? "yes" : "no");
QApplication::processEvents();
- PRINTF(" Vertices: %6d", (int)root_N->p2.explorer().number_of_vertices());
+ PRINTF(" Vertices: %6d", (int)this->root_N->p2.explorer().number_of_vertices());
QApplication::processEvents();
- PRINTF(" Halfedges: %6d", (int)root_N->p2.explorer().number_of_halfedges());
+ PRINTF(" Halfedges: %6d", (int)this->root_N->p2.explorer().number_of_halfedges());
QApplication::processEvents();
- PRINTF(" Edges: %6d", (int)root_N->p2.explorer().number_of_edges());
+ PRINTF(" Edges: %6d", (int)this->root_N->p2.explorer().number_of_edges());
QApplication::processEvents();
- PRINTF(" Faces: %6d", (int)root_N->p2.explorer().number_of_faces());
+ PRINTF(" Faces: %6d", (int)this->root_N->p2.explorer().number_of_faces());
QApplication::processEvents();
- PRINTF(" FaceCycles: %6d", (int)root_N->p2.explorer().number_of_face_cycles());
+ PRINTF(" FaceCycles: %6d", (int)this->root_N->p2.explorer().number_of_face_cycles());
QApplication::processEvents();
- PRINTF(" ConnComp: %6d", (int)root_N->p2.explorer().number_of_connected_components());
+ PRINTF(" ConnComp: %6d", (int)this->root_N->p2.explorer().number_of_connected_components());
QApplication::processEvents();
}
- if (root_N->dim == 3) {
+ if (this->root_N->dim == 3) {
PRINTF(" Top level object is a 3D object:");
- PRINTF(" Simple: %6s", root_N->p3.is_simple() ? "yes" : "no");
+ PRINTF(" Simple: %6s", this->root_N->p3.is_simple() ? "yes" : "no");
QApplication::processEvents();
- PRINTF(" Valid: %6s", root_N->p3.is_valid() ? "yes" : "no");
+ PRINTF(" Valid: %6s", this->root_N->p3.is_valid() ? "yes" : "no");
QApplication::processEvents();
- PRINTF(" Vertices: %6d", (int)root_N->p3.number_of_vertices());
+ PRINTF(" Vertices: %6d", (int)this->root_N->p3.number_of_vertices());
QApplication::processEvents();
- PRINTF(" Halfedges: %6d", (int)root_N->p3.number_of_halfedges());
+ PRINTF(" Halfedges: %6d", (int)this->root_N->p3.number_of_halfedges());
QApplication::processEvents();
- PRINTF(" Edges: %6d", (int)root_N->p3.number_of_edges());
+ PRINTF(" Edges: %6d", (int)this->root_N->p3.number_of_edges());
QApplication::processEvents();
- PRINTF(" Halffacets: %6d", (int)root_N->p3.number_of_halffacets());
+ PRINTF(" Halffacets: %6d", (int)this->root_N->p3.number_of_halffacets());
QApplication::processEvents();
- PRINTF(" Facets: %6d", (int)root_N->p3.number_of_facets());
+ PRINTF(" Facets: %6d", (int)this->root_N->p3.number_of_facets());
QApplication::processEvents();
- PRINTF(" Volumes: %6d", (int)root_N->p3.number_of_volumes());
+ PRINTF(" Volumes: %6d", (int)this->root_N->p3.number_of_volumes());
QApplication::processEvents();
}
@@ -996,7 +1008,6 @@ void MainWindow::actionRenderCGAL()
delete pd;
current_win = NULL;
-
}
#endif /* ENABLE_CGAL */
@@ -1054,19 +1065,19 @@ void MainWindow::actionExportSTLorOFF(bool)
#ifdef ENABLE_CGAL
current_win = this;
- if (!root_N) {
+ if (!this->root_N) {
PRINT("Nothing to export! Try building first (press F6).");
current_win = NULL;
return;
}
- if (root_N->dim != 3) {
+ if (this->root_N->dim != 3) {
PRINT("Current top level object is not a 3D object.");
current_win = NULL;
return;
}
- if (!root_N->p3.is_simple()) {
+ if (!this->root_N->p3.is_simple()) {
PRINT("Object isn't a valid 2-manifold! Modify your design..");
current_win = NULL;
return;
@@ -1083,16 +1094,16 @@ void MainWindow::actionExportSTLorOFF(bool)
QProgressDialog *pd = new QProgressDialog(
stl_mode ? "Exporting object to STL file..." : "Exporting object to OFF file...",
- QString(), 0, root_N->p3.number_of_facets() + 1);
+ QString(), 0, this->root_N->p3.number_of_facets() + 1);
pd->setValue(0);
pd->setAutoClose(false);
pd->show();
QApplication::processEvents();
if (stl_mode)
- export_stl(root_N, stl_filename, pd);
+ export_stl(this->root_N, stl_filename, pd);
else
- export_off(root_N, stl_filename, pd);
+ export_off(this->root_N, stl_filename, pd);
PRINTF("%s export finished.", stl_mode ? "STL" : "OFF");
@@ -1117,13 +1128,13 @@ void MainWindow::actionExportDXF()
#ifdef ENABLE_CGAL
current_win = this;
- if (!root_N) {
+ if (!this->root_N) {
PRINT("Nothing to export! Try building first (press F6).");
current_win = NULL;
return;
}
- if (root_N->dim != 2) {
+ if (this->root_N->dim != 2) {
PRINT("Current top level object is not a 2D object.");
current_win = NULL;
return;
@@ -1137,7 +1148,7 @@ void MainWindow::actionExportDXF()
return;
}
- export_dxf(root_N, stl_filename, NULL);
+ export_dxf(this->root_N, stl_filename, NULL);
PRINTF("DXF export finished.");
current_win = NULL;
@@ -1206,6 +1217,7 @@ static void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool hi
} else if (background) {
chain->polysets[j]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m, shaderinfo);
} else if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0 || m[19] >= 0) {
+ // User-defined color from source
glColor4d(m[16], m[17], m[18], m[19]);
if (shaderinfo) {
glUniform4f(shaderinfo[1], m[16], m[17], m[18], m[19]);
@@ -1301,14 +1313,15 @@ static void renderGLviaCGAL(void *vp)
MainWindow *m = (MainWindow*)vp;
if (m->recreate_cgal_ogl_p) {
m->recreate_cgal_ogl_p = false;
- CGAL::OGL::Polyhedron *p = (CGAL::OGL::Polyhedron*)m->cgal_ogl_p;
+ 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 && m->root_N->dim == 2)
+ if (!m->root_N) return;
+ if (m->root_N->dim == 2)
{
if (m->cgal_ogl_ps == NULL) {
DxfData dd(*m->root_N);
@@ -1317,8 +1330,10 @@ static void renderGLviaCGAL(void *vp)
dxf_tesselate(m->cgal_ogl_ps, &dd, 0, true, false, 0);
}
+ // Draw 2D polygons
glDisable(GL_LIGHTING);
- glColor3d(0.0, 0.75, 0.6);
+ 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);
@@ -1335,10 +1350,12 @@ static void renderGLviaCGAL(void *vp)
typedef Explorer::Point Point;
Explorer E = m->root_N->p2.explorer();
+ // Draw 2D edges
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glLineWidth(2);
- glColor3d(0.0, 0.0, 0.0);
+ 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(), fend = E.faces_end(); fit != fend; ++fit)
@@ -1366,22 +1383,30 @@ static void renderGLviaCGAL(void *vp)
glEnable(GL_DEPTH_TEST);
}
- if (m->root_N && m->root_N->dim == 3)
+ else if (m->root_N->dim == 3)
{
- CGAL::OGL::Polyhedron *p = (CGAL::OGL::Polyhedron*)m->cgal_ogl_p;
+ Polyhedron *p = (Polyhedron*)m->cgal_ogl_p;
if (!p) {
- m->cgal_ogl_p = p = new CGAL::OGL::Polyhedron();
- CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron3>::convert_to_OGLPolyhedron(m->root_N->p3, 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(CGAL::OGL::SNC_BOUNDARY);
+ p->set_style(SNC_BOUNDARY);
if (m->viewActionCGALGrid->isChecked())
- p->set_style(CGAL::OGL::SNC_SKELETON);
+ p->set_style(SNC_SKELETON);
#if 0
p->draw();
#else
- if (p->style == CGAL::OGL::SNC_BOUNDARY) {
+ if (p->style == SNC_BOUNDARY) {
glCallList(p->object_list_+2);
if (m->viewActionShowEdges->isChecked()) {
glDisable(GL_LIGHTING);
@@ -1709,3 +1734,8 @@ void MainWindow::closeEvent(QCloseEvent *event)
}
}
+void
+MainWindow::preferences()
+{
+ Preferences::inst()->show();
+}
diff --git a/openscad.pro b/openscad.pro
index 0216876..7e7ca16 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -1,6 +1,7 @@
isEmpty(VERSION) VERSION = $$system(date "+%Y.%m.%d")
DEFINES += OPENSCAD_VERSION=$$VERSION
TEMPLATE = app
+RESOURCES = openscad.qrc
macx {
TARGET = OpenSCAD
@@ -18,7 +19,7 @@ QT += opengl
# Application configuration
CONFIG += debug
# CONFIG += release
-# CONFIG += mdi
+CONFIG += mdi
CONFIG += cgal
CONFIG += opencsg
@@ -74,12 +75,15 @@ QMAKE_CXXFLAGS_DEBUG = -O0 -ggdb
LEXSOURCES += lexer.l
YACCSOURCES += parser.y
-FORMS += MainWindow.ui
+FORMS += MainWindow.ui \
+ Preferences.ui
HEADERS += openscad.h \
MainWindow.h \
+ Preferences.h \
GLView.h \
- printutils.h
+ printutils.h \
+ CGAL_renderer.h
macx: HEADERS += EventFilter.h
@@ -90,7 +94,8 @@ SOURCES += openscad.cc mainwin.cc glview.cc export.cc \
import.cc dxfdata.cc dxftess.cc dxftess-glu.cc \
dxftess-cgal.cc dxfdim.cc \
dxflinextrude.cc dxfrotextrude.cc highlighter.cc \
- printutils.cc nef2dxf.cc
+ printutils.cc nef2dxf.cc \
+ Preferences.cc
target.path = /usr/local/bin/
INSTALLS += target
diff --git a/polyset.cc b/polyset.cc
index 5bccd6a..ecaea4d 100644
--- a/polyset.cc
+++ b/polyset.cc
@@ -22,6 +22,7 @@
#include "openscad.h"
#include "printutils.h"
+#include "Preferences.h"
QCache<QString,PolySet::ps_cache_entry> PolySet::ps_cache(100);
@@ -133,16 +134,18 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m
bool mirrored = m_scale_rotate_det < 0;
if (colormode == COLORMODE_MATERIAL) {
- glColor3ub(249, 215, 44);
+ const QColor &col = Preferences::inst()->color(Preferences::OPENCSG_FACE_FRONT_COLOR);
+ glColor3f(col.redF(), col.greenF(), col.blueF());
#ifdef ENABLE_OPENCSG
if (shaderinfo) {
- glUniform4f(shaderinfo[1], 249 / 255.0, 215 / 255.0, 44 / 255.0, 1.0);
+ glUniform4f(shaderinfo[1], col.redF(), col.greenF(), col.blueF(), 1.0f);
glUniform4f(shaderinfo[2], 255 / 255.0, 236 / 255.0, 94 / 255.0, 1.0);
}
#endif /* ENABLE_OPENCSG */
}
if (colormode == COLORMODE_CUTOUT) {
- glColor3ub(157, 203, 81);
+ const QColor &col = Preferences::inst()->color(Preferences::OPENCSG_FACE_BACK_COLOR);
+ glColor3f(col.redF(), col.greenF(), col.blueF());
#ifdef ENABLE_OPENCSG
if (shaderinfo) {
glUniform4f(shaderinfo[1], 157 / 255.0, 203 / 255.0, 81 / 255.0, 1.0);
contact: Jan Huwald // Impressum