📄 formatdxffile.pas
字号:
unit FormatDxfFile;
interface
uses
Windows, Classes, DXF_structs, DXF_Utils,
FlexBase, FlexUtils, FlexPath, FlexControls, FlexFileFormats;
resourcestring
sDxfFileDescription = 'DXF file';
type
TFlexDxfGroup = (
dgBlock,
dgInsert,
dgPolygonMesh,
dgPolyfaceMesh
);
TFlexDxfGroups = set of TFlexDxfGroup;
PDxfMapParams = ^TDxfMapParams;
TDxfMapParams = record
xscale,yscale : double;
xmin,xmax : double;
ymin,ymax : double;
xmid,ymid : double;
end;
TFlexDxfFormat = class(TFlexFileFormat)
private
FFlex: TFlexPanel;
FDxf: DXF_Object;
FFlexLayer: TFlexLayer;
FMapParams: TDxfMapParams;
FPenWidth: integer;
FGroups: TFlexDxfGroups;
protected
function MapFn(P:Point3D; OCS:pMatrix): TPoint;
function LoadLayer(Layer: DXF_layer): boolean;
function LoadEntityList(EntList: Entity_List): boolean;
function LoadEntity(Entity: DXF_Entity; OCS:pM;
FlexParent: TFlexControl): boolean;
function LoadBlock(Block: Block_; OCS:pM;
FlexParent: TFlexControl): TFlexGroup;
function LoadInsert(Insert: Insert_; OCS:pM;
FlexParent: TFlexControl): TFlexGroup;
function LoadLine(Line: Line_; OCS:pM;
FlexParent: TFlexControl): TFlexCurve;
function LoadPolyLine(PolyLine: PolyLine_; OCS:pM;
FlexParent: TFlexControl): TFlexCurve;
function LoadPolygonMesh(PolygonMesh: Polygon_Mesh_; OCS:pM;
FlexParent: TFlexControl): TFlexGroup;
function LoadPolyfaceMesh(PolyfaceMesh: Polyface_Mesh_; OCS:pM;
FlexParent: TFlexControl): TFlexGroup;
function LoadCircle(Circle: Circle_; OCS:pM;
FlexParent: TFlexControl): TFlexEllipse;
function LoadArc(Arc: Arc_; OCS:pM; FlexParent: TFlexControl): TFlexEllipse;
function LoadText(Text: Text_; OCS:pM; FlexParent: TFlexControl): TFlexText;
function Convert(AFlex: TFlexPanel; ADxf: DXF_Object): boolean;
procedure RegisterSupportedExtensions; override;
property Flex: TFlexPanel read FFlex;
property Dxf: DXF_Object read FDxf;
public
constructor Create(AOwner: TObject); override;
destructor Destroy; override;
procedure ImportFromStream(AStream: TStream; AFlexPanel: TFlexPanel;
const Extension: TFlexFileExtension; const AFileName: string); override;
property MapParams: TDxfMapParams read FMapParams write FMapParams;
property Groups: TFlexDxfGroups read FGroups write FGroups;
end;
implementation
procedure SetCurveAbsPointsEx(Curve: TFlexControl; const APoints: TPointArray;
const ATypes: TPointTypeArray);
var NewPoints: TPointArray;
Org: TPoint;
i, ACount: integer;
begin
with Curve do begin
Org := DocRect.TopLeft;
if (Org.x = 0) and (Org.y = 0) then begin
// no need to convert
if not Assigned(ATypes)
then SetPoints(APoints)
else SetPointsEx(APoints, ATypes);
end else begin
// Covert to relative coords
ACount := Length(APoints);
SetLength(NewPoints, ACount);
for i:=0 to ACount-1 do begin
NewPoints[i].x := APoints[i].x - Org.x;
NewPoints[i].y := APoints[i].y - Org.y;
end;
if not Assigned(ATypes)
then SetPoints(NewPoints)
else SetPointsEx(NewPoints, ATypes);
end;
end;
end;
// TFlexDxfImport /////////////////////////////////////////////////////////////
constructor TFlexDxfFormat.Create(AOwner: TObject);
begin
inherited;
FPenWidth := PixelScaleFactor div 100;
FGroups := [dgBlock, dgInsert{, dgPolygonMesh, dgPolyfaceMesh}];
// Init parameters
with FMapParams do begin
xscale := 1;
yscale := 1;
xmin := 0;
xmax := 0;
ymin := 1;
ymax := 1;
xmid := (xmin + xmax) / 2;
ymid := (ymin + ymax) / 2;
end;
end;
destructor TFlexDxfFormat.Destroy;
begin
inherited;
end;
function TFlexDxfFormat.MapFn(P: Point3D; OCS: pMatrix): TPoint;
var tc : Point3D;
begin
try
with FMapParams do
if not Assigned(OCS) then begin
Result.x := Round((P.x - xmin) * xscale * PixelScaleFactor);
Result.y := Round((ymax - P.y) * yscale * PixelScaleFactor);
end else begin
tc := TransformPoint(OCS^, P);
Result.x := Round((tc.x - xmin) * xscale * PixelScaleFactor);
Result.y := Round((ymax - tc.y) * yscale * PixelScaleFactor);
end;
except
//
end;
end;
function TFlexDxfFormat.Convert(AFlex: TFlexPanel; ADxf: DXF_Object): boolean;
var i: integer;
Layer: DXF_layer;
begin
Result := false;
if Assigned(FFlex) or Assigned(FDxf) or
not Assigned(AFlex) or not Assigned(ADxf) then exit;
try
FFlex := AFlex;
FDxf := ADxf;
// Set name
FFlex.Schemes.Name := Dxf.DXF_name;
// Set document size
with FMapParams do begin
FFlex.DocWidth := Round((xmax - xmin) * xscale * PixelScaleFactor);
//(FDxf.emax.x - FDxf.emin.x) * PixelScaleFactor);
FFlex.DocHeight := Round((ymax - ymin) * yscale * PixelScaleFactor);
//(FDxf.emax.y - FDxf.emin.y) * PixelScaleFactor);
end;
// Process layers
for i:=0 to FDxf.num_layers-1 do begin
Layer := DXF_layer(FDxf.layer_lists[i]);
// Find flex layer
FFlexLayer := FFlex.Layers.ByName[Layer.layer_name];
if not Assigned(FFlexLayer) then begin
// Create new layer
FFlexLayer := FFlex.Layers.New;
FFlexLayer.Name := Layer.layer_name;
end;
Result := LoadLayer(Layer);
if not Result then exit;
FFlexLayer := Nil;
end;
finally
FFlex := Nil;
FDxf := Nil;
end;
Result := true;
end;
function TFlexDxfFormat.LoadLayer(Layer: DXF_layer): boolean;
var i: integer;
EntList: Entity_List;
begin
Result := false;
if not Assigned(Layer) then exit;
for i:=0 to Layer.num_lists-1 do begin
EntList := Entity_List(Layer.entity_lists[i]);
Result := LoadEntityList(EntList);
if not Result then exit;
end;
Result := true;
end;
function TFlexDxfFormat.LoadEntityList(EntList: Entity_List): boolean;
var i: integer;
Entity: DXF_Entity;
begin
Result := false;
if not Assigned(EntList) then exit;
for i:=0 to EntList.num_entities-1 do begin
Entity := DXF_Entity(EntList.entities[i]);
Result := LoadEntity(Entity, Nil, FFlex.ActiveScheme);
if not Result then exit;
end;
Result := true;
end;
function TFlexDxfFormat.LoadEntity(Entity: DXF_Entity; OCS:pM;
FlexParent: TFlexControl): boolean;
begin
Result := false;
if not Assigned(Entity) then exit;
if Entity.ClassType = Block_ then
LoadBlock(Block_(Entity), OCS, FlexParent)
else
if Entity.ClassType = Insert_ then
LoadInsert(Insert_(Entity), OCS, FlexParent)
else
if Entity.ClassType = Line_ then
LoadLine(Line_(Entity), OCS, FlexParent)
else
if (Entity.ClassType = PolyLine_) or
(Entity.ClassType = Face3D_) then
LoadPolyLine(PolyLine_(Entity), OCS, FlexParent)
else
if Entity.ClassType = Polygon_Mesh_ then
LoadPolygonMesh(Polygon_Mesh_(Entity), OCS, FlexParent)
else
if Entity.ClassType = Polyface_Mesh_ then
LoadPolyfaceMesh(Polyface_Mesh_(Entity), OCS, FlexParent)
else
if Entity.ClassType = Circle_ then
LoadCircle(Circle_(Entity), OCS, FlexParent)
else
if Entity.ClassType = Arc_ then
LoadArc(Arc_(Entity), OCS, FlexParent)
else
if (Entity.ClassType = Text_) or
(Entity.ClassType = Attrib_) then
LoadText(Text_(Entity), OCS, FlexParent);
Result := true; //Assigned(Control);
end;
function TFlexDxfFormat.LoadBlock(Block: Block_; OCS:pM;
FlexParent: TFlexControl): TFlexGroup;
var i: integer;
t_matrix: pMatrix;
TempMatrix: Matrix;
begin
// we mustn't use the update_transformations call because blocks may be
// nested inside blocks inside other blocks, and update_transformations uses
// a temp fixed matrix which will be overwritten.
if not Assigned(OCS) then
t_matrix := Block.OCS_WCS
else
if not Assigned(Block.OCS_WCS) then
t_matrix := OCS
else begin
TempMatrix := MatrixMultiply(Block.OCS_WCS^, OCS^);
t_matrix := @TempMatrix;
end;
if dgBlock in FGroups then begin
Result := TFlexGroup.Create(FFlex, FlexParent, FFlexLayer);
Result.Name := Block.name;
FlexParent := Result;
end else
Result := Nil;
for i:=0 to Block.entities.count-1 do
LoadEntity(DXF_Entity(Block.entities[i]), t_matrix, FlexParent);
end;
function TFlexDxfFormat.LoadInsert(Insert: Insert_; OCS:pM;
FlexParent: TFlexControl): TFlexGroup;
var i: integer;
t_matrix: pMatrix;
TempMatrix: Matrix;
begin
// we mustn't use the update_transformations call because inserts may be
// nested inside blocks inside other blocks, and update_transformations uses
// a temp fixed matrix which will be overwritten.
if not Assigned(OCS) then
t_matrix := Insert.OCS_WCS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -