Allow selecting unit (px/mm) in Canvas::Stroke.
By directly specifying the desired end result to the renderer, we can avoid regeneration of geometry.
This commit is contained in:
parent
a5c7fc6ad9
commit
9f97e9aad4
@ -79,11 +79,9 @@ void Constraint::DoLabel(Canvas *canvas, Canvas::hStroke hcs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Constraint::DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *r) {
|
void Constraint::DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *r) {
|
||||||
const Camera &camera = canvas->GetCamera();
|
|
||||||
|
|
||||||
Canvas::Stroke strokeStippled = *canvas->strokes.FindById(hcs);
|
Canvas::Stroke strokeStippled = *canvas->strokes.FindById(hcs);
|
||||||
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH;
|
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH;
|
||||||
strokeStippled.stippleScale = 4.0 / camera.scale;
|
strokeStippled.stippleScale = 4.0;
|
||||||
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled);
|
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled);
|
||||||
|
|
||||||
Vector p = r->ProjectInto(workplane);
|
Vector p = r->ProjectInto(workplane);
|
||||||
@ -542,7 +540,7 @@ void Constraint::DoLayout(DrawAs how, Canvas *canvas,
|
|||||||
case Type::PROJ_PT_DISTANCE: {
|
case Type::PROJ_PT_DISTANCE: {
|
||||||
Canvas::Stroke strokeStippled = stroke;
|
Canvas::Stroke strokeStippled = stroke;
|
||||||
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH;
|
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH;
|
||||||
strokeStippled.stippleScale = 4.0 / camera.scale;
|
strokeStippled.stippleScale = 4.0;
|
||||||
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled);
|
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled);
|
||||||
|
|
||||||
Vector ap = SK.GetEntity(ptA)->PointGetNum(),
|
Vector ap = SK.GetEntity(ptA)->PointGetNum(),
|
||||||
|
@ -499,6 +499,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
|
|||||||
pointStroke.zIndex = IsPoint() ? zIndex + 1 : 0;
|
pointStroke.zIndex = IsPoint() ? zIndex + 1 : 0;
|
||||||
pointStroke.color = stroke.color;
|
pointStroke.color = stroke.color;
|
||||||
pointStroke.width = 7.0;
|
pointStroke.width = 7.0;
|
||||||
|
pointStroke.unit = Canvas::Unit::PX;
|
||||||
Canvas::hStroke hcsPoint = canvas->GetStroke(pointStroke);
|
Canvas::hStroke hcsPoint = canvas->GetStroke(pointStroke);
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
@ -555,7 +556,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
|
|||||||
if(!SK.GetGroup(group)->IsVisible() || !SS.GW.showNormals) continue;
|
if(!SK.GetGroup(group)->IsVisible() || !SS.GW.showNormals) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
stroke.layer = (asReference) ? Canvas::Layer::FRONT : Canvas::Layer::NORMAL;
|
stroke.layer = (asReference) ? Canvas::Layer::FRONT : Canvas::Layer::NORMAL;
|
||||||
if(how != DrawAs::HOVERED && how != DrawAs::SELECTED) {
|
if(how != DrawAs::HOVERED && how != DrawAs::SELECTED) {
|
||||||
// Always draw the x, y, and z axes in red, green, and blue;
|
// Always draw the x, y, and z axes in red, green, and blue;
|
||||||
// brighter for the ones at the bottom left of the screen,
|
// brighter for the ones at the bottom left of the screen,
|
||||||
@ -627,7 +628,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
|
|||||||
Canvas::Stroke strokeBorder = stroke;
|
Canvas::Stroke strokeBorder = stroke;
|
||||||
strokeBorder.zIndex -= 3;
|
strokeBorder.zIndex -= 3;
|
||||||
strokeBorder.stipplePattern = StipplePattern::SHORT_DASH;
|
strokeBorder.stipplePattern = StipplePattern::SHORT_DASH;
|
||||||
strokeBorder.stippleScale = 8.0 / camera.scale;
|
strokeBorder.stippleScale = 8.0;
|
||||||
Canvas::hStroke hcsBorder = canvas->GetStroke(strokeBorder);
|
Canvas::hStroke hcsBorder = canvas->GetStroke(strokeBorder);
|
||||||
|
|
||||||
double textHeight = Style::TextHeight(hs) / camera.scale;
|
double textHeight = Style::TextHeight(hs) / camera.scale;
|
||||||
|
@ -137,6 +137,50 @@ bool Canvas::Stroke::Equals(const Stroke &other) const {
|
|||||||
stippleScale == other.stippleScale);
|
stippleScale == other.stippleScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Canvas::Stroke::WidthMm(const Camera &camera) const {
|
||||||
|
switch(unit) {
|
||||||
|
case Canvas::Unit::MM:
|
||||||
|
return width;
|
||||||
|
case Canvas::Unit::PX:
|
||||||
|
return width / camera.scale;
|
||||||
|
default:
|
||||||
|
ssassert(false, "Unexpected unit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Canvas::Stroke::WidthPx(const Camera &camera) const {
|
||||||
|
switch(unit) {
|
||||||
|
case Canvas::Unit::MM:
|
||||||
|
return width * camera.scale;
|
||||||
|
case Canvas::Unit::PX:
|
||||||
|
return width;
|
||||||
|
default:
|
||||||
|
ssassert(false, "Unexpected unit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Canvas::Stroke::StippleScaleMm(const Camera &camera) const {
|
||||||
|
switch(unit) {
|
||||||
|
case Canvas::Unit::MM:
|
||||||
|
return stippleScale;
|
||||||
|
case Canvas::Unit::PX:
|
||||||
|
return stippleScale / camera.scale;
|
||||||
|
default:
|
||||||
|
ssassert(false, "Unexpected unit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Canvas::Stroke::StippleScalePx(const Camera &camera) const {
|
||||||
|
switch(unit) {
|
||||||
|
case Canvas::Unit::MM:
|
||||||
|
return stippleScale * camera.scale;
|
||||||
|
case Canvas::Unit::PX:
|
||||||
|
return stippleScale;
|
||||||
|
default:
|
||||||
|
ssassert(false, "Unexpected unit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Canvas::Fill::Equals(const Fill &other) const {
|
bool Canvas::Fill::Equals(const Fill &other) const {
|
||||||
return (layer == other.layer &&
|
return (layer == other.layer &&
|
||||||
zIndex == other.zIndex &&
|
zIndex == other.zIndex &&
|
||||||
|
@ -87,6 +87,12 @@ public:
|
|||||||
CONTOUR_ONLY // Contour outlines only
|
CONTOUR_ONLY // Contour outlines only
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Stroke widths, etc, can be scale-invariant (in pixels) or scale-dependent (in millimeters).
|
||||||
|
enum class Unit {
|
||||||
|
MM,
|
||||||
|
PX
|
||||||
|
};
|
||||||
|
|
||||||
class Stroke {
|
class Stroke {
|
||||||
public:
|
public:
|
||||||
hStroke h;
|
hStroke h;
|
||||||
@ -95,11 +101,17 @@ public:
|
|||||||
int zIndex;
|
int zIndex;
|
||||||
RgbaColor color;
|
RgbaColor color;
|
||||||
double width;
|
double width;
|
||||||
|
Unit unit;
|
||||||
StipplePattern stipplePattern;
|
StipplePattern stipplePattern;
|
||||||
double stippleScale;
|
double stippleScale;
|
||||||
|
|
||||||
void Clear() { *this = {}; }
|
void Clear() { *this = {}; }
|
||||||
bool Equals(const Stroke &other) const;
|
bool Equals(const Stroke &other) const;
|
||||||
|
|
||||||
|
double WidthMm(const Camera &camera) const;
|
||||||
|
double WidthPx(const Camera &camera) const;
|
||||||
|
double StippleScaleMm(const Camera &camera) const;
|
||||||
|
double StippleScalePx(const Camera &camera) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class FillPattern {
|
enum class FillPattern {
|
||||||
|
@ -43,8 +43,9 @@ void CairoRenderer::SelectStroke(hStroke hcs) {
|
|||||||
|
|
||||||
RgbaColor color = stroke->color;
|
RgbaColor color = stroke->color;
|
||||||
std::vector<double> dashes =
|
std::vector<double> dashes =
|
||||||
StipplePatternDashes(stroke->stipplePattern, stroke->stippleScale * camera.scale);
|
StipplePatternDashes(stroke->stipplePattern,
|
||||||
cairo_set_line_width(context, stroke->width);
|
stroke->StippleScalePx(camera));
|
||||||
|
cairo_set_line_width(context, stroke->WidthPx(camera));
|
||||||
cairo_set_dash(context, dashes.data(), dashes.size(), 0);
|
cairo_set_dash(context, dashes.data(), dashes.size(), 0);
|
||||||
cairo_set_source_rgba(context, color.redF(), color.greenF(), color.blueF(),
|
cairo_set_source_rgba(context, color.redF(), color.greenF(), color.blueF(),
|
||||||
color.alphaF());
|
color.alphaF());
|
||||||
|
@ -191,7 +191,7 @@ Canvas::Stroke *OpenGl1Renderer::SelectStroke(hStroke hcs) {
|
|||||||
UnSelectPrimitive();
|
UnSelectPrimitive();
|
||||||
ssglColorRGBA(stroke->color);
|
ssglColorRGBA(stroke->color);
|
||||||
ssglDepthRange(stroke->layer, stroke->zIndex);
|
ssglDepthRange(stroke->layer, stroke->zIndex);
|
||||||
ssglLineWidth(stroke->width);
|
ssglLineWidth(stroke->WidthPx(camera));
|
||||||
// Fat lines and points are quads affected by glPolygonStipple, so make sure
|
// Fat lines and points are quads affected by glPolygonStipple, so make sure
|
||||||
// they are displayed correctly.
|
// they are displayed correctly.
|
||||||
ssglFillPattern(FillPattern::SOLID);
|
ssglFillPattern(FillPattern::SOLID);
|
||||||
@ -329,12 +329,12 @@ void OpenGl1Renderer::DoLine(const Vector &a, const Vector &b, hStroke hcs) {
|
|||||||
if(a.Equals(b)) return;
|
if(a.Equals(b)) return;
|
||||||
|
|
||||||
Stroke *stroke = SelectStroke(hcs);
|
Stroke *stroke = SelectStroke(hcs);
|
||||||
if(stroke->width <= 3.0) {
|
if(stroke->WidthPx(camera) <= 3.0) {
|
||||||
SelectPrimitive(GL_LINES);
|
SelectPrimitive(GL_LINES);
|
||||||
ssglVertex3v(a);
|
ssglVertex3v(a);
|
||||||
ssglVertex3v(b);
|
ssglVertex3v(b);
|
||||||
} else {
|
} else {
|
||||||
DoFatLine(a, b, stroke->width / camera.scale);
|
DoFatLine(a, b, stroke->WidthPx(camera) / camera.scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ void OpenGl1Renderer::DoStippledLine(const Vector &a, const Vector &b, hStroke h
|
|||||||
|
|
||||||
const char *si = patternSeq;
|
const char *si = patternSeq;
|
||||||
double end = len;
|
double end = len;
|
||||||
double ss = stroke->stippleScale / 2.0;
|
double ss = stroke->StippleScaleMm(camera) / 2.0;
|
||||||
do {
|
do {
|
||||||
double start = end;
|
double start = end;
|
||||||
switch(*si) {
|
switch(*si) {
|
||||||
@ -400,7 +400,7 @@ void OpenGl1Renderer::DoStippledLine(const Vector &a, const Vector &b, hStroke h
|
|||||||
case '.':
|
case '.':
|
||||||
end = max(end - 0.5 * ss, 0.0);
|
end = max(end - 0.5 * ss, 0.0);
|
||||||
if(end == 0.0) break;
|
if(end == 0.0) break;
|
||||||
DoPoint(a.Plus(dir.ScaledBy(end)), stroke->width);
|
DoPoint(a.Plus(dir.ScaledBy(end)), stroke->WidthPx(camera));
|
||||||
end = max(end - 0.5 * ss, 0.0);
|
end = max(end - 0.5 * ss, 0.0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -291,6 +291,14 @@ Canvas::Stroke Style::Stroke(hStyle hs) {
|
|||||||
stroke.stipplePattern = style->stippleType;
|
stroke.stipplePattern = style->stippleType;
|
||||||
stroke.stippleScale = Style::StippleScaleMm(hs);
|
stroke.stippleScale = Style::StippleScaleMm(hs);
|
||||||
stroke.width = Style::Width(hs.v);
|
stroke.width = Style::Width(hs.v);
|
||||||
|
switch(style->widthAs) {
|
||||||
|
case Style::UnitsAs::PIXELS:
|
||||||
|
stroke.unit = Canvas::Unit::PX;
|
||||||
|
break;
|
||||||
|
case Style::UnitsAs::MM:
|
||||||
|
stroke.unit = Canvas::Unit::MM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
return stroke;
|
return stroke;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user