« ☆式の評価(数式の計算) | トップページ | ■GIS・・・。 »

☆JWWファイルの超簡易表示 その5

ブロックデータの回転処理を含めてみました。(倍率処理に関しては線のみ)
まだまだ怪しい部分は多いのですが、一応表示できているようです。 コードは、「JWWファイルの超簡易表示 その4」からの 変更部分のみ載せますね。

Blocktree

Unit1名前空間での訂正内容です。
// 初期設定
procedure TForm1.FormCreate(Sender: TObject);
var
  FileName: String;
  WindowStyles: Integer;
begin
  // TreeViewにCheckBoxを表示させます。
  WindowStyles := GetWindowLong(TreeView1.Handle, GWL_STYLE);
  SetWindowLong(TreeView1.Handle, GWL_STYLE, WindowStyles or TVS_CHECKBOXES);

  JWWBlockList := TJWWBlockList.Create;

  FileName := 'test.jww';
  JwwDataLoadFromFile(FileName);
  SetLayerName(TreeView1);
  MakeBlockTree(TreeView2);   // ブロックツリーの作成  
  JWWDataDraw(PaintBox1);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  BlockTreeClear;
  JWWBlockList.Free;
end;

procedure TForm1.BlockTreeClear;
var
  Node: TTreeNode;
begin
  Node := TreeView2.Items.GetFirstNode;
  while Node <> nil do
  begin
    if Assigned(Node.Data) then
      TBlockNodeData(Node.Data).Free;
    Node := Node.GetNext;
  end;
end;


jwwDraw名前空間の追加・変更内容です。
type
  TBlockNodeData = class(TObject)
  private
    x1  : Double;
    y1  : Double;
    kaku: Double;
    bx  : Double;
    by  : Double;
    ID  : Integer;
  public
    constructor Create(AID: Integer; ACDataBlock: CDataBlock);
  end;

implementation

uses
  Commctrl, ShlObj;

const
  TVIS_CHECKED  = $2000;
constructor TBlockNodeData.Create(AID: Integer; ACDataBlock: CDataBlock);
begin
  ID   := AID;
  x1   := ACDataBlock.m_DPKijunTen_x;
  y1   := ACDataBlock.m_DPKijunTen_y;
  kaku := ACDataBlock.m_radKaitenKaku;
  bx   := ACDataBlock.m_dBairitsuX;
  by   := ACDataBlock.m_dBairitsuY;
end;

var
  TV: TTreeView;

// ブロックデータの取得
function GetData(var ID: Integer; var x1, y1, kaku, bx, by: Double): Boolean;
var
  ANode: TTreeNode;
begin
  Result := False;
  x1 := 0;
  y1 := 0;
  kaku := 0;
  bx := 0;
  by := 0;

  // 指定IDを持つノードの検索
  ANode := TV.Items.GetFirstNode;
  repeat
    if Assigned(ANode.Data) and (TBlockNodeData(ANode.Data).ID = ID) then Break;
    ANode := ANode.GetNext;
  until ANode = nil;

  // 見つからなかった場合には終了させます。
  if ANode = nil then
  begin
    ID := -1; // 見つからなかった場合
    Exit;
  end;

  // 指定ノードのブロックデータ取得
  if Assigned(ANode.Data) then
  begin
    x1   := TBlockNodeData(ANode.Data).x1;
    y1   := TBlockNodeData(ANode.Data).y1;
    kaku := TBlockNodeData(ANode.Data).kaku;
    bx   := TBlockNodeData(ANode.Data).bx;
    by   := TBlockNodeData(ANode.Data).by;
  end;

  // 指定ノードの親ノードのID取得
  ANode := ANode.Parent;
  if Assigned(ANode.Data) then
    ID := TBlockNodeData(ANode.Data).ID
  else
    ID := -1; // 見つからなかった場合
  Result := True;
end;


