⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formatdxffile.pas

📁 FlexGraphics是一套创建矢量图形的VCL组件
💻 PAS
📖 第 1 页 / 共 2 页
字号:
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 + -