mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-27 22:41:13 +02:00
fpvectorial: Adds 3D polygon support to the base code and to DXF, together with a 2D rendering
git-svn-id: trunk@39936 -
This commit is contained in:
parent
f64d8b0994
commit
ea48f9e94f
@ -104,6 +104,7 @@ type
|
||||
procedure ReadBLOCKS_BLOCK(ATokens: TDXFTokens; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||
procedure ReadBLOCKS_ENDBLK(ATokens: TDXFTokens; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||
procedure ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||
function ReadENTITIES_3DFACE(ATokens: TDXFTokens; AData: TvVectorialPage; ADoc: TvVectorialDocument; AOnlyCreate: Boolean = False): TvCircularArc;
|
||||
function ReadENTITIES_LINE(ATokens: TDXFTokens; AData: TvVectorialPage; ADoc: TvVectorialDocument; AOnlyCreate: Boolean = False): TPath;
|
||||
function ReadENTITIES_ARC(ATokens: TDXFTokens; AData: TvVectorialPage; ADoc: TvVectorialDocument; AOnlyCreate: Boolean = False): TvCircularArc;
|
||||
function ReadENTITIES_CIRCLE(ATokens: TDXFTokens; AData: TvVectorialPage; ADoc: TvVectorialDocument; AOnlyCreate: Boolean = False): TvCircle;
|
||||
@ -125,6 +126,7 @@ type
|
||||
function ConvertDXFStringToUTF8(AStr: string): string;
|
||||
//
|
||||
function DXFColorIndexToFPColor(AColorIndex: Integer): TFPColor;
|
||||
procedure DXFCoordsToFPCoords(AInX, AInY, AInZ: Double; out AOutX, AOutY, AOutZ: Double);
|
||||
public
|
||||
{ General reading methods }
|
||||
Tokenizer: TDXFTokenizer;
|
||||
@ -946,6 +948,80 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TvDXFVectorialReader.ReadENTITIES_3DFACE(ATokens: TDXFTokens;
|
||||
AData: TvVectorialPage; ADoc: TvVectorialDocument; AOnlyCreate: Boolean
|
||||
): TvCircularArc;
|
||||
var
|
||||
CurToken: TDXFToken;
|
||||
lPolygon: TvPolygon;
|
||||
i: Integer;
|
||||
begin
|
||||
Result := nil;
|
||||
lPolygon := TvPolygon.Create;
|
||||
SetLength(lPolygon.Points, 3);
|
||||
|
||||
for i := 0 to ATokens.Count - 1 do
|
||||
begin
|
||||
// Now read and process the item name
|
||||
CurToken := TDXFToken(ATokens.Items[i]);
|
||||
|
||||
// Avoid an exception by previously checking if the conversion can be made
|
||||
if CurToken.GroupCode in [10, 20, 30, 11, 21, 31, 12, 22, 32, 13, 23, 33, 70] then
|
||||
begin
|
||||
CurToken.FloatValue := StrToFloat(Trim(CurToken.StrValue), FPointSeparator);
|
||||
end;
|
||||
|
||||
case CurToken.GroupCode of
|
||||
10: lPolygon.Points[0].X := CurToken.FloatValue;
|
||||
20: lPolygon.Points[0].Y := CurToken.FloatValue;
|
||||
30: lPolygon.Points[0].Z := CurToken.FloatValue;
|
||||
11: lPolygon.Points[1].X := CurToken.FloatValue;
|
||||
21: lPolygon.Points[1].Y := CurToken.FloatValue;
|
||||
31: lPolygon.Points[1].Z := CurToken.FloatValue;
|
||||
12: lPolygon.Points[2].X := CurToken.FloatValue;
|
||||
22: lPolygon.Points[2].Y := CurToken.FloatValue;
|
||||
32: lPolygon.Points[2].Z := CurToken.FloatValue;
|
||||
13:
|
||||
begin
|
||||
SetLength(lPolygon.Points, 4);
|
||||
lPolygon.Points[3].X := CurToken.FloatValue;
|
||||
end;
|
||||
23:
|
||||
begin
|
||||
SetLength(lPolygon.Points, 4);
|
||||
lPolygon.Points[3].Y := CurToken.FloatValue;
|
||||
end;
|
||||
33:
|
||||
begin
|
||||
SetLength(lPolygon.Points, 4);
|
||||
lPolygon.Points[3].Z := CurToken.FloatValue;
|
||||
end;
|
||||
{
|
||||
Invisible edge flags (optional; default = 0):
|
||||
1 = First edge is invisible
|
||||
2 = Second edge is invisible
|
||||
4 = Third edge is invisible
|
||||
8 = Fourth edge is invisible
|
||||
}
|
||||
70:
|
||||
begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
DXFCoordsToFPCoords(lPolygon.Points[0].X, lPolygon.Points[0].Y, lPolygon.Points[0].Z,
|
||||
lPolygon.Points[0].X, lPolygon.Points[0].Y, lPolygon.Points[0].Z);
|
||||
DXFCoordsToFPCoords(lPolygon.Points[1].X, lPolygon.Points[1].Y, lPolygon.Points[1].Z,
|
||||
lPolygon.Points[1].X, lPolygon.Points[1].Y, lPolygon.Points[1].Z);
|
||||
DXFCoordsToFPCoords(lPolygon.Points[2].X, lPolygon.Points[2].Y, lPolygon.Points[2].Z,
|
||||
lPolygon.Points[2].X, lPolygon.Points[2].Y, lPolygon.Points[2].Z);
|
||||
if Length(lPolygon.Points) >= 4 then
|
||||
DXFCoordsToFPCoords(lPolygon.Points[3].X, lPolygon.Points[3].Y, lPolygon.Points[3].Z,
|
||||
lPolygon.Points[3].X, lPolygon.Points[3].Y, lPolygon.Points[3].Z);
|
||||
|
||||
AData.AddEntity(lPolygon);
|
||||
end;
|
||||
|
||||
function TvDXFVectorialReader.ReadENTITIES_LINE(ATokens: TDXFTokens; AData: TvVectorialPage; ADoc: TvVectorialDocument; AOnlyCreate: Boolean = False): TPath;
|
||||
var
|
||||
CurToken: TDXFToken;
|
||||
@ -1920,6 +1996,7 @@ function TvDXFVectorialReader.InternalReadENTITIES(ATokenStr: string;
|
||||
begin
|
||||
Result := nil;
|
||||
case ATokenStr of
|
||||
'3DFACE': Result := ReadENTITIES_3DFACE(ATokens, AData, ADoc, AOnlyCreate);
|
||||
'ARC': Result := ReadENTITIES_ARC(ATokens, AData, ADoc, AOnlyCreate);
|
||||
'CIRCLE': Result := ReadENTITIES_CIRCLE(ATokens, AData, ADoc, AOnlyCreate);
|
||||
'DIMENSION':Result := ReadENTITIES_DIMENSION(ATokens, AData, ADoc, AOnlyCreate);
|
||||
@ -1982,6 +2059,14 @@ begin
|
||||
raise Exception.Create(Format('[TvDXFVectorialReader.DXFColorIndexToFPVColor] Invalid DXF Color Index: %d', [AColorIndex]));
|
||||
end;
|
||||
|
||||
procedure TvDXFVectorialReader.DXFCoordsToFPCoords(AInX, AInY, AInZ: Double;
|
||||
out AOutX, AOutY, AOutZ: Double);
|
||||
begin
|
||||
AOutX := AInX - DOC_OFFSET.X;
|
||||
AOutY := AInY - DOC_OFFSET.Y;
|
||||
AOutZ := AInZ;
|
||||
end;
|
||||
|
||||
constructor TvDXFVectorialReader.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
|
@ -397,8 +397,10 @@ type
|
||||
|
||||
{ TvRectangle }
|
||||
|
||||
TvRectangle = class(TvEntityWithPenAndBrush)
|
||||
TvRectangle = class(TvEntityWithPenBrushAndFont)
|
||||
public
|
||||
// A text displayed in the center of the square, usually empty
|
||||
Text: string;
|
||||
// Mandatory fields
|
||||
CX, CY, CZ: Double;
|
||||
// Corner rounding, zero indicates no rounding
|
||||
@ -408,6 +410,18 @@ type
|
||||
ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
||||
end;
|
||||
|
||||
{ TvPolygon }
|
||||
|
||||
TvPolygon = class(TvEntityWithPenBrushAndFont)
|
||||
public
|
||||
// A text displayed in the center of the square, usually empty
|
||||
Text: string;
|
||||
// All points of the polygon
|
||||
Points: array of T3DPoint;
|
||||
procedure Render(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo; ADestX: Integer = 0;
|
||||
ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
||||
end;
|
||||
|
||||
{@@
|
||||
DimensionLeft ---text--- DimensionRight
|
||||
| |
|
||||
@ -2035,6 +2049,37 @@ begin
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
{ TvPolygon }
|
||||
|
||||
procedure TvPolygon.Render(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo;
|
||||
ADestX: Integer; ADestY: Integer; AMulX: Double; AMulY: Double);
|
||||
|
||||
function CoordToCanvasX(ACoord: Double): Integer;
|
||||
begin
|
||||
Result := Round(ADestX + AmulX * ACoord);
|
||||
end;
|
||||
|
||||
function CoordToCanvasY(ACoord: Double): Integer;
|
||||
begin
|
||||
Result := Round(ADestY + AmulY * ACoord);
|
||||
end;
|
||||
|
||||
var
|
||||
lPoints: array of TPoint;
|
||||
i: Integer;
|
||||
begin
|
||||
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
||||
|
||||
SetLength(lPoints, Length(Points));
|
||||
for i := 0 to Length(Points)-1 do
|
||||
begin
|
||||
lPoints[i].X := CoordToCanvasX(Points[i].X);
|
||||
lPoints[i].Y := CoordToCanvasY(Points[i].Y);
|
||||
end;
|
||||
|
||||
ADest.Polygon(lPoints);
|
||||
end;
|
||||
|
||||
{ TvAlignedDimension }
|
||||
|
||||
procedure TvAlignedDimension.Render(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo; ADestX: Integer;
|
||||
|
Loading…
Reference in New Issue
Block a user