-
I need to create a Hatch entity with predefined pattern, saying, the "ANSI34" pattern. var doc = new CadDocument();
var hatch = new Hatch();
var pline = new Hatch.BoundaryPath.Polyline();
pline.Vertices.Add(new XYZ(0, 0, 0));
pline.Vertices.Add(new XYZ(10, 0, 0));
pline.Vertices.Add(new XYZ(10, 10, 0));
pline.Vertices.Add(new XYZ(0, 10, 0));
pline.Vertices.Add(new XYZ(0, 0, 0));
var path = new Hatch.BoundaryPath();
path.Edges.Add(pline);
path.Flags |= BoundaryPathFlags.Polyline;
hatch.Paths.Add(path);
// Define hatch pattern
hatch.PatternType = HatchPatternType.SolidFill;
var pattern = new HatchPattern("ANSI34") { Scale = 0.2 };
hatch.Pattern = pattern;
doc.Entities.Add(hatch);
const string filePath = @"D:\TestHatch02.dwg";
using var writer = new DwgWriter(filePath, doc);
writer.OnNotification += NotificationHelper.LogConsoleNotification;
writer.Write(); The output DWG file contain a Hatch object with desired size, but it is invisible and has no visible fill pattern. Here is the screen shot |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
Through some research and analysis, I found a solution. public static void TestCreatePredefinedHatch()
{
var doc = new CadDocument();
var hatch = new Hatch();
var pline = new Hatch.BoundaryPath.Polyline();
pline.Vertices.Add(new XYZ(0, 0, 0));
pline.Vertices.Add(new XYZ(20, 0, 0));
pline.Vertices.Add(new XYZ(20, 10, 0));
pline.Vertices.Add(new XYZ(0, 10, 0));
pline.Vertices.Add(new XYZ(0, 0, 0));
var path = new Hatch.BoundaryPath();
path.Edges.Add(pline);
path.Flags |= BoundaryPathFlags.Polyline;
hatch.Paths.Add(path);
//
const string patFilePath = @"D:\acadiso.pat";
var hatchPatternDict = HatchPatternInfo.LoadHatchPatternInfo(patFilePath)
.ToDictionary(info => info.Name, info => info.HatchPatternLines);
var hatchPatternName = "AR-CONC"; // Predefined hatch pattern name
Debug.Assert(hatchPatternDict.ContainsKey(hatchPatternName));
var scale = 0.025;
var hatchPatternLines = hatchPatternDict[hatchPatternName]
.Select(line => line.Scale(scale));
hatch.PatternType = HatchPatternType.SolidFill;
hatch.Pattern = new HatchPattern(hatchPatternName) { Scale = scale };
hatch.Pattern.Lines.AddRange(hatchPatternLines);
//
doc.Entities.Add(hatch);
//
const string filePath = @"D:\TestHatch02.dwg";
using var writer = new DwgWriter(filePath, doc);
writer.OnNotification += NotificationHelper.LogConsoleNotification;
writer.Write();
}
internal sealed class HatchPatternInfo
{
public string Name { get; set; }
public List<HatchPattern.Line> HatchPatternLines { get; set; }
public static List<HatchPatternInfo> LoadHatchPatternInfo(string patFilePath)
{
Debug.Assert(File.Exists(patFilePath));
var allLines = File.ReadLines(patFilePath)
.Select(line => line.Trim())
.Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith(";")).ToList();
var leadingIndices = allLines.Select((line, i) => (line, i))
.Where(t => t.line.StartsWith("*"))
.Select(t => t.i)
.OrderBy(i => i).ToList();
Debug.Assert(leadingIndices.Count > 0);
Debug.Assert(leadingIndices.Last() < allLines.Count - 1);
leadingIndices.Add(allLines.Count);
var patternInfos = new List<HatchPatternInfo>();
for (var i = 0; i < leadingIndices.Count - 1; i++)
{
var startIndex = leadingIndices[i];
var dataLineCount = leadingIndices[i + 1] - startIndex - 1;
Debug.Assert(dataLineCount > 0);
var headingText = allLines[startIndex];
Debug.Assert(headingText.StartsWith("*"));
var index = headingText.IndexOf(",");
var patternName = index > 0
? headingText.Substring(1, index - 1)
: headingText.Substring(1);
var hatchPatternLines = new List<HatchPattern.Line>();
for (var j = 0; j < dataLineCount; j++)
{
var dataLineText = allLines[startIndex + j + 1];
var data = dataLineText.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(double.Parse).ToList();
Debug.Assert(data.Count >= 5);
var angle = data[0] * Math.PI / 180D;
var basePoint = new XY(data[1], data[2]);
var offset = new XY(data[3], data[4])
.RotateAroundZAxis(angle);
var dashLengths = data.Count > 5
? data.GetRange(5, data.Count - 5)
: new List<double>();
hatchPatternLines.Add(new HatchPattern.Line()
{
Angle = angle,
BasePoint = basePoint,
Offset = offset,
DashLengths = dashLengths,
});
}
patternInfos.Add(new HatchPatternInfo()
{
Name = patternName,
HatchPatternLines = hatchPatternLines,
});
}
return patternInfos;
}
}
internal static class HatchPatternLineExtension
{
public static HatchPattern.Line Scale(this HatchPattern.Line hatchPatternLine, double scale)
{
var line = new HatchPattern.Line
{
Angle = hatchPatternLine.Angle,
BasePoint = hatchPatternLine.BasePoint.Scale(scale),
Offset = hatchPatternLine.Offset.Scale(scale),
DashLengths = hatchPatternLine.DashLengths.Select(len => len * scale).ToList()
};
return line;
}
}
internal static class XyExtension
{
public static XY RotateAroundZAxis(this XY xy, double angle)
{
var cost = Math.Cos(angle);
var sint = Math.Sin(angle);
return new XY(xy.X * cost - xy.Y * sint, xy.X * sint + xy.Y * cost);
}
public static XY Scale(this XY xy, double scale)
=> new XY(xy.X * scale, xy.Y * scale);
} Hope it will be helpful to others, and the author may improve the API to ease the use of Hatch entity. |
Beta Was this translation helpful? Give feedback.
-
Hi @wdhust Right now there is no BuildIn patterns in the library, the only tests that I performed with Hatch has been using the solid one: Hatch hatch = new Hatch();
hatch.IsSolid = true; Your solution looks really interesting, the hatch pattern file that you are loading is created by some application or has some standard format? or is created by you? I'm thinking about using json format to do that. |
Beta Was this translation helpful? Give feedback.
-
Hi, DomCR. Thanks for your excellent DWG/DXG library, it is really useful for me. The file "acadiso.pat" used in my code is copied from AutoCAD's installation directory, such as
AutoCAD uses such kind of file to define the predefined (build in) pattern of Hatch entity, and some users may create their custom Hatch pattern definition following the .pat file's format rule. The .pat file is just a plain text file, and the content in such file looks like: *SOLID, Solid fill
45, 0,0, 0,.125
*ANGLE,Angle steel
0, 0, 0, 0, 6.985, 5.08, -1.905
90, 0, 0, 0, 6.985, 5.08, -1.905
*ANSI31,ANSI Iron, Brick, Stone masonry
45, 0, 0, 0, 3.175
*ANSI32,ANSI Steel
45, 0, 0, 0, 9.525
45, 4.49013, 0, 0, 9.525
*ANSI33,ANSI Bronze, Brass, Copper
45, 0, 0, 0, 6.35
45, 4.49013, 0, 0, 6.35, 3.175, -1.5875
*ANSI34,ANSI Plastic, Rubber
45, 0, 0, 0, 19.05
45, 4.49013, 0, 0, 19.05
45, 8.98026, 0, 0, 19.05
45, 13.4704, 0, 0, 19.05
*ANSI35,ANSI Fire brick, Refractory material
45, 0, 0, 0, 6.35
45, 4.49013, 0, 0, 6.35, 7.9375, -1.5875, 0, -1.5875
*ANSI36,ANSI Marble, Slate, Glass
45, 0, 0, 5.55625, 3.175, 7.9375, -1.5875, 0, -1.5875 Some users of AcadSharp may need to use predefined Hatch entity in their drawings, rather than to create a Hatch entity from scratch. So It is best to provide support for predefined Hatch in the AcadSharp lib. |
Beta Was this translation helpful? Give feedback.
-
The Hatch class, and the associated HatchPattern class in the AcadSharp, is straightforward to construct, while it's not that clear on how to construct the HatchPattern.Line collection. I found the data of HatchPattern.Line can be converted from the data from .pat file, but I am not sure that is the right way. |
Beta Was this translation helpful? Give feedback.
Through some research and analysis, I found a solution.
Here is the code.