AFsoft WebSite(エーエフソフト・ウェブサイト)
 

オペレーティング・システムについて

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
CADを考える:シンボル
前頁までは、幾何要素/表記要素フィーチャのクロソイドについて見てみました。これによりSXF仕様書の幾何要素/表記要素については終了という事になります。これ以降は、構造化要素フィーチャとなります。
SXF仕様書の次の頁は、構造化要素/複合図形定義・複合図形配置ですが、これについては既に実装済みです。その次となると、「既定義シンボル」とあります。「既定義シンボル」とは? どうも唐突感があります。SXF仕様書には余り詳しく書かれていないようなのでどうもよく分かりません。
 
通常、シンボルといえば、製図における図記号、例えば、電気用図記号や配管用図記号などを思いおこします。これは一般的に、尺度を考慮した実寸で作図するのではなく、尺度に無関係に用紙上の寸法として作図するのが通例ですが、「SXF Ver.3.1仕様書・同解説附属書SFC編(第2版).PDF」のp.44には「定義シンボルの大きさは用紙座標系で解釈する。」とありますので納得出来ますが、既定義シンボルは「ハッチング(パターン)」で使用すると、「SXF Ver.3.1仕様書・同解説フィーチャ仕様編(第2版).PDF」のp.64や、「SXF Ver.3.1実装規約.PDF」のp.1-9にはありますが、ここでは、「部分図の縮尺や作図部品配置倍率を考慮し、用紙上の大きさが変化する」等とあります。ですので既定義シンボルとは、単独で使用する場合と、ハッチング(パターン)で使用する場合とがあり、扱いが異なっている、と解釈出来そうです。
 
また、「既定義」というからには、いろいろなものが既に定義されているのであろうと想定されますが、「SXF Ver.3.1仕様書・同解説共通既定義要素編.PDF」には、「馬踏み sxf_hatch_style_7_symbol」「45 度重ねあじろsxf_hatch_style_8_symbol」の2つのハッチング(パターン)用のものが記述されていますが、それ以外は? また、「SXF Ver.3.1実装規約.PDF」のp.2-6に「そして、SXF 仕様の既定義シンボルのように、幾何形状を交換することなく、属性として与えられた図形生成情報を元にして、幾何形状を再現することも可能である。(※@)」のような記述もあり、ますますもって不明であります。
また、「既定義」という言葉がある以上、「ユーザー定義」というものもあるのだろうか?と思ってしまいますが、それはどのようにして定義をするのか?複合図形定義? それならば複合図形定義の解説でシンボルについての言及があるはずですが、見当たりませんでした。また、「シンボル名」と指定がある以上、これを複合図形名と解釈するのは強引といえます。また、上記※@の文章より、シンボル図形の定義は、外部定義されるのかもしれません。
 
仕様である以上、明確に記載して欲しいのですが、現在、謎です。という訳でこの辺りは、独自仕様として実装する事とします。
 
シンボル図形は、複合図形定義のような感じで TSymbolZukeiDef として定義するものとし、シンボル内に種別フラグや複合図形配置は無いものとします。シンボル内に既定義シンボルも無いものとします。
UnitData.pas
type
 ・・・
 TSymbolZukeiDef = record // 構造化要素|シンボル図形定義
  exf : Boolean ;     // 存在フラグ(True:有り False:無し)
  name : string ;     // シンボル名
  cnt : Integer ;     // 配置数
  mOrd : array of TDataOrder ;  // 作図順
  mOrdN : Integer ;       // 数
  mTen : array of TDataTenMarker; // 幾何要素|点マーカ
  mTenN : Integer ;       // 数
  mLin : array of TDataLine;   // 幾何要素|線分
  mLinN : Integer ;       // 数
  mLns : array of TDataLines;  // 幾何要素|折線
  mLnsN : Integer ;       // 数
  mCir : array of TDataCircle;  // 幾何要素|円
  mCirN : Integer ;       // 数
  mArc : array of TDataArc;   // 幾何要素|円弧
  mArcN : Integer ;       // 数
  mEll : array of TDataEllipse; // 幾何要素|楕円
  mEllN : Integer ;       // 数
  mEAr : array of TDataEllipseArc; // 幾何要素|楕円弧
  mEArN : Integer ;       // 数
  mTxt : array of TDataText;   // 幾何要素|文字
  mTxtN : Integer ;       // 数
  mBez : array of TDataBezier;  // 幾何要素|スプライン→ベジェ
  mBezN : Integer ;       // 数
  mBsp : array of TDataBspline; // 幾何要素|Bスプライン曲線
  mBspN : Integer ;       // 数
  mSpl : array of TDataSpline;  // 幾何要素|スプライン曲線
  mSplN : Integer ;       // 数
  mClo : array of TDataClothoid; // 幾何要素|クロソイド曲線
  mCloN : Integer ;       // 数
 end;
 
 TDataClass = class
  public
  { Public 宣言 }
  ・・・
  sDef : array of TSymbolZukeiDef; // 構造化要素|シンボル定義
  sDefN: Integer ; // 数
  ・・・
 
