Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Parsing a dxf file to extract coordinate data from obscure entities 1

Status
Not open for further replies.

Bminer

Technical User
Aug 28, 2012
16
US
Greetings,

I work with topographical cad files which normally contain well behaved polyline entities (2d, 2d with elevation and 3d linework). Most of the tools I have deal with these various entities. However, I often run across older cad files that contain polymesh entities. These rascals have been almost impossible to deal with. Upto this point, I have been redigitizing the linework using a 2d with elevation line. Very time consuming and not exact.

After messing around with these entities trying different approaches, I found that if I expost these entities to a DXF file, all the vertex data is found in a well behaved manner.

What I plan on doing is to export the offending entities to a DXF (nothing else included) then parse the file and creating a data line containing the data set for each vertex then placing each data line in a text file. I will ignore anything else in the dxf file.

In the dxf file, the data of interest consists of 22 lines and a sample is as follows
VERTEX
5
75
330
74
100
AcDbEntity
8
MINOR
100
AcDbVertex
100
AcDbPolyFaceMeshVertex
10
1262334.232859563
20
687059.6123241198
30
0.0
70
192
0

I want this to be paced in a text file like so

VERTEX,5,75,330,74,100,AcDbEntity,8,MINOR,100,AcDbVertex,100,AcDbPolyFaceMeshVertex,10,1262334.23285956,20,687059.612324119,30,0,70,192,0

From here, I can manipulate this as I like either using a spreadsheet or other tools available.

I have been playing with code to do this and have been wildly unsuccessfull.

Code:
set fi [open data_files\\strings_dtms\\topos\\1998\\polymesh.dxf "r"]
set fo  [open tempwrite.str "w"]

set a "VERTEX"
while {[gets $fi line] >= 0} {if {$a == $line} { {set var 0} {for {set i 1} {$i<=22} {incr $i} {{append $var "," $fi}{gets $fi line}}}{puts $fo $var}} else {gets $fi 

line}}


close $fi
close $fo

Please be kind. My programming skills are rudimentary although I aspire to better....

Any thought, comments and or corrections are appreciated.

Brian
 
