diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-08-08 11:53:00 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-08-08 11:53:00 +0200 |
commit | b623f5953691b2a0614e6f1f4def86bdbb9a4113 (patch) | |
tree | 18102bd36f7e22eb2ba2b9f880e4cb29346f4cb8 /app/bin/cgroup.c | |
parent | 359b557176b9bb2ff1aed2082641eed39c358d0d (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.c | 495 |
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 ); } |