2013-07-28 22:08:34 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Data structures used frequently in the program, various kinds of vectors
|
|
|
|
// (of real numbers, not symbolic algebra stuff) and our templated lists.
|
|
|
|
//
|
|
|
|
// Copyright 2008-2013 Jonathan Westhues.
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-03-25 10:02:13 +00:00
|
|
|
#ifndef __DSC_H
|
|
|
|
#define __DSC_H
|
|
|
|
|
2015-02-26 14:19:15 +00:00
|
|
|
#include "solvespace.h"
|
|
|
|
|
2008-04-18 11:11:48 +00:00
|
|
|
class Vector;
|
2009-04-14 04:19:23 +00:00
|
|
|
class Vector4;
|
2008-05-08 07:30:30 +00:00
|
|
|
class Point2d;
|
|
|
|
class hEntity;
|
2008-06-01 08:29:59 +00:00
|
|
|
class hParam;
|
2008-04-18 11:11:48 +00:00
|
|
|
|
|
|
|
class Quaternion {
|
|
|
|
public:
|
2008-05-05 06:18:01 +00:00
|
|
|
// a + (vx)*i + (vy)*j + (vz)*k
|
|
|
|
double w, vx, vy, vz;
|
2008-04-18 11:11:48 +00:00
|
|
|
|
2009-03-15 23:04:45 +00:00
|
|
|
static const Quaternion IDENTITY;
|
|
|
|
|
2008-06-01 08:45:11 +00:00
|
|
|
static Quaternion From(double w, double vx, double vy, double vz);
|
2008-06-02 03:31:37 +00:00
|
|
|
static Quaternion From(hParam w, hParam vx, hParam vy, hParam vz);
|
2008-06-01 08:45:11 +00:00
|
|
|
static Quaternion From(Vector u, Vector v);
|
2009-04-29 02:42:44 +00:00
|
|
|
static Quaternion From(Vector axis, double dtheta);
|
2008-04-18 11:11:48 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
Quaternion Plus(Quaternion b) const;
|
|
|
|
Quaternion Minus(Quaternion b) const;
|
|
|
|
Quaternion ScaledBy(double s) const;
|
|
|
|
double Magnitude() const;
|
|
|
|
Quaternion WithMagnitude(double s) const;
|
2015-03-29 00:30:52 +00:00
|
|
|
|
2008-04-18 11:11:48 +00:00
|
|
|
// Call a rotation matrix [ u' v' n' ]'; this returns the first and
|
|
|
|
// second rows, where that matrix is generated by this quaternion
|
2016-05-21 05:18:00 +00:00
|
|
|
Vector RotationU() const;
|
|
|
|
Vector RotationV() const;
|
|
|
|
Vector RotationN() const;
|
|
|
|
Vector Rotate(Vector p) const;
|
|
|
|
|
|
|
|
Quaternion ToThe(double p) const;
|
|
|
|
Quaternion Inverse() const;
|
|
|
|
Quaternion Times(Quaternion b) const;
|
|
|
|
Quaternion Mirror() const;
|
2008-04-18 11:11:48 +00:00
|
|
|
};
|
|
|
|
|
2008-03-28 10:00:37 +00:00
|
|
|
class Vector {
|
|
|
|
public:
|
2008-03-25 10:02:13 +00:00
|
|
|
double x, y, z;
|
2015-03-29 00:30:52 +00:00
|
|
|
|
2008-06-01 08:45:11 +00:00
|
|
|
static Vector From(double x, double y, double z);
|
|
|
|
static Vector From(hParam x, hParam y, hParam z);
|
2008-05-19 09:23:49 +00:00
|
|
|
static Vector AtIntersectionOfPlanes(Vector n1, double d1,
|
|
|
|
Vector n2, double d2);
|
2009-01-03 12:27:33 +00:00
|
|
|
static Vector AtIntersectionOfLines(Vector a0, Vector a1,
|
|
|
|
Vector b0, Vector b1,
|
2009-01-21 05:04:38 +00:00
|
|
|
bool *skew,
|
|
|
|
double *pa=NULL, double *pb=NULL);
|
2009-02-23 10:06:02 +00:00
|
|
|
static Vector AtIntersectionOfPlaneAndLine(Vector n, double d,
|
|
|
|
Vector p0, Vector p1,
|
|
|
|
bool *parallel);
|
2009-02-27 13:04:36 +00:00
|
|
|
static Vector AtIntersectionOfPlanes(Vector na, double da,
|
|
|
|
Vector nb, double db,
|
2009-03-15 23:04:45 +00:00
|
|
|
Vector nc, double dc, bool *parallel);
|
2009-07-07 08:21:59 +00:00
|
|
|
static void ClosestPointBetweenLines(Vector pa, Vector da,
|
|
|
|
Vector pb, Vector db,
|
|
|
|
double *ta, double *tb);
|
2008-03-27 09:53:51 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
double Element(int i) const;
|
|
|
|
bool Equals(Vector v, double tol=LENGTH_EPS) const;
|
|
|
|
bool EqualsExactly(Vector v) const;
|
|
|
|
Vector Plus(Vector b) const;
|
|
|
|
Vector Minus(Vector b) const;
|
|
|
|
Vector Negated() const;
|
|
|
|
Vector Cross(Vector b) const;
|
|
|
|
double DirectionCosineWith(Vector b) const;
|
|
|
|
double Dot(Vector b) const;
|
|
|
|
Vector Normal(int which) const;
|
|
|
|
Vector RotatedAbout(Vector orig, Vector axis, double theta) const;
|
|
|
|
Vector RotatedAbout(Vector axis, double theta) const;
|
|
|
|
Vector DotInToCsys(Vector u, Vector v, Vector n) const;
|
|
|
|
Vector ScaleOutOfCsys(Vector u, Vector v, Vector n) const;
|
|
|
|
double DistanceToLine(Vector p0, Vector dp) const;
|
|
|
|
bool OnLineSegment(Vector a, Vector b, double tol=LENGTH_EPS) const;
|
|
|
|
Vector ClosestPointOnLine(Vector p0, Vector deltal) const;
|
|
|
|
double Magnitude() const;
|
|
|
|
double MagSquared() const;
|
|
|
|
Vector WithMagnitude(double s) const;
|
|
|
|
Vector ScaledBy(double s) const;
|
|
|
|
Vector ProjectInto(hEntity wrkpl) const;
|
|
|
|
Vector ProjectVectorInto(hEntity wrkpl) const;
|
|
|
|
double DivPivoting(Vector delta) const;
|
|
|
|
Vector ClosestOrtho() const;
|
|
|
|
void MakeMaxMin(Vector *maxv, Vector *minv) const;
|
|
|
|
Vector ClampWithin(double minv, double maxv) const;
|
2009-01-27 07:59:58 +00:00
|
|
|
static bool BoundingBoxesDisjoint(Vector amax, Vector amin,
|
|
|
|
Vector bmax, Vector bmin);
|
2009-03-08 10:59:57 +00:00
|
|
|
static bool BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
2016-05-25 12:08:19 +00:00
|
|
|
Vector p0, Vector p1, bool asSegment);
|
2016-05-21 05:18:00 +00:00
|
|
|
bool OutsideAndNotOn(Vector maxv, Vector minv) const;
|
2015-03-29 00:30:52 +00:00
|
|
|
Vector InPerspective(Vector u, Vector v, Vector n,
|
2016-05-21 05:18:00 +00:00
|
|
|
Vector origin, double cameraTan) const;
|
|
|
|
Point2d Project2d(Vector u, Vector v) const;
|
|
|
|
Point2d ProjectXy() const;
|
|
|
|
Vector4 Project4d() const;
|
2009-04-14 04:19:23 +00:00
|
|
|
};
|
|
|
|
|
2016-06-24 09:06:30 +00:00
|
|
|
struct VectorHash {
|
|
|
|
size_t operator()(const Vector &v) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct VectorPred {
|
|
|
|
bool operator()(Vector a, Vector b) const;
|
|
|
|
};
|
|
|
|
|
2009-04-14 04:19:23 +00:00
|
|
|
class Vector4 {
|
|
|
|
public:
|
|
|
|
double w, x, y, z;
|
2015-03-29 00:30:52 +00:00
|
|
|
|
2009-04-14 04:19:23 +00:00
|
|
|
static Vector4 From(double w, double x, double y, double z);
|
|
|
|
static Vector4 From(double w, Vector v3);
|
|
|
|
static Vector4 Blend(Vector4 a, Vector4 b, double t);
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
Vector4 Plus(Vector4 b) const;
|
|
|
|
Vector4 Minus(Vector4 b) const;
|
|
|
|
Vector4 ScaledBy(double s) const;
|
|
|
|
Vector PerspectiveProject() const;
|
2008-03-28 10:00:37 +00:00
|
|
|
};
|
2008-03-25 10:02:13 +00:00
|
|
|
|
2008-03-28 10:00:37 +00:00
|
|
|
class Point2d {
|
|
|
|
public:
|
2008-03-27 09:53:51 +00:00
|
|
|
double x, y;
|
2008-04-12 14:12:26 +00:00
|
|
|
|
2009-03-14 20:01:20 +00:00
|
|
|
static Point2d From(double x, double y);
|
2016-04-24 22:35:23 +00:00
|
|
|
static Point2d FromPolar(double r, double a);
|
2009-03-14 20:01:20 +00:00
|
|
|
|
2016-02-03 13:00:52 +00:00
|
|
|
Point2d Plus(const Point2d &b) const;
|
|
|
|
Point2d Minus(const Point2d &b) const;
|
|
|
|
Point2d ScaledBy(double s) const;
|
|
|
|
double DivPivoting(Point2d delta) const;
|
|
|
|
double Dot(Point2d p) const;
|
|
|
|
double DistanceTo(const Point2d &p) const;
|
2016-05-25 12:08:19 +00:00
|
|
|
double DistanceToLine(const Point2d &p0, const Point2d &dp, bool asSegment) 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
|
|
|
double DistanceToLineSigned(const Point2d &p0, const Point2d &dp, bool asSegment) const;
|
2016-04-24 22:35:23 +00:00
|
|
|
double Angle() const;
|
|
|
|
double AngleTo(const Point2d &p) const;
|
2016-05-05 05:54:05 +00:00
|
|
|
double Magnitude() const;
|
|
|
|
double MagSquared() const;
|
2016-02-03 13:00:52 +00:00
|
|
|
Point2d WithMagnitude(double v) const;
|
2016-05-05 05:54:05 +00:00
|
|
|
Point2d Normal() const;
|
2016-02-03 13:00:52 +00:00
|
|
|
bool Equals(Point2d v, double tol=LENGTH_EPS) const;
|
2008-03-28 10:00:37 +00:00
|
|
|
};
|
2008-03-27 09:53:51 +00:00
|
|
|
|
2009-01-13 06:56:05 +00:00
|
|
|
// A simple list
|
|
|
|
template <class T>
|
|
|
|
class List {
|
|
|
|
public:
|
|
|
|
T *elem;
|
|
|
|
int n;
|
|
|
|
int elemsAllocated;
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void AllocForOneMore() {
|
2009-01-13 06:56:05 +00:00
|
|
|
if(n >= elemsAllocated) {
|
|
|
|
elemsAllocated = (elemsAllocated + 32)*2;
|
2015-11-06 11:11:11 +00:00
|
|
|
T *newElem = (T *)MemAlloc((size_t)elemsAllocated*sizeof(elem[0]));
|
|
|
|
for(int i = 0; i < n; i++) {
|
|
|
|
new(&newElem[i]) T(std::move(elem[i]));
|
|
|
|
elem[i].~T();
|
|
|
|
}
|
|
|
|
MemFree(elem);
|
|
|
|
elem = newElem;
|
2009-01-13 06:56:05 +00:00
|
|
|
}
|
2009-06-27 05:53:56 +00:00
|
|
|
}
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
void Add(const T *t) {
|
2009-06-27 05:53:56 +00:00
|
|
|
AllocForOneMore();
|
2015-11-06 11:11:11 +00:00
|
|
|
new(&elem[n++]) T(*t);
|
2009-01-13 06:56:05 +00:00
|
|
|
}
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
void AddToBeginning(const T *t) {
|
2009-06-27 05:53:56 +00:00
|
|
|
AllocForOneMore();
|
2015-11-06 11:11:11 +00:00
|
|
|
new(&elem[n]) T();
|
|
|
|
std::move_backward(elem, elem + 1, elem + n + 1);
|
2009-06-27 05:53:56 +00:00
|
|
|
elem[0] = *t;
|
2015-11-06 11:11:11 +00:00
|
|
|
n++;
|
2009-06-27 05:53:56 +00:00
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
T *First() {
|
2009-01-19 10:37:10 +00:00
|
|
|
return (n == 0) ? NULL : &(elem[0]);
|
|
|
|
}
|
2016-05-21 05:18:00 +00:00
|
|
|
const T *First() const {
|
|
|
|
return (n == 0) ? NULL : &(elem[0]);
|
|
|
|
}
|
2009-01-19 10:37:10 +00:00
|
|
|
T *NextAfter(T *prev) {
|
|
|
|
if(!prev) return NULL;
|
|
|
|
if(prev - elem == (n - 1)) return NULL;
|
|
|
|
return prev + 1;
|
|
|
|
}
|
2016-05-21 05:18:00 +00:00
|
|
|
const T *NextAfter(const T *prev) const {
|
|
|
|
if(!prev) return NULL;
|
|
|
|
if(prev - elem == (n - 1)) return NULL;
|
|
|
|
return prev + 1;
|
|
|
|
}
|
2009-01-19 10:37:10 +00:00
|
|
|
|
2016-05-29 14:14:38 +00:00
|
|
|
T *begin() { return &elem[0]; }
|
|
|
|
T *end() { return &elem[n]; }
|
|
|
|
const T *begin() const { return &elem[0]; }
|
|
|
|
const T *end() const { return &elem[n]; }
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void ClearTags() {
|
2009-01-13 06:56:05 +00:00
|
|
|
int i;
|
|
|
|
for(i = 0; i < n; i++) {
|
|
|
|
elem[i].tag = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {
|
2015-11-06 11:11:11 +00:00
|
|
|
for(int i = 0; i < n; i++)
|
|
|
|
elem[i].~T();
|
2009-01-13 06:56:05 +00:00
|
|
|
if(elem) MemFree(elem);
|
|
|
|
elem = NULL;
|
|
|
|
n = elemsAllocated = 0;
|
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void RemoveTagged() {
|
2009-01-13 06:56:05 +00:00
|
|
|
int src, dest;
|
|
|
|
dest = 0;
|
|
|
|
for(src = 0; src < n; src++) {
|
|
|
|
if(elem[src].tag) {
|
|
|
|
// this item should be deleted
|
|
|
|
} else {
|
|
|
|
if(src != dest) {
|
|
|
|
elem[dest] = elem[src];
|
|
|
|
}
|
|
|
|
dest++;
|
|
|
|
}
|
|
|
|
}
|
2015-11-06 11:11:11 +00:00
|
|
|
for(int i = dest; i < n; i++)
|
|
|
|
elem[i].~T();
|
2009-01-13 06:56:05 +00:00
|
|
|
n = dest;
|
|
|
|
// and elemsAllocated is untouched, because we didn't resize
|
|
|
|
}
|
2009-01-19 03:33:15 +00:00
|
|
|
|
2009-10-29 07:16:28 +00:00
|
|
|
void RemoveLast(int cnt) {
|
2016-05-18 22:51:36 +00:00
|
|
|
ssassert(n >= cnt, "Removing more elements than the list contains");
|
2015-11-06 11:11:11 +00:00
|
|
|
for(int i = n - cnt; i < n; i++)
|
|
|
|
elem[i].~T();
|
2009-10-29 07:16:28 +00:00
|
|
|
n -= cnt;
|
|
|
|
// and elemsAllocated is untouched, same as in RemoveTagged
|
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Reverse() {
|
2009-01-19 03:33:15 +00:00
|
|
|
int i;
|
|
|
|
for(i = 0; i < (n/2); i++) {
|
2015-03-27 15:43:28 +00:00
|
|
|
swap(elem[i], elem[(n-1)-i]);
|
2009-01-19 03:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
2009-01-13 06:56:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// A list, where each element has an integer identifier. The list is kept
|
|
|
|
// sorted by that identifier, and items can be looked up in log n time by
|
|
|
|
// id.
|
2008-03-28 10:00:37 +00:00
|
|
|
template <class T, class H>
|
|
|
|
class IdList {
|
|
|
|
public:
|
2008-04-18 07:21:17 +00:00
|
|
|
T *elem;
|
2008-04-18 11:11:48 +00:00
|
|
|
int n;
|
2008-04-18 07:21:17 +00:00
|
|
|
int elemsAllocated;
|
2008-03-26 09:18:12 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
uint32_t MaximumId() {
|
2016-11-17 14:14:56 +00:00
|
|
|
if(n == 0) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return elem[n - 1].h.v;
|
2008-03-28 10:00:37 +00:00
|
|
|
}
|
2009-09-18 08:14:15 +00:00
|
|
|
}
|
2008-03-28 10:00:37 +00:00
|
|
|
|
2009-09-18 08:14:15 +00:00
|
|
|
H AddAndAssignId(T *t) {
|
|
|
|
t->h.v = (MaximumId() + 1);
|
2008-04-09 08:39:01 +00:00
|
|
|
Add(t);
|
2008-04-08 12:54:53 +00:00
|
|
|
|
2008-04-09 08:39:01 +00:00
|
|
|
return t->h;
|
2008-03-28 10:00:37 +00:00
|
|
|
}
|
|
|
|
|
2008-04-09 08:39:01 +00:00
|
|
|
void Add(T *t) {
|
2008-04-18 11:11:48 +00:00
|
|
|
if(n >= elemsAllocated) {
|
2008-03-28 10:00:37 +00:00
|
|
|
elemsAllocated = (elemsAllocated + 32)*2;
|
2015-11-06 11:11:11 +00:00
|
|
|
T *newElem = (T *)MemAlloc((size_t)elemsAllocated*sizeof(elem[0]));
|
|
|
|
for(int i = 0; i < n; i++) {
|
|
|
|
new(&newElem[i]) T(std::move(elem[i]));
|
|
|
|
elem[i].~T();
|
|
|
|
}
|
|
|
|
MemFree(elem);
|
|
|
|
elem = newElem;
|
2008-03-28 10:00:37 +00:00
|
|
|
}
|
|
|
|
|
2008-06-12 04:36:33 +00:00
|
|
|
int first = 0, last = n;
|
|
|
|
// We know that we must insert within the closed interval [first,last]
|
|
|
|
while(first != last) {
|
|
|
|
int mid = (first + last)/2;
|
|
|
|
H hm = elem[mid].h;
|
2016-05-18 22:51:36 +00:00
|
|
|
ssassert(hm.v != t->h.v, "Handle isn't unique");
|
2008-06-12 04:36:33 +00:00
|
|
|
if(hm.v > t->h.v) {
|
|
|
|
last = mid;
|
|
|
|
} else if(hm.v < t->h.v) {
|
|
|
|
first = mid + 1;
|
2008-06-06 07:50:08 +00:00
|
|
|
}
|
|
|
|
}
|
2008-06-12 04:36:33 +00:00
|
|
|
|
2015-11-06 11:11:11 +00:00
|
|
|
int i = first;
|
|
|
|
new(&elem[n]) T();
|
|
|
|
std::move_backward(elem + i, elem + n, elem + n + 1);
|
2008-06-06 07:50:08 +00:00
|
|
|
elem[i] = *t;
|
2008-04-18 11:11:48 +00:00
|
|
|
n++;
|
2008-03-28 10:00:37 +00:00
|
|
|
}
|
2008-06-12 04:36:33 +00:00
|
|
|
|
2008-04-08 12:54:53 +00:00
|
|
|
T *FindById(H h) {
|
2008-04-13 10:57:41 +00:00
|
|
|
T *t = FindByIdNoOops(h);
|
2016-05-18 22:51:36 +00:00
|
|
|
ssassert(t != NULL, "Cannot find handle");
|
2008-04-13 10:57:41 +00:00
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2016-01-27 08:19:40 +00:00
|
|
|
int IndexOf(H h) {
|
|
|
|
int first = 0, last = n-1;
|
|
|
|
while(first <= last) {
|
|
|
|
int mid = (first + last)/2;
|
|
|
|
H hm = elem[mid].h;
|
|
|
|
if(hm.v > h.v) {
|
|
|
|
last = mid-1; // and first stays the same
|
|
|
|
} else if(hm.v < h.v) {
|
|
|
|
first = mid+1; // and last stays the same
|
|
|
|
} else {
|
|
|
|
return mid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-04-13 10:57:41 +00:00
|
|
|
T *FindByIdNoOops(H h) {
|
2008-06-06 07:50:08 +00:00
|
|
|
int first = 0, last = n-1;
|
|
|
|
while(first <= last) {
|
|
|
|
int mid = (first + last)/2;
|
|
|
|
H hm = elem[mid].h;
|
|
|
|
if(hm.v > h.v) {
|
|
|
|
last = mid-1; // and first stays the same
|
|
|
|
} else if(hm.v < h.v) {
|
|
|
|
first = mid+1; // and last stays the same
|
|
|
|
} else {
|
|
|
|
return &(elem[mid]);
|
2008-04-08 12:54:53 +00:00
|
|
|
}
|
|
|
|
}
|
2008-04-13 10:57:41 +00:00
|
|
|
return NULL;
|
2008-04-08 12:54:53 +00:00
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
T *First() {
|
2009-01-19 10:37:10 +00:00
|
|
|
return (n == 0) ? NULL : &(elem[0]);
|
|
|
|
}
|
|
|
|
T *NextAfter(T *prev) {
|
|
|
|
if(!prev) return NULL;
|
|
|
|
if(prev - elem == (n - 1)) return NULL;
|
|
|
|
return prev + 1;
|
|
|
|
}
|
|
|
|
|
2016-05-29 14:14:38 +00:00
|
|
|
T *begin() { return &elem[0]; }
|
|
|
|
T *end() { return &elem[n]; }
|
|
|
|
const T *begin() const { return &elem[0]; }
|
|
|
|
const T *end() const { return &elem[n]; }
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void ClearTags() {
|
2008-04-08 12:54:53 +00:00
|
|
|
int i;
|
2008-04-18 11:11:48 +00:00
|
|
|
for(i = 0; i < n; i++) {
|
2008-04-08 12:54:53 +00:00
|
|
|
elem[i].tag = 0;
|
|
|
|
}
|
|
|
|
}
|
2008-03-28 10:00:37 +00:00
|
|
|
|
2008-04-14 10:28:32 +00:00
|
|
|
void Tag(H h, int tag) {
|
|
|
|
int i;
|
2008-04-18 11:11:48 +00:00
|
|
|
for(i = 0; i < n; i++) {
|
2008-04-18 07:21:17 +00:00
|
|
|
if(elem[i].h.v == h.v) {
|
2008-04-14 10:28:32 +00:00
|
|
|
elem[i].tag = tag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void RemoveTagged() {
|
2008-03-28 10:00:37 +00:00
|
|
|
int src, dest;
|
|
|
|
dest = 0;
|
2008-04-18 11:11:48 +00:00
|
|
|
for(src = 0; src < n; src++) {
|
2008-03-28 10:00:37 +00:00
|
|
|
if(elem[src].tag) {
|
|
|
|
// this item should be deleted
|
2016-11-08 16:28:16 +00:00
|
|
|
elem[src].Clear();
|
2008-03-28 10:00:37 +00:00
|
|
|
} else {
|
|
|
|
if(src != dest) {
|
|
|
|
elem[dest] = elem[src];
|
|
|
|
}
|
|
|
|
dest++;
|
|
|
|
}
|
|
|
|
}
|
2015-11-06 11:11:11 +00:00
|
|
|
for(int i = dest; i < n; i++)
|
|
|
|
elem[i].~T();
|
2008-04-18 11:11:48 +00:00
|
|
|
n = dest;
|
2008-04-08 12:54:53 +00:00
|
|
|
// and elemsAllocated is untouched, because we didn't resize
|
2008-03-28 10:00:37 +00:00
|
|
|
}
|
2008-05-17 06:04:55 +00:00
|
|
|
void RemoveById(H h) {
|
|
|
|
ClearTags();
|
|
|
|
FindById(h)->tag = 1;
|
|
|
|
RemoveTagged();
|
|
|
|
}
|
2008-03-28 10:00:37 +00:00
|
|
|
|
2008-04-13 10:57:41 +00:00
|
|
|
void MoveSelfInto(IdList<T,H> *l) {
|
2015-11-06 09:41:56 +00:00
|
|
|
l->Clear();
|
2015-11-06 11:11:11 +00:00
|
|
|
*l = *this;
|
2008-04-18 11:11:48 +00:00
|
|
|
elemsAllocated = n = 0;
|
2008-04-13 10:57:41 +00:00
|
|
|
elem = NULL;
|
|
|
|
}
|
|
|
|
|
2008-04-21 08:16:38 +00:00
|
|
|
void DeepCopyInto(IdList<T,H> *l) {
|
2015-11-06 09:41:56 +00:00
|
|
|
l->Clear();
|
2008-04-21 08:16:38 +00:00
|
|
|
l->elem = (T *)MemAlloc(elemsAllocated * sizeof(elem[0]));
|
2015-11-06 11:11:11 +00:00
|
|
|
for(int i = 0; i < n; i++)
|
|
|
|
new(&l->elem[i]) T(elem[i]);
|
2008-04-21 08:16:38 +00:00
|
|
|
l->elemsAllocated = elemsAllocated;
|
|
|
|
l->n = n;
|
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Clear() {
|
2013-09-19 04:33:12 +00:00
|
|
|
for(int i = 0; i < n; i++) {
|
|
|
|
elem[i].Clear();
|
2015-11-06 11:11:11 +00:00
|
|
|
elem[i].~T();
|
2013-09-19 04:33:12 +00:00
|
|
|
}
|
2008-04-18 11:11:48 +00:00
|
|
|
elemsAllocated = n = 0;
|
2008-05-07 04:17:29 +00:00
|
|
|
if(elem) MemFree(elem);
|
2008-04-12 16:28:48 +00:00
|
|
|
elem = NULL;
|
2008-03-28 10:00:37 +00:00
|
|
|
}
|
2008-03-26 09:18:12 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2009-10-21 04:46:01 +00:00
|
|
|
class BandedMatrix {
|
|
|
|
public:
|
2013-09-09 19:50:32 +00:00
|
|
|
enum {
|
|
|
|
MAX_UNKNOWNS = 16,
|
|
|
|
RIGHT_OF_DIAG = 1,
|
|
|
|
LEFT_OF_DIAG = 2
|
|
|
|
};
|
2009-10-21 04:46:01 +00:00
|
|
|
|
|
|
|
double A[MAX_UNKNOWNS][MAX_UNKNOWNS];
|
|
|
|
double B[MAX_UNKNOWNS];
|
|
|
|
double X[MAX_UNKNOWNS];
|
|
|
|
int n;
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Solve();
|
2009-10-21 04:46:01 +00:00
|
|
|
};
|
|
|
|
|
2015-07-10 11:54:39 +00:00
|
|
|
#define RGBi(r, g, b) RgbaColor::From((r), (g), (b))
|
|
|
|
#define RGBf(r, g, b) RgbaColor::FromFloat((float)(r), (float)(g), (float)(b))
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
|
2015-07-10 11:54:39 +00:00
|
|
|
// Note: sizeof(class RgbaColor) should be exactly 4
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
//
|
2015-07-10 11:54:39 +00:00
|
|
|
class RgbaColor {
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
public:
|
2015-03-26 10:30:12 +00:00
|
|
|
uint8_t red, green, blue, alpha;
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
float redF() const { return (float)red / 255.0f; }
|
|
|
|
float greenF() const { return (float)green / 255.0f; }
|
|
|
|
float blueF() const { return (float)blue / 255.0f; }
|
|
|
|
float alphaF() const { return (float)alpha / 255.0f; }
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +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
|
|
|
bool IsEmpty() const { return alpha == 0; }
|
|
|
|
|
2015-07-10 11:54:39 +00:00
|
|
|
bool Equals(RgbaColor c) const {
|
2015-03-26 10:30:12 +00:00
|
|
|
return
|
|
|
|
c.red == red &&
|
|
|
|
c.green == green &&
|
|
|
|
c.blue == blue &&
|
|
|
|
c.alpha == alpha;
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +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
|
|
|
RgbaColor WithAlpha(uint8_t newAlpha) const {
|
|
|
|
RgbaColor color = *this;
|
|
|
|
color.alpha = newAlpha;
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
uint32_t ToPackedIntBGRA() const {
|
2015-12-28 10:50:38 +00:00
|
|
|
return
|
|
|
|
blue |
|
|
|
|
(uint32_t)(green << 8) |
|
|
|
|
(uint32_t)(red << 16) |
|
|
|
|
(uint32_t)((255 - alpha) << 24);
|
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
uint32_t ToPackedInt() const {
|
2015-03-26 10:30:12 +00:00
|
|
|
return
|
|
|
|
red |
|
|
|
|
(uint32_t)(green << 8) |
|
|
|
|
(uint32_t)(blue << 16) |
|
|
|
|
(uint32_t)((255 - alpha) << 24);
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
uint32_t ToARGB32() const {
|
2015-08-31 19:33:57 +00:00
|
|
|
return
|
|
|
|
blue |
|
|
|
|
(uint32_t)(green << 8) |
|
|
|
|
(uint32_t)(red << 16) |
|
|
|
|
(uint32_t)(alpha << 24);
|
|
|
|
}
|
|
|
|
|
2015-07-10 11:54:39 +00:00
|
|
|
static RgbaColor From(int r, int g, int b, int a = 255) {
|
|
|
|
RgbaColor c;
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
c.red = (uint8_t)r;
|
|
|
|
c.green = (uint8_t)g;
|
|
|
|
c.blue = (uint8_t)b;
|
2015-03-26 10:30:12 +00:00
|
|
|
c.alpha = (uint8_t)a;
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2015-07-10 11:54:39 +00:00
|
|
|
static RgbaColor FromFloat(float r, float g, float b, float a = 1.0) {
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
return From(
|
|
|
|
(int)(255.1f * r),
|
|
|
|
(int)(255.1f * g),
|
2015-03-26 10:30:12 +00:00
|
|
|
(int)(255.1f * b),
|
|
|
|
(int)(255.1f * a));
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
}
|
|
|
|
|
2016-04-13 08:43:06 +00:00
|
|
|
static RgbaColor FromPackedInt(uint32_t rgba) {
|
|
|
|
return From(
|
|
|
|
(int)((rgba) & 0xff),
|
|
|
|
(int)((rgba >> 8) & 0xff),
|
|
|
|
(int)((rgba >> 16) & 0xff),
|
|
|
|
(int)(255 - ((rgba >> 24) & 0xff)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static RgbaColor FromPackedIntBGRA(uint32_t bgra) {
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
return From(
|
2015-03-26 10:30:12 +00:00
|
|
|
(int)((bgra >> 16) & 0xff),
|
2016-04-13 08:43:06 +00:00
|
|
|
(int)((bgra >> 8) & 0xff),
|
|
|
|
(int)((bgra) & 0xff),
|
2015-03-26 10:30:12 +00:00
|
|
|
(int)(255 - ((bgra >> 24) & 0xff)));
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
}
|
2016-07-04 06:02:30 +00:00
|
|
|
};
|
2016-04-13 08:43:06 +00:00
|
|
|
|
2016-07-04 06:02:30 +00:00
|
|
|
struct RgbaColorCompare {
|
|
|
|
bool operator()(RgbaColor a, RgbaColor b) const {
|
|
|
|
return a.ToARGB32() < b.ToARGB32();
|
|
|
|
}
|
Replaced RGB-color integers with dedicated data structure
RGB colors were represented using a uint32_t with the red, green and blue
values stuffed into the lower three octets (i.e. 0x00BBGGRR), like
Microsoft's COLORREF. This approach did not lend itself to type safety,
however, so this change replaces it with an RgbColor class that provides
the same infomation plus a handful of useful methods to work with it. (Note
that sizeof(RgbColor) == sizeof(uint32_t), so this change should not lead
to memory bloat.)
Some of the new methods/fields replace what were previously macro calls;
e.g. RED(c) is now c.red, REDf(c) is now c.redF(). The .Equals() method is
now used instead of == to compare colors.
RGB colors still need to be represented as packed integers in file I/O and
preferences, so the methods .FromPackedInt() and .ToPackedInt() are
provided. Also implemented are Cnf{Freeze,Thaw}Color(), type-safe wrappers
around Cnf{Freeze,Thaw}Int() that facilitate I/O with preferences.
(Cnf{Freeze,Thaw}Color() are defined outside of the system-dependent code
to minimize the footprint of the latter; because the same can be done with
Cnf{Freeze,Thaw}Bool(), those are also moved out of the system code with
this commit.)
Color integers were being OR'ed with 0x80000000 in some places for two
distinct purposes: One, to indicate use of a default color in
glxFillMesh(); this has been replaced by use of the .UseDefault() method.
Two, to indicate to TextWindow::Printf() that the format argument of a
"%Bp"/"%Fp" specifier is an RGB color rather than a color "code" from
TextWindow::bgColors[] or TextWindow::fgColors[] (as the specifier can
accept either); instead, we define a new flag "z" (as in "%Bz" or "%Fz") to
indicate an RGBcolor pointer, leaving "%Bp"/"%Fp" to indicate a color code
exclusively.
(This also allows TextWindow::meta[][].bg to be a char instead of an int,
partly compensating for the new .bgRgb field added immediately after.)
In array declarations, RGB colors could previously be specified as 0 (often
in a terminating element). As that no longer works, we define NULL_COLOR,
which serves much the same purpose for RgbColor variables as NULL serves
for pointers.
2013-10-16 20:00:58 +00:00
|
|
|
};
|
|
|
|
|
2016-01-23 08:05:02 +00:00
|
|
|
class BBox {
|
|
|
|
public:
|
|
|
|
Vector minp;
|
|
|
|
Vector maxp;
|
|
|
|
|
2016-02-18 09:53:31 +00:00
|
|
|
static BBox From(const Vector &p0, const Vector &p1);
|
2016-01-23 08:05:02 +00:00
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
Vector GetOrigin() const;
|
|
|
|
Vector GetExtents() const;
|
2016-01-23 08:05:02 +00:00
|
|
|
|
|
|
|
void Include(const Vector &v, double r = 0.0);
|
2016-05-21 05:18:00 +00:00
|
|
|
bool Overlaps(const BBox &b1) const;
|
2016-05-24 03:44:38 +00:00
|
|
|
bool Contains(const Point2d &p, double r = 0.0) const;
|
2016-01-23 08:05:02 +00:00
|
|
|
};
|
|
|
|
|
2008-03-25 10:02:13 +00:00
|
|
|
#endif
|