Skip to content

Commit

Permalink
Merge pull request #419 from nanoLogika/20240619_mme_#6-support-dynam…
Browse files Browse the repository at this point in the history
…ic-blocks-read-evaluation-graphs-and-block-visibility-parameters

Sync Branch 20240619 mme #6 support dynamic blocks read evaluation graphs and block visibility parameters
  • Loading branch information
DomCR authored Nov 4, 2024
2 parents a569331 + e691e5b commit 3be9c45
Show file tree
Hide file tree
Showing 7 changed files with 457 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/ACadSharp/DxfFileToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 2 additions & 0 deletions src/ACadSharp/DxfSubclassMarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}
133 changes: 132 additions & 1 deletion src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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;
}
Expand All @@ -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<ulong> subBlockHandles = new List<ulong>();
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)
Expand Down
42 changes: 42 additions & 0 deletions src/ACadSharp/IO/Templates/BlockVisibilityParameterTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Collections.Generic;

using ACadSharp.Entities;
using ACadSharp.Objects;

namespace ACadSharp.IO.Templates {

internal class BlockVisibilityParameterTemplate : CadTemplate<BlockVisibilityParameter> {

public BlockVisibilityParameterTemplate(BlockVisibilityParameter cadObject)
: base(cadObject) {
}

public IDictionary<ulong, Entity> TotalEntityHandles { get; } = new Dictionary<ulong, Entity>();

public IDictionary<BlockVisibilityParameter.SubBlock, IList<ulong>> SubBlockHandles { get; } = new Dictionary<BlockVisibilityParameter.SubBlock, IList<ulong>>();

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<ulong> 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)) {
}
}
}
}
}
}
}
25 changes: 25 additions & 0 deletions src/ACadSharp/IO/Templates/EvaluationGraphTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Collections.Generic;

using ACadSharp.Objects;

namespace ACadSharp.IO.Templates {
internal class EvaluationGraphTemplate : CadTemplate<EvaluationGraph>{

public EvaluationGraphTemplate(EvaluationGraph evaluationGraph)
: base(evaluationGraph) {
}

public IDictionary<EvaluationGraph.GraphNode, ulong> NodeHandles { get; } = new Dictionary<EvaluationGraph.GraphNode, ulong>();

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;
}
}
}
}
}
131 changes: 131 additions & 0 deletions src/ACadSharp/Objects/BlockVisibilityParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;

using ACadSharp.Attributes;
using ACadSharp.Entities;

using CSMath;


namespace ACadSharp.Objects
{

/// <summary>
/// Represents a BLOCKVISIBILITYPARAMETER object, in AutoCAD used to
/// control the visibility state of entities in a dynamic block.
/// </summary>
public class BlockVisibilityParameter : CadObject
{

/// <inheritdoc/>
public override ObjectType ObjectType => ObjectType.UNLISTED;

/// <inheritdoc/>
public override string ObjectName => DxfFileToken.ObjectBlockVisibilityParameter;

/// <inheritdoc/>
public override string SubclassMarker => DxfSubclassMarker.BlockVisibilityParameter;


/// <summary>
/// Gets the list of all <see cref="Entity"/> objects of the dynamic block
/// this <see cref="BlockVisibilityParameter"/> is associated with.
/// </summary>
[DxfCodeValue(331)]
public IList<Entity> Entities { get; private set; } = new List<Entity>();

/// <summary>
/// Gets the list of subblocks each containing a subset of the <see cref="Entity"/>
/// objects of the dynamic block this <see cref="BlockVisibilityParameter"/>
/// is associated with.
/// </summary>
public IList<SubBlock> SubBlocks { get; private set; } = new List<SubBlock>();

/// <summary>
/// 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.
/// </summary>
[DxfCodeValue(1010, 1020, 1030)]
public XYZ BasePosition { get; internal set; }

/// <summary>
/// Gets a text presumably describing the purpose of this <see cref="BlockVisibilityParameter"/>.
/// </summary>
[DxfCodeValue(300)]
public string ParameterType { get; internal set; }

/// <summary>
/// Gets a title for the dialog to select the subblock that is to be set visible.
/// </summary>
[DxfCodeValue(301)]
public string Name { get; internal set; }

/// <summary>
/// Gets a description presumably for the dialog to select the subblock that is to be set visible.
/// </summary>
[DxfCodeValue(302)]
public string Description { get; internal set; }

/// <summary>
/// Unknown
/// </summary>
[DxfCodeValue(91)]
public int L91 { get; internal set; }

/// <summary>
/// Represents a named subblock containing <see cref="Entity"/> objects.
/// The visibility of the entities of a subblock can be determined
/// interactively in AutoCAD.
/// </summary>
public class SubBlock : ICloneable
{

/// <summary>
/// Gets the name of the subblock.
/// </summary>
[DxfCodeValue(303)]
public string Name { get; set; }

/// <summary>
/// Get the list of <see cref="Entity"/> objects in this subblock.
/// </summary>
[DxfCodeValue(332)]
public IList<Entity> Entities { get; private set; } = new List<Entity>();


public object Clone()
{
SubBlock clone = (SubBlock)MemberwiseClone();

clone.Entities = new List<Entity>();
foreach (var item in this.Entities)
{
clone.Entities.Add((Entity)item.Clone());
}

return clone;
}
}


/// <inheritdoc/>
public override CadObject Clone()
{
BlockVisibilityParameter clone = (BlockVisibilityParameter)base.Clone();

clone.Entities = new List<Entity>();
foreach (var item in this.Entities)
{
clone.Entities.Add((Entity)item.Clone());
}

clone.SubBlocks = new List<SubBlock>();
foreach (var item in this.SubBlocks)
{
clone.SubBlocks.Add((SubBlock)item.Clone());
}

return clone;
}
}
}
Loading

0 comments on commit 3be9c45

Please sign in to comment.