Skip to content

Commit

Permalink
Parmaeter -t for therion source file format output added
Browse files Browse the repository at this point in the history
  • Loading branch information
hbeni committed Mar 30, 2020
1 parent 8008bf4 commit 29e035c
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 21 deletions.
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# therionsurface2survex
Convert therion (or GDAL) surface meshes to survex surface legs.
Convert therion (or GDAL) surface meshes to survex (or therion) surface legs.

```
Usage: [-hsd] [-o outfile] [-i infile] -- [infile]
Expand All @@ -8,6 +8,7 @@ Usage: [-hsd] [-o outfile] [-i infile] -- [infile]
-h Print this help and exit.
-s Skip check of contents - process entire file (use in case
your therion grid data file has no "surface" declaration
-t Export in therion centerline format
-d debug mode: spew any action on stdout
```

Expand All @@ -20,7 +21,7 @@ The main intend of this progam is to generate survex surface meshes that will
be processed by survex cavern program. This generates a 3d-file that can be
merged with your cave by therion. This way you can use your existing therion digital elevation
model (DEM) and include it in therions 3d-export; for example to get the distance
from the cave passage to the sourface.
from the cave passage to the surface.

![Screenshot from Hirlatzhöhle made with V.0.10](example/screenshot_0.10.png)

Expand All @@ -38,12 +39,20 @@ The drawback is, that the grid file does not contain any coordinate system refer


#### Output formats
The supported output formats are:

- _Survex_ (default)
The output file is in survex `.swx` format, suitable to be processed from
`cavern` to create a survex 3d-file, which contains the 3d mesh.
Each grid section is translated to a station. Station names follow the
naming scheme surface.<row>.<column>, where row and column is the cell address
naming scheme `surface.<row>.<column>`, where row and column is the cell address
from the source therion file.

- _Therion source file_ (with `-t`)
The output is in therions `.th` centerline format, suitable to be `source`'d
from therion `thconfig` files which may be even easier to combine with
you cave data in therion.


## How it operates
It reads the input file line by line and tries to parse any relevant therion
Expand Down Expand Up @@ -74,6 +83,7 @@ different points of the surface (like heights of walls or distances from peaks).
For this to work, you need to create a combined 3d-file with your cave and the
new surface 3d file.

#### Combining several survex/aven 3d-files
Integration is easy, once you know how it works. You need to prepare some
therion source file to `import` your 3d file. See the therion book fo examples.
(this method is needed because aven currently does not support opening
Expand All @@ -89,6 +99,20 @@ endsource
export model -o myCave_with_mySurface.3d
```

#### Combine using therion native format (-t option)
Things get even easier if you directly export a native therion surface mesh.
This can be activated either by ending the output file parameter `-o` with a name
ending in `.th` or by explicitely requesting the `-t`parameter.
Exporting directly to therion native format allows you more fine control.

A short example may be a single thconfig file like this:
```
source myCave.th
source mySurface.th
export model -o myCave_with_mySurface.3d
```


## Alternatives
Survex 1.2.18 added support for loading terrain data and rendering it as a transparent surface in `aven`. As far as i know this is similar to therions `loch` terrain feature, where a transparent height model is displayed.
Expand Down
20 changes: 20 additions & 0 deletions example/myCave.th
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
encoding utf-8
survey testcave
centerline
cs EPSG:31290
data normal from to length bearing gradient
1.0 1.1 2 0 -35
1.1 1.2 4 23 -5
1.2 1.3 2 98 +5
1.3 1.4 8 45 +15
1.4 1.5 15 60 +20
1.5 1.6 16.7 350 +33

1.4 1.4a 5 120 +25
1.4a 1.4b 12 180 +5

fix 1.6 400105 5419782 12
station 1.6 "fooEntrance" entrance

endcenterline
endsurvey
7 changes: 4 additions & 3 deletions example/surface.th
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
some garbage
#some garbage

surface
bitmap foo.jpg
cs EPSG:31290
bitmap foo.jpg [0 0 400080 5419750 10 10 400120 5419800]

# x y xs ys cnum rnum
grid 400080 5419750 10 10 4 5
10 10 10 10
Expand All @@ -14,4 +15,4 @@ surface
endsurface some #stuff left here


more garbage to be ignored
#more garbage to be ignored
14 changes: 14 additions & 0 deletions example/thconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
encoding utf-8
# This example shows how to integrate a fictive cave with therion surface grid.
#
# Prerequisite is to run the command `therionsurface2survex example/surface.th -t`
# The command will parse the surface.th grid file and outputs a surface.th.th
# therion source file containing a surface leg survey.
# Then compile this file with `therion`. This produces a test.3d file,
# containing both the survey and the surface mesh.
#

source myCave.th # ficitve data from the survey
source surface.th.th # exported from surface.th grid data with Option "-t"

export model -o test.3d
56 changes: 41 additions & 15 deletions therionsurface2survex.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @author 2020 Benedikt Hallinger <[email protected]>
*/

const char VERSION[] = "0.10";
const char VERSION[] = "1.0";
const char PROGNAME[] = "therionsurface2survex";

#include <ctype.h>
Expand All @@ -40,12 +40,13 @@ using namespace std;
void usage () {
cout << PROGNAME << " Version " << VERSION << ", License GPLv3" <<endl;
cout << "Convert therion surface meshes to survex" << endl;
cout << "Usage: [-hsd] [-o outfile] [-i infile] -- [infile]"<<endl;
cout << "Usage: [-hsdt] [-o outfile] [-i infile] -- [infile]"<<endl;
cout << " -o outfile File to write to. Will be derived from infile if not specified."<<endl;
cout << " -i infile File to read from, if not given by last parameter."<<endl;
cout << " -h Print this help and exit."<<endl;
cout << " -s Skip check of contents - process entire file (use in case" <<endl;
cout << " your therion grid data file has no \"surface\" declaration)" <<endl;
cout << " -t Export in therion centerline format\n" <<endl;
cout << " -d debug mode: spew any action on stdout" <<endl;
}

Expand All @@ -55,6 +56,7 @@ int main (int argc, char **argv)
string inFile;
string outFile;
bool skipCheck = false; // true=process entire file
bool outFormatTH = false; // output in therion centerline format
bool debug = false;


Expand All @@ -64,7 +66,7 @@ int main (int argc, char **argv)

opterr = 0;

while ((c = getopt (argc, argv, "hsdi:o:")) != -1)
while ((c = getopt (argc, argv, "hstdi:o:")) != -1)
switch (c)
{
case 'h':
Expand All @@ -80,6 +82,9 @@ int main (int argc, char **argv)
case 's':
skipCheck = true;
break;
case 't':
outFormatTH = true;
break;
case 'd':
debug = true;
break;
Expand Down Expand Up @@ -114,13 +119,24 @@ int main (int argc, char **argv)
return 1;
}

// switch to therion mode in case outfile was given and ends with *.th
if (outFile != "" && outFile.length() >= 3 && outFile.substr(outFile.length()-3,3) == ".th" )
outFormatTH = true;

// generate default value for outFile in case nothing was given from user
if (outFile == "") {
outFile = inFile + ".swx";
if (outFormatTH) {
outFile = inFile + ".th";
} else {
outFile = inFile + ".swx";
}
}




// therion/survex prefixes
std::string comment_prfx = (outFormatTH)? "#" : ";";
std::string command_prfx = (outFormatTH)? "" : "*";


// Read infile, parse and write result to outfile
ifstream h_infile;
Expand All @@ -140,9 +156,13 @@ int main (int argc, char **argv)
// write a nice header
auto now = std::chrono::system_clock::now();
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
h_outfile << "; converted by " << PROGNAME << " Version " << VERSION << "\n";
h_outfile << "; on " << std::ctime(&now_time);
h_outfile << "; from file " << inFile.c_str() << "\n\n";
h_outfile << comment_prfx << " converted by " << PROGNAME << " Version " << VERSION << "\n";
h_outfile << comment_prfx << " on " << std::ctime(&now_time);
h_outfile << comment_prfx << " from file " << inFile.c_str() << "\n\n";
if (outFormatTH) {
h_outfile << "survey surface\n";
h_outfile << "centerline\n";
}

// prepare some regexes for parsing
std::regex detect_surface_start_re ("^\\s*(surface|grid)");
Expand Down Expand Up @@ -207,15 +227,16 @@ int main (int argc, char **argv)
// direct commandos will go directly into the tgt file
std::smatch sm_cmd;
if (std::regex_search(in_line, sm_cmd, parse_cmddirect_re)) {
h_outfile << "*" << sm_cmd[1] << " " << sm_cmd[2] << "\n";
h_outfile << command_prfx << sm_cmd[1] << " " << sm_cmd[2] << "\n";
if (debug) printf (" DBG: line %i: Parsed '%s' to direct cmd\n", line_nr, in_line.c_str());
}

// copy cs command in case it was given
std::smatch sm_cs;
if (std::regex_search(in_line, sm_cs, parse_cs_re)) {
h_outfile << "*" << sm_cs[1] << " " << sm_cs[2] << "\n";
h_outfile << "*" << "cs out" << " " << sm_cs[2] << "\n";
h_outfile << command_prfx << sm_cs[1] << " " << sm_cs[2] << "\n";
if (!outFormatTH)
h_outfile << command_prfx << "cs out" << " " << sm_cs[2] << "\n";
}

// parse grid command, we need to get some values out:
Expand Down Expand Up @@ -276,7 +297,7 @@ int main (int argc, char **argv)


/* Ok, now we write the fix station data */
h_outfile << "*flags surface" << "\n";
h_outfile << command_prfx << "flags surface" << "\n";
float tgt_x, tgt_y, tgt_z;
float bbox_ur_x = origin_x + step_x * cols_num;
float bbox_ur_y = origin_y + step_y * cols_num;
Expand All @@ -289,15 +310,15 @@ int main (int argc, char **argv)
tgt_y = origin_y + step_y * cur_row;
tgt_z = parsedData[cur_row][cur_col];
string tgt_name = "surface." + to_string(cur_row) + "." + to_string(cur_col);
string outStr = "*fix " + tgt_name + " " + to_string(tgt_x) + " " + to_string(tgt_y) + " " + to_string(tgt_z);
string outStr = command_prfx + "fix " + tgt_name + " " + to_string(tgt_x) + " " + to_string(tgt_y) + " " + to_string(tgt_z);
h_outfile << outStr.c_str() << "\n";

if (debug) printf (" DBG: data written: parsedData[%i][%i]='%f' => '%s'\n", cur_row, cur_col, parsedData[cur_row][cur_col], outStr.c_str() );
}
}

/* Ok, now on to write the mesh */
h_outfile << "\n*data nosurvey from to" << "\n";
h_outfile << "\n" << command_prfx << "data nosurvey from to" << "\n";
for (cur_row = 0; cur_row < parsedData.size(); ++cur_row) {
for (cur_col = 0; cur_col < parsedData[cur_row].size(); ++cur_col) {

Expand All @@ -320,6 +341,11 @@ int main (int argc, char **argv)
}
}

if (outFormatTH) {
h_outfile << "endcenterline\n";
h_outfile << "endsurvey\n";
}

h_outfile.close();

} else {
Expand Down

0 comments on commit 29e035c

Please sign in to comment.