<入門者歓迎です。ベテランのあなた、VectorScriptの普及にお力添えを!> |
あまり確認はしていませんが、3D多角形の周長を計算します。
PROCEDURE AddSidePoly3D ;
VAR
v1, v2 : VECTOR;
h : HANDLE;
i, End_i, c : INTEGER;
result : REAL;
BEGIN
h := FSActLayer;
IF ( h <> NIL ) AND ( 25 = GetType( h ) ) THEN
BEGIN
IF IsPolyClosed( h ) THEN
BEGIN
End_i := GetVertNum( h );
i := -1;
c := 0;
REPEAT
i := i+1;
c := c+1;
GetPolyPt3D( h, i, v1.x, v1.y, v1.z );
GetPolyPt3D( h, c, v2.x, v2.y, v2.z );
result := result+Norm( v2-v1 );
UNTIL i = End_i-1 ;
GetPolyPt3D( h, End_i-1, v1.x, v1.y, v1.z );
GetPolyPt3D( h, 0, v2.x, v2.y, v2.z );
result := result+Norm( v2-v1 );
AlrtDialog( Concat( 'この3D多角形の周長は', result ) );
END ELSE BEGIN
End_i := GetVertNum( h );
i := -1;
c := 0;
REPEAT
i := i+1;
c := c+1;
GetPolyPt3D( h, i, v1.x, v1.y, v1.z );
GetPolyPt3D( h, c, v2.x, v2.y, v2.z );
result := result+Norm( v2-v1 );
UNTIL i = End_i-1 ;
AlrtDialog( Concat( 'この3D多角形の周長は', result ) );
END;
END;
END ;
RUN( AddSidePoly3D ) ;
いただきました。
3D多角形って距離(3次元での長さ)は表示されないんですよね。
ありがとうございます。
2010でようやくまともな3次元計測ツールができました。以前は3D基準点を使ったうさん臭い
ものは出来たのですが、2009ではそれも出来なくなりましたが...。
PROCEDURE Measur3D ;
VAR
v1, v2 : VECTOR;
FUNCTION TempToolCallback(action, msg1, msg2 : LONGINT) : LONGINT;
BEGIN
TempToolCallback := 0;
CASE action OF
3: BEGIN {kOnToolDoSetupEventID}
vstSetHelpString ( '計測したい2点目をクリックしてください' );
END;
103 : BEGIN {kToolDrawEventID}
vstGetCurrPt3D( v2.x, v2.y, v2.z, FALSE );
vstDrawCoordLine3D( v1.x, v1.y, v1.z, v2.x, v2.y, v2.z );
END;
END;
END;
BEGIN
SetTempToolHelpStr( '計測開始点をクリックしてください' );
GetPt3D( v1.x, v1.y, v1.z, FALSE );
RunTempTool( TempToolCallback, FALSE );
AlrtDialog( Concat( '距離= ', Num2Str( 3,Norm( v2-v1 ) ), ' x= ', Num2Str( 3, v2.x-v1.x ), ' y= ', Num2Str( 3, v2.y-v1.y ), ' z= ', Num2Str( 3, v2.z-v1.z ) ) );
END;
RUN( Measur3D ) ;
与太郎さま
江戸の黒板当番さま
ご親切な回答ありがとうございました。
出来なくはないかもしれないが、かなり技術が必要なんだということがわかりました。
また何か質問等あればよろしくお願い致します。
ワークシートの問題すっね。
ファイルリンク機能が出来た段階でワークシート名称がユニーク(唯一の存在)の
方でないとだめみたいですよ。
>ファイルA.ファイルB.に共通した名称のワークシートがあり、その中の同一のセルの内容を
ファイルCのワークシートにリンクさせることは可能でしょうか?
は共通名称があった段階でできない。
>ひとつのフォルダ内にある、すべてのファイルのワークシートの同一セルを他のファイルの
ワークシートにリンクさせることは可能でしょうか?
可能だけど大変そうだな。
ここん所はマニュアルも避けて通っているんじゃないだろうかと思われる程
未開の地ですよ。最近、ちょっとお化粧できるようになったのも
オーストラリアのパワーだもんね。
BIMだと標榜するんならもう少し使い易くして欲しい所ですな。
ところで一つのセルに1bite文字256字の制約解けないかなあ。
残念ですが、
VWではファイル間のワークシート参照は出来ません。
また、VectorScriptでファイルを指定することも出来ません。
なので、ご質問のようなことは無理だと思います。
ただしAppleScriptを使えば、フォルダー内のVWファイルを1つずつ開いて、
ワークシートのセルの内容を合計したり出来るはずです。
AppleScriptには、VectorScriptを埋め込む必要があるかも知れません。
WinでもAppleScriptに相当するものがあると思いますが、よく判りません。
はじめましてこんにちは。
script機能なのかワークシート機能なのかわからずこちらに投稿させて頂きます。
ワークシートを使っているのですが、下記の内容が可能かどうかご存じでしたら教えてください。
ファイルA.ファイルB.に共通した名称のワークシートがあり、その中の同一のセルの内容を
ファイルCのワークシートにリンクさせることは可能でしょうか?
もしくはひとつのフォルダ内にある、すべてのファイルのワークシートの同一セルを他のファイルのワークシートにリンクさせることは可能でしょうか?
どなたか教えてください。よろしくお願いします。
64ビット対応と言ってもメモリ空間が広くなるだけなので、スクリプトへの影響はないでしょう。
それよりも、PowerPCの時点ですでにCPU内部のレジスタは64ビットになってるのに、
いまだに整数型が16ビットのInteger型と32ビットのLongint型しかないのは困ります。
32ビットだと地球の全人口も扱えないし、金融関係も無理ですからね。
配列サイズの16ビット縛りもいい加減直して貰いたいです。
いまどきファイル内の図形が6万以上というのはざらにあるので、配列に入り切らない場面もあります。
配列を使わなくても図形の数を調べることは結構ありますが、Integer型(16ビット)だとオーバーフロー
する可能性が無視できません。
出来るだけLongint型(32ビット)を使うようにしていますが、
Integer型でもLongint型でも内部の処理は64ビットで構わないんじゃないかと思ったりします。
すみません。Scriptのことは全く分らないのですけども
>32ビット整数という制限も仕方がなかったと思われます。
に吸い寄せられてしまいました。
今は64ビットへOS段階で対応しつつあるようですが、
アプリベースではAr○○CADの窓7上で64ビットが動いている
ようですよね。
アプリ業界では生き残りをかけて書き直していると言うことなんでしょうか?
とするとVector Scriptも64ビット用なんてことになるんでしょうか?
VWのワークシートでもExcelのように日付や時間を使えます。
もちろん日数計算も出来ますが、2040年2月6日までしか扱えないという問題があります。
正確に言うと1904/1/1 0:00:00〜2040/2/6 6:28:15までしか扱えません。
40/2/7と打ち込むと一見ちゃんと表示されますが、それは2040/2/7じゃなくて1940/2/7です。
2040/2/7と打つと、1940/1/2か2040/2/6(最近のバージョン)になってしまいます。
VectorWorksでもExcelでも、日付データは内部では単なる数字です。
セルの書式を「標準」にしてみればそれは判ります。
たとえば、2010/5/21なら38857.5(Excelでは38857または38858)になるはずです。
これは、1904/1/1から2010/5/21までの日数です。
VWの場合は1904/1/1の0:00:00をゼロとして、そこからの日数がセルのデータとして記憶されます。
時刻は少数部の値(0〜1)が0:00:00〜24:00:00に対応します。
先の38857.5は2010/5/21の12:00:00PMということになります。
時刻(h:m:s)を0〜1の数値データにする式は、n = ((s/60 + m)/60 + h)/24 です。
VWのワークシートが2040/2/6までしか扱えない理由は、MiniCADが生まれた1988年当時のMacの仕様
と関係がありそうです。
当時のMacの内部時計は32ビットカウンタに秒単位の整数値を保持していました。
VWのほうでもそれに合わせておけば、システムルーチンで数値⇔日付時刻を変換できるし、
データも32ビット整数で間に合います。
そのころのMacで32ビット以上のデータを扱うのは煩雑で処理時間もかかりました。
そのために、MiniCADでは基本となる座標データも32ビット整数にしてしまいました。
建築用CADとしては、9桁の精度があれば必要十分ということもあったでしょう。
オプション扱いのFPU(もう若い人には通じないかも)を駆使してもMPUの整数演算にはかないません。
32ビット整数という制限も仕方がなかったと思われます。
さて、
32ビット整数では0〜4,294,967,295秒までを表せます。これは約49710日、136年ちょっとです。
Macの内部時計は1904/1/1からの秒数をカウントしていたので、VWでも当然それに合わせています。
そういうわけで、VWのワークシートで扱える日付の範囲は1904/1/1 0:00:00〜2040/2/6 6:28:15に
なってしまいました。
今でもそのままなのはどうかと思いますが、たぶん誰も使ってないので問題ないのでしょう。
32ビット整数と連呼してるのに、セルの値は実数じゃないかと言われるかも知れませんが、
そのへんのカラクリは判りません。
単純に86400で割って日単位の実数値にした方が扱いやすいんだと思います。(Excelもそうだし)
今でもシステムルーチンを使ってるわけもないだろうし。
石男様
回答ありがとうございます。
SDKの情報をネットで検索していますが、英語の情報しかないようですね。
あまり時間もないのですが、取り合えずVC++で開発してみます。
今後もよろしくお願いします。
テキストファイルを取り出すような細かい設定は出来ませんが、次のようなやり方は
出来ます。
DoMenuTextByName('Export Image File',0 );
これで、イメージファイルの取り出しは出来ます。
>SDKを使っての開発になるのでしょうか?
はい、その通りです。資料はほぼ100%英語です。サポートもありませんので、素人の方に
はまずは無理かと思われます。
初めまして。
最近VectorWorks2009でスクリプトを書き始めました。
環境:
WindowsXP+SP3
VectorWorks2009
作図した画像を、ビットマップファイルとして取り出すスクリプトを書きたいのですが、テキストファイル以外にはできないように思えますが、本当にできないのでしょうか?
またスクリプトで実現できない機能は、SDKを使っての開発になるのでしょうか?
どうぞお知恵を貸して下さい。
(2日前の続き)
単にiの値を1つ増やすなら、CやJavaでは
i++;
と書けますが、VectorScript(Pascal)で
PostInc(i);
と書くとエラーになります。
VectorScriptでは関数の戻り値を無視することは出来ないので、
変数:= PostInc(i);
のように書かないといけません。ダミー変数を使うくらいなら、素直に
i:= i + 1;
と書いたほうがましでしょうか。
こういう場合はfunctionでなくprocedureにします。procedureには戻り値はありません。
procedure Inc(var i:integer);
begin
__i:= i + 1;
end;{Inc}
呼び出し側は、
Inc(i);
となります。
結局、VectorScriptでインクリメントを使いたければ、
procedure Inc(var i:integer);
function PostInc(var i:integer):integer;
function PreInc(var i:integer):integer;
の3つのサブルーチンを使い分けることになります。
また、変数を参照する都合から、変数型が違えば別のサブルーチンが必要です。
インクリメントは整数以外には使わないので、integer型とlongint型があればいいでしょう。
名前の最後に変数型の頭文字を付けて区別することにします。
つまり、インクリメントには下の6つのサブルーチンが必要です。
procedure IncI(var i:integer);
procedure IncL(var i:longint);
function PostIncI(var i:integer):integer;
function PostIncL(var i:longint):longint;
function PreIncI(var i:integer):integer;
function PreIncL(var i:longint):longint;
i++ があれば当然 i-- や --i もあります。
こちらはデクリメントと呼びます。
同じように6つのサブルーチンが必要です。
procedure DecI(var i:integer);
procedure DecL(var i:longint);
function PostDecI(var i:integer):integer;
function PostDecL(var i:longint):longint;
function PreDecI(var i:integer):integer;
function PreDecL(var i:longint):longint;
プログラム(スクリプト)ではループ内でインデックス変数を+1して様々な処理を行うことが多いのですが、
VectorScript(Pascal)だと
j:= j + 1;
Message(j);
のように2つの文を書かないといけません。
CやJavaだと、
Message(++j);
のように1つの文で済みます。
Message(j);
j:= j + 1;
なら、
Message(j++);
と書きます。
++はインクリメント演算子で、++jをプリ・インクリメント、j++をポスト・インクリメントと呼びます。
Messageを呼ぶ前にjを+1するのがプリ・インクリメント、あとで+1するのがポスト・インクリメントです。
どちらの言語でも、機械語やアセンブラのレベルでは
Inc j
Push j
Call Message
のようになるので実行速度やプログラムサイズには違いはありませんが、
元が教育用プログラミング言語だけあってPascalのほうが処理の順番は明確です。
後から出来たCやJavaでは簡潔な書き方が可能になっていますが、
メリットは命令が1行で済むとか、タイピング量が少ないことではなくて、
Pascalではjが3個もあるのに、CやJavaのような書き方だと1個で済むことです。
jを別の名前に変える場合、3箇所変えるより1箇所のほうが変え忘れなどのミスは少ないでしょう。
というわけで、Pascal(VectorScript)でも同じようなことが可能かどうかやってみましょう。
例として、下の簡単なスクリプトを改造してみます。
procedure test1;
{$DEBUG}
var
__i, j, k__:integer;
begin
__j:= 0; k:= 0;
__for i:= 1 to 5 do begin
____j:= j + 1;
____Message(j, ', ', k);
____k:= k + 1;
__end;
end;
Run(test1);
ループ内の
j:= j + 1;
Message(j, ', ', k);
k:= k + 1;
の3行を Message(++j, ', ', k++); のようにしたいのですが、Pascalにはインクリメント演算子はありません。
仕方がないので関数でやってみます。
procedure test2;
{$DEBUG}
var
__i, j, k__:integer;
function PreInc(var i:integer):integer;
begin
__i:= i + 1;
__PreInc:= i;
end;{PreInc}
function PostInc(var i:integer):integer;
begin
__PostInc:= i;
__i:= i + 1;
end;{PostInc}
begin{main}
__j:= 0; k:= 0;
__for i:= 1 to 5 do begin
____Message(PreInc(j), ', ', PostInc(k));
__end;
end;{main}
Run(test2);
元よりかなり長くなりましたが、ループ内は1行に収めることが出来ました。
GetObject('プラグインツールの名前')で返ってくるハンドルは、レコードを指しています。
この図形に属さないレコードがプラグインツールのデフォルトパラメータです。
もちろんSetRFieldで値を書き換えることも出来ます。
プラグインメニューやツールで計算作業を行うとき、初期設定値をファイルに残したいのです。
プラグインオブジェクトでは、オブジェクト自身のハンドルとパラメーターを使用して
SerRfieldでパラメーターの値を書き換えることは可能なのですが、
ツールやメニューは自身のハンドルを持たないので、パラメーターの内容を変更することができません。
何かよい方法は有りませんか?
>>Tabを特定することが出来ません。
>とは、表示するタブをスクリプトで変更するということでせうか?
はい、例えばTab1のアイテムによってTab3の表示するアイテムを変えられるのかと...
結局のところ、SwapControlを併せて使わないと出来ないということが分かりました。
もっとも、他に方法があるかもしれませんが...。
私自身はダイアログはめったに作らないので、タブコントロールもはじめて触ったのですが、
タブは意識せずにアイテムのみに注目すればいいような感じです。
あるアイテムでイベントが発生したら、そのアイテムの属するタブが表示されてるはずなので、
あえてタブを特定する必要はないと思いますが...
>Tabを特定することが出来ません。
とは、表示するタブをスクリプトで変更するということでせうか?
モダンダイアログにタブを付けられるようになって久しいですが、今回初めて挑戦してお
ります。そこで、Tab1、Tab2、Tab3と作ってTab毎の命令を書いていきたいのですが、
Tabを特定することが出来ません。どのようにしたら、良いのか分かる方がいましたら
お教えください。
続きを書いてくださっても、もちろん構いません。
もし、談話室の不具合などありましたら、管理人までご一報下さい。