summaryrefslogtreecommitdiff
path: root/app/bin/cgroup.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2020-08-08 11:53:00 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2020-08-08 11:53:00 +0200
commitb623f5953691b2a0614e6f1f4def86bdbb9a4113 (patch)
tree18102bd36f7e22eb2ba2b9f880e4cb29346f4cb8 /app/bin/cgroup.c
parent359b557176b9bb2ff1aed2082641eed39c358d0d (diff)
New upstream version 5.2.0Beta2.1upstream/5.2.0Beta2.1
Diffstat (limited to 'app/bin/cgroup.c')
-rw-r--r--app/bin/cgroup.c495
1 files changed, 309 insertions, 186 deletions
diff --git a/app/bin/cgroup.c b/app/bin/cgroup.c
index 0094564..1183e76 100644
--- a/app/bin/cgroup.c
+++ b/app/bin/cgroup.c
@@ -472,11 +472,12 @@ 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), pathPtr_da.cnt, &pathPtr(0), tempSegs_da.cnt, &tempSegs(0) );
+ 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);
xx1->ungrouped = TRUE;
SetTrkVisible( trk1, TRUE );
+ SetTrkNoTies( trk1, FALSE );
SetTrkBits( trk1, TB_SELECTED );
for ( segInx=0; segInx<segCnt; segInx++ ) {
if ( refCount(segInx) == inx ) {
@@ -608,19 +609,25 @@ EXPORT void DoUngroup( void )
static drawCmd_t groupD = {
- NULL, &tempSegDrawFuncs, DC_GROUP, 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 double groupOriginX;
+static double groupOriginY;
char * groupReplaceLabels[] = { N_("Replace with new group?"), 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 },
-/*4*/ { PD_TOGGLE, &groupReplace, "replace", 0, groupReplaceLabels, "", BC_HORZ|BC_NOBORDER } };
+#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] };
@@ -652,18 +659,14 @@ static dynArr_t pathElem_da;
static int pathElemStart;
-static BOOL_T CheckTurnoutEndPoint(
- trkSeg_p segs,
- coOrd pos,
- int end )
-{
- coOrd pos1;
- DIST_T d;
- pos1 = GetSegEndPt( segs, end, FALSE, NULL );
- d = FindDistance( pos, pos1 );
- return ( d < connectDistance );
-}
-
+/*
+ * Find sub-path that connects the 2 EPs for the given 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,
@@ -671,12 +674,11 @@ static char * FindPathBtwEP(
BOOL_T * flip )
{
struct extraData * xx = GetTrkExtraData( trk );
- char * cp, *cp0;
- int epN;
- coOrd pos1, pos2;
- int segInx;
- EPINX_T segEP;
+ char * cp;
+ coOrd trkPos[2];
+
+ 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" );
@@ -685,40 +687,63 @@ static char * FindPathBtwEP(
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, 3, (" Flip:%s Path= Seg=%d-\n", *flip?"T":"F", *cp ) );
return cp;
}
cp = (char *)xx->paths;
- pos1 = GetTrkEndPos(trk,ep1);
- Rotate( &pos1, xx->orig, -xx->angle );
- pos1.x -= xx->orig.x;
- pos1.y -= xx->orig.y;
- pos2 = GetTrkEndPos(trk,ep2);
- Rotate( &pos2, xx->orig, -xx->angle );
- pos2.x -= xx->orig.x;
- pos2.y -= xx->orig.y;
+ trkPos[0] = GetTrkEndPos(trk,ep1);
+ Rotate( &trkPos[0], xx->orig, -xx->angle );
+ trkPos[0].x -= xx->orig.x;
+ trkPos[0].y -= xx->orig.y;
+ trkPos[1] = GetTrkEndPos(trk,ep2);
+ Rotate( &trkPos[1], xx->orig, -xx->angle );
+ trkPos[1].x -= xx->orig.x;
+ trkPos[1].y -= xx->orig.y;
+ DIST_T dist = 1000.0;
+ char * path = NULL;
+ char * pName = "Not Found";
while ( cp[0] ) {
- cp += strlen(cp)+1; //Ignore Path Name
+ char * pName1 = cp; // Save path name
+ cp += strlen(cp)+1;
while ( cp[0] ) {
- cp0 = cp;
- epN = -1;
+ int segInx;
+ int segEP;
+ coOrd segPos[2];
+ // Check if this sub-path endpts match the requested endpts
+ char * path1 = cp;
+
+ // get the seg indices for the start and end
GetSegInxEP( cp[0], &segInx, &segEP );
- if ( CheckTurnoutEndPoint( &xx->segs[segInx], pos1, segEP ) )
- epN = 1;
- else if ( CheckTurnoutEndPoint( &xx->segs[segInx], pos2, segEP ) )
- epN = 0;
+ segPos[0] = GetSegEndPt( &xx->segs[segInx], segEP, FALSE, NULL );
cp += strlen(cp);
- if ( epN != -1 ) {
- GetSegInxEP( cp[-1], &segInx, &segEP );
- if ( CheckTurnoutEndPoint( &xx->segs[segInx], epN==0?pos1:pos2, 1-segEP ) ) {
- *flip = epN==0; // If its reversed, set up to be flipped or noted
- return cp0; //Found path between EPs
+ 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
+ DIST_T dist1 = FindDistance( trkPos[0], segPos[inx] );
+ if ( dist1 < connectDistance && dist1 < dist ) {
+ // Closest so far, Check 2nd end
+ 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;
+ path = path1;
+ pName = pName1;
+ *flip = (inx==1);
+ }
}
}
cp++;
}
cp++;
}
- return NULL;
+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;
}
@@ -754,7 +779,7 @@ static int GroupShortestPathFunc(
return -1;
case SPTC_ADD_TRK:
-if (log_shortPath<=0||logTable(log_shortPath).level<4) LOG( log_group, 2, ( " T%d[%d]\n", GetTrkIndex(trk), ep2 ) )
+ 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);
for ( inx=0; inx<groupTrk_da.cnt; inx++ ) {
@@ -793,7 +818,7 @@ if (log_shortPath<=0||logTable(log_shortPath).level<4) LOG( log_group, 2, ( "
}
}
if ( ep1<0 || ep2<0 ) {
-LOG( log_group, 2, ( " Remove: ep not found\n" ) )
+LOG( log_group, 4, ( " Remove: ep not found\n" ) )
pathElem_da.cnt = pathElemStart;
return 0;
}
@@ -801,7 +826,7 @@ LOG( log_group, 2, ( " Remove: ep not found\n" ) )
pp = &path(inx);
if ( ( ep1 < 0 || ( pp->ep1 == ep1 || pp->ep2 == ep1 ) ) &&
( ep2 < 0 || ( pp->ep1 == ep2 || pp->ep2 == ep2 ) ) ) {
-LOG( log_group, 2, ( " Remove: duplicate path P%d\n", inx ) )
+LOG( log_group, 4, ( " Remove: duplicate path P%d\n", inx ) )
pathElem_da.cnt = pathElemStart;
return 0;
}
@@ -814,7 +839,7 @@ LOG( log_group, 2, ( " Remove: duplicate path P%d\n", inx ) )
pp->ep1 = ep1;
pp->ep2 = ep2;
pathElemStart = pathElem_da.cnt;
-LOG( log_group, 2, ( " Keep\n" ) )
+LOG( log_group, 4, ( " Keep\n" ) )
return 0;
case SPTC_IGNNXTTRK:
@@ -917,6 +942,87 @@ 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 )
+{
+ if ( segP == NULL ) {
+ LogPrintf( "<NULL>\n" );
+ return;
+ }
+ LogPrintf( "%c: ", segP->type );
+ switch ( segP->type ) {
+ case SEG_STRTRK:
+ case SEG_STRLIN:
+ case SEG_DIMLIN:
+ 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 );
+ 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 );
+ 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 all segs to segInMap[]
+ * - if no track segments goto step 9
+ * 2 - Collect boundary endPts and sort them in tempEndPts[]
+ * 3 - Find shortest path between all endPts (if it exists)
+ * - For each track we add to the shortest path tree
+ * capture the sub-path elements (FindPathBtwEP) in pathElem[]
+ * 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
+ * 8 - Build segment list, adjust endPts in tempEndPts[]
+ * 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 )
{
@@ -925,7 +1031,6 @@ static void GroupOk( void * junk )
int inx;
EPINX_T ep, epCnt, epN;
coOrd orig, size;
- long oldOptions;
FILE * f = NULL;
BOOL_T rc = TRUE;
track_p trk, trk1;
@@ -937,17 +1042,7 @@ static void GroupOk( void * junk )
ANGLE_T angle, angleN;
pathElem_t pathElemTemp;
char * cp=NULL;
-#ifdef SEGMAP
- pathElem_p ppp1, ppp2;
- int segInx1, segInx2;
- coOrd pos1, pos2;
- static dynArr_t segMap_da;
-#define segMap(I,J) DYNARR_N( char, segMap_da, (2*(I)+0)*trackSegs_da.cnt+(J) )
-#define segAcc(I,J) DYNARR_N( char, segMap_da, (2*(I)+1)*trackSegs_da.cnt+(J) )
-#define segSum(I,J) DYNARR_N( char, segMap_da, (2*(groupTrk_da.cnt)+0)*trackSegs_da.cnt+(J) )
-#endif
- static dynArr_t trackSegs_da;
-#define trackSegs(N) DYNARR_N( trkSeg_t, trackSegs_da, N )
+
trkSeg_p segPtr;
int segCnt;
static dynArr_t conflictMap_da;
@@ -965,9 +1060,6 @@ static void GroupOk( void * junk )
signed char pathChar;
char *oldLocale = NULL;
-#ifdef SEGMAP
- DYNARR_RESET( char, segMap_da );
-#endif
DYNARR_RESET( trkSeg_t, trackSegs_da );
DYNARR_RESET( trkSeg_t, tempSegs_da );
DYNARR_RESET( groupTrk_t, groupTrk_da );
@@ -976,6 +1068,8 @@ static void GroupOk( void * junk )
DYNARR_RESET( trkEndPt_t, tempEndPts_da );
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 );
@@ -991,9 +1085,10 @@ static void GroupOk( void * junk )
wDrawDelayUpdate( mainD.d, TRUE );
/*
- * Collect tracks
+ * 1: Collect tracks
*/
trk = NULL;
+ int InInx = -1;
while ( TrackIterate( &trk ) ) {
if ( GetTrkSelected( trk ) ) {
if ( IsTrack(trk) ) {
@@ -1008,41 +1103,82 @@ static void GroupOk( void * junk )
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);
+
+ AddToSegMap(trackSegs_da.cnt-1,TRUE); // Add Single Bezier Track
+
} else if (GetTrkType(trk) == T_CORNU) {
- GetBezierSegmentsFromCornu(trk,&trackSegs_da); //Only give back Bezier - cant be undone
+
+ int start = trackSegs_da.cnt;
+
+ GetBezierSegmentsFromCornu(trk,&trackSegs_da,TRUE); //Only give back Bezier - cant be undone
+
+ AddSegsToSegMap(start,trackSegs_da.cnt-1,TRUE); /* Add Multiple Track Segs */
+
} else {
segCnt = tempSegs_da.cnt;
- oldOptions = groupD.options;
- groupD.options |= (DC_QUICK|DC_SIMPLE|DC_SEGTRACK);
DrawTrack( trk, &groupD, wDrawColorBlack );
- groupD.options = oldOptions;
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 */
}
}
}
+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) );
+ }
+ LogPrintf( "Other Segs:\n");
+ for ( int inx = 0; inx < tempSegs_da.cnt; inx++ ) {
+ LogPrintf( " %d: ", inx+1 );
+ LogSeg( &tempSegs(inx) );
+ }
+}
+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 ( groupTrk_da.cnt>0 ) {
if ( groupTrk_da.cnt > 128 ) {
@@ -1084,6 +1220,17 @@ static void GroupOk( void * junk )
}
}
}
+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 );
+ }
+}
+ /*
+ * 2: Collect EndPts
+ */
if ( tempEndPts_da.cnt <= 0 ) {
NoticeMessage( _("No endpts"), _("Ok"), NULL );
wDrawDelayUpdate( mainD.d, FALSE );
@@ -1140,10 +1287,7 @@ static void GroupOk( void * junk )
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 ) ) {
-#ifdef LATER
- if ( endPtAngle-FindAngle(endPtOrig,tempEndPts(tempEndPts_da.cnt-1).pos) >
- FindAngle(endPtOrig,tempEndPts(1).pos)-endPtAngle ) {
-#endif
+
for ( ep=1; ep<(tempEndPts_da.cnt+1)/2; ep++ ) {
trkEndPt_t tempEndPt;
tempEndPt = tempEndPts(ep);
@@ -1151,9 +1295,17 @@ static void GroupOk( void * junk )
tempEndPts(tempEndPts_da.cnt-ep) = tempEndPt;
}
}
+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 );
+ }
+}
/*
- * Find shortest Paths
+ * 3: Find shortest Paths
*/
for ( inx=0; inx<groupTrk_da.cnt; inx++ ) {
trk = groupTrk(inx).trk;
@@ -1162,13 +1314,37 @@ static void GroupOk( void * junk )
trk1 = GetTrkEndTrk(trk,ep);
if ( trk1 == NULL || !GetTrkSelected(trk1) ) {
/* boundary EP */
+ LOG( log_group, 3, ("FindShortPath: T%d.%d\n", GetTrkIndex(trk), ep ) );
rc = FindShortestPath( trk, ep, FALSE, GroupShortestPathFunc, NULL );
}
}
}
-
+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" );
+ }
+}
/*
- * Flip paths so they align
+ * 4: Flip paths so they align
*/
if ( path_da.cnt == 0 ) {
NoticeMessage( _("No paths"), _("Ok"), NULL );
@@ -1226,11 +1402,11 @@ LOG( log_group, 1, ( "P%d aligns flipped with P%d\n", pinx, pinx2 ) );
path(inx).done = TRUE;
}
}
-if ( log_group >= 1 && logTable(log_group).level > log_group ) {
+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 );
+ 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 );
@@ -1239,62 +1415,9 @@ if ( log_group >= 1 && logTable(log_group).level > log_group ) {
}
}
-#ifdef SEGMAP
- DYNARR_SET( char, segMap_da, 2 * trackSegs_da.cnt * path_da.cnt + 2 );
- memset( segMap_da.ptr, 0, segMap_da.max * sizeof segMap(0,0) );
- for ( inx=0; inx<path_da.cnt; inx++ ) {
- pp = &path(inx);
- for ( inx2=pp->pathElem_da.cnt-1; inx2>=0; inx2-- ) {
- ppp = &pathElem(pp->pathElemStart+inx2);
- groupP = &groupTrk(ppp->groupInx);
- if ( GetTrkEndPtCnt(groupP->trk) == 2 ) {
- segMap(inx,groupP->segStart) = 1;
- continue;
- }
- cp = ppp->path;
- if ( cp == NULL )
- continue;
- segInx1 = cp[0]-1;
- for ( ; *cp; cp++ )
- segMap(inx,groupP->segInx+cp[0]-1) = 1;
- segInx2 = cp[-1]-1;
- pos1 = GetSegEndPt( &trackSegs(groupP->segInx+segInx1), ppp->flip?1:0, FALSE, NULL );
- pos2 = GetSegEndPt( &trackSegs(groupP->segInx+segInx2), ppp->flip?0:1, FALSE, NULL );
- for ( inx3=0; inx3<groupP->segCnt; inx3++ ) {
- if ( inx3 == segInx1 || inx3 == segInx2 ) continue;
- if ( segMap(inx,groupP->segInx+inx3) != 0 ) continue;
- if ( CheckTurnoutEndPoint( &trackSegs(groupP->segInx+inx3), pos1, 0 ) )
- segMap(inx,inx3) = 2;
- else if ( CheckTurnoutEndPoint( &trackSegs(groupP->segInx+inx3), pos2, 0 ) )
- segMap(inx,groupP->segInx+inx3) = 2;
- }
- }
- }
-if ( log_group >= 1 && logTable(log_group).level > log_group ) {
- LogPrintf( "Path to Segment Map\n ");
- for ( inx=0; inx<groupTrk_da.cnt; inx++ ) {
- groupP = &groupTrk(inx);
- LogPrintf( "%2d", GetTrkIndex(groupP->trk) );
- for ( inx2=1; inx2<groupP->segCnt; inx2++ ) LogPrintf( "--" );
- }
- LogPrintf( "\n " );
- for ( inx=0; inx<groupTrk_da.cnt; inx++ ) {
- groupP = &groupTrk(inx);
- for ( inx2=0; inx2<groupP->segCnt; inx2++ )
- LogPrintf( "%2d", inx2+1 );
- }
- LogPrintf( "\n" );
- for ( inx=0; inx<path_da.cnt; inx++ ) {
- LogPrintf( "%2d ", inx );
- for ( inx2=0; inx2<trackSegs_da.cnt; inx2++ )
- LogPrintf( "%2d", segMap(inx,inx2) );
- LogPrintf("\n");
- }
-}
-#endif
/*
- * Create Conflict Map
+ * 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) );
@@ -1353,42 +1476,18 @@ if ( log_group >= 1 && logTable(log_group).level > log_group ) {
}
}
-if ( log_group >= 1 && logTable(log_group).level > log_group ) {
+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", groupMap(pinx,ginx) );
+ LogPrintf( " %d: %d", ginx, groupMap(pinx,ginx) );
LogPrintf( "\n" );
}
}
-#ifdef SEGMAP
- for ( inx=0; inx<path_da.cnt; inx++ ) {
- for ( inx2=0; inx2<tempSegs_da.cnt; inx2++ ) {
- groupInx = 0;
- memset( &SegTotal(0), 0, tempSegs_da.cnt * sizeof SegAcc(0) );
- while (1) {
- memcpy( &SegAcc(0), &SegTotal(0), tempSegs_da.cnt * sizeof SegAcc(0) );
- collision = FALSE;
- for ( inx=0; inx<path_da.cnt; inx++ ) {
- pp = path(0);
- if ( pp->groupInx < 0 ) continue;
- for ( inx2=0; inx2<tempSegs_da.cnt; inx2++ ) {
- if ( !segMap(inx,inx2) ) continue;
- if ( SegAcc(inx2) ) {
- collision = TRUE;
- break;
- }
- SegAcc(inx2) = TRUE;
- }
- }
- if ( collision )
- }
-#endif
-
/*
- * Count number of times each segment is used as flipped
+ * 6: Count number of times each segment is used as flipped
*/
DYNARR_SET( int, conflictMap_da, trackSegs_da.cnt );
memset( &segFlip(0), 0, trackSegs_da.cnt * sizeof segFlip(0) );
@@ -1414,15 +1513,17 @@ if ( log_group >= 1 && logTable(log_group).level > log_group ) {
/*
* Flip each segment that is used as flipped more than not
*/
+LOG( log_group, 3, ( "Flipping Segments:" ) );
for ( pinx=0; pinx<trackSegs_da.cnt; pinx++ ) {
if ( segFlip(pinx) < 0 ) {
-LOG( log_group, 1, ( "Flipping Segment %d\n", pinx+1 ) );
SegProc( SEGPROC_FLIP, &trackSegs(pinx), NULL );
+LOG( log_group, 3, ( " %d", pinx ) );
}
}
+LOG( log_group, 3, ( "\n" ) );
/*
- * Output Path lists
+ * 7: Output Path lists
*/
for ( pinx=0; pinx<groupCnt; pinx++ ) {
sprintf( message, "P%d", pinx );
@@ -1431,8 +1532,10 @@ LOG( log_group, 1, ( "Flipping Segment %d\n", pinx+1 ) );
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" ) );
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 ));
groupP = &groupTrk( ppp->groupInx );
path = ppp->path;
flip = ppp->flip;
@@ -1453,7 +1556,9 @@ LOG( log_group, 1, ( "Flipping Segment %d\n", pinx+1 ) );
if ( flip1 ) pathChar = - pathChar;
pathPtr(pathPtr_da.cnt-1) = pathChar;
path += (flip?-1:1);
+ LOG( log_group, 3, (" %d", pathChar ) );
}
+ LOG( log_group, 3, ("\n") );
}
DYNARR_APPEND( char, pathPtr_da, 10 );
pathPtr(pathPtr_da.cnt-1) = 0;
@@ -1468,43 +1573,49 @@ LOG( log_group, 1, ( "Flipping Segment %d\n", pinx+1 ) );
groupSimpleTurnout:
/*
- * Copy and Reorigin Segments
+ * 8: Copy and Reorigin Segments - Start by putting them out in the original order
*/
- if ( tempSegs_da.cnt > 0 ) {
- inx = trackSegs_da.cnt;
- DYNARR_SET( trkSeg_t, trackSegs_da, trackSegs_da.cnt+tempSegs_da.cnt );
- memcpy( &trackSegs(inx), tempSegs_da.ptr, tempSegs_da.cnt*sizeof trackSegs(0) );
- CloneFilledDraw( tempSegs_da.cnt, &trackSegs(inx), TRUE );
+
+
+ DYNARR_RESET(trkSeg_t, outputSegs_da);
+ for (int i=0; i<segInMap_da.cnt;i++) {
+ DYNARR_APPEND(trkSeg_t,outputSegs_da,10);
+ trkSeg_p from_p = GetSegFromSegMap(i);
+ trkSeg_p to_p = &DYNARR_LAST(trkSeg_t, outputSegs_da);
+ memcpy((void *)to_p,(void *)from_p,sizeof( trkSeg_t));
}
- GetSegBounds( zero, 0, trackSegs_da.cnt, &trackSegs(0), &orig, &size );
+ CloneFilledDraw( outputSegs_da.cnt, outputSegs_da.ptr, FALSE );
+
+ GetSegBounds( zero, 0, outputSegs_da.cnt, &outputSegs(0), &orig, &size );
orig.x = - tempEndPts(0).pos.x;
orig.y = - tempEndPts(0).pos.y;
- MoveSegs( trackSegs_da.cnt, &trackSegs(0), orig );
+ 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;
}
/*
- * Final: create new definition
+ * 9: Final: create new definition
+ */
+
+ CheckPaths( outputSegs_da.cnt, &outputSegs(0), path );
+
+ to = CreateNewTurnout( curScaleName, groupTitle, outputSegs_da.cnt, &outputSegs(0), pathLen, path, tempEndPts_da.cnt, &tempEndPts(0), NULL, TRUE );
+
+ /*
+ * 10: Write defn to xtrkcad.cus
*/
- CheckPaths( trackSegs_da.cnt, &trackSegs(0), path );
- to = CreateNewTurnout( curScaleName, groupTitle, trackSegs_da.cnt, &trackSegs(0), pathLen, path, tempEndPts_da.cnt, &tempEndPts(0), TRUE );
-#ifdef LATER
- if ( xx )
- to->customInfo = xx->customInfo;
-#endif
f = OpenCustom("a");
if (f && to) {
oldLocale = SaveLocale("C");
rc &= fprintf( f, "TURNOUT %s \"%s\"\n", curScaleName, PutTitle(to->title) )>0;
-#ifdef LATER
- if ( to->customInfo )
- rc &= fprintf( f, "\tU %s\n", to->customInfo )>0;
-#endif
- rc &= WriteCompoundPathsEndPtsSegs( f, path, trackSegs_da.cnt, &trackSegs(0), tempEndPts_da.cnt, &tempEndPts(0) );
+ rc &= WriteCompoundPathsEndPtsSegs( f, path, outputSegs_da.cnt, &outputSegs(0), tempEndPts_da.cnt, &tempEndPts(0) );
}
if ( groupReplace ) {
+ /*
+ * 11: Replace defn
+ */
UndoStart( _("Group Tracks"), "group" );
orig.x = - orig.x;
orig.y = - orig.y;
@@ -1528,8 +1639,7 @@ groupSimpleTurnout:
trackCount--;
}
}
- trk = NewCompound( T_TURNOUT, 0, orig, 0.0, to->title, tempEndPts_da.cnt, &tempEndPts(0), pathLen, (char *)path, trackSegs_da.cnt, &trackSegs(0) );
- SetTrkVisible( trk, TRUE );
+ trk = NewCompound( T_TURNOUT, 0, orig, 0.0, to->title, tempEndPts_da.cnt, &tempEndPts(0), NULL, pathLen, (char *)path, outputSegs_da.cnt, &outputSegs(0) );
SetTrkVisible( trk, TRUE );
for ( ep=0; ep<tempEndPts_da.cnt; ep++ ) {
@@ -1544,18 +1654,15 @@ groupSimpleTurnout:
} else {
CloneFilledDraw( tempSegs_da.cnt, &tempSegs(0), TRUE );
GetSegBounds( zero, 0, tempSegs_da.cnt, &tempSegs(0), &orig, &size );
- orig.x = - orig.x;
- orig.y = - orig.y;
+
+ 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 );
f = OpenCustom("a");
if (f && to) {
oldLocale = SaveLocale("C");
rc &= fprintf( f, "STRUCTURE %s \"%s\"\n", curScaleName, PutTitle(groupTitle) )>0;
-#ifdef LATER
- if ( to->customInfo )
- rc &= fprintf( f, "\tU %s\n", to->customInfo )>0;
-#endif
rc &= WriteSegs( f, tempSegs_da.cnt, &tempSegs(0) );
}
if ( groupReplace ) {
@@ -1570,7 +1677,7 @@ groupSimpleTurnout:
}
orig.x = - orig.x;
orig.y = - orig.y;
- trk = NewCompound( T_STRUCTURE, 0, orig, 0.0, groupTitle, 0, NULL, 0, "", tempSegs_da.cnt, &tempSegs(0) );
+ trk = NewCompound( T_STRUCTURE, 0, orig, 0.0, groupTitle, 0, NULL, NULL, 0, "", tempSegs_da.cnt, &tempSegs(0) );
SetTrkVisible( trk, TRUE );
DrawNewTrack( trk );
EnableCommands();
@@ -1594,10 +1701,14 @@ EXPORT void DoGroup( void )
xx = NULL;
groupSegCnt = 0;
groupCompoundCount = 0;
+ groupOriginX = 0.0;
+ groupOriginY = 0.0;
+ BOOL_T isTurnout = FALSE;
while ( TrackIterate( &trk ) ) {
if ( GetTrkSelected( trk ) ) {
trkType = GetTrkType(trk);
+ if ( IsTrack(trk) ) isTurnout = TRUE;
if ( trkType == T_TURNOUT || trkType == T_STRUCTURE ) {
xx = GetTrkExtraData(trk);
groupSegCnt += xx->segCnt;
@@ -1618,6 +1729,18 @@ EXPORT void DoGroup( void )
groupW = ParamCreateDialog( &groupPG, MakeWindowTitle(_("Group Objects")), _("Ok"), GroupOk, wHide, TRUE, NULL, F_BLOCK, NULL );
groupD.dpi = mainD.dpi;
}
+ if (isTurnout) {
+ groupPLs[4].option |= PDO_DLGIGNORE;
+ wControlShow( groupPLs[4].control, FALSE );
+ groupPLs[5].option |= PDO_DLGIGNORE;
+ wControlShow( groupPLs[5].control, FALSE );
+ } else {
+ groupPLs[4].option &= ~PDO_DLGIGNORE;
+ wControlShow( groupPLs[4].control, TRUE );
+ groupPLs[5].option &= ~PDO_DLGIGNORE;
+ wControlShow( groupPLs[5].control, TRUE );
+ }
+
ParamLoadControls( &groupPG );
wShow( groupW );
}