Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double Bug in MText rotation #184

Open
rocchellid opened this issue Jun 13, 2022 · 11 comments
Open

Double Bug in MText rotation #184

rocchellid opened this issue Jun 13, 2022 · 11 comments

Comments

@rocchellid
Copy link

There is a double problem about the rotation angle in MText: the first is that you write it twice, the first correct and the second at 0, so when you read the DXF the 2nd overwrites the first and therefore all the writings are at 0.
The second problem is that in reality AutoCAD never writes code 50 (the angle) but only compiles 11 and 21 from which the angle is obtained; indeed the 50 gives him his own annoyance.
In practice, never write 50.
Or remove the data (which is always 0 in reading as it never appears in a DXF) or you calculate it by doing:
Read: (360M - Angle.FromRadiant (Math.Atan2 (MText.XAxisDirection.X, MText.XAxisDirection.Y)) + 90M)
Write: XAxisDirection = new DxfVector (Rotation.Cos (), Rotation.Sin (), 0)
Tested with AutoCAD 2015.
Regards,
Davide

@rocchellid
Copy link
Author

Just read form http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-79f8.htm

50 | Rotation angle in radians
50 | Column heights; this code is followed by a column count (Int16), and then the number of column heights

That's why AutoCAD doesn't use code 50 for rotation ... and why you type it twice ...

@brettfo
Copy link
Member

brettfo commented Jun 24, 2022

The spec lists code 50 being written multiple times; once as the rotation angle, and then again as column heights, but it's not very clear exactly how the column heights are written. E.g., it says for the second instance of code 50:

Column heights; this code is followed by a column count (Int16), and then the number of column heights

But code 50 is supposed to be a double, not int16, but that's not too bad because we can always cast it, but then it says it's followed by the number of column heights. Does this mean if there are 3 column heights of values (1.5, 2.5, 3.5) that it'll write 4 code pairs: 50/3, 50/1.5, 50/2.5, 50/3.5?

Do you have an example MTEXT with multiple column heights? I can likely figure out what's expected and make it work appropriately.

On another note, I don't want to skip the first code 50 rotation angle, because other apps might depend on that value, but once I figure out how to handle the subsequent code 50's, the first one won't be a problem.

@rocchellid
Copy link
Author

I have attached an example of DXF with 5 static columns; what I see in the DXF is a somewhat thick structure ACAD_MTEXT_COLUMN_INFO_BEGIN - ACAD_MTEXT_COLUMN_INFO_END with different data on the columns.
Regards,
Davide

Columns.zip

@brettfo
Copy link
Member

brettfo commented Jun 29, 2022

Columns.dxf is specifying its column data in XDATA, not as code 50 values, so unfortunately I can't draw enough information from this to determine exactly how the various code 50 columns are supposed to work. E.g., if you open Columns.dxf in notepad or any other text editor and look at lines 2229-2274 you'll see where all of this is specified. The column count is either being defined by the value 1070/5 on lines 2243-2244 or the value 1070/5 on lines 2263-2264, but I can't say for certain.

I'm reluctant to add any special handling to this library for the AutoCAD-specific XDATA (denoted by 1001/ACAD on lines 2229-2230) because:

  1. It's application specific, not generic to all DXF files
  2. I haven't seen any official spec from Autodesk about what these values actually mean.

If you want to add this XDATA handling to your own app, you can read (and set for writing) the raw data with something like this:

var dxf = DxfFile.Load("Columns.dxf");
var mtext = dxf.Entities.OfType<DxfMText>().First();
var acadXData = mtext.XData["ACAD"];
// `acadXData` is an `IList<>` that you can enumerate through

Since this issue was opened for the handling of code 50 values I'll leave it open in case more information is gathered.

@rocchellid
Copy link
Author

I agree with you on not managing the columns (by the way I don't care specifically).
But I ask you to remove the other code 50 in order not to have the double repetition as now which is interpreted by AutoCAD as an angle.
Regards,
Davide

@brettfo
Copy link
Member

brettfo commented Jun 30, 2022

Since the spec defines those other code 50 values, I can't remove them, but if I can find an example of how those other values are used I can fix the behavior so that it's correct and the rotation angle isn't overwritten.

If you ever run into a file with MTEXT with those extra code 50 values, I'd love to see a copy of it so I can see exactly what it's doing.

@rocchellid
Copy link
Author

Maybe I understood: the explanation in the PDF is a bit convoluted but looking (PNG attached) it corresponds to the DXF (attached) I would say that it is "clear": 50 indicates that the next integer data (1070) is the number of columns (5)
Regards,
David

Example.zip

@brettfo
Copy link
Member

brettfo commented Jul 1, 2022

Ohh, this is annoying. The spec doesn't say that these code pairs are double-encoded in XDATA, but the drawing you sent me obviously shows this. It appears that through code 44 (what I call LineSpacingFactor), the values are in normal code pairs, but the next set of codes introduced in the 2008 spec are really held inside XDATA, even though the spec doesn't say it. I'm hesitant to do more without understanding it better, but could you do me a favor and try to load the file I've attached to this message? It's the same as the Example.dxf you just posted, but I converted the XDATA back to regular code pairs, e.g., I changed ColumnType (code 75) from the XDATA form:

1070
    75
1070
     2

to a normal form:

 75
     2

I want to see if your version of AutoCAD understands the normal form, or only the XDATA form. Based on how it handles it I'll have to decide what to do.

Example.zip

@rocchellid
Copy link
Author

AutoCad 2015 response: Xdata wasn't read. Invalid or incomplete DXF input -- drawing discarded.
Also Autodesk Viewer 2020 can't read the file.
As you can see from the attachment, the codes you have not put are essential ...

Errors.zip

@brettfo
Copy link
Member

brettfo commented Jul 1, 2022

Thanks for checking. I'll think about it a bit and then start working on reading/writing those values from XDATA.

@psychopatt
Copy link

psychopatt commented Nov 27, 2023

Hi, just so you know, QCad seems to behave the same way than AutoCad when reading, the second 50 pair is also interpreted as an angle and overwrites the first value.
I don't need column heights, is there currently a workaround to have the text rotated?

Anyway, thanks for your work. I just started using your library, it's simple, straightforward, and very promising!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants