How to get or set arrow size for dimension?

such as CadRotatedDimension

@mayo1983,
Hi.
The arrow size value is stored not directly in dimension object, but deeper in the file. Could you please clarify what are the initial and output formats, e.g., into what format you are going to save dimensions with modified arrow size values?

Hi Alex,
The input file format is dwg and the output is dxf,my coding language is c#,.

—Original—

@mayo1983,
Hello.

The situation with arrow size is a bit messy because there are few parameters that can affect its size. They are DIMASZ value from file header, value from style, value from dimension itself and scale of the dimension.

Here is the example how to get all these related values:

using (CadImage cadImage = (CadImage)Aspose.CAD.Image.Load(fileName))
{
	foreach (CadEntityBase baseEntity in cadImage.Entities)
	{
		// get size of arrow and scale
		if (baseEntity.TypeName == CadEntityTypeName.DIMENSION)
		{
			CadDimensionBase dimensionBase = (CadDimensionBase)baseEntity;

			CadDimensionStyleTable dimensionStyleTable = GetDimensionStyle(cadImage, dimensionBase.StyleName);

			double arrowSize = 0;

			if (cadImage.Header != null && cadImage.Header.HeaderProperties.ContainsKey(CadHeaderAttribute.DIMASZ))
			{
				arrowSize = GetArrowSize(dimensionBase, dimensionStyleTable);
			}

			// get size from header
			if (arrowSize < 0.0001)
			{
				arrowSize = ((CadDoubleParameter)cadImage.Header.HeaderProperties[CadHeaderAttribute.DIMASZ][0]).Value;
			}

			System.Console.WriteLine("Arrow size =" + arrowSize);

			CadCodeValue dimScaleString = GetValueFromXData(dimensionBase, (int)CadEntityAttribute.Cad040);

			float dimScale = 1f;
			if (dimScaleString != null && dimScaleString.Value != null)
			{
				dimScale = float.Parse(dimScaleString.Value, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture);
			}
			else
			{
				if (dimensionStyleTable != null && dimensionStyleTable.Dimscale > 0.0001f)
				{
					dimScale = (float)dimensionStyleTable.Dimscale;
				}
			}

			System.Console.WriteLine("Dim scale=" + dimScale);
		}
	}
}

static CadDimensionStyleTable GetDimensionStyle(CadImage cadImage, string styleName)
{
	CadDimensionStyleTable styleTableObject = null;

	if (cadImage.DimensionStyles.ContainsKey(styleName))
	{
		styleTableObject = cadImage.DimensionStyles[styleName];
	}
	else
	{
		if (cadImage.DimensionStyles.ContainsKey(CadCommon.STANDARD_STYLE))
		{
			styleTableObject = cadImage.DimensionStyles[CadCommon.STANDARD_STYLE];
		}
	}

	return styleTableObject;
}

static float GetArrowSize(CadEntityBase cadObject, CadDimensionStyleTable styleTable)
{
	float arrowSize = 0;

	if (styleTable != null)
	{
		arrowSize = (float)styleTable.Dimasz;
	}

	CadCodeValue xdataOverride = GetValueFromXData(cadObject, (int)CadEntityAttribute.Cad041);

	if (xdataOverride != null)
	{
		arrowSize = (float)xdataOverride.GetDoubleValue();
	}

	return arrowSize;
}

static CadCodeValue GetValueFromXData(CadEntityBase baseObject, short codeValue)
{
	CadXdata xdata = baseObject.XdataContainer.GetAcadData();
	if (xdata != null && xdata.DataList.Count > 0)
	{
		for (int i = 0; i < xdata.DataList.Count; i++)
		{
			if (xdata.DataList[i].Code == (int)CadEntityAttribute.Cad1070 && xdata.DataList[i].GetShortValue() == codeValue)
			{
				if (xdata.DataList[i + 1].Code == (int)CadEntityAttribute.Cad1040)
				{
					return xdata.DataList[i + 1];
				}
			}
		}
	}

	return null;
}

The actual arrow element is stored in file separately as SOLID object, it is possible to evaluate its size additionally, e.g.:

if (baseEntity.TypeName == CadEntityTypeName.DIMENSION)
{
	CadBlockEntity block = cadImage.BlockEntities[dimensionBase.BlockName];

	foreach (CadEntityBase blockEntity in block.Entities)
	{
		if (baseEntity.TypeName == CadEntityTypeName.DIMENSION)
		{
			if (baseEntity.TypeName == CadEntityTypeName.SOLID)
			{
				CadSolid solid = (CadSolid)baseEntity;

				Cad3DPoint middleCorner = new Cad3DPoint(
					(solid.FirstCorner.X + solid.SecondCorner.X) / 2,
					(solid.FirstCorner.Y + solid.SecondCorner.Y) / 2,
					(solid.FirstCorner.Z + solid.SecondCorner.Z) / 2);

				double arrow = Distance(middleCorner, solid.ThirdCorner);
				break;
			}
		}
	}
}

private static double Distance(Cad3DPoint point1, Cad3DPoint point2)
{
	double deltaX = point1.X - point2.X;
	double deltaY = point1.Y - point2.Y;
	double deltaZ = point1.Z - point2.Z;
	double distance = Math.Sqrt((deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ));
	return distance;
}

From Aspose.CAD for .NET 23.9 the last method will be embedded as dimensionBase.ArrowSize public property.

So, it seems that changing of arrow size requires changing both some of the properties in the first code snippet and rescaling of the proper SOLID objects, but this may depend on the application that is used to open the result file.

Thank Alex, may be I can wait for the latest version which the arrow size become a public property。

—Original—

1 Like

@mayo1983,
please, note, that only getter will be implemented as public API for 23.9.