Something like this
Code:
[COLOR=#804040][b]set[/b][/color] fi [[COLOR=#804040][b]open[/b][/color] [COLOR=#ff00ff]"polymesh.dxf"[/color] [COLOR=#ff00ff]"r"[/color]]
[COLOR=#804040][b]set[/b][/color] fo [[COLOR=#804040][b]open[/b][/color] [COLOR=#ff00ff]"tempwrite.str"[/color] [COLOR=#ff00ff]"w"[/color]]

[COLOR=#804040][b]set[/b][/color] k [COLOR=#ff00ff]0[/color]
[COLOR=#804040][b]set[/b][/color] out_line {}
[COLOR=#804040][b]while[/b][/color] {! [[COLOR=#804040][b]eof[/b][/color] [COLOR=#008080]$fi[/color]]} {
[COLOR=#0000ff]  # read line from file[/color]
  [COLOR=#804040][b]set[/b][/color] line [[COLOR=#804040][b]gets[/b][/color] [COLOR=#008080]$fi[/color]]
[COLOR=#0000ff]  # remove leading and trailing spaces[/color]
  [COLOR=#804040][b]set[/b][/color] line [[COLOR=#804040][b]string[/b][/color] trim [COLOR=#008080]$line[/color]]
  [COLOR=#804040][b]if[/b][/color] {[COLOR=#008080]$line[/color] != {}} {
    [COLOR=#804040][b]incr[/b][/color] k
[COLOR=#0000ff]    #puts "'$line'"[/color]
    [COLOR=#804040][b]if[/b][/color] {[COLOR=#008080]$k[/color] == [COLOR=#ff00ff]1[/color]} {
      [COLOR=#804040][b]set[/b][/color] out_line [COLOR=#ff00ff]"$line"[/color]
    } [COLOR=#804040][b]else[/b][/color] {
      [COLOR=#804040][b]set[/b][/color] out_line [COLOR=#ff00ff]"$out_line,$line"[/color]
    }
  }
}

[COLOR=#0000ff]#puts "$out_line"[/color]

[COLOR=#0000ff]# write to output file[/color]
[COLOR=#804040][b]puts[/b][/color] [COLOR=#008080]$fo[/color] [COLOR=#ff00ff]"$out_line"[/color]

[COLOR=#804040][b]close[/b][/color] [COLOR=#008080]$fi[/color]
[COLOR=#804040][b]close[/b][/color] [COLOR=#008080]$fo[/color]
 
Thanks for the suggestion mikrom,

I plugged your code in and appear to be getting an endless loop (ran 5 minutes) After killing the run, the temp file had nothing in it.

Not sure what it occuring.

Brian
 
I tried the script and it worked fine. I used this input file:
polymesh.dxf
Code:
VERTEX
5
75
330
74
100
AcDbEntity
8
MINOR
100
AcDbVertex
100
AcDbPolyFaceMeshVertex
10
1262334.232859563
20
687059.6123241198
30
0.0
70
192
0
and it created this output file:
tempwrite.str
Code:
VERTEX,5,75,330,74,100,AcDbEntity,8,MINOR,100,AcDbVertex,100,AcDbPolyFaceMeshVertex,10,1262334.232859563,20,687059.6123241198,30,0.0,70,192,0
 
Ah,

I think I know the disconnect. In the file I am parsing, it contains sometimes several thousand lines. Each group of lines (as few as 4 and as many at 30+) are identified by a entity type. As mentioned, I am only interested in the entity type "VERTEX" which when found contains 21 additional lines of detail. The snippet I put in that you used for the data file contains one instance of "VERTEX". I need to ignore all occurances of other entities and only record the details when "VERTEX" is found. When I run the your code, it it attempting to place the entire file on a single line and is probably the reason for the hanging of the process.

The output you generate is exactly what I want for each instance of "VERTEX". How do i search through the file for VERTEX, then execute this code on the following 21 lines, saving the stransposed dataset to the tempwrite file then continue searching the file for the next VERTEX instance?

Thanks for your help so far.

Brian
 
Finally getting back to this and tried another stab using Mikrom's code.


Code:
set fi [open data_files\\strings_dtms\\topos\\1998\\polymesh.dxf "r"]
set fo  [open tempwrite.str "w"]

set a "VERTEX"
#target entity to search for
set out_line {}

while {! [eof $fi]} {
  # read line from file
  set line [gets $fi]
  # remove leading and trailing spaces
  set line [string trim $line]

  if { $line = $a } {
      set k 0
      set out_line "$line"
      while { k < 22 } {
         set out_line "$out_line,[string trim [gets $fi]]"
         incr k
            }
      puts $line $fo
   }
}

In the if statement, testing to see if the line = the target entity. TRUE - Process subsequent 21 lines into out_line FALSE - read next line and retest

here is the error message

TCL Error Message said:
Warning: Tcl generated error at line 20:
syntax error in expression " line = $a "
while executing
"if { $line = $a } {
set k 0
set out_line "$line"
while { k < 22 } {
set out_line "$out_line,[string trim [gets $fi]]"
..."
("while" body line 6)
invoked from within
"while {! [eof $fi]} {
# read line from file
set line [gets $fi]
# remove leading and trailing spaces
set line [string trim $line]
if { line ..."
(file "macro_files\utility\polymesh_dxf_vertex_extract - copy.tcl" line 20)
invoked from within
"default_source "macro_files\\utility\\polymesh_dxf_vertex_extract - copy.tcl""

I somehow malformed the condition test. I also tried { line = a}, {= [ line a]}, {$line = a } and a few other variations before posting.


Thoughts, suggestions, dopeslaps?

Brian
 
Now I hope I understand better what you need ...

Ginen is an input file
polymesh.dxf
Code:
VERTEX
5
75
330
74
100
AcDbEntity
8
MINOR
100
AcDbVertex
100
AcDbPolyFaceMeshVertex
10
1262334.232859563
20
687059.6123241198
30
0.0
70
192
0
something else
skip
skip
VERTEX
6
75
330
74
100
AcDbEntity
8
MINOR
100
AcDbVertex
100
AcDbPolyFaceMeshVertex
10
1262334.232859563
20
687059.6123241198
30
0.0
70
192
1

other data
other data


VERTEX
7
75
330
74
100
AcDbEntity
8
MINOR
100
AcDbVertex
100
AcDbPolyFaceMeshVertex
10
1262334.232859563
20
687059.6123241198
30
0.0
70
192
2

Now this script
Bminer.tcl
Code:
[COLOR=#804040][b]set[/b][/color] fi [[COLOR=#804040][b]open[/b][/color] [COLOR=#ff00ff]"polymesh.dxf"[/color] [COLOR=#ff00ff]"r"[/color]]
[COLOR=#804040][b]set[/b][/color] fo [[COLOR=#804040][b]open[/b][/color] [COLOR=#ff00ff]"tempwrite.str"[/color] [COLOR=#ff00ff]"w"[/color]]

[COLOR=#804040][b]set[/b][/color] vertex_found [COLOR=#ff00ff]0[/color]
[COLOR=#804040][b]set[/b][/color] out_line {}
[COLOR=#804040][b]while[/b][/color] {! [[COLOR=#804040][b]eof[/b][/color] [COLOR=#008080]$fi[/color]]} {
[COLOR=#0000ff]  # read line from file[/color]
  [COLOR=#804040][b]set[/b][/color] line [[COLOR=#804040][b]gets[/b][/color] [COLOR=#008080]$fi[/color]]
[COLOR=#0000ff]  # remove leading and trailing spaces[/color]
  [COLOR=#804040][b]set[/b][/color] line [[COLOR=#804040][b]string[/b][/color] trim [COLOR=#008080]$line[/color]]
  [COLOR=#804040][b]if[/b][/color] {[COLOR=#008080]$line[/color] == [COLOR=#ff00ff]"VERTEX"[/color]} {
    [COLOR=#804040][b]set[/b][/color] vertex_found [COLOR=#ff00ff]1[/color]
    [COLOR=#804040][b]set[/b][/color] k [COLOR=#ff00ff]0[/color]
[COLOR=#0000ff]    #puts "'$line'"[/color]
    [COLOR=#804040][b]set[/b][/color] out_line [COLOR=#ff00ff]"$line"[/color]
[COLOR=#0000ff]    # next iteartion[/color]
    [COLOR=#804040][b]continue[/b][/color]
  }
  [COLOR=#804040][b]if[/b][/color] {[COLOR=#008080]$vertex_found[/color]} {
    [COLOR=#804040][b]incr[/b][/color] k
    [COLOR=#804040][b]if[/b][/color] {[COLOR=#008080]$k[/color] <= [COLOR=#ff00ff]21[/color]} {
[COLOR=#0000ff]      #puts "'$line'"[/color]
      [COLOR=#804040][b]set[/b][/color] out_line [COLOR=#ff00ff]"$out_line,$line"[/color]
    } [COLOR=#804040][b]else[/b][/color] {
[COLOR=#0000ff]      # write to output file[/color]
[COLOR=#0000ff]      #puts $out_line[/color]
      [COLOR=#804040][b]puts[/b][/color] [COLOR=#008080]$fo[/color] [COLOR=#ff00ff]"$out_line"[/color]
      [COLOR=#804040][b]set[/b][/color] vertex_found [COLOR=#ff00ff]0[/color]
    }
  }  
}

[COLOR=#804040][b]close[/b][/color] [COLOR=#008080]$fi[/color]
[COLOR=#804040][b]close[/b][/color] [COLOR=#008080]$fo[/color]

produces this output file
tempwrite.str
Code:
VERTEX,5,75,330,74,100,AcDbEntity,8,MINOR,100,AcDbVertex,100,AcDbPolyFaceMeshVertex,10,1262334.232859563,20,687059.6123241198,30,0.0,70,192,0
VERTEX,6,75,330,74,100,AcDbEntity,8,MINOR,100,AcDbVertex,100,AcDbPolyFaceMeshVertex,10,1262334.232859563,20,687059.6123241198,30,0.0,70,192,1
VERTEX,7,75,330,74,100,AcDbEntity,8,MINOR,100,AcDbVertex,100,AcDbPolyFaceMeshVertex,10,1262334.232859563,20,687059.6123241198,30,0.0,70,192,2
 
Mikrom,

That is the ticket! Thanks for your help. It is doing exactly what I need. No I can get on with breaking up these pesky entities and eliminate all the extra work I was doing.

Brian
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top