You've already forked lazarus-ccr
fpvectorial: Fixes DXF reading of SPLINE and LWPOLYLINE and adds better debug info
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1546 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -50,6 +50,15 @@ type
|
|||||||
Destructor Destroy; override;
|
Destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TSPLineElement = record
|
||||||
|
X, Y: Double;
|
||||||
|
KnotValue: Integer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TLWPOLYLINEElement = record
|
||||||
|
X, Y: Double;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TDXFTokenizer }
|
{ TDXFTokenizer }
|
||||||
|
|
||||||
TDXFTokenizer = class
|
TDXFTokenizer = class
|
||||||
@@ -71,7 +80,7 @@ type
|
|||||||
ANGDIR: Integer;
|
ANGDIR: Integer;
|
||||||
INSBASE, EXTMIN, EXTMAX, LIMMIN, LIMMAX: T3DPoint;
|
INSBASE, EXTMIN, EXTMAX, LIMMIN, LIMMAX: T3DPoint;
|
||||||
// Calculated HEADER data
|
// 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
|
// For building the POLYLINE objects which is composed of multiple records
|
||||||
IsReadingPolyline: Boolean;
|
IsReadingPolyline: Boolean;
|
||||||
PolylineX, PolylineY: array of Double;
|
PolylineX, PolylineY: array of Double;
|
||||||
@@ -908,14 +917,14 @@ begin
|
|||||||
AData.AddText(PosX, PosY, PosZ, '', Round(FontSize), Str);
|
AData.AddText(PosX, PosY, PosZ, '', Round(FontSize), Str);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//{$define FPVECTORIALDEBUG_LWPOLYLINE}
|
{.$define FPVECTORIALDEBUG_LWPOLYLINE}
|
||||||
procedure TvDXFVectorialReader.ReadENTITIES_LWPOLYLINE(ATokens: TDXFTokens;
|
procedure TvDXFVectorialReader.ReadENTITIES_LWPOLYLINE(ATokens: TDXFTokens;
|
||||||
AData: TvVectorialDocument);
|
AData: TvVectorialDocument);
|
||||||
var
|
var
|
||||||
CurToken: TDXFToken;
|
CurToken: TDXFToken;
|
||||||
i, curPoint: Integer;
|
i, curPoint: Integer;
|
||||||
// LINE
|
// LINE
|
||||||
LineX, LineY, LineZ: array of Double;
|
LWPolyline: array of TLWPOLYLINEElement;
|
||||||
begin
|
begin
|
||||||
curPoint := -1;
|
curPoint := -1;
|
||||||
|
|
||||||
@@ -937,29 +946,26 @@ begin
|
|||||||
begin
|
begin
|
||||||
// Starting a new point
|
// Starting a new point
|
||||||
Inc(curPoint);
|
Inc(curPoint);
|
||||||
SetLength(LineX, curPoint+1);
|
SetLength(LWPolyline, curPoint+1);
|
||||||
SetLength(LineY, curPoint+1);
|
|
||||||
// SetLength(LineZ, curPoint+1);
|
|
||||||
|
|
||||||
LineX[curPoint] := CurToken.FloatValue - DOC_OFFSET.X;
|
LWPolyline[curPoint].X := CurToken.FloatValue - DOC_OFFSET.X;
|
||||||
end;
|
end;
|
||||||
20: LineY[curPoint] := CurToken.FloatValue - DOC_OFFSET.Y;
|
20: LWPolyline[curPoint].Y := CurToken.FloatValue - DOC_OFFSET.Y;
|
||||||
// 30: LineZ[curPoint] := CurToken.FloatValue;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// And now write it
|
// And now write it
|
||||||
if curPoint >= 0 then // otherwise the polyline is empty of points
|
if curPoint >= 0 then // otherwise the polyline is empty of points
|
||||||
begin
|
begin
|
||||||
AData.StartPath(LineX[0], LineY[0]);
|
AData.StartPath(LWPolyline[0].X, LWPolyline[0].Y);
|
||||||
{$ifdef FPVECTORIALDEBUG_LWPOLYLINE}
|
{$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}
|
{$endif}
|
||||||
for i := 1 to curPoint do
|
for i := 1 to curPoint do
|
||||||
begin
|
begin
|
||||||
AData.AddLineToPath(LineX[i], LineX[i]);
|
AData.AddLineToPath(LWPolyline[i].X, LWPolyline[i].Y);
|
||||||
{$ifdef FPVECTORIALDEBUG_LWPOLYLINE}
|
{$ifdef FPVECTORIALDEBUG_LWPOLYLINE}
|
||||||
Write(Format(' %f,%f', [LineX[i], LineX[i]]));
|
Write(Format(' %f,%f', [LWPolyline[i].X, LWPolyline[i].Y]));
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
{$ifdef FPVECTORIALDEBUG_LWPOLYLINE}
|
{$ifdef FPVECTORIALDEBUG_LWPOLYLINE}
|
||||||
@@ -969,14 +975,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$define FPVECTORIALDEBUG_SPLINE}
|
{.$define FPVECTORIALDEBUG_SPLINE}
|
||||||
procedure TvDXFVectorialReader.ReadENTITIES_SPLINE(ATokens: TDXFTokens;
|
procedure TvDXFVectorialReader.ReadENTITIES_SPLINE(ATokens: TDXFTokens;
|
||||||
AData: TvVectorialDocument);
|
AData: TvVectorialDocument);
|
||||||
var
|
var
|
||||||
CurToken: TDXFToken;
|
CurToken: TDXFToken;
|
||||||
i, curPoint: Integer;
|
i, curPoint: Integer;
|
||||||
// LINE
|
// LINE
|
||||||
LineX, LineY{, LineZ}: array of Double;
|
SPLine: array of TSPLineElement;
|
||||||
begin
|
begin
|
||||||
curPoint := -1;
|
curPoint := -1;
|
||||||
|
|
||||||
@@ -998,29 +1004,26 @@ begin
|
|||||||
begin
|
begin
|
||||||
// Starting a new point
|
// Starting a new point
|
||||||
Inc(curPoint);
|
Inc(curPoint);
|
||||||
SetLength(LineX, curPoint+1);
|
SetLength(SPLine, curPoint+1);
|
||||||
SetLength(LineY, curPoint+1);
|
|
||||||
// SetLength(LineZ, curPoint+1);
|
|
||||||
|
|
||||||
LineX[curPoint] := CurToken.FloatValue - DOC_OFFSET.X;
|
SPLine[curPoint].X := CurToken.FloatValue - DOC_OFFSET.X;
|
||||||
end;
|
end;
|
||||||
20: LineY[curPoint] := CurToken.FloatValue - DOC_OFFSET.Y;
|
20: SPLine[curPoint].Y := CurToken.FloatValue - DOC_OFFSET.Y;
|
||||||
// 30: LineZ[curPoint] := CurToken.FloatValue;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// And now write it
|
// And now write it
|
||||||
if curPoint >= 0 then // otherwise the polyline is empty of points
|
if curPoint >= 0 then // otherwise the polyline is empty of points
|
||||||
begin
|
begin
|
||||||
AData.StartPath(LineX[0], LineY[0]);
|
AData.StartPath(SPLine[0].X, SPLine[0].Y);
|
||||||
{$ifdef FPVECTORIALDEBUG_SPLINE}
|
{$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}
|
{$endif}
|
||||||
for i := 1 to curPoint do
|
for i := 1 to curPoint do
|
||||||
begin
|
begin
|
||||||
AData.AddLineToPath(LineX[i], LineX[i]);
|
AData.AddLineToPath(SPLine[i].X, SPLine[i].Y);
|
||||||
{$ifdef FPVECTORIALDEBUG_SPLINE}
|
{$ifdef FPVECTORIALDEBUG_SPLINE}
|
||||||
Write(Format(' %f,%f', [LineX[i], LineX[i]]));
|
Write(Format(' %f,%f', [SPLine[i].X, SPLine[i].Y]));
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
{$ifdef FPVECTORIALDEBUG_SPLINE}
|
{$ifdef FPVECTORIALDEBUG_SPLINE}
|
||||||
|
@@ -94,6 +94,7 @@ end;
|
|||||||
|
|
||||||
DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
|
DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
|
||||||
}
|
}
|
||||||
|
{.$define FPVECTORIAL_TOCANVAS_DEBUG}
|
||||||
procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
|
procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
|
||||||
{$ifdef USE_LCL_CANVAS}
|
{$ifdef USE_LCL_CANVAS}
|
||||||
ADest: TCanvas;
|
ADest: TCanvas;
|
||||||
@@ -138,7 +139,7 @@ var
|
|||||||
Points: array of TPoint;
|
Points: array of TPoint;
|
||||||
UpperDim, LowerDim: T3DPoint;
|
UpperDim, LowerDim: T3DPoint;
|
||||||
begin
|
begin
|
||||||
{$ifdef FPVECTORIALDEBUG}
|
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
||||||
WriteLn(':>DrawFPVectorialToCanvas');
|
WriteLn(':>DrawFPVectorialToCanvas');
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
@@ -154,6 +155,10 @@ begin
|
|||||||
//WriteLn('i = ', i);
|
//WriteLn('i = ', i);
|
||||||
ASource.Paths[i].PrepareForSequentialReading;
|
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
|
for j := 0 to ASource.Paths[i].Len - 1 do
|
||||||
begin
|
begin
|
||||||
//WriteLn('j = ', j);
|
//WriteLn('j = ', j);
|
||||||
@@ -163,10 +168,16 @@ begin
|
|||||||
stMoveTo:
|
stMoveTo:
|
||||||
begin
|
begin
|
||||||
ADest.MoveTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
|
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;
|
end;
|
||||||
st2DLine, st3DLine:
|
st2DLine, st3DLine:
|
||||||
begin
|
begin
|
||||||
ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
|
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;
|
end;
|
||||||
{ To draw a bezier we need to divide the interval in parts and make
|
{ To draw a bezier we need to divide the interval in parts and make
|
||||||
lines between this parts }
|
lines between this parts }
|
||||||
@@ -189,6 +200,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
||||||
|
WriteLn('');
|
||||||
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Draws all entities
|
// Draws all entities
|
||||||
|
@@ -11,7 +11,7 @@ object frmFPVViewer: TfrmFPVViewer
|
|||||||
LCLVersion = '0.9.31'
|
LCLVersion = '0.9.31'
|
||||||
object editFileName: TFileNameEdit
|
object editFileName: TFileNameEdit
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 25
|
Height = 22
|
||||||
Top = 8
|
Top = 8
|
||||||
Width = 304
|
Width = 304
|
||||||
DialogOptions = []
|
DialogOptions = []
|
||||||
@@ -33,7 +33,7 @@ object frmFPVViewer: TfrmFPVViewer
|
|||||||
end
|
end
|
||||||
object spinScale: TFloatSpinEdit
|
object spinScale: TFloatSpinEdit
|
||||||
Left = 72
|
Left = 72
|
||||||
Height = 25
|
Height = 16
|
||||||
Top = 72
|
Top = 72
|
||||||
Width = 168
|
Width = 168
|
||||||
DecimalPlaces = 6
|
DecimalPlaces = 6
|
||||||
@@ -45,9 +45,9 @@ object frmFPVViewer: TfrmFPVViewer
|
|||||||
end
|
end
|
||||||
object Label1: TLabel
|
object Label1: TLabel
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 18
|
Height = 17
|
||||||
Top = 79
|
Top = 79
|
||||||
Width = 58
|
Width = 56
|
||||||
Caption = 'Scale by:'
|
Caption = 'Scale by:'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
@@ -76,8 +76,8 @@ object frmFPVViewer: TfrmFPVViewer
|
|||||||
object pageViewer: TPage
|
object pageViewer: TPage
|
||||||
end
|
end
|
||||||
object Page2: TPage
|
object Page2: TPage
|
||||||
ClientWidth = 132
|
ClientWidth = 264
|
||||||
ClientHeight = 156
|
ClientHeight = 312
|
||||||
object DXFTreeView: TTreeView
|
object DXFTreeView: TTreeView
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 313
|
Height = 313
|
||||||
|
@@ -50,6 +50,10 @@ uses
|
|||||||
{ TfrmFPVViewer }
|
{ TfrmFPVViewer }
|
||||||
|
|
||||||
procedure TfrmFPVViewer.btnVisualizeClick(Sender: TObject);
|
procedure TfrmFPVViewer.btnVisualizeClick(Sender: TObject);
|
||||||
|
const
|
||||||
|
FPVVIEWER_MAX_IMAGE_SIZE = 1000;
|
||||||
|
FPVVIEWER_MIN_IMAGE_SIZE = 100;
|
||||||
|
FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS = 100;
|
||||||
var
|
var
|
||||||
Vec: TvVectorialDocument;
|
Vec: TvVectorialDocument;
|
||||||
CanvasSize: TPoint;
|
CanvasSize: TPoint;
|
||||||
@@ -67,12 +71,13 @@ begin
|
|||||||
|
|
||||||
// We need to be robust, because sometimes the document size won't be given
|
// 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
|
// 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
|
// and also give some space in the image to allow for negative coordinates
|
||||||
else if Vec.Width < 100 then CanvasSize.X := Drawer.Width
|
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);
|
else CanvasSize.X := Round(Vec.Width * spinScale.Value);
|
||||||
|
|
||||||
if Vec.Height * spinScale.Value > 1000 then CanvasSize.Y := 1000
|
if Vec.Height * spinScale.Value > FPVVIEWER_MAX_IMAGE_SIZE then CanvasSize.Y := FPVVIEWER_MAX_IMAGE_SIZE
|
||||||
else if Vec.Height < 100 then CanvasSize.Y := Drawer.Height
|
else if Vec.Height < FPVVIEWER_MIN_IMAGE_SIZE then CanvasSize.Y := Drawer.Height
|
||||||
else CanvasSize.Y := Round(Vec.Height * spinScale.Value);
|
else CanvasSize.Y := Round(Vec.Height * spinScale.Value);
|
||||||
|
|
||||||
Drawer.Drawing.Width := CanvasSize.X;
|
Drawer.Drawing.Width := CanvasSize.X;
|
||||||
@@ -83,8 +88,8 @@ begin
|
|||||||
DrawFPVectorialToCanvas(
|
DrawFPVectorialToCanvas(
|
||||||
Vec,
|
Vec,
|
||||||
Drawer.Drawing.Canvas,
|
Drawer.Drawing.Canvas,
|
||||||
0,
|
FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS,
|
||||||
Drawer.Drawing.Height,
|
Drawer.Drawing.Height - FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS,
|
||||||
spinScale.Value,
|
spinScale.Value,
|
||||||
-1 * spinScale.Value);
|
-1 * spinScale.Value);
|
||||||
Drawer.Invalidate;
|
Drawer.Invalidate;
|
||||||
|
Reference in New Issue
Block a user