また、シンボル定義データ用の初期化・解放用の手続き「DataClearSymbol」「DataInitSymbol」、及び、シンボル定義データの追加用関数「AddSymbolDef」も追加しておきます。シンボル図形は、ひょっとすると、DXFファイル等で他CADソフト等へデータを受け渡す際、複合図形(ブロック図形)として受け渡すかもしれません。そうなると、シンボル名は、複合図形名と同じ名前を使わないようにしないといけないでしょう。ですので、複合図形名のチェックを行う関数 FZukeiNameCheck にシンボル名のチェックも組み込み、シンボル名の場合はマイナス値で返すようにします。ですのでこの関数を使用している箇所の変更も行っておきます。各要素の登録で 追加先複合図形名にシンボル名を入れた場合、シンボル図形への要素データ定義を行うようにします。
例:点マーカ の場合
UnitData.pas
// 点マーカ データ項目の追加登録
function TDataClass.AddDataTen(s:string;lay,col,mc:integer;px,py,an,sc:double) : Boolean;
 ・・・
 end
 else begin
  m := FZukeiNameCheck(0,s);
  if (m = 0) then exit ; // 追加先の複合図形名は無いのでエラー
  with fDef[m-1] do begin
   if (AddDataOrder(m,1,mTenN)) then begin
    try
     Inc(mTenN);
     if ((mTenN mod 200) = 1) then SetLength(mTen, mTenN+199);
     with mTen[mTenN-1] do begin
      exf := True ;
      Layer := lay ;
      Color := col ;
      start_x := px ;
      start_y := py ;
      marker_code := mc ;
      rotate_angle:= an ;
      Scale := sc ;
     end;
     Result := True ;
     AddLayerFCnt(lay,col,-1,-1,-1);
    except
     Dec(mTenN);
     Dec(mOrdN);
    end;
   end;
  end;
 end;
end;
          ↓
          ↓
UnitData.pas
// 点マーカ データ項目の追加登録
function TDataClass.AddDataTen(s:string;lay,col,mc:integer;px,py,an,sc:double) : Boolean;
 ・・・
 end
 else begin
  m := FZukeiNameCheck(0,s);
  if (m > 0) then begin
   with fDef[m-1] do begin
    if (AddDataOrder(m,1,mTenN)) then begin
     try
      Inc(mTenN);
      if ((mTenN mod 200)=1) then SetLength(mTen, mTenN+199);
      with mTen[mTenN-1] do begin
       exf := True ;
       Layer := lay ;
       Color := col ;
       start_x := px ;
       start_y := py ;
       marker_code := mc ;
       rotate_angle:= an ;
       Scale := sc ;
      end;
      Result := True ;
      AddLayerFCnt(lay,col,-1,-1,-1);
     except
      Dec(mTenN);
      Dec(mOrdN);
     end;
    end;
   end;
  end
  else if (m < 0) then begin
   with sDef[-m-1] do begin
    if (AddDataOrder(m,1,mTenN)) then begin
     try
      Inc(mTenN);
      if ((mTenN mod 200)=1) then SetLength(mTen, mTenN+199);
      with mTen[mTenN-1] do begin
       exf := True ;
       Layer := lay ;
       Color := col ;
       start_x := px ;
       start_y := py ;
       marker_code := mc ;
       rotate_angle:= an ;
       Scale := sc ;
      end;
      Result := True ;
     except
      Dec(mTenN);
      Dec(mOrdN);
     end;
    end;
   end;
  end;
 end;
end;
その他、関数 AddDataOrder等の内容も修正しています。これにより、複合図形定義するのと同様にシンボル図形の定義も行う事が出来ます。
 
それではシンボル図形の配置について考えます。
以下、SXF仕様書での既定義シンボルについてです。
構造化要素|既定義シンボル

※SXF Ver.3.1仕様書より
パラメータ説明範囲
LayerIntレイヤコード
color_flagInt色コードフラグ(0:色コード無効、1:有効)
ColorInt色コード
name[257]Charシンボル名0<文字列長≦256バイト
start_xdouble配置位置X座標 double(64bits)の
範囲(有効桁15桁)
start_ydouble配置位置Y座標 double(64bits)の
範囲(有効桁15桁)
rotate_angledouble回転角0≦度<360
Scaledouble倍率0<倍率<1.0×1015
備考
・既定義シンボルの大きさは用紙座標系で解釈する。
とありますが、上記の図で「用紙」とありますが、部分図、作図グループ、作図部品の上にも登録出来ます。但し、大きさは部分図・作図部品での尺度は考慮しない(尺度=1)けれども、ここで指定出来る倍率での大きさの変化は可能とする、という事です。
 
それではシンボル図形のデータ構造を決めます。
UnitData.pas
type
 ・・・
 TDataSymbolZukei = record // 構造化要素|シンボル図形配置
  exf : Boolean ;     // 存在フラグ(True:有り False:無し)
  Layer : Integer ;    // レイヤ(0:定義しない 1〜256)
  color_flag : Integer ; // 色コードフラグ(0:無効 1:有効)
  Color : Integer ;    // 色 (0:レイヤ色  1〜256)
  name : string ;     // シンボル図形名
  start_x : double ;   // 配置位置X座標
  start_y : double ;   // 配置位置Y座標
  rotate_angle : double ; // 回転角[°]
  Scale : double ;    // 倍率
 end;
 
 TFukugoZukeiDef = record  // 構造化要素|複合図形定義
  exf : Boolean ;     // 存在フラグ(True:有り False:無し)
  name : string ;     // 複合図形名
  Flag : Integer ;     // 種別フラグ
  cnt : Integer ;     // 配置数
  ・・・
  mSzk : array of TDataSymbolZukei; // 構造化要素|シンボル配置
  mSzkN : Integer ; // 数
  mFzk : array of TDataFukugoZukei; // 構造化要素|複合図形配置
  mFzkN : Integer ;         // 数
 end;
 
 TDataClass = class
  public
  { Public 宣言 }
  ・・・
  dSzk : array of TDataSymbolZukei; // 構造化要素|シンボル配置
  dSzkN : Integer ; // 数
  ・・・
 
データ追加用の関数は
function AddDataSZukei(s:string;lay,cf,col:integer;nam:string;
 px,py,an,sc:double) : Boolean;
のようにします。線分・折線等と同様、最初に「データ追加先の複合図形名(幾何要素) null:用紙へ追加(表記要素)」を指定するようにしています。
 
UnitData.pas
// シンボル図形配置 データ項目の追加登録
function TDataClass.AddDataSZukei(s:string;lay,cf,col:integer;nam:string;px,py,an,sc:double) : Boolean;
var
 m,n : integer ;
