unit LoadDXF; Interface uses SysUtils, Classes, Windows, Graphics, ComCtrls, Variants, PCTypesUtils,DrawObjects,Menus, DlgBase, ExtDlgs, PCLayerDlg, OleCtnrs, Buttons, PCgui, GuiStrings, DrawEngine, PowerCad; type TSections = (scHeader, scTables, scBlocks, scEntities, scUnknow); { Used to store readed groups from 0 group to 0 group. } TGroupTable = array[0..512] of Variant; type TPoint2D = record X, Y, W: Real; end; TRect2D = record case Byte of 0: (Left, Bottom, W1, Right, Top, W2: Real); 1: (FirstEdge, SecondEdge: TPoint2D); end; procedure ReadDXF(aPCad: TPowerCad); procedure Rewind; function ConsumeGroup: Boolean; procedure NextSection; { Read the DXF header. } procedure ReadHeader; function ReadAnEntry(GroupDel: Word; var Values: TGroupTable): Word; procedure ReadEntities; procedure ReadEntity; procedure LinePaint; function ReOrderRect2D(const R: TRect2D): TRect2D; function CartesianRect2D(const R: TRect2D): TRect2D; function CartesianPoint2D(const P: TPoint2D): TPoint2D; var FCad: TPowerCad; FCurrentSection: TSections; FStream: TextFile; FGroupCode: Word; FGroupValue: Variant; Entry: TGroupTable; implementation //-------------------------------------------------- //чтение файла по секциям procedure ReadDXF(aPCad: TPowerCad); begin // if fCADCmp2D = nil then Exit; // fUnableToReadAll := False; FCad := aPCad; Rewind; while (FCurrentSection <> scUnknow) do begin case FCurrentSection of scHeader: ReadHeader; { scTables: ReadTables; scBlocks: ReadBlocks; } scEntities: ReadEntities; end; NextSection; end; end; //-------------------------------------------------- // procedure Rewind; begin Reset(FStream); ConsumeGroup; NextSection; end; //-------------------------------------------------- function ConsumeGroup; var TxtLine: String; LastSep: Char; begin LastSep := DecimalSeparator; try ReadLn(FStream, FGroupCode); ReadLn(FStream, TxtLine); if EOF(FStream) then begin Result := False; Exit; end; case FGroupCode of 0..9, 999, 1000..1009: FGroupValue := Trim(TxtLine); 10..59, 140..147, 210..239, 1010..1059: begin if Pos('.', TxtLine) > 0 then DecimalSeparator := '.' else DecimalSeparator := ','; try FGroupValue := StrToFloat_My(Trim(TxtLine)); except FGroupValue := varEmpty; end; end; 60..79, 170..175, 1060..1079 : begin if Pos('.', TxtLine) > 0 then DecimalSeparator := '.' else DecimalSeparator := ','; try FGroupValue := StrToInt(Trim(TxtLine)); except FGroupValue := varEmpty; end; end; else FGroupValue := TxtLine; end; Result := True; finally DecimalSeparator := LastSep; end; end; //-------------------------------------------------- procedure NextSection; begin FCurrentSection := scUnknow; while not ((FGroupCode = 0) and (FGroupValue = 'SECTION')) do if ConsumeGroup = False then Exit; ConsumeGroup; if FGroupValue = 'HEADER' then FCurrentSection := scHeader else if FGroupValue = 'TABLES' then FCurrentSection := scTables else if FGroupValue = 'BLOCKS' then FCurrentSection := scBlocks else if FGroupValue = 'ENTITIES' then FCurrentSection := scEntities; ConsumeGroup; end; //-------------------------------------------------- //чтение заголовка блока procedure ReadHeader; var Entry: TGroupTable; fHasExtension: boolean; fExtension: Trect2D; begin fHasExtension := False; fExtension.Right := 1000; fExtension.Top := 1000; fExtension.W1 := 1.0; fExtension.Left := -1000; fExtension.Bottom := -1000; fExtension.W2 := 1.0; // fAngleDir := adCounterClockwise; угол поворота - CS4Shapes.pas while ReadAnEntry(9, Entry) <> 0 do begin if Entry[9] = '$ANGDIR' then begin { if Entry[70] = 1 then fAngleDir := adClockwise else fAngleDir := adCounterClockwise; } end else if Entry[9] = '$EXTMAX' then begin fExtension.Right := Entry[10]; fExtension.Top := Entry[20]; fHasExtension := True; end else if Entry[9] = '$EXTMIN' then begin fExtension.Left := Entry[10]; fExtension.Bottom := Entry[20]; fHasExtension := True; end; end; if fHasExtension then {!!!!!!!CADSys4.pas!!!!!!!! function ReorderRect2D(const R: TRect2D): TRect2D; This function transforms a point into a point in which the coordinates are integers. To do the transformation the function is used. The resulting point is specified in Windows screen coordinate system. Parameters: is the point being transformed.> } FExtension := ReOrderRect2D(FExtension); end; //-------------------------------------------------- { GroupDel = Group delimiter } function ReadAnEntry(GroupDel: Word; var Values: TGroupTable): Word; begin Result := 0; { Find the start of the entry. } while (FGroupCode <> GroupDel) and (FGroupCode <> 0) do if ConsumeGroup = False then Exit; if (FGroupCode = 0) and (FGroupCode <> GroupDel) then Exit; { Read all values. } repeat if FGroupCode < 256 then Values[FGroupCode] := FGroupValue else if FGroupCode > 999 then { The extended data types are remapped from 256=1000. } Values[FGroupCode - 744] := FGroupValue; ConsumeGroup; until (FGroupCode = GroupDel) or (FGroupCode = 0); Result := GroupDel; end; //-------------------------------------------------- function ReOrderRect2D(const R: TRect2D): TRect2D; begin Result := CartesianRect2D(R); if R.Left > R.Right then begin Result.Left := R.Right; Result.Right := R.Left; end; if R.Bottom > R.Top then begin Result.Bottom := R.Top; Result.Top := R.Bottom; end; end; //-------------------------------------------------- function CartesianRect2D(const R: TRect2D): TRect2D; begin Result.FirstEdge := CartesianPoint2D(R.FirstEdge); Result.SecondEdge := CartesianPoint2D(R.SecondEdge); end; //-------------------------------------------------- function CartesianPoint2D(const P: TPoint2D): TPoint2D; begin if (P.W <> 1.0) and (P.W <> 0.0) then begin Result.X := P.X / P.W; Result.Y := P.Y / P.W; Result.W := 1.0; end else Result := P; end; //-------------------------------------------------- (* procedure TDXF2DImport.ReadTables; var Entry: TGroupTable; begin if fCADCmp2D = nil then Exit; fDXFRead.ReadAnEntry(0, Entry); while fDXFRead.GroupValue <> 'ENDSEC' do begin if Entry[0] = 'LAYER' then begin if fSetLayers then with fCADCmp2D.Layers[fLayerList.Count] do begin Pen.Color := Colors[Abs(Round(Entry[62]))]; Brush.Style := bsClear; Active := Entry[62] >= 0; Name := Entry[2]; end; fLayerList.AddObject(Entry[2], fCADCmp2D.Layers[fLayerList.Count]); end; fDXFRead.ReadAnEntry(0, Entry); end; end; //-------------------------------------------------- procedure TDXF2DImport.ReadBlocks; var Entry: TGroupTable; Tmp: TSourceBlock2D; NLayer: Integer; begin if fCADCmp2D = nil then Exit; while DXFRead.GroupValue <> 'ENDSEC' do begin FDXFRead.ReadAnEntry(0, Entry); NLayer := FLayerList.IndexOf(Entry[8]); if NLayer > -1 then FCADCmp2D.CurrentLayer := NLayer; if Entry[0] = 'BLOCK' then begin Tmp := ReadSourceBlock(Entry); if Assigned(Tmp) then begin FCADCmp2D.AddSourceBlock(Tmp); { Entry[2] contains the name of the block for future ref. } fBlockList.AddObject(Entry[2], Tmp); end; end; end; end; //-------------------------------------------------- function TLayers.GetLayer(Index: Byte): TLayer; begin Result := TLayer(Flayers.Items[Index]); end; //-------------------------------------------------- procedure TLayer.SetName(Nm: TLayerName); begin if fName <> Nm then begin FName := Nm; FModified := True; end; end; *) //-------------------------------------------------- procedure ReadEntities; //var // Tmp: TObject2D; begin // if fCADCmp2D = nil then Exit; while FGroupValue <> 'ENDSEC' do begin // ConsumeGroup; ReadEntity; { Tmp := ReadEntity(False); if Assigned(Tmp) then begin Tmp.Transform(Scale2D(fScale, fScale)); Tmp.ApplyTransform; FCADCmp2D.AddObject(-1, Tmp); end else fUnableToReadAll := True;} end; end; //-------------------------------------------------- {function TDXF2DImport.ReadEntity(IgnoreBlock: Boolean): TObject2D; } procedure ReadEntity; //var // NLayer: Integer; begin ReadAnEntry(0, Entry); // NLayer := FLayerList.IndexOf(Entry[8]); // if NLayer > -1 then // FCADCmp2D.CurrentLayer := NLayer; if Entry[0] = 'LINE' then LinePaint; //Result := ReadLine2D(Entry) { else if Entry[0] = 'ARC' then Result := ReadArc2D(Entry) else if Entry[0] = 'TRACE' then Result := ReadTrace2D(Entry) else if Entry[0] = 'SOLID' then Result := ReadSolid2D(Entry) else if Entry[0] = 'CIRCLE' then Result := ReadCircle2D(Entry) else if Entry[0] = 'ELLIPSE' then Result := ReadEllipse2D(Entry) else if Entry[0] = 'POLYLINE' then Result := ReadPolyline2D(Entry) else if Entry[0] = 'TEXT' then Result := ReadText2D(Entry) else if (not IgnoreBlock) and (Entry[0] = 'INSERT') then Result := ReadBlock(Entry);} end; //-------------------------------------------------- procedure LinePaint; Var CurPos: TPoint; CurPos1: TPoint; begin {CurPos:= Point(Entry[10],Entry[20]); Form2.Pipe.SetNewObj(CurPos); CurPos:= Point(Entry[11],Entry[21]); Form2.pipe.LinkNewObj(CurPos); //обрыв линии Form2.Pipe.BreakPolyline; } CurPos:= Point(Entry[10],Entry[20]); CurPos1:= Point(Entry[11],Entry[21]); FCad.Line(FCad.GetLayerNbr('Подложка'), CurPos.X, CurPos.y, CurPos1.X, CurPos1.Y, 0, 0, 0, 0, False); end; //-------------------------------------------------- (* //-------------------------------------------------- function Point2D(const X, Y: TRealType): TPoint2D; begin Result.X := X; Result.Y := Y; Result.W := 1.0; end; *) //-------------------------------------------------- //-------------------------------------------------- //-------------------------------------------------- //-------------------------------------------------- //-------------------------------------------------- end.