JP2000090144A - 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法 - Google Patents

薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法

Info

Publication number
JP2000090144A
JP2000090144A JP11273474A JP27347499A JP2000090144A JP 2000090144 A JP2000090144 A JP 2000090144A JP 11273474 A JP11273474 A JP 11273474A JP 27347499 A JP27347499 A JP 27347499A JP 2000090144 A JP2000090144 A JP 2000090144A
Authority
JP
Japan
Prior art keywords
bending
screen
information
image
dimensional
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Granted
Application number
JP11273474A
Other languages
English (en)
Other versions
JP2000090144A5 (ja
JP3884195B2 (ja
Inventor
Hazama Kensuke
ハザマ ケンスケ
Kalev Kask
カスク カレブ
Satoshi Sakai
サカイ サトシ
Anand Hariharan Subbaraman
ハリハラン サバラマン アーナンド
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Amada Metrecs Co Ltd
Original Assignee
Amada Metrecs Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Amada Metrecs Co Ltd filed Critical Amada Metrecs Co Ltd
Publication of JP2000090144A publication Critical patent/JP2000090144A/ja
Publication of JP2000090144A5 publication Critical patent/JP2000090144A5/ja
Application granted granted Critical
Publication of JP3884195B2 publication Critical patent/JP3884195B2/ja
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y02TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
    • Y02PCLIMATE CHANGE MITIGATION TECHNOLOGIES IN THE PRODUCTION OR PROCESSING OF GOODS
    • Y02P90/00Enabling technologies with a potential contribution to greenhouse gas [GHG] emissions mitigation
    • Y02P90/02Total factory control, e.g. smart factories, flexible manufacturing systems [FMS] or integrated manufacturing systems [IMS]
    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y02TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
    • Y02PCLIMATE CHANGE MITIGATION TECHNOLOGIES IN THE PRODUCTION OR PROCESSING OF GOODS
    • Y02P90/00Enabling technologies with a potential contribution to greenhouse gas [GHG] emissions mitigation
    • Y02P90/30Computing systems specially adapted for manufacturing

Landscapes

  • Bending Of Plates, Rods, And Pipes (AREA)
  • Management, Administration, Business Operations System, And Electronic Commerce (AREA)
  • General Factory Administration (AREA)
  • Control By Computers (AREA)
  • Information Retrieval, Db Structures And Fs Structures Therefor (AREA)

Abstract

(57)【要約】 曲げ板金要素の如き、要素の生産を容易にするために、
工場を通して設計及び製造情報を管理し分配するための
装置及び装置が提供される。此の発明の側面によれば、
重要な設計及び製造情報は、各作業に付随する設計及び
製造情報を格納し分配することにより達成される。従来
の紙作業セットアップ及び作業シートを、例えば、工場
の何れの場所からも瞬時にアクセスされる電子的格納作
業シートで置き換えることにより、此の発明は工場の全
体的効率を改良する。さらに、此の発明の種々の側面及
び特徴により、パーツ情報およびエキスパート知識の組
織化及びアクセス可能性が改良される。

Description

【発明の詳細な説明】
【0001】関連出願データ 本出願は1996年5月6日出願の「薄板金属製作設備全体に
亘って設計製作情報を管理し分配する装置と方法」と題
したU.S.仮出願No. 60/016,948に準拠し、その明細書を
全般的に参照する事によって本明細書に明白にとりいれ
ていることを主張する。
【0002】著作権についての注意書き 本特許文書の明細書の一部は、著作権保護の対象になっ
ている。著作権保有者はU.S.特許・商標局の特許フアイ
ルや記録に記載されている特許明細書の何人かによる複
写には異議を申し立てないが、それ以外のものについて
は著作権保有者は著作権すべてを保留する。
【0003】発明の背景 発明の分野 本発明は一般的に、製造分野及び薄板金属部品のような
部品の製作に関するものである。特に、本発明は曲げ薄
板金属部品の製作を容易にするために設計・製作情報を
工場全体にわたって管理・分配する装置と方法に関する
ものである。
【0004】背景情報 伝統的に、たとえば薄板金属の進歩的な製造設備での曲
げ薄板金属の製作は、連続的な製作製造段階を含む。第
一段階は設計段階で、そこでは顧客の仕様にもとづいて
薄板金属部品の設計が行われる。通例顧客は特定の薄板
金属部品の設備での製作を注文する。顧客の注文は通
例、部品を工場で製造するのに必要な製品と設計の情報
を含んでいる。この情報は、たとえば部品の幾何学的寸
法、部品に必要な材料(たとえば鋼鉄、ステインレス
鋼、またはアルミニウム)、特殊な成形の情報、分量、
引き渡し年月日等を含むことがある。客先から要請され
た薄板金属部品は広範囲の種類の応用に設計・製作する
ことが出来る。たとえば、製作された部品は最終的には
コンピュータのケース、配電盤、航空機の肘掛け、また
は自動車のドアのパネルに使われるかもしれない。設計
段階では、薄板金属部品の設計は、適当なコンピュータ
支援設計(CAD)システムによって製造設備の設計部で
なされる。顧客の仕様に応じて、プログラマーがCADシ
ステムを用いて薄板金属部品の2次元(2ーD)モデルを作
成することもできる。通例、客先は部品の重要な幾何学
的寸法を含む青写真を提供する。この青写真は、部品に
含まれる特別の成形や記号、または薄板金属部品の表面
の孔や他の開口を示すこともある。設計プログラマーは
CADシステムで2ーDモデルを作成するため、この青写真を
度々用いる。この2ーDモデルはまた、薄板金属部品の曲
げ線及び/または寸法情報を含む平面図と、一つまたは
一つ以上の透視図を含むこともある。
【0005】実際に薄板金属部品の曲げ加工を開始する
前に、先ず原材料から部品を打ち抜き切断するか/また
は切断しなければならない。在庫材料の処理に当たっ
て、打ち抜きプレスやプラズマまたはレーザー切断機を
制御作動するのに、普通コンピュータ数値制御(CNC)
または数値制御(NC)が用いられる。この在庫材料の処
理を容易にするため、設計プログラマーは、コンピュー
タ支援製造(CAM)システムまたはCAD/CAM システムを
用いて2ーDモデルにもとづいた制御コードを作成するこ
とが出来る。この制御コードには、打ち抜きプレス及び
/または切断機にとりいれて、在庫材料からの薄板金属
部品の打ち抜き、または切断に利用できる部品プログラ
ムが含められていることもある。
【0006】製造プロセスの次の段階は曲げ加工計画段
階である.この段階で、曲げ加工計画が作業場で曲げ加
工オペレータによって立てられる。オペレータには通常
切断または打ち抜かれた一つまたは一つ以上の在庫材料
とともに、部品の青写真または2ーD図面が渡される。こ
れらの材料で曲げ加工オペレータは使用する工具と実施
される曲げの手順を定める曲げ加工計画を立てる。曲げ
作業場には、オペレータがデータを入力した曲げコー
ド、または曲げ計画にもとづいたプログラムが作成でき
るCNCプレスブレーキのようなCNC金属曲げ機も含まれ
る。
【0007】曲げ加工計画が作成されると、オペレータ
は曲げ加工の順序の初期テストのための作業場を設置す
る。このテスト段階では、打ち抜きまたは切断された材
料はプレスブレーキに手で組み込まれ、プレスブレーキ
はプログラムされた順序に従って製作品に曲げを加工す
るように操作される。オペレータは出来上がった曲げ薄
板金属部品を分析して顧客の仕様に適合しているかどう
かを検査する。このプレスブレーキの初期作業の結果に
よって、オペレータは曲げプログラムを編集し、曲げ順
序を修正することもある。オペレータはまた、薄板金属
部品の設計が適当に修正出来るように、設計部に結果を
フイードバックすることもある。テストは通常曲げ薄板
金属部品が要求されている設計仕様内におさまるまで続
けて行われる。
【0008】製作プロセスの最後の段階の一つは曲げ段
階である。曲げ計画が作成され、テストされた後、曲げ
オペレータは曲げ加工場に必要な工具を装備し、曲げ計
画と記憶されている曲げプログラムまたはコードに従っ
てプレスブレーキを作動する。曲げ加工場に必要な量の
打ち抜きまたは切断された材料が確保されるように、ま
た他の作業が指定された引き渡し年月日までに完了して
いるように、作業日程も作成される。作業日程は製作過
程の初期段階と/または全過程に平行して作業場監督に
よって作成または修正されることもある。最後の曲げ薄
板金属部品の製作が完了すると、顧客への引き渡しのた
めに部品は集められ、梱包される。
【0009】通常の製作、製造過程は幾つかの欠点や不
利な点がある。たとえば、各々顧客の設計製造データは
通常物理的に(たとえば紙によってフアイルキャビネッ
トに)、電子的に(たとえばデイスクまたは磁気テープ
に)保管されるが、こうしたデータは普通別々に保管さ
れていて検索するのが容易でない。さらに、多くの工場
環境では、重要な仕事情報の分配は工場全体にわたって
配布される仕事または企画用紙の形をとる。その結果、
データがしばしば紛失または損傷し、以前または類似の
仕事に関する設計製造データを検索するのが困難にな
る。加うるに、データの保管方法の不備によって、設計
製造情報を全工場の作業場やその他の場所に配布するの
に貴重な時間が失われる。また部品の設計や曲げ計画の
作成は、主として設計プログラマーと曲げオペレータに
よって行われ、個人の知識、手腕と経験によるところが
大きいので、薄板金属部品と曲げ計画の作成の間に製造
時間がかなり失われる。
【0010】近年、慣習的な薄板金属製造過程を改善
し、過程全体にわたる効率を改善するための開発と試み
がなされてきた。たとえば、市販のCAD/CAMシステムに
おける2次元(2-D)および3次元(3-D)モデル作成の使
用と開発によって曲げ薄板金属の製作過程とモデル作成
を促進され、改善された。今では設計プログラマーやオ
ペレーターは2ーD及び3ーD表示を用いて、部品の形状をよ
りよく理解し、部品設計と曲げコードの順序をより効率
的’に作成出来るようになっている。データを電子的に
記憶し、トランスフアーする機能は、設計部から作業場
への情報の流れを改善した。コンピュータとデータ通信
ネットワークの進歩により、最早古い紙テープや磁気デ
イスクをキャビネットまたはフアイルから探し出すこと
が不要になった。
【0011】こうした進歩があるにもかかわらず、組織
と工場環境全体にわたる設計と製造情報の組織化と流れ
を改善する必要がまだある。たとえば、在来の製造シス
テムでは、各顧客の注文の重要な設計及び製造情報が、
工場のどの場所でも容易にアクセスでき、検索できるよ
うな論理的関係づけがなされていない。今までのシステ
ムはまた、薄板金属部品の特徴や特質のような、色々な
特色にもとづいた仕事情報を探索する機能をもたない。
たとえば同一または類似の部品の探索にもとづいた、以
前の仕事情報が探索でき、検索出来ることは、全体的な
製作プロセスを大幅に増強し、将来の仕事の必要製造時
間を短縮する。
【0012】過去の試みはまた、設計プログラマーや作
業場オペレータによる薄板金属部品の設計を容易にする
ことに欠けている。2ーDや3ーDモデリング・システムによ
って、設計者は部品の形状や幾何学をよりよく理解出来
るようになったが、このシステムによって設計プログラ
マーや作業場オペレータに科せられた負担は軽減されて
いない。たとえば、これらのシステムによって設計プロ
グラマーが現存の2ーDCADモデルを簡単に3ーD表示に変換
することはできない。また作業場オペレータに曲げ加工
計画を立てる助けとなる部品の2ーD及び/また3-D図面が
提供されても、オペレータは必要な工具や曲げ手順を手
で/または試行によって決めなければならない。
【0013】発明の要約 上記に照らして、本発明は、発明の一つまたは一つ以上
の見地、実施例及び/または特色あ、るいはサブコンポ
ーネントを通して、以下にに特記する一つまたは一つ以
上の目的と利点をもたらすために供するものである。
【0014】本発明の一般的な目的は、曲げ薄板金属部
品のような部品の製作を促進するために、設計と製造情
報を全工場に亘って管理し、分配する装置と方法の提供
である。
【0015】さらに本発明の目的としては、たとえば進
歩的な薄板金属製作設備における重要な仕事情報の紛失
または破壊を防止し、専門的知識の蓄積の有効活用と整
理を助長する装置と方法の提供がある。
【0016】もう一つの本発明の目的は、各顧客の注文
の設計と製造情報の双方を、論理的に記憶する装置と方
法を備えることによって、工場のどの場所でも容易にア
クセスでき、検索できるようにすることにある。
【0017】さらにもう一つの本発明の目的は、仕事デ
ータが中央のデータベースまたはフアイルサーバーに、
全工場のどの場所でも容易に探索し、検索できるよう論
理的に記憶されている設計と製造情報を管理し、分配す
る装置と方法の提供にある。仕事データは仕事に関連し
た設計と製造情報ばかりでなく、必要な曲げ操作を遂行
するための実際の曲げコードも提供できる。
【0018】またさらに本発明の目的は、色々な探索基
準にもとづいた、設計と製造情報を含む以前の仕事情報
を探索する装置と方法の提供である。探索基準は、たと
えばこれから製造される薄板金属部品の特色や特徴を含
むことができ、これによって同一または類似の部品に関
連した以前の仕事情報を、将来の仕事の全体的な製造時
間の短縮に利用できる。
【0019】本発明のもう一つの目的は、各顧客の注文
に関連した従来の書類仕事または企画用紙を、工場の何
処からでも瞬間的にアクセスできる電子的ジョッブシー
トに置き換えることである。電子的なジョッブシートは
どの場所でも表示でき、部品の2ーD及び/または3-Dモデ
ル像、工具の選択、最適曲げ手順、必要なステイジング
情報やバーコードまたは認識番号を含む、仕事に関連し
た重要な設計と製造情報を含む。この電子的ジョッブシ
ートには、曲げオペレータによって将来再び同じ、また
は類似の仕事を行うときに役立つと思われる、特別の指
図または手順を録音録画したオーデイオ及び/またはビ
デオ部品も備えられる。
【0020】本発明のもう一つの目的は薄板金属部品の
2ーDと3-Dコンピュータ画像を提供することによって部品
図面の解析に要する時間を短縮する事にある。固体3ーD
画像モード、3ーDワイヤフレーム画像モード、2-D平面画
像モード及び正射画像モードを含む、色々な画像が提供
できる。薄板金属部品の解析に役立つズーミング、パン
ニング、回転及び自動寸法入れを含む色々な異なる画像
機能も備えられる。
【0021】さらに本発明は設計者の薄板金属部品の設
計と曲げ計画の製作を容易にする装置と方法を提供する
目的を持つ。たとえば、現存する部品の2ーDモデルから
部品の3ーD表示を容易に製作することができるようにす
るのも本発明の目的である。さらにもう一つの本発明の
目的として、曲げ計画とプログラムされた曲げコードを
作成する時間を短縮するためのグラフィックスインター
フエイスの提供がある。
【0022】上記に鑑みてこの発明は設備において製造
されるべきパーツ(例えば板金パーツ)を表現するため
にコンピュータ可読媒体に格納されたオブジェクト指向
ベンドモデルに向けられる。このオブジェクト指向ベン
ドモデルは、前記パーツの特徴に関連するパーツ情報及
びこのパーツになされる曲げ操作に関連する曲げ情報を
有する複数のオブジェクトを含むパーツクラスを備え
る。前記パーツ情報は、パーツの設計及び製造情報を含
む。前記パーツ設計情報は2次元及び3次元座標空間に
おける前記パーツの表現に関連する。更に、前記曲げ情
報は、前記パーツの曲げ線において曲げ操作を行なうた
めの曲げデータ及び命令を備えた一群のオブジェクトを
有する。曲げデータは、曲げ角度量及び曲げ半径量を含
む。
【0023】この発明の1つの側面によれば、前記パー
ツクラスは前記曲げ操作が前記パーツになされるところ
の順番に関連する曲げシーケンス情報を備える属性を含
む。前記属性はパーツ材質タイプ及びパーツ厚さを備え
る。更に上記複数のオブジェクトは、面オブジェクトを
備え、この面オブジェクトは、前記パーツの各面の寸法
に関連する設計データ及び少なくとも1つの座標空間内
における前記パーツの各面の表現に関連する1データを
含む。前記複数のオブジェクトは更に、曲げ線オブジェ
クトを含む。前記曲げ線オブジェクトは前記パーツの各
曲げ線の寸法に関連する設計データ及び少なくとも1つ
の所定の座標空間内での前記パーツの各曲げ線の表現に
関連する1データを含む。前記曲げ線オブジェクトは更
に、前記パーツになされる曲げ操作に関連する曲げ製造
データを含む。前記曲げ製造データは、前記パーツの各
曲げ線についての部位幅データ及び曲げピッチ及び配向
データを含む。
【0024】前記曲げモデルの複数のオブジェクトはま
た穴オブジェクト及び成形オブジェクトを含む。この穴
オブジェクトは、前記パーツにおける少なくとも1つの
穴の寸法に関連する設計データ及び少なくとも1つの所
定の座標空間内での前記パーツの各穴の表現に関連する
1データとを含む。前記成形オブジェクトは、前記パー
ツの各々の成形部の寸法に関連する設計データ及び少な
くとも1つの座標空間内における前記パーツの各成形部
の表現に関連する1データとを含む。トポロジーオブジ
ェクトと曲げ特性オブジェクトが更に設けてある。前記
トポロジーオブジェクトは、前記パーツの特徴に関連す
るパーツトポロジーデータを含み、前記パーツの特徴
は、前記パーツの面または穴または成形部または曲げ線
の少なくとも1つを含む。更に前記曲げ特性オブジェク
トは、前記パーツに関連する製造拘束データを含む。こ
の発明はまた製造設備において製造されるべき板金パー
ツを表現するための、コンピュータ可読媒体に格納され
たオブジェクト指向曲げモデルに向けられる。前記オブ
ジェクト指向モデルは、複数のパーツ特性を有するパー
ツオブジェクトと2次元座標空間及び3次元座標空間に
おいて板金パーツを表現するための複数のオブジェクト
を含むパーツクラスを備える。前記複数のオブジェクト
は、前記板金パーツの特徴に関連する設計情報及び前記
板金パーツに少なくとも1つの曲げ操作を行なうための
曲げ情報を含む。前記パーツの特徴は、面及び穴及び成
形部及びまたは曲げ線を含み、前記複数のオブジェクト
は、面オブジェクト及び穴オブジェクト及び成形オブジ
ェクト及びまたは曲げ線オブジェクトを備える。
【0025】前記曲げ情報は、前記板金パーツになされ
る複数の曲げ操作に関連する。前記曲げ情報は、前記板
金パーツに少なくとも1つの曲げ操作を行なうための曲
げデータ及び命令を備えた一群のオブジェクトを備え
る。前記曲げデータは、例えば、曲げ角度量及び曲げ半
径量を含む。更に前記曲げ属性は、前記曲げ操作が前記
板金パーツに対してなされる順番に関連する曲げシーケ
ンス情報を備える。前記パーツ属性はまた、パーツ材料
タイプ及びパーツ厚さを備える。
【0026】この発明の他の側面によれば、コンピュー
タ制御システムにおいて用いられるように構成されたオ
ブジェクト指向曲げモデルビューアが提供される。前記
コンピュータ制御システムは、前記パーツに関連する曲
げモデルデータを格納するデータベースと前記パーツの
画像を表示するための表示装置とを含む。前記オブジェ
クト指向曲げモデルビューアは、曲げモデルビューア観
察クラスを備え、この曲げモデルビューア観察クラス
は、観察モデル属性と前記ベンドモデルビューア観察ク
ラスの要素機能として実行される少なくとも1つの観察
機能とを含む。前記パーツの少なくとも1つの画像が、
前記曲げモデルデータ及び観察モデル属性とに基づい
て、前記コンピュータ制御システムの表示装置上に表示
される。
【0027】種々の追加的特徴が、この発明のオブジェ
クト指向曲げモデルビューアに設けてある。例えば、前
記観察モデル属性は所定の観察モード或いは複数のモー
ドに関連する表示情報を備え、前記所定の観察モード或
いは複数の観察モードは実線観察モードまたはワイヤフ
レーム観察モード、2次元平面図モード、及びまたは斜
視図モードを含む。前記曲げモデルビューア観察クラス
はまた、1つまたはそれ以上の観察機能に応じて前記パ
ーツの画像を修正するための情報を含む。前記観察機能
は、例えば、ズーミング機能または回転機能またはタン
ニング機能及びまたは寸法付け機能を含む。前記ズーミ
ング機能は、表示装置上で前記パーツの画像をズームす
るための操作を含み、前記回転機能は前記パーツの画像
を回転するための操作を含む。前記タンニング機能は、
前記表示装置上で前記パーツの画像をタンニングする操
作を含み、前記寸法機能は、前記パーツの少なくとも1
つの特徴に関連する寸法情報を追加的に表示するために
前記パーツの画像を修正する操作を含む。前記寸法情報
は、前記パーツの少なくとも1つの曲げ線の長さまたは
前記パーツの各曲げ線の曲げ角度及びまたは前記パーツ
の少なくとも1つのフランジ部の長さを含む。
【0028】前記オブジェクト指向曲げモデルビューア
は、前記パーツの画像の現在表示されている姿に基づい
て前記表示装置上において観察可能な前記パーツの特徴
に関連する観察可能性情報を維持し提供するための観察
可能性機能を有する。前記曲げモデルビューア観察クラ
スは、少なくとも1つの観察機能に応じてパーツの画像
を修正するための情報を含む。前記観察機能は、観察可
能性情報に基づいて前記パーツの画像を修正しパーツの
観察可能な特徴に関連する寸法情報を表現するための操
作を含む寸法機能を備える。更にオブジェクト指向曲げ
モデルビューアは、前記表示装置上のパーツの画像の現
在表示されている姿のズーム係数に関連するズーム係数
情報を含む。
【0029】本発明の更に他の側面によれば、パーツの
表示されている画像を操作するためのシステムが提供さ
れる。前記パーツの表示されているイメージは3次元座
標空間においてスクリーン上に表示される。このシステ
ムは以下を含む。指令信号を生成するための入力装置
(例えばジョイスティック装置或いはマウス装置)ここ
に前記指令信号は前記パーツの表示されている画像を修
正するように構成された少なくとも1つの所定の観察機
能に関連する。表示されている画像の現在の姿を決定す
るための現在姿決定システム。表示されているイメージ
の現在の姿に基づいて前記パーツの回転軸を動力学的に
設定するための設定システム。前記観察機能に応じて、
前記指令信号及び回転軸に基づいて前記パーツの表示さ
れている画像を修正するための画像修正システム。
【0030】所定の観察機能は、回転機能を備え、前記
画像修正システムは前記指令信号に基づいて前記回転軸
を中心としてパーツの表示されている画像を回転するよ
うに構成されている。更に現在姿決定システムは、パー
ツの表示されている画像の現在の姿がパーツの全体の姿
であるか或いはパーツの部分的姿であるかを決定するよ
うに構成されている。前記設定システムは、前記現在姿
決定システムが前記パーツの表示されているイメージの
現在の姿は全体の姿であると決定する時、前記パーツの
幾何学的中心を前記パーツの回転軸が通るように設定す
るように構成されている。更に前記設定システムは、前
記現在姿決定システムがパーツの表示されている現在の
姿が部分的姿であると決定する時、前記パーツの回転軸
が前記スクリーンのセンターを通るように設定するよう
に構成されている。
【0031】前記システムには他の特徴が設けてある。
例えばパーツ観察可能システムが設けてあり、それは現
在の姿に基づいてパーツの一部がスクリーンの中心に観
察可能であるか否かを決定する。その場合には、前記パ
ーツ観察可能性システムが前記パーツの前記一部が観察
可能であると決定する時前記回転軸が前記スクリーンの
中心における前記パーツの前記一部を通るように設定す
るように構成されている。更に前記設定システムは、前
記パーツ観察可能性システムが前記パーツの前記部分が
スクリーンの中心において観察可能ではないと決定する
時、前記パーツの幾何学的中心のZ座標軸における前記
スクリーンの中心を前記回転軸が通るように設定するよ
うに構成されている。
【0032】前記現在姿決定システムがパーツの表示さ
れている画像の現在の姿は部分的姿であると決定する
時、前記スクリーンの中心に位置し且つ前記スクリーン
のカメラ視野に最も近い前記パーツの部分を特定するた
めのシステムが設けてある。前記パーツの特定された部
分が前記パーツの開口部に対応するかどうかを決定する
ためのオブジェクト検出システムがまた設けてある。こ
のオブジェクト検出システムが、パーツの特定された部
分はパーツの開口部に関係しないと決定する時、前記計
算システムは、前記回転軸が前記パーツの前記特定され
た部分を通るように設定するように構成されている。更
に前記オブジェクト検出システムが前記パーツの特定さ
れた部分が当該パーツの開口部に関連すると決定する
時、前記パーツの幾何学的中心のZ座標に対応する深さ
において前記スクリーンの中心を前記回転軸が設定され
るように前記設定システムは構成されている。
【0033】前記入力装置はジョイスティック装置及び
またはマウス装置を備えている。前記ジョイスティック
装置は、ジョイスティック仮想空間を含み、当該装置か
らの指令信号は前記ジョイスティック仮想空間内での前
記ジョイスティック装置の移動に関連する情報を含む。
前記画像修正システムは、前記ジョイスティック仮想空
間内でのジョイスティック装置の移動をスクリーンのス
クリーン空間内での仮想の移動に写像するための写像シ
ステムを有する。従って、前記画像修正システムはジョ
イスティック移動から写像されたカーソルの移動に基づ
いて前記パーツの表示された画像を修正する。前記写像
システムは、前記ジョイスティック仮想空間の寸法に対
する前記スクリーン空間の寸法の比率に基づいて、前記
ジョイスティック装置の移動を前記スクリーン空間内で
のカーソルの移動へ写像するように構成されている。例
えば前記カーソルの移動は以下の式に基づいて前記写像
システムにより写像される。
【0034】 現在位置=従前位置+(スケール係数×V) ここに現在位置はスクリーン空間内でのカーソルの現在
の位置であり、従前位置は前記スクリーン空間内でのカ
ーソルの従前の位置であり、スケール係数はジョイステ
ィック仮想空間の寸法に対するスクリーン空間の寸法の
比率であり、Vは前記ジョイスティック仮想空間内での
ジョイスティック原点からジョイスティック現在位置へ
のジョイスティック装置の移動及び方向に関連するベク
トルである。
【0035】この発明の他の特徴によれば、前記写像シ
ステムは、前記写像システムにより必要されるスケール
係数を調整するためのスケール調整システムを備える。
このスケール調整システムは、前記スクリーン空間の寸
法の前記ジョイスティック仮想空間の寸法に対する比率
に所定の調整係数を掛け合わせ調整されたスケール係数
を提供するように構成されている。前記写像システムは
前記ジョイスティック運動を写像する際にこの調整され
たスケール係数を用いるように構成されている。非限定
的な事例として、3という調整係数が使用される。
【0036】この発明はまたパーツの表示された画像を
操作する方法を含む。ここに前記パーツの前記表示され
た画像は3次元座標空間においてスクリーン上に表示さ
れる。前記方法は以下の工程を含む。入力装置から生成
された指令信号を受け取る工程。ここに前記指令信号は
前記パーツの表示された画像を修正するように構成され
た少なくとも1つの所定の観察機能に関連する。スクリ
ーン上においてパーツの表示された画像の現在の姿を決
定する工程。前記パーツの現在の姿に基づいて前記パー
ツの回転軸を動力学的に設定する工程。前記観察機能に
応じて、前記指令信号及び回転軸に基づいて前記パーツ
の表示された画像を修正する工程。
【0037】この発明の上記した方法によれば、前記所
定の観察機能は、回転機能を備え、これにより前記パー
ツの表示された画像は指令信号に基づいて前記回転軸を
中心として回転される。更に前記設定の工程は、前記パ
ーツの表示された画像の現在の姿が全体の姿であると決
定される時、前記パーツの幾何学的中心を前記パーツの
回転軸が通るように設定する操作を含む。前記設定の工
程はまた、前記パーツの表示された画像の現在の姿が部
分的な姿であると決定される時、前記パーツの回転軸が
前記スクリーンの中心を通るように設定する操作を含
む。
【0038】この発明の他の側面によれば、パーツの画
像と共に寸法情報をスクリーン上に表示するシステム及
び方法が提供される。前記方法は以下の工程を含む。前
記パーツの表示された画像の現在の姿を決定し且つ前記
現在の姿に基づいてスクリーン上で複数の特徴のうちの
いずれが観察可能であるかを決定する工程。前記パーツ
の表示された画像と共にスクリーン上に、スクリーン上
で観察可能であると決定されたパーツの特徴の各々につ
いてのみの寸法情報を選択的に表示する工程。前記方法
は更に、前記パーツに関連する曲げモデルデータにアク
セスし、この曲げモデルデータに基づいて前記パーツの
特徴の各々についての寸法情報を表示するためのスクリ
ーン上の全ての可能な位置を決定する。更に、前記選択
的に表示する工程は所定のヒューリスティックを適用
し、前記可能な位置に基づいて前記観察可能な特徴の寸
法情報を表示する場所を決定する。前記ヒューリスティ
ックは、前記パーツの表示された画像の外側に存在する
スクリーン上の位置に前記寸法情報を表示する動作と観
察者の観察点に近い方のスクリーン上の位置に前記寸法
情報を表示する動作と及びまたはスクリーン上で寸法情
報が重なり合わないように前記寸法情報を表示する動作
を備える。
【0039】表示される前記寸法情報は、前記パーツの
各曲げ線についての曲げ長さ及び曲げ角度を備える。前
記寸法情報はまた、前記パーツの各曲げ線に関連する内
側曲げ半径及び曲げ縮小量を含む。ここに前記表示の工
程は、前記現在姿に基づいて観察可能であると決定され
る前記パーツの各曲げ線についての曲げ線長さ、曲げ角
度、曲げ半径及びまたは曲げ縮小量を表示する。前記パ
ーツの各フランジ部のフランジ長さのような他の寸法情
報も表示される。追加の情報例えばパーツの幅及び深さ
及び高さも表示される。
【0040】選択的に表示する工程は、パーツの所定の
特徴のみの寸法情報を表示するための自動寸法付け操作
を行なうことを含む。従って観察可能であると決定され
る所定の特徴のみについて寸法情報が表示される。更に
前記選択的表示の工程は、パーツの特徴に関連するユー
ザにより選択された寸法情報を表示するためのマニュア
ル寸法付け操作を実行することを含む。従ってユーザに
選択された寸法情報の各々は観察可能であると決定され
るパーツの特徴についてのみ表示される。スクリーン上
に表示されたパーツの画像と共に寸法情報を表示するシ
ステムも提供される。このシステムはパーツの表示され
た画像の現在の姿を決定し且つ現在の姿に基づいて複数
の特徴のうちのいずれがスクリーン上で観察可能である
かを決定するためのシステムと前記パーツの表示された
イメージと共にスクリーン上に、スクリーン上で観察可
能であると決定されたパーツの特徴のみについて寸法情
報を選択的に表示するシステムとを含む。
【0041】パーツに関連する曲げモデルデータにアク
セスするためのアクセスシステムのみならずこの曲げモ
デルデータに基づいてパーツの複数の特徴の各々につい
ての寸法情報を表示するためのスクリーン上の全ての可
能な位置を決定するためのシステムが設けてある。前記
選択的表示システムは、所定のヒューリスティックを適
用し前記可能な位置に基づいて観察可能な特徴の寸法情
報を表示すべき場所を決定するためのシステムを含む。
表示される前記寸法情報は、前記現在姿に基づいて観察
可能であると判断される前記パーツの各曲げ線について
の曲げ線長さ、曲げ角度、曲げ半径及びまたは曲げ縮小
量を含む。他の寸法情報、例えばパーツの各フランジ部
のフランジ長さはまた表示される。追加の情報例えばパ
ーツの幅及び深さ及び高さもこの発明によれば表示され
る。
【0042】上記の特徴に加えて、さらに特徴と/また
はその変形を設けることができる、たとえば、発明を上
述した特徴の色々な組み合わせ、または再組み合わせ及
び/または下記の詳細な記述にある幾つかの特徴の組み
合わせとの再組み合わせに適用させることができる。
【0043】上に列記したものや他の本発明の対象物、
特徴及び利点については、この後により詳細に記述す
る。
【0044】付録の要約 本発明の詳細な記述をさらに促進するため、付記の限定
されない本発明の望ましい実施例の例に沿っての発明の
色々な特徴、操作及び機能に関するソースコードの例や
コメントを記した、以下の多数の付録を参照する: 付録の要約 本発明の詳細な記述をさらに促進するため、付記の限定
されない本発明の望ましい実施例の例に沿っての発明の
色々な特徴、操作及び機能に関するソースコードの例や
コメントを記した、以下の多数の付録を参照する:付録
Aはたとえば一つの類似部品を探索するときの特徴抽出
演算実行の典型的なソースコードであり;付録Bはたと
えば本発明の幾つかの類似部品の探索時に類似指数演算
を行使する典型的なソースコードであり;付録Cはこの
発明で曲げ線検出操作を行う典型的なソースコードであ
り;付録Dは本発明の2-Dクリーンアップを実行するため
の典型的なソースコードであり、これによって薄板金属
部品の3-Dモデルを元の3方向からの2-D図面にもとづい
て作成するのに使用出来;付録Eは本発明の曲げモデル
ビューアーに色々なビュー モードや機能を実行するた
めの典型的ソースコードであり;付録F,G,HとIは本発明
の自動寸法入れ特性を実行するための典型的なソースコ
ードとコメントであり;付録Jは本発明の曲げモデルビ
ューアーの、部品・エンテイテイの観察可能性機能を実
行するための典型的なソースコードであり;付録Kは曲
げモデルの実施と部品構造の構成に関する、本発明の色
々な教訓をふまえた一般的なコメントを含み、付録Lは
与えられた部品の回転軸の動的計算による3-D操作とナ
ビゲーションシステムを実行する典型的なソースコード
である。
【0045】本発明はこの後の詳細記述で限定されない
本発明の望ましい実施例の例についての多数の図面を参
照しながら記述されており、記述の中の同じ参照番号は
全図面中の類似の部品を示す。
【0046】詳細な説明 本発明の見地に沿って、全工場に亘って設計製造情報を
管理分配し、工場内での部品の製造を促進するための装
置と方法が具備される。この本発明の特徴は広範囲の工
場環境や装置に利用することができ、特にこの発明は一
続きの製作製造段階が異なる場所で行われる工場環境の
充足に利用できる。限定されない実施例や種々の例を通
じて、本発明を、たとえば進歩的な薄板金属製造設備に
おける曲げ薄板金属部品の製作を参照しながら記述す
る。
【0047】図1に、本発明の実施例に従って、進歩的
な薄板金属製造設備38一般が、ブロック線図で図示され
ている。図1に示すように、薄板金属製造設備または工
場38は全工場に分散している多数の場所10,12,14...20
をもつ。
【0048】これらの場所には設計事務所10、出荷作業
場14、打ち抜き作業場16、曲げ作業場18及び溶接作業場
20が含まれる。図1に画かれている薄板金属工場38には
分離した場所が六つしかないが、勿論工場は六つ以上の
分離した場所をもちうるし、また図1に画かれている各
タイプの事務所または作業場は一つ以上の場所を占める
こともある。たとえば設備38の大きさと製産必要容量に
より、一つ以上の打ち抜き作業場16、曲げ作業場18と/
または溶接作業場20を設けることができる。さらに工場
38は一つ以上の設計事務所10、組立作業場12または出荷
作業場14をもちうるし、曲げ薄板金属部品の製作製造を
促進するための他のタイプの場所をもちうる。
【0049】工場38内の各場所10,12,14...20は部品の
製作製造に伴う一つまたは一つ以上の別個の製作製造段
階や処理に対応し、実行する用具を備えている。たとえ
ば、設計事務所10は顧客の仕様にもとづいた薄板金属部
品の設計を促進するために、適当なキャド/キャム(CA
D/CAM)システムをもちうる。このCAD/CAMシステムには
一つまたは一つ以上のパソコンとデイスプレイ、プリン
ター及び市販のCAD/CAMソフトウエアーを含みうる。限
定されない例として、設計事務所10のCAD/CAMシステム
はオートキャドまたはキャドキー、またはアマダ・アメ
リカ 社(以前はU.S.アマダ株式会社の社名で営業)ビ
ユエナ パーク、カリフオルニアから入手できる アマ
ダAP40またはAP60 CAD/CAMシステムを含みうる。さら
に、ベールムのようなアシュラー社から入手できるウイ
ンドウズにもとづいたCADシステムも使用できる。このC
AD/CAMシステムを用いて設計プログラマーは客先の注文
にある図面やデータにもとづいて薄板金属部品の2-Dモ
デルと/または3-Dモデルを作成できる。設計プログラマ
ーはまた薄板金属部品の設計にもとづいた制御コードを
作成し、これによってたとえば被加工材から薄板金属部
品を打ち抜きまたは切断するための、CNC打ち抜きプレ
スと/または切断機を制御する部品プログラムが作成で
きる。
【0050】打ち抜き作業場16と曲げ作業場18は各々CN
C及び/またはNC機械工具のどのような組み合わせでも備
えられる。たとえば打ち抜き作業場16は、コマ・シリー
ズ及び/またはペガ・シリーズのアマダ・タレット打ち
抜きプレス、あるいは他の市販されているCNC及び/また
はNC打ち抜きプレス一つまたは一つ以上もつことがで
き、また曲げ作業場18は、RGシリーズ アマダ・プレス
ブレーキまたは他の市販されている多軸ゲージング・プ
レスブレーキのようなCNC及び/またはNCプレスブレーキ
を一つまたは一つ以上もつことができる。さらに溶接作
業場20は、薄板金属部品に対して必要な如何なる溶接を
も果たすために適当な溶接機器を備えることができる。
打ち抜き作業場16、曲げ作業場18と溶接作業場20は設備
38の工場内のどの場所にも設置出来、熟練オペレータ
(たとえば打ち抜きプレスオペレータ、曲げ機オペレー
タ等)によって手動で動かすことができる機械も備えて
いる。アマダ セルロボミニやアマダ プロムキャムの
ような全自動またはロボット支援機械もこれらの場所に
備えることができる。必要な打ち抜きと曲げの作業、あ
るいは必要な如何なる溶接作業もこれらの作業場で製作
過程中に行うことができる。
【0051】さらに図1に示すように、進歩的な薄板金
属設備38は組立作業場12と出荷作業場14も含む。組立作
業場12と出荷作業場14には、顧客への製造部品の組立と
出荷を促進するために必要な梱包、ルート割り当て及び
/または輸送機器も含まれる。部品の組立と出荷は工場
職員によって手動で行使または管理されるが、機械自動
化及び/または機械支援にすることもできる。さらに組
立作業場12と出荷作業場14は、物理的に工場作業場(た
とえば打ち抜き作業場16、曲げ作業場18及び/または
‘溶接作業場20に近接した)に近い場所に置くか、また
は薄板金属工場38とは別の設備または区域に置くことが
できる。本発明の見地に沿って、重要な設計と製造情報
の管理と分配は、設計と製造情報を電子的に記憶し、分
配することによって行われる。伝統的な紙上の仕事の段
取りまたはワークシートを、工場のどの場所からでも瞬
時的にアクセスできる電子的なジョッブシートに置き換
え、または補足することによって、本発明は工場の全体
的な効率を改善することができる。加えて、本発明の色
々な側面や特徴によって、記憶された設計製造情報の編
成とアクセスが改善される。さらに類似または同一の薄
板金属部品に関する以前の仕事情報のアクセスや検索
が、この発明の色々な特徴を通じて出来るようになって
いる。
【0052】この目的のため、本発明の色々な側面は、
サーバーモジュール32とデータベース30を薄板金属設備
38内の多数の場所10,12,14...20各々と結ぶ通信ネット
ワーク26を設けることによって実行される。このあと論
ずるように、各場所10,12,14...20は通信ネットワーク2
6とデータベース30にインターフエイスするステーショ
ンモジュールをもつ。図1、2と3に発明のこれらの特
色と実装の限定されない例を示す。
【0053】図1と2に示すように、通信ネットワーク2
6は設備38の色々な場所10,12,14...20の各々とサーバー
モジュール32とデータベース30を結んでいる。通信ネッ
トワーク26はデータや情報を場所10,12,14...20とサー
バーモジュール32とデータベース30間で伝送できるもの
であれば、どのようなネットワークでもよい。伝送は電
子的または光学的に、無線周波数伝送または遠赤外伝送
によって行われる。限定されない例として、通信ネット
ワーク26は、ローカルエリアネットワーク(LAN)、エ
ーテルネットまたは同様のネットワーク構造で構成出来
る。後でさらに述べるように、場所10,12,14...20の各
々はまた、通信ネットワーク26を通じて情報を伝送し、
受信するためネットワーク終端接続装置(たとえばコン
ピュータ、ミニコンピュータまたはワークステイショ
ン)及び/または周辺機器(たとえばデイスプレイモニ
ターまたは画面、プリンター、CD-ROM、及び/またはモ
デム)をもつことができる。ネットワーク終端接続装置
と周辺機器は通信ネットワーク26とインターフエイスす
るためと、あとで詳しく論ずるよに、本発明の色々な特
徴と側面を備えるためのハードウエアと適当なソフトウ
エアまたはプログラム論理を含む。工場内の場所にコン
ピュータを設置する場合のコンピュータは独立型、パソ
コンまたはその場所にある装備や機械類のインターフエ
イス装置の一部である汎用コンピュータであってもよ
い。たとえば、コンピュータはIBM互換性パソコンまた
はアマダAMNCのような機械類のインターフエイス/制御
システムの一部であるコンピュータであってもよい。
【0054】サーバーモジュール32とデータベース30も
通信ネットワークにつながれている。サーバーモジュー
ル32は、通信ネットワーク26とインターフエイスするの
に適したハードウエアとソフトウエアをもつパソコン、
ミニコンまたはミニフレームを含む。 サーバーモジュ
ール32はまた、あとで詳細に期述する、この発明の色々
な特徴を満たすソフトウエアやフアームウエアも含めら
れる。さらに本発明の見地に沿って、サーバーモジュー
ル32は顧客の注文に関連する設計製造情報を記憶するた
めのデータベース30をもちうる。データベース30は十分
な記憶容量をもつ市販のデータベースを備えることによ
り、工場の顧客の設計製造情報やその他のデータ、表、
及び/またはプログラムを記憶しておくことができる。
たとえば、データベース30に4GBまたはそれ以上の記憶
容量をもつスカジー(SCSI)メモリー・デイスクを含め
ることができる。データベース30に記憶された設計製造
情報をアクセスして、通信ネットワーク26を通じて薄板
金属設備38の色々な場所10,12,14...20に分配すること
ができる。構造的問い合わせ言語(SQL)のような、色々
なデータフオーマットがデータベース30にデータをアク
セスまたは記憶させるために使用されることができる。
さらに、データベース30に記憶されている情報は色々な
種類の記憶媒体、たとえば磁気テープ、光学デイスクあ
るいはフロッピーデでバックアップし、記憶しておくこ
とができる。サーバーモジュール32とデータベース30の
通信ネットワーク26との連結は、工場38内の別々の区域
または場所で(たとえば図1参照)、あるいは予め定め
られたステイションの中で(たとえば設計事務所内)、
またはこれに近接した場所で行うことができる。図1の
実施例では、データベース30がサーバーモジュール32の
一部で通信ネットワーク26とサーバーモジュールを通し
てインタフエースしているように画かれているが、デー
タベース30は勿論サーバーモジュール32と物理的に離れ
た場所に置かれていて、図2に示すように通信ネットワ
ーク26とネットワークデータベースモジュール34を介し
てつなぐことができる。
【0055】本発明の望ましい実施例に沿った限定され
ない例として、サーバーモジュール32と各場所10,12,1
4...20は100-200MHzの、ペンテイアムまたは同等のマイ
クロプロセッサーを含む中央処理装置(CPU)と、少なく
とも32MBの記憶容量と市販の800×600分解能をもつSVGA
モニターのような高分解能デイスプレースクリーンをも
つ、IBM互換機のようなパソコンを含む。サーバーモジ
ュール32と場所10,12,14...20にはまた、情報のデイス
プレイとのインターフエスと制御のための、ジョイステ
イックまたはマウスとサウンド・ブラスターまたはそれ
に代わる音響とゲームポートアダプターカードが含まれ
る。通信を支援するための実行システムのソフトウエア
も備えられる。たとえば、サーバーモジュール32はマイ
クロソフトウィンドウズニューテクノロジー(NT)また
はウインドウズ95実行システムソフトウエア(両方とも
マイクロソフト社、レッドモンド、ワシントン州から入
手できる)を備え、また各場所10,12,14...20はマイク
ロソフトウインドウズ95実行システムソフトウエアを含
められる。さらにサーバーモジュール32と場所10,12,1
4...20は多数の言語(たとえば英語、日本語等)の支援
に対応でき、またOLE2サーバーのようなオブジェクトリ
ンクと埋め込み(OLE)サーバーの全面的な支援を具備
できる。
【0056】色々なデータベース言語と管理システムは
またデータベースに記憶された情報を創りだしたり、保
持したり見たりすることに用いられる。構造的問い合わ
せ言語(SQL)のようなデータベース言語をデータベー
ス30のデータを確定したり、操作したり、制御したりす
るのに用いることができる。たとえば、SQLサーバー
(マイクロソフト社から入手できる小売り製品)は本発
明の実施に利用できる。さらに、この発明は開放データ
ベース連結オープン・データベース・コネクテイビテイ
ー(ODBC)互換ドライバーを備えることによって通信ネ
ットワーク26を通してのデータベース30からの情報のア
クセスを促進できる。ODBCに関するより詳しい情報はマ
イクロソフトオープン・データベース。コネクテイビテ
イー・ソフトウエア開発キットプログラマー用レフアラ
ンス・マニュエルでえられる。
【0057】図2は本発明の別の実施例に従って建設さ
れた進歩的な薄板金属製造設備のブロック線図である。
図2の実施例では、データベース30とサーバーモジュー
ル32は別々に設置されており、データベース30はネット
ワークデータベースモジュール34を介して通信ネットワ
ーク26につながれている。上記のように、本発明はこの
構成に限定されたものではなく、データベース30とサー
バーモジュール32は一緒に設置でき(たとえば図1に示
すように)、ネットワークデータベースモジュール34の
データベースにアクセスする機能をサーバーモジュール
に取り入れることができる。図2はまた、薄板金属製造
設備38内の色々な場所10,12,14...20に設置できるステ
イションモジュール36の例を示す。図示の目的で、図2
には曲げステイション18に設置されたステイションモジ
ュール36が例示されている。図2の例には示されていな
いが、同様のステーションモジュール36を設備38内の他
の場所にも設置できる。
【0058】図2に示すように、各モジュール(サーバ
ーモジュール32、ネットワークデータベースモジュール
34及びステイションモジュール36)はネットワークイン
ターフエイスカードまたはポート42を介して通信ネット
ワーク26につなぐことができる。ネットワークインター
フエイスカード26はベンダー専用で、選ばれた通信ネッ
トワークの形式にもとづいて選択できる。 各モジュー
ル32、34、36は通信ネットワーク26とインターフエイス
するためのネットワークソフトウエアまたはプログラム
された論理を含むことができる。 通信ネットワーク26
はイーサネット(Ethernet)で、10ベース/T(ツイスト
対)、10ベース/2(同軸)、または10ベース/5(厚膜ケ
ーブル)のような多くのタイプの市販ケーブルから設備
38の大きさと必要なケーブル長さにもとづいて選んだタ
イプのケーブルを用いたものであってもよい。
【0059】図2でサーバモジュール32はデイスプレイ
モニターまたはCRT44とキーボード、マウス及び/または
ジョイステイックを含む入力/出力デバイスをもつパソ
コンを含めうる。ネットワークインターフエスカード42
は備えられている拡張スロットまたはパソコン40のポー
トに挿入できる。さらに、パソコン40は100-200MHzの処
理速度とペンテイアムまたはペンテイアム・プロ マイ
クロプロセッサーを含むことができる。パソコン40はま
た、たとえば32MBまたはそれ以上の主記憶装置と1.2GB
またはそれ以上のランダムアクセス記憶装置(RAM)を
含むことができる。デイスプレイ44は高解像度の表示画
面、たとえば800×600の解像度をもつ市販のSVGAモニタ
ーを含むことができる。デイスプレイ44に表示された色
々なグラフ一クスや情報を支援するため、パソコン40は
また、PCIグラフイックス・カードのような市販のグラフ
イックスクス・カードを含むことができる。さらに、コ
ンピュータ40はサウンド・ブラスター、または互換の音
声及びゲームポートアダプターカードを含み、入力/出
力装置46はキーボード、ジョイステイックと/またはマ
ウスを含むことができる。
【0060】この発明の色々な特徴を実行するために、
サーバーモジュール32にはソフトウエアや色々なパッケ
ージソフトが備えられている。たとえば、サーバーモジ
ュール32はマイクロソフト ウインドウズ NT(ワーク
ステーション型)またはウインドウズ95を備えてい
る。さらに、サーバーモジュールにこの発明特有の機能
と特徴(たとえば図4を見よ)を持たせるために、サー
バーモジュール32はソフトウエアまたはプログラムされ
た論理を備えたルーチンを含ませることができる。後で
より詳しく論ずるように、これらのルーチンは、C++の
ような高レベルのプログラム言語とオブジェクト指向プ
ログラミングによって作成できる。サーバーモジュール
32はまた、顧客の仕様にもとづいた2-D及び3-D図面を入
力及び/または作成するために、ベルムまたはアマダAP4
0またはAP60ソフトウエアのようなCADまたはCAD/CAMソ
フトウエアを含むか、インタフエースできるようになっ
ている。この理由で、サーバーモジュールは製造設備38
の設計事務所10におくことができる。データベース30か
らデータをアクセスするために、サーバーモジュール32
は、マイクロソフトODBドライバーのようなODBCドライ
バーをもち、またSQLをデータ アクセスの標準に用い
ることができる。OLE2サーバーのようなOLEサーバー
を、データをリンクするために備えることができる。
【0061】図2の実施例では、データベース30はサー
バーモジュール32から分離して備えられており、ネット
ワーク データベース モジュール34を経由して通信ネ
ットワーク26につなげられている。先に述べたように、
データベース30は工場38の規模と、データベースに記憶
させる部品情報の量にもとづいて選ばれた、適当な記憶
スペースをもったSCSIデイスク(たとえば1-4 GB)を含
むことができる。ネットワーク データベース モジュ
ール34は、ペンテイウム マイクロプロセッサーを備え
たIBM互換機のようなパソコン40と、通信ネットワーク2
6とインターフェースするためのネットワーク インタ
ーフエース カード42を備えた拡張スロットを含むこと
ができる。データベース30はデータ母線を介してパソコ
ン40に連結でき、パソコン40は標準的なデイスプレイや
デイスプレイ モニターまたはCRTとキーボードのよう
な入力/出力デバイス(図2には示されていない)も含
む。
【0062】SQLに基づいたデータベース30へのアクセ
スを容易にするため、ネットワークデータベース モジ
ュール 34のパソコン40は、 マイクロソフトSQLサー
バーやオラクルSQLサーバーのような、市販のSQLサーバ
ーと合わせて設置することができる。OLE2サーバーのよ
うなOLEサーバーをデータをリンクするために備えてお
くことができる。パソコン40もDOSやマイクロソフト・
ウインドウズNT(サーバー バージョン)のような、色
々なソフトウエアを備えておくことができる。図2の実
施例は一つのステーションモジュール36の典型的な実装
例を含んでいる。この実施例では、ステーションモジュ
ール36は、曲げステーション18に装備されている。図2
に示すように、ステーションモジュール36はサーバーモ
ジュール32と同様のハードウエアを含んでいる。つま
り、各ステーションモジュール(たとえば図1に示す他
のステーション)はデイスプレイ モニターまたはCRT4
4と、ジョイステイックまたはマウスを含む入力/出力デ
バイス46をもつコンピュータ48を備えている。ネットワ
ーク・インターフエイス・カード42はコンピュータ40に
備えられている拡張スロットまたはポートに差し込むこ
とができる。前に論じたように、ステーションモジュー
ル36のコンピュータは 独立型、またはパソコン、また
はその場所に備えられた装置または機械類のインターフ
エイス ・デバイスの一部である汎用コンピュータであ
ってもよい。たとえば、コンピュータ48は、100-200 M
Hzの動作速度とペンテイウムまたはペンテイウム プロ
マイクロプロセッサーをもつIBM互換機のような自立型
パソコンであってもよいし、コンピュータ48はアマダAM
NCシステムのような機械類のインターフエイス/制御シ
ステムの一部、あるいはシステムに組み込まれたコンピ
ュータであってもよい。コンピュータ48はまた、たとえ
ば32MBまたはそれ以上の主記憶と、1.2GBまたはすれ以
上のランダム・アクセス記憶(RAM)を保有することが
できる。デイスプレイ44は高解像度デイスプレイ画面、
市販のたとえば解像度800×600をもつSVGAモニターを含
みうる。デイスプレイ44にデイスプレイされる色々なグ
ラフイックスや情報を支援するために、コンピュータ48
はPCIグラフイックス・カードのような市販のグラフイ
ックス・カードを備えることができる。さらに、コンピ
ュータ48はサウンド・ブラスター、または互換できる音
響及びゲームポート・アダプターとそれを支援する入力
/出力デバイス46のジョイステイックまたはマウスを含
むことができる。
【0063】この発明の色々な特徴を実行するために、
ステイション・モジュール36はソフトウエアといろいろ
な市販ソフトウエアが配置されている。たとえば、ステ
ーション・モジュール36はマイクロソフト・ウインドウ
ズ95またはウインドウズNT(ワークステーション版)の
ような基本ソフトが備えられている。さらに、ステーシ
ョン・モジュールに、この発明固有の機能と特徴をもた
せるために(たとえば図5を見よ)、ステーション・モ
ジュール36にソフトウエアまたはプログラム化論理装備
ルチーンが備えられる。後でより詳しく論ずるように、
これらのルチーンは高レベルのプログラム言語、たとえ
ばC++、及びオブジェクト指向プログラミング技術を用
いることによって開発できる。データをアクセスし、リ
ンクするために、ステーション・モジュール36はマイク
ロシフトOBCDドライバーとOLE2サーバーのようなOLEサ
ーバーが含まれている。サーバー・モジュール32と同
様、ステーション・モジュールもSQLをデータベース30
からデータをアクセスする基準に用いることができる。
【0064】曲げステーション18のステーション・モジ
ュール36が自立型パソコンとして備えられている場合、
曲げコードデータを作成するためと曲げ機械類25(たと
えばCNCまたはNC制御プレス・ブレーキ)とインターフ
エースするためのソフトウエアを装備できる。図2の実
施例では、コンピュータ36はパソコンとして装備され、
標準RS-232-C配線インターフエースを通じて曲げ機械25
とインターフエースするソフトウエアを配備しているよ
うに画かれている。このインターフエースはステーショ
ン・モジュール36が、RS-232-Cインターフエースを通じ
て曲げ機械25と通信し、曲げコードを送受できるために
装備されている。このインターフエースの実行はベンダ
ー用であり、曲げ機械25に用いられるデータ書式と命令
セットに依存する。ステーション・モジュール36から曲
げ機械25に送られるすべてのデータは、機械に決められ
ている機械命令セットにもとづいてフオーマットしたも
のでなければならない。ステーション・モジュール36の
コンピュータ48は、曲げコード生成のため、市販で入手
できるCNCまたはNCソフトウエアを備えることにより、
このような機械類のためにCNCまたはNCシステム(たと
えばアマダAMNC)の組み込みコンピュータに通常備わっ
ている機能をシミュレートできる。
【0065】図3はデータのサーバー・モジュール32、
データベース30と薄板金属製造設備38の間のそれぞれの
データの流れを示す実施例の典型である。図で表すため
と実施例におけるそれぞれのデータの流れの記述を容易
にするため、図3ではサーバー・モジュール32とデータ
ベース30(ネットワーク・データベース・モジュール34
に統合されている)は、各々別々に通信ネットワーク26
と直接に接続されていて、これらの構成要素間のデータ
の流れは通信ネットワークを通して行われる。勿論、こ
の技術に熟練した人なら分かるように、これら構成要素
間には多種多様のデータの流れ方式を用いることができ
る;また、データベース30がサーバー・モジュール32に
直接接続されている場合、データと情報はサーバー・モ
ジュールからデータベースに直接に、通信ネットワーク
26を用いることなく伝達できる。さらに、記述を容易に
するため、図3の通信ネットワーク26は簡略化されてお
り、図には打ち抜きステーション16と曲げステーション
18しか示されていない。しかしながら、場所10,12,1
4...20(工場内の他のあらゆる場所や区域も含めて)か
らのデータのやりとりの流れは、打ち抜きステーション
16と曲げステーション18について示したのと同様の方法
で行うことができる。
【0066】各顧客の注文に関連した設計製造情報は、
編成してデータベース30に記憶することができる。最初
に顧客から注文を受けると、基本的な製品と設計情報が
サーバー・モジュール32に入力され、それからデータベ
ース30に伝送され、記憶される。前に論じたように、サ
ーバー・モジュール32は、キーボードを備えたパソコン
等のような、データを入力する適当な手段を備えてい
る。サーバー・モジュール32でパソコンが用いられると
き、工場職員によるデータの入力を容易にするため、メ
ニュー方式画面を生成するソフトウエアを備えることが
できる。データ入力プログラムは、たとえばマイクロソ
フト・ウインドウズをベースとしたアプリケーション
で、ヘルプ及び/またはメニュー画面をもつものであっ
てよい。限定されない例として、サーバー・モジュール
32に入力され/または作成されて、データベース30に転
送されたデータは、図3に一般的に示してあるように、
部品情報、曲げモデル、特徴抽出データ及び曲げ線情報
を含むことができる。
【0067】部品情報は、たとえば部品または注文参照
番号、顧客の名前、部品の簡単な説明、バッチの大きさ
または量及び引き渡し予定日を含むことができる。曲げ
モデルデータは、たとえば部品の全体的な寸法(たとえ
ば幅、高さ、深さ)と材料のタイプ(たとえば鋼鉄、ス
テインレス鋼またはアルミニウム)、厚さ及び引っ張り
強さのような部品材料の情報を含むことができる。さら
に、特徴抽出データは手動による入力と/または自動的
に生成することによって、部品の主要な特徴を識別し、
データベースの類似部品の探索やその他の探索を容易に
する。特徴抽出データはデータベース30の別のフアイル
に格納するか、曲げモデルデータや各部品の仕事情報と
一緒に格納することができる。特徴抽出データは、たと
えば表面や面の数、曲げタイプの数(たとえば二面間の
正の折り曲げ、または二面間の負の折り曲げ)、面の間
の関係及び/または部品にある孔や他のタイプの開口の
数を含むことができる。後でより詳しく論ずるように、
このようなデータは特徴ベース部品マトリクスと/また
は逐次探索キー(たとえば下記の図6-10を見よ)に
よって表現し、編成できる。最後に、曲げ線情報はデー
タベース30に格納するため、サーバー・モジュール32に
入力できる。曲げ線情報は、たとえば部品の各折り曲げ
の曲げ角度、曲げ長さ、曲げの内半径(IR)、縮小量及
び曲げ方向(たとえば前方または後方)を含む主要な曲
げ線情報を含む。
【0068】通信ネットワーク26を通じてデータベース
30へデータを送受信するため、各場所10,12,14...20は
通信ネットワークに接続されているステーション・モジ
ュール(前に述べたステーション・モジュール36のよう
な)を含めることができる。図3には、打ち抜きステー
ション16と曲げステーション18は一般的にステーション
・モジュールと合わせたブロック線図で示されている。
前に論じたように、ステーション・モジュールは、たと
えばソフトウエア、または制御論理と独立型パソコン、
またはその場所に備えられた装置または機械類の一部で
ある汎用コンピュータを含む。各顧客の注文に応じて、
設計製造情報(部品情報、曲げ線情報および曲げモデル
・データを含む)が、所定参照番号またはコードを入力
することによってアクセスでき、検索できる。参照番号
またはコードは手動(たとえばキーボードまたはデジタ
ル入力パッドによって)またはバー・コードを、ステー
ション・モジュールに備えられているバー・コード読み
とり装置またはスキャナーでスキャンすることによって
入力できる。さらに、本発明の見地に沿って、以前の仕
事情報はデータベース30から、工場内のどの場所10,12,
14...20からでも、同様の部品探索を行うことによって
アクセスし、検索できる。引き続く詳しい記述で論ずる
ように、類似部品の探索は、特徴抽出データ、またはデ
ータベース30に記憶されている探索キーにもとづいて行
うことができ、これによって同一または類似の部品に関
する以前の仕事情報が検索され、将来の仕事の全体的な
製造時間の短縮に利用できる。
【0069】データベース30から検索された製造情報
は、作業場オペレータが曲げ計画を作成し、テストする
のに用いられる。たとえば、曲げステーション18の曲げ
オペレータは、薄板金属部品に必要な工具や最適な曲げ
手順を決めるために、データベース30から部品情報、曲
げ線情報や曲げモデル・データをアクセスし、検索する
ことができる。本発明の見地に沿って、ODBCドライバー
を備えることにより、各ステーション・モジュールがデ
ータベース30とインターフエースし、データベースに記
憶されている情報を表示できるようにすることができ
る。さらに、サーバー・モジュール32またはデータベー
ス30のネットワーク・データベース・モジュールは、デ
ータベースに記憶されているデータのアクセスと検索を
容易にするために、SQLサーバーを含むことができる。
最終曲げ計画に基づいて曲げコードがプログラムされる
と、曲げコードは曲げ手順とともに、図3に一般的に示
すように通信ネットワーク30を通じて、曲げステーショ
ンのステーション・モジュール18からデータベース30に
送られる。この情報は、当該の仕事に関連する他の設計
製造情報とともに記憶される。
【0070】他の情報もデータベース30に記憶すること
ができる。たとえば、部品の2-D及び/または3-D画像表
現は曲げモデルデータとともに記憶することができる。
この2-Dまたは3-D画像表現は設計ステーション10または
他の場所でCAD/CAMシステムを用いて作成し、設計ステ
ーション(あるいは他の適当な場所)のステーション・
モジュールを介して通信ネットワーク26を通じ、データ
ベース30に転送できる。あるいはまた、2-Dまたは3-D画
像はサーバー・モジュール32で、後でより詳しく述べる
ように、適当なCAD/CAMシステムまたはモデル化ソフト
ウエアを用いて、一連の機能または演算を実行すること
によって作成できる。
【0071】図4と5を参照しながら、サーバー・モジ
ュール32と各場所10,12,14...20においてプログラムさ
れ実行される処理や演算について詳述する。図4と5は
サーバー・モジュール32と薄板金属製造設備38内の各場
所10,12,14...20で実行される基本論理の流れの流れ図
である。図5は、たとえば曲げステーション18で実行さ
れる典型的な処理や操作に対するものであるが、設備38
内の特定な場所で実行される操作によっては、これ以外
の処理やステップも実行できることは理解できよう。以
下に述べる処理や操作はソフトウエア、または多種類の
プログラム作成言語と技法の一つを利用することによっ
て実施できる。たとえば、本発明の見地に沿って、関連
図面を参照しながら記述する下記の処理や操作は、C++
のような高レベルのプログラム作成言語とオブジェクト
指向プログラミング技法を用いることによって実施でき
る。さらに、限定されない例として、ウインドウズ・ベ
ースアプリケーション用にマイクロソフト社が作成し
た、プログラム作成言語のバージョンであるヴイジュア
ルC++を利用することができる。
【0072】図4は本発明の見地に沿って、サーバー・
モジュール 32が行う基本的な処理と操作の流れ図であ
る。図4はサーバー・モジュール32がソフトウエアまた
はプログラム化論理によって実行する処理と操作の基本
論理フローである。サーバー・モジュール32は、オペレ
ータまたはユーザーがサーバー・モジュールの色々な処
理や操作の選択と実行を支援するためにツール・バーや
ヘルプ及び/またはメニュー画面をもつウインドウズ・
ベース アプリケーションを含むことができる。処理は
薄板金属製造設備38で顧客の注文を受けたステップS.1
から開始される。顧客の注文は通常部品が工場で製造す
るのに必要な製品と設計の情報を含む。この情報は、た
とえば部品の幾何学的寸法、部品に必要な材料や他の設
計情報も含む。顧客から受けた情報をもとに、サーバー
・モジュール32は、ステップS.3に画かれているよう
に、データベース30に記憶されている以前の仕事情報の
探索を実行する。データベース30に記憶されている仕事
情報は多様な探索基準にもとづいて探索できる。たとえ
ば、情報は事前定義参照または仕事番号にもとづいて探
索でき、あるいは類似部品の探索は部品のある設計特徴
にもとづいて実行でき、これによって同一または類似の
部品に関する以前の仕事情報が現在の仕事のために検索
でき、利用できる。利用できる類似部品探索のさらに詳
しい記述は、図6-10を参照しながら以下に記す。
【0073】ステップS.5では、データベースの検索結
果が解析され、現在の顧客の注文が新しい部品か、以前
の仕事に類似の部品か、あるいは以前の仕事の繰り返し
かが決定される。同一の照合が見いだされる(たとえば
同じ部品または参照番号が見いだされる)と、顧客の現
在の注文は工場で行った以前の仕事の完全な繰り返しに
なり、仕事情報に対するこれ以上の修正は不必要で、以
前の仕事情報をデータベース30からアクセスしてステッ
プS.11に示すように現在の顧客の注文の遂行に利用でき
る。データベースの探索は以前の仕事の部品または参照
番号及び/またはフアイル名を与え、それによってサー
バー・モジュール32またはどのステーション・モジュー
ルにいるオペレータでもデータベースから仕事情報をア
クセスすることができる。部品または参照番号しかえら
れない場合、変換テーブルを備えることによって、オペ
レータが部品参照または仕事番号を入力することによっ
て以前の仕事情報のフアイル名を決定し、アクセスでき
る。従って、たとえばサーバー・モジュール32にいるオ
ペレータは、仕事情報と2-Dと3-Dモデル化情報をデータ
ベース30からアクセスすることによって部品の幾何学を
解析し、繰り返しの注文と類似であることを確認するこ
とができる。注文が繰り返しの注文であることが確認さ
れると、曲げステーション18のステーション・モジュー
ルにいる曲げオペレータは、さらに以前の仕事情報をア
クセスし、曲げコードのデータと工具段取り情報を含む
製造情報を曲げと部品の製作に利用することができる。
かかる記憶された専門的知識を利用することによって、
このようにして、繰り返しの注文をより効率的に、以前
に入力され開発された仕事情報を必要とせずに製造する
ことを可能にする。
【0074】しかしステップS.5で、もし現在の顧客の
注文が以前の仕事と類似か、以前の仕事と同じである
が、たとえば仕事または参照番号またはバッチの大きさ
等の修正が必要と決定されれば、ステップS.7での探索
で捜し出した以前の仕事情報データはデータベース30か
ら検索され、サーバー・モジュール32にいるオペレータ
によって編集し、修正される。編集機能を備えることに
よって、以前の仕事データを編集し、修正して新しい仕
事データを作成し、現在の顧客の注文のためにデータベ
ース30に格納できる。必要とする編集の量は、以前の仕
事と現在の仕事間の類似性の程度による。編集の量は、
参照または仕事番号またはバッチの大きさの単なる修正
から/または、部品の寸法や定められた曲げ手順の編集
のような、より広範囲な修正を含むものにわたる。以前
の仕事情報の編集が終わると、修正された仕事情報はス
テップS.9でデータベース30に格納される。修正された
仕事情報は新しい参照または仕事番号で格納できる。さ
らに、色々なデータベース管理機能(コーピー、削除、
保管、再命名等)を備えることによって、特別なコマン
ドの入力でデータベース30の以前の仕事情報の保持、ま
たは以前の仕事情報の消去または上書きができる。
【0075】現在の仕事に適合する類似または同一のも
のが無く、従って現在の顧客の注文は新しい仕事に関係
することが決定されると、論理フローは図4に示すステ
ップS.15に進む。この場合、現在の仕事は新しい仕事に
関するものになるので、設計製造情報を独立に作成し、
入力しなければならない。サーバー・モジュール32から
メニュー及び/またはヘルプ画面を提供することによっ
て、オペレータが必要な仕事情報すべてを入力するのを
支援することができる。本発明の見地に沿って、サーバ
ー・モジュール32のオペレータは、最初に新しい仕事の
基本的な部品情報を入力することによって新しいフアイ
ルを作成できる。部品情報は、たとえば参照または仕事
番号、顧客の名前、部品の簡単な記述、仕事に必要なバ
ッチの大きさまたは量及び予定引き渡し年月日を含む。
特徴抽出データまたは探索キーもステップS.15で入力で
きるし、また、以下に記すように、このデータを自動的
に作成するか、曲げモデルデータの作成と同時に抽出す
ることができる。他のデータや情報もステップS.15で入
力するか、部品の各曲げ線の曲げ角度、半径や長さを含
む曲げ線情報のような曲げモデルデータの入力後か入力
中に入力できる。ステップS.15に引き続き、論理フロー
は図4に示すように、オペレータによって曲げモデルデ
ータがサーバー・モジュール32で開発され、入力される
ように進む。
【0076】曲げモデルの開発と入力は、顧客から提供
された原図や情報に依存する。顧客の注文は、たとえば
製造される部品の2-Dの一方向平面図及び/または部品の
2-D、三方向図(たとえば上面、前面、側面図)を含む
かも知れない。たまには顧客は、部品材の厚さが図に示
されている、またはいない部品の3-Dワイヤーフレーム
を提供することもある。本発明の見地に沿って、曲げモ
デルデータは、製造される部品の展開(2-D平面表示)
と折りたたみ(3-D表示)情報を双方とも含む。従って顧
客が2-D平面図しか提供しない場合、たとえば2-D図面に
対して折りたたみアルゴリズムまたは処理を適用するこ
とによって3-D図面を作成する必要がある。これにひき
かえ、部品の3-D図面が提供された場合、3-D図面に対し
て展開アルゴリズムまたはプロセスを適用することによ
って2-D平面図を作成しなければならない。本発明の別
の見地に沿って、曲げモデルに保管されている2-D及び3
-Dモデルは、薄板材料厚さなし(つまり厚さなし)で作
成し表現できる。これが可能なのはすべての薄板金属部
品に特有の対称性による。厚さなしの2-Dと3-D図面の提
供と表現は、設計プログラマー、曲げオペレータや他の
ユーザがより容易に解釈され理解される部品のモデリン
グとシミュレーションの図を与える。厚さ情報を省くこ
とはまた、サーバー・モジュールやステーション・モジ
ュールで、文中に記述の本発明の色々な特徴を実行し達
成するのに要する処理時間を短縮し、改善する。このよ
うな特徴のより詳細な記述や、本発明で利用することが
できる折りたたみと展開アルゴりズムについては、以下
に付図を参照しながら記述する。
【0077】図4は曲げモデルを開発するときに行われ
る一般的な処理と操作を示す。受理した、または顧客の
注文にもとづいて開発され、曲げモデルデータを作成す
るために入力できる色々なタイプの図面は、一般的にス
テップS.19,S.23,S.27とS.31に示されている。 ツール
・アイコン・バーとメニュー及び/またはヘルプ画面
を、サーバー・モジュール32によって、これらの各ステ
ップを選択し実施するオペレータを支援するために提供
できる。これらの図面から曲げモデルのための部品の2-
Dと3-Dモデルを作成する処理は、最初に提供された図面
のタイプに依存する。これらの図面は、サーバー・モジ
ュール32で手動で入力または作成するか、テープまたは
デイスクからダウンロードできる。サーバー・モジュー
ル32は、たとえば、設計事務所10にあるCAD/CAMシステ
ムとインターフエイスするか、またはサーバー・モジュ
ール32が独立型CAD/CAMシステムをもつことができる。
さらに、2-Dと3-D図面は、DXFまたはIGESフアイルとし
て保管され、サーバー・モジュール32に取り入れられ
る。
【0078】一方向平面図が提供された場合は、曲げモ
デルを作成する処理は、図4に示すようにステップS.19
から始められる。ステップS.19で、受理または作成され
た2-D平面図はサーバー・モジュール32に入力される。
部品の全体的な寸法(幅、高さ、深さ)のような他の曲
げモデルデータ及び部品材料情報もステップS.19で入力
できる。その後、折りたたみアルゴリズムまたは処理を
用いて、ステップS.21に一般的に示されているように、
元の2-D一方向図面にもとづいて3-Dモデル(材料の厚さ
のない)を作成することができる。2-D平面図から3-Dモ
デルを作成するのに行われる処理や操作の例は、図11
-18を参照しながら後で述べる。
【0079】部品の3-Dワイヤーフレーム図(材料厚さ
の無い)が受理または作成された場合、図の情報はステ
ップS.27で入力される。さらに、他の曲げモデルデー
タ、たとえば部品の全体的な寸法(幅、高さ、深さ)及
び部品材料情報もステップS.27で入力できる。この後
に、ステップS.27に示すように、部品の2-Dモデルを作
成するために、サーバー・モジュール32で展開のアルゴ
リズムまたは処理が実行される。2-Dモデルを3-D図面
(厚さのない)から作成するために行われる処理と操作
の例は、たとえば図19を参照しながら後で述べる。
【0080】部品の2-Dと3-Dモデル表示は、その部品の
ための曲げモデルの一部として格納される。さらに、前
に注記したように、2-Dと3-Dモデルの作成と格納の間
に、他の曲げモデルデータ(部品材料情報やその他の製
造情報のような)も入力し、曲げモデルデータとともに
データベース30に格納できる。曲げモデルデータを編成
し、格納するために実施できる、いろいろな機能やデー
タ構造配列についてはあとでより詳しく記述する(たと
えば図26と27を見よ)。
【0081】図4に示すように、簡単な3-D図面(材料
厚さなしの)がもともと作成または受理されていない場
合は、最終的な2-Dモデルを作成するのに必要な展開ア
ルゴリズムまたは処理を行う前に、部品の3-Dモデル
(厚さなし)を作成するための付加的な処理が必要とな
る。ステップS.23、S.25、S.31とS.33は、ステップS.29
で展開アルゴリズムを実行し、2-Dモデルを作成する前
に、サーバー・モジュール32で一般に実施される付加的
な処理と操作を示す。
【0082】たとえば、部品の2-D、三方向図面(三面
図)がはじめに提供または作成されている場合、ステッ
プS.23で図面はサーバー・モジュール32に入力または取
り入れることができる。さらに部品の全体的な寸法
(幅、高さ、深さ)のような他の曲げモデルデータや部
品材料情報もS.23で入力できる。引き続きステップS.25
では、入力された2-D三方向図面にもとづいて、部品の
簡単な3-D平面図が作成できる。作成された3-D図面は、
図4に示すように、ステップS.29で2-Dモデルを作成す
るのに用いられる。3-Dモデルを2-D三方向図面から作成
する処理と操作の例は、あとでたとえば図20を参照し
ながら述べる。
【0083】しかしながら、もし材料厚さが入っている
3-D図面がもともと受理または作成されている場合、展
開アルゴリズムを適用する前に、さらに先の処理のため
図面情報をステップS.31で入力する事ができる。他の曲
げモデルデータ、部品の全体的な寸法(幅、高さ、深
さ)と部品材料情報もステップS.31で入力できる。その
あとステップS.33で、3-D図面にある厚さを削除するた
めの厚さ削除手順を行うことができる。本発明の見地に
沿って、サーバー・モジュール32は、オペレータまたは
ユーザーが厚さ削除手順を実行するとき、図面に厚さを
示し、どの表面(外側か内側か)を保存するかを示すよ
うに促すことがある。本発明で利用できる厚さ削除手順
については、たとえば図24(a)と24(b)を参照
しながら下記に述べる。ステップS.33で3-D図面の厚さ
が削除された後、論理の流れはステップS.29に進み、そ
こでは最終的2-Dモデルを作成するために、改訂された
厚さの無い3-Dモデルを利用して適当な展開アルゴリズ
ムまたは処理が施される。3-D図面から2-Dモデル作成す
るための展開処理と色々な処理や操作は、たとえば図1
9を参照しながら下記に述べる。
【0084】図4に示すように、すべての重要な情報が
作成され、入力された後、顧客の注文に関連する部品情
報、曲げモデル情報及びその他のデータは、ステップS.
35でサーバー・モジュール32からデータベース30に移さ
れて格納される。データベース30に格納されたデータ
は、データベース探索を行うときに利用できる特徴抽出
または探索データも含む。下記に述べるように、特徴抽
出または探索データは、各仕事に関連した部品の基本的
または主要な特徴を指示するデータも含まれ、これによ
って仕事情報や格納されている同一または類似部品に関
する専門的知識の探索が実施できる。サーバー・モジュ
ール32に入力されたデータと情報は、たとえば図3に示
すように、直接データベース30に、または通信ネットワ
ーク26を介して転送することができる。上述のように、
曲げモデルデータを作成するときに、色々な図面に対し
て実施できる各種の処理や操作についての詳しい記述
は、下記に付図を参照しながら記す。
【0085】図5は薄板製造設備38の場所10,12,14...2
0に設けられ、各ステーション・モジュールで実施され
る基本的な処理や操作の流れ図を示す。例証のため、図
5は、たとえば曲げステーション18に置かれたステーシ
ョン・モジュールで実施される基本的な処理や操作の基
本論理の流れの例を示す。本発明の教示にもとづく技術
に熟練した者には理解できるように、図5に示す論理の
流れは、各場所で実施される操作や処理の性格により、
各ステーション・モジュールで修正できることは勿論で
ある。さらに、サーバー・モジュール32と同様、下記に
述べるステーション・モジュールでの処理や操作にはソ
フトウエアまたはプログラム化論理を装備できる。加う
るに、ステーション・モジュールは、オペレータまたは
ユーザーによる色々な処理や操作の選択と実施を容易に
するために、ツール・バー・アイコンまたはヘルプ及び
/またはメニュー画面をもつウインドウズ・ベース・ア
プリケーションを含むことができる。このようなヘルプ
及び/またはメニュー画面は、ステーション・モジュー
ルにおいてデータの入力または転送を容易にするために
も設けることができる。
【0086】図5に示すように、ステップS.51でステー
ション・モジュールを初期設定した後、オペレータはス
テップS.53で一つまたは一つ以上のデータベース探索基
準またはキー項目を入力することができる。探索基準
は、データベース30に格納されている以前の仕事情報、
または新しいまたは現在の仕事に関する仕事情報を捜し
出すために入力できる。オペレータは、たとえばデータ
ベース30から特定の仕事情報を検索するために、予め定
められた番号またはコードを入力できる。たとえば、本
発明の見地に沿って、バーコード をルーチングシート
に付すか、せん孔された材料につけて、ステーション・
モジュールでバーコード読みとり装置でスキャンするこ
とによって情報をアクセスすることができる。あるい
は、参照コードまたは番号を、ステーション・モジュー
ルでキーボードまたはデイジタル入力パッドを介して手
動で入力できる。変換テーブルを備えることによって、
部品参照または仕事番号のオペレータによる入力によっ
て、以前の仕事情報を定めることもできる。さらに、探
索基準またはキーを入力することによって、以前に格納
した仕事情報の類似部品探索を行うことも予想される。
このような探索は、部品の色々な設計特性または特徴抽
出データにもとづいて行うことができる。本発明の見地
に沿って実行できる類似部品探索の説明は、下記に図6
-10を参照しながら記す。
【0087】探索基準をステップS.53で入力した後、ス
テーション・モジュールはステップS.55で、通信ネット
ワーク26とネットワーク・データベース・モジュール34
を介してデータベース30の探索を実行できる。探索の結
果はステーション・モジュールに戻され、ステップS.57
でオペレータまたはユーザーが新しい仕事または類似の
以前の仕事に関する情報を要請したのか、または要請が
以前の仕事の完全な繰り返しに関するものなのかを決め
るために解析される。
【0088】同一のものが見いだされる(たとえば同じ
部品または参照番号が突きとめられる)と、以前の仕事
の繰り返しが決定され、仕事に関する格納されている設
計と製造情報がデータベース30からステーション・モジ
ュールに転送され、ステップS.59に一般的に示している
ように、オペレータが見られるように表示される。ステ
ーション・モジュールは一つまたは一つ以上のメニュー
表示画面または登録簿をもち、オペレータがデータベー
ス30から検索された色々な情報を選択し、表示できるよ
うになっている。オペレータは表示された情報をレビュ
ーし、ステップS.61における3-D曲げシミュレーション
のような、色々なシミュレーションを走らせて、その仕
事の曲げ手順の色々な段階を観察し、部品の幾何学を理
解することができる。オペレータはまた、必要工具や仕
事情報に記録されている他の特別な命令やメッセージの
ような他の情報をレビューすることもできる。仕事情報
の確認が終わると、オペレータは曲げ、または他の必要
な機械類を構成し(組立)、機械を操作して指定された
薄板金属部品を製作することができる。データベース30
から検索された仕事情報は、たとえば曲げステーション
18の機械類を制御する曲げコードを含む最終曲げ計画デ
ータを含む。機械類の構成と実際の操作は、このように
して図5のステップS.63に一般的に示してあるように、
オペレータによって遂行される。
【0089】もし同一または類似の仕事情報が捜し出さ
れず、情報が新しい仕事(つまりサーバー・モジュール
32には予備的な仕事情報のみ入力され、完全な仕事情報
が作成されていない)に関するものであることが決定し
た場合、部分的な部品情報と曲げモデルデータはデータ
ベース30から引き出されてステーション・モジュールに
送られ、ステップS.77でオペレータによって観察され
る。要請した情報は新しい仕事に関するものなので、オ
ペレータは必要な工具と曲げ手順を含む曲げ計画を作成
し、入力する必要がある。下記により詳しくのべるよう
に、曲げオペレータによる曲げ計画の作成を容易にする
ため、ステーション・モジュールにグラフイカル・ユー
ザー・インターフエース(GUI)や他の機能を備えるこ
とができる。GUIは、たとえば工具の選択、部品と工具
間の潜在的な不一致の自動点検、及び提案された曲げ手
順の各中間段階のシミュレーションを表示することによ
ってオペレータが曲げ計画を作成するのを支援するため
に設けることができる。サーバー・モジュールで曲げ計
画を作成し、入力したオペレータは、ステップS.80で曲
げコード(曲げ機械で曲げ手順を実行するためのCNCま
たはNCコード)を生成するために曲げ手順をプログラム
する。曲げコードは直接サーバー・モジュールで入力す
るか、曲げ機械類のCNCまたはNC制御装置とインター
フエースしてサーバー・モジュールに取り入れることが
できる。しかる後、オペレータはステップS.81で、曲げ
作業ステーションにおいてセットアップし、曲げ計画を
テストすることができる。曲げ計画に必要なすべてのテ
ストと必要な修正が完了すると、ステップS.83で最終的
な曲げデータをデータベース30に入力し格納する。最終
的な曲げデータは、曲げプログラムとともに、曲げ手順
と工具構成情報を含む。この情報は、たとえば曲げステ
ーション18のステーション・モジュールからデータベー
ス30に送られ、新しい仕事に関する他の設計製造情報と
ともに格納される。
【0090】図5のステップS.57で、情報が以前の仕事
の類似部品または同じ部品に関係しているが、たとえば
異なる参照あるいは仕事番号またはバッチ量等をもつこ
とが決定されれば、論理の流れはステップS.65に進む。
ステップS.65では、以前の仕事情報がデータベース30か
ら検索され、曲げステーション18で表示される。曲げオ
ペレータまたはユーザーはデータを見て、類似部品に必
要なデータの変更が何かを決める。この場合もステーシ
ョン・モジュールは一連のメニュー表示画面または登録
簿(ディレクトリ)を備えて、オペレータが、表示する
情報と、情報をどのように表示または修正するかの選択
ができるようにされている。たとえば、ステップS.69で
は、オペレータの類似部品の曲げ計画の作成を容易にす
るため、検索された情報にもとづいた3-D曲げシミュレ
ーションを備えることができる。以前の仕事情報をレビ
ューした後、オペレータはステップS.70で、曲げプログ
ラムとともに、工具と曲げ情報を修正する。部品の寸
法、参照番号やバッチ量のような他の仕事情報もステッ
プS.70で修正し、編集することができる。これが終わる
と、ステップS.71で実際の工具セットアップとテスト
が、オペレータによって作業場において、修正された曲
げ計画をテストするために行われる。テストと曲げ計画
をさらに修正することが完了すれば、オペレータはステ
ップS.73で最終的な曲げデータを入力し、それに新しい
参照番号または仕事番号をつけてデータベース30に格納
する。上記のように、以前の仕事情報もデータベース30
に、他の格納された仕事フアイルとともに保持できる。
さらに、色々なデータベース管理機能を、データベース
に格納されているフアイルを格納、消去、再命名等する
ために備えることができる。
【0091】次に図6-10を参照しながら、本発明の
教えるところに従って実行できる類似部品探索機能の例
を詳しく述べる。本発明の見地に沿って、特徴ベース形
態類似性探索アルゴリズムを利用する類似部品探索手続
きを、データベース30から以前の仕事情報を探索し、検
索するのに備えることができる。類似部品探索は製作さ
れる部品に関する設計特徴及び/または製造情報にもと
づいた同一及び/または類似部品の探索を含むことがあ
る。また類似部品探索は、たとえばサーバー・モジュー
ル32及び/または工場38内の色々なステーション・モジ
ュールにあるソフトウエアまたはプログラム化論理の使
用によっても実施できる。類似部品探索はサーバー・モ
ジュール32または薄板金属曲げ工場38内の場所10,12,1
4...20のいずれかで実行できる。C++またはマイクロソ
フト社のビジュアルC++プログラム言語のような、高レ
ベルのプログラム言語とオブジェクト指向プログラム技
法が類似部品探索の色々な処理や操作を実施するのに利
用することができる。
【0092】図6と7は利用できる類似部品探索アルゴ
リズムまたは処理の論理の流れを示す。図6に示すよう
に、重要な部品モデルデータフアイルはステップS.100
でアクセスできる。部品モデルには、たとえば設計事務
所10に置かれたCADシステムで作成された曲げモデルデ
ータ及び/またはサーバー・モジュール32で作成され、
入力されたデータが含まれる。部品モデルには、たとえ
ば部品の色々な表面または面及び曲げ線の向き、幾何学
的関係及び相対位置を表す部品形態データ(部品トポロ
ジーデータ)が含まれる。部品モデルデータが検索さ
れ、または曲げモデルデータが手動で入力された後、ス
テップS.102で、当該部品の曲げモデル及び/または部品
形態データにもとづいた特徴抽出データを自動的に導出
するための特徴抽出操作を行うことができる。
【0093】本発明の見地に沿って、特徴抽出データ
は、薄板金属部品の色々な特徴を解析することによって
導出できる。たとえば、部品の色々な面の解析によっ
て、隣り合わせの面が開放または接触コーナーをもつか
どうかを決めることができる。平行曲げ、直列曲げ、共
線曲げまた対向曲げのような他の特徴も、各部品の明確
かつ独特な特徴を決定し、抽出するために解析すること
ができる。
【0094】表1は類似部品探索を行うときに解析され
る色々な曲げと面の特徴を示す。特徴抽出操作に含めな
ければならない抽出特徴は、正の曲げ、負の曲げ特徴と
ともに接触コーナー、開放コーナー特徴である。さらに
特徴抽出操作は、少なくとも平行曲げ、直列曲げ、共線
曲げ、異相共線曲げ及び厚さオフセット曲げの特徴解析
を含まなければならない。
【0095】ステップS.102で行った特徴抽出操作は、
各特徴の曲げモデルデータと形態(トポロジー)の解
析、形態の修正、今後の解析のための形態にもとづく特
徴ベース行列(特徴に基づく行列)の作成からなる一連
の操作を含むこともある。例証のため、図8(a)―9
(d)に接触コーナーをもつ4折り曲げ箱部品と開放コ
ーナーをもつ4折り曲げ箱部品に対する特徴抽出操作を
示す。
【0096】
【表1】 例証のため、図8(a)-9(d)には隣接面のコーナ
ー関係にもとづく特徴抽出が示されている。図8(a)
に示す五つの面(1-5)をもつ閉じた4折り曲げ箱や、図
8(b)に示す五つの面(1-5)をもつ開いた4折り曲げ
箱については、いずれの部品を表すにも、図8(c)に
示す同じ簡単な面形態が提供される。この形態は部品ま
たは曲げモデルデータとともに格納し、提供することが
できる。しかしながら、図8(c)の単純な面形態(面
トポロジー)は、部品の面(1-5)の間の関係の基本的な
情報しか与えず、隣接する面間のコーナーの関係や曲げ
の種類のような部品の色々な特徴の情報は与えない。従
って、特徴抽出操作時に、部品または曲げモデルデータ
とともに格納されている関連面形態をを解析することに
より、基本的な面形態が部品の色々な特徴についての付
加的な情報を含むように修正することができる。
【0097】たとえば、図8(a)の閉じた4折り曲げ
箱の部品または曲げモデルデータを調べることにより、
隣接面間のコーナーが解析でき、図9(a)に示されて
いる修正された面形態が作成でき、これによって各面間
の接触コーナー状況を示すことができる。同様に、図9
(a)に示されている開いた4折り曲げ箱の部品または
曲げモデルデータを調べることにより、図9(b)に示
す修正された面形態を作成し、それによって部品の色々
な隣接する面の間の開放コーナー関係を示すことができ
る。図9(a)と9(b)に示すように、面形態に面の
コーナーの関係(たとえば接触または開放)を示す特別
の連結線を加えることができる。他のデータも他の特徴
(たとえば存在する曲げの形式)を示すため、及び特徴
ベース面形態を作成するために加えることができる。特
徴ベース情報が含められるように形態を修正した後、抽
出情報をより簡単に解析し、比較するために行列を作成
することができる。たとえば、図9(a)の特徴ベース
面幾何学にもとづいて、図9(c)に示す行列を作成
し、これによって図8(a)の閉じた4折り曲げ箱の色
々な特徴を示すことができる。同様に、開いた4折り曲
げ箱に対しては、たとえば図9(b)に示す特徴ベース
面形態にもとづいて、図9(d)に示す行列を作成でき
る。他の特徴抽出データ、たとえば部品の曲げ特徴(た
とえば90゜正の曲げ角度または90゜負の曲げ角度等)も
行列の中に示すことができる。
【0098】上記のように、ステップS.102の特徴抽出
操作は、曲げモデルデータと形態を解析することによっ
て、部品に色々な特徴が存在するかどうかを決めるため
に実施できる。本発明の見地に沿って、特徴抽出操作は
部品に提供されている曲げモデルと形態データについて
行うことができる。このデータは、面のデータ、曲げ線
データ(たとえば曲げ線長さと位置等)、面―曲げ線関
係データ、曲げ角度データ及び特別の特徴データ(たと
えばZ―曲げや縁取り等)を含む、薄板金属部品に関す
るすべての重要な幾何学と位置のデータ(たとえば2-D
空間(X,Y)及び/または3-D空間(X.Y.Z)における)を
含む。線、曲げ線や他の構成要素はエンドポイント(端
点)や/またはベクトルで定義することができる。たと
えば各2D線は一組の2Dエンドポイント(たとえばX1,Y1
とX2,Y2)、各3D線は一組の3Dエンドポイント(たとえ
ばX1,Y1,Z1,とX2,Y2,Z2)で指定することができる。曲
げ線は2Dまたは3D空間における場所とともに曲げ線の方
向を示すベクトルで表すことができる。さらに、2Dの弧
は2D空間データ(たとえば中心X、中心Y、半径、開始角
度、終了角度)、3Dの弧は3D空間データ(たとえば中心
X、中心Y、中心Z、ビユー行列、半径、角度開始、角度
終了)で指定することができる。部品形態データも、部
品の色々な面や曲げ線の場所やこれらの間の幾何学的関
係を示すために提供することができる。各面は線と/ま
たは弧の集合または連結データリストで定義することが
できる。
【0099】部品の特徴を抽出するため、曲げモデルと
形態データの特徴抽出操作を行い、解析することによっ
て、ある特徴が部品に存在するかどうかを定めることが
できる。このプロセスは、抽出する各特徴間の色々な特
色や関係にもとづく、曲げモデルと形態データの解析を
含むこともできる。各特徴の特色と関係を知るための曲
げモデルと形態データの解析によって、ある特徴(たと
えば面間の接触コーナー、開放コーナー特性、または平
行または直列曲げ特性)の存在が検出できる。異なるプ
ロセスを、各特徴の特定の特性と関係を特徴抽出操作で
検出するために備えることもできる。解析される各特徴
間の特性と関係の類似性にもとづいて、部品に一つ以上
の特徴が存在するかどうかをチェックするために幾つか
のプロセスを組み合わせるか作成することもできる。
【0100】限定されない例として、ステップS.102に
おける特徴抽出操作の際に、コーナーの特徴、たとえば
同じ曲げ方向をもつ二つ面の接触コーナー特徴(表1のT
ouchCnr特徴)を抽出し、検出するために行うことがで
きるプロセスについて述べる。下記のプロセスは、他の
特徴の検出、たとえば逆曲げ方向をもつ二つの面の接触
コーナー特徴(表1のtouchCnr特徴)または同じまたは
逆曲げ方向を持つ二つの面の開放コーナー特徴(表1のO
penCnrとopenCnr特徴)に用いることもできる。プロセ
スを修正することによって、他の特徴も検出できる(た
とえば平行曲げ、直列曲げ等)。さらに、面の可能な各
組み合わせに関するデータを、抽出される各特徴の特性
と関係を知るために解析することができる。
【0101】たとえば、接触コーナーの特徴をもつTouc
hCnrの場合、検出する特徴または関係は:共通の面を持
つ二つの面;同じ曲げ線方向;同じ頂点を(または頂点
間の距離が事前に定めた範囲内にある頂点)をもつ曲げ
線を含む。接触コーナーの特徴をもつtouchCnrの場合、
同様の特性または関係を検出しなければならない;ただ
同じ方向の曲げ線をもつ面ではなく、面は逆方向の曲げ
線をもっていなければならない(たとえば表1をみ
よ)。開放コーナー特徴OpenCnrとopenCnrも同様に検出
できるが、各特徴に接触コーナー関係の代わりに、面間
に開放コーナーが存在する(たとえば面の曲げ線が事前
設定の範囲の距離より大きく隔たっている)ことと、同
じまたは逆の曲げ線方向(たとえば表1と表中のOpenCnr
とopenCnrの定義をみよ)をもつ曲げ線を検出し、解析
しなければならない。
【0102】接触コーナー特徴(たとえば表1のTouchCn
r特徴)を検出するためには、先ずある二つの面を解析
し、二つの面が共通の面に接続しているかを決定する。
これは各面の曲げ線データと各曲げ線の曲げ線―面関係
データを探索して、共通面が存在するかどうかを決定す
ることによって検出できる。もし二つの面が共通の面に
接続していれば、各面の曲げ線方向を解析して同じ曲げ
線方向(または、たとえばtouchCnr特徴を検出する場合
は逆の曲げ線方向)をもつかを見る。これは、たとえば
各面の曲げ線方向を示すベクトルデータを解析する事に
よって決められる。
【0103】二つの面が共通の面をもち、曲げモデルと
形態データにもとづいて同じ曲げ線方向をもつことが決
定されると、データを検査することによって曲げ線が平
行かどうかが検出される。色々な方法を用いて、曲げモ
デルと形態データにもとづいて曲げ線が平行かどうかを
検出することができる。たとえば、平行曲げ線の検出
は、曲げ線方向を定めるベクトルの外積をとることによ
って決められる。もしベクトルの外積がゼロ(または近
似的にゼロ)であれば、曲げ線は平行であると決定され
る。もしベクトルの外積がゼロでなければ(または近似
的にゼロでない)、二つの面の曲げ線は平行でない。
【0104】二つの面が共通の面をもち、曲げ線方向が
同じで曲げ線は平行ではないことが決まった後、面の間
のコーナーの関係(たとえば接触か開放か)を決めるた
めに、曲げモデルデータが解析される。二つの面のコー
ナー関係は、曲げモデルデータから、面の曲げ線が共通
の頂点をもつかどうかを検出することによって決められ
る。曲げ線が共通の頂点をもっていれば、二つの面は同
じ曲げ線方向の接触コーナー関係(表1のTouchCnr特
徴)をもつ。曲げ線は共通の頂点をもっているが、二つ
の面の曲げ線方向が異なることが決まれば、二つの面は
逆方向の接触コーナー関係(たとえば表1のtouchCnr特
徴)をもつと決められる。
【0105】二つの面が共通の頂点をもっていない場合
でも、頂点間の距離が予め定められた範囲内であれば、
二つの面は接触コーナー関係をもつと決定できる。しば
しば部品の隣接する面の間に、たとえばパンチ工具を通
すためのすき間として最小限のスペースが設けられるこ
とがある。このスペースは、通常フランジの高さのとこ
ろでの工具の幅で決められる。例をあげれば、二つの面
の曲げ線の頂点間の距離が0-5mm以内であれば、接触コ
ーナー特徴の存在が決定できる。もし二つの面のコーナ
ー間のスペースが、事前に定められた範囲より大きけれ
ば、開放コーナー特徴の存在が決定できる(たとえば表
1のOpenCnrまたはopenCnr特徴)。
【0106】上記のプロセスは部品の面のあらゆる組み
合わせについて、各面のコーナー特徴を決めるために実
施することができる。部品の面や曲げ線に関連する他の
特徴も、同じように部品幾何学と形態データの解析によ
って行うことができる。ステップS.102における特徴抽
出操作を実行するための典型的なコードを付録Aに示
す。このコードはC++プログラム言語で書かれており、
表1に記してあるような特徴を抽出検出するための色々
なプロセスを含む。付録Aのコードには、使用されてい
る論理やアルゴリズムの解析を容易にするためのコメン
トがついている。またこのコード例では、色々な特徴の
理解を助けるために、表1と同じ特徴の用語が使われて
いる。
【0107】部品の色々な特徴が検出されると、部品の
基本的な形態は修正され、抽出された特徴が含められ
る。特徴ベース形態を提供することは有用かもしれない
が、このような形態をお互いに比較することは容易でな
い。その代わりに、本応用の発明者達は行列の形で提供
された特徴抽出情報を比較する方が、より有効で容易で
あることを発見した。従って、本発明の一つの特徴とし
て、特徴抽出操作の際に、検出された特徴にもとづいた
特徴ベース部品行列(図9(c)と9(d)に示す代表
的な行列のような)が作成される。作成された部品の特
徴ベース行列は、他の所定の、格納された行列と比較す
ることによって、どのような基本的な形や特徴が部品に
含まれているかを決定する。
【0108】特徴ベース行列は、部品の色々な特徴を検
出し、抽出した後に、部品毎に作成され、格納される。
図9(c)と9(d)に示すように、行列は対称的な2
次元行列で部品の面の数に等しい次数をもつ。行列は部
品のすべての検出された特徴情報を含み、各面の間の色
々な特徴が行列の各場所に提供されている。特徴ベース
行列は、一時的にサーバーまたはステーションモジュー
ルの記憶装置に格納し、類似部品探索を実行するときに
のみ使用し、所定の行列と比較することができる。ある
いは、特徴ベース部品行列を永久的に他の仕事情報とと
もにデータベース30に格納し、工場内のどの場所でもア
クセスできるようにすることができる。
【0109】図6に戻ると、特徴抽出操作を行った後、
引き出した特徴抽出データ行列を、特徴形態ライブラリ
に備えられている所定の特徴抽出データ行列と比較する
ことができる。特徴形態ライブラリは、別のデータフア
イルとして、データベース30のようなデータベース、ま
たはサーバー・モジュールかステーション・モジュール
に格納しておくことができる。特徴ライブラリは、基本
的または基礎的な部品の形状(たとえば4折り曲げ箱、
橋梁等)に対応するまたは定義する特徴抽出データを含
む所定の行列よりなる。各所定特徴ベース行列は、特徴
ベース部品行列とともに、ASCIIまたはテキストフアイ
ルとして格納できる。ステップS.104のおける比較は、
ステップS.106に図示されているように、薄板金属部品
に存在する基本的または基礎的な形状/特徴を決めるた
めに行われる。格納されたルックアップテーブルを、ど
の基礎的な形状が各所定特徴行列に対応するかを示すた
めにを備えておくことができる。一致するものが見いだ
されると、ステップS.106でどの基礎的形状が存在する
かを決めるために、ルックアップテーブルがアクセスさ
れる。事前定義ライブラリに存在する一致する行列は、
特徴ベース部品行列と同じ次数であるか(この場合は部
品はただ一つの基礎的形状を含み、精確に対応すること
が決定される)、または部品行列のサブ行列かもしれな
い(この場合は部品は一つ以上の基礎的形状を含むかも
しれない)。
【0110】特徴ベース部品行列を事前定義ライブラリ
にある行列と比較するために再帰プログラミング技法を
利用することができる。含まれている情報を比較すると
き、行列の指標を入れ替えることによって、データ割り
当ての使用が避けられ、必要なプロセス時間が短縮され
る。再帰プログラミング技法と指標の入れ替えはまた、
異なる次数と異なる基底面をもつ行列の比較を容易にす
る。
【0111】本発明の見地に沿って、ステップS.104で
実施される比較操作は、一連の比較よりなり、最初によ
り複雑な形状(たとえば多数の曲げ、またはタブのよう
な複雑な成形を含む形状)に関する行列の比較から開始
し、より複雑でない形状(たとえば、より少ない曲げ、
またはより複雑でない曲げ、より少ない数の面をもつ形
状)へと進む。この一連の比較は部品に、所定数の基本
的形状が見いだされるまで行われる。たとえば、比較操
作はある特定の部品の三つの最も複雑な特徴または形状
を抽出するために行うことができる。さらに、この操作
を最初に、薄板金属部品によく、または度々みられる形
状に関する行列のグループに対する一連の比較から始
め、次により一般的でない形状に進むこともできる。部
品を事前定義ライブラリと比較するために、色々な方法
を有用な結果をうるために行うことができる。
【0112】たとえば、一連の比較操作を先ず、多数の
直角曲げを持つ長方形や正方形形状や直角曲げをもつ単
純な部品のような、直角曲げをもつ基本形状を含む行列
の直角グループに適用することができる。この行列のグ
ループは、グループの中の、より複雑な行列(たとえ
ば、タブをもつ四つ折り曲げ箱に対応する行列)からグ
ループの中のより単純な行列(たとえば、単純ハット部
品に関する行列)へと進める一連の比較にもとづいて探
索することができる。それから一連の比較を多角形部品
グループの行列に、さらに特別特徴グループの行列へ適
用することができる。多角形部品グループは五つ以上の
側面と、少なくとも90度以上の曲げを一つもつ部品を定
める行列を含みうる。特別特徴グループの行列は、Z―
曲げまたは縁取り曲げのような、特別な特徴または成形
をもつ部品に関係する事前定義ライブラリ内の行列を含
みうる。ここでもまた、部品の特徴ベース行列と各グル
ープの所定行列との間の一連の比較は、複雑性の度合い
の減少に従って行われる。この後に、部品の一つの面に
二つまたは二つ以上の特徴をもつ多重特徴グループのよ
うな、所定行列の他のグループを比較することができ
る。
【0113】複雑性の度合いに従って部品を事前定義ラ
イブラリの行列と比較し、実現と使用頻度にもとづく行
列のグループの一連の比較をすることによって、部品に
存在する基本的な形状の決定するためのライブラリとの
より効果的で有効な比較ができる。さらに、検出特徴の
重複が防がれ、より複雑な形状のみが識別される。
【0114】ステップS,108では、部品にある基本的な
特徴または形状間の関係を決めるために特徴関係操作を
行う。特徴または形状間の関係は距離によって定められ
る。二つの形状間の距離は、各々形状の基底面(基本
面)の間の曲げ線または面の数にもとづいて決められ
る。あるいは、特徴間の関係は、部品及び、各特徴の基
底面の相対位置と間隔を幾何学的に解析することによ
り、特徴間の物理的な距離または実際の寸法によって定
めることができる。
【0115】例示のため、ステップS.106で決定した部
品の三つの最も複雑な特徴または形状は、図10(a)
に示す4折り曲げ箱と、ブリッジと、もう一つの4折り曲
げ箱とであるとしよう。このような部品については、特
徴関係操作を、たとえば各基本的特徴の基底表面または
面の間の曲げ線の数を決めるために行うことができる。
図10(b)で示すように、第一の4折り曲げ箱の基底
(1)とブリッジの基底(2)の間の特徴関係は、二つの
曲げ線の間隔である。さらに、第一の4折り曲げ箱の基
底(1)と第二の4折り曲げ箱の基底(3)の間の関係
は、四つの曲げ線の間隔であり、ブリッジの基底(2)
と第二の4折り曲げ箱の基底(3)の間の関係は、二つの
曲げ線の間隔である。
【0116】いろいろなプロセスによって、部品の基本
形状の基底面間の曲げ線の数を決めることができる。た
とえば、特徴ベース部品行列と所定形状行列を利用し
て、ステップS.108で特徴関係を決めることができる。
最初に、部品行列にある各基本形状に対応する基底面を
捜し出す。これは所定形状行列の基底面を、部品行列の
面指標と相関することによって行うことができる。前に
論じたように、比較操作で切り離した所定形状行列は、
部品行列のサブ行列かもしれない。部品行列で各基本形
状に対応する基底面を捜し出すには、部品行列内の形状
行列の位置と行列の指標の間の相関を解析する。各基本
形状の基底面は、予め定められており形状行列の第1列
に位置しているので、部品行列内の対応する位置と基底
面を捜しだすことができる。
【0117】特徴ベース部品行列内の各基本形状の基底
面を決定した後、特徴関係を決めるために、各形状の基
底面間の距離を解析する。この解析は、如何なる二つの
基底面間の距離をも同定する探索プロセスを含んでい
る。部品行列内の特徴と曲げ線情報を見ることによっ
て、どの二つの基底面間の曲げ線の数でも決定できる。
二つの面の間に一つ以上の経路が可能な場合には、最小
距離を用いてステップS.108において特徴関係を定義す
ることができる。
【0118】特徴関係操作を終えた後の論理の流れはス
テップS.110に続く。図7に示すように、ステップS.110
では、データベースの類似部品探索に用いる探索キーを
決めるために、データベース探索キーの同定が行われ
る。探索キーは、部品に同定された特徴や特徴関係の幾
通りもの組み合わせを含みうる。さらに、探索キーをア
センブルするのに、どのような基準の階層も用いること
ができる。限定されない例として、下記の基準に従って
探索キーを作成することができる:(i)部品に同定さ
れた一番目と二番目に複雑な特徴または形状;(ii)最
も複雑な二つの特徴間の距離または特徴関係;(iii)
部品に同定された三番目に複雑な特徴または形状;及び
(iv)部品に同定された一番目に複雑な特徴と三番目に
複雑な特徴間の特徴関係または距離、及び二番目に複雑
な特徴と三番目に複雑な特徴間の距離または特徴関係。
図10(c)に図10(a)の例にもとづいて開発され
た探索キーを示す。
【0119】データベースの探索を容易にするために、
探索キーは、形状ライブラリで定義された色々な基本形
状に割り当てられた所定コードをもつ整数の列で表すこ
とができる。たとえば、4折り曲げ箱に整数コード“1
6”が割り当てられ、ブリッジに整数コード“32”が割
り当てられたとしよう。この場合、図10(c)の例の
探索キーは、整数列“16,16,4,32,2,2”で表され、この
なかで“4”と“2”は基本形状または特徴間の色々な距
離を表す。しかしながら、探索キーの表示は、整数列に
限定されるものではなく、どのような組み合わせの整数
及び/または文字列を探索キーの表示に用いることがで
きる。
【0120】各部品の探索キーは、仕事情報とともに
(別のフアイルまたは同じフアイルに)、データべー
ス、たとえばデータベース30、に格納できる。特徴抽出
データの代表的な探索キーは、手動で入力するか、上記
のように自動的に作成できる。特徴ベース部品行列のよ
うな付加的特徴抽出データは、探索キーを用いて格納で
きる。探索キーが別のフアイルに格納してあるときに
は、各探索キーのセットと関連する部品情報を捜し出す
ための参照用テーブルを用意できる。あるいは、探索キ
ーは部品情報を同定する(たとえば部品または参照番号
によって)データフイールドとともに格納しておくこと
ができる。
【0121】ステップS.112では、同定された探索キー
にもとづくデータベースの協調探索が行われる。協調探
索は、協調データベース探索技法を用いる探索である。
協調探索技法は、同一の探索キーをもつ部品ばかりでな
く、類似の探索キーを持つ部品を捜し出す。これによっ
てデータベースにある、類似および同一部品を同定する
ことができる。特定の部品についての探索を行うと、そ
の部品のものと同定された探索キーを、データベースに
ある他の探索キーデータと比較することができる。ステ
ップS.112で行われる協調探索は、探索キーの順序を緩
めるか修正することによって、データベースにある項目
で、探索キーによって同定された特定の部品と正確に一
致するか又は最も類似している項目を同定するように構
成される。色々なプロセスと方法を、協調探索において
探索キーを適合させるのに用いることができる。たとえ
ば、最初にデータベースの探索を、探索する部品のもの
と同定されたものと正確に一致する探索キーの順序をも
つ部品を同定するために行うとする。これは同定された
探索キーをデータベースに格納されている探索キーと比
較することによって行われる。同じ探索キーをもつ部品
(もしあれば)を同定した後、引き続き他の類似部品を
捜しだすために、異なる修正された探索キー順序に基づ
くデータベースの探索を行うことができる。最初探索キ
ーにある、あまり重要または敏感でない項目または基準
(特徴関係または距離のような)は、より重要または敏
感な探索項目(部品にある基本的な特徴または形状のよ
うな)を修正する前に修正し、探索することができる。
さらに、これらの各項目は、項目の重要度に従って修正
し、部品にある一番目と二番目に複雑な特徴または形状
に関連する項目に、より高い重みまたは重要度を当てる
ことができる。たとえば、ひき続き最初に行う探索は、
三番目に複雑な特徴と一番目、二番目に複雑な特徴間の
定義された距離を修正した後に行うことができる。この
距離は、所定曲げ線数(たとえば1-3)だけ変更し又は
現在の距離に基づいた距離の所定範囲を定義することに
よって修正できる。しかる後、一番目と二番目に複雑な
特徴または形状間の距離を変更して、データベース探索
用の修正された探索キーの組をもう一つ備えることがで
きる。部品の特徴関係または距離の探索キーを修正した
後、同定された形状を、協調探索における付加的な修正
探索キーを導くために変えることができる。たとえば、
三番目に複雑な特徴または形状に関する探索キー項目
を、現在扱っているものの特徴または形状によって、関
連するがより複雑でない形状に変えることができる(た
とえばタブのある4折り曲げ箱を単純な4折り曲げ箱
に)。さらに、一番目と二番目に複雑な特徴の探索キー
を同じように変えることによって、さらに協調探索のた
めの修正探索キーを加えることができる。
【0122】探索キーに関係する距離と特徴/形状の、
協調探索中の修正は、いろいろな方法と技法によって実
行できる。上記のように、どのくらい距離を変えるか
は、距離の現在値に依存する。距離の大きさ(たとえば
4曲げ線)を、探索を拡張し、より協調的にするために
距離の範囲(たとえば3-5)で修正することができる。
特徴または形状についても、類似部品を同定するために
探索キーを修正できる。特徴または形状は、特徴タイプ
の階層構造を通して修正できる。たとえば、現在扱って
いる特徴タイプ(たとえば4折り曲げ箱)を、関連し同
じ特徴タイプに属するより複雑でない特徴タイプ(たと
えば3折り曲げ箱)に修正することができる。特徴/形状
を修正するに用いる階層構造は、複数の異なる技法、た
とえば型抽象化階層(TAH)に基づいて事前に定義でき
作成できる。TAHとTAH世代に関する詳しい情報は、たと
えばチューら、ウエスリー、W(CHUWesley W.)による"
型抽象化階層による協調的問い合わせ応答"(Cooperati
ve Query Answering via Type Abstraction Hierarch
y)CSD-900032,1990年10月、カリフォニア大学ロスアン
ジェレス(University of California,LosAngeles,Octo
ber 1990)および1995年、コンピュータ科学哲学博士の
博士論文、クオーロン・チアング“協調的問い合わせ応
答のための型抽象化階層の自動生成”(CHIANG,Kuoron
g,Automatic Generation of Type Abstraction Hiera
rchies for Cooperative Query Answering)にあり、そ
こに開示されている情報すべてを参照することによって
ここに取り入れられている。
【0123】協調探索の間に、他のプロセスやステップ
を実施するこができる。たとえば、部品の特徴に関連し
ていると同定された探索キーに基づいたデータベースの
探索に加えて、部品の製造情報に関連した探索基準に基
づいて探索することもできる。たとえば、付加的な探索
キーを利用して、一例として各部品に必要な機械構成を
比較することができる。機械構成情報は機械のタイプま
たは部品を製作するために必要な機械類、部品を製作す
るために用いる工具類や工具構成および/または機械類
のバックゲージング設定を含む。付加的探索キーは、機
械構成情報および/または他の製造情報に基づいて開発
することができ、本発明の協調探索をする際に、同定さ
れた探索キーとともに用いることができる。その結果、
製作される部品と同一または類似な部品は、部品の設計
と製造特徴両方に基づいて同定することができる。
【0124】最も類似した部品を選ぶために、選択部品
探索をステップS.114で実行し、協調探索の結果のより
詳しい比較と、探索された部品と同じまたは最も類似し
ている部品を所定数だけ選ぶ。選択部品探索は、協調探
索で同定された各部品に対する付加的な情報や特性の解
析を伴いうる。これは部品の寸法や部品にある孔や開口
の形のような、捜し出された部品の色々な特徴の解析を
含む。さらに各部品に要する機械構成のような、捜し出
された各部品の製造情報の比較も含みうる。上記のよう
に、機械構成情報は、部品の製作に要する機械の種類ま
たは機械類、部品の製作に用いる工具や工具構成、及び
/または機械類のバックゲージング設定を含む。選択部
品探索を行うために、各部品の曲げモデルや他の仕事情
報が、協調探索で同定された探索キーに基づいてデータ
ベースからアクセスされる。上記のように、各探索キー
の組に対応する仕事参照番号またはコードを提供するた
めに、ルックアップ表や付加的データフイルドを設ける
ことができる。データベースから部品情報を検索した
後、各部品の付加的情報(たとえば部品寸法、材料のタ
イプ、特別な成形、部品の孔または開口等)を、どの部
品が探索された部品に最も類似しているかを決めるため
に解析できる。このプロセスはオプションで、データベ
ースの部品で、当該部品に最も類似の部品を選び集約す
る付加的な選択プロセスの役割を果たす。この部品の付
加的情報または特性を解析し、照合することによって、
選択部品探索を、所定の数または組の最類似部品を同定
または選択するために行うことができる。たとえば、選
択部品探索で、照合探索キーの数と付加的部品特性の照
合に基づいて、五つの最類似部品を同定できる。選択部
品探索で選択される部品の数は五つに限らず、工場の必
要性とデータベースに実際に格納されている部品の数に
基づいて選ぶことができる。この数は、より有効で役立
つ探索結果をうるために選択的に修正でき、またユーザ
ーに探索の組を変えるために、この数を修正する機会を
与えることもできる。
【0125】選択部品探索を行った後、ステップS.116
で部品をランク付けする(特徴の類似性や突き合わせ探
索キーの数に従って)ために、類似性指標を計算するこ
とができる。類似性指標はステップS.116で計算され、
サーバーまたはステーションモジュールの出力として提
供され、これによってユーザーはどの仕事フアイルをデ
ータベースから検索し、画面に映し出すかを選択でき
る。類似性指標によって、選択された部品と探索部品の
特徴の類似性の程度に基づいて、選択部品のランク付け
(たとえば各部品の仕事または参照番号を付してランク
1から5)ができる。このためには各部品の特徴ベース行
列を探索部品のものと比較する。特徴ベース行列の比較
は、選択部品と探索部品の間の類似性をよりよく示す。
前のべたように、特徴ベース部品行列は各部品の探索キ
ーとともに格納できる。しかしながら、各以前の仕事の
特徴ベース部品行列を探索キーとともに永久格納するこ
とは、不必要に大きな記憶スペースを占有する(特にデ
ータベースに多数の部品が格納されている場合)。従っ
て各部品の探索キー・データのみを格納し、類似部品探
索を行うときに自動的に各選択部品の特徴ベース行列を
生成することしかできない。 従って、選択部品の曲げ
モデルと他の仕事情報を検索した後、前にステップS.10
2についてのべたように、特徴ベース行列は本発明の特
徴ベース抽出操作を通じて作成する。そのあとで、類似
部品探索時に一時的に格納した探索部品の特徴ベース行
列を、作成した選択部品の特徴ベース行列の各々と比較
できる。色々な方法とプロセスを、部品の特徴ベース行
列の比較と部品間の類似性の決定に利用できる。たとえ
ば、各選択部品の特徴ベース行列について、行列内の場
所を探索部品のものと比較できる。行列内の各場所は、
再帰的プログラム技法に基づいて比較できる。行列内の
情報は、各行列内の対応する基底面の場所を決め、行列
の指標を交換することによって比較できる。選択部品は
探索部品の副特徴に対応するか又はその形状をもつこと
もあり、又行列の指標が同一でないか、または同じ番号
付けがされていないこともあるので、含まれている情報
を比較するときに、部品行列内で比較できる面を捜しだ
して指標を振り替えなければならない。さらに探索部品
の中に一つ以上の副特徴が存在する場合、行列内の情報
を比較するとき、同じ次数の行列を提供するために、一
つまたは一つ以上の擬似面(行列の行と列で情報が無い
か空白のもの)を導入しなければならないことがある。
【0126】行列の情報を比較するときに、各選択部品
と探索部品の類似性の程度を決めるために、複数の異な
る順序づけ方式を用いることができる。たとえば、所定
ペナルティレベルまたは量を、行列内の整合しない各位
置に割り当てるペナルティベース順序づけ方式を用いる
ことができる。行列内のすべての情報を比較した後、各
選択部品の総ペナルティレベルを用いて類似性の程度を
決めることができる。最も低いペナルティレベルをもつ
選択部品が、探索部品に最も類似した部品と決定され
る。他の選択部品も、各部品に付せられた総ペナルティ
レベルに基づいて順序づけできる(たとえばペナルティ
レベルが低いほど類似指標が高い)。
【0127】本発明のさらなる見地に沿って、各非整合
位置のペナルティレベルは、その位置にある情報のタイ
プに基づいて割り当てることができる。ペナルティレベ
ルは整数量で非整合情報の重大性または重要性に応じて
変えることができる。たとえば、異なる、関係のない特
徴グループ(たとえば平行曲げ特徴対直列曲げ特徴)に
関する非整合位置に対しては、高いペナルティレベルま
たは量を割り当てることができる。これと対照的なの
は、異なるが類似の特徴グループ(たとえば同じ曲げ線
方向をもつ接触コーナー特徴対逆の曲げ線方向をもつ接
触コーナー特徴)である。ペナルティレベルまたは量
は、非整合位置に存在する情報のタイプと相違のタイプ
に従って事前に定義、類別される。
【0128】ステップS.116における類似性指標操作の
典型的なコードは付録Bに示されている。このコードはC
++言語で書かれており、上に記述した行列の比較と非整
合位置に対するペナルティレベルの割り当てに関する色
々なプロセスと操作を含んでいる。上に付記したよう
に、比較された各選択部品の結果としてえられた総ペナ
ルティレベルは、類似性指標を導き、表示するのに用い
ることができる。付録Bにあるコード・リステイングに
は、記されている典型プログラム・コードの理解を助け
るためのコメントも含まれている。
【0129】次に図11−25を参照しながら、曲げモ
デルの開発と、色々な2-D、3-D図面に基づいた部品の2-
D、3-Dモデルの開発を、本発明の見地に沿ってより詳し
く記述する。前に論じたように、各薄板金属部品に関す
る曲げモデルデータは、部品の2-D、3-D表現両方に関連
するデータを含んでいる。顧客の注文に基づいて提供ま
たは作成された原図のタイプに基づいて、色々な折りた
たみと展開アルゴリズムや他のプロセスを2-D及び3-Dモ
デルの開発に利用できる。特に図11-18は、部品の
元の2-D一方向図面(2次元単一図面)に基づいて、3-D
モデルを作成するに利用できる折りたたみアルゴリズム
の論理の流れの例を示す。図19は、3-D原図(厚さぬ
き)に基づいて2-Dモデルを作成するのに用いられる展
開アルゴリズムや他のプロセスの基本的な論理の流れの
例を示す。最後に図20-24と図25は、2-D三方向図
面(2次元三面図)と厚さありの3-D図面から、厚さぬ
きの3-Dモデルを作成するのに実施できる色々なプロセ
スや操作の論理の流れの例を示す。これらのプロセスや
操作でえられた3-Dモデル(厚さぬき)は、文中に明示
されているように、展開アルゴリズムまたはプロセスに
基づいて2-Dモデルを作成するのに利用できる。
【0130】図11は2-D一方向図面から折りたたみア
ルゴリズムを用いて3-Dモデルを作成するプロセスと操
作の論理の流れを示す。図11の流れ図で行われる機能
や操作は、たとえばサーバー・モジュール32にあるソフ
トウエアまたはプログラム論理によって実施できる。ス
テップS.120では、顧客の仕様に基づいて提供された、
あるいは新たに作成された2-D一方向平面図が、サーバ
ーモジュール32に入力または取り入れられる。2-D平面
図はCADソフトウエアを用いて作成し、サーバー・モジ
ュール32に入力するか、ベルムまたはキャドキーのよう
な、適当なCADまたはCAD/CAMシステムとインターフエイ
スすることによってサーバー・モジュールに取り入れる
ことができる。2-D図面は、たとえばDXFまたはIGESフア
イルとして格納され、曲げられる打ち抜き及び/または
切断材料を図示することができる。2-D図面はまた、薄
板金属部品の表面や面の曲げ線の位置や、孔または開口
を示すことができる。2-D図面を後で処理するための準
備として、ステップS.124における次の面検出プロセス
とステップS.126における曲げ線検出作業を行う前に、
ステップS.122でサーバー・モジュール32によって自動
クリーニングやクリーンアップ機能を実施することもで
きる。
【0131】本発明の自動トリミングとクリーンアップ
機能は、2-D平面図を、処理に対して準備するために備
えられている。2-D平面図は、薄板金属部品の展開状態
の2-D表示で、部品の幾何学を構成し表現する線及び曲
線の如き部品要素(エンティティ)を含むとともに、部
品に存在する開口または孔の位置を示す。通常このよう
な2-D平面図の構成要素(エンティティ)は、CADまたは
CAD/CAMシステムを使用して入力し、作成する。しか
し、2-D平面図を作成するとき、このような要素はしば
しば誤って連結または重ね合わされ、一つの要素が一つ
以上の面の境界を示すのに用いられることがある。さら
に、部品の境界を決めている外側線が、境界の隣接する
コーナーで分断されていて、部品と各面の外側の寸法の
検出を難しくしている。さらに、2-D平面図は、寸法情
報やテキストのような本質的でない情報を含みうる。こ
のような異常は、元の2-D図面を正確に解析し、部品の
面や曲げ線を均一に検出するのを難しくする。本発明の
自動トリミングとクリーンアップ操作を備えることによ
って、各面は連結された要素の一義的なセット(セッ
ト)で表現できる。その結果、2-D平面図は、引き続き
行われる処理と最終的に行われる3-Dモデル表現作成の
ための折りたたみのために、より簡単かつ効率よく解析
できる。
【0132】図12に示すように、元の2-D図面では面
間のトリミングがされておらず、図中の一つの線要素が
一つ以上の面の外側境界または複数の境界を定めている
ことがある。上記で論じたように、このような配置は各
々の面の検出を困難にする。本発明の自動トリミング機
能は、連結性情報を決定し、上記のような要素を交点で
断ち切るために、各部品要素(線、弧や曲げ線のよう
な)の終点と交点を解析するのに備えられている。この
ようなトリミング機能は、断ち切られた各要素の終点を
決められた交点に設定する機能ももつ。たとえば、図1
2に図示されている交点をトリミングすることによっ
て、各々が交点に終点を共有する三つの要素(二つの線
と一つの曲げ線)がえられる。このようなトリミング機
能を備えることによって、要素解析と連結に基づいて部
品の面をより容易に検出することができる。実施できる
面検出操作のさらに詳しい記述は、下記に図15(a)
-16(c)を参照しながら提供される。
【0133】色々なプロセスや操作を用いて2-D図面の
要素の交点を検出することができる。このようなプロセ
スは、2-D図面のフアイルのデータのフオーマットと配
列に基づいて作成できる。通例2-D平面図は幾何学デー
タ(色々な部品要素を定義する)と非幾何学データ(た
とえばテキスト等)を含む。幾何学データは、データの
各行またはシーケンスにあるキーワードによって非幾何
学データと区別できる。このようなキーワードは2-D図
面のデータ書式に従って設定される。2-D、3-D図面によ
く用いられる書式としてDXFとTGES書式がある。各要素
の幾何学データを解析することによって要素の終点や交
点が検出でき、適当であればトリミングができる。
【0134】上記で論じたように、線、曲げ線や他の要
素は終点及び/またはベクトルで定義できる。たとえば2
-D平面図では、各2-D線は2-D終点の組(たとえばX1,Y1
とX2,Y2)で特定することができ、曲げ線は曲げ線の2-D
空間位置とともに方向を示すベクトルで表すことができ
る。さらに2-D弧は2-D空間データ(たとえば中心X、中
心Y、半径、開始角度、終了角度)で特定することがで
きる。幾何学データはまた、色々なタイプの線要素(た
とえば弧、実線、破線、鎖線等)を区別する属性をも
つ。通常弧要素は薄板金属部品の孔や開口を、実線は部
品の境界や形状を示すのに用いられる。曲げ線は普通破
線で示され、部品の中心線は鎖線で示される。
【0135】元の2-D図面の幾何学データを解析し、各
要素の交点を決めることができる。データ割り当てやデ
ータ反復のような、色々なデータ解析手法を2-D図面の
各要素の幾何学データの解析に用いることができる。各
要素の終点及び/または他の2-D空間データに基づいて、
線や他の要素が交差するかどうかを決める簡単な幾何学
解析をすることができる。二つの要素が交差することが
決まれば、各要素を決定された交点で断ち切り、残った
要素の終点には交点で定められた共有点を割り当てるこ
とができる。
【0136】トリミングの方法は、交差することが検出
された要素のタイプに基づいて行われる。たとえば二つ
の実線が交差することが検出されると、図13(a)に
示すように、各線要素を断ち切ることによって、定めら
れた交点で接する四つの線要素がえられる。また線要素
と弧要素が、図13(b)に示すように交差することが
決まると、各要素を断ち切ることによって共通の終点を
もつ二つの線要素と二つの弧要素をうることができる。
しかしながら、要素の交差が検出されても、トリミング
を必要としないこともある。たとえば、如何なる要素で
も中心線(たとえば鎖線要素)と交差することが決定し
た場合、どの部品の中心線も部品の面または曲げ線を定
めたり区別したりすることはないので、トリミングの必
要はない。また、連結しない要素でも、開いている交点
または面積が、所定の許容度内であれば切断できる。た
とえば、潜在的に交差する線の終点が、実際に他の要素
と交差するときの交点と、事前に定義した許容度または
距離ε(たとえば0.0-0.01mmまたは0.0-0.001インチ)以内
であれば、要素は投影された点で連結交差しているもの
と扱ってよい;そしてたとえば図13(c)に示すよう
に、要素を断ち切ることができる。
【0137】自動トリミングをした後、えられたデータ
を、非連結要素を検出し修正するためにクリーンアップ
機能で処理することができる。しかしながら、本発明は
このような処理のみに限られていない;処理時間を短縮
するためにクリーンアップ機能を、各要素が解析されて
いる間に、自動トリミング機能と同時に行うことができ
る。クリーンアップの間に、2-D図面の幾何学データ
が、隣接する要素間の開いた交点または領域を検出する
ために解析される。自動トリミング機能と同様に、要素
間の開いた交点の領域を検出するために、各要素の終点
や他の2-D空間データも解析できる。このようなデータ
に簡単な幾何学的解析を加えることによって、要素の終
点が互いに事前に定義した許容度または距離(0.0-0.01
mmまたは0.0-0.001インチ)内にあるかどうかが決定でき
る。要素の終点がこのような開いた交点をもつことが決
定されると、要素を連結し、図14に示すように共通の
終点を割り当てることができる。
【0138】ここでもまた、クリーンアップ機能をどの
ように行うかは、開いた交点をもつことが検出された要
素のタイプによる。二つの実線が開いた交点をもつこと
が検出された場合、各終点に共通の終点を割り当てるこ
とができる(たとえば図14を見よ)。しかしある要素
が部品の中心線(たとえば鎖線要素)と開いた交点をも
つことが決まったときには、要素を連結したり共通の終
点を割り当るべきでは無く、中心線は無視しなければな
らない。またクリーンアップ機能は、2-D図面から非幾
何学データ(テキスト等)を消去するための付加的なプ
ロセスまたは操作を含みうる。前述べたように、非幾何
学データは、2-D図面データとともに用意されているキ
ーワードに基づいて幾何学データと区別できる。クリー
ンアップ機能にはまた、後で本発明の2-Dクリーンアッ
プ機能を参照しながらより詳しく説明するような、他の
クリーンアップ機能を組み込むことができる(たとえば
図21-23(b)を見よ)。
【0139】ステップS.122で自動トリミングとクリー
ンアップ機能を行った後、ステップS.124で処理された2
-D図面について面検出の手続きを行うことができる。本
発明の見地に沿って、面検出手順は要素(線や弧)とル
ープ解析に基づいた部品の面の検出と定義付けを含む。
図15(a)-16(d)に面検出手続きで行われる色
々なプロセスと操作の例を示す。ループ検出技法を本発
明で部品の面を検出し、決定するのに用いることができ
る。面検出手続きは、たとえばサーバー・モジュール32
にあるソフトウエアまたはプログラムされた論理によっ
て実施できる。
【0140】本発明の見地に沿って、部品の外側境界の
ループ検出解析に引き続く、部品の最小または内側ルー
プの解析を用いて、面の各々を検出できる。薄板金属部
品のユニークな幾何学のため、面と部品にある開口は、
相対的極大(たとえば外側)と極小(たとえば内側)ル
ープの順序の解析によって検出することができる。下記
に論じるように、ループ解析は部品の線と弧要素の連結
性にもとづいて行うことができる。ループ解析を部品の
外側から部品の中心に向かって行うことにより、部品の
開口や面を、循環順序(たとえば面材料、開口、面材
料、開口等)に従って定義されたループ間の境界に基づ
いて検出することができる。
【0141】図15(a)に示すような、図示の各面の
各種の線要素を含む2-D平面図が提供されたとしよう。
上記のように、ループと要素解析は部品の外側から始め
るように行う。部品の外側境界にあるどの要素を初期参
照点にとってもよい。限定されない例として、図15
(b)に示すように、最も左側の線要素を検出し、初期
参照点に用いる。最も左側の線要素は、2-D図面にある
各要素の幾何学データを比較し、どの要素が最も小さい
X座標の値をもつかを決めることによって検出できる。
最も左側の線要素を検出した後、点P1から部品の外観が
導かれ、図15(c)に示すように部品の外側境界を検
出される。点P1を決めるには、最も左側の線要素のいず
れの終点を用いてもよい。図15(c)に示す実施例で
は、上側の終点(つまり最も大きなY座標の値をもつ終
点)が点P1に用いられている。
【0142】部品の外観、またはまわりのループを導く
のには、通常のループ解析技法を使うことができる。た
とえば、リード線ベクトルを、部品の外観を追ってゆく
に従って、始点P1と連結している要素の終点から投影し
てゆくことができる。一つ一つの要素が検出され、通過
される毎に、要素が選ばれたことを示すフラグを設定す
ることができる(たとえば記憶内のフラグは、一度選ば
れたことを示すために1に設定する)。ループの経路は
始点P1からどちらの方向にも始められる。たとえば、リ
ード線ベクトルを点P1から反時計方向(たとえばリード
線ベクトルをY座標方向に投影する)に投影することが
できる。ループはループ経路が始点(つまり点P1)に戻
ったところで完結する。
【0143】上記のように、始点P1からリード線ベクト
ルを反時計方向に投影できる(たとえば最初のリード線
ベクトルをY座標方向から始めることによって)。引き
続きループの経路にある最初の要素を検出するために、
各未検出要素が点P1のまわりにリード線ベクトルとなす
角度を座標枠に基づいて測定し、解析してリード線ベク
トルと最も小さい角度をもつ要素を選ぶ。外側ループで
は、 各角度は要素線がリード線ベクトルとなす外側角
度を測る。点P1の回りの要素は、どの要素が点P1と終点
を共有するかによって決められる。各要素の未選択状況
は、各要素に付したフラグを解析することによって決定
できる。図15(c)に示すように、図示の2-D図面例
では二つの要素線(X座標方向のものとY座標方向のも
の)がP1のまわりにある。これらの要素の解析では、Y
座標方向の線要素が、リード線ベクトルとなす角度(0
度)が他の線要素がなす角度(270度)より小さいので
選ばれる。
【0144】続いてループ解析は選択された他の線要素
の終点に進み、選択されたことを示すためにフラグが設
定される。その終点で、別のリード線ベクトルが投影さ
れ、その点のまわりの非選択要素を比較することによっ
て、どの要素がリード線ベクトルと最小の角度をもつか
を決める。ここでもまた、角度はリード線の外側から測
り、座標フレームを用いて角度の大きさを決める。弧要
素に出会った場合は、リード線ベクトルの外側から弧の
接線までの角度を測らなければならない。また、次の終
点にある要素が一つのみであれば(部品のコーナー位置
のように)、比較の必要はなく、単にその要素を選択し
てループに含めればよい。
【0145】部品の外観に沿ってループ経路が進むにつ
れ、選択された各要素は、ループ内の要素の連結性を示
すためにリンクされたリストに含めることができる。経
路が始点P1に戻るとサイクルは完了し、外観と、部品の
外側境界を示す要素または線のリンクされたリストに基
づいてループを(L4)と定義できる。ループL4内の各線
または要素は、各終点で連結できる。ループL4の方向
を、外側ループであることを示すために、図15(d)
に示すように、反対方向(つまり時計方向)に変えるこ
とができ。ループの方向は、ループL4で線がリンクされ
る順序に基づいて定義することができる;従って方向
を、リンクされたリストの順序を逆にすることによって
変えることができる。
【0146】外側ループの完了後、外側ループ解析に用
いたのと類似のプロセスで部品の内側ループの解析を行
うことができる。ただ内側ループの解析では、各非選択
要素は各要素がリード線ベクトルの内側となす角度に基
づいて比較される。さらに、内側ループ解析では、ある
点のまわりの両方の要素がすでに選択されていると示さ
れた場合(たとえば面を境する二つの外側線要素を比較
するとき)でも、二つの要素が既に二度選択(2のフラ
ッグ設定)されてない限り、二つの要素を比較すること
ができる。少なくとも一度選択された要素(たとえば外
側要素)と選択されていない要素の場合は比較は行わ
ず、非選択要素をループの一部分として選択する。図1
6(a)-16(c)に、図15(a)に示す部品の面
を検出し、規定するのに行うことができる内側ループが
例示してある。
【0147】内側ループ解析は、どの外側要素の終点か
らでも、あるいは選択されていない要素を検出すること
によって開始することができる。たとえば点P1を、内側
ループ解析の始点に選び、リード線ベクトルを投影する
のに用いることができる;あるいは外側ループ解析の際
に選ばなかった内側の線要素の一つも解析の始点に用い
ることができる。外側ループ解析と同じように、リード
線ベクトルを反時計方向(たとえば一番目のリード線ベ
クトルをY座標方向から始める)に延ばしてゆくことが
できる。次いで点P1のまわりの各要素を比較し、どの要
素がリード線ベクトルと最小の角度をもつかを決める。
リード線ベクトルとなす角度を決めるのに、座標枠を用
いることができる。前記のように、内側ループ解析に際
には、要素の比較は各要素がリード線ベクトルの外側で
なく、内側となす角度をもとに行う。最初の要素が選ば
れ、ループのリンクされたリストに含めたら、そのフラ
グを1だけ増分し、つぎのリード線ベクトルを投影する
ことによって解析を進めることができる。このプロセス
はループが最初の始点に戻るまで続けられ、そこで第一
の内側ループが、対応する要素のリンクされたリストに
よって定義(たとえばL1)される。
【0148】さらに部品の内部に進んで、同じように内
側ループ解析を行うことができる。次の始点は、どの要
素が一度しか選ばれていないかを決めることによって選
ぶことができる。二度選ばれたフラグをもつ要素は、そ
の要素がすでに外側ループ(たとえばL4)と少なくとも
内側ループの一つ(たとえばL1)で選ばれた外側要素で
あることを示す。ここでもまた、各要素が選ばれるたび
に、それが内側ループのリンク・リストに含まれたこと
を示すために、フラグを1だけ増分する。
【0149】すべての内側ループが定められた後(たと
えば図16(c)の例ですべての要素が二度選ばれた
後)、えられたループを用いてループツリー(ループ
木)を作成することができる。図16(d)に、検出さ
れたループL1-L4に基づいて作成したループツリーの例
を示す。部品の外側ループ(L4)はツリーの根(ルー
ツ)と定義し、外側ループと共通の要素をもつ各内側ル
ープ(L1-L3)は、根の子どもと定義されている。共通
要素の存在は、各ループを規定する要素のリンクされた
リストの解析と比較によって検出できる。内側ループ内
に、さらに要素(たとえば孔または開口)が検出された
場合には、これらのループを、それが位置する内側ルー
プの子ども(つまりループツリーの根の孫)と定義する
ことができる。
【0150】ステップS.124で面検出手続きを行った
後、ステップS.126で曲げ線検出操作を行うことができ
る。たとえば図17に示すように、ステップS.124で部
品のループを検出し解析するときに、本発明の面検出論
理は、面情報を規定し、検出された面を曲げグラフ・デ
ータ構造にノードとして格納するのに、ループツリーを
利用することができる。部品の面は、ループツリーにお
ける外側と内側ループの順序から検出できる。上記のよ
うに、各ループは要素または線のリンクされたリストを
含む。これらの要素は、部品の各面の境界を定めるのに
用いられる。従ってステップS.126において曲げ線検出
操作を行い、部品の面と曲げ線の間の関係を決めること
ができる。ステップS.126の曲げ線検出操作は、ある二
つの隣接する面が共有する端または線要素を検出するこ
とによって、部品の色々な面間のすべての曲げ線を検出
する曲げ線検出論理を含むことができる。また一つ以上
の領域で接続している面(たとえば3-Dモデルに曲げ線
検出アルゴリズムを適用する場合―たとえば下記に論ず
る図19を見よ)については、いろいろな発見的方法
(ヒューリスティク)を適用して、部品の曲げ線の最小
数を検出し、選択することができる。検出された曲げ線
は、たとえば図18に示すように、最終的な曲げグラフ
・データ構造を作成するための、面の節(ノード)の間
の連結エージェントとして格納しておこことができる。
【0151】本発明の曲げ線検出操作は、たとえばサー
バー・モジュール32に備えたソフトウエアまたはプログ
ラムされた論理によって実施できる。曲げ線検出操作の
目的は、部品が最も少ない数の曲げ線で連結されるよう
に、部品の曲げ線を検出し、選択することにある。曲げ
線検出操作は、部品の2-Dと3-Dバージョン両方に備える
ことができる。原3-Dモデルについての曲げ線検出の適
用は、下記に図19を参照しながら論ずる。上記のよう
に、検出された曲げ線は、最終的な曲げグラフ・データ
構造を作成するための面の節の間の連結エージェントと
して格納できる。この最終的曲げグラフ・データ構造
は、2-Dデータ・モデルから折りたたんで部品の3-Dバー
ジョンを作成するのに利用できる。
【0152】図11のステップS.120で入力として提供
された2-D図面は、曲げ線情報を含まないか、曲げ線情
報が不明確で、一義的にまたは矛盾なく定義されていな
いことがある。その場合、曲げ線検出操作を、曲げ線を
検出し、部品の検出された面との関係を検出するために
行うことができる。このプロセスの間に、各面を定義す
る要素(エンティティ)のリンクされたリストを解析
し、各面が部品の他の面と共にもつ隣接する端または線
要素を決めることができる。これはある与えられた二つ
の面の間の可能なすべての接触を解析することによって
行うことができる。接触は、長さが0以上の(つまり線
要素が点ではなく、実際の線である)、共通する線要素
(またはお互いに事前に定めた距離許容度にある複数の
線要素)の存在によって決定できる。リンクされたリス
トにある幾何学データを解析することによって、部品の
すべての二つの面間のこのような接触の存在を決めるこ
とができる。
【0153】ある特定の面が、他の面と共通の端または
接触領域を一つしかもっていない場合、両方の面に共通
の要素は曲げ線であると定義することができる。一つ以
上の領域で共通接触を持つ複数の面(たとえば3-Dモデ
ル;ただし2-Dモデルでも起こりうる)については、色
々な発見的方法(ヒューリスティック)を用いて部品の
最小数の曲げ線を検出し、選択することができる。使用
する発見的方法は、複数の面が曲げ線で連結され、複数
の面にわたる連続ループが形成されないようになってい
なければならない(このような曲げ薄板金属部品の製作
は不可能なため)。
【0154】利用できる発見的方法の例として、共通す
る領域で最も長い接触領域をもつものを曲げ線に選ぶ方
法がある。ある面が、他の面と一つ以上の共通端をもっ
ている場合、この発見的方法によって最も長い長さをも
つ共通要素を面の曲げ線に選ぶことができる。この発見
的方法は、曲げ薄板金属部品を製作するときに、通常長
い接触領域を持っている方が良いという原則にもとづい
ている。使用できるもう一つの発見的方法は、異なる可
能な曲げ線の組み合わせ(3-Dモデルの曲げ線を決める
ときのような)に関係する。この発見的方法では、すべ
ての可能な共通領域が検出され、曲げ線の色々な組み合
わせが選択されると、曲げ線の組み合わせで最小の曲げ
線の数をもつ組み合わせが選ばれる。
【0155】曲げ線が検出されると、部品の面と決めら
れた曲げ線は確認のためにオペレータに表示される。オ
ペレータが部品の曲げ線の選択に満足しない場合には、
曲げ線検出操作に手動選択機能を備えることによって、
サーバー・モジュール32でオペレータが選択的に、薄板
金属部品に好ましい曲げ線を指示できるようにすること
ができる。オペレータは、マウスやキーボード等、適当
な入力手段を用いて、曲げ線を保持するか変更するかを
指示することができる。しかる後、オペレータによって
選ばれた修正された曲げ線を用いて、最終的な3-D(ま
たは2-D)部品を作成することができる。
【0156】本発明の曲げ線検出操作を実施するため
に、色々なプロセスや操作を備えることができる。曲げ
線検出操作を実施するためのコードの例を、付記の付録
Cに与える。例示のコードはC++プログラム言語で書かれ
ており、記述の論理フローの理解を助けるためのコメン
トが含まれている。例示コードは、2-Dまたは3-Dモデル
について行うことができる曲げ線検出操作の実施例で、
曲げ線の最適選択を決める発見的方法(上述のような)
を含む。
【0157】検出された面と曲げ線情報は、本発明の折
りたたみと展開プロセスに利用することができる。折り
たたみまたは展開の際、各曲げ線の回りに3次元回転を
行うと、結果として3-Dまたは2-Dモデルが導かれる。こ
の仕事を行うには、単に部品の各面と他の要素に対し
て、回転と並進を含む行列変換を行えばよい。色々な市
販で入手できる展開と折りたたみソフトウエア適用の特
性を、本発明の基本的な展開または折りたたみステップ
を実施するのに利用できる。たとえばアマダ アンフオ
ルドとフオルド システム・ソフトウエアをこれらの基
本操作を行うのに利用できる。アマダ アンフオルドと
フオルド システム・ソフトウエアはアマダ・アメリカ
社(以前は社名U.S.アマダ社で業務)、ベユナ・パー
ク、カリフオルニアから入手できる。アマダアンフオル
ドとフオルド・システム・ソフトウエアについての情報
は、オートキャドのためのアマダ・アンフオルド・マニ
ュアル(1994年3月版)、キャドキーのためのアマダ・
アンフオルド・マニュアル(1994年5月版)とキャドキ
ーのためのアマダ・ウインドウズ・アンフオルド・マニ
ュアルにあり、その明細を全般的に参照することによっ
て本文書に明白に取り入れる。2-Dモデルから3-Dモデル
を作成するための折りたたみ操作については、後でステ
ップS.132を参照しながら論ずる。図11に戻って、曲
げ線検出操作をステップS.126で行った後、サーバー・
モジュール32がユーザーに対し、この後の折りたたみプ
ロセスに用いる主要な曲げと差引高(縮小量)の情報を
指令することがある。たとえば、ステップS.128で、サ
ーバー・モジュール32はユーザーに、曲げ方向(たとえ
ば前方、後方等)も含む曲げ角度及び/または曲げ内側
半径を含む各曲げ線の曲げ高(曲げ量)の指示を求める
ことがある。ステップS.130で、サーバー・モジュール3
2はまたユーザーに対し、V―幅、材料のタイプ、及び/
または差引高(縮小量)の入力を求めることがある。こ
れらの情報は、折りたたみ操作における曲げ差引高(曲
げ縮小量)を補償するのに利用できる。材料の厚さとタ
イプとともに、曲げ角度と使用するダイスのV-幅によっ
て、実際の薄板金属部品は薄板金属部品を折りたたむと
きに、差引高だけ引き伸ばされる傾向がある。
【0158】前記モデルでこの効果を補償するために、
差引高情報を利用して、折りたたみ操作で3-Dモデルを
作成するときに、曲げ線の各側で部品の面の寸法を差引
高の半分だけ引き延ばす。本発明の見地に沿って、この
差引高はユーザーによってサーバー・モジュール32に入
力(たとえばキーボード等によって)できる。あるい
は、部品の材料のタイプと厚さにもとづいた差引高を含
む材料表をオペレータに表示することができる。材料表
は、異なる曲げ角度やV―幅に対する色々な差引高を示
す。ユーザーは、サーバー・モジュール32で表示された
材料表から適切なV―幅と曲げ角度を選ぶ(たとえばマ
ウスまたはキーボードを用いて)ことによって、自動的
に差引高をセットすることができる。曲げ角度の内側半
径も、適切なV―幅を選ぶときに、材料表を介してユー
ザーによって自動的にセットできる。オペレータが入力
する(あるいはオペレータによる入力後に変換される)
差引高は、部品幾何学データを表すものと同じ長さの単
位(たとえばmm)である。折りたたみ操作時に、曲げ線
の各側の各面の長さ寸法を、注目している曲げ線の差引
高の半量だけ増やす。面の曲げ線に垂直な長さ寸法は、
曲げ線の各側にある面の境界を定める要素の終点を引き
伸ばすことによって増やすことができる。このような差
引高補償は、各折り曲げについてオペレータによって供
給された差引高にもとづいて、部品の他の曲げ線の各々
について行うことができる。
【0159】ステップS.132では、加工された2-D平面図
にもとづいて、3-Dモデルを作成するための、差引高補
償を含めた折りたたみ操作が行われる。前記のように、
折りたたみ手続きは、行列変換の使用と最終的曲げグラ
フ・データ構造で定義されたそれぞれの曲げ線を回転軸
に用いることを含む通常の幾何学的模型化法によって遂
行することができる。さらに、差引高の効果を補償する
ために、3-Dモデルを作成する折りたたみの際に、部品
の面を曲げ線の各側で差引高の半量だけ引き伸ばすこと
によって、薄板金属を実際に折り曲げるときの面の寸法
の変化をより正確に反映することができる。
【0160】たとえば、ステップS.132で折りたたみ操
作を行う時に、曲げパラメータ(たとえば曲げ角度、内
側半径)とともに、部品幾何学と形態データ(または曲
げグラフ構造)を利用することができる。2-D空間で表
わされた部品の各面、曲げ線、孔と成形についての変換
行列を計算できる。通常の行列変換を、2-D平面図に適
用することによって、3-D空間データをうることができ
る。変換は一般に回転に続く並進を含む。上記のよう
に、回転は曲げ角度の大きさに従って、各曲げ線軸の回
りに行われる。並進操作は、幾何学データを空間の中で
移したり、動かしたりすることによって行われる。この
ような並進操作は、曲げ半径、曲げ角度と各曲げの差引
高にもとづいて決められる。折りたたみの際に、差引高
補償は前述べたように曲げ線の各側で、面の寸法を差引
高の半量だけ伸ばすか増やすことによって行われる。こ
のような差引高補償は、曲げ機で曲げられる2-D薄板金
属部品の寸法を、より正確に反映する部品の3-D表現を
与える。
【0161】幾何学的モデル化と変換のさらに進んだ情
報は、たとえば、その明細を全般的に参照することによ
って本文書に明白に取り入れられているモルテンソン、
マイケル M著、幾何学的モデル化、ジョン・ワイリー&
サンズ、ニューヨーク(1988年)及びフオリーら著、ジ
ェイムス システム・プログラミング・シリーズ:会話
形コンピュータ・グラフイックスの基礎、アデイソン・
ウエスリー出版、レデイング、マセチューセッツ(1983
年)を見られたい。モルテンソンの8章には、並進と回
転を含む幾何学的変換が論じられている(たとえば345-
354頁参照)。さらにフオリーらは7章、245-265頁で、2-
Dと3-D変換の行列表示を含む、幾何学的変換の情報を与
えている。モデル化と幾何学的変換についての付加的情
報は、その明細を全般的に参照することによって本文書
に明白に取り入れられている、マンテイラ、マルッテイ
著、ソリッドモデル化入門、コンピュータ・サイエンス
出版社、ロックビル、メリーランド(1988年)にも与え
られている。座標変換に関する情報は、マンテイラの36
5-367頁にある。
【0162】次に図19を参照しながら、本発明の別の
見地に沿って、元の厚さぬきの3-D平面図にもとづいて2
-Dモデルを作成するプロセスと操作について説明する。
図11を参照しながら前に説明した折りたたみプロセス
と同様に、3-D図面を展開し、2-Dモデルを作成する色々
なプロセスや操作は、サーバー・モジュール32にあるソ
フトウエアや/またはプログラム化論理を用いて実施で
きる。図19に示されているように、顧客の仕様にもと
づいて提供され作成された元の3-D図面は、ステップS.1
40でサーバー・モジュール32に入力されるか取り入れら
れる。3-D図面はDXFまたはIGESフアイルとして格納さ
れ、サーバー・モジュール32からCADまたはCAD/CAMシス
テムとインターフエイスするか、利用するかして入力で
きる。3-D図面を入力後、ステップS.142でサーバー・モ
ジュール32によって、引き続き行われる面検出や他のプ
ロセスのための図面の準備のために、自動トリミングと
クリーンアップ操作が行われる。
【0163】図12-14に関連して論じたように、自
動トリミングとクリーンアップ機能は、部品の色々な面
が適正に検出定義されされるように、構成要素や表面を
切り離したり、連結したりする。
【0164】図11と12、13に関連した上記の自動
トリミングとクリーンアップ操作は、図19のステップ
S.140で入力した3-D図面の幾何学データに対しても、同
じように適用できる。データを2-D空間で解析する(2-D
平面図の場合のように)代わりに、3-D図面に図示され
ている各構成要素(たとえば線、弧等)は、図中の3-D
座標と空間情報にもとづいて解析することができる。交
点と開放交差領域は、各構成要素(エンティティ)を個
別的に解析し、他の構成要素の一つ一つと比較すること
によって解析できる。ここでもまた、構成要素の終点や
他の属性の基本的な幾何学的解析を用いて、許容度内で
交点と開放交差領域を決めることができる。
【0165】前記3次元図面に対しての自動トリミング
及びクリーンアップ機能を実行した後、ステップS14
4で、前記板金パーツの面の各々を検出し定義するため
に面検出操作が行なわれる。前記3次元図面についての
面検出は2次元空間における各面を分析し且つ検出し且
つ上記と同様にしてループツリーを生成することにより
行なわれる。面検出は任意の所定のエンティティで開始
することにより実行される。例えば、一番左側のエンテ
ィティ(即ち最小のx座標を有するエンティティ)が最
初のエンティティとして使用される。その後、1つの面
は前記最初の線分エンティティ及び他の連結するまたは
隣接する線エンティティ(即ち前記最初のエンティティ
と共通の端点を有する任意のエンティティ)を取出すこ
とにより定義される。面検出操作は次に、図15(a)
−16(d)に関連して上記に説明したようにループ及
びエンティティ解析を用いて行なわれる。各エンティテ
ィは前記定義された2次元平面内で検出されるため、種
々の外側及び内側ループが定義され、且つ前記エンティ
ティがマークされ(即ち前記選択されたエンティティの
フラグを設定し或いは増加することにより)、それら
が、前記面における複数のループの1つを定義する連結
されたリストに選択され且つ含まれたことを示す。
【0166】引き続くループ解析は、次に前記3次元図
面を構成する他の2次元平面において行なわれる。前記
他のエンティティのループ解析を行なうために、前記3
次元図面内でのマークされてない或いは選択されてない
エンティティを検索することにより追加の平面が定義さ
れる。そのような平面は、2つの選択されてないエンテ
ィティの間或いは選択されてないエンティティと以前に
選択されたエンティティとの間に定義される。追加の2
次元平面の各々において、更なるループ解析が行なわれ
前記内側及び外側ループを検出する。再び連結されたエ
ンティティの連結リストが保持され、前記複数のループ
経路の各々が定義されるにつれて、前記選択されたエン
ティティがマークされる(即ち前記選択されたエンティ
ティに付随するフラグを増加することにより)。
【0167】全てのエンティティが検出された後、すで
に解析された2次元平面の各々についてのループツリー
を生成するために、結果の複数のループが使用される。
すでに述べたように、ループツリーは、板金パーツにお
ける複数の面及び開口部及び穴を定義するために提供さ
れる。3次元の図面については、ループツリーは、前記
板金パーツの各面について生成される。各面内で検出さ
れた複数のループは、各ループツリーを生成するために
グループ化され分析される。各ツリーのルーツ(根)は
前記平面において検出された外側ループとして定義され
る。前記外側ループと共通のエンティティを有する前記
平面の各内側ループは前記ツールの子供として定義され
る。共通エンティティの存在は、各ループを定義する連
結されたエンティティのリストの分析及び比較に基づい
て検出される。追加のエンティティ(即ち穴或いは開口
部)が前記平面の内側ループにおいて検出される時、こ
れらのループはそれらがその内部に存在する内側ループ
の子供(即ち前記ループツリーのルーツの孫)として定
義される。生成された複数のループツリーは次に、前記
3次元図面の全ての面を検出するために用いられる。検
出された面は次に曲げグラフデータ構造におけるノード
(節)として格納される。
【0168】前記結果としての曲げグラフ構造はステッ
プS146における曲げ線検出操作の実行の後、連結す
る曲げ線連結エージェントにより補足される。曲げ線検
出操作及び最終曲げグラフ構造またはパーツ・トポロジ
ーの生成は図17及び18を参照して上記したと同様の
やり方で実行される。
【0169】上記したように、前記曲げ線検出操作を実
行するための代表的なコードがここに添付された付録C
に提供される。このサンプルコードは、2次元或いは3
次元モデルに対してなされる曲げ線検出操作のための代
表的実行例であり、曲げ線の最適選択を決定するための
ヒューリスティック(例えば上記したような)を含む。
前記曲げ線検出操作は、検出された曲げ線に満足しない
時、サーバモジュール32におけるオペレータが前記板
金パーツのための好ましい曲げ線を選択的に指定するこ
とを許すマニュアル選択特性を含む。前記オペレータ
は、マウスあるいはキーボード等のごとき適宜の入力手
段により曲げ線を維持し或いは変更することを指示す
る。前記オペレータにより選択され改定された曲げ線は
最終的2次元パーツを生成するために用いられる。
【0170】最終的曲げグラフ構造の複数の曲げ線を中
心とする展開工程を実行する前に、ユーザは、ステップ
S148でV幅、材料タイプ及びまたは縮小量について
促される。上記したように、板金は折り曲げられる時伸
びる傾向を有するため、3次元パーツの寸法は前記2次
元平面パーツのそれより少し大きい。従って、板金パー
ツの展開の過程で、パーツの寸法は、選択された材料タ
イプ及びV幅に基づく縮小量だけ縮み或いは減少され
る。従ってこの発明の1つの側面によれば、3次元モデ
ルを展開する際、前記2次元モデル及びその表面の各々
の寸法をより正確に生成するために縮小操作が行なわれ
る。上記したように、前記縮小量は、前記ユーザにより
直接入力され或いは所望のV幅及び曲げ角度を選択する
ことによりユーザが自動的に前記縮小量を設定すること
ができるように、材料テーブルが表示される。
【0171】前記オペレータにより入力される前記縮小
量は前記パーツ幾何学データにより表現されるそれと同
じ長さの単位(例えばミリメートル)である(或いはオ
ペレータによる入力の後その単位に変換される)。展開
操作の間に、前記曲げ線の両側の面の各々の寸法長さは
前記所定の曲げ線について入力された縮小量の半分だけ
減少される。前記曲げ線に直交する前記面の寸法長さは
前記曲げ線の両側に位置する前記面の境界を定義するエ
ンティティの終点を減少することにより減少される。前
記縮小補償は、各曲げについて前記オペレータにより提
供される前記縮小量に基づいて、前記パーツの他の曲げ
線のそれぞれにおいて行なわれる。
【0172】前記全ての必要なデータの入力の後、ステ
ップS150で、前記2次元モデルを生成するために展
開プロセスが行なわれる。前記3次元曲げモデルを展開
するために通常の方法が用いられ、それは前記複数の曲
げ線の各々を回転軸として用いるマトリックス変換の使
用を含む。この展開プロセスの間に各曲げ角度が測定さ
れ、前記平面曲げモデルを生成するために前記曲げ角度
量だけ前記パーツは展開される。更に、前記入力された
縮小量に基づいて、前記板金材料の物理的性質及び前記
3次元及び2次元モデルの間の差をより正確にシミュレ
ートするために、前記曲げ線の両側で前記縮小量の半分
だけの前記面の寸法の縮小或いは減少が行なわれる。
【0173】ステップS150で前記展開工程を実行す
る時、前記パーツの寸法及びトポロジーデータ(または
曲げグラフ構造)が前記曲げパラメータ(例えば曲げ角
度、内側半径等)と共に用いられる。前記3次元空間に
おいて表現された前記パーツにおける各面及び曲げ線及
び穴及び成形部についての変換マトリックスが計算され
る。通常のマトリックス変換が前記2次元空間データを
得るために前記3次元データに対して適用される。前記
変換は一般的に回転を含み、その後に並進がくる。上記
したように、回転は、曲げ角度量に応じて各曲げ線の周
りに行なわれる。展開のために、2つの面の間に180
°が存在するまで(即ち面が平面になるまで)回転は逆
方向に行なわれる。並進は空間内で前記幾何学的データ
をシフトし移動するために行なわれる。そのような並進
は、各曲げについての前記曲げ半径及び曲げ角度及び縮
小量に基づいて決定される。展開の間、縮小補償は上記
したように、曲げ線の両側で前記縮小量の半分だけ前記
複数の面の寸法を縮め或いは減少せしめるために行なわ
れる。そのような縮小補償はそれが曲げ工程の間に折り
曲げられる前の前記板金パーツの寸法をより正確に反映
する前記パーツの2次元表示を提供する。
【0174】再び幾何学的モデル化及び変換についての
情報はモルテンソン、フォリー等及びマンティラに見出
される。上記したように、モルテンソンの8章は変換及
び回転(例えば345〜354頁を見よ)を含む幾何学
的変換の議論を提供する。更にフォリー等は、7章の2
45〜265頁で2次元及び3次元変換のマトリックス
表示を含む幾何学的変換についての情報を提供する。更
に座標変換についての情報はマンティラの365頁〜3
67頁に見出される。
【0175】図4を参照して上記したように、前記顧客
の注文に基づいて、2次元3面図或いは厚さを有しない
3次元ワイヤフレーム図が最初に提供され或いは生成さ
れる場合、厚さを有しない3次元モデルを生成するため
に更なる工程が必要とされる。そしてその後、前記厚さ
を有しない生成された3次元モデルは展開プロセス或い
はアルゴリズムを適用することにより2次元モデルを生
成するために用いられる。図20−24は、最初の2次
元3面図に基づいて3次元モデルを生成するために適用
される種々のプロセス或いは操作を図示する。更に図2
5は、この発明の他の側面に応じて、厚さを有する最初
の3次元ワイヤフレーム図から厚さを有しない3次元モ
デルを生成するために適用される追加のプロセス或いは
操作を図示する。再び、図20−25において図示され
る種々のプロセス及び操作は、例えば前記サーバモジュ
ール32に存在するソフトウエア及びまたはプログラム
論理により実行される。
【0176】図20を参照するに、この発明の教示に応
じて、最初の2次元3面図に基づいて3次元モデル(厚
さを有しない)を生成するために行なわれる操作或いは
プロセスの論理フローの記載が提供される。最初、ステ
ップS160で2次元3面図がサーバモジュール32へ
入力され或いは搬入される。前記最初の2次元3面図
は、前記パーツの種々の図(例えば正面図及び平面図及
び右側面図、例えば図22(a)及び22(b)を見
よ)を含み、前記サーバモジュール32へダウンロード
され或いは搬入されるDXF或いはIGESファイルの
ごときCAD図面である。しかる後、ステップS162
で、前記3次元モデルへの引き続く操作のための図面を
作成するために、サーバモジュール32により2次元ク
リーンアップ操作が行なわれる。この2次元クリーンア
ップ操作は、前記パーツの実際の幾何学形状を表現しな
い余分な及び非幾何学的な情報、それはテキスト及び中
心線及び寸法線を含む、を消去するために行なわれる。
前記2次元クリーンアップ操作はまた全ての外側線分
を、例えばそれらの接続端部で接続し、或いは任意の交
差するライン或いはエンティティを分断し或いはトリミ
ングするために行なわれる。図21は、前記サーバモジ
ュール32により前記クリーンアップ操作が行なわれる
際実行される種々のプロセスの論理フローの例を図示す
る。
【0177】図21に示されるように、最初に2次元図
面が前記サーバモジュール32により、ステップS18
0でデータファイルから読み取られ或いはロードされ
る。しかる後ステップS182でサーバモジュールは、
2次元図面において各々のエンティティ或いは幾何学デ
ータを分析し次の工程のための図面を作成するために種
々のエンティティを分割する。ステップS182におい
て行なわれる前記分割或いはトリミング機能は、この発
明の前記自動トリミング及びクリーンアップ機能に関連
して上記に記載したと同様な方法で実行される。従って
ステップS182で前記2次元3面図における全ての幾
何学的データは、エンティティの交差点及び所定の誤差
範囲内にある空白(開放)交差部を検出するために分析
される。任意の交差線は分断され、結果のエンティティ
は交差点により定義される共通の終点で出会う。更に所
定の誤差の範囲内にある(例えば0.0−0.01mm
或いは0.0−0.001インチ)空白交差領域を有す
るエンティティについてはそれらのエンティティは、例
えば図12―14に関連して上で記載されたと同様の方
法で結合される。
【0178】ステップS184で前記2次元図面シート
の周辺が検索され任意の外部の線分またはデータ(例え
ば境界線分及び座標格子及び数字等)が消去される。図
22(a)に示されるように2次元3面図は、しばしば
図面シート上に提供される。前記図面シートは前記板金
パーツの種々の図面を生成するために必要でない余分な
及び非幾何学的な情報を含む。従ってステップS184
で、本発明の2次元クリーンアッププロセスを利用し
て、前記3次元モデルを展開するにあたってこのタイプ
の情報が検出され前記2次元図面から消去される。
【0179】前記2次元図面データはそこに含まれるデ
ータのタイプ(例えば幾何学的或いは非幾何学的/テキ
スト)を指示するためのキーワード或いはタイプフィー
ルドを含む。従ってこれらのキーワードあるいはタイプ
フィールド(それらは図面ファイルのデータフォーマッ
トに基づいて提供される)はテキスト或いは他の非幾何
学的データのごとき種々の余分の情報を削除するために
用いられる。しかし全ての不必要な図面シートデータを
正しく削除するためには更なる操作が通常必要である。
しばしば、前記境界線或いは他の外側情報はエンティテ
ィー(例えば線分等)として保存され、それらは前記デ
ータキーワード或いはタイプフィールドに基づいて容易
に識別することができない。従ってこの発明の1つの側
面によれば、前記2次元図面のデータを分析する際に連
結性グラフ構造が生成される。この連結性グラフ構造は
各エンティティーについて複数の付随的頂点のリスト及
び連結されたエンティティーのリストを示す。各頂点に
ついては、隣接する複数の頂点のリスト及びそれが付随
するところのエンティティーのリストが提供される。こ
のグラフ構造により、(それはステップS182の分断
及びトリミング機能を実行する際に生成されるが)、ど
のエンティティーがくっつき合う終点により結合される
かが決定される。結果として、境界線及び情報ボックス
及び他の非幾何学的データのような余分なデータは削除
される。これは、このデータは典型的に連結されたエン
ティティーで構成されることがなくまたそれを含まない
からである。
【0180】上記したように、2次元3面図は寸法線及
び矢印線及び中心線及びテキストのような余分の情報を
含み、それらは前記パーツの実際の幾何学形状を表現し
ない。これらのエンティティーはステップS186で検
出され、次の工程のための2次元図面を作成するために
前記2次元データファイルから削除される。これらの余
分のエンティティーの検出はサーバモジュール32によ
り自動的に行なわれる(例えば前記パーツの実際の幾何
学形状に関連しない2次元データファイル中の項目を検
出することにより)。例えば、前記連結性データグラフ
構造を用いて、両端が開放されたエンティティー(例え
ばテキストにアンダーラインをするため或いは寸法或い
はパーツの中心線を示すために用いられる複数の線)が
検出され消去される。矢印のごとき他のエンティティー
もまた、浮動する終点或いはそのようなエンティティー
の他の特徴の存在に基づいて検出される。全ての不必要
なデータを効果的に削除するために、サーバモジュール
32は前記2次元図面中のいずれの項目が消去されるべ
きかを(例えばマウスまたはキーボードにより)オペレ
ータをして指示することができるようにするためのマニ
ュアル編集機能を提供する。オペレータのこの援助或い
は確認により、追加の余分の情報が図面から除去され
る。
【0181】ステップS186の後、前記2次元図面の
種々の図が、ステップS188でグループ化され且つそ
れぞれ定義される。この発明の1つの側面によれば、サ
ーバモジュール32は、図22(b)及び23(a)に
示されるような平面図(上面図)及び正面図、右側面の
配置のごとき、予め定められた或いは標準的な図と向き
をサポートする。平面図及び正面或いは背面図及び右或
いは左図のような他の図及びレイアウトもまたサポート
され得る。更に以下に記載されるように、サーバモジュ
ール32はまた前記2次元図面の図を前記パーツの3次
元表現へ加工するために、回転された図(例えば図23
(a)を見よ)もサポートする。いずれにしても、パー
ツの3次元モデルが構成されるためには、厚さ表現を有
するパーツの少なくとも2つ(そして好ましくは3つ)
の異なる図が提供される必要がある。連結性グラフ構造
において前記エンティティーの連結性及びグループ化を
解析することにより、サーバモジュール32は、複数の
図の各々の相対的位置及び/又は座標位置に基づいて前
記複数の図を分類し且つ定義する。
【0182】限定しない事例として、サーバモジュール
32による前記図の定義は、予め定義された或いは通常
の配置或いは前記データファイルにおける図の解析をす
るためのレイアウトにより、及び/又は前記複数の図の
向きの検出及び前記図面の各々の図のそれぞれにおける
前記パーツの種々の寸法の重ね合わせに基づいて実行さ
れる。図23(b)において示されるそれのごとき予め
定義された或いは標準的フォームは、潜在的な図のタイ
プに応じて前記図の各々を決定し定義するために用いら
れる。種々の終点及び各グループを定義する複数のエン
ティティーの間の関係の幾何学的比較は、前記ステップ
S188を実行するために行なわれる。サーバモジュー
ル32の図検出特性(図検出機能)は、複数の潜在的図
面タイプ(例えば平面図、正面図、背面図、左図、右
図)の1つに応じて前記図面の各々にラベルを付ける。
前記複数の図の各々の検出は、予め定義された或いは標
準的図の配置或いは形状及び存在する図の各々の間の検
出された関係に基づく。種々の工程或いは操作が、ステ
ップS188で、前記2次元3面図における複数の図を
分類し且つ定義するために使用される。例えば前記加工
された2次元3面図にアクセスした後、前記サーバモジ
ュール32はまずこの図面データにおけるパーツの平面
図を特定する。前記平面図は、予め定義された或いは標
準的な形状または図配置(例えば図23(b)における
それのような)に基づいて検出される。仮に3つの異な
る図が水平方向或いは垂直方向において検出される場合
には、中央の図が平面図であると定義される。更に仮に
3つの別個の図が検出されず且つ垂直方向においてただ
2つの別個の図が検出される場合には、上側の図が平面
図であると定義される。再び前記連結性グラフ構造にお
ける前記エンティティーの連結性及びグループ化が前記
複数の図の各々を検出するために使用される。前記予め
定義された或いは標準的形態を表現する、格納されたル
ックアップテーブル或いはマトリックスが前記2次元図
面の各図を比較し且つ複数の図の各々を検出するために
用いられる。
【0183】前記2次元3面図データから平面図を検出
した後、前記パーツの他の図は前記検出された平面図に
対する前記複数の図の各々の相対的位置に基づいて検出
される。例えば、図23(b)の標準的レイアウトに基
づいて、例えば図グループが前記平面図の上に位置して
いる場合には、その図は背面図であると定義される。し
かしもし図グループが前記平面図の下に位置している場
合には、その図は前記パーツの正面図であると定義され
る。更に右図及び左図は、前記平面図のそれぞれ対応す
る右側及び左側におけるそれらの相対的位置に基づいて
検出される。しかる後、前記標準的形態(例えば図23
(b))に合致しない任意の残りの図は前記検出された
図(例えば検出された背面図或いは正面図)に対するそ
れらの相対的位置に基づいて検出される。例えば図23
(a)に示されるレイアウトBについて、前記右図は前
記平面図に対して回転された位置に設けてある。しかし
ながらレイアウトBにおける右図は前記検出された正面
図に対するその関係に基づいて検出される。即ち検出さ
れた背面図或いは正面図の右側或いは左側に存在する検
出されていない図はそれぞれ前記パーツの右図或いは左
図として定義される。
【0184】種々の予め定義された或いは標準的な図の
レイアウトが前記2次元3面図図面において複数の図を
検出し且つ定義するために用いられる。標準的な形態
(例えば図23(b)または図23(a)におけるそ
れ)は、製造設備において広く行き渡っており或いは選
択され/要求される図レイアウトに基づいて、及び/又
はサポートされている図タイプの基づいて選択される。
仮にいずれの図も検出されない場合には、サーバモジュ
ールにより警告信号が提供され、オペレータは、好まし
い図面レイアウトに応じて前記2次元3面図データを変
形したり、他の適当な動作を行なう。前記2次元図面に
おける複数の図を検出するための予め定められた或いは
標準的形態の提供に加えて、予め定められた標準的形態
(例えば図23(a)のレイアウトAのように)は検出
された図を加工し前記パーツの3次元モデルを生成する
ために設けられる。従って更なる加工が行なわれる前に
前記標準的形態に基づいて検出された図を正しく分類す
るために、回転された図の特徴が提供される。
【0185】上記したように、前記2次元クリーンアッ
プ操作は図面において複数の図を検出するための予め定
められた、或いは標準的形態に合致しない回転された複
数の図をサポートし且つ検出する。回転された図のオプ
ションでは、検出された標準的でない複数の図は、パー
ツの3次元モデルを加工し且つ生成するために、前記複
数の図の各々が前記予め定められた或いは標準的な図の
形態に合致するように、回転され或いは並行移動され
る。前記パーツの複数の図を検出するために図23
(b)に図示されるそれのような標準的形態を仮定し
て、図23(a)におけるレイアウトBにおける複数の
図の各々は、上記したように、前記平面図及び他の検出
された図に対する当該複数の図の相対的な位置に基づい
て検出される。例えば仮に図23(a)のレイアウトA
が、平面図及び正面図及び右図を有する2次元図面にお
ける種々の図を加工するための予め定められた或いは標
準的図レイアウトとして使用される場合、ステップS1
88でレイアウトBにおける右図は90度回転されレイ
アウトAと同様な、前記パーツの変形された図レイアウ
トを提供する。前記パーツの右図が前記パーツの平面図
の右側に位置するように前記レイアウトBにおいて右図
を90度回転することにより、図面中の前記複数の図は
レイアウトAで表現される標準的な形態に応じて加工さ
れる。格納されたルックアップテーブル或いは予め定め
られた或いは標準的な形態を表現するマトリックスが、
前記2次元図面の複数の図を比較し且つどの図が回転或
いは並進運動を必要とするかを決定するために用いられ
る。
【0186】前記2次元図面における複数の図から前記
パーツの正確な3次元モデルが生成されることを保証す
るために、前記複数の図の各々においてそれぞれの寸法
が相互に矛盾がないか或いは一致しているかチェックさ
れる。図21において更に示されるようにステップS1
90で前記データファイルにおける前記複数の図の境界
が、それぞれの図の全ての寸法が相互に同じ寸法である
かを確認するために検出される。仮に複数の図が所定の
誤差の範囲内で(例えば0.0−0.01インチ)一致
しないことが判断されるとステップS190で、全ての
複数の図が同じスケールになるように任意の特定の図の
寸法を変更するために適宜の修正が行なわれる。図面の
寸法が相互に一致せず現在存在する2次元図面データに
対して必要な修正が行なわれるようにユーザに警告する
ためにサーバモジュール32に警報要素が設けられる。
【0187】前記パーツの各々の図における寸法の一貫
性を検出し且つ確認するために種々の操作或いは工程が
使用される。例えば、前記複数の図の各々の対応する寸
法が、それらが相互に所定の誤差の範囲内にあるかどう
かを決定するために比較される。そのような解析は、前
記パーツの各図の境界線を定義する線分エンティティー
を比較することを含む。図23(b)における標準的な
形態を仮定して以下のようであれば平面図は右図または
左図と一致すると検出される。即ちそれぞれの図につい
て、最大Y座標位置と最小Y座標位置が所定の誤差範囲
(例えば0.0−0.01インチ)内にある。更に前記
平面図は、以下の場合には正面図または背面図と一致す
ると検出される。即ち各図について、最大X座標位置と
最小X座標位置とが所定の誤差範囲(例えば0.0−
0.01インチ)内にある。更に左図または右図は、最
大Y座標位置と最小Y座標位置との間の差に比較して最
大X座標位置と最小X座標位置との差が所定の誤差範囲
(例えば0.0−0.01インチ)内にあれば正面図ま
たは背面図と一致すると決定される。再び前記図の寸法
或いは関連する面の寸法が一致しないとき前記2次元図
面データに対して必要な修正が加えられるようにユーザ
に警告するように、サーバモジュール32に警告要素或
いはモジュールが設けられる。
【0188】最後にステップS192で、本発明の面検
出方法の教示に基づいて、前記パーツの内側ループ及び
穴及び形状が検出される。各図の複数の面の内側に設け
られている種々の穴或いは形状は、前記パーツの種々の
線及び境界を通ってパーツの外側から中央へ向かってル
ープを形成していくことにより検出される。ループ及び
エンティティーの分析は、前記2次元図面における前記
パーツの各図に対してなされる。前記パーツの外側から
作用的に中央へ向かって内側へ各々の図を分析すること
により、検出されたループは前記パーツの物質と開口部
の境界及び領域を、周期的順番(即ち物質、開口部、物
質等)に基づいて決定する。図16(d)におけるそれ
のごときループツリーが複数の面の位置及び各々の面の
内部の任意の穴の位置を決定するために各図面について
生成される。浮遊する円弧或いは線分のごとき前記パー
ツの面の内部で連結されないエンティティーは、ステッ
プS192の中で検出され消去される。
【0189】本発明の前記2次元クリーンアップ操作を
行なうための代表的なコードは付録Dに提供される。こ
のコードはC++プログラム言語で記載されており、そ
こに使用される論理及びアルゴリズムの解析を円滑にす
るためのコメントを含む。そのコードは、図21−22
(b)を参照して上で議論したそれらのごとき、2次元
クリーンアップモードの種々の工程及び操作を含む。
【0190】図20を再び参照するに、2次元クリーン
アップ操作が行なわれた後論理フローはステップS16
4へ連続しそこで前記2次元図面が材料の厚さを表現し
または含むか否か(即ち前記2次元図面が厚さを有する
か否か)が決定される。もし前記2次元図面が厚さの量
を含むと判断される場合には、ステップS166で3次
元モデルへの引き続く操作のための2次元図面を作成す
るためにサーバモジュール32により厚さ消去手続きが
行なわれる。前記2次元図面における厚さの存在の判断
は図面のデータに基づいてサーバモジュール32により
自動的に行なわれ、或いはオペレータからの援助或いは
応答を介して前記サーバモジュールにより行なわれる
(オペレータは厚さ除去が必要であるか或いは好ましい
かを指示するように促される)。前記パーツの厚さは全
ての板金パーツの独特の対称性により消去される。前記
パーツの厚さを消去することにより、厚さを有しない、
結果としての板金パーツは板金オペレータ或いは設計者
により、より容易に分析される。更にこの出願の発明者
は、前記2次元3面図の厚さを除去することにより、2
次元図面を変換し3次元モデルを生成するに必要な時間
が著しく短縮されることを見出した。
【0191】殆どの2次元3面図は材料厚さ量を含むた
め、オペレータはしばしば、2次元図面から3次元モデ
ルを作成するためにいずれの曲げ線が選択されなければ
ならないかで混乱する。結果として、2次元3面図が3
次元モデルへ変換されるように適切な曲げ線を選択する
際に相当の時間が無駄になる。厚さを有する2次元3面
図の例が図24に示されている。この発明の1つの側面
によれば、材質厚さを持つことなく表現され且つ処理さ
れるが、当該材質厚さ量及び前記パーツの内側及び外側
寸法を曲げモデルデータ中に保有する簡単化された2次
元3面図モデルを表示するように、厚さ除去手続きが設
けられている。図24(b)は前記厚さ除去工程を行な
った後、前記サーバモジュール32において前記オペレ
ータに対して観察され且つ表示される簡単化された2次
元3面図を図示する。
【0192】前記厚さ除去手続きが実行される時、ユー
ザは、2次元3面図表示における材質厚さを特定するよ
うに促されてもよく、また前記表示内においていずれの
寸法(即ち外側寸法或いは内側寸法)が保持されるべき
であるかを特定するように促されても良い。オペレータ
は、例えばマウスを用いて複数の図の中の1つにおいて
保持される厚さ及び表面を指示する。このユーザにより
入力されたデータに基づいて、サーバモジュール32は
前記2次元3面図を修正し、ユーザにより指示された材
料厚さを消去し、前記オペレータの選択に基づいて内側
或いは外側寸法を残す。
【0193】前記2次元3面図図面において厚さを消去
するために、前記サーバモジュール32は前記オペレー
タにより行なわれた選択に基づいて前記3つの図の各々
を分析する。選択された表面は幾何学的計算により(即
ち選択されたエンティティー線分或いは表面と同じX座
標或いはY座標射影に存在する対応するエンティティー
を検出することにより)他の図の1つへ射影され、前記
複数の図の各々における対応するエンティティー及び線
分を検出する。対応するエンティティーは、マークされ
且つ保持され、合致しないエンティティー或いは表面は
削除され或いは図24(b)に示されるそれのように、
スクリーン上に表示されない。更にオペレータにより指
示される厚さ寸法線は他の図の各々へ同様に射影され、
合致する厚さ寸法線或いはエンティティーは図24
(b)の例に更に示されるように削除される。結果とし
て、図面内の複数の図の各々は適宜に修正され、前記サ
ーバモジュール32においてユーザに対して表示され
る。厚さを有しない、結果としての2次元3面図は前記
パーツの3次元モデルを生成するために次の工程で使用
される。
【0194】この発明の厚さ削除手続は、各図において
削除されるべき厚さ線及び残されるべき表面エンティテ
ィーをオペレータが選択的に指示するようにするための
マニュアル厚さ消去モードを含む。表示された図の各々
においてどの領域が削除されるべきであり、どの表面が
残されるべきであるかを指示するためにマウス或いは他
の適当な入力装置がオペレータにより使用される。前記
オペレータにより入力されるデータに基づいて前記サー
バモジュール32は、厚さを有しない図面を提供するた
めに、前記2次元3面図からオペレータにより選択され
る各線分エンティティーを削除する。
【0195】この発明はまた全ての厚さ表現が前記2次
元3面図図面において正しく特定されたか否かを分析し
且つ検出し且つ、マークされない厚さ要素が存在する時
及び/又は図面データ中に矛盾が存在する時、ユーザに
警告するための警告システム或いはモジュールを含む。
例えば厚さ警告要素は、前記表示スクリーン上で潜在的
なマークされない厚さ部分を強調するために設けられ、
面警告要素は面の寸法が他の図における厚さのマークと
一致しない時、前記スクリーン上で潜在的な一致しない
面を強調するために設けられる。曲げ線警告要素は、ま
た矛盾する曲げ線を強調し及び一致しない厚さ曲線を強
調するために設けられる。曲線は、この曲線上に射影さ
れる少なくとも1つの曲げ線が2つの横断厚さ線分(厚
み横断線)により挟まれないとき強調される。例えば図
24(c)は、2つ或いは他の零でない偶数の横断厚さ
線分(即ち各図において厚さを横断する短い線)により
正しく挟まれている厚さ曲線を図示する。各曲げ線は2
つ又は他の零でない偶数の横断厚さ線分により挟まれる
べきである。各図面における前記パーツのこれらのエン
ティティーの分析は、ループ分析を実行し且つ各図を作
り上げる線分及び円弧エンティティーの連結性を解析す
ることに基づく。開放された厚さ線分は他の厚さ線分或
いは曲線と接続しない少なくとも1つの端点を有する厚
さ線分に基づいて定義される。1つの開放厚さ線分を含
むサイドは開放厚さサイドと定義される。厚さ線分は、
開放厚さ線分の開放厚さサイドが最小ループの境界ボッ
クスに一致しない場合に強調される。前記加工された2
次元3面図の像に関連する警告をユーザに与えることに
より、ユーザは図面データ中の矛盾を警告され、ユーザ
はパーツの3次元モデルを生成するために更に加工を行
なう前に、前記図面データを修正及び/又は訂正するこ
とができる。そのような警告システム及びユーザとの相
互作用を含むことが3次元モデルによる前記パーツの表
現の精密さを改善する。
【0196】図20のステップS168で、厚さを有し
ない加工された2次元3面図図面は3次元モデルへ変換
され発展させられる。2次元3面図図面から前記3次元
モデルへの変換及び展開は良く知られ或いは確立された
射影及び/又は突出方法を用いて行なわれる。例えば前
記2次元3面図から3次元モデルを生成するために、各
図の深さが検出され3次元モデルを展開するために各図
が射影される。結果としての3次元モデルは次に曲げモ
デルデータを生成する際に使用され、また上記した展開
アルゴリズムを適用することにより単一の2次元平面図
へ変換される。幾何学的モデル化技術についての更なる
情報については、モルテンソン、フォリー等及びマンテ
ィラを見よ。2次元図面から3次元モデルを構成するた
めの射影技術についての追加の情報については例えば以
下を見よ。ウェズレイ等,W.A.「投影図の肉付け」
I.B.M.J,RES,DEVELOP、25巻、N
O.6、934―954頁(1981)、アオムラ・シ
ゲル、「機械的図面を用いてソリッドモデルを形成する
こと」第6回コンピュータメカニクスコンファレンス、
JSME、NO.930−71、日本、497−98頁
(1993)、アオムラ・シゲル、研究及び実際使用の
最近の傾向及び将来の可能性(図面から3次元モデルの
自動的再構成)東京工学株式会社、日本、6−13頁
(1995)。これらの開示はここにそれらの全てにお
いて明示的に取り込まれる。
【0197】ステップS168で3次元モデルを展開す
る際、結果としての3次元モデルを更に加工し且つ精密
化するために追加のクリーンアップ工程が含まれる。こ
の発明の1つの側面によれば、3次元クリーンアップ工
程は、前記パーツの2次元3面図において存在し且つ前
記パーツの生成された3次元表現において余計な或いは
過剰な情報を生成する不明瞭さを補償するために設けら
れる。当業者に理解されるように、パーツの2次元3面
図表現は3次元座標空間における前記パーツの種々の特
徴の表現に関連して不明瞭さを含む。前記2次元3面図
から3次元モデルを生成する際余計な且つ過剰な情報が
これらの不明瞭さの結果として生成される。従ってこの
発明の側面によれば、前記3次元クリーンアップ工程
は、1つの端部がつながっていない線分を検出し且つ除
去すると共に曲げ線を検出し且つきれいにすると共に面
をトリミングする工程を含む。前記3次元クリーンアッ
ププロセスは前記パーツの結果としての3次元モデルを
生成する際に自動的に行なわれ或いは前記生成された3
次元モデルが追加の工程を要求すると判断される時、オ
ペレータからの入力に基づいて選択的に行なわれる。
【0198】前記3次元クリーンアップ工程によれば、
前記生成された3次元図面データを分析することによ
り、一端部において他のエンティティーと接続されない
と判断される全ての線分或いは曲線が特定され片側開放
線分として定義される。片側開放線分であると判断され
る任意のエンティティーは前記パーツの3次元表現から
除去される。一旦開放線分が除去されると、それは他の
線分或いはエンティティーが開放されることを導くかも
しれない。従って新しい片側開放線分がまた特定され、
全ての開放線分或いはエンティティーが除去されるま
で、繰り返し除去される。図63は片側開放線分が除去
される前のパーツの3次元表現の例を図示し、図64は
片側開放線分が前記3次元表現から除去された後の前記
パーツを図示する。
【0199】上記したように、ステップS168で行な
われる3次元クリーンアップ工程は曲げ線を検出しきれ
いにする工程も含む。曲げ線は、3次元空間におけるパ
ーツの面情報の検出を促進するために特定され且つきれ
いにされる(例えばモールド線分を加えることによ
り)。前記生成された3次元モデルデータに基づいて、
各曲げ線は、それぞれの中心により定義される同一の法
線を有する一対の3次元曲線(例えばそれは図面データ
における曲線エンティティーにより表現される)の検出
に基づいて同定される。この過程において、特定された
前記曲げ線に対してモールド(形取り)線分が付加され
る。前記モールド線分は、3次元曲線の各対において対
応する終点を特定し且つ前記3次元曲線の対応する終点
の間でモールド線分(例えば線分エンティティーで表現
される)を延長することにより追加される。図65は曲
げ線が特定される前のパーツの代表的3次元表示を図示
し図66は前記モールド線分(図において破線で表現さ
れる)が追加された後のパーツを図示する。
【0200】曲げ線が特定され且つモールド線分が追加
された後、3次元クリーンアップ工程は更に前記パーツ
の全ての曲げ線をきれいにし且つ面をトリミングするた
めに前記パーツの3次元表現を加工する。前記2次元3
面図データの図における頻繁に生ずる不明瞭さにより、
前記パーツの3次元表現に前記面の過剰な部分が生成さ
れる。前記3次元クリーンアップ工程は前記面の過剰な
部分を特定しそして板金領域知識(例えば何が折り畳め
ないかについての知識)を用いて前記面をトリミングす
る。余分な穴或いは開口部のような他の余分な情報も特
定され除去される。結果として前記パーツの過剰な部分
は除去され前記3次元表現は前記板金パーツのより精密
な表現を提供する。図67は前記曲げ線をきれいにし且
つ前記面をトリミングする前のパーツの代表的な部分を
図示し、図68は正常化及びトリミングがなされた後の
パーツの前記部分を示す。
【0201】図25は材料厚さを持つ最初の3次元図面
から材料厚さを持たない3次元図面を生成するためにな
される工程及び操作の論理フローの例を示す。ステップ
S200で、材料厚さを有する最初の3次元図面が入力
されサーバモジュール32へ搬入される。前記3次元モ
デルは材料厚さを有する3次元のワイヤフレーム図面
で、DXF或いはIGESファイルのごときCAD図面
ファイルである。前記3次元図面が前記サーバモジュー
ル32へ搬入された後、厚さ除去工程がステップS20
4で行なわれる。ステップS204における前記3次元
モデルに対する厚さ除去工程は上記したアマダUNFO
LDソフトウエア・システムにおいて提供されると同じ
方法で行なわれる。前記3次元モデルにおいて厚さを消
去するために、オペレータはまず厚さを指示し且つ残さ
れる面を選択するように促される。このオペレータの選
択に基づいて厚さを定義するエンティティー線分の終点
を解析することにより厚さが測定される。しかる後、選
択された表面の境界が、前記ループ及びエンティティー
解析工程に関連して上記したと類似の方法により探索さ
れる。そして保持されるエンティティーはマークされ
(例えばフラグを設定し或いは増加することにより)、
対応する厚さエンティティーは除去される。前記3次元
パーツのエンティティーを探索する際、前記エンティテ
ィーは、ユーザにより選択された厚さエンティティーの
長さに基づいて識別される。一般的に前記厚さエンティ
ティーと同じ長さを有する全てのエンティティーは選択
されず除去され、同じ長さでない他のエンティティーが
マークされ残される。前記3次元パーツの表面の探索で
マークされなかった残りのエンティティーもまた除去さ
れることがある。再びサーバモジュール32はマニュア
ル厚さ除去モードを提供し、そこではオペレータは除去
されるべき3次元パーツにおける各エンティティーを手
動で指示する。
【0202】ステップS204の後、厚さを有しない、
結果としての3次元モデルがステップS206で展開さ
れ及び/又はオペレータに対して表示される。展開アル
ゴリズム或いは工程が次にその材料厚さを有しない3次
元モデルに適用され上に詳細に説明したように、曲げモ
デルデータについての単一の2次元平面図を生成する。
上記したように前記データベース30に格納されるデザ
イン及び製造情報は、板金要素についての製造データの
みならず板金の幾何学形状及びトポロジーを含む曲げモ
デル・データファイルを含む。更にこの発明の種々の特
徴を実行するために使用されるソフトウエアはC++の
ごとき高度のプログラム言語を用い且つオブジェクト指
向プログラム技術を用いて生成される。この発明の種々
の特徴を実行するためには、Booch或いはOMTの
ごとき異なるオブジェクト指向技術も使用される。オブ
ジェクト指向プログラムが使用される場合は、前記板金
パーツを表現するためにオブジェクト指向データが使用
され、前記パーツのための曲げモデルは完全に自己充足
的クラス・ライブラリを介して実行される。この発明の
1つの側面により、オブジェクト指向プログラム技術に
基づく、前記曲げモデルのための代表的データ構造及び
アクセス・アルゴリズムの記述が提供される。図26
は、本願発明をオブジェクト指向プログラムにより実行
する際使用される前記曲げモデルの代表的データ構造及
びアクセスアルゴリズムを図示する。オブジェクト指向
プログラムは、データを含む複数のオブジェクト或いは
モジュールのみならずそのデータに作用する複数の指示
を結合することにより現実世界をモデル化することがで
きるソフトウエア展開の1つのタイプ或いは形態であ
る。オブジェクト指向プログラムにおいては、オブジェ
クトは板金パーツのごとき、何か物理的なものをモデル
化するソフトウエアエンティティーであり、或いはそれ
らはビジネス上の商取引のごとき仮想的な何かをモデル
化するものである。オブジェクトはそのオブジェクトの
状態を集合的に定義する1つもしくはそれ以上の属性
(即ちフィールド)を含み、且つ全ての他のオブジェク
トからそれを識別するための識別子を含む。更にオブジ
ェクトはある種の条件の存在に基づいて、前記属性を修
正し或いは前記オブジェクトに対して作用をなす一群の
方法(即ち手続き)により定義される振る舞いを含む。
【0203】この発明の実施例によれば、前記板金パー
ツはオブジェクト指向データモデルとして表現される。
図26に示されるように板金パーツの曲げモデルは完全
に自己充足的なクラスライブラリとして定義される。前
記板金パーツのための全ての要求されるデータ操作及び
機能(例えば折曲げ、展開等)はこのクラスライブラリ
の要素機能として取り込まれる。全ての幾何学的或いは
トポロジーデータは前記曲げモデルの中で分類される複
数のオブジェクトの内部で定義される。前記曲げモデル
クラスライブラリは複数のクラス或いはオブジェクトの
階層であり、パーツクラスはその階層の最上レベルのク
ラスである。前記パーツクラスは種々のパーツ属性を有
するパーツオブジェクトを含み、前記パーツ及び前記パ
ーツに対してなされる複数の作用を定義する種々のオブ
ジェクトを含む。
【0204】図26は、前記曲げモデルクラスライブラ
リにおいて分類される種々のオブジェクトの例を示す。
例えば種々の属性52を含むパーツクラス50が提供さ
れる。前記パーツ属性52はパーツ番号及び/又は名
前、パーツ材料タイプ及びパーツの厚さのごとき種々の
パーツ情報を含む。前記属性52はまた、複数の曲げが
なされる順番を指示するための曲げ順情報及び前記パー
ツの種々の寸法についての誤差要求のごとき他の製造情
報を含む。前記パーツクラス50はまた図26に示され
るように面オブジェクト54、穴オブジェクト56、成
形部オブジェクト58、及び曲げ線オブジェクト60の
ごとき種々のオブジェクトを含む。前記オブジェクト5
4,56,58及び60の各々はそこに表現されたエン
ティティー(例えば面、穴、成形部、及び曲げ線)の各
々についての一群のオブジェクトからなる。前記面オブ
ジェクト54、穴オブジェクト56、成形部オブジェク
ト58、及び曲げ線オブジェクト60はそれぞれ幾何学
形状及び寸法データ、2次元及び3次元空間表現におけ
る位置及び座標データ、及び前記パーツのそれらの各エ
ンティティー(例えば面、穴、成形部、及び曲げ線)の
端及び表面に関連するデータを含む。例えば、前記面オ
ブジェクト54は、前記複数の面の各々についての幾何
学形状及び寸法データ、2次元及び3次元表現における
前記複数の面の空間位置データ、及び前記複数の面の端
及び表面についての端及び表面データを含む。更に、成
形部オブジェクト58は、前記パーツにおける特殊な成
形部に関連するデータを含み、このデータは幾何学形状
及び寸法データ、2次元及び3次元空間位置データ、及
び端及び表面データを含む。
【0205】図26の実施例に更に示されるように、パ
ーツクラス50は更にトポロジー・オブジェクト62及
び曲げ特性オブジェクト64を含む。前記トポロジーオ
ブジェクト62は、前記パーツの前記面、穴、成形部及
び曲げ線についてのパーツトポロジーデータを含む。前
記トポロジーオブジェクト62におけるデータは前記パ
ーツの前記種々の特徴の構造的及び幾何学的関係を示
す。前記曲げ特性オブジェクト64は前記パーツの1つ
或いはそれ以上の特徴についての特殊な製造上の拘束に
関する情報を含む。例えば如何に前記板金パーツが曲げ
られるべきであるかに関する曲げ特性情報が、前記曲げ
特性オブジェクト64に設けられる。前記曲げ特性情報
は、異なる曲げ特性タイプ(例えば同時曲げ、同一直線
上曲げ、Z曲げ等)についての特殊製造データを含む。
【0206】前記曲げ線オブジェクト60は、また行な
われる曲げに関連する製造特殊データを含む。従って、
各曲げ線についての幾何学的或いは寸法データ、2次元
及び3次元空間位置データ、端データに加えて、前記曲
げ線オブジェクト60はまた、各曲げ線についてのV幅
データ、曲げピッチデータ、曲げ数データ及び/又は配
向データを含む。各曲げ線は、図26に示すように付随
する曲げ操作を含む。この曲げ操作は、各曲げ線におい
て曲げを行なうためのデータ及び操作/指示を有する一
群のオブジェクトとして実行される。仮にオブジェクト
として提供されると、各曲げ操作は、曲げ角度、曲げ半
径及び/又は曲げ縮小量のごとき固有の曲げデータのみ
ならず、如何に或いはどのタイプの曲げを行なうべきか
(例えば円錐曲げ、Z曲げ、ヘミング、円弧曲げ等)を
指示するデータ及び指令を含む。
【0207】前記パーツの曲げモデルを、オブジェクト
指向データモデルを介して実行することにより、全ての
複雑な数学的計算、計算幾何学及びマトリックス変換が
単一のクラスライブラリに組み込まれる。ヘミング、Z
曲げ及び円弧曲げのごとき特殊な曲げ操作もそのクラス
ライブラリに取り込まれる。更にV幅及び曲げ縮小量及
び曲げ順のごとき製造情報もそのクラスライブラリに取
り込まれる。前記曲げモデルにより、前記2次元平面モ
デル及び3次元モデルの同時二重表示が図26に示すよ
うに行なわれる。更に、前記曲げモデルの曲げ線オブジ
ェクト60に応じて曲げ加工が行なわれる。前記曲げモ
デル及びパーツ構造並びにそれらについての実行に関連
する一般的なコメントはここに添付した付録Kに提供さ
れる。
【0208】曲げモデルビューアが前記曲げモデルを解
釈し、2次元及び/又は3次元表現における前記パーツ
の視覚的な画像を表示するために設けられる。図27
は、この発明の他の側面による、前記曲げモデルビュー
アの構造と前記曲げモデルとの関係のブロック図を図示
する。前記曲げモデルビューアはオブジェクト指向プロ
グラム技術を介して実行され、前記設備38における種
々の場所10,12,14,…20の前記ステーション
モジュールにおけるユーザが前記曲げモデルに設けた情
報に基づいて前記パーツの種々の図を表示できるように
するウインドウズに基づくアプリケーションである。前
記曲げモデルビューアは、前記板金パーツを視覚化する
ために用いられる一群のアプリケーション・ライブラリ
・モジュールを含む。更に、前記曲げモデルビューア
は、ウインドウズ・アプリケーションの画像クラスとし
て設計され、従ってそれは任意のウインドウズ・アプリ
ケーションについての基本的画像クラスとして使用され
る。前記2次元及び3次元モデルを見るための殆どの標
準的操作(例えばズーム92、回転96、パン100、
寸法102等)は前記曲げモデルビューアの要素機能と
して実行される。幾何学的変換及び基本的コンピュータ
グラフィックス技術は、画像操作を実行する際に前記曲
げモデルオブジェクトに対して適用される。更に、前記
曲げモデルビューアは、画像モデル属性88を含み、そ
れはソリッド画像、ワイヤフレーム画像、2次元平面画
像及び正射影画像を含む4つの主なる画像モードを有す
る。
【0209】この発明の1つの側面によれば、前記曲げ
モデルクラスライブラリ80は、選択された画像(例え
ばソリッド、ワイヤ、2次元平面又は正射影画像)に応
じて、前記板金パーツに作用する一群の手続き又は機能
を含む。前記曲げモデルビューア観察クラス84は、ズ
ーム92、回転96、パン100及び寸法102のごと
き、一連の標準的操作を含む。そして、前記曲げモデル
ビューアの状態に応じて、前記曲げモデルビューア観察
クラスは、前記曲げモデル・クラス・ライブラリ80か
ら複数の機能を呼び出す。図27に示されるように、ユ
ーザにより選択される前記種々の観察モデル属性或いは
特徴88は、ソリッド画像、ワイヤフレーム画像、2次
元平面画像及び正射影画像を含む。この発明に設けてあ
るこれらの種々の観察モードの記述は図28−31を参
照して以下に提供される。
【0210】基本的コンピュータグラフィックス及び幾
何学的モデル化技術、例えば幾何学的変換及び3次元幾
何学的技術は、前記曲げモデルの種々の特徴を実行し且
つ異なる観察モード或いは機能を提供するために使用さ
れる。コンピュータに基づいた2次元及び3次元のモデ
ル化及びシミュレーションにおける最近の発展及び展
開、例えばグラフィックライブラリ或いはパッケージの
効用はこの発明のこれらの特徴を実行するために適用さ
れる。更に、コンピュータグラフィックス及びモデル化
については広い種類の刊行物或いは文献が利用可能であ
る。例えば、モルテンソン、フォリー等、マンティラを
見よ。それらの各々は上に記載した。
【0211】この発明の種々の観察及びモデル化の特徴
を提供するために各ステーションモジュール及びサーバ
モジュールは、800×600の解像度を有するSVG
Aスクリーンのごとき高解像度表示スクリーンを有す
る。ジョイスティック及び/或いはゲームカードも前記
ステーションモジュール及びサーバモジュールに提供さ
れ、ユーザが、前記パーツの異なる2次元及び3次元表
現を選択的に修正し且つ観察することを可能とする。ソ
フトウエアに基づいたグラフィックス・パッケージ、例
えばオープンGL(OpenGL)及びレンダウェア
(RenderWare)は、グラフィック計算を行な
うために使用される。それらのグラフィックライブラリ
或いはパッケージはウインドウズに基づいたアプリケー
ションで種々の観察モードを実行するために使用され
る。例えばオープンGLは前記曲げモデルに設けてある
パーツ幾何形状及びトポロジーデータに基づいて種々の
2次元ワイヤフレーム画像を実行するために使用され
る。更にレンダウェアは前記曲げモデルに設けてあるパ
ーツデータに基づいて、前記板金パーツの種々の2次元
及び3次元ソリッド画像を表示するために使用される。
オープンGLについての更なる情報については、例えば
オープンGL・レファレンスマニュアル及びオープンG
L・プログラミングガイド、リリース1、オープンGL
・アーキテクチャ・レビュー・ボード、アディソン−ウ
エズレイ発行社、リーディング、マサチューセッツ(1
992)を見よ。レンダウェアの情報については例えば
レンダウェアAPIレファレンスマニュアルV2.0、
クライテリオンソフトウエア株式会社、イギリス(19
96)を見よ。
【0212】前記パーツの種々の画像を表示するため
に、前記曲げモデルは例えばオペレータのステーション
モジュールにより前記データベース30からアクセスさ
れる。前記曲げモデルデータは、使用されているグラフ
ィック・ライブラリ或いはパッケージ(例えばオープン
GL又はレンダウェア)により使用されるデータフォー
マットに応じて再フォーマット化される。しかる後、前
記グラフィックデータは、オペレータにより選択された
観察モード(ワイヤ、ソリッド等)を表示し、或いは前
記ユーザにより実行された観察機能(ズーム、パン等)
を実行するために種々のプログラムされた順序に従って
加工される。
【0213】特定の観察モードがオペレータにより選択
される時、選択された観察モードは、前記画像の現在の
ズーム比率或いはファクター及び向きと共に検出され
る。この情報は、次に前記現在の表示を更新するために
前記グラフィックパッケージに対して機能コールを行な
うために使用される。前記グラフィックパッケージに対
する機能コールは、表示される観察モード並びに実行さ
れるズーム或いはその他の観察機能に応じて行なわれ
る。これらの機能コールに基づいて前記グラフィックパ
ッケージは必要なデータを提供し、従って前記ステーシ
ョンモジュールは前記オペレータに対して前記パーツの
画像を表示する。前記ユーザによる前記2次元又は3次
元表現の修正(例えばジョイスティック或いはマウスを
移動することにより)に基づいて前記表示された画像を
更新するために追加の機能コールは前記グラフィックラ
イブラリに対してなされる。
【0214】前記パーツのワイヤフレーム画像を提供す
るために、前記グラフィックパッケージに対して前記パ
ーツの線分エンティティーデータが提供され必要なグラ
フィック計算がなされる。しかし、ソリッド画像につい
ては、前記面の各々について1つもしくはそれ以上の多
角形(ポリゴン)が引き出され、前記画像を表示するた
めに前記グラフィックパッケージへ入力として提供され
る。オープンGL及びレンダウェアのようなグラフィッ
クパッケージは、多角形データを入力として取得し、ソ
リッド画像を提供するために前記多角形により定義され
る領域を満たす。前記多角形は、前記曲げモデルにおけ
る面及び曲げ線情報から導出され各面の境界を決定する
ことにより導出される。前記多角形は前記パーツの各面
を表示し且つ定義するために生成されなければならな
い。これらの面は次に、板金パーツ全体を表示するため
に、前記曲げモデルにおける前記パーツトポロジー及び
他のデータに基づいて接続される。仮に面が開口部或い
は穴を有する場合には、そのような開口部を囲まない幾
つかの多角形を有する面を定義することが必要となる。
正射図については、個々の図の各々(それはワイヤフレ
ーム又はソリッドである。)についてのデータは前記グ
ラフィックパッケージに送られ、図31に示されるごと
く、結果としての複数の図が単一の表示スクリーン上で
結合される。前記曲げモデル像の種々の観察モード及び
機能を実行するための代表的コードは付録Eに提供され
る。このサンプルコードはC++で記載され前記プロセ
ス及びそこで実行される操作に関連する複数のコメント
を含む。適当なグラフィックパッケージ(例えばオープ
ンGL及びレンダウェア)との結合における前記コード
は異なった図(例えば2次元及び3次元ワイヤフレーム
或いはソリッド)を表示するために使用されるだけでな
く、前記観察機能(例えばズーム、回転、パン等)の各
々の機能を提供する。表示される種々の観察モード表示
スクリーンの簡単な説明が以下に与えられる。
【0215】ソリッド図モードは、前記曲げモデルによ
り定義される前記パーツの、ソリッドで表示される3次
元図を表示する。図28は前記板金設備38内での位置
10,12,14,…20のいずれかにおいて設けてあ
る表示スクリーンへ出力として提供される代表的ソリッ
ド図ウインドウを図示する。このソリッド図モードにお
いて、ユーザ或いはオペレータは、3次元空間でのナビ
ゲーション及び3次元自動寸法付けを操作するための複
数の観察機能を与えられる。前記パーツのソリッド図を
変更するために設けられる基本的な機能は回転、ズーミ
ング、パンニング、及び/又は標準図選択を含む。前記
ユーザにより与えられ或いは選択される前記標準図は以
下を含む。即ち等測投影法図、平面図、底面図、正面
図、背面図、左図、及び右図。自動及びマニュアル寸法
付け操作がまた提供され、現在の観察角度に基づいて前
記パーツの重要な寸法を表示する。この発明の寸法付け
特性の代表的例が、図32−36を参照して以下に提供
される。
【0216】図28に示されるようにソリッド図ウイン
ドウはウインドウズに基づいたアプリケーションであ
り、従って前記パーツの複数のウインドウ或いは部分図
が提供される。前記複数の図のウインドウは、ウインド
ウの中で1つの極めてクローズアップされた単一の図を
提供する拡大図及び単一のウインドウにおいて前記パー
ツの極めて遠くからの図を与える鳥瞰図を含む。前記部
分図はユーザにより選択されたオブジェクトの部分図を
与える。前記種々の観察機能を制御するために、前記場
所10,12,14,…20の各々の前記サーバモジュ
ール32及びステーションモジュールに、ジョイスティ
ックインタフェースが設けられる。前記ジョイスティッ
クだけ及び/又はキーボード上の所定のキー(例えばシ
フトキー又はコントロールキー)の操作との組み合わせ
の操作が、回転及びパンニング及びズーミングのごとき
種々の機能を実行するためにユーザにより行なわれる。
更に、前記パーツのソリッド図の表示される生地は、デ
ータベース内での前記パーツについて特定された材質を
シミュレートするように選択される。この目的のため
に、スチール、ステンレススチール、アルミニウム等の
ごとき材料の生地のライブラリを有する材料生地ライブ
ラリが提供される。格納された材料生地ライブラリはソ
リッド図が存在する時オペレータによりアクセスされ適
用される。従って、表示されるパーツの表面は前記板金
パーツの実際の生地をより忠実にシミュレートする。
【0217】前記ワイヤフレーム図モードは、前記板金
パーツのワイヤフレーム図のウインドウズに基づいた表
示を提供する。ワイヤフレームウインドウの例が図29
に示されている。前記ワイヤフレームにおける3次元空
間ナビゲーション及び3次元寸法付けを提供するための
キーの機能は、前記ソリッド図に関して上に記載したと
類似である。例えば回転、ズーミング、パンニング及び
標準図の選択のごとき機能が提供される。自動寸法付
け、多重図ウインドウ及び断面図オプションも前記ワイ
ヤフレーム図モードにおいて提供される。更に、ジョイ
スティック及び/又はキーボードインタフェースが、ユ
ーザが前記種々の観察機能を選択し且つ活性化すること
ができるように提供される。
【0218】前記2次元平面図モードはワイヤフレーム
表示において、前記パーツの展開された2次元平面図を
表示する。2次元平面図ウインドウの例が図30に示さ
れている。この2次元平面図モードはユーザがウインド
ウ中の図を変更し又は改造するのを可能とするための複
数の観察機能を有する。例えばユーザが前記2次元平面
ワイヤフレーム図を選択的にズームし且つパンするのを
可能とするようにズーミング及びパンニング機能が設け
てある。更に、寸法付け及び多重ウインドウ観察機能
が、前記ソリッド図モードに関して上記したと同様の態
様で設けてある。ジョイスティック及び/又はキーボー
ドインタフェースはユーザがパンし、ズームし他の観察
機能を制御するのを可能とするように設けてある。前記
パーツに設けられている特殊な成形部または形状は、特
殊な成形部の指示又は記載と共に、前記成形領域の前記
最も外側の境界についての成形または形状として表示さ
れる。
【0219】図31に図示されるような正射図ウインド
ウも前記曲げモデルビューアの一部として提供される。
前記正射図モードはワイヤフレーム表示において平面
図、正面図、右図及び等測投影法図を表示する。隠れ線
オプションが、観察角度に基づいてブロックされた線を
見えなくするために設けられる。この隠れ線オプション
は各図のウインドウを簡単化するために用いられる。前
記正射図モードにおいても種々の観察機能が提供され、
ユーザが前記ウインドウにおいて現在の図を選択的に操
作し且つ変更するのを可能とする。例えば、ズーミング
及びパンニング機能が寸法付け及び多重ウインドウ観察
機能と共に設けられる。上記したように、多重ウインド
ウ観察機能が設けられ、ユーザが、多重ウインドウにお
いて前記正射図の拡大図及び/又は鳥瞰図を選択的に表
示することを可能とする。ジョイスティック及び/又は
キーボードインタフェースが、前記複数の場所の各々に
設けられ、ユーザが、前記正射図モードにおいて前記複
数の観察機能の各々を選択的に活性化し且つ操作するの
を可能とする。
【0220】上記した種々の図の表示の各々を表示せし
めるのに加えて、前記曲げモデルビューア観察クラスは
他の特徴と共に実行される。例えば前記曲げモデルビュ
ーアはオペレータにより選択され強調されている、現在
の図における複数の項目或いはエンティティーを指示す
るための選択集合を含み且つ維持する。この発明の1つ
の側面によれば、オペレータは、選択された項目に関連
するデータを修正し或いは前記パーツのそれらの項目の
所定の操作を行なうために、前記表示されたパーツの面
及び曲げ線及び他の特徴を選択することを可能とされ
る。例えばオペレータは、表示されたパーツの面を選択
し、その面のその幅或いは長さに沿っての寸法データを
変更することができる。オペレータはまた曲げ角度又は
V幅のごとき各曲げ線に付随する種々の曲げデータを修
正することができる。
【0221】前記曲げモデルビューアはユーザにより選
択されたエンティティー或いは項目(例えば面、曲げ
線、面或いは曲げ線の端等)のリストを保持する。観察
者はそのリストを更新する。従ってオペレータにより現
在選択されている現在の項目は前記選択リストに常に保
持される。この発明におけるソフトウエアの他の部分
は、異なる手順(例えばマニュアル寸法付け等)を実行
し或いは行なう際、選択されたエンティティーの前記現
在のリストの図面クラスを呼び出す。
【0222】更に前記曲げモデルビューアは観察可能性
機能を提供する。それは現在表示されている図に基づい
て観察可能性情報及び座標情報を提供する。以下に更に
十分に説明されるように、前記観察可能性機能は前記パ
ーツの特定な部分或いはエンティティーがスクリーン上
で現在観察可能であるか否かについての情報を提供し且
つスクリーンエンティティーが現在位置する場所につい
ての座標情報を提供する。前記曲げモデルビューアの観
察可能性機能は、前記パーツのどの部分が現在スクリー
ン上で観察可能であるかを決定するためにこの発明の寸
法付け特性により呼び出される。従ってスクリーン上で
観察可能である前記パーツの部分の寸法情報のみが観察
者に対して表示される。この発明の寸法付け及び観察可
能性機能のより詳細な説明は以下に提供される。更に前
記曲げモデルビューアの観察可能性機能を実行するため
の代表的コードはここに添付する付録Jに提供される。
【0223】図32−36を参照するに、この発明の1
つの側面に基づく、寸法付け特性の事例が説明される。
上記したように、観察モードの各々は現在の観察方向に
基づいて、前記パーツの寸法を自動的に表示する寸法付
け機能を含む。自動寸法付け機能は、現在の観察角度に
おいては見ることができないフランジ或いは曲げ線の寸
法がユーザに対して表示されないように提供される。前
記自動寸法付け機能或いはモードが活性化される時、前
記パーツの観察可能な寸法のみが、現在の観察角度に基
づいて表示される。更に、自動寸法付けモードにおいて
は、所定の寸法(即ち前記曲げ操作に対して重要である
寸法)のみが現在の観察角度の状態に基づいて表示され
る。マニュアルの寸法付けモードも提供され、ユーザが
どの寸法が表示されるべきであるかを選択的に指示する
ことを可能とする。このマニュアル寸法付けモードにお
いては、ユーザにより選択された寸法事項のみが、現在
のパーツの観察角度に基づいて表示される。いずれの寸
法付けモードにおいても、表示された寸法事項は、前記
パーツがズーム化され或いはパンされる時ウインドウ表
示から消去され或いは除去される。
【0224】図32は自動寸法付けモードにおいて表示
される種々の寸法事項の例を図示する。前記自動寸法付
けモードにおいて表示される寸法事項は、曲げ操作に重
要な事項(例えばフランジ長さ、曲げ線長さ、曲げ角度
等)からなり、パンチ加工された穴或いは開口部の寸法
のような余分な寸法事項ではない。前記表示される寸法
事項は例えば前記板金パーツの幅、深さ、及び高さ並び
にフランジ長さを含む。更に、各曲げ線の前記曲げ線長
さL、曲げ角度A、内側半径R及び曲げ縮小Dは単独で
或いは一緒に、1つのウインドウに或いはグループ情報
ボックスに表示される。上記したように、現在の観察角
度に基づいて観察可能な寸法事項のみが表示される。更
に前記オペレータが、前記パーツの観察角度を変えるた
めに回転、ズーミング或いはパンニングをする時全ての
寸法は表示から消去され或いは除去され、各操作が完了
した時それらの寸法は再び表示される。表示情報(任意
のテキスト或いは参照矢印)の寸法及び向きは、現在の
ズームの比率或いは観察角度ではなくスクリーンの寸法
に対して常に寸法調整される。しかしながら、前記寸法
情報の可読性を改良するために前記寸法情報の色、スタ
イル、重み及び/又はフォントはユーザがそれらを変更
できるように形成可能である。結果としてオペレータ或
いはデザイナーは、前記寸法情報の特殊の色、フォント
サイズ等を選択することによりパーツにおける重要な寸
法を強調することができる。例えば、寸法テキストの
色、寸法又はフォント又は、寸法参照事項、線又は矢印
の色、線の重み或いはスタイルは、パーツにおける重要
な寸法を指示するために強調され或いは選択的に変更さ
れる。オペレータはまたウインドウ情報ボックスを色付
けし満たし或いはスタイル付けし或いは特定の曲げ線を
色付けし或いはパーツ内の他の重要な寸法を強調する。
【0225】この発明の寸法付け特性を実行するために
種々のプロセス或いは操作が利用される。更に上記した
ように本発明の寸法付け特性に対して観察可能性情報を
提供する観察可能性機能を、前記曲げモデルビューアは
備える。これらの機能或いは特性は、例えばサーバモジ
ュール32及び/又は工場全体に位置するステーション
モジュールのそれぞれでソフトウエアにより実行され
る。この発明の自動寸法付け特性を実行するための代表
的コードが付録F−Iに設けてある。更に、曲げモデル
ビューアの観察可能性機能のためのサンプルコードが付
録Jに設けてある。これらの付録におけるコードはC+
+プログラム言語で書かれており、そこで行なわれる手
続き及び操作の論理フローの理解を容易にするためのコ
メントを含む。
【0226】この発明の寸法付け特性の論理フローは一
般的に3つの段階に分類される。第1の段階で、前記パ
ーツの曲げモデル幾何形状及びトポロジーデータがデー
タベース30からアクセスされ、前記パーツの全ての寸
法並びにそれらの寸法が表示され得る全ての態様を計算
するために使用される。前記パーツの各曲げ線及び面に
ついて、データが表示され得る全ての最も遠い点が計算
され、これらの点について、寸法線或いは矢印が表示さ
れ得る全ての方法が計算される。前記寸法データ或いは
他の情報が表示され得る場所を決定する際に一定のヒュ
ーリスティックが適用される。例えば一般的なルールと
して、全ての情報は前記パーツの外側にのみ表示される
と決定される。このようなヒューリスティックが、前記
ビューアに対してより意味のあるそしてより込み合わな
い情報の表示を提供するために適用される。
【0227】上記した第1の段階は、本発明の寸法付け
特性がオペレータにより活性化された際常に実行され
る。或いは、前記第1段階の計算は前記パーツが最初に
オペレータにより観察された際にのみ行なわれる。この
ような場合に、前記計算されたデータは次の使用のため
にメモリに格納され、前記パーツの寸法或いは他の幾何
学的データがユーザにより修正され或いは変更された時
変更される。更に前記第1段階の全ての計算は図面スク
リーンに対してではなくパーツの幾何学形状に対して行
なわれる。従って前記データは、現在の図面に関わりな
く或いはその図面が変更されても何時でも再び使用され
得る。
【0228】この発明の自動寸法付け特性の第2段階は
前記パーツの図面が更新された時常に行なわれる。この
第2段階の主たる目的は、変更された図において前記パ
ーツのどのエンティティーが観察可能であるかに基づい
て前記第1段階中に生成されたデータをふるいにかける
ことである。この第2段階において、現在の図において
観察可能でない全てのデータはふるいにかけられ、現在
観察可能である、前記第1段階において計算されたデー
タのみが残る。前記パーツのいずれの点あるいは部分が
現在観察可能であるかを決定するために前記曲げモデル
ビューアに対する機能コールがなされる。上記したよう
に、前記曲げモデルビューアは、表示されている現在の
図に基づいて前記パーツの観察可能な部分についての情
報を保持し且つ提供する観察機能を含む。前記パーツの
向きに基づいて前記曲げモデルビューアは前記パーツの
どの面及び曲げ線(並びにそれらの面及び曲げ線のどの
端或いは部分)が観察可能であるか、そして何がスクリ
ーン上で隠されているかを決定する。
【0229】上記したように、前記曲げモデルビューア
の観察可能機能を実行するためのサンプルコードは付録
Jに提供される。前記パーツのいずれの点あるいは部分
が観察可能であるかを決定するために、前記曲げモデル
ビューアは前記パーツの現在の図の向き及び現在のズー
ム面又は表示されているパーツの比率を決定し且つ維持
する。前記曲げモデルビューアはこの現在の図の向きを
決定し維持するために従来の透視図射影技術(モルテン
ソンの例えば12章を見よ)を使用する。前記パーツの
任意の点の観察可能性を決定する際に前記点の世界座標
(即ちそこにおいて前記パーツが表現されているところ
の座標)を前記観察可能性機能は獲得する。次に、前記
現在の図面の向き及びズーム面あるいは比率に基づいて
その点について、前記世界座標に対応するスクリーン座
標(即ちスクリーン上の画素の位置)が決定される。そ
の後、前記スクリーン座標に基づいて、前記スクリーン
の観察点の眺めから前記部品の任意のエンティティー或
いは部分が問題の点の前方にあるか否かが決定される。
前記パーツの上の点の隠されている特性は、前記パーツ
の他のエンティティー或いは部分が問題の点と同じスク
リーン上の点を割り当てられているかどうかに基づいて
も決定され得る。グラフィックパッケージ或いはライブ
ラリ(例えばオープンGLあるいはレンダウェア)への
機能コールは、前記パーツの1つの点以上が同じスクリ
ーン上の点に割り当てられているかどうかを決定するた
めに使用される。もし何かが同じスクリーン上の点に割
り当てられているならば、それらの点のそれぞれのZバ
ッファ深さに基づいて、前記パーツの点がそれの後ろに
あるかどうかが決定される。前記Zバッファ深さはオー
プンGL或いはレンダウェアのごときグラフィックパッ
ケージにより使用され、観察点或いはカメラ位置からそ
れぞれの点への距離を定義する。前記Z深さは、興味の
ある前記パーツの複数の点について前記グラフィックパ
ッケージへ機能コールを行なうことにより決定される。
【0230】前記曲げモデルビューアの観察可能性機能
の前記プロセスはこの発明の自動寸法付け特性から前記
曲げモデルビューアへ催促がある時いつでも実行され
る。そのようなプロセスは従って前記オペレータにより
表示されているパーツの現在の図が修正され或いは変更
される時いつでも実行される。上記したように、前記曲
げモデルビューアは、表示された画像の向きに対して変
更がなされる時は常に、現在の図の向き及びズーム比の
状態を維持し且つ更新し、従って要求される時観察可能
性情報を正確に提供する。
【0231】どのデータが観察可能であるかを決定した
後、自動寸法付け機能は、(例えば第1段階での計算に
基づいて)前記寸法データ或いは他の情報が表示され得
る全ての可能な方法及び位置を決定する。前記データが
表示され得る全ての可能な方法からデータを表示するた
めの最適の方法を選択するために一群のヒューリスティ
ックが適用される。例えば第1のヒューリスティック
は、観察者の観察点により近いスクリーン上の領域が好
ましいと要求する。第2のヒューリスティックは、前記
寸法を定義するための2つの可能な点の間の距離が最小
であるところの領域により近い領域にデータは表示され
るべきであると規定する。他のヒューリスティックはま
た、スクリーン上での重なり合い或いは混雑を避けるた
めに、他の寸法データ或いは他の情報の相対的位置に基
づいて適用される。
【0232】前記パーツの観察可能な部分及び前記観察
可能な領域についての情報を表示するための最適の領域
を決定した後、前記自動寸法付け機能の第3の段階は前
記表示スクリーン上で種々の情報を描くために実行され
る。例えば、前記情報を表示するための領域の選択に基
づいて、寸法情報は前記パーツの観察可能な寸法の各々
についてスクリーン上に表示される。更にどの曲げ線が
観察可能であるかに基づいて、曲げ線情報がまた、他の
パーツ情報とオーバーラップしないスクリーンの領域に
おいて情報ボックス(例えば図32に示されるそれ)に
表示される。前記パーツの幅、高さ、及び深さを含むパ
ーツの寸法はまた前記スクリーン上の所定の位置(例え
ば前記パーツの右下)或いは前記パーツに最も近く他の
情報にオーバーラップしない或いはそれを邪魔しない位
置に表示される。
【0233】図33−36は前記寸法付けモードにおい
て寸法事項を表示する際に、使用される種々の方法及び
定義を図示する。特に図33(a)−33(b)及び3
3(c)は、種々の異なるパーツについてフランジ寸法
が定義される方法を図示する。この発明の1つの側面に
よれば、前記フランジ長さは、各曲げ線からフランジ上
で最も遠い点として定義される。もし前記曲げ線と並行
であるフランジの最も長い端部に前記フランジの最も遠
い点が存在しない場合には、前記寸法付けモードにおい
て最も長いフランジが追加され表示される。限定しない
事例として図34(a)及び34(b)は、2つの異な
るタイプのパーツについて補助的なフランジ長さを追加
することを図示する。前記パーツの厚さが表示される
時、フランジ長さは外側寸法の外側として表示される。
例えば図35(a)、35(b)及び35(c)は、厚
さを有して表示される種々のパーツについて前記フラン
ジ長さが指示される態様を図示する。更に、鋭角の曲げ
を備えたパーツについて、前記フランジ長さは種々の方
法で表示される。例えば図36(a)に示されるよう
に、フランジ長さは、接線寸法定義に基づいて表示さ
れ、そこでは前記フランジ長さは前記鋭角曲げから延長
される接線から測定される。或いは、前記鋭角曲げ角度
の2つの辺から延長された2つの直線の交差により定義
される点に基づいてフランジ長さを定義するために、図
36(b)に示されるそれのごとき交差寸法方法が使用
される。オペレータは、前記フランジ長さを表示するた
めに前記接線寸法或いは交差寸法方法のうちから選択す
ることを可能とされ、及び/又は特定の寸法方法(例え
ば接線寸法方法)はデフォルト設定として提供される。
【0234】曲げコード順番の生成を促進するために、
種々の表示機能を有した図形的ユーザインタフェースが
設けられ、オペレータによる曲げプランの生成を助け
る。図37−44はこの発明の他の側面により、図形的
ユーザインタフェースの使用により曲げコード順番を生
成するために実行される種々の手続き及び操作を図示す
る。通常、最初の曲げモデルデータ及び他の作業情報は
サーバモジュール32において重要な幾何学的及び製造
データを入力することにより設計プログラマにより生成
される。結果としての曲げモデルファイルは次にデータ
ベース30に格納される。板金パーツが製造される前
に、曲げオペレータが、所望の曲げ操作を実行するため
の曲げ順を生成する必要がある。この曲げオペレータ
は、どのタイプの工具が必要であるかを決定し且つ前記
曲げ機械装置について工具取付けを定義しなければなら
ない。この曲げプラン生成の工程は、図形的ユーザイン
タフェースの使用によりまたこの発明の種々の教示によ
り援助され、且つより効率的となる。
【0235】前記曲げプランを生成するために、例えば
曲げステーション18の曲げオペレータは、前記データ
ベース30から前記曲げモデル及び他の作業情報へアク
セスし且つダウンロードする。前記関連するパーツにつ
いての曲げモデルは前記コミュニケーションネットワー
ク26を介して曲げステーション18における工場フロ
ア上のステーションモジュールへ搬入され或いは移入さ
れる。この工程は、一般的に図37のステップS220
に示される。その後、ステップS224で曲げオペレー
タは、前記曲げモデルビューアを用いて前記パーツの形
状及び寸法を調べる。ここで、前記曲げオペレータは、
前記曲げステーションに位置付けられた表示スクリーン
で前記パーツの種々の2次元及び3次元図を選択的にズ
ームし且つパンする。この発明の自動寸法付け特性を活
性化することにより、前記曲げオペレータはまた曲げ操
作を実行するために前記パーツの重要な曲げ寸法を観察
する。
【0236】一旦オペレータが前記パーツの形状及び寸
法を理解すると、この曲げオペレータはステップS22
8で曲げ順入力ウインドウを選択し且つ表示することに
より前記曲げプランを生成することを開始する。前記曲
げ順入力ウインドウは、曲げオペレータが曲げ順を生成
し且つ修正し且つ消去するのを援助するために図形的ユ
ーザインタフェースを提供し且つオペレータが、前記曲
げ順における各段階についての種々の製造パラメータ
(例えばバックゲージ位置、工具、NCデータ等)を特
定し且つ入力することを可能とする。前記曲げ順入力ウ
インドウは前記スクリーンの一部(例えばスクリーンの
中央部或いはスクリーンの左側の方)に表示される前記
パーツの2次元平面図画像を含む。前記2次元平面図画
像は、前記パーツのフランジ、穴及び開口部を含む、前
記展開パーツの種々の特徴を含む。前記曲げオペレータ
が前記複数の曲げ線及び各曲げ線についての曲げ順を選
択し且つ指示すると、各曲げ段階における前記中間的パ
ーツ形状のソリッド2次元或いは3次元画像が現れ、例
えば図38に示されるように、スクリーンの右側の端の
ごときスクリーンの一部にそれらが提供される。前記中
間パーツ形状の画像は入力された曲げ順に対応した順番
で表示され且つ(図38の例に示されるように)前記パ
ーツの2次元平面図と共にスクリーン上に同時に表示さ
れ、或いは別個のスクリーン表示に別個に表示される。
【0237】更に各曲げ線が選択されるにつれて、前記
曲げ線は強調され、図39(a)に一例として示される
ように、曲げ順番号及び挿入方向(例えば矢印で表現さ
れる)が前記曲げ線の上或いは近くに表示される。各曲
げ線についての前記曲げ線番号は、それが選択される順
番に基づいて自動的に設定され、或いは各曲げ線が選択
された後オペレータによりマニュアルで入力される。曲
げ角度、曲げ線長さ、及びバックゲージ位置のごとき曲
げ線に関連する他の製造情報も、図40及び41に例と
して示されるように、各曲げ線が選択され強調されると
き入力され及び/又はスクリーン上に表示される。図4
0及び41に示すように、ダイアログ或いは情報ボック
スがスクリーン上に表示され、曲げオペレータが各曲げ
線に関連する製造情報及び他のパラメータを選択し、入
力し或いは修正することを可能とする。
【0238】前記ダイアログ或いは情報ボックスは、曲
げオペレータが曲げ線を強調し或いは選択するのを可能
とする。ホット機能キー或いは高速スイッチキーが前記
曲げシーケンス入力ウインドウに表示され、オペレータ
が工具立てを選択し或いは入力し且つNCデータを監視
し且つ修正するのを可能とする。例えば曲げオペレータ
は、工具機能キーを選択し、前記曲げ順入力ウインドウ
から、工具立て情報を入力するための工具入力表示スク
リーン或いは複数の表示スクリーンへ切替える。NC機
能制御キー(例えばNC9EX)も設けられ、オペレー
タが実行されるべき曲げ操作に関連するNCデータを監
視し及び/又は修正するのを可能とする。更に図40及
び41に示されるように、曲げ線を定義し及び/又は修
正すること及び関連する製造情報に関連して他の機能キ
ー及び制御部が設けられている。例えばZOOM AL
Lキーが、前記2次元平面図画像をズームイン及びズー
ムアウトするために設けられている。バックゲージキー
は、前記バックゲージの位置を選択し或いは設定するた
めに設けられている。グループ化及びグループ解除化制
御キーは、一緒に曲げられる複数の曲げ線を可能とし或
いは制御するために表示される。更に制御キー(例えば
アマ曲げ)が特殊な曲げ操作を定義するために設けられ
ている。他の機能キーも表示されオペレータが前記曲げ
順を選択し、修正し及び/又は消去するために設けられ
ている(例えばREMOVE CLEAR FWD、C
LEAR ALL、OK、CANCELL)。この曲げ
順入力ウインドウにより、曲げオペレータは、前記曲げ
順及び種々の製造情報を効率的に監視し且つ修正するこ
とが可能となる。
【0239】更にこの発明の他の側面によれば、前記パ
ーツの断面図及び/又はパーツの曲げシミュレーション
が、前記曲げ順における各曲げ工程についてスクリーン
上に表示される(例えば図41を見よ)。前記断面図及
び曲げシミュレーションは前記スクリーン上に選択的に
表示され、或いは曲げオペレータにより各曲げ線が選択
される時表示される。前記断面図及び曲げシミュレーシ
ョンは、例えば上下曲げ工具(例えばパンチ及びダイ)
又はバックゲージ位置・設定の表現を含み、それらは前
記2次元平面図画像と共に同時にスクリーン上に表示さ
れ或いは異なるスクリーン表示上に別個に表示される。
前記バックゲージ位置は前記パーツのトポロジーに基づ
いて自動的に決定され或いはオペレータにより設定され
或いは修正される。前記曲げ線のための工具立て情報が
入力されておらず或いは曲げオペレータにより設定され
る場合には、前記断面図及び/又は曲げシミュレーショ
ンはスクリーン上に表示されず又は前記中間パーツ形状
の表現及び計算され或いは定義されたバックゲージ位置
のみが表示される。前記曲げシミュレーションは、前記
パーツの所望の反転、前記パーツの操作及び配向動作及
び/又は各曲げ線でなされる前記パーツの曲げ加工の表
示されるシミュレーションを含む。前記表示スクリーン
上に前記パーツの2次元平面図画像と共に、曲げ工程の
前のパーツの断面図及び曲げ工程がなされた後の前記パ
ーツの断面図を同時に表示することもまた可能である
(例えば図41を見よ)。これらの断面図は、スクリー
ンの右側に提供され前記曲げ順における各曲げ工程につ
いての前記上下曲げ工具及びバックゲージの表現を含
む。更にズーム制御或いは機能キー(ZOOM IN及
びZOOM OUT)が表示され、オペレータが、前記
曲げ前及び曲げ後断面図に関連してズームの比或いは向
きを制御することを可能とする。日本公告公報平7−1
21418(丹羽等の名前で1995年12月15日に
発行)及び日本公開公報平1−309728(長沢等の
名前で1989年12月14日に発行)に開示されるそ
れと類似の技術及び手続きが前記パーツの断面図或いは
曲げシミュレーションを表示するために使用される。前
記文献の開示はここにその全体において参考により積極
的に取り込まれる。
【0240】この発明の1つの側面によれば、選択され
た曲げ線に関連して前記パーツの短い或いは小さいサイ
ドを計算することにより前記曲げについて挿入方向を自
動的に決定するためのソフトウエア或いはプログラム論
理が提供される。この発明の特徴に基づいて、各曲げ線
はそのパーツを2つのサイドに分断するために使用され
る。挿入方向は、より小さい或いは短い長さ(例えば前
記曲げ線に直交する辺の寸法)を有する前記パーツのサ
イドに基づいて或いは、より小さい全体的面積を有する
サイドに基づいて各曲げ線について決定される。もしオ
ペレータが前記選択された挿入方向に満足しない場合に
は、図39(b)に図示されるように、オペレータは挿
入方向を反転する。オペレータは挿入方向を、例えば曲
げ線が強調されている際にマウス或いはキーパッドの選
択ボタンをクリックすることにより変更し或いは反転す
る。挿入方向情報は、曲げ装置或いは機械装置で前記パ
ーツを曲げ加工するために、前記曲げ線により定義され
るフランジの挿入方向を指示するための矢印及び/又は
テキストを含む。前記挿入方向情報は、曲げ線の上或い
は近く(例えば図39(a)及び39(b)を見よ)或
いは関連するフランジの端の上或いは近く(例えば図4
0を見よ)に表示される。更に前記挿入方向情報は、各
曲げ線が選択された時に表示され或いはジョイスティッ
ク装置、マウス装置、或いはキーボード装置から受け取
った入力に基づいて選択的に表示される。
【0241】従って図形的ユーザインタフェースの使用
を介して、曲げオペレータは、種々の中間形状及び最終
パーツの形を、オペレータにより入力された選択された
曲げ順に基づいて見ることができる。再び、オペレータ
はジョイスティックインタフェース、マウスインタフェ
ース及び又はキーボードインタフェースのごとき適宜の
入力装置を通して前記スクリーン上にデータを入力し選
択することができる。曲げオペレータが提案された曲げ
順に満足しない場合には、曲げオペレータは、ステップ
S232に一般的に示されるように曲げプランを最終化
する前に曲げ順を編集する。この曲げ順の編集は種々の
やり方及び方法において実行される。特にこの発明の1
つの側面によれば、ドラッグ及びドロップ編集特性が提
供され図42に示されるようにオペレータは単に、前記
スクリーンの左側或いは右側に提供された中間的パーツ
形状アイコン或いは表示の1つをつかみ且つそれを前記
順番の所望の位置へドロップすることにより選択された
曲げ順を編集する。その後、前記曲げ順に対する曲げオ
ペレータの修正に基づいて前記スクリーン上の前記種々
の中間パーツ形状が修正され、改定された曲げ順に基づ
く中間的曲げ段階を示す。更に前記曲げオペレータの前
記曲げ順のドラッグ及びドロップ編集に基づいて、前記
2次元平面図画像上の曲げ順番号が改定される。
【0242】前記曲げ順が決定された後、オペレータ
は、ステップS236に示すように、格納された工具立
てデータのライブラリから工具を選択することによりど
のタイプの工具立てが使用されるべきであるかを決定す
る。関連する工具立て情報は、工場フロアの曲げオペレ
ータに対して表示され、曲げオペレータが前記ライブラ
リから工具立てを選択するのを図形的に支援するために
表示メニューが提供される。一旦特定の工具が前記ライ
ブラリから選択されると、前記工具に関連するデータが
スクリーン上に表示される。図43は、マニュアル工具
選択のために前記曲げオペレータに対して図形的に表示
される種々の表示メニュー及びデータテーブルの事例を
図示する。図43の例では前記曲げオペレータが前記工
具ライブラリから特定の工具を取り出すのを支援するた
めに、連続的な表示メニュー或いはスクリーン表示が図
形的に表示される。連続的に表示されるスクリーン表示
は前記表示装置上に連続的に表示され(例えばオーバー
ラップする或いはカスケードする態様で)或いはそれは
個々に表示され、そのスクリーンは次の引き続くスクリ
ーン表示が表示される前にクリアされる。一旦特定の工
具が選択されると、その工具に対する特定のデータがテ
ーブルに提供され且つオペレータに表示される。工具ラ
イブラリにおけるデータは、前記ソフトウエアの最初の
セットアップ手続きにおいて、(例えばデータベース3
0の中に)予め定義され且つ可能されている。
【0243】この発明のマニュアル工具選択特性はオペ
レータが工具タイプを選択し且つ各タイプにおいて工具
の形状を選択することを可能とする。例えば、パンチ、
ダイ、ダイホルダ、及びダイレールを含む種々の工具タ
イプが選択される。各タイプは多数の形状からなり、且
つ各形状に対して異なったサイズ及び寸法の多数の工具
が存在する。1つの工具を選択するために、ユーザは、
図43に示されるような、表示される工具タイプアイコ
ンから1つのアイコンを選択することにより1つの工具
タイプをまず特定する。その後ユーザは選択された工具
について利用できる異なる形状のメニューを提供され
る。工具形状を分析した後、ユーザは選択された工具に
ついて、表示された形状アイコンから1つの形状アイコ
ンを選択することにより工具形状を選択する(例えば図
43では、グースネック形状パンチが選択された)。最
後にユーザは選択された工具形状について適当なサイズ
及び寸法を選択する。図43に更に示されるように、選
択された工具形状に対して利用可能な工具の異なるサイ
ズ及び寸法を示すためのテーブルがユーザに対して表示
される。このテーブルから1つの項目を選択することに
より、選択された工具がアイコンとして表示され一般的
な工具タイプアイコンに置き変わり、且つ工具の選択を
確認する。
【0244】ステップS240で、曲げオペレータは次
に図形インタフェースの支援により、プレスブレーキに
おける種々の工具段階(工具ステージ)を設定する。図
44は前記曲げプランにおいて使用される工具セットア
ップ(工具取り付け)の定義を容易にするために曲げオ
ペレータに対して与えられる代表的工具セットアップウ
インドウを図示する。図44に例として示されるよう
に、種々のパンチ、ダイ及びレールのデータが前記ツー
ルセットアップウインドウに表示される。前記板金パー
ツのための工具及びダイの情報はオペレータにより入力
される。ジョイスティックが曲げオペレータのステーシ
ョンモジュールに提供され曲げオペレータが工具位置を
指示し且つ利用可能な工具及びダイのリストから工具及
びリストを選択することを可能とする。この工具セット
アップウインドウにおいてスクリーンの左側は現在の工
具セットアップの断面形状を表し、スクリーンの右側は
プレスブレーキにおける現在のセットアップの位置を表
示する。現在のセットアップの位置は図44に示される
ように強調され或いは影が付けられる。
【0245】最後にオペレータが曲げ順に満足すると前
記工具立て及び曲げシーケンスを含む曲げプラン情報
が、図37におけるステップS242に一般的に示され
るように、前記データベース30の中に前記曲げモデル
と共に保存される。前記曲げ順の実際のテストが、前記
曲げオペレータにより選択された曲げ順を確認するため
にプレスブレーキにより行なわれる。もし必要なら、前
記工具立ての定義或いは曲げ順に対する更なる修正が、
前記ステーションモジュールにおけるオペレータ或いは
デザイナーにより実行される。
【0246】この発明の種々の他の特徴は、前記曲げプ
ランの生成における前記曲げオペレータを支援するため
に設けられる。例えばこの発明の他の側面によれば、工
具立てエキスパートが設けられ、前記曲げオペレータに
対して前記曲げモデルに格納されたパーツ形状及び他の
情報に基づいて、工具立て及び曲げ順の示唆を自動的に
与える。前記工具立てエキスパートからの示唆は当該示
唆の分析の後、曲げオペレータにより改定される。更
に、より複雑な工具立てエキスパートシステムが提供さ
れ、前記曲げファイルにおける前記パーツの形状、及び
潜在的な衝突及び干渉をチェックするための工具の形状
分析に基づいて更に複雑な操作について工具立て示唆及
び曲げ順示唆を行なう。そのようなエキスパートシステ
ムは手動或いはロボットにより支援された曲げ機械装置
により使用され実行される。限定しない例として、この
発明はデービッドAボーン等の名前による「板金曲げプ
ランを生成し且つ実行するための知的システム」と題さ
れる米国特許出願第08−386.369、及びデービ
ッドAボーン等の名前による「ロボットウインドウの計
画/制御の方法」と題される米国特許出願第08−33
8.115号に開示される特徴及び教示により実行され
る。これらの開示はここに全体として参照により積極的
に取り込まれる。上記したように図形的ユーザインタフ
ェース或いは種々の機能は、板金パーツのための曲げプ
ランを生成する際に曲げオペレータを支援するために設
けられる。この発明の他の側面によれば、追加の特徴が
更に設けられ、前記パーツの設計及び製造において支援
を行なう。以下に更に十分に説明するように、音声的或
いは視覚的情報の格納のごとき種々のマルチメディア機
能が本発明において実行され前記曲げプランを生成し或
いは曲げ順を実行する際に曲げオペレータに対して追加
の支援を行なう。更に、中間の曲げ段階の各々において
前記工具及びパーツの間の潜在的干渉及び衝突を自動的
にチェックする衝突チェック機能が提供される。この衝
突チェック機能は、工具形状及び、パーツにおける間隔
の面倒で時間のかかるマニュアルチェックに置き変わる
ために提供される。前記マニュアルチェックは曲げプラ
ンを生成する際曲げオペレータにより通常行なわれる。
これらの機能及びその他のものは添付する図面を参照し
て今から説明される。
【0247】この発明の1つの側面によれば、前記曲げ
モデルデータと共に音声及び映像情報を格納するための
方法が設けられる。種々の音声及び映像情報は、工場フ
ロアにおいて記録され、例えば板金パーツの操作及び曲
げ加工に関連する特殊な指令を提供する。この目的のた
めCCDカメラ又はディジタルカメラが音声マイクロフ
ォンと共に種々の場所10,12,14,…20のステ
ーションモジュールの各々に設けられる。他の装置、例
えばオーディオマイクロフォンを有するビデオカメラが
オペレータ或いはユーザが音声或いは映像の情報を記録
することを可能とするために前記ステーションモジュー
ルに設けられる。前記種々の記録装置は工場フロアにお
けるステーションモジュールコンピュータに接続され
る。限定しない事例としてインテルのPROSHARE
個人会議CCDカメラ(インテル株式会社から入手可
能)が音声及び映像情報を記録するために使用される。
他の商業的に入手可能なCCDカメラ或いはディジタル
カメラもそのような情報を記録するために使用される。
【0248】前記曲げモデルデータと共に格納された種
々の音声及び映像情報は種々の方法及び手続きにより、
ユーザによりアクセスされ且つ読み出される。例えば格
納された音声及び映像情報を再生するために、前記ステ
ーションモジュールによりメニューオプションが表示さ
れる。更に、この発明の好適な実施例によれば、オペレ
ータは、観察ウインドウに表示されるアイコンを選択し
且つ生成することにより、格納されている音声及び映像
情報を種々の表示スクリーン及びパーツの図に付随させ
る能力を有する。この機能は、ソフトウエア及びオブジ
ェクト指向プログラム技術により実行される。これによ
りアイコンオブジェクトは曲げモデルデータ構造の中に
生成され且つ格納される。このアイコンオブジェクト
は、ある種の条件(例えばマウスのダブルクリック或い
はジョイスティック或いは他の入力手段の使用による選
択の指示によるオペレータによるアイコンの選択)に基
づいてメモリから付随された音声及び映像情報を読み出
すための手続きを含む。この発明のアイコンの特徴によ
りオペレータは異なる音声及び映像メッセージ或いは情
報を前記板金パーツの異なる部分及び任意の表示に関連
させる。このアイコンを前記パーツの表現に組み込むこ
とにより、前記アイコンは、スクリーン上で画面が変わ
るにつれて前記パーツの2次元及び/又は3次元モデル
の表示と共にズームし、回転し並進運動するように構成
される。
【0249】図45は前記パーツの3次元ソリッドモデ
ルに張り付けられたアイコンの使用を介して音声及び映
像情報を添付する事例を図示する。ユーザが前記音声及
び映像情報を記録した後、オペレータが前記3次元モデ
ルウインドウの任意の位置にアイコンを張り付ける。前
記アイコンがオペレータ或いはユーザにより次に選択さ
れる時、格納された音声及び映像情報は再生され、前記
ウインドウに表示され、そのアイコンが配置された前記
パーツのある部分或いは領域に関する特殊な指令又はメ
ッセージを提供する。他の情報、例えば前記曲げ運動の
シミュレーション或いは記録は前記パーツの種々の曲げ
線の近傍にアイコンを置くことにより前記パーツに関連
される。前記曲げ運動に関連する映像情報は次に前記ア
イコンが選択される時ユーザに対して再生される。
【0250】オペレータ或いはユーザは、音声及び映像
情報を記録し、或いは単に1つの音声メッセージ或いは
静止或いは運動映像信号を記録し、それらはユーザに対
して選択的に再生される。前記ウインドウ表示に対して
付着されたアイコンは格納された情報のタイプを図形的
に指示する(例えば、音声情報が格納されていることを
示しているためにマイクロフォンのアイコンが表示され
又は映像情報が格納されていることを示すために表示モ
ニタのアイコンが表示される)。特殊なアイコンは、そ
のアイコンに音声及び映像情報が関連されていることを
示すために設けられる(例えば「A/V」の記号或いは
マイクロフォンを含むビデオカメラのアイコン)。アイ
コンの一覧が設けられ且つ表示され、ユーザが、前記ス
クリーン表示或いは画像に対して音声及び或いは映像情
報を添付する際に種々のアイコンから選択することを可
能とする。
【0251】図46は格納された音声及び映像情報を読
み出すためのアイコンを組み込んだ表示ウインドウの他
の事例を図示する。図46に表示された表示ウインドウ
は、図42を参照して上で説明したそれのごとき、工具
セットアップスクリーン画像に関連する。図46の例で
は、音声情報が格納され、マイクロフォンのアイコンに
より読み出される。そして別個の映像情報が格納され、
前記表示ウインドウに対してビデオアイコンを張り付け
ることにより読み出される。前記音声及び映像情報は工
具セットアップ或いは操作に関連する特殊な指令或いは
情報に関連する。更に現在活性化されているウインドウ
表示のタイプに関係なく、オペレータは、異なる音声及
び映像情報を後に読み出すために、前記ウインドウ表示
における種々の領域に必要なだけ多数のアイコンを張り
付けることができる。
【0252】この発明の他の側面によれば、画像編集ウ
インドウ特性が提供され、オペレータが格納された画像
を選択しそれらを異なるスクリーンへ適用するのを容易
にする。前記画像編集ウインドウ特性はウインドウに基
づくアプリケーションとして提供され、それは例えばサ
ーバモジュール32或いは製造設備を通して設けられた
ステーションモジュールのいずれかにおいてアクセスさ
れる。図47は、この発明の教示により実行される画像
編集(イメージ編集)ウインドウの例を図示する。前記
イメージ編集ウインドウに表示される画像はディジタル
カメラ或いはCADコーダによる画像写真を含む。前記
スクリーンに表示される画像はオペレータにより(例え
ばマウス或いは他の適当なデータ入力手段により)選択
的に選ばれ、他のスクリーンにコピーされ、それらはパ
ーツの特定のモデルの図に関連させられる。オペレータ
は次にその画像或いはアイコンを前記モデルのウインド
ウ(例えば図46に関連して上で示したそれのごとき前
記パーツの3次元ソリッドモデルウインドウ)へ張り付
ける。図45、46及び47の画像は実際のスクリーン
画像の写真再生である。実際の画像イメージは、使用さ
れるカメラ或いはスクリーンの解像度に応じてそれ自体
更に明瞭である。前記画像は例えば、曲げ操作に関連す
る特殊な操作或いは他の指令を議論し或いは図示する曲
げオペレータの静止或いは運動映像イメージを含み、或
いは板金曲げ操作の映像イメージである。換言するば、
有用であると思われる実際の画像が取られ後に表示され
る。従って図45−47に示される実際の画像は例示的
な目的のためのみのものである。図48及び49を参照
するに、この発明の衝突チェック機能の例が設けてあ
る。この発明の1つの側面によれば、衝突チェック機能
が設けられ、ユーザは前記パーツ及びパンチ工具の間の
潜在的な衝突を、図形的ユーザインタフェースの使用に
よりチェックすることを可能とする。前記衝突チェック
機能はウインドウズに基づくアプリケーションであり、
前記製造設備における任意のステーションモジュール或
いは場所でアクセスされる。この発明の自動的衝突チェ
ック機能は、前記曲げプランを生成する際に通常行なわ
れている伝統的なそして面倒なマニュアルの形状チェッ
クに変わり曲げオペレータにより使用される。
【0253】伝統的には、板金パーツの曲げプランを生
成する際、曲げオペレータはまず前記パーツの曲げ順を
決定する。前記曲げ順は前記板金パーツが製造の間に曲
げられる順番或いは態様を決定する。その曲げ順が決定
された後、曲げオペレータはその曲げ操作の各々を実行
するために使用される工具を選択し定義する。この過程
で、選択された前記工具の形状及び前記パーツの中間的
形状が、前記曲げ工程の各々を実行する際に前記工具と
パーツとの間の干渉あるいは衝突が存在しないことを確
実にするために解析される。衝突或いは干渉が検出され
る場合には、選択された工具のタイプ(或いは必要に応
じて曲げ順)は、前記工具と板金パーツとの間の干渉或
いは衝突を生ずることなく曲げ操作が実行されるように
修正されなければならない。
【0254】潜在的な衝突或いは干渉を検出する際に、
前記工具の形状と板金要素の曲げられた部分或いは形状
との間のクリアランスを分析するために、曲げオペレー
タは伝統的にマニュアルの方法に頼っていた。典型的に
は、曲げオペレータにより工具形状のモデルが構成され
使用されている。工具形状モデルは、板金の種々の中間
的形状の工学的或いは技術的図面(前記工具形状モデル
と同じスケールの寸法を有する)に対してマニュアルで
合わせられ或いはその上に置かれる。この工具形状モデ
ルを前記パーツの図面に対して適合させ及び合わせるこ
とにより前記曲げオペレータは、曲げ工程の各々におい
て工具とパーツとの間に十分な空間或いはクリアランス
があるかどうかを決定することができる。しかしながら
この工程は面倒で且つ時間を浪費する傾向がある。
【0255】この発明は自動的干渉チェック機能を設け
ることにより、そのような伝統的な方法の不利益を克服
することである。この発明の干渉チェック機能は、図形
的ユーザインタフェースを介して実行され、曲げオペレ
ータが所定の曲げ順における各中間的工程において衝突
をチェックするのを可能とする。図48及び49は図形
的ユーザインタフェースを介して実行される衝突チェッ
ク機能の例を図示する。活性化される時、前記衝突チェ
ック機能は前記曲げ順における前記パーツの各中間的形
状とその順番に対して定義されるパンチ工具或いは複数
の工具との間の衝突を自動的にチェックする。前記中間
形状はスクリーンに表示され(例えば図48及び49を
見よ)、衝突が発見されると、当該衝突が検出される工
程がスクリーン上に強調される。更にテキストのごとき
他の表示示唆が検出された衝突の数を指示するために提
供される。図48及び49の例では、前記衝突情報は表
示ウインドウの右上領域に提供される。更に、前記衝突
がチェックされたパンチ工具或いは複数の工具のタイプ
は表示ウインドウの左上領域に表示され或いは指示され
る。
【0256】衝突が、オペレータにより選択されたパン
チ工具について検出される時、衝突が検出される中間的
形状或いは段階がスクリーン上に強調される。この場
合、オペレータはその特定の曲げ段階について他のパン
チ工具を選択することもでき、前記パンチ工具の第2の
選択について衝突が起きるか否か決定するために前記衝
突チェック機能が再び実行される。オペレータは、各曲
げについてパンチ工具を選択し、前記衝突チェック機能
により衝突をチェックすることができる。ドラッグ及び
ドロップ編集が、中間的曲げ形状をドラッグし、それを
前記提案された曲げ順内の所望の位置へドロップするこ
とにより、前記ウインドウ表示中に表示された曲げ順を
オペレータが変更することを可能とするように設けられ
てもよい。前記曲げ順は図44を参照して上に記載した
それと同様の対応で、オペレータによりなされた前記ド
ラッグ及びドロップ編集に基づいて修正される。
【0257】この発明の衝突チェック機能を実行するた
めに種々の手続き及び操作が使用される。例えば潜在的
な衝突を検出するために、選択された工具の幾何形状と
中間的形状におけるパーツの幾何形状とがアクセスされ
る。各中間工程における前記パーツに関連する幾何形状
データは前記曲げ順及びパーツ寸法及びトポロジーデー
タに基づいて生成される。前記パーツの各フランジは、
前記曲げ順における各中間段階における前記パーツを表
示するために、曲げデータ(例えば曲げ角度、曲げ線位
置、縮小量等)に応じて折り曲げられる。上記折り曲げ
工程及びこの発明の縮小量補償特性は各中間段階での前
記パーツに対する幾何形状データを生成する際に適用さ
れる。この工具及びパーツの幾何形状により、前記曲げ
段階の各々において前記工具の先端をパーツの曲げ線へ
置くことにより、前記工具及びパーツが相互に配向され
る。衝突は、前記幾何学的データ及び前記工具とパーツ
との境界を分析し、前記工具及びパーツにおいて共通な
点或いは重なり合う点が存在するか否かを決定すること
により検出される。衝突は、特定の曲げ工程で検出され
る時、その工程は、ユーザに対して衝突の検出を示すた
めにスクリーン上で強調される。衝突を検出するために
使用される工具データは、ユーザによりなされる工具選
択に基づいて、工具形状ライブラリから積極的に取り出
される。任意の中間曲げ工程での衝突の再計算は異なる
工具形状或いは曲げ順の修正に基づいて行なわれる。そ
のような機能を設け、ここに記載されるごとき、図形的
ユーザインタファースを用いてそのような情報を表示す
ることにより、衝突の可能性は、曲げオペレータによ
り、より容易に決定され且つ修正される。
【0258】上記したように、ジョイスティック或いは
マウス装置は、板金パーツの表示されるモデルを観察す
る際、ユーザが選択的に種々の観察機能(例えばズー
ム、パン、回転等)を活性化し及び制御することを可能
とするために、前記製造設備を通して前記ステーション
モジュールの各々及びそれらの場所に設けられる。前記
ジョイスティック装置は多重の軸を有するジョイスティ
ックで、選択或いは制御ボタンを有する。前記ジョイス
ティックはマイクロソフト・サイドワインダ・ジョイス
ティックを含む種々の商業的に入手可能なジョイスティ
ック装置を介して実行され、各ステーションモジュール
及び/又は当該設備の他の位置のコンピュータのゲーム
ポートに差し込まれる。前記マウスはまたウンドウズ9
5或いはウインドウズNTのごとき任意の商業的に入手
可能なマウスをサポートするソフトウエア及び、各設備
位置におけるコンピュータのゲームポート或いはマウス
ポートに差し込まれる任意の商業的に入手可能なマウス
装置により実行される。
【0259】限定しない事例として図50−55は、ジ
ョイスティック装置或いはマウス装置を用いて、3次元
幾何学的形状を操作し且つ前記パーツを表示するための
システムの種々の側面を図示する。この発明の3次元ナ
ビゲーションシステムは、ユーザが回転、ズーミング及
びパンニングのごとき種々の観察機能を制御することを
可能とする。この発明の1つの側面によれば、システム
はまた3次元モデルを観察する際に、現在のズーム画像
に基づいて計算される動力学的回転軸を用いる。この側
面によれば、回転の中心は現在の図及びズーム比或いは
係数に基づいて動力学的に変化され且つ計算され、従っ
て前記パーツのズームされた領域は前記パーツが例えば
高いズーム比或いは係数において回転される時、前記ス
クリーンから消えることがない。
【0260】この発明の1つの側面によれば、3次元操
作及びナビゲーションシステムが前記設備のステーショ
ンモジュール及び/又はサーバモジュールに提供され
る。3次元ナビゲーションシステムの工程及び操作は、
ソフトウエア或いはプログラムされた論理を介して且つ
広い範囲のプログラム言語及び教示の1つを用いて実行
される。例えば前記システムはC++のごとき高レベル
のプログラム言語を用いて且つオブジェクト指向プログ
ラム技術を用いて実行される。更に限定しない例とし
て、VISUAL C++が使用される。それはウィン
ドウズに基づくアプリケーションのためにマイクロソフ
ト株式会社により提供されるC++プログラム言語の1
つのバージョンである。前記観察機能(例えばズーム、
回転、パン等)は上記した本発明の曲げモデルビューア
の観察クラスの要素機能として実行される(例えば図2
7及び上記関連の開示を見よ)。前記現在ズーム係数及
びパーツの位置(例えば3次元空間におけるパーツの位
置)に関する情報は、また、前記動力学的回転軸を計算
し且つ所望の観察機能を提供するために前記曲げモデル
ビューアからアクセスされる。
【0261】種々のハードウエア成分及びインタフェー
スが、本発明の3次元ナビゲーションシステムを実行す
るために提供される。例えばシステムを実行するために
使用されるソフトウエアが前記ステーションモジュール
及びサーバモジュールのコンピュータ或いはパーソナル
コンピュータに設けて有り或いは存在する。上で議論し
たように、前記コンピュータ或いはパーソナルコンピュ
ータは、板金パーツの3次元表示をユーザに対して表示
するために、高解像度モニタのごとき図形カード及び表
示スクリーン或いはターミナルを含む。前記コンピュー
タ或いはパーソナルコンピュータはまた、前記マウス或
いはジョイスティック装置と接続し及びインタフェース
するためのマウス或いはゲームポートアダプタを含む。
商業的に入手可能なソフトウエアも設けられており、ユ
ーザにより操作されるマウス或いはジョイスティック装
置からマウス或いはゲームアダプタカードにより受信さ
れる指令信号を解釈する。
【0262】図50a及び50bは、例えば単純な3次
元箱形状パーツを回転するために多重軸ジョイスティッ
ク112により行われる回転機能の例を図示する。上に
述べたように、ジョイスティックは設備を通して設けら
れているステーションモジュール及び/又はサーバモジ
ュールに設けられているコンピュータ或いは装置に設け
られ且つ接続されている。図50a及び50bに示すよ
うに、前記パーツの回転は、前記ジョイスティック11
2を前後に且つ左右に移動することにより行なわれる。
前記回転軸の方向或いは向きは前記ジョイスティック1
12(或いはマウス)の移動に基づいて設定される。例
えば前記ジョイスティック112を前後に移動させるこ
とは、パーツを前記X座標軸に沿って定義される回転軸
の周りに時計方向或いは反時計方向に回転させることを
もたらす(例えば図50aを見よ)。更に前記ジョイス
ティック112を左右に動かすことは、前記パーツを前
記Y座標軸に沿って定義される回転軸を中心として時計
方向或いは反時計方向に回転させることをもたらす(例
えば図50bを見よ)。
【0263】現在の図のズーム比或いは係数が低く、パ
ーツの全体表示がスクリーン上に提供される時、前記回
転軸は前記パーツの幾何学的中心或いは図芯を通るよう
に定義される。上記したように、前記ズーム係数及びス
クリーン上のパーツの観察可能性は、本発明の曲げモデ
ルビューアにより提供される観察可能性機能に基づいて
決定される。スクリーン上にパーツ全体が表示されると
判断される時(図50a及び50bにおけるそれのよう
に)、回転軸を定義しそしてその回転軸を前記パーツの
幾何学中心へ設定するために座標幾何技術が用いられ
る。前記パーツの回転は、次に、前記ジョイスティック
装置のユーザにより定義された移動に基づき、且つこの
発明の曲げモデルビューアの回転要素観察機能を介して
実行される。しかし仮に前記オブジェクトの一部のみが
画面に表示され、前記パーツの幾つかの部分は見えない
場合(例えば高いズーム係数或いは比率が選択された
時)、前記回転軸は、前記パーツの幾何学中心或いは図
芯に維持されるべきではない。それはそのようにするこ
とは、回転中に前記パーツのズーム化された部分がスク
リーンから消えるからである。実際この発明によれば、
ズーム比が増大される時、回転軸は動力学的に再計算さ
れ、前記スクリーンのセンターにおける観察点(或いは
カメラ視野)に最も近い点の座標を通る。前記ズーム係
数の変化に基づいて、前記回転軸を動力学的に再計算す
ることにより、前記パーツは、前記パーツの観察可能な
部分が回転の間に画面からはみ出すことにならない軸を
中心として回転される。
【0264】前記3次元モデルのズーミング及びパンニ
ングを行なうために、前記ジョイスティック或いはマウ
ス装置と別個に或いはそれと共に設けられたキーパッド
に追加の制御ボタンが設けられる。例えばズームボタン
114を押すと共に、ジョイスティック112を前後に
移動することにより、図51に示すように、所定の割合
で前記パーツはズームインまたはズームアウトされる。
上記したように、前記回転軸は各ズームウィンドウの中
で再計算され、回転がなされる時、ユーザが前記パーツ
のズーム化された部分を観察することができるようにす
る。更に、3次元形状のパンニングは、図52に示すよ
うに、パンボタン116を押圧し或いは活性化し且つジ
ョイスティック112を移動することにより、ユーザに
より制御される。前記ズームボタン114の場合と同様
に、パンボタン116は前記設備の種々の位置の各々に
おける前記ジョイスティックまたはマウス装置と別個に
或いはそれらと一緒に設けられたディジタル入力パッド
の上に設けてある。
【0265】この発明の代表的な実施例に応じて、前記
3次元ナビゲーション及び操作を実行するために設けら
れた種々の工程及び操作が図53−55を参照して以下
に記載される。上に示したように、前記3次元ナビゲー
ションシステムの必要な工程及び操作はソフトウエア或
いはプログラムロジック及びハードウエア成分及びイン
タフェースの組み合わせを介して実行される。ジョイス
ティック或いはマウス装置のごときユーザにより制御さ
れる装置からの入力信号は所望の表示されたパーツの運
動及び再配向の量を決めるように解釈される。この発明
によれば、表示されたパーツの回転軸は、回転中にパー
ツのズーム化された領域が画面から消えるのを防止する
ため、現在の画面及びズーム係数に基づいて動力学的に
計算される。
【0266】表示されたパーツの現在の画面を更新する
際に、図53のステップS301に一般的に示されるよ
うに、前記ジョイスティック或いはマウス装置の操作に
基づいてユーザからの信号が受信される。ユーザにより
前記ジョイスティック或いはマウス装置の特定の方向の
運動及び/又は特殊な制御ボタンの活性化との組み合わ
せが、所定の観察機能(例えば回転、ズーム、パン等)
及び表示されたパーツの所定の方向(例えば時計回り或
いは反時計回り、ズームイン又はズームアウト、右又は
左等)の運動を、図50−52に例えば示されるよう
に、引き起こす。受信された信号は、それらがジョイス
ティックからであるかマウス装置であるかを問わず、カ
ーソルの移動に写像され、ユーザにより所望されるスク
リーン上の移動量を決定する。ユーザが前記観察機能モ
ードのうちの1つに存在しない場合(例えばユーザがス
クリーン上の情報を選択しているか或いはダイアログボ
ックス或いはウィンドウ内の情報を観察している場
合)、前記受信した信号の写像は要求されない。
【0267】当業者により理解されるように、通常のジ
ョイスティック或いはマウス装置から受信される信号は
スクリーン空間のそれとは異なる座標或いは参照システ
ムに基づいており、従ってそれらは前記スクリーン上の
カーソル移動に関する意味のある情報を提供するために
翻訳されなければならない。従って前記ユーザからの入
力信号を受け取った後、ステップS303に示されるよ
うに、回転軸の計算及び表示されたパーツの現在の図を
更新する前に受信された信号はカーソル移動に写像され
る。
【0268】ユーザにより制御される装置からの入力信
号をスクリーン空間上のカーソル運動に翻訳及び写像す
るために異なる方法及び工程が使用される。伝統的に
は、マウス装置の移動は、商業的に入手可能なソフトウ
エアによりカーソル移動へ翻訳され且つ写像されてい
た。例えばウィンドウズ95及びウィンドウズNTは、
マウス移動をカーソル移動へ翻訳するためのソフトウエ
アルーチンを含む。従って、マウス装置の移動は、その
ような商業的に入手可能なソフトウエアによりカーソル
移動に写像される。しかしながらユーザにジョイスティ
ックインタフェースが与えられている場合、有用な情報
を提供するには、前記ジョイスティック運動もカーソル
運動へ翻訳され且つ写像されなければならない。前記ジ
ョイスティック仮想空間におけるジョイスティックの運
動をスクリーン空間におけるカーソル運動へ写像するた
めに種々の方法及び技術が使用される。例えば、ジョイ
スティックの移動信号は、最終的にカーソル運動へ写像
される前に、まずマウス運動へ加工され且つ翻訳され
る。或いは、前記ジョイスティック仮想空間のサイズに
対するスクリーン空間のサイズの比率の関数として、前
記ジョイスティック信号は直接カーソル運動へ写像され
る。
【0269】図54は、この発明の1つの側面に基づ
く、ジョイスティック運動のスクリーン空間内でのカー
ソル運動への写像の例を図示する。上に示したように、
ジョイスティック装置は自身の仮想的座標システム或い
は空間218を含む。前記ジョイスティック仮想空間2
18は、前記ジョイスティックが中心或いは中立位置
(即ちジョイスティックが移動しない位置)に存在する
位置に対応する原点J1を含む。前記ジョイスティック
が新しい位置(例えば図54に示されるように現在の位
置J2)へ移動する時、前記ジョイスティック装置は前
記ジョイスティックの仮想空間内での新しい或いは現在
の位置を示す信号を生成する。前記ジョイスティック仮
想空間218は、しばしばスクリーン空間212よりも
大きい(画素の意味で)ので、前記ジョイスティックの
仮想座標及び移動は、所望のカーソル移動従ってスクリ
ーン上でのパーツの移動を決定するためにスクリーン座
標へ翻訳されなければならない。
【0270】前記ジョイスティックの仮想座標移動をス
クリーン座標移動へ写像し且つ翻訳するために種々の方
法及び工程が使用される。例えば、前記ジョイスティッ
ク仮想空間サイズに対するスクリーン空間サイズの比率
に基づいて、ジョイスティック運動はスクリーンカーソ
ル運動へ写像される。より詳細には、観察機能モード
(例えばズーム、回転、パン等)が活性化され、ジョイ
スティック装置がユーザにより操作された時、前回の点
C1から現在の点C2へのカーソルの実際の移動は次の
式で決定される。
【0271】 現在の点=前回の点+(スケール係数x V) ここに「現在の点」はカーソルの現在の点C2であり、
「前回の点」は前記カーソルの前回の点C1であり、
「スケール係数」はジョイスティック仮想空間サイズに
対するスクリーンサイズの比であり(いずれも画素にお
いて)、「V」はジョイスティック原点J1からジョイ
スティック現在位置J2へのジョイスティックの運動及
び方向を表すベクトルである。従ってジョイスティック
運動をカーソル運動へ写像するために、ジョイスティッ
ク装置がユーザにより操作される時ジョイスティック装
置から受け取られる信号に基づいて、前記原点J1から
現在位置J2へのジョイスティックの方向及び運動を示
すベクトル「V」が最初に計算される。このベクトル
「V」が計算された後、前記ジョイスティック運動は、
前記方程式における前記ベクトル「V」量及び前記「ス
ケール係数」量を用いてカーソル運動へ写像される。即
ち、前記カーソルの新しい或いは現在の位置C2は、前
記ベクトル「V」に前記ジョイスティック空間サイズに
対するスクリーンサイズの比(即ちスケール係数)を掛
け合わせ、次にこの計算の結果を以前のカーソル位置C
1に足し合わせることにより計算される。
【0272】前記スケール係数に応じて、前記スケール
或いは運動の割合を所定の或いはユーザにより選択され
た調整係数だけ増大し又は減少することが必要となる。
そのような場合には、そしてユーザの好みにより、前記
スケールの割合を増大し又は減少するために、前記カー
ソルの現在位置を計算する時に、前記スケール係数に調
整係数が掛けられる。例えば、前記ジョイスティック空
間サイズに対するスクリーンサイズの割合がスケール係
数1/64を与える場合、ジョイスティックの運動とス
クリーン上の表示されたパーツの運動の割合との間の一
層満足できる関係を与えるために、スケールの割合を増
大するのが望ましい。限定的でない例として、スケール
係数1/64について、前記表示されたパーツをズーム
し或いは回転する際調整係数3が用いられる。更にスケ
ール係数1/64について、表示されたパーツのパンニ
ングが行なわれる際には調整係数6が使用される。勿
論、スケーリング(縮尺)の割合は、ユーザの特定の必
要に基づいて修正され、前記調整係数は予め決定され或
いはユーザが、前記スケールの割合を修正するための調
整係数を調整或いは選択するためにオプションを与え
る。更に上に議論した事例において示したように、前記
調整係数は複数の観察機能の各々について同じ量に設定
されてもよいし、前記観察機能の各々について、同じ或
いは異なる量に個別に設定されてもよい。
【0273】受信された信号が適当に写像され翻訳され
た後、前記パーツの回転軸が、図53のステップS30
5に一般的に示されるように動力学的に計算される。前
記パーツの現在の図に依存して、前記パーツが例えば高
いズーム比率或いはファクターで回転される時、前記パ
ーツのズーム化された領域がスクリーンから消えないよ
うに、前記回転軸は前記パーツの中心を通るか或いは他
の点を通るか決定される。現在のズーム図に基づいて、
前記パーツの回転軸を動力学的に再計算するために種々
の方法及び工程が使用される。この発明の他の側面に応
じて、図55は前記パーツの図がユーザにより修正され
た時常に前記回転軸を計算するために行なわれるプロセ
ス及び工程の代表的論理フロー及び手順を図示する。
【0274】図55に示されるように、現在のズーム係
数或いは比率及びパーツの位置及び現在の図がステップ
S311及びS313で決定される。ユーザにより選択
された表示パーツのズーム係数及び向きが、パーツ全体
をスクリーン上で観察可能にする(即ち全体図)か、或
いは前記パーツの一部のみをスクリーン上で観察可能に
する(即ち部分図)。従って現在のズーム係数及びパー
ツの向きが、表示パーツの回転軸を適正に設定するため
に定められなければならない。前記パーツの現在の図を
決定するために種々の方法及び工程が使用される。上に
記載したように、観察可能性機能は、本発明の曲げモデ
ルビューアを備え、表示される画像に対する変更が存在
する場合には何時も、現在の図の向き及びズーム比率の
状態を維持しそして更新する。前記曲げモデルビューア
に対する機能コールがなされ、前記パーツのどの点或い
は部分が現在観察可能であるかを決定する。スクリーン
上に前記パーツの全てが表示されているかどうかは画像
体積をパーツの境界基本線サイズと比較することにより
決定される。
【0275】ステップS315でパーツの全体図が現在
スクリーン上で観察可能であると決定される場合には、
ステップS317で前記回転軸は前記パーツの中心を通
るように設定される。全体図が存在する時、前記パーツ
の中心を前記回転軸が通るように設定することは可能で
ある。というのは全体が表示されたパーツはユーザによ
り回転される時スクリーン上で観察可能であるからであ
る。スクリーン上で全てのパーツが観察可能である時、
回転軸はパーツの幾何学中心或いは図芯を取るように定
義される。従来の座標幾何学技術が、前記パーツの幾何
学中心へ前記回転軸を定義し設定するために用いられ
る。更に前記回転軸の方向は、前記前回のカーソル位置
から現在のカーソル位置へのベクトルに直交するベクト
ルとして定義されることもできる。
【0276】ステップS315で、スクリーン上にパー
ツの部分図のみが現在観察可能であると判断される場
合、ズーム化されたパーツがユーザにより回転される時
表示されたパーツの一部がスクリーンから消えないよう
にするために、回転軸を計算するために、前記論理フロ
ーはステップS319−S325へ引き続く。上記した
ように、ユーザにより高いズーム係数が選択され前記パ
ーツの一部のみがスクリーン上に表示される時、前記回
転軸は、前記パーツの幾何学中心を通るように設定され
てはならない。というのは、そのようにすることは、回
転中に表示されたパーツのズーム化された部分(ズーム
アップされた部分)がスクリーンから消えるからであ
る。パーツの表示された部分がスクリーンから見えなく
なり或いは消えることを防止するために、スクリーンの
中心における観察点(即ちカメラ)に最も近い点の座標
を前記回転軸が通るようにされなければならない。その
ような場合、回転軸の向きは前回のカーソル位置から今
回のカーソル位置へのベクトルに直交するベクトルとし
て定義されても良い。
【0277】従ってステップS319で、スクリーンの
中心が決定され、カメラに最も近いスクリーンの中心に
おけるオブジェクト或いは前記パーツの部分が選択され
る。即ち、スクリーンのセンターに位置する表示パーツ
の部分及びカメラに最も近い或いはスクリーンのユーザ
の観察点に最も近い表示パーツの部分が取り出される。
ステップS321で、前記カメラにおけるオブジェクト
が存在すること(例えば前記スクリーンの中心に位置し
且つ前記カメラに最も近い前記パーツのソリッド部分が
存在すること)が決定される場合、ステップS325で
前記回転軸は前記取り出された点を通るように設定され
る。上記したように、回転軸の方向は前回のカーソル位
置から今回のカーソル位置へのベクトルに直交するベク
トルとして定義されても良い。
【0278】ステップS321でカメラにおけるオブジ
ェクトが存在しない(例えば前記パーツは前記スクリー
ンの中心に位置し且つ前記カメラに最も近い穴或いは開
口部を含む)と判断される場合、論理フローはステップ
S323へ引き続く。ステップS323で、前記回転軸
は前記スクリーンの中心(例えば前記スクリーンの物理
的中心のX及びY座標)を通り且つ前記パーツの幾何学
中心に等しいZ座標(深さ)にあるように定義される。
従って回転軸は前記X,Y,Z座標を通るように設定さ
れ、回転軸の向きは前回のカーソル位置から今回のカー
ソル位置へのベクトルに直交するベクトルとして定義さ
れても良い。
【0279】図53を再び参照するに、前記動力学的回
転軸が決定された後、選択された観察機能(例えばズー
ム、回転、パン等)がステップS307で呼び出され
る。上記したように3次元操作システムの種々の観察機
能は前記曲げモデルビューア観察クラスの要素機能とし
て定義され実行される(例えば図27及び関連する上記
開示を見よ)。そのような場合、ユーザにより選択され
た観察機能に基づいて、機能コールが前記曲げモデルビ
ューアになされ、ステップS309で表示されたパーツ
の現在の図が更新される。前記パーツの現在の図及び向
きは、ユーザにより選択された観察機能及びユーザによ
り操作された入力装置(マウス或いはジョイスティック
装置)からの受信された写像カーソル運動に基づいて更
新される。オープンGL或いはレンダウェアのごときグ
ラフィックパッケージが、ユーザに提供される現在の図
の更新を容易にするために提供される。図53及び55
の代表的フローチャートにおいて行なわれる論理フロー
及びプロセスはソフトウエアにより及び広い種類のプロ
グラム言語及び技術を用いて実行される。例えばオブジ
ェクト指向プログラム技術及びC++が前記プロセス或
いは操作を実行するために使用される。この発明の3次
元操作システムを実行するための代表的コードが付録L
に提供される。代表的コードはC++プログラム言語で
書かれ、前記動力学的回転軸を計算するための種々の工
程及び操作を含む。付録Lのコードにはコメントが提供
され、そこに使用される論理及びアルゴリズムの解析を
容易にする。
【0280】上記3次元操作システムはジョイスティッ
ク装置及び制御ボタンの使用に関して記載されている
が、このシステムは、マウス或いはキーボードを含む他
の特定のタイプの入力手段により実行されることもでき
る。更に図51−52の上記実施例では、前記オブジェ
クトのスクリーンから無限への又はその反対のズーミン
グ或いはパンニングを制限するために境界が定義され
る。というのは連続的なズーミング或いはパンニングは
システムを故障させ或いは破壊させるからである。
【0281】更に、前記ジョイスティックインタフェー
スに関連して種々の他の機能が実行される。例えば、前
記観察機能のいずれかにおける移動は、ジョイスティッ
クがジョイスティックセンター位置から所定の範囲或い
は距離を越えて移動されなければ実行されない。パーツ
の移動が許される前にそのようなジョイスティックの移
動のしきい値を要求することは、前記中心点からの前記
ジョイスティックの不注意な操作或いは押圧に基づい
て、表示されたパーツの偶然の移動の発生を防止する。
ユーザとのジョイスティックインタフェース及びシステ
ム相互作用を改善するために他の機能がまた設けられ
る。例えばユーザによるジョイスティックの単一の操作
に基づいて、前記観察機能(例えばズーム、回転、パン
等)のいずれか1つにおける連続的或いは増加的(例え
ばステップごと)の移動が提供される。前記連続的或い
は増加的移動の選択はまた単一の方向におけるジョイス
ティックの移動の量或いは時間に基づいて提供される。
必要ならば表示されるパーツのスケール或いは移動の割
合は、任意の方向におけるジョイスティックの運動の程
度或いは時間に基づいて増加される。上記した速度調整
係数の修正はまた、ユーザが前記スケールの比率を増加
し或いは減少するために、マニュアルで調整係数に対す
る補正を入力することを可能とすることにより実行され
る。
【0282】工場における部品の設計及び製造における
支援を行なうために、本発明において種々の他の機能及
び実施例が実行される。例えば各顧客のオーダに関する
情報を追跡し且つアクセスするためにバーコードシステ
ムが実行される。所定の参照番号或いは作業番号を有す
るバーコードが顧客により注文される各部品へ割り当て
られる。このバーコードはデータベース30にアクセス
し作業情報を読み取るために用いられる。ユタ、サンデ
ィにおけるゼブラテクノロジVTIからのバーコード・
エニシング・バーコードSCAN CCDセンサのごと
きバーコードリーダ或いはスキャナが各場所に設けら
れ、ユーザが前記サーバモジュール或いはステーション
モジュールにおいて所定の作業のためのバーコードをス
キャンすることを可能にし、またデータベース30に格
納されているそのパーツに付随する重要な設計及び製造
情報をアクセスし読み出すことを可能にする。前記バー
コードリーダは各ステーションモジュール及び/或いは
サーバモジュールのコンピュータに差し込まれている。
前記バーコードは任意の通常のバーコードフォーマット
に基づいてフォーマット化されている。例えばUPS−
A CODA BARCODE39 EAN/JAN−
8或いはPLESSEYである。そして結果としてのバ
ーコードナンバーはルックアップテーブルに基づいて翻
訳され、前記データベースから作業情報を読み出すため
に、対応する作業参照番号及び/又はファイル名を検出
する。或いは、前記作業番号は、工場全体にわたって存
在する任意のステーションにおいて表示される指示へタ
イプ入力され或いはそこから選択され、瞬時にユーザの
位置で作業情報を読み出し表示する。そのような情報を
瞬時に読み出す能力は、コミュニケーションネットワー
ク26の使用及びデータベース30のごとき中央に位置
するデータベースへの前記デザイン及び情報の格納によ
り支援される。
【0283】この発明の更に他の側面によれば、作業を
スケジュールし割り当てるための装置及び方法が提案さ
れるシステムに設けられる。従来、製造設備にわたる作
業のスケジュール化及び割り当てはショップ或いは工場
の工場長により行なわれた。工場長は、機械装置の現在
のセットアップ及び利用可能性のみならず現在の仕事の
状態を決定する。これらの情報を集め且つ分析した後、
ショップ或いは工場の工場長はスケジュールを生成し且
つ工場における種々の場所においてなされる作業につい
て割り当てを分配する(例えば工場フロアに分配される
作業スケジュールシートの形態で)。作業のスケジュー
ル割り当ては、各顧客の作業がタイミングの良い形態で
且つ所定の出荷日までに完了することを確実にするため
に行なわれる。作業のスケジュール化及び割り当ての従
来の工程はしかし骨の折れるものであり、通常工場長に
よりマニュアルで行なわれていた。
【0284】この発明の1つの側面によれば、ショップ
或いは工場の工場長がその工場についての作業のスケジ
ュールを立てることを支援するために、作業割り当て及
びスケジュールシステムが設けられている。そのシステ
ムはコミュニケーションネットワーク及びデータベース
30に格納されている曲げモデル情報を利用し、自動的
に必要な情報を集め、従って工場長はより容易に作業ス
ケジュールを生成することができる。このシステムは、
前記サーバモジュール或いは工場にわたって配置されて
いるステーションモジュールにおいてソフトウエア又は
プログラムロジックを介して実行される。スケジュール
されるべき種々の作業を入力することにより、システム
ソフトウエアはデザイン及びパーツ情報を分析し所定の
作業を行なうためにどの機械が最も適しているかを決定
する。この目的のため、工場における機械の現在の状態
及びセットアップが定義され、データベース30に格納
され、作業スケジュールソフトウエアによりアクセスさ
れる。種々の条件に基づいて、表示の形態で、特定の作
業を実行するためにどの機械が利用可能であるか及びど
の機械が他の仕事を実行することができないかを示唆す
る。この点について、特定の作業について機械の利用可
能性をランク付けし且つ提案作業スケジュールを提供す
るテーブルが表示される。前記提案作業スケジュールは
工場長により実行され或いは修正される。作業スケジュ
ールを設定し且つ推薦するために使用される条件は広い
種類の条件を含む。そしてそれは、工場における各マシ
ンの現在のセットアップ、各作業について必要とされる
曲げのタイプ及び工具、及び同じ時間枠或いは時間の間
に実行されなければならない他のタイプの作業を含む。
どの機械が特定の作業を実行できるかを決定するため
に、前記曲げ角度、フランジ長さ及び曲げのタイプを含
む各パーツについての曲げモデルファイルからの情報が
利用される。例えばデータベース30に格納されている
テーブルは前記工場フロアにおけるパンチング及び曲げ
機械の各々の現在のセットアップ及び能力についての重
要な情報を含む。
【0285】提案された作業スケジュールに基づいて、
工場長は、工場の生産及び出力能力を最大限にするため
に、複数の作業を工場全体にわたる種々の場所へ割り当
てる。最後の作業スケジュール或いは割り当ては電子的
に入力されコミュニケーションネットワーク26を介し
て機械の各々へ送られる。
【0286】LEDのごときパイロットランプが曲げ及
び機械装置ワークステーションの各々に設けられ、その
ステーションに作業が割り当てられ転送されたことを指
示し且つ確認する。前記作業割り当て及びスケジュール
は、工場内の任意の位置から瞬時にアクセス可能なサー
バモジュールのファイルに格納される。上記機能に加え
て、その他の機能が、この発明の教示に応じて実行され
る。例えば種々のステーションモジュール或いは位置に
メニュースクリーンが設けられ且つ表示され、ユーザが
この発明の種々の表示及び機能モードを選択するのを容
易にする。例えば図56に示されるそれのごときメイン
のメニュースクリーンが、前記ステーションモジュール
が開始される際にユーザに対して提供される。このメイ
ンメニューウインドウ表示はステーションモジュールに
より提供される利用可能なウインドウ表示及び観察モー
ドの各々のアイコン画像を含む。このメインメニュース
クリーンはメニューボタン(例えばF1キー)が選択さ
れるとき何時でも現れる。ユーザは、強調されたブロッ
クを所望のウインドウアイコンへ移動しそれを選択する
ことによりそのウインドウを選択する。そのような操作
は、キーボード、マウス或いはジョイスティックの使用
を介して行なわれる。
【0287】他のウインドウスクリーンもユーザに対し
て提供され且つ表示され作業情報の入力及び表示を容易
にする。例えばパーツ情報ウインドウは、ユーザがパー
ツ情報を入力し或いは修正するのを可能にするために表
示される。パーツ情報ウインドウ表示の例が図57に与
えられる。このパーツ情報ウインドウは全ての関連する
パーツ情報(例えばパーツ番号、材料タイプ、寸法等)
を含み、板金パーツの2次元平面図及び等測投影法図を
含む。曲げ線情報ウインドウ(例えば図58に示される
もの)は、ユーザが各曲げ線についての曲げ順及び縮小
量を含む種々の曲げ線情報を監視することを可能とする
ために設けられる。前記曲げ線情報ウインドウはユーザ
が、各曲げについての曲げ線情報を入力し或いは修正す
るのを可能とし、板金パーツの2次元平面図及び等測投
影図を含む。
【0288】オペレータの曲げ順の分析を容易にするた
めに、追加のウインドウ表示が提供される。例えば曲げ
順ウインドウ表示及び曲げシミュレーションウインドウ
表示が提供され、前記パーツの種々の曲げ段階を表示
し、且つ曲げ操作中におけるパーツの向きをシミュレー
トする。図59に示されるような曲げ順ウインドウは前
記メインメニュースクリーンから選択され曲げ順の各段
階における前記パーツの(静止状態における)中間形状
をユーザに対して表示する。曲げシミュレーションウイ
ンドウ(例えば図60を見よ)もユーザにより選択さ
れ、曲げ段階の静止情報(スクリーンの右側に提供され
るパーツアイコンの形態で)及び、曲げ順における各段
階で行なわれる位置付け及び曲げの動的シミュレーショ
ン(表示装置の中央において)を提供する。スクリーン
上のパーツアイコンを間欠的に選択することにより、ユ
ーザは選択されたパーツアイコンにより表現される段階
における、曲げ加工中でのパーツの向きの動的シミュレ
ーションを見ることができる。各曲げ順を動的にシミュ
レートするために、パーツは反転され、並進移動され、
曲げ線の周りで曲げられ/回転される。
【0289】図57−60の上記ウインドウ表示の各々
は、図56のメインメニューウインドウ表示からユーザ
に対して選択され且つ表示される。更に、任意のステー
ションモジュールにおけるユーザは、メインメニューウ
インドウ表示において適宜のウインドウアイコンを選択
し、この発明の観察モード(例えば2次元平面、ワイヤ
フレーム、ソリッド、正射図)に応じて表示されるパー
ツの2次元及び/又は3次元表示を得る。これは図28
−31を参照して上で詳細に説明された。種々のメニュ
ーウインドウがまた例えばステーションモジュールに設
けられ、この発明の特性及び機能の操作を容易にする。
図61は2次元から3次元操作のために表示される代表
的メニューを図示する。更に図62はこの発明の2次元
クリーンアップ操作のための代表的メニュー構造を図示
する。この発明はしかしこれらのメニュー配置に限定さ
れるものではなく、他のメニュースクリーン及び/又は
工具アイコンバーが設けられ、ユーザのシステムとの相
互作用を容易にする。
【0290】他の特性もまたこの発明において実行され
る。例えば、高いレベルの自動装置も提供され曲げプラ
ンの生成を容易にする。例えば曲げ及び工具立てエキス
パートシステムが提供され、各作業についてのパーツの
幾何形状及び形状に基づいて工具立てセットアップ及び
曲げ順を生成し且つ提案する。それは例えば米国特許出
願出願番号08/386.369及び08/338.1
15に開示されるようなものである。
【0291】この発明は幾つかの代表的な実施例を参照
して記載されたがここで用いられた用語は、限定の用語
ではなく、記載及び説明の用語である。この発明の範囲
及び精神及び種々の側面から逸脱することなく種々の変
形がなされ得る。この発明はここで特定の手段、材料及
び実施例を参照して記載されたが、発明はここに開示さ
れた特定のものに限定されるように意図されるものでは
ない。むしろ発明は全ての機能的に等価な構造、方法及
び使用に広がる。
【0292】付録A 曲げモデルパーツからのフィーチャエンティティ抽出の
例 .int SPS_cal_part_matrix ( BM_PART *part, FENT **i
np_sp,char*pname,int *inp_parrank, int*inp_part_nu
mface,int *inp_part_numbend, int*inp_part_maxface
){// local variablesint parrank, part_numface, pa
rt_numbend, part_maxface ;int **imatrix = NULL ;in
t *nbl_face = NULL ;BENDFACE *facelist= NULL ;BEND
LINE *bendlinelist = NULL ;ARTIFICIAL_FACE *bendfa
celist = NULL ;int num_error = 0 ;//counter for th
e number of errors in the partint face_1, face_2,
bend_1, bend_0, i ;long num_of_faces, num_of_bendl
ines, entity_id;BM_FACE *face;BM_BENDLINE *ben
dline;BM_2D_BODY *two_d_body;BM_3D_BODY *three_d
_body;BM_BEND_OP *bend_op;BM_TOPOLOGY_RECORD *to
pology_record;// get name and number of faces and
bendlines of the partpart->get_name( pname ) ;doub
le thickness = part->get_metal_thickness();num_of_
faces = part->get_number_of_faces() ;num_of_bendli
nes = part->get_number_of_bendlines();if (num_of_f
aces == 0 || num_of_bendlines == 0)return ( -1 );/
/ create local working arrayfacelist = new BENDFAC
E [num_of_faces];bendlinelist = new BENDLINE [num_
of_bendlines];// count number of faces defined.dou
ble maxfacearea = -1.0 ;part_maxface = 0 ;part_num
face = 0 ;face = part->get_face_list() ;for ( i =
0 ; face && i < num_of_faces ;i++, face = (BM_FACE
*)(face->next())) { // Count the defined faces.//
initialize the strucfacelist[i].faceid = 0 ;facel
ist[i].facept =NULL ;facelist[i].twodpt = NULL ;fa
celist[i].threedpt = NULL ;facelist[i].topologyrec
pt = NULL ;facelist[i].numadjbody = 0 ;facelist
[i].numadjbend = 0 ;facelist[i].numadjhole = 0 ;fa
celist[i].numadjface = 0 ;facelist[i].face_area =
0. ;if (face == NULL) break ;two_d_body = face->ge
t_3D_version() ;if (two_d_body == NULL) continue ;
// It is considered as a valid face, when its BM_2
D_BODY exists.part_numface++ ;facelist[i].faceid =
part_numface ;facelist[i].facept = face ;facelist
[i].twodpt = two_d_body ;facelist[i].face_area = a
rea_of_a_2D_body(two_d_body) ;if (maxfacearea < fa
celist[i].face_area) {maxfacearea = facelist[i].fa
ce_area ;part_maxface = facelist[i].faceid ;} thre
e_d_body = two_d_body->get_3D_body() ;facelist[i].
threedpt = three_d_body ;if (three_d_body == NULL)
continue;entity_id = three_d_body->get_name() ;fa
celist[i].org_entity = entity_id ;topology_record
= three_d_body->get_adj_list() ;facelist[i].topolo
gyrecpt = topology_record ;if (topology_record ==
NULL) continue ;facelist[i].numadjbody = (int)topo
logy_record->get_number_of_adjacent_bodies() ;face
list[i].numadjface = (int)topology_record->get_num
ber_of_adjacent_faces() ;facelist[i].numadjhole =
(int)topology_record->get_number_of_adjacent_holes
() ;facelist[i].numadjbend = (int)topology_record-
>get_number_of_adjacent_bendlines() ;}if (num_erro
r > 0) {clean_up ( part_numface, imatrix, nbl_fac
e, facelist,bendlinelist, bendfacelist) ;return (
num_error ) ;}if (part_numface == 1) {// this is a
trivial case, where the partonly has one flat fac
e.*inp_part_numface = part_numface ;*inp_parrank =
part_numface ;*inp_part_numbend = 0 ;*inp_part_max
face = 1 ;*inp_sp = new FENT [2] ;*inp_sp[2] = Nul
lFent ;clean_up ( part_numface, imatrix, nbl_face,
facelist, bendlinelist, bendfacelist) ;return ( 0
) ;}// varify all the valid face, the current req
uirements are://1) A face cannot be adjacent to an
other face.//2)A face without an adjacent bendline
is not allowed.//(Note: The single faced part has
been processed.)// Also, creata pointer array tha
t links assigned part_face_id// to the netry in th
e facelist.int *fid_pt = new int [part_numface] ;f
or ( i = 0 ; i < num_of_faces ; i++) {if (facelist
[i].faceid) {fid_pt[facelist[i].faceid] = i ;if(fa
celist[i].numadjface ||facelist[i].numadjbend < 1)
num_error++ ;}}if(fid_pt) delete [] fid_pt ;if (n
um_error > 0) {clean_up ( part_numface,imatrix, nb
l_face, facelist, bendlinelist, bendfacelist) ;ret
urn ( num_error ) ;}// count the number of bendlin
es that is defined.part_numbend= 0 ;bendline = par
t->get_bendline_list() ; for ( i = 0 ; bendlin
e && i < num_of_bendlines ;i++, bendline = (BM_BEN
DLINE *)(bendline->next())) {// initialize the str
uctbendlinelist[i].bendlineid = 0 ; bendlinelist
[i].bendlinept = NULL ;// BM_BENDLINE pointer bend
linelist[i].bendoppt= NULL ;// BM_BEND_OP pointerb
endlinelist[i].twodpt = NULL ;// BM_2D_BODY poi
nterbendlinelist[i].threedpt = NULL ;// BM_3D_BO
DY pointerbendlinelist[i].topologyrecpt = NULL ;//
BM_TOPOLOGY_RECORD pointerbendlinelist[i].numadjb
ody = 0 ;bendlinelist[i].numadjbend = 0 ;bendlinel
ist[i].numadjhole = 0 ;bendlinelist[i].numadjface
= 0 ; if (bendline == NULL) break ;two_d_body =
bendline->get_3D_version() ;if (two_d_body == NUL
L) continue ;// It is considered as a valid bendli
ne, when its BM_2D_BODY exists.part_numbend++ ;ben
dlinelist[i].bendlineid = part_numbend ; bendlinel
ist[i].bendlinept = bendline ;// BM_BENDLINE point
er bendlinelist[i].twodpt = two_d_body ; // BM_2D_
BODY pointerbend_op = bendline->get_bend_op() ; be
ndlinelist[i].bendoppt = bend_op ;// BM_BEND_OP po
interif (bend_op == NULL) num_error++ ;// Note: Be
nd operation must be defined for each // ben
dline, otherwise it is an error.three_d_body = two
_d_body->get_3D_body() ;bendlinelist[i].threedpt =
three_d_body ; // BM_3D_BODY pointerif (three_d_b
ody == NULL) continue ;entity_id = three_d_body->g
et_name() ;facelist[i].org_entity = entity_id ;top
ology_record = three_d_body->get_adj_list() ;bendl
inelist[i].topologyrecpt = topology_record ;if (to
pology_record == NULL) continue ;bendlinelist[i].n
umadjbody = (int) topology_record->get_number_of_a
djacent_bodies() ;bendlinelist[i].numadjface = (in
t) topology_record->get_number_of_adjacent_faces()
;bendlinelist[i].numadjhole
= (int) topology_record−
>get_number_of_adjacent_h
oles() ;bendlinelist[i].n
umadjbend = (int) topolog
y_record−>get_number_of_a
djacent_bendlines() ;}if
(num_error > 0) {clean_up
( part_numface, imatrix,
nbl_face, facelist, bend
linelist, bendfacelist) ;
return ( num_error ) ;}//
varify all the valid ben
dlines, the current requi
rements are://1) The tota
l number of bendlines sho
uld not be less than// th
e totalnumber of faces minus 1.// 2) A bendline w
ithout an adjacent face or bendline is not allowe
d.// 3) A bendline with more than two adjacent fac
es and bendlines is not allowed.//4)The adjacent f
ace or bendline of a bendline must bea valid face
or// bendline that is defined in the facelist o
r bendlinelist.// 5) Two adjacent faces, face1 and
face2, will be defined for each bendline// a)
If the bendline has an adjacent faces,then the fac
e’s faceid is used// as face1 or face2.//b)
If the bendline has an adjacent bendline, thena b
endline_only_face// will be created inbetwee
n these two bendlines. The faceid of the // bendl
ine_only_face will be used as face1 or face2.//c)I
f the bendline has only one adjacent face or adjac
ent bendline, then//a bendline_only_face will becr
eated for this bendline. The faceid of// th
e bendline_only_face is face2.// maxnewfaces is th
e maximum number of bendline_only_face need to be
created// without encounter error in the part.if
(part_numbend> part_numface-1) num_error++ ; // co
ndition 1if (num_error > 0) {clean_up ( part_numfa
ce, imatrix, nbl_face, facelist, bendlinelist, b
endfacelist) ;return ( num_error ) ;}int maxnewfac
es = part_numbend + 1 - part_numface ;if (maxnewfa
ces > 0) {bendfacelist = new ARTIFICIAL_FACE [maxn
ewfaces] ;bendfacelist[0].faceid = -part_numface
;}for ( i = 0 ; i < num_of_bendlines ; i++) {if
(bendlinelist[i].bendlineid) {bend_0 = bendlinelis
t[i].bendlineid ;intnumadj = bendlinelist[i].numad
jface + bendlinelist[i].numadjbend ;if (numadj < 1
|| numadj > 2) num_error++ ; // condition2 & 3els
e {if (bendlinelist[i].numadjface > 0) { // condit
ion 4 - firstfacethree_d_body = bendlinelist[i].to
pologyrecpt->get_first_face() ;face_1 = find_face_
id( three_d_body, facelist, num_of_faces ) ;if (fa
ce_1 <= 0) num_error++ ;else bendlinelist[i].face1
= face_1 ; }if (bendlinelist[i].numadjface == 2)
{ // condition 4 - second facethree_d_body = bendl
inelist[i].topologyrecpt->get_next_face() ;face_1
= find_face_id( three_d_body, facelist, num_of_fac
es ) ;if (face_1 <= 0) num_error++ ;else bendlinel
ist[i].face2 = face_1 ; }if (bendlinelist[i].numad
jbend > 0) { // condition 4 - first bendlinethre
e_d_body = bendlinelist[i].topologyrecpt->get_firs
t_bendline() ;bend_1 = find_bendline_id( three_d_b
ody, bendlinelist, num_of_bendlines ) ;if (bend_1
<= 0) num_error++ ;else {face_1= define_bendline_o
nly_face ( bend_1, bend_0,bendfacelist, maxnewface
s );if (face_1 <= 0) num_error++ ;else {if (bendli
nelist[i].numadjface > 0) bendlinelist[i].face2 =
face_1 ;else bendlinelist[i].face1 = face_1 ;}}}i
f (bendlinelist[i].numadjbend == 2) { // conditi
on 4 - second bendlinethree_d_body = bendlinelist
[i].topologyrecpt->get_next_bendline() ;bend_1 = f
ind_bendline_id( three_d_body, bendlinelist, num_o
f_bendlines );if (bend_1 <= 0) num_error++ ;else
{face_1 = define_bendline_only_face( bend_1, bend_
0, bendfacelist, maxnewfaces ) ;if (face_1 <= 0) n
um_error++ ;else bendlinelist[i].face2 = face_1
;}}if (numadj == 1) {face_1 =define_bendline_only
_face ( bend_0, 0,bendfacelist, maxnewfaces ) ;if
(face_1 <= 0) num_error++ ;else bendlinelist[i].fa
ce2 = face_1 ;}}}}if (num_error > 0) {clean_up ( p
art_numface, imatrix, nbl_face, facelist, bendli
nelist, bendfacelist) ;return ( num_error ) ;}// n
ow check whether there is any bendline only face b
een created// increase the part_numfaceif there i
s.int numregfaces = part_numface ;int numnewfaces
= 0 ;if (maxnewfaces > 0) { for ( i = 0 ; i < maxn
ewfaces ; i++ ) {if (bendfacelist[i].faceid <= 0)
{numnewfaces = i + 1 ;break ;}}part_numface += num
newfaces ;}//first create integer topological matr
ix to record all the topological relationsint j ;i
matrix = new int *[part_numface] ;for ( i = 0 ; i<
part_numface ; i++ ) {imatrix[i] = new int [part_
numface] ;for( j = 0; j < part_numface; j++ ) imat
rix[i][j] = 0;}for ( i = 0 ; i < num_of_bendlines
; i++ ) {// save the bendline entry + 1 in imatri
xif (bendlinelist[i].bendlineid) {face_1 = bendlin
elist[i].face1 ;face_2 = bendlinelist[i].face2 ;im
atrix[face_1-1][face_2-1] = i+1 ;imatrix[face_2-1]
[face_1-1] = i+1 ;}}// from imatrix to find the nu
mber of bendlines of each face,nbl_face[i],// and
to verify that each face has at least one bendline
nbl_face = new int [part_numface] ;for ( i = 0 ; i
< part_numface ; i++ ){nbl_face[i] = 0 ;for ( j =
0 ; j < part_numface ; j++ ) {if ( imatrix[i][j]
) nbl_face[i]++;}if (!nbl_face[i]) num_error++ ;}
if (num_error > 0){clean_up ( part_numface, imatri
x, nbl_face, facelist, bendlinelist,bendfacelis
t) ;return ( num_error ) ;}// create the Cbpart’s
topological matrix’s input data FENT array// and
initialize it.part->get_name( pname ) ;parrank =
part_numface ;int spsize = parrank*(parrank + 1)/2
+ 1; // +1 is for End of FENT array indicator FE
NT *sp = new FENT [ spsize] ;for(i = 0; i < spsize
-1 ; i++ )*(sp+i) = NoRelation ;*(sp+spsize-1)= Nu
llFent ;// step 1: set up the positive or negative
bend// The included FENT’s are://*PosBen
d = ’+’; // positive bend betweentwo faces/
/*NegBend = ’-’; // negative bend between t
wo faces//*P90Bend= ’A’; // 90 deg positive be
nd angle//*N90Bend = ’B’; // 90 deg negative b
end angle//MrPosBend = ’3’; // multiple posit
ive bendlines between two faces//MrNegBend = ’
4’; // multiple negative bendlines between two f
aces//* marks what is currently implemented.for (
i = 0 ; i < num_of_bendlines ; i++ ) {if (bendline
list[i].bendlineid) {face_1 = bendlinelist[i].face
1 ;face_2 = bendlinelist[i].face2 ;FENT btype = Ne
gBend ;BM_BEND_OP_REGULAR *bendopregular = (BM_BEN
D_OP_REGULAR *)bendlinelist[i].bendoppt;if (bendop
regular->get_bend_type()) btype = PosBend ;double
angle = bendopregular->get_bend_angle() ;if (angle
> PI) {// angle > PI => reverse bend direction and
reset the bend angleangle = 2*PI - angle ;if (bty
pe == PosBend)btype = NegBend ;elsebtype = PosBend
;}bendlinelist[i].bendangle = angle ;bendlinelist
[i].bendtype =btype ;// set up 90 degree bend typ
eif (angle == PI_over_2) {if (btype == PosBend)bty
pe = P90Bend ;elsebtype = N90Bend ;}//set_FENT (s
p, face_1,face_2, parrank, btype) ;}}// step 2: se
t up the corner relationships,which is the relatio
n//between two faces that are connected to a commo
nface.// The included FENT are://*TouchCnr =
’T’; // two faces same bend dir//*OpenCnr
= ’O’; // two faces same bend dir//*PrllBend
= ’P’; // two parallel bendline same bend
angle dir opposite bendline dir//*SerlBend =
’S’; // two parallel bendline same bend angle
dir same bendline dir//*cLnrBend = ’L’; /
/ colinear bendline same bend angle dir on one fac
e//*DfClnrBend = ’D’; //colinear bendline sa
me bend angle on different faces//*tHkOffBend =
’H’;// tHickness offset bendline same bend ang
le dir on two neighboring face//*touchCnr =
’t’; // two faces opposite bend dir//*openCnr
= ’o’; // two faces opposite bend dir//*prll
Bend = ’p’;//two parallel bendline opposite
bend angle dir opposite bendline dir//*serlBend
= ’s’; // two parallel bendline opposite be
nd angle dirsame bendline dir//*clnrBend = ’
l’; //colinear bendline opposite bend angle dir
on one face//thkOffBend = ’h’; // tHickness
offset bendline opposite bend angle dir on two nei
ghboring face//* marks whatis currently implemente
d.// Algorithm : for every face that has more than
one bend line then//a pair of any two bend lines
will have relationship.for ( i = 0 ; i < part_numf
ace ; i++ ) {if (nbl_face[i] > 1) {int face_c = i
+ 1 ;// create a list of faces that are connected
to this face.for ( j = 0 ; j < part_numface ; j++
) {if ( imatrix[i][j] ) {int bl_1 =imatrix[i][j]
;face_1 = j + 1 ;for ( int k = j+1 ;k < part_numf
ace ; k++) {if ( imatrix[i][k] ) {int bl_2 = imatr
ix[i][k] ;face_2 = k + 1 ;// define the relation s
hip between the two bendlinesset_bendline_rel_FENT
(sp, parrank,facelist, face_c, face_1, face_2,ben
dlinelist, bl_1, bl_2,outfile) ;}}}}}}//*tHkOffBen
d = ’H’; // tHickness offset bendlinesame be
nd angle dir on two neighboring face// from imatri
x to find the faces that may be of the thickness o
ffset bendlines//and verify these faces first base
d on touch cornerinfomation then based on// the be
ndlines’distance and parallel condition.for ( i =
0 ; i < part_numface ; i++ ){if ( nbl_face[i] < 2
) continue ;// face i should have at least 2 bend
linesfor ( j = i+1 ; j < part_numface ; j++ ) {if
( !imatrix[i][j] || nbl_face[j] < 2 ) continue ;//
faces i and j must have a common bendline//and fa
ce j should have at least 2 bendlinesfor ( int i2
= 0 ; i2 < part_numface ; i2++ ) {if ( !imatrix[i]
[i2] || i2 == j ) continue ;// faces iand i2 must
have a common bendline// and face i2 is different
from j//first requirement - bendlines imatrix[i]
[j] and// imatrix[i][i2] form atouch cornerif ( ge
t_FENT(sp, j+1, i2+1, parrank) != TouchCnr ) conti
nue;for ( int j2 = 0 ; j2 < part_numface ; j2++ )
{if ( !imatrix[j][j2] ||j2 == i ) continue ;// sec
ond requirement - bendlines imatrix[i][j] and// im
atrix[j][j2] also form a touch cornerif ( get_FENT
(sp, i+1, j2+1, parrank) != TouchCnr ) continue ;/
/ comes here, we have obtained a candidate for the
// thickness offset bendlines, the two candidate
// bendlines are imatrix[i,i2] and imatrix[j][j
2] int bl_1 = imatrix[i][i2] ;intbl_2 = imatrix
[j][j2] ;check_thkoffbend ( sp, parrank,facelist,
i+1, i2+1, j+1,j2+1,bendlinelist, bl_1, bl_2, thic
kness, outfile);}}}}//DfClnrBend = ’D’; //co
linear bendline same bend angle on different faces
// Here is to find all the colinear bends that are
colinear but not related to each other// with a c
ommon face.int num_undetermined = 0 ;UNDETERMINED
*undetermined = new UNDETERMINED [num_of_bendline
s] ;UNDETERMINED *undetpt = undetermined ;for ( i
= 0 ; i < num_of_bendlines ; i++ ) {if (bendlineli
st[i].bendlineid) {int face_i1 = bendlinelist[i].f
ace1 ;int face_i2 = bendlinelist[i].face2 ;for ( j
= i+1 ; j < num_of_bendlines ; j++ ) {if (bendlin
elist[j].bendlineid) {int face_j1 = bendlinelist
[j].face1 ;int face_j2 = bendlinelist[j].face2 ;if
( face_i1 == face_j1 || face_i1 == face_j2 ||face
_i2 == face_j1 || face_i2 == face_j2 ) continue ;i
f( bendlinelist[j].bendtype != bendlinelist[j].be
ndtype ) continue ;if( bendlinelist[j].bendangle
!= bendlinelist[j].bendangle ) continue ;//come he
re when the two bend lines have the same bend angl
e and type,// and they do not share a common face.
// now examine whether they are colinearint bl_i =
i + 1 ;int bl_j = j + 1 ;int unknown = check_DfCl
nrBend (sp, parrank, facelist,face_i1, face_i2, fa
ce_j1, face_j2,bendlinelist, bl_i, bl_j,part_numfa
ce, imatrix, outfile) ;if (unknown) {undetermined
[num_undetermined].bendline_i = bl_i ;undetermined
[num_undetermined].bendline_j = bl_j ;num_undeterm
ined++ ;}}}}}// Note: if num_undetermined is not z
ero, then there are confirmed DfClnrBend//but with
undetermined facesfor specify this FENT.//A tree
structure of all the faces that recordsthe connect
ivity between//faces need to be constructed. And
then each pair of undetermined//bendlines need to
be processed to determine which two faces of the f
our//that connected with the two bendlines should
be used torecord this FENT.// Currently, we will n
eglect these information and simply delete// undet
ermined array, which will not be used any more. de
lete [] undetermined ;// transfer all the data bac
k *inp_part_numface =part_numface ;*inp_parrank =
parrank ;*inp_part_numbend = part_numbend;*inp_par
t_maxface = part_maxface ;*inp_sp = sp ;num_error
= fclose (outfile) ;clean_up ( part_numface, imatr
ix, nbl_face, facelist, bendlinelist, bendfaceli
st) ;return ( num_error ) ; } 付録B 相似性指数特性の例。2つの部分のトポロジカルマトリ
クスを比較し、それらの最良の相似性指数を求める。相
似性指数は、2つの部分のFENTマトリクストポロジ
カルマトリクス)の不一致FENTsの全てのペナルテ
イの和として与えられる。最良の相似性指数は最小値を
持つものである。
【0293】int matrix_similarity_index ( FENT
*newmatrix,int newmatrixdim,int *newmatchlist,
FENT *oldmatrix,int oldmatrixdim,int *oldmatchli
st, int nfacefixed,int requiredvalue,int *minimum
value){ //input //newmatrix- new part topolog
ical matrix to be matched on// by the oldmatrix//
newmatrixdim- matrix dimension of newmatrix//newma
tchlist- the first nfacefixed entries should// co
ntain the entries (faces) of the new part//matrix
that has already been fixed for// matching with t
he old part matrix. //oldmatrix- old part matri
x to match with the new part // topological matr
ix//oldmatrixdim- matrix dimension of oldmatrix//o
ldmatchlist- the first nfacefixed entries should//
contain the entries (faces)of the old part// ma
trix that has already been fixed for// matching w
ith the new part matrix.//nfacefixed- the number o
f entries in matchlistthat// has already been mat
ched. Enter 0 when// there is no prematched entr
ies.//requiredvalue- the known or interested upper
bound on the//minimum similarity index. When thi
s value// is inputed as a positivevalue, then a//
branch of the search tree in finding the// mini
mum value of the similarity index may// be cut of
f when the branch’s currentvalue// becomes great
er than this minimum value.// set to 0 or a negat
ive value when there is// no restriction. In thi
s case, a minimumvalue// and its corresponding ma
cthlists will always// be found and returned.
//output//newmatchlist- the first nfacefixed ent
ries should//contain the entries (faces) of the ne
w part// matrix that has already been fixed for//
matching with the old part matrix.//oldmatchlist
- the first nfacefixed entries should// contain t
he entries (faces) of the oldpart// matrix that h
as already been fixed for// matching with the new
part matrix.//minimumvalue- the minimum similarity
index, which is the// smallest possible value of
summation of all// the penalties of the mismatch
ed FENTs of the// two part’s FENT matrix (topolo
gical matrix).// This value may not exist, if the
original// inputed value (which isthe requiremen
t) is// too small.//return- index on whether or n
ot foundthe minimum// value.//= 1, found the mini
um value and its match. //= 0, a new minium value
cannot be reached.//= -1, error in the input data
newmatchlist.//= -2, error in the input data oldma
tchlist.//= -3, error,the minimum similarity index
of// the given matrices are larger than the// i
nputed minimumvalue.// create two integer pointer
arrays to keep track the // corresponding entries
of the two matrices that matches.int matrixdim = n
ewmatrixdim ;if (matrixdim < oldmatrixdim) matrixd
im = oldmatrixdim ;int *pnewmatchlist = new int[ m
atrixdim ];int *poldmatchlist =new int[ matrixdim
];if ( poldmatchlist && pnewmatchlist ) {int *p1
= pnewmatchlist;int *p2 = poldmatchlist;for ( int
icol = 1; icol <= matrixdim; icol++,p1++,p2++)*p1
= *p2 = icol;}elsecout << "Unable to allocate memo
ry..." << endl ;// if there are already fixed entr
ies (nfacefixed > 0),then reset// the temporary wo
rking pointer arrays (newmatchlist & oldmatchlist)
// to contain those fixed face list.if (nfacefixed
> 0){for (inticol = 0; icol < nfacefixed; icol++)
{int iface = *(newmatchlist+icol);for ( int jcol
= icol; jcol < matrixdim; jcol++) {if (iface == *
(pnewmatchlist+jcol)) {if (jcol != icol) {*(pnewma
tchlist+jcol) = *(pnewmatchlist+icol) ;*(pnewmatch
list+icol) = iface ;}break ;}// comes here only if
the inputed face number "iface"// from newmatchlis
t is wrongreturn (-1); }iface = *(oldmatchlist+ico
l) ;for ( jcol = icol; jcol < matrixdim; jcol++)
{if (iface == *(poldmatchlist+jcol)) {if (jcol !=
icol) {*(poldmatchlist+jcol) = *(poldmatchlist+ico
l) ;*(poldmatchlist+icol) = iface ;}break ;}// com
es here only if the inputed face number "iface"//
from oldmatchlist is wrongreturn (-2) ; }}}// conv
ert the FENT matrix to the counter part of integer
matrix// at the same time, expand the smaller mat
rixto have the same dimension.int *pnewmatrix = ne
w int[matrixdim*matrixdim];int *poldmatrix = new i
nt[matrixdim*matrixdim];convert_fent_to_int (newma
trix, newmatrixdim, pnewmatrix, matrixdim) ;conver
t_fent_to_int (oldmatrix, oldmatrixdim, poldmatri
x, matrixdim) ;// define required valueintrequired
v = requiredvalue ;if (requiredv <= 0) requiredv =
matrixdim *400 ;// create the FENT counters and u
se calculate_partial_similarity_index// to calcula
te the initial similarity index and set the initia
l FENT// counts for each column of the fixed faces
and that of all the// unfixed faces.FENTCOUNT *pc
new = new FENTCOUNT[matrixdim+1];FENTCOUNT *pcold=
new FENTCOUNT[matrixdim+1];int currentvalue = cal
culate_partial_similarity_index ( pnewmatrix, p
newmatchlist, pcnew, poldmatrix, poldmatchlis
t, pcold, matrixdim, nfacefixed ) ;if (currentva
lue > requiredv) return (-3) ;// reset the unfixed
faces in pnewmatchlist to be in thesequence of//
its total weighting.int ncandidates = matrixdim -
nfacefixed ;int *pcandidates = new int [ncandidat
es] ;int *pweights = new int [ncandidates] ;for (
int i = 0 ; i < ncandidates ; i++ ) {int facenew =
*(pnewmatchlist+nfacefixed+i) ;*(pcandidates+i) =
facenew ;int weight = 0;int *pnewi = pnewmatrix +
(facenew-1)*matrixdim ;for ( int j = 0 ; j <matri
xdim ; j++, pnewi++ )weight += fent_weight(*pnewi)
;*(pweights+i)= weight ;}sort_the_candidates (pca
ndidates, pweights, ncandidates) ;for( i = 0 ; i <
ncandidates ; i++ ) *(pnewmatchlist+nfacefixed+i)
= *(pcandidates+ncandidates-1-i) ;delete [] pcand
idates ;delete [] pweights ;//call the internal ro
utine recursively to perform similarity index// se
arch.*minimumvalue = requiredv ;int recursive_leve
l = 0;int *newminmatchlist = new int[matrixdim];in
t *oldminmatchlist = new int[matrixdim];int *retur
nlevelcounts = new int[matrixdim];int errorcode =
matrix_similarity_index_loop ( pnewmatrix, pnew
matchlist, newminmatchlist, poldmatrix, poldm
atchlist, oldminmatchlist, pcnew, pcold, &current
value, matrixdim, nfacefixed, &recursive_level, m
inimumvalue, returnlevelcounts);// clean updelete
[] pnewmatchlist ;delete [] poldmatchlist ;delete
[]pnewmatrix ;delete [] poldmatrix ;delete [] pcn
ew ;delete [] pcold ;delete [] returnlevelcounts ;
delete [] newminmatchlist ;delete [] oldminmatchli
st ;return (errorcode);}// 新しい部分マトリクスと
一致する既存の部分マトリクスからエントリのリストを
抽出する。部分マトリクスのデイメンシヨンはトポロジ
カルマトリクスのデイメンシヨンより大きいか等しくな
ければならない。注意:一致リストの第一要素は初期化
されてトポロジカルマトリクスの第一面との一致のため
部分マトリクスの面番号を含まなければならない。 n
matchedが0より大きいときは、マッチリストの
第一のnmatchedエントリは正の番号を含んで部
分マトリクスの既に一致されたエントリを示さなければ
ならない。//int matrix_similarity_index_loop (
int *pnewmatrix, int *pnewmatchlist, int *newmi
nmatchlist, int *poldmatrix, int *poldmatc
hlist, int *oldminmatchlist, FENTCOUNT *pcnew,
FENTCOUNT *pcold, int *currentvalue, int matrix
dim, int nfacefixed, int *recursive_leve
l, int *minimumvalue, int *returnlevelcounts){//
input//pnewmatrix- the new part’s topological ma
trix, where//the FENT contents have been changed t
o// their representing inte
gers.// (integer array of m
atrixdim * matrixdim)//pnewmatchlist- the list of
entries of the newmatrixthat // has been matched
by the oldmatrix.// (intege
r array of matrixdim)//newminmatchlist- the list o
f entries of the newmatrix that // has been match
ed by the oldmatrix that// provides theminimum va
lue.// (integer array of ma
trixdim)//poldmatrix- the old parts’s topological
matrix, where//the FENT contents have been change
d to//their representing integers.//
(int array ofmatrixdim * matrixdim)//pol
dmatchlist- the list of entries of the oldmatrix t
hat // has matched with the newmatrix.//
(integer array of matrixdim)//oldm
inmatchlist- the list of entries of theoldmatrix t
hat // has matched with the oldmatrix that// pro
vides the minimum value.//
(integer array of matrixdim)//matrixdim- the matri
x dimension of both matrices//nfacematched- the nu
mberof entries (faces) that has// been fixed in m
atching the two matrices.// recursive_level- this
keep the number of times this procedure// has bee
n called recursivly. This provides a// way to de
tect the error before going into a// infinite loo
p. (integer pointer)// output//return- error inde
x,//= 0 means there is no error,//> 0 error code./
/// verify therecursive levelif ( *recursive_level
> matrixdim ) {cout << "??? Error -the recursive
level is too high. ???\n";cout << " The matrix
dimension is " << matrixdim << ".\n";cout << "
The recursive level is " <<*recursive_level << ".
\n";return (9) ;}// Step 1) Choose a row to be mat
ched with in the new matrix.// ( Currently, it use
s whatever the next row in line. Therefore,// n
othing to do at this moment.// This may need to
be changed to be properly matching up with// the
algorithm thatmay be used in defining the sequenc
e of the// candidate list.// Note: If facenew
is not next to the nfacefixed position, then//
it should be changed to that position. )int
facenew = *(pnewmatchlist+nfacefixed) ;// Step 2)
Create a list of candidate face list in the old ma
trix.// and calculate the increases in the
similarity index for//each of the candidates.//
( Currently we are using what ever thesequence tha
t is inside// the poldmatchlist.// One may cho
ose to usethe faces that at least matches up with/
/ the face connectivity of the chosen face in th
e new matrix.// Note: The sequence of faces in p
candidates does not need to// be correspon
ding to that in poldmatchlist. )int ncandidates =
matrixdim - nfacefixed ;int *pcandidates = newint
[ncandidates] ;int *pincreases = new int [ncandid
ates] ;for ( int i= 0 ; i < ncandidates ; i++ ) {i
nt faceold = *(poldmatchlist+nfacefixed+i) ;*(pcan
didates+i) = faceold ;int increase = increase_on_s
imilarity_index ( pnewmatrix,pnewmatchlist,face
new, poldmatrix,poldmatchlist,faceold, p
cnew,pcold,currentvalue, matrixdim,nfacefixed,m
inimumvalue) ;*(pincreases+i) = increase ;}// Step
3) Sort the candidate facebased on the increased
values// the candidates with the lower inc
rease will be tried first.sort_the_candidates (pca
ndidates, pincreases, ncandidates) ;// Step 4) cha
nge the FENT counters of the newmatrix forfixing f
acenewint errorcode = change_counts_for_fix_one_fa
ce ( pnewmatrix, pnewmatchlist, facenew, pcnew,
matrixdim, nfacefixed) ;if (errorcode != 0) retur
n (errorcode) ;// Step 5) Loop thru the candidate
face and based on the increased value// de
termines whether or not to continue to the lower l
evel match.for ( int icandi = 0 ; icandi < ncandid
ates ; icandi++ ) {// get the candidate face numbe
r of the old matrix and// its corresponding amount
of increase on similarity index.int faceold= *(pc
andidates+icandi) ;int increase = *(pincreases+ica
ndi) ; // Now check whether it is any need to cont
inue the matching// If the current value plus the
increase has already exceed the // minimum value,
then thereis no need to continue the matching.// a
dd the returnlevelcount and goto the next candidat
es.if (*currentvalue + increase >= *minimumvalue)
{returnlevelcounts[nfacefixed] += 1 ;}else if (nfa
cefixed+1 == matrixdim){// A new minimum similarit
y index has been found, update// the minimumvalue*
minimumvalue = *currentvalue + increase ;for ( i =
0 ; i < matrixdim ; i++ ) {newminmatchlist[i] = p
newmatchlist[i] ;oldminmatchlist[i] =poldmatchlist
[i] ;}}else {// It is necessary to go down another
level inthis recursive// call to define the simil
arity index.// change the FENTcounters of the oldm
atrix for fixing faceolderrorcode = change_counts_
for_fix_one_face ( poldmatrix, poldmatchlist, f
aceold, pcold, matrixdim, nfacefixed) ;if (errorco
de != 0) return (errorcode) ;// call recursively*c
urrentvalue += increase ;*recursive_level += 1 ;er
rorcode = matrix_similarity_index_loop ( pnew
matrix,pnewmatchlist,newminmatchlist,poldmatrix,po
ldmatchlist,oldminmatchlist, pcnew, pcold,curre
ntvalue, matrixdim,nfacefixed+1,recursive_leve
l, minimumvalue,returnlevelcounts) ;if (errorcode
!= 0) return (errorcode) ;*recursive_level -= 1 ;
*currentvalue -= increase ;// change the FENT coun
ters of the oldmatrix for unfixing faceoldchange_c
ounts_for_unfix_one_face ( poldmatrix, poldmatc
hlist, pcold, matrixdim, nfacefixed+1) ;}}// chang
e the FENT counters of the newmatrix for unfixing
facenewchange_counts_for_unfix_one_face( pnewmatri
x, pnewmatchlist, pcnew, matrixdim, nfacefixed+
1) ;//cleanupdelete [] pcandidates ;delete [] pinc
reases ;return (0);}//////////////////////////////
//////////////////////////////////// 1以上の面を
固定するためのカウンターを更新する。//////////////
//////////////////////////////////////////////////
////int change_counts_for_fix_one_face ( int*pn
ewmatrix, int *pnewmatchlist, int facenew, FEN
TCOUNT *pcnew, int matrixdim, int nfacefixe
d){// input//pnewmatrix- the new part’stopologica
l matrix, where// the FENT
contents have been changed to//
their representing integers.//
(integer array of matrixdim * matrixdim)
//pnewmatchlist- the list of entries of the newmat
rix that // has been matchedby the oldmatrix.//
(integer array of matrixdim)
//facenew- the face that is to be fixed.//pcnew- t
he FENTCOUNT of all the faces.//matrixdim- the mat
rix dimension of both matrices//nfacematched- the
number of entries (faces) that has// been fixed i
n matching the two matrices.// output//pnewmatchli
st- the updated list of entries of the// newmatri
x matched by the oldmatrix,// with the facenew en
try is moved to the // nfacefixed+1 location. //p
cnew- the updated FENTCOUNT of all the faces// swi
tch the to be fixed face to the location of nfacef
ixed+1// in the pnewmatchlistint ifound = 0 ;for
( int i = nfacefixed ; i <matrixdim ; i++ ) {if (*
(pnewmatchlist+i) == facenew) {*(pnewmatchlist+i)
= *(pnewmatchlist+nfacefixed) ;*(pnewmatchlist+nfa
cefixed) = facenew ;ifound++ ;}}if ( ifound != 1 )
{cout << "Fatal error from change_counts_for_fix_
one_face /n" ;return ( 91 ) ;}// define the pointe
r to the FENTon the to be fixed faceint *pnewrow =
pnewmatrix + (facenew-1)*matrixdim;// first chang
e the counters for the previously fixed facesfor
( i = 0; i < nfacefixed ; i++ ) {int newcol = *(pn
ewmatchlist+i) ;int pnewv =*(pnewrow + newcol -
1) ;pcnew[newcol].count[pnewv]-- ;int igroup = fen
t_group (pnewv) ;pcnew[newcol].gcount[igroup]-- ;i
f ( pcnew[newcol].count[pnewv] < 0 || pcnew[ne
wcol].gcount[igroup] < 0 ) {cout << "Fatal error f
rom change_counts_for_fix_one_face /n" ;return ( 9
2 ) ;}}// secondchange the counters for the unfixe
d faces// use count_specified_fents to initialize
the FENTCOUNT of// the newly seleted face and coun
t the numbers of fents of // the undetermined colu
mns on the to be fixed rowsintlistdim = matrixdim
- nfacefixed ;pcnew[facenew] = count_specified_fen
ts( pnewrow, pnewmatchlist+nfacefixed, matrixdim,
listdim ) ; // decreasethe FENTCOUNT of the newly
seleted face from that// in remaining unfixed face
sfor ( i = 0; i < NumIntFent; i++ ) pcnew[0].count
[i] -= pcnew[facenew].count[i] ;for ( i = 0; i < N
umIntFentGroup; i++ ) pcnew[0].gcount[i] -= pcnew
[facenew].gcount[i] ;return (0) ;}////////////////
//////////////////////////////////////////////////
//// この関数はカウンタを更新して固定面を開放す
る。解放された面は現在nface////fixed位置
にある面である。//////////////////////////////////
////////////////////////////////////void change_co
unts_for_unfix_one_face ( int *pnewmatrix, i
nt *pnewmatchlist, FENTCOUNT *pcnew, int matrix
dim, int nfacefixed){// input//pnewmatrix- th
e new part’s topological matrix, where//the FENT
contents have been changed to//their representing
integers.// (integer array
of matrixdim * matrixdim)//pnewmatchlist- the list
of entriesof the newmatrix that // has been matc
hed by the oldmatrix.//(integer array of matrixdi
m)//pcnew- the FENTCOUNT of all the faces.//matrix
dim- the matrix dimension of both matrices//nfacem
atched- the number of entries (faces) that has//
been fixed in matching the two matrices.// output/
/pcnew- the updated FENTCOUNT of all the faces// g
et the to be unfixed face number and// define the
pointer to the FENT on the to be fixed faceint fac
enew = *(pnewmatchlist+nfacefixed-1) ;int *pnewrow
= pnewmatrix + (facenew-1)*matrixdim ;// first ch
ange the counters for the previously fixed facesfo
r ( int i = 0 ; i < nfacefixed-1 ;i++ ) {int newco
l = *(pnewmatchlist+i) ;int pnewv = *(pnewrow + n
ewcol- 1) ;pcnew[newcol].count[pnewv]++ ;int igrou
p = fent_group (pnewv) ;pcnew[newcol].gcount[igrou
p]++ ;}// second change the counters for the unfix
ed faces by// adding the FENTCOUNT of the to be re
leased face to that// of the remaining unfixed fac
esfor ( i = 0; i < NumIntFent; i++ ) pcnew[0].coun
t[i] += pcnew[facenew].count[i] ;for ( i = 0; i <
NumIntFentGroup; i++ ) pcnew[0].gcount[i] += pcnew
[facenew].gcount[i] ;}////////////////////////////
///////////////////////////////////////////// こ
の関数は所与のintfentの配列におけるFENT
sの個数をカウントす//// る。////////////////////
//////////////////////////////////////////////////
///FENTCOUNT count_fents ( int *pintfentarray, int
arraydim){// input//pintfentarray- the pointer to
the intfent array//arraydim- the dimension ofthe
intfent array// output//return- FENTCOUNT, the FEN
T count of the//input array// define an FENT count
and initialize itstatic FENTCOUNT fentc ;for ( in
t j = 0; j < NumIntFent; j++ ) fentc.count[j] = 0
;for ( j= 0; j < NumIntFentGroup; j++ ) fentc.gco
unt[j] = 0 ;// Count the numbers of fents in an ar
ray of intfentfor ( int *i = pintfentarray ; i < p
intfentarray+arraydim ; i++ ) {fentc.count[*i]++ ;
fentc.gcount[fent_group(*i)]++ ;}return (fentc) ;}
//////////////////////////////////////////////////
//////////////////// この関数は特定の組のintf
ent配列におけるFENTsの個数をカウント////
する。////////////////////////////////////////////
//////////////////////////FENTCOUNT count_specifie
d_fents ( int *pintfentarray,int *locationlist, in
t arraydim, int listdim){// input//pintfentarray-
the pointer to the intfent array//locationlist- th
e locations in the intfent array// that are to be
included in counting//arraydim- the dimension of
the intfent array//listdim- the dimension of the l
ocation list// output//return- FENTCOUNT, the FENT
count of the// selected elements in the input ar
ray// define an FENT count and initialize itstatic
FENTCOUNT fentc ;for ( int j = 0; j < NumIntFent;
j++ ) fentc.count[j] = 0 ;for ( j = 0; j < NumInt
FentGroup; j++ ) fentc.gcount[j] = 0 ;// Count the
numbers of fents in an array of intfentfor ( int
*i = locationlist ; i < locationlist+listdim ; i++
) {int intfent = *(pintfentarray+(*i)-1) ;fentc.c
ount[intfent]++ ;fentc.gcount[fent_group(intfent)]
++ ;}return (fentc) ;}////////////////////////////
/////////////////////////////////////////////////
この関数は特定の組のintfentマトリクスにおけるF
ENTsの個数をカウントする。////注意:intfe
ntマトリクスは対称である。マトリクスの半分だけが
カウントに含ま//// れる。////////////////////
//////////////////////////////////////////////////
///////FENTCOUNTcount_specified_fents_matrix ( int
*pintfentmatrix,int *locationlist, int matrixdim,
int listdim){// input//pintfentmatrix- the pointe
r to theintfent matrix//locationlist- the location
s in the intfent matrix// that are to be included
in counting//matrixdim- the dimension of the intf
ent matrix//listdim- the dimension of the location
list// output//return-FENTCOUNT, the FENT count o
f the// selected elements in the input matrix// d
efine an FENT count and initialize itstatic FENTCO
UNT fentc ;for (int j = 0; j < NumIntFent; j++ ) f
entc.count[j] = 0 ;for ( j = 0; j < NumIntFentGrou
p; j++ ) fentc.gcount[j] = 0 ;// Count the numbers
of fentsin an matrix of intfentfor ( int i = 0 ;
i < listdim ; i++ ) {int facenum = *(locationlist+
i) ;int *pintfentrow = pintfentmatrix + (facenum -
1)*matrixdim ;// Note: only half of the symmetric
matrix is counted =>//the k is atarted from i (di
agonal included).for ( int k = i ; k < listdim ; k
++ ) { int intfent = *(pintfentrow+(*(locationlist
+k))-1) ;fentc.count[intfent]++ ;fentc.gcount[fent
_group(intfent)]++ ;}}return (fentc) ;}///////////
//////////////////////////////////////////////////
//////// この関数は不一致な対のFENTに対してペナル
テイを戻す。//////////////////////////////////////
///////////////////////////////int penalty_of_fent
_pair ( int intfent1, int intfent2){// input//intf
ent1- the intfent of part 1//intfent2- the intfent
of part 2// output//return- the penalty forthe mi
smatched intfents.// No penalty, if they are the s
ameif (intfent1== intfent2) return (0) ;// add the
penalty for mismatching the individual intfentint
indexvalue = 0;indexvalue += fent_weight(intfent
1) ;indexvalue += fent_weight(intfent2) ;// add th
e penalty for mismatching theirfent groupint fentg
roup1 = fent_group(intfent1) ;int fentgroup2 = fen
t_group(intfent2) ;if (fentgroup1 != fentgroup2)
{indexvalue += fent_group_weight(fentgroup1) ;inde
xvalue += fent_group_weight(fentgroup2) ;}return
(indexvalue) ;}///////////////////////////////////
///////////////////////////////// この関数は2つ
の最小可能不一致に対して最小ペナルテイを戻す。////
//////////////////////////////////////////////////
//////////////int penalty_of_FENTCOUNT_pair ( FENT
COUNT const &fentcount1,FENTCOUNT const &fentcount
2){// input//fentcount1- the FENTCOUNT of part 1//
fentcount2- the FENTCOUNT of part 2// output//retu
rn- the minimum penalty on themismatches//
of two FENTCOUNTs.// Now loop thru the
FENTCOUNT, // currently method uses the penalty of
the minimum possible// individual mismatches as t
he penalty plus the penalty of// the minimum possi
ble mismatched groupsint indexvalue = 0;for ( int
i = 1; i < NumIntFent; i++ )if ( fentcount1.count
[i] != fentcount2.count[i] )indexvalue += fent_wei
ght(i) * abs ( fentcount1.count[i] - fentcount2.co
unt[i] );for ( i = 1; i < NumIntFentGroup; i++ )if
( fentcount1.gcount[i] != fentcount2.gcount[i] )i
ndexvalue += fent_group_weight(i) * abs ( fentcoun
t1.gcount[i] - fentcount2.gcount[i] ) ;return (ind
exvalue) ;}///////////////////////////////////////
///////////////////////////// この関数は不一致対
のFENTのペナルテイを戻す。////////////////////
//////////////////////////////////////////////int
change_from_seperate_fent_sets ( int ntnew, int nt
old, int nsnew, int nsold ){// input//ntnew- numbe
r of FENT inthe whole set of the new part.//ntold-
number of FENT in the whole setof the old part.//
nsnew- number of FENT in the sub-set of the new pa
rt.//nsold- number of FENT in the sub-set of the o
ld part.// output//return-the change in the number
of counts of the mismatch// due to the separatio
n of the sub-set from the // whole set.int diffor
g = abs( ntnew-ntold ) ;int diffsub = abs( nsnew-n
sold ) ;int diffnew = abs( ntnew-nsnew-ntold+nsold
) ;int change = diffsub + diffnew - difforg ;retu
rn ( change );}///////////////////////////////////
//////////////////////////////////////////// この
関数は2つのFENTCOUNTの最小可能不一致に対
する最小ペナルテイを戻す。////////////////////////
//////////////////////////////////////////////////
/////int increase_from_separate_a_pair_of_fent (FE
NTCOUNT const &pcnew_total,FENTCOUNT const &pcold_
total,int intfentnew_separ,int intfentold_separ )
{// input//pcnew_total- the total FENTCOUNT of the
new part//pcold_total- the total FENTCOUNT of the
old part//intfentnew_separ - to be seperated FENT
of the new part//intfentold_separ - tobe seperate
d FENT of the old part// output//return- the incre
ase in thepenalty due to the//
seperation of the FENTs.staticint ntnew, ntold, ig
roup ;static int increase ;if (intfentnew_separ ==
intfentold_separ) {ntnew = pcnew_total.count[intf
entnew_separ] ;ntold = pcold_total.count[intfentne
w_separ] ;increase = fent_weight(intfentnew_separ)
*change_from_seperate_fent_sets(ntnew, ntold, 1,
1 ) ;igroup = fent_group(intfentnew_separ) ;ntnew
= pcnew_total.gcount[igroup] ;ntold = pcold_total.
gcount[igroup] ;increase += fent_group_weight(igro
up) *change_from_seperate_fent_sets(ntnew, ntold,
1, 1 ) ;}else {ntnew = pcnew_total.count[intfentne
w_separ] ;ntold = pcold_total.count[intfentnew_sep
ar] ;increase = fent_weight(intfentnew_separ) *cha
nge_from_seperate_fent_sets(ntnew, ntold, 1, 0 ) ;
ntnew = pcnew_total.count[intfentold_separ] ;ntold
= pcold_total.count[intfentold_separ] ;increase +=
fent_weight(intfentold_separ) *change_from_sepera
te_fent_sets(ntnew, ntold, 0, 1 ) ;if (fent_group
(intfentnew_separ) == fent_group(intfentold_sepa
r)) {igroup = fent_group(intfentnew_separ) ;ntnew
= pcnew_total.gcount[igroup] ;ntold = pcold_total.
gcount[igroup] ;increase += fent_group_weight(igro
up) *change_from_seperate_fent_sets(ntnew, ntold,
1, 1 ) ;}else {igroup = fent_group(intfentnew_sepa
r) ;ntnew = pcnew_total.gcount[igroup] ;ntold = pc
old_total.gcount[igroup] ;increase += fent_group_w
eight(igroup) *change_from_seperate_fent_sets(ntne
w, ntold, 1, 0 ) ;igroup = fent_group(intfentold_s
epar) ;ntnew = pcnew_total.gcount[igroup] ;ntold =
pcold_total.gcount[igroup] ;increase += fent_grou
p_weight(igroup) *change_from_seperate_fent_sets(n
tnew, ntold, 0, 1 ) ;}}return (increase) ;}///////
//////////////////////////////////////////////////
//////////////////// この関数は2つのFENTCO
UNTの最小可能不一致に対する最小ペネルテイを戻
す。//////////////////////////////////////////////
///////////////////////////////intincrease_from_se
parate_a_pair_of_fentcount (FENTCOUNT const &pcnew
_total,FENTCOUNT const &pcold_total,FENTCOUNT cons
t &pcnew_separ,FENTCOUNT const &pcold_separ ){// i
nput//pcnew_total- the total FENTCOUNT of the newp
art//pcold_total- the total FENTCOUNT of the old p
art//pcnew_separ- tobe seperated FENTCOUNT of the
new part//pcold_separ- to be seperated FENTCOUNT o
f the old part// output//return- the increase in t
he penalty due to the// seperat
ion of the FENTCOUNTs.// Now loop thru the FENTCOU
NT, // currently method uses the penalty of the mi
nimum possible // individual mismatches as the pe
nalty plus the penalty of// the minimum possible m
ismatched groupsint change, increase ;increase =
0;for ( int i = 1; i < NumIntFent; i++ ) {change =
change_from_seperate_fent_sets (pcnew_total.count
[i], pcold_total.count[i],pcnew_separ.count[i], pc
old_separ.count[i] ) ;if ( change != 0 ) increase
+= fent_weight(i)* change ;}for ( i = 1; i < NumIn
tFentGroup; i++ ) {change = change_from_seperate_f
ent_sets (pcnew_total.gcount[i], pcold_total.gcoun
t[i],pcnew_separ.gcount[i], pcold_separ.gcount[i]
) ;if ( change != 0 ) increase += fent_group_weig
ht(i) * change ;}return (increase) ;}/////////////
//////////////////////////////////////////////////
/////////// この関数は特定の固定した面までの所与
の組の面に対して相似の指数を計算する。//// 注意:
マトリクスの半分だけが計算に含まれる。////////////
//////////////////////////////////////////////////
////////////int direct_calculate_similarity_index
( int *pnewmatrix, int *pnewmatchlist,
int *poldmatrix,int *poldmatchlist,int matrixdi
m){// loop thru the faces and calculate the simila
rity indexint indexvalue = 0 ;for (int iface = 0;
iface < matrixdim; iface++) {int facenew = *(pnewm
atchlist+iface) ;int faceold =*(poldmatchlist+ifac
e) ;int *pnewrow = pnewmatrix + (facenew - 1)*matr
ixdim ;int *poldrow = poldmatrix + (faceold - 1)*m
atrixdim ;// first fromthe mismatches of the fixed
faces.// Note: the diagonal terms of the matrix a
re always iNoRelation.// therefore, they are
skip in the loop.// also due to the symmetr
y, only half of the matrix are//included in the ca
lculation of the similarity indexfor (int icol = i
face; icol < matrixdim; icol++) {int newcol = *(pn
ewmatchlist+icol) ;int oldcol = *(poldmatchlist+ic
ol) ;int pnewv = *(pnewrow + newcol - 1) ;int pold
v = *(poldrow + oldcol - 1) ;if ( pnewv != poldv )
indexvalue += penalty_of_fent_pair(pnewv,poldv)
;}}return (indexvalue) ;}////////////////////////
////////////////////////////////////////////////
この関数は特定の固定した面までの所与の組の面に対す
る相似の指数を計算する。//////////////////////////
//////////////////////////////////////////////int
calculate_partial_similarity_index ( int *pnewm
atrix, int *pnewmatchlist,FENTCOUNT *pcnew,
int *poldmatrix, int *poldmatchlist, FENTCO
UNT*pcold, int matrixdim, int nfacefixed){//
loop thru the faces andcalculate the similarity i
ndexint indexvalue = 0 ;for (int iface = 0 ; iface
< nfacefixed; iface++) {int facenew = *(pnewmatch
list+iface) ;int faceold = *(poldmatchlist+iface)
;int *pnewrow = pnewmatrix + (facenew -1)*matrixd
im ;int *poldrow = poldmatrix + (faceold - 1)*matr
ixdim ;// first from the mismatches of the fixed f
aces.// Note: the diagonal terms of the matrix are
always iNoRelation.// therefore, they are s
kip inthe loop.// also due to the symmetry,
only half of the matrix are// included in th
e calculation of the similarity indexfor (int icol
= iface ; icol < nfacefixed; icol++) {int newcol
= *(pnewmatchlist+icol) ;int oldcol = *(poldmatchl
ist+icol) ;int pnewv = *(pnewrow + newcol -1) ;int
poldv = *(poldrow + oldcol - 1) ;if ( pnewv != po
ldv ) indexvalue += penalty_of_fent_pair(pnewv,pol
dv) ;}// use count_specified_fents to initialize t
he FENTCOUNT of// the facenew and faceold and to c
ount thenumbers of fents of // the columns of the
unfixed facesint listdim = matrixdim - nfacefixed
;pcnew[facenew] = count_specified_fents ( pnewro
w,pnewmatchlist+nfacefixed, matrixdim, listdim ) ;
pcold[faceold] = count_specified_fents ( poldrow,
poldmatchlist+nfacefixed, matrixdim, listdim );//
Now loop thru the FENTCOUNT of the facenew and fac
eold// and calculate the penalty of their mismatch
es.indexvalue += penalty_of_FENTCOUNT_pair ( pcnew
[facenew], pcold[faceold] ) ;}// use count_specif
ied_fents_matrix to get the FENTCOUNT// of the unf
ixed faces of both matrices int listdim = matrixdi
m - nfacefixed ;pcnew[0] = count_specified_fents_m
atrix( pnewmatrix, pnewmatchlist+nfacefixed, matri
xdim, listdim ) ;pcold[0]= count_specified_fents_m
atrix ( poldmatrix, poldmatchlist+nfacefixed, matr
ixdim, listdim ) ;// Finally calculate the penalty
of the FENTCOUNT//of the unfixed faces of the two
matrices.indexvalue += penalty_of_FENTCOUNT_pair
( pcnew[0], pcold[0] ) ;// Return the amount of p
enalty on the two partially fixed// part matrices
as its minimum possible similarityindex.return (in
dexvalue);}///////////////////////////////////////
////////////////////////////////// この関数は所与
のfacenewとfaceoldのミスマッチに対す
る相似の指//// 数の増加を計算する。/////////////
//////////////////////////////////////////////////
//////////int increase_on_similarity_index ( in
t *pnewmatrix, int *pnewmatchlist, intfacenew,
int *poldmatrix, int *poldmatchlist, int
faceold, FENTCOUNT *pcnew, FENTCOUNT *pcold,
int *currentvalue, int matrixdim,int nfacefixed,
int *minimumvalue){// loop thru the faces to
seehow much increase is in the// current value.int
increase = 0 ;int *pnewrow = pnewmatrix + (facene
w-1)*matrixdim ;int *poldrow = poldmatrix + (faceo
ld-1)*matrixdim ;// first loop thru the previously
fixed faces and calculate// the increase for the
mismatches between the chosen columnsfor( int i =
0; i < nfacefixed; i++ ) {int newcol = *(pnewmatch
list+i) ;int oldcol = *(poldmatchlist+i) ;int pnew
v = *(pnewrow + newcol - 1) ;intpoldv = *(poldrow
+ oldcol - 1) ;if ( pnewv != poldv ) {FENTCOUNT pc
newcol = pcnew[newcol] ;FENTCOUNT pcoldcol = pcold
[oldcol] ;increase += increase_from_separate_a_pai
r_of_fent (pcnewcol, pcoldcol, pnewv, poldv ) ;}}/
/ use count_specified_fents to initialize the FENT
COUNT of// the newlyseleted face and count the num
bers of fents of // the undetermined columns on th
e to be fixed rowsint listdim = matrixdim - nfacef
ixed ;pcnew[facenew] = count_specified_fents ( pne
wrow, pnewmatchlist+nfacefixed, matrixdim, listdim
) ;pcold[faceold] = count_specified_fents ( poldr
ow, poldmatchlist+nfacefixed, matrixdim, listdim )
;increase += increase_from_separate_a_pair_of_fen
tcount (pcnew[0], pcold[0], pcnew[facenew], pcold
[faceold] ) ;// Return the amount of increase in t
he similarity index for// the matching of the chos
en two faces, facenew in new part// and the faceol
d in the old part.return (increase);} 付録C // コメントを含むベンドライン検出の例。このモジュ
ールはBM PART:: 自動ベンド( )の実施を含む。
【0294】//* ********** ********** ********** *
********** ********* これは、部分の設計と構成に供
する主要な高レベルベンドモデル関数である。その目的
は、(もし可能なら)部分が接続されるようになるよう
に面間にベンドラインを形成することにある。 この関
数は部分の形成を容易にすることにある。通常は、第三
パーテイのCADプログラムの部分を描画する。ベンド
モデルはCADシステムにわたる制御をもたず、我々の
目的に対してこの描画は丁度一組のエッジである。従っ
て、この図は部分の構造を検出するために解析されなけ
ればならない。その後、我々は部分の面とベンドライン
を形成することが出来る。しかし、入力された図はしば
しば曖昧であり、ベンドラインは一意には定義されな
い。その場合、我々は一連の発見的手法を用いてベンド
ラインを形成する。この発見的手法は、多くのものが可
能のとき一つの出力を取り出すための優先基準を規定す
る。この問題は多くの応用に対して共通なので、この関
数はベンドモデルの一部である。更に、ベンドモデルに
おいてこの関数を実施すると、CADシステムの一部で
なければならない面検出ソフトウエアを簡単にする。こ
の関数において、我々は、垂直な平面に一致するように
左手側の規則に従って(これは平面の向きを規定す
る。)面のエッジが分類されると仮定する。基本的に
は、この関数は、全ての平面が、分離して見たとき、そ
れ自身正しいと仮定する。しかし、この関数は、隣接す
る平面の向きがそれらの平面の間のベンドラインに関し
て正しいことを要求しない(後にそれを固定するベンド
モデル関数が存在する。)。 この関数を用いて部分の
3Dバージヨンおよび部分のフラットバージヨンの両者
に対してベンドラインを生成することが出来る。しか
し、部分はフラットまたは3Dバージヨンのいずれかを
持つことが出来るが、両者を持つことは出来ない。換言
すれば、3D体の全ての3Dバージヨンはゼロでなけれ
ばならないか(その場合、我々はフラットバージヨンを
持つ。)全てのフラットバージヨンがゼロでなければな
らないかのいずれかである。*//************ ********
** ********** ********** ********** **********アル
ゴリズム/プロセス: アルゴリズムの目的は、部分の
トポロジーグラフにおいてループを形成しないという拘
束が与えられたとき、全体の部分が接続されるようにな
るように(すなわち、全ての面が全てベンドラインを介
して接続され、周囲にスタンドアロン面が垂れ下がるこ
とを望まない)最小数のベンドラインを形成することに
ある(何故なら、我々は部分を出来るだけ変化させたく
ない)。 入力部分がいかなるベンドラインも含まない
ということは要求されない。AutoBendは既存の
ベンドラインを考慮し、部分に新しいベンドラインを付
加したものである。トップレベルでは、このアルゴリズ
ムは最大スパンツリーアルゴリズムの一バージヨンを行
う。任意の時間点で、アルゴリズムは現在接続された要
素と一組のフリンジ面(これらは接続された要素の部分
である。)を有している。これらのフリンジ面は接続要
素の外側の面との接点を有する。一回の過程の間に、接
続要素の外側にある一つの新しい面が接続要素に付加さ
れる。フリンジ面に当接する接続要素の外側の面の間
で、Autobendは最大のコンタクトを持つものを
取り出す。 この最大のコンタクトを用いる発見的手法
は、薄板製造において、通常、接触が大きければ大きい
程より良好な結果が得られるという事実に基づいてい
る。しかし、タイが存在するとき、すなわち、接続要素
におけるフリンジ面と同じ最大コンタクトを持つ接続要
素の外側に幾つかの面があるときは、我々は他の発見的
手法を用いる。この発見的手法は部分の直径を最小にす
る面を取り出す。部分の直径は、部分のトポロジーグラ
フにおける任意の2つの面間の最大距離である。******
***** ********** ********** ********** **********
*技術的注意:-この関数は、部分の厚みがゼロでないと
きは恐らく十分には作用しない。-この関数は、アルゴ
リズムにおける面l(主として、垂直な面l)に一致す
るベンドライン情報を生成する点に注目されたい。しか
し、垂直な面2はこの情報と一致することは出来ない
が、それは後に固定されなければならない。PART.
HXX.のコメントを参照されたい。#include <stdio.
h>#include <stdlib.h>#include "GLOBAL.HXX"#include
"ENTITY.HXX"#include "PLANE.HXX"#include "CYLINDE
R.HXX"#include "LINE.HXX"#include "LOOP.HXX"#inclu
de "2D_BODY.HXX"#include "FORMING.HXX"#include "FA
CE.HXX"#include "BEND_OP_R.HXX"#include "BEND_PRP.
HXX"#include "BENDLINE.HXX"#include "PART.HXX"#inc
lude "DBM.HXX"/*この関数は、所定の2つの面の間の全
てのコンタクトを計算する。コンタクト接触は、2つの
面が互いに接触しているときに得られ(すなわち、ある
非常に小さな距離公差内で)、それらを分離する線分は
0より大きな長さを有する(すなわち、共通の線分は点
ではなく、実際の線分である)。目的:与えられた2つ
の面の間の潜在的なベンドラインのを計算すること。仮
定:-両面は、計算のために用いられる最新の非空3D
バージヨンを有する。-いずれかの面における全てのル
ープは閉じられる。 要件:-両面は同じ面内になければならない。リター
ン:-コンタクトのリストこのリターンされたリストは
構造を有する:ノード0:objは”コンタクトの個
数”である。ノード2i-1:objは”コンタクトi
の面l側のリストのヘッド”である。ノード2i:ob
jはコンタクトiの面2側のリストのヘッド”であり、
ただし、iは、〔1、”コンタクトの個数”〕内にあ
る。各々のコンタクトは”閉じた”コンタクトであり、
すなわちコンタクトにはギャップは存在しない点に注目
されたい。コンタクトのいずれかの側の各々のリスト
は、リスト中のラインの順序がスイープ方向とは逆の
(現在はXZYスイープ)ラインのリストである(実際
にはラインに対するポインタ)。これはコンタクトのリ
ストがどの様に見えるかを示すものである:コンタクト
の#->リスト1.面1.ヘッド->リスト1.面2.ヘ
ッド->...->リストi.面1.ヘッド->リストi
面2.ヘッド.||||VVVV面1におけるライン1
面2におけるライン1 面1におけるライン1面2に
おけるライン1||||VVV
V............||||VVVV面1にお
けるラインi面2におけるラインj面1におけるライン
k面2におけるライン1この関数においては、kベンド
のコリネアベンドラインは、k個の個別コンタクトと考
えられる。注意:――――――――デフォールトによ
り、我々は両面における全てのラインをベンドラインに
対する候補と考える。しかし、もしユーザが、ベンドラ
インが何かを既に知っている(あるいは実際には、ベン
ドラインエッジが何であるかを知っている)ときは、ユ
ーザはこれらのラインの名前を用いて、この関数がそれ
らのラインのみを考えるように指示することが出来る。
この関数は、面1または面2のいずれかが、他の面のi
dxに等しい名称を持つか否かをチェックする(面1お
よび面2は個別にチェックされる。)。もし、イエスな
ら、これらのラインのみがその面の側のベンドラインに
対する候補と考えられることになる。*/static int BM_
compute_all_face_to_face_contacts(BM_FACE & face1
/* IN */, BM_FACE & face2 /* IN */,BM_LINKED_LIST_
NODE **list_of_contacts /* OUT */){// initialize g
lobal variables.// this is the contacts list we wi
ll be computing. initially list is NIL.*list_of_co
ntacts = NULL ;// this points to the beginning of
the contacts list.// it does not contain the numbe
r of contacts.// ie. points to "list_of_contacts
[1]".BM_LINKED_LIST_NODE *contacts = NULL ;double
*line_start_coordinates = NULL ; // used when the
set of lines is sortedBM_LINE **line_pointers = NU
LL ; // an array of lines (actually pointers to li
nes) used to store // lines being swept.// once li
nes are sortedaccording to the XZY order, we will
scan this array from the end// to the beginning ->
this implements the sweep.// at the same time, we
maintain a list of open lines. this is done by le
aving line// pointers in thisarray "behind" as the
y are when we move forward in the array.// to eras
e a line from the open list, we simple set the poi
nter in the array to NULL.// endpoints of lines in
face1 and face2 that are larger with respect to X
ZY ordering.// used when processing contacts.BM_PO
INT p_face1, p_face2 ;// some variables used in ma
ny places.long i, j ;BM_POINT p ;/********* ******
**** **********資格チェック********** ********** *
********************/// both faces must be in the
same partif (face1.get_part() == NULL || face1.get
_part() != face2.get_part()) return 0 ;double loca
l_tolerance = (face1.get_part())->get_distance_tol
erance() ;// first try 3D-versions of faces. if bo
th of them are empty, try flat versions.BM_2D_BODY
*body1 = face1.get_current_3D_version() ;BM_2D_BO
DY *body2 = face2.get_current_3D_version() ;if (NU
LL == body1 && NULL == body2) {body1 = face1.get_f
lat() ;body2 = face2.get_flat() ;}// if either of
the 3D-bodiesis NULL we are successfully done.if
(NULL == body1 || NULL == body2) return 1 ;// both
faces must have a plane as the underlying surface
BM_SURFACE *surface1 = body1->get_surface() ;BM_SU
RFACE *surface2 = body2->get_surface() ;if (NULL =
= surface2 || NULL == surface2) return 0 ;if (! su
rface2->is(BM_TYPE_PLANE) || ! surface2->is(BM_TYP
E_PLANE)) return 0 ;//if any of the faces has an e
mpty bloop, we are successfully doneBM_LOOP*bloop1
= body1->get_bloop() ;BM_LOOP *bloop2 = body2->ge
t_bloop() ;if (NULL == bloop1 || NULL == bloop2) r
eturn 1 ;/*********** ********** ********** ******
**** ********** ********** ********** ********** *
*********ここで、我々は、これらの面がともかく接触
出来るか否かの非常に迅速なチェックを行う。 ここ
で、我々は、面2のbループが接触するか(1点以上
で)、面1の平面に交差するか否かをチェックする。
これは、これらの2つの面が明らかに接触出来ない時間
を節約することになる。********** ********** ******
**** ********** ********** ********** ********** *
********* ***********/// these variables will be u
sed to do a quick check if these two// facescan po
ssible touch each otherdouble distance_plane_to_bl
oop1, distance_plane_to_bloop2,distance_plane_to_b
loop3, distance_plane_to_bloop4 ;intdistance_plane
_to_bloop_count ;if (! bloop2->is_bbox_up_to_dat
e()) bloop2->recompute_bbox() ;if (! BM_distance_b
etween_point_and_plane(bloop2->get_bbox_p1(), (BM_
PLANE&) (*surface1), &distance_plane_to_bloop1, NU
LL))return 0 ;if (! BM_distance_between_point_and_
plane(bloop2->get_bbox_p2(), (BM_PLANE&) (*surface
1), &distance_plane_to_bloop2, NULL)) return 0;if
(! BM_distance_between_point_and_plane(bloop2->get
_bbox_p3(), (BM_PLANE&) (*surface1), &distance_pla
ne_to_bloop3, NULL)) return 0 ;if (! BM_distance_b
etween_point_and_plane(bloop2->get_bbox_p4(), (BM_
PLANE&) (*surface1), &distance_plane_to_bloop4, NU
LL)) return 0 ;distance_plane_to_bloop_count = 0 ;
if (fabs(distance_plane_to_bloop1) >= local_tolera
nce) distance_plane_to_bloop_count++ ;if (fabs(dis
tance_plane_to_bloop2) >= local_tolerance) distanc
e_plane_to_bloop_count++ ;if (fabs(distance_plane_
to_bloop3) >= local_tolerance) distance_plane_to_b
loop_count++ ;if (fabs(distance_plane_to_bloop4) >
= local_tolerance) distance_plane_to_bloop_count++
;if (distance_plane_to_bloop_count > 2) {// at mo
st one of the bloop corners is on the plane.// tha
t means, bbox itself is not in contactwith face1./
/ however, it could be that different corners of b
box are on different sides of the plane.// here we
will return if all bloop2 points are on one side
of plane1// ie. these two faces cannot be in conta
ct// // note : at most one of the 4 distance_plane
_to_bloop-i can be zero.// // in the next line we
pick "distance_plane_to_bloop1" for checking not b
ecause it is special,// but because any of the 4 w
ould do.if (fabs(distance_plane_to_bloop1) >= loca
l_tolerance) {if (distance_plane_to_bloop1*distanc
e_plane_to_bloop2 >= 0.0 &&distance_plane_to_bloop
1*distance_plane_to_bloop3 >= 0.0 &&distance_plane
_to_bloop1*distance_plane_to_bloop4>= 0.0) return
1 ;}else {if (distance_plane_to_bloop2*distance_pl
ane_to_bloop3 >= 0.0 &&distance_plane_to_bloop2*di
stance_plane_to_bloop4 >= 0.0) return 1 ;}}// if t
he count is 0, 1 or 2, it means that 2, 3 or 4 bbo
x corners are on the plane.// that means, it is po
ssible that there is acontact./* ここで、我々は、
面2に関してbボックス1に対して同じものをチェック
する。*/if (! bloop1->is_bbox_up_to_date()) bloop1
->recompute_bbox() ;if (! BM_distance_between_poin
t_and_plane(bloop1->get_bbox_p1(), (BM_PLANE&) (*s
urface2), &distance_plane_to_bloop1, NULL)) return
0 ;if (! BM_distance_between_point_and_plane(bloo
p1->get_bbox_p2(), (BM_PLANE&)(*surface2), &distan
ce_plane_to_bloop2, NULL)) return 0 ;if (! BM_dist
ance_between_point_and_plane(bloop1->get_bbox_p
3(), (BM_PLANE&) (*surface2), &distance_plane_to_b
loop3, NULL)) return 0 ;if (! BM_distance_between_
point_and_plane(bloop1->get_bbox_p4(), (BM_PLANE&)
(*surface2), &distance_plane_to_bloop4, NULL)) re
turn 0 ;distance_plane_to_bloop_count = 0;if (fabs
(distance_plane_to_bloop1) >= local_tolerance) dis
tance_plane_to_bloop_count++ ;if (fabs(distance_pl
ane_to_bloop2) >= local_tolerance)distance_plane_t
o_bloop_count++ ;if (fabs(distance_plane_to_bloop
3) >= local_tolerance) distance_plane_to_bloop_cou
nt++ ;if (fabs(distance_plane_to_bloop4) >= local_
tolerance) distance_plane_to_bloop_count++ ;if (di
stance_plane_to_bloop_count > 2) {// at most one o
f the bloop corners ison the plane.// here we will
return if all bloop1 points are on one sideof pla
ne2// ie. these two faces cannot be in contactif
(fabs(distance_plane_to_bloop1) >= local_toleranc
e) {if (distance_plane_to_bloop1*distance_plane_to
_bloop2 >= 0.0 &&distance_plane_to_bloop1*distance
_plane_to_bloop3 >= 0.0 &&distance_plane_to_bloop1
*distance_plane_to_bloop4 >= 0.0)return 1 ;}else
{if (distance_plane_to_bloop2*distance_plane_to_bl
oop3>= 0.0 &&distance_plane_to_bloop2*distance_pla
ne_to_bloop4 >= 0.0) return 1 ;}}/*********** ****
****** ********** ********** ********** **********
********** ********** ********** 両面のラインの
全数をカウントする。メモリを割当てる必要がある。
注意:ラインのみがベンドラインを作ることが出来るの
でラインであるエッジを単にカウントする。 注意:ユ
ーザが特定のベンドエッジを持つか否かをチェックす
る。ユーザは、どのエッジが可能なベンドエッジとして
考えられるかを、それらのエッジの名称を設定すること
により限定することが出来る。********** **********
********** ********** ******************** *******
*** ********** ***********/long face1_has_user_def
ined_bend_edges = 0 ; // the number of user-speici
fed bend edges in face1long face2_has_user_defined
_bend_edges = 0 ; // the number of user-speicifed
bend edges in face2long face1_line_count = 0, face
2_line_count = 0 ;long line_count ; // sum of line
s in faces 1 and 2 participating in the sweep.BM_L
OOP *holes ;BM_EDGE *edges ;for (edges = bloop1->g
et_first_edge() ; edges ; edges = (BM_EDGE *) edge
s->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE))
continue ;if (edges->get_name() == face2.get_id
x()) face1_has_user_defined_bend_edges++ ;face1_li
ne_count++ ;}for (holes = body1->get_first_hole()
; holes ; holes = (BM_LOOP *) holes->next()) {for
(edges = holes->get_first_edge() ; edges ; edges
= (BM_EDGE *) edges->next()) {if (! edges->is(BM_E
NTITY_TYPE_LINE)) continue ;if (edges->get_name()=
= face2.get_idx()) face1_has_user_defined_bend_edg
es++ ;face1_line_count++ ;}}for (edges = bloop2->g
et_first_edge() ; edges ; edges = (BM_EDGE*) edges
->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE)) c
ontinue ;if (edges->get_name() == face1.get_idx())
face2_has_user_defined_bend_edges++ ;face2_line_c
ount++ ;}for (holes = body2->get_first_hole() ; ho
les ; holes = (BM_LOOP *) holes->next()) {for (edg
es = holes->get_first_edge(); edges ; edges = (BM_
EDGE *) edges->next()) {if (! edges->is(BM_ENTITY_
TYPE_LINE)) continue ;if (edges->get_name() == fac
e1.get_idx()) face2_has_user_defined_bend_edges++
;face2_line_count++ ;}}// if there are no lines,
we are successfully doneif (face1_has_user_defined
_bend_edges) face1_line_count = face1_has_user_def
ined_bend_edges ;if (face2_has_user_defined_bend_e
dges) face2_line_count = face2_has_user_defined_be
nd_edges ;if (face1_line_count < 1 || face2_line_c
ount < 1) return 1 ;line_count =face1_line_count +
face2_line_count ;/*********** ********** *******
************* ********** ********** ********** ***
******* **********メモリを割り当てる。********** *
********* ********** ********** ********** *******
*** ********** ********** ***********/if (NULL ==
(line_pointers = new BM_LINE*[line_count])) return
0 ;if (NULL == (line_start_coordinates= new doubl
e[line_count])) {delete [] line_pointers ;}/******
***** ********** ********** ********** **********
********** ********** ********************先ず、ラ
インポインタ配列を充填する。必要なら、ユーザが特定
したエッジだけを取る。********** ********** ******
**** ********** ******************** ********** **
******** ***********/i = 0 ;for (edges = bloop1->g
et_first_edge() ; edges ; edges = (BM_EDGE *) edge
s->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE))
continue ;if (face1_has_user_defined_bend_edges &&
edges->get_name() != face2.get_idx()) continue ;l
ine_pointers[i++] = (BM_LINE *) edges ;}for (holes
= body1->get_first_hole() ; holes; holes = (BM_LO
OP *) holes->next()) {for (edges = holes->get_firs
t_edge() ; edges ; edges = (BM_EDGE *) edges->next
()) {if (! edges->is(BM_ENTITY_TYPE_LINE)) continu
e ;if (face1_has_user_defined_bend_edges && edges-
>get_name() != face2.get_idx()) continue ;line_poi
nters[i++] = (BM_LINE*) edges ;}}for (edges = bloo
p2->get_first_edge() ; edges ; edges = (BM_EDGE *)
edges->next()) {if (! edges->is(BM_ENTITY_TYPE_LI
NE)) continue ;if (face2_has_user_defined_bend_edg
es && edges->get_name() != face1.get_idx()) contin
ue ;line_pointers[i++] = (BM_LINE *) edges ;}for
(holes = body2->get_first_hole() ; holes ; holes =
(BM_LOOP *) holes->next()) {for(edges = holes->ge
t_first_edge() ; edges ; edges = (BM_EDGE *) edges
->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE)) c
ontinue ;if (face2_has_user_defined_bend_edges &&
edges->get_name() != face1.get_idx()) continue;lin
e_pointers[i++] = (BM_LINE *) edges ;}}/**********
* ********** ********** ********** ********** ****
****** ********** ********** **********X座標によ
り、つぎにZ座標により、さらにYによりラインの配列
を分類する。********** ********** ********** *****
***** ********** ********** ********** **********
***********/{ // this is a block of code for sorti
ng the array// first, construct the array of point
s and lines associated with themfor (i = 0 ; i < l
ine_count ; i++) {p = BM_get_greater_point_by_XZY
((line_pointers[i])->get_startpt(),(line_pointers
[i])->get_endpt()) ;line_start_coordinates[i] = p.
X() ;}// sort by XDBM_QuickSort_double(line_start_
coordinates, line_count, (long *) line_pointers) ;
// sort by Zdouble first_in_set_Z = line_start_coo
rdinates[0] ;long set_Z_size = 1, first_in_set_Z_i
dx = 0 ;p = BM_get_greater_point_by_XZY((line_poin
ters[0])->get_startpt(),(line_pointers[0])->get_en
dpt()) ;line_start_coordinates[0] = p.Z() ;for (i
= 1 ; i <= line_count ; i++) {if (i < line_count)
{p =BM_get_greater_point_by_XZY((line_pointers[i])
->get_startpt(),(line_pointers[i])->get_endpt()) ;
if (line_start_coordinates[i] == first_in_set_Z)
{set_Z_size++ ;line_start_coordinates[i] = p.Z() ;
continue ;}}// elsewe have passed the end of the X
-sequenceif (set_Z_size > 1) DBM_QuickSort_double
(line_start_coordinates + first_in_set_Z_idx, set_
Z_size, (long*) line_pointers + first_in_set_Z_id
x) ;// sort by Ylong set_Z_end = first_in_set_Z_id
x + set_Z_size ;double first_in_set_Y = line_start
_coordinates[first_in_set_Z_idx] ;long set_Y_size
= 1, first_in_set_Y_idx = first_in_set_Z_idx ;BM_P
OINT pY(BM_get_greater_point_by_XZY((line_pointers
[first_in_set_Z_idx])->get_startpt(),(line_pointer
s[first_in_set_Z_idx])->get_endpt())) ;line_start_
coordinates[first_in_set_Z_idx] = pY.Y() ;for(j =
first_in_set_Z_idx + 1 ; j <= set_Z_end ; j++) {if
(j < set_Z_end){pY = BM_get_greater_point_by_XZY
((line_pointers[j])->get_startpt(),(line_pointers
[j])->get_endpt()) ;if (line_start_coordinates[j]
== first_in_set_Y) {set_Y_size++ ;line_start_coord
inates[j] = pY.Y() ;continue ;}}//else, we have pa
ssed the end of the Z-sequenceif (set_Y_size > 1)
DBM_QuickSort_double(line_start_coordinates + firs
t_in_set_Y_idx, set_Y_size,(long *) line_pointers
+ first_in_set_Y_idx) ;if (j < set_Z_end) {set_Y_s
ize = 1 ;first_in_set_Y_idx = j ;first_in_set_Y =
line_start_coordinates[j] ;line_start_coordinates
[j] = pY.Y() ;}}if (i < line_count) {set_Z_size =
1 ;first_in_set_Z_idx = i ;first_in_set_Z = line_s
tart_coordinates[i] ;line_start_coordinates[i] =
p.Z() ;}}} // end of the block of codefor sorting
the array/*********** ********** ********** ******
**** ********** ********** ********** ********** *
*********ライン開始座標はこれ以上不要なので、削除
する。********** ********** ********** **********
********** ********** ********** ********** ******
*****/if (line_start_coordinates) {delete [] line_
start_coordinates ;line_start_coordinates = NULL;}
/*********** ********** ********** ********** 主
ループ。2面を掃引する。 開放ラインのトラックを常
に保持する(出発点を我々が見たライン、しかし終点は
未だ見ていないライン-実際には、開始-そして-終了-点
ではなくて、XZYオーダリングに対してより大きくか
つより小さい端点)。 始めに、開放ラインの組は空で
ある。 全ての繰り返しの間次のことを行う: -開
放であったが、今は閉じられるべき全てのラインを除去
する、 -現在のラインが開放ラインと重なるか否か
をチェックする、 -このラインを開放ラインの組に
加える。*/// these represent lists of contactsBM_L
INKED_LIST_NODE *face1_list, *face2_list ;BM_LINKE
D_LIST_NODE *last_face1_list, *last_face2_list;BM_
LINKED_LIST_NODE *left, *right ;BM_LINKED_LIST_NOD
E *new_left = NULL, *new_right = NULL ;BM_LINE *li
ne_in_left, *line_in_right ;// these are the two l
ines we will be comparingBM_2D_BODY *face_of_line
1, *face_of_line2 ;BM_LINE *line_in_face1, *line_i
n_face2 ;BM_LINE *line ;double k,dotp ;BM_POINT p_
open ;BM_VECTOR v ;long num_of_contacts = 0 ;long
open_line_idx ;for (i = line_count - 1 ; i >= 0 ;
i--) {// initially face_of_line1 is the face of th
e current line.// however, later we will sort thec
urrent-sweep-line and current-open-line pointers.f
ace_of_line1 = ((line_pointers[i])->get_loop())->g
et_2D_body() ;p = BM_get_greater_point_by_XZY((lin
e_pointers[i])->get_startpt(),(line_pointers[i])->
get_endpt()) ;// compare this current line against
all open lines in order to detect overlaps, ie. b
endlines.for (open_line_idx = i + 1 ; open_line_id
x < line_count ; open_line_idx++) {line = line_poi
nters[open_line_idx] ;if (NULL== line) {// time-sa
ving trick. if this is the last pointer, there is
no need to try it again.// reduce the index.if (op
en_line_idx == line_count - 1) {--line_count ;brea
k ;}continue ;}// ********** ********** **********
********** **********// check if this open line s
hould really be removed.// it should be removed if
its endpoint is larger than p (ie. the// startpoi
nt of this line).// ********** ********** ********
** ********** **********p_open = BM_get_smaller_po
int_by_XZY(line->get_startpt(),line->get_endpt())
;if (BM_compare_points_by_XZY(p_open,p)) {// time
-saving trick.// if the line we are removing from
the open list is the last one, reduce the index//
instead of setting the pointer to NULL. next timew
e don’t even try this element// in the array, bec
ause it would be beyond the boundaryif (open_line_
idx == line_count - 1) {--line_count ;break;}line_
pointers[open_line_idx] = NULL ;continue ;}// ****
****** ********** ********** ********** **********
// first, check if both lines are inthe same face.
if yes, skip it.// ********** ********** ********
** ********** **********face_of_line2 = (line->get
_loop())->get_2D_body() ;if (face_of_line1 == face
_of_line2) continue ;// ********** ********** ****
****** ********** **********// Check if this line
and the open line overlap.// ********** **********
********** ********** **********// First check if
the startpoint is on the (open) line segment.if
(! line->is_point_on_line(p,&k)) continue ;// Note
that parameter k has to be in [0,1] now, because/
/ the line "line" is open still, ie. it startpoint
is "before"p// and endpoint is "after" p.// Now c
heck if vectors are parallel.v =(line->get_v()) *
((line_pointers[i])->get_v()) ;if (v.Len() > BM_PR
ECISION) continue ;// Last thing, it could be that
only endpoints of the lines overlap.dotp = (line-
>get_v()) % ((line_pointers[i])->get_v()) ;if (dot
p < 0.0) { // lines are opposite// startpoint-star
tpoint/endpoint-endpoint should not matchif ((line
->get_startpt()) == ((line_pointers[i])->get_start
pt()) || (line->get_endpt()) == ((line_pointers
[i])->get_endpt())) continue ;}else { // lines hav
e the same direction// startpoint-endpoint/endpoin
t-startpoint should not matchif ((line->get_endp
t()) == ((line_pointers[i])->get_startpt()) || (li
ne->get_startpt()) == ((line_pointers[i])->get_end
pt())) continue ;}// ********** ********** *******
*** ********** **********// Ok, these two lines ov
erlap.// First, sort lines according to which face
they are in// ********** ********** ********** **
******** **********if (&face1 == (BM_FACE *) face_
of_line1->get_3D_body()) {line_in_face1 = line_poi
nters[i] ;line_in_face2 = line ;p_face1 = p ;p_fac
e2 = BM_get_greater_point_by_XZY(line->get_startpt
(),line->get_endpt()) ;}else {line_in_face1 = line
;line_in_face2 = line_pointers[i] ;p_face1 = BM_g
et_greater_point_by_XZY(line->get_startpt(),line->
get_endpt()) ;p_face2 = p ;}// ********** ********
** ********** ********** **********// Scan all kno
wn contacts and check if this contact should be//
addedto an existing contact// ********** *********
* ********** ********** **********for (j = 0, last
_face2_list = NULL ; j < num_of_contacts ; j++){if
(NULL == last_face2_list) {last_face1_list = cont
acts ;last_face2_list = last_face1_list->next() ;}
else {last_face1_list = last_face2_list->next() ;l
ast_face2_list = last_face1_list->next() ;}left =
(BM_LINKED_LIST_NODE *) last_face1_list->get_obj()
;right = (BM_LINKED_LIST_NODE *) last_face2_list-
>get_obj() ;line_in_left = (BM_LINE *) left->get_o
bj() ;line_in_right = (BM_LINE *) right->get_obj()
;// Check if the line of this existing contact ov
erlaps the new contact.// condition is : point on
the line and vectors are parallel.if (! line_in_le
ft->is_point_on_line(p_face1,&k)) continue ;v = (l
ine_in_left->get_v()) * (line_in_face1->get_v()) ;
if (v.Len() > BM_PRECISION) continue ;// Check tha
t lines in face1and face2 and exact extensions of
left and right in this contact// thisis because we
want every contact in the list of contacts to be
a "closed" contact// note it could be that one of
the new lines in already in this contact.// then w
e don’t need to check.if (line_in_left != line_in
_face1) {dotp = (line_in_left->get_v()) % (line_in
_face1->get_v()) ;if (dotp < 0.0) { // lines are o
pposite// startpoints must matchif ((line_in_left-
>get_startpt()) != (line_in_face1->get_startpt())
&&(line_in_left->get_endpt()) != (line_in_face1->g
et_endpt())) continue ;}else { // lines have the s
ame direction// endpoints must matchif ((line_in_l
eft->get_endpt()) != (line_in_face1->get_startp
t()) &&(line_in_left->get_startpt()) != (line_in_f
ace1->get_endpt())) continue ;}}if (line_in_right
!= line_in_face2) {dotp = (line_in_right->get_v())
% (line_in_face2->get_v()) ;if(dotp < 0.0) { // l
ines are opposite// startpoints must matchif ((lin
e_in_right->get_startpt()) != (line_in_face2->get_
startpt()) &&(line_in_right->get_endpt()) != (line
_in_face2->get_endpt())) continue ;}else { // line
s have the same direction// endpoints must matchif
((line_in_right->get_endpt()) != (line_in_face2->
get_startpt()) &&(line_in_right->get_startpt()) !=
(line_in_face2->get_endpt())) continue ;}}// ever
ything is fine. add lines to this contact.// note
that is could be that the line is already in the c
ontact.if (line_in_left != line_in_face1) {if (NUL
L == (new_left = new BM_LINKED_LIST_NODE(line_in_f
ace1,NULL,left))) goto failure ;last_face1_list->s
et_obj((BM_BASIC *) new_left) ;new_left = NULL ;}i
f(line_in_right != line_i
n_face2) {if (NULL == (ne
w_right = new BM_LINKED_L
IST_NODE(line_in_face2,NU
LL,right))) goto failure
;last_face2_list−>set_ob
j((BM_BASIC *) new_right)
;new_right = NULL ;}// n
ow we have to break out o
f here. we added this con
tact to an existing conta
ct.break ;}//check if we
checked all contacts and
could not find a matchif
(j < num_of_contacts) con
tinue ;// ********** ****
****** ********** *******
*** **********// Create a
new contact.// *********
* ********** ********** *
********* **********// Fi
rst, create nodes for bot
h lines.if (NULL == (left
= new BM_LINKED_LIST_NODE
(line_in_face1))) goto fa
ilure ;if (NULL == (right
= new BM_LINKED_LIST_NOD
E(line_in_face2))) {delet
e left ;goto failure ;}//
Create lists for both si
des of the contact.if (NU
LL == (face2_list = new B
M_LINKED_LIST_NODE((BM_BA
SIC *) right))) {delete l
eft ;delete right ;goto f
ailure ;}if (NULL == (fac
e1_list = new BM_LINKED_L
IST_NODE((BM_BASIC *) lef
t,NULL,face2_list))) {del
ete left ;delete right ;d
elete face2_list ;goto fa
ilure ;}// add the new co
ntact to the list of cont
actsif (num_of_contacts <
1) contacts = face1_list
;else last_face2_list−>a
dd_after(face1_list) ;++n
um_of_contacts ;}// we us
e i to index line_pointer
s[] array.// since i will
be decremented shortly,
line_pointers[i] will be
”implictly” put on // th
e open list of sweep line
s.}/*********** *********
* ********** **********必要
ならメモリを自由にする。********** ********** ****
****** ***********/if (line_start_coordinates) del
ete [] line_start_coordinates ;if (line_pointers)
delete [] line_pointers ;// finally, create a node
for the number of contactsif (NULL == (left = new
BM_LINKED_LIST_NODE((BM_BASIC *) num_of_contacts,
NULL,contacts))) goto failure ;*list_of_contacts =
left ;return 1 ;failure :// free memory if necess
aryif (line_start_coordinates) delete [] line_star
t_coordinates ;if (line_pointers) delete [] line_p
ointers ;BM_LINKED_LIST_NODE *list, *next_list ;BM
_LINKED_LIST_NODE *line_in_list, *next_line_in_lis
t ;for (list =contacts ; list ; list = next_list)
{next_list = list->next() ;for (line_in_list = (BM
_LINKED_LIST_NODE *) list->get_obj() ; line_in_lis
t ; line_in_list = next_line_in_list) {next_line_i
n_list = line_in_list->next();delete line_in_list
;}delete list ;}if (new_left) delete new_left ;if
(new_right) delete new_right ;return 0 ;}/* この
関数は2つの面の間のコンタクトのリストを掃引する
(BMにより殆ど同様に生成される 全ての面から面の
接点を計算する)そして全ての、ただし最大の接点を除
去する。 基本的には、それは接点のリストを”濾過”
し、最も長い接触部に属さない接触部を除去する。一般
に、最も長い接触部は同時的なベンドラインのリストで
ある点に注目されたい。かくして、接触部リストの基本
構造は同じである。 例えば、リスト中の第一のノード
は最も長いコンタクト中のコンタクトの数である。 こ
の関数はまた最も長いコンタクトの長さに戻す。 この
関数においては、全てのコンタクトが閉じられ、従って
コンタクト中のラインのリストにおいて、ラインの端点
は次のラインの出発点に等しくなるという事実を利用し
ている。 この方法で唯一のトリッキーな部分は、第一
の、および最後のラインにおける重なり部分の長さを計
算することにある。次に、リストの中間でラインの長さ
を付加する。前の関数を参照されたい。*/static doubl
e BM_keep_largest_contact_remove_the_rest(BM_LINKE
D_LIST_NODE **list_of_contacts){long i, j ;if (NUL
L == list_of_contacts) return 0.0 ;BM_LINKED_LIST_
NODE *contacts = *list_of_contacts ;if (NULL == co
ntacts) return 0.0 ;// some of the most importantp
arameters we compute in this function.double lengt
h_of_largest_contact= 0.0 ;long largest_contact_i
= -1 ;// we need to keep track of the lengths of c
ontacts.// we need to store the length of every co
ntact.// // NOTICE : here we try to save some heap
allocation/release time by using apre-allocated//
array if the list of contacts is not very long.//
staticdouble static_contact_len_array[32] ;double
*dynamic_contact_len_array= NULL ;double *contact
_len_array = NULL ;// get the number of contactslo
ng num_of_contacts = (long) contacts->get_obj() ;c
ontacts = contacts->next() ;// if no contacts, del
ete the entire listif (num_of_contacts < 1){// the
re is no list. delete node 0 as well.delete *list_
of_contacts ;*list_of_contacts = NULL ;return 0.0
;}// allocate memory for the contactlength arrayi
f (num_of_contacts <= 32) {contact_len_array = sta
tic_contact_len_array ;}else {if (NULL == (dynamic
_contact_len_array = new double[num_of_contacts]))
goto computation_done__clean_up ;contact_len_arra
y= dynamic_contact_len_array ;}// Scan all known c
ontacts and compute thelength of every contact.//
later we use these values to find the longest cont
act (which could be a simultaneous bendline).BM_LI
NKED_LIST_NODE *last_face1_list, *last_face2_list
;BM_LINKED_LIST_NODE *line_in_list ;double k ;dou
ble first_k1, first_k2 ;double last_k1, last_k2 ;l
ast_face2_list = NULL ;for (i = 0 ; i < num_of_con
tacts ; i++) {if (NULL == last_face2_list) last_fa
ce1_list = contacts ;else last_face1_list = last_f
ace2_list->next() ;last_face2_list = last_face1_li
st->next() ;BM_LINKED_LIST_NODE *left = (BM_LINKED
_LIST_NODE *) last_face1_list->get_obj() ;BM_LINKE
D_LIST_NODE *right = (BM_LINKED_LIST_NODE *) last_
face2_list->get_obj();BM_LINE *first_line_in_left
= (BM_LINE *) left->get_obj() ;BM_LINE *first_line
_in_right = (BM_LINE *) right->get_obj() ;// here
is what we do.we know that the first lines in left
and right have to have// an overlapping part. we
compute overlapping parameters k1 and k2 with resp
ect tothe// first line on the left, between the fi
rst lines. // the idea is that one of the points t
hat corresponds to these parameters (k1 and k2)//i
s the extreme point of the contact. we just don’t
know yet which one.// then we find the last point
s in both lists. we know that they must have non-e
mpty// overlapping part as well. we compute k1 and
k2 for these two lines as well.// then we compate
k1,k2 for the first and last pairs to find the tw
o// extreme points of the contact. distance betwee
n them isthe length of the contact.// compute k1 a
nd k2 for the first lines.first_line_in_left->is_p
oint_on_line(first_line_in_right->get_startpt(),&f
irst_k1) ;first_line_in_left->is_point_on_line(fir
st_line_in_right->get_endpt(),&first_k2) ;// we on
ly want k1 and k2 within the first lineif (first_k
1 < 0.0) first_k1 = 0.0 ;else if (first_k1 > 1.0)
first_k1 = 1.0 ;if(first_k2 < 0.0) first_k2 = 0.0
;else if (first_k2 > 1.0) first_k2 = 1.0 ;// sort
k1 and k2if (first_k1 > first_k2) { k = first_k1
; first_k1 =first_k2 ; first_k2 = k ; }// find th
e last line in the left.for (line_in_list = left->
next() ; line_in_list ; line_in_list = line_in_lis
t->next()) {left = line_in_list ;}// "left" is the
last node in the left now.BM_LINE *last_line_in_l
eft = (BM_LINE *) left->get_obj() ;// find the las
t line in the right.for (line_in_list = right->nex
t() ; line_in_list ; line_in_list = line_in_list->
next()) {right = line_in_list ;}// "right" is the
last node in the left now.BM_LINE *last_line_in_ri
ght = (BM_LINE *) right->get_obj() ;// compute k1
and k2 for the first lines.last_line_in_left->is_p
oint_on_line(last_line_in_right->get_startpt(),&la
st_k1) ;last_line_in_left->is_point_on_line(last_l
ine_in_right->get_endpt(),&last_k2) ;// we only wa
nt k1 and k2 within the last lineif (last_k1 < 0.
0) last_k1 = 0.0 ;else if (last_k1 > 1.0) last_k1
= 1.0 ;if (last_k2 < 0.0) last_k2 = 0.0 ;else if
(last_k2 > 1.0) last_k2 = 1.0 ;// note that we hav
e compute last k1 and k2 with respect to the last
line in the left.// wereally need last k1 and k2 w
ith respect to the first line in the left.BM_POINT
lastk1(last_line_in_left->get_startpt() + last_k1
*(last_line_in_left->get_v())) ;BM_POINT lastk2(la
st_line_in_left->get_startpt() + last_k2*(last_lin
e_in_left->get_v())) ;first_line_in_left->is_point
_on_line(lastk1,&last_k1) ;first_line_in_left->is_
point_on_line(lastk2,&last_k2);// sort k1 and k2if
(last_k1 > last_k2) { k = last_k1 ; last_k1 = las
t_k2 ; last_k2 = k ; }// now we need to take the e
xtreme points of these two pairsif (first_k1 > las
t_k1) first_k1 = last_k1 ;if (first_k2 < last_k2)
first_k2 = last_k2 ;contact_len_array[i] = (first_
k2 - first_k1)*(first_line_in_left->get_len()) ;}/
/ find the longest contact.// the main feature her
e is to check for simultaneous bendlineslast_face2
_list = NULL;for (i = 0 ; i < num_of_contacts ; i+
+) {if (NULL == last_face2_list)last_face1_list =
contacts ;else last_face1_list = last_face2_list->
next() ;last_face2_list = last_face1_list->next()
;// make sure we don’t accept contacts that have
zero length.if (contact_len_array[i] < BM_PRECISI
ON) continue ;BM_LINKED_LIST_NODE *left = (BM_LINK
ED_LIST_NODE *) last_face1_list->get_obj() ;BM_LIN
E *first_line_in_left = (BM_LINE *) left->get_ob
j() ;// check if this contact is part of a simulta
neous bendline.//if yes, add its length to the fir
st bendline in the simultaneous bendline and// set
this length here to -1.0, so that we know it late
rBM_LINKED_LIST_NODE *temp_last_face1_list, *temp_
last_face2_list = NULL ;for (j =0 ; j < i ; j++)
{if (contact_len_array[i] < BM_PRECISION) continue
; // already part of something elseif (NULL == te
mp_last_face2_list) temp_last_face1_list = contact
s ;else temp_last_face1_list = temp_last_face2_lis
t->next() ;temp_last_face2_list = temp_last_face1_
list->next() ;BM_LINKED_LIST_NODE *temp_left = (BM
_LINKED_LIST_NODE *) temp_last_face1_list->get_obj
() ;BM_LINE *temp_first_line_in_left = (BM_LINE *)
temp_left->get_obj() ;// check if the lines overl
apif (! first_line_in_left->is_point_on_line(temp_
first_line_in_left->get_startpt(),NULL)) continue
;if (! first_line_in_left->is_point_on_line(temp_
first_line_in_left->get_endpt(),NULL)) continue ;/
/ ok, they overlap// add the length to the first i
n simultaneous bend and set this to -1.0contact_le
n_array[j] += contact_len_array[i] ;contact_len_ar
ray[i] = -1.0 ;break ;}}// in this loop we actuall
y find the largestfor (i = 0 ; i < num_of_contacts
; i++) {// check to see if this new contact is th
e largestif (length_of_largest_contact <contact_le
n_array[i]) {length_of_largest_contact = contact_l
en_array[i];largest_contact_i = i ;}}computation_d
one__clean_up :// remove all other contacts that a
re not largestBM_LINKED_LIST_NODE *next_last_face1
_list, *next_last_face2_list = NULL ;BM_LINKED_LIS
T_NODE *largest_contact_list_f1 = NULL, *largest_c
ontact_list_f2 ;last_face1_list = contacts ;last_f
ace2_list = last_face1_list->next() ;for (i = j =
0 ; i < num_of_contacts ; i++) {nex
t_last_face1_list = last_
face2_list−>next() ;if (n
ext_last_face1_list) next
_last_face2_list = next_l
ast_face1_list−>next() ;e
lse next_last_face2_list
= NULL ;// make sure we d
on’t delete the largest contact// note : we ski
p two lists, face1 list and face2 listif (contact_
len_array[i] < 0.0 || largest_contact_i == i) {if
(NULL == largest_contact_list_f1) largest_contact_
list_f1 = last_face1_list ;else largest_contact_li
st_f2->add_after(last_face1_list) ;largest_contact
_list_f2 = last_face2_list ;// count the number of
contacts++j ;last_face1_list = next_last_face1_li
st ;last_face2_list = next_last_face2_list ;contin
ue ;}// ok,this is not the largest contact, delete
both face1 and face2 sides of the contactBM_LINKE
D_LIST_NODE *next_line_in_list ;for (line_in_list
= (BM_LINKED_LIST_NODE *) last_face1_list->get_obj
() ; line_in_list ; line_in_list = next_line_in_li
st) {next_line_in_list = line_in_list->next() ;del
ete line_in_list ;}for (line_in_list = (BM_LINKED_
LIST_NODE *) last_face2_list->get_obj() ; line_in_
list ; line_in_list = next_line_in_list) {next_lin
e_in_list = line_in_list->next() ;delete line_in_l
ist ;}delete last_face1_list ;delete last_face2_li
st ;last_face1_list = next_last_face1_list ;last_f
ace2_list = next_last_face2_list ;}// end the cont
act listwith a NULL pointerif (largest_contact_lis
t_f2) largest_contact_list_f2->add_after(NULL) ;//
write the number of contacts left in node 0. als
o,set the correct beginning of the list.// howeve
r, if there is no contact, erase the entire list.i
f (NULL == largest_contact_list_f1) {// thereis no
list. delete node 0 as well.delete *list_of_conta
cts ;*list_of_contacts = NULL ;}else {(*list_of_co
ntacts)->set_obj((BM_BASIC *) j) ;(*list_of_contac
ts)->add_after(largest_contact_list_f1) ;}// delet
e dynamic_contact_len_array if it was allocatedif
(dynamic_contact_len_array) delete [] dynamic_cont
act_len_array ;return length_of_largest_contact ;}
/*この関数は、サブルーチンとして静的なint BM
create ベンドライン(...)によってのみ
用いられる。 現在の大きな問題は、我々が幾つかのラ
インを削除しているということである。 この問題は、
我々が同時ベンドを持つとき、他のコンタクトはなお我
々が丁度削除したこれらのラインを参照していることが
出来るということである。 我々は進んでそれをチェッ
クしなければならず、もし真なら、有効な参照によりポ
インタを我々が変更し/削除したラインに置き換えなけ
ればならない。 すなわち、影響されたラインは左側の
最初のそして最後のラインである。 潜在的には、それ
らに対する参照は11および13を参照して置き換えら
れる必要がある。*/static void check_references_in_
remaining_contacts(BM_LINKED_LIST_NODE *side_1, //
current list we are working withBM_LINKED_LIST_NO
DE *side_2, // list on the other side of thecontac
tBM_LINE *line1, BM_LINE *line3, // these are old
references, tobe checked if still validBM_LINE *l
1, BM_LINE *l3 // l1 and l3 are the new reference
s){BM_LINKED_LIST_NODE *side1 = side_1, *side2 = s
ide_2 ;process_next_contact :// find the beginning
s of lists in the next contactBM_LINKED_LIST_NODE
*contact_list ;if (NULL == (contact_list = side1->
next())) return ; // done, no more listsif (NULL =
= (side1 = contact_list->next())) return ; // don
e, no more listsif (NULL == (contact_list = side2-
>next())) return ; // done, no more listsif (NULL
== (side2 = contact_list->next())) return ; // don
e, no more lists// now we need to check thebeginni
ng of this contact and the end of this contact exa
ctly the sameway.// we describe checking the begin
ning, check the end is the same.//whenever we find
a match, we can go to the next list (ie. don’t h
ave tocontinue with the// current list).// // we t
ake first lines is side1 and side2. if the first l
ine in side1 is either line1 or line3,// we checkw
hich of l1 and l3 overlaps the first line in side
2. we know that exactly one of// l1 and l3 has to
overlap. then we replace the reference to line1/li
ne3 with a reference to the// one of l1/l3 that ov
erlaps the first line in side2.BM_LINKED_LIST_NODE
*start_side1 = (BM_LINKED_LIST_NODE*) side1->get_
obj() ;BM_LINKED_LIST_NODE *start_side2 = (BM_LINK
ED_LIST_NODE *) side2->get_obj() ;// check the beg
inning of the contactBM_LINE *line_in_side1 = (BM_
LINE *) start_side1->get_obj() ;BM_LINE *line_in_s
ide2 = (BM_LINE *) start_side2->get_obj() ;if (lin
e_in_side1 == line1 || line_in_side1 == line3) {if
(l1) { // check if l1 overlaps first line inside2
if (line_in_side2->is_point_on_line_segment(l1->ge
t_startpt(), NULL) ||line_in_side2->is_point_on_li
ne_segment(l1->get_endpt(), NULL)) {start_side1->s
et_obj(l1) ;goto process_next_contact ;}}if (l3)
{ // check if l3 overlaps first line in side2if (l
ine_in_side2->is_point_on_line_segment(l3->get_sta
rtpt(), NULL) ||line_in_side2->is_point_on_line_se
gment(l3->get_endpt(), NULL)) start_side1->set_obj
(l3) ;}goto process_next_contact ;}BM_LINKED_LIST_
NODE *line_in_list, *prev_line_in_list ;// find th
e last line in side2.for (line_in_list = start_sid
e2->next() ; line_in_list ; line_in_list = line_in
_list->next()) {prev_line_in_list = line_in_list
;}// "prev_line_in_list" is the last node in the
left now.line_in_side2 = (BM_LINE *) prev_line_in_
list->get_obj() ;// find the last line in side1.fo
r (line_in_list = start_side1->next() ; line_in_li
st ; line_in_list = line_in_list->next()) {prev_li
ne_in_list = line_in_list ;}// "prev_line_in_list"
is the last node in side1 now.line_in_side1 = (BM
_LINE*) prev_line_in_list->get_obj() ;// check the
end of the contactif (line_in_side1 == line1 || l
ine_in_side1 == line3) {if (l1) { // check if l1ov
erlaps first line in side2if (line_in_side2->is_po
int_on_line_segment(l1->get_startpt(), NULL) ||lin
e_in_side2->is_point_on_line_segment(l1->get_endpt
(), NULL)) {prev_line_in_list->set_obj(l1) ;goto p
rocess_next_contact ;}}if (l3) { // check if l3 ov
erlaps first line in side2if (line_in_side2->is_po
int_on_line_segment(l3->get_startpt(), NULL) ||lin
e_in_side2->is_point_on_line_segment(l3->get_endpt
(), NULL)) prev_line_in_list->set_obj(l3) ;}}goto
process_next_contact ;}/* この関数は、入力として
与えられたコンタクトリストに基づいて、2つの面間に
簡単な(規則的な)ベンドラインを形成する。一端これ
がなされると、それはコンタクトリストを消去する。
この関数では、面のエッジは左手の規則に従って分類さ
れると仮定する。この関数は、もし全てがファインのと
きは、TRUEに戻す。 NB!ここでの問題点は、新
しいベンドラインを形成したとき、何かを部分的に無効
にすることではない。 それを完成するために、我々
は、分離であるベンドopを形成し(ベンドライン無し
に)(原文理解出来ず)、後にそれをベンドラインに付
加する。 更に、我々は、ベンドラインが形成され、部
分に付加された後にのみトポロジーを形成する。 この
関数は、面1(主として、垂直な面1)に一致するベン
ドライン情報を形成する点に注目されたい。 ただし、
垂直な面2はこの情報と不一致でもよいが、後に固定さ
れなければならない。*/static int BM_create_bendlin
e(BM_PART & part, BM_LINKED_LIST_NODE **contact, B
M_BENDLINE **bendline_created /* OUT */){// so fa
r, nothing is created*bendline_created= NULL ;// i
t is possible, that we are building bendlines for
the flat version of the part.// if this variables
is TRUE, we are building bendlines for the 3D-vers
ion, otherwise for the flat.int using_3D_version =
1 ;// later we need to create a bendline centerli
ne// these are the start-end points of the bendlin
e centerline// note that they are points p1 andp2
on the face1 side of the bendline// this is done b
ecause sometimes (when the bendline is not bent) w
e use the// face1 surface as the bendlinesurface,
ie. the bendline orientation is defined// with res
pect to face1BM_POINT bendline_centerline_p1, bend
line_centerline_p2 ;// contact list parametersBM_L
INKED_LIST_NODE *line_in_list, *next_line_in_list
;BM_LINKED_LIST_NODE *left, *right ;int number_of
_lists = (long) (*contact)->get_obj() ;BM_LINKED_L
IST_NODE *contact_list = (*contact)->next() ;left
=(BM_LINKED_LIST_NODE *) contact_list->get_obj() ;
right = (BM_LINKED_LIST_NODE *) (contact_list->nex
t())->get_obj() ;BM_LINE *first_line_in_left= (BM_
LINE *) left->get_obj() ;BM_LINE *first_line_in_ri
ght = (BM_LINE*) right->get_obj() ;BM_LINE *last_l
ine_in_left ;BM_LINE *left_line, *right_line ;// g
et loops in both bodiesBM_LOOP *face1_loop = first
_line_in_left->get_loop() ;BM_LOOP *face2_loop = f
irst_line_in_right->get_loop();if (NULL == face1_l
oop || NULL == face2_loop) return 0 ;// 2D-bodies
of either faceBM_2D_BODY *face1_body = face1_loop-
>get_2D_body() ;BM_2D_BODY *face2_body = face2_loo
p->get_2D_body() ;if (NULL == face1_body || NULL =
= face2_body) return 0 ;// get face1 and face2BM_F
ACE *face1 = (BM_FACE *) face1_body->get_3D_body()
;BM_FACE *face2 = (BM_FACE *) face2_body->get_3D_
body() ;if (NULL == face1 || NULL == face2) return
0 ;// check whether we are using the flat version
of the part, or 3D-version of the part.if (face1-
>get_current_3D_version() != face1_body || face2->
get_current_3D_version() != face2_body) using_3D_v
ersion = 0 ;// get surfacesof either facesBM_PLANE
*face1_plane, *face2_plane ;face1_plane = (BM_PLA
NE *) face1_body->get_surface() ;face2_plane = (BM
_PLANE *) face2_body->get_surface() ;/* 先ず、ベ
ンドラインと共にしなければならない全てのこと、ベン
ドラインを形成する、ベンドopを形成する、ベンドo
pパラメータを設定する、ベンドラインに対するシリン
ダを形成、設定する、ベンドライン、センタラインを設
定するなどを行う。*/// try to figure out whether w
e have aFRONT or BACK bend.BM_VECTOR v_face2_body
((face2_plane->get_normal())*(first_line_in_right-
>get_v())) ; // this vector// points towards the i
nside of face2 on the plane of face2BM_VECTOR v_fa
ce2_normal(v_face2_body*(first_line_in_left->get_v
())) ; // this is the correct normal for face2?//
compute the angle between facesdouble angle = v_fa
ce2_normal ^ (face1_plane->get_normal()) ;// compu
te bend type (FRONT/BACK)if (fabs(angle) <= BM_ANG
LE_TOLERANCE) angle = PI ;else {BM_VECTOR v((face1
_plane->get_normal())*v_face2_normal) ;if (v % (fi
rst_line_in_left->get_v()) > 0.0)angle = PI + angl
e ; // BACK bendelse angle = PI - angle ; // FRONT
bend}// create a new empty bendline and add it to
the partBM_2D_BODY *new_auto_bendline = new BM_2D
_BODY ;if (NULL == new_auto_bendline) return 0 ;BM
_BENDLINE *new_bendline = new BM_BENDLINE(&part, u
sing_3D_version ? NULL : new_auto_bendline, using_
3D_version ? new_auto_bendline : NULL) ;if(NULL ==
new_bendline) {delete new_auto_bendline ;return 0
;}// createa regular bend op for the bendlineBM_B
END_OP_REGULAR *new_bend_op = newBM_BEND_OP_REGULA
R(NULL,angle,0.0,0.0) ; // don’t attach to bendli
ne yetif (NULL == new_bend_op) {delete new_bendlin
e ;return 0 ;}// attach this bend op to the bendli
ne. this will just assign the bend_op variable int
he bendlinenew_bendline->attach_bend_op(new_bend_o
p) ;// create bendline surface. if angle is not 18
0 degrees, we create a cylinder, otherwisea (face
1) plane.BM_SURFACE *bend_surface ;if (fabs(angle
- PI) <= BM_ANGLE_TOLERANCE) { // bendline not bei
ng bent// note : face1 plane is thebendline surfac
ebend_surface = new BM_PLANE(*face1_plane) ;new_be
ndline->Do_This_Bend(0) ; // this will invalidate
3D version as well. later wevalidate it.// set sen
se to the same as face1 sensenew_auto_bendline->se
t_sense(face1_body->get_sense()) ;}else {// first,
compute vxBM_VECTOR v_face1_body((face1_plane->ge
t_normal())*(first_line_in_left->get_v())) ;// v_f
ace1_body points towards the inside of face1 on th
e plane of face1v_face1_body.set_length(-1.0) ; //
invert and normalizev_face2_body.set_length(-1.0)
; // invert and normalize// this is the vx vector
of the bendline surfaceBM_VECTOR vx(v_face1_body
+ v_face2_body) ;bend_surface =new BM_CYLINDER(fir
st_line_in_left->get_startpt(), first_line_in_left
->get_endpt(), vx, 0.0) ;new_bendline->Do_This_Ben
d(1) ; // this will invalidate 3D version as well.
later we validate it.// set sense to 0, because w
e want the bendline (cylinder) to represent explic
itly OUTSIDE// ie.thickness vector is opposite to
the normal (= radius vector).new_auto_bendline->se
t_sense(0) ;}if (NULL == bend_surface) {delete new
_bendline ;return 0 ;}new_auto_bendline->set_surfa
ce(bend_surface) ;// lastly we need to create the
bendline centerline, but for that we need to know
its length, and// start-end-points. However, for t
hat we need to process the contact list which cont
ains the// lines that are adjacent. We will do tha
t next, and when done, will create bendline center
line./* 第二に、必要なら、幾つかのラインを破断
し、全ての隣接ラインを1つの隣接ラインに結合する。
更に、面1-ベンドラインと面2-ベンドラインの間の隣
接情報を形成する。*/// notice that processing one
side of the contact is independent of the other si
de.// moreover, the logic is exactly the same. the
refore, we will use the following code// to proces
s both face1’ side and face2’ side.char face2_pr
ocessed = 0 ;process_one_side_of_the_contact :// i
n general, the contact line (on the side of either
face (face1 and face2)) will consist// of three l
ines - we have a list of lines, first line is thel
ine before the contact, the// second line is the c
ontact line, the lastline is the line after the co
ntact.// these variables will be used to compute t
hese three lines.double k ;double k0, k1, k2, k3 ;
// parametersk for the first line in the leftdoub
le end_k1, end_k2 ; // parameters kfor the last li
ne in the left listBM_POINT p0, p1, p2, p3 ; // p0
- p3are the endpoints of the edges that will be l
eft (ie. endpoint of left_line, l2, l3).// p0 and
p3 and the two extreme endpoints and trivial to fi
nd. we really need to compute only p1 and p2.BM_LI
NE *l1, *l2, *l3 ; //l1 is the line before l2, l2
is the line that is adjacent, l3 is the one after
it.// process first line of the left sidek0 = 0.0
;k3 = 1.0 ;first_line_in_left->is_point_on_line(f
irst_line_in_right->get_startpt(),&k1) ;first_line
_in_left->is_point_on_line(first_line_in_right->ge
t_endpt(),&k2) ;if (k1 > 1.0) k1 = 1.0 ;else if (k
1 < 0.0) k1 = 0.0 ;if (k2 > 1.0) k2 = 1.0 ;else if
(k2 < 0.0) k2 = 0.0 ;if (k2 < k1) { k = k1 ; k1 =
k2; k2 = k ; }// note that we cannot yet compute
p0, p1 and p3 because wedon’t know the relative o
rder// of the first and last lines in the left lis
t// find and process the last linefor (line_in_lis
t = left ; line_in_list ; line_in_list = next_line
_in_list) {if (NULL == (next_line_in_list = line_i
n_list->next())) {left_line = (BM_LINE *) line_in_
list->get_obj() ;// first, we have to find the end
of the face2 listfor (line_in_list = right ; line
_in_list ; line_in_list = next_line_in_list) {if
(NULL== (next_line_in_list = line_in_list->nex
t())) break ;}right_line = (BM_LINE *) line_in_lis
t->get_obj() ;left_line->is_point_on_line(right_li
ne->get_startpt(),&end_k1) ;left_line->is_point_on
_line(right_line->get_endpt(),&end_k2) ;if (end_k1
> 1.0) end_k1 = 1.0 ;else if (end_k1 < 0.0) end_k
1 = 0.0 ;if (end_k2 > 1.0) end_k2 = 1.0 ;else if
(end_k2 < 0.0) end_k2 = 0.0 ;if (end_k2 < end_k1)
{ k = end_k1 ; end_k1 = end_k2 ; end_k2 =k ; }brea
k ;}}// now we have to compute points p0, p1, p2 a
nd p3.// butfirst we need to convert end-k paramet
ers to equivalent parameters withrespect to the //
first line in the leftp0 = left_line->get_startpt
() ;p1 = left_line->get_startpt() + end_k1 * (left
_line->get_v()) ;p2 = left_line->get_startpt() + e
nd_k2 * (left_line->get_v()) ;p3 = left_line->get_
endpt() ;// check k0first_line_in_left->is_point_o
n_line(p0,&k) ;if (k< k0) k0 = k ;// check k1first
_line_in_left->is_point_on_line(p1,&k) ;if(k < k1)
k1 = k ;// check k2first_line_in_left->is_point_o
n_line(p2,&k);if (k > k2) k2 = k ;// check k3first
_line_in_left->is_point_on_line(p3,&k) ;if (k > k
3) k3 = k ;// here we can compute p0, p1 and p3. l
ater wecompute p2.p0 = first_line_in_left->get_sta
rtpt() + k0 * (first_line_in_left->get_v()) ;p1 =
first_line_in_left->get_startpt() + k1 * (first_li
ne_in_left->get_v()) ;p2 = first_line_in_left->get
_startpt() + k2 * (first_line_in_left->get_v()) ;p
3 = first_line_in_left->get_startpt() + k3 *(first
_line_in_left->get_v()) ;// ok, we have computed p
0-p3. now we will erase left list, except for the
first line.// we need the first linelater.// actua
lly, the first line will, in the future, point to
new linel2.BM_LOOP *left_loop = first_line_in_left
->get_loop() ;last_line_in_left = NULL ; // the la
st line in the left. we need it later to replace o
ut-of-date pointers with valid ones.line_in_list =
left->next() ; // thisis the second line in the l
eft list.left->add_after(NULL) ;// note : wewill e
rase all lines in the left list, starting from the
second line.for (; line_in_list ; line_in_list =
next_line_in_list) {next_line_in_list= line_in_lis
t->next() ;// store a pointer to the last linelast
_line_in_left = (BM_LINE *) line_in_list->get_ob
j() ;left_loop->remove_edge(last_line_in_left) ;de
lete last_line_in_left ;delete line_in_list ;}// f
inally, create the adjacent line l2, and two more
lines (l1 and l3) if necessary.if (p0 != p1) {l1 =
first_line_in_left ;l1->set(p0,p1) ;l2 = new BM_L
INE(p1,p2) ;left_loop->add_edge_after(l1,l2) ;}els
e {l1 = NULL ;l2 = first_line_in_left ;l2->set(p0,
p2) ;}if (p2 != p3) {l3 = new BM_LINE(p2,p3) ;left
_loop->add_edge_after(l2,l3) ;}else l3 = NULL ;//
last thing, create topology by making this line ad
jacent to the bendlinel2->make_body_adjacent(new_b
endline) ;// a big problem now is that we have del
eted some lines.// the problem is that if we have
a simultaneous bend, other contacts could still be
refering// to these lines we just deleted.// we h
ave to go and check that, and if true, replace poi
nters to the lines we have changed/deleted// with
valid references.// // namely, lines that areaffec
ted are the first and last lines in the left.// po
tentially references to them need to be replaced w
ith references to l1 and l3.if (l1 || l3) check_re
ferences_in_remaining_contacts(face2_processed ? c
ontact_list->next() : contact_list, // current lis
t we are working withface2_processed ? contact_lis
t : contact_list->next(), // list on the other sid
e ofthe contactfirst_line_in_left, last_line_in_le
ft, // these are old references, to be checked if
still validl1, l3 // l1 and l3 are the new referen
ces) ;// we will use the same piece of code to pro
cess both sides of the contact.// if face2 side ha
s not been processed, do it now.// however, first
we need to set some values of variables that are c
ommonly used.if (! face2_processed) {face2_process
ed = 1 ;// first, l2 should be the left line.// l2
is the real adjacent line (on the left). now it b
ecomes the right line.left->set_obj(l2) ;// now we
need to switch left and rightsides// switch lines
first_line_in_left = first_line_in_right ;first_li
ne_in_right = l2 ;// switch listsline_in_list = le
ft ;left = right ;right= line_in_list ;// store be
ndline centerline start-end pointsbendline_centerl
ine_p1 = p1 ;bendline_centerline_p2 = p2 ;goto pro
cess_one_side_of_the_contact ;}/*
ここで、コンタクトリストを削除することが出来る。*/
BM_LINKED_LIST_NODE *list, *next_list ;int lists_d
eleted = 0 ; // note, we can only delete first two
listsfor (list = contact_list ; lists_deleted <2
&& list ; list = next_list) {next_list = list->nex
t() ;// delete the listfor (line_in_list = (BM_LIN
KED_LIST_NODE *) list->get_obj() ; line_in_list ;
line_in_list = next_line_in_list) {next_line_in_li
st = line_in_list->next() ;delete line_in_list ;}d
elete list ;++lists_deleted ;}// setthe correct nu
mber of contacts left and update the pointerslong
num_contacts = (long) (*contact)->get_obj() ;if (-
-num_contacts < 1) {// if nocontacts left, erase t
he whole contacts listdelete *contact ;*contact =N
ULL ;}else {(*contact)->set_obj((BM_BASIC *) num_c
ontacts) ;(*contact)->add_after(list) ;}/* 最後
に、センタラインを形成する。方向と長さが正しいこと
を確かにする。 p1とp2は面1に関して規定される
点に注目されたい。 すなわち、p1->p2は面1の
側のコンタクトに対する方向である。*/BM_LINE center
line(bendline_centerline_p1,bendline_centerline_p
2) ;if (fabs(angle - PI) <= BM_ANGLE_TOLERANCE) {
// bendline not being bent// face1plane is the ben
dline surfaceif (face1->get_idx() > face2->get_idx
()) centerline.reverse_line() ;}else if (angle < P
I) {if (face1->get_idx() <face2->get_idx()) center
line.reverse_line() ;}else { // angle is > PIif(fa
ce1->get_idx() > face2->get_idx()) centerline.reve
rse_line() ;}new_auto_bendline->set_center_line(ce
nterline) ;// if we are building bendlines for the
3D-version of the part, // make sure 3D-version o
f the bendline is validated because most likely we
// want to UNFOLD right away.if (using_3D_versio
n) new_bendline->validate_3D_version() ;*bendline_
created= new_bendline ;return 1 ;}/* この関数の目
的は、面からなる切断された要素を持つ部分であって、
この部分が、これらの新しいベンドラインを付加する
と、接続されるようになるように最小数のベンドライン
を形成することにある。This function assumes that t
he part has thickness 0.The basic idea we usein th
is function is maximum spanning tree.We model the
part by an undirected graph, where faces are the n
odes of the graph andthere is an edge between two
nodes iff these two faces are in contact (ie. are
touching each other),the cost (or length) of the e
dge is the length of the longestcontact between th
ese two faces (ie. the length of the longest possi
blebendline between the two faces).In order to cre
ate bendlines we computea maximum spanning tree fo
r this graph and create abendline for every edge o
f the graph that is in the maximum spanning tree.T
here are two problems however :- It could be that
the part already contains some bendlines(ie. some
faces are already connected).- When we compute th
e maximum spanning tree, we can have two fringe-ed
ges that have the same length.In that case, we d
on’t want to break ties randomly, but instead cho
osean edge that would minimize the diameter of t
he spanning tree (the maximum distance between an
y two vertices of the tree).Algorithm :-----------
We will process faces one-by-one, starting from th
e first faces of the part and proceedinguntil the
last faces, and building the maximum spanning tree
along the way as we go.For every pair of faces, s
uch that at least one of the is not yet in the spa
nning tree,we keep the longest contact between the
m. When we expand the spanning tree, we choosethe
contactbetween a face in the tree and a face not i
n the tree that is the longest contactbetween any
face in the tree and a face outside. If there is a
tie, we choose an edge thatwould minimize the *//*
面(面1)を与えると、この構造はこの面と他の面の
間のコンタクトについての情報を含む。 任意の2つの
面に対して、これらの面の間にコンタクトが有るか否か
を知る必要があり、もしイエスなら、何がその長さであ
るかを知る必要がある。このデータを処理する最も簡単
な方法はそれを二次元配列として記憶することにより与
えられる。しかし、これは多くのスペースを取り、その
殆どは無駄に使われ、というのは、通常は、多くの面が
あるときは、それらの殆どはそれらの面の間で何らのコ
ンタクトも持たないことによる。 代わりに、我々は全
ての面に対してこの情報を構造のリストとして記憶する
ことになる。我々は、2つの面の間のコンタクトの長さ
が0より大きいときにのみこの記録を(すなわち、構
造)生成する。*/typedef struct CONTACT_INFO {// he
re we will keep track what is the length of the lo
ngest contact between any two faces// this is real
ly a two-dimensional arraydouble length ;// here w
e keep a pointer to the other faceBM_FACE *face2 ;
// here we will keep the longest contact for any t
wo faces// this is really a two-dimensional array
stored as a linked list of lists.BM_LINKED_LIST_NO
DE *contact ;// a pointer to the next structure in
alistCONTACT_INFO *next ;} contact_info ;/*これ
は、このファイルにおいて多くの関数により用いられる
非常に基本的な関数である。 それはコンタクトリスト
を削除する。*/static void delete_contact_info_list
(contact_info *list){contact_info *c, *c_next ;BM_
LINKED_LIST_NODE *clist, *next_clist ;BM_LINKED_LI
ST_NODE *line_in_list, *next_line_in_list ;for (c
= list ; c ;c = c_next) {c_next = c->next ;if (c->
contact) {// skip the header = num of contactsfor
(clist = (c->contact)->next() ; clist ; clist = ne
xt_clist) {next_clist = clist->next() ;// delete t
he listfor (line_in_list =(BM_LINKED_LIST_NODE *)
clist->get_obj() ; line_in_list ; line_in_list =ne
xt_line_in_list) {next_line_in_list = line_in_list
->next() ;delete line_in_list ;}delete clist ;}//
delete the headerdelete c->contact ;}delete c ;}}s
tatic void delete_contact_info_structure(contact_i
nfo *c){BM_LINKED_LIST_NODE *clist, *next_clist ;B
M_LINKED_LIST_NODE *line_in_list, *next_line_in_li
st ;if (NULL == c) return ;if (c->contact) {// ski
p the headerfor (clist = (c->contact)->next() ; cl
ist ; clist = next_clist) {next_clist = clist->nex
t() ;// delete the listfor (line_in_list = (BM_LIN
KED_LIST_NODE *) clist->get_obj() ; line_in_list ;
line_in_list = next_line_in_list) {next_line_in_l
ist = line_in_list->next() ;delete line_in_list ;}
delete clist ;}// delete the headerdelete c->conta
ct ;}delete c ;}/* この関数は2つの面の間で最良の
(すなわち、最も長い)コンタクトを計算し、格納す
る。*/static int compute_the_longest_contact_betwe
en_faces(BM_FACE & face1 /* IN */, BM_FACE & face2
/* IN */,contact_info **computed_contact_list /*
OUT */){// so far we have computed nothing*compute
d_contact_list = NULL ;BM_LINKED_LIST_NODE *contac
t_list ; // a list of all contacts between face1 a
nd face2 we will computeif (! BM_compute_all_face_
to_face_contacts(face1, face2, &contact_list)) ret
urn 0 ;double x = BM_keep_largest_contact_remove_t
he_rest(&contact_list) ;if (x < BM_PRECISION) retu
rn 1 ; // no contact between these two facescontac
t_info *c ;if (NULL == (c = new contact_info)) {//
delete contact listBM_LINKED_LIST_NODE *clist, *n
ext_clist ;BM_LINKED_LIST_NODE *line_in_list, *nex
t_line_in_list ;for (clist = contact_list->next()
; clist ; clist = next_clist) {next_clist = clist
->next() ;// delete the listfor (line_in_list = (B
M_LINKED_LIST_NODE *) clist->get_obj() ; line_in_l
ist ; line_in_list = next_line_in_list) {next_line
_in_list = line_in_list->next() ;delete line_in_li
st ;}delete clist ;}delete contact_list ;return 0
;}// initialize the structurec->contact = contact
_list ;c->next = NULL ;c->face2 = &face2 ;c->lengt
h = x ;*computed_contact_list = c ;return 1 ;}/*
この関数は現在接続された要素に新しい面を付加する。
それはまた、この新しい面と、処理されていない他の
全ての面の間の最も長いコンタクトを計算する。*/stat
ic int add_face_to_connected_component(BM_PART *pa
rt, BM_FACE *face2 /* this is the face we are addi
ng to the connected component */, long *end_id /*
an index of the last face in the connected compone
nt. this is where face2 is. */, contact_info **all
_contacts /* all contact info between face2 andoth
er outside faces will be here *//* we will compute
it and construct this list in this function */,BM
_FACE **idx_to_face_mapping){BM_FACE *current_face
;contact_info *last_clist = NULL, *cl ;// just in
case face2 has no adjacent faces outside the conn
ected componentall_contacts[*end_id] = NULL ;// in
this loop we want to compute all contacts between
face2and all other// faces not yet in any connect
ed component.for (current_face = part->get_face_li
st() ; current_face ; current_face = (BM_FACE *) c
urrent_face->next()) {if (current_face->get_user_i
d() >= 0) continue ; // current_face is in some ot
her connected component// compute the best contact
between face2 and current_faceif (! compute_the_l
ongest_contact_between_faces(*face2, *current_fac
e, &cl)) return 0 ;if (NULL == cl) continue ; // t
here is no contact between these two facesif (NULL
== last_clist) all_contacts[*end_id] = cl ;else l
ast_clist->next = cl ;last_clist= cl ;}face2->set_
user_id(*end_id) ;idx_to_face_mapping[*end_id] = f
ace2;++(*end_id) ;return 1 ;}/* これらの2つの関
数は、ユーザがトポロジーグラフにおける2つの面の間
の距離を設定し得ることを許容する。 dist btw 面は
二次元配列の上部右半部である。*/static long get_fa
ce2face_dist(unsigned char *dist_btw_faces,long nu
mber_of_faces, long dist_array_size, longj, long
i){long k ;// distance between face_i and face_i i
s zeroif (i ==j) return 0 ;// sort indecesif (j <
i) { k = i ; i = j ; j = k ; }k = number_of_faces
- i ;return dist_btw_faces[dist_array_size - ((k*
(k-1)) >> 1) + (j - i) - 1] ;}static void set_face
2face_dist(unsigned char *dist_btw_faces,long numb
er_of_faces, long dist_array_size, long j, long i,
unsigned char distance){long k ;// distance betwe
en face_i and face_i cannot be setif (i == j) retu
rn ;// sort indecesif (j < i) { k = i ; i = j; j =
k ; }k = number_of_faces - i ;dist_btw_faces[dist
_array_size - ((k*(k-1)) >> 1) + (j - i) - 1] = di
stance ;}/* この関数は接続された要素における所定
の面と他の面の間の最大距離を戻す。*/static long ge
t_largest_distance_for_face(unsigned char *dist_bt
w_faces,long number_of_faces, longdist_array_size,
long start_id, long end_id, long face_id){long j,
k ;if (NULL == dist_btw_faces) return 0 ;long cur
rent_face_to_face_distance= 0 ;for (j = start_id ;
j < end_id ; j++) {k = get_face2face_dist(dist_bt
w_faces,number_of_faces,dist_array_size,j,face_id)
;if (k > current_face_to_face_distance) current_f
ace_to_face_distance = k ;}return current_face_to_
face_distance ;}/* これは主要なAutobend関
数である。その目的は部分に対するベンドラインを自動
的に生成することにある。*/int BM_PART::auto_bend(v
oid){long i, j, k ;BM_FACE *current_face ;BM_FORMI
NG *current_forming ;BM_BENDLINE *current_bendline
;// at end of the function werelease memory. this
code for releasing memory is shared// between the
cases when this function fails, or succeeds.// the
refore, before we getto that code, we have to know
the return code.int ret_value ;// these are the t
wo faces we will be creating a bendline for (ie. b
etween these two faces).BM_FACE *face1, *face2 ;//
here we keep a list of information about contacts
between every face and other faces.// this is an
array lists.contact_info **all_contacts = NULL ;//
here we will keep track what face corresponds to
each row in face_to_face_length[] and all_contacts
[]arraysBM_FACE **idx_to_face_mapping = NULL ;// t
his (two-dimensional) array is used to store dista
nces between faces in the TOPOLOGY GRAPH.// these
distance values are used to break ties in the maxi
mum spanning treealgorithm when// two edges have t
he same length. Note that the distancebetween (i,
j) is the same as// the distance between (j,i). Th
is means that the distance matrix is a symmetric m
atrix, and we// only need to store one half (upper
right triangle) to save space.// we will use this
method of breaking ties only when the number of f
aces is less than 256.// this has two advantages :
1) the distance between any two faces is alwaysle
ss than 256,// and therefore we only need a char
(8 bits) to store thedistance values, 2) since we
only// need a char for a pair, the total this arra
y can take is 32K bytes, which is not too much mem
ory.unsigned char *dist_btw_faces = NULL ;// this
will be the size of the distance array, given some
number of faceslong dist_array_size ;// we will h
ave to create a heap because some portion of the p
art can already be connected//and we need to make
sure we don’t create any bendlines for that porti
on of the part.// we will use a heap to traverse t
hat portion of the part.long body_priority = numbe
r_of_formings + number_of_faces + number_of_bendli
nes ;// Check if there are any bodies. If no, we a
re done.if (body_priority < 1) return 1 ;// this i
s the heap we will allocate. this is used when we
add a face to the connected component// to add all
other faces connected to it as well. the problem
is that the part could already//contain some bendl
ines.DBM_HEAP *heap = NULL ;// this is the start-i
ndex(in face_to_face_length[] and all_contacts[])
arrays // of the currentconnected componentlong st
art_id = 0 ;// this is the end-index (in face_to_f
ace_length[] and all_contacts[]) arrays // of the
current connectedcomponentlong end_id = 0 ;// if T
RUE, we are starting a new connected componentint
starting_new_connected_component = 1 ;// allocate
memory forlocal variablesif (NULL == (all_contacts
= new contact_info*[number_of_faces])) goto failu
re ;if (NULL == (idx_to_face_mapping = new BM_FACE
*[number_of_faces])) goto failure ;if (NULL == (he
ap = new DBM_HEAP(0,NULL,NULL,body_priority))) got
o failure ;if (number_of_faces < 256) { // allocat
e memory for the face-face distance array only whe
n // the number of faces is not too largedist_arra
y_size = (number_of_faces*(number_of_faces- 1)) >>
1 ;if (NULL == (dist_btw_faces = new unsigned cha
r[dist_array_size])) goto failure ;}++body_priorit
y ; // just in case, we don’t wantthe priority to
go to 0 later.// initialize arraysfor (i = 0 ; i
< number_of_faces ; i++) {all_contacts[i] = NULL ;
idx_to_face_mapping[i] = NULL ;}// initially mark
all faces as not processedfor (i = 0, current_face
= first_face ; current_face ; current_face = (BM_F
ACE *) current_face->next()) {current_face->this_b
ody_already_processed = 0 ;// this will tell us wh
ether this face has been already processed.// if y
es, this id isthe index in face_to_face_length[] a
nd all_contacts[] arrays.current_face->set_user_id
(-1) ;}/* 先ず、面の現在接続された要素の最大スパ
ンツリーを拡大することを試みる。*/// these two var
iables are used in tie-breakinglong best_face_to_f
ace_distance, current_face_to_face_distance ;// th
isis the length of the best contact so far (ie. th
e longest contact)double best_length ;// this is a
pointer to the best contact_info structure found
so farcontact_info *best_cntct ;expand_spanning_tr
ee :// first, check if all faces have been process
ed// end_id is where we will put the next face we
add to the connected componentif (end_id >= number
_of_faces)goto done ;contact_info *cntct, *cntct_n
ext, *cntct_prev ;best_length =-1.0 ;best_face_to_
face_distance = 999999 ; // a really large number/
/ in this loop we check all faces already in the c
onnected component and try// to find a face that h
as the largest contact between itself and an adjac
ent face outside the// current connected componen
t.for (i = start_id; i < end_id ; i++) {// in this
loop we are checking for a largest contact betwee
n the current face// in the connected component an
d all of itsadjacent faces outside the connected c
omponent.cntct_prev = NULL ;for (cntct = all_conta
cts[i] ; cntct ; cntct = cntct_next) {cntct_next =
cntct->next ;// check if this adjacent face is al
ready processedif ((cntct->face2)->get_user_id() >
= 0) {// this means that face2 has already been ad
ded to the connected component// and we don’t rea
lly need the contact info stored in this structure
any more.// we will delete it.// this willsome ti
me in the future and free up some space.delete_con
tact_info_structure(cntct) ;if (NULL == cntct_pre
v) all_contacts[i] = cntct_next ;elsecntct_prev->n
ext = cntct_next ;continue ;}// ok, this adjacent
face notprocessed. // check if it is better than t
he previously known best.// first check if there i
s a tie, and if we have allocated a face-face dist
ance array// then use the face-to-face distances t
o break the tieif (fabs(cntct->length - best_lengt
h) <= distance_tolerance && dist_btw_faces) {// if
tie-breaking is used, compute the largest distanc
e for this face (ie. face1)current_face_to_face_di
stance = get_largest_distance_for_face(dist_btw_fa
ces,number_of_faces, dist_array_size, start_id, en
d_id, i) ;//prefer the one with the smaller larges
t distanceif (current_face_to_face_distance < best
_face_to_face_distance) {face1 = idx_to_face_mappi
ng[i];face2 = cntct->face2 ;best_length = cntct->l
ength ;best_cntct = cntct;best_face_to_face_distan
ce = current_face_to_face_distance ;}}// take si
mply the one that is bett
erelse if (cntct−>length
> best_length) {face1= id
x_to_face_mapping[i] ;fac
e2 = cntct−>face2 ;best_l
ength = cntct−>length ;be
st_cntct = cntct ;// if t
ie−breaking is used, comp
ute the largest distance
for this face (ie. face1)
best_face_to_face_distanc
e = current_face_to_face_
distance = get_largest_di
stance_for_face(dist_btw_
faces,number_of_faces, di
st_array_size, start_id,
end_id, i) ;}cntct_prev =
cntct ;}}// at the end o
f this loop,// face1, fac
e2, best_cntct should hav
ecorrect values, if best_
length > 0.0, // that mea
ns we can expand the tre
e./* 我々がスパンツリーを拡大出来るか否かをチ
ェックする。 我々が接続要素を拡大することに戻るま
でまでのこの点に対して、我々は単に面2を用いつつあ
り、すなわち、我々は面1を必要としていない。 唯一
の場合は、我々が新しいベンドラインを生成するときで
あるが、我々はコンタクトリストから面idを抽出する
ことが出来る。*/if (best_length < distance_toleran
ce) {// looks like we cannot expand the spanning t
ree// none of the faces in the current connected c
omponent has any adjacent faces// outside the conn
ectedcomponent.// most likely this connected compo
nent is finished and, sincethere must be still fac
es left,// there is more than one connected compon
ent.// // next we try to find the first face in th
e next connected component so that we// can contin
ue and create all bendlines for this new conencted
component.for (current_face = first_face ; curren
t_face ; current_face = (BM_FACE *) current_face->
next()) {if (current_face->get_user_id() < 0) brea
k ;}if (NULL == current_face) goto done ; // we sh
ould never get here// first, we can delete all con
tact information about the current (now old) conne
cted componentfor (i = start_id ; i < end_id ; i+
+){delete_contact_info_list(all_contacts[i]) ;all_
contacts[i] = NULL ;}//here we will be starting a
new connected componentstarting_new_connected_comp
onent = 1 ;start_id = end_id ;// we will skip the
bendline creationnormally needed when adding a fac
e to a connected componentface2 = current_face ;}e
lse {// ok, we are in the middle of a conencted co
mponentstarting_new_connected_component = 0 ;// cr
eate a bendline between face1 and face2// notice :
we might have to create a simultaneous bendlong n
um_contacts = (long) (best_cntct->contact)->get_ob
j() ;BM_BEND_PROPERTY_SIMULTANEOUS *sim_bend = NUL
L ;if (num_contacts > 1) {sim_bend = new BM_BEND_P
ROPERTY_SIMULTANEOUS(this, num_contacts, NULL) ;if
(NULL == sim_bend)goto failure ;}BM_BENDLINE *new
_bendline ;for (long contacts_done = 0 ;contacts_d
one < num_contacts ; contacts_done++) {if (! BM_cr
eate_bendline(*this, &(best_cntct->contact),&new_b
endline)) goto failure ;// note that this function
will delete one contact for which a bendline was
created as wellif (num_contacts > 1) {// add this
bendline to the simultaneouspropertynew_bendline->
add_property(sim_bend) ;}}}// store "1 + the curre
nt index of the last connected-component-face"j =
end_id ;// we could add face2 to the connected com
ponent right away, but we could save some time by/
/ first checking if face2 has any other stuff (out
side this connected component) connected to it.//
if yes, we will be adding that stuffto this connec
ted component right away,// but in that case there
is no need for us to compute contacts between fac
e2 and that other// stuff in the first place.// Th
erefore, we will just remember that face2 should b
eadded, will process adjacent stuff first,// and t
hen will actually add face2 (and some more stuff m
ay-be) to the connected component.// // Note: we w
ill actully put face2 in the heap, and when we rem
ove it from theheap,// we will remember to add it
to the connected component/* ここで,我々は、この
面(すなわち、面2)がそれに接続された他の任意の3
D体を有するか否かをチェックする必要がある。 も
し、イエスなら、我々は、面2に接続された全ての面を
現在接続された要素に付加するために、これらの接続を
追求する必要がある。*/heap->empty() ;if (! heap->i
nsert(body_priority--, (long) face2)) goto failure
;face2->this_body_already_processed = 1 ;// check
if face2 has a parent face or not. if not, set th
e id in local arrayequal to // face2’s own id. th
is way we know it has no parent face.// // IMPORTA
NT : normally user_id of every face is a pointer t
o its index in the contact-info array.// temporari
ly we will use this information tokeep track which
of the faces already processed// is the parent-fa
ce (inthe topology graph) of every new face added
to the connected component.// this information wil
l be used later to compute distances in the faceto
pology graph.// the following loop (controlled by
the heap) stores allfaces not yet in the connected
// component, but connected to this face2.// later
when the actualy adding of new faces to the conen
cted component is done,// we overwrite user_id wit
h the correct value.if (! starting_new_connected_c
omponent) face2->set_user_id(face1->get_user_id())
;elseface2->set_user_id(end_id) ;// in the follow
ing while loop we will use this_body_already_proce
ssed member variable to keep// track whether a var
ible is processed; not processed, but sitting in t
he heap; or unseen yet.// 0 - unseen body// 1 - bo
dy in the heap// 2 - body already finished//also,
in this while loop we will be using the user_defin
ed_id of every3D-body to keep// track of the paren
t face of every 3D-body we traverse.// this has tw
o benefits : 1) we will remember the parent face o
f everyface and can compute// distances between fa
ces later, and // 2) this waywhen faces are later
added to the spanning tree, distance between someo
ther // face and this face will not be computed, s
ince it is not necessary.BM_3D_BODY *body ;BM_TOPO
LOGY_RECORD *toplgy ;while (heap->get_size() > 0)
{if (! heap->remove(&i,(long *) &body)) goto failu
re ;// a safetycheckif (NULL == body) continue ;//
check if this body is already finishedif (body->t
his_body_already_processed > 1) continue ;// get b
ody topologytoplgy = body->get_adj_list() ;if (NUL
L == toplgy) continue ;// check if the body is a f
ace. if yes, memorize.if (body->is(BM_ENTITY_TYPE_
FACE)) {face2 = (BM_FACE *) body ;// memorize to a
dd this face to the connected component lateridx_t
o_face_mapping[j++] = face2 ;}body->this_body_alre
ady_processed = 2 ;// process all adjacent bodiesf
or (current_face =(BM_FACE *) toplgy->get_first_fa
ce() ; current_face ; current_face = (BM_FACE *) t
oplgy->get_next_face()) {// make sure that we do
n’t processfaces twiceif (current_face->this_body
_already_processed) continue ;if (! heap->insert(b
ody_priority--,(long) current_face)) goto failure
;current_face->this_body_already_processed = 1 ;/
/ make sure we memorize the parent face index in t
he local spanning tree arraycurrent_face->set_user
_id(body->get_user_id()) ;}for (current_forming =
(BM_FORMING *) toplgy->get_first_forming() ; curre
nt_forming ; current_forming = (BM_FORMING *)toplg
y->get_next_forming()) {if (current_forming->this_
body_already_processed) continue ;if (! heap->inse
rt(body_priority--,(long) current_forming)) goto f
ailure ;current_forming->this_body_already_process
ed = 1 ;//make sure we memorize the parent face in
dex in the local spanning treearrayif (body->is(BM
_ENTITY_TYPE_FACE)) current_forming->set_user_id(j
-1) ;else current_forming->set_user_id(body->get_u
ser_id()) ;}for (current_bendline = (BM_BENDLINE
*) toplgy->get_first_bendline() ; current_bendline
; current_bendline = (BM_BENDLINE *) toplgy->get_
next_bendline()) {if (current_bendline->this_body_
already_processed) continue ;if (! heap->insert(bo
dy_priority--,(long) current_bendline)) goto failu
re ;current_bendline->this_body_already_processed
= 1 ;// make sure we memorize the parent face inde
x in the local spanning tree arrayif (body->is(BM_
ENTITY_TYPE_FACE)) current_bendline->set_user_id(j
-1) ;else current_bendline->set_user_id(body->get_
user_id()) ;}}// finally we need to compute contac
ts between this face and all other faces, that we
postponed// and add them to the connected componen
t.long face1_id ;for (i = end_id ; i < j ; i++) {f
ace2 = idx_to_face_mapping[i] ;// first, compute d
istances in the TOPOLOGY GRAPH between this face
(ie. face2) // and all faces previouslyin the conn
ected component.// we will use the parent face id
in the local spanning tree array for that.face1_id
= face2->get_user_id() ; // note: face1_id is the
parent id of face2 (ie. there is a bendline betwe
en face1_id and face2 that we count).if (dist_btw_
faces && face1_id != i) {// if equal -> face2 has
no parents, // ie. a new connected component (must
be start_id = end_id).// actually, it must be her
e true that face1_id < ifor (k = start_id ; k < en
d_id ; k++) {set_face2face_dist(dist_btw_faces, nu
mber_of_faces, dist_array_size, k, i, get_face2fac
e_dist(dist_btw_faces,number_of_faces,dist_array_s
ize,k,face1_id) + 1) ;}}// else ifequal, it must b
e that i == ’the end_id’ in the beginning of thi
s for-loop.// note that the next function (add_fac
e_to_connected_component(...)) will increment end_
id.if (! add_face_to_connected_component(this, fac
e2, &end_id, all_contacts, idx_to_face_mapping)) g
oto failure ;}// ok, the current connected compone
nt has no connections to the outside.// tryto expa
nd the spanning tree.goto expand_spanning_tree ;do
ne :ret_value =1 ;goto release_memory_and_return ;
failure :ret_value = 0 ;release_memory_and_return
:// free memory if necessaryfor (i = 0 ; i < numb
er_of_faces ; i++) {delete_contact_info_list(all_c
ontacts[i]) ;}if (all_contacts)delete [] all_conta
cts ;if (idx_to_face_mapping) delete [] idx_to_fac
e_mapping ;if (heap) delete heap ;if (dist_btw_fac
es) delete [] dist_btw_faces ;return ret_value ;} 付録D 2dクリーアップ関数の例 #include <stdio.h>#include <stdlib.h> #include <
math.h>#include <memory.h>#include <string.h>/* F
unction名称:1 control levelTestFindBoundaryTestFi
ndDrawingSheetControlTestFindViewsControlTestFindB
oundaryControlTestFindArrowControlTestFindOneSideO
penControlTestFindOneSideOpen2ControlTestFindCente
rLineControlTestFindOneSideOpenConnectControlTestF
indSameColorControlTestFindSelectSingleControlTest
UnselectSingleControlTestClearControlTestClearKeep
FlagsControlTestDeleteControlTestUndoControlTestUn
doPreControlTestDeleteViewsControlTestSetUndoFlagV
iewsControl TestBackColorControl2 applicate
levelF2dCleanUpFindDrawingSheetF2dCleanUpFindView
sF2dCleanUpFindSameColorEntityF2dCleanUpFindCenter
LineEntityF2dCleanUpFindOnesideOpenConnectEntityF2
dCleanUpFindOneSideOpenEntity2F2dCleanUpClearDrawi
ngEntityF2dCleanUpDeleteDrawingEntityF2dCleanUpDel
eteViewsF2dCleanUpUndoF2dCleanUpUndoPreF2dCleanUpP
ickUpAllOneSideOpenEntityF2dCleanUpPickUpAllArcEnt
ityF2dCleanUpFindLongestEntityF2dCleanUpFindGroupF
2dCleanUpCheckEntityExistF2dCleanUpFindViewsRelati
onF2dCleanUpFindRelativeViewsF2dCleanUpFindOutSide
LoopF2dCleanUpFindInSideEntityF2dCleanUpFindOneSid
eOpenEntityF2dCleanUpFindGroupMinXF2dCleanUpFindOu
tNextEntityF2dCleanUpFindOnesideOpenConnectEntityN
extF2dCleanUpFindArrowF2dCleanUpFindArrowOneSideOp
enEntityF2dCleanUpFindArrowEndEntityF2dCleanUpChec
kStartEndEntityF2dCleanUpComputeCenterLineAngleF2d
CleanUpFindArrowCenterEntityF2dCleanUpChangeArrowV
ertexFlagF2dCleanUpArcAngleF2dCleanUpLineAngleF2dC
leanUpLineLengthF2dCleanUpChangeColorF2dCleanUpCha
ngeDrawingColorF2dCleanUpChangeChildrenFlagF2dClea
nUpChangeDrawingFlagF2dCleanUpClearDrawingKeepFlag
sF2dVectorF2dVectorUnitF2dDistancePointLine*/#ifde
f VELLUM#include "ck_cdlc.h"// VCI_VLM.DLL include
files#include "system.h"// CadKey emulation files
#include "vlm_ck.h"#endif#ifdef CKWIN#include "ck_
cdlc.h"#include "ck_cde.h"#include <ckcdll.h>#incl
ude <ck_attr.h>#define ck_setattr2ck_setattr#endif
#ifdef AUTOCAD#include <ACAD_VCI.H>#endif// 2d3d f
iles#include "view3D.h"//#include "Proto.h" // in
cludes prototypes of all functions.#define VLM_ID_
2DTO3D32#define Regular 0#define ThreeViews 1//
#define SECURITY// Some definitions//#undef DEBUG/
/// Following is the definition of the global vari
ables//#ifdefCKWINint TopViewNum, IsometricViewNu
m;// These variables are used onlywith CADKEY whe
n changing to TopView or Isometric view.#endif// b
y Ji Feb.14,1996double F2dCleanUpTolerance = 0.01;
//undo flag ( set a No. for views )extern int F
2dCleanUpExcutedNo = 0;extern int WorkLevel, Tr
imLevel, VW3DLevel; // Thr
ee layers are useD: WorkLevel is used to highlight
views and display temporary drawings.//TrimLevel
is used to store the trimmed drawing.//VW3DLevel i
s used to store the projected 3D drawing.// these
are the four drawings used.extern struct drawing i
nput_drawing, projected_drawing, trim_drawing, fin
al_drawing; // Three drawing structures are const
ructed:// InputDrawing is c
onstructed from the input entities //
taken from from all the l
ayers that are turned on.//TrimmedDrawing is const
ructed from the trimmed entities. Once the//Trimme
d Drawing is constructed, the Input Drawing is not
used.// ProjectedDrawing i
s constructed from the entities projected in a sin
gle flange.//If ’DoneProjection’ is selected, th
en these entities are saved on VW3DLevel.//
If ’UndoProjection’ is selecte
d, these entities are discarded.extern struct plan
ar_flange *AllFlanges;// this is a pointer to the
list of flangesextern char Messages[MaxMessages][8
0];// This array stores the messages read from the
message file.extern int message_flag;// This vari
able is assigned to ’1’ if the messages were rea
d successfully from the message file.// Otherwise,
it isset to ’0’.extern int number_of_views;// T
his vairbale stores the number of disconnected com
ponents discovered in the *input* drawing.externin
t number_of_entities;// This variable stores the n
umber of entities loaded for the current drawing.e
xtern int number_trimmed_entities;// Thisvariable
stores the number of entities loaded for the trimm
ed drawing.extern int n_edges;// This variable sto
res the number of connecting edgesbetween the trim
med entities.extern double MatchTolerance, Connect
ivityTolerance;// ConnectivityTolerance is used to
determine whether two entities are close enough t
o be considered connected.// Matching Tolerance is
used to determine whether two entities on differen
t views are matching.extern double
ArrowHeadAngle, ArrowHead
Length;// These variuable
s definethe structure of
an arrow for the 2D clean
up funciton.extern doubl
e view_boundaries[MaxNumb
erOfViews+1][4];// This a
rray is used to store the
bounding box of each conn
ected component of the in
put drawing.// once the views a
re detected, several components might be mapped to
a single view.extern int type_of_view[MaxNumbe
rOfViews+1];// This array mapsevery view to its ty
pe, namely to one of Top, Left, Right, Front, Back
view.// Its content is valid only after ’DoneView
s’ was called.//int view_rotation_flag[MaxNumberO
fViews+1];// This array is used for markingrotated
views. // If the i’th element is ’1’ then the
view is rotated.//extern static char original_lvma
sk[32] ;// At the beginning we save the (on,off) s
tatus of all the layers.//extern static char twoDm
ask[32] ;//extern static char threeDmask[32] ;// T
he masks used to display the 2Dand 3D models.//ext
ern static int original_worklevel ;// Specifies th
eoriginal work level of the user when fold is star
ted// static int original_setup_available = 0 ; //
true iff original (layer) setup is available, ie.
can be restoredextern int dialog_open_flag = 0;//
This variable isa flag which specifies whether so
me dialog boxes were opened.extern intAtrimLineTyp
eSwitch, AtrimColorSwitch, AtrimWidthSwitch, Atrim
CenterLineSwitch;// these switches are used to spe
cify in which cases AutoTrim will trim lines.//str
uct node *F2dCleanUpInputEntity(char *, struct dra
wing *);//static int select_flange(struct resbuf *
rb);typedefstruct Vector{doublex,y,z;};extern doub
le BBminX,BBmaxX,BBminY,BBmaxY,BBminZ,BBmaxZ;/*関
数: 名称: TestFindBoundaryDescription: It is a m
anual function. When user selected a boundary’s e
ntity of a view, the function would findall of the
connected entities for the view.戻り値:< 0: Erro
r= 0: No proccess> 0: Completed successfully; the
Number is the counter of found entities.パラメー
タ:副関数:int F2dCleanUpFindArrowlook for arrow
type entityint F2dCleanUpFindArrowEndEntityfind ar
row end lineint F2dCleanUpFindArrowCenterEntityfin
d arrow center lineint F2dCleanUpFindArrowOneSideO
penEntityfind one side open entity for arrow typei
nt F2dCleanUpComputeCenterLineAnglecompute center
line angleint F2dCleanUpCheckStartEndEntitycheck s
tart and end entitiesint F2dCleanUpFindOutSideLoop
look for out sideloop entitiesint F2dCleanUpFindOu
tNextEntitylook for connected entity with out side
loop entitiesstruct node *F2dCleanUpFindGroupMinX
look for minimum X-value for a entities groupstruc
t node_list *F2dCleanUpFindGrouplook for a group e
ntities connected with input entitystruct node *F2
dCleanUpInputEntity ( old function )look for a sel
ected entity on screenintF2dCleanUpLineAnglecomput
e a line type entity’s angle int F2dCleanUpArcAng
lecompute a arc type entity’s angle.int F2dCleanU
pChangeChildrenFlagchange entity’s children flags
int F2dCleanUpChangeArrowVertexFlagchangearrow top
vertex’s flags and set arrow center line coordin
atesint F2dCleanUpChangeColorchange entity’s colo
rint F2dCleanUpFindOneSideOpenEntitylook for one s
ide open entities and they are vertical with arrow
typeentities double F2dCleanUpLineLengthcompute l
ine type entity’s length=========================
========================================*/intTestF
indBoundary(){//external functionsint F2dCleanUpFi
ndArrow();int F2dCleanUpChangeColor();int F2dClean
UpFindOneSideOpenEntity();int F2dCleanUpFindOutSid
eLoop();int F2dCleanUpChangeDrawingColor();struct
node *F2dCleanUpInputEntity();struct node *F2dClea
nUpFindGroupMinX();struct node_list *F2dCleanUpFin
dGroup();//entities counter and flagsint count =
0,assistant_line_flag = 0;//link list and temp lis
tstruct node_list*Entities_change_color_list1; //s
elected entity and temp entitiesstruct node *enti
ty,*MinXvalueEntity;//Begin//---------------------
-------------//Step_1://check the number of entite
s// get count of all entities// if an error occur
red, exit immidiately. if (number_of_entities<
0) return -1;for( ;; ){//------------------------
---------//Step_2:select one entityentity= F2dClea
nUpInputEntity( "Select a Boundary Entity for a vi
ew",&trim_drawing);if ( entity == 0 )return0;if (
entity->flags != 0 )continue;//-------------------
--------------//Step_3: find a connected entities
groupEntities_change_color_list1 = F2dCleanUpFindG
roup( entity, &count );if ( Entities_change_color_
list1 == 0 )return0;//----------------------------
-----//Step_4: find arrow lineF2dCleanUpFindArrow
( Entities_change_color_list1 );//----------------
-----------------//Step_5:find one side open entit
iesassistant_line_flag = F2dCleanUpFindOneSideOpen
Entity( Entities_change_color_list1 );//----------
-----------------------//Step_6:find outside loop
entities without assistant entities//check a flag
for outsideloop processif ( count < 1 )continue;Mi
nXvalueEntity = F2dCleanUpFindGroupMinX(Entities_c
hange_color_list1);if ( MinXvalueEntity == 0 )cont
inue;//---------------------------------//Step_7:/
/find outside loop entitiesF2dCleanUpFindOutSideLo
op( MinXvalueEntity );//--------------------------
-------//Step_X://change color to Magenta for a se
lected boundary //turn off input levels ck_l
evels(CK_OFF,1,255);#ifdef CKWINF2dCleanUpChangeCo
lor(Entities_change_color_list1);#endif#ifdef VELL
UMF2dCleanUpChangeDrawingColor(&trim_drawing);#end
if//clear a flag for outside loop processassistant
_line_flag = 0;// turn ON the level used to store
the trimmed entities. ck_levels(CK_ON,TrimLeve
l, TrimLevel);#ifdef CKWINif (*SwitchRedraw == 1)c
k_redraw( CK_PRIME_VP );#endif}return count;}/*===
==================================================
============関数: 名称: F2dCleanUpFindGroup記
述: look for a group entities connected with inpu
t entity 戻り値:= 0: Completed successfully;パラ
メータ:入力: Entity: a entity出力:NodeList: a n
ode list connected with input entity =============
==================================================
==*/struct node_list *F2dCleanUpFindGroup(struct n
ode *Entity, int *Cnt ){//entities counter and fla
gsint count = 0;//link list and temp liststruct no
de_list*EntitiesList1,*Out_temp_list,*temp_list, *
temp_list1,*open_temp_list, *open_list; //selected
entity and temp entitiesstruct node *Next_entity;
//initializeEntitiesList1 =( struct node_list * )
calloc ( 1, sizeof ( struct node_list ));open_list
=( struct node_list * ) calloc ( 1, sizeof ( stru
ct node_list ));//set a flag for the boundary enti
tycount = 0;//set pointer to first entityopen_list
->car = Entity;//set a open flagto the nodeopen_li
st->car->flags = 1;//set link addressopen_list->cd
r = NULL;//set the pointer to output node listEnti
tiesList1->car = open_list->car;EntitiesList1->cdr
= open_list->cdr;//------------------------------
---//Step_3://find connected entitiesfor( temp_lis
t = open_list; ( temp_list //&&(temp_list
->cdr != 0) ); ) {if ( temp_list->car == N
ULL )break;//get a pointer from open listNext_enti
ty = temp_list->car;//set a closed flag to the nod
eNext_entity->flags = 2;//close the node ( delete
the node from open list )open_list = open_list->cd
r;//count the number of entitiescount++;// look fo
r first connected entity whose flags=0.for (temp_l
ist1=Next_entity->connected_nodes; // temp_lis
t1 && temp_list1->car->flags==1; ( temp_list1
!=0 && temp_list1->car!=0); temp_list
1=temp_list1->cdr){ if ( temp_list1->car == NUL
L )break; // if found an unmarked connected entity
if (temp_list1 && temp_list1->car->flags==0&& Enti
ty->line_type == temp_list1->car->line_type&& Enti
ty->color == temp_list1->car->color&& Entity->is_t
hickness == temp_list1->car->is_thickness ) {//
allocate memory for open list elementopen_temp_lis
t = ( struct node_list * ) calloc ( 1, sizeof ( st
ruct node_list));// allocate memory for output nod
e list elementOut_temp_list = ( struct node_list *
) calloc ( 1, sizeof ( struct node_list ));// add
this entity to the open listopen_temp_list->car =
temp_list1->car;// add thisentity to the output n
ode list Out_temp_list->car = temp_list1->car;//se
t a open flagto the nodeopen_temp_list->car->flags
= 1; // connect to the open listopen_temp_list->c
dr = open_list;// move the pointer of open list to
the topopen_list = open_temp_list;// connect to t
he output node listOut_temp_list->cdr = EntitiesLi
st1;// move the pointer of output nodelist to the
topEntitiesList1 = Out_temp_list;}}// assign value
to the loop variabletemp_list = open_list;}*Cnt =
count;return EntitiesList1; }/*==================
===============================================
関数: 名称: F2dCleanUpArcAngle 記述:アー
ク形エンティティの角度を計算する。 戻り値:Rotate
VertexFlag:方向フラグ =1:vertex
1は回転ポイントである。 =2:vert
ex2は回転ポイントである。 パラメータ:
入力: 1 OriginVertex:回転頂点
2 Entity:アーク形エンティティ 出
力:1 EntityAngle:方向角度(ラジアン)
2 EntityAngleAnother: 他のサイド方向角度=======
==================================================
=======*/int F2dCleanUpArcAngle(//inputstructplana
r_vertex *OriginVertex,structnode *Entity,//output
double*EntityAngle,double*EntityAngleAnother){//re
turn value intRotateVertexFlag=0;//length and angl
edoubleTolerance = 0.0;//set toleranceTolerance =
F2dCleanUpTolerance;//select connected side of ent
ityif ( Entity->vertex1 == OriginVertex ){//get ar
c start-angle//( direction : from circle-center to
start-point )RotateVertexFlag= 1;*EntityAngle =
( Entity->AngBegin ) * pi / 180.0;//change angleto
oppsite direction//( direction : from start-point
to circle-center )*EntityAngle = *EntityAngle + p
i;//check angle if ( *EntityAngle >(2.0*pi)) *Enti
tyAngle = *EntityAngle - 2.0*pi;if ( fabs(*EntityA
ngle-2.0*pi) <Tolerance ) *EntityAngle = 0.0;//com
pute tangentline angle for the arcend-angle//( dir
ection : from start-point to end-point )*EntityAng
le = *EntityAngle + 1.5 * pi;//check angle if ( *E
ntityAngle >(2.0*pi)) *EntityAngle = *EntityAngle
- 2.0*pi;if ( fabs(*EntityAngle-2.0*pi) < Toleranc
e ) *EntityAngle = 0.0;//get another side data//ge
t arc start-angle//( direction : from circle-cente
r to end-point )*EntityAngleAnother = ( Entity->An
gEnd ) * pi / 180.0;//change angle to oppsite dire
ction//( direction : from end-point to circle-cent
er )*EntityAngleAnother = *EntityAngleAnother + p
i;//check angle if ( *EntityAngleAnother > 2.0*pi
)*EntityAngleAnother = *EntityAngleAnother - 2.0
* pi;elseif ( fabs(*EntityAngleAnother-2.0*pi) < T
olerance ) *EntityAngleAnother = 0.0;//compute tan
gentline angle for the arc end-angle//( direction
: from end-point to start-point )*EntityAngleAnot
her = *EntityAngleAnother + 0.5 * pi;//check angle
if ( *EntityAngleAnother > 2.0*pi )*EntityAngleAno
ther = *EntityAngleAnother - 2.0 * pi;else if ( fa
bs(*EntityAngleAnother-2.0*pi) < Tolerance )*Entit
yAngleAnother = 0.0;}else{//get arc end-angle//( d
irection : fromcircle-center to end-point )RotateV
ertexFlag= 2;*EntityAngle= ( Entity->AngEnd ) * pi
/ 180.0;//change angle to oppsite direction//( di
rection: from end-point to circle-center )*EntityA
ngle = *EntityAngle + pi;if (*EntityAngle > 2.0*pi
) *EntityAngle = *EntityAngle - 2.0*pi;if ( fabs
(*EntityAngle - 2.0*pi) < Tolerance )*EntityAngle
= 0.0;//compute tangentline angle for the arc end-
angle//( direction : from end-point to start-point
)*EntityAngle = *EntityAngle + 0.5 * pi;if ( *Ent
ityAngle > 2.0*pi) *EntityAngle = *EntityAngle -
2.0*pi;if ( fabs(*EntityAngle - 2.0*pi)< Tolerance
)*EntityAngle = 0.0;//get another side data//get
arc start-angle//( direction : from circle-center
to start-point )*EntityAngleAnother = ( Entity->An
gBegin ) * pi / 180.0;//change angle to oppsite di
rection//( direction : from start-point to circle-
center )*EntityAngleAnother = *EntityAngleAnother
+ pi;if ( *EntityAngleAnother > 2.0*pi )*EntityAng
leAnother = *EntityAngleAnother - 2.0 * pi;if ( fa
bs(*EntityAngleAnother - 2.0*pi ) < Tolerance )*En
tityAngleAnother = 0.0;//compute tangentline angle
for the arc start-angle//( direction : from start
-point to end-point )*EntityAngleAnother = *Entity
AngleAnother + 1.5 * pi;if ( *EntityAngleAnother >
2.0*pi )*EntityAngleAnother = *EntityAngleAnother
- 2.0 *pi;if ( fabs(*EntityAngleAnother - 2.0*pi
) < Tolerance )*EntityAngleAnother = 0.0;}//the e
nd of this functionreturn RotateVertexFlag;}/*====
==================================================
===========関数: 名称:F2dCleanUpLineAngle記述:
It is a function for control how to compute aline
typeentity’s angle. 戻り値:RotateVertexFlag: dir
ection flag=1: vertex1 is rotate point=2: vertex2
is rotate pointパラメータ:入力: 1 OriginVertex:
rotationary vertex2 Entity: line type entity 出
力:1 EntityAngle: direction angle ( radian )2 Ent
ityAngleAnother: another side direction angle=====
==================================================
=========*/int F2dCleanUpLineAngle(//inputstructpl
anar_vertex *OriginVertex,structnode *Entity,//out
putdouble*EntityAngle,double*EntityAngleAnother){/
/return value intRotateVertexFlag=0;//selected ent
ity and temp entitiesstruct planar_vertex*VertexTe
mp,*VertexAnotherTemp;//length and angledoublediff
_x = 0.0,diff_y = 0.0,Tolerance = 0.0;//set tolera
nceTolerance = F2dCleanUpTolerance;//select connec
ted side of entityif ( Entity->vertex1== OriginVer
tex ){//get vertex1->vertex2 RotateVertexFlag= 1;V
ertexTemp=Entity->vertex1;VertexAnotherTemp= Entit
y->vertex2;}else{ //get vertex2->vertex1 RotateVe
rtexFlag= 2;VertexTemp = Entity->vertex2;VertexAno
therTemp= Entity->vertex1;}//compute angleif ( fab
s( VertexTemp->X - VertexAnotherTemp->X ) < Tolera
nce ){//angle = 0.5 * piif ( VertexTemp->Y < Verte
xAnotherTemp->Y )*EntityAngle = 0.5 * pi;//angle =
1.5 * pielse*EntityAngle = 1.5 * pi;}else{ //-pi
< angle < pidiff_y = VertexAnotherTemp->Y- VertexT
emp->Y;if ( fabs( diff_y ) > Tolerance ){diff_x =
VertexAnotherTemp->X - VertexTemp->X; *EntityAng
le = atan2( diff_y, diff_x );//-pi< angle < 0.0if
( *EntityAngle < 0.0 ) *EntityAngle = *EntityAngle
+ 2.0*pi; }else{ //angle = 0.0or piif ( VertexAn
otherTemp->X > VertexTemp->X )*EntityAngle = 0.0;e
lse*EntityAngle = pi;}}if ( fabs(*EntityAngle - 2.
0*pi) < Tolerance ) *EntityAngle = 0.0;//get anoth
er side angle*EntityAngleAnother = *EntityAngle +
pi;// check angleif ( *EntityAngleAnother> ( 2.0
* pi ) ){*EntityAngleAnother = *EntityAngleAnother
- 2.0 * pi;}if ( fabs(*EntityAngleAnother - 2.0*p
i) < Tolerance ) {*EntityAngleAnother = 0.0;}//the
end of this functionreturn RotateVertexFlag;}/*==
==================================================
============= 関数: 名称:F2dCleanUpChangeColor
記述: エンティティの色を変更する関数。戻り
値: =0:成功裏に完了 パラメータ:
入力:Entities_change_color_list :変更され
た色であるノードリスト============================
=====================================*/int F2dClea
nUpChangeColor(struct node_list *Entities_change_c
olor_list){//link list and temp liststruct node_li
st*Color_temp_list;//selected entity and temp enti
tiesstruct node *Next_entity;//entity’s specifit
ysCK_ENTATTattr;//specificity of entitiesint Count
Prompt = 0;charmessage[64];#ifdef VELLUMCountPromp
t++;sprintf( message,"Start Change Color Entity %
d", CountPrompt );ck_prompt( message ); #endif#if
def VELLUM // clear views highlighting ck_er
ase_level("VW_2D");// ck_erase_level("VW_TRI
M");#endif//check all of entities on the listfor(
Color_temp_list=Entities_change_color_list; Color
_temp_list; Color_temp_list = Color_temp_list->cd
r){if ( Color_temp_list->car == NULL )break;Next_e
ntity = Color_temp_list->car;switch ( Next_entity-
>flags ){case 1:attr.color = CK_GREEN;ck_setattr(
Next_entity->id, CK_COLOR, NULL, &attr );break;cas
e 3:attr.color =CK_GRAY;ck_setattr( Next_entity->i
d, CK_COLOR, NULL, &attr );break;case4:attr.color
= CK_MAGENTA;ck_setattr( Next_entity->id, CK_COLO
R, NULL, &attr );break;}}#ifdef VELLUMCountPrompt+
+;sprintf( message,"Finished change color Entity %
d", CountPrompt );ck_prompt( message ); #endifret
urn0;}/*==========================================
=======================関数: 名称: F2dClea
nUpChangeDrawingColor 記述: エンティティの
色を変更する関数。 復帰値: =0:成功裏に完
了; パラメータ:入力: 1 In drawin
g:図中で1:変更された色である図==================
===============================================*/i
ntF2dCleanUpChangeDrawingColor(struct drawing *In_
drawing){//extern functionsvoid draw_entity();//se
lected entity and temp entitiesstruct node *entit
y;int CountPrompt = 0;charmessage[64];//entity’s
specifitysCK_ENTATTattr;//specificity of entities#
ifdef VELLUM // clear views highlighting ck_
erase_level("VW_2D");// ck_erase_level("VW_TRI
M");CountPrompt++;sprintf( message,"Start Change C
olor Sheet Entity %d", CountPrompt);ck_prompt( mes
sage ); #endif//check all of entities on the list
for( entity=In_drawing->objects; entity; entity
= entity->next){switch ( entity->flags ){#ifdef VE
LLUMcase 0:draw_entity( entity, entity->color );br
eak;case 1:draw_entity( entity, CK_GREEN );break;c
ase 2:draw_entity( entity, entity->color );break;c
ase 3:draw_entity( entity, CK_BLUE );break;case 4:
draw_entity( entity, CK_MAGENTA );break;case 5:dr
aw_entity( entity, entity->color );break;case 6: d
raw_entity( entity, CK_RED );break;case 7:draw_ent
ity( entity, CK_YELLOW );break;case 8:draw_entity
( entity, entity->color );break;case 9:draw_entity
( entity, entity->color );break;case 10:draw_entit
y( entity, CK_CYAN );break;case 11:draw_entity( en
tity,entity->color );break; #endif #ifdef CKWINcas
e 1:attr.color = CK_L_GREEN;ck_setattr( entity->i
d, CK_COLOR, NULL, &attr );break;case 3:attr.color
= CK_L_GRAY;ck_setattr( entity->id, CK_COLOR, NUL
L, &attr );break;case4:attr.color = CK_MAGENTA;ck_
setattr( entity->id, CK_COLOR, NULL, &attr);break;
case 6:attr.color = CK_L_RED;ck_setattr( entity->i
d, CK_COLOR,NULL, &attr );break;case 7:attr.color
= CK_YELLOW;ck_setattr( entity->id, CK_COLOR, NUL
L, &attr );break;case 10:attr.color = CK_L_CYAN;ck
_setattr( entity->id, CK_COLOR, NULL, &attr );brea
k; #endif} if ( entity->next== NULL ) break;}#ifde
f VELLUMCountPrompt++;sprintf( message,"Finished c
hange color Sheet Entity %d", CountPrompt );ck_pro
mpt( message ); #endifreturn 0;}/*===============
==================================================
関数: 名称: F2dCleanUpUndoPre 記述:
取消関数のためのデータフラグを準備すること。
復帰値: =0:成功裏に完了;パラメータ:
入力: 1 In drawing: 変更ステ
ータスである図。==================================
===============================*/int F2dCleanUpUnd
oPre(struct drawing *In_drawing){//selected entity
and temp entitiesstruct node *entity;//set flagF2
dCleanUpExcutedNo = 2;//check all of entities on t
he listfor( entity=In_drawing->objects; entity; e
ntity = entity->next){entity->status = entity->fla
gs;if ( entity->next == NULL )break;}return 0;}/*=
==================================================
==============関数: 名称: F2dCleanUpUndo記述: T
o undo. 戻り値:= 0: Completed successfully;パラメ
ータ:入力: 1 In_drawing: drawing that will be un
doed status=======================================
==========================*/int F2dCleanUpUndo(str
uct drawing *In_drawing){//selected entity and tem
p entitiesstruct node *entity;//flagint NoChangeFl
ag = 0;//checkflagif ( F2dCleanUpExcutedNo == 0 )r
eturn NoChangeFlag;//check all of entities on the
listfor( entity=In_drawing->objects; entity; enti
ty = entity->next){if ( entity->status != entity->
flags ){NoChangeFlag = 1;entity->flags = entity->s
tatus;}if ( entity->next == NULL )break;} //check
views flagif ( F2dCleanUpExcutedNo == 1 )In_drawin
g->views = NULL;//resetflag for viewsF2dCleanUpExc
utedNo = 0;return NoChangeFlag;}/*================
=================================================
関数: 名称:F2dCleanUpChangeDrawingFlag 記
述: エンティティのフラグを変更する関数。 復
帰値: =0:成功裏に完了; パラメータ:
入力: 1 In drawing: 変更された色
である図==========================================
=======================*/int F2dCleanUpChangeDrawi
ngFlag(struct drawing *In_drawing){//selected enti
ty and temp entitiesstruct node *entity;int CountP
rompt = 0;charmessage[64];#ifdef VELLUMCountPrompt
++;sprintf( message,"Start Flag Sheet Entity %d",
CountPrompt );ck_prompt( message ); #endif//check
all of entities on the listfor( entity=In_drawing
->objects; entity; entity = entity->next){if ( e
ntity->flags== 4 ) entity->flags = 3;#ifdef VELLU
M//CountPrompt++;//sprintf( message,"Flag Sheet En
tity %d", CountPrompt );//ck_prompt( message ); #
endifif ( entity->next == NULL )break;}#ifdef VELL
UMCountPrompt++;sprintf( message,"Finished Flag Sh
eet Entity %d", CountPrompt );ck_prompt( message
); #endifreturn 0;}/*===========================
====================================== 関数: 名
称: F2dCleanUpFindSameColorEntity 記述:
同じ色のエンティティを見出す。 復帰値:
=0: 成功裏に完了; パラメータ: 入力:
1 In entity: エンティティ2 In drawin
g: 変更された色である図==========================
======================================*/int F2dCle
anUpFindSameColorEntity(struct node *In_entity,str
uct drawing *In_drawing){//selected entity and tem
p entitiesstruct node *entity;int CountPrompt = 0;
charmessage[64];#ifdef VELLUMCountPrompt++;sprintf
( message,"Start Find same color Entity%d", CountP
rompt );ck_prompt( message ); #endif//check all o
f entitieson the listfor( entity=In_drawing->objec
ts; entity; entity = entity->next){if ( entity->
color == In_entity->color && entity->flags == 0) e
ntity->flags = 3;if ( entity->next == NULL )brea
k;}#ifdef VELLUMCountPrompt++;sprintf( message,"Fi
nished find same color Entity %d", CountPrompt );c
k_prompt( message ); #endifreturn 0;}/*==========
==================================================
===== 関数: 名称: F2dCleanUpClearDrawingEnt
ity 記述: それは復帰エンティティの色である。
復帰値:=0:成功裏に完了; パラメータ:
入力: 1 In drawing: 変更された色であ
る図==============================================
================*/int F2dCleanUpClearDrawingEntity
(struct drawing *In_drawing){//selected entity and
temp entitiesstruct node *entity;//entity’sspeci
fitysCK_ENTATTattr;//specificity of entitiesint Co
untPrompt = 0;charmessage[64];#ifdef VELLUM //
clear views highlighting ck_erase_level("VW_2
D");// ck_erase_level("VW_TRIM");//CountPrompt+
+;//sprintf(message,"Start Clear Entity %d", Count
Prompt );//ck_prompt( message );#endif//check all
of entities on the listfor( entity=In_drawing->obj
ects; entity; entity = entity->next){ if ( entit
y == NULL )break;switch (entity->flags ){case 0:ca
se 1:case 2:case 3:case 4:case 5:case 6:case 7:cas
e 8:case 9:case 10:entity->flags = 0;draw_entity(
entity, entity->color );//attr.color = entity->col
or;//ck_setattr( entity->id, CK_COLOR, NULL, &attr
);default:break;}}#ifdef VELLUM//CountPrompt++;//
sprintf( message,"Finished clear Entity %d", Count
Prompt );//ck_prompt( message ); #endif//clear vi
ews connectedIn_drawing->views = NULL;return 0;}/*
==================================================
=============== 関数: 名称:F2dCleanUpClearDraw
ingKeepFlags 記述: エンティティの色を復帰させ
るが、フラグは保持する。復帰値: =0:成功裏に
完了; パラメータ: 入力:1 In drawing:
変更された色である図==============================
===================================*/int F2dCleanU
pClearDrawingKeepFlags(structdrawing *In_drawing)
{//selected entity and temp entitiesstruct node *e
ntity;//entity’s specifitysCK_ENTATTattr;//specif
icity of entitiesint CountPrompt = 0;charmessage[6
4];#ifdef VELLUM // clear views highlighting
ck_erase_level("VW_2D");#endif//check all of ent
ities on the listfor( entity=In_drawing->objects;
entity; entity = entity->next){switch( entity->
flags ){case 0:case 1:case 2:case 3:case 4:case 5:
case 6:case7:case 8:case 9:case 10://center linedr
aw_entity( entity, entity->color);//attr.color = e
ntity->color;//ck_setattr( entity->id, CK_COLOR, N
ULL,&attr );}if ( entity->next == NULL )break;}ret
urn 0;}/*=========================================
======================= 関数: 名称: F2dClea
nUpDeleteViews 記述: それは削除ビユーに対す
る関数である。 復帰値: =0:成功裏に完了;
パラメータ: 入力: 1 Indrawin
g:図=============================================
====================*/int F2dCleanUpDeleteViews(st
ruct drawing *In_drawing){//check drawingif ( In_d
rawing == NULL )return 0; //delete views ( Not
release memory )In_drawing->views == NULL;return
0;}/*=============================================
==================== 関数: 名称: F2dCleanUp
DeleteDrawingEntity 記述: それは削除エンティ
ティに対する関数である。復帰値: =0:成功裏
に完了; パラメータ: 入力:1 In drawing:
図================================================
=================*/int F2dCleanUpDeleteDrawingEnti
ty(struct drawing *In_drawing){//selected entity a
nd temp entitiesstruct node *entity;struct group *
Gp;//groupstruct node_list *ETL;//Entity Temp List
intCountPrompt = 0;charmessage[64];#ifdef VELLUMCo
untPrompt++;sprintf( message,"Start Delete Entity
%d", CountPrompt );ck_prompt( message ); #endif//
check all of entities on the listfor( entity=In_dr
awing->objects; entity; entity = entity->next){i
f ( entity->flags == 3 || entity->flags == 6 || e
ntity->flags== 0 || entity->flags == 10 ){#ifdef C
KWINck_delent( entity->id );#endif#ifdef VELLUM//
remove_entity ( entity, In_drawing );
#endifentity->flags = 99;}if ( entity->next == NUL
L )break;}if ( In_drawing->views == NULL )return
0;//unuse group entitiesfor( Gp=In_drawing->views;
Gp; Gp = Gp->next){if ( Gp == NULL )break;if ( Gp-
>index != 0 )continue;for ( ETL = Gp->entities; ET
L; ETL = ETL->cdr ){#ifdef CKWINck_delent( ETL->ca
r->id );#endif#ifdef VELLUM // remove_en
tity ( ETL->car,In_drawing );#endifETL->car->flags
= 99; if ( ETL->cdr == NULL )break;}if ( Gp->next
== NULL )break;}#ifdef VELLUMCountPrompt++;sprint
f( message,"Finished Delete Entity %d", CountPromp
t );ck_prompt( message ); #endifreturn 0;}/*=====
==================================================
==========関数: 名称: F2dCleanUpCheckEntityExist
記述: check an entity for current drawingif the e
ntity is not same to database, drawing was changed
戻り値:= 0: No change;= 1: Changed;パラメータ:
入力: 1 In_drawing: drawing =====================
===========================================*/int F
2dCleanUpCheckEntityExist(struct drawing *In_drawi
ng){//selected entity and temp entitiesstruct node
*entity;//defineint ReturnCode = 0, etype = 0;dou
blex1=0.0,y1=0.0,z1=0.0,x2=0.0,y2=0.0,z2=0.0,rad=
0.0,ang1=0.0,ang2=0.0;//entity’s specifitysCK_ENT
ATTattr;//specificity of entities//check all of en
tities on the listif ( In_drawing->objects == NULL
)return1;for( entity=In_drawing->objects; entit
y; entity = entity->next){if ( entity->flags == 9
9 )continue;ReturnCode = ck_getentid( entity->id,
&etype );if ( ReturnCode == CK_NO_ENT )return1;els
e{//check all ofentities on the listswitch ( entit
y->type ){case CK_ARC:ck_getarc ( entity->id, &x1,
&y1,&z1, &rad,&ang1,&ang2, &attr );break; case C
K_LINE: ck_getline( entity->id, &x1,&y1,&z1, &x2,
&y2,&z2, &attr );break;}if ( attr.level == 191 )re
turn0;elsereturn1;}if ( entity->next == NULL )brea
k;}return 1;}/*===================================
============================= 関数: 名称: F
2dCleanUpChangeArrowVertexFlag 記述: アラウ
トップ頂点フラグを変更し、アローセンタライン座標を
設定する。 復帰値:=0:成功裏に完了; パラメー
タ: 入力: 1 Flags:フラグ
2 TopVertex:アロートップ頂点
3 Entiry: アローセンタラインエンティティ======
==================================================
=========*/int F2dCleanUpChangeArrowVertexFlag(//i
nputint *flags,structplanar_vertex *TopVertex,stru
ctnode *Entity){//set flagto arrow top vertexTopVe
rtex->flags = *flags;//set arrow center line coord
inatesTopVertex->ArrowCenterLine_X1 = Entity->X1;T
opVertex->ArrowCenterLine_Y1 = Entity->Y1;TopVerte
x->ArrowCenterLine_Z1 = Entity->Z1;TopVertex->Arro
wCenterLine_X2 = Entity->X2;TopVertex->ArrowCenter
Line_Y2 = Entity->Y2;TopVertex->ArrowCenterLine_Z2
= Entity->Z2;//endreturn 0;}/*===================
============================================== 関
数:名称: F2dCleanUpFindArrowCenterEntity 記
述: アローセンタラインを見出し、フラグをアロー
メンバに設定する。 復帰値: =0:アロー無
し; =1:アロー パラメータ: 入力:
1 Nodes:接続されたノード 2 Top
Vertex:アロートップ頂点 3 StartEntity:
アロースタートラインエンティティ 4 EndEnt
ity:アローエンドラインエンティティ 5 Cen
terLineAngleTemp:アローセンタライン角度==========
==================================================
=====*/int F2dCleanUpFindArrowCenterEntity(//input
struct node_list *Nodes,structplanar_vertex *TopVe
rtex,structnode *StartEntity,structnode *EndEntit
y,double*CenterLineAngleTemp ){//external function
sint F2dCleanUpLineAngle(); int F2dCleanUpChangeCh
ildrenFlag();int F2dCleanUpChangeArrowVertexFla
g();double F2dCleanUpLineLength();//nodesstructnod
e *CenterEntity;//linklist and temp liststruct nod
e_list*temp_list;//flagsint ReturnFlag = 0,ArrowFl
ags = 3; //doubledoubleCenterParentLength = 0.0,Ce
nterParentAngle= 0.0,CenterParentAngleAnother = 0.
0;doubleTolerance = 0.0;//set valueTolerance = F2d
CleanUpTolerance;// look for arrow center linefor
( temp_list = Nodes; temp_list; temp_list = temp_
list->cdr){//check pointer addressif ( StartEntity
== temp_list->car || EndEntity == temp_list->ca
r)continue;//get new entityCenterEntity = temp_lis
t->car;//check flags//if (CenterEntity->flags !=
2 //&& CenterEntity->flags != 3 )continue; if( Ce
nterEntity->type != CK_LINE )continue; if ( Cente
rEntity->line_type!= StartEntity->line_type && Cen
terEntity->color != StartEntity->color && Center
Entity->is_thickness != StartEntity->is_thickness
) continue; if ( CenterEntity->no_connected_1 < 2
&& CenterEntity->no_connected_2 < 2 ) continue;
//check lengthCenterParentLength = F2dCleanUpL
ineLength( CenterEntity->parent );if ( CenterParen
tLength < Tolerance ) continue;//arrow central-ent
ity angleF2dCleanUpLineAngle(//inputTopVertex, Cen
terEntity->parent,//output&CenterParentAngle, &Cen
terParentAngleAnother);//check the angle for centr
al entity if ( fabs( CenterParentAngle - *CenterLi
neAngleTemp )> Tolerance ) continue;// set flags
for arrow’s entitiesReturnFlag = 1;//look for arr
ow entity’s childrenF2dCleanUpChangeChildrenFlag
( StartEntity->parent );F2dCleanUpChangeChildrenFl
ag( EndEntity->parent );F2dCleanUpChangeChildrenFl
ag( CenterEntity->parent );//set flag to arrow top
vertexF2dCleanUpChangeArrowVertexFlag( &ArrowFlag
s,TopVertex, CenterEntity );return ReturnFlag;if
( temp_list->cdr == NULL)break;}return ReturnFla
g;}/* 関数: 名称: F2dCleanUpFindArrowOneSid
eOpenEntity 記述: 1つのサイドオープンエンテ
ィティを見出す。 復帰値: =0: ノーオープ
ン; =1: オープン =2: オープンパラメー
タ: 入力: 1 Nodes:接続されたノー
ド================================================
================*/int F2dCleanUpFindArrowOneSideOp
enEntity( struct node_list *Nodes ){//link list an
d temp liststruct node_list*temp_list;//entities c
ounter and flagsint open_entity_flag = 0;//startfo
r( temp_list = Nodes; temp_list; temp_list = tem
p_list->cdr){//ckeck another side connected’s cou
nterif ( temp_list->car->no_connected_1 == 0 && te
mp_list->car->no_connected_2 > 1 ){open_entity_fla
g = 1;break;}if ( temp_list->car->no_connected_2 =
= 0 && temp_list->car->no_connected_1 > 1 ){open_e
ntity_flag = 2;break;}if ( temp_list->cdr== NULL )
break;}return open_entity_flag;}/*================
=================================================
関数: 名称: F2dClaenUpCheckStartEndEntity
記述: 開始および終了エンティティをチェックす
る 復帰値: =0: ノーアロー;= 1: good
パラメータ:入力: 1 StartEntity: アロー開始ライン
エンティティ2 EndEntity: アロー終了ラインエンティ
ティ==============================================
===================*/int F2dCleanUpCheckStartEndEn
tity(//inputstructnode *StartEntity,structnode *En
dEntity ){//external functionsdouble F2dCleanUpLin
eLength();//doubledoublearrow_start_parent_length
= 0.0,arrow_end_parent_length = 0.0,arrow_toleranc
e = 0.0;//set tolerancearrow_tolerance = F2dCleanU
pTolerance;//start//compute entities’ parent leng
tharrow_start_parent_length = F2dCleanUpLineLength
( StartEntity );arrow_end_parent_length = F2dCle
anUpLineLength( EndEntity );//check lengthif ( arr
ow_start_parent_length < arrow_tolerance )return
0; if ( arrow_end_parent_length < arrow_tolerance
)return 0; //check tloeranceif ( fabs( arrow_star
t_parent_length - arrow_end_parent_length )> arrow
_tolerance )return 0; //check angle:if entitiesar
e parallel, STOPif (sqrt(fabs((( StartEntity->X1 -
StartEntity->X2 )* ( EndEntity->Y1 - EndEntity-
>Y2 )) -(( EndEntity->X1 - EndEntity->X2 )
* ( StartEntity->Y1 - StartEntity->Y2 ))))< arro
w_tolerance )return 0;//normal endreturn 1;}/*====
==================================================
==========関数: 名称: F2dCleanUpComputeCenterLin
eAngle記述: センタライン角度を計算する。戻り値:=
0: ノーアロー;= 1: 良好パラメータ:入力: 1 TopVe
rtex: アロートップ頂点2 StartEntity: アロー開始ラ
インエンティティ 3 EndEntity: アロー終了ラインエン
ティティ出力:1 CenterLineAngle: アローセンターラ
イン角度 ========================================
========================*/int F2dCleanUpComputeCen
terLineAngle(//inputstructplanar_vertex *TopVerte
x,structnode *StartEntity,structnode*EndEntity,//o
utputdouble*CenterLineAngle ){//external functions
int F2dCleanUpLineAngle();//entities counter and f
lagsint ReturnFlag = 0;//doubledoublearrow_start_p
arent_angle = 0.0,arrow_end_parent_angle = 0.0,arr
ow_center_diff_angle = 0.0,RotateAxisAngleAnotherT
emp = 0.0,arrow_center_parent_angle_temp = 0.0,arr
ow_tolerance = 0.0;//set tolerancearrow_tolerance
= F2dCleanUpTolerance;//start// compute central an
gle of arrow////angle_center = 0.5 * ( angle_start
+ angle_end )//atan2 returns the arctangent of y/
x//atan2 returns a value in the range -pi to pi ra
dians//getarrow start angleF2dCleanUpLineAngle(//i
nputTopVertex, StartEntity,//output&arrow_start_pa
rent_angle, &RotateAxisAngleAnotherTemp);//arrow e
nd angleF2dCleanUpLineAngle(//inputTopVertex, EndE
ntity,//output&arrow_end_parent_angle, &RotateAxis
AngleAnotherTemp);//get difference anglearrow_cent
er_diff_angle = fabs( arrow_end_parent_angle - a
rrow_start_parent_angle );//same angleif ( arrow_c
enter_diff_angle < arrow_tolerance )return0;if ( a
rrow_center_diff_angle < pi ){//diff < piarrow_cen
ter_parent_angle_temp = 0.5 * (arrow_end_parent_an
gle + arrow_start_parent_angle );}else{//diff > pi
( take opposite angle ) arrow_center_parent_angle
_temp =0.5 * (arrow_end_parent_angle + arrow_start
_parent_angle ) + pi;//angle> 2*piif ( fabs ( arro
w_center_parent_angle_temp - 2.0 * pi )< arrow_tol
erance ){arrow_center_parent_angle_temp = 0.0;}els
e{if ( arrow_center_parent_angle_temp > ( 2.0 * pi
) ){arrow_center_parent_angle_temp = arrow_center
_parent_angle_temp - 2.0 * pi;}}}*CenterLineAngle
= arrow_center_parent_angle_temp;//normal endretur
n 1;}/*===========================================
======================関数: 名称: F2dCleanUpFind
ArrowEndEntity記述: アロー終了ラインを見出す戻り
値:= 0: ノーアロー;= 1: アローパラメータ:入力:
1 Nodes: 接続ノード2 TopVertex: アロートップ頂点3
StartEntity: アロー開始エンティティ===============
=================================================*
/int F2dCleanUpFindArrowEndEntity(//inputstructnod
e_list *Nodes,structplanar_vertex *TopVertex,struc
tnode *StartEntity){//external functionsint F2dCle
anUpFindArrowOneSideOpenEntity();int F2dCleanUpCom
puteCenterLineAngle();int F2dCleanUpCheckStartEndE
ntity();intF2dCleanUpFindArrowCenterEntity();//lin
k list and temp liststruct node_list*temp_list; //
selected entity and temp entitiesstruct node *Next
_entity,*arrow_start_entity_parent,*arrow_end_enti
ty,*arrow_end_entity_parent;//entities counter and
flagsint assistant_line_flag = 0,ReturnFlag = 0;/
/doubledoublearrow_center_parent_angle_temp = 0.0;
//startfor( temp_list=Nodes; temp_list; temp_li
st = temp_list->cdr){ if ( temp_list->car== NULL )
break;Next_entity = temp_list->car;arrow_end_entit
y = temp_list->car;//if ( Next_entity->flags != 2
)continue;if ( Next_entity->type !=CK_LINE )conti
nue;if ( Next_entity->line_type != StartEntity->li
ne_type)continue;if ( Next_entity->color != StartE
ntity->color )continue;if (Next_entity->is_thickne
ss != StartEntity->is_thickness )continue; //set
parentarrow_start_entity_parent = StartEntity->pa
rent; arrow_end_entity_parent = Next_entity->par
ent; //look for broken entity’s another side Retu
rnFlag = F2dCleanUpFindArrowOneSideOpenEntity( arr
ow_end_entity_parent->children ); if ( ReturnFlag
== 0 )continue;//check parents entitiesReturnFlag
= F2dCleanUpCheckStartEndEntity( //inputarrow_sta
rt_entity_parent, arrow_end_entity_parent );if ( R
eturnFlag == 0 )continue;// look for central entit
yof arrowReturnFlag = F2dCleanUpComputeCenterLineA
ngle(//inputTopVertex, arrow_start_entity_parent,
arrow_end_entity_parent,//output&arrow_center_pare
nt_angle_temp );if ( ReturnFlag == 0 )continue;//
get central entity of arrowassistant_line_flag = F
2dCleanUpFindArrowCenterEntity(//inputNodes, TopVe
rtex, StartEntity, arrow_end_entity, &arrow_center
_parent_angle_temp );return assistant_line_flag;}r
eturn assistant_line_flag;}/*=====================
============================================関数:
名称: F2dCleanUpChangeChildrenFlag記述: エンテ
ィティのチルドレンフラグを変更する関数戻り値:= 0:
成功裏に完了;パラメータ:入力: =================
================================================*/
int F2dCleanUpChangeChildrenFlag(struct node *Enti
ty){//temp liststruct node_list*Temp_list;//check
all of children of the entityfor( Temp_list=Entity
->children; Temp_list; Temp_list = Temp_list->cd
r){//change flag to light grayTemp_list->car->flag
s = 3; if ( Temp_list->cdr == NULL )break;}return
0;}/*=============================================
====================関数: 名称: F2dCleanUpLineLe
ngth記述: ライン形エンティティの長さを計算する関
数 戻り値:= 長さ;パラメータ:入力: エンティティ:
ペアレントエンティティ===========================
=====================================*/double F2dC
leanUpLineLength(struct node *Entity){//defination
doubleEntityLength=0.0;//compute entities’ parent
lengthEntityLength =sqrt( ( Entity->X1 - Entity-
>X2 ) * ( Entity->X1 - Entity->X2 )+ ( Entity->Y1
- Entity->Y2 ) *( Entity->Y1 - Entity->Y2 ));retur
nEntityLength;}/*=================================
================================関数: 名称: F2dC
leanUpFindArrow記述: アロー型エンティティを求め、
フラグをそれらに設定する。 戻り値:= 0: 成功裏に完
了;パラメータ:入力: 1 Entities_list: チェックさ
れるノードリスト==================================
==============================*/int F2dCleanUpFind
Arrow( struct node_list *Entities_list ){//externa
l functionsint F2dCleanUpLineAngle();int F2dCleanU
pFindArrowEndEntity(); //link list and temp listst
ruct node_list*temp_nodes1,*arrow_list,*temp_list;
//selected entity and temp entitiesstruct node *N
ext_entity;struct planar_vertex*top_vertex;//entit
ies counter and flagsint bug_flag = 0,ReturnFlag =
0,assistant_line_flag = 0;int CountPrompt = 0;cha
rmessage[64];#ifdef VELLUMCountPrompt++;sprintf( m
essage,"Start Find Arrow Entity %d", CountPrompt
);ck_prompt( message ); #endif// Step_1:look for
one side open entity//arrow start entityfor( temp
_list=Entities_list; temp_list; temp_list = temp
_list->cdr){Next_entity =temp_list->car;//if ( Nex
t_entity->flags != 2 ) continue;if ( Next_entity->
type != CK_LINE ) continue;if ( Next_entity->no_co
nnected_1 == 0&&Next_entity->no_connected_2 < 2 )
continue;if ( Next_entity->no_connected_1 < 2
&& Next_entity->no_connected_2 == 0 ) continue;
//selectentity’s sideif ( Next_entity->no_conne
cted_1 == 0 ){// clear bug_flagbug_flag = 0;//look
for broken entity’s another side for( arrow_list
= Next_entity->parent->children; arrow_list; ar
row_list = arrow_list->cdr){//ckeck another side v
ertex’s pointerif ( Next_entity->parent->vertex2
== arrow_list->car->vertex2 ){ bug_flag = 1; br
eak;}if ( arrow_list->cdr == NULL )break;}if ( bug
_flag == 1 ){top_vertex = Next_entity->parent->ver
tex2;temp_nodes1 = arrow_list->car->connected_node
s_2;}}else{//clear bug_flagbug_flag = 0;//look for
broken entity’s another side for(arrow_list = Ne
xt_entity->parent->children; arrow_list; arrow_l
ist =arrow_list->cdr){//ckeck another side verte
x’s pointerif ( Next_entity->parent->vertex1 ==
arrow_list->car->vertex1 ){ bug_flag = 1; brea
k;}if ( arrow_list->cdr == NULL )break;}if ( bug_f
lag == 1 ){top_vertex = Next_entity->parent->verte
x1;temp_nodes1 = arrow_list->car->connected_nodes_
1;}}if ( bug_flag != 1 ) continue;// get end e
ntity of arrowReturnFlag = F2dCleanUpFindArrowEndE
ntity(//inputtemp_nodes1, top_vertex, Next_entity
);if ( ReturnFlag == 1 )assistant_line_flag = 1;i
f ( temp_list->cdr == NULL )break;}#ifdef VELLUMCo
untPrompt++;sprintf( message,"Finished find arrows
Entity %d", CountPrompt );ck_prompt( message );
#endifreturnassistant_line_flag;}/*===============
==================================================
関数: 名称: F2dCleanUpFindOneSideOpenEntity記
述:look for one side open entities and they are v
ertical with arrow type entities. 戻り値:= 0: Com
pleted successfully and No found;= NUM: Open entit
ies’ numberパラメータ:入力: 1 Entities_list: a
node list that willbe checked=====================
===========================================*/int F
2dCleanUpFindOneSideOpenEntity( struct node_list *
Entities_list){//external functionsint F2dCleanUpC
hangeChildrenFlag();//link list and temp liststruc
t node_list *temp_list; //selected entity and temp
entitiesstruct node *Next_entity;//entities count
er and flagsint count = 0;//doubledoubleassistant_
line_angle = 0.0,arrow_tolerance = 0.0;int CountPr
ompt = 0;charmessage[64];//set tolerancearrow_tole
rance = F2dCleanUpTolerance;#ifdef VELLUMCountProm
pt++;sprintf( message,"Start Find One side open En
tity %d", CountPrompt );ck_prompt( message ); #en
dif // checkall of entities which connected wit
h outside loop for( temp_list=Entities_list; t
emp_list; temp_list = temp_list->cdr){ if ( temp_
list->car== NULL )break;Next_entity = temp_list->c
ar;//check flags//if ( Next_entity->flags !=2 )con
tinue;//check vertex’ flagif ( Next_entity->verte
x1->flags != 3 && Next_entity->vertex2->flags != 3
)continue;//check linesverticallyif ( Next_entity
->vertex1->flags == 3 ){assistant_line_angle= fabs
( ( Next_entity->X1 - Next_entity->X2 )* (Next_
entity->vertex1->ArrowCenterLine_X1 - Next_ent
ity->vertex1->ArrowCenterLine_X2 ) + (Next_entity-
>Y1 - Next_entity->Y2 ) * (Next_entity->vertex1->A
rrowCenterLine_Y1 - Next_entity->vertex1->Arro
wCenterLine_Y2 ) );}else{assistant_line_angle = fa
bs ( ( Next_entity->X1 - Next_entity->X2 )* (Nex
t_entity->vertex2->ArrowCenterLine_X1 - Next_e
ntity->vertex2->ArrowCenterLine_X2 ) + ( Next_enti
ty->Y1 - Next_entity->Y2 ) * (Next_entity->vertex2
->ArrowCenterLine_Y1 - Next_entity->vertex2->A
rrowCenterLine_Y2 ));}//check the angle for centra
l entity if ( sqrt(assistant_line_angle)> arrow_to
lerance ) continue;//look for childrenF2dCleanUpCh
angeChildrenFlag( Next_entity->parent );count++;}#
ifdef VELLUMCountPrompt++;sprintf( message,"Finish
ed find one side open Entity %d", CountPrompt );ck
_prompt( message ); #endif//normal endreturn coun
t;}/*=============================================
====================関数: 名称: F2dCleanUpFindOn
eSideOpenEntity2記述: ビユーを見出した後に一側が
オープンのエンティティとビユーの境界を横切るエンテ
ィティを見出す。戻り値:= 0: 成功裏に完了し、何も
見出されない;= NUM: オープンエンティティの個数パラ
メータ:入力: 1In_drawing: 図====================
============================================*/int
F2dCleanUpFindOneSideOpenEntity2( struct drawing *
In_drawing ){//external functionsint F2dCleanUpCha
ngeChildrenFlag();//link list and temp liststruct
node_list *temp_list, *ConnectedNode; //selected e
ntity and temp entitiesstruct node *Entity;//defin
e flagintBoundaryFlag = 0; int CountPrompt = 0;cha
rmessage[64];#ifdef VELLUMCountPrompt++;sprintf( m
essage,"2 Start Find Oneside Open Entity %d", Cou
ntPrompt );ck_prompt( message ); #endif //check
node listif ( In_drawing == NULL )return-1;if ( I
n_drawing->objects == NULL )return-1; // check
all of entities which connected with outside loop
for( Entity=In_drawing->objects;Entity;Entity
= Entity->next ){//check connected nodes countif
( Entity== NULL )break;if (( Entity->no_connected_
1 == 0 ) &&( Entity->no_connected_2 == 0 ))contin
ue;//check flagsif (( Entity->flags == 3 ) &&( Ent
ity->type == CK_LINE ) &&(( Entity->no_connected_
1 == 0 ) ||( Entity->no_connected_2 == 0 ))){//o
ne side open and line typeif ( Entity->no_connecte
d_2 == 0 ) ConnectedNode = Entity->connected_no
des_1;else ConnectedNode = Entity->connected_nodes
_2;//clear found boundary’s flagBoundaryFlag = 0;
//check across with views’ boundaryif ( Connected
Node != NULL){for ( temp_list = ConnectedNode; tem
p_list;temp_list = temp_list->cdr){//check wrong d
ataif ( temp_list->car == NULL )break;if ( temp_li
st->car->flags == 4 ){//find boundary’s entityBou
ndaryFlag = 1;break;}if (temp_list->cdr == NULL )b
reak;}if ( BoundaryFlag == 1 ) //look for childre
n F2dCleanUpChangeChildrenFlag( Entity->parent
);}}//check arc if ((Entity->type == CK_ARC ) &&
( Entity->flags != 99 ) &&(( Entity->no_connected
_1 == 0 ) ||( Entity->no_connected_2 == 0 ))){//
look for childrenF2dCleanUpChangeChildrenFlag( Ent
ity->parent );}if ( Entity->next == NULL )break;}#
ifdef VELLUMCountPrompt++;sprintf( message,"Finish
ed 2 one side open Entity %d", CountPrompt );ck_pr
ompt( message ); #endif//normalendreturn 0;}/*===
==================================================
===========関数: 名称: F2dCleanUpFindGroupMinX記
述: エンティティグループに対する最小X値を求め
る。戻り値:= 0: 成功裏に完了し、エンティティ無し;
パラメータ:入力: 1 Entities_list: チェックされる
ノードリスト出力:1 Entity: エンティティは最小の
X値を含む。======================================
==========================*/struct node *F2dCleanU
pFindGroupMinX( struct node_list *Entities_list )
{//double F2dCleanUpLineLength();//entities counte
r and flagsint open_entity_flag = 0;//link list an
d temp liststruct node_list*EntitiesList2,*Out_tem
p_list2,*open_temp_list2, *open_list2, *temp_list
1, *temp_list2; //selected entity and temp entitie
sstructnode *Next_entity, *MinXvalueEntity;//leng
th and angledoubleMinXvalueGroup = 0.0;//check all
of entities which connected with outside loop//in
itializeEntitiesList2 =( struct node_list * ) call
oc ( 1, sizeof ( struct node_list ));open_list2 =
( struct node_list * ) calloc ( 1, sizeof (struct
node_list ));//check first entity//search connecte
d entity untilreal entity be foundfor ( temp_list2
= Entities_list;//entity->connected_nodes; ( tem
p_list2!=0 && temp_list2->car!=0 ); te
mp_list2=temp_list2->cdr){if ( temp_list2->car ==
NULL )break;if ( temp_list2->car->no_connected_1 =
= 0 ) continue;if ( temp_list2->car->no_connected_
2== 0 ) continue;if ( temp_list2->car->flags == 2
){//set pointer to first entityopen_list2->car =
temp_list2->car;//set minimum X valueMinXvalueGrou
p = temp_list2->car->Min_X;MinXvalueEntity = temp_
list2->car;break;}if ( temp_list2->cdr == NULL )br
eak;}if ( open_list2->car == 0 )return 0;//set lin
k addressopen_list2->cdr = NULL;//set the pointer
to output node listEntitiesList2->car = open_list2
->car;EntitiesList2->cdr = open_list2->cdr;////Ste
p_6_1://find connected entitiesfor ( temp_list1 =
open_list2; ( temp_list1 //&&(temp_list
->cdr != 0) ); ) {//get a pointer from op
en listif ( temp_list1->car == NULL )break;Next_en
tity = temp_list1->car;//set a closed flag to the
node//Next_entity->flags = 1;//close the node ( de
lete the node from open list )open_list2 = open_li
st2->cdr;// look for first connected entity whose
flags=0.for ( temp_list2 = Next_entity->connected_
nodes; ( temp_list2!=0 && temp_list2->car!
=0 ); temp_list2=temp_list2->cdr){ if ( t
emp_list2->car == NULL ) break;// if found an unma
rked connected entityif ( temp_list2 && temp_list2
->car->flags==2&& MinXvalueEntity->line_type == te
mp_list2->car->line_type&& MinXvalueEntity->color
== temp_list2->car->color&& MinXvalueEntity->is_th
ickness == temp_list2->car->is_thickness ){//
check minimum Xif ( temp_list2->car->Min_X < MinXv
alueGroup ){//change minimum X valueMinXvalueGroup
= temp_list2->car->Min_X;MinXvalueEntity = temp_
list2->car; }// allocate memory for open list elem
entopen_temp_list2 = ( struct node_list * ) calloc
( 1, sizeof ( struct node_list ));// allocate mem
ory for output node list elementOut_temp_list2 =
( structnode_list * ) calloc ( 1, sizeof ( struct
node_list ));// add this entity to the open listop
en_temp_list2->car = temp_list2->car;// add this e
ntity to the output node list Out_temp_list2->car
= temp_list2->car;//seta open flagto the nodeopen_
temp_list2->car->flags = 1; // connect to the open
listopen_temp_list2->cdr = open_list2;// move the
pointer of openlist to the topopen_list2 = open_t
emp_list2;// connect to the output node listOut_te
mp_list2->cdr = EntitiesList2;// move the pointer
of outputnode list to the topEntitiesList2 = Out_t
emp_list2;}if ( temp_list2->cdr == NULL )break;}//
assign value to the loop variabletemp_list1 = ope
n_list2;}return MinXvalueEntity;}/*===============
==================================================
関数: 名称: F2dCleanUpFindOutNextEntity記述: ア
ウトサイドループエンティティに接続されたエンティテ
ィを求める。戻り値:= 0: 成功裏に完了;パラメータ:
入力: 1 In_entity: 軸エンティティを回転 2 In_Node
s: エンティティのノード3 In_Vertex: エンティティ
の頂点4 *In_Angle: エンティティの角度=============
==================================================
=*/int F2dCleanUpFindOutNextEntity(//input struct
node*In_entity,struct node_list *In_Nodes, struct
planar_vertex *In_Vertex,double *In_Angle){//exter
nal functionsint F2dCleanUpArcAngle(); int F2dClea
nUpLineAngle();//link list and temp liststruct nod
e_list*temp_list, *RotateNodes,*RotateNodesTemp,*R
otateNodesAnother,*RotateNodesAnotherTemp;//select
ed entity and temp entitiesstruct node *Next_enti
ty, *RotateEntity;struct planar_vertex*RotateVerte
x,*RotateVertexTemp,*RotateVertexAnother,*RotateVe
rtexAnotherTemp;int RotateVertexFlag = 0,RotateAxi
sEntityType = 0,RotateAxisEntityVertexFlag = 0,Fin
dNextFlag = 0;//length and angledoubleRotateAxisAn
gleAnother = 0.0,RotateAxisAngleAnotherTemp = 0.0,
RotateMinAngleTemp = 0.0,RotateDiffAngleTemp = 0.
0,RotateAxisAngle = 0.0,RotateAxisAngleTemp = 0.0;
//set tolerance TolerancedoubleTolerance = 0.0;To
lerance = F2dCleanUpTolerance;//initializeRotateAx
isAngleAnother= *In_Angle;RotateEntity= In_entity;
RotateNodesAnother= In_Nodes;RotateVertexAnother=
In_Vertex;//check all of entities which connected
with outside loopfor( ; ; ){//set flag for first
entity on loopFindNextFlag = 0;RotateEntity->flags
= 4;RotateAxisEntityType = RotateEntity->type;if
( RotateEntity->vertex1 == RotateVertexAnother )Ro
tateAxisEntityVertexFlag = 1;else RotateAxisEntity
VertexFlag = 2;//set standard axis for first searc
hRotateAxisAngle = RotateAxisAngleAnother;RotateMi
nAngleTemp= 2.0 * pi;RotateNodes= RotateNodesAnoth
er;RotateVertex= RotateVertexAnother; //check n
ext connected entityif ( RotateNodes == 0 )break;/
/start loop processfor( temp_list=RotateNodes; te
mp_list; temp_list = temp_list->cdr){if ( temp_li
st->car == NULL )break;Next_entity = temp_list->ca
r;//checkflagsif ( Next_entity->flags == 4 )break;
if ( Next_entity->flags != 1 )continue;switch ( Ne
xt_entity->type ){//arc type entitycaseCK_ARC:Rot
ateVertexFlag = F2dCleanUpArcAngle(//inputRotateVe
rtex, Next_entity,//output&RotateAxisAngleTemp, &R
otateAxisAngleAnotherTemp);break;//line typeentit
ycaseCK_LINE:RotateVertexFlag = F2dCleanUpLineAngl
e(//inputRotateVertex, Next_entity,//output&Rotate
AxisAngleTemp, &RotateAxisAngleAnotherTemp);break;
//wrong type entitydefault:break;}//select connect
ed side ofentityif ( RotateVertexFlag == 1 ){//get
start->end //set rotation vertex nodeRotateNodesT
emp = Next_entity->connected_nodes_1;RotateVertexT
emp=Next_entity->vertex1;//set another side vertex
nodeRotateNodesAnotherTemp = Next_entity->connect
ed_nodes_2;RotateVertexAnotherTemp= Next_entity->v
ertex2;}else{//set rotation vertex nodeRotateNodes
Temp = Next_entity->connected_nodes_2;RotateVertex
Temp = Next_entity->vertex2;//set anotherside vert
ex nodeRotateNodesAnotherTemp = Next_entity->conne
cted_nodes_1;RotateVertexAnotherTemp= Next_entity-
>vertex1;}//compute diff angle//for change current
entityRotateDiffAngleTemp = RotateAxisAngleTemp -
RotateAxisAngle;if ( fabs( RotateDiffAngleTemp )
< Tolerance ) {switch( RotateAxisEntityType ){case
CK_ARC:switch( RotateAxisEntityVertexFlag ){case1:
RotateDiffAngleTemp = 2.0 * pi;break;case2:RotateD
iffAngleTemp = 0.0;break;}break;caseCK_LINE:switch
( RotateVertexFlag ){case1:RotateDiffAngleTemp =
0.0;break;case2:RotateDiffAngleTemp = 2.0 * pi;bre
ak;}break;}}if (RotateDiffAngleTemp < 0.0 ){Rotate
DiffAngleTemp = RotateDiffAngleTemp +2.0 * pi;}if
( fabs( RotateDiffAngleTemp - RotateMinAngleTemp )
< Tolerance ) {switch( Next_entity->type ){caseCK
_ARC:switch( RotateEntity->type){caseCK_ARC:switch
( RotateVertexFlag ){case1://no changebreak;case2:
RotateEntity= Next_entity;RotateNodes = RotateNo
desTemp;RotateVertex= RotateVertexTemp;RotateNodes
Another = RotateNodesAnotherTemp;RotateVertexAnoth
er = RotateVertexAnotherTemp;RotateAxisAngleAnothe
r = RotateAxisAngleAnotherTemp;break;}break;caseCK
_LINE:switch( RotateVertexFlag ){case1://no change
break;case2:RotateEntity= Next_entity;RotateNodes
= RotateNodesTemp;RotateVertex= RotateVertexTem
p;RotateNodesAnother = RotateNodesAnotherTemp;Rota
teVertexAnother = RotateVertexAnotherTemp;RotateAx
isAngleAnother = RotateAxisAngleAnotherTemp;brea
k;}break;}caseCK_LINE:switch( RotateEntity->type )
{caseCK_ARC:if ( RotateEntity->vertex1 == RotateVe
rtex ){RotateEntity= Next_entity;RotateNodes = R
otateNodesTemp;RotateVertex= RotateVertexTemp;Rota
teNodesAnother = RotateNodesAnotherTemp;RotateVert
exAnother = RotateVertexAnotherTemp;RotateAxisAngl
eAnother = RotateAxisAngleAnotherTemp;}break;}}}if
( RotateDiffAngleTemp < RotateMinAngleTemp ){Find
NextFlag = 1;RotateMinAngleTemp = RotateDiffAngleT
emp;//set rotation entityRotateEntity= Next_entit
y;RotateNodes = RotateNodesTemp;RotateVertex= Ro
tateVertexTemp;RotateNodesAnother = RotateNodesAno
therTemp;RotateVertexAnother = RotateVertexAnother
Temp;RotateAxisAngleAnother =RotateAxisAngleAnothe
rTemp;}}//check flags//if loop meet closed entity
if ( Next_entity->flags == 4 )break;if ( FindNextF
lag == 0 ) break;}return 0;}/*====================
=============================================関
数: 名称: F2dCleanUpFindOutSideLoop記述: アウト
サイドループエンティティを求める。戻り値:= 0: ア
ウトサイドループエンティティを求める。;= NUM: アウ
トサイドエンティティの個数パラメータ:入力: 1 Ent
ity: エンティティはループの最小X値を含む。======
==================================================
========*/int F2dCleanUpFindOutSideLoop( struct no
de *MinXvalueEntity ){//external functionsint F2dC
leanUpArcAngle(); int F2dCleanUpLineAngle();int F2
dCleanUpFindOutFirstEntity();int F2dCleanUpFindOut
NextEntity(); //entities counter and flagsint coun
t = 0,count2 = 0,open_entity_flag = 0,RotateVertex
Flag = 0,assistant_line_flag = 0;//link list and t
emp liststruct node_list*outside_loop_temp_list3,
*RotateNodes,*RotateNodesTemp,*RotateNodesAnother,
*RotateNodesAnotherTemp;//selected entity and temp
entitiesstruct node *Next_entity, *RotateEntity;
struct planar_vertex*RotateVertex,*RotateVertexTem
p,*RotateVertexAnother,*RotateVertexAnotherTemp;//
length and angledoubleassistant_line_angle = 0.0,M
inXvalueGroup = 0.0,RotateAxisAngleAnother = 0.0,R
otateAxisAngleAnotherTemp =0.0,RotateMinAngleTemp
= 0.0,RotateDiffAngle = 0.0,RotateDiffAngleTemp =
0.0,RotateAxisAngle = 0.0,RotateAxisAngleTemp = 0.
0;//set tolerance Tolerancedoubleloop_tolerance =
0.00;loop_tolerance = F2dCleanUpTolerance;//loop
direction : counter-clock//check a flag for outsid
e loop process//if ( count2 > 0 ){//step_7_1:find
first entity for the group//set standard axis for
first searchRotateAxisAngle = 1.5 * pi;RotateMinAn
gleTemp=2.0 * pi;//step_7_1_1: only one entity//ch
eck entities’ angle//arc case: special case ( no
vertex on min_x )if ( MinXvalueEntity->type == CK_
ARC && ( fabs ( MinXvalueEntity->Min_X - MinXvalu
eEntity->vertex1->X ) >loop_tolerance ) && ( fabs
( MinXvalueEntity->Min_X - MinXvalueEntity->vertex
2->X ) > loop_tolerance ) ){//set rotation vertex
nodeRotateNodesAnother = MinXvalueEntity->connecte
d_nodes_2;RotateVertexAnother = MinXvalueEntity->v
ertex2;RotateEntity= MinXvalueEntity;//get arc end
-angle //(direction : from circle-center to end-po
int )RotateAxisAngleAnotherTemp= ( MinXvalueEntity
->AngEnd ) * pi / 180.0;//change angle to oppsite
direction//( direction : from end-point to circle-
center )RotateAxisAngleAnotherTemp = RotateAxisAng
leAnotherTemp + pi;//check angle if ( RotateAxisAn
gleAnotherTemp > ( 2.0 * pi )){ RotateAxisAngleAno
therTemp = RotateAxisAngleAnotherTemp - 2.0 * pi;}
if ( fabs ( RotateAxisAngleAnotherTemp -( 2.0 * pi
)) < loop_tolerance ){RotateAxisAngleAnotherTemp
= 0.0;}//compute tangentline angle for the arc end
-angle//( direction : from end-point to start-poin
t )RotateAxisAngleAnotherTemp = RotateAxisAngleAno
therTemp + 0.5 * pi;//check angle if ( RotateAxisA
ngleAnotherTemp > ( 2.0 * pi )){ RotateAxisAngleAn
otherTemp = RotateAxisAngleAnotherTemp - 2.0 * p
i;}if ( fabs ( RotateAxisAngleAnotherTemp - ( 2.0
* pi )) < loop_tolerance ){RotateAxisAngleAnotherT
emp = 0.0;}//set rotation standard angle ( clock d
irection )RotateAxisAngleAnother = RotateAxisAngle
AnotherTemp;}//step_7_1_2: multiple entities aroun
d Min_xelse{//select connected side ofentityif ( f
abs ( MinXvalueEntity->Min_X - MinXvalueEntity->ve
rtex1->X )< loop_tolerance )//get start->end //set
rotation vertex nodeRotateVertex= MinXvalueEntity
->vertex1;elseRotateVertex= MinXvalueEntity->verte
x2;switch ( MinXvalueEntity->type ){//arc type en
titycaseCK_ARC:RotateVertexFlag = F2dCleanUpArcAng
le(//inputRotateVertex, MinXvalueEntity,//output&R
otateAxisAngleTemp, &RotateAxisAngleAnotherTemp);b
reak;//line type entitycaseCK_LINE:RotateVertexFl
ag = F2dCleanUpLineAngle(//inputRotateVertex, MinX
valueEntity,//output&RotateAxisAngleTemp, &RotateA
xisAngleAnotherTemp);break;default:break;} //selec
t connected side of entityif ( RotateVertexFlag ==
1 ){//get start->end //set rotation vertex nodeRo
tateNodesTemp = MinXvalueEntity->connected_nodes_
1;RotateVertexTemp= MinXvalueEntity->vertex1;//set
another side vertex nodeRotateNodesAnotherTemp =
MinXvalueEntity->connected_nodes_2;RotateVertexAno
therTemp= MinXvalueEntity->vertex2;}else{//set rot
ation vertex nodeRotateNodesTemp = MinXvalueEntity
->connected_nodes_2;RotateVertexTemp = MinXvalueEn
tity->vertex2;//set another side vertex nodeRotate
NodesAnotherTemp = MinXvalueEntity->connected_node
s_1;RotateVertexAnotherTemp= MinXvalueEntity->vert
ex1;}//compute diff angle//for change current enti
tyRotateDiffAngleTemp = RotateAxisAngleTemp - Rota
teAxisAngle;if ( RotateDiffAngleTemp < 0.0 ){Rotat
eDiffAngleTemp = RotateDiffAngleTemp + 2.0 * pi;}i
f ( RotateDiffAngleTemp < RotateMinAngleTemp ){Rot
ateMinAngleTemp = RotateDiffAngleTemp;//set rotati
on entityRotateEntity= MinXvalueEntity;RotateNodes
= RotateNodesTemp;RotateVertex= RotateVertexTem
p;RotateNodesAnother = RotateNodesAnotherTemp;Rota
teVertexAnother = RotateVertexAnotherTemp;RotateAx
isAngleAnother =RotateAxisAngleAnotherTemp;}//step
_7_1_3: find next connected entity with first enti
ty around Min_x-vertex//check all of entities whic
h connected with first entity if ( RotateNodes
!= 0 ){ for( outside_loop_temp_list3=RotateNode
s; outside_loop_temp_list3; outside_loop_temp_li
st3= outside_loop_temp_list3->cdr){if ( outside_lo
op_temp_list3->car == NULL )break;Next_entity = ou
tside_loop_temp_list3->car;//check flagsif ( Next_
entity->flags !=1 )continue;switch ( Next_entity->
type ){//arc typeentitycaseCK_ARC:RotateVertexFla
g = F2dCleanUpArcAngle(//inputRotateVertex, Next_e
ntity, //output&RotateAxisAngleTemp, &RotateAxisAn
gleAnotherTemp);break;//line type entitycaseCK_LI
NE:RotateVertexFlag = F2dCleanUpLineAngle(//inputR
otateVertex, Next_entity, //output&RotateAxisAngle
Temp,&RotateAxisAngleAnotherTemp);break;//wrong ty
pe entitydefault:break;}//select connected side of
entityif ( RotateVertexFlag == 1 ){//get start->e
nd //set rotation vertex nodeRotateNodesTemp = Nex
t_entity->connected_nodes_1;RotateVertexTemp= Next
_entity->vertex1;//set another side vertexnodeRota
teNodesAnotherTemp = Next_entity->connected_nodes_
2;RotateVertexAnotherTemp= Next_entity->vertex2;}e
lse{//set rotation vertex nodeRotateNodesTemp = Ne
xt_entity->connected_nodes_2;RotateVertexTemp = Ne
xt_entity->vertex2;//set another side vertex nodeR
otateNodesAnotherTemp = Next_entity->connected_nod
es_1;RotateVertexAnotherTemp= Next_entity->vertex
1;}//compute diff angle//for change current entity
RotateDiffAngleTemp = RotateAxisAngleTemp - Rotate
AxisAngle;if ( RotateDiffAngleTemp < 0.0 ){RotateD
iffAngleTemp = RotateDiffAngleTemp + 2.0 * pi;}if
( fabs( RotateDiffAngleTemp - RotateMinAngleTemp )
< loop_tolerance ) {switch( Next_entity->type ){c
aseCK_ARC:switch( RotateEntity->type ){caseCK_ARC:
switch( RotateVertexFlag ){case1://no changebreak;
case2:RotateEntity= Next_entity;RotateNodes = Ro
tateNodesTemp;RotateVertex= RotateVertexTemp;Rotat
eNodesAnother = RotateNodesAnotherTemp;RotateVerte
xAnother = RotateVertexAnotherTemp;RotateAxisAngle
Another = RotateAxisAngleAnotherTemp;break;}break;
caseCK_LINE:switch( RotateVertexFlag ){case1://no
changebreak;case2:RotateEntity= Next_entity;Rotate
Nodes = RotateNodesTemp;RotateVertex= RotateVert
exTemp;RotateNodesAnother = RotateNodesAnotherTem
p;RotateVertexAnother = RotateVertexAnotherTemp;Ro
tateAxisAngleAnother = RotateAxisAngleAnotherTemp;
break;}break;}caseCK_LINE:switch( RotateEntity->ty
pe ){caseCK_ARC:if ( RotateEnt
ity−>vertex1 == RotateVer
tex ){RotateEntity= Next_
entity;RotateNodes = RotateNod
esTemp;RotateVertex= RotateVertexTemp;RotateNodesA
nother = RotateNodesAnotherTemp;RotateVertexAnothe
r = RotateVertexAnotherTemp;RotateAxisAngleAnother
= RotateAxisAngleAnotherTemp;}break;}}}if ( Rotat
eDiffAngleTemp < RotateMinAngleTemp ){RotateMinAng
leTemp =RotateDiffAngleTemp;//set rotation entityR
otateEntity= Next_entity;RotateNodes = RotateNod
esTemp;RotateVertex= RotateVertexTemp;RotateNodesA
nother = RotateNodesAnotherTemp;RotateVertexAnothe
r = RotateVertexAnotherTemp;RotateAxisAngleAnother
= RotateAxisAngleAnotherTemp;}}}}//step_7_2:find
next connected entity with first entity along the
loopF2dCleanUpFindOutNextEntity(//input RotateEnti
ty, RotateNodesAnother, RotateVertexAnother, &Rota
teAxisAngleAnother );return 0;}/*=================
================================================関
数: 名称: TestFindArrowControl記述: 手動関数。
ビユーに対して全てのアロー型エンティティを求める。
戻り値:< 0: エラー= 0: プロセスなし> 0: 成功裏に
完了; 個数は見出されたエンティティのカウンタ値であ
る。パラメータ:副関数:struct node_list *F2dClean
UpPickUpAllOneSideOpenEntity一側オープンのエンティ
ティを求める。int F2dCleanUpFindArrowアロー型エン
ティティを求める。int F2dCleanUpFindArrowEndEntity
アローエンドラインを見出す。int F2dCleanUpFindArro
wCenterEntityアローセンターラインを見出す。int F2d
CleanUpFindArrowOneSideOpenEntityアロー型の一側オ
ープンのエンティティを見出す。int F2dCleanUpComput
eCenterLineAngleセンターライン角度を計算する。int
F2dCleanUpCheckStartEndEntityスタートエンティティ
およびエンドエンティティをチェックする。int F2dCle
anUpLineAngleラインタイプエンティティの角度を計算
する。int F2dCleanUpArcAngle弓形のエンティティの角
度を計算する。int F2dCleanUpChangeChildrenFlagエン
ティティのチルドレンフラグを変更する。int F2dClean
UpChangeArrowVertexFlagアロー頂点のフラグを変更
し、アローセンターライン座標を設定する。int F2dCle
anUpChangeDrawingColorエンティティの色を変更する。
double F2dCleanUpLineLengthライン型エンティティの
長さを計算する。==================================
==============================*/intTestFindArrowCo
ntrol( int*SwitchRedraw ){//external functionsint
F2dCleanUpFindArrow();int F2dCleanUpChangeDrawingC
olor();struct node_list *F2dCleanUpPickUpAllOneSid
eOpenEntity();//entities counter and flagsint coun
t = 0,assistant_line_flag= 0;//link list and temp
liststruct node_list*Entities_change_color_list1;
//Begin//----------------------------------//Step_
1://check the number of entites// get count of al
l entities// if an error occurred, exit immidiatel
y. if (number_of_entities<0) return -1;//-----
----------------------------//Step_3: pickup all o
ne side open entitiesEntities_change_color_list1 =
F2dCleanUpPickUpAllOneSideOpenEntity( &trim_drawi
ng );if (Entities_change_color_list1 == 0) return
0;//---------------------------------//Step_4: fi
nd arrow lineF2dCleanUpFindArrow( Entities_change_
color_list1 );//---------------------------------/
/Step_X://change color to Magenta for a selected b
oundary // turn off input levels#ifdefCKWINif
( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#endi
fif ( *SwitchRedraw == 1)F2dCleanUpChangeDrawingCo
lor(&trim_drawing);//clear a flag for outside loop
processassistant_line_flag = 0;// turn ON the lev
el usedto store the trimmed entities.#ifdef CKWINi
f ( *SwitchRedraw == 1)ck_levels(CK_ON,TrimLevel,
TrimLevel);if ( *SwitchRedraw == 1)ck_redraw( CK_P
RIME_VP );#endifreturn count;}/*==================
===============================================関
数: 名称: TestFindOneSideOpen2Control記述:手動
関数。 一側がオープンで、ビユーの境界を横切るエン
ティティを全て見出す。 戻り値:< 0: エラー= 0: プ
ロセスなしパラメータ:副関数:int F2dCleanUpFindOn
eSideOpenEntity2一側がオープンで、ビユーの境界を横
切るエンティティを全て求める。int F2dCleanUpChange
DrawingColorエンティティの色を変更する。==========
==================================================
====*/intTestFindOneSideOpen2Control( int *SwitchR
edraw ){//external functionsint F2dCleanUpFindOneS
ideOpenEntity2();int F2dCleanUpChangeDrawingColo
r();//Step_1:check the number of entites// if an e
rror occurred, exit immidiately. if (number_of_
entities<0) return -1;//Step_2:pickup all oneside
open entitiesF2dCleanUpFindOneSideOpenEntity2( &t
rim_drawing );//Step_X:change color to Magenta for
a selected boundary // turn off input levels#i
fdef CKWINif ( *SwitchRedraw == 1)ck_levels(CK_OF
F,1,255);#endifif ( *SwitchRedraw == 1)F2dCleanUpC
hangeDrawingColor(&trim_drawing);// turn ON the le
vel used to store the trimmed entities.#ifdef CKWI
Nif (*SwitchRedraw == 1)ck_levels(CK_ON,TrimLevel,
TrimLevel);if ( *SwitchRedraw == 1)ck_redraw( CK_
PRIME_VP );#endifreturn 0;}/*=====================
============================================関数:
名称: TestFindOneSideOpenControl記述: 手動関
数。 ビユーに対して、一側が開放でアロー型エンティ
ティに対して垂直のものを見出す。戻り値:< 0: エラ
ー= 0: プロセスなし> 0: 成功裏に完了; この数は、見
出されたエンティティの個数。パラメータ:副関数:st
ruct node_list *F2dCleanUpPickUpAllOneSideOpenEnti
ty一側開放エンティティを求める。int F2dCleanUpChan
geChildrenFlagエンティティのチルドレンフラグを変更
する。int F2dCleanUpChangeDrawingColorエンティティ
の色を変更する。int F2dCleanUpFindOneSideOpenEntit
y一側開放エンティティを求め、それらはアロー型エン
ティティに対して垂直である。======================
==========================================*/intTes
tFindOneSideOpenControl( int *SwitchRedraw ){//ext
ernal functionsint F2dCleanUpFindOneSideOpenEntity
();int F2dCleanUpChangeDrawingColor();struct node_
list *F2dCleanUpPickUpAllOneSideOpenEntity();//ent
ities counter and flagsint count = 0,assistant_lin
e_flag = 0;//link list and temp liststruct node_li
st*Entities_list; //Begin//-----------------------
-----------//Step_1://check thenumber of entites//
if an error occurred, exit immidiately. if (nu
mber_of_entities<0) return -1;//-----------------
----------------//Step_2:pickup all one side open
entitiesEntities_list = F2dCleanUpPickUpAllOneSide
OpenEntity( &trim_drawing ); if (Entities_list
== 0) return 0;//--------------------------------
-//Step_3: find lines vertical with arrow type ent
itiesF2dCleanUpFindOneSideOpenEntity( Entities_lis
t );//---------------------------------//Step_X://
change color to Magenta for a selected boundary
// turn off input levels#ifdef CKWINif ( *Switch
Redraw== 1)ck_levels(CK_OFF,1,255);#endifif ( *Swi
tchRedraw == 1)F2dCleanUpChangeDrawingColor(&trim_
drawing);//clear a flag for outside loop processas
sistant_line_flag = 0;// turn ON the level used to
store the trimmed entities.#ifdef CKWINif ( *Swit
chRedraw == 1)ck_levels(CK_ON,TrimLevel, TrimLeve
l);if ( *SwitchRedraw == 1)ck_redraw( CK_PRIME_VP
);#endifreturn count;}/*=========================
========================================関数: 名
称: F2dCleanUpPickUpAllOneSideOpenEntity記述: 選
択図の全ての一側開放エンティティを求める。戻り値:
= 0: 成功裏に完了;パラメータ:入力: In_drawing:
図出力:NodeList:全ての一側開放エンティティに対す
るノードリスト====================================
============================*/struct node_list *F2
dCleanUpPickUpAllOneSideOpenEntity(struct drawing
*In_drawing ){//entities counter and flagsint coun
t = 0;//link list and temp liststruct node_list*En
titiesList1,*Out_temp_list; //selected entityand t
emp entitiesstruct node *entity;//initializeEntiti
esList1 =( structnode_list * ) calloc ( 1, sizeof
( struct node_list ));//set a flag forthe boundary
entitycount = 0;//check pointer about first entit
yif ( In_drawing->objects == 0 ) return0;//set a
open flagto the node//open_list->car->flags = 1;//
set the pointer to output node list//set pointer t
o first entityfor (entity=In_drawing->objects;
entity && (count<number_trimmed_entities);
entity=entity->next) {if ( entity == NULL )brea
k;if ( entity->no_connected_1 > 0 && entity->no_co
nnected_2 > 0 )continue;if ( entity->no_connected_
1 == 0 && entity->no_connected_2 == 0 )continue;
if ( entity->type != CK_LINE )continue;Entit
iesList1->car= entity;break;}//set link addressEnt
itiesList1->cdr = NULL;//-------------------------
--------//find connected entitiesif ( EntitiesList
1 == 0) return 0; if ( entity == 0 ) return 0;
if ( entity->next == 0 )return EntitiesList1;
for (entity=entity->next; entity && (coun
t<number_trimmed_entities); entity=entity-
>next) {count++;if ( entity == NULL )break;
if ( entity->type != CK_LINE )continue;if( entit
y->no_connected_1 > 0 && entity->no_connected_2 >
0 )continue;if( entity->no_connected_1 == 0 && ent
ity->no_connected_2 == 0 )continue;// allocate mem
ory for output node list elementOut_temp_list = (
struct node_list * ) calloc ( 1, sizeof ( struct n
ode_list ));// add this entityto the output node l
ist Out_temp_list->car = entity;// connect to the
output node listOut_temp_list->cdr = EntitiesList
1;// move the pointer ofoutput node list to the to
pEntitiesList1 = Out_temp_list;if ( entity->next
== NULL )break;} if (count>=number_trimmed_enti
ties) return 0;else return EntitiesList1;}/*======
==================================================
=========関数: 名称: F2dCleanUpPickUpAllArcEntit
y記述: 選択図の全てのアークエンティティを求める。
戻り値:= 0: 成功裏に完了;パラメータ:入力: In_dr
awing: 図出力:NodeList:全てのアークエンティティに
対するノードリスト================================
================================*/struct node_list
*F2dCleanUpPickUpAllArcEntity(struct drawing *In_
drawing ){//entities counter and flagsint count =
0;//link list and temp liststruct node_list*Entiti
esList1,*Out_temp_list; //selected entity and temp
entitiesstruct node *entity;//initializeEntitiesL
ist1 =( struct node_list * ) calloc ( 1, sizeof (
struct node_list ));//set a flag for the boundary
entitycount = 0;//check pointer about first entity
if ( In_drawing->objects == 0 ) return0;//set poi
nter to first entityfor (entity=In_drawing->object
s; entity && (count<number_trimmed_entities);
entity=entity->next) { if (entity
== NULL )break; if ( entity->type != CK_ARC
)continue;EntitiesList1->car = entity;break;}//se
t link addressEntitiesList1->cdr = NULL;//--------
-------------------------//find connected entities
if ( EntitiesList1 == 0 ) return 0; if ( entity
== 0 ) return 0; if ( entity->next == 0 ) retu
rn EntitiesList1; for (entity=entity->next;enti
ty && (count<number_trimmed_entities); ent
ity=entity->next){count++;if ( entity == NULL )bre
ak; if ( entity->type != CK_ARC)continue;//
allocate memory for output node list elementOut_t
emp_list =( struct node_list * ) calloc ( 1, sizeo
f ( struct node_list ));// addthis entity to the o
utput node list Out_temp_list->car = entity;// con
nect to the output node listOut_temp_list->cdr = E
ntitiesList1;// move thepointer of output node lis
t to the topEntitiesList1 = Out_temp_list;if( enti
ty->next == NULL )break;} if (count>=number_tri
mmed_entities) return 0;
else return EntitiesList1;}/*================
=================================================
関数: 名称: F2dCleanUpFindCenterLineEntity記述:
アークのセンタラインエンティティを求める。 戻り
値:= 0: 成功裏に完了し、何も見出されない。= NUM:
開放エンティティの個数副関数:int F2dCleanUpChange
ChildrenFlag未使用エンティティに対してフラグを設定
する。doubleF2dDistancePointLineアークの中心点から
エンティティまでの距離を計算する。パラメータ:入
力: 1 In_Drawing: a図2In_Entities_list: 全てのア
ークに対するノードリスト==========================
======================================*/int F2dCle
anUpFindCenterLineEntity( struct drawing *In_drawi
ng, struct node_list *In_Entities_list ){//externa
l functionsint F2dCleanUpChangeChildrenFlag();doub
leF2dDistancePointLine();double F2dCleanUpLineLeng
th();//link list and temp liststruct node_list *te
mp_list, *temp_list2, *temp_list3, *temp_list4; //
selected entity and temp entitiesstruct node *ArcE
ntity,*ViewEntity;//define 3D coordinates struct V
ectorVsp, Vep, Vp;//entities counter and flagsintc
ount = 0;//doubledoubleDistance = 0.0,DistanceView
Entity2Center = 0.0,DX = 0.0,DY = 0.0,ViewEntityLe
ngth = 0.0,Tolerance = 0.0;int CountPrompt= 0;char
message[64];//set toleranceTolerance = F2dCleanUpT
olerance;#ifdef VELLUMCountPrompt++;sprintf( messa
ge,"Start Find Center Entity %d", CountPrompt );ck
_prompt( message ); #endif // check all of ent
ities which connected with outside loop for( te
mp_list=In_Entities_list; temp_list; temp_list =
temp_list->cdr){ if ( temp_list->car == NULL )bre
ak;ArcEntity = temp_list->car;//check all of entit
ies in the viewfor( ViewEntity=In_drawing->object
s; ViewEntity; ViewEntity = ViewEntity->next){//
check flags: only no marks entities if ( ViewEntit
y->flags !=0 && ViewEntity->flags !=10 )continue;/
/check type : only line if ( ViewEntity->type != C
K_LINE )continue;//check open side: only open line
if ( ViewEntity->no_connected_1 > 0 && ViewEntity-
>no_connected_2 > 0 )continue;//check open side: t
wo side open line ( delete )if ( ViewEntity->no_co
nnected_1 == 0 && ViewEntity->no_connected_2 == 0&
& ViewEntity->line_type != CK_CENTER ){ViewEntity-
>flags = 3;continue;}//check parent open sideif (
ViewEntity->no_connected_1 == 0&& ViewEntity->line
_type != CK_CENTER ){//set center line flags ( loo
k for children )for( temp_list2=ViewEntity->parent
->children; temp_list2 && temp_list2->cdr; temp_
list2 = temp_list2->cdr){//change flag to light gr
ayif ( temp_list2->car == NULL ) break;if ( temp_l
ist2->car->vertex2 == ViewEntity->parent->vertex2
) break;}if( temp_list2->car->no_connected_2 !=
0) continue;}if ( ViewEntity->no_connected_2 == 0&
& ViewEntity->line_type != CK_CENTER ){//set cente
r lineflags ( look for children )for( temp_list3=V
iewEntity->parent->children; temp_list3 && temp_l
ist3->cdr; temp_list3 = temp_list3->cdr){//change
flag to light grayif ( temp_list3->car == NULL )
break;if ( temp_list3->car->vertex1 == ViewEntity-
>parent->vertex1 ) break;}if ( temp_list3->car->no
_connected_1 != 0) continue;}//check distance from
arc’s centerto line entityVsp.x=ViewEntity->X1;V
sp.y=ViewEntity->Y1;Vsp.z=ViewEntity->Z1;Vep.x=Vie
wEntity->X2;Vep.y=ViewEntity->Y2;Vep.z=ViewEntity-
>Z2;Vp.x=ArcEntity->CenterX;Vp.y=ArcEntity->Center
Y;Vp.z=ArcEntity->CenterZ;Distance = F2dDistancePo
intLine( Vsp, Vep, Vp );if ( Distance > Tolerance
)continue;//check bounding box : only outside and
no touchif (( ViewEntity->parent->Max_X >= ArcEnt
ity->Min_X && ViewEntity->parent->Max_X <= ArcEnt
ity->Max_X )&& ( ViewEntity->parent->Max_Y >= ArcE
ntity->Min_Y &&ViewEntity−>pare
nt−>Max_Y <= ArcEntity−>M
ax_Y )) {F2dCleanUpChange
ChildrenFlag( ViewEntity−
>parent );continue;}if
(( ViewEntity−>parent−>Mi
n_X >= ArcEntity−>Min_X &&
ViewEntity->parent->Min_X <= ArcEntity->Max_X )&&
( ViewEntity->parent->Min_Y >= ArcEntity->Min_Y
&& ViewEntity->parent->Min_Y <= ArcEntity->Max_Y
)) {F2dCleanUpChangeChildrenFlag( ViewEntity->par
ent );continue;}if (( ArcEntity->Max_X >= ViewEnti
ty->parent->Min_X&& ArcEntity->Max_X <= ViewEntity
->parent->Max_X )&& ( ArcEntity->Max_Y >= ViewEnti
ty->parent->Min_Y && ArcEntity->Max_Y <= ViewEnt
ity->parent->Max_Y )) {F2dCleanUpChangeChildrenFla
g( ViewEntity->parent );continue;}if (( ArcEntity-
>Min_X >= ViewEntity->parent->Min_X && ArcEntity-
>Min_X <= ViewEntity->parent->Max_X )&& ( ArcEntit
y->Min_Y >= ViewEntity->parent->Min_Y && ArcEnti
ty->Min_Y <= ViewEntity->parent->Max_Y )) {F2dClea
nUpChangeChildrenFlag( ViewEntity->parent );contin
ue;}//check distance from arc to entityViewEntityL
ength = F2dCleanUpLineLength(ViewEntity->parent);D
X = 0.5*(ViewEntity->parent->Min_X+ViewEntity->par
ent->Max_X) -ArcEntity->CenterX;DY = 0.5*(ViewEnti
ty->parent->Min_Y+ViewEntity->parent->Max_Y) - Arc
Entity->CenterY;DistanceViewEntity2Center = sqrt(D
X*DX+DY*DY) - ArcEntity->Radius - 0.5*ViewEntityLe
ngth;if ( DistanceViewEntity2Center <= ViewEntityL
ength ){F2dCleanUpChangeChildrenFlag( ViewEntity->
parent );continue;}//set center line flags ( look
for children )for( temp_list4=ViewEntity->parent->
children; temp_list4; temp_list4 = temp_list4->c
dr){//change flag to light grayif ( temp_list4->ca
r == NULL ) break;temp_list4->car->flags = 10;coun
t++;}if ( ViewEntity->next == NULL )break;}}#ifdef
VELLUMCountPrompt++;sprintf( message,"Finished fi
nd centerEntity %d", CountPrompt );ck_prompt( mess
age ); #endif//normal endreturn count;}/*========
==================================================
=======関数: 名称: F2dCleanUpFindInSideEntity記
述: アウトサイドループに対するインサイドエンティ
ティを求める。戻り値:= 0: 成功裏に完了し、何も見
出されない;= NUM: 開放エンティティの個数副関数:int
F2dCleanUpChangeChildrenFlag未使用エンティティに
対するフラグを設定する。パラメータ:入力:1 In_Dra
wing: a図2 In_Entities_list: 外側ループに対するノ
ードリスト========================================
========================*/int F2dCleanUpFindInSide
Entity( struct drawing *In_drawing, struct node_li
st *In_Entities_list ){//external functionsint F2d
CleanUpChangeChildrenFlag();//link list and temp l
iststruct node_list *temp_list, *temp_list2,*NewNo
deList, *NewNodeListTemp; struct group *NewGroup,*
temp_group_list; struct bounding_box *NewBoundBo
x;//selected entity and temp entitiesstruct node*O
utsideEntity,*ViewEntity;//entities counter and fl
agsint count = 0,NoFlag = 0;//doubledoubleToleranc
e = 0.0;//set toleranceTolerance = F2dCleanUpToler
ance;//initializeNewGroup = (struct group *)calloc
(1,sizeof(struct group ));NewBoundBox = (struct bo
unding_box *)calloc(1,sizeof(structbounding_box
));NewNodeList = (struct node_list *)calloc(1,siz
eof(struct node_list ));//set group dataNewGroup->
next = NULL;NewGroup->box = NewBoundBox;// check a
ll of entities which connected with outside loop
for( temp_list=In_Entities_list; temp_list; //&
& temp_list->cdr; temp_list = temp_list->cdr){if
( temp_list->car == NULL ) break;OutsideEntity= te
mp_list->car;//check entity : only boundary group
( flags = 1 and 4) if ( OutsideEntity->flags != 1
&& OutsideEntity->flags != 4 )continue;if ( !Outsi
deEntity ){NoFlag = 1;break;}NewGroup->box->Min_X
= OutsideEntity->Min_X;NewGroup->box->Max_X = Outs
ideEntity->Max_X;NewGroup->box->Min_Y = OutsideEnt
ity->Min_Y;NewGroup->box->Max_Y = OutsideEntity->M
ax_Y;break;}if ( NoFlag == 1 )return0; NewNodeL
ist->car = OutsideEntity;NewNodeList->cdr = NULL;/
/ check first groupif( In_drawing->views == NULL)
{NewGroup->index = 1;In_drawing->views = NewGrou
p;}else{//check group number for( temp_group_li
st= In_drawing->views; temp_group_list; //&&temp_
group_list->next; temp_group_list = temp_group_li
st->next){if ( temp_group_list->next == NULL ){New
Group->index = (temp_group_list->index)+1;temp_gro
up_list->next = NewGroup;break;}}} // check con
nected entity if ( !temp_list->cdr && temp_list
->car->type != CK_ARC )return 0;// check all of en
tities which connected with outside loop if ( t
emp_list->cdr ){ for( temp_list2 = temp_list->c
dr; temp_list2;// &&temp_list2->cdr; temp_list2
= temp_list2->cdr){if ( temp_list2->car ==NULL ) b
reak;OutsideEntity = temp_list2->car;//check entit
y : only boundary group ( flags = 1 and 4 ) if ( O
utsideEntity->flags != 1 && OutsideEntity->flags !
= 4 )continue;if ( NewGroup->box->Min_X > OutsideE
ntity->Min_X )NewGroup->box->Min_X = OutsideEntity
->Min_X;if ( NewGroup->box->Max_X < OutsideEntity-
>Max_X )NewGroup->box->Max_X = OutsideEntity->Max_
X;if ( NewGroup->box->Min_Y > OutsideEntity->Min_Y
)NewGroup->box->Min_Y =OutsideEntity->Min_Y;if (
NewGroup->box->Max_Y < OutsideEntity->Max_Y )NewGr
oup->box->Max_Y = OutsideEntity->Max_Y;//allocate
memory for node list NewNodeListTemp = (struct nod
e_list *)calloc(1,sizeof(struct node_list ));//add
this entity to node list NewNodeListTemp->car = O
utsideEntity;//connect to the node list NewNodeLis
tTemp->cdr = NewNodeList;//move the pointer of the
node list to the topNewNodeList = NewNodeListTem
p;count++;}}//check all of entities in the viewfor
( ViewEntity=In_drawing->objects; ViewEntity; Vi
ewEntity = ViewEntity->next){//check flags: only n
o marks entities if ( ViewEntity == NULL )break;i
f ( ViewEntity->flags!=0 )continue;//check boundi
ng box: only inside entities if (( NewGroup->box->
Min_X <= ViewEntity->Min_X ) &&( NewGroup->box->M
ax_X >= ViewEntity->Max_X ) &&( NewGroup->box->Mi
n_Y <= ViewEntity->Min_Y ) &&( NewGroup->box->Max
_Y >= ViewEntity->Max_Y )){//set flag ViewEntity->
flags = 7;//allocate memory for node list NewNodeL
istTemp = (struct node_list *)calloc(1,sizeof(stru
ct node_list ));//add this entity to node list New
NodeListTemp->car = ViewEntity;//connect to the no
de list NewNodeListTemp->cdr = NewNodeList;//move
the pointer of the node list to the topNewNodeList
= NewNodeListTemp;count++;}}//set node list to gr
oup NewGroup->entities = NewNodeList;//normal endr
eturn count;}/*===================================
==============================関数: 名称: F2dCle
anUpFindOnesideOpenConnectEntityNext記述: 一側オ
ープンエンティティに接続された次のエンティティを求
める。戻り値:= Out_entity: 成功裏に完了;パラメー
タ:入力: 1 In_entity: エンティティ =============
==================================================
=*/struct node *F2dCleanUpFindOnesideOpenConnectEn
tityNext(struct node *In_entity){//selected entity
and temp entitiesstructnode *Out_entity;//link li
st and temp liststruct node_list *TempList1,*TempL
ist2, *TempList3, *NextNodes;//defineintFlag1 = 0,
Flag2 = 0,Count= 0;int CountPrompt = 0;charmessage
[64];#ifdef VELLUMCountPrompt++;sprintf( message,"
Start Find One Side Open Connected Entity %d", Cou
ntPrompt);ck_prompt( message ); #endif//initializ
eOut_entity = NULL;//check input entityif ( !In_en
tity )returnOut_entity;//check open sidefor( TempL
ist1=In_entity->connected_nodes_1; TempList1; //&&
TempList1->cdr; TempList1 = TempList1->cdr){if (
TempList1->car == NULL )break;if ( TempList1->car-
>flags == 6 )Flag1 = 1;}for( TempList2=In_entity->
connected_nodes_2;TempList2; //&& TempList2->cdr;
TempList2 = TempList2->cdr){if ( TempList2->car ==
NULL )break;if ( TempList2->car->flags == 6 )Flag
2 = 1;}//first entity caseif ( Flag1 == 0 && Flag2
== 0 ) {if ( In_entity->no_connected_1 == 0 )Fla
g1 = 1;if ( In_entity->no_connected_2 == 0 )Flag2
= 1;}//finish case: returnif (( Flag1 == 0 && Flag
2 == 0 ) ||( Flag1 == 1 && Flag2 == 1 ))returnOu
t_entity;//check all of entities connected with in
put entityif ( Flag1 == 1 )NextNodes = In_entity->
connected_nodes_2;elseNextNodes = In_entity->conne
cted_nodes_1;for( TempList3= NextNodes; TempList3;
//&& TempList3->cdr; TempList3 = TempList3->cdr)
{if ( TempList3->car == NULL )break;if ( TempList3
->car->flags == 0 ){Out_entity = TempList3->car;Co
unt++;}}//check resultif ( Count != 1 )Out_entity
= NULL;#ifdef VELLUMCountPrompt++;sprintf( messag
e,"Finished one side open connected Entity %d", Co
untPrompt );ck_prompt( message ); #endifreturnOut
_entity;}/*=======================================
==========================関数: 名称: F2dCleanUp
FindOnesideOpenConnectEntity記述: 一側オープンエ
ンティティおよびそれに接続された単一エンティティを
求める。。戻り値:=0: 成功裏に完了;副関数:struct
node *F2dCleanUpFindOnesideOpenConnectEntityNext一
側開放エンティティに接続された次のエンティティを求
める。パラメータ:入力: 1 In_drawing: 図 ========
==================================================
======*/int F2dCleanUpFindOnesideOpenConnectEntity
(struct drawing *In_drawing){//external functionss
truct node *F2dCleanUpFindOnesideOpenConnectEntity
Next();//selected entity and temp entitiesstruct n
ode *entity, *FindEntity, *NextEntity;//check all
of entities on the listfor( entity=In_drawing->obj
ects; entity; entity = entity->next){if (entity
== NULL )break; if ( entity->flags != 0 )continue;
if ( entity->type != CK_LINE )continue; if ( enti
ty->no_connected_1 > 0 && entity->no_connected_2 >
0 )continue;if ( entity->no_connected_1 == 0 && e
ntity->no_connected_2 == 0 )continue;if ((entity->
no_connected_1 == 0 && entity->no_connected_2 >=
1) ||(entity->no_connected_2 == 0 && entity->no_c
onnected_1 >= 1)) {//set flagentity->flags =6;Find
Entity = entity;//find connected entityfor (;;){Ne
xtEntity = F2dCleanUpFindOnesideOpenConnectEntityN
ext( FindEntity );if ( NextEntity == NULL )break;/
/set flagFindEntity= NextEntity;FindEntity->flags
=6;}}}return 0;}/*================================
=================================関数: 名称: F2d
CleanUpFindLongestEntity記述: 図に対して最も長い
エンティティを求める。戻り値:= Entity: 成功裏に
完了;= 0: エンティティ無し;パラメータ:入力: 1 I
n_drawing: 図 ====================================
============================*/struct node *F2dClea
nUpFindLongestEntity(struct drawing *In_drawing){/
/selected entity and temp entitiesstruct node *ent
ity, *LongestEntity;//definedoubleLongestLength =
0.0,ArcLength = 0.0;//check all of entitieson the
listfor( entity=In_drawing->objects; entity; ent
ity = entity->next){//only not usedif ( entity ==
NULL )break;if ( entity->flags != 0 )continue;//ch
eck lengthif ( entity->parent->length <= LongestLe
ngth )continue; //check arc lengthif ( entity->ty
pe == CK_ARC ){ArcLength = 2.0* entity->parent->Ra
dius;if ( entity->parent->length < ArcLength)ArcLe
ngth = entity->parent->length;if ( ArcLength > Lon
gestLength ){//change max value and entityLongestL
ength = ArcLength;LongestEntity = entity;}}else{//
change max value and entityLongestLength = entity-
>parent->length;LongestEntity = entity;}}if ( Long
estLength == 0.0 )returnNULL;elsereturnLongestEnti
ty;}/*============================================
=====================関数: 名称: F2dCleanUpFindV
iews記述: 図に対するビユーのグループを求める。戻
り値:= Entity: 成功裏に完了;= 0: エンティティな
し;副関数:struct node *F2dCleanUpFindLongestEntit
y図に対する最も長いエンティティを求める。struct no
de_list *F2dCleanUpFindGroup入力エンティティと接続
されたグループエンティティを求める。struct node *F
2dCleanUpFindGroupMinXエンティティグループに対する
最小X値を求める。int F2dCleanUpFindOutSideLoopエ
ンティティグループに対する最小X値を求める。int F2
dCleanUpFindInSideEntity外側ループパラメータに対す
るインサイドエンティティを求める。パラメータ:入
力: 1 In_drawing: 図 ============================
====================================*/int F2dClean
UpFindViews( struct drawing *In_drawing ){//extern
al functionsstruct node *F2dCleanUpFindLongestEnti
ty();struct node_list *F2dCleanUpFindGroup();struc
t node *F2dCleanUpFindGroupMinX();int F2dCleanUpFi
ndOutSideLoop();int F2dCleanUpFindInSideEntity();/
/selected entity and temp entitiesstruct node *Lon
gestEntity, *MinXvalueEntity;struct node_list *Vie
wGroup;//defineint ReturnFlag = 1,NoGroup= 0,Count
= 0;doubleLongestLength = 0.0;int CountPrompt =
0;charmessage[64];//check all viewswhile( ReturnFl
ag ){#ifdef VELLUMCountPrompt++;sprintf( message,"
Start Find Views Entity %d", CountPrompt );ck_prom
pt( message ); #endif//Step_1:find a longest enti
ty for a drawingLongestEntity= F2dCleanUpFindLonge
stEntity( In_drawing );if ( LongestEntity == NULL
)ReturnFlag = 0;else {//set flagNoGroup = 1; //c
lear counterCount = 0;//Step_2:find connected grou
p with the longest entityViewGroup = F2dCleanUpFin
dGroup( LongestEntity, &Count ); //Step_3:find out
side loop entities//check a flag for outside loop
processif ( Count > 1 )MinXvalueEntity =F2dCleanUp
FindGroupMinX( ViewGroup );elseMinXvalueEntity = L
ongestEntity;if ( MinXvalueEntity == 0 )continue;/
/Step_4:find outside loop entitiesif ( Count > 1 )
F2dCleanUpFindOutSideLoop( MinXvalueEntity );elseM
inXvalueEntity->flags = 4;//Step_5:find inside ent
itiesF2dCleanUpFindInSideEntity( In_drawing, ViewG
roup );}#ifdef VELLUMCountPrompt++;sprintf( messag
e,"Finished find view Entity %d", CountPrompt );ck
_prompt( message );#endif}if ( NoGroup == 0 )retur
n-1;elsereturn0;}/*===============================
==================================関数: 名称: F2
dCleanUpFindRelativeViews記述: 相対ビユーを求め
る。 戻り値:= 0: 成功裏に完了;= 1:相対ビユーが見
出される。パラメータ:入力: 1 In_Drawing: 図2 In_
Group:グループ3 In_ToleranceViews: ビユーに対する
公差==============================================
==================*/int F2dCleanUpFindRelativeView
s(struct drawing*In_drawing,struct group*In_Group,
double *In_ToleranceViews ) {//link list and temp
liststruct group *TempGroup;struct group_list*Temp
GroupList; //entities counter and flagsint ReturnF
lag = 0;//doubledoubleTolerance = 0.0;//set tolera
nceTolerance = *In_ToleranceViews;//check viewsif
( In_drawing->views == NULL )return0;if( In_Group
== NULL )return0;for( TempGroup= In_drawing->view
s; TempGroup; //&& TempGroup->next; TempGroup =
TempGroup->next){//check same groupif ( TempGroup
== NULL)break;if ( TempGroup == In_Group )continu
e;//Step_1:check top and bottom directionif ((Temp
Group->box->Max_X>=((In_Group->box->Max_X)-Toleran
ce )) &&(TempGroup->box->Max_X<=((In_Group->box-
>Max_X)+Tolerance )) &&(TempGroup->box->Min_X>=
((In_Group->box->Min_X)-Tolerance )) &&(TempGrou
p->box->Min_X<=((In_Group->box->Min_X)+Tolerance
))) {//set return flagReturnFlag = 1;//Step_1_1:c
heck top directionif ( TempGroup->box->Min_Y > In_
Group->box->Max_Y ){//check top directionrelative
viewsif ( In_Group->to_top == NULL ){TempGroupList
= (struct group_list *)calloc(1,sizeof(struct gro
up_list ));TempGroupList->car = TempGroup;TempGrou
pList->cdr = NULL;In_Group->to_top = TempGroupLis
t;}else{//check distanceif ( In_Group->to_top->car
->box->Min_Y > TempGroup->box->Min_Y ){//change to
p viewIn_Group->to_top->car = TempGroup;}}}else//S
tep_1_2:check bottom directionif ( TempGroup->box-
>Max_Y < In_Group->box->Min_Y ){//check top direct
ionrelative viewsif ( In_Group->to_bottom == NULL
){TempGroupList = (struct group_list *)calloc(1,s
izeof(struct group_list ));TempGroupList->car = Te
mpGroup;TempGroupList->cdr = NULL;In_Group->to_bot
tom = TempGroupList;}else{//check distanceif ( In_
Group->to_bottom->car->box->Max_Y < TempGroup->box
->Max_Y ){//change top viewIn_Group->to_bottom->ca
r = TempGroup;}}}}else//Step_2:check left and righ
t directionif ((TempGroup->box->Max_Y>=((In_Group-
>box->Max_Y)-Tolerance )) &&(TempGroup->box->Max
_Y<=((In_Group->box->Max_Y)+Tolerance )) &&(TempG
roup->box->Min_Y>=((In_Group->box->Min_Y)-Toleranc
e )) &&(TempGroup->box->Min_Y<=((In_Group->box->
Min_Y)+Tolerance ))) {//set return flagReturnFlag
= 1;//Step_2_1:check right directionif ( TempGroup
->box->Min_X > In_Group->box->Max_X ){//check righ
t direction relative viewsif ( In_Group->to_right
== NULL ){TempGroupList = (struct group_list *)cal
loc(1,sizeof(struct group_list ));TempGroupList->c
ar = TempGroup;TempGroupList->cdr = NULL;In_Group-
>to_right = TempGroupList;}else{//check distanceif
( In_Group->to_right->car->box->Min_X > TempGroup
->box->Min_X ){//change left viewIn_Group->to_righ
t->car = TempGroup;}}}else//Step_2_2:check left di
rectionif ( TempGroup->box->Max_X < In_Group->box-
>Min_X ){//check left directionrelative viewsif (
In_Group->to_left == NULL ){TempGroupList = (struc
t group_list *)calloc(1,sizeof(struct group_list
));TempGroupList->car = TempGroup;TempGroupList->
cdr = NULL;In_Group->to_left = TempGroupList;}else
{//check distanceif ( In_Group->to_left->car->box-
>Max_X < TempGroup->box->Max_X ){//change right vi
ewIn_Group->to_left->car = TempGroup;}}}}}//normal
endreturn ReturnFlag;}/*=========================
========================================関数: 名
称: F2dCleanUpFindViewsRelation記述: 図に対する
ビユー関係を求める。 戻り値:= 0: 成功裏に完了する
が、何も見出されない。;=NUM: ビユーの個数副関数:i
nt F2dCleanUpFindRelativeViews相対ビユーを求める。
パラメータ:入力: 1 In_Drawing: a図==============
==================================================
*/int F2dCleanUpFindViewsRelation( struct drawing*
In_drawing ) {//external functionsint F2dCleanUpFi
ndRelativeViews();//link list and temp liststruct
group *MaxGroup,*TempGroup,*NextGroup;struct group
_list*OpenGroupList,*TempOpenGroupList,*TempGroupL
ist;struct node_list *ETL;//Entity Temp List//enti
ties counter and flagsintNoFlag = 0;//doubledouble
BiggestSize = 0.0, BiggestSizeTemp = 0.0;doubleTol
erance = 0.0,ToleranceViews = 0.0;//set toleranceT
olerance = F2dCleanUpTolerance;//check viewsif( In
_drawing->views == NULL )return0;//Step_1:get the
biggest group’s sizefor( TempGroup= In_drawing->v
iews; TempGroup; //&& TempGroup->next; TempGroup
= TempGroup->next){// clear flagsTempGroup->index
= 0;// compute size for boxBiggestSizeTemp = fabs
( TempGroup->box->Max_X - TempGroup->box->Min_X )
+ fabs( TempGroup->box->Max_Y - TempGroup->box->
Min_Y );//check sizeif ( BiggestSizeTemp > Biggest
Size ){BiggestSize = BiggestSizeTemp;MaxGroup= Tem
pGroup;}//check last oneif ( TempGroup->next == NU
LL )break;}//check views toleranceToleranceViews =
0.01 * BiggestSize;if ( ToleranceViews < Toleranc
e ) ToleranceViews = Tolerance;//Step_2:find relat
ionship for each view//initialize a open list Open
GroupList = (struct group_list *)calloc(1,sizeof(s
truct group_list ));OpenGroupList->car = MaxGroup;
OpenGroupList->cdr = NULL;// seta open flag to the
groupMaxGroup->index = 1;for ( TempGroupList = Op
enGroupList; TempGroupList; ){//get a pointer from
open list if ( TempGroupList->car == NULL )break;
NextGroup = TempGroupList->car;//set a closed flag
to the groupNextGroup->index = 2;//close the grou
p ( delete the groupfrom open list )OpenGroupList
= OpenGroupList->cdr;//get relationNoFlag= F2dClea
nUpFindRelativeViews( In_drawing, NextGroup, &Tole
ranceViews );if ( NoFlag == 0 )break;//check each
direction for the viewif ( NextGroup->to_top != NU
LL ){if ( NextGroup->to_top->car->index == 0 ){Tem
pOpenGroupList = (struct group_list *)calloc(1,siz
eof(struct group_list ));TempOpenGroupList->car =
NextGroup->to_top->car;TempOpenGroupList->cdr = Op
enGroupList;TempOpenGroupList->car->index = 1;Open
GroupList = TempOpenGroupList;}}if ( NextGroup->to
_bottom != NULL ){if ( NextGroup->to_bottom->car->
index == 0 ){TempOpenGroupList = (struct group_lis
t *)calloc(1,sizeof(struct group_list ));TempOpenG
roupList->car = NextGroup->to_bottom->car;TempOpen
GroupList->cdr = OpenGroupList;TempOpenGroupList->
car->index= 1;OpenGroupList = TempOpenGroupList;}}
if ( NextGroup->to_left != NULL){if ( NextGroup->t
o_left->car->index == 0 ){TempOpenGroupList = (str
uct group_list *)calloc(1,sizeof(struct group_list
));TempOpenGroupList->car = NextGroup->to_left->c
ar;TempOpenGroupList->cdr = OpenGroupList;TempOpen
GroupList->car->index = 1;OpenGroupList = TempOpen
GroupList;}}if ( NextGroup->to_right != NULL ){if
( NextGroup->to_right->car->index == 0 ){TempOpenG
roupList = (struct group_list *)calloc(1,sizeof(st
ruct group_list ));TempOpenGroupList->car = NextGr
oup->to_right->car;TempOpenGroupList->cdr = OpenGr
oupList;TempOpenGroupList->car->index = 1;OpenGrou
pList= TempOpenGroupList;}}//assign value to the l
oop variableTempGroupList =OpenGroupList;}//Step_
3:clear flags for no relative groupsfor( NextGroup
=In_drawing->views; NextGroup; NextGroup = NextGro
up->next){if ( NextGroup == NULL )break;if ( NextG
roup->index != 0 )continue;for ( ETL=NextGroup->en
tities; ETL; ETL=ETL->cdr ) {ETL->car->flags = 0;i
f ( ETL->cdr == NULL )break;}}//normal endreturn
0;}/*=============================================
====================関数: 名称: F2dCleanUpFindDr
awingSheet記述: 図に対する描画シートを求める。戻
り値:= -1: エラーデータ;= 0: 成功裏に完了;= 1:
シートなし;副関数:struct node_list *F2dCleanUpFin
dGroup入力エンティティと接続されたグループエンティ
ティを求める。パラメータ:入力: 1 In_drawing: 図
==================================================
==============*/int F2dCleanUpFindDrawingSheet(str
uct drawing*In_drawing,struct bounding_box *InOut_
BB,int *In_TimesFlag ){//externalfunctionsstruct n
ode_list *F2dCleanUpFindGroup();//selected entity
andtemp entitiesstruct node *entity, *LongestEntit
yX, *LongestEntityY;struct node_list*SheetGroup, *
temp_list2; //bounding boxstruct bounding_box BB,
EBB;//defineintSheetFlag = 0, count = 0,CountPromp
t = 0;doubleLongestLengthX = 0.0,LongestLengthY =
0.0,AlphaX = 0.0, AlphaY = 0.0;charmessage[64]; do
ubleTolerance = 0.0;//set toleranceTolerance = F2d
CleanUpTolerance;#ifdef VELLUMCountPrompt++;sprint
f( message,"Start Find Sheet Entity%d", CountPromp
t );ck_prompt( message ); #endif//STEP_1:look for
the longest line type parent entity //check all o
f entities on the listfor( entity=In_drawing->obje
cts; entity; entity = entity->next){//only linet
ypeif ( entity == NULL )break;if ( entity->type !=
CK_LINE )continue; //only not usedif ( entity->fl
ags != 0 )continue;//check lengthif (( entity->par
ent->length <= LongestLengthX ) &&( entity->paren
t->length <= LongestLengthY ))continue; //check h
orizontally and vertically //if angle(alpha) was s
maller than ( sin ( alpha ) = alpha )AlphaX = fabs
( ( entity->parent->Max_X - entity->parent->Min_X
)/ entity->parent->length );AlphaY = fabs( ( enti
ty->parent->Max_Y - entity->parent->Min_Y )/ entit
y->parent->length );if ( ( AlphaX > Tolerance ) &&
( AlphaY > Tolerance ) )continue;//change max val
ue and entityif ( AlphaY < Tolerance ){ if ( entit
y->parent->length > LongestLengthX ){ LongestLeng
thX = entity->parent->length;LongestEntityX = enti
ty;}}else{ if ( entity->parent->length > LongestLe
ngthY ){ LongestLengthY = entity->parent->length;
LongestEntityY= entity;}} #ifdef VELLUM//CountProm
pt++;//sprintf( message,"Sheet Entity %d", CountPr
ompt );//ck_prompt( message ); #endif}//check the
longest entitiy’s lengthif (( LongestLengthX < T
olerance ) ||( LongestLengthY < Tolerance ))retur
n-1; //set bounding boxBB.Min_X = Lo
ngestEntityX->parent->Min_X;BB.Max_X = LongestEnti
tyX->parent->Max_X;BB.Min_Y = LongestEntityY->pare
nt->Min_Y;BB.Max_Y = LongestEntityY->parent->Max_
Y;//check inside drawing sheet sizeif ( *In_TimesF
lag == 1)*InOut_BB= BB; //set valueselse{if ( (In
Out_BB->Min_X == 0.0 ) && (InOut_BB->Max_X == 0.0
) &&(InOut_BB->Min_Y == 0.0 ) && (InOut_BB->Max_Y
== 0.0 )) return0;if (( BB.Max_X - BB.Min_X ) < T
olerance )return0;if ( fabs(( InOut_BB->Max_X - In
Out_BB->Min_X ) / ( BB.Max_X - BB.Min_X )) > 1.2 )
return0;}//set a flag to entityLongestEntityX->fla
gs = 3; //STEP_2:look for connected entities group
and make boundarySheetGroup = F2dCleanUpFindGroup
( LongestEntityX, &count);if ( SheetGroup == 0 )re
turn0;//STEP_3:clear flagsfor all entitiesfor(enti
ty=In_drawing->objects; entity; entity = entity-
>next){if ( entity == NULL )break;if ( entity->fla
gs == 3 )continue;if ( entity->flags ==4 )continu
e;entity->flags = 0; }//STEP_4:set flags the group
for ( temp_list2 = SheetGroup; ( temp_list2!=0 &&
temp_list2->car!=0 );temp_list2=temp_list2
->cdr){if ( temp_list2->car == NULL )break;temp_li
st2->car->flags = 3; }//STEP_5:set expanding box
( 20% for +X,-X,+Y,-Y)EBB.Min_X = ( BB.Min_X ) -
0.2 * fabs(( BB.Max_X ) - ( BB.Min_X ));EBB.Max_X
= ( BB.Max_X ) + 0.2 * fabs(( BB.Max_X ) - ( BB.Mi
n_X ));EBB.Min_Y= ( BB.Min_Y ) - 0.2 * fabs(( BB.M
ax_Y ) - ( BB.Min_Y ));EBB.Max_Y = (BB.Max_Y ) +
0.2 * fabs(( BB.Max_Y ) - ( BB.Min_Y ));//STEP_6:c
heck outside entity( out of the bounding box ) in
the DRAWING//if any entity wasfound, no sheet was
found for this drawingfor( entity=In_drawing->obje
cts; entity; entity = entity->next){if ( entity
== NULL )break; if ( entity->flags != 0 )continue;
//look for out side entity if ( entity->Max_X> EB
B.Max_X ){ SheetFlag = 1;break;}if ( entity->Max_Y
> EBB.Max_Y ){ SheetFlag = 1;break;}if ( entity->
Min_X < EBB.Min_X ){ SheetFlag = 1;break;}if ( ent
ity->Min_Y < EBB.Min_Y ){ SheetFlag = 1;break;}}//
STEP_7:lookfor sheet data ( out side of the bounda
ry )if ( SheetFlag == 0 ){//lookfor sheet data for
( entity=In_drawing->objects; entity; entity = e
ntity->next){if ( entity == NULL )break; if ( enti
ty->flags == 3 )entity->flags = 4; if ( entity->fl
ags != 0 )continue; if (( entity->Min_X <= BB.Min_
X )||( entity->Max_X >= BB.Max_X ) ||( entity->Mi
n_Y <= BB.Min_Y )||(entity->Max_Y >= BB.Max_Y ))//
set flagentity->flags =4;}//Goodreturn 0;}//STEP_
8:clear flags ( No sheet was found ! )for( entity=
In_drawing->objects; entity; entity = entity->ne
xt){if ( entity == NULL )break;if (entity->flags =
= 4 )continue; entity->flags = 0; }if ( SheetFlag
!= 0 )return 1;#ifdef VELLUMCountPrompt++;sprintf
( message,"Finished find SheetEntity %d", CountPro
mpt );ck_prompt( message ); #endifreturn 0;}/*===
==================================================
============関数: 名称: TestFindDrawingSheetCont
rol 記述: 手動関数。図に対する描画シートを求め
る。戻り値:< 0: エラー= 0: プロセスなし> 0: 成功
裏に完了;個数は見出されたエンティティのカウンタ値
である。パラメータ:副関数:int F2dCleanUpFindDraw
ingSheet成功裏に完了;個数は見出されたエンティティ
のカウンタ値である。intF2dCleanUpChangeDrawingFlag
エンティティのフラグを変更する( 4 >>3 )===========
==================================================
===*/intTestFindDrawingSheetControl( int *SwitchRe
draw ){//external functionsint F2dCleanUpFindDrawi
ngSheet();int F2dCleanUpChangeDrawingColor();intF2
dCleanUpChangeDrawingFlag();//definestruct boundin
g_box BB;intReturnFlag= 0; intTimesFlag = 0;//----
------------------------------//Step_1:check the n
umber of entites// if an error occurred, exit immi
diately. if (number_of_entities<0)return -1;//-
--------------------------------//Step_2: find cen
ter line entitiesTimesFlag = 1;ReturnFlag = F2dCle
anUpFindDrawingSheet( &trim_drawing, &BB, &TimesFl
ag );if( ReturnFlag == 1 ) return 0;if( ReturnFlag
== -1 ) return 0;TimesFlag = 2;F2dCleanUpFindDrawi
ngSheet( &trim_drawing, &BB, &TimesFlag );//------
---------------------------//Step_3: changeflagsF2
dCleanUpChangeDrawingFlag( &trim_drawing );//-----
----------------------------//Step_X:change color
to light gray for a selected center lines // tu
rn off input levels#ifdef CKWINif ( *SwitchRedraw
== 1)ck_levels(CK_OFF,1,255);#endifif ( *SwitchRed
raw == 1)F2dCleanUpChangeDrawingColor(&trim_drawin
g);// turn ON the level used to store the trimmed
entities.#ifdef CKWINif ( *SwitchRedraw == 1)ck_le
vels(CK_ON,TrimLevel, TrimLevel);//if ( *SwitchRed
raw == 1)ck_redraw( CK_PRIME_VP );#endifreturn0;}/
*=================================================
================関数: 名称: TestFindViewsControl
記述: 手動関数。 図に対する描画シートを求める。
戻り値:< 0: 図= 0: プロセスなし> 0: 成功裏に完了;
個数は見出されたエンティティのカウンタ値である。
パラメータ:副関数:int F2dCleanUpFindViews図に対
するビューのグループを求める。int F2dCleanUpFindVi
ewsRelation図に対するビュー関係を求める。int F2dCl
eanUpChangeDrawingColor===========================
=====================================*/intTestFind
ViewsControl( int *SwitchRedraw ){//external funct
ionsint F2dCleanUpFindViews();int F2dCleanUpFindVi
ewsRelation();int F2dCleanUpChangeDrawingColor();/
/Step_1:check the number of entites// if an error
occurred, exit immidiately. if (number_of_entit
ies<0) return -1;//Step_2: find views’ group if
( F2dCleanUpFindViews( &trim_drawing ) == -1 ) re
turn -1;//Step_3: find views’ relationship //move
to delete function ( Mar. 29,1996 )//F2dCleanUpFi
ndViewsRelation( &trim_drawing );//Step_X:change c
olorto light gray for a selected center lines /
/ turn off input levels#ifdef CKWINif ( *SwitchRed
raw == 1)ck_levels(CK_OFF,1,255);#endifif ( *Switc
hRedraw == 1)F2dCleanUpChangeDrawingColor(&trim_dr
awing);// turn ON the level used to store the trim
med entities.#ifdef CKWINif ( *SwitchRedraw == 1)c
k_levels(CK_ON,TrimLevel, TrimLevel);if ( *SwitchR
edraw == 1)ck_redraw( CK_PRIME_VP );#endifreturn
0;}/*=============================================
====================関数: 名称: TestFindBoundary
Control記述: 手動関数。 ユーザがビユーの境界のエ
ンティティを選択したとき、この関数はビユーに対する
接続されたエンティティの全てを見出す。戻り値:< 0:
エラー= 0: プロセスなし> 0: 成功裏に完了; 成功裏に
完了パラメータ:副関数:int F2dCleanUpFindOutSideL
oopサイドループのエンティティを求める。int F2dClea
nUpFindInSideEntity外側ループに対するサイドエンテ
ィティを求める。int F2dCleanUpFindOutNextEntity外
側ループエンティティと接続されたエンティティを求め
る。struct node *F2dCleanUpFindGroupMinXエンティテ
ィグループに対する最小X値を求める。struct node_li
st *F2dCleanUpFindGroup入力エンティティと接続され
たグループエンティティを求める。ystruct node *F2dC
leanUpInputEntity ( old function )画面上の選択され
たエンティティを求める。intF2dCleanUpLineAngleライ
ン形エンティティの角度を計算する。int F2dCleanUpAr
cAngleアーク形エンティティの角度を求める。int F2dC
leanUpChangeChildrenFlagエンティティのチルドレンフ
ラグを変更する。int F2dCleanUpChangeArrowVertexFla
gアロートップ頂点のフラグを変更し、アローセンタラ
イン座標を設定する。int F2dCleanUpFindViewsRelatio
nl図に対するビユー関係を求める。int F2dCleanUpChan
geColorエンティティの色を変更する。 double F2dClea
nUpLineLengthライン形エンティティの長さを計算す
る。==============================================
==================*/intTestFindBoundaryControl( in
t *SwitchRedraw ){//external functions
int F2dCleanUpChangeDrawingCol
or();int F2dCleanUpFindOutSideLoop();int F2dCleanU
pFindInSideEntity();int F2dCleanUpFindViewsRelatio
n();struct node *F2dCleanUpInputEntity();struct no
de *F2dCleanUpFindGroupMinX();struct node_list *F2
dCleanUpFindGroup();//entities counter and flagsin
t count = 0;//link list and temp liststruct node_l
ist *Entities_list; //selected entity and temp ent
itiesstruct node *entity,*MinXvalueEntity;//Begin
//----------------------------------//Step_1://che
ck the number of entites// get count of all entit
ies// if an error occurred, exit immidiately. i
f (number_of_entities<0) return -1;for( ; ; ){//-
--------------------------------//Step_2:select on
e entityentity = F2dCleanUpInputEntity( "Select aB
oundary Entity for a view",&trim_drawing);if ( ent
ity == 0 )return0;if( entity->flags != 0 )continu
e;//---------------------------------//Step_3: fin
d a connected entities groupEntities_list = F2dCle
anUpFindGroup(entity, &count );//-----------------
----------------//Step_4:find outside loop entitie
s without assistant entities//check a flag for out
side loop processif ( count < 1 )continue;MinXvalu
eEntity = F2dCleanUpFindGroupMinX( Entities_list);
if ( MinXvalueEntity == 0 )continue;//------------
---------------------//Step_5:find outside loop en
titiesF2dCleanUpFindOutSideLoop( MinXvalueEntity
);//---------------------------------//Step_6:fin
d inside entitiesF2dCleanUpFindInSideEntity( &trim
_drawing, Entities_list );//----------------------
-----------//Step_7: find views’ relationship //m
ove delete function (Mar.29, 1996 By Ji )//F2dClea
nUpFindViewsRelation( &trim_drawing );//----------
-----------------------//Step_X:change color to Ma
genta for a selected boundary // turn off input
levels#ifdef CKWINif ( *SwitchRedraw == 1)ck_leve
ls(CK_OFF,1,255);#endifF2dCleanUpChangeDrawingColo
r(&trim_drawing);// turn ON the level used to stor
ethe trimmed entities.#ifdef CKWINif ( *SwitchRedr
aw == 1)ck_levels(CK_ON,TrimLevel, TrimLevel);if
( *SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );#end
if}return count;}/*===============================
==================================関数: 名称: Te
stFindCenterLineControl記述: 手動関数。ビユー中の
全てのアークに対するセンタラインを見出す。戻り値:
< 0: エラー= 0: プロセスなし> 0: 成功理に完了; 成
功理に完了パラメータ:副関数:struct node_list *F2
dCleanUpPickUpAllArcEntity選択された図中の全てのア
ークエンティティを求める。int F2dCleanUpChangeDraw
ingColorエンティティの色を変更する。==============
==================================================
*/intTestFindCenterLineControl( int *SwitchRedraw
){//external functionsint F2dCleanUpFindCenterLin
eEntity();int F2dCleanUpChangeDrawingColor();struc
t node_list *F2dCleanUpPickUpAllArcEntity();//link
list and templiststruct node_list*Entities_list;
//Begin//----------------------------------//Step_
1:check the number of entites// if an error occurr
ed, exitimmidiately. if (number_of_entities<0)
return -1;//---------------------------------//S
tep_2: pickup all arc entitiesEntities_list = F2dC
leanUpPickUpAllArcEntity( &trim_drawing ); if
(Entities_list == 0) return 0;//-----------------
----------------//Step_3: find center line entitie
sF2dCleanUpFindCenterLineEntity( &trim_drawing, En
tities_list );//---------------------------------/
/Step_X:change color to light gray for aselected c
enter lines // turn off input levels#ifdef CKWI
Nif ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#
endifif ( *SwitchRedraw == 1)F2dCleanUpChangeDrawi
ngColor(&trim_drawing);// turn ON the level used t
o store the trimmed entities.#ifdef CKWINif ( *Swi
tchRedraw == 1)ck_levels(CK_ON,TrimLevel, TrimLeve
l);if ( *SwitchRedraw == 1)ck_redraw( CK_PRIME_V
P);#endifreturn 0;}/*=============================
====================================関数: 名称:
TestFindOneSideOpenConnectControl 記述: 手動関
数。 一側オープン接続エンティティを見出す。戻り
値:< 0: エラー= 0: プロセスなし> 0: 成功裏に完了;
数は見出されたエンティティのカウンタ値である。パ
ラメータ:副関数:int F2dCleanUpFindOnesideOpenCon
nectEntity一側開放接続エンティティを求める。======
==================================================
========*/intTestFindOneSideOpenConnectControl( in
t *SwitchRedraw ){//external functionsint F2dClean
UpFindOnesideOpenConnectEntity();int F2dCleanUpCha
ngeDrawingColor();//------------------------------
----//Step_1:check the number of entites// if an e
rror occurred, exit immidiately. if (number_of_
entities<0) return -1;//-------------------------
--------//Step_2: find center line entitiesF2dClea
nUpFindOnesideOpenConnectEntity( &trim_drawing );/
/---------------------------------//Step_X:change
color to light gray for a selected center lines
// turn off input levels#ifdef CKWINif ( *Switch
Redraw == 1)ck_levels(CK_OFF,1,255);#endifif ( *Sw
itchRedraw == 1)F2dCleanUpChangeDrawingColor(&trim
_drawing);// turn ON the level used to store the t
rimmed entities.#ifdef CKWINif( *SwitchRedraw ==
1)ck_levels(CK_ON,TrimLevel, TrimLevel);if ( *Swit
chRedraw == 1)ck_redraw( CK_PRIME_VP );#endifretur
n 0;}/*===========================================
======================関数: 名称: TestFindSameCo
lorControl記述: 手動関数。同じ色のエンティティを
見出す。戻り値:= 0:成功裏に完了;数は見出されたエ
ンティティのカウンタ値である。パラメータ:副関数:
struct node *F2dCleanUpInputEntity ( old function
)画面上の選択されたエンティティを求める。int F2dC
leanUpFindSameColorEntity選択されたエンティティに
より同じ色のエンティティを求める。int F2dCleanUpCh
angeDrawingColorエンティティの色を変更する。======
==================================================
========*/intTestFindSameColorControl(){//external
functionsint F2dCleanUpChangeDrawingColor();int F2
dCleanUpFindSameColorEntity();struct node *F2dClea
nUpInputEntity();//selected entity and tempentitie
sstruct node*entity;//Begin//---------------------
-------------//Step_1://check the number of entite
s// if an error occurred, exit immidiately. if
(number_of_entities<0) return -1;for( ; ; ){//---
------------------------------//Step_2:select one
entityentity = F2dCleanUpInputEntity( "Select a Un
use Color Entity",&trim_drawing);if ( entity == 0
)return0;if ( entity->flags != 0 )continue;//----
-----------------------------//Step_3: find a conn
ected entities groupF2dCleanUpFindSameColorEntity
( entity, &trim_drawing );//----------------------
-----------//Step_X:change color to Magenta for a
selected boundary // turn off input levels#ifde
f CKWIN ck_levels(CK_OFF,1,255);#endifF2dCleanU
pChangeDrawingColor(&trim_drawing);// turn ON the
level used to store the trimmed entities.#ifdef CK
WIN ck_levels(CK_ON,TrimLevel, TrimLevel);if (
*SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );#endi
f}return 0;}/*====================================
=============================関数: 名称: TestFin
dSelectSingleControl記述: 手動関数。使用エンティ
ティを見出す。戻り値:= 0:成功裏に完了; パラメー
タ:副関数:struct node *F2dCleanUpInputEntity (古
い関数 )画面上の選択されたエンティティを求める。==
==================================================
============*/intTestFindSelectSingleControl(){//e
xternal functionsstruct node *F2dCleanUpInputEntit
y();//selectedentity and temp entitiesstruct node*
entity;//entity’s specifitysCK_ENTATTattr;//speci
ficity of entities//Begin//-----------------------
-----------//Step_1:check the number of entites//
if an error occurred, exit immidiately. if (num
ber_of_entities<0) return -1;for( ; ; ){//-------
--------------------------//Step_2:select one enti
tyentity = F2dCleanUpInputEntity( "Select an Unuse
Entity", &trim_drawing);if ( entity == 0 )return
0;//---------------------------------//Step_3: cha
nge flagif ( entity->flags == 7 ){entity->flags =
0;attr.color = CK_BLUE; }elseif ( entity
->flags == 0 ){entity->flags = 7;attr.color =
CK_YELLOW;}elsereturn0;//------------------------
---------//Step_X:change color tolight gray for un
use entity // turn off input levels// ck_lev
els(CK_OFF,1,255);ck_setattr( entity->id, CK_COLO
R, NULL, &attr );// turn ONthe level used to store
the trimmed entities.// ck_levels(CK_ON,TrimLe
vel, TrimLevel);ck_redraw( CK_PRIME_VP );}return
0;}/*=============================================
====================関数: 名称: TestUnselectSing
leControl記述: 手動関数。使用エンティティをクリア
する。戻り値:=0: 成功裏に完了;パラメータ:副関
数:struct node *F2dCleanUpInputEntity (old functi
on )画面上の選択されたエンティティを求める。======
==================================================
========*/intTestUnselectSingleControl(){//externa
l functionsstruct node *F2dCleanUpInputEntity();//
selected entity and temp entitiesstruct node*entit
y;//entity’s specifitysCK_ENTATTattr;//specificit
y of entities//Begin//----------------------------
------//Step_1:check the number of entites// if an
error occurred, exitimmidiately. if (number_of
_entities<0) return -1;for( ; ; ){//-------------
--------------------//Step_2:select one entityenti
ty = F2dCleanUpInputEntity( "Select an Entity to r
elease",&trim_drawing);if ( entity == 0 )return0;/
/---------------------------------//Step_3: change
flagif( entity->flags != 3&& entity->flags != 4 &
& entity->flags != 10 ) continue;entity->flags =
0;//---------------------------------//Step_X:chan
gecolor to light gray for unuse entity // turn
off input levels ck_levels(CK_OFF,1,255);attr.c
olor = entity->color;ck_setattr( entity->id,CK_COL
OR, NULL, &attr );// turn ON the level used to sto
re the trimmed entities. ck_levels(CK_ON,TrimLe
vel, TrimLevel);ck_redraw( CK_PRIME_VP);}return
0;}/*=============================================
====================関数: 名称: TestClearKeepFla
gsControl記述: 手動関数。全ての選択されたエンティ
ティを戻す。戻り値:= 0: 成功裏に完了;パラメータ:
副関数:int F2dCleanUpClearDrawingKeepFlagsエンテ
ィティの色を元に変更するが、フラグは維持する。====
==================================================
==========*/intTestClearKeepFlagsControl( int *Swi
tchRedraw ){//external functionsint F2dCleanUpClea
rDrawingKeepFlags();//Begin//---------------------
-------------//check the number of entites// if an
error occurred, exit immidiately. if (number_o
f_entities<0) return -1;//-----------------------
---------- // turn off input levels#ifdef CKWIN
if ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#e
ndifF2dCleanUpClearDrawingKeepFlags(&trim_drawin
g);if ( *SwitchRedraw == 1)ck_redraw( CK_PRIME_VP
);// turn ON the level used tostore the trimmed e
ntities.#ifdef CKWINif ( *SwitchRedraw == 1)ck_lev
els(CK_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw
== 1)ck_redraw( CK_PRIME_VP );#endifreturn0;}/*==
==================================================
=============関数: 名称: TestClearControl記述:
手動関数。全ての選択されたエンティティを元に戻す。
戻り値:= 0: 成功裏に完了;パラメータ:副関数:int
F2dCleanUpClearDrawingEntityエンティティの色を元に
戻す。============================================
====================*/intTestClearControl( int *Sw
itchRedraw ){//external functionsint F2dCleanUpCle
arDrawingEntity();//Begin//-----------------------
-----------//check the number of entites// if an e
rror occurred, exit immidiately. if (number_of_
entities<0) return -1;//-------------------------
-------- // turn off input levels#ifdef CKWINif
( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#end
ifF2dCleanUpClearDrawingEntity(&trim_drawing);// t
urn ON the levelused to store the trimmed entitie
s.#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels(CK
_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw == 1)
ck_redraw(CK_PRIME_VP );#endifreturn0;}/*=========
==================================================
======関数: 名称: TestDeleteControl記述: 手動関
数。全ての選択されたエンティティを削除する。戻り
値:= 0: Completed successfully;パラメータ:副関
数:int F2dCleanUpDeleteDrawingEntity全てエンティ
ティを削除する。==================================
==============================*/intTestDeleteContr
ol( int *SwitchRedraw ){//external functionsint F2
dCleanUpDeleteDrawingEntity();//Begin//-----------
-----------------------//check the number of entit
es// if an error occurred, exit immidiately. if
(number_of_entities<0) return -1; //Step_
7: find views’ relationship //move from find boun
dary function (Mar.29, 1996 By Ji)F2dCleanUpFindVi
ewsRelation( &trim_drawing );//-------------------
--------------#ifdef CKWIN
if ( *SwitchRedraw == 1)ck_levels
(CK_OFF,1,255);#endif// turn ON the level used tos
tore the trimmed entities.F2dCleanUpDeleteDrawingE
ntity(&trim_drawing);#ifdef VELLUMif ( *SwitchRedr
aw == 1)F2dCleanUpChangeDrawingColor(&trim_drawin
g);#endif#ifdef CKWINif ( *SwitchRedraw == 1)ck_le
vels(CK_ON,TrimLevel, TrimLevel);if ( *SwitchRedra
w == 1)ck_redraw( CK_PRIME_VP );#endifreturn0;}/*=
==================================================
==============関数: 名称: TestBackColorControl記
述: 元に戻す。戻り値:= 0: 成功裏に完了;パラメー
タ:副関数:int F2dCleanUpUndo元に戻す。==========
==================================================
====*/intTestBackColorControl( int *SwitchRedraw )
{//external functionsint F2dCleanUpChangeDrawingCo
lor();if( *SwitchRedraw == 1)F2dCleanUpChangeDrawi
ngColor(&trim_drawing);return0;}/*================
=================================================
関数: 名称: TestUndoControl記述: 元に戻す。戻り
値:= 0: 成功裏に完了;パラメータ:副関数:int F2dC
leanUpUndo元に戻す。==============================
==================================*/intTestUndoCon
trol( int *SwitchRedraw ){//external functionsint
F2dCleanUpUndo();//check the number of entites :
if an error occurred, exit immidiately. if (num
ber_of_entities<0) return -1;//Step_1: get flags
if ( F2dCleanUpUndo( &trim_drawing) == 0 ) return
0;#ifdef CKWIN
if ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,25
5);#endif// turn ON the level used to store the tr
immed entities.#ifdef VELLUMif ( *SwitchRedraw ==
1)F2dCleanUpChangeDrawingColor(&trim_drawing);#end
if#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels(CK
_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw== 1)c
k_redraw( CK_PRIME_VP );#endifreturn0;}/*=========
==================================================
======関数: 名称: TestUndoPreControl記述: 元に
戻す準備をする。戻り値:= 0: 成功裏に完了; パラメ
ータ:副関数:int F2dCleanUpUndoPre元に戻す準備を
する。============================================
====================*/intTestUndoPreControl( int *
SwitchRedraw ){//external functionsint F2dCleanUpU
ndoPre();//check the numberof entites: if an error
occurred, exit immidiately. if (number_of_enti
ties<0) return -1;//Step_1: get flags F2dCleanUpU
ndoPre( &trim_drawing );return0;}/*===============
==================================================
関数: 名称: TestSetUndoFlagViewsControl記述: 元
に戻すためフラグを設定する。flag=0:ビューが存在し
ない。flag=1: ビューが存在する。戻り値:= 0: 成功
裏に完了; パラメータ:============================
====================================*/intTestSetUn
doFlagViewsControl( int *SwitchRedraw ){ //set
flag F2dCleanUpExcutedNo = 1; return0;}/*関
数:==============================================
==================名称:TestDeleteViewsControl記
述: ビユーを削除する。戻り値:= 0: 成功裏に完了;
パラメータ:副関数:int F2dCleanUpDeleteViewsビユ
ーを削除する。====================================
============================*/intTestDeleteViewsCo
ntrol( int *SwitchRedraw ){//external functionsint
F2dCleanUpDeleteViews();//check the number of ent
ites: if an error occurred, exit immidiately. i
f (number_of_entities<0) return -1;//delete views
F2dCleanUpDeleteViews( &trim_drawing );return0;}s
truct node *F2dCleanUpInputEntity(char *prompt, s
truct drawing *select_drawing){int etype, count, s
tat;unsigned long entid;struct node *entity;//CK_
ENTATT attr;if (( ck_getent(prompt, &etype, &enti
d) != CK_NOERROR) || ( stat == CK_BACKUP ) || (sta
t == CK_ESCAPE )) return 0;#ifdef DEBUGprint("ID:
%ld; #",entid);#endifcount=0; for (entity=selec
t_drawing->objects; entity && (count<numb
er_trimmed_entities) && (entity->id !=entid) && (e
ntity->highlighted_id !=entid); entity=en
tity->next) count++;if (count>=number_
trimmed_entities) return 0;else return entity;}/*=
==================================================
==============関数: 名称: F2dVector記述: ライン
のユニットベクトルを計算する。戻り値:= Out_v: 成
功裏に完了;パラメータ:入力: 1 In_sp: ラインエン
ティティ開始点座標2 In_ep: インエンティティ終了点
座標出力:1Out_v: ラインエンティティベクトル======
==================================================
========*/struct Vector F2dVector( struct Vector I
n_sp, struct Vector In_ep ){struct VectorOut_v;Out
_v.x = In_ep.x - In_sp.x;Out_v.y = In_ep.y - In_s
p.y;Out_v.z = In_ep.z - In_sp.z;returnOut_v;}/*===
==================================================
============関数: 名称: F2dVectorUnit記述: ライ
ンのユニットベクトルを計算する。戻り値:= Out_n:
成功裏に完了;< 0: エラーパラメータ:入力: 1 In_v:
ラインエンティティベクトル 出力:1 Out_n: ライン
エンティティユニットベクトル======================
===========================================*/struc
t VectorF2dVectorUnit(struct VectorIn_v){struct Ve
ctorOut_n;doubleLength = 0.0;//tolerancedoubletole
rance = 0.0;tolerance = F2dCleanUpTolerance;Length
= sqrt( In_v.x*In_v.x + In_v.y*In_v.y + In_v.z*In
_v.z );//check lengthif (Length < tolerance )retur
nOut_n;Out_n.x = In_v.x / Length;Out_n.y = In_v.y
/ Length;Out_n.z = In_v.z / Length;returnOut_n;}/*
==================================================
===============関数: 名称: F2dDistancePointLine
記述: 点からラインまでの距離を計算する。戻り値:=
0: 成功裏に完了;パラメータ:入力: 1 In_sp: ライ
ンエンティティ開始点座標2 In_ep: ラインエンティテ
ィ終了点座標3 In_p: 点座標出力:1 Out_d: 距離 ===
==================================================
===========*/doubleF2dDistancePointLine(//inputstr
uct Vector In_sp, struct Vector In_ep, struct Vect
or In_p ){//external functionsstruct Vector F2dVec
tor();struct Vector F2dVectorUnit();//definestruct
VectorVe, Vne, Vp;double Out_d=0.0;//get vectorVe
= F2dVector( In_sp, In_ep );Vp = F2dVector( In_s
p, In_p );//get unitvectorVne = F2dVectorUnit( Ve
);//compute distanceOut_d = sqrt( Vp.x*Vp.x + V
p.y*Vp.y-(Vp.x*Vne.x + Vp.y*Vne.y) * (Vp.x*Vne.x +
Vp.y*Vne.y) );return Out_d;} 付録E ベンドモデルビユワ実施の例; CBendCADViewPartメンバ
関数の実施およびメニュー駆動関数の実施を含む。
【0295】//#include "stdafx.h"// include all BM
API files#include "ALLBMAPI.HXX"//RW_DRAW library
include file.#include "RW_DRAW.HXX"#include "BendC
AD.h"#include "BendCADDoc.h"#include "BendCADViewP
art.h"// RenderWare includefiles; found in \rwwin\
include#include "rwlib.h"// OpenGL include files.#
include "gl\gl.h"#include "gl\glu.h"// GL_LIST lib
rary include file.#include "GL_LIST.HXX"#include <
stdlib.h> // Orthoview dialog include file#inclu
de "OrthoViewDlg.h"///////////////////////////////
//////////////////////////////////////////////#def
ine WINDOWTITLE "BAJA CAD SYSTEM"static void multi
ply_pt_by_matrix(BM_POINT *point, float rot_matrix
[4][4]);static RwClump * RWCALLBACK do_transformat
ions(RwClump *clump, void *matrix);static RwClump
* RWCALLBACK clear_scene(RwClump *clump);static Rw
Polygon3d * RWCALLBACK SetPolygonColor(RwPolygon3d
*polygon, void *color);// The following variables
are defined to set up the color palette of the sc
reen.unsigned char threeto8[8] = {0, 0111>>1, 0222
>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377};uns
igned char twoto8[4] = {0, 0x55, 0xaa, 0xff};unsig
ned char oneto8[2] = {0, 255};static int defaultOv
erride[13] ={0, 3, 24, 27, 64, 67, 88, 173, 181, 2
36, 247, 164, 91};static PALETTEENTRY defaultPalEn
try[20] = {{ 0, 0, 0, 0 },{ 0x80,0, 0,
0 },{ 0, 0x80,0, 0 },{ 0x80,0x80,0, 0 },
{ 0, 0, 0x80, 0 },{ 0x80,0, 0x80, 0 },{ 0,
0x80,0x80, 0 },{ 0xC0,0xC0,0xC0, 0 },{ 192, 220,1
92, 0 },{ 166, 202, 240, 0 },{ 255, 251, 240, 0
},{ 160, 160, 164,0 },{ 0x80,0x80,0x80, 0 },{ 0xF
F,0, 0, 0 },{ 0, 0xFF,0, 0 },{0xFF,0xFF,
0, 0 },{ 0, 0, 0xFF, 0 },{ 0xFF,0, 0xFF,
0 },{ 0, 0xFF,0xFF, 0 },{ 0xFF,0xFF,0xFF, 0 }};v
oid PrintString(char *s){}// Thisfunction initiali
zes the RenderWare library, creates a scene, camer
a andlight.int CBendCADViewPart::Init3D(HWND windo
w) {BOOL berr = FALSE;// Open the RenderWare libra
ry. if (!RwOpen("MSWindows", NULL)) {::Messa
geBox(window, "Could not open th
e RenderWare library", WINDOWTIT
LE, MB_OK | MB_ICONSTOP | MB_APPLMODAL); re
turn 0; }// Create a camera.RwInt32 x_size, y_s
ize;x_size = GetSystemMetrics(SM_CXFULLSCREEN); //
The camera should be ableto displayy_size = GetSy
stemMetrics(SM_CYFULLSCREEN); // on the maximumsiz
e allowed by the screen. m_camera = RwCreateCam
era(x_size, y_size, NULL);if( ! m_camera) { ::M
essageBox(window, "Could not create camera",
WINDOWTITLE, MB_OK | MB_ICONSTOP | M
B_APPLMODAL); return 0;}else { RwSetCameraProj
ection(m_camera, rwPARALLEL); RwWCMoveCamera(m_c
amera, 0.0f, 0.0f, 10000.0f); // Move camera far a
way from xy plane. RwSetCameraViewport(m_camera,
0, 0, x_size, y_size); // Default sizes of viewing
volume RwSetCameraViewwindow(m_camera, (floa
t)(x_size), (float)(y_size)); // and viewport.}//
Create a scene. m_scene = RwCreateScene(); i
f (m_scene == NULL) { RwDestroyCamera(m_
camera); m_camera = NULL; RwClose();
::MessageBox(window, "Could not create the
3D Scene", WINDOWTITLE, MB_OK |
MB_ICONSTOP | MB_APPLMODAL); return 0;
}// Createlights.m_lights.RemoveAll();RwLight* l
ight1 = RwCreateLight(rwDIRECTIONAL, 0.7f, -0.7f,
-0.7f, 0.8f); //- good cornerRwLight* light2 = RwC
reateLight(rwDIRECTIONAL, -1.0f, 1.0f, -1.0f, 0.25
f);RwLight* light3 = RwCreateLight(rwPOINT, CREAL
(0.0), CREAL(0.0), CREAL(0.0), CREAL(1.0));if(ligh
t1) {m_lights.Add(light1);RwAddLightToScene(m_sce
ne, light1);}elseberr= TRUE;if(light2) {m_lights.
Add(light2);RwAddLightToScene(m_scene, light2);}el
seberr = TRUE;if(light3) {m_lights.Add(light3);Rw
AddLightToScene(m_scene, light3);}elseberr = TRUE;
if (berr) AfxMessageBox("Could not create light so
urce");//RwSetLightState(m_light, rwON);//RwSetLig
htColor(m_light, CREAL(1.0), CREAL(1.0), CREAL(1.
0));return 1;}// This function is used by the docu
ment class to initialize certain // parameters whe
never a new part is loaded. What we do here is com
pute the centroid,// prepare RenderWare clumps and
show the part as requested - wireframe/shaded if
show_solid is 0/1,// flat/3d version of part if sh
ow_3d is 0/1.void CBendCADViewPart::new_part_init
(int show_solid, int show_3d){ int i; BM_PART *p
art = NULL; CBendCADDoc* pDoc = GetDocument(); A
SSERT_VALID(pDoc); part = pDoc->get_part(); if(!
part) { mi_part_is_up_to_date = 0; return; }
mi_part_is_up_to_date = 1; compute_part_centroi
d(part, 0, &m_flat_part_centroid); // Compute 3d a
nd flat part centroids. compute_part_centroid(par
t, 1, &m_3d_part_centroid); m_part_centroid = m_
3d_part_centroid; mi_show_3d = show_3d;
mi_show_solid = show_solid; // Cle
ar out any RenderWare clumps around. if(m_flat_ba
se_clump) { RwRemoveClumpFromScene(m_flat_base_
clump); RwDestroyClump(m_flat_base_clump); m
_flat_base_clump = NULL; } if(m_3d_base_clump)
{ RwRemoveClumpFromScene(m_3d_base_clump); R
wDestroyClump(m_3d_base_clump); m_3d_base_clump
= NULL; } m_base_clump = NULL;if(mi_show_3d)
{ // Prepare 3d solid or 3d wireframe. m_pa
rt_centroid = m_3d_part_centroid; if(! mi_show_so
lid) { // Prepare wireframe. i = prepare_d
isplay_list(part, mi_show_3d, 1, 0, 1, 1, md_face_
color, md_bendline_color); if(! i) { m
i_display_list_is_up_to_date = 0; return;
} mi_display_list_is_up_to_date = 1;mi_3d_i
s_up_to_date = 1; mi_flat_is_up_to_date = 0; }
else {// Prepare solid. i = facet_part_rw(p
art, &m_3d_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_3d_base_clump) ) return;
m_base_clump = m_3d_base_clump; RwAddClumpToSce
ne(m_scene, m_base_clump); mi_display_list_is
_up_to_date = 0; mi_3d_is_up_to_date = 0;
mi_flat_is_up_to_date = 0; } } else {
// Prepare flat solid or flat wireframe. m
_part_centroid = m_flat_part_centroid; if(! mi_s
how_solid) { // Prepare wireframe. i = pre
pare_display_list(part, mi_show_3d, 1, 0, 1, 1, md
_face_color, md_bendline_color); if(! i) {
mi_display_list_is_up_to_date = 0; retu
rn; } mi_display_list_is_up_to_date = 1;
mi_flat_is_up_to_date = 1; mi_3d_is_up_
to_date = 0; } else { // Preparesolid.
i = facet_part_rw(part, &m_flat_base_clump, mi
_show_3d, md_part_color); if( (! i) || (! m_fla
t_base_clump) ) return; m_base_clump = m_flat_b
ase_clump; RwAddClumpToScene(m_scene, m_base_cl
ump);mi_display_list_is_up_to_date = 0; mi_3d
_is_up_to_date = 0;mi_flat_is_up_to_date = 0; }
} mi_bbox_is_up_to_date = 0; ml_num_faces
= part->get_number_of_faces(); ml_num_bendlines
= part->get_number_of_bendlines(); ml_num_forming
s = part->get_number_of_formings();clear_selection
_set(); reset_selection_buffer(); OnViewIsometri
c();}//This function destroys all parent clumps in
the scene, and hence all clumps in the scene.// I
t always returns NULL.static RwClump * RWCALLBACKc
lear_scene(RwClump *clump){ int i = RwGetClumpNum
Children(clump); if(i) RwDestroyClump(clump);
return NULL;} // This allows other classes to s
ignal that the part has changed, and hence// curre
nt clumps/display lists are no longer valid. We re
compute centroids, prepare new clumps// or display
lists, and show the part in its current orientati
on and zoom.void CBendCADViewPart::invalidate_disp
lay(void) { int i; BM_PART *part = NULL; CBendC
ADDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);
part = pDoc->get_part(); if(! part) { mi_par
t_is_up_to_date = 0; return; } mi_part_is_up_to
_date = 1; compute_part_centroid(part, 0, &m_flat
_part_centroid); // Compute 3d and flat part centr
oids. compute_part_centroid(part, 1, &m_3d_part_c
entroid); mi_3d_is_up_to_date = 0; mi_flat_is_
up_to_date = 0; // Clear out any RenderWare clump
s around. if(m_flat_base_clump) { RwRemoveClum
pFromScene(m_flat_base_clump); RwDestroyClump(m
_flat_base_clump); m_flat_base_clump = NULL; }
if(m_3d_base_clump) { RwRemoveClumpFromScene
(m_3d_base_clump); RwDestroyClump(m_3d_base_clu
mp); m_3d_base_clump = NULL; } m_base_clump =
NULL; if(mi_show_3d) { // Prepare 3d solid o
r 3d wireframe. m_part_centroid = m_3d_part_cen
troid; if(! mi_show_solid) { // Prepare wirefra
me. i = prepare_display_list(part, mi_show_3
d, 1, 0, 1, 1, md_face_color, md_bendline_color);
if(! i) { mi_display_list_is_up_to_da
te = 0; return; } mi_display_list_i
s_up_to_date =1; mi_3d_is_up_to_date = 1;
mi_flat_is_up_to_date = 0; } else{ // Pr
epare solid. i = facet_part_rw(part, &m_3d_ba
se_clump, mi_show_3d, md_part_color); if( (! i)
|| (! m_3d_base_clump) ) return; m_base_clump
= m_3d_base_clump; RwAddClumpToScene(m_scene, m
_base_clump); } } else { // Prepa
re flat solid or flatwireframe. m_part_centroid
= m_flat_part_centroid; if(! mi_show_solid) {
// Prepare wireframe. i = prepare_display_l
ist(part, mi_show_3d, 1, 0, 1, 1, md_face_color, m
d_bendline_color); if(! i) {mi_display_list_i
s_up_to_date = 0; return; } mi_disp
lay_list_is_up_to_date = 1; mi_flat_is_up_to_
date = 1; mi_3d_is_up_to_date = 0; } else
{ // Prepare solid. i = facet_part_rw
(part, &m_flat_base_clump, mi_show_3d, md_part_col
or); if( (! i)|| (! m_flat_base_clump) ) retur
n; m_base_clump = m_flat_base_clump;RwAddClumpT
oScene(m_scene, m_base_clump); } } mi_bbox_is_u
p_to_date = 0; ml_num_faces = part->get_number_of
_faces(); ml_num_bendlines =part->get_number_of_b
endlines(); ml_num_formings = part->get_number_of
_formings(); clear_selection_set(); reset_select
ion_buffer(); ml_last_function_chosen = RETURN_FR
OM_DIALOG_MODE; DrawPart(m_hdc); ml_last_functio
n_chosen = NO_FUNCTION_MODE;}void CBendCADViewPar
t::OnShowFlat() {if(! mi_show_3d) return; // Flat
is already being shown. int i; BM_PART *part
= NULL; CBendCADDoc* pDoc = GetDocument(); ASSER
T_VALID(pDoc); part = pDoc->get_part(); if(! par
t) { mi_part_is_up_to_date =0; return; } //
Store the current 3d view parameters. md_old_x_tr
ans = md_x_trans; md_old_y_trans = md_y_trans; f
or(i=0; i < 3; ++i) {md_old_part_bbox_size[i] = md
_part_bbox_size[i]; md_old_view_vol[i] =md_curren
t_view_vol[i]; } if(md_old_rot_matrix) RwDestroy
Matrix(md_old_rot_matrix); md_old_rot_matrix = Rw
DuplicateMatrix(md_rot_matrix); mi_show_3d = 0;
m_part_centroid = m_flat_part_centroid; if(! mi_
show_solid) {// Compute the flat’s display list.
if(! mi_flat_is_up_to_date) { i = prepa
re_display_list(part, mi_show_3d, 1, 0, 1, 1, md_f
ace_color, md_bendline_color); if(! i) {
mi_display_list_is_up_to_date = 0; retur
n; } } mi_display_list_is_up_to_date=
1; mi_flat_is_up_to_date = 1; mi_3d_is_up_to_dat
e = 0; } else {//Compute flat’s clump if not al
ready done. if(m_3d_base_clump) RwRemoveClumpFr
omScene(m_3d_base_clump); m_base_clump = NULL;
if(! m_flat_base_clump) { i = facet_part_rw(p
art, &m_flat_base_clump, mi_show_3d, md_part_colo
r); if( (! i) || (! m_flat_base_clump) ) {
mi_display_list_is_up_to_date = 0; ret
urn; } } m_base_clump= m_flat_base_clump;
// Set the base clump to be the flat’s base clum
p.RwAddClumpToScene(m_scene, m_base_clump); } mi
_bbox_is_up_to_date= 0; OnViewTop(); }// Here we
show the 3d version, in its old orientation and z
oom (before flat was// asked to be shown).void CBe
ndCADViewPart::OnShow3d() { if(mi_show_3d) retur
n; // 3D view is already being shown. int i;
BM_PART *part = NULL; CBendCADDoc* pDoc = GetDo
cument(); ASSERT_VALID(pDoc); part = pDoc->get_p
art(); if(! part) { mi_part_is_up_to_date = 0;
return; } // Restore the old 3d view parameter
s.md_x_trans = md_old_x_trans; md_y_trans = md_ol
d_y_trans; for(i=0; i< 3; ++i) { md_part_bbox_
size[i] = md_old_part_bbox_size[i]; md_current_vi
ew_vol[i] = md_old_view_vol[i]; } if(md_rot_matr
ix) RwDestroyMatrix(md_rot_matrix); md_rot_matrix
= RwDuplicateMatrix(md_old_rot_matrix); mi_show_
3d = 1; m_part_centroid = m_3d_part_centroid; if
(! mi_show_solid) { if(! mi_3d_is_up_to_date)
{ i = prepare_display_list(part, mi_show_3d,
1, 0, 1, 1, md_face_color, md_bendline_color);
if(! i) { mi_display_list_is_up_to_date
= 0; return; }mi_display_list_is_up_to_
date = 1; mi_3d_is_up_to_date = 1;mi_flat_is_
up_to_date = 0; } } else {// Compute the 3d_v
ersion’s clumps if have not already done so. i
f(m_flat_base_clump) RwRemoveClumpFromScene(m_flat
_base_clump); m_base_clump = NULL; if(! m_3d_b
ase_clump) { i = facet_part_rw(part, &m_3d_b
ase_clump, mi_show_3d, md_part_color); if( (!
i) || (! m_3d_base_clump) ) { mi_display_l
ist_is_up_to_date = 0; return; } }
m_base_clump = m_3d_base_clump;// Set the base c
lump to be the 3d version’s base clump.RwAddClump
ToScene(m_scene, m_base_clump); } mi_bbox_is_up_
to_date = 0;md_current_view_vol[1] = md_current_vi
ew_vol[0]/md_aspect; RwSetCameraViewwindow(m_cam
era, (float)(md_current_view_vol[0]), (float)(md_c
urrent_view_vol[1])); glMatrixMode(GL_PROJECTIO
N); glLoadIdentity(); glOrtho(- md_current_view_
vol[0],md_current_view_vol[0],- md_current_view_vo
l[1], md_current_view_vol[1],//- 50000.0, 50000.
0); - md_current_view_vol[2], md_current_
view_vol[2]); glMatrixMode(GL_MODELVIEW); DrawPa
rt(m_hdc); }void CBendCADViewPart::OnHide3d() {
OnShowFlat();// For now, just switch to showing fl
at.}void CBendCADViewPart::OnHideFlat(){ OnShow3d
();// For now, just switch to showing 3D.}void CBe
ndCADViewPart::OnViewWireframe() { if(! mi_show_s
olid) return; // Wireframe already being shown.
int i; CreateRGBPalette(m_hdc);// when wirefram
e --recreate the palette -- AK HGLRC hrc = wglGet
CurrentContext(); // Therendering context of OpenG
L. wglMakeCurrent(NULL, NULL); wglMakeCurrent(m_
hdc, hrc); // Associate the rendering conte
xt with this view.BM_PART *part = NULL; CBendCADD
oc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pa
rt = pDoc->get_part(); if(! part) { mi_part_is
_up_to_date = 0; return; } mi_show_solid = 0;
if(mi_show_3d) { if(! mi_3d_is_up_to_date) {
i = prepare_display_list(part, mi_show_3d, 1,
0, 1, 1, md_face_color, md_bendline_color);
if(! i) { mi_display_list_is_up_to_date =
0; return; } mi_display_list_is_up_
to_date = 1; mi_3d_is_up_to_date = 1; mi_fla
t_is_up_to_date = 0;} } else { if(! mi_flat_i
s_up_to_date) { i = prepare_display_list(par
t, mi_show_3d, 1, 0, 1, 1, md_face_color, md_bendl
ine_color);if(! i) { mi_display_list_is_up_
to_date = 0; return;} mi_display_list_is
_up_to_date = 1; mi_3d_is_up_to_date = 0; mi
_flat_is_up_to_date = 1; } } ml_last_function
_chosen = WIREFRAME_MODE; DrawPart(m_hdc); ml_la
st_function_chosen = NO_FUNCTION_MODE; }void CB
endCADViewPart::OnViewShaded() { if(mi_show_soli
d) return;// Solid already being shown. int i; B
M_PART *part = NULL; CBendCADDoc* pDoc = GetDocum
ent(); ASSERT_VALID(pDoc); part = pDoc->get_part
(); if(! part) { mi_part_is_up_to_date = 0; r
eturn; } mi_show_solid = 1; if(mi_show_3d) {
if(! m_3d_base_clump) { i = facet_part_rw
(part, &m_3d_base_clump, mi_show_3d, md_part_colo
r); if( (!i) || (! m_3d_base_clump) ) {
mi_display_list_is_up_to_date = 0;return; }
}RwRemoveClumpFromScene(m_base_clump); m_ba
se_clump = m_3d_base_clump;// Set the base clump t
o be the 3d version’s base clump. RwAddClumpTo
Scene(m_scene, m_base_clump); } else { if(! m
_flat_base_clump) { i = facet_part_rw(part,
&m_flat_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_flat_base_clump) ){ m
i_display_list_is_up_to_date = 0; return;
} }RwRemoveClumpFromScene(m_base_clump); m
_base_clump = m_flat_base_clump;//Set the base clu
mp to be the 3d version’s base clump. RwAddClu
mpToScene(m_scene, m_base_clump); } ml_last_func
tion_chosen = SOLID_MODE;DrawPart(m_hdc); ml_last
_function_chosen = NO_FUNCTION_MODE; }void CBend
CADViewPart::OnZoomWindow() { ml_last_function_ch
osen = ZOOM_WINDOW_MODE; mi_bbox_is_up_to_date
= 0;}void CBendCADViewPart::OnUpdateZoomWindow(CCm
dUI* pCmdUI) {pCmdUI->SetCheck((ZOOM_WINDOW_MODE =
= ml_last_function_chosen) ? TRUE : FALSE);}void C
BendCADViewPart::OnZoomInOut() { ml_last_function
_chosen = ZOOM_IN_OUT_MODE; mi_bbox_is_up_to_da
te = 0;}void CBendCADViewPart::OnUpdateZoomInOut(C
CmdUI* pCmdUI) {pCmdUI->SetCheck((ZOOM_IN_OUT_MODE
== ml_last_function_chosen) ? TRUE : FALSE);}void
CBendCADViewPart::OnZoomAll() { BM_PART *part = N
ULL; CBendCADDoc* pDoc; BM_VECTOR offset; if(!
mi_bbox_is_up_to_date) { pDoc = GetDocument();
ASSERT_VALID(pDoc); part = pDoc->get_par
t(); if(! part) return;if(! mi_part_is_up_to_da
te) { // By nowwe expec
t the centroid to have alreadycompute_part_centroi
d(part, 0, &m_flat_part_centroid); // been comput
ed; this is only a safety check. compute_part_cent
roid(part, 1, &m_3d_part_centroid); if(mi_show_3d)
m_part_centroid = m_3d_part_centroid;else m_part_
centroid = m_flat_part_centroid;}compute_part_bbo
x(part, mi_show_3d, md_rot_matrix, m_part_centroi
d,md_part_bbox_size, &offset); mi_bbox_is_up_to
_date = 1;md_x_trans =-(offset.X()); // Adjust
for the fact that bbox center maymd_y_trans= -(of
fset.Y()); // not coincide with centroid of pa
rt. } set_new_view_volume(md_part_bbox_size[0],
md_part_bbox_size[1]); ml_last_function_chosen =
ZOOM_ALL_MODE; DrawPart(m_hdc); ml_last_function
_chosen =NO_FUNCTION_MODE; }void CBendCADViewPar
t::OnUpdateZoomAll(CCmdUI* pCmdUI) {pCmdUI->SetChe
ck((ZOOM_ALL_MODE == ml_last_function_chosen) ? TR
UE: FALSE);}void CBendCADViewPart::OnViewIsometric
() { ml_last_function_chosen = ISOMETRIC_VIEW_MOD
E; mi_bbox_is_up_to_date = 0; md_z_angle = 270.
0; md_y_angle = 305.2643897;// 270 + tan^-1(1/sqr
t(2)) RwRotateMatrix(RwScratchMatrix(), 0.0f, 0.0
f, 1.0f, CREAL(md_z_angle), rwREPLACE);RwRotateMat
rix(RwScratchMatrix(), 0.0f, 1.0f, 0.0f, CREAL(md_
y_angle), rwPRECONCAT); md_z_angle = 45.0; RwRot
ateMatrix(RwScratchMatrix(), 0.0f, 0.0f, 1.0f, CRE
AL(md_z_angle), rwPRECONCAT); if(md_rot_matrix) R
wDestroyMatrix(md_rot_matrix); md_rot_matrix = Rw
DuplicateMatrix(RwScratchMatrix());// glPushMatri
x();// glLoadIdentity();// glRotated(md_z_angle,
0.0, 0.0, 1.0); // Rotation about z axis.// gl
Rotated(md_y_angle,0.0, 1.0, 0.0); // Rotation ab
out y axis.// md_z_angle = 45.0;// glRotated(md_
z_angle, 0.0, 0.0, 1.0);// glGetDoublev(GL_MODELV
IEW_MATRIX, md_rot_matrix);// glPopMatrix(); OnZ
oomAll();}void CBendCADViewPart::OnViewRight() {
ml_last_function_chosen = RIGHT_VIEW_MODE; mi_bbo
x_is_up_to_date = 0; md_z_angle = 270.0; md_y_an
gle = 270.0; md_x_angle = 0.0; RwRotateMatrix(Rw
ScratchMatrix(), 0.0f, 0.0f, 1.0f, CREAL(md_z_angl
e), rwREPLACE); RwRotateMatrix(RwScratchMatrix(),
0.0f, 1.0f, 0.0f, CREAL(md_y_angle), rwPRECONCA
T); if(md_rot_matrix) RwDestroyMatrix(md_rot_matr
ix); md_rot_matrix = RwDuplicateMatrix(RwScratchM
atrix());// glPushMatrix();// glLoadIdentity();/
/ glRotated(md_z_angle, 0.0, 0.0, 1.0);// Rotatio
n about z axis.// glRotated(md_y_angle, 0.0, 1.
0, 0.0);// Rotation about y axis.// glGetDoublev
(GL_MODELVIEW_MATRIX, md_rot_matrix);// glPopMatr
ix(); OnZoomAll();}void CBendCADViewPart::OnViewF
ront() { ml_last_function_chosen = FRONT_VIEW_MOD
E; mi_bbox_is_up_to_date= 0; md_y_angle = 0.0;
md_z_angle = 0.0; md_x_angle = 270.0; RwRotateMa
trix(RwScratchMatrix(), 1.0f, 0.0f, 0.0f, CREAL(md
_x_angle), rwREPLACE); if(md_rot_matrix) RwDestro
yMatrix(md_rot_matrix); md_rot_matrix =RwDuplicat
eMatrix(RwScratchMatrix());// glPushMatrix(); //
glLoadIdentity();// glRotated(md_x_angle, 1.0,
0.0, 0.0); // Rotation about x axis.// glGetDou
blev(GL_MODELVIEW_MATRIX, md_rot_matrix);// glPop
Matrix(); OnZoomAll();}void CBendCADViewPart::OnV
iewTop() { ml_last_function_chosen = TOP_VIEW_MOD
E; mi_bbox_is_up_to_date = 0; RwIdentityMatrix(m
d_rot_matrix); OnZoomAll();}void CBendCADViewPar
t::OnViewsOrtho() {if (NULL == GetDocument()->get_
part()) { // no partreturn ;} COrthoViewDlg orhodl
g(NULL, GetDocument()->get_part(), this) ;int ret
= orhodlg.DoModal() ;// if we are in a Client Mod
e, the user cannot have entered anything.// we hav
e to redisplay the main client menu bar.if (BENDCA
D_CLIENT_MODE) {::PostMessage(this->GetSafeHwnd(),
WM_COMMAND,MAKEWPARAM(ID_DISPLAY_CLIENT_MENU,1),NU
LL) ;return ;}// when OK pressed, get return value
sif (IDOK == ret) {}}void CBendCADViewPart::OnView
Back() { ml_last_function_chosen = BACK_VIEW_MOD
E; mi_bbox_is_up_to_date = 0; md_x_angle = 270.
0; md_y_angle = 0.0; md_z_angle = 180.0; RwRota
teMatrix(RwScratchMatrix(), 1.0f, 0.0f, 0.0f, CREA
L(md_x_angle), rwREPLACE); RwRotateMatrix(RwScrat
chMatrix(), 0.0f, 0.0f, 0.1f, CREAL(md_z_angle), r
wPRECONCAT); if(md_rot_matrix) RwDestroyMatrix(md
_rot_matrix); md_rot_matrix = RwDuplicateMatrix(R
wScratchMatrix()); OnZoomAll();}void CBendCADView
Part::OnViewBottom() { ml_last_function_chosen =
BOTTOM_VIEW_MODE; mi_bbox_is_up_to_date = 0; md_
x_angle = 0.0; md_y_angle = 180.0; md_z_angle =
0.0;RwRotateMatrix(RwScratchMatrix(), 0.0f, 1.0f,
0.0f, CREAL(md_y_angle),rwREPLACE); if(md_rot_mat
rix) RwDestroyMatrix(md_rot_matrix); md_rot_matri
x = RwDuplicateMatrix(RwScratchMatrix()); OnZoomA
ll();}void CBendCADViewPart::OnViewLeft() { ml_la
st_function_chosen = LEFT_VIEW_MODE; mi_bbox_is_u
p_to_date = 0; md_z_angle = 90.0; md_y_angle = 9
0.0; md_x_angle = 0.0; RwRotateMatrix(RwScratchM
atrix(), 0.0f, 0.0f, 1.0f, CREAL(md_z_angle), rwRE
PLACE); RwRotateMatrix(RwScratchMatrix(), 0.0f,
1.0f,0.0f, CREAL(md_y_angle), rwPRECONCAT); if(md
_rot_matrix) RwDestroyMatrix(md_rot_matrix); md_r
ot_matrix = RwDuplicateMatrix(RwScratchMatrix());O
nZoomAll();} void CBendCADViewPart::OnRotate()
{ ml_last_function_chosen = ROTATION_MODE; mi_bb
ox_is_up_to_date = 0;}void CBendCADViewPart::OnUpd
ateRotate(CCmdUI* pCmdUI) {pCmdUI->SetCheck((ROTAT
ION_MODE == ml_last_function_chosen) ? TRUE : FALS
E);}void CBendCADViewPart::OnPan() {ml_last_functi
on_chosen = PAN_MODE; mi_bbox_is_up_to_date =
0;}void CBendCADViewPart::OnUpdatePan(CCmdUI* pCmd
UI) {pCmdUI->SetCheck((PAN_MODE == ml_last_functio
n_chosen) ? TRUE : FALSE);}// This function comput
es the rotation angles about x and y axes.// It is
called on mouse movement, if the rotation mode is
on.void CBendCADViewPart::compute_rotation_angles
(int x_flag){ double x_dir = (double)(m_current_p
oint.x - m_previous_point.x); double y_dir = (dou
ble)(m_current_point.y - m_previous_point.y); dou
ble mag = sqrt(x_dir*x_dir + y_dir*y_dir); // Cre
ate the rotation matrix corresponding to the axis
computed. if(mag > 0.1) { RwRotateMatrix(RwScr
atchMatrix(), CREAL(y_dir/mag), CREAL(x_dir/mag),
CREAL(0.0), CREAL(360.0*mag/(1.
414*m_old_rect.bottom)),rwREPLACE); RwTransform
Matrix(RwScratchMatrix(), md_rot_matrix, rwPRECONC
AT); if(md_rot_matrix) RwDestroyMatrix(md_rot_m
atrix); md_rot_matrix = RwDuplicateMatrix(RwScr
atchMatrix()); } // glPushMatrix();// glLoad
Identity();// glRotated(md_y_angle, 0.0, 1.0, 0.
0); // Rotation about y axis.// if(x_flag)//
glRotated(md_x_angle, 1.0, 0.0,1.0); // Rota
tion about x axis.// else// glRotated(md_z_ang
le, 0.0, 0.0, 1.0); // Rotation about z axis.//
glMultMatrixd(md_rot_matrix);// glGetDoublev(GL
_MODELVIEW_MATRIX, md_rot_matrix);// glPopMatri
x();} // This function computes the x and y transl
ation values.// It is called on mouse movement, if
the pan mode is on.void CBendCADViewPart::compute
_pan_translation(void){ double x; if( (x = (doub
le)m_old_rect.right) > 0.0 ) md_x_trans += (m_c
urrent_point.x - m_previous_point.x)*md_current_vi
ew_vol[0]/x; if( (x = (double)m_old_rect.bottom)
> 0.0 ) md_y_trans += -(m_current_point.y - m_p
revious_point.y)* // -ve sign for md_y_trans
md_current_view_vol[1]/x;
// bec. y axis points up screen.
}// This funciton computes translation value
s when user zooms in/out.void CBendCADViewPart::co
mpute_zoom_in_out_translation(void){ double x; i
f( (x= (double)m_old_rect.right) > 0.0 ) md_x_t
rans += -(m_current_point.x - m_previous_point.x)*
md_current_view_vol[0]/x;}//Thi
s funciton computes translation values when user z
ooms into a // selected rectangular region.void CB
endCADViewPart::compute_zoom_region_translation(vo
id){ double x1 = ((double)(m_lt_btn_down_point.x
+ m_lt_btn_up_point.x))/2.0; double delta_x = x1
- ((double)m_old_rect.right)/2.0;double y1 = ((dou
ble)(m_lt_btn_down_point.y + m_lt_btn_up_point.y))
/2.0;double delta_y = -( y1 - ((double)m_old_rect.
bottom)/2.0 ); md_x_trans -= //m_part_centroid.
X() - md_x_trans + delta_x*2.0*md_c
urrent_view_vol[0]/((double)m_old_rect.right); md
_y_trans -= //m_part_centroid.Y() - md_y_trans +
delta_y*2.0*md_current_view_vol[1]/
((double)m_old_rect.bottom);}// This function comp
utes the new view volume when the user zooms in/ou
t.// The part has already been translated appropri
ately.void CBendCADViewPart::compute_zoom_in_out_v
iew_volume(void){ double x = -(m_current_point.y
- m_previous_point.y); md_current_view_vol[0] -=
md_current_view_vol[0]*x/(double)m_old_rect.botto
m; md_current_view_vol[1] = md_current_view_vol
[0]/md_aspect; RwSetCameraViewwindow(m_camera, (f
loat)(md_current_view_vol[0]), (float)(md_current_
view_vol[1])); glMatrixMode(GL_PROJECTION); glL
oadIdentity(); glOrtho(- md_current_view_vol[0],m
d_current_view_vol[0],- md_current_view_vol[1], md
_current_view_vol[1],//- 50000.0, 50000.0);
- md_current_view_vol[2], md_current_view_vol
[2]); glMatrixMode(GL_MODELVIEW);}// This functio
n computes and sets the new view volume when the u
ser zooms into // a selected rectangular region.
(In the case of zoom all, the selected// region is
simply the bounding box of the part).// The part
has already been translated appropriately.void CBe
ndCADViewPart::set_new_view_volume(double x_exten
t, double y_extent){ double longer = __max(x_ext
ent, y_extent); double shorter = __min(x_extent,
y_extent); if(longer ==x_extent) { // The x ex
tent is longer. if(longer/md_aspect < shorter)
// y extent does not fit screen. longer =
shorter*md_aspect;md_current_view_vol[0] = 0.55*l
onger;md_current_view_vol[1] = 0.55*longer/md_aspe
ct;md_current_view_vol[2] = __max(longer, md_part_
bbox_size[2]); } else { // The y extent is long
er. if(longer*md_aspect < shorter) // x e
xtent does not fit screen. longer = shorter/md_as
pect;md_current_view_vol[0] = 0.55*longer*md_aspec
t;md_current_view_vol[1] = 0.55*longer;md_current_
view_vol[2] = __max(longer, md_part_bbox_size
[2]);} RwSetCameraViewwindow(m_camera, (float)(md
_current_view_vol[0]), (float)(md_current_view_vol
[1])); glMatrixMode(GL_PROJECTION); glLoadIdent
ity(); glOrtho(- md_current_view_vol[0],md_curren
t_view_vol[0],- md_current_view_vol[1], md_current
_view_vol[1],//- 50000.0, 50000.0);- md_current_vi
ew_vol[2], md_current_view_vol[2]); glMatrixMode
(GL_MODELVIEW); glLoadIdentity();}// This functio
n draws a part on the viewwindow. It is called by
OnDraw.void CBendCADViewPart::DrawPart(HDC draw_d
c) { long size, i, parent_tag, key;static long *se
lected_items = NULL;RwClump *picked_clump, *parent
_clump; static double red_color[3] = {1.0, 0.0,
0.0}; static double green_color[3] = {0.0, 1.0,
0.0};double array[16];BV_SELECT_DATA *data = NULL;
static RwMatrix4d *old_matrix[50];static float rw_
array[4][4];if(mi_simulation_is_on) {// Set camera
parameters to view window values. RwSetCameraVie
wport(m_camera, 0, 0, m_old_rect.right, m_old_rec
t.bottom); glViewport(0, 0, m_old_rect.right, m
_old_rect.bottom);RwSetCameraViewwindow(m_camera,
(float)(md_current_view_vol[0]), (float)(md_curren
t_view_vol[1])); glMatrixMode(GL_PROJECTION);glLoa
dIdentity();glOrtho(- md_current_view_vol[0],md_cu
rrent_view_vol[0],- md_current_view_vol[1], md_cur
rent_view_vol[1],//- 50000.0, 50000.0);
-md_current_view_vol[2], md_current_view_vol
[2]);glMatrixMode(GL_MODELVIEW);}if(! mi_show_soli
d){ // Wireframe drawing; use OpenGL drawing c
ommands. glPushMatrix();glTranslated(m_camera_pos
ition.X(), m_camera_position.Y(), m_camera_positio
n.Z());gluLookAt(m_camera_position.X(), m_camera_p
osition.Y(), m_camera_position.Z(), m_camera_targ
et.X(), m_camera_target.Y(), m_camera_target.Z(),
m_camera_look_up.X(), m_camera_look_up.Y
(), m_camera_look_up.Z()); glTranslated(md_x_tr
ans, md_y_trans, 0.0); convert_rw_matrix_to_gl_ar
ray(md_rot_matrix, array); glMultMatrixd(array);
glTranslated(- m_part_centroid.X(), - m_part_cen
troid.Y(), - m_part_centroid.Z()); glClearColor
(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_B
IT | GL_DEPTH_BUFFER_BIT); if(ml_last_function_ch
osen == SELECT_OBJECTS_MODE) glRenderMode(GL_S
ELECT); else glRenderMode(GL_RENDER); glSel
ectBuffer(512, mw_selected_objects); glInitName
s(); glPushName(0); if(! mi_simulation_is_on)
{ // First drawthe selected items in red, if any.
size = m_selection_set.list_size();if(size) {selec
ted_items = new long [size*2 + 1]; // +1 for safe
ty.m_selection_set.display(size, selected_items);g
lColor3d(1.0, 0.0, 0.0);for(i=0;i < size; ++i) {
data = (BV_SELECT_DATA *)selected_items[i*2 +1];if
(!data) continue;if(data->edge) {
//Edge is available, => not
a trivial glCallList((unsigned int)selected_item
s[i<<1]); // bendline or body of something.}else
{// Body of face/forming/bendline picked; highligh
t whole thing.key = selected_items[i<<1]/100000;gl
CallList((unsigned int)key*100000);}} } } glCal
lList(1);glFinish(); glPopMatrix(); SwapBuffe
rs(wglGetCurrentDC());} else {// Solid drawing; u
se RenderWare. // Transform the part if necessar
y.if(ml_last_function_chosen != NO_FUNCTION_MODE)
{ RwTranslateMatrix(RwScratchMatrix(), CREAL
(md_x_trans), CREAL(md_y_trans), CREAL(0.0),rwREPL
ACE); RwTransformMatrix(RwScratchMatrix(), m
d_rot_matrix, rwPRECONCAT); RwTranslateMatrix
(RwScratchMatrix(), CREAL(- m_part_centroid.X()),
CREAL(- m_part_centroid.Y()),
CREAL(- m_part_centroid.Z()), rwPRECONCAT);
// RwForAllClumpsInScenePointer(m_scene, do_t
ransformations, (void *)RwScratchMatrix()); R
wTransformClump(m_base_clump, RwScratchMatrix(), r
wREPLACE); }/*RwClump *clump; for(i=0; i < ml_n
um_faces + ml_num_bendlines + ml_num_formings; ++
i) { clump = RwFindTaggedClump(m_base_clum
p, i + 10001);if(! clump) continue;old_matrix[i] =
RwCreateMatrix(); // clump の現在のモデル化マトリ
クスを記憶する. RwGetClumpMatrix(clump, old_mat
rix[i]);RwGetMatrixElements(old_matrix[i], rw_arra
y); RwTranslateMatrix(RwScratchMatrix(), CREAL
(md_x_trans), CREAL(md_y_trans), CREAL(0.0), rwREP
LACE);RwTransformMatrix(RwScratchMatrix(), md_rot_
matrix, rwPRECONCAT); RwTranslateMatrix(RwScrat
chMatrix(), CREAL(- m_part_centroid.X()), CREAL(-m
_part_centroid.Y()), CREAL(-
m_part_centroid.Z()), rwPRECONCAT); //RwForAllClu
mpsInScenePointer(m_scene, do_transformations, (vo
id *)RwScratchMatrix());RwTransformClump(clump, Rw
ScratchMatrix(), rwPOSTCONCAT); }*///Now set the
color of the clumps in the selectionset to red.si
ze = m_selection_set.list_size();if(size) {selecte
d_items= new long [(size << 1) + 1]; // +1 for sa
fety.m_selection_set.display(size, selected_item
s);for(i=0; i < size; ++i) {data = (BV_SELECT_DATA
*)selected_items[i*2 +1];if(! data) continue;if(d
ata->edge) { // Edge is available, => not
a trivial bendline or body of something.parent_tag
= (selected_items[i<<1]/100000) + 10000;parent_cl
ump = RwFindTaggedClump(m_base_clump, parent_ta
g);}else {key = selected_items[i<<1]%100000;// Che
ck if it is a trivial bendline.if((key/10000) ==
6) {parent_tag= (selected_items[i<<1]/100000) + 10
000;parent_clump = RwFindTaggedClump(m_base_clump,
parent_tag);}else parent_clump = m_base_clump;}ke
y = selected_items[i<<1]%100000;picked_clump = RwF
indTaggedClump(parent_clump, key);RwForAllPolygons
InClumpPointer(picked_clump, SetPolygonColor, (voi
d*)red_color); }} // In case simulation is going
on, we don’t want to show the m_sim_base_clump, o
nly m_base_clump. if(mi_simulation_is_on) {if(m_s
im_base_clump) RwRemoveClumpFromScene(m_sim_base_c
lump);if(mi_show_3d) {m_base_clump = m_3d_base_clu
mp;RwAddClumpToScene(m_scene, m_base_clump);}else
{m_base_clump = m_flat_base_clump;RwAddClumpToScen
e(m_scene,m_base_clump); } } // Now draw
the part. RwInvalidateCameraViewport(m_camera);
RwBeginCameraUpdate(m_ca
mera, (void *)m_hwnd); RwClearCameraViewport
(m_camera); i = RwGetSceneNumClumps(m_scene);
// Render the scene. RwRenderScene(m
_scene); RwEndCameraUpdate(m_camera); RwShowCa
meraImage(m_camera, (void*)(DWORD)draw_dc); //S
how the image on the view window./* for(i=0; i <
ml_num_faces + ml_num_bendlines + ml_num_formings;
++i) { clump = RwFindTaggedClump(m_base_clump,
i + 10001);if(! clump) continue;RwTransformClump
(clump, old_matrix[i], rwREPLACE); RwGetClum
pMatrix(clump, old_matrix[i]); RwGetMatrixElement
s(old_matrix[i], rw_array);if(old_matrix[i]) RwDes
troyMatrix(old_matrix[i]);} */ // Put the simulat
ionclump back in the scene so that simulation can
see it. if(mi_simulation_is_on) {if(m_sim_base_cl
ump) RwAddClumpToScene(m_scene, m_sim_base_clump);
if(mi_show_3d) RwRemoveClumpFromScene(m_3d_base_cl
ump);else RwRemoveClumpFromScene(m_flat_base_clum
p);m_base_clump = NULL; } // Now set thecolor of
the clumps in the selection set back to their ori
ginal colors.if(size) { m_selection_set.display
(size, selected_items); for(i=0; i < size; ++i)
{data = (BV_SELECT_DATA *)selected_items[i*2 +1];
if(data->edge) { // Edge is available, =>
not a trivial bendline or body of something.parent
_tag = (selected_items[i<<1]/100000) + 10000;paren
t_clump = RwFindTaggedClump(m_base_clump, parent_t
ag);}else {key = selected_items[i<<1]%100000;
// Check if it is a trivial bendline.if((key
/10000) == 6) {parent_tag = (selected_items[i<<1]/
100000) + 10000;parent_clump = RwFindTaggedClump(m
_base_clump, parent_tag); } else parent_clump
= m_base_clump; }key = selected_items[i<<1]%1000
00;picked_clump = RwFindTaggedClump(parent_clump,
key);if( (! data->edge) && ((key/10000) == 6) ) /
/ Trivial bendline.RwForAllPolygonsInClumpPointer
(picked_clump, SetPolygonColor, (void *)green_colo
r); elseRwForAllPolygonsInClumpPointer(picked_clum
p, SetPolygonColor, (void *)md_part_color); }}
if(selected_items) delete [] selected_items; se
lected_items = NULL;}if(mi_simulation_is_on) { /
/ Restore camera parameters to simulationvalues.
RwSetCameraViewport(m_camera, 0, 0, mi_bitmap_w ,
mi_bitmap_h); glViewport(0, 0, mi_bitmap_w, mi_
bitmap_h); RwSetCameraViewwindow(m_ca
mera, (float)(md_sim_view_vol[0]), (float)(md_sim_
view_vol[1])); glMatrixMode(GL_PROJECTION);glLoadI
dentity();glOrtho(- md_sim_view_vol[0], md_sim_vie
w_vol[0],- md_sim_view_vol[1], md_sim_view_vol[1],
//- 50000.0, 50000.0); - md_current_vie
w_vol[2], md_current_view_vol[2]);glMatrixMode(GL_
MODELVIEW);}}/*if(size) { for(i=0 ; i < size; ++
i) { BM_3D_BODY *b3;long three_d_type;if(select
ed_items[i*2 +1]){ // エッジが得ら
れる => trivalベンドラインまたはフォーミングではな
い. three_d_type = (selected_items[i<<1]%100000)
/10000; if((three_d_type >= 3) && (three_d_type <
6)) three_d_type = BM_ENTITY_TYPE_FACE; else if
((three_d_type >= 6) && (three_d_type < 9)) three_
d_type = BM_ENTITY_TYPE_BENDLINE; else if(three_d
_type >= 9) three_d_type =BM_ENTITY_TYPE_FORMING;
parent_tag = (selected_items[i<<1]/100000) + 100
00; parent_clump = RwFindTaggedClump(m_base_clum
p, parent_tag);}else {CBendCADDoc* pDoc = GetDocum
ent(); ASSERT_VALID(pDoc); BM_PA
RT *part = pDoc->get_part(); if(! part) r
eturn;// 注意: この段階で部分がNULLであることを期
待しない。 BM_TOPOLOGY *topology = part->
get_topology(); if(! topology) return;thr
ee_d_type = selected_items[i<<1]/100000; //
用語の注意: three_d_type は実際ではない。
b3 = topology->map_id_into_pointer(three_d_typ
e); // b3->get_type()までthree_d_type. three_d_ty
pe = b3->get_type(); parent_clump = m_base_clum
p;}if(three_d_type == BM_ENTITY_TYPE_FACE) {
for(j=0; j < 3; ++j) original_color[j] = md_face_c
olor[j];}else if(three_d_type == BM_ENTITY_TYPE_BE
NDLINE) { for(j=0; j < 3;++j) original_color
[j] = md_bendline_color[j];}else if(three_d_type =
= BM_ENTITY_TYPE_FORMING) { for(j=0; j < 3; +
+j) original_color[j] = md_forming_color[j];}key =
selected_items[i<<1];key = key%100000; picked_
clump = RwFindTaggedClump(parent_clump, key); R
wForAllPolygonsInClumpPointer(picked_clump, SetPol
ygonColor, (void *)original_color); }}*/// This
callback function performs the necessary transform
ations on each clump in the scene.// Transform onl
y parent clumps, since this automatically transfor
ms child clumps as well.static RwClump * RWCALLBAC
K do_transformations(RwClump *clump, void *matrix)
{ int i = RwGetClumpNumChildren(clump); if(i)
{if( !(i = RwGetClumpNumPolygons(clump)) ) Rw
SetClumpState(clump, rwOFF);// Do not render this
clump if it has no polygons. RwTransformClump(c
lump, (RwMatrix4d *)matrix, rwREPLACE); }return
clump;}// This callback function sets the color of
the polygon to the required color.static RwPolygo
n3d * RWCALLBACK SetPolygonColor(RwPolygon3d *poly
gon, void *color) { polygon = RwSetPolygonColo
r(polygon, CREAL(((double *)color)[0]), CREAL(((do
uble *)color)[1]),CREAL(((double *)color)[2]));ret
urn polygon;}// This function sets the pixel forma
t of the view window to the kindthat// OpenGL like
s. Note: Pixel format of a window should be set on
lyonce.BOOL CBendCADViewPart::SetupPixelFormat(HDC
hDC){ static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size ofthis
pfd 1, // ver
sion numberPFD_DRAW_TO_WINDOW | // supp
ort window PFD_SUPPORT_OPENGL |
// support OpenGL PFD_DOUBLEBUFFER,// dou
ble buffered PFD_TYPE_RGBA,
// RGBA type 24,
// 24-bit color depth0, 0, 0, 0, 0, 0,
// color bits ignored 0,// no alph
a buffer 0,// shift bit ignored 0,
// no accumulation buf
fer 0, 0, 0, 0, // accu
m bits ignored 32,
// 32-bit z-buffer0,
// no stencil buffer 0,// no auxiliar
y buffer PFD_MAIN_PLANE,// main layer
0, // reserved
0, 0, 0 // layer masks
ignored}; int pixelformat; if ( (pixelforma
t = ChoosePixelFormat(hDC, &pfd)) == 0 ) {
MessageBox("ChoosePixelFormat failed");return
FALSE; } if (SetPixelFormat(hDC, pixelforma
t, &pfd) == FALSE) { MessageBox("SetPixe
lFormat failed"); return FALSE;} // do
n’t need this call any more; the function will be
calledfrom OnActivateView()// and on OnViewWirefr
ame() -- AK//CreateRGBPalette(hDC); return TRU
E;}unsigned char CBendCADViewPart::ComponentFromIn
dex(int i, UINT nbits, UINT shift){ unsigned ch
ar val; val = (unsigned char) (i >> shift);
switch (nbits) { case 1: val &= 0x1;retu
rn oneto8[val]; case 2: val &= 0x3;
returntwoto8[val]; case 3: val &= 0x
7; return threeto8[val];default: ret
urn 0; }}void CBendCADViewPart::CreateRGBPalett
e(HDC hDC){ PIXELFORMATDESCRIPTOR pfd; LOGPA
LETTE *pPal; int n, i; CDC dc; n = ::GetP
ixelFormat(hDC); ::DescribePixelFormat(hDC, n,
sizeof(PIXELFORMATDESCRIPTOR), &pfd); if (pfd.d
wFlags & PFD_NEED_PALETTE) { n = 1 << pf
d.cColorBits; pPal = (PLOGPALETTE)LocalAllo
c(LMEM_FIXED, sizeof(LOGPALETTE) +
n * sizeof(PALETTEENTRY)); pPal->palVersion
= 0x300; pPal->palNumEntries = n; f
or (i=0; i<n; i++) { pPal->palPa
lEntry[i].peRed = ComponentFrom
Index(i, pfd.cRedBits, pfd.cRedShift);
pPal->palPalEntry[i].peGreen =ComponentFromIndex
(i, pfd.cGreenBits, pfd.cGreenShift); p
Pal->palPalEntry[i].peBlue = Co
mponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShif
t); pPal->palPalEntry[i].peFlags =0;
} /* 省略時GDIパレットを含むようにパ
レットを固定する */if ((pfd.cColorBits == 8)
&&(pfd.cRedBits == 3) && (p
fd.cRedShift == 0) && (pfd.cGreenBits
== 3) && (pfd.cGreenShift == 3) && (pf
d.cBlueBits ==2) && (pfd.cBlueShift == 6)
) {for (i = 1 ; i <= 12 ;i++)
pPal->palPalEntry[defaultOverride[i]] = de
faultPalEntry[i]; } dc.Attach(hDC);C
Palette*pOldPal; // since we call this func
tion not only when creating a view,// but also eac
h time activating, delete the prev palette (if an
y) -- AKint resp = m_cPal.DeleteObject(); m
_cPal.CreatePalette(pPal); LocalFree(pPal);
pOldPal = dc.SelectPalette(&m_cPal, FALS
E); dc.RealizePalette(); dc.Detac
h(); }}// This function computes the bounding b
ox parameters of the given part -// the x, y and z
extents, in globalcoordinates, for the orientatio
n specified by orient_matrix.// The computation is
done with respect to the BM_POINT centroid as ori
gin.// It does so by taking the bbox of each face,
projecting each onto the coordinate // axes, and
then finding the extents along each axis. If three
D_flagis non-zero, the// three-d version’s bbox i
s computed; else, the flat’s bbox is computed. Th
e results of the// computation are put into thearr
y bbox_size[3]; if this pointer is zero, no comput
ation// is performed. The offset, ie. the vector f
rom the centroid’s coords to the bbox center’s c
oords,// is passed back in the pointer to the BM_V
ECTOR.// Returns 1 if successful, 0 otherwise.int
CBendCADViewPart::compute_part_bbox(BM_PART *part,
int threeD_flag, RwMatrix4d *orient_matrix,BM_POI
NT centroid, double *bbox_size, BM_VECTOR*offset)
{ BM_FACE *face = NULL; BM_BENDLINE *bendline =
NULL; BM_2D_BODY *two_d_body = NULL; BM_LOOP *lo
op = NULL; BM_POINT dot1, dot2, dot3, dot4; doub
le left, right, top, bot, front, back; // Fir
st tworefer to x direction, // last two to z dir
ection. BM_VECTOR vec1; int first_pass = 1; flo
at rot_matrix[4][4]; if(! part) return 0; if((p
art->get_number_of_faces() == 0) && (part->get_num
ber_of_bendlines() == 0) ) return 0; if(! bbox
_size) return 0; if(! part->get_number_of_face
s()) { // In this case, find bendline bboxes. f
or(bendline = part->get_bendline_list(); bendline;
bendline = (BM_BENDLINE *)bendline->next()) { //
First check that the bbox of the bloop is up to d
ate; if notcompute bbox. if(threeD_flag) two_d
_body = bendline->get_3D_version(); else two_d
_body = bendline->get_flat(); if(two_d_body) loop
= two_d_body->get_bloop(); else continue; if(!
loop) continue; if(!(loop->is_bbox_up_to_date()))
loop->recompute_bbox(); // Now find the envelope
(union) of the projected bboxes. vec1 = BM_VECTO
R(centroid.X(), centroid.Y(), centroid.Z()); dot1
= loop->get_bbox_p1() + (-1.0)*vec1;// The bbox c
oordinates, dot2 = loop->get_bbox_p2() + (-1.0)*v
ec1;// with respect to the dot3 = loop->get_bbox_
p3() + (-1.0)*vec1;// centroid as origin. dot4 =
loop->get_bbox_p4() + (-1.0)*vec1; RwGetMatrixEle
ments(orient_matrix, rot_matrix); multiply_pt_by_
matrix(&dot1, rot_matrix);// Transform coords by t
he current multiply_pt_by_matrix(&dot2, rot_matri
x);// rotation matrix. multiply_pt_by_matrix(&dot
3, rot_matrix); multiply_pt_by_matrix(&dot4, rot_
matrix); if(first_pass) { left = __min(dot1.X
(), dot2.X()); right = __max(dot1.X(), dot2.
X()); bot = __min(dot1.Y(), dot2.Y()); top
= __max(dot1.Y(), dot2.Y()); back =__min(do
t1.Z(), dot2.Z()); front = __max(dot1.Z(), dot
2.Z()); first_pass = 0; } else { left = __
min(left, dot1.X()); left = __min(left, dot
2.X()); right = __max(right, dot1.X()); righ
t = __max(right, dot2.X()); bot = __min(bot
, dot1.Y()); bot = __min(bot , dot2.Y());
top = __max(top , dot1.Y()); top = __m
ax(top, dot2.Y()); back = __min(back , dot1.
Z()); back = __min(back, dot2.Z()); front =
__max(front, dot1.Z()); front = __max(front,do
t2.Z()); } left = __min(left, dot3.X()); left
= __min(left, dot4.X()); right = __max(right,
dot3.X()); right = __max(right, dot4.X()); bot
= __min(bot , dot3.Y()); bot = __min(bot , d
ot4.Y()); top= __max(top , dot3.Y()); top = _
_max(top , dot4.Y()); back = __min(back , dot3.
Z()); back = __min(back , dot4.Z()); front = __
max(front, dot3.Z()); front = __max(front, dot4.Z
()); } bbox_size[0] =right - left;bbox_size
[1] = top - bot;// Copy bbox size into the array
passed.bbox_size[2] = front - back;if(offset)
// Copy the bbox center into the pointer passed.
*offset = BM_VECTOR((right + left)/2.0, (top + b
ot)/2.0, (front + back)/2.0);mi_bbox_is_up_to_date
= 1; return 1;} // Faces are available, so find
bbox of faces. for(face = part->get_face_list();
face; face = (BM_FACE *)face->next()) { if(! f
ace) break; // First check that the bbox of the
bloop is up to date; if not compute bbox.if(three
D_flag) two_d_body = face->get_3D_version();else
two_d_body = face->get_flat();if(two_d_body) loo
p = two_d_body->get_bloop();else continue;if(! loo
p) continue;if(!(loop->is_bbox_up_to_date())) loop
->recompute_bbox();// Now find the envelope (unio
n) of the projectedbboxes.vec1 = BM_VECTOR(centroi
d.X(), centroid.Y(), centroid.Z());dot1 =loop->get
_bbox_p1() + (-1.0)*vec1;// The bbox coordinates,d
ot2 = loop->get_bbox_p2() + (-1.0)*vec1;// with re
spect to thedot3 = loop->get_bbox_p3() + (-1.0)*ve
c1;// centroid as origin.dot4 = loop->get_bbox_p
4() + (-1.0)*vec1; RwGetMatrixElements(orient_m
atrix, rot_matrix);multiply_pt_by_matrix(&dot1, ro
t_matrix);// Transform coords by the currentmultip
ly_pt_by_matrix(&dot2, rot_matrix);// rotation mat
rix.multiply_pt_by_matrix(&dot3, rot_matrix);multi
ply_pt_by_matrix(&dot4, rot_matrix);if(first_pass)
{ left = __min(dot1.X(), dot2.X()); right = __
max(dot1.X(), dot2.X()); bot = __min(dot1.Y(),
dot2.Y()); top = __max(dot1.Y(), dot2.Y()); ba
ck = __min(dot1.Z(), dot2.Z()); front = __max(do
t1.Z(), dot2.Z()); first_pass = 0;}else { left
= __min(left, dot1.X()); left =__min(left, dot
2.X()); right = __max(right, dot1.X()); right =
__max(right, dot2.X()); bot = __min(bot , dot
1.Y()); bot = __min(bot, dot2.Y()); top = __
max(top , dot1.Y()); top = __max(top , dot2.Y
()); back = __min(back , dot1.Z()); back = __m
in(back , dot2.Z());front = __max(front, dot1.
Z()); front = __max(front, dot2.Z());}left= __min
(left, dot3.X());left = __min(left, dot4.X());r
ight = __max(right, dot3.X());right = __max(right,
dot4.X());bot = __min(bot , dot3.Y());bot =
__min(bot , dot4.Y());top = __max(top , dot3.Y
());top= __max(top , dot4.Y());back = __min(back
, dot3.Z());back = __min(back , dot4.Z());front
= __max(front, dot3.Z());front = __max(front, dot
4.Z()); } bbox_size[0] = right - left; bbox_siz
e[1] = top - bot;//Copy bbox size into the array
passed. bbox_size[2] = front - back; if(offset)
// Copy the bbox center into the pointer pass
ed.*offset = BM_VECTOR((right + left)/2.0, (top +
bot)/2.0, (front + back)/2.0); mi_bbox_is_up_to_d
ate = 1; return 1;}// This function computes the
part’scentroid. This is done with respect to// th
e original (given) coordinates of the part. If thr
eeD_flag is non-zero, the// three-d version’s cen
troid is computed; else, the flat’s centroid is c
omputed.// The resultsare passed back in the point
er to a BM_POINT; if this pointer is NULL, no// co
mputation is done. Returns 1 if successful, 0 othe
rwise.int CBendCADViewPart::compute_part_centroid
(BM_PART *part, int threeD_flag, BM_POINT *centroi
d) { BM_FACE *face; BM_2D_BODY *two_d_body; B
M_LOOP *loop; BM_POINT dot1, dot2, dot3, dot4; d
ouble left, right, top, bot, front, back; // Firs
t two refer to x direction, // last two to z dire
ction. int first_pass = 1; if(! part) return 0;
if( (part->get_number_of_faces == 0) && (part->g
et_number_of_bendlines == 0) ) return 0; if(!c
entroid) return 0; for(face = part->get_face_list
(); face; face = (BM_FACE *)face->next()) { if
(! face) break; // First check that the bbox of
the bloop is up to date; if not compute bbox.if(t
hreeD_flag) two_d_body = face->get_3D_version();e
lse two_d_body = face->get_flat();if(two_d_body)
loop = two_d_body->get_bloop();else continue;if(!
loop) continue;if(!(loop->is_bbox_up_to_date())) l
oop->recompute_bbox();// Now find the envelope (un
ion) of the projected bboxes.dot1 = loop->get_bbox
_p1();dot2 = loop->get_bbox_p2();dot3 = loop->get_
bbox_p3(); dot4 = loop->get_bbox_p4(); if(first_pa
ss) { left = __min(dot1.X(), dot2.X()); right
= __max(dot1.X(), dot2.X()); bot = __min(dot1.
Y(), dot2.Y()); top= __max(dot1.Y(), dot2.Y());
back = __min(dot1.Z(), dot2.Z()); front = __max
(dot1.Z(), dot2.Z()); first_pass = 0;}else { lef
t = __min(left, dot1.X()); left = __min(left,
dot2.X()); right = __max(right,dot1.X()); righ
t = __max(right, dot2.X()); bot = __min(bot ,
dot1.Y()); bot = __min(bot , dot2.Y()); top
= __max(top , dot1.Y());top = __max(top , dot
2.Y()); back = __min(back , dot1.Z()); back= __
min(back , dot2.Z()); front = __max(front, dot1.Z
()); front = __max(front, dot2.Z());}left = __mi
n(left, dot3.X());left = __min(left,dot4.X());ri
ght = __max(right, dot3.X());right = __max(right,
dot4.X());bot = __min(bot , dot3.Y());bot = _
_min(bot , dot4.Y());top = __max(top , dot3.
Y());top = __max(top , dot4.Y());back = __min
(back ,dot3.Z());back = __min(back , dot4.Z());fr
ont = __max(front, dot3.Z());front = __max(front,
dot4.Z()); } *centroid = BM_POINT((right + left)
/2.0, (top + bot )/2.0, (front + back)/2.0); //
Copy centroid into/*//ポインタが供給される。 if(t
hreeD_flag) { m_3d_part_centroid.set_X((right +
left)/2.0); m_3d_part_centroid.set_Y((top +
bot )/2.0); // このpartは3d重心である。 m_3d_
part_centroid.set_Z((front + back)/2.0); } else
{ m_flat_part_centroid.set_X((right + left)/2.
0); m_flat_part_centroid.set_Y((top + bot )/
2.0); // このpartは平面重心である。 m_flat_pa
rt_centroid.set_Z((front + back)/2.0); }*/ retur
n 1;}// This function multiplies a bend model poin
t by a 4x4 RenderWare transform matrix.// The func
tion is destructive.It is NOT a BMAPPView memberfu
nction.// Note that the point is considered to be
a row vector; this is// RenderWare’s (and the Ben
d Model’s) convention. static void multiply_pt_by
_matrix(BM_POINT *point, float rot_matrix[4][4])
{ double x = point->X(); double y = point->Y();
double z = point->Z(); point->set_X((x*rot_matr
ix[0][0] + y*rot_matrix[1][0] + z*rot_matrix[2]
[0])); point->set_Y((x*rot_matrix[0][1] + y*rot_m
atrix[1][1] + z*rot_matrix[2][1]));point->set_Z((x
*rot_matrix[0][2] + y*rot_matrix[1][2] + z*rot_mat
rix[2][2]));}// This function outlines the rectang
ular region selected by theuser.void CBendCADViewP
art::outline_region(void) { CClientDC view_dc(thi
s); CPoint corner1_curr = m_lt_btn_down_point, co
rner2_curr = m_lt_btn_down_point; CPoint corner1_
prev = m_lt_btn_down_point, corner2_prev =m_lt_btn
_down_point; corner1_curr.Offset(m_current_point.
x - m_lt_btn_down_point.x, 0); corner2_curr.Offse
t(0, m_current_point.y - m_lt_btn_down_point.y);
corner1_prev.Offset(m_previous_point.x - m_lt_btn_
down_point.x, 0); corner2_prev.Offset(0, m_previo
us_point.y - m_lt_btn_down_point.y); view_dc.SetR
OP2(R2_NOT); view_dc.MoveTo(m_lt_btn_down_point);
view_dc.LineTo(corner1_prev); view_dc.MoveTo(m_lt
_btn_down_point); view_dc.LineTo(corner2_prev);
view_dc.MoveTo(corner1_prev); view_dc.LineTo(m_pr
evious_point); view_dc.MoveTo(corner2_prev); vie
w_dc.LineTo(m_previous_point); view_dc.MoveTo(m_l
t_btn_down_point); view_dc.LineTo(corner1_curr);
view_dc.MoveTo(m_lt_btn_down_point); view_dc.Li
neTo(corner2_curr); view_dc.MoveTo(corner1_curr);
view_dc.LineTo(m_current_point); view_dc.MoveTo
(corner2_curr); view_dc.LineTo(m_current_point);}
//This function processes the hits record to pick
out the edge(s) selectedby the// user. If add_hit_
to_list is non-zero, which it is if the control bu
tton is held down,// the current hit, if any, is a
dded to the selection set; else, the selection se
t// is cleared and only the current hitis added to
the list. If there is no hit, the // selection se
t is cleared as well, unless add_to_list is non-ze
ro, in which case // nothing happens. // This func
tion recognizes trivial bendlines and formings and
modifies the selection set// appropriately. void
CBendCADViewPart::process_hits_record(int add_hit_
to_list){ RwClump *picked_clump = NULL; RwClump
*parent_clump = NULL;RwV3d vert; long parent_tag,
clump_tag, three_d_type = 0, offset = 0, key = 0;
int num_hits = -3, j; unsigned long z_max = 0U
L, z_min = ULONG_MAX, name_id = 0UL; unsigned int
*ptr = mw_selected_objects; BM_EDGE *edge = NUL
L;long old_data; if(mi_show_solid) {// RenderWare
picking. if(m_pick.type == rwNAPICKOBJECT) {//
No clump was picked. if(add_hit_to_list) ret
urn;else clear_selection_set();return; } els
e if(m_pick.type == rwPICKCLUMP) {// Some clump wa
s picked; process it. picked_clump =m_pick.ob
ject.clump.clump;vert = m_pick.object.clump.wcpoin
t; RwTranslateMatrix(RwScratchMatrix(), CREAL
(md_x_trans), CREAL(md_y_trans), CREAL(0.0), rwREP
LACE); RwTransformMatrix(RwScratchMatrix(),
md_rot_matrix, rwPRECONCAT); RwTranslateMatri
x(RwScratchMatrix(), CREAL(-m_part_centroid.X()),
CREAL(- m_part_centroid.Y()),CREAL(- m_part_centro
id.Z()), rwPRECONCAT); RwMatrix4d *inverse= Rw
CreateMatrix();RwInvertMatrix(RwScratchMatrix(), i
nverse);RwTransformPoint(&vert, inverse);RwDestroy
Matrix(inverse);parent_clump = RwGetClumpParent(pi
cked_clump);parent_tag = RwGetClumpTag(parent_clum
p);clump_tag = RwGetClumpTag(picked_clump);if(pare
nt_tag == 1) {// The body of a face/bendline/formi
ng was picked.key = (clump_tag%10000)*100000 + clu
mp_tag; if(m_selection_set.find(key, NULL))
{ m_selection_set.remove(key, &old_d
ata); // Remove clump from selection set (t
oggle).if(old_data) delete (BV_SELECT_DATA *)old_d
ata;return;}else {if(!add_hit_to_list) clear_selec
tion_set(); // Remove everything else in selectio
n set, BV_SELECT_DATA *data = new BV_SELECT_DATA;d
ata->key = key;data->edge = NULL; (data->
world_pt) = BM_POINT(vert.x, vert.y, vert.z);m_sel
ection_set.insert(key, (long)data);// insert this
key and data.return;}}// Now an edge was picked.ke
y = (parent_tag%10000)*100000 +clump_tag; if(clump
_tag) {// Safety check; we expect clump_tag to be
non-zero.if(m_selection_set.find(key, NULL)){ m_s
election_set.remove(key,&old_data); // Remo
ve clump from selection set (toggle).if(old_data)
delete (BV_SELECT_DATA *)old_data;} else {if(! ad
d_hit_to_list) clear_selection_set(); // Remove e
verything else in selection set. edge =map_list_na
me_to_bm_edge(parent_tag, clump_tag);BV_SELECT_DAT
A *data = new BV_SELECT_DATA;data->key = key;data-
>edge = edge; (data->world_pt) = BM_POINT
(vert.x, vert.y, vert.z);m_selection_set.insert(ke
y, (long)data);// insert this key and data.}} }
} else {// OpenGL Picking. num_hits = glRend
erMode(GL_RENDER); // The numbero
f hits. if(num_hits == -1) {
// Selection buffer has overflowed. Afx
MessageBox("Too many entities selected; change vie
w and try again.");return; } if(num_hits ==
0) {// No hit; only a miss. if(add_hit_to_lis
t) return;else clear_selection_set();return; }
// Process the hits : find the edge with LOWES
T z value of all the edges picked. for(j=0; j <
num_hits; ++j) { ptr += 1;
// Skip the 1st element bec. it will alw
ays be 1, if( (unsigned long)(*ptr) < (unsign
ed long)z_min) {z_min = (unsigned long)(*ptr); ptr
+= 2;name_id = (long)(*ptr); ++ptr;}else ptr +=
3; } // Find the bm edge corresp. to the
name and add it to the selection set. if(name_i
d) {// Something was selected. if(m_selection
_set.find(name_id, NULL)) {m_selection_set.remove
(name_id, &old_data); //Remove edge fromselecti
on set (toggle).if(old_data) delete (BV_SELECT_DAT
A *)old_data;}else {if(! add_hit_to_list) clear_se
lection_set();// First, we massage the name_id int
o the format RenderWare picking uses.parent_tag =
name_id/100000 + 10000;clump_tag = name_id%100000;
edge = map_list_name_to_bm_edge(parent_tag, clump_
tag);BV_SELECT_DATA *data = new BV_SELECT_DATA;dat
a->key = key;data->edge = edge; (data->worl
d_pt) =BM_POINT(0.0, 0.0, 0.0);m_selection_set.ins
ert(name_id, (long)data);// insert this key and da
ta.} } } return;}// This function maps a Rend
erWare parent clump and child clump pair to the //
Bend Model edge whichthe child clump represents.
The pointer to the edge is returned.// Thisfunctio
n only needs to deal with "real" edges, ie. trivia
l bendlines and// formings are filtered out by pro
cess_hits_records itself.BM_EDGE *CBendCADViewPar
t::map_list_name_to_bm_edge(long parent_tag, long
clump_tag){ long three_d_name, three_d_type, loop
_name, edge_name, count = 0, offset = 0; BM_3D_BO
DY *three_d_body = NULL; BM_2D_BODY *two_d_body =
NULL; BM_LOOP *loop = NULL; BM_EDGE *edge = NUL
L; BM_PART *part = NULL;BM_TOPOLOGY *topology = N
ULL; CBendCADDoc* pDoc = GetDocument(); ASSERT_V
ALID(pDoc); part = pDoc->get_part(); if(! part)
return NULL; //Note: we do not expect part to be
NULL at this stage. topology = part->get_topolog
y(); if(! topology) return NULL; three_d_name =
parent_tag%10000; three_d_body = topology->map_id
_into_pointer(three_d_name); // Now we have a po
inter to the face/bendline to which the picked edg
e belongs. three_d_type = three_d_body->get_typ
e(); if(three_d_type == BM_ENTITY_TYPE_FACE)offse
t = 30000; if(three_d_type == BM_ENTITY_TYPE_BEND
LINE)offset = 60000; if(three_d_type == BM_ENTITY
_TYPE_FORMING)offset =90000; loop_name = (clump_t
ag - offset)/100; edge_name = (clump_tag -offset)
%100; if(loop_name == 0) return NULL; // This s
hould never bethe case. // Now have the edge_name
-th edge in the loop_name-th loop of the face/bend
line/forming. // Now we have the face/bendline to
whichthe edge belongs. if(mi_show_3d) two_d_body
= three_d_body->get_3D_version(); else two_d_bo
dy = three_d_body->get_flat(); if(! two_d_body) r
eturn NULL; if(loop_name == 1) loop = two_d_body-
>get_bloop(); else {count = 1; for(loop = two_
d_body->get_first_hole(); loop; loop =(BM_LOOP *)l
oop->next()) { if(! loop) return NULL; ++count;
if(count== loop_name) break;} } // Now we have
the loop to which the edge belongs. if(loop == N
ULL) return NULL; // A trivial bendline
waspicked. count = 0; for(edge = loop->get_firs
t_edge(); edge; edge = (BM_EDGE *)edge->next()) {i
f(! edge) break;++count;if(count == edge_name)brea
k; } // Now we have the edge itself. return edg
e;/* three_d_name= list_name/10000; loop_name =
list_name%10000; // loop_name-th の中の edge_nam
e 番目の edge loop_name /= 100; // loop of the
three_d_name 番目のthree-d-body, edge_name = lis
t_name%100; //最初のthree-d-bodyとして最初のベン
ドラインと共にに開始. if(three_d_name > (ml_num_b
endlines + ml_num_faces)) return NULL;
// 描かれるものはフォーミングである。 if(!
loop_name) return NULL; // 描かれるものはトリビ
アルなベンドラインである。 if(three_d_name > ml
_num_bendlines) { // three_d_body は面である。
for(three_d_body = part->get_face_list();three_d
_body; three_d_body = (B
M_3D_BODY *)three_d_body->next()) { if(! thre
e_d_body) return NULL; ++count; if((ml_num_bendl
ines + count) == three_d_name) break;} } else
{ // three_d_body はベンドラインである。 for(t
hree_d_body = part->get_bendline_list(); three_d_b
ody; three_d_body = (BM_
3D_BODY *)three_d_body->next()) { if(! three_
d_body) return NULL; ++count; if(count == three_
d_name) break; } }// この時点でエッジが属する
面/ベンドラインを持つ。 if(mi_show_3d) two_d_body
= three_d_body->get_3D_version(); else two_d_bod
y = three_d_body->get_flat(); if(! two_d_body) re
turn NULL; if(loop_name == 1) loop = two_d_body->
get_bloop();else { count = 1; for(loop = two
_d_body->get_first_hole(); loop; loop = (BM_LOOP
*)loop->next()) { if(! loop) return NULL; ++coun
t; if(count == loop_name) break;} }// この時点で
エッジが属するループを持つ。count = 0; for(edge =
loop->get_first_edge(); edge; edge = (BM_EDGE *)e
dge->next()) {if(! edge) break;++count;if(count ==
edge_name) break;} return edge;*/} // This func
tion returns the number of items currently in the
selection set.long CBendCADViewPart::get_number_of
_selected_items(void){ return m_selection_set.lis
t_size();}/* これにより、他のクラスが選択セットを
得ることができる。選択された項目は、配列selected_i
tems_array 内でパスバックされる; それは、この配列
が十分な大きさであることを保証するユーザの義務であ
る。サイズnum_requested*2 の配列は確かに十分であ
る。この関数は、もし多くのものが得られるときは、 n
um_requested 項目までパスバックする。戻り値は、実
際にパスバックされた項目の個数である。配列中の復帰
された項目のフォーマットは次のように与えられる。 s
elected_items_array[2*i -2] は描かれたエッジのOpen
GL Display List idを含み、またselected_items_array
[2*i -1] はそのエッジに対するベンドモデルポインタ
を含む。例えば、 selected_items_array[0], selected
_items_array[1]は, 選択セットなど,選択セット中のnu
m_requested番目の項目に対する配列[2*num_requested
-2],配列array[2*num_requested -1] までの全てのもの
を含む。エッジポインタがNULLのときは更に、 N をこ
のエッジのopenG1 display list id (N は長いタイ
プ)とする必要がある。ケース A): もし N/10000 >
(num_bendlines_in_part +num_faces_in_part) なら
ば、ユーザはN-(num bendlines + num faces)のフォー
ミングを取り上げている。例えば、num bendlines = 4,
num faces = 3, numformings = 5, N/10000 =9, など
のエッジポインタは空である。このとき、ユーザは二回
目のフォーミングを取り上げている。ケースB): もし(N
%10000)/100== 0 (すなわち、N の100 番目の桁がゼロ)
ならば、ユーザはトリビアル(曲げられてない)なベン
ドラインのセンタラインを取り上げている。ベンドライ
ンは(N/10000) 番目のベンドラインである。例えば、N/
10000 = 3, エッジポインタはNULLであり,(N%10000)/1
00=0 である。ユーザは、たまたま曲げてない第三番面
目のベンドラインを取り上げている。(あなたが驚いて
も、この部分は少なくとも3 個のベンドラインを持つこ
とが保証される。)*/long CBendCADViewPart::get_sele
cted_items(long num_requested, long *selected_item
s_array) { if(selected_items_array == NULL) retur
n 0; long i = m_selection_set.display(num_request
ed, selected_items_array); return i;} // This al
lows others to clear the selection set.void CBendC
ADViewPart::clear_selection_set(void){int size = m
_selection_set.list_size(); long *array = new long
[(size<<1) + 1]; m_selection_set.di
splay(size, array);for(long i=0; i < size; ++i)
{ if(array[(i<<1) + 1]) delete (BV_SELECT_DATA*)a
rray[(i<<1) + 1];} m_selection_set.remove();delet
e [] array;}// Thisfunction writes a RenderWare ma
trix’s rotation part into an array[16],which can
be used by// OpenGL. int CBendCADViewPart::convert
_rw_matrix_to_gl_array(RwMatrix4d *rw_matrix, doub
le *array){ RwReal rw_array[4][4], *test; test =
RwGetMatrixElements(rw_matrix, rw_array); if(! t
est)return 0; int i, j; for(i=0; i < 4; ++i) {
for(j=0; j < 4; ++j)array[4*i + j] = rw_array[i]
[j]; } array[15] = 1.0; array[3] = array[7] = a
rray[11] = 0.0; return 1;} // This function al
lows you to set the drawing mode: show_solid = 1 f
or solid, 0 for wireframe.// This function assumes
that the part has not changed.void CBendCADViewPa
rt::set_drawing_mode(int show_solid){ if(show_sol
id) OnViewShaded();else OnViewWireframe();}// This
function allows you to set the current view of th
epart: show_3d = 1 for 3d version,// 0 for flat.//
This function assumesthat the part has not change
d.void CBendCADViewPart::set_current_view(int show
_3d){if(show_3d) OnShow3d();else OnShowFlat();}//
This allows youto set both solid/wireframe (show_s
olid = 0/1) and flat/3d_version (show_3d = 0/1).//
If flat is asked for, the picture shown is top vi
ew, zoomed-all.// If 3d is asked for and flat is c
urrently in view, the picture shown is 3d, isometr
ic, zoomed-all.// If 3d is asked for and 3d is alr
eady currently in view, the view volume is not cha
nged.// If part_has_changed is not zero, re-faceti
ng is done.void CBendCADViewPart::set_drawing_view
_mode(int show_solid, int show_3d, int part_has_ch
anged){int show_3d_isometric = 0;if( (! mi_show_3
d) && (show_3d) )show_3d_isometric = 1;mi_show_sol
id = show_solid;mi_show_3d = show_3d; int i; BM_
PART *part = NULL; CBendCADDoc* pDoc = GetDocumen
t(); ASSERT_VALID(pDoc); part = pDoc->get_par
t(); if(! part) { mi_part_is_up_to_date = 0;
return; }mi_part_is_up_to_date = 1;if(part_has_ch
anged) { compute_part_centroid(part, 0, &m_flat
_part_centroid); // Compute 3d and flat part centr
oids. compute_part_centroid(part, 1, &m_3d_part
_centroid); }if(mi_show_solid) { // Renderware s
tuff.if(mi_show_3d) { if(part_has_changed ||(! m_
3d_base_clump)) { i = facet_part_rw(part, &
m_3d_base_clump,mi_show_3d, md_part_color); i
f( (! i) || (! m_3d_base_clump) ) return;}RwRemove
ClumpFromScene(m_base_clump); m_base_clump = m_
3d_base_clump; RwAddClumpToScene(m_scene, m_bas
e_clump);}else { if(part_has_changed || (! m_flat
_base_clump)) { i = facet_part_rw(part, &m_
flat_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_3d_base_clump) ) return;}RwRemov
eClumpFromScene(m_base_clump); m_base_clump =m_
flat_base_clump; RwAddClumpToScene(m_scene, m_b
ase_clump);}}else {// OpenGl stuff. i = prepar
e_display_list(part, mi_show_3d, 1, 0, 1,1, md_fac
e_color, md_bendline_color); if(! i) { mi_
display_list_is_up_to_date = 0; return; }
mi_display_list_is_up_to_date = 1; if(mi_show_3
d) { mi_3d_is_up_to_date = 1; mi_flat_i
s_up_to_date = 0;}else { mi_3d_is_up_to_date
= 0; mi_flat_is_up_to_date= 1;}} mi_bbox_is_up
_to_date = 0;if(mi_show_3d) m_part_centroid = m_3d
_part_centroid;else m_part_centroid = m_flat_part_
centroid;if(part_has_changed) {ml_num_faces = part
->get_number_of_faces();ml_num_bendlines = part->g
et_number_of_bendlines();ml_num_formings = part->g
et_number_of_formings();} ml_last_function_chosen
= RETURN_FROM_DIALOG_MODE;if(show_3d_isometric)
{ OnZoomAll();return;}if(! mi_show_3d) { OnViewT
op();return;}return;} 付録F コメント付きファイルを含むメインを自動寸法化するBM
APIの例/ *一般的注意:---------------***************--------
-------一般的注意:−自動寸法化パッケージはそのパ
ートが既に更新されている(すなわちパートの3Dバー
ジヨンが既に計算されている)と仮定する。そのパート
の現在の3Dバージヨンを取り、それを用いる。−04/0
2/96付の自動寸法化は、単にパートの3Dバージヨンに
対する寸法を生成する。−04/02/96付の自動寸法化は、
パートが厚みを持って示されていると仮定する(すなわ
ち、それは、我々が薄板の一側を示していないと仮定す
る。)。概要 :---------------***************------
---------自動寸法は2種類の描画を行う:- 全てのベン
ドラインに対するフランジ長さ- 全てのベンドラインに
対するベンドライン情報ベンドライン情報は、それが係
わるベンドラインを指示する小さなinfo-box内に描かれ
れる。このinfo-boxを描画する際の唯一の問題点は、ベ
ンドラインが可視であるか、どこにinfo-boxを描くか
(すなわち、それが良好に見え、他の成分に干渉せず、
例えば、他の事物と重ならないようにそれを描く画面上
の場所)、如何にそれをベンドラインと関係付けるかと
いうことにある。この成分は比較的容易である。ベンド
ラインのフランジ長さは、ベンドラインとこのベンドラ
インの側部の隣接フランジとの間の最大外側距離により
与えられる。ベンドラインは高々2つの隣接フランジを
持つことが出来、従って両隣接フランジに対してフラン
ジ長さを描かなければならないという点に注意された
い。実際、フランジ長さは、我々がディメンションポイ
ントと呼ぶ点の間で(距離として)描かれる。ここには
2種類のディメンションポイントがある。第一のものは
ベンドラインディメンションポイントである。フランジ
長さはベンドラインと隣接フランジの間の(最大外側)
距離なので、ベンドラインの側部のこれらのディメンシ
ョンポイントはベンドラインディメンションポイントと
呼ばれる。それらの位置は厳密にベンドラインにより定
義される。1本のベンドラインは隣接フランジの各々に
関して正確に2つのベンドラインディメンションポイン
トを持つことが出来る(少なくとも、 BendModel/BendC
ADの現在のバージヨンでは)という点に注意されたい。
2つのベンドラインディメンションポイントはそれぞれ
ベンドラインの2つの端部に対応する。更に、通常は、
両隣接フランジに対するこれらのベンドラインディメン
ションポイントの対は一致する点に注意されたい。すな
わち、隣接フランジAに対するンドラインディメンショ
ンポイント(Aに対して2つのベンドラインディメンシ
ョンポイントがある)と他の隣接フランジBに対するベ
ンドラインディメンションポイントと同じものがある。
すなわち、それらは特に同一ではないが、同じ値を持
つ。ベンドラインディメンションポイントはインタセク
シヨン近似(ベンド角が90度程度)またはタンジェン
ト近似(ベンド角が90度以上のとき)を用いて計算さ
れる。もしベンド角が90程度のときは、インタセクシ
ヨン近似点は一致するので、両隣接フランジに対するベ
ンドラインディメンションポイントの対は同じになる。
他の種類のディメンションポイントはフランジディメン
ションポイントである。それらは、ベンドラインカラ最
も離れたベンドラインの側のベンドラインに隣接するフ
ランジ上の点である。フランジが正しい(すなわち、非
空)とすると、少なくとも1つのフランジディメンショ
ンポイントがある。ただし、理論的には、フランジディ
メンションポイントの個数には上限はない。次の重要な
点に注目されたい。もしフランジAが、ベンドラインB
に隣接し、更にその最遠点において(すなわち、Bに対
するフランジディメンションポイントにおいて)ベンド
ラインCに隣接すると、Aに対するBのフランジディメ
ンションポイントは、実際にはAに対するCの同じベン
ドラインディメンションポイントである(あるいは、ベ
ンドラインBとCが平行と仮定すると、さもなければ事
態はトリッキーになり、それは最早真ではない。)。フ
ランジディメンションポイントは、寸法はフランジの側
で描かれなければならないので、フランジの角で計算さ
れる。以下は自動寸法化作業の方法である。:---------
-----------------------------*********************
*****************---------------------------------
-----それは異なる2つのタスクに分割される。1つは
全てのディメンションポイント(共に、ベンドラインデ
ィメンションポイントとフランジディメンションポイン
ト)を計算するものである。この段階で、我々は、フラ
ンジ長さを描くことが出来る全てのディメンションポイ
ントを計算する。潜在的には、これは単に一度行うこと
が出来、またもし部分が変化しないときは、我々は、自
動寸法が描かれなければならない度にこの情報を後に再
使用することが出来る。(ただし、部分は通常は変化し
ない−ユーザが部分を回転させるとき、ビユーアは、カ
メラ(これは通常なされる)ではなく、実際には部分を
回転させる)従って、部分の3D座標は変化しない。し
かし、この種の変化により影響されない部分のフラット
部分に基づいて我々の計算をすることが出来るのである
が、幸運にも全てのディメンションポイントの計算はか
なり早く、全ての時点でディメンションポイントを再計
算することが可能であると思われる。私は丁度、我々
が、もし必要なら、これらのディメンションポイントを
一度予め計算し、後にそれらを再使用することにより時
間を節約出来るということを指摘したい。我々が全ての
ディメンションポイントを計算すると、我々は寸法を描
くことが出来る。ただし、われわれは先ず、ディメンシ
ョンポイントのどれが可視であり、どれがそうでないか
を解決しなければならない。割れれ我ワイヤフレーム像
を持つときは、それはかなり容易である。ディメンショ
ンポイントは、もしそれがビユーウインド内にあるとき
は可視である。これのチェックは非常に速くできる。我
々が中実(陰影)像を持つときは、通常ビユーアに近い
フランジがはるかに離れた他のフランジのビユーをブロ
ックし、同様に幾つかのディメンションポイントをブロ
ックすることから、事態はより困難である。そこで、我
々は或る種の隠されたラインの除去を行う必要がある。
我々が、どのディメンションポイントが可視であるかを
決定すると、フランジ長さは一連の異なる方法で描くこ
とが出来、その場合我々は1つ、望ましくは最良のもの
を取り上げなければならない。注意:フランジ長さを示
すためには、ベンドラインディメンションポイントとフ
ランジディメンションポイントを必要とする。1つの発
見的な方法は、ビユーアに近接し、サイドウエイ距離が
最小のベンドライン−フランジ−ディメンションポイン
トを用いることにより与えられる。我々が全てのベンド
ラインに対するディメンションポイントを取り出すと、
我々は寸法を描くことが出来る。自動寸法化の主要デー
タ構造:----------------------------------------***
*************************************-------------
---------------------------3種類の使用対象物があ
る。BM_AUTO_DIMENSION-----------------BM_AUTO_DIME
NSIONは、トップレベルのAuto-Dimension対象物であ
り、通常はBM_PARTと共にBendCAD書類の一部である。そ
れは、自動寸法が描かれるBM_PARTに対するポインタ、
並びに書類、ビユーおよびデバイスコンテクトポインタ
を含む。それは更に、ビユーウインドサイズ、ベンドラ
インの個数、 BM_AD_bendline対象物などのようなハイ
レベルの情報を含む。将来(現在04/03/96),
それは、ラインカラーやライン幅、フォントサイズなど
のようなペンやブラシ特性についての情報を格納すべき
である。BM_AD_bendline--------------BM_AD_bendline
は1つのBM ADベンドラインに関係する全ての自
動寸法情報を格納する。また、隣接フランジの各々に対
して内蔵の2つのベンドラインディメンションポイント
を有する。また、隣接フランジの各々に対してフランジ
ディメンションポイントのリストへのポイントを有す
る。BM_AD_dim_corner----------------BM_AD_dim_corn
erはディメンションポイント(ベンドラインかフランジ
のいずれか)である。ディメンションポイントは1また
は3BM_POINTのいずれかを有することが出来る。ディメン
ションポイントの1つの重要なメンバは開放方向であ
る。それは、このディメンションポイントに関する実際
のディメンションが描かれなければならない方向を指示
する。更に、このディメンションポイントが可視である
方向を指示する。もしそれが可視のときは、それはその
BM_POINTの全ての画面座標を格納する。*/#ifndef BMAP
I_AUTO_DIM_HXX_INCLUDED#define BMAPI_AUTO_DIM_HXX_
INCLUDED// include some BMAPI include files#includ
e "POINT.HXX"#include "VECTOR.HXX"#include "LINE.H
XX"#include "PLANE.HXX"#include "CYLINDER.HXX"#inc
lude "2D_BODY.HXX"#include "3D_BODY.HXX"#include "
BEND_OP.HXX"#include "BENDLINE.HXX"#include "PART.
HXX"// include header for mesh to determine clear
regions for drawing#ifndef __AD_MESH_H__#include "
AD_Mesh.h"#endif// some BendCAD classesclassCBendC
ADDoc ;class CBendCADViewPart ;// Auto-Dimension c
lassesclass BM_AD_dim_corner ;class BM_AD_bendline
;class BM_AUTO_DIMENSION ;/*********** **********
********** ********** ********** ********** *****
***** ********** ********** 自動寸法定数**********
********** ********** ********** ********** *****
***** ********** ********** ********** */// dimens
ionline length is 30 pixels#define PIXELS_PER_DIME
NSION_LINE30.0// arrow angle is 30 degrees//#defin
e ARROW_ANGLE0.524// arrow length is 15 pixels//#d
efine PIXELS_PER_ARROW15.0// this is the distance
tolerance used inAuto-Dimension#define AUTODIM_DIS
TANCE_TOLERANCE0.001/*********** ********** ******
**** ********** ********** ********** ********** *
********* ********** この種の対象物は、ディメンシ
ョンを描くことが出来るディメンションポイントを表
す。********** ********** ********** ********** **
****************** ********** ********** *********
* */class BM_AD_dim_corner{friend BM_AUTO_DIMENSIO
N ;friend BM_AD_bendline ;/*********** **********
********** ********** ********** ********** ******
**** ********** **********全てのデータメンバはPriv
ateなものである。********** ********** **********
********** ********** ********** ********** ******
**** ***********/private :// Auto-Dimension BM_AD_
bendline object that owns this dimension point// B
M_AD_bendline *bend ;// this is the 3D-body in the
part thathas to be visible (actually some points
on this// body have to be visible) in order for th
is dimension point to be drawable.// note : this i
s used only when we are in solid mode.// // usuall
y, for bend-dim points, this points to the bendlin
e, and for flange-dim points // points to the flan
ge. // However, when this dimension point contains
only one point (point p), some special // conside
rations come into effect.// BM_3D_BODY *body_requi
red_visible ;// this variable is used only when we
are drawing in a solid mode.// if TRUE, we will i
gnore this dimension point as if itwas not visibl
e.// // in solid mode we will be using this heuris
tic in order to save time.// when two bendlines ar
e using equivalent flange-dimension points for (po
tentially)// displaying flange-length, we will onl
ycompute the visibility information only// for the
bendline (of these twobendlines) which has the la
rger idx.// // this is initialized to FALSE,and se
t to TRUE only after all other dim-point computati
ons// have beendone.// int ignore_in_solid_mode ;/
/ Sometimes when the point in the part for which w
e want to draw dimensions is a// bendline (either
inside or outside) such that the radius and thickn
ess both are not 0,// we haveto draw two short lin
es (as in the picture following) that connect the/
/outsides of adjacent flanges. However, sometimes
(when both radius andthickness // are 0, or the po
int is just an outside edge of a face) we need onl
y one point.// To capture these two cases, we eith
er compute three points between which the // short
line have to be drawn, or just one point (in whic
h case no short lines are needed).// // --
---------- p2// | \|/// | p ------
----bbFFFFFFFFFFFF// || bbb F// t
wo | | bbb F// short -----> | b F//
lines | b bbFFFFFFFFFFFF// |b
b // |b b // bb // b b//
p1 FFFFFFFF// F F// F F// F F// F F// F F/
/ // this is the number of points that we have com
puted here. itis either 1 or 3.// int num_of_point
s ;// // p is always the centerpoint to which the
dimension arrow should be connected to// (actually
it iswhat we call a ’dimension-line-extensio
n’).// if we have computed morethan 1 point, p1 a
nd p2 are the side-points.// // IMPORTANT : p1 is
onthe plane of the adjacent body for which the fla
nge length is being drawn.// // Note : point p is
always computed.// BM_POINT p, p1, p2 ;// thisvari
able is used when this dimension point is a flange
dimension point,and// the edge in the flange, for
which this flange dimension points was computed,
// is adjacent to a bendline. adj_bendline points
to that bendline.// // this is used to avoid drawi
ng some flange-length twice. forexample, in this p
icture// // B2-----------------// |// | A//
|// |// ---------------B1// //
we want to draw dimensions for face A in the midd
le only once. That means that if// we draw flange
length for bendline B1 with respect to A, we shoul
d not draw it for //bendline B2 (with respect to
A).// BM_BENDLINE *adj_bendline ;// this vector po
ints to the direction in which the dimension shoul
d be drawn forthis dim-point.// // IMPORTANT : thi
s vector should be normalized.// BM_VECTOR opening
_direction ;// // if this is TRUE, we can reverse
the opening_direction if we need.// sometimes the
dimension point correcponds to an extreme point of
an arc. in that case it does// not matter on whic
hside we are drawing the dimension arc (ie. we can
reverse the opening direction).// int can_reverse
_opening_dir ;// // these variable are usedonly wh
en this dimension point is actually drawn.// pos_l
en is the length of the dimension-line-extension d
rawn in the direction of the openingvector.// neg_
len is the length of the dimension-line-extension
drawn inthe direction opposite to // the opening v
ector.// // they are initially set to 0 when the v
isibility of this point is computed.// // the purp
ose is that we can use them to avoid redrawing the
same extension line, if several // other dimensio
n points need it.// // Note : as of 04/02/96these
points are not used. KK.// double pos_len, neg_len
;// +1, this dimension point is visible and the d
imension arc can be drawn for this point.// 0, th
is dimension point is not visible.// -1, we don’t
know if this dimension points is visible.// // in
itially we set this to -1 and use it to compute th
e visibility information on demand// (ie. only whe
n wewant to know if this points is visible. someti
mes we don’t care).// int visible ;// these are t
he actual view window coordinates of all 3 points.
// int screen_x, screen_x1, screen_x2 ;int screen_
y, screen_y1, screen_y2 ;// // this is the z-buffe
r value of the point p when rendered.// double z_b
uf_value ;// this is used to construct lists of di
m-points.// BM_AD_dim_corner *next ;/*********** *
********* ********** ********** ********** *******
*** ********** ********** **********Privateのメン
バ関数。自動寸法によってのみ用いられる。**********
********** ********** ********** ********** *****
***** ********** ********** ***********/// this fu
nction computes the visibility of this dimension p
oint.// it handles wireframe and solid modes separ
ately.// this function checks strict visibility.//
void compute_visibility(CBendCADViewPart *view) ;
// this function will draw the dim-point in the gi
ven device context.// this is really just a debug
function.// void draw_with_dim_line(CBendCADViewPa
rt *view, CDC *dc, double object_space_per_pixel)
;// given a bendline dimension point and a list o
f flange dimension points, this function// returns
TRUE iff there is a way to display the flange-len
gth-dimension using these points // (ie. there is
a pair of points that is visible) or FALSE if not.
// If it returns TRUE, it also returns the best fl
ange dimension point ;as well as// the distance be
tween the bendline dimension point p and thebest f
lange dimension point p, // with respect to the be
ndline dimension point.// // Note that the best di
stance returned could be negative since it is the
k-factor with respect// to the bendline-dimension-
opening-direction-vector.// Remember : bendline-di
mension-opening-direction-vector should be normali
zed.// // this function checks strict visibility./
/ friend int compute_best_dim_pair(CBendCADViewPar
t *view, BM_AD_dim_corner*bend_dim_point,BM_AD_dim
_corner *flange_dim_list, double object_space_per_
pixel, // OUTPUT parametersdouble *best_distance /
* distance of thebest flange-dim points found */,B
M_AD_dim_corner **best_flange_dim_point/* the best
flange-dim points */) ;// this function draws one
flange length dimension. the first argument is a
bendline dimension point,// thesecond is a flange
dimension point.// this function might allow cases
where some dimension extension line is a little-b
it// outside the view window.// however, endpoints
of the dimension arrow have to be within the view
window.// friend void draw_dim_point(BM_AD_dim_co
rner *bend_dim_point, BM_AD_dim_corner *flange_dim
_point, CBendCADViewPart *view, CDC *dc,double obj
ect_space_per_pixel) ;/*********** ********** ****
****** ********** ********** ********** **********
********** **********公共のメンバ関数********** *
********* ********** ********** ********** *******
*** ********** ********** ***********/public :BM_A
D_dim_corner(void) ;// thisconstructor is for crea
ting a dimension point that has only one point (po
int p) in it.// BM_AD_dim_corner(BM_POINT const&
p, BM_AD_bendline *bend, BM_3D_BODY *body_required
_visible, BM_VECTOR const& opening_direction, int
reverse_bit, BM_AD_dim_corner **prev, BM_BENDLINE
*adj_bendline) ;// this constructor is for creatin
g a dimension point that has 3 pointsin it.// BM_A
D_dim_corner(BM_POINT const& p, BM_POINT const& p
1, BM_POINT const& p2, BM_AD_bendline *bend, BM_3D
_BODY *body_required_visible, BM_VECTOR const& ope
ning_direction, int reverse_bit, BM_AD_dim_corner
**prev, BM_BENDLINE *adj_bendline) ;// to assign o
ne dimension point to another dimension point// it
copies contents exactly. not sure if it is a very
useful function.// void operator=(BM_AD_dim_corne
r const &) ;// thisfunction will return TRUE iff t
he given point is, for the purpose of drawing dime
nsions,// the same as this point. // Two dimension
points points are equivalent iff the point p of o
ne of them is on the// line definedby the line (po
int p, opening direction) of the other dimension p
oint,// and their opening directions match.// // h
ere we depend on the fact that opening vectors are
normalized.// // it returns 2 iff both points p m
atch, otherwise 1.// int operator==(BM_AD_dim_corn
er const& another_dim_point) ;} ;/*********** ****
****** ********** ********** ********** **********
********** ********** ********** この種の対象物
は、1ベンドラインに係わる自動寸法化データを表す。
ベンドラインに対する基本のAD操作は隣接するフラン
ジ長さを描くことである。技術的注意 :- tベンドライ
ンディメンションポイントとフランジディメンションポ
イントの開放方向ベクトルは相関付けされない。それ
は、あなたは、同じ開放方向を持つ2点に対シテチェッ
クするべきである。- アルゴリスム:先ず、我々は全て
のベンドラインに対する全てのベンドラインディメンシ
ョンポイントを計算する。次に、我々は、全てのベンド
ラインに対する全てのフランジディメンションポイント
を計算する。その理由は、我々がフランジディメンショ
ンポイントを計算するとき、フランジ内の、および他の
ベンドラインに隣接する幾つかのエッジがあるというこ
とである。全てのベンドラインディメンションを先ず計
算するときは、他のBM_AD_bendline構造のベンドライン
ディメンションポイントからこれらのベクトルを取るこ
とが出来る。********** ********** ********** *****
***** ********** ********** ********** **********
********** */class BM_AD_bendline{friend BM_AUTO_D
IMENSION ;friend BM_AD_dim_corner ;/*********** **
******** ********** ********** ********** ********
** ********** ********** **********全てのデータメ
ンバはprivateなものである。********** ********** *
********* ********** ********** ********** *******
*** ********** ***********/private :/*********** *
********* ********** ********** ********** *******
*** ********** ********** **********これらのデータ
メンバはコンストラクタにより設定される。**********
********** ********** ********** ********** *****
***** ********** ********** ***********/// informa
tion stored in this BM_AD_bendline object refers t
o this bendline.// ie. this dimension point is dra
wn to show the flange length of this bendline.// B
M_BENDLINE *bend ;// thisobject belongs to this Au
to-Dimension object.// BM_AUTO_DIMENSION *parent ;
/*********** ********** ********** ********** ****
****** ********** ********** ********** **********
これらのデータメンバは、ベンドラインディメンション
ポイントデータ構造が、 BM_AD_bendline::compute_BM_
AD_bendline(...).で計算されるとき計算される。*****
***** ********** ********** ********** **********
********** ********** ********** ***********/// if
FALSE, this data for this object has not been yet
computed, or the computation failed.// this means
that this object will always be ignored, no matte
r what.// this can be set to TRUE only by BM_AD_be
ndline::compute_BM_AD_bendline(...).// int data_va
lid ;// number of adjacent bodies for whichwe have
to draw dimensions. either 0, 1 or 2.// int num_o
f_adjacent_bodies ;// every bendline is adjacent t
o at most two bodies.// either of these can be NUL
L. you should always check for that.// // adj_body
1 is theadjacent body that has the smaller idx.//
adj_body2 is the adjacent bodythat has the larger
idx.// BM_3D_BODY *adj_body1 ;BM_3D_BODY *adj_body
2;// this is the flange length with respect to eac
h of the adjacent bodies// double fl1 ;double fl2
;/*These parameters are computed some time during
the process and are needed later, so forperforman
ce reasons we store them so that we don’t have to
recompute them later.Each of them is avector poin
ting towards the adjacent body (from the bendline)
and isona plane tangent to end end-point of the b
end-arc touching the adjacent body.*/BM_VECTOR sid
e_vector1 ;BM_VECTOR side_vector2 ;/*これらのパラ
メータは、プロセス中にしばしば計算され、後に必要と
され、そこで性能理由に対して我々はそれらを、我々が
それらを後に再計算する必要がないように格納する。そ
れらの各々は(ベンドラインから)隣接体に向け指示す
るベクトルであり、隣接体に接触するベンドアークの端
点に対して接線をなす平面上にある。 これらは主要デ
ータ構造の幾つかである。 各々の隣接体に対して、ベ
ンドラインの各々の端点(すなわち、左および右)に対
して1つの2つ端点を持つ。これらの点は、フランジ長
に対する寸法がベンドラインで(すなわち、ベンドライ
ンの側部で)描くことが出来る点を特定する。注意:現
在(04/02/96)、我々は全てのベンドラインに
おいてディメンションを描くため正確に2つの可能な点
を考える。これらの2つの点はベンドラインセンタライ
ンの方向のベンドラインの2つの最端点である。注意:
これらはベンドラインのベンドラインディメンションポ
イントと呼ばれる。注意:これらの点は、例えadj
body1およびadj body2が空であっても常
に計算される。*/BM_AD_dim_corner bend_body1_point_
left, bend_body1_point_right ;BM_AD_dim_corner ben
d_body2_point_left, bend_body2_point_right ;// the
se variables indicate whether theleft(right) bendl
ine dimension points // with respect to adj-body1
and adj-body2 are respectively equivalent.// these
points should be computedright after bend_body1_p
oint_left, bend_body1_point_right,// bend_body2_po
int_left, bend_body2_point_right are computed.// /
/ if 0, they are notequivalent.// if 2, they are e
quivalent, and points p match.// if 1, they are eq
uivalent, but points p don’t match (ie. on the sa
me line, butsome distance apart).// // for us, equ
ivalence value 2 is the only really useful one, be
cause in that case we can // trust that when one i
s visible, the other is too, without checking. in
that case they have the// same screen coordinates
as well.// // note the same means not the same poi
nters, but the contents are equivalent.// int body
12_left_the_same ;intbody12_right_the_same ;/*ここ
にディメンションポイントの2つのリストがある。1つ
はadj-bodyに関するもので、他はadj−body2に
関するものである。両リストはフランジ長ディメンショ
ンポイントである点を含む。注意:これらはベンドライ
ンのフランジディメンションポイントと呼ばれる。*/BM
_AD_dim_corner *body1_points ;BM_AD_dim_corner *bo
dy2_points ;/*********** ********** ********** ***
******* ********** ********** ********** *********
***********これらのデータメンバは、ディメンション
が描かれるとき用いられる。********** ********** **
******** ********** ********** ********** ********
** ********** ***********/// if this is TRUE, this
bendline structure should be ignored for the purp
ose of drawing dimensions.// this is usually used
when we have a simultaneous bendline. in that case
we have todraw// dimensions for only one of them,
the rest should be ignored.// int ignore ;// if T
RUE, the adjacent body already has its flange leng
th drawn.// // if the value is 2, this bendline dr
ew the flange dimension with respect to the adj bo
dy.// if the value is 1, some other bendline drewt
he flange dimension with respect to the adj body./
/ int body1_drawn ;int body2_drawn ;// when we dra
w flange length for adjacent bodies, we will memor
ize the point at which the// dimensions were draw
n.// actually the dimensions are always drawn betw
een two points - one at the bendline,// the other
at the farthest point on the adjacent body (ie. be
ndline dimension point and// flange dimension poin
t).// // the reason we need tomemorize these point
s is that sometimes the flange-length-dimension//
with respect to one bendline is also the flange-le
ngth dimension with respect to the// other bendlin
e. in that case we want to avoid drawing the same
thing twice.// // the first two points are bendlin
e dimension points.// other two are flange dimensi
on points.// // reason #2 : when we drawbendline d
imensions with respect to adj-body1 and adj-body2,
// it depends whether the bend angle is acute or n
ot. if the bend angle is not morethan// 90 degree
s, then most likely we will be able to use the sam
e dimension-point at the bendline// to draw both f
lange length’s. However, if the bend angle is mor
e than 90 degrees, we will// be using the tangent-
dimension-point at the bendline and these points a
re different for// each adjacent body. In general,
we want to know, before we draw a dimension-point
at a// bendline, if we can use any of the dimensi
on-points already drawn at this bendline.// // not
e these points do not have to part ofthis AD_bendl
ine structure.// BM_AD_dim_corner *drawn_bend_dim_
point1 ;BM_AD_dim_corner *drawn_bend_dim_point2 ;B
M_AD_dim_corner *drawn_flange_dim_point1 ;BM_AD_di
m_corner *drawn_flange_dim_point2 ;/*********** **
******** ********** ********** ********** ********
** ********** ********************Privateメンバ−
関数********** ********** ********** ********** **
******** ********** ********** ********** ********
***/// This function computes bendline dimension p
oints of this BM_AD_bendline structure.// Note tha
t bend-dimension points will always be computed, e
ven if adj_body1 and adj_body2// are NULL.// int c
ompute_BM_AD_bendline(void) ;// This function comp
utes flange dimensions points of this BM_AD_bendli
ne structure // with respect to one adjacent body.
// int compute_BM_AD_flange_points(BM_3D_BODY *adj
_body) ;// This function computes the visibility o
f all bendline dimension points of the bendline.//
note the the visibility of bend-dimension points
with respect to adj-body1 is always// computed, ev
en if adj_body1 pointer is NULL.// This is needed
for drawing bendline info-boxes.// void compute_be
ndline_dim_points_visibility(void) ;//this functio
n computes which dimension points are best to draw
flange length for this bendline.// // this functi
on does it strictly for one bendline.// void compu
te_dim_points_to_display_indiv(BM_AD_bendline *bes
t_AD_bendline[2] /* best AD_bendline structure so
far */, BM_AD_dim_corner*bodies_bend_flange[6] /*
0,1 is bend-dim points; 3,4 is flange-dim points;
4,5 is flange lists */,double distance_and_z[4] /*
0,1 is distance;3,4 is z-buf */) ;// this functio
n does it for a given bendline, takinginto account
simultaneous bendlines.// this function uses the
previous function.// void compute_dim_points_to_di
splay(void) ;// this function draws flange length
dimensions for this bendline.// it uses the inform
ation computed by compute_dim_points_to_display()
function.// void draw_dimension_points(void) ;/***
******** ********** ********** ********** ********
** ********** ********** ********** **********公共
メンバ−関数********** ********** ********** *****
***** ********** ********** ********** **********
***********/ public :// some trivial
constructors,destructors.BM_AD_bendline(BM_AUTO_DI
MENSION *owner, BM_BENDLINE *bendline) ;~BM_AD_ben
dline(void) ;} ;/*********** ********** **********
********** ********** ********** ********** *****
***** ********** この対象物は部分に対して自動ディ
メンションを生成するために用いることが出来る。****
****** ********** ********** ********** **********
********** ********** ********** ********** */cla
ss BM_AUTO_DIMENSION{friend BM_AD_dim_corner ;frie
nd BM_AD_bendline ;/*********** ********** *******
*** ********** ********** ********** ********** **
******** **********すべてのデータメンバはprivateで
ある。********** ********** ********** **********
******************** ********** ********** *******
****/private :// this is the document to which thi
s auto-dim object is attached to.// also, this is
where we get the part.// CBendCADDoc *doc ;// view
in which we draw the dimensions.// usually the vi
ew attached to the document.// CBendCADViewPart*vi
ew ;int view_size_x, view_size_y ;// device contex
t in which we drawthe dimensions.// CDC *dc ;// th
is is the part for which we will createdimensions.
// BM_PART *part ;// is TRUE iff 3D view is being
displayed,FALSE if flat.//int view_type ;// half o
f the metal thickness// double half_metal_thicknes
s ;// if TRUE, we need to recompute auto dimension
bendline and point data structures// int dirty ;/
/ number of bendlines in the part// int num_of_ben
dlines ;// this is an array of bendlines for which
flange length has to be drawn.// BM_AD_bendline *
*bends ;// this is the distance in object space th
at gets mapped into one pixel on the screen.// we
use it to draw lines of fixed pixel length (in tha
t case object-space length varies).// double objec
t_space_per_pixel ;// if this variable is TRUE, it
will set the flag which will trigger// auto-dimen
sions tobe drawn to FALSE in the view class, once
dimensions are drawn.// however, once it is done,
this variable will be set to FALSE automatically./
/int reset_view_to_false_once_drawn ;// every time
we construct new dim-point data structures, we se
t this to FALSE.// when points which can beignored
in solid mode have been computed, we set it to TR
UE.// int points_to_ignore_in_solid_computed ;// p
ointer to mesh for determining clearareas of the s
creen to draw dimension info//CAutoDimRgnMesh *pMe
sh;// region to keep track of dirty screen areas//
CRgn* pDirtyRegion;public:// Booleans for the show
state of dimension info//BOOL m_bShowFlangeDim;BO
OLm_bShowBendDim;BOOL m_bShowPartDim;// COLORREFs
for drawing dimensions//COLORREF m_crFlange;COLORR
EF m_crBend;COLORREF m_crPart;// pointers tofonts/
/CFont* m_pFlangeFont;CFont* m_pBendFont;CFont* m_
pPartFont;// line and arrow parameters//int m_nLin
eStyle;int m_nLineWeight;// in pixelsint m_nArrowS
tyle;int m_nArrowAngle;// in degreesint m_nArrowLe
ngth;// inpixels/*********** ********** **********
********** ********** ********** ********** *****
***** **********Privateメンバ関数********** ******
**** ********** ********** ********** ********** *
********* ********** ***********/private :// This
function is used to propagate the effects of drawi
ng a flange length for a given bendline,// to acco
unt for the fact that the flange dimension point i
s adjacent to the given adj-body.// it returns TRU
E iff the adj-bend will be marked as drawn as well
with respectto the given flange.// int compute_ef
fects_flange_length_drawn(BM_BENDLINE *bendline, B
M_3D_BODY *adj_body /* flange length with respect
to this body are being drawn */, BM_AD_dim_corner
*bend_dim_point /* bend dimpoint for bendline */,
BM_AD_dim_corner *flange_dim_point /* flange dimpo
ints for bendline */, BM_BENDLINE *adj_bend /* fla
nge dim points is adjacent to this bendline */) ;/
/ this function returns a pointer to the BM_AD_ben
dline structure that contains data // about the gi
ven bendline.// BM_AD_bendline *get_AD_bend_struct
ure(BM_BENDLINE *bendline) ;// thisfunction will r
eturn TRUE iff adj_bend has a flange-dimension poi
nt withrespect to the// given flange, that is adja
cent to the given bendline.// // a handy function.
// int check_two_bendlines_adjacent_to_same_flange
(BM_BENDLINE *bendline, BM_3D_BODY *flange, BM_BEN
DLINE *adj_bend) ;// just a debug function// void
test_draw(void) ;// Check if we can ignore some po
ints in solid mode.// // in solid mode we will be
using this heuristic in order to save time.// when
two bendlines are using equivalent flange-dimensi
on points for (potentially)// displaying flange-le
ngth, we will only compute the visibility informat
ion only// for the bendline (ofthese two bendline
s) which has the higher idx.// void compute_points
_to_ignore_in_solid(void) ;// this function draws
a box with bendline data for every bendline.// voi
d draw_bendline_data(CDC *pdc) ;/*********** *****
***** ********** ********** ********** **********
********** ********** **********公共メンバ関数****
****** ********** ********** ********** **********
********** ********** ********** ***********/publ
ic :BM_AUTO_DIMENSION(CBendCADDoc *BendCAD_doc) ;~
BM_AUTO_DIMENSION(void) ;// this function returns
a (p->p2) vector for a given bendline with respect
to a given adj-body.// // It also computes a line
between the p2 points of thebend dimension points
of the adjacent bendline // with respect to this
flange.// BM_VECTOR const& compute_bend_direction_
vector(BM_BENDLINE *bendline, BM_3D_BODY *adj_bod
y, BM_LINE *p2_line) ;// destroy the contentsof th
is Auto-Dimensions object,// void delete_contents
(void) ;// To seta new part. This updates the view
class pointer as well.// void set_part(BM_PART *n
ew_part) ;// to force AD to recompute the dimensio
n points.//inline void invalidate(void) { dirty =
1 ; }// get current view type when points were com
puted// inline int get_view_type(void) const { ret
urnview_type ; }// this function will build auto d
imension bendline and point data structures.// //
This is the main function for computing dimension
points.// int compute_auto_dimension_data(void) ;/
/ draw flange dimension data//void draw_dim_point
(BM_AD_dim_corner *bend_dim_point, BM_AD_dim_corne
r *flange_dim_point, CBendCADViewPart *view, CDC *
dc, double object_space_per_pixel);// to draw part
dimensions in this device context//int draw_auto_
dimensions(CDC *target_dc) ;// Used with draw_auto
_dimensions to construct a geometric pen// with us
er-defined styles. This is necessary to draw patte
rned thick lines.//CPen* create_auto_dim_pen(CPen*
pPen, int nLineStyle, int nLineWeight, COLORREF c
r) ;// this will enableus to draw part dimension o
nly once//inline void disable_view_dimensions_flag
_next_time(void) { reset_view_to_false_once_drawn
= 1 ; }} ;#endif// BMAPI_AUTO_DIM_HXX_INCLUDED 付録G 機能を描く自動寸法化の例。これらの関数は、デイメン
シヨンポイントが既に計算されていることを仮定する。
【0296】///*ディメンションポイントを計算する関
数はAD_POINTS.CPP内にある。先ず、どのディメンショ
ンポイントが可視であるか、そうでないかを検出する必
要がある。次に、フランジ長ディメンションを描く方法
を決定しなければならない。*/#include "stdafx.h"#in
clude "BendCAD.h"#include "BendCADDoc.h"#include "
BendCADViewPart.h"#include "BCAD_CTXT.HXX"#include
"AD_Arrow.h"#include"AUTODIM.HXX"/*********** ***
******* ********** ********** ********** *********
* ********** ********** **********BM_AD_dim_corner
クラススタッフ********** ********** ********** ***
******* ********** ********** ********** *********
* ***********//*この関数はディメンションポイントの
可視度を計算する。*/void BM_AD_dim_corner::compute
_visibility(CBendCADViewPart *view){int i, j, k ;d
ouble z_buf ;// by default, the points is not visi
blevisible = 0 ;if (num_of_points < 1) return ;//
note : when in wireframemode, we don’t have to ch
eck if points p1 and p2 actually// map into the sa
me bendline/flange points. in solid mode we need t
o check.// checkif we have solid or wireframe mod
e.if (view->get_drawing_mode()) goto solid_picture
;/*ワイヤフレームは、このディメンションポイントが
実際に最前面にある3D体か否かをチェックしない(原
文不明) ワイヤフレームモードでは、我々は、ビユー
ウインドにおける全ての事態が可視であると仮定する。
*///get visibility datai = view->map_point_to_clos
est_edge(p, &screen_x, &screen_y, &z_buf_value, NU
LL) ;if (! i) return ;if (num_of_points > 1) {i= v
iew->map_point_to_closest_edge(p1, &screen_x1, &sc
reen_y1, &z_buf, NULL) ;if (! i) return ;i = view-
>map_point_to_closest_edge(p2, &screen_x2, &screen
_y2, &z_buf, NULL) ;if (! i) return ;}// process v
isibility datapos_len = neg_len = 0.0 ;visible = 1
;return ;/*ソリッドモードで示されたパート*/solid_
picture :// here we keep pointers to 3D-bodies tha
t haveto be visible.BM_3D_BODY *visible_bodies[4]
;visible_bodies[0] = body_required_visible ;if (b
ody_required_visible->is(BM_ENTITY_TYPE_BENDLINE))
{visible_bodies[1] = (((BM_BENDLINE *) body_requir
ed_visible)->get_adj_list())->find_lowest_id_adj_b
ody() ;visible_bodies[2] = (((BM_BENDLINE *) body_
required_visible)->get_adj_list())->find_second_lo
west_id_adj_body() ;visible_bodies[3] = NULL ;}els
e visible_bodies[1] = NULL ;// handlecases when th
ere is just one point differently from when there
are 3 points.// if there is only 1 point, we have
a complete paper-part - thickness and radius both
0.// in that case there is really no bendline. we
have to check any of the adjacent bodies.if (num_o
f_points < 2) {// if this is a bend-dimension poin
t, the body_required_visible pointer should point
to the // adjacent body with respect to this dimen
sion point is computed.i = view->is_3d_body_near_p
oint(p, visible_bodies, &i, &screen_x, &screen_y,
&z_buf_value) ;if (! i) return ;}else {/*ソリッド
発見手法:これはソリッドモードを操作する新しいバー
ジヨンである。先ず、全ての3点p,p1および2がビ
ユーウインド内にあるかをチェックする。もし真なら、
我々は、ベンドアークのサイドプロフィルのセンタ点を
計算し、この点におけるベンドラインが実際に可視か否
かをチェックする。*/i = view->map_point_to_closest
_edge(p, &screen_x, &screen_y, &z_buf_value, NULL)
;if (! i) return ;/*ソリッド発見手法 :開放方向が
反転出来ないとき、それが指示していないかをチェック
する。if (! can_reverse_opening_dir) {BM_POINT p_o
pening_direction(p+ opening_direction) ;view->map_
point_to_closest_edge(p_opening_direction, &j, &k,
&z_buf, NULL) ;if (z_buf > (z_buf_value + 0.001))
return ; // ここで、特定の大きな公差を用いる// 開
放方向は指示している}*/// check if points p1 and p
2 are in the view window as well.i = view->map_poi
nt_to_closest_edge(p1, &screen_x1, &screen_y1, &z_
buf, NULL) ;if (! i) return;i = view->map_point_to
_closest_edge(p2, &screen_x2, &screen_y2, &z_buf,
NULL) ;if (! i) return ;BM_VECTOR v_pp1(p,p1) ;BM_
VECTOR v_pp2(p,p2) ;BM_POINT p_center ;double angl
e_alpha = (v_pp1 ^ v_pp2)/2.0 ;if (angle_alpha < P
I_over_2) {BM_VECTOR v_p1p2(0.5*(p2 - p1)) ;BM_POI
NT temp_p(p1 +v_p1p2) ;BM_VECTOR v_tip(p,temp_p) ;
double z = (v_pp1.Len())/cos(angle_alpha) ;double
y = z*sin(angle_alpha) ;v_tip.set_length((z - y) +
(bend->parent)->half_metal_thickness) ;p_center =
p + v_tip ;}else p_center =p ;i = view->is_3d_bod
y_near_point(p_center, visible_bodies, &i, &j, &k,
&z_buf) ;if (! i) return ;/* これはソリッドモード
を操作する古いバージヨンである。ここで我々は、ポイ
ントpがビユーウインド内にあるか否かをチェックし、
更にポイントp1およびp2が基礎をなす可視の3D体を持
つか否かをチェックする。// もし我々が3点を持つと
きは、点pは3D体上にはない。従って、我々は、それ
が有るか否かをチェックするのみである。// ビユーウ
インド内に。view->is_3d_body_near_point(p, NULL, &
i, &screen_x, &screen_y, &z_buf_value) ;if (! i) r
eturn ;// ポイントp1およびp2は3D体上になければなら
ない。i = view->is_3d_body_near_point(p1, visible_
bodies, &visibility_count, &screen_x1, &screen_y1,
&z_buf) ;if (! i) return ;i = view->is_3d_body_ne
ar_point(p2, visible_bodies, &visibility_count, &s
creen_x2, &screen_y2, &z_buf) ;if (! i) return ;*
/}// process visibility datapos_len = neg_len = 0.
0 ;visible = 1 ;}/*この関数は所定のデバイスコンテ
クスト内にdim-pointを描く。これは実際にはデバッグ
関数である。*/void BM_AD_dim_corner::draw_with_dim
_line(CBendCADViewPart *view, CDC *dc, double obje
ct_space_per_pixel){int i, j ;double x ;static POI
NT points[3] ;BOOL res ;// if this point is not kn
own to be visible, return.if (visible < 1) return
;if(num_of_points < 1) return ;points[1].x = scre
en_x ;points[1].y = screen_y ;// draw dimension li
neBM_POINT p_dim_line(p + (PIXELS_PER_DIMENSION_LI
NE * object_space_per_pixel)*opening_direction) ;v
iew->map_point_to_closest_edge(p_dim_line, &i, &j,
&x, NULL) ;points[2].x = i ;points[2].y= j ;if (c
an_reverse_opening_dir) {p_dim_line = p + (-PIXELS
_PER_DIMENSION_LINE * object_space_per_pixel)*open
ing_direction ;view->map_point_to_closest_edge(p_d
im_line, &i, &j, &x, NULL) ;points[1].x = i ;point
s[1].y= j ;res = dc->Polyline(points + 1, 2) ;poin
ts[1].x = screen_x ;points[1].y = screen_y ;}else
res = dc->Polyline(points + 1, 2) ;if (num_of_poin
ts < 2) return ;points[0].x = screen_x1 ;points
[0].y = screen_y1 ;points[2].x = screen_x2 ;points
[2].y = screen_y2 ;res = dc->Polyline(points,3) ;}
/*この関数は1フランジ長ディメンションを描く。 第
一の引数はベンドラインディメンションポイントであ
り、第二はフランジディメンションポイントである。*/
void BM_AUTO_DIMENSION::draw_dim_point(BM_AD_dim_c
orner *bend_dim_point, BM_AD_dim_corner *flange_di
m_point, CBendCADViewPart *view, CDC*dc, double ob
ject_space_per_pixel){int i, j ;double x, y, z, do
tp, half_dim_line ;BOOL res ;// points with screen
coordinates. Windows type.static POINT points[3]
;// these variable store the coordinates of the d
im-line-extension endpointsdouble bend_end_x, flan
ge_end_x ;BM_POINT bend_end_p, flange_end_p ;BM_VE
CTOR end_v(bend_dim_point->opening_direction);// t
hese variables store arrow head endpointsBM_POINT
bend_arrow_p, flange_arrow_p ;// compute the dimen
sion line extensionBM_VECTOR v((flange_dim_point->
p) - (bend_dim_point->p)) ;x = v % (bend_dim_point
->opening_direction) ;if (fabs(x) > AUTODIM_DISTAN
CE_TOLERANCE) { // we have to extend at least one
dimension linehalf_dim_line = (PIXELS_PER_DIMENSIO
N_LINE * object_space_per_pixel)/2.0 ;// here we w
ill first compute extensionlines, then the arrow,
and then the dimension points themselvesif (x <0.
0) {// here we assume that for bendline, we cannot
reverse the openingdirection.// it must be that t
he flange-dim points has a valid openingdirection
in the same direction// as the bend-dim point.// /
/ arrow point is to the right of the bend-dim poin
t.bend_arrow_p = (bend_dim_point->p) + half_dim_li
ne*end_v ;if (! view->map_point_to_closest_edge(be
nd_arrow_p, &i, &j, &y, NULL)) return ;points[0].x
= i ;points[0].y = j ;flange_arrow_p = (flange_di
m_point->p) + (-x + half_dim_line)*end_v ;if (! vi
ew->map_point_to_closest_edge(flange_arrow_p, &i,
&j, &y, NULL)) return;points[1].x = i ;points[1].y
= j ;half_dim_line *= 2.0 ;bend_end_x = half_dim_
line ;flange_end_x = -x + half_dim_line ;bend_end_
p = bend_dim_point->p + bend_end_x*end_v ;flange_e
nd_p = flange_dim_point->p + flange_end_x*end_v ;}
else {// here we assume that for bendline, we cann
ot reverse the opening direction.dotp = (bend_dim_
point->opening_direction) % (flange_dim_point->ope
ning_direction) ;// first lets try if we can rever
sethe flange-dim point opening directionif (dotp <
0.0 || flange_dim_point->can_reverse_opening_dir)
{// try to draw the arrow in the middle//// arrow
point is midway between flange- and bend-dim poin
ts.z = x/2.0 ;bend_arrow_p = (bend_dim_point->p) +
z*end_v ;if (! view->map_point_to_closest_edge(be
nd_arrow_p, &i, &j, &y, NULL)) goto try_other_dire
ction ;points[0].x = i ;points[0].y = j ;flange_ar
row_p = (flange_dim_point->p) + (-z)*end_v ;if (!
view->map_point_to_closest_edge(flange_arrow_p, &
i, &j,&y, NULL)) goto try_other_direction ;points
[1].x = i ;points[1].y = j ;bend_end_x = z + half_
dim_line ;flange_end_x = -x - half_dim_line ;bend_
end_p = bend_dim_point->p + bend_end_x*end_v ;flan
ge_end_p = flange_dim_point->p + flange_end_x*end_
v ;goto begin_to_draw ;}try_other_direction :if (d
otp > 0.0 || flange_dim_point->can_reverse_opening
_dir) {// arrow point is to the right of the flang
e-dim point.bend_arrow_p = (bend_dim_point->p) +
(x + half_dim_line)*end_v ;if (! view->map_point_t
o_closest_edge(bend_arrow_p, &i, &j, &y, NULL)) re
turn ;points[0].x = i ;points[0].y= j ;flange_arro
w_p = (flange_dim_point->p) + half_dim_line*end_v
;if (! view->map_point_to_closest_edge(flange_arr
ow_p, &i, &j, &y, NULL)) return ;points[1].x = i ;
points[1].y = j ;half_dim_line *= 2.0 ;bend_end_x=
x + half_dim_line ;flange_end_x = half_dim_line ;
bend_end_p = bend_dim_point->p + bend_end_x*end_v
;flange_end_p = flange_dim_point->p + flange_end_
x*end_v ;}else return ; // failure, cannot draw be
cause opening direction don’t match or not visibl
e.}}else { // no need to extend dimension lines//
check the direction of opening vectorif (end_v %
(flange_dim_point->opening_direction) < 0.0) {if
(! flange_dim_point->can_reverse_opening_dir) end_
v.reverse() ;}bend_end_x = flange_end_x = (PIXELS_
PER_DIMENSION_LINE * object_space_per_pixel) ;bend
_end_p = bend_dim_point->p +bend_end_x*end_v ;flan
ge_end_p = flange_dim_point->p + flange_end_x*end_
v ;bend_arrow_p = bend_dim_point->p + (bend_end_x/
2.0)*end_v ;flange_arrow_p = flange_dim_point->p +
(flange_end_x/2.0)*end_v ;// compute arrowendpoin
tsif (! view->map_point_to_closest_edge(bend_arrow
_p, &i, &j, &y, NULL)) return ;points[0].x = i ;po
ints[0].y = j ;if (! view->map_point_to_closest_ed
ge(flange_arrow_p, &i, &j, &y, NULL)) return ;poin
ts[1].x= i ;points[1].y = j ;}begin_to_draw :/*ア
ローを描く。*/// draw arrow line. points[0] is the
bend-dim-points side of the arrow.res = dc->Polyl
ine(points, 2) ;// draw arrowsBM_VECTOR v_arrow(fl
ange_arrow_p - bend_arrow_p) ;x = v_arrow.Len() ;
// this is the real flange length// change tosolid
pen for arrow headsCPen* pArrowPen = new CPen(PS_
SOLID, BCAD_context.m_nFlangeLineWeight, BCAD_cont
ext.m_crFlange);CPen* pOldPen = dc->SelectObject(p
ArrowPen);// compute arrow head at bend sideCAutoD
imArrow arrowBend(CPoint(points[0].x,points[0].y),
CPoint(points[1].x,points[1].y),BCAD_context.m_nAr
rowAngle,BCAD_context.m_nArrowLength);arrowBend.Dr
awHead(dc);// compute arrow head at flange sideCAu
toDimArrow arrowFlange(CPoint(points[1].x,points
[1].y),CPoint(points[0].x,points[0].y),BCAD_contex
t.m_nArrowAngle,BCAD_context.m_nArrowLength);arrow
Flange.DrawHead(dc);dc->SelectObject(pOldPen);dele
te pArrowPen;// write flange length on the screeni
nt center_x = (points[0].x + points[1].x) >> 1 ;in
t center_y = (points[0].y + points[1].y) >> 1 ;int
font_height = 21 ;double dx = (double)(points[1].
x - points[0].x) ;double dy = (double) (points[1].
y - points[0].y) ;if (fabs(dx) > AUTODIM_DISTANCE_
TOLERANCE) {if (dy/dx > 0.0) center_y -= font_heig
ht ;}center_x += 3 ; // move the beginning to the
right so that it won’t overlap the arrow line.CSt
ring str;str.Format("%6.4f",x);CSize sizeTextExten
t = dc->GetTextExtent(str);if (pDirtyRegion != NUL
L){CPoint pntText(center_x, center_y);CRect rectTe
xt(pntText, sizeTextExtent);if (!pDirtyRegion->Rec
tInRegion(&rectText))dc->TextOut(center_x,center_
y, str);CRgn rgn;rgn.CreateRectRgn(center_x, cente
r_y, center_x+ sizeTextExtent.cx, center_y + sizeT
extExtent.cy);pDirtyRegion->CombineRgn(pDirtyRegio
n, &rgn, RGN_OR);}else{pDirtyRegion = new CRgn();p
DirtyRegion->CreateRectRgn(center_x, center_y, cen
ter_x + sizeTextExtent.cx, center_y + sizeTextExte
nt.cy);dc->TextOut(center_x, center_y, str);}/*ben
d-dim-pointsにp1,p2を描く必要があるならば*/points
[1].x = bend_dim_point->screen_x ;points[1].y = be
nd_dim_point->screen_y ;if (bend_dim_point->num_of
_points > 1) {points[0].x = bend_dim_point->screen
_x1 ;points[0].y =bend_dim_point->screen_y1 ;point
s[2].x = bend_dim_point->screen_x2 ;points[2].y =
bend_dim_point->screen_y2 ;res = dc->Polyline(poin
ts, 3) ;}//draw dimension line extensionview->map_
point_to_closest_edge(bend_end_p, &i, &j, &x, NUL
L) ;points[2].x = i ;points[2].y = j ;res = dc->Po
lyline(points + 1, 2) ;/*flange-dim-pointsに対して
p1,p2を描く必要があるならば*/points[1].x = flange_
dim_point->screen_x ;points[1].y = flange_dim_poin
t->screen_y ;if (flange_dim_point->num_of_points >
1) {points[0].x = flange_dim_point->screen_x1 ;po
ints[0].y = flange_dim_point->screen_y1 ;points
[2].x = flange_dim_point->screen_x2 ;points[2].y =
flange_dim_point->screen_y2 ;res = dc->Polyline(p
oints, 3) ;}// draw dimension line extensionview->
map_point_to_closest_edge(flange_end_p, &i, &j, &
x, NULL) ;points[2].x = i ;points[2].y = j ;res =
dc->Polyline(points + 1, 2) ;}/*ベンドラインディメ
ンションポイントおよびフランジディメンションポイン
トが与えられると、この関数は、もしこれらのポイント
を用いてflange-length-dimensionを表示する方法が有
るときはTRUEを戻し、(すなわち、全てが可視である)
またはもしそうでないときはFALSEWO戻す。もしそれがT
RUEのときは、それは更に最良のフランジディメンショ
ンポイントを戻し;同様にベンドラインディメンション
ポイントに関してベンドラインディメンションポイント
pと最良のフランジディメンションポイントpの間の距離
を戻す。戻された最良の距離は、それが、bendline-dim
ension-opening-direction-vectorに対してK因子のた
めに負になり得る。ここでこの関数は、dimension-exte
nsion-linesが:1つのdimension-extension-lineが単位
長さであり、また他のものが、第一のものに達するのに
必要な程度に長いように描かれることを仮定する。すな
わち、この関数はディメンションポイントの1つに隣接
するディメンションアローを描く。すなわち、それは2
つのディメンションポイントの間のラインの途中の或る
点でディメンションポイントを描くことを試みない。想
起:bendline-dimension-opening-direction-vectorは
規格化されるべきである。注意:ここでこの関数は、di
mension-extension-linesが:1つのdimension-extension
-lineが単位長さであり、また他のものが、第一のもの
に達するのに必要な程度に長いように描かれることを仮
定する。すなわち、この関数はディメンションポイント
の1つに隣接するディメンションアローを描く。すなわ
ち、それは2つのディメンションポイントの間のライン
の途中の或る点でディメンションポイントを描くことを
試みない。注意:この関数において、dim pointが可視
でない場合直接チェックしない(別の関数を呼び出
す)。表示されているウインドウの中にいくつかのdime
nsion-extension-lineがあるかをチェックする。注意:
この関数において、ディメンションアローが進む点をチ
ェックする。それらが厳密にビユー領域内に有ることを
要求される。注意:この関数において、実際には近似位
置を用いる。すなわち、発見手法として。*/int comput
e_best_dim_pair(CBendCADViewPart *view, BM_AD_dim_
corner *bend_dim_point,BM_AD_dim_corner *flange_di
m_list, double object_space_per_pixel, // OUTPUT p
arametersdouble *best_distance /* 見出された最良の
flange-dim points の距離 */,BM_AD_dim_corner **bes
t_flange_dim_point /* 最良のflange-dim points */)
{BM_VECTOR v ;BM_POINT dim_arrow_point ;int i, j,k
;double x, y, dotp ;// if the bendline dimension
point is not known to be visible, return FALSE.//
otherwise we might be wasting our time.if(bend_dim
_point->visible < 1) return 0 ;// scan the list of
flange dimension pointsBM_AD_dim_corner *temp_poi
nt, *best_fdp = NULL ;double best_distance_so_far
;for (temp_point = flange_dim_list ; temp_point ;
temp_point = temp_point->next) {if (! temp_point-
>visible) continue ;/*ソリッド発見手法 :ソリッドモ
ードにおいて、我々は時間を節約するためにこの発見的
手法を用いている。2つのベンドラインがフランジ長を
表示するために(潜在的に)等価なflange-dimension p
ointsを用いているときは、我々は単に、より高いidxを
持つベンドライン(これらの2つのベンドラインの)に
対してのみ可視度を計算する。*/if (view->get_drawin
g_mode() && temp_point->ignore_in_solid_mode) cont
inue ;// compute a vector from bend-dim-p to flang
e-dim-pv = (temp_point->p) - (bend_dim_point->p) ;
x = v % (bend_dim_point->opening_direction) ;// ch
eck that opening directions are valid.// idea : if
bothvectors points in opposite directions are we
cannot reverse them,// we cannot use these two dim
ension points to draw dimensions.dotp = (bend_dim_
point->opening_direction) % (temp_point->opening_d
irection) ;if (dotp <0.0 && ! temp_point->can_reve
rse_opening_dir && ! bend_dim_point->can_reverse_o
pening_dir) continue ;// check that the point wher
e the dimension arrow would go is in the view area
// note : we will use half-of-the-minimal-extensio
n-length as the unit separating // zero and non-ze
ro length extension lines.if (fabs(x) > AUTODIM_DI
STANCE_TOLERANCE) {k = 0 ; //if k is TRUE at the e
nd, we can draw the dimension arrow pointif (x <
0.0) {// note : add space for a line segment where
we will draw the arrow// // check if the directio
ns agree. // we check this first, because it would
give us a smaller distance.if (dotp > 0.0) {dim_a
rrow_point = (temp_point->p) + (-x)*(bend_dim_poin
t->opening_direction) ;if (view->map_point_to_clos
est_edge(dim_arrow_point, &i, &j, &y, NULL)) k = 1
;}// checkthat the extension of the bend-dim-line
is visible.// in that case the opening direction
of the flange-dime-line does not matter.if (!k &&
bend_dim_point->can_reverse_opening_dir) {dim_arro
w_point = (bend_dim_point->p) + (x)*(bend_dim_poin
t->opening_direction) ;if (view->map_point_to_clos
est_edge(dim_arrow_point, &i, &j, &y, NULL)) k = 1
;}}else { // x > 0.0// note : add space for a lin
e segment where we will draw the arrow.// // check
if the extension line is visible.// we check this
first, becauseit would give us a smaller distanc
e.if (dotp < 0.0 || temp_point->can_reverse_openin
g_dir) {dim_arrow_point = (temp_point->p) + (-x)*
(bend_dim_point->opening_direction) ;if (view->map
_point_to_closest_edge(dim_arrow_point, &i, &j, &
y, NULL)) k = 1 ;}// otherwise check if the direct
ionsagree.if (!k) {dim_arrow_point = (bend_dim_poi
nt->p) + (x)*(bend_dim_point->opening_direction) ;
if (view->map_point_to_closest_edge(dim_arrow_poin
t, &i, &j, &y, NULL)) k = 1 ;}}if (!k) continue ;
// cannot draw the dimension arrow point}// check
if visibility information is already computed.// i
f not, compute it. if flange dimension points not
visible, continue.if (temp_point->visible < 0) {te
mp_point->compute_visibility(view) ;if (! temp_poi
nt->visible) continue ;}// check if this new dista
nce is the best distanceif (best_fdp) {if (fabs(be
st_distance_so_far) > fabs(x)){best_fdp = temp_poi
nt ;best_distance_so_far = x ;}}else {best_fdp = t
emp_point ;best_distance_so_far = x ;}// check if
we are done.// if we have a point with a distance
0, we are done since we cannot find a betterpoint.
if (best_fdp && fabs(best_distance_so_far) <= AUTO
DIM_DISTANCE_TOLERANCE) break ;}if (best_fdp) {*be
st_distance = best_distance_so_far ;*best_flange_d
im_point = best_fdp ;return 1 ;}return 0 ;}/******
***** ********** ********** ********** **********
********** ********** ********************BM_AD_be
ndline クラススタッフ********** ********** *******
************* ********** ********** ********** ***
******* ***********//*この関数はベンドラインの全て
のベンドラインディメンションポイントの可視度を計算
する。注意: 時間の節約のために、我々は、体1 、22の
左( 右) ポイントが等価であるか否かをチェックする。
*/void BM_AD_bendline::compute_bendline_dim_points
_visibility(void){CBendCADViewPart *view = parent-
>view ;// here we always compute the visibility of
adj-body1 bend-dimension points,// even though we
don’t check if adj_body1 pointer is NULL or not,
// because we might want to know the visibility ev
en if they don’t exist.// // in practice this sho
uld not be a problem because almost always there a
re two// adjacent bodies.// bend_body1_point_left.
compute_visibility(view) ;bend_body1_point_right.c
ompute_visibility(view) ;if (adj_body2) {if(2 == b
ody12_left_the_same) {if (bend_body2_point_left.vi
sible = bend_body1_point_left.visible) {// note we
are switching pointsbend_body2_point_left.screen_
x = bend_body1_point_left.screen_x ;bend_body2_poi
nt_left.screen_y = bend_body1_point_left.screen_y
;bend_body2_point_left.screen_x1 = bend_body1_poi
nt_left.screen_x2 ;bend_body2_point_left.screen_y1
= bend_body1_point_left.screen_y2 ;bend_body2_poi
nt_left.screen_x2 = bend_body1_point_left.screen_x
1 ;bend_body2_point_left.screen_y2 = bend_body1_po
int_left.screen_y1 ;bend_body2_point_left.z_buf_va
lue = bend_body1_point_left.z_buf_value ;}}else be
nd_body2_point_left.compute_visibility(view) ;if
(2 == body12_right_the_same) {if (bend_body2_point
_right.visible= bend_body1_point_right.visible) {/
/ note we are switching pointsbend_body2_point_rig
ht.screen_x = bend_body1_point_right.screen_x ;ben
d_body2_point_right.screen_y = bend_body1_point_ri
ght.screen_y ;bend_body2_point_right.screen_x1 = b
end_body1_point_right.screen_x2 ;bend_body2_point_
right.screen_y1 = bend_body1_point_right.screen_y2
;bend_body2_point_right.screen_x2 = bend_body1_po
int_right.screen_x1 ;bend_body2_point_right.screen
_y2 = bend_body1_point_right.screen_y1 ;bend_body2
_point_right.z_buf_value = bend_body1_point_right.
z_buf_value ;}}else bend_body2_point_right.compute
_visibility(view) ;}// else adj_body2 is NULL and
there is nothing to compute}/*この関数はそれを1つ
のベンドラインに対して厳密に行う。重要:それは単
に、どの方法が最良なものかを決定するが、ADが実際
にそれをそのように行うか否かを決定することはない。
ここで、それは他のデータ構造を更新する何らかかの方
法を実施する。端的には、それはADデータ構造のいず
れかを変えることはない。注意:始めは何らのチェック
もなされない。アイデア:この関数において、我々は、
異なるbend-flange-dimポイントの組み合わせに対する
値を割り当てる発見的手法を用いる。最終的には、我々
は最良の組み合わせを選択する。我々が用いる発見的手
法は、ベンドおよびフランジdimポイントの間の距離の
組み合わせ、プラスビユー画面からのbend-pointの距離
である。実際的なトリック:先ず我々は、最も良く知ら
れた距離の値が既に0であるか否かをチェックする。も
し0であるなら、我々は、この新しいbend−dim
ポイントが良好なz−buf値を持つときにのみ他のbe
nd-dimポイントに対して最良の一致を見出そうとする。
注意:4部分のテストの後、私は、これが丁度非常にわ
ずかな改善を与えることを見出す。それは恐らく5−1
0%KKである(原文不明)。*/void BM_AD_bendlin
e::compute_dim_points_to_display_indiv(BM_AD_bendl
ine *best_AD_bendline[2] /* これまでの最良のADベン
ドライン構造*/,BM_AD_dim_corner *bodies_bend_flang
e[6] /* 0、1はbend-dim構造であり、3、4はflange-di
mポイントであり、4、5はフランジリストである。 *
/,double distance_and_z[4] /* 0,1は距離であり、3、4
はz−bufである。*/){BM_AD_dim_corner *best_fdp
;double best_distance ;// check adjacent body1if
(adj_body1 && ! (body1_drawn)) {// check if we alr
eady have a distance 0 bend-flange-dim points. if
yes, go in only if the// new bend-dim points has a
strictly better z-buf value.if ((NULL == best_AD_b
endline[0]) || distance_and_z[2] > (bend_body1_poi
nt_left.z_buf_value + AUTODIM_DISTANCE_TOLERANCE)
|| distance_and_z[0] > AUTODIM_DISTANCE_TOLERANCE)
{if (compute_best_dim_pair(parent->view, &bend_bo
dy1_point_left, body1_points, parent->object_space
_per_pixel, &best_distance, &best_fdp)) {best_dist
ance = fabs(best_distance) ;// check if the new po
int is betterif (best_AD_bendline[0]) {// heuristi
c : if the sum of the z-buf value and distance is
smallerif ((best_distance + bend_body1_point_left.
z_buf_value) < (distance_and_z[0] + distance_and_z
[2])) {best_AD_bendline[0] = this ;bodies_bend_fla
nge[0] = &bend_body1_point_left ;bodies_bend_flang
e[2] = best_fdp ;bodies_bend_flange[4] = body1_poi
nts ;distance_and_z[0] = best_distance ;distance_a
nd_z[2] = bend_body1_point_left.z_buf_value ;}}els
e {best_AD_bendline[0] = this ;bodies_bend_flange
[0] = &bend_body1_point_left ;bodies_bend_flange
[2] = best_fdp ;bodies_bend_flange[4] = body1_poin
ts ;distance_and_z[0] = best_distance ;distance_an
d_z[2] = bend_body1_point_left.z_buf_value ;}}}//
check if we already have a distance 0 bend-flange-
dimpoints. if yes, go in only if the// new bend-di
m points has a strictly better z-buf value.if (dis
tance_and_z[2] > (bend_body1_point_right.z_buf_val
ue + AUTODIM_DISTANCE_TOLERANCE) || (NULL == best_
AD_bendline[0]) ||distance_and_z[0] > AUTODIM_DIST
ANCE_TOLERANCE) {if (compute_best_dim_pair(parent-
>view, &bend_body1_point_right, body1_points, pare
nt->object_space_per_pixel, &best_distance, &best_
fdp)) {best_distance = fabs(best_distance) ;// che
ck if the new point is betterif (best_AD_bendline
[0]) {// heuristic : if the sum of the z-buf value
and distance is smallerif ((best_distance + bend_
body1_point_right.z_buf_value) < (distance_and_z
[0]+ distance_and_z[2])) {best_AD_bendline[0] = th
is ;bodies_bend_flange[0] = &bend_body1_point_righ
t ;bodies_bend_flange[2] = best_fdp ;bodies_bend_f
lange[4] = body1_points ;distance_and_z[0] = best_
distance ;distance_and_z[2] = bend_body1_point_rig
ht.z_buf_value ;}}else {best_AD_bendline[0] = this
;bodies_bend_flange[0] = &bend_body1_point_right
;bodies_bend_flange[2] = best_fdp ;bodies_bend_fl
ange[4] = body1_points ;distance_and_z[0] = best_d
istance ;distance_and_z[2] = bend_body1_point_righ
t.z_buf_value ;}}}}// check adjacent body2if (adj_
body2 && ! (body2_drawn)) {//check if we already h
ave a distance 0 bend-flange-dim points. if yes, g
o in only if the// new bend-dim points has a stric
tly better z-buf value.if ((NULL == best_AD_bendli
ne[1]) || distance_and_z[3] > (bend_body2_point_le
ft.z_buf_value + AUTODIM_DISTANCE_TOLERANCE) || di
stance_and_z[1]> AUTODIM_DISTANCE_TOLERANCE) {if
(compute_best_dim_pair(parent->view, &bend_body2_p
oint_left, body2_points, parent->object_space_per_
pixel, &best_distance, &best_fdp)) {best_distance
= fabs(best_distance) ;// checkif the new point is
betterif (best_AD_bendline[1]) {// heuristic : if
the sum of the z-buf value and distance is smalle
rif ((best_distance + bend_body2_point_left.z_buf_
value) < (distance_and_z[1] + distance_and_z[3]))
{best_AD_bendline[1] = this ;bodies_bend_flange[1]
= &bend_body2_point_left ;bodies_bend_flange[3] =
best_fdp ;bodies_bend_flange[5] = body2_points ;d
istance_and_z[1] = best_distance ;distance_and_z
[3] = bend_body2_point_left.z_buf_value ;}}else {b
est_AD_bendline[1] = this ;bodies_bend_flange[1] =
&bend_body2_point_left ;bodies_bend_flange[3] = b
est_fdp ;bodies_bend_flange[5] = body2_points ;dis
tance_and_z[1] = best_distance;distance_and_z[3] =
bend_body2_point_left.z_buf_value ;}}}// check if
we already have a distance 0 bend-flange-dim poin
ts. if yes, go in only if the// new bend-dim point
s has a strictly better z-buf value.if (distance_a
nd_z[3] > (bend_body2_point_right.z_buf_value + AU
TODIM_DISTANCE_TOLERANCE) || (NULL == best_AD_bend
line[1]) || distance_and_z[1] > AUTODIM_DISTANCE_T
OLERANCE) {if (compute_best_dim_pair(parent->view,
&bend_body2_point_right, body2_points, parent->ob
ject_space_per_pixel, &best_distance, &best_fdp))
{best_distance = fabs(best_distance) ;// check if
the new point is betterif (best_AD_bendline[1]) {/
/ heuristic : if the sum ofthe z-buf value and dis
tance is smallerif ((best_distance + bend_body2_po
int_right.z_buf_value) < (distance_and_z[1] + dist
ance_and_z[3])) {best_AD_bendline[1] = this ;bodie
s_bend_flange[1] = &bend_body2_point_right;bodies_
bend_flange[3] = best_fdp ;bodies_bend_flange[5] =
body2_points;distance_and_z[1] = best_distance ;d
istance_and_z[3] = bend_body2_point_right.z_buf_va
lue ;}}else {best_AD_bendline[1] = this ;bodies_be
nd_flange[1] = &bend_body2_point_right ;bodies_ben
d_flange[3] = best_fdp ;bodies_bend_flange[5] = bo
dy2_points ;distance_and_z[1] = best_distance ;dis
tance_and_z[3] = bend_body2_point_right.z_buf_valu
e ;}}}}}/*この関数は、ベンドラインに対するフランジ
長さを描く方法を決定する。これは、サブルーチントシ
テ以前の関数を用いるものにおける以前の関数とは異な
っている。それは、ベンドラインに対するフランジ長デ
ィメンションを描く方法、従って全てのデータ構造を更
新する方法を決定する。更に、それは同時のベンドライ
ンを考慮する。*/void BM_AD_bendline::compute_dim_p
oints_to_display(void){// qualification checkif (N
ULL == bend) return ;BM_AD_bendline *bl ;long i ;/
/ these variable store the bendline dimension data
that will be used later to draw // 0,1 is with re
spect to adj-body1; 2,3 is with respect to adj-bod
y2BM_AD_dim_corner *bodies_bend_flange_list[6] ; /
/ 0,1 is bend-dim points; 2,3 is flange-dim point
s; 4,5 is flange listsdouble distance_and_z[4] ; /
/ 0,1 is distance; 2,3 is z-buf// this is the bend
line for whichwe will be drawing the dimensions.//
this is trivial when there is no simultaneous ben
dlines.BM_AD_bendline *best_AD_bendline[2] = { NUL
L, NULL} ;/*フランジ長を描く最良の方法を計算する。
同時のベンドラインを考慮する。*/// these variables
are for handling simultaneous bendline property t
hings.BM_BEND_PROPERTY *prop ;BM_LINKED_LIST_NODE
*prop_list ;DBM_ARRAY*bendlines ;BM_BENDLINE *bnd
;long size, this_bend_seen = 0 ;for (prop_list =
bend->get_properties() ; prop_list ; prop_list = p
rop_list->next()) {prop = (BM_BEND_PROPERTY *) pro
p_list->get_obj() ;if (prop->is(BM_TYPE_BEND_SIMUL
TANEOUS)) {bendlines = (DBM_ARRAY *) prop->get_ben
dlines() ;size = bendlines->get_size() ;for (i = 0
; i < size ; i++) {// get a bendline in the bend
property objectif (NULL == (bnd = (BM_BENDLINE *)
bendlines->get(i))) continue ;bl = parent->get_AD_
bend_structure(bnd) ;if (NULL == bl) continue ;if
(bl == this) this_bend_seen = 1 ;if (! bl->data_va
lid || bl->ignore) continue ;// compute how to dra
w flange length dimensions for this one bendline.b
l->compute_dim_points_to_display_indiv(best_AD_ben
dline, bodies_bend_flange_list, distance_and_z)
;}}}if (! this_bend_seen) { // make sure this ben
dline gets processedbl = parent->get_AD_bend_struc
ture(bend) ;if (bl && bl->data_valid && ! bl->igno
re) {bl->compute_dim_points_to_display_indiv(best_
AD_bendline, bodies_bend_flange_list, distance_and
_z) ;}}/*同時のベンドにおける全ての他のベンドライ
ンを"ignore"としてマークする。*/for (prop_list = b
end->get_properties() ; prop_list ; prop_list = pr
op_list->next()) {prop = (BM_BEND_PROPERTY *) prop
_list->get_obj() ;if (prop->is(BM_TYPE_BEND_SIMULT
ANEOUS)) {bendlines =(DBM_ARRAY *) prop->get_bendl
ines() ;size = bendlines->get_size() ;for (i = 0 ;
i < size ; i++) {// get next bendline in the bend
property objectif (NULL == (bnd = (BM_BENDLINE *)
bendlines->get(i))) continue ;bl = parent->get_AD
_bend_structure(bnd) ;if (NULL == bl) continue ;//
mark asignoreif (bl->adj_body1 && ! (bl->body1_dr
awn) && bl != best_AD_bendline[0]) {bl->body1_draw
n = 1 ;bl->drawn_bend_dim_point1 = bodies_bend_fla
nge_list[0] ;bl->drawn_flange_dim_point1 = bodies_
bend_flange_list[2] ;}if(bl->adj_body1 && ! (bl->b
ody2_drawn) && bl != best_AD_bendline[1]) {bl->bod
y2_drawn = 1 ;bl->drawn_bend_dim_point2 = bodies_b
end_flange_list[1] ;bl->drawn_flange_dim_point2 =
bodies_bend_flange_list[3] ;}}}}/*このベンドライン
を図に対してマークする。*/if (best_AD_bendline[0])
{best_AD_bendline[0]->body1_drawn = 2 ;best_AD_be
ndline[0]->drawn_bend_dim_point1= bodies_bend_flan
ge_list[0] ;best_AD_bendline[0]->drawn_flange_dim_
point1 = bodies_bend_flange_list[2] ;}if (best_AD_
bendline[1]) {best_AD_bendline[1]->body2_drawn = 2
;best_AD_bendline[1]->drawn_bend_dim_point2 =bodi
es_bend_flange_list[1] ;best_AD_bendline[1]->drawn
_flange_dim_point2= bodies_bend_flange_list[3] ;}/
*flange-dimポイントがベンドラインに隣接するか否か
をチェックする。ここではわれわれは同時的なベンドは
チェックしない、何故なら、我々が今ここで持つように
それらは正確に同じフランジリストを持つべきだからで
ある。*/BM_AD_dim_corner *temp_point ;if (best_AD_
bendline[0]) {for (temp_point = bodies_bend_flange
_list[4] ; temp_point ; temp_point = temp_point->n
ext) {if (NULL == temp_point->adj_bendline) contin
ue ;(best_AD_bendline[0]->parent)->compute_effects
_flange_length_drawn(best_AD_bendline[0]->bend,bes
t_AD_bendline[0]->adj_body1, bodies_bend_flange_li
st[0], bodies_bend_flange_list[2], temp_point->adj
_bendline) ;}}if(best_AD_bendline[1]) {for (temp_p
oint = bodies_bend_flange_list[5] ; temp_point ; t
emp_point = temp_point->next) {if (NULL == temp_po
int->adj_bendline) continue ;(best_AD_bendline[1]-
>parent)->compute_effects_flange_length_drawn(best
_AD_bendline[1]->bend,best_AD_bendline[1]->adj_bod
y2,bodies_bend_flange_list[1], bodies_bend_flange_
list[3], temp_point->adj_bendline) ;}}}/*この関数
はこのベンドラインに対するフランジ長さを描く。それ
は、compute dim points to display()関数により計算
された情報を用いる。TODO : この関数においては、わ
れわれは、ベンドラインデイメンシヨンポイントが既に
描かれているトラックを保持することが出来る。adj-bo
dy1およびadj-body2に対するベンドラインデイメンシヨ
ンポイントは一致する。その場合、それを一回だけ実際
に描くべきである。*/void BM_AD_bendline::draw_dime
nsion_points(){// qualification checkif (! data_va
lid || ignore) return ;if (adj_body1 && 2 == body1
_drawn) {parent->draw_dim_point(drawn_bend_dim_poi
nt1, drawn_flange_dim_point1, parent->view, parent
->dc, parent->object_space_per_pixel) ;}if (adj_bo
dy2 && 2 == body2_drawn) {parent->draw_dim_point(d
rawn_bend_dim_point2, drawn_flange_dim_point2, par
ent->view, parent->dc, parent->object_space_per_pi
xel) ;}}/*********** ********** ********** *******
*** ********** ********** ********** ********** **
********BM_AUTO_DIMENSION class stuff.********** *
********* ********** ******************** ********
** ********** ********** ***********//*これはデバ
ッグ関数である。*/void BM_AUTO_DIMENSION::test_dra
w(void){BM_AD_dim_corner *temp_point ;int i ;for
(i = 0 ; i < num_of_bendlines ; i++) {if (! bends
[i]->data_valid) continue ;if (bends[i]->adj_body
1) {(bends[i]->bend_body1_point_left).draw_with_di
m_line(view,dc,object_space_per_pixel) ;(bends[i]-
>bend_body1_point_right).draw_with_dim_line(view,d
c,object_space_per_pixel) ;for (temp_point = bends
[i]->body1_points ; temp_point ; temp_point = temp
_point->next) {temp_point->draw_with_dim_line(vie
w,dc,object_space_per_pixel) ;}}if (bends[i]->adj_
body2) {(bends[i]->bend_body2_point_left).draw_wit
h_dim_line(view,dc,object_space_per_pixel) ;(bends
[i]->bend_body2_point_right).draw_with_dim_line(vi
ew,dc,object_space_per_pixel) ;for (temp_point = b
ends[i]->body2_points ; temp_point ; temp_point =t
emp_point->next) {temp_point->draw_with_dim_line(v
iew,dc,object_space_per_pixel) ;}}}}/*この関数は全
てのベンドラインに対してベンドラインデータと共にi
nfo−boxを描く。アイデア:われわれは、ソリッ
ドモードではレンダウエアはその種の情報を提示しない
ため、ビユー領域における部分の可視部分のboundingボ
ックスをチェックしない。更に、しばしば、ユーザは部
分のデイメンシヨンを診るためにズームインし、その場
合、部分によりカバーされないビユーポートの部位はな
く、すなわちboundingボックスは全体のビー領
域をカバーし、実際には無用である。代わりに、我々は
ビユー領域のエッジに沿いベンドライン情報ボックスを
描いていることになる。我々はビユー領域を4領域に分
割し、info−boxが関係するベンドポイントにど
れがより近くても、それらの領域にベンドラインinf
oボックスを配置する。ここで当然、我々はビユーポー
トの左−右垂直エッジに沿いそれらのボックスを描く。
*/void BM_AUTO_DIMENSION::draw_bendline_data(CDC *
pdc){int i, j ;// these variablesare used to calcu
late the info-box size and to draw itint font_heig
ht =21 ;int font_avg_char_width = 8 ; // average w
idth of a characterint box_height = (font_height <
< 1) /* テキストの2列 */ ;int half_box_height =box
_height >> 1 ;int box_width = font_avg_char_width
* 15 ; // space for15 charactersint box_x ;int ver
t_space_per_box ;int offset ;// computemaximum num
ber of info-boxes we can draw.int half_max_num_inf
o_boxes = view_size_y / box_height ;if (half_max_n
um_info_boxes < 1) return ; // not enough screen s
paceint max_num_info_boxes = half_max_num_info_bo
xes << 1 ;/*我々が表示出来るベンドの個数を計算す
る。*/int num_bends_to_be_drawn = 0 ;for (i = 0 ;
i < num_of_bendlines ; i++) {if (! bends[i]->data_
valid || NULL == bends[i]->bend) continue ;// reme
mber, visibility of adj_body1 bend-dimension point
s is always computed.// here we only check visibil
ity with respect to adj_body1.// most likely visib
ility with respect to adj_body1 and adj_body2 is t
he same.if ((bends[i]->bend_body1_point_left).visi
ble || (bends[i]->bend_body1_point_right).visible)
{++num_bends_to_be_drawn ;}else continue ;if (num
_bends_to_be_drawn >= max_num_info_boxes) break ;
// out of view space}// check if there are any ben
dlines to be drawnif (0 == num_bends_to_be_drawn)
return ;/*ベンドラインポインタおよびエンドポイント
のy座標を記憶するためのスペースを割り当てる。*/BM_
AD_bendline **bendlines = new BM_AD_bendline*[num_
bends_to_be_drawn] ;if (NULL == bendlines) return
; // out of spacedouble *bend_y_coordinates = new
double[num_bends_to_be_drawn] ;if (NULL == bend_y
_coordinates) {// out of spacedelete [] bendlines
; return ; }BM_AD_dim_corner **bend_points = new
BM_AD_dim_corner*[num_bends_to_be_drawn] ;if (NULL
== bend_points) {delete [] bendlines ; delete []
bend_y_coordinates ; return ; }/*ベンドラインポイ
ンタおよびbend−dim−pointポインタを集
める。*/for (i = j = 0 ; i < num_of_bendlines ; i+
+) {if (! bends[i]->data_valid || NULL == bends[i]
->bend) continue ;if (! (bends[i]->bend_body1_poin
t_left).visible && ! (bends[i]->bend_body1_point_r
ight).visible) continue ;// first, decide which of
the endpoints we will usebendlines[j] = bends[i]
;if ((bends[i]->bend_body1_point_left).visible)
{if (! (bends[i]->bend_body1_point_right).visible)
bend_points[j] = &(bends[i]->bend_body1_point_lef
t) ;else {if ((bends[i]->bend_body1_point_left).z_
buf_value< (bends[i]->bend_body1_point_right).z_bu
f_value) bend_points[j] = &(bends[i]->bend_body1_p
oint_left) ;else bend_points[j] = &(bends[i]->bend
_body1_point_right) ;}}else bend_points[j] = &(ben
ds[i]->bend_body1_point_right) ;if (++j >= num_ben
ds_to_be_drawn) break ; // out of view space}/*inf
o-boxが画面のどの側にあるべきかに従ってポイントを
分類する。bend-line-dim-pointが画面の左側にない全
てのボックスを含む(少なくとも始めは)。*/int half
_screen = (view_size_x >> 1) ;i = 0 ; // i will be
topj = num_bends_to_be_drawn - 1 ; // j will be b
ottom// we will use these to temporarily store stu
ffBM_AD_bendline *p_bend ;BM_AD_dim_corner *p_bend
_point ;while (i < j) {while (i < j && bend_points
[i]->screen_x < half_screen) i++ ;while (i < j &&
bend_points[j]->screen_x >= half_screen) j-- ;// s
witch i and jif (i < j) {p_bend = bendlines[i] ;p_
bend_point = bend_points[i] ;bendlines[i] = bendli
nes[j] ;bend_points[i] = bend_points[j] ;bendlines
[j] = p_bend ;bend_points[j] = p_bend_point ;}}if
(bend_points[i]->screen_x < half_screen) i++ ;// i
points to the first info-box on the right side/*
どちらの側も(すなわち、左−右)余りに多くのinfo-b
oxを有さないことをチェックする。*/if (i > half_max
_num_info_boxes) {// too many boxeson the left sid
e.// sort them according to x-coordinates.// this
way wewill move points with the largest x-coordiat
es to the right side.for (j= 0 ; j < i ; j++) bend
_y_coordinates[j] = bend_points[j]->screen_x ;DBM_
QuickSort_double(bend_y_coordinates, (unsigned lon
g) i, (long *) bendlines) ;i = half_max_num_info_b
oxes ;}else if ((num_bends_to_be_drawn - i)> half_
max_num_info_boxes) {// too many boxes on the righ
t side.// sortthem according to x-coordinates.// t
his way we will move points with the smallest x-co
ordiates to the left side.for (j = i ; j < num_ben
ds_to_be_drawn ; j++) bend_y_coordinates[j] = bend
_points[j]->screen_x ;DBM_QuickSort_double(bend_y_
coordinates + i, (unsigned long) (num_bends_to_be_
drawn - i), (long *) (bendlines + i)) ;i = num_ben
ds_to_be_drawn - half_max_num_info_boxes ;}// it c
ould have been that when we chose a point fora ben
dline, it is not the best point.// (although this
point was used to place this point on the left-rig
ht side).// imagine a point on the left. it could
be that both endpoints are visible, but// out poin
t is not the best, because the other endpoint of t
he bendline is actually to the//left of our point.
for (j = 0 ; j < i ; j++) {// check if we have cho
iceif (! (bendlines[j]->bend_body1_point_left).vis
ible || ! (bendlines[j]->bend_body1_point_right).v
isible) continue ;if ((bendlines[j]->bend_body1_po
int_left).screen_x < (bendlines[j]->bend_body1_poi
nt_right).screen_x)bend_points[j] = &(bendlines[j]
->bend_body1_point_left) ;else bend_points[j] = &
(bendlines[j]->bend_body1_point_right) ;}for (j =
i ; j < num_bends_to_be_drawn ; j++) {// check if
we have choiceif (! (bendlines[j]->bend_body1_poin
t_left).visible || ! (bendlines[j]->bend_body1_poi
nt_right).visible) continue ;if ((bendlines[j]->be
nd_body1_point_left).screen_x> (bendlines[j]->bend
_body1_point_right).screen_x) bend_points[j] = &(b
endlines[j]->bend_body1_point_left) ;else bend_poi
nts[j] = &(bendlines[j]->bend_body1_point_right)
;}// store the y-coordinate for Quicksortfor(j =
0 ; j < num_bends_to_be_drawn ; j++) bend_y_coordi
nates[j] = bend_points[j]->screen_y ;// sort both
sides according to the screen y-coordinate// note
a glitch : while the bendlines[] array has been pe
rmuted, thebend_points[] array has not been.// in
the next paragraph we restore the point array. TOD
O : may-be there is a better solution.//we could r
esort the array, but then we need to get original
y-coordinates array.//we could just compute a sepa
rate permutation array, but then we need space for
it, and//the code to compute the permutation, whi
ch is non-tirivial.// anyway, for now we just do i
t the easy way.if (i > 0) DBM_QuickSort_double(ben
d_y_coordinates, (unsigned long) i, (long *) bendl
ines) ;if ((num_bends_to_be_drawn - i) > 0) DBM_Qu
ickSort_double(bend_y_coordinates +i, (unsigned lo
ng) (num_bends_to_be_drawn - i), (long *) (bendlin
es + i)) ;for (j = 0 ; j < i ; j++) {if ((bendline
s[j]->bend_body1_point_left).visible) {if (! (bend
lines[j]->bend_body1_point_right).visible) bend_po
ints[j] = &(bendlines[j]->bend_body1_point_left) ;
else {if ((bendlines[j]->bend_body1_point_left).sc
reen_x < (bendlines[j]->bend_body1_point_right).sc
reen_x) bend_points[j] = &(bendlines[j]->bend_body
1_point_left) ;else bend_points[j] = &(bendlines
[j]->bend_body1_point_right) ;}}else bend_points
[j] = &(bendlines[j]->bend_body1_point_right) ;}fo
r (j = i ; j <num_bends_to_be_drawn ; j++) {if ((b
endlines[j]->bend_body1_point_left).visible) {if
(! (bendlines[j]->bend_body1_point_right).visible)
bend_points[j] = &(bendlines[j]->bend_body1_point
_left) ;else {if ((bendlines[j]->bend_body1_point_
left).screen_x > (bendlines[j]->bend_body1_point_r
ight).screen_x) bend_points[j] = &(bendlines[j]->b
end_body1_point_left) ;else bend_points[j] = &(ben
dlines[j]->bend_body1_point_right) ;}}else bend_po
ints[j] = &(bendlines[j]->bend_body1_point_right)
;}/*ここで描画の準備が完了する。*/static char inf
o_box_text[256] ;static POINT box_corners[5] ;stat
ic POINT arrow[3] ;BM_BENDLINE *b ;BM_BEND_OP *bop
;BM_2D_BODY*b_body ;/*左側を描く。*/int left = 3
;int top ;if (0 == i) goto draw_right_side ;// co
mpute vertical space per info-boxvert_space_per_bo
x = view_size_y / i ;// compute vertical offset fo
r the top-left corner of theinfo-boxoffset = (vert
_space_per_box - box_height) >> 1 ;box_corners[0].
x = box_corners[3].x = box_corners[4].x = left ;bo
x_corners[1].x = box_corners[2].x = left + box_wid
th ;for (j = 0 ; j < i ; j++) {b = bendlines[j]->b
end ;bop = b->get_bend_op() ;if (NULL == bop) cont
inue ;// 043996KKif (view_type) b_body = b->get_cu
rrent_3D_version() ;else b_body = b->get_flat() ;t
op = j*vert_space_per_box + offset ;box_corners
[0].y = box_corners[1].y = box_corners[4].y = top
;box_corners[2].y = box_corners[3].y = top + box_
height ;sprintf(info_box_text,"A:%5.1f,L:%6.2f",(b
op->get_bend_angle2())*57.29578,(b_body->get_curre
nt_center_line()).get_len()) ;pdc->TextOut(5, top,
info_box_text, strlen(info_box_text)) ;switch (bo
p->get_type()) {case BM_TYPE_BEND_OP_REGULAR :spri
ntf(info_box_text,"R:%5.2f,D:%5.2f",((BM_BEND_OP_R
EGULAR *) bop)->get_bend_radius(),bop->get_bend_de
duction()) ;pdc->TextOut(5, top + font_height, inf
o_box_text, strlen(info_box_text)) ;break ;case BM
_TYPE_BEND_OP_CONIC :// TODO : implementconic bend
op.break ;}// draw boxpdc->Polyline(box_corners,
5) ;// drawarrowarrow[0].x = left + box_width ;arr
ow[0].y = top + half_box_height;// calculate arrow
tip at fixed percentage length in from end pointC
Point ptLeft(bendlines[j]->bend_body1_point_left.s
creen_x, bendlines[j]->bend_body1_point_left.scree
n_y);CPoint ptRight(bendlines[j]->bend_body1_point
_right.screen_x, bendlines[j]->bend_body1_point_ri
ght.screen_y);CSizesizeDiff = ptRight - ptLeft;CPo
int ptArrowTip;if ( bend_points[j] == &(bendlines
[j]->bend_body1_point_left) ){ptArrowTip.x = ptLef
t.x + sizeDiff.cx/8;ptArrowTip.y = ptLeft.y + size
Diff.cy/8;}else{ptArrowTip.x = ptRight.x - sizeDif
f.cx/8;ptArrowTip.y = ptRight.y - sizeDiff.cy/8;}a
rrow[1].x = ptArrowTip.x;arrow[1].y = ptArrowTip.
y;pdc->Polyline(arrow, 2) ;//change to solid pen f
or arrow headsCPen* pArrowPen = new CPen(PS_SOLID,
BCAD_context.m_nBendLineWeight, BCAD_context.m_crB
end);CPen* pOldPen = pdc->SelectObject(pArrowPen);
// compute arrow headCAutoDimArrow arrowBend(ptArr
owTip,CPoint(arrow[0].x,arrow[0].y),BCAD_context.m
_nArrowAngle,BCAD_context.m_nArrowLength);// draw
arrow headarrowBend.DrawHead(dc);pdc->SelectObject
(pOldPen);delete pArrowPen;}/*右側を描く。*/draw_r
ight_side:if (0 == num_bends_to_be_drawn - i) goto
done ;box_x = view_size_x - box_width - 3 ;left =
box_x ;// compute vertical space per info-boxvert
_space_per_box = view_size_y / (num_bends_to_be_dr
awn - i) ;// compute vertical offset for the top-l
eft corner of the info-boxoffset = (vert_space_per
_box - box_height) >> 1 ;box_corners[0].x = box_co
rners[3].x = box_corners[4].x = left ;box_corners
[1].x = box_corners[2].x = left + box_width ;box_x
+= 2 ;for (j = i ; j < num_bends_to_be_drawn ; j+
+) {b = bendlines[j]->bend ;bop = b->get_bend_op()
;if (NULL == bop) continue ;// 043996KKif (view_t
ype) b_body = b->get_current_3D_version() ;else b_
body = b->get_flat() ;top = (j - i)*vert_space_per
_box + offset ;box_corners[0].y = box_corners[1].y
= box_corners[4].y = top ;box_corners[2].y = box_
corners[3].y = top + box_height ;sprintf(info_box_
text,"A:%5.1f,L:%6.2f",(bop->get_bend_angle2())*5
7.29578,(b_body->get_current_center_line()).get_le
n()) ;pdc->TextOut(box_x, top, info_box_text, strl
en(info_box_text));switch (bop->get_type()) {case
BM_TYPE_BEND_OP_REGULAR :sprintf(info_box_text,"R:
%5.2f,D:%5.2f",((BM_BEND_OP_REGULAR *) bop)->get_b
end_radius(),bop->get_bend_deduction()) ;pdc->Text
Out(box_x, top + font_height, info_box_text, strle
n(info_box_text)) ;break ;case BM_TYPE_BEND_OP_CON
IC ://TODO : implement conic bend op.break ;}// dr
aw boxpdc->Polyline(box_corners, 5) ;// draw arrow
arrow[0].x = left ;arrow[0].y = top + half_box_hei
ght ;// calculate arrow tip at fixed percentage le
ngth in from end pointCPoint ptLeft(bendlines[j]->
bend_body1_point_left.screen_x, bendlines[j]->bend
_body1_point_left.screen_y);CPoint ptRight(bendlin
es[j]->bend_body1_point_right.screen_x, bendlines
[j]->bend_body1_point_right.screen_y);CSize sizeDi
ff = ptRight - ptLeft;CPoint ptArrowTip;if ( bend_
points[j]== &(bendlines[j]->bend_body1_point_left)
){ptArrowTip.x = ptLeft.x + sizeDiff.cx/8;ptArrow
Tip.y = ptLeft.y + sizeDiff.cy/8;}else{ptArrowTip.
x =ptRight.x - sizeDiff.cx/8;ptArrowTip.y = ptRigh
t.y - sizeDiff.cy/8;}arrow[1].x = ptArrowTip.x;arr
ow[1].y = ptArrowTip.y;pdc->Polyline(arrow, 2);//
change to solid pen for arrow headsCPen* pArrowPen
= new CPen(PS_SOLID, BCAD_context.m_nBendLineWeig
ht, BCAD_context.m_crBend);CPen* pOldPen = pdc->Se
lectObject(pArrowPen);// compute arrow headCAutoDi
mArrow arrowBend(ptArrowTip,CPoint(arrow[0].x,arro
w[0].y),BCAD_context.m_nArrowAngle,BCAD_context.m_
nArrowLength);// draw arrow headarrowBend.DrawHead
(dc);pdc->SelectObject(pOldPen);delete pArrowPen;}
/*割り当てたメモリを開放する。*/done :delete [] be
nd_points ;delete [] bend_y_coordinates ;delete[]
bendlines ;}/*デバイスコンテクストに部分デイメンシ
ヨンを描く。*/int BM_AUTO_DIMENSION::draw_auto_dim
ensions(CDC *target_dc){BM_AD_dim_corner*temp_poin
t ;int i ;// check that we have a valid dcif (NULL
== target_dc) return 0 ;// check if we need to re
compute the data structuresif (dirty) {if (! compu
te_auto_dimension_data()) return 0 ;if (dirty) ret
urn 0;}if (NULL == part) return 1 ;dc = target_dc
;// get view sizeview_size_x = view->get_viewport
_width() ;view_size_y = view->get_viewport_heigh
t() ;// create a mesh to determine clear spaces to
draw dimensions & datapMesh = new CAutoDimRgnMesh
(view_size_x, view_size_y);// check if we needto c
ompute points to ignore in solidif (view->get_draw
ing_mode() && ! points_to_ignore_in_solid_compute
d) {compute_points_to_ignore_in_solid();}object_sp
ace_per_pixel = view->get_object_to_device_ratio()
;// initially set all "ignore" flags to FALSE. we
should not ignore anything.// also, nothing is dr
awn yet.for (i = 0 ; i < num_of_bendlines ; i++)
{bends[i]->ignore = 0 ;bends[i]->body1_drawn = ben
ds[i]->body2_drawn = 0 ;}/*全てのベンドラインの全
てのベンドラインデイメンシヨンポイントのビジビリテ
イを計算する。*/for (i = 0 ; i < num_of_bendlines
; i++) {if (! bends[i]->data_valid) continue ;ben
ds[i]->compute_bendline_dim_points_visibility() ;i
f (bends[i]->adj_body1) {for (temp_point = bends
[i]->body1_points ;temp_point ; temp_point = temp_
point->next) temp_point->visible = -1 ;}if (bends
[i]->adj_body2) {for (temp_point = bends[i]->body1
_points ; temp_point ; temp_point = temp_point->ne
xt) temp_point->visible = -1 ;}}/*全てのベンドライ
ンに対して、描くべきデイメンシヨンポイントを計算す
る。*/for (i = 0 ; i < num_of_bendlines ; i++) {if
(! bends[i]->data_valid ||bends[i]->ignore) conti
nue ;bends[i]->compute_dim_points_to_display() ;}/
*パートを描くペンを生成する。フランジデイメンシヨ
ンを描くペンを生成する。*/// create the pen : typ
e, (line)width, color.CPen penFlange;CPen* pFlange
Pen = create_auto_dim_pen(&penFlange, BCAD_contex
t.m_nFlangeLineStyle, BCAD_context.m_nFlangeLineWe
ight, BCAD_context.m_crFlange);// selectnew pen, s
ave old penCPen* pOldPen = dc->SelectObject(pFlang
ePen);COLORREF oldtextcolor = dc->SetTextColor(BCA
D_context.m_crFlange) ;int old_bk_mode = dc->SetBk
Mode(TRANSPARENT) ;/*フランジ長さディメンシヨンを
表示する。*/if (BCAD_context.m_bShowFlangeDim){for
(i = 0 ; i < num_of_bendlines ; i++) {if (! bends
[i]->data_valid || bends[i]->ignore) continue ;ben
ds[i]->draw_dimension_points();}}/*// ダーテイ領域
の表示をテストする。CBrush brRed(RGB(255,0,0));CBr
ush* pOldBrush = dc->SelectObject(&brRed);dc->Pain
tRgn(pDirtyRegion);dc->SelectObject(pOldBrush);*/d
elete pDirtyRegion;pDirtyRegion = NULL;/*ベンドラ
インinfoを描くペンを生成する。*/// create the pen
: type, (line)width, color.CPen penBend;CPen* pBe
ndPen = create_auto_dim_pen(&penBend, BCAD_contex
t.m_nBendLineStyle, BCAD_context.m_nBendLineWeigh
t, BCAD_context.m_crBend);// select the new pendc-
>SelectObject(pBendPen);dc->SetTextColor(BCAD_cont
ext.m_crBend);/*ベンドラインinfoを描く。*/if (BCAD
_context.m_bShowBendDim)draw_bendline_data(dc) ;//
Delete the mesh now that we are finished with it.
//delete pMesh;/*古いペンを復帰させる。*/dc->Selec
tObject(pOldPen) ;dc->SetTextColor(oldtextcolor) ;
dc->SetBkMode(old_bk_mode) ;// see if we have to d
isable auto-dimensioning in the view classif (rese
t_view_to_false_once_drawn) {reset_view_to_false_o
nce_drawn = 0 ;view->set_auto_dimensions(0) ;}retu
rn 1 ;}CPen* BM_AUTO_DIMENSION::create_auto_dim_pe
n(CPen* pPen, int nLineStyle, intnLineWeight, COLO
RREF cr){if (nLineWeight == 1 || nLineStyle == PS_
SOLID)pPen->CreatePen(nLineStyle, nLineWeight, c
r);// for speedelse{CBrush brushNew(cr);LOGBRUSH l
b;brushNew.GetLogBrush(&lb);DWORD dwStyleArray[6];
int nStyleCount = 2;DWORD dwDashLength = 2 + (nLin
eWeight * 4);DWORD dwDotLength = dwDashLength / 4;
DWORD dwGapLength = dwDashLength / 2;switch(nLineS
tyle){case PS_DASH:dwStyleArray[0] = dwDashLength;
// pixels ondwStyleArray[1] = dwGapLength;// pixel
s offnStyleCount = 2;break;case PS_DOT:dwStyleArra
y[0] = dwDotLength;// ondwStyleArray[1] = dwGapLen
gth;// offnStyleCount = 2;break;case PS_DASHDOT:dw
StyleArray[0] = dwDashLength;//ondwStyleArray[1] =
dwGapLength;// offdwStyleArray[2] = dwDotLength;/
/ondwStyleArray[3] = dwGapLength;// offnStyleCount
= 4;break;case PS_DASHDOTDOT:dwStyleArray[0] = dw
DashLength;// ondwStyleArray[1] = dwGapLength;// o
ffdwStyleArray[2] = dwDotLength;// ondwStyleArray
[3] = dwGapLength;// offdwStyleArray[4] = dwDotLen
gth;// ondwStyleArray[5] = dwGapLength;// offnStyl
eCount = 6;break;}pPen->CreatePen(PS_GEOMETRIC | P
S_USERSTYLE,nLineWeight, &lb, nStyleCount, dwStyle
Array);}return pPen;}void CBendCADDoc::OnDrawAutoD
im() {// if we have no dimension object, do nothin
g.if(NULL == auto_dim) {auto_dim = new BM_AUTO_DIM
ENSION(this) ;}if (NULL ==auto_dim) return ;CBendC
ADViewPart *pActiveView = (CBendCADViewPart *)get_
view(BENDCAD_VIEW_TYPE_PART) ;if (NULL == pActiveV
iew) return ;if (!pActiveView->get_auto_dimensions
()) auto_dim->disable_view_dimensions_flag_next_ti
me() ;pActiveView->set_auto_dimensions(1) ;// alwa
ys recompute dimension pointsauto_dim->invalidat
e() ;pActiveView->Invalidate(0) ;} 付録H ディメンションポイントを計算する自動寸法化関数の
例。ディメンションポイントは、フランジ長ディメンシ
ョンが描かれる前に計算される。
【0297】//#include "stdafx.h"#include "BendCA
D.h"#include "BendCADDoc.h"#include"BendCADViewPar
t.h"#include "AUTODIM.HXX"/*********** **********
********** ********** ********** ********** ******
**** ********** **********BM_AD_bendline class stu
ff.********** ********** ********** ********** ***
******* ********** ********** ********** *********
**//*これは、所与の基準点とエッジポイントの間の距
離を計算するBM_AD_bendline::compute_BM_AD_flange_p
oints(..)に用いられるローカルな関数である。この関
数はポイントが基準ラインの1つの間違った側である場
合にFALSEを戻す。 ベクトルdirはユニットベクトルで
あるべきである。*/static int compute_distance_from
_ref_point(BM_POINT const& pt /* given reference p
oint */,BM_VECTOR const& dir /*direction vector *
/, BM_POINT *p /* point whose distance we want to
compute */, double &distance){BM_VECTOR v(*p - pt)
;double x = v % dir ;if (x < -AUTODIM_DISTANCE_TO
LERANCE) return 0 ;distance = x ;return 1 ;}/*BM_A
D_bendline::compute_BM_AD_flange_points(...)により
用いられるローカル関数。注意:参照するディメンショ
ンリストはフランジディメンションポイントのリストで
ある。”左”に開放したリスト中のディメンションポイ
ントの個数が”右”に開放したリスト中のディメンショ
ンポイントの個数に等しくないとき、ディメンションリ
ストは開放である。これは通常リストに付加した最後の
フランジディメンションポイントが”閉じる”に一致す
るフランジディメンションポイントを持たないことを意
味する。これらはすべて、実際には小片に分解されたラ
イン(1つのラインのように見える)を我々が持つこと
が出来る可能性によりもたらされる。その場合、ユーザ
はそれらの小片を見ず(1つのラインのように見え
る)、また我々はポイントを途中で正当なフランジディ
メンションポイントと考えることを望まない。この関数
は、我々が所与のエッジをスキップし、ディメンション
ポイントを開放のままにすることが出来るときはTRUEを
戻し、また、我々が、現在のエッジのエンドポイントの
1つから左側ディメンションポイントを生成することに
より開放ディメンションを閉じる必要があるときはFALS
Eを戻す。基本的には、この関数は、ループ中の次のエ
ッジが無視されないラインであるときはTRUEを戻す。実
際には、更に幾つかの条件を付加する。注意:この関数
は、エッジのエンドポイントがフランジ長距離にあり、
また我々が、このエンドポイントに対する(フランジ)
ディメンションポイントを描くべきかを考えているとき
に求められる。*/static int leave_dimension_open(BM
_EDGE *edge /* current edge */,BM_LOOP *bloop /* l
oop where the current edge belongs to */,BM_VECTOR
const& side_vector /* side vector for the current
bendline-ajd_flange pair */, BM_VECTOR const& nor
mal /* normal of the plane underlying the adjacent
flange */){BM_EDGE *next_edge = (BM_EDGE *) edge-
>next();if (NULL == next_edge) next_edge = bloop->
get_first_edge() ;if (next_edge->is(BM_ENTITY_TYPE
_LINE)) {// problem. if the next edge (which is al
ine) will be ignored, we need to// close the dimen
sion here.BM_VECTOR temp_v((((BM_LINE *) next_edg
e)->get_v()) * side_vector) ;// if the nextline wi
ll not be ignored we can skip the current edge.if
(temp_v.Len() >AUTODIM_DISTANCE_TOLERANCE && (temp
_v % normal) < 0.0) {// next edge isa line that wi
ll not be ignored.// note that there is a problem.
if this edge is a line, and one of the two lines
// (rememeber, next edge is aline) is adjacent to
a bendline that // the other is not adjacent to, w
e should close the dimension.if (! edge->is(BM_ENT
ITY_TYPE_LINE)) return1 ;BM_3D_BODY *ab = edge->ge
t_adj_body() ;BM_3D_BODY *ab_next = next_edge->get
_adj_body() ;if (! ab) {if (! ab_next) return 1 ;i
f (! ab_next->is(BM_ENTITY_TYPE_BENDLINE)) return
1 ;return 0 ;}if (! ab_next) {if (! ab->is(BM_ENTI
TY_TYPE_BENDLINE)) return 1 ;return 0 ;}if ((! ab-
>is(BM_ENTITY_TYPE_BENDLINE) && ! ab_next->is(BM_E
NTITY_TYPE_BENDLINE)) ||ab == ab_next) return 1
;}}// if next edge is not a line, we have to clos
e theopen dimensionreturn 0 ;}/*BM_AD_bendline::co
mpute_BM_AD_flange_points(...)により用いられるロー
カルな関数この関数は最も一般的な形態でディメンショ
ンポイントを生成する。我々は、我々がラインに対する
ディメンションポイントを生成していると仮定する。こ
のラインはベンドラインに隣接することが出来る。*/st
atic BM_AD_dim_corner *create_dim_point(double d /
* bendline arcoutside length projected onto our pl
ane */, // these are basic parameters needed to dr
aw any dimension pointBM_POINT const& p /* point p
in theflange dimension point */,BM_VECTOR const&
rv /* reference vector to make sure point p in the
flange dimension point is on the same plane as de
fined by the bendline dimension point */,BM_VECTOR
const& opening_direction_vector /* for flange dim
ension point */, int opening_vector_reverse_bit,BM
_AD_bendline *owner,BM_3D_BODY *Body_required_visi
ble,BM_AD_dim_corner **prev /* previous flange dim
ension point in the list of flange dimpoints */,BM
_VECTOR const& side_vector, // these parameters ar
e used when the line for which we are computing th
e dimension point is adjacent//to another bendlin
e.double d_proj_side_vector /* d projected onto th
e side-vector : angle_factor*d in compute_BM_AD_fl
ange_points(...) */,BM_VECTOR & bend_arc_direction
/* direction of the bend arc projected onto our p
lane *//* should be line->v * plane_normal */,BM_V
ECTOR & bend_direction /* points to the direction
in which the bendline "turns" *//* depends on whet
her the bend angle is acute or not. *//* if acute
then tangentto the other end of bend arc *//* if n
ot acute, then an endpoint of thetangent approxima
tion *//* basically this is the (p->p2) vector for
theother bendline with respect to this flange */,
BM_BENDLINE *adj_bendline/* if the line is adjacen
t to a bendline this is a pointer to it *//* this
parameter is stored to avoid drawing some dimenion
s twice */,BM_LINEconst& adj_bend_p2_line /* this
is the line between p2 points of the bend-dimensio
n *//* points of the adjacent bendline with respec
t to this flange *//* note that our p2 point has t
o be on that line. *//* usually our p->p2 vector i
s perpendicular to this line, although not always
*/){//this our local copy of the adj-bendline-poin
terBM_3D_BODY *adj_bend = adj_bendline ;BM_POINT p
_local(p + rv) ;// note : even if this line is adj
acent to another bendline, // but if the line we a
re creating the flange dimension point for is not
perpendicular to// the side-vector, we should not
memorize that this flange dimension point is adjac
ent to // a bendline, because the flange length di
mension drawn at this flange dimension point // is
not parallel to the side-vector of the adjacent b
endline with respect to this flange.if (adj_bendli
ne && fabs(bend_arc_direction %side_vector) < (ben
d_arc_direction.Len() - AUTODIM_DISTANCE_TOLERANC
E)){// not perpendicularadj_bendline = NULL ;}// c
heck if the line is attached to a bendlineif (d <=
AUTODIM_DISTANCE_TOLERANCE) {// not attachedto a
bendline, or both thickness and bendline radius ar
e 0.// create a 1-point flange-dimension point.//
note that body_required_visible pointsto the flang
e with respect to which // the dimension point is
computed.return new BM_AD_dim_corner(p_local, owne
r, Body_required_visible, opening_direction_vecto
r, opening_vector_reverse_bit, prev, adj_bendline)
;}//note that since we have 3 points now, this li
ne is adjacent to anotherbendline.// compute p1. p
_local is p1.// compute pBM_POINT dim_p(p_local+ d
_proj_side_vector*side_vector) ;// compute p2bend_
arc_direction.set_length(d) ;BM_POINT dim_p2(p_loc
al + bend_arc_direction) ;// now the problem is th
at with respect to the adjacent bendline, our flan
ge dimensionpoints// p and p1 might not be on the
outside - they could be on the inside.// the dista
nce from p to p2 depends on that.// however, we kn
ow the p2-line of the adjacent bendline (with resp
ect to our flange),// so wewill compute the distan
ce between that p2-line and dim_p2. // we will use
that to compute the correct p2 point for our flan
ge dimension (note that// our p2 point has to be o
n the p2-line of the adjacent bendline).double dis
tance ;BM_distance_between_point_and_line(dim_p2,
adj_bend_p2_line, &distance, (BM_POINT *) NULL) ;b
end_direction.set_length(distance) ;dim_p2 = dim_p
2 + bend_direction ;// note that the body_required
_visiblepointer points not to this flange, but to
the // adjacent-bendline instead, ALWAYS, even if
this flange dim point will not be marked as// adja
cent to another bendline.return new BM_AD_dim_corn
er(dim_p, p_local, dim_p2, owner, adj_bend ? adj_b
end : Body_required_visible, opening_direction_vec
tor, opening_vector_reverse_bit, prev, adj_bendlin
e) ;}/*この関数は隣接フランジに対するフランジディ
メンションポイントを計算する。注意:この関数の直前
に計算した基準ポイントは、我々が任意の種類のadj-bo
dy面を操作出来るを確実にするために与えられる。第一
の問題は、我々が、adj-bodyの3次元- バージヨンの2
次元- bodyがOUTSIDEまたはINSIDEを表すかどうか解ら
ないということである。我々は、ベンドラインに対する
ベンドラインディメンションポイントがOUTSIDEポイン
トであることを知っている。ただし、 adj-bodyが明瞭
にINSIDEを表すということがあり得る。その場合、ここ
で計算しようとしている全てのポイントをシフトさせる
並進ベクトルを計算する基準ポイント(これはadj-body
の外側面上にある)に対して用いられる。更に、この並
進ベクトルを用いて、フランジディメンションポイント
のポイントp1およびp2が正しいということを確認するた
めに用いる。(もし、adj-bodyがinsideを表すときは、
我々はoutsideに対して実際にディメンションポイント
を計算し、ライン(p->p2)は注意して構成されなければ
ならず、それはライン(p->p1)より短い。)注意:この
関数は、我々がここでより多くの仮定を行うがBMAPI’s
BM_2D_BODY::compute_outside_width(...)関数に非常
によく相似している。*/int BM_AD_bendline::compute_
BM_AD_flange_points(BM_3D_BODY *adj_body){// flang
e dimension points we aregoing to compute will be
stored hereBM_AD_dim_corner **list_of_points ;// l
ist_of_points is where we write the pointer to the
// next flange dimension pointBM_AD_dim_corner *t
emp_dp ;// these parameters are used asinput to th
is function.double flange_length ; /* it is import
ant that the flange length be the correct flange l
ength */BM_POINT ref_point ; /*reference point, de
fines the right plane for flange dimension points
*/BM_VECTOR side_vector ; /* should be normalized
*/// check which adjacentbody we computeif (adj_bo
dy == adj_body1) {flange_length = fl1 ;list_of_poi
nts = &body1_points ;ref_point = bend_body1_point_
left.p ;side_vector = side_vector1 ;}else if (adj_
body == adj_body2) {flange_length = fl2;list_of_po
ints = &body2_points ;ref_point = bend_body2_point
_left.p ;side_vector = side_vector2 ;}else return
0 ; // not an adjcent body// variables to store te
mporary valuesBM_VECTOR temp_v ;double temp_x ;//
parameters for fixing the reference pointBM_POINT
rp(ref_point) ; // this a local copy of the refere
nce point. we will modify it.BM_VECTOR rv ; // ave
ctor for translating flange dimension points.int r
ef_vector_valid = 0; // if this is TRUE, we need t
o translate all flange dimension points.// if TRU
E, the only really tricky part is to construct the
p2 point in the flange dimension point.// qualifi
cation checkBM_2D_BODY *adj_displayed_version ;if
(parent->get_view_type()) adj_displayed_version =
adj_body->get_current_3D_version() ;else adj_displ
ayed_version = adj_body->get_flat() ;if (NULL == a
dj_displayed_version) return 0 ;BM_SURFACE *surfac
e= adj_displayed_version->get_surface() ;if (NULL
== surface) return 0 ;BM_LOOP *bloop = adj_display
ed_version->get_bloop() ;if (NULL == bloop) return
0 ;BM_EDGE *edge ; // here we will store edges as
we scan the loop.double distance1, distance2 ; //
here we will store the distance of points we seed
ouble d1, d2 ; // here we store distance that has
to be addedbecause of a bend arc. for lines adjace
nt to a bendline.double td1, td2; // here we store
the total distance which is the sum of distanceX
+ dX.BM_3D_BODY *ab ; // here we store a pointer t
o a body that is adjacentto the current edge.BM_BE
ND_OP *bop ; // here we store a pointer to thebend
op associated with the bendline that is// adjacen
t to the edge wescan (valid only iff the body adja
cent to the edge is a bendline).BM_VECTOR right_op
ening_direction ; // this is the right-side openin
g direction vector. BM_VECTOR left_opening_directi
on ; // this is the left-side opening direction ve
ctor. int fl_dim_open = 0 ; // if this is TRUE, we
have created a right-side flange dimension point,
but// no corresponding left-side dimension point.
That is, the dimension is "open".BM_VECTOR bend_a
rc_direction ; // direction of the bend arc projec
ted onto our plane//should be line->v * plane_norm
al. Used when a line is adjacent to a bendline.BM_
VECTOR bend_direction ; // points in the direction
in which thebendline "turns"// depends on whether
the bend angle is acute or not. // if acute then
tangent to the other end of bend arc.// if not acu
te, then an endpoint of the tangent approximation.
// basically this is the (p->p2) vector for the ot
her bendline with respect to this flange.// this i
s used when a line is adjacent to a bendline, to c
ompute the p2 point for // the flange dimension po
int.BM_LINE adj_bend_p2_line ; // this is the left
-right-p2 line, of the adjacent bendline,// with r
espect to this flange.// this is used when a line
is adjacent to a bendline, to computethe p2 point
for // the flange dimension point.double bend_arc_
outside_length_proj ; // bendline arc outside leng
th projected onto our plane/*表面のタイプを操作す
る。*/if (surface->is(BM_TYPE_PLANE)) goto handle_
planes ;/*********** ********** ********** *******
*** ********** ******************** ********** ***
******* 一時的拘束:我々は単に平面である表面を操作
する。TODO:他の表面タイプを操作する。********** *
********* ********** ********** ********** *******
*** ********** ********** ***********///unknown su
rfacereturn 0 ;/*ここで、平面を操作する。*/handle_
planes : BM_PLANE *plane = (BM_PLANE *) surface ;/
/ we assume that the reference point correctly def
ines the plane (which is parallel to our plane)//
thatis the OUTSIDE plane.// check if reference poi
nt is on our plane. If not(in that case our plane
represents the INSIDE// plane) compute a translati
on vector for moving from our plane to reference p
lane,// and move the reference point to our plane.
rv = plane->get_normal() ;rv.normalise();temp_v =
rp - (plane->get_pt()) ;temp_x = temp_v % rv ;if
(fabs(temp_x)> AUTODIM_DISTANCE_TOLERANCE) {// ok,
need to translate all dimension points. reference
point not on the plane.ref_vector_valid = 1 ;rv.s
et_length(temp_x) ;rp = rp + (-rv) ;}else rv = BM_
null_vector ;// compute right- and left-side openi
ng vectors.right_opening_direction = side_vector *
(plane->get_normal()) ;right_opening_direction.nor
malise() ;left_opening_direction = -(right_opening
_direction) ;/*********** ********** ********** **
******** ********** ********** ********** ********
** **********この関数の主要部分。adj_bodyの束縛ル
ープを掃引し、ディメンションポイントを構成する。所
与のラインから最も遠く離れたエッジはbloop内になけ
ればならないので我々は単にbloopを掃引する必要があ
る点に注意されたい。******************** *********
* ********** ********** ********** ********** ****
****** ********** 注意:ディメンションリストが開放
のとき、生成される最後の右-側ディメンションポイン
トは、ループの始めにおいて現在のエッジの開始-点か
ら異なっていなければならない。********** *********
* ********** ********** ********** ********** ****
****** ********** ********** */// scan alledges in
the bloop// first, we have a problem where to sta
rt scanning.// if we start from the first edge, we
basically start from an arbitraryedge.// this mig
ht not be good since we might create dimension poi
nts wedon’t really want.// therefore we will find
an edge that is adjacent to our bendline and star
t from that and// finish when we get back to it.BM
_EDGE *start_edge, *stop_edge, *next_edge ;for (st
art_edge = bloop->get_first_edge() ; start_edge ;
start_edge = (BM_EDGE *) start_edge->next()) {if
(start_edge->get_adj_body() == bend) break ; // ed
ge adjacent to this bendline is a good start-edgee
lse if (! start_edge->is(BM_ENTITY_TYPE_LINE)) bre
ak ; // any non-line is a good start-edgeelse { //
any linethat will be ignored is also a good place
to starttemp_v = (((BM_LINE *)start_edge)->get_
v()) * side_vector ;// in these two cases this lin
e will be ignoredif (temp_v.Len() <= AUTODIM_DISTA
NCE_TOLERANCE) break ; //line parallel to the side
-vectorif ((temp_v % plane->get_normal()) > 0.0) b
reak ; // material "above" the line}}if (NULL == s
tart_edge) {*list_of_points = NULL ;return 1 ;}//
this is the main loop.// initially we setstop_edge
to NULL. we would like to set it to start-edge, b
ut we cannot,// because in that case we would neve
r enter the loop. therefore we setit to NULL and r
ight // after we enter the loop, we set it to star
t_edge.// (this is important in the case when the
loop consists of only one circle).stop_edge = NULL
;for (edge = start_edge ; edge != stop_edge ; edg
e = next_edge) {stop_edge = start_edge ;// compute
the next edge we will scannext_edge = (BM_EDGE *)
edge->next() ;if (NULL == next_edge) next_edge =
bloop->get_first_edge() ;switch (edge->get_type())
{case BM_ENTITY_TYPE_LINE : { // compute distance
for start- and end-points// first, we want to ign
ore lines that are parallel to the side-vector.//
we also want to ignore lines that have material "a
bove" them when looking in the// side-vector direc
tion (because they cannot have to largest width, s
ince material is// "above" them, there must be som
e other edge bounding thebody from above).temp_v =
(((BM_LINE *) edge)->get_v()) * side_vector ;if
(temp_v.Len() <= AUTODIM_DISTANCE_TOLERANCE) conti
nue ; // line parallel to the side-vectorif ((temp
_v % plane->get_normal()) > 0.0) continue; // mate
rial "above" the line// note that this leaves only
lines whosedirection-vector goes to the "left"//
of the side-vector.// we need tocheck if this line
is adjacent to a bendlineab = edge->get_adj_bod
y() ;// check if this line is adjacent to a valid
bendline (ie. one that is not the // bendline asso
ciated with this BM_AD_bendline object).d1 = d2 =b
end_arc_outside_length_proj = 0.0 ;if (ab && ab !=
bend && ab->is(BM_ENTITY_TYPE_BENDLINE)) {// chec
k if the bendline is being bentbop = ((BM_BENDLINE
*) ab)->get_bend_op() ;if ((parent->get_view_type
()) /* have tohave a 3D view */ && ((BM_BENDLINE
*) ab)->get_bending_status() && bop){// a problem
: it could be that the bendline is not perpendicu
lar to the side-vector.// in that case we need to
project the bend-arc-approximation-value onto the
side-vector.// for example, if the bendline is par
allel to the side-vector, we should not add// the
approximation value at all, since it plays no role
in the width computation.temp_x = side_vector^
(((BM_LINE *) edge)->get_v()) ; // temp_x is "angl
e_factor"if (temp_x> PI_over_2) temp_x = PI - temp
_x ;temp_x = sin(temp_x) ;switch (bop->get_type())
{case BM_TYPE_BEND_OP_REGULAR :bend_arc_outside_l
ength_proj =((BM_BEND_OP_REGULAR *) bop)->compute_
3D_outside_approx_per_side() ;d1 =temp_x*bend_arc_
outside_length_proj ;d2 = d1 ; // d2 is the same a
s d1!break ;// TODO : implement more bend operatio
ns here.default : ; // unknown bend op}// compute
some needed parameters// compute : direction ofthe
bend arc projected onto our planebend_arc_directi
on = (((BM_LINE *)edge)->get_v()) * plane->get_nor
mal() ;bend_direction = parent->compute_bend_direc
tion_vector((BM_BENDLINE *) ab, adj_body, &adj_ben
d_p2_line) ;}}else ab = NULL ; // make sure ab doe
s not point to anything we don’twant to.// handle
two cases separately - depending on whether the d
imension list is open or not.if (fl_dim_open) {//
if the dimension is open, we don’t need to check
the start-point of the line,// since it is at thef
lange length distance anyway.// // first we will c
heck if the line isperpendicular to the side-vecto
rif (fabs(side_vector % ((BM_LINE *) edge)->get_
v()) > AUTODIM_DISTANCE_TOLERANCE) {// not perpend
icular.// thisline has to be "coming down" (becaus
e it is not perpendicular to the// side-vector and
the dimension is open, ie. it cannot be "going u
p").// now we have to close the dimension by creat
ing a left-hand-side dimensionpoint// from the sta
rt-point of the line.if (temp_dp = create_dim_poin
t(bend_arc_outside_length_proj, ((BM_LINE *) edge)
->get_startpt(), rv, left_opening_direction, 0, th
is, adj_body, list_of_points, side_vector, d1,bend
_arc_direction, bend_direction, (BM_BENDLINE *) a
b, adj_bend_p2_line)) {list_of_points = &(temp_dp-
>next) ;}fl_dim_open = 0 ;}else {// is perpendicul
ar.// here we need to check the type of the next e
dge.// if itis not line, we need to close the dime
nsion here by creating // a left-hand-side dimensi
on point from the end-point of the line.// if the
nextedge is a line, we can just continue.if (leave
_dimension_open(edge,bloop,side_vector,plane->get_
normal())) break ;if (temp_dp = create_dim_point(b
end_arc_outside_length_proj, ((BM_LINE *) edge)->g
et_endpt(), rv, left_opening_direction, 0, this, a
dj_body, list_of_points, side_vector, d1,bend_arc_
direction, bend_direction, (BM_BENDLINE *) ab, adj
_bend_p2_line)) {list_of_points = &(temp_dp->next)
;}// ok, close the dimension.fl_dim_open = 0 ;//
this is a small trick that will save us some time.
// if the next edge is a line that will be ignore
d, we can skip is right now here.if (next_edge->is
(BM_ENTITY_TYPE_LINE) && next_edge != stop_edge)
{next_edge = (BM_EDGE *) edge->next() ;if (NULL ==
next_edge) next_edge = bloop->get_first_edge()
;}}break ;}if (! compute_distance_from_ref_point
(rp, side_vector, edge->get_edge_startpoint(), dis
tance1)) continue ;if (! compute_distance_from_ref
_point(rp, side_vector, edge->get_edge_endpoint(),
distance2)) continue ;td1 = distance1 + d1 ;td2 =
distance2 + d2 ;// check if the start-point is a
flange dimension pointif (fabs(td1 - flange_lengt
h) <= AUTODIM_DISTANCE_TOLERANCE) {// check if the
second point is a flange dimension pointif (fabs
(td2 - flange_length) > AUTODIM_DISTANCE_TOLERANC
E) {// only start-point is a flange dimension poin
t.// create a left-right (ie. in both directions)
flange dim point and continue.if (temp_dp = create
_dim_point(bend_arc_outside_length_proj, ((BM_LINE
*) edge)->get_startpt(), rv, right_opening_direct
ion, 1, this, adj_body,list_of_points, side_vecto
r, d1, bend_arc_direction, bend_direction, (BM_BEN
DLINE *) ab, adj_bend_p2_line)) {list_of_points =
&(temp_dp->next) ;}break ;}// else open the dimens
ion list// create right flange dimensionpoint from
start-pointif (temp_dp = create_dim_point(bend_ar
c_outside_length_proj, ((BM_LINE *) edge)->get_sta
rtpt(), rv, right_opening_direction, 0, this, adj_
body, list_of_points, side_vector, d1, bend_arc_di
rection, bend_direction, (BM_BENDLINE *) ab, adj_b
end_p2_line)) {list_of_points = &(temp_dp->next)
;}// check if we can leave the dimension list ope
nand continueif (leave_dimension_open(edge,bloop,s
ide_vector,plane->get_normal())) {fl_dim_open = 1
;break ;}// create left flange dim point from end
-point.if (temp_dp = create_dim_point(bend_arc_out
side_length_proj,((BM_LINE *) edge)->get_endpt(),
rv, left_opening_direction, 0, this, adj_body, lis
t_of_points, side_vector, d1, bend_arc_direction,
bend_direction, (BM_BENDLINE *) ab, adj_bend_p2_li
ne)) {list_of_points = &(temp_dp->next) ;}// ok, c
lose the dimension list.fl_dim_open = 0 ;// this i
s asmall trick that will save us some time.// if t
he next edge is a line that will be ignored, we ca
n skip is right now here.if (next_edge->is(BM_ENTI
TY_TYPE_LINE) && next_edge != stop_edge) {next_edg
e = (BM_EDGE *) edge->next() ;if (NULL == next_edg
e) next_edge = bloop->get_first_edge() ;}break ;}e
lse if (fabs(td2 - flange_length) > AUTODIM_DISTAN
CE_TOLERANCE){// the start-point is not a flange d
imension point// if the end-pointis also not a fla
nge dimension point, we can continue.continue ;}//
ok,only the end−point is a
flange dimension point./
/ two possibilities. ifwe
can leave the dimension
list open (right now dime
nsion is // closed!)we do
n’t even have to open it, we can just continue.i
f (leave_dimension_open(edge,bloop,side_vector,pla
ne->get_normal())) break ;// second possibility. n
ow we have to create a left-right flange dimension
point.// dimension list stays closed.if (temp_dp
= create_dim_point(bend_arc_outside_length_proj,
((BM_LINE *) edge)->get_endpt(), rv, right_opening
_direction, 1, this, adj_body, list_of_points, sid
e_vector, d1, bend_arc_direction, bend_direction,
(BM_BENDLINE *) ab, adj_bend_p2_line)) {list_of_po
ints = &(temp_dp->next) ;}// this is a small trick
that will save us some time.// if the next edge i
s a line that will be ignored, we can skip is righ
t now here.if (next_edge->is(BM_ENTITY_TYPE_LINE)
&& next_edge !=stop_edge) {next_edge = (BM_EDGE *)
edge->next() ;if (NULL == next_edge)next_edge = b
loop->get_first_edge() ;}}break ;case BM_ENTITY_TY
PE_ARC :{// note : we can always ignore the start-
point of the arc !// becauseof the way we keep tra
ck of the open dimension list.// make sure the dim
ension list will be closed.fl_dim_open = 0 ;// fir
st, compute start- andend-angles of the arc with r
espect to the side vector.// ie. convert start- an
d end-angles so as if the side-vector was the 0-an
gle vector.double startang = ((BM_ARC *) edge)->ge
t_startang() ;double endang = ((BM_ARC *) edge)->g
et_endang() ;temp_v = side_vector*(((BM_ARC *) edg
e)->get_vx()) ;double delta_angle = (temp_v.Len())
/(((BM_ARC *) edge)->get_rad());if (delta_angle <
-1.0) delta_angle = -1.0 ;else if (delta_angle >
1.0) delta_angle = 1.0 ;delta_angle = asin(delta_a
ngle) ;if (fabs((((BM_ARC*) edge)->get_normal())%t
emp_v) > 0.0) {startang += delta_angle ;endang+= d
elta_angle ;if (startang > PI_times_2) startang -=
PI_times_2 ;if (endang > PI_times_2) endang -= PI
_times_2 ;}else {startang -= delta_angle ;endang -
= delta_angle ;if (startang < 0.0) startang += PI_
times_2 ;if(endang < 0.0) endang += PI_times_2 ;}/
/ compute the extreme pointBM_POINT arc_extreme_po
int ;// 0-angle point is the extreme pointif (enda
ng <startang) arc_extreme_point = ((BM_ARC *) edg
e)->get_center() + (((BM_ARC *) edge)->get_rad())*
side_vector ;else arc_extreme_point = *(((BM_ARC*)
edge)->get_edge_endpoint()) ;// check the distanc
e of the extreme pointif (! compute_distance_from_
ref_point(rp, side_vector, &arc_extreme_point, dis
tance1)) continue ;if (fabs(distance1 - flange_len
gth) <= AUTODIM_DISTANCE_TOLERANCE) {// if we have
the 0-angle point, create a left-right flange dim
ension point.// otherwise if next line is a non-ig
nored line, don’t do anything,// otherwise create
a left-right flange dimension point.if (endang >=
startang && leave_dimension_open(edge,bloop,side_
vector,plane->get_normal())) {continue ;}// create
a left-right flange dimension point. dimension li
st stays closed.// this is a 1-point flange dimens
ion point.if (temp_dp = new BM_AD_dim_corner(rv +
arc_extreme_point, this, adj_body,right_opening_di
rection, 1, list_of_points, NULL)) {list_of_points
= &(temp_dp->next) ;}}}break ;case BM_ENTITY_TYPE
_CIRCLE : // circles are a much simpler version of
the arc case.{BM_POINT circle_extreme_point = ((B
M_CIRCLE *) edge)->get_center() + (((BM_CIRCLE *)
edge)->get_rad())*side_vector ;// we won’t check
the distance since it mustbe a flange dimension po
int// create a left-right flange dimension point./
/ this is a 1-point flange dimension point.if (tem
p_dp = new BM_AD_dim_corner(rv + circle_extreme_po
int, this, adj_body,right_opening_direction, 1, li
st_of_points, NULL)) {list_of_points = &(temp_dp->
next) ;}}break;case BM_ENTITY_TYPE_ELLIPSE : // TO
DO : implement ellipse here. shouldbe similar to t
he way arc is handled.continue ;break ;default : c
ontinue ; // unknown edge type}}/* OK、全て終了。
*/*list_of_points = NULL ;return 1 ;}/*この関数は
1つのBM_AD_bendline構造に対するベンドラインディメ
ンションポイントを計算する。注意: p1は、フランジ
長が描かれる隣接体の平面上にある。pはセンタポイン
トである。 p2はベンドラインの側部のポイントであ
る。注意:この関数においては、我々は常にadj-body1
およびadj-body2に対するベンド-ディメンションポイン
トを計算する。このベンドラインは1または0の隣接体を
持つことになるが、我々は将来これらのポイントのビジ
ビリテイを知る必要がある。*/int BM_AD_bendline::co
mpute_BM_AD_bendline(void){double metal_thickness
; // thickness of the sheetmetalBM_2D_BODY *bendl
ine_displayed_version ; // 3D-version of the bendl
ineBM_VECTOR temp_v ; // vectorused for very short
periods for storing temporary stuff// initally ma
rkthe bendline data as invalid, in case we fail he
re.data_valid = 0 ;// qualification checkif (NULL
== bend) return 0 ;if (NULL == bend->get_adj_lis
t()) return 0 ;if (NULL == bend->get_part()) retur
n 0 ;// this bendline has to have a 3D-versionif
(parent->get_view_type()) {if (NULL == (bendline_d
isplayed_version = bend->get_current_3D_versio
n())) return 0 ;}else {if (NULL == (bendline_displ
ayed_version = bend->get_flat())) return0 ;}metal_
thickness = (bend->get_part())->get_metal_thicknes
s() ;/* ********** ********** ********** *********
* ********** ********** ********** ********** ****
******これは一時的な測度である。我々は単に規則的な
ベンドラインを処理する。すなわち、円錐ベンドライン
は無視する。03/16/96. KK.*/if (bend->get_bending_s
tatus() && bend->get_bend_op() && ! (bend->get_ben
d_op())->is(BM_TYPE_BEND_OP_REGULAR)) return 0 ;/*
********** ********** ********** ********** *****
***** ********** ********** ********** **********
*/// get the number of adjacent bodies.adj_body1 =
(bend->get_adj_list())->find_lowest_id_adj_body()
;adj_body2 = (bend->get_adj_list())->find_second_
lowest_id_adj_body() ;num_of_adjacent_bodies = (ad
j_body1? 1 : 0) + (adj_body2 ? 1 : 0) ;/*サイドベ
クトルを計算する。*/if (adj_body1) {if (! bendline
_displayed_version->compute_vector_perp_towards_ad
j_body(adj_body1, side_vector1)) return 0 ;side_ve
ctor1.normalise() ;}if(adj_body2) {if (! bendline_
displayed_version->compute_vector_perp_towards_adj
_body(adj_body2, side_vector2)) return 0 ;side_vec
tor2.normalise();}/*ベンドラインディメンションポイ
ントを計算する。*/if (! bend->get_bending_status()
/* bendline not bent */ || ! parent->get_view_typ
e() /* flat view */) {// note : here we don’t kno
w whether the dimension point is OUTSIDE or INSID
E.// this has to be taken into account later.// ho
wever, it should work either way.bend_body1_point_
left.num_of_points = bend_body1_point_right.num_of
_points = 1 ;bend_body1_point_left.can_reverse_ope
ning_dir = bend_body1_point_right.can_reverse_open
ing_dir = 0 ;bend_body1_point_left.p = (bendline_d
isplayed_version->get_current_center_line()).get_s
tartpt() ;bend_body1_point_right.p = (bendline_dis
played_version->get_current_center_line()).get_end
pt() ;// note opening directions. left will get st
art-point, right will get end-point, ie. vector go
es left->right.bend_body1_point_right.opening_dire
ction = (bendline_displayed_version->get_current_c
enter_line()).get_v() ;(bend_body1_point_right.ope
ning_direction).normalise() ;bend_body1_point_lef
t.opening_direction = -(bend_body1_point_right.ope
ning_direction) ;// points with respect to bothadj
acent bodies are the samebend_body2_point_left.num
_of_points = bend_body2_point_right.num_of_points
= 1 ;bend_body2_point_left.can_reverse_opening_dir
= bend_body2_point_right.can_reverse_opening_dir
= 0 ;bend_body2_point_right.opening_direction = be
nd_body1_point_right.opening_direction ;bend_body2
_point_left.opening_direction = bend_body1_point_l
eft.opening_direction ;bend_body2_point_left.p = b
end_body1_point_left.p ;bend_body2_point_right.p =
bend_body1_point_right.p ;}else {// first, get so
me bending parametersBM_SURFACE *surface = bendlin
e_displayed_version->get_surface() ;if (NULL == su
rface) return 0 ;BM_BEND_OP *bop = bend->get_bend_
op() ;if (NULL == bop) return 0 ;double bend_angle
= bop->get_bend_angle2() ;double bend_arc_angle =
PI - bend_angle ;double half_bend_arc_angle = ben
d_arc_angle/2.0 ;switch (surface->get_type()) {cas
e BM_TYPE_CYLINDER : { // note that the bend op ca
n be both regular and conicBM_CYLINDER *cylinder =
(BM_CYLINDER *) surface ;double radius = cylinder
->get_rad() ;double outside_radius = radius ;if (b
endline_displayed_version->get_sense()) outside_ra
dius += metal_thickness ;// set some common values
bend_body1_point_left.can_reverse_opening_dir = be
nd_body1_point_right.can_reverse_opening_dir = 0 ;
bend_body1_point_right.opening_direction =(bendlin
e_displayed_version->get_current_center_line()).ge
t_v() ;(bend_body1_point_right.opening_direction).
normalise() ;bend_body1_point_left.opening_directi
on = -(bend_body1_point_right.opening_direction) ;
if (outside_radius <= AUTODIM_DISTANCE_TOLERANCE)
{// special case : outside radius 0 - trivial dime
nsion point.bend_body1_point_left.num_of_points =
bend_body1_point_right.num_of_points = 1 ;bend_bod
y1_point_left.p = (bendline_displayed_version->get
_current_center_line()).get_startpt() ;bend_body1_
point_right.p = (bendline_displayed_version->get_c
urrent_center_line()).get_endpt() ;bend_body2_poin
t_left.num_of_points = bend_body2_point_right.num_
of_points = 1 ;bend_body2_point_left.can_reverse_o
pening_dir= bend_body2_point_right.can_reverse_ope
ning_dir = 0 ;bend_body2_point_right.opening_direc
tion = bend_body1_point_right.opening_direction ;b
end_body2_point_left.opening_direction = bend_body
1_point_left.opening_direction ;bend_body2_point_l
eft.p = bend_body1_point_left.p ;bend_body2_point_
right.p = bend_body1_point_right.p ;}else {bend_bo
dy1_point_left.num_of_points = bend_body1_point_ri
ght.num_of_points = 3 ;// compute points p1 for ad
j_body1bend_body1_point_left.p1 = (bendline_displa
yed_version->get_current_center_line()).get_startp
t() ;bend_body1_point_right.p1 = (bendline_display
ed_version->get_current_center_line()).get_endpt()
;// theproblem now is that it could be that these
centerline points (which are// on the surface of
the bendline), could be only inside surface of the
bendline.if (bendline_displayed_version->get_sense
() && metal_thickness> AUTODIM_DISTANCE_TOLERANCE)
{temp_v = cylinder->get_vx() ;temp_v.set_length(m
etal_thickness) ;bend_body1_point_left.p1 = bend_b
ody1_point_left.p1 + temp_v ;bend_body1_point_righ
t.p1 = bend_body1_point_right.p1 + temp_v ;}// a b
reak in the computation of adj_body1.p1.// store c
urrent p1values for adj_body2 as well. this will s
ave some time.// // note thatwe should not really
compute adj_body2 points unless adj_body2 pointer/
/is not NULL. However, this point (adj_body2.p1) i
s very useful for computing// adj_body1.p2 (if ang
le is acute). so we compute it anyway.bend_body2_p
oint_left.p1 = bend_body1_point_left.p1 ;bend_body
2_point_right.p1= bend_body1_point_right.p1 ;// fi
nish adj_body1.p1. rotate points p1 into their fin
al correct location.// note we rotate in the negat
ive direction since adj_body1 is the smallest-inde
x// adjacent body as is "to-the-left-of-the-bendli
ne-centerline", which means// rotating to the lef
t.//first, compute the right vector for the rotati
on line.BM_VECTOR rot_v(cylinder->get_v()) ;if (ro
t_v % ((bendline_displayed_version->get_current_ce
nter_line()).get_v()) < 0.0) {rot_v.reverse() ;}BM
_rotate_point_around_line(&(bend_body1_point_left.
p1), cylinder->get_pt1(), rot_v, -half_bend_arc_an
gle) ;BM_rotate_point_around_line(&(bend_body1_poi
nt_right.p1),cylinder->get_pt1(), rot_v, -half_ben
d_arc_angle) ;// finish also adj_body2.p1. rotate
points p1 into their final correct location.BM_rot
ate_point_around_line(&(bend_body2_point_left.p1),
cylinder->get_pt1(), rot_v,half_bend_arc_angle) ;
BM_rotate_point_around_line(&(bend_body2_point_rig
ht.p1), cylinder->get_pt1(), rot_v, half_bend_arc_
angle) ;// compute points p for adj_body1.double x
;if (bop->is(BM_TYPE_BEND_OP_REGULAR)) {x= ((BM_B
END_OP_REGULAR *) bop)->compute_3D_outside_approx_
per_side() ;}else if (bop->is(BM_TYPE_BEND_OP_CONI
C)) {// TODO : implement conic bendline herereturn
0 ;}temp_v = -x*side_vector1 ;bend_body1_point_le
ft.p = bend_body1_point_left.p1 + temp_v ;bend_bod
y1_point_right.p = bend_body1_point_right.p1 + tem
p_v ;// note : adj_body1.p2 and adj_body2.p, adj_b
ody2.p2 are yet to be computed.// now there are tw
o cases : 1) the bend arc angle is acute (ie. no m
ore than 90 degrees),// 2) the bend arc angleis mo
re than 90 degrees.if (bend_arc_angle > (PI_over_2
+ BM_ANGLE_TOLERANCE)) { // use tangent approxima
tion// we will finish computing adj_body1. adj_bod
y1.p2 is left.// idea : notice that adj_body1 is t
o the leftof the bendline−cent
erline// because it is th
e lowest−index neighbor.
Therefore the cross−produ
ct// of centerline−v by t
emp_v points towards thec
ylinder (actually it is t
angent// to the cylinde
r).BM_VECTOR tangent_v(be
nd_body1_point_right.open
ing_direction * temp_v) ;
tangent_v.set_length(x) ;
bend_body1_point_left.p2
= bend_body1_point_left.p
+ tangent_v ;bend_body1_
point_right.p2 = bend_bod
y1_point_right.p + tangen
t_v ;// noteadj_body2.p1
is already computed. firs
t set some common values.
bend_body2_point_left.num
_of_points = bend_body2_p
oint_right.num_of_points
= 3 ;bend_body2_point_lef
t.can_reverse_opening_dir
= bend_body2_point_righ
t.can_reverse_opening_dir
= 0 ;bend_body2_point_ri
ght.opening_direction = b
end_body1_point_right.ope
ning_direction ;bend_body
2_point_left.opening_dire
ction = bend_body1_point_
left.opening_direction ;/
/ now compute adj_body2.p
temp_v = −x*side_vector2
;bend_body2_point_left.p
= bend_body2_point_left.
p1 + temp_v ;bend_body2_p
oint_right.p = bend_body2
_point_right.p1+ temp_v ;
// finally, compute adj_b
ody2.p2// note the order
in the cross−product !tan
gent_v = temp_v * bend_bo
dy2_point_right.opening_d
irection; tangent_v.set_l
ength(x) ;bend_body2_poin
t_left.p2 = bend_body2_po
int_left.p + tangent_v ;b
end_body2_point_right.p2
= bend_body2_point_right.
p+ tangent_v ;}else { //
use intersection approxim
ation// note : adj_body2.
p2 is the same as asj_bod
y1.p1.bend_body1_point_le
ft.p2 = bend_body2_point_
left.p1 ;bend_body1_point
_right.p2 = bend_body2_po
int_right.p1 ;//when usin
g intersection approximat
ion, dimensions points wi
th respect to// both adja
cent bodies are the same,
so we just copy them.ben
d_body2_point_left.num_of
_points = bend_body2_poin
t_right.num_of_points = 3
;bend_body2_point_left.c
an_reverse_opening_dir =
bend_body2_point_right.ca
n_reverse_opening_dir = 0
;bend_body2_point_right.
opening_direction = bend_
body1_point_right.opening
_direction ;bend_body2_po
int_left.opening_directio
n = bend_body1_point_lef
t.opening_direction ;// n
ote we are switchingpoint
sbend_body2_point_left.p2
= bend_body1_point_left.
p1 ;bend_body2_point_righ
t.p2 = bend_body1_point_r
ight.p1 ;bend_body2_point
_left.p = bend_body1_poin
t_left.p ;bend_body2_poin
t_right.p = bend_body1_po
int_right.p ;}}}break ;ca
se BM_TYPE_CONE :break ;d
efault : ; // unknown or
illegalsurface ;}}/*隣接体の各
々に対するフランジ長を計算する。*/if (adj_body1){/
/ if the flange length computation fails, pretend
the adjacent body does not exist. for simplicity.i
f (! bend->compute_flange_length(parent->get_view_
type(),adj_body1,fl1)) {adj_body1 = NULL ;--num_of
_adjacent_bodies ;}}if (adj_body2) {if (! bend->co
mpute_flange_length(parent->get_view_type(),adj_bo
dy2,fl2)) {adj_body2 = NULL ;--num_of_adjacent_bod
ies ;}}/*よし、データを有効なものとしてマークす
る。ベンドラインディメンションポイントが全てのベン
ドラインに対して計算されると、我々は同様に巣手のベ
ンドラインに対してフランジディメンションポイントを
計算することが出来る。*/data_valid = 1 ;// before
we can return, we have to check if body1,2 left(ri
ght) bendline dimension points // are the same.//
note the same meansnot the same pointers, but the
contents are equivalent.if (adj_body1 &&adj_body2)
{body12_left_the_same = (bend_body1_point_left ==
bend_body2_point_left) ;body12_right_the_same =
(bend_body1_point_right == bend_body2_point_right)
;}/*重要:ベンド-ディメンションポイントのいずれか
が1ポイント(ポイントp)のみを含むときは、実際には
見るべきベンドラインがないのでbody_required_visibl
eポインタは隣接体を指示するべきである。*/if (1 ==b
end_body1_point_left.num_of_points) bend_body1_poi
nt_left.body_required_visible = adj_body1 ;if (1 =
= bend_body1_point_right.num_of_points) bend_body1
_point_right.body_required_visible = adj_body1 ;if
(1 == bend_body2_point_left.num_of_points) bend_b
ody2_point_left.body_required_visible= adj_body2 ;
if (1 == bend_body2_point_right.num_of_points) ben
d_body2_point_right.body_required_visible = adj_bo
dy2 ;return 1 ;}/*********** ********** **********
********** ********** ********** ********** *****
***** **********BM_AUTO_DIMENSION class stuff.****
****** ********** ********** ********** **********
********** ********** ********** ***********//*確
実な発見的手法:ソリッドモードにおいて幾つかのポイ
ントを我々が無視出来るか否かをチェックする。ソリッ
ドモードにおいては、我々は時間の節約のためにこの発
見的手法を用いている。2つのベンドラインがフランジ
-長を表示するために(潜在的に)等価なフランジ-ディ
メンションポイントを用いているときは、我々は単に、
より高いidxを持つベンドライン(これらの2つのベン
ドラインに対する)に対してのみビジビリテイ情報を計
算する。*/void BM_AUTO_DIMENSION::compute_points_t
o_ignore_in_solid(void){int i ;BM_AD_dim_corner*te
mp_point ;for (i = 0 ; i < num_of_bendlines ; i++)
{if (! bends[i]->data_valid) continue ;if (bends
[i]->adj_body1) {for (temp_point = bends[i]->body1
_points ; temp_point ; temp_point = temp_point->ne
xt) {if (NULL== temp_point->adj_bendline) continue
;if ((temp_point->adj_bendline)->get_idx() > (ben
ds[i]->bend)->get_idx()) continue ;if (check_two_b
endlines_adjacent_to_same_flange(bends[i]->bend,be
nds[i]->adj_body1,temp_point->adj_bendline)) {temp
_point->ignore_in_solid_mode = 1 ;}}}if (bends[i]-
>adj_body2) {for (temp_point = bends[i]->body2_poi
nts ; temp_point ; temp_point = temp_point->next)
{if (NULL == temp_point->adj_bendline) continue ;i
f ((temp_point->adj_bendline)->get_idx() > (bends
[i]->bend)->get_idx()) continue ;if (check_two_ben
dlines_adjacent_to_same_flange(bends[i]->bend,bend
s[i]->adj_body2,temp_point->adj_bendline)) {temp_p
oint->ignore_in_solid_mode = 1 ;}}}}points_to_igno
re_in_solid_computed = 1 ;}/*この関数は自動寸法化
ベンドラインを構成し、データ構造を指示する。これは
ディメンションポイントを計算する主要関数である。*/
int BM_AUTO_DIMENSION::compute_auto_dimension_data
(void){int i ;// have to have a documentif (NULL =
= doc) return 0 ;// if no part, try to get a new p
art from the documentif (NULL == part) {set_part(d
oc->get_part()) ;}if (NULL == part) {dirty =0 ;ret
urn 1 ;}points_to_ignore_in_solid_computed = 0 ;/*
ビユータイプを得る。*/if (view) {view_type = view-
>get_current_view() ;}else {// we are screwedretur
n 0 ;}/*全てのベンドラインに対して全てのベンドライ
ンディメンションポイントを計算する。*/for (i = 0 ;
i < num_of_bendlines ; i++) {bends[i]->compute_BM
_AD_bendline() ;}/*全てのベンドラインに対してフラ
ンジディメンションポイントを計算する。*/for (i = 0
; i < num_of_bendlines; i++) {if (bends[i]->data_
valid) {if (bends[i]->adj_body1) bends[i]->compute
_BM_AD_flange_points(bends[i]->adj_body1) ;if (ben
ds[i]->adj_body2)bends[i]->compute_BM_AD_flange_po
ints(bends[i]->adj_body2) ;}}dirty = 0;return 1 ;} 付録I 幾つかの基本的自動寸法化関数、コンストラクタ、デス
トラクタおよび幾つかの他の基本的関数の例 //#include "stdafx.h"#include "BendCAD.h"#include
"BendCADDoc.h"#include"BendCADViewPart.h"#include
"AUTODIM.HXX"/*********** ********** ********** *
********* ********** ********** ********** *******
*** **********BM_AD_dim_corner class stuff.*******
*** ********** ********** ********** ********** **
******** ********** ********** ***********/BM_AD_d
im_corner::BM_AD_dim_corner(void) {visible = -1 ;n
um_of_points = 0 ;bend = NULL ;next = NULL ;adj_be
ndline = NULL ;body_required_visible = NULL ;ignor
e_in_solid_mode = 0 ;}/*このコンストラクタは中にた
だ1つのポイント(ポイントp)を持つディメンション
ポイントを生成するためのものである。*/BM_AD_dim_co
rner::BM_AD_dim_corner(BM_POINT const& P, BM_AD_be
ndline *B, BM_3D_BODY*Body_required_visible,BM_VEC
TOR const& OD, int RB, BM_AD_dim_corner **prev, BM
_BENDLINE *adj_bend){visible = -1 ;num_of_points =
1 ;p = P ;bend = B ;opening_direction = OD ;can_r
everse_opening_dir = RB ;next = NULL;body_required
_visible = Body_required_visible ;adj_bendline = a
dj_bend;ignore_in_solid_mode = 0 ;if (prev) *prev
= this ;}/*このコンストラクタは中に3ポイントを持つ
ディメンションポイントを生成するためのものである。
*/BM_AD_dim_corner::BM_AD_dim_corner(BM_POINT cons
t& P, BM_POINT const& P1, BM_POINT const& P2, BM_A
D_bendline *B, BM_3D_BODY *Body_required_visible,B
M_VECTOR const& OD, int RB, BM_AD_dim_corner **pre
v, BM_BENDLINE*adj_bend){visible = -1 ;num_of_poin
ts = 3 ;p = P ;p1 = P1 ;p2 = P2 ;bend = B ;opening
_direction = OD ;can_reverse_opening_dir = RB ;nex
t = NULL ;body_required_visible = Body_required_vi
sible ;adj_bendline = adj_bend ;ignore_in_solid_mo
de = 0 ;if (prev) *prev = this ;}/*1つのディメン
ションポイントを他のディメンションポイントに割り当
てる。この関数は内容を正確にコピーする。それが非常
に有用な関数であるか否かは確実ではない。*/voidBM_A
D_dim_corner::operator=(BM_AD_dim_corner const& gi
ven_point){num_of_points = given_point.num_of_poin
ts ;p = given_point.p ;p1 = given_point.p1 ;p2 = g
iven_point.p2 ;bend = given_point.bend ;opening_di
rection = given_point.opening_direction ;can_rever
se_opening_dir = given_point.can_reverse_opening_d
ir ;visible = given_point.visible ;screen_x = give
n_point.screen_x ;screen_y = given_point.screen_y
;z_buf_value = given_point.z_buf_value ;ignore_in
_solid_mode = given_point.ignore_in_solid_mode ;}/
*この関数は、もしディメンションを描くために所定の
ポイントがこのポイントと同じときはTRUEを戻す。2つ
のディメンションポイントは、それらの1つのポイント
pが他のディメンションポイントのライン(ポイントp,
開放方向)により定義されるライン上にあるとき、また
それらの開放方向が一致するとき、等価である。ここで
我々は、開放ベクトルが規格化されるという事実に依存
する。it returns 2 iff both points p match, otherw
ise 1.*/int BM_AD_dim_corner::operator==(BM_AD_dim
_corner const& another_dim_point){int ret_val = 1
;double k ;if (num_of_points < 1 || another_dim_p
oint.num_of_points < 1) return 0 ;// point has to
be on the lineif (! BM_is_point_on_line(p, opening
_direction, another_dim_point.p, &k)) return 0 ;if
(fabs(k) <= BM_PRECISION) ret_val = 2 ;// since b
oth vectors should be normalized, the dot-product
is the cos of the angle.double x = opening_directi
on % another_dim_point.opening_direction ;// check
if both vectors agreeif (x > 0.99) return ret_val
;// check if they have opposite direction and one
of the can be reversedif (x < -0.99) {if (can_rev
erse_opening_dir || another_dim_point.can_reverse_
opening_dir) return ret_val ;}return 0 ;}/********
************* ********** ********** ********** ***
******* ********** ********** **********BM_AD_bend
line class stuff.********** ********** **********
********** ********** ********** ********** ******
**** ***********/BM_AD_bendline::BM_AD_bendline(BM
_AUTO_DIMENSION *owner, BM_BENDLINE *bendline){par
ent = owner ;bend = bendline ;data_valid = 0 ; //
data not valid - no data computed yetbend_body1_po
int_left.bend = bend_body1_point_right.bend = this
;bend_body2_point_left.bend = bend_body2_point_ri
ght.bend = this ;bend_body1_point_left.body_requir
ed_visible = bend_body1_point_right.body_required_
visible = bend ;bend_body2_point_left.body_require
d_visible = bend_body2_point_right.body_required_v
isible = bend ;body1_points = NULL ;body2_points =
NULL ;}BM_AD_bendline::~BM_AD_bendline(void){BM_A
D_dim_corner *temp_point, *temp_p ;// delete lists
of pointsfor (temp_point = body1_points ; temp_po
int ; temp_point = temp_p) {temp_p = temp_point->n
ext ;delete temp_point ;}for (temp_point = body2_p
oints ; temp_point ; temp_point = temp_p) {temp_p
= temp_point->next ;delete temp_point ;}}/********
*** ********** ********** ********** ********** **
******** ********** ********** **********BM_AUTO_D
IMENSION class stuff.********** ********** *******
*** ********** ********** ********** *************
******* ***********/BM_AUTO_DIMENSION::BM_AUTO_DIM
ENSION(CBendCADDoc*BendCAD_doc){doc = BendCAD_doc
;view = (CBendCADViewPart *) doc->get_view(BENDCA
D_VIEW_TYPE_PART) ;dc = NULL ;part = NULL ;dirty =
1 ;view_type= 1 ; // 3D viewreset_view_to_false_o
nce_drawn = 0 ;points_to_ignore_in_solid_computed
= 0 ;num_of_bendlines = 0 ;bends = NULL ;// initia
lize show states for dimension infom_bShowFlangeDi
m = TRUE;m_bShowBendDim = TRUE;m_bShowPartDim = FA
LSE;// initialize Auto-Dim colorsm_crFlange = RGB
(0,0,255);m_crBend = RGB(0,0,255);m_crPart = RGB
(0,0,255);// initialize font pointersm_pFlangeFont
= NULL;m_pBendFont = NULL;m_pPartFont = NULL;// i
nitialize line and arrow stylesm_nLineStyle = PS_S
OLID;m_nLineWeight= 1;// in pixelsm_nArrowStyle =
1;m_nArrowAngle = 30;// in degreesm_nArrowLength =
15;// in pixels// initialize dirty region pointer
pDirtyRegion= NULL;}BM_AUTO_DIMENSION::~BM_AUTO_DI
MENSION(void){delete_contents() ;}/*この自動-寸法
化対象を破壊する。*/void BM_AUTO_DIMENSION::delete
_contents(void){int i ;if (bends) {for (i = 0 ; i
< num_of_bendlines ; i++) {if (bends[i]) delete be
nds[i] ;}delete [] bends ;bends = NULL ;}num_of_be
ndlines = 0 ;points_to_ignore_in_solid_computed =
0 ;part = NULL ;dirty= 1 ;}/*この関数は所定のベン
ドラインに係わるディメンションデータを含むBM_AD_be
ndline構造に対するポインタを戻す。*/BM_AD_bendline
*BM_AUTO_DIMENSION::get_AD_bend_structure(BM_BEND
LINE *bendline){int i ;for (i = 0 ; i< num_of_bend
lines ; i++) {if (bends[i]->bend == bendline) retu
rn bends[i] ;}return NULL ;}/*この関数は所定のadj-
bodyに対する所定のベンドラインに対する(p->p2)ベク
トルを戻す。それはまたこのフランジに対する隣接ベン
ドラインのベンドディメンションポイントのp2ポイント
の間のラインを計算する。*/BM_VECTOR const& BM_AUTO
_DIMENSION::compute_bend_direction_vector(BM_BENDL
INE *bendline, BM_3D_BODY *adj_body, BM_LINE *p2_l
ine){static BM_VECTOR v ;int i ;for (i = 0 ; i < n
um_of_bendlines ; i++) {if (bends[i]->data_valid &
& bends[i]->bend == bendline) {if (bends[i]->adj_b
ody1 == adj_body) {v = (bends[i]->bend_body1_point
_left).p2 - (bends[i]->bend_body1_point_left).p ;p
2_line->set((bends[i]->bend_body1_point_left).p2,
(bends[i]->bend_body1_point_right).p2) ;return v
;}else if (bends[i]->adj_body2== adj_body) {v =
(bends[i]->bend_body2_point_left).p2 - (bends[i]->
bend_body2_point_left).p ;p2_line->set((bends[i]->
bend_body2_point_left).p2,(bends[i]->bend_body2_po
int_right).p2) ;return v ;}}}return BM_null_vector
;}/*この関数は、フランジディメンションポイントが
所定のadj-bodyに隣接するという事実を考慮するため所
定のベンドラインに対するフランジ長を描く効果を伝搬
させるために用いられる。それは、 adj-bendが所定の
フランジに対して同様に描かれるものとしてマークされ
るときTRUEを戻す。*/int BM_AUTO_DIMENSION::compute
_effects_flange_length_drawn(BM_BENDLINE *bendlin
e, BM_3D_BODY *adj_body, BM_AD_dim_corner *bend_di
m_point /* bend dim point for bendline */, BM_AD_d
im_corner *flange_dim_point /* flange dim points f
orbendline */, BM_BENDLINE *adj_bend){BM_AD_dim_co
rner **p_body_points ;int *p_body_drawn ;BM_AD_dim
_corner **p_drawn_bend_dim_point ;BM_AD_dim_corner
**p_drawn_flange_dim_point ;int i ;// first we ha
ve to find a BM_AD_bendline structure for this adj
-bendfor (i = 0 ; i < num_of_bendlines ;i++) {if
(! bends[i]->data_valid || bends[i]->bend != adj_b
end || bends[i]->ignore) continue ;if (bends[i]->a
dj_body1 == adj_body) {if (bends[i]->body1_drawn)
return 0 ;p_body_points = &(bends[i]->body1_point
s) ;p_body_drawn = &(bends[i]->body1_drawn) ;p_dra
wn_bend_dim_point= &(bends[i]->drawn_bend_dim_poin
t1) ;p_drawn_flange_dim_point= &(bends[i]->drawn_f
lange_dim_point1) ;break ;}else if (bends[i]->adj_
body2 == adj_body) {if(bends[i]->body2_drawn) retu
rn 0 ;p_body_points = &(bends[i]->body2_points) ;p
_body_drawn = &(bends[i]->body2_drawn) ;p_drawn_be
nd_dim_point = &(bends[i]->drawn_bend_dim_point2)
;p_drawn_flange_dim_point = &(bends[i]->drawn_fla
nge_dim_point2) ;break ;}else return 0 ;}if (i >=
num_of_bendlines) return 0 ;// now we need to chec
k if the list of flange dimensionpoints for this n
ewly found // BM_AD_bendline structure contains an
y flange dimension points that are adjacent to our
bendlineBM_AD_dim_corner*temp_point ;for (temp_po
int = *p_body_points ; temp_point ; temp_point= te
mp_point->next) {if (temp_point->adj_bendline == b
endline) break ;}if (NULL == temp_point) return 0
;// mark the flange length for the adj-bend drawn
with respect to this adj-body*p_body_drawn = 1 ;*
p_drawn_bend_dim_point = flange_dim_point ;*p_draw
n_flange_dim_point = bend_dim_point;return 1 ;}/*
この関数は、 adj_bendが、所定のベンドラインに隣接
する所定のフランジに対してフランジ-ディメンション
ポイントを持つときTRUEを戻す。*/int BM_AUTO_DIMENS
ION::check_two_bendlines_adjacent_to_same_flange(B
M_BENDLINE *bendline, BM_3D_BODY *flange, BM_BENDL
INE *adj_bend){BM_AD_dim_corner **p_body_points ;i
nt i ;// first we have to find a BM_AD_bendlinestr
ucture for this adj-bendfor (i = 0 ; i < num_of_be
ndlines ; i++) {if(! bends[i]->data_valid || bends
[i]->bend != adj_bend) continue ;if (bends[i]->adj
_body1 == flange) {p_body_points = &(bends[i]->bod
y1_points);break ;}else if (bends[i]->adj_body2 ==
flange) {p_body_points = &(bends[i]->body2_point
s) ;break ;}else return 0 ;}if (i >= num_of_bendli
nes)return 0 ;// now we need to check if the list
of flange dimension pointsfor this newly found //
BM_AD_bendline structure contains a flange dimensi
on points that is adjacent to our bendlineBM_AD_di
m_corner *temp_point ;for (temp_point = *p_body_po
ints ; temp_point ; temp_point = temp_point->next)
{if (temp_point->adj_bendline == bendline) return
1 ;}return 0;}/*新しい部分を設定する。これは同様
にビユークラスポインタを更新し、幾つかの他のパラメ
ータを設定する。*/void BM_AUTO_DIMENSION::set_part
(BM_PART *new_part){BM_BENDLINE *bendlist ;int i ;
delete_contents() ;if (NULL== doc) return ;part =
new_part ;if (NULL == part) return ;half_metal_thi
ckness = (part->get_metal_thickness())/2.0 ;// all
ocate the bendlistif(0 == (num_of_bendlines = part
->get_number_of_bendlines())) return ;if (NULL ==
(bends = new BM_AD_bendline*[num_of_bendlines])) g
oto failure ;bendlist = part->get_bendline_list()
;for (i = 0 ; i < num_of_bendlines ;i++) {if (ben
dlist) {bends[i] = new BM_AD_bendline(this,bendlis
t) ;bendlist = (BM_BENDLINE *) bendlist->next() ;}
else bends[i] = NULL ;}// note, dirty is TRUEretur
n ;failure :delete_contents() ;} 付録J 薄板部分に対するエンティティビジビリテイ関数を含む
ベンドモデルビユワ実施の例 #include "stdafx.h"// include all BMAPI files#incl
ude "ALLBMAPI.HXX"// RW_DRAW library include file.
#include "RW_DRAW.HXX"#include "BendCADDoc.h"#incl
ude "BendCADViewPart.h"// RenderWare include file
s; found in \rwwin\include#include "rwlib.h"// Ope
nGL include files.#include "gl\gl.h"#include "gl\g
lu.h"// GL_LIST library include file.#include "GL_
LIST.HXX"#include <stdlib.h> /* ワールド座標に
おけるポイントを表すBM_POINTが与えられると、人はそ
れをビユーウインド座標上に射影することが出来る。
A) Ifthe display is showing the SOLID version of t
he part, this function passes back a pointer to th
e edge closest to the camera that lies undert
hat projected point. The x_pos, y_pos, and z_depth
pointers carry theview window coordinates (with t
op left corner as (0,0) and the z-buffervalue. If
the projected point is not in the viewing volume,
the return value is 0; then of course the edge po
inter is meaningless, and is set to NULL. If the p
rojected point IS within the viewing volume, the
n thereturn value is 1, and the edge pointer point
s to the edge that lies under the projected point.
If the pointer is NULL, no edge lies under thepr
ojected point. B) If the display is showing the W
IREFRAME version ofthe part, only the return valu
e: 1 if within view volume, 0 otherwise - shou
ld be examined. If return value is 1, x_pos, y_pos
and z_depth values have meaning. The edge pointer
is always NULL.*/int CBendCADViewPart::map_point_
to_closest_edge(BM_POINT const& three_d_point, int
*x_pos,int *y_pos,
double *z_depth,BM_EDGE **closest_ed
ge){ int x, y, visible = 1; double z; visible
= map_3d_to_screen(three_d_point, &x, &y, &z); if
( ! visible ) {// Point is outside viewing volume.
if(closest_edge) *closest_edge = NULL;if(x_po
s) *x_pos = x;if(y_pos) *y_pos = y;if(z_depth) *z_
depth = z;return 0; } // Now point is inside vie
w volume. if(x_pos) *x_pos = x; if(y_pos) *y_pos
= y; if(z_depth) *z_depth = z; if(! mi_show_sol
id) { // Wireframe being drawn; ju
st return that point is if(closest_edge) *clos
est_edge = NULL; // within view vol.return 1; }
// Now solid is being shown. if(! closest_edge) r
eturn 1; //Point is within view volume. Pick that
point. pick_point_rw(x, y, closest_edge); retur
n 1;}// This function returns the view window coor
dinates of a point, with top left corner as (0,0),
and the // z-buffer depth,given the three-dimensi
onal world coordinates of the point. It does soby
calling either // map_3d_to_screen_solid or map_3d
_to_screen_wire, depending on whether wireframe or
solid is being shown. // On return, iff*x_pos, *y
_pos are both zero, the point was not mapped onto
the screen at all.int CBendCADViewPart::map_3d_to_
screen(BM_POINT three_d_point, int*x_pos, int *y_p
os, double *z_depth){ int visible; if(mi_show_s
olid)visible = map_3d_to_screen_solid(three_d_poin
t, x_pos, y_pos, z_depth);else visible = map_3d_to
_screen_wire(three_d_point, x_pos, y_pos, z_dept
h); return visible;}// This function returns the
view window coordinates of a point, with top left
corner as (0,0), and the// z-buffer depth,given th
e three-dimensional world coordinates of the poin
t, using OpenGL utilities // (ie. when wireframe i
s on). If return value is 0, point is not mapped o
nto screen, ie. not visible.int CBendCADViewPart::
map_3d_to_screen_wire(BM_POINT three_d_point, int
*x_pos, int *y_pos, double *z_depth){ int viewp
ort[4], visible = 1; double width, height, depth;
double model_mat[16], proj_mat[16], array[16]; //
Get the current viewport coords. glGetIntegerv(G
L_VIEWPORT, viewport); // Now build a modelview m
atrix out of the current set of transformations.
glMatrixMode(GL_MODELVIEW); glPushMatrix(); gl
Translated(md_x_trans, md_y_trans, 0.0);convert_rw
_matrix_to_gl_array(md_rot_matrix, array);glMultMa
trixd(array);glTranslated(- m_part_centroid.X(), -
m_part_centroid.Y(), - m_part_centroid.Z()); g
lGetDoublev(GL_MODELVIEW_MATRIX, model_mat); gl
GetDoublev(GL_PROJECTION_MATRIX, proj_mat); glPop
Matrix(); gluProject(three_d_point.X(), three_d_p
oint.Y(), three_d_point.Z(), model_mat, proj_mat,
viewport, &width, &height,
&depth); if( ((int)width > m_old_rect.right) ||
((int)width < 0) ) visible = 0; if( ((int)height
> m_old_rect.bottom) || ((int)height < 0) ) visibl
e = 0; if(x_pos) *x_pos = (int) width; if(y_pos)
*y_pos = (m_old_rect.bottom - (int) height); if
(z_depth) *z_depth = depth; return visible;}
// This function returns the
view window coordinates o
f a point, with top left
corner as (0,0), and the/
/ z−buffer depth, given t
he three−dimensional worl
d coordinates of the poin
t, using RenderWare utili
ties // (ie. when solid i
s on). If return value is
0, point is not mapped o
nto the screen, ie.not vi
sible.// Note: At presen
t, same as map_3d_to_scre
en_wire.int CBendCADViewP
art::map_3d_to_screen_sol
id(BM_POINT three_d_poin
t, int *x_pos,int *y_pos,
double *z_depth){ int viewpo
rt[4], visible = 1; doublewidth, height, depth;
double model_mat[16], proj_mat[16], array[16]; //
Get the current viewport coords. glGetIntegerv(G
L_VIEWPORT, viewport); // Now build a modelview m
atrix out of the current set of transformations.
glMatrixMode(GL_MODELVIEW); glPushMatrix(); gl
Translated(md_x_trans, md_y_trans, 0.0);convert_rw
_matrix_to_gl_array(md_rot_matrix, array);glMultMa
trixd(array);glTranslated(- m_part_centroid.X(), -
m_part_centroid.Y(), - m_part_centroid.Z()); g
lGetDoublev(GL_MODELVIEW_MATRIX, model_mat); gl
GetDoublev(GL_PROJECTION_MATRIX, proj_mat); glPop
Matrix(); gluProject(three_d_point.X(), three_d_p
oint.Y(), three_d_point.Z(), model_mat, proj_mat,
viewport, &width, &height,
&depth); if( ((int)width > m_old_rect.right) ||
((int)width < 0) ) visible = 0; if( ((int)height
> m_old_rect.bottom) || ((int)height < 0) )visible
= 0; if(x_pos) *x_pos = (int) width; if(y_pos)
*y_pos = (m_old_rect.bottom - (int) height); if(z
_depth) *z_depth = depth; returnvisible; }// T
his function picks the point indicated by map_3d_t
o_screen, using RenderWare picking, so this is// c
alled only when solid is being shown. Note that th
e pick position is with respect to the top left//
corner of the view window being (0,0). If the pick
results in an edge, apointer to the edge is// pas
sed back in picked_edge; else, picked_edge is set
to null. This does not modify the selection// set
in any way.voidCBendCADViewPart::pick_point_rw(int
x_pos, int y_pos, BM_EDGE **picked_edge) { if(pi
cked_edge == NULL) return; if( (x_pos > m_old_rec
t.right)|| (y_pos > m_old_rect.bottom)) { // Make
sure point given is within*picked_edge = NULL;//
viewport.return; } RwClump *picked_clump = NUL
L;RwClump *parent_clump = NULL; long parent_tag,
clump_tag, key = 0; BM_EDGE *edge = NULL; if(! R
wPickScene(m_scene, x_pos, y_pos, m_camera,&m_pic
k)) { // Picking command was not successful. *p
icked_edge = NULL;return; } if(m_pick.type == rw
NAPICKOBJECT) { // No clump was
picked.*picked_edge = NULL;return; } else if(m_p
ick.type == rwPICKCLUMP) { // So
me clump was picked; process it.picked_clump = m_p
ick.object.clump.clump;parent_clump = RwGetClumpPa
rent(picked_clump);parent_tag = RwGetClumpTag(pare
nt_clump);clump_tag =RwGetClumpTag(picked_clump);i
f(parent_tag == 1) { *picked_edge = NULL;return;
// A trivia
l bendline orforming was picked. } // Now so
me real edge was picked.key = (parent_tag%10000)*1
00000 + clump_tag; if(clump_tag) // Safety check;
we expect clump_tag to be non-zero. *picked_e
dge = map_list_name_to_bm_edge(parent_tag, clump_t
ag); }} // This function returns the ratio o
f the view volume dimension (object space dimensio
ns) to// the viewportdimension (device space dimen
sions).double CBendCADViewPart::get_object_to_devi
ce_ratio(void){ double ratio; if(m_old_rect.righ
t) ratio =2.0*md_current_view_vol[0]/(double)
(m_old_rect.right); else ratio = 0.0; return rat
io;}/* Given a BM_POINT, which represents a point
in worldcoordinates, one can project it onto view
window coordinates. This function first checks if
the projected point is within the viewing volume.
If it IS within viewing volume, the pointer "visi
ble" carries value 1; else, 0. If the point is not
visible, no other parameters have any meaning; th
e return value is 0. Now suppose the point is vis
ible. A) If the display is showing the SOLID vers
ion of the part, this function checks ifANY of the
three_d_bodies in the array "three_db_array" lies
"approximately under" the projected point. If the
answer is yes, return value is 1; else, return va
lue is zero. The x_pos, y_pos, and z_depth pointer
s carry the view window coordinates (with top left
corner as (0,0)) and the z-buffer value. The arra
y "thee_db_array" must be terminated by a NULL poi
nter to indicate end of array. B) If the display
is showing the WIREFRAME version of the part the r
eturn value is always zero. If the point is withi
n view volume, *visible is set to 1; else, 0. If *
visible is 1, x_pos, y_pos and z_depth values have
the meaning mentioned above. */int CBendCADViewPa
rt::is_3d_body_near_point(BM_POINT const& three_d_
point, BM_3D_BODY **three_db_array,
int *visible, int *x_po
s, int *y_pos, double *z_depth){ int x, y, is_vis
ible= 1; double z; int found = 0; is_visible =
map_3d_to_screen(three_d_point, &x, &y, &z); if(
! is_visible) { // Point is outsidevie
wing volume.if(x_pos) *x_pos = x;if(y_pos) *y_pos
= y;if(z_depth) *z_depth = z;if(visible) *visible
= 0;return 0; } // Now point is insideview volum
e. if(x_pos) *x_pos = x; if(y_pos) *y_pos = y;
if(z_depth)*z_depth = z; if(visible) *visible =
1; if(! mi_show_solid) {// Wireframe being drawn;
just return that point is return 1; // within vie
w volume. } // Now solid is being shown. if(! t
hree_db_array) return 0; // Point is within view
volume. Pick pixels in a triangle around that poin
t. found = pick_point_for_3db_rw((x - 2), (y -
2), three_db_array); if(found) return 1; found =
pick_point_for_3db_rw((x -2), (y + 2), three_db_a
rray); if(found) return 1; found = pick_point_fo
r_3db_rw((x + 2), (y + 2), three_db_array); if(fo
und) return 1; found= pick_point_for_3db_rw((x +
2), (y - 2), three_db_array); if(found) return 1;
return 0;}// This function picks the point indic
ated, using RenderWare picking, so this is called
only when solid is // being shown. Note that the p
ick position is with respect to the top left corne
r of theview window being // (0,0). If the pick re
sults in a three_d_body’s clump, and the picked c
lump corresponds to ANY of the// three_d_bodies i
nthe array passed, return value is 1; if no match
or no three_d_body, return is 0.// This does not m
odify the selection set in any way.int CBendCADVie
wPart::pick_point_for_3db_rw(int x_pos, int y_pos,
BM_3D_BODY **three_db_array) { if(three_db_array
== NULL) return 0; if( (x_pos > m_old_rect.righ
t) || (y_pos > m_old_rect.bottom)) { // Make sure
point given is withinreturn 0;
// viewport. } RwClump *picked_clump
= NULL; RwClump *parent_clump = NULL; long paren
t_tag,clump_tag, required_id;int found = 0; if(!
RwPickScene(m_scene, x_pos, y_pos, m_camera, &m_p
ick)) { // Picking command was not successful.retu
rn 0; } if(m_pick.type == rwNAPICKOBJECT) {
// No clump was picked.return 0; }
else if(m_pick.type == rwPICKCLUMP) {// Some clu
mp was picked; process it. picked_clump = m_pic
k.object.clump.clump;parent_clump = RwGetClumpPare
nt(picked_clump);parent_tag = RwGetClumpTag(parent
_clump);clump_tag = RwGetClumpTag(picked_clump);if
(parent_tag == 1) { // Body of fac
e/bendline/formingwas picked.for(int i=0; three_db
_array[i]; ++i) { // Check if it matches any of th
e ones in array.if(three_db_array[i] == NULL) brea
k;required_id = three_db_array[i]->get_idx();if(cl
ump_tag%10000 == required_id){found = 1;break;}}re
turn found;} // Now some edge’s clump was pick
ed. Check if it matches any of the ones in array.f
or(int i=0; three_db_array[i]; ++i) {if(three_db_a
rray[i] == NULL) break;required_id = three_db_arra
y[i]->get_idx();if(parent_tag%10000 == required_i
d) {found = 1;break;} } } return found;} /
/ This allows the user to insert itemsinto the sel
ection set. "list" is an array of pointers// to th
ree-d-bodies, terminated by NULL to indicate end o
f array. If list is passed as NULL, every // three
-d-body in the part is inserted into the selection
set. void CBendCADViewPart::insert_selection_set
(BM_3D_BODY **list){ int tag;BV_SELECT_DATA *data
= NULL; if(! list) { // Insert ev
ery three_d_body in part into selection set.BM_PAR
T *part = NULL;CBendCADDoc* pDoc = GetDocument();A
SSERT_VALID(pDoc);part = pDoc->get_part();if(! par
t) return; BM_FACE *face = NULL;BM_BENDLINE *bend
line = NULL;BM_FORMING *forming = NULL;for(face =
part->get_face_list(); face; face = (BM_FACE *)fac
e->next()) { if(! face) continue;tag = 100000*(fa
ce->get_idx()) + 10000 + face->get_idx();if(! m_se
lection_set.find(tag, NULL)) {data = new BV_SELECT
_DATA;data->key = tag;data->edge = NULL;data->worl
d_pt = BM_POINT(0.0, 0.0, 0.0);m_selection_set.ins
ert(tag, (long)data);}}for(bendline = part->get_be
ndline_list(); bendline; bendline = (BM_BENDLINE
*)bendline->next()) { if(! bendline) continue;tag
= 100000*(bendline->get_idx()) + 10000 + bendline
->get_idx();if(! m_selection_set.find(tag,NULL))
{data = new BV_SELECT_DATA;data->key = tag;data->e
dge = NULL;data->world_pt = BM_POINT(0.0, 0.0, 0.
0);m_selection_set.insert(tag, (long)data);}}for(f
orming = part->get_forming_list(); forming; formin
g = (BM_FORMING *)forming->next()) { if(! formin
g) continue;tag = 100000*(forming->get_idx()) + 10
000 + forming->get_idx();if(! m_selection_set.find
(tag, NULL)) {data = new BV_SELECT_DATA;data->key
= tag;data->edge = NULL;data->world_pt = BM_POINT
(0.0, 0.0, 0.0);m_selection_set.insert(tag, (long)
data);}}DrawPart(m_hdc);return;}BM_3D_BODY *three_
d_body;long i;for(i=0, three_d_body = list[0]; thr
ee_d_body; ++i, three_d_body = list[i]) {if(! thre
e_d_body) break;tag = 100000*(three_d_body->get_id
x()) + 10000+ three_d_body->get_idx();if(! m_selec
tion_set.find(tag, NULL)) {data =new BV_SELECT_DAT
A;data->key = tag;data->edge = NULL;data->world_pt
= BM_POINT(0.0, 0.0, 0.0);m_selection_set.insert
(tag, (long)data);}}DrawPart(m_hdc);return;}// Thi
s function returns the largest of the x, y and z p
rojections of the part’s// bounding box.double CB
endCADViewPart::get_approx_part_size(void){ if(md
_part_bbox_size) { double size = __max(md_part_
bbox_size[0], md_part_bbox_size[1]); size = __m
ax(size, md_part_bbox_size[2]); return size; }
else return 0.0;}// This function passes back th
e bounding box size of the part in its original or
ientation,in the// array "dimensions". This array
should be at least of size 3. Returns 1 if success
ful, 0 otherwise.// Caution: This is a quick and h
ence not very accurate calculation; if you want gr
eater precision,// writeyour own function.int CBen
dCADViewPart::get_part_dimensions(double *dimensio
ns){ CBendCADDoc* pDoc = GetDocument();if(! pDoc)
return 0;BM_PART*part = pDoc->get_part();if(! par
t) return 0;if(! dimensions) return 0;int i;BM_POI
NT centroid;RwMatrix4d *temp = RwCreateMatrix();i
= compute_part_centroid(part, 1, &centroid);if(!
i) return 0; i = compute_part_bbox(part, 1, temp,
centroid, dimensions, NULL); if(! i) return 0;RwD
estroyMatrix(temp);return 1;} 付録K PART.HXXはベンドモデルおよび部分構造などに関するコ
メント /*このファイルはBMAPI BM_PARTクラスの定義を含む。
部分関数の殆どはPART.CPPにある。コンストラクタとデ
ストラクタはPART_NEW.CPPにある。シリアル化関数はPA
RT_LOAD_x.CPPおよびPART_SAVE.CPPにある。フォルデイ
ング関数はFOLD.CPPおよび3D_FUNC.CPPにある。アンフ
ォルデイング関数はUNFOLD.CPPにある。***** ********
********* ********* ********* ********* *********
議論:-BMAPIの設計原理の1つは、全体の部分を厚さと
全てのもので正確に表そうとすることである。これの利
点の1つは、我々が何かを問い合わせ、迅速に答えを得
ることが出来るということにある。答えがあからさまに
は表されなくても、それは容易に計算される。それの他
の利点は、我々は"中実な部分"として部分を表している
ので、部分を3Dモデル化することが直ちに出来るという
ことにある。-薄板の特殊な性質の1つは、それが対称
的であることである。我々は、我々がその部分を表し、
それについて理由付けするときこの事実の利点を用いる
ことが出来る。例えば、我々は薄板の1つの側のみを、
その他側は我々が厚さベクトルを知ると定義されるの
で、表すことが出来る。-1つの問題は、我々が部分の
フラットバージヨンを与えられたとき(それは通常は厚
さを含まない)如何に我々はそれから部分を構成するか
ということにある。このフラットは部分の中性ラインを
表すということを採用するか?このBMAPIにおいて、我々
は、ベンドモデルであからさまに表される部分のフラッ
トバージヨンは、部分がトップビユー(上面図)にある
とき薄板のボトム側であるということを採用している。
他の重要な点は、このフラットバージヨンがX-Y面上に
あるということである。この方法では、例え厚さが変化
しても、我々のモデルに対する変化は最小である。- フ
ラットは薄板のボトム側を表すが、フラットのデイメン
シヨンは中性ラインデイメンシヨンを表す。すなわち、
我々が部分を曲げたとき、曲げた部分の中性ラインのデ
イメンシヨンはフラットデイメンシヨンに一致する(ま
たは、ベンドデダクシヨンにより定義される量だけずら
される)。これは、それらに対して内側=中性ライン=外
側なので面に対して不適切である。しかし、それはベン
ドラインに対して重要である。それは、ベンドラインの
基礎をなすフラットがベンドアークの中性ライン上にマ
ップされるということを意味する。- 部分が畳まれると
き、BMAPIは通常はベース-ボデイの2D->3D変換を変化さ
せることはない。しかし、ベース-ボデイがベンドライ
ンであり、ベンパラメータの幾つかを(例えば、ベンド
角)変える時は2D->3D変換マトリクスは’not-up-to-da
te’とマークされる。我々がこの古い変換マトリクスを
用いたときは、結果は悪くなる。従って、我々は実際に
古い(out-of-date)変換マトリクスを用いることは出来
ない。しかし、その場合、我々は、変換マトリクスを一
致マトリクスにリセットすることより行うべき更によい
ものを持つことはない。-全ての3D体のサイズは2通り
の方法で変化することが出来る。先ず、もし面が、ベン
ドデダクシヨンの半分の量に等しい量によりトリムされ
る。第二に、全てのボデイは隣接するベンドラインに関
してそれに係わるトリミング値を持つことが出来る。隣
接ベンドラインが曲げられるとき、このボデイはこの量
によりトリムされる。-BM APIはBMAPIファイルの全ての
公知の(すなわち、最近のおよび全ての初期の)バージ
ヨンをロードすることが出来る。-部分がフォルドされ
たとき、2D->3D変換のみが直ちに計算される。計算の残
部は要求に応じて、すなわち必要なときは常になされ
る。我々が部分をアンフォルドするときは、全ての事
態、すなわち3D-2D変換および部分のフラットバージヨ
ンが直ちに計算される。-部分がアンフォルドされると
きは、BMAPIは、3D-ボデイの現在の3D-バージヨンを、
それらがup-to-dateとしてマークされるか否かとは無関
係に、用いる。-BM_PARTクラスは部分の生成を容易にす
る幾つかのハイレベルの関数を有する。例えば、それ
は、部分のフラットバージヨンを検査し、見出された問
題点を固定する関数を有する。更に、それは、1組の面
のみが与えられたとき部分に対するベンドラインを生成
する関数を有する。これらは、多くの用途において共通
のタスクであるハイ-レベルの関数である。-部分のベン
ドラインに対しては、それらが特定のセンタラインを持
つことが絶対必要である。センタラインがないと、ベン
ドラインは殆ど無用であり、それはフォルドされること
もアンフォルドされることも出来ない。ベンドラインセ
ンタラインは3つの目的のために用いられる:-ベンド
ラインフォルデイング-アンフォルデイングのため。-ベ
ンドラインが空のときベンドラインンを表すため。-ベ
ンドラインの向きを決定するため。センタラインは、フ
ラットバージヨンが一定の向きを持つので(すなわち、
法線は(0,0,1)でなければならない。)、部分の2D(す
なわち、フラット)バージヨンにおいて最も"目的的"で
あるという点に注意されたい。部分の3Dバージヨンにお
いては、センタラインは、その意味が、変化可能な基礎
となる表面により定義されるので、幾らか"主観的"であ
る。例えば、我々は、表面(これは必然的に薄板を変化
させない)部分をフリップすることが出来、また結果と
してベンドラインの向きを同じに保つために同様にセン
タラインを反転させなければならない。-全てのベンド
ラインはそれに係わるンドデダクシヨンを持つ。 この
ベンドデダクシヨンは、部分がフォルドまたはアンフォ
ルドされるとき部分デイメンシヨンが(このベンドライ
ンにおいて)如何に変化するかを制御する。ベンドデダ
クシヨン値は正および負の両者を取ることが出来る。そ
れが正であり、我々が部分をフォルドするときは部分の
デイメンシヨンは拡大し、それが負のときは部分デイメ
ンシヨンは収縮する。正のベンドデダクシヨンはアンフ
ォルデイング時に部分をフォルドしシュリンクするとき
部分を拡大することを意味し、そして従って負のベンド
デダクシヨンはアンフォルデイング時に部分をフォルド
し、拡大するとき部分を収縮させることを意味する産業
基準である(と言われた)。-BM_PARTは、部分のデイメ
ンシヨンを制御するパラメータbendline_dimensions_st
atusを持つ。それは、部分の設計と生成を容易にするた
めに付加される。ユーザが(例えば)外側から外側へ部
分デイメンシヨンを与えられということはしばしば起こ
る。これらのデイメンシヨンはカスタマにより固定さ
れ、特定される。薄板設計プロセスのゴールは、コノフ
ラットがフォルドされるときそのデイメンシヨンが所定
のデイメンシヨンに正確に一致するようにこの部分のフ
ラットを生成することにある。設計プロセスにおいて
は、ユーザは一連の方法で部分を変化させることが出来
る。ただし、これが与えられたとき、我々は常に部分デ
イメンシヨンを変化しないようにすることを望む。 be
ndline_dimensions_statusがTRUEのとき、BMAPIは、ユ
ーザが部分/ベンドラインパラメータ(薄板の厚さまた
はベンドラインの半径などのような)を変化させると
き、可能んらば常に部分デイメンシヨンを(全てのベン
ドラインにおいて)一定に保とうとする。さもなけれ
ば、我々は注意しない。-以前の問題と関連して生じる
他の問題は、部分寸法が通常はOUTSIDE/INSIDE/NEUTRAL
デイメンシヨンとして特定されるということである。例
えば、ユーザは、ボックスが与えられ、その外側デイメ
ンシヨンは100x100であると特定する。技術的には、ユ
ーザは、フラット上でこのボックス内の全てのベンドラ
インが外側デイメンシヨンを表すということを特定して
いる。例えば、ユーザが後に薄板の厚さを変えたとき、
外側デイメンシヨンは同じままであり、すなわち全ての
付加された厚さは”ボックスの内側に行かなければなら
ない”一般に、ユーザ(またはカスタマ)は、同じ面内
でも、部分デイメンシヨンをOUTSIDE/INSIDE/NEUTRALデ
イメンシヨンと特定する。例えば、ユーザは、ボックス
を横切ってデイメンシヨンが、1側の薄板の内側から他
側の薄板の外側へとして与えられるということが出来
る。 我々は、ユーザが部分デイメンシヨンを一定に保
ことを望むか否かのトラックを保持する変数を部分内に
有する。もしこの変数が、ユーザが、部分デイメンシヨ
ンが一定に保持されることを要求しないように設定され
るとき、このINSIDE/OUTSIDE/NUETRAL-LINEのホワイル
ビジネスは無視される。*/#ifndef BM_PART_HXX_INCLUD
ED#define BM_PART_HXX_INCLUDED#include <stdio.h>#i
nclude "GLOBAL.HXX"#include "ENTITY.HXX"#include "
TOPOLOGY.HXX"class BM_PART : public BM_ENTITY{frie
nd BM_FACE ;friend BM_HOLE ;friend BM_BENDLINE ;fr
iend BM_FORMING ;friend BM_TOPOLOGY ;friendBM_TOPO
LOGY_RECORD ;friend BM_BEND_PROPERTY ;friend BM_BE
ND_PROPERTY_SIMULTANEOUS ;// every part has a (use
r-defined) name that it inherits fromBM_ENTITY.//
also, the type (BM_ENTITY_TYPE_PART) is stored in
BM_ENTITY.protected :/*これらの変数は、ユーザをし
て名前や、数、材料の種類などのパラメータを部分と関
係させる。*/char material_type[256] ;char name[25
6];char number[32] ;/*これらの変数は材料とメタル特
性を記述する。*/double metal_thickness ;/*この部分
内では、2つのポイントは、もしそれらの間の距離がこ
の値程度のときは同じであると考えられる。*/double d
istance_tolerance;/*全ての部分はベンド特性のリスト
を有する。ベンドラインがベンド特性を持つときは、こ
の特性の対象は部分に係わるベンド特性のリスト上にな
ければならない。これは、我々が部分をセーブまたはロ
ードするとき必要とされる。これらの変数は、内部にの
み使用される。BMAPIのユーザは、これらの変数にアク
セスを持たない。*/long number_of_bend_properties ;
BM_BEND_PROPERTY *list_of_bend_properties ;/*部分
のトポロジーここでボデイをリストに直接付加すること
は可能ではないことに注意されたい。これは、ボデイが
部分トポロジーに付加されるときにのみなされる。*/BM
_TOPOLOGY topology ;// number of different3D bodie
s in the part.// these numbers should be consisten
t with the part topology.long number_of_faces ;lon
g number_of_holes ;long number_of_bendlines ;long
number_of_formings ;// lists of faces, holes and b
endlines of the part// Note that these are lists o
f BM_3D_BODY’s.BM_FACE *first_face ;BM_HOLE *firs
t_hole ;BM_BENDLINE *first_bendline ;BM_FORMING *f
irst_forming ;/*これらのパラメータは部分に係わるベ
ンドシーケンスを表す。*/long bend_sequence_size ;B
M_LINKED_LIST_NODE *bend_sequence ;/*このパラメー
タは部分デイメンシヨンを制御する。それがTRUEのとき
は、BMAPIは、ユーザが(薄板の厚さまたはベンドライ
ンの半径などの)部分/ベンドラインパラメータを変え
るとき、可能なときは常に、部分のデイメンシヨンを
(全てのベンドラインにおいて)一定に保とうと試み
る。さもなければ、我々は注意しない。デフォールト値
は0であり、デイメンシヨンを一定に保持する必要はな
い。*/charbendline_dimensions_status ;public :/*コ
ンストラクタとデストラクタ。PART_NEW.CPPにおいて。
*/BM_PART(void) ;BM_PART(BM_PART *existing_part) ;
~BM_PART(void) ;// use this to erase the content o
f the part. the part willbe empty.// it will use t
opology::erase_content() to destroy the topology a
nd will then // destroy all bodies in the part.voi
d erase_content(void) ;void get_material_type(char
*out_mat_type) ;void set_material_type(char *in_m
at_type) ;void get_name(char *out_name) ;void set_
name(char *in_name) ;void get_part_number(char *ou
t_number) ;void set_part_number(char *in_number) ;
// get number of faces, holes, bendlinesinline lon
g get_number_of_faces(void) const { return number_
of_faces ; }inline long get_number_of_holes(void)
const { return number_of_holes ; }inline long get_
number_of_bendlines(void) const { return number_of
_bendlines ; }inline long get_number_of_formings(v
oid) const { return number_of_formings ; }//get po
inters to lists of faces, holes and bendlinesinlin
e BM_FACE *get_face_list(void) const { return firs
t_face ; }inline BM_HOLE *get_hole_list(void) cons
t { return first_hole ; }inline BM_BENDLINE *get_b
endline_list(void) const { return first_bendline ;
}inline BM_FORMING *get_forming_list(void) const
{ return first_forming ; }// To get the number of
bendproperties and the first property object on th
e list.inline BM_BEND_PROPERTY *get_list_of_bend_p
roperties(void) const { return list_of_bend_proper
ties ; }inline long get_number_of_bend_properties
(void) const { return number_of_bend_properties ;
}// this function tries to find a good default ba
se face.// it chooses a face that has the largest
bbox.BM_FACE *get_default_base_face(void) ;/*部分
に係わる距離公差を獲得し変化させる関数*/inline dou
ble get_distance_tolerance(void) const { return di
stance_tolerance ; }void set_distance_tolerance(do
uble new_distance_tolerance) ;/*この部分の現在のメ
タル厚さを得る。*/inline double get_metal_thicknes
s(void) const { return metal_thickness ; }/*厚さを
変えると、部分に多くの変化が生じる。面は、厚さを変
えるとベンドラインも変化し易くなるので、若干のトリ
ミングを必要とする。更に、面の2D->3D変換は最も変化
し易い。これは、ベンドラインの3D形状が変化するであ
ろうため生じ、またフラットは中性-ラインデイメンシ
ヨンを表すので、部分の3Dデイメンシヨンは最も変化し
易くなる。ベンドラインは大きく変化することは殆ど確
かである。全てのベンドラインのW3Dは再計算されなけ
ればならない。また、2D->3D変換も再計算されなければ
ならない。部分自体は、厚さを変えた結果としてスペー
ス内を移動しないことに注意されたい。しかし、ベンド
ライン2D->3D変換は’not-up-to-date’としてマークさ
れる。それらを更新する1つの方法は、任意の面をベー
ス-面として取り、その部分をリ-フォールドすることに
より与えられる(これは、その最新の2D->3D 変換を持
つ場合にのみ行われる)。部分は同じ場所に滞在し(ベ
ース-面は適切に滞在するので)、またベンドラインは
それらの更新された2D->3D 変換を持つ。厚さを変える
ことは、部分における全てのボデイは2D->3D 変換を持
ち易く、また無効にされた3Dバージヨンを持ち易いので
実際にはトリッキーである。問題は、ユーザが通常は部
分をリ-フォルドすることを望まないということであ
る。従って、われわれは、如何に新しい有効な2D->3D
変換を自動的に得るかを検討しなければならない。この
関数はそれをなさない点に注意されたい。これは、或る
他の関数によりなされなければならない事態である。こ
の関数は、faces-bendlinesを正確に一致させようとは
しない。それを実現するには、この関数の後match_all_
faces_adjacent_to_bendlines(...)をコールせよ。更
に、新しい厚さを設定し、次に隣接面を一致させると共
に新しい最新の2D->3D変換を計算するset_metal_thickn
ess_update_part(...)を用いよ。*/void set_metal_thi
ckness(doublethickness) ;void set_metal_thickness_
update_part(double thickness) ;/*この関数は、3Dス
ペースにおいてそれらがそれらに隣接するベンドライン
に正確に触れるように全ての面をトリムする(必要に応
じて)。この関数は、厚さが変化した後にまたはベンド
ラインパラメータが変化した後にコールするのによい。
*/void match_all_faces_adjacent_to_bendlines(void)
;/*3Dボデイ(面、孔、フォーミングまたはベンドライ
ン)を部分に付加する。付加出来ないときはFALSEを戻
す。この関数は、基本的にはトポロジーのadd_body() m
ember関数をコールする。*/int add_3d_body(BM_3D_BOD
Y *body) ;// get part topologyinline BM_TOPOLOGY *
get_topology(void) const { return (BM_TOPOLOGY *)
&topology ;}/*これらの関数は、ユーザが、ベンドライ
ンにおける部分デイメンシヨンが可能なときは常に一定
に保たれるべきか否かを照会し、特定することを許容す
る。*/// to get the current statusinline int get_b
endline_dimensions_status(void) const { return ben
dline_dimensions_status ; }// to set the new statu
s.// for example, if we set it to TRUE, then from
this point on, BMAPI// will try to keep to current
part dimensions constant.void set_bendline_dimens
ions_status(int new_bendline_dimensions_status) ;/
*ベンドシーケンス関係関数*/void delete_bend_sequen
ce(void) ;inline long get_bend_sequence_size(void)
const { return bend_sequence_size ; }// this func
tion returns the number of bendlines copied into O
UT arrayint get_bend_sequence(BM_BENDLINE *bendlin
es[], long bendlines_array_length) ;// this functi
on sets a new bend sequence for this bendlineint s
et_bend_sequence(BM_BENDLINE **bendlines, long ben
dlines_array_length) ;// this function checksis a
bendline is in the current bend sequence of the pa
rt.// if yes, itreturns its index in the bend sequ
ence (ie. the number of this bendline// in the ben
d sequence order). This index is from 0 through se
quence_lenght - 1.// if this bendline is not in th
e bend sequence, it returns -1.int is_bendline_in_
bend_sequence(BM_BENDLINE *bendline) ;// this func
tion removes a bendline from the bend sequence.//
note that if the bendlineis in a simultaneous bend
property, it will replace the bendline// withanot
her bendline from the simultaneous bend property t
hat is not already in the bend sequence.void remov
e_bendline_from_bend_sequence(BM_BENDLINE *bendlin
e) ;// this function deletes the current bend sequ
ence (if one exists) and creates a default // bend
sequence.void create_default_bend_sequence(void)
;/*この関数は、孔を含まない全てのベンドラインのフ
ラットバージヨンを排除する。この関数は、部分がアン
フォルドされた後有用になり得る。通常は、部分のフォ
ルドされたバージヨンはトリビアルでないベンドライン
(すなわち、0でないインサイド半径および/または厚
さ)を含む。部分がアンフォルドされたとき、BMAPIは
これらのベンドラインを、それらが有るように正確にフ
ラットバージヨンに変換する。たとえば、ゼロ以外の厚
みまたは半径を有するベンドラインの3D-バージョンに
は通常、曲がった弧が描かれる。これは平面バージョン
のベンドラインにマッピングされる。これはパートの平
面バージョンにおいて、ベンドラインに対応する2つの
面の間に長方形が存在することを意味する。ただし我々
は、この矩形を見たくないときがある。この関数は、単
純な平面(つまり平面に穴がない)を有し、2つの面に
正確に隣接するベンドラインだけを処理する。 この関
数は、隣接するすべての面を切り取って(トリミン
グ)、ベンドラインの中心線に接触させ、ベンドライン
平面におけるすべての輪(ループ)を削除する。この関
数は通常UNFOLDの直後に使われることに注意せよ。いっ
たん平面がトリミングされると、それは隣接する面にも
適合する。これは、この関数がいくつかの特殊なトリミ
ング値を計算および設定し、後ほど我々がパートをたた
む(フォルドする)ときに、面がベンドラインに正確に
接する正しい3D-バージョンを得ることを意味する。こ
の関数はベンドラインを変えない。*/void eliminate_s
imple_bendlines_in_flat_version_A(void) ;/*この関
数は、パートにおけるすべての3D-ボディを走査して
(フォーミングを除く)、それらの平面バージョンを整
える。基本的にこの関数は、パートにおけるすべての3D
_body(フォーミングを除く)に対してBM_2D_BODY::fix
_flat()関数を呼び出す。この関数は現行の平面バージ
ョンのみをチェックするので注意せよ。この関数は、何
らかの操作が失敗するか(つまりメモリー割り当て)、
またはこの関数が解決できない問題を発見したときにFA
ILUREを返す。*/int fix_flat(void) ;/*この関数は、
フェース・ノーマル(face normal)がベンドラインの
定義に合致していることをチェックする。たとえば、fa
ce1が法線を持ち(0,0,1)、face1とface2との間に90度の
FRONTベンドがある場合、face2の法線は(-1,0,0)になら
なければならない。本来とは逆の法線がある場合、この
関数はそれを整える。さもなくば、この関数は問題を見
つけるとFAILUREを返す。入力面が与えられる場合、こ
の関数はその面の中心に位置する接続されたコンポーネ
ントだけをチェックする。さもなくば、この関数はパー
ト全体をチェックする。この場合、この関数が面をチェ
ックする順番は、面インデックスの順番である。この関
数は必要なチェックをいくつか行なう(たとえば、ベン
ドラインが曲げられるとき、それはbend op, a3D-バー
ジョン(それは空のこともある)およびサーフェスを持
たなければならない)。この関数は、すべての面および
ベンドラインの3D-バージョンが最新のものであるか否
かをチェックする。いずれかが最新のものでない場合に
は、この関数はFAILUREを返す。この関数は、現行バー
ジョンが最新であるか否かをチェックするだけであり、
現行バージョンが最新でない場合は、新しい3D-バージ
ョンを計算しない(この関数は通常展開(アンフォル
ド)の後に使われるので、この時点では何も計算したく
ない)。この関数は穴とフォーミング(formings)を無
視する。In 3D_FUNC.CPP.*/int fix_3D_face_normals(B
M_FACE *given_base_face = NULL) ;/*この関数は、パ
ートにおける3D-ボディをチェックし、これが見つける
問題を解決する。この関数は現行の3D-バージョンのみ
をチェックするので注意せよ。さらにこの関数は、何も
のをも無効にしない。只今この関数は:フェース・ノー
マル(face normal)がベンドラインの定義に合致して
いることをチェックする。たとえば、face1が法線を持
ち(0,0,1)、face1とface2との間に90度のFRONTベンドが
ある場合、face2の法線は(-1,0,0)にならなければなら
ない。この関数は、何らかの操作が失敗するか(つまり
メモリー割り当て)、またはこの関数が解決できない問
題を発見したときにFAILUREを返す。In 3D_FUNC.CPP.*/
int fix_3D(void) ;/*********** ********** ********
** ********** ********** ********** ********** ***
******* **********これは、パートの設計および建造に
用いる主要な高水準Bend Model機能である。その用途は
次の通りである:-パートが結合されるように(可能であ
る場合)、面と面との間にベンドラインを作る。この関
数は、パート制作を合理化するために作られた。通常は
パートを描くのにサードパーティのCADプログラムが使
われる。Bend ModelはCADシステムをコントロールしな
いので、我々の目的にとってこの描画(ドローイング)
は単なるエッジの集合である。このため、パートの構造
を見つけるには、ドローイングを分析しなければならな
い。その後に我々は、パートのベンドラインと面を作る
ことができる。ただし、この入力ドローイングはしばし
ば曖昧である。つまり、面、そして特にベンドラインは
一意に定義されていない。このことが多くのアプリケー
ションに共通する問題であるため、この関数がBend Mod
elの一部になっている。さらに、Bend Modelにこの関数
を実装することにより、CADシステムの一部を形成する
面検出ソフトウェアを簡略化する。この関数において我
々は、面のエッジが、プレーン・ノーマル(平面の方向
を定義する)と調和する方法で、左側の罫線(ルール)
に従って揃えられることを想定する。基本的に、この関
数は、各平面を分離して見た場合にすべての平面がそれ
自体で適正であることを想定する。ただしこの関数は、
隣接平面の向きが、それらの間にあるベンドラインに対
して適正であることを要求しない。この関数は、パート
の厚さがゼロ以外の場合に、恐らく良好に機能しない。
この関数は、パートの3D-バージョンとパートの平面バ
ージョンの両方についてベンドラインを生成するのに使
える。ただしパートは、パートの平面バージョンかまた
は3Dバージョンのいずれかを持つことができ、その両方
を持つことはできない。すなわち、3D-ボディのすべて
の3D-バージョンがNULLであるか(この場合我々は平面
バージョンを得る)、またはすべての平面バージョンが
NULLでなければならない。Implementation is in AUTO_
BEND.CPP.*/int auto_bend(void) ;/*この関数は、CAD
システムによってBend Modelに送信されたデータからパ
ートを制作することを促進するために設計された。問題
は、情報を利用できるようにするため、しばしばパート
が部分ごとに建造されることである。ただし問題は、我
々がパートのボディを建造するとき、入力データがパー
トの平面バージョン(FLAT)と3Dバージョンのいずれを
表わしているのかを事前に知ることができないことであ
る。通常それは3D_versionである。このため我々はデフ
ォルトで、それが3Dバージョンであると想定する。後ほ
ど、パートの3D-ボディのすべてが建造された時点で、
我々は入力データが3D-バージョンであることをチェッ
クできる。もしも3D-バージョンでなければ、我々はす
べての3D-バージョンを平面バージョンに移さなければ
ならない。この関数は、この目的のためにのみ設計され
ており、他のいかなる目的にも使用するべきでない。こ
の関数の誤用は、システムをクラッシュする。この関数
はまず初めに、ボディの平面バージョン(FLAT)がNULL
であるか否かをチェックする。これがNULLでない場合、
この関数は3D-バージョンを移さない。 TODO : right n
ow, it only moves faces.*/void BM_PART::move_3D_to
_flat(void) ;/*********** ******************** ***
******* ********** ********** ********** *********
* **********Bend Modelは、パート操作を両方の方向で
処理できる。:-パートの3Dバージョンの場合、パートの
2D(平面)バージョンを見つける。-2D(平面)バージ
ョンの場合、それを所定の屈曲パラメータでフォルドす
る。BMAPIはほとんどの場合、2つのバージョン(2Dお
よび3D)のパートを有するので、それらの一貫性を維持
することが重要である。BMAPIは通常、効率性の理由か
ら、パートの2Dバージョンと3Dバージョンを明示的には
計算せず、かわりに要求に応じて(ユーザーが計算を要
求するときのみ)それらを計算する。ほとんどの場合我
々は、ある所定のボディのバージョンから別のボディの
バージョンが作られる変形(トランスフォーメーショ
ン)を知るだけで十分である。2D->3D変形と3D->2D変形
との間には1つの違いがある。通常2D->3D変形はユーザ
ーによって指定され、ユーザーは任意の方法でそれを実
施できる(何らかの理由により結果が不正になることが
あるが、とりあえず当面はそのことを無視する)。3D->
2D変形はアンフォルドに対応し、これには1つの方法だ
けがある。つまり、所定の固定された3D-バージョンに
ついて、最終的なパートの平面バージョンが1つだけ存
在する。フォルドとアンフォルドはいずれも、パートの
屈曲情報を用いて、すべての3Dボディを各々の屈曲パラ
メータに従って個別に計算する。一般に、これらの変形
では、パート内のすべてのボディが’flat’バージョン
かまたは’3D-version’を有することが要求される。つ
まり、当初3Dバージョンのパートがある場合、2D->3D変
形を使用する前に、それをアンフォルドしなければなら
ない。アンフォルドは’flat’を作り出す。フォルド
は’3D-version’を作り出す。ユーザーは最初に、フラ
ット・バージョンか3D-バージョンのいずれかを指定し
なければならない。********** ********** **********
********** ********** ********** ****************
**** ***********//*この関数は、BMAPIに(フラットか
ら)パートの3Dバージョンを強制的に計算させる。具体
的にBMAPIは、面−穴−ベンドラインのすべてをチェッ
クし、3Dバージョンが新しくなければ、BMAPIは2D->3D
変形を用いてフラットから最新の3Dバージョンを計算す
る。2D->3D変形が新しくない場合、BMAPIは最新の有効
な2D->3D変形の計算を試みる。また、あるベンドライン
について新しい3D-バージョンが計算されるとき、BMAPI
は初めに隣接するベンドラインを適合させる。*/void b
ring_3D_up_to_date(void) ;/*********** **********
********** ********** ********** ********** ******
**** ********** **********2D->3D変形関数**********
********** ********** ********** ********** *****
***** ********** ********** ***********//*この関数
はすべての変形をアイデンティティ変形(identity tra
nsformation)にリセットする。さらにこの関数は、す
べてのベンドラインにおける’bending_status’変数を
FALSEに設定する。さらにこの関数は、すべての面のす
べての3Dバージョンを’not-up-to-date’(非最新)と
記すが、ただしその再計算は行なわない。3D->2D変形は
リセットできないので、この関数が2D->3D変形のみをリ
セットすることに注意せよ。*/void reset_all_transfo
rmations(void) ;/*パートの2D->3D変形をリセットす
る。’body’は、アイデンティティ変形になる変形を持
つ面である。他のボディは、この基本ボディ(ベース・
ボディ)に関する屈曲情報に従って、各々の変形を設定
する。この関数は、すべての変形母体(マトリックス)
を更新する。基本的にこの関数では、ユーザーがパート
全体に行なった回転や移動のすべてを取り消し(アンド
ゥー)できる。*/void reset_part_2Dto3D_transformat
ions(BM_3D_BODY *base_body) ;/*********** ********
** ********** ********** ********** ********** ***
******* ********** **********これらの関数は、ユー
ザーにパートの回転または移動を実施させる。たとえ
ば、屈曲のとき、ユーザーはパートの反転を希望するこ
とがある。これらの関数は、パート全体に均一に作用す
る。すなわち、すべての面−穴−ベンドラインが全く同
様に変化する。これらの関数が2D->3D変形であることに
注意せよ。すなわち、これらの関数はパートの3Dバージ
ョンだけを変更するが、これらの関数はパートの平面バ
ージョンの計算を要する。基本的にこれらの関数が実施
する唯一のことは、すべてのボディに付随する2D-3D変
形を変更し、すべてのボディの3D-バージョンを’not-u
p-to-date’(非最新)と記すことである。**********
********** ********** ********** ********** ******
**** ********** ********** ***********//*パート全
体を線を軸に一定の角度(ラジアン単位)で回転させ
る。正の方向は、線の方向を見たときの時計回りであ
る。*/void rotate(BM_LINE const& line, double cons
tangle) ;/*パート全体をこのベクトルで移動する*/voi
d translate(BM_VECTOR const& translation_vector) ;
/*この変形をパートに適用する*/void transform(BM_TR
ANSFORM const& transformation) ;/*********** *****
***** ******************** ********** ********** *
********* ********** **********FOLD関数。FOLD.CPP
モジュール内********** ********** ********** *****
***** ********** ********** ********** **********
***********//*パートの3Dバージョンを計算する。この
関数は、ベース・ボディに従ってパートの3Dバージョン
を計算する。つまり、’base_body’は留まり、パート
の残りの部分は動く。これまでパート全体に回転や移動
を実行した場合、回転または移動はこの操作の後にも有
効であるので注意せよ。通常ユーザーは、いくつかのベ
ンドライン・パラメータを設定してから、この関数を呼
び出してパートを更新することを希望する。この関数
は、変化する(最小限度の変化)ボディの変形母体だけ
を計算する。各ボディの3Dバージョンは要求に応じて
(ユーザーが計算を要求するときのみ)計算される。こ
の関数は、各ベンドラインのメンバ変数’bending_stat
us’を用いて、ベンドラインを屈曲するか否かを決め
る。ベース-ボディの2D->3D変形が新しくない場合、FOL
Dはそれをアイデンティティ変形にリセットするので注
意せよ。*/int fold(BM_3D_BODY *base_body) ;/*この
関数は、各ベンドラインのメンバ変数’bending_statu
s’がFALSEであると想定し(FALSEでない場合は、この
関数が’bending_status’をFALSEに設定する)、さら
に屈曲するベンドラインのリストが配列’bendline_arr
ay’にあると想定する(配列の長さは’number_of_bend
lines’)ことを除き、同じことを実行する。この関数
が終るときに、各ベンドラインのメンバ変数’bending_
status’は、ベンドラインが屈曲されたか否かを表示す
る。*/int fold(BM_3D_BODY *base_body, BM_BENDLINE
*bendline_array[], long number_of_bendlines) ;/*こ
の関数は、パートの屈曲順位における最初のnベンドラ
インをフォルドする。*/int fold_sequence(BM_3D_BODY
*base_body, int n) ;/*3Dボディがすでにその2D->3D
変形母体を計算している場合、この関数は所定のベンド
ラインについて変形母体を計算する。この関数は数々の
事柄を想定する(これらの事柄はチェックされない):-
このベンドラインはボディに隣接している。-このボデ
ィはすでに最新の変形母体を有する。-このベンドライ
ンは最新のcenter_line_2Dを有する。これら2つの関数
では、ベンドラインが2D中心線を有することが要求され
るので注意せよ。これはまた、ベンドラインに平面があ
ることをも意味する。性能上の理由から、これらの関数
はベンドラインにおける平面の有無をチェックせず、か
わりにベンドラインに平面があるものと想定し、それを
直接的に参照する。この関数はFOLDによって使われる。
*/int bend_bendline_wrt_3D_body(BM_3D_BODY *body /
* finished body */, BM_BENDLINE*current_bendline /
* bendline whose transformation we are computing *
/,BM_TRANSFORM *tf /* start with this transformati
on */) ;/*ベンドラインがすでに完成しており、我々が
3Dボディを計算していることを除き、同じ。This funct
ion is used by FOLD.*/int bend_3D_body_wrt_bendlin
e(BM_BENDLINE *current_bendline /* finished bendli
ne */, BM_3D_BODY *body /* body whose transformati
on we are computing */, BM_TRANSFORM *tf /* start
with this transformation */) ;/*********** *******
*** ********** ********** ********** ********** **
******** ********** **********UNFOLD関数。UNFOLD.C
PPモジュール内********** ********** ********** ***
******* ********** ********** ********** *********
* ***********//*この関数はパート全体をアンフォルド
する。この関数は、接続されたパートの各コンポーネン
トにつき、デフォルトのベース・ボディを選択する。こ
の関数は、パートがアンフォルドされるときに、ベース
・ボディが原点(0,0,0)に重なるようにパートをX-Y平面
に移動させる。この関数は最初に各3Dボディについて3D
->2D変形を計算し、それから各3D-ボディについてWflat
を計算し、次にWflatをトリミングし、最後に平面を計
算する。この関数は、ベース-ボディとして非-NULLの法
線を持ち、最小idを持つ面を選択する。これが不可能で
ある場合、この関数は、ベース-ボディとして非-NULLの
法線を計算することができる基礎のサーフェスを有する
最初のベンドラインを選択する。この関数は、BM_PAR
T::unfold(BM_3D_BODY *base_body)を用いて、パートの
接続されたコンポーネントのすべてをアンフォルドす
る。この関数は、全面的に成功した場合に1を返し、パ
ートの一部でアンフォルドに失敗した場合には0を返
す。この関数はまず初めに、すべてのフェース・ノーマ
ルが現行のベンドラインに対して適正であることをチェ
ックする。この関数は、各3D-ボディの現行3D-バージョ
ンを使用することに注意せよ。アンフォルドを行なうに
は、すべての3D-バージョンが新しくなっていなければ
ならない。この関数は3Dボディが新しいか否かをチェッ
クせず、実際にはすべての3D-ボディを最新と記す。さ
らにこの関数は、すべてのベンドラインが有効な3D-中
心線を持っていると想定する。ここでもこの関数は3D-
中心線をチェックせず、かわりに現行の中心線をただ単
に批准する。*/int unfold(void) ;/*この関数は、ベー
ス-ボディの周囲を中心とするパートの接続コンポーネ
ントだけをアンフォルドする。この関数は、パート全体
をアンフォルドするBM_PART::unfold(void)関数によっ
て使われる。この関数は、接続コンポーネントの各3D-
ボディについて新しい3D->2D変形を計算し、次にBM_3D_
BODY::compute_flat_from_3D()関数を用いて各3D-ボデ
ィについて新しい平面バージョンを計算する。ベース・
ボディが面であり、入力フラグがTRUEに設定されている
場合、この関数が最初に実行することは、すべてのフェ
ース・ノーマルが現行のベンドラインに対して適正であ
ることをチェックすることである。ただしこれは、その
ベース・ボディ(面)を中心とする接続コンポーネント
に限られる。この関数は各3D-ボディの現行3D-バージョ
ンを使用するので注意せよ。この関数を呼び出す前に、
すべての3D-バージョンが最新であることを確認せよ。
この関数は実際、それが処理するすべての3D-ボディを
最新と記す。*/int unfold(BM_3D_BODY *base_body, in
t check_face_normals = 0) ;/*3Dボディの3D->2D変形
母体がすでに計算済みの場合、この関数は所定のベンド
ラインについて変形母体を計算する。この関数は数々の
事柄を想定する(これらの事柄はチェックされない):-
このベンドラインはボディに隣接している。-このボデ
ィはすでに最新の変形母体を有する。-このベンドライ
ンは最新のcenter_line_3Dを有する。これら2つの関数
では、ベンドラインが中心線を有することが要求される
ので注意せよ。これはまた、ベンドラインが非-NULLの3
D-バージョンであることをも意味する。性能上の理由か
ら、これらの関数はベンドラインが非-NULLの3D-バージ
ョンであることをチェックせず、かわりにベンドライン
が非-NULLの3D-バージョンであるものと想定し、それを
直接的に参照する。この関数はUNFOLDによって使われ
る。この関数は実際にはbend_bendline_wrt_3D_bod
y(...)の逆であることに注意せよ。*/int unfold_bendl
ine_wrt_3D_body(BM_3D_BODY *body /* finished body
*/, BM_BENDLINE *current_bendline /* bendline whos
e transformation we are computing */, BM_TRANSFORM
*tf /* start with this transformation */) ;/*ベン
ドラインがすでに完成しており、我々が3Dボディを計算
していることを除き、同じ。この関数はUNFOLDによって
使われる。この関数は実際にはbend_3D_body_wrt_bendl
ine(...)の逆であることに注意せよ。*/int unfold_3D_
body_wrt_bendline(BM_BENDLINE *current_bendline /*
bendline終了*/, BM_3D_BODY *body /* 我々が変形を
計算しているところのボディ */, BM_TRANSFORM *tf /*
この変形から開始する */) ;/*********** **********
********** ********** ********** ********** *****
***** ********** **********この関数は"paper model
of this part"(このパートのペーパー・モデル)を返
す。ペーパー・モデルとは、厚みが0であり、ベンドラ
インの半径と屈曲控除も0であるパートである。必要に
応じこの関数は、ベンドラインのユーザ-id’から’内
部半径’と’屈曲控除’をマッピングした結果を返す。
********** ********** ********** ********** ******
**** ********** ********** ********** ***********/
BM_PART *make_paper_model(double **inside_radius /
* OUT */, double **bend_deduction /* OUT */) ;/*こ
の関数は、現行のパートを所定のファイルにPGF形式で
保存する。PGF形式はCMUのBendCADプログラムによって
使われる。戻り値:万事良好でパートが保存された場合
にTRUEを返す。*/int save_PGF_file(FILE *file) ;int
save_PGF_file(char *filename) ;/*ロード関数はPART
_LOAD_x.CPPにある。*/virtual int load(FILE *file)
;virtual int load(char *filename/* must not be NU
LL */) ;int BM_PART_Load(FILE *file, long version)
;/*保存関数はPART_SAVE.CPPにある。*/virtual int s
ave(FILE *file) ;virtual int save(char *filename /
* must not be NULL */) ;} ;#endif // BM_PART_HXX_I
NCLUDED 付録L 3次元操作および回転軸の動的計算によるナビゲーショ
ンの例 void CBendCADViewPart::OnLButtonUp(UINT nFlags, CP
oint point) {::ReleaseCapture();::ClipCursor(NUL
L);// Release mouse, free cursor.m_lt_btn_up_point
= point;double x_extent, y_extent;int add_hit_to_
list = 0;int viewport[4];BM_VECTOR offset;BM_PART
*part = GetDocument()->get_part();RwV3dvert;switch
(ml_last_function_chosen){ case(ZOOM_WINDOW_MOD
E):if(mi_dynamic_rot_center_on) {// User has furth
er zoomed in. compute_non_dyn_equivalent();RwIdent
ityMatrix(md_dyn_rot_matrix);}compute_zoom_region_
translation();x_extent = fabs((double)(m_lt_btn_do
wn_point.x - m_lt_btn_up_point.x))* 2.0*md_cu
rrent_view_vol[0]/(double)(m_old_rect.right);y_ext
ent = fabs((double)(m_lt_btn_down_point.y - m_lt_b
tn_up_point.y))* 2.0*md_current_view_vol[1]/
(double)(m_old_rect.bottom);set_new_view_volume(x_
extent, y_extent); compute_part_bbox(part, mi_s
how_3d, md_rot_matrix, m_part_centroid, md_part_bb
ox_size, &offset); mi_bbox_is_up_to_date = 0;//
Even though bbox computed, we mark as not up to da
te so that zoom-allDrawPart(m_hdc);// will work co
rrectly.// Now turn on dynamic rotation center if
need be.if( (md_part_bbox_size[0] >2.2*md_curr
ent_view_vol[0]) || // User has zoomed in so that
not all (md_part_bbox_size[1] > 2.2*md_current
_view_vol[1]) ) { // of the part is in view volum
e.if(! md_dyn_rot_matrix) md_dyn_rot_matrix = RwCr
eateMatrix(); if(mi_show_solid) {// Pick the cen
ter of the screen to find point on clump to rotate
around.if(RwPickScene(m_scene, m_old_rect.right/
2, m_old_rect.bottom/2, m_camera, &m_pick)) {if(m_
pick.type == rwNAPICKOBJECT) {// No clump was pick
ed. m_dynamic_rot_center = BM_POINT(0.0, 0.0,
0.0);}else if(m_pick.type == rwPICKCLUMP) {
// Some clump was picked; process it.ve
rt = m_pick.object.clump.wcpoint;m_dynamic_rot_cen
ter = BM_POINT(vert.x, vert.y, vert.z);}}}else {
m_dynamic_rot_center = BM_POINT(0.0, 0.0, 0.0);}mi
_dynamic_rot_center_on =1;}else {compute_non_dyn_e
quivalent();if(md_dyn_rot_matrix) RwDestroyMatrix
(md_dyn_rot_matrix);md_dyn_rot_matrix = NULL; mi_
dynamic_rot_center_on = 0;} break; case(SELECT_O
BJECTS_MODE): if(nFlags & MK_CONTROL)add_hit_to
_list = 1;if(! mi_show_solid) { // Wireframe be
ing displayed, which means OpenGL picking.glGetInt
egerv(GL_VIEWPORT, viewport);glMatrixMode(GL_PROJE
CTION);glPushMatrix();glLoadIdentity();gluPickMatr
ix((double)point.x, (double)(m_old_rect.bottom - p
oint.y), 3.0, 3.0, viewport);glOrtho(- md_current_
view_vol[0], md_current_view_vol[0],- md_current_v
iew_vol[1], md_current_view_vol[1],- md_current_vi
ew_vol[2], md_current_view_vol[2]);glMatrixMode(GL
_MODELVIEW);DrawPart(m_hdc); // Draw the part in
selection mode.glMatrixMode(GL_PROJECTION);glPopM
atrix();glMatrixMode(GL_MODELVIEW);process_hits_re
cord(add_hit_to_list);ml_last_function_chosen = NO
_FUNCTION_MODE;DrawPart(m_hdc); reset_selection_bu
ffer();}else { // Solid being shown, so RenderWare
picking.if(RwPickScene(m_scene,point.x, point.y,
m_camera, &m_pick)) process_hits_record(add_hit_
to_list);ml_last_function_chosen = NO_FUNCTION_MOD
E;DrawPart(m_hdc); }break;case(ZOOM_IN_OUT_MODE):
compute_part_bbox(part, mi_show_3d, md_rot_mat
rix, m_part_centroid, md_part_bbox_size, &offset);
mi_bbox_is_up_to_date = 0;if(mi_dynamic_rot_cen
ter_on) {// User has furtherzoomed in. compute_non
_dyn_equivalent();RwIdentityMatrix(md_dyn_rot_matr
ix);}// Now turn on dynamic rotation center if nee
d be.if( (md_part_bbox_size[0] > 2.2*md_current_vi
ew_vol[0]) || // User has zoomed in so thatnot al
l (md_part_bbox_size[1] > 2.2*md_current_view_v
ol[1]) ) { // of the part is in view volume.mi_bbo
x_is_up_to_date = 0;// Even though bbox computed,
we mark as not up to date so that zoom-allif(! md_
dyn_rot_matrix) md_dyn_rot_matrix = RwCreateMatrix
(); // will work correctly.if(mi_show_solid) {//
Pick the center of the screen to find point on cl
umpto rotate around.if(RwPickScene(m_scene, m_old_
rect.right/2, m_old_rect.bottom/2, m_camera, &m_pi
ck)) {if(m_pick.type == rwNAPICKOBJECT) {// No clu
mp was picked. m_dynamic_rot_center = BM_POIN
T(0.0, 0.0, 0.0);}else if(m_pick.type == rwPICKCLU
MP) {// Some clump was picked; process it.vert = m
_pick.object.clump.wcpoint; m_dynamic_rot_cen
ter = BM_POINT(vert.x, vert.y, vert.z);}}}else {m_
dynamic_rot_center = BM_POINT(0.0, 0.0, 0.0);}mi_d
ynamic_rot_center_on = 1;}else {if(mi_dynamic_rot_
center_on) {compute_non_dyn_equivalent();if(md_dyn
_rot_matrix) RwDestroyMatrix(md_dyn_rot_matrix);md
_dyn_rot_matrix = NULL;mi_dynamic_rot_center_on =
0;}}break; default: break;};ml_last_function_chos
en = NO_FUNCTION_MODE;CBendCADView::OnLButtonUp(nF
lags,point);}
【図面の簡単な説明】
【図1】この発明の実施例に基づいて構成された、進歩
的板金製造設備のブロックダイヤグラム図である。
【図2】この発明の他の実施例に基づいて構成された進
歩的板金製造設備のブロックダイヤグラム図である。
【図3】この発明の1つの側面による、サーバモジュー
ル、データベース及びステーションモジュールの間のそ
れぞれのデータの流れを図示する。
【図4】この発明の他の側面による、サーバモジュール
により実行される一般的な工程及び操作のフローチャー
トである。
【図5】この発明の教示による、前記ステーションモジ
ュールの各々により実行される基本的工程及び操作の代
表的フローチャートである。
【図6】この発明の一側面による類似パーツ検索アルゴ
リズム或いは工程の論理フローを説明するフローチャー
トである。
【図7】この発明の一側面による類似パーツ検索アルゴ
リズム或いは工程の論理フローを説明するフローチャー
トである。
【図8】図8(a)、(b)、(c)はこの発明の側面
による、接触した角部を有する4曲げ箱及び開放された
角部を有する4曲げ箱についての特徴抽出操作を説明す
る。
【図9】図9(a)、(b)、(c)及び(d)はこの
発明の側面による、接触した角部を有する4曲げ箱及び
開放された角部を有する4曲げ箱についての特徴抽出操
作を説明する。
【図10】図10(a),(b)及び(c)は、この発
明の他の側面による、4曲げ箱、ブリッジ及び他の4曲
げ箱を有するパーツについての検索キーを特定するため
の特徴関連操作及び工程を説明する。
【図11】図11は、折り曲げアルゴリズムを用いて、
2次元単一図面図から3次元モデルを生成するためにな
される工程及び操作の論理フローを説明するフローチャ
ートである。
【図12】面検出工程のための図面を作成するために行
なわれる自動トリミング機能及びクリーンアップ機能の
例を説明する。
【図13】図13(a)、(b)、(c)は、面検出工
程のための図面を作成するために行なわれる自動トリミ
ング機能及びクリーンアップ機能の例を説明する。
【図14】面検出工程のための図面を作成するために行
なわれる自動トリミング機能及びクリーンアップ機能の
例を説明する。
【図15】図15(a)、(b)、(c)、(d)はこ
の発明の側面による、面検出工程においてなされる種々
の工程及び操作を説明する。
【図16】図16(a)、(b)、(c)、(d)はこ
の発明の側面による、面検出工程においてなされる種々
の工程及び操作を説明する。
【図17】この発明の側面による、面検出工程及び曲げ
線検出工程の実行から最終曲げグラフデータの生成を説
明する。
【図18】この発明の側面による、面検出工程及び曲げ
線検出工程の実行から最終曲げグラフデータの生成を説
明する。
【図19】この発明の教示による、展開アルゴリズム及
び他の工程を用いて最初の3次元図面(厚さを有しな
い)に基づいて2次元モデルを生成するための基本的論
理フローのフローチャートである。
【図20】この発明の側面による、2次元クリーンアッ
プ操作を用いて最初の2次元3面図に基づいて3次元モ
デルを生成するための基本的論理フローのフローチャー
トである。
【図21】この発明の側面による、2次元3面図に対し
て2次元クリーンアップ操作を行なうための工程及び操
作の基本的論理フローのフローチャートである。
【図22】図22(a)及び(b)は、この発明の2次
元クリーンアップ操作により加工される代表的2次元3
面図の図及び側面を説明する。
【図23】図23(a)はこの発明の2次元クリーンア
ップ操作の回転された図の特徴を説明する。図23
(b)はこの発明の側面による、この発明の2次元クリ
ーンアップ操作に関連する標準形態を説明する。
【図24】図24(a)及び(b)は、この発明の教示
による、厚さを有する2次元3面図及び厚さ除去工程を
用いて生成される厚さを有しない簡単化された2次元3
面図を説明する。図24(c)はこの発明の側面によ
る、代表的パーツの横断厚さ線分及び厚さ円弧の図であ
る。
【図25】本発明の側面による、厚さを有する3次元図
面から厚さを有しない3次元モデルを展開するために実
行される種々の工程及び操作の論理フローのフローチャ
ートである。
【図26】例えばオブジェクト指向プログラム技術を通
して本発明を実行する際に、使用される曲げモデルの代
表的データ構造及びアクセスアルゴリズムを説明する。
【図27】この発明の他の側面による、曲げモデルビュ
ーアの構造のブロックダイヤグラムを説明する。
【図28】表示スクリーンへ出力として提供される代表
的ソリッド図ウインドウ表示を説明する。
【図29】表示スクリーンへ出力として提供される代表
的ワイヤフレーム図ウインドウを説明する。
【図30】表示スクリーンへ出力として提供される2次
元平面スクリーン像ウインドウ表示を説明する。
【図31】表示スクリーンへ出力として提供される正射
影図スクリーン像を説明する。
【図32】この発明の自動寸法付けモードにおいて表示
される種々の寸法事項の例を説明する。
【図33】図33(a)、(b)及び(c)は、この発
明の1つの側面による、種々の異なるパーツについてフ
ランジ長さが定義される態様を図示する。
【図34】図34(a)及び(b)は、この発明の他の
側面による、2つの異なるタイプのパーツについて補助
的なフランジ長さを追加することを図示する。
【図35】図35(a)、(b)及び(c)は、この発
明の更に他の側面による、厚さを備えて表示される種々
のパーツについてフランジ長さが指示される態様を図示
する。
【図36】図36(a)及び(b)は、この発明の接線
寸法方法及び交差寸法方法による、鋭角曲げ角度を有す
るパーツのフランジ長さが表示される態様を示す。
【図37】この発明の他の側面による、図形的ユーザイ
ンタフェースの使用により曲げプランが生成されるため
に行なわれる工程及び操作の論理フローのフローチャー
トである。
【図38】曲げ順を生成するために曲げオペレータに対
して表示される曲げ順入力スクリーン像の例を図示す
る。
【図39】図39(a)及び(b)は、この発明の他の
側面による、曲げ順の選択及び挿入方向の修正の例を示
す。
【図40】曲げ順入力スクリーン画像及び関連するスク
リーン表示の更なる例を示す。
【図41】曲げ順入力スクリーン画像及び関連するスク
リーン表示の更なる例を示す。
【図42】この発明の1つの側面による、オペレータが
提案された曲げ順を修正し且つ編集するのを容易にする
ために設けられるドラッグ及びドロップ編集特性を示
す。
【図43】曲げオペレータが工具を選択するのを支援す
るために図形的に表示される種々の表示メニュー及びデ
ータテーブルの例を示す。
【図44】提案された曲げプランにおいて工具のセット
アップを容易にするために曲げオペレータに対して表示
される代表的工具セットアップウインドウを示す。
【図45】張り付けられたアイコンの使用を介して、添
付された音声及び映像情報を有する3次元ソリッド図ウ
インド表示の例を示す。
【図46】この発明の一側面による、格納された音声及
び映像情報を読み出すためのアイコンと共に組み込まれ
た表示ウインドウの他の例を示す。
【図47】この発明の教示に基づいて実行されるイメー
ジ編集ウインドウの例を示す。
【図48】図形的ユーザインタフェースを介して実行さ
れるこの発明の干渉チェック機能の例を示す。
【図49】図形的ユーザインタフェースを介して実行さ
れるこの発明の干渉チェック機能の例を示す。
【図50】図50(a)及び(b)は、例えばジョイス
ティックを用いて3次元幾何学形状の回転及び表示を操
作するための、この発明の操作システムを示す。
【図51】例えばジョイスティック及びズームボタンを
用いて3次元幾何学形状のズーミング及び表示を操作す
るためのこの発明の操作システムを示す。
【図52】例えばジョイスティック及びパンボタンを用
いて、3次元幾何学形状のパンニング及び表示を操作す
るための、この発明の操作システムを示す。
【図53】この発明の3次元ナビゲーション及び操作シ
ステムを実行するために、実行される工程及び操作の代
表的フローチャートである。
【図54】この発明の側面による、ジョイスティック運
動をカーソル運動へ写像する例を示す。
【図55】表示されたパーツの回転軸を動力学的に計算
するためになされる工程及び操作の代表的フローチャー
トである。
【図56】例えばステーションモジュールにおいて設け
られ且つ表示されるメインメニューウインドウ表示の例
を示す。
【図57】ユーザがパーツ情報を入力し且つ修正するこ
とを可能とするように設けられた代表的パーツ情報ウイ
ンドウ表示を示す。
【図58】ユーザが曲げ情報を入力し且つ修正すること
を可能とするように設けられた代表的曲げ線情報ウイン
ドウ表示を示す。
【図59】板金パーツの中間的曲げ段階を観察するため
の、この発明の代表的曲げ順ウインドウ表示を示す。
【図60】板金パーツの中間曲げ段階をシミュレートす
るための、この発明の代表的曲げシミュレーションウイ
ンドウ表示を示す。
【図61】2次元から3次元への変換のためユーザに対
して設けられ且つ表示される、この発明の代表的メニュ
ースクリーン図及び構造である。
【図62】この発明の2次元クリーンアップ操作のため
の代表的メニュースクリーン図及び構造である。
【図63】一端が開放された線分が除去される前のパー
ツの3次元表示の例を示す。
【図64】パーツの2次元3面図からパーツの3次元モ
デルを生成する際に使用されるこの発明の3次元クリー
ンアップ工程による、前記一方が開放された線分が3次
元表示から除去された後のパーツを示す。
【図65】曲げ線が特定される前のパーツの代表的3次
元表現を示す。
【図66】この発明の3次元クリーンアップ工程による
モールド線が追加された後のパーツを示す。
【図67】曲げ線をきれいにし且つ面をトリミングする
前のパーツの代表的部分を示す。
【図68】この発明の3次元クリーンアップ工程による
前記正常化及びトリミングが行なわれた後のパーツの部
分を示す。
フロントページの続き (72)発明者 サトシ サカイ アメリカ合衆国 92657 カリフォルニア 州 ニュ ーポート コースト アヴィグ ノン 9 (72)発明者 アーナンド ハリハラン サバラマン アメリカ合衆国 92707 カリフォルニア 州 サン タ アナ 225 ウエスト ス ティーブンズ アヴェ ニュー 1101

Claims (116)

    【特許請求の範囲】
  1. 【請求項1】 コンピュータ読取可能媒体に格納され、
    且つ、ある設備により製造されるべきパーツを表現する
    ためのオブジェクト指向曲げモデルにして、 前記オブジェクト指向曲げモデルはパーツクラスを有
    し、このパーツクラスは、前記パーツの複数の特徴に関
    連するパーツ情報を有する複数のオブジェクトと、前記
    パーツになされる複数の曲げ動作に関連する曲げ情報
    と、を含む。
  2. 【請求項2】 請求項1のオブジェクト指向曲げモデル
    にして、前記パーツ情報は、パーツデザインおよびパー
    ツ製造情報を含む。
  3. 【請求項3】 請求項2のオブジェクト指向曲げモデル
    にして、前記パーツデザインは、2次元座標空間および
    3次元座標空間における前記パーツの表現に関連する。
  4. 【請求項4】 請求項1のオブジェクト指向曲げモデル
    にして、前記パーツクラスは複数の属性を有し、前記複
    数の属性は、前記曲げ動作が前記パーツに対してなされ
    る順番に関連する曲げシーケンス情報を有する。
  5. 【請求項5】 請求項1のオブジェクト指向曲げモデル
    にして、前記パーツクラスは複数の属性を有し、前記複
    数の属性は、パーツの材質タイプおよびパーツ厚さを含
    む。
  6. 【請求項6】 請求項1のオブジェクト指向曲げモデル
    にして、前記設備において製造される前記パーツは板金
    パーツを含む。
  7. 【請求項7】 請求項1のオブジェクト指向曲げモデル
    にして、前記曲げ情報は、曲げデータを備える一組の対
    象と、前記パーツの曲げ線において曲げ動作を行うため
    の指令を含む。
  8. 【請求項8】 請求項7のオブジェクト指向曲げモデル
    にして、前記曲げデータは、曲げ角度量および曲げ縮小
    量および曲げ半径量を含む。
  9. 【請求項9】 請求項1のオブジェクト指向曲げモデル
    にして、前記複数の対象は面の対象を含み、前記面の対
    象は、前記パーツの各面の寸法に関連するデザインデー
    タと、少なくとも一つの所定の座標空間における前記パ
    ーツの各面の表現に関連する位置データと、を含む。
  10. 【請求項10】 請求項1のオブジェクト指向曲げモデ
    ルにして、前記複数の対象は曲げ線の対象を含み、前記
    曲げ線の対象は、前記パーツの各曲げ線の寸法に関連す
    るデザインデータと少なくとも一つの所定の座標空間内
    における前記パーツの各曲げ線の表現に関連する位置デ
    ータとを含む。
  11. 【請求項11】 請求項10によるオブジェクト指向曲
    げモデルにして、前記曲げ線オブジェクトは更に前記パ
    ーツに対してなされる曲げ作用に関連する曲げ加工デー
    タを有する。
  12. 【請求項12】 請求項11によるオブジェクト指向曲
    げモデルにして、前記曲げ加工データは、前記パーツの
    各曲げ線についての部位幅データ及び曲げピッチデータ
    及び曲げカウントデータを含む。
  13. 【請求項13】 請求項1のオブジェクト指向曲げモデ
    ルにして、前記複数の対象は穴の対象を含み、前記穴の
    対象は、前記パーツにおける少なくとも一つのパーツの
    寸法に関連するデザインデータと、少なくとも一つの所
    定の座標空間内における前記パーツの前記穴の表現に関
    連する位置データとを有する。
  14. 【請求項14】 請求項1のオブジェクト指向曲げモデ
    ルにして、前記複数の対象はフォーミングの対象を含
    み、前記フォーミングの対象は、前記パーツの各フォー
    ミングの寸法に関連するデザインデータと、少なくとも
    一つの所定の座標空間内における前記パーツの前記フォ
    ーミングの表現に関連する位置データとを有する。
  15. 【請求項15】 請求項1のオブジェクト指向曲げモデ
    ルにして、前記複数の対象はトポロジーの対象を含み、
    前記トポロジーの対象は前記パーツの特徴に関連するパ
    ーツ・トポロジーデータを含む。
  16. 【請求項16】 請求項15によるオブジェクト指向曲
    げモデルにして、前記パーツの前記特徴は、前記パーツ
    の少なくとも1つの面または穴または成形部または曲げ
    線を含む。
  17. 【請求項17】 請求項1のオブジェクト指向曲げモデ
    ルにして、前記複数の対象は曲げ特性の対象を含み、前
    記曲げ特性の対象は、前記パーツの少なくとも一つの曲
    げ特性タイプに関連する製造束縛データを含む。
  18. 【請求項18】 請求項17のオブジェクト指向曲げモ
    デルにして、前記曲げ特性タイプは、同時曲げ、共通直
    線曲げ、およびZ曲げの内の一つである。
  19. 【請求項19】 請求項1のオブジェクト指向曲げモデ
    ルにして、前記パーツは板金パーツを含み、前記曲げ動
    作は少なくとも一つの円錐状曲げあるいは円弧状曲げを
    含む。
  20. 【請求項20】 コンピュータにより読み出し可能の媒
    体に格納され、かつ、ある製造設備において製造される
    べき板金パーツを表現するためのオブジェクト指向曲げ
    モデルにして、 前記オブジェクト指向曲げモデルはパーツクラスを含
    み、 前記パーツクラスは、複数のパーツ属性および、2次元
    座標空間および3次元座標空間における前記板金パーツ
    を表現するための複数の対象を有するパーツ対象を含
    む、前記複数の対象は、前記板金パーツの特徴に関連す
    るデザイン情報と、前記板金パーツへの少なくとも一つ
    の曲げ動作を行うための曲げ情報と、を含む。
  21. 【請求項21】 請求項20によるオブジェクト指向曲
    げモデルにして、前記パーツの前記特徴は、少なくとも
    1つの面及び穴及び成形部及び曲げ線を備え、前記複数
    のオブジェクトは、少なくとも1つの面オブジェクト及
    び穴オブジェクト及び成形部オブジェクト及び曲げ線オ
    ブジェクトを備える。
  22. 【請求項22】 請求項19によるオブジェクト指向曲
    げモデルにして、前記複数のオブジェクトは、曲げ特性
    オブジェクトを含み、この曲げ特性オブジェクトは、前
    記板金パーツの少なくとも1つの曲げ特性タイプに関連
    する製造制限データを含む。
  23. 【請求項23】 請求項22によるオブジェクト指向曲
    げモデルにして、前記曲げ特性タイプは、同時曲げ及び
    共線曲げ及びZ曲げの1つを含む。
  24. 【請求項24】 請求項20のオブジェクト指向曲げモ
    デルにして、前記曲げ情報は、前記板金パーツに対して
    成される複数の曲げ操作に関連する。
  25. 【請求項25】 請求項24のオブジェクト指向曲げモ
    デルにして、前記パーツ属性は、前記板金パーツに対し
    て成される曲げ操作の順番に関する曲げシーケンス情報
    からなる。
  26. 【請求項26】 請求項22によるオブジェクト指向曲
    げモデルにして、前記パーツ属性は、パーツ材質タイプ
    及びパーツ厚さを含む。
  27. 【請求項27】 請求項20によるオブジェクト指向曲
    げモデルにして、前記曲げ情報は、曲げデータ及び前記
    板金パーツに対する前記少なくとも1つの曲げ動作を行
    なうための指令を有する一群のオブジェクトを含む。
  28. 【請求項28】 請求項27によるオブジェクト指向曲
    げモデルにして、前記曲げデータは、曲げ角度量及び曲
    げ縮小量及び曲げ半径量を含む。
  29. 【請求項29】 請求項20によるオブジェクト指向曲
    げモデルにして、前記複数のオブジェクトは、面オブジ
    ェクトを備え、前記面オブジェクトは、前記板金パーツ
    の各面の寸法に関連するデザインデータ及び前記2次元
    及び3次元座標空間内での前記板金パーツの各面の表現
    に関連する1データを含む。
  30. 【請求項30】 請求項20によるオブジェクト指向曲
    げモデルにして、前記複数のオブジェクトは曲げ線オブ
    ジェクトを備え、前記曲げ線オブジェクトは、前記板金
    パーツの曲げ線の寸法に関連するデザインデータ及び前
    記2次元及び3次元座標空間内での前記板金パーツの前
    記曲げ線の表現に関連する1データとを含む。
  31. 【請求項31】 請求項30によるオブジェクト指向曲
    げモデルにして、前記曲げ線オブジェクトは更に前記板
    金パーツに対してなされる少なくとも1つの曲げ操作に
    関連する曲げ製造データを含む。
  32. 【請求項32】 請求項31によるオブジェクト指向曲
    げモデルにして、前記曲げ製造データは、前記板金パー
    ツの各曲げ線についての部位幅データ及び曲げピッチデ
    ータ及び曲げカウントデータを含む。
  33. 【請求項33】 請求項20によるオブジェクト指向曲
    げモデルにして、前記複数のオブジェクトは穴オブジェ
    クトを含み、この穴オブジェクトは、前記板金パーツの
    少なくとも1つの穴の寸法に関連するデザインデータと
    前記2次元及び3次元座標空間内での前記板金パーツの
    前記各穴の表現に関連する1データとを含む。
  34. 【請求項34】 請求項20によるオブジェクト指向曲
    げモデルにして、前記複数のオブジェクトは成形部オブ
    ジェクトを含み、この成形部オブジェクトは前記板金パ
    ーツの各成形部の寸法に関連するデザインデータと前記
    2次元及び3次元座標空間内での前記板金パーツの各成
    形部の表現に関連する1データとを含む。
  35. 【請求項35】 請求項20によるオブジェクト指向曲
    げモデルにして、前記複数のオブジェクトはトポロジー
    オブジェクトを含み、このトポロジーオブジェクトは前
    記板金パーツの特徴に関連するパーツトポロジーデータ
    を含む。
  36. 【請求項36】 請求項35によるオブジェクト指向曲
    げモデルにして、前記パーツの特徴は、前記板金パーツ
    の面または穴または成形部または曲げ線の少なくとも1
    つを含む。
  37. 【請求項37】 請求項20によるオブジェクト指向曲
    げモデルにして、前記少なくとも1つの曲げ操作は、円
    錐曲げ或いは円弧状曲げの少なくとも1つを含む。
  38. 【請求項38】 コンピュータ制御システムにおいて使
    用されるように作られたオブジェクト指向曲げモデルビ
    ューアにして、前記コンピュータ制御されるシステム
    は、前記パーツに関連する曲げモデルデータを格納する
    ためのデータベースと、前記パーツの画像を表示するた
    めの表示装置とを備え、 前記オブジェクト指向曲げモデルビューアは、曲げモデ
    ルビューア観察クラスとを備え;曲げモデルビューア観
    察クラスは、観察モデル属性と、前記曲げモデルビュー
    ア観察クラスのメンバー機能として実行される少なくと
    も一つの観察機能を有し;前記パーツの少なくとも一つ
    の画像は、前記曲げモデルデータおよび前記観察モデル
    属性に基づいて前記コンピュータ制御システムの前記表
    示装置に表示される。
  39. 【請求項39】 請求項38のオブジェクト指向曲げモ
    デルビューアにして、 前記観察モデル属性は、所定の観察モードに関連する表
    示情報を備え、前記所定の観察モードは、実線観察モー
    ド・ワイヤフレーム観察モード・2次元平面観察モード
    ・正斜影観察モードの少なくとも一つを含む。
  40. 【請求項40】 請求項38のオブジェクト指向曲げモ
    デルビューアにして、前記曲げモデルビューア観察クラ
    スは、前記少なくとも一つの観察機能に応じて前記パー
    ツの前記画像を変形する情報を更に備える。
  41. 【請求項41】 請求項40のオブジェクト指向曲げモ
    デルビューアにして、前記少なくとも一つの観察機能
    は、ズーム機能、回転機能、パンニング機能、又は寸法
    機能の内の少なくとも一つを有する。
  42. 【請求項42】 請求項41によるオブジェクト指向曲
    げモデルビューアにして前記ズーミング機能は前記パー
    ツの画像のズーミング動作を含む。
  43. 【請求項43】 請求項41によるオブジェクト指向曲
    げモデルビューアにして前記回転機能は前記パーツの画
    像の回転動作を含む。
  44. 【請求項44】 請求項41によるオブジェクト指向曲
    げモデルビューアにして前記タンニング機能は前記パー
    ツの画像のタンニングの動作を含む。
  45. 【請求項45】 請求項41によるオブジェクト指向曲
    げモデルビューアにして前記寸法機能は前記パーツの画
    像を変形し前記パーツの少なくとも1つの特徴に関連す
    る寸法情報を追加的に表示する動作を含む。
  46. 【請求項46】 請求項45によるオブジェクト指向曲
    げモデルビューアにして、前記寸法情報は、前記パーツ
    の少なくとも1つの曲げ線の長さと前記各曲げ線の曲げ
    角度とを含む。
  47. 【請求項47】 請求項45によるオブジェクト指向曲
    げモデルビューアにして前記寸法情報は、前記パーツの
    少なくとも1つのフランジ部の長さを含む。
  48. 【請求項48】 請求項38のオブジェクト指向曲げモ
    デルビューアにして、 前記曲げモデルビューア観察クラスは、前記曲げモデル
    ビューア観察クラスのメンバー機能として提供される複
    数の観察機能を備え、前記曲げモデルビューア観察クラ
    スは更に、前記観察機能の各々に応じて前記パーツの前
    記画像を変形するための情報を備える。
  49. 【請求項49】 請求項48によるオブジェクト指向曲
    げモデルビューアにして、前記撮影機能は、ズーミング
    機能及び回転機能及びタンニング機能及び寸法機能の少
    なくとも1つを含む。
  50. 【請求項50】 請求項38によるオブジェクト指向曲
    げモデルビューアにして、前記表示装置上での前記パー
    ツの前記画像の前記現在表示された図のズームケースに
    関連するズームケース情報を含む。
  51. 【請求項51】 請求項38のオブジェクト指向曲げモ
    デルビューアにして、更に前記パーツの前記画像の現在
    表示されている画面に基づいて、前記表示装置上で観察
    可能な前記パーツの特徴に関連する観察可能情報を提供
    し維持するための観察可能機能を有するもの。
  52. 【請求項52】 請求項51によるオブジェクト指向曲
    げモデルビューアにして、前記曲げモデルビューア画像
    クラスは、前記少なくとも1つの撮影機能に応じて前記
    パーツの画像を変更するための情報を含み、前記少なく
    とも1つの撮影機能は、寸法機能を含み、この寸法機能
    は前記可視性情報に基づき前記パーツの画像を変形し前
    記パーツの観察可能の特徴に関連する寸法情報を表示す
    る操作を含む。
  53. 【請求項53】 パーツの表示画像を操作するためのシ
    ステムにして、 前記表示パーツ画像は3次元空間のスクリーン上に表示
    され、前記システムは以下を備える。指令信号を生成す
    るための入力装置にして、前記指令信号は前記パーツの
    表示された画像を変形するようにされた少なくとも一つ
    の所定の観察機能に関連するもの;前記表示された画像
    の現在の画面を決定するための現在画面決定システム;
    前記表示画像の前記現在画面に基づいて前記パーツの回
    転軸を動力学的に設定するための設定システム;前記指
    令信号および前記回転軸に基づいて、前記パーツの前記
    表示される画像を、前記観察機能に応じて変更するため
    の画像変更システム。
  54. 【請求項54】 請求項53によるシステムにして、前
    記所定の撮影機能は、回転機能を含み、前記画像変形シ
    ステムは、前記指令信号に基づいて前記回転軸を中心と
    して前記パーツの表示された画像を回転するようにされ
    ている。
  55. 【請求項55】 請求項53によるシステムにして、前
    記現在画面決定システムは、前記スクリーン上での前記
    パーツの表示された画像の現在の姿が前記パーツの全体
    の姿であるか或いは部分的な姿であるかを決定するよう
    に構成されている。
  56. 【請求項56】 請求項55によるシステムにして、前
    記設定システムは、前記現在画像決定システムが、前記
    パーツの表示された像の現在の姿は全体の姿であると決
    定する時、前記パーツの回転軸が前記パーツの幾何学的
    中心を通るように設定する。
  57. 【請求項57】 請求項55によるシステムにして、前
    記設定装置は、前記現在画像決定システムが、前記パー
    ツの表示された画像の現在の姿は部分的な姿であると決
    定する時、前記パーツの回転軸が前記スクリーンの中心
    を通るように設定する。
  58. 【請求項58】 請求項57によるシステムにして、そ
    れは更に、前記パーツの一部が前記スクリーンの中心に
    おいて見ることができるか否かを前記現在の画像に基づ
    いて決定するパーツ可視性システムを備え、前記設定シ
    ステムは、前記パーツ可視性システムが前記パーツの一
    部が可視であることを決定する時、前記スクリーンの中
    心における前記パーツの前記一部を前記回転軸が通るよ
    うに設定する。
  59. 【請求項59】 請求項58によるシステムにして、前
    記設定システムは、前記パーツ可視性システムが前記パ
    ーツの前記一部は前記スクリーンの中心において可視で
    はないと決定する時、前記パーツの幾何学的中心のZ座
    標軸上における前記スクリーンの中心を前記回転軸が通
    るように設定する。
  60. 【請求項60】 請求項57によるシステムにして、そ
    れは更に、前記現在画像決定システムが、前記パーツの
    表示された画像の現在の姿は部分的姿であると決定する
    時、前記スクリーンの中心に位置し、且つ前記スクリー
    ンのカメラ視界に最も近い前記パーツの一部を特定する
    ためのシステムと、前記パーツの特定された一部が前記
    パーツの開口部に対応するか否かを決定するためのオブ
    ジェクト検出システムとを備え、前記計算システムは、
    前記オブジェクト検出システムが、前記パーツの特定さ
    れた一部が前記パーツの開口部に対応しないと決定する
    時、前記パーツの特定された一部を前記回転軸が通るよ
    うに設定する。
  61. 【請求項61】 請求項60によるシステムにして、前
    記設定システムは、前記オブジェクト検出システムが、
    前記パーツの特定された一部は前記パーツの開口部に関
    連すると決定する時、前記パーツの幾何学的中心のZ座
    標軸に対応する深さにおいて前記スクリーンの前記中心
    を前記回転軸が通るように設定するように構成されてい
    る。
  62. 【請求項62】 請求項55によるシステムにして、前
    記現在画像決定システムは、画像の体積を、前記パーツ
    の境界基本サイズと比較することにより、前記現在画像
    が前記パーツの全体画像であるか又は部分的画像である
    かを決定するように構成されている。
  63. 【請求項63】 請求項53によるシステムにして、前
    記入力装置はジョイスティック装置を備え、前記指令信
    号は、前記ジョイスティック装置の所定の運動に基づい
    て生成される。
  64. 【請求項64】 請求項63による装置にして、前記ジ
    ョイスティック装置は、ジョイスティック仮想空間を備
    え、前記指令信号は、前記ジョイスティック仮想空間内
    での前記ジョイスティック装置の運動に関連する情報を
    含む。
  65. 【請求項65】 請求項64によるシステムにして、前
    記画像変形システムは、前記ジョイスティック仮想空間
    内での前記ジョイスティック装置の前記運動を前記スク
    リーンのスクリーン空間におけるカーソルの運動に写像
    する写像システムを備えており、前記画像変形システム
    は、前記パーツの表示された画像を、前記ジョイスティ
    ック運動から写像された前記カーソル運動に基づいて変
    形する。
  66. 【請求項66】 請求項65によるシステムにして、前
    記写像システムは、前記ジョイスティック仮想空間の寸
    法に対する前記スクリーン空間の寸法の比率に基づいて
    前記ジョイスティック仮想空間内における前記ジョイス
    ティック装置の運動を前記スクリーン空間におけるカー
    ソルの運動へ写像するように構成されている。
  67. 【請求項67】 請求項66によるシステムにして、前
    記カーソルの運動は次の式に基づいて前記写像システム
    により写像される。 現在位置=従前位置+(スケール係数×V) ここに現在位置は、前記スクリーン空間におけるカーソ
    ルの現在位置であり、従前位置は、前記スクリーン空間
    における前記カーソルの従前の位置であり、スケール係
    数は前記ジョイスティック仮想空間の寸法に対する前記
    スクリーン空間の寸法の比率であり、前記Vは前記ジョ
    イスティック仮想空間におけるジョイスティック原点か
    らジョイスティック現在位置への前記ジョイスティック
    装置の移動量及び方向に関連するベクトルである。
  68. 【請求項68】 請求項67によるシステムにして、前
    記写像システムは、前記写像システムにより使用される
    スケール係数を調整するためのスケール調整システムを
    有し、このスケール調整システムは、前記ジョイスティ
    ック仮想空間の寸法に対する前記スクリーン空間の寸法
    の比率に所定の調整係数を掛け合わせ、調整されたスケ
    ールファクターを提供するように構成されており、前記
    写像システムは、前記ジョイスティック運動を写像する
    にあたって前記調整されたスケール係数を用いるように
    構成されている。
  69. 【請求項69】 請求項68によるシステムにして、前
    記調整ファクターは3の値に設定されている。
  70. 【請求項70】 パーツの表示画像を操作するための方
    法にして、前記パーツの表示画像は3次元座標空間にお
    けるスクリーン上に表示され、前記方法は次の工程から
    なる。入力装置から生成された指令信号を受信し、ここ
    に前記指令信号は、前記パーツの表示される画像を変形
    するように構成された少なくとも一つの所定の観察機能
    に関連する;前記スクリーン上において、前記パーツの
    表示される画像の現在画面を決定する;前記パーツの前
    記現在画面に基づいて前記パーツの回転軸を動力学的に
    設定する;前記指令信号および前記回転軸に基づいて、
    前記パーツの表示される画像を、前記観察機能に応じて
    変形する。
  71. 【請求項71】 請求項70による方法にして、前記所
    定の撮影機能は、回転機能を備え、前記変形操作は前記
    指令信号に基づいて、前記パーツの表示された画像を前
    記回転軸を中心として回転させる工程を含む。
  72. 【請求項72】 請求項53による方法にして、前記決
    定操作は、前記スクリーン上のパーツの表示された画像
    の現在の姿が前記パーツの全体の姿であるか部分的な姿
    であるかを決定する操作を含む。
  73. 【請求項73】 請求項72による方法にして、前記設
    定操作は、前記パーツの表示された画像の現在の姿が全
    体の姿である時、前記回転軸が前記パーツの幾何学的中
    心を通るように設定する操作を含む。
  74. 【請求項74】 請求項72による方法にして、前記設
    定操作は、前記パーツの表示された画像の現在の姿が部
    分的姿であると決定される時、前記パーツの回転軸が前
    記スクリーンの中心を通るように設定する操作を含む。
  75. 【請求項75】 請求項74による方法にして、それは
    更に、前記現在画面に基づいて、前記スクリーンの中心
    に前記パーツの一部が見えるか否かを決定する操作を含
    み、前記設定操作は、前記パーツの前記一部が見えると
    決定される時、前記回転軸が前記スクリーンの中心にお
    ける前記パーツの前記一部を通るように設定する操作を
    含む。
  76. 【請求項76】 請求項75による方法にして、前記設
    定操作は、前記パーツの前記一部が前記スクリーンの中
    心において見えないと決定される時、前記パーツの前記
    幾何学的中心のZ座標軸における前記スクリーンの中心
    を前記回転軸が通るように設定する操作を含む。
  77. 【請求項77】 請求項74による方法にして、それは
    更に、前記パーツの表示された画像の現在の姿が部分的
    な姿である時、前記スクリーンの中心に位置し且つ前記
    スクリーンのカメラ視野に最も近い前記部品の部分を特
    定する操作と、前記パーツの前記特定された部分が前記
    パーツの開口部に対応するかどうかを決定する操作と、
    前記パーツの特定された部分が前記パーツの開口部に関
    連しない時、前記パーツの特定された部分を、前記回転
    軸が通るように設定する操作とを含む。
  78. 【請求項78】 請求項77による方法にして、前記パ
    ーツの前記特定された部分が前記パーツの開口部に関連
    する時、前記パーツの幾何学的中心のZ座標軸に対応す
    る深さにおいて前記スクリーンの中心を前記回転軸が通
    るように設定される。
  79. 【請求項79】 請求項72による方法にして、前記現
    在の姿は、前記スクリーンの画像体積を前記パーツの境
    界基本寸法と比較することにより決定される。
  80. 【請求項80】 請求項70による方法にして、それは
    更に、ジョイスティック装置でもって指令信号を生成す
    る操作を含み、前記指令信号は前記ジョイスティック装
    置の所定の運動に基づいて生成される。
  81. 【請求項81】 請求項80による方法にして、前記ジ
    ョイスティック装置は、ジョイスティック仮想空間を備
    え、前記コマンドシグナルは、前記ジョイスティック仮
    想空間においての前記ジョイスティック装置の運動に関
    連する情報を含む。
  82. 【請求項82】 請求句81による方法にして、前記変
    形操作は、前記ジョイスティック仮想空間における前記
    ジョイスティック装置の前記運動を前記スクリーンのス
    クリーン空間におけるカーソルの運動に写像し前記変形
    操作は、前記ジョイスティック運動から写像された前記
    カーソルの運動に基づいて前記パーツの表示された画像
    を変形する。
  83. 【請求項83】 請求項82による方法にして、前記写
    像操作は、前記ジョイスティック仮想空間の寸法に対す
    る前記スクリーン空間の寸法の比率に基づいて、前記ジ
    ョイスティック仮想空間における前記ジョイスティック
    装置の運動を前記スクリーン空間におけるカーソルの運
    動へ写像する。
  84. 【請求項84】 請求項83による装置にして、前記
    ジョイスティック装置は、ジョイスティック仮想空間を
    備え、前記指令信号は、前記ジョイスティック仮想空間
    内での前記ジョイスティック装置の運動に関連する情報
    を含む。
  85. 【請求項85】 請求項84による方法にして、前記写
    像操作は前記写像により使用されるスケール係数を調整
    することを含み、前記調整操作は、前記ジョイスティッ
    ク仮想空間の寸法に対する前記スクリーン空間の寸法の
    比率に所定の調整係数を掛け合わせ、調整されたスケー
    ル係数を提供し、前記写像操作は、前記ジョイスティッ
    クの運動を写像する際にこの調整されたスケール係数を
    用いる。
  86. 【請求項86】 請求項85による方法にして、前記調
    整係数は3の値にセットされている。
  87. 【請求項87】 請求項85による方法にして、前記調
    整係数は6の値にセットされている。
  88. 【請求項88】 スクリーン上に表示されたパーツの画
    像と共に寸法情報を表示するための方法にして、前記寸
    法情報は前記パーツの特徴に関連し、前記方法は以下を
    含む。前記パーツの前記表示された画像の現在画面を決
    定し、且つ、前記現在画面に基づいて前記スクリーン上
    で前記特徴のうちのどれが観察可能であるかを決定す
    る;前記パーツの前記表示された画像と共に、前記スク
    リーン上で観察可能であると決定された前記パーツの各
    特徴のみについての寸法情報を前記スクリーン上に選択
    的に表示する。
  89. 【請求項89】 請求項88による方法にして、それは
    更に、前記パーツに関連する曲げモデルデータへアクセ
    スし、前記曲げモデルデータに基づいて、前記パーツの
    前記特徴のそれぞれについての寸法情報を表示するため
    の前記画面上の全ての可能な位置を決定する。
  90. 【請求項90】 請求項89による方法にして、前記選
    択的に表示する操作は、所定のヒューリスティックを適
    用し前記全ての可能な位置に基づいて前記可視の特徴の
    寸法情報を表示するための場所を決定する操作を含む。
  91. 【請求項91】 請求項90による方法にして、前記ヒ
    ューリスティックは、前記パーツの表示された画像の外
    側に位置する前記スクリーン上の位置に前記寸法情報を
    表示する。
  92. 【請求項92】 請求項90による方法にして、前記ヒ
    ューリスティックは、観察者の観察位置に近い前記スク
    リーン上の位置に前記寸法情報を表示する操作を含む。
  93. 【請求項93】 請求項90による方法にして、前記ヒ
    ューリスティックは、前記寸法情報が前記スクリーンに
    重ならないように前記寸法情報を表示する操作を含む。
  94. 【請求項94】 請求項90による方法にして、前記寸
    法情報は前記パーツの曲げ線のそれぞれについての曲げ
    線長さ及び曲げ角度を含む。
  95. 【請求項95】 請求項94による方法にして、前記寸
    法情報は、前記パーツの各曲げ線に関連する内部曲げ半
    径及び曲げ縮小量を含み、前記表示操作は、前記現在の
    姿に基づいて可視であると決定されたパーツの各曲げ線
    についての曲げ線長さ及び曲げ角度及び曲げ半径及び曲
    げ縮小量を表示する。
  96. 【請求項96】 請求項88による方法にして、前記寸
    法情報は、前記パーツのフランジ部のフランジ長さを含
    む。
  97. 【請求項97】 請求項88による方法にして、更に追
    加の情報を表示しこの追加の情報は前記パーツの幅及び
    深さ及び高さを含む。
  98. 【請求項98】 請求項88による方法にして、前記選
    択的表示操作は、前記パーツの所定の特徴のみの寸法情
    報を表示する自動寸法付け操作を含み前記寸法情報は可
    視であると判断された前記所定の特徴についてのみ表示
    される。
  99. 【請求項99】 請求項98による方法にして、前記所
    定の特徴の寸法情報は、前記パーツの各曲げ線について
    の曲げ線長さ及び曲げ角度、及び前記パーツの各フラン
    ジ部のフランジ長さを備える。
  100. 【請求項100】 請求項88による方法にして、前記
    選択的に表示する操作は、前記パーツの特徴に関連する
    ユーザにより選択された寸法情報を表示するマニュアル
    寸法付け操作を含み、従って各ユーザにより選択された
    寸法情報は、可視であると決定された前記部品の前記特
    徴についてのみ表示される。
  101. 【請求項101】 請求項88による方法にして、前記
    パーツの表示された画像は3次元座標空間における前記
    パーツの表現を備える。
  102. 【請求項102】 スクリーン上に表示されたパーツの
    画像と共に寸法情報を表示するためのシステムにして、
    前記寸法情報は前記パーツの特徴に関連し前記システム
    は以下を含む。前記パーツの前記表示された画像の現在
    姿を決定し且つ前記現在姿に基づいて前記スクリーン上
    で前記特徴のうちのいずれが可視であるかを決定するシ
    ステムと、 前記パーツの前記表示された画像と共に前記スクリーン
    上に前記スクリーン上で観察可能であると決定された前
    記パーツの前記特徴のみについての寸法情報を選択的に
    表示するシステム。
  103. 【請求項103】 請求項102による方法にして、そ
    れは更に、前記パーツに関連する曲げモデルデータへア
    クセスするためのアクセスシステムと、前記曲げモデル
    データに基づいて、前記パーツの前記特徴のそれぞれに
    ついての寸法情報を表示するためのスクリーン上の全て
    の可能な位置を決定するシステムとを含む。
  104. 【請求項104】 請求項103によるシステムにし
    て、前記選択的表示装置は、所定のヒューリスティック
    を適用し、前記可能な位置に基づいて、前記観察可能な
    特徴の寸法情報を表示する場所を決定する方法を有す
    る。
  105. 【請求項105】 請求項104による方法にして、前
    記ヒューリスティックは、前記パーツの前記表示された
    イメージの外側に存在する前記スクリーンの位置に前記
    寸法情報を表示する操作を含む。
  106. 【請求項106】 請求項104によるシステムにし
    て、前記ヒューリスティックは、観察者の観察点により
    近い前記スクリーンの位置に前記寸法情報を表示する操
    作を含む。
  107. 【請求項107】 請求項104によるシステムにし
    て、前記ヒューリスティックは、前記寸法情報が前記ス
    クリーンに重ならないように前記寸法情報を表示する操
    作を含む。
  108. 【請求項108】 請求項104によるシステムにし
    て、前記寸法情報は、前記パーツの各々の曲げ線につい
    ての曲げ線長さ及び曲げ角度を含む。
  109. 【請求項109】 請求項108によるシステムにし
    て、前記寸法情報は更に、前記パーツの各曲げ線に関連
    する内側曲げ半径及び曲げ縮小量を含み、前記選択的表
    示システムは、前記現在の姿に基づいて観察可能である
    と判断された前記パーツの各曲げ線についての曲げ線長
    さ及び曲げ角度及び曲げ半径及び曲げ縮小量を表示する
    ように構成されている。
  110. 【請求項110】 請求項102によるシステムにし
    て、前記寸法情報は、前記パーツの各フランジ部のフラ
    ンジ長さを含む。
  111. 【請求項111】 請求項102によるシステムにし
    て、それは更に、前記パーツの幅及び深さ及び高さを追
    加的に表示するシステムを含む。
  112. 【請求項112】 請求項102によるシステムにし
    て、前記選択的表示システムは、自動寸法付け操作を行
    ない、前記パーツの所定の特徴の寸法情報のみ表示し従
    って前記所定の特徴の前記寸法情報は観察可能であると
    判断された所定の特徴についてのみ表示される。
  113. 【請求項113】 請求項112によるシステムにし
    て、前記所定の特徴の寸法情報は、前記パーツの各曲げ
    線についての曲げ線長さ及び曲げ角度を含む。
  114. 【請求項114】 請求項113によるシステムにし
    て、前記寸法情報は更に前記パーツの各フランジ部のフ
    ランジ長さを備える。
  115. 【請求項115】 請求項102によるシステムにし
    て、前記選択的表示システムは、前記パーツの特徴に関
    連するユーザにより選択された寸法情報を表示するため
    の手動寸法付け操作を次のように行なう。即ち、前記ユ
    ーザにより選択された寸法情報の各々は観察可能である
    と決定された前記パーツの前記特徴についてのみ表示さ
    れる。
  116. 【請求項116】 請求項102によるシステムにし
    て、前記パーツの表示される画像は3次元座標空間にお
    ける前記パーツの表現を備える。
JP27347499A 1996-05-06 1999-09-27 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法 Expired - Fee Related JP3884195B2 (ja)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US1695896P 1996-05-06 1996-05-06
US60/016958 1996-05-06

Related Parent Applications (1)

Application Number Title Priority Date Filing Date
JP18338897A Division JP3265233B2 (ja) 1996-05-06 1997-05-02 部品を表現するためのオブジェクト指向曲げモデルを格納したコンピュータ読取可能媒体

Publications (3)

Publication Number Publication Date
JP2000090144A true JP2000090144A (ja) 2000-03-31
JP2000090144A5 JP2000090144A5 (ja) 2005-12-02
JP3884195B2 JP3884195B2 (ja) 2007-02-21

Family

ID=21779940

Family Applications (10)

Application Number Title Priority Date Filing Date
JP18338997A Expired - Fee Related JP3009135B2 (ja) 1996-05-06 1997-05-02 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP18338797A Expired - Fee Related JP3009134B2 (ja) 1996-05-06 1997-05-02 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP18338897A Expired - Fee Related JP3265233B2 (ja) 1996-05-06 1997-05-02 部品を表現するためのオブジェクト指向曲げモデルを格納したコンピュータ読取可能媒体
JP18339097A Expired - Fee Related JP2966376B2 (ja) 1996-05-06 1997-05-02 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP14216799A Expired - Fee Related JP3803509B2 (ja) 1996-05-06 1999-04-05 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法
JP11142166A Pending JP2000003384A (ja) 1996-05-06 1999-04-05 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法
JP10135799A Expired - Fee Related JP3803502B2 (ja) 1996-05-06 1999-04-08 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP11102564A Pending JPH11345260A (ja) 1996-05-06 1999-04-09 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP11273475A Withdrawn JP2000090145A (ja) 1996-05-06 1999-09-27 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法
JP27347499A Expired - Fee Related JP3884195B2 (ja) 1996-05-06 1999-09-27 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法

Family Applications Before (9)

Application Number Title Priority Date Filing Date
JP18338997A Expired - Fee Related JP3009135B2 (ja) 1996-05-06 1997-05-02 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP18338797A Expired - Fee Related JP3009134B2 (ja) 1996-05-06 1997-05-02 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP18338897A Expired - Fee Related JP3265233B2 (ja) 1996-05-06 1997-05-02 部品を表現するためのオブジェクト指向曲げモデルを格納したコンピュータ読取可能媒体
JP18339097A Expired - Fee Related JP2966376B2 (ja) 1996-05-06 1997-05-02 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP14216799A Expired - Fee Related JP3803509B2 (ja) 1996-05-06 1999-04-05 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法
JP11142166A Pending JP2000003384A (ja) 1996-05-06 1999-04-05 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法
JP10135799A Expired - Fee Related JP3803502B2 (ja) 1996-05-06 1999-04-08 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP11102564A Pending JPH11345260A (ja) 1996-05-06 1999-04-09 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法
JP11273475A Withdrawn JP2000090145A (ja) 1996-05-06 1999-09-27 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法

Country Status (1)

Country Link
JP (10) JP3009135B2 (ja)

Families Citing this family (14)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP4426717B2 (ja) 2000-12-06 2010-03-03 ヤマハ発動機株式会社 二輪車用サスペンション
JP4727835B2 (ja) * 2001-04-03 2011-07-20 株式会社アマダ 加工不可情報教示方法及びそのシステム
DE10131045A1 (de) * 2001-06-29 2003-01-09 Achim Fricker Konfektioniervorrichtung
JP4755779B2 (ja) * 2001-07-31 2011-08-24 株式会社アマダ 板金加工製品の3次元検査・利用方法及びそのシステム
JP2005092274A (ja) * 2003-09-12 2005-04-07 Amada Co Ltd 板金製品製造方法及びそのシステム並びに板金モデルを記録した記録媒体
JP2006092484A (ja) * 2004-09-27 2006-04-06 Matsushita Electric Works Ltd 設計支援システム
JP2008030110A (ja) * 2006-07-31 2008-02-14 Icgb Co Ltd プレスブレーキ用操作補助装置
JP5178483B2 (ja) * 2008-12-05 2013-04-10 富士通株式会社 プログラム、情報処理装置及び表示方法
JP6097657B2 (ja) * 2013-08-29 2017-03-15 株式会社アマダホールディングス 段曲げ認識システム及びその方法
JP6237498B2 (ja) * 2014-06-30 2017-11-29 カシオ計算機株式会社 図形表示制御装置、表示制御方法およびプログラム
US10817526B2 (en) * 2014-07-16 2020-10-27 Machine Research Corporation Systems and methods for searching a machining knowledge database
JP2017080198A (ja) * 2015-10-29 2017-05-18 キヤノンマーケティングジャパン株式会社 情報処理装置、情報処理方法、プログラム
EP3502930A1 (en) * 2017-12-22 2019-06-26 Dassault Systèmes Method for computing an unfolded part of a modeled bended part of a 3d object
CN109992684A (zh) * 2019-04-12 2019-07-09 中民筑友智能装备科技有限公司 预制构件生产线自动投影方法、装置、设备、系统及介质

Also Published As

Publication number Publication date
JPH11338909A (ja) 1999-12-10
JPH11345260A (ja) 1999-12-14
JP3009134B2 (ja) 2000-02-14
JP3803502B2 (ja) 2006-08-02
JP2000090145A (ja) 2000-03-31
JP2966376B2 (ja) 1999-10-25
JP2000003384A (ja) 2000-01-07
JP2000003385A (ja) 2000-01-07
JP3009135B2 (ja) 2000-02-14
JPH10187794A (ja) 1998-07-21
JP3803509B2 (ja) 2006-08-02
JPH10187795A (ja) 1998-07-21
JP3265233B2 (ja) 2002-03-11
JPH10187793A (ja) 1998-07-21
JPH10187796A (ja) 1998-07-21
JP3884195B2 (ja) 2007-02-21

Similar Documents

Publication Publication Date Title
US6411862B1 (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US7197372B2 (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US6219586B1 (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US5864482A (en) Apparatus and method for managing distributing design and manufacturing information throughout a sheet metal production facility
WO1997042608A9 (en) Apparatus and method for generating a sheet-metal bend model
CN102812463A (zh) 能够进行三维对象模型的3d印刷的方法和系统
JP2000090144A (ja) 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法
US6944513B1 (en) CAD system, CAD cooperative system, CAD data managing method, and storage medium
JP3308869B2 (ja) 部品表示画像操作システムおよび方法
JP3766857B2 (ja) 3次元モデルの開発支援システム
EP1830323A2 (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
JP2003067746A (ja) 形状特徴マイニング方法およびその装置

Legal Events

Date Code Title Description
A625 Written request for application examination (by other person)

Free format text: JAPANESE INTERMEDIATE CODE: A625

Effective date: 20040430

A521 Written amendment

Free format text: JAPANESE INTERMEDIATE CODE: A523

Effective date: 20051013

A711 Notification of change in applicant

Free format text: JAPANESE INTERMEDIATE CODE: A712

Effective date: 20051013

TRDD Decision of grant or rejection written
A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

Effective date: 20061114

A61 First payment of annual fees (during grant procedure)

Free format text: JAPANESE INTERMEDIATE CODE: A61

Effective date: 20061116

R150 Certificate of patent or registration of utility model

Free format text: JAPANESE INTERMEDIATE CODE: R150

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20101124

Year of fee payment: 4

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20101124

Year of fee payment: 4

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20111124

Year of fee payment: 5

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20111124

Year of fee payment: 5

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20121124

Year of fee payment: 6

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20121124

Year of fee payment: 6

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20131124

Year of fee payment: 7

LAPS Cancellation because of no payment of annual fees