summaryrefslogtreecommitdiff
path: root/app/bin/cgroup.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2024-11-14 19:35:45 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2024-11-14 19:35:45 +0100
commitdf5520aa2dae5b3ce7abf8733dcdd152898af163 (patch)
tree00d3047bfb14f682bfb5a21010c731ed649bfed7 /app/bin/cgroup.c
parentdf247efec654e512242e4f4f1b0212034f9e01fe (diff)
parentec3c0f6f6e7153fa797dc57a0e95779cbc63a23b (diff)
Merge branch 'release/debian/1_5.3.0GA-1'debian/1_5.3.0GA-1
Diffstat (limited to 'app/bin/cgroup.c')
-rw-r--r--app/bin/cgroup.c1210
1 files changed, 674 insertions, 536 deletions
diff --git a/app/bin/cgroup.c b/app/bin/cgroup.c
index 1183e76..6940ea0 100644
--- a/app/bin/cgroup.c
+++ b/app/bin/cgroup.c
@@ -18,27 +18,32 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <ctype.h>
-#include <math.h>
-#include <string.h>
-
+#include "cselect.h"
#include "compound.h"
#include "cundo.h"
#include "custom.h"
#include "fileio.h"
-#include "i18n.h"
#include "tbezier.h"
#include "tcornu.h"
#include "common.h"
-#include "messages.h"
#include "param.h"
#include "shrtpath.h"
#include "track.h"
-#include "utility.h"
+#include "trkendpt.h"
+#include "common-ui.h"
+/*
+ * Note: Bumper support
+ * Currently Ungroup will convert 1 ended Turnouts (Bumpers) to simple 2-ended Straight
+ * Group will remove any Bumpers from the Selected track list
+ * See TODO-BUMPER
+ *
+ * The remaining issue is that the ShortestPath logic aborts if it gets to the end of a
+ * path elem list and can't find the corresponing EP.
+ */
/*****************************************************************************
*
@@ -54,87 +59,96 @@ static dynArr_t pathPtr_da;
static char groupManuf[STR_SIZE];
static char groupDesc[STR_SIZE];
static char groupPartno[STR_SIZE];
-static char groupTitle[STR_SIZE];
+static char groupTitle[STR_LONG_SIZE];
static int groupCompoundCount = 0;
-extern TRKTYP_T T_BZRTRK;
-extern TRKTYP_T T_BZRLIN;
-extern TRKTYP_T T_CORNU;
+
+/*****************************************************************************
+ *
+ * Ungroup
+ *
+ */
typedef struct {
- int segInx;
- EPINX_T segEP;
- int inx;
- track_p trk;
- } mergePt_t;
+ int segInx;
+ EPINX_T segEP;
+ int inx;
+ track_p trk;
+} mergePt_t;
static dynArr_t mergePt_da;
#define mergePt(N) DYNARR_N( mergePt_t, mergePt_da, N )
static void AddMergePt(
- int segInx,
- EPINX_T segEP )
+ int segInx,
+ EPINX_T segEP )
{
int inx;
mergePt_t * mp;
for ( inx=0; inx<mergePt_da.cnt; inx++ ) {
mp = &mergePt(inx);
if ( mp->segInx == segInx &&
- mp->segEP == segEP )
+ mp->segEP == segEP ) {
return;
+ }
}
DYNARR_APPEND( mergePt_t, mergePt_da, 10 );
mp = &mergePt(mergePt_da.cnt-1);
mp->segInx = segInx;
mp->segEP = segEP;
mp->inx = mergePt_da.cnt-1;
-LOG( log_group, 2, ( " MergePt: %d.%d\n", segInx, segEP ) );
+ LOG( log_group, 2, ( " MergePt: %d.%d\n", segInx, segEP ) );
}
static EPINX_T FindEP(
- EPINX_T epCnt,
- trkEndPt_p endPts,
- coOrd pos )
+ EPINX_T epCnt,
+ trkEndPt_p endPts,
+ coOrd pos )
{
DIST_T dist;
EPINX_T ep;
for ( ep=0; ep<epCnt; ep++ ) {
- dist = FindDistance( pos, endPts[ep].pos );
- if ( dist < connectDistance )
+ dist = FindDistance( pos, GetEndPtPos( EndPtIndex( endPts, ep ) ) );
+ if ( dist < connectDistance ) {
return ep;
+ }
}
return -1;
}
static void SegOnMP(
- int segInx,
- int mpInx,
- int segCnt,
- int * map )
+ int segInx,
+ int mpInx,
+ int segCnt,
+ int * map )
{
int inx;
mergePt_t * mp;
if ( map[segInx] < 0 ) {
-LOG( log_group, 2, ( " S%d: on MP%d\n", segInx, mpInx ) );
+ LOG( log_group, 2, ( " S%d: on MP%d\n", segInx, mpInx ) );
map[segInx] = mpInx;
return;
}
-LOG( log_group, 2, ( " S%d: remapping MP%d to MP%d\n", segInx, mpInx, map[segInx] ) );
+ LOG( log_group, 2, ( " S%d: remapping MP%d to MP%d\n", segInx, mpInx,
+ map[segInx] ) );
for ( inx=0; inx<segCnt; inx++ )
- if ( map[inx] == mpInx )
+ if ( map[inx] == mpInx ) {
map[inx] = map[segInx];
+ }
for ( inx=0; inx<mergePt_da.cnt; inx++ ) {
- if ( inx == map[segInx] )
+ if ( inx == map[segInx] ) {
continue;
+ }
mp = &mergePt(inx);
- if ( mp->inx == mpInx )
+ if ( mp->inx == mpInx ) {
mp->inx = map[segInx];
+ }
}
}
static void GroupCopyTitle(
- char * title )
+ char * title )
{
char *mP, *nP, *pP;
int mL, nL, pL;
@@ -153,23 +167,32 @@ static void GroupCopyTitle(
groupPartno[pL] = '\0';
} else {
if ( mL != (int)strlen( groupManuf ) ||
- strncmp( groupManuf, mP, mL ) != 0 )
+ strncmp( groupManuf, mP, mL ) != 0 ) {
groupManuf[0] = '\0';
+ }
if ( nL != (int)strlen( groupDesc ) ||
- strncmp( groupDesc, nP, nL ) != 0 )
+ strncmp( groupDesc, nP, nL ) != 0 ) {
groupDesc[0] = '\0';
+ }
if ( pL != (int)strlen( groupPartno ) ||
- strncmp( groupPartno, pP, pL ) != 0 )
+ strncmp( groupPartno, pP, pL ) != 0 ) {
groupPartno[0] = '\0';
+ }
}
}
+// TODO-BUMPER - handle paths which don't end on an EP
+// Set GROUP_BUMPER_REFCOUT
+// to 1 to convert Bumper tracks to Straight tracks with 2 EP
+// to 2 to create 1 EP Turnout tracks
+#define GROUP_BUMPER_REFCOUNT (1)
EXPORT void UngroupCompound(
- track_p trk )
+ track_p trk )
{
- struct extraData *xx = GetTrkExtraData(trk);
- struct extraData *xx1;
+ struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataCompound_t);
+ struct extraDataCompound_t *xx1;
trkSeg_p sp;
track_p trk0, trk1;
int segCnt, segInx, segInx1;
@@ -187,7 +210,7 @@ EXPORT void UngroupCompound(
typedef struct {
track_p trk;
EPINX_T ep[2];
- } segTrack_t;
+ } segTrack_t;
#define segTrack(N) DYNARR_N( segTrack_t, segTrack_da, N )
static dynArr_t segTrack_da;
segTrack_t * stp, * stp1;
@@ -217,87 +240,114 @@ EXPORT void UngroupCompound(
}
#endif
-LOG( log_group, 1, ( "Ungroup( T%d )\n", GetTrkIndex(trk) ) );
+ LOG( log_group, 1, ( "Ungroup( T%d )\n", GetTrkIndex(trk) ) );
epCnt = GetTrkEndPtCnt(trk);
- for ( segCnt=0; segCnt<xx->segCnt&&IsSegTrack(&xx->segs[segCnt]); segCnt++ );
- ASSERT( (epCnt==0) == (segCnt==0) );
+ segCnt = xx->segCnt;
+ int trackCount = 0;
+ for ( sp=xx->segs; sp<&xx->segs[xx->segCnt]; sp++ ) {
+ if (IsSegTrack(sp)) { trackCount++; }
+ }
+ //CHECK( (epCnt==0) == (segCnt==0) );
+ CHECK( (epCnt==0) == (trackCount==0) );
turnoutChanged = FALSE;
if ( epCnt > 0 ) {
turnoutChanged = TRUE;
/* 1: collect EPs
*/
- DYNARR_SET( trkEndPt_t, tempEndPts_da, epCnt );
+ TempEndPtsSet( epCnt );
DYNARR_SET( segTrack_t, segTrack_da, segCnt );
- memset( segTrack_da.ptr, 0, segCnt * sizeof segTrack(0) );
+ memset( &segTrack(0), 0, segCnt * sizeof segTrack(0) );
for ( ep=0; ep<epCnt; ep++ ) {
- epp = &tempEndPts(ep);
- epp->pos = GetTrkEndPos( trk, ep );
- epp->angle = GetTrkEndAngle( trk, ep );
- Rotate( &epp->pos, xx->orig, -xx->angle );
- epp->pos.x -= xx->orig.x;
- epp->pos.y -= xx->orig.y;
- epp->track = GetTrkEndTrk( trk, ep );
- if ( epp->track )
- epp->index = GetEndPtConnectedToMe( epp->track, trk );
- else
- epp->index = -1;
-LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, epp->pos.y, epp->angle, epp->track?GetTrkIndex(epp->track):-1, epp->track?epp->index:-1 ) );
+ epp = TempEndPt(ep);
+ coOrd pos = GetTrkEndPos( trk, ep );
+ Rotate( &pos, xx->orig, -xx->angle );
+ pos.x -= xx->orig.x;
+ pos.y -= xx->orig.y;
+ ANGLE_T angle = GetTrkEndAngle( trk, ep );
+ track_p trk1 = GetTrkEndTrk( trk, ep );
+ EPINX_T ep1;
+ ep1 = trk1 ? GetEndPtConnectedToMe( trk1, trk ) : -1 ;
+ SetEndPt( epp, pos, angle );
+ SetEndPtTrack( epp, trk1 );
+ // Remember what EP on trk1 was connecting to me
+ SetEndPtEndPt( epp, ep1 );
+ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, pos.x, pos.y,
+ angle, trk1?GetTrkIndex(trk1):-1, ep1 ) );
}
/* 3: Count number of times each segment is referenced
* If the refcount differs between adjacent segments
* add segment with smaller count to mergePts
* Treat EndPts as a phantom segment with inx above segCnt
- * Path ends that don't map onto a real EndPt (bumpers) get a fake EP
+ * Path ends that don't map onto a real EndPt (bumpers) get a virtual EP
*/
DYNARR_SET( int, refCount_da, segCnt+epCnt );
- memset( refCount_da.ptr, 0, refCount_da.cnt * sizeof *(int*)0 );
- cp = (char *)xx->paths;
+ memset( &refCount(0), 0, refCount_da.cnt * sizeof *(int*)0 );
+ cp = (char *)GetPaths( trk );
while ( cp[0] ) {
cp += strlen(cp)+1;
while ( cp[0] ) {
+ // Process 1st seg in sub-path
GetSegInxEP( cp[0], &segInx, &segEP );
+ // Find EP its connected to
pos = GetSegEndPt( xx->segs+segInx, segEP, FALSE, NULL );
- segInx1 = FindEP( tempEndPts_da.cnt, &tempEndPts(0), pos );
+ segInx1 = FindEP( TempEndPtsCount(), TempEndPt(0), pos );
if ( segInx1 >= 0 ) {
+ // Found existing EP, incr it's refCount
segInx1 += segCnt;
+ if ( segInx1 >= refCount_da.cnt ) {
+ InputError( "Invalid segInx1 %d", TRUE, segInx1 );
+ return;
+ }
refCount(segInx1)++;
} else {
- DYNARR_APPEND( trkEndPt_t, tempEndPts_da, 10 );
+ // No existing EP: must be a bumper, add virtual EP
+ epp = TempEndPtsAppend();
DYNARR_APPEND( int, refCount_da, 10 );
- epp = &tempEndPts(tempEndPts_da.cnt-1);
- epp->pos = pos;
- epp->angle = 0;
+ SetEndPt( epp, pos, 0 );
segInx1 = refCount_da.cnt-1;
- refCount(segInx1) = 2;
+ refCount(segInx1) = GROUP_BUMPER_REFCOUNT;
}
segEP1 = 0;
while ( cp[0] ) {
+ // Process remaining segs
GetSegInxEP( cp[0], &segInx, &segEP );
+ if ( segInx1 >= refCount_da.cnt ) {
+ InputError( "Invalid segInx1 %d", TRUE, segInx1 );
+ return;
+ }
+ // Incr it's refCoount
refCount(segInx)++;
- if ( refCount(segInx) > refCount(segInx1) )
+ // Is my refCount > then previous seg/EP?
+ if ( refCount(segInx) > refCount(segInx1) ) {
AddMergePt( segInx, segEP );
- if ( refCount(segInx1) > refCount(segInx) )
+ }
+ // Is previous seg/EP refCount > my refCount
+ if ( refCount(segInx1) > refCount(segInx) ) {
AddMergePt( segInx1, segEP1 );
+ }
+ // Advance to next seg
segInx1 = segInx;
segEP1 = 1-segEP;
cp++;
}
+ // Process last seg in sub-path
GetSegInxEP( cp[-1], &segInx, &segEP );
+ // Find EP its connected to
pos = GetSegEndPt( xx->segs+segInx, 1-segEP, FALSE, NULL );
- segInx = FindEP( tempEndPts_da.cnt, &tempEndPts(0), pos );
+ segInx = FindEP( TempEndPtsCount(), TempEndPt(0), pos );
if ( segInx >= 0 ) {
+ // Found EP, incr refCount
segInx += segCnt;
refCount(segInx)++;
} else {
- DYNARR_APPEND( trkEndPt_t, tempEndPts_da, 10 );
+ // No existing EP: must be a bumper, add virtual EP
+ epp = TempEndPtsAppend();
DYNARR_APPEND( int, refCount_da, 10 );
- epp = &tempEndPts(tempEndPts_da.cnt-1);
- epp->pos = pos;
- epp->angle = 0;
+ SetEndPt( epp, pos, 0 );
segInx = refCount_da.cnt-1;
- refCount(segInx) = 2;
+ refCount(segInx) = GROUP_BUMPER_REFCOUNT;
}
if ( refCount(segInx) > refCount(segInx1) ) {
AddMergePt( segInx, 0 );
@@ -306,22 +356,21 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
}
cp++;
}
- epCnt1 = tempEndPts_da.cnt;
-
+
/* 4: For each path element, map segment to a mergePt if the adjacent segment
* and EP is a mergePt
* If segment is already mapped then merge mergePts
*/
DYNARR_SET( int, refCount_da, segCnt );
- memset( refCount_da.ptr, -1, segCnt * sizeof *(int*)0 );
- cp = (char *)xx->paths;
+ memset( &refCount(0), -1, segCnt * sizeof *(int*)0 );
+ cp = (char *)GetPaths( trk );
while ( cp[0] ) {
cp += strlen(cp)+1;
while ( cp[0] ) {
GetSegInxEP( cp[0], &segInx, &segEP );
pos = GetSegEndPt( xx->segs+segInx, segEP, FALSE, NULL );
/*REORIGIN1( pos, xx->angle, xx->orig );*/
- segInx1 = FindEP( tempEndPts_da.cnt, &tempEndPts(0), pos );
+ segInx1 = FindEP( TempEndPtsCount(), TempEndPt(0), pos );
if ( segInx1 >= 0 ) {
segInx1 += segCnt;
}
@@ -346,7 +395,7 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
GetSegInxEP( cp[-1], &segInx, &segEP );
pos = GetSegEndPt( xx->segs+segInx, 1-segEP, FALSE, NULL );
/*REORIGIN1( pos, xx->angle, xx->orig );*/
- segInx = FindEP( tempEndPts_da.cnt, &tempEndPts(0), pos );
+ segInx = FindEP( TempEndPtsCount(), TempEndPt(0), pos );
if ( segInx >= 0 ) {
segInx += segCnt;
for ( inx=0; inx<mergePt_da.cnt; inx++ ) {
@@ -365,8 +414,9 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
*/
if ( mergePt_da.cnt > 0 ) {
for ( segInx=0; segInx<segCnt; segInx++ )
- if ( refCount(segInx) != mergePt(0).inx )
+ if ( refCount(segInx) != mergePt(0).inx ) {
break;
+ }
if ( segInx == segCnt ) {
/* all segments on same turnout, nothing we can do here */
turnoutChanged = FALSE;
@@ -383,11 +433,13 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
wDrawDelayUpdate( mainD.d, TRUE );
if ( turnoutChanged ) {
for ( ep=0; ep<epCnt; ep++ ) {
- epp = &tempEndPts(ep);
- if ( epp->track ) {
- DrawEndPt( &mainD, epp->track, epp->index, wDrawColorWhite );
+ epp = TempEndPt(ep);
+ track_p trk1 = GetEndPtTrack(epp);
+ if ( trk1 ) {
+ EPINX_T ep1 = GetEndPtEndPt(epp);
+ DrawEndPt( &mainD, trk1, ep1, wDrawColorWhite );
DrawEndPt( &mainD, trk, ep, wDrawColorWhite );
- DisconnectTracks( trk, ep, epp->track, epp->index );
+ DisconnectTracks( trk, ep, trk1, ep1 );
}
}
}
@@ -418,11 +470,13 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
*/
for ( inx=0; inx<mergePt_da.cnt; inx++ ) {
mp = &mergePt(inx);
- if ( mp->inx != inx )
+ if ( mp->inx != inx ) {
continue;
+ }
DYNARR_RESET( trkSeg_t, tempSegs_da );
- DYNARR_SET( trkEndPt_t, tempEndPts_da, epCnt1 );
DYNARR_RESET( char, pathPtr_da );
+ // Mark start of virtual EPs for this MergePt
+ epCnt1 = TempEndPtsCount();
for ( segInx=0; segInx<segCnt; segInx++ ) {
if ( refCount(segInx) == inx ) {
DYNARR_APPEND( trkSeg_t, tempSegs_da, 10 );
@@ -437,22 +491,23 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
pathPtr(off+2) = '\0';
for ( ep=0; ep<2; ep++ ) {
pos = GetSegEndPt( xx->segs+segInx, ep, FALSE, &angle );
- segEP = FindEP( epCnt1, &tempEndPts(0), pos );
+ segEP = FindEP( epCnt1, TempEndPt(0), pos );
if ( segEP >= 0 && segEP >= epCnt && segEP < epCnt1 ) {
/* was a bumper: no EP */
eps[ep] = -1;
+ // TODO-BUMPER To support Bumpers remove this continue
continue;
}
REORIGIN1( pos, xx->angle, xx->orig );
angle = NormalizeAngle( xx->angle+angle );
- eps[ep] = FindEP( tempEndPts_da.cnt-epCnt1, &tempEndPts(epCnt1), pos );
+ eps[ep] = -1;
+ if ( TempEndPtsCount()-epCnt1 > 0 ) {
+ eps[ep] = FindEP( TempEndPtsCount()-epCnt1, TempEndPt(epCnt1), pos );
+ }
if ( eps[ep] < 0 ) {
- DYNARR_APPEND( trkEndPt_t, tempEndPts_da, 10 );
- eps[ep] = tempEndPts_da.cnt-1-epCnt1;
- epp = &tempEndPts(tempEndPts_da.cnt-1);
- memset( epp, 0, sizeof *epp );
- epp->pos = pos;
- epp->angle = angle;
+ epp = TempEndPtsAppend();
+ eps[ep] = TempEndPtsCount()-1-epCnt1;
+ SetEndPt( epp, pos, angle );
}
}
segTrack(segInx).ep[0] = eps[0];
@@ -461,10 +516,7 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
}
DYNARR_SET( char, pathPtr_da, pathPtr_da.cnt+1 );
pathPtr(pathPtr_da.cnt-1) = '\0';
- if ( tempSegs_da.cnt == 0 ) {
- AbortProg( "tempSegs_da.cnt == 0" );
- continue;
- }
+ CHECK ( tempSegs_da.cnt != 0 );
GetSegBounds( zero, 0, tempSegs_da.cnt, &tempSegs(0), &orig, &size );
orig.x = -orig.x;
orig.y = -orig.y;
@@ -472,9 +524,13 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
Rotate( &orig, zero, xx->angle );
orig.x = xx->orig.x - orig.x;
orig.y = xx->orig.y - orig.y;
- trk1 = NewCompound( T_TURNOUT, 0, orig, xx->angle, xx->title, tempEndPts_da.cnt-epCnt1, &tempEndPts(epCnt1), NULL, pathPtr_da.cnt, &pathPtr(0), tempSegs_da.cnt, &tempSegs(0) );
- xx1 = GetTrkExtraData(trk1);
+ trk1 = NewCompound( T_TURNOUT, 0, orig, xx->angle, xx->title,
+ TempEndPtsCount()-epCnt1, TempEndPt(epCnt1), (PATHPTR_T)&pathPtr(0),
+ tempSegs_da.cnt, &tempSegs(0) );
+ xx1 = GET_EXTRA_DATA(trk1, T_TURNOUT, extraDataCompound_t);
xx1->ungrouped = TRUE;
+ xx1->pathOverRide = xx->pathOverRide;
+ xx1->pathNoCombine = xx->pathNoCombine;
SetTrkVisible( trk1, TRUE );
SetTrkNoTies( trk1, FALSE );
@@ -490,7 +546,10 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
/* 8: for remaining segments, create simple tracks
*/
for ( segInx=0; segInx<segCnt; segInx++ ) {
- if ( refCount(segInx) >= 0 ) continue;
+ if ( refCount(segInx) >= 0 ) { continue; }
+ if ( ! IsSegTrack( xx->segs+segInx ) ) {
+ continue;
+ }
SegProc( SEGPROC_NEWTRACK, xx->segs+segInx, &segProcData );
SetTrkScale( segProcData.newTrack.trk, GetTrkScale(trk) );
SetTrkBits( segProcData.newTrack.trk, TB_SELECTED );
@@ -503,20 +562,23 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
/* 9: reconnect tracks
*/
- cp = (char *)xx->paths;
+ cp = (char *)GetPaths( trk );
while ( cp[0] ) {
cp += strlen(cp)+1;
while ( cp[0] ) {
/* joint EP to this segment */
GetSegInxEP( cp[0], &segInx, &segEP );
stp = &segTrack(segInx);
- ep = FindEP( epCnt, &tempEndPts(0), GetSegEndPt( xx->segs+segInx, segEP, FALSE, NULL ) );
+ ep = FindEP( epCnt, TempEndPt(0), GetSegEndPt( xx->segs+segInx, segEP, FALSE,
+ NULL ) );
if ( ep >= 0 ) {
- epp = &tempEndPts(ep);
- if ( epp->track ) {
- ConnectTracks( stp->trk, stp->ep[segEP], epp->track, epp->index );
- DrawEndPt( &mainD, epp->track, epp->index, GetTrkColor(epp->track,&mainD) );
- epp->track = NULL;
+ epp = TempEndPt(ep);
+ track_p trk1 = GetEndPtTrack(epp);
+ if ( trk1 ) {
+ EPINX_T ep1 = GetEndPtEndPt(epp);
+ ConnectTracks( stp->trk, stp->ep[segEP], trk1, ep1 );
+ DrawEndPt( &mainD, trk1, ep1, GetTrkColor(trk1, &mainD) );
+ SetEndPtTrack( epp, NULL ); // Finished with this EP
}
}
stp1 = stp;
@@ -525,28 +587,35 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
while ( cp[0] ) {
GetSegInxEP( cp[0], &segInx, &segEP );
stp = &segTrack(segInx);
+ // Check EPs are not virtual (Bumpers)
+ // TODO-BUMPER May not be necessary
+ CHECK( stp->ep[segEP] >= 0 );
+ CHECK( stp1->ep[segEP1] >= 0 );
trk0 = GetTrkEndTrk( stp->trk, stp->ep[segEP] );
trk1 = GetTrkEndTrk( stp1->trk, stp1->ep[segEP1] );
if ( trk0 == NULL ) {
- if ( trk1 != NULL )
- AbortProg( "ungroup: seg half connected" );
+ CHECK ( trk1 == NULL );
ConnectTracks( stp->trk, stp->ep[segEP], stp1->trk, stp1->ep[segEP1] );
} else {
- if ( trk1 != stp->trk || stp1->trk != trk0 )
- AbortProg( "ungroup: last seg not connected to curr" );
+ CHECK( trk1 == stp->trk );
+ CHECK( stp1->trk == trk0 );
+ // ungroup: last seg not connected to curr
}
stp1 = stp;
segEP1 = 1-segEP;
cp++;
}
/* joint EP to last segment */
- ep = FindEP( epCnt, &tempEndPts(0), GetSegEndPt( xx->segs+segInx, segEP1, FALSE, NULL ) );
+ ep = FindEP( epCnt, TempEndPt(0), GetSegEndPt( xx->segs+segInx, segEP1, FALSE,
+ NULL ) );
if ( ep > 0 ) {
- epp = &tempEndPts(ep);
- if ( epp->track ) {
- ConnectTracks( stp1->trk, stp1->ep[segEP1], epp->track, epp->index );
- DrawEndPt( &mainD, epp->track, epp->index, wDrawColorWhite );
- epp->track = NULL;
+ epp = TempEndPt(ep);
+ track_p trk1 = GetEndPtTrack( epp );
+ if ( trk1 ) {
+ EPINX_T ep1 = GetEndPtEndPt( epp );
+ ConnectTracks( stp1->trk, stp1->ep[segEP1], trk1, ep1 );
+ DrawEndPt( &mainD, trk1, ep1, wDrawColorWhite );
+ SetEndPtTrack( epp, NULL ); // Finished with this EP
}
}
cp++;
@@ -566,7 +635,9 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
mp->trk = NULL;
}
} else {
- DrawNewTrack( segTrack(segInx).trk );
+ if ( segTrack(segInx).trk ) {
+ DrawNewTrack( segTrack(segInx).trk );
+ }
}
}
wDrawDelayUpdate( mainD.d, FALSE );
@@ -575,15 +646,16 @@ LOG( log_group, 1, ( " EP%d = [%0.3f %0.3f] A%0.3f T%d.%d\n", ep, epp->pos.x, ep
-EXPORT void DoUngroup( void )
+EXPORT void DoUngroup( void * unused )
{
track_p trk = NULL;
int ungroupCnt;
int oldTrackCount;
TRKINX_T lastTrackIndex;
- if ( log_group < 0 )
+ if ( log_group < 0 ) {
log_group = LogFindIndex( "group" );
+ }
groupManuf[0] = 0;
groupDesc[0] = 0;
groupPartno[0] = 0;
@@ -596,62 +668,71 @@ EXPORT void DoUngroup( void )
if ( GetTrkSelected( trk ) && GetTrkIndex(trk) <= lastTrackIndex ) {
oldTrackCount = trackCount;
UngroupTrack( trk );
- if ( oldTrackCount != trackCount )
+ if ( oldTrackCount != trackCount ) {
ungroupCnt++;
+ }
}
}
- if ( ungroupCnt )
+ if ( ungroupCnt ) {
InfoMessage( _("%d objects ungrouped"), ungroupCnt );
- else
+ } else {
InfoMessage( _("No objects ungrouped") );
+ }
}
static drawCmd_t groupD = {
- NULL, &tempSegDrawFuncs, DC_SEGTRACK, 1, 0.0, {0.0, 0.0}, {0.0, 0.0}, Pix2CoOrd, CoOrd2Pix };
+ NULL, &tempSegDrawFuncs, DC_SEGTRACK, 1, 0.0, {0.0, 0.0}, {0.0, 0.0}, Pix2CoOrd, CoOrd2Pix
+};
static long groupSegCnt;
static long groupReplace;
+static long groupNoCombine;
static double groupOriginX;
static double groupOriginY;
char * groupReplaceLabels[] = { N_("Replace with new group?"), NULL };
+char * groupNoCombineLabels[] = { N_("Turntable/TransferTable/DblSlipSwith?"), NULL };
static wWin_p groupW;
static paramIntegerRange_t r0_999999 = { 0, 999999 };
static paramFloatRange_t r_1000_1000 = { -1000.0, 1000.0, 80 };
static paramData_t groupPLs[] = {
-/*0*/ { PD_STRING, groupManuf, "manuf", PDO_NOPREF | PDO_STRINGLIMITLENGTH, (void*)350, N_("Manufacturer"), 0, 0, sizeof(groupManuf)},
-/*1*/ { PD_STRING, groupDesc, "desc", PDO_NOPREF | PDO_STRINGLIMITLENGTH, (void*)230, N_("Description"), 0, 0, sizeof(groupDesc)},
-/*2*/ { PD_STRING, groupPartno, "partno", PDO_NOPREF|PDO_DLGHORZ|PDO_DLGIGNORELABELWIDTH|PDO_STRINGLIMITLENGTH, (void*)100, N_("#"), 0, 0, sizeof(groupPartno)},
-/*3*/ { PD_LONG, &groupSegCnt, "segcnt", PDO_NOPREF, &r0_999999, N_("# Segments"), BO_READONLY },
+ /*0*/ { PD_STRING, groupManuf, "manuf", PDO_NOPREF | PDO_NOTBLANK, I2VP(350), N_("Manufacturer"), 0, 0, sizeof(groupManuf)},
+ /*1*/ { PD_STRING, groupDesc, "desc", PDO_NOPREF | PDO_NOTBLANK, I2VP(230), N_("Description"), 0, 0, sizeof(groupDesc)},
+ /*2*/ { PD_STRING, groupPartno, "partno", PDO_NOPREF|PDO_DLGHORZ|PDO_DLGIGNORELABELWIDTH|PDO_NOTBLANK, I2VP(100), N_("#"), 0, 0, sizeof(groupPartno)},
+ /*3*/ { PD_LONG, &groupSegCnt, "segcnt", PDO_NOPREF, &r0_999999, N_("# Segments"), BO_READONLY },
#define I_GROUP_ORIGIN_OFFSET 4 /* Need to change if add above */
-/*4*/ { PD_FLOAT, &groupOriginX, "orig", PDO_DIM, &r_1000_1000, N_("Offset X,Y:")},
-/*5*/ { PD_FLOAT, &groupOriginY, "origy",PDO_DIM | PDO_DLGHORZ, &r_1000_1000, ""},
-/*6*/ { PD_TOGGLE, &groupReplace, "replace", 0, groupReplaceLabels, "", BC_HORZ|BC_NOBORDER } };
-static paramGroup_t groupPG = { "group", 0, groupPLs, sizeof groupPLs/sizeof groupPLs[0] };
+ /*4*/ { PD_FLOAT, &groupOriginX, "orig", PDO_DIM, &r_1000_1000, N_("Offset X,Y:")},
+ /*5*/ { PD_FLOAT, &groupOriginY, "origy",PDO_DIM | PDO_DLGHORZ, &r_1000_1000, ""},
+ /*6*/ { PD_TOGGLE, &groupNoCombine, "noCombine", 0, groupNoCombineLabels, "", BC_HORZ|BC_NOBORDER },
+ /*7*/ { PD_TOGGLE, &groupReplace, "replace", 0, groupReplaceLabels, "", BC_HORZ|BC_NOBORDER }
+};
+static paramGroup_t groupPG = { "group", 0, groupPLs, COUNT( groupPLs ) };
typedef struct {
- track_p trk;
- int segStart;
- int segEnd;
- } groupTrk_t, * groupTrk_p;
+ track_p trk;
+ int segStart;
+ int segEnd;
+ int totalSegStart; //Where we are overall
+ int totalSegEnd;
+} groupTrk_t, * groupTrk_p;
static dynArr_t groupTrk_da;
#define groupTrk(N) DYNARR_N( groupTrk_t, groupTrk_da, N )
typedef struct {
- int groupInx;
- EPINX_T ep1, ep2;
- PATHPTR_T path;
- BOOL_T flip;
- } pathElem_t, *pathElem_p;
+ int groupInx;
+ EPINX_T ep1, ep2;
+ PATHPTR_T path;
+ BOOL_T flip;
+} pathElem_t, *pathElem_p;
typedef struct {
- int pathElemStart;
- int pathElemEnd;
- EPINX_T ep1, ep2;
- int conflicts;
- BOOL_T inGroup;
- BOOL_T done;
- } path_t, *path_p;
+ int pathElemStart;
+ int pathElemEnd;
+ EPINX_T ep1, ep2;
+ int conflicts;
+ BOOL_T inGroup;
+ BOOL_T done;
+} path_t, *path_p;
static dynArr_t path_da;
#define path(N) DYNARR_N( path_t, path_da, N )
static dynArr_t pathElem_da;
@@ -662,35 +743,37 @@ static int pathElemStart;
/*
* Find sub-path that connects the 2 EPs for the given track
*
- * \param trk IN Track
+ * \param trk IN Track
* \param ep1, ep2 IN EndPt index
* \param BOOL_T *flip OUT whether path is flipped
* \return sub-path that connects the 2 EPs
*/
static char * FindPathBtwEP(
- track_p trk,
- EPINX_T ep1,
- EPINX_T ep2,
- BOOL_T * flip )
+ track_p trk,
+ EPINX_T ep1,
+ EPINX_T ep2,
+ BOOL_T * flip )
{
- struct extraData * xx = GetTrkExtraData( trk );
char * cp;
coOrd trkPos[2];
-
- LOG( log_group, 3, (" FindPathBtwEP: T%d .%d .%d = ", trk?GetTrkIndex(trk):-1, ep1, ep2 ));
+
+ LOG( log_group, 3, (" FindPathBtwEP: T%d .%d .%d = ", trk?GetTrkIndex(trk):-1,
+ ep1, ep2 ));
if ( GetTrkType(trk) != T_TURNOUT ) {
- if ( ep1+ep2 != 1 )
- AbortProg( "findPathBtwEP" );
+ CHECK( ep1+ep2 == 1 );
*flip = ( ep1 == 1 );
- if (GetTrkType(trk) == T_CORNU ) { // Cornu doesn't have a path but lots of segs!
+ if (GetTrkType(trk) ==
+ T_CORNU ) { // Cornu doesn't have a path but lots of segs!
cp = CreateSegPathList(trk); // Make path
-LOG( log_group, 2, ( " Group: Cornu path:%s \n", cp ) )
- } else cp = "\1\0\0"; //One segment (but could be a Bezier)
+ LOG( log_group, 2, ( " Group: Cornu path:%s \n", cp ) )
+ } else { cp = "\1\0\0"; } //One segment (but could be a Bezier)
LOG( log_group, 3, (" Flip:%s Path= Seg=%d-\n", *flip?"T":"F", *cp ) );
return cp;
}
- cp = (char *)xx->paths;
+ struct extraDataCompound_t * xx = GET_EXTRA_DATA( trk, T_TURNOUT,
+ extraDataCompound_t );
+ cp = (char *)GetPaths( trk );
trkPos[0] = GetTrkEndPos(trk,ep1);
Rotate( &trkPos[0], xx->orig, -xx->angle );
trkPos[0].x -= xx->orig.x;
@@ -718,7 +801,7 @@ LOG( log_group, 2, ( " Group: Cornu path:%s \n", cp ) )
cp += strlen(cp);
GetSegInxEP( cp[-1], &segInx, &segEP );
segPos[1] = GetSegEndPt( &xx->segs[segInx], 1-segEP, FALSE, NULL );
-
+
// Find the closest seg end
for ( int inx = 0; inx<2; inx++ ) {
// Check 1st end
@@ -728,7 +811,9 @@ LOG( log_group, 2, ( " Group: Cornu path:%s \n", cp ) )
DIST_T dist2 = FindDistance( trkPos[1], segPos[1-inx] );
if ( dist2 > dist1 )
// 2nd end is further away
+ {
dist1 = dist2;
+ }
if ( dist1 < connectDistance && dist1 < dist ) {
// both ends are closest
dist = dist1;
@@ -742,18 +827,19 @@ LOG( log_group, 2, ( " Group: Cornu path:%s \n", cp ) )
}
cp++;
}
-LOG( log_group, 3, (" %s: %d..%d Flip:%s\n", pName, path?path[0]:-1, path?path[strlen(path)-1]:-1, *flip?"T":"F" ) );
+ LOG( log_group, 3, (" %s: %d..%d Flip:%s\n", pName, path?path[0]:-1,
+ path?path[strlen(path)-1]:-1, *flip?"T":"F" ) );
return path;
}
static int GroupShortestPathFunc(
- SPTF_CMD cmd,
- track_p trk,
- EPINX_T ep1,
- EPINX_T ep2,
- DIST_T dist,
- void * data )
+ SPTF_CMD cmd,
+ track_p trk,
+ EPINX_T ep1,
+ EPINX_T ep2,
+ DIST_T dist,
+ void * data )
{
track_p trk1;
path_t *pp;
@@ -766,13 +852,20 @@ static int GroupShortestPathFunc(
switch ( cmd ) {
case SPTC_MATCH:
- if ( !GetTrkSelected(trk) )
+ if ( !GetTrkSelected(trk) ) {
return 0;
+ }
+ // TODO-BUMPER may not be necessary
+ if ( GetTrkEndPtCnt(trk) < 2 && ep1 >= 1 ) {
+ return 1;
+ }
trk1 = GetTrkEndTrk(trk,ep1);
- if ( trk1 == NULL )
+ if ( trk1 == NULL ) {
return 1;
- if ( !GetTrkSelected(trk1) )
+ }
+ if ( !GetTrkSelected(trk1) ) {
return 1;
+ }
return 0;
case SPTC_MATCHANY:
@@ -781,7 +874,7 @@ static int GroupShortestPathFunc(
case SPTC_ADD_TRK:
LOG( log_group, 4, ( " Add T%d[%d]\n", GetTrkIndex(trk), ep2 ) )
DYNARR_APPEND( pathElem_t, pathElem_da, 10 );
- ppp = &pathElem(pathElem_da.cnt-1);
+ ppp = &pathElem(pathElem_da.cnt-1);
for ( inx=0; inx<groupTrk_da.cnt; inx++ ) {
if ( groupTrk(inx).trk == trk ) {
ppp->groupInx = inx;
@@ -791,7 +884,9 @@ static int GroupShortestPathFunc(
return 0;
}
}
- AbortProg( "GroupShortestPathFunc(SPTC_ADD_TRK, T%d) - track not in group", GetTrkIndex(trk) );
+ CHECKMSG( FALSE,
+ ( "GroupShortestPathFunc(SPTC_ADD_TRK, T%d) - track not in group",
+ GetTrkIndex(trk) ) );
case SPTC_TERMINATE:
ppp = &pathElem(pathElemStart);
@@ -803,31 +898,35 @@ static int GroupShortestPathFunc(
pos2 = GetTrkEndPos( trk, ppp->ep1 );
ang2 = GetTrkEndAngle( trk, ppp->ep1 );
ep1 = ep2 = -1;
- for ( ep=0; ep<tempEndPts_da.cnt; ep++ ) {
+ for ( ep=0; ep<TempEndPtsCount(); ep++ ) {
if ( ep1 < 0 ) {
- dist = FindDistance( pos1, tempEndPts(ep).pos );
- angle = NormalizeAngle( ang1 - tempEndPts(ep).angle + connectAngle/2.0 );
- if ( dist < connectDistance && angle < connectAngle )
+ dist = FindDistance( pos1, GetEndPtPos(TempEndPt(ep)));
+ angle = NormalizeAngle( ang1 - GetEndPtAngle(TempEndPt(ep)) +
+ connectAngle/2.0 );
+ if ( dist < connectDistance && angle < connectAngle ) {
ep1 = ep;
+ }
}
if ( ep2 < 0 ) {
- dist = FindDistance( pos2, tempEndPts(ep).pos );
- angle = NormalizeAngle( ang2 - tempEndPts(ep).angle + connectAngle/2.0 );
- if ( dist < connectDistance && angle < connectAngle )
+ dist = FindDistance( pos2, GetEndPtPos(TempEndPt(ep)) );
+ angle = NormalizeAngle( ang2 - GetEndPtAngle(TempEndPt(ep)) +
+ connectAngle/2.0 );
+ if ( dist < connectDistance && angle < connectAngle ) {
ep2 = ep;
+ }
}
}
if ( ep1<0 || ep2<0 ) {
-LOG( log_group, 4, ( " Remove: ep not found\n" ) )
- pathElem_da.cnt = pathElemStart;
+ LOG( log_group, 4, ( " Remove: ep not found\n" ) )
+ DYNARR_SET( pathElem_t, pathElem_da, pathElemStart );
return 0;
}
for ( inx=0; inx<path_da.cnt; inx++ ) {
pp = &path(inx);
if ( ( ep1 < 0 || ( pp->ep1 == ep1 || pp->ep2 == ep1 ) ) &&
- ( ep2 < 0 || ( pp->ep1 == ep2 || pp->ep2 == ep2 ) ) ) {
-LOG( log_group, 4, ( " Remove: duplicate path P%d\n", inx ) )
- pathElem_da.cnt = pathElemStart;
+ ( ep2 < 0 || ( pp->ep1 == ep2 || pp->ep2 == ep2 ) ) ) {
+ LOG( log_group, 4, ( " Remove: duplicate path P%d\n", inx ) )
+ DYNARR_SET( pathElem_t, pathElem_da, pathElemStart );
return 0;
}
}
@@ -839,18 +938,21 @@ LOG( log_group, 4, ( " Remove: duplicate path P%d\n", inx ) )
pp->ep1 = ep1;
pp->ep2 = ep2;
pathElemStart = pathElem_da.cnt;
-LOG( log_group, 4, ( " Keep\n" ) )
+ LOG( log_group, 4, ( " Keep\n" ) )
return 0;
case SPTC_IGNNXTTRK:
- if ( !GetTrkSelected(trk) )
+ if ( !GetTrkSelected(trk) ) {
return 1;
- if ( ep1 == ep2 )
+ }
+ if ( ep1 == ep2 ) {
return 1;
- if ( GetTrkEndPtCnt(trk) == 2 )
+ }
+ if ( GetTrkEndPtCnt(trk) == 2 ) {
return 0;
- if ( GetTrkType(trk) != T_TURNOUT )
- AbortProg( "GroupShortestPathFunc(IGNNXTTRK,T%d:%d,%d)", GetTrkIndex(trk), ep1, ep2 );
+ }
+ CHECKMSG( GetTrkType(trk) == T_TURNOUT,
+ ( "GroupShortestPathFunc(IGNNXTTRK,T%d:%d,%d)", GetTrkIndex(trk), ep1, ep2 ) );
return FindPathBtwEP( trk, ep2, ep1, &flip ) == NULL;
case SPTC_VALID:
@@ -862,8 +964,8 @@ LOG( log_group, 4, ( " Keep\n" ) )
static int CmpGroupOrder(
- const void * ptr1,
- const void * ptr2 )
+ const void * ptr1,
+ const void * ptr2 )
{
int inx1 = *(int*)ptr1;
int inx2 = *(int*)ptr2;
@@ -873,68 +975,76 @@ static int CmpGroupOrder(
static coOrd endPtOrig;
static ANGLE_T endPtAngle;
static int CmpEndPtAngle(
- const void * ptr1,
- const void * ptr2 )
+ const void * ptr1,
+ const void * ptr2 )
{
ANGLE_T angle;
trkEndPt_p epp1 = (trkEndPt_p)ptr1;
trkEndPt_p epp2 = (trkEndPt_p)ptr2;
-
- angle = NormalizeAngle(FindAngle(endPtOrig,epp1->pos)-endPtAngle) - NormalizeAngle(FindAngle(endPtOrig,epp2->pos)-endPtAngle);
+
+ angle = NormalizeAngle(FindAngle(endPtOrig,
+ GetEndPtPos(epp1))-endPtAngle) - NormalizeAngle(FindAngle(endPtOrig,
+ GetEndPtPos(epp2))-endPtAngle);
return (int)angle;
}
static int ConflictPaths(
- path_p path0,
- path_p path1 )
+ path_p path0,
+ path_p path1 )
{
+ if ( groupNoCombine != 0 ) {
+ // No grouping
+ return TRUE;
+ }
/* do these paths share an EP? */
- if ( path0->ep1 == path1->ep1 ) return TRUE;
- if ( path0->ep1 == path1->ep2 ) return TRUE;
- if ( path0->ep2 == path1->ep1 ) return TRUE;
- if ( path0->ep2 == path1->ep2 ) return TRUE;
+ if ( path0->ep1 == path1->ep1 ) { return TRUE; }
+ if ( path0->ep1 == path1->ep2 ) { return TRUE; }
+ if ( path0->ep2 == path1->ep1 ) { return TRUE; }
+ if ( path0->ep2 == path1->ep2 ) { return TRUE; }
return FALSE;
}
static BOOL_T CheckPathEndPt(
- track_p trk,
- char cc,
- EPINX_T ep )
+ track_p trk,
+ char cc,
+ EPINX_T ep )
{
- struct extraData *xx = GetTrkExtraData(trk);
+ struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_TURNOUT,
+ extraDataCompound_t);
wIndex_t segInx;
EPINX_T segEP, epCnt;
DIST_T d;
coOrd pos;
GetSegInxEP( cc, &segInx, &segEP );
- if ( ep ) segEP = 1-segEP;
+ if ( ep ) { segEP = 1-segEP; }
pos = GetSegEndPt( &xx->segs[segInx], segEP, FALSE, NULL );
REORIGIN1( pos, xx->angle, xx->orig );
epCnt = GetTrkEndPtCnt(trk);
for ( ep=0; ep<epCnt; ep++ ) {
d = FindDistance( pos, GetTrkEndPos( trk, ep ) );
- if ( d < connectDistance )
+ if ( d < connectDistance ) {
return TRUE;
+ }
}
return FALSE;
}
static BOOL_T CheckForBumper(
- track_p trk )
+ track_p trk )
{
- struct extraData *xx = GetTrkExtraData(trk);
char * cp;
- cp = (char *)xx->paths;
+ cp = (char *)GetPaths( trk );
while ( cp[0] ) {
cp += strlen(cp)+1;
while ( cp[0] ) {
- if ( !CheckPathEndPt( trk, cp[0], 0 ) ) return FALSE;
- while ( cp[0] )
+ if ( !CheckPathEndPt( trk, cp[0], 0 ) ) { return FALSE; }
+ while ( cp[0] ) {
cp++;
- if ( !CheckPathEndPt( trk, cp[-1], 1 ) ) return FALSE;
+ }
+ if ( !CheckPathEndPt( trk, cp[-1], 1 ) ) { return FALSE; }
cp++;
}
cp++;
@@ -942,41 +1052,15 @@ static BOOL_T CheckForBumper(
return TRUE;
}
-typedef struct {
- int inx;
- wBool_t track;
-} segInMap_t;
-static dynArr_t segInMap_da;
-#define segInMap(N) DYNARR_N( segInMap_t, segInMap_da, N)
-
-void AddToSegMap(int inx,wBool_t track) {
- DYNARR_APPEND(segInMap_t,segInMap_da,10);
- DYNARR_LAST(segInMap_t,segInMap_da).inx = inx;
- DYNARR_LAST(segInMap_t,segInMap_da).track = track;
-}
-
-void AddSegsToSegMap(int start, int end, wBool_t track) {
- for (int i = start; i<= end; i++) {
- AddToSegMap(i,track);
- }
-}
-
static dynArr_t trackSegs_da;
#define trackSegs(N) DYNARR_N( trkSeg_t, trackSegs_da, N )
-trkSeg_p GetSegFromSegMap(int index) {
- if (DYNARR_N( segInMap_t, segInMap_da, index).track) {
- return &DYNARR_N(trkSeg_t,trackSegs_da,DYNARR_N( segInMap_t, segInMap_da, index).inx);
- } else
- return &DYNARR_N(trkSeg_t,tempSegs_da,DYNARR_N( segInMap_t, segInMap_da, index).inx);
-}
-
static dynArr_t outputSegs_da;
#define outputSegs(N) DYNARR_N( trkSeg_t, outputSegs_da, N)
static void LogSeg(
- trkSeg_p segP )
+ trkSeg_p segP )
{
if ( segP == NULL ) {
LogPrintf( "<NULL>\n" );
@@ -990,24 +1074,26 @@ static void LogSeg(
case SEG_BENCH:
case SEG_TBLEDGE:
LogPrintf( "[ %0.3f %0.3f ] [ %0.3f %0.3f ]\n",
- segP->u.l.pos[0].x, segP->u.l.pos[0].y,
- segP->u.l.pos[1].x, segP->u.l.pos[1].y );
+ segP->u.l.pos[0].x, segP->u.l.pos[0].y,
+ segP->u.l.pos[1].x, segP->u.l.pos[1].y );
break;
case SEG_CRVLIN:
case SEG_CRVTRK:
LogPrintf( "R:%0.3f [ %0.3f %0.3f } A0:%0.3f A1:%0.3f\n",
- segP->u.c.radius,
- segP->u.c.center.x, segP->u.c.center.y,
- segP->u.c.a0, segP->u.c.a1 );
+ segP->u.c.radius,
+ segP->u.c.center.x, segP->u.c.center.y,
+ segP->u.c.a0, segP->u.c.a1 );
break;
default:
LogPrintf( "%c:\n", segP->type );
}
}
+
+
/*
* GroupOk: create a TURNOUT or STRUCTURE from the selected objects
* 1 - Add selected tracks to groupTrk[]
- * - Add each group trk's segments to trackSeg[] or tempSegs[]
+ * - Add each group trk's segments to trackSeg[]
* - Add all segs to segInMap[]
* - if no track segments goto step 9
* 2 - Collect boundary endPts and sort them in tempEndPts[]
@@ -1017,16 +1103,16 @@ static void LogSeg(
* 4 - Flip tracks so sub-path elements match up
* 5 - Create conflict map
* 6 - Flip paths to minimize the number of flipped segments
- * 7 - Build the path ('P') string
+ * 7 - Build the path ('P') string (new-P)
* 8 - Build segment list, adjust endPts in tempEndPts[]
- * 9 - create new TURNOUT/STRUCTURE definition
+ * 9 - create new TURNOUT/STRUCTURE definition
* 10 - write defn to xtrkcad.cus
* 11 - optionally replace grouped tracks with new defn
*/
-static void GroupOk( void * junk )
+static void GroupOk( void * unused )
{
- struct extraData *xx = NULL;
+ struct extraDataCompound_t *xx = NULL;
turnoutInfo_t * to;
int inx;
EPINX_T ep, epCnt, epN;
@@ -1055,21 +1141,16 @@ static void GroupOk( void * junk )
int groupCnt;
int pinx, pinx2, ginx, ginx2, gpinx2;
trkEndPt_p endPtP;
- PATHPTR_T path;
- int pathLen;
signed char pathChar;
- char *oldLocale = NULL;
DYNARR_RESET( trkSeg_t, trackSegs_da );
DYNARR_RESET( trkSeg_t, tempSegs_da );
DYNARR_RESET( groupTrk_t, groupTrk_da );
DYNARR_RESET( path_t, path_da );
DYNARR_RESET( pathElem_t, pathElem_da );
- DYNARR_RESET( trkEndPt_t, tempEndPts_da );
+ TempEndPtsReset();
DYNARR_RESET( char, pathPtr_da );
- DYNARR_RESET( segInMap_t, segInMap_da);
-
ParamUpdate( &groupPG );
if ( groupManuf[0]==0 || groupDesc[0]==0 || groupPartno[0]==0 ) {
NoticeMessage2( 0, MSG_GROUP_NONBLANK, _("Ok"), NULL );
@@ -1078,8 +1159,9 @@ static void GroupOk( void * junk )
sprintf( message, "%s\t%s\t%s", groupManuf, groupDesc, groupPartno );
if ( strcmp( message, groupTitle ) != 0 ) {
if ( FindCompound( FIND_TURNOUT|FIND_STRUCT, curScaleName, message ) )
- if ( !NoticeMessage2( 1, MSG_TODSGN_REPLACE, _("Yes"), _("No") ) )
+ if ( !NoticeMessage2( 1, MSG_TODSGN_REPLACE, _("Yes"), _("No") ) ) {
return;
+ }
strcpy( groupTitle, message );
}
@@ -1088,106 +1170,107 @@ static void GroupOk( void * junk )
* 1: Collect tracks
*/
trk = NULL;
- int InInx = -1;
+// int InInx = -1;
+ BOOL_T hasTracks = FALSE;
+ wIndex_t nTrkSeg = 0;
+ wIndex_t nSeg = 0;
+ wIndex_t iLastTrkSeg = 0;
while ( TrackIterate( &trk ) ) {
if ( GetTrkSelected( trk ) ) {
- if ( IsTrack(trk) ) {
- DYNARR_APPEND( groupTrk_t, groupTrk_da, 10 );
- groupP = &groupTrk(groupTrk_da.cnt-1);
- groupP->trk = trk;
- groupP->segStart = trackSegs_da.cnt;
- if ( GetTrkType(trk) == T_TURNOUT ) {
- xx = GetTrkExtraData(trk);
- for ( pinx=0; pinx<xx->segCnt; pinx++ ) {
- segPtr = &xx->segs[pinx];
- if ( IsSegTrack(segPtr) ) {
- DYNARR_APPEND( trkSeg_t, trackSegs_da, 10 );
- trackSegs(trackSegs_da.cnt-1) = *segPtr;
-
- AddToSegMap(trackSegs_da.cnt-1,TRUE); /* Single Track Seg - Note no Cornu*/
-
- RotateSegs( 1, &trackSegs(trackSegs_da.cnt-1), zero, xx->angle );
- MoveSegs( 1, &trackSegs(trackSegs_da.cnt-1), xx->orig );
-
- } else {
- int start = tempSegs_da.cnt;
- DrawSegs( &groupD, xx->orig, xx->angle, segPtr, 1, trackGauge, wDrawColorBlack );
-
- AddSegsToSegMap(start,tempSegs_da.cnt-1,FALSE); /* Multiple Non-Track Segs */
- }
- }
- } else if (GetTrkType(trk) == T_BEZIER || GetTrkType(trk) == T_BZRLIN ) {
- DYNARR_APPEND(trkSeg_t, trackSegs_da, 10);
- segPtr = &trackSegs(trackSegs_da.cnt-1);
-
- GetBezierSegmentFromTrack(trk,segPtr);
+ DYNARR_APPEND( groupTrk_t, groupTrk_da, 10 );
+ groupP = &groupTrk(groupTrk_da.cnt-1);
+ groupP->trk = trk;
+ groupP->segStart = trackSegs_da.cnt;
+ groupP->totalSegStart = tempSegs_da.cnt+trackSegs_da.cnt;
+ if (IsTrack(trk)) { hasTracks = TRUE; }
+ if ( GetTrkType(trk) == T_TURNOUT || GetTrkType(trk) == T_STRUCTURE) {
+ xx = GET_EXTRA_DATA(trk, T_NOTRACK, extraDataCompound_t);
+ for ( pinx=0; pinx<xx->segCnt; pinx++ ) {
+ segPtr = &xx->segs[pinx];
+ if ( IsSegTrack(segPtr) ) {
+ DYNARR_APPEND( trkSeg_t, trackSegs_da, 10 );
+ trackSegs(trackSegs_da.cnt-1) = *segPtr;
+ hasTracks = TRUE;
+ RotateSegs( 1, &trackSegs(trackSegs_da.cnt-1), zero, xx->angle );
+ MoveSegs( 1, &trackSegs(trackSegs_da.cnt-1), xx->orig );
+
+ } else {
+ DYNARR_APPEND( trkSeg_t, trackSegs_da, 10 );
+ trackSegs(trackSegs_da.cnt-1) = *segPtr;
+
+ RotateSegs( 1, &trackSegs(trackSegs_da.cnt-1), zero, xx->angle );
+ MoveSegs( 1, &trackSegs(trackSegs_da.cnt-1), xx->orig );
- AddToSegMap(trackSegs_da.cnt-1,TRUE); // Add Single Bezier Track
+ }
+ }
+ } else if (GetTrkType(trk) == T_BEZIER || GetTrkType(trk) == T_BZRLIN ) {
+ DYNARR_APPEND(trkSeg_t, trackSegs_da, 10);
+ segPtr = &trackSegs(trackSegs_da.cnt-1);
- } else if (GetTrkType(trk) == T_CORNU) {
+ GetBezierSegmentFromTrack(trk,segPtr);
- int start = trackSegs_da.cnt;
+ } else if (GetTrkType(trk) == T_CORNU) {
- GetBezierSegmentsFromCornu(trk,&trackSegs_da,TRUE); //Only give back Bezier - cant be undone
+// int start = trackSegs_da.cnt;
- AddSegsToSegMap(start,trackSegs_da.cnt-1,TRUE); /* Add Multiple Track Segs */
+ GetBezierSegmentsFromCornu(trk,&trackSegs_da,
+ TRUE); //Only give back Bezier - cant be undone
- } else {
- segCnt = tempSegs_da.cnt;
- DrawTrack( trk, &groupD, wDrawColorBlack );
+ } else {
+ if (IsTrack(trk)) { hasTracks=TRUE; }
+ segCnt = tempSegs_da.cnt;
+ DrawTrack( trk, &groupD, wDrawColorBlack );
+ for ( ; segCnt < tempSegs_da.cnt; segCnt++ ) {
+ // Copy drawn segments
DYNARR_APPEND( trkSeg_t, trackSegs_da, 10 );
segPtr = &trackSegs(trackSegs_da.cnt-1);
*segPtr = tempSegs( segCnt );
-
- AddToSegMap(trackSegs_da.cnt-1,TRUE); // Add One Track
-
- if ( tempSegs_da.cnt != segCnt+1 ||
- !IsSegTrack(segPtr) ) {
- NoticeMessage2( 0, MSG_CANNOT_GROUP_TRACK, _("Ok"), NULL );
- wHide( groupW );
- return;
- }
-
- tempSegs_da.cnt = segCnt;
}
- groupP->segEnd = trackSegs_da.cnt-1;
- } else {
- int start = tempSegs_da.cnt;
-
- DrawTrack( trk, &groupD, wDrawColorBlack );
+ }
- AddSegsToSegMap(start,tempSegs_da.cnt-1,FALSE); /* Multiple Non-Track Segs */
+ // Count number of track segs and if any appear after seg 127
+ for ( ; nSeg < trackSegs_da.cnt; nSeg++ ) {
+ if ( IsSegTrack( &trackSegs( nSeg ) ) ) {
+ nTrkSeg++;
+ iLastTrkSeg = nSeg;
+ }
}
+ groupP->segEnd = trackSegs_da.cnt-1;
}
}
-if ( log_group >= 1 && logTable(log_group).level >= 4 ) {
- LogPrintf( "Track Segs:\n");
- for ( int inx = 0; inx < trackSegs_da.cnt; inx++ ) {
- LogPrintf( " %d: ", inx+1 );
- LogSeg( &trackSegs(inx) );
+ if ( log_group >= 1 && logTable(log_group).level >= 4 ) {
+ LogPrintf( "Track Segs:\n");
+ for ( int inx = 0; inx < trackSegs_da.cnt; inx++ ) {
+ if (IsSegTrack(&trackSegs(inx))) {
+ LogPrintf( " %d: ", inx+1 );
+ LogSeg( &trackSegs(inx) );
+ }
+ }
+ LogPrintf( "Other Segs:\n");
+ for ( int inx = 0; inx < trackSegs_da.cnt; inx++ ) {
+ if (!IsSegTrack(&trackSegs(inx))) {
+ LogPrintf( " %d: ", inx+1 );
+ LogSeg( &tempSegs(inx) );
+ }
+ }
}
- LogPrintf( "Other Segs:\n");
- for ( int inx = 0; inx < tempSegs_da.cnt; inx++ ) {
- LogPrintf( " %d: ", inx+1 );
- LogSeg( &tempSegs(inx) );
+
+ if ( nTrkSeg > MAX_PATH_SEGS ) {
+ // Too many track segs
+ NoticeMessage( MSG_TOOMANYSEGSINGROUP, _("Ok"), NULL );
+ wDrawDelayUpdate( mainD.d, FALSE );
+ wHide( groupW );
+ return;
}
-}
-if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
- LogPrintf( "Combined Segs:\n" );
- for ( int inx = 0; inx<segInMap_da.cnt; inx++ ) {
- LogPrintf( "%d: %s X%d - ", inx+1, segInMap(inx).track?"Track":"Other", segInMap(inx).inx );
- LogSeg( GetSegFromSegMap( inx ) );
+ if ( iLastTrkSeg > MAX_PATH_SEGS ) {
+ // track segs beyond threshold
+ NoticeMessage( MSG_TOOMANYSEGSINGROUP2, _("Ok"), NULL );
+ wDrawDelayUpdate( mainD.d, FALSE );
+ wHide( groupW );
+ return;
}
-}
-
- if ( groupTrk_da.cnt>0 ) {
- if ( groupTrk_da.cnt > 128 ) {
- NoticeMessage( MSG_TOOMANYSEGSINGROUP, _("Ok"), NULL );
- wDrawDelayUpdate( mainD.d, FALSE );
- wHide( groupW );
- return;
- }
+ if ( groupTrk_da.cnt>0 && hasTracks) {
/*
* Collect EndPts and find paths
*/
@@ -1200,51 +1283,49 @@ if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
trk1 = GetTrkEndTrk(trk,ep);
if ( trk1 == NULL || !GetTrkSelected(trk1) ) {
/* boundary EP */
- for ( epN=0; epN<tempEndPts_da.cnt; epN++ ) {
- dist = FindDistance( GetTrkEndPos(trk,ep), tempEndPts(epN).pos );
- angle = NormalizeAngle( GetTrkEndAngle(trk,ep) - tempEndPts(epN).angle + connectAngle/2.0 );
- if ( dist < connectDistance && angle < connectAngle )
+ for ( epN=0; epN<TempEndPtsCount(); epN++ ) {
+ dist = FindDistance( GetTrkEndPos(trk,ep), GetEndPtPos(TempEndPt(epN)) );
+ angle = NormalizeAngle( GetTrkEndAngle(trk,
+ ep) - GetEndPtAngle(TempEndPt(epN)) + connectAngle/2.0 );
+ if ( dist < connectDistance && angle < connectAngle ) {
break;
+ }
}
- if ( epN>=tempEndPts_da.cnt ) {
- DYNARR_APPEND( trkEndPt_t, tempEndPts_da, 10 );
- endPtP = &tempEndPts(tempEndPts_da.cnt-1);
- memset( endPtP, 0, sizeof *endPtP );
- endPtP->pos = GetTrkEndPos(trk,ep);
- endPtP->angle = GetTrkEndAngle(trk,ep);
- endPtP->track = trk1;
- endPtP->index = (trk1?GetEndPtConnectedToMe(trk1,trk):-1);
- endPtOrig.x += endPtP->pos.x;
- endPtOrig.y += endPtP->pos.y;
+ if ( epN>=TempEndPtsCount() ) {
+ endPtP = TempEndPtsAppend();
+ SetEndPt( endPtP, GetTrkEndPos(trk,ep), GetTrkEndAngle(trk,ep));
+ SetEndPtTrack( endPtP, trk1 );
+ // Remember what EP on trk1 was connecting to me
+ SetEndPtEndPt( endPtP, trk1?GetEndPtConnectedToMe(trk1,trk):-1 );
+ endPtOrig.x += GetEndPtPos(endPtP).x;
+ endPtOrig.y += GetEndPtPos(endPtP).y;
}
}
}
}
-if ( log_group >= 1 && logTable(log_group).level >= 4 ) {
- LogPrintf( "EndPts:\n" );
- for ( int inx=0; inx<tempEndPts_da.cnt; inx++ ) {
- endPtP = &tempEndPts(inx);
- LogPrintf( " [ %0.3f %0.3f ] A:%0.3f, T:%d.%d\n",
- endPtP->pos.x, endPtP->pos.y, endPtP->angle, endPtP->track?GetTrkIndex(endPtP->track):-1, endPtP->index );
- }
-}
+ if ( log_group >= 1 && logTable(log_group).level >= 4 ) {
+ LogPrintf( "EndPts:\n" );
+ for ( int inx=0; inx<TempEndPtsCount(); inx++ ) {
+ endPtP = TempEndPt(inx);
+ LogPrintf( " [ %0.3f %0.3f ] A:%0.3f, T:%d.%d\n",
+ GetEndPtPos(endPtP).x, GetEndPtPos(endPtP).y, GetEndPtAngle(endPtP),
+ GetEndPtTrack(endPtP)?GetTrkIndex(GetEndPtTrack(endPtP)):-1,
+ GetEndPtEndPt(endPtP) );
+ }
+ }
/*
* 2: Collect EndPts
*/
- if ( tempEndPts_da.cnt <= 0 ) {
+ if ( TempEndPtsCount() <= 0 ) {
NoticeMessage( _("No endpts"), _("Ok"), NULL );
wDrawDelayUpdate( mainD.d, FALSE );
wHide( groupW );
return;
}
- if ( groupTrk_da.cnt == 1 && GetTrkType( groupTrk(0).trk ) == T_TURNOUT ) {
- path = xx->paths;
- pathLen = xx->pathLen;
- goto groupSimpleTurnout;
- }
/* Make sure no turnouts in groupTrk list have a path end which is not an EndPt */
- //TODO Add Trap Points (which are Turnouts with a bumper track)
+ // TODO-BUMPER Add Trap Points (which are Turnouts with a bumper track)
+ // for Bumper support remove this loop
for ( inx=0; inx<groupTrk_da.cnt; inx++ ) {
trk = groupTrk(0).trk;
if ( GetTrkType( trk ) == T_TURNOUT ) {
@@ -1272,37 +1353,38 @@ if ( log_group >= 1 && logTable(log_group).level >= 4 ) {
/*
* Sort EndPts by angle
*/
- endPtOrig.x /= tempEndPts_da.cnt;
- endPtOrig.y /= tempEndPts_da.cnt;
+ endPtOrig.x /= TempEndPtsCount();
+ endPtOrig.y /= TempEndPtsCount();
angleN = 270.0;
epN = -1;
- for ( ep=0; ep<tempEndPts_da.cnt; ep++ ) {
- angle = FindAngle(endPtOrig,tempEndPts(ep).pos);
+ for ( ep=0; ep<TempEndPtsCount(); ep++ ) {
+ angle = FindAngle(endPtOrig,GetEndPtPos(TempEndPt(ep)));
if ( fabs(angle-270.0) < angleN ) {
epN = ep;
angleN = fabs(angle-270.0);
endPtAngle = angle;
}
}
- qsort( tempEndPts_da.ptr, tempEndPts_da.cnt, sizeof *endPtP, CmpEndPtAngle );
- if ( NormalizeAngle( tempEndPts(0).angle - tempEndPts(tempEndPts_da.cnt-1).angle ) >
- NormalizeAngle( tempEndPts(1).angle - tempEndPts(0).angle ) ) {
-
- for ( ep=1; ep<(tempEndPts_da.cnt+1)/2; ep++ ) {
- trkEndPt_t tempEndPt;
- tempEndPt = tempEndPts(ep);
- tempEndPts(ep) = tempEndPts(tempEndPts_da.cnt-ep);
- tempEndPts(tempEndPts_da.cnt-ep) = tempEndPt;
+ qsort( TempEndPt(0), TempEndPtsCount(), EndPtSize(1), CmpEndPtAngle );
+ // TODO-BUMPER - handle TempEndPt(1)
+ if ( NormalizeAngle( GetEndPtAngle(TempEndPt(0)) - GetEndPtAngle(TempEndPt(
+ TempEndPtsCount()-1)) ) >
+ NormalizeAngle( GetEndPtAngle(TempEndPt(1)) - GetEndPtAngle(TempEndPt(0)) ) ) {
+
+ for ( ep=1; ep<(TempEndPtsCount()+1)/2; ep++ ) {
+ SwapEndPts( TempEndPt(0), ep, TempEndPtsCount()-ep );
+ }
+ }
+ if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
+ LogPrintf( "Sorted EndPts:\n" );
+ for ( int inx=0; inx<TempEndPtsCount(); inx++ ) {
+ endPtP = TempEndPt(inx);
+ track_p trk1 = GetEndPtTrack(endPtP);
+ LogPrintf( " [ %0.3f %0.3f ] A:%0.3f, T:%d.%d\n",
+ GetEndPtPos(endPtP).x, GetEndPtPos(endPtP).y, GetEndPtAngle(endPtP),
+ trk1?GetTrkIndex(trk1):-1, GetEndPtEndPt(endPtP) );
}
}
-if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
- LogPrintf( "Sorted EndPts:\n" );
- for ( int inx=0; inx<tempEndPts_da.cnt; inx++ ) {
- endPtP = &tempEndPts(inx);
- LogPrintf( " [ %0.3f %0.3f ] A:%0.3f, T:%d.%d\n",
- endPtP->pos.x, endPtP->pos.y, endPtP->angle, endPtP->track?GetTrkIndex(endPtP->track):-1, endPtP->index );
- }
-}
/*
* 3: Find shortest Paths
@@ -1319,35 +1401,40 @@ if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
}
}
}
-if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
- LogPrintf( "Shortest path:\n Group Tracks\n" );
- for ( int inx=0; inx<groupTrk_da.cnt; inx++ ) {
- groupTrk_p gtp = &groupTrk(inx);
- LogPrintf( " %d: T%d S%d-%d\n", inx, GetTrkIndex( gtp->trk ), gtp->segStart+1, gtp->segEnd+1 );
- }
- LogPrintf( " Path Elem\n" );
- for ( int inx=0; inx<pathElem_da.cnt; inx++ ) {
- ppp = &pathElem(inx);
- LogPrintf( " %d: GTx: %d, EP: %d %d, F:%s, P:",
- inx, ppp->groupInx, ppp->ep1, ppp->ep2, ppp->flip?"T":"F" );
- for ( PATHPTR_T cp = ppp->path; cp[0] || cp[1]; cp++ ) {
- LogPrintf( " %d", *cp );
- }
- LogPrintf( " 0\n" );
- }
- LogPrintf( " Path\n" );
- for ( int inx=0; inx<path_da.cnt; inx++ ) {
- path_p pp = &path(inx);
- LogPrintf( " %d: PE: %d-%d, EP: %d-%d, Conf: %d, InGrp: %s, Done: %s\n",
- inx, pp->pathElemStart, pp->pathElemEnd, pp->ep1, pp->ep2,
- pp->conflicts, pp->inGroup?"T":"F", pp->done?"T":"F" );
- }
-}
+ if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
+ LogPrintf( "Shortest path:\n Group Tracks\n" );
+ for ( int inx=0; inx<groupTrk_da.cnt; inx++ ) {
+ groupTrk_p gtp = &groupTrk(inx);
+ LogPrintf( " %d: T%d S%d-%d\n", inx, GetTrkIndex( gtp->trk ),
+ gtp->segStart+1, gtp->segEnd+1 );
+ }
+ LogPrintf( " Path Elem\n" );
+ for ( int inx=0; inx<pathElem_da.cnt; inx++ ) {
+ ppp = &pathElem(inx);
+ LogPrintf( " %d: GTx: %d, EP: %d %d, F:%s, P:",
+ inx, ppp->groupInx, ppp->ep1, ppp->ep2, ppp->flip?"T":"F" );
+ if ( ppp->path == NULL ) {
+ LogPrintf( "No Paths!\n" );
+ } else {
+ for ( PATHPTR_T cp = ppp->path; cp[0] || cp[1]; cp++ ) {
+ LogPrintf( " %d", *cp );
+ }
+ }
+ LogPrintf( " 0\n" );
+ }
+ LogPrintf( " Path\n" );
+ for ( int inx=0; inx<path_da.cnt; inx++ ) {
+ path_p pp = &path(inx);
+ LogPrintf( " %d: PE: %d-%d, EP: %d-%d, Conf: %d, InGrp: %s, Done: %s\n",
+ inx, pp->pathElemStart, pp->pathElemEnd, pp->ep1, pp->ep2,
+ pp->conflicts, pp->inGroup?"T":"F", pp->done?"T":"F" );
+ }
+ }
/*
* 4: Flip paths so they align
*/
if ( path_da.cnt == 0 ) {
- NoticeMessage( _("No paths"), _("Ok"), NULL );
+ NoticeMessage( MSG_GROUP_NO_PATHS, _("Ok"), NULL );
wDrawDelayUpdate( mainD.d, FALSE );
wHide( groupW );
return;
@@ -1359,24 +1446,25 @@ if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
inx = -1;
for ( pinx=0; pinx<path_da.cnt; pinx++ ) {
pp = &path(pinx);
- if ( pp->done ) continue;
+ if ( pp->done ) { continue; }
for ( pinx2=0; pinx2<path_da.cnt; pinx2++ ) {
- if ( pinx2==pinx ) continue;
+ if ( pinx2==pinx ) { continue; }
ppN = &path(pinx2);
if ( pp->ep1 == ppN->ep1 ||
- pp->ep2 == ppN->ep2 ) {
+ pp->ep2 == ppN->ep2 ) {
pp->done = TRUE;
allDone = FALSE;
-LOG( log_group, 1, ( "P%d aligns with P%d\n", pinx, pinx2 ) );
+ LOG( log_group, 1, ( "P%d aligns with P%d\n", pinx, pinx2 ) );
break;
}
if ( pp->ep1 == ppN->ep2 ||
- pp->ep2 == ppN->ep1 ) {
+ pp->ep2 == ppN->ep1 ) {
pp->done = TRUE;
allDone = FALSE;
-LOG( log_group, 1, ( "P%d aligns flipped with P%d\n", pinx, pinx2 ) );
+ LOG( log_group, 1, ( "P%d aligns flipped with P%d\n", pinx, pinx2 ) );
inx = (pp->pathElemStart+pp->pathElemEnd-1)/2;
- for ( ginx=pp->pathElemStart,ginx2=pp->pathElemEnd; ginx<=inx; ginx++,ginx2-- ) {
+ for ( ginx=pp->pathElemStart,ginx2=pp->pathElemEnd; ginx<=inx;
+ ginx++,ginx2-- ) {
pathElemTemp = pathElem(ginx);
pathElem(ginx) = pathElem(ginx2);
pathElem(ginx2) = pathElemTemp;
@@ -1394,33 +1482,35 @@ LOG( log_group, 1, ( "P%d aligns flipped with P%d\n", pinx, pinx2 ) );
break;
}
}
- if ( inx<0 && !pp->done )
+ if ( inx<0 && !pp->done ) {
inx = pinx;
+ }
}
if ( allDone && inx>=0 ) {
allDone = FALSE;
path(inx).done = TRUE;
- }
- }
-if ( log_group >= 1 && logTable(log_group).level >= 1 ) {
- LogPrintf( "Group Paths\n" );
- for ( pinx=0; pinx<path_da.cnt; pinx++ ) {
- pp = &path(pinx);
- LogPrintf( " P%2d:%d.%d ", pinx, pp->ep1, pp->ep2 );
- for ( pinx2=pp->pathElemEnd; pinx2>=pp->pathElemStart; pinx2-- ) {
- ppp = &pathElem(pinx2);
- LogPrintf( " %sT%d:%d.%d", ppp->flip?"-":"", GetTrkIndex(groupTrk(ppp->groupInx).trk), ppp->ep1, ppp->ep2 );
- }
- LogPrintf( "\n" );
- }
-}
+ }
+ }
+ if ( log_group >= 1 && logTable(log_group).level >= 1 ) {
+ LogPrintf( "Group Paths\n" );
+ for ( pinx=0; pinx<path_da.cnt; pinx++ ) {
+ pp = &path(pinx);
+ LogPrintf( " P%2d:%d.%d ", pinx, pp->ep1, pp->ep2 );
+ for ( pinx2=pp->pathElemEnd; pinx2>=pp->pathElemStart; pinx2-- ) {
+ ppp = &pathElem(pinx2);
+ LogPrintf( " %sT%d:%d.%d", ppp->flip?"-":"",
+ GetTrkIndex(groupTrk(ppp->groupInx).trk), ppp->ep1, ppp->ep2 );
+ }
+ LogPrintf( "\n" );
+ }
+ }
/*
* 5: Create Conflict Map
*/
DYNARR_SET( int, conflictMap_da, path_da.cnt*path_da.cnt );
- memset( conflictMap_da.ptr, 0, conflictMap_da.max * sizeof conflictMap(0,0) );
+ memset( &conflictMap(0,0), 0, conflictMap_da.cnt * sizeof conflictMap(0,0) );
for ( pinx=0; pinx<path_da.cnt; pinx++ ) {
for ( pinx2=pinx+1; pinx2<path_da.cnt; pinx2++ ) {
if ( ConflictPaths( &path(pinx), &path(pinx2) ) ) {
@@ -1435,27 +1525,28 @@ if ( log_group >= 1 && logTable(log_group).level >= 1 ) {
* Sort Paths by number of conflicts
*/
DYNARR_SET( int, groupOrder_da, path_da.cnt );
- for ( pinx=0; pinx<path_da.cnt; pinx++ ) groupOrder(pinx) = pinx;
- qsort( groupOrder_da.ptr, path_da.cnt, sizeof groupOrder(0), CmpGroupOrder );
+ for ( pinx=0; pinx<path_da.cnt; pinx++ ) { groupOrder(pinx) = pinx; }
+ qsort( &groupOrder(0), path_da.cnt, sizeof groupOrder(0), CmpGroupOrder );
/*
- * Group Paths, 1st pass:
+ * Group Paths, 1st pass:
*/
DYNARR_SET( int, groupMap_da, path_da.cnt*(path_da.cnt+1) );
- memset( groupMap_da.ptr, -1, groupMap_da.max * sizeof groupMap(0,0) );
+ memset( &groupMap(0,0), -1, groupMap_da.cnt * sizeof groupMap(0,0) );
groupCnt = 0;
for ( pinx=0; pinx<path_da.cnt; pinx++ ) {
pp = &path(groupOrder(pinx));
- if ( pp->inGroup ) continue;
+ if ( pp->inGroup ) { continue; }
pp->inGroup = TRUE;
groupCnt++;
groupMap( groupCnt-1, 0 ) = groupOrder(pinx);
ginx = 1;
for ( pinx2=pinx+1; pinx2<path_da.cnt; pinx2++ ) {
gpinx2 = groupOrder(pinx2);
- if ( path(gpinx2).inGroup ) continue;
- for ( ginx2=0; ginx2<ginx && !conflictMap(groupMap(groupCnt-1,ginx2),gpinx2); ginx2++ );
- if ( ginx2<ginx ) continue;
+ if ( path(gpinx2).inGroup ) { continue; }
+ for ( ginx2=0; ginx2<ginx
+ && !conflictMap(groupMap(groupCnt-1,ginx2),gpinx2); ginx2++ );
+ if ( ginx2<ginx ) { continue; }
path(gpinx2).inGroup = TRUE;
groupMap( groupCnt-1, ginx++ ) = gpinx2;
}
@@ -1469,22 +1560,24 @@ if ( log_group >= 1 && logTable(log_group).level >= 1 ) {
for ( pinx2=0; pinx2<path_da.cnt; pinx2++ ) {
gpinx2 = groupOrder(pinx2);
for ( ginx2=0; ginx2<ginx && groupMap(pinx,ginx2)!=gpinx2; ginx2++ );
- if ( ginx2<ginx ) continue; /* already on list */
- for ( ginx2=0; ginx2<ginx && !conflictMap(groupMap(pinx,ginx2),gpinx2); ginx2++ );
- if ( ginx2<ginx ) continue; /* conflicts with someone on list */
+ if ( ginx2<ginx ) { continue; } /* already on list */
+ for ( ginx2=0; ginx2<ginx
+ && !conflictMap(groupMap(pinx,ginx2),gpinx2); ginx2++ );
+ if ( ginx2<ginx ) { continue; } /* conflicts with someone on list */
groupMap(pinx,ginx++) = gpinx2;
}
}
-if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
- LogPrintf( "Group Map\n");
- for ( pinx=0; pinx<groupCnt; pinx++ ) {
- LogPrintf( "G%d:", pinx );
- for ( ginx=0; groupMap(pinx,ginx) >= 0; ginx++ )
- LogPrintf( " %d: %d", ginx, groupMap(pinx,ginx) );
- LogPrintf( "\n" );
- }
-}
+ if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
+ LogPrintf( "Group Map\n");
+ for ( pinx=0; pinx<groupCnt; pinx++ ) {
+ LogPrintf( "G%d:", pinx );
+ for ( ginx=0; groupMap(pinx,ginx) >= 0; ginx++ ) {
+ LogPrintf( " %d: %d", ginx, groupMap(pinx,ginx) );
+ }
+ LogPrintf( "\n" );
+ }
+ }
/*
* 6: Count number of times each segment is used as flipped
@@ -1493,34 +1586,36 @@ if ( log_group >= 1 && logTable(log_group).level >= 3 ) {
memset( &segFlip(0), 0, trackSegs_da.cnt * sizeof segFlip(0) );
for ( pinx=0; pinx<pathElem_da.cnt; pinx++ ) {
ppp = &pathElem(pinx);
- for ( path=ppp->path; *path; path++ ) {
- inx = *path;
- if ( inx<0 )
+ for ( PATHPTR_T pPaths=ppp->path; pPaths && *pPaths; pPaths++ ) {
+ inx = *pPaths;
+ if ( inx<0 ) {
inx = - inx;
- if ( inx > trackSegs_da.cnt )
- AbortProg( "inx > trackSegs_da.cnt" );
- flip = *path<0;
- if ( ppp->flip )
+ }
+ CHECK( inx <= trackSegs_da.cnt );
+ flip = *pPaths<0;
+ if ( ppp->flip ) {
flip = !flip;
+ }
inx += groupTrk(ppp->groupInx).segStart - 1;
- if ( !flip )
+ if ( !flip ) {
segFlip(inx)++;
- else
+ } else {
segFlip(inx)--;
+ }
}
}
/*
* Flip each segment that is used as flipped more than not
*/
-LOG( log_group, 3, ( "Flipping Segments:" ) );
+ LOG( log_group, 3, ( "Flipping Segments:" ) );
for ( pinx=0; pinx<trackSegs_da.cnt; pinx++ ) {
if ( segFlip(pinx) < 0 ) {
- SegProc( SEGPROC_FLIP, &trackSegs(pinx), NULL );
-LOG( log_group, 3, ( " %d", pinx ) );
+ SegProc( SEGPROC_FLIP, &trackSegs(pinx), NULL );
+ LOG( log_group, 3, ( " %d", pinx ) );
}
}
-LOG( log_group, 3, ( "\n" ) );
+ LOG( log_group, 3, ( "\n" ) );
/*
* 7: Output Path lists
@@ -1532,30 +1627,39 @@ LOG( log_group, 3, ( "\n" ) );
memcpy( &pathPtr(inx), message, pathPtr_da.cnt-inx );
for ( ginx=0; groupMap(pinx,ginx) >= 0; ginx++ ) {
pp = &path(groupMap(pinx,ginx));
- LOG( log_group, 3, (" Group Map(%d, %d): elem %d-%d, EP %d %d, Conflicts %d, inGrp %d, Done: %s\n", pinx, ginx, pp->pathElemStart, pp->pathElemEnd, pp->ep1, pp->ep2, pp->conflicts, pp->inGroup, pp->done?"T":"F" ) );
+ LOG( log_group, 3,
+ (" Group Map(%d, %d): elem %d-%d, EP %d %d, Conflicts %d, inGrp %d, Done: %s\n",
+ pinx, ginx, pp->pathElemStart, pp->pathElemEnd, pp->ep1, pp->ep2, pp->conflicts,
+ pp->inGroup, pp->done?"T":"F" ) );
for ( pinx2=pp->pathElemEnd; pinx2>=pp->pathElemStart; pinx2-- ) {
ppp = &pathElem( pinx2 );
- LOG( log_group, 3, (" PE %d: GI %d, EP %d %d, Flip %d =", pinx2, ppp->groupInx, ppp->ep1, ppp->ep2, ppp->flip ));
+ LOG( log_group, 3, (" PE %d: GI %d, EP %d %d, Flip %d =", pinx2,
+ ppp->groupInx, ppp->ep1, ppp->ep2, ppp->flip ));
groupP = &groupTrk( ppp->groupInx );
- path = ppp->path;
+ PATHPTR_T pPaths = ppp->path;
flip = ppp->flip;
- if ( path == NULL )
- AbortProg( "Missing Path T%d:%d.%d", GetTrkIndex(groupP->trk), ppp->ep2, ppp->ep1 );
- if ( flip ) path += strlen((char *)path)-1;
- while ( *path && (path >= ppp->path) ) { //Add Guard for flip backwards
+ if ( pPaths == NULL ) {
+ ErrorMessage( MSG_GROUP_NO_PATHS, _("Ok"), NULL );
+ wDrawDelayUpdate( mainD.d, FALSE );
+ wHide( groupW );
+ return;
+ }
+ if ( flip ) { pPaths += strlen((char *)pPaths)-1; }
+ while ( *pPaths && (pPaths >= ppp->path) ) { //Add Guard for flip backwards
DYNARR_APPEND( char, pathPtr_da, 10 );
- pathChar = *path;
+ pathChar = *pPaths;
flip1 = flip;
if ( pathChar < 0 ) {
flip1 = !flip;
pathChar = - pathChar;
}
pathChar = groupP->segStart+pathChar;
- if ( segFlip(pathChar-1)<0 )
+ if ( segFlip(pathChar-1)<0 ) {
flip1 = ! flip1;
- if ( flip1 ) pathChar = - pathChar;
+ }
+ if ( flip1 ) { pathChar = - pathChar; }
pathPtr(pathPtr_da.cnt-1) = pathChar;
- path += (flip?-1:1);
+ pPaths += (flip?-1:1);
LOG( log_group, 3, (" %d", pathChar ) );
}
LOG( log_group, 3, ("\n") );
@@ -1568,49 +1672,58 @@ LOG( log_group, 3, ( "\n" ) );
}
DYNARR_APPEND( char, pathPtr_da, 10 );
pathPtr(pathPtr_da.cnt-1) = 0;
- path = (PATHPTR_T)&pathPtr(0);
- pathLen = pathPtr_da.cnt;
-groupSimpleTurnout:
/*
* 8: Copy and Reorigin Segments - Start by putting them out in the original order
*/
DYNARR_RESET(trkSeg_t, outputSegs_da);
- for (int i=0; i<segInMap_da.cnt;i++) {
+ for (int i=0; i<trackSegs_da.cnt; i++) {
DYNARR_APPEND(trkSeg_t,outputSegs_da,10);
- trkSeg_p from_p = GetSegFromSegMap(i);
+ trkSeg_p from_p = &trackSegs(i);
trkSeg_p to_p = &DYNARR_LAST(trkSeg_t, outputSegs_da);
- memcpy((void *)to_p,(void *)from_p,sizeof( trkSeg_t));
+ memcpy(to_p,from_p,sizeof( trkSeg_t));
}
- CloneFilledDraw( outputSegs_da.cnt, outputSegs_da.ptr, FALSE );
+ CloneFilledDraw( outputSegs_da.cnt, &outputSegs(0), FALSE );
GetSegBounds( zero, 0, outputSegs_da.cnt, &outputSegs(0), &orig, &size );
- orig.x = - tempEndPts(0).pos.x;
- orig.y = - tempEndPts(0).pos.y;
+ orig.x = - GetEndPtPos(TempEndPt(0)).x;
+ orig.y = - GetEndPtPos(TempEndPt(0)).y;
MoveSegs( outputSegs_da.cnt, &outputSegs(0), orig );
- for ( ep=0; ep<tempEndPts_da.cnt; ep++ ) {
- tempEndPts(ep).pos.x += orig.x;
- tempEndPts(ep).pos.y += orig.y;
+ for ( ep=0; ep<TempEndPtsCount(); ep++ ) {
+ trkEndPt_p epp = TempEndPt(ep);
+ coOrd pos = GetEndPtPos(epp);
+ pos.x += orig.x;
+ pos.y += orig.y;
+ SetEndPt( epp, pos, GetEndPtAngle(epp) );
}
/*
* 9: Final: create new definition
*/
- CheckPaths( outputSegs_da.cnt, &outputSegs(0), path );
+ PATHPTR_T pPaths = (PATHPTR_T)&pathPtr(0);
+ CheckPaths( outputSegs_da.cnt, &outputSegs(0), pPaths, groupTitle );
- to = CreateNewTurnout( curScaleName, groupTitle, outputSegs_da.cnt, &outputSegs(0), pathLen, path, tempEndPts_da.cnt, &tempEndPts(0), NULL, TRUE );
+ long options = 0;
+ if ( groupNoCombine != 0 ) {
+ options |= COMPOUND_OPTION_PATH_NOCOMBINE;
+ }
+ to = CreateNewTurnout( curScaleName, groupTitle, outputSegs_da.cnt,
+ &outputSegs(0), pPaths, TempEndPtsCount(), TempEndPt(0), TRUE, options );
/*
* 10: Write defn to xtrkcad.cus
*/
f = OpenCustom("a");
if (f && to) {
- oldLocale = SaveLocale("C");
- rc &= fprintf( f, "TURNOUT %s \"%s\"\n", curScaleName, PutTitle(to->title) )>0;
- rc &= WriteCompoundPathsEndPtsSegs( f, path, outputSegs_da.cnt, &outputSegs(0), tempEndPts_da.cnt, &tempEndPts(0) );
+ SetCLocale();
+ rc &= fprintf( f, "TURNOUT %s \"%s\" %ld\n", curScaleName, PutTitle(to->title),
+ options )>0;
+ rc &= WriteCompoundPathsEndPtsSegs( f, pPaths, outputSegs_da.cnt,
+ &outputSegs(0), TempEndPtsCount(), TempEndPt(0) );
+ SetUserLocale();
}
if ( groupReplace ) {
/*
@@ -1619,17 +1732,21 @@ groupSimpleTurnout:
UndoStart( _("Group Tracks"), "group" );
orig.x = - orig.x;
orig.y = - orig.y;
- for ( ep=0; ep<tempEndPts_da.cnt; ep++ ) {
- endPtP = &tempEndPts(ep);
- if ( endPtP->track ) {
- trk = GetTrkEndTrk( endPtP->track, endPtP->index );
- epN = GetEndPtConnectedToMe( trk, endPtP->track );
- DrawEndPt( &mainD, endPtP->track, endPtP->index, wDrawColorWhite );
+ for ( ep=0; ep<TempEndPtsCount(); ep++ ) {
+ endPtP = TempEndPt(ep);
+ track_p trk1 = GetEndPtTrack(endPtP);
+ if ( trk1 ) {
+ EPINX_T ep1 = GetEndPtEndPt(endPtP);
+ trk = GetTrkEndTrk( trk1, ep1 );
+ epN = GetEndPtConnectedToMe( trk, trk1 );
+ DrawEndPt( &mainD, trk1, ep1, wDrawColorWhite );
DrawEndPt( &mainD, trk, epN, wDrawColorWhite );
- DisconnectTracks( trk, epN, endPtP->track, endPtP->index );
+ DisconnectTracks( trk, epN, trk1, ep1 );
}
- endPtP->pos.x += orig.x;
- endPtP->pos.y += orig.y;
+ coOrd pos = GetEndPtPos(endPtP);
+ pos.x += orig.x;
+ pos.y += orig.y;
+ SetEndPt( endPtP, pos, GetEndPtAngle(endPtP) );
}
trk = NULL;
while ( TrackIterate( &trk ) ) {
@@ -1639,31 +1756,43 @@ groupSimpleTurnout:
trackCount--;
}
}
- trk = NewCompound( T_TURNOUT, 0, orig, 0.0, to->title, tempEndPts_da.cnt, &tempEndPts(0), NULL, pathLen, (char *)path, outputSegs_da.cnt, &outputSegs(0) );
+ SelectRecount();
+ trk = NewCompound( T_TURNOUT, 0, orig, 0.0, to->title, TempEndPtsCount(),
+ TempEndPt(0), pPaths, outputSegs_da.cnt, &outputSegs(0) );
+ struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_TURNOUT,
+ extraDataCompound_t);
+ xx->pathOverRide = FALSE;
+ xx->pathNoCombine = groupNoCombine;
SetTrkVisible( trk, TRUE );
- for ( ep=0; ep<tempEndPts_da.cnt; ep++ ) {
- if ( tempEndPts(ep).track ) {
- ConnectTracks( trk, ep, tempEndPts(ep).track, (EPINX_T)tempEndPts(ep).index );
- DrawEndPt( &mainD, tempEndPts(ep).track, (EPINX_T)tempEndPts(ep).index, GetTrkColor( tempEndPts(ep).track, &mainD ) );
+ for ( ep=0; ep<TempEndPtsCount(); ep++ ) {
+ trkEndPt_p epp = TempEndPt(ep);
+ track_p trk1 = GetEndPtTrack(epp);
+ if ( trk1 ) {
+ EPINX_T ep1 = GetEndPtEndPt(epp);
+ ConnectTracks( trk, ep, trk1, ep1 );
+ DrawEndPt( &mainD, trk1, ep1, GetTrkColor(trk1, &mainD ) );
}
}
DrawNewTrack( trk );
EnableCommands();
}
} else {
- CloneFilledDraw( tempSegs_da.cnt, &tempSegs(0), TRUE );
- GetSegBounds( zero, 0, tempSegs_da.cnt, &tempSegs(0), &orig, &size );
+ CloneFilledDraw( trackSegs_da.cnt, &trackSegs(0), TRUE );
+ GetSegBounds( zero, 0, trackSegs_da.cnt, &trackSegs(0), &orig, &size );
orig.x = - orig.x-groupOriginX; //Include orig offset
orig.y = - orig.y-groupOriginY;
- MoveSegs( tempSegs_da.cnt, &tempSegs(0), orig );
- to = CreateNewStructure( curScaleName, groupTitle, tempSegs_da.cnt, &tempSegs(0), TRUE );
+ MoveSegs( trackSegs_da.cnt, &trackSegs(0), orig );
+ to = CreateNewStructure( curScaleName, groupTitle, trackSegs_da.cnt,
+ &trackSegs(0), TRUE );
f = OpenCustom("a");
if (f && to) {
- oldLocale = SaveLocale("C");
- rc &= fprintf( f, "STRUCTURE %s \"%s\"\n", curScaleName, PutTitle(groupTitle) )>0;
- rc &= WriteSegs( f, tempSegs_da.cnt, &tempSegs(0) );
+ SetCLocale();
+ rc &= fprintf( f, "STRUCTURE %s \"%s\"\n", curScaleName,
+ PutTitle(groupTitle) )>0;
+ rc &= WriteSegs( f, trackSegs_da.cnt, &trackSegs(0) );
+ SetUserLocale();
}
if ( groupReplace ) {
UndoStart( _("Group Tracks"), "group" );
@@ -1675,16 +1804,17 @@ groupSimpleTurnout:
trackCount--;
}
}
+ SelectRecount();
orig.x = - orig.x;
orig.y = - orig.y;
- trk = NewCompound( T_STRUCTURE, 0, orig, 0.0, groupTitle, 0, NULL, NULL, 0, "", tempSegs_da.cnt, &tempSegs(0) );
+ trk = NewCompound( T_STRUCTURE, 0, orig, 0.0, groupTitle, 0, NULL, NULL,
+ trackSegs_da.cnt, &trackSegs(0) );
SetTrkVisible( trk, TRUE );
DrawNewTrack( trk );
EnableCommands();
}
}
- if (f) fclose(f);
- RestoreLocale(oldLocale);
+ if (f) { fclose(f); }
DoChangeNotification( CHANGE_PARAMS );
wHide( groupW );
wDrawDelayUpdate( mainD.d, FALSE );
@@ -1693,10 +1823,10 @@ groupSimpleTurnout:
}
-EXPORT void DoGroup( void )
+EXPORT void DoGroup( void * unused )
{
track_p trk = NULL;
- struct extraData *xx;
+ struct extraDataCompound_t *xx;
TRKTYP_T trkType;
xx = NULL;
groupSegCnt = 0;
@@ -1705,16 +1835,22 @@ EXPORT void DoGroup( void )
groupOriginY = 0.0;
BOOL_T isTurnout = FALSE;
+ groupNoCombine = FALSE;
while ( TrackIterate( &trk ) ) {
if ( GetTrkSelected( trk ) ) {
trkType = GetTrkType(trk);
- if ( IsTrack(trk) ) isTurnout = TRUE;
+ if ( IsTrack(trk) ) { isTurnout = TRUE; }
if ( trkType == T_TURNOUT || trkType == T_STRUCTURE ) {
- xx = GetTrkExtraData(trk);
+ xx = GET_EXTRA_DATA(trk, trkType, extraDataCompound_t);
groupSegCnt += xx->segCnt;
GroupCopyTitle( xtitle(xx) );
- } else
+ if ( trkType == T_TURNOUT && GetTrkEndPtCnt(trk) > 2
+ && xx->pathNoCombine != 0 ) {
+ groupNoCombine = TRUE;
+ }
+ } else {
groupSegCnt += 1;
+ }
}
}
if ( groupSegCnt <= 0 ) {
@@ -1722,11 +1858,13 @@ EXPORT void DoGroup( void )
return;
}
sprintf( groupTitle, "%s\t%s\t%s", groupManuf, groupDesc, groupPartno );
- if ( log_group < 0 )
+ if ( log_group < 0 ) {
log_group = LogFindIndex( "group" );
+ }
if ( !groupW ) {
ParamRegister( &groupPG );
- groupW = ParamCreateDialog( &groupPG, MakeWindowTitle(_("Group Objects")), _("Ok"), GroupOk, wHide, TRUE, NULL, F_BLOCK, NULL );
+ groupW = ParamCreateDialog( &groupPG, MakeWindowTitle(_("Group Objects")),
+ _("Ok"), GroupOk, wHide, TRUE, NULL, F_BLOCK, NULL );
groupD.dpi = mainD.dpi;
}
if (isTurnout) {