JPH11338909A - 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 - Google Patents
薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法Info
- Publication number
- JPH11338909A JPH11338909A JP11101357A JP10135799A JPH11338909A JP H11338909 A JPH11338909 A JP H11338909A JP 11101357 A JP11101357 A JP 11101357A JP 10135799 A JP10135799 A JP 10135799A JP H11338909 A JPH11338909 A JP H11338909A
- Authority
- JP
- Japan
- Prior art keywords
- bending
- dimensional
- information
- data
- representation
- 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
Links
Classifications
-
- Y—GENERAL 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
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02P—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN THE PRODUCTION OR PROCESSING OF GOODS
- Y02P90/00—Enabling technologies with a potential contribution to greenhouse gas [GHG] emissions mitigation
- Y02P90/02—Total factory control, e.g. smart factories, flexible manufacturing systems [FMS] or integrated manufacturing systems [IMS]
-
- Y—GENERAL 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
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02P—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN THE PRODUCTION OR PROCESSING OF GOODS
- Y02P90/00—Enabling technologies with a potential contribution to greenhouse gas [GHG] emissions mitigation
- Y02P90/30—Computing 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
工場を通して設計及び製造情報を管理し分配するための
装置及び装置が提供される。此の発明の側面によれば、
重要な設計及び製造情報は、各作業に付随する設計及び
製造情報を格納し分配することにより達成される。従来
の紙作業セットアップ及び作業シートを、例えば、工場
の何れの場所からも瞬時にアクセスされる電子的格納作
業シートで置き換えることにより、此の発明は工場の全
体的効率を改良する。さらに、此の発明の種々の側面及
び特徴により、パーツ情報およびエキスパート知識の組
織化及びアクセス可能性が改良される。
Description
の「薄板金属製作設備全体に亘って設計製作情報を管理
し分配する装置と方法」と題したU.S.仮出願No. 60/01
6,948に準拠し、その明細書を全般的に参照する事によ
って本明細書に明白にとりいれていることを主張する。
細書の一部は、著作権保護の対象になっている。著作権
保有者はU.S.特許・商標局の特許フアイルや記録に記載
されている特許明細書の何人かによる複写には異議を申
し立てないが、それ以外のものについては著作権保有者
は著作権すべてを保留する。
部品の製作に関するものである。特に、本発明は曲げ薄
板金属部品の製作を容易にするために設計・製作情報を
工場全体にわたって管理・分配する装置と方法に関する
ものである。
げ薄板金属の製作は、連続的な製作製造段階を含む。第
一段階は設計段階で、そこでは顧客の仕様にもとづいて
薄板金属部品の設計が行われる。通例顧客は特定の薄板
金属部品の設備での製作を注文する。顧客の注文は通
例、部品を工場で製造するのに必要な製品と設計の情報
を含んでいる。この情報は、たとえば部品の幾何学的寸
法、部品に必要な材料(たとえば鋼鉄、ステインレス
鋼、またはアルミニウム)、特殊な成形の情報、分量、
引き渡し年月日等を含むことがある。客先から要請され
た薄板金属部品は広範囲の種類の応用に設計・製作する
ことが出来る。たとえば、製作された部品は最終的には
コンピュータのケース、配電盤、航空機の肘掛け、また
は自動車のドアのパネルに使われるかもしれない。設計
段階では、薄板金属部品の設計は、適当なコンピュータ
支援設計(CAD)システムによって製造設備の設計部で
なされる。顧客の仕様に応じて、プログラマーがCADシ
ステムを用いて薄板金属部品の2次元(2ーD)モデルを作
成することもできる。通例、客先は部品の重要な幾何学
的寸法を含む青写真を提供する。この青写真は、部品に
含まれる特別の成形や記号、または薄板金属部品の表面
の孔や他の開口を示すこともある。設計プログラマーは
CADシステムで2ーDモデルを作成するため、この青写真を
度々用いる。この2ーDモデルはまた、薄板金属部品の曲
げ線及び/または寸法情報を含む平面図と、一つまたは
一つ以上の透視図を含むこともある。
前に、先ず原材料から部品を打ち抜き切断するか/また
は切断しなければならない。在庫材料の処理に当たっ
て、打ち抜きプレスやプラズマまたはレーザー切断機を
制御作動するのに、普通コンピュータ数値制御(CNC)
または数値制御(NC)が用いられる。この在庫材料の処
理を容易にするため、設計プログラマーは、コンピュー
タ支援製造(CAM)システムまたはCAD/CAM システムを
用いて2ーDモデルにもとづいた制御コードを作成するこ
とが出来る。この制御コードには、打ち抜きプレス及び
/または切断機にとりいれて、在庫材料からの薄板金属
部品の打ち抜き、または切断に利用できる部品プログラ
ムが含められていることもある。
階である.この段階で、曲げ加工計画が作業場で曲げ加
工オペレータによって立てられる。オペレータには通常
切断または打ち抜かれた一つまたは一つ以上の在庫材料
とともに、部品の青写真または2ーD図面が渡される。こ
れらの材料で曲げ加工オペレータは使用する工具と実施
される曲げの手順を定める曲げ加工計画を立てる。曲げ
作業場には、オペレータがデータを入力した曲げコー
ド、または曲げ計画にもとづいたプログラムが作成でき
るCNCプレスブレーキのようなCNC金属曲げ機も含まれ
る。
は曲げ加工の順序の初期テストのための作業場を設置す
る。このテスト段階では、打ち抜きまたは切断された材
料はプレスブレーキに手で組み込まれ、プレスブレーキ
はプログラムされた順序に従って製作品に曲げを加工す
るように操作される。オペレータは出来上がった曲げ薄
板金属部品を分析して顧客の仕様に適合しているかどう
かを検査する。このプレスブレーキの初期作業の結果に
よって、オペレータは曲げプログラムを編集し、曲げ順
序を修正することもある。オペレータはまた、薄板金属
部品の設計が適当に修正出来るように、設計部に結果を
フイードバックすることもある。テストは通常曲げ薄板
金属部品が要求されている設計仕様内におさまるまで続
けて行われる。
階である。曲げ計画が作成され、テストされた後、曲げ
オペレータは曲げ加工場に必要な工具を装備し、曲げ計
画と記憶されている曲げプログラムまたはコードに従っ
てプレスブレーキを作動する。曲げ加工場に必要な量の
打ち抜きまたは切断された材料が確保されるように、ま
た他の作業が指定された引き渡し年月日までに完了して
いるように、作業日程も作成される。作業日程は製作過
程の初期段階と/または全過程に平行して作業場監督に
よって作成または修正されることもある。最後の曲げ薄
板金属部品の製作が完了すると、顧客への引き渡しのた
めに部品は集められ、梱包される。
利な点がある。たとえば、各々顧客の設計製造データは
通常物理的に(たとえば紙によってフアイルキャビネッ
トに)、電子的に(たとえばデイスクまたは磁気テープ
に)保管されるが、こうしたデータは普通別々に保管さ
れていて検索するのが容易でない。さらに、多くの工場
環境では、重要な仕事情報の分配は工場全体にわたって
配布される仕事または企画用紙の形をとる。その結果、
データがしばしば紛失または損傷し、以前または類似の
仕事に関する設計製造データを検索するのが困難にな
る。加うるに、データの保管方法の不備によって、設計
製造情報を全工場の作業場やその他の場所に配布するの
に貴重な時間が失われる。また部品の設計や曲げ計画の
作成は、主として設計プログラマーと曲げオペレータに
よって行われ、個人の知識、手腕と経験によるところが
大きいので、薄板金属部品と曲げ計画の作成の間に製造
時間がかなり失われる。
し、過程全体にわたる効率を改善するための開発と試み
がなされてきた。たとえば、市販のCAD/CAMシステムに
おける2次元(2-D)および3次元(3-D)モデル作成の使
用と開発によって曲げ薄板金属の製作過程とモデル作成
を促進され、改善された。今では設計プログラマーやオ
ペレーターは2ーD及び3ーD表示を用いて、部品の形状をよ
りよく理解し、部品設計と曲げコードの順序をより効率
的’に作成出来るようになっている。データを電子的に
記憶し、トランスフアーする機能は、設計部から作業場
への情報の流れを改善した。コンピュータとデータ通信
ネットワークの進歩により、最早古い紙テープや磁気デ
イスクをキャビネットまたはフアイルから探し出すこと
が不要になった。
と工場環境全体にわたる設計と製造情報の組織化と流れ
を改善する必要がまだある。たとえば、在来の製造シス
テムでは、各顧客の注文の重要な設計及び製造情報が、
工場のどの場所でも容易にアクセスでき、検索できるよ
うな論理的関係づけがなされていない。今までのシステ
ムはまた、薄板金属部品の特徴や特質のような、色々な
特色にもとづいた仕事情報を探索する機能をもたない。
たとえば同一または類似の部品の探索にもとづいた、以
前の仕事情報が探索でき、検索出来ることは、全体的な
製作プロセスを大幅に増強し、将来の仕事の必要製造時
間を短縮する。
業場オペレータによる薄板金属部品の設計を容易にする
ことに欠けている。2ーDや3ーDモデリング・システムによ
って、設計者は部品の形状や幾何学をよりよく理解出来
るようになったが、このシステムによって設計プログラ
マーや作業場オペレータに科せられた負担は軽減されて
いない。たとえば、これらのシステムによって設計プロ
グラマーが現存の2ーDCADモデルを簡単に3ーD表示に変換
することはできない。また作業場オペレータに曲げ加工
計画を立てる助けとなる部品の2ーD及び/また3-D図面が
提供されても、オペレータは必要な工具や曲げ手順を手
で/または試行によって決めなければならない。
の見地、実施例及び/または特色あ、るいはサブコンポ
ーネントを通して、以下にに特記する一つまたは一つ以
上の目的と利点をもたらすために供するものである。
品のような部品の製作を促進するために、設計と製造情
報を全工場に亘って管理し、分配する装置と方法の提供
である。
歩的な薄板金属製作設備における重要な仕事情報の紛失
または破壊を防止し、専門的知識の蓄積の有効活用と整
理を助長する装置と方法の提供がある。
の設計と製造情報の双方を、論理的に記憶する装置と方
法を備えることによって、工場のどの場所でも容易にア
クセスでき、検索できるようにすることにある。
ータが中央のデータベースまたはフアイルサーバーに、
全工場のどの場所でも容易に探索し、検索できるよう論
理的に記憶されている設計と製造情報を管理し、分配す
る装置と方法の提供にある。仕事データは仕事に関連し
た設計と製造情報ばかりでなく、必要な曲げ操作を遂行
するための実際の曲げコードも提供できる。
準にもとづいた、設計と製造情報を含む以前の仕事情報
を探索する装置と方法の提供である。探索基準は、たと
えばこれから製造される薄板金属部品の特色や特徴を含
むことができ、これによって同一または類似の部品に関
連した以前の仕事情報を、将来の仕事の全体的な製造時
間の短縮に利用できる。
に関連した従来の書類仕事または企画用紙を、工場の何
処からでも瞬間的にアクセスできる電子的ジョッブシー
トに置き換えることである。電子的なジョッブシートは
どの場所でも表示でき、部品の2ーD及び/または3-Dモデ
ル像、工具の選択、最適曲げ手順、必要なステイジング
情報やバーコードまたは認識番号を含む、仕事に関連し
た重要な設計と製造情報を含む。この電子的ジョッブシ
ートには、曲げオペレータによって将来再び同じ、また
は類似の仕事を行うときに役立つと思われる、特別の指
図または手順を録音録画したオーデイオ及び/またはビ
デオ部品も備えられる。
2ーDと3-Dコンピュータ画像を提供することによって部品
図面の解析に要する時間を短縮する事にある。固体3ーD
画像モード、3ーDワイヤフレーム画像モード、2-D平面画
像モード及び正射画像モードを含む、色々な画像が提供
できる。薄板金属部品の解析に役立つズーミング、パン
ニング、回転及び自動寸法入れを含む色々な異なる画像
機能も備えられる。
計と曲げ計画の製作を容易にする装置と方法を提供する
目的を持つ。たとえば、現存する部品の2ーDモデルから
部品の3ーD表示を容易に製作することができるようにす
るのも本発明の目的である。さらにもう一つの本発明の
目的として、曲げ計画とプログラムされた曲げコードを
作成する時間を短縮するためのグラフィックスインター
フエイスの提供がある。
いて製造されるべき部品の曲げモデルを生成するための
装置及び方法に向けられ、前記パーツは複数の面と少な
くとも1つの曲げ線を有する。前記装置は前記パーツに
関する初期パーツ情報を受け取るための受取システムを
含み、前記パーツ情報は第1の所定の座標空間の中での
前記パーツの表現に関連するデータを含む。面検出装置
が更に設けられ、それは前記第1所定座標空間内におい
て、前記初期パーツ情報に基づいて前記パーツの面を検
出する。更に装置は、検出された面に基づいて前記パー
ツの少なくとも1つの曲げ線を特定するための曲げ線特
定システムと前記面検出システムにより検出された面の
各々に対して所定の操作を行なうことにより、第2の所
定の座標空間内での前記パーツの表現に関連するデータ
を含み且つ前記パーツに関連する追加のパーツ情報を生
成するためのシステムとを含む。前記所定の操作は、少
なくとも初期パーツ情報と前記曲げ線特定システムによ
り特定される少なくとも1つの曲げ線に基づいて行なわ
れる。
間からなり前記第2の所定座標空間は3次元座標空間か
らなる。前記所定の操作は、前記面検出システムにより
検出された前記面に対してなされる折り曲げ操作からな
る。前記折り曲げ操作は、前記曲げ線特定システムによ
り特定された少なくとも1つの曲げ線に対して前記面検
出システムにより特定された複数の面のうちの各々を回
転し且つ並行移動する操作を含む。更に、前記初期パー
ツ情報は、更に前記パーツの少なくとも1つの曲げ線に
関連する曲げ角度量を含み、前記折り曲げ操作は、この
折り曲げ角度量に基づいて行なわれる。
所定の座標空間は3次元座標空間からなり第2の所定の
座標空間は2次元座標空間からなり、前記所定の操作
は、前記面検出システムにより検出された面に対してな
される展開操作からなる。前記展開操作は、前記曲げ線
特定システムにより特定された少なくとも1つの曲げ線
に対して前記面検出システムにより検出された複数の面
の各々を回転し且つ並行移動する操作を含む。更に前記
初期パーツ情報は更に前記パーツの少なくとも1つの曲
げ線に関連する曲げ角度量を含み、前記展開操作は、こ
の曲げ角度量に基づいて行なわれる。
らなり、前記第1の所定の座標空間内によるパーツの表
現に関連するデータは、座標データ及び/又はベクトル
データを含む。更に、前記パーツの複数の面は、前記パ
ーツの複数又は単数の基本的表面並びに前記パーツの屈
曲された表面からなる。この発明の他の側面によれば、
前記初期パーツ情報は、3次元空間におけるパーツの表
現に関連するデータを含み、前記データは、前記3次元
空間における前記パーツの厚さデータを含む。曲げモデ
ルを生成するための装置は更に、前記初期パーツ情報に
関連するデータに対して自動装飾及びクリーンアップ操
作を行ない、前記面検出システム及び曲げ線特性システ
ムのためのデータを作成する自動装飾及びクリーンアッ
プシステムを含む。前記データは少なくとも前記パーツ
の線分エンティティー及び曲げ線エンティティーを表現
するパーツエンティティーデータを含み、前記自動装飾
及びクリーンアップシステムは、前記エンティティーの
交差点を検出し且つ検出された交差点において前記エン
ティティーを選択的に分断するためのシステムと検出さ
れた交差点に基づいて、結果としての分断されたエンテ
ィティーが共通端点を有するように割り当てるシステム
とを含む。前記自動装飾及びクリーンアップシステム
は、又、隣接するエンティティーの間の空白の交差領域
を検出し且つ、共通端点を前記隣接したエンティティー
に対して付与することにより隣接したエンティティーを
選択的に接続するためのシステムを有する。
の端点が相互に所定の間隔の間に存在すると判断される
時空白交差領域を検出するための前記装置により検出さ
れる。
期パーツ情報に関連するデータは、少なくとも前記パー
ツの線分エンティティーを表現するパーツエンティティ
ーデータを含み、前記面検出システムは、前記パーツの
複数の面を検出するために、前記パーツエンティティー
データに基づいて前記パーツのループ及びエンティティ
ー分析を行なうようにされている。前記ループ及びエン
ティティー分析は、最初、前記パーツの外側境界に対し
て行なわれ、然る後、前記パーツの内側境界及び領域に
対して行なわれる。前記面検出システムは、前記パーツ
の外側領域に対して前記ループ及びエンティティー分析
を行なう際に、エンティティーの最初の結合されたリス
トを生成し、前記エンティティーの最初の結合されたリ
ストは前記パーツの外側ループ及び境界を定義する。前
記面検出システムは更に前記パーツの内部境界及び領域
に対して前記ループ及びエンティティー分析を行なう際
に前記エンティティーの追加の結合されたリストを生成
し、前記エンティティーの追加の結合されたリストは、
前記パーツの内部のループ及び境界を定義する。
ティティーの初期連結リストにより定義される外側ルー
プ及び前記エンティティーの追加の連結リストにより定
義される内側ループに基づいてループツリーを生成する
ためのシステムを有する。更に前記面検出システムは前
記ループツリー及び前記初期連結リストエンティティー
及び前記エンティティーの追加の連結リストにより定義
される境界のシーケンスに基づいて前記パーツの面を検
出する。
ンティティーの最初の連結リストと前記エンティティー
の追加の連結リストを解析し、前記面検出システムによ
り検出された面の間の共通の線分エンティティーを決定
するシステムを有する。
つとただ1つの共通線分エンティティーを有することの
検出に基づいて特定される。更に、前記曲げ線特定シス
テムは、前記共通線分エンティティーを決定するための
システムが前記面の間に1つ以上の共通線分が存在する
と検出した時、前記パーツの曲げ線を特定するための所
定のヒューリスティックを適用する。前記ヒューリステ
ィックは、前記部品に対して最小数の全曲げ線が特定さ
れるように前記パーツの曲げ線を特定する操作を含む。
前記ヒューリスティックは又、前記面の1つが前記面の
他の1つと1以上の共通線分エンティティーを有する時
最も長い長さを有する共通線分エンティティーに基づい
て前記部品の曲げ線を特定することを含む。
け取るためのシステムが設けられ、前記部品に関連する
縮小量を受け取る。前記面に対して所定の操作を行なう
際に前記縮小量に基づいて曲げ縮小についての補正を行
なうための装置も設けてある。曲げ縮小についての補正
を行なうための装置は、折り曲げ操作を行なう際に前記
パーツの前記曲げ線の両側において前記縮小量の半分だ
け前記面の寸法長さを増大する。前記曲げ縮小について
の補正を行なうためのシステムは、更に、展開操作を行
なう際に、前記パーツの前記曲げ線の両側において前記
縮小量の半分だけ前記面の寸法長さを減少せしめるよう
になっている。
工程を含む。前記パーツに関連する初期パーツ情報を受
け取る工程。前記初期パーツ情報は、第1の所定の座標
空間内で前記パーツの表現に関連するデータを含む。前
記第1所定座標空間内において前記初期パーツ情報に基
づいて前記パーツの面を検出する工程。前記検出により
検出された複数の面に基づいて前記パーツの少なくとも
1つの曲げ線を特定する工程。前記検出により検出され
た前記複数の面の各々に対して所定の操作を行なうこと
により、第2の所定の座標空間内における前記パーツの
表現に関連するデータを含む追加のパーツ情報を生成す
る工程。前記操作は、前記初期パーツ情報及び前記特定
操作により特定される少なくとも1つの曲げ線とに基づ
いて行なわれる。
間からなり、前記第2の所定の座標空間は3次元座標空
間からなる。更に、前記方法は、前記検出の工程により
検出された前記面に対して折り曲げ操作を行なう工程を
含む。前記折り曲げ操作は、前記特定するための工程に
より特定された少なくとも1つの曲げ線に対して前記面
の各々を回転し且つ並行移動する操作を含む。更に、前
記初期パーツ情報は、前記パーツの少なくとも1つの曲
げ線に関連する曲げ角度量を含み、前記折り曲げ操作
は、この曲げ角度量に基づいて行なわれる。
所定の座標空間は、3次元座標空間からなり、前記第2
の所定座標空間は2次元座標空間からなる。前記方法は
更に前記検出の工程により検出された面に対して展開操
作を行なう工程を有する。この展開操作は、前記特定す
るという工程により特定された少なくとも1つの曲げ線
に対して前記複数の面の各々を回転及び並行移動する操
作を含む。更に前記初期パーツ情報は、前記パーツの少
なくとも1つの曲げ線に関連する曲げ角度量を含み、前
記展開操作は、この曲げ角度量に基づいて行なわれる。
少なくとも1つの曲げ線を特定する前に、前記初期パー
ツ情報のデータに対して自動装飾及びクリーンアップ操
作を行なう工程を有する。前記初期パーツ情報のデータ
は、前記パーツの少なくとも線分エンティティーを表現
するパーツエンティティーデータを含み、前記面を検出
する工程は、前記パーツの面を検出するために前記パー
ツエンティティーデータに基づいて前記パーツのループ
及びエンティティー分析を行なうことを含む。前記ルー
プ及びエンティティー分析は、最初に前記パーツの外側
境界に対してなされ、次に前記パーツの内側境界及び領
域に対してなされる。
は、更に前記面の間に1以上の共通端部が検出される時
前記部品の曲げ線を特定するために所定のヒューリステ
ィックを適応することを含む。前記ヒューリスティック
は、前記パーツに対して最小数の全曲げ数が特定される
ように前記パーツの曲げ線を特定する工程を含む。前記
ヒューリスティックは又、前記面の1つが当該面の他の
1つと1以上の共通線分エンティティーを有する時最も
長い長さを有する共通線分エンティティーに基づいて前
記部品の曲げ線を特定することを含む。
ーツの曲げモデルを生成するためのシステムを含み、そ
こにおいて前記パーツは複数の面と少なくとも1つの曲
げ線を含む。前記システムは、前記部品に関連する初期
パーツ情報を受け取る手段を含み、前記初期パーツ情報
は、第1の所定の座標空間内での前記パーツの表現に関
連するデータを含む。前記第1所定空間内で前記初期パ
ーツ情報に基づいて前記パーツの面を検出するための検
出手段もまた設けてある。システムは更に、前記面検出
手段により検出された面に基づいて前記パーツの少なく
とも1つの曲げ線を同定する手段を含む。前記システム
は又、前記検出手段により検出された面に対して所定の
操作を行なうことにより第2の所定の座標空間内での前
記パーツの表現に関連するデータを含む追加のパーツ情
報を生成する手段を含む。前記所定の操作は、前記シス
テムの曲げ線決定手段により特定される曲げ線に少なく
とも部分的には基づいて行なわれる。この発明の他の側
面によれば、高知能製造設備において製造されるべきパ
ーツのベンドモデルを生成するための装置及び方法が提
供される。このシステムは、前記部品に関連する初期パ
ーツ情報を受け取るための受取システムを備え、前記初
期パーツ情報は、2次元空間内での前記パーツの複数の
姿の各表現を含み、前記表現の各々は前記パーツのパー
ツ厚さ表現を含む。クリーンアップ操作システムが更に
設けられ前記初期パーツ情報に対して2次元クリーンア
ップ操作を行ない、任意の余分な情報を消去し且つ、前
記表現の各々を特定する。前記システムは又、前記特定
された表現の各々におけるパーツ厚さ表現を選択的に消
去し2次元座標空間内での厚さを有しない前記パーツの
姿の修正された表現を提供する。前記システムはまた2
次元座標空間内での厚さを有しない前記パーツの前記修
正された表現に基づいて3次元座標空間内での前記パー
ツの表現を生成するシステムを含む。
ーツの線分エンティティーを表現するパーツエンティテ
ィーデータを含み、前記クリーンアップ操作は、前記エ
ンティティーの交差点を検出し且つ、検出された交差点
において前記エンティティーを選択的に分断するための
分断・装飾システムを含む。更にこの分断・装飾システ
ムは、前記検出された交差点に基づいて、前記結果とし
ての分断エンティティーが共通端点を有するように割り
付けを行なう。前記分断及び装飾システムは、更に、隣
接するエンティティーの間の空白の交差領域を検出し且
つそれらの隣接エンティティーに対して共通の端点を付
与することによりそれらの隣接エンティティーを選択的
に接続するためのシステムを有する。空白交差領域は、
前記隣接するエンティティーの端点が相互に所定距離の
間に存在すると判断される時、前記空白交差領域を検出
するシステムにより検出される。
ンアップ操作システムは、前記初期パーツ情報に基づい
て連結性グラフ構造を展開するためのシステムを備え、
前記クリーンアップ操作システムは、前記連結性グラフ
構造に基づいて余分の情報を消去する。前記消去される
余分の情報は、連結されない線分エンティティーを含
み、前記連結されない線分エンティティーは少なくとも
寸法線に関連する。
ィーデータ及びテキストに関連する余分の情報を特定す
るためのキーワードを含む。前記クリーンアップ操作シ
ステムは、前記初期パーツ情報に含まれるキーワードに
基づいてテキストに関連する余分の情報を消去する。
ンアップ操作システムは、前記初期パーツ情報に基づい
て前記パーツの平面図及び正面図及び右側面図の表現を
検出するためのシステムを有する。ここに開示されるよ
うに、前記パーツの複数の姿(図)は、2次元座標空間
における前記パーツの平面図及び正面図及び右側面図か
らなる。更に前記生成システムは、2次元座標空間にお
けるパーツの表現に基づいて3次元座標空間におけるパ
ーツの表現を生成するための射影操作を行なうシステム
を含む。前記射影操作は、前記複数の図面の各々の相対
的な深さを検出し、これらの複数の図面の各々を3次元
座標空間へ射影することを含む。
含む。前記パーツに関連する初期パーツ情報を受け取る
工程。前記初期パーツ情報は、2次元座標空間における
前記パーツの複数の図のそれぞれの表現を含み、前記表
現の各々は前記パーツのパーツ厚さ表現を含む。前記初
期パーツ情報に対して2次元クリーンアップ操作を行な
い、余分の情報を消去し且つ前記表現の各々を特定する
工程。前記特定された表現の各々においてパーツ厚さ表
現を選択的に消去し2次元座標空間における厚さを有し
ない前記パーツの図面の修正された表現を提供する工
程。前記2次元座標空間における厚さを有しないパーツ
の前記修正された表現に基づいて3次元座標空間におけ
る前記パーツの表現を生成する工程。前記初期パーツ情
報は、少なくとも前記パーツの線分エンティティーを表
現するパーツエンティティーデータを含み、前記操作の
工程は、前記エンティティーの交差点を検出し前記検出
された交差点において前記エンティティーを選択的に分
断する工程を含み、結果としての分断されたエンティテ
ィーは、検出された交差点に基づいて1つの共通の端点
を持つように割り付けられる。前記操作の工程は更に隣
接するエンティティーの間の空白の交差領域を検出し当
該隣接エンティティーに対して共通の端点を付与するこ
とにより当該隣接エンティティーを選択的に接続するこ
とを含む。空白交差領域は、隣接するエンティティーの
端点が相互に所定距離の間に存在する時検出される。
づいて連結性グラフ構造を生成し且つこの連結性グラフ
構造に基づいて前記初期パーツ情報から余分の情報を消
去する工程を含む。前記余分の情報は、連結されない線
分エンティティーを含み、前記連結されない線分エンテ
ィティーは少なくとも寸法線に関連する。
ンティティーデータとテキストに関連する余分の情報と
を特定するためのキーワードを含み、前記操作の工程
は、前記キーワードに基づいてテキストに関連する余分
の情報を削除する工程を含む。
厚さを選択的に消去する工程は、前記複数の図面の各々
において消去されるべきパーツ厚さ表現を特定し且つ前
記複数の図面の各々において残されるべきパーツの寸法
を特定するようにユーザに促す操作を含む。前記パーツ
の寸法は、前記パーツの外側寸法又は内側寸法の1つを
含む。更に前記生成の工程は、前記2次元空間における
パーツの修正された表現に基づいて3次元空間における
パーツの表現を生成するための射影操作を行なうことを
含む。前記射影操作は、前記複数の図面の各々の相対的
な深さを検出し且つ前記複数の図面の各々を3次元空間
へ射影することを含む。
はその変形を設けることができる、たとえば、発明を上
述した特徴の色々な組み合わせ、または再組み合わせ及
び/または下記の詳細な記述にある幾つかの特徴の組み
合わせとの再組み合わせに適用させることができる。
特徴及び利点については、この後により詳細に記述す
る。
されない本発明の望ましい実施例の例に沿っての発明の
色々な特徴、操作及び機能に関するソースコードの例や
コメントを記した、以下の多数の付録を参照する:付録
Aはたとえば一つの類似部品を探索するときの特徴抽出
演算実行の典型的なソースコードであり;付録Bはたと
えば本発明の幾つかの類似部品の探索時に類似指数演算
を行使する典型的なソースコードであり;付録Cはこの
発明で曲げ線検出操作を行う典型的なソースコードであ
り;付録Dは本発明の2-Dクリーンアップを実行するため
の典型的なソースコードであり、これによって薄板金属
部品の3-Dモデルを元の3方向からの2-D図面にもとづい
て作成するのに使用出来;付録Eは本発明の曲げモデル
ビューアーに色々なビュー モードや機能を実行するた
めの典型的ソースコードであり;付録F,G,HとIは本発明
の自動寸法入れ特性を実行するための典型的なソースコ
ードとコメントであり;付録Jは本発明の曲げモデルビ
ューアーの、部品・エンテイテイの観察可能性機能を実
行するための典型的なソースコードであり;付録Kは曲
げモデルの実施と部品構造の構成に関する、本発明の色
々な教訓をふまえた一般的なコメントを含み、付録Lは
与えられた部品の回転軸の動的計算による3-D操作とナ
ビゲーションシステムを実行する典型的なソースコード
である。
本発明の望ましい実施例の例についての多数の図面を参
照しながら記述されており、記述の中の同じ参照番号は
全図面中の類似の部品を示す。
管理分配し、工場内での部品の製造を促進するための装
置と方法が具備される。この本発明の特徴は広範囲の工
場環境や装置に利用することができ、特にこの発明は一
続きの製作製造段階が異なる場所で行われる工場環境の
充足に利用できる。限定されない実施例や種々の例を通
じて、本発明を、たとえば進歩的な薄板金属製造設備に
おける曲げ薄板金属部品の製作を参照しながら記述す
る。
な薄板金属製造設備38一般が、ブロック線図で図示され
ている。図1に示すように、薄板金属製造設備または工
場38は全工場に分散している多数の場所10,12,14...20
をもつ。
場14、打ち抜き作業場16、曲げ作業場18及び溶接作業場
20が含まれる。図1に画かれている薄板金属工場38には
分離した場所が六つしかないが、勿論工場は六つ以上の
分離した場所をもちうるし、また図1に画かれている各
タイプの事務所または作業場は一つ以上の場所を占める
こともある。たとえば設備38の大きさと製産必要容量に
より、一つ以上の打ち抜き作業場16、曲げ作業場18と/
または溶接作業場20を設けることができる。さらに工場
38は一つ以上の設計事務所10、組立作業場12または出荷
作業場14をもちうるし、曲げ薄板金属部品の製作製造を
促進するための他のタイプの場所をもちうる。
製作製造に伴う一つまたは一つ以上の別個の製作製造段
階や処理に対応し、実行する用具を備えている。たとえ
ば、設計事務所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打ち抜きプレ
スと/または切断機を制御する部品プログラムが作成で
きる。
C及び/またはNC機械工具のどのような組み合わせでも備
えられる。たとえば打ち抜き作業場16は、コマ・シリー
ズ及び/またはペガ・シリーズのアマダ・タレット打ち
抜きプレス、あるいは他の市販されているCNC及び/また
はNC打ち抜きプレス一つまたは一つ以上もつことがで
き、また曲げ作業場18は、RGシリーズ アマダ・プレス
ブレーキまたは他の市販されている多軸ゲージング・プ
レスブレーキのようなCNC及び/またはNCプレスブレーキ
を一つまたは一つ以上もつことができる。さらに溶接作
業場20は、薄板金属部品に対して必要な如何なる溶接を
も果たすために適当な溶接機器を備えることができる。
打ち抜き作業場16、曲げ作業場18と溶接作業場20は設備
38の工場内のどの場所にも設置出来、熟練オペレータ
(たとえば打ち抜きプレスオペレータ、曲げ機オペレー
タ等)によって手動で動かすことができる機械も備えて
いる。アマダ セルロボミニやアマダ プロムキャムの
ような全自動またはロボット支援機械もこれらの場所に
備えることができる。必要な打ち抜きと曲げの作業、あ
るいは必要な如何なる溶接作業もこれらの作業場で製作
過程中に行うことができる。
属設備38は組立作業場12と出荷作業場14も含む。組立作
業場12と出荷作業場14には、顧客への製造部品の組立と
出荷を促進するために必要な梱包、ルート割り当て及び
/または輸送機器も含まれる。部品の組立と出荷は工場
職員によって手動で行使または管理されるが、機械自動
化及び/または機械支援にすることもできる。さらに組
立作業場12と出荷作業場14は、物理的に工場作業場(た
とえば打ち抜き作業場16、曲げ作業場18及び/または
‘溶接作業場20に近接した)に近い場所に置くか、また
は薄板金属工場38とは別の設備または区域に置くことが
できる。本発明の見地に沿って、重要な設計と製造情報
の管理と分配は、設計と製造情報を電子的に記憶し、分
配することによって行われる。伝統的な紙上の仕事の段
取りまたはワークシートを、工場のどの場所からでも瞬
時的にアクセスできる電子的なジョッブシートに置き換
え、または補足することによって、本発明は工場の全体
的な効率を改善することができる。加えて、本発明の色
々な側面や特徴によって、記憶された設計製造情報の編
成とアクセスが改善される。さらに類似または同一の薄
板金属部品に関する以前の仕事情報のアクセスや検索
が、この発明の色々な特徴を通じて出来るようになって
いる。
サーバーモジュール32とデータベース30を薄板金属設備
38内の多数の場所10,12,14...20各々と結ぶ通信ネット
ワーク26を設けることによって実行される。このあと論
ずるように、各場所10,12,14...20は通信ネットワーク2
6とデータベース30にインターフエイスするステーショ
ンモジュールをもつ。図1、2と3に発明のこれらの特
色と実装の限定されない例を示す。
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のような機械類のインターフエイス/制御
システムの一部であるコンピュータであってもよい。
通信ネットワークにつながれている。サーバーモジュー
ル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を介し
てつなぐことができる。
ない例として、サーバーモジュール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)サーバーの全面的な支援を具備
できる。
またデータベースに記憶された情報を創りだしたり、保
持したり見たりすることに用いられる。構造的問い合わ
せ言語(SQL)のようなデータベース言語をデータベー
ス30のデータを確定したり、操作したり、制御したりす
るのに用いることができる。たとえば、SQLサーバー
(マイクロソフト社から入手できる小売り製品)は本発
明の実施に利用できる。さらに、この発明は開放データ
ベース連結オープン・データベース・コネクテイビテイ
ー(ODBC)互換ドライバーを備えることによって通信ネ
ットワーク26を通してのデータベース30からの情報のア
クセスを促進できる。ODBCに関するより詳しい情報はマ
イクロソフトオープン・データベース。コネクテイビテ
イー・ソフトウエア開発キットプログラマー用レフアラ
ンス・マニュエルでえられる。
れた進歩的な薄板金属製造設備のブロック線図である。
図2の実施例では、データベース30とサーバーモジュー
ル32は別々に設置されており、データベース30はネット
ワークデータベースモジュール34を介して通信ネットワ
ーク26につながれている。上記のように、本発明はこの
構成に限定されたものではなく、データベース30とサー
バーモジュール32は一緒に設置でき(たとえば図1に示
すように)、ネットワークデータベースモジュール34の
データベースにアクセスする機能をサーバーモジュール
に取り入れることができる。図2はまた、薄板金属製造
設備38内の色々な場所10,12,14...20に設置できるステ
イションモジュール36の例を示す。図示の目的で、図2
には曲げステイション18に設置されたステイションモジ
ュール36が例示されている。図2の例には示されていな
いが、同様のステーションモジュール36を設備38内の他
の場所にも設置できる。
ーモジュール32、ネットワークデータベースモジュール
34及びステイションモジュール36)はネットワークイン
ターフエイスカードまたはポート42を介して通信ネット
ワーク26につなぐことができる。ネットワークインター
フエイスカード26はベンダー専用で、選ばれた通信ネッ
トワークの形式にもとづいて選択できる。 各モジュー
ル32、34、36は通信ネットワーク26とインターフエイス
するためのネットワークソフトウエアまたはプログラム
された論理を含むことができる。 通信ネットワーク26
はイーサネット(Ethernet)で、10ベース/T(ツイスト
対)、10ベース/2(同軸)、または10ベース/5(厚膜ケ
ーブル)のような多くのタイプの市販ケーブルから設備
38の大きさと必要なケーブル長さにもとづいて選んだタ
イプのケーブルを用いたものであってもよい。
モニターまたはCRT44とキーボード、マウス及び/または
ジョイステイックを含む入力/出力デバイスをもつパソ
コンを含めうる。ネットワークインターフエスカード42
は備えられている拡張スロットまたはパソコン40のポー
トに挿入できる。さらに、パソコン40は100-200MHzの処
理速度とペンテイアムまたはペンテイアム・プロ マイ
クロプロセッサーを含むことができる。パソコン40はま
た、たとえば32MBまたはそれ以上の主記憶装置と1.2GB
またはそれ以上のランダムアクセス記憶装置(RAM)を
含むことができる。デイスプレイ44は高解像度の表示画
面、たとえば800×600の解像度をもつ市販のSVGAモニタ
ーを含むことができる。デイスプレイ44に表示された色
々なグラフ一クスや情報を支援するため、パソコン40は
また、PCIグラフイックス・カードのような市販のグラフ
イックスクス・カードを含むことができる。さらに、コ
ンピュータ40はサウンド・ブラスター、または互換の音
声及びゲームポートアダプターカードを含み、入力/出
力装置46はキーボード、ジョイステイックと/またはマ
ウスを含むことができる。
サーバーモジュール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サーバー
を、データをリンクするために備えることができる。
バーモジュール32から分離して備えられており、ネット
ワーク データベース モジュール34を経由して通信ネ
ットワーク26につなげられている。先に述べたように、
データベース30は工場38の規模と、データベースに記憶
させる部品情報の量にもとづいて選ばれた、適当な記憶
スペースをもったSCSIデイスク(たとえば1-4 GB)を含
むことができる。ネットワーク データベース モジュ
ール34は、ペンテイウム マイクロプロセッサーを備え
たIBM互換機のようなパソコン40と、通信ネットワーク2
6とインターフェースするためのネットワーク インタ
ーフエース カード42を備えた拡張スロットを含むこと
ができる。データベース30はデータ母線を介してパソコ
ン40に連結でき、パソコン40は標準的なデイスプレイや
デイスプレイ モニターまたはCRTとキーボードのよう
な入力/出力デバイス(図2には示されていない)も含
む。
スを容易にするため、ネットワークデータベース モジ
ュール 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のジョイステイックまたはマウスを含
むことができる。
ステイション・モジュール36はソフトウエアといろいろ
な市販ソフトウエアが配置されている。たとえば、ステ
ーション・モジュール36はマイクロソフト・ウインドウ
ズ95またはウインドウズNT(ワークステーション版)の
ような基本ソフトが備えられている。さらに、ステーシ
ョン・モジュールに、この発明固有の機能と特徴をもた
せるために(たとえば図5を見よ)、ステーション・モ
ジュール36にソフトウエアまたはプログラム化論理装備
ルチーンが備えられる。後でより詳しく論ずるように、
これらのルチーンは高レベルのプログラム言語、たとえ
ばC++、及びオブジェクト指向プログラミング技術を用
いることによって開発できる。データをアクセスし、リ
ンクするために、ステーション・モジュール36はマイク
ロシフトOBCDドライバーとOLE2サーバーのようなOLEサ
ーバーが含まれている。サーバー・モジュール32と同
様、ステーション・モジュールもSQLをデータベース30
からデータをアクセスする基準に用いることができる。
ュール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)の組み込みコンピュータに通常備わっ
ている機能をシミュレートできる。
データベース30と薄板金属製造設備38の間のそれぞれの
データの流れを示す実施例の典型である。図で表すため
と実施例におけるそれぞれのデータの流れの記述を容易
にするため、図3ではサーバー・モジュール32とデータ
ベース30(ネットワーク・データベース・モジュール34
に統合されている)は、各々別々に通信ネットワーク26
と直接に接続されていて、これらの構成要素間のデータ
の流れは通信ネットワークを通して行われる。勿論、こ
の技術に熟練した人なら分かるように、これら構成要素
間には多種多様のデータの流れ方式を用いることができ
る;また、データベース30がサーバー・モジュール32に
直接接続されている場合、データと情報はサーバー・モ
ジュールからデータベースに直接に、通信ネットワーク
26を用いることなく伝達できる。さらに、記述を容易に
するため、図3の通信ネットワーク26は簡略化されてお
り、図には打ち抜きステーション16と曲げステーション
18しか示されていない。しかしながら、場所10,12,1
4...20(工場内の他のあらゆる場所や区域も含めて)か
らのデータのやりとりの流れは、打ち抜きステーション
16と曲げステーション18について示したのと同様の方法
で行うことができる。
編成してデータベース30に記憶することができる。最初
に顧客から注文を受けると、基本的な製品と設計情報が
サーバー・モジュール32に入力され、それからデータベ
ース30に伝送され、記憶される。前に論じたように、サ
ーバー・モジュール32は、キーボードを備えたパソコン
等のような、データを入力する適当な手段を備えてい
る。サーバー・モジュール32でパソコンが用いられると
き、工場職員によるデータの入力を容易にするため、メ
ニュー方式画面を生成するソフトウエアを備えることが
できる。データ入力プログラムは、たとえばマイクロソ
フト・ウインドウズをベースとしたアプリケーション
で、ヘルプ及び/またはメニュー画面をもつものであっ
てよい。限定されない例として、サーバー・モジュール
32に入力され/または作成されて、データベース30に転
送されたデータは、図3に一般的に示してあるように、
部品情報、曲げモデル、特徴抽出データ及び曲げ線情報
を含むことができる。
番号、顧客の名前、部品の簡単な説明、バッチの大きさ
または量及び引き渡し予定日を含むことができる。曲げ
モデルデータは、たとえば部品の全体的な寸法(たとえ
ば幅、高さ、深さ)と材料のタイプ(たとえば鋼鉄、ス
テインレス鋼またはアルミニウム)、厚さ及び引っ張り
強さのような部品材料の情報を含むことができる。さら
に、特徴抽出データは手動による入力と/または自動的
に生成することによって、部品の主要な特徴を識別し、
データベースの類似部品の探索やその他の探索を容易に
する。特徴抽出データはデータベース30の別のフアイル
に格納するか、曲げモデルデータや各部品の仕事情報と
一緒に格納することができる。特徴抽出データは、たと
えば表面や面の数、曲げタイプの数(たとえば二面間の
正の折り曲げ、または二面間の負の折り曲げ)、面の間
の関係及び/または部品にある孔や他のタイプの開口の
数を含むことができる。後でより詳しく論ずるように、
このようなデータは特徴ベース部品マトリクスと/また
は逐次探索キー(たとえば下記の図6-10を見よ)に
よって表現し、編成できる。最後に、曲げ線情報はデー
タベース30に格納するため、サーバー・モジュール32に
入力できる。曲げ線情報は、たとえば部品の各折り曲げ
の曲げ角度、曲げ長さ、曲げの内半径(IR)、縮小量及
び曲げ方向(たとえば前方または後方)を含む主要な曲
げ線情報を含む。
30へデータを送受信するため、各場所10,12,14...20は
通信ネットワークに接続されているステーション・モジ
ュール(前に述べたステーション・モジュール36のよう
な)を含めることができる。図3には、打ち抜きステー
ション16と曲げステーション18は一般的にステーション
・モジュールと合わせたブロック線図で示されている。
前に論じたように、ステーション・モジュールは、たと
えばソフトウエア、または制御論理と独立型パソコン、
またはその場所に備えられた装置または機械類の一部で
ある汎用コンピュータを含む。各顧客の注文に応じて、
設計製造情報(部品情報、曲げ線情報および曲げモデル
・データを含む)が、所定参照番号またはコードを入力
することによってアクセスでき、検索できる。参照番号
またはコードは手動(たとえばキーボードまたはデジタ
ル入力パッドによって)またはバー・コードを、ステー
ション・モジュールに備えられているバー・コード読み
とり装置またはスキャナーでスキャンすることによって
入力できる。さらに、本発明の見地に沿って、以前の仕
事情報はデータベース30から、工場内のどの場所10,12,
14...20からでも、同様の部品探索を行うことによって
アクセスし、検索できる。引き続く詳しい記述で論ずる
ように、類似部品の探索は、特徴抽出データ、またはデ
ータベース30に記憶されている探索キーにもとづいて行
うことができ、これによって同一または類似の部品に関
する以前の仕事情報が検索され、将来の仕事の全体的な
製造時間の短縮に利用できる。
は、作業場オペレータが曲げ計画を作成し、テストする
のに用いられる。たとえば、曲げステーション18の曲げ
オペレータは、薄板金属部品に必要な工具や最適な曲げ
手順を決めるために、データベース30から部品情報、曲
げ線情報や曲げモデル・データをアクセスし、検索する
ことができる。本発明の見地に沿って、ODBCドライバー
を備えることにより、各ステーション・モジュールがデ
ータベース30とインターフエースし、データベースに記
憶されている情報を表示できるようにすることができ
る。さらに、サーバー・モジュール32またはデータベー
ス30のネットワーク・データベース・モジュールは、デ
ータベースに記憶されているデータのアクセスと検索を
容易にするために、SQLサーバーを含むことができる。
最終曲げ計画に基づいて曲げコードがプログラムされる
と、曲げコードは曲げ手順とともに、図3に一般的に示
すように通信ネットワーク30を通じて、曲げステーショ
ンのステーション・モジュール18からデータベース30に
送られる。この情報は、当該の仕事に関連する他の設計
製造情報とともに記憶される。
ができる。たとえば、部品の2-D及び/または3-D画像表
現は曲げモデルデータとともに記憶することができる。
この2-Dまたは3-D画像表現は設計ステーション10または
他の場所でCAD/CAMシステムを用いて作成し、設計ステ
ーション(あるいは他の適当な場所)のステーション・
モジュールを介して通信ネットワーク26を通じ、データ
ベース30に転送できる。あるいはまた、2-Dまたは3-D画
像はサーバー・モジュール32で、後でより詳しく述べる
ように、適当なCAD/CAMシステムまたはモデル化ソフト
ウエアを用いて、一連の機能または演算を実行すること
によって作成できる。
ュール32と各場所10,12,14...20においてプログラムさ
れ実行される処理や演算について詳述する。図4と5は
サーバー・モジュール32と薄板金属製造設備38内の各場
所10,12,14...20で実行される基本論理の流れの流れ図
である。図5は、たとえば曲げステーション18で実行さ
れる典型的な処理や操作に対するものであるが、設備38
内の特定な場所で実行される操作によっては、これ以外
の処理やステップも実行できることは理解できよう。以
下に述べる処理や操作はソフトウエア、または多種類の
プログラム作成言語と技法の一つを利用することによっ
て実施できる。たとえば、本発明の見地に沿って、関連
図面を参照しながら記述する下記の処理や操作は、C++
のような高レベルのプログラム作成言語とオブジェクト
指向プログラミング技法を用いることによって実施でき
る。さらに、限定されない例として、ウインドウズ・ベ
ースアプリケーション用にマイクロソフト社が作成し
た、プログラム作成言語のバージョンであるヴイジュア
ルC++を利用することができる。
モジュール 32が行う基本的な処理と操作の流れ図であ
る。図4はサーバー・モジュール32がソフトウエアまた
はプログラム化論理によって実行する処理と操作の基本
論理フローである。サーバー・モジュール32は、オペレ
ータまたはユーザーがサーバー・モジュールの色々な処
理や操作の選択と実行を支援するためにツール・バーや
ヘルプ及び/またはメニュー画面をもつウインドウズ・
ベース アプリケーションを含むことができる。処理は
薄板金属製造設備38で顧客の注文を受けたステップS.1
から開始される。顧客の注文は通常部品が工場で製造す
るのに必要な製品と設計の情報を含む。この情報は、た
とえば部品の幾何学的寸法、部品に必要な材料や他の設
計情報も含む。顧客から受けた情報をもとに、サーバー
・モジュール32は、ステップS.3に画かれているよう
に、データベース30に記憶されている以前の仕事情報の
探索を実行する。データベース30に記憶されている仕事
情報は多様な探索基準にもとづいて探索できる。たとえ
ば、情報は事前定義参照または仕事番号にもとづいて探
索でき、あるいは類似部品の探索は部品のある設計特徴
にもとづいて実行でき、これによって同一または類似の
部品に関する以前の仕事情報が現在の仕事のために検索
でき、利用できる。利用できる類似部品探索のさらに詳
しい記述は、図6-10を参照しながら以下に記す。
果が解析され、現在の顧客の注文が新しい部品か、以前
の仕事に類似の部品か、あるいは以前の仕事の繰り返し
かが決定される。同一の照合が見いだされる(たとえば
同じ部品または参照番号が見いだされる)と、顧客の現
在の注文は工場で行った以前の仕事の完全な繰り返しに
なり、仕事情報に対するこれ以上の修正は不必要で、以
前の仕事情報をデータベース30からアクセスしてステッ
プS.11に示すように現在の顧客の注文の遂行に利用でき
る。データベースの探索は以前の仕事の部品または参照
番号及び/またはフアイル名を与え、それによってサー
バー・モジュール32またはどのステーション・モジュー
ルにいるオペレータでもデータベースから仕事情報をア
クセスすることができる。部品または参照番号しかえら
れない場合、変換テーブルを備えることによって、オペ
レータが部品参照または仕事番号を入力することによっ
て以前の仕事情報のフアイル名を決定し、アクセスでき
る。従って、たとえばサーバー・モジュール32にいるオ
ペレータは、仕事情報と2-Dと3-Dモデル化情報をデータ
ベース30からアクセスすることによって部品の幾何学を
解析し、繰り返しの注文と類似であることを確認するこ
とができる。注文が繰り返しの注文であることが確認さ
れると、曲げステーション18のステーション・モジュー
ルにいる曲げオペレータは、さらに以前の仕事情報をア
クセスし、曲げコードのデータと工具段取り情報を含む
製造情報を曲げと部品の製作に利用することができる。
かかる記憶された専門的知識を利用することによって、
このようにして、繰り返しの注文をより効率的に、以前
に入力され開発された仕事情報を必要とせずに製造する
ことを可能にする。
注文が以前の仕事と類似か、以前の仕事と同じである
が、たとえば仕事または参照番号またはバッチの大きさ
等の修正が必要と決定されれば、ステップS.7での探索
で捜し出した以前の仕事情報データはデータベース30か
ら検索され、サーバー・モジュール32にいるオペレータ
によって編集し、修正される。編集機能を備えることに
よって、以前の仕事データを編集し、修正して新しい仕
事データを作成し、現在の顧客の注文のためにデータベ
ース30に格納できる。必要とする編集の量は、以前の仕
事と現在の仕事間の類似性の程度による。編集の量は、
参照または仕事番号またはバッチの大きさの単なる修正
から/または、部品の寸法や定められた曲げ手順の編集
のような、より広範囲な修正を含むものにわたる。以前
の仕事情報の編集が終わると、修正された仕事情報はス
テップS.9でデータベース30に格納される。修正された
仕事情報は新しい参照または仕事番号で格納できる。さ
らに、色々なデータベース管理機能(コーピー、削除、
保管、再命名等)を備えることによって、特別なコマン
ドの入力でデータベース30の以前の仕事情報の保持、ま
たは以前の仕事情報の消去または上書きができる。
のが無く、従って現在の顧客の注文は新しい仕事に関係
することが決定されると、論理フローは図4に示すステ
ップS.15に進む。この場合、現在の仕事は新しい仕事に
関するものになるので、設計製造情報を独立に作成し、
入力しなければならない。サーバー・モジュール32から
メニュー及び/またはヘルプ画面を提供することによっ
て、オペレータが必要な仕事情報すべてを入力するのを
支援することができる。本発明の見地に沿って、サーバ
ー・モジュール32のオペレータは、最初に新しい仕事の
基本的な部品情報を入力することによって新しいフアイ
ルを作成できる。部品情報は、たとえば参照または仕事
番号、顧客の名前、部品の簡単な記述、仕事に必要なバ
ッチの大きさまたは量及び予定引き渡し年月日を含む。
特徴抽出データまたは探索キーもステップS.15で入力で
きるし、また、以下に記すように、このデータを自動的
に作成するか、曲げモデルデータの作成と同時に抽出す
ることができる。他のデータや情報もステップS.15で入
力するか、部品の各曲げ線の曲げ角度、半径や長さを含
む曲げ線情報のような曲げモデルデータの入力後か入力
中に入力できる。ステップS.15に引き続き、論理フロー
は図4に示すように、オペレータによって曲げモデルデ
ータがサーバー・モジュール32で開発され、入力される
ように進む。
された原図や情報に依存する。顧客の注文は、たとえば
製造される部品の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図面の提
供と表現は、設計プログラマー、曲げオペレータや他の
ユーザがより容易に解釈され理解される部品のモデリン
グとシミュレーションの図を与える。厚さ情報を省くこ
とはまた、サーバー・モジュールやステーション・モジ
ュールで、文中に記述の本発明の色々な特徴を実行し達
成するのに要する処理時間を短縮し、改善する。このよ
うな特徴のより詳細な記述や、本発明で利用することが
できる折りたたみと展開アルゴりズムについては、以下
に付図を参照しながら記述する。
る一般的な処理と操作を示す。受理した、または顧客の
注文にもとづいて開発され、曲げモデルデータを作成す
るために入力できる色々なタイプの図面は、一般的にス
テップ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に取り入れられ
る。
デルを作成する処理は、図4に示すようにステップS.19
から始められる。ステップS.19で、受理または作成され
た2-D平面図はサーバー・モジュール32に入力される。
部品の全体的な寸法(幅、高さ、深さ)のような他の曲
げモデルデータ及び部品材料情報もステップS.19で入力
できる。その後、折りたたみアルゴリズムまたは処理を
用いて、ステップS.21に一般的に示されているように、
元の2-D一方向図面にもとづいて3-Dモデル(材料の厚さ
のない)を作成することができる。2-D平面図から3-Dモ
デルを作成するのに行われる処理や操作の例は、図11
-18を参照しながら後で述べる。
の無い)が受理または作成された場合、図の情報はステ
ップS.27で入力される。さらに、他の曲げモデルデー
タ、たとえば部品の全体的な寸法(幅、高さ、深さ)及
び部品材料情報もステップS.27で入力できる。この後
に、ステップS.27に示すように、部品の2-Dモデルを作
成するために、サーバー・モジュール32で展開のアルゴ
リズムまたは処理が実行される。2-Dモデルを3-D図面
(厚さのない)から作成するために行われる処理と操作
の例は、たとえば図19を参照しながら後で述べる。
ための曲げモデルの一部として格納される。さらに、前
に注記したように、2-Dと3-Dモデルの作成と格納の間
に、他の曲げモデルデータ(部品材料情報やその他の製
造情報のような)も入力し、曲げモデルデータとともに
データベース30に格納できる。曲げモデルデータを編成
し、格納するために実施できる、いろいろな機能やデー
タ構造配列についてはあとでより詳しく記述する(たと
えば図26と27を見よ)。
厚さなしの)がもともと作成または受理されていない場
合は、最終的な2-Dモデルを作成するのに必要な展開ア
ルゴリズムまたは処理を行う前に、部品の3-Dモデル
(厚さなし)を作成するための付加的な処理が必要とな
る。ステップS.23、S.25、S.31とS.33は、ステップS.29
で展開アルゴリズムを実行し、2-Dモデルを作成する前
に、サーバー・モジュール32で一般に実施される付加的
な処理と操作を示す。
図)がはじめに提供または作成されている場合、ステッ
プS.23で図面はサーバー・モジュール32に入力または取
り入れることができる。さらに部品の全体的な寸法
(幅、高さ、深さ)のような他の曲げモデルデータや部
品材料情報もS.23で入力できる。引き続きステップS.25
では、入力された2-D三方向図面にもとづいて、部品の
簡単な3-D平面図が作成できる。作成された3-D図面は、
図4に示すように、ステップS.29で2-Dモデルを作成す
るのに用いられる。3-Dモデルを2-D三方向図面から作成
する処理と操作の例は、あとでたとえば図20を参照し
ながら述べる。
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を参照しながら下記に述べる。
作成され、入力された後、顧客の注文に関連する部品情
報、曲げモデル情報及びその他のデータは、ステップS.
35でサーバー・モジュール32からデータベース30に移さ
れて格納される。データベース30に格納されたデータ
は、データベース探索を行うときに利用できる特徴抽出
または探索データも含む。下記に述べるように、特徴抽
出または探索データは、各仕事に関連した部品の基本的
または主要な特徴を指示するデータも含まれ、これによ
って仕事情報や格納されている同一または類似部品に関
する専門的知識の探索が実施できる。サーバー・モジュ
ール32に入力されたデータと情報は、たとえば図3に示
すように、直接データベース30に、または通信ネットワ
ーク26を介して転送することができる。上述のように、
曲げモデルデータを作成するときに、色々な図面に対し
て実施できる各種の処理や操作についての詳しい記述
は、下記に付図を参照しながら記す。
0に設けられ、各ステーション・モジュールで実施され
る基本的な処理や操作の流れ図を示す。例証のため、図
5は、たとえば曲げステーション18に置かれたステーシ
ョン・モジュールで実施される基本的な処理や操作の基
本論理の流れの例を示す。本発明の教示にもとづく技術
に熟練した者には理解できるように、図5に示す論理の
流れは、各場所で実施される操作や処理の性格により、
各ステーション・モジュールで修正できることは勿論で
ある。さらに、サーバー・モジュール32と同様、下記に
述べるステーション・モジュールでの処理や操作にはソ
フトウエアまたはプログラム化論理を装備できる。加う
るに、ステーション・モジュールは、オペレータまたは
ユーザーによる色々な処理や操作の選択と実施を容易に
するために、ツール・バー・アイコンまたはヘルプ及び
/またはメニュー画面をもつウインドウズ・ベース・ア
プリケーションを含むことができる。このようなヘルプ
及び/またはメニュー画面は、ステーション・モジュー
ルにおいてデータの入力または転送を容易にするために
も設けることができる。
ション・モジュールを初期設定した後、オペレータはス
テップS.53で一つまたは一つ以上のデータベース探索基
準またはキー項目を入力することができる。探索基準
は、データベース30に格納されている以前の仕事情報、
または新しいまたは現在の仕事に関する仕事情報を捜し
出すために入力できる。オペレータは、たとえばデータ
ベース30から特定の仕事情報を検索するために、予め定
められた番号またはコードを入力できる。たとえば、本
発明の見地に沿って、バーコード をルーチングシート
に付すか、せん孔された材料につけて、ステーション・
モジュールでバーコード読みとり装置でスキャンするこ
とによって情報をアクセスすることができる。あるい
は、参照コードまたは番号を、ステーション・モジュー
ルでキーボードまたはデイジタル入力パッドを介して手
動で入力できる。変換テーブルを備えることによって、
部品参照または仕事番号のオペレータによる入力によっ
て、以前の仕事情報を定めることもできる。さらに、探
索基準またはキーを入力することによって、以前に格納
した仕事情報の類似部品探索を行うことも予想される。
このような探索は、部品の色々な設計特性または特徴抽
出データにもとづいて行うことができる。本発明の見地
に沿って実行できる類似部品探索の説明は、下記に図6
-10を参照しながら記す。
テーション・モジュールはステップS.55で、通信ネット
ワーク26とネットワーク・データベース・モジュール34
を介してデータベース30の探索を実行できる。探索の結
果はステーション・モジュールに戻され、ステップS.57
でオペレータまたはユーザーが新しい仕事または類似の
以前の仕事に関する情報を要請したのか、または要請が
以前の仕事の完全な繰り返しに関するものなのかを決め
るために解析される。
部品または参照番号が突きとめられる)と、以前の仕事
の繰り返しが決定され、仕事に関する格納されている設
計と製造情報がデータベース30からステーション・モジ
ュールに転送され、ステップS.59に一般的に示している
ように、オペレータが見られるように表示される。ステ
ーション・モジュールは一つまたは一つ以上のメニュー
表示画面または登録簿をもち、オペレータがデータベー
ス30から検索された色々な情報を選択し、表示できるよ
うになっている。オペレータは表示された情報をレビュ
ーし、ステップS.61における3-D曲げシミュレーション
のような、色々なシミュレーションを走らせて、その仕
事の曲げ手順の色々な段階を観察し、部品の幾何学を理
解することができる。オペレータはまた、必要工具や仕
事情報に記録されている他の特別な命令やメッセージの
ような他の情報をレビューすることもできる。仕事情報
の確認が終わると、オペレータは曲げ、または他の必要
な機械類を構成し(組立)、機械を操作して指定された
薄板金属部品を製作することができる。データベース30
から検索された仕事情報は、たとえば曲げステーション
18の機械類を制御する曲げコードを含む最終曲げ計画デ
ータを含む。機械類の構成と実際の操作は、このように
して図5のステップS.63に一般的に示してあるように、
オペレータによって遂行される。
れず、情報が新しい仕事(つまりサーバー・モジュール
32には予備的な仕事情報のみ入力され、完全な仕事情報
が作成されていない)に関するものであることが決定し
た場合、部分的な部品情報と曲げモデルデータはデータ
ベース30から引き出されてステーション・モジュールに
送られ、ステップS.77でオペレータによって観察され
る。要請した情報は新しい仕事に関するものなので、オ
ペレータは必要な工具と曲げ手順を含む曲げ計画を作成
し、入力する必要がある。下記により詳しくのべるよう
に、曲げオペレータによる曲げ計画の作成を容易にする
ため、ステーション・モジュールにグラフイカル・ユー
ザー・インターフエース(GUI)や他の機能を備えるこ
とができる。GUIは、たとえば工具の選択、部品と工具
間の潜在的な不一致の自動点検、及び提案された曲げ手
順の各中間段階のシミュレーションを表示することによ
ってオペレータが曲げ計画を作成するのを支援するため
に設けることができる。サーバー・モジュールで曲げ計
画を作成し、入力したオペレータは、ステップS.80で曲
げコード(曲げ機械で曲げ手順を実行するためのCNCま
たはNCコード)を生成するために曲げ手順をプログラム
する。曲げコードは直接サーバー・モジュールで入力す
るか、曲げ機械類のCNCまたはNC制御装置とインター
フエースしてサーバー・モジュールに取り入れることが
できる。しかる後、オペレータはステップS.81で、曲げ
作業ステーションにおいてセットアップし、曲げ計画を
テストすることができる。曲げ計画に必要なすべてのテ
ストと必要な修正が完了すると、ステップS.83で最終的
な曲げデータをデータベース30に入力し格納する。最終
的な曲げデータは、曲げプログラムとともに、曲げ手順
と工具構成情報を含む。この情報は、たとえば曲げステ
ーション18のステーション・モジュールからデータベー
ス30に送られ、新しい仕事に関する他の設計製造情報と
ともに格納される。
の類似部品または同じ部品に関係しているが、たとえば
異なる参照あるいは仕事番号またはバッチ量等をもつこ
とが決定されれば、論理の流れはステップS.65に進む。
ステップS.65では、以前の仕事情報がデータベース30か
ら検索され、曲げステーション18で表示される。曲げオ
ペレータまたはユーザーはデータを見て、類似部品に必
要なデータの変更が何かを決める。この場合もステーシ
ョン・モジュールは一連のメニュー表示画面または登録
簿(ディレクトリ)を備えて、オペレータが、表示する
情報と、情報をどのように表示または修正するかの選択
ができるようにされている。たとえば、ステップS.69で
は、オペレータの類似部品の曲げ計画の作成を容易にす
るため、検索された情報にもとづいた3-D曲げシミュレ
ーションを備えることができる。以前の仕事情報をレビ
ューした後、オペレータはステップS.70で、曲げプログ
ラムとともに、工具と曲げ情報を修正する。部品の寸
法、参照番号やバッチ量のような他の仕事情報もステッ
プS.70で修正し、編集することができる。これが終わる
と、ステップS.71で実際の工具セットアップとテスト
が、オペレータによって作業場において、修正された曲
げ計画をテストするために行われる。テストと曲げ計画
をさらに修正することが完了すれば、オペレータはステ
ップS.73で最終的な曲げデータを入力し、それに新しい
参照番号または仕事番号をつけてデータベース30に格納
する。上記のように、以前の仕事情報もデータベース30
に、他の格納された仕事フアイルとともに保持できる。
さらに、色々なデータベース管理機能を、データベース
に格納されているフアイルを格納、消去、再命名等する
ために備えることができる。
教えるところに従って実行できる類似部品探索機能の例
を詳しく述べる。本発明の見地に沿って、特徴ベース形
態類似性探索アルゴリズムを利用する類似部品探索手続
きを、データベース30から以前の仕事情報を探索し、検
索するのに備えることができる。類似部品探索は製作さ
れる部品に関する設計特徴及び/または製造情報にもと
づいた同一及び/または類似部品の探索を含むことがあ
る。また類似部品探索は、たとえばサーバー・モジュー
ル32及び/または工場38内の色々なステーション・モジ
ュールにあるソフトウエアまたはプログラム化論理の使
用によっても実施できる。類似部品探索はサーバー・モ
ジュール32または薄板金属曲げ工場38内の場所10,12,1
4...20のいずれかで実行できる。C++またはマイクロソ
フト社のビジュアルC++プログラム言語のような、高レ
ベルのプログラム言語とオブジェクト指向プログラム技
法が類似部品探索の色々な処理や操作を実施するのに利
用することができる。
リズムまたは処理の論理の流れを示す。図6に示すよう
に、重要な部品モデルデータフアイルはステップS.100
でアクセスできる。部品モデルには、たとえば設計事務
所10に置かれたCADシステムで作成された曲げモデルデ
ータ及び/またはサーバー・モジュール32で作成され、
入力されたデータが含まれる。部品モデルには、たとえ
ば部品の色々な表面または面及び曲げ線の向き、幾何学
的関係及び相対位置を表す部品形態データ(部品トポロ
ジーデータ)が含まれる。部品モデルデータが検索さ
れ、または曲げモデルデータが手動で入力された後、ス
テップS.102で、当該部品の曲げモデル及び/または部品
形態データにもとづいた特徴抽出データを自動的に導出
するための特徴抽出操作を行うことができる。
は、薄板金属部品の色々な特徴を解析することによって
導出できる。たとえば、部品の色々な面の解析によっ
て、隣り合わせの面が開放または接触コーナーをもつか
どうかを決めることができる。平行曲げ、直列曲げ、共
線曲げまた対向曲げのような他の特徴も、各部品の明確
かつ独特な特徴を決定し、抽出するために解析すること
ができる。
る色々な曲げと面の特徴を示す。特徴抽出操作に含めな
ければならない抽出特徴は、正の曲げ、負の曲げ特徴と
ともに接触コーナー、開放コーナー特徴である。さらに
特徴抽出操作は、少なくとも平行曲げ、直列曲げ、共線
曲げ、異相共線曲げ及び厚さオフセット曲げの特徴解析
を含まなければならない。
各特徴の曲げモデルデータと形態(トポロジー)の解
析、形態の修正、今後の解析のための形態にもとづく特
徴ベース行列(特徴に基づく行列)の作成からなる一連
の操作を含むこともある。例証のため、図8(a)―9
(d)に接触コーナーをもつ4折り曲げ箱部品と開放コ
ーナーをもつ4折り曲げ箱部品に対する特徴抽出操作を
示す。
ー関係にもとづく特徴抽出が示されている。図8(a)
に示す五つの面(1-5)をもつ閉じた4折り曲げ箱や、図
8(b)に示す五つの面(1-5)をもつ開いた4折り曲げ
箱については、いずれの部品を表すにも、図8(c)に
示す同じ簡単な面形態が提供される。この形態は部品ま
たは曲げモデルデータとともに格納し、提供することが
できる。しかしながら、図8(c)の単純な面形態(面
トポロジー)は、部品の面(1-5)の間の関係の基本的な
情報しか与えず、隣接する面間のコーナーの関係や曲げ
の種類のような部品の色々な特徴の情報は与えない。従
って、特徴抽出操作時に、部品または曲げモデルデータ
とともに格納されている関連面形態をを解析することに
より、基本的な面形態が部品の色々な特徴についての付
加的な情報を含むように修正することができる。
箱の部品または曲げモデルデータを調べることにより、
隣接面間のコーナーが解析でき、図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゜負の曲げ角度等)も
行列の中に示すことができる。
操作は、曲げモデルデータと形態を解析することによっ
て、部品に色々な特徴が存在するかどうかを決めるため
に実施できる。本発明の見地に沿って、特徴抽出操作は
部品に提供されている曲げモデルと形態データについて
行うことができる。このデータは、面のデータ、曲げ線
データ(たとえば曲げ線長さと位置等)、面―曲げ線関
係データ、曲げ角度データ及び特別の特徴データ(たと
えば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、ビユー行列、半径、角度開始、角度
終了)で指定することができる。部品形態データも、部
品の色々な面や曲げ線の場所やこれらの間の幾何学的関
係を示すために提供することができる。各面は線と/ま
たは弧の集合または連結データリストで定義することが
できる。
形態データの特徴抽出操作を行い、解析することによっ
て、ある特徴が部品に存在するかどうかを定めることが
できる。このプロセスは、抽出する各特徴間の色々な特
色や関係にもとづく、曲げモデルと形態データの解析を
含むこともできる。各特徴の特色と関係を知るための曲
げモデルと形態データの解析によって、ある特徴(たと
えば面間の接触コーナー、開放コーナー特性、または平
行または直列曲げ特性)の存在が検出できる。異なるプ
ロセスを、各特徴の特定の特性と関係を特徴抽出操作で
検出するために備えることもできる。解析される各特徴
間の特性と関係の類似性にもとづいて、部品に一つ以上
の特徴が存在するかどうかをチェックするために幾つか
のプロセスを組み合わせるか作成することもできる。
おける特徴抽出操作の際に、コーナーの特徴、たとえば
同じ曲げ方向をもつ二つ面の接触コーナー特徴(表1のT
ouchCnr特徴)を抽出し、検出するために行うことがで
きるプロセスについて述べる。下記のプロセスは、他の
特徴の検出、たとえば逆曲げ方向をもつ二つの面の接触
コーナー特徴(表1のtouchCnr特徴)または同じまたは
逆曲げ方向を持つ二つの面の開放コーナー特徴(表1のO
penCnrとopenCnr特徴)に用いることもできる。プロセ
スを修正することによって、他の特徴も検出できる(た
とえば平行曲げ、直列曲げ等)。さらに、面の可能な各
組み合わせに関するデータを、抽出される各特徴の特性
と関係を知るために解析することができる。
hCnrの場合、検出する特徴または関係は:共通の面を持
つ二つの面;同じ曲げ線方向;同じ頂点を(または頂点
間の距離が事前に定めた範囲内にある頂点)をもつ曲げ
線を含む。接触コーナーの特徴をもつtouchCnrの場合、
同様の特性または関係を検出しなければならない;ただ
同じ方向の曲げ線をもつ面ではなく、面は逆方向の曲げ
線をもっていなければならない(たとえば表1をみ
よ)。開放コーナー特徴OpenCnrとopenCnrも同様に検出
できるが、各特徴に接触コーナー関係の代わりに、面間
に開放コーナーが存在する(たとえば面の曲げ線が事前
設定の範囲の距離より大きく隔たっている)ことと、同
じまたは逆の曲げ線方向(たとえば表1と表中のOpenCnr
とopenCnrの定義をみよ)をもつ曲げ線を検出し、解析
しなければならない。
r特徴)を検出するためには、先ずある二つの面を解析
し、二つの面が共通の面に接続しているかを決定する。
これは各面の曲げ線データと各曲げ線の曲げ線―面関係
データを探索して、共通面が存在するかどうかを決定す
ることによって検出できる。もし二つの面が共通の面に
接続していれば、各面の曲げ線方向を解析して同じ曲げ
線方向(または、たとえばtouchCnr特徴を検出する場合
は逆の曲げ線方向)をもつかを見る。これは、たとえば
各面の曲げ線方向を示すベクトルデータを解析する事に
よって決められる。
形態データにもとづいて同じ曲げ線方向をもつことが決
定されると、データを検査することによって曲げ線が平
行かどうかが検出される。色々な方法を用いて、曲げモ
デルと形態データにもとづいて曲げ線が平行かどうかを
検出することができる。たとえば、平行曲げ線の検出
は、曲げ線方向を定めるベクトルの外積をとることによ
って決められる。もしベクトルの外積がゼロ(または近
似的にゼロ)であれば、曲げ線は平行であると決定され
る。もしベクトルの外積がゼロでなければ(または近似
的にゼロでない)、二つの面の曲げ線は平行でない。
同じで曲げ線は平行ではないことが決まった後、面の間
のコーナーの関係(たとえば接触か開放か)を決めるた
めに、曲げモデルデータが解析される。二つの面のコー
ナー関係は、曲げモデルデータから、面の曲げ線が共通
の頂点をもつかどうかを検出することによって決められ
る。曲げ線が共通の頂点をもっていれば、二つの面は同
じ曲げ線方向の接触コーナー関係(表1のTouchCnr特
徴)をもつ。曲げ線は共通の頂点をもっているが、二つ
の面の曲げ線方向が異なることが決まれば、二つの面は
逆方向の接触コーナー関係(たとえば表1のtouchCnr特
徴)をもつと決められる。
でも、頂点間の距離が予め定められた範囲内であれば、
二つの面は接触コーナー関係をもつと決定できる。しば
しば部品の隣接する面の間に、たとえばパンチ工具を通
すためのすき間として最小限のスペースが設けられるこ
とがある。このスペースは、通常フランジの高さのとこ
ろでの工具の幅で決められる。例をあげれば、二つの面
の曲げ線の頂点間の距離が0-5mm以内であれば、接触コ
ーナー特徴の存在が決定できる。もし二つの面のコーナ
ー間のスペースが、事前に定められた範囲より大きけれ
ば、開放コーナー特徴の存在が決定できる(たとえば表
1のOpenCnrまたはopenCnr特徴)。
合わせについて、各面のコーナー特徴を決めるために実
施することができる。部品の面や曲げ線に関連する他の
特徴も、同じように部品幾何学と形態データの解析によ
って行うことができる。ステップS.102における特徴抽
出操作を実行するための典型的なコードを付録Aに示
す。このコードはC++プログラム言語で書かれており、
表1に記してあるような特徴を抽出検出するための色々
なプロセスを含む。付録Aのコードには、使用されてい
る論理やアルゴリズムの解析を容易にするためのコメン
トがついている。またこのコード例では、色々な特徴の
理解を助けるために、表1と同じ特徴の用語が使われて
いる。
基本的な形態は修正され、抽出された特徴が含められ
る。特徴ベース形態を提供することは有用かもしれない
が、このような形態をお互いに比較することは容易でな
い。その代わりに、本応用の発明者達は行列の形で提供
された特徴抽出情報を比較する方が、より有効で容易で
あることを発見した。従って、本発明の一つの特徴とし
て、特徴抽出操作の際に、検出された特徴にもとづいた
特徴ベース部品行列(図9(c)と9(d)に示す代表
的な行列のような)が作成される。作成された部品の特
徴ベース行列は、他の所定の、格納された行列と比較す
ることによって、どのような基本的な形や特徴が部品に
含まれているかを決定する。
出し、抽出した後に、部品毎に作成され、格納される。
図9(c)と9(d)に示すように、行列は対称的な2
次元行列で部品の面の数に等しい次数をもつ。行列は部
品のすべての検出された特徴情報を含み、各面の間の色
々な特徴が行列の各場所に提供されている。特徴ベース
行列は、一時的にサーバーまたはステーションモジュー
ルの記憶装置に格納し、類似部品探索を実行するときに
のみ使用し、所定の行列と比較することができる。ある
いは、特徴ベース部品行列を永久的に他の仕事情報とと
もにデータベース30に格納し、工場内のどの場所でもア
クセスできるようにすることができる。
引き出した特徴抽出データ行列を、特徴形態ライブラリ
に備えられている所定の特徴抽出データ行列と比較する
ことができる。特徴形態ライブラリは、別のデータフア
イルとして、データベース30のようなデータベース、ま
たはサーバー・モジュールかステーション・モジュール
に格納しておくことができる。特徴ライブラリは、基本
的または基礎的な部品の形状(たとえば4折り曲げ箱、
橋梁等)に対応するまたは定義する特徴抽出データを含
む所定の行列よりなる。各所定特徴ベース行列は、特徴
ベース部品行列とともに、ASCIIまたはテキストフアイ
ルとして格納できる。ステップS.104のおける比較は、
ステップS.106に図示されているように、薄板金属部品
に存在する基本的または基礎的な形状/特徴を決めるた
めに行われる。格納されたルックアップテーブルを、ど
の基礎的な形状が各所定特徴行列に対応するかを示すた
めにを備えておくことができる。一致するものが見いだ
されると、ステップS.106でどの基礎的形状が存在する
かを決めるために、ルックアップテーブルがアクセスさ
れる。事前定義ライブラリに存在する一致する行列は、
特徴ベース部品行列と同じ次数であるか(この場合は部
品はただ一つの基礎的形状を含み、精確に対応すること
が決定される)、または部品行列のサブ行列かもしれな
い(この場合は部品は一つ以上の基礎的形状を含むかも
しれない)。
にある行列と比較するために再帰プログラミング技法を
利用することができる。含まれている情報を比較すると
き、行列の指標を入れ替えることによって、データ割り
当ての使用が避けられ、必要なプロセス時間が短縮され
る。再帰プログラミング技法と指標の入れ替えはまた、
異なる次数と異なる基底面をもつ行列の比較を容易にす
る。
実施される比較操作は、一連の比較よりなり、最初によ
り複雑な形状(たとえば多数の曲げ、またはタブのよう
な複雑な成形を含む形状)に関する行列の比較から開始
し、より複雑でない形状(たとえば、より少ない曲げ、
またはより複雑でない曲げ、より少ない数の面をもつ形
状)へと進む。この一連の比較は部品に、所定数の基本
的形状が見いだされるまで行われる。たとえば、比較操
作はある特定の部品の三つの最も複雑な特徴または形状
を抽出するために行うことができる。さらに、この操作
を最初に、薄板金属部品によく、または度々みられる形
状に関する行列のグループに対する一連の比較から始
め、次により一般的でない形状に進むこともできる。部
品を事前定義ライブラリと比較するために、色々な方法
を有用な結果をうるために行うことができる。
直角曲げを持つ長方形や正方形形状や直角曲げをもつ単
純な部品のような、直角曲げをもつ基本形状を含む行列
の直角グループに適用することができる。この行列のグ
ループは、グループの中の、より複雑な行列(たとえ
ば、タブをもつ四つ折り曲げ箱に対応する行列)からグ
ループの中のより単純な行列(たとえば、単純ハット部
品に関する行列)へと進める一連の比較にもとづいて探
索することができる。それから一連の比較を多角形部品
グループの行列に、さらに特別特徴グループの行列へ適
用することができる。多角形部品グループは五つ以上の
側面と、少なくとも90度以上の曲げを一つもつ部品を定
める行列を含みうる。特別特徴グループの行列は、Z―
曲げまたは縁取り曲げのような、特別な特徴または成形
をもつ部品に関係する事前定義ライブラリ内の行列を含
みうる。ここでもまた、部品の特徴ベース行列と各グル
ープの所定行列との間の一連の比較は、複雑性の度合い
の減少に従って行われる。この後に、部品の一つの面に
二つまたは二つ以上の特徴をもつ多重特徴グループのよ
うな、所定行列の他のグループを比較することができ
る。
イブラリの行列と比較し、実現と使用頻度にもとづく行
列のグループの一連の比較をすることによって、部品に
存在する基本的な形状の決定するためのライブラリとの
より効果的で有効な比較ができる。さらに、検出特徴の
重複が防がれ、より複雑な形状のみが識別される。
特徴または形状間の関係を決めるために特徴関係操作を
行う。特徴または形状間の関係は距離によって定められ
る。二つの形状間の距離は、各々形状の基底面(基本
面)の間の曲げ線または面の数にもとづいて決められ
る。あるいは、特徴間の関係は、部品及び、各特徴の基
底面の相対位置と間隔を幾何学的に解析することによ
り、特徴間の物理的な距離または実際の寸法によって定
めることができる。
品の三つの最も複雑な特徴または形状は、図10(a)
に示す4折り曲げ箱と、ブリッジと、もう一つの4折り曲
げ箱とであるとしよう。このような部品については、特
徴関係操作を、たとえば各基本的特徴の基底表面または
面の間の曲げ線の数を決めるために行うことができる。
図10(b)で示すように、第一の4折り曲げ箱の基底
(1)とブリッジの基底(2)の間の特徴関係は、二つの
曲げ線の間隔である。さらに、第一の4折り曲げ箱の基
底(1)と第二の4折り曲げ箱の基底(3)の間の関係
は、四つの曲げ線の間隔であり、ブリッジの基底(2)
と第二の4折り曲げ箱の基底(3)の間の関係は、二つの
曲げ線の間隔である。
形状の基底面間の曲げ線の数を決めることができる。た
とえば、特徴ベース部品行列と所定形状行列を利用し
て、ステップS.108で特徴関係を決めることができる。
最初に、部品行列にある各基本形状に対応する基底面を
捜し出す。これは所定形状行列の基底面を、部品行列の
面指標と相関することによって行うことができる。前に
論じたように、比較操作で切り離した所定形状行列は、
部品行列のサブ行列かもしれない。部品行列で各基本形
状に対応する基底面を捜し出すには、部品行列内の形状
行列の位置と行列の指標の間の相関を解析する。各基本
形状の基底面は、予め定められており形状行列の第1列
に位置しているので、部品行列内の対応する位置と基底
面を捜しだすことができる。
面を決定した後、特徴関係を決めるために、各形状の基
底面間の距離を解析する。この解析は、如何なる二つの
基底面間の距離をも同定する探索プロセスを含んでい
る。部品行列内の特徴と曲げ線情報を見ることによっ
て、どの二つの基底面間の曲げ線の数でも決定できる。
二つの面の間に一つ以上の経路が可能な場合には、最小
距離を用いてステップS.108において特徴関係を定義す
ることができる。
テップS.110に続く。図7に示すように、ステップS.110
では、データベースの類似部品探索に用いる探索キーを
決めるために、データベース探索キーの同定が行われ
る。探索キーは、部品に同定された特徴や特徴関係の幾
通りもの組み合わせを含みうる。さらに、探索キーをア
センブルするのに、どのような基準の階層も用いること
ができる。限定されない例として、下記の基準に従って
探索キーを作成することができる:(i)部品に同定さ
れた一番目と二番目に複雑な特徴または形状;(ii)最
も複雑な二つの特徴間の距離または特徴関係;(iii)
部品に同定された三番目に複雑な特徴または形状;及び
(iv)部品に同定された一番目に複雑な特徴と三番目に
複雑な特徴間の特徴関係または距離、及び二番目に複雑
な特徴と三番目に複雑な特徴間の距離または特徴関係。
図10(c)に図10(a)の例にもとづいて開発され
た探索キーを示す。
探索キーは、形状ライブラリで定義された色々な基本形
状に割り当てられた所定コードをもつ整数の列で表すこ
とができる。たとえば、4折り曲げ箱に整数コード“1
6”が割り当てられ、ブリッジに整数コード“32”が割
り当てられたとしよう。この場合、図10(c)の例の
探索キーは、整数列“16,16,4,32,2,2”で表され、この
なかで“4”と“2”は基本形状または特徴間の色々な距
離を表す。しかしながら、探索キーの表示は、整数列に
限定されるものではなく、どのような組み合わせの整数
及び/または文字列を探索キーの表示に用いることがで
きる。
(別のフアイルまたは同じフアイルに)、データべー
ス、たとえばデータベース30、に格納できる。特徴抽出
データの代表的な探索キーは、手動で入力するか、上記
のように自動的に作成できる。特徴ベース部品行列のよ
うな付加的特徴抽出データは、探索キーを用いて格納で
きる。探索キーが別のフアイルに格納してあるときに
は、各探索キーのセットと関連する部品情報を捜し出す
ための参照用テーブルを用意できる。あるいは、探索キ
ーは部品情報を同定する(たとえば部品または参照番号
によって)データフイールドとともに格納しておくこと
ができる。
にもとづくデータベースの協調探索が行われる。協調探
索は、協調データベース探索技法を用いる探索である。
協調探索技法は、同一の探索キーをもつ部品ばかりでな
く、類似の探索キーを持つ部品を捜し出す。これによっ
てデータベースにある、類似および同一部品を同定する
ことができる。特定の部品についての探索を行うと、そ
の部品のものと同定された探索キーを、データベースに
ある他の探索キーデータと比較することができる。ステ
ップS.112で行われる協調探索は、探索キーの順序を緩
めるか修正することによって、データベースにある項目
で、探索キーによって同定された特定の部品と正確に一
致するか又は最も類似している項目を同定するように構
成される。色々なプロセスと方法を、協調探索において
探索キーを適合させるのに用いることができる。たとえ
ば、最初にデータベースの探索を、探索する部品のもの
と同定されたものと正確に一致する探索キーの順序をも
つ部品を同定するために行うとする。これは同定された
探索キーをデータベースに格納されている探索キーと比
較することによって行われる。同じ探索キーをもつ部品
(もしあれば)を同定した後、引き続き他の類似部品を
捜しだすために、異なる修正された探索キー順序に基づ
くデータベースの探索を行うことができる。最初探索キ
ーにある、あまり重要または敏感でない項目または基準
(特徴関係または距離のような)は、より重要または敏
感な探索項目(部品にある基本的な特徴または形状のよ
うな)を修正する前に修正し、探索することができる。
さらに、これらの各項目は、項目の重要度に従って修正
し、部品にある一番目と二番目に複雑な特徴または形状
に関連する項目に、より高い重みまたは重要度を当てる
ことができる。たとえば、ひき続き最初に行う探索は、
三番目に複雑な特徴と一番目、二番目に複雑な特徴間の
定義された距離を修正した後に行うことができる。この
距離は、所定曲げ線数(たとえば1-3)だけ変更し又は
現在の距離に基づいた距離の所定範囲を定義することに
よって修正できる。しかる後、一番目と二番目に複雑な
特徴または形状間の距離を変更して、データベース探索
用の修正された探索キーの組をもう一つ備えることがで
きる。部品の特徴関係または距離の探索キーを修正した
後、同定された形状を、協調探索における付加的な修正
探索キーを導くために変えることができる。たとえば、
三番目に複雑な特徴または形状に関する探索キー項目
を、現在扱っているものの特徴または形状によって、関
連するがより複雑でない形状に変えることができる(た
とえばタブのある4折り曲げ箱を単純な4折り曲げ箱
に)。さらに、一番目と二番目に複雑な特徴の探索キー
を同じように変えることによって、さらに協調探索のた
めの修正探索キーを加えることができる。
協調探索中の修正は、いろいろな方法と技法によって実
行できる。上記のように、どのくらい距離を変えるか
は、距離の現在値に依存する。距離の大きさ(たとえば
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)にあり、そ
こに開示されている情報すべてを参照することによって
ここに取り入れられている。
を実施するこができる。たとえば、部品の特徴に関連し
ていると同定された探索キーに基づいたデータベースの
探索に加えて、部品の製造情報に関連した探索基準に基
づいて探索することもできる。たとえば、付加的な探索
キーを利用して、一例として各部品に必要な機械構成を
比較することができる。機械構成情報は機械のタイプま
たは部品を製作するために必要な機械類、部品を製作す
るために用いる工具類や工具構成および/または機械類
のバックゲージング設定を含む。付加的探索キーは、機
械構成情報および/または他の製造情報に基づいて開発
することができ、本発明の協調探索をする際に、同定さ
れた探索キーとともに用いることができる。その結果、
製作される部品と同一または類似な部品は、部品の設計
と製造特徴両方に基づいて同定することができる。
探索をステップS.114で実行し、協調探索の結果のより
詳しい比較と、探索された部品と同じまたは最も類似し
ている部品を所定数だけ選ぶ。選択部品探索は、協調探
索で同定された各部品に対する付加的な情報や特性の解
析を伴いうる。これは部品の寸法や部品にある孔や開口
の形のような、捜し出された部品の色々な特徴の解析を
含む。さらに各部品に要する機械構成のような、捜し出
された各部品の製造情報の比較も含みうる。上記のよう
に、機械構成情報は、部品の製作に要する機械の種類ま
たは機械類、部品の製作に用いる工具や工具構成、及び
/または機械類のバックゲージング設定を含む。選択部
品探索を行うために、各部品の曲げモデルや他の仕事情
報が、協調探索で同定された探索キーに基づいてデータ
ベースからアクセスされる。上記のように、各探索キー
の組に対応する仕事参照番号またはコードを提供するた
めに、ルックアップ表や付加的データフイルドを設ける
ことができる。データベースから部品情報を検索した
後、各部品の付加的情報(たとえば部品寸法、材料のタ
イプ、特別な成形、部品の孔または開口等)を、どの部
品が探索された部品に最も類似しているかを決めるため
に解析できる。このプロセスはオプションで、データベ
ースの部品で、当該部品に最も類似の部品を選び集約す
る付加的な選択プロセスの役割を果たす。この部品の付
加的情報または特性を解析し、照合することによって、
選択部品探索を、所定の数または組の最類似部品を同定
または選択するために行うことができる。たとえば、選
択部品探索で、照合探索キーの数と付加的部品特性の照
合に基づいて、五つの最類似部品を同定できる。選択部
品探索で選択される部品の数は五つに限らず、工場の必
要性とデータベースに実際に格納されている部品の数に
基づいて選ぶことができる。この数は、より有効で役立
つ探索結果をうるために選択的に修正でき、またユーザ
ーに探索の組を変えるために、この数を修正する機会を
与えることもできる。
で部品をランク付けする(特徴の類似性や突き合わせ探
索キーの数に従って)ために、類似性指標を計算するこ
とができる。類似性指標はステップS.116で計算され、
サーバーまたはステーションモジュールの出力として提
供され、これによってユーザーはどの仕事フアイルをデ
ータベースから検索し、画面に映し出すかを選択でき
る。類似性指標によって、選択された部品と探索部品の
特徴の類似性の程度に基づいて、選択部品のランク付け
(たとえば各部品の仕事または参照番号を付してランク
1から5)ができる。このためには各部品の特徴ベース行
列を探索部品のものと比較する。特徴ベース行列の比較
は、選択部品と探索部品の間の類似性をよりよく示す。
前のべたように、特徴ベース部品行列は各部品の探索キ
ーとともに格納できる。しかしながら、各以前の仕事の
特徴ベース部品行列を探索キーとともに永久格納するこ
とは、不必要に大きな記憶スペースを占有する(特にデ
ータベースに多数の部品が格納されている場合)。従っ
て各部品の探索キー・データのみを格納し、類似部品探
索を行うときに自動的に各選択部品の特徴ベース行列を
生成することしかできない。 従って、選択部品の曲げ
モデルと他の仕事情報を検索した後、前にステップS.10
2についてのべたように、特徴ベース行列は本発明の特
徴ベース抽出操作を通じて作成する。そのあとで、類似
部品探索時に一時的に格納した探索部品の特徴ベース行
列を、作成した選択部品の特徴ベース行列の各々と比較
できる。色々な方法とプロセスを、部品の特徴ベース行
列の比較と部品間の類似性の決定に利用できる。たとえ
ば、各選択部品の特徴ベース行列について、行列内の場
所を探索部品のものと比較できる。行列内の各場所は、
再帰的プログラム技法に基づいて比較できる。行列内の
情報は、各行列内の対応する基底面の場所を決め、行列
の指標を交換することによって比較できる。選択部品は
探索部品の副特徴に対応するか又はその形状をもつこと
もあり、又行列の指標が同一でないか、または同じ番号
付けがされていないこともあるので、含まれている情報
を比較するときに、部品行列内で比較できる面を捜しだ
して指標を振り替えなければならない。さらに探索部品
の中に一つ以上の副特徴が存在する場合、行列内の情報
を比較するとき、同じ次数の行列を提供するために、一
つまたは一つ以上の擬似面(行列の行と列で情報が無い
か空白のもの)を導入しなければならないことがある。
と探索部品の類似性の程度を決めるために、複数の異な
る順序づけ方式を用いることができる。たとえば、所定
ペナルティレベルまたは量を、行列内の整合しない各位
置に割り当てるペナルティベース順序づけ方式を用いる
ことができる。行列内のすべての情報を比較した後、各
選択部品の総ペナルティレベルを用いて類似性の程度を
決めることができる。最も低いペナルティレベルをもつ
選択部品が、探索部品に最も類似した部品と決定され
る。他の選択部品も、各部品に付せられた総ペナルティ
レベルに基づいて順序づけできる(たとえばペナルティ
レベルが低いほど類似指標が高い)。
位置のペナルティレベルは、その位置にある情報のタイ
プに基づいて割り当てることができる。ペナルティレベ
ルは整数量で非整合情報の重大性または重要性に応じて
変えることができる。たとえば、異なる、関係のない特
徴グループ(たとえば平行曲げ特徴対直列曲げ特徴)に
関する非整合位置に対しては、高いペナルティレベルま
たは量を割り当てることができる。これと対照的なの
は、異なるが類似の特徴グループ(たとえば同じ曲げ線
方向をもつ接触コーナー特徴対逆の曲げ線方向をもつ接
触コーナー特徴)である。ペナルティレベルまたは量
は、非整合位置に存在する情報のタイプと相違のタイプ
に従って事前に定義、類別される。
典型的なコードは付録Bに示されている。このコードはC
++言語で書かれており、上に記述した行列の比較と非整
合位置に対するペナルティレベルの割り当てに関する色
々なプロセスと操作を含んでいる。上に付記したよう
に、比較された各選択部品の結果としてえられた総ペナ
ルティレベルは、類似性指標を導き、表示するのに用い
ることができる。付録Bにあるコード・リステイングに
は、記されている典型プログラム・コードの理解を助け
るためのコメントも含まれている。
デルの開発と、色々な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モデルを作成するのに利用できる。
ルゴリズムを用いて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によって自動
クリーニングやクリーンアップ機能を実施することもで
きる。
機能は、2-D平面図を、処理に対して準備するために備
えられている。2-D平面図は、薄板金属部品の展開状態
の2-D表示で、部品の幾何学を構成し表現する線及び曲
線の如き部品要素(エンティティ)を含むとともに、部
品に存在する開口または孔の位置を示す。通常このよう
な2-D平面図の構成要素(エンティティ)は、CADまたは
CAD/CAMシステムを使用して入力し、作成する。しか
し、2-D平面図を作成するとき、このような要素はしば
しば誤って連結または重ね合わされ、一つの要素が一つ
以上の面の境界を示すのに用いられることがある。さら
に、部品の境界を決めている外側線が、境界の隣接する
コーナーで分断されていて、部品と各面の外側の寸法の
検出を難しくしている。さらに、2-D平面図は、寸法情
報やテキストのような本質的でない情報を含みうる。こ
のような異常は、元の2-D図面を正確に解析し、部品の
面や曲げ線を均一に検出するのを難しくする。本発明の
自動トリミングとクリーンアップ操作を備えることによ
って、各面は連結された要素の一義的なセット(セッ
ト)で表現できる。その結果、2-D平面図は、引き続き
行われる処理と最終的に行われる3-Dモデル表現作成の
ための折りたたみのために、より簡単かつ効率よく解析
できる。
間のトリミングがされておらず、図中の一つの線要素が
一つ以上の面の外側境界または複数の境界を定めている
ことがある。上記で論じたように、このような配置は各
々の面の検出を困難にする。本発明の自動トリミング機
能は、連結性情報を決定し、上記のような要素を交点で
断ち切るために、各部品要素(線、弧や曲げ線のよう
な)の終点と交点を解析するのに備えられている。この
ようなトリミング機能は、断ち切られた各要素の終点を
決められた交点に設定する機能ももつ。たとえば、図1
2に図示されている交点をトリミングすることによっ
て、各々が交点に終点を共有する三つの要素(二つの線
と一つの曲げ線)がえられる。このようなトリミング機
能を備えることによって、要素解析と連結に基づいて部
品の面をより容易に検出することができる。実施できる
面検出操作のさらに詳しい記述は、下記に図15(a)
-16(c)を参照しながら提供される。
要素の交点を検出することができる。このようなプロセ
スは、2-D図面のフアイルのデータのフオーマットと配
列に基づいて作成できる。通例2-D平面図は幾何学デー
タ(色々な部品要素を定義する)と非幾何学データ(た
とえばテキスト等)を含む。幾何学データは、データの
各行またはシーケンスにあるキーワードによって非幾何
学データと区別できる。このようなキーワードは2-D図
面のデータ書式に従って設定される。2-D、3-D図面によ
く用いられる書式としてDXFとTGES書式がある。各要素
の幾何学データを解析することによって要素の終点や交
点が検出でき、適当であればトリミングができる。
素は終点及び/またはベクトルで定義できる。たとえば2
-D平面図では、各2-D線は2-D終点の組(たとえばX1,Y1
とX2,Y2)で特定することができ、曲げ線は曲げ線の2-D
空間位置とともに方向を示すベクトルで表すことができ
る。さらに2-D弧は2-D空間データ(たとえば中心X、中
心Y、半径、開始角度、終了角度)で特定することがで
きる。幾何学データはまた、色々なタイプの線要素(た
とえば弧、実線、破線、鎖線等)を区別する属性をも
つ。通常弧要素は薄板金属部品の孔や開口を、実線は部
品の境界や形状を示すのに用いられる。曲げ線は普通破
線で示され、部品の中心線は鎖線で示される。
要素の交点を決めることができる。データ割り当てやデ
ータ反復のような、色々なデータ解析手法を2-D図面の
各要素の幾何学データの解析に用いることができる。各
要素の終点及び/または他の2-D空間データに基づいて、
線や他の要素が交差するかどうかを決める簡単な幾何学
解析をすることができる。二つの要素が交差することが
決まれば、各要素を決定された交点で断ち切り、残った
要素の終点には交点で定められた共有点を割り当てるこ
とができる。
された要素のタイプに基づいて行われる。たとえば二つ
の実線が交差することが検出されると、図13(a)に
示すように、各線要素を断ち切ることによって、定めら
れた交点で接する四つの線要素がえられる。また線要素
と弧要素が、図13(b)に示すように交差することが
決まると、各要素を断ち切ることによって共通の終点を
もつ二つの線要素と二つの弧要素をうることができる。
しかしながら、要素の交差が検出されても、トリミング
を必要としないこともある。たとえば、如何なる要素で
も中心線(たとえば鎖線要素)と交差することが決定し
た場合、どの部品の中心線も部品の面または曲げ線を定
めたり区別したりすることはないので、トリミングの必
要はない。また、連結しない要素でも、開いている交点
または面積が、所定の許容度内であれば切断できる。た
とえば、潜在的に交差する線の終点が、実際に他の要素
と交差するときの交点と、事前に定義した許容度または
距離ε(たとえば0.0-0.01mmまたは0.0-0.001インチ)以内
であれば、要素は投影された点で連結交差しているもの
と扱ってよい;そしてたとえば図13(c)に示すよう
に、要素を断ち切ることができる。
を、非連結要素を検出し修正するためにクリーンアップ
機能で処理することができる。しかしながら、本発明は
このような処理のみに限られていない;処理時間を短縮
するためにクリーンアップ機能を、各要素が解析されて
いる間に、自動トリミング機能と同時に行うことができ
る。クリーンアップの間に、2-D図面の幾何学データ
が、隣接する要素間の開いた交点または領域を検出する
ために解析される。自動トリミング機能と同様に、要素
間の開いた交点の領域を検出するために、各要素の終点
や他の2-D空間データも解析できる。このようなデータ
に簡単な幾何学的解析を加えることによって、要素の終
点が互いに事前に定義した許容度または距離(0.0-0.01
mmまたは0.0-0.001インチ)内にあるかどうかが決定でき
る。要素の終点がこのような開いた交点をもつことが決
定されると、要素を連結し、図14に示すように共通の
終点を割り当てることができる。
ように行うかは、開いた交点をもつことが検出された要
素のタイプによる。二つの実線が開いた交点をもつこと
が検出された場合、各終点に共通の終点を割り当てるこ
とができる(たとえば図14を見よ)。しかしある要素
が部品の中心線(たとえば鎖線要素)と開いた交点をも
つことが決まったときには、要素を連結したり共通の終
点を割り当るべきでは無く、中心線は無視しなければな
らない。またクリーンアップ機能は、2-D図面から非幾
何学データ(テキスト等)を消去するための付加的なプ
ロセスまたは操作を含みうる。前述べたように、非幾何
学データは、2-D図面データとともに用意されているキ
ーワードに基づいて幾何学データと区別できる。クリー
ンアップ機能にはまた、後で本発明の2-Dクリーンアッ
プ機能を参照しながらより詳しく説明するような、他の
クリーンアップ機能を組み込むことができる(たとえば
図21-23(b)を見よ)。
ンアップ機能を行った後、ステップS.124で処理された2
-D図面について面検出の手続きを行うことができる。本
発明の見地に沿って、面検出手順は要素(線や弧)とル
ープ解析に基づいた部品の面の検出と定義付けを含む。
図15(a)-16(d)に面検出手続きで行われる色
々なプロセスと操作の例を示す。ループ検出技法を本発
明で部品の面を検出し、決定するのに用いることができ
る。面検出手続きは、たとえばサーバー・モジュール32
にあるソフトウエアまたはプログラムされた論理によっ
て実施できる。
ループ検出解析に引き続く、部品の最小または内側ルー
プの解析を用いて、面の各々を検出できる。薄板金属部
品のユニークな幾何学のため、面と部品にある開口は、
相対的極大(たとえば外側)と極小(たとえば内側)ル
ープの順序の解析によって検出することができる。下記
に論じるように、ループ解析は部品の線と弧要素の連結
性にもとづいて行うことができる。ループ解析を部品の
外側から部品の中心に向かって行うことにより、部品の
開口や面を、循環順序(たとえば面材料、開口、面材
料、開口等)に従って定義されたループ間の境界に基づ
いて検出することができる。
各種の線要素を含む2-D平面図が提供されたとしよう。
上記のように、ループと要素解析は部品の外側から始め
るように行う。部品の外側境界にあるどの要素を初期参
照点にとってもよい。限定されない例として、図15
(b)に示すように、最も左側の線要素を検出し、初期
参照点に用いる。最も左側の線要素は、2-D図面にある
各要素の幾何学データを比較し、どの要素が最も小さい
X座標の値をもつかを決めることによって検出できる。
最も左側の線要素を検出した後、点P1から部品の外観が
導かれ、図15(c)に示すように部品の外側境界を検
出される。点P1を決めるには、最も左側の線要素のいず
れの終点を用いてもよい。図15(c)に示す実施例で
は、上側の終点(つまり最も大きなY座標の値をもつ終
点)が点P1に用いられている。
のには、通常のループ解析技法を使うことができる。た
とえば、リード線ベクトルを、部品の外観を追ってゆく
に従って、始点P1と連結している要素の終点から投影し
てゆくことができる。一つ一つの要素が検出され、通過
される毎に、要素が選ばれたことを示すフラグを設定す
ることができる(たとえば記憶内のフラグは、一度選ば
れたことを示すために1に設定する)。ループの経路は
始点P1からどちらの方向にも始められる。たとえば、リ
ード線ベクトルを点P1から反時計方向(たとえばリード
線ベクトルをY座標方向に投影する)に投影することが
できる。ループはループ経路が始点(つまり点P1)に戻
ったところで完結する。
ルを反時計方向に投影できる(たとえば最初のリード線
ベクトルをY座標方向から始めることによって)。引き
続きループの経路にある最初の要素を検出するために、
各未検出要素が点P1のまわりにリード線ベクトルとなす
角度を座標枠に基づいて測定し、解析してリード線ベク
トルと最も小さい角度をもつ要素を選ぶ。外側ループで
は、 各角度は要素線がリード線ベクトルとなす外側角
度を測る。点P1の回りの要素は、どの要素が点P1と終点
を共有するかによって決められる。各要素の未選択状況
は、各要素に付したフラグを解析することによって決定
できる。図15(c)に示すように、図示の2-D図面例
では二つの要素線(X座標方向のものとY座標方向のも
の)がP1のまわりにある。これらの要素の解析では、Y
座標方向の線要素が、リード線ベクトルとなす角度(0
度)が他の線要素がなす角度(270度)より小さいので
選ばれる。
の終点に進み、選択されたことを示すためにフラグが設
定される。その終点で、別のリード線ベクトルが投影さ
れ、その点のまわりの非選択要素を比較することによっ
て、どの要素がリード線ベクトルと最小の角度をもつか
を決める。ここでもまた、角度はリード線の外側から測
り、座標フレームを用いて角度の大きさを決める。弧要
素に出会った場合は、リード線ベクトルの外側から弧の
接線までの角度を測らなければならない。また、次の終
点にある要素が一つのみであれば(部品のコーナー位置
のように)、比較の必要はなく、単にその要素を選択し
てループに含めればよい。
れ、選択された各要素は、ループ内の要素の連結性を示
すためにリンクされたリストに含めることができる。経
路が始点P1に戻るとサイクルは完了し、外観と、部品の
外側境界を示す要素または線のリンクされたリストに基
づいてループを(L4)と定義できる。ループL4内の各線
または要素は、各終点で連結できる。ループL4の方向
を、外側ループであることを示すために、図15(d)
に示すように、反対方向(つまり時計方向)に変えるこ
とができ。ループの方向は、ループL4で線がリンクされ
る順序に基づいて定義することができる;従って方向
を、リンクされたリストの順序を逆にすることによって
変えることができる。
いたのと類似のプロセスで部品の内側ループの解析を行
うことができる。ただ内側ループの解析では、各非選択
要素は各要素がリード線ベクトルの内側となす角度に基
づいて比較される。さらに、内側ループ解析では、ある
点のまわりの両方の要素がすでに選択されていると示さ
れた場合(たとえば面を境する二つの外側線要素を比較
するとき)でも、二つの要素が既に二度選択(2のフラ
ッグ設定)されてない限り、二つの要素を比較すること
ができる。少なくとも一度選択された要素(たとえば外
側要素)と選択されていない要素の場合は比較は行わ
ず、非選択要素をループの一部分として選択する。図1
6(a)-16(c)に、図15(a)に示す部品の面
を検出し、規定するのに行うことができる内側ループが
例示してある。
らでも、あるいは選択されていない要素を検出すること
によって開始することができる。たとえば点P1を、内側
ループ解析の始点に選び、リード線ベクトルを投影する
のに用いることができる;あるいは外側ループ解析の際
に選ばなかった内側の線要素の一つも解析の始点に用い
ることができる。外側ループ解析と同じように、リード
線ベクトルを反時計方向(たとえば一番目のリード線ベ
クトルをY座標方向から始める)に延ばしてゆくことが
できる。次いで点P1のまわりの各要素を比較し、どの要
素がリード線ベクトルと最小の角度をもつかを決める。
リード線ベクトルとなす角度を決めるのに、座標枠を用
いることができる。前記のように、内側ループ解析に際
には、要素の比較は各要素がリード線ベクトルの外側で
なく、内側となす角度をもとに行う。最初の要素が選ば
れ、ループのリンクされたリストに含めたら、そのフラ
グを1だけ増分し、つぎのリード線ベクトルを投影する
ことによって解析を進めることができる。このプロセス
はループが最初の始点に戻るまで続けられ、そこで第一
の内側ループが、対応する要素のリンクされたリストに
よって定義(たとえばL1)される。
側ループ解析を行うことができる。次の始点は、どの要
素が一度しか選ばれていないかを決めることによって選
ぶことができる。二度選ばれたフラグをもつ要素は、そ
の要素がすでに外側ループ(たとえばL4)と少なくとも
内側ループの一つ(たとえばL1)で選ばれた外側要素で
あることを示す。ここでもまた、各要素が選ばれるたび
に、それが内側ループのリンク・リストに含まれたこと
を示すために、フラグを1だけ増分する。
えば図16(c)の例ですべての要素が二度選ばれた
後)、えられたループを用いてループツリー(ループ
木)を作成することができる。図16(d)に、検出さ
れたループL1-L4に基づいて作成したループツリーの例
を示す。部品の外側ループ(L4)はツリーの根(ルー
ツ)と定義し、外側ループと共通の要素をもつ各内側ル
ープ(L1-L3)は、根の子どもと定義されている。共通
要素の存在は、各ループを規定する要素のリンクされた
リストの解析と比較によって検出できる。内側ループ内
に、さらに要素(たとえば孔または開口)が検出された
場合には、これらのループを、それが位置する内側ルー
プの子ども(つまりループツリーの根の孫)と定義する
ことができる。
後、ステップS.126で曲げ線検出操作を行うことができ
る。たとえば図17に示すように、ステップS.124で部
品のループを検出し解析するときに、本発明の面検出論
理は、面情報を規定し、検出された面を曲げグラフ・デ
ータ構造にノードとして格納するのに、ループツリーを
利用することができる。部品の面は、ループツリーにお
ける外側と内側ループの順序から検出できる。上記のよ
うに、各ループは要素または線のリンクされたリストを
含む。これらの要素は、部品の各面の境界を定めるのに
用いられる。従ってステップS.126において曲げ線検出
操作を行い、部品の面と曲げ線の間の関係を決めること
ができる。ステップS.126の曲げ線検出操作は、ある二
つの隣接する面が共有する端または線要素を検出するこ
とによって、部品の色々な面間のすべての曲げ線を検出
する曲げ線検出論理を含むことができる。また一つ以上
の領域で接続している面(たとえば3-Dモデルに曲げ線
検出アルゴリズムを適用する場合―たとえば下記に論ず
る図19を見よ)については、いろいろな発見的方法
(ヒューリスティク)を適用して、部品の曲げ線の最小
数を検出し、選択することができる。検出された曲げ線
は、たとえば図18に示すように、最終的な曲げグラフ
・データ構造を作成するための、面の節(ノード)の間
の連結エージェントとして格納しておこことができる。
バー・モジュール32に備えたソフトウエアまたはプログ
ラムされた論理によって実施できる。曲げ線検出操作の
目的は、部品が最も少ない数の曲げ線で連結されるよう
に、部品の曲げ線を検出し、選択することにある。曲げ
線検出操作は、部品の2-Dと3-Dバージョン両方に備える
ことができる。原3-Dモデルについての曲げ線検出の適
用は、下記に図19を参照しながら論ずる。上記のよう
に、検出された曲げ線は、最終的な曲げグラフ・データ
構造を作成するための面の節の間の連結エージェントと
して格納できる。この最終的曲げグラフ・データ構造
は、2-Dデータ・モデルから折りたたんで部品の3-Dバー
ジョンを作成するのに利用できる。
された2-D図面は、曲げ線情報を含まないか、曲げ線情
報が不明確で、一義的にまたは矛盾なく定義されていな
いことがある。その場合、曲げ線検出操作を、曲げ線を
検出し、部品の検出された面との関係を検出するために
行うことができる。このプロセスの間に、各面を定義す
る要素(エンティティ)のリンクされたリストを解析
し、各面が部品の他の面と共にもつ隣接する端または線
要素を決めることができる。これはある与えられた二つ
の面の間の可能なすべての接触を解析することによって
行うことができる。接触は、長さが0以上の(つまり線
要素が点ではなく、実際の線である)、共通する線要素
(またはお互いに事前に定めた距離許容度にある複数の
線要素)の存在によって決定できる。リンクされたリス
トにある幾何学データを解析することによって、部品の
すべての二つの面間のこのような接触の存在を決めるこ
とができる。
接触領域を一つしかもっていない場合、両方の面に共通
の要素は曲げ線であると定義することができる。一つ以
上の領域で共通接触を持つ複数の面(たとえば3-Dモデ
ル;ただし2-Dモデルでも起こりうる)については、色
々な発見的方法(ヒューリスティック)を用いて部品の
最小数の曲げ線を検出し、選択することができる。使用
する発見的方法は、複数の面が曲げ線で連結され、複数
の面にわたる連続ループが形成されないようになってい
なければならない(このような曲げ薄板金属部品の製作
は不可能なため)。
る領域で最も長い接触領域をもつものを曲げ線に選ぶ方
法がある。ある面が、他の面と一つ以上の共通端をもっ
ている場合、この発見的方法によって最も長い長さをも
つ共通要素を面の曲げ線に選ぶことができる。この発見
的方法は、曲げ薄板金属部品を製作するときに、通常長
い接触領域を持っている方が良いという原則にもとづい
ている。使用できるもう一つの発見的方法は、異なる可
能な曲げ線の組み合わせ(3-Dモデルの曲げ線を決める
ときのような)に関係する。この発見的方法では、すべ
ての可能な共通領域が検出され、曲げ線の色々な組み合
わせが選択されると、曲げ線の組み合わせで最小の曲げ
線の数をもつ組み合わせが選ばれる。
れた曲げ線は確認のためにオペレータに表示される。オ
ペレータが部品の曲げ線の選択に満足しない場合には、
曲げ線検出操作に手動選択機能を備えることによって、
サーバー・モジュール32でオペレータが選択的に、薄板
金属部品に好ましい曲げ線を指示できるようにすること
ができる。オペレータは、マウスやキーボード等、適当
な入力手段を用いて、曲げ線を保持するか変更するかを
指示することができる。しかる後、オペレータによって
選ばれた修正された曲げ線を用いて、最終的な3-D(ま
たは2-D)部品を作成することができる。
に、色々なプロセスや操作を備えることができる。曲げ
線検出操作を実施するためのコードの例を、付記の付録
Cに与える。例示のコードはC++プログラム言語で書かれ
ており、記述の論理フローの理解を助けるためのコメン
トが含まれている。例示コードは、2-Dまたは3-Dモデル
について行うことができる曲げ線検出操作の実施例で、
曲げ線の最適選択を決める発見的方法(上述のような)
を含む。
りたたみと展開プロセスに利用することができる。折り
たたみまたは展開の際、各曲げ線の回りに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-幅によっ
て、実際の薄板金属部品は薄板金属部品を折りたたむと
きに、差引高だけ引き伸ばされる傾向がある。
差引高情報を利用して、折りたたみ操作で3-Dモデルを
作成するときに、曲げ線の各側で部品の面の寸法を差引
高の半分だけ引き延ばす。本発明の見地に沿って、この
差引高はユーザーによってサーバー・モジュール32に入
力(たとえばキーボード等によって)できる。あるい
は、部品の材料のタイプと厚さにもとづいた差引高を含
む材料表をオペレータに表示することができる。材料表
は、異なる曲げ角度やV―幅に対する色々な差引高を示
す。ユーザーは、サーバー・モジュール32で表示された
材料表から適切なV―幅と曲げ角度を選ぶ(たとえばマ
ウスまたはキーボードを用いて)ことによって、自動的
に差引高をセットすることができる。曲げ角度の内側半
径も、適切なV―幅を選ぶときに、材料表を介してユー
ザーによって自動的にセットできる。オペレータが入力
する(あるいはオペレータによる入力後に変換される)
差引高は、部品幾何学データを表すものと同じ長さの単
位(たとえばmm)である。折りたたみ操作時に、曲げ線
の各側の各面の長さ寸法を、注目している曲げ線の差引
高の半量だけ増やす。面の曲げ線に垂直な長さ寸法は、
曲げ線の各側にある面の境界を定める要素の終点を引き
伸ばすことによって増やすことができる。このような差
引高補償は、各折り曲げについてオペレータによって供
給された差引高にもとづいて、部品の他の曲げ線の各々
について行うことができる。
にもとづいて、3-Dモデルを作成するための、差引高補
償を含めた折りたたみ操作が行われる。前記のように、
折りたたみ手続きは、行列変換の使用と最終的曲げグラ
フ・データ構造で定義されたそれぞれの曲げ線を回転軸
に用いることを含む通常の幾何学的模型化法によって遂
行することができる。さらに、差引高の効果を補償する
ために、3-Dモデルを作成する折りたたみの際に、部品
の面を曲げ線の各側で差引高の半量だけ引き伸ばすこと
によって、薄板金属を実際に折り曲げるときの面の寸法
の変化をより正確に反映することができる。
作を行う時に、曲げパラメータ(たとえば曲げ角度、内
側半径)とともに、部品幾何学と形態データ(または曲
げグラフ構造)を利用することができる。2-D空間で表
わされた部品の各面、曲げ線、孔と成形についての変換
行列を計算できる。通常の行列変換を、2-D平面図に適
用することによって、3-D空間データをうることができ
る。変換は一般に回転に続く並進を含む。上記のよう
に、回転は曲げ角度の大きさに従って、各曲げ線軸の回
りに行われる。並進操作は、幾何学データを空間の中で
移したり、動かしたりすることによって行われる。この
ような並進操作は、曲げ半径、曲げ角度と各曲げの差引
高にもとづいて決められる。折りたたみの際に、差引高
補償は前述べたように曲げ線の各側で、面の寸法を差引
高の半量だけ伸ばすか増やすことによって行われる。こ
のような差引高補償は、曲げ機で曲げられる2-D薄板金
属部品の寸法を、より正確に反映する部品の3-D表現を
与える。
報は、たとえば、その明細を全般的に参照することによ
って本文書に明白に取り入れられているモルテンソン、
マイケル M著、幾何学的モデル化、ジョン・ワイリー&
サンズ、ニューヨーク(1988年)及びフオリーら著、ジ
ェイムス システム・プログラミング・シリーズ:会話
形コンピュータ・グラフイックスの基礎、アデイソン・
ウエスリー出版、レデイング、マセチューセッツ(1983
年)を見られたい。モルテンソンの8章には、並進と回
転を含む幾何学的変換が論じられている(たとえば345-
354頁参照)。さらにフオリーらは7章、245-265頁で、2-
Dと3-D変換の行列表示を含む、幾何学的変換の情報を与
えている。モデル化と幾何学的変換についての付加的情
報は、その明細を全般的に参照することによって本文書
に明白に取り入れられている、マンテイラ、マルッテイ
著、ソリッドモデル化入門、コンピュータ・サイエンス
出版社、ロックビル、メリーランド(1988年)にも与え
られている。座標変換に関する情報は、マンテイラの36
5-367頁にある。
見地に沿って、元の厚さぬきの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によって、引き続き行われる面検出や他のプ
ロセスのための図面の準備のために、自動トリミングと
クリーンアップ操作が行われる。
動トリミングとクリーンアップ機能は、部品の色々な面
が適正に検出定義されされるように、構成要素や表面を
切り離したり、連結したりする。
トリミングとクリーンアップ操作は、図19のステップ
S.140で入力した3-D図面の幾何学データに対しても、同
じように適用できる。データを2-D空間で解析する(2-D
平面図の場合のように)代わりに、3-D図面に図示され
ている各構成要素(たとえば線、弧等)は、図中の3-D
座標と空間情報にもとづいて解析することができる。交
点と開放交差領域は、各構成要素(エンティティ)を個
別的に解析し、他の構成要素の一つ一つと比較すること
によって解析できる。ここでもまた、構成要素の終点や
他の属性の基本的な幾何学的解析を用いて、許容度内で
交点と開放交差領域を決めることができる。
及びクリーンアップ機能を実行した後、ステップS14
4で、前記板金パーツの面の各々を検出し定義するため
に面検出操作が行なわれる。前記3次元図面についての
面検出は2次元空間における各面を分析し且つ検出し且
つ上記と同様にしてループツリーを生成することにより
行なわれる。面検出は任意の所定のエンティティで開始
することにより実行される。例えば、一番左側のエンテ
ィティ(即ち最小のx座標を有するエンティティ)が最
初のエンティティとして使用される。その後、1つの面
は前記最初の線分エンティティ及び他の連結するまたは
隣接する線エンティティ(即ち前記最初のエンティティ
と共通の端点を有する任意のエンティティ)を取出すこ
とにより定義される。面検出操作は次に、図15(a)
−16(d)に関連して上記に説明したようにループ及
びエンティティ解析を用いて行なわれる。各エンティテ
ィは前記定義された2次元平面内で検出されるため、種
々の外側及び内側ループが定義され、且つ前記エンティ
ティがマークされ(即ち前記選択されたエンティティの
フラグを設定し或いは増加することにより)、それら
が、前記面における複数のループの1つを定義する連結
されたリストに選択され且つ含まれたことを示す。
面を構成する他の2次元平面において行なわれる。前記
他のエンティティのループ解析を行なうために、前記3
次元図面内でのマークされてない或いは選択されてない
エンティティを検索することにより追加の平面が定義さ
れる。そのような平面は、2つの選択されてないエンテ
ィティの間或いは選択されてないエンティティと以前に
選択されたエンティティとの間に定義される。追加の2
次元平面の各々において、更なるループ解析が行なわれ
前記内側及び外側ループを検出する。再び連結されたエ
ンティティの連結リストが保持され、前記複数のループ
経路の各々が定義されるにつれて、前記選択されたエン
ティティがマークされる(即ち前記選択されたエンティ
ティに付随するフラグを増加することにより)。
に解析された2次元平面の各々についてのループツリー
を生成するために、結果の複数のループが使用される。
すでに述べたように、ループツリーは、板金パーツにお
ける複数の面及び開口部及び穴を定義するために提供さ
れる。3次元の図面については、ループツリーは、前記
板金パーツの各面について生成される。各面内で検出さ
れた複数のループは、各ループツリーを生成するために
グループ化され分析される。各ツリーのルーツ(根)は
前記平面において検出された外側ループとして定義され
る。前記外側ループと共通のエンティティを有する前記
平面の各内側ループは前記ツールの子供として定義され
る。共通エンティティの存在は、各ループを定義する連
結されたエンティティのリストの分析及び比較に基づい
て検出される。追加のエンティティ(即ち穴或いは開口
部)が前記平面の内側ループにおいて検出される時、こ
れらのループはそれらがその内部に存在する内側ループ
の子供(即ち前記ループツリーのルーツの孫)として定
義される。生成された複数のループツリーは次に、前記
3次元図面の全ての面を検出するために用いられる。検
出された面は次に曲げグラフデータ構造におけるノード
(節)として格納される。
プS146における曲げ線検出操作の実行の後、連結す
る曲げ線連結エージェントにより補足される。曲げ線検
出操作及び最終曲げグラフ構造またはパーツ・トポロジ
ーの生成は図17及び18を参照して上記したと同様の
やり方で実行される。
行するための代表的なコードがここに添付された付録C
に提供される。このサンプルコードは、2次元或いは3
次元モデルに対してなされる曲げ線検出操作のための代
表的実行例であり、曲げ線の最適選択を決定するための
ヒューリスティック(例えば上記したような)を含む。
前記曲げ線検出操作は、検出された曲げ線に満足しない
時、サーバモジュール32におけるオペレータが前記板
金パーツのための好ましい曲げ線を選択的に指定するこ
とを許すマニュアル選択特性を含む。前記オペレータ
は、マウスあるいはキーボード等のごとき適宜の入力手
段により曲げ線を維持し或いは変更することを指示す
る。前記オペレータにより選択され改定された曲げ線は
最終的2次元パーツを生成するために用いられる。
心とする展開工程を実行する前に、ユーザは、ステップ
S148でV幅、材料タイプ及びまたは縮小量について
促される。上記したように、板金は折り曲げられる時伸
びる傾向を有するため、3次元パーツの寸法は前記2次
元平面パーツのそれより少し大きい。従って、板金パー
ツの展開の過程で、パーツの寸法は、選択された材料タ
イプ及びV幅に基づく縮小量だけ縮み或いは減少され
る。従ってこの発明の1つの側面によれば、3次元モデ
ルを展開する際、前記2次元モデル及びその表面の各々
の寸法をより正確に生成するために縮小操作が行なわれ
る。上記したように、前記縮小量は、前記ユーザにより
直接入力され或いは所望のV幅及び曲げ角度を選択する
ことによりユーザが自動的に前記縮小量を設定すること
ができるように、材料テーブルが表示される。
量は前記パーツ幾何学データにより表現されるそれと同
じ長さの単位(例えばミリメートル)である(或いはオ
ペレータによる入力の後その単位に変換される)。展開
操作の間に、前記曲げ線の両側の面の各々の寸法長さは
前記所定の曲げ線について入力された縮小量の半分だけ
減少される。前記曲げ線に直交する前記面の寸法長さは
前記曲げ線の両側に位置する前記面の境界を定義するエ
ンティティの終点を減少することにより減少される。前
記縮小補償は、各曲げについて前記オペレータにより提
供される前記縮小量に基づいて、前記パーツの他の曲げ
線のそれぞれにおいて行なわれる。
ップS150で、前記2次元モデルを生成するために展
開プロセスが行なわれる。前記3次元曲げモデルを展開
するために通常の方法が用いられ、それは前記複数の曲
げ線の各々を回転軸として用いるマトリックス変換の使
用を含む。この展開プロセスの間に各曲げ角度が測定さ
れ、前記平面曲げモデルを生成するために前記曲げ角度
量だけ前記パーツは展開される。更に、前記入力された
縮小量に基づいて、前記板金材料の物理的性質及び前記
3次元及び2次元モデルの間の差をより正確にシミュレ
ートするために、前記曲げ線の両側で前記縮小量の半分
だけの前記面の寸法の縮小或いは減少が行なわれる。
る時、前記パーツの寸法及びトポロジーデータ(または
曲げグラフ構造)が前記曲げパラメータ(例えば曲げ角
度、内側半径等)と共に用いられる。前記3次元空間に
おいて表現された前記パーツにおける各面及び曲げ線及
び穴及び成形部についての変換マトリックスが計算され
る。通常のマトリックス変換が前記2次元空間データを
得るために前記3次元データに対して適用される。前記
変換は一般的に回転を含み、その後に並進がくる。上記
したように、回転は、曲げ角度量に応じて各曲げ線の周
りに行なわれる。展開のために、2つの面の間に180
°が存在するまで(即ち面が平面になるまで)回転は逆
方向に行なわれる。並進は空間内で前記幾何学的データ
をシフトし移動するために行なわれる。そのような並進
は、各曲げについての前記曲げ半径及び曲げ角度及び縮
小量に基づいて決定される。展開の間、縮小補償は上記
したように、曲げ線の両側で前記縮小量の半分だけ前記
複数の面の寸法を縮め或いは減少せしめるために行なわ
れる。そのような縮小補償はそれが曲げ工程の間に折り
曲げられる前の前記板金パーツの寸法をより正確に反映
する前記パーツの2次元表示を提供する。
情報はモルテンソン、フォリー等及びマンティラに見出
される。上記したように、モルテンソンの8章は変換及
び回転(例えば345〜354頁を見よ)を含む幾何学
的変換の議論を提供する。更にフォリー等は、7章の2
45〜265頁で2次元及び3次元変換のマトリックス
表示を含む幾何学的変換についての情報を提供する。更
に座標変換についての情報はマンティラの365頁〜3
67頁に見出される。
の注文に基づいて、2次元3面図或いは厚さを有しない
3次元ワイヤフレーム図が最初に提供され或いは生成さ
れる場合、厚さを有しない3次元モデルを生成するため
に更なる工程が必要とされる。そしてその後、前記厚さ
を有しない生成された3次元モデルは展開プロセス或い
はアルゴリズムを適用することにより2次元モデルを生
成するために用いられる。図20−24は、最初の2次
元3面図に基づいて3次元モデルを生成するために適用
される種々のプロセス或いは操作を図示する。更に図2
5は、この発明の他の側面に応じて、厚さを有する最初
の3次元ワイヤフレーム図から厚さを有しない3次元モ
デルを生成するために適用される追加のプロセス或いは
操作を図示する。再び、図20−25において図示され
る種々のプロセス及び操作は、例えば前記サーバモジュ
ール32に存在するソフトウエア及びまたはプログラム
論理により実行される。
じて、最初の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により前記クリーンアップ操作が行なわれる
際実行される種々のプロセスの論理フローの例を図示す
る。
面が前記サーバモジュール32により、ステップS18
0でデータファイルから読み取られ或いはロードされ
る。しかる後ステップS182でサーバモジュールは、
2次元図面において各々のエンティティ或いは幾何学デ
ータを分析し次の工程のための図面を作成するために種
々のエンティティを分割する。ステップS182におい
て行なわれる前記分割或いはトリミング機能は、この発
明の前記自動トリミング及びクリーンアップ機能に関連
して上記に記載したと同様な方法で実行される。従って
ステップS182で前記2次元3面図における全ての幾
何学的データは、エンティティの交差点及び所定の誤差
範囲内にある空白(開放)交差部を検出するために分析
される。任意の交差線は分断され、結果のエンティティ
は交差点により定義される共通の終点で出会う。更に所
定の誤差の範囲内にある(例えば0.0−0.01mm
或いは0.0−0.001インチ)空白交差領域を有す
るエンティティについてはそれらのエンティティは、例
えば図12―14に関連して上で記載されたと同様の方
法で結合される。
の周辺が検索され任意の外部の線分またはデータ(例え
ば境界線分及び座標格子及び数字等)が消去される。図
22(a)に示されるように2次元3面図は、しばしば
図面シート上に提供される。前記図面シートは前記板金
パーツの種々の図面を生成するために必要でない余分な
及び非幾何学的な情報を含む。従ってステップS184
で、本発明の2次元クリーンアッププロセスを利用し
て、前記3次元モデルを展開するにあたってこのタイプ
の情報が検出され前記2次元図面から消去される。
ータのタイプ(例えば幾何学的或いは非幾何学的/テキ
スト)を指示するためのキーワード或いはタイプフィー
ルドを含む。従ってこれらのキーワードあるいはタイプ
フィールド(それらは図面ファイルのデータフォーマッ
トに基づいて提供される)はテキスト或いは他の非幾何
学的データのごとき種々の余分の情報を削除するために
用いられる。しかし全ての不必要な図面シートデータを
正しく削除するためには更なる操作が通常必要である。
しばしば、前記境界線或いは他の外側情報はエンティテ
ィー(例えば線分等)として保存され、それらは前記デ
ータキーワード或いはタイプフィールドに基づいて容易
に識別することができない。従ってこの発明の1つの側
面によれば、前記2次元図面のデータを分析する際に連
結性グラフ構造が生成される。この連結性グラフ構造は
各エンティティーについて複数の付随的頂点のリスト及
び連結されたエンティティーのリストを示す。各頂点に
ついては、隣接する複数の頂点のリスト及びそれが付随
するところのエンティティーのリストが提供される。こ
のグラフ構造により、(それはステップS182の分断
及びトリミング機能を実行する際に生成されるが)、ど
のエンティティーがくっつき合う終点により結合される
かが決定される。結果として、境界線及び情報ボックス
及び他の非幾何学的データのような余分なデータは削除
される。これは、このデータは典型的に連結されたエン
ティティーで構成されることがなくまたそれを含まない
からである。
び矢印線及び中心線及びテキストのような余分の情報を
含み、それらは前記パーツの実際の幾何学形状を表現し
ない。これらのエンティティーはステップS186で検
出され、次の工程のための2次元図面を作成するために
前記2次元データファイルから削除される。これらの余
分のエンティティーの検出はサーバモジュール32によ
り自動的に行なわれる(例えば前記パーツの実際の幾何
学形状に関連しない2次元データファイル中の項目を検
出することにより)。例えば、前記連結性データグラフ
構造を用いて、両端が開放されたエンティティー(例え
ばテキストにアンダーラインをするため或いは寸法或い
はパーツの中心線を示すために用いられる複数の線)が
検出され消去される。矢印のごとき他のエンティティー
もまた、浮動する終点或いはそのようなエンティティー
の他の特徴の存在に基づいて検出される。全ての不必要
なデータを効果的に削除するために、サーバモジュール
32は前記2次元図面中のいずれの項目が消去されるべ
きかを(例えばマウスまたはキーボードにより)オペレ
ータをして指示することができるようにするためのマニ
ュアル編集機能を提供する。オペレータのこの援助或い
は確認により、追加の余分の情報が図面から除去され
る。
種々の図が、ステップS188でグループ化され且つそ
れぞれ定義される。この発明の1つの側面によれば、サ
ーバモジュール32は、図22(b)及び23(a)に
示されるような平面図(上面図)及び正面図、右側面の
配置のごとき、予め定められた或いは標準的な図と向き
をサポートする。平面図及び正面或いは背面図及び右或
いは左図のような他の図及びレイアウトもまたサポート
され得る。更に以下に記載されるように、サーバモジュ
ール32はまた前記2次元図面の図を前記パーツの3次
元表現へ加工するために、回転された図(例えば図23
(a)を見よ)もサポートする。いずれにしても、パー
ツの3次元モデルが構成されるためには、厚さ表現を有
するパーツの少なくとも2つ(そして好ましくは3つ)
の異なる図が提供される必要がある。連結性グラフ構造
において前記エンティティーの連結性及びグループ化を
解析することにより、サーバモジュール32は、複数の
図の各々の相対的位置及び/又は座標位置に基づいて前
記複数の図を分類し且つ定義する。
32による前記図の定義は、予め定義された或いは通常
の配置或いは前記データファイルにおける図の解析をす
るためのレイアウトにより、及び/又は前記複数の図の
向きの検出及び前記図面の各々の図のそれぞれにおける
前記パーツの種々の寸法の重ね合わせに基づいて実行さ
れる。図23(b)において示されるそれのごとき予め
定義された或いは標準的フォームは、潜在的な図のタイ
プに応じて前記図の各々を決定し定義するために用いら
れる。種々の終点及び各グループを定義する複数のエン
ティティーの間の関係の幾何学的比較は、前記ステップ
S188を実行するために行なわれる。サーバモジュー
ル32の図検出特性(図検出機能)は、複数の潜在的図
面タイプ(例えば平面図、正面図、背面図、左図、右
図)の1つに応じて前記図面の各々にラベルを付ける。
前記複数の図の各々の検出は、予め定義された或いは標
準的図の配置或いは形状及び存在する図の各々の間の検
出された関係に基づく。種々の工程或いは操作が、ステ
ップS188で、前記2次元3面図における複数の図を
分類し且つ定義するために使用される。例えば前記加工
された2次元3面図にアクセスした後、前記サーバモジ
ュール32はまずこの図面データにおけるパーツの平面
図を特定する。前記平面図は、予め定義された或いは標
準的な形状または図配置(例えば図23(b)における
それのような)に基づいて検出される。仮に3つの異な
る図が水平方向或いは垂直方向において検出される場合
には、中央の図が平面図であると定義される。更に仮に
3つの別個の図が検出されず且つ垂直方向においてただ
2つの別個の図が検出される場合には、上側の図が平面
図であると定義される。再び前記連結性グラフ構造にお
ける前記エンティティーの連結性及びグループ化が前記
複数の図の各々を検出するために使用される。前記予め
定義された或いは標準的形態を表現する、格納されたル
ックアップテーブル或いはマトリックスが前記2次元図
面の各図を比較し且つ複数の図の各々を検出するために
用いられる。
した後、前記パーツの他の図は前記検出された平面図に
対する前記複数の図の各々の相対的位置に基づいて検出
される。例えば、図23(b)の標準的レイアウトに基
づいて、例えば図グループが前記平面図の上に位置して
いる場合には、その図は背面図であると定義される。し
かしもし図グループが前記平面図の下に位置している場
合には、その図は前記パーツの正面図であると定義され
る。更に右図及び左図は、前記平面図のそれぞれ対応す
る右側及び左側におけるそれらの相対的位置に基づいて
検出される。しかる後、前記標準的形態(例えば図23
(b))に合致しない任意の残りの図は前記検出された
図(例えば検出された背面図或いは正面図)に対するそ
れらの相対的位置に基づいて検出される。例えば図23
(a)に示されるレイアウトBについて、前記右図は前
記平面図に対して回転された位置に設けてある。しかし
ながらレイアウトBにおける右図は前記検出された正面
図に対するその関係に基づいて検出される。即ち検出さ
れた背面図或いは正面図の右側或いは左側に存在する検
出されていない図はそれぞれ前記パーツの右図或いは左
図として定義される。
レイアウトが前記2次元3面図図面において複数の図を
検出し且つ定義するために用いられる。標準的な形態
(例えば図23(b)または図23(a)におけるそ
れ)は、製造設備において広く行き渡っており或いは選
択され/要求される図レイアウトに基づいて、及び/又
はサポートされている図タイプの基づいて選択される。
仮にいずれの図も検出されない場合には、サーバモジュ
ールにより警告信号が提供され、オペレータは、好まし
い図面レイアウトに応じて前記2次元3面図データを変
形したり、他の適当な動作を行なう。前記2次元図面に
おける複数の図を検出するための予め定められた或いは
標準的形態の提供に加えて、予め定められた標準的形態
(例えば図23(a)のレイアウトAのように)は検出
された図を加工し前記パーツの3次元モデルを生成する
ために設けられる。従って更なる加工が行なわれる前に
前記標準的形態に基づいて検出された図を正しく分類す
るために、回転された図の特徴が提供される。
プ操作は図面において複数の図を検出するための予め定
められた、或いは標準的形態に合致しない回転された複
数の図をサポートし且つ検出する。回転された図のオプ
ションでは、検出された標準的でない複数の図は、パー
ツの3次元モデルを加工し且つ生成するために、前記複
数の図の各々が前記予め定められた或いは標準的な図の
形態に合致するように、回転され或いは並行移動され
る。前記パーツの複数の図を検出するために図23
(b)に図示されるそれのような標準的形態を仮定し
て、図23(a)におけるレイアウトBにおける複数の
図の各々は、上記したように、前記平面図及び他の検出
された図に対する当該複数の図の相対的な位置に基づい
て検出される。例えば仮に図23(a)のレイアウトA
が、平面図及び正面図及び右図を有する2次元図面にお
ける種々の図を加工するための予め定められた或いは標
準的図レイアウトとして使用される場合、ステップS1
88でレイアウトBにおける右図は90度回転されレイ
アウトAと同様な、前記パーツの変形された図レイアウ
トを提供する。前記パーツの右図が前記パーツの平面図
の右側に位置するように前記レイアウトBにおいて右図
を90度回転することにより、図面中の前記複数の図は
レイアウトAで表現される標準的な形態に応じて加工さ
れる。格納されたルックアップテーブル或いは予め定め
られた或いは標準的な形態を表現するマトリックスが、
前記2次元図面の複数の図を比較し且つどの図が回転或
いは並進運動を必要とするかを決定するために用いられ
る。
パーツの正確な3次元モデルが生成されることを保証す
るために、前記複数の図の各々においてそれぞれの寸法
が相互に矛盾がないか或いは一致しているかチェックさ
れる。図21において更に示されるようにステップS1
90で前記データファイルにおける前記複数の図の境界
が、それぞれの図の全ての寸法が相互に同じ寸法である
かを確認するために検出される。仮に複数の図が所定の
誤差の範囲内で(例えば0.0−0.01インチ)一致
しないことが判断されるとステップS190で、全ての
複数の図が同じスケールになるように任意の特定の図の
寸法を変更するために適宜の修正が行なわれる。図面の
寸法が相互に一致せず現在存在する2次元図面データに
対して必要な修正が行なわれるようにユーザに警告する
ためにサーバモジュール32に警報要素が設けられる。
性を検出し且つ確認するために種々の操作或いは工程が
使用される。例えば、前記複数の図の各々の対応する寸
法が、それらが相互に所定の誤差の範囲内にあるかどう
かを決定するために比較される。そのような解析は、前
記パーツの各図の境界線を定義する線分エンティティー
を比較することを含む。図23(b)における標準的な
形態を仮定して以下のようであれば平面図は右図または
左図と一致すると検出される。即ちそれぞれの図につい
て、最大Y座標位置と最小Y座標位置が所定の誤差範囲
(例えば0.0−0.01インチ)内にある。更に前記
平面図は、以下の場合には正面図または背面図と一致す
ると検出される。即ち各図について、最大X座標位置と
最小X座標位置とが所定の誤差範囲(例えば0.0−
0.01インチ)内にある。更に左図または右図は、最
大Y座標位置と最小Y座標位置との間の差に比較して最
大X座標位置と最小X座標位置との差が所定の誤差範囲
(例えば0.0−0.01インチ)内にあれば正面図ま
たは背面図と一致すると決定される。再び前記図の寸法
或いは関連する面の寸法が一致しないとき前記2次元図
面データに対して必要な修正が加えられるようにユーザ
に警告するように、サーバモジュール32に警告要素或
いはモジュールが設けられる。
出方法の教示に基づいて、前記パーツの内側ループ及び
穴及び形状が検出される。各図の複数の面の内側に設け
られている種々の穴或いは形状は、前記パーツの種々の
線及び境界を通ってパーツの外側から中央へ向かってル
ープを形成していくことにより検出される。ループ及び
エンティティーの分析は、前記2次元図面における前記
パーツの各図に対してなされる。前記パーツの外側から
作用的に中央へ向かって内側へ各々の図を分析すること
により、検出されたループは前記パーツの物質と開口部
の境界及び領域を、周期的順番(即ち物質、開口部、物
質等)に基づいて決定する。図16(d)におけるそれ
のごときループツリーが複数の面の位置及び各々の面の
内部の任意の穴の位置を決定するために各図面について
生成される。浮遊する円弧或いは線分のごとき前記パー
ツの面の内部で連結されないエンティティーは、ステッ
プS192の中で検出され消去される。
行なうための代表的なコードは付録Dに提供される。こ
のコードはC++プログラム言語で記載されており、そ
こに使用される論理及びアルゴリズムの解析を円滑にす
るためのコメントを含む。そのコードは、図21−22
(b)を参照して上で議論したそれらのごとき、2次元
クリーンアップモードの種々の工程及び操作を含む。
アップ操作が行なわれた後論理フローはステップS16
4へ連続しそこで前記2次元図面が材料の厚さを表現し
または含むか否か(即ち前記2次元図面が厚さを有する
か否か)が決定される。もし前記2次元図面が厚さの量
を含むと判断される場合には、ステップS166で3次
元モデルへの引き続く操作のための2次元図面を作成す
るためにサーバモジュール32により厚さ消去手続きが
行なわれる。前記2次元図面における厚さの存在の判断
は図面のデータに基づいてサーバモジュール32により
自動的に行なわれ、或いはオペレータからの援助或いは
応答を介して前記サーバモジュールにより行なわれる
(オペレータは厚さ除去が必要であるか或いは好ましい
かを指示するように促される)。前記パーツの厚さは全
ての板金パーツの独特の対称性により消去される。前記
パーツの厚さを消去することにより、厚さを有しない、
結果としての板金パーツは板金オペレータ或いは設計者
により、より容易に分析される。更にこの出願の発明者
は、前記2次元3面図の厚さを除去することにより、2
次元図面を変換し3次元モデルを生成するに必要な時間
が著しく短縮されることを見出した。
め、オペレータはしばしば、2次元図面から3次元モデ
ルを作成するためにいずれの曲げ線が選択されなければ
ならないかで混乱する。結果として、2次元3面図が3
次元モデルへ変換されるように適切な曲げ線を選択する
際に相当の時間が無駄になる。厚さを有する2次元3面
図の例が図24に示されている。この発明の1つの側面
によれば、材質厚さを持つことなく表現され且つ処理さ
れるが、当該材質厚さ量及び前記パーツの内側及び外側
寸法を曲げモデルデータ中に保有する簡単化された2次
元3面図モデルを表示するように、厚さ除去手続きが設
けられている。図24(b)は前記厚さ除去工程を行な
った後、前記サーバモジュール32において前記オペレ
ータに対して観察され且つ表示される簡単化された2次
元3面図を図示する。
ザは、2次元3面図表示における材質厚さを特定するよ
うに促されてもよく、また前記表示内においていずれの
寸法(即ち外側寸法或いは内側寸法)が保持されるべき
であるかを特定するように促されても良い。オペレータ
は、例えばマウスを用いて複数の図の中の1つにおいて
保持される厚さ及び表面を指示する。このユーザにより
入力されたデータに基づいて、サーバモジュール32は
前記2次元3面図を修正し、ユーザにより指示された材
料厚さを消去し、前記オペレータの選択に基づいて内側
或いは外側寸法を残す。
するために、前記サーバモジュール32は前記オペレー
タにより行なわれた選択に基づいて前記3つの図の各々
を分析する。選択された表面は幾何学的計算により(即
ち選択されたエンティティー線分或いは表面と同じX座
標或いはY座標射影に存在する対応するエンティティー
を検出することにより)他の図の1つへ射影され、前記
複数の図の各々における対応するエンティティー及び線
分を検出する。対応するエンティティーは、マークされ
且つ保持され、合致しないエンティティー或いは表面は
削除され或いは図24(b)に示されるそれのように、
スクリーン上に表示されない。更にオペレータにより指
示される厚さ寸法線は他の図の各々へ同様に射影され、
合致する厚さ寸法線或いはエンティティーは図24
(b)の例に更に示されるように削除される。結果とし
て、図面内の複数の図の各々は適宜に修正され、前記サ
ーバモジュール32においてユーザに対して表示され
る。厚さを有しない、結果としての2次元3面図は前記
パーツの3次元モデルを生成するために次の工程で使用
される。
削除されるべき厚さ線及び残されるべき表面エンティテ
ィーをオペレータが選択的に指示するようにするための
マニュアル厚さ消去モードを含む。表示された図の各々
においてどの領域が削除されるべきであり、どの表面が
残されるべきであるかを指示するためにマウス或いは他
の適当な入力装置がオペレータにより使用される。前記
オペレータにより入力されるデータに基づいて前記サー
バモジュール32は、厚さを有しない図面を提供するた
めに、前記2次元3面図からオペレータにより選択され
る各線分エンティティーを削除する。
元3面図図面において正しく特定されたか否かを分析し
且つ検出し且つ、マークされない厚さ要素が存在する時
及び/又は図面データ中に矛盾が存在する時、ユーザに
警告するための警告システム或いはモジュールを含む。
例えば厚さ警告要素は、前記表示スクリーン上で潜在的
なマークされない厚さ部分を強調するために設けられ、
面警告要素は面の寸法が他の図における厚さのマークと
一致しない時、前記スクリーン上で潜在的な一致しない
面を強調するために設けられる。曲げ線警告要素は、ま
た矛盾する曲げ線を強調し及び一致しない厚さ曲線を強
調するために設けられる。曲線は、この曲線上に射影さ
れる少なくとも1つの曲げ線が2つの横断厚さ線分(厚
み横断線)により挟まれないとき強調される。例えば図
24(c)は、2つ或いは他の零でない偶数の横断厚さ
線分(即ち各図において厚さを横断する短い線)により
正しく挟まれている厚さ曲線を図示する。各曲げ線は2
つ又は他の零でない偶数の横断厚さ線分により挟まれる
べきである。各図面における前記パーツのこれらのエン
ティティーの分析は、ループ分析を実行し且つ各図を作
り上げる線分及び円弧エンティティーの連結性を解析す
ることに基づく。開放された厚さ線分は他の厚さ線分或
いは曲線と接続しない少なくとも1つの端点を有する厚
さ線分に基づいて定義される。1つの開放厚さ線分を含
むサイドは開放厚さサイドと定義される。厚さ線分は、
開放厚さ線分の開放厚さサイドが最小ループの境界ボッ
クスに一致しない場合に強調される。前記加工された2
次元3面図の像に関連する警告をユーザに与えることに
より、ユーザは図面データ中の矛盾を警告され、ユーザ
はパーツの3次元モデルを生成するために更に加工を行
なう前に、前記図面データを修正及び/又は訂正するこ
とができる。そのような警告システム及びユーザとの相
互作用を含むことが3次元モデルによる前記パーツの表
現の精密さを改善する。
ない加工された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)。これらの開示はここにそれらの全てにお
いて明示的に取り込まれる。
る際、結果としての3次元モデルを更に加工し且つ精密
化するために追加のクリーンアップ工程が含まれる。こ
の発明の1つの側面によれば、3次元クリーンアップ工
程は、前記パーツの2次元3面図において存在し且つ前
記パーツの生成された3次元表現において余計な或いは
過剰な情報を生成する不明瞭さを補償するために設けら
れる。当業者に理解されるように、パーツの2次元3面
図表現は3次元座標空間における前記パーツの種々の特
徴の表現に関連して不明瞭さを含む。前記2次元3面図
から3次元モデルを生成する際余計な且つ過剰な情報が
これらの不明瞭さの結果として生成される。従ってこの
発明の側面によれば、前記3次元クリーンアップ工程
は、1つの端部がつながっていない線分を検出し且つ除
去すると共に曲げ線を検出し且つきれいにすると共に面
をトリミングする工程を含む。前記3次元クリーンアッ
ププロセスは前記パーツの結果としての3次元モデルを
生成する際に自動的に行なわれ或いは前記生成された3
次元モデルが追加の工程を要求すると判断される時、オ
ペレータからの入力に基づいて選択的に行なわれる。
前記生成された3次元図面データを分析することによ
り、一端部において他のエンティティーと接続されない
と判断される全ての線分或いは曲線が特定され片側開放
線分として定義される。片側開放線分であると判断され
る任意のエンティティーは前記パーツの3次元表現から
除去される。一旦開放線分が除去されると、それは他の
線分或いはエンティティーが開放されることを導くかも
しれない。従って新しい片側開放線分がまた特定され、
全ての開放線分或いはエンティティーが除去されるま
で、繰り返し除去される。図63は片側開放線分が除去
される前のパーツの3次元表現の例を図示し、図64は
片側開放線分が前記3次元表現から除去された後の前記
パーツを図示する。
われる3次元クリーンアップ工程は曲げ線を検出しきれ
いにする工程も含む。曲げ線は、3次元空間におけるパ
ーツの面情報の検出を促進するために特定され且つきれ
いにされる(例えばモールド線分を加えることによ
り)。前記生成された3次元モデルデータに基づいて、
各曲げ線は、それぞれの中心により定義される同一の法
線を有する一対の3次元曲線(例えばそれは図面データ
における曲線エンティティーにより表現される)の検出
に基づいて同定される。この過程において、特定された
前記曲げ線に対してモールド(形取り)線分が付加され
る。前記モールド線分は、3次元曲線の各対において対
応する終点を特定し且つ前記3次元曲線の対応する終点
の間でモールド線分(例えば線分エンティティーで表現
される)を延長することにより追加される。図65は曲
げ線が特定される前のパーツの代表的3次元表示を図示
し図66は前記モールド線分(図において破線で表現さ
れる)が追加された後のパーツを図示する。
された後、3次元クリーンアップ工程は更に前記パーツ
の全ての曲げ線をきれいにし且つ面をトリミングするた
めに前記パーツの3次元表現を加工する。前記2次元3
面図データの図における頻繁に生ずる不明瞭さにより、
前記パーツの3次元表現に前記面の過剰な部分が生成さ
れる。前記3次元クリーンアップ工程は前記面の過剰な
部分を特定しそして板金領域知識(例えば何が折り畳め
ないかについての知識)を用いて前記面をトリミングす
る。余分な穴或いは開口部のような他の余分な情報も特
定され除去される。結果として前記パーツの過剰な部分
は除去され前記3次元表現は前記板金パーツのより精密
な表現を提供する。図67は前記曲げ線をきれいにし且
つ前記面をトリミングする前のパーツの代表的な部分を
図示し、図68は正常化及びトリミングがなされた後の
パーツの前記部分を示す。
から材料厚さを持たない3次元図面を生成するためにな
される工程及び操作の論理フローの例を示す。ステップ
S200で、材料厚さを有する最初の3次元図面が入力
されサーバモジュール32へ搬入される。前記3次元モ
デルは材料厚さを有する3次元のワイヤフレーム図面
で、DXF或いはIGESファイルのごときCAD図面
ファイルである。前記3次元図面が前記サーバモジュー
ル32へ搬入された後、厚さ除去工程がステップS20
4で行なわれる。ステップS204における前記3次元
モデルに対する厚さ除去工程は上記したアマダUNFO
LDソフトウエア・システムにおいて提供されると同じ
方法で行なわれる。前記3次元モデルにおいて厚さを消
去するために、オペレータはまず厚さを指示し且つ残さ
れる面を選択するように促される。このオペレータの選
択に基づいて厚さを定義するエンティティー線分の終点
を解析することにより厚さが測定される。しかる後、選
択された表面の境界が、前記ループ及びエンティティー
解析工程に関連して上記したと類似の方法により探索さ
れる。そして保持されるエンティティーはマークされ
(例えばフラグを設定し或いは増加することにより)、
対応する厚さエンティティーは除去される。前記3次元
パーツのエンティティーを探索する際、前記エンティテ
ィーは、ユーザにより選択された厚さエンティティーの
長さに基づいて識別される。一般的に前記厚さエンティ
ティーと同じ長さを有する全てのエンティティーは選択
されず除去され、同じ長さでない他のエンティティーが
マークされ残される。前記3次元パーツの表面の探索で
マークされなかった残りのエンティティーもまた除去さ
れることがある。再びサーバモジュール32はマニュア
ル厚さ除去モードを提供し、そこではオペレータは除去
されるべき3次元パーツにおける各エンティティーを手
動で指示する。
結果としての3次元モデルがステップS206で展開さ
れ及び/又はオペレータに対して表示される。展開アル
ゴリズム或いは工程が次にその材料厚さを有しない3次
元モデルに適用され上に詳細に説明したように、曲げモ
デルデータについての単一の2次元平面図を生成する。
上記したように前記データベース30に格納されるデザ
イン及び製造情報は、板金要素についての製造データの
みならず板金の幾何学形状及びトポロジーを含む曲げモ
デル・データファイルを含む。更にこの発明の種々の特
徴を実行するために使用されるソフトウエアはC++の
ごとき高度のプログラム言語を用い且つオブジェクト指
向プログラム技術を用いて生成される。この発明の種々
の特徴を実行するためには、Booch或いはOMTの
ごとき異なるオブジェクト指向技術も使用される。オブ
ジェクト指向プログラムが使用される場合は、前記板金
パーツを表現するためにオブジェクト指向データが使用
され、前記パーツのための曲げモデルは完全に自己充足
的クラス・ライブラリを介して実行される。この発明の
1つの側面により、オブジェクト指向プログラム技術に
基づく、前記曲げモデルのための代表的データ構造及び
アクセス・アルゴリズムの記述が提供される。図26
は、本願発明をオブジェクト指向プログラムにより実行
する際使用される前記曲げモデルの代表的データ構造及
びアクセスアルゴリズムを図示する。オブジェクト指向
プログラムは、データを含む複数のオブジェクト或いは
モジュールのみならずそのデータに作用する複数の指示
を結合することにより現実世界をモデル化することがで
きるソフトウエア展開の1つのタイプ或いは形態であ
る。オブジェクト指向プログラムにおいては、オブジェ
クトは板金パーツのごとき、何か物理的なものをモデル
化するソフトウエアエンティティーであり、或いはそれ
らはビジネス上の商取引のごとき仮想的な何かをモデル
化するものである。オブジェクトはそのオブジェクトの
状態を集合的に定義する1つもしくはそれ以上の属性
(即ちフィールド)を含み、且つ全ての他のオブジェク
トからそれを識別するための識別子を含む。更にオブジ
ェクトはある種の条件の存在に基づいて、前記属性を修
正し或いは前記オブジェクトに対して作用をなす一群の
方法(即ち手続き)により定義される振る舞いを含む。
ツはオブジェクト指向データモデルとして表現される。
図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次元空間位置データ、及
び端及び表面データを含む。
ーツクラス50は更にトポロジー・オブジェクト62及
び曲げ特性オブジェクト64を含む。前記トポロジーオ
ブジェクト62は、前記パーツの前記面、穴、成形部及
び曲げ線についてのパーツトポロジーデータを含む。前
記トポロジーオブジェクト62におけるデータは前記パ
ーツの前記種々の特徴の構造的及び幾何学的関係を示
す。前記曲げ特性オブジェクト64は前記パーツの1つ
或いはそれ以上の特徴についての特殊な製造上の拘束に
関する情報を含む。例えば如何に前記板金パーツが曲げ
られるべきであるかに関する曲げ特性情報が、前記曲げ
特性オブジェクト64に設けられる。前記曲げ特性情報
は、異なる曲げ特性タイプ(例えば同時曲げ、同一直線
上曲げ、Z曲げ等)についての特殊製造データを含む。
われる曲げに関連する製造特殊データを含む。従って、
各曲げ線についての幾何学的或いは寸法データ、2次元
及び3次元空間位置データ、端データに加えて、前記曲
げ線オブジェクト60はまた、各曲げ線についてのV幅
データ、曲げピッチデータ、曲げ数データ及び/又は配
向データを含む。各曲げ線は、図26に示すように付随
する曲げ操作を含む。この曲げ操作は、各曲げ線におい
て曲げを行なうためのデータ及び操作/指示を有する一
群のオブジェクトとして実行される。仮にオブジェクト
として提供されると、各曲げ操作は、曲げ角度、曲げ半
径及び/又は曲げ縮小量のごとき固有の曲げデータのみ
ならず、如何に或いはどのタイプの曲げを行なうべきか
(例えば円錐曲げ、Z曲げ、ヘミング、円弧曲げ等)を
指示するデータ及び指令を含む。
指向データモデルを介して実行することにより、全ての
複雑な数学的計算、計算幾何学及びマトリックス変換が
単一のクラスライブラリに組み込まれる。ヘミング、Z
曲げ及び円弧曲げのごとき特殊な曲げ操作もそのクラス
ライブラリに取り込まれる。更にV幅及び曲げ縮小量及
び曲げ順のごとき製造情報もそのクラスライブラリに取
り込まれる。前記曲げモデルにより、前記2次元平面モ
デル及び3次元モデルの同時二重表示が図26に示すよ
うに行なわれる。更に、前記曲げモデルの曲げ線オブジ
ェクト60に応じて曲げ加工が行なわれる。前記曲げモ
デル及びパーツ構造並びにそれらについての実行に関連
する一般的なコメントはここに添付した付録Kに提供さ
れる。
釈し、2次元及び/又は3次元表現における前記パーツ
の視覚的な画像を表示するために設けられる。図27
は、この発明の他の側面による、前記曲げモデルビュー
アの構造と前記曲げモデルとの関係のブロック図を図示
する。前記曲げモデルビューアはオブジェクト指向プロ
グラム技術を介して実行され、前記設備38における種
々の場所10,12,14,…20の前記ステーション
モジュールにおけるユーザが前記曲げモデルに設けた情
報に基づいて前記パーツの種々の図を表示できるように
するウインドウズに基づくアプリケーションである。前
記曲げモデルビューアは、前記板金パーツを視覚化する
ために用いられる一群のアプリケーション・ライブラリ
・モジュールを含む。更に、前記曲げモデルビューア
は、ウインドウズ・アプリケーションの画像クラスとし
て設計され、従ってそれは任意のウインドウズ・アプリ
ケーションについての基本的画像クラスとして使用され
る。前記2次元及び3次元モデルを見るための殆どの標
準的操作(例えばズーム92、回転96、パン100、
寸法102等)は前記曲げモデルビューアの要素機能と
して実行される。幾何学的変換及び基本的コンピュータ
グラフィックス技術は、画像操作を実行する際に前記曲
げモデルオブジェクトに対して適用される。更に、前記
曲げモデルビューアは、画像モデル属性88を含み、そ
れはソリッド画像、ワイヤフレーム画像、2次元平面画
像及び正射影画像を含む4つの主なる画像モードを有す
る。
モデルクラスライブラリ80は、選択された画像(例え
ばソリッド、ワイヤ、2次元平面又は正射影画像)に応
じて、前記板金パーツに作用する一群の手続き又は機能
を含む。前記曲げモデルビューア観察クラス84は、ズ
ーム92、回転96、パン100及び寸法102のごと
き、一連の標準的操作を含む。そして、前記曲げモデル
ビューアの状態に応じて、前記曲げモデルビューア観察
クラスは、前記曲げモデル・クラス・ライブラリ80か
ら複数の機能を呼び出す。図27に示されるように、ユ
ーザにより選択される前記種々の観察モデル属性或いは
特徴88は、ソリッド画像、ワイヤフレーム画像、2次
元平面画像及び正射影画像を含む。この発明に設けてあ
るこれらの種々の観察モードの記述は図28−31を参
照して以下に提供される。
何学的モデル化技術、例えば幾何学的変換及び3次元幾
何学的技術は、前記曲げモデルの種々の特徴を実行し且
つ異なる観察モード或いは機能を提供するために使用さ
れる。コンピュータに基づいた2次元及び3次元のモデ
ル化及びシミュレーションにおける最近の発展及び展
開、例えばグラフィックライブラリ或いはパッケージの
効用はこの発明のこれらの特徴を実行するために適用さ
れる。更に、コンピュータグラフィックス及びモデル化
については広い種類の刊行物或いは文献が利用可能であ
る。例えば、モルテンソン、フォリー等、マンティラを
見よ。それらの各々は上に記載した。
を提供するために各ステーションモジュール及びサーバ
モジュールは、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)を見よ。
に、前記曲げモデルは例えばオペレータのステーション
モジュールにより前記データベース30からアクセスさ
れる。前記曲げモデルデータは、使用されているグラフ
ィック・ライブラリ或いはパッケージ(例えばオープン
GL又はレンダウェア)により使用されるデータフォー
マットに応じて再フォーマット化される。しかる後、前
記グラフィックデータは、オペレータにより選択された
観察モード(ワイヤ、ソリッド等)を表示し、或いは前
記ユーザにより実行された観察機能(ズーム、パン等)
を実行するために種々のプログラムされた順序に従って
加工される。
される時、選択された観察モードは、前記画像の現在の
ズーム比率或いはファクター及び向きと共に検出され
る。この情報は、次に前記現在の表示を更新するために
前記グラフィックパッケージに対して機能コールを行な
うために使用される。前記グラフィックパッケージに対
する機能コールは、表示される観察モード並びに実行さ
れるズーム或いはその他の観察機能に応じて行なわれ
る。これらの機能コールに基づいて前記グラフィックパ
ッケージは必要なデータを提供し、従って前記ステーシ
ョンモジュールは前記オペレータに対して前記パーツの
画像を表示する。前記ユーザによる前記2次元又は3次
元表現の修正(例えばジョイスティック或いはマウスを
移動することにより)に基づいて前記表示された画像を
更新するために追加の機能コールは前記グラフィックラ
イブラリに対してなされる。
るために、前記グラフィックパッケージに対して前記パ
ーツの線分エンティティーデータが提供され必要なグラ
フィック計算がなされる。しかし、ソリッド画像につい
ては、前記面の各々について1つもしくはそれ以上の多
角形(ポリゴン)が引き出され、前記画像を表示するた
めに前記グラフィックパッケージへ入力として提供され
る。オープンGL及びレンダウェアのようなグラフィッ
クパッケージは、多角形データを入力として取得し、ソ
リッド画像を提供するために前記多角形により定義され
る領域を満たす。前記多角形は、前記曲げモデルにおけ
る面及び曲げ線情報から導出され各面の境界を決定する
ことにより導出される。前記多角形は前記パーツの各面
を表示し且つ定義するために生成されなければならな
い。これらの面は次に、板金パーツ全体を表示するため
に、前記曲げモデルにおける前記パーツトポロジー及び
他のデータに基づいて接続される。仮に面が開口部或い
は穴を有する場合には、そのような開口部を囲まない幾
つかの多角形を有する面を定義することが必要となる。
正射図については、個々の図の各々(それはワイヤフレ
ーム又はソリッドである。)についてのデータは前記グ
ラフィックパッケージに送られ、図31に示されるごと
く、結果としての複数の図が単一の表示スクリーン上で
結合される。前記曲げモデル像の種々の観察モード及び
機能を実行するための代表的コードは付録Eに提供され
る。このサンプルコードはC++で記載され前記プロセ
ス及びそこで実行される操作に関連する複数のコメント
を含む。適当なグラフィックパッケージ(例えばオープ
ンGL及びレンダウェア)との結合における前記コード
は異なった図(例えば2次元及び3次元ワイヤフレーム
或いはソリッド)を表示するために使用されるだけでな
く、前記観察機能(例えばズーム、回転、パン等)の各
々の機能を提供する。表示される種々の観察モード表示
スクリーンの簡単な説明が以下に与えられる。
り定義される前記パーツの、ソリッドで表示される3次
元図を表示する。図28は前記板金設備38内での位置
10,12,14,…20のいずれかにおいて設けてあ
る表示スクリーンへ出力として提供される代表的ソリッ
ド図ウインドウを図示する。このソリッド図モードにお
いて、ユーザ或いはオペレータは、3次元空間でのナビ
ゲーション及び3次元自動寸法付けを操作するための複
数の観察機能を与えられる。前記パーツのソリッド図を
変更するために設けられる基本的な機能は回転、ズーミ
ング、パンニング、及び/又は標準図選択を含む。前記
ユーザにより与えられ或いは選択される前記標準図は以
下を含む。即ち等測投影法図、平面図、底面図、正面
図、背面図、左図、及び右図。自動及びマニュアル寸法
付け操作がまた提供され、現在の観察角度に基づいて前
記パーツの重要な寸法を表示する。この発明の寸法付け
特性の代表的例が、図32−36を参照して以下に提供
される。
ドウはウインドウズに基づいたアプリケーションであ
り、従って前記パーツの複数のウインドウ或いは部分図
が提供される。前記複数の図のウインドウは、ウインド
ウの中で1つの極めてクローズアップされた単一の図を
提供する拡大図及び単一のウインドウにおいて前記パー
ツの極めて遠くからの図を与える鳥瞰図を含む。前記部
分図はユーザにより選択されたオブジェクトの部分図を
与える。前記種々の観察機能を制御するために、前記場
所10,12,14,…20の各々の前記サーバモジュ
ール32及びステーションモジュールに、ジョイスティ
ックインタフェースが設けられる。前記ジョイスティッ
クだけ及び/又はキーボード上の所定のキー(例えばシ
フトキー又はコントロールキー)の操作との組み合わせ
の操作が、回転及びパンニング及びズーミングのごとき
種々の機能を実行するためにユーザにより行なわれる。
更に、前記パーツのソリッド図の表示される生地は、デ
ータベース内での前記パーツについて特定された材質を
シミュレートするように選択される。この目的のため
に、スチール、ステンレススチール、アルミニウム等の
ごとき材料の生地のライブラリを有する材料生地ライブ
ラリが提供される。格納された材料生地ライブラリはソ
リッド図が存在する時オペレータによりアクセスされ適
用される。従って、表示されるパーツの表面は前記板金
パーツの実際の生地をより忠実にシミュレートする。
パーツのワイヤフレーム図のウインドウズに基づいた表
示を提供する。ワイヤフレームウインドウの例が図29
に示されている。前記ワイヤフレームにおける3次元空
間ナビゲーション及び3次元寸法付けを提供するための
キーの機能は、前記ソリッド図に関して上に記載したと
類似である。例えば回転、ズーミング、パンニング及び
標準図の選択のごとき機能が提供される。自動寸法付
け、多重図ウインドウ及び断面図オプションも前記ワイ
ヤフレーム図モードにおいて提供される。更に、ジョイ
スティック及び/又はキーボードインタフェースが、ユ
ーザが前記種々の観察機能を選択し且つ活性化すること
ができるように提供される。
表示において、前記パーツの展開された2次元平面図を
表示する。2次元平面図ウインドウの例が図30に示さ
れている。この2次元平面図モードはユーザがウインド
ウ中の図を変更し又は改造するのを可能とするための複
数の観察機能を有する。例えばユーザが前記2次元平面
ワイヤフレーム図を選択的にズームし且つパンするのを
可能とするようにズーミング及びパンニング機能が設け
てある。更に、寸法付け及び多重ウインドウ観察機能
が、前記ソリッド図モードに関して上記したと同様の態
様で設けてある。ジョイスティック及び/又はキーボー
ドインタフェースはユーザがパンし、ズームし他の観察
機能を制御するのを可能とするように設けてある。前記
パーツに設けられている特殊な成形部または形状は、特
殊な成形部の指示又は記載と共に、前記成形領域の前記
最も外側の境界についての成形または形状として表示さ
れる。
ウも前記曲げモデルビューアの一部として提供される。
前記正射図モードはワイヤフレーム表示において平面
図、正面図、右図及び等測投影法図を表示する。隠れ線
オプションが、観察角度に基づいてブロックされた線を
見えなくするために設けられる。この隠れ線オプション
は各図のウインドウを簡単化するために用いられる。前
記正射図モードにおいても種々の観察機能が提供され、
ユーザが前記ウインドウにおいて現在の図を選択的に操
作し且つ変更するのを可能とする。例えば、ズーミング
及びパンニング機能が寸法付け及び多重ウインドウ観察
機能と共に設けられる。上記したように、多重ウインド
ウ観察機能が設けられ、ユーザが、多重ウインドウにお
いて前記正射図の拡大図及び/又は鳥瞰図を選択的に表
示することを可能とする。ジョイスティック及び/又は
キーボードインタフェースが、前記複数の場所の各々に
設けられ、ユーザが、前記正射図モードにおいて前記複
数の観察機能の各々を選択的に活性化し且つ操作するの
を可能とする。
めるのに加えて、前記曲げモデルビューア観察クラスは
他の特徴と共に実行される。例えば前記曲げモデルビュ
ーアはオペレータにより選択され強調されている、現在
の図における複数の項目或いはエンティティーを指示す
るための選択集合を含み且つ維持する。この発明の1つ
の側面によれば、オペレータは、選択された項目に関連
するデータを修正し或いは前記パーツのそれらの項目の
所定の操作を行なうために、前記表示されたパーツの面
及び曲げ線及び他の特徴を選択することを可能とされ
る。例えばオペレータは、表示されたパーツの面を選択
し、その面のその幅或いは長さに沿っての寸法データを
変更することができる。オペレータはまた曲げ角度又は
V幅のごとき各曲げ線に付随する種々の曲げデータを修
正することができる。
択されたエンティティー或いは項目(例えば面、曲げ
線、面或いは曲げ線の端等)のリストを保持する。観察
者はそのリストを更新する。従ってオペレータにより現
在選択されている現在の項目は前記選択リストに常に保
持される。この発明におけるソフトウエアの他の部分
は、異なる手順(例えばマニュアル寸法付け等)を実行
し或いは行なう際、選択されたエンティティーの前記現
在のリストの図面クラスを呼び出す。
機能を提供する。それは現在表示されている図に基づい
て観察可能性情報及び座標情報を提供する。以下に更に
十分に説明されるように、前記観察可能性機能は前記パ
ーツの特定な部分或いはエンティティーがスクリーン上
で現在観察可能であるか否かについての情報を提供し且
つスクリーンエンティティーが現在位置する場所につい
ての座標情報を提供する。前記曲げモデルビューアの観
察可能性機能は、前記パーツのどの部分が現在スクリー
ン上で観察可能であるかを決定するためにこの発明の寸
法付け特性により呼び出される。従ってスクリーン上で
観察可能である前記パーツの部分の寸法情報のみが観察
者に対して表示される。この発明の寸法付け及び観察可
能性機能のより詳細な説明は以下に提供される。更に前
記曲げモデルビューアの観察可能性機能を実行するため
の代表的コードはここに添付する付録Jに提供される。
つの側面に基づく、寸法付け特性の事例が説明される。
上記したように、観察モードの各々は現在の観察方向に
基づいて、前記パーツの寸法を自動的に表示する寸法付
け機能を含む。自動寸法付け機能は、現在の観察角度に
おいては見ることができないフランジ或いは曲げ線の寸
法がユーザに対して表示されないように提供される。前
記自動寸法付け機能或いはモードが活性化される時、前
記パーツの観察可能な寸法のみが、現在の観察角度に基
づいて表示される。更に、自動寸法付けモードにおいて
は、所定の寸法(即ち前記曲げ操作に対して重要である
寸法)のみが現在の観察角度の状態に基づいて表示され
る。マニュアルの寸法付けモードも提供され、ユーザが
どの寸法が表示されるべきであるかを選択的に指示する
ことを可能とする。このマニュアル寸法付けモードにお
いては、ユーザにより選択された寸法事項のみが、現在
のパーツの観察角度に基づいて表示される。いずれの寸
法付けモードにおいても、表示された寸法事項は、前記
パーツがズーム化され或いはパンされる時ウインドウ表
示から消去され或いは除去される。
される種々の寸法事項の例を図示する。前記自動寸法付
けモードにおいて表示される寸法事項は、曲げ操作に重
要な事項(例えばフランジ長さ、曲げ線長さ、曲げ角度
等)からなり、パンチ加工された穴或いは開口部の寸法
のような余分な寸法事項ではない。前記表示される寸法
事項は例えば前記板金パーツの幅、深さ、及び高さ並び
にフランジ長さを含む。更に、各曲げ線の前記曲げ線長
さL、曲げ角度A、内側半径R及び曲げ縮小Dは単独で
或いは一緒に、1つのウインドウに或いはグループ情報
ボックスに表示される。上記したように、現在の観察角
度に基づいて観察可能な寸法事項のみが表示される。更
に前記オペレータが、前記パーツの観察角度を変えるた
めに回転、ズーミング或いはパンニングをする時全ての
寸法は表示から消去され或いは除去され、各操作が完了
した時それらの寸法は再び表示される。表示情報(任意
のテキスト或いは参照矢印)の寸法及び向きは、現在の
ズームの比率或いは観察角度ではなくスクリーンの寸法
に対して常に寸法調整される。しかしながら、前記寸法
情報の可読性を改良するために前記寸法情報の色、スタ
イル、重み及び/又はフォントはユーザがそれらを変更
できるように形成可能である。結果としてオペレータ或
いはデザイナーは、前記寸法情報の特殊の色、フォント
サイズ等を選択することによりパーツにおける重要な寸
法を強調することができる。例えば、寸法テキストの
色、寸法又はフォント又は、寸法参照事項、線又は矢印
の色、線の重み或いはスタイルは、パーツにおける重要
な寸法を指示するために強調され或いは選択的に変更さ
れる。オペレータはまたウインドウ情報ボックスを色付
けし満たし或いはスタイル付けし或いは特定の曲げ線を
色付けし或いはパーツ内の他の重要な寸法を強調する。
種々のプロセス或いは操作が利用される。更に上記した
ように本発明の寸法付け特性に対して観察可能性情報を
提供する観察可能性機能を、前記曲げモデルビューアは
備える。これらの機能或いは特性は、例えばサーバモジ
ュール32及び/又は工場全体に位置するステーション
モジュールのそれぞれでソフトウエアにより実行され
る。この発明の自動寸法付け特性を実行するための代表
的コードが付録F−Iに設けてある。更に、曲げモデル
ビューアの観察可能性機能のためのサンプルコードが付
録Jに設けてある。これらの付録におけるコードはC+
+プログラム言語で書かれており、そこで行なわれる手
続き及び操作の論理フローの理解を容易にするためのコ
メントを含む。
般的に3つの段階に分類される。第1の段階で、前記パ
ーツの曲げモデル幾何形状及びトポロジーデータがデー
タベース30からアクセスされ、前記パーツの全ての寸
法並びにそれらの寸法が表示され得る全ての態様を計算
するために使用される。前記パーツの各曲げ線及び面に
ついて、データが表示され得る全ての最も遠い点が計算
され、これらの点について、寸法線或いは矢印が表示さ
れ得る全ての方法が計算される。前記寸法データ或いは
他の情報が表示され得る場所を決定する際に一定のヒュ
ーリスティックが適用される。例えば一般的なルールと
して、全ての情報は前記パーツの外側にのみ表示される
と決定される。このようなヒューリスティックが、前記
ビューアに対してより意味のあるそしてより込み合わな
い情報の表示を提供するために適用される。
特性がオペレータにより活性化された際常に実行され
る。或いは、前記第1段階の計算は前記パーツが最初に
オペレータにより観察された際にのみ行なわれる。この
ような場合に、前記計算されたデータは次の使用のため
にメモリに格納され、前記パーツの寸法或いは他の幾何
学的データがユーザにより修正され或いは変更された時
変更される。更に前記第1段階の全ての計算は図面スク
リーンに対してではなくパーツの幾何学形状に対して行
なわれる。従って前記データは、現在の図面に関わりな
く或いはその図面が変更されても何時でも再び使用され
得る。
前記パーツの図面が更新された時常に行なわれる。この
第2段階の主たる目的は、変更された図において前記パ
ーツのどのエンティティーが観察可能であるかに基づい
て前記第1段階中に生成されたデータをふるいにかける
ことである。この第2段階において、現在の図において
観察可能でない全てのデータはふるいにかけられ、現在
観察可能である、前記第1段階において計算されたデー
タのみが残る。前記パーツのいずれの点あるいは部分が
現在観察可能であるかを決定するために前記曲げモデル
ビューアに対する機能コールがなされる。上記したよう
に、前記曲げモデルビューアは、表示されている現在の
図に基づいて前記パーツの観察可能な部分についての情
報を保持し且つ提供する観察機能を含む。前記パーツの
向きに基づいて前記曲げモデルビューアは前記パーツの
どの面及び曲げ線(並びにそれらの面及び曲げ線のどの
端或いは部分)が観察可能であるか、そして何がスクリ
ーン上で隠されているかを決定する。
の観察可能機能を実行するためのサンプルコードは付録
Jに提供される。前記パーツのいずれの点あるいは部分
が観察可能であるかを決定するために、前記曲げモデル
ビューアは前記パーツの現在の図の向き及び現在のズー
ム面又は表示されているパーツの比率を決定し且つ維持
する。前記曲げモデルビューアはこの現在の図の向きを
決定し維持するために従来の透視図射影技術(モルテン
ソンの例えば12章を見よ)を使用する。前記パーツの
任意の点の観察可能性を決定する際に前記点の世界座標
(即ちそこにおいて前記パーツが表現されているところ
の座標)を前記観察可能性機能は獲得する。次に、前記
現在の図面の向き及びズーム面あるいは比率に基づいて
その点について、前記世界座標に対応するスクリーン座
標(即ちスクリーン上の画素の位置)が決定される。そ
の後、前記スクリーン座標に基づいて、前記スクリーン
の観察点の眺めから前記部品の任意のエンティティー或
いは部分が問題の点の前方にあるか否かが決定される。
前記パーツの上の点の隠されている特性は、前記パーツ
の他のエンティティー或いは部分が問題の点と同じスク
リーン上の点を割り当てられているかどうかに基づいて
も決定され得る。グラフィックパッケージ或いはライブ
ラリ(例えばオープンGLあるいはレンダウェア)への
機能コールは、前記パーツの1つの点以上が同じスクリ
ーン上の点に割り当てられているかどうかを決定するた
めに使用される。もし何かが同じスクリーン上の点に割
り当てられているならば、それらの点のそれぞれのZバ
ッファ深さに基づいて、前記パーツの点がそれの後ろに
あるかどうかが決定される。前記Zバッファ深さはオー
プンGL或いはレンダウェアのごときグラフィックパッ
ケージにより使用され、観察点或いはカメラ位置からそ
れぞれの点への距離を定義する。前記Z深さは、興味の
ある前記パーツの複数の点について前記グラフィックパ
ッケージへ機能コールを行なうことにより決定される。
の前記プロセスはこの発明の自動寸法付け特性から前記
曲げモデルビューアへ催促がある時いつでも実行され
る。そのようなプロセスは従って前記オペレータにより
表示されているパーツの現在の図が修正され或いは変更
される時いつでも実行される。上記したように、前記曲
げモデルビューアは、表示された画像の向きに対して変
更がなされる時は常に、現在の図の向き及びズーム比の
状態を維持し且つ更新し、従って要求される時観察可能
性情報を正確に提供する。
後、自動寸法付け機能は、(例えば第1段階での計算に
基づいて)前記寸法データ或いは他の情報が表示され得
る全ての可能な方法及び位置を決定する。前記データが
表示され得る全ての可能な方法からデータを表示するた
めの最適の方法を選択するために一群のヒューリスティ
ックが適用される。例えば第1のヒューリスティック
は、観察者の観察点により近いスクリーン上の領域が好
ましいと要求する。第2のヒューリスティックは、前記
寸法を定義するための2つの可能な点の間の距離が最小
であるところの領域により近い領域にデータは表示され
るべきであると規定する。他のヒューリスティックはま
た、スクリーン上での重なり合い或いは混雑を避けるた
めに、他の寸法データ或いは他の情報の相対的位置に基
づいて適用される。
可能な領域についての情報を表示するための最適の領域
を決定した後、前記自動寸法付け機能の第3の段階は前
記表示スクリーン上で種々の情報を描くために実行され
る。例えば、前記情報を表示するための領域の選択に基
づいて、寸法情報は前記パーツの観察可能な寸法の各々
についてスクリーン上に表示される。更にどの曲げ線が
観察可能であるかに基づいて、曲げ線情報がまた、他の
パーツ情報とオーバーラップしないスクリーンの領域に
おいて情報ボックス(例えば図32に示されるそれ)に
表示される。前記パーツの幅、高さ、及び深さを含むパ
ーツの寸法はまた前記スクリーン上の所定の位置(例え
ば前記パーツの右下)或いは前記パーツに最も近く他の
情報にオーバーラップしない或いはそれを邪魔しない位
置に表示される。
て寸法事項を表示する際に、使用される種々の方法及び
定義を図示する。特に図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)に示されるそれのごとき交差寸法方法が使用
される。オペレータは、前記フランジ長さを表示するた
めに前記接線寸法或いは交差寸法方法のうちから選択す
ることを可能とされ、及び/又は特定の寸法方法(例え
ば接線寸法方法)はデフォルト設定として提供される。
種々の表示機能を有した図形的ユーザインタフェースが
設けられ、オペレータによる曲げプランの生成を助け
る。図37−44はこの発明の他の側面により、図形的
ユーザインタフェースの使用により曲げコード順番を生
成するために実行される種々の手続き及び操作を図示す
る。通常、最初の曲げモデルデータ及び他の作業情報は
サーバモジュール32において重要な幾何学的及び製造
データを入力することにより設計プログラマにより生成
される。結果としての曲げモデルファイルは次にデータ
ベース30に格納される。板金パーツが製造される前
に、曲げオペレータが、所望の曲げ操作を実行するため
の曲げ順を生成する必要がある。この曲げオペレータ
は、どのタイプの工具が必要であるかを決定し且つ前記
曲げ機械装置について工具取付けを定義しなければなら
ない。この曲げプラン生成の工程は、図形的ユーザイン
タフェースの使用によりまたこの発明の種々の教示によ
り援助され、且つより効率的となる。
曲げステーション18の曲げオペレータは、前記データ
ベース30から前記曲げモデル及び他の作業情報へアク
セスし且つダウンロードする。前記関連するパーツにつ
いての曲げモデルは前記コミュニケーションネットワー
ク26を介して曲げステーション18における工場フロ
ア上のステーションモジュールへ搬入され或いは移入さ
れる。この工程は、一般的に図37のステップS220
に示される。その後、ステップS224で曲げオペレー
タは、前記曲げモデルビューアを用いて前記パーツの形
状及び寸法を調べる。ここで、前記曲げオペレータは、
前記曲げステーションに位置付けられた表示スクリーン
で前記パーツの種々の2次元及び3次元図を選択的にズ
ームし且つパンする。この発明の自動寸法付け特性を活
性化することにより、前記曲げオペレータはまた曲げ操
作を実行するために前記パーツの重要な曲げ寸法を観察
する。
法を理解すると、この曲げオペレータはステップS22
8で曲げ順入力ウインドウを選択し且つ表示することに
より前記曲げプランを生成することを開始する。前記曲
げ順入力ウインドウは、曲げオペレータが曲げ順を生成
し且つ修正し且つ消去するのを援助するために図形的ユ
ーザインタフェースを提供し且つオペレータが、前記曲
げ順における各段階についての種々の製造パラメータ
(例えばバックゲージ位置、工具、NCデータ等)を特
定し且つ入力することを可能とする。前記曲げ順入力ウ
インドウは前記スクリーンの一部(例えばスクリーンの
中央部或いはスクリーンの左側の方)に表示される前記
パーツの2次元平面図画像を含む。前記2次元平面図画
像は、前記パーツのフランジ、穴及び開口部を含む、前
記展開パーツの種々の特徴を含む。前記曲げオペレータ
が前記複数の曲げ線及び各曲げ線についての曲げ順を選
択し且つ指示すると、各曲げ段階における前記中間的パ
ーツ形状のソリッド2次元或いは3次元画像が現れ、例
えば図38に示されるように、スクリーンの右側の端の
ごときスクリーンの一部にそれらが提供される。前記中
間パーツ形状の画像は入力された曲げ順に対応した順番
で表示され且つ(図38の例に示されるように)前記パ
ーツの2次元平面図と共にスクリーン上に同時に表示さ
れ、或いは別個のスクリーン表示に別個に表示される。
曲げ線は強調され、図39(a)に一例として示される
ように、曲げ順番号及び挿入方向(例えば矢印で表現さ
れる)が前記曲げ線の上或いは近くに表示される。各曲
げ線についての前記曲げ線番号は、それが選択される順
番に基づいて自動的に設定され、或いは各曲げ線が選択
された後オペレータによりマニュアルで入力される。曲
げ角度、曲げ線長さ、及びバックゲージ位置のごとき曲
げ線に関連する他の製造情報も、図40及び41に例と
して示されるように、各曲げ線が選択され強調されると
き入力され及び/又はスクリーン上に表示される。図4
0及び41に示すように、ダイアログ或いは情報ボック
スがスクリーン上に表示され、曲げオペレータが各曲げ
線に関連する製造情報及び他のパラメータを選択し、入
力し或いは修正することを可能とする。
げオペレータが曲げ線を強調し或いは選択するのを可能
とする。ホット機能キー或いは高速スイッチキーが前記
曲げシーケンス入力ウインドウに表示され、オペレータ
が工具立てを選択し或いは入力し且つNCデータを監視
し且つ修正するのを可能とする。例えば曲げオペレータ
は、工具機能キーを選択し、前記曲げ順入力ウインドウ
から、工具立て情報を入力するための工具入力表示スク
リーン或いは複数の表示スクリーンへ切替える。NC機
能制御キー(例えばNC9EX)も設けられ、オペレー
タが実行されるべき曲げ操作に関連するNCデータを監
視し及び/又は修正するのを可能とする。更に図40及
び41に示されるように、曲げ線を定義し及び/又は修
正すること及び関連する製造情報に関連して他の機能キ
ー及び制御部が設けられている。例えばZOOM AL
Lキーが、前記2次元平面図画像をズームイン及びズー
ムアウトするために設けられている。バックゲージキー
は、前記バックゲージの位置を選択し或いは設定するた
めに設けられている。グループ化及びグループ解除化制
御キーは、一緒に曲げられる複数の曲げ線を可能とし或
いは制御するために表示される。更に制御キー(例えば
アマ曲げ)が特殊な曲げ操作を定義するために設けられ
ている。他の機能キーも表示されオペレータが前記曲げ
順を選択し、修正し及び/又は消去するために設けられ
ている(例えばREMOVE CLEAR FWD、C
LEAR ALL、OK、CANCELL)。この曲げ
順入力ウインドウにより、曲げオペレータは、前記曲げ
順及び種々の製造情報を効率的に監視し且つ修正するこ
とが可能となる。
ーツの断面図及び/又はパーツの曲げシミュレーション
が、前記曲げ順における各曲げ工程についてスクリーン
上に表示される(例えば図41を見よ)。前記断面図及
び曲げシミュレーションは前記スクリーン上に選択的に
表示され、或いは曲げオペレータにより各曲げ線が選択
される時表示される。前記断面図及び曲げシミュレーシ
ョンは、例えば上下曲げ工具(例えばパンチ及びダイ)
又はバックゲージ位置・設定の表現を含み、それらは前
記2次元平面図画像と共に同時にスクリーン上に表示さ
れ或いは異なるスクリーン表示上に別個に表示される。
前記バックゲージ位置は前記パーツのトポロジーに基づ
いて自動的に決定され或いはオペレータにより設定され
或いは修正される。前記曲げ線のための工具立て情報が
入力されておらず或いは曲げオペレータにより設定され
る場合には、前記断面図及び/又は曲げシミュレーショ
ンはスクリーン上に表示されず又は前記中間パーツ形状
の表現及び計算され或いは定義されたバックゲージ位置
のみが表示される。前記曲げシミュレーションは、前記
パーツの所望の反転、前記パーツの操作及び配向動作及
び/又は各曲げ線でなされる前記パーツの曲げ加工の表
示されるシミュレーションを含む。前記表示スクリーン
上に前記パーツの2次元平面図画像と共に、曲げ工程の
前のパーツの断面図及び曲げ工程がなされた後の前記パ
ーツの断面図を同時に表示することもまた可能である
(例えば図41を見よ)。これらの断面図は、スクリー
ンの右側に提供され前記曲げ順における各曲げ工程につ
いての前記上下曲げ工具及びバックゲージの表現を含
む。更にズーム制御或いは機能キー(ZOOM IN及
びZOOM OUT)が表示され、オペレータが、前記
曲げ前及び曲げ後断面図に関連してズームの比或いは向
きを制御することを可能とする。日本公告公報平7−1
21418(丹羽等の名前で1995年12月15日に
発行)及び日本公開公報平1−309728(長沢等の
名前で1989年12月14日に発行)に開示されるそ
れと類似の技術及び手続きが前記パーツの断面図或いは
曲げシミュレーションを表示するために使用される。前
記文献の開示はここにその全体において参考により積極
的に取り込まれる。
た曲げ線に関連して前記パーツの短い或いは小さいサイ
ドを計算することにより前記曲げについて挿入方向を自
動的に決定するためのソフトウエア或いはプログラム論
理が提供される。この発明の特徴に基づいて、各曲げ線
はそのパーツを2つのサイドに分断するために使用され
る。挿入方向は、より小さい或いは短い長さ(例えば前
記曲げ線に直交する辺の寸法)を有する前記パーツのサ
イドに基づいて或いは、より小さい全体的面積を有する
サイドに基づいて各曲げ線について決定される。もしオ
ペレータが前記選択された挿入方向に満足しない場合に
は、図39(b)に図示されるように、オペレータは挿
入方向を反転する。オペレータは挿入方向を、例えば曲
げ線が強調されている際にマウス或いはキーパッドの選
択ボタンをクリックすることにより変更し或いは反転す
る。挿入方向情報は、曲げ装置或いは機械装置で前記パ
ーツを曲げ加工するために、前記曲げ線により定義され
るフランジの挿入方向を指示するための矢印及び/又は
テキストを含む。前記挿入方向情報は、曲げ線の上或い
は近く(例えば図39(a)及び39(b)を見よ)或
いは関連するフランジの端の上或いは近く(例えば図4
0を見よ)に表示される。更に前記挿入方向情報は、各
曲げ線が選択された時に表示され或いはジョイスティッ
ク装置、マウス装置、或いはキーボード装置から受け取
った入力に基づいて選択的に表示される。
を介して、曲げオペレータは、種々の中間形状及び最終
パーツの形を、オペレータにより入力された選択された
曲げ順に基づいて見ることができる。再び、オペレータ
はジョイスティックインタフェース、マウスインタフェ
ース及び又はキーボードインタフェースのごとき適宜の
入力装置を通して前記スクリーン上にデータを入力し選
択することができる。曲げオペレータが提案された曲げ
順に満足しない場合には、曲げオペレータは、ステップ
S232に一般的に示されるように曲げプランを最終化
する前に曲げ順を編集する。この曲げ順の編集は種々の
やり方及び方法において実行される。特にこの発明の1
つの側面によれば、ドラッグ及びドロップ編集特性が提
供され図42に示されるようにオペレータは単に、前記
スクリーンの左側或いは右側に提供された中間的パーツ
形状アイコン或いは表示の1つをつかみ且つそれを前記
順番の所望の位置へドロップすることにより選択された
曲げ順を編集する。その後、前記曲げ順に対する曲げオ
ペレータの修正に基づいて前記スクリーン上の前記種々
の中間パーツ形状が修正され、改定された曲げ順に基づ
く中間的曲げ段階を示す。更に前記曲げオペレータの前
記曲げ順のドラッグ及びドロップ編集に基づいて、前記
2次元平面図画像上の曲げ順番号が改定される。
は、ステップS236に示すように、格納された工具立
てデータのライブラリから工具を選択することによりど
のタイプの工具立てが使用されるべきであるかを決定す
る。関連する工具立て情報は、工場フロアの曲げオペレ
ータに対して表示され、曲げオペレータが前記ライブラ
リから工具立てを選択するのを図形的に支援するために
表示メニューが提供される。一旦特定の工具が前記ライ
ブラリから選択されると、前記工具に関連するデータが
スクリーン上に表示される。図43は、マニュアル工具
選択のために前記曲げオペレータに対して図形的に表示
される種々の表示メニュー及びデータテーブルの事例を
図示する。図43の例では前記曲げオペレータが前記工
具ライブラリから特定の工具を取り出すのを支援するた
めに、連続的な表示メニュー或いはスクリーン表示が図
形的に表示される。連続的に表示されるスクリーン表示
は前記表示装置上に連続的に表示され(例えばオーバー
ラップする或いはカスケードする態様で)或いはそれは
個々に表示され、そのスクリーンは次の引き続くスクリ
ーン表示が表示される前にクリアされる。一旦特定の工
具が選択されると、その工具に対する特定のデータがテ
ーブルに提供され且つオペレータに表示される。工具ラ
イブラリにおけるデータは、前記ソフトウエアの最初の
セットアップ手続きにおいて、(例えばデータベース3
0の中に)予め定義され且つ可能されている。
レータが工具タイプを選択し且つ各タイプにおいて工具
の形状を選択することを可能とする。例えば、パンチ、
ダイ、ダイホルダ、及びダイレールを含む種々の工具タ
イプが選択される。各タイプは多数の形状からなり、且
つ各形状に対して異なったサイズ及び寸法の多数の工具
が存在する。1つの工具を選択するために、ユーザは、
図43に示されるような、表示される工具タイプアイコ
ンから1つのアイコンを選択することにより1つの工具
タイプをまず特定する。その後ユーザは選択された工具
について利用できる異なる形状のメニューを提供され
る。工具形状を分析した後、ユーザは選択された工具に
ついて、表示された形状アイコンから1つの形状アイコ
ンを選択することにより工具形状を選択する(例えば図
43では、グースネック形状パンチが選択された)。最
後にユーザは選択された工具形状について適当なサイズ
及び寸法を選択する。図43に更に示されるように、選
択された工具形状に対して利用可能な工具の異なるサイ
ズ及び寸法を示すためのテーブルがユーザに対して表示
される。このテーブルから1つの項目を選択することに
より、選択された工具がアイコンとして表示され一般的
な工具タイプアイコンに置き変わり、且つ工具の選択を
確認する。
に図形インタフェースの支援により、プレスブレーキに
おける種々の工具段階(工具ステージ)を設定する。図
44は前記曲げプランにおいて使用される工具セットア
ップ(工具取り付け)の定義を容易にするために曲げオ
ペレータに対して与えられる代表的工具セットアップウ
インドウを図示する。図44に例として示されるよう
に、種々のパンチ、ダイ及びレールのデータが前記ツー
ルセットアップウインドウに表示される。前記板金パー
ツのための工具及びダイの情報はオペレータにより入力
される。ジョイスティックが曲げオペレータのステーシ
ョンモジュールに提供され曲げオペレータが工具位置を
指示し且つ利用可能な工具及びダイのリストから工具及
びリストを選択することを可能とする。この工具セット
アップウインドウにおいてスクリーンの左側は現在の工
具セットアップの断面形状を表し、スクリーンの右側は
プレスブレーキにおける現在のセットアップの位置を表
示する。現在のセットアップの位置は図44に示される
ように強調され或いは影が付けられる。
記工具立て及び曲げシーケンスを含む曲げプラン情報
が、図37におけるステップS242に一般的に示され
るように、前記データベース30の中に前記曲げモデル
と共に保存される。前記曲げ順の実際のテストが、前記
曲げオペレータにより選択された曲げ順を確認するため
にプレスブレーキにより行なわれる。もし必要なら、前
記工具立ての定義或いは曲げ順に対する更なる修正が、
前記ステーションモジュールにおけるオペレータ或いは
デザイナーにより実行される。
ランの生成における前記曲げオペレータを支援するため
に設けられる。例えばこの発明の他の側面によれば、工
具立てエキスパートが設けられ、前記曲げオペレータに
対して前記曲げモデルに格納されたパーツ形状及び他の
情報に基づいて、工具立て及び曲げ順の示唆を自動的に
与える。前記工具立てエキスパートからの示唆は当該示
唆の分析の後、曲げオペレータにより改定される。更
に、より複雑な工具立てエキスパートシステムが提供さ
れ、前記曲げファイルにおける前記パーツの形状、及び
潜在的な衝突及び干渉をチェックするための工具の形状
分析に基づいて更に複雑な操作について工具立て示唆及
び曲げ順示唆を行なう。そのようなエキスパートシステ
ムは手動或いはロボットにより支援された曲げ機械装置
により使用され実行される。限定しない例として、この
発明はデービッドAボーン等の名前による「板金曲げプ
ランを生成し且つ実行するための知的システム」と題さ
れる米国特許出願第08−386.369、及びデービ
ッドAボーン等の名前による「ロボットウインドウの計
画/制御の方法」と題される米国特許出願第08−33
8.115号に開示される特徴及び教示により実行され
る。これらの開示はここに全体として参照により積極的
に取り込まれる。上記したように図形的ユーザインタフ
ェース或いは種々の機能は、板金パーツのための曲げプ
ランを生成する際に曲げオペレータを支援するために設
けられる。この発明の他の側面によれば、追加の特徴が
更に設けられ、前記パーツの設計及び製造において支援
を行なう。以下に更に十分に説明するように、音声的或
いは視覚的情報の格納のごとき種々のマルチメディア機
能が本発明において実行され前記曲げプランを生成し或
いは曲げ順を実行する際に曲げオペレータに対して追加
の支援を行なう。更に、中間の曲げ段階の各々において
前記工具及びパーツの間の潜在的干渉及び衝突を自動的
にチェックする衝突チェック機能が提供される。この衝
突チェック機能は、工具形状及び、パーツにおける間隔
の面倒で時間のかかるマニュアルチェックに置き変わる
ために提供される。前記マニュアルチェックは曲げプラ
ンを生成する際曲げオペレータにより通常行なわれる。
これらの機能及びその他のものは添付する図面を参照し
て今から説明される。
モデルデータと共に音声及び映像情報を格納するための
方法が設けられる。種々の音声及び映像情報は、工場フ
ロアにおいて記録され、例えば板金パーツの操作及び曲
げ加工に関連する特殊な指令を提供する。この目的のた
めCCDカメラ又はディジタルカメラが音声マイクロフ
ォンと共に種々の場所10,12,14,…20のステ
ーションモジュールの各々に設けられる。他の装置、例
えばオーディオマイクロフォンを有するビデオカメラが
オペレータ或いはユーザが音声或いは映像の情報を記録
することを可能とするために前記ステーションモジュー
ルに設けられる。前記種々の記録装置は工場フロアにお
けるステーションモジュールコンピュータに接続され
る。限定しない事例としてインテルのPROSHARE
個人会議CCDカメラ(インテル株式会社から入手可
能)が音声及び映像情報を記録するために使用される。
他の商業的に入手可能なCCDカメラ或いはディジタル
カメラもそのような情報を記録するために使用される。
々の音声及び映像情報は種々の方法及び手続きにより、
ユーザによりアクセスされ且つ読み出される。例えば格
納された音声及び映像情報を再生するために、前記ステ
ーションモジュールによりメニューオプションが表示さ
れる。更に、この発明の好適な実施例によれば、オペレ
ータは、観察ウインドウに表示されるアイコンを選択し
且つ生成することにより、格納されている音声及び映像
情報を種々の表示スクリーン及びパーツの図に付随させ
る能力を有する。この機能は、ソフトウエア及びオブジ
ェクト指向プログラム技術により実行される。これによ
りアイコンオブジェクトは曲げモデルデータ構造の中に
生成され且つ格納される。このアイコンオブジェクト
は、ある種の条件(例えばマウスのダブルクリック或い
はジョイスティック或いは他の入力手段の使用による選
択の指示によるオペレータによるアイコンの選択)に基
づいてメモリから付随された音声及び映像情報を読み出
すための手続きを含む。この発明のアイコンの特徴によ
りオペレータは異なる音声及び映像メッセージ或いは情
報を前記板金パーツの異なる部分及び任意の表示に関連
させる。このアイコンを前記パーツの表現に組み込むこ
とにより、前記アイコンは、スクリーン上で画面が変わ
るにつれて前記パーツの2次元及び/又は3次元モデル
の表示と共にズームし、回転し並進運動するように構成
される。
ルに張り付けられたアイコンの使用を介して音声及び映
像情報を添付する事例を図示する。ユーザが前記音声及
び映像情報を記録した後、オペレータが前記3次元モデ
ルウインドウの任意の位置にアイコンを張り付ける。前
記アイコンがオペレータ或いはユーザにより次に選択さ
れる時、格納された音声及び映像情報は再生され、前記
ウインドウに表示され、そのアイコンが配置された前記
パーツのある部分或いは領域に関する特殊な指令又はメ
ッセージを提供する。他の情報、例えば前記曲げ運動の
シミュレーション或いは記録は前記パーツの種々の曲げ
線の近傍にアイコンを置くことにより前記パーツに関連
される。前記曲げ運動に関連する映像情報は次に前記ア
イコンが選択される時ユーザに対して再生される。
情報を記録し、或いは単に1つの音声メッセージ或いは
静止或いは運動映像信号を記録し、それらはユーザに対
して選択的に再生される。前記ウインドウ表示に対して
付着されたアイコンは格納された情報のタイプを図形的
に指示する(例えば、音声情報が格納されていることを
示しているためにマイクロフォンのアイコンが表示され
又は映像情報が格納されていることを示すために表示モ
ニタのアイコンが表示される)。特殊なアイコンは、そ
のアイコンに音声及び映像情報が関連されていることを
示すために設けられる(例えば「A/V」の記号或いは
マイクロフォンを含むビデオカメラのアイコン)。アイ
コンの一覧が設けられ且つ表示され、ユーザが、前記ス
クリーン表示或いは画像に対して音声及び或いは映像情
報を添付する際に種々のアイコンから選択することを可
能とする。
み出すためのアイコンを組み込んだ表示ウインドウの他
の事例を図示する。図46に表示された表示ウインドウ
は、図42を参照して上で説明したそれのごとき、工具
セットアップスクリーン画像に関連する。図46の例で
は、音声情報が格納され、マイクロフォンのアイコンに
より読み出される。そして別個の映像情報が格納され、
前記表示ウインドウに対してビデオアイコンを張り付け
ることにより読み出される。前記音声及び映像情報は工
具セットアップ或いは操作に関連する特殊な指令或いは
情報に関連する。更に現在活性化されているウインドウ
表示のタイプに関係なく、オペレータは、異なる音声及
び映像情報を後に読み出すために、前記ウインドウ表示
における種々の領域に必要なだけ多数のアイコンを張り
付けることができる。
インドウ特性が提供され、オペレータが格納された画像
を選択しそれらを異なるスクリーンへ適用するのを容易
にする。前記画像編集ウインドウ特性はウインドウに基
づくアプリケーションとして提供され、それは例えばサ
ーバモジュール32或いは製造設備を通して設けられた
ステーションモジュールのいずれかにおいてアクセスさ
れる。図47は、この発明の教示により実行される画像
編集(イメージ編集)ウインドウの例を図示する。前記
イメージ編集ウインドウに表示される画像はディジタル
カメラ或いはCADコーダによる画像写真を含む。前記
スクリーンに表示される画像はオペレータにより(例え
ばマウス或いは他の適当なデータ入力手段により)選択
的に選ばれ、他のスクリーンにコピーされ、それらはパ
ーツの特定のモデルの図に関連させられる。オペレータ
は次にその画像或いはアイコンを前記モデルのウインド
ウ(例えば図46に関連して上で示したそれのごとき前
記パーツの3次元ソリッドモデルウインドウ)へ張り付
ける。図45、46及び47の画像は実際のスクリーン
画像の写真再生である。実際の画像イメージは、使用さ
れるカメラ或いはスクリーンの解像度に応じてそれ自体
更に明瞭である。前記画像は例えば、曲げ操作に関連す
る特殊な操作或いは他の指令を議論し或いは図示する曲
げオペレータの静止或いは運動映像イメージを含み、或
いは板金曲げ操作の映像イメージである。換言するば、
有用であると思われる実際の画像が取られ後に表示され
る。従って図45−47に示される実際の画像は例示的
な目的のためのみのものである。図48及び49を参照
するに、この発明の衝突チェック機能の例が設けてあ
る。この発明の1つの側面によれば、衝突チェック機能
が設けられ、ユーザは前記パーツ及びパンチ工具の間の
潜在的な衝突を、図形的ユーザインタフェースの使用に
よりチェックすることを可能とする。前記衝突チェック
機能はウインドウズに基づくアプリケーションであり、
前記製造設備における任意のステーションモジュール或
いは場所でアクセスされる。この発明の自動的衝突チェ
ック機能は、前記曲げプランを生成する際に通常行なわ
れている伝統的なそして面倒なマニュアルの形状チェッ
クに変わり曲げオペレータにより使用される。
成する際、曲げオペレータはまず前記パーツの曲げ順を
決定する。前記曲げ順は前記板金パーツが製造の間に曲
げられる順番或いは態様を決定する。その曲げ順が決定
された後、曲げオペレータはその曲げ操作の各々を実行
するために使用される工具を選択し定義する。この過程
で、選択された前記工具の形状及び前記パーツの中間的
形状が、前記曲げ工程の各々を実行する際に前記工具と
パーツとの間の干渉あるいは衝突が存在しないことを確
実にするために解析される。衝突或いは干渉が検出され
る場合には、選択された工具のタイプ(或いは必要に応
じて曲げ順)は、前記工具と板金パーツとの間の干渉或
いは衝突を生ずることなく曲げ操作が実行されるように
修正されなければならない。
前記工具の形状と板金要素の曲げられた部分或いは形状
との間のクリアランスを分析するために、曲げオペレー
タは伝統的にマニュアルの方法に頼っていた。典型的に
は、曲げオペレータにより工具形状のモデルが構成され
使用されている。工具形状モデルは、板金の種々の中間
的形状の工学的或いは技術的図面(前記工具形状モデル
と同じスケールの寸法を有する)に対してマニュアルで
合わせられ或いはその上に置かれる。この工具形状モデ
ルを前記パーツの図面に対して適合させ及び合わせるこ
とにより前記曲げオペレータは、曲げ工程の各々におい
て工具とパーツとの間に十分な空間或いはクリアランス
があるかどうかを決定することができる。しかしながら
この工程は面倒で且つ時間を浪費する傾向がある。
ることにより、そのような伝統的な方法の不利益を克服
することである。この発明の干渉チェック機能は、図形
的ユーザインタフェースを介して実行され、曲げオペレ
ータが所定の曲げ順における各中間的工程において衝突
をチェックするのを可能とする。図48及び49は図形
的ユーザインタフェースを介して実行される衝突チェッ
ク機能の例を図示する。活性化される時、前記衝突チェ
ック機能は前記曲げ順における前記パーツの各中間的形
状とその順番に対して定義されるパンチ工具或いは複数
の工具との間の衝突を自動的にチェックする。前記中間
形状はスクリーンに表示され(例えば図48及び49を
見よ)、衝突が発見されると、当該衝突が検出される工
程がスクリーン上に強調される。更にテキストのごとき
他の表示示唆が検出された衝突の数を指示するために提
供される。図48及び49の例では、前記衝突情報は表
示ウインドウの右上領域に提供される。更に、前記衝突
がチェックされたパンチ工具或いは複数の工具のタイプ
は表示ウインドウの左上領域に表示され或いは指示され
る。
チ工具について検出される時、衝突が検出される中間的
形状或いは段階がスクリーン上に強調される。この場
合、オペレータはその特定の曲げ段階について他のパン
チ工具を選択することもでき、前記パンチ工具の第2の
選択について衝突が起きるか否か決定するために前記衝
突チェック機能が再び実行される。オペレータは、各曲
げについてパンチ工具を選択し、前記衝突チェック機能
により衝突をチェックすることができる。ドラッグ及び
ドロップ編集が、中間的曲げ形状をドラッグし、それを
前記提案された曲げ順内の所望の位置へドロップするこ
とにより、前記ウインドウ表示中に表示された曲げ順を
オペレータが変更することを可能とするように設けられ
てもよい。前記曲げ順は図44を参照して上に記載した
それと同様の対応で、オペレータによりなされた前記ド
ラッグ及びドロップ編集に基づいて修正される。
めに種々の手続き及び操作が使用される。例えば潜在的
な衝突を検出するために、選択された工具の幾何形状と
中間的形状におけるパーツの幾何形状とがアクセスされ
る。各中間工程における前記パーツに関連する幾何形状
データは前記曲げ順及びパーツ寸法及びトポロジーデー
タに基づいて生成される。前記パーツの各フランジは、
前記曲げ順における各中間段階における前記パーツを表
示するために、曲げデータ(例えば曲げ角度、曲げ線位
置、縮小量等)に応じて折り曲げられる。上記折り曲げ
工程及びこの発明の縮小量補償特性は各中間段階での前
記パーツに対する幾何形状データを生成する際に適用さ
れる。この工具及びパーツの幾何形状により、前記曲げ
段階の各々において前記工具の先端をパーツの曲げ線へ
置くことにより、前記工具及びパーツが相互に配向され
る。衝突は、前記幾何学的データ及び前記工具とパーツ
との境界を分析し、前記工具及びパーツにおいて共通な
点或いは重なり合う点が存在するか否かを決定すること
により検出される。衝突は、特定の曲げ工程で検出され
る時、その工程は、ユーザに対して衝突の検出を示すた
めにスクリーン上で強調される。衝突を検出するために
使用される工具データは、ユーザによりなされる工具選
択に基づいて、工具形状ライブラリから積極的に取り出
される。任意の中間曲げ工程での衝突の再計算は異なる
工具形状或いは曲げ順の修正に基づいて行なわれる。そ
のような機能を設け、ここに記載されるごとき、図形的
ユーザインタファースを用いてそのような情報を表示す
ることにより、衝突の可能性は、曲げオペレータによ
り、より容易に決定され且つ修正される。
マウス装置は、板金パーツの表示されるモデルを観察す
る際、ユーザが選択的に種々の観察機能(例えばズー
ム、パン、回転等)を活性化し及び制御することを可能
とするために、前記製造設備を通して前記ステーション
モジュールの各々及びそれらの場所に設けられる。前記
ジョイスティック装置は多重の軸を有するジョイスティ
ックで、選択或いは制御ボタンを有する。前記ジョイス
ティックはマイクロソフト・サイドワインダ・ジョイス
ティックを含む種々の商業的に入手可能なジョイスティ
ック装置を介して実行され、各ステーションモジュール
及び/又は当該設備の他の位置のコンピュータのゲーム
ポートに差し込まれる。前記マウスはまたウンドウズ9
5或いはウインドウズNTのごとき任意の商業的に入手
可能なマウスをサポートするソフトウエア及び、各設備
位置におけるコンピュータのゲームポート或いはマウス
ポートに差し込まれる任意の商業的に入手可能なマウス
装置により実行される。
ョイスティック装置或いはマウス装置を用いて、3次元
幾何学的形状を操作し且つ前記パーツを表示するための
システムの種々の側面を図示する。この発明の3次元ナ
ビゲーションシステムは、ユーザが回転、ズーミング及
びパンニングのごとき種々の観察機能を制御することを
可能とする。この発明の1つの側面によれば、システム
はまた3次元モデルを観察する際に、現在のズーム画像
に基づいて計算される動力学的回転軸を用いる。この側
面によれば、回転の中心は現在の図及びズーム比或いは
係数に基づいて動力学的に変化され且つ計算され、従っ
て前記パーツのズームされた領域は前記パーツが例えば
高いズーム比或いは係数において回転される時、前記ス
クリーンから消えることがない。
作及びナビゲーションシステムが前記設備のステーショ
ンモジュール及び/又はサーバモジュールに提供され
る。3次元ナビゲーションシステムの工程及び操作は、
ソフトウエア或いはプログラムされた論理を介して且つ
広い範囲のプログラム言語及び教示の1つを用いて実行
される。例えば前記システムはC++のごとき高レベル
のプログラム言語を用いて且つオブジェクト指向プログ
ラム技術を用いて実行される。更に限定しない例とし
て、VISUAL C++が使用される。それはウィン
ドウズに基づくアプリケーションのためにマイクロソフ
ト株式会社により提供されるC++プログラム言語の1
つのバージョンである。前記観察機能(例えばズーム、
回転、パン等)は上記した本発明の曲げモデルビューア
の観察クラスの要素機能として実行される(例えば図2
7及び上記関連の開示を見よ)。前記現在ズーム係数及
びパーツの位置(例えば3次元空間におけるパーツの位
置)に関する情報は、また、前記動力学的回転軸を計算
し且つ所望の観察機能を提供するために前記曲げモデル
ビューアからアクセスされる。
スが、本発明の3次元ナビゲーションシステムを実行す
るために提供される。例えばシステムを実行するために
使用されるソフトウエアが前記ステーションモジュール
及びサーバモジュールのコンピュータ或いはパーソナル
コンピュータに設けて有り或いは存在する。上で議論し
たように、前記コンピュータ或いはパーソナルコンピュ
ータは、板金パーツの3次元表示をユーザに対して表示
するために、高解像度モニタのごとき図形カード及び表
示スクリーン或いはターミナルを含む。前記コンピュー
タ或いはパーソナルコンピュータはまた、前記マウス或
いはジョイスティック装置と接続し及びインタフェース
するためのマウス或いはゲームポートアダプタを含む。
商業的に入手可能なソフトウエアも設けられており、ユ
ーザにより操作されるマウス或いはジョイスティック装
置からマウス或いはゲームアダプタカードにより受信さ
れる指令信号を解釈する。
元箱形状パーツを回転するために多重軸ジョイスティッ
ク112により行われる回転機能の例を図示する。上に
述べたように、ジョイスティックは設備を通して設けら
れているステーションモジュール及び/又はサーバモジ
ュールに設けられているコンピュータ或いは装置に設け
られ且つ接続されている。図50a及び50bに示すよ
うに、前記パーツの回転は、前記ジョイスティック11
2を前後に且つ左右に移動することにより行なわれる。
前記回転軸の方向或いは向きは前記ジョイスティック1
12(或いはマウス)の移動に基づいて設定される。例
えば前記ジョイスティック112を前後に移動させるこ
とは、パーツを前記X座標軸に沿って定義される回転軸
の周りに時計方向或いは反時計方向に回転させることを
もたらす(例えば図50aを見よ)。更に前記ジョイス
ティック112を左右に動かすことは、前記パーツを前
記Y座標軸に沿って定義される回転軸を中心として時計
方向或いは反時計方向に回転させることをもたらす(例
えば図50bを見よ)。
ーツの全体表示がスクリーン上に提供される時、前記回
転軸は前記パーツの幾何学的中心或いは図芯を通るよう
に定義される。上記したように、前記ズーム係数及びス
クリーン上のパーツの観察可能性は、本発明の曲げモデ
ルビューアにより提供される観察可能性機能に基づいて
決定される。スクリーン上にパーツ全体が表示されると
判断される時(図50a及び50bにおけるそれのよう
に)、回転軸を定義しそしてその回転軸を前記パーツの
幾何学中心へ設定するために座標幾何技術が用いられ
る。前記パーツの回転は、次に、前記ジョイスティック
装置のユーザにより定義された移動に基づき、且つこの
発明の曲げモデルビューアの回転要素観察機能を介して
実行される。しかし仮に前記オブジェクトの一部のみが
画面に表示され、前記パーツの幾つかの部分は見えない
場合(例えば高いズーム係数或いは比率が選択された
時)、前記回転軸は、前記パーツの幾何学中心或いは図
芯に維持されるべきではない。それはそのようにするこ
とは、回転中に前記パーツのズーム化された部分がスク
リーンから消えるからである。実際この発明によれば、
ズーム比が増大される時、回転軸は動力学的に再計算さ
れ、前記スクリーンのセンターにおける観察点(或いは
カメラ視野)に最も近い点の座標を通る。前記ズーム係
数の変化に基づいて、前記回転軸を動力学的に再計算す
ることにより、前記パーツは、前記パーツの観察可能な
部分が回転の間に画面からはみ出すことにならない軸を
中心として回転される。
ングを行なうために、前記ジョイスティック或いはマウ
ス装置と別個に或いはそれと共に設けられたキーパッド
に追加の制御ボタンが設けられる。例えばズームボタン
114を押すと共に、ジョイスティック112を前後に
移動することにより、図51に示すように、所定の割合
で前記パーツはズームインまたはズームアウトされる。
上記したように、前記回転軸は各ズームウィンドウの中
で再計算され、回転がなされる時、ユーザが前記パーツ
のズーム化された部分を観察することができるようにす
る。更に、3次元形状のパンニングは、図52に示すよ
うに、パンボタン116を押圧し或いは活性化し且つジ
ョイスティック112を移動することにより、ユーザに
より制御される。前記ズームボタン114の場合と同様
に、パンボタン116は前記設備の種々の位置の各々に
おける前記ジョイスティックまたはマウス装置と別個に
或いはそれらと一緒に設けられたディジタル入力パッド
の上に設けてある。
3次元ナビゲーション及び操作を実行するために設けら
れた種々の工程及び操作が図53−55を参照して以下
に記載される。上に示したように、前記3次元ナビゲー
ションシステムの必要な工程及び操作はソフトウエア或
いはプログラムロジック及びハードウエア成分及びイン
タフェースの組み合わせを介して実行される。ジョイス
ティック或いはマウス装置のごときユーザにより制御さ
れる装置からの入力信号は所望の表示されたパーツの運
動及び再配向の量を決めるように解釈される。この発明
によれば、表示されたパーツの回転軸は、回転中にパー
ツのズーム化された領域が画面から消えるのを防止する
ため、現在の画面及びズーム係数に基づいて動力学的に
計算される。
際に、図53のステップS301に一般的に示されるよ
うに、前記ジョイスティック或いはマウス装置の操作に
基づいてユーザからの信号が受信される。ユーザにより
前記ジョイスティック或いはマウス装置の特定の方向の
運動及び/又は特殊な制御ボタンの活性化との組み合わ
せが、所定の観察機能(例えば回転、ズーム、パン等)
及び表示されたパーツの所定の方向(例えば時計回り或
いは反時計回り、ズームイン又はズームアウト、右又は
左等)の運動を、図50−52に例えば示されるよう
に、引き起こす。受信された信号は、それらがジョイス
ティックからであるかマウス装置であるかを問わず、カ
ーソルの移動に写像され、ユーザにより所望されるスク
リーン上の移動量を決定する。ユーザが前記観察機能モ
ードのうちの1つに存在しない場合(例えばユーザがス
クリーン上の情報を選択しているか或いはダイアログボ
ックス或いはウィンドウ内の情報を観察している場
合)、前記受信した信号の写像は要求されない。
ョイスティック或いはマウス装置から受信される信号は
スクリーン空間のそれとは異なる座標或いは参照システ
ムに基づいており、従ってそれらは前記スクリーン上の
カーソル移動に関する意味のある情報を提供するために
翻訳されなければならない。従って前記ユーザからの入
力信号を受け取った後、ステップS303に示されるよ
うに、回転軸の計算及び表示されたパーツの現在の図を
更新する前に受信された信号はカーソル移動に写像され
る。
号をスクリーン空間上のカーソル運動に翻訳及び写像す
るために異なる方法及び工程が使用される。伝統的に
は、マウス装置の移動は、商業的に入手可能なソフトウ
エアによりカーソル移動へ翻訳され且つ写像されてい
た。例えばウィンドウズ95及びウィンドウズNTは、
マウス移動をカーソル移動へ翻訳するためのソフトウエ
アルーチンを含む。従って、マウス装置の移動は、その
ような商業的に入手可能なソフトウエアによりカーソル
移動に写像される。しかしながらユーザにジョイスティ
ックインタフェースが与えられている場合、有用な情報
を提供するには、前記ジョイスティック運動もカーソル
運動へ翻訳され且つ写像されなければならない。前記ジ
ョイスティック仮想空間におけるジョイスティックの運
動をスクリーン空間におけるカーソル運動へ写像するた
めに種々の方法及び技術が使用される。例えば、ジョイ
スティックの移動信号は、最終的にカーソル運動へ写像
される前に、まずマウス運動へ加工され且つ翻訳され
る。或いは、前記ジョイスティック仮想空間のサイズに
対するスクリーン空間のサイズの比率の関数として、前
記ジョイスティック信号は直接カーソル運動へ写像され
る。
く、ジョイスティック運動のスクリーン空間内でのカー
ソル運動への写像の例を図示する。上に示したように、
ジョイスティック装置は自身の仮想的座標システム或い
は空間218を含む。前記ジョイスティック仮想空間2
18は、前記ジョイスティックが中心或いは中立位置
(即ちジョイスティックが移動しない位置)に存在する
位置に対応する原点J1を含む。前記ジョイスティック
が新しい位置(例えば図54に示されるように現在の位
置J2)へ移動する時、前記ジョイスティック装置は前
記ジョイスティックの仮想空間内での新しい或いは現在
の位置を示す信号を生成する。前記ジョイスティック仮
想空間218は、しばしばスクリーン空間212よりも
大きい(画素の意味で)ので、前記ジョイスティックの
仮想座標及び移動は、所望のカーソル移動従ってスクリ
ーン上でのパーツの移動を決定するためにスクリーン座
標へ翻訳されなければならない。
クリーン座標移動へ写像し且つ翻訳するために種々の方
法及び工程が使用される。例えば、前記ジョイスティッ
ク仮想空間サイズに対するスクリーン空間サイズの比率
に基づいて、ジョイスティック運動はスクリーンカーソ
ル運動へ写像される。より詳細には、観察機能モード
(例えばズーム、回転、パン等)が活性化され、ジョイ
スティック装置がユーザにより操作された時、前回の点
C1から現在の点C2へのカーソルの実際の移動は次の
式で決定される。
V) ここに「現在の点」はカーソルの現在の点C2であり、
「前回の点」は前記カーソルの前回の点C1であり、
「スケール係数」はジョイスティック仮想空間サイズに
対するスクリーンサイズの比であり(いずれも画素にお
いて)、「V」はジョイスティック原点J1からジョイ
スティック現在位置J2へのジョイスティックの運動及
び方向を表すベクトルである。従ってジョイスティック
運動をカーソル運動へ写像するために、ジョイスティッ
ク装置がユーザにより操作される時ジョイスティック装
置から受け取られる信号に基づいて、前記原点J1から
現在位置J2へのジョイスティックの方向及び運動を示
すベクトル「V」が最初に計算される。このベクトル
「V」が計算された後、前記ジョイスティック運動は、
前記方程式における前記ベクトル「V」量及び前記「ス
ケール係数」量を用いてカーソル運動へ写像される。即
ち、前記カーソルの新しい或いは現在の位置C2は、前
記ベクトル「V」に前記ジョイスティック空間サイズに
対するスクリーンサイズの比(即ちスケール係数)を掛
け合わせ、次にこの計算の結果を以前のカーソル位置C
1に足し合わせることにより計算される。
或いは運動の割合を所定の或いはユーザにより選択され
た調整係数だけ増大し又は減少することが必要となる。
そのような場合には、そしてユーザの好みにより、前記
スケールの割合を増大し又は減少するために、前記カー
ソルの現在位置を計算する時に、前記スケール係数に調
整係数が掛けられる。例えば、前記ジョイスティック空
間サイズに対するスクリーンサイズの割合がスケール係
数1/64を与える場合、ジョイスティックの運動とス
クリーン上の表示されたパーツの運動の割合との間の一
層満足できる関係を与えるために、スケールの割合を増
大するのが望ましい。限定的でない例として、スケール
係数1/64について、前記表示されたパーツをズーム
し或いは回転する際調整係数3が用いられる。更にスケ
ール係数1/64について、表示されたパーツのパンニ
ングが行なわれる際には調整係数6が使用される。勿
論、スケーリング(縮尺)の割合は、ユーザの特定の必
要に基づいて修正され、前記調整係数は予め決定され或
いはユーザが、前記スケールの割合を修正するための調
整係数を調整或いは選択するためにオプションを与え
る。更に上に議論した事例において示したように、前記
調整係数は複数の観察機能の各々について同じ量に設定
されてもよいし、前記観察機能の各々について、同じ或
いは異なる量に個別に設定されてもよい。
た後、前記パーツの回転軸が、図53のステップS30
5に一般的に示されるように動力学的に計算される。前
記パーツの現在の図に依存して、前記パーツが例えば高
いズーム比率或いはファクターで回転される時、前記パ
ーツのズーム化された領域がスクリーンから消えないよ
うに、前記回転軸は前記パーツの中心を通るか或いは他
の点を通るか決定される。現在のズーム図に基づいて、
前記パーツの回転軸を動力学的に再計算するために種々
の方法及び工程が使用される。この発明の他の側面に応
じて、図55は前記パーツの図がユーザにより修正され
た時常に前記回転軸を計算するために行なわれるプロセ
ス及び工程の代表的論理フロー及び手順を図示する。
数或いは比率及びパーツの位置及び現在の図がステップ
S311及びS313で決定される。ユーザにより選択
された表示パーツのズーム係数及び向きが、パーツ全体
をスクリーン上で観察可能にする(即ち全体図)か、或
いは前記パーツの一部のみをスクリーン上で観察可能に
する(即ち部分図)。従って現在のズーム係数及びパー
ツの向きが、表示パーツの回転軸を適正に設定するため
に定められなければならない。前記パーツの現在の図を
決定するために種々の方法及び工程が使用される。上に
記載したように、観察可能性機能は、本発明の曲げモデ
ルビューアを備え、表示される画像に対する変更が存在
する場合には何時も、現在の図の向き及びズーム比率の
状態を維持しそして更新する。前記曲げモデルビューア
に対する機能コールがなされ、前記パーツのどの点或い
は部分が現在観察可能であるかを決定する。スクリーン
上に前記パーツの全てが表示されているかどうかは画像
体積をパーツの境界基本線サイズと比較することにより
決定される。
スクリーン上で観察可能であると決定される場合には、
ステップS317で前記回転軸は前記パーツの中心を通
るように設定される。全体図が存在する時、前記パーツ
の中心を前記回転軸が通るように設定することは可能で
ある。というのは全体が表示されたパーツはユーザによ
り回転される時スクリーン上で観察可能であるからであ
る。スクリーン上で全てのパーツが観察可能である時、
回転軸はパーツの幾何学中心或いは図芯を取るように定
義される。従来の座標幾何学技術が、前記パーツの幾何
学中心へ前記回転軸を定義し設定するために用いられ
る。更に前記回転軸の方向は、前記前回のカーソル位置
から現在のカーソル位置へのベクトルに直交するベクト
ルとして定義されることもできる。
ツの部分図のみが現在観察可能であると判断される場
合、ズーム化されたパーツがユーザにより回転される時
表示されたパーツの一部がスクリーンから消えないよう
にするために、回転軸を計算するために、前記論理フロ
ーはステップS319−S325へ引き続く。上記した
ように、ユーザにより高いズーム係数が選択され前記パ
ーツの一部のみがスクリーン上に表示される時、前記回
転軸は、前記パーツの幾何学中心を通るように設定され
てはならない。というのは、そのようにすることは、回
転中に表示されたパーツのズーム化された部分(ズーム
アップされた部分)がスクリーンから消えるからであ
る。パーツの表示された部分がスクリーンから見えなく
なり或いは消えることを防止するために、スクリーンの
中心における観察点(即ちカメラ)に最も近い点の座標
を前記回転軸が通るようにされなければならない。その
ような場合、回転軸の向きは前回のカーソル位置から今
回のカーソル位置へのベクトルに直交するベクトルとし
て定義されても良い。
中心が決定され、カメラに最も近いスクリーンの中心に
おけるオブジェクト或いは前記パーツの部分が選択され
る。即ち、スクリーンのセンターに位置する表示パーツ
の部分及びカメラに最も近い或いはスクリーンのユーザ
の観察点に最も近い表示パーツの部分が取り出される。
ステップS321で、前記カメラにおけるオブジェクト
が存在すること(例えば前記スクリーンの中心に位置し
且つ前記カメラに最も近い前記パーツのソリッド部分が
存在すること)が決定される場合、ステップS325で
前記回転軸は前記取り出された点を通るように設定され
る。上記したように、回転軸の方向は前回のカーソル位
置から今回のカーソル位置へのベクトルに直交するベク
トルとして定義されても良い。
ェクトが存在しない(例えば前記パーツは前記スクリー
ンの中心に位置し且つ前記カメラに最も近い穴或いは開
口部を含む)と判断される場合、論理フローはステップ
S323へ引き続く。ステップS323で、前記回転軸
は前記スクリーンの中心(例えば前記スクリーンの物理
的中心のX及びY座標)を通り且つ前記パーツの幾何学
中心に等しいZ座標(深さ)にあるように定義される。
従って回転軸は前記X,Y,Z座標を通るように設定さ
れ、回転軸の向きは前回のカーソル位置から今回のカー
ソル位置へのベクトルに直交するベクトルとして定義さ
れても良い。
転軸が決定された後、選択された観察機能(例えばズー
ム、回転、パン等)がステップS307で呼び出され
る。上記したように3次元操作システムの種々の観察機
能は前記曲げモデルビューア観察クラスの要素機能とし
て定義され実行される(例えば図27及び関連する上記
開示を見よ)。そのような場合、ユーザにより選択され
た観察機能に基づいて、機能コールが前記曲げモデルビ
ューアになされ、ステップS309で表示されたパーツ
の現在の図が更新される。前記パーツの現在の図及び向
きは、ユーザにより選択された観察機能及びユーザによ
り操作された入力装置(マウス或いはジョイスティック
装置)からの受信された写像カーソル運動に基づいて更
新される。オープンGL或いはレンダウェアのごときグ
ラフィックパッケージが、ユーザに提供される現在の図
の更新を容易にするために提供される。図53及び55
の代表的フローチャートにおいて行なわれる論理フロー
及びプロセスはソフトウエアにより及び広い種類のプロ
グラム言語及び技術を用いて実行される。例えばオブジ
ェクト指向プログラム技術及びC++が前記プロセス或
いは操作を実行するために使用される。この発明の3次
元操作システムを実行するための代表的コードが付録L
に提供される。代表的コードはC++プログラム言語で
書かれ、前記動力学的回転軸を計算するための種々の工
程及び操作を含む。付録Lのコードにはコメントが提供
され、そこに使用される論理及びアルゴリズムの解析を
容易にする。
ク装置及び制御ボタンの使用に関して記載されている
が、このシステムは、マウス或いはキーボードを含む他
の特定のタイプの入力手段により実行されることもでき
る。更に図51−52の上記実施例では、前記オブジェ
クトのスクリーンから無限への又はその反対のズーミン
グ或いはパンニングを制限するために境界が定義され
る。というのは連続的なズーミング或いはパンニングは
システムを故障させ或いは破壊させるからである。
スに関連して種々の他の機能が実行される。例えば、前
記観察機能のいずれかにおける移動は、ジョイスティッ
クがジョイスティックセンター位置から所定の範囲或い
は距離を越えて移動されなければ実行されない。パーツ
の移動が許される前にそのようなジョイスティックの移
動のしきい値を要求することは、前記中心点からの前記
ジョイスティックの不注意な操作或いは押圧に基づい
て、表示されたパーツの偶然の移動の発生を防止する。
ユーザとのジョイスティックインタフェース及びシステ
ム相互作用を改善するために他の機能がまた設けられ
る。例えばユーザによるジョイスティックの単一の操作
に基づいて、前記観察機能(例えばズーム、回転、パン
等)のいずれか1つにおける連続的或いは増加的(例え
ばステップごと)の移動が提供される。前記連続的或い
は増加的移動の選択はまた単一の方向におけるジョイス
ティックの移動の量或いは時間に基づいて提供される。
必要ならば表示されるパーツのスケール或いは移動の割
合は、任意の方向におけるジョイスティックの運動の程
度或いは時間に基づいて増加される。上記した速度調整
係数の修正はまた、ユーザが前記スケールの比率を増加
し或いは減少するために、マニュアルで調整係数に対す
る補正を入力することを可能とすることにより実行され
る。
支援を行なうために、本発明において種々の他の機能及
び実施例が実行される。例えば各顧客のオーダに関する
情報を追跡し且つアクセスするためにバーコードシステ
ムが実行される。所定の参照番号或いは作業番号を有す
るバーコードが顧客により注文される各部品へ割り当て
られる。このバーコードはデータベース30にアクセス
し作業情報を読み取るために用いられる。ユタ、サンデ
ィにおけるゼブラテクノロジVTIからのバーコード・
エニシング・バーコードSCAN CCDセンサのごと
きバーコードリーダ或いはスキャナが各場所に設けら
れ、ユーザが前記サーバモジュール或いはステーション
モジュールにおいて所定の作業のためのバーコードをス
キャンすることを可能にし、またデータベース30に格
納されているそのパーツに付随する重要な設計及び製造
情報をアクセスし読み出すことを可能にする。前記バー
コードリーダは各ステーションモジュール及び/或いは
サーバモジュールのコンピュータに差し込まれている。
前記バーコードは任意の通常のバーコードフォーマット
に基づいてフォーマット化されている。例えばUPS−
A CODA BARCODE39 EAN/JAN−
8或いはPLESSEYである。そして結果としてのバ
ーコードナンバーはルックアップテーブルに基づいて翻
訳され、前記データベースから作業情報を読み出すため
に、対応する作業参照番号及び/又はファイル名を検出
する。或いは、前記作業番号は、工場全体にわたって存
在する任意のステーションにおいて表示される指示へタ
イプ入力され或いはそこから選択され、瞬時にユーザの
位置で作業情報を読み出し表示する。そのような情報を
瞬時に読み出す能力は、コミュニケーションネットワー
ク26の使用及びデータベース30のごとき中央に位置
するデータベースへの前記デザイン及び情報の格納によ
り支援される。
スケジュールし割り当てるための装置及び方法が提案さ
れるシステムに設けられる。従来、製造設備にわたる作
業のスケジュール化及び割り当てはショップ或いは工場
の工場長により行なわれた。工場長は、機械装置の現在
のセットアップ及び利用可能性のみならず現在の仕事の
状態を決定する。これらの情報を集め且つ分析した後、
ショップ或いは工場の工場長はスケジュールを生成し且
つ工場における種々の場所においてなされる作業につい
て割り当てを分配する(例えば工場フロアに分配される
作業スケジュールシートの形態で)。作業のスケジュー
ル割り当ては、各顧客の作業がタイミングの良い形態で
且つ所定の出荷日までに完了することを確実にするため
に行なわれる。作業のスケジュール化及び割り当ての従
来の工程はしかし骨の折れるものであり、通常工場長に
よりマニュアルで行なわれていた。
或いは工場の工場長がその工場についての作業のスケジ
ュールを立てることを支援するために、作業割り当て及
びスケジュールシステムが設けられている。そのシステ
ムはコミュニケーションネットワーク及びデータベース
30に格納されている曲げモデル情報を利用し、自動的
に必要な情報を集め、従って工場長はより容易に作業ス
ケジュールを生成することができる。このシステムは、
前記サーバモジュール或いは工場にわたって配置されて
いるステーションモジュールにおいてソフトウエア又は
プログラムロジックを介して実行される。スケジュール
されるべき種々の作業を入力することにより、システム
ソフトウエアはデザイン及びパーツ情報を分析し所定の
作業を行なうためにどの機械が最も適しているかを決定
する。この目的のため、工場における機械の現在の状態
及びセットアップが定義され、データベース30に格納
され、作業スケジュールソフトウエアによりアクセスさ
れる。種々の条件に基づいて、表示の形態で、特定の作
業を実行するためにどの機械が利用可能であるか及びど
の機械が他の仕事を実行することができないかを示唆す
る。この点について、特定の作業について機械の利用可
能性をランク付けし且つ提案作業スケジュールを提供す
るテーブルが表示される。前記提案作業スケジュールは
工場長により実行され或いは修正される。作業スケジュ
ールを設定し且つ推薦するために使用される条件は広い
種類の条件を含む。そしてそれは、工場における各マシ
ンの現在のセットアップ、各作業について必要とされる
曲げのタイプ及び工具、及び同じ時間枠或いは時間の間
に実行されなければならない他のタイプの作業を含む。
どの機械が特定の作業を実行できるかを決定するため
に、前記曲げ角度、フランジ長さ及び曲げのタイプを含
む各パーツについての曲げモデルファイルからの情報が
利用される。例えばデータベース30に格納されている
テーブルは前記工場フロアにおけるパンチング及び曲げ
機械の各々の現在のセットアップ及び能力についての重
要な情報を含む。
工場長は、工場の生産及び出力能力を最大限にするため
に、複数の作業を工場全体にわたる種々の場所へ割り当
てる。最後の作業スケジュール或いは割り当ては電子的
に入力されコミュニケーションネットワーク26を介し
て機械の各々へ送られる。
び機械装置ワークステーションの各々に設けられ、その
ステーションに作業が割り当てられ転送されたことを指
示し且つ確認する。前記作業割り当て及びスケジュール
は、工場内の任意の位置から瞬時にアクセス可能なサー
バモジュールのファイルに格納される。上記機能に加え
て、その他の機能が、この発明の教示に応じて実行され
る。例えば種々のステーションモジュール或いは位置に
メニュースクリーンが設けられ且つ表示され、ユーザが
この発明の種々の表示及び機能モードを選択するのを容
易にする。例えば図56に示されるそれのごときメイン
のメニュースクリーンが、前記ステーションモジュール
が開始される際にユーザに対して提供される。このメイ
ンメニューウインドウ表示はステーションモジュールに
より提供される利用可能なウインドウ表示及び観察モー
ドの各々のアイコン画像を含む。このメインメニュース
クリーンはメニューボタン(例えばF1キー)が選択さ
れるとき何時でも現れる。ユーザは、強調されたブロッ
クを所望のウインドウアイコンへ移動しそれを選択する
ことによりそのウインドウを選択する。そのような操作
は、キーボード、マウス或いはジョイスティックの使用
を介して行なわれる。
て提供され且つ表示され作業情報の入力及び表示を容易
にする。例えばパーツ情報ウインドウは、ユーザがパー
ツ情報を入力し或いは修正するのを可能にするために表
示される。パーツ情報ウインドウ表示の例が図57に与
えられる。このパーツ情報ウインドウは全ての関連する
パーツ情報(例えばパーツ番号、材料タイプ、寸法等)
を含み、板金パーツの2次元平面図及び等測投影法図を
含む。曲げ線情報ウインドウ(例えば図58に示される
もの)は、ユーザが各曲げ線についての曲げ順及び縮小
量を含む種々の曲げ線情報を監視することを可能とする
ために設けられる。前記曲げ線情報ウインドウはユーザ
が、各曲げについての曲げ線情報を入力し或いは修正す
るのを可能とし、板金パーツの2次元平面図及び等測投
影図を含む。
めに、追加のウインドウ表示が提供される。例えば曲げ
順ウインドウ表示及び曲げシミュレーションウインドウ
表示が提供され、前記パーツの種々の曲げ段階を表示
し、且つ曲げ操作中におけるパーツの向きをシミュレー
トする。図59に示されるような曲げ順ウインドウは前
記メインメニュースクリーンから選択され曲げ順の各段
階における前記パーツの(静止状態における)中間形状
をユーザに対して表示する。曲げシミュレーションウイ
ンドウ(例えば図60を見よ)もユーザにより選択さ
れ、曲げ段階の静止情報(スクリーンの右側に提供され
るパーツアイコンの形態で)及び、曲げ順における各段
階で行なわれる位置付け及び曲げの動的シミュレーショ
ン(表示装置の中央において)を提供する。スクリーン
上のパーツアイコンを間欠的に選択することにより、ユ
ーザは選択されたパーツアイコンにより表現される段階
における、曲げ加工中でのパーツの向きの動的シミュレ
ーションを見ることができる。各曲げ順を動的にシミュ
レートするために、パーツは反転され、並進移動され、
曲げ線の周りで曲げられ/回転される。
は、図56のメインメニューウインドウ表示からユーザ
に対して選択され且つ表示される。更に、任意のステー
ションモジュールにおけるユーザは、メインメニューウ
インドウ表示において適宜のウインドウアイコンを選択
し、この発明の観察モード(例えば2次元平面、ワイヤ
フレーム、ソリッド、正射図)に応じて表示されるパー
ツの2次元及び/又は3次元表示を得る。これは図28
−31を参照して上で詳細に説明された。種々のメニュ
ーウインドウがまた例えばステーションモジュールに設
けられ、この発明の特性及び機能の操作を容易にする。
図61は2次元から3次元操作のために表示される代表
的メニューを図示する。更に図62はこの発明の2次元
クリーンアップ操作のための代表的メニュー構造を図示
する。この発明はしかしこれらのメニュー配置に限定さ
れるものではなく、他のメニュースクリーン及び/又は
工具アイコンバーが設けられ、ユーザのシステムとの相
互作用を容易にする。
る。例えば、高いレベルの自動装置も提供され曲げプラ
ンの生成を容易にする。例えば曲げ及び工具立てエキス
パートシステムが提供され、各作業についてのパーツの
幾何形状及び形状に基づいて工具立てセットアップ及び
曲げ順を生成し且つ提案する。それは例えば米国特許出
願出願番号08/386.369及び08/338.1
15に開示されるようなものである。
して記載されたがここで用いられた用語は、限定の用語
ではなく、記載及び説明の用語である。この発明の範囲
及び精神及び種々の側面から逸脱することなく種々の変
形がなされ得る。この発明はここで特定の手段、材料及
び実施例を参照して記載されたが、発明はここに開示さ
れた特定のものに限定されるように意図されるものでは
ない。むしろ発明は全ての機能的に等価な構造、方法及
び使用に広がる。
例 .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_reco
rd->get_number_of_adjacent_holes() ;bendlinelist
[i].numadjbend = (int) topology_record->get_number
_of_adjacent_bendlines() ;}if (num_error > 0) {cle
an_up ( part_numface, imatrix, nbl_face, facelist,
bendlinelist, bendfacelist) ;return ( num_error )
;}// varify all the valid bendlines, the current
requirements are://1) The total number of bendline
s should not be less than// the totalnumber of
faces minus 1.// 2) A bendline without an adjacen
t face or bendline is not allowed.// 3) A bendline
with more than two adjacent faces and bendlines i
s not allowed.//4)The adjacent face or bendline of
a bendline must bea valid face or// bendline t
hat is defined in the facelist or bendlinelist.//
5) Two adjacent faces, face1 and face2, will be de
fined for each bendline// a) If the bendline ha
s an adjacent faces,then the face’s faceid is use
d// as face1 or face2.//b) If the bendline h
as an adjacent bendline, thena bendline_only_face/
/ will be created inbetween these two bendli
nes. The faceid of the // bendline_only_face will
be used as face1 or face2.//c)If the bendline has
only one adjacent face or adjacent bendline, then
//a bendline_only_face will becreated for this ben
dline. The faceid of// the bendline_only_fa
ce is face2.// maxnewfaces is the maximum number o
f bendline_only_face need to be created// without
encounter error in the part.if (part_numbend> part
_numface-1) num_error++ ; // condition 1if (num_er
ror > 0) {clean_up ( part_numface, imatrix, nbl_fa
ce, facelist, bendlinelist, bendfacelist) ;retur
n ( num_error ) ;}int maxnewfaces = part_numbend +
1 - part_numface ;if (maxnewfaces > 0) {bendfacel
ist = new ARTIFICIAL_FACE [maxnewfaces] ;bendfacel
ist[0].faceid = -part_numface ;}for ( i = 0 ; i <
num_of_bendlines ; i++) {if (bendlinelist[i].bendl
ineid) {bend_0 = bendlinelist[i].bendlineid ;intnu
madj = bendlinelist[i].numadjface + bendlinelist
[i].numadjbend ;if (numadj < 1 || numadj > 2) num_
error++ ; // condition2 & 3else {if (bendlinelist
[i].numadjface > 0) { // condition 4 - firstfaceth
ree_d_body = bendlinelist[i].topologyrecpt->get_fi
rst_face() ;face_1 = find_face_id( three_d_body, f
acelist, num_of_faces ) ;if (face_1 <= 0) num_erro
r++ ;else bendlinelist[i].face1 = face_1 ; }if (be
ndlinelist[i].numadjface ==
2) { // condition 4 − sec
ond facethree_d_body = be
ndlinelist[i].topologyrec
pt−>get_next_face() ;face
_1 = find_face_id( three_
d_body, facelist, num_of_
faces ) ;if (face_1 <= 0)
num_error++ ;else bendli
nelist[i].face2 = face_1
; }if (bendlinelist[i].n
umadjbend > 0) { // condition 4
- first bendlinethree_d_body = bendlinelist[i].top
ologyrecpt->get_first_bendline() ;bend_1 = find_be
ndline_id( three_d_body, bendlinelist, num_of_bend
lines ) ;if (bend_1 <= 0) num_error++ ;else {face_
1= define_bendline_only_face ( bend_1, bend_0,bend
facelist, maxnewfaces );if (face_1 <= 0) num_error
++ ;else {if (bendlinelist[i].numadjface > 0) ben
dlinelist[i].face2 = face_1 ;else bendlinelist[i].
face1 = face_1 ;}}}if (bendlinelist[i].numadjbend
== 2) { // condition 4 - second bendlinethree_d_
body = bendlinelist[i].topologyrecpt->get_next_ben
dline() ;bend_1 = find_bendline_id( three_d_body,
bendlinelist, num_of_bendlines );if (bend_1 <= 0)
num_error++ ;else {face_1 = define_bendline_only_f
ace( bend_1, bend_0, bendfacelist, maxnewfaces ) ;
if (face_1 <= 0) num_error++ ;else bendlinelist
[i].face2 = face_1 ;}}if (numadj == 1) {face_1 =de
fine_bendline_only_face ( bend_0, 0,bendfacelist,
maxnewfaces ) ;if (face_1 <= 0) num_error++ ;else
bendlinelist[i].face2 = face_1 ;}}}}if (num_error
> 0) {clean_up ( part_numface, imatrix, nbl_face,
facelist, bendlinelist, bendfacelist) ;return
( num_error ) ;}// now check whether there is any
bendline only face been created// increase the par
t_numfaceif there is.int numregfaces = part_numfac
e ;int numnewfaces = 0 ;if (maxnewfaces > 0) { for
( i = 0 ; i < maxnewfaces ; i++ ) {if (bendfaceli
st[i].faceid <= 0) {numnewfaces = i + 1 ;break ;}}
part_numface += numnewfaces ;}//first create integ
er topological matrix to record all the topologica
l relationsint j ;imatrix = new int *[part_numfac
e] ;for ( i = 0 ; i< part_numface ; i++ ) {imatrix
[i] = new int [part_numface] ;for( j = 0; j < part
_numface; j++ ) imatrix[i][j] = 0;}for ( i = 0 ; i
< num_of_bendlines ; i++ ) {// save the bendline
entry + 1 in imatrixif (bendlinelist[i].bendlinei
d) {face_1 = bendlinelist[i].face1 ;face_2 = bendl
inelist[i].face2 ;imatrix[face_1-1][face_2-1] = i+
1 ;imatrix[face_2-1][face_1-1] = i+1 ;}}// from im
atrix to find the number of bendlines of each fac
e,nbl_face[i],// and to verify that each face has
at least one bendlinenbl_face = new int [part_numf
ace] ;for ( i = 0 ; i < part_numface ; i++ ){nbl_f
ace[i] = 0 ;for ( j = 0 ; j < part_numface ; j++ )
{if ( imatrix[i][j] ) nbl_face[i]++;}if (!nbl_fac
e[i]) num_error++ ;}if (num_error > 0){clean_up (
part_numface, imatrix, nbl_face, facelist, bendl
inelist,bendfacelist) ;return ( num_error ) ;}// c
reate the Cbpart’s topological matrix’s input da
ta FENT array// and initialize it.part->get_name(
pname ) ;parrank = part_numface ;int spsize = parr
ank*(parrank + 1)/2 + 1; // +1 is for End of FENT
array indicator FENT *sp = new FENT [ spsize] ;fo
r(i = 0; i < spsize-1 ; i++ )*(sp+i) = NoRelation
;*(sp+spsize-1)= NullFent ;// step 1: set up the
positive or negative bend// The included F
ENT’s are://*PosBend = ’+’; // positive be
nd betweentwo faces//*NegBend = ’-’; // neg
ative bend between two faces//*P90Bend= ’A’; /
/ 90 deg positive bend angle//*N90Bend = ’B’;
// 90 deg negative bend angle//MrPosBend = ’
3’; // multiple positive bendlines between two f
aces//MrNegBend = ’4’; // multiple negative b
endlines between two faces//* marks what is curren
tly implemented.for ( i = 0 ; i < num_of_bendlines
; i++ ) {if (bendlinelist[i].bendlineid) {face_1
= bendlinelist[i].face1 ;face_2 = bendlinelist[i].
face2 ;FENT btype = NegBend ;BM_BEND_OP_REGULAR *b
endopregular = (BM_BEND_OP_REGULAR *)bendlinelist
[i].bendoppt;if (bendopregular->get_bend_type()) b
type = PosBend ;double angle = bendopregular->get_
bend_angle() ;if (angle> PI) {// angle > PI => rev
erse bend direction and reset the bend angleangle
= 2*PI - angle ;if (btype == PosBend)btype = NegBe
nd ;elsebtype = PosBend ;}bendlinelist[i].bendangl
e = angle ;bendlinelist[i].bendtype =btype ;// se
t up 90 degree bend typeif (angle == PI_over_2) {i
f (btype == PosBend)btype = P90Bend ;elsebtype = N
90Bend ;}//set_FENT (sp, face_1,face_2, parrank, b
type) ;}}// step 2: set up the corner relationship
s,which is the relation//between two faces that ar
e connected to a commonface.// The included FENT
are://*TouchCnr = ’T’; // two faces same b
end dir//*OpenCnr = ’O’; // two faces sam
e bend dir//*PrllBend = ’P’; // two parall
el bendline same bend angle dir opposite bendline
dir//*SerlBend = ’S’; // two parallel bend
line same bend angle dir same bendline dir//*cLnrB
end = ’L’; // colinear bendline same bend
angle dir on one face//*DfClnrBend = ’D’; //
colinear bendline same bend angle on different fac
es//*tHkOffBend = ’H’;// tHickness offset ben
dline same bend angle dir on two neighboring face/
/*touchCnr = ’t’; // two faces opposite be
nd dir//*openCnr= ’o’; // two faces opposite
bend dir//*prllBend = ’p’;//two parallel b
endline opposite bend angle dir opposite bendline
dir//*serlBend = ’s’; // two parallel bend
line opposite bend angle dirsame bendline dir//*cl
nrBend = ’l’; //colinear bendline opposite
bend angle dir on one face//thkOffBend = ’
h’; // tHickness offset bendline opposite bend a
ngle dir on two neighboring face//* marks whatis c
urrently implemented.// 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_numface ; 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_numface ; k++) {if ( imatrix[i][k] )
{int bl_2 = imatrix[i][k] ;face_2 = k + 1 ;// defi
ne the relation ship between the two bendlinesset_
bendline_rel_FENT (sp, parrank,facelist, face_c, f
ace_1, face_2,bendlinelist, bl_1, bl_2,outfile)
;}}}}}}//*tHkOffBend = ’H’; // tHickness of
fset bendlinesame bend angle dir on two neighborin
g face// from imatrix to find the faces that may b
e of the thickness offset bendlines//and verify th
ese faces first based on touch cornerinfomation th
en based on// the bendlines’distance and parallel
condition.for ( i = 0 ; i < part_numface ; i++ )
{if ( nbl_face[i] < 2 ) continue ;// face i should
have at least 2 bendlinesfor ( j = i+1 ; j < part
_numface ; j++ ) {if ( !imatrix[i][j] || nbl_face
[j] < 2 ) continue ;// faces i and j must have a c
ommon bendline//and face 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 ( get_FENT(sp, j+1, i2+1, parrank)
!= TouchCnr ) continue;for ( int j2 = 0 ; j2 < pa
rt_numface ; j2++ ) {if ( !imatrix[j][j2] ||j2 ==
i ) continue ;// second requirement - bendlines im
atrix[i][j] and// imatrix[j][j2] also form a touch
cornerif ( get_FENT(sp, i+1, j2+1, parrank) != To
uchCnr ) continue ;// comes here, we have obtained
a candidate for the // thickness offset bendline
s, the two candidate // bendlines are imatrix[i,i
2] and imatrix[j][j2] int bl_1 = imatrix[i][i2] ;
intbl_2 = imatrix[j][j2] ;check_thkoffbend ( sp, p
arrank,facelist, i+1, i2+1, j+1,j2+1,bendlinelist,
bl_1, bl_2, thickness, outfile);}}}}//DfClnrBend
= ’D’; //colinear bendline same bend angle o
n different faces// Here is to find all the coline
ar bends that are colinear but not related to each
other// with a common face.int num_undetermined =
0 ;UNDETERMINED *undetermined = new UNDETERMINED
[num_of_bendlines] ;UNDETERMINED *undetpt = undete
rmined ;for ( i = 0 ; i < num_of_bendlines ; i++ )
{if (bendlinelist[i].bendlineid) {int face_i1 = b
endlinelist[i].face1 ;int face_i2 = bendlinelist
[i].face2 ;for ( j = i+1 ; j < num_of_bendlines ;
j++ ) {if (bendlinelist[j].bendlineid) {int face_j
1 = bendlinelist[j].face1 ;int face_j2 = bendlinel
ist[j].face2 ;if ( face_i1 == face_j1 || face_i1 =
= face_j2 ||face_i2 == face_j1 || face_i2 == face_
j2 ) continue ;if( bendlinelist[j].bendtype != be
ndlinelist[j].bendtype ) continue ;if( bendlineli
st[j].bendangle != bendlinelist[j].bendangle ) con
tinue ;//come here when the two bend lines have th
e same bend angle and type,// and they do not shar
e a common face.// now examine whether they are co
linearint bl_i = i + 1 ;int bl_j = j + 1 ;int unkn
own = check_DfClnrBend (sp, parrank, facelist,face
_i1, face_i2, face_j1, face_j2,bendlinelist, bl_i,
bl_j,part_numface, imatrix, outfile) ;if (unknow
n) {undetermined[num_undetermined].bendline_i = bl
_i ;undetermined[num_undetermined].bendline_j = bl
_j ;num_undetermined++ ;}}}}}// Note: if num_undet
ermined is not zero, then there are confirmed DfCl
nrBend//but with undetermined facesfor specify thi
s FENT.//A tree structure of all the faces that re
cordsthe connectivity between//faces need to be co
nstructed. And then each pair of undetermined//be
ndlines need to be processed to determine which tw
o faces of the four//that connected with the two b
endlines should be used torecord this FENT.// Curr
ently, we will neglect these information and simpl
y delete// undetermined array, which will not be u
sed any more. delete [] undetermined ;// transfer
all the data back *inp_part_numface =part_numface
;*inp_parrank = parrank ;*inp_part_numbend = part
_numbend;*inp_part_maxface = part_maxface ;*inp_sp
= sp ;num_error = fclose (outfile) ;clean_up ( pa
rt_numface, imatrix, nbl_face, facelist, bendlin
elist, bendfacelist) ;return ( num_error ) ; } 付録B 相似性指数特性の例。2つの部分のトポロジカルマトリ
クスを比較し、それらの最良の相似性指数を求める。相
似性指数は、2つの部分のFENTマトリクストポロジ
カルマトリクス)の不一致FENTsの全てのペナルテ
イの和として与えられる。最良の相似性指数は最小値を
持つものである。
*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, ¤t
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_level,
minimumvalue,returnlevelcounts) ;if (errorcode !
= 0) return (errorcode) ;*recursive_level -= 1 ;*c
urrentvalue -= increase ;// change the FENT counte
rs of the oldmatrix for unfixing faceoldchange_cou
nts_for_unfix_one_face ( poldmatrix, poldmatchl
ist, pcold, matrixdim, nfacefixed+1) ;}}// change
the FENT counters of the newmatrix for unfixing fa
cenewchange_counts_for_unfix_one_face( pnewmatrix,
pnewmatchlist, pcnew, matrixdim, nfacefixed+1)
;//cleanupdelete [] pcandidates ;delete [] pincre
ases ;return (0);}////////////////////////////////
////////////////////////////////// 1以上の面を固
定するためのカウンターを更新する。////////////////
//////////////////////////////////////////////////
//int change_counts_for_fix_one_face ( int*pnew
matrix, int *pnewmatchlist, int facenew, FENTC
OUNT *pcnew, int matrixdim, int nfacefixed)
{// input//pnewmatrix- the new part’stopological
matrix, where// the FENT co
ntents have been changed to//
their representing integers.//
(integer array of matrixdim * matrixdim)//
pnewmatchlist- the list of entries of the newmatri
x that // has been matchedby the oldmatrix.//
(integer array of matrixdim)//
facenew- the face that is to be fixed.//pcnew- the
FENTCOUNT of all the faces.//matrixdim- the matri
x dimension of both matrices//nfacematched- the nu
mber of entries (faces) that has// been fixed in
matching the two matrices.// output//pnewmatchlist
- the updated list of entries of the// newmatrix
matched by the oldmatrix,// with the facenew entr
y is moved to the // nfacefixed+1 location. //pcn
ew- the updated FENTCOUNT of all the faces// switc
h the to be fixed face to the location of nfacefix
ed+1// in the pnewmatchlistint ifound = 0 ;for ( i
nt i = nfacefixed ; i <matrixdim ; i++ ) {if (*(pn
ewmatchlist+i) == facenew) {*(pnewmatchlist+i) = *
(pnewmatchlist+nfacefixed) ;*(pnewmatchlist+nfacef
ixed) = facenew ;ifound++ ;}}if ( ifound != 1 ) {c
out << "Fatal error from change_counts_for_fix_one
_face /n" ;return ( 91 ) ;}// define the pointer t
o the FENTon the to be fixed faceint *pnewrow = pn
ewmatrix + (facenew-1)*matrixdim;// first change t
he counters for the previously fixed facesfor ( i
= 0; i < nfacefixed ; i++ ) {int newcol = *(pnewma
tchlist+i) ;int pnewv =*(pnewrow + newcol - 1) ;p
cnew[newcol].count[pnewv]-- ;int igroup = fent_gro
up (pnewv) ;pcnew[newcol].gcount[igroup]-- ;if ( p
cnew[newcol].count[pnewv] < 0 || pcnew[newco
l].gcount[igroup] < 0 ) {cout << "Fatal error from
change_counts_for_fix_one_face /n" ;return ( 92 )
;}}// secondchange the counters for the unfixed f
aces// use count_specified_fents to initialize the
FENTCOUNT of// the newly seleted face and count t
he numbers of fents of // the undetermined columns
on the to be fixed rowsintlistdim = matrixdim - n
facefixed ;pcnew[facenew] = count_specified_fents
( pnewrow, pnewmatchlist+nfacefixed, matrixdim, li
stdim ) ; // decreasethe FENTCOUNT of the newly se
leted face from that// in remaining unfixed facesf
or ( 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 calculation of the similarity indexfor (int ic
ol = iface; icol < matrixdim; icol++) {int newcol
= *(pnewmatchlist+icol) ;int oldcol = *(poldmatchl
ist+icol) ;int pnewv = *(pnewrow + newcol - 1) ;in
t poldv = *(poldrow + oldcol - 1) ;if ( pnewv != p
oldv ) indexvalue += penalty_of_fent_pair(pnewv,po
ldv) ;}}return (indexvalue) ;}////////////////////
//////////////////////////////////////////////////
// この関数は特定の固定した面までの所与の組の面に
対する相似の指数を計算する。//////////////////////
//////////////////////////////////////////////////
int calculate_partial_similarity_index ( int *p
newmatrix, int *pnewmatchlist,FENTCOUNT *pcnew,
int *poldmatrix, int *poldmatchlist, FE
NTCOUNT*pcold, int matrixdim, int nfacefixe
d){// loop thru the faces andcalculate the similar
ity indexint indexvalue = 0 ;for (int iface = 0 ;
iface < nfacefixed; iface++) {int facenew = *(pnew
matchlist+iface) ;int faceold = *(poldmatchlist+if
ace) ;int *pnewrow = pnewmatrix + (facenew -1)*mat
rixdim ;int *poldrow = poldmatrix + (faceold - 1)*
matrixdim ;// first from the mismatches of the fix
ed faces.// Note: the diagonal terms of the matrix
are always iNoRelation.// therefore, they a
re skip inthe loop.// also due to the symmet
ry, only half of the matrix are// included i
n the calculation of the similarity indexfor (int
icol = iface ; icol < nfacefixed; icol++) {int new
col = *(pnewmatchlist+icol) ;int oldcol = *(poldma
tchlist+icol) ;int pnewv = *(pnewrow + newcol -1)
;int poldv = *(poldrow + oldcol - 1) ;if ( pnewv
!= poldv ) indexvalue += penalty_of_fent_pair(pnew
v,poldv) ;}// use count_specified_fents to initial
ize the FENTCOUNT of// the facenew and faceold and
to count thenumbers of fents of // the columns of
the unfixed facesint 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
);// Now loop thru the FENTCOUNT of the facenew a
nd faceold// and calculate the penalty of their mi
smatches.indexvalue += penalty_of_FENTCOUNT_pair
( pcnew[facenew], pcold[faceold] ) ;}// use count
_specified_fents_matrix to get the FENTCOUNT// of
the unfixed faces of both matrices int listdim = m
atrixdim - nfacefixed ;pcnew[0] = count_specified_
fents_matrix( pnewmatrix, pnewmatchlist+nfacefixe
d, matrixdim, listdim ) ;pcold[0]= count_specified
_fents_matrix ( poldmatrix, poldmatchlist+nfacefix
ed, matrixdim, listdim ) ;// Finally calculate the
penalty of the FENTCOUNT//of the unfixed faces of
the two matrices.indexvalue += penalty_of_FENTCOU
NT_pair ( pcnew[0], pcold[0] ) ;// Return the amo
unt of penalty on the two partially fixed// part m
atrices as its minimum possible similarityindex.re
turn (indexvalue);}///////////////////////////////
////////////////////////////////////////// この関
数は所与のfacenewとfaceoldのミスマッ
チに対する相似の指//// 数の増加を計算する。/////
//////////////////////////////////////////////////
//////////////////int increase_on_similarity_index
( int *pnewmatrix, int *pnewmatchlist, intf
acenew, int *poldmatrix, int *poldmatchlis
t, int faceold, FENTCOUNT *pcnew, FENTCOUNT *pc
old, int *currentvalue, int matrixdim,int nface
fixed, int *minimumvalue){// loop thru the fac
es to seehow much increase is in the// current val
ue.int increase = 0 ;int *pnewrow = pnewmatrix +
(facenew-1)*matrixdim ;int *poldrow = poldmatrix +
(faceold-1)*matrixdim ;// first loop thru the pre
viously fixed faces and calculate// the increase f
or the mismatches between the chosen columnsfor( i
nt i = 0; i < nfacefixed; i++ ) {int newcol = *(pn
ewmatchlist+i) ;int oldcol = *(poldmatchlist+i) ;i
nt pnewv = *(pnewrow + newcol - 1) ;intpoldv = *(p
oldrow + oldcol - 1) ;if ( pnewv != poldv ) {FENTC
OUNT pcnewcol = pcnew[newcol] ;FENTCOUNT pcoldcol
= pcold[oldcol] ;increase += increase_from_separat
e_a_pair_of_fent (pcnewcol, pcoldcol, pnewv, poldv
) ;}}// use count_specified_fents to initialize t
he FENTCOUNT of// the newlyseleted face and count
the numbers of fents of // the undetermined column
s on the to be fixed rowsint listdim = matrixdim -
nfacefixed ;pcnew[facenew] = count_specified_fent
s ( pnewrow, pnewmatchlist+nfacefixed, matrixdim,
listdim ) ;pcold[faceold] = count_specified_fents
( poldrow, poldmatchlist+nfacefixed, matrixdim, li
stdim ) ;increase += increase_from_separate_a_pair
_of_fentcount (pcnew[0], pcold[0], pcnew[facenew],
pcold[faceold] ) ;// Return the amount of increas
e in the similarity index for// the matching of th
e chosen two faces, facenew in new part// and the
faceold in the old part.return (increase);} 付録C // コメントを含むベンドライン検出の例。このモジュ
ールはBM PART:: 自動ベンド( )の実施を含む。
********** ********* これは、部分の設計と構成に供
する主要な高レベルベンドモデル関数である。その目的
は、(もし可能なら)部分が接続されるようになるよう
に面間にベンドラインを形成することにある。 この関
数は部分の形成を容易にすることにある。通常は、第三
パーテイの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:objはコンタクト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 v
ariables will be used to do a quick check if these
two// facescan possible touch each otherdouble di
stance_plane_to_bloop1, distance_plane_to_bloop2,d
istance_plane_to_bloop3, distance_plane_to_bloop4
;intdistance_plane_to_bloop_count ;if (! bloop2->
is_bbox_up_to_date()) bloop2->recompute_bbox() ;if
(! BM_distance_between_point_and_plane(bloop2->ge
t_bbox_p1(), (BM_PLANE&) (*surface1), &distance_pl
ane_to_bloop1, NULL))return 0 ;if (! BM_distance_b
etween_point_and_plane(bloop2->get_bbox_p2(), (BM_
PLANE&) (*surface1), &distance_plane_to_bloop2, NU
LL)) return 0;if (! BM_distance_between_point_and_
plane(bloop2->get_bbox_p3(), (BM_PLANE&) (*surface
1), &distance_plane_to_bloop3, NULL)) return 0 ;if
(! BM_distance_between_point_and_plane(bloop2->ge
t_bbox_p4(), (BM_PLANE&) (*surface1), &distance_pl
ane_to_bloop4, NULL)) return 0 ;distance_plane_to_
bloop_count = 0 ;if (fabs(distance_plane_to_bloop
1) >= local_tolerance) distance_plane_to_bloop_cou
nt++ ;if (fabs(distance_plane_to_bloop2) >= local_
tolerance) distance_plane_to_bloop_count++ ;if (fa
bs(distance_plane_to_bloop3) >= local_tolerance) d
istance_plane_to_bloop_count++ ;if (fabs(distance_
plane_to_bloop4) >= local_tolerance) distance_plan
e_to_bloop_count++ ;if (distance_plane_to_bloop_co
unt > 2) {// at most one of the bloop corners is o
n the plane.// that means, bbox itself is not in c
ontactwith face1.// however, it could be that diff
erent corners of bbox are on different sides of th
e plane.// here we will return if all bloop2 point
s are on one side of plane1// ie. these two faces
cannot be in contact// // note : at most one of th
e 4 distance_plane_to_bloop-i can be zero.// // in
the next line we pick "distance_plane_to_bloop1"
for checking not because it is special,// but beca
use any of the 4 would do.if (fabs(distance_plane_
to_bloop1) >= local_tolerance) {if (distance_plane
_to_bloop1*distance_plane_to_bloop2 >= 0.0 &&dista
nce_plane_to_bloop1*distance_plane_to_bloop3 >= 0.
0 &&distance_plane_to_bloop1*distance_plane_to_blo
op4>= 0.0) return 1 ;}else {if (distance_plane_to_
bloop2*distance_plane_to_bloop3 >= 0.0 &&distance_
plane_to_bloop2*distance_plane_to_bloop4 >= 0.0) r
eturn 1 ;}}// if the count is 0, 1 or 2, it means
that 2, 3 or 4 bbox corners are on the plane.// th
at means, it is possible that there is acontact./*
ここで、我々は、面2に関してbボックス1に対して
同じものをチェックする。*/if (! bloop1->is_bbox_up
_to_date()) bloop1->recompute_bbox() ;if (! BM_dis
tance_between_point_and_plane(bloop1->get_bbox_p
1(), (BM_PLANE&) (*surface2), &distance_plane_to_b
loop1, NULL)) return 0 ;if (! BM_distance_between_
point_and_plane(bloop1->get_bbox_p2(), (BM_PLANE&)
(*surface2), &distance_plane_to_bloop2, NULL)) ret
urn 0 ;if (! BM_distance_between_point_and_plane(b
loop1->get_bbox_p3(), (BM_PLANE&) (*surface2), &di
stance_plane_to_bloop3, NULL)) return 0 ;if (! BM_
distance_between_point_and_plane(bloop1->get_bbox_
p4(), (BM_PLANE&) (*surface2), &distance_plane_to_
bloop4, NULL)) return 0 ;distance_plane_to_bloop_c
ount = 0;if (fabs(distance_plane_to_bloop1) >= loc
al_tolerance) distance_plane_to_bloop_count++ ;if
(fabs(distance_plane_to_bloop2) >= local_toleranc
e)distance_plane_to_bloop_count++ ;if (fabs(distan
ce_plane_to_bloop3) >= local_tolerance) distance_p
lane_to_bloop_count++ ;if (fabs(distance_plane_to_
bloop4) >= local_tolerance) distance_plane_to_bloo
p_count++ ;if (distance_plane_to_bloop_count > 2)
{// at most one of the bloop corners ison the plan
e.// here we will return if all bloop1 points are
on one sideof plane2// ie. these two faces cannot
be in contactif (fabs(distance_plane_to_bloop1) >=
local_tolerance) {if (distance_plane_to_bloop1*di
stance_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)re
turn 1 ;}else {if (distance_plane_to_bloop2*distan
ce_plane_to_bloop3>= 0.0 &&distance_plane_to_bloop
2*distance_plane_to_bloop4 >= 0.0) return 1 ;}}/**
********* ********** ********** ********** *******
*** ********** ********** ********** **********
両面のラインの全数をカウントする。メモリを割当てる
必要がある。 注意:ラインのみがベンドラインを作る
ことが出来るのでラインであるエッジを単にカウントす
る。 注意:ユーザが特定のベンドエッジを持つか否か
をチェックする。ユーザは、どのエッジが可能なベンド
エッジとして考えられるかを、それらのエッジの名称を
設定することにより限定することが出来る。**********
********** ********** ********** ****************
**** ********** ********** ***********/long face1_
has_user_defined_bend_edges = 0 ; // the number of
user-speicifed bend edges in face1long face2_has_
user_defined_bend_edges = 0 ; // the number of use
r-speicifed bend edges in face2long face1_line_cou
nt = 0, face2_line_count = 0 ;long line_count ; //
sum of lines in faces 1 and 2 participating in th
e sweep.BM_LOOP *holes ;BM_EDGE *edges ;for (edges
= bloop1->get_first_edge() ; edges ; edges = (BM_
EDGE *) edges->next()) {if (! edges->is(BM_ENTITY_
TYPE_LINE)) continue ;if (edges->get_name() == fac
e2.get_idx()) face1_has_user_defined_bend_edges++
;face1_line_count++ ;}for (holes = body1->get_fir
st_hole() ; holes ; holes = (BM_LOOP *) holes->nex
t()) {for (edges = holes->get_first_edge() ; edges
; edges = (BM_EDGE *) edges->next()) {if (! edges
->is(BM_ENTITY_TYPE_LINE)) continue ;if (edges->ge
t_name()== face2.get_idx()) face1_has_user_defined
_bend_edges++ ;face1_line_count++ ;}}for (edges =
bloop2->get_first_edge() ; edges ; edges = (BM_EDG
E*) edges->next()) {if (! edges->is(BM_ENTITY_TYPE
_LINE)) continue ;if (edges->get_name() == face1.g
et_idx()) face2_has_user_defined_bend_edges++ ;fac
e2_line_count++ ;}for (holes = body2->get_first_ho
le() ; holes ; holes = (BM_LOOP *) holes->next())
{for (edges = holes->get_first_edge(); edges ; edg
es = (BM_EDGE *) edges->next()) {if (! edges->is(B
M_ENTITY_TYPE_LINE)) continue ;if (edges->get_name
() == face1.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_defined_bend_edges ;if (face2_has_user_define
d_bend_edges) face2_line_count = face2_has_user_de
fined_bend_edges ;if (face1_line_count < 1 || face
2_line_count < 1) return 1 ;line_count =face1_line
_count + face2_line_count ;/*********** **********
******************** ********** ********** ******
**** ********** **********メモリを割り当てる。****
****** ********** ********** ********** **********
********** ********** ********** ***********/if
(NULL == (line_pointers = new BM_LINE*[line_coun
t])) return 0 ;if (NULL == (line_start_coordinates
= new double[line_count])) {delete [] line_pointer
s ;}/*********** ********** ********** **********
********** ********** ********** *****************
***先ず、ラインポインタ配列を充填する。必要なら、
ユーザが特定したエッジだけを取る。********** *****
***** ********** ********** ******************** *
********* ********** ***********/i = 0 ;for (edges
= bloop1->get_first_edge() ; edges ; edges = (BM_
EDGE *) edges->next()) {if (! edges->is(BM_ENTITY_
TYPE_LINE)) continue ;if (face1_has_user_defined_b
end_edges && edges->get_name() != face2.get_idx())
continue ;line_pointers[i++] = (BM_LINE *) edges
;}for (holes = body1->get_first_hole() ; holes; h
oles = (BM_LOOP *) holes->next()) {for (edges = ho
les->get_first_edge() ; edges ; edges = (BM_EDGE
*) edges->next()) {if (! edges->is(BM_ENTITY_TYPE_
LINE)) continue ;if (face1_has_user_defined_bend_e
dges && edges->get_name() != face2.get_idx()) cont
inue ;line_pointers[i++] = (BM_LINE*) edges ;}}for
(edges = bloop2->get_first_edge() ; edges ; edges
= (BM_EDGE *) edges->next()) {if (! edges->is(BM_
ENTITY_TYPE_LINE)) continue ;if (face2_has_user_de
fined_bend_edges && edges->get_name() != face1.get
_idx()) continue ;line_pointers[i++] = (BM_LINE *)
edges ;}for (holes = body2->get_first_hole() ; ho
les ; holes = (BM_LOOP *) holes->next()) {for(edge
s = holes->get_first_edge() ; edges ; edges = (BM_
EDGE *) edges->next()) {if (! edges->is(BM_ENTITY_
TYPE_LINE)) continue ;if (face2_has_user_defined_b
end_edges && edges->get_name() != face1.get_idx())
continue;line_pointers[i++] = (BM_LINE *) edges
;}}/*********** ********** ********** **********
********** ********** ********** ********** ******
****X座標により、つぎにZ座標により、さらにYによ
りラインの配列を分類する。********** ********** **
******** ********** ********** ********** ********
** ********** ***********/{ // this is a block of
code for sorting the array// first, construct the
array of points and lines associated with themfor
(i = 0 ; i < line_count ; i++) {p = BM_get_greater
_point_by_XZY((line_pointers[i])->get_startpt(),(l
ine_pointers[i])->get_endpt()) ;line_start_coordin
ates[i] = p.X() ;}// sort by XDBM_QuickSort_double
(line_start_coordinates, line_count, (long *) line
_pointers) ;// sort by Zdouble first_in_set_Z = li
ne_start_coordinates[0] ;long set_Z_size = 1, firs
t_in_set_Z_idx = 0 ;p = BM_get_greater_point_by_XZ
Y((line_pointers[0])->get_startpt(),(line_pointers
[0])->get_endpt()) ;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])->ge
t_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_Quic
kSort_double(line_start_coordinates + first_in_set
_Z_idx, set_Z_size, (long*) line_pointers + first_
in_set_Z_idx) ;// sort by Ylong set_Z_end = first_
in_set_Z_idx + 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_POINT pY(BM_get_greater_point_by_XZY((li
ne_pointers[first_in_set_Z_idx])->get_startpt(),(l
ine_pointers[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_e
nd ; j++) {if (j < set_Z_end){pY = BM_g
et_greater_point_by_XZY
((line_pointers[j])−>get_
startpt(),(line_pointers
[j])−>get_endpt()) ;if (l
ine_start_coordinates[j]
== first_in_set_Y) {set_Y
_size++ ;line_start_coord
inates[j] = pY.Y() ;conti
nue ;}}//else, we have pa
ssed the end of the Z−seq
uenceif (set_Y_size > 1)
DBM_QuickSort_double(line
_start_coordinates + firs
t_in_set_Y_idx, set_Y_siz
e,(long *) line_pointers
+ first_in_set_Y_idx) ;if
(j < set_Z_end) {set_Y_s
ize = 1 ;first_in_set_Y_i
dx = j ;first_in_set_Y =
line_start_coordinates[j]
;line_start_coordinates
[j] = pY.Y() ;}}if (i < l
ine_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 cont
actsBM_LINKED_LIST_NODE *face1_list, *face2_list ;
BM_LINKED_LIST_NODE *last_face1_list, *last_face2_
list;BM_LINKED_LIST_NODE *left, *right ;BM_LINKED_
LIST_NODE *new_left = NULL, *new_right = NULL ;BM_
LINE *line_in_left, *line_in_right ;// these are t
he two lines we will be comparingBM_2D_BODY *face_
of_line1, *face_of_line2 ;BM_LINE *line_in_face1,
*line_in_face2 ;BM_LINE *line ;double k,dotp ;BM_P
OINT 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 fac
e of the current line.// however, later we will so
rt thecurrent-sweep-line and current-open-line poi
nters.face_of_line1 = ((line_pointers[i])->get_loo
p())->get_2D_body() ;p = BM_get_greater_point_by_X
ZY((line_pointers[i])->get_startpt(),(line_pointer
s[i])->get_endpt()) ;// compare this current line
against all open lines in order to detect overlap
s, ie. bendlines.for (open_line_idx = i + 1 ; open
_line_idx < line_count ; open_line_idx++) {line =
line_pointers[open_line_idx] ;if (NULL== line) {//
time-saving trick. if this is the last pointer, t
here is no need to try it again.// reduce the inde
x.if (open_line_idx == line_count - 1) {--line_cou
nt ;break ;}continue ;}// ********** ********** **
******** ********** **********// check if this ope
n line should really be removed.// it should be re
moved if its endpoint is larger than p (ie. the//
startpoint of this line).// ********** **********
********** ********** **********p_open = BM_get_sm
aller_point_by_XZY(line->get_startpt(),line->get_e
ndpt()) ;if (BM_compare_points_by_XZY(p_open,p))
{// time-saving trick.// if the line we are removi
ng from the open list is the last one, reduce the
index// instead of setting the pointer to NULL. ne
xt timewe don’t even try this element// in the ar
ray, because it would be beyond the boundaryif (op
en_line_idx == line_count - 1) {--line_count ;brea
k;}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_lin
e1 == face_of_line2) continue ;// ********** *****
***** ********** ********** **********// Check if
this line and the open line overlap.// **********
********** ********** ********** **********// Firs
t check if the startpoint is on the (open) line se
gment.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 s
tartpoint is "before"p// and endpoint is "after"
p.// Now check if vectors are parallel.v =(line->g
et_v()) * ((line_pointers[i])->get_v()) ;if (v.Len
() > BM_PRECISION) continue ;// Last thing, it cou
ld be that only endpoints of the lines overlap.dot
p = (line->get_v()) % ((line_pointers[i])->get_
v()) ;if (dotp < 0.0) { // lines are opposite// st
artpoint-startpoint/endpoint-endpoint should not m
atchif ((line->get_startpt()) == ((line_pointers
[i])->get_startpt()) || (line->get_endpt()) == ((l
ine_pointers[i])->get_endpt())) continue ;}else {
// lines have the same direction// startpoint-endp
oint/endpoint-startpoint should not matchif ((line
->get_endpt()) == ((line_pointers[i])->get_startpt
()) || (line->get_startpt()) == ((line_pointers
[i])->get_endpt())) continue ;}// ********** *****
***** ********** ********** **********// Ok, these
two lines overlap.// First, sort lines according
to which face they are in// ********** **********
********** ********** **********if (&face1 == (BM_
FACE *) face_of_line1->get_3D_body()) {line_in_fac
e1 = line_pointers[i] ;line_in_face2 = line ;p_fac
e1 = p ;p_face2 = 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_get_greater_point_by_XZY(line->get_sta
rtpt(),line->get_endpt()) ;p_face2 = p ;}// ******
**** ********** ********** ********** **********//
Scan all known contacts and check if this contact
should be// addedto an existing contact// *******
*** ********** ********** ********** **********for
(j = 0, last_face2_list = NULL ; j < num_of_conta
cts ; j++){if (NULL == last_face2_list) {last_face
1_list = contacts ;last_face2_list = last_face1_li
st->next() ;}else {last_face1_list = last_face2_li
st->next() ;last_face2_list = last_face1_list->nex
t() ;}left = (BM_LINKED_LIST_NODE *) last_face1_li
st->get_obj() ;right = (BM_LINKED_LIST_NODE *) las
t_face2_list->get_obj() ;line_in_left = (BM_LINE
*) left->get_obj() ;line_in_right = (BM_LINE *) ri
ght->get_obj() ;// Check if the line of this exist
ing contact overlaps the new contact.// condition
is : point on the line and vectors are parallel.if
(! line_in_left->is_point_on_line(p_face1,&k)) co
ntinue ;v = (line_in_left->get_v()) * (line_in_fac
e1->get_v()) ;if (v.Len() > BM_PRECISION) continue
;// Check that lines in face1and face2 and exact
extensions of left and right in this contact// thi
sis because we want every contact in the list of c
ontacts to be a "closed" contact// note it could b
e that one of the new lines in already in this con
tact.// then we don’t need to check.if (line_in_l
eft != line_in_face1) {dotp = (line_in_left->get_v
()) % (line_in_face1->get_v()) ;if (dotp < 0.0) {
// lines are opposite// startpoints must matchif
((line_in_left->get_startpt()) != (line_in_face1->
get_startpt()) &&(line_in_left->get_endpt()) != (l
ine_in_face1->get_endpt())) continue ;}else { // l
ines have the same direction// endpoints must matc
hif ((line_in_left->get_endpt()) != (line_in_face1
->get_startpt()) &&(line_in_left->get_startpt()) !
= (line_in_face1->get_endpt())) continue ;}}if (li
ne_in_right != line_in_face2) {dotp = (line_in_rig
ht->get_v()) % (line_in_face2->get_v()) ;if(dotp <
0.0) { // lines are opposite// startpoints must m
atchif ((line_in_right->get_startpt()) != (line_in
_face2->get_startpt()) &&(line_in_right->get_endpt
()) != (line_in_face2->get_endpt())) continue ;}el
se { // lines have the same direction// endpoints
must matchif ((line_in_right->get_endpt()) != (lin
e_in_face2->get_startpt()) &&(line_in_right->get_s
tartpt()) != (line_in_face2->get_endpt())) continu
e ;}}// everything is fine. add lines to this cont
act.// note that is could be that the line is alre
ady in the contact.if (line_in_left != line_in_fac
e1) {if (NULL == (new_left = new BM_LINKED_LIST_NO
DE(line_in_face1,NULL,left))) goto failure ;last_f
ace1_list->set_obj((BM_BASIC *) new_left) ;new_lef
t = NULL ;}if(line_in_right != line_in_face2) {if
(NULL == (new_right = new BM_LINKED_LIST_NODE(line
_in_face2,NULL,right))) goto failure ;last_face2_l
ist->set_obj((BM_BASIC *) new_right) ;new_right =
NULL ;}// now we have to break out of here. we add
ed this contact to an existing contact.break ;}//c
heck if we checked all contacts and could not find
a matchif (j < num_of_contacts) continue ;// ****
****** ********** ********** ********** **********
// Create a new contact.// ********** ********** *
********* ********** **********// First, create no
des for both lines.if (NULL == (left= new BM_LINKE
D_LIST_NODE(line_in_face1))) goto failure ;if (NUL
L == (right = new BM_LINKED_LIST_NODE(line_in_face
2))) {delete left ;goto failure ;}// Create lists
for both sides of the contact.if (NULL == (face2_l
ist = new BM_LINKED_LIST_NODE((BM_BASIC *) righ
t))) {delete left ;delete right ;goto failure ;}if
(NULL == (face1_list = new BM_LINKED_LIST_NODE((B
M_BASIC *) left,NULL,face2_list))) {delete left ;d
elete right ;delete face2_list ;goto failure ;}//
add the new contact to the list of contactsif (num
_of_contacts < 1) contacts = face1_list ;else last
_face2_list->add_after(face1_list) ;++num_of_conta
cts ;}// we use i to index line_pointers[] array./
/ since i will be decremented shortly, line_pointe
rs[i] will be "implictly" put on // the open list
of sweep lines.}/*********** ********** **********
**********必要ならメモリを自由にする。**********
********** ********** ***********/if (line_start_c
oordinates) delete [] line_start_coordinates ;if
(line_pointers) delete [] line_pointers ;// finall
y, create a node for the number of contactsif (NUL
L == (left = new BM_LINKED_LIST_NODE((BM_BASIC *)
num_of_contacts,NULL,contacts))) goto failure ;*li
st_of_contacts = left ;return 1 ;failure :// free
memory if necessaryif (line_start_coordinates) del
ete [] line_start_coordinates ;if (line_pointers)
delete [] line_pointers ;BM_LINKED_LIST_NODE *lis
t, *next_list ;BM_LINKED_LIST_NODE *line_in_list,
*next_line_in_list ;for (list =contacts ; list ; l
ist = next_list) {next_list = list->next() ;for (l
ine_in_list = (BM_LINKED_LIST_NODE *) list->get_ob
j() ; line_in_list ; line_in_list = next_line_in_l
ist) {next_line_in_list = line_in_list->next();del
ete line_in_list ;}delete list ;}if (new_left) del
ete new_left ;if(new_right) delete new_right ;retu
rn 0 ;}/* この関数は2つの面の間のコンタクトのリ
ストを掃引する (BMにより殆ど同様に生成される
全ての面から面の接点を計算する)そして全ての、ただ
し最大の接点を除去する。 基本的には、それは接点の
リストを”濾過”し、最も長い接触部に属さない接触部
を除去する。一般に、最も長い接触部は同時的なベンド
ラインのリストである点に注目されたい。かくして、接
触部リストの基本構造は同じである。 例えば、リスト
中の第一のノードは最も長いコンタクト中のコンタクト
の数である。 この関数はまた最も長いコンタクトの長
さに戻す。 この関数においては、全てのコンタクトが
閉じられ、従ってコンタクト中のラインのリストにおい
て、ラインの端点は次のラインの出発点に等しくなると
いう事実を利用している。 この方法で唯一のトリッキ
ーな部分は、第一の、および最後のラインにおける重な
り部分の長さを計算することにある。次に、リストの中
間でラインの長さを付加する。前の関数を参照された
い。*/static double BM_keep_largest_contact_remove
_the_rest(BM_LINKED_LIST_NODE **list_of_contacts)
{long i, j ;if (NULL == list_of_contacts) return
0.0 ;BM_LINKED_LIST_NODE *contacts = *list_of_cont
acts ;if (NULL == contacts) return 0.0 ;// some of
the most importantparameters we compute in this f
unction.double length_of_largest_contact= 0.0 ;lon
g largest_contact_i = -1 ;// we need to keep track
of the lengths of contacts.// we need to store th
e length of every contact.// // NOTICE : here we t
ry to save some heap allocation/release time by us
ing apre-allocated// array if the list of contacts
is not very long.// staticdouble static_contact_l
en_array[32] ;double *dynamic_contact_len_array= N
ULL ;double *contact_len_array = NULL ;// get the
number of contactslong num_of_contacts = (long) co
ntacts->get_obj() ;contacts = contacts->next() ;//
if no contacts, delete the entire listif (num_of_
contacts < 1){// there is no list. delete node 0 a
s well.delete *list_of_contacts ;*list_of_contacts
= NULL ;return 0.0 ;}// allocate memory for the c
ontactlength arrayif (num_of_contacts <= 32) {cont
act_len_array = static_contact_len_array ;}else {i
f (NULL == (dynamic_contact_len_array = new double
[num_of_contacts])) goto computation_done__clean_u
p ;contact_len_array= dynamic_contact_len_array ;}
// Scan all known contacts and compute thelength o
f every contact.// later we use these values to fi
nd the longest contact (which could be a simultane
ous bendline).BM_LINKED_LIST_NODE *last_face1_lis
t, *last_face2_list ;BM_LINKED_LIST_NODE *line_in_
list ;double k ;double first_k1, first_k2 ;double
last_k1, last_k2 ;last_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_l
ist = last_face1_list->next() ;BM_LINKED_LIST_NODE
*left = (BM_LINKED_LIST_NODE *) last_face1_list->
get_obj() ;BM_LINKED_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 ov
erlapping part. we compute overlapping parameters
k1 and k2 with respect tothe// first line on the l
eft, between the first lines. // the idea is that
one of the points that corresponds to these parame
ters (k1 and k2)//is the extreme point of the cont
act. we just don’t know yet which one.// then we
find the last points in both lists. we know that t
hey must have non-empty// overlapping part as wel
l. we compute k1 and k2 for these two lines as wel
l.// then we compate k1,k2 for the first and last
pairs to find the two// extreme points of the cont
act. distance between them isthe length of the con
tact.// compute k1 and k2 for the first lines.firs
t_line_in_left->is_point_on_line(first_line_in_rig
ht->get_startpt(),&first_k1) ;first_line_in_left->
is_point_on_line(first_line_in_right->get_endpt(),
&first_k2) ;// we only want k1 and k2 within the f
irst lineif (first_k1 < 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) firs
t_k2 = 1.0 ;// sort k1 and k2if (first_k1 > first_
k2) { k = first_k1 ; first_k1 =first_k2 ; first_k2
= k ; }// find the last line in the left.for (lin
e_in_list = left->next() ; line_in_list ; line_in_
list = line_in_list->next()) {left = line_in_list
;}// "left" is the last node in the left now.BM_L
INE *last_line_in_left = (BM_LINE *) left->get_obj
() ;// find the last line in the right.for (line_i
n_list = right->next() ; line_in_list ; line_in_li
st = line_in_list->next()) {right = line_in_list
;}// "right" is the last node in the left now.BM_
LINE *last_line_in_right = (BM_LINE *) right->get_
obj() ;// compute k1 and k2 for the first lines.la
st_line_in_left->is_point_on_line(last_line_in_rig
ht->get_startpt(),&last_k1) ;last_line_in_left->is
_point_on_line(last_line_in_right->get_endpt(),&la
st_k2) ;// we only want k1 and k2 within the last
lineif (last_k1 < 0.0) last_k1 = 0.0 ;else if (las
t_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 have compute last k1 and k2 with r
espect to the last line in the left.// wereally ne
ed last k1 and k2 with respect to the first line i
n the left.BM_POINT lastk1(last_line_in_left->get_
startpt() + last_k1*(last_line_in_left->get_v()))
;BM_POINT lastk2(last_line_in_left->get_startpt()
+ last_k2*(last_line_in_left->get_v())) ;first_li
ne_in_left->is_point_on_line(lastk1,&last_k1) ;fir
st_line_in_left->is_point_on_line(lastk2,&last_k
2);// sort k1 and k2if (last_k1 > last_k2) { k = l
ast_k1 ; last_k1 = last_k2 ; last_k2 = k ; }// now
we need to take the extreme points of these two p
airsif (first_k1 > last_k1) first_k1 = last_k1 ;if
(first_k2 < last_k2) first_k2 = last_k2 ;contact_
len_array[i] = (first_k2 - first_k1)*(first_line_i
n_left->get_len()) ;}// find the longest contact./
/ the main feature here is to check for simultaneo
us bendlineslast_face2_list = NULL;for (i = 0 ; i
< num_of_contacts ; i++) {if (NULL == last_face2_l
ist)last_face1_list = contacts ;else last_face1_li
st = last_face2_list->next() ;last_face2_list = la
st_face1_list->next() ;// make sure we don’t acce
pt contacts that have zero length.if (contact_len_
array[i] < BM_PRECISION) continue ;
BM_LINKED_LIST_NODE *left
= (BM_LINKED_LIST_NODE
*) last_face1_list−>get_o
bj() ;BM_LINE *first_line
_in_left = (BM_LINE *) le
ft−>get_obj() ;// check i
f this contact is part of
a simultaneous bendline.
//if yes, add its length
to the first bendline in
the simultaneous bendline
and// set this length he
re to −1.0, so that we kn
ow it laterBM_LINKED_LIST
_NODE *temp_last_face1_li
st, *temp_last_face2_list
= NULL ;for (j =0 ; j <
i ; j++) {if (contact_len
_array[i] < BM_PRECISION)
continue ; // already pa
rt of something elseif (N
ULL == temp_last_face2_li
st) temp_last_face1_list
= contacts ;else temp_las
t_face1_list = temp_last_
face2_list−>next() ;temp_
last_face2_list = temp_la
st_face1_list−>next() ;BM
_LINKED_LIST_NODE *temp_l
eft = (BM_LINKED_LIST_NOD
E *) temp_last_face1_list
−>get_obj() ;BM_LINE *tem
p_first_line_in_left = (B
M_LINE *) temp_left−>get_
obj() ;// check if the li
nes overlapif (! first_li
ne_in_left−>is_point_on_l
ine(temp_first_line_in_le
ft−>get_startpt(),NULL))
continue ;if (! first_lin
e_in_left−>is_point_on_li
ne(temp_first_line_in_lef
t−>get_endpt(),NULL)) con
tinue ;// ok, they overla
p// add the length to the
first in simultaneous be
nd and set this to −1.0co
ntact_len_array[j] += con
tact_len_array[i] ;contac
t_len_array[i] = −1.0 ;br
eak ;}}// in this loop we
actually find the larges
tfor (i = 0 ; i < num_of_
contacts ; i++) {// check
to see if this new conta
ct is the largestif (leng
th_of_largest_contact <co
ntact_len_array[i]) {leng
th_of_largest_contact = c
ontact_len_array[i];large
st_contact_i = i ;}}compu
tation_done__clean_up ://
remove all other contact
s that are not largestBM_
LINKED_LIST_NODE *next_la
st_face1_list, *next_last
_face2_list = NULL ;BM_LI
NKED_LIST_NODE *largest_c
ontact_list_f1 = NULL, *l
argest_contact_list_f2 ;l
ast_face1_list = contacts
;last_face2_list = last_
face1_list−>next() ;for
(i = j = 0 ; i < num_of_c
ontacts ; i++) {next_last
_face1_list = last_face2_
list−>next() ;if (next_la
st_face1_list) next_last_
face2_list = next_last_fa
ce1_list−>next() ;else ne
xt_last_face2_list = NULL
;// make sure we don’t dele
te the largest contact// note : we skip two lists,
face1 list and face2 listif (contact_len_array[i]
< 0.0 || largest_contact_i == i) {if (NULL == lar
gest_contact_list_f1) largest_contact_list_f1 = la
st_face1_list ;else largest_contact_list_f2->add_a
fter(last_face1_list) ;largest_contact_list_f2 = l
ast_face2_list ;// count the number of contacts++j
;last_face1_list = next_last_face1_list ;last_fac
e2_list = next_last_face2_list ;continue ;}// ok,t
his is not the largest contact, delete both face1
and face2 sides of the contactBM_LINKED_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_list) {next_li
ne_in_list = line_in_list->next() ;delete 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_line_in_list =
line_in_list->next() ;delete line_in_list ;}delete
last_face1_list ;delete last_face2_list ;last_fac
e1_list = next_last_face1_list ;last_face2_list =
next_last_face2_list ;}// end the contact listwith
a NULL pointerif (largest_contact_list_f2) larges
t_contact_list_f2->add_after(NULL) ;// write the n
umber of contacts left in node 0. also,set the cor
rect beginning of the list.// however, if there is
no contact, erase the entire list.if (NULL == lar
gest_contact_list_f1) {// thereis no list. delete
node 0 as well.delete *list_of_contacts ;*list_of_
contacts = NULL ;}else {(*list_of_contacts)->set_o
bj((BM_BASIC *) j) ;(*list_of_contacts)->add_after
(largest_contact_list_f1) ;}// delete dynamic_cont
act_len_array if it was allocatedif (dynamic_conta
ct_len_array) delete [] dynamic_contact_len_array
;return length_of_largest_contact ;}/*この関数
は、サブルーチンとして静的なint BM crea
te ベンドライン(...)によってのみ用いられ
る。 現在の大きな問題は、我々が幾つかのラインを削
除しているということである。 この問題は、我々が同
時ベンドを持つとき、他のコンタクトはなお我々が丁度
削除したこれらのラインを参照していることが出来ると
いうことである。 我々は進んでそれをチェックしなけ
ればならず、もし真なら、有効な参照によりポインタを
我々が変更し/削除したラインに置き換えなければなら
ない。 すなわち、影響されたラインは左側の最初のそ
して最後のラインである。 潜在的には、それらに対す
る参照は11および13を参照して置き換えられる必要
がある。*/static void check_references_in_remainin
g_contacts(BM_LINKED_LIST_NODE *side_1, // current
list we are working withBM_LINKED_LIST_NODE *side
_2, // list on the other side of thecontactBM_LINE
*line1, BM_LINE *line3, // these are old referenc
es, tobe checked if still validBM_LINE *l1, BM_LIN
E *l3 // l1 and l3 are the new references){BM_LINK
ED_LIST_NODE *side1 = side_1, *side2 = side_2 ;pro
cess_next_contact :// find the beginnings of lists
in the next contactBM_LINKED_LIST_NODE *contact_l
ist ;if (NULL == (contact_list = side1->next())) r
eturn ; // done, no more listsif (NULL == (side1 =
contact_list->next())) return ; // done, no more
listsif (NULL == (contact_list = side2->next())) r
eturn ; // done, no more listsif (NULL == (side2 =
contact_list->next())) return ; // done, no more
lists// now we need to check thebeginning of this
contact and the end of this contact exactly the sa
meway.// we describe checking the beginning, check
the end is the same.//whenever we find a match, w
e can go to the next list (ie. don’t have toconti
nue with the// current list).// // we take first l
ines is side1 and side2. if the first line in side
1 is either line1 or line3,// we checkwhich of l1
and l3 overlaps the first line in side2. we know t
hat exactly one of// l1 and l3 has to overlap. the
n we replace the reference to line1/line3 with a r
eference to the// one of l1/l3 that overlaps the f
irst line in side2.BM_LINKED_LIST_NODE *start_side
1 = (BM_LINKED_LIST_NODE*) side1->get_obj() ;BM_LI
NKED_LIST_NODE *start_side2 = (BM_LINKED_LIST_NODE
*) side2->get_obj() ;// check the beginning of th
e contactBM_LINE *line_in_side1 = (BM_LINE *) star
t_side1->get_obj() ;BM_LINE *line_in_side2 = (BM_L
INE *) start_side2->get_obj() ;if (line_in_side1 =
= line1 || line_in_side1 == line3) {if (l1) { // c
heck if l1 overlaps first line inside2if (line_in_
side2->is_point_on_line_segment(l1->get_startpt(),
NULL) ||line_in_side2->is_point_on_line_segment(l
1->get_endpt(), NULL)) {start_side1->set_obj(l1) ;
goto process_next_contact ;}}if (l3) { // check if
l3 overlaps first line in side2if (line_in_side2-
>is_point_on_line_segment(l3->get_startpt(), NULL)
||line_in_side2->is_point_on_line_segment(l3->get
_endpt(), NULL)) start_side1->set_obj(l3) ;}goto p
rocess_next_contact ;}BM_LINKED_LIST_NODE *line_in
_list, *prev_line_in_list ;// find the last line i
n side2.for (line_in_list = start_side2->next() ;
line_in_list ; line_in_list = line_in_list->nex
t()) {prev_line_in_list = line_in_list ;}// "prev_
line_in_list" is the last node in the left now.lin
e_in_side2 = (BM_LINE *) prev_line_in_list->get_ob
j() ;// find the last line in side1.for (line_in_l
ist = start_side1->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 side1 now.line_in_side1 = (BM_LINE*) prev
_line_in_list->get_obj() ;// check the end of the
contactif (line_in_side1 == line1 || line_in_side1
== line3) {if (l1) { // check if l1overlaps first
line in side2if (line_in_side2->is_point_on_line_
segment(l1->get_startpt(), NULL) ||line_in_side2->
is_point_on_line_segment(l1->get_endpt(), NULL))
{prev_line_in_list->set_obj(l1) ;goto process_next
_contact ;}}if (l3) { // check if l3 overlaps firs
t line in side2if (line_in_side2->is_point_on_line
_segment(l3->get_startpt(), NULL) ||line_in_side2-
>is_point_on_line_segment(l3->get_endpt(), NULL))
prev_line_in_list->set_obj(l3) ;}}goto process_nex
t_contact ;}/* この関数は、入力として与えられたコ
ンタクトリストに基づいて、2つの面間に簡単な(規則
的な)ベンドラインを形成する。一端これがなされる
と、それはコンタクトリストを消去する。 この関数で
は、面のエッジは左手の規則に従って分類されると仮定
する。この関数は、もし全てがファインのときは、TR
UEに戻す。 NB!ここでの問題点は、新しいベンド
ラインを形成したとき、何かを部分的に無効にすること
ではない。 それを完成するために、我々は、分離であ
るベンドopを形成し(ベンドライン無しに)(原文理
解出来ず)、後にそれをベンドラインに付加する。 更
に、我々は、ベンドラインが形成され、部分に付加され
た後にのみトポロジーを形成する。 この関数は、面1
(主として、垂直な面1)に一致するベンドライン情報
を形成する点に注目されたい。 ただし、垂直な面2は
この情報と不一致でもよいが、後に固定されなければな
らない。*/static int BM_create_bendline(BM_PART &
part, BM_LINKED_LIST_NODE **contact, BM_BENDLINE *
*bendline_created /* OUT */){// so far, nothing is
created*bendline_created= NULL ;// it is possibl
e, that we are building bendlines for the flat ver
sion of the part.// if this variables is TRUE, we
are building bendlines for the 3D-version, otherwi
se for the flat.int using_3D_version = 1 ;// later
we need to create a bendline centerline// these a
re the start-end points of the bendline centerline
// note that they are points p1 andp2 on the face1
side of the bendline// this is done because somet
imes (when the bendline is not bent) we use the//
face1 surface as the bendlinesurface, ie. the bend
line orientation is defined// with respect to face
1BM_POINT bendline_centerline_p1, bendline_centerl
ine_p2 ;// contact list parametersBM_LINKED_LIST_N
ODE *line_in_list, *next_line_in_list ;BM_LINKED_L
IST_NODE *left, *right ;int number_of_lists = (lon
g) (*contact)->get_obj() ;BM_LINKED_LIST_NODE *con
tact_list = (*contact)->next() ;left =(BM_LINKED_L
IST_NODE *) contact_list->get_obj() ;right = (BM_L
INKED_LIST_NODE *) (contact_list->next())->get_obj
() ;BM_LINE *first_line_in_left= (BM_LINE *) left-
>get_obj() ;BM_LINE *first_line_in_right = (BM_LIN
E*) right->get_obj() ;BM_LINE *last_line_in_left ;
BM_LINE *left_line, *right_line ;// get loops in b
oth bodiesBM_LOOP *face1_loop = first_line_in_left
->get_loop() ;BM_LOOP *face2_loop = first_line_in_
right->get_loop();if (NULL == face1_loop || NULL =
= face2_loop) return 0 ;// 2D-bodies of either fac
eBM_2D_BODY *face1_body = face1_loop->get_2D_bod
y() ;BM_2D_BODY *face2_body = face2_loop->get_2D_b
ody() ;if (NULL == face1_body || NULL == face2_bod
y) return 0 ;// get face1 and face2BM_FACE *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 ;// chec
k whether we are using the flat version of the par
t, or 3D-version of the part.if (face1->get_curren
t_3D_version() != face1_body || face2->get_current
_3D_version() != face2_body) using_3D_version = 0
;// get surfacesof either facesBM_PLANE *face1_pl
ane, *face2_plane ;face1_plane = (BM_PLANE *) face
1_body->get_surface() ;face2_plane = (BM_PLANE *)
face2_body->get_surface() ;/* 先ず、ベンドライン
と共にしなければならない全てのこと、ベンドラインを
形成する、ベンドopを形成する、ベンドopパラメー
タを設定する、ベンドラインに対するシリンダを形成、
設定する、ベンドライン、センタラインを設定するなど
を行う。*/// try to figure out whether we have aFR
ONT or BACK bend.BM_VECTOR v_face2_body((face2_pla
ne->get_normal())*(first_line_in_right->get_v()))
; // this vector// points towards the inside of f
ace2 on the plane of face2BM_VECTOR v_face2_normal
(v_face2_body*(first_line_in_left->get_v())) ; //
this is the correct normal for face2?// compute th
e angle between facesdouble angle = v_face2_normal
^ (face1_plane->get_normal()) ;// compute bend ty
pe (FRONT/BACK)if (fabs(angle) <= BM_ANGLE_TOLERAN
CE) angle = PI ;else {BM_VECTOR v((face1_plane->ge
t_normal())*v_face2_normal) ;if (v % (first_line_i
n_left->get_v()) > 0.0)angle = PI + angle ; // BAC
K bendelse angle = PI - angle ; // FRONT bend}// c
reate a new empty bendline and add it to the partB
M_2D_BODY *new_auto_bendline = new BM_2D_BODY ;if
(NULL == new_auto_bendline) return 0 ;BM_BENDLINE
*new_bendline = new BM_BENDLINE(&part, using_3D_ve
rsion ? NULL : new_auto_bendline, using_3D_version
? new_auto_bendline : NULL) ;if(NULL == new_bendl
ine) {delete new_auto_bendline ;return 0 ;}// crea
tea regular bend op for the bendlineBM_BEND_OP_REG
ULAR *new_bend_op = newBM_BEND_OP_REGULAR(NULL,ang
le,0.0,0.0) ; // don’t attach to bendline yetif
(NULL == new_bend_op) {delete new_bendline ;return
0 ;}// attach this bend op to the bendline. this
will just assign the bend_op variable inthe bendli
nenew_bendline->attach_bend_op(new_bend_op) ;// cr
eate bendline surface. if angle is not 180 degree
s, we create a cylinder, otherwisea (face1) plane.
BM_SURFACE *bend_surface ;if (fabs(angle - PI) <=
BM_ANGLE_TOLERANCE) { // bendline not being bent//
note : face1 plane is thebendline surfacebend_sur
face = new BM_PLANE(*face1_plane) ;new_bendline->D
o_This_Bend(0) ; // this will invalidate 3D versio
n as well. later wevalidate it.// set sense to the
same as face1 sensenew_auto_bendline->set_sense(f
ace1_body->get_sense()) ;}else {// first, compute
vxBM_VECTOR v_face1_body((face1_plane->get_norma
l())*(first_line_in_left->get_v())) ;// v_face1_bo
dy points towards the inside of face1 on the plane
of face1v_face1_body.set_length(-1.0) ; // invert
and normalizev_face2_body.set_length(-1.0) ; // i
nvert and normalize// this is the vx vector of the
bendline surfaceBM_VECTOR vx(v_face1_body + v_fac
e2_body) ;bend_surface =new BM_CYLINDER(first_line
_in_left->get_startpt(), first_line_in_left->get_e
ndpt(), vx, 0.0) ;new_bendline->Do_This_Bend(1) ;
// this will invalidate 3D version as well. later
we validate it.// set sense to 0, because we want
the bendline (cylinder) to represent explicitly OU
TSIDE// ie.thickness vector is opposite to the nor
mal (= radius vector).new_auto_bendline->set_sense
(0) ;}if (NULL == bend_surface) {delete new_bendli
ne ;return 0 ;}new_auto_bendline->set_surface(bend
_surface) ;// lastly we need to create the bendlin
e centerline, but for that we need to know its len
gth, and// start-end-points. However, for that we
need to process the contact list which contains th
e// lines that are adjacent. We will do that next,
and when done, will create bendline centerline./*
第二に、必要なら、幾つかのラインを破断し、全ての
隣接ラインを1つの隣接ラインに結合する。更に、面1
-ベンドラインと面2-ベンドラインの間の隣接情報を形
成する。*/// notice that processing one side of th
e contact is independent of the other side.// more
over, the logic is exactly the same. therefore, we
will use the following code// to process both fac
e1’ side and face2’ side.char face2_processed =
0 ;process_one_side_of_the_contact :// in general,
the contact line (on the side of either face (fac
e1 and face2)) will consist// of three lines - we
have a list of lines, first line is theline before
the contact, the// second line is the contact lin
e, the lastline is the line after the contact.// t
hese variables will be used to compute these three
lines.double k ;double k0, k1, k2, k3 ; // parame
tersk for the first line in the leftdouble end_k1,
end_k2 ; // parameters kfor the last line in the
left listBM_POINT p0, p1, p2, p3 ; // p0 - p3are t
he endpoints of the edges that will be left (ie. e
ndpoint of left_line, l2, l3).// p0 and p3 and the
two extreme endpoints and trivial to find. we rea
lly need to compute only p1 and p2.BM_LINE *l1, *l
2, *l3 ; //l1 is the line before l2, l2 is the lin
e that is adjacent, l3 is the one after it.// proc
ess first line of the left sidek0 = 0.0 ;k3 = 1.0
;first_line_in_left->is_point_on_line(first_line_
in_right->get_startpt(),&k1) ;first_line_in_left->
is_point_on_line(first_line_in_right->get_endpt(),
&k2) ;if (k1 > 1.0) k1 = 1.0 ;else if (k1 < 0.0) k
1 = 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 an
d p3 because wedon’t know the relative order// of
the first and last lines in the left list// find
and process the last linefor (line_in_list = left
; line_in_list ; line_in_list = next_line_in_lis
t) {if (NULL == (next_line_in_list = line_in_list-
>next())) {left_line = (BM_LINE *) line_in_list->g
et_obj() ;// first, we have to find the end of the
face2 listfor (line_in_list = right ; line_in_lis
t ; line_in_list = next_line_in_list) {if (NULL==
(next_line_in_list = line_in_list->next())) break
;}right_line = (BM_LINE *) line_in_list->get_ob
j() ;left_line->is_point_on_line(right_line->get_s
tartpt(),&end_k1) ;left_line->is_point_on_line(rig
ht_line->get_endpt(),&end_k2) ;if (end_k1 > 1.0) e
nd_k1 = 1.0 ;else if (end_k1 < 0.0) end_k1 = 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 ; }break ;}}// no
w we have to compute points p0, p1, p2 and p3.// b
utfirst we need to convert end-k parameters to equ
ivalent parameters withrespect to the // first lin
e in the leftp0 = left_line->get_startpt() ;p1 = l
eft_line->get_startpt() + end_k1 * (left_line->get
_v()) ;p2 = left_line->get_startpt() + end_k2 * (l
eft_line->get_v()) ;p3 = left_line->get_endpt() ;/
/ check k0first_line_in_left->is_point_on_line(p0,
&k) ;if (k< k0) k0 = k ;// check k1first_line_in_l
eft->is_point_on_line(p1,&k) ;if(k < k1) k1 = k ;/
/ check k2first_line_in_left->is_point_on_line(p2,
&k);if (k > k2) k2 = k ;// check k3first_line_in_l
eft->is_point_on_line(p3,&k) ;if (k > k3) k3 = k ;
// here we can compute p0, p1 and p3. later wecomp
ute p2.p0 = first_line_in_left->get_startpt() + k0
* (first_line_in_left->get_v()) ;p1 = first_line_
in_left->get_startpt() + k1 * (first_line_in_left-
>get_v()) ;p2 = first_line_in_left->get_startpt()
+ k2 * (first_line_in_left->get_v()) ;p3 = first_l
ine_in_left->get_startpt() + k3 *(first_line_in_le
ft->get_v()) ;// ok, we have computed p0-p3. now w
e will erase left list, except for the first line.
// we need the first linelater.// actually, the fi
rst line will, in the future, point to new linel2.
BM_LOOP *left_loop = first_line_in_left->get_loo
p() ;last_line_in_left = NULL ; // the last line i
n the left. we need it later to replace out-of-dat
e pointers with valid ones.line_in_list = left->ne
xt() ; // thisis the second line in the left list.
left->add_after(NULL) ;// note : wewill erase all
lines in the left list, starting from the second l
ine.for (; line_in_list ; line_in_list = next_line
_in_list) {next_line_in_list= line_in_list->next()
;// store a pointer to the last linelast_line_in_
left = (BM_LINE *) line_in_list->get_obj() ;left_l
oop->remove_edge(last_line_in_left) ;delete last_l
ine_in_left ;delete line_in_list ;}// finally, cre
ate the adjacent line l2, and two more lines (l1 a
nd l3) if necessary.if (p0 != p1) {l1 = first_line
_in_left ;l1->set(p0,p1) ;l2 = new BM_LINE(p1,p2)
;left_loop->add_edge_after(l1,l2) ;}else {l1 = NU
LL ;l2 = first_line_in_left ;l2->set(p0,p2) ;}if
(p2 != p3) {l3 = new BM_LINE(p2,p3) ;left_loop->ad
d_edge_after(l2,l3) ;}else l3 = NULL ;// last thin
g, create topology by making this line adjacent to
the bendlinel2->make_body_adjacent(new_bendline)
;// a big problem now is that we have deleted som
e lines.// the problem is that if we have a simult
aneous bend, other contacts could still be referin
g// to these lines we just deleted.// we have to g
o and check that, and if true, replace pointers to
the lines we have changed/deleted// with valid re
ferences.// // namely, lines that areaffected are
the first and last lines in the left.// potentiall
y references to them need to be replaced with refe
rences to l1 and l3.if (l1 || l3) check_references
_in_remaining_contacts(face2_processed ? contact_l
ist->next() : contact_list, // current list we are
working withface2_processed ? contact_list : cont
act_list->next(), // list on the other side ofthe
contactfirst_line_in_left, last_line_in_left, // t
hese are old references, to be checked if still va
lidl1, l3 // l1 and l3 are the new references) ;//
we will use the same piece of code to process bot
h sides of the contact.// if face2 side has not be
en processed, do it now.// however, first we need
to set some values of variables that are commonly
used.if (! face2_processed) {face2_processed = 1 ;
// first, l2 should be the left line.// l2 is the
real adjacent line (on the left). now it becomes t
he right line.left->set_obj(l2) ;// now we need to
switch left and rightsides// switch linesfirst_li
ne_in_left = first_line_in_right ;first_line_in_ri
ght = l2 ;// switch listsline_in_list = left ;left
= right ;right= line_in_list ;// store bendline c
enterline start-end pointsbendline_centerline_p1 =
p1 ;bendline_centerline_p2 = p2 ;goto process_one
_side_of_the_contact ;}/*ここで、コンタクトリスト
を削除することが出来る。*/BM_LINKED_LIST_NODE *lis
t, *next_list ;int lists_deleted = 0 ; // note, we
can only delete first two listsfor (list = contac
t_list ; lists_deleted <2 && list ; list = next_li
st) {next_list = list->next() ;// delete the listf
or (line_in_list = (BM_LINKED_LIST_NODE *) list->g
et_obj() ; line_in_list ; line_in_list = next_line
_in_list) {next_line_in_list = line_in_list->nex
t() ;delete line_in_list ;}delete list ;++lists_de
leted ;}// setthe correct number of contacts left
and update the pointerslong num_contacts = (long)
(*contact)->get_obj() ;if (--num_contacts < 1) {//
if nocontacts left, erase the whole contacts list
delete *contact ;*contact =NULL ;}else {(*contact)
->set_obj((BM_BASIC *) num_contacts) ;(*contact)->
add_after(list) ;}/* 最後に、センタラインを形成す
る。方向と長さが正しいことを確かにする。 p1とp
2は面1に関して規定される点に注目されたい。 すな
わち、p1->p2は面1の側のコンタクトに対する方
向である。*/BM_LINE centerline(bendline_centerline
_p1,bendline_centerline_p2) ;if (fabs(angle - PI)
<= BM_ANGLE_TOLERANCE) { // bendline not being ben
t// face1plane is the bendline surfaceif (face1->g
et_idx() > face2->get_idx()) centerline.reverse_li
ne() ;}else if (angle < PI) {if (face1->get_idx()
<face2->get_idx()) centerline.reverse_line() ;}els
e { // angle is > PIif(face1->get_idx() > face2->g
et_idx()) centerline.reverse_line() ;}new_auto_ben
dline->set_center_line(centerline) ;// if we are b
uilding bendlines for the 3D-version of the part,
// make sure 3D-version of the bendline is validat
ed because most likely we // want to UNFOLD right
away.if (using_3D_version) new_bendline->validate_
3D_version() ;*bendline_created= new_bendline ;ret
urn 1 ;}/* この関数の目的は、面からなる切断された
要素を持つ部分であって、この部分が、これらの新しい
ベンドラインを付加すると、接続されるようになるよう
に最小数のベンドラインを形成することにある。This f
unction assumes that the part has thickness 0.The
basic idea we usein this function is maximum spann
ing tree.We model the part by an undirected graph,
where faces are the nodes of the graph andthere i
s an edge between two nodes iff these two faces ar
e in contact (ie. are touching each other),the cos
t (or length) of the edge is the length of the lon
gestcontact between these two faces (ie. the lengt
h of the longest possiblebendline between the two
faces).In order to create bendlines we computea ma
ximum spanning tree for this graph and create aben
dline for every edge of the graph that is in the m
aximum spanning tree.There are two problems howeve
r :- It could be that the part already contains so
me bendlines(ie. some faces are already connecte
d).- When we compute the maximum spanning tree, we
can have two fringe-edges that have the same le
ngth.In that case, we don’t want to break ties ra
ndomly, but instead choosean edge that would min
imize the diameter of the spanning tree (the maxim
um distance between any two vertices of the tre
e).Algorithm :-----------We will process faces one
-by-one, starting from the first faces of the part
and proceedinguntil the last faces, and building
the maximum spanning tree along the way as we go.F
or every pair of faces, such that at least one of
the is not yet in the spanning tree,we keep the lo
ngest contact between them. When we expand the spa
nning tree, we choosethe contactbetween a face in
the tree and a face not in the tree that is the lo
ngest contactbetween any face in the tree and a fa
ce outside. If there is atie, we choose an edge th
atwould minimize the *//* 面(面1)を与えると、
この構造はこの面と他の面の間のコンタクトについての
情報を含む。 任意の2つの面に対して、これらの面の
間にコンタクトが有るか否かを知る必要があり、もしイ
エスなら、何がその長さであるかを知る必要がある。こ
のデータを処理する最も簡単な方法はそれを二次元配列
として記憶することにより与えられる。しかし、これは
多くのスペースを取り、その殆どは無駄に使われ、とい
うのは、通常は、多くの面があるときは、それらの殆ど
はそれらの面の間で何らのコンタクトも持たないことに
よる。 代わりに、我々は全ての面に対してこの情報を
構造のリストとして記憶することになる。我々は、2つ
の面の間のコンタクトの長さが0より大きいときにのみ
この記録を(すなわち、構造)生成する。*/typedef st
ruct CONTACT_INFO {// here we will keep track what
is the length of the longest contact between any
two faces// this is really a two-dimensional array
double length ;// here we keep a pointer to the ot
her faceBM_FACE *face2 ;// here we will keep the l
ongest contact for any two faces// this is really
a two-dimensional array stored as a linked list of
lists.BM_LINKED_LIST_NODE *contact ;// a pointer
to the next structure in alistCONTACT_INFO *next
;} contact_info ;/*これは、このファイルにおいて
多くの関数により用いられる非常に基本的な関数であ
る。 それはコンタクトリストを削除する。*/static v
oid delete_contact_info_list(contact_info *list){c
ontact_info *c, *c_next ;BM_LINKED_LIST_NODE *clis
t, *next_clist ;BM_LINKED_LIST_NODE *line_in_list,
*next_line_in_list ;for (c = list ; c ;c = c_nex
t) {c_next = c->next ;if (c->contact) {// skip the
header = num of contactsfor (clist = (c->contact)
->next() ; clist ; clist = next_clist) {next_clist
= clist->next() ;// delete the listfor (line_in_l
ist =(BM_LINKED_LIST_NODE *) clist->get_obj() ; li
ne_in_list ; line_in_list =next_line_in_list) {nex
t_line_in_list = line_in_list->next() ;delete line
_in_list ;}delete clist ;}// delete the headerdele
te c->contact ;}delete c ;}}static void delete_con
tact_info_structure(contact_info *c){BM_LINKED_LIS
T_NODE *clist, *next_clist ;BM_LINKED_LIST_NODE *l
ine_in_list, *next_line_in_list ;if (NULL == c) re
turn ;if (c->contact) {// skip the headerfor (clis
t = (c->contact)->next() ; clist ; clist = next_cl
ist) {next_clist = clist->next() ;// delete the li
stfor (line_in_list = (BM_LINKED_LIST_NODE *) clis
t->get_obj() ; line_in_list ; line_in_list = next_
line_in_list) {next_line_in_list = line_in_list->n
ext() ;delete line_in_list ;}delete clist ;}// del
ete the headerdelete c->contact ;}delete c ;}/*
この関数は2つの面の間で最良の(すなわち、最も長
い)コンタクトを計算し、格納する。*/static int com
pute_the_longest_contact_between_faces(BM_FACE & f
ace1 /* IN */, BM_FACE & face2 /* IN */,contact_in
fo **computed_contact_list /* OUT */){// so far we
have computed nothing*computed_contact_list = NUL
L ;BM_LINKED_LIST_NODE *contact_list ; // a list o
f all contacts between face1 and face2 we will com
puteif (! BM_compute_all_face_to_face_contacts(fac
e1, face2, &contact_list)) return 0 ;double x = BM
_keep_largest_contact_remove_the_rest(&contact_lis
t) ;if (x < BM_PRECISION) return 1 ; // no contact
between these two facescontact_info *c ;if (NULL
== (c = new contact_info)) {// delete contact list
BM_LINKED_LIST_NODE *clist, *next_clist ;BM_LINKED
_LIST_NODE *line_in_list, *next_line_in_list ;for
(clist = contact_list->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 =
next_line_in_list) {next_line_in_list = line_in_li
st->next() ;delete line_in_list ;}delete clist ;}d
elete contact_list ;return 0 ;}// initialize the s
tructurec->contact = contact_list ;c->next = NULL
;c->face2 = &face2 ;c->length = x ;*computed_cont
act_list = c ;return 1 ;}/* この関数は現在接続さ
れた要素に新しい面を付加する。 それはまた、この新
しい面と、処理されていない他の全ての面の間の最も長
いコンタクトを計算する。*/static int add_face_to_c
onnected_component(BM_PART *part, BM_FACE *face2 /
* this is the face we are adding to the connected
component */, long *end_id /* an index of the last
face in the connected component. this is where fa
ce2 is. */, contact_info **all_contacts /* all con
tact info between face2 andother outside faces wil
l be here *//* we will compute it and construct th
is 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 a
djacent faces outside the connected componentall_c
ontacts[*end_id] = NULL ;// in this loop we want t
o compute all contacts between face2and all other/
/ faces not yet in any connected component.for (cu
rrent_face = part->get_face_list() ; current_face
; current_face = (BM_FACE *) current_face->nex
t()) {if (current_face->get_user_id() >= 0) contin
ue ; // current_face is in some other connected co
mponent// compute the best contact between face2 a
nd current_faceif (! compute_the_longest_contact_b
etween_faces(*face2, *current_face, &cl)) return 0
;if (NULL == cl) continue ; // there is no contac
t between these two facesif (NULL == last_clist) a
ll_contacts[*end_id] = cl ;else last_clist->next =
cl ;last_clist= cl ;}face2->set_user_id(*end_id)
;idx_to_face_mapping[*end_id] = face2;++(*end_id)
;return 1 ;}/* これらの2つの関数は、ユーザがト
ポロジーグラフにおける2つの面の間の距離を設定し得
ることを許容する。 dist btw 面は二次元配列の上部
右半部である。*/static long get_face2face_dist(uns
igned char *dist_btw_faces,long number_of_faces, l
ong dist_array_size, longj, long i){long k ;// dis
tance between face_i and face_i is 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_face2face_dist(unsigne
d char *dist_btw_faces,long number_of_faces, long
dist_array_size, long j, long i, unsigned char dis
tance){long k ;// distance between face_i and face
_i cannot be setif (i == j) return ;// sort indece
sif (j < i) { k = i ; i = j; j = k ; }k = number_o
f_faces - i ;dist_btw_faces[dist_array_size - ((k*
(k-1)) >> 1) + (j - i) - 1] = distance ;}/* この
関数は接続された要素における所定の面と他の面の間の
最大距離を戻す。*/static long get_largest_distance
_for_face(unsigned char *dist_btw_faces,long numbe
r_of_faces, longdist_array_size, long start_id, lo
ng end_id, long face_id){long j, k ;if (NULL == di
st_btw_faces) return 0 ;long current_face_to_face_
distance= 0 ;for (j = start_id ; j < end_id ; j++)
{k = get_face2face_dist(dist_btw_faces,number_of_
faces,dist_array_size,j,face_id) ;if (k > current_
face_to_face_distance) current_face_to_face_distan
ce = k ;}return current_face_to_face_distance ;}/*
これは主要なAutobend関数である。その目的
は部分に対するベンドラインを自動的に生成することに
ある。*/int BM_PART::auto_bend(void){long i, j, k
;BM_FACE *current_face ;BM_FORMING *current_formi
ng ;BM_BENDLINE *current_bendline ;// at end of th
e function werelease memory. this code for releasi
ng memory is shared// between thecases when this f
unction fails, or succeeds.// therefore, before we
getto that code, we have to know the return code.
int ret_value ;// these are the two faces we will
be creating a bendline for (ie. between these two
faces).BM_FACE *face1, *face2 ;// here we keep a l
ist of information about contacts between every fa
ce and other faces.// this is an array lists.conta
ct_info **all_contacts = NULL ;// here we will kee
p track what face corresponds to each row in face_
to_face_length[] and all_contacts[]arraysBM_FACE *
*idx_to_face_mapping = NULL ;// this (two-dimensio
nal) array is used to store distances between face
s in the TOPOLOGY GRAPH.// these distance values a
re used to break ties in the maximum spanning tree
algorithm when// two edges have the same length. N
ote that the distancebetween (i,j) is the same as/
/ the distance between (j,i). This means that the
distance matrix is a symmetric matrix, and we// on
ly need to store one half (upper right triangle) t
o save space.// we will use this method of breakin
g ties only when the number of faces is less than
256.// this has two advantages : 1) the distance b
etween any two faces is alwaysless than 256,// and
therefore we only need a char (8 bits) to store t
hedistance values, 2) since we only// need a char
for a pair, the total this array can take is 32K b
ytes, which is not too much memory.unsigned char *
dist_btw_faces = NULL ;// this will be the size of
the distance array, given some number of faceslon
g dist_array_size ;// we will have to create a hea
p because some portion of the part can already be
connected//and we need to make sure we don’t crea
te any bendlines for that portion of the part.// w
e will use a heap to traverse that portion of the
part.long body_priority = number_of_formings + num
ber_of_faces + number_of_bendlines ;// Check if th
ere are any bodies. If no, we are done.if (body_pr
iority < 1) return 1 ;// this is the heap we will
allocate. this is used when we add a face to the c
onnected component// to add all other faces connec
ted to it as well. the problem is that the part co
uld already//contain some bendlines.DBM_HEAP *heap
= NULL ;// this is the start-index(in face_to_fac
e_length[] and all_contacts[]) arrays // of the cu
rrentconnected componentlong start_id = 0 ;// this
is the end-index (in face_to_face_length[] and al
l_contacts[]) arrays // of the current connectedco
mponentlong end_id = 0 ;// if TRUE, we are startin
g a new connected componentint starting_new_connec
ted_component = 1 ;// allocate memory forlocal var
iablesif (NULL == (all_contacts = new contact_info
*[number_of_faces])) goto failure ;if (NULL == (id
x_to_face_mapping = new BM_FACE*[number_of_face
s])) goto failure ;if (NULL == (heap = new DBM_HEA
P(0,NULL,NULL,body_priority))) goto failure ;if (n
umber_of_faces < 256) { // allocate memory for the
face-face distance array only when // the number
of faces is not too largedist_array_size = (number
_of_faces*(number_of_faces- 1)) >> 1 ;if (NULL ==
(dist_btw_faces = new unsigned char[dist_array_siz
e])) goto failure ;}++body_priority ; // just in c
ase, we don’t wantthe priority to go to 0 later./
/ initialize arraysfor (i = 0 ; i < number_of_face
s ; i++) {all_contacts[i] = NULL ;idx_to_face_mapp
ing[i] = NULL ;}// initially mark all faces as not
processedfor (i = 0, current_face= first_face ; c
urrent_face ; current_face = (BM_FACE *) current_f
ace->next()) {current_face->this_body_already_proc
essed = 0 ;// this will tell us whether this face
has been already processed.// if yes, this id isth
e index in face_to_face_length[] and all_contact
s[] arrays.current_face->set_user_id(-1) ;}/* 先
ず、面の現在接続された要素の最大スパンツリーを拡大
することを試みる。*/// these two variables are use
d in tie-breakinglong best_face_to_face_distance,
current_face_to_face_distance ;// thisis the lengt
h of the best contact so far (ie. the longest cont
act)double best_length ;// this is a pointer to th
e best contact_info structure found so farcontact_
info *best_cntct ;expand_spanning_tree :// first,
check if all faces have been processed// end_id is
where we will put the next face we add to the con
nected componentif (end_id >= number_of_faces)goto
done ;contact_info *cntct, *cntct_next, *cntct_pr
ev ;best_length =-1.0 ;best_face_to_face_distance
= 999999 ; // a really large number// in this loop
we check all faces already in the connected compo
nent and try// to find a face that has the largest
contact between itself and an adjacent face outsi
de the// current connected component.for (i = star
t_id; i < end_id ; i++) {// in this loop we are ch
ecking for a largest contact between the current f
ace// in the connected component and all of itsadj
acent faces outside the connected component.cntct_
prev = NULL ;for (cntct = all_contacts[i] ; cntct
; cntct = cntct_next) {cntct_next = cntct->next ;
// check if this adjacent face is already processe
dif ((cntct->face2)->get_user_id() >= 0) {// this
means that face2 has already been added to the con
nected component// and we don’t really need the c
ontact info stored in this structure any more.// w
e will delete it.// this willsome time in the futu
re and free up some space.delete_contact_info_stru
cture(cntct) ;if (NULL == cntct_prev) all_contacts
[i] = cntct_next ;elsecntct_prev->next = cntct_nex
t ;continue ;}// ok, this adjacent face notprocess
ed. // check if it is better than the previously k
nown best.// first check if there is a tie, and if
we have allocated a face-face distance array// th
en use the face-to-face distances to break the tie
if (fabs(cntct->length - best_length) <= distance_
tolerance && dist_btw_faces) {// if tie-breaking i
s used, compute the largest distance for this face
(ie. face1)current_face_to_face_distance = get_la
rgest_distance_for_face(dist_btw_faces,number_of_f
aces, dist_array_size, start_id, end_id, i) ;//pre
fer the one with the smaller largest distanceif (c
urrent_face_to_face_distance < best_face_to_face_d
istance) {face1 = idx_to_face_mapping[i];face2 = c
ntct->face2 ;best_length = cntct->length ;best_cnt
ct = cntct;best_face_to_face_distance = current_fa
ce_to_face_distance ;}}// take simply the one that
is betterelse if (cntct->length > best_length) {f
ace1= idx_to_face_mapping[i] ;face2 = cntct->face2
;best_length = cntct->length ;best_cntct = cntct
;// if tie-breaking is used, compute the largest
distance for this face (ie. face1)best_face_to_fac
e_distance = current_face_to_face_distance = get_l
argest_distance_for_face(dist_btw_faces,number_of_
faces, dist_array_size, start_id, end_id, i) ;}cnt
ct_prev = cntct ;}}// at the end of this loop,// f
ace1, face2, best_cntct should havecorrect values,
if best_length > 0.0, // that means we can expand
the tree./* 我々がスパンツリーを拡大出来るか否か
をチェックする。 我々が接続要素を拡大することに戻
るまでまでのこの点に対して、我々は単に面2を用いつ
つあり、すなわち、我々は面1を必要としていない。
唯一の場合は、我々が新しいベンドラインを生成すると
きであるが、我々はコンタクトリストから面idを抽出
することが出来る。*/if (best_length < distance_tol
erance) {// looks like we cannot expand the spanni
ng tree// none of the faces in the current connect
ed component has any adjacent faces// outside the
connectedcomponent.// most likely this connected c
omponent is finished and, sincethere must be still
faces left,// there is more than one connected co
mponent.// // next we try to find the first face i
n the next connected component so that we// can co
ntinue and create all bendlines for this new conen
cted component.for (current_face = first_face ; cu
rrent_face ; current_face = (BM_FACE *) current_fa
ce->next()) {if (current_face->get_user_id() < 0)
break ;}if (NULL == current_face) goto done ; // w
e should never get here// first, we can delete all
contact information about the current (now old) c
onnected componentfor (i = start_id ; i < end_id ;
i++){delete_contact_info_list(all_contacts[i]) ;a
ll_contacts[i] = NULL ;}//here we will be starting
a new connected componentstarting_new_connected_c
omponent = 1 ;start_id = end_id ;// we will skip t
he bendline creationnormally needed when adding a
face to a connected componentface2 = current_face
;}else {// ok, we are in the middle of a conencte
d componentstarting_new_connected_component = 0 ;/
/ create a bendline between face1 and face2// noti
ce : we might have to create a simultaneous bendlo
ng num_contacts = (long) (best_cntct->contact)->ge
t_obj() ;BM_BEND_PROPERTY_SIMULTANEOUS *sim_bend =
NULL ;if (num_contacts > 1) {sim_bend = new BM_BE
ND_PROPERTY_SIMULTANEOUS(this, num_contacts, NULL)
;if (NULL == sim_bend)goto failure ;}BM_BENDLINE
*new_bendline ;for (long contacts_done = 0 ;contac
ts_done < num_contacts ; contacts_done++) {if (! B
M_create_bendline(*this, &(best_cntct->contact),&n
ew_bendline)) goto failure ;// note that this func
tion will delete one contact for which a bendline
was created as wellif (num_contacts > 1) {// add t
his bendline to the simultaneouspropertynew_bendli
ne->add_property(sim_bend) ;}}}// store "1 + the c
urrent index of the last connected-component-face"
j = end_id ;// we could add face2 to the connected
component right away, but we could save some time
by// first checking if face2 has any other stuff
(outside this connected component) connected to i
t.// if yes, we will be adding that stuffto this c
onnected component right away,// but in that case
there is no need for us to compute contacts betwee
n face2 and that other// stuff in the first place.
// Therefore, we will just remember that face2 sho
uld beadded, will process adjacent stuff first,//
and then will actually add face2 (and some more st
uff may-be) to the connected component.// // Note:
we will actully put face2 in the heap, and when w
e remove it from theheap,// we will remember to ad
d it to the connected component/* ここで,我々
は、この面(すなわち、面2)がそれに接続された他の
任意の3D体を有するか否かをチェックする必要があ
る。 もし、イエスなら、我々は、面2に接続された全
ての面を現在接続された要素に付加するために、これら
の接続を追求する必要がある。*/heap->empty() ;if (!
heap->insert(body_priority--, (long) face2)) goto
failure ;face2->this_body_already_processed = 1 ;
// check if face2 has a parent face or not. if no
t, set the id in local arrayequal to // face2’s o
wn id. this way we know it has no parent face.// /
/ IMPORTANT : normally user_id of every face is a
pointer to its index in the contact-info array.//
temporarily we will use this information tokeep tr
ack which of the faces already processed// is the
parent-face (inthe topology graph) of every new fa
ce added to the connected component.// this inform
ation will be used later to compute distances in t
he facetopology graph.// the following loop (contr
olled by the heap) stores allfaces not yet in the
connected// component, but connected to this face
2.// later when the actualy adding of new faces to
the conencted component is done,// we overwrite u
ser_id with the correct value.if (! starting_new_c
onnected_component) face2->set_user_id(face1->get_
user_id()) ;elseface2->set_user_id(end_id) ;// in
the following while loop we will use this_body_alr
eady_processed member variable to keep// track whe
ther a varible is processed; not processed, but si
tting in the heap; or unseen yet.// 0 - unseen bod
y// 1 - body in the heap// 2 - body already finish
ed//also, in this while loop we will be using the
user_defined_id of every3D-body to keep// track of
the parent face of every 3D-body we traverse.// t
his has two benefits : 1) we will remember the par
ent face of everyface and can compute// distances
between faces later, and // 2) this waywhen faces
are later added to the spanning tree, distance bet
ween someother // face and this face will not be c
omputed, since it is not necessary.BM_3D_BODY *bod
y ;BM_TOPOLOGY_RECORD *toplgy ;while (heap->get_si
ze() > 0) {if (! heap->remove(&i,(long *) &body))
goto failure ;// a safetycheckif (NULL == body) co
ntinue ;// check if this body is already finishedi
f (body->this_body_already_processed > 1) continue
;// get body topologytoplgy = body->get_adj_lis
t() ;if (NULL == toplgy) continue ;// check if the
body is a face. if yes, memorize.if (body->is(BM_
ENTITY_TYPE_FACE)) {face2 = (BM_FACE *) body ;// m
emorize to add this face to the connected componen
t lateridx_to_face_mapping[j++] = face2 ;}body->th
is_body_already_processed = 2 ;// process all adja
cent bodiesfor (current_face =(BM_FACE *) toplgy->
get_first_face() ; current_face ; current_face =
(BM_FACE *) toplgy->get_next_face()) {// make sure
that we don’t processfaces twiceif (current_face
->this_body_already_processed) continue ;if (! hea
p->insert(body_priority--,(long) current_face)) go
to failure ;current_face->this_body_already_proces
sed = 1 ;// make sure we memorize the parent face
index in the local spanning tree arraycurrent_face
->set_user_id(body->get_user_id()) ;}for (current_
forming = (BM_FORMING *) toplgy->get_first_forming
() ; current_forming ; current_forming = (BM_FORMI
NG *)toplgy->get_next_forming()) {if (current_form
ing->this_body_already_processed) continue ;if (!
heap->insert(body_priority--,(long) current_formin
g)) goto failure ;current_forming->this_body_alrea
dy_processed = 1 ;//make sure we memorize the pare
nt face index in the local spanning treearrayif (b
ody->is(BM_ENTITY_TYPE_FACE)) current_forming->set
_user_id(j-1) ;else current_forming->set_user_id(b
ody->get_user_id()) ;}for (current_bendline = (BM_
BENDLINE *) toplgy->get_first_bendline() ; current
_bendline ; current_bendline = (BM_BENDLINE *) top
lgy->get_next_bendline()) {if (current_bendline->t
his_body_already_processed) continue ;if (! heap->
insert(body_priority--,(long) current_bendline)) g
oto failure ;current_bendline->this_body_already_p
rocessed = 1 ;// make sure we memorize the parent
face index in the local spanning tree arrayif (bod
y->is(BM_ENTITY_TYPE_FACE)) current_bendline->set_
user_id(j-1) ;else current_bendline->set_user_id(b
ody->get_user_id()) ;}}// finally we need to compu
te contacts between this face and all other faces,
that we postponed// and add them to the connected
component.long face1_id ;for (i = end_id ; i < j
; i++) {face2 = idx_to_face_mapping[i] ;// first,
compute distances in the TOPOLOGY GRAPH between t
his face (ie. face2) // and all faces previouslyin
the connected component.// we will use the parent
face id in the local spanning tree array for tha
t.face1_id = face2->get_user_id() ; // note: face1
_id is the parent id of face2 (ie. there is a bend
line between face1_id and face2 that we count).if
(dist_btw_faces && face1_id != i) {// if equal ->
face2 has no parents, // ie. a new connected compo
nent (must be start_id = end_id).// actually, it m
ust be here true that face1_id < ifor (k = start_i
d ; k < end_id ; k++) {set_face2face_dist(dist_btw
_faces, number_of_faces, dist_array_size, k, i, ge
t_face2face_dist(dist_btw_faces,number_of_faces,di
st_array_size,k,face1_id) + 1) ;}}// else ifequal,
it must be that i == ’the end_id’ in the beginn
ing of this for-loop.// note that the next functio
n (add_face_to_connected_component(...)) will incr
ement end_id.if (! add_face_to_connected_component
(this, face2, &end_id, all_contacts, idx_to_face_m
apping)) goto failure ;}// ok, the current connect
ed component has no connections to the outside.//
tryto expand the spanning tree.goto expand_spannin
g_tree ;done :ret_value =1 ;goto release_memory_an
d_return ;failure :ret_value = 0 ;release_memory_a
nd_return :// free memory if necessaryfor (i = 0 ;
i < number_of_faces ; i++) {delete_contact_info_l
ist(all_contacts[i]) ;}if (all_contacts)delete []
all_contacts ;if (idx_to_face_mapping) delete [] i
dx_to_face_mapping ;if (heap) delete heap ;if (dis
t_btw_faces) 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,
ArrowHeadLength;// These variuables definethe str
ucture of an arrow for the 2D clean up funciton.ex
tern double view_boundaries[MaxNumberOfViews+1]
[4];// This array is used to store thebounding box
of each connected component of the input drawing.
// once the views are detected, several compo
nents might be mapped to a single view.extern int
type_of_view[MaxNumberOfViews+1];// This array
mapsevery view to its type, namely to one of Top,
Left, Right, Front, Backview.// Its content is va
lid only after ’DoneViews’ was called.//int view
_rotation_flag[MaxNumberOfViews+1];// This array i
s used for markingrotated views. // If the i’th e
lement is ’1’ then the view is rotated.//extern
static char original_lvmask[32] ;// At the beginni
ng we save the (on,off) status of all the layers./
/extern static char twoDmask[32] ;//extern static
char threeDmask[32] ;// The masks used to display
the 2Dand 3D models.//extern static int original_w
orklevel ;// Specifies theoriginal work level of t
he user when fold is started// static int original
_setup_available = 0 ; // true iff original (laye
r) setup is available, ie. can be restoredextern i
nt dialog_open_flag = 0;// This variable isa flag
which specifies whether some dialog boxes were ope
ned.extern intAtrimLineTypeSwitch, AtrimColorSwitc
h, AtrimWidthSwitch, AtrimCenterLineSwitch;// thes
e switches are used to specify in which cases Auto
Trim will trim lines.//struct node *F2dCleanUpInpu
tEntity(char *, struct drawing *);//static int sel
ect_flange(struct resbuf *rb);typedefstruct Vector
{doublex,y,z;};extern double BBminX,BBmaxX,BBminY,
BBmaxY,BBminZ,BBmaxZ;/*関数: 名称: TestFindBound
aryDescription: It is a manual function. When user
selected a boundary’s entity of a view, the func
tion would findall of the connected entities for t
he view.戻り値:< 0: Error= 0: No proccess> 0: Com
pleted successfully; the Number is the counter of
found entities.パラメータ:副関数:int F2dCleanU
pFindArrowlook for arrow type entityint F2dCleanUp
FindArrowEndEntityfind arrow end lineint F2dCleanU
pFindArrowCenterEntityfind arrow center lineint F2
dCleanUpFindArrowOneSideOpenEntityfind one side op
en entity for arrow typeint F2dCleanUpComputeCente
rLineAnglecompute center line angleint F2dCleanUpC
heckStartEndEntitycheck start and end entitiesint
F2dCleanUpFindOutSideLooplook for out sideloop ent
itiesint F2dCleanUpFindOutNextEntitylook for conne
cted entity with out side loop entitiesstruct node
*F2dCleanUpFindGroupMinXlook for minimum X-value
for a entities groupstruct node_list *F2dCleanUpFi
ndGrouplook for a group entities connected with in
put entitystruct node *F2dCleanUpInputEntity ( old
function )look for a selected entity on screenint
F2dCleanUpLineAnglecompute a line type entity’s a
ngle int F2dCleanUpArcAnglecompute a arc type enti
ty’s angle.int F2dCleanUpChangeChildrenFlagchange
entity’s children flagsint F2dCleanUpChangeArrow
VertexFlagchangearrow top vertex’s flags and set
arrow center line coordinatesint F2dCleanUpChangeC
olorchange entity’s colorint F2dCleanUpFindOneSid
eOpenEntitylook for one side open entities and the
y are vertical with arrow typeentities double F2dC
leanUpLineLengthcompute line type entity’s length
==================================================
===============*/intTestFindBoundary(){//external
functionsint F2dCleanUpFindArrow();int F2dCleanUpC
hangeColor();int F2dCleanUpFindOneSideOpenEntit
y();int F2dCleanUpFindOutSideLoop();int F2dCleanUp
ChangeDrawingColor();struct node *F2dCleanUpInputE
ntity();struct node *F2dCleanUpFindGroupMinX();str
uct node_list *F2dCleanUpFindGroup();//entities co
unter and flagsint count = 0,assistant_line_flag =
0;//link list and temp liststruct node_list*Entit
ies_change_color_list1; //selected entity and temp
entitiesstruct node *entity,*MinXvalueEntity;//B
egin//----------------------------------//Step_1:/
/check the number of entites// get count of all e
ntities// if an error occurred, exit immidiately.
if (number_of_entities<0) return -1;for( ;; )
{//---------------------------------//Step_2:selec
t one entityentity= F2dCleanUpInputEntity( "Select
a Boundary Entity for a view",&trim_drawing);if
( entity == 0 )return0;if ( entity->flags != 0 )co
ntinue;//---------------------------------//Step_
3: find a connected entities groupEntities_change_
color_list1 = F2dCleanUpFindGroup( entity, &count
);if ( Entities_change_color_list1 == 0 )return0;
//---------------------------------//Step_4: find
arrow lineF2dCleanUpFindArrow( Entities_change_col
or_list1 );//---------------------------------//St
ep_5:find one side open entitiesassistant_line_fla
g = F2dCleanUpFindOneSideOpenEntity( Entities_chan
ge_color_list1 );//-------------------------------
--//Step_6:find outside loop entities without assi
stant entities//check a flag for outsideloop proce
ssif ( count < 1 )continue;MinXvalueEntity = F2dCl
eanUpFindGroupMinX(Entities_change_color_list1);if
( MinXvalueEntity == 0 )continue;//--------------
-------------------//Step_7://find outside loop en
titiesF2dCleanUpFindOutSideLoop( MinXvalueEntity
);//---------------------------------//Step_X://c
hange color to Magenta for a selected boundary
//turn off input levels ck_levels(CK_OFF,1,25
5);#ifdef CKWINF2dCleanUpChangeColor(Entities_chan
ge_color_list1);#endif#ifdef VELLUMF2dCleanUpChang
eDrawingColor(&trim_drawing);#endif//clear a flag
for outside loop processassistant_line_flag = 0;//
turn ON the level used to store the trimmed entit
ies. ck_levels(CK_ON,TrimLevel, TrimLevel);#ifd
ef CKWINif (*SwitchRedraw == 1)ck_redraw( CK_PRIME
_VP );#endif}return count;}/*=====================
============================================関数:
名称: F2dCleanUpFindGroup記述: look for a group
entities connected with input entity 戻り値:= 0:
Completed successfully;パラメータ:入力: Entity:
a entity出力:NodeList: a node list connected wit
h input entity ===================================
==============================*/struct node_list *
F2dCleanUpFindGroup(struct node *Entity, int *Cnt
){//entities counter and flagsint count = 0;//lin
k list and temp liststruct node_list*EntitiesList
1,*Out_temp_list,*temp_list, *temp_list1,*open_tem
p_list, *open_list; //selected entity and temp ent
itiesstruct node *Next_entity;//initializeEntities
List1 =( struct node_list * ) calloc ( 1, sizeof
( struct node_list ));open_list =( struct node_lis
t * ) calloc ( 1, sizeof ( struct node_list ));//s
et a flag for the boundary entitycount = 0;//set p
ointer to first entityopen_list->car = Entity;//se
t a open flagto the nodeopen_list->car->flags = 1;
//set link addressopen_list->cdr = NULL;//set the
pointer to output node listEntitiesList1->car = op
en_list->car;EntitiesList1->cdr = open_list->cdr;/
/---------------------------------//Step_3://find
connected entitiesfor( temp_list = open_list;
( temp_list //&&(temp_list->cdr != 0)
); ) {if ( temp_list->car == NULL )break;//ge
t a pointer from open listNext_entity = temp_list-
>car;//set a closed flag to the nodeNext_entity->f
lags = 2;//close the node ( delete the node from o
pen list )open_list = open_list->cdr;//count the n
umber of entitiescount++;// look for first connect
ed entity whose flags=0.for (temp_list1=Next_entit
y->connected_nodes; // temp_list1 && temp_list
1->car->flags==1; ( temp_list1!=0 && t
emp_list1->car!=0); temp_list1=temp_list1->c
dr){ if ( temp_list1->car == NULL )break; // if
found an unmarked connected entityif (temp_list1
&& temp_list1->car->flags==0&& Entity->line_type =
= temp_list1->car->line_type&& Entity->color == te
mp_list1->car->color&& Entity->is_thickness == tem
p_list1->car->is_thickness ) {// allocate memory
for open list elementopen_temp_list = ( struct no
de_list * ) calloc ( 1, sizeof ( struct node_lis
t));// allocate memory for output node list elemen
tOut_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 node list Out
_temp_list->car = temp_list1->car;//set a open fla
gto the nodeopen_temp_list->car->flags = 1; // con
nect to the open listopen_temp_list->cdr = open_li
st;// move the pointer of open list to the topopen
_list = open_temp_list;// connect to the output no
de listOut_temp_list->cdr = EntitiesList1;// move
the pointer of output nodelist to the topEntitiesL
ist1 = Out_temp_list;}}// assign value to the loop
variabletemp_list = open_list;}*Cnt = count;retur
n EntitiesList1; }/*==============================
=================================== 関数: 名
称: F2dCleanUpArcAngle 記述:アーク形エンテ
ィティの角度を計算する。 戻り値:RotateVertexFla
g:方向フラグ =1:vertex1は回転ポ
イントである。 =2:vertex2は回転
ポイントである。 パラメータ: 入力:
1 OriginVertex:回転頂点 2 E
ntity:アーク形エンティティ 出力:1 Entity
Angle:方向角度(ラジアン) 2 EntityAn
gleAnother: 他のサイド方向角度===================
=============================================*/int
F2dCleanUpArcAngle(//inputstructplanar_vertex *Or
iginVertex,structnode *Entity,//outputdouble*Entit
yAngle,double*EntityAngleAnother){//return value i
ntRotateVertexFlag=0;//length and angledoubleToler
ance = 0.0;//set toleranceTolerance = F2dCleanUpTo
lerance;//select connected side of entityif ( Enti
ty->vertex1 == OriginVertex ){//get arc start-angl
e//( direction : from circle-center to start-point
)RotateVertexFlag= 1;*EntityAngle = ( Entity->Ang
Begin ) * pi / 180.0;//change angleto oppsite dire
ction//( direction : from start-point to circle-ce
nter )*EntityAngle = *EntityAngle + pi;//check ang
le if ( *EntityAngle >(2.0*pi)) *EntityAngle = *En
tityAngle - 2.0*pi;if ( fabs(*EntityAngle-2.0*pi)
<Tolerance ) *EntityAngle = 0.0;//compute tangentl
ine angle for the arcend-angle//( direction : from
start-point to end-point )*EntityAngle = *EntityA
ngle + 1.5 * pi;//check angle if ( *EntityAngle >
(2.0*pi)) *EntityAngle = *EntityAngle - 2.0*pi;if
( fabs(*EntityAngle-2.0*pi) < Tolerance ) *EntityA
ngle = 0.0;//get another side data//get arc start-
angle//( direction : from circle-center to end-poi
nt )*EntityAngleAnother = ( Entity->AngEnd ) * pi
/ 180.0;//change angle to oppsite direction//( dir
ection : from end-point to circle-center )*EntityA
ngleAnother = *EntityAngleAnother + pi;//check ang
le if ( *EntityAngleAnother > 2.0*pi )*EntityAngle
Another = *EntityAngleAnother - 2.0 * pi;elseif (
fabs(*EntityAngleAnother-2.0*pi) < Tolerance ) *En
tityAngleAnother = 0.0;//compute tangentline angle
for the arc end-angle//( direction : from end-poi
nt to start-point )*EntityAngleAnother = *EntityAn
gleAnother + 0.5 * pi;//check angleif ( *EntityAng
leAnother > 2.0*pi )*EntityAngleAnother = *EntityA
ngleAnother - 2.0 * pi;else if ( fabs(*EntityAngle
Another-2.0*pi) < Tolerance )*EntityAngleAnother =
0.0;}else{//get arc end-angle//( direction : from
circle-center to end-point )RotateVertexFlag= 2;*E
ntityAngle= ( Entity->AngEnd ) * pi / 180.0;//chan
ge angle to oppsite direction//( direction: from e
nd-point to circle-center )*EntityAngle = *EntityA
ngle + 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//( directi
on : from end-point to start-point )*EntityAngle =
*EntityAngle + 0.5 * pi;if ( *EntityAngle > 2.0*p
i) *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->AngBegin ) * pi /
180.0;//change angle to oppsite direction//( direc
tion : from start-point to circle-center )*EntityA
ngleAnother = *EntityAngleAnother + pi;if ( *Entit
yAngleAnother > 2.0*pi )*EntityAngleAnother = *Ent
ityAngleAnother - 2.0 * pi;if ( fabs(*EntityAngleA
nother - 2.0*pi ) < Tolerance )*EntityAngleAnother
= 0.0;//compute tangentline angle for the arc sta
rt-angle//( direction : from start-point to end-po
int )*EntityAngleAnother = *EntityAngleAnother +
1.5 * pi;if ( *EntityAngleAnother > 2.0*pi )*Entit
yAngleAnother = *EntityAngleAnother - 2.0 *pi;if
( fabs(*EntityAngleAnother - 2.0*pi ) < Tolerance
)*EntityAngleAnother = 0.0;}//the end of this fun
ctionreturn RotateVertexFlag;}/*==================
===============================================関
数: 名称:F2dCleanUpLineAngle記述: It is a funct
ion for control how to compute aline typeentity’s
angle. 戻り値:RotateVertexFlag: direction flag=
1: vertex1 is rotate point=2: vertex2 is rotate po
intパラメータ:入力: 1 OriginVertex: rotationary
vertex2 Entity: line type entity 出力:1 EntityAng
le: direction angle ( radian )2 EntityAngleAnothe
r: another side direction angle===================
=============================================*/int
F2dCleanUpLineAngle(//inputstructplanar_vertex *O
riginVertex,structnode *Entity,//outputdouble*Enti
tyAngle,double*EntityAngleAnother){//return value
intRotateVertexFlag=0;//selected entity and temp e
ntitiesstruct planar_vertex*VertexTemp,*VertexAnot
herTemp;//length and angledoublediff_x = 0.0,diff_
y = 0.0,Tolerance = 0.0;//set toleranceTolerance =
F2dCleanUpTolerance;//select connected side of en
tityif ( Entity->vertex1== OriginVertex ){//get ve
rtex1->vertex2 RotateVertexFlag= 1;VertexTemp=Enti
ty->vertex1;VertexAnotherTemp= Entity->vertex2;}el
se{ //get vertex2->vertex1 RotateVertexFlag= 2;Ve
rtexTemp = Entity->vertex2;VertexAnotherTemp= Enti
ty->vertex1;}//compute angleif ( fabs( VertexTemp-
>X - VertexAnotherTemp->X ) < Tolerance ){//angle
= 0.5 * piif ( VertexTemp->Y < VertexAnotherTemp->
Y )*EntityAngle = 0.5 * pi;//angle = 1.5 * pielse*
EntityAngle = 1.5 * pi;}else{ //-pi< angle < pidi
ff_y = VertexAnotherTemp->Y- VertexTemp->Y;if ( fa
bs( diff_y ) > Tolerance ){diff_x = VertexAnotherT
emp->X - VertexTemp->X; *EntityAngle = atan2( di
ff_y, diff_x );//-pi< angle < 0.0if ( *EntityAngle
< 0.0 ) *EntityAngle = *EntityAngle + 2.0*pi; }el
se{ //angle = 0.0or piif ( VertexAnotherTemp->X >
VertexTemp->X )*EntityAngle = 0.0;else*EntityAngl
e = pi;}}if ( fabs(*EntityAngle - 2.0*pi) < Tolera
nce ) *EntityAngle = 0.0;//get another side angle*
EntityAngleAnother = *EntityAngle + pi;// check a
ngleif ( *EntityAngleAnother> ( 2.0 * pi ) ){*Enti
tyAngleAnother = *EntityAngleAnother - 2.0 * pi;}i
f ( fabs(*EntityAngleAnother - 2.0*pi) < Tolerance
) {*EntityAngleAnother = 0.0;}//the end of this f
unctionreturn RotateVertexFlag;}/*================
=================================================
関数: 名称:F2dCleanUpChangeColor 記述:
エンティティの色を変更する関数。戻り値:
=0:成功裏に完了 パラメータ: 入力:Ent
ities_change_color_list :変更された色であるノード
リスト============================================
=====================*/int F2dCleanUpChangeColor(s
truct node_list *Entities_change_color_list){//lin
k list and temp liststruct node_list*Color_temp_li
st;//selected entity and temp entitiesstruct node
*Next_entity;//entity’s specifitysCK_ENTATTatt
r;//specificity of entitiesint CountPrompt = 0;cha
rmessage[64];#ifdef VELLUMCountPrompt++;sprintf( m
essage,"Start Change Color Entity %d", CountPrompt
);ck_prompt( message ); #endif#ifdef VELLUM /
/ clear views highlighting ck_erase_level("VW_2
D");// ck_erase_level("VW_TRIM");#endif//check
all of entities on the listfor( Color_temp_list=En
tities_change_color_list; Color_temp_list; Color
_temp_list = Color_temp_list->cdr){if ( Color_temp
_list->car == NULL )break;Next_entity = Color_temp
_list->car;switch ( Next_entity->flags ){case 1:at
tr.color = CK_GREEN;ck_setattr( Next_entity->id, C
K_COLOR, NULL, &attr );break;case 3:attr.color =CK
_GRAY;ck_setattr( Next_entity->id, CK_COLOR, NULL,
&attr );break;case4:attr.color = CK_MAGENTA;ck_se
tattr( Next_entity->id, CK_COLOR, NULL, &attr );br
eak;}}#ifdef VELLUMCountPrompt++;sprintf( messag
e,"Finished change color Entity %d", CountPrompt
);ck_prompt( message ); #endifreturn0;}/*=======
==================================================
========関数: 名称: F2dCleanUpChangeDrawin
gColor 記述: エンティティの色を変更する関
数。 復帰値: =0:成功裏に完了; パラメー
タ:入力: 1 In drawing:図中で1:変
更された色である図================================
=================================*/intF2dCleanUpCh
angeDrawingColor(struct drawing *In_drawing){//ext
ern functionsvoid draw_entity();//selected entity
and temp entitiesstruct node *entity;int CountProm
pt = 0;charmessage[64];//entity’s specifitysCK_EN
TATTattr;//specificity of entities#ifdef VELLUM
// clear views highlighting ck_erase_level("V
W_2D");// ck_erase_level("VW_TRIM");CountPrompt
++;sprintf( message,"Start Change Color Sheet Enti
ty %d", CountPrompt);ck_prompt( message ); #endif
//check all of entities on the listfor( entity=In_
drawing->objects; entity; entity = entity->next)
{switch ( entity->flags ){#ifdef VELLUMcase 0:draw
_entity( entity, entity->color );break;case 1:draw
_entity( entity, CK_GREEN );break;case 2:draw_enti
ty( entity, entity->color );break;case 3:draw_enti
ty( entity, CK_BLUE );break;case 4: draw_entity( e
ntity, CK_MAGENTA );break;case 5:draw_entity( enti
ty, entity->color );break;case 6: draw_entity( ent
ity, CK_RED );break;case 7:draw_entity( entity, CK
_YELLOW );break;case 8:draw_entity( entity, entity
->color );break;case 9:draw_entity( entity, entity
->color );break;case 10:draw_entity( entity, CK_CY
AN );break;case 11:draw_entity( entity,entity->col
or );break; #endif #ifdef CKWINcase 1:attr.color =
CK_L_GREEN;ck_setattr( entity->id, CK_COLOR, NUL
L, &attr );break;case 3:attr.color = CK_L_GRAY;ck_
setattr( entity->id, CK_COLOR, NULL, &attr );brea
k;case4:attr.color = CK_MAGENTA;ck_setattr( entity
->id, CK_COLOR, NULL, &attr);break;case 6:attr.col
or = CK_L_RED;ck_setattr( entity->id, CK_COLOR,NUL
L, &attr );break;case 7:attr.color = CK_YELLOW;ck_
setattr( entity->id, CK_COLOR, NULL, &attr );brea
k;case 10:attr.color = CK_L_CYAN;ck_setattr( entit
y->id, CK_COLOR, NULL, &attr );break; #endif} if
( entity->next== NULL ) break;}#ifdef VELLUMCountP
rompt++;sprintf( message,"Finished change color Sh
eet Entity %d", CountPrompt );ck_prompt( message
); #endifreturn 0;}/*===========================
====================================== 関数: 名
称: F2dCleanUpUndoPre 記述: 取消関
数のためのデータフラグを準備すること。 復帰値:
=0:成功裏に完了;パラメータ: 入
力: 1 In drawing: 変更ステータスであ
る図。============================================
=====================*/int F2dCleanUpUndoPre(struc
t drawing *In_drawing){//selected entity and temp
entitiesstruct node *entity;//set flagF2dCleanUpEx
cutedNo = 2;//check all of entities on the listfor
( entity=In_drawing->objects; entity; entity = en
tity->next){entity->status = entity->flags;if ( en
tity->next == NULL )break;}return 0;}/*===========
==================================================
====関数: 名称: F2dCleanUpUndo記述: To undo. 戻
り値:= 0: Completed successfully;パラメータ:入
力: 1 In_drawing: drawing that will be undoed sta
tus===============================================
==================*/int F2dCleanUpUndo(struct draw
ing *In_drawing){//selected entity and temp entiti
esstruct node *entity;//flagint NoChangeFlag = 0;/
/checkflagif ( F2dCleanUpExcutedNo == 0 )return No
ChangeFlag;//check all of entities on the listfor
( entity=In_drawing->objects; entity; entity = en
tity->next){if ( entity->status != entity->flags )
{NoChangeFlag = 1;entity->flags = entity->status;}
if ( entity->next == NULL )break;} //check views f
lagif ( F2dCleanUpExcutedNo == 1 )In_drawing->view
s = NULL;//resetflag for viewsF2dCleanUpExcutedNo
= 0;return NoChangeFlag;}/*=======================
========================================== 関数:
名称:F2dCleanUpChangeDrawingFlag 記述:
エンティティのフラグを変更する関数。 復帰値:
=0:成功裏に完了; パラメータ: 入力:
1 In drawing: 変更された色である図===
==================================================
============*/int F2dCleanUpChangeDrawingFlag(stru
ct drawing *In_drawing){//selected entity and temp
entitiesstruct node *entity;int CountPrompt = 0;c
harmessage[64];#ifdef VELLUMCountPrompt++;sprintf
( message,"Start Flag Sheet Entity %d", CountPromp
t );ck_prompt( message ); #endif//check all of en
tities on the listfor( entity=In_drawing->objects;
entity; entity = entity->next){if ( entity->fla
gs== 4 ) entity->flags = 3;#ifdef VELLUM//CountPr
ompt++;//sprintf( message,"Flag Sheet Entity %d",
CountPrompt );//ck_prompt( message ); #endifif (
entity->next == NULL )break;}#ifdef VELLUMCountPro
mpt++;sprintf( message,"Finished Flag Sheet Entity
%d", CountPrompt );ck_prompt( message ); #endifr
eturn 0;}/*=======================================
========================== 関数: 名称: F2
dCleanUpFindSameColorEntity 記述: 同じ色のエ
ンティティを見出す。 復帰値: =0: 成功裏
に完了; パラメータ: 入力:
1 In entity: エンティティ2 In drawing: 変更され
た色である図======================================
==========================*/int F2dCleanUpFindSame
ColorEntity(struct node *In_entity,struct drawing
*In_drawing){//selected entity and temp entitiesst
ruct node *entity;int CountPrompt = 0;charmessage
[64];#ifdef VELLUMCountPrompt++;sprintf( message,"
Start Find same color Entity%d", CountPrompt );ck_
prompt( message ); #endif//check all of entitieso
n the listfor( entity=In_drawing->objects; entit
y; entity = entity->next){if ( entity->color == I
n_entity->color && entity->flags == 0) entity->fla
gs = 3;if ( entity->next == NULL )break;}#ifdef VE
LLUMCountPrompt++;sprintf( message,"Finished find
same color Entity %d", CountPrompt );ck_prompt( me
ssage ); #endifreturn 0;}/*======================
=========================================== 関
数: 名称: F2dCleanUpClearDrawingEntity 記
述: それは復帰エンティティの色である。 復帰
値:=0:成功裏に完了; パラメータ: 入
力: 1 In drawing: 変更された色である図
==================================================
============*/int F2dCleanUpClearDrawingEntity(str
uct drawing *In_drawing){//selected entity and tem
p entitiesstruct node *entity;//entity’sspecifity
sCK_ENTATTattr;//specificity of entitiesint CountP
rompt = 0;charmessage[64];#ifdef VELLUM // clea
r views highlighting ck_erase_level("VW_2D");//
ck_erase_level("VW_TRIM");//CountPrompt++;//sp
rintf(message,"Start Clear Entity %d", CountPrompt
);//ck_prompt( message );#endif//check all of ent
ities on the listfor( entity=In_drawing->objects;
entity; entity = entity->next){ if ( entity ==
NULL )break;switch (entity->flags ){case 0:case 1:
case 2:case 3:case 4:case 5:case 6:case 7:case 8:c
ase 9:case 10:entity->flags = 0;draw_entity( entit
y, entity->color );//attr.color = entity->color;//
ck_setattr( entity->id, CK_COLOR, NULL, &attr );de
fault:break;}}#ifdef VELLUM//CountPrompt++;//sprin
tf( message,"Finished clear Entity %d", CountPromp
t );//ck_prompt( message ); #endif//clear views c
onnectedIn_drawing->views = NULL;return 0;}/*=====
==================================================
========== 関数: 名称:F2dCleanUpClearDrawingKe
epFlags 記述: エンティティの色を復帰させる
が、フラグは保持する。復帰値: =0:成功裏に完
了; パラメータ: 入力:1 In drawing:変
更された色である図================================
=================================*/int F2dCleanUpC
learDrawingKeepFlags(structdrawing *In_drawing){//
selected entity and temp entitiesstruct node *enti
ty;//entity’s specifitysCK_ENTATTattr;//specifici
ty of entitiesint CountPrompt = 0;charmessage[64];
#ifdef VELLUM // clear views highlighting ck
_erase_level("VW_2D");#endif//check all of entitie
s on the listfor( entity=In_drawing->objects; ent
ity; 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 linedraw_en
tity( entity, entity->color);//attr.color = entity
->color;//ck_setattr( entity->id, CK_COLOR, NULL,&
attr );}if ( entity->next == NULL )break;}return
0;}/*=============================================
=================== 関数: 名称: F2dCleanUpD
eleteViews 記述: それは削除ビユーに対する関
数である。 復帰値: =0:成功裏に完了; パ
ラメータ: 入力: 1 Indrawing:図=
==================================================
==============*/int F2dCleanUpDeleteViews(struct d
rawing *In_drawing){//check drawingif ( In_drawing
== NULL )return 0; //delete views ( Not releas
e memory )In_drawing->views == NULL;return 0;}/*==
==================================================
============= 関数: 名称: F2dCleanUpDeleteD
rawingEntity 記述: それは削除エンティティに対
する関数である。復帰値: =0:成功裏に完了;
パラメータ: 入力:1 In drawing:図======
==================================================
=========*/int F2dCleanUpDeleteDrawingEntity(struc
t drawing *In_drawing){//selected entity and temp
entitiesstruct node *entity;struct group *Gp;//gro
upstruct node_list *ETL;//Entity Temp ListintCount
Prompt = 0;charmessage[64];#ifdef VELLUMCountPromp
t++;sprintf( message,"Start Delete Entity %d", Cou
ntPrompt );ck_prompt( message ); #endif//check al
l of entities on the listfor( entity=In_drawing->o
bjects; entity; entity = entity->next){if ( enti
ty->flags == 3 || entity->flags == 6 || entity->f
lags== 0 || entity->flags == 10 ){#ifdef CKWINck_d
elent( entity->id );#endif#ifdef VELLUM//
remove_entity ( entity, In_drawing );#endifen
tity->flags = 99;}if ( entity->next == NULL )brea
k;}if ( In_drawing->views == NULL )return 0;//unus
e group entitiesfor( Gp=In_drawing->views;Gp; Gp =
Gp->next){if ( Gp == NULL )break;if ( Gp->index !
= 0 )continue;for ( ETL = Gp->entities; ETL; ETL =
ETL->cdr ){#ifdef CKWINck_delent( ETL->car->id );
#endif#ifdef VELLUM // remove_entity ( E
TL->car,In_drawing );#endifETL->car->flags = 99; i
f ( ETL->cdr == NULL )break;}if ( Gp->next == NULL
)break;}#ifdef VELLUMCountPrompt++;sprintf( messa
ge,"Finished Delete Entity %d", CountPrompt );ck_p
rompt( message ); #endifreturn 0;}/*=============
==================================================
==関数: 名称: F2dCleanUpCheckEntityExist記述: c
heck an entity for current drawingif the entity is
not same to database, drawing was changed 戻り
値:= 0: No change;= 1: Changed;パラメータ:入力:
1 In_drawing: drawing ===========================
=====================================*/int F2dClea
nUpCheckEntityExist(struct drawing *In_drawing){//
selected entity and temp entitiesstruct node *enti
ty;//defineint ReturnCode = 0, etype = 0;doublex1=
0.0,y1=0.0,z1=0.0,x2=0.0,y2=0.0,z2=0.0,rad=0.0,ang
1=0.0,ang2=0.0;//entity’s specifitysCK_ENTATTatt
r;//specificity of entities//check all of entities
on the listif ( In_drawing->objects == NULL )retu
rn1;for( entity=In_drawing->objects; entity; ent
ity = entity->next){if ( entity->flags == 99 )cont
inue;ReturnCode = ck_getentid( entity->id, &etype
);if ( ReturnCode == CK_NO_ENT )return1;else{//ch
eck all ofentities on the listswitch ( entity->typ
e ){case CK_ARC:ck_getarc ( entity->id, &x1,&y1,&z
1, &rad,&ang1,&ang2, &attr );break; case CK_LIN
E: ck_getline( entity->id, &x1,&y1,&z1, &x2,&y2,&
z2, &attr );break;}if ( attr.level == 191 )return
0;elsereturn1;}if ( entity->next == NULL )break;}r
eturn 1;}/*=======================================
========================= 関数: 名称: F2dCl
eanUpChangeArrowVertexFlag 記述: アラウトッ
プ頂点フラグを変更し、アローセンタライン座標を設定
する。 復帰値:=0:成功裏に完了; パラメータ:
入力: 1 Flags:フラグ
2 TopVertex:アロートップ頂点 3 E
ntiry: アローセンタラインエンティティ===========
==================================================
====*/int F2dCleanUpChangeArrowVertexFlag(//inputi
nt *flags,structplanar_vertex *TopVertex,structnod
e *Entity){//set flagto arrow top vertexTopVertex-
>flags = *flags;//set arrow center line coordinate
sTopVertex->ArrowCenterLine_X1 = Entity->X1;TopVer
tex->ArrowCenterLine_Y1 = Entity->Y1;TopVertex->Ar
rowCenterLine_Z1 = Entity->Z1;TopVertex->ArrowCent
erLine_X2 = Entity->X2;TopVertex->ArrowCenterLine_
Y2 = Entity->Y2;TopVertex->ArrowCenterLine_Z2 = En
tity->Z2;//endreturn 0;}/*========================
========================================= 関数:
名称: F2dCleanUpFindArrowCenterEntity 記述:
アローセンタラインを見出し、フラグをアローメン
バに設定する。 復帰値: =0:アロー無し;
=1:アロー パラメータ: 入力:
1 Nodes:接続されたノード 2 TopVerte
x:アロートップ頂点 3 StartEntity:アロー
スタートラインエンティティ 4 EndEntity:
アローエンドラインエンティティ 5 CenterLi
neAngleTemp:アローセンタライン角度===============
==================================================
*/int F2dCleanUpFindArrowCenterEntity(//inputstruc
t node_list *Nodes,structplanar_vertex *TopVertex,
structnode *StartEntity,structnode *EndEntity,doub
le*CenterLineAngleTemp ){//external functionsint F
2dCleanUpLineAngle(); int F2dCleanUpChangeChildren
Flag();int F2dCleanUpChangeArrowVertexFlag();doubl
e F2dCleanUpLineLength();//nodesstructnode *Center
Entity;//linklist and temp liststruct node_list*te
mp_list;//flagsint ReturnFlag = 0,ArrowFlags = 3;
//doubledoubleCenterParentLength = 0.0,CenterParen
tAngle= 0.0,CenterParentAngleAnother = 0.0;doubleT
olerance = 0.0;//set valueTolerance = F2dCleanUpTo
lerance;// look for arrow center linefor( temp_lis
t = Nodes; temp_list; temp_list = temp_list->cdr)
{//check pointer addressif ( StartEntity == temp_l
ist->car || EndEntity == temp_list->car)continue;
//get new entityCenterEntity = temp_list->car;//ch
eck flags//if (CenterEntity->flags != 2 //&& Cen
terEntity->flags != 3 )continue; if( CenterEntity-
>type != CK_LINE )continue; if ( CenterEntity->li
ne_type!= StartEntity->line_type && CenterEntity->
color != StartEntity->color && CenterEntity->is_
thickness != StartEntity->is_thickness ) continue;
if ( CenterEntity->no_connected_1 < 2 && CenterE
ntity->no_connected_2 < 2 ) continue; //check l
engthCenterParentLength = F2dCleanUpLineLength( Ce
nterEntity->parent );if ( CenterParentLength < Tol
erance ) continue;//arrow central-entity angleF2dC
leanUpLineAngle(//inputTopVertex, CenterEntity->pa
rent,//output&CenterParentAngle, &CenterParentAngl
eAnother);//check the angle for central entity if
( fabs( CenterParentAngle - *CenterLineAngleTemp )
> Tolerance ) continue;// set flags for arrow’s
entitiesReturnFlag = 1;//look for arrow entity’s
childrenF2dCleanUpChangeChildrenFlag( StartEntity-
>parent );F2dCleanUpChangeChildrenFlag( EndEntity-
>parent );F2dCleanUpChangeChildrenFlag( CenterEnti
ty->parent );//set flag to arrow top vertexF2dClea
nUpChangeArrowVertexFlag( &ArrowFlags,TopVertex, C
enterEntity );return ReturnFlag;if ( temp_list->cd
r == NULL)break;}return ReturnFlag;}/* 関数: 名
称: F2dCleanUpFindArrowOneSideOpenEntity 記
述: 1つのサイドオープンエンティティを見出す。
復帰値: =0: ノーオープン; =1: オー
プン =2: オープンパラメータ: 入力:
1 Nodes:接続されたノード=================
===============================================*/i
nt F2dCleanUpFindArrowOneSideOpenEntity( struct no
de_list *Nodes ){//link list and temp liststruct n
ode_list*temp_list;//entities counter and flagsint
open_entity_flag = 0;//startfor( temp_list = Node
s; temp_list; temp_list = temp_list->cdr){//ckec
k another side connected’s counterif ( temp_list-
>car->no_connected_1 == 0 && temp_list->car->no_co
nnected_2 > 1 ){open_entity_flag = 1;break;}if ( t
emp_list->car->no_connected_2 == 0 && temp_list->c
ar->no_connected_1 > 1 ){open_entity_flag = 2;brea
k;}if ( temp_list->cdr== NULL )break;}return open_
entity_flag;}/*===================================
============================== 関数: 名称:
F2dClaenUpCheckStartEndEntity 記述: 開始およ
び終了エンティティをチェックする 復帰値:
=0: ノーアロー;= 1: goodパラメータ:入力: 1
StartEntity: アロー開始ラインエンティティ2 EndEnti
ty: アロー終了ラインエンティティ==================
===============================================*/i
nt F2dCleanUpCheckStartEndEntity(//inputstructnode
*StartEntity,structnode *EndEntity ){//external f
unctionsdouble F2dCleanUpLineLength();//doubledoub
learrow_start_parent_length = 0.0,arrow_end_parent
_length = 0.0,arrow_tolerance = 0.0;//set toleranc
earrow_tolerance = F2dCleanUpTolerance;//start//co
mpute entities’ parent lengtharrow_start_parent_l
ength = F2dCleanUpLineLength( StartEntity );arrow_
end_parent_length = F2dCleanUpLineLength( EndEnt
ity );//check lengthif ( arrow_start_parent_length
< arrow_tolerance )return 0; if ( arrow_end_paren
t_length < arrow_tolerance )return 0; //check tloe
ranceif ( fabs( arrow_start_parent_length - arrow_
end_parent_length )> arrow_tolerance )return 0; /
/check angle:if entitiesare parallel, STOPif (sqrt
(fabs((( StartEntity->X1 - StartEntity->X2 )* ( En
dEntity->Y1 - EndEntity->Y2 )) -(( EndEntity-
>X1 - EndEntity->X2 ) * ( StartEntity->Y1 - S
tartEntity->Y2 ))))< arrow_tolerance )return 0;//n
ormal endreturn 1;}/*=============================
===================================関数: 名称: F
2dCleanUpComputeCenterLineAngle記述: センタライン
角度を計算する。戻り値:= 0: ノーアロー;= 1: 良好
パラメータ:入力: 1 TopVertex: アロートップ頂点2
StartEntity: アロー開始ラインエンティティ 3 EndEnt
ity: アロー終了ラインエンティティ出力:1 CenterLin
eAngle: アローセンターライン角度 ================
================================================*/
int F2dCleanUpComputeCenterLineAngle(//inputstruct
planar_vertex *TopVertex,structnode *StartEntity,s
tructnode*EndEntity,//outputdouble*CenterLineAngle
){//external functionsint F2dCleanUpLineAngle();/
/entities counter and flagsint ReturnFlag = 0;//do
ubledoublearrow_start_parent_angle = 0.0,arrow_end
_parent_angle = 0.0,arrow_center_diff_angle = 0.0,
RotateAxisAngleAnotherTemp = 0.0,arrow_center_pare
nt_angle_temp = 0.0,arrow_tolerance = 0.0;//set to
lerancearrow_tolerance = F2dCleanUpTolerance;//sta
rt// compute central angle of arrow////angle_cente
r = 0.5 * ( angle_start + angle_end )//atan2 retur
ns the arctangent of y/x//atan2 returns a value in
the range -pi to pi radians//getarrow start angle
F2dCleanUpLineAngle(//inputTopVertex, StartEntity,
//output&arrow_start_parent_angle, &RotateAxisAngl
eAnotherTemp);//arrow end angleF2dCleanUpLineAngle
(//inputTopVertex, EndEntity,//output&arrow_end_pa
rent_angle, &RotateAxisAngleAnotherTemp);//get dif
ference anglearrow_center_diff_angle = fabs( arrow
_end_parent_angle - arrow_start_parent_angle );/
/same angleif ( arrow_center_diff_angle < arrow_to
lerance )return0;if ( arrow_center_diff_angle < pi
){//diff < piarrow_center_parent_angle_temp = 0.5
* (arrow_end_parent_angle + arrow_start_parent_an
gle );}else{//diff > pi ( take opposite angle ) ar
row_center_parent_angle_temp =0.5 * (arrow_end_par
ent_angle + arrow_start_parent_angle ) + pi;//angl
e> 2*piif ( fabs ( arrow_center_parent_angle_temp
- 2.0 * pi )< arrow_tolerance ){arrow_center_paren
t_angle_temp = 0.0;}else{if ( arrow_center_parent_
angle_temp > ( 2.0 * pi ) ){arrow_center_parent_an
gle_temp = arrow_center_parent_angle_temp - 2.0 *
pi;}}}*CenterLineAngle = arrow_center_parent_angle
_temp;//normal endreturn 1;}/*====================
=============================================関
数: 名称: F2dCleanUpFindArrowEndEntity記述: ア
ロー終了ラインを見出す戻り値:= 0: ノーアロー;= 1:
アローパラメータ:入力: 1 Nodes: 接続ノード2 Top
Vertex: アロートップ頂点3 StartEntity: アロー開始
エンティティ======================================
==========================*/int F2dCleanUpFindArro
wEndEntity(//inputstructnode_list *Nodes,structpla
nar_vertex *TopVertex,structnode *StartEntity){//e
xternal functionsint F2dCleanUpFindArrowOneSideOpe
nEntity();int F2dCleanUpComputeCenterLineAngle();i
nt F2dCleanUpCheckStartEndEntity();intF2dCleanUpFi
ndArrowCenterEntity();//link list and temp liststr
uct node_list*temp_list; //selected entity and tem
p entitiesstruct node *Next_entity,*arrow_start_en
tity_parent,*arrow_end_entity,*arrow_end_entity_pa
rent;//entities counter and flagsint assistant_lin
e_flag = 0,ReturnFlag = 0;//doubledoublearrow_cent
er_parent_angle_temp = 0.0;//startfor( temp_list=N
odes; temp_list; temp_list = temp_list->cdr){ i
f ( temp_list->car== NULL )break;Next_entity = tem
p_list->car;arrow_end_entity = temp_list->car;//if
( Next_entity->flags != 2 )continue;if ( Next_ent
ity->type !=CK_LINE )continue;if ( Next_entity->li
ne_type != StartEntity->line_type)continue;if ( Ne
xt_entity->color != StartEntity->color )continue;i
f (Next_entity->is_thickness != StartEntity->is_th
ickness )continue; //set parentarrow_start_entit
y_parent = StartEntity->parent; arrow_end_entity_p
arent = Next_entity->parent; //look for broken e
ntity’s another side ReturnFlag = F2dCleanUpFindA
rrowOneSideOpenEntity( arrow_end_entity_parent->ch
ildren ); if ( ReturnFlag == 0 )continue;//check p
arents entitiesReturnFlag = F2dCleanUpCheckStartEn
dEntity( //inputarrow_start_entity_parent, arrow_
end_entity_parent );if ( ReturnFlag == 0 )continu
e;// look for central entityof arrowReturnFlag = F
2dCleanUpComputeCenterLineAngle(//inputTopVertex,
arrow_start_entity_parent, arrow_end_entity_paren
t,//output&arrow_center_parent_angle_temp );if ( R
eturnFlag == 0 )continue;// get central entity of
arrowassistant_line_flag = F2dCleanUpFindArrowCent
erEntity(//inputNodes, TopVertex, StartEntity, arr
ow_end_entity, &arrow_center_parent_angle_temp );r
eturn assistant_line_flag;}return assistant_line_f
lag;}/*===========================================
======================関数: 名称: F2dCleanUpChan
geChildrenFlag記述: エンティティのチルドレンフラ
グを変更する関数戻り値:= 0: 成功裏に完了;パラメー
タ:入力: =======================================
==========================*/int F2dCleanUpChangeCh
ildrenFlag(struct node *Entity){//temp liststruct
node_list*Temp_list;//check all of children of the
entityfor( Temp_list=Entity->children; Temp_lis
t; Temp_list = Temp_list->cdr){//change flag to l
ight grayTemp_list->car->flags = 3; if ( Temp_list
->cdr == NULL )break;}return 0;}/*================
=================================================
関数: 名称: F2dCleanUpLineLength記述: ライン形
エンティティの長さを計算する関数 戻り値:= 長さ;パ
ラメータ:入力: エンティティ: ペアレントエンティ
ティ==============================================
==================*/double F2dCleanUpLineLength(st
ruct node *Entity){//definationdoubleEntityLength=
0.0;//compute entities’ parent lengthEntityLength
=sqrt( ( Entity->X1 - Entity->X2 ) * ( Entity->X
1 - Entity->X2 )+ ( Entity->Y1 - Entity->Y2 ) *( E
ntity->Y1 - Entity->Y2 ));returnEntityLength;}/*==
==================================================
=============関数: 名称: F2dCleanUpFindArrow記
述: アロー型エンティティを求め、フラグをそれらに
設定する。 戻り値:= 0: 成功裏に完了;パラメータ:
入力: 1 Entities_list: チェックされるノードリスト
==================================================
==============*/int F2dCleanUpFindArrow( struct no
de_list *Entities_list ){//external functionsint F
2dCleanUpLineAngle();int F2dCleanUpFindArrowEndEnt
ity(); //link list and temp liststruct node_list*t
emp_nodes1,*arrow_list,*temp_list; //selected enti
ty and temp entitiesstruct node *Next_entity;struc
t planar_vertex*top_vertex;//entities counter and
flagsint bug_flag = 0,ReturnFlag = 0,assistant_lin
e_flag = 0;int CountPrompt = 0;charmessage[64];#if
def VELLUMCountPrompt++;sprintf( message,"Start Fi
nd Arrow Entity %d", CountPrompt );ck_prompt( mess
age ); #endif// Step_1:look for one side open ent
ity//arrow start entityfor( temp_list=Entities_lis
t; temp_list; temp_list = temp_list->cdr){Next_e
ntity =temp_list->car;//if ( Next_entity->flags !=
2 ) continue;if ( Next_entity->type != CK_LINE )
continue;if ( Next_entity->no_connected_1 == 0&&N
ext_entity->no_connected_2 < 2 ) continue;if ( Ne
xt_entity->no_connected_1 < 2&& Next_entity->no
_connected_2 == 0 ) continue; //selectentity’
s sideif ( Next_entity->no_connected_1 == 0 ){// c
lear bug_flagbug_flag = 0;//look for broken entit
y’s another side for( arrow_list = Next_entity->p
arent->children; arrow_list; arrow_list = arrow_
list->cdr){//ckeck another side vertex’s pointeri
f ( Next_entity->parent->vertex2 == arrow_list->c
ar->vertex2 ){ bug_flag = 1; break;}if ( arrow_l
ist->cdr == NULL )break;}if ( bug_flag == 1 ){top_
vertex = Next_entity->parent->vertex2;temp_nodes1
= arrow_list->car->connected_nodes_2;}}else{//clea
r bug_flagbug_flag = 0;//look for broken entity’s
another side for(arrow_list = Next_entity->parent
->children; arrow_list; arrow_list =arrow_list->
cdr){//ckeck another side vertex’s pointerif ( Ne
xt_entity->parent->vertex1 == arrow_list->car->ve
rtex1 ){ bug_flag = 1; break;}if ( arrow_list->c
dr == NULL )break;}if ( bug_flag == 1 ){top_vertex
= Next_entity->parent->vertex1;temp_nodes1 = arro
w_list->car->connected_nodes_1;}}if ( bug_flag !=
1 ) continue;// get end entity of arrowReturnF
lag = F2dCleanUpFindArrowEndEntity(//inputtemp_nod
es1, top_vertex, Next_entity );if ( ReturnFlag ==
1 )assistant_line_flag = 1;if ( temp_list->cdr ==
NULL )break;}#ifdef VELLUMCountPrompt++;sprintf( m
essage,"Finished find arrows Entity %d", CountProm
pt );ck_prompt( message ); #endifreturnassistant_
line_flag;}/*=====================================
============================関数: 名称: F2dClean
UpFindOneSideOpenEntity記述:look for one side ope
n entities and they are vertical with arrow type e
ntities. 戻り値:= 0: Completed successfully and N
o found;= NUM: Open entities’ numberパラメータ:
入力: 1 Entities_list: a node list that willbe
checked=================
=========================
======================*/i
nt F2dCleanUpFindOneSideO
penEntity( struct node_li
st *Entities_list){//exte
rnal functionsint F2dClea
nUpChangeChildrenFlag();/
/link list and temp lists
truct node_list *temp_lis
t; //selected entity and
temp entitiesstruct node
*Next_entity;//entities c
ounter and flagsint count
= 0;//doubledoubleassist
ant_line_angle = 0.0,arro
w_tolerance = 0.0;int Cou
ntPrompt = 0;charmessage
[64];//set tolerancearrow
_tolerance = F2dCleanUpTo
lerance;#ifdef VELLUMCoun
tPrompt++;sprintf( messag
e,”Start Find One side op
en Entity %d”, CountPromp
t );ck_prompt( message );
#endif // checkall of entities which connecte
d with outside loop for( temp_list=Entities_lis
t; temp_list; temp_list = temp_list->cdr){ if (
temp_list->car== NULL )break;Next_entity = temp_li
st->car;//check flags//if ( Next_entity->flags !=2
)continue;//check vertex’ flagif ( Next_entity->
vertex1->flags != 3 && Next_entity->vertex2->flags
!= 3 )continue;//check linesverticallyif ( Next_e
ntity->vertex1->flags == 3 ){assistant_line_angle=
fabs ( ( Next_entity->X1 - Next_entity->X2 )*
(Next_entity->vertex1->ArrowCenterLine_X1 - Ne
xt_entity->vertex1->ArrowCenterLine_X2 ) + (Next_e
ntity->Y1 - Next_entity->Y2 ) * (Next_entity->vert
ex1->ArrowCenterLine_Y1 - Next_entity->vertex1
->ArrowCenterLine_Y2 ) );}else{assistant_line_angl
e = fabs ( ( Next_entity->X1 - Next_entity->X2 )
* (Next_entity->vertex2->ArrowCenterLine_X1 -
Next_entity->vertex2->ArrowCenterLine_X2 ) + ( Nex
t_entity->Y1 - Next_entity->Y2 ) * (Next_entity->v
ertex2->ArrowCenterLine_Y1 - Next_entity->vert
ex2->ArrowCenterLine_Y2 ));}//check the angle for
central entity if ( sqrt(assistant_line_angle)> ar
row_tolerance ) continue;//look for childrenF2dCle
anUpChangeChildrenFlag( Next_entity->parent );coun
t++;}#ifdef VELLUMCountPrompt++;sprintf( message,"
Finished find one side open Entity %d", CountPromp
t );ck_prompt( message ); #endif//normal endretur
n count;}/*=======================================
==========================関数: 名称: F2dCleanUp
FindOneSideOpenEntity2記述: ビユーを見出した後に
一側がオープンのエンティティとビユーの境界を横切る
エンティティを見出す。戻り値:= 0: 成功裏に完了
し、何も見出されない;= NUM: オープンエンティティの
個数パラメータ:入力: 1In_drawing: 図============
==================================================
==*/int F2dCleanUpFindOneSideOpenEntity2( struct d
rawing *In_drawing ){//external functionsint F2dCl
eanUpChangeChildrenFlag();//link list and temp lis
tstruct node_list *temp_list, *ConnectedNode; //se
lected entity and temp entitiesstruct node *Entit
y;//define flagintBoundaryFlag = 0; int CountPromp
t = 0;charmessage[64];#ifdef VELLUMCountPrompt++;s
printf( message,"2 Start Find Oneside Open Entity
%d", CountPrompt );ck_prompt( message ); #endif
//check node listif ( In_drawing == NULL )retur
n-1;if ( In_drawing->objects == NULL )return-1;
// check all of entities which connected with ou
tside loop for( Entity=In_drawing->objects;Enti
ty;Entity = Entity->next ){//check connected nodes
countif ( Entity== NULL )break;if (( Entity->no_c
onnected_1 == 0 ) &&( Entity->no_connected_2 == 0
))continue;//check flagsif (( Entity->flags == 3
) &&( Entity->type == CK_LINE ) &&(( Entity->no_
connected_1 == 0 ) ||( Entity->no_connected_2 ==
0 ))){//one side open and line typeif ( Entity->n
o_connected_2 == 0 ) ConnectedNode = Entity->co
nnected_nodes_1;else ConnectedNode = Entity->conne
cted_nodes_2;//clear found boundary’s flagBoundar
yFlag = 0;//check across with views’ boundaryif
( ConnectedNode != NULL){for ( temp_list = Connect
edNode; temp_list;temp_list = temp_list->cdr){//ch
eck wrong dataif ( temp_list->car == NULL )break;i
f ( temp_list->car->flags == 4 ){//find boundary’
s entityBoundaryFlag = 1;break;}if (temp_list->cdr
== NULL )break;}if ( BoundaryFlag == 1 ) //look
for children F2dCleanUpChangeChildrenFlag( Entity-
>parent );}}//check arc if ((Entity->type == CK_AR
C ) &&( Entity->flags != 99 ) &&(( Entity->no_co
nnected_1 == 0 ) ||( Entity->no_connected_2 == 0
))){//look for childrenF2dCleanUpChangeChildrenFl
ag( Entity->parent );}if ( Entity->next == NULL )b
reak;}#ifdef VELLUMCountPrompt++;sprintf( messag
e,"Finished 2 one side open Entity %d", CountPromp
t );ck_prompt( message ); #endif//normalendreturn
0;}/*============================================
====================関数: 名称: F2dCleanUpFindGr
oupMinX記述: エンティティグループに対する最小X値
を求める。戻り値:= 0: 成功裏に完了し、エンティテ
ィ無し;パラメータ:入力: 1 Entities_list: チェッ
クされるノードリスト出力:1 Entity: エンティティ
は最小のX値を含む。==============================
==================================*/struct node *F
2dCleanUpFindGroupMinX( struct node_list *Entities
_list ){//double F2dCleanUpLineLength();//entities
counter and flagsint open_entity_flag = 0;//link
list and temp liststruct node_list*EntitiesList2,*
Out_temp_list2,*open_temp_list2, *open_list2, *tem
p_list1, *temp_list2; //selected entity and temp e
ntitiesstructnode *Next_entity, *MinXvalueEntity;
//length and angledoubleMinXvalueGroup = 0.0;//che
ck all of entities which connected with outside lo
op//initializeEntitiesList2 =( struct node_list *
) calloc ( 1, sizeof ( struct node_list ));open_l
ist2 = ( struct node_list * ) calloc ( 1, sizeof
(struct node_list ));//check first entity//search
connected entity untilreal entity be foundfor ( te
mp_list2 = Entities_list;//entity->connected_node
s; ( temp_list2!=0 && temp_list2->car!=0
); temp_list2=temp_list2->cdr){if ( temp_lis
t2->car == NULL )break;if ( temp_list2->car->no_co
nnected_1 == 0 ) continue;if ( temp_list2->car->no
_connected_2== 0 ) continue;if ( temp_list2->car->
flags == 2 ){//set pointer to first entityopen_lis
t2->car = temp_list2->car;//set minimum X valueMin
XvalueGroup = temp_list2->car->Min_X;MinXvalueEnti
ty = temp_list2->car;break;}if ( temp_list2->cdr =
= NULL )break;}if ( open_list2->car == 0 )return
0;//set link addressopen_list2->cdr = NULL;//set t
he pointer to output node listEntitiesList2->car =
open_list2->car;EntitiesList2->cdr = open_list2->
cdr;////Step_6_1://find connected entitiesfor ( te
mp_list1 = open_list2; ( temp_list1 //&
&(temp_list->cdr != 0) ); ) {//get a poin
ter from open listif ( temp_list1->car == NULL )br
eak;Next_entity = temp_list1->car;//set a closed f
lag to the node//Next_entity->flags = 1;//close th
e node ( delete the node from open list )open_list
2 = open_list2->cdr;// look for first connected en
tity whose flags=0.for ( temp_list2 = Next_entity-
>connected_nodes; ( temp_list2!=0 && temp_
list2->car!=0 ); temp_list2=temp_list2->cdr)
{ if ( temp_list2->car == NULL ) break;// if f
ound an unmarked connected entityif ( temp_list2 &
& temp_list2->car->flags==2&& MinXvalueEntity->lin
e_type == temp_list2->car->line_type&& MinXvalueEn
tity->color == temp_list2->car->color&& MinXvalueE
ntity->is_thickness == temp_list2->car->is_thickne
ss ){//check minimum Xif ( temp_list2->car->M
in_X < MinXvalueGroup ){//change minimum X valueMi
nXvalueGroup = temp_list2->car->Min_X;MinXvalueEn
tity = temp_list2->car; }// allocate memory for op
en list elementopen_temp_list2 = ( struct node_lis
t * ) calloc ( 1, sizeof ( struct node_list ));//
allocate memory for output node list elementOut_te
mp_list2 = ( structnode_list * ) calloc ( 1, sizeo
f ( struct node_list ));// add this entity to the
open listopen_temp_list2->car = temp_list2->car;//
add this entity to the output node list Out_temp_
list2->car = temp_list2->car;//seta open flagto th
e nodeopen_temp_list2->car->flags = 1; // connect
to the open listopen_temp_list2->cdr = open_list2;
// move the pointer of openlist to the topopen_lis
t2 = open_temp_list2;// connect to the output node
listOut_temp_list2->cdr = EntitiesList2;// move t
he pointer of outputnode list to the topEntitiesLi
st2 = Out_temp_list2;}if ( temp_list2->cdr == NULL
)break;}// assign value to the loop variabletemp_
list1 = open_list2;}return MinXvalueEntity;}/*====
==================================================
===========関数: 名称: F2dCleanUpFindOutNextEnti
ty記述: アウトサイドループエンティティに接続され
たエンティティを求める。戻り値:= 0: 成功裏に完了;
パラメータ:入力: 1 In_entity: 軸エンティティを回
転 2 In_Nodes: エンティティのノード3 In_Vertex:
エンティティの頂点4 *In_Angle: エンティティの角度=
==================================================
=============*/int F2dCleanUpFindOutNextEntity(//i
nput struct node*In_entity,struct node_list *In_No
des, struct planar_vertex *In_Vertex,double *In_An
gle){//external functionsint F2dCleanUpArcAngle();
int F2dCleanUpLineAngle();//link list and temp li
ststruct node_list*temp_list, *RotateNodes,*Rotate
NodesTemp,*RotateNodesAnother,*RotateNodesAnotherT
emp;//selected entity and temp entitiesstruct node
*Next_entity, *RotateEntity;struct planar_vertex
*RotateVertex,*RotateVertexTemp,*RotateVertexAnoth
er,*RotateVertexAnotherTemp;int RotateVertexFlag =
0,RotateAxisEntityType = 0,RotateAxisEntityVertex
Flag = 0,FindNextFlag = 0;//length and angledouble
RotateAxisAngleAnother = 0.0,RotateAxisAngleAnothe
rTemp = 0.0,RotateMinAngleTemp = 0.0,RotateDiffAng
leTemp = 0.0,RotateAxisAngle = 0.0,RotateAxisAngle
Temp = 0.0;//set tolerance TolerancedoubleToleranc
e = 0.0;Tolerance = F2dCleanUpTolerance;//initial
izeRotateAxisAngleAnother= *In_Angle;RotateEntity=
In_entity;RotateNodesAnother= In_Nodes;RotateVert
exAnother= In_Vertex;//check all of entities which
connected with outside loopfor( ; ; ){//set flag
for first entity on loopFindNextFlag = 0;RotateE
ntity->flags= 4;RotateAxisEntityType = RotateEntit
y->type;if ( RotateEntity->vertex1 == RotateVertex
Another )RotateAxisEntityVertexFlag = 1;else Rotat
eAxisEntityVertexFlag = 2;//set standard axis for
first searchRotateAxisAngle = RotateAxisAngleAnoth
er;RotateMinAngleTemp= 2.0 * pi;RotateNodes= Rotat
eNodesAnother;RotateVertex= RotateVertexAnother;
//check next connected entityif ( RotateNodes ==
0 )break;//start loop processfor( temp_list=Rotat
eNodes; temp_list; temp_list = temp_list->cdr){i
f ( temp_list->car == NULL )break;Next_entity = te
mp_list->car;//checkflagsif ( Next_entity->flags =
= 4 )break;if ( Next_entity->flags != 1 )continue;
switch ( Next_entity->type ){//arc type entitycas
eCK_ARC:RotateVertexFlag = F2dCleanUpArcAngle(//in
putRotateVertex, Next_entity,//output&RotateAxisAn
gleTemp, &RotateAxisAngleAnotherTemp);break;//line
typeentitycaseCK_LINE:Rota
teVertexFlag = F2dCleanUp
LineAngle(//inputRotateVe
rtex, Next_entity,//outpu
t&RotateAxisAngleTemp, &R
otateAxisAngleAnotherTem
p);break;//wrong type ent
itydefault:break;}//selec
t connected side ofentity
if ( RotateVertexFlag ==
1 ){//get start−>end //se
t rotation vertex nodeRot
ateNodesTemp = Next_entit
y−>connected_nodes_1;Rota
teVertexTemp=Next_entity−
>vertex1;//set another si
de vertex nodeRotateNodes
AnotherTemp = Next_entity
−>connected_nodes_2;Rotat
eVertexAnotherTemp= Next_
entity−>vertex2;}else{//s
et rotation vertex nodeRo
tateNodesTemp = Next_enti
ty−>connected_nodes_2;Rot
ateVertexTemp = Next_enti
ty−>vertex2;//set another
side vertex nodeRotateNod
esAnotherTemp = Next_enti
ty−>connected_nodes_1;Rot
ateVertexAnotherTemp= Nex
t_entity−>vertex1;}//comp
ute diff angle//for chang
e current entityRotateDif
fAngleTemp = RotateAxisAn
gleTemp − RotateAxisAngl
e;if ( fabs( RotateDiffAn
gleTemp ) < Tolerance )
{switch( RotateAxisEntity
Type ){caseCK_ARC:switch
( RotateAxisEntityVertexF
lag ){case1:RotateDiffAng
leTemp = 2.0 * pi;break;c
ase2:RotateDiffAngleTemp
= 0.0;break;}break;caseCK
_LINE:switch( RotateVerte
xFlag ){case1:RotateDiffA
ngleTemp = 0.0;break;case
2:RotateDiffAngleTemp =
2.0 * pi;break;}break;}}i
f (RotateDiffAngleTemp <
0.0 ){RotateDiffAngleTemp
= RotateDiffAngleTemp +
2.0 * pi;}if ( fabs( Rota
teDiffAngleTemp − RotateM
inAngleTemp ) < Tolerance
) {switch( Next_entity−>
type ){caseCK_ARC:switch
( RotateEntity−>type){cas
eCK_ARC:switch( RotateVer
texFlag ){case1://no chan
gebreak;case2:RotateEntit
y= Next_entity;RotateNode
s = RotateNodesTemp;RotateVertex= RotateVertexT
emp;RotateNodesAnother = RotateNodesAnotherTemp;Ro
tateVertexAnother = RotateVertexAnotherTemp;Rotate
AxisAngleAnother = RotateAxisAngleAnotherTemp;brea
k;}break;caseCK_LINE:switch( RotateVertexFlag ){ca
se1://no changebreak;case2:RotateEntity= Next_enti
ty;RotateNodes = RotateNodesTemp;RotateVertex= R
otateVertexTemp;RotateNodesAnother = RotateNodesAn
otherTemp;RotateVertexAnother = RotateVertexAnothe
rTemp;RotateAxisAngleAnother = RotateAxisAngleAnot
herTemp;break;}break;}caseCK_LINE:switch( Rota
teEntity−>type ){caseCK_A
RC:if ( RotateEntity−>ver
tex1 == RotateVertex ){Ro
tateEntity= Next_entity;R
otateNodes = RotateNodesTemp;RotateVer
tex= RotateVertexTemp;RotateNodesAnother = RotateN
odesAnotherTemp;RotateVertexAnother = RotateVertex
AnotherTemp;RotateAxisAngleAnother = RotateAxisAng
leAnotherTemp;}break;}}}if ( RotateDiffAngleTemp <
RotateMinAngleTemp ){FindNextFlag = 1;RotateMinAn
gleTemp = RotateDiffAngleTemp;//set rotation entit
yRotateEntity= Next_entity;RotateNodes = RotateN
odesTemp;RotateVertex= RotateVertexTemp;RotateNode
sAnother = RotateNodesAnotherTemp;RotateVertexAnot
her = RotateVertexAnotherTemp;RotateAxisAngleAnoth
er =RotateAxisAngleAnotherTemp;}}//check flags//if
loop meet closed entity if ( Next_entity->flags =
= 4 )break;if ( FindNextFlag == 0 ) break;}return
0;}/*=============================================
====================関数: 名称: F2dCleanUpFindOu
tSideLoop記述: アウトサイドループエンティティを求
める。戻り値:= 0: アウトサイドループエンティティ
を求める。;= NUM: アウトサイドエンティティの個数パ
ラメータ:入力: 1 Entity: エンティティはループの
最小X値を含む。==================================
==============================*/int F2dCleanUpFind
OutSideLoop( struct node *MinXvalueEntity ){//exte
rnal functionsint F2dCleanUpArcAngle(); int F2dCle
anUpLineAngle();int F2dCleanUpFindOutFirstEntit
y();int F2dCleanUpFindOutNextEntity(); //entities
counter and flagsint count = 0,count2 = 0,open_ent
ity_flag = 0,RotateVertexFlag = 0,assistant_line_f
lag = 0;//link list and temp liststruct node_list*
outside_loop_temp_list3, *RotateNodes,*RotateNodes
Temp,*RotateNodesAnother,*RotateNodesAnotherTemp;/
/selected entity and temp entitiesstruct node *Ne
xt_entity, *RotateEntity;struct planar_vertex*Rota
teVertex,*RotateVertexTemp,*RotateVertexAnother,*R
otateVertexAnotherTemp;//length and angledoubleass
istant_line_angle = 0.0,MinXvalueGroup = 0.0,Rotat
eAxisAngleAnother = 0.0,RotateAxisAngleAnotherTemp
=0.0,RotateMinAngleTemp = 0.0,RotateDiffAngle =
0.0,RotateDiffAngleTemp =0.0,RotateAxisAngle = 0.
0,RotateAxisAngleTemp = 0.0;//set tolerance Tolera
ncedoubleloop_tolerance = 0.00;loop_tolerance = F
2dCleanUpTolerance;//loop direction : counter-cloc
k//check a flag for outside loop process//if ( cou
nt2 > 0 ){//step_7_1:find first entity for the gro
up//set standard axis for first searchRotateAxisAn
gle = 1.5 * pi;RotateMinAngleTemp=2.0 * pi;//step_
7_1_1: only one entity//check entities’ angle//ar
c case: special case ( no vertex on min_x )if ( Mi
nXvalueEntity->type == CK_ARC && ( fabs ( MinXval
ueEntity->Min_X - MinXvalueEntity->vertex1->X ) >l
oop_tolerance ) && ( fabs ( MinXvalueEntity->Min_X
- MinXvalueEntity->vertex2->X ) > loop_tolerance
) ){//set rotation vertex nodeRotateNodesAnother
= MinXvalueEntity->connected_nodes_2;RotateVertexA
nother = MinXvalueEntity->vertex2;RotateEntity= Mi
nXvalueEntity;//get arc end-angle //(direction : f
rom circle-center to end-point )RotateAxisAngleAno
therTemp= ( MinXvalueEntity->AngEnd ) * pi / 180.
0;//change angle to oppsite direction//( direction
: from end-point to circle-center )RotateAxisAngl
eAnotherTemp = RotateAxisAngleAnotherTemp + pi;//c
heck angle if ( RotateAxisAngleAnotherTemp > ( 2.0
* pi )){ RotateAxisAngleAnotherTemp = RotateAxisA
ngleAnotherTemp - 2.0 * pi;}if ( fabs ( RotateAxis
AngleAnotherTemp -( 2.0 * pi )) < loop_tolerance )
{RotateAxisAngleAnotherTemp = 0.0;}//compute tange
ntline angle for the arc end-angle//( direction :
from end-point to start-point )RotateAxisAngleAnot
herTemp = RotateAxisAngleAnotherTemp + 0.5 * pi;//
check angle if ( RotateAxisAngleAnotherTemp > ( 2.
0 * pi )){ RotateAxisAngleAnotherTemp = RotateAxis
AngleAnotherTemp - 2.0 * pi;}if ( fabs ( RotateAxi
sAngleAnotherTemp - ( 2.0 * pi )) < loop_tolerance
){RotateAxisAngleAnotherTemp = 0.0;}//set rotatio
n standard angle ( clock direction )RotateAxisAngl
eAnother = RotateAxisAngleAnotherTemp;}//step_7_1_
2: multiple entities around Min_xelse{//select con
nected side ofentityif ( fabs ( MinXvalueEntity->M
in_X - MinXvalueEntity->vertex1->X )< loop_toleran
ce )//get start->end //set rotation vertex nodeRot
ateVertex= MinXvalueEntity->vertex1;elseRotateVert
ex= MinXvalueEntity->vertex2;switch ( M
inXvalueEntity−>type ){//
arc type entitycaseCK_ARC:RotateVertexFlag = F
2dCleanUpArcAngle(//inputRotateVertex, MinXvalueEn
tity,//output&RotateAxisAngleTemp, &RotateAxisAngl
eAnotherTemp);break;//line type entitycaseCK_LIN
E:RotateVertexFlag = F2dCleanUpLineAngle(//inputRo
tateVertex, MinXvalueEntity,//output&RotateAxisAng
leTemp, &RotateAxisAngleAnotherTemp);break;defaul
t:break;} //select connected side of entityif ( Ro
tateVertexFlag == 1 ){//get start->end //set rotat
ion vertex nodeRotateNodesTemp = MinXvalueEntity->
connected_nodes_1;RotateVertexTemp= MinXvalueEntit
y->vertex1;//set another side vertex nodeRotateNod
esAnotherTemp = MinXvalueEntity->connected_nodes_
2;RotateVertexAnotherTemp= MinXvalueEntity->vertex
2;}else{//set rotation vertex nodeRotateNodesTemp
= MinXvalueEntity->connected_nodes_2;RotateVertexT
emp = MinXvalueEntity->vertex2;//set another side
vertex nodeRotateNodesAnotherTemp = MinXvalueEntit
y->connected_nodes_1;RotateVertexAnotherTemp= MinX
valueEntity->vertex1;}//compute diff angle//for ch
ange current entityRotateDiffAngleTemp = RotateAxi
sAngleTemp - RotateAxisAngle;if ( RotateDiffAngleT
emp < 0.0 ){RotateDiffAngleTemp = RotateDiffAngleT
emp + 2.0 * pi;}if ( RotateDiffAngleTemp < RotateM
inAngleTemp ){RotateMinAngleTemp = RotateDiffAngle
Temp;//set rotation entityRotateEntity= MinXvalueE
ntity;RotateNodes = RotateNodesTemp;RotateVertex
= RotateVertexTemp;RotateNodesAnother = RotateNode
sAnotherTemp;RotateVertexAnother = RotateVertexAno
therTemp;RotateAxisAngleAnother =RotateAxisAngleAn
otherTemp;}//step_7_1_3: find next connected entit
y with first entity around Min_x-vertex//check all
of entities which connected with first entity
if ( RotateNodes != 0 ){ for( outside_loop_temp
_list3=RotateNodes; outside_loop_temp_list3; out
side_loop_temp_list3= outside_loop_temp_list3->cd
r){if ( outside_loop_temp_list3->car == NULL )brea
k;Next_entity = outside_loop_temp_list3->car;//che
ck flagsif ( Next_entity->flags !=1 )continue;swit
ch ( Next_entity->type ){//arc typeentitycaseCK_A
RC:RotateVertexFlag = F2dCleanUpArcAngle(//inputRo
tateVertex, Next_entity, //output&RotateAxisAngleT
emp, &RotateAxisAngleAnotherTemp);break;//line ty
pe entitycaseCK_LINE:RotateVertexFlag = F2dCleanUp
LineAngle(//inputRotateVertex, Next_entity, //outp
ut&RotateAxisAngleTemp,&RotateAxisAngleAnotherTem
p);break;//wrong type entitydefault:break;}//selec
t connected side of entityif ( RotateVertexFlag ==
1 ){//get start->end //set rotation vertex nodeRo
tateNodesTemp = Next_entity->connected_nodes_1;Rot
ateVertexTemp= Next_entity->vertex1;//set another
side vertexnodeRotateNodesAnotherTemp = Next_entit
y->connected_nodes_2;RotateVertexAnotherTemp= Next
_entity->vertex2;}else{//set rotation vertex nodeR
otateNodesTemp = Next_entity->connected_nodes_2;Ro
tateVertexTemp = Next_entity->vertex2;//set anothe
r side vertex nodeRotateNodesAnotherTemp = Next_en
tity->connected_nodes_1;RotateVertexAnotherTemp= N
ext_entity->vertex1;}//compute diff angle//for cha
nge current entityRotateDiffAngleTemp = RotateAxis
AngleTemp - RotateAxisAngle;if ( RotateDiffAngleTe
mp < 0.0 ){RotateDiffAngleTemp = RotateDiffAngleTe
mp + 2.0 * pi;}if ( fabs( RotateDiffAngleTemp - Ro
tateMinAngleTemp ) < loop_tolerance ) {switch( Nex
t_entity->type ){caseCK_ARC:switch( RotateEntity->
type ){caseCK_ARC:switch( RotateVertexFlag ){case
1://no changebreak;case2:RotateEntity= Next_entit
y;RotateNodes = RotateNodesTemp;RotateVertex= Ro
tateVertexTemp;RotateNodesAnother = RotateNodesAno
therTemp;RotateVertexAnother = RotateVertexAnother
Temp;RotateAxisAngleAnother = RotateAxisAngleAnoth
erTemp;break;}break;caseCK_LINE:switch( RotateVert
exFlag ){case1://no changebreak;case2:RotateEntity
= Next_entity;RotateNodes = RotateNodesTemp;Rota
teVertex= RotateVertexTemp;RotateNodesAnother = Ro
tateNodesAnotherTemp;RotateVertexAnother = RotateV
ertexAnotherTemp;RotateAxisAngleAnother = RotateAx
isAngleAnotherTemp;break;}break;}caseCK_LINE:switc
h( RotateEntity->type ){caseCK_ARC:if ( RotateEnti
ty->vertex1 == RotateVertex ){RotateEntity= Next_e
ntity;RotateNodes = RotateNodesTemp;RotateVertex
= RotateVertexTemp;RotateNodesAnother = RotateNode
sAnotherTemp;RotateVertexAnother = RotateVertexA
notherTemp;RotateAxisAngl
eAnother = RotateAxisAngl
eAnotherTemp;}break;}}}if
( RotateDiffAngleTemp <
RotateMinAngleTemp ){Rota
teMinAngleTemp =RotateDif
fAngleTemp;//set rotation
entityRotateEntity= Next
_entity;RotateNodes = RotateN
odesTemp;RotateVertex= RotateVertexTemp;RotateNode
sAnother = RotateNodesAnotherTemp;RotateVertexAnot
her = RotateVertexAnotherTemp;RotateAxisAngleAnoth
er = RotateAxisAngleAnotherTemp;}}}}//step_7_2:fin
d next connected entity with first entity along th
e loopF2dCleanUpFindOutNextEntity(//input RotateEn
tity, RotateNodesAnother, RotateVertexAnother, &Ro
tateAxisAngleAnother );return 0;}/*===============
==================================================
関数: 名称: TestFindArrowControl記述: 手動関
数。ビユーに対して全てのアロー型エンティティを求め
る。戻り値:< 0: エラー= 0: プロセスなし> 0: 成功
裏に完了; 個数は見出されたエンティティのカウンタ値
である。パラメータ:副関数:struct node_list *F2dC
leanUpPickUpAllOneSideOpenEntity一側オープンのエン
ティティを求める。int F2dCleanUpFindArrowアロー型
エンティティを求める。int F2dCleanUpFindArrowEndEn
tityアローエンドラインを見出す。int F2dCleanUpFind
ArrowCenterEntityアローセンターラインを見出す。int
F2dCleanUpFindArrowOneSideOpenEntityアロー型の一
側オープンのエンティティを見出す。int F2dCleanUpCo
mputeCenterLineAngleセンターライン角度を計算する。
int F2dCleanUpCheckStartEndEntityスタートエンティ
ティおよびエンドエンティティをチェックする。int F2
dCleanUpLineAngleラインタイプエンティティの角度を
計算する。int F2dCleanUpArcAngle弓形のエンティティ
の角度を計算する。int F2dCleanUpChangeChildrenFlag
エンティティのチルドレンフラグを変更する。int F2dC
leanUpChangeArrowVertexFlagアロー頂点のフラグを変
更し、アローセンターライン座標を設定する。int F2dC
leanUpChangeDrawingColorエンティティの色を変更す
る。 double F2dCleanUpLineLengthライン型エンティテ
ィの長さを計算する。==============================
==================================*/intTestFindArr
owControl( int*SwitchRedraw ){//external functions
int F2dCleanUpFindArrow();int F2dCleanUpChangeDraw
ingColor();struct node_list *F2dCleanUpPickUpAllOn
eSideOpenEntity();//entities counter and flagsint
count = 0,assistant_line_flag= 0;//link list and t
emp liststruct node_list*Entities_change_color_lis
t1; //Begin//----------------------------------//S
tep_1://check the number of entites// get count o
f all entities// if an error occurred, exit immidi
ately. if (number_of_entities<0) return -1;//-
--------------------------------//Step_3: pickup a
ll one side open entitiesEntities_change_color_lis
t1 = F2dCleanUpPickUpAllOneSideOpenEntity( &trim_d
rawing );if (Entities_change_color_list1 == 0) re
turn 0;//---------------------------------//Step_
4: find arrow lineF2dCleanUpFindArrow( Entities_ch
ange_color_list1 );//-----------------------------
----//Step_X://change color to Magenta for a selec
ted boundary // turn off input levels#ifdefCKWI
Nif ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#
endifif ( *SwitchRedraw == 1)F2dCleanUpChangeDrawi
ngColor(&trim_drawing);//clear a flag for outside
loop processassistant_line_flag = 0;// turn ON the
level usedto store the trimmed entities.#ifdef CK
WINif ( *SwitchRedraw == 1)ck_levels(CK_ON,TrimLev
el, TrimLevel);if ( *SwitchRedraw == 1)ck_redraw(
CK_PRIME_VP );#endifreturn count;}/*==============
==================================================
=関数: 名称: TestFindOneSideOpen2Control記述:手
動関数。 一側がオープンで、ビユーの境界を横切るエ
ンティティを全て見出す。 戻り値:< 0: エラー= 0:
プロセスなしパラメータ:副関数:int F2dCleanUpFind
OneSideOpenEntity2一側がオープンで、ビユーの境界を
横切るエンティティを全て求める。int F2dCleanUpChan
geDrawingColorエンティティの色を変更する。========
==================================================
======*/intTestFindOneSideOpen2Control( int *Switc
hRedraw ){//external functionsint F2dCleanUpFindOn
eSideOpenEntity2();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->parent->Max_Y <= ArcE
ntity->Max_Y )) {F2dCleanUpChangeChildrenFlag( Vie
wEntity->parent );continue;}if (( ViewEntity->pare
nt->Min_X >= ArcEntity->Min_X && ViewEntity->pare
nt->Min_X <= ArcEntity->Max_X )&&( ViewEntity->par
ent->Min_Y >= ArcEntity->Min_Y && ViewEntity->pa
rent->Min_Y <= ArcEntity->Max_Y )) {F2dCleanUpChan
geChildrenFlag( ViewEntity->parent );continue;}if
(( ArcEntity->Max_X >= ViewEntity->parent->Min_X&&
ArcEntity->Max_X <= ViewEntity->parent->Max_X )&&
( ArcEntity->Max_Y >= ViewEntity->parent->Min_Y
&& ArcEntity->Max_Y <= ViewEntity->parent->Max_Y
)) {F2dCleanUpChangeChildrenFlag( ViewEntity->par
ent );continue;}if (( ArcEntity->Min_X >= ViewEnti
ty->parent->Min_X && ArcEntity->Min_X <= ViewEnti
ty->parent->Max_X )&& ( ArcEntity->Min_Y >= ViewEn
tity->parent->Min_Y && ArcEntity->Min_Y <= ViewE
ntity->parent->Max_Y )) {F2dCleanUpChangeChildrenF
lag( ViewEntity->parent );continue;}//check distan
ce from arc to entityViewEntityLength = F2dCleanUp
LineLength(ViewEntity->parent);DX = 0.5*(ViewEntit
y->parent->Min_X+ViewEntity->parent->Max_X) -ArcEn
tity->CenterX;DY = 0.5*(ViewEntity->parent->Min_Y+
ViewEntity->parent->Max_Y) - ArcEntity->CenterY;Di
stanceViewEntity2Center = sqrt(DX*DX+DY*DY) - ArcE
ntity->Radius - 0.5*ViewEntityLength;if ( Distance
ViewEntity2Center <= ViewEntityLength ){F2dCleanUp
ChangeChildrenFlag( ViewEntity->parent );continu
e;}//set center line flags ( look for children )fo
r( temp_list4=ViewEntity->parent->children; temp_
list4; temp_list4 = temp_list4->cdr){//change fla
g to light grayif ( temp_list4->car == NULL ) brea
k;temp_list4->car->flags = 10;count++;}if ( ViewEn
tity->next == NULL )break;}}#ifdef VELLUMCountProm
pt++;sprintf( message,"Finished find centerEntity
%d", CountPrompt );ck_prompt( message ); #endif//
normal endreturn count;}/*========================
=========================================関数: 名
称: F2dCleanUpFindInSideEntity記述: アウトサイド
ループに対するインサイドエンティティを求める。戻り
値:= 0: 成功裏に完了し、何も見出されない;= NUM:
開放エンティティの個数副関数:int F2dCleanUpChangeC
hildrenFlag未使用エンティティに対するフラグを設定
する。パラメータ:入力:1 In_Drawing: a図2 In_Enti
ties_list: 外側ループに対するノードリスト=========
==================================================
=====*/int F2dCleanUpFindInSideEntity( struct draw
ing *In_drawing, struct node_list *In_Entities_lis
t ){//external functionsint F2dCleanUpChangeChildr
enFlag();//link list and temp liststruct node_list
*temp_list, *temp_list2,*NewNodeList, *NewNodeLis
tTemp; struct group *NewGroup,*temp_group_list; st
ruct bounding_box *NewBoundBox;//selected entity
and temp entitiesstruct node*OutsideEntity,*ViewEn
tity;//entities counter and flagsint count = 0,NoF
lag = 0;//doubledoubleTolerance = 0.0;//set tolera
nceTolerance = F2dCleanUpTolerance;//initializeNew
Group = (struct group *)calloc(1,sizeof(struct gro
up ));NewBoundBox = (struct bounding_box *)calloc
(1,sizeof(structbounding_box ));NewNodeList = (str
uct node_list *)calloc(1,sizeof(struct node_list
));//set group dataNewGroup->next = NULL;NewGroup
->box = NewBoundBox;// check all of entities which
connected with outside loop for( temp_list=In_
Entities_list; temp_list; //&& temp_list->cdr; t
emp_list = temp_list->cdr){if ( temp_list->car ==
NULL ) break;OutsideEntity= temp_list->car;//check
entity : only boundary group ( flags = 1 and 4) i
f ( OutsideEntity->flags != 1 && OutsideEntity->fl
ags != 4 )continue;if ( !OutsideEntity ){NoFlag =
1;break;}NewGroup->box->Min_X = OutsideEntity->Min
_X;NewGroup->box->Max_X = OutsideEntity->Max_X;New
Group->box->Min_Y = OutsideEntity->Min_Y;NewGroup-
>box->Max_Y = OutsideEntity->Max_Y;break;}if ( NoF
lag == 1 )return0; NewNodeList->car = OutsideEn
tity;NewNodeList->cdr = NULL;// check first groupi
f( In_drawing->views == NULL){NewGroup->index = 1;
In_drawing->views = NewGroup;}else{//check group n
umber for( temp_group_list= In_drawing->views;
temp_group_list; //&&temp_group_list->next; tem
p_group_list = temp_group_list->next){if ( temp_gr
oup_list->next == NULL ){NewGroup->index = (temp_g
roup_list->index)+1;temp_group_list->next = NewGro
up;break;}}} // check connected entity if (
!temp_list->cdr && temp_list->car->type != CK_ARC
)return 0;// check all of entities which connecte
d with outside loop if ( temp_list->cdr ){ f
or( temp_list2 = temp_list->cdr; temp_list2;// &&
temp_list2->cdr; temp_list2 = temp_list2->cdr){if
( temp_list2->car ==NULL ) break;OutsideEntity =
temp_list2->car;//check entity : only boundary gro
up ( flags = 1 and 4 ) if ( OutsideEntity->flags !
= 1 && OutsideEntity->flags != 4 )continue;if ( Ne
wGroup->box->Min_X > OutsideEntity->Min_X )NewGrou
p->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 )NewGroup->box->Max_Y = Out
sideEntity->Max_Y;//allocate memory for node list
NewNodeListTemp = (struct node_list *)calloc(1,siz
eof(struct node_list ));//add this entity to node
list NewNodeListTemp->car = OutsideEntity;//connec
t to the node list NewNodeListTemp->cdr = NewNodeL
ist;//move the pointer of the node list to the top
NewNodeList = NewNodeListTemp;count++;}}//check al
l of entities in the viewfor( ViewEntity=In_drawin
g->objects; ViewEntity; ViewEntity = ViewEntity-
>next){//check flags: only no marks entities if (
ViewEntity == NULL )break;if ( ViewEntity->flags!
=0 )continue;//check bounding box: only inside en
tities if (( NewGroup->box->Min_X <= ViewEntity->M
in_X ) &&( NewGroup->box->Max_X >= ViewEntity->Ma
x_X ) &&( NewGroup->box->Min_Y <= ViewEntity->Min
_Y ) &&( NewGroup->box->Max_Y >= ViewEntity->Max_
Y )){//set flag ViewEntity->flags = 7;//allocate m
emory for node list NewNodeListTemp = (struct node
_list *)calloc(1,sizeof(struct node_list ));//add
this entity to node list NewNodeListTemp->car = Vi
ewEntity;//connect to the node list NewNodeListTem
p->cdr = NewNodeList;//move the pointer of the nod
e list to the topNewNodeList = NewNodeListTemp;cou
nt++;}}//set node list to group NewGroup->entities
= NewNodeList;//normal endreturn count;}/*=======
==================================================
========関数: 名称: F2dCleanUpFindOnesideOpenCon
nectEntityNext記述: 一側オープンエンティティに接
続された次のエンティティを求める。戻り値:= Out_en
tity: 成功裏に完了;パラメータ:入力: 1 In_entity:
エンティティ ====================================
============================*/struct node *F2dClea
nUpFindOnesideOpenConnectEntityNext(struct node *I
n_entity){//selected entity and temp entitiesstruc
tnode *Out_entity;//link list and temp liststruct
node_list *TempList1,*TempList2, *TempList3, *Next
Nodes;//defineintFlag1 = 0,Flag2 = 0,Count= 0;int
CountPrompt = 0;charmessage[64];#ifdef VELLUMCount
Prompt++;sprintf( message,"Start Find One Side Ope
n Connected Entity %d", CountPrompt);ck_prompt( me
ssage ); #endif//initializeOut_entity = NULL;//ch
eck input entityif ( !In_entity )returnOut_entity;
//check open sidefor( TempList1=In_entity->connect
ed_nodes_1; TempList1; //&& TempList1->cdr; TempLi
st1 = TempList1->cdr){if ( TempList1->car == NULL
)break;if ( TempList1->car->flags == 6 )Flag1 =
1;}for( TempList2=In_entity->connected_nodes_2;Tem
pList2; //&& TempList2->cdr; TempList2 = TempList2
->cdr){if ( TempList2->car == NULL )break;if ( Tem
pList2->car->flags == 6 )Flag2 = 1;}//first entity
caseif ( Flag1 == 0 && Flag2 == 0 ) {if ( In_ent
ity->no_connected_1 == 0 )Flag1 = 1;if ( In_entity
->no_connected_2 == 0 )Flag2 = 1;}//finish case: r
eturnif (( Flag1 == 0 && Flag2 == 0 ) ||( Flag1
== 1 && Flag2 == 1 ))returnOut_entity;//check all
of entities connected with input entityif ( Flag1
== 1 )NextNodes = In_entity->connected_nodes_2;els
eNextNodes = In_entity->connected_nodes_1;for( Tem
pList3= NextNodes; TempList3; //&& TempList3->cdr;
TempList3 = TempList3->cdr){if ( TempList3->car
== NULL )break;if ( TempList3->car->flags == 0 ){O
ut_entity = TempList3->car;Count++;}}//check resul
tif ( Count != 1 )Out_entity = NULL;#ifdef VELLUMC
ountPrompt++;sprintf( message,"Finished one side o
pen connected Entity %d", CountPrompt );ck_prompt
( message ); #endifreturnOut_entity;}/*==========
==================================================
=====関数: 名称: F2dCleanUpFindOnesideOpenConnec
tEntity記述: 一側オープンエンティティおよびそれに
接続された単一エンティティを求める。。戻り値:=0:
成功裏に完了;副関数:struct node *F2dCleanUpFindOn
esideOpenConnectEntityNext一側開放エンティティに接
続された次のエンティティを求める。パラメータ:入
力: 1 In_drawing: 図 ============================
====================================*/int F2dClean
UpFindOnesideOpenConnectEntity(struct drawing *In_
drawing){//external functionsstruct node *F2dClean
UpFindOnesideOpenConnectEntityNext();//selected en
tity and temp entitiesstruct node *entity, *FindEn
tity, *NextEntity;//check all of entities on the l
istfor( entity=In_drawing->objects; entity; enti
ty = entity->next){if (entity == NULL )break; if
( entity->flags != 0 )continue; if ( entity->type
!= CK_LINE )continue; if ( entity->no_connected_1
> 0 && entity->no_connected_2 > 0 )continue;if ( e
ntity->no_connected_1 == 0 && entity->no_connected
_2 == 0 )continue;if ((entity->no_connected_1 == 0
&& entity->no_connected_2 >= 1) ||(entity->no_co
nnected_2 == 0 && entity->no_connected_1 >= 1)) {/
/set flagentity->flags =6;FindEntity = entity;//fi
nd connected entityfor (;;){NextEntity = F2dCleanU
pFindOnesideOpenConnectEntityNext( FindEntity );if
( NextEntity == NULL )break;//set flagFindEntity=
NextEntity;FindEntity->flags =6;}}}return 0;}/*==
==================================================
=============関数: 名称: F2dCleanUpFindLongestEn
tity記述: 図に対して最も長いエンティティを求め
る。戻り値:= Entity: 成功裏に完了;= 0: エンティ
ティ無し;パラメータ:入力: 1 In_drawing: 図 =====
==================================================
=========*/struct node *F2dCleanUpFindLongestEntit
y(struct drawing *In_drawing){//selected entity an
d temp entitiesstruct node *entity, *LongestEntit
y;//definedoubleLongestLength = 0.0,ArcLength = 0.
0;//check all of entitieson the listfor( entity=In
_drawing->objects; entity; entity = entity->nex
t){//only not usedif ( entity == NULL )break;if (
entity->flags != 0 )continue;//check lengthif ( en
tity->parent->length <= LongestLength )continue;
//check arc lengthif ( entity->type == CK_ARC ){Ar
cLength = 2.0* entity->parent->Radius;if ( entity-
>parent->length < ArcLength)ArcLength = entity->pa
rent->length;if ( ArcLength > LongestLength ){//ch
ange max value and entityLongestLength = ArcLengt
h;LongestEntity = entity;}}else{//change max value
and entityLongestLength = entity->parent->length;
LongestEntity = entity;}}if ( LongestLength == 0.0
)returnNULL;elsereturnLongestEntity;}/*==========
==================================================
=====関数: 名称: F2dCleanUpFindViews記述: 図に
対するビユーのグループを求める。戻り値:= Entity:
成功裏に完了;= 0: エンティティなし;副関数:struc
t node *F2dCleanUpFindLongestEntity図に対する最も
長いエンティティを求める。struct node_list *F2dCle
anUpFindGroup入力エンティティと接続されたグループ
エンティティを求める。struct node *F2dCleanUpFindG
roupMinXエンティティグループに対する最小X値を求め
る。int F2dCleanUpFindOutSideLoopエンティティグル
ープに対する最小X値を求める。int F2dCleanUpFindIn
SideEntity外側ループパラメータに対するインサイドエ
ンティティを求める。パラメータ:入力: 1 In_drawin
g: 図 ============================================
====================*/int F2dCleanUpFindViews( str
uct drawing *In_drawing ){//external functionsstru
ct node *F2dCleanUpFindLongestEntity();struct node
_list *F2dCleanUpFindGroup();struct node *F2dClean
UpFindGroupMinX();int F2dCleanUpFindOutSideLoop();
int F2dCleanUpFindInSideEntity();//selected entity
and temp entitiesstruct node *LongestEntity, *Min
XvalueEntity;struct node_list *ViewGroup;//definei
nt ReturnFlag = 1,NoGroup= 0,Count = 0;doubleLonge
stLength = 0.0;int CountPrompt = 0;charmessage[6
4];//check all viewswhile( ReturnFlag ){#ifdef VEL
LUMCountPrompt++;sprintf( message,"Start Find View
s Entity %d", CountPrompt );ck_prompt( message );
#endif//Step_1:find a longest entity for a drawi
ngLongestEntity= F2dCleanUpFindLongestEntity( In_d
rawing );if ( LongestEntity == NULL )ReturnFlag =
0;else {//set flagNoGroup = 1; //clear counterCou
nt = 0;//Step_2:find connected group with the long
est entityViewGroup = F2dCleanUpFindGroup( Longest
Entity, &Count ); //Step_3:find outside loop entit
ies//check a flag for outside loop processif ( Cou
nt > 1 )MinXvalueEntity =F2dCleanUpFindGroupMinX(
ViewGroup );elseMinXvalueEntity = LongestEntity;if
( MinXvalueEntity == 0 )continue;//Step_4:find ou
tside loop entitiesif ( Count > 1 )F2dCleanUpFindO
utSideLoop( MinXvalueEntity );elseMinXvalueEntity-
>flags = 4;//Step_5:find inside entitiesF2dCleanUp
FindInSideEntity( In_drawing, ViewGroup );}#ifdef
VELLUMCountPrompt++;sprintf( message,"Finished fin
d view Entity %d", CountPrompt );ck_prompt( messag
e );#endif}if ( NoGroup == 0 )return-1;elsereturn
0;}/*=============================================
====================関数: 名称: F2dCleanUpFindRe
lativeViews記述: 相対ビユーを求める。 戻り値:=
0: 成功裏に完了;= 1:相対ビユーが見出される。パラメ
ータ:入力: 1 In_Drawing: 図2 In_Group:グループ3
In_ToleranceViews: ビユーに対する公差=============
==================================================
=*/int F2dCleanUpFindRelativeViews(struct drawing*
In_drawing,struct group*In_Group,double *In_Tolera
nceViews ) {//link list and temp liststruct group
*TempGroup;struct group_list*TempGroupList; //enti
ties counter and flagsint ReturnFlag = 0;//doubled
oubleTolerance = 0.0;//set toleranceTolerance = *I
n_ToleranceViews;//check viewsif( In_drawing->view
s == NULL )return0;if( In_Group == NULL )return0;f
or( TempGroup= In_drawing->views; TempGroup; //&&
TempGroup->next; TempGroup = TempGroup->next){//
check same groupif ( TempGroup == NULL)break;if (
TempGroup == In_Group )continue;//Step_1:check top
and bottom directionif ((TempGroup->box->Max_X>=
((In_Group->box->Max_X)-Tolerance )) &&(TempGrou
p->box->Max_X<=((In_Group->box->Max_X)+Tolerance
)) &&(TempGroup->box->Min_X>=((In_Group->box->Mi
n_X)-Tolerance )) &&(TempGroup->box->Min_X<=((In
_Group->box->Min_X)+Tolerance ))) {//set return fl
agReturnFlag = 1;//Step_1_1:check top directionif
( TempGroup->box->Min_Y > In_Group->box->Max_Y ){/
/check top directionrelative viewsif ( In_Group->t
o_top == NULL ){TempGroupList = (struct group_list
*)calloc(1,sizeof(struct group_list ));TempGroupL
ist->car = TempGroup;TempGroupList->cdr = NULL;In_
Group->to_top = TempGroupList;}else{//check distan
ceif ( In_Group->to_top->car->box->Min_Y > TempGro
up->box->Min_Y ){//change top viewIn_Group->to_top
->car = TempGroup;}}}else//Step_1_2:check bottom d
irectionif ( TempGroup->box->Max_Y < In_Group->box
->Min_Y ){//check top directionrelative viewsif (
In_Group->to_bottom == NULL ){TempGroupList = (str
uct group_list *)calloc(1,sizeof(struct group_list
));TempGroupList->car = TempGroup;TempGroupList->
cdr = NULL;In_Group->to_bottom = TempGroupList;}el
se{//check distanceif ( In_Group->to_bottom->car->
box->Max_Y < TempGroup->box->Max_Y ){//change top
viewIn_Group->to_bottom->car = TempGroup;}}}}else/
/Step_2:check left and right directionif ((TempGro
up->box->Max_Y>=((In_Group->box->Max_Y)-Tolerance
)) &&(TempGroup->box->Max_Y<=((In_Group->box->M
ax_Y)+Tolerance )) &&(TempGroup->box->Min_Y>=((In
_Group->box->Min_Y)-Tolerance )) &&(TempGroup->b
ox->Min_Y<=((In_Group->box->Min_Y)+Tolerance )))
{//set return flagReturnFlag = 1;//Step_2_1:check
right directionif ( TempGroup->box->Min_X > In_Gro
up->box->Max_X ){//check right direction relative
viewsif ( In_Group->to_right == NULL ){TempGroupLi
st = (struct group_list *)calloc(1,sizeof(struct g
roup_list ));TempGroupList->car = TempGroup;TempGr
oupList->cdr = NULL;In_Group->to_right = TempGroup
List;}else{//check distanceif ( In_Group->to_right
->car->box->Min_X > TempGroup->box->Min_X ){//chan
ge left viewIn_Group->to_right->car = TempGrou
p;}}}else//Step_2_2:check left directionif ( TempG
roup->box->Max_X < In_Group->box->Min_X ){//check
left directionrelative viewsif ( In_Group->to_left
== NULL ){TempGroupList = (struct group_list *)ca
lloc(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 viewIn_Group->to_left
->car = TempGroup;}}}}}//normal endreturn ReturnFl
ag;}/*============================================
=====================関数: 名称: F2dCleanUpFindV
iewsRelation記述: 図に対するビユー関係を求める。
戻り値:= 0: 成功裏に完了するが、何も見出されな
い。;=NUM: ビユーの個数副関数:int F2dCleanUpFindR
elativeViews相対ビユーを求める。パラメータ:入力:
1 In_Drawing: a図================================
================================*/int F2dCleanUpFi
ndViewsRelation( struct drawing*In_drawing ) {//ex
ternal functionsint F2dCleanUpFindRelativeViews();
//link list and temp liststruct group *MaxGroup,*T
empGroup,*NextGroup;struct group_list*OpenGroupLis
t,*TempOpenGroupList,*TempGroupList;struct node_li
st *ETL;//Entity Temp List//entities counter and f
lagsintNoFlag = 0;//doubledoubleBiggestSize = 0.0,
BiggestSizeTemp = 0.0;doubleTolerance = 0.0,Toler
anceViews = 0.0;//set toleranceTolerance = F2dClea
nUpTolerance;//check viewsif( In_drawing->views ==
NULL )return0;//Step_1:get the biggest group’s s
izefor( TempGroup= In_drawing->views; TempGroup;
//&& TempGroup->next; TempGroup = TempGroup->nex
t){// clear flagsTempGroup->index = 0;// compute s
ize for boxBiggestSizeTemp = fabs( TempGroup->box-
>Max_X - TempGroup->box->Min_X ) + fabs( TempGrou
p->box->Max_Y - TempGroup->box->Min_Y );//check si
zeif ( BiggestSizeTemp > BiggestSize ){BiggestSize
= BiggestSizeTemp;MaxGroup= TempGroup;}//check la
st oneif ( TempGroup->next == NULL )break;}//check
views toleranceToleranceViews = 0.01 * BiggestSiz
e;if ( ToleranceViews < Tolerance ) ToleranceViews
= Tolerance;//Step_2:find relationship for each v
iew//initialize a open list OpenGroupList = (struc
t group_list *)calloc(1,sizeof(struct group_list
));OpenGroupList->car = MaxGroup;OpenGroupList->c
dr = NULL;// seta open flag to the groupMaxGroup->
index = 1;for ( TempGroupList = OpenGroupList; Tem
pGroupList; ){//get a pointer from open list if (
TempGroupList->car == NULL )break;NextGroup = Temp
GroupList->car;//set a closed flag to the groupNex
tGroup->index = 2;//close the group ( delete the g
roupfrom open list )OpenGroupList = OpenGroupList-
>cdr;//get relationNoFlag= F2dCleanUpFindRelativeV
iews( In_drawing, NextGroup, &ToleranceViews );if
( NoFlag == 0 )break;//check each direction for th
e viewif ( NextGroup->to_top != NULL ){if ( NextGr
oup->to_top->car->index == 0 ){TempOpenGroupList =
(struct group_list *)calloc(1,sizeof(struct group
_list ));TempOpenGroupList->car = NextGroup->to_to
p->car;TempOpenGroupList->cdr = OpenGroupList;Temp
OpenGroupList->car->index = 1;OpenGroupList = Temp
OpenGroupList;}}if ( NextGroup->to_bottom != NULL
){if ( NextGroup->to_bottom->car->index == 0 ){Te
mpOpenGroupList = (struct group_list *)calloc(1,si
zeof(struct group_list ));TempOpenGroupList->car =
NextGroup->to_bottom->car;TempOpenGroupList->cdr
= OpenGroupList;TempOpenGroupList->car->index= 1;O
penGroupList = TempOpenGroupList;}}if ( NextGroup-
>to_left != NULL){if ( NextGroup->to_left->car->in
dex == 0 ){TempOpenGroupList = (struct group_list
*)calloc(1,sizeof(struct group_list ));TempOpenGro
upList->car = NextGroup->to_left->car;TempOpenGrou
pList->cdr = OpenGroupList;TempOpenGroupList->car-
>index = 1;OpenGroupList = TempOpenGroupList;}}if
( NextGroup->to_right != NULL ){if ( NextGroup->to
_right->car->index == 0 ){TempOpenGroupList = (str
uct group_list *)calloc(1,sizeof(struct group_list
));TempOpenGroupList->car = NextGroup->to_right->
car;TempOpenGroupList->cdr = OpenGroupList;TempOpe
nGroupList->car->index = 1;OpenGroupList= TempOpen
GroupList;}}//assign value to the loop variableTem
pGroupList =OpenGroupList;}//Step_3:clear flags fo
r no relative groupsfor( NextGroup=In_drawing->vie
ws; NextGroup; NextGroup = NextGroup->next){if ( N
extGroup == NULL )break;if ( NextGroup->index != 0
)continue;for ( ETL=NextGroup->entities; ETL; ETL
=ETL->cdr ) {ETL->car->flags = 0;if ( ETL->cdr ==
NULL )break;}}//normal endreturn 0;}/*===========
==================================================
====関数: 名称: F2dCleanUpFindDrawingSheet記述:
図に対する描画シートを求める。戻り値:= -1: エラ
ーデータ;= 0: 成功裏に完了;= 1: シートなし;副関
数:struct node_list *F2dCleanUpFindGroup入力エン
ティティと接続されたグループエンティティを求める。
パラメータ:入力: 1 In_drawing: 図 ==============
==================================================
*/int F2dCleanUpFindDrawingSheet(struct drawing*In
_drawing,struct bounding_box *InOut_BB,int *In_Tim
esFlag ){//externalfunctionsstruct node_list *F2dC
leanUpFindGroup();//selected entity andtemp entiti
esstruct node *entity, *LongestEntityX, *LongestEn
tityY;struct node_list*SheetGroup, *temp_list2; //
bounding boxstruct bounding_box BB, EBB;//definein
tSheetFlag = 0, count = 0,CountPrompt = 0;doubleLo
ngestLengthX = 0.0,LongestLengthY = 0.0,AlphaX =
0.0, AlphaY = 0.0;charmessage[64]; doubleTolerance
= 0.0;//set toleranceTolerance = F2dCleanUpTolera
nce;#ifdef VELLUMCountPrompt++;sprintf( message,"S
tart Find Sheet Entity%d", CountPrompt );ck_prompt
( message ); #endif//STEP_1:look for the longest
line type parent entity //check all of entities on
the listfor( entity=In_drawing->objects; entity;
entity = entity->next){//only linetypeif ( entit
y == NULL )break;if ( entity->type != CK_LINE )con
tinue; //only not usedif ( entity->flags != 0 )con
tinue;//check lengthif (( entity->parent->length <
= LongestLengthX ) &&( entity->parent->length <=
LongestLengthY ))continue; //check horizontally a
nd vertically //if angle(alpha) was smaller than
( sin ( alpha ) = alpha )AlphaX = fabs( ( entity->
parent->Max_X - entity->parent->Min_X )/ entity->p
arent->length );AlphaY = fabs( ( entity->parent->M
ax_Y - entity->parent->Min_Y )/ entity->parent->le
ngth );if ( ( AlphaX > Tolerance ) && ( AlphaY > T
olerance ) )continue;//change max value and entity
if ( AlphaY < Tolerance ){ if ( entity->parent->le
ngth > LongestLengthX ){ LongestLengthX = entity-
>parent->length;LongestEntityX = entity;}}else{ if
( entity->parent->length > LongestLengthY ){ Lon
gestLengthY = entity->parent->length;LongestEntity
Y= entity;}} #ifdef VELLUM//CountPrompt++;//sprint
f( message,"Sheet Entity %d", CountPrompt );//ck_p
rompt( message ); #endif}//check the longest enti
tiy’s lengthif (( LongestLengthX < Tolerance ) |
|( LongestLengthY < Tolerance ))return-1;
//set bounding boxBB.Min_X = LongestEntityX
->parent->Min_X;BB.Max_X = LongestEntityX->parent-
>Max_X;BB.Min_Y = LongestEntityY->parent->Min_Y;B
B.Max_Y = LongestEntityY->parent->Max_Y;//check in
side drawing sheet sizeif ( *In_TimesFlag == 1)*In
Out_BB= BB; //set valueselse{
if ( (InOut_BB->Min_X ==
0.0 ) && (InOut_BB->Max_X == 0.0 ) &&(InOut_BB->M
in_Y == 0.0 ) && (InOut_BB->Max_Y == 0.0 )) return
0;if (( BB.Max_X - BB.Min_X ) < Tolerance )return
0;if ( fabs(( InOut_BB->Max_X - InOut_BB->Min_X )
/ ( BB.Max_X - BB.Min_X )) > 1.2 )return0;}//set a
flag to entityLongestEntityX->flags = 3; //STEP_
2:look for connected entities group and make bound
arySheetGroup = F2dCleanUpFindGroup( LongestEntity
X, &count);if ( SheetGroup == 0 )return0;//STEP_3:
clear flagsfor all entitiesfor(entity=In_drawing->
objects; entity; entity = entity->next){if ( ent
ity == NULL )break;if ( entity->flags == 3 )contin
ue;if ( entity->flags ==4 )continue;entity->flags
= 0; }//STEP_4:set flags the groupfor ( temp_list2
= SheetGroup; ( temp_list2!=0 && temp_list
2->car!=0 );temp_list2=temp_list2->cdr){if ( temp_
list2->car == NULL )break;temp_list2->car->flags =
3; }//STEP_5:set expanding box ( 20% for +X,-X,+
Y,-Y)EBB.Min_X = ( BB.Min_X ) - 0.2 * fabs(( BB.Ma
x_X ) - ( BB.Min_X ));EBB.Max_X = ( BB.Max_X ) +
0.2 * fabs(( BB.Max_X ) - ( BB.Min_X ));EBB.Min_Y=
( BB.Min_Y ) - 0.2 * fabs(( BB.Max_Y ) - ( BB.Min
_Y ));EBB.Max_Y = (BB.Max_Y ) + 0.2 * fabs(( BB.Ma
x_Y ) - ( BB.Min_Y ));//STEP_6:check outside entit
y( out of the bounding box ) in the DRAWING//if an
y entity wasfound, no sheet was found for this dra
wingfor( entity=In_drawing->objects; entity; ent
ity = entity->next){if ( entity == NULL )break; if
( entity->flags != 0 )continue;//look for out sid
e entity if ( entity->Max_X> EBB.Max_X ){ SheetFla
g = 1;break;}if ( entity->Max_Y > EBB.Max_Y ){ She
etFlag = 1;break;}if ( entity->Min_X < EBB.Min_X )
{ SheetFlag = 1;break;}if ( entity->Min_Y < EBB.Mi
n_Y ){ SheetFlag = 1;break;}}//STEP_7:lookfor shee
t data ( out side of the boundary )if ( SheetFlag
== 0 ){//lookfor sheet data for( entity=In_drawing
->objects; entity; entity = entity->next){if ( e
ntity == NULL )break; if ( entity->flags == 3 )ent
ity->flags = 4; if ( entity->flags != 0 )continue;
if (( entity->Min_X <= BB.Min_X )||( entity->Max_
X >= BB.Max_X ) ||( entity->Min_Y <= BB.Min_Y )||
(entity->Max_Y >= BB.Max_Y ))//set flagentity->fla
gs =4;}//Goodreturn 0;}//STEP_8:clear flags ( No s
heet was found ! )for( entity=In_drawing->objects;
entity; entity = entity->next){if ( entity == N
ULL )break;if (entity->flags == 4 )continue; entit
y->flags = 0; }if ( SheetFlag != 0 )return 1;#ifde
f VELLUMCountPrompt++;sprintf( message,"Finished f
ind SheetEntity %d", CountPrompt );ck_prompt( mess
age ); #endifreturn 0;}/*========================
=========================================関数: 名
称: TestFindDrawingSheetControl 記述: 手動関数。
図に対する描画シートを求める。戻り値:< 0: エラー=
0: プロセスなし> 0: 成功裏に完了;個数は見出され
たエンティティのカウンタ値である。パラメータ:副関
数:int F2dCleanUpFindDrawingSheet成功裏に完了;個
数は見出されたエンティティのカウンタ値である。intF
2dCleanUpChangeDrawingFlagエンティティのフラグを変
更する( 4 >>3 )===================================
=============================*/intTestFindDrawingS
heetControl( int *SwitchRedraw ){//external functi
onsint F2dCleanUpFindDrawingSheet();int F2dCleanUp
ChangeDrawingColor();intF2dCleanUpChangeDrawingFla
g();//definestruct bounding_box BB;intReturnFlag=
0; intTimesFlag = 0;//----------------------------
------//Step_1:check the number of entites// if an
error occurred, exit immidiately. if (number_o
f_entities<0)return -1;//-------------------------
--------//Step_2: find center line entitiesTimesFl
ag = 1;ReturnFlag = F2dCleanUpFindDrawingSheet( &t
rim_drawing, &BB, &TimesFlag );if( ReturnFlag == 1
) return 0;if( ReturnFlag== -1 ) return 0;TimesFl
ag = 2;F2dCleanUpFindDrawingSheet( &trim_drawing,
&BB, &TimesFlag );//------------------------------
---//Step_3: changeflagsF2dCleanUpChangeDrawingFla
g( &trim_drawing );//-----------------------------
----//Step_X:change color to light gray for a sele
cted center lines // turn off input levels#ifde
f CKWINif ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,
255);#endifif ( *SwitchRedraw == 1)F2dCleanUpChang
eDrawingColor(&trim_drawing);// turn ON the level
used to store the trimmed entities.#ifdef CKWINif
( *SwitchRedraw == 1)ck_levels(CK_ON,TrimLevel, Tr
imLevel);//if ( *SwitchRedraw == 1)ck_redraw( CK_P
RIME_VP );#endifreturn0;}/*=======================
==========================================関数:
名称: TestFindViewsControl 記述: 手動関数。 図に
対する描画シートを求める。戻り値:< 0: 図= 0: プロ
セスなし> 0: 成功裏に完了; 個数は見出されたエンテ
ィティのカウンタ値である。パラメータ:副関数:int
F2dCleanUpFindViews図に対するビューのグループを求
める。int F2dCleanUpFindViewsRelation図に対するビ
ュー関係を求める。int F2dCleanUpChangeDrawingColor
==================================================
==============*/intTestFindViewsControl( int *Swit
chRedraw ){//external functionsint F2dCleanUpFindV
iews();int F2dCleanUpFindViewsRelation();int F2dCl
eanUpChangeDrawingColor();//Step_1:check the numbe
r of entites// if an error occurred, exit immidiat
ely. if (number_of_entities<0) return -1;//Ste
p_2: find views’ group if ( F2dCleanUpFindViews(
&trim_drawing ) == -1 ) return -1;//Step_3: find
views’ relationship //move to delete function ( M
ar. 29,1996 )//F2dCleanUpFindViewsRelation( &trim_
drawing );//Step_X:change colorto light gray for a
selected center lines // turn off input levels
#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels(CK_O
FF,1,255);#endifif ( *SwitchRedraw == 1)F2dCleanUp
ChangeDrawingColor(&trim_drawing);// turn ON the l
evel used to store the trimmed entities.#ifdef CKW
INif ( *SwitchRedraw == 1)ck_levels(CK_ON,TrimLeve
l, TrimLevel);if ( *SwitchRedraw == 1)ck_redraw( C
K_PRIME_VP );#endifreturn 0;}/*===================
==============================================関
数: 名称: TestFindBoundaryControl記述: 手動関
数。 ユーザがビユーの境界のエンティティを選択した
とき、この関数はビユーに対する接続されたエンティテ
ィの全てを見出す。戻り値:< 0:エラー= 0: プロセス
なし> 0: 成功裏に完了; 成功裏に完了パラメータ:副
関数:int F2dCleanUpFindOutSideLoopサイドループの
エンティティを求める。int F2dCleanUpFindInSideEnti
ty外側ループに対するサイドエンティティを求める。in
t F2dCleanUpFindOutNextEntity外側ループエンティテ
ィと接続されたエンティティを求める。struct node *F
2dCleanUpFindGroupMinXエンティティグループに対する
最小X値を求める。struct node_list *F2dCleanUpFind
Group入力エンティティと接続されたグループエンティ
ティを求める。ystruct node *F2dCleanUpInputEntity
( old function )画面上の選択されたエンティティを求
める。intF2dCleanUpLineAngleライン形エンティティの
角度を計算する。int F2dCleanUpArcAngleアーク形エン
ティティの角度を求める。int F2dCleanUpChangeChildr
enFlagエンティティのチルドレンフラグを変更する。in
t F2dCleanUpChangeArrowVertexFlagアロートップ頂点
のフラグを変更し、アローセンタライン座標を設定す
る。int F2dCleanUpFindViewsRelationl図に対するビユ
ー関係を求める。int F2dCleanUpChangeColorエンティ
ティの色を変更する。 double F2dCleanUpLineLengthラ
イン形エンティティの長さを計算する。==============
==================================================
*/intTestFindBoundaryControl( int *SwitchRedraw )
{//external functions
int F2dCleanUpChangeDrawingColor();int F2dClea
nUpFindOutSideLoop();int F2dCleanUpFindInSideEntit
y();int F2dCleanUpFindViewsRelation();struct node
*F2dCleanUpInputEntity();struct node *F2dCleanUpFi
ndGroupMinX();struct node_list *F2dCleanUpFindGrou
p();//entities counter and flagsint count = 0;//li
nk list and temp liststruct node_list *Entities_li
st; //selected entity and temp entitiesstruct node
*entity,*MinXvalueEntity;//Begin//--------------
--------------------//Step_1://check the number of
entites// get count of all entities// if an erro
r occurred, exit immidiately. if (number_of_ent
ities<0) return -1;for( ; ; ){//-----------------
----------------//Step_2:select one entityentity =
F2dCleanUpInputEntity( "Select aBoundary Entity f
or a view",&trim_drawing);if ( entity == 0 )return
0;if( entity->flags != 0 )continue;//-------------
--------------------//Step_3: find a connected ent
ities groupEntities_list = F2dCleanUpFindGroup(ent
ity, &count );//---------------------------------/
/Step_4:find outside loop entities without assista
nt entities//check a flag for outside loop process
if ( count < 1 )continue;MinXvalueEntity = F2dClea
nUpFindGroupMinX( Entities_list);if ( MinXvalueEnt
ity == 0 )continue;//-----------------------------
----//Step_5:find outside loop entitiesF2dCleanUpF
indOutSideLoop( MinXvalueEntity );//--------------
-------------------//Step_6:find inside entitiesF2
dCleanUpFindInSideEntity( &trim_drawing, Entities_
list );//---------------------------------//Step_
7: find views’ relationship //move delete functio
n (Mar.29, 1996 By Ji )//F2dCleanUpFindViewsRelati
on( &trim_drawing );//----------------------------
-----//Step_X:change color to Magenta for a select
ed boundary // turn off input levels#ifdef CKWI
Nif ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#
endifF2dCleanUpChangeDrawingColor(&trim_drawing);/
/ turn ON the level used to storethe trimmed entit
ies.#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels
(CK_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw ==
1)ck_redraw( CK_PRIME_VP );#endif}return count;}/
*=================================================
================関数: 名称: TestFindCenterLineCo
ntrol記述: 手動関数。ビユー中の全てのアークに対す
るセンタラインを見出す。戻り値:< 0: エラー= 0: プ
ロセスなし> 0: 成功理に完了; 成功理に完了パラメー
タ:副関数:struct node_list *F2dCleanUpPickUpAllA
rcEntity選択された図中の全てのアークエンティティを
求める。int F2dCleanUpChangeDrawingColorエンティテ
ィの色を変更する。================================
================================*/intTestFindCente
rLineControl( int *SwitchRedraw ){//external funct
ionsint F2dCleanUpFindCenterLineEntity();int F2dCl
eanUpChangeDrawingColor();struct node_list *F2dCle
anUpPickUpAllArcEntity();//link list and templists
truct node_list*Entities_list; //Begin//----------
------------------------//Step_1:check the number
of entites// if an error occurred, exitimmidiatel
y. if (number_of_entities<0) return -1;//-----
----------------------------//Step_2: pickup all a
rc entitiesEntities_list = F2dCleanUpPickUpAllArcE
ntity( &trim_drawing ); if (Entities_list == 0)
return 0;//---------------------------------//St
ep_3: find center line entitiesF2dCleanUpFindCente
rLineEntity( &trim_drawing, Entities_list );//----
-----------------------------//Step_X:change color
to light gray for aselected 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 ( *SwitchRedra
w == 1)ck_redraw( CK_PRIME_VP);#endifreturn 0;}/*=
==================================================
==============関数: 名称: TestFindOneSideOpenCon
nectControl 記述: 手動関数。 一側オープン接続エン
ティティを見出す。戻り値:< 0: エラー= 0: プロセス
なし> 0: 成功裏に完了; 数は見出されたエンティティ
のカウンタ値である。パラメータ:副関数:int F2dCle
anUpFindOnesideOpenConnectEntity一側開放接続エンテ
ィティを求める。==================================
==============================*/intTestFindOneSide
OpenConnectControl( int *SwitchRedraw ){//external
functionsint F2dCleanUpFindOnesideOpenConnectEnti
ty();int F2dCleanUpChangeDrawingColor();//--------
--------------------------//Step_1:check the numbe
r of entites// if an error occurred, exit immidiat
ely. if (number_of_entities<0) return -1;//---
------------------------------//Step_2: find cente
r line entitiesF2dCleanUpFindOnesideOpenConnectEnt
ity( &trim_drawing );//---------------------------
------//Step_X:change color to light gray for a se
lected center lines // turn off input levels#if
def CKWINif ( *SwitchRedraw == 1)ck_levels(CK_OFF,
1,255);#endifif ( *SwitchRedraw == 1)F2dCleanUpCha
ngeDrawingColor(&trim_drawing);// turn ON the leve
l used to store the trimmed entities.#ifdef CKWINi
f( *SwitchRedraw == 1)ck_levels(CK_ON,TrimLevel, T
rimLevel);if ( *SwitchRedraw == 1)ck_redraw( CK_PR
IME_VP );#endifreturn 0;}/*=======================
==========================================関数:
名称: TestFindSameColorControl記述: 手動関数。同
じ色のエンティティを見出す。戻り値:= 0:成功裏に完
了;数は見出されたエンティティのカウンタ値である。
パラメータ:副関数:struct node *F2dCleanUpInputEn
tity ( old function )画面上の選択されたエンティテ
ィを求める。int F2dCleanUpFindSameColorEntity選択
されたエンティティにより同じ色のエンティティを求め
る。int F2dCleanUpChangeDrawingColorエンティティの
色を変更する。====================================
============================*/intTestFindSameColor
Control(){//externalfunctionsint F2dCleanUpChangeD
rawingColor();int F2dCleanUpFindSameColorEntity();
struct node *F2dCleanUpInputEntity();//selected en
tity and tempentitiesstruct node*entity;//Begin//-
---------------------------------//Step_1://check
the number of entites// if an error occurred, exit
immidiately. if (number_of_entities<0) return
-1;for( ; ; ){//---------------------------------
//Step_2:select one entityentity = F2dCleanUpInput
Entity( "Select a Unuse Color Entity",&trim_drawin
g);if ( entity == 0 )return0;if ( entity->flags !=
0 )continue;//---------------------------------//
Step_3: find a connected entities groupF2dCleanUpF
indSameColorEntity( entity, &trim_drawing );//----
-----------------------------//Step_X:change color
to Magenta for a selected boundary // turn off
input levels#ifdef CKWIN ck_levels(CK_OFF,1,25
5);#endifF2dCleanUpChangeDrawingColor(&trim_drawin
g);// turn ON the level used to store the trimmed
entities.#ifdef CKWIN ck_levels(CK_ON,TrimLeve
l, TrimLevel);if ( *SwitchRedraw == 1)ck_redraw( C
K_PRIME_VP );#endif}return 0;}/*==================
===============================================関
数: 名称: TestFindSelectSingleControl記述: 手動
関数。使用エンティティを見出す。戻り値:= 0:成功裏
に完了; パラメータ:副関数:struct node *F2dCleanU
pInputEntity (古い関数 )画面上の選択されたエンティ
ティを求める。====================================
============================*/intTestFindSelectSin
gleControl(){//external functionsstruct node *F2dC
leanUpInputEntity();//selectedentity and temp enti
tiesstruct node*entity;//entity’s specifitysCK_EN
TATTattr;//specificity of entities//Begin//-------
---------------------------//Step_1:check the numb
er of entites// if an error occurred, exit immidia
tely. if (number_of_entities<0) return -1;for
( ; ; ){//---------------------------------//Step_
2:select one entityentity = F2dCleanUpInputEntity
( "Select an Unuse Entity", &trim_drawing);if ( en
tity == 0 )return0;//-----------------------------
----//Step_3: change 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 unuse entity // turn off input
levels// ck_levels(CK_OFF,1,255);ck_setattr( e
ntity->id, CK_COLOR, NULL, &attr );// turn ONthe l
evel used to store the trimmed entities.// ck_l
evels(CK_ON,TrimLevel, TrimLevel);ck_redraw( CK_PR
IME_VP );}return 0;}/*============================
=====================================関数: 名称:
TestUnselectSingleControl記述: 手動関数。使用エ
ンティティをクリアする。戻り値:=0: 成功裏に完了;
パラメータ:副関数:struct node *F2dCleanUpInputEn
tity (old function )画面上の選択されたエンティティ
を求める。========================================
========================*/intTestUnselectSingleCon
trol(){//external functionsstruct node *F2dCleanUp
InputEntity();//selected entity and temp entitiess
truct node*entity;//entity’s specifitysCK_ENTATTa
ttr;//specificity 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:sel
ect one entityentity = F2dCleanUpInputEntity( "Sel
ect an Entity to release",&trim_drawing);if ( enti
ty == 0 )return0;//-------------------------------
--//Step_3: change flagif( entity->flags != 3&& en
tity->flags != 4 && entity->flags != 10 ) continu
e;entity->flags = 0;//----------------------------
-----//Step_X:changecolor to light gray for unuse
entity // turn off input levels ck_levels(CK
_OFF,1,255);attr.color = entity->color;ck_setattr
( entity->id,CK_COLOR, NULL, &attr );// turn ON th
e level used to store the trimmed entities. ck_
levels(CK_ON,TrimLevel, TrimLevel);ck_redraw( CK_P
RIME_VP);}return 0;}/*============================
=====================================関数: 名称:
TestClearKeepFlagsControl記述: 手動関数。全ての
選択されたエンティティを戻す。戻り値:= 0: 成功裏
に完了;パラメータ:副関数:int F2dCleanUpClearDraw
ingKeepFlagsエンティティの色を元に変更するが、フラ
グは維持する。====================================
============================*/intTestClearKeepFlag
sControl( int *SwitchRedraw ){//external functions
int F2dCleanUpClearDrawingKeepFlags();//Begin//---
-------------------------------//check the number
of entites// if an error occurred, exit immidiatel
y. if (number_of_entities<0) return -1;//-----
---------------------------- // turn off input
levels#ifdef CKWINif ( *SwitchRedraw == 1)ck_level
s(CK_OFF,1,255);#endifF2dCleanUpClearDrawingKeepFl
ags(&trim_drawing);if ( *SwitchRedraw == 1)ck_redr
aw( CK_PRIME_VP );// turn ON the level used tostor
e the trimmed entities.#ifdef CKWINif ( *SwitchRed
raw == 1)ck_levels(CK_ON,TrimLevel, TrimLevel);if
( *SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );#end
ifreturn0;}/*=====================================
============================関数: 名称: TestClea
rControl記述: 手動関数。全ての選択されたエンティ
ティを元に戻す。戻り値:= 0: 成功裏に完了;パラメー
タ:副関数:int F2dCleanUpClearDrawingEntityエンテ
ィティの色を元に戻す。============================
====================================*/intTestClear
Control( int *SwitchRedraw ){//external functionsi
nt F2dCleanUpClearDrawingEntity();//Begin//-------
---------------------------//check the number of e
ntites// if an error occurred, exit immidiately.
if (number_of_entities<0) return -1;//---------
------------------------ // turn off input leve
ls#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels(CK
_OFF,1,255);#endifF2dCleanUpClearDrawingEntity(&tr
im_drawing);// turn ON the levelused to store the
trimmed entities.#ifdef CKWINif ( *SwitchRedraw ==
1)ck_levels(CK_ON,TrimLevel, TrimLevel);if ( *Swi
tchRedraw == 1)ck_redraw(CK_PRIME_VP );#endifretur
n0;}/*============================================
=====================関数: 名称: TestDeleteContr
ol記述: 手動関数。全ての選択されたエンティティを
削除する。戻り値:= 0: Completed successfully;パラ
メータ:副関数:int F2dCleanUpDeleteDrawingEntity
全てエンティティを削除する。======================
==========================================*/intTes
tDeleteControl( int *SwitchRedraw ){//external fun
ctionsint F2dCleanUpDeleteDrawingEntity();//Begin/
/----------------------------------//check the num
ber of entites// if an error occurred, exit immidi
ately. if (number_of_entities<0) return -1;
//Step_7: find views’ relationship //move fr
om find boundary function (Mar.29, 1996 By Ji)F2dC
leanUpFindViewsRelation( &trim_drawing );//-------
--------------------------#ifdef CKWIN
if ( *SwitchRedraw ==
1)ck_levels(CK_OFF,1,255);#endif// turn ON the lev
el used tostore the trimmed entities.F2dCleanUpDel
eteDrawingEntity(&trim_drawing);#ifdef VELLUMif (
*SwitchRedraw == 1)F2dCleanUpChangeDrawingColor(&t
rim_drawing);#endif#ifdef CKWINif ( *SwitchRedraw
== 1)ck_levels(CK_ON,TrimLevel, TrimLevel);if ( *S
witchRedraw == 1)ck_redraw( CK_PRIME_VP );#endifre
turn0;}/*=========================================
========================関数: 名称: TestBackColo
rControl記述: 元に戻す。戻り値:= 0: 成功裏に完
了;パラメータ:副関数:int F2dCleanUpUndo元に戻
す。==============================================
==================*/intTestBackColorControl( int *
SwitchRedraw ){//external functionsint F2dCleanUpC
hangeDrawingColor();if( *SwitchRedraw == 1)F2dClea
nUpChangeDrawingColor(&trim_drawing);return0;}/*==
==================================================
=============関数: 名称: TestUndoControl記述:
元に戻す。戻り値:= 0: 成功裏に完了;パラメータ:副
関数:int F2dCleanUpUndo元に戻す。================
================================================*/
intTestUndoControl( int *SwitchRedraw ){//external
functionsint F2dCleanUpUndo();//check the number
of entites : if an error occurred, exit immidiate
ly. if (number_of_entities<0) return -1;//Step
_1: get flags if ( F2dCleanUpUndo( &trim_drawing)
== 0 ) return 0;#ifdef CKWIN
if ( *SwitchRedraw == 1)ck_level
s(CK_OFF,1,255);#endif// turn ON the level used to
store the trimmed entities.#ifdef VELLUMif ( *Swi
tchRedraw ==1)F2dCleanUpChangeDrawingColor(&trim_d
rawing);#endif#ifdef CKWINif ( *SwitchRedraw == 1)
ck_levels(CK_ON,TrimLevel, TrimLevel);if ( *Switch
Redraw== 1)ck_redraw( CK_PRIME_VP );#endifreturn
0;}/*=============================================
====================関数: 名称: TestUndoPreContr
ol記述: 元に戻す準備をする。戻り値:= 0: 成功裏に
完了; パラメータ:副関数:int F2dCleanUpUndoPre元
に戻す準備をする。================================
================================*/intTestUndoPreCo
ntrol( int *SwitchRedraw ){//external functionsint
F2dCleanUpUndoPre();//check the numberof entites:
if an error occurred, exit immidiately. if (nu
mber_of_entities<0) return -1;//Step_1: get flags
F2dCleanUpUndoPre( &trim_drawing );return0;}/*===
==================================================
============関数: 名称: TestSetUndoFlagViewsCont
rol記述: 元に戻すためフラグを設定する。flag=0:ビ
ューが存在しない。flag=1: ビューが存在する。戻り
値:= 0: 成功裏に完了; パラメータ:===============
=================================================*
/intTestSetUndoFlagViewsControl( int *SwitchRedraw
){ //set flag F2dCleanUpExcutedNo = 1; r
eturn0;}/*関数:==================================
==============================名称:TestDeleteView
sControl記述: ビユーを削除する。戻り値:= 0: 成功
裏に完了; パラメータ:副関数:int F2dCleanUpDelete
Viewsビユーを削除する。===========================
=====================================*/intTestDele
teViewsControl( int *SwitchRedraw ){//external fun
ctionsint F2dCleanUpDeleteViews();//check the numb
er of entites: if an error occurred, exit immidiat
ely. if (number_of_entities<0) return -1;//del
ete views F2dCleanUpDeleteViews( &trim_drawing );r
eturn0;}struct node *F2dCleanUpInputEntity(char *
prompt, struct drawing *select_drawing){int etype,
count, stat;unsigned long entid;struct node *ent
ity;//CK_ENTATT attr;if (( ck_getent(prompt, &etyp
e, &entid) != CK_NOERROR) || ( stat == CK_BACKUP )
|| (stat == CK_ESCAPE )) return 0;#ifdef DEBUGpri
nt("ID: %ld; #",entid);#endifcount=0; for (enti
ty=select_drawing->objects; entity && (co
unt<number_trimmed_entities) && (entity->id !=enti
d) && (entity->highlighted_id !=entid); e
ntity=entity->next) count++;if (count>
=number_trimmed_entities) return 0;else return ent
ity;}/*===========================================
======================関数: 名称: F2dVector記
述: ラインのユニットベクトルを計算する。戻り値:=
Out_v: 成功裏に完了;パラメータ:入力: 1 In_sp:
ラインエンティティ開始点座標2 In_ep: インエンティ
ティ終了点座標出力:1Out_v: ラインエンティティベク
トル==============================================
==================*/struct Vector F2dVector( struc
t Vector In_sp, struct Vector In_ep ){struct Vecto
rOut_v;Out_v.x = In_ep.x - In_sp.x;Out_v.y = In_e
p.y - In_sp.y;Out_v.z = In_ep.z - In_sp.z;returnOu
t_v;}/*===========================================
======================関数: 名称: F2dVectorUnit
記述: ラインのユニットベクトルを計算する。戻り
値:= Out_n: 成功裏に完了;< 0: エラーパラメータ:
入力: 1 In_v: ラインエンティティベクトル 出力:1
Out_n: ラインエンティティユニットベクトル=========
==================================================
======*/struct VectorF2dVectorUnit(struct VectorIn
_v){struct VectorOut_n;doubleLength = 0.0;//tolera
ncedoubletolerance = 0.0;tolerance = F2dCleanUpTol
erance;Length = sqrt( In_v.x*In_v.x + In_v.y*In_v.
y + In_v.z*In_v.z );//check lengthif (Length < tol
erance )returnOut_n;Out_n.x = In_v.x / Length;Out_
n.y = In_v.y / Length;Out_n.z = In_v.z / Length;re
turnOut_n;}/*=====================================
============================関数: 名称: F2dDista
ncePointLine記述: 点からラインまでの距離を計算す
る。戻り値:= 0: 成功裏に完了;パラメータ:入力: 1
In_sp: ラインエンティティ開始点座標2 In_ep: ライ
ンエンティティ終了点座標3 In_p: 点座標出力:1 Out
_d: 距離 =========================================
=======================*/doubleF2dDistancePointLin
e(//inputstruct Vector In_sp, struct Vector In_ep,
struct Vector In_p ){//external functionsstruct V
ector F2dVector();struct Vector F2dVectorUnit();//
definestruct VectorVe, Vne, Vp;double Out_d=0.0;//
get vectorVe = F2dVector( In_sp, In_ep );Vp = F2dV
ector( In_sp, In_p );//get unitvectorVne = F2dVect
orUnit( Ve );//compute distanceOut_d = sqrt( Vp.x*
Vp.x + Vp.y*Vp.y-(Vp.x*Vne.x + Vp.y*Vne.y) * (Vp.
x*Vne.x + Vp.y*Vne.y) );return Out_d;} 付録E ベンドモデルビユワ実施の例; CBendCADViewPartメンバ
関数の実施およびメニュー駆動関数の実施を含む。
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(RwS
cratchMatrix(), CREAL(- m_part_centroid.X()), CREA
L(-m_part_centroid.Y()), CRE
AL(- m_part_centroid.Z()), rwPRECONCAT); //RwForAl
lClumpsInScenePointer(m_scene, do_transformations,
(void *)RwScratchMatrix());RwTransformClump(clum
p, RwScratchMatrix(), rwPOSTCONCAT); }*///Now se
t the color of the clumps in the selectionset to r
ed.size = m_selection_set.list_size();if(size) {se
lected_items= new long [(size << 1) + 1]; // +1 f
or safety.m_selection_set.display(size, selected_i
tems);for(i=0; i < size; ++i) {data = (BV_SELECT_D
ATA *)selected_items[i*2 +1];if(! data) continue;i
f(data->edge) { // Edge is available, => n
ot a trivial bendline or body of something.parent_
tag = (selected_items[i<<1]/100000) + 10000;parent
_clump = 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 = Rw
FindTaggedClump(m_base_cl
ump, parent_tag); } else pare
nt_clump = m_base_clump; }key = selected_items[i
<<1]%100000;picked_clump = RwFindTaggedClump(paren
t_clump, key);if( (! data->edge) && ((key/10000) =
= 6) ) // Trivial bendline.RwForAllPolygonsInClum
pPointer(picked_clump, SetPolygonColor, (void *)gr
een_color); elseRwForAllPolygonsInClumpPointer(pic
ked_clump, SetPolygonColor, (void *)md_part_colo
r); }} if(selected_items) delete [] selected_
items; selected_items = NULL;}if(mi_simulation_is
_on) { // Restore camera parameters to simulatio
nvalues. RwSetCameraViewport(m_camera, 0, 0, mi_b
itmap_w , mi_bitmap_h); glViewport(0, 0, mi_bit
map_w, mi_bitmap_h); RwSetCameraVieww
indow(m_camera, (float)(md_sim_view_vol[0]), (floa
t)(md_sim_view_vol[1])); glMatrixMode(GL_PROJECTIO
N);glLoadIdentity();glOrtho(- md_sim_view_vol[0],
md_sim_view_vol[0],- md_sim_view_vol[1], md_sim_vi
ew_vol[1],//- 50000.0, 50000.0); - md_c
urrent_view_vol[2], md_current_view_vol[2]);glMatr
ixMode(GL_MODELVIEW);}}/*if(size) { for(i=0 ; i <
size; ++i) { BM_3D_BODY *b3;long three_d_type;
if(selected_items[i*2 +1]){ // エ
ッジが得られる => trivalベンドラインまたはフォーミ
ングではない. three_d_type = (selected_items[i<<
1]%100000)/10000; if((three_d_type >= 3) && (thre
e_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]/1000
00) + 10000; parent_clump = RwFindTaggedClump(m_b
ase_clump, parent_tag);}else {CBendCADDoc* pDoc =
GetDocument(); ASSERT_VALID(pDoc);
BM_PART *part = pDoc->get_part(); if
(! part) return;// 注意: この段階で部分がNULLであ
ることを期待しない。 BM_TOPOLOGY *topolog
y = part->get_topology(); if(! topology)
return;three_d_type = selected_items[i<<1]/100000;
// 用語の注意: three_d_type は実際ではな
い。 b3 = topology->map_id_into_pointer(t
hree_d_type); // b3->get_type()までthree_d_type.
three_d_type = b3->get_type(); parent_clump = m_b
ase_clump;}if(three_d_type == BM_ENTITY_TYPE_FACE)
{ for(j=0; j < 3; ++j) original_color[j] = m
d_face_color[j];}else if(three_d_type == BM_ENTITY
_TYPE_BENDLINE) { for(j=0; j < 3;++j) origina
l_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); RwForAllPolygonsInClumpPointer(picked_cl
ump, SetPolygonColor, (void *)original_color);
}}*/// This callback function performs the necess
ary transformations on each clump in the scene.//
Transform only parent clumps, since this automatic
ally transforms child clumps as well.static RwClum
p * RWCALLBACK do_transformations(RwClump *clump,
void *matrix) { int i = RwGetClumpNumChildren(clu
mp); if(i) {if( !(i = RwGetClumpNumPolygons(clum
p)) ) RwSetClumpState(clump, rwOFF);// Do not
render this clump if it has no polygons. RwTra
nsformClump(clump, (RwMatrix4d *)matrix, rwREPLAC
E); }return clump;}// This callback function set
s the color of the polygon to the required color.s
tatic RwPolygon3d * RWCALLBACK SetPolygonColor(RwP
olygon3d *polygon, void *color) { polygon = Rw
SetPolygonColor(polygon, CREAL(((double *)color)
[0]), CREAL(((double *)color)[1]),CREAL(((double
*)color)[2]));return polygon;}// This function set
s the pixel format of the view window to the kindt
hat// OpenGL likes. Note: Pixel format of a window
should be set onlyonce.BOOL CBendCADViewPart::Set
upPixelFormat(HDC hDC){ static PIXELFORMATDESCR
IPTOR pfd = { sizeof(PIXELFORMATDESCRIPTO
R), // size ofthis pfd 1,
// version numberPFD_DRAW_TO_WINDOW
| // support window PFD_SUPPOR
T_OPENGL | // support OpenGL PFD
_DOUBLEBUFFER,// double buffered PFD_TYPE_R
GBA, // RGBA type 24,
// 24-bit color depth0,
0, 0, 0, 0, 0, // color bits ignored
0,// no alpha buffer 0,// shift bit
ignored 0, //
no accumulation buffer 0, 0, 0, 0,
// accum bits ignored 32,
// 32-bit z-buffer0,
// no stencil buffer
0,// no auxiliary buffer PFD_MAIN_PLAN
E,// main layer 0,
// reserved 0, 0, 0
// layer masks ignored}; int pixelforma
t; if ( (pixelformat = ChoosePixelFormat(hDC, &
pfd)) == 0 ) { MessageBox("ChoosePixelFo
rmat failed");return FALSE; } if (SetPixelFo
rmat(hDC, pixelformat, &pfd) == FALSE) {
MessageBox("SetPixelFormat failed"); retu
rn FALSE;} // don’t need this call any more; t
he function will be calledfrom OnActivateView()//
and on OnViewWireframe() -- AK//CreateRGBPalette(h
DC); return TRUE;}unsigned char CBendCADViewPar
t::ComponentFromIndex(int i, UINT nbits, UINT shif
t){ unsigned char val; val = (unsigned char)
(i >> shift); switch (nbits) { case 1:
val &= 0x1;return oneto8[val]; case 2:
val &= 0x3; returntwoto8[val]; case
3: val &= 0x7; return threeto8[val];
default: return 0; }}void CBendCADViewPa
rt::CreateRGBPalette(HDC hDC){ PIXELFORMATDESCR
IPTOR pfd; LOGPALETTE *pPal; int n, i; CD
C dc; n = ::GetPixelFormat(hDC); ::DescribeP
ixelFormat(hDC, n, sizeof(PIXELFORMATDESCRIPTOR),
&pfd); if (pfd.dwFlags & PFD_NEED_PALETTE)
{ n = 1 << pfd.cColorBits; pPal = (P
LOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETT
E) + n * sizeof(PALETTEENTRY));
pPal->palVersion = 0x300; pPal->palNumE
ntries = n; for (i=0; i<n; i++) {
pPal->palPalEntry[i].peRed =
ComponentFromIndex(i, pfd.cRedBits, pfd.cR
edShift); pPal->palPalEntry[i].peGreen
=ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenS
hift); pPal->palPalEntry[i].peBlue =
ComponentFromIndex(i, pfd.cBlueB
its, pfd.cBlueShift); pPal->palPalEntry
[i].peFlags =0; } /* 省略時GDIパレッ
トを含むようにパレットを固定する */if ((pfd.cColor
Bits == 8) &&(pfd.cRedBi
ts == 3) && (pfd.cRedShift == 0) &&
(pfd.cGreenBits == 3) && (pfd.cGreenShift == 3)
&& (pfd.cBlueBits ==2) && (pfd.cBlueSh
ift == 6) ) {for (i = 1 ; i <= 1
2 ;i++) pPal->palPalEntry[defaultOv
erride[i]] = defaultPalEntry[i]; } d
c.Attach(hDC);CPalette*pOldPal; // since we
call this function not only when creating a view,
// but also each time activating, delete the prev
palette (if any) -- AKint resp = m_cPal.DeleteObje
ct(); m_cPal.CreatePalette(pPal); Lo
calFree(pPal); pOldPal = dc.SelectPalette(&
m_cPal, FALSE); dc.RealizePalette();
dc.Detach(); }}// This function computes the
bounding box parameters of the given part -// the
x, y and z extents, in globalcoordinates, for the
orientation specified by orient_matrix.// The comp
utation is done with respect to the BM_POINT centr
oid as origin.// It does so by taking the bbox of
each face, projecting each onto the coordinate //
axes, and then finding the extents along each axi
s. If threeD_flagis non-zero, the// three-d versio
n’s bbox is computed; else, the flat’s bbox is c
omputed. The results of the// computation are put
into thearry bbox_size[3]; if this pointer is zer
o, no computation// is performed. The offset, ie.
the vector from the centroid’s coords to the bbox
center’s coords,// is passed back in the pointer
to the BM_VECTOR.// Returns 1 if successful, 0 ot
herwise.int CBendCADViewPart::compute_part_bbox(BM
_PART *part, int threeD_flag, RwMatrix4d *orient_m
atrix,BM_POINT centroid, double *bbox_size, BM_VEC
TOR*offset) { BM_FACE *face = NULL; BM_BENDLINE
*bendline = NULL; BM_2D_BODY *two_d_body = NULL;
BM_LOOP *loop = NULL; BM_POINT dot1, dot2, dot
3, dot4; double left, right, top, bot, front, bac
k; // First tworefer to x direction, // las
t two to z direction. BM_VECTOR vec1; int first_
pass = 1; float rot_matrix[4][4]; if(! part) re
turn 0; if((part->get_number_of_faces() == 0) &&
(part->get_number_of_bendlines() == 0) ) return
0; if(! bbox_size) return 0; if(! part->get_num
ber_of_faces()) { // In this case, find bendline b
boxes. for(bendline = part->get_bendline_lis
t(); bendline; bendline = (BM_BENDLINE *)bendline-
>next()) { // First check that the bbox of the bl
oop is up to date; if notcompute bbox. if(threeD_
flag) two_d_body = bendline->get_3D_version();
else two_d_body = bendline->get_flat(); if(t
wo_d_body) loop = two_d_body->get_bloop(); else c
ontinue; if(! loop) continue; if(!(loop->is_bbox
_up_to_date())) loop->recompute_bbox(); // Now fi
nd the envelope (union) of the projected bboxes.
vec1 = BM_VECTOR(centroid.X(), centroid.Y(), centr
oid.Z()); dot1 = loop->get_bbox_p1() + (-1.0)*vec
1;// The bbox coordinates, dot2 = loop->get_bbox_
p2() + (-1.0)*vec1;// with respect to the dot3 =
loop->get_bbox_p3() + (-1.0)*vec1;// centroid as o
rigin. dot4 = loop->get_bbox_p4() + (-1.0)*vec1;
RwGetMatrixElements(orient_matrix, rot_matrix);
multiply_pt_by_matrix(&dot1, rot_matrix);// Tran
sform coords by the current multiply_pt_by_matrix
(&dot2, rot_matrix);// rotation matrix. multiply_
pt_by_matrix(&dot3, rot_matrix); multiply_pt_by_m
atrix(&dot4, rot_matrix); if(first_pass) { lef
t = __min(dot1.X(), dot2.X()); right = __max(d
ot1.X(), dot2.X()); bot = __min(dot1.Y(), dot
2.Y()); top = __max(dot1.Y(), dot2.Y()); b
ack =__min(dot1.Z(), dot2.Z()); front = __max
(dot1.Z(), dot2.Z()); first_pass = 0; } else
{ left = __min(left, dot1.X()); left = __
min(left, dot2.X()); right = __max(right, dot
1.X()); right = __max(right, dot2.X()); bot
= __min(bot , dot1.Y()); bot = __min(bot
, dot2.Y()); top = __max(top , dot1.Y());
top = __max(top, dot2.Y()); back = __min
(back , dot1.Z()); back = __min(back, dot2.
Z()); front = __max(front, dot1.Z()); front
= __max(front,dot2.Z()); } left = __min(left,
dot3.X()); left = __min(left, dot4.X()); right
= __max(right, dot3.X()); right = __max(right, d
ot4.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 = __m
ax(front, dot4.Z()); } bbox_size[0] =right -
left;bbox_size[1] = top - bot;// Copy bbox size
into the array passed.bbox_size[2] = front - bac
k;if(offset) // Copy the bbox center into the
pointer passed. *offset = BM_VECTOR((right + lef
t)/2.0, (top + bot)/2.0, (front + back)/2.0);mi_bb
ox_is_up_to_date = 1; return 1;} // Faces are av
ailable, so find bbox of faces. for(face = part->
get_face_list(); face; face = (BM_FACE *)face->nex
t()) { if(! face) break; // First check that
the bbox of the bloop is up to date; if not compu
te bbox.if(threeD_flag) two_d_body = face->get_3D
_version();else two_d_body = face->get_flat();if
(two_d_body) loop = two_d_body->get_bloop();else c
ontinue;if(! loop) continue;if(!(loop->is_bbox_up_
to_date())) loop->recompute_bbox();// Now find the
envelope (union) of the projectedbboxes.vec1 = BM
_VECTOR(centroid.X(), centroid.Y(), centroid.Z());
dot1 =loop->get_bbox_p1() + (-1.0)*vec1;// The bbo
x coordinates,dot2 = loop->get_bbox_p2() + (-1.0)*
vec1;// with respect to thedot3 = loop->get_bbox_p
3() + (-1.0)*vec1;// centroid as origin.dot4 = loo
p->get_bbox_p4() + (-1.0)*vec1; RwGetMatrixElem
ents(orient_matrix, rot_matrix);multiply_pt_by_mat
rix(&dot1, rot_matrix);// Transform coords by the
currentmultiply_pt_by_matrix(&dot2, rot_matrix);//
rotation matrix.multiply_pt_by_matrix(&dot3, rot_
matrix);multiply_pt_by_matrix(&dot4, rot_matrix);i
f(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(dot1.Z(), dot2.
Z()); front = __max(dot1.Z(), dot2.Z()); first_p
ass = 0;}else { left = __min(left, dot1.X());
left =__min(left, dot2.X()); right = __max(righ
t, dot1.X()); right = __max(right, dot2.X()); bo
t = __min(bot , dot1.Y()); bot = __min(bot,
dot2.Y()); top = __max(top , dot1.Y()); top
= __max(top , dot2.Y()); back = __min(back , d
ot1.Z()); back = __min(back , dot2.Z());front =
__max(front, dot1.Z()); front = __max(front, dot
2.Z());}left= __min(left, dot3.X());left = __min
(left, dot4.X());right = __max(right, dot3.X());r
ight = __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());f
ront = __max(front, dot4.Z()); } bbox_size[0] =
right - left; bbox_size[1] = top - bot;//Copy b
box size into the array passed. bbox_size[2] = fr
ont - back; if(offset) // Copy the bbox cente
r into the pointer passed.*offset = BM_VECTOR((rig
ht + left)/2.0, (top + bot)/2.0, (front + back)/2.
0); mi_bbox_is_up_to_date = 1; return 1;}// This
function computes the part’scentroid. This is do
ne with respect to// the original (given) coordina
tes of the part. If threeD_flag is non-zero, the//
three-d version’s centroid is computed; else, th
e flat’s centroid is computed.// The resultsare p
assed back in the pointer to a BM_POINT; if this p
ointer is NULL, no// computation is done. Returns
1 if successful, 0 otherwise.int CBendCADViewPar
t::compute_part_centroid(BM_PART *part, int threeD
_flag, BM_POINT *centroid) { BM_FACE *face; BM
_2D_BODY *two_d_body; BM_LOOP *loop; BM_POINT do
t1, dot2, dot3, dot4; double left, right, top, bo
t, front, back; // First two refer to x directio
n, // last two to z direction. int first_pass =
1; if(! part) return 0; if( (part->get_number_of
_faces == 0) && (part->get_number_of_bendlines ==
0) ) return 0; if(!centroid) return 0; for(fa
ce = 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; i
f not compute bbox.if(threeD_flag) two_d_body = f
ace->get_3D_version();else two_d_body = face->get
_flat();if(two_d_body) loop = two_d_body->get_bloo
p();else continue;if(! loop) continue;if(!(loop->i
s_bbox_up_to_date())) loop->recompute_bbox();// No
w find the envelope (union) of the projected bboxe
s.dot1 = loop->get_bbox_p1();dot2 = loop->get_bbox
_p2();dot3 = loop->get_bbox_p3(); dot4 = loop->get
_bbox_p4(); if(first_pass) { left = __min(dot
1.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()); fi
rst_pass = 0;}else { left = __min(left, dot1.
X()); left = __min(left, dot2.X()); right = __
max(right,dot1.X()); right = __max(right, dot2.
X()); bot = __min(bot , dot1.Y()); bot = __
min(bot , dot2.Y()); top = __max(top , dot1.Y
());top = __max(top , dot2.Y()); back = __min
(back , dot1.Z()); back= __min(back , dot2.Z());
front = __max(front, dot1.Z()); front = __max(f
ront, dot2.Z());}left = __min(left, dot3.X());le
ft = __min(left,dot4.X());right = __max(right, do
t3.X());right = __max(right, dot4.X());bot = __m
in(bot , dot3.Y());bot = __min(bot , dot4.
Y());top = __max(top , dot3.Y());top = __max
(top , dot4.Y());back = __min(back ,dot3.Z());ba
ck = __min(back , dot4.Z());front = __max(front,
dot3.Z());front = __max(front, dot4.Z()); } *cen
troid = BM_POINT((right + left)/2.0, (top + bot
)/2.0, (front + back)/2.0); // Copy centroid into
/*//ポインタが供給される。 if(threeD_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_part_centroid.set_Z
((front + back)/2.0); }*/ return 1;}// This func
tion multiplies a bend model point by a 4x4 Render
Ware transform matrix.// The function is destructi
ve.It is NOT a BMAPPView memberfunction.// Note th
at the point is considered to be a row vector; thi
s is// RenderWare’s (and the Bend Model’s) conve
ntion. static void multiply_pt_by_matrix(BM_POINT
*point, float rot_matrix[4][4]) { double x = poin
t->X(); double y = point->Y(); double z = point-
>Z(); point->set_X((x*rot_matrix[0][0] + y*rot_ma
trix[1][0] + z*rot_matrix[2][0])); point->set_Y
((x*rot_matrix[0][1] + y*rot_matrix[1][1] + z*rot_
matrix[2][1]));point->set_Z((x*rot_matrix[0][2] +
y*rot_matrix[1][2] + z*rot_matrix[2][2]));}// This
function outlines the rectangular region selected
by theuser.void CBendCADViewPart::outline_region
(void) { CClientDC view_dc(this); CPoint corner1
_curr = m_lt_btn_down_point, corner2_curr = m_lt_b
tn_down_point; CPoint corner1_prev = m_lt_btn_dow
n_point, corner2_prev =m_lt_btn_down_point; corne
r1_curr.Offset(m_current_point.x - m_lt_btn_down_p
oint.x, 0); corner2_curr.Offset(0, m_current_poin
t.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_previous_point.y - m_lt_b
tn_down_point.y); view_dc.SetROP2(R2_NOT); view_
dc.MoveTo(m_lt_btn_down_point);view_dc.LineTo(corn
er1_prev); view_dc.MoveTo(m_lt_btn_down_point);
view_dc.LineTo(corner2_prev); view_dc.MoveTo(corn
er1_prev); view_dc.LineTo(m_previous_point); vie
w_dc.MoveTo(corner2_prev); view_dc.LineTo(m_previ
ous_point); view_dc.MoveTo(m_lt_btn_down_point);
view_dc.LineTo(corner1_curr); view_dc.MoveTo(m_
lt_btn_down_point); view_dc.LineTo(corner2_curr);
view_dc.MoveTo(corner1_curr); view_dc.LineTo(m_
current_point); view_dc.MoveTo(corner2_curr); vi
ew_dc.LineTo(m_current_point);}//This function pro
cesses the hits record to pick out the edge(s) sel
ectedby the// user. If add_hit_to_list is non-zer
o, which it is if the control button is held down,
// the current hit, if any, is added to the select
ion set; else, the selection set// is cleared and
only the current hitis added to the list. If ther
e is no hit, the // selection set is cleared as we
ll, unless add_to_list is non-zero, in which case
// nothing happens. // This function recognizes tr
ivial bendlines and formings and modifies the sele
ction set// appropriately. void CBendCADViewPart::
process_hits_record(int add_hit_to_list){ RwClump
*picked_clump = NULL; RwClump *parent_clump = NU
LL;RwV3d vert; long parent_tag, clump_tag, three_
d_type = 0, offset = 0, key = 0; int num_hits = -
3, j; unsigned long z_max = 0UL, z_min = ULONG_MA
X, name_id = 0UL; unsigned int *ptr = mw_selected
_objects; BM_EDGE *edge = NULL;long old_data; if
(mi_show_solid) {// RenderWare picking. if(m_pi
ck.type == rwNAPICKOBJECT) {// No clump was picke
d. if(add_hit_to_list) return;else clear_sele
ction_set();return; } else if(m_pick.type ==
rwPICKCLUMP) {// Some clump was picked; process i
t. picked_clump =m_pick.object.clump.clump;ve
rt = m_pick.object.clump.wcpoint; RwTranslate
Matrix(RwScratchMatrix(), CREAL(md_x_trans), CREAL
(md_y_trans), CREAL(0.0), rwREPLACE); RwTran
sformMatrix(RwScratchMatrix(), md_rot_matrix, rwPR
ECONCAT); RwTranslateMatrix(RwScratchMatri
x(), CREAL(-m_part_centroid.X()), CREAL(- m_part_c
entroid.Y()),CREAL(- m_part_centroid.Z()), rwPRECO
NCAT); RwMatrix4d *inverse= RwCreateMatrix();R
wInvertMatrix(RwScratchMatrix(), inverse);RwTransf
ormPoint(&vert, inverse);RwDestroyMatrix(inverse);
parent_clump = RwGetClumpParent(picked_clump);pare
nt_tag = RwGetClumpTag(parent_clump);clump_tag = R
wGetClumpTag(picked_clump);if(parent_tag == 1) {//
The body of a face/bendline/forming was picked.ke
y = (clump_tag%10000)*100000 + clump_tag; if(m
_selection_set.find(key, NULL)) { m_
selection_set.remove(key, &old_data); // Re
move clump from selection set (toggle).if(old_dat
a) delete (BV_SELECT_DATA *)old_data;return;}else
{if(!add_hit_to_list) clear_selection_set(); // R
emove everything else in selection set, BV_SELECT_
DATA *data = new BV_SELECT_DATA;data->key = key;da
ta->edge = NULL; (data->world_pt) = BM_PO
INT(vert.x, vert.y, vert.z);m_selection_set.insert
(key, (long)data);// insert this key and data.retu
rn;}}// Now an edge was picked.key = (parent_tag%1
0000)*100000 +clump_tag; if(clump_tag) {// Safety
check; we expect clump_tag to be non-zero.if(m_sel
ection_set.find(key, NULL)){ m_selection_set.remo
ve(key,&old_data); // Remove clump from sel
ection set (toggle).if(old_data) delete (BV_SELECT
_DATA *)old_data;} else {if(! add_hit_to_list) cl
ear_selection_set(); // Remove everything else in
selection set. edge =map_list_name_to_bm_edge(par
ent_tag, clump_tag);BV_SELECT_DATA *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(key, (long)data);//
insert this key and data.}} } } else {// Ope
nGL Picking. num_hits = glRenderMode(GL_RENDE
R); // The numberof hits. if(n
um_hits == -1) { // Selecti
on buffer has overflowed. AfxMessageBox("Too
many entities selected; change view and try agai
n.");return; } if(num_hits == 0) {// No hit;
only a miss. if(add_hit_to_list) return;else
clear_selection_set();return; } // Process
the hits : find the edge with LOWEST z value of al
l the edges picked. for(j=0; j < num_hits; ++j)
{ ptr += 1; // Sk
ip the 1st element bec. it will always be 1,
if( (unsigned long)(*ptr) < (unsigned 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_id) {// Something
was selected. if(m_selection_set.find(name_i
d, NULL)) {m_selection_set.remove(name_id, &old_da
ta); //Remove edge fromselection set (toggle).i
f(old_data) delete (BV_SELECT_DATA *)old_data;}els
e {if(! add_hit_to_list) clear_selection_set();//
First, we massage the name_id into the format Rend
erWare picking uses.parent_tag = name_id/100000 +
10000;clump_tag = name_id%100000;edge = map_list_n
ame_to_bm_edge(parent_tag, clump_tag);BV_SELECT_DA
TA *data = new BV_SELECT_DATA;data->key = key;data
->edge = edge; (data->world_pt) =BM_POINT
(0.0, 0.0, 0.0);m_selection_set.insert(name_id, (l
ong)data);// insert this key and data.} } } r
eturn;}// This function maps a RenderWare parent c
lump and child clump pair to the // Bend Model edg
e whichthe child clump represents. The pointer to
the edge is returned.// Thisfunction only needs to
deal with "real" edges, ie. trivial bendlines and
// formings are filtered out by process_hits_recor
ds itself.BM_EDGE *CBendCADViewPart::map_list_name
_to_bm_edge(long parent_tag, long clump_tag){ lon
g three_d_name, three_d_type, loop_name, edge_nam
e, count = 0, offset = 0; BM_3D_BODY *three_d_bod
y = NULL; BM_2D_BODY *two_d_body = NULL; BM_LOOP
*loop = NULL; BM_EDGE *edge = NULL; BM_PART *pa
rt = NULL;BM_TOPOLOGY *topology = NULL; CBendCADD
oc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pa
rt = pDoc->get_part(); if(! part) return NULL;
//Note: we do not expect part to be NULL at this s
tage. topology = part->get_topology(); if(! topo
logy) return NULL; three_d_name = parent_tag%1000
0; three_d_body = topology->map_id_into_pointer(t
hree_d_name); // Now we have a pointer to the fa
ce/bendline to which the picked edge belongs. thr
ee_d_type = three_d_body->get_type(); if(three_d_
type == BM_ENTITY_TYPE_FACE)offset = 30000; if(th
ree_d_type == BM_ENTITY_TYPE_BENDLINE)offset = 600
00; if(three_d_type == BM_ENTITY_TYPE_FORMING)off
set =90000; loop_name = (clump_tag - offset)/100;
edge_name = (clump_tag -offset)%100; if(loop_na
me == 0) return NULL; // This should never bethe
case. // Now have the edge_name-th edge in the l
oop_name-th loop of the face/bendline/forming. //
Now we have the face/bendline to whichthe edge be
longs. if(mi_show_3d) two_d_body = three_d_body->
get_3D_version(); else two_d_body = three_
d_body->get_flat(); if(! two_d_body) return NULL;
if(loop_name == 1) loop = two_d_body->get_bloo
p(); else {count = 1; for(loop = two_d_body->g
et_first_hole(); loop; loop =(BM_LOOP *)loop->next
()) { if(! loop) return NULL; ++count; if(count
== loop_name) break;} } // Now we have the loop
to which the edge belongs. if(loop == NULL) retur
n NULL; // A trivial bendline waspicke
d. count = 0; for(edge = loop->get_first_edge();
edge; edge = (BM_EDGE *)edge->next()) {if(! edge)
break;++count;if(count == edge_name)break; } //
Now we have the edge itself. return edge;/* thr
ee_d_name= list_name/10000; loop_name = list_name
%10000; // loop_name-th の中の edge_name 番目の
edge loop_name /= 100; // loop of the three_d_
name 番目のthree-d-body, edge_name = list_name%10
0; //最初のthree-d-bodyとして最初のベンドライン
と共にに開始. if(three_d_name > (ml_num_bendlines
+ ml_num_faces)) return NULL; /
/ 描かれるものはフォーミングである。 if(! loop_na
me) return NULL; // 描かれるものはトリビアルなベ
ンドラインである。 if(three_d_name > ml_num_ben
dlines) { // three_d_body は面である。 for(thr
ee_d_body = part->get_face_list();three_d_body;
three_d_body = (BM_3D_BOD
Y *)three_d_body->next()) { if(! three_d_bod
y) return NULL; ++count; if((ml_num_bendlines +
count) == three_d_name) break;} } else { // thr
ee_d_body はベンドラインである。 for(three_d_bo
dy = part->get_bendline_list(); three_d_body;
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_body = three
_d_body->get_flat(); if(! two_d_body) return NUL
L; if(loop_name == 1) loop = two_d_body->get_bloo
p();else { count = 1; for(loop = two_d_body-
>get_first_hole(); loop; loop = (BM_LOOP *)loop->n
ext()) { if(! loop) return NULL; ++count; if(co
unt == loop_name) break;} }// この時点でエッジが
属するループを持つ。count = 0; for(edge = loop->g
et_first_edge(); edge; edge = (BM_EDGE *)edge->nex
t()) {if(! edge) break;++count;if(count == edge_na
me) break;} return edge;*/} // This function ret
urns the number of items currently in the selectio
n set.long CBendCADViewPart::get_number_of_selecte
d_items(void){ return m_selection_set.list_siz
e();}/* これにより、他のクラスが選択セットを得るこ
とができる。選択された項目は、配列selected_items_a
rray 内でパスバックされる; それは、この配列が十分
な大きさであることを保証するユーザの義務である。サ
イズnum_requested*2 の配列は確かに十分である。この
関数は、もし多くのものが得られるときは、 num_reque
sted 項目までパスバックする。戻り値は、実際にパス
バックされた項目の個数である。配列中の復帰された項
目のフォーマットは次のように与えられる。 selected_
items_array[2*i -2] は描かれたエッジのOpenGL Displ
ay List idを含み、またselected_items_array[2*i -1]
はそのエッジに対するベンドモデルポインタを含む。
例えば、 selected_items_array[0], selected_items_a
rray[1]は, 選択セットなど,選択セット中のnum_reques
ted番目の項目に対する配列[2*num_requested -2],配列
array[2*num_requested -1] までの全てのものを含む。
エッジポインタがNULLのときは更に、 N をこのエッジ
のopenG1 display list id (N は長いタイプ)とする
必要がある。ケース A): もし N/10000 > (num_bendli
nes_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)/100=0 である。
ユーザは、たまたま曲げてない第三番面目のベンドライ
ンを取り上げている。(あなたが驚いても、この部分は
少なくとも3 個のベンドラインを持つことが保証され
る。)*/long CBendCADViewPart::get_selected_items(l
ong num_requested, long *selected_items_array) {
if(selected_items_array == NULL) return 0; long i
= m_selection_set.display(num_requested, selected
_items_array); return i;} // This allows others
to clear the selection set.void CBendCADViewPart::
clear_selection_set(void){int size = m_selection_s
et.list_size(); long *array = new long[(size<<1) +
1]; m_selection_set.display(size,
array);for(long i=0; i < size; ++i) { if(array[(i
<<1) + 1]) delete (BV_SELECT_DATA*)array[(i<<1) +
1];} m_selection_set.remove();delete [] array;}//
Thisfunction writes a RenderWare matrix’s rotati
on part into an array[16],which can be used by// O
penGL. int CBendCADViewPart::convert_rw_matrix_to_
gl_array(RwMatrix4d *rw_matrix, double *array){ R
wReal rw_array[4][4], *test; test = RwGetMatrixEl
ements(rw_matrix, rw_array); if(! test)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] = array[11] = 0.
0; return 1;} // This function allows you to s
et the drawing mode: show_solid = 1 for solid, 0 f
or wireframe.// This function assumes that the par
t has not changed.void CBendCADViewPart::set_drawi
ng_mode(int show_solid){ if(show_solid) OnViewSha
ded();else OnViewWireframe();}// This function all
ows you to set the current view of thepart: show_3
d = 1 for 3d version,// 0 for flat.// This functio
n assumesthat the part has not changed.void CBendC
ADViewPart::set_current_view(int show_3d){if(show_
3d) OnShow3d();else OnShowFlat();}// This allows y
outo set both solid/wireframe (show_solid = 0/1) a
nd flat/3d_version (show_3d = 0/1).// If flat is a
sked for, the picture shown is top view, zoomed-al
l.// If 3d is asked for and flat is currently in v
iew, the picture shown is 3d, isometric, zoomed-al
l.// If 3d is asked for and 3d is already currentl
y in view, the view volume is not changed.// If pa
rt_has_changed is not zero, re-faceting is done.vo
id CBendCADViewPart::set_drawing_view_mode(int sho
w_solid, int show_3d, int part_has_changed){int sh
ow_3d_isometric = 0;if( (! mi_show_3d) && (show_3
d) )show_3d_isometric = 1;mi_show_solid = show_sol
id;mi_show_3d = show_3d; int i; BM_PART *part =
NULL; CBendCADDoc* pDoc = GetDocument(); ASSERT_
VALID(pDoc); part = pDoc->get_part(); if(! part)
{ mi_part_is_up_to_date = 0; return; }mi_par
t_is_up_to_date = 1;if(part_has_changed) { comp
ute_part_centroid(part, 0, &m_flat_part_centroid);
// Compute 3d and flat part centroids. compute
_part_centroid(part, 1, &m_3d_part_centroid); }if
(mi_show_solid) { // Renderware stuff.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); if( (! i) || (! m
_3d_base_clump) ) return;}RwRemoveClumpFromScene(m
_base_clump); m_base_clump = m_3d_base_clump;
RwAddClumpToScene(m_scene, m_base_clump);}else
{ if(part_has_changed || (! m_flat_base_clump))
{ i = facet_part_rw(part, &m_flat_base_clum
p, mi_show_3d, md_part_color); if( (! i) ||
(! m_3d_base_clump) ) return;}RwRemoveClumpFromSce
ne(m_base_clump); m_base_clump =m_flat_base_clu
mp; RwAddClumpToScene(m_scene, m_base_clump);}}
else {// OpenGl stuff. i = prepare_display_lis
t(part, mi_show_3d, 1, 0, 1,1, md_face_color, md_b
endline_color); if(! i) { mi_display_list_
is_up_to_date = 0; return; } mi_display_l
ist_is_up_to_date = 1; if(mi_show_3d) { m
i_3d_is_up_to_date = 1; mi_flat_is_up_to_date =
0;}else { mi_3d_is_up_to_date = 0; mi_fla
t_is_up_to_date= 1;}} mi_bbox_is_up_to_date = 0;i
f(mi_show_3d) m_part_centroid = m_3d_part_centroi
d;else m_part_centroid = m_flat_part_centroid;if(p
art_has_changed) {ml_num_faces = part->get_number_
of_faces();ml_num_bendlines = part->get_number_of_
bendlines();ml_num_formings = part->get_number_of_
formings();} ml_last_function_chosen = RETURN_FRO
M_DIALOG_MODE;if(show_3d_isometric) { OnZoomAl
l();return;}if(! mi_show_3d) { OnViewTop();retur
n;}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, i
nt reverse_bit, BM_AD_dim
_corner **prev, BM_BENDLI
NE *adj_bendline) ;// thi
s constructor is for crea
ting a dimension point th
at has 3 pointsin it.// B
M_AD_dim_corner(BM_POINT
const& p, BM_POINT const&
p1, BM_POINT const& p2,
BM_AD_bendline *bend, BM_
3D_BODY *body_required_vi
sible, BM_VECTOR const& o
pening_direction, int rev
erse_bit, BM_AD_dim_corne
r **prev, BM_BENDLINE *ad
j_bendline) ;// to assign
one dimension point to a
nother dimension point//
it copies contents exactl
y. not sure if it is a ve
ry useful function.// voi
d operator=(BM_AD_dim_cor
ner const &) ;// thisfunc
tion will return TRUE iff
the given point is, for
the purpose of drawing di
mensions,// the same as t
his point. // Two dimensi
on points points are equi
valent iff the point p of
one of them is on the//
line definedby the line
(point p, opening directi
on) of the other dimensio
n point,// and their open
ing directions match.// /
/ here we depend on the f
act that opening vectors
are normalized.// // it r
eturns 2 iff both points
p match, otherwise 1.// i
nt operator==(BM_AD_dim_c
orner const& another_dim_
point) ;} ;/*********** *
********* ********** ****
****** ********** *******
*** ********** **********
********** この種の対象物は、1ベンド
ラインに係わる自動寸法化データを表す。ベンドライン
に対する基本のAD操作は隣接するフランジ長さを描く
ことである。技術的注意 :- tベンドラインディメンシ
ョンポイントとフランジディメンションポイントの開放
方向ベクトルは相関付けされない。それは、あなたは、
同じ開放方向を持つ2点に対シテチェックするべきであ
る。- アルゴリスム:先ず、我々は全てのベンドライン
に対する全てのベンドラインディメンションポイントを
計算する。次に、我々は、全てのベンドラインに対する
全てのフランジディメンションポイントを計算する。そ
の理由は、我々がフランジディメンションポイントを計
算するとき、フランジ内の、および他のベンドラインに
隣接する幾つかのエッジがあるということである。全て
のベンドラインディメンションを先ず計算するときは、
他のBM_AD_bendline構造のベンドラインディメンション
ポイントからこれらのベクトルを取ることが出来る。**
******** ********** ********** ********** ********
** ********** ********** ********** ********** */c
lass BM_AD_bendline{friend BM_AUTO_DIMENSION ;frie
nd BM_AD_dim_corner ;/*********** ********** *****
***** ********** ********** ********** **********
********** **********全てのデータメンバはprivateな
ものである。********** ********** ********** *****
***** ********** ********** ********** **********
***********/private :/*********** ********** *****
***** ********** ********** ********** **********
********** **********これらのデータメンバはコンス
トラクタにより設定される。********** ********** **
******** ********** ********** ********** ********
** ********** ***********/// information stored in
this BM_AD_bendline object refers to this bendlin
e.// ie. this dimension point is drawn to show the
flange length of this bendline.// BM_BENDLINE *be
nd ;// thisobject belongs to this Auto-Dimension o
bject.// BM_AUTO_DIMENSION *parent ;/*********** *
********* ********** ********** ********** *******
*** ********** ********** **********これらのデータ
メンバは、ベンドラインディメンションポイントデータ
構造が、 BM_AD_bendline::compute_BM_AD_bendlin
e(...).で計算されるとき計算される。********** ****
****** ********** ********** ********** **********
********** ********** ***********/// if FALSE, th
is data for this object has not been yet computed,
or the computation failed.// this means that this
object will always be ignored, no matter what.//
this can be set to TRUE only by BM_AD_bendline::co
mpute_BM_AD_bendline(...).// int data_valid ;// nu
mber of adjacent bodies for whichwe have to draw d
imensions. either 0, 1 or 2.// int num_of_adjacent
_bodies ;// every bendline is adjacent to at most
two bodies.// either of these can be NULL. you sho
uld always check for that.// // adj_body1 is thead
jacent 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_body2;// this
is the flange length with respect to each of the a
djacent bodies// double fl1 ;double fl2 ;/*These p
arameters are computed some time during the proces
s and are needed later, so forperformance reasons
we store them so that we don’t have to recompute
them later.Each of them is avector pointing toward
s the adjacent body (from the bendline) and isona
plane tangent to end end-point of the bend-arc tou
ching the adjacent body.*/BM_VECTOR side_vector1 ;
BM_VECTOR side_vector2 ;/*これらのパラメータは、プ
ロセス中にしばしば計算され、後に必要とされ、そこで
性能理由に対して我々はそれらを、我々がそれらを後に
再計算する必要がないように格納する。それらの各々は
(ベンドラインから)隣接体に向け指示するベクトルで
あり、隣接体に接触するベンドアークの端点に対して接
線をなす平面上にある。 これらは主要データ構造の幾
つかである。 各々の隣接体に対して、ベンドラインの
各々の端点(すなわち、左および右)に対して1つの2
つ端点を持つ。これらの点は、フランジ長に対する寸法
がベンドラインで(すなわち、ベンドラインの側部で)
描くことが出来る点を特定する。注意:現在(04/0
2/96)、我々は全てのベンドラインにおいてディメ
ンションを描くため正確に2つの可能な点を考える。こ
れらの2つの点はベンドラインセンタラインの方向のベ
ンドラインの2つの最端点である。注意:これらはベン
ドラインのベンドラインディメンションポイントと呼ば
れる。注意:これらの点は、例えadj body1お
よびadj body2が空であっても常に計算され
る。*/BM_AD_dim_corner bend_body1_point_left, bend
_body1_point_right ;BM_AD_dim_corner bend_body2_po
int_left, bend_body2_point_right ;// these variabl
es indicate whether theleft(right) bendline dimens
ion points // with respect to adj-body1 and adj-bo
dy2 are respectively equivalent.// these points sh
ould be computedright after bend_body1_point_left,
bend_body1_point_right,// bend_body2_point_left,
bend_body2_point_right are computed.// // if 0, th
ey are notequivalent.// if 2, they are equivalent,
and points p match.// if 1, they are equivalent,
but points p don’t match (ie. on the same line, b
utsome distance apart).// // for us, equivalence v
alue 2 is the only really useful one, because in t
hat case we can // trust that when one is 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 pointers, but
the contents are equivalent.// int body12_left_th
e_same ;intbody12_right_the_same ;/*ここにディメン
ションポイントの2つのリストがある。1つはadj-body
に関するもので、他はadj−body2に関するもの
である。両リストはフランジ長ディメンションポイント
である点を含む。注意:これらはベンドラインのフラン
ジディメンションポイントと呼ばれる。*/BM_AD_dim_co
rner *body1_points ;BM_AD_dim_corner *body2_points
;/*********** ********** ********** ********** **
******** ********** ********** *******************
*これらのデータメンバは、ディメンションが描かれる
とき用いられる。********** ********** ********** *
********* ********** ********** ********** *******
*** ***********/// if this is TRUE, this bendline
structure should be ignored for the purpose of dra
wing dimensions.// this is usually used when we ha
ve a simultaneous bendline. in that case we have t
odraw// dimensions for only one of them, the rest
should be ignored.// int ignore ;// if TRUE, the a
djacent body already has its flange length drawn./
/ // if the value is 2, this bendline drew the fla
nge dimension with respect to the adj body.// if t
he value is 1, some other bendline drewthe flange
dimension with respect to the adj body.// int body
1_drawn ;int body2_drawn ;// when we draw flange l
ength for adjacent bodies, we will memorize the po
int at which the// dimensions were drawn.// actual
ly the dimensions are always drawn between two poi
nts - one at the bendline,// the other at the fart
hest point on the adjacent body (ie. bendline dime
nsion point and// flange dimension point).// // th
e reason we need tomemorize these points is that s
ometimes the flange-length-dimension// with respec
t to one bendline is also the flange-length dimens
ion with respect to the// other bendline. in that
case we want to avoid drawing the same thing twic
e.// // the first two points are bendline dimensio
n points.// other two are flange dimension points.
// // reason #2 : when we drawbendline dimensions
with respect to adj-body1 and adj-body2,// it depe
nds whether the bend angle is acute or not. if the
bend angle is not morethan// 90 degrees, then mos
t likely we will be able to use the same dimension
-point at the bendline// to draw both flange lengt
h’s. However, if the bend angle is more than 90 d
egrees, we will// be using the tangent-dimension-p
oint at the bendline and these points are differen
t for// each adjacent body. In general, we want to
know, before we draw a dimension-point at a// ben
dline, if we can use any of the dimension-points a
lready drawn at this bendline.// // note these poi
nts do not have to part ofthis AD_bendline structu
re.// BM_AD_dim_corner *drawn_bend_dim_point1 ;BM_
AD_dim_corner *drawn_bend_dim_point2 ;BM_AD_dim_co
rner *drawn_flange_dim_point1 ;BM_AD_dim_corner *d
rawn_flange_dim_point2 ;/*********** ********** **
******** ********** ********** ********** ********
** ********************Privateメンバ−関数********
** ********** ********** ********** ********** ***
******* ********** ********** ***********/// This
function computes bendline dimension points of thi
s BM_AD_bendline structure.// Note that bend-dimen
sion points will always be computed, even if adj_b
ody1 and adj_body2// are NULL.// int compute_BM_AD
_bendline(void) ;// This function computes flange
dimensions points of this BM_AD_bendline structure
// with respect to one adjacent body.// int compu
te_BM_AD_flange_points(BM_3D_BODY *adj_body) ;// T
his function computes the visibility of all bendli
ne dimension points of the bendline.// note the th
e visibility of bend-dimension points with respect
to adj-body1 is always// computed, even if adj_bo
dy1 pointer is NULL.// This is needed for drawing
bendline info-boxes.// void compute_bendline_dim_p
oints_visibility(void) ;//this function computes w
hich dimension points are best to draw flange leng
th for this bendline.// // this function does it s
trictly for one bendline.// void compute_dim_point
s_to_display_indiv(BM_AD_bendline *best_AD_bendlin
e[2] /* best AD_bendline structure so far */, BM_A
D_dim_corner*bodies_bend_flange[6] /* 0,1 is bend-
dim points; 3,4 is flange-dim points; 4,5 is flang
e lists */,double distance_and_z[4] /* 0,1 is dist
ance;3,4 is z-buf */) ;// this function does it fo
r a given bendline, takinginto account simultaneou
s bendlines.// this function uses the previous fun
ction.// void compute_dim_points_to_display(void)
;// this function draws flange length dimensions
for this bendline.// it uses the information compu
ted by compute_dim_points_to_display() function.//
void draw_dimension_points(void) ;/*********** **
******** ********** ********** ********** ********
** ********** ********** **********公共メンバ−関
数********** ********** ********** ********** ****
****** ********** ********** ********** **********
*/ public :// some trivial constructo
rs,destructors.BM_AD_bendline(BM_AUTO_DIMENSION *o
wner, BM_BENDLINE *bendline) ;~BM_AD_bendline(voi
d) ;} ;/*********** ********** ********** ********
** ********** ********** ********** ********** ***
******* この対象物は部分に対して自動ディメンション
を生成するために用いることが出来る。********** ***
******* ********** ********** ********** *********
* ********** ********** ********** */class BM_AUTO
_DIMENSION{friend BM_AD_dim_corner ;friend BM_AD_b
endline ;/*********** ********** ********** ******
**** ********** ********** ********** ********** *
*********すべてのデータメンバはprivateである。****
****** ********** ********** ********** **********
********** ********** ********** ***********/priva
te :// this is the document to which this auto-dim
object is attached to.// also, this is where we g
et the part.// CBendCADDoc *doc ;// view in which
we draw the dimensions.// usually the view attache
d to the document.// CBendCADViewPart*view ;int vi
ew_size_x, view_size_y ;// device context in which
we drawthe dimensions.// CDC *dc ;// this 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 of the meta
l thickness// double half_metal_thickness ;// if T
RUE, we need to recompute auto dimension bendline
and point data structures// int dirty ;// number o
f bendlines in the part// int num_of_bendlines ;//
this is an array of bendlines for which flange le
ngth has to be drawn.// BM_AD_bendline **bends ;//
this is the distance in object space that gets ma
pped into one pixel on the screen.// we use it to
draw lines of fixed pixel length (in that case obj
ect-space length varies).// double object_space_pe
r_pixel ;// if this variable is TRUE, it will set
the flag which will trigger// auto-dimensions tobe
drawn to FALSE in the view class, once dimensions
are drawn.// however, once it is done, this varia
ble will be set to FALSE automatically.//int reset
_view_to_false_once_drawn ;// every time we constr
uct new dim-point data structures, we set this to
FALSE.// when points which can beignored in solid
mode have been computed, we set it to TRUE.// int
points_to_ignore_in_solid_computed ;// pointer to
mesh for determining clearareas of the screen to d
raw dimension info//CAutoDimRgnMesh *pMesh;// regi
on to keep track of dirty screen areas//CRgn* pDir
tyRegion;public:// Booleans for the show state of
dimension info//BOOL m_bShowFlangeDim;BOOLm_bShowB
endDim;BOOL m_bShowPartDim;// COLORREFs for drawin
g dimensions//COLORREF m_crFlange;COLORREF m_crBen
d;COLORREF m_crPart;// pointers tofonts//CFont* m_
pFlangeFont;CFont* m_pBendFont;CFont* m_pPartFont;
// line and arrow parameters//int m_nLineStyle;int
m_nLineWeight;// in pixelsint m_nArrowStyle;int m
_nArrowAngle;// in degreesint m_nArrowLength;// in
pixels/*********** ********** ********** *********
* ********** ********** ********** ********** ****
******Privateメンバ関数********** ********** *****
***** ********** ********** ********** **********
********** ***********/private :// This function i
s used to propagate the effects of drawing a flang
e length for a given bendline,// to account for th
e fact that the flange dimension point is adjacent
to the given adj-body.// it returns TRUE iff the
adj-bend will be marked as drawn as well with resp
ectto the given flange.// int compute_effects_flan
ge_length_drawn(BM_BENDLINE *bendline, BM_3D_BODY
*adj_body /* flange length with respect to this bo
dy are being drawn */, BM_AD_dim_corner *bend_dim_
point /* bend dimpoint for bendline */, BM_AD_dim_
corner *flange_dim_point /* flange dimpoints for b
endline */, BM_BENDLINE *adj_bend /* flange dim po
ints is adjacent to this bendline */) ;// this fun
ction returns a pointer to the BM_AD_bendline stru
cture that contains data // about the given bendli
ne.// BM_AD_bendline *get_AD_bend_structure(BM_BEN
DLINE *bendline) ;// thisfunction will return TRUE
iff adj_bend has a flange-dimension point withres
pect to the// given flange, that is adjacent to th
e given bendline.// // a handy function.// int che
ck_two_bendlines_adjacent_to_same_flange(BM_BENDLI
NE *bendline, BM_3D_BODY *flange, BM_BENDLINE *adj
_bend) ;// just a debug function// void test_draw
(void) ;// Check if we can ignore some points in s
olid mode.// // in solid mode we will be using thi
s heuristic in order to save time.// when two bend
lines are using equivalent flange-dimension points
for (potentially)// displaying flange-length, we
will only compute the visibility information only/
/ for the bendline (ofthese two bendlines) which h
as the higher idx.// void compute_points_to_ignore
_in_solid(void) ;// this function draws a box with
bendline data for every bendline.// void draw_ben
dline_data(CDC *pdc) ;/*********** ********** ****
****** ********** ********** ********** **********
********** **********公共メンバ関数********** ***
******* ********** ********** ********** *********
* ********** ********** ***********/public :BM_AUT
O_DIMENSION(CBendCADDoc *BendCAD_doc) ;~BM_AUTO_DI
MENSION(void) ;// this function returns a (p->p2)
vector for a given bendline with respect to a give
n adj-body.// // It also computes a line between t
he p2 points of thebend dimension points of the ad
jacent bendline // with respect to this flange.//
BM_VECTOR const& compute_bend_direction_vector(BM_
BENDLINE *bendline, BM_3D_BODY *adj_body, BM_LINE
*p2_line) ;// destroy the contentsof this Auto-Dim
ensions object,// void delete_contents(void) ;// T
o seta new part. This updates the view class point
er as well.// void set_part(BM_PART *new_part) ;//
to force AD to recompute the dimension points.//i
nline void invalidate(void) { dirty = 1 ; }// get
current view type when points were computed// inli
ne int get_view_type(void) const { returnview_type
; }// this function will build auto dimension ben
dline and point data structures.// // This is the
main function for computing dimension points.// in
t compute_auto_dimension_data(void) ;// draw flang
e dimension data//void draw_dim_point(BM_AD_dim_co
rner *bend_dim_point, BM_AD_dim_corner *flange_dim
_point, CBendCADViewPart *view, CDC *dc, double ob
ject_space_per_pixel);// to draw part dimensions i
n this device context//int draw_auto_dimensions(CD
C *target_dc) ;// Used with draw_auto_dimensions t
o construct a geometric pen// with user-defined st
yles. This is necessary to draw patterned thick li
nes.//CPen* create_auto_dim_pen(CPen*pPen, int nLi
neStyle, int nLineWeight, COLORREF cr) ;// this wi
ll enableus to draw part dimension only once//inli
ne void disable_view_dimensions_flag_next_time(voi
d) { reset_view_to_false_once_drawn = 1 ; }} ;#end
if// BMAPI_AUTO_DIM_HXX_INCLUDED 付録G 機能を描く自動寸法化の例。これらの関数は、デイメン
シヨンポイントが既に計算されていることを仮定する。
数は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]−>b
end_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_rig
ht) ;}}else bend_points
[j] = &(bendlines[j]−>ben
d_body1_point_right) ;}fo
r (j = i ; j <num_bends_t
o_be_drawn ; j++) {if ((b
endlines[j]−>bend_body1_p
oint_left).visible) {if
(! (bendlines[j]−>bend_bo
dy1_point_right).visible)
bend_points[j] = &(bendl
ines[j]−>bend_body1_point
_left) ;else {if ((bendli
nes[j]−>bend_body1_point_
left).screen_x > (bendlin
es[j]−>bend_body1_point_r
ight).screen_x) bend_poin
ts[j] = &(bendlines[j]−>b
end_body1_point_left) ;el
se bend_points[j] = &(ben
dlines[j]−>bend_body1_poi
nt_right) ;}}else bend_po
ints[j] = &(bendlines[j]−
>bend_body1_point_right)
;}/*ここで描画の準備が完了する。*/static cha
r info_box_text[256] ;static POINT box_corners[5]
;static POINT arrow[3] ;BM_BENDLINE *b ;BM_BEND_O
P *bop ;BM_2D_BODY*b_body ;/*左側を描く。*/int lef
t = 3 ;int top ;if (0 == i) goto draw_right_side ;
// compute vertical space per info-boxvert_space_p
er_box = view_size_y / i ;// compute vertical offs
et for the top-left corner of theinfo-boxoffset =
(vert_space_per_box - box_height) >> 1 ;box_corner
s[0].x = box_corners[3].x = box_corners[4].x = lef
t ;box_corners[1].x = box_corners[2].x = left + bo
x_width ;for (j = 0 ; j < i ; j++) {b = bendlines
[j]->bend ;bop = b->get_bend_op() ;if (NULL == bo
p) continue ;// 043996KKif (view_type) b_body = b-
>get_current_3D_version() ;else b_body = b->get_fl
at() ;top = j*vert_space_per_box + offset ;box_cor
ners[0].y = box_corners[1].y = box_corners[4].y =
top ;box_corners[2].y = box_corners[3].y = top + b
ox_height ;sprintf(info_box_text,"A:%5.1f,L:%6.2
f",(bop->get_bend_angle2())*57.29578,(b_body->get_
current_center_line()).get_len()) ;pdc->TextOut(5,
top, info_box_text, strlen(info_box_text)) ;switc
h (bop->get_type()) {case BM_TYPE_BEND_OP_REGULAR
:sprintf(info_box_text,"R:%5.2f,D:%5.2f",((BM_BEN
D_OP_REGULAR *) bop)->get_bend_radius(),bop->get_b
end_deduction()) ;pdc->TextOut(5, top + font_heigh
t, info_box_text, strlen(info_box_text)) ;break ;c
ase BM_TYPE_BEND_OP_CONIC :// TODO : implementconi
c bend op.break ;}// draw boxpdc->Polyline(box_cor
ners, 5) ;// drawarrowarrow[0].x = left + box_widt
h ;arrow[0].y = top + half_box_height;// calculate
arrow tip at fixed percentage length in from end
pointCPoint ptLeft(bendlines[j]->bend_body1_point_
left.screen_x, bendlines[j]->bend_body1_point_lef
t.screen_y);CPoint ptRight(bendlines[j]->bend_body
1_point_right.screen_x, bendlines[j]->bend_body1_p
oint_right.screen_y);CSizesizeDiff = ptRight - ptL
eft;CPoint ptArrowTip;if ( bend_points[j] == &(ben
dlines[j]->bend_body1_point_left) ){ptArrowTip.x =
ptLeft.x + sizeDiff.cx/8;ptArrowTip.y = ptLeft.y
+ sizeDiff.cy/8;}else{ptArrowTip.x = ptRight.x - s
izeDiff.cx/8;ptArrowTip.y = ptRight.y - sizeDiff.c
y/8;}arrow[1].x = ptArrowTip.x;arrow[1].y = ptArro
wTip.y;pdc->Polyline(arrow, 2) ;//change to solid
pen for arrow headsCPen* pArrowPen = new CPen(PS_S
OLID,BCAD_context.m_nBendLineWeight, BCAD_context.
m_crBend);CPen* pOldPen = pdc->SelectObject(pArrow
Pen);// compute arrow headCAutoDimArrow arrowBend
(ptArrowTip,CPoint(arrow[0].x,arrow[0].y),BCAD_con
text.m_nArrowAngle,BCAD_context.m_nArrowLength);//
draw arrow headarrowBend.DrawHead(dc);pdc->Select
Object(pOldPen);delete pArrowPen;}/*右側を描く。*/
draw_right_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_drawn - i) ;// compute vertical offset for t
he top-left corner of the info-boxoffset = (vert_s
pace_per_box - box_height) >> 1 ;box_corners[0].x
= box_corners[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_dra
wn ; j++) {b = bendlines[j]->bend ;bop = b->get_be
nd_op() ;if (NULL == bop) continue ;// 043996KKif
(view_type) b_body = b->get_current_3D_version() ;
else b_body = b->get_flat() ;top = (j - i)*vert_sp
ace_per_box + offset ;box_corners[0].y = box_corne
rs[1].y = box_corners[4].y = top ;box_corners[2].y
= box_corners[3].y = top + box_height ;sprintf(in
fo_box_text,"A:%5.1f,L:%6.2f",(bop->get_bend_angle
2())*57.29578,(b_body->get_current_center_line()).
get_len()) ;pdc->TextOut(box_x, top, info_box_tex
t, strlen(info_box_text));switch (bop->get_type())
{case BM_TYPE_BEND_OP_REGULAR :sprintf(info_box_t
ext,"R:%5.2f,D:%5.2f",((BM_BEND_OP_REGULAR *) bop)
->get_bend_radius(),bop->get_bend_deduction()) ;pd
c->TextOut(box_x, top + font_height, info_box_tex
t, strlen(info_box_text)) ;break ;case BM_TYPE_BEN
D_OP_CONIC ://TODO : implement conic bend op.break
;}// draw boxpdc->Polyline(box_corners, 5) ;// dr
aw arrowarrow[0].x = left ;arrow[0].y = top + half
_box_height ;// calculate arrow tip at fixed perce
ntage length in from end pointCPoint ptLeft(bendli
nes[j]->bend_body1_point_left.screen_x, bendlines
[j]->bend_body1_point_left.screen_y);CPoint ptRigh
t(bendlines[j]->bend_body1_point_right.screen_x, b
endlines[j]->bend_body1_point_right.screen_y);CSiz
e sizeDiff = ptRight - ptLeft;CPoint ptArrowTip;if
( bend_points[j]== &(bendlines[j]->bend_body1_poi
nt_left) ){ptArrowTip.x = ptLeft.x + sizeDiff.cx/
8;ptArrowTip.y = ptLeft.y + sizeDiff.cy/8;}else{pt
ArrowTip.x =ptRight.x - sizeDiff.cx/8;ptArrowTip.y
= ptRight.y - sizeDiff.cy/8;}arrow[1].x = ptArrow
Tip.x;arrow[1].y = ptArrowTip.y;pdc->Polyline(arro
w, 2);// change to solid pen for arrow headsCPen*
pArrowPen = new CPen(PS_SOLID, BCAD_context.m_nBen
dLineWeight, BCAD_context.m_crBend);CPen* pOldPen
= pdc->SelectObject(pArrowPen);// compute arrow he
adCAutoDimArrow arrowBend(ptArrowTip,CPoint(arrow
[0].x,arrow[0].y),BCAD_context.m_nArrowAngle,BCAD_
context.m_nArrowLength);// draw arrow headarrowBen
d.DrawHead(dc);pdc->SelectObject(pOldPen);delete p
ArrowPen;}/*割り当てたメモリを開放する。*/done :de
lete [] bend_points ;delete [] bend_y_coordinates
;delete[] bendlines ;}/*デバイスコンテクストに部
分デイメンシヨンを描く。*/int BM_AUTO_DIMENSION::d
raw_auto_dimensions(CDC *target_dc){BM_AD_dim_corn
er*temp_point ;int i ;// check that we have a vali
d dcif (NULL == target_dc) return 0 ;// check if w
e need to recompute the data structuresif (dirty)
{if (! compute_auto_dimension_data()) return 0 ;if
(dirty) return 0;}if (NULL == part) return 1 ;dc
= target_dc ;// get view sizeview_size_x = view->g
et_viewport_width() ;view_size_y = view->get_viewp
ort_height() ;// create a mesh to determine clear
spaces to draw dimensions & datapMesh = new CAutoD
imRgnMesh(view_size_x, view_size_y);// check if we
needto compute points to ignore in solidif (view-
>get_drawing_mode() && ! points_to_ignore_in_solid
_computed) {compute_points_to_ignore_in_solid();}o
bject_space_per_pixel = view->get_object_to_device
_ratio() ;// initially set all "ignore" flags to F
ALSE. we should not ignore anything.// also, nothi
ng is drawn yet.for (i = 0 ; i < num_of_bendlines
; i++) {bends[i]->ignore = 0 ;bends[i]->body1_dra
wn = bends[i]->body2_drawn = 0 ;}/*全てのベンドラ
インの全てのベンドラインデイメンシヨンポイントのビ
ジビリテイを計算する。*/for (i = 0 ; i < num_of_be
ndlines ; i++) {if (! bends[i]->data_valid) contin
ue ;bends[i]->compute_bendline_dim_points_visibili
ty() ;if (bends[i]->adj_body1) {for (temp_point =
bends[i]->body1_points ;temp_point ; temp_point =
temp_point->next) temp_point->visible = -1 ;}if (b
ends[i]->adj_body2) {for (temp_point = bends[i]->b
ody1_points ; temp_point ; temp_point = temp_point
->next) temp_point->visible = -1 ;}}/*全てのベンド
ラインに対して、描くべきデイメンシヨンポイントを計
算する。*/for (i = 0 ; i < num_of_bendlines ; i++)
{if (! bends[i]->data_valid ||bends[i]->ignore) c
ontinue ;bends[i]->compute_dim_points_to_display()
;}/*パートを描くペンを生成する。フランジデイメン
シヨンを描くペンを生成する。*/// create the pen :
type, (line)width, color.CPen penFlange;CPen* pFla
ngePen = create_auto_dim_pen(&penFlange, BCAD_cont
ext.m_nFlangeLineStyle, BCAD_context.m_nFlangeLine
Weight, BCAD_context.m_crFlange);// selectnew pen,
save old penCPen* pOldPen = dc->SelectObject(pFla
ngePen);COLORREF oldtextcolor = dc->SetTextColor(B
CAD_context.m_crFlange) ;int old_bk_mode = dc->Set
BkMode(TRANSPARENT) ;/*フランジ長さディメンシヨン
を表示する。*/if (BCAD_context.m_bShowFlangeDim){f
or (i = 0 ; i < num_of_bendlines ; i++) {if (! ben
ds[i]->data_valid || bends[i]->ignore) continue ;b
ends[i]->draw_dimension_points();}}/*// ダーテイ領
域の表示をテストする。CBrush brRed(RGB(255,0,0));C
Brush* pOldBrush = dc->SelectObject(&brRed);dc->Pa
intRgn(pDirtyRegion);dc->SelectObject(pOldBrush);*
/delete pDirtyRegion;pDirtyRegion = NULL;/*ベンド
ラインinfoを描くペンを生成する。*/// create the pe
n : type, (line)width, color.CPen penBend;CPen* pB
endPen = 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 ディメンションポイントを計算する自動寸法化関数の
例。ディメンションポイントは、フランジ長ディメンシ
ョンが描かれる前に計算される。
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 p2ben
d_arc_direction.set_lengt
h(d) ;BM_POINT dim_p2(p_l
ocal + bend_arc_directio
n) ;// now the problem is
that with respect to the
adjacent bendline, our f
lange dimensionpoints// p
and p1 might not be on t
he outside − they could b
e on the inside.// the di
stance from p to p2 depen
ds on that.// however, we
know the p2−line of the
adjacent bendline (with r
espect to our flange),//
so wewill compute the dis
tance between that p2−lin
e and dim_p2. // we will
use that to compute the c
orrect p2 point for our f
lange dimension (note tha
t// our p2 point has to b
e on the p2−line of the a
djacent bendline).double
distance ;BM_distance_bet
ween_point_and_line(dim_p
2, adj_bend_p2_line, &dis
tance, (BM_POINT *) NULL)
;bend_direction.set_leng
th(distance) ;dim_p2 = di
m_p2 + bend_direction ;//
note that the body_requi
red_visiblepointer points
not to this flange, but
to the // adjacent−bendli
ne instead, ALWAYS, even
if this flange dim point
will not be marked as// a
djacent to another bendli
ne.return new BM_AD_dim_c
orner(dim_p, p_local, dim
_p2, owner, adj_bend ? ad
j_bend : Body_required_vi
sible, opening_direction_
vector, opening_vector_re
verse_bit, prev, adj_bend
line) ;}/*この関数は隣接フランジに対する
フランジディメンションポイントを計算する。注意:こ
の関数の直前に計算した基準ポイントは、我々が任意の
種類のadj-body面を操作出来るを確実にするために与え
られる。第一の問題は、我々が、adj-bodyの3次元- バ
ージヨンの2次元- bodyがOUTSIDEまたはINSIDEを表す
かどうか解らないということである。我々は、ベンドラ
インに対するベンドラインディメンションポイントがOU
TSIDEポイントであることを知っている。ただし、 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_bendlin
e::compute_BM_AD_flange_points(BM_3D_BODY *adj_bod
y){// flange dimension points we aregoing to compu
te will be stored hereBM_AD_dim_corner **list_of_p
oints ;// list_of_points is where we write the poi
nter to the // next flange dimension pointBM_AD_di
m_corner *temp_dp ;// these parameters are used as
input to this function.double flange_length ; /* i
t is important that the flange length be the corre
ct flange length */BM_POINT ref_point ; /*referenc
e point, defines the right plane for flange dimens
ion points */BM_VECTOR side_vector ; /* should be
normalized */// check which adjacentbody we comput
eif (adj_body == adj_body1) {flange_length = fl1 ;
list_of_points = &body1_points ;ref_point = bend_b
ody1_point_left.p ;side_vector = side_vector1 ;}el
se if (adj_body == adj_body2) {flange_length = fl
2;list_of_points = &body2_points ;ref_point = bend
_body2_point_left.p ;side_vector = side_vector2 ;}
else return 0 ; // not an adjcent body// variables
to store temporary valuesBM_VECTOR temp_v ;double
temp_x ;// parameters for fixing the reference po
intBM_POINT rp(ref_point) ; // this a local copy o
f the reference point. we will modify it.BM_VECTOR
rv ; // avector for translating flange dimension
points.int ref_vector_valid = 0; // if this is TRU
E, we need to translate all flange dimension point
s.// if TRUE, the only really tricky part is to co
nstruct the p2 point in the flange dimension poin
t.// qualification checkBM_2D_BODY *adj_displayed_
version ;if (parent->get_view_type()) adj_displaye
d_version = adj_body->get_current_3D_version() ;el
se adj_displayed_version = adj_body->get_flat() ;i
f (NULL == adj_displayed_version) return 0 ;BM_SUR
FACE *surface= adj_displayed_version->get_surfac
e() ;if (NULL == surface) return 0 ;BM_LOOP *bloop
= adj_displayed_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 seedouble d1, d2 ; // here we store dist
ance that has to be addedbecause of a bend arc. fo
r lines adjacent 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 sto
re a pointer to a body that is adjacentto the curr
ent edge.BM_BEND_OP *bop ; // here we store a poin
ter to thebend op associated with the bendline tha
t is// adjacent to the edge wescan (valid only iff
the body adjacent to the edge is a bendline).BM_V
ECTOR right_opening_direction ; // this is the rig
ht-side opening direction vector. BM_VECTOR left_o
pening_direction ; // this is the left-side openin
g direction vector. int fl_dim_open = 0 ; // if th
is is TRUE, we have created a right-side flange di
mension point, but// no corresponding left-side di
mension point. That is, the dimension is "open".BM
_VECTOR bend_arc_direction ; // direction of the b
end arc projected onto our plane//should be line->
v * plane_normal. Used when a line is adjacent to
a bendline.BM_VECTOR bend_direction ; // points in
the direction in which thebendline "turns"// depe
nds on whether the bend angle is acute or not. //
if acute then tangent to the other end of bend ar
c.// if not acute, then an endpoint of the tangent
approximation.// basically this is the (p->p2) ve
ctor for the other bendline with respect to this f
lange.// this is used when a line is adjacent to a
bendline, to compute the p2 point for // the flan
ge dimension point.BM_LINE adj_bend_p2_line ; // t
his is the left-right-p2 line, of the adjacent ben
dline,// with respect to this flange.// this is us
ed when a line is adjacent to a bendline, to compu
tethe p2 point for // the flange dimension point.d
ouble bend_arc_outside_length_proj ; // bendline a
rc outside length projected onto our plane/*表面の
タイプを操作する。*/if (surface->is(BM_TYPE_PLAN
E)) goto handle_planes ;/*********** ********** **
******** ********** ********** *******************
* ********** ********** 一時的拘束:我々は単に平面
である表面を操作する。TODO:他の表面タイプを操作す
る。********** ********** ********** ********** **
******** ********** ********** ********** ********
***///unknown surfacereturn 0 ;/*ここで、平面を操
作する。*/handle_planes : BM_PLANE *plane = (BM_PL
ANE *) surface ;// we assume that the reference po
int correctly defines the plane (which is parallel
to our plane)// thatis the OUTSIDE plane.// check
if reference point is on our plane. If not(in tha
t case our plane represents the INSIDE// plane) co
mpute a translation vector for moving from our pla
ne to reference plane,// and move the reference po
int to our plane.rv = plane->get_normal() ;rv.norm
alise();temp_v = rp - (plane->get_pt()) ;temp_x =
temp_v % rv ;if (fabs(temp_x)> AUTODIM_DISTANCE_TO
LERANCE) {// ok, need to translate all dimension p
oints. reference point not on the plane.ref_vector
_valid = 1 ;rv.set_length(temp_x) ;rp = rp + (-rv)
;}else rv = BM_null_vector ;// compute right- and
left-side opening vectors.right_opening_direction
= side_vector *(plane->get_normal()) ;right_openi
ng_direction.normalise() ;left_opening_direction =
-(right_opening_direction) ;/*********** ********
** ********** ********** ********** ********** ***
******* ********** **********この関数の主要部分。a
dj_bodyの束縛ループを掃引し、ディメンションポイン
トを構成する。所与のラインから最も遠く離れたエッジ
はbloop内になければならないので我々は単にbloopを掃
引する必要がある点に注意されたい。****************
**** ********** ********** ********** ********** *
********* ********** ********** 注意:ディメンショ
ンリストが開放のとき、生成される最後の右-側ディメ
ンションポイントは、ループの始めにおいて現在のエッ
ジの開始-点から異なっていなければならない。*******
*** ********** ********** ********** ********** **
******** ********** ********** ********** */// sca
n alledges in the bloop// first, we have a problem
where to start scanning.// if we start from the f
irst edge, we basically start from an arbitraryedg
e.// this might not be good since we might create
dimension points wedon’t really want.// therefore
we will find an edge that is adjacent to our bend
line and start from that and// finish when we get
back to it.BM_EDGE *start_edge, *stop_edge, *next_
edge ;for (start_edge = bloop->get_first_edge() ;
start_edge ; start_edge = (BM_EDGE *) start_edge->
next()) {if (start_edge->get_adj_body() == bend) b
reak ; // edge adjacent to this bendline is a good
start-edgeelse if (! start_edge->is(BM_ENTITY_TYP
E_LINE)) break ; // any non-line is a good start-e
dgeelse { // any linethat will be ignored is also
a good place to starttemp_v = (((BM_LINE *)start_e
dge)->get_v()) * side_vector ;// in these two case
s this line will be ignoredif (temp_v.Len() <= AUT
ODIM_DISTANCE_TOLERANCE) break ; //line parallel t
o the side-vectorif ((temp_v % plane->get_norma
l()) > 0.0) break ; // material "above" the line}}
if (NULL == start_edge) {*list_of_points = NULL ;r
eturn 1 ;}// this is the main loop.// initially we
setstop_edge to NULL. we would like to set it to
start-edge, but we cannot,// because in that case
we would never enter the loop. therefore we setit
to NULL and right // after we enter the loop, we s
et it to start_edge.// (this is important in the c
ase when the loop consists of only one circle).sto
p_edge = NULL ;for (edge = start_edge ; edge != st
op_edge ; edge = next_edge) {stop_edge = start_edg
e ;// 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 : { // com
pute distance for start- and end-points// first, w
e want to ignore lines that are parallel to the si
de-vector.// we also want to ignore lines that hav
e material "above" them when looking in the// side
-vector direction (because they cannot have to lar
gest width, since material is// "above" them, ther
e must be some other edge bounding thebody from ab
ove).temp_v = (((BM_LINE *) edge)->get_v()) * side
_vector ;if (temp_v.Len() <= AUTODIM_DISTANCE_TOLE
RANCE) continue ; // line parallel to the side-vec
torif ((temp_v % plane->get_normal()) > 0.0) conti
nue; // material "above" the line// note that this
leaves only lines whosedirection−vec
tor goes to the ”left”//
of the side−vector.// we
need tocheck if this line
is adjacent to a bendlin
eab = edge−>get_adj_bod
y() ;// check if this lin
e is adjacent to a valid
bendline (ie. one that is
not the // bendline asso
ciated with this BM_AD_be
ndline object).d1 = d2 =b
end_arc_outside_length_pr
oj = 0.0 ;if (ab && ab !=
bend && ab−>is(BM_ENTITY
_TYPE_BENDLINE)) {// chec
k if the bendline is bein
g bentbop = ((BM_BENDLINE
*) ab)−>get_bend_op() ;i
f ((parent−>get_view_type
()) /* have tohave a 3D v
iew */ && ((BM_BENDLINE
*) ab)−>get_bending_statu
s() && bop){// a problem
: it could be that the b
endline is not perpendicu
lar to the side−vector.//
in that case we need to
project the bend−arc−appr
oximation−value onto the
side−vector.// for exampl
e, if the bendline is par
allel to the side−vector,
we should not add// the
approximation value at al
l, since it plays no role
in the width computatio
n.temp_x = side_vector^
(((BM_LINE *) edge)−>get_
v()) ; // temp_x is ”angl
e_factor”if (temp_x> PI_o
ver_2) temp_x = PI − temp
_x ;temp_x = sin(temp_x)
;switch (bop−>get_typ
e()) {case BM_TYPE_BEND_O
P_REGULAR :bend_arc_outsi
de_length_proj =((BM_BEND
_OP_REGULAR *) bop)−>comp
ute_3D_outside_approx_per
_side() ;d1 =temp_x*bend_
arc_outside_length_proj ;
d2 = d1 ; // d2 is the sa
me as d1!break ;// TODO :
implement more bend oper
ations here.default : ; /
/ unknown bend op}// comp
ute some needed parameter
s// compute : direction o
fthe bend arc projected o
nto our planebend_arc_dir
ection = (((BM_LINE *)edg
e)−>get_v()) * plane−>get
_normal() ;bend_direction
= parent−>compute_bend_d
irection_vector((BM_BENDL
INE *) ab, adj_body, &adj
_bend_p2_line) ;}}else ab
= NULL ; // make sure ab
does not point to anythi
ng we don’twant to.// handle two cases s
eparately - depending on whether the dimension lis
t is open or not.if (fl_dim_open) {// if the dimen
sion is open, we don’t need to check the start-po
int of the line,// since it is at theflange length
distance anyway.// // first we will check if the
line isperpendicular to the side-vectorif (fabs(si
de_vector % ((BM_LINE *) edge)->get_v()) > AUTODIM
_DISTANCE_TOLERANCE) {// not perpendicular.// this
line has to be "coming down" (because it is not pe
rpendicular to the// side-vector and the dimension
is open, ie. it cannot be "going up").// now we h
ave to close the dimension by creating a left-hand
-side dimensionpoint// from the start-point of the
line.if (temp_dp = create_dim_point(bend_arc_outs
ide_length_proj, ((BM_LINE *) edge)->get_startp
t(), rv, left_opening_direction, 0, this, adj_bod
y, list_of_points, side_vector, d1,bend_arc_direct
ion, bend_direction, (BM_BENDLINE *) ab, adj_bend_
p2_line)) {list_of_points = &(temp_dp->next) ;}fl_
dim_open = 0 ;}else {// is perpendicular.// here w
e need to check the type of the next edge.// if it
is not line, we need to close the dimension here b
y creating // a left-hand-side dimension point fro
m the end-point of the line.// if the nextedge is
a line, we can just continue.if (leave_dimension_o
pen(edge,bloop,side_vector,plane->get_normal())) b
reak ;if (temp_dp = create_dim_point(bend_arc_outs
ide_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, b
end_direction, (BM_BENDLINE *) ab, adj_bend_p2_lin
e)) {list_of_points = &(temp_dp->next) ;}// ok, cl
ose the dimension.fl_dim_open = 0 ;// this is a sm
all trick that will save us some time.// if the ne
xt edge is a line that will be ignored, we can ski
p is right now here.if (next_edge->is(BM_ENTITY_TY
PE_LINE) && next_edge != stop_edge) {next_edge =
(BM_EDGE *) edge->next() ;if (NULL == next_edge) n
ext_edge = bloop->get_first_edge() ;}}break ;}if
(! compute_distance_from_ref_point(rp, side_vecto
r, edge->get_edge_startpoint(), distance1)) contin
ue ;if (! compute_distance_from_ref_point(rp, side
_vector, edge->get_edge_endpoint(), distance2)) co
ntinue ;td1 = distance1 + d1 ;td2 = distance2 + d2
;// check if the start-point is a flange dimensio
n pointif (fabs(td1 - flange_length) <= AUTODIM_DI
STANCE_TOLERANCE) {// check if the second point is
a flange dimension pointif (fabs(td2 - flange_len
gth) > AUTODIM_DISTANCE_TOLERANCE)
{// only start−point is
a flange dimension point.
// create a left−right (i
e. in both directions) fl
ange dim point and contin
ue.if (temp_dp = create_d
im_point(bend_arc_outside
_length_proj, ((BM_LINE
*) edge)−>get_startpt(),
rv, right_opening_directi
on, 1, this, adj_body,lis
t_of_points, side_vector,
d1, bend_arc_direction,
bend_direction, (BM_BENDL
INE *) ab, adj_bend_p2_li
ne)) {list_of_points = &
(temp_dp−>next) ;}break
;}// else open the dimen
sion list// create right
flange dimensionpoint fro
m start−pointif (temp_dp
= create_dim_point(bend_a
rc_outside_length_proj,
((BM_LINE *) edge)−>get_s
tartpt(), rv, right_openi
ng_direction, 0, this, ad
j_body, list_of_points, s
ide_vector, d1, bend_arc_
direction, bend_directio
n, (BM_BENDLINE *) ab, ad
j_bend_p2_line)) {list_of
_points = &(temp_dp−>nex
t) ;}// check if we can l
eave the dimension list o
penand continueif (leave_
dimension_open(edge,bloo
p,side_vector,plane−>get_
normal())) {fl_dim_open =
1 ;break ;}// create lef
t flange dim point from e
nd−point.if (temp_dp = cr
eate_dim_point(bend_arc_o
utside_length_proj,((BM_L
INE *) edge)−>get_endp
t(), rv, left_opening_dir
ection, 0, this, adj_bod
y, list_of_points, side_v
ector, d1, bend_arc_direc
tion, bend_direction, (BM
_BENDLINE *) ab, adj_bend
_p2_line)) {list_of_point
s = &(temp_dp−>next) ;}//
ok, close the dimension
list.fl_dim_open = 0 ;//
this is asmall trick that
will save us some time./
/ if the next edge is a l
ine that will be ignored,
we can skip is right now
here.if (next_edge−>is(B
M_ENTITY_TYPE_LINE) && ne
xt_edge != stop_edge) {ne
xt_edge = (BM_EDGE *) edg
e−>next() ;if (NULL == ne
xt_edge) next_edge = bloo
p−>get_first_edge() ;}bre
ak ;}else if (fabs(td2 −
flange_length) > AUTODIM_
DISTANCE_TOLERANCE){// th
e start−point is not a fl
ange dimension point// if
the end−pointis also not
a flange dimension poin
t, we can continue.contin
ue ;}// ok,only the end−p
oint is a flange dimensio
n point.// two possibilit
ies. ifwe can leave the d
imension list open (right
now dimension is // clos
ed!)we don’t even have to open it, we c
an just continue.if (leave_dimension_open(edge,blo
op,side_vector,plane->get_normal())) break ;// sec
ond possibility. now we have to create a left-righ
t flange dimension point.// dimension list stays c
losed.if (temp_dp = create_dim_point(bend_arc_outs
ide_length_proj, ((BM_LINE *) edge)->get_endpt(),
rv, right_opening_direction, 1, this, adj_body, li
st_of_points, side_vector, d1, bend_arc_direction,
bend_direction, (BM_BENDLINE *) ab, adj_bend_p2_l
ine)) {list_of_points = &(temp_dp->next) ;}// this
is a small trick that will save us some time.// i
f the next edge is a line that will be ignored, we
can skip is right now here.if (next_edge->is(BM_E
NTITY_TYPE_LINE) && next_edge !=stop_edge) {next_e
dge = (BM_EDGE *) edge->next() ;if (NULL == next_e
dge)next_edge = bloop->get_first_edge() ;}}break ;
case BM_ENTITY_TYPE_ARC :{// note : we can always
ignore the start-point of the arc !// becauseof th
e way we keep track of the open dimension list.//
make sure the dimension list will be closed.fl_dim
_open = 0 ;// first, compute start- andend-angles
of the arc with respect to the side vector.// ie.
convert start- and end-angles so as if the side-ve
ctor was the 0-angle vector.double startang = ((BM
_ARC *) edge)->get_startang() ;double endang = ((B
M_ARC *) edge)->get_endang() ;temp_v = side_vector
*(((BM_ARC *) edge)->get_vx()) ;double delta_angle
= (temp_v.Len())/(((BM_ARC *) edge)->get_rad());i
f (delta_angle < -1.0) delta_angle = -1.0 ;else if
(delta_angle > 1.0) delta_angle = 1.0 ;delta_angl
e = asin(delta_angle) ;if (fabs((((BM_ARC*) edge)-
>get_normal())%temp_v) > 0.0) {startang += delta_a
ngle ;endang+= delta_angle ;if (startang > PI_time
s_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_POIN
T arc_extreme_point ;// 0-angle point is the extre
me pointif (endang <startang) arc_extreme_point =
((BM_ARC *) edge)->get_center() + (((BM_ARC *) edg
e)->get_rad())*side_vector ;else arc_extreme_point
= *(((BM_ARC*) edge)−>get_edge
_endpoint()) ;// check th
e distance of the extreme
pointif (! compute_dista
nce_from_ref_point(rp, si
de_vector, &arc_extreme_p
oint, distance1)) continu
e ;if (fabs(distance1 − f
lange_length) <= AUTODIM_
DISTANCE_TOLERANCE) {// i
f we have the 0−angle poi
nt, create a left−right f
lange dimension point.//
otherwise if next line is
a non−ignored line, don’
t do anything,// otherwise create a left-right fla
nge dimension point.if (endang >= startang && leav
e_dimension_open(edge,bloop,side_vector,plane->get
_normal())) {continue ;}// create a left-right fla
nge dimension point. dimension list stays closed./
/ this is a 1-point flange dimension point.if (tem
p_dp = new BM_AD_dim_corner(rv + arc_extreme_poin
t, this, adj_body,right_opening_direction, 1, list
_of_points, NULL)) {list_of_points = &(temp_dp->ne
xt) ;}}}break ;case BM_ENTITY_TYPE_CIRCLE : // cir
cles are a much simpler version of the arc case.{B
M_POINT circle_extreme_point = ((BM_CIRCLE *) edg
e)->get_center() + (((BM_CIRCLE *) edge)->get_ra
d())*side_vector ;// we won’t check the distance
since it mustbe a flange dimension point// create
a left-right flange dimension point.// this is a 1
-point flange dimension point.if (temp_dp = new BM
_AD_dim_corner(rv + circle_extreme_point, this, ad
j_body,right_opening_direction, 1, list_of_points,
NULL)) {list_of_points = &(temp_dp->next) ;}}brea
k;case BM_ENTITY_TYPE_ELLIPSE : // TODO : implemen
t ellipse here. shouldbe similar to the way arc is
handled.continue ;break ;default : continue ; //
unknown edge type}}/* OK、全て終了。*/*list_of_po
ints = NULL ;return 1 ;}/*この関数は1つのBM_AD_be
ndline構造に対するベンドラインディメンションポイン
トを計算する。注意: p1は、フランジ長が描かれる隣
接体の平面上にある。pはセンタポイントである。 p2は
ベンドラインの側部のポイントである。注意:この関数
においては、我々は常にadj-body1およびadj-body2に対
するベンド-ディメンションポイントを計算する。この
ベンドラインは1または0の隣接体を持つことになるが、
我々は将来これらのポイントのビジビリテイを知る必要
がある。*/int BM_AD_bendline::compute_BM_AD_bendli
ne(void){double metal_thickness ; // thickness of
the sheetmetalBM_2D_BODY *bendline_displayed_versi
on ; // 3D-version of the bendlineBM_VECTOR temp_v
; // vectorused for very short periods for storin
g temporary stuff// initally markthe bendline data
as invalid, in case we fail here.data_valid = 0 ;
// qualification checkif (NULL == bend) return 0 ;
if (NULL == bend->get_adj_list()) return 0 ;if (NU
LL == bend->get_part()) return 0 ;// this bendline
has to have a 3D-versionif (parent->get_view_type
()) {if (NULL == (bendline_displayed_version = ben
d->get_current_3D_version())) return 0 ;}else {if
(NULL == (bendline_displayed_version = bend->get_f
lat())) return0 ;}metal_thickness = (bend->get_par
t())->get_metal_thickness() ;/* ********** *******
*** ********** ********** ********** ********** **
******** ********** **********これは一時的な測度で
ある。我々は単に規則的なベンドラインを処理する。す
なわち、円錐ベンドラインは無視する。03/16/96. KK.*
/if (bend->get_bending_status() && bend->get_bend_
op() && ! (bend->get_bend_op())->is(BM_TYPE_BEND_O
P_REGULAR)) return 0 ;/* ********** ********** ***
******* ********** ********** ********** *********
* ********** ********** */// get the number of adj
acent bodies.adj_body1 = (bend->get_adj_list())->f
ind_lowest_id_adj_body() ;adj_body2 = (bend->get_a
dj_list())->find_second_lowest_id_adj_body() ;num_
of_adjacent_bodies = (adj_body1? 1 : 0) + (adj_bod
y2 ? 1 : 0) ;/*サイドベクトルを計算する。*/if (adj
_body1) {if (! bendline_displayed_version->compute
_vector_perp_towards_adj_body(adj_body1, side_vect
or1)) return 0 ;side_vector1.normalise() ;}if(adj_
body2) {if (! bendline_displayed_version->compute_
vector_perp_towards_adj_body(adj_body2, side_vecto
r2)) return 0 ;side_vector2.normalise();}/*ベンド
ラインディメンションポイントを計算する。*/if (! be
nd->get_bending_status() /* bendline not bent */ |
| ! parent->get_view_type() /* flat view */) {// n
ote : here we don’t know whether the dimension po
int is OUTSIDE or INSIDE.// this has to be taken i
nto account later.// however, it should work eithe
r way.bend_body1_point_left.num_of_points = bend_b
ody1_point_right.num_of_points = 1 ;bend_body1_poi
nt_left.can_reverse_opening_dir = bend_body1_point
_right.can_reverse_opening_dir = 0 ;bend_body1_poi
nt_left.p = (bendline_displayed_version->get_curre
nt_center_line()).get_startpt() ;bend_body1_point_
right.p = (bendline_displayed_version->get_current
_center_line()).get_endpt() ;// note opening direc
tions. left will get start-point, right will get e
nd-point, ie. vector goes left->right.bend_body1_p
oint_right.opening_direction = (bendline_displayed
_version->get_current_center_line()).get_v() ;(ben
d_body1_point_right.opening_direction).normalise()
;bend_body1_point_left.opening_direction = -(bend
_body1_point_right.opening_direction) ;// points w
ith respect to bothadjacent bodies are the sameben
d_body2_point_left.num_of_points = bend_body2_poin
t_right.num_of_points = 1 ;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_point_left.opening_directio
n = bend_body1_point_left.opening_direction ;bend_
body2_point_left.p = bend_body1_point_left.p ;bend
_body2_point_right.p = bend_body1_point_right.p ;}
else {// first, get some bending parametersBM_SURF
ACE *surface = bendline_displayed_version->get_sur
face() ;if (NULL == surface) return 0 ;BM_BEND_OP
*bop = bend->get_bend_op() ;if (NULL == bop) retur
n 0 ;double bend_angle = bop->get_bend_angle2() ;d
ouble bend_arc_angle = PI - bend_angle ;double hal
f_bend_arc_angle = bend_arc_angle/2.0 ;switch (sur
face->get_type()) {case BM_TYPE_CYLINDER : { // no
te that the bend op can be both regular and conicB
M_CYLINDER *cylinder = (BM_CYLINDER *) surface ;do
uble radius = cylinder->get_rad() ;double outside_
radius = radius ;if (bendline_displayed_version->g
et_sense()) outside_radius += metal_thickness ;//
set some common valuesbend_body1_point_left.can_re
verse_opening_dir = bend_body1_point_right.can_rev
erse_opening_dir = 0 ;bend_body1_point_right.openi
ng_direction =(bendline_displayed_version->get_cur
rent_center_line()).get_v() ;(bend_body1_point_rig
ht.opening_direction).normalise() ;bend_body1_poin
t_left.opening_direction = -(bend_body1_point_righ
t.opening_direction) ;if (outside_radius <= AUTODI
M_DISTANCE_TOLERANCE) {// special case : outside r
adius 0 - trivial dimension point.bend_body1_point
_left.num_of_points = bend_body1_point_right.num_o
f_points = 1 ;bend_body1_point_left.p = (bendline_
displayed_version->get_current_center_line()).get_
startpt() ;bend_body1_point_right.p = (bendline_di
splayed_version->get_current_center_line()).get_en
dpt() ;bend_body2_point_left.num_of_points = bend_
body2_point_right.num_of_points = 1 ;bend_body2_po
int_left.can_reverse_opening_dir= bend_body2_point
_right.can_reverse_opening_dir = 0 ;bend_body2_poi
nt_right.opening_direction = bend_body1_point_righ
t.opening_direction ;bend_body2_point_left.opening
_direction = bend_body1_point_left.opening_directi
on ;bend_body2_point_left.p = bend_body1_point_lef
t.p ;bend_body2_point_right.p = bend_body1_point_r
ight.p ;}else {bend_body1_point_left.num_of_points
= bend_body1_point_right.num_of_points = 3 ;// co
mpute points p1 for adj_body1bend_body1_point_lef
t.p1 = (bendline_displayed_version->get_current_ce
nter_line()).get_startpt() ;bend_body1_point_righ
t.p1 = (bendline_displayed_version->get_current_ce
nter_line()).get_endpt() ;// theproblem now is tha
t it could be that these centerline points (which
are// on the surface of the bendline), could be on
ly inside surface of thebendline.if (bendline_disp
layed_version->get_sense() && metal_thickness> AUT
ODIM_DISTANCE_TOLERANCE) {temp_v = cylinder->get_v
x() ;temp_v.set_length(metal_thickness) ;bend_body
1_point_left.p1 = bend_body1_point_left.p1 + temp_
v ;bend_body1_point_right.p1 = bend_body1_point_ri
ght.p1 + temp_v ;}// a break in the computation of
adj_body1.p1.// store current p1values for adj_bo
dy2 as well. this will save some time.// // note t
hatwe should not really compute adj_body2 points u
nless adj_body2 pointer//is not NULL. However, thi
s point (adj_body2.p1) is very useful for computin
g// adj_body1.p2 (if angle is acute). so we comput
e it anyway.bend_body2_point_left.p1 = bend_body1_
point_left.p1 ;bend_body2_point_right.p1= bend_bod
y1_point_right.p1 ;// finish adj_body1.p1. rotate
points p1 into their final correct location.// not
e we rotate in the negative direction since adj_bo
dy1 is the smallest-index// adjacent body as is "t
o-the-left-of-the-bendline-centerline", which mean
s// rotating to the left.//first, compute the righ
t vector for the rotation line.BM_VECTOR rot_v(cyl
inder->get_v()) ;if (rot_v % ((bendline_displayed_
version->get_current_center_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_angle) ;BM_rotate_point_aro
und_line(&(bend_body1_point_right.p1),cylinder->ge
t_pt1(), rot_v, -half_bend_arc_angle) ;// finish a
lso adj_body2.p1. rotate points p1 into their fina
l correct location.BM_rotate_point_around_line(&(b
end_body2_point_left.p1), cylinder->get_pt1(), rot
_v,half_bend_arc_angle) ;BM_rotate_point_around_li
ne(&(bend_body2_point_right.p1), cylinder->get_pt1
(), rot_v, half_bend_arc_angle) ;// compute points
p for adj_body1.double x ;if (bop->is(BM_TYPE_BEN
D_OP_REGULAR)) {x= ((BM_BEND_OP_REGULAR *) bop)->c
ompute_3D_outside_approx_per_side() ;}else if (bop
->is(BM_TYPE_BEND_OP_CONIC)) {// TODO : implement
conic bendline herereturn 0 ;}temp_v = -x*side_vec
tor1 ;bend_body1_point_left.p = bend_body1_point_l
eft.p1 + temp_v ;bend_body1_point_right.p = bend_b
ody1_point_right.p1 + temp_v ;// note : adj_body1.
p2 and adj_body2.p, adj_body2.p2 are yet to be com
puted.// now there are two cases : 1) the bend arc
angle is acute (ie. no more than 90 degrees),//
2) the bend arc angleis more than 90 degrees.if (b
end_arc_angle > (PI_over_2 + BM_ANGLE_TOLERANCE))
{ // use tangent approximation// we will finish co
mputing adj_body1. adj_body1.p2 is left.// idea :
notice that adj_body1 is to the leftof the bendlin
e-centerline// because it is the lowest-index neig
hbor. Therefore the cross-product// of centerline-
v by temp_v points towards thecylinder (actually i
t is tangent// to the cylinder).BM_VECTOR tangent_
v(bend_body1_point_right.
opening_direction * temp_
v) ;tangent_v.set_length
(x) ;bend_body1_point_lef
t.p2 = bend_body1_point_l
eft.p + tangent_v ;bend_b
ody1_point_right.p2 = ben
d_body1_point_right.p + t
angent_v ;// noteadj_body
2.p1 is already computed.
first set some common va
lues.bend_body2_point_lef
t.num_of_points = bend_bo
dy2_point_right.num_of_po
ints = 3 ;bend_body2_poin
t_left.can_reverse_openin
g_dir = bend_body2_point_
right.can_reverse_opening
_dir = 0 ;bend_body2_poin
t_right.opening_direction
= bend_body1_point_righ
t.opening_direction ;bend
_body2_point_left.opening
_direction = bend_body1_p
oint_left.opening_directi
on ;// now compute adj_bo
dy2.ptemp_v = −x*side_vec
tor2 ;bend_body2_point_le
ft.p = bend_body2_point_l
eft.p1 + temp_v ;bend_bod
y2_point_right.p = bend_b
ody2_point_right.p1+ temp
_v ;// finally, compute a
dj_body2.p2// note the or
der in the cross−product
!tangent_v = temp_v * ben
d_body2_point_right.openi
ng_direction; tangent_v.s
et_length(x) ;bend_body2_
point_left.p2 = bend_body
2_point_left.p + tangent_
v ;bend_body2_point_righ
t.p2 = bend_body2_point_r
ight.p+ tangent_v ;}else
{ // use intersection app
roximation// note : adj_b
ody2.p2 is the same as as
j_body1.p1.bend_body1_poi
nt_left.p2 = bend_body2_p
oint_left.p1 ;bend_body1_
point_right.p2 = bend_bod
y2_point_right.p1 ;//when
using intersection appro
ximation, dimensions poin
ts with respect to// both
adjacent bodies are the
same, so we just copy the
m.bend_body2_point_left.n
um_of_points = bend_body2
_point_right.num_of_point
s = 3 ;bend_body2_point_l
eft.can_reverse_opening_d
ir = bend_body2_point_rig
ht.can_reverse_opening_di
r = 0 ;bend_body2_point_r
ight.opening_direction =
bend_body1_point_right.op
ening_direction ;bend_bod
y2_point_left.opening_dir
ection = bend_body1_point
_left.opening_direction ;
// note we are switchingp
ointsbend_body2_point_lef
t.p2 = bend_body1_point_l
eft.p1 ;bend_body2_point_
right.p2 = bend_body1_poi
nt_right.p1 ;bend_body2_p
oint_left.p = bend_body1_
point_left.p ;bend_body2_
point_right.p = bend_body
1_point_right.p ;}}}break
;case BM_TYPE_CONE :brea
k ;default : ; // unknown
or illegalsurface ;}}/*隣
接体の各々に対するフランジ長を計算する。*/if (adj_
body1){// if the flange length computation fails,
pretend the adjacent body does not exist. for simp
licity.if (! bend->compute_flange_length(parent->g
et_view_type(),adj_body1,fl1)) {adj_body1 = NULL ;
--num_of_adjacent_bodies ;}}if (adj_body2) {if (!
bend->compute_flange_length(parent->get_view_typ
e(),adj_body2,fl2)) {adj_body2 = NULL ;--num_of_ad
jacent_bodies ;}}/*よし、データを有効なものとして
マークする。ベンドラインディメンションポイントが全
てのベンドラインに対して計算されると、我々は同様に
巣手のベンドラインに対してフランジディメンションポ
イントを計算することが出来る。*/data_valid = 1 ;//
before we can return, we have to check if body1,2
left(right) bendline dimension points // are the
same.// note the same meansnot the same pointers,
but the contents are equivalent.if (adj_body1 &&ad
j_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_require
d_visibleポインタは隣接体を指示するべきである。*/i
f (1 ==bend_body1_point_left.num_of_points) bend_b
ody1_point_left.body_required_visible = adj_body1
;if (1 == bend_body1_point_right.num_of_points) b
end_body1_point_right.body_required_visible = adj_
body1 ;if (1 == bend_body2_point_left.num_of_point
s) bend_body2_point_left.body_required_visible= ad
j_body2 ;if (1 == bend_body2_point_right.num_of_po
ints) bend_body2_point_right.body_required_visible
= adj_body2 ;return 1 ;}/*********** ********** *
********* ********** ********** ********** *******
*** ********** **********BM_AUTO_DIMENSION class s
tuff.********** ********** ********** ********** *
********* ********** ********** ********** *******
****//*確実な発見的手法:ソリッドモードにおいて幾
つかのポイントを我々が無視出来るか否かをチェックす
る。ソリッドモードにおいては、我々は時間の節約のた
めにこの発見的手法を用いている。2つのベンドライン
がフランジ-長を表示するために(潜在的に)等価なフ
ランジ-ディメンションポイントを用いているときは、
我々は単に、より高いidxを持つベンドライン(これら
の2つのベンドラインに対する)に対してのみビジビリ
テイ情報を計算する。*/void BM_AUTO_DIMENSION::comp
ute_points_to_ignore_in_solid(void){int i ;BM_AD_d
im_corner*temp_point ;for (i = 0 ; i < num_of_bend
lines ; i++) {if (! bends[i]->data_valid) continue
;if (bends[i]->adj_body1) {for (temp_point = bend
s[i]->body1_points ; temp_point ; temp_point = tem
p_point->next) {if (NULL== temp_point->adj_bendlin
e) continue ;if ((temp_point->adj_bendline)->get_i
dx() > (bends[i]->bend)->get_idx()) continue ;if
(check_two_bendlines_adjacent_to_same_flange(bends
[i]->bend,bends[i]->adj_body1,temp_point->adj_bend
line)) {temp_point->ignore_in_solid_mode = 1 ;}}}i
f (bends[i]->adj_body2) {for (temp_point = bends
[i]->body2_points ; temp_point ; temp_point = temp
_point->next) {if (NULL == temp_point->adj_bendlin
e) continue ;if ((temp_point->adj_bendline)->get_i
dx() > (bends[i]->bend)->get_idx()) continue ;if
(check_two_bendlines_adjacent_to_same_flange(bends
[i]->bend,bends[i]->adj_body2,temp_point->adj_bend
line)) {temp_point->ignore_in_solid_mode = 1 ;}}}}
points_to_ignore_in_solid_computed = 1 ;}/*この関
数は自動寸法化ベンドラインを構成し、データ構造を指
示する。これはディメンションポイントを計算する主要
関数である。*/int BM_AUTO_DIMENSION::compute_auto_
dimension_data(void){int i ;// have to have a docu
mentif (NULL == doc) return 0 ;// if no part, try
to get a new part from the documentif (NULL == par
t) {set_part(doc->get_part()) ;}if (NULL == part)
{dirty =0 ;return 1 ;}points_to_ignore_in_solid_co
mputed = 0 ;/*ビユータイプを得る。*/if (view) {vie
w_type = view->get_current_view() ;}else {// we ar
e screwedreturn 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) b
ends[i]->compute_BM_AD_flange_points(bends[i]->adj
_body1) ;if (bends[i]->adj_body2)bends[i]->compute
_BM_AD_flange_points(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 coordin
ates of a point, with top left corner as (0,0), an
d the// z-buffer depth, given the three-dimensiona
l world coordinates of the point, using RenderWare
utilities // (ie. when solid is on). If return va
lue is 0, point is not mapped onto the screen, ie.
not visible.// Note: At present, same as map_3d_to
_screen_wire.int CBendCADViewPart::map_3d_to_scree
n_solid(BM_POINT three_d_point, int *x_pos,int *y_
pos, double *z_depth){ int viewport[4], visible
= 1; doublewidth, height, depth; double model_m
at[16], proj_mat[16], array[16]; // Get the curre
nt viewport coords. glGetIntegerv(GL_VIEWPORT, vi
ewport); // Now build a modelview matrix out of t
he current set of transformations. glMatrixMode(G
L_MODELVIEW); glPushMatrix(); glTranslated(md_
x_trans, md_y_trans, 0.0);convert_rw_matrix_to_gl_
array(md_rot_matrix, array);glMultMatrixd(array);g
lTranslated(- m_part_centroid.X(), - m_part_centro
id.Y(), - m_part_centroid.Z()); glGetDoublev(GL
_MODELVIEW_MATRIX, model_mat); glGetDoublev(GL_
PROJECTION_MATRIX, proj_mat); glPopMatrix(); glu
Project(three_d_point.X(), three_d_point.Y(), thre
e_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.b
ottom) || ((int)height < 0) )visible = 0; if(x_po
s) *x_pos = (int) width; if(y_pos) *y_pos = (m_ol
d_rect.bottom - (int) height); if(z_depth) *z_dep
th = depth; returnvisible; }// This function p
icks the point indicated by map_3d_to_screen, usin
g RenderWare picking, so this is// called only whe
n solid is being shown. Note that the pick positio
n 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// passed back in pi
cked_edge; else, picked_edge is set to null. This
does not modify the selection// set in any way.voi
dCBendCADViewPart::pick_point_rw(int x_pos, int y_
pos, BM_EDGE **picked_edge) { if(picked_edge == N
ULL) return; if( (x_pos > m_old_rect.right)|| (y_
pos > m_old_rect.bottom)) { // Make sure point gi
ven is within*picked_edge = NULL;// viewport.retur
n; } RwClump *picked_clump = NULL;RwClump *pare
nt_clump = NULL; long parent_tag, clump_tag, key
= 0; BM_EDGE *edge = NULL; if(! RwPickScene(m_sc
ene, x_pos, y_pos, m_camera,&m_pick)) { // Picking
command was not successful. *picked_edge = NUL
L;return; } if(m_pick.type == rwNAPICKOBJECT)
{ // No clump was picked.*picked
_edge = NULL;return; } else if(m_pick.type == rw
PICKCLUMP) { // Some clump was p
icked; process it.picked_clump = m_pick.object.clu
mp.clump;parent_clump = RwGetClumpParent(picked_cl
ump);parent_tag = RwGetClumpTag(parent_clump);clum
p_tag =RwGetClumpTag(picked_clump);if(parent_tag =
= 1) { *picked_edge = NULL;return;
// A trivial bendline orf
orming was picked. } // Now some real edge w
as picked.key = (parent_tag%10000)*100000 + clump_
tag; if(clump_tag) // Safety check; we expect clum
p_tag to be non-zero. *picked_edge = map_list
_name_to_bm_edge(parent_tag, clump_tag); }}
// This function returns the ratio of the view vol
ume dimension (object space dimensions) to// the v
iewportdimension (device space dimensions).double
CBendCADViewPart::get_object_to_device_ratio(void)
{ double ratio; if(m_old_rect.right) ratio =
2.0*md_current_view_vol[0]/(double)(m_old_rect.rig
ht); else ratio = 0.0; return ratio;}/* Given a
BM_POINT, which represents a point in worldcoordi
nates, one can project it onto view window coordin
ates. This function first checks if the projected
point is within the viewing volume. If it IS withi
n viewing volume, the pointer "visible" carries va
lue 1; else, 0. If the point is not visible, no ot
her parameters have any meaning; the return value
is 0. Now suppose the point is visible. A) If th
e display is showing the SOLID version of the par
t, this function checks ifANY of the three_d_bodie
s in the array "three_db_array" lies "approximatel
y under" the projected point. If the answer is ye
s, return value is 1; else, return value is zero.
The x_pos, y_pos, and z_depth pointers carry the v
iew window coordinates (with top left corner as
(0,0)) and the z-buffer value. The array "thee_db_
array" must be terminated by a NULL pointer to ind
icate end of array. B) If the display is showing
the WIREFRAME version of the part the return value
is always zero. If the point is within view volu
me, *visible is set to 1; else, 0. If *visible is
1, x_pos, y_pos and z_depth values have the meanin
g mentioned above. */int CBendCADViewPart::is_3d_b
ody_near_point(BM_POINT const& three_d_point, BM_3
D_BODY **three_db_array,
int *visible, int *x_pos, int *y_po
s, double *z_depth){ int x, y, is_visible= 1; do
uble z; int found = 0; is_visible = map_3d_to_sc
reen(three_d_point, &x, &y, &z); if( ! is_visibl
e) { // Point is outsideviewing volum
e.if(x_pos) *x_pos = x;if(y_pos) *y_pos = y;if(z_d
epth) *z_depth = z;if(visible) *visible = 0;return
0; } // Now point is insideview volume. if(x_p
os) *x_pos = x; if(y_pos) *y_pos = y; if(z_dept
h)*z_depth = z; if(visible) *visible = 1; if(! m
i_show_solid) {// Wireframe being drawn; just retu
rn that point is return 1; // within view volume.
} // Now solid is being shown. if(! three_db_a
rray) return 0; // Point is within view volume. P
ick pixels in a triangle around that point. found
= pick_point_for_3db_rw((x - 2), (y - 2), three_d
b_array); if(found) return 1; 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_array); if(found) ret
urn 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 indicated, us
ing RenderWare picking, so this is called only whe
n solid is // being shown. Note that the pick posi
tion is with respect to the top left corner of the
view window being // (0,0). If the pick results in
a three_d_body’s clump, and the picked clump cor
responds to ANY of the// three_d_bodies inthe arr
ay passed, return value is 1; if no match or no th
ree_d_body, return is 0.// This does not modify th
e selection set in any way.int CBendCADViewPart::p
ick_point_for_3db_rw(int x_pos, int y_pos, BM_3D_B
ODY **three_db_array) { if(three_db_array == NUL
L) return 0; if( (x_pos > m_old_rect.right) || (y
_pos > m_old_rect.bottom)) { // Make sure point g
iven is withinreturn 0;
// viewport. } RwClump *picked_clump = NULL;
RwClump *parent_clump = NULL; long parent_tag,c
lump_tag, required_id;int found = 0; if(! RwPick
Scene(m_scene, x_pos, y_pos, m_camera, &m_pick))
{ // Picking command was not successful.return 0;
} if(m_pick.type == rwNAPICKOBJECT) {
// No clump was picked.return 0; } else
if(m_pick.type == rwPICKCLUMP) {// Some clump was
picked; process it. picked_clump = m_pick.obje
ct.clump.clump;parent_clump = RwGetClumpParent(pic
ked_clump);parent_tag = RwGetClumpTag(parent_clum
p);clump_tag = RwGetClumpTag(picked_clump);if(pare
nt_tag == 1) { // Body of face/ben
dline/formingwas picked.for(int i=0; three_db_arra
y[i]; ++i) { // Check if it matches any of the one
s in array.if(three_db_array[i] == NULL) break;req
uired_id = three_db_array[i]->get_idx();if(clump_t
ag%10000 == required_id){found = 1;break;}}return
found;} // Now some edge’s clump was picked. C
heck if it matches any of the ones in array.for(in
t i=0; three_db_array[i]; ++i) {if(three_db_array
[i] == NULL) break;required_id = three_db_array[i]
->get_idx();if(parent_tag%10000 == required_id) {f
ound = 1;break;} } } return found;} // Thi
s allows the user to insert itemsinto the selectio
n set. "list" is an array of pointers// to three-d
-bodies, terminated by NULL to indicate end of arr
ay. If list is passed as NULL, every // three-d-bo
dy in the part is inserted into the selection set.
void CBendCADViewPart::insert_selection_set(BM_3D
_BODY **list){ int tag;BV_SELECT_DATA *data = NUL
L; if(! list) { // Insert every th
ree_d_body in part into selection set.BM_PART *par
t = NULL;CBendCADDoc* pDoc = GetDocument();ASSERT_
VALID(pDoc);part = pDoc->get_part();if(! part) ret
urn; BM_FACE *face = NULL;BM_BENDLINE *bendline =
NULL;BM_FORMING *forming = NULL;for(face = part->
get_face_list(); face; face = (BM_FACE *)face->nex
t()) { if(! face) continue;tag = 100000*(face->ge
t_idx()) + 10000 + face->get_idx();if(! m_selectio
n_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(ta
g, (long)data);}}for(bendline = part->get_bendline
_list(); bendline; bendline = (BM_BENDLINE *)bendl
ine->next()) { if(! bendline) continue;tag = 1000
00*(bendline->get_idx()) + 10000 + bendline->get_i
dx();if(! m_selection_set.find(tag,NULL)) {data =
new BV_SELECT_DATA;data->key = tag;data->edge = NU
LL;data->world_pt = BM_POINT(0.0, 0.0, 0.0);m_sele
ction_set.insert(tag, (long)data);}}for(forming =
part->get_forming_list(); forming; forming = (BM_F
ORMING *)forming->next()) { if(! forming) continu
e;tag = 100000*(forming->get_idx()) + 10000 + form
ing->get_idx();if(! m_selection_set.find(tag, NUL
L)) {data = new BV_SELECT_DATA;data->key = tag;dat
a->edge = NULL;data->world_pt = BM_POINT(0.0, 0.0,
0.0);m_selection_set.insert(tag, (long)data);}}Dr
awPart(m_hdc);return;}BM_3D_BODY *three_d_body;lon
g i;for(i=0, three_d_body = list[0]; three_d_body;
++i, three_d_body = list[i]) {if(! three_d_body)
break;tag = 100000*(three_d_body->get_idx()) + 100
00+ three_d_body->get_idx();if(! m_selection_set.f
ind(tag, NULL)) {data =new BV_SELECT_DATA;data->ke
y = tag;data->edge = NULL;data->world_pt = BM_POIN
T(0.0, 0.0, 0.0);m_selection_set.insert(tag, (lon
g)data);}}DrawPart(m_hdc);return;}// This function
returns the largest of the x, y and z projections
of the part’s// bounding box.double CBendCADView
Part::get_approx_part_size(void){ if(md_part_bbox
_size) { double size = __max(md_part_bbox_size
[0], md_part_bbox_size[1]); size = __max(size,
md_part_bbox_size[2]); return size; } else re
turn 0.0;}// This function passes back the boundin
g box size of the part in its original orientatio
n,in the// array "dimensions". This array should b
e at least of size 3. Returns 1 if successful, 0 o
therwise.// Caution: This is a quick and hence not
very accurate calculation; if you want greater pr
ecision,// writeyour own function.int CBendCADView
Part::get_part_dimensions(double *dimensions){ CB
endCADDoc* pDoc = GetDocument();if(! pDoc) return
0;BM_PART*part = pDoc->get_part();if(! part) retur
n 0;if(! dimensions) return 0;int i;BM_POINT centr
oid;RwMatrix4d *temp = RwCreateMatrix();i = comput
e_part_centroid(part, 1, ¢roid);if(! i) return
0; i = compute_part_bbox(part, 1, temp, centroi
d, dimensions, NULL); if(! i) return 0;RwDestroyMa
trix(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_t
ransformations(void) ;/*パートの2D->3D変形をリセッ
トする。’body’は、アイデンティティ変形になる変形
を持つ面である。他のボディは、この基本ボディ(ベー
ス・ボディ)に関する屈曲情報に従って、各々の変形を
設定する。この関数は、すべての変形母体(マトリック
ス)を更新する。基本的にこの関数では、ユーザーがパ
ート全体に行なった回転や移動のすべてを取り消し(ア
ンドゥー)できる。*/void reset_part_2Dto3D_transfo
rmations(BM_3D_BODY *base_body) ;/*********** ****
****** ********** ********** ********** **********
********** ********** **********これらの関数は、
ユーザーにパートの回転または移動を実施させる。たと
えば、屈曲のとき、ユーザーはパートの反転を希望する
ことがある。これらの関数は、パート全体に均一に作用
する。すなわち、すべての面−穴−ベンドラインが全く
同様に変化する。これらの関数が2D->3D変形であること
に注意せよ。すなわち、これらの関数はパートの3Dバー
ジョンだけを変更するが、これらの関数はパートの平面
バージョンの計算を要する。基本的にこれらの関数が実
施する唯一のことは、すべてのボディに付随する2D-3D
変形を変更し、すべてのボディの3D-バージョンを’not
-up-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);}
的板金製造設備のブロックダイヤグラム図である。
歩的板金製造設備のブロックダイヤグラム図である。
ル、データベース及びステーションモジュールの間のそ
れぞれのデータの流れを図示する。
により実行される一般的な工程及び操作のフローチャー
トである。
ュールの各々により実行される基本的工程及び操作の代
表的フローチャートである。
リズム或いは工程の論理フローを説明するフローチャー
トである。
リズム或いは工程の論理フローを説明するフローチャー
トである。
による、接触した角部を有する4曲げ箱及び開放された
角部を有する4曲げ箱についての特徴抽出操作を説明す
る。
発明の側面による、接触した角部を有する4曲げ箱及び
開放された角部を有する4曲げ箱についての特徴抽出操
作を説明する。
明の他の側面による、4曲げ箱、ブリッジ及び他の4曲
げ箱を有するパーツについての検索キーを特定するため
の特徴関連操作及び工程を説明する。
2次元単一図面図から3次元モデルを生成するためにな
される工程及び操作の論理フローを説明するフローチャ
ートである。
なわれる自動トリミング機能及びクリーンアップ機能の
例を説明する。
程のための図面を作成するために行なわれる自動トリミ
ング機能及びクリーンアップ機能の例を説明する。
なわれる自動トリミング機能及びクリーンアップ機能の
例を説明する。
の発明の側面による、面検出工程においてなされる種々
の工程及び操作を説明する。
の発明の側面による、面検出工程においてなされる種々
の工程及び操作を説明する。
線検出工程の実行から最終曲げグラフデータの生成を説
明する。
線検出工程の実行から最終曲げグラフデータの生成を説
明する。
び他の工程を用いて最初の3次元図面(厚さを有しな
い)に基づいて2次元モデルを生成するための基本的論
理フローのフローチャートである。
プ操作を用いて最初の2次元3面図に基づいて3次元モ
デルを生成するための基本的論理フローのフローチャー
トである。
て2次元クリーンアップ操作を行なうための工程及び操
作の基本的論理フローのフローチャートである。
元クリーンアップ操作により加工される代表的2次元3
面図の図及び側面を説明する。
ップ操作の回転された図の特徴を説明する。図23
(b)はこの発明の側面による、この発明の2次元クリ
ーンアップ操作に関連する標準形態を説明する。
による、厚さを有する2次元3面図及び厚さ除去工程を
用いて生成される厚さを有しない簡単化された2次元3
面図を説明する。図24(c)はこの発明の側面によ
る、代表的パーツの横断厚さ線分及び厚さ円弧の図であ
る。
面から厚さを有しない3次元モデルを展開するために実
行される種々の工程及び操作の論理フローのフローチャ
ートである。
して本発明を実行する際に、使用される曲げモデルの代
表的データ構造及びアクセスアルゴリズムを説明する。
ーアの構造のブロックダイヤグラムを説明する。
的ソリッド図ウインドウ表示を説明する。
的ワイヤフレーム図ウインドウを説明する。
元平面スクリーン像ウインドウ表示を説明する。
影図スクリーン像を説明する。
される種々の寸法事項の例を説明する。
明の1つの側面による、種々の異なるパーツについてフ
ランジ長さが定義される態様を図示する。
側面による、2つの異なるタイプのパーツについて補助
的なフランジ長さを追加することを図示する。
明の更に他の側面による、厚さを備えて表示される種々
のパーツについてフランジ長さが指示される態様を図示
する。
寸法方法及び交差寸法方法による、鋭角曲げ角度を有す
るパーツのフランジ長さが表示される態様を示す。
ンタフェースの使用により曲げプランが生成されるため
に行なわれる工程及び操作の論理フローのフローチャー
トである。
して表示される曲げ順入力スクリーン像の例を図示す
る。
側面による、曲げ順の選択及び挿入方向の修正の例を示
す。
リーン表示の更なる例を示す。
リーン表示の更なる例を示す。
提案された曲げ順を修正し且つ編集するのを容易にする
ために設けられるドラッグ及びドロップ編集特性を示
す。
るために図形的に表示される種々の表示メニュー及びデ
ータテーブルの例を示す。
アップを容易にするために曲げオペレータに対して表示
される代表的工具セットアップウインドウを示す。
付された音声及び映像情報を有する3次元ソリッド図ウ
インド表示の例を示す。
び映像情報を読み出すためのアイコンと共に組み込まれ
た表示ウインドウの他の例を示す。
ジ編集ウインドウの例を示す。
れるこの発明の干渉チェック機能の例を示す。
れるこの発明の干渉チェック機能の例を示す。
ティックを用いて3次元幾何学形状の回転及び表示を操
作するための、この発明の操作システムを示す。
用いて3次元幾何学形状のズーミング及び表示を操作す
るためのこの発明の操作システムを示す。
いて、3次元幾何学形状のパンニング及び表示を操作す
るための、この発明の操作システムを示す。
ステムを実行するために、実行される工程及び操作の代
表的フローチャートである。
動をカーソル運動へ写像する例を示す。
するためになされる工程及び操作の代表的フローチャー
トである。
られ且つ表示されるメインメニューウインドウ表示の例
を示す。
とを可能とするように設けられた代表的パーツ情報ウイ
ンドウ表示を示す。
を可能とするように設けられた代表的曲げ線情報ウイン
ドウ表示を示す。
の、この発明の代表的曲げ順ウインドウ表示を示す。
るための、この発明の代表的曲げシミュレーションウイ
ンドウ表示を示す。
して設けられ且つ表示される、この発明の代表的メニュ
ースクリーン図及び構造である。
の代表的メニュースクリーン図及び構造である。
ツの3次元表示の例を示す。
デルを生成する際に使用されるこの発明の3次元クリー
ンアップ工程による、前記一方が開放された線分が3次
元表示から除去された後のパーツを示す。
元表現を示す。
モールド線が追加された後のパーツを示す。
前のパーツの代表的部分を示す。
前記正常化及びトリミングが行なわれた後のパーツの部
分を示す。
Claims (152)
- 【請求項1】 高知能製造設備において製造されるべき
パーツの曲げモデルを展開するためのシステムにして、
前記パーツは、複数の面と少なくとも一つの曲げ線とを
含み、前記システムは以下を含む。前記パーツに関連す
る初期パーツ情報を受信する受信システムにして、前記
初期パーツ情報は、第1座標空間における前記パーツの
表現に関連するデータを含むもの;前記第1座標空間内
で前記初期パーツ情報に基づいて、前記パーツの面を検
出するための面検出システム;前記面検出システムによ
り検出された前記面に基づいて、前記パーツの少なくと
も一つ曲げ線を同定するための曲げ線同定システム;前
記面検出システムにより検出された前記面の各々に対し
て所定操作を加えることにより、前記パーツに関連し且
つ第2座標空間内での前記パーツの表現に関連するデー
タを含む追加パーツ情報を生成するためのシステムにし
て、前記所定操作は、少なくとも前記初期パーツ情報と
前記曲げ線同定システムにより同定された少なくとも一
つの曲げ線とに基づいて行われるもの。 - 【請求項2】 請求項1によるシステムにして、前記第
1所定座標空間が、2次元座標空間からなり、前記第2
所定座標空間は3次元座標空間からなり、前記所定操作
が、前記面検出システムにより検出された前記各面にな
される折り畳み操作からなる。 - 【請求項3】 請求項2によるシステムにして、前記折
り畳み操作は、前記面検出システムにより検出された各
面の、前記曲げ線同定システムにより同定された少なく
とも1つの曲げ線に対する回転及び移動を含む。 - 【請求項4】 請求項2によるシステムにして、前記初
期パーツ情報は、前記パーツの少なくとも1本に関連す
る曲げ角度量を備え、前記曲げ操作は、この曲げ角度量
に基づいて行なわれる。 - 【請求項5】 請求項4のシステムにして、前記折り畳
み操作は、前記パーツの少なくとも1つの曲げ線の周り
の、前記曲げ角度量に基づく前記各面の回転及び移動か
らなる。 - 【請求項6】 請求項1によるシステムにして、前記第
1所定座標空間は、3次元座標空間からなり、前記第2
所定座標空間は、2次元座標空間からなり、前記所定操
作は、前記面検出システムにより検出された前記面に対
してなされる展開操作からなる。 - 【請求項7】 請求項6によるシステムにして、前記展
開操作は、前記面検出システムにより検出された前記各
面の、前記曲げ線同定システムにより同定された前記少
なくとも1つの曲げ線に対する回転及び移動操作を含
む。 - 【請求項8】 請求項6によるシステムにして、前記初
期パーツ情報は、更に、前記パーツの少なくとも1つの
曲げ線に対する曲げ角度量を含み、前記展開操作は、前
記曲げ角度量に基づいて行なわれる。 - 【請求項9】 請求項8によるシステムにして、前記展
開操作は、前記パーツの少なくとも1つの曲げ線の周り
の、前記曲げ角度量に基づく前記面の各々の回転及び移
動操作からなる。 - 【請求項10】 請求項1によるシステムにして、前記
第1所定座標空間内での前記パーツの表現に関する前記
データは、座標データからなる。 - 【請求項11】 請求項1によるシステムにして、前記
第1所定空間内での前記パーツの表現に関する前記デー
タは、ベクトルデータを含む。 - 【請求項12】 請求項1によるシステムにして、前記
パーツは、板金パーツからなる。 - 【請求項13】 請求項1によるシステムにして、前記
複数の面は、前記パーツの複数の基本面及び前記パーツ
の複数の屈曲面からなる。 - 【請求項14】 請求項1によるシステムにして、前記
パーツの追加の特徴を検出するシステムを更に含み、前
記所定操作は、前記パーツの前記追加の特徴に対してな
される。 - 【請求項15】 請求項14によるシステムにして、前
記追加の特徴は、前記パーツの複数の穴、開口部及び特
殊な成形部を含む。 - 【請求項16】 請求項1によるシステムにして、前記
初期パーツ情報は、3次元座標空間内での前記パーツの
表現に関連するデータを含み、前記データは、前記3次
元座標空間内での前記パーツの厚さデータを含む。 - 【請求項17】 請求項16によるシステムにして、前
記厚さデータを削除し、厚さを含まない前記3次元座標
空間内での前記パーツの表現に関連する変形されたパー
ツデータを提供するシステムを更に含む。 - 【請求項18】 請求項17によるシステムにして、前
記面検出システムは、前記変形されたパーツデータ及び
厚さを有しない前記3次元座標空間内での前記パーツの
前記表現とに基づいて前記パーツの前記複数の面を検出
する。 - 【請求項19】 請求項18によるシステムにして、前
記第2所定座標空間は、2次元座標空間を含み、前記所
定操作は、前記面検出システムにより検出された前記面
に対してなされる展開操作を有する。 - 【請求項20】 請求項19によるシステムにして、前
記展開操作は、前記面検出システムにより検出された前
記複数の面の各々の、前記曲げ線同定システムにより同
定された少なくとも1つの曲げ線に対する回転及び並行
移動操作からなる。 - 【請求項21】 請求項1によるシステムにして、前記
初期パーツ情報に関連する前記データに対しての自動装
飾及びクリーンアップ操作を行ない、前記面検出システ
ム用及び前記曲げ線同定システム用のデータを作成する
自動装飾及びクリーンアップシステムを更に含む。 - 【請求項22】 請求項21によるシステムにして、前
記データは、前記パーツの少なくとも線分エンティティ
ー及び曲げ線エンティティーを表現するパーツエンティ
ティーデータを含み、前記自動装飾及びクリーンアップ
システムは、前記エンティティーの交差点を検出し、前
記検出された交差点において前記エンティティーを選択
的に分断するためのシステムと結果としての分断された
エンティティーが前記検出された交差点に基づいて共通
の最終点を持つように割り当てるシステムとを含む。 - 【請求項23】 請求項21によるシステムにして、前
記データは、少なくとも前記パーツの線分エンティティ
ーを表現するパーツエンティティーデータを含み、前記
自動装飾及びクリーンアップシステムは、前記隣接する
エンティティーの間の離間した交差領域を検出し、前記
隣接するエンティティーを、前記隣接するエンティティ
ーに対して共通の最終点を割り当てることにより選択的
に接続するシステムを含む。 - 【請求項24】 請求項23によるシステムにして、前
記隣接するエンティティーの最終点が相互に所定の距離
の範囲内にある場合に、前記離間交差領域検出用システ
ムにより、前記離間交差領域が検出される。 - 【請求項25】 請求項1によるシステムにして、前記
初期パーツ情報に関連する前記データは、少なくとも前
記パーツの線分エンティティーを表現するパーツエンテ
ィティーデータからなり、前記面検出システムは、前記
パーツエンティティーデータに基づき前記パーツのリン
ク及びエンティティー解析を行ない、前記パーツの前記
面を検出する。 - 【請求項26】 請求項25によるシステムにして、前
記ループ及びエンティティー解析は、前記パーツの外側
境界に対して最初行なわれ、次に前記パーツの内部境界
に対して行なわれる。 - 【請求項27】 請求項26によるシステムにして、前
記面検出システムは、前記パーツの外側境界に対して前
記ループ及びエンティティー解析を行なう時エンティテ
ィーの最初の結合されたリストを生成し、前記エンティ
ティーの最初の結合リストは、前記パーツの外側ループ
及び境界を規定する。 - 【請求項28】 請求項27によるシステムにして、前
記面検出システムは、更に、前記パーツの内部の境界及
び領域に対して前記ループ及びエンティティー解析を行
なった時、前記エンティティーの追加の結合リストを生
成し、前記エンティティーの追加の結合リストは、前記
パーツの内部のループ及び境界を規定する。 - 【請求項29】 請求項28によるシステムにして、前
記面検出システムは、更に、前記エンティティーの最初
の結合リストにより定義される外側ループ及び前記エン
ティティーの前記追加の結合リストにより定義される前
記内部ループとに基づきループツリーを生成するための
システムを有する。 - 【請求項30】 請求項29によるシステムにして、前
記面検出システムは、前記ループツリー及び前記最初の
結合されたリストエンティティー及び前記追加の結合さ
れたエンティティーのリストにより定義される境界のシ
ーケンスに基づいて前記パーツの各面を検出する。 - 【請求項31】 請求項28によるシステムにして、前
記曲げ線同定システムは、前記最初の結合されたエンテ
ィティーのリスト及び前記追加の結合されたエンティテ
ィーのリストを分析し、前記面検出システムにより検出
された前記各面の間の共通線分エンティティーを決定す
るシステムを含む。 - 【請求項32】 請求項31によるシステムにして、前
記少なくとも1つの曲げ線は、前記複数の面のうちの1
つが当該複数の面のうちの他の1つとただ1つの共通線
分エンティティーを有することを検出することに基づい
て同定される。 - 【請求項33】 請求項32によるシステムにして、前
記少なくとも1つの曲げ線は、前記複数の面の間で検出
される1つの共通線分エンティティーにおいて同定され
規定される。 - 【請求項34】 請求項32によるシステムにして、前
記曲げ線同定システムは、前記共通線分エンティティー
を決定するためのシステムが、前記複数の面の間に1つ
以上の線分エンティティーが存在することを検出する時
前記パーツの曲げ線を同定するための所定のヒューリス
ティックを適応する。 - 【請求項35】 請求項34によるシステムにして、前
記ヒューリスティックは、前記パーツに対して、最小数
の全曲げ線が同定されるように、前記パーツの曲げ線を
同定する。 - 【請求項36】 請求項34によるシステムにして、前
記ヒューリスティックは、最長の長さを有する共通線分
エンティティーに基づいて、前記複数の面の1つが前記
複数の面の他の1つと1つ以上の共通線分エンティティ
ーを有する時前記パーツの曲げ線を同定する。 - 【請求項37】 請求項1によるシステムにして、前記
曲げ線同定システムは、前記面検出システムにより検出
された前記複数の面の間の共通の端部を検出するシステ
ムを有し、少なくとも1つの曲げ線は、前記複数の面の
1つが前記複数の面の他の1つとただ1つの共通端部を
有することの検出に基づいて同定される。 - 【請求項38】 請求項37によるシステムにして、前
記少なくとも1つの曲げ線は、前記複数の面の間で検出
された1つの共通端部において同定され定義される。 - 【請求項39】 請求項37によるシステムにして、前
記曲げ線同定システムは、前記共通端部を検出するため
のシステムが、前記複数の面の間に1つ以上の共通端部
が存在することを検出した時、前記パーツの複数の曲げ
線を同定するための所定のヒューリスティックを適応す
る。 - 【請求項40】 請求項39によるシステムにして、前
記ヒューリスティックは、前記パーツに対して最小数の
全曲げ線が同定されるように、前記パーツの曲げ線を同
定する。 - 【請求項41】 請求項39によるシステムにして、前
記ヒューリスティックは、最長長さを有する共通端部に
基づいて、前記複数の面の1つが当該複数の面の他の1
つと1つ以上の端部を有する時前記パーツの曲げ線と同
定することを含む。 - 【請求項42】 請求項1によるシステムにして、前記
パーツに関連する縮小量を受け取るシステムと、前記複
数の面に対して前記所定の操作を行なう際に、前記縮小
量に基づいて曲げ縮小に対して補正を行なうシステムと
を更に備えてなるもの。 - 【請求項43】 請求項42によるシステムにして、前
記所定の操作は、前記面検出システムにより検出された
前記複数の面に対してなされる折り曲げ操作からなり、
前記曲げ縮小に対する補正用システムは、前記折り曲げ
操作を行なう際に、前記パーツの前記曲げ線の各サイド
において、前記縮小量の半分だけ前記各面の寸法長さを
増大する。 - 【請求項44】 請求項42によるシステムにして、前
記所定の操作は、前記面検出システムにより検出された
前記複数の面に対してなされる展開操作からなり、前記
曲げ縮小量に対する補正用システムは、前記展開操作を
行なう際に、前記パーツの前記曲げ線の両サイドにおい
て前記縮小量の半分だけ前記各面の寸法長さを縮小す
る。 - 【請求項45】 高知能製造設備において製造されるべ
きパーツの曲げモデルを生成するための方法にして、前
記パーツは複数の面と少なくとも1つの曲げ線とを含
み、前記方法は以下の工程を含む。前記パーツに関連す
る初期パーツ情報を受信し、前記初期パーツ情報は第1
座標空間における前記パーツの表現に関連するデータを
含み、 前記第1座標空間内で前記初期パーツ情報に基づいて前
記パーツの前記複数の面を検出し、 前記検出により検出された前記複数の面に基づいて前記
パーツの少なくとも1つの曲げ線を同定し、 前記検出により検出された前記複数の面の各々に対して
所定の操作を行なうことにより第2座標空間内での前記
パーツの表現に関連するデータを含む追加のパーツ情報
を生成し、前記操作は、前記初期パーツ情報及び前記同
定により同定された少なくとも1つの曲げ線とに基づい
てなされる。 - 【請求項46】 請求項45による方法にして、前記第
1所定座標空間は2次元座標空間からなり、前記第2所
定座標空間は3次元座標空間からなり、前記方法は、前
記検出により検出された前記複数の面に対してなされる
折り曲げ操作を含む。 - 【請求項47】 請求項46による方法にして、前記折
り曲げ操作は、前記同定により同定された少なくとも1
つの曲げ線に対する前記複数の面の各々の回転及び並行
移動を含む。 - 【請求項48】 請求項46による方法にして、前記初
期パーツ情報は、前記パーツの少なくとも1つの曲げ線
に関連する曲げ角度量を含み、前記折り曲げ操作は、こ
の曲げ角度量に基づいてなされる。 - 【請求項49】 請求項48による方法にして、前記折
り曲げ操作は、前記折り曲げ角度量に基づく前記パーツ
の少なくとも1つの曲げ線の周りでの前記複数の面の各
々の回転及び並行移動を含む。 - 【請求項50】 請求項45の方法にして、前記第1所
定座標空間は、3次元座標空間を含み、前記第2所定座
標空間は2次元座標空間を含み、前記方法は、前記検出
により検出された前記複数の面に対する展開操作を行な
うことを含む。 - 【請求項51】 請求項50による方法にして、前記展
開操作は、前記同定により同定された少なくとも1つの
曲げ線に対して前記複数の面の各々を回転し及び並行移
動することを含む。 - 【請求項52】 請求項50による方法にして、前記初
期パーツ情報は、前記パーツの少なくとも1つの曲げ線
に対する曲げ角度量を含み、前記展開操作はこの曲げ角
度量に基づいてなされる。 - 【請求項53】 請求項52による方法にして、前記展
開操作は、前記曲げ角度量に基づく、前記パーツの少な
くとも1つの曲げ線の周りの前記複数の面の各々の回転
及び並行移動を含む。 - 【請求項54】 請求項45による方法にして、前記パ
ーツの追加の特徴を検出することを含み前記所定の操作
は、このパーツの追加の特徴に対してなされる。 - 【請求項55】 請求項54による方法にして、前記追
加の特徴は、前記パーツの穴、開口部及び特殊な成形部
を含む。 - 【請求項56】 請求項45による方法にして、前記初
期パーツ情報は、3次元空間における前記パーツの表現
に関連するデータを含み、前記データは、前記3次元空
間における前記パーツの厚さのデータを含む。 - 【請求項57】 請求項56による方法にして、前記厚
さのデータを消去し前記3次元空間において厚さを持た
ない前記パーツの表現に関連する変形されたパーツデー
タを提供することを含む。 - 【請求項58】 請求項57による方法にして、前記パ
ーツの前記各面を検出することは、前記3次元空間にお
ける厚さを有しない前記パーツの前記表現及び前記変形
されたパーツデータとに基づいて行なわれるように構成
されている。 - 【請求項59】 請求項58による方法にして、前記第
2の所定座標空間は、2次元座標空間からなり、前記方
法は、前記検出操作により検出された前記複数の面に対
する展開操作を行なうことを含む。 - 【請求項60】 請求項45による方法にして、前記複
数の面を検出し及び少なくとも1つの曲げ線を同定する
前に、前記初期パーツ情報のデータに対して自動装飾及
びクリーンアップ操作を行なうことを有する。 - 【請求項61】 請求項45による方法にして、前記初
期パーツ情報のデータは、少なくとも前記パーツの線分
エンティティーを表現するパーツエンティティーデータ
を含み、前記複数の面を検出する操作は、前記パーツの
複数の面を検出するために、前記パーツエンティティー
データに基づいて前記パーツのループ及びエンティティ
ー分析を行なう操作を有する。 - 【請求項62】 請求項61による方法にして、前記ル
ープ及びエンティティー分析は、前記パーツの外側境界
に対して最初行なわれ、次に前記パーツの内部境界及び
領域に対してなされる。 - 【請求項63】 請求項45による方法にして、前記少
なくとも1つの曲げ線を検出する操作は、前記検出によ
り検出された前記面の間の共通端部を検出する操作を含
み、前記少なくとも1つの曲げ線は、前記複数の面のう
ちの1つが当該複数の面のうちの他の1つとただ1つの
共通端部を有することを検出することにより基づいて同
定される。 - 【請求項64】 請求項63による方法にして、前記少
なくとも1つの曲げ線を同定する操作は、前記複数の面
の間で1つ以上の共通端部が検出された時、前記パーツ
の曲げ線を同定するために所定のヒューリスティックを
適合する操作を含む。 - 【請求項65】 請求項64による方法にして、前記ヒ
ューリスティックは、前記パーツに対して最小数の全曲
げ線が同定されるように、前記パーツの曲げ線を同定す
る操作を含む。 - 【請求項66】 請求項64による方法にして、前記ヒ
ューリスティックは、最長長さを有する共通端部に基づ
いて、前記複数の面の1つが当該複数の面の他の1つと
1以上の共通端部を有する時前記パーツの曲げ線を同定
する操作を含む。 - 【請求項67】 請求項45による方法にして、前記パ
ーツに関連する縮小量を受信し、この縮小量に基づい
て、前記複数の面に所定の操作を行なう時、曲げ縮小に
ついて補正を行なう操作を更に含む。 - 【請求項68】 請求項67による方法にして、前記複
数の面に対して折り曲げ操作を行なう工程を更に含み、
前記曲げ縮小についての補正操作は、前記折り曲げ操作
は行なわれる時前記パーツの曲げ線の各サイドにおいて
前記縮小量の半分だけ前記面の寸法長さを増大する操作
を含む。 - 【請求項69】 請求項67による方法にして、更に、
前記複数の面に対して展開操作を行なうことを含み、前
記縮小量についての補正は、前記展開操作を行なう時、
前記パーツの前記曲げ線の各サイドにおいて前記縮小量
の半分だけ前記各面の寸法長さを縮小する操作を含む。 - 【請求項70】 製造設備において製造されるべきパー
ツの曲げモデルを展開するためのシステムにして、前記
パーツは、複数の面と少なくとも一つの曲げ線とを有
し、前記システムは以下を含む。前記パーツに関連する
初期パーツ情報を受取る手段にして、前記初期パーツ情
報は、第1の所定座標空間内における前記パーツの表現
に関連するデータを含むもの;前記第1の所定座標空間
内で前記初期パーツ情報に基づいて前記パーツの面を検
出するための手段;前記面検出手段により検出された前
記面に基づいて前記パーツの少なくとも一つの曲げ線を
同定するための手段;前記検出手段により検出された前
記面に対して所定の操作を行うことにより、第2の所定
座標空間内における前記パーツの表現に関連するデータ
を含む追加のパーツ情報を生成するための手段にして、
前記所定の操作は、少なくとも一部は、前記曲げ線検出
手段により同定された曲げ線に基づいて行われる。 - 【請求項71】 請求項1によるシステムにして、前記
第1所定座標空間は2次元座標空間からなり、前記第2
所定座標空間は、3次元座標空間からなり、前記所定操
作は、前記面検出手段により検出された前記面に対して
なされる曲げ操作からなる。 - 【請求項72】 請求項71によるシステムにして、前
記曲げ操作は、前記曲げ線同定手段により同定された少
なくとも1つの曲げ線に対する、前記面検出手段により
検出された前記複数の面の各々の回転及び並行移動を含
む。 - 【請求項73】 請求項71によるシステムにして、前
記初期パーツ情報は、前記パーツの少なくとも1つの曲
げ線に関連する曲げ角度量を含み、前記折り曲げ操作
は、前記曲げ角度量に基づいて行なわれる。 - 【請求項74】 請求項70によるシステムにして、前
記第1所定座標空間は3次元座標空間からなり、前記第
2所定座標空間は2次元座標空間からなり、前記所定動
作は、前記面検出手段により検出された前記複数の面に
対してなされる展開操作からなる。 - 【請求項75】 請求項74によるシステムにして、前
記展開操作は、前記面検出手段により検出された前記複
数の面の各々を、前記曲げ線同定手段により同定された
少なくとも1つの曲げ線に対して回転し及び並行移動す
る操作を含む。 - 【請求項76】 請求項74によるシステムにして、前
記初期パーツ情報は、前記パーツの少なくとも1つの曲
げ線に関連する曲げ角度量を含み、前記展開操作は、こ
の曲げ角度量に基づいて行なわれる。 - 【請求項77】 請求項70によるシステムにして、前
記パーツの追加の特徴を検出する手段を更に含み、前記
所定操作は、このパーツの追加の特徴に対してなされ
る。 - 【請求項78】 請求項77によるシステムにして、前
記追加の特徴は、前記パーツの穴及び開口部及び特殊成
形部を含む。 - 【請求項79】 請求項70によるシステムにして、前
記初期パーツ情報は3次元空間における前記パーツの表
現に関連するデータを含み、前記データは前記3次元座
標空間内での前記パーツの厚さデータを含む。 - 【請求項80】 請求項79によるシステムにして、前
記厚さデータを消去し前記3次元座標空間において厚さ
を有しない前記パーツの表現に関連する変形されたパー
ツデータを提供する手段を更に含む。 - 【請求項81】 請求項80によるシステムにして、前
記面検出手段は、前記変形されたパーツデータ及び前記
3次元座標空間において厚さを有しない前記パーツの前
記表現とに基づいて前記パーツの複数の面を検出する。 - 【請求項82】 請求項81によるシステムにして、前
記第2の所定座標空間は2次元座標空間を有し、前記所
定の操作は、前記面検出手段により検出された前記複数
の面に対してなされる展開操作を含む。 - 【請求項83】 請求項70によるシステムにして、前
記初期パーツ情報に関連する前記データに対して自動装
飾及びクリーンアップ操作を行ない、前記面検出手段及
び前記曲げ線同定手段のための前記データを作成するた
めの自動装飾及びクリーンアップ手段を更に含む。 - 【請求項84】 請求項83によるシステムにして、前
記データは、少なくとも前記パーツの線分エンティティ
ー及び曲げ線エンティティーを表現するパーツエンティ
ティーデータを含み、前記自動装飾及びクリーンアップ
手段は、前記エンティティーの交差点を検出し且つ前記
検出された複数の交差点において前記エンティティーを
選択的に分断する手段と結果としての分断されたエンテ
ィティーが前記検出された複数の交差点に基づいて共通
の最終点を有するように割り当てる手段とを有する。 - 【請求項85】 請求項83によるシステムにして、前
記データは、前記パーツの線分エンティティーを少なく
とも表現するパーツエンティティーデータを備え、前記
自動装飾及びクリーンアップ手段は、隣接するエンティ
ティーの間の離間した交差領域を検出し且つ当該隣接エ
ンティティーに対して共通最終点を割り当てることによ
り当該隣接エンティティーを選択的に接続する手段を有
する。 - 【請求項86】 請求項85によるシステムにして、前
記隣接エンティティーの端部ポイントが相互に所定距離
の間にある時、前記離間交差領域検出手段により離間交
差領域が検出される。 - 【請求項87】 請求項70によるシステムにして、前
記初期パーツ情報に関連するデータは、少なくとも前記
パーツの線分エンティティーを表現するパーツエンティ
ティーデータを含み、前記面検出手段は、前記パーツの
前記面を検出するために、前記パーツエンティティーデ
ータに基づいて前記パーツのループ及びエンティティー
分析を行なう。 - 【請求項88】 請求項87によるシステムにして、前
記ループ及びエンティティー解析は、当初前記パーツの
外側境界に対して行なわれ、次に当該パーツの内部境界
及び領域に対して行なわれる。 - 【請求項89】 請求項88によるシステムにして、前
記面検出手段は、前記パーツの外側領域に対してループ
及びエンティティー解析を行なう際に、エンティティー
の初期連結リストを生成し、前記エンティティーの初期
連結リストは、前記パーツの外側ループ及び境界を定義
する。 - 【請求項90】 請求項89によるシステムにして、前
記面検出手段は、前記パーツの内側境界及び領域に対し
て前記ループ及びエンティティー解析を行なう際に、前
記エンティティーの追加の連結リストを生成し、前記追
加のエンティティーの連結リストは前記パーツの内部ル
ープ及び境界を定義する。 - 【請求項91】 請求項90によるシステムにして、前
記面検出手段は、更に、前記初期エンティティー連結リ
ストにより定義される前記外側ループ及び前記追加のエ
ンティティー連結リストにより定義される内部ループに
基づいてループツリーを生成する手段を備える。 - 【請求項92】 請求項91によるシステムにして、前
記面検出手段は、前記ループツリー及び前記初期連結リ
ストエンティティー及び前記エンティティーの追加の連
結リストにより定義される境界のシーケンス等に基づい
て前記パーツの前記面を検出する。 - 【請求項93】 請求項70によるシステムにして、前
記曲げ線同定手段は、前記面検出手段により検出された
前記面の間の共通端部を検出するための手段を備え、前
記少なくとも1つの曲げ線は、前記面の1つが前記面の
他の1つとただ1つの共通端部を有することを検出する
ことに基づいて同定される。 - 【請求項94】 請求項93によるシステムにして、前
記曲げ線同定手段は、前記共通端部検出手段が、前記面
の間に1つ以上の共通端部が存在することを検出する時
前記パーツの曲げ線を同定するための所定のヒューリス
ティックを適応する。 - 【請求項95】 請求項94によるシステムにして、前
記ヒューリスティックは、前記パーツに対して最小数の
全曲げ数が同定されるように、前記パーツの曲げ線を同
定するものを含む。 - 【請求項96】 請求項94によるシステムにして、前
記ヒューリスティックは、最長の長さを有する共通端部
に基づいて、前記面の1つが前記面の他の1つと1つ以
上の共通端部を有する時前記パーツの曲げ線を同定す
る。 - 【請求項97】 請求項70によるシステムにして、前
記パーツに関連する縮小量を受け取る手段と前記面に対
する所定の操作を行なう際に、前記縮小量に基づいて曲
げ縮小のための補正を行なう手段とを有する。 - 【請求項98】 請求項97によるシステムにして、前
記所定操作は、前記面検出手段により検出された前記面
に対してなされる折り曲げ操作を備え、前記曲げ縮小の
ための補正の手段が、前記曲げ操作を行なう際に前記パ
ーツの曲げ線の両側で前記縮小量の半分だけ前記面の寸
法長さを増大する。 - 【請求項99】 請求項97によるシステムにして、前
記所定の操作は、前記面検出手段により検出される前記
面に対してなされる展開操作を含み、前記曲げ縮小のた
めの補正手段は、前記展開操作を行なう際に前記パーツ
の曲げ線の両側で前記縮小量の半分だけ前記面の寸法長
さを減少させる。 - 【請求項100】 高知能製造設備により製造されるべ
きパーツの曲げモデルを展開するためのシステムにし
て、前記システムは以下を含む。前記パーツに関連する
初期パーツ情報を受信する受信システムにして、前記初
期パーツ情報は、2次元座標空間における前記パーツの
複数の図の各表現を備え、前記複数の表現の各々は前記
パーツの厚さの表現を含み、前記初期パーツ情報は非本
質的情報を含むもの;前記初期パーツ情報に対して2次
元クリーンアップ操作を行い、前記非本質的情報を除去
し、前記各表現を同定するクリーンアップ操作システ
ム;前記同定された各表現においてパーツ厚さの表現を
選択的に除去し、2次元座標空間における厚さを有しな
い、前記パーツについての前記各図の修正表現を提供す
るパーツ厚さ除去システム;前記2次元空間における厚
さを有しない、前記パーツの前記修正表現に基づいて3
次元空間における前記パーツの表現を展開するシステ
ム。 - 【請求項101】 請求項100によるシステムにし
て、前記初期パーツ情報は、少なくとも前記パーツの線
分エンティティーを表現するパーツエンティティーデー
タを備え、前記クリーンアップ操作システムは、前記エ
ンティティーの交差点を検出し且つ前記検出された交差
点において前記エンティティーを選択的に分断する分断
装飾システムを備え、前記分断装飾システムは、前記分
断エンティティーが前記検出された交差点に基づいて共
通の最終点を有するように割り当てる。 - 【請求項102】 請求項101によるシステムにし
て、前記分断及び装飾システムは、隣接するエンティテ
ィーの間の離間した交差領域を検出し且つ前記隣接エン
ティティーに対して共通の最終点を割り当てることによ
り前記隣接エンティティーを選択的に接続するシステム
を有する。 - 【請求項103】 請求項102によるシステムにし
て、前記離間交差領域は、前記隣接するエンティティー
の最終点が相互に所定距離の範囲内にある時前記離間交
差領域を検出するシステムにより検出される。 - 【請求項104】 請求項100によるシステムにし
て、前記クリーンアップ操作システムは、前記初期パー
ツ情報に基づいて連結性グラフ構造を展開するためのシ
ステムを備え、前記クリーンアップ操作システムは、前
記連結性グラフ構造に基づいて前記余計な情報を消去す
る。 - 【請求項105】 請求項104のシステムにして、前
記余分の情報は、連結されない線分エンティティーを含
み、前記連結されない線分エンティティーは少なくとも
寸法線に関連する。 - 【請求項106】 請求項100によるシステムにし
て、前記初期パーツ情報は、パーツエンティティーデー
タとテキストに関連する余分な情報を同定するためのタ
イプ・フィールド・データを備え、前記クリーンアップ
操作システムは、前記タイプ・フィールド・データに基
づいてテキストに関連する前記余分の情報を消去する。 - 【請求項107】 請求項100によるシステムにし
て、前記複数の図は、2次元座標空間内での前記パーツ
の平面図及び正面図及び右側面図を有する。 - 【請求項108】 請求項107によるシステムにし
て、前記クリーンアップ操作システムは、前記初期パー
ツ情報に基づいて、前記パーツの前記平面図及び正面図
及び右側面図の表現を検出するシステムを有する。 - 【請求項109】 請求項100によるシステムにし
て、前記パーツは板金パーツからなる。 - 【請求項110】 請求項100のシステムにして、前
記パーツ厚さ消去システムは、前記複数の図のそれぞれ
において消去すべき前記パーツ厚さ情報を特定し前記複
数の図において残すべき前記パーツの寸法を特定するよ
うにユーザに対して促すシステムを有する。 - 【請求項111】 請求項110のシステムにして、前
記パーツの前記寸法は、前記パーツの外側寸法又は内側
寸法の1つからなる。 - 【請求項112】 請求項100によるシステムにし
て、前記展開システムは、前記2次元空間における前記
パーツの前記変形された表現に基づいて前記3次元空間
における前記パーツの前記表現を展開するために射影操
作を行なうシステムを有する。 - 【請求項113】 請求項112によるシステムにし
て、前記射影操作は、前記複数の図のそれぞれの相対的
な深さを検出し前記複数の図のそれぞれを3次元空間に
射影する。 - 【請求項114】 高知能製造設備により製造されるべ
きパーツの曲げモデルを展開するための方法にして前記
システムは以下の工程を含む。前記パーツに関連する初
期パーツ情報を受信し、前記初期パーツ情報は2次元座
標空間における前記パーツの複数の図の各表現を備え、
前記各表現の各々は、前記パーツの厚さの表現を含むも
のと、 前記初期パーツ情報に対して2次元クリーンアップ操作
を行ない、前記余分の情報を消去し且つ前記表現の各々
を同定するものと、 前記同定された各表現において前記パーツ厚さ表現を選
択的に除去し、2次元座標空間において厚さを有しない
前記パーツの前記各図の修正された表現を提供するもの
と、 前記2次元空間における厚さを有しない前記パーツの修
正された表現に基づいて3次元空間における前記パーツ
の表現を展開するもの。 - 【請求項115】 請求項114による方法にして、前
記初期パーツ情報は、前記パーツの線分エンティティー
を少なくとも表現するパーツエンティティーデータを備
え、前記操作は前記エンティティーの前記交差点を検出
し検出された交差点において前記エンティティーを選択
的に分断する操作を含み、前記結果としての分断された
エンティティーは、前記検出された交差点に基づいて共
通の端点を有するように割り当てられる。 - 【請求項116】 請求項114による方法にして、前
記操作は、隣接するエンティティーの間の離間された交
差領域を検出し前記隣接するエンティティーに対して共
通の端点を付与することにより前記隣接するエンティテ
ィーを選択的に接続する操作を含む。 - 【請求項117】 請求項116による方法にして、前
記離間された交差領域は、前記隣接するエンティティー
が相互に所定距離の間に存在する場合に、前記離間され
た交差領域を検出する方法により検出される。 - 【請求項118】 請求項114による方法にして、前
記操作は、前記初期パーツ情報に基づいて連結性グラフ
構造を展開し、この連結性グラフ構造に基づいて前記余
分の情報を消去する操作を含む。 - 【請求項119】 請求項118による方法にして、前
記余分の情報は、連結されない線分エンティティーを備
え、前記連結されない線分エンティティーは、少なくと
も寸法線に関連する。 - 【請求項120】 請求項114による方法にして、前
記初期パーツ情報は、パーツエンティティーデータとテ
キストに関連する余分の情報を特定するためのタイプ・
フィールド・データを備え、前記操作は、このタイプ・
フィールド・データに基づいてテキストに関連する余分
の情報を消去する。 - 【請求項121】 請求項114による方法にして、前
記複数の図は、2次元空間における前記パーツの平面図
及び正面図及び右側面図からなる。 - 【請求項122】 請求項121による方法にして、前
記操作は、前記初期パーツ情報に基づいて、前記パーツ
の前記平面図及び正面図及び右側面図の表現を検出する
操作を含む。 - 【請求項123】 請求項114による方法にして、前
記パーツは板金パーツを含む。 - 【請求項124】 請求項114による方法にして、選
択的に前記パーツ厚さを消去する工程は、前記複数の図
のそれぞれにおいて消去されるべきパーツの厚さ表現を
特定し且つ前記複数の図のそれぞれにおいて残されるべ
きパーツの寸法を特定するようにユーザに促す操作を含
む。 - 【請求項125】 請求項124による方法にして、前
記パーツの寸法は前記パーツの外側寸法及び内側寸法の
1つを含む。 - 【請求項126】 請求項114による方法にして、前
記展開操作は、前記2次元空間における前記パーツの前
記変形された表現に基づいて3次元空間における前記パ
ーツの表現を展開するための射影操作を実行する操作を
含む。 - 【請求項127】 請求項126による方法にして、前
記射影操作は、前記複数の図のそれぞれの相対的深さを
検出し3次元空間内へ前記複数の図のそれぞれを射影す
る操作を含む。 - 【請求項128】 高知能製造設備により製造されるべ
きパーツの曲げモデルを展開するためのシステムにし
て、前記システムは以下を含む。前記パーツに関連する
初期パーツ情報を受信する受信システムにして、前記初
期パーツ情報は、2次元座標空間における前記パーツの
複数の図の各表現を備え、前記複数の表現の各々は前記
パーツの厚さの表現を含み、前記初期パーツ情報は非本
質的情報を含むもの;前記初期パーツ情報に対して2次
元クリーンアップ操作を行い、前記非本質的情報を除去
し、前記各表現を同定するクリーンアップ操作システ
ム;前記2次元空間における厚さを有しない前記パーツ
の前記同定表現に基づいて3次元空間における前記パー
ツの表現を展開するシステム。 - 【請求項129】 請求項128によるシステムにし
て、前記初期パーツ情報は、少なくとも前記パーツの線
分エンティティーを表現するパーツエンティティーデー
タを備え、前記クリーンアップ操作システムは、前記エ
ンティティーの交差点を検出し且つ前記検出された交差
点において前記エンティティーを選択的に分断する分断
装飾システムを備え、前記分断装飾システムは、前記分
断エンティティーが前記検出された交差点に基づいて共
通の最終点を有するように割り当てる。 - 【請求項130】 請求項129によるシステムにし
て、前記分断及び装飾システムは、隣接するエンティテ
ィーの間の離間した交差領域を検出し且つ前記隣接エン
ティティーに対して共通の最終点を割り当てることによ
り前記隣接エンティティーを選択的に接続するシステム
を有する。 - 【請求項131】 請求項130によるシステムにし
て、前記離間交差領域は、前記隣接するエンティティー
の最終点が相互に所定距離の範囲内にある時前記離間交
差領域を検出するシステムにより検出される。 - 【請求項132】 請求項128によるシステムにし
て、前記複数の図は、2次元座標空間内での前記パーツ
の平面図及び正面図及び右側面図を有する。 - 【請求項133】 請求項132によるシステムにし
て、前記クリーンアップ操作システムは、前記初期パー
ツ情報に基づいて、前記パーツの前記平面図及び正面図
及び右側面図の表現を検出するシステムを有する。 - 【請求項134】 請求項128によるシステムにし
て、前記パーツは板金パーツからなる。 - 【請求項135】 請求項128によるシステムにし
て、それはさらに、前記同定された各表現においてパー
ツ厚さの表現を選択的に除去し、2次元座標空間におけ
る厚さを有しない、前記パーツについての前記各図の修
正表現を提供するパーツ厚さ除去システム;前記システ
ムは、前記パーツの同定された各々に基づいて3次元空
間における前記パーツの表現を展開するようになってい
る。 - 【請求項136】 請求項135のシステムにして、前
記パーツ厚さ消去システムは、前記複数の図のそれぞれ
において消去すべき前記パーツ厚さ情報を特定し前記複
数の図において残すべき前記パーツの寸法を特定するよ
うにユーザに対して促すシステムを有する。 - 【請求項137】 請求項128によるシステムにし
て、前記展開システムは、前記2次元空間における前記
パーツの前記同定された表現に基づいて前記3次元空間
における前記パーツの前記表現を展開するために射影操
作を行なうシステムを有する。 - 【請求項138】 請求項137によるシステムにし
て、前記射影操作は、前記複数の図のそれぞれの相対的
な深さを検出し前記複数の図のそれぞれを3次元空間に
射影する。 - 【請求項139】 請求項128によるシステムにし
て、3次元空間における前記パーツの前記表現に対して
3次元クリーンアップ操作を行ない、前記パーツの前記
表現における余分の情報を更にクリーンアップし消去す
るためのシステムを更に含む。 - 【請求項140】 請求項139によるシステムにし
て、前記3次元クリーンアップ操作は、前記3次元空間
における前記パーツの前記表現に存在する一端部が開放
された線分を同定し且つ消去する工程を含む。 - 【請求項141】 請求項139によるシステムにし
て、前記3次元クリーンアップ操作は、前記3次元空間
における前記パーツの表現に存在する各曲げ線を同定し
且つ消去する工程を含む。 - 【請求項142】 請求項139によるシステムにし
て、前記3次元クリーンアップ操作は、前記3次元空間
において前記パーツの前記表現に存在する各面を調整す
るための工程を含む。 - 【請求項143】 高知能製造設備により製造されるべ
きパーツの曲げモデルを展開するためのシステムにし
て、前記システムは以下を含む。前記パーツに関連する
初期パーツ情報を受信する受信システムにして、前記初
期パーツ情報は、2次元座標空間における前記パーツの
複数の図の各表現を備え、前記複数の表現の各々は前記
パーツの厚さの表現を含み;前記同定された各表現にお
いてパーツ厚さの表現を選択的に除去し、2次元座標空
間における厚さを有しない、前記パーツについての前記
各図の表現を提供するパーツ厚さ除去システム;前記2
次元空間における厚さを有しない、前記パーツの前記修
正表現に基づいて3次元空間における前記パーツの表現
を展開するシステム。 - 【請求項144】 請求項143のシステムにして、前
記初期パーツ情報は、非本質情報を含み、前記システム
は、前記初期パーツ情報に対して2次元クリーンアップ
操作を行い、前記非本質的情報を除去し、前記各表現を
同定するクリーンアップ操作システムを有する。 - 【請求項145】 請求項144によるシステムにし
て、前記初期パーツ情報は、少なくとも前記パーツの線
分エンティティーを表現するパーツエンティティーデー
タを備え、前記クリーンアップ操作システムは、前記エ
ンティティーの交差点を検出し且つ前記検出された交差
点において前記エンティティーを選択的に分断する分断
装飾システムを備え、前記分断装飾システムは、前記分
断エンティティーが前記検出された交差点に基づいて共
通の最終点を有するように割り当てる。 - 【請求項146】 請求項146によるシステムにし
て、前記展開システムは、前記2次元空間における前記
パーツの前記変形された表現に基づいて前記3次元空間
における前記パーツの前記表現を展開するために射影操
作を行なうシステムを有する。 - 【請求項147】 請求項146によるシステムにし
て、前記射影操作は、前記複数の図のそれぞれの相対的
な深さを検出し前記複数の図のそれぞれを3次元空間に
射影する。 - 【請求項148】 請求項143のシステムにして、前
記パーツ厚さ消去システムは、前記複数の図のそれぞれ
において消去すべき前記パーツ厚さ情報を特定し前記複
数の図において残すべき前記パーツの寸法を特定するよ
うにユーザに対して促すシステムを有する。 - 【請求項149】 請求項143によるシステムにし
て、3次元空間における前記パーツの前記表現に対して
3次元クリーンアップ操作を行ない、前記パーツの前記
表現における余分の情報を更にクリーンアップし消去す
るためのシステムを更に含む。 - 【請求項150】 請求項149によるシステムにし
て、前記3次元クリーンアップ操作は、前記3次元空間
における前記パーツの前記表現に存在する一端部が開放
された線分を同定し且つ消去する工程を含む。 - 【請求項151】 請求項149によるシステムにし
て、前記3次元クリーンアップ操作は、前記3次元空間
における前記パーツの表現に存在する各曲げ線を同定し
且つ消去する工程を含む。 - 【請求項152】 請求項149によるシステムにし
て、前記3次元クリーンアップ操作は、前記3次元空間
において前記パーツの前記表現に存在する各面を調整す
るための工程を含む。
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 |
---|---|---|---|
JP18338997A Division JP3009135B2 (ja) | 1996-05-06 | 1997-05-02 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
JPH11338909A true JPH11338909A (ja) | 1999-12-10 |
JP3803502B2 JP3803502B2 (ja) | 2006-08-02 |
Family
ID=21779940
Family Applications (10)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP18338797A Expired - Fee Related JP3009134B2 (ja) | 1996-05-06 | 1997-05-02 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
JP18339097A Expired - Fee Related JP2966376B2 (ja) | 1996-05-06 | 1997-05-02 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
JP18338997A Expired - Fee Related JP3009135B2 (ja) | 1996-05-06 | 1997-05-02 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
JP18338897A Expired - Fee Related JP3265233B2 (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 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
JP27347499A Expired - Fee Related JP3884195B2 (ja) | 1996-05-06 | 1999-09-27 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法 |
JP11273475A Withdrawn JP2000090145A (ja) | 1996-05-06 | 1999-09-27 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法 |
Family Applications Before (6)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP18338797A Expired - Fee Related JP3009134B2 (ja) | 1996-05-06 | 1997-05-02 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
JP18339097A Expired - Fee Related JP2966376B2 (ja) | 1996-05-06 | 1997-05-02 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
JP18338997A Expired - Fee Related JP3009135B2 (ja) | 1996-05-06 | 1997-05-02 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
JP18338897A Expired - Fee Related JP3265233B2 (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 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法 |
Family Applications After (3)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP11102564A Pending JPH11345260A (ja) | 1996-05-06 | 1999-04-09 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 |
JP27347499A Expired - Fee Related JP3884195B2 (ja) | 1996-05-06 | 1999-09-27 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法 |
JP11273475A Withdrawn JP2000090145A (ja) | 1996-05-06 | 1999-09-27 | 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法 |
Country Status (1)
Country | Link |
---|---|
JP (10) | JP3009134B2 (ja) |
Families Citing this family (18)
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 | 中民筑友智能装备科技有限公司 | 预制构件生产线自动投影方法、装置、设备、系统及介质 |
US20220067223A1 (en) * | 2020-09-02 | 2022-03-03 | The Boeing Company | Optimization of Cross-Sectional Profile Shapes for Manufacture of Structural Parts |
WO2024135796A1 (ja) * | 2022-12-23 | 2024-06-27 | リンクウィズ株式会社 | 機械制御システム、情報処理システム、プログラム及び製造方法 |
WO2024209822A1 (ja) * | 2023-04-07 | 2024-10-10 | 村田機械株式会社 | 情報処理装置、プレス機械システム及びデータ生成方法 |
CN118279538B (zh) * | 2024-06-04 | 2024-08-20 | 广州科莱瑞迪医疗器材股份有限公司 | 一种针对体表模型的弯曲方法和系统 |
-
1997
- 1997-05-02 JP JP18338797A patent/JP3009134B2/ja not_active Expired - Fee Related
- 1997-05-02 JP JP18339097A patent/JP2966376B2/ja not_active Expired - Fee Related
- 1997-05-02 JP JP18338997A patent/JP3009135B2/ja not_active Expired - Fee Related
- 1997-05-02 JP JP18338897A patent/JP3265233B2/ja not_active Expired - Fee Related
-
1999
- 1999-04-05 JP JP14216799A patent/JP3803509B2/ja not_active Expired - Fee Related
- 1999-04-05 JP JP11142166A patent/JP2000003384A/ja active Pending
- 1999-04-08 JP JP10135799A patent/JP3803502B2/ja not_active Expired - Fee Related
- 1999-04-09 JP JP11102564A patent/JPH11345260A/ja active Pending
- 1999-09-27 JP JP27347499A patent/JP3884195B2/ja not_active Expired - Fee Related
- 1999-09-27 JP JP11273475A patent/JP2000090145A/ja not_active Withdrawn
Also Published As
Publication number | Publication date |
---|---|
JP2000090144A (ja) | 2000-03-31 |
JP3009134B2 (ja) | 2000-02-14 |
JP3009135B2 (ja) | 2000-02-14 |
JPH10187794A (ja) | 1998-07-21 |
JP2000003385A (ja) | 2000-01-07 |
JP3803509B2 (ja) | 2006-08-02 |
JP3803502B2 (ja) | 2006-08-02 |
JP2966376B2 (ja) | 1999-10-25 |
JPH10187795A (ja) | 1998-07-21 |
JP3265233B2 (ja) | 2002-03-11 |
JPH11345260A (ja) | 1999-12-14 |
JP3884195B2 (ja) | 2007-02-21 |
JPH10187796A (ja) | 1998-07-21 |
JP2000090145A (ja) | 2000-03-31 |
JPH10187793A (ja) | 1998-07-21 |
JP2000003384A (ja) | 2000-01-07 |
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 | |
US6185476B1 (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 | |
JPH11338909A (ja) | 薄板金属製作設備全体にわたって設計製作情報を分配する装置と方法 | |
Grimstead et al. | Creating solid models from single 2D sketches | |
WO1997042608A9 (en) | Apparatus and method for generating a sheet-metal bend model | |
JP3308869B2 (ja) | 部品表示画像操作システムおよび方法 | |
Kalay | Worldview: An integrated geometric-modeling/drafting system | |
EP1830323A2 (en) | Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility | |
Mukerjee | Modeling visual objects based on accidental alignment |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
A621 | Written request for application examination |
Free format text: JAPANESE INTERMEDIATE CODE: A621 Effective date: 20040430 |
|
A521 | Written amendment |
Free format text: JAPANESE INTERMEDIATE CODE: A523 Effective date: 20051013 |
|
A131 | Notification of reasons for refusal |
Free format text: JAPANESE INTERMEDIATE CODE: A131 Effective date: 20060117 |
|
A521 | Written amendment |
Free format text: JAPANESE INTERMEDIATE CODE: A523 Effective date: 20060317 |
|
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: 20060425 |
|
A61 | First payment of annual fees (during grant procedure) |
Free format text: JAPANESE INTERMEDIATE CODE: A61 Effective date: 20060508 |
|
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: 20100512 Year of fee payment: 4 |
|
FPAY | Renewal fee payment (event date is renewal date of database) |
Free format text: PAYMENT UNTIL: 20100512 Year of fee payment: 4 |
|
FPAY | Renewal fee payment (event date is renewal date of database) |
Free format text: PAYMENT UNTIL: 20110512 Year of fee payment: 5 |
|
FPAY | Renewal fee payment (event date is renewal date of database) |
Free format text: PAYMENT UNTIL: 20120512 Year of fee payment: 6 |
|
FPAY | Renewal fee payment (event date is renewal date of database) |
Free format text: PAYMENT UNTIL: 20130512 Year of fee payment: 7 |
|
FPAY | Renewal fee payment (event date is renewal date of database) |
Free format text: PAYMENT UNTIL: 20140512 Year of fee payment: 8 |
|
LAPS | Cancellation because of no payment of annual fees |