From 7f3a6e2c8be6a0257a44f2ca8d47ad4fa829a4d2 Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Fri, 11 Feb 2011 08:44:59 +0000 Subject: [PATCH] Starts the dimensions git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1494 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../fpvectorialsrc/dxfvectorialreader.pas | 85 ++++++++++++++----- .../fpvviewer/fpvectorialsrc/fpvectorial.pas | 30 +++++++ .../fpvviewer/fpvectorialsrc/fpvtocanvas.pas | 25 ++++++ 3 files changed, 118 insertions(+), 22 deletions(-) diff --git a/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas b/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas index a4bc9dbc2..0a2cf3d51 100644 --- a/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas +++ b/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas @@ -33,7 +33,6 @@ uses fpvectorial; type - { Used by tcutils.SeparateString } T10Strings = array[0..9] of shortstring; @@ -571,23 +570,40 @@ Group codes Description 210 Extrusion direction (optional; default = 0, 0, 1) DXF: X value; APP: 3D vector 220, 230 DXF: Y and Z values of extrusion direction (optional) 3 Dimension style name + +Aligned Dimension Group Codes + +100 Subclass marker (AcDbAlignedDimension) +12 Insertion point for clones of a dimension-Baseline and Continue (in OCS) DXF: X value; APP: 3D point +22, 32 DXF: Y and Z values of insertion point for clones of a dimension-Baseline and Continue (in OCS) +13 Definition point for linear and angular dimensions (in WCS) DXF: X value; APP: 3D point +23, 33 DXF: Y and Z values of definition point for linear and angular dimensions (in WCS) +14 Definition point for linear and angular dimensions (in WCS) DXF: X value; APP: 3D point +24, 34 DXF: Y and Z values of definition point for linear and angular dimensions (in WCS) + + |--text--|->10,20 + | | + | | + X->14,24 X->13,23 } procedure TvDXFVectorialReader.ReadENTITIES_DIMENSION(ATokens: TDXFTokens; AData: TvVectorialDocument); -{var +var CurToken: TDXFToken; i: Integer; - // LINE - LineStartX, LineStartY, LineStartZ: Double; - LineEndX, LineEndY, LineEndZ: Double;} + // DIMENSION + BaseLeft, BaseRight, DimensionRight, DimensionLeft, TmpPoint: T3DPoint; + IsAlignedDimension: Boolean = False; begin -{ // Initial values - LineStartX := 0; - LineStartY := 0; - LineStartZ := 0; - LineEndX := 0; - LineEndY := 0; - LineEndZ := 0; + // Initial values + BaseLeft.X := 0; + BaseLeft.Y := 0; + BaseRight.X := 0; + BaseRight.X := 0; + DimensionRight.X := 0; + DimensionRight.Y := 0; + DimensionLeft.X := 0; + DimensionLeft.Y := 0; for i := 0 to ATokens.Count - 1 do begin @@ -595,28 +611,53 @@ begin 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] then + if CurToken.GroupCode in [10, 20, 30, 11, 21, 31, 13, 23, 33, 14, 24, 34] then begin CurToken.FloatValue := StrToFloat(Trim(CurToken.StrValue), FPointSeparator); end; case CurToken.GroupCode of - 10: LineStartX := CurToken.FloatValue; - 20: LineStartY := CurToken.FloatValue; - 30: LineStartZ := CurToken.FloatValue; - 11: LineEndX := CurToken.FloatValue; - 21: LineEndY := CurToken.FloatValue; - 31: LineEndZ := CurToken.FloatValue; + 10: DimensionRight.X := CurToken.FloatValue; + 20: DimensionRight.Y := CurToken.FloatValue; + 30: DimensionRight.Z := CurToken.FloatValue; + 13: BaseRight.X := CurToken.FloatValue; + 23: BaseRight.Y := CurToken.FloatValue; + 33: BaseRight.Z := CurToken.FloatValue; + 14: BaseLeft.X := CurToken.FloatValue; + 24: BaseLeft.Y := CurToken.FloatValue; + 34: BaseLeft.Z := CurToken.FloatValue; + 100: + begin + if CurToken.StrValue = 'AcDbAlignedDimension' then IsAlignedDimension := True; + end; end; end; + // Now make sure that we actually have the right positions + if BaseRight.X < BaseLeft.X then + begin + TmpPoint := BaseRight; + BaseRight := BaseLeft; + BaseLeft := TmpPoint; + end; + + // Considering the the Base and the Dimension position must form a parallelogram + // we can solve the other dimention point through the midpoint formula + // which means that in a paralelogram A, B, C, D, with A and D opposites + // midpoint(AD)=midpoint(BC) + // in our case: A=BaseLeft B=DimLeft C=BaseRight D=DimRIght + // midpoint(AD)x=(Ax+Dx)/2 + DimensionLeft.X := BaseLeft.X - BaseRight.X + DimensionRight.X; + DimensionLeft.Y := BaseLeft.Y - BaseRight.Y + DimensionRight.Y; + // And now write it {$ifdef FPVECTORIALDEBUG} // WriteLn(Format('Adding Line from %f,%f to %f,%f', [LineStartX, LineStartY, LineEndX, LineEndY])); {$endif} - AData.StartPath(LineStartX, LineStartY); - AData.AddLineToPath(LineEndX, LineEndY); - AData.EndPath();} + if IsAlignedDimension then + begin + AData.AddAlignedDimension(BaseLeft, BaseRight, DimensionLeft, DimensionRight); + end; end; { diff --git a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas index af0feaa86..bbc3bf1e8 100644 --- a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas +++ b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas @@ -39,6 +39,10 @@ const STR_WINMETAFILE_EXTENSION = '.wmf'; type + T3DPoint = record + X, Y, Z: Double; + end; + TSegmentType = ( st2DLine, st2DBezier, st3DLine, st3DBezier, stMoveTo); @@ -159,6 +163,17 @@ type procedure CalculateBoundingRectangle; end; + {@@ + } + + { TvAlignedDimension } + + TvAlignedDimension = class(TvEntity) + public + // Mandatory fields + BaseLeft, BaseRight, DimensionLeft, DimensionRight: T3DPoint; + end; + type TvCustomVectorialWriter = class; @@ -216,6 +231,8 @@ type procedure AddCircle(ACenterX, ACenterY, ACenterZ, ARadius: Double); procedure AddCircularArc(ACenterX, ACenterY, ACenterZ, ARadius, AStartAngle, AEndAngle: Double); procedure AddEllipse(CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis, Angle: Double); + // Dimensions + procedure AddAlignedDimension(BaseLeft, BaseRight, DimLeft, DimRight: T3DPoint); { properties } property PathCount: Integer read GetPathCount; property Paths[Index: Cardinal]: TPath read GetPath; @@ -642,6 +659,19 @@ begin FEntities.Add(lEllipse); end; +procedure TvVectorialDocument.AddAlignedDimension(BaseLeft, BaseRight, + DimLeft, DimRight: T3DPoint); +var + lDim: TvAlignedDimension; +begin + lDim := TvAlignedDimension.Create; + lDim.BaseLeft := BaseLeft; + lDim.BaseRight := BaseRight; + lDim.DimensionLeft := DimLeft; + lDim.DimensionRight := DimRight; + FEntities.Add(lDim); +end; + {@@ Convenience method which creates the correct writer object for a given vector graphics document format. diff --git a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas index 8dbda7cca..f6eaf6255 100644 --- a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas +++ b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas @@ -97,6 +97,17 @@ procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas; {$endif} ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); + + 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 i, j, k: Integer; PosX, PosY: Integer; // Not modified by ADestX, etc @@ -115,6 +126,7 @@ var CurEllipse: TvEllipse; CurArc: TvCircularArc; FinalStartAngle, FinalEndAngle: double; + CurDim: TvAlignedDimension; begin {$ifdef FPVECTORIALDEBUG} WriteLn(':>DrawFPVectorialToCanvas'); @@ -222,6 +234,19 @@ begin Round(16*(FinalEndAngle - FinalStartAngle)) ); {$endif} + end + else if CurEntity is TvAlignedDimension then + begin + CurDim := CurEntity as TvAlignedDimension; +{ ADest.MoveTo(CoordToCanvasX(CurDim.BaseRight.X), CoordToCanvasY(CurDim.BaseRight.Y)); + ADest.LineTo(CoordToCanvasX(CurDim.DimensionRight.X), CoordToCanvasY(CurDim.DimensionRight.Y)); + ADest.LineTo(CoordToCanvasX(CurDim.DimensionLeft.X), CoordToCanvasY(CurDim.DimensionLeft.Y)); + ADest.LineTo(CoordToCanvasX(CurDim.BaseLeft.X), CoordToCanvasY(CurDim.BaseLeft.Y));} + // Debug info +// ADest.TextOut(CoordToCanvasX(CurDim.BaseRight.X), CoordToCanvasY(CurDim.BaseRight.Y), 'BR'); +// ADest.TextOut(CoordToCanvasX(CurDim.DimensionRight.X), CoordToCanvasY(CurDim.DimensionRight.Y), 'DR'); +// ADest.TextOut(CoordToCanvasX(CurDim.DimensionLeft.X), CoordToCanvasY(CurDim.DimensionLeft.Y), 'DL'); +// ADest.TextOut(CoordToCanvasX(CurDim.BaseLeft.X), CoordToCanvasY(CurDim.BaseLeft.Y), 'BL'); end; end;