begin
 Result := False;
 if (lay < 0) or (lay > zLayN) then lay := 0 ;
 if (cf <> 1) then cf := 0 ;
 if (col < 0) or (col > zColN) then col := 0 ;
 if (nam = '') then exit ;
 n := FZukeiNameCheck(0,nam); // シンボル図形名が無くても登録
 an := SetAngle(an);
 if (sc < LIMIT8) then sc := 1.0;
 
 if (s = '') then begin
  // 用紙へ追加
  if (AddDataOrder(0,100,dSzkN)) then begin
   try
    Inc(dSzkN);
    if ((dSzkN mod 200) = 1) then SetLength(dSzk, dSzkN+199);
    with dSzk[dSzkN-1] do begin
     exf := True ;
     Layer := lay ;
     color_flag := cf ;
     Color := col ;
     name := nam ;
     start_x := px ;
     start_y := py ;
     rotate_angle:= an ;
     Scale := sc ;
    end;
    Result := True ;
    if (cf = 0) then
     AddLayerCnt(lay,-1,-1,-1,-1)
    else
     AddLayerCnt(lay,col,-1,-1,-1);
   except
    Dec(dSzkN);
    Dec(dOrdN);
   end;
   if (Result)and(n < 0) then
    sDef[-n-1].cnt := sDef[-n-1].cnt + 1 ; // 配置数カウント
  end;
 end
 else begin
  m := FZukeiNameCheck(0,s);
  if (m > 0) then begin
   with fDef[m-1] do begin
    if (AddDataOrder(m,100,mSzkN)) then begin
     try
      Inc(mSzkN);
      if ((mSzkN mod 200)=1) then SetLength(mSzk, mSzkN+199);
      with mSzk[mSzkN-1] do begin
       exf := True ;
       Layer := lay ;
       color_flag := cf ;
       Color := col ;
       name := nam ;
       start_x := px ;
       start_y := py ;
       rotate_angle:= an ;
       Scale := sc ;
      end;
      Result := True ;
      if (cf = 0) then
       AddLayerFCnt(lay,-1,-1,-1,-1)
      else
       AddLayerFCnt(lay,col,-1,-1,-1);
     except
      Dec(mSzkN);
      Dec(mOrdN);
     end;
    end;
   end;
   if (Result)and(n < 0) then
    sDef[-n-1].cnt := sDef[-n-1].cnt + 1 ; // 配置数カウント
  end
 end;
end;
 
これでシンボル図形データの登録は出来るようになりました。
 
次にシンボル図形の描画についてです。
指定したシンボル名のシンボル図形がない場合は、「SXF Ver.3.1実装規約.PDF」のp.1-11に
1-10 既定義シンボル
(1)既定義シンボルの形状を描画できない場合の処理
図形の表示
・図形が再現できない既定義シンボルが渡された場合、既定義シンボル名称もしくは“?”を、文字フィーチャとして、以下の条件で配置するものとする。
   配置点座標:シンボル配置点座標
   配置基準 :中央
   文字の大きさ:任意(可能な限り小さくすることが望ましい)
※パターンハッチング中の既定義シンボルは適用対象外
とありますので、それに対応するようにします。
 
UnitDataGraph.pas
// シンボル図形の表示
procedure DisplaySymbolZukei(lay,cf,col:integer;nam:string;px,py,an,sc:double;t:TMatrix);
var
 x1,y1,x2,y2,ma : double ;
 tr,tr1 : TMatrix ;
 j,k,o,o1,o2,la,co : integer ;
 lx1,ly1,lx2,ly2,lan,lsc : double ;
 lx,ly : array of double ;
