Skip to content

Commit f6a15ec

Browse files
committed
Marcelshapes for the artwork
1 parent 58b8de8 commit f6a15ec

8 files changed

Lines changed: 309 additions & 23 deletions

File tree

DirtyPCBs/DirtyPCB_BoardRender/DirtyPCB_BoardRender.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ enum Arguments
2121
Copper,
2222
SkipFix,
2323
None,
24-
TimeOut
24+
TimeOut,
25+
TraceColor
2526
}
2627

2728
public class BoardRenderSettings
@@ -34,6 +35,8 @@ public class BoardRenderSettings
3435
public string OutputFolder { get; internal set; }
3536
public int TimeOut = -1;
3637
public bool TimeOutExpired = false;
38+
public Color TraceColor;
39+
public bool HasTraceColor = false;
3740
}
3841
public static BoardRenderSettings TheSettings = new BoardRenderSettings();
3942

@@ -49,11 +52,14 @@ static void Main(string[] args)
4952
Console.WriteLine("Usage:");
5053
Console.WriteLine("DirtyPCB_BoardRender.exe [--soldermask_color {blue,yellow,green,black,white,red}]");
5154
Console.WriteLine("\t[--silkscreen_color {white, black}]");
55+
Console.WriteLine("\t[--trace_color {blue,yellow,green,black,white,red}]");
5256
Console.WriteLine("\t[--copper_color {silver, gold}]");
5357
Console.WriteLine("\t[--timeout {seconds}]");
5458
Console.WriteLine("\t[--skipeaglefix]");
5559
Console.WriteLine("\tinput_path");
5660
Console.WriteLine("\toutput_directory");
61+
Console.WriteLine("");
62+
Console.WriteLine("\tHTML colors in the form of #rrggbb are also supported");
5763

5864
return;
5965
}
@@ -66,6 +72,7 @@ static void Main(string[] args)
6672
case Arguments.SilkScreen: TheSettings.SilkScreenColor = GerberLibrary.Gerber.ParseColor(args[i]); NextArg = Arguments.None; break;
6773
case Arguments.Copper: TheSettings.CopperColor = GerberLibrary.Gerber.ParseColor(args[i]); NextArg = Arguments.None; break;
6874
case Arguments.SolderMask: TheSettings.SolderMaskColor = GerberLibrary.Gerber.ParseColor(args[i]); NextArg = Arguments.None; break;
75+
case Arguments.TraceColor: TheSettings.TraceColor = GerberLibrary.Gerber.ParseColor(args[i]); NextArg = Arguments.None; TheSettings.HasTraceColor = true; break;
6976
case Arguments.TimeOut: TheSettings.TimeOut = int.Parse(args[i]); NextArg = Arguments.None; break;
7077

7178
case Arguments.None:
@@ -74,6 +81,7 @@ static void Main(string[] args)
7481
case "--silkscreen_color": NextArg = Arguments.SilkScreen; break;
7582
case "--copper_color": NextArg = Arguments.Copper; break;
7683
case "--soldermask_color": NextArg = Arguments.SolderMask; break;
84+
case "--trace_color": NextArg = Arguments.TraceColor; break;
7785
case "--timeout": NextArg = Arguments.TimeOut; break;
7886
case "--skipeaglefix": NextArg = Arguments.None; Gerber.SkipEagleDrillFix = true; break;
7987
}
@@ -130,6 +138,7 @@ private static void RunImageGeneration()
130138
BoardRenderColorSet Colors = new BoardRenderColorSet();
131139
Colors.BoardRenderColor = TheSettings.SolderMaskColor;
132140
Colors.BoardRenderTraceColor = TheSettings.SolderMaskColor;
141+
if (TheSettings.HasTraceColor) Colors.BoardRenderTraceColor = TheSettings.TraceColor;
133142

134143
Colors.BoardRenderSilkColor = TheSettings.SilkScreenColor;
135144
Colors.BoardRenderPadColor = TheSettings.CopperColor;

GerberLibrary/Artwork Related/SVGWriter.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public void DrawLine(Pen P, PointF p1, PointF p2)
146146

147147
}
148148

149-
public void DrawPolyline(Pen p, List<PointF> TheList, bool closed = false, bool clipagainstboundary = false)
149+
public void DrawPolyline(Pen p, List<PointF> TheList, bool closed = false, bool clipagainstboundary = false, float strokewidth = -1)
150150
{
151151
string commands = "";
152152

@@ -158,7 +158,8 @@ public void DrawPolyline(Pen p, List<PointF> TheList, bool closed = false, bool
158158
scaletrns[0].Y -= CurrentTransform.Elements[5];
159159

160160

161-
double stroke = Math.Sqrt(scaletrns[0].X * scaletrns[0].X + scaletrns[0].Y* scaletrns[0].Y);
161+
double stroke = strokewidth;
162+
if (stroke<=-1) stroke = Math.Sqrt(scaletrns[0].X * scaletrns[0].X + scaletrns[0].Y* scaletrns[0].Y);
162163
var list = TheList.ToArray();
163164
CurrentTransform.TransformPoints(list);
164165
if (clipagainstboundary)

GerberLibrary/GerberLibrary.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<DefineConstants>DEBUG;TRACE</DefineConstants>
2121
<ErrorReport>prompt</ErrorReport>
2222
<WarningLevel>4</WarningLevel>
23-
<UseVSHostingProcess>true</UseVSHostingProcess>
23+
<UseVSHostingProcess>false</UseVSHostingProcess>
2424
</PropertyGroup>
2525
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
2626
<DebugType>pdbonly</DebugType>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
using ClipperLib;
8+
9+
10+
namespace ArtWork
11+
{
12+
using Path = List<ClipperLib.IntPoint>;
13+
using Paths = List<List<ClipperLib.IntPoint>>;
14+
15+
public class MarcelShape
16+
{
17+
public List<ClipperLib.IntPoint> Vertices = new List<ClipperLib.IntPoint>();
18+
19+
public void ShrinkFromShape(Path shape, float amt=7*3)
20+
{
21+
Path pp = new Path();
22+
pp.AddRange(shape);
23+
Paths pps = new Paths();
24+
pps.Add(pp);
25+
var Res = Clipper.OffsetPolygons(pps, -amt);
26+
27+
if (Res.Count == 1)
28+
{
29+
Vertices.Clear();
30+
Vertices.AddRange(Res[0]);
31+
}
32+
}
33+
34+
public Paths BuildOutlines(float growamt = 5*3)
35+
{
36+
37+
ClipperLib.Clipper cp = new ClipperLib.Clipper();
38+
Path pp = new Path();
39+
pp.AddRange(Vertices);
40+
Paths pps = new Paths();
41+
pps.Add(pp);
42+
var Res = Clipper.OffsetPolygons(pps, growamt, JoinType.jtRound);
43+
44+
45+
return Res;
46+
}
47+
48+
public Paths BuildHoles(float radius = 3*3.0f/2.0f)
49+
{
50+
Paths pps = new Paths();
51+
foreach(var v in Vertices)
52+
{
53+
Path c = new Path();
54+
for(int i =0;i<20;i++)
55+
{
56+
double P = (i * Math.PI * 2) / 20;
57+
double x = Math.Cos(P) * radius + v.X;
58+
double y = Math.Sin(P) * radius + v.Y;
59+
60+
c.Add(new IntPoint((long)x, (long)y));
61+
}
62+
63+
pps.Add(c);
64+
}
65+
66+
return pps;
67+
}
68+
}
69+
}

Project_Utilities/TilingLibrary/TINRS-ArtWork.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<PlatformTarget>AnyCPU</PlatformTarget>
2525
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
2626
<Prefer32Bit>false</Prefer32Bit>
27-
<UseVSHostingProcess>true</UseVSHostingProcess>
27+
<UseVSHostingProcess>false</UseVSHostingProcess>
2828
</PropertyGroup>
2929
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
3030
<DebugType>pdbonly</DebugType>
@@ -57,6 +57,7 @@
5757
<ItemGroup>
5858
<Compile Include="Announcer.cs" />
5959
<Compile Include="DelaunayBuilder.cs" />
60+
<Compile Include="MarcelShape.cs" />
6061
<Compile Include="Properties\AssemblyInfo.cs" />
6162
<Compile Include="QuadTree.cs" />
6263
<Compile Include="Tiling.cs" />

Project_Utilities/TilingLibrary/TINRSArtWorkRenderer.cs

Lines changed: 128 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using GerberLibrary.Core;
1+
using ArtWork;
2+
using GerberLibrary.Core;
3+
using GlmNet;
24
using System;
35
using System.Collections.Generic;
46
using System.Drawing;
@@ -10,6 +12,9 @@
1012

1113
namespace Artwork
1214
{
15+
using Path = List<ClipperLib.IntPoint>;
16+
using Paths = List<List<ClipperLib.IntPoint>>;
17+
1318
public class SolidQuadTreeItem : QuadTreeItem
1419
{
1520
int _x;
@@ -345,17 +350,16 @@ public void DrawTiling(Settings S, Bitmap MaskBitmap, Graphics G, Color FGColor,
345350
if (S.Mode == Settings.ArtMode.Tiling)
346351
{
347352
if (Clear) G.Clear(BG);
348-
PointF[] ThePoints = new PointF[3] { new PointF(), new PointF(), new PointF() };
349353
Pen P = new Pen(FG, linewidth);
350354
for (int j = 0; j < SubDivPoly.Count; j++)
351355
{
352356
var a = SubDivPoly[j];
353-
for (int i = 0; i < 3; i++)
357+
PointF[] ThePoints = new PointF[a.Vertices.Count];
358+
for (int i = 0; i < a.Vertices.Count; i++)
354359
{
355-
ThePoints[i].X = (float)a.Vertices[i].x;
356-
ThePoints[i].Y = (float)a.Vertices[i].y;
360+
ThePoints[i] = new PointF((float)a.Vertices[i].x,(float)a.Vertices[i].y);
357361
}
358-
G.DrawPolygon(P, ThePoints);
362+
G.DrawPolygon(P, ThePoints);
359363
}
360364
}
361365
}
@@ -521,7 +525,7 @@ public int BuildStuff(Bitmap Mask, Settings TheSettings)
521525
}
522526
}
523527
}
524-
528+
525529
Delaunay.Build(ArtTree, TheSettings.DegreesOff);
526530

527531
var Elapsed = DateTime.Now - rR;
@@ -565,7 +569,7 @@ public int BuildStuff(Bitmap Mask, Settings TheSettings)
565569
foreach (var A in SubDivPoly)
566570
{
567571
var M = A.Mid();
568-
float scaler = 1.0f - ((float)(M.x-offs) / width) * TheSettings.xscalesmallerlevel * 0.01f;
572+
float scaler = 1.0f - ((float)(M.x - offs) / width) * TheSettings.xscalesmallerlevel * 0.01f;
569573
//scaler = Math.Max(0, Math.Min(1.0f, scaler));
570574
A.ScaleDown(TheSettings.scalingMode, scaler);
571575
}
@@ -591,18 +595,80 @@ public int BuildStuff(Bitmap Mask, Settings TheSettings)
591595
}
592596
foreach (var A in SubDivPoly)
593597
{
594-
598+
595599
if (A.depth - TheSettings.scalesmallerlevel <= 1)
596600
{
597601

598602
}
599603
else
600604
{
601605
A.ScaleDown(TheSettings.scalingMode, (1 + scaler * (1.0f / (A.depth - TheSettings.scalesmallerlevel))));
602-
606+
603607
}
604608
}
605609
}
610+
if (TheSettings.distanceToMaskScale != 0)
611+
{
612+
float scaler = Math.Abs(TheSettings.distanceToMaskScale);
613+
if (TheSettings.distanceToMaskScale > 0)
614+
{
615+
scaler = scaler / 10.0f;
616+
}
617+
else
618+
{
619+
scaler = -scaler / 10.0f;
620+
}
621+
622+
623+
float aThresholdLevel = TheSettings.Threshold * 0.01f;
624+
625+
foreach (var A in SubDivPoly)
626+
{
627+
628+
var m = A.Mid();
629+
float sum = GetPixelSum(m, Mask, TheSettings.distanceToMaskRange, aThresholdLevel, TheSettings.InvertSource);
630+
//if (sum > 1) sum = 1;
631+
A.ScaleDown(TheSettings.scalingMode, (scaler * sum));
632+
633+
634+
}
635+
}
636+
637+
638+
if (TheSettings.MarcelPlating)
639+
{
640+
List<Tiling.Polygon> MarcelShapes = new List<Tiling.Polygon>();
641+
foreach (var A in SubDivPoly)
642+
{
643+
644+
645+
MarcelShape MS = new MarcelShape();
646+
MarcelShape MS2 = new MarcelShape();
647+
648+
foreach (var v in A.Vertices)
649+
{
650+
MS2.Vertices.Add(new ClipperLib.IntPoint((long)((v.x+1000)*1000), (long)((v.y+1000)*1000)));
651+
}
652+
653+
MS.ShrinkFromShape(MS2.Vertices, TheSettings.Gap /2 + TheSettings.Rounding/2 );
654+
Paths Ps = new Paths();
655+
656+
Ps.AddRange(MS.BuildOutlines(TheSettings.Rounding / 2.0f));
657+
if (TheSettings.BallRadius > 0) Ps.AddRange(MS.BuildHoles(TheSettings.BallRadius));
658+
659+
foreach(var p in Ps)
660+
{
661+
Tiling.Polygon Poly = new Tiling.Polygon();
662+
Poly.Vertices.AddRange(from a in p select new vec2((a.X) * 0.001f-1000, (a.Y ) * 0.001f-1000));
663+
MarcelShapes.Add(Poly);
664+
}
665+
666+
667+
}
668+
SubDivPoly.Clear();
669+
SubDivPoly = MarcelShapes;
670+
}
671+
606672
var Elapsed = DateTime.Now - rR;
607673
return (int)Elapsed.TotalMilliseconds;
608674
}
@@ -611,6 +677,58 @@ public int BuildStuff(Bitmap Mask, Settings TheSettings)
611677
return 0;
612678
}
613679

680+
681+
682+
private float GetPixelSum(vec2 m, Bitmap mask, float distanceToMaskRange, float ThresholdLevel, bool invert)
683+
{
684+
float sum = 0;
685+
if (distanceToMaskRange == 0) distanceToMaskRange = 0.001f;
686+
float wrange = distanceToMaskRange * mask.Width * 0.5f;
687+
float hrange = distanceToMaskRange * mask.Width * 0.5f;
688+
float total = 0;
689+
float[] cp = new float[40];
690+
float[] sp = new float[40];
691+
for (int p = 0; p < 40; p++)
692+
693+
{
694+
double P = (p * Math.PI * 2) / 40.0f;
695+
sp[p] = (float)Math.Sin(P) * wrange;
696+
cp[p] = (float)Math.Cos(P) * wrange ;
697+
}
698+
699+
for (int ring = 1;ring<10;ring++)
700+
{
701+
float RW = ring / 10.0f;
702+
for (int p = 0; p < 40; p++)
703+
704+
{
705+
int x = (int)(cp[p] * RW + m.x);
706+
int y = (int)(sp[p] * RW + m.y);
707+
total++;
708+
if (x >= 0 && x < mask.Width)
709+
{
710+
if (y >= 0 && y < mask.Height)
711+
{
712+
var C = mask.GetPixel(x, y);
713+
bool doit = false;
714+
if (invert)
715+
{
716+
doit = C.GetBrightness() > ThresholdLevel;
717+
}
718+
else
719+
{
720+
doit = C.GetBrightness() < ThresholdLevel;
721+
}
722+
if (doit) sum++;
723+
724+
}
725+
}
726+
}
727+
728+
}
729+
730+
return 1000*sum / total;
731+
}
614732
}
615733

616734
}

0 commit comments

Comments
 (0)