diff --git a/src/ACadSharp/DxfFileToken.cs b/src/ACadSharp/DxfFileToken.cs index 71d3213a..06a15fcf 100644 --- a/src/ACadSharp/DxfFileToken.cs +++ b/src/ACadSharp/DxfFileToken.cs @@ -125,6 +125,8 @@ public static class DxfFileToken public const string ObjectSortEntsTable = "SORTENTSTABLE"; public const string ObjectXRecord = "XRECORD"; public const string ObjectMLeaderContextData = "CONTEXT_DATA"; + public const string ObjectEvalGraph = "ACAD_EVALUATION_GRAPH"; + public const string ObjectBlockVisibilityParameter = "BLOCKVISIBILITYPARAMETER"; #endregion } diff --git a/src/ACadSharp/DxfSubclassMarker.cs b/src/ACadSharp/DxfSubclassMarker.cs index 617e9d14..a4709d20 100644 --- a/src/ACadSharp/DxfSubclassMarker.cs +++ b/src/ACadSharp/DxfSubclassMarker.cs @@ -82,5 +82,7 @@ public static class DxfSubclassMarker public const string PlotSettings = "AcDbPlotSettings"; public const string DictionaryVariables = "DictionaryVariables"; public const string Scale = "AcDbScale"; + public const string EvalGraph = "AcDbEvalGraph"; + public const string BlockVisibilityParameter = "AcDbBlockVisibilityParameter"; } } diff --git a/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs b/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs index 437f252e..e069326d 100644 --- a/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs +++ b/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs @@ -7,13 +7,16 @@ using ACadSharp.Tables; using ACadSharp.Tables.Collections; using CSMath; +using CSUtilities.IO; using System.Collections.Generic; using System.Linq; using System.IO; using System; +using ACadSharp.Types; +using static ACadSharp.Objects.MultiLeaderAnnotContext; +using System.Net; using CSUtilities.Converters; using CSUtilities.Extensions; -using static ACadSharp.Objects.MultiLeaderAnnotContext; namespace ACadSharp.IO.DWG { @@ -1036,6 +1039,12 @@ private CadTemplate readUnlistedType(short classNumber) case "XRECORD": template = this.readXRecord(); break; + case "ACAD_EVALUATION_GRAPH": + template = this.readEvaluationGraph(); + break; + case "BLOCKVISIBILITYPARAMETER": + template = this.readBlockVisibilityParameter(); + break; default: break; } @@ -1059,6 +1068,128 @@ private CadTemplate readUnlistedType(short classNumber) return template; } + #region Evaluation Graph, Enhanced Block etc. + + private CadTemplate readEvaluationGraph() { + EvaluationGraph evaluationGraph = new EvaluationGraph(); + EvaluationGraphTemplate template = new EvaluationGraphTemplate(evaluationGraph); + + this.readCommonNonEntityData(template); + + // DXF fields 96, 97 contain the value 5, here are three fields returning the same value 5 + var val1 = _objectReader.ReadBitLong(); + var val2 = _objectReader.ReadBitLong(); + var val3 = _objectReader.ReadBitLong(); + int nodeCount = val3; + + for (int i = 0; i < nodeCount; i++) { + var node = new EvaluationGraph.GraphNode(); + evaluationGraph.Nodes.Add(node); + node.Index = _objectReader.ReadBitLong(); + node.Flags = _objectReader.ReadBitLong(); + node.NextNodeIndex = _objectReader.ReadBitLong(); + template.NodeHandles.Add(node, this.handleReference()); + node.Data1 = _objectReader.ReadBitLong(); + node.Data2 = _objectReader.ReadBitLong(); + node.Data3 = _objectReader.ReadBitLong(); + node.Data4 = _objectReader.ReadBitLong(); + } + + foreach (EvaluationGraph.GraphNode node in evaluationGraph.Nodes) { + int nextNodeIndex = node.NextNodeIndex; + if (nextNodeIndex >= 0 && nextNodeIndex < nodeCount) { + node.Next = evaluationGraph.Nodes[nextNodeIndex]; + } + } + + var val15 = _objectReader.ReadBitLong(); + + return template; + } + + + private CadTemplate readBlockVisibilityParameter() { + BlockVisibilityParameter blockVisibilityParameter = new BlockVisibilityParameter(); + BlockVisibilityParameterTemplate template = new BlockVisibilityParameterTemplate(blockVisibilityParameter); + + this.readCommonNonEntityData(template); + + //analyse02(200); + + var l1 = _objectReader.ReadBitLong(); + var s2 = _objectReader.ReadBitShort(); // can also be L + var s3 = _objectReader.ReadBitShort(); // can also be L + var b4 = _objectReader.ReadBit(); + var s5 = _objectReader.ReadBitShort(); // can also be L + var b6 = _objectReader.ReadBit(); + var s7 = _objectReader.ReadBitShort(); // can also be L + + var b_8 = _objectReader.ReadBit(); + var b_9 = _objectReader.ReadBit(); + var b_10 = _objectReader.ReadBit(); + var b_11 = _objectReader.ReadBit(); + var b_12 = _objectReader.ReadBit(); + var b_13 = _objectReader.ReadBit(); + var S_14 = _objectReader.ReadBitShort(); // can also be L + + var s_15 = _objectReader.ReadBitShort(); + var b_16 = _objectReader.ReadBit(); + var b_17 = _objectReader.ReadBit(); + var s_18 = _objectReader.ReadBitShort(); + + // 300 Parameter Type + blockVisibilityParameter.ParameterType = _textReader.ReadVariableText(); + + //resetPosition(214275, 2); + // 1010, 1020, 1030 Menu position + blockVisibilityParameter.BasePosition = _objectReader.Read3BitDouble(); + // 2x0 <- + var s170 = _objectReader.ReadBitShort(); + var s171 = _objectReader.ReadBitShort(); + var l93 = _objectReader.ReadBitLong(); + //DwgAnalyseTools.ShowCurrentPosAndShift(); + + //var s281 = _objectReader.ReadBitShort(); + + // 301 + blockVisibilityParameter.Name = _textReader.ReadVariableText(); + // 302 + blockVisibilityParameter.Description = _textReader.ReadVariableText(); + // DXF 91 + blockVisibilityParameter.L91 = _objectReader.ReadBitLong(); + //DwgAnalyseTools.resetPosition(214293, 0); + // DXF 93 Total entities count (no property) + var totalEntitiesCount = _objectReader.ReadBitLong(); + for (int i = 0; i < totalEntitiesCount; i++) { + var handle = this.handleReference(); + template.TotalEntityHandles.Add(handle, null); + } + + // DXF 92 Sub blocks count (no property) + var subBlocksCount = _objectReader.ReadBitLong(); + for (int sbi = 0; sbi < subBlocksCount; sbi++) { + BlockVisibilityParameter.SubBlock subBlock = new BlockVisibilityParameter.SubBlock(); + subBlock.Name = _textReader.ReadVariableText(); + blockVisibilityParameter.SubBlocks.Add(subBlock); + + IList subBlockHandles = new List(); + template.SubBlockHandles.Add(subBlock, subBlockHandles); + // DXF 94 Subblock entities count (no property) + int entitiesCount = _objectReader.ReadBitLong(); + for (int i = 0; i < entitiesCount; i++) { + var handle = this.handleReference(); + subBlockHandles.Add(handle); + } + //DwgAnalyseTools.showCurrentPosAndShift(); + // DXF 95 + var endMark = _objectReader.ReadBitLong(); + } + + return template; + } + + #endregion + #region Text entities private CadTemplate readUnknownEntity(DxfClass dxfClass) diff --git a/src/ACadSharp/IO/Templates/BlockVisibilityParameterTemplate.cs b/src/ACadSharp/IO/Templates/BlockVisibilityParameterTemplate.cs new file mode 100644 index 00000000..b5ac7e8f --- /dev/null +++ b/src/ACadSharp/IO/Templates/BlockVisibilityParameterTemplate.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; + +using ACadSharp.Entities; +using ACadSharp.Objects; + +namespace ACadSharp.IO.Templates { + + internal class BlockVisibilityParameterTemplate : CadTemplate { + + public BlockVisibilityParameterTemplate(BlockVisibilityParameter cadObject) + : base(cadObject) { + } + + public IDictionary TotalEntityHandles { get; } = new Dictionary(); + + public IDictionary> SubBlockHandles { get; } = new Dictionary>(); + + public override void Build(CadDocumentBuilder builder) { + base.Build(builder); + + foreach (var cadObjectHandle in this.TotalEntityHandles) { + ulong handle = cadObjectHandle.Key; + if (builder.TryGetCadObject(handle, out Entity entity)) { + this.TotalEntityHandles[handle] = entity; + this.CadObject.Entities.Add(entity); + } + } + + foreach (var subGroup in this.CadObject.SubBlocks) { + if (this.SubBlockHandles.TryGetValue(subGroup, out IList subBlockHandles)) { + foreach (ulong handle in subBlockHandles) { + if (this.TotalEntityHandles.TryGetValue(handle, out Entity entity)) { + subGroup.Entities.Add(entity); + } + else if (builder.TryGetCadObject(handle, out Entity entityX)) { + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/ACadSharp/IO/Templates/EvaluationGraphTemplate.cs b/src/ACadSharp/IO/Templates/EvaluationGraphTemplate.cs new file mode 100644 index 00000000..6dd44dba --- /dev/null +++ b/src/ACadSharp/IO/Templates/EvaluationGraphTemplate.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +using ACadSharp.Objects; + +namespace ACadSharp.IO.Templates { + internal class EvaluationGraphTemplate : CadTemplate{ + + public EvaluationGraphTemplate(EvaluationGraph evaluationGraph) + : base(evaluationGraph) { + } + + public IDictionary NodeHandles { get; } = new Dictionary(); + + public override void Build(CadDocumentBuilder builder) { + base.Build(builder); + + foreach (EvaluationGraph.GraphNode node in this.CadObject.Nodes) { + var nodeHandle = this.NodeHandles[node]; + if (builder.TryGetCadObject(nodeHandle, out CadObject nodeObject)) { + node.NodeObject = nodeObject; + } + } + } + } +} \ No newline at end of file diff --git a/src/ACadSharp/Objects/BlockVisibilityParameter.cs b/src/ACadSharp/Objects/BlockVisibilityParameter.cs new file mode 100644 index 00000000..c73b17c7 --- /dev/null +++ b/src/ACadSharp/Objects/BlockVisibilityParameter.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; + +using ACadSharp.Attributes; +using ACadSharp.Entities; + +using CSMath; + + +namespace ACadSharp.Objects +{ + + /// + /// Represents a BLOCKVISIBILITYPARAMETER object, in AutoCAD used to + /// control the visibility state of entities in a dynamic block. + /// + public class BlockVisibilityParameter : CadObject + { + + /// + public override ObjectType ObjectType => ObjectType.UNLISTED; + + /// + public override string ObjectName => DxfFileToken.ObjectBlockVisibilityParameter; + + /// + public override string SubclassMarker => DxfSubclassMarker.BlockVisibilityParameter; + + + /// + /// Gets the list of all objects of the dynamic block + /// this is associated with. + /// + [DxfCodeValue(331)] + public IList Entities { get; private set; } = new List(); + + /// + /// Gets the list of subblocks each containing a subset of the + /// objects of the dynamic block this + /// is associated with. + /// + public IList SubBlocks { get; private set; } = new List(); + + /// + /// Gets a position presumably used to display a triangle-button in AutoCAD open + /// a dialog to select the subblock that is to be set visible. + /// + [DxfCodeValue(1010, 1020, 1030)] + public XYZ BasePosition { get; internal set; } + + /// + /// Gets a text presumably describing the purpose of this . + /// + [DxfCodeValue(300)] + public string ParameterType { get; internal set; } + + /// + /// Gets a title for the dialog to select the subblock that is to be set visible. + /// + [DxfCodeValue(301)] + public string Name { get; internal set; } + + /// + /// Gets a description presumably for the dialog to select the subblock that is to be set visible. + /// + [DxfCodeValue(302)] + public string Description { get; internal set; } + + /// + /// Unknown + /// + [DxfCodeValue(91)] + public int L91 { get; internal set; } + + /// + /// Represents a named subblock containing objects. + /// The visibility of the entities of a subblock can be determined + /// interactively in AutoCAD. + /// + public class SubBlock : ICloneable + { + + /// + /// Gets the name of the subblock. + /// + [DxfCodeValue(303)] + public string Name { get; set; } + + /// + /// Get the list of objects in this subblock. + /// + [DxfCodeValue(332)] + public IList Entities { get; private set; } = new List(); + + + public object Clone() + { + SubBlock clone = (SubBlock)MemberwiseClone(); + + clone.Entities = new List(); + foreach (var item in this.Entities) + { + clone.Entities.Add((Entity)item.Clone()); + } + + return clone; + } + } + + + /// + public override CadObject Clone() + { + BlockVisibilityParameter clone = (BlockVisibilityParameter)base.Clone(); + + clone.Entities = new List(); + foreach (var item in this.Entities) + { + clone.Entities.Add((Entity)item.Clone()); + } + + clone.SubBlocks = new List(); + foreach (var item in this.SubBlocks) + { + clone.SubBlocks.Add((SubBlock)item.Clone()); + } + + return clone; + } + } +} \ No newline at end of file diff --git a/src/ACadSharp/Objects/EvaluationGraph.cs b/src/ACadSharp/Objects/EvaluationGraph.cs new file mode 100644 index 00000000..0b5f7287 --- /dev/null +++ b/src/ACadSharp/Objects/EvaluationGraph.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; + +using ACadSharp.Attributes; + + +namespace ACadSharp.Objects +{ + + /// + /// Represents an evaluation graph containing a list of + /// objects. + /// + public class EvaluationGraph : NonGraphicalObject + { + + public EvaluationGraph() {} + + /// + public override ObjectType ObjectType => ObjectType.UNLISTED; + + /// + public override string ObjectName => DxfFileToken.ObjectEvalGraph; + + /// + public override string SubclassMarker => DxfSubclassMarker.EvalGraph; + + /// + /// Gets a list of objects. + /// + public IList Nodes { get; private set; } = new List(); + + + /// + /// Represents a graph node of a . + /// + public class GraphNode : ICloneable + { + + /// + /// Gets or sets the index of this in the list of + /// graph nodes in the owning . + /// + [DxfCodeValue(91)] + public int Index { get; set; } + + /// + /// Gets or sets the index of the next in the list of + /// graph nodes in the owning . + /// + [DxfCodeValue(95)] + internal int NextNodeIndex { get; set; } + + /// + /// Gets the next in the list of + /// graph nodes in the owning . + /// + public GraphNode Next { get; internal set; } + + /// + /// Unknown + /// + [DxfCodeValue(93)] + public int Flags { get; set; } + + /// + /// Unknown + /// + [DxfCodeValue(92)] + public int Data1 { get; internal set; } + + /// + /// Unknown + /// + [DxfCodeValue(92)] + public int Data2 { get; internal set; } + + /// + /// Unknown + /// + [DxfCodeValue(92)] + public int Data3 { get; internal set; } + + /// + /// Unknown + /// + [DxfCodeValue(92)] + public int Data4 { get; internal set; } + + /// + /// Gets a associated with this . + /// + [DxfCodeValue(360)] + public CadObject NodeObject { get; internal set; } + + + public object Clone() + { + GraphNode clone = (GraphNode)MemberwiseClone(); + + clone.Next = (GraphNode)Next.Clone(); + clone.NodeObject = NodeObject.Clone(); + + return clone; + } + } + + + /// + public override CadObject Clone() + { + EvaluationGraph clone = (EvaluationGraph)base.Clone(); + + clone.Nodes = new List(); + foreach (var item in this.Nodes) + { + clone.Nodes.Add((GraphNode)item.Clone()); + } + + return clone; + } + } +} \ No newline at end of file