Entity resizing in a dxf file

Hello, I was wondering if is possible to change the dimensions of any entity in a dxf file (lines for example) by updating the value of attributes using Aspose.CAD. I mean, not just change the text of
a dimension between two points, but also resize the entities visually.

Thanks!

1 Like

@jaiv1978

Plese visit this API refernece guide link where you will find the properties for setting the line weights, scales and other properties for your convenince.

Thanks for the answer, but I still having problems updating the values

I tried with a simple dxf file that has a square of 40x40 (you can see in the uploaded file)

image.png (3.5 KB)

Then I executed this code (based on the ASPOSE-examples project)

		try
		{
			//ExStart:AddAttribute
			// The path to the documents directory.
			string MyDir = RunExamples.GetDataDir_DXFDrawings();
			string sourceFilePath = MyDir + "Drawing1.dxf";
			FileStream fileStream = new FileStream(MyDir + "Drawing1_v2.dxf", FileMode.OpenOrCreate, FileAccess.Write);
			
			using (CadImage cadImage = (CadImage)Image.Load(sourceFilePath))
			{
				foreach (var entity in cadImage.Entities)
				{
					if (entity.TypeName == CadEntityTypeName.DIMENSION)
					{
						var dimension = (CadDimensionBase)entity;
						dimension.Text = "50";
					}
				}
				cadImage.Save(fileStream);
				fileStream.Close();
			}		
		}
		catch (Exception ex)
		{
			Console.WriteLine(ex.Message);
		}

When I open Drawing1_v2.dxf I don’t see the Text dimensions changed, but when I see their properties, I can see that the new text value is changed. What do I need to do to display the new values?.

PD. If I double click on the dimensions, the new texts are displayed

Drawing1_v2.PNG (13.6 KB)

@jaiv1978

Can you please possibly share the desired output file that you want to achieve so that we may try to help you further in this regard.

Sure, What I want is the following:

I have a dxf file with a square of 40x40

image.png (3.5 KB)

I process it using ASPOSE.Cad and change the values of the dimensiones like this (using CadDimensionBase object)

ActualMeasurement = 50
Text = “50”

Then, I get a new dxf file with a square of 50x50 (the dimension text has changed and the real dimensions of the square too)

Drawing1_changed.PNG (3.6 KB)

@jaiv1978

I can observe the snapshots shared by you. However, as requested earlier please share the desired output DXF along with source DXF that I may use to log the issue for investigation and resolution.

Hello,

This is the zip file with both dxf files.

Drawing1_v2.zip (18.9 KB)

“Drawing1.dxf” is the input file
“Drawing1_v2.dxf” is the output required

thanks

@jaiv1978

We need to further evaluate your requirements and for this I have added a ticket with ID CADNET-1263 in our issue tracking system to further investigate and resolve the issue. This thread has been linked with the issue so that you may be notified once the issue will be fixed.

The issues you have found earlier (filed as CADNET-1263) have been fixed in this update.

@jaiv1978

Changing of entities depends on the structure of entity in terms of the format. Unfortunately, dimension entities are problematic to change with code.
The main issues are below. In explanations I will refer to this dimension structure in example file:

  1. Dimension objects in file are not linked with the objects they “measure”. So there is the problem in the searching for the “proper” object, there is no relation between the dimension and red line it is “attached” to. The only way here is to search for the match between DefinitionPoint1 and DefinitionPoint2 of the dimension and FirstPoint and SecondPoint of line entity. This is based only on the a priori knowing that dimension “relates” to LINE entity. This becomes much more complicated when we don’t know that it is LINE.

For example, you can get all rotated dimensions like:

List<CadRotatedDimension> dimensions = new List<CadRotatedDimension>();

foreach (var entity in cadImage.Entities)
{
if (entity.TypeName == CadEntityTypeName.DIMENSION)
{
CadDimensionBase dimensionBase = (CadDimensionBase)entity;

if (dimensionBase.TypeOfDimension == CadDimensionType.Rotated)
{
dimensions.Add((CadRotatedDimension)entity);
}
}
}
And find proper line match with this:
foreach (CadRotatedDimension rotated in dimensions)
{
foreach (var entity in cadImage.Entities)
{
if (entity.TypeName == CadEntityTypeName.LINE)
{
CadLine line = (CadLine)entity;

if ((ClosePoints(line.FirstPoint, rotated.DefinitionPoint1) && ClosePoints(line.SecondPoint, rotated.DefinitionPoint2)) || (ClosePoints(line.SecondPoint, rotated.DefinitionPoint1) && ClosePoints(line.FirstPoint, rotated.DefinitionPoint2)))
{
// match
}
}
}
}

private static bool ClosePoints(Cad2DPoint point2D, Cad3DPoint point3D, double eps = 0.0001)
{
return Math.Abs(point2D.X - point3D.X) < eps && Math.Abs(point2D.Y - point3D.Y) < eps;
}
  1. The next issue is geometrical modification of entities. It is straightforward in this particular example as we need to increase X coordinate of line and dimension at 10 points.

    // match
    line.SecondPoint.X += 10;
    rotated.DefinitionPoint2.X += 10;
    rotated.DefinitionPoint.X += 10;
    rotated.ActualMeasurement = 50;
    rotated.Text = “50”;

But even here we have some troubles. You need to know somehow that you need to move only Second point of line but not First one. Besides that you need to move DefinitionPoint and DefinitionPoint2 of the dimension and modify its measurement and text. You don’t need to modify DefinitionPoint1 and you need to know this (with analysis of space positioning of objects being changed).

  1. Finally we have the last issue. We should take into account the fact that dimension has complex structure itself, it is shown in figure above. It contains 4 LINE entities, 2 SOLIDS, 1 MTEXT, 2 POINTS (this set may vary depending on dimension type or its properties, e.g. switching extension lines off etc.). Unfortunately, they are stored separately in a block related to the dimension.

So, you commonly need to modify some of these parts too. The complex part is that you need to detect (again with positions analysis or somehow) which parts should be changed, e.g. change Line 2 but not Line 1. In our particular example we need to make such changes to preserve structure:

//For line 2: 
line.FirstPoint.X += 10;
line.SecondPoint.X += 10;

//For line 3:
line.SecondPoint.X += 5;

//For line 4:
line.FirstPoint.X += 10;
line.SecondPoint.X += 5;

//For solid 2:
solid.FirstCorner.X += 10;
solid.SecondCorner.X += 10;
solid.ThirdCorner.X += 10;
solid.FourthCorner.X += 10;


//For point 2:
point.PointLocation.X += 10;


//For Mtext:
mtext.InsertionPoint.X += 5;

And take into account that it is just moving along X coordinate. If the dimension will be more complicated (e.g. arbitrary oriented) or of other type everything gets more complicated.

This code allows to iterate over all parts of the dimension:

CadBlockEntity dimensionBlock = cadImage.BlockEntities[rotated.BlockName];
foreach (CadBaseEntity dimensionEntity in dimensionBlock.Entities)
{
…
}

So, the entire example of resizing of this dimension (I left only one this dimension in the initial file) and corresponding line is:

List<CadRotatedDimension> dimensions = new List<CadRotatedDimension>();

foreach (var entity in cadImage.Entities)
{
if (entity.TypeName == CadEntityTypeName.DIMENSION)
{
CadDimensionBase dimensionBase = (CadDimensionBase)entity;

if (dimensionBase.TypeOfDimension == CadDimensionType.Rotated)
{
dimensions.Add((CadRotatedDimension)entity);
}
}
}

foreach (CadRotatedDimension rotated in dimensions)
{
foreach (var entity in cadImage.Entities)
{
if (entity.TypeName == CadEntityTypeName.LINE)
{
CadLine line = (CadLine)entity;

if ((ClosePoints(line.FirstPoint, rotated.DefinitionPoint1) && ClosePoints(line.SecondPoint, rotated.DefinitionPoint2)) || (ClosePoints(line.SecondPoint, rotated.DefinitionPoint1) && ClosePoints(line.FirstPoint, rotated.DefinitionPoint2)))
{
line.SecondPoint.X += 10;
rotated.DefinitionPoint2.X += 10;
rotated.DefinitionPoint.X += 10;
rotated.ActualMeasurement = 50;
rotated.Text = "50";
}
}
}

CadBlockEntity dimensionBlock = cadImage.BlockEntities[rotated.BlockName];
int lines = 0;
int solids = 0;
int points = 0;
foreach (CadBaseEntity dimensionEntity in dimensionBlock.Entities)
{
System.Console.WriteLine(dimensionEntity.TypeName);

switch (dimensionEntity.TypeName)
{

case CadEntityTypeName.LINE:
{
lines++;
CadLine line = (CadLine)dimensionEntity;
if (lines == 2)
{
line.FirstPoint.X += 10;
line.SecondPoint.X += 10;
}


if (lines == 3)
{
line.SecondPoint.X += 5;
}

if (lines == 4)
{
line.FirstPoint.X += 10;
line.SecondPoint.X += 5;
}

break;
}

case CadEntityTypeName.SOLID:
{
solids++;

CadSolid solid = (CadSolid)dimensionEntity;
if (solids==2)
{
solid.FirstCorner.X += 10;
solid.SecondCorner.X += 10;
solid.ThirdCorner.X += 10;
solid.FourthCorner.X += 10;
}
break;

}

case CadEntityTypeName.POINT:
{
points++;
CadPoint point = (CadPoint)dimensionEntity;
if (points == 2)
{
point.PointLocation.X += 10;
}

break;
}
case CadEntityTypeName.MTEXT:
{
CadMText mtext = (CadMText)dimensionEntity;
mtext.InsertionPoint.X += 5;

break;
}
}
}
}

As a final note: if you skip step 3 and modify dimension entity only partially (after step 2) Autocad recovers the dimension to the updated position automatically when you open the file and click on the dimension.