summaryrefslogtreecommitdiff
path: root/app/bin/track.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/track.c')
-rw-r--r--app/bin/track.c270
1 files changed, 143 insertions, 127 deletions
diff --git a/app/bin/track.c b/app/bin/track.c
index bbbf48a..22af292 100644
--- a/app/bin/track.c
+++ b/app/bin/track.c
@@ -1,5 +1,5 @@
-/*
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/track.c,v 1.7 2009-07-05 15:11:02 m_fischer Exp $
+/** \file track.c
+ * Track
*/
/* XTrkCad - Model Railroad CAD
@@ -20,17 +20,29 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#include <assert.h>
#include <time.h>
#include <ctype.h>
#include <stdarg.h>
#include <math.h>
-#include "track.h"
+#include <string.h>
+
#include "ccurve.h"
-#include "cstraigh.h"
#include "cjoin.h"
#include "compound.h"
-#include "i18n.h"
+#include "cselect.h"
+#include "cstraigh.h"
+#include "cundo.h"
+#include "custom.h"
#include "draw.h"
+#include "fileio.h"
+#include "i18n.h"
+#include "layout.h"
+#include "messages.h"
+#include "param.h"
+#include "paths.h"
+#include "track.h"
+#include "utility.h"
#ifndef TRACKDEP
#ifndef FASTTRACK
@@ -64,8 +76,10 @@ static int log_readTracks = 0;
EXPORT wIndex_t trackCount;
EXPORT long drawEndPtV = 2;
+EXPORT long drawUnconnectedEndPt = 0; /**< How do we draw Unconnected EndPts */
EXPORT long centerDrawMode = FALSE; /**< flag to control drawing of circle centers */
+EXPORT long printCenterLines = FALSE; /**< flag to control drawing of centerline in Print */
static BOOL_T exportingTracks = FALSE;
@@ -78,15 +92,15 @@ static dynArr_t trackCmds_da;
EXPORT BOOL_T useCurrentLayer = FALSE;
-EXPORT LAYER_T curTrackLayer;
+EXPORT unsigned int curTrackLayer;
EXPORT coOrd descriptionOff;
EXPORT DIST_T roadbedWidth = 0.0;
EXPORT DIST_T roadbedLineWidth = 3.0/75.0;
-EXPORT DIST_T minTrackRadius;
-EXPORT DIST_T maxTrackGrade = 5.0;
+//EXPORT DIST_T minTrackRadius;
+//EXPORT DIST_T maxTrackGrade = 5.0;
static int suspendElevUpdates = FALSE;
@@ -115,9 +129,9 @@ EXPORT void DescribeTrack( track_cp trk, char * str, CSIZE_T len )
}
-EXPORT DIST_T GetTrkDistance( track_cp trk, coOrd pos )
+EXPORT DIST_T GetTrkDistance( track_cp trk, coOrd * pos )
{
- return trackCmds( GetTrkType(trk) )->distance( trk, &pos );
+ return trackCmds( GetTrkType(trk) )->distance( trk, pos );
}
/**
@@ -133,7 +147,7 @@ EXPORT DIST_T GetTrkDistance( track_cp trk, coOrd pos )
* \return NULL if there is no track, pointer to track otherwise
*/
-EXPORT track_p OnTrack2( coOrd * fp, BOOL_T complain, BOOL_T track, BOOL_T ignoreHidden )
+EXPORT track_p OnTrack2( coOrd * fp, BOOL_T complain, BOOL_T track, BOOL_T ignoreHidden, track_p t )
{
track_p trk;
DIST_T distance, closestDistance = 1000000;
@@ -148,6 +162,7 @@ EXPORT track_p OnTrack2( coOrd * fp, BOOL_T complain, BOOL_T track, BOOL_T ignor
TRK_ITERATE( trk ) {
if ( track && !IsTrack(trk) )
continue;
+ if (trk == t) continue;
if (trk->hi.x < q0.x ||
trk->lo.x > q1.x ||
trk->hi.y < q0.y ||
@@ -186,7 +201,11 @@ EXPORT track_p OnTrack2( coOrd * fp, BOOL_T complain, BOOL_T track, BOOL_T ignor
EXPORT track_p OnTrack( coOrd * fp, BOOL_T complain, BOOL_T track )
{
- return OnTrack2( fp, complain, track, TRUE );
+ return OnTrack2( fp, complain, track, TRUE, NULL );
+}
+
+EXPORT track_p OnTrackIgnore (coOrd * fp, BOOL_T complain, BOOL_T track, track_p t ) {
+ return OnTrack2(fp, complain, track, TRUE, t);
}
@@ -316,7 +335,7 @@ EXPORT void SetTrkScale( track_p trk, SCALEINX_T si )
trk->scale = (char)si;
}
-EXPORT LAYER_T GetTrkLayer( track_p trk )
+EXPORT unsigned int GetTrkLayer( track_p trk )
{
return trk->layer;
}
@@ -490,13 +509,22 @@ EXPORT void SetTrkEndPtCnt( track_p trk, EPINX_T cnt )
memset( &trk->endPt[oldCnt], 0, (cnt-oldCnt) * sizeof *trk->endPt );
}
-
-EXPORT void SetTrkLayer( track_p trk, int layer )
+/**
+ * Set the layer for a track.
+ *
+ * \param trk IN the layer to change the layer for
+ * \param layer IN the new layer for the track
+ */
+void SetTrkLayer( track_p trk, int layer )
{
+ DecrementLayerObjects(trk->layer);
+
if (useCurrentLayer)
- trk->layer = (LAYER_T)curLayer;
+ trk->layer = (unsigned int)curLayer;
else
- trk->layer = (LAYER_T)layer;
+ trk->layer = (unsigned int)layer;
+
+ IncrementLayerObjects(trk->layer);
}
@@ -580,27 +608,36 @@ EXPORT BOOL_T WriteEndPt( FILE * f, track_cp trk, EPINX_T ep )
assert ( endPt != NULL );
if (endPt->track == NULL ||
( exportingTracks && !GetTrkSelected(endPt->track) ) ) {
- rc &= fprintf( f, "\tE " )>0;
+ rc &= fprintf( f, "\tE4 " )>0;
} else {
- rc &= fprintf( f, "\tT %d ", endPt->track->index )>0;
+ rc &= fprintf( f, "\tT4 %d ", endPt->track->index )>0;
}
rc &= fprintf( f, "%0.6f %0.6f %0.6f", endPt->pos.x, endPt->pos.y, endPt->angle )>0;
option = (endPt->option<<8) | (endPt->elev.option&0xFF);
if ( option != 0 ) {
rc &= fprintf( f, " %ld %0.6f %0.6f", option, endPt->elev.doff.x, endPt->elev.doff.y )>0;
- if ( (endPt->elev.option&ELEV_MASK) != ELEV_NONE ) {
- switch ( endPt->elev.option&ELEV_MASK ) {
- case ELEV_DEF:
- rc &= fprintf( f, " %0.6f", endPt->elev.u.height )>0;
- break;
- case ELEV_STATION:
- rc &= fprintf( f, " \"%s\"", PutTitle( endPt->elev.u.name ) )>0;
- break;
- default:
- ;
- }
+ switch ( endPt->elev.option&ELEV_MASK ) {
+ case ELEV_DEF:
+ rc &= fprintf( f, " %0.6f ", endPt->elev.u.height )>0;
+ break;
+ case ELEV_STATION:
+ rc &= fprintf( f, " \"%s\" ", PutTitle( endPt->elev.u.name ) )>0;
+ break;
+ default:
+ rc &= fprintf( f, " 0.0 ")>0;
}
+ } else {
+ rc &= fprintf( f, " 0 0.0 0.0 0.0 ")>0;
}
+ if ((endPt->elev.option&ELEV_MASK) == ELEV_DEF)
+ rc &= fprintf( f, "%0.6f ",endPt->elev.u.height)>0;
+ else
+ rc &= fprintf( f, "0.0 ")>0;
+ long elevVisible = (endPt->elev.option&ELEV_VISIBLE)?1:0;
+ long elevType = endPt->elev.option&ELEV_MASK;
+ long gapType = endPt->option;
+ rc &= fprintf( f, "%ld %ld %ld ", elevVisible, elevType, gapType)>0;
+ rc &= fprintf( f, "%0.6f ", trk->elev)>0;
rc &= fprintf( f, "\n" )>0;
return rc;
}
@@ -652,6 +689,28 @@ EXPORT EPINX_T PickUnconnectedEndPoint( coOrd p, track_cp trk )
return inx;
}
+EXPORT EPINX_T PickUnconnectedEndPointSilent( coOrd p, track_cp trk )
+{
+ EPINX_T inx, i;
+ DIST_T d=10000.0, dd;
+ coOrd pos;
+ inx = -1;
+
+ for ( i=0; i<trk->endCnt; i++ ) {
+ if (trk->endPt[i].track == NULL) {
+ pos = trk->endPt[i].pos;
+ dd=FindDistance(p, pos);
+ if (inx == -1 || dd <= d) {
+ d = dd;
+ inx = i;
+ }
+ }
+ }
+
+ return inx;
+}
+
+
EXPORT EPINX_T GetEndPtConnectedToMe( track_p trk, track_p me )
{
@@ -805,6 +864,15 @@ EXPORT BOOL_T MakeParallelTrack(
return FALSE;
}
+EXPORT BOOL_T RebuildTrackSegs(
+ track_p trk)
+{
+ if (trackCmds(trk->type)->rebuildSegs)
+ return trackCmds(trk->type)->rebuildSegs(trk);
+ return FALSE;
+}
+
+
/*****************************************************************************
*
@@ -855,7 +923,7 @@ LOG( log_track, 1, ( "NewTrack( T%d, t%d, E%d, X%ld)\n", index, type, endCnt, ex
trk->index = index;
trk->type = type;
trk->layer = curLayer;
- trk->scale = (char)curScaleInx;
+ trk->scale = (char)GetLayoutCurScale();
trk->bits = TB_VISIBLE;
trk->elevMode = ELEV_ALONE;
trk->elev = 0;
@@ -874,6 +942,7 @@ LOG( log_track, 1, ( "NewTrack( T%d, t%d, E%d, X%ld)\n", index, type, endCnt, ex
trk->extraSize = extraSize;
UndoNew( trk );
trackCount++;
+ IncrementLayerObjects(curLayer);
InfoCount( trackCount );
return trk;
}
@@ -971,10 +1040,12 @@ LOG( log_track, 4, ( "DeleteTrack(T%d)\n", GetTrkIndex(trk) ) )
}
CheckDeleteSwitchmotor( trk );
CheckDeleteBlock( trk );
- UndoDelete( trk );
- MainRedraw();
+ DecrementLayerObjects(trk->layer);
trackCount--;
AuditTracks( "deleteTrack T%d", trk->index);
+ UndoDelete(trk); /**< Attention: trk is invalidated during that call */
+ MainRedraw();
+ MapRedraw();
InfoCount( trackCount );
return TRUE;
}
@@ -1296,8 +1367,10 @@ static void AuditPrint( char * msg )
{
time_t clock;
if (auditFile == NULL) {
- sprintf( message, "%s%s%s", workingDir, FILE_SEP_CHAR, sAuditF );
- auditFile = fopen( message, "a+" );
+ char *path;
+ MakeFullpath(&path, workingDir, sAuditF, NULL);
+ auditFile = fopen( path, "a+" );
+ free(path);
if (auditFile == NULL) {
NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Audit"), message, strerror(errno) );
auditIgnore = TRUE;
@@ -1524,6 +1597,7 @@ EXPORT STATUS_T EndPtDescriptionMove(
if (action != C_UP)
DrawLine( &tempD, p0, p1, 0, wDrawColorBlack );
MainRedraw();
+ MapRedraw();
return action==C_UP?C_TERMINATE:C_CONTINUE;
case C_REDRAW:
@@ -1697,9 +1771,11 @@ EXPORT BOOL_T SplitTrack( track_p trk, coOrd pos, EPINX_T ep, track_p *leftover,
*leftover = NULL;
LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos.x, pos.y ) )
- if ((splitCmd = trackCmds(trk->type)->split) == NULL) {
- ErrorMessage( MSG_CANT_SPLIT_TRK, trackCmds(trk->type)->name );
- return FALSE;
+ if (((splitCmd = trackCmds(trk->type)->split) == NULL)) {
+ if (!(FindDistance( trk->endPt[ep].pos, pos) <= minLength)) {
+ ErrorMessage( MSG_CANT_SPLIT_TRK, trackCmds(trk->type)->name );
+ return FALSE;
+ }
}
UndrawNewTrack( trk );
UndoModify( trk );
@@ -1720,11 +1796,6 @@ LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos
*leftover = trk2;
DrawNewTrack( trk );
-#ifdef LATER
- } else if ( IsTurnout(trk) ) {
- ErrorMessage( MSG_CANT_SPLIT_TRK, _("Turnout") );
- return FALSE;
-#endif
} else if ( epCnt == 2 &&
(d = FindDistance( trk->endPt[1-ep].pos, pos )) <= minLength) {
@@ -1737,15 +1808,9 @@ LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos
DisconnectTracks( trk, 1-ep, trk2, ep2 );
LOG( log_track, 2, ( " at endPt with T%d[%d]\n", trk2->index, ep2 ) )
DrawNewTrack( trk2 );
-#ifdef LATER
- *trk = trk2;
- *ep = ep1;
- *leftover = trk;
-#endif
+
} else {
-#ifdef LATER
- *trk = NULL;
-#endif
+
LOG( log_track, 2, ( " at endPt (no connection)\n") )
}
DrawNewTrack( trk );
@@ -1833,6 +1898,7 @@ EXPORT BOOL_T TraverseTrack(
return FALSE;
trvTrk->length = -1;
trvTrk->dist = 0.0;
+
}
return TRUE;
}
@@ -1954,22 +2020,6 @@ EXPORT BOOL_T GetTrackParams( int inx, track_p trk, coOrd pos, trackParams_t * p
return trackCmds(trk->type)->getTrackParams( inx, trk, pos, params );
} else {
ASSERT( FALSE ); /* CHECKME */
-#ifdef LATER
- switch ( inx ) {
- case PARAMS_1ST_JOIN:
- case PARAMS_2ND_JOIN:
- ErrorMessage( MSG_JOIN_TRK, (inx==PARAMS_1ST_JOIN?_("First"):_("Second")) );
- break;
- case PARAMS_EXTEND:
- ErrorMessage( MSG_CANT_EXTEND );
- break;
- case PARAMS_PARALLEL:
- ErrorMessage( MSG_INV_TRK_PARALLEL );
- break;
- default:
- ErrorMessage( MSG_INVALID_TRK );
- }
-#endif
return FALSE;
}
}
@@ -2113,15 +2163,7 @@ EXPORT void DrawTie(
Translate( &p[2], pos, angle+180, length );
Translate( &p[3], p[2], angle-90, width );
Translate( &p[2], p[2], angle+90, width );
-#ifdef LATER
- lo = hi = p[0];
- for ( i=1; i<4; i++ ) {
- if ( p[i].x < lo.x ) lo.x = p[i].x;
- if ( p[i].y < lo.y ) lo.y = p[i].y;
- if ( p[i].x > hi.x ) hi.x = p[i].x;
- if ( p[i].y > hi.y ) hi.y = p[i].y;
- }
-#endif
+
if ( d == &mainD ) {
lo.x -= RBORDER/mainD.dpi*mainD.scale;
lo.y -= TBORDER/mainD.dpi*mainD.scale;
@@ -2150,7 +2192,7 @@ EXPORT void DrawCurvedTies(
ANGLE_T a1,
wDrawColor color )
{
- tieData_p td = GetScaleTieData(GetTrkScale(trk));
+ tieData_p td;
DIST_T len;
ANGLE_T ang, dang;
coOrd pos;
@@ -2160,6 +2202,9 @@ EXPORT void DrawCurvedTies(
return;
if ( trk == NULL )
return;
+
+ td = GetScaleTieData(GetTrkScale(trk));
+
if ( (!GetTrkVisible(trk)) && drawTunnel!=DRAW_TUNNEL_SOLID )
return;
if (color == wDrawColorBlack)
@@ -2235,7 +2280,8 @@ LOG( log_track, 4, ( "DST( (%0.3f %0.3f) R%0.3f A%0.3f..%0.3f)\n",
} else if (d->options & DC_QUICK) {
DrawArc( d, p, r, a0, a1, ((d->scale<32) && centerDrawMode && !(options&DTS_NOCENTER)) ? 1 : 0, 0, color );
} else {
- if ( (d->scale <= 1 && (d->options&DC_SIMPLE)==0) || (d->options&DC_CENTERLINE)!=0 ) {
+ if ( (d->scale <= 1 && (d->options&DC_SIMPLE)==0) || (d->options&DC_CENTERLINE)!=0
+ || (d->scale <= scale2rail/2 && d->options&DC_PRINT && printCenterLines)) { // if printing two rails respect print CenterLine option
long options = d->options;
d->options |= DC_DASH;
DrawArc( d, p, r, a0, a1, 0, 0, color );
@@ -2263,7 +2309,7 @@ EXPORT void DrawStraightTies(
coOrd p1,
wDrawColor color )
{
- tieData_p td = GetScaleTieData(GetTrkScale(trk));
+ tieData_p td;
DIST_T tieOff0=0.0, tieOff1=0.0;
DIST_T len, dlen;
coOrd pos;
@@ -2274,6 +2320,8 @@ EXPORT void DrawStraightTies(
return;
if ( trk == NULL )
return;
+
+ td = GetScaleTieData(GetTrkScale(trk));
if ( (!GetTrkVisible(trk)) && drawTunnel!=DRAW_TUNNEL_SOLID )
return;
if ( color == wDrawColorBlack )
@@ -2350,7 +2398,8 @@ LOG( log_track, 4, ( "DST( (%0.3f %0.3f) .. (%0.3f..%0.3f)\n",
} else if (d->options&DC_QUICK) {
DrawLine( d, p0, p1, 0, color );
} else {
- if ( (d->scale <= 1 && (d->options&DC_SIMPLE)==0) || (d->options&DC_CENTERLINE)!=0 ) {
+ if ( (d->scale <= 1 && (d->options&DC_SIMPLE)==0) || (d->options&DC_CENTERLINE)!=0
+ || (d->scale <= scale2rail/2 && d->options&DC_PRINT && printCenterLines)) { // if printing two rails respect print CenterLine option
long options = d->options;
d->options |= DC_DASH;
DrawLine( d, p0, p1, 0, color );
@@ -2393,7 +2442,7 @@ EXPORT wDrawColor GetTrkColor( track_p trk, drawCmd_p d )
}
}
if ( (d->options&(DC_GROUP)) == 0 ) {
- if ( grade > maxTrackGrade )
+ if ( grade > GetLayoutMaxTrackGrade())
return exceptionColor;
if ( QueryTrack( trk, Q_EXCEPTION ) )
return exceptionColor;
@@ -2406,7 +2455,7 @@ EXPORT wDrawColor GetTrkColor( track_p trk, drawCmd_p d )
}
if ( (d->options&(DC_GROUP)) == 0 ) {
if ( (IsTrack(trk)?(colorLayers&1):(colorLayers&2)) )
- return GetLayerColor((LAYER_T)curTrackLayer);
+ return GetLayerColor((unsigned int)curTrackLayer);
}
return wDrawColorBlack;
}
@@ -2434,7 +2483,7 @@ EXPORT void DrawTrack( track_cp trk, drawCmd_p d, wDrawColor color )
return;
if ( (IsTrack(trk)?(colorLayers&1):(colorLayers&2)) &&
d != &mapD && color == wDrawColorBlack )
- color = GetLayerColor((LAYER_T)curTrackLayer);
+ color = GetLayerColor((unsigned int)curTrackLayer);
scale2rail = (d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale;
if ( (!inDrawTracks) &&
tieDrawMode!=TIEDRAWMODE_NONE &&
@@ -2516,11 +2565,11 @@ static void DrawUnconnectedEndPt( drawCmd_p d, coOrd p, ANGLE_T a, DIST_T trackG
Translate( &p0, p, a, trackGauge );
Translate( &p1, p, a-180.0, trackGauge );
DrawLine( d, p0, p1, 0, color );
- if (d->scale < 8) {
+ if (d->scale < 8 || drawUnconnectedEndPt > 0) {
Translate( &p, p, a+90.0, 0.2 );
Translate( &p0, p, a, trackGauge );
Translate( &p1, p, a-180.0, trackGauge );
- DrawLine( d, p0, p1, 0, color );
+ DrawLine( d, p0, p1, (drawUnconnectedEndPt>0)?4:0, (drawUnconnectedEndPt>1)?exceptionColor:color );
}
}
@@ -2605,7 +2654,7 @@ EXPORT void DrawEndPt(
EPINX_T ep,
wDrawColor color )
{
- coOrd p, pp;
+ coOrd p;
ANGLE_T a;
track_p trk1;
coOrd p0, p1, p2;
@@ -2630,11 +2679,8 @@ EXPORT void DrawEndPt(
if (labelScale >= d->scale)
DrawEndElev( d, trk, ep, color );
- if ( d->scale >= ((d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale) )
- return;
-
trk1 = GetTrkEndTrk(trk,ep);
- pp = p = GetTrkEndPos( trk, ep );
+ p = GetTrkEndPos( trk, ep );
a = GetTrkEndAngle( trk, ep ) + 90.0;
trackGauge = GetTrkGauge(trk);
@@ -2643,6 +2689,9 @@ EXPORT void DrawEndPt(
return;
}
+ if ( d->scale >= ((d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale) )
+ return;
+
sepBoundary = FALSE;
if ((d->options&DC_PRINT)==0 && importTrack == NULL && GetTrkSelected(trk) && (!GetTrkSelected(trk1))) {
DIST_T len;
@@ -2734,14 +2783,13 @@ EXPORT void DrawTracks( drawCmd_p d, DIST_T scale, coOrd orig, coOrd size )
{
track_cp trk;
TRKINX_T inx;
- wIndex_t count;
+ wIndex_t count = 0;
coOrd lo, hi;
BOOL_T doSelectRecount = FALSE;
inDrawTracks = TRUE;
- count = 0;
InfoCount( 0 );
- count = 0;
+
d->options |= DC_TIES;
TRK_ITERATE( trk ) {
if ( (d->options&DC_PRINT) != 0 &&
@@ -2779,43 +2827,11 @@ EXPORT void DrawTracks( drawCmd_p d, DIST_T scale, coOrd orig, coOrd size )
}
-EXPORT void RedrawLayer( LAYER_T l, BOOL_T draw )
+EXPORT void RedrawLayer( unsigned int l, BOOL_T draw )
{
MainRedraw();
-#ifdef LATER
- track_cp trk;
- track_cp trk1;
- EPINX_T ep;
- wIndex_t count;
- coOrd hi, lo;
+ MapRedraw();
- count = 0;
- InfoCount( 0 );
- TRK_ITERATE( trk ) {
- if (GetTrkLayer(trk) != l)
- continue;
- GetBoundingBox( trk, &hi, &lo );
- if ( !OFF_MAIND( lo, hi ) ) {
- if ( GetLayerVisible( l ) ) {
- DrawTrack( trk, &mainD, draw?wDrawColorBlack:wDrawColorWhite );
- }
- for (ep=0; ep<GetTrkEndPtCnt(trk); ep++) {
- trk1 = GetTrkEndTrk( trk, ep );
- if ( trk1 && GetTrkLayer(trk1) != l && GetLayerVisible(GetTrkLayer(trk1)) ) {
- DrawEndPt( &mainD, trk1, GetEndPtConnectedToMe( trk1, trk ),
- draw?wDrawColorBlack:wDrawColorWhite );
- }
- }
- count++;
- if (count%10 == 0)
- InfoCount( count );
- }
- if (draw)
- ClrTrkBits( trk, TB_SELECTED );
- }
- InfoCount( trackCount );
- SelectRecount();
-#endif
}