SPH
RenderContext.cpp
Go to the documentation of this file.
2 
4 
5 template <typename PixelOp>
7  if (flags.has(ColorFlag::LINE)) {
8  colors.line = color;
9  }
10  if (flags.has(ColorFlag::FILL)) {
11  colors.fill = color;
12  }
13  if (flags.has(ColorFlag::TEXT)) {
14  colors.text = color;
15  }
16  // SPH_ASSERT(colors.line.alpha() == 1.f);
17 }
18 
19 template <typename PixelOp>
20 void PreviewRenderContext<PixelOp>::setThickness(const float newThickness) {
21  thickness = newThickness;
22 }
23 
24 template <typename PixelOp>
25 void PreviewRenderContext<PixelOp>::setFontSize(const int newFontSize) {
26  fontSize = newFontSize;
27 }
28 
29 template <typename PixelOp>
30 void PreviewRenderContext<PixelOp>::fill(const Rgba& color) {
31  bitmap.fill(color);
32 }
33 
34 template <typename PixelOp>
36  if (abs(p2.x - p1.x) > abs(p2.y - p1.y)) {
37  if (p1.x > p2.x) {
38  std::swap(p1, p2);
39  }
40  const int x1 = int(floor(p1.x));
41  const int x2 = int(ceil(p2.x));
42  const float y1 = p1.y;
43  const float y2 = p2.y;
44  for (int x = x1; x <= x2; ++x) {
45  int y = int(y1 + (x - x1) * (y2 - y1) / (x2 - x1));
46  drawSafe(Pixel(x, y), colors.line);
47  }
48  } else {
49  if (p1.y > p2.y) {
50  std::swap(p1, p2);
51  }
52  const int y1 = int(floor(p1.y));
53  const int y2 = int(ceil(p2.y));
54  const float x1 = p1.x;
55  const float x2 = p2.x;
56  for (int y = y1; y <= y2; ++y) {
57  int x = int(x1 + (y - y1) * (x2 - x1) / (y2 - y1));
58  drawSafe(Pixel(x, y), colors.line);
59  }
60  }
61 }
62 
63 template <typename PixelOp>
64 void PreviewRenderContext<PixelOp>::drawCircle(const Coords center, const float radius) {
65  if (center.x < -radius || center.x > bitmap.size().x + radius || center.y < -radius ||
66  center.y > bitmap.size().y + radius) {
67  return;
68  }
69  const Pixel p(center);
70  const int intRadius = min(int(radius), bitmap.size().x);
71  if (p.x >= intRadius && p.x < bitmap.size().x - intRadius - 1 && p.y >= intRadius &&
72  p.y < bitmap.size().y - intRadius - 1) {
73  // can draw without checking
74  for (int y = -intRadius; y <= intRadius; ++y) {
75  for (int x = -intRadius; x <= intRadius; ++x) {
76  const int rSqr = sqr(x) + sqr(y);
77  if (rSqr <= sqr(radius - 1)) {
78  draw(p + Pixel(x, y), colors.fill);
79  } else if (rSqr <= sqr(radius)) {
80  draw(p + Pixel(x, y), colors.line);
81  }
82  }
83  }
84  } else {
85  for (int y = -intRadius; y <= intRadius; ++y) {
86  for (int x = -intRadius; x <= intRadius; ++x) {
87  const int rSqr = sqr(x) + sqr(y);
88  if (rSqr <= sqr(radius - 1)) {
89  drawSafe(p + Pixel(x, y), colors.fill);
90  } else if (rSqr <= sqr(radius)) {
91  drawSafe(p + Pixel(x, y), colors.line);
92  }
93  }
94  }
95  }
96 }
97 
98 template <typename PixelOp>
100  // http://www-users.mat.uni.torun.pl/~wrona/3d_tutor/tri_fillers.html
101 
102  StaticArray<Coords, 3> p{ p1, p2, p3 };
103  std::sort(p.begin(), p.end(), [](Coords p1, Coords p2) { return p1.y < p2.y; });
104  SPH_ASSERT(p[0].y <= p[1].y && p[1].y <= p[2].y); // sanity check
105  Coords a = p[0];
106  Coords b = p[1];
107  Coords c = p[2];
108  a.y--;
109  c.y++;
110 
111  auto getDx = [](const Coords p1, const Coords p2) {
112  if (p2.y - p1.y > 0) {
113  return float(p2.x - p1.x) / (p2.y - p1.y);
114  } else {
115  return 0.f;
116  }
117  };
118  const float dx1 = getDx(a, b);
119  const float dx2 = getDx(a, c);
120  const float dx3 = getDx(b, c);
121 
122  auto doLine = [this](float x1, float x2, float y) {
123  if (x1 > x2) {
124  std::swap(x1, x2);
125  }
126  for (int x = int(floor(x1)); x <= int(ceil(x2)); ++x) {
127  drawSafe(Pixel(x, int(y)), colors.fill);
128  }
129  };
130 
131  Coords s = a, e = a;
132  for (; s.y <= b.y; s.y++, e.y++, s.x += dx2, e.x += dx1) {
133  doLine(s.x, e.x, s.y);
134  }
135  e = b;
136  for (; s.y <= c.y; s.y++, e.y++, s.x += dx2, e.x += dx3) {
137  doLine(s.x, e.x, s.y);
138  }
139 }
140 
141 template <typename PixelOp>
143  for (int y = 0; y < subBitmap.size().y; ++y) {
144  for (int x = 0; x < subBitmap.size().x; ++x) {
145  drawSafe(Pixel(x, y) + Pixel(p), subBitmap[Pixel(x, y)]);
146  }
147  }
148 }
149 
150 template <typename PixelOp>
152  const Flags<TextAlign> align,
153  const std::string& s) {
154  std::wstring ws(s.begin(), s.end());
155  this->drawText(p, align, ws);
156 }
157 
158 template <typename PixelOp>
160  const Flags<TextAlign> align,
161  const std::wstring& s) {
162  labels.push(IRenderOutput::Label{ s, colors.text, fontSize, align, Pixel(p) });
163 }
164 
166 template class PreviewRenderContext<OverPixelOp>;
167 
168 void AntiAliasedRenderContext::drawCircle(const Coords center, const float radius) {
169  if (center.x < -radius || center.x > bitmap.size().x + radius || center.y < -radius ||
170  center.y > bitmap.size().y + radius) {
171  return;
172  }
173  const Pixel p(center);
174  if (radius <= 1.f) {
175  Rgba color = colors.fill;
176  color.a() = sqr(radius);
177  drawSafe(p, color);
178  } else {
179  const int r = int(std::ceil(radius)) + 1;
180  for (int y = p.y - r; y <= p.y + r; ++y) {
181  for (int x = p.x - r; x <= p.x + r; ++x) {
182  const float distSqr = sqr(x - center.x) + sqr(y - center.y);
183  Rgba color = colors.fill;
184  color.a() = clamp(radius - sqrt(distSqr), 0.f, 1.f);
185  drawSafe(Pixel(x, y), color);
186  }
187  }
188  }
189 }
190 
191 void SmoothedRenderContext::drawCircle(const Coords center, const float radius) {
192  if (center.x < -radius || center.x > bitmap.size().x + radius || center.y < -radius ||
193  center.y > bitmap.size().y + radius) {
194  return;
195  }
196  const Pixel p(center);
197  const float maxRadius = radius * float(kernel.radius());
198  const float normalization = 1.f / float(kernel.valueImpl(0)); // sqr(25.f / particleScale);
199  const int r = int(std::ceil(maxRadius)) + 1;
200  for (int y = p.y - r; y <= p.y + r; ++y) {
201  for (int x = p.x - r; x <= p.x + r; ++x) {
202  const float distSqr = sqr(x - center.x) + sqr(y - center.y);
203  if (distSqr <= sqr(maxRadius + 1)) {
204  Rgba color = colors.fill;
205 
206  const float alpha = float(kernel.valueImpl(distSqr / sqr(radius))) * normalization;
207  color.a() = clamp(alpha, 0.f, 1.f);
208  drawSafe(Pixel(x, y), color);
209  }
210  }
211  }
212 }
213 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
const float radius
Definition: CurveDialog.cpp:18
constexpr INLINE T clamp(const T &f, const T &f1, const T &f2)
Definition: MathBasic.h:35
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
Definition: MathBasic.h:15
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE auto floor(const T &f)
Definition: MathUtils.h:346
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
INLINE auto ceil(const T &f)
Definition: MathUtils.h:351
INLINE auto abs(const T &f)
Definition: MathUtils.h:276
#define NAMESPACE_SPH_END
Definition: Object.h:12
void drawSafe(const Pixel p, const Rgba c)
virtual void drawCircle(const Coords center, const float radius) override
Draws a circle, given its center and a radius.
Pixel size() const
Definition: Bitmap.h:72
Wrapper of an integral value providing functions for reading and modifying individual bits.
Definition: Flags.h:20
constexpr INLINE bool has(const TEnum flag) const
Checks if the object has a given flag.
Definition: Flags.h:77
INLINE Float valueImpl(const Float qSqr) const noexcept
Definition: Kernel.h:111
INLINE Float radius() const noexcept
Definition: Kernel.h:107
virtual void drawCircle(const Coords center, const float radius) override
Draws a circle, given its center and a radius.
virtual void setColor(const Rgba &color, const Flags< ColorFlag > flags) override
Selects the color for one or more drawing modes.
virtual void setThickness(const float newThickness) override
Modifies the thickness of the lines.
virtual void drawTriangle(const Coords p1, const Coords p2, const Coords p3) override
Draws a triangle given three points.
virtual void drawBitmap(const Coords p, const Bitmap< Rgba > &subBitmap) override
Draws a bitmap, given the position of its left-top corner.
virtual void drawText(const Coords p, const Flags< TextAlign > align, const std::string &s) override
virtual void setFontSize(const int newFontSize) override
struct PreviewRenderContext::@28 colors
virtual void drawLine(const Coords p1, const Coords p2) override
Draws a line connecting two points.
Definition: Color.h:8
float & a()
Definition: Color.h:63
virtual void drawCircle(const Coords center, const float radius) override
Draws a circle, given its center and a radius.
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
void swap(Sph::Array< T, TCounter > &ar1, Sph::Array< T, TCounter > &ar2)
Definition: Array.h:580
Definition: Point.h:115
std::wstring text
Definition: IRenderer.h:41
Definition: Point.h:101