begin
 // 変換行列による角度を取得する
 x1 := 0.0;  y1 := 0.0;  MtxXY(x1,y1, x1,y1, t);
 x2 := 10.0; y2 := 0.0;  MtxXY(x2,y2, x2,y2, t);
 ma := dAngle((x2-x1),(y2-y1));
 ma := ma + an ;
 // 変換行列による位置を取得する
 x1 := px ;  y1 := py ;  MtxXY(x1,y1, x1,y1, t);
 // 変換行列を作成
 MtxScale(tr, sc,sc);
 MtxRotD(tr1, ma);
 tr := MtxMult(tr,tr1) ;
 MtxMove(tr1, x1,y1);
 tr := MtxMult(tr,tr1) ;
 //
 j := CData.FZukeiNameCheck(0,nam) ;
 if (j < 0) then begin
  with CData.sDef[-j-1] do begin
   for o:=0 to mOrdN-1 do begin
    o1 := mOrd[o].DataType ;
    o2 := mOrd[o].DataNo ;
    case (o1) of
    1: begin
      // 点マーカ・データ表示
      with mTen[o2] do begin
       MtxXY(lx1,ly1, start_x,start_y, tr);
       lan := (rotate_angle + ma)/180.0*Pi ;
       lsc := Scale * sc ;
       la := Layer ; if (lay > 0) then la := lay ;
       co := Color ; if (cf = 1) then co := col ;
       DisplayTenMarker(la,co,marker_code,lx1,ly1,lan,lsc);
      end;
     end;
    2: begin
      // 線分データ表示
      with mLin[o2] do begin
       MtxXY(lx1,ly1, start_x,start_y, tr);
       MtxXY(lx2,ly2, end_x ,end_y , tr);
       la := Layer ; if (lay > 0) then la := lay ;
       co := Color ; if (cf = 1) then co := col ;
       DisplayLine(la,co,Ltype,line_width,lx1,ly1,lx2,ly2);
      end;
     end;
     ・・・・・・
    end;
   end;
  end;
  lx := nil;
  ly := nil;
 end
 else begin
  // シンボルが存在しない場合は文字を表示(W=2,H=2,S=0)
  if (lay = 0) then lay := 1;
  if (cf = 0) then col := 0;
  lx2 := 2.0*Length(nam);
  DisplayText(lay,col,0,5,1, 0,0, 2,lx2,0, 0,0,nam,tr);
 end;
end;
 
全体のクリッピングはどのような状態になるのか分かりませんので入れていません。シンボルは最初に
with CData do begin
 ・・・
 // シンボル定義
 DataClearSymbol ;
 AddSymbolDef('シンボルA');
 ・・・
のように初期化と「シンボルA」を1つ追加定義しています。シンボルの図形定義は複合図形定義と同じような感じで、例えば
CData.AddDataTen( 'シンボルA', 1, 1,2, 0,0,1,0);
CData.AddDataLine('シンボルA', 1,10,1,1, -10,-10, 10,-10);
CData.AddDataLine('シンボルA', 1,11,1,1, 10,-10, 10, 10);
CData.AddDataLine('シンボルA', 1,12,1,1, 10, 10, -10, 10);
CData.AddDataLine('シンボルA', 1,13,1,1, -10, 10, -10,-10);
CData.AddDataLine('シンボルA', 1,14,1,1, -10,-10, 10, 10);
CData.AddDataLine('シンボルA', 1,15,1,1, -10, 10, 10,-10);
のように作っておきます。上記の場合は、正方形に×を入れて中央に点マーカ(○)を入れます。このシンボルを使う時には
CData.AddDataSZukei('' , 1,0,0,'シンボルA', 100,80,0,1);
CData.AddDataSZukei('部分図A', 1,0,0,'シンボルA', 100,80,0,1);
のようにすると、位置(100,80)に角度0°倍率1でレイヤ1・色指定無し=定義した各データ要素の色で表示します。また、
CData.AddDataSZukei('' , 1,1,2,'シンボルA', 130,80,30,0.5);
CData.AddDataSZukei('部分図A', 1,1,2,'シンボルA', 130,80,30,0.5);
のようにすると、位置(130,80)に角度30°倍率0.5でレイヤ1・色指定有り=No.2=赤色で表示します。
 

 
それでは、ここまでのテストプログラムです。実行ファイル、gdiplus.dll、gdipフォルダは入っていません。ソースのみです。
 
CAD装置(1)
CAD装置(2)
メディア
AutoCADの
DIESELマクロ
CSV
DXF
PCES
IGES
STEP
数学とCAD
CAD作ろ!
CADを考える
 ▲PREV
 ▼NEXT
M7
Jw_cad
 
お問い合わせ 
本サイトはリンクフリーです
リンクバナー
(C)Copyright 1999-2015 By AFsoft All Rights Reserved.