You've already forked lazarus-ccr
Starts fixing the rendering of documents with negative coords and crazy document sizes
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1513 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -29,7 +29,7 @@ unit dxfvectorialreader;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils, Math,
|
||||||
fpvectorial;
|
fpvectorial;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -69,6 +69,9 @@ type
|
|||||||
// HEADER data
|
// HEADER data
|
||||||
ANGBASE: Double;
|
ANGBASE: Double;
|
||||||
ANGDIR: Integer;
|
ANGDIR: Integer;
|
||||||
|
INSBASE, EXTMIN, EXTMAX, LIMMIN, LIMMAX: T3DPoint;
|
||||||
|
// Calculated HEADER data
|
||||||
|
DOC_OFFSET: T3DPoint;
|
||||||
//
|
//
|
||||||
function SeparateString(AString: string; ASeparator: Char): T10Strings;
|
function SeparateString(AString: string; ASeparator: Char): T10Strings;
|
||||||
procedure ReadHEADER(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure ReadHEADER(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
@ -328,6 +331,7 @@ procedure TvDXFVectorialReader.ReadHEADER(ATokens: TDXFTokens;
|
|||||||
var
|
var
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
CurToken: TDXFToken;
|
CurToken: TDXFToken;
|
||||||
|
CurField: P3DPoint;
|
||||||
begin
|
begin
|
||||||
i := 0;
|
i := 0;
|
||||||
while i < ATokens.Count do
|
while i < ATokens.Count do
|
||||||
@ -346,8 +350,16 @@ begin
|
|||||||
Inc(i);
|
Inc(i);
|
||||||
end
|
end
|
||||||
// This indicates the size of the document
|
// This indicates the size of the document
|
||||||
else if CurToken.StrValue = '$LIMMAX' then
|
else if (CurToken.StrValue = '$INSBASE') or
|
||||||
|
(CurToken.StrValue = '$EXTMIN') or (CurToken.StrValue = '$EXTMAX') or
|
||||||
|
(CurToken.StrValue = '$LIMMIN') or (CurToken.StrValue = '$LIMMAX') then
|
||||||
begin
|
begin
|
||||||
|
if (CurToken.StrValue = '$INSBASE') then CurField := @INSBASE
|
||||||
|
else if (CurToken.StrValue = '$EXTMIN') then CurField := @EXTMIN
|
||||||
|
else if (CurToken.StrValue = '$EXTMAX') then CurField := @EXTMAX
|
||||||
|
else if (CurToken.StrValue = '$LIMMIN') then CurField := @LIMMIN
|
||||||
|
else if (CurToken.StrValue = '$LIMMAX') then CurField := @LIMMAX;
|
||||||
|
|
||||||
// Check the next 2 items and verify if they are the values of the size of the document
|
// Check the next 2 items and verify if they are the values of the size of the document
|
||||||
for j := 0 to 1 do
|
for j := 0 to 1 do
|
||||||
begin
|
begin
|
||||||
@ -355,12 +367,12 @@ begin
|
|||||||
case CurToken.GroupCode of
|
case CurToken.GroupCode of
|
||||||
10:
|
10:
|
||||||
begin;
|
begin;
|
||||||
aData.Width := StrToFloat(CurToken.StrValue, FPointSeparator);
|
CurField^.X := StrToFloat(CurToken.StrValue, FPointSeparator);
|
||||||
Inc(i);
|
Inc(i);
|
||||||
end;
|
end;
|
||||||
20:
|
20:
|
||||||
begin
|
begin
|
||||||
aData.Height := StrToFloat(CurToken.StrValue, FPointSeparator);
|
CurField^.Y := StrToFloat(CurToken.StrValue, FPointSeparator);
|
||||||
Inc(i);
|
Inc(i);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -369,6 +381,37 @@ begin
|
|||||||
|
|
||||||
Inc(i);
|
Inc(i);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// After getting all the data, we can try to make so sense out of it
|
||||||
|
|
||||||
|
// Sometimes EXTMIN comes as 10^20 and EXTMAX as -10^20, which makes no sence
|
||||||
|
// In these cases we need to ignore them.
|
||||||
|
if (EXTMIN.X > 100000) or (EXTMIN.X < -100000) or (EXTMAX.X > 100000) or (EXTMAX.X < -100000) then
|
||||||
|
begin
|
||||||
|
DOC_OFFSET.X := 0;
|
||||||
|
DOC_OFFSET.Y := 0;
|
||||||
|
|
||||||
|
AData.Width := LIMMAX.X;
|
||||||
|
AData.Height := LIMMAX.Y;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// The size of the document seams to be given by:
|
||||||
|
// DOC_SIZE = min(EXTMAX, LIMMAX) - DOC_OFFSET;
|
||||||
|
// if EXTMIN is <> -infinite then DOC_OFFSET = EXTMIN else DOC_OFFSET = (0, 0)
|
||||||
|
// We will shift the whole document so that it has only positive coordinates and
|
||||||
|
// DOC_OFFSET will be utilized for that
|
||||||
|
|
||||||
|
if EXTMIN.X > -100 then
|
||||||
|
begin
|
||||||
|
DOC_OFFSET.X := EXTMIN.X;
|
||||||
|
DOC_OFFSET.Y := EXTMIN.Y;
|
||||||
|
end
|
||||||
|
else FillChar(DOC_OFFSET, sizeof(T3DPoint), #0);
|
||||||
|
|
||||||
|
AData.Width := min(EXTMAX.X, LIMMAX.X) - DOC_OFFSET.X;
|
||||||
|
AData.Height := min(EXTMAX.Y, LIMMAX.Y) - DOC_OFFSET.Y;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvDXFVectorialReader.ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure TvDXFVectorialReader.ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
@ -487,6 +530,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
CenterX := CenterX - DOC_OFFSET.X;
|
||||||
|
CenterY := CenterY - DOC_OFFSET.Y;
|
||||||
|
|
||||||
{$ifdef FPVECTORIALDEBUG}
|
{$ifdef FPVECTORIALDEBUG}
|
||||||
WriteLn(Format('Adding Arc Center=%f,%f Radius=%f StartAngle=%f EndAngle=%f',
|
WriteLn(Format('Adding Arc Center=%f,%f Radius=%f StartAngle=%f EndAngle=%f',
|
||||||
[CenterX, CenterY, Radius, StartAngle, EndAngle]));
|
[CenterX, CenterY, Radius, StartAngle, EndAngle]));
|
||||||
|
@ -43,6 +43,8 @@ type
|
|||||||
X, Y, Z: Double;
|
X, Y, Z: Double;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
P3DPoint = ^T3DPoint;
|
||||||
|
|
||||||
TSegmentType = (
|
TSegmentType = (
|
||||||
st2DLine, st2DBezier,
|
st2DLine, st2DBezier,
|
||||||
st3DLine, st3DBezier, stMoveTo);
|
st3DLine, st3DBezier, stMoveTo);
|
||||||
|
@ -52,6 +52,7 @@ uses
|
|||||||
procedure TfrmFPVViewer.btnVisualizeClick(Sender: TObject);
|
procedure TfrmFPVViewer.btnVisualizeClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
Vec: TvVectorialDocument;
|
Vec: TvVectorialDocument;
|
||||||
|
CanvasSize: TPoint;
|
||||||
begin
|
begin
|
||||||
// First check the in input
|
// First check the in input
|
||||||
//if not CheckInput() then Exit;
|
//if not CheckInput() then Exit;
|
||||||
@ -65,11 +66,17 @@ begin
|
|||||||
Vec.ReadFromFile(editFileName.FileName, vfDXF);
|
Vec.ReadFromFile(editFileName.FileName, vfDXF);
|
||||||
|
|
||||||
// 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
|
||||||
if Vec.Width < 100 then Vec.Width := Drawer.Width;
|
// also give up drawing everything if we need more then 4MB of RAM for the image
|
||||||
if Vec.Height < 100 then Vec.Height := Drawer.Height;
|
if Vec.Width * spinScale.Value > 1000 then CanvasSize.X := 1000
|
||||||
|
else if Vec.Width < 100 then CanvasSize.X := Drawer.Width
|
||||||
|
else CanvasSize.X := Round(Vec.Width * spinScale.Value);
|
||||||
|
|
||||||
Drawer.Drawing.Width := Round(Vec.Width * spinScale.Value);
|
if Vec.Height * spinScale.Value > 1000 then CanvasSize.Y := 1000
|
||||||
Drawer.Drawing.Height := Round(Vec.Height * spinScale.Value);
|
else if Vec.Height < 100 then CanvasSize.Y := Drawer.Height
|
||||||
|
else CanvasSize.Y := Round(Vec.Height * spinScale.Value);
|
||||||
|
|
||||||
|
Drawer.Drawing.Width := CanvasSize.X;
|
||||||
|
Drawer.Drawing.Height := CanvasSize.Y;
|
||||||
Drawer.Drawing.Canvas.Brush.Color := clWhite;
|
Drawer.Drawing.Canvas.Brush.Color := clWhite;
|
||||||
Drawer.Drawing.Canvas.Brush.Style := bsSolid;
|
Drawer.Drawing.Canvas.Brush.Style := bsSolid;
|
||||||
Drawer.Drawing.Canvas.FillRect(0, 0, Drawer.Drawing.Width, Drawer.Drawing.Height);
|
Drawer.Drawing.Canvas.FillRect(0, 0, Drawer.Drawing.Width, Drawer.Drawing.Height);
|
||||||
|
Reference in New Issue
Block a user