Shape Files: Import & Export Blender Meshes

Talk about your new mod or map here

Moderators: bert_the_turtle, jelco

Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Shape Files: Import & Export Blender Meshes

Postby brice » Sat Apr 28, 2007 9:30 pm

Hi all, I've been busy hacking all the shape files in Darwinia. (Well, except for the trunkports and goddishes and a few other venerable and iconic things.) I've built most of my models from the fragments in the original game models. Mix-n-match & scale. Most of my work has been done using spreadsheets to adjust coordinates. I'm recycling and I'm trying to keep the low-poly aesthetic.

One thing that's helped me is a perl script which ripped all the fragments and placed them in a nice grid level so I could browse and do mockups. I'll give you that script below. I also needed a few geometric shapes which weren't anywhere in the original game, mods, or the free shapes posted by people like cyberdyne and micr0chip. For that I've figured out how to get Blender to export useful vertex and triangle list data. Blender is a free, open source modelling program available for all platforms. I'll tell you what little I know.

Let's start with Blender. I don't have a direct Blender --> .shp exporter, although that would be simple to do if you know Python since Blender has an embeded Python scripting engine. I was looking to see which existing export formats would have useful vertex and triangle lists, so I tried 'em all. In Blender 2.43 you can export a mesh to a SoftImage XSI file, and with a few simple text edits you can paste the data into an existing .shp file and be done. Very simple.

I don't know much about the magic of Blender, but I'll walk you through getting an icosohedron into a .shp file. Launch Blender and select Add > Mesh > IcoSphere and click the popup button down to 1 "Subdivision". You'll see a tiny mesh appear inside the starter cube. You could scale and edit the mesh. If you do, you will be in "Edit Mode". Before you can export the XSI format you must always remember to return to "Object Mode". There are sveral ways to do this -- a dropdown selector appears along the bottom edge of the viewport.

For kicks, let's scale the icosohedron. New meshes start out at unit size, so they'll be tiny in Darwinia. With the cursor in the viewport hit the "S" key and drag the mouse. The amount of scaling available depends on the relative positions of the mouse and selected object when you hit the "S" key. You can always undo mesh edits with the "U" key, but again, be sure the cursor is inside the viewport. Blender uses all the mouse buttons in context sensitive combinations. It's confusing at first. But since we spent all of 3 seconds creating this mesh, do as I did and choose File > New whenever you get into a bind. Read the Blender Quick Start Tutorial, it's good.

Once back in Object Mode, choose File > Export > SoftImage XSI and work the file dialog to put the file where you want it. We're done with Blender. Fire up your favorite text editor and load both the .xsi file and a .shp file. Your life will be easier if you start with a large .shp fragment. The one I like to use is the sphere out of micr0chip's engineer model (google "darwinia micr0chip" with a zero in the name.) It has >400 vertices and all the vertex mappings and colours are in numerical order. This means we can simply paste in our Blender data and tidy up. The .xsi verices are all in order, and the triangle lists use them in order.

So you're looking at the .xsi text file and the vertex coordinates are in a section that looks like this:

Code: Select all

      SI_Mesh MSH-Sphere {
         SI_Shape SHP-Sphere-ORG {


You can cut and paste the coordinate list into the Positions list in your .shp file and then type the "1:" "2:" etc. in front of each line. Or if your editor supports block selections you can clear the coords from the .shp file and then paste the coords into the rectangular area after the position numbers. The total number of Positions is the "12" just above the word "POSITION" in the .xsi file. The Vertices list takes the same count.

If you chose to start with cyberdyne's sphere fragment, then you can simply edit the Vertices list to the right length. The .xsi data is all used in-order. Otherwise you can use block select to make two copies of your position numbers and then add the colour index column by hand.

And finally for the triangle list, you' see the following section in the .xsi file:

Code: Select all

         SI_TriangleList Sphere {


Just cut and paste into the Triangles section of your .shp and use the "20" count listed above the word "NORMAL". You only want the first block of triangle tuples. The second block (not shown here) is pretty useless.

[There's only two things left to do.] EDIT: Darwinia is perfectly happy with the trailing commas everywhere, and the comma delimited coordinate list, so there is nothing else to do. Just cut & paste! So skip this: [First you need to search and replace the commas in the coordinate data. Darwinia uses whitespace separators. Second you need to remove all the trailing commas from the triangle list. You can do this by hand, or if your editor supports regular expressions, you can do something like ",$" --> "" where the quotes are not to be typed in.]

If your shape file crashes Darwinia, check that you properly set all the counts at the beginning of the Positions:, Vertices: and Triangles: sections. I always forget to set the Vertices count because of the way I go about this.

Also note that the .xsi file will have a section called "Cube". This is the annoying little cube that appears in every new Blender scene. If you made a complex scene there would be one section for every Object you created. There is probably a way to merge objects in Blender so they produce a single triangle list when exported. I don't know how. I only wanted a few simple things.

You're done! As you can see the steps for taking an .xsi export file and producing a .shp file are pretty trivial. I'm sure a perl script could be hacked together in a few minutes. Or a python exporter for use from within Blender. If anyone gets ambitious, please share!

Here's the final icosahedron shape file:

Code: Select all

Fragment: Icosahedron
   ParentName: sceneroot
   up:     0.00  1.00  0.00
   front:  0.00  0.00  1.00
   pos:    0.00 20.00 0.00
   Positions:  12
      0:    0.000000  -0.000000  -9.902285     
      1:    7.165293  -5.205829  -4.428450     
      2:    -2.736843  -8.423280  -4.428450     
      3:    -8.856851  -0.000000  -4.428450     
      4:    -2.736843  8.423280  -4.428450     
      5:    7.165293  5.205829  -4.428450     
      6:    2.736843  -8.423280  4.428450     
      7:    -7.165293  -5.205829  4.428450     
      8:    -7.165293  5.205829  4.428450     
      9:    2.736843  8.423280  4.428450     
      10:  8.856851  -0.000000  4.428450     
      11:  0.000000  -0.000000  9.902285     
   Normals: 0
   Colours: 1
      0: 128  128  128
   Vertices: 12
      0: 0 0
      1: 1 0
      2: 2 0
      3: 3 0
      4: 4 0
      5: 5 0
      6: 6 0
      7: 7 0
      8: 8 0
      9: 9 0
      10: 10 0
      11: 11 0
   Triangles: 20

EDIT: Blender and Darwinia apparently use different axis orientations. If you want the shape to appear in the same orientation as in Blender, replace the fragment header with the following:

Code: Select all

Fragment: Icosahedron
   ParentName: sceneroot
   up:     0.00  0.00  1.00
   front:  0.00  1.00  0.00
   pos:    0.00 20.00 0.00

OK, now for the perl script which extracts fragments from existing .shp files:

Code: Select all


@shpfiles = <*.shp>;

$i = 0;

open LISTFILE, ">", "shapelist.txt";

foreach $shpfile (@shpfiles) { if (not $shpfile =~ /zfrag/) {

   open INFILE, "<", $shpfile;
                   local $/; #slurp mode
                   $shp = <INFILE>;
           } #exit local slurp mode
   close INFILE;

   #for Windows machines, comment this line out!!
   $shp =~ s/\r//g;
   #for Windows machines, comment this line out!!
   $shp .= "\nEOF\n"; # to catch last frag
   @frags = $shp =~ /Fragment .*? (?=^\w)/xgmsi;
   foreach $frag (@frags) {
      $frag =~ /\s+ Positions (.*?) (?=^\s+ Normals)/xgmsi;
      $coords = $1;
      @xcoords = $coords =~ /\d+: \s+ (\-?\d+\.?\d*) \s+  \-?\d+\.?\d*  \s+  \-?\d+\.?\d* /gx;
      @ycoords = $coords =~ /\d+: \s+  \-?\d+\.?\d*  \s+ (\-?\d+\.?\d*) \s+  \-?\d+\.?\d* /gx;
      @zcoords = $coords =~ /\d+: \s+  \-?\d+\.?\d*  \s+  \-?\d+\.?\d*  \s+ (\-?\d+\.?\d*)/gx;
      if ($#xcoords == -1 or $#ycoords == -1 or $#zcoords == -1 ) {
         print "dropped frag from $shpfile : no coords\n";

      $min = 9999; $max = -9999;
      foreach $c (@xcoords) {
         $min = $c if $c < $min; $max = $c if $c > $max;
      }   $spanx = $max - $min;
      $min = 9999; $max = -9999;
      foreach $c (@ycoords) {
         $min = $c if $c < $min; $max = $c if $c > $max;
      }   $spany = $max - $min; $miny = $min;
      $min = 9999; $max = -9999;
      foreach $c (@zcoords) {
         $min = $c if $c < $min; $max = $c if $c > $max;
      }   $spanz = $max - $min;
      #print "$spanx  $spanz ($shpfile)\n";
      $maxspan = $spanx < $spanz ? $spanz : $spanx;
      $maxspan = $spany < $maxspan ? $maxspan : $spany;
      if ($maxspan == 0) {
         print "dropped frag from $shpfile : zero span\n";
      $scale = 100 / $maxspan;
      if ($scale > 100) { $scale = 100; }

      $cx = 0; $cy = 0; $cz = 0;
      foreach $c (@xcoords) { $cx += $c }
      foreach $c (@ycoords) { $cy += $c }
      foreach $c (@zcoords) { $cz += $c }
      $cx = -($cx / ($#xcoords + 1)) ;
      $cz = -($cz / ($#zcoords + 1)) ;
      $cy = -($cy / ($#ycoords + 1)) + (-$miny + 100) / $scale;

      $cx = sprintf "%.3f", $cx;
      $cy = sprintf "%.3f", $cy;
      $cz = sprintf "%.3f", $cz;
      $frag =~ s/ParentName: \s+ .*/ParentName: sceneroot/xm;
      $frag =~ s/^\s+ up:    .*/\t up:     0.00  1.00  0.00/xm;
      $frag =~ s/^\s+ front: .*/\t front:  0.00  0.00  1.00/xm;
      $frag =~ s/^\s+ pos:   .*/\t pos:    $cx  $cy  $cz   /xm;
      $fragshp = "zfrag$i.shp";
      open OUTFILE, ">", $fragshp;
      print OUTFILE $frag, "\n\n";
      $x = 500 + 140 * ($i % 28);
      $z = 500 + 140 * int($i / 28);
      $scale = sprintf "%.3f", $scale;
      print LISTFILE "\t  StaticShape  $i  $x  $z  1  0.00 0.00  0  $scale  $fragshp \n";

First off, I am not a professional programmer, or even a good one. This is just code that works for me. You're free to clean it up if you like. If it's broken, I'll try to help you get it working.

To use this, place it in a subdirectory with all your shape files. Please do me and yourself a favor: make a copy of all your shapes in a new subdirectory. Then run "perl" there, with no arguments. It will scan all the .shp files in the current working directory and do two things. It will output one shape file for each fragment it finds. These will be called "zfrag000", etc. And it will output a file called "shapelist.txt" which contains StaticShape lines for your map file. Just cut and paste.

The program assumes your map will be 5000 x 5000. You don't need any land tiles since the fragments will be positioned to float in space. Each fragment is scaled to fit the nice grid, so tiny fragments will appear huge and huge fragments kinda small. There are a few fragments which appear way up in the air. I never figured out what was wrong with my spaghetti code. AND there are some homemade shapes that the program cannot parse. I think Trickfred's mushroom is one. These just get discarded from the fragments list.

***IF YOU ARE USING WINDOWS: you must comment out the line that says so near the beginning of the script file. (Place a # in front of it, just like the lines around it.) I'm using linux and the end-of-line conventions differ. If your zfrag000.shp files are all on one line in your text editor... you didn't comment out this line, and you need to.

That's it for now. Happy modding!
Last edited by brice on Wed May 02, 2007 4:55 pm, edited 5 times in total.
Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Postby brice » Wed May 02, 2007 1:03 am

...Unfortunately Blender can't re-import Softimage XSI files. So the above export method is a one way street. However there is another very simple file format which Blender can both export and import: DEC Object File Format (.off). There are a few caveats, but this format would make a good basis for a .shp conversion script -- one step short of a real import / export python script for Blender. I'm not going to write that script, but I'll show you how the DEC .off files work. They're even simpler than the .xsi files.

Here's the *entire* .off for the little starter cube that begins every Blender scene:

Code: Select all

8 12 0
1.000000 1.000000 -1.000000
1.000000 -1.000000 -1.000000
-1.000000 -1.000000 -1.000000
-1.000000 1.000000 -1.000000
1.000000 0.999999 1.000000
0.999999 -1.000001 1.000000
-1.000000 -1.000000 1.000000
-1.000000 1.000000 1.000000
3 7 0 4
3 7 3 0
3 7 6 2
3 3 7 2
3 2 5 1
3 2 6 5
3 1 4 0
3 1 5 4
3 6 7 4
3 5 6 4
3 2 1 0
3 3 2 0

Pretty obvious what's what. The first two numbers below "OFF" are the vertex / position count followed by the triangle count. I don't know what the third number is. Below that is the coordinate list, which is whitespace delimited, just like .shp files. Cut and paste into your Positions list.

Last comes the polygon list. The first number of each line tells how many vertices in that polygon. Since every line here starts with a "3", this is a list of triangles. This is where the first caveat comes in. If you simply openned up Blender and exported the little starter cube, you wouldn't get the triangle list above. You'd get a quadrilateral list where every line started with a "4". Darwinia shape files can't use that. So you have to manually tell Blender to switch your mesh to triangles only. In Edit Mode you select everything and then go to Mesh > Faces > Convert Quads to Triangles. Then when you export you get the triangle list shown above. You can leave your mesh in triangles, but your cube will no longer look quite as "cubey". Just remember to convert to triangles before exporting to DEC .off format. Some of Blender's edits may create quads instead of triangles. You'll see the "4"s in your .off file.

The second caveat is about how the exporter works. It is a very very simple exporter. It only exports the mesh for the currently selected Object. That's all it knows how to do. So if you have several objects in a scene you will either have to export them one at a time, or you will have to join them. If you select more than one Object in Object Mode you can go to Object > Join Objects. I don't know if you can easily undo this, so plan ahead and experiment with your workflow before modelling something huge.

Obviously importing is as simple as copying out the coordinate list and the triangle list from a .shp file and then adding the few details the DEC .off format requires. You need the two header lines, and you need to prefix every line of the triangle list with a "3". [For both importing and exporting you will have to search and replace the delimiiters in the triangle list -- DEC .off uses spaces, while .shp files use commas.] EDIT: Darwinia is perfectly happy with either commas or whitespace in both coordinate lists and triangle lists. Trailing commas are OK too. So just cut & paste.

EDIT: Importing is not that simple because Darwinia remaps the vertices in some odd way. See two posts down... does anyone understand it?

Overall, for exporting just a few meshes, the DEC .off format is about as easy as the Softimage XSI format described in my first post. But you can go back and forth with DEC .off. You can even paste existing Darwinia shape file data into DEC .off files if you want to start from there and tweak them.

That's it! Import and export on the cheap, for use with a free modelling program.
Last edited by brice on Wed May 02, 2007 9:30 pm, edited 1 time in total.
Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Postby brice » Wed May 02, 2007 5:07 pm

...It turns out Darwinia is perfectly happy with either whitespace or comma delimiters in shape files. This applies to both coordinate lists and triangle lists (and probably everything, although I haven't checked). Trailing commas are OK too. So if you get data out of Blender or some other modelling package, just try pasting it in. Darwinia might accept it without reformatting and/or replacing the delimiters. One thing you can't do is have blank lines in your triangle list. Blank lines are OK everywhere else.

I edited the above posts, but thought this info was useful enough to highlight.

Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Postby brice » Wed May 02, 2007 10:05 pm

(sorry, xander, I've make a blog of this thread)

...In order to paste a .shp file's coordinate list (Positions) into a DEC .off file, they must first be reordered so the vertices are in numerical order. At first this seemed straightforward. But it isn't.

I wrongly imagined that the Vertices list was a simple remapping of Position numbers to Vertex numbers. The Triangles list then uses the Vertex numbers. If this were the case, then a simple sort in a spreadsheet would be a quick way to reorder the data from one of the original game shapes:

Code: Select all

  A         B        C                 D         E        F      
0.00      0.73     0.00                0:        0        0 
34.16     0.73     0.00                1:        2        0 
17.08     0.73     -29.58              2:        1        0 
-17.08    0.73     -29.58              3:        3        0 
-34.16    0.73     0.00                4:        4        0 
-17.08    0.73     29.59               5:        5        0 
17.08     0.73     29.59               6:        6        0 
34.16     21.59    0.00                7:       80        0 
17.08     21.59    -29.58              8:       87        0 
-17.08    21.59    -29.58              9:       86        0 
-34.16    21.59    0.00                10:      81        0 
-17.08    21.59    29.59               11:      69        0 
17.08     21.59    29.59               12:      76        0 
0.00      50.00    0.00                13:      75        0 
73.55     0.61     -32.11              14:      70        0 
64.58     0.61     -47.64              15:      82        0 
-64.58    0.61     -47.64              16:      89        0 
-73.55    0.61     -32.11              17:      88        0 
-8.97     0.61     79.75               18:      83        0 
8.97      0.61     79.75               19:      71        0 
73.55     7.80     -32.11              20:      78        0

This is unsorted data from generator.shp, pasted into a spreadsheet. The coordinate list is in columns A-C, and the Vertices list is in columns D-F. If the Vertices list were a simple remapping you could sort the data by column E and then the Positions would be in vertex order. That's what is needed for pasting into the DEC .off format.

But using the sorted Positions results in a jumbled mess of triangles. And it's not Blender's fault. If I edit the original generator.shp to use the sorted Positions I get the same jumble in Darwinia. When using the sorted list I should be able to use a straightforward Vertices list where every line is "n: n 0". Apparently it doesn't work that way.

So the Darwinia Vertices list is doing something more complex than simply renaming the Positions. It seems to be reordering the triangle references too. Does anyone understand it? If I -- or anyone else -- ever write an import / export module for Blender (or a perl .shp <--> .off coverter) we will need to understand the Vertices list. Otherwise it won't be possible to import the existing game shapes to edit. Not a big loss, but mildly annoying. It's nice to keep some of the look and feel of the original by recycling the shape fragments. Remodelling would be easier if fragments could be imported. Unfortunately Blender can't import the IV .max files.

Hopefully someone here understands the Vertices remapping... xander?
User avatar
Posts: 428
Joined: Mon Jan 02, 2006 8:03 pm
Location: Atlanta, Georgia

Postby Lowell » Thu May 03, 2007 6:11 am

This is just awesome...I just downloaded that version the other week for building/editing train engines and train cars for import to a couple games. I also picked up a student version of Max, but that is the new version...still no plugin yet for .shp from them. However I am going to give this a try on my new "Fuel" level models. This will be great.

Thanks again for all the brain work... :)
Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Postby brice » Thu May 03, 2007 10:43 am


Until someone figures out the vertex remapping in shape files, there is a round-about way to get Darwinia .shp fragments into Blender. You can use a DEC .off file to import just the vertices / positions, and then you can rebuild the faces by hand. For most Darwinia shapes this is pretty simple to do because they are so low-poly. If there is a spin symmetry you only have to rebuild one part and then you can use Blender's "spin dup" operation to copy it while rotating. I did that for the SpawnPoint bowl.

To get coordinate info into Blender, just make a DEC .off file with zero triangles. Simply cut and paste the Positions list in the existing order. The header line will read "#verts 0 0". When you go to Edit Mode you can select 3s and 4s of vertices and use the FKEY to rebuild the faces. It took me less than 10 min to rebuild the SpawnPointMaster in Blender this way ... quicker than trying to figure out the Vertices remapping issue.

I'm still hoping xander knows something about the Vertices list. He's built the most shapes by hand, I think. Paperwinia is very impressive. xander?
User avatar
The GoldFish
Posts: 3961
Joined: Fri Mar 01, 2002 9:01 pm
Location: Bowl / South UK

Postby The GoldFish » Thu May 03, 2007 11:13 am

OK uhm, is that going to result in;

0: 0
1: 1
2: 2



for the first 3 values of that?
And are those vertex numbers OBSERVED when they're imported?

if the former, or they are not observed and it's taken automatically concectuvily as they're loaded, then, the vertexes referenced in the triangles list are getting mapped to the wrong vertex - If vert 1 is getting changed to be pos 1 instead of pos 2, then the triangle including vert 1 isn't going to be working from the right position, resulting in a mess of triangles. (which you're getting) - this is just a theory at any rate, I have no idea how to test it.

You might be able to get around this in excel fairly easily by getting a formula to work out what number you add to E to get to D, then using a lookup table to get that number and then apply it to whichever value is found in the triangles section

That way you reorder the the positions into the order they're shown in the vertex list, the vertex listing is a direct mapping, so 0:0, 1:1, etc, and every reference, and in the case of having 1:5 originally, all references to 5 are subtracted by 4 to read 1 in the triangles list, 1:1, and position 5 is shifted up to be position 1.

That should fix the issue... probably!
Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Postby brice » Thu May 03, 2007 11:38 am

The GoldFish wrote:OK uhm, is that going to result in;

0: 0
1: 1
2: 2



[ ... ] That should fix the issue... probably!

You're right! I'm missing a lookup with my cheap sort! It did seem too good to be true, but that's what hapens when I don't do stuff out longhand on paper... like I just did, and realized my sort doesn't do what I thought it would. (Although it sounds plausible!)

I'll go look through the spreadsheet formulas for a simple lookup thingie, and I'll post something that really works next time.

User avatar
The GoldFish
Posts: 3961
Joined: Fri Mar 01, 2002 9:01 pm
Location: Bowl / South UK

Postby The GoldFish » Thu May 03, 2007 11:52 am

Actually, having played around, I think you need to take the opposite of what my post suggests, and leave the triangles alone completely, and map the rest of the shape to them.

Also, you can use the OFFSET command in excel, along with MATCH.

for example;


looks at 1x1 cells, J19 rows down from C7

You can use match() to find "Orange" in a list, or 4, to match shifted verticals to new colours if relavent, in theory it shouldn't be - Vertex 1 should *still be* vertex 1, but its position should have been moved around in the positions list to be in vertex order (as you were attempting lt do originally) - you *only* need to change the triangles if vertex 1 isn't vertex 1 any more.

5:7 should be 5:5, and position 7 should be position 5, that's all you should need to change, but your sort might be garbaging the vertex numbers as well by accident, resulting in tlhe crazy triangle changes; It should however still be in the position vertex 5 ought to be in (ie 6th one down)
-- The GoldFish - member of former GIT and commander in chief of GALLAHAD. You could have done something, but it's been fixed. The end. Also, play bestgameever!
Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Postby brice » Thu May 03, 2007 12:48 pm

... hey you beat me to it! Yes OFFSET can solve the whole enchilada with one formula pasted into every cell. Sweet and simple as long as you get the "$" in the right places. And the answer is...

Code: Select all

A      B     C     D         E     F   G      H     I     J     K         L

0:    0.00 -0.11  0.00       0:    0   0       0:   0.00 -0.11  0.00       0:
1:    0.48  0.08  0.00       1:   15   0       1:   0.15 -0.11 -0.26      15:
2:    0.24  0.08 -0.41       2:   14   0       2:   0.29 -0.11  0.00      14:
3:   -0.24  0.08 -0.41       3:   16   0       3:  -0.15 -0.11 -0.26      16:
4:   -0.48  0.08  0.00       4:   17   0       4:  -0.29 -0.11  0.00      17:
5:   -0.24  0.08  0.41       5:   18   0       5:  -0.15 -0.11  0.26      18:
6:    0.24  0.08  0.41       6:   19   0       6:   0.15 -0.11  0.26      19:
7:    0.48  0.50  0.00       7:    1   0       7:   0.48  0.08  0.00       1:
8:    0.24  0.50 -0.41       8:    8   0       8:   0.24  0.50 -0.41       8:
9:   -0.24  0.50 -0.41       9:    7   0       9:   0.48  0.50  0.00       7:
10:  -0.48  0.50  0.00       10:   2   0       10:  0.24  0.08 -0.41       2:
11:  -0.24  0.50  0.41       11:   9   0       11: -0.24  0.50 -0.41       9:
12:   0.24  0.50  0.41       12:   3   0       12: -0.24  0.08 -0.41       3:
13:   0.00  0.69  0.00       13:  10   0       13: -0.48  0.50  0.00      10:
14:   0.29 -0.11  0.00       14:   4   0       14: -0.48  0.08  0.00       4:
15:   0.15 -0.11 -0.26       15:  11   0       15: -0.24  0.50  0.41      11:
16:  -0.15 -0.11 -0.26       16:   5   0       16: -0.24  0.08  0.41       5:
17:  -0.29 -0.11  0.00       17:  12   0       17:  0.24  0.50  0.41      12:
18:  -0.15 -0.11  0.26       18:   6   0       18:  0.24  0.08  0.41       6:
19:   0.15 -0.11  0.26       19:  13   0       19:  0.00  0.69  0.00      13:
20:   0.29  0.69  0.00       20:  20   0       20:  0.29  0.69  0.00      20:
21:   0.15  0.69 -0.26       21:  21   0       21:  0.15  0.69 -0.26      21:
22:  -0.15  0.69 -0.26       22:  22   0       22: -0.15  0.69 -0.26      22:
23:  -0.29  0.69  0.00       23:  23   0       23: -0.29  0.69  0.00      23:
24:  -0.15  0.69  0.26       24:  24   0       24: -0.15  0.69  0.26      24:
25:   0.15  0.69  0.26       25:  25   0       25:  0.15  0.69  0.26      25:

A-D = Positions list
E-G = Vertices list
H-K = reordered Positions list (H is just a copy of A)
I-K = formula:  I1=OFFSET(B$1;$F1;0) and copy into range I1:K26 (or I1:L26)
L   = same formula, but verifies the new order matches F

This is a real shape fragment -- the hexagonal box on top of the fuel system buildings, scaled down really small. You paste the fragment data into columns A-G, and make a copy of A into H for good measure. Then comes the magic OFFSET formula. Paste "=OFFSET(B$1;$F1;0)" into I1 (minus the quotes). Then copy that cell to the range I1:K26 (or I1:L26 if you want the verification column). That's it! The reordered Position list is now in columns H-K. Column L should match column F if you extend the paste area.

You probably have to futz with column formatting for A, E, and H because of the colons. Set them to "text". If column F shows decimal places it doesn't seem to affect the lookup.

For cell I1 the formula works by taking the value of F1 and using it to index the column(s) starting at B1. The third parameter of 0 says we want the start column itself, with no column offset. When you copy this formula across the range I1:K26 the "$" things lock the appropriate row/col so the indexing works from every cell. Because I placed the first column of the Vertices list back to back with the Positions list, you can simply copy the formula into one more column (L) and you will get a verification of the reordering.

Anyone who is confused / curious about the OFFSET formula should look it up in the help pages of their favorite spreadsheet.

Seems like it's time to write a perl script... someday. Thanks TGF!!
Last edited by brice on Fri May 04, 2007 12:21 am, edited 1 time in total.
User avatar
The GoldFish
Posts: 3961
Joined: Fri Mar 01, 2002 9:01 pm
Location: Bowl / South UK

Postby The GoldFish » Thu May 03, 2007 12:58 pm

It should be fairly trivial to adapt the function into Scripter (I haven't touched that for months...) - of course that makes everyone else angry because it's in VB, but hey!

If you can give me an example shp file and its conversion into an importable/exportable format, whatever that might be, I ought to be able to make a dialog to convert them fairly easily (I have la final exam tomorrow so it won't be till after that)
Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Postby brice » Thu May 03, 2007 1:08 pm

Sure! I'll put something together. But most (if not all) of the info is a few posts back. The one about the DEC .off format. Blender can both export and import it. And it is the simplest file format I've ever seen.

The only thing you'd have to check for in the .off --> .shp direction would be for "4"s at the beginning of the polygon lines. That would mean the user didn't make Blender convert quads to triangles before exporting. Other exporters (like the .xsi I talked about above) do that automatically, but this one is just dirt cheap simple.

The format also has a third parameter in the header line, so presumably Blender might output a third list of some sort, which you would have to ignore.

I'll put an example together in the next couple of days. You might want to download Blender and play with the DEC .off import / exporters. Even if you don't know how to model in Blender yet, there is always a cube Object created when you fire it up. So you can use that as a starting point. And there is lots of web help for Blender. Lookup converting quads to triangles because the little cube starts it's life as six quads, which is useless for shape files.

If you have questions about Blender, I'll try my best to answer them. But I don't know a lot. It's a weird interface to get used to, but the program is very powerful once you get the hang of it.

User avatar
The GoldFish
Posts: 3961
Joined: Fri Mar 01, 2002 9:01 pm
Location: Bowl / South UK

Postby The GoldFish » Thu May 03, 2007 2:35 pm

ok I'll have a play tomorrow!
-- The GoldFish - member of former GIT and commander in chief of GALLAHAD. You could have done something, but it's been fixed. The end. Also, play bestgameever!
Posts: 167
Joined: Fri Feb 23, 2007 6:04 am

Postby brice » Fri May 04, 2007 12:09 am


If you know any Python, you might want to look at the following two pages:

Writing a very simple .shp importer / exporter, for use from within Blender, looks, well, pretty simple. I may give it a go someday soon, but my python skills are very minimal. A python script would be a cross-platform utility since Blender embeds python in all it's installations. Nothing against VB, but if you know python...

And the DEC .off importer / exporter is a pair of python scripts named: and, located under the .blender folder (with a leading dot) which is in your blender application folder. I'm not sure about the locations on Mac or Windows, but I think it's the same.

Anyhow, the script I used in my first post is also there. It would be good to look through it to see how it automatically converts quads to triangles before exporting. This is something the .off exporter doesn't do. The .xsi script is much more complex because it exports all kinds of data in a structured format, while the .off only does meshes in a very minimalist format. A .shp import / export script can probably be hacked together from these three scripts. I'm just not comfortable enough with python to jump on it just yet.

EDIT: the code which does the quad to triangles conversion is the following:

Code: Select all

  tris = []
  normalX = []
  mats = []
  for f in mesh.faces:
    tris.extend ( triangulate_face(f) )
    aVal = triangulate_normals(mesh,f)

    for v in aVal:
      normalX.append ( v )

... I think. Geez, it's so darn simple! Adding that to the .off exporter would probably fix the issue of lines begining with a "4", and it would do so without requiring the user to always convert their model to triangles before exporting. A very good thing indeed. Adding the .shp fragment headers and sections would be pretty simple from there.

Looks like I'm getting sucked in!

User avatar
The GoldFish
Posts: 3961
Joined: Fri Mar 01, 2002 9:01 pm
Location: Bowl / South UK

Postby The GoldFish » Sun May 06, 2007 4:35 am


Tada? Anyway I made an awful shp->off converter in VB; it does the job.

Currently, it doesn't understand what to do with up and front (mainly because *I* don't know what to do with them, I know they relate to the orientation but I don't know how to translate that into linear space) and it doesn't support strips (although as I understand it a strip A B C D E F is triangles A B C, B C D, C D E, etc)

Nor does it do OFF->SHP, but I'm not too fussed about that right now.

Return to “Mod Projects”

Who is online

Users browsing this forum: No registered users and 1 guest