2009-06-20 16:10:55 +04:00
/*
* OpenSCAD ( www . openscad . at )
* Copyright ( C ) 2009 Clifford Wolf < clifford @ clifford . at >
*
* 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 .
*
* 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 OPENSCAD_H
# define OPENSCAD_H
2009-06-25 12:12:41 +04:00
# ifdef ENABLE_OPENCSG
// this must be included before the GL headers
# include <GL / glew.h>
# endif
2009-06-20 23:00:19 +04:00
# include <QHash>
2009-07-03 11:51:22 +04:00
# include <QCache>
2009-06-20 23:00:19 +04:00
# include <QVector>
2009-06-23 23:56:46 +04:00
# include <QMainWindow>
2009-10-18 12:50:01 +04:00
# include <QProgressDialog>
2009-11-01 21:26:38 +03:00
# include <QSyntaxHighlighter>
2009-06-23 23:56:46 +04:00
# include <QSplitter>
# include <QTextEdit>
2009-07-28 19:15:29 +04:00
# include <QLineEdit>
2009-06-23 23:56:46 +04:00
# include <QGLWidget>
2009-06-27 14:04:57 +04:00
# include <QPointer>
2009-10-14 13:44:41 +04:00
# include <QLabel>
2009-07-28 19:15:29 +04:00
# include <QTimer>
2009-06-23 23:56:46 +04:00
2009-06-21 10:53:46 +04:00
# include <stdio.h>
2009-06-23 23:56:46 +04:00
# include <errno.h>
2009-06-21 10:53:46 +04:00
# include <stdlib.h>
2009-06-23 23:56:46 +04:00
# include <string.h>
2009-09-24 12:32:41 +04:00
# include <assert.h>
2009-06-21 10:53:46 +04:00
# include <math.h>
2009-06-20 23:00:19 +04:00
2009-06-21 20:41:38 +04:00
# include <fstream>
# include <iostream>
2009-07-26 20:31:19 +04:00
// for win32 and maybe others..
# ifndef M_PI
# define M_PI 3.14159265358979323846
# endif
2009-06-20 23:00:19 +04:00
class Value ;
class Expression ;
class AbstractFunction ;
class BuiltinFunction ;
class Function ;
class AbstractModule ;
class ModuleInstanciation ;
class Module ;
class Context ;
2009-06-24 19:39:08 +04:00
class PolySet ;
2009-07-28 22:17:29 +04:00
class PolySetPtr ;
2009-06-25 12:12:41 +04:00
class CSGTerm ;
class CSGChain ;
2009-06-20 23:00:19 +04:00
class AbstractNode ;
2009-06-24 19:39:08 +04:00
class AbstractPolyNode ;
2009-06-20 23:00:19 +04:00
2009-07-21 23:33:39 +04:00
template < typename T >
class Grid2d
{
public :
double res ;
QHash < QPair < int , int > , T > db ;
Grid2d ( double resolution = 0.001 ) {
res = resolution ;
}
T & align ( double & x , double & y ) {
2009-08-10 11:18:35 +04:00
int ix = ( int ) round ( x / res ) ;
int iy = ( int ) round ( y / res ) ;
2009-07-21 23:33:39 +04:00
x = ix * res , y = iy * res ;
if ( db . contains ( QPair < int , int > ( ix , iy ) ) )
return db [ QPair < int , int > ( ix , iy ) ] ;
int dist = 10 ;
T * ptr = NULL ;
for ( int jx = ix - 1 ; jx < = ix + 1 ; jx + + )
for ( int jy = iy - 1 ; jy < = iy + 1 ; jy + + ) {
if ( ! db . contains ( QPair < int , int > ( jx , jy ) ) )
continue ;
if ( abs ( ix - jx ) + abs ( iy - jy ) < dist ) {
x = jx * res , y = jy * res ;
dist = abs ( ix - jx ) + abs ( iy - jy ) ;
ptr = & db [ QPair < int , int > ( jx , jy ) ] ;
}
}
if ( ptr )
return * ptr ;
return db [ QPair < int , int > ( ix , iy ) ] ;
}
bool has ( double x , double y ) {
2009-08-10 11:18:35 +04:00
int ix = ( int ) round ( x / res ) ;
int iy = ( int ) round ( y / res ) ;
2009-07-21 23:33:39 +04:00
if ( db . contains ( QPair < int , int > ( ix , iy ) ) )
return true ;
for ( int jx = ix - 1 ; jx < = ix + 1 ; jx + + )
for ( int jy = iy - 1 ; jy < = iy + 1 ; jy + + ) {
if ( db . contains ( QPair < int , int > ( jx , jy ) ) )
2009-08-10 11:18:35 +04:00
return true ;
2009-07-21 23:33:39 +04:00
}
return false ;
}
2009-07-22 02:12:50 +04:00
bool eq ( double x1 , double y1 , double x2 , double y2 ) {
align ( x1 , y1 ) ;
align ( x2 , y2 ) ;
if ( fabs ( x1 - x2 ) < res & & fabs ( y1 - y2 ) < res )
return true ;
return false ;
}
2009-07-21 23:33:39 +04:00
T & data ( double x , double y ) {
return align ( x , y ) ;
}
} ;
template < typename T >
class Grid3d
{
public :
double res ;
QHash < QPair < QPair < int , int > , int > , T > db ;
Grid3d ( double resolution = 0.001 ) {
res = resolution ;
}
T & align ( double & x , double & y , double & z ) {
2009-08-10 11:18:35 +04:00
int ix = ( int ) round ( x / res ) ;
int iy = ( int ) round ( y / res ) ;
int iz = ( int ) round ( z / res ) ;
2009-07-21 23:33:39 +04:00
x = ix * res , y = iy * res , z = iz * res ;
if ( db . contains ( QPair < QPair < int , int > , int > ( QPair < int , int > ( ix , iy ) , iz ) ) )
return db [ QPair < QPair < int , int > , int > ( QPair < int , int > ( ix , iy ) , iz ) ] ;
int dist = 10 ;
T * ptr = NULL ;
for ( int jx = ix - 1 ; jx < = ix + 1 ; jx + + )
for ( int jy = iy - 1 ; jy < = iy + 1 ; jy + + )
for ( int jz = iz - 1 ; jz < = iz + 1 ; jz + + ) {
if ( ! db . contains ( QPair < QPair < int , int > , int > ( QPair < int , int > ( jx , jy ) , jz ) ) )
continue ;
if ( abs ( ix - jx ) + abs ( iy - jy ) + abs ( iz - jz ) < dist ) {
x = jx * res , y = jy * res , z = jz * res ;
dist = abs ( ix - jx ) + abs ( iy - jy ) + abs ( iz - jz ) ;
ptr = & db [ QPair < QPair < int , int > , int > ( QPair < int , int > ( jx , jy ) , jz ) ] ;
}
}
if ( ptr )
return * ptr ;
return db [ QPair < QPair < int , int > , int > ( QPair < int , int > ( ix , iy ) , iz ) ] ;
}
bool has ( double x , double y , double z ) {
2009-08-10 11:18:35 +04:00
int ix = ( int ) round ( x / res ) ;
int iy = ( int ) round ( y / res ) ;
int iz = ( int ) round ( z / res ) ;
2009-07-21 23:33:39 +04:00
if ( db . contains ( QPair < QPair < int , int > , int > ( QPair < int , int > ( ix , iy ) , iz ) ) )
return true ;
for ( int jx = ix - 1 ; jx < = ix + 1 ; jx + + )
for ( int jy = iy - 1 ; jy < = iy + 1 ; jy + + )
for ( int jz = iz - 1 ; jz < = iz + 1 ; jz + + ) {
if ( db . contains ( QPair < QPair < int , int > , int > ( QPair < int , int > ( jx , jy ) , jz ) ) )
return true ;
}
return false ;
}
2009-07-22 02:12:50 +04:00
bool eq ( double x1 , double y1 , double z1 , double x2 , double y2 , double z2 ) {
align ( x1 , y1 , z1 ) ;
align ( x2 , y2 , z2 ) ;
if ( fabs ( x1 - x2 ) < res & & fabs ( y1 - y2 ) < res & & fabs ( z1 - z2 ) < res )
return true ;
return false ;
}
2009-07-21 23:33:39 +04:00
T & data ( double x , double y , double z ) {
return align ( x , y , z ) ;
}
} ;
2009-06-20 23:00:19 +04:00
class Value
{
public :
2009-06-23 14:31:25 +04:00
enum type_e {
UNDEFINED ,
BOOL ,
NUMBER ,
RANGE ,
VECTOR ,
STRING
} ;
enum type_e type ;
bool b ;
double num ;
2009-06-30 22:05:10 +04:00
QVector < Value * > vec ;
double range_begin ;
double range_step ;
double range_end ;
2009-06-21 12:59:53 +04:00
QString text ;
2009-06-20 23:00:19 +04:00
2009-06-23 14:31:25 +04:00
Value ( ) ;
2009-06-30 22:05:10 +04:00
~ Value ( ) ;
2009-06-23 14:31:25 +04:00
Value ( bool v ) ;
Value ( double v ) ;
Value ( const QString & t ) ;
Value ( const Value & v ) ;
2009-06-20 23:00:19 +04:00
Value & operator = ( const Value & v ) ;
2009-06-23 14:31:25 +04:00
2009-07-01 12:06:06 +04:00
Value operator ! ( ) const ;
Value operator & & ( const Value & v ) const ;
Value operator | | ( const Value & v ) const ;
2009-06-20 23:00:19 +04:00
Value operator + ( const Value & v ) const ;
Value operator - ( const Value & v ) const ;
Value operator * ( const Value & v ) const ;
Value operator / ( const Value & v ) const ;
Value operator % ( const Value & v ) const ;
2009-07-01 12:06:06 +04:00
Value operator < ( const Value & v ) const ;
Value operator < = ( const Value & v ) const ;
Value operator = = ( const Value & v ) const ;
Value operator ! = ( const Value & v ) const ;
Value operator > = ( const Value & v ) const ;
Value operator > ( const Value & v ) const ;
2009-06-20 23:00:19 +04:00
Value inv ( ) const ;
2009-06-21 10:53:46 +04:00
2009-06-30 22:05:10 +04:00
bool getnum ( double & v ) const ;
2009-07-20 21:45:39 +04:00
bool getv2 ( double & x , double & y ) const ;
2009-06-30 22:05:10 +04:00
bool getv3 ( double & x , double & y , double & z ) const ;
2009-06-21 10:53:46 +04:00
QString dump ( ) const ;
2009-06-23 14:31:25 +04:00
private :
void reset_undef ( ) ;
2009-06-20 23:00:19 +04:00
} ;
class Expression
{
public :
QVector < Expression * > children ;
2009-06-30 22:05:10 +04:00
Value * const_value ;
2009-06-20 23:00:19 +04:00
QString var_name ;
QString call_funcname ;
QVector < QString > call_argnames ;
2009-07-01 12:06:06 +04:00
// Boolean: ! && ||
// Operators: * / % + -
// Relations: < <= == != >= >
// Vector element: []
// Condition operator: ?:
2009-06-20 23:00:19 +04:00
// Invert (prefix '-'): I
// Constant value: C
2009-06-23 14:31:25 +04:00
// Create Range: R
2009-06-21 10:53:46 +04:00
// Create Vector: V
2009-06-23 14:31:25 +04:00
// Create Matrix: M
2009-06-21 10:53:46 +04:00
// Lookup Variable: L
2009-06-23 14:31:25 +04:00
// Lookup member per name: N
2009-06-20 23:00:19 +04:00
// Function call: F
2009-07-01 12:06:06 +04:00
QString type ;
2009-06-20 23:00:19 +04:00
Expression ( ) ;
~ Expression ( ) ;
2009-06-21 10:53:46 +04:00
Value evaluate ( const Context * context ) const ;
QString dump ( ) const ;
2009-06-20 23:00:19 +04:00
} ;
class AbstractFunction
{
public :
virtual ~ AbstractFunction ( ) ;
2009-06-21 10:53:46 +04:00
virtual Value evaluate ( const Context * ctx , const QVector < QString > & call_argnames , const QVector < Value > & call_argvalues ) const ;
virtual QString dump ( QString indent , QString name ) const ;
2009-06-20 23:00:19 +04:00
} ;
class BuiltinFunction : public AbstractFunction
{
public :
2009-07-25 00:50:30 +04:00
typedef Value ( * eval_func_t ) ( const QVector < QString > & argnames , const QVector < Value > & args ) ;
2009-06-20 23:00:19 +04:00
eval_func_t eval_func ;
BuiltinFunction ( eval_func_t f ) : eval_func ( f ) { }
virtual ~ BuiltinFunction ( ) ;
2009-06-21 10:53:46 +04:00
virtual Value evaluate ( const Context * ctx , const QVector < QString > & call_argnames , const QVector < Value > & call_argvalues ) const ;
virtual QString dump ( QString indent , QString name ) const ;
2009-06-20 23:00:19 +04:00
} ;
class Function : public AbstractFunction
{
public :
QVector < QString > argnames ;
QVector < Expression * > argexpr ;
2009-06-21 10:53:46 +04:00
Expression * expr ;
2009-06-20 23:00:19 +04:00
Function ( ) { }
virtual ~ Function ( ) ;
2009-06-21 10:53:46 +04:00
virtual Value evaluate ( const Context * ctx , const QVector < QString > & call_argnames , const QVector < Value > & call_argvalues ) const ;
virtual QString dump ( QString indent , QString name ) const ;
2009-06-20 23:00:19 +04:00
} ;
extern QHash < QString , AbstractFunction * > builtin_functions ;
extern void initialize_builtin_functions ( ) ;
2009-07-25 00:50:30 +04:00
extern void initialize_builtin_dxf_dim ( ) ;
2009-06-20 23:00:19 +04:00
extern void destroy_builtin_functions ( ) ;
class AbstractModule
{
public :
virtual ~ AbstractModule ( ) ;
2009-07-01 13:48:25 +04:00
virtual AbstractNode * evaluate ( const Context * ctx , const ModuleInstanciation * inst ) const ;
2009-06-21 10:53:46 +04:00
virtual QString dump ( QString indent , QString name ) const ;
2009-06-20 23:00:19 +04:00
} ;
class ModuleInstanciation
{
public :
QString label ;
QString modname ;
QVector < QString > argnames ;
QVector < Expression * > argexpr ;
2009-07-01 13:48:25 +04:00
QVector < Value > argvalues ;
2009-06-21 10:53:46 +04:00
QVector < ModuleInstanciation * > children ;
2009-06-20 23:00:19 +04:00
2009-07-01 13:48:25 +04:00
bool tag_root ;
bool tag_highlight ;
2009-07-23 16:05:05 +04:00
bool tag_background ;
2009-07-01 13:48:25 +04:00
const Context * ctx ;
2009-07-23 16:05:05 +04:00
ModuleInstanciation ( ) : tag_root ( false ) , tag_highlight ( false ) , tag_background ( false ) , ctx ( NULL ) { }
2009-06-20 23:00:19 +04:00
~ ModuleInstanciation ( ) ;
2009-06-21 10:53:46 +04:00
2009-06-21 12:59:53 +04:00
QString dump ( QString indent ) const ;
AbstractNode * evaluate ( const Context * ctx ) const ;
2009-06-20 23:00:19 +04:00
} ;
class Module : public AbstractModule
{
public :
QVector < QString > argnames ;
QVector < Expression * > argexpr ;
2009-06-21 15:41:11 +04:00
QVector < QString > assignments_var ;
QVector < Expression * > assignments_expr ;
2009-06-20 23:00:19 +04:00
QHash < QString , AbstractFunction * > functions ;
QHash < QString , AbstractModule * > modules ;
2009-06-21 10:53:46 +04:00
QVector < ModuleInstanciation * > children ;
2009-06-20 23:00:19 +04:00
Module ( ) { }
virtual ~ Module ( ) ;
2009-07-01 13:48:25 +04:00
virtual AbstractNode * evaluate ( const Context * ctx , const ModuleInstanciation * inst ) const ;
2009-06-21 10:53:46 +04:00
virtual QString dump ( QString indent , QString name ) const ;
2009-06-20 23:00:19 +04:00
} ;
extern QHash < QString , AbstractModule * > builtin_modules ;
extern void initialize_builtin_modules ( ) ;
extern void destroy_builtin_modules ( ) ;
2009-06-30 00:30:43 +04:00
extern void register_builtin_csgops ( ) ;
extern void register_builtin_transform ( ) ;
extern void register_builtin_primitives ( ) ;
2009-07-25 06:37:21 +04:00
extern void register_builtin_surface ( ) ;
2009-06-30 00:30:43 +04:00
extern void register_builtin_control ( ) ;
2009-07-14 09:25:55 +04:00
extern void register_builtin_render ( ) ;
2009-10-14 16:34:50 +04:00
extern void register_builtin_import ( ) ;
2009-07-17 03:11:08 +04:00
extern void register_builtin_dxf_linear_extrude ( ) ;
2009-07-17 04:34:15 +04:00
extern void register_builtin_dxf_rotate_extrude ( ) ;
2009-06-21 15:41:11 +04:00
2009-06-20 23:00:19 +04:00
class Context
{
public :
2009-06-21 10:53:46 +04:00
const Context * parent ;
2009-06-20 23:00:19 +04:00
QHash < QString , Value > variables ;
2009-06-26 08:32:52 +04:00
QHash < QString , Value > config_variables ;
2009-06-21 15:41:11 +04:00
const QHash < QString , AbstractFunction * > * functions_p ;
const QHash < QString , AbstractModule * > * modules_p ;
2009-06-20 23:00:19 +04:00
2009-06-26 08:32:52 +04:00
static QVector < const Context * > ctx_stack ;
Context ( const Context * parent = NULL ) ;
~ Context ( ) ;
2009-06-20 23:00:19 +04:00
void args ( const QVector < QString > & argnames , const QVector < Expression * > & argexpr , const QVector < QString > & call_argnames , const QVector < Value > & call_argvalues ) ;
2009-06-26 08:32:52 +04:00
void set_variable ( QString name , Value value ) ;
2009-07-20 21:45:39 +04:00
Value lookup_variable ( QString name , bool silent = false ) const ;
2009-06-26 08:32:52 +04:00
2009-06-21 10:53:46 +04:00
Value evaluate_function ( QString name , const QVector < QString > & argnames , const QVector < Value > & argvalues ) const ;
2009-07-01 13:48:25 +04:00
AbstractNode * evaluate_module ( const ModuleInstanciation * inst ) const ;
2009-06-20 23:00:19 +04:00
} ;
2009-07-17 03:11:08 +04:00
class DxfData
{
public :
struct Point {
double x , y ;
Point ( ) : x ( 0 ) , y ( 0 ) { }
Point ( double x , double y ) : x ( x ) , y ( y ) { }
} ;
struct Line {
Point * p [ 2 ] ;
2009-07-22 02:12:50 +04:00
bool disabled ;
Line ( Point * p1 , Point * p2 ) { p [ 0 ] = p1 ; p [ 1 ] = p2 ; disabled = false ; }
Line ( ) { p [ 0 ] = NULL ; p [ 1 ] = NULL ; disabled = false ; }
2009-07-17 03:11:08 +04:00
} ;
struct Path {
QList < Point * > points ;
bool is_closed , is_inner ;
Path ( ) : is_closed ( false ) , is_inner ( false ) { }
} ;
2009-07-25 00:50:30 +04:00
struct Dim {
unsigned int type ;
double coords [ 7 ] [ 2 ] ;
double angle ;
QString name ;
Dim ( ) {
for ( int i = 0 ; i < 7 ; i + + )
for ( int j = 0 ; j < 2 ; j + + )
coords [ i ] [ j ] = 0 ;
type = 0 ;
}
} ;
2009-07-17 03:11:08 +04:00
QList < Point > points ;
QList < Path > paths ;
2009-07-25 00:50:30 +04:00
QList < Dim > dims ;
2009-07-17 03:11:08 +04:00
2009-07-20 21:45:39 +04:00
DxfData ( double fn , double fs , double fa , QString filename , QString layername = QString ( ) , double xorigin = 0.0 , double yorigin = 0.0 , double scale = 1.0 ) ;
2009-07-17 03:11:08 +04:00
Point * p ( double x , double y ) ;
} ;
2009-06-21 15:41:11 +04:00
// The CGAL template magic slows down the compilation process by a factor of 5.
// So we only include the declaration of AbstractNode where it is needed...
# ifdef INCLUDE_ABSTRACT_NODE_DETAILS
2009-06-23 23:56:46 +04:00
# ifdef ENABLE_CGAL
2009-06-21 15:41:11 +04:00
# include <CGAL/Gmpq.h>
# include <CGAL/Cartesian.h>
# include <CGAL/Polyhedron_3.h>
# include <CGAL/Nef_polyhedron_3.h>
2009-06-21 20:41:38 +04:00
# include <CGAL/IO/Polyhedron_iostream.h>
2009-06-21 15:41:11 +04:00
2009-06-21 20:41:38 +04:00
typedef CGAL : : Cartesian < CGAL : : Gmpq > CGAL_Kernel ;
2009-06-21 15:41:11 +04:00
typedef CGAL : : Polyhedron_3 < CGAL_Kernel > CGAL_Polyhedron ;
2009-06-21 20:41:38 +04:00
typedef CGAL_Polyhedron : : HalfedgeDS CGAL_HDS ;
typedef CGAL : : Polyhedron_incremental_builder_3 < CGAL_HDS > CGAL_Polybuilder ;
2009-06-21 15:41:11 +04:00
typedef CGAL : : Nef_polyhedron_3 < CGAL_Kernel > CGAL_Nef_polyhedron ;
typedef CGAL_Nef_polyhedron : : Aff_transformation_3 CGAL_Aff_transformation ;
typedef CGAL_Nef_polyhedron : : Vector_3 CGAL_Vector ;
typedef CGAL_Nef_polyhedron : : Plane_3 CGAL_Plane ;
typedef CGAL_Nef_polyhedron : : Point_3 CGAL_Point ;
2009-06-23 23:56:46 +04:00
# endif /* ENABLE_CGAL */
2009-06-25 12:12:41 +04:00
# ifdef ENABLE_OPENCSG
# include <opencsg.h>
# endif
2009-06-24 14:59:15 +04:00
class PolySet
{
public :
struct Point {
double x , y , z ;
Point ( ) : x ( 0 ) , y ( 0 ) , z ( 0 ) { }
Point ( double x , double y , double z ) : x ( x ) , y ( y ) , z ( z ) { }
} ;
typedef QList < Point > Polygon ;
QVector < Polygon > polygons ;
2009-07-21 23:33:39 +04:00
Grid3d < void * > grid ;
2009-07-15 01:47:32 +04:00
int convexity ;
2009-06-24 14:59:15 +04:00
PolySet ( ) ;
2009-07-28 16:53:52 +04:00
~ PolySet ( ) ;
2009-06-24 14:59:15 +04:00
void append_poly ( ) ;
void append_vertex ( double x , double y , double z ) ;
void insert_vertex ( double x , double y , double z ) ;
2009-06-25 12:12:41 +04:00
enum colormode_e {
2009-08-04 22:55:25 +04:00
COLORMODE_NONE ,
COLORMODE_MATERIAL ,
COLORMODE_CUTOUT ,
COLORMODE_HIGHLIGHT ,
COLORMODE_BACKGROUND
2009-06-25 12:12:41 +04:00
} ;
2009-07-28 22:17:29 +04:00
static QCache < QString , PolySetPtr > ps_cache ;
2009-06-26 21:07:40 +04:00
void render_surface ( colormode_e colormode , GLint * shaderinfo = NULL ) const ;
2009-06-25 12:12:41 +04:00
void render_edges ( colormode_e colormode ) const ;
2009-06-24 14:59:15 +04:00
# ifdef ENABLE_CGAL
CGAL_Nef_polyhedron render_cgal_nef_polyhedron ( ) const ;
# endif
2009-07-28 16:53:52 +04:00
int refcount ;
PolySet * link ( ) ;
void unlink ( ) ;
} ;
class PolySetPtr
{
public :
PolySet * ps ;
PolySetPtr ( PolySet * ps ) {
this - > ps = ps ;
}
~ PolySetPtr ( ) {
ps - > unlink ( ) ;
}
2009-06-24 14:59:15 +04:00
} ;
class CSGTerm
{
public :
enum type_e {
2009-08-04 22:55:25 +04:00
TYPE_PRIMITIVE ,
TYPE_UNION ,
TYPE_INTERSECTION ,
TYPE_DIFFERENCE
2009-06-24 14:59:15 +04:00
} ;
type_e type ;
PolySet * polyset ;
2009-06-24 19:39:08 +04:00
QString label ;
2009-06-24 14:59:15 +04:00
CSGTerm * left ;
CSGTerm * right ;
2009-07-28 16:53:52 +04:00
double m [ 16 ] ;
2009-06-24 14:59:15 +04:00
int refcounter ;
2009-07-28 16:53:52 +04:00
CSGTerm ( PolySet * polyset , double m [ 16 ] , QString label ) ;
2009-06-24 14:59:15 +04:00
CSGTerm ( type_e type , CSGTerm * left , CSGTerm * right ) ;
2009-06-24 19:39:08 +04:00
CSGTerm * normalize ( ) ;
CSGTerm * normalize_tail ( ) ;
2009-06-24 14:59:15 +04:00
CSGTerm * link ( ) ;
void unlink ( ) ;
2009-06-24 19:39:08 +04:00
QString dump ( ) ;
2009-06-24 14:59:15 +04:00
} ;
2009-06-25 12:12:41 +04:00
class CSGChain
{
public :
QVector < PolySet * > polysets ;
2009-07-28 16:53:52 +04:00
QVector < double * > matrices ;
2009-06-25 12:12:41 +04:00
QVector < CSGTerm : : type_e > types ;
QVector < QString > labels ;
CSGChain ( ) ;
2009-07-28 16:53:52 +04:00
void add ( PolySet * polyset , double * m , CSGTerm : : type_e type , QString label ) ;
2009-08-04 22:55:25 +04:00
void import ( CSGTerm * term , CSGTerm : : type_e type = CSGTerm : : TYPE_UNION ) ;
2009-06-25 12:12:41 +04:00
QString dump ( ) ;
} ;
2009-06-24 14:59:15 +04:00
2009-06-20 23:00:19 +04:00
class AbstractNode
{
public :
QVector < AbstractNode * > children ;
2009-07-01 13:48:25 +04:00
const ModuleInstanciation * modinst ;
2009-06-21 15:41:11 +04:00
2009-06-21 16:43:52 +04:00
int progress_mark ;
void progress_prepare ( ) ;
void progress_report ( ) const ;
2009-06-24 14:59:15 +04:00
int idx ;
static int idx_counter ;
2009-07-03 11:51:22 +04:00
QString dump_cache ;
2009-06-24 14:59:15 +04:00
2009-07-01 13:48:25 +04:00
AbstractNode ( const ModuleInstanciation * mi ) ;
2009-06-21 15:41:11 +04:00
virtual ~ AbstractNode ( ) ;
2009-07-28 16:53:52 +04:00
virtual QString mk_cache_id ( ) const ;
2009-06-23 23:56:46 +04:00
# ifdef ENABLE_CGAL
2009-07-03 11:51:22 +04:00
static QCache < QString , CGAL_Nef_polyhedron > cgal_nef_cache ;
2009-06-21 15:41:11 +04:00
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron ( ) const ;
2009-06-24 14:59:15 +04:00
# endif
2009-07-23 16:05:05 +04:00
virtual CSGTerm * render_csg_term ( double m [ 16 ] , QVector < CSGTerm * > * highlights , QVector < CSGTerm * > * background ) const ;
2009-06-21 15:41:11 +04:00
virtual QString dump ( QString indent ) const ;
2009-06-20 23:00:19 +04:00
} ;
2009-06-24 14:59:15 +04:00
class AbstractPolyNode : public AbstractNode
{
public :
enum render_mode_e {
RENDER_CGAL ,
RENDER_OPENCSG
} ;
2009-07-01 13:48:25 +04:00
AbstractPolyNode ( const ModuleInstanciation * mi ) : AbstractNode ( mi ) { } ;
2009-06-24 14:59:15 +04:00
virtual PolySet * render_polyset ( render_mode_e mode ) const ;
# ifdef ENABLE_CGAL
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron ( ) const ;
# endif
2009-07-23 16:05:05 +04:00
virtual CSGTerm * render_csg_term ( double m [ 16 ] , QVector < CSGTerm * > * highlights , QVector < CSGTerm * > * background ) const ;
2009-07-28 22:17:29 +04:00
static CSGTerm * render_csg_term_from_ps ( double m [ 16 ] , QVector < CSGTerm * > * highlights , QVector < CSGTerm * > * background , PolySet * ps , const ModuleInstanciation * modinst , int idx ) ;
2009-06-24 14:59:15 +04:00
} ;
2009-06-21 16:43:52 +04:00
extern int progress_report_count ;
extern void ( * progress_report_f ) ( const class AbstractNode * , void * , int ) ;
extern void * progress_report_vp ;
void progress_report_prep ( AbstractNode * root , void ( * f ) ( const class AbstractNode * node , void * vp , int mark ) , void * vp ) ;
void progress_report_fin ( ) ;
2009-07-24 22:18:56 +04:00
void dxf_tesselate ( PolySet * ps , DxfData * dxf , double rot , bool up , double h ) ;
2009-07-21 23:33:39 +04:00
2009-06-23 23:56:46 +04:00
# else
2009-06-24 14:59:15 +04:00
// Needed for Mainwin::root_N
2009-06-23 23:56:46 +04:00
// this is a bit hackish - but a pointer is a pointer..
struct CGAL_Nef_polyhedron ;
2009-06-21 15:41:11 +04:00
# endif /* HIDE_ABSTRACT_NODE_DETAILS */
2009-06-23 23:56:46 +04:00
class GLView : public QGLWidget
{
Q_OBJECT
public :
void ( * renderfunc ) ( void * ) ;
void * renderfunc_vp ;
2009-10-12 15:31:54 +04:00
bool orthomode ;
2009-10-26 15:16:41 +03:00
bool showaxes ;
2009-10-14 06:07:23 +04:00
bool showcrosshairs ;
2009-10-12 18:49:31 +04:00
2009-06-23 23:56:46 +04:00
double viewer_distance ;
2009-10-14 06:07:23 +04:00
double object_rot_x ;
2009-06-23 23:56:46 +04:00
double object_rot_y ;
double object_rot_z ;
2009-10-14 06:07:23 +04:00
double object_trans_x ;
double object_trans_y ;
double object_trans_z ;
2009-06-23 23:56:46 +04:00
2009-06-27 02:01:53 +04:00
double w_h_ratio ;
GLint shaderinfo [ 11 ] ;
2009-06-26 17:29:48 +04:00
2009-10-14 13:44:41 +04:00
QLabel * statusLabel ;
2009-10-19 23:20:18 +04:00
# ifdef ENABLE_OPENCSG
bool opencsg_support ;
# endif
2009-10-14 11:59:44 +04:00
2009-06-23 23:56:46 +04:00
GLView ( QWidget * parent = NULL ) ;
protected :
bool mouse_drag_active ;
int last_mouse_x ;
int last_mouse_y ;
2009-10-05 15:23:23 +04:00
void keyPressEvent ( QKeyEvent * event ) ;
2009-06-23 23:56:46 +04:00
void wheelEvent ( QWheelEvent * event ) ;
void mousePressEvent ( QMouseEvent * event ) ;
void mouseMoveEvent ( QMouseEvent * event ) ;
void mouseReleaseEvent ( QMouseEvent * event ) ;
void initializeGL ( ) ;
void resizeGL ( int w , int h ) ;
void paintGL ( ) ;
2009-10-19 23:20:18 +04:00
# ifdef ENABLE_OPENCSG
private slots :
void display_opengl20_warning ( ) ;
# endif
2009-10-22 23:42:52 +04:00
signals :
void doAnimateUpdate ( ) ;
2009-06-23 23:56:46 +04:00
} ;
2009-11-01 21:26:38 +03:00
class MainWindow ;
class Highlighter : public QSyntaxHighlighter
{
public :
Highlighter ( QTextDocument * parent ) ;
void highlightBlock ( const QString & text ) ;
} ;
2009-06-23 23:56:46 +04:00
class MainWindow : public QMainWindow
{
Q_OBJECT
public :
QString filename ;
QSplitter * s1 , * s2 ;
QTextEdit * editor ;
2009-11-01 21:26:38 +03:00
Highlighter * highlighter ;
2009-06-23 23:56:46 +04:00
GLView * screen ;
QTextEdit * console ;
2009-07-28 19:15:29 +04:00
QWidget * animate_panel ;
QTimer * animate_timer ;
2009-07-28 22:17:29 +04:00
double tval , fps , fsteps ;
QLineEdit * e_tval , * e_fps , * e_fsteps ;
2009-07-28 19:15:29 +04:00
2009-06-23 23:56:46 +04:00
Context root_ctx ;
AbstractModule * root_module ;
2009-07-01 15:09:19 +04:00
AbstractNode * absolute_root_node ;
2009-06-24 19:39:08 +04:00
CSGTerm * root_raw_term ;
CSGTerm * root_norm_term ;
2009-06-25 12:12:41 +04:00
CSGChain * root_chain ;
2009-06-23 23:56:46 +04:00
# ifdef ENABLE_CGAL
CGAL_Nef_polyhedron * root_N ;
# endif
2009-07-01 15:09:19 +04:00
QVector < CSGTerm * > highlight_terms ;
CSGChain * highlights_chain ;
2009-07-23 16:05:05 +04:00
QVector < CSGTerm * > background_terms ;
CSGChain * background_chain ;
2009-07-01 15:09:19 +04:00
AbstractNode * root_node ;
2009-11-07 01:41:57 +03:00
QString last_compiled_doc ;
2009-07-03 01:21:05 +04:00
bool enableOpenCSG ;
2009-07-01 15:09:19 +04:00
2009-06-23 23:56:46 +04:00
MainWindow ( const char * filename = 0 ) ;
~ MainWindow ( ) ;
2009-07-28 19:15:29 +04:00
private slots :
void updatedFps ( ) ;
void updateTVal ( ) ;
2009-06-27 14:20:24 +04:00
private :
void load ( ) ;
2009-07-25 23:45:38 +04:00
void maybe_change_dir ( ) ;
2009-07-01 15:09:19 +04:00
void find_root_tag ( AbstractNode * n ) ;
2009-07-28 22:17:29 +04:00
void compile ( bool procevents ) ;
2009-06-27 14:20:24 +04:00
2009-06-23 23:56:46 +04:00
private slots :
void actionNew ( ) ;
void actionOpen ( ) ;
void actionSave ( ) ;
void actionSaveAs ( ) ;
2009-06-27 14:20:24 +04:00
void actionReload ( ) ;
2009-06-27 14:04:57 +04:00
2009-07-01 02:30:22 +04:00
private slots :
void editIndent ( ) ;
void editUnindent ( ) ;
void editComment ( ) ;
void editUncomment ( ) ;
2009-10-14 11:59:44 +04:00
void pasteViewportTranslation ( ) ;
void pasteViewportRotation ( ) ;
2009-07-01 02:30:22 +04:00
2009-06-25 02:38:31 +04:00
private slots :
2009-06-27 14:20:24 +04:00
void actionReloadCompile ( ) ;
2009-06-23 23:56:46 +04:00
void actionCompile ( ) ;
# ifdef ENABLE_CGAL
void actionRenderCGAL ( ) ;
# endif
void actionDisplayAST ( ) ;
2009-06-24 14:59:15 +04:00
void actionDisplayCSGTree ( ) ;
void actionDisplayCSGProducts ( ) ;
2009-10-18 12:50:01 +04:00
void actionExportSTLorOFF ( bool stl_mode ) ;
2009-06-23 23:56:46 +04:00
void actionExportSTL ( ) ;
void actionExportOFF ( ) ;
2009-06-25 02:38:31 +04:00
public :
# ifdef ENABLE_OPENCSG
QAction * actViewModeOpenCSG ;
# endif
# ifdef ENABLE_CGAL
QAction * actViewModeCGALSurface ;
QAction * actViewModeCGALGrid ;
# endif
2009-06-25 12:12:41 +04:00
QAction * actViewModeThrownTogether ;
2009-07-02 19:12:10 +04:00
QAction * actViewModeShowEdges ;
2009-10-26 15:16:41 +03:00
QAction * actViewModeShowAxes ;
2009-10-14 06:07:23 +04:00
QAction * actViewModeShowCrosshairs ;
2009-07-28 19:15:29 +04:00
QAction * actViewModeAnimate ;
2009-10-12 15:31:54 +04:00
QAction * actViewPerspective ;
QAction * actViewOrthogonal ;
2009-06-25 02:38:31 +04:00
void viewModeActionsUncheck ( ) ;
2009-10-19 23:20:18 +04:00
public slots :
2009-06-25 02:38:31 +04:00
# ifdef ENABLE_OPENCSG
void viewModeOpenCSG ( ) ;
# endif
# ifdef ENABLE_CGAL
void viewModeCGALSurface ( ) ;
void viewModeCGALGrid ( ) ;
# endif
2009-06-25 12:12:41 +04:00
void viewModeThrownTogether ( ) ;
2009-07-02 19:12:10 +04:00
void viewModeShowEdges ( ) ;
2009-10-26 15:16:41 +03:00
void viewModeShowAxes ( ) ;
2009-10-14 06:07:23 +04:00
void viewModeShowCrosshairs ( ) ;
2009-07-28 19:15:29 +04:00
void viewModeAnimate ( ) ;
2009-10-05 15:23:23 +04:00
void viewAngleTop ( ) ;
void viewAngleBottom ( ) ;
void viewAngleLeft ( ) ;
void viewAngleRight ( ) ;
void viewAngleFront ( ) ;
void viewAngleBack ( ) ;
void viewAngleDiagonal ( ) ;
2009-10-22 23:42:52 +04:00
void viewCenter ( ) ;
2009-10-12 15:31:54 +04:00
void viewPerspective ( ) ;
void viewOrthogonal ( ) ;
2009-11-07 01:41:57 +03:00
void animateUpdateDocChanged ( ) ;
2009-10-22 23:42:52 +04:00
void animateUpdate ( ) ;
2009-10-29 00:08:25 +03:00
void dragEnterEvent ( QDragEnterEvent * event ) ;
void dropEvent ( QDropEvent * event ) ;
2009-06-23 23:56:46 +04:00
} ;
extern AbstractModule * parse ( const char * text , int debug ) ;
2009-07-17 04:34:15 +04:00
extern int get_fragments_from_r ( double r , double fn , double fs , double fa ) ;
2009-06-21 10:53:46 +04:00
2009-10-19 22:27:47 +04:00
extern int parser_error_pos ;
2009-06-27 14:04:57 +04:00
extern QPointer < MainWindow > current_win ;
2009-10-18 12:50:01 +04:00
# ifdef ENABLE_CGAL
void export_stl ( CGAL_Nef_polyhedron * root_N , QString filename , QProgressDialog * pd ) ;
void export_off ( CGAL_Nef_polyhedron * root_N , QString filename , QProgressDialog * pd ) ;
# endif
extern void handle_dep ( QString filename ) ;
2009-06-27 14:04:57 +04:00
# define PRINT(_msg) do { if (current_win.isNull()) fprintf(stderr, "%s\n", QString(_msg).toAscii().data()); else current_win->console->append(_msg); } while (0)
# define PRINTF(_fmt, ...) do { QString _m; _m.sprintf(_fmt, ##__VA_ARGS__); PRINT(_m); } while (0)
# define PRINTA(_fmt, ...) do { QString _m = QString(_fmt).arg(__VA_ARGS__); PRINT(_m); } while (0)
2009-06-20 16:10:55 +04:00
# endif