source: git/src/cad3d.c @ 6c0dc95

RELEASE/1.0RELEASE/1.1RELEASE/1.2debug-cidebug-ci-sanitisersfaster-cavernloglog-selectstereowalls-datawalls-data-hanging-as-warningwarn-only-for-hanging-survey
Last change on this file since 6c0dc95 was 643a360, checked in by Olly Betts <olly@…>, 22 years ago

Better to use ossizeof() than sizeof()

git-svn-id: file:///home/survex-svn/survex/trunk@2009 4b37db11-9a0c-4f06-9ece-9ab7cdaee568

  • Property mode set to 100644
File size: 19.3 KB
RevLine 
[80e25c3]1/* cad3d.c
2 * Converts a .3d file to CAD-like formats (DXF, Sketch) and also Compass PLT.
[bd1913f]3 * Also useful as an example of how to use the img code in your own programs
4 */
[d1b1380]5
[e1b99fc]6/* Copyright (C) 1994-2002 Olly Betts
[846746e]7 *
[89231c4]8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
[846746e]12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
[89231c4]15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
[846746e]17 *
[89231c4]18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
[846746e]21 */
[d1b1380]22
[80e25c3]23/* #define DEBUG_CAD3D */
[d1b1380]24
[5ed96af8]25#ifdef HAVE_CONFIG_H
[c418627]26#include <config.h>
27#endif
28
[e1b99fc]29#include <float.h>
[badeec8]30#include <math.h>
[d1b1380]31#include <stdio.h>
32#include <stdlib.h>
[e1b99fc]33#include <string.h>
[5ed96af8]34
[c418627]35#include "cmdline.h"
[e1b99fc]36#include "debug.h"
[fa42426]37#include "filename.h"
[e1b99fc]38#include "hash.h"
39#include "img.h"
[c418627]40#include "message.h"
[e1b99fc]41#include "useful.h"
[c418627]42
[3f60fc8]43/* default values - can be overridden with --htext and --msize respectively */
44#define TEXT_HEIGHT     0.6
[c418627]45#define MARKER_SIZE     0.8
[d1b1380]46
[3abc88e]47#define GRID_SPACING    100
48
[e343e15f]49#define POINTS_PER_INCH 72.0
50#define POINTS_PER_MM (POINTS_PER_INCH / MM_PER_INCH)
51
[b387524]52/* default to DXF */
53#define FMT_DEFAULT FMT_DXF
54
[c0f7829]55static FILE *fh;
56
57/* bounds */
58static double min_x, min_y, min_z, max_x, max_y, max_z;
59
60static double text_height; /* for station labels */
61static double marker_size; /* for station markers */
62static double grid; /* grid spacing (or 0 for no grid) */
[e343e15f]63static double scale = 500.0;
64static double factor;
[c0f7829]65
[5173649]66static img *pimg;
67static const char *survey = NULL;
68
[c0f7829]69static void
70dxf_header(void)
71{
72   fprintf(fh, "0\nSECTION\n");
73   fprintf(fh, "2\nHEADER\n");
74   fprintf(fh, "9\n$EXTMIN\n"); /* lower left corner of drawing */
75   fprintf(fh, "10\n%#-.6f\n", min_x); /* x */
76   fprintf(fh, "20\n%#-.6f\n", min_y); /* y */
77   fprintf(fh, "30\n%#-.6f\n", min_z); /* min z */
78   fprintf(fh, "9\n$EXTMAX\n"); /* upper right corner of drawing */
79   fprintf(fh, "10\n%#-.6f\n", max_x); /* x */
80   fprintf(fh, "20\n%#-.6f\n", max_y); /* y */
81   fprintf(fh, "30\n%#-.6f\n", max_z); /* max z */
82   fprintf(fh, "9\n$PDMODE\n70\n3\n"); /* marker style as CROSS */
83   fprintf(fh, "9\n$PDSIZE\n40\n%6.2f\n", marker_size); /* marker size */
84   fprintf(fh, "0\nENDSEC\n");
85
86   fprintf(fh, "0\nSECTION\n");
87   fprintf(fh, "2\nTABLES\n");
88   fprintf(fh, "0\nTABLE\n");
89   fprintf(fh, "2\nLAYER\n");
90   fprintf(fh, "70\n10\n"); /* max # off layers in this DXF file : 10 */
91   /* First Layer: CentreLine */
92   fprintf(fh, "0\nLAYER\n2\nCentreLine\n");
93   fprintf(fh, "70\n64\n"); /* shows layer is referenced by entities */
94   fprintf(fh, "62\n5\n"); /* color: kept the same used by SpeleoGen */
95   fprintf(fh, "6\nCONTINUOUS\n"); /* linetype */
96   /* Next Layer: Stations */
97   fprintf(fh, "0\nLAYER\n2\nStations\n");
98   fprintf(fh, "70\n64\n"); /* shows layer is referenced by entities */
99   fprintf(fh, "62\n7\n"); /* color: kept the same used by SpeleoGen */
100   fprintf(fh, "6\nCONTINUOUS\n"); /* linetype */
101   /* Next Layer: Labels */
102   fprintf(fh, "0\nLAYER\n2\nLabels\n");
103   fprintf(fh, "70\n64\n"); /* shows layer is referenced by entities */
104   fprintf(fh, "62\n7\n"); /* color: kept the same used by SpeleoGen */
105   fprintf(fh, "6\nCONTINUOUS\n"); /* linetype */
106   if (grid > 0) {
107      /* Next Layer: Grid */
108      fprintf(fh, "0\nLAYER\n2\nGrid\n");
109      fprintf(fh, "70\n64\n"); /* shows layer is referenced by entities */
110      fprintf(fh, "62\n7\n"); /* color: kept the same used by SpeleoGen */
111      fprintf(fh, "6\nCONTINUOUS\n"); /* linetype */
112   }
113   fprintf(fh, "0\nENDTAB\n");
114   fprintf(fh, "0\nENDSEC\n");
115
116   fprintf(fh, "0\nSECTION\n");
117   fprintf(fh, "2\nENTITIES\n");
118
119   if (grid > 0) {
120      double x, y;
121      x = floor(min_x / grid) * grid + grid;
122      y = floor(min_y / grid) * grid + grid;
[80e25c3]123#ifdef DEBUG_CAD3D
[c0f7829]124      printf("x_min: %f  y_min: %f\n", x, y);
125#endif
126      while (x < max_x) {
127         /* horizontal line */
[421b7d2]128         fprintf(fh, "0\nLINE\n");
129         fprintf(fh, "8\nGrid\n"); /* Layer */
130         fprintf(fh, "10\n%6.2f\n", x);
131         fprintf(fh, "20\n%6.2f\n", min_y);
132         fprintf(fh, "30\n0\n");
133         fprintf(fh, "11\n%6.2f\n", x);
134         fprintf(fh, "21\n%6.2f\n", max_y);
135         fprintf(fh, "31\n0\n");
[c0f7829]136         x += grid;
137      }
138      while (y < max_y) {
[421b7d2]139         /* vertical line */
140         fprintf(fh, "0\nLINE\n");
141         fprintf(fh, "8\nGrid\n"); /* Layer */
142         fprintf(fh, "10\n%6.2f\n", min_x);
143         fprintf(fh, "20\n%6.2f\n", y);
144         fprintf(fh, "30\n0\n");
145         fprintf(fh, "11\n%6.2f\n", max_x);
146         fprintf(fh, "21\n%6.2f\n", y);
147         fprintf(fh, "31\n0\n");
[c0f7829]148         y += grid;
149      }
150   }
151}
152
153static void
154dxf_start_pass(int layer)
155{
[eb18f4d]156   layer = layer;
[c0f7829]157}
158
159static void
[6317ee2]160dxf_move(const img_point *p)
[c0f7829]161{
[eb18f4d]162   p = p;
[c0f7829]163}
164
165static void
[6317ee2]166dxf_line(const img_point *p1, const img_point *p)
[c0f7829]167{
168   fprintf(fh, "0\nLINE\n");
169   fprintf(fh, "8\nCentreLine\n"); /* Layer */
[6317ee2]170   fprintf(fh, "10\n%6.2f\n", p1->x);
171   fprintf(fh, "20\n%6.2f\n", p1->y);
172   fprintf(fh, "30\n%6.2f\n", p1->z);
173   fprintf(fh, "11\n%6.2f\n", p->x);
174   fprintf(fh, "21\n%6.2f\n", p->y);
175   fprintf(fh, "31\n%6.2f\n", p->z);
[c0f7829]176}
177
178static void
[6317ee2]179dxf_label(const img_point *p, const char *s)
[c0f7829]180{
181   /* write station label to dxf file */
182   fprintf(fh, "0\nTEXT\n");
183   fprintf(fh, "8\nLabels\n"); /* Layer */
[6317ee2]184   fprintf(fh, "10\n%6.2f\n", p->x);
185   fprintf(fh, "20\n%6.2f\n", p->y);
186   fprintf(fh, "30\n%6.2f\n", p->z);
[c0f7829]187   fprintf(fh, "40\n%6.2f\n", text_height);
188   fprintf(fh, "1\n%s\n", s);
189}
190
191static void
[6317ee2]192dxf_cross(const img_point *p)
[c0f7829]193{
194   /* write station marker to dxf file */
195   fprintf(fh, "0\nPOINT\n");
196   fprintf(fh, "8\nStations\n"); /* Layer */
[6317ee2]197   fprintf(fh, "10\n%6.2f\n", p->x);
198   fprintf(fh, "20\n%6.2f\n", p->y);
199   fprintf(fh, "30\n%6.2f\n", p->z);
[c0f7829]200}
201
202static void
203dxf_footer(void)
204{
205   fprintf(fh, "000\nENDSEC\n");
206   fprintf(fh, "000\nEOF\n");
207}
208
209static void
210sketch_header(void)
211{
212   fprintf(fh, "##Sketch 1 2\n"); /* Sketch file version */
213   fprintf(fh, "document()\n");
[e343e15f]214   fprintf(fh, "layout((%.3f,%.3f),0)\n",
215           (max_x - min_x) * factor, (max_y - min_y) * factor);
[c0f7829]216}
217
218static const char *layer_names[] = {
219   NULL,
220   "Legs",
221   "Stations",
222   NULL,
223   "Labels"
224};
225
226static void
227sketch_start_pass(int layer)
228{
229   fprintf(fh, "layer('%s',1,1,0,0,(0,0,0))\n", layer_names[layer]);
230}
231
232static void
[6317ee2]233sketch_move(const img_point *p)
[c0f7829]234{
235   fprintf(fh, "b()\n");
[6317ee2]236   fprintf(fh, "bs(%.3f,%.3f,%.3f)\n", p->x * factor, p->y * factor, 0.0);
[c0f7829]237}
238
239static void
[6317ee2]240sketch_line(const img_point *p1, const img_point *p)
[c0f7829]241{
[eb18f4d]242   p1 = p1;
[6317ee2]243   fprintf(fh, "bs(%.3f,%.3f,%.3f)\n", p->x * factor, p->y * factor, 0.0);
[c0f7829]244}
245
246static void
[6317ee2]247sketch_label(const img_point *p, const char *s)
[c0f7829]248{
249   fprintf(fh, "fp((0,0,0))\n");
250   fprintf(fh, "le()\n");
251   fprintf(fh, "Fn('Times-Roman')\n");
252   fprintf(fh, "Fs(5)\n");
253   fprintf(fh, "txt('");
254   while (*s) {
255      int ch = *s++;
256      if (ch == '\'' || ch == '\\') putc('\\', fh);
257      putc(ch, fh);
258   }
[6317ee2]259   fprintf(fh, "',(%.3f,%.3f))\n", p->x * factor, p->y * factor);
[c0f7829]260}
261
262static void
[6317ee2]263sketch_cross(const img_point *p)
[c0f7829]264{
265   fprintf(fh, "b()\n");
266   fprintf(fh, "bs(%.3f,%.3f,%.3f)\n",
[6317ee2]267           p->x * factor - MARKER_SIZE, p->y * factor - MARKER_SIZE, 0.0);
[c0f7829]268   fprintf(fh, "bs(%.3f,%.3f,%.3f)\n",
[6317ee2]269           p->x * factor + MARKER_SIZE, p->y * factor + MARKER_SIZE, 0.0);
[c0f7829]270   fprintf(fh, "bn()\n");
271   fprintf(fh, "bs(%.3f,%.3f,%.3f)\n",
[6317ee2]272           p->x * factor + MARKER_SIZE, p->y * factor - MARKER_SIZE, 0.0);
[c0f7829]273   fprintf(fh, "bs(%.3f,%.3f,%.3f)\n",
[6317ee2]274           p->x * factor - MARKER_SIZE, p->y * factor + MARKER_SIZE, 0.0);
[c0f7829]275}
276
277static void
278sketch_footer(void)
279{
280   fprintf(fh, "guidelayer('Guide Lines',1,0,0,1,(0,0,1))\n");
[e343e15f]281   if (grid) {
282      fprintf(fh, "grid((0,0,%.3f,%.3f),1,(0,0,1),'Grid')\n",
283              grid * factor, grid * factor);
284   }
[c0f7829]285}
286
[e1b99fc]287typedef struct point {
288   img_point p;
289   const char *label;
290   struct point *next;
291} point;
292
293static point **htab;
294
295static void
296plt_header(void)
297{
[febe041]298   size_t i;
[643a360]299   htab = osmalloc(0x2000 * ossizeof(point *));
[febe041]300   for (i = 0; i < 0x2000; ++i) htab[i] = NULL;
[5173649]301   /* Survex is E, N, Alt - PLT file is N, E, Alt */
302   fprintf(fh, "Z %.3f %.3f %.3f %.3f %.3f %.3f\r\n",
303           min_y / METRES_PER_FOOT, max_y / METRES_PER_FOOT,
304           min_x / METRES_PER_FOOT, max_x / METRES_PER_FOOT,
305           min_z / METRES_PER_FOOT, max_z / METRES_PER_FOOT);
306   fprintf(fh, "N%s D 1 1 1 C%s\r\n", survey ? survey : "X", pimg->title);
[e1b99fc]307}
308
309static void
310plt_start_pass(int layer)
311{
312   layer = layer;
313}
314
315static void
[6317ee2]316set_name(const img_point *p, const char *s)
[e1b99fc]317{
318   int hash;
319   point *pt;
320   union {
321      char data[sizeof(int) * 3];
322      int x[3];
323   } u;
[5757725]324
[6317ee2]325   u.x[0] = p->x * 100;
326   u.x[1] = p->y * 100;
327   u.x[2] = p->z * 100;
[e1b99fc]328   hash = (hash_data(u.data, sizeof(int) * 3) & 0x1fff);
329   for (pt = htab[hash]; pt; pt = pt->next) {
[6317ee2]330      if (pt->p.x == p->x && pt->p.y == p->y && pt->p.z == p->z) {
[e1b99fc]331         /* already got name for these coordinates */
[8f7d8f6]332         /* FIXME: what about multiple names for the same station? */
[e1b99fc]333         return;
334      }
335   }
336
337   pt = osnew(point);
338   pt->label = osstrdup(s);
[6317ee2]339   pt->p = *p;
[e1b99fc]340   pt->next = htab[hash];
341   htab[hash] = pt;
342
343   return;
344}
345
346static const char *
347find_name(const img_point *p)
348{
349   int hash;
350   point *pt;
351   union {
352      char data[sizeof(int) * 3];
353      int x[3];
354   } u;
355   ASSERT(p);
[5757725]356
[e1b99fc]357   u.x[0] = p->x * 100;
358   u.x[1] = p->y * 100;
359   u.x[2] = p->z * 100;
360   hash = (hash_data(u.data, sizeof(int) * 3) & 0x1fff);
361   for (pt = htab[hash]; pt; pt = pt->next) {
362      if (pt->p.x == p->x && pt->p.y == p->y && pt->p.z == p->z)
363         return pt->label;
364   }
365   return "?";
366}
367
368static void
[6317ee2]369plt_move(const img_point *p)
[e1b99fc]370{
371   /* Survex is E, N, Alt - PLT file is N, E, Alt */
372   fprintf(fh, "M %.3f %.3f %.3f ",
[6317ee2]373           p->y / METRES_PER_FOOT, p->x / METRES_PER_FOOT, p->z / METRES_PER_FOOT);
[1b5a73d]374   /* dummy passage dimensions are required to avoid compass bug */
375   fprintf(fh, "S%s P -9 -9 -9 -9\r\n", find_name(p));
[e1b99fc]376}
377
378static void
[6317ee2]379plt_line(const img_point *p1, const img_point *p)
[e1b99fc]380{
381   p1 = p1;
382   /* Survex is E, N, Alt - PLT file is N, E, Alt */
383   fprintf(fh, "D %.3f %.3f %.3f ",
[6317ee2]384           p->y / METRES_PER_FOOT, p->x / METRES_PER_FOOT, p->z / METRES_PER_FOOT);
[1b5a73d]385   /* dummy passage dimensions are required to avoid compass bug */
386   fprintf(fh, "S%s P -9 -9 -9 -9\r\n", find_name(p));
[e1b99fc]387}
388
389static void
[6317ee2]390plt_label(const img_point *p, const char *s)
[e1b99fc]391{
392   /* FIXME: also ctrl characters - ought to remap them, not give up */
393   if (strchr(s, ' ')) {
394      fprintf(stderr, "PLT format can't cope with spaces in station names\n");
395      exit(1);
396   }
[5757725]397   set_name(p, s);
[e1b99fc]398}
399
400static void
[6317ee2]401plt_cross(const img_point *p)
[e1b99fc]402{
403   p = p;
404}
405
406static void
407plt_footer(void)
408{
[5173649]409   /* Survex is E, N, Alt - PLT file is N, E, Alt */
410   fprintf(fh, "X %.3f %.3f %.3f %.3f %.3f %.3f\r\n",
411           min_y / METRES_PER_FOOT, max_y / METRES_PER_FOOT,
412           min_x / METRES_PER_FOOT, max_x / METRES_PER_FOOT,
413           min_z / METRES_PER_FOOT, max_z / METRES_PER_FOOT);
[e1b99fc]414   /* Yucky DOS "end of textfile" marker */
[6317ee2]415   putc('\x1a', fh);
[e1b99fc]416}
417
[c0f7829]418#define LEGS 1
419#define STNS 2
420#define LABELS 4
421static int dxf_passes[] = { LEGS|STNS|LABELS, 0 };
422static int sketch_passes[] = { LEGS, STNS, LABELS, 0 };
[e1b99fc]423static int plt_passes[] = { LABELS, LEGS, 0 };
[c0f7829]424
[0a830d7]425int
426main(int argc, char **argv)
427{
[c0f7829]428   char *fnm_3d, *fnm_out;
[c418627]429   unsigned char labels, crosses, legs;
[d1b1380]430   int item;
[493c523]431   int fSeenMove = 0;
[0ed0e16]432   img_point p, p1;
[9624a5a]433   int elevation = 0;
434   double elev_angle = 0;
435   double s = 0, c = 0;
[b387524]436   enum { FMT_DXF = 0, FMT_SKETCH, FMT_PLT, FMT_AUTO } format;
437   static const char *extensions[] = { "dxf", "sk", "plt" };
[c0f7829]438   int *pass;
439
440   void (*header)(void);
441   void (*start_pass)(int);
[6317ee2]442   void (*move)(const img_point *);
443   void (*line)(const img_point *, const img_point *);
444   void (*label)(const img_point *, const char *);
445   void (*cross)(const img_point *);
[c0f7829]446   void (*footer)(void);
[6317ee2]447   const char *mode = "w"; /* default to text output */
[d1b1380]448
[647407d]449   /* TRANSLATE */
[c418627]450   static const struct option long_opts[] = {
451        /* const char *name; int has_arg (0 no_argument, 1 required, 2 options_*); int *flag; int val */
[76bbb7c9]452        {"survey", required_argument, 0, 's'},
[c418627]453        {"no-crosses", no_argument, 0, 'c'},
454        {"no-station-names", no_argument, 0, 'n'},
455        {"no-legs", no_argument, 0, 'l'},
[3abc88e]456        {"grid", optional_argument, 0, 'g'},
[9c5aca6]457        {"text-height", required_argument, 0, 't'},
458        {"marker-size", required_argument, 0, 'm'},
[9624a5a]459        {"elevation", required_argument, 0, 'e'},
[e343e15f]460        {"reduction", required_argument, 0, 'r'},
[421b7d2]461        {"dxf", no_argument, 0, 'D'},
462        {"sketch", no_argument, 0, 'S'},
[e1b99fc]463        {"plt", no_argument, 0, 'P'},
[c418627]464        {"help", no_argument, 0, HLP_HELP},
[83643569]465        {"version", no_argument, 0, HLP_VERSION},
[c418627]466        {0,0,0,0}
467   };
[d1b1380]468
[e1b99fc]469#define short_opts "s:cnlg::t:m:er::DSPh"
[421b7d2]470
[647407d]471   /* TRANSLATE */
[c418627]472   static struct help_msg help[] = {
[76bbb7c9]473        {HLP_ENCODELONG(0), "only load the sub-survey with this prefix"},
474        {HLP_ENCODELONG(1), "do not generate station markers"},
475        {HLP_ENCODELONG(2), "do not generate station labels"},
476        {HLP_ENCODELONG(3), "do not generate the survey legs"},
[e343e15f]477        {HLP_ENCODELONG(4), "generate grid (default "STRING(GRID_SPACING)"m)"},
478        {HLP_ENCODELONG(5), "station labels text height (default "STRING(TEXT_HEIGHT)")"},
479        {HLP_ENCODELONG(6), "station marker size (default "STRING(MARKER_SIZE)")"},
[76bbb7c9]480        {HLP_ENCODELONG(7), "produce an elevation view"},
[e343e15f]481        {HLP_ENCODELONG(8), "factor to scale down by (default 500)"},
482        {HLP_ENCODELONG(9), "produce DXF output"},
[b387524]483        {HLP_ENCODELONG(10), "produce Sketch output"},
[e1b99fc]484        {HLP_ENCODELONG(11), "produce Compass PLT output for Carto"},
[cb3d1e2]485        {0,0}
[c418627]486   };
487
[bdfe97f]488   msg_init(argv);
[c418627]489
490   /* Defaults */
491   crosses = 1;
492   labels = 1;
493   legs = 1;
[3abc88e]494   grid = 0;
[c418627]495   text_height = TEXT_HEIGHT;
496   marker_size = MARKER_SIZE;
[b387524]497   format = FMT_AUTO;
[c418627]498
[493c523]499   cmdline_init(argc, argv, short_opts, long_opts, NULL, help, 1, 2);
[cb3d1e2]500   while (1) {
[9c5aca6]501      int opt = cmdline_getopt();
[c418627]502      if (opt == EOF) break;
503      switch (opt) {
[9624a5a]504       case 'e': /* Elevation */
505         elevation = 1;
506         elev_angle = cmdline_double_arg();
[421b7d2]507         break;
[c418627]508       case 'c': /* Crosses */
[421b7d2]509         crosses = 0;
510         break;
[c418627]511       case 'n': /* Labels */
512         labels = 0;
513         break;
514       case 'l': /* Legs */
515         legs = 0;
516         break;
[3abc88e]517       case 'g': /* Grid */
[e343e15f]518         if (optarg) {
[3abc88e]519            grid = cmdline_double_arg();
[e343e15f]520         } else {
521            grid = (double)GRID_SPACING;
522         }
523         break;
524       case 'r': /* Reduction factor */
525         scale = cmdline_double_arg();
[3abc88e]526         break;
[c418627]527       case 't': /* Text height */
[acc20b1]528         text_height = cmdline_double_arg();
[80e25c3]529#ifdef DEBUG_CAD3D
[759fb47]530         printf("Text Height: `%s' input, converted to %6.2f\n", optarg, text_height);
[c418627]531#endif
532         break;
533       case 'm': /* Marker size */
[acc20b1]534         marker_size = cmdline_double_arg();
[80e25c3]535#ifdef DEBUG_CAD3D
[759fb47]536         printf("Marker Size: `%s', converted to %6.2f\n", optarg, marker_size);
[c418627]537#endif
538         break;
[c0f7829]539       case 'D':
540         format = FMT_DXF;
541         break;
542       case 'S':
543         format = FMT_SKETCH;
544         break;
[e1b99fc]545       case 'P':
546         format = FMT_PLT;
547         break;
[76bbb7c9]548       case 's':
549         survey = optarg;
550         break;
[80e25c3]551#ifdef DEBUG_CAD3D
[c418627]552       default:
[9624a5a]553         printf("Internal Error: 'getopt' returned '%c' %d\n", opt, opt);
[9c5aca6]554#endif
[c418627]555      }
[cb3d1e2]556   }
[c418627]557
[b387524]558   fnm_3d = argv[optind++];
559   if (argv[optind]) {
560      fnm_out = argv[optind];
561      if (format == FMT_AUTO) {
562         size_t i;
563         size_t len = strlen(fnm_out);
564         format = FMT_DEFAULT;
565         for (i = 0; i < FMT_AUTO; ++i) {
566            size_t l = strlen(extensions[i]);
567            if (len > l + 1 && fnm_out[len - l - 1] == FNM_SEP_EXT &&
568                strcasecmp(fnm_out + len - l, extensions[i]) == 0) {
569               format = i;
570               break;
571            }
572         }
573      }
574   } else {
575      char *baseleaf = baseleaf_from_fnm(fnm_3d);
576      if (format == FMT_AUTO) format = FMT_DEFAULT;
[6317ee2]577      /* note : memory allocated by fnm_out gets leaked in this case... */
[b387524]578      fnm_out = add_ext(baseleaf, extensions[format]);
579      osfree(baseleaf);
580   }
581
[c0f7829]582   switch (format) {
583    case FMT_DXF:
584      header = dxf_header;
585      start_pass = dxf_start_pass;
586      move = dxf_move;
587      line = dxf_line;
588      label = dxf_label;
589      cross = dxf_cross;
590      footer = dxf_footer;
591      pass = dxf_passes;
592      break;
593    case FMT_SKETCH:
594      header = sketch_header;
595      start_pass = sketch_start_pass;
596      move = sketch_move;
597      line = sketch_line;
598      label = sketch_label;
599      cross = sketch_cross;
600      footer = sketch_footer;
601      pass = sketch_passes;
[e343e15f]602      factor = POINTS_PER_MM * 1000.0 / scale;
[6317ee2]603      mode = "wb"; /* Binary file output */
[c0f7829]604      break;
[e1b99fc]605    case FMT_PLT:
606      header = plt_header;
607      start_pass = plt_start_pass;
608      move = plt_move;
609      line = plt_line;
610      label = plt_label;
611      cross = plt_cross;
612      footer = plt_footer;
613      pass = plt_passes;
[6317ee2]614      mode = "wb"; /* Binary file output */
[e1b99fc]615      break;
[c0f7829]616    default:
617      exit(1);
618   }
619
[a2ad284]620   pimg = img_open_survey(fnm_3d, survey);
[c0f7829]621   if (!pimg) fatalerror(img_error(), fnm_3d);
[d1b1380]622
[6317ee2]623   fh = safe_fopen(fnm_out, mode);
[9c5aca6]624
[9624a5a]625   if (elevation) {
[e343e15f]626      s = sin(rad(elev_angle));
627      c = cos(rad(elev_angle));
[9624a5a]628   }
[cb3d1e2]629
[c418627]630   /* Get drawing corners */
[ee7bafa]631   min_x = min_y = min_z = HUGE_VAL;
632   max_x = max_y = max_z = -HUGE_VAL;
[a420b49]633   do {
[23f7ea7]634      item = img_read_item(pimg, &p);
[9624a5a]635
636      if (elevation) {
[e343e15f]637         double xnew = p.x * c - p.y * s;
638         double znew = - p.x * s - p.y * c;
639         p.y = p.z;
640         p.z = znew;
641         p.x = xnew;
[9624a5a]642      }
643
[a420b49]644      switch (item) {
[0a830d7]645       case img_MOVE: case img_LINE: case img_LABEL:
[421b7d2]646         if (p.x < min_x) min_x = p.x;
647         if (p.x > max_x) max_x = p.x;
648         if (p.y < min_y) min_y = p.y;
649         if (p.y > max_y) max_y = p.y;
650         if (p.z < min_z) min_z = p.z;
651         if (p.z > max_z) max_z = p.z;
652         break;
[a420b49]653      }
[cb3d1e2]654   } while (item != img_STOP);
[9c5aca6]655
[3abc88e]656   if (grid > 0) {
657      min_x -= grid / 2;
658      max_x += grid / 2;
659      min_y -= grid / 2;
660      max_y += grid / 2;
661   }
662
[9c5aca6]663   /* handle empty file gracefully */
664   if (min_x > max_x) {
665      min_x = min_y = min_z = 0;
666      max_x = max_y = max_z = 0;
667   }
[cb3d1e2]668
[c418627]669   /* Header */
[c0f7829]670   header();
671
672   p1.x = p1.y = p1.z = 0; /* avoid compiler warning */
673
674   while (*pass) {
[421b7d2]675      if (((*pass & LEGS) && legs) ||
[c0f7829]676          ((*pass & STNS) && crosses) ||
677          ((*pass & LABELS) && labels)) {
678         img_rewind(pimg);
679         start_pass(*pass);
680         do {
[23f7ea7]681            item = img_read_item(pimg, &p);
[c0f7829]682
683            if (format == FMT_SKETCH) {
684               p.x -= min_x;
685               p.y -= min_y;
686               p.z -= min_z;
687            }
[d1b1380]688
[c0f7829]689            if (elevation) {
690               double xnew = p.x * c - p.y * s;
691               double znew = - p.x * s - p.y * c;
692               p.y = p.z;
693               p.z = znew;
694               p.x = xnew;
695            }
[9c5aca6]696
[c0f7829]697            switch (item) {
698             case img_BAD:
699               img_close(pimg);
700               fatalerror(/*Bad 3d image file `%s'*/106, fnm_3d);
701               break;
702             case img_LINE:
[80e25c3]703#ifdef DEBUG_CAD3D
[c0f7829]704               printf("line to %9.2f %9.2f %9.2f\n", p.x, p.y, p.z);
[f2588ca]705#endif
[c0f7829]706               if (!fSeenMove) {
[80e25c3]707#ifdef DEBUG_CAD3D
[1a3eb43]708                  printf("Something is wrong -- img_LINE before any img_MOVE!\n");
[d1b1380]709#endif
[c0f7829]710                  img_close(pimg);
711                  fatalerror(/*Bad 3d image file `%s'*/106, fnm_3d);
712               }
[6317ee2]713               if ((*pass & LEGS) && legs) line(&p1, &p);
[c0f7829]714               p1 = p;
715               break;
716             case img_MOVE:
[80e25c3]717#ifdef DEBUG_CAD3D
[c0f7829]718               printf("move to %9.2f %9.2f %9.2f\n",x,y,z);
[0a830d7]719#endif
[6317ee2]720               if ((*pass & LEGS) && legs) move(&p);
[c0f7829]721               fSeenMove = 1;
722               p1 = p;
723               break;
724             case img_LABEL:
[80e25c3]725#ifdef DEBUG_CAD3D
[23f7ea7]726               printf("label `%s' at %9.2f %9.2f %9.2f\n",pimg->label,x,y,z);
[0a830d7]727#endif
[6317ee2]728               if ((*pass & LABELS) && labels) label(&p, pimg->label);
729               if ((*pass & STNS) && crosses) cross(&p);
[c0f7829]730               break;
[80e25c3]731#ifdef DEBUG_CAD3D
[c0f7829]732             case img_STOP:
733               printf("stop\n");
734               break;
735             default:
736               printf("other info tag (code %d) ignored\n",item);
[f2588ca]737#endif
738            }
[c0f7829]739         } while (item != img_STOP);
[f2588ca]740      }
[f794f56]741      pass++;
[f2588ca]742   }
[d1b1380]743   img_close(pimg);
[c0f7829]744   footer();
[f1067a2]745   safe_fclose(fh);
[d1b1380]746   return 0;
747}
Note: See TracBrowser for help on using the repository browser.