// MakeBlockTree
procedure MakeBlockTree(TreeView: TTreeView);
var
  Node: TTreeNode;
  S: String;

  function GetLable(S: String): String;
  var
    I: Integer;
  begin
    I := AnsiPos('@@',S);
    Result := Copy(S,1,I-1);
  end;

  procedure GetNode(CDB: CDataBlock);
  var
    I,J: Integer;
    S :String;
  begin
    I := CDB.m_n_Number;
    S := GetLable(JWWBlockList.BlockList[I].m_strName);
    Node := TV.Items.AddChildObject(Node, S, TBlockNodeData.Create(I, CDB));
    for J := JWWBlockList.BlockList[I].Count -1 downto 0  do
    begin
      if JWWBlockList.DataType[I,J] = Block then
        GetNode(JWWBlockList.DataBlock[I,J]);
    end;
    Node := Node.Parent;
  end;

var
  I: Integer;
begin
  TV := TreeView;
  TV.Items.BeginUpdate;
  try
    TV.Items.Clear;
    Node := TV.Items.Add(nil,'BlockTree');
    for I:= Low(JWWBlock) to High(JWWBlock) do
    begin
      S := '';
      Node := TV.Items.GetFirstNode;
      GetNode(JWWBlock[I]);
    end;
    // 名前で並べ替えさせます。
    TV.SortType := stText;
    TV.SortType := stNone;
    TV.FullExpand;
  finally
    TV.Items.EndUpdate;
  end;
end;


ブロック図形の描画部分です。 前回のものと入れ替えて下さい。
  // ブロック図形の描画

  // 回転移動
  procedure Revo(x1, y1, xc, yc, a: Double; var x2, y2: Double);
  begin
    x2 := xc + (x1-xc)*Cos(a) - (y1-yc)*Sin(a);
    y2 := yc + (x1-xc)*Sin(a) + (y1-yc)*Cos(a);
  end;

  // 線の変形
  procedure SenModified(ID: Integer; var Sen: CDataSen);
  var
    x1, y1, kaku, bx, by, x2, y2: Double;
  begin
    while True do
    begin
      if not GetData(ID, x1, y1, kaku, bx, by) then Exit;
      Sen.m_start_x := (Sen.m_start_x * bx)+x1;
      Sen.m_start_y := (Sen.m_start_y * by)+y1;
      Sen.m_end_x   := (Sen.m_end_x   * bx)+x1;
      Sen.m_end_y   := (Sen.m_end_y   * by)+y1;
      if Kaku <> 0 then
      begin
        Revo(Sen.m_start_x, Sen.m_start_y, x1, y1, Kaku, x2, y2);
        Sen.m_start_x := x2;
        Sen.m_start_y := y2;
        Revo(Sen.m_end_x, Sen.m_end_y, x1, y1, Kaku, x2, y2);
        Sen.m_end_x := x2;
        Sen.m_end_y := y2;
      end;
      if ID < 0 then Exit;
    end;
  end;

  // 円弧の変形
  procedure EnkoModified(ID: Integer; var Enko: CDataEnko);
  var
    x1, y1, kaku, bx, by, x2, y2: Double;
  begin
    while True do
    begin
      if not GetData(ID, x1, y1, kaku, bx, by) then Exit;
      Enko.m_start_x := (Enko.m_start_x * bx)+x1;
      Enko.m_start_y := (Enko.m_start_y * by)+y1;
      if Kaku <> 0 then
      begin
        Revo(Enko.m_start_x, Enko.m_start_y, x1, y1, Kaku, x2, y2);
        Enko.m_start_x := x2;
        Enko.m_start_y := y2;
        Enko.m_radKatamukiKaku := Enko.m_radKatamukiKaku + kaku;
      end;
      if ID < 0 then Break;
    end;
  end;

  // 文字の変形
  procedure MojiModified(ID: Integer; var Moji: CDataMoji);
  var
    x1, y1, kaku, bx, by, x2, y2: Double;
  begin
    while True do
    begin
      if not GetData(ID, x1, y1, kaku, bx, by) then Exit;
      Moji.m_start_x := (Moji.m_start_x * bx)+x1;
      Moji.m_start_y := (Moji.m_start_y * by)+y1;
      if Kaku <> 0 then
      begin
        Revo(Moji.m_start_x, Moji.m_start_y, x1, y1, Kaku, x2, y2);
        Moji.m_start_x := x2;
        Moji.m_start_y := y2;
        Moji.m_degKakudo := Moji.m_degKakudo + RadToDeg(Kaku);
      end;
      if ID < 0 then Break;
    end;
  end;

  // ソリッド図形の変形
  procedure SolidModified(ID: Integer; var Solid: CDataSolid);
  var
    x1, y1, kaku, bx, by, x2, y2: Double;
  begin
    while True do
    begin
      if not GetData(ID, x1, y1, kaku, bx, by) then Exit;
      Solid.m_start_x := (Solid.m_start_x * bx)+x1;
      Solid.m_start_y := (Solid.m_start_y * by)+y1;
      Solid.m_end_x   := (Solid.m_end_x * bx)+x1;
      Solid.m_end_y   := (Solid.m_end_y * by)+y1;
      Solid.m_DPoint2_x:= (Solid.m_DPoint2_x * bx)+x1;
      Solid.m_DPoint2_y:= (Solid.m_DPoint2_y * by)+y1;
      Solid.m_DPoint3_x:= (Solid.m_DPoint3_x * bx)+x1;
      Solid.m_DPoint3_y:= (Solid.m_DPoint3_y * by)+y1;

      if Kaku <> 0 then
      begin
        Revo(Solid.m_start_x, Solid.m_start_y, x1, y1, Kaku, x2, y2);
        Solid.m_start_x := x2;
        Solid.m_start_y := y2;
        Revo(Solid.m_end_x, Solid.m_end_y, x1, y1, Kaku, x2, y2);
        Solid.m_end_x := x2;
        Solid.m_end_y := y2;
        Revo(Solid.m_DPoint2_x, Solid.m_DPoint2_y, x1, y1, Kaku, x2, y2);
        Solid.m_DPoint2_x := x2;
        Solid.m_DPoint2_y := y2;
        Revo(Solid.m_DPoint3_x, Solid.m_DPoint3_y, x1, y1, Kaku, x2, y2);
        Solid.m_DPoint3_x := x2;
        Solid.m_DPoint3_y := y2;
      end;
      if ID < 0 then Break;
    end;
  end;

  procedure DrawBlock(CDB: CDataBlock);
  var
    I,J: Integer;
    Sen1: CDataSen;
    Enko1: CDataEnko;
    Moji1: CDataMoji;
    Solid1: CDataSolid;
  begin
    I :=  CDB.m_n_Number;

    for J := JWWBlockList.BlockList[I].Count-1  downto 0 do
    begin
      case JWWBlockList.DataType[I,J] of
        Sen: begin
              Sen1 := JWWBlockList.DataSen[I,J];
              SenModified(I, Sen1);
              DrawSen(Sen1);
            end;
        Enko: begin
                Enko1 := JWWBlockList.DataEnko[I,J];
                EnkoModified(I, Enko1);
                DrawEnko(Enko1);
             end;
        //Ten:
        Moji: begin
                Moji1 := JWWBlockList.DataMoji[I,J];
                MojiModified(I, Moji1);
                DrawMoji(Moji1);
             end;
        Solid: begin
                Solid1 := JWWBlockList.DataSolid[I,J];
                SolidModified(I, Solid1);
                DrawSolid(Solid1);
             end;
       Block: begin
                DrawBlock(JWWBlockList.DataBlock[I,J]);
             end;
      end;
    end;
  end;

var
  I: Integer;
begin
  // 画面の消去
  CLS;

  // 用紙枠の描画
  Draw_Paper_Frame;

  // 線の描画
  for I := Low(JWWSen) to High(JWWSen) do
    DrawSen(JWWSen[I]);

  // 円弧の描画
  for I := Low(JWWEnko) to High(JWWEnko) do
    DrawEnko(JWWEnko[I]);

  // 文字の描画
  for I := Low(JWWMoji) to High(JWWMoji) do
    DrawMoji(JWWMoji[I]);

  // ソリッド図形
  for I := Low(JWWSolid) to High(JWWSolid) do
    DrawSolid(JWWSolid[I]);

  // ブロックデータの描画
  for I:= Low(JWWBlock) to High(JWWBlock) do
    DrawBlock(JWWBlock[I]);
end;

|

« ☆式の評価(数式の計算) | トップページ | ■GIS・・・。 »