JamesBremner / DXF_Viewer

A simple DXF File viewer
MIT License
22 stars 4 forks source link

Alternate parsers for the SOLID entity in DXF files #23

Closed asmwarrior closed 5 months ago

asmwarrior commented 4 years ago

Hi, I see recently, reading the solid type of DXF is introduced.

I just did some test and found some issues here.

First, I create a dxf file for test by using the python's ezdxf library. Here is the code:

import ezdxf

def rect1(x, y, width=10, height=10):
    return (x, y), (x + width, y), (x, y + height), (x + width, y + height)

def rect2(x, y, width=10, height=10):
    return (x, y), (x + width, y), (x + width, y + height), (x, y + height)

doc = ezdxf.new('R12')
msp = doc.modelspace()
msp.add_solid(rect1(150, 250, 10, 20)) #first rect
msp.add_solid(rect2(170, 250, 10, 20)) #second rect
msp.add_solid([(190,250), (200,250), (190,270)]) #trangle
doc.saveas('solid.dxf')

I open the solid.dxf under the liberCAD software, and shows such result image: 2020-03-13 13 55 14

You can see, the image shows three elements. For a normal rectangle(the first element), we should take the 4 points like: (x, y), (x + width, y), (x, y + height), (x + width, y + height) sequence.

If we pass the point sequence like (x, y), (x + width, y), (x + width, y + height), (x, y + height) which shows in middle of the screen shot. That may be the solid we are not expected.

Now, back to DXF_Viewer's code, in the file src\Solid.cpp, there are some code like below:

https://github.com/JamesBremner/DXF_Viewer/blob/e476b55acaad3f1e0ac22ab04b2dfd1303d827eb/src/Solid.cpp#L43-L68

It only read the first point and the third point, which is not enough to reconstruct the rectangle.

solid.zip

I have upload the solid.dxf in the solid.zip file.

And here is the suggested code changes: 1, it looks like the whole 4 points are needed. 2, the points sequence should be considered, for example, in the first element, the dxf shows such text:

  0
SECTION
  2
ENTITIES
  0
SOLID
  5
2D
  8
0
 10
150.0
 20
250.0
 30
0.0
 11
160.0
 21
250.0
 31
0.0
 12
150.0
 22
270.0
 32
0.0
 13
160.0
 23
270.0
 33
0.0

To draw a normal rectangle, at least we need two points, which is the first point (150,250)( (x, y)), and the fourth point(160, 270)((x + width, y + height)).

Here are some reference: Solid — ezdxf 0.11.1 documentation

Help: SOLID (DXF)

JamesBremner commented 4 years ago

As always, the DXF documentation establishes the format of the code-value pairs in a DXF entity, but leaves it up to implementation to decide the meaning of the values. I have seen all sorts of different interpretations of SOLID entities, all the way up to 3D triangular meshes.

I have chosen a very simple interpretation that serves my current purposes, visualizing the results of a 2d packing engine used to cut plywood panels from larger plywood sheets ( https://github.com/JamesBremner/pack2 ) I have added code documentation describing this interpretation ( bc51ec0bf00ae295d6c3bb260bfd2b236f3fdc9e )

What is your purpose for using DXF-Viewer?

If you wish to contribute a different SOLID entity parser, perhaps along with a different drawing method, please let me know and I will add some infrastructure to switch between parsers.

xubury commented 4 years ago

I think we do need all four points to have a universal result for SOLID. Because it looks like SOLID is designed to parse with three vertices(triangle) as a stride and a index list of [0,1, 2, 1, 2, 3]. See the image below QQ截图20200313215750 And as the doc describes, Fourth corner. If only three corners are entered to define the SOLID, then the fourth corner coordinate is the same as the third. So maybe there's even no need to switch parser between rectangle and triangle.

JamesBremner commented 4 years ago

I think we do need all four points to have a universal result for SOLID.

No such thing is possible. There are many different interpretations of the DXF format out there. You will have noticed that when you use different viewers for a DXF file, some will render it correctly and others will be confused. Each generator and viewer pair need to decide and agree on what they want to do. There is no such thing as a universal DXF Viewer capable of correctly rendering every DXF file.

asmwarrior commented 4 years ago

What is your purpose for using DXF-Viewer?

Mostly, interests.

I used the DXF_Viewer in a wxWidgets based project to show a 2D DXF file. The project does not need to show the SOLID entity. But as I see you have added this SOLID support, I think we should make the SOLID support feature rich. I have tested the DXF_Viewer to show the test dxf file in https://github.com/JamesBremner/DXF_Viewer/blob/master/dxf/HFP1JZ.dxf ,and I see that HFP1JZ.dxf contains triangle arrows which is SOLID type, but current implementation of the DXF_Viewer does not support it.

If you wish to contribute a different SOLID entity parser, perhaps along with a different drawing method, please let me know and I will add some infrastructure to switch between parsers.

I think at least 3 points and 4 points SOLID 2D entity is needed, and hope I can contribute to it.

JamesBremner commented 4 years ago

OK, I will add infrastructure to enable different SOLID parsers.

JamesBremner commented 4 years ago

image

I have left you to actually implement the parsers!

asmwarrior commented 4 years ago

2020-03-15 14 15 54 This is the result if I open the solid.dxf in this issue and with my pull request https://github.com/JamesBremner/DXF_Viewer/pull/25

JamesBremner commented 4 years ago

I have added your solid.dxf to the repo, renamed solidtid23.dxf

Are you working on this?

asmwarrior commented 4 years ago

Are you working on this?

Not yet, but I will do it in the next days. I'm considering the condition that a solid may have either:

So, I may need a counter to remember how many points we have parsed.

JamesBremner commented 4 years ago

Please do not do it that way.

IfmyParser == eParser::solid_2point then 2 point solids are expected, if myParser == eParser::solid_4point the 4 point solids are expected.

Add a case to https://github.com/JamesBremner/DXF_Viewer/blob/abefc7a8be3220f3fd8425a7072d08af06411b25/src/Solid.cpp#L52

asmwarrior commented 4 years ago

Please do not do it that way.

IfmyParser == eParser::solid_2point then 2 point solids are expected, if myParser == eParser::solid_4point the 4 point solids are expected.

Add a case to

https://github.com/JamesBremner/DXF_Viewer/blob/abefc7a8be3220f3fd8425a7072d08af06411b25/src/Solid.cpp#L52

OK, pull request is created, see here: https://github.com/JamesBremner/DXF_Viewer/pull/26

JamesBremner commented 4 years ago

I have refactored the SOLID parser slightly to make it clearer what the while loop was doing ( since I confused myself over that! ) and updated the documentation

https://github.com/JamesBremner/DXF_Viewer/blob/7de47652ca159b8d7c409d291741451582ce3991/src/Solid.h#L28-L47

Perhaps you could add documentation for your 4-point parser?

asmwarrior commented 4 years ago

I have refactored the SOLID parser slightly to make it clearer what the while loop was doing ( since I confused myself over that! ) and updated the documentation

https://github.com/JamesBremner/DXF_Viewer/blob/7de47652ca159b8d7c409d291741451582ce3991/src/Solid.h#L28-L47

Perhaps you could add documentation for your 4-point parser?

See this pull request: document the 4-point parser of the solid by asmwarrior · Pull Request #27 · JamesBremner/DXF_Viewer

JamesBremner commented 5 months ago

Is there a reason this issue is still open?

asmwarrior commented 5 months ago

Is there a reason this issue is still open?

Hi, thanks. I'm still using this library. I think this feature request can be closed. Because it is implemented.

JamesBremner commented 5 months ago

Good to know you still find this useful. It seems a relatively mundane app but apparently gets more users than anything else I have.

asmwarrior commented 5 months ago

One thing I like to mention is that when I export dxf file from autocad or other tool, this library can not handle dxf files contains splines. This is a big issue I see those years.

JamesBremner commented 5 months ago

Please open an issue for this and provide a small, simple example of a DXF file that fails. Ensure that you do NOT have SPLINE with fit AND control points.