diff --git a/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas b/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas index 1260ba084..3a1eae067 100644 --- a/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas +++ b/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas @@ -50,6 +50,15 @@ type Destructor Destroy; override; end; + TSPLineElement = record + X, Y: Double; + KnotValue: Integer; + end; + + TLWPOLYLINEElement = record + X, Y: Double; + end; + { TDXFTokenizer } TDXFTokenizer = class @@ -71,7 +80,7 @@ type ANGDIR: Integer; INSBASE, EXTMIN, EXTMAX, LIMMIN, LIMMAX: T3DPoint; // Calculated HEADER data - DOC_OFFSET: T3DPoint; + DOC_OFFSET: T3DPoint; // The DOC_OFFSET compensates for documents with huge coordinates // For building the POLYLINE objects which is composed of multiple records IsReadingPolyline: Boolean; PolylineX, PolylineY: array of Double; @@ -908,14 +917,14 @@ begin AData.AddText(PosX, PosY, PosZ, '', Round(FontSize), Str); end; -//{$define FPVECTORIALDEBUG_LWPOLYLINE} +{.$define FPVECTORIALDEBUG_LWPOLYLINE} procedure TvDXFVectorialReader.ReadENTITIES_LWPOLYLINE(ATokens: TDXFTokens; AData: TvVectorialDocument); var CurToken: TDXFToken; i, curPoint: Integer; // LINE - LineX, LineY, LineZ: array of Double; + LWPolyline: array of TLWPOLYLINEElement; begin curPoint := -1; @@ -937,29 +946,26 @@ begin begin // Starting a new point Inc(curPoint); - SetLength(LineX, curPoint+1); - SetLength(LineY, curPoint+1); -// SetLength(LineZ, curPoint+1); + SetLength(LWPolyline, curPoint+1); - LineX[curPoint] := CurToken.FloatValue - DOC_OFFSET.X; + LWPolyline[curPoint].X := CurToken.FloatValue - DOC_OFFSET.X; end; - 20: LineY[curPoint] := CurToken.FloatValue - DOC_OFFSET.Y; -// 30: LineZ[curPoint] := CurToken.FloatValue; + 20: LWPolyline[curPoint].Y := CurToken.FloatValue - DOC_OFFSET.Y; end; end; // And now write it if curPoint >= 0 then // otherwise the polyline is empty of points begin - AData.StartPath(LineX[0], LineY[0]); + AData.StartPath(LWPolyline[0].X, LWPolyline[0].Y); {$ifdef FPVECTORIALDEBUG_LWPOLYLINE} - Write(Format('LWPOLYLINE %f,%f', [LineX[0], LineY[0]])); + Write(Format('LWPOLYLINE ID=%d %f,%f', [AData.PathCount-1, LWPolyline[0].X, LWPolyline[0].Y])); {$endif} for i := 1 to curPoint do begin - AData.AddLineToPath(LineX[i], LineX[i]); + AData.AddLineToPath(LWPolyline[i].X, LWPolyline[i].Y); {$ifdef FPVECTORIALDEBUG_LWPOLYLINE} - Write(Format(' %f,%f', [LineX[i], LineX[i]])); + Write(Format(' %f,%f', [LWPolyline[i].X, LWPolyline[i].Y])); {$endif} end; {$ifdef FPVECTORIALDEBUG_LWPOLYLINE} @@ -969,14 +975,14 @@ begin end; end; -{$define FPVECTORIALDEBUG_SPLINE} +{.$define FPVECTORIALDEBUG_SPLINE} procedure TvDXFVectorialReader.ReadENTITIES_SPLINE(ATokens: TDXFTokens; AData: TvVectorialDocument); var CurToken: TDXFToken; i, curPoint: Integer; // LINE - LineX, LineY{, LineZ}: array of Double; + SPLine: array of TSPLineElement; begin curPoint := -1; @@ -998,29 +1004,26 @@ begin begin // Starting a new point Inc(curPoint); - SetLength(LineX, curPoint+1); - SetLength(LineY, curPoint+1); -// SetLength(LineZ, curPoint+1); + SetLength(SPLine, curPoint+1); - LineX[curPoint] := CurToken.FloatValue - DOC_OFFSET.X; + SPLine[curPoint].X := CurToken.FloatValue - DOC_OFFSET.X; end; - 20: LineY[curPoint] := CurToken.FloatValue - DOC_OFFSET.Y; -// 30: LineZ[curPoint] := CurToken.FloatValue; + 20: SPLine[curPoint].Y := CurToken.FloatValue - DOC_OFFSET.Y; end; end; // And now write it if curPoint >= 0 then // otherwise the polyline is empty of points begin - AData.StartPath(LineX[0], LineY[0]); + AData.StartPath(SPLine[0].X, SPLine[0].Y); {$ifdef FPVECTORIALDEBUG_SPLINE} - Write(Format('SPLINE %f,%f', [LineX[0], LineY[0]])); + Write(Format('SPLINE ID=%d %f,%f', [AData.PathCount-1, SPLine[0].X, SPLine[0].Y])); {$endif} for i := 1 to curPoint do begin - AData.AddLineToPath(LineX[i], LineX[i]); + AData.AddLineToPath(SPLine[i].X, SPLine[i].Y); {$ifdef FPVECTORIALDEBUG_SPLINE} - Write(Format(' %f,%f', [LineX[i], LineX[i]])); + Write(Format(' %f,%f', [SPLine[i].X, SPLine[i].Y])); {$endif} end; {$ifdef FPVECTORIALDEBUG_SPLINE} diff --git a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas index 4a6e530b3..e012679fe 100644 --- a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas +++ b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas @@ -94,6 +94,7 @@ end; DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0); } +{.$define FPVECTORIAL_TOCANVAS_DEBUG} procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; {$ifdef USE_LCL_CANVAS} ADest: TCanvas; @@ -138,7 +139,7 @@ var Points: array of TPoint; UpperDim, LowerDim: T3DPoint; begin - {$ifdef FPVECTORIALDEBUG} + {$ifdef FPVECTORIAL_TOCANVAS_DEBUG} WriteLn(':>DrawFPVectorialToCanvas'); {$endif} @@ -154,6 +155,10 @@ begin //WriteLn('i = ', i); ASource.Paths[i].PrepareForSequentialReading; + {$ifdef FPVECTORIAL_TOCANVAS_DEBUG} + Write(Format('[Path] ID=%d', [i])); + {$endif} + for j := 0 to ASource.Paths[i].Len - 1 do begin //WriteLn('j = ', j); @@ -163,10 +168,16 @@ begin stMoveTo: begin ADest.MoveTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)); + {$ifdef FPVECTORIAL_TOCANVAS_DEBUG} + Write(Format(' M%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)])); + {$endif} end; st2DLine, st3DLine: begin ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)); + {$ifdef FPVECTORIAL_TOCANVAS_DEBUG} + Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)])); + {$endif} end; { To draw a bezier we need to divide the interval in parts and make lines between this parts } @@ -189,6 +200,9 @@ begin end; end; end; + {$ifdef FPVECTORIAL_TOCANVAS_DEBUG} + WriteLn(''); + {$endif} end; // Draws all entities diff --git a/applications/fpvviewer/fpvv_mainform.lfm b/applications/fpvviewer/fpvv_mainform.lfm index 7719f6efa..5dfffbece 100644 --- a/applications/fpvviewer/fpvv_mainform.lfm +++ b/applications/fpvviewer/fpvv_mainform.lfm @@ -11,7 +11,7 @@ object frmFPVViewer: TfrmFPVViewer LCLVersion = '0.9.31' object editFileName: TFileNameEdit Left = 8 - Height = 25 + Height = 22 Top = 8 Width = 304 DialogOptions = [] @@ -33,7 +33,7 @@ object frmFPVViewer: TfrmFPVViewer end object spinScale: TFloatSpinEdit Left = 72 - Height = 25 + Height = 16 Top = 72 Width = 168 DecimalPlaces = 6 @@ -45,9 +45,9 @@ object frmFPVViewer: TfrmFPVViewer end object Label1: TLabel Left = 8 - Height = 18 + Height = 17 Top = 79 - Width = 58 + Width = 56 Caption = 'Scale by:' ParentColor = False end @@ -76,8 +76,8 @@ object frmFPVViewer: TfrmFPVViewer object pageViewer: TPage end object Page2: TPage - ClientWidth = 132 - ClientHeight = 156 + ClientWidth = 264 + ClientHeight = 312 object DXFTreeView: TTreeView Left = 8 Height = 313 diff --git a/applications/fpvviewer/fpvv_mainform.pas b/applications/fpvviewer/fpvv_mainform.pas index 353faad42..615f1e284 100644 --- a/applications/fpvviewer/fpvv_mainform.pas +++ b/applications/fpvviewer/fpvv_mainform.pas @@ -50,6 +50,10 @@ uses { TfrmFPVViewer } procedure TfrmFPVViewer.btnVisualizeClick(Sender: TObject); +const + FPVVIEWER_MAX_IMAGE_SIZE = 1000; + FPVVIEWER_MIN_IMAGE_SIZE = 100; + FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS = 100; var Vec: TvVectorialDocument; CanvasSize: TPoint; @@ -67,12 +71,13 @@ begin // We need to be robust, because sometimes the document size won't be given // also give up drawing everything if we need more then 4MB of RAM for the image - if Vec.Width * spinScale.Value > 1000 then CanvasSize.X := 1000 - else if Vec.Width < 100 then CanvasSize.X := Drawer.Width + // and also give some space in the image to allow for negative coordinates + if Vec.Width * spinScale.Value > FPVVIEWER_MAX_IMAGE_SIZE then CanvasSize.X := FPVVIEWER_MAX_IMAGE_SIZE + else if Vec.Width < FPVVIEWER_MIN_IMAGE_SIZE then CanvasSize.X := Drawer.Width else CanvasSize.X := Round(Vec.Width * spinScale.Value); - if Vec.Height * spinScale.Value > 1000 then CanvasSize.Y := 1000 - else if Vec.Height < 100 then CanvasSize.Y := Drawer.Height + if Vec.Height * spinScale.Value > FPVVIEWER_MAX_IMAGE_SIZE then CanvasSize.Y := FPVVIEWER_MAX_IMAGE_SIZE + else if Vec.Height < FPVVIEWER_MIN_IMAGE_SIZE then CanvasSize.Y := Drawer.Height else CanvasSize.Y := Round(Vec.Height * spinScale.Value); Drawer.Drawing.Width := CanvasSize.X; @@ -83,8 +88,8 @@ begin DrawFPVectorialToCanvas( Vec, Drawer.Drawing.Canvas, - 0, - Drawer.Drawing.Height, + FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS, + Drawer.Drawing.Height - FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS, spinScale.Value, -1 * spinScale.Value); Drawer.Invalidate;