From d1a8285f818eb7e5c3d6a05709ea21a808490b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 19 Mar 2018 19:55:58 +0100 Subject: New upstream version 5.1.0 --- app/bin/track.c | 270 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 143 insertions(+), 127 deletions(-) (limited to 'app/bin/track.c') 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 #include #include #include #include -#include "track.h" +#include + #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; iendCnt; 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