2013-07-28 22:08:34 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// The parametric structure of our sketch, in multiple groups, that generate
|
|
|
|
// geometric entities and surfaces.
|
|
|
|
//
|
|
|
|
// Copyright 2008-2013 Jonathan Westhues.
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-03-26 09:18:12 +00:00
|
|
|
|
|
|
|
#ifndef __SKETCH_H
|
|
|
|
#define __SKETCH_H
|
|
|
|
|
2008-04-12 16:28:48 +00:00
|
|
|
class hGroup;
|
2008-03-28 10:00:37 +00:00
|
|
|
class hRequest;
|
2008-04-12 16:28:48 +00:00
|
|
|
class hEntity;
|
2008-03-28 10:00:37 +00:00
|
|
|
class hParam;
|
2009-07-20 01:47:59 +00:00
|
|
|
class hStyle;
|
|
|
|
class hConstraint;
|
|
|
|
class hEquation;
|
2008-03-26 09:18:12 +00:00
|
|
|
|
2008-04-09 08:39:01 +00:00
|
|
|
class Entity;
|
2008-04-12 16:28:48 +00:00
|
|
|
class Param;
|
2008-04-14 10:28:32 +00:00
|
|
|
class Equation;
|
2016-05-07 10:54:44 +00:00
|
|
|
class Style;
|
2008-04-14 10:28:32 +00:00
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class PolyError : uint32_t {
|
|
|
|
GOOD = 0,
|
|
|
|
NOT_CLOSED = 1,
|
|
|
|
NOT_COPLANAR = 2,
|
|
|
|
SELF_INTERSECTING = 3,
|
|
|
|
ZERO_LEN_EDGE = 4
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class StipplePattern : uint32_t {
|
|
|
|
CONTINUOUS = 0,
|
2016-05-26 19:20:39 +00:00
|
|
|
SHORT_DASH = 1,
|
|
|
|
DASH = 2,
|
|
|
|
LONG_DASH = 3,
|
|
|
|
DASH_DOT = 4,
|
|
|
|
DASH_DOT_DOT = 5,
|
|
|
|
DOT = 6,
|
|
|
|
FREEHAND = 7,
|
|
|
|
ZIGZAG = 8,
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
|
|
|
|
LAST = ZIGZAG
|
|
|
|
};
|
|
|
|
|
2016-07-21 20:27:53 +00:00
|
|
|
std::vector<double> StipplePatternDashes(StipplePattern pattern, double scale);
|
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class Command : uint32_t;
|
|
|
|
|
2008-04-09 08:39:01 +00:00
|
|
|
// All of the hWhatever handles are a 32-bit ID, that is used to represent
|
|
|
|
// some data structure in the sketch.
|
2008-04-08 12:54:53 +00:00
|
|
|
class hGroup {
|
|
|
|
public:
|
2008-04-19 11:09:47 +00:00
|
|
|
// bits 15: 0 -- group index
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t v;
|
2008-04-27 09:03:01 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hEntity entity(int i) const;
|
|
|
|
inline hParam param(int i) const;
|
|
|
|
inline hEquation equation(int i) const;
|
2008-04-08 12:54:53 +00:00
|
|
|
};
|
2008-03-28 10:00:37 +00:00
|
|
|
class hRequest {
|
|
|
|
public:
|
2008-04-19 11:09:47 +00:00
|
|
|
// bits 15: 0 -- request index
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t v;
|
2008-04-13 10:57:41 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hEntity entity(int i) const;
|
|
|
|
inline hParam param(int i) const;
|
2008-04-21 08:16:38 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline bool IsFromReferences() const;
|
2008-04-09 08:39:01 +00:00
|
|
|
};
|
|
|
|
class hEntity {
|
|
|
|
public:
|
2008-04-19 11:09:47 +00:00
|
|
|
// bits 15: 0 -- entity index
|
|
|
|
// 31:16 -- request index
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t v;
|
2008-04-13 10:57:41 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline bool isFromRequest() const;
|
|
|
|
inline hRequest request() const;
|
|
|
|
inline hGroup group() const;
|
|
|
|
inline hEquation equation(int i) const;
|
2008-03-28 10:00:37 +00:00
|
|
|
};
|
2008-04-08 12:54:53 +00:00
|
|
|
class hParam {
|
2008-03-28 10:00:37 +00:00
|
|
|
public:
|
2008-04-19 11:09:47 +00:00
|
|
|
// bits 15: 0 -- param index
|
|
|
|
// 31:16 -- request index
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t v;
|
2008-04-13 10:57:41 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hRequest request() const;
|
2008-04-08 12:54:53 +00:00
|
|
|
};
|
|
|
|
|
2009-07-20 01:47:59 +00:00
|
|
|
class hStyle {
|
|
|
|
public:
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t v;
|
2009-07-20 01:47:59 +00:00
|
|
|
};
|
|
|
|
|
2008-04-27 03:26:27 +00:00
|
|
|
class EntityId {
|
2008-04-27 09:03:01 +00:00
|
|
|
public:
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t v; // entity ID, starting from 0
|
2008-04-27 03:26:27 +00:00
|
|
|
};
|
|
|
|
class EntityMap {
|
2008-04-27 09:03:01 +00:00
|
|
|
public:
|
2008-04-27 03:26:27 +00:00
|
|
|
int tag;
|
|
|
|
|
|
|
|
EntityId h;
|
|
|
|
hEntity input;
|
|
|
|
int copyNumber;
|
|
|
|
// (input, copyNumber) gets mapped to ((Request)xxx).entity(h.v)
|
2013-09-19 04:33:12 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {}
|
2008-04-27 03:26:27 +00:00
|
|
|
};
|
|
|
|
|
2008-04-18 07:06:37 +00:00
|
|
|
// A set of requests. Every request must have an associated group.
|
2008-04-08 12:54:53 +00:00
|
|
|
class Group {
|
|
|
|
public:
|
|
|
|
static const hGroup HGROUP_REFERENCES;
|
2008-03-26 09:18:12 +00:00
|
|
|
|
2008-04-18 07:21:17 +00:00
|
|
|
int tag;
|
2008-04-09 08:39:01 +00:00
|
|
|
hGroup h;
|
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class Type : uint32_t {
|
2013-09-09 19:50:32 +00:00
|
|
|
DRAWING_3D = 5000,
|
|
|
|
DRAWING_WORKPLANE = 5001,
|
|
|
|
EXTRUDE = 5100,
|
|
|
|
LATHE = 5101,
|
|
|
|
ROTATE = 5200,
|
|
|
|
TRANSLATE = 5201,
|
2016-05-07 05:27:54 +00:00
|
|
|
LINKED = 5300
|
2013-09-09 19:50:32 +00:00
|
|
|
};
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
Group::Type type;
|
2008-04-24 06:22:16 +00:00
|
|
|
|
2008-02-07 09:53:52 +00:00
|
|
|
int order;
|
|
|
|
|
2008-04-27 09:03:01 +00:00
|
|
|
hGroup opA;
|
2008-06-21 10:18:20 +00:00
|
|
|
hGroup opB;
|
2008-04-23 07:29:19 +00:00
|
|
|
bool visible;
|
2008-02-15 11:35:15 +00:00
|
|
|
bool suppress;
|
2009-10-01 11:22:56 +00:00
|
|
|
bool relaxConstraints;
|
2016-01-21 15:01:43 +00:00
|
|
|
bool allowRedundant;
|
2010-05-10 01:06:09 +00:00
|
|
|
bool allDimsReference;
|
2009-12-15 12:26:22 +00:00
|
|
|
double scale;
|
2008-02-15 11:35:15 +00:00
|
|
|
|
2008-06-02 09:31:26 +00:00
|
|
|
bool clean;
|
2008-05-27 02:22:20 +00:00
|
|
|
hEntity activeWorkplane;
|
2008-06-14 08:43:38 +00:00
|
|
|
double valA;
|
2008-06-23 08:25:17 +00:00
|
|
|
double valB;
|
|
|
|
double valC;
|
2015-07-10 11:54:39 +00:00
|
|
|
RgbaColor color;
|
2008-04-23 07:29:19 +00:00
|
|
|
|
2008-05-26 09:56:50 +00:00
|
|
|
struct {
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
SolveResult how;
|
2008-07-10 07:42:35 +00:00
|
|
|
int dof;
|
2009-01-13 06:56:05 +00:00
|
|
|
List<hConstraint> remove;
|
2008-05-26 09:56:50 +00:00
|
|
|
} solved;
|
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class Subtype : uint32_t {
|
2013-09-09 19:50:32 +00:00
|
|
|
// For drawings in 2d
|
|
|
|
WORKPLANE_BY_POINT_ORTHO = 6000,
|
|
|
|
WORKPLANE_BY_LINE_SEGMENTS = 6001,
|
|
|
|
// For extrudes, translates, and rotates
|
|
|
|
ONE_SIDED = 7000,
|
|
|
|
TWO_SIDED = 7001
|
|
|
|
};
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
Group::Subtype subtype;
|
2008-05-17 08:02:39 +00:00
|
|
|
|
2008-06-12 04:36:33 +00:00
|
|
|
bool skipFirst; // for step and repeat ops
|
|
|
|
|
2008-05-11 10:40:37 +00:00
|
|
|
struct {
|
|
|
|
Quaternion q;
|
|
|
|
hEntity origin;
|
|
|
|
hEntity entityB;
|
|
|
|
hEntity entityC;
|
|
|
|
bool swapUV;
|
|
|
|
bool negateU;
|
|
|
|
bool negateV;
|
2008-06-01 08:29:59 +00:00
|
|
|
} predef;
|
2008-05-11 10:40:37 +00:00
|
|
|
|
2009-10-29 07:16:28 +00:00
|
|
|
SPolygon polyLoops;
|
|
|
|
SBezierLoopSetSet bezierLoops;
|
|
|
|
SBezierList bezierOpens;
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
|
2008-05-02 10:54:22 +00:00
|
|
|
struct {
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
PolyError how;
|
2008-05-02 10:54:22 +00:00
|
|
|
SEdge notClosedAt;
|
2009-01-23 03:30:30 +00:00
|
|
|
Vector errorPointAt;
|
2008-05-02 10:54:22 +00:00
|
|
|
} polyError;
|
2008-06-12 04:36:33 +00:00
|
|
|
|
2009-05-30 08:49:09 +00:00
|
|
|
bool booleanFailed;
|
|
|
|
|
2009-01-23 03:30:30 +00:00
|
|
|
SShell thisShell;
|
|
|
|
SShell runningShell;
|
2009-03-29 06:05:28 +00:00
|
|
|
|
2009-05-21 09:06:26 +00:00
|
|
|
SMesh thisMesh;
|
2008-06-21 10:18:20 +00:00
|
|
|
SMesh runningMesh;
|
2009-05-21 09:06:26 +00:00
|
|
|
|
|
|
|
bool displayDirty;
|
|
|
|
SMesh displayMesh;
|
2016-03-14 16:14:24 +00:00
|
|
|
SOutlineList displayOutlines;
|
2008-04-25 07:04:09 +00:00
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class CombineAs : uint32_t {
|
|
|
|
UNION = 0,
|
|
|
|
DIFFERENCE = 1,
|
|
|
|
ASSEMBLE = 2
|
2013-09-09 19:50:32 +00:00
|
|
|
};
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
CombineAs meshCombine;
|
2008-05-25 13:11:44 +00:00
|
|
|
|
2009-05-21 09:06:26 +00:00
|
|
|
bool forceToMesh;
|
|
|
|
|
2008-05-29 10:10:12 +00:00
|
|
|
IdList<EntityMap,EntityId> remap;
|
2013-09-09 19:50:32 +00:00
|
|
|
enum { REMAP_PRIME = 19477 };
|
2008-06-12 04:36:33 +00:00
|
|
|
int remapCache[REMAP_PRIME];
|
2008-05-29 10:10:12 +00:00
|
|
|
|
2016-05-07 05:27:54 +00:00
|
|
|
std::string linkFile;
|
|
|
|
std::string linkFileRel;
|
2015-12-27 01:03:24 +00:00
|
|
|
SMesh impMesh;
|
|
|
|
SShell impShell;
|
|
|
|
EntityList impEntity;
|
2008-05-29 10:10:12 +00:00
|
|
|
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string name;
|
2008-05-29 10:10:12 +00:00
|
|
|
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Activate();
|
|
|
|
std::string DescriptionString();
|
|
|
|
void Clear();
|
2008-04-23 07:29:19 +00:00
|
|
|
|
2008-06-23 08:25:17 +00:00
|
|
|
static void AddParam(ParamList *param, hParam hp, double v);
|
|
|
|
void Generate(EntityList *entity, ParamList *param);
|
2016-01-21 15:01:43 +00:00
|
|
|
bool IsSolvedOkay();
|
2009-07-20 19:05:33 +00:00
|
|
|
void TransformImportedBy(Vector t, Quaternion q);
|
2008-04-27 03:26:27 +00:00
|
|
|
// When a request generates entities from entities, and the source
|
|
|
|
// entities may have come from multiple requests, it's necessary to
|
|
|
|
// remap the entity ID so that it's still unique. We do this with a
|
|
|
|
// mapping list.
|
2013-09-09 19:50:32 +00:00
|
|
|
enum {
|
|
|
|
REMAP_LAST = 1000,
|
|
|
|
REMAP_TOP = 1001,
|
|
|
|
REMAP_BOTTOM = 1002,
|
|
|
|
REMAP_PT_TO_LINE = 1003,
|
2015-10-31 08:22:26 +00:00
|
|
|
REMAP_LINE_TO_FACE = 1004,
|
|
|
|
REMAP_LATHE_START = 1006,
|
|
|
|
REMAP_LATHE_END = 1007,
|
|
|
|
REMAP_PT_TO_ARC = 1008,
|
|
|
|
REMAP_PT_TO_NORMAL = 1009,
|
2013-09-09 19:50:32 +00:00
|
|
|
};
|
2008-04-27 03:26:27 +00:00
|
|
|
hEntity Remap(hEntity in, int copyNumber);
|
2008-06-23 08:25:17 +00:00
|
|
|
void MakeExtrusionLines(EntityList *el, hEntity in);
|
2015-10-31 08:22:26 +00:00
|
|
|
void MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *param, hEntity in, Vector pt, Vector axis, int ai);
|
2008-06-23 08:25:17 +00:00
|
|
|
void MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt);
|
|
|
|
void CopyEntity(EntityList *el,
|
2008-06-06 07:50:08 +00:00
|
|
|
Entity *ep, int timesApplied, int remap,
|
2008-06-01 08:29:59 +00:00
|
|
|
hParam dx, hParam dy, hParam dz,
|
2008-05-11 06:09:46 +00:00
|
|
|
hParam qw, hParam qvx, hParam qvy, hParam qvz,
|
2008-06-01 08:29:59 +00:00
|
|
|
bool asTrans, bool asAxisAngle);
|
2008-05-11 06:09:46 +00:00
|
|
|
|
2008-06-01 08:29:59 +00:00
|
|
|
void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index);
|
2008-05-11 06:09:46 +00:00
|
|
|
void GenerateEquations(IdList<Equation,hEquation> *l);
|
2016-05-05 05:54:05 +00:00
|
|
|
bool IsVisible();
|
2016-05-04 10:18:13 +00:00
|
|
|
int GetNumConstraints();
|
|
|
|
Vector ExtrusionGetVector();
|
|
|
|
void ExtrusionForceVectorTo(const Vector &v);
|
2008-04-27 03:26:27 +00:00
|
|
|
|
2009-01-19 03:33:15 +00:00
|
|
|
// Assembling the curves into loops, and into a piecewise linear polygon
|
|
|
|
// at the same time.
|
2009-12-03 19:14:34 +00:00
|
|
|
void AssembleLoops(bool *allClosed, bool *allCoplanar, bool *allNonZeroLen);
|
2016-05-05 05:54:05 +00:00
|
|
|
void GenerateLoops();
|
2008-06-21 10:18:20 +00:00
|
|
|
// And the mesh stuff
|
2016-05-05 05:54:05 +00:00
|
|
|
Group *PreviousGroup();
|
|
|
|
Group *RunningMeshGroup();
|
2016-04-02 13:34:17 +00:00
|
|
|
bool IsMeshGroup();
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void GenerateShellAndMesh();
|
2009-07-20 01:47:59 +00:00
|
|
|
template<class T> void GenerateForStepAndRepeat(T *steps, T *outs);
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
template<class T> void GenerateForBoolean(T *a, T *b, T *o, Group::CombineAs how);
|
2016-05-05 05:54:05 +00:00
|
|
|
void GenerateDisplayItems();
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
|
|
|
|
enum class DrawMeshAs { DEFAULT, HOVERED, SELECTED };
|
|
|
|
void DrawMesh(DrawMeshAs how, Canvas *canvas);
|
|
|
|
void Draw(Canvas *canvas);
|
|
|
|
void DrawPolyError(Canvas *canvas);
|
|
|
|
void DrawFilledPaths(Canvas *canvas);
|
2008-04-25 07:04:09 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
SPolygon GetPolygon();
|
2008-04-27 09:03:01 +00:00
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
static void MenuGroup(Command id);
|
2008-03-28 10:00:37 +00:00
|
|
|
};
|
2008-03-26 09:18:12 +00:00
|
|
|
|
2008-04-08 12:54:53 +00:00
|
|
|
// A user request for some primitive or derived operation; for example a
|
2008-04-20 11:35:10 +00:00
|
|
|
// line, or a step and repeat.
|
2008-04-08 12:54:53 +00:00
|
|
|
class Request {
|
2008-03-28 10:00:37 +00:00
|
|
|
public:
|
2008-04-09 08:39:01 +00:00
|
|
|
// Some predefined requests, that are present in every sketch.
|
2008-04-08 12:54:53 +00:00
|
|
|
static const hRequest HREQUEST_REFERENCE_XY;
|
|
|
|
static const hRequest HREQUEST_REFERENCE_YZ;
|
|
|
|
static const hRequest HREQUEST_REFERENCE_ZX;
|
|
|
|
|
2008-04-18 07:21:17 +00:00
|
|
|
int tag;
|
2008-04-18 07:06:37 +00:00
|
|
|
hRequest h;
|
|
|
|
|
2008-04-09 08:39:01 +00:00
|
|
|
// Types of requests
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class Type : uint32_t {
|
2013-09-09 19:50:32 +00:00
|
|
|
WORKPLANE = 100,
|
|
|
|
DATUM_POINT = 101,
|
|
|
|
LINE_SEGMENT = 200,
|
|
|
|
CUBIC = 300,
|
|
|
|
CUBIC_PERIODIC = 301,
|
|
|
|
CIRCLE = 400,
|
|
|
|
ARC_OF_CIRCLE = 500,
|
|
|
|
TTF_TEXT = 600
|
|
|
|
};
|
2008-04-08 12:54:53 +00:00
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
Request::Type type;
|
2009-10-21 04:46:01 +00:00
|
|
|
int extraPoints;
|
2008-03-26 09:18:12 +00:00
|
|
|
|
2008-04-27 03:26:27 +00:00
|
|
|
hEntity workplane; // or Entity::FREE_IN_3D
|
2008-04-08 12:54:53 +00:00
|
|
|
hGroup group;
|
2009-07-20 01:47:59 +00:00
|
|
|
hStyle style;
|
2008-04-27 03:26:27 +00:00
|
|
|
|
2008-04-22 13:14:15 +00:00
|
|
|
bool construction;
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string str;
|
|
|
|
std::string font;
|
2015-03-29 00:30:52 +00:00
|
|
|
|
2008-06-23 08:25:17 +00:00
|
|
|
static hParam AddParam(ParamList *param, hParam hp);
|
2016-05-21 05:18:00 +00:00
|
|
|
void Generate(EntityList *entity, ParamList *param) const;
|
2008-04-12 14:12:26 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
std::string DescriptionString() const;
|
|
|
|
int IndexOfPoint(hEntity he) const;
|
2013-09-19 04:33:12 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {}
|
2008-03-28 10:00:37 +00:00
|
|
|
};
|
2008-03-26 09:18:12 +00:00
|
|
|
|
2009-12-03 19:14:34 +00:00
|
|
|
#define MAX_POINTS_IN_ENTITY (12)
|
2009-04-19 04:28:21 +00:00
|
|
|
class EntityBase {
|
2008-03-28 10:00:37 +00:00
|
|
|
public:
|
2008-04-18 11:11:48 +00:00
|
|
|
int tag;
|
|
|
|
hEntity h;
|
|
|
|
|
2008-04-27 03:26:27 +00:00
|
|
|
static const hEntity FREE_IN_3D;
|
2008-05-08 07:30:30 +00:00
|
|
|
static const hEntity NO_ENTITY;
|
2008-04-27 03:26:27 +00:00
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class Type : uint32_t {
|
2013-09-09 19:50:32 +00:00
|
|
|
POINT_IN_3D = 2000,
|
|
|
|
POINT_IN_2D = 2001,
|
|
|
|
POINT_N_TRANS = 2010,
|
|
|
|
POINT_N_ROT_TRANS = 2011,
|
|
|
|
POINT_N_COPY = 2012,
|
|
|
|
POINT_N_ROT_AA = 2013,
|
|
|
|
|
|
|
|
NORMAL_IN_3D = 3000,
|
|
|
|
NORMAL_IN_2D = 3001,
|
|
|
|
NORMAL_N_COPY = 3010,
|
|
|
|
NORMAL_N_ROT = 3011,
|
|
|
|
NORMAL_N_ROT_AA = 3012,
|
|
|
|
|
|
|
|
DISTANCE = 4000,
|
|
|
|
DISTANCE_N_COPY = 4001,
|
|
|
|
|
|
|
|
FACE_NORMAL_PT = 5000,
|
|
|
|
FACE_XPROD = 5001,
|
|
|
|
FACE_N_ROT_TRANS = 5002,
|
|
|
|
FACE_N_TRANS = 5003,
|
|
|
|
FACE_N_ROT_AA = 5004,
|
|
|
|
|
|
|
|
WORKPLANE = 10000,
|
|
|
|
LINE_SEGMENT = 11000,
|
|
|
|
CUBIC = 12000,
|
|
|
|
CUBIC_PERIODIC = 12001,
|
|
|
|
CIRCLE = 13000,
|
|
|
|
ARC_OF_CIRCLE = 14000,
|
|
|
|
TTF_TEXT = 15000
|
|
|
|
};
|
2008-05-05 06:18:01 +00:00
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
Type type;
|
2008-04-09 08:39:01 +00:00
|
|
|
|
2009-04-19 04:28:21 +00:00
|
|
|
hGroup group;
|
|
|
|
hEntity workplane; // or Entity::FREE_IN_3D
|
|
|
|
|
2008-04-27 03:26:27 +00:00
|
|
|
// When it comes time to draw an entity, we look here to get the
|
|
|
|
// defining variables.
|
2009-12-03 19:14:34 +00:00
|
|
|
hEntity point[MAX_POINTS_IN_ENTITY];
|
2009-10-21 04:46:01 +00:00
|
|
|
int extraPoints;
|
2008-05-05 06:18:01 +00:00
|
|
|
hEntity normal;
|
2008-05-07 08:19:37 +00:00
|
|
|
hEntity distance;
|
|
|
|
// The only types that have their own params are points, normals,
|
|
|
|
// and directions.
|
2008-05-11 06:09:46 +00:00
|
|
|
hParam param[7];
|
2008-05-05 06:18:01 +00:00
|
|
|
|
2008-05-29 10:10:12 +00:00
|
|
|
// Transformed points/normals/distances have their numerical base
|
2008-05-05 06:18:01 +00:00
|
|
|
Vector numPoint;
|
|
|
|
Quaternion numNormal;
|
2008-05-07 08:19:37 +00:00
|
|
|
double numDistance;
|
2008-06-13 04:41:27 +00:00
|
|
|
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string str;
|
|
|
|
std::string font;
|
2008-05-07 04:17:29 +00:00
|
|
|
|
2008-04-27 09:03:01 +00:00
|
|
|
// For entities that are derived by a transformation, the number of
|
|
|
|
// times to apply the transformation.
|
|
|
|
int timesApplied;
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
Quaternion GetAxisAngleQuaternion(int param0) const;
|
|
|
|
ExprQuaternion GetAxisAngleQuaternionExprs(int param0) const;
|
2008-06-02 09:31:26 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool IsCircle() const;
|
|
|
|
Expr *CircleGetRadiusExpr() const;
|
|
|
|
double CircleGetRadiusNum() const;
|
|
|
|
void ArcGetAngles(double *thetaa, double *thetab, double *dtheta) const;
|
2008-05-08 07:30:30 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool HasVector() const;
|
|
|
|
ExprVector VectorGetExprs() const;
|
|
|
|
Vector VectorGetNum() const;
|
|
|
|
Vector VectorGetRefPoint() const;
|
|
|
|
Vector VectorGetStartPoint() const;
|
2008-05-07 04:17:29 +00:00
|
|
|
|
2008-05-07 08:19:37 +00:00
|
|
|
// For distances
|
2016-05-21 05:18:00 +00:00
|
|
|
bool IsDistance() const;
|
|
|
|
double DistanceGetNum() const;
|
|
|
|
Expr *DistanceGetExpr() const;
|
2008-05-07 08:19:37 +00:00
|
|
|
void DistanceForceTo(double v);
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool IsWorkplane() const;
|
2008-05-05 11:17:00 +00:00
|
|
|
// The plane is points P such that P dot (xn, yn, zn) - d = 0
|
2016-05-21 05:18:00 +00:00
|
|
|
void WorkplaneGetPlaneExprs(ExprVector *n, Expr **d) const;
|
|
|
|
ExprVector WorkplaneGetOffsetExprs() const;
|
|
|
|
Vector WorkplaneGetOffset() const;
|
|
|
|
EntityBase *Normal() const;
|
|
|
|
|
|
|
|
bool IsFace() const;
|
|
|
|
ExprVector FaceGetNormalExprs() const;
|
|
|
|
Vector FaceGetNormalNum() const;
|
|
|
|
ExprVector FaceGetPointExprs() const;
|
|
|
|
Vector FaceGetPointNum() const;
|
|
|
|
|
|
|
|
bool IsPoint() const;
|
2008-04-19 11:09:47 +00:00
|
|
|
// Applies for any of the point types
|
2016-05-21 05:18:00 +00:00
|
|
|
Vector PointGetNum() const;
|
|
|
|
ExprVector PointGetExprs() const;
|
|
|
|
void PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) const;
|
2008-04-19 11:44:44 +00:00
|
|
|
void PointForceTo(Vector v);
|
2008-05-11 06:09:46 +00:00
|
|
|
// These apply only the POINT_N_ROT_TRANS, which has an assoc rotation
|
2016-05-21 05:18:00 +00:00
|
|
|
Quaternion PointGetQuaternion() const;
|
2008-05-11 06:09:46 +00:00
|
|
|
void PointForceQuaternionTo(Quaternion q);
|
2008-04-21 08:16:38 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool IsNormal() const;
|
2008-05-05 06:18:01 +00:00
|
|
|
// Applies for any of the normal types
|
2016-05-21 05:18:00 +00:00
|
|
|
Quaternion NormalGetNum() const;
|
|
|
|
ExprQuaternion NormalGetExprs() const;
|
2008-05-05 06:18:01 +00:00
|
|
|
void NormalForceTo(Quaternion q);
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
Vector NormalU() const;
|
|
|
|
Vector NormalV() const;
|
|
|
|
Vector NormalN() const;
|
|
|
|
ExprVector NormalExprsU() const;
|
|
|
|
ExprVector NormalExprsV() const;
|
|
|
|
ExprVector NormalExprsN() const;
|
2016-05-05 05:54:05 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
Vector CubicGetStartNum() const;
|
|
|
|
Vector CubicGetFinishNum() const;
|
|
|
|
ExprVector CubicGetStartTangentExprs() const;
|
|
|
|
ExprVector CubicGetFinishTangentExprs() const;
|
|
|
|
Vector CubicGetStartTangentNum() const;
|
|
|
|
Vector CubicGetFinishTangentNum() const;
|
2016-05-05 05:54:05 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool HasEndpoints() const;
|
|
|
|
Vector EndpointStart() const;
|
|
|
|
Vector EndpointFinish() const;
|
2009-11-03 18:54:49 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) const;
|
|
|
|
void GenerateEquations(IdList<Equation,hEquation> *l) const;
|
2013-09-19 04:33:12 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {}
|
2009-04-19 04:28:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Entity : public EntityBase {
|
|
|
|
public:
|
2015-03-27 15:31:23 +00:00
|
|
|
// Necessary for Entity e = {} to zero-initialize, since
|
|
|
|
// classes with base classes are not aggregates and
|
|
|
|
// the default constructor does not initialize members.
|
2015-12-28 15:46:08 +00:00
|
|
|
//
|
|
|
|
// Note EntityBase({}); without explicitly value-initializing
|
|
|
|
// the base class, MSVC2013 will default-initialize it, leaving
|
|
|
|
// POD members with indeterminate value.
|
|
|
|
Entity() : EntityBase({}), forceHidden(), actPoint(), actNormal(),
|
2015-03-27 15:31:23 +00:00
|
|
|
actDistance(), actVisible(), style(), construction(),
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
beziers(), edges(), edgesChordTol(), screenBBox(), screenBBoxValid() {};
|
2015-03-27 15:31:23 +00:00
|
|
|
|
2016-05-07 05:27:54 +00:00
|
|
|
// A linked entity that was hidden in the source file ends up hidden
|
2009-04-19 04:28:21 +00:00
|
|
|
// here too.
|
|
|
|
bool forceHidden;
|
|
|
|
|
|
|
|
// All points/normals/distances have their numerical value; this is
|
2016-05-07 05:27:54 +00:00
|
|
|
// a convenience, to simplify the link/assembly code, so that the
|
2009-04-19 04:28:21 +00:00
|
|
|
// part is entirely described by the entities.
|
|
|
|
Vector actPoint;
|
|
|
|
Quaternion actNormal;
|
|
|
|
double actDistance;
|
|
|
|
// and the shown state also gets saved here, for later import
|
|
|
|
bool actVisible;
|
|
|
|
|
2009-07-20 01:47:59 +00:00
|
|
|
hStyle style;
|
2009-04-19 04:28:21 +00:00
|
|
|
bool construction;
|
|
|
|
|
2016-02-04 09:46:24 +00:00
|
|
|
SBezierList beziers;
|
|
|
|
SEdgeList edges;
|
|
|
|
double edgesChordTol;
|
2016-03-05 15:09:11 +00:00
|
|
|
BBox screenBBox;
|
|
|
|
bool screenBBoxValid;
|
2016-02-04 09:46:24 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool IsStylable() const;
|
|
|
|
bool IsVisible() const;
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
|
|
|
|
enum class DrawAs { DEFAULT, HIDDEN, HOVERED, SELECTED };
|
|
|
|
void Draw(DrawAs how, Canvas *canvas);
|
|
|
|
void GetReferencePoints(std::vector<Vector> *refs);
|
|
|
|
int GetPositionOfPoint(const Camera &camera, Point2d p);
|
2009-04-19 04:28:21 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
void ComputeInterpolatingSpline(SBezierList *sbl, bool periodic) const;
|
|
|
|
void GenerateBezierCurves(SBezierList *sbl) const;
|
2016-05-24 03:47:08 +00:00
|
|
|
void GenerateEdges(SEdgeList *el);
|
2008-07-10 05:26:08 +00:00
|
|
|
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
SBezierList *GetOrGenerateBezierCurves();
|
|
|
|
SEdgeList *GetOrGenerateEdges();
|
|
|
|
BBox GetOrGenerateScreenBBox(bool *hasBBox);
|
2008-04-19 11:09:47 +00:00
|
|
|
|
2008-06-13 04:41:27 +00:00
|
|
|
void CalculateNumerical(bool forExport);
|
2008-05-29 10:10:12 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
std::string DescriptionString() const;
|
2016-02-04 09:46:24 +00:00
|
|
|
|
|
|
|
void Clear() {
|
|
|
|
beziers.l.Clear();
|
|
|
|
edges.l.Clear();
|
|
|
|
}
|
2008-03-28 10:00:37 +00:00
|
|
|
};
|
2008-03-26 09:18:12 +00:00
|
|
|
|
2009-10-22 14:02:08 +00:00
|
|
|
class EntReqTable {
|
|
|
|
public:
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
static bool GetRequestInfo(Request::Type req, int extraPoints,
|
2016-05-25 08:47:08 +00:00
|
|
|
EntityBase::Type *ent, int *pts, bool *hasNormal, bool *hasDistance);
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
static bool GetEntityInfo(EntityBase::Type ent, int extraPoints,
|
2016-05-25 08:47:08 +00:00
|
|
|
Request::Type *req, int *pts, bool *hasNormal, bool *hasDistance);
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
static Request::Type GetRequestForEntity(EntityBase::Type ent);
|
2009-10-22 14:02:08 +00:00
|
|
|
};
|
|
|
|
|
2008-04-09 08:39:01 +00:00
|
|
|
class Param {
|
2008-03-28 10:00:37 +00:00
|
|
|
public:
|
2008-04-18 07:21:17 +00:00
|
|
|
int tag;
|
2008-04-09 08:39:01 +00:00
|
|
|
hParam h;
|
2008-04-18 07:21:17 +00:00
|
|
|
|
2008-04-09 08:39:01 +00:00
|
|
|
double val;
|
|
|
|
bool known;
|
2009-01-04 12:01:46 +00:00
|
|
|
bool free;
|
2008-05-07 07:10:20 +00:00
|
|
|
|
|
|
|
// Used only in the solver
|
|
|
|
hParam substd;
|
2008-05-11 06:09:46 +00:00
|
|
|
|
|
|
|
static const hParam NO_PARAM;
|
2013-09-19 04:33:12 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {}
|
2008-03-28 10:00:37 +00:00
|
|
|
};
|
2008-03-26 09:18:12 +00:00
|
|
|
|
2008-04-08 12:54:53 +00:00
|
|
|
|
2008-04-14 10:28:32 +00:00
|
|
|
class hConstraint {
|
|
|
|
public:
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t v;
|
2008-04-20 11:35:10 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hEquation equation(int i) const;
|
2008-04-14 10:28:32 +00:00
|
|
|
};
|
|
|
|
|
2009-04-19 04:28:21 +00:00
|
|
|
class ConstraintBase {
|
2008-04-14 10:28:32 +00:00
|
|
|
public:
|
2009-04-19 04:28:21 +00:00
|
|
|
int tag;
|
|
|
|
hConstraint h;
|
|
|
|
|
2008-05-26 09:56:50 +00:00
|
|
|
static const hConstraint NO_CONSTRAINT;
|
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class Type : uint32_t {
|
2013-09-09 19:50:32 +00:00
|
|
|
POINTS_COINCIDENT = 20,
|
|
|
|
PT_PT_DISTANCE = 30,
|
|
|
|
PT_PLANE_DISTANCE = 31,
|
|
|
|
PT_LINE_DISTANCE = 32,
|
|
|
|
PT_FACE_DISTANCE = 33,
|
|
|
|
PROJ_PT_DISTANCE = 34,
|
|
|
|
PT_IN_PLANE = 41,
|
|
|
|
PT_ON_LINE = 42,
|
|
|
|
PT_ON_FACE = 43,
|
|
|
|
EQUAL_LENGTH_LINES = 50,
|
|
|
|
LENGTH_RATIO = 51,
|
|
|
|
EQ_LEN_PT_LINE_D = 52,
|
|
|
|
EQ_PT_LN_DISTANCES = 53,
|
|
|
|
EQUAL_ANGLE = 54,
|
|
|
|
EQUAL_LINE_ARC_LEN = 55,
|
2015-10-27 10:28:33 +00:00
|
|
|
LENGTH_DIFFERENCE = 56,
|
2013-09-09 19:50:32 +00:00
|
|
|
SYMMETRIC = 60,
|
|
|
|
SYMMETRIC_HORIZ = 61,
|
|
|
|
SYMMETRIC_VERT = 62,
|
|
|
|
SYMMETRIC_LINE = 63,
|
|
|
|
AT_MIDPOINT = 70,
|
|
|
|
HORIZONTAL = 80,
|
|
|
|
VERTICAL = 81,
|
|
|
|
DIAMETER = 90,
|
|
|
|
PT_ON_CIRCLE = 100,
|
|
|
|
SAME_ORIENTATION = 110,
|
|
|
|
ANGLE = 120,
|
|
|
|
PARALLEL = 121,
|
|
|
|
PERPENDICULAR = 122,
|
|
|
|
ARC_LINE_TANGENT = 123,
|
|
|
|
CUBIC_LINE_TANGENT = 124,
|
|
|
|
CURVE_CURVE_TANGENT = 125,
|
|
|
|
EQUAL_RADIUS = 130,
|
|
|
|
WHERE_DRAGGED = 200,
|
|
|
|
|
|
|
|
COMMENT = 1000
|
|
|
|
};
|
2008-06-12 08:58:58 +00:00
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
Type type;
|
2008-04-27 03:26:27 +00:00
|
|
|
|
2008-04-14 10:28:32 +00:00
|
|
|
hGroup group;
|
2008-04-27 03:26:27 +00:00
|
|
|
hEntity workplane;
|
2008-04-14 10:28:32 +00:00
|
|
|
|
|
|
|
// These are the parameters for the constraint.
|
2008-06-14 08:43:38 +00:00
|
|
|
double valA;
|
2008-04-19 11:09:47 +00:00
|
|
|
hEntity ptA;
|
|
|
|
hEntity ptB;
|
2008-04-14 10:28:32 +00:00
|
|
|
hEntity entityA;
|
|
|
|
hEntity entityB;
|
2008-07-20 12:24:43 +00:00
|
|
|
hEntity entityC;
|
|
|
|
hEntity entityD;
|
2008-07-13 12:44:05 +00:00
|
|
|
bool other;
|
2010-05-10 04:14:06 +00:00
|
|
|
bool other2;
|
2008-04-14 10:28:32 +00:00
|
|
|
|
2009-04-19 04:28:21 +00:00
|
|
|
bool reference; // a ref dimension, that generates no eqs
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string comment; // since comments are represented as constraints
|
2008-06-09 09:03:21 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool HasLabel() const;
|
2010-05-10 01:06:09 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
void Generate(IdList<Equation,hEquation> *l) const;
|
|
|
|
void GenerateReal(IdList<Equation,hEquation> *l) const;
|
2009-04-19 04:28:21 +00:00
|
|
|
// Some helpers when generating symbolic constraint equations
|
2016-05-05 05:54:05 +00:00
|
|
|
void ModifyToSatisfy();
|
2016-05-21 05:18:00 +00:00
|
|
|
void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) const;
|
2009-04-19 04:28:21 +00:00
|
|
|
static Expr *DirectionCosine(hEntity wrkpl, ExprVector ae, ExprVector be);
|
|
|
|
static Expr *Distance(hEntity workplane, hEntity pa, hEntity pb);
|
|
|
|
static Expr *PointLineDistance(hEntity workplane, hEntity pt, hEntity ln);
|
|
|
|
static Expr *PointPlaneDistance(ExprVector p, hEntity plane);
|
|
|
|
static Expr *VectorsParallel(int eq, ExprVector a, ExprVector b);
|
|
|
|
static ExprVector PointInThreeSpace(hEntity workplane, Expr *u, Expr *v);
|
2013-09-19 04:33:12 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {}
|
2009-04-19 04:28:21 +00:00
|
|
|
};
|
2008-06-12 08:58:58 +00:00
|
|
|
|
2009-04-19 04:28:21 +00:00
|
|
|
class Constraint : public ConstraintBase {
|
|
|
|
public:
|
2015-03-27 15:31:23 +00:00
|
|
|
// See Entity::Entity().
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
Constraint() : ConstraintBase({}), disp() {}
|
2015-03-27 15:31:23 +00:00
|
|
|
|
2008-04-14 10:28:32 +00:00
|
|
|
// These define how the constraint is drawn on-screen.
|
|
|
|
struct {
|
|
|
|
Vector offset;
|
2009-07-20 01:47:59 +00:00
|
|
|
hStyle style;
|
2008-04-14 10:28:32 +00:00
|
|
|
} disp;
|
|
|
|
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
bool IsVisible() const;
|
2016-05-21 05:18:00 +00:00
|
|
|
bool IsStylable() const;
|
2016-05-07 10:54:44 +00:00
|
|
|
hStyle GetStyle() const;
|
2016-05-21 05:18:00 +00:00
|
|
|
bool HasLabel() const;
|
|
|
|
std::string Label() const;
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
|
|
|
|
enum class DrawAs { DEFAULT, HOVERED, SELECTED };
|
|
|
|
void Draw(DrawAs how, Canvas *canvas);
|
|
|
|
Vector GetLabelPos(const Camera &camera);
|
|
|
|
void GetReferencePoints(const Camera &camera, std::vector<Vector> *refs);
|
|
|
|
|
|
|
|
void DoLayout(DrawAs how, Canvas *canvas,
|
|
|
|
Vector *labelPos, std::vector<Vector> *refs);
|
2016-08-02 11:48:16 +00:00
|
|
|
void DoLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b);
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
bool DoLineExtend(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector p0, Vector p1, Vector pt, double salient);
|
|
|
|
void DoArcForAngle(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector a0, Vector da, Vector b0, Vector db,
|
|
|
|
Vector offset, Vector *ref, bool trim);
|
|
|
|
void DoArrow(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector p, Vector dir, Vector n, double width, double angle, double da);
|
|
|
|
void DoLineWithArrows(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector ref, Vector a, Vector b, bool onlyOneExt);
|
|
|
|
int DoLineTrimmedAgainstBox(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector ref, Vector a, Vector b, bool extend,
|
|
|
|
Vector gr, Vector gu, double swidth, double sheight);
|
|
|
|
int DoLineTrimmedAgainstBox(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector ref, Vector a, Vector b, bool extend = true);
|
|
|
|
void DoLabel(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector ref, Vector *labelPos, Vector gr, Vector gu);
|
|
|
|
void DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector *p);
|
|
|
|
void DoEqualLenTicks(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
Vector a, Vector b, Vector gn, Vector *refp);
|
|
|
|
void DoEqualRadiusTicks(Canvas *canvas, Canvas::hStroke hcs,
|
|
|
|
hEntity he, Vector *refp);
|
2008-04-21 10:12:04 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
std::string DescriptionString() const;
|
2008-04-14 10:28:32 +00:00
|
|
|
|
2016-04-26 00:47:02 +00:00
|
|
|
static hConstraint AddConstraint(Constraint *c, bool rememberForUndo);
|
|
|
|
static hConstraint AddConstraint(Constraint *c);
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
static void MenuConstrain(Command id);
|
|
|
|
static void DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA);
|
2008-04-23 07:29:19 +00:00
|
|
|
|
2016-04-26 00:47:02 +00:00
|
|
|
static hConstraint ConstrainCoincident(hEntity ptA, hEntity ptB);
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
static hConstraint Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA);
|
|
|
|
static hConstraint Constrain(Constraint::Type type, hEntity ptA, hEntity ptB,
|
2008-07-14 02:45:11 +00:00
|
|
|
hEntity entityA, hEntity entityB,
|
2010-05-16 16:36:23 +00:00
|
|
|
bool other, bool other2);
|
2008-04-14 10:28:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class hEquation {
|
|
|
|
public:
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
uint32_t v;
|
2008-09-05 11:25:53 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline bool isFromConstraint() const;
|
|
|
|
inline hConstraint constraint() const;
|
2008-04-14 10:28:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Equation {
|
|
|
|
public:
|
2008-04-18 07:21:17 +00:00
|
|
|
int tag;
|
2008-04-14 10:28:32 +00:00
|
|
|
hEquation h;
|
2008-04-18 07:21:17 +00:00
|
|
|
|
2008-04-14 10:28:32 +00:00
|
|
|
Expr *e;
|
2013-09-19 04:33:12 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {}
|
2008-04-14 10:28:32 +00:00
|
|
|
};
|
|
|
|
|
2008-05-08 07:30:30 +00:00
|
|
|
|
2009-07-20 01:47:59 +00:00
|
|
|
class Style {
|
2009-09-17 07:32:36 +00:00
|
|
|
public:
|
2009-07-20 01:47:59 +00:00
|
|
|
int tag;
|
|
|
|
hStyle h;
|
2013-09-09 19:50:32 +00:00
|
|
|
|
|
|
|
enum {
|
|
|
|
// If an entity has no style, then it will be colored according to
|
|
|
|
// whether the group that it's in is active or not, whether it's
|
|
|
|
// construction or not, and so on.
|
|
|
|
NO_STYLE = 0,
|
|
|
|
|
|
|
|
ACTIVE_GRP = 1,
|
|
|
|
CONSTRUCTION = 2,
|
|
|
|
INACTIVE_GRP = 3,
|
|
|
|
DATUM = 4,
|
|
|
|
SOLID_EDGE = 5,
|
|
|
|
CONSTRAINT = 6,
|
|
|
|
SELECTED = 7,
|
|
|
|
HOVERED = 8,
|
|
|
|
CONTOUR_FILL = 9,
|
|
|
|
NORMALS = 10,
|
|
|
|
ANALYZE = 11,
|
|
|
|
DRAW_ERROR = 12,
|
|
|
|
DIM_SOLID = 13,
|
2016-03-09 04:53:46 +00:00
|
|
|
HIDDEN_EDGE = 14,
|
2016-03-14 16:14:24 +00:00
|
|
|
OUTLINE = 15,
|
2013-09-09 19:50:32 +00:00
|
|
|
|
|
|
|
FIRST_CUSTOM = 0x100
|
|
|
|
};
|
2009-07-20 01:47:59 +00:00
|
|
|
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string name;
|
2009-09-17 07:32:36 +00:00
|
|
|
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
enum class UnitsAs : uint32_t {
|
|
|
|
PIXELS = 0,
|
|
|
|
MM = 1
|
2013-09-09 19:50:32 +00:00
|
|
|
};
|
2009-07-20 01:47:59 +00:00
|
|
|
double width;
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
UnitsAs widthAs;
|
2009-09-24 15:52:48 +00:00
|
|
|
double textHeight;
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
UnitsAs textHeightAs;
|
|
|
|
enum class TextOrigin : uint32_t {
|
|
|
|
NONE = 0x00,
|
|
|
|
LEFT = 0x01,
|
|
|
|
RIGHT = 0x02,
|
|
|
|
BOT = 0x04,
|
|
|
|
TOP = 0x08
|
2013-09-09 19:50:32 +00:00
|
|
|
};
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
TextOrigin textOrigin;
|
2009-09-29 11:35:19 +00:00
|
|
|
double textAngle;
|
2015-07-10 11:54:39 +00:00
|
|
|
RgbaColor color;
|
2009-10-22 17:16:20 +00:00
|
|
|
bool filled;
|
2015-07-10 11:54:39 +00:00
|
|
|
RgbaColor fillColor;
|
2009-07-20 01:47:59 +00:00
|
|
|
bool visible;
|
|
|
|
bool exportable;
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
StipplePattern stippleType;
|
2016-02-23 18:00:39 +00:00
|
|
|
double stippleScale;
|
2016-03-13 09:27:59 +00:00
|
|
|
int zIndex;
|
2009-09-17 07:32:36 +00:00
|
|
|
|
|
|
|
// The default styles, for entities that don't have a style assigned yet,
|
|
|
|
// and for datums and such.
|
|
|
|
typedef struct {
|
2013-08-26 18:58:35 +00:00
|
|
|
hStyle h;
|
|
|
|
const char *cnfPrefix;
|
2015-07-10 11:54:39 +00:00
|
|
|
RgbaColor color;
|
2013-08-26 18:58:35 +00:00
|
|
|
double width;
|
2016-03-13 09:27:59 +00:00
|
|
|
int zIndex;
|
2009-09-17 07:32:36 +00:00
|
|
|
} Default;
|
|
|
|
static const Default Defaults[];
|
|
|
|
|
2015-11-06 08:40:12 +00:00
|
|
|
static std::string CnfColor(const std::string &prefix);
|
|
|
|
static std::string CnfWidth(const std::string &prefix);
|
2016-02-21 19:07:58 +00:00
|
|
|
static std::string CnfTextHeight(const std::string &prefix);
|
2015-11-06 08:40:12 +00:00
|
|
|
static std::string CnfPrefixToName(const std::string &prefix);
|
2009-09-18 08:14:15 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
static void CreateAllDefaultStyles();
|
2009-09-17 07:32:36 +00:00
|
|
|
static void CreateDefaultStyle(hStyle h);
|
2016-05-26 10:17:31 +00:00
|
|
|
static void FillDefaultStyle(Style *s, const Default *d = NULL, bool factory = false);
|
2016-05-05 05:54:05 +00:00
|
|
|
static void FreezeDefaultStyles();
|
|
|
|
static void LoadFactoryDefaults();
|
2009-09-17 07:32:36 +00:00
|
|
|
|
Use C99 integer types and C++ boolean types/values
This change comprehensively replaces the use of Microsoft-standard integer
and boolean types with their C99/C++ standard equivalents, as the latter is
more appropriate for a cross-platform application. With matter-of-course
exceptions in the Win32-specific code, the types/values have been converted
as follows:
QWORD --> uint64_t
SQWORD --> int64_t
DWORD --> uint32_t
SDWORD --> int32_t
WORD --> uint16_t
SWORD --> int16_t
BYTE --> uint8_t
BOOL --> bool
TRUE --> true
FALSE --> false
The following related changes are also included:
* Added C99 integer type definitions for Windows, as stdint.h is not
available prior to Visual Studio 2010
* Changed types of some variables in the SolveSpace class from 'int' to
'bool', as they actually represent boolean settings
* Implemented new Cnf{Freeze,Thaw}Bool() functions to support boolean
variables in the Registry
* Cnf{Freeze,Thaw}DWORD() are now Cnf{Freeze,Thaw}Int()
* TtfFont::Get{WORD,DWORD}() are now TtfFont::Get{USHORT,ULONG}() (names
inspired by the OpenType spec)
* RGB colors are packed into an integer of type uint32_t (nee DWORD), but
in a few places, these were represented by an int; these have been
corrected to uint32_t
2013-10-02 05:45:13 +00:00
|
|
|
static void AssignSelectionToStyle(uint32_t v);
|
2016-04-13 08:43:06 +00:00
|
|
|
static uint32_t CreateCustomStyle(bool rememberForUndo = true);
|
2009-09-23 10:59:59 +00:00
|
|
|
|
2015-07-10 11:54:39 +00:00
|
|
|
static RgbaColor RewriteColor(RgbaColor rgb);
|
2010-08-14 19:00:25 +00:00
|
|
|
|
2009-09-17 07:32:36 +00:00
|
|
|
static Style *Get(hStyle hs);
|
2015-07-10 11:54:39 +00:00
|
|
|
static RgbaColor Color(hStyle hs, bool forExport=false);
|
|
|
|
static RgbaColor FillColor(hStyle hs, bool forExport=false);
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
static double Width(hStyle hs);
|
2015-07-10 11:54:39 +00:00
|
|
|
static RgbaColor Color(int hs, bool forExport=false);
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
static double Width(int hs);
|
2009-09-22 05:46:30 +00:00
|
|
|
static double WidthMm(int hs);
|
2009-09-24 15:52:48 +00:00
|
|
|
static double TextHeight(hStyle hs);
|
2016-03-02 17:15:28 +00:00
|
|
|
static double DefaultTextHeight();
|
2009-09-22 05:46:30 +00:00
|
|
|
static bool Exportable(int hs);
|
2009-09-17 07:32:36 +00:00
|
|
|
static hStyle ForEntity(hEntity he);
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
static StipplePattern PatternType(hStyle hs);
|
2016-02-23 18:00:39 +00:00
|
|
|
static double StippleScaleMm(hStyle hs);
|
2009-09-18 08:14:15 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
std::string DescriptionString() const;
|
2013-09-19 04:33:12 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {}
|
2009-07-20 01:47:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hEntity hGroup::entity(int i) const
|
2013-10-19 05:36:45 +00:00
|
|
|
{ hEntity r; r.v = 0x80000000 | (v << 16) | (uint32_t)i; return r; }
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hParam hGroup::param(int i) const
|
2013-10-19 05:36:45 +00:00
|
|
|
{ hParam r; r.v = 0x80000000 | (v << 16) | (uint32_t)i; return r; }
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hEquation hGroup::equation(int i) const
|
2013-10-19 05:36:45 +00:00
|
|
|
{ hEquation r; r.v = (v << 16) | 0x80000000 | (uint32_t)i; return r; }
|
2008-05-08 07:30:30 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline bool hRequest::IsFromReferences() const {
|
2008-05-08 07:30:30 +00:00
|
|
|
if(v == Request::HREQUEST_REFERENCE_XY.v) return true;
|
|
|
|
if(v == Request::HREQUEST_REFERENCE_YZ.v) return true;
|
|
|
|
if(v == Request::HREQUEST_REFERENCE_ZX.v) return true;
|
|
|
|
return false;
|
|
|
|
}
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hEntity hRequest::entity(int i) const
|
2013-10-19 05:36:45 +00:00
|
|
|
{ hEntity r; r.v = (v << 16) | (uint32_t)i; return r; }
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hParam hRequest::param(int i) const
|
2013-10-19 05:36:45 +00:00
|
|
|
{ hParam r; r.v = (v << 16) | (uint32_t)i; return r; }
|
2008-05-08 07:30:30 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline bool hEntity::isFromRequest() const
|
2008-05-08 07:30:30 +00:00
|
|
|
{ if(v & 0x80000000) return false; else return true; }
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hRequest hEntity::request() const
|
2008-05-08 07:30:30 +00:00
|
|
|
{ hRequest r; r.v = (v >> 16); return r; }
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hGroup hEntity::group() const
|
2008-05-11 10:40:37 +00:00
|
|
|
{ hGroup r; r.v = (v >> 16) & 0x3fff; return r; }
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hEquation hEntity::equation(int i) const
|
2016-05-18 22:51:36 +00:00
|
|
|
{ hEquation r; r.v = v | 0x40000000; return r; }
|
2008-05-08 07:30:30 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hRequest hParam::request() const
|
2008-05-08 07:30:30 +00:00
|
|
|
{ hRequest r; r.v = (v >> 16); return r; }
|
|
|
|
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hEquation hConstraint::equation(int i) const
|
2013-10-19 05:36:45 +00:00
|
|
|
{ hEquation r; r.v = (v << 16) | (uint32_t)i; return r; }
|
2008-04-20 11:35:10 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
inline bool hEquation::isFromConstraint() const
|
2008-09-05 11:25:53 +00:00
|
|
|
{ if(v & 0xc0000000) return false; else return true; }
|
2016-05-21 05:18:00 +00:00
|
|
|
inline hConstraint hEquation::constraint() const
|
2008-09-05 11:25:53 +00:00
|
|
|
{ hConstraint r; r.v = (v >> 16); return r; }
|
|
|
|
|
2009-12-03 19:14:34 +00:00
|
|
|
// The format for entities stored on the clipboard.
|
2009-12-04 08:08:41 +00:00
|
|
|
class ClipboardRequest {
|
2009-12-03 19:14:34 +00:00
|
|
|
public:
|
Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:
class Foo {
enum { X = 1, Y = 2 };
int kind;
}
... foo.kind = Foo::X; ...
and convert it to this:
class Foo {
enum class Kind : uint32_t { X = 1, Y = 2 };
Kind kind;
}
... foo.kind = Foo::Kind::X;
(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)
The benefits are as follows:
* The type of the field gives a clear indication of intent, both
to humans and tools (such as binding generators).
* The compiler is able to automatically warn when a switch is not
exhaustive; but this is currently suppressed by the
default: ssassert(false, ...)
idiom.
* Integers and plain enums are weakly type checked: they implicitly
convert into each other. This can hide bugs where type conversion
is performed but not intended. Enum classes are strongly type
checked.
* Plain enums pollute parent namespaces; enum classes do not.
Almost every defined enum we have already has a kind of ad-hoc
namespacing via `NAMESPACE_`, which is now explicit.
* Plain enums do not have a well-defined ABI size, which is
important for bindings. Enum classes can have it, if specified.
We specify the base type for all enums as uint32_t, which is
a safe choice and allows us to not change the numeric values
of any variants.
This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-20 08:31:20 +00:00
|
|
|
Request::Type type;
|
2009-12-03 19:14:34 +00:00
|
|
|
int extraPoints;
|
|
|
|
hStyle style;
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string str;
|
|
|
|
std::string font;
|
2009-12-03 19:14:34 +00:00
|
|
|
bool construction;
|
2009-12-04 08:08:41 +00:00
|
|
|
|
|
|
|
Vector point[MAX_POINTS_IN_ENTITY];
|
|
|
|
double distance;
|
|
|
|
|
|
|
|
hEntity oldEnt;
|
|
|
|
hEntity oldPointEnt[MAX_POINTS_IN_ENTITY];
|
|
|
|
hRequest newReq;
|
2009-12-03 19:14:34 +00:00
|
|
|
};
|
2008-04-13 10:57:41 +00:00
|
|
|
|
2008-04-08 12:54:53 +00:00
|
|
|
#endif
|