(C#)read Graph issue

Actually, I asked this question few weeks ago,but I’m still haunted by this question.Let me recap this question. The attachment is the grpah which I want to read. I need to read all the Mtext and the graph above of them. One graph belongs to one Mtext(the one which below the graph). But here is the thing, there is no any relationship between the graph and Mtext(they are not in the same block or other container) .How can I read them under the circumstances? I got some tips from this forum. I tried to use
cadImage.GetBounds() to solve this problem,but I still no idea how to solve this problem in this case. Because for some graph, there is not rectangle, but lots of little entities。(for example, in the attactment, the graph above the MText “-PART-M,Q235,T2,N1,C,J,H,K1” is consist of many entities). Maybe I didn’t use this method in correct way, can you give me more support ? Thank you very much
demo.zip (207.0 KB)

@autopay,
We would love to help you more, but I’m afraid we can draw just common ideas. You are right - there is no relationship in the file between MTEXT items and figures above it. It is easy for humans :slight_smile: to establish the relation between entities visually, but to process it automatically we need some criteria what is one item “belongs to” other. There are more questions than answers here. Do you always have MTEXT below the corresponding figure? Can MTEXT above the figure (or to the right/left to it) be closer to it, than MTEXT object below? Probably, it is possible to create some grid (table) from positions of MTEXT objects and after than process all other entities, mapping them to closest MTEXT below? Answers on these questions depend on the variety of drawings you can face during processing. I believe that the best results in such deep drawing analysis can be achieved when the drawing was created specially for this, e.g., MTEXT and proper items related to it were grouped.

Thanks for reply, the MTEXT is always below the corresponding figure, no other circumstances. About the original cad file, I cannot make any changes about it, because the old program,the program that the client is currently using,(but I don’t know the program’s author and its reading logic) can read it under this circumstance. Over 30,000 drawings already exist based on this logic, just like the attactment which I upload. They don’t want to make any changes on the original graph.So, the only thing I can do is just read it by some logic or method.

1 Like

@autopay,
Here is the rough example to start from but this is neither single nor best solution:

Dictionary<CadMText, List<CadEntityBase>> references = new Dictionary<CadMText, List<CadEntityBase>>();

using (CadImage cadImage = (CadImage)Aspose.CAD.Image.Load(GetPath(fileName)))
{
	List<CadEntityBase> otherEntities = new List<CadEntityBase>();

	foreach (CadEntityBase entityBase in cadImage.Entities)
	{
		if (entityBase.TypeName == CadEntityTypeName.MTEXT)
		{
			references.Add((CadMText)entityBase, new List<CadEntityBase>());
		}
		else 
		{
			otherEntities.Add(entityBase);
		}
	}

	cadImage.GetBounds();

	foreach (CadEntityBase entityBase in otherEntities)
	{
		List<Cad3DPoint> points = entityBase.Bounds;
		Tuple<Cad3DPoint, double> centerAndMinY = Center(points);

		CadMText closestMText = null;
		double minDistanceToMtext = double.MaxValue;

		foreach (CadMText mtext in references.Keys)
		{
			Tuple<Cad3DPoint, double> centerAndMinYMText = Center(mtext.Bounds);

			if (centerAndMinYMText.Item2 > centerAndMinY.Item2)
			{
				continue;
			}

			double distance = Distance2(centerAndMinY.Item1, centerAndMinYMText.Item1);
			if (distance < minDistanceToMtext)
			{
				minDistanceToMtext = distance;
				closestMText = mtext;
			}
		}

		// the associated MTEXT item has not been found
		// e.g. there are some empty TEXT objects in the drawing
		if (closestMText == null)
		{
			continue;
		}

		references[closestMText].Add(entityBase);
	}

	List<CadMText> allMtext = new List<CadMText>(references.Keys);

        // number of block to export
	int num = 0;
	List<CadEntityBase> newEntities = new List<CadEntityBase>();
	newEntities.Add(allMtext[num]);
	newEntities.AddRange(references[allMtext[num]]);

	cadImage.Entities = newEntities.ToArray();

	cadImage.Save(outPath, new PdfOptions());
}


private static Tuple<Cad3DPoint, double> Center(List<Cad3DPoint> points)
{
	double sumX = 0;
	double sumY = 0;

	double minY = points[0].Y;
	foreach (Cad3DPoint point in points)
	{
		sumX += point.X;
		sumY += point.Y;

		if (point.Y < minY)
		{
			minY = point.Y;
		}
	}

	return new Tuple<Cad3DPoint, double> (new Cad3DPoint(sumX/points.Count, sumY / points.Count, 0), minY);
}

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