JP3308869B2 - 部品表示画像操作システムおよび方法 - Google Patents

部品表示画像操作システムおよび方法

Info

Publication number
JP3308869B2
JP3308869B2 JP21933297A JP21933297A JP3308869B2 JP 3308869 B2 JP3308869 B2 JP 3308869B2 JP 21933297 A JP21933297 A JP 21933297A JP 21933297 A JP21933297 A JP 21933297A JP 3308869 B2 JP3308869 B2 JP 3308869B2
Authority
JP
Japan
Prior art keywords
bending
information
data
dimensional
bend
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.)
Expired - Fee Related
Application number
JP21933297A
Other languages
English (en)
Other versions
JPH10149206A (ja
Inventor
ハザマ ケンスケ
ハワン ヤーンーツォ
サカイ サトシ
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Amada Co Ltd
Original Assignee
Amada Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Priority claimed from US08/690,671 external-priority patent/US5886897A/en
Priority claimed from US08/688,860 external-priority patent/US5828575A/en
Priority claimed from US08/690,084 external-priority patent/US5864482A/en
Priority claimed from US08/700,671 external-priority patent/US5971589A/en
Application filed by Amada Co Ltd filed Critical Amada Co Ltd
Publication of JPH10149206A publication Critical patent/JPH10149206A/ja
Application granted granted Critical
Publication of JP3308869B2 publication Critical patent/JP3308869B2/ja
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

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

Landscapes

  • General Factory Administration (AREA)
  • Control By Computers (AREA)
  • Bending Of Plates, Rods, And Pipes (AREA)
  • Processing Or Creating Images (AREA)
  • Management, Administration, Business Operations System, And Electronic Commerce (AREA)
  • Multi-Process Working Machines And Systems (AREA)

Description

【発明の詳細な説明】
【0001】関連出願データ 本出願は1996年5月6日出願の「薄板金属製作設備全体に
亘って設計製作情報を管理し分配する装置と方法」と題
したU.S.仮出願No. 60/016,948に準拠し、その明細書を
全般的に参照する事によって本明細書に明白にとりいれ
ていることを主張する。
【0002】著作権についての注意書き 本特許文書の明細書の一部は、著作権保護の対象になっ
ている。著作権保有者はU.S.特許・商標局の特許フアイ
ルや記録に記載されている特許明細書の何人かによる複
写には異議を申し立てないが、それ以外のものについて
は著作権保有者は著作権すべてを保留する。
【0003】発明の背景 発明の分野 本発明は一般的に、製造分野及び薄板金属部品のような
部品の製作に関するものである。特に、本発明は曲げ薄
板金属部品の製作を容易にするために設計・製作情報を
工場全体にわたって管理・分配する装置と方法に関する
ものである。
【0004】背景情報 伝統的に、たとえば薄板金属の進歩的な製造設備での曲
げ薄板金属の製作は、連続的な製作製造段階を含む。第
一段階は設計段階で、そこでは顧客の仕様にもとづいて
薄板金属部品の設計が行われる。通例顧客は特定の薄板
金属部品の設備での製作を注文する。顧客の注文は通
例、部品を工場で製造するのに必要な製品と設計の情報
を含んでいる。この情報は、たとえば部品の幾何学的寸
法、部品に必要な材料(たとえば鋼鉄、ステインレス
鋼、またはアルミニウム)、特殊な成形の情報、分量、
引き渡し年月日等を含むことがある。客先から要請され
た薄板金属部品は広範囲の種類の応用に設計・製作する
ことが出来る。たとえば、製作された部品は最終的には
コンピュータのケース、配電盤、航空機の肘掛け、また
は自動車のドアのパネルに使われるかもしれない。設計
段階では、薄板金属部品の設計は、適当なコンピュータ
支援設計(CAD)システムによって製造設備の設計部で
なされる。顧客の仕様に応じて、プログラマーがCADシ
ステムを用いて薄板金属部品の2次元(2-D)モデルを作
成することもできる。通例、客先は部品の重要な幾何学
的寸法を含む青写真を提供する。この青写真は、部品に
含まれる特別の成形や記号、または薄板金属部品の表面
の孔や他の開口を示すこともある。設計プログラマーは
CADシステムで2-Dモデルを作成するため、この青写真を
度々用いる。この2-Dモデルはまた、薄板金属部品の曲
げ線及び/または寸法情報を含む平面図と、一つまたは
一つ以上の透視図を含むこともある。
【0005】実際に薄板金属部品の曲げ加工を開始する
前に、先ず原材料から部品を打ち抜き切断するか/また
は切断しなければならない。在庫材料の処理に当たっ
て、打ち抜きプレスやプラズマまたはレーザー切断機を
制御作動するのに、普通コンピュータ数値制御(CNC)
または数値制御(NC)が用いられる。この在庫材料の処
理を容易にするため、設計プログラマーは、コンピュー
タ支援製造(CAM)システムまたはCAD/CAMシステムを用
いて2-Dモデルにもとづいた制御コードを作成すること
が出来る。この制御コードには、打ち抜きプレス及び/
または切断機にとりいれて、在庫材料からの薄板金属部
品の打ち抜き、または切断に利用できる部品プログラム
が含められていることもある。
【0006】製造プロセスの次の段階は曲げ加工計画段
階である.この段階で、曲げ加工計画が作業場で曲げ加
工オペレータによって立てられる。オペレータには通常
切断または打ち抜かれた一つまたは一つ以上の在庫材料
とともに、部品の青写真または2-D図面が渡される。こ
れらの材料で曲げ加工オペレータは使用する工具と実施
される曲げの手順を定める曲げ加工計画を立てる。曲げ
作業場には、オペレータがデータを入力した曲げコー
ド、または曲げ計画にもとづいたプログラムが作成でき
るCNCプレスブレーキのようなCNC金属曲げ機も含まれ
る。
【0007】曲げ加工計画が作成されると、オペレータ
は曲げ加工の順序の初期テストのための作業場を設置す
る。このテスト段階では、打ち抜きまたは切断された材
料はプレスブレーキに手で組み込まれ、プレスブレーキ
はプログラムされた順序に従って製作品に曲げを加工す
るように操作される。オペレータは出来上がった曲げ薄
板金属部品を分析して顧客の仕様に適合しているかどう
かを検査する。このプレスブレーキの初期作業の結果に
よって、オペレータは曲げプログラムを編集し、曲げ順
序を修正することもある。オペレータはまた、薄板金属
部品の設計が適当に修正出来るように、設計部に結果を
フイードバックすることもある。テストは通常曲げ薄板
金属部品が要求されている設計仕様内におさまるまで続
けて行われる。
【0008】製作プロセスの最後の段階の一つは曲げ段
階である。曲げ計画が作成され、テストされた後、曲げ
オペレータは曲げ加工場に必要な工具を装備し、曲げ計
画と記憶されている曲げプログラムまたはコードに従っ
てプレスブレーキを作動する。曲げ加工場に必要な量の
打ち抜きまたは切断された材料が確保されるように、ま
た他の作業が指定された引き渡し年月日までに完了して
いるように、作業日程も作成される。作業日程は製作過
程の初期段階と/または全過程に平行して作業場監督に
よって作成または修正されることもある。最後の曲げ薄
板金属部品の製作が完了すると、顧客への引き渡しのた
めに部品は集められ、梱包される。
【0009】通常の製作、製造過程は幾つかの欠点や不
利な点がある。たとえば、各々顧客の設計製造データは
通常物理的に(たとえば紙によってフアイルキャビネッ
トに)、電子的に(たとえばデイスクまたは磁気テープ
に)保管されるが、こうしたデータは普通別々に保管さ
れていて検索するのが容易でない。さらに、多くの工場
環境では、重要な仕事情報の分配は工場全体にわたって
配布される仕事または企画用紙の形をとる。その結果、
データがしばしば紛失または損傷し、以前または類似の
仕事に関する設計製造データを検索するのが困難にな
る。加うるに、データの保管方法の不備によって、設計
製造情報を全工場の作業場やその他の場所に配布するの
に貴重な時間が失われる。また部品の設計や曲げ計画の
作成は、主として設計プログラマーと曲げオペレータに
よって行われ、個人の知識、手腕と経験によるところが
大きいので、薄板金属部品と曲げ計画の作成の間に製造
時間がかなり失われる。
【0010】近年、慣習的な薄板金属製造過程を改善
し、過程全体にわたる効率を改善するための開発と試み
がなされてきた。たとえば、市販のCAD/CAMシステムに
おける2次元(2-D)および3次元(3-D)モデル作成の使
用と開発によって曲げ薄板金属の製作過程とモデル作成
を促進され、改善された。今では設計プログラマーやオ
ペレーターは2-D及び3-D表示を用いて、部品の形状をよ
りよく理解し、部品設計と曲げコードの順序をより効率
的‘に作成出来るようになっている。データを電子的に
記憶し、トランスフアーする機能は、設計部から作業場
への情報の流れを改善した。コンピュータとデータ通信
ネットワークの進歩により、最早古い紙テープや磁気デ
イスクをキャビネットまたはフアイルから探し出すこと
が不要になった。
【0011】こうした進歩があるにもかかわらず、組織
と工場環境全体にわたる設計と製造情報の組織化と流れ
を改善する必要がまだある。たとえば、在来の製造シス
テムでは、各顧客の注文の重要な設計及び製造情報が、
工場のどの場所でも容易にアクセスでき、検索できるよ
うな論理的関係づけがなされていない。今までのシステ
ムはまた、薄板金属部品の特徴や特質のような、色々な
特色にもとづいた仕事情報を探索する機能をもたない。
たとえば同一または類似の部品の探索にもとづいた、以
前の仕事情報が探索でき、検索出来ることは、全体的な
製作プロセスを大幅に増強し、将来の仕事の必要製造時
間を短縮する。
【0012】過去の試みはまた、設計プログラマーや作
業場オペレータによる薄板金属部品の設計を容易にする
ことに欠けている。2-Dや3-Dモデリング・システムによ
って、設計者は部品の形状や幾何学をよりよく理解出来
るようになったが、このシステムによって設計プログラ
マーや作業場オペレータに科せられた負担は軽減されて
いない。たとえば、これらのシステムによって設計プロ
グラマーが現存の2-D CADモデルを簡単に3-D表示に変
換することはできない。また作業場オペレータに曲げ加
工計画を立てる助けとなる部品の2-D及び/また3-D図面
が提供されても、オペレータは必要な工具や曲げ手順を
手で/または試行によって決めなければならない。
【0013】発明の要約 上記に照らして、本発明は、発明の一つまたは一つ以上
の見地、実施例及び/または特色あるいはサブコンポー
ネントを通して、以下に特記する一つまたは一つ以上の
目的と利点をもたらすために供するものである。
【0014】本発明の一般的な目的は、曲げ薄板金属部
品のような部品の製作を促進するために、設計と製造情
報を全工場に亘って管理し、分配する装置と方法の提供
である。
【0015】さらに本発明の目的としては、たとえば進
歩的な薄板金属製作設備における重要な仕事情報の紛失
または破壊を防止し、専門的知識の蓄積の有効活用と整
理を助長する装置と方法の提供がある。
【0016】もう一つの本発明の目的は、各顧客の注文
の設計と製造情報の双方を、論理的に記憶する装置と方
法を備えることによって、工場のどの場所でも容易にア
クセスでき、検索できるようにすることにある。
【0017】さらにもう一つの本発明の目的は、仕事デ
ータが中央のデータベースまたはフアイルサーバーに、
全工場のどの場所でも容易に探索し、検索できるよう論
理的に記憶されている設計と製造情報を管理し、分配す
る装置と方法の提供にある。仕事データは仕事に関連し
た設計と製造情報ばかりでなく、必要な曲げ操作を遂行
するための実際の曲げコードも提供できる。
【0018】またさらに本発明の目的は、色々な探索基
準にもとづいた、設計と製造情報を含む以前の仕事情報
を探索する装置と方法の提供である。探索基準は、たと
えばこれから製造される薄板金属部品の特色や特徴を含
むことができ、これによって同一または類似の部品に関
連した以前の仕事情報を、将来の仕事の全体的な製造時
間の短縮に利用できる。
【0019】本発明のもう一つの目的は、各顧客の注文
に関連した従来の書類仕事または企画用紙を、工場の何
処からでも瞬間的にアクセスできる電子的ジョッブシー
トに置き換えることである。電子的なジョッブシートは
どの場所でも表示でき、部品の2-D及び/または3-Dモデ
ル像、工具の選択、最適曲げ手順、必要なステイジング
情報やバーコードまたは認識番号を含む、仕事に関連し
た重要な設計と製造情報を含む。この電子的ジョッブシ
ートには、曲げオペレータによって将来再び同じ、また
は類似の仕事を行うときに役立つと思われる、特別の指
図または手順を録音録画したオーデイオ及び/またはビ
デオ部も備えられる。
【0020】本発明のもう一つの目的は薄板金属部品の
2-Dと3-Dコンピュータ画像を提供することによって部品
図面の解析に要する時間を短縮する事にある。ソリッド
3-D画像モード、3-Dワイヤフレーム画像モード、2-D平
面画像モード及び正射画像モードを含む、色々な画像が
提供できる。薄板金属部品の解析に役立つズーミング、
パンニング、回転及び自動寸法入れを含む色々な異なる
画像機能も備えられる。
【0021】さらに本発明は設計者の薄板金属部品の設
計と曲げ計画の製作を容易にする装置と方法を提供する
目的を持つ。たとえば、現存する部品の2-Dモデルから
部品の3-D表示を容易に製作することができるようにす
るのも本発明の目的である。さらにもう一つの本発明の
目的として、曲げ計画とプログラムされた曲げコードを
作成する時間を短縮するためのグラフィックスインター
フエイスの提供がある。
【0022】本発明は従って、部品を製作する情報処理
機能をもつ設備と、かかる設備において部品を製作する
方法に向けられたものである。以前この設備で製作され
た部品に関する仕事情報を記憶するデータベースが備え
られている。各以前に製作された部品の以前の仕事情報
には、各以前に製作された部品の特色に関連した以前の
設計データも含められる。さらに現在の仕事要請に応え
て設備によって製作される現在の部品に関する現在の情
報を受けるシステムを備えることもできる。この現在の
仕事情報には現在の部品の提案された特色に関する提案
された設計データも含められる。
【0023】情報処理機能をもつ設備はまたデータベー
スを探索することにより、記憶されている各以前に製作
された部品の以前の仕事情報設計データと現在の仕事情
報設計データを比較するシステムも含められる。上記の
探索比較は、以前の仕事情報設計データと現在の仕事情
報設計データが、現在の仕事要請に応じて以前の仕事情
報の少なくとも一部を利用する現在部品の製作計画を作
成出来る程度の、事前に定義された類似性をもつことを
決めるために遂行できる。
【0024】発明の一面として、各以前に製作された部
品と現在の部品は薄板金属部品を含み、新部品の提案設
計データは部品の形態データも含む。加えて発明の探索
システムは、以前の仕事情報の設計の特色と現在の仕事
情報の設計の特色の比較によって、以前の製作部品が現
在の部品と同一、類似また異質の特色もつかどうかを決
めることもできる。
【0025】情報処理機能をもつ設備はまた、データベ
ースから予め定められた類似性を有することが決定した
以前の仕事情報を検索するシステムと、検索された以前
の仕事情報にもとづいて現在の部品の製作計画が立てら
れるよう、検索された以前の仕事情報を全設備の色々な
場所に分配するシステムも含められる。検索された以前
の仕事情報は、以前に製作された部品の少なくとも一つ
を製作する曲げ手順と工具情報を含みうる。分配システ
ムはデータベースと全設備にわたって配置されたステー
ション・モジュールに連結された通信ネットワークを含
みうる。各ステイションモジュールはデータベースから
検索された以前の仕事情報を受けるため、通信ネットワ
ークに連結されている。各ステーション・モジュールに
は通信ネットワークと検索された以前の仕事情報を表示
する表示装置と通信ネットワークとインターフエイスす
るためのインターフエイスネットワークも含みうる。
【0026】発明のもう一つの面に沿って、情報処理機
能をもつ設備はさらに、通信ネットワークに連結されて
いるサーバーモジュールをもちうる。このサーバーモジ
ュールは現在の仕事情報を入力する入力デバイスと、入
力デバイスによって入力された現在の仕事情報を通信ネ
ットワークを通してデータベースに移すネットワークイ
ンターフエイスデバイスをもちうる。さらに、設備の場
所は、ステーション・モジュールをもつ曲げステーショ
ンと曲げコードにもとづいて、薄板金属部品を曲げ加工
する曲げ機も含む。また、検索された以前の仕事情報
は、さらに曲げ機で以前に製作された部品の少なくとも
一つを製作するための、予め設定された曲げコードも含
まれる。
【0027】以前製作された部品と設備で製作されよう
とする部品が薄板金属部品を含む場合、検索された以前
の仕事情報には製作されようとする現在の部品に類似
の、少なくとも一つの以前に製作された部品を表示でき
る曲げモデルのデータを含みうる。各ステーションモジ
ュールの表示装置は曲げモデルデータにもとづく各以前
に製作された画像を表示することによって、現在部品の
製作計画の立案を容易にする。特に、曲げモデルデータ
は以前の製作部品の2-D画像、3-D画像を含む以前の製作
部品の画像を多数表示するデータを含みうる。各ステイ
ションモジュールの表示装置は、曲げモデルにもとづい
た以前の製作部品の2-Dまたは3-D画像を選択的に表示で
きる。
【0028】以前の仕事情報は以前の製作部品に関する
製造情報も含み、また現在の仕事情報は製作される部品
の製造情報も含む。さらに探索システムは、以前の仕事
情報と現在の仕事情報が所定程度の類似性をもつかどう
かの決定に当たって、データベースの探索で仕事情報の
比較を加えるように改造することができる。仕事情報
は、少なくとも一つのタイプの機械のデータ、工具のデ
ータ、バックゲイジング調節法のデータを含む機械の段
取りデータも含む。
【0029】情報機能をもつ部品設備における部品製作
の方法として、データ記憶装置に設備で以前製作された
部品の製作に関する情報を記憶させることを含む方法が
ある。各以前に製作された部品の以前の仕事情報には、
各以前に製作された部品の特性に関する設計データも含
まれる。さらに、この方法は現在の仕事要請に応じて現
在部品に関する現在の仕事情報を受けることも含む。現
在の仕事情報には現在部品の提案された特性に関する設
計データも含みうる。
【0030】この発明の別の見地に沿って、この方法は
各以前の製作部品について記憶された以前の仕事情報設
計データを現在の仕事情報設計データと比較するための
データ記憶装置の探索を含むこともある。この方法は以
前の仕事情報設計データと現在の仕事情報設計データが
少なくとも所定程度の類似性をもち、現在の仕事の要請
に応じて、以前の仕事情報の少なくとも一部を利用する
現在部品の製作計画が立てうることを決める段階を含み
うる。
【0031】この方法はさらに製作される現在部品と所
定程度の類似性をもつことが決定した以前の仕事情報を
データベースから検索する段階を含む、他の段階を含み
うる。これに加えて全設備にわたる色々な場所に検索さ
れた以前の仕事情報を分配することによって、検索され
た以前の仕事情報にもとづいた、現在部品の製作計画を
立てうるようにする分配段階ももちうる。この分配段階
では、検索された以前の仕事情報は、データベースと全
設備に亘って配置されているステーションモジュールに
接続している通信ネットワークを通じて分配できる。各
ステーション・モジュールはデータベースから検索され
た以前の仕事情報を受信するため、通信ネットワークに
接続することができる。
【0032】この発明のもう一つの側面として、情報処
理機能をもつ製作システムと類似部品の探索を行う方法
が設けてある。情報処理機能をもつ製作システムは以前
の製作部品の以前の仕事情報を記憶するるデータ記憶装
置を含む。以前の仕事情報は以前の各製作部品の特色に
関連した以前の設計データも含む。システムはまた新部
品製作の現在の仕事要請に関連した現在の仕事情報を受
信する手段をもち、この現在の仕事情報は、現在仕事要
請されたの新部品に提案された特色に関連して提案され
た設計データも含む。
【0033】本発明に従って、システムはさらにデータ
記憶装置を探索し、以前の仕事情報を現在の仕事情報と
比較して、現在の仕事要請の新部品と事前に定めた程度
の類似性をもつ以前の製作部品を特定する手段をもつ。
データ記憶装置から、予め定められた類似性をもつこと
が確定した以前の仕事情報を検索する手段も備えられ
る。さらに検索された以前の仕事情報を色々な場所に分
配し、それによって現在の仕事要請の新部品を製作する
計画を、検索された以前の仕事情報の少なくとも一部に
もとづいて立案する手段も備えられる。
【0034】情報処理機能をもつ設備はまた、データ記
憶装置と多数のステーションモジュールを連結する通信
ネットワークを含むことができる。各ステーションモジ
ュールはデータ記憶装置から検索された以前の仕事情報
の受信するため、通信ネットワークに連結されている。
各ステーションモジュールはまた、検索された以前の仕
事情報を表示する表示装置と通信ネットワークをインタ
ーフエイスするためのネットワークインターフエイスデ
バイスをもちうる。また通信ネットワークに連結された
サーバーモジュールも備えうる。このサーバーモジュー
ルは現在の仕事情報を入力する入力デバイスと、入力デ
バイスによって入力された現在の仕事情報を通信ネット
ワークを通してデータ記憶装置にトランスフアーするた
めの、ネットワーク・インターフエイス・デバイスをも
ちうる。
【0035】本発明はまた、類似部品を探索する方法に
も向けられている。この方法は、データ記憶装置に以前
の製作部品の以前の仕事情報を記憶させる段階と、新部
品製作の現在の仕事要請に関する現在の仕事情報を受け
る段階を含む。この方法はまた、データ記憶装置を探索
し、以前の仕事情報と現在の仕事情報を比較することに
よって、現在の仕事要請の新部品と事前に定めた類似性
をもつ以前の製作部品を特定する段階も含みうる。
【0036】この発明の見地に沿って、類似部品の探索
を行う方法にさらに、以前の仕事情報と現在の仕事情報
より特徴を抽出するオペレーションを行うことによっ
て、各以前の製作部品と現在の仕事要請の新部品に事前
に定めた特徴が存在するかどうかを決める操作を含めう
る。特徴を抽出する操作によって、各以前の製作部品と
現在の仕事要請の新部品の特徴抽出データが作成され
る。この特徴抽出データを特徴抽出ライブラリに記憶さ
れている予め決められた特徴抽出データと比較すること
によって、各以前の製作部品と現在の仕事要請部品の基
本的な特徴を同定する段階も設けられる。
【0037】この方法はさらに特徴関係オペレーション
を行うことにより、各以前の製作部品と現在の仕事要請
部品で同定された基本特徴間の関係の決定段階をもちう
る。部品の基本特徴間の関係は、基本特徴間の隔たりで
決めることができる。たとえば部品の二つの基本特徴間
の隔たりは、二つの基本特徴における基準面間の曲げ線
の数にもとづいて定めることができる。
【0038】類似部品探索の一部として、この方法は、
同定された基本特徴と、各部品の基本特徴間の定められ
た関係にもとづいた、各以前の製作部品の探索キーと現
在の仕事要請部品の探索キーの作成を含む。さらに探索
段階は、現在の仕事要請の新部品のために作成された探
索キーと各以前の製作部品のために作成された探索キー
の比較のために、データ記憶装置の連動探索を行うこと
も含まれる。連動探索を行う段階は、現在の仕事要請新
部品の探索キーと同一の探索キーをもつ以前の製作部品
の同定と、現在の仕事要請新部品の探索キーと類似の探
索キーをもつ以前の製作部品を同定することも含む。
【0039】選択部品探索を行うこともでき、それによ
って連動探索によって同定された以前の製作部品のう
ち、現在の仕事要請の新部品の探索キーと同一または最
も類似している、事前に定めた数の探索キーをもつ以前
の製作部品を選択できる。特徴の類似性の程度にもとづ
いた選択部品探索によって選択された、以前の各製作部
品をランク付けする類似性指数を計算することもでき
る。類似性指数は表示でき、それによって選択部品探索
で選択された以前の製作部品に関する以前の仕事情報
を、現在の仕事要請新部品を製作する計画を立てるた
め、データ記憶装置から選択的にアクセスできる。
【0040】この発明のさらに別の面に沿って、部品製
作のための情報機能をもつ設備と、かかる設備における
使用法が提供されている。設備は設備で以前に製作され
た部品に関する多数の事前に定めた特徴を表すデータを
記憶する記憶装置をもつ。データ受信システムも備えら
れ、それによって設備で製作される部品に関する多数の
事前に定めた特徴を表すデータが受信できる。設備はさ
らに比較システムを含み、それによって少なくとも一つ
の以前に製作された部品に関する記憶データを製作され
る部品に関する受信データと比較し、比較の結果を用い
て少なくとも一つの以前の製作部品と製作される部品が
同一、類似または異質かを決定する。
【0041】本発明の情報機能をもつ設備では、データ
記憶装置から、製作される部品と同一または類似である
と決定した以前の製作部品に関するデータを検索するシ
ステムが設備されている。設備はさらに、検索されたデ
ータを全設備の色々な場所に分配するシステムを含み、
それによって検索されたデータにもとづいて、製作され
る部品の製作計画が立てられるようになっている。
【0042】この発明の分配システムは、データ記憶装
置と全設備に亘って設けられているステーションモジュ
ールに連結されている通信ネットワークよりなってい
る。各ステーションモジュールはデータ記憶装置から検
索されたデータを受信するために通信ネットワークに連
結されている。少なくとも一つの以前の製作部品が製作
される部品と同一であることが決まると、同一の以前の
製作部品に関連したデータは検索システムによって検索
され、分配システムによって分配することによって、デ
ータが製作される部品の製作に利用できるようになって
いる。
【0043】情報機能をもつ設備はさらに以前の製作部
品に関するデータを編集するシステムを有し、少なくと
も一つの以前の製作部品が製作される部品と類似である
ことが決定したところで、類似の以前の製作部品に関す
るデータが検索され、編集システムによって編集され、
編集されたデータが製作される部品の製作に用いられ
る。さらに受信されたデータにもとづいて製作する部品
の製作計画の立案システムを設けることができ、以前の
製作部品すべてが製作される部品と異なることが決定し
たとき、この立案システムによって受信データを用いて
製作される部品の製作計画を立てられる。
【0044】情報機能をもつ部品製作設備で用いられる
方式では、方式はデータ記憶装置に設備で以前に製作さ
れた部品に関する多数の事前に定めた特徴に関するデー
タを記憶させる段階を含む。 方式はまた設備で製作さ
れる部品に関する多数の事前に定めた特徴を表すデータ
を受信し、記憶されている少なくとも一つの以前の製作
部品に関する記憶データと製作される部品に関する受信
データを比較する段階も含まれている。 この比較段階
の結果にもとづいて、この方式で以前の製作部品が製作
される部品が同一か、類似か、または異質かを決めるこ
とができる。
【0045】この方式はさらにデータ記憶装置から、製
作される部品と同一または類似であることが決定した以
前の製作部品に関するデータをの検索を含む。設備はま
た、検索されたデータを全設備の色々な場所に分配する
こシステムをもち、これによって検索されたデータにも
とづいて製作される部品の製作計画を立てるシステムを
含む。少なくとも以前の製作部品の一つが製作される部
品と同一であることが決定されると、同一の以前の製作
部品に関するデータは検索され、製作される部品の製作
にデータが利用できるよう、分配システムによって分配
される。
【0046】この方式はさらに以前の製作部品に関する
データを編集する段階を含み、少なくとも一つの以前の
製作部品が製作される部品と類似であることが決定され
ると、類似の以前の製作部品に関するがデータが検索さ
れ、編集データが製作される部品の製作に利用できるよ
う、編集システムによって編集される。さらに、受信デ
ータにもとづいて製作される部品の製作計画を立てる段
階も用意でき、以前の製作部品すべてが製作される部品
と異質であることが決定したとき、この段階で受信デー
タは製作される部品の製作計画を立てるのに用いられ
る。
【0047】更に、この発明は、高知能製造設備におい
て製造されるべき部品の曲げモデルを生成するための装
置及び方法に向けられ、前記パーツは複数の面と少なく
とも1つの曲げ線を有する。前記装置は前記パーツに関
する初期パーツ情報を受け取るための受取システムを含
み、前記パーツ情報は第1の所定の座標空間の中での前
記パーツの表現に関連するデータを含む。面検出システ
ムが更に設けられ、それは前記第1所定座標空間内にお
いて、前記初期パーツ情報に基づいて前記パーツの面を
検出する。更に装置は、検出された面に基づいて前記パ
ーツの少なくとも1つの曲げ線を特定するための曲げ線
特定システムと、前記面検出システムにより検出された
面の各々に対して所定の操作を行なうことにより、第2
の所定の座標空間内での前記パーツの表現に関連するデ
ータを含み且つ前記パーツに関連する、追加のパーツ情
報を生成するためのシステムとを含む。前記所定の操作
は、少なくとも初期パーツ情報と前記曲げ線特定システ
ムにより特定される少なくとも1つの曲げ線に基づいて
行なわれる。
【0048】前記第1の所定の座標空間は2次元座標空
間からなり前記第2の所定座標空間は3次元座標空間か
らなる。前記所定の操作は、前記面検出システムにより
検出された前記面に対してなされる折り曲げ操作からな
る。前記折り曲げ操作は、前記曲げ線特定システムによ
り特定された少なくとも1つの曲げ線に対して前記面検
出システムにより特定された複数の面のうちの各々を回
転し且つ並行移動する操作を含む。更に、前記初期パー
ツ情報は、更に前記パーツの少なくとも1つの曲げ線に
関連する曲げ角度量を含み、前記折り曲げ操作は、この
折り曲げ角度量に基づいて行なわれる。
【0049】この発明の他の側面によれば、前記第1の
所定の座標空間は3次元座標空間からなり第2の所定の
座標空間は2次元座標空間からなり、前記所定の操作
は、前記面検出システムにより検出された面に対してな
される展開操作からなる。前記展開操作は、前記曲げ線
特定システムにより特定された少なくとも1つの曲げ線
に対して前記面検出システムにより検出された複数の面
の各々を回転し且つ並行移動する操作を含む。更に前記
初期パーツ情報は更に前記パーツの少なくとも1つの曲
げ線に関連する曲げ角度量を含み、前記展開操作は、こ
の曲げ角度量に基づいて行なわれる。
【0050】前記製造されるべきパーツは板金パーツか
らなり、前記第1の所定の座標空間内によるパーツの表
現に関連するデータは、座標データ及び/又はベクトル
データを含む。更に、前記パーツの複数の面は、前記パ
ーツの複数又は単数の基本的表面並びに前記パーツの屈
曲された表面からなる。この発明の他の側面によれば、
前記初期パーツ情報は、3次元空間におけるパーツの表
現に関連するデータを含み、前記データは、前記3次元
空間における前記パーツの厚さデータを含む。
【0051】曲げモデルを生成するための装置は更に、
前記初期パーツ情報に関連するデータに対して自動トリ
ミング及びクリーンアップ操作を行ない、前記面検出シ
ステム及び曲げ線特定システムのためのデータを作成す
る自動トリミング及びクリーンアップシステムを含む。
前記データは少なくとも前記パーツの線分エンティティ
ー及び曲げ線エンティティーを表現するパーツエンティ
ティーデータを含み、前記自動トリミング及びクリーン
アップシステムは、前記エンティティーの交差点を検出
し且つ検出された交差点において前記エンティティーを
選択的に分断するためのシステムと検出された交差点に
基づいて、結果としての分断されたエンティティーが共
通端点を有するように割り当てるシステムとを含む。前
記自動トリミング及びクリーンアップシステムは、又、
隣接するエンティティーの間の空白の(開放)交差領域
を検出し且つ、共通端点を前記隣接したエンティティー
に対して付与することにより隣接したエンティティーを
選択的に接続するためのシステムを有する。
【0052】空白交差領域は、前記隣接エンティティー
の端点が相互に所定の間隔の間に存在すると判断される
時空白交差領域を検出するための前記装置により検出さ
れる。この発明の更に他の特徴によれば、前記初期パー
ツ情報に関連するデータは、少なくとも前記パーツの線
分エンティティーを表現するパーツエンティティーデー
タを含み、前記面検出システムは、前記パーツの複数の
面を検出するために、前記パーツエンティティーデータ
に基づいて前記パーツのループ及びエンティティー分析
を行なうようにされている。前記ループ及びエンティテ
ィー分析は、最初、前記パーツの外側境界に対して行な
われ、然る後、前記パーツの内側境界及び領域に対して
行なわれる。前記面検出システムは、前記パーツの外側
領域に対して前記ループ及びエンティティー分析を行な
う際に、エンティティーの最初の結合されたリストを生
成し、前記エンティティーの最初の結合されたリストは
前記パーツの外側ループ及び境界を定義する。前記面検
出システムは更に前記パーツの内部境界及び領域に対し
て前記ループ及びエンティティー分析を行なう際に前記
エンティティーの追加の結合されたリストを生成し、前
記エンティティーの追加の結合されたリストは、前記パ
ーツの内部のループ及び境界を定義する。
【0053】更に、前記面検出システムは更に前記エン
ティティーの初期連結リストにより定義される外側ルー
プ及び前記エンティティーの追加の連結リストにより定
義される内側ループに基づいてループツリーを生成する
ためのシステムを有する。更に前記面検出システムは前
記ループツリー及び前記初期連結リストエンティティー
及び前記エンティティーの追加の連結リストにより定義
される境界のシーケンスに基づいて前記パーツの面を検
出する。
【0054】この発明の曲げ線特定システムは、前記エ
ンティティーの最初の連結リストと前記エンティティー
の追加の連結リストを解析し、前記面検出システムによ
り検出された面の間の共通の線分エンティティーを決定
するシステムを有する。
【0055】曲げ線は、前記面の1つが前記面の他の1
つとただ1つの共通線分エンティティーを有することの
検出に基づいて特定される。更に、前記曲げ線特定シス
テムは、前記共通線分エンティティーを決定するための
システムが前記面の間に1つ以上の共通線分が存在する
と検出した時、前記パーツの曲げ線を特定するための所
定のヒューリスティックを適用する。前記ヒューリステ
ィックは、前記部品に対して最小数の全曲げ線が特定さ
れるように前記パーツの曲げ線を特定する操作を含む。
前記ヒューリスティックは又、前記面の1つが前記面の
他の1つと1以上の共通線分エンティティーを有する時
最も長い長さを有する共通線分エンティティーに基づい
て前記部品の曲げ線を特定することを含む。
【0056】この発明の他の特徴によれば、縮小量を受
け取るためのシステムが設けられ、前記部品に関連する
縮小量を受け取る。前記面に対して所定の操作を行なう
際に前記縮小量に基づいて曲げ縮小についての補正を行
なうための装置も設けてある。曲げ縮小についての補正
を行なうための装置は、折り曲げ操作を行なう際に前記
パーツの前記曲げ線の両側において前記縮小量の半分だ
け前記面の寸法長さを増大する。前記曲げ縮小について
の補正を行なうためのシステムは、更に、展開操作を行
なう際に、前記パーツの前記曲げ線の両側において前記
縮小量の半分だけ前記面の寸法長さを減少せしめるよう
になっている。
【0057】前記曲げモデルを生成する方法は、以下の
工程を含む:前記パーツに関連する初期パーツ情報を受
け取る工程、前記初期パーツ情報は、第1の所定の座標
空間内で前記パーツの表現に関連するデータを含む;前
記第1所定座標空間内において前記初期パーツ情報に基
づいて前記パーツの面を検出する工程;前記検出により
検出された複数の面に基づいて前記パーツの少なくとも
1つの曲げ線を特定する工程。前記検出により検出され
た前記複数の面の各々に対して所定の操作を行なうこと
により、第2の所定の座標空間内における前記パーツの
表現に関連するデータを含む追加のパーツ情報を生成す
る工程。前記操作は、前記初期パーツ情報及び前記特定
操作により特定される少なくとも1つの曲げ線とに基づ
いて行なわれる。
【0058】前記第1の所定の座標空間は2次元座標空
間からなり、前記第2の所定の座標空間は3次元座標空
間からなる。更に、前記方法は、前記検出の工程により
検出された前記面に対して折り曲げ操作を行なう工程を
含む。前記折り曲げ操作は、前記特定するための工程に
より特定された少なくとも1つの曲げ線に対して前記面
の各々を回転し且つ並行移動する操作を含む。更に、前
記初期パーツ情報は、前記パーツの少なくとも1つの曲
げ線に関連する曲げ角度量を含み、前記折り曲げ操作
は、この曲げ角度量に基づいて行なわれる。
【0059】この発明の他の特徴によれば、前記第1の
所定の座標空間は、3次元座標空間からなり、前記第2
の所定座標空間は2次元座標空間からなる。前記方法は
更に前記検出の工程により検出された面に対して展開操
作を行なう工程を有する。この展開操作は、前記特定す
るという工程により特定された少なくとも1つの曲げ線
に対して前記複数の面の各々を回転及び並行移動する操
作を含む。更に前記初期パーツ情報は、前記パーツの少
なくとも1つの曲げ線に関連する曲げ角度量を含み、前
記展開操作は、この曲げ角度量に基づいて行なわれる。
【0060】前記操作は、更に前記面を検出し且つ前記
少なくとも1つの曲げ線を特定する前に、前記初期パー
ツ情報のデータに対して自動トリミング及びクリーンア
ップ操作を行なう工程を有する。前記初期パーツ情報の
データは、前記パーツの少なくとも線分エンティティー
を表現するパーツエンティティーデータを含み、前記面
を検出する工程は、前記パーツの面を検出するために前
記パーツエンティティーデータに基づいて前記パーツの
ループ及びエンティティー分析を行なうことを含む。前
記ループ及びエンティティー分析は、最初に前記パーツ
の外側境界に対してなされ、次に前記パーツの内側境界
及び領域に対してなされる。
【0061】更にこの発明によれば、前記特定する工程
は、更に前記面の間に1以上の共通端部が検出される時
前記部品の曲げ線を特定するために所定のヒューリステ
ィックを適応することを含む。前記ヒューリスティック
は、前記パーツに対して最小数の全曲げ数が特定される
ように前記パーツの曲げ線を特定する工程を含む。前記
ヒューリスティックは又、前記面の1つが当該面の他の
1つと1以上の共通線分エンティティーを有する時最も
長い長さを有する共通線分エンティティーに基づいて前
記部品の曲げ線を特定することを含む。
【0062】この発明は製造設備において製造されるパ
ーツの曲げモデルを生成するためのシステムを含み、そ
こにおいて前記パーツは複数の面と少なくとも1つの曲
げ線を含む。前記システムは、前記部品に関連する初期
パーツ情報を受け取る手段を含み、前記初期パーツ情報
は、第1の所定の座標空間内での前記パーツの表現に関
連するデータを含む。前記第1所定空間内で前記初期パ
ーツ情報に基づいて前記パーツの面を検出するための検
出手段もまた設けてある。システムは更に、前記面検出
手段により検出された面に基づいて前記パーツの少なく
とも1つの曲げ線を同定する手段を含む。前記システム
は又、前記検出手段により検出された面に対して所定の
操作を行なうことにより第2の所定の座標空間内での前
記パーツの表現に関連するデータを含む追加のパーツ情
報を生成する手段を含む。前記所定の操作は、前記シス
テムの曲げ線決定手段により特定される曲げ線に少なく
とも部分的には基づいて行なわれる。この発明の他の側
面によれば、高知能製造設備において製造されるべきパ
ーツのベンドモデルを生成するための装置及び方法が提
供される。このシステムは、前記部品に関連する初期パ
ーツ情報を受け取るための受取システムを備え、前記初
期パーツ情報は、2次元空間内での前記パーツの複数の
姿の各表現を含み、前記表現の各々は前記パーツのパー
ツ厚さ表現を含む。クリーンアップ操作システムが更に
設けられ前記初期パーツ情報に対して2次元クリーンア
ップ操作を行ない、任意の余分な情報を消去し且つ、前
記表現の各々を特定する。前記システムは又、前記特定
された表現の各々におけるパーツ厚さ表現を選択的に消
去し2次元座標空間内での厚さを有しない前記パーツの
姿の修正された表現を提供する。前記システムはまた2
次元座標空間内での厚さを有しない前記パーツの前記修
正された表現に基づいて3次元座標空間内での前記パー
ツの表現を生成するシステムを含む。
【0063】前記初期パーツ情報は、少なくとも前記パ
ーツの線分エンティティーを表現するパーツエンティテ
ィーデータを含み、前記クリーンアップ操作は、前記エ
ンティティーの交差点を検出し且つ、検出された交差点
において前記エンティティーを選択的に分断するための
分断・トリミングシステムを含む。更にこの分断・トリ
ミングシステムは、前記検出された交差点に基づいて、
前記結果としての分断エンティティーが共通端点を有す
るように割り付けを行なう。前記分断及びトリミングシ
ステムは、更に、隣接するエンティティーの間の空白の
交差領域を検出し且つそれらの隣接エンティティーに対
して共通の端点を付与することによりそれらの隣接エン
ティティーを選択的に接続するためのシステムを有す
る。空白交差領域は、前記隣接するエンティティーの端
点が相互に所定距離の間に存在すると判断される時、前
記空白交差領域を検出するシステムにより検出される。
【0064】この発明の他の側面によれば、前記クリー
ンアップ操作システムは、前記初期パーツ情報に基づい
て連結性グラフ構造を展開するためのシステムを備え、
前記クリーンアップ操作システムは、前記連結性グラフ
構造に基づいて余分の情報を消去する。前記消去される
余分の情報は、連結されない線分エンティティーを含
み、前記連結されない線分エンティティーは少なくとも
寸法線に関連する。
【0065】前記初期パーツ情報は、パーツエンティテ
ィーデータ及びテキストに関連する余分の情報を特定す
るためのキーワードを含む。前記クリーンアップ操作シ
ステムは、前記初期パーツ情報に含まれるキーワードに
基づいてテキストに関連する余分の情報を消去する。
【0066】この発明の更に他の特徴によれば、クリー
ンアップ操作システムは、前記初期パーツ情報に基づい
て前記パーツの平面図及び正面図及び右側面図の表現を
検出するためのシステムを有する。ここに開示されるよ
うに、前記パーツの複数の姿(図)は、2次元座標空間
における前記パーツの平面図及び正面図及び右側面図か
らなる。更に前記生成システムは、2次元座標空間にお
けるパーツの表現に基づいて3次元座標空間におけるパ
ーツの表現を生成するための射影操作を行なうシステム
を含む。前記射影操作は、前記複数の図面の各々の相対
的な深さを検出し、これらの複数の図面の各々を3次元
座標空間へ射影することを含む。
【0067】曲げモデルを生成する方法は以下の工程を
含む:前記パーツに関連する初期パーツ情報を受け取る
工程、前記初期パーツ情報は、2次元座標空間における
前記パーツの複数の図のそれぞれの表現を含み、前記表
現の各々は前記パーツのパーツ厚さ表現を含む;前記初
期パーツ情報に対して2次元クリーンアップ操作を行な
い、余分の情報を消去し且つ前記表現の各々を特定する
工程;前記特定された表現の各々においてパーツ厚さ表
現を選択的に消去し2次元座標空間における厚さを有し
ない前記パーツの図面の修正された表現を提供する工
程;前記2次元座標空間における厚さを有しないパーツ
の前記修正された表現に基づいて3次元座標空間におけ
る前記パーツの表現を生成する工程。前記初期パーツ情
報は、少なくとも前記パーツの線分エンティティーを表
現するパーツエンティティーデータを含み、前記操作の
工程は、前記エンティティーの交差点を検出し前記検出
された交差点において前記エンティティーを選択的に分
断する工程を含み、結果としての分断されたエンティテ
ィーは、検出された交差点に基づいて1つの共通の端点
を持つように割り付けられる。前記操作の工程は更に隣
接するエンティティーの間の空白の交差領域を検出し当
該隣接エンティティーに対して共通の端点を付与するこ
とにより当該隣接エンティティーを選択的に接続するこ
とを含む。空白交差領域は、隣接するエンティティーの
端点が相互に所定距離の間に存在する時検出される。
【0068】前記方法は更に、前記初期パーツ情報に基
づいて連結性グラフ構造を生成し且つこの連結性グラフ
構造に基づいて前記初期パーツ情報から余分の情報を消
去する工程を含む。前記余分の情報は、連結されない線
分エンティティーを含み、前記連結されない線分エンテ
ィティーは少なくとも寸法線に関連する。
【0069】更に前記初期パーツ情報は、前記パーツエ
ンティティーデータとテキストに関連する余分の情報と
を特定するためのキーワードを含み、前記操作の工程
は、前記キーワードに基づいてテキストに関連する余分
の情報を削除する工程を含む。
【0070】この発明の他の特徴によれば、前記パーツ
厚さを選択的に消去する工程は、前記複数の図面の各々
において消去されるべきパーツ厚さ表現を特定し且つ前
記複数の図面の各々において残されるべきパーツの寸法
を特定するようにユーザに促す操作を含む。前記パーツ
の寸法は、前記パーツの外側寸法又は内側寸法の1つを
含む。更に前記生成の工程は、前記2次元空間における
パーツの修正された表現に基づいて3次元空間における
パーツの表現を生成するための射影操作を行なうことを
含む。前記射影操作は、前記複数の図面の各々の相対的
な深さを検出し且つ前記複数の図面の各々を3次元空間
へ射影することを含む。
【0071】又、この発明は設備において製造されるべ
きパーツ(例えば板金パーツ)を表現するためにコンピ
ュータ可読媒体に格納されたオブジェクト指向ベンドモ
デルに向けられる。このオブジェクト指向ベンドモデル
は、前記パーツの特徴に関連するパーツ情報及びこのパ
ーツになされる曲げ操作に関連する曲げ情報を有する複
数のオブジェクトを含むパーツクラスを備える。前記パ
ーツ情報は、パーツの設計及び製造情報を含む。前記パ
ーツ設計情報は2次元及び3次元座標空間における前記
パーツの表現に関連する。更に、前記曲げ情報は、前記
パーツの曲げ線において曲げ操作を行なうための曲げデ
ータ及び命令を備えた一群のオブジェクトを有する。曲
げデータは、曲げ角度量及び曲げ半径量を含む。
【0072】この発明の1つの側面によれば、前記パー
ツクラスは前記曲げ操作が前記パーツになされるところ
の順番に関連する曲げシーケンス情報を備える属性を含
む。前記属性はパーツ材質タイプ及びパーツ厚さを備え
る。更に上記複数のオブジェクトは、面オブジェクトを
備え、この面オブジェクトは、前記パーツの各面の寸法
に関連する設計データ及び少なくとも1つの座標空間内
における前記パーツの各面の表現に関連する位置データ
を含む。前記複数のオブジェクトは更に、曲げ線オブジ
ェクトを含む。前記曲げ線オブジェクトは前記パーツの
各曲げ線の寸法に関連する設計データ及び少なくとも1
つの所定の座標空間内での前記パーツの各曲げ線の表現
に関連する位置データを含む。前記曲げ線オブジェクト
は更に、前記パーツになされる曲げ操作に関連する曲げ
製造データを含む。前記曲げ製造データは、前記パーツ
の各曲げ線についてのV幅データ及び曲げピッチ及び配
向データを含む。
【0073】前記曲げモデルの複数のオブジェクトはま
た穴オブジェクト及び成形オブジェクトを含む。この穴
オブジェクトは、前記パーツにおける少なくとも1つの
穴の寸法に関連する設計データ及び少なくとも1つの所
定の座標空間内での前記パーツの各穴の表現に関連する
位置データとを含む。前記成形オブジェクトは、前記パ
ーツの各々の成形部の寸法に関連する設計データ及び少
なくとも1つの座標空間内における前記パーツの各成形
部の表現に関連する位置データとを含む。トポロジーオ
ブジェクトと曲げ特性オブジェクトが更に設けてある。
前記トポロジーオブジェクトは、前記パーツの特徴に関
連するパーツトポロジーデータを含み、前記パーツの特
徴は、前記パーツの面または穴または成形部または曲げ
線の少なくとも1つを含む。更に前記曲げ特性オブジェ
クトは、前記パーツに関連する製造拘束データを含む。
この発明はまた製造設備において製造されるべき板金パ
ーツを表現するための、コンピュータ可読媒体に格納さ
れたオブジェクト指向曲げモデルに向けられる。前記オ
ブジェクト指向モデルは、複数のパーツ特性を有するパ
ーツオブジェクトと2次元座標空間及び3次元座標空間
において板金パーツを表現するための複数のオブジェク
トを含むパーツクラスを備える。前記複数のオブジェク
トは、前記板金パーツの特徴に関連する設計情報及び前
記板金パーツに少なくとも1つの曲げ操作を行なうため
の曲げ情報を含む。前記パーツの特徴は、面及び穴及び
成形部及びまたは曲げ線を含み、前記複数のオブジェク
トは、面オブジェクト及び穴オブジェクト及び成形オブ
ジェクト及びまたは曲げ線オブジェクトを備える。
【0074】前記曲げ情報は、前記板金パーツになされ
る複数の曲げ操作に関連する。前記曲げ情報は、前記板
金パーツに少なくとも1つの曲げ操作を行なうための曲
げデータ及び命令を備えた一群のオブジェクトを備え
る。前記曲げデータは、例えば、曲げ角度量及び曲げ半
径量を含む。更に前記曲げ属性は、前記曲げ操作が前記
板金パーツに対してなされる順番に関連する曲げシーケ
ンス情報を備える。前記パーツ属性はまた、パーツ材料
タイプ及びパーツ厚さを備える。
【0075】この発明の他の側面によれば、コンピュー
タ制御システムにおいて用いられるように構成されたオ
ブジェクト指向曲げモデルビューアが提供される。前記
コンピュータ制御システムは、前記パーツに関連する曲
げモデルデータを格納するデータベースと前記パーツの
画像を表示するための表示装置とを含む。前記オブジェ
クト指向曲げモデルビューアは、曲げモデルビューア観
察クラスを備え、この曲げモデルビューア観察クラス
は、観察モデル属性(ビューモデル属性)と前記ベンド
モデルビューア観察クラスの要素機能として実行される
少なくとも1つの観察機能とを含む。前記パーツの少な
くとも1つの画像が、前記曲げモデルデータ及び観察モ
デル属性とに基づいて、前記コンピュータ制御システム
の表示装置上に表示される。
【0076】種々の追加的特徴が、この発明のオブジェ
クト指向曲げモデルビューアに設けてある。例えば、前
記観察モデル属性は所定の観察モード或いは複数のモー
ドに関連する表示情報を備え、前記所定の観察モード或
いは複数の観察モードはソリッド観察モードまたはワイ
ヤフレーム観察モード、2次元平面図モード、及びまた
は斜視図モードを含む。前記曲げモデルビューア観察ク
ラスはまた、1つまたはそれ以上の観察機能に応じて前
記パーツの画像を修正するための情報を含む。前記観察
機能は、例えば、ズーミング機能または回転機能または
パンニング機能及びまたは寸法付け機能を含む。前記ズ
ーミング機能は、表示装置上で前記パーツの画像をズー
ムするための操作を含み、前記回転機能は前記パーツの
画像を回転するための操作を含む。前記パンニング機能
は、前記表示装置上で前記パーツの画像をパンニングす
る操作を含み、前記寸法機能は、前記パーツの少なくと
も1つの特徴に関連する寸法情報を追加的に表示するた
めに前記パーツの画像を修正する操作を含む。前記寸法
情報は、前記パーツの少なくとも1つの曲げ線の長さま
たは前記パーツの各曲げ線の曲げ角度及びまたは前記パ
ーツの少なくとも1つのフランジ部の長さを含む。
【0077】前記オブジェクト指向曲げモデルビューア
は、前記パーツの画像の現在表示されている姿(ビュ
ー)に基づいて前記表示装置上において観察可能な前記
パーツの特徴に関連する観察可能性情報を維持し提供す
るための観察可能性機能を有する。前記曲げモデルビュ
ーア観察クラスは、少なくとも1つの観察機能に応じて
パーツの画像を修正するための情報を含む。前記観察機
能は、観察可能性情報に基づいて前記パーツの画像を修
正しパーツの観察可能な特徴に関連する寸法情報を表現
するための操作を含む寸法機能を備える。更にオブジェ
クト指向曲げモデルビューアは、前記表示装置上のパー
ツの画像の現在表示されている姿のズーム係数に関連す
るズーム係数情報を含む。
【0078】本発明の更に他の側面によれば、パーツの
表示されている画像を操作するためのシステムが提供さ
れる。前記パーツの表示されているイメージは3次元座
標空間においてスクリーン上に表示される。このシステ
ムは以下を含む:指令信号を生成するための入力装置
(例えばジョイスティック装置或いはマウス装置)、こ
こに前記指令信号は前記パーツの表示されている画像を
修正するように構成された少なくとも1つの所定の観察
機能に関連する;表示されている画像の現在の姿を決定
するための現在姿決定システム;表示されているイメー
ジの現在の姿に基づいて前記パーツの回転軸を動力学的
に設定するための設定システム。前記観察機能に応じ
て、前記指令信号及び回転軸に基づいて前記パーツの表
示されている画像を修正するための画像修正システム。
【0079】所定の観察機能は、回転機能を備え、前記
画像修正システムは前記指令信号に基づいて前記回転軸
を中心としてパーツの表示されている画像を回転するよ
うに構成されている。更に現在姿決定システムは、パー
ツの表示されている画像の現在の姿がパーツの全体の姿
であるか或いはパーツの部分的姿であるかを決定するよ
うに構成されている。前記設定システムは、前記現在姿
決定システムが前記パーツの表示されているイメージの
現在の姿は全体の姿であると決定する時、前記パーツの
幾何学的中心を前記パーツの回転軸が通るように設定す
るように構成されている。更に前記設定システムは、前
記現在姿決定システムがパーツの表示されている現在の
姿が部分的姿であると決定する時、前記パーツの回転軸
が前記スクリーンのセンターを通るように設定するよう
に構成されている。
【0080】前記システムには他の特徴が設けてある。
例えばパーツ観察可能システムが設けてあり、それは現
在の姿に基づいてパーツの一部がスクリーンの中心に観
察可能であるか否かを決定する。その場合には、前記パ
ーツ観察可能性システムが前記パーツの前記一部が観察
可能であると決定する時前記回転軸が前記スクリーンの
中心における前記パーツの前記一部を通るように設定す
るように構成されている。更に前記設定システムは、前
記パーツ観察可能性システムが前記パーツの前記部分が
スクリーンの中心において観察可能ではないと決定する
時、前記パーツの幾何学的中心のZ座標において前記ス
クリーンの中心を前記回転軸が通るように設定するよう
に構成されている。
【0081】前記現在姿決定システムがパーツの表示さ
れている画像の現在の姿は部分的姿であると決定する
時、前記スクリーンの中心に位置し且つ前記スクリーン
のカメラ視野に最も近い前記パーツの部分を特定するた
めのシステムが設けてある。前記パーツの特定された部
分が前記パーツの開口部に対応するかどうかを決定する
ためのオブジェクト検出システムがまた設けてある。こ
のオブジェクト検出システムが、パーツの特定された部
分はパーツの開口部に関係しないと決定する時、前記計
算システムは、前記回転軸が前記パーツの前記特定され
た部分を通るように設定するように構成されている。更
に前記オブジェクト検出システムが前記パーツの特定さ
れた部分が当該パーツの開口部に関連すると決定する
時、前記回転軸が、前記パーツの幾何学的中心のZ座標
に対応する深さにおいて前記スクリーンの中心を通るよ
うに設定されるように前記設定システムは構成されてい
る。
【0082】前記入力装置はジョイスティック装置及び
またはマウス装置を備えている。前記ジョイスティック
装置は、ジョイスティック仮想空間を含み、当該装置か
らの指令信号は前記ジョイスティック仮想空間内での前
記ジョイスティック装置の移動に関連する情報を含む。
前記画像修正システムは、前記ジョイスティック仮想空
間内でのジョイスティック装置の移動をスクリーンのス
クリーン空間内での仮想の移動に写像するための写像シ
ステムを有する。従って、前記画像修正システムはジョ
イスティック移動から写像されたカーソルの移動に基づ
いて前記パーツの表示された画像を修正する。前記写像
システムは、前記ジョイスティック仮想空間の寸法に対
する前記スクリーン空間の寸法の比率に基づいて、前記
ジョイスティック装置の移動を前記スクリーン空間内で
のカーソルの移動へ写像するように構成されている。例
えば前記カーソルの移動は以下の式に基づいて前記写像
システムにより写像される。
【0083】 現在位置=従前位置+(スケール係数×V) ここに現在位置はスクリーン空間内でのカーソルの現在
の位置であり、従前位置は前記スクリーン空間内でのカ
ーソルの従前の位置であり、スケール係数はジョイステ
ィック仮想空間の寸法に対するスクリーン空間の寸法の
比率であり、Vは前記ジョイスティック仮想空間内での
ジョイスティック原点からジョイスティック現在位置へ
のジョイスティック装置の移動及び方向に関連するベク
トルである。
【0084】この発明の他の特徴によれば、前記写像シ
ステムは、前記写像システムにより必要されるスケール
係数を調整するためのスケール調整システムを備える。
このスケール調整システムは、前記スクリーン空間の寸
法の前記ジョイスティック仮想空間の寸法に対する比率
に所定の調整係数を掛け合わせ調整されたスケール係数
を提供するように構成されている。前記写像システムは
前記ジョイスティック運動を写像する際にこの調整され
たスケール係数を用いるように構成されている。非限定
的な事例として、3という調整係数が使用される。
【0085】この発明はまたパーツの表示された画像を
操作する方法を含む。ここに前記パーツの前記表示され
た画像は3次元座標空間においてスクリーン上に表示さ
れる。前記方法は以下の工程を含む:入力装置から生成
された指令信号を受け取る工程、ここに前記指令信号は
前記パーツの表示された画像を修正するように構成され
た少なくとも1つの所定の観察機能に関連する;スクリ
ーン上においてパーツの表示された画像の現在の姿を決
定する工程;前記パーツの現在の姿に基づいて前記パー
ツの回転軸を動力学的に設定する工程;前記観察機能に
応じて、前記指令信号及び回転軸に基づいて前記パーツ
の表示された画像を修正する工程。
【0086】この発明の上記した方法によれば、前記所
定の観察機能は、回転機能を備え、これにより前記パー
ツの表示された画像は指令信号に基づいて前記回転軸を
中心として回転される。更に前記設定の工程は、前記パ
ーツの表示された画像の現在の姿が全体の姿であると決
定される時、前記パーツの幾何学的中心を前記パーツの
回転軸が通るように設定する操作を含む。前記設定の工
程はまた、前記パーツの表示された画像の現在の姿が部
分的な姿であると決定される時、前記パーツの回転軸が
前記スクリーンの中心を通るように設定する操作を含
む。
【0087】この発明の他の側面によれば、パーツの画
像と共に寸法情報をスクリーン上に表示するシステム及
び方法が提供される。前記方法は以下の工程を含む:前
記パーツの表示された画像の現在の姿を決定し且つ前記
現在の姿に基づいてスクリーン上で複数の特徴のうちの
いずれが観察可能であるかを決定する工程;前記パーツ
の表示された画像と共にスクリーン上に、スクリーン上
で観察可能であると決定されたパーツの特徴の各々につ
いてのみの寸法情報を選択的に表示する工程。前記方法
は更に、前記パーツに関連する曲げモデルデータにアク
セスし、この曲げモデルデータに基づいて前記パーツの
特徴の各々についての寸法情報を表示するためのスクリ
ーン上の全ての可能な位置を決定する。更に、前記選択
的に表示する工程は所定のヒューリスティックを適用
し、前記可能な位置に基づいて前記観察可能な特徴の寸
法情報を表示する場所を決定する。前記ヒューリスティ
ックは、前記パーツの表示された画像の外側に存在する
スクリーン上の位置に前記寸法情報を表示する動作と観
察者の観察点に近い方のスクリーン上の位置に前記寸法
情報を表示する動作と及びまたはスクリーン上で寸法情
報が重なり合わないように前記寸法情報を表示する動作
を備える。
【0088】表示される前記寸法情報は、前記パーツの
各曲げ線についての曲げ長さ及び曲げ角度を備える。前
記寸法情報はまた、前記パーツの各曲げ線に関連する内
側曲げ半径及び曲げ縮小量を含む。ここに前記表示の工
程は、前記現在姿に基づいて観察可能であると決定され
る前記パーツの各曲げ線についての曲げ線長さ、曲げ角
度、曲げ半径及びまたは曲げ縮小量を表示する。前記パ
ーツの各フランジ部のフランジ長さのような他の寸法情
報も表示される。追加の情報、例えばパーツの幅及び深
さ及び高さも表示される。
【0089】選択的に表示する工程は、パーツの所定の
特徴のみの寸法情報を表示するための自動寸法付け操作
を行なうことを含む。従って観察可能であると決定され
る所定の特徴のみについて寸法情報が表示される。更に
前記選択的表示の工程は、パーツの特徴に関連するユー
ザにより選択された寸法情報を表示するためのマニュア
ル寸法付け操作を実行することを含む。従ってユーザに
選択された寸法情報の各々は観察可能であると決定され
るパーツの特徴についてのみ表示される。スクリーン上
に表示されたパーツの画像と共に寸法情報を表示するシ
ステムも提供される。このシステムはパーツの表示され
た画像の現在の姿を決定し且つ現在の姿に基づいて複数
の特徴のうちのいずれがスクリーン上で観察可能である
かを決定するためのシステムと、前記パーツの表示され
たイメージと共にスクリーン上に、スクリーン上で観察
可能であると決定されたパーツの特徴のみについて寸法
情報を選択的に表示するシステムとを含む。
【0090】パーツに関連する曲げモデルデータにアク
セスするためのアクセスシステムのみならずこの曲げモ
デルデータに基づいてパーツの複数の特徴の各々につい
ての寸法情報を表示するためのスクリーン上の全ての可
能な位置を決定するためのシステムが設けてある。前記
選択的表示システムは、所定のヒューリスティックを適
用し前記可能な位置に基づいて観察可能な特徴の寸法情
報を表示すべき場所を決定するためのシステムを含む。
表示される前記寸法情報は、前記現在姿に基づいて観察
可能であると判断される前記パーツの各曲げ線について
の曲げ線長さ、曲げ角度、曲げ半径及びまたは曲げ縮小
量を含む。他の寸法情報、例えばパーツの各フランジ部
のフランジ長さはまた表示される。追加の情報、例えば
パーツの幅及び深さ及び高さもこの発明によれば表示さ
れる。
【0091】又この発明は、図形的ユーザインタフェー
スを使用して曲げプラン(曲げ計画)を生成するために
設けられたシステム及び方法に向けられる。ここに前記
曲げプランは、設備におけるパーツの製造において使用
されるように構成されている。前記システムは表示装置
上に曲げ順入力ウィンドウを生成且つ表示する曲げ順表
示システムを含み、前記曲げ順入力ウィンドウはパーツ
の2次元平面画像を有する。工具表示システムが更に設
けられそれは表示装置上に工具立て情報を生成し且つ表
示する入力装置が設けられ、それは前記パーツの2次元
平面画像に基づいて曲げ順を入力し且つ前記表示装置上
に表示された工具立て情報(工具構成情報)に基づいて
工具立て(工具構成)を選択する。更にシステムは前記
曲げ順に基づく前記パーツのための曲げプラン及び前記
入力装置により入力され且つ選択された工具立てを格納
するための曲げプラン格納システムを含む。
【0092】前記パーツの2次元平面画像は前記パーツ
の各曲げ線の表現を含む。そして前記入力装置は前記パ
ーツの前記2次元平面画像において表示される曲げ線の
各々を選択することにより曲げ順を入力するように構成
されている。前記入力装置はまた曲げ線が選択されると
ころの順番に基づいて曲げ順を入力するように構成され
ている。前記の代わりに或いはこれらと組み合わせて、
前記入力装置はまた前記各曲げ線が選択される時、前記
入力装置により入力される曲げ順番号に基づいて曲げ順
を入力するように構成されている。ここに開示されるよ
うに、前記システムと共に用いられる入力装置はジョイ
スティック装置またはマウス装置を含む。システムは更
に前記表示装置上に前記入力装置により入力される曲げ
順に基づいて前記曲げ線の各々についての曲げ順番号を
表示するための曲げ順番号表示システムを含む。入力方
向決定システムが、前記パーツの曲げ線の各々について
の挿入方向情報を前記表示装置上で決定し且つ表示する
ために設けられる。前記挿入方向情報は、各曲げ線のた
めの挿入方向を表現するための、表示される矢印を含
む。更に前記曲げ線の各々は前記パーツを2つのサイド
に分離し、前記挿入方向決定システムは、より小さい所
定の寸法を有する前記パーツの前記サイドに基づいて前
記曲げ線のそれぞれについての挿入方向情報を決定す
る。前記所定の寸法は、前記曲げ線に直交する各サイド
の長さに関連し或いはそれは前記曲げ線に関連する各々
のサイドの面積に関連する。
【0093】曲げ順表示システムは、更に曲げ順に基づ
いて前記表示装置上に前記パーツの複数の画像を生成し
表示するように構成されている。ここに前記複数の画像
の各々は前記曲げ順の中での1つの段階における前記パ
ーツの表現に関連する。表現される複数の画像は前記曲
げ順に対応して順番に表示される。ドラッグ・ドロップ
編集システムが、前記表示装置上の前記複数の画像の表
示される順番の変更に基づいて、前記曲げ順を修正する
ために更に設けられている。このドラッグ・ドロップ編
集システムは、前記複数の画像の1つが前記入力装置に
より選択され且つ前記表示された順番の中で異なる位置
に移動される時、前記表示された順番を変更するように
構成されている。
【0094】この発明の1つの側面によれば、前記表示
された工具立て情報は、前記表示装置上に表示される複
数の工具アイコンを含む。ここに前記工具アイコンの各
々は所定の工具を表す。前記表示された工具立て情報は
更に、前記表示装置上に表示される工具データのテーブ
ルを含む。前記工具データのテーブル内での各記載は所
定の工具に関連する。この発明の1つの特徴によれば、
工具立て情報は、一連の連続的に表示されるスクリーン
表示を通して前記工具立て表示システムにより表示され
る。これにより前記連続的に表示されるスクリーン表示
の少なくとも1つは前記入力装置による前回の選択に基
づいて表示される。
【0095】例えば、前記工具立て表示システムは、前
記表示装置上に複数の工具タイプアイコンを含む第1の
スクリーン表示を表示するように構成されている。ここ
に前記工具タイプアイコンの各々は1つの工具タイプを
表す。前記工具タイプはパンチまたはダイまたはダイホ
ルダまたはダイレールの少なくとも1つに関連する。前
記工具立て表示システムはまた前記工具タイプアイコン
の1つの選択に応じて、前記表示装置上に第2のスクリ
ーン表示を表示するように構成されている。ここに前記
第2のスクリーン表示は複数の工具形状アイコンを含
み、且つ前記工具形状アイコンの各々は前記入力装置に
より選択される工具タイプアイコンに関連する。前記工
具立て表示システムは更に、前記工具形状アイコンの1
つの選択に応じて、前記表示装置上に工具寸法データの
テーブルを表現するように構成されている。ここに前記
工具寸法データは複数の工具に関連し、前記工具の各々
は前記入力装置により選択される工具形状アイコンに関
連する。前記工具立ての少なくとも一部は、前記工具寸
法データのテーブルからのデータの選択に基づいて前記
入力装置により選択され且つ入力される。
【0096】他の特徴がこの発明の装置に含まれる。例
えば前記工具立て情報は、前記曲げプランにおいて用い
られる各工具についての、曲げ機械内での工具立て位置
に関連する工具取り付け情報を含む。更に工具立て表示
システムは、前記入力装置により前記工具取り付け情報
を入力するために前記表示装置上に工具取り付けウィン
ドウを生成し且つ表示するように構成されている。更に
前記システムは、前記パーツの2次元平面画像と前記パ
ーツの複数のイメージが前記表示装置上に同時に表示さ
れるように構成されている。この発明の更に他の側面に
よれば、図形的ユーザインタフェースを用いて曲げプラ
ンを生成するための方法が提供される。この方法は以下
のステップを含む:表示装置上に曲げ順入力ウィンドウ
を生成し且つ表示すること、ここに曲げ順入力ウィンド
ウは前記パーツの2次元平面画像を含む;入力装置によ
り前記パーツの2次元平面画像に基づいて曲げ順を入力
すること;前記表示装置上に工具立て情報を生成し且つ
表示すること、ここに前記工具立て情報は複数の工具に
関連する;前記入力装置により、前記表示装置上に表示
される工具立て情報に基づいて工具立てを選択するこ
と;そして格納装置に、前記入力された曲げ順及び選択
された工具立てに基づく前記パーツのための曲げプラン
を格納すること。
【0097】前記方法によれば、前記パーツの2次元平
面画像は前記パーツの各曲げ線の表現を含み、且つ前記
曲げ順は前記パーツの2次元平面画像において表示され
る曲げ線の各々を選択することにより入力される。特
に、前記曲げ順は、各曲げ線が選択された順番に基づい
て或いは各曲げ線が選択される際、前記入力装置により
入力される曲げ順番号に基づいて入力される。ここに開
示されるようにこの方法で使用される入力装置はジョイ
スティック装置またはマウス装置を含む。
【0098】前記方法は更に前記表示装置上に、前記入
力装置により入力された曲げ順に基づいて各曲げ線の曲
げ順番号を表示することを含む。他の工程が更に提供さ
れる。例えば表示装置上に前記パーツの各曲げ線のため
の挿入方向情報を決定し表示することである。前記各曲
げ線のための挿入方向情報は、前記曲げ線により分離さ
れ、より小さい所定の寸法を有する前記パーツのサイド
に基づいて決定される。更に前記各曲げ線のための表示
される挿入決定情報は前記曲げ線のための挿入方向に関
連する矢印を含む。他の特徴によれば、発明は更に曲げ
順に基づいて前記表示装置上に前記パーツの複数の画像
を生成し表示する工程を含む。ここに前記パーツの複数
の画像の各々は前記曲げ順内での各段階のパーツの表現
に関連する。ドラッグ・ドロップ編集ステップが前記表
示上の前記複数の画像の表示される順番の変更に基づい
て前記曲げ順を変更するために設けられる。前記表示さ
れる順番は前記複数の画像の少なくとも1つを表示され
る順番の中で異なる位置へ移動することにより変更され
る。そして前記複数の画像と前記パーツのそれぞれの表
現は、変更された曲げ順に基づいて再生成され且つ表示
される。
【0099】前記方法はまた、一連の連続的に表示され
るスクリーン表示を介して工具立て情報を表示すること
を含む。ここに前記連続的に表示されるスクリーン表示
の少なくとも1つは前記入力装置による前回の選択に基
づいて表示される。前記表示の工程は、表示装置上に、
複数の工具タイプアイコンを含む第1のスクリーン表示
を表示するために設けられ、工具タイプアイコンの各々
は1つの工具タイプを表す。更にこの方法は、また前記
入力装置により前記工具タイプアイコンの1つを選択す
る工程及び前記工具タイプアイコンの1つの選択に応じ
て前記表示装置上に第2のスクリーンディスプレイを表
示する工程を含む。ここに前記第2のスクリーン表示
は、複数の工具形状アイコンを含み、前記工具形状アイ
コンの各々は前記入力装置により選択された工具タイプ
アイコンに関連する。前記方法はまた、前記入力装置に
より前記工具形状アイコンの1つを選択する工程と前記
工具形状アイコンの1つの選択に応じて、前記表示装置
上に工具寸法データのテーブルを表示する工程とを含
む。前記工具寸法データは、複数の工具に関連し、複数
の工具の各々は前記入力装置により選択された工具形状
アイコンに関連する。
【0100】この発明の更に他の側面によれば、図形的
ユーザインタフェースの使用により曲げ順を生成するた
めのシステムが提供される。このシステムは、表示装置
上に曲げ順入力ウィンドウを生成し表示するための曲げ
順表示システムを含む。ここに前記曲げ順入力ウィンド
ウは、前記パーツの2次元平面画像と前記パーツの2次
元平面画像に基づいて曲げ順を入力するための入力装置
とを含む。前記曲げ順表示システムは、前記入力装置に
より入力された曲げ順に基づいて前記パーツの複数の画
像を生成し且つ表示するように構成されている。そして
前記パーツの複数の画像は前記曲げ順における各段階の
パーツの表現に関連する。
【0101】前記システムはまた、前記入力装置により
入力された曲げ順に基づいて前記パーツの曲げ順を格納
するための曲げ順格納システムを有する。前記曲げ順は
前記パーツの2次元平面画像において表示される前記パ
ーツの曲げ線の各々を選択することにより前記入力装置
により入力される。曲げ順番号表示システムが、前記入
力装置により入力された曲げ順に基づいて曲げ線の各々
に対して曲げ順番号を、前記表示装置上に表示するため
に設けられる。更に挿入方向決定システムが、前記パー
ツの各曲げ線について挿入方向情報を、前記表示装置上
において決定し表示するために設けられる。
【0102】前記曲げ順を変更するために、前記表示装
置上の複数の画像の表示される順番の変更に基づいて前
記曲げ順を変更するためのドラッグ・ドロップ編集シス
テムが設けられる。前記ドラッグ・ドロップ編集システ
ムは、前記入力装置により前記複数の画像の1つが選択
され前記表示順番において異なる位置へ移動される時、
前記表示された順番を変更するための手段を有する。前
記曲げ順表示システムはまた、前記変更された曲げ順に
基づいて前記複数の画像及び前記パーツの各々の表示を
再生成し且つ表示するための手段を有する。
【0103】図形的ユーザインタフェースを用いて曲げ
順を生成するための方法がまた設けられている。ここに
前記曲げ順が設備においてパーツの製造において使用さ
れるように構成されている。前記方法は以下の工程を含
む:表示装置上に曲げ順入力ウィンドウを生成し且つ表
示する工程、ここに前記曲げ順入力ウィンドウは前記パ
ーツの2次元平面画像を含む;入力装置を用いて前記パ
ーツの前記2次元平面画像に基づいて曲げ順を入力する
工程;前記パーツの複数の画像のそれぞれが前記曲げ順
におけるある段階の前記パーツの表現に関連するよう
に、前記入力装置により入力された前記曲げ順に基づい
て前記パーツの複数の画像を生成し且つ表示する工程。
【0104】この発明の更に他の側面によれば、図形的
ユーザインタフェースの使用を介してパーツのための工
具立てを生成するためのシステムが提供される。このシ
ステムは、前記表示装置上に工具立て情報を生成し且つ
表示するための工具立て表示システムを含む。これによ
り前記工具立て情報は、一連の連続的に表示されるスク
リーン表示及び前記表示装置上に表示される工具立て情
報に基づいて工具立てを選択するための入力装置を介し
て表示される。
【0105】前記連続的に表示されるスクリーン表示の
少なくとも1つは、前記入力装置による前回の選択に基
づいて表示される。前記表示された工具立て情報は、複
数の工具に関連し且つ前記表示装置上に表示される複数
の工具アイコンを含む。ここに前記複数の工具アイコン
の各々は所定の工具を表す。前記表示された工具立て情
報はまた前記表示装置上に表示される工具データのテー
ブルを含む。ここに前記工具データのテーブル内の各記
載は所定の工具に関連する。この発明によれば図形的ユ
ーザインタフェースの使用によりパーツに対する工具立
てを生成するための方法がまた提供される。この方法は
以下の工程を有する:表示装置上に工具立て情報を生成
し且つ表示する工程、ここに前記工具立て情報は一連の
連続的に表示されるスクリーン表示で表示される;前記
表示装置上に表示される工具立て情報に基づいて、入力
装置を用いて工具立てを選択する工程。
【0106】前記方法はまた、前記入力装置によりなさ
れる前回の選択に部分的に基づいて前記連続的に表示さ
れるスクリーン表示の少なくとも1つを表示することを
含む。前記表示の工程はまた、複数の工具タイプアイコ
ンを有する第1のスクリーン表示を前記表示装置上に表
示するように設けられる。前記工具タイプアイコンの各
々は工具タイプを表す。更に前記方法は、前記入力装置
により前記工具タイプアイコンの1つを選択する工程と
前記工具タイプアイコンの1つの選択に応じて前記表示
装置上に第2のスクリーン表示を表示する工程とを含
む。ここに前記第2のスクリーン表示は複数の工具形状
アイコンを含み、前記工具形状アイコンの各々は前記入
力装置により選択された工具タイプアイコンに関連す
る。前記方法はまた前記入力装置により前記工具形状ア
イコンの1つを選択する工程と前記工具形状アイコンの
1つの選択に応じて前記表示装置上に工具寸法データの
テーブルを表示する工程とを含む。前記工具寸法データ
は複数の工具に関連し前記複数の工具の各々は前記入力
装置により選択された工具形状アイコンに関連する。
【0107】上記の特徴に加えて、さらに特徴と/また
はその変形を設けることができる、たとえば、発明を上
述した特徴の色々な組み合わせ、または再組み合わせ及
び/または下記の詳細な記述にある幾つかの特徴の組み
合わせとの再組み合わせに適用させることができる。
【0108】上に列記したものや他の本発明の対象物、
特徴及び利点については、この後により詳細に記述す
る。
【0109】付録の要約 本発明の詳細な記述をさらに促進するため、付記の限定
されない本発明の望ましい実施例の例に沿っての発明の
色々な特徴、操作及び機能に関するソースコードの例や
コメントを記した、以下の多数の付録を参照する:付録
Aはたとえば一つの類似部品を探索するときの特徴抽出
演算実行の典型的なソースコードであり;付録Bはたと
えば本発明の幾つかの類似部品の探索時に類似指数演算
を行使する典型的なソースコードであり;付録Cはこの
発明で曲げ線検出操作を行う典型的なソースコードであ
り;付録Dは本発明の2-Dクリーンアップを実行するため
の典型的なソースコードであり、これによって薄板金属
部品の3-Dモデルを元の3方向からの2-D図面にもとづい
て作成するのに使用出来;付録Eは本発明の曲げモデル
ビューアーに色々なビュー モードや機能を実行するた
めの典型的ソースコードであり;付録F,G,HとIは本発明
の自動寸法入れ特性を実行するための典型的なソースコ
ードとコメントであり;付録Jは本発明の曲げモデルビ
ューアーの、部品・エンテイテイの観察可能性機能を実
行するための典型的なソースコードであり;付録Kは曲
げモデルの実施と部品構造の構成に関する、本発明の色
々な教訓をふまえた一般的なコメントを含み、付録Lは
与えられた部品の回転軸の動的計算による3-D操作とナ
ビゲーションシステムを実行する典型的なソースコード
である。
【0110】本発明はこの後の詳細記述で限定されない
本発明の望ましい実施例の例についての多数の図面を参
照しながら記述されており、記述の中の同じ参照番号は
全図面中の類似の部品を示す。
【0111】詳細な説明 本発明の見地に沿って、全工場に亘って設計製造情報を
管理分配し、工場内での部品の製造を促進するための装
置と方法が具備される。この本発明の特徴は広範囲の工
場環境や装置に利用することができ、特にこの発明は一
続きの製作製造段階が異なる場所で行われる工場環境の
充足に利用できる。限定されない実施例や種々の例を通
じて、本発明を、たとえば進歩的な薄板金属製造設備に
おける曲げ薄板金属部品の製作を参照しながら記述す
る。
【0112】図1に、本発明の実施例に従って、進歩的
な薄板金属製造設備38一般が、ブロック線図で図示され
ている。図1に示すように、薄板金属製造設備または工
場38は全工場に分散している多数の場所10,12,14...20
をもつ。
【0113】これらの場所には設計事務所10、出荷作業
場14、打ち抜き作業場16、曲げ作業場18及び溶接作業場
20が含まれる。図1に画かれている薄板金属工場38には
分離した場所が六つしかないが、勿論工場は六つ以上の
分離した場所をもちうるし、また図1に画かれている各
タイプの事務所または作業場は一つ以上の場所を占める
こともある。たとえば設備38の大きさと製産必要容量に
より、一つ以上の打ち抜き作業場16、曲げ作業場18と/
または溶接作業場20を設けることができる。さらに工場
38は一つ以上の設計事務所10、組立作業場12または出荷
作業場14をもちうるし、曲げ薄板金属部品の製作製造を
促進するための他のタイプの場所をもちうる。
【0114】工場38内の各場所10,12,14...20は部品の
製作製造に伴う一つまたは一つ以上の別個の製作製造段
階や処理に対応し、実行する用具を備えている。たとえ
ば、設計事務所10は顧客の仕様にもとづいた薄板金属部
品の設計を促進するために、適当なキャド/キャム(CA
D/CAM)システムをもちうる。このCAD/CAMシステムには
一つまたは一つ以上のパソコンとデイスプレイ、プリン
ター及び市販のCAD/CAMソフトウエアーを含みうる。限
定されない例として、設計事務所10のCAD/CAMシステム
はオートキャドまたはキャドキー、またはアマダ・アメ
リカ 社(以前はU.S.アマダ株式会社の社名で営業)ビ
ユエナ パーク、カリフオルニアから入手できる アマ
ダAP40またはAP60 CAD/CAMシステムを含みうる。さら
に、ベールムのようなアシュラー社から入手できるウイ
ンドウズにもとづいたCADシステムも使用できる。このC
AD/CAMシステムを用いて設計プログラマーは客先の注文
にある図面やデータにもとづいて薄板金属部品の2-Dモ
デルと/または3-Dモデルを作成できる。設計プログラマ
ーはまた薄板金属部品の設計にもとづいた制御コードを
作成し、これによってたとえば被加工材から薄板金属部
品を打ち抜きまたは切断するための、CNC打ち抜きプレ
スと/または切断機を制御する部品プログラムが作成で
きる。
【0115】打ち抜き作業場16と曲げ作業場18は各々CN
C及び/またはNC機械工具のどのような組み合わせでも備
えられる。たとえば打ち抜き作業場16は、コマ・シリー
ズ及び/またはペガ・シリーズのアマダ・タレット打ち
抜きプレス、あるいは他の市販されているCNC及び/また
はNC打ち抜きプレス一つまたは一つ以上もつことがで
き、また曲げ作業場18は、RGシリーズ アマダ・プレス
ブレーキまたは他の市販されている多軸ゲージング・プ
レスブレーキのようなCNC及び/またはNCプレスブレーキ
を一つまたは一つ以上もつことができる。さらに溶接作
業場20は、薄板金属部品に対して必要な如何なる溶接を
も果たすために適当な溶接機器を備えることができる。
打ち抜き作業場16、曲げ作業場18と溶接作業場20は設備
38の工場内のどの場所にも設置出来、熟練オペレータ
(たとえば打ち抜きプレスオペレータ、曲げ機オペレー
タ等)によって手動で動かすことができる機械も備えて
いる。アマダ セルロボミニやアマダ プロムキャムの
ような全自動またはロボット支援機械もこれらの場所に
備えることができる。必要な打ち抜きと曲げの作業、あ
るいは必要な如何なる溶接作業もこれらの作業場で製作
過程中に行うことができる。
【0116】さらに図1に示すように、進歩的な薄板金
属設備38は組立作業場12と出荷作業場14も含む。組立作
業場12と出荷作業場14には、顧客への製造部品の組立と
出荷を促進するために必要な梱包、ルート割り当て及び
/または輸送機器も含まれる。部品の組立と出荷は工場
職員によって手動で行使または管理されるが、機械自動
化及び/または機械支援にすることもできる。さらに組
立作業場12と出荷作業場14は、物理的に工場作業場(た
とえば打ち抜き作業場16、曲げ作業場18及び/または
‘溶接作業場20に近接した)に近い場所に置くか、また
は薄板金属工場38とは別の設備または区域に置くことが
できる。本発明の見地に沿って、重要な設計と製造情報
の管理と分配は、設計と製造情報を電子的に記憶し、分
配することによって行われる。伝統的な紙上の仕事の段
取りまたはワークシートを、工場のどの場所からでも瞬
時的にアクセスできる電子的なジョッブシートに置き換
え、または補足することによって、本発明は工場の全体
的な効率を改善することができる。加えて、本発明の色
々な側面や特徴によって、記憶された設計製造情報の編
成とアクセスが改善される。さらに類似または同一の薄
板金属部品に関する以前の仕事情報のアクセスや検索
が、この発明の色々な特徴を通じて出来るようになって
いる。
【0117】この目的のため、本発明の色々な側面は、
サーバーモジュール32とデータベース30を薄板金属設備
38内の多数の場所10,12,14...20各々と結ぶ通信ネット
ワーク26を設けることによって実行される。このあと論
ずるように、各場所10,12,14...20は通信ネットワーク2
6とデータベース30にインターフエイスするステーショ
ンモジュールをもつ。図1、2と3に発明のこれらの特
色と実装の限定されない例を示す。
【0118】図1と2に示すように、通信ネットワーク2
6は設備38の色々な場所10,12,14...20の各々とサーバー
モジュール32とデータベース30を結んでいる。通信ネッ
トワーク26はデータや情報を場所10,12,14...20とサー
バーモジュール32とデータベース30間で伝送できるもの
であれば、どのようなネットワークでもよい。伝送は電
子的または光学的に、無線周波数伝送または遠赤外伝送
によって行われる。限定されない例として、通信ネット
ワーク26は、ローカルエリアネットワーク(LAN)、エ
ーテルネットまたは同様のネットワーク構造で構成出来
る。後でさらに述べるように、場所10,12,14...20の各
々はまた、通信ネットワーク26を通じて情報を伝送し、
受信するためネットワーク終端接続装置(たとえばコン
ピュータ、ミニコンピュータまたはワークステイショ
ン)及び/または周辺機器(たとえばデイスプレイモニ
ターまたは画面、プリンター、CD-ROM、及び/またはモ
デム)をもつことができる。ネットワーク終端接続装置
と周辺機器は通信ネットワーク26とインターフエイスす
るためと、あとで詳しく論ずるよに、本発明の色々な特
徴と側面を備えるためのハードウエアと適当なソフトウ
エアまたはプログラム論理を含む。工場内の場所にコン
ピュータを設置する場合のコンピュータは独立型、パソ
コンまたはその場所にある装備や機械類のインターフエ
イス装置の一部である汎用コンピュータであってもよ
い。たとえば、コンピュータはIBM互換性パソコンまた
はアマダAMNCのような機械類のインターフエイス/制御
システムの一部であるコンピュータであってもよい。
【0119】サーバーモジュール32とデータベース30も
通信ネットワークにつながれている。サーバーモジュー
ル32は、通信ネットワーク26とインターフエイスするの
に適したハードウエアとソフトウエアをもつパソコン、
ミニコンまたはミニフレームを含む。 サーバーモジュ
ール32はまた、あとで詳細に期述する、この発明の色々
な特徴を満たすソフトウエアやフアームウエアも含めら
れる。さらに本発明の見地に沿って、サーバーモジュー
ル32は顧客の注文に関連する設計製造情報を記憶するた
めのデータベース30をもちうる。データベース30は十分
な記憶容量をもつ市販のデータベースを備えることによ
り、工場の顧客の設計製造情報やその他のデータ、表、
及び/またはプログラムを記憶しておくことができる。
たとえば、データベース30に4GBまたはそれ以上の記憶
容量をもつスカジー(SCSI)メモリー・デイスクを含め
ることができる。データベース30に記憶された設計製造
情報をアクセスして、通信ネットワーク26を通じて薄板
金属設備38の色々な場所10,12,14...20に分配すること
ができる。構造的問い合わせ言語(SQL)のような、色々
なデータフオーマットがデータベース30にデータをアク
セスまたは記憶させるために使用されることができる。
さらに、データベース30に記憶されている情報は色々な
種類の記憶媒体、たとえば磁気テープ、光学デイスクあ
るいはフロッピーデでバックアップし、記憶しておくこ
とができる。サーバーモジュール32とデータベース30の
通信ネットワーク26との連結は、工場38内の別々の区域
または場所で(たとえば図1参照)、あるいは予め定め
られたステイションの中で(たとえば設計事務所内)、
またはこれに近接した場所で行うことができる。図1の
実施例では、データベース30がサーバーモジュール32の
一部で通信ネットワーク26とサーバーモジュールを通し
てインタフエースしているように画かれているが、デー
タベース30は勿論サーバーモジュール32と物理的に離れ
た場所に置かれていて、図2に示すように通信ネットワ
ーク26とネットワークデータベースモジュール34を介し
てつなぐことができる。
【0120】本発明の望ましい実施例に沿った限定され
ない例として、サーバーモジュール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)サーバーの全面的な支援を具備
できる。
【0121】色々なデータベース言語と管理システムは
またデータベースに記憶された情報を創りだしたり、保
持したり見たりすることに用いられる。構造的問い合わ
せ言語(SQL)のようなデータベース言語をデータベー
ス30のデータを確定したり、操作したり、制御したりす
るのに用いることができる。たとえば、SQLサーバー
(マイクロソフト社から入手できる小売り製品)は本発
明の実施に利用できる。さらに、この発明は開放データ
ベース連結オープン・データベース・コネクテイビテイ
ー(ODBC)互換ドライバーを備えることによって通信ネ
ットワーク26を通してのデータベース30からの情報のア
クセスを促進できる。ODBCに関するより詳しい情報はマ
イクロソフトオープン・データベース。コネクテイビテ
イー・ソフトウエア開発キットプログラマー用レフアラ
ンス・マニュエルでえられる。
【0122】図2は本発明の別の実施例に従って建設さ
れた進歩的な薄板金属製造設備のブロック線図である。
図2の実施例では、データベース30とサーバーモジュー
ル32は別々に設置されており、データベース30はネット
ワークデータベースモジュール34を介して通信ネットワ
ーク26につながれている。上記のように、本発明はこの
構成に限定されたものではなく、データベース30とサー
バーモジュール32は一緒に設置でき(たとえば図1に示
すように)、ネットワークデータベースモジュール34の
データベースにアクセスする機能をサーバーモジュール
に取り入れることができる。図2はまた、薄板金属製造
設備38内の色々な場所10,12,14...20に設置できるステ
イションモジュール36の例を示す。図示の目的で、図2
には曲げステイション18に設置されたステイションモジ
ュール36が例示されている。図2の例には示されていな
いが、同様のステーションモジュール36を設備38内の他
の場所にも設置できる。
【0123】図2に示すように、各モジュール(サーバ
ーモジュール32、ネットワークデータベースモジュール
34及びステイションモジュール36)はネットワークイン
ターフエイスカードまたはポート42を介して通信ネット
ワーク26につなぐことができる。ネットワークインター
フエイスカード26はベンダー専用で、選ばれた通信ネッ
トワークの形式にもとづいて選択できる。 各モジュー
ル32、34、36は通信ネットワーク26とインターフエイス
するためのネットワークソフトウエアまたはプログラム
された論理を含むことができる。 通信ネットワーク26
はイーサネット(Ethernet)で、10ベース/T(ツイスト
対)、10ベース/2(同軸)、または10ベース/5(厚膜ケ
ーブル)のような多くのタイプの市販ケーブルから設備
38の大きさと必要なケーブル長さにもとづいて選んだタ
イプのケーブルを用いたものであってもよい。
【0124】図2でサーバモジュール32はデイスプレイ
モニターまたはCRT44とキーボード、マウス及び/または
ジョイステイックを含む入力/出力デバイスをもつパソ
コンを含めうる。ネットワークインターフエスカード42
は備えられている拡張スロットまたはパソコン40のポー
トに挿入できる。さらに、パソコン40は100-200MHzの処
理速度とペンテイアムまたはペンテイアム・プロ マイ
クロプロセッサーを含むことができる。パソコン40はま
た、たとえば32MBまたはそれ以上の主記憶装置と1.2GB
またはそれ以上のランダムアクセス記憶装置(RAM)を
含むことができる。デイスプレイ44は高解像度の表示画
面、たとえば800×600の解像度をもつ市販のSVGAモニタ
ーを含むことができる。デイスプレイ44に表示された色
々なグラフ一クスや情報を支援するため、パソコン40は
また、PCIグラフイックス・カードのような市販のグラフ
イックスクス・カードを含むことができる。さらに、コ
ンピュータ40はサウンド・ブラスター、または互換の音
声及びゲームポートアダプターカードを含み、入力/出
力装置46はキーボード、ジョイステイックと/またはマ
ウスを含むことができる。
【0125】この発明の色々な特徴を実行するために、
サーバーモジュール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サーバー
を、データをリンクするために備えることができる。
【0126】図2の実施例では、データベース30はサー
バーモジュール32から分離して備えられており、ネット
ワーク データベース モジュール34を経由して通信ネ
ットワーク26につなげられている。先に述べたように、
データベース30は工場38の規模と、データベースに記憶
させる部品情報の量にもとづいて選ばれた、適当な記憶
スペースをもったSCSIデイスク(たとえば1-4 GB)を含
むことができる。ネットワーク データベース モジュ
ール34は、ペンテイウム マイクロプロセッサーを備え
たIBM互換機のようなパソコン40と、通信ネットワーク2
6とインターフェースするためのネットワーク インタ
ーフエース カード42を備えた拡張スロットを含むこと
ができる。データベース30はデータ母線を介してパソコ
ン40に連結でき、パソコン40は標準的なデイスプレイや
デイスプレイ モニターまたはCRTとキーボードのよう
な入力/出力デバイス(図2には示されていない)も含
む。
【0127】SQLに基づいたデータベース30へのアクセ
スを容易にするため、ネットワークデータベース モジ
ュール 34のパソコン40は、 マイクロソフトSQLサー
バーやオラクルSQLサーバーのような、市販のSQLサーバ
ーと合わせて設置することができる。OLE2サーバーのよ
うなOLEサーバーをデータをリンクするために備えてお
くことができる。パソコン40もDOSやマイクロソフト・
ウインドウズNT(サーバー バージョン)のような、色
々なソフトウエアを備えておくことができる。図2の実
施例は一つのステーションモジュール36の典型的な実装
例を含んでいる。この実施例では、ステーションモジュ
ール36は、曲げステーション18に装備されている。図2
に示すように、ステーションモジュール36はサーバーモ
ジュール32と同様のハードウエアを含んでいる。つま
り、各ステーションモジュール(たとえば図1に示す他
のステーション)はデイスプレイ モニターまたはCRT4
4と、ジョイステイックまたはマウスを含む入力/出力デ
バイス46をもつコンピュータ48を備えている。ネットワ
ーク・インターフエイス・カード42はコンピュータ40に
備えられている拡張スロットまたはポートに差し込むこ
とができる。前に論じたように、ステーションモジュー
ル36のコンピュータは 独立型、またはパソコン、また
はその場所に備えられた装置または機械類のインターフ
エイス ・デバイスの一部である汎用コンピュータであ
ってもよい。たとえば、コンピュータ48は、100-200 M
Hzの動作速度とペンテイウムまたはペンテイウム プロ
マイクロプロセッサーをもつIBM互換機のような自立型
パソコンであってもよいし、コンピュータ48はアマダAM
NCシステムのような機械類のインターフエイス/制御シ
ステムの一部、あるいはシステムに組み込まれたコンピ
ュータであってもよい。コンピュータ48はまた、たとえ
ば32MBまたはそれ以上の主記憶と、1.2GBまたはすれ以
上のランダム・アクセス記憶(RAM)を保有することが
できる。デイスプレイ44は高解像度デイスプレイ画面、
市販のたとえば解像度800×600をもつSVGAモニターを含
みうる。デイスプレイ44にデイスプレイされる色々なグ
ラフイックスや情報を支援するために、コンピュータ48
はPCIグラフイックス・カードのような市販のグラフイ
ックス・カードを備えることができる。さらに、コンピ
ュータ48はサウンド・ブラスター、または互換できる音
響及びゲームポート・アダプターとそれを支援する入力
/出力デバイス46のジョイステイックまたはマウスを含
むことができる。
【0128】この発明の色々な特徴を実行するために、
ステイション・モジュール36はソフトウエアといろいろ
な市販ソフトウエアが配置されている。たとえば、ステ
ーション・モジュール36はマイクロソフト・ウインドウ
ズ95またはウインドウズNT(ワークステーション版)の
ような基本ソフトが備えられている。さらに、ステーシ
ョン・モジュールに、この発明固有の機能と特徴をもた
せるために(たとえば図5を見よ)、ステーション・モ
ジュール36にソフトウエアまたはプログラム化論理装備
ルチーンが備えられる。後でより詳しく論ずるように、
これらのルチーンは高レベルのプログラム言語、たとえ
ばC++、及びオブジェクト指向プログラミング技術を用
いることによって開発できる。データをアクセスし、リ
ンクするために、ステーション・モジュール36はマイク
ロシフトOBCDドライバーとOLE2サーバーのようなOLEサ
ーバーが含まれている。サーバー・モジュール32と同
様、ステーション・モジュールもSQLをデータベース30
からデータをアクセスする基準に用いることができる。
【0129】曲げステーション18のステーション・モジ
ュール36が自立型パソコンとして備えられている場合、
曲げコードデータを作成するためと曲げ機械類25(たと
えばCNCまたはNC制御プレス・ブレーキ)とインターフ
エースするためのソフトウエアを装備できる。図2の実
施例では、コンピュータ36はパソコンとして装備され、
標準RS-232-C配線インターフエースを通じて曲げ機械25
とインターフエースするソフトウエアを配備しているよ
うに画かれている。このインターフエースはステーショ
ン・モジュール36が、RS-232-Cインターフエースを通じ
て曲げ機械25と通信し、曲げコードを送受できるために
装備されている。このインターフエースの実行はベンダ
ー用であり、曲げ機械25に用いられるデータ書式と命令
セットに依存する。ステーション・モジュール36から曲
げ機械25に送られるすべてのデータは、機械に決められ
ている機械命令セットにもとづいてフオーマットしたも
のでなければならない。ステーション・モジュール36の
コンピュータ48は、曲げコード生成のため、市販で入手
できるCNCまたはNCソフトウエアを備えることにより、
このような機械類のためにCNCまたはNCシステム(たと
えばアマダAMNC)の組み込みコンピュータに通常備わっ
ている機能をシミュレートできる。
【0130】図3はデータのサーバー・モジュール32、
データベース30と薄板金属製造設備38の間のそれぞれの
データの流れを示す実施例の典型である。図で表すため
と実施例におけるそれぞれのデータの流れの記述を容易
にするため、図3ではサーバー・モジュール32とデータ
ベース30(ネットワーク・データベース・モジュール34
に統合されている)は、各々別々に通信ネットワーク26
と直接に接続されていて、これらの構成要素間のデータ
の流れは通信ネットワークを通して行われる。勿論、こ
の技術に熟練した人なら分かるように、これら構成要素
間には多種多様のデータの流れ方式を用いることができ
る;また、データベース30がサーバー・モジュール32に
直接接続されている場合、データと情報はサーバー・モ
ジュールからデータベースに直接に、通信ネットワーク
26を用いることなく伝達できる。さらに、記述を容易に
するため、図3の通信ネットワーク26は簡略化されてお
り、図には打ち抜きステーション16と曲げステーション
18しか示されていない。しかしながら、場所10,12,1
4...20(工場内の他のあらゆる場所や区域も含めて)か
らのデータのやりとりの流れは、打ち抜きステーション
16と曲げステーション18について示したのと同様の方法
で行うことができる。
【0131】各顧客の注文に関連した設計製造情報は、
編成してデータベース30に記憶することができる。最初
に顧客から注文を受けると、基本的な製品と設計情報が
サーバー・モジュール32に入力され、それからデータベ
ース30に伝送され、記憶される。前に論じたように、サ
ーバー・モジュール32は、キーボードを備えたパソコン
等のような、データを入力する適当な手段を備えてい
る。サーバー・モジュール32でパソコンが用いられると
き、工場職員によるデータの入力を容易にするため、メ
ニュー方式画面を生成するソフトウエアを備えることが
できる。データ入力プログラムは、たとえばマイクロソ
フト・ウインドウズをベースとしたアプリケーション
で、ヘルプ及び/またはメニュー画面をもつものであっ
てよい。限定されない例として、サーバー・モジュール
32に入力され/または作成されて、データベース30に転
送されたデータは、図3に一般的に示してあるように、
部品情報、曲げモデル、特徴抽出データ及び曲げ線情報
を含むことができる。
【0132】部品情報は、たとえば部品または注文参照
番号、顧客の名前、部品の簡単な説明、バッチの大きさ
または量及び引き渡し予定日を含むことができる。曲げ
モデルデータは、たとえば部品の全体的な寸法(たとえ
ば幅、高さ、深さ)と材料のタイプ(たとえば鋼鉄、ス
テインレス鋼またはアルミニウム)、厚さ及び引っ張り
強さのような部品材料の情報を含むことができる。さら
に、特徴抽出データは手動による入力と/または自動的
に生成することによって、部品の主要な特徴を識別し、
データベースの類似部品の探索やその他の探索を容易に
する。特徴抽出データはデータベース30の別のフアイル
に格納するか、曲げモデルデータや各部品の仕事情報と
一緒に格納することができる。特徴抽出データは、たと
えば表面や面の数、曲げタイプの数(たとえば二面間の
正の折り曲げ、または二面間の負の折り曲げ)、面の間
の関係及び/または部品にある孔や他のタイプの開口の
数を含むことができる。後でより詳しく論ずるように、
このようなデータは特徴ベース部品マトリクスと/また
は逐次探索キー(たとえば下記の図6-10を見よ)に
よって表現し、編成できる。最後に、曲げ線情報はデー
タベース30に格納するため、サーバー・モジュール32に
入力できる。曲げ線情報は、たとえば部品の各折り曲げ
の曲げ角度、曲げ長さ、曲げの内半径(IR)、縮小量及
び曲げ方向(たとえば前方または後方)を含む主要な曲
げ線情報を含む。
【0133】通信ネットワーク26を通じてデータベース
30へデータを送受信するため、各場所10,12,14...20は
通信ネットワークに接続されているステーション・モジ
ュール(前に述べたステーション・モジュール36のよう
な)を含めることができる。図3には、打ち抜きステー
ション16と曲げステーション18は一般的にステーション
・モジュールと合わせたブロック線図で示されている。
前に論じたように、ステーション・モジュールは、たと
えばソフトウエア、または制御論理と独立型パソコン、
またはその場所に備えられた装置または機械類の一部で
ある汎用コンピュータを含む。各顧客の注文に応じて、
設計製造情報(部品情報、曲げ線情報および曲げモデル
・データを含む)が、所定参照番号またはコードを入力
することによってアクセスでき、検索できる。参照番号
またはコードは手動(たとえばキーボードまたはデジタ
ル入力パッドによって)またはバー・コードを、ステー
ション・モジュールに備えられているバー・コード読み
とり装置またはスキャナーでスキャンすることによって
入力できる。さらに、本発明の見地に沿って、以前の仕
事情報はデータベース30から、工場内のどの場所10,12,
14...20からでも、同様の部品探索を行うことによって
アクセスし、検索できる。引き続く詳しい記述で論ずる
ように、類似部品の探索は、特徴抽出データ、またはデ
ータベース30に記憶されている探索キーにもとづいて行
うことができ、これによって同一または類似の部品に関
する以前の仕事情報が検索され、将来の仕事の全体的な
製造時間の短縮に利用できる。
【0134】データベース30から検索された製造情報
は、作業場オペレータが曲げ計画を作成し、テストする
のに用いられる。たとえば、曲げステーション18の曲げ
オペレータは、薄板金属部品に必要な工具や最適な曲げ
手順を決めるために、データベース30から部品情報、曲
げ線情報や曲げモデル・データをアクセスし、検索する
ことができる。本発明の見地に沿って、ODBCドライバー
を備えることにより、各ステーション・モジュールがデ
ータベース30とインターフエースし、データベースに記
憶されている情報を表示できるようにすることができ
る。さらに、サーバー・モジュール32またはデータベー
ス30のネットワーク・データベース・モジュールは、デ
ータベースに記憶されているデータのアクセスと検索を
容易にするために、SQLサーバーを含むことができる。
最終曲げ計画に基づいて曲げコードがプログラムされる
と、曲げコードは曲げ手順とともに、図3に一般的に示
すように通信ネットワーク30を通じて、曲げステーショ
ンのステーション・モジュール18からデータベース30に
送られる。この情報は、当該の仕事に関連する他の設計
製造情報とともに記憶される。
【0135】他の情報もデータベース30に記憶すること
ができる。たとえば、部品の2-D及び/または3-D画像表
現は曲げモデルデータとともに記憶することができる。
この2-Dまたは3-D画像表現は設計ステーション10または
他の場所でCAD/CAMシステムを用いて作成し、設計ステ
ーション(あるいは他の適当な場所)のステーション・
モジュールを介して通信ネットワーク26を通じ、データ
ベース30に転送できる。あるいはまた、2-Dまたは3-D画
像はサーバー・モジュール32で、後でより詳しく述べる
ように、適当なCAD/CAMシステムまたはモデル化ソフト
ウエアを用いて、一連の機能または演算を実行すること
によって作成できる。
【0136】図4と5を参照しながら、サーバー・モジ
ュール32と各場所10,12,14...20においてプログラムさ
れ実行される処理や演算について詳述する。図4と5は
サーバー・モジュール32と薄板金属製造設備38内の各場
所10,12,14...20で実行される基本論理の流れの流れ図
である。図5は、たとえば曲げステーション18で実行さ
れる典型的な処理や操作に対するものであるが、設備38
内の特定な場所で実行される操作によっては、これ以外
の処理やステップも実行できることは理解できよう。以
下に述べる処理や操作はソフトウエア、または多種類の
プログラム作成言語と技法の一つを利用することによっ
て実施できる。たとえば、本発明の見地に沿って、関連
図面を参照しながら記述する下記の処理や操作は、C++
のような高レベルのプログラム作成言語とオブジェクト
指向プログラミング技法を用いることによって実施でき
る。さらに、限定されない例として、ウインドウズ・ベ
ースアプリケーション用にマイクロソフト社が作成し
た、プログラム作成言語のバージョンであるヴイジュア
ルC++を利用することができる。
【0137】図4は本発明の見地に沿って、サーバー・
モジュール 32が行う基本的な処理と操作の流れ図であ
る。図4はサーバー・モジュール32がソフトウエアまた
はプログラム化論理によって実行する処理と操作の基本
論理フローである。サーバー・モジュール32は、オペレ
ータまたはユーザーがサーバー・モジュールの色々な処
理や操作の選択と実行を支援するためにツール・バーや
ヘルプ及び/またはメニュー画面をもつウインドウズ・
ベース アプリケーションを含むことができる。処理は
薄板金属製造設備38で顧客の注文を受けたステップS.1
から開始される。顧客の注文は通常部品が工場で製造す
るのに必要な製品と設計の情報を含む。この情報は、た
とえば部品の幾何学的寸法、部品に必要な材料や他の設
計情報も含む。顧客から受けた情報をもとに、サーバー
・モジュール32は、ステップS.3に画かれているよう
に、データベース30に記憶されている以前の仕事情報の
探索を実行する。データベース30に記憶されている仕事
情報は多様な探索基準にもとづいて探索できる。たとえ
ば、情報は事前定義参照または仕事番号にもとづいて探
索でき、あるいは類似部品の探索は部品のある設計特徴
にもとづいて実行でき、これによって同一または類似の
部品に関する以前の仕事情報が現在の仕事のために検索
でき、利用できる。利用できる類似部品探索のさらに詳
しい記述は、図6-10を参照しながら以下に記す。
【0138】ステップS.5では、データベースの検索結
果が解析され、現在の顧客の注文が新しい部品か、以前
の仕事に類似の部品か、あるいは以前の仕事の繰り返し
かが決定される。同一の照合が見いだされる(たとえば
同じ部品または参照番号が見いだされる)と、顧客の現
在の注文は工場で行った以前の仕事の完全な繰り返しに
なり、仕事情報に対するこれ以上の修正は不必要で、以
前の仕事情報をデータベース30からアクセスしてステッ
プS.11に示すように現在の顧客の注文の遂行に利用でき
る。データベースの探索は以前の仕事の部品または参照
番号及び/またはフアイル名を与え、それによってサー
バー・モジュール32またはどのステーション・モジュー
ルにいるオペレータでもデータベースから仕事情報をア
クセスすることができる。部品または参照番号しかえら
れない場合、変換テーブルを備えることによって、オペ
レータが部品参照または仕事番号を入力することによっ
て以前の仕事情報のフアイル名を決定し、アクセスでき
る。従って、たとえばサーバー・モジュール32にいるオ
ペレータは、仕事情報と2-Dと3-Dモデル化情報をデータ
ベース30からアクセスすることによって部品の幾何学を
解析し、繰り返しの注文と類似であることを確認するこ
とができる。注文が繰り返しの注文であることが確認さ
れると、曲げステーション18のステーション・モジュー
ルにいる曲げオペレータは、さらに以前の仕事情報をア
クセスし、曲げコードのデータと工具段取り情報を含む
製造情報を曲げと部品の製作に利用することができる。
かかる記憶された専門的知識を利用することによって、
このようにして、繰り返しの注文をより効率的に、以前
に入力され開発された仕事情報を必要とせずに製造する
ことを可能にする。
【0139】しかしステップS.5で、もし現在の顧客の
注文が以前の仕事と類似か、以前の仕事と同じである
が、たとえば仕事または参照番号またはバッチの大きさ
等の修正が必要と決定されれば、ステップS.7での探索
で捜し出した以前の仕事情報データはデータベース30か
ら検索され、サーバー・モジュール32にいるオペレータ
によって編集し、修正される。編集機能を備えることに
よって、以前の仕事データを編集し、修正して新しい仕
事データを作成し、現在の顧客の注文のためにデータベ
ース30に格納できる。必要とする編集の量は、以前の仕
事と現在の仕事間の類似性の程度による。編集の量は、
参照または仕事番号またはバッチの大きさの単なる修正
から/または、部品の寸法や定められた曲げ手順の編集
のような、より広範囲な修正を含むものにわたる。以前
の仕事情報の編集が終わると、修正された仕事情報はス
テップS.9でデータベース30に格納される。修正された
仕事情報は新しい参照または仕事番号で格納できる。さ
らに、色々なデータベース管理機能(コーピー、削除、
保管、再命名等)を備えることによって、特別なコマン
ドの入力でデータベース30の以前の仕事情報の保持、ま
たは以前の仕事情報の消去または上書きができる。
【0140】現在の仕事に適合する類似または同一のも
のが無く、従って現在の顧客の注文は新しい仕事に関係
することが決定されると、論理フローは図4に示すステ
ップS.15に進む。この場合、現在の仕事は新しい仕事に
関するものになるので、設計製造情報を独立に作成し、
入力しなければならない。サーバー・モジュール32から
メニュー及び/またはヘルプ画面を提供することによっ
て、オペレータが必要な仕事情報すべてを入力するのを
支援することができる。本発明の見地に沿って、サーバ
ー・モジュール32のオペレータは、最初に新しい仕事の
基本的な部品情報を入力することによって新しいフアイ
ルを作成できる。部品情報は、たとえば参照または仕事
番号、顧客の名前、部品の簡単な記述、仕事に必要なバ
ッチの大きさまたは量及び予定引き渡し年月日を含む。
特徴抽出データまたは探索キーもステップS.15で入力で
きるし、また、以下に記すように、このデータを自動的
に作成するか、曲げモデルデータの作成と同時に抽出す
ることができる。他のデータや情報もステップS.15で入
力するか、部品の各曲げ線の曲げ角度、半径や長さを含
む曲げ線情報のような曲げモデルデータの入力後か入力
中に入力できる。ステップS.15に引き続き、論理フロー
は図4に示すように、オペレータによって曲げモデルデ
ータがサーバー・モジュール32で開発され、入力される
ように進む。
【0141】曲げモデルの開発と入力は、顧客から提供
された原図や情報に依存する。顧客の注文は、たとえば
製造される部品の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図面の提
供と表現は、設計プログラマー、曲げオペレータや他の
ユーザがより容易に解釈され理解される部品のモデリン
グとシミュレーションの図を与える。厚さ情報を省くこ
とはまた、サーバー・モジュールやステーション・モジ
ュールで、文中に記述の本発明の色々な特徴を実行し達
成するのに要する処理時間を短縮し、改善する。このよ
うな特徴のより詳細な記述や、本発明で利用することが
できる折りたたみと展開アルゴりズムについては、以下
に付図を参照しながら記述する。
【0142】図4は曲げモデルを開発するときに行われ
る一般的な処理と操作を示す。受理した、または顧客の
注文にもとづいて開発され、曲げモデルデータを作成す
るために入力できる色々なタイプの図面は、一般的にス
テップS.19,S.23,S.27とS.31に示されている。 ツール
・アイコン・バーとメニュー及び/またはヘルプ画面
を、サーバー・モジュール32によって、これらの各ステ
ップを選択し実施するオペレータを支援するために提供
できる。これらの図面から曲げモデルのための部品の2-
Dと3-Dモデルを作成する処理は、最初に提供された図面
のタイプに依存する。これらの図面は、サーバー・モジ
ュール32で手動で入力または作成するか、テープまたは
デイスクからダウンロードできる。サーバー・モジュー
ル32は、たとえば、設計事務所10にあるCAD/CAMシステ
ムとインターフエイスするか、またはサーバー・モジュ
ール32が独立型CAD/CAMシステムをもつことができる。
さらに、2-Dと3-D図面は、DXFまたはIGESフアイルとし
て保管され、サーバー・モジュール32に取り入れられ
る。
【0143】一方向平面図が提供された場合は、曲げモ
デルを作成する処理は、図4に示すようにステップS.19
から始められる。ステップS.19で、受理または作成され
た2-D平面図はサーバー・モジュール32に入力される。
部品の全体的な寸法(幅、高さ、深さ)のような他の曲
げモデルデータ及び部品材料情報もステップS.19で入力
できる。その後、折りたたみアルゴリズムまたは処理を
用いて、ステップS.21に一般的に示されているように、
元の2-D一方向図面にもとづいて3-Dモデル(材料の厚さ
のない)を作成することができる。2-D平面図から3-Dモ
デルを作成するのに行われる処理や操作の例は、図11
-18を参照しながら後で述べる。
【0144】部品の3-Dワイヤーフレーム図(材料厚さ
の無い)が受理または作成された場合、図の情報はステ
ップS.27で入力される。さらに、他の曲げモデルデー
タ、たとえば部品の全体的な寸法(幅、高さ、深さ)及
び部品材料情報もステップS.27で入力できる。この後
に、ステップS.27に示すように、部品の2-Dモデルを作
成するために、サーバー・モジュール32で展開のアルゴ
リズムまたは処理が実行される。2-Dモデルを3-D図面
(厚さのない)から作成するために行われる処理と操作
の例は、たとえば図19を参照しながら後で述べる。
【0145】部品の2-Dと3-Dモデル表示は、その部品の
ための曲げモデルの一部として格納される。さらに、前
に注記したように、2-Dと3-Dモデルの作成と格納の間
に、他の曲げモデルデータ(部品材料情報やその他の製
造情報のような)も入力し、曲げモデルデータとともに
データベース30に格納できる。曲げモデルデータを編成
し、格納するために実施できる、いろいろな機能やデー
タ構造配列についてはあとでより詳しく記述する(たと
えば図26と27を見よ)。
【0146】図4に示すように、簡単な3-D図面(材料
厚さなしの)がもともと作成または受理されていない場
合は、最終的な2-Dモデルを作成するのに必要な展開ア
ルゴリズムまたは処理を行う前に、部品の3-Dモデル
(厚さなし)を作成するための付加的な処理が必要とな
る。ステップS.23、S.25、S.31とS.33は、ステップS.29
で展開アルゴリズムを実行し、2-Dモデルを作成する前
に、サーバー・モジュール32で一般に実施される付加的
な処理と操作を示す。
【0147】たとえば、部品の2-D、三方向図面(三面
図)がはじめに提供または作成されている場合、ステッ
プS.23で図面はサーバー・モジュール32に入力または取
り入れることができる。さらに部品の全体的な寸法
(幅、高さ、深さ)のような他の曲げモデルデータや部
品材料情報もS.23で入力できる。引き続きステップS.25
では、入力された2-D三方向図面にもとづいて、部品の
簡単な3-D平面図が作成できる。作成された3-D図面は、
図4に示すように、ステップS.29で2-Dモデルを作成す
るのに用いられる。3-Dモデルを2-D三方向図面から作成
する処理と操作の例は、あとでたとえば図20を参照し
ながら述べる。
【0148】しかしながら、もし材料厚さが入っている
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を参照しながら下記に述べる。
【0149】図4に示すように、すべての重要な情報が
作成され、入力された後、顧客の注文に関連する部品情
報、曲げモデル情報及びその他のデータは、ステップS.
35でサーバー・モジュール32からデータベース30に移さ
れて格納される。データベース30に格納されたデータ
は、データベース探索を行うときに利用できる特徴抽出
または探索データも含む。下記に述べるように、特徴抽
出または探索データは、各仕事に関連した部品の基本的
または主要な特徴を指示するデータも含まれ、これによ
って仕事情報や格納されている同一または類似部品に関
する専門的知識の探索が実施できる。サーバー・モジュ
ール32に入力されたデータと情報は、たとえば図3に示
すように、直接データベース30に、または通信ネットワ
ーク26を介して転送することができる。上述のように、
曲げモデルデータを作成するときに、色々な図面に対し
て実施できる各種の処理や操作についての詳しい記述
は、下記に付図を参照しながら記す。
【0150】図5は薄板製造設備38の場所10,12,14...2
0に設けられ、各ステーション・モジュールで実施され
る基本的な処理や操作の流れ図を示す。例証のため、図
5は、たとえば曲げステーション18に置かれたステーシ
ョン・モジュールで実施される基本的な処理や操作の基
本論理の流れの例を示す。本発明の教示にもとづく技術
に熟練した者には理解できるように、図5に示す論理の
流れは、各場所で実施される操作や処理の性格により、
各ステーション・モジュールで修正できることは勿論で
ある。さらに、サーバー・モジュール32と同様、下記に
述べるステーション・モジュールでの処理や操作にはソ
フトウエアまたはプログラム化論理を装備できる。加う
るに、ステーション・モジュールは、オペレータまたは
ユーザーによる色々な処理や操作の選択と実施を容易に
するために、ツール・バー・アイコンまたはヘルプ及び
/またはメニュー画面をもつウインドウズ・ベース・ア
プリケーションを含むことができる。このようなヘルプ
及び/またはメニュー画面は、ステーション・モジュー
ルにおいてデータの入力または転送を容易にするために
も設けることができる。
【0151】図5に示すように、ステップS.51でステー
ション・モジュールを初期設定した後、オペレータはス
テップS.53で一つまたは一つ以上のデータベース探索基
準またはキー項目を入力することができる。探索基準
は、データベース30に格納されている以前の仕事情報、
または新しいまたは現在の仕事に関する仕事情報を捜し
出すために入力できる。オペレータは、たとえばデータ
ベース30から特定の仕事情報を検索するために、予め定
められた番号またはコードを入力できる。たとえば、本
発明の見地に沿って、バーコード をルーチングシート
に付すか、せん孔された材料につけて、ステーション・
モジュールでバーコード読みとり装置でスキャンするこ
とによって情報をアクセスすることができる。あるい
は、参照コードまたは番号を、ステーション・モジュー
ルでキーボードまたはデイジタル入力パッドを介して手
動で入力できる。変換テーブルを備えることによって、
部品参照または仕事番号のオペレータによる入力によっ
て、以前の仕事情報を定めることもできる。さらに、探
索基準またはキーを入力することによって、以前に格納
した仕事情報の類似部品探索を行うことも予想される。
このような探索は、部品の色々な設計特性または特徴抽
出データにもとづいて行うことができる。本発明の見地
に沿って実行できる類似部品探索の説明は、下記に図6
-10を参照しながら記す。
【0152】探索基準をステップS.53で入力した後、ス
テーション・モジュールはステップS.55で、通信ネット
ワーク26とネットワーク・データベース・モジュール34
を介してデータベース30の探索を実行できる。探索の結
果はステーション・モジュールに戻され、ステップS.57
でオペレータまたはユーザーが新しい仕事または類似の
以前の仕事に関する情報を要請したのか、または要請が
以前の仕事の完全な繰り返しに関するものなのかを決め
るために解析される。
【0153】同一のものが見いだされる(たとえば同じ
部品または参照番号が突きとめられる)と、以前の仕事
の繰り返しが決定され、仕事に関する格納されている設
計と製造情報がデータベース30からステーション・モジ
ュールに転送され、ステップS.59に一般的に示している
ように、オペレータが見られるように表示される。ステ
ーション・モジュールは一つまたは一つ以上のメニュー
表示画面または登録簿をもち、オペレータがデータベー
ス30から検索された色々な情報を選択し、表示できるよ
うになっている。オペレータは表示された情報をレビュ
ーし、ステップS.61における3-D曲げシミュレーション
のような、色々なシミュレーションを走らせて、その仕
事の曲げ手順の色々な段階を観察し、部品の幾何学を理
解することができる。オペレータはまた、必要工具や仕
事情報に記録されている他の特別な命令やメッセージの
ような他の情報をレビューすることもできる。仕事情報
の確認が終わると、オペレータは曲げ、または他の必要
な機械類を構成し(組立)、機械を操作して指定された
薄板金属部品を製作することができる。データベース30
から検索された仕事情報は、たとえば曲げステーション
18の機械類を制御する曲げコードを含む最終曲げ計画デ
ータを含む。機械類の構成と実際の操作は、このように
して図5のステップS.63に一般的に示してあるように、
オペレータによって遂行される。
【0154】もし同一または類似の仕事情報が捜し出さ
れず、情報が新しい仕事(つまりサーバー・モジュール
32には予備的な仕事情報のみ入力され、完全な仕事情報
が作成されていない)に関するものであることが決定し
た場合、部分的な部品情報と曲げモデルデータはデータ
ベース30から引き出されてステーション・モジュールに
送られ、ステップS.77でオペレータによって観察され
る。要請した情報は新しい仕事に関するものなので、オ
ペレータは必要な工具と曲げ手順を含む曲げ計画を作成
し、入力する必要がある。下記により詳しくのべるよう
に、曲げオペレータによる曲げ計画の作成を容易にする
ため、ステーション・モジュールにグラフイカル・ユー
ザー・インターフエース(GUI)や他の機能を備えるこ
とができる。GUIは、たとえば工具の選択、部品と工具
間の潜在的な不一致の自動点検、及び提案された曲げ手
順の各中間段階のシミュレーションを表示することによ
ってオペレータが曲げ計画を作成するのを支援するため
に設けることができる。サーバー・モジュールで曲げ計
画を作成し、入力したオペレータは、ステップS.80で曲
げコード(曲げ機械で曲げ手順を実行するためのCNCま
たはNCコード)を生成するために曲げ手順をプログラム
する。曲げコードは直接サーバー・モジュールで入力す
るか、曲げ機械類のCNCまたはNC制御装置とインター
フエースしてサーバー・モジュールに取り入れることが
できる。しかる後、オペレータはステップS.81で、曲げ
作業ステーションにおいてセットアップし、曲げ計画を
テストすることができる。曲げ計画に必要なすべてのテ
ストと必要な修正が完了すると、ステップS.83で最終的
な曲げデータをデータベース30に入力し格納する。最終
的な曲げデータは、曲げプログラムとともに、曲げ手順
と工具構成情報を含む。この情報は、たとえば曲げステ
ーション18のステーション・モジュールからデータベー
ス30に送られ、新しい仕事に関する他の設計製造情報と
ともに格納される。
【0155】図5のステップS.57で、情報が以前の仕事
の類似部品または同じ部品に関係しているが、たとえば
異なる参照あるいは仕事番号またはバッチ量等をもつこ
とが決定されれば、論理の流れはステップS.65に進む。
ステップS.65では、以前の仕事情報がデータベース30か
ら検索され、曲げステーション18で表示される。曲げオ
ペレータまたはユーザーはデータを見て、類似部品に必
要なデータの変更が何かを決める。この場合もステーシ
ョン・モジュールは一連のメニュー表示画面または登録
簿(ディレクトリ)を備えて、オペレータが、表示する
情報と、情報をどのように表示または修正するかの選択
ができるようにされている。たとえば、ステップS.69で
は、オペレータの類似部品の曲げ計画の作成を容易にす
るため、検索された情報にもとづいた3-D曲げシミュレ
ーションを備えることができる。以前の仕事情報をレビ
ューした後、オペレータはステップS.70で、曲げプログ
ラムとともに、工具と曲げ情報を修正する。部品の寸
法、参照番号やバッチ量のような他の仕事情報もステッ
プS.70で修正し、編集することができる。これが終わる
と、ステップS.71で実際の工具セットアップとテスト
が、オペレータによって作業場において、修正された曲
げ計画をテストするために行われる。テストと曲げ計画
をさらに修正することが完了すれば、オペレータはステ
ップS.73で最終的な曲げデータを入力し、それに新しい
参照番号または仕事番号をつけてデータベース30に格納
する。上記のように、以前の仕事情報もデータベース30
に、他の格納された仕事フアイルとともに保持できる。
さらに、色々なデータベース管理機能を、データベース
に格納されているフアイルを格納、消去、再命名等する
ために備えることができる。
【0156】次に図6-10を参照しながら、本発明の
教えるところに従って実行できる類似部品探索機能の例
を詳しく述べる。本発明の見地に沿って、特徴ベース形
態類似性探索アルゴリズムを利用する類似部品探索手続
きを、データベース30から以前の仕事情報を探索し、検
索するのに備えることができる。類似部品探索は製作さ
れる部品に関する設計特徴及び/または製造情報にもと
づいた同一及び/または類似部品の探索を含むことがあ
る。また類似部品探索は、たとえばサーバー・モジュー
ル32及び/または工場38内の色々なステーション・モジ
ュールにあるソフトウエアまたはプログラム化論理の使
用によっても実施できる。類似部品探索はサーバー・モ
ジュール32または薄板金属曲げ工場38内の場所10,12,1
4...20のいずれかで実行できる。C++またはマイクロソ
フト社のビジュアルC++プログラム言語のような、高レ
ベルのプログラム言語とオブジェクト指向プログラム技
法が類似部品探索の色々な処理や操作を実施するのに利
用することができる。
【0157】図6と7は利用できる類似部品探索アルゴ
リズムまたは処理の論理の流れを示す。図6に示すよう
に、重要な部品モデルデータフアイルはステップS.100
でアクセスできる。部品モデルには、たとえば設計事務
所10に置かれたCADシステムで作成された曲げモデルデ
ータ及び/またはサーバー・モジュール32で作成され、
入力されたデータが含まれる。部品モデルには、たとえ
ば部品の色々な表面または面及び曲げ線の向き、幾何学
的関係及び相対位置を表す部品形態データ(部品トポロ
ジーデータ)が含まれる。部品モデルデータが検索さ
れ、または曲げモデルデータが手動で入力された後、ス
テップS.102で、当該部品の曲げモデル及び/または部品
形態データにもとづいた特徴抽出データを自動的に導出
するための特徴抽出操作を行うことができる。
【0158】本発明の見地に沿って、特徴抽出データ
は、薄板金属部品の色々な特徴を解析することによって
導出できる。たとえば、部品の色々な面の解析によっ
て、隣り合わせの面が開放または接触コーナーをもつか
どうかを決めることができる。平行曲げ、直列曲げ、共
線曲げまた対向曲げのような他の特徴も、各部品の明確
かつ独特な特徴を決定し、抽出するために解析すること
ができる。
【0159】表1は類似部品探索を行うときに解析され
る色々な曲げと面の特徴を示す。特徴抽出操作に含めな
ければならない抽出特徴は、正の曲げ、負の曲げ特徴と
ともに接触コーナー、開放コーナー特徴である。さらに
特徴抽出操作は、少なくとも平行曲げ、直列曲げ、共線
曲げ、異相共線曲げ及び厚さオフセット曲げの特徴解析
を含まなければならない。
【0160】ステップS.102で行った特徴抽出操作は、
各特徴の曲げモデルデータと形態(トポロジー)の解
析、形態の修正、今後の解析のための形態にもとづく特
徴ベース行列(特徴に基づく行列)の作成からなる一連
の操作を含むこともある。例証のため、図8(a)―9
(d)に接触コーナーをもつ4折り曲げ箱部品と開放コ
ーナーをもつ4折り曲げ箱部品に対する特徴抽出操作を
示す。
【0161】
【表1】 例証のため、図8(a)-9(d)には隣接面のコーナ
ー関係にもとづく特徴抽出が示されている。図8(a)
に示す五つの面(1-5)をもつ閉じた4折り曲げ箱や、図
8(b)に示す五つの面(1-5)をもつ開いた4折り曲げ
箱については、いずれの部品を表すにも、図8(c)に
示す同じ簡単な面形態が提供される。この形態は部品ま
たは曲げモデルデータとともに格納し、提供することが
できる。しかしながら、図8(c)の単純な面形態(面
トポロジー)は、部品の面(1-5)の間の関係の基本的な
情報しか与えず、隣接する面間のコーナーの関係や曲げ
の種類のような部品の色々な特徴の情報は与えない。従
って、特徴抽出操作時に、部品または曲げモデルデータ
とともに格納されている関連面形態をを解析することに
より、基本的な面形態が部品の色々な特徴についての付
加的な情報を含むように修正することができる。
【0162】たとえば、図8(a)の閉じた4折り曲げ
箱の部品または曲げモデルデータを調べることにより、
隣接面間のコーナーが解析でき、図9(a)に示されて
いる修正された面形態が作成でき、これによって各面間
の接触コーナー状況を示すことができる。同様に、図9
(a)に示されている開いた4折り曲げ箱の部品または
曲げモデルデータを調べることにより、図9(b)に示
す修正された面形態を作成し、それによって部品の色々
な隣接する面の間の開放コーナー関係を示すことができ
る。図9(a)と9(b)に示すように、面形態に面の
コーナーの関係(たとえば接触または開放)を示す特別
の連結線を加えることができる。他のデータも他の特徴
(たとえば存在する曲げの形式)を示すため、及び特徴
ベース面形態を作成するために加えることができる。特
徴ベース情報が含められるように形態を修正した後、抽
出情報をより簡単に解析し、比較するために行列を作成
することができる。たとえば、図9(a)の特徴ベース
面幾何学にもとづいて、図9(c)に示す行列を作成
し、これによって図8(a)の閉じた4折り曲げ箱の色
々な特徴を示すことができる。同様に、開いた4折り曲
げ箱に対しては、たとえば図9(b)に示す特徴ベース
面形態にもとづいて、図9(d)に示す行列を作成でき
る。他の特徴抽出データ、たとえば部品の曲げ特徴(た
とえば90゜正の曲げ角度または90゜負の曲げ角度等)も
行列の中に示すことができる。
【0163】上記のように、ステップS.102の特徴抽出
操作は、曲げモデルデータと形態を解析することによっ
て、部品に色々な特徴が存在するかどうかを決めるため
に実施できる。本発明の見地に沿って、特徴抽出操作は
部品に提供されている曲げモデルと形態データについて
行うことができる。このデータは、面のデータ、曲げ線
データ(たとえば曲げ線長さと位置等)、面―曲げ線関
係データ、曲げ角度データ及び特別の特徴データ(たと
えばZ―曲げや縁取り等)を含む、薄板金属部品に関す
るすべての重要な幾何学と位置のデータ(たとえば2-D
空間(X,Y)及び/または3-D空間(X.Y.Z)における)を
含む。線、曲げ線や他の構成要素はエンドポイント(端
点)や/またはベクトルで定義することができる。たと
えば各2D線は一組の2Dエンドポイント(たとえばX1,Y1
とX2,Y2)、各3D線は一組の3Dエンドポイント(たとえ
ばX1,Y1,Z1,とX2,Y2,Z2)で指定することができる。曲
げ線は2Dまたは3D空間における場所とともに曲げ線の方
向を示すベクトルで表すことができる。さらに、2Dの弧
は2D空間データ(たとえば中心X、中心Y、半径、開始角
度、終了角度)、3Dの弧は3D空間データ(たとえば中心
X、中心Y、中心Z、ビユー行列、半径、角度開始、角度
終了)で指定することができる。部品形態データも、部
品の色々な面や曲げ線の場所やこれらの間の幾何学的関
係を示すために提供することができる。各面は線と/ま
たは弧の集合または連結データリストで定義することが
できる。
【0164】部品の特徴を抽出するため、曲げモデルと
形態データの特徴抽出操作を行い、解析することによっ
て、ある特徴が部品に存在するかどうかを定めることが
できる。このプロセスは、抽出する各特徴間の色々な特
色や関係にもとづく、曲げモデルと形態データの解析を
含むこともできる。各特徴の特色と関係を知るための曲
げモデルと形態データの解析によって、ある特徴(たと
えば面間の接触コーナー、開放コーナー特性、または平
行または直列曲げ特性)の存在が検出できる。異なるプ
ロセスを、各特徴の特定の特性と関係を特徴抽出操作で
検出するために備えることもできる。解析される各特徴
間の特性と関係の類似性にもとづいて、部品に一つ以上
の特徴が存在するかどうかをチェックするために幾つか
のプロセスを組み合わせるか作成することもできる。
【0165】限定されない例として、ステップS.102に
おける特徴抽出操作の際に、コーナーの特徴、たとえば
同じ曲げ方向をもつ二つ面の接触コーナー特徴(表1のT
ouchCnr特徴)を抽出し、検出するために行うことがで
きるプロセスについて述べる。下記のプロセスは、他の
特徴の検出、たとえば逆曲げ方向をもつ二つの面の接触
コーナー特徴(表1のtouchCnr特徴)または同じまたは
逆曲げ方向を持つ二つの面の開放コーナー特徴(表1のO
penCnrとopenCnr特徴)に用いることもできる。プロセ
スを修正することによって、他の特徴も検出できる(た
とえば平行曲げ、直列曲げ等)。さらに、面の可能な各
組み合わせに関するデータを、抽出される各特徴の特性
と関係を知るために解析することができる。
【0166】たとえば、接触コーナーの特徴をもつTouc
hCnrの場合、検出する特徴または関係は:共通の面を持
つ二つの面;同じ曲げ線方向;同じ頂点を(または頂点
間の距離が事前に定めた範囲内にある頂点)をもつ曲げ
線を含む。接触コーナーの特徴をもつtouchCnrの場合、
同様の特性または関係を検出しなければならない;ただ
同じ方向の曲げ線をもつ面ではなく、面は逆方向の曲げ
線をもっていなければならない(たとえば表1をみ
よ)。開放コーナー特徴OpenCnrとopenCnrも同様に検出
できるが、各特徴に接触コーナー関係の代わりに、面間
に開放コーナーが存在する(たとえば面の曲げ線が事前
設定の範囲の距離より大きく隔たっている)ことと、同
じまたは逆の曲げ線方向(たとえば表1と表中のOpenCnr
とopenCnrの定義をみよ)をもつ曲げ線を検出し、解析
しなければならない。
【0167】接触コーナー特徴(たとえば表1のTouchCn
r特徴)を検出するためには、先ずある二つの面を解析
し、二つの面が共通の面に接続しているかを決定する。
これは各面の曲げ線データと各曲げ線の曲げ線―面関係
データを探索して、共通面が存在するかどうかを決定す
ることによって検出できる。もし二つの面が共通の面に
接続していれば、各面の曲げ線方向を解析して同じ曲げ
線方向(または、たとえばtouchCnr特徴を検出する場合
は逆の曲げ線方向)をもつかを見る。これは、たとえば
各面の曲げ線方向を示すベクトルデータを解析する事に
よって決められる。
【0168】二つの面が共通の面をもち、曲げモデルと
形態データにもとづいて同じ曲げ線方向をもつことが決
定されると、データを検査することによって曲げ線が平
行かどうかが検出される。色々な方法を用いて、曲げモ
デルと形態データにもとづいて曲げ線が平行かどうかを
検出することができる。たとえば、平行曲げ線の検出
は、曲げ線方向を定めるベクトルの外積をとることによ
って決められる。もしベクトルの外積がゼロ(または近
似的にゼロ)であれば、曲げ線は平行であると決定され
る。もしベクトルの外積がゼロでなければ(または近似
的にゼロでない)、二つの面の曲げ線は平行でない。
【0169】二つの面が共通の面をもち、曲げ線方向が
同じで曲げ線は平行ではないことが決まった後、面の間
のコーナーの関係(たとえば接触か開放か)を決めるた
めに、曲げモデルデータが解析される。二つの面のコー
ナー関係は、曲げモデルデータから、面の曲げ線が共通
の頂点をもつかどうかを検出することによって決められ
る。曲げ線が共通の頂点をもっていれば、二つの面は同
じ曲げ線方向の接触コーナー関係(表1のTouchCnr特
徴)をもつ。曲げ線は共通の頂点をもっているが、二つ
の面の曲げ線方向が異なることが決まれば、二つの面は
逆方向の接触コーナー関係(たとえば表1のtouchCnr特
徴)をもつと決められる。
【0170】二つの面が共通の頂点をもっていない場合
でも、頂点間の距離が予め定められた範囲内であれば、
二つの面は接触コーナー関係をもつと決定できる。しば
しば部品の隣接する面の間に、たとえばパンチ工具を通
すためのすき間として最小限のスペースが設けられるこ
とがある。このスペースは、通常フランジの高さのとこ
ろでの工具の幅で決められる。例をあげれば、二つの面
の曲げ線の頂点間の距離が0-5mm以内であれば、接触コ
ーナー特徴の存在が決定できる。もし二つの面のコーナ
ー間のスペースが、事前に定められた範囲より大きけれ
ば、開放コーナー特徴の存在が決定できる(たとえば表
1のOpenCnrまたはopenCnr特徴)。
【0171】上記のプロセスは部品の面のあらゆる組み
合わせについて、各面のコーナー特徴を決めるために実
施することができる。部品の面や曲げ線に関連する他の
特徴も、同じように部品幾何学と形態データの解析によ
って行うことができる。ステップS.102における特徴抽
出操作を実行するための典型的なコードを付録Aに示
す。このコードはC++プログラム言語で書かれており、
表1に記してあるような特徴を抽出検出するための色々
なプロセスを含む。付録Aのコードには、使用されてい
る論理やアルゴリズムの解析を容易にするためのコメン
トがついている。またこのコード例では、色々な特徴の
理解を助けるために、表1と同じ特徴の用語が使われて
いる。
【0172】部品の色々な特徴が検出されると、部品の
基本的な形態は修正され、抽出された特徴が含められ
る。特徴ベース形態を提供することは有用かもしれない
が、このような形態をお互いに比較することは容易でな
い。その代わりに、本応用の発明者達は行列の形で提供
された特徴抽出情報を比較する方が、より有効で容易で
あることを発見した。従って、本発明の一つの特徴とし
て、特徴抽出操作の際に、検出された特徴にもとづいた
特徴ベース部品行列(図9(c)と9(d)に示す代表
的な行列のような)が作成される。作成された部品の特
徴ベース行列は、他の所定の、格納された行列と比較す
ることによって、どのような基本的な形や特徴が部品に
含まれているかを決定する。
【0173】特徴ベース行列は、部品の色々な特徴を検
出し、抽出した後に、部品毎に作成され、格納される。
図9(c)と9(d)に示すように、行列は対称的な2
次元行列で部品の面の数に等しい次数をもつ。行列は部
品のすべての検出された特徴情報を含み、各面の間の色
々な特徴が行列の各場所に提供されている。特徴ベース
行列は、一時的にサーバーまたはステーションモジュー
ルの記憶装置に格納し、類似部品探索を実行するときに
のみ使用し、所定の行列と比較することができる。ある
いは、特徴ベース部品行列を永久的に他の仕事情報とと
もにデータベース30に格納し、工場内のどの場所でもア
クセスできるようにすることができる。
【0174】図6に戻ると、特徴抽出操作を行った後、
引き出した特徴抽出データ行列を、特徴形態ライブラリ
に備えられている所定の特徴抽出データ行列と比較する
ことができる。特徴形態ライブラリは、別のデータフア
イルとして、データベース30のようなデータベース、ま
たはサーバー・モジュールかステーション・モジュール
に格納しておくことができる。特徴ライブラリは、基本
的または基礎的な部品の形状(たとえば4折り曲げ箱、
橋梁等)に対応するまたは定義する特徴抽出データを含
む所定の行列よりなる。各所定特徴ベース行列は、特徴
ベース部品行列とともに、ASCIIまたはテキストフアイ
ルとして格納できる。ステップS.104のおける比較は、
ステップS.106に図示されているように、薄板金属部品
に存在する基本的または基礎的な形状/特徴を決めるた
めに行われる。格納されたルックアップテーブルを、ど
の基礎的な形状が各所定特徴行列に対応するかを示すた
めにを備えておくことができる。一致するものが見いだ
されると、ステップS.106でどの基礎的形状が存在する
かを決めるために、ルックアップテーブルがアクセスさ
れる。事前定義ライブラリに存在する一致する行列は、
特徴ベース部品行列と同じ次数であるか(この場合は部
品はただ一つの基礎的形状を含み、精確に対応すること
が決定される)、または部品行列のサブ行列かもしれな
い(この場合は部品は一つ以上の基礎的形状を含むかも
しれない)。
【0175】特徴ベース部品行列を事前定義ライブラリ
にある行列と比較するために再帰プログラミング技法を
利用することができる。含まれている情報を比較すると
き、行列の指標を入れ替えることによって、データ割り
当ての使用が避けられ、必要なプロセス時間が短縮され
る。再帰プログラミング技法と指標の入れ替えはまた、
異なる次数と異なる基底面をもつ行列の比較を容易にす
る。
【0176】本発明の見地に沿って、ステップS.104で
実施される比較操作は、一連の比較よりなり、最初によ
り複雑な形状(たとえば多数の曲げ、またはタブのよう
な複雑な成形を含む形状)に関する行列の比較から開始
し、より複雑でない形状(たとえば、より少ない曲げ、
またはより複雑でない曲げ、より少ない数の面をもつ形
状)へと進む。この一連の比較は部品に、所定数の基本
的形状が見いだされるまで行われる。たとえば、比較操
作はある特定の部品の三つの最も複雑な特徴または形状
を抽出するために行うことができる。さらに、この操作
を最初に、薄板金属部品によく、または度々みられる形
状に関する行列のグループに対する一連の比較から始
め、次により一般的でない形状に進むこともできる。部
品を事前定義ライブラリと比較するために、色々な方法
を有用な結果をうるために行うことができる。
【0177】たとえば、一連の比較操作を先ず、多数の
直角曲げを持つ長方形や正方形形状や直角曲げをもつ単
純な部品のような、直角曲げをもつ基本形状を含む行列
の直角グループに適用することができる。この行列のグ
ループは、グループの中の、より複雑な行列(たとえ
ば、タブをもつ四つ折り曲げ箱に対応する行列)からグ
ループの中のより単純な行列(たとえば、単純ハット部
品に関する行列)へと進める一連の比較にもとづいて探
索することができる。それから一連の比較を多角形部品
グループの行列に、さらに特別特徴グループの行列へ適
用することができる。多角形部品グループは五つ以上の
側面と、少なくとも90度以上の曲げを一つもつ部品を定
める行列を含みうる。特別特徴グループの行列は、Z―
曲げまたは縁取り曲げのような、特別な特徴または成形
をもつ部品に関係する事前定義ライブラリ内の行列を含
みうる。ここでもまた、部品の特徴ベース行列と各グル
ープの所定行列との間の一連の比較は、複雑性の度合い
の減少に従って行われる。この後に、部品の一つの面に
二つまたは二つ以上の特徴をもつ多重特徴グループのよ
うな、所定行列の他のグループを比較することができ
る。
【0178】複雑性の度合いに従って部品を事前定義ラ
イブラリの行列と比較し、実現と使用頻度にもとづく行
列のグループの一連の比較をすることによって、部品に
存在する基本的な形状の決定するためのライブラリとの
より効果的で有効な比較ができる。さらに、検出特徴の
重複が防がれ、より複雑な形状のみが識別される。
【0179】ステップS,108では、部品にある基本的な
特徴または形状間の関係を決めるために特徴関係操作を
行う。特徴または形状間の関係は距離によって定められ
る。二つの形状間の距離は、各々形状の基底面(基本
面)の間の曲げ線または面の数にもとづいて決められ
る。あるいは、特徴間の関係は、部品及び、各特徴の基
底面の相対位置と間隔を幾何学的に解析することによ
り、特徴間の物理的な距離または実際の寸法によって定
めることができる。
【0180】例示のため、ステップS.106で決定した部
品の三つの最も複雑な特徴または形状は、図10(a)
に示す4折り曲げ箱と、ブリッジと、もう一つの4折り曲
げ箱とであるとしよう。このような部品については、特
徴関係操作を、たとえば各基本的特徴の基底表面または
面の間の曲げ線の数を決めるために行うことができる。
図10(b)で示すように、第一の4折り曲げ箱の基底
(1)とブリッジの基底(2)の間の特徴関係は、二つの
曲げ線の間隔である。さらに、第一の4折り曲げ箱の基
底(1)と第二の4折り曲げ箱の基底(3)の間の関係
は、四つの曲げ線の間隔であり、ブリッジの基底(2)
と第二の4折り曲げ箱の基底(3)の間の関係は、二つの
曲げ線の間隔である。
【0181】いろいろなプロセスによって、部品の基本
形状の基底面間の曲げ線の数を決めることができる。た
とえば、特徴ベース部品行列と所定形状行列を利用し
て、ステップS.108で特徴関係を決めることができる。
最初に、部品行列にある各基本形状に対応する基底面を
捜し出す。これは所定形状行列の基底面を、部品行列の
面指標と相関することによって行うことができる。前に
論じたように、比較操作で切り離した所定形状行列は、
部品行列のサブ行列かもしれない。部品行列で各基本形
状に対応する基底面を捜し出すには、部品行列内の形状
行列の位置と行列の指標の間の相関を解析する。各基本
形状の基底面は、予め定められており形状行列の第1列
に位置しているので、部品行列内の対応する位置と基底
面を捜しだすことができる。
【0182】特徴ベース部品行列内の各基本形状の基底
面を決定した後、特徴関係を決めるために、各形状の基
底面間の距離を解析する。この解析は、如何なる二つの
基底面間の距離をも同定する探索プロセスを含んでい
る。部品行列内の特徴と曲げ線情報を見ることによっ
て、どの二つの基底面間の曲げ線の数でも決定できる。
二つの面の間に一つ以上の経路が可能な場合には、最小
距離を用いてステップS.108において特徴関係を定義す
ることができる。
【0183】特徴関係操作を終えた後の論理の流れはス
テップS.110に続く。図7に示すように、ステップS.110
では、データベースの類似部品探索に用いる探索キーを
決めるために、データベース探索キーの同定が行われ
る。探索キーは、部品に同定された特徴や特徴関係の幾
通りもの組み合わせを含みうる。さらに、探索キーをア
センブルするのに、どのような基準の階層も用いること
ができる。限定されない例として、下記の基準に従って
探索キーを作成することができる:(i)部品に同定さ
れた一番目と二番目に複雑な特徴または形状;(ii)最
も複雑な二つの特徴間の距離または特徴関係;(iii)
部品に同定された三番目に複雑な特徴または形状;及び
(iv)部品に同定された一番目に複雑な特徴と三番目に
複雑な特徴間の特徴関係または距離、及び二番目に複雑
な特徴と三番目に複雑な特徴間の距離または特徴関係。
図10(c)に図10(a)の例にもとづいて開発され
た探索キーを示す。
【0184】データベースの探索を容易にするために、
探索キーは、形状ライブラリで定義された色々な基本形
状に割り当てられた所定コードをもつ整数の列で表すこ
とができる。たとえば、4折り曲げ箱に整数コード“1
6”が割り当てられ、ブリッジに整数コード“32”が割
り当てられたとしよう。この場合、図10(c)の例の
探索キーは、整数列“16,16,4,32,2,2”で表され、この
なかで“4”と“2”は基本形状または特徴間の色々な距
離を表す。しかしながら、探索キーの表示は、整数列に
限定されるものではなく、どのような組み合わせの整数
及び/または文字列を探索キーの表示に用いることがで
きる。
【0185】各部品の探索キーは、仕事情報とともに
(別のフアイルまたは同じフアイルに)、データべー
ス、たとえばデータベース30、に格納できる。特徴抽出
データの代表的な探索キーは、手動で入力するか、上記
のように自動的に作成できる。特徴ベース部品行列のよ
うな付加的特徴抽出データは、探索キーを用いて格納で
きる。探索キーが別のフアイルに格納してあるときに
は、各探索キーのセットと関連する部品情報を捜し出す
ための参照用テーブルを用意できる。あるいは、探索キ
ーは部品情報を同定する(たとえば部品または参照番号
によって)データフイールドとともに格納しておくこと
ができる。
【0186】ステップS.112では、同定された探索キー
にもとづくデータベースの協調探索が行われる。協調探
索は、協調データベース探索技法を用いる探索である。
協調探索技法は、同一の探索キーをもつ部品ばかりでな
く、類似の探索キーを持つ部品を捜し出す。これによっ
てデータベースにある、類似および同一部品を同定する
ことができる。特定の部品についての探索を行うと、そ
の部品のものと同定された探索キーを、データベースに
ある他の探索キーデータと比較することができる。ステ
ップS.112で行われる協調探索は、探索キーの順序を緩
めるか修正することによって、データベースにある項目
で、探索キーによって同定された特定の部品と正確に一
致するか又は最も類似している項目を同定するように構
成される。色々なプロセスと方法を、協調探索において
探索キーを適合させるのに用いることができる。たとえ
ば、最初にデータベースの探索を、探索する部品のもの
と同定されたものと正確に一致する探索キーの順序をも
つ部品を同定するために行うとする。これは同定された
探索キーをデータベースに格納されている探索キーと比
較することによって行われる。同じ探索キーをもつ部品
(もしあれば)を同定した後、引き続き他の類似部品を
捜しだすために、異なる修正された探索キー順序に基づ
くデータベースの探索を行うことができる。最初探索キ
ーにある、あまり重要または敏感でない項目または基準
(特徴関係または距離のような)は、より重要または敏
感な探索項目(部品にある基本的な特徴または形状のよ
うな)を修正する前に修正し、探索することができる。
さらに、これらの各項目は、項目の重要度に従って修正
し、部品にある一番目と二番目に複雑な特徴または形状
に関連する項目に、より高い重みまたは重要度を当てる
ことができる。たとえば、ひき続き最初に行う探索は、
三番目に複雑な特徴と一番目、二番目に複雑な特徴間の
定義された距離を修正した後に行うことができる。この
距離は、所定曲げ線数(たとえば1-3)だけ変更し又は
現在の距離に基づいた距離の所定範囲を定義することに
よって修正できる。しかる後、一番目と二番目に複雑な
特徴または形状間の距離を変更して、データベース探索
用の修正された探索キーの組をもう一つ備えることがで
きる。部品の特徴関係または距離の探索キーを修正した
後、同定された形状を、協調探索における付加的な修正
探索キーを導くために変えることができる。たとえば、
三番目に複雑な特徴または形状に関する探索キー項目
を、現在扱っているものの特徴または形状によって、関
連するがより複雑でない形状に変えることができる(た
とえばタブのある4折り曲げ箱を単純な4折り曲げ箱
に)。さらに、一番目と二番目に複雑な特徴の探索キー
を同じように変えることによって、さらに協調探索のた
めの修正探索キーを加えることができる。
【0187】探索キーに関係する距離と特徴/形状の、
協調探索中の修正は、いろいろな方法と技法によって実
行できる。上記のように、どのくらい距離を変えるか
は、距離の現在値に依存する。距離の大きさ(たとえば
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)にあり、そ
こに開示されている情報すべてを参照することによって
ここに取り入れられている。
【0188】協調探索の間に、他のプロセスやステップ
を実施するこができる。たとえば、部品の特徴に関連し
ていると同定された探索キーに基づいたデータベースの
探索に加えて、部品の製造情報に関連した探索基準に基
づいて探索することもできる。たとえば、付加的な探索
キーを利用して、一例として各部品に必要な機械構成を
比較することができる。機械構成情報は機械のタイプま
たは部品を製作するために必要な機械類、部品を製作す
るために用いる工具類や工具構成および/または機械類
のバックゲージング設定を含む。付加的探索キーは、機
械構成情報および/または他の製造情報に基づいて開発
することができ、本発明の協調探索をする際に、同定さ
れた探索キーとともに用いることができる。その結果、
製作される部品と同一または類似な部品は、部品の設計
と製造特徴両方に基づいて同定することができる。
【0189】最も類似した部品を選ぶために、選択部品
探索をステップS.114で実行し、協調探索の結果のより
詳しい比較と、探索された部品と同じまたは最も類似し
ている部品を所定数だけ選ぶ。選択部品探索は、協調探
索で同定された各部品に対する付加的な情報や特性の解
析を伴いうる。これは部品の寸法や部品にある孔や開口
の形のような、捜し出された部品の色々な特徴の解析を
含む。さらに各部品に要する機械構成のような、捜し出
された各部品の製造情報の比較も含みうる。上記のよう
に、機械構成情報は、部品の製作に要する機械の種類ま
たは機械類、部品の製作に用いる工具や工具構成、及び
/または機械類のバックゲージング設定を含む。選択部
品探索を行うために、各部品の曲げモデルや他の仕事情
報が、協調探索で同定された探索キーに基づいてデータ
ベースからアクセスされる。上記のように、各探索キー
の組に対応する仕事参照番号またはコードを提供するた
めに、ルックアップ表や付加的データフイルドを設ける
ことができる。データベースから部品情報を検索した
後、各部品の付加的情報(たとえば部品寸法、材料のタ
イプ、特別な成形、部品の孔または開口等)を、どの部
品が探索された部品に最も類似しているかを決めるため
に解析できる。このプロセスはオプションで、データベ
ースの部品で、当該部品に最も類似の部品を選び集約す
る付加的な選択プロセスの役割を果たす。この部品の付
加的情報または特性を解析し、照合することによって、
選択部品探索を、所定の数または組の最類似部品を同定
または選択するために行うことができる。たとえば、選
択部品探索で、照合探索キーの数と付加的部品特性の照
合に基づいて、五つの最類似部品を同定できる。選択部
品探索で選択される部品の数は五つに限らず、工場の必
要性とデータベースに実際に格納されている部品の数に
基づいて選ぶことができる。この数は、より有効で役立
つ探索結果をうるために選択的に修正でき、またユーザ
ーに探索の組を変えるために、この数を修正する機会を
与えることもできる。
【0190】選択部品探索を行った後、ステップS.116
で部品をランク付けする(特徴の類似性や突き合わせ探
索キーの数に従って)ために、類似性指標を計算するこ
とができる。類似性指標はステップS.116で計算され、
サーバーまたはステーションモジュールの出力として提
供され、これによってユーザーはどの仕事フアイルをデ
ータベースから検索し、画面に映し出すかを選択でき
る。類似性指標によって、選択された部品と探索部品の
特徴の類似性の程度に基づいて、選択部品のランク付け
(たとえば各部品の仕事または参照番号を付してランク
1から5)ができる。このためには各部品の特徴ベース行
列を探索部品のものと比較する。特徴ベース行列の比較
は、選択部品と探索部品の間の類似性をよりよく示す。
前のべたように、特徴ベース部品行列は各部品の探索キ
ーとともに格納できる。しかしながら、各以前の仕事の
特徴ベース部品行列を探索キーとともに永久格納するこ
とは、不必要に大きな記憶スペースを占有する(特にデ
ータベースに多数の部品が格納されている場合)。従っ
て各部品の探索キー・データのみを格納し、類似部品探
索を行うときに自動的に各選択部品の特徴ベース行列を
生成することしかできない。 従って、選択部品の曲げ
モデルと他の仕事情報を検索した後、前にステップS.10
2についてのべたように、特徴ベース行列は本発明の特
徴ベース抽出操作を通じて作成する。そのあとで、類似
部品探索時に一時的に格納した探索部品の特徴ベース行
列を、作成した選択部品の特徴ベース行列の各々と比較
できる。色々な方法とプロセスを、部品の特徴ベース行
列の比較と部品間の類似性の決定に利用できる。たとえ
ば、各選択部品の特徴ベース行列について、行列内の場
所を探索部品のものと比較できる。行列内の各場所は、
再帰的プログラム技法に基づいて比較できる。行列内の
情報は、各行列内の対応する基底面の場所を決め、行列
の指標を交換することによって比較できる。選択部品は
探索部品の副特徴に対応するか又はその形状をもつこと
もあり、又行列の指標が同一でないか、または同じ番号
付けがされていないこともあるので、含まれている情報
を比較するときに、部品行列内で比較できる面を捜しだ
して指標を振り替えなければならない。さらに探索部品
の中に一つ以上の副特徴が存在する場合、行列内の情報
を比較するとき、同じ次数の行列を提供するために、一
つまたは一つ以上の擬似面(行列の行と列で情報が無い
か空白のもの)を導入しなければならないことがある。
【0191】行列の情報を比較するときに、各選択部品
と探索部品の類似性の程度を決めるために、複数の異な
る順序づけ方式を用いることができる。たとえば、所定
ペナルティレベルまたは量を、行列内の整合しない各位
置に割り当てるペナルティベース順序づけ方式を用いる
ことができる。行列内のすべての情報を比較した後、各
選択部品の総ペナルティレベルを用いて類似性の程度を
決めることができる。最も低いペナルティレベルをもつ
選択部品が、探索部品に最も類似した部品と決定され
る。他の選択部品も、各部品に付せられた総ペナルティ
レベルに基づいて順序づけできる(たとえばペナルティ
レベルが低いほど類似指標が高い)。
【0192】本発明のさらなる見地に沿って、各非整合
位置のペナルティレベルは、その位置にある情報のタイ
プに基づいて割り当てることができる。ペナルティレベ
ルは整数量で非整合情報の重大性または重要性に応じて
変えることができる。たとえば、異なる、関係のない特
徴グループ(たとえば平行曲げ特徴対直列曲げ特徴)に
関する非整合位置に対しては、高いペナルティレベルま
たは量を割り当てることができる。これと対照的なの
は、異なるが類似の特徴グループ(たとえば同じ曲げ線
方向をもつ接触コーナー特徴対逆の曲げ線方向をもつ接
触コーナー特徴)である。ペナルティレベルまたは量
は、非整合位置に存在する情報のタイプと相違のタイプ
に従って事前に定義、類別される。
【0193】ステップS.116における類似性指標操作の
典型的なコードは付録Bに示されている。このコードはC
++言語で書かれており、上に記述した行列の比較と非整
合位置に対するペナルティレベルの割り当てに関する色
々なプロセスと操作を含んでいる。上に付記したよう
に、比較された各選択部品の結果としてえられた総ペナ
ルティレベルは、類似性指標を導き、表示するのに用い
ることができる。付録Bにあるコード・リステイングに
は、記されている典型プログラム・コードの理解を助け
るためのコメントも含まれている。
【0194】次に図11−25を参照しながら、曲げモ
デルの開発と、色々な2-D、3-D図面に基づいた部品の2-
D、3-Dモデルの開発を、本発明の見地に沿ってより詳し
く記述する。前に論じたように、各薄板金属部品に関す
る曲げモデルデータは、部品の2-D、3-D表現両方に関連
するデータを含んでいる。顧客の注文に基づいて提供ま
たは作成された原図のタイプに基づいて、色々な折りた
たみと展開アルゴリズムや他のプロセスを2-D及び3-Dモ
デルの開発に利用できる。特に図11-18は、部品の
元の2-D一方向図面(2次元単一図面)に基づいて、3-D
モデルを作成するに利用できる折りたたみアルゴリズム
の論理の流れの例を示す。図19は、3-D原図(厚さぬ
き)に基づいて2-Dモデルを作成するのに用いられる展
開アルゴリズムや他のプロセスの基本的な論理の流れの
例を示す。最後に図20-24と図25は、2-D三方向図
面(2次元三面図)と厚さありの3-D図面から、厚さぬ
きの3-Dモデルを作成するのに実施できる色々なプロセ
スや操作の論理の流れの例を示す。これらのプロセスや
操作でえられた3-Dモデル(厚さぬき)は、文中に明示
されているように、展開アルゴリズムまたはプロセスに
基づいて2-Dモデルを作成するのに利用できる。
【0195】図11は2-D一方向図面から折りたたみア
ルゴリズムを用いて3-Dモデルを作成するプロセスと操
作の論理の流れを示す。図11の流れ図で行われる機能
や操作は、たとえばサーバー・モジュール32にあるソフ
トウエアまたはプログラム論理によって実施できる。ス
テップS.120では、顧客の仕様に基づいて提供された、
あるいは新たに作成された2-D一方向平面図が、サーバ
ーモジュール32に入力または取り入れられる。2-D平面
図はCADソフトウエアを用いて作成し、サーバー・モジ
ュール32に入力するか、ベルムまたはキャドキーのよう
な、適当なCADまたはCAD/CAMシステムとインターフエイ
スすることによってサーバー・モジュールに取り入れる
ことができる。2-D図面は、たとえばDXFまたはIGESフア
イルとして格納され、曲げられる打ち抜き及び/または
切断材料を図示することができる。2-D図面はまた、薄
板金属部品の表面や面の曲げ線の位置や、孔または開口
を示すことができる。2-D図面を後で処理するための準
備として、ステップS.124における次の面検出プロセス
とステップS.126における曲げ線検出作業を行う前に、
ステップS.122でサーバー・モジュール32によって自動
クリーニングやクリーンアップ機能を実施することもで
きる。
【0196】本発明の自動トリミングとクリーンアップ
機能は、2-D平面図を、処理に対して準備するために備
えられている。2-D平面図は、薄板金属部品の展開状態
の2-D表示で、部品の幾何学を構成し表現する線及び曲
線の如き部品要素(エンティティ)を含むとともに、部
品に存在する開口または孔の位置を示す。通常このよう
な2-D平面図の構成要素(エンティティ)は、CADまたは
CAD/CAMシステムを使用して入力し、作成する。しか
し、2-D平面図を作成するとき、このような要素はしば
しば誤って連結または重ね合わされ、一つの要素が一つ
以上の面の境界を示すのに用いられることがある。さら
に、部品の境界を決めている外側線が、境界の隣接する
コーナーで分断されていて、部品と各面の外側の寸法の
検出を難しくしている。さらに、2-D平面図は、寸法情
報やテキストのような本質的でない情報を含みうる。こ
のような異常は、元の2-D図面を正確に解析し、部品の
面や曲げ線を均一に検出するのを難しくする。本発明の
自動トリミングとクリーンアップ操作を備えることによ
って、各面は連結された要素の一義的なセット(セッ
ト)で表現できる。その結果、2-D平面図は、引き続き
行われる処理と最終的に行われる3-Dモデル表現作成の
ための折りたたみのために、より簡単かつ効率よく解析
できる。
【0197】図12に示すように、元の2-D図面では面
間のトリミングがされておらず、図中の一つの線要素が
一つ以上の面の外側境界または複数の境界を定めている
ことがある。上記で論じたように、このような配置は各
々の面の検出を困難にする。本発明の自動トリミング機
能は、連結性情報を決定し、上記のような要素を交点で
断ち切るために、各部品要素(線、弧や曲げ線のよう
な)の終点と交点を解析するのに備えられている。この
ようなトリミング機能は、断ち切られた各要素の終点を
決められた交点に設定する機能ももつ。たとえば、図1
2に図示されている交点をトリミングすることによっ
て、各々が交点に終点を共有する三つの要素(二つの線
と一つの曲げ線)がえられる。このようなトリミング機
能を備えることによって、要素解析と連結に基づいて部
品の面をより容易に検出することができる。実施できる
面検出操作のさらに詳しい記述は、下記に図15(a)
-16(c)を参照しながら提供される。
【0198】色々なプロセスや操作を用いて2-D図面の
要素の交点を検出することができる。このようなプロセ
スは、2-D図面のフアイルのデータのフオーマットと配
列に基づいて作成できる。通例2-D平面図は幾何学デー
タ(色々な部品要素を定義する)と非幾何学データ(た
とえばテキスト等)を含む。幾何学データは、データの
各行またはシーケンスにあるキーワードによって非幾何
学データと区別できる。このようなキーワードは2-D図
面のデータ書式に従って設定される。2-D、3-D図面によ
く用いられる書式としてDXFとTGES書式がある。各要素
の幾何学データを解析することによって要素の終点や交
点が検出でき、適当であればトリミングができる。
【0199】上記で論じたように、線、曲げ線や他の要
素は終点及び/またはベクトルで定義できる。たとえば2
-D平面図では、各2-D線は2-D終点の組(たとえばX1,Y1
とX2,Y2)で特定することができ、曲げ線は曲げ線の2-D
空間位置とともに方向を示すベクトルで表すことができ
る。さらに2-D弧は2-D空間データ(たとえば中心X、中
心Y、半径、開始角度、終了角度)で特定することがで
きる。幾何学データはまた、色々なタイプの線要素(た
とえば弧、実線、破線、鎖線等)を区別する属性をも
つ。通常弧要素は薄板金属部品の孔や開口を、実線は部
品の境界や形状を示すのに用いられる。曲げ線は普通破
線で示され、部品の中心線は鎖線で示される。
【0200】元の2-D図面の幾何学データを解析し、各
要素の交点を決めることができる。データ割り当てやデ
ータ反復のような、色々なデータ解析手法を2-D図面の
各要素の幾何学データの解析に用いることができる。各
要素の終点及び/または他の2-D空間データに基づいて、
線や他の要素が交差するかどうかを決める簡単な幾何学
解析をすることができる。二つの要素が交差することが
決まれば、各要素を決定された交点で断ち切り、残った
要素の終点には交点で定められた共有点を割り当てるこ
とができる。
【0201】トリミングの方法は、交差することが検出
された要素のタイプに基づいて行われる。たとえば二つ
の実線が交差することが検出されると、図13(a)に
示すように、各線要素を断ち切ることによって、定めら
れた交点で接する四つの線要素がえられる。また線要素
と弧要素が、図13(b)に示すように交差することが
決まると、各要素を断ち切ることによって共通の終点を
もつ二つの線要素と二つの弧要素をうることができる。
しかしながら、要素の交差が検出されても、トリミング
を必要としないこともある。たとえば、如何なる要素で
も中心線(たとえば鎖線要素)と交差することが決定し
た場合、どの部品の中心線も部品の面または曲げ線を定
めたり区別したりすることはないので、トリミングの必
要はない。また、連結しない要素でも、開いている交点
または面積が、所定の許容度内であれば切断できる。た
とえば、潜在的に交差する線の終点が、実際に他の要素
と交差するときの交点と、事前に定義した許容度または
距離ε(たとえば0.0-0.01mmまたは0.0-0.001インチ)以内
であれば、要素は投影された点で連結交差しているもの
と扱ってよい;そしてたとえば図13(c)に示すよう
に、要素を断ち切ることができる。
【0202】自動トリミングをした後、えられたデータ
を、非連結要素を検出し修正するためにクリーンアップ
機能で処理することができる。しかしながら、本発明は
このような処理のみに限られていない;処理時間を短縮
するためにクリーンアップ機能を、各要素が解析されて
いる間に、自動トリミング機能と同時に行うことができ
る。クリーンアップの間に、2-D図面の幾何学データ
が、隣接する要素間の開いた交点または領域を検出する
ために解析される。自動トリミング機能と同様に、要素
間の開いた交点の領域を検出するために、各要素の終点
や他の2-D空間データも解析できる。このようなデータ
に簡単な幾何学的解析を加えることによって、要素の終
点が互いに事前に定義した許容度または距離(0.0-0.01
mmまたは0.0-0.001インチ)内にあるかどうかが決定でき
る。要素の終点がこのような開いた交点をもつことが決
定されると、要素を連結し、図14に示すように共通の
終点を割り当てることができる。
【0203】ここでもまた、クリーンアップ機能をどの
ように行うかは、開いた交点をもつことが検出された要
素のタイプによる。二つの実線が開いた交点をもつこと
が検出された場合、各終点に共通の終点を割り当てるこ
とができる(たとえば図14を見よ)。しかしある要素
が部品の中心線(たとえば鎖線要素)と開いた交点をも
つことが決まったときには、要素を連結したり共通の終
点を割り当るべきでは無く、中心線は無視しなければな
らない。またクリーンアップ機能は、2-D図面から非幾
何学データ(テキスト等)を消去するための付加的なプ
ロセスまたは操作を含みうる。前述べたように、非幾何
学データは、2-D図面データとともに用意されているキ
ーワードに基づいて幾何学データと区別できる。クリー
ンアップ機能にはまた、後で本発明の2-Dクリーンアッ
プ機能を参照しながらより詳しく説明するような、他の
クリーンアップ機能を組み込むことができる(たとえば
図21-23(b)を見よ)。
【0204】ステップS.122で自動トリミングとクリー
ンアップ機能を行った後、ステップS.124で処理された2
-D図面について面検出の手続きを行うことができる。本
発明の見地に沿って、面検出手順は要素(線や弧)とル
ープ解析に基づいた部品の面の検出と定義付けを含む。
図15(a)-16(d)に面検出手続きで行われる色
々なプロセスと操作の例を示す。ループ検出技法を本発
明で部品の面を検出し、決定するのに用いることができ
る。面検出手続きは、たとえばサーバー・モジュール32
にあるソフトウエアまたはプログラムされた論理によっ
て実施できる。
【0205】本発明の見地に沿って、部品の外側境界の
ループ検出解析に引き続く、部品の最小または内側ルー
プの解析を用いて、面の各々を検出できる。薄板金属部
品のユニークな幾何学のため、面と部品にある開口は、
相対的極大(たとえば外側)と極小(たとえば内側)ル
ープの順序の解析によって検出することができる。下記
に論じるように、ループ解析は部品の線と弧要素の連結
性にもとづいて行うことができる。ループ解析を部品の
外側から部品の中心に向かって行うことにより、部品の
開口や面を、循環順序(たとえば面材料、開口、面材
料、開口等)に従って定義されたループ間の境界に基づ
いて検出することができる。
【0206】図15(a)に示すような、図示の各面の
各種の線要素を含む2-D平面図が提供されたとしよう。
上記のように、ループと要素解析は部品の外側から始め
るように行う。部品の外側境界にあるどの要素を初期参
照点にとってもよい。限定されない例として、図15
(b)に示すように、最も左側の線要素を検出し、初期
参照点に用いる。最も左側の線要素は、2-D図面にある
各要素の幾何学データを比較し、どの要素が最も小さい
X座標の値をもつかを決めることによって検出できる。
最も左側の線要素を検出した後、点P1から部品の外観が
導かれ、図15(c)に示すように部品の外側境界を検
出される。点P1を決めるには、最も左側の線要素のいず
れの終点を用いてもよい。図15(c)に示す実施例で
は、上側の終点(つまり最も大きなY座標の値をもつ終
点)が点P1に用いられている。
【0207】部品の外観、またはまわりのループを導く
のには、通常のループ解析技法を使うことができる。た
とえば、リード線ベクトルを、部品の外観を追ってゆく
に従って、始点P1と連結している要素の終点から投影し
てゆくことができる。一つ一つの要素が検出され、通過
される毎に、要素が選ばれたことを示すフラグを設定す
ることができる(たとえば記憶内のフラグは、一度選ば
れたことを示すために1に設定する)。ループの経路は
始点P1からどちらの方向にも始められる。たとえば、リ
ード線ベクトルを点P1から反時計方向(たとえばリード
線ベクトルをY座標方向に投影する)に投影することが
できる。ループはループ経路が始点(つまり点P1)に戻
ったところで完結する。
【0208】上記のように、始点P1からリード線ベクト
ルを反時計方向に投影できる(たとえば最初のリード線
ベクトルをY座標方向から始めることによって)。引き
続きループの経路にある最初の要素を検出するために、
各未検出要素が点P1のまわりにリード線ベクトルとなす
角度を座標枠に基づいて測定し、解析してリード線ベク
トルと最も小さい角度をもつ要素を選ぶ。外側ループで
は、 各角度は要素線がリード線ベクトルとなす外側角
度を測る。点P1の回りの要素は、どの要素が点P1と終点
を共有するかによって決められる。各要素の未選択状況
は、各要素に付したフラグを解析することによって決定
できる。図15(c)に示すように、図示の2-D図面例
では二つの要素線(X座標方向のものとY座標方向のも
の)がP1のまわりにある。これらの要素の解析では、Y
座標方向の線要素が、リード線ベクトルとなす角度(0
度)が他の線要素がなす角度(270度)より小さいので
選ばれる。
【0209】続いてループ解析は選択された他の線要素
の終点に進み、選択されたことを示すためにフラグが設
定される。その終点で、別のリード線ベクトルが投影さ
れ、その点のまわりの非選択要素を比較することによっ
て、どの要素がリード線ベクトルと最小の角度をもつか
を決める。ここでもまた、角度はリード線の外側から測
り、座標フレームを用いて角度の大きさを決める。弧要
素に出会った場合は、リード線ベクトルの外側から弧の
接線までの角度を測らなければならない。また、次の終
点にある要素が一つのみであれば(部品のコーナー位置
のように)、比較の必要はなく、単にその要素を選択し
てループに含めればよい。
【0210】部品の外観に沿ってループ経路が進むにつ
れ、選択された各要素は、ループ内の要素の連結性を示
すためにリンクされたリストに含めることができる。経
路が始点P1に戻るとサイクルは完了し、外観と、部品の
外側境界を示す要素または線のリンクされたリストに基
づいてループを(L4)と定義できる。ループL4内の各線
または要素は、各終点で連結できる。ループL4の方向
を、外側ループであることを示すために、図15(d)
に示すように、反対方向(つまり時計方向)に変えるこ
とができ。ループの方向は、ループL4で線がリンクされ
る順序に基づいて定義することができる;従って方向
を、リンクされたリストの順序を逆にすることによって
変えることができる。
【0211】外側ループの完了後、外側ループ解析に用
いたのと類似のプロセスで部品の内側ループの解析を行
うことができる。ただ内側ループの解析では、各非選択
要素は各要素がリード線ベクトルの内側となす角度に基
づいて比較される。さらに、内側ループ解析では、ある
点のまわりの両方の要素がすでに選択されていると示さ
れた場合(たとえば面を境する二つの外側線要素を比較
するとき)でも、二つの要素が既に二度選択(2のフラ
ッグ設定)されてない限り、二つの要素を比較すること
ができる。少なくとも一度選択された要素(たとえば外
側要素)と選択されていない要素の場合は比較は行わ
ず、非選択要素をループの一部分として選択する。図1
6(a)-16(c)に、図15(a)に示す部品の面
を検出し、規定するのに行うことができる内側ループが
例示してある。
【0212】内側ループ解析は、どの外側要素の終点か
らでも、あるいは選択されていない要素を検出すること
によって開始することができる。たとえば点P1を、内側
ループ解析の始点に選び、リード線ベクトルを投影する
のに用いることができる;あるいは外側ループ解析の際
に選ばなかった内側の線要素の一つも解析の始点に用い
ることができる。外側ループ解析と同じように、リード
線ベクトルを反時計方向(たとえば一番目のリード線ベ
クトルをY座標方向から始める)に延ばしてゆくことが
できる。次いで点P1のまわりの各要素を比較し、どの要
素がリード線ベクトルと最小の角度をもつかを決める。
リード線ベクトルとなす角度を決めるのに、座標枠を用
いることができる。前記のように、内側ループ解析に際
には、要素の比較は各要素がリード線ベクトルの外側で
なく、内側となす角度をもとに行う。最初の要素が選ば
れ、ループのリンクされたリストに含めたら、そのフラ
グを1だけ増分し、つぎのリード線ベクトルを投影する
ことによって解析を進めることができる。このプロセス
はループが最初の始点に戻るまで続けられ、そこで第一
の内側ループが、対応する要素のリンクされたリストに
よって定義(たとえばL1)される。
【0213】さらに部品の内部に進んで、同じように内
側ループ解析を行うことができる。次の始点は、どの要
素が一度しか選ばれていないかを決めることによって選
ぶことができる。二度選ばれたフラグをもつ要素は、そ
の要素がすでに外側ループ(たとえばL4)と少なくとも
内側ループの一つ(たとえばL1)で選ばれた外側要素で
あることを示す。ここでもまた、各要素が選ばれるたび
に、それが内側ループのリンク・リストに含まれたこと
を示すために、フラグを1だけ増分する。
【0214】すべての内側ループが定められた後(たと
えば図16(c)の例ですべての要素が二度選ばれた
後)、えられたループを用いてループツリー(ループ
木)を作成することができる。図16(d)に、検出さ
れたループL1-L4に基づいて作成したループツリーの例
を示す。部品の外側ループ(L4)はツリーの根(ルー
ツ)と定義し、外側ループと共通の要素をもつ各内側ル
ープ(L1-L3)は、根の子どもと定義されている。共通
要素の存在は、各ループを規定する要素のリンクされた
リストの解析と比較によって検出できる。内側ループ内
に、さらに要素(たとえば孔または開口)が検出された
場合には、これらのループを、それが位置する内側ルー
プの子ども(つまりループツリーの根の孫)と定義する
ことができる。
【0215】ステップS.124で面検出手続きを行った
後、ステップS.126で曲げ線検出操作を行うことができ
る。たとえば図17に示すように、ステップS.124で部
品のループを検出し解析するときに、本発明の面検出論
理は、面情報を規定し、検出された面を曲げグラフ・デ
ータ構造にノードとして格納するのに、ループツリーを
利用することができる。部品の面は、ループツリーにお
ける外側と内側ループの順序から検出できる。上記のよ
うに、各ループは要素または線のリンクされたリストを
含む。これらの要素は、部品の各面の境界を定めるのに
用いられる。従ってステップS.126において曲げ線検出
操作を行い、部品の面と曲げ線の間の関係を決めること
ができる。ステップS.126の曲げ線検出操作は、ある二
つの隣接する面が共有する端または線要素を検出するこ
とによって、部品の色々な面間のすべての曲げ線を検出
する曲げ線検出論理を含むことができる。また一つ以上
の領域で接続している面(たとえば3-Dモデルに曲げ線
検出アルゴリズムを適用する場合―たとえば下記に論ず
る図19を見よ)については、いろいろな発見的方法
(ヒューリスティク)を適用して、部品の曲げ線の最小
数を検出し、選択することができる。検出された曲げ線
は、たとえば図18に示すように、最終的な曲げグラフ
・データ構造を作成するための、面の節(ノード)の間
の連結エージェントとして格納しておこことができる。
【0216】本発明の曲げ線検出操作は、たとえばサー
バー・モジュール32に備えたソフトウエアまたはプログ
ラムされた論理によって実施できる。曲げ線検出操作の
目的は、部品が最も少ない数の曲げ線で連結されるよう
に、部品の曲げ線を検出し、選択することにある。曲げ
線検出操作は、部品の2-Dと3-Dバージョン両方に備える
ことができる。原3-Dモデルについての曲げ線検出の適
用は、下記に図19を参照しながら論ずる。上記のよう
に、検出された曲げ線は、最終的な曲げグラフ・データ
構造を作成するための面の節の間の連結エージェントと
して格納できる。この最終的曲げグラフ・データ構造
は、2-Dデータ・モデルから折りたたんで部品の3-Dバー
ジョンを作成するのに利用できる。
【0217】図11のステップS.120で入力として提供
された2-D図面は、曲げ線情報を含まないか、曲げ線情
報が不明確で、一義的にまたは矛盾なく定義されていな
いことがある。その場合、曲げ線検出操作を、曲げ線を
検出し、部品の検出された面との関係を検出するために
行うことができる。このプロセスの間に、各面を定義す
る要素(エンティティ)のリンクされたリストを解析
し、各面が部品の他の面と共にもつ隣接する端または線
要素を決めることができる。これはある与えられた二つ
の面の間の可能なすべての接触を解析することによって
行うことができる。接触は、長さが0以上の(つまり線
要素が点ではなく、実際の線である)、共通する線要素
(またはお互いに事前に定めた距離許容度にある複数の
線要素)の存在によって決定できる。リンクされたリス
トにある幾何学データを解析することによって、部品の
すべての二つの面間のこのような接触の存在を決めるこ
とができる。
【0218】ある特定の面が、他の面と共通の端または
接触領域を一つしかもっていない場合、両方の面に共通
の要素は曲げ線であると定義することができる。一つ以
上の領域で共通接触を持つ複数の面(たとえば3-Dモデ
ル;ただし2-Dモデルでも起こりうる)については、色
々な発見的方法(ヒューリスティック)を用いて部品の
最小数の曲げ線を検出し、選択することができる。使用
する発見的方法は、複数の面が曲げ線で連結され、複数
の面にわたる連続ループが形成されないようになってい
なければならない(このような曲げ薄板金属部品の製作
は不可能なため)。
【0219】利用できる発見的方法の例として、共通す
る領域で最も長い接触領域をもつものを曲げ線に選ぶ方
法がある。ある面が、他の面と一つ以上の共通端をもっ
ている場合、この発見的方法によって最も長い長さをも
つ共通要素を面の曲げ線に選ぶことができる。この発見
的方法は、曲げ薄板金属部品を製作するときに、通常長
い接触領域を持っている方が良いという原則にもとづい
ている。使用できるもう一つの発見的方法は、異なる可
能な曲げ線の組み合わせ(3-Dモデルの曲げ線を決める
ときのような)に関係する。この発見的方法では、すべ
ての可能な共通領域が検出され、曲げ線の色々な組み合
わせが選択されると、曲げ線の組み合わせで最小の曲げ
線の数をもつ組み合わせが選ばれる。
【0220】曲げ線が検出されると、部品の面と決めら
れた曲げ線は確認のためにオペレータに表示される。オ
ペレータが部品の曲げ線の選択に満足しない場合には、
曲げ線検出操作に手動選択機能を備えることによって、
サーバー・モジュール32でオペレータが選択的に、薄板
金属部品に好ましい曲げ線を指示できるようにすること
ができる。オペレータは、マウスやキーボード等、適当
な入力手段を用いて、曲げ線を保持するか変更するかを
指示することができる。しかる後、オペレータによって
選ばれた修正された曲げ線を用いて、最終的な3-D(ま
たは2-D)部品を作成することができる。
【0221】本発明の曲げ線検出操作を実施するため
に、色々なプロセスや操作を備えることができる。曲げ
線検出操作を実施するためのコードの例を、付記の付録
Cに与える。例示のコードはC++プログラム言語で書かれ
ており、記述の論理フローの理解を助けるためのコメン
トが含まれている。例示コードは、2-Dまたは3-Dモデル
について行うことができる曲げ線検出操作の実施例で、
曲げ線の最適選択を決める発見的方法(上述のような)
を含む。
【0222】検出された面と曲げ線情報は、本発明の折
りたたみと展開プロセスに利用することができる。折り
たたみまたは展開の際、各曲げ線の回りに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-幅によっ
て、実際の薄板金属部品は薄板金属部品を折りたたむと
きに、差引高だけ引き伸ばされる傾向がある。
【0223】前記モデルでこの効果を補償するために、
差引高情報を利用して、折りたたみ操作で3-Dモデルを
作成するときに、曲げ線の各側で部品の面の寸法を差引
高の半分だけ引き延ばす。本発明の見地に沿って、この
差引高はユーザーによってサーバー・モジュール32に入
力(たとえばキーボード等によって)できる。あるい
は、部品の材料のタイプと厚さにもとづいた差引高を含
む材料表をオペレータに表示することができる。材料表
は、異なる曲げ角度やV―幅に対する色々な差引高を示
す。ユーザーは、サーバー・モジュール32で表示された
材料表から適切なV―幅と曲げ角度を選ぶ(たとえばマ
ウスまたはキーボードを用いて)ことによって、自動的
に差引高をセットすることができる。曲げ角度の内側半
径も、適切なV―幅を選ぶときに、材料表を介してユー
ザーによって自動的にセットできる。オペレータが入力
する(あるいはオペレータによる入力後に変換される)
差引高は、部品幾何学データを表すものと同じ長さの単
位(たとえばmm)である。折りたたみ操作時に、曲げ線
の各側の各面の長さ寸法を、注目している曲げ線の差引
高の半量だけ増やす。面の曲げ線に垂直な長さ寸法は、
曲げ線の各側にある面の境界を定める要素の終点を引き
伸ばすことによって増やすことができる。このような差
引高補償は、各折り曲げについてオペレータによって供
給された差引高にもとづいて、部品の他の曲げ線の各々
について行うことができる。
【0224】ステップS.132では、加工された2-D平面図
にもとづいて、3-Dモデルを作成するための、差引高補
償を含めた折りたたみ操作が行われる。前記のように、
折りたたみ手続きは、行列変換の使用と最終的曲げグラ
フ・データ構造で定義されたそれぞれの曲げ線を回転軸
に用いることを含む通常の幾何学的模型化法によって遂
行することができる。さらに、差引高の効果を補償する
ために、3-Dモデルを作成する折りたたみの際に、部品
の面を曲げ線の各側で差引高の半量だけ引き伸ばすこと
によって、薄板金属を実際に折り曲げるときの面の寸法
の変化をより正確に反映することができる。
【0225】たとえば、ステップS.132で折りたたみ操
作を行う時に、曲げパラメータ(たとえば曲げ角度、内
側半径)とともに、部品幾何学と形態データ(または曲
げグラフ構造)を利用することができる。2-D空間で表
わされた部品の各面、曲げ線、孔と成形についての変換
行列を計算できる。通常の行列変換を、2-D平面図に適
用することによって、3-D空間データをうることができ
る。変換は一般に回転に続く並進を含む。上記のよう
に、回転は曲げ角度の大きさに従って、各曲げ線軸の回
りに行われる。並進操作は、幾何学データを空間の中で
移したり、動かしたりすることによって行われる。この
ような並進操作は、曲げ半径、曲げ角度と各曲げの差引
高にもとづいて決められる。折りたたみの際に、差引高
補償は前述べたように曲げ線の各側で、面の寸法を差引
高の半量だけ伸ばすか増やすことによって行われる。こ
のような差引高補償は、曲げ機で曲げられる2-D薄板金
属部品の寸法を、より正確に反映する部品の3-D表現を
与える。
【0226】幾何学的モデル化と変換のさらに進んだ情
報は、たとえば、その明細を全般的に参照することによ
って本文書に明白に取り入れられているモルテンソン、
マイケル M著、幾何学的モデル化、ジョン・ワイリー&
サンズ、ニューヨーク(1988年)及びフオリーら著、ジ
ェイムス システム・プログラミング・シリーズ:会話
形コンピュータ・グラフイックスの基礎、アデイソン・
ウエスリー出版、レデイング、マセチューセッツ(1983
年)を見られたい。モルテンソンの8章には、並進と回
転を含む幾何学的変換が論じられている(たとえば345-
354頁参照)。さらにフオリーらは7章、245-265頁で、2-
Dと3-D変換の行列表示を含む、幾何学的変換の情報を与
えている。モデル化と幾何学的変換についての付加的情
報は、その明細を全般的に参照することによって本文書
に明白に取り入れられている、マンテイラ、マルッテイ
著、ソリッドモデル化入門、コンピュータ・サイエンス
出版社、ロックビル、メリーランド(1988年)にも与え
られている。座標変換に関する情報は、マンテイラの36
5-367頁にある。
【0227】次に図19を参照しながら、本発明の別の
見地に沿って、元の厚さぬきの3-D平面図にもとづいて2
-Dモデルを作成するプロセスと操作について説明する。
図11を参照しながら前に説明した折りたたみプロセス
と同様に、3-D図面を展開し、2-Dモデルを作成する色々
なプロセスや操作は、サーバー・モジュール32にあるソ
フトウエアや/またはプログラム化論理を用いて実施で
きる。図19に示されているように、顧客の仕様にもと
づいて提供され作成された元の3-D図面は、ステップS.1
40でサーバー・モジュール32に入力されるか取り入れら
れる。3-D図面はDXFまたはIGESフアイルとして格納さ
れ、サーバー・モジュール32からCADまたはCAD/CAMシス
テムとインターフエイスするか、利用するかして入力で
きる。3-D図面を入力後、ステップS.142でサーバー・モ
ジュール32によって、引き続き行われる面検出や他のプ
ロセスのための図面の準備のために、自動トリミングと
クリーンアップ操作が行われる。
【0228】図12-14に関連して論じたように、自
動トリミングとクリーンアップ機能は、部品の色々な面
が適正に検出定義されされるように、構成要素や表面を
切り離したり、連結したりする。
【0229】図11と12、13に関連した上記の自動
トリミングとクリーンアップ操作は、図19のステップ
S.140で入力した3-D図面の幾何学データに対しても、同
じように適用できる。データを2-D空間で解析する(2-D
平面図の場合のように)代わりに、3-D図面に図示され
ている各構成要素(たとえば線、弧等)は、図中の3-D
座標と空間情報にもとづいて解析することができる。交
点と開放交差領域は、各構成要素(エンティティ)を個
別的に解析し、他の構成要素の一つ一つと比較すること
によって解析できる。ここでもまた、構成要素の終点や
他の属性の基本的な幾何学的解析を用いて、許容度内で
交点と開放交差領域を決めることができる。
【0230】前記3次元図面に対しての自動トリミング
及びクリーンアップ機能を実行した後、ステップS14
4で、前記板金パーツの面の各々を検出し定義するため
に面検出操作が行なわれる。前記3次元図面についての
面検出は2次元空間における各面を分析し且つ検出し且
つ上記と同様にしてループツリーを生成することにより
行なわれる。面検出は任意の所定のエンティティで開始
することにより実行される。例えば、一番左側のエンテ
ィティ(即ち最小のx座標を有するエンティティ)が最
初のエンティティとして使用される。その後、1つの面
は前記最初の線分エンティティ及び他の連結するまたは
隣接する線エンティティ(即ち前記最初のエンティティ
と共通の端点を有する任意のエンティティ)を取出すこ
とにより定義される。面検出操作は次に、図15(a)
−16(d)に関連して上記に説明したようにループ及
びエンティティ解析を用いて行なわれる。各エンティテ
ィは前記定義された2次元平面内で検出されるため、種
々の外側及び内側ループが定義され、且つ前記エンティ
ティがマークされ(即ち前記選択されたエンティティの
フラグを設定し或いは増加することにより)、それら
が、前記面における複数のループの1つを定義する連結
されたリストに選択され且つ含まれたことを示す。
【0231】引き続くループ解析は、次に前記3次元図
面を構成する他の2次元平面において行なわれる。前記
他のエンティティのループ解析を行なうために、前記3
次元図面内でのマークされてない或いは選択されてない
エンティティを検索することにより追加の平面が定義さ
れる。そのような平面は、2つの選択されてないエンテ
ィティの間或いは選択されてないエンティティと以前に
選択されたエンティティとの間に定義される。追加の2
次元平面の各々において、更なるループ解析が行なわれ
前記内側及び外側ループを検出する。再び連結されたエ
ンティティの連結リストが保持され、前記複数のループ
経路の各々が定義されるにつれて、前記選択されたエン
ティティがマークされる(即ち前記選択されたエンティ
ティに付随するフラグを増加することにより)。
【0232】全てのエンティティが検出された後、すで
に解析された2次元平面の各々についてのループツリー
を生成するために、結果の複数のループが使用される。
すでに述べたように、ループツリーは、板金パーツにお
ける複数の面及び開口部及び穴を定義するために提供さ
れる。3次元の図面については、ループツリーは、前記
板金パーツの各面について生成される。各面内で検出さ
れた複数のループは、各ループツリーを生成するために
グループ化され分析される。各ツリーのルーツ(根)は
前記平面において検出された外側ループとして定義され
る。前記外側ループと共通のエンティティを有する前記
平面の各内側ループは前記ツールの子供として定義され
る。共通エンティティの存在は、各ループを定義する連
結されたエンティティのリストの分析及び比較に基づい
て検出される。追加のエンティティ(即ち穴或いは開口
部)が前記平面の内側ループにおいて検出される時、こ
れらのループはそれらがその内部に存在する内側ループ
の子供(即ち前記ループツリーのルーツの孫)として定
義される。生成された複数のループツリーは次に、前記
3次元図面の全ての面を検出するために用いられる。検
出された面は次に曲げグラフデータ構造におけるノード
(節)として格納される。
【0233】前記結果としての曲げグラフ構造はステッ
プS146における曲げ線検出操作の実行の後、連結す
る曲げ線連結エージェントにより補足される。曲げ線検
出操作及び最終曲げグラフ構造またはパーツ・トポロジ
ーの生成は図17及び18を参照して上記したと同様の
やり方で実行される。
【0234】上記したように、前記曲げ線検出操作を実
行するための代表的なコードがここに添付された付録C
に提供される。このサンプルコードは、2次元或いは3
次元モデルに対してなされる曲げ線検出操作のための代
表的実行例であり、曲げ線の最適選択を決定するための
ヒューリスティック(例えば上記したような)を含む。
前記曲げ線検出操作は、検出された曲げ線に満足しない
時、サーバモジュール32におけるオペレータが前記板
金パーツのための好ましい曲げ線を選択的に指定するこ
とを許すマニュアル選択特性を含む。前記オペレータ
は、マウスあるいはキーボード等のごとき適宜の入力手
段により曲げ線を維持し或いは変更することを指示す
る。前記オペレータにより選択され改定された曲げ線は
最終的2次元パーツを生成するために用いられる。
【0235】最終的曲げグラフ構造の複数の曲げ線を中
心とする展開工程を実行する前に、ユーザは、ステップ
S148でV幅、材料タイプ及びまたは縮小量について
促される。上記したように、板金は折り曲げられる時伸
びる傾向を有するため、3次元パーツの寸法は前記2次
元平面パーツのそれより少し大きい。従って、板金パー
ツの展開の過程で、パーツの寸法は、選択された材料タ
イプ及びV幅に基づく縮小量だけ縮み或いは減少され
る。従ってこの発明の1つの側面によれば、3次元モデ
ルを展開する際、前記2次元モデル及びその表面の各々
の寸法をより正確に生成するために縮小操作が行なわれ
る。上記したように、前記縮小量は、前記ユーザにより
直接入力され或いは所望のV幅及び曲げ角度を選択する
ことによりユーザが自動的に前記縮小量を設定すること
ができるように、材料テーブルが表示される。
【0236】前記オペレータにより入力される前記縮小
量は前記パーツ幾何学データにより表現されるそれと同
じ長さの単位(例えばミリメートル)である(或いはオ
ペレータによる入力の後その単位に変換される)。展開
操作の間に、前記曲げ線の両側の面の各々の寸法長さは
前記所定の曲げ線について入力された縮小量の半分だけ
減少される。前記曲げ線に直交する前記面の寸法長さは
前記曲げ線の両側に位置する前記面の境界を定義するエ
ンティティの終点を減少することにより減少される。前
記縮小補償は、各曲げについて前記オペレータにより提
供される前記縮小量に基づいて、前記パーツの他の曲げ
線のそれぞれにおいて行なわれる。
【0237】前記全ての必要なデータの入力の後、ステ
ップS150で、前記2次元モデルを生成するために展
開プロセスが行なわれる。前記3次元曲げモデルを展開
するために通常の方法が用いられ、それは前記複数の曲
げ線の各々を回転軸として用いるマトリックス変換の使
用を含む。この展開プロセスの間に各曲げ角度が測定さ
れ、前記平面曲げモデルを生成するために前記曲げ角度
量だけ前記パーツは展開される。更に、前記入力された
縮小量に基づいて、前記板金材料の物理的性質及び前記
3次元及び2次元モデルの間の差をより正確にシミュレ
ートするために、前記曲げ線の両側で前記縮小量の半分
だけの前記面の寸法の縮小或いは減少が行なわれる。
【0238】ステップS150で前記展開工程を実行す
る時、前記パーツの寸法及びトポロジーデータ(または
曲げグラフ構造)が前記曲げパラメータ(例えば曲げ角
度、内側半径等)と共に用いられる。前記3次元空間に
おいて表現された前記パーツにおける各面及び曲げ線及
び穴及び成形部についての変換マトリックスが計算され
る。通常のマトリックス変換が前記2次元空間データを
得るために前記3次元データに対して適用される。前記
変換は一般的に回転を含み、その後に並進がくる。上記
したように、回転は、曲げ角度量に応じて各曲げ線の周
りに行なわれる。展開のために、2つの面の間に180
°が存在するまで(即ち面が平面になるまで)回転は逆
方向に行なわれる。並進は空間内で前記幾何学的データ
をシフトし移動するために行なわれる。そのような並進
は、各曲げについての前記曲げ半径及び曲げ角度及び縮
小量に基づいて決定される。展開の間、縮小補償は上記
したように、曲げ線の両側で前記縮小量の半分だけ前記
複数の面の寸法を縮め或いは減少せしめるために行なわ
れる。そのような縮小補償はそれが曲げ工程の間に折り
曲げられる前の前記板金パーツの寸法をより正確に反映
する前記パーツの2次元表示を提供する。
【0239】再び幾何学的モデル化及び変換についての
情報はモルテンソン、フォリー等及びマンティラに見出
される。上記したように、モルテンソンの8章は変換及
び回転(例えば345〜354頁を見よ)を含む幾何学
的変換の議論を提供する。更にフォリー等は、7章の2
45〜265頁で2次元及び3次元変換のマトリックス
表示を含む幾何学的変換についての情報を提供する。更
に座標変換についての情報はマンティラの365頁〜3
67頁に見出される。
【0240】図4を参照して上記したように、前記顧客
の注文に基づいて、2次元3面図或いは厚さを有しない
3次元ワイヤフレーム図が最初に提供され或いは生成さ
れる場合、厚さを有しない3次元モデルを生成するため
に更なる工程が必要とされる。そしてその後、前記厚さ
を有しない生成された3次元モデルは展開プロセス或い
はアルゴリズムを適用することにより2次元モデルを生
成するために用いられる。図20−24は、最初の2次
元3面図に基づいて3次元モデルを生成するために適用
される種々のプロセス或いは操作を図示する。更に図2
5は、この発明の他の側面に応じて、厚さを有する最初
の3次元ワイヤフレーム図から厚さを有しない3次元モ
デルを生成するために適用される追加のプロセス或いは
操作を図示する。再び、図20−25において図示され
る種々のプロセス及び操作は、例えば前記サーバモジュ
ール32に存在するソフトウエア及びまたはプログラム
論理により実行される。
【0241】図20を参照するに、この発明の教示に応
じて、最初の2次元3面図に基づいて3次元モデル(厚
さを有しない)を生成するために行なわれる操作或いは
プロセスの論理フローの記載が提供される。最初、ステ
ップS160で2次元3面図がサーバモジュール32へ
入力され或いは搬入される。前記最初の2次元3面図
は、前記パーツの種々の図(例えば正面図及び平面図及
び右側面図、例えば図22(a)及び22(b)を見
よ)を含み、前記サーバモジュール32へダウンロード
され或いは搬入されるDXF或いはIGESファイルの
ごときCAD図面である。しかる後、ステップS162
で、前記3次元モデルへの引き続く操作のための図面を
作成するために、サーバモジュール32により2次元ク
リーンアップ操作が行なわれる。この2次元クリーンア
ップ操作は、前記パーツの実際の幾何学形状を表現しな
い余分な及び非幾何学的な情報、それはテキスト及び中
心線及び寸法線を含む、を消去するために行なわれる。
前記2次元クリーンアップ操作はまた全ての外側線分
を、例えばそれらの接続端部で接続し、或いは任意の交
差するライン或いはエンティティを分断し或いはトリミ
ングするために行なわれる。図21は、前記サーバモジ
ュール32により前記クリーンアップ操作が行なわれる
際実行される種々のプロセスの論理フローの例を図示す
る。
【0242】図21に示されるように、最初に2次元図
面が前記サーバモジュール32により、ステップS18
0でデータファイルから読み取られ或いはロードされ
る。しかる後ステップS182でサーバモジュールは、
2次元図面において各々のエンティティ或いは幾何学デ
ータを分析し次の工程のための図面を作成するために種
々のエンティティを分割する。ステップS182におい
て行なわれる前記分割或いはトリミング機能は、この発
明の前記自動トリミング及びクリーンアップ機能に関連
して上記に記載したと同様な方法で実行される。従って
ステップS182で前記2次元3面図における全ての幾
何学的データは、エンティティの交差点及び所定の誤差
範囲内にある空白(開放)交差部を検出するために分析
される。任意の交差線は分断され、結果のエンティティ
は交差点により定義される共通の終点で出会う。更に所
定の誤差の範囲内にある(例えば0.0−0.01mm
或いは0.0−0.001インチ)空白交差領域を有す
るエンティティについてはそれらのエンティティは、例
えば図12―14に関連して上で記載されたと同様の方
法で結合される。
【0243】ステップS184で前記2次元図面シート
の周辺が検索され任意の外部の線分またはデータ(例え
ば境界線分及び座標格子及び数字等)が消去される。図
22(a)に示されるように2次元3面図は、しばしば
図面シート上に提供される。前記図面シートは前記板金
パーツの種々の図面を生成するために必要でない余分な
及び非幾何学的な情報を含む。従ってステップS184
で、本発明の2次元クリーンアッププロセスを利用し
て、前記3次元モデルを展開するにあたってこのタイプ
の情報が検出され前記2次元図面から消去される。
【0244】前記2次元図面データはそこに含まれるデ
ータのタイプ(例えば幾何学的或いは非幾何学的/テキ
スト)を指示するためのキーワード或いはタイプフィー
ルドを含む。従ってこれらのキーワードあるいはタイプ
フィールド(それらは図面ファイルのデータフォーマッ
トに基づいて提供される)はテキスト或いは他の非幾何
学的データのごとき種々の余分の情報を削除するために
用いられる。しかし全ての不必要な図面シートデータを
正しく削除するためには更なる操作が通常必要である。
しばしば、前記境界線或いは他の外側情報はエンティテ
ィー(例えば線分等)として保存され、それらは前記デ
ータキーワード或いはタイプフィールドに基づいて容易
に識別することができない。従ってこの発明の1つの側
面によれば、前記2次元図面のデータを分析する際に連
結性グラフ構造が生成される。この連結性グラフ構造は
各エンティティーについて複数の付随的頂点のリスト及
び連結されたエンティティーのリストを示す。各頂点に
ついては、隣接する複数の頂点のリスト及びそれが付随
するところのエンティティーのリストが提供される。こ
のグラフ構造により、(それはステップS182の分断
及びトリミング機能を実行する際に生成されるが)、ど
のエンティティーがくっつき合う終点により結合される
かが決定される。結果として、境界線及び情報ボックス
及び他の非幾何学的データのような余分なデータは削除
される。これは、このデータは典型的に連結されたエン
ティティーで構成されることがなくまたそれを含まない
からである。
【0245】上記したように、2次元3面図は寸法線及
び矢印線及び中心線及びテキストのような余分の情報を
含み、それらは前記パーツの実際の幾何学形状を表現し
ない。これらのエンティティーはステップS186で検
出され、次の工程のための2次元図面を作成するために
前記2次元データファイルから削除される。これらの余
分のエンティティーの検出はサーバモジュール32によ
り自動的に行なわれる(例えば前記パーツの実際の幾何
学形状に関連しない2次元データファイル中の項目を検
出することにより)。例えば、前記連結性データグラフ
構造を用いて、両端が開放されたエンティティー(例え
ばテキストにアンダーラインをするため或いは寸法或い
はパーツの中心線を示すために用いられる複数の線)が
検出され消去される。矢印のごとき他のエンティティー
もまた、浮動する終点或いはそのようなエンティティー
の他の特徴の存在に基づいて検出される。全ての不必要
なデータを効果的に削除するために、サーバモジュール
32は前記2次元図面中のいずれの項目が消去されるべ
きかを(例えばマウスまたはキーボードにより)オペレ
ータをして指示することができるようにするためのマニ
ュアル編集機能を提供する。オペレータのこの援助或い
は確認により、追加の余分の情報が図面から除去され
る。
【0246】ステップS186の後、前記2次元図面の
種々の図が、ステップS188でグループ化され且つそ
れぞれ定義される。この発明の1つの側面によれば、サ
ーバモジュール32は、図22(b)及び23(a)に
示されるような平面図(上面図)及び正面図、右側面の
配置のごとき、予め定められた或いは標準的な図と向き
をサポートする。平面図及び正面或いは背面図及び右或
いは左図のような他の図及びレイアウトもまたサポート
され得る。更に以下に記載されるように、サーバモジュ
ール32はまた前記2次元図面の図を前記パーツの3次
元表現へ加工するために、回転された図(例えば図23
(a)を見よ)もサポートする。いずれにしても、パー
ツの3次元モデルが構成されるためには、厚さ表現を有
するパーツの少なくとも2つ(そして好ましくは3つ)
の異なる図が提供される必要がある。連結性グラフ構造
において前記エンティティーの連結性及びグループ化を
解析することにより、サーバモジュール32は、複数の
図の各々の相対的位置及び/又は座標位置に基づいて前
記複数の図を分類し且つ定義する。
【0247】限定しない事例として、サーバモジュール
32による前記図の定義は、予め定義された或いは通常
の配置或いは前記データファイルにおける図の解析をす
るためのレイアウトにより、及び/又は前記複数の図の
向きの検出及び前記図面の各々の図のそれぞれにおける
前記パーツの種々の寸法の重ね合わせに基づいて実行さ
れる。図23(b)において示されるそれのごとき予め
定義された或いは標準的フォームは、潜在的な図のタイ
プに応じて前記図の各々を決定し定義するために用いら
れる。種々の終点及び各グループを定義する複数のエン
ティティーの間の関係の幾何学的比較は、前記ステップ
S188を実行するために行なわれる。サーバモジュー
ル32の図検出特性(図検出機能)は、複数の潜在的図
面タイプ(例えば平面図、正面図、背面図、左図、右
図)の1つに応じて前記図面の各々にラベルを付ける。
前記複数の図の各々の検出は、予め定義された或いは標
準的図の配置或いは形状及び存在する図の各々の間の検
出された関係に基づく。種々の工程或いは操作が、ステ
ップS188で、前記2次元3面図における複数の図を
分類し且つ定義するために使用される。例えば前記加工
された2次元3面図にアクセスした後、前記サーバモジ
ュール32はまずこの図面データにおけるパーツの平面
図を特定する。前記平面図は、予め定義された或いは標
準的な形状または図配置(例えば図23(b)における
それのような)に基づいて検出される。仮に3つの異な
る図が水平方向或いは垂直方向において検出される場合
には、中央の図が平面図であると定義される。更に仮に
3つの別個の図が検出されず且つ垂直方向においてただ
2つの別個の図が検出される場合には、上側の図が平面
図であると定義される。再び前記連結性グラフ構造にお
ける前記エンティティーの連結性及びグループ化が前記
複数の図の各々を検出するために使用される。前記予め
定義された或いは標準的形態を表現する、格納されたル
ックアップテーブル或いはマトリックスが前記2次元図
面の各図を比較し且つ複数の図の各々を検出するために
用いられる。
【0248】前記2次元3面図データから平面図を検出
した後、前記パーツの他の図は前記検出された平面図に
対する前記複数の図の各々の相対的位置に基づいて検出
される。例えば、図23(b)の標準的レイアウトに基
づいて、例えば図グループが前記平面図の上に位置して
いる場合には、その図は背面図であると定義される。し
かしもし図グループが前記平面図の下に位置している場
合には、その図は前記パーツの正面図であると定義され
る。更に右図及び左図は、前記平面図のそれぞれ対応す
る右側及び左側におけるそれらの相対的位置に基づいて
検出される。しかる後、前記標準的形態(例えば図23
(b))に合致しない任意の残りの図は前記検出された
図(例えば検出された背面図或いは正面図)に対するそ
れらの相対的位置に基づいて検出される。例えば図23
(a)に示されるレイアウトBについて、前記右図は前
記平面図に対して回転された位置に設けてある。しかし
ながらレイアウトBにおける右図は前記検出された正面
図に対するその関係に基づいて検出される。即ち検出さ
れた背面図或いは正面図の右側或いは左側に存在する検
出されていない図はそれぞれ前記パーツの右図或いは左
図として定義される。
【0249】種々の予め定義された或いは標準的な図の
レイアウトが前記2次元3面図図面において複数の図を
検出し且つ定義するために用いられる。標準的な形態
(例えば図23(b)または図23(a)におけるそ
れ)は、製造設備において広く行き渡っており或いは選
択され/要求される図レイアウトに基づいて、及び/又
はサポートされている図タイプの基づいて選択される。
仮にいずれの図も検出されない場合には、サーバモジュ
ールにより警告信号が提供され、オペレータは、好まし
い図面レイアウトに応じて前記2次元3面図データを変
形したり、他の適当な動作を行なう。前記2次元図面に
おける複数の図を検出するための予め定められた或いは
標準的形態の提供に加えて、予め定められた標準的形態
(例えば図23(a)のレイアウトAのように)は検出
された図を加工し前記パーツの3次元モデルを生成する
ために設けられる。従って更なる加工が行なわれる前に
前記標準的形態に基づいて検出された図を正しく分類す
るために、回転された図の特徴が提供される。
【0250】上記したように、前記2次元クリーンアッ
プ操作は図面において複数の図を検出するための予め定
められた、或いは標準的形態に合致しない回転された複
数の図をサポートし且つ検出する。回転された図のオプ
ションでは、検出された標準的でない複数の図は、パー
ツの3次元モデルを加工し且つ生成するために、前記複
数の図の各々が前記予め定められた或いは標準的な図の
形態に合致するように、回転され或いは並行移動され
る。前記パーツの複数の図を検出するために図23
(b)に図示されるそれのような標準的形態を仮定し
て、図23(a)におけるレイアウトBにおける複数の
図の各々は、上記したように、前記平面図及び他の検出
された図に対する当該複数の図の相対的な位置に基づい
て検出される。例えば仮に図23(a)のレイアウトA
が、平面図及び正面図及び右図を有する2次元図面にお
ける種々の図を加工するための予め定められた或いは標
準的図レイアウトとして使用される場合、ステップS1
88でレイアウトBにおける右図は90度回転されレイ
アウトAと同様な、前記パーツの変形された図レイアウ
トを提供する。前記パーツの右図が前記パーツの平面図
の右側に位置するように前記レイアウトBにおいて右図
を90度回転することにより、図面中の前記複数の図は
レイアウトAで表現される標準的な形態に応じて加工さ
れる。格納されたルックアップテーブル或いは予め定め
られた或いは標準的な形態を表現するマトリックスが、
前記2次元図面の複数の図を比較し且つどの図が回転或
いは並進運動を必要とするかを決定するために用いられ
る。
【0251】前記2次元図面における複数の図から前記
パーツの正確な3次元モデルが生成されることを保証す
るために、前記複数の図の各々においてそれぞれの寸法
が相互に矛盾がないか或いは一致しているかチェックさ
れる。図21において更に示されるようにステップS1
90で前記データファイルにおける前記複数の図の境界
が、それぞれの図の全ての寸法が相互に同じ寸法である
かを確認するために検出される。仮に複数の図が所定の
誤差の範囲内で(例えば0.0−0.01インチ)一致
しないことが判断されるとステップS190で、全ての
複数の図が同じスケールになるように任意の特定の図の
寸法を変更するために適宜の修正が行なわれる。図面の
寸法が相互に一致せず現在存在する2次元図面データに
対して必要な修正が行なわれるようにユーザに警告する
ためにサーバモジュール32に警報要素が設けられる。
【0252】前記パーツの各々の図における寸法の一貫
性を検出し且つ確認するために種々の操作或いは工程が
使用される。例えば、前記複数の図の各々の対応する寸
法が、それらが相互に所定の誤差の範囲内にあるかどう
かを決定するために比較される。そのような解析は、前
記パーツの各図の境界線を定義する線分エンティティー
を比較することを含む。図23(b)における標準的な
形態を仮定して以下のようであれば平面図は右図または
左図と一致すると検出される。即ちそれぞれの図につい
て、最大Y座標位置と最小Y座標位置が所定の誤差範囲
(例えば0.0−0.01インチ)内にある。更に前記
平面図は、以下の場合には正面図または背面図と一致す
ると検出される。即ち各図について、最大X座標位置と
最小X座標位置とが所定の誤差範囲(例えば0.0−
0.01インチ)内にある。更に左図または右図は、最
大Y座標位置と最小Y座標位置との間の差に比較して最
大X座標位置と最小X座標位置との差が所定の誤差範囲
(例えば0.0−0.01インチ)内にあれば正面図ま
たは背面図と一致すると決定される。再び前記図の寸法
或いは関連する面の寸法が一致しないとき前記2次元図
面データに対して必要な修正が加えられるようにユーザ
に警告するように、サーバモジュール32に警告要素或
いはモジュールが設けられる。
【0253】最後にステップS192で、本発明の面検
出方法の教示に基づいて、前記パーツの内側ループ及び
穴及び形状が検出される。各図の複数の面の内側に設け
られている種々の穴或いは形状は、前記パーツの種々の
線及び境界を通ってパーツの外側から中央へ向かってル
ープを形成していくことにより検出される。ループ及び
エンティティーの分析は、前記2次元図面における前記
パーツの各図に対してなされる。前記パーツの外側から
作用的に中央へ向かって内側へ各々の図を分析すること
により、検出されたループは前記パーツの物質と開口部
の境界及び領域を、周期的順番(即ち物質、開口部、物
質等)に基づいて決定する。図16(d)におけるそれ
のごときループツリーが複数の面の位置及び各々の面の
内部の任意の穴の位置を決定するために各図面について
生成される。浮遊する円弧或いは線分のごとき前記パー
ツの面の内部で連結されないエンティティーは、ステッ
プS192の中で検出され消去される。
【0254】本発明の前記2次元クリーンアップ操作を
行なうための代表的なコードは付録Dに提供される。こ
のコードはC++プログラム言語で記載されており、そ
こに使用される論理及びアルゴリズムの解析を円滑にす
るためのコメントを含む。そのコードは、図21−22
(b)を参照して上で議論したそれらのごとき、2次元
クリーンアップモードの種々の工程及び操作を含む。
【0255】図20を再び参照するに、2次元クリーン
アップ操作が行なわれた後論理フローはステップS16
4へ連続しそこで前記2次元図面が材料の厚さを表現し
または含むか否か(即ち前記2次元図面が厚さを有する
か否か)が決定される。もし前記2次元図面が厚さの量
を含むと判断される場合には、ステップS166で3次
元モデルへの引き続く操作のための2次元図面を作成す
るためにサーバモジュール32により厚さ消去手続きが
行なわれる。前記2次元図面における厚さの存在の判断
は図面のデータに基づいてサーバモジュール32により
自動的に行なわれ、或いはオペレータからの援助或いは
応答を介して前記サーバモジュールにより行なわれる
(オペレータは厚さ除去が必要であるか或いは好ましい
かを指示するように促される)。前記パーツの厚さは全
ての板金パーツの独特の対称性により消去される。前記
パーツの厚さを消去することにより、厚さを有しない、
結果としての板金パーツは板金オペレータ或いは設計者
により、より容易に分析される。更にこの出願の発明者
は、前記2次元3面図の厚さを除去することにより、2
次元図面を変換し3次元モデルを生成するに必要な時間
が著しく短縮されることを見出した。
【0256】殆どの2次元3面図は材料厚さ量を含むた
め、オペレータはしばしば、2次元図面から3次元モデ
ルを作成するためにいずれの曲げ線が選択されなければ
ならないかで混乱する。結果として、2次元3面図が3
次元モデルへ変換されるように適切な曲げ線を選択する
際に相当の時間が無駄になる。厚さを有する2次元3面
図の例が図24に示されている。この発明の1つの側面
によれば、材質厚さを持つことなく表現され且つ処理さ
れるが、当該材質厚さ量及び前記パーツの内側及び外側
寸法を曲げモデルデータ中に保有する簡単化された2次
元3面図モデルを表示するように、厚さ除去手続きが設
けられている。図24(b)は前記厚さ除去工程を行な
った後、前記サーバモジュール32において前記オペレ
ータに対して観察され且つ表示される簡単化された2次
元3面図を図示する。
【0257】前記厚さ除去手続きが実行される時、ユー
ザは、2次元3面図表示における材質厚さを特定するよ
うに促されてもよく、また前記表示内においていずれの
寸法(即ち外側寸法或いは内側寸法)が保持されるべき
であるかを特定するように促されても良い。オペレータ
は、例えばマウスを用いて複数の図の中の1つにおいて
保持される厚さ及び表面を指示する。このユーザにより
入力されたデータに基づいて、サーバモジュール32は
前記2次元3面図を修正し、ユーザにより指示された材
料厚さを消去し、前記オペレータの選択に基づいて内側
或いは外側寸法を残す。
【0258】前記2次元3面図図面において厚さを消去
するために、前記サーバモジュール32は前記オペレー
タにより行なわれた選択に基づいて前記3つの図の各々
を分析する。選択された表面は幾何学的計算により(即
ち選択されたエンティティー線分或いは表面と同じX座
標或いはY座標射影に存在する対応するエンティティー
を検出することにより)他の図の1つへ射影され、前記
複数の図の各々における対応するエンティティー及び線
分を検出する。対応するエンティティーは、マークされ
且つ保持され、合致しないエンティティー或いは表面は
削除され或いは図24(b)に示されるそれのように、
スクリーン上に表示されない。更にオペレータにより指
示される厚さ寸法線は他の図の各々へ同様に射影され、
合致する厚さ寸法線或いはエンティティーは図24
(b)の例に更に示されるように削除される。結果とし
て、図面内の複数の図の各々は適宜に修正され、前記サ
ーバモジュール32においてユーザに対して表示され
る。厚さを有しない、結果としての2次元3面図は前記
パーツの3次元モデルを生成するために次の工程で使用
される。
【0259】この発明の厚さ削除手続は、各図において
削除されるべき厚さ線及び残されるべき表面エンティテ
ィーをオペレータが選択的に指示するようにするための
マニュアル厚さ消去モードを含む。表示された図の各々
においてどの領域が削除されるべきであり、どの表面が
残されるべきであるかを指示するためにマウス或いは他
の適当な入力装置がオペレータにより使用される。前記
オペレータにより入力されるデータに基づいて前記サー
バモジュール32は、厚さを有しない図面を提供するた
めに、前記2次元3面図からオペレータにより選択され
る各線分エンティティーを削除する。
【0260】この発明はまた全ての厚さ表現が前記2次
元3面図図面において正しく特定されたか否かを分析し
且つ検出し且つ、マークされない厚さ要素が存在する時
及び/又は図面データ中に矛盾が存在する時、ユーザに
警告するための警告システム或いはモジュールを含む。
例えば厚さ警告要素は、前記表示スクリーン上で潜在的
なマークされない厚さ部分を強調するために設けられ、
面警告要素は面の寸法が他の図における厚さのマークと
一致しない時、前記スクリーン上で潜在的な一致しない
面を強調するために設けられる。曲げ線警告要素は、ま
た矛盾する曲げ線を強調し及び一致しない厚さ曲線を強
調するために設けられる。曲線は、この曲線上に射影さ
れる少なくとも1つの曲げ線が2つの横断厚さ線分(厚
み横断線)により挟まれないとき強調される。例えば図
24(c)は、2つ或いは他の零でない偶数の横断厚さ
線分(即ち各図において厚さを横断する短い線)により
正しく挟まれている厚さ曲線を図示する。各曲げ線は2
つ又は他の零でない偶数の横断厚さ線分により挟まれる
べきである。各図面における前記パーツのこれらのエン
ティティーの分析は、ループ分析を実行し且つ各図を作
り上げる線分及び円弧エンティティーの連結性を解析す
ることに基づく。開放された厚さ線分は他の厚さ線分或
いは曲線と接続しない少なくとも1つの端点を有する厚
さ線分に基づいて定義される。1つの開放厚さ線分を含
むサイドは開放厚さサイドと定義される。厚さ線分は、
開放厚さ線分の開放厚さサイドが最小ループの境界ボッ
クスに一致しない場合に強調される。前記加工された2
次元3面図の像に関連する警告をユーザに与えることに
より、ユーザは図面データ中の矛盾を警告され、ユーザ
はパーツの3次元モデルを生成するために更に加工を行
なう前に、前記図面データを修正及び/又は訂正するこ
とができる。そのような警告システム及びユーザとの相
互作用を含むことが3次元モデルによる前記パーツの表
現の精密さを改善する。
【0261】図20のステップS168で、厚さを有し
ない加工された2次元3面図図面は3次元モデルへ変換
され発展させられる。2次元3面図図面から前記3次元
モデルへの変換及び展開は良く知られ或いは確立された
射影及び/又は突出方法を用いて行なわれる。例えば前
記2次元3面図から3次元モデルを生成するために、各
図の深さが検出され3次元モデルを展開するために各図
が射影される。結果としての3次元モデルは次に曲げモ
デルデータを生成する際に使用され、また上記した展開
アルゴリズムを適用することにより単一の2次元平面図
へ変換される。幾何学的モデル化技術についての更なる
情報については、モルテンソン、フォリー等及びマンテ
ィラを見よ。2次元図面から3次元モデルを構成するた
めの射影技術についての追加の情報については例えば以
下を見よ。ウェズレイ等,W.A.「投影図の肉付け」
I.B.M.J,RES,DEVELOP、25巻、N
O.6、934―954頁(1981)、アオムラ・シ
ゲル、「機械的図面を用いてソリッドモデルを形成する
こと」第6回コンピュータメカニクスコンファレンス、
JSME、NO.930−71、日本、497−98頁
(1993)、アオムラ・シゲル、研究及び実際使用の
最近の傾向及び将来の可能性(図面から3次元モデルの
自動的再構成)東京工学株式会社、日本、6−13頁
(1995)。これらの開示はここにそれらの全てにお
いて明示的に取り込まれる。
【0262】ステップS168で3次元モデルを展開す
る際、結果としての3次元モデルを更に加工し且つ精密
化するために追加のクリーンアップ工程が含まれる。こ
の発明の1つの側面によれば、3次元クリーンアップ工
程は、前記パーツの2次元3面図において存在し且つ前
記パーツの生成された3次元表現において余計な或いは
過剰な情報を生成する不明瞭さを補償するために設けら
れる。当業者に理解されるように、パーツの2次元3面
図表現は3次元座標空間における前記パーツの種々の特
徴の表現に関連して不明瞭さを含む。前記2次元3面図
から3次元モデルを生成する際余計な且つ過剰な情報が
これらの不明瞭さの結果として生成される。従ってこの
発明の側面によれば、前記3次元クリーンアップ工程
は、1つの端部がつながっていない線分を検出し且つ除
去すると共に曲げ線を検出し且つきれいにすると共に面
をトリミングする工程を含む。前記3次元クリーンアッ
ププロセスは前記パーツの結果としての3次元モデルを
生成する際に自動的に行なわれ或いは前記生成された3
次元モデルが追加の工程を要求すると判断される時、オ
ペレータからの入力に基づいて選択的に行なわれる。
【0263】前記3次元クリーンアップ工程によれば、
前記生成された3次元図面データを分析することによ
り、一端部において他のエンティティーと接続されない
と判断される全ての線分或いは曲線が特定され片側開放
線分として定義される。片側開放線分であると判断され
る任意のエンティティーは前記パーツの3次元表現から
除去される。一旦開放線分が除去されると、それは他の
線分或いはエンティティーが開放されることを導くかも
しれない。従って新しい片側開放線分がまた特定され、
全ての開放線分或いはエンティティーが除去されるま
で、繰り返し除去される。図63は片側開放線分が除去
される前のパーツの3次元表現の例を図示し、図64は
片側開放線分が前記3次元表現から除去された後の前記
パーツを図示する。
【0264】上記したように、ステップS168で行な
われる3次元クリーンアップ工程は曲げ線を検出しきれ
いにする工程も含む。曲げ線は、3次元空間におけるパ
ーツの面情報の検出を促進するために特定され且つきれ
いにされる(例えばモールド線分を加えることによ
り)。前記生成された3次元モデルデータに基づいて、
各曲げ線は、それぞれの中心により定義される同一の法
線を有する一対の3次元曲線(例えばそれは図面データ
における曲線エンティティーにより表現される)の検出
に基づいて同定される。この過程において、特定された
前記曲げ線に対してモールド(形取り)線分が付加され
る。前記モールド線分は、3次元曲線の各対において対
応する終点を特定し且つ前記3次元曲線の対応する終点
の間でモールド線分(例えば線分エンティティーで表現
される)を延長することにより追加される。図65は曲
げ線が特定される前のパーツの代表的3次元表示を図示
し図66は前記モールド線分(図において破線で表現さ
れる)が追加された後のパーツを図示する。
【0265】曲げ線が特定され且つモールド線分が追加
された後、3次元クリーンアップ工程は更に前記パーツ
の全ての曲げ線をきれいにし且つ面をトリミングするた
めに前記パーツの3次元表現を加工する。前記2次元3
面図データの図における頻繁に生ずる不明瞭さにより、
前記パーツの3次元表現に前記面の過剰な部分が生成さ
れる。前記3次元クリーンアップ工程は前記面の過剰な
部分を特定しそして板金領域知識(例えば何が折り畳め
ないかについての知識)を用いて前記面をトリミングす
る。余分な穴或いは開口部のような他の余分な情報も特
定され除去される。結果として前記パーツの過剰な部分
は除去され前記3次元表現は前記板金パーツのより精密
な表現を提供する。図67は前記曲げ線をきれいにし且
つ前記面をトリミングする前のパーツの代表的な部分を
図示し、図68は正常化及びトリミングがなされた後の
パーツの前記部分を示す。
【0266】図25は材料厚さを持つ最初の3次元図面
から材料厚さを持たない3次元図面を生成するためにな
される工程及び操作の論理フローの例を示す。ステップ
S200で、材料厚さを有する最初の3次元図面が入力
されサーバモジュール32へ搬入される。前記3次元モ
デルは材料厚さを有する3次元のワイヤフレーム図面
で、DXF或いはIGESファイルのごときCAD図面
ファイルである。前記3次元図面が前記サーバモジュー
ル32へ搬入された後、厚さ除去工程がステップS20
4で行なわれる。ステップS204における前記3次元
モデルに対する厚さ除去工程は上記したアマダUNFO
LDソフトウエア・システムにおいて提供されると同じ
方法で行なわれる。前記3次元モデルにおいて厚さを消
去するために、オペレータはまず厚さを指示し且つ残さ
れる面を選択するように促される。このオペレータの選
択に基づいて厚さを定義するエンティティー線分の終点
を解析することにより厚さが測定される。しかる後、選
択された表面の境界が、前記ループ及びエンティティー
解析工程に関連して上記したと類似の方法により探索さ
れる。そして保持されるエンティティーはマークされ
(例えばフラグを設定し或いは増加することにより)、
対応する厚さエンティティーは除去される。前記3次元
パーツのエンティティーを探索する際、前記エンティテ
ィーは、ユーザにより選択された厚さエンティティーの
長さに基づいて識別される。一般的に前記厚さエンティ
ティーと同じ長さを有する全てのエンティティーは選択
されず除去され、同じ長さでない他のエンティティーが
マークされ残される。前記3次元パーツの表面の探索で
マークされなかった残りのエンティティーもまた除去さ
れることがある。再びサーバモジュール32はマニュア
ル厚さ除去モードを提供し、そこではオペレータは除去
されるべき3次元パーツにおける各エンティティーを手
動で指示する。
【0267】ステップS204の後、厚さを有しない、
結果としての3次元モデルがステップS206で展開さ
れ及び/又はオペレータに対して表示される。展開アル
ゴリズム或いは工程が次にその材料厚さを有しない3次
元モデルに適用され上に詳細に説明したように、曲げモ
デルデータについての単一の2次元平面図を生成する。
上記したように前記データベース30に格納されるデザ
イン及び製造情報は、板金要素についての製造データの
みならず板金の幾何学形状及びトポロジーを含む曲げモ
デル・データファイルを含む。更にこの発明の種々の特
徴を実行するために使用されるソフトウエアはC++の
ごとき高度のプログラム言語を用い且つオブジェクト指
向プログラム技術を用いて生成される。この発明の種々
の特徴を実行するためには、Booch或いはOMTの
ごとき異なるオブジェクト指向技術も使用される。オブ
ジェクト指向プログラムが使用される場合は、前記板金
パーツを表現するためにオブジェクト指向データが使用
され、前記パーツのための曲げモデルは完全に自己充足
的クラス・ライブラリを介して実行される。この発明の
1つの側面により、オブジェクト指向プログラム技術に
基づく、前記曲げモデルのための代表的データ構造及び
アクセス・アルゴリズムの記述が提供される。図26
は、本願発明をオブジェクト指向プログラムにより実行
する際使用される前記曲げモデルの代表的データ構造及
びアクセスアルゴリズムを図示する。オブジェクト指向
プログラムは、データを含む複数のオブジェクト或いは
モジュールのみならずそのデータに作用する複数の指示
を結合することにより現実世界をモデル化することがで
きるソフトウエア展開の1つのタイプ或いは形態であ
る。オブジェクト指向プログラムにおいては、オブジェ
クトは板金パーツのごとき、何か物理的なものをモデル
化するソフトウエアエンティティーであり、或いはそれ
らはビジネス上の商取引のごとき仮想的な何かをモデル
化するものである。オブジェクトはそのオブジェクトの
状態を集合的に定義する1つもしくはそれ以上の属性
(即ちフィールド)を含み、且つ全ての他のオブジェク
トからそれを識別するための識別子を含む。更にオブジ
ェクトはある種の条件の存在に基づいて、前記属性を修
正し或いは前記オブジェクトに対して作用をなす一群の
方法(即ち手続き)により定義される振る舞いを含む。
【0268】この発明の実施例によれば、前記板金パー
ツはオブジェクト指向データモデルとして表現される。
図26に示されるように板金パーツの曲げモデルは完全
に自己充足的なクラスライブラリとして定義される。前
記板金パーツのための全ての要求されるデータ操作及び
機能(例えば折曲げ、展開等)はこのクラスライブラリ
の要素機能として取り込まれる。全ての幾何学的或いは
トポロジーデータは前記曲げモデルの中で分類される複
数のオブジェクトの内部で定義される。前記曲げモデル
クラスライブラリは複数のクラス或いはオブジェクトの
階層であり、パーツクラスはその階層の最上レベルのク
ラスである。前記パーツクラスは種々のパーツ属性を有
するパーツオブジェクトを含み、前記パーツ及び前記パ
ーツに対してなされる複数の作用を定義する種々のオブ
ジェクトを含む。
【0269】図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次元空間位置データ、及
び端及び表面データを含む。
【0270】図26の実施例に更に示されるように、パ
ーツクラス50は更にトポロジー・オブジェクト62及
び曲げ特性オブジェクト64を含む。前記トポロジーオ
ブジェクト62は、前記パーツの前記面、穴、成形部及
び曲げ線についてのパーツトポロジーデータを含む。前
記トポロジーオブジェクト62におけるデータは前記パ
ーツの前記種々の特徴の構造的及び幾何学的関係を示
す。前記曲げ特性オブジェクト64は前記パーツの1つ
或いはそれ以上の特徴についての特殊な製造上の拘束に
関する情報を含む。例えば如何に前記板金パーツが曲げ
られるべきであるかに関する曲げ特性情報が、前記曲げ
特性オブジェクト64に設けられる。前記曲げ特性情報
は、異なる曲げ特性タイプ(例えば同時曲げ、同一直線
上曲げ、Z曲げ等)についての特殊製造データを含む。
【0271】前記曲げ線オブジェクト60は、また行な
われる曲げに関連する製造特殊データを含む。従って、
各曲げ線についての幾何学的或いは寸法データ、2次元
及び3次元空間位置データ、端データに加えて、前記曲
げ線オブジェクト60はまた、各曲げ線についてのV幅
データ、曲げピッチデータ、曲げ数データ及び/又は配
向データを含む。各曲げ線は、図26に示すように付随
する曲げ操作を含む。この曲げ操作は、各曲げ線におい
て曲げを行なうためのデータ及び操作/指示を有する一
群のオブジェクトとして実行される。仮にオブジェクト
として提供されると、各曲げ操作は、曲げ角度、曲げ半
径及び/又は曲げ縮小量のごとき固有の曲げデータのみ
ならず、如何に或いはどのタイプの曲げを行なうべきか
(例えば円錐曲げ、Z曲げ、ヘミング、円弧曲げ等)を
指示するデータ及び指令を含む。
【0272】前記パーツの曲げモデルを、オブジェクト
指向データモデルを介して実行することにより、全ての
複雑な数学的計算、計算幾何学及びマトリックス変換が
単一のクラスライブラリに組み込まれる。ヘミング、Z
曲げ及び円弧曲げのごとき特殊な曲げ操作もそのクラス
ライブラリに取り込まれる。更にV幅及び曲げ縮小量及
び曲げ順のごとき製造情報もそのクラスライブラリに取
り込まれる。前記曲げモデルにより、前記2次元平面モ
デル及び3次元モデルの同時二重表示が図26に示すよ
うに行なわれる。更に、前記曲げモデルの曲げ線オブジ
ェクト60に応じて曲げ加工が行なわれる。前記曲げモ
デル及びパーツ構造並びにそれらについての実行に関連
する一般的なコメントはここに添付した付録Kに提供さ
れる。
【0273】曲げモデルビューアが前記曲げモデルを解
釈し、2次元及び/又は3次元表現における前記パーツ
の視覚的な画像を表示するために設けられる。図27
は、この発明の他の側面による、前記曲げモデルビュー
アの構造と前記曲げモデルとの関係のブロック図を図示
する。前記曲げモデルビューアはオブジェクト指向プロ
グラム技術を介して実行され、前記設備38における種
々の場所10,12,14,…20の前記ステーション
モジュールにおけるユーザが前記曲げモデルに設けた情
報に基づいて前記パーツの種々の図を表示できるように
するウインドウズに基づくアプリケーションである。前
記曲げモデルビューアは、前記板金パーツを視覚化する
ために用いられる一群のアプリケーション・ライブラリ
・モジュールを含む。更に、前記曲げモデルビューア
は、ウインドウズ・アプリケーションの画像クラスとし
て設計され、従ってそれは任意のウインドウズ・アプリ
ケーションについての基本的画像クラスとして使用され
る。前記2次元及び3次元モデルを見るための殆どの標
準的操作(例えばズーム92、回転96、パン100、
寸法102等)は前記曲げモデルビューアの要素機能と
して実行される。幾何学的変換及び基本的コンピュータ
グラフィックス技術は、画像操作を実行する際に前記曲
げモデルオブジェクトに対して適用される。更に、前記
曲げモデルビューアは、画像モデル属性88を含み、そ
れはソリッド画像、ワイヤフレーム画像、2次元平面画
像及び正射影画像を含む4つの主なる画像モードを有す
る。
【0274】この発明の1つの側面によれば、前記曲げ
モデルクラスライブラリ80は、選択された画像(例え
ばソリッド、ワイヤ、2次元平面又は正射影画像)に応
じて、前記板金パーツに作用する一群の手続き又は機能
を含む。前記曲げモデルビューア観察クラス84は、ズ
ーム92、回転96、パン100及び寸法102のごと
き、一連の標準的操作を含む。そして、前記曲げモデル
ビューアの状態に応じて、前記曲げモデルビューア観察
クラスは、前記曲げモデル・クラス・ライブラリ80か
ら複数の機能を呼び出す。図27に示されるように、ユ
ーザにより選択される前記種々の観察モデル属性或いは
特徴88は、ソリッド画像、ワイヤフレーム画像、2次
元平面画像及び正射影画像を含む。この発明に設けてあ
るこれらの種々の観察モードの記述は図28−31を参
照して以下に提供される。
【0275】基本的コンピュータグラフィックス及び幾
何学的モデル化技術、例えば幾何学的変換及び3次元幾
何学的技術は、前記曲げモデルの種々の特徴を実行し且
つ異なる観察モード或いは機能を提供するために使用さ
れる。コンピュータに基づいた2次元及び3次元のモデ
ル化及びシミュレーションにおける最近の発展及び展
開、例えばグラフィックライブラリ或いはパッケージの
効用はこの発明のこれらの特徴を実行するために適用さ
れる。更に、コンピュータグラフィックス及びモデル化
については広い種類の刊行物或いは文献が利用可能であ
る。例えば、モルテンソン、フォリー等、マンティラを
見よ。それらの各々は上に記載した。
【0276】この発明の種々の観察及びモデル化の特徴
を提供するために各ステーションモジュール及びサーバ
モジュールは、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)を見よ。
【0277】前記パーツの種々の画像を表示するため
に、前記曲げモデルは例えばオペレータのステーション
モジュールにより前記データベース30からアクセスさ
れる。前記曲げモデルデータは、使用されているグラフ
ィック・ライブラリ或いはパッケージ(例えばオープン
GL又はレンダウェア)により使用されるデータフォー
マットに応じて再フォーマット化される。しかる後、前
記グラフィックデータは、オペレータにより選択された
観察モード(ワイヤ、ソリッド等)を表示し、或いは前
記ユーザにより実行された観察機能(ズーム、パン等)
を実行するために種々のプログラムされた順序に従って
加工される。
【0278】特定の観察モードがオペレータにより選択
される時、選択された観察モードは、前記画像の現在の
ズーム比率或いはファクター及び向きと共に検出され
る。この情報は、次に前記現在の表示を更新するために
前記グラフィックパッケージに対して機能コールを行な
うために使用される。前記グラフィックパッケージに対
する機能コールは、表示される観察モード並びに実行さ
れるズーム或いはその他の観察機能に応じて行なわれ
る。これらの機能コールに基づいて前記グラフィックパ
ッケージは必要なデータを提供し、従って前記ステーシ
ョンモジュールは前記オペレータに対して前記パーツの
画像を表示する。前記ユーザによる前記2次元又は3次
元表現の修正(例えばジョイスティック或いはマウスを
移動することにより)に基づいて前記表示された画像を
更新するために追加の機能コールは前記グラフィックラ
イブラリに対してなされる。
【0279】前記パーツのワイヤフレーム画像を提供す
るために、前記グラフィックパッケージに対して前記パ
ーツの線分エンティティーデータが提供され必要なグラ
フィック計算がなされる。しかし、ソリッド画像につい
ては、前記面の各々について1つもしくはそれ以上の多
角形(ポリゴン)が引き出され、前記画像を表示するた
めに前記グラフィックパッケージへ入力として提供され
る。オープンGL及びレンダウェアのようなグラフィッ
クパッケージは、多角形データを入力として取得し、ソ
リッド画像を提供するために前記多角形により定義され
る領域を満たす。前記多角形は、前記曲げモデルにおけ
る面及び曲げ線情報から導出され各面の境界を決定する
ことにより導出される。前記多角形は前記パーツの各面
を表示し且つ定義するために生成されなければならな
い。これらの面は次に、板金パーツ全体を表示するため
に、前記曲げモデルにおける前記パーツトポロジー及び
他のデータに基づいて接続される。仮に面が開口部或い
は穴を有する場合には、そのような開口部を囲まない幾
つかの多角形を有する面を定義することが必要となる。
正射図については、個々の図の各々(それはワイヤフレ
ーム又はソリッドである。)についてのデータは前記グ
ラフィックパッケージに送られ、図31に示されるごと
く、結果としての複数の図が単一の表示スクリーン上で
結合される。前記曲げモデル像の種々の観察モード及び
機能を実行するための代表的コードは付録Eに提供され
る。このサンプルコードはC++で記載され前記プロセ
ス及びそこで実行される操作に関連する複数のコメント
を含む。適当なグラフィックパッケージ(例えばオープ
ンGL及びレンダウェア)との結合における前記コード
は異なった図(例えば2次元及び3次元ワイヤフレーム
或いはソリッド)を表示するために使用されるだけでな
く、前記観察機能(例えばズーム、回転、パン等)の各
々の機能を提供する。表示される種々の観察モード表示
スクリーンの簡単な説明が以下に与えられる。
【0280】ソリッド図モードは、前記曲げモデルによ
り定義される前記パーツの、ソリッドで表示される3次
元図を表示する。図28は前記板金設備38内での位置
10,12,14,…20のいずれかにおいて設けてあ
る表示スクリーンへ出力として提供される代表的ソリッ
ド図ウインドウを図示する。このソリッド図モードにお
いて、ユーザ或いはオペレータは、3次元空間でのナビ
ゲーション及び3次元自動寸法付けを操作するための複
数の観察機能を与えられる。前記パーツのソリッド図を
変更するために設けられる基本的な機能は回転、ズーミ
ング、パンニング、及び/又は標準図選択を含む。前記
ユーザにより与えられ或いは選択される前記標準図は以
下を含む。即ち等測投影法図、平面図、底面図、正面
図、背面図、左図、及び右図。自動及びマニュアル寸法
付け操作がまた提供され、現在の観察角度に基づいて前
記パーツの重要な寸法を表示する。この発明の寸法付け
特性の代表的例が、図32−36を参照して以下に提供
される。
【0281】図28に示されるようにソリッド図ウイン
ドウはウインドウズに基づいたアプリケーションであ
り、従って前記パーツの複数のウインドウ或いは部分図
が提供される。前記複数の図のウインドウは、ウインド
ウの中で1つの極めてクローズアップされた単一の図を
提供する拡大図及び単一のウインドウにおいて前記パー
ツの極めて遠くからの図を与える鳥瞰図を含む。前記部
分図はユーザにより選択されたオブジェクトの部分図を
与える。前記種々の観察機能を制御するために、前記場
所10,12,14,…20の各々の前記サーバモジュ
ール32及びステーションモジュールに、ジョイスティ
ックインタフェースが設けられる。前記ジョイスティッ
クだけ及び/又はキーボード上の所定のキー(例えばシ
フトキー又はコントロールキー)の操作との組み合わせ
の操作が、回転及びパンニング及びズーミングのごとき
種々の機能を実行するためにユーザにより行なわれる。
更に、前記パーツのソリッド図の表示される生地は、デ
ータベース内での前記パーツについて特定された材質を
シミュレートするように選択される。この目的のため
に、スチール、ステンレススチール、アルミニウム等の
ごとき材料の生地のライブラリを有する材料生地ライブ
ラリが提供される。格納された材料生地ライブラリはソ
リッド図が存在する時オペレータによりアクセスされ適
用される。従って、表示されるパーツの表面は前記板金
パーツの実際の生地をより忠実にシミュレートする。
【0282】前記ワイヤフレーム図モードは、前記板金
パーツのワイヤフレーム図のウインドウズに基づいた表
示を提供する。ワイヤフレームウインドウの例が図29
に示されている。前記ワイヤフレームにおける3次元空
間ナビゲーション及び3次元寸法付けを提供するための
キーの機能は、前記ソリッド図に関して上に記載したと
類似である。例えば回転、ズーミング、パンニング及び
標準図の選択のごとき機能が提供される。自動寸法付
け、多重図ウインドウ及び断面図オプションも前記ワイ
ヤフレーム図モードにおいて提供される。更に、ジョイ
スティック及び/又はキーボードインタフェースが、ユ
ーザが前記種々の観察機能を選択し且つ活性化すること
ができるように提供される。
【0283】前記2次元平面図モードはワイヤフレーム
表示において、前記パーツの展開された2次元平面図を
表示する。2次元平面図ウインドウの例が図30に示さ
れている。この2次元平面図モードはユーザがウインド
ウ中の図を変更し又は改造するのを可能とするための複
数の観察機能を有する。例えばユーザが前記2次元平面
ワイヤフレーム図を選択的にズームし且つパンするのを
可能とするようにズーミング及びパンニング機能が設け
てある。更に、寸法付け及び多重ウインドウ観察機能
が、前記ソリッド図モードに関して上記したと同様の態
様で設けてある。ジョイスティック及び/又はキーボー
ドインタフェースはユーザがパンし、ズームし他の観察
機能を制御するのを可能とするように設けてある。前記
パーツに設けられている特殊な成形部または形状は、特
殊な成形部の指示又は記載と共に、前記成形領域の前記
最も外側の境界についての成形または形状として表示さ
れる。
【0284】図31に図示されるような正射図ウインド
ウも前記曲げモデルビューアの一部として提供される。
前記正射図モードはワイヤフレーム表示において平面
図、正面図、右図及び等測投影法図を表示する。隠れ線
オプションが、観察角度に基づいてブロックされた線を
見えなくするために設けられる。この隠れ線オプション
は各図のウインドウを簡単化するために用いられる。前
記正射図モードにおいても種々の観察機能が提供され、
ユーザが前記ウインドウにおいて現在の図を選択的に操
作し且つ変更するのを可能とする。例えば、ズーミング
及びパンニング機能が寸法付け及び多重ウインドウ観察
機能と共に設けられる。上記したように、多重ウインド
ウ観察機能が設けられ、ユーザが、多重ウインドウにお
いて前記正射図の拡大図及び/又は鳥瞰図を選択的に表
示することを可能とする。ジョイスティック及び/又は
キーボードインタフェースが、前記複数の場所の各々に
設けられ、ユーザが、前記正射図モードにおいて前記複
数の観察機能の各々を選択的に活性化し且つ操作するの
を可能とする。
【0285】上記した種々の図の表示の各々を表示せし
めるのに加えて、前記曲げモデルビューア観察クラスは
他の特徴と共に実行される。例えば前記曲げモデルビュ
ーアはオペレータにより選択され強調されている、現在
の図における複数の項目或いはエンティティーを指示す
るための選択集合を含み且つ維持する。この発明の1つ
の側面によれば、オペレータは、選択された項目に関連
するデータを修正し或いは前記パーツのそれらの項目の
所定の操作を行なうために、前記表示されたパーツの面
及び曲げ線及び他の特徴を選択することを可能とされ
る。例えばオペレータは、表示されたパーツの面を選択
し、その面のその幅或いは長さに沿っての寸法データを
変更することができる。オペレータはまた曲げ角度又は
V幅のごとき各曲げ線に付随する種々の曲げデータを修
正することができる。
【0286】前記曲げモデルビューアはユーザにより選
択されたエンティティー或いは項目(例えば面、曲げ
線、面或いは曲げ線の端等)のリストを保持する。観察
者はそのリストを更新する。従ってオペレータにより現
在選択されている現在の項目は前記選択リストに常に保
持される。この発明におけるソフトウエアの他の部分
は、異なる手順(例えばマニュアル寸法付け等)を実行
し或いは行なう際、選択されたエンティティーの前記現
在のリストの図面クラスを呼び出す。
【0287】更に前記曲げモデルビューアは観察可能性
機能を提供する。それは現在表示されている図に基づい
て観察可能性情報及び座標情報を提供する。以下に更に
十分に説明されるように、前記観察可能性機能は前記パ
ーツの特定な部分或いはエンティティーがスクリーン上
で現在観察可能であるか否かについての情報を提供し且
つスクリーンエンティティーが現在位置する場所につい
ての座標情報を提供する。前記曲げモデルビューアの観
察可能性機能は、前記パーツのどの部分が現在スクリー
ン上で観察可能であるかを決定するためにこの発明の寸
法付け特性により呼び出される。従ってスクリーン上で
観察可能である前記パーツの部分の寸法情報のみが観察
者に対して表示される。この発明の寸法付け及び観察可
能性機能のより詳細な説明は以下に提供される。更に前
記曲げモデルビューアの観察可能性機能を実行するため
の代表的コードはここに添付する付録Jに提供される。
【0288】図32−36を参照するに、この発明の1
つの側面に基づく、寸法付け特性の事例が説明される。
上記したように、観察モードの各々は現在の観察方向に
基づいて、前記パーツの寸法を自動的に表示する寸法付
け機能を含む。自動寸法付け機能は、現在の観察角度に
おいては見ることができないフランジ或いは曲げ線の寸
法がユーザに対して表示されないように提供される。前
記自動寸法付け機能或いはモードが活性化される時、前
記パーツの観察可能な寸法のみが、現在の観察角度に基
づいて表示される。更に、自動寸法付けモードにおいて
は、所定の寸法(即ち前記曲げ操作に対して重要である
寸法)のみが現在の観察角度の状態に基づいて表示され
る。マニュアルの寸法付けモードも提供され、ユーザが
どの寸法が表示されるべきであるかを選択的に指示する
ことを可能とする。このマニュアル寸法付けモードにお
いては、ユーザにより選択された寸法事項のみが、現在
のパーツの観察角度に基づいて表示される。いずれの寸
法付けモードにおいても、表示された寸法事項は、前記
パーツがズーム化され或いはパンされる時ウインドウ表
示から消去され或いは除去される。
【0289】図32は自動寸法付けモードにおいて表示
される種々の寸法事項の例を図示する。前記自動寸法付
けモードにおいて表示される寸法事項は、曲げ操作に重
要な事項(例えばフランジ長さ、曲げ線長さ、曲げ角度
等)からなり、パンチ加工された穴或いは開口部の寸法
のような余分な寸法事項ではない。前記表示される寸法
事項は例えば前記板金パーツの幅、深さ、及び高さ並び
にフランジ長さを含む。更に、各曲げ線の前記曲げ線長
さL、曲げ角度A、内側半径R及び曲げ縮小Dは単独で
或いは一緒に、1つのウインドウに或いはグループ情報
ボックスに表示される。上記したように、現在の観察角
度に基づいて観察可能な寸法事項のみが表示される。更
に前記オペレータが、前記パーツの観察角度を変えるた
めに回転、ズーミング或いはパンニングをする時全ての
寸法は表示から消去され或いは除去され、各操作が完了
した時それらの寸法は再び表示される。表示情報(任意
のテキスト或いは参照矢印)の寸法及び向きは、現在の
ズームの比率或いは観察角度ではなくスクリーンの寸法
に対して常に寸法調整される。しかしながら、前記寸法
情報の可読性を改良するために前記寸法情報の色、スタ
イル、重み及び/又はフォントはユーザがそれらを変更
できるように形成可能である。結果としてオペレータ或
いはデザイナーは、前記寸法情報の特殊の色、フォント
サイズ等を選択することによりパーツにおける重要な寸
法を強調することができる。例えば、寸法テキストの
色、寸法又はフォント又は、寸法参照事項、線又は矢印
の色、線の重み或いはスタイルは、パーツにおける重要
な寸法を指示するために強調され或いは選択的に変更さ
れる。オペレータはまたウインドウ情報ボックスを色付
けし満たし或いはスタイル付けし或いは特定の曲げ線を
色付けし或いはパーツ内の他の重要な寸法を強調する。
【0290】この発明の寸法付け特性を実行するために
種々のプロセス或いは操作が利用される。更に上記した
ように本発明の寸法付け特性に対して観察可能性情報を
提供する観察可能性機能を、前記曲げモデルビューアは
備える。これらの機能或いは特性は、例えばサーバモジ
ュール32及び/又は工場全体に位置するステーション
モジュールのそれぞれでソフトウエアにより実行され
る。この発明の自動寸法付け特性を実行するための代表
的コードが付録F−Iに設けてある。更に、曲げモデル
ビューアの観察可能性機能のためのサンプルコードが付
録Jに設けてある。これらの付録におけるコードはC+
+プログラム言語で書かれており、そこで行なわれる手
続き及び操作の論理フローの理解を容易にするためのコ
メントを含む。
【0291】この発明の寸法付け特性の論理フローは一
般的に3つの段階に分類される。第1の段階で、前記パ
ーツの曲げモデル幾何形状及びトポロジーデータがデー
タベース30からアクセスされ、前記パーツの全ての寸
法並びにそれらの寸法が表示され得る全ての態様を計算
するために使用される。前記パーツの各曲げ線及び面に
ついて、データが表示され得る全ての最も遠い点が計算
され、これらの点について、寸法線或いは矢印が表示さ
れ得る全ての方法が計算される。前記寸法データ或いは
他の情報が表示され得る場所を決定する際に一定のヒュ
ーリスティックが適用される。例えば一般的なルールと
して、全ての情報は前記パーツの外側にのみ表示される
と決定される。このようなヒューリスティックが、前記
ビューアに対してより意味のあるそしてより込み合わな
い情報の表示を提供するために適用される。
【0292】上記した第1の段階は、本発明の寸法付け
特性がオペレータにより活性化された際常に実行され
る。或いは、前記第1段階の計算は前記パーツが最初に
オペレータにより観察された際にのみ行なわれる。この
ような場合に、前記計算されたデータは次の使用のため
にメモリに格納され、前記パーツの寸法或いは他の幾何
学的データがユーザにより修正され或いは変更された時
変更される。更に前記第1段階の全ての計算は図面スク
リーンに対してではなくパーツの幾何学形状に対して行
なわれる。従って前記データは、現在の図面に関わりな
く或いはその図面が変更されても何時でも再び使用され
得る。
【0293】この発明の自動寸法付け特性の第2段階は
前記パーツの図面が更新された時常に行なわれる。この
第2段階の主たる目的は、変更された図において前記パ
ーツのどのエンティティーが観察可能であるかに基づい
て前記第1段階中に生成されたデータをふるいにかける
ことである。この第2段階において、現在の図において
観察可能でない全てのデータはふるいにかけられ、現在
観察可能である、前記第1段階において計算されたデー
タのみが残る。前記パーツのいずれの点あるいは部分が
現在観察可能であるかを決定するために前記曲げモデル
ビューアに対する機能コールがなされる。上記したよう
に、前記曲げモデルビューアは、表示されている現在の
図に基づいて前記パーツの観察可能な部分についての情
報を保持し且つ提供する観察機能を含む。前記パーツの
向きに基づいて前記曲げモデルビューアは前記パーツの
どの面及び曲げ線(並びにそれらの面及び曲げ線のどの
端或いは部分)が観察可能であるか、そして何がスクリ
ーン上で隠されているかを決定する。
【0294】上記したように、前記曲げモデルビューア
の観察可能機能を実行するためのサンプルコードは付録
Jに提供される。前記パーツのいずれの点あるいは部分
が観察可能であるかを決定するために、前記曲げモデル
ビューアは前記パーツの現在の図の向き及び現在のズー
ム面又は表示されているパーツの比率を決定し且つ維持
する。前記曲げモデルビューアはこの現在の図の向きを
決定し維持するために従来の透視図射影技術(モルテン
ソンの例えば12章を見よ)を使用する。前記パーツの
任意の点の観察可能性を決定する際に前記点の世界座標
(即ちそこにおいて前記パーツが表現されているところ
の座標)を前記観察可能性機能は獲得する。次に、前記
現在の図面の向き及びズーム面あるいは比率に基づいて
その点について、前記世界座標に対応するスクリーン座
標(即ちスクリーン上の画素の位置)が決定される。そ
の後、前記スクリーン座標に基づいて、前記スクリーン
の観察点の眺めから前記部品の任意のエンティティー或
いは部分が問題の点の前方にあるか否かが決定される。
前記パーツの上の点の隠されている特性は、前記パーツ
の他のエンティティー或いは部分が問題の点と同じスク
リーン上の点を割り当てられているかどうかに基づいて
も決定され得る。グラフィックパッケージ或いはライブ
ラリ(例えばオープンGLあるいはレンダウェア)への
機能コールは、前記パーツの1つの点以上が同じスクリ
ーン上の点に割り当てられているかどうかを決定するた
めに使用される。もし何かが同じスクリーン上の点に割
り当てられているならば、それらの点のそれぞれのZバ
ッファ深さに基づいて、前記パーツの点がそれの後ろに
あるかどうかが決定される。前記Zバッファ深さはオー
プンGL或いはレンダウェアのごときグラフィックパッ
ケージにより使用され、観察点或いはカメラ位置からそ
れぞれの点への距離を定義する。前記Z深さは、興味の
ある前記パーツの複数の点について前記グラフィックパ
ッケージへ機能コールを行なうことにより決定される。
【0295】前記曲げモデルビューアの観察可能性機能
の前記プロセスはこの発明の自動寸法付け特性から前記
曲げモデルビューアへ催促がある時いつでも実行され
る。そのようなプロセスは従って前記オペレータにより
表示されているパーツの現在の図が修正され或いは変更
される時いつでも実行される。上記したように、前記曲
げモデルビューアは、表示された画像の向きに対して変
更がなされる時は常に、現在の図の向き及びズーム比の
状態を維持し且つ更新し、従って要求される時観察可能
性情報を正確に提供する。
【0296】どのデータが観察可能であるかを決定した
後、自動寸法付け機能は、(例えば第1段階での計算に
基づいて)前記寸法データ或いは他の情報が表示され得
る全ての可能な方法及び位置を決定する。前記データが
表示され得る全ての可能な方法からデータを表示するた
めの最適の方法を選択するために一群のヒューリスティ
ックが適用される。例えば第1のヒューリスティック
は、観察者の観察点により近いスクリーン上の領域が好
ましいと要求する。第2のヒューリスティックは、前記
寸法を定義するための2つの可能な点の間の距離が最小
であるところの領域により近い領域にデータは表示され
るべきであると規定する。他のヒューリスティックはま
た、スクリーン上での重なり合い或いは混雑を避けるた
めに、他の寸法データ或いは他の情報の相対的位置に基
づいて適用される。
【0297】前記パーツの観察可能な部分及び前記観察
可能な領域についての情報を表示するための最適の領域
を決定した後、前記自動寸法付け機能の第3の段階は前
記表示スクリーン上で種々の情報を描くために実行され
る。例えば、前記情報を表示するための領域の選択に基
づいて、寸法情報は前記パーツの観察可能な寸法の各々
についてスクリーン上に表示される。更にどの曲げ線が
観察可能であるかに基づいて、曲げ線情報がまた、他の
パーツ情報とオーバーラップしないスクリーンの領域に
おいて情報ボックス(例えば図32に示されるそれ)に
表示される。前記パーツの幅、高さ、及び深さを含むパ
ーツの寸法はまた前記スクリーン上の所定の位置(例え
ば前記パーツの右下)或いは前記パーツに最も近く他の
情報にオーバーラップしない或いはそれを邪魔しない位
置に表示される。
【0298】図33−36は前記寸法付けモードにおい
て寸法事項を表示する際に、使用される種々の方法及び
定義を図示する。特に図33(a)−33(b)及び3
3(c)は、種々の異なるパーツについてフランジ寸法
が定義される方法を図示する。この発明の1つの側面に
よれば、前記フランジ長さは、各曲げ線からフランジ上
で最も遠い点として定義される。もし前記曲げ線と並行
であるフランジの最も長い端部に前記フランジの最も遠
い点が存在しない場合には、前記寸法付けモードにおい
て最も長いフランジが追加され表示される。限定しない
事例として図34(a)及び34(b)は、2つの異な
るタイプのパーツについて補助的なフランジ長さを追加
することを図示する。前記パーツの厚さが表示される
時、フランジ長さは外側寸法の外側として表示される。
例えば図35(a)、35(b)及び35(c)は、厚
さを有して表示される種々のパーツについて前記フラン
ジ長さが指示される態様を図示する。更に、鋭角の曲げ
を備えたパーツについて、前記フランジ長さは種々の方
法で表示される。例えば図36(a)に示されるよう
に、フランジ長さは、接線寸法定義に基づいて表示さ
れ、そこでは前記フランジ長さは前記鋭角曲げから延長
される接線から測定される。或いは、前記鋭角曲げ角度
の2つの辺から延長された2つの直線の交差により定義
される点に基づいてフランジ長さを定義するために、図
36(b)に示されるそれのごとき交差寸法方法が使用
される。オペレータは、前記フランジ長さを表示するた
めに前記接線寸法或いは交差寸法方法のうちから選択す
ることを可能とされ、及び/又は特定の寸法方法(例え
ば接線寸法方法)はデフォルト設定として提供される。
【0299】曲げコード順番の生成を促進するために、
種々の表示機能を有した図形的ユーザインタフェースが
設けられ、オペレータによる曲げプランの生成を助け
る。図37−44はこの発明の他の側面により、図形的
ユーザインタフェースの使用により曲げコード順番を生
成するために実行される種々の手続き及び操作を図示す
る。通常、最初の曲げモデルデータ及び他の作業情報は
サーバモジュール32において重要な幾何学的及び製造
データを入力することにより設計プログラマにより生成
される。結果としての曲げモデルファイルは次にデータ
ベース30に格納される。板金パーツが製造される前
に、曲げオペレータが、所望の曲げ操作を実行するため
の曲げ順を生成する必要がある。この曲げオペレータ
は、どのタイプの工具が必要であるかを決定し且つ前記
曲げ機械装置について工具取付けを定義しなければなら
ない。この曲げプラン生成の工程は、図形的ユーザイン
タフェースの使用によりまたこの発明の種々の教示によ
り援助され、且つより効率的となる。
【0300】前記曲げプランを生成するために、例えば
曲げステーション18の曲げオペレータは、前記データ
ベース30から前記曲げモデル及び他の作業情報へアク
セスし且つダウンロードする。前記関連するパーツにつ
いての曲げモデルは前記コミュニケーションネットワー
ク26を介して曲げステーション18における工場フロ
ア上のステーションモジュールへ搬入され或いは移入さ
れる。この工程は、一般的に図37のステップS220
に示される。その後、ステップS224で曲げオペレー
タは、前記曲げモデルビューアを用いて前記パーツの形
状及び寸法を調べる。ここで、前記曲げオペレータは、
前記曲げステーションに位置付けられた表示スクリーン
で前記パーツの種々の2次元及び3次元図を選択的にズ
ームし且つパンする。この発明の自動寸法付け特性を活
性化することにより、前記曲げオペレータはまた曲げ操
作を実行するために前記パーツの重要な曲げ寸法を観察
する。
【0301】一旦オペレータが前記パーツの形状及び寸
法を理解すると、この曲げオペレータはステップS22
8で曲げ順入力ウインドウを選択し且つ表示することに
より前記曲げプランを生成することを開始する。前記曲
げ順入力ウインドウは、曲げオペレータが曲げ順を生成
し且つ修正し且つ消去するのを援助するために図形的ユ
ーザインタフェースを提供し且つオペレータが、前記曲
げ順における各段階についての種々の製造パラメータ
(例えばバックゲージ位置、工具、NCデータ等)を特
定し且つ入力することを可能とする。前記曲げ順入力ウ
インドウは前記スクリーンの一部(例えばスクリーンの
中央部或いはスクリーンの左側の方)に表示される前記
パーツの2次元平面図画像を含む。前記2次元平面図画
像は、前記パーツのフランジ、穴及び開口部を含む、前
記展開パーツの種々の特徴を含む。前記曲げオペレータ
が前記複数の曲げ線及び各曲げ線についての曲げ順を選
択し且つ指示すると、各曲げ段階における前記中間的パ
ーツ形状のソリッド2次元或いは3次元画像が現れ、例
えば図38に示されるように、スクリーンの右側の端の
ごときスクリーンの一部にそれらが提供される。前記中
間パーツ形状の画像は入力された曲げ順に対応した順番
で表示され且つ(図38の例に示されるように)前記パ
ーツの2次元平面図と共にスクリーン上に同時に表示さ
れ、或いは別個のスクリーン表示に別個に表示される。
【0302】更に各曲げ線が選択されるにつれて、前記
曲げ線は強調され、図39(a)に一例として示される
ように、曲げ順番号及び挿入方向(例えば矢印で表現さ
れる)が前記曲げ線の上或いは近くに表示される。各曲
げ線についての前記曲げ線番号は、それが選択される順
番に基づいて自動的に設定され、或いは各曲げ線が選択
された後オペレータによりマニュアルで入力される。曲
げ角度、曲げ線長さ、及びバックゲージ位置のごとき曲
げ線に関連する他の製造情報も、図40及び41に例と
して示されるように、各曲げ線が選択され強調されると
き入力され及び/又はスクリーン上に表示される。図4
0及び41に示すように、ダイアログ或いは情報ボック
スがスクリーン上に表示され、曲げオペレータが各曲げ
線に関連する製造情報及び他のパラメータを選択し、入
力し或いは修正することを可能とする。
【0303】前記ダイアログ或いは情報ボックスは、曲
げオペレータが曲げ線を強調し或いは選択するのを可能
とする。ホット機能キー或いは高速スイッチキーが前記
曲げシーケンス入力ウインドウに表示され、オペレータ
が工具立てを選択し或いは入力し且つNCデータを監視
し且つ修正するのを可能とする。例えば曲げオペレータ
は、工具機能キーを選択し、前記曲げ順入力ウインドウ
から、工具立て情報を入力するための工具入力表示スク
リーン或いは複数の表示スクリーンへ切替える。NC機
能制御キー(例えばNC9EX)も設けられ、オペレー
タが実行されるべき曲げ操作に関連するNCデータを監
視し及び/又は修正するのを可能とする。更に図40及
び41に示されるように、曲げ線を定義し及び/又は修
正すること及び関連する製造情報に関連して他の機能キ
ー及び制御部が設けられている。例えばZOOM AL
Lキーが、前記2次元平面図画像をズームイン及びズー
ムアウトするために設けられている。バックゲージキー
は、前記バックゲージの位置を選択し或いは設定するた
めに設けられている。グループ化及びグループ解除化制
御キーは、一緒に曲げられる複数の曲げ線を可能とし或
いは制御するために表示される。更に制御キー(例えば
アマ曲げ)が特殊な曲げ操作を定義するために設けられ
ている。他の機能キーも表示されオペレータが前記曲げ
順を選択し、修正し及び/又は消去するために設けられ
ている(例えばREMOVE CLEAR FWD、C
LEAR ALL、OK、CANCELL)。この曲げ
順入力ウインドウにより、曲げオペレータは、前記曲げ
順及び種々の製造情報を効率的に監視し且つ修正するこ
とが可能となる。
【0304】更にこの発明の他の側面によれば、前記パ
ーツの断面図及び/又はパーツの曲げシミュレーション
が、前記曲げ順における各曲げ工程についてスクリーン
上に表示される(例えば図41を見よ)。前記断面図及
び曲げシミュレーションは前記スクリーン上に選択的に
表示され、或いは曲げオペレータにより各曲げ線が選択
される時表示される。前記断面図及び曲げシミュレーシ
ョンは、例えば上下曲げ工具(例えばパンチ及びダイ)
又はバックゲージ位置・設定の表現を含み、それらは前
記2次元平面図画像と共に同時にスクリーン上に表示さ
れ或いは異なるスクリーン表示上に別個に表示される。
前記バックゲージ位置は前記パーツのトポロジーに基づ
いて自動的に決定され或いはオペレータにより設定され
或いは修正される。前記曲げ線のための工具立て情報が
入力されておらず或いは曲げオペレータにより設定され
る場合には、前記断面図及び/又は曲げシミュレーショ
ンはスクリーン上に表示されず又は前記中間パーツ形状
の表現及び計算され或いは定義されたバックゲージ位置
のみが表示される。前記曲げシミュレーションは、前記
パーツの所望の反転、前記パーツの操作及び配向動作及
び/又は各曲げ線でなされる前記パーツの曲げ加工の表
示されるシミュレーションを含む。前記表示スクリーン
上に前記パーツの2次元平面図画像と共に、曲げ工程の
前のパーツの断面図及び曲げ工程がなされた後の前記パ
ーツの断面図を同時に表示することもまた可能である
(例えば図41を見よ)。これらの断面図は、スクリー
ンの右側に提供され前記曲げ順における各曲げ工程につ
いての前記上下曲げ工具及びバックゲージの表現を含
む。更にズーム制御或いは機能キー(ZOOM IN及
びZOOM OUT)が表示され、オペレータが、前記
曲げ前及び曲げ後断面図に関連してズームの比或いは向
きを制御することを可能とする。日本公告公報平7−1
21418(丹羽等の名前で1995年12月15日に
発行)及び日本公開公報平1−309728(長沢等の
名前で1989年12月14日に発行)に開示されるそ
れと類似の技術及び手続きが前記パーツの断面図或いは
曲げシミュレーションを表示するために使用される。前
記文献の開示はここにその全体において参考により積極
的に取り込まれる。
【0305】この発明の1つの側面によれば、選択され
た曲げ線に関連して前記パーツの短い或いは小さいサイ
ドを計算することにより前記曲げについて挿入方向を自
動的に決定するためのソフトウエア或いはプログラム論
理が提供される。この発明の特徴に基づいて、各曲げ線
はそのパーツを2つのサイドに分断するために使用され
る。挿入方向は、より小さい或いは短い長さ(例えば前
記曲げ線に直交する辺の寸法)を有する前記パーツのサ
イドに基づいて或いは、より小さい全体的面積を有する
サイドに基づいて各曲げ線について決定される。もしオ
ペレータが前記選択された挿入方向に満足しない場合に
は、図39(b)に図示されるように、オペレータは挿
入方向を反転する。オペレータは挿入方向を、例えば曲
げ線が強調されている際にマウス或いはキーパッドの選
択ボタンをクリックすることにより変更し或いは反転す
る。挿入方向情報は、曲げ装置或いは機械装置で前記パ
ーツを曲げ加工するために、前記曲げ線により定義され
るフランジの挿入方向を指示するための矢印及び/又は
テキストを含む。前記挿入方向情報は、曲げ線の上或い
は近く(例えば図39(a)及び39(b)を見よ)或
いは関連するフランジの端の上或いは近く(例えば図4
0を見よ)に表示される。更に前記挿入方向情報は、各
曲げ線が選択された時に表示され或いはジョイスティッ
ク装置、マウス装置、或いはキーボード装置から受け取
った入力に基づいて選択的に表示される。
【0306】従って図形的ユーザインタフェースの使用
を介して、曲げオペレータは、種々の中間形状及び最終
パーツの形を、オペレータにより入力された選択された
曲げ順に基づいて見ることができる。再び、オペレータ
はジョイスティックインタフェース、マウスインタフェ
ース及び又はキーボードインタフェースのごとき適宜の
入力装置を通して前記スクリーン上にデータを入力し選
択することができる。曲げオペレータが提案された曲げ
順に満足しない場合には、曲げオペレータは、ステップ
S232に一般的に示されるように曲げプランを最終化
する前に曲げ順を編集する。この曲げ順の編集は種々の
やり方及び方法において実行される。特にこの発明の1
つの側面によれば、ドラッグ及びドロップ編集特性が提
供され図42に示されるようにオペレータは単に、前記
スクリーンの左側或いは右側に提供された中間的パーツ
形状アイコン或いは表示の1つをつかみ且つそれを前記
順番の所望の位置へドロップすることにより選択された
曲げ順を編集する。その後、前記曲げ順に対する曲げオ
ペレータの修正に基づいて前記スクリーン上の前記種々
の中間パーツ形状が修正され、改定された曲げ順に基づ
く中間的曲げ段階を示す。更に前記曲げオペレータの前
記曲げ順のドラッグ及びドロップ編集に基づいて、前記
2次元平面図画像上の曲げ順番号が改定される。
【0307】前記曲げ順が決定された後、オペレータ
は、ステップS236に示すように、格納された工具立
てデータのライブラリから工具を選択することによりど
のタイプの工具立てが使用されるべきであるかを決定す
る。関連する工具立て情報は、工場フロアの曲げオペレ
ータに対して表示され、曲げオペレータが前記ライブラ
リから工具立てを選択するのを図形的に支援するために
表示メニューが提供される。一旦特定の工具が前記ライ
ブラリから選択されると、前記工具に関連するデータが
スクリーン上に表示される。図43は、マニュアル工具
選択のために前記曲げオペレータに対して図形的に表示
される種々の表示メニュー及びデータテーブルの事例を
図示する。図43の例では前記曲げオペレータが前記工
具ライブラリから特定の工具を取り出すのを支援するた
めに、連続的な表示メニュー或いはスクリーン表示が図
形的に表示される。連続的に表示されるスクリーン表示
は前記表示装置上に連続的に表示され(例えばオーバー
ラップする或いはカスケードする態様で)或いはそれは
個々に表示され、そのスクリーンは次の引き続くスクリ
ーン表示が表示される前にクリアされる。一旦特定の工
具が選択されると、その工具に対する特定のデータがテ
ーブルに提供され且つオペレータに表示される。工具ラ
イブラリにおけるデータは、前記ソフトウエアの最初の
セットアップ手続きにおいて、(例えばデータベース3
0の中に)予め定義され且つ可能されている。
【0308】この発明のマニュアル工具選択特性はオペ
レータが工具タイプを選択し且つ各タイプにおいて工具
の形状を選択することを可能とする。例えば、パンチ、
ダイ、ダイホルダ、及びダイレールを含む種々の工具タ
イプが選択される。各タイプは多数の形状からなり、且
つ各形状に対して異なったサイズ及び寸法の多数の工具
が存在する。1つの工具を選択するために、ユーザは、
図43に示されるような、表示される工具タイプアイコ
ンから1つのアイコンを選択することにより1つの工具
タイプをまず特定する。その後ユーザは選択された工具
について利用できる異なる形状のメニューを提供され
る。工具形状を分析した後、ユーザは選択された工具に
ついて、表示された形状アイコンから1つの形状アイコ
ンを選択することにより工具形状を選択する(例えば図
43では、グースネック形状パンチが選択された)。最
後にユーザは選択された工具形状について適当なサイズ
及び寸法を選択する。図43に更に示されるように、選
択された工具形状に対して利用可能な工具の異なるサイ
ズ及び寸法を示すためのテーブルがユーザに対して表示
される。このテーブルから1つの項目を選択することに
より、選択された工具がアイコンとして表示され一般的
な工具タイプアイコンに置き変わり、且つ工具の選択を
確認する。
【0309】ステップS240で、曲げオペレータは次
に図形インタフェースの支援により、プレスブレーキに
おける種々の工具段階(工具ステージ)を設定する。図
44は前記曲げプランにおいて使用される工具セットア
ップ(工具取り付け)の定義を容易にするために曲げオ
ペレータに対して与えられる代表的工具セットアップウ
インドウを図示する。図44に例として示されるよう
に、種々のパンチ、ダイ及びレールのデータが前記ツー
ルセットアップウインドウに表示される。前記板金パー
ツのための工具及びダイの情報はオペレータにより入力
される。ジョイスティックが曲げオペレータのステーシ
ョンモジュールに提供され曲げオペレータが工具位置を
指示し且つ利用可能な工具及びダイのリストから工具及
びリストを選択することを可能とする。この工具セット
アップウインドウにおいてスクリーンの左側は現在の工
具セットアップの断面形状を表し、スクリーンの右側は
プレスブレーキにおける現在のセットアップの位置を表
示する。現在のセットアップの位置は図44に示される
ように強調され或いは影が付けられる。
【0310】最後にオペレータが曲げ順に満足すると前
記工具立て及び曲げシーケンスを含む曲げプラン情報
が、図37におけるステップS242に一般的に示され
るように、前記データベース30の中に前記曲げモデル
と共に保存される。前記曲げ順の実際のテストが、前記
曲げオペレータにより選択された曲げ順を確認するため
にプレスブレーキにより行なわれる。もし必要なら、前
記工具立ての定義或いは曲げ順に対する更なる修正が、
前記ステーションモジュールにおけるオペレータ或いは
デザイナーにより実行される。
【0311】この発明の種々の他の特徴は、前記曲げプ
ランの生成における前記曲げオペレータを支援するため
に設けられる。例えばこの発明の他の側面によれば、工
具立てエキスパートが設けられ、前記曲げオペレータに
対して前記曲げモデルに格納されたパーツ形状及び他の
情報に基づいて、工具立て及び曲げ順の示唆を自動的に
与える。前記工具立てエキスパートからの示唆は当該示
唆の分析の後、曲げオペレータにより改定される。更
に、より複雑な工具立てエキスパートシステムが提供さ
れ、前記曲げファイルにおける前記パーツの形状、及び
潜在的な衝突及び干渉をチェックするための工具の形状
分析に基づいて更に複雑な操作について工具立て示唆及
び曲げ順示唆を行なう。そのようなエキスパートシステ
ムは手動或いはロボットにより支援された曲げ機械装置
により使用され実行される。限定しない例として、この
発明はデービッドAボーン等の名前による「板金曲げプ
ランを生成し且つ実行するための知的システム」と題さ
れる米国特許出願第08−386.369、及びデービ
ッドAボーン等の名前による「ロボットウインドウの計
画/制御の方法」と題される米国特許出願第08−33
8.115号に開示される特徴及び教示により実行され
る。これらの開示はここに全体として参照により積極的
に取り込まれる。上記したように図形的ユーザインタフ
ェース或いは種々の機能は、板金パーツのための曲げプ
ランを生成する際に曲げオペレータを支援するために設
けられる。この発明の他の側面によれば、追加の特徴が
更に設けられ、前記パーツの設計及び製造において支援
を行なう。以下に更に十分に説明するように、音声的或
いは視覚的情報の格納のごとき種々のマルチメディア機
能が本発明において実行され前記曲げプランを生成し或
いは曲げ順を実行する際に曲げオペレータに対して追加
の支援を行なう。更に、中間の曲げ段階の各々において
前記工具及びパーツの間の潜在的干渉及び衝突を自動的
にチェックする衝突チェック機能が提供される。この衝
突チェック機能は、工具形状及び、パーツにおける間隔
の面倒で時間のかかるマニュアルチェックに置き変わる
ために提供される。前記マニュアルチェックは曲げプラ
ンを生成する際曲げオペレータにより通常行なわれる。
これらの機能及びその他のものは添付する図面を参照し
て今から説明される。
【0312】この発明の1つの側面によれば、前記曲げ
モデルデータと共に音声及び映像情報を格納するための
方法が設けられる。種々の音声及び映像情報は、工場フ
ロアにおいて記録され、例えば板金パーツの操作及び曲
げ加工に関連する特殊な指令を提供する。この目的のた
めCCDカメラ又はディジタルカメラが音声マイクロフ
ォンと共に種々の場所10,12,14,…20のステ
ーションモジュールの各々に設けられる。他の装置、例
えばオーディオマイクロフォンを有するビデオカメラが
オペレータ或いはユーザが音声或いは映像の情報を記録
することを可能とするために前記ステーションモジュー
ルに設けられる。前記種々の記録装置は工場フロアにお
けるステーションモジュールコンピュータに接続され
る。限定しない事例としてインテルのPROSHARE
個人会議CCDカメラ(インテル株式会社から入手可
能)が音声及び映像情報を記録するために使用される。
他の商業的に入手可能なCCDカメラ或いはディジタル
カメラもそのような情報を記録するために使用される。
【0313】前記曲げモデルデータと共に格納された種
々の音声及び映像情報は種々の方法及び手続きにより、
ユーザによりアクセスされ且つ読み出される。例えば格
納された音声及び映像情報を再生するために、前記ステ
ーションモジュールによりメニューオプションが表示さ
れる。更に、この発明の好適な実施例によれば、オペレ
ータは、観察ウインドウに表示されるアイコンを選択し
且つ生成することにより、格納されている音声及び映像
情報を種々の表示スクリーン及びパーツの図に付随させ
る能力を有する。この機能は、ソフトウエア及びオブジ
ェクト指向プログラム技術により実行される。これによ
りアイコンオブジェクトは曲げモデルデータ構造の中に
生成され且つ格納される。このアイコンオブジェクト
は、ある種の条件(例えばマウスのダブルクリック或い
はジョイスティック或いは他の入力手段の使用による選
択の指示によるオペレータによるアイコンの選択)に基
づいてメモリから付随された音声及び映像情報を読み出
すための手続きを含む。この発明のアイコンの特徴によ
りオペレータは異なる音声及び映像メッセージ或いは情
報を前記板金パーツの異なる部分及び任意の表示に関連
させる。このアイコンを前記パーツの表現に組み込むこ
とにより、前記アイコンは、スクリーン上で画面が変わ
るにつれて前記パーツの2次元及び/又は3次元モデル
の表示と共にズームし、回転し並進運動するように構成
される。
【0314】図45は前記パーツの3次元ソリッドモデ
ルに張り付けられたアイコンの使用を介して音声及び映
像情報を添付する事例を図示する。ユーザが前記音声及
び映像情報を記録した後、オペレータが前記3次元モデ
ルウインドウの任意の位置にアイコンを張り付ける。前
記アイコンがオペレータ或いはユーザにより次に選択さ
れる時、格納された音声及び映像情報は再生され、前記
ウインドウに表示され、そのアイコンが配置された前記
パーツのある部分或いは領域に関する特殊な指令又はメ
ッセージを提供する。他の情報、例えば前記曲げ運動の
シミュレーション或いは記録は前記パーツの種々の曲げ
線の近傍にアイコンを置くことにより前記パーツに関連
される。前記曲げ運動に関連する映像情報は次に前記ア
イコンが選択される時ユーザに対して再生される。
【0315】オペレータ或いはユーザは、音声及び映像
情報を記録し、或いは単に1つの音声メッセージ或いは
静止或いは運動映像信号を記録し、それらはユーザに対
して選択的に再生される。前記ウインドウ表示に対して
付着されたアイコンは格納された情報のタイプを図形的
に指示する(例えば、音声情報が格納されていることを
示しているためにマイクロフォンのアイコンが表示され
又は映像情報が格納されていることを示すために表示モ
ニタのアイコンが表示される)。特殊なアイコンは、そ
のアイコンに音声及び映像情報が関連されていることを
示すために設けられる(例えば「A/V」の記号或いは
マイクロフォンを含むビデオカメラのアイコン)。アイ
コンの一覧が設けられ且つ表示され、ユーザが、前記ス
クリーン表示或いは画像に対して音声及び或いは映像情
報を添付する際に種々のアイコンから選択することを可
能とする。
【0316】図46は格納された音声及び映像情報を読
み出すためのアイコンを組み込んだ表示ウインドウの他
の事例を図示する。図46に表示された表示ウインドウ
は、図42を参照して上で説明したそれのごとき、工具
セットアップスクリーン画像に関連する。図46の例で
は、音声情報が格納され、マイクロフォンのアイコンに
より読み出される。そして別個の映像情報が格納され、
前記表示ウインドウに対してビデオアイコンを張り付け
ることにより読み出される。前記音声及び映像情報は工
具セットアップ或いは操作に関連する特殊な指令或いは
情報に関連する。更に現在活性化されているウインドウ
表示のタイプに関係なく、オペレータは、異なる音声及
び映像情報を後に読み出すために、前記ウインドウ表示
における種々の領域に必要なだけ多数のアイコンを張り
付けることができる。
【0317】この発明の他の側面によれば、画像編集ウ
インドウ特性が提供され、オペレータが格納された画像
を選択しそれらを異なるスクリーンへ適用するのを容易
にする。前記画像編集ウインドウ特性はウインドウに基
づくアプリケーションとして提供され、それは例えばサ
ーバモジュール32或いは製造設備を通して設けられた
ステーションモジュールのいずれかにおいてアクセスさ
れる。図47は、この発明の教示により実行される画像
編集(イメージ編集)ウインドウの例を図示する。前記
イメージ編集ウインドウに表示される画像はディジタル
カメラ或いはCADコーダによる画像写真を含む。前記
スクリーンに表示される画像はオペレータにより(例え
ばマウス或いは他の適当なデータ入力手段により)選択
的に選ばれ、他のスクリーンにコピーされ、それらはパ
ーツの特定のモデルの図に関連させられる。オペレータ
は次にその画像或いはアイコンを前記モデルのウインド
ウ(例えば図46に関連して上で示したそれのごとき前
記パーツの3次元ソリッドモデルウインドウ)へ張り付
ける。図45、46及び47の画像は実際のスクリーン
画像の写真再生である。実際の画像イメージは、使用さ
れるカメラ或いはスクリーンの解像度に応じてそれ自体
更に明瞭である。前記画像は例えば、曲げ操作に関連す
る特殊な操作或いは他の指令を議論し或いは図示する曲
げオペレータの静止或いは運動映像イメージを含み、或
いは板金曲げ操作の映像イメージである。換言するば、
有用であると思われる実際の画像が取られ後に表示され
る。従って図45−47に示される実際の画像は例示的
な目的のためのみのものである。図48及び49を参照
するに、この発明の衝突チェック機能の例が設けてあ
る。この発明の1つの側面によれば、衝突チェック機能
が設けられ、ユーザは前記パーツ及びパンチ工具の間の
潜在的な衝突を、図形的ユーザインタフェースの使用に
よりチェックすることを可能とする。前記衝突チェック
機能はウインドウズに基づくアプリケーションであり、
前記製造設備における任意のステーションモジュール或
いは場所でアクセスされる。この発明の自動的衝突チェ
ック機能は、前記曲げプランを生成する際に通常行なわ
れている伝統的なそして面倒なマニュアルの形状チェッ
クに変わり曲げオペレータにより使用される。
【0318】伝統的には、板金パーツの曲げプランを生
成する際、曲げオペレータはまず前記パーツの曲げ順を
決定する。前記曲げ順は前記板金パーツが製造の間に曲
げられる順番或いは態様を決定する。その曲げ順が決定
された後、曲げオペレータはその曲げ操作の各々を実行
するために使用される工具を選択し定義する。この過程
で、選択された前記工具の形状及び前記パーツの中間的
形状が、前記曲げ工程の各々を実行する際に前記工具と
パーツとの間の干渉あるいは衝突が存在しないことを確
実にするために解析される。衝突或いは干渉が検出され
る場合には、選択された工具のタイプ(或いは必要に応
じて曲げ順)は、前記工具と板金パーツとの間の干渉或
いは衝突を生ずることなく曲げ操作が実行されるように
修正されなければならない。
【0319】潜在的な衝突或いは干渉を検出する際に、
前記工具の形状と板金要素の曲げられた部分或いは形状
との間のクリアランスを分析するために、曲げオペレー
タは伝統的にマニュアルの方法に頼っていた。典型的に
は、曲げオペレータにより工具形状のモデルが構成され
使用されている。工具形状モデルは、板金の種々の中間
的形状の工学的或いは技術的図面(前記工具形状モデル
と同じスケールの寸法を有する)に対してマニュアルで
合わせられ或いはその上に置かれる。この工具形状モデ
ルを前記パーツの図面に対して適合させ及び合わせるこ
とにより前記曲げオペレータは、曲げ工程の各々におい
て工具とパーツとの間に十分な空間或いはクリアランス
があるかどうかを決定することができる。しかしながら
この工程は面倒で且つ時間を浪費する傾向がある。
【0320】この発明は自動的干渉チェック機能を設け
ることにより、そのような伝統的な方法の不利益を克服
することである。この発明の干渉チェック機能は、図形
的ユーザインタフェースを介して実行され、曲げオペレ
ータが所定の曲げ順における各中間的工程において衝突
をチェックするのを可能とする。図48及び49は図形
的ユーザインタフェースを介して実行される衝突チェッ
ク機能の例を図示する。活性化される時、前記衝突チェ
ック機能は前記曲げ順における前記パーツの各中間的形
状とその順番に対して定義されるパンチ工具或いは複数
の工具との間の衝突を自動的にチェックする。前記中間
形状はスクリーンに表示され(例えば図48及び49を
見よ)、衝突が発見されると、当該衝突が検出される工
程がスクリーン上に強調される。更にテキストのごとき
他の表示示唆が検出された衝突の数を指示するために提
供される。図48及び49の例では、前記衝突情報は表
示ウインドウの右上領域に提供される。更に、前記衝突
がチェックされたパンチ工具或いは複数の工具のタイプ
は表示ウインドウの左上領域に表示され或いは指示され
る。
【0321】衝突が、オペレータにより選択されたパン
チ工具について検出される時、衝突が検出される中間的
形状或いは段階がスクリーン上に強調される。この場
合、オペレータはその特定の曲げ段階について他のパン
チ工具を選択することもでき、前記パンチ工具の第2の
選択について衝突が起きるか否か決定するために前記衝
突チェック機能が再び実行される。オペレータは、各曲
げについてパンチ工具を選択し、前記衝突チェック機能
により衝突をチェックすることができる。ドラッグ及び
ドロップ編集が、中間的曲げ形状をドラッグし、それを
前記提案された曲げ順内の所望の位置へドロップするこ
とにより、前記ウインドウ表示中に表示された曲げ順を
オペレータが変更することを可能とするように設けられ
てもよい。前記曲げ順は図44を参照して上に記載した
それと同様の対応で、オペレータによりなされた前記ド
ラッグ及びドロップ編集に基づいて修正される。
【0322】この発明の衝突チェック機能を実行するた
めに種々の手続き及び操作が使用される。例えば潜在的
な衝突を検出するために、選択された工具の幾何形状と
中間的形状におけるパーツの幾何形状とがアクセスされ
る。各中間工程における前記パーツに関連する幾何形状
データは前記曲げ順及びパーツ寸法及びトポロジーデー
タに基づいて生成される。前記パーツの各フランジは、
前記曲げ順における各中間段階における前記パーツを表
示するために、曲げデータ(例えば曲げ角度、曲げ線位
置、縮小量等)に応じて折り曲げられる。上記折り曲げ
工程及びこの発明の縮小量補償特性は各中間段階での前
記パーツに対する幾何形状データを生成する際に適用さ
れる。この工具及びパーツの幾何形状により、前記曲げ
段階の各々において前記工具の先端をパーツの曲げ線へ
置くことにより、前記工具及びパーツが相互に配向され
る。衝突は、前記幾何学的データ及び前記工具とパーツ
との境界を分析し、前記工具及びパーツにおいて共通な
点或いは重なり合う点が存在するか否かを決定すること
により検出される。衝突は、特定の曲げ工程で検出され
る時、その工程は、ユーザに対して衝突の検出を示すた
めにスクリーン上で強調される。衝突を検出するために
使用される工具データは、ユーザによりなされる工具選
択に基づいて、工具形状ライブラリから積極的に取り出
される。任意の中間曲げ工程での衝突の再計算は異なる
工具形状或いは曲げ順の修正に基づいて行なわれる。そ
のような機能を設け、ここに記載されるごとき、図形的
ユーザインタファースを用いてそのような情報を表示す
ることにより、衝突の可能性は、曲げオペレータによ
り、より容易に決定され且つ修正される。
【0323】上記したように、ジョイスティック或いは
マウス装置は、板金パーツの表示されるモデルを観察す
る際、ユーザが選択的に種々の観察機能(例えばズー
ム、パン、回転等)を活性化し及び制御することを可能
とするために、前記製造設備を通して前記ステーション
モジュールの各々及びそれらの場所に設けられる。前記
ジョイスティック装置は多重の軸を有するジョイスティ
ックで、選択或いは制御ボタンを有する。前記ジョイス
ティックはマイクロソフト・サイドワインダ・ジョイス
ティックを含む種々の商業的に入手可能なジョイスティ
ック装置を介して実行され、各ステーションモジュール
及び/又は当該設備の他の位置のコンピュータのゲーム
ポートに差し込まれる。前記マウスはまたウンドウズ9
5或いはウインドウズNTのごとき任意の商業的に入手
可能なマウスをサポートするソフトウエア及び、各設備
位置におけるコンピュータのゲームポート或いはマウス
ポートに差し込まれる任意の商業的に入手可能なマウス
装置により実行される。
【0324】限定しない事例として図50−55は、ジ
ョイスティック装置或いはマウス装置を用いて、3次元
幾何学的形状を操作し且つ前記パーツを表示するための
システムの種々の側面を図示する。この発明の3次元ナ
ビゲーションシステムは、ユーザが回転、ズーミング及
びパンニングのごとき種々の観察機能を制御することを
可能とする。この発明の1つの側面によれば、システム
はまた3次元モデルを観察する際に、現在のズーム画像
に基づいて計算される動力学的回転軸を用いる。この側
面によれば、回転の中心は現在の図及びズーム比或いは
係数に基づいて動力学的に変化され且つ計算され、従っ
て前記パーツのズームされた領域は前記パーツが例えば
高いズーム比或いは係数において回転される時、前記ス
クリーンから消えることがない。
【0325】この発明の1つの側面によれば、3次元操
作及びナビゲーションシステムが前記設備のステーショ
ンモジュール及び/又はサーバモジュールに提供され
る。3次元ナビゲーションシステムの工程及び操作は、
ソフトウエア或いはプログラムされた論理を介して且つ
広い範囲のプログラム言語及び教示の1つを用いて実行
される。例えば前記システムはC++のごとき高レベル
のプログラム言語を用いて且つオブジェクト指向プログ
ラム技術を用いて実行される。更に限定しない例とし
て、VISUAL C++が使用される。それはウィン
ドウズに基づくアプリケーションのためにマイクロソフ
ト株式会社により提供されるC++プログラム言語の1
つのバージョンである。前記観察機能(例えばズーム、
回転、パン等)は上記した本発明の曲げモデルビューア
の観察クラスの要素機能として実行される(例えば図2
7及び上記関連の開示を見よ)。前記現在ズーム係数及
びパーツの位置(例えば3次元空間におけるパーツの位
置)に関する情報は、また、前記動力学的回転軸を計算
し且つ所望の観察機能を提供するために前記曲げモデル
ビューアからアクセスされる。
【0326】種々のハードウエア成分及びインタフェー
スが、本発明の3次元ナビゲーションシステムを実行す
るために提供される。例えばシステムを実行するために
使用されるソフトウエアが前記ステーションモジュール
及びサーバモジュールのコンピュータ或いはパーソナル
コンピュータに設けて有り或いは存在する。上で議論し
たように、前記コンピュータ或いはパーソナルコンピュ
ータは、板金パーツの3次元表示をユーザに対して表示
するために、高解像度モニタのごとき図形カード及び表
示スクリーン或いはターミナルを含む。前記コンピュー
タ或いはパーソナルコンピュータはまた、前記マウス或
いはジョイスティック装置と接続し及びインタフェース
するためのマウス或いはゲームポートアダプタを含む。
商業的に入手可能なソフトウエアも設けられており、ユ
ーザにより操作されるマウス或いはジョイスティック装
置からマウス或いはゲームアダプタカードにより受信さ
れる指令信号を解釈する。
【0327】図50a及び50bは、例えば単純な3次
元箱形状パーツを回転するために多重軸ジョイスティッ
ク112により行われる回転機能の例を図示する。上に
述べたように、ジョイスティックは設備を通して設けら
れているステーションモジュール及び/又はサーバモジ
ュールに設けられているコンピュータ或いは装置に設け
られ且つ接続されている。図50a及び50bに示すよ
うに、前記パーツの回転は、前記ジョイスティック11
2を前後に且つ左右に移動することにより行なわれる。
前記回転軸の方向或いは向きは前記ジョイスティック1
12(或いはマウス)の移動に基づいて設定される。例
えば前記ジョイスティック112を前後に移動させるこ
とは、パーツを前記X座標軸に沿って定義される回転軸
の周りに時計方向或いは反時計方向に回転させることを
もたらす(例えば図50aを見よ)。更に前記ジョイス
ティック112を左右に動かすことは、前記パーツを前
記Y座標軸に沿って定義される回転軸を中心として時計
方向或いは反時計方向に回転させることをもたらす(例
えば図50bを見よ)。
【0328】現在の図のズーム比或いは係数が低く、パ
ーツの全体表示がスクリーン上に提供される時、前記回
転軸は前記パーツの幾何学的中心或いは図芯を通るよう
に定義される。上記したように、前記ズーム係数及びス
クリーン上のパーツの観察可能性は、本発明の曲げモデ
ルビューアにより提供される観察可能性機能に基づいて
決定される。スクリーン上にパーツ全体が表示されると
判断される時(図50a及び50bにおけるそれのよう
に)、回転軸を定義しそしてその回転軸を前記パーツの
幾何学中心へ設定するために座標幾何技術が用いられ
る。前記パーツの回転は、次に、前記ジョイスティック
装置のユーザにより定義された移動に基づき、且つこの
発明の曲げモデルビューアの回転要素観察機能を介して
実行される。しかし仮に前記オブジェクトの一部のみが
画面に表示され、前記パーツの幾つかの部分は見えない
場合(例えば高いズーム係数或いは比率が選択された
時)、前記回転軸は、前記パーツの幾何学中心或いは図
芯に維持されるべきではない。それはそのようにするこ
とは、回転中に前記パーツのズーム化された部分がスク
リーンから消えるからである。実際この発明によれば、
ズーム比が増大される時、回転軸は動力学的に再計算さ
れ、前記スクリーンのセンターにおける観察点(或いは
カメラ視野)に最も近い点の座標を通る。前記ズーム係
数の変化に基づいて、前記回転軸を動力学的に再計算す
ることにより、前記パーツは、前記パーツの観察可能な
部分が回転の間に画面からはみ出すことにならない軸を
中心として回転される。
【0329】前記3次元モデルのズーミング及びパンニ
ングを行なうために、前記ジョイスティック或いはマウ
ス装置と別個に或いはそれと共に設けられたキーパッド
に追加の制御ボタンが設けられる。例えばズームボタン
114を押すと共に、ジョイスティック112を前後に
移動することにより、図51に示すように、所定の割合
で前記パーツはズームインまたはズームアウトされる。
上記したように、前記回転軸は各ズームウィンドウの中
で再計算され、回転がなされる時、ユーザが前記パーツ
のズーム化された部分を観察することができるようにす
る。更に、3次元形状のパンニングは、図52に示すよ
うに、パンボタン116を押圧し或いは活性化し且つジ
ョイスティック112を移動することにより、ユーザに
より制御される。前記ズームボタン114の場合と同様
に、パンボタン116は前記設備の種々の位置の各々に
おける前記ジョイスティックまたはマウス装置と別個に
或いはそれらと一緒に設けられたディジタル入力パッド
の上に設けてある。
【0330】この発明の代表的な実施例に応じて、前記
3次元ナビゲーション及び操作を実行するために設けら
れた種々の工程及び操作が図53−55を参照して以下
に記載される。上に示したように、前記3次元ナビゲー
ションシステムの必要な工程及び操作はソフトウエア或
いはプログラムロジック及びハードウエア成分及びイン
タフェースの組み合わせを介して実行される。ジョイス
ティック或いはマウス装置のごときユーザにより制御さ
れる装置からの入力信号は所望の表示されたパーツの運
動及び再配向の量を決めるように解釈される。この発明
によれば、表示されたパーツの回転軸は、回転中にパー
ツのズーム化された領域が画面から消えるのを防止する
ため、現在の画面及びズーム係数に基づいて動力学的に
計算される。
【0331】表示されたパーツの現在の画面を更新する
際に、図53のステップS301に一般的に示されるよ
うに、前記ジョイスティック或いはマウス装置の操作に
基づいてユーザからの信号が受信される。ユーザにより
前記ジョイスティック或いはマウス装置の特定の方向の
運動及び/又は特殊な制御ボタンの活性化との組み合わ
せが、所定の観察機能(例えば回転、ズーム、パン等)
及び表示されたパーツの所定の方向(例えば時計回り或
いは反時計回り、ズームイン又はズームアウト、右又は
左等)の運動を、図50−52に例えば示されるよう
に、引き起こす。受信された信号は、それらがジョイス
ティックからであるかマウス装置であるかを問わず、カ
ーソルの移動に写像され、ユーザにより所望されるスク
リーン上の移動量を決定する。ユーザが前記観察機能モ
ードのうちの1つに存在しない場合(例えばユーザがス
クリーン上の情報を選択しているか或いはダイアログボ
ックス或いはウィンドウ内の情報を観察している場
合)、前記受信した信号の写像は要求されない。
【0332】当業者により理解されるように、通常のジ
ョイスティック或いはマウス装置から受信される信号は
スクリーン空間のそれとは異なる座標或いは参照システ
ムに基づいており、従ってそれらは前記スクリーン上の
カーソル移動に関する意味のある情報を提供するために
翻訳されなければならない。従って前記ユーザからの入
力信号を受け取った後、ステップS303に示されるよ
うに、回転軸の計算及び表示されたパーツの現在の図を
更新する前に受信された信号はカーソル移動に写像され
る。
【0333】ユーザにより制御される装置からの入力信
号をスクリーン空間上のカーソル運動に翻訳及び写像す
るために異なる方法及び工程が使用される。伝統的に
は、マウス装置の移動は、商業的に入手可能なソフトウ
エアによりカーソル移動へ翻訳され且つ写像されてい
た。例えばウィンドウズ95及びウィンドウズNTは、
マウス移動をカーソル移動へ翻訳するためのソフトウエ
アルーチンを含む。従って、マウス装置の移動は、その
ような商業的に入手可能なソフトウエアによりカーソル
移動に写像される。しかしながらユーザにジョイスティ
ックインタフェースが与えられている場合、有用な情報
を提供するには、前記ジョイスティック運動もカーソル
運動へ翻訳され且つ写像されなければならない。前記ジ
ョイスティック仮想空間におけるジョイスティックの運
動をスクリーン空間におけるカーソル運動へ写像するた
めに種々の方法及び技術が使用される。例えば、ジョイ
スティックの移動信号は、最終的にカーソル運動へ写像
される前に、まずマウス運動へ加工され且つ翻訳され
る。或いは、前記ジョイスティック仮想空間のサイズに
対するスクリーン空間のサイズの比率の関数として、前
記ジョイスティック信号は直接カーソル運動へ写像され
る。
【0334】図54は、この発明の1つの側面に基づ
く、ジョイスティック運動のスクリーン空間内でのカー
ソル運動への写像の例を図示する。上に示したように、
ジョイスティック装置は自身の仮想的座標システム或い
は空間218を含む。前記ジョイスティック仮想空間2
18は、前記ジョイスティックが中心或いは中立位置
(即ちジョイスティックが移動しない位置)に存在する
位置に対応する原点J1を含む。前記ジョイスティック
が新しい位置(例えば図54に示されるように現在の位
置J2)へ移動する時、前記ジョイスティック装置は前
記ジョイスティックの仮想空間内での新しい或いは現在
の位置を示す信号を生成する。前記ジョイスティック仮
想空間218は、しばしばスクリーン空間212よりも
大きい(画素の意味で)ので、前記ジョイスティックの
仮想座標及び移動は、所望のカーソル移動従ってスクリ
ーン上でのパーツの移動を決定するためにスクリーン座
標へ翻訳されなければならない。
【0335】前記ジョイスティックの仮想座標移動をス
クリーン座標移動へ写像し且つ翻訳するために種々の方
法及び工程が使用される。例えば、前記ジョイスティッ
ク仮想空間サイズに対するスクリーン空間サイズの比率
に基づいて、ジョイスティック運動はスクリーンカーソ
ル運動へ写像される。より詳細には、観察機能モード
(例えばズーム、回転、パン等)が活性化され、ジョイ
スティック装置がユーザにより操作された時、前回の点
C1から現在の点C2へのカーソルの実際の移動は次の
式で決定される。
【0336】 現在の点=前回の点+(スケール係数x V) ここに「現在の点」はカーソルの現在の点C2であり、
「前回の点」は前記カーソルの前回の点C1であり、
「スケール係数」はジョイスティック仮想空間サイズに
対するスクリーンサイズの比であり(いずれも画素にお
いて)、「V」はジョイスティック原点J1からジョイ
スティック現在位置J2へのジョイスティックの運動及
び方向を表すベクトルである。従ってジョイスティック
運動をカーソル運動へ写像するために、ジョイスティッ
ク装置がユーザにより操作される時ジョイスティック装
置から受け取られる信号に基づいて、前記原点J1から
現在位置J2へのジョイスティックの方向及び運動を示
すベクトル「V」が最初に計算される。このベクトル
「V」が計算された後、前記ジョイスティック運動は、
前記方程式における前記ベクトル「V」量及び前記「ス
ケール係数」量を用いてカーソル運動へ写像される。即
ち、前記カーソルの新しい或いは現在の位置C2は、前
記ベクトル「V」に前記ジョイスティック空間サイズに
対するスクリーンサイズの比(即ちスケール係数)を掛
け合わせ、次にこの計算の結果を以前のカーソル位置C
1に足し合わせることにより計算される。
【0337】前記スケール係数に応じて、前記スケール
或いは運動の割合を所定の或いはユーザにより選択され
た調整係数だけ増大し又は減少することが必要となる。
そのような場合には、そしてユーザの好みにより、前記
スケールの割合を増大し又は減少するために、前記カー
ソルの現在位置を計算する時に、前記スケール係数に調
整係数が掛けられる。例えば、前記ジョイスティック空
間サイズに対するスクリーンサイズの割合がスケール係
数1/64を与える場合、ジョイスティックの運動とス
クリーン上の表示されたパーツの運動の割合との間の一
層満足できる関係を与えるために、スケールの割合を増
大するのが望ましい。限定的でない例として、スケール
係数1/64について、前記表示されたパーツをズーム
し或いは回転する際調整係数3が用いられる。更にスケ
ール係数1/64について、表示されたパーツのパンニ
ングが行なわれる際には調整係数6が使用される。勿
論、スケーリング(縮尺)の割合は、ユーザの特定の必
要に基づいて修正され、前記調整係数は予め決定され或
いはユーザが、前記スケールの割合を修正するための調
整係数を調整或いは選択するためにオプションを与え
る。更に上に議論した事例において示したように、前記
調整係数は複数の観察機能の各々について同じ量に設定
されてもよいし、前記観察機能の各々について、同じ或
いは異なる量に個別に設定されてもよい。
【0338】受信された信号が適当に写像され翻訳され
た後、前記パーツの回転軸が、図53のステップS30
5に一般的に示されるように動力学的に計算される。前
記パーツの現在の図に依存して、前記パーツが例えば高
いズーム比率或いはファクターで回転される時、前記パ
ーツのズーム化された領域がスクリーンから消えないよ
うに、前記回転軸は前記パーツの中心を通るか或いは他
の点を通るか決定される。現在のズーム図に基づいて、
前記パーツの回転軸を動力学的に再計算するために種々
の方法及び工程が使用される。この発明の他の側面に応
じて、図55は前記パーツの図がユーザにより修正され
た時常に前記回転軸を計算するために行なわれるプロセ
ス及び工程の代表的論理フロー及び手順を図示する。
【0339】図55に示されるように、現在のズーム係
数或いは比率及びパーツの位置及び現在の図がステップ
S311及びS313で決定される。ユーザにより選択
された表示パーツのズーム係数及び向きが、パーツ全体
をスクリーン上で観察可能にする(即ち全体図)か、或
いは前記パーツの一部のみをスクリーン上で観察可能に
する(即ち部分図)。従って現在のズーム係数及びパー
ツの向きが、表示パーツの回転軸を適正に設定するため
に定められなければならない。前記パーツの現在の図を
決定するために種々の方法及び工程が使用される。上に
記載したように、観察可能性機能は、本発明の曲げモデ
ルビューアを備え、表示される画像に対する変更が存在
する場合には何時も、現在の図の向き及びズーム比率の
状態を維持しそして更新する。前記曲げモデルビューア
に対する機能コールがなされ、前記パーツのどの点或い
は部分が現在観察可能であるかを決定する。スクリーン
上に前記パーツの全てが表示されているかどうかは画像
体積をパーツの境界基本線サイズと比較することにより
決定される。
【0340】ステップS315でパーツの全体図が現在
スクリーン上で観察可能であると決定される場合には、
ステップS317で前記回転軸は前記パーツの中心を通
るように設定される。全体図が存在する時、前記パーツ
の中心を前記回転軸が通るように設定することは可能で
ある。というのは全体が表示されたパーツはユーザによ
り回転される時スクリーン上で観察可能であるからであ
る。スクリーン上で全てのパーツが観察可能である時、
回転軸はパーツの幾何学中心或いは図芯を取るように定
義される。従来の座標幾何学技術が、前記パーツの幾何
学中心へ前記回転軸を定義し設定するために用いられ
る。更に前記回転軸の方向は、前記前回のカーソル位置
から現在のカーソル位置へのベクトルに直交するベクト
ルとして定義されることもできる。
【0341】ステップS315で、スクリーン上にパー
ツの部分図のみが現在観察可能であると判断される場
合、ズーム化されたパーツがユーザにより回転される時
表示されたパーツの一部がスクリーンから消えないよう
にするために、回転軸を計算するために、前記論理フロ
ーはステップS319−S325へ引き続く。上記した
ように、ユーザにより高いズーム係数が選択され前記パ
ーツの一部のみがスクリーン上に表示される時、前記回
転軸は、前記パーツの幾何学中心を通るように設定され
てはならない。というのは、そのようにすることは、回
転中に表示されたパーツのズーム化された部分(ズーム
アップされた部分)がスクリーンから消えるからであ
る。パーツの表示された部分がスクリーンから見えなく
なり或いは消えることを防止するために、スクリーンの
中心における観察点(即ちカメラ)に最も近い点の座標
を前記回転軸が通るようにされなければならない。その
ような場合、回転軸の向きは前回のカーソル位置から今
回のカーソル位置へのベクトルに直交するベクトルとし
て定義されても良い。
【0342】従ってステップS319で、スクリーンの
中心が決定され、カメラに最も近いスクリーンの中心に
おけるオブジェクト或いは前記パーツの部分が選択され
る。即ち、スクリーンのセンターに位置する表示パーツ
の部分及びカメラに最も近い或いはスクリーンのユーザ
の観察点に最も近い表示パーツの部分が取り出される。
ステップS321で、前記カメラにおけるオブジェクト
が存在すること(例えば前記スクリーンの中心に位置し
且つ前記カメラに最も近い前記パーツのソリッド部分が
存在すること)が決定される場合、ステップS325で
前記回転軸は前記取り出された点を通るように設定され
る。上記したように、回転軸の方向は前回のカーソル位
置から今回のカーソル位置へのベクトルに直交するベク
トルとして定義されても良い。
【0343】ステップS321でカメラにおけるオブジ
ェクトが存在しない(例えば前記パーツは前記スクリー
ンの中心に位置し且つ前記カメラに最も近い穴或いは開
口部を含む)と判断される場合、論理フローはステップ
S323へ引き続く。ステップS323で、前記回転軸
は前記スクリーンの中心(例えば前記スクリーンの物理
的中心のX及びY座標)を通り且つ前記パーツの幾何学
中心に等しいZ座標(深さ)にあるように定義される。
従って回転軸は前記X,Y,Z座標を通るように設定さ
れ、回転軸の向きは前回のカーソル位置から今回のカー
ソル位置へのベクトルに直交するベクトルとして定義さ
れても良い。
【0344】図53を再び参照するに、前記動力学的回
転軸が決定された後、選択された観察機能(例えばズー
ム、回転、パン等)がステップS307で呼び出され
る。上記したように3次元操作システムの種々の観察機
能は前記曲げモデルビューア観察クラスの要素機能とし
て定義され実行される(例えば図27及び関連する上記
開示を見よ)。そのような場合、ユーザにより選択され
た観察機能に基づいて、機能コールが前記曲げモデルビ
ューアになされ、ステップS309で表示されたパーツ
の現在の図が更新される。前記パーツの現在の図及び向
きは、ユーザにより選択された観察機能及びユーザによ
り操作された入力装置(マウス或いはジョイスティック
装置)からの受信された写像カーソル運動に基づいて更
新される。オープンGL或いはレンダウェアのごときグ
ラフィックパッケージが、ユーザに提供される現在の図
の更新を容易にするために提供される。図53及び55
の代表的フローチャートにおいて行なわれる論理フロー
及びプロセスはソフトウエアにより及び広い種類のプロ
グラム言語及び技術を用いて実行される。例えばオブジ
ェクト指向プログラム技術及びC++が前記プロセス或
いは操作を実行するために使用される。この発明の3次
元操作システムを実行するための代表的コードが付録L
に提供される。代表的コードはC++プログラム言語で
書かれ、前記動力学的回転軸を計算するための種々の工
程及び操作を含む。付録Lのコードにはコメントが提供
され、そこに使用される論理及びアルゴリズムの解析を
容易にする。
【0345】上記3次元操作システムはジョイスティッ
ク装置及び制御ボタンの使用に関して記載されている
が、このシステムは、マウス或いはキーボードを含む他
の特定のタイプの入力手段により実行されることもでき
る。更に図51−52の上記実施例では、前記オブジェ
クトのスクリーンから無限への又はその反対のズーミン
グ或いはパンニングを制限するために境界が定義され
る。というのは連続的なズーミング或いはパンニングは
システムを故障させ或いは破壊させるからである。
【0346】更に、前記ジョイスティックインタフェー
スに関連して種々の他の機能が実行される。例えば、前
記観察機能のいずれかにおける移動は、ジョイスティッ
クがジョイスティックセンター位置から所定の範囲或い
は距離を越えて移動されなければ実行されない。パーツ
の移動が許される前にそのようなジョイスティックの移
動のしきい値を要求することは、前記中心点からの前記
ジョイスティックの不注意な操作或いは押圧に基づい
て、表示されたパーツの偶然の移動の発生を防止する。
ユーザとのジョイスティックインタフェース及びシステ
ム相互作用を改善するために他の機能がまた設けられ
る。例えばユーザによるジョイスティックの単一の操作
に基づいて、前記観察機能(例えばズーム、回転、パン
等)のいずれか1つにおける連続的或いは増加的(例え
ばステップごと)の移動が提供される。前記連続的或い
は増加的移動の選択はまた単一の方向におけるジョイス
ティックの移動の量或いは時間に基づいて提供される。
必要ならば表示されるパーツのスケール或いは移動の割
合は、任意の方向におけるジョイスティックの運動の程
度或いは時間に基づいて増加される。上記した速度調整
係数の修正はまた、ユーザが前記スケールの比率を増加
し或いは減少するために、マニュアルで調整係数に対す
る補正を入力することを可能とすることにより実行され
る。
【0347】工場における部品の設計及び製造における
支援を行なうために、本発明において種々の他の機能及
び実施例が実行される。例えば各顧客のオーダに関する
情報を追跡し且つアクセスするためにバーコードシステ
ムが実行される。所定の参照番号或いは作業番号を有す
るバーコードが顧客により注文される各部品へ割り当て
られる。このバーコードはデータベース30にアクセス
し作業情報を読み取るために用いられる。ユタ、サンデ
ィにおけるゼブラテクノロジVTIからのバーコード・
エニシング・バーコードSCAN CCDセンサのごと
きバーコードリーダ或いはスキャナが各場所に設けら
れ、ユーザが前記サーバモジュール或いはステーション
モジュールにおいて所定の作業のためのバーコードをス
キャンすることを可能にし、またデータベース30に格
納されているそのパーツに付随する重要な設計及び製造
情報をアクセスし読み出すことを可能にする。前記バー
コードリーダは各ステーションモジュール及び/或いは
サーバモジュールのコンピュータに差し込まれている。
前記バーコードは任意の通常のバーコードフォーマット
に基づいてフォーマット化されている。例えばUPS−
A CODA BARCODE39 EAN/JAN−
8或いはPLESSEYである。そして結果としてのバ
ーコードナンバーはルックアップテーブルに基づいて翻
訳され、前記データベースから作業情報を読み出すため
に、対応する作業参照番号及び/又はファイル名を検出
する。或いは、前記作業番号は、工場全体にわたって存
在する任意のステーションにおいて表示される指示へタ
イプ入力され或いはそこから選択され、瞬時にユーザの
位置で作業情報を読み出し表示する。そのような情報を
瞬時に読み出す能力は、コミュニケーションネットワー
ク26の使用及びデータベース30のごとき中央に位置
するデータベースへの前記デザイン及び情報の格納によ
り支援される。
【0348】この発明の更に他の側面によれば、作業を
スケジュールし割り当てるための装置及び方法が提案さ
れるシステムに設けられる。従来、製造設備にわたる作
業のスケジュール化及び割り当てはショップ或いは工場
の工場長により行なわれた。工場長は、機械装置の現在
のセットアップ及び利用可能性のみならず現在の仕事の
状態を決定する。これらの情報を集め且つ分析した後、
ショップ或いは工場の工場長はスケジュールを生成し且
つ工場における種々の場所においてなされる作業につい
て割り当てを分配する(例えば工場フロアに分配される
作業スケジュールシートの形態で)。作業のスケジュー
ル割り当ては、各顧客の作業がタイミングの良い形態で
且つ所定の出荷日までに完了することを確実にするため
に行なわれる。作業のスケジュール化及び割り当ての従
来の工程はしかし骨の折れるものであり、通常工場長に
よりマニュアルで行なわれていた。
【0349】この発明の1つの側面によれば、ショップ
或いは工場の工場長がその工場についての作業のスケジ
ュールを立てることを支援するために、作業割り当て及
びスケジュールシステムが設けられている。そのシステ
ムはコミュニケーションネットワーク及びデータベース
30に格納されている曲げモデル情報を利用し、自動的
に必要な情報を集め、従って工場長はより容易に作業ス
ケジュールを生成することができる。このシステムは、
前記サーバモジュール或いは工場にわたって配置されて
いるステーションモジュールにおいてソフトウエア又は
プログラムロジックを介して実行される。スケジュール
されるべき種々の作業を入力することにより、システム
ソフトウエアはデザイン及びパーツ情報を分析し所定の
作業を行なうためにどの機械が最も適しているかを決定
する。この目的のため、工場における機械の現在の状態
及びセットアップが定義され、データベース30に格納
され、作業スケジュールソフトウエアによりアクセスさ
れる。種々の条件に基づいて、表示の形態で、特定の作
業を実行するためにどの機械が利用可能であるか及びど
の機械が他の仕事を実行することができないかを示唆す
る。この点について、特定の作業について機械の利用可
能性をランク付けし且つ提案作業スケジュールを提供す
るテーブルが表示される。前記提案作業スケジュールは
工場長により実行され或いは修正される。作業スケジュ
ールを設定し且つ推薦するために使用される条件は広い
種類の条件を含む。そしてそれは、工場における各マシ
ンの現在のセットアップ、各作業について必要とされる
曲げのタイプ及び工具、及び同じ時間枠或いは時間の間
に実行されなければならない他のタイプの作業を含む。
どの機械が特定の作業を実行できるかを決定するため
に、前記曲げ角度、フランジ長さ及び曲げのタイプを含
む各パーツについての曲げモデルファイルからの情報が
利用される。例えばデータベース30に格納されている
テーブルは前記工場フロアにおけるパンチング及び曲げ
機械の各々の現在のセットアップ及び能力についての重
要な情報を含む。
【0350】提案された作業スケジュールに基づいて、
工場長は、工場の生産及び出力能力を最大限にするため
に、複数の作業を工場全体にわたる種々の場所へ割り当
てる。最後の作業スケジュール或いは割り当ては電子的
に入力されコミュニケーションネットワーク26を介し
て機械の各々へ送られる。
【0351】LEDのごときパイロットランプが曲げ及
び機械装置ワークステーションの各々に設けられ、その
ステーションに作業が割り当てられ転送されたことを指
示し且つ確認する。前記作業割り当て及びスケジュール
は、工場内の任意の位置から瞬時にアクセス可能なサー
バモジュールのファイルに格納される。上記機能に加え
て、その他の機能が、この発明の教示に応じて実行され
る。例えば種々のステーションモジュール或いは位置に
メニュースクリーンが設けられ且つ表示され、ユーザが
この発明の種々の表示及び機能モードを選択するのを容
易にする。例えば図56に示されるそれのごときメイン
のメニュースクリーンが、前記ステーションモジュール
が開始される際にユーザに対して提供される。このメイ
ンメニューウインドウ表示はステーションモジュールに
より提供される利用可能なウインドウ表示及び観察モー
ドの各々のアイコン画像を含む。このメインメニュース
クリーンはメニューボタン(例えばF1キー)が選択さ
れるとき何時でも現れる。ユーザは、強調されたブロッ
クを所望のウインドウアイコンへ移動しそれを選択する
ことによりそのウインドウを選択する。そのような操作
は、キーボード、マウス或いはジョイスティックの使用
を介して行なわれる。
【0352】他のウインドウスクリーンもユーザに対し
て提供され且つ表示され作業情報の入力及び表示を容易
にする。例えばパーツ情報ウインドウは、ユーザがパー
ツ情報を入力し或いは修正するのを可能にするために表
示される。パーツ情報ウインドウ表示の例が図57に与
えられる。このパーツ情報ウインドウは全ての関連する
パーツ情報(例えばパーツ番号、材料タイプ、寸法等)
を含み、板金パーツの2次元平面図及び等測投影法図を
含む。曲げ線情報ウインドウ(例えば図58に示される
もの)は、ユーザが各曲げ線についての曲げ順及び縮小
量を含む種々の曲げ線情報を監視することを可能とする
ために設けられる。前記曲げ線情報ウインドウはユーザ
が、各曲げについての曲げ線情報を入力し或いは修正す
るのを可能とし、板金パーツの2次元平面図及び等測投
影図を含む。
【0353】オペレータの曲げ順の分析を容易にするた
めに、追加のウインドウ表示が提供される。例えば曲げ
順ウインドウ表示及び曲げシミュレーションウインドウ
表示が提供され、前記パーツの種々の曲げ段階を表示
し、且つ曲げ操作中におけるパーツの向きをシミュレー
トする。図59に示されるような曲げ順ウインドウは前
記メインメニュースクリーンから選択され曲げ順の各段
階における前記パーツの(静止状態における)中間形状
をユーザに対して表示する。曲げシミュレーションウイ
ンドウ(例えば図60を見よ)もユーザにより選択さ
れ、曲げ段階の静止情報(スクリーンの右側に提供され
るパーツアイコンの形態で)及び、曲げ順における各段
階で行なわれる位置付け及び曲げの動的シミュレーショ
ン(表示装置の中央において)を提供する。スクリーン
上のパーツアイコンを間欠的に選択することにより、ユ
ーザは選択されたパーツアイコンにより表現される段階
における、曲げ加工中でのパーツの向きの動的シミュレ
ーションを見ることができる。各曲げ順を動的にシミュ
レートするために、パーツは反転され、並進移動され、
曲げ線の周りで曲げられ/回転される。
【0354】図57−60の上記ウインドウ表示の各々
は、図56のメインメニューウインドウ表示からユーザ
に対して選択され且つ表示される。更に、任意のステー
ションモジュールにおけるユーザは、メインメニューウ
インドウ表示において適宜のウインドウアイコンを選択
し、この発明の観察モード(例えば2次元平面、ワイヤ
フレーム、ソリッド、正射図)に応じて表示されるパー
ツの2次元及び/又は3次元表示を得る。これは図28
−31を参照して上で詳細に説明された。種々のメニュ
ーウインドウがまた例えばステーションモジュールに設
けられ、この発明の特性及び機能の操作を容易にする。
図61は2次元から3次元操作のために表示される代表
的メニューを図示する。更に図62はこの発明の2次元
クリーンアップ操作のための代表的メニュー構造を図示
する。この発明はしかしこれらのメニュー配置に限定さ
れるものではなく、他のメニュースクリーン及び/又は
工具アイコンバーが設けられ、ユーザのシステムとの相
互作用を容易にする。
【0355】他の特性もまたこの発明において実行され
る。例えば、高いレベルの自動装置も提供され曲げプラ
ンの生成を容易にする。例えば曲げ及び工具立てエキス
パートシステムが提供され、各作業についてのパーツの
幾何形状及び形状に基づいて工具立てセットアップ及び
曲げ順を生成し且つ提案する。それは例えば米国特許出
願出願番号08/386.369及び08/338.1
15に開示されるようなものである。
【0356】この発明は幾つかの代表的な実施例を参照
して記載されたがここで用いられた用語は、限定の用語
ではなく、記載及び説明の用語である。この発明の範囲
及び精神及び種々の側面から逸脱することなく種々の変
形がなされ得る。この発明はここで特定の手段、材料及
び実施例を参照して記載されたが、発明はここに開示さ
れた特定のものに限定されるように意図されるものでは
ない。むしろ発明は全ての機能的に等価な構造、方法及
び使用に広がる。
【0357】付録A 曲げモデルパーツからのフィーチャエンティティ抽出の
例 .int SPS_cal_part_matrix ( BM_PART *part, FENT **i
np_sp,char*pname,int *inp_parrank, int*inp_part_nu
mface,int *inp_part_numbend, int*inp_part_maxface
){// local variablesint parrank, part_numface, pa
rt_numbend, part_maxface ;int **imatrix = NULL ;in
t *nbl_face = NULL ;BENDFACE *facelist= NULL ;BEND
LINE *bendlinelist = NULL ;ARTIFICIAL_FACE *bendfa
celist = NULL ;int num_error = 0 ;//counter for th
e number of errors in the partint face_1, face_2,
bend_1, bend_0, i ;long num_of_faces, num_of_bendl
ines, entity_id;BM_FACE *face;BM_BENDLINE *ben
dline;BM_2D_BODY *two_d_body;BM_3D_BODY *three_d
_body;BM_BEND_OP *bend_op;BM_TOPOLOGY_RECORD *to
pology_record;// get name and number of faces and
bendlines of the partpart->get_name( pname ) ;doub
le thickness = part->get_metal_thickness();num_of_
faces = part->get_number_of_faces() ;num_of_bendli
nes = part->get_number_of_bendlines();if (num_of_f
aces == 0 || num_of_bendlines == 0)return ( -1 );/
/ create local working arrayfacelist = new BENDFAC
E [num_of_faces];bendlinelist = new BENDLINE [num_
of_bendlines];// count number of faces defined.dou
ble maxfacearea = -1.0 ;part_maxface = 0 ;part_num
face = 0 ;face = part->get_face_list() ;for ( i =
0 ; face && i < num_of_faces ;i++, face = (BM_FACE
*)(face->next())) { // Count the defined faces.//
initialize the strucfacelist[i].faceid = 0 ;facel
ist[i].facept =NULL ;facelist[i].twodpt = NULL ;fa
celist[i].threedpt = NULL ;facelist[i].topologyrec
pt = NULL ;facelist[i].numadjbody = 0 ;facelist
[i].numadjbend = 0 ;facelist[i].numadjhole = 0 ;fa
celist[i].numadjface = 0 ;facelist[i].face_area =
0. ;if (face == NULL) break ;two_d_body = face->ge
t_3D_version() ;if (two_d_body == NULL) continue ;
// It is considered as a valid face, when its BM_2
D_BODY exists.part_numface++ ;facelist[i].faceid =
part_numface ;facelist[i].facept = face ;facelist
[i].twodpt = two_d_body ;facelist[i].face_area = a
rea_of_a_2D_body(two_d_body) ;if (maxfacearea < fa
celist[i].face_area) {maxfacearea = facelist[i].fa
ce_area ;part_maxface = facelist[i].faceid ;} thre
e_d_body = two_d_body->get_3D_body() ;facelist[i].
threedpt = three_d_body ;if (three_d_body == NULL)
continue;entity_id = three_d_body->get_name() ;fa
celist[i].org_entity = entity_id ;topology_record
= three_d_body->get_adj_list() ;facelist[i].topolo
gyrecpt = topology_record ;if (topology_record ==
NULL) continue ;facelist[i].numadjbody = (int)topo
logy_record->get_number_of_adjacent_bodies() ;face
list[i].numadjface = (int)topology_record->get_num
ber_of_adjacent_faces() ;facelist[i].numadjhole =
(int)topology_record->get_number_of_adjacent_holes
() ;facelist[i].numadjbend = (int)topology_record-
>get_number_of_adjacent_bendlines() ;}if (num_erro
r > 0) {clean_up ( part_numface, imatrix, nbl_fac
e, facelist,bendlinelist, bendfacelist) ;return (
num_error ) ;}if (part_numface == 1) {// this is a
trivial case, where the partonly has one flat fac
e.*inp_part_numface = part_numface ;*inp_parrank =
part_numface ;*inp_part_numbend = 0 ;*inp_part_max
face = 1 ;*inp_sp = new FENT [2] ;*inp_sp[2] = Nul
lFent ;clean_up ( part_numface, imatrix, nbl_face,
facelist, bendlinelist, bendfacelist) ;return ( 0
) ;}// varify all the valid face, the current req
uirements are://1) A face cannot be adjacent to an
other face.//2)A face without an adjacent bendline
is not allowed.//(Note: The single faced part has
been processed.)// Also, creata pointer array tha
t links assigned part_face_id// to the netry in th
e facelist.int *fid_pt = new int [part_numface] ;f
or ( i = 0 ; i < num_of_faces ; i++) {if (facelist
[i].faceid) {fid_pt[facelist[i].faceid] = i ;if(fa
celist[i].numadjface ||facelist[i].numadjbend < 1)
num_error++ ;}}if(fid_pt) delete [] fid_pt ;if (n
um_error > 0) {clean_up ( part_numface,imatrix, nb
l_face, facelist, bendlinelist, bendfacelist) ;ret
urn ( num_error ) ;}// count the number of bendlin
es that is defined.part_numbend= 0 ;bendline = par
t->get_bendline_list() ; for ( i = 0 ; bendlin
e && i < num_of_bendlines ;i++, bendline = (BM_BEN
DLINE *)(bendline->next())) {// initialize the str
uctbendlinelist[i].bendlineid = 0 ; bendlinelist
[i].bendlinept = NULL ;// BM_BENDLINE pointer bend
linelist[i].bendoppt= NULL ;// BM_BEND_OP pointerb
endlinelist[i].twodpt = NULL ;// BM_2D_BODY poi
nterbendlinelist[i].threedpt = NULL ;// BM_3D_BO
DY pointerbendlinelist[i].topologyrecpt = NULL ;//
BM_TOPOLOGY_RECORD pointerbendlinelist[i].numadjb
ody = 0 ;bendlinelist[i].numadjbend = 0 ;bendlinel
ist[i].numadjhole = 0 ;bendlinelist[i].numadjface
= 0 ; if (bendline == NULL) break ;two_d_body =
bendline->get_3D_version() ;if (two_d_body == NUL
L) continue ;// It is considered as a valid bendli
ne, when its BM_2D_BODY exists.part_numbend++ ;ben
dlinelist[i].bendlineid = part_numbend ; bendlinel
ist[i].bendlinept = bendline ;// BM_BENDLINE point
er bendlinelist[i].twodpt = two_d_body ; // BM_2D_
BODY pointerbend_op = bendline->get_bend_op() ; be
ndlinelist[i].bendoppt = bend_op ;// BM_BEND_OP po
interif (bend_op == NULL) num_error++ ;// Note: Be
nd operation must be defined foreach // bend
line, 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_bo
dy == NULL) continue ;entity_id = three_d_body->ge
t_name() ;facelist[i].org_entity = entity_id ;topo
logy_record = three_d_body->get_adj_list() ;bendli
nelist[i].topologyrecpt = topology_record;if
(topology_record == NULL)
continue ;bendlinelist
[i].numadjbody = (int) to
pology_record−>get_number
_of_adjacent_bodies() ;be
ndlinelist[i].numadjface
= (int) topology_record−>
get_number_of_adjacent_fa
ces() ;bendlinelist[i].nu
madjhole = (int) topology
_record−>get_number_of_ad
jacent_holes() ;bendlinel
ist[i].numadjbend = (int)
topology_record−>get_num
ber_of_adjacent_bendlines
() ;}if (num_error > 0)
{clean_up ( part_numface,
imatrix, nbl_face, facel
ist, bendlinelist, bendfa
celist) ;return ( num_err
or) ;}// varify all the v
alid bendlines, the curre
nt requirements are://1)
The total number of bendl
ines should not be less t
han// the totalnumber
of faces minus 1.// 2) A
bendline without an adja
cent face or bendline is
not allowed.// 3) A bendl
ine with more than two ad
jacent facesand bendlines
is not allowed.//4)The a
djacent face or bendline
of a bendline must bea va
lid face or// bendline
that is defined in the f
acelist or bendlinelist./
/ 5) Two adjacent faces,
face1 and face2, will be
defined for each bendline
// a) If the bendline
has an adjacent faces, th
en the face’s faceid is u
sed// as face1 or f
ace2.//b) If the bendline
has an adjacent bendlin
e, thena bendline_only_fa
ce// will becreated
inbetween these two bend
lines. The faceid of the
// bendline_only_face wi
ll be used as face1 or fa
ce2.//c)If the bendline h
as only oneadjacent face
or adjacent bendline, the
n//a bendline_only_face w
ill be created for this b
endline. The faceid of//
the bendline_only_
faceis face2.// maxnewfac
es is the maximum number
of bendline_only_face nee
dto be created// without
encounter error in the pa
rt.if (part_numbend >part
_numface−1) num_error++ ;
// condition 1if (num_er
ror > 0) {clean_up( part_
numface, imatrix, nbl_fac
e, facelist, bendlineli
st, bendfacelist) ;return
( num_error ) ;}int maxn
ewfaces = part_numbend +
1 − part_numface ;if (max
newfaces > 0) {bendfaceli
st = new ARTIFICIAL_FACE
[maxnewfaces] ;bendfaceli
st[0].faceid = −part_numf
ace ;}for ( i = 0 ; i < n
um_of_bendlines ; i++) {i
f (bendlinelist[i].bendli
neid) {bend_0 = bendlinel
ist[i].bendlineid ;intnum
adj = bendlinelist[i].num
adjface + bendlinelist
[i].numadjbend ;if (numad
j < 1 || numadj > 2) num_
error++ ; // condition 2&
3else {if (bendlinelist
[i].numadjface > 0) { //
condition 4 − first facet
hree_d_body = bendlinelis
t[i].topologyrecpt−>get_f
irst_face() ;face_1 = fin
d_face_id( three_d_body,
facelist, num_of_faces )
;if (face_1 <=0) num_err
or++ ;else bendlinelist
[i].face1 = face_1 ; }if
(bendlinelist[i].numadjfa
ce == 2) { // condition 4
− second facethree_d_bod
y = bendlinelist[i].topol
ogyrecpt−>get_next_face()
;face_1 = find_face_id(
three_d_body, facelist, n
um_of_faces ) ;if (face_1
<= 0) num_error++ ;else
bendlinelist[i].face2 = f
ace_1 ; }if (bendlinelist
[i].numadjbend > 0) { /
/condition 4 − first bend
linethree_d_body = bendli
nelist[i].topologyrecpt−>
get_first_bendline() ;ben
d_1 = find_bendline_id( t
hree_d_body, bendlinelis
t, num_of_bendlines ) ;if
(bend_1 <= 0) num_error+
+ ;else {face_1 =define_b
endline_only_face ( bend_
1, bend_0,bendfacelist, m
axnewfaces ) ;if (face_1
<= 0) num_error++ ;else
{if (bendlinelist[i].numa
djface > 0)bendlinelist
[i].face2 = face_1 ;else
bendlinelist[i].face1 = f
ace_1 ;}}}if (bendlinelis
t[i].numadjbend == 2) {
// condition 4 − second
bendlinethree_d_body = be
ndlinelist[i].topologyrec
pt−>get_next_bendline() ;
bend_1 = find_bendline_id
( three_d_body, bendlinel
ist, num_of_bendlines ) ;
if (bend_1 <= 0) num_erro
r++ ;else {face_1 = defin
e_bendline_only_face (ben
d_1, bend_0, bendfacelis
t, maxnewfaces ) ;if (fac
e_1 <= 0) num_error++ ;el
se bendlinelist[i].face2
= face_1 ;}}if (numadj ==
1) {face_1 = define_bend
line_only_face ( bend_0,
0,bendfacelist, maxnewfac
es ) ;if (face_1 <= 0) nu
m_error++ ;else bendlinel
ist[i].face2 = face_1
;}}}}if (num_error > 0)
{clean_up ( part_numface,
imatrix, nbl_face, fac
elist, bendlinelist, bend
facelist) ;return ( num_e
rror ) ;}// now check whe
ther there is any bendlin
e only face been created/
/ increase the part_numfa
ce ifthere is.int numregf
aces = part_numface ;int
numnewfaces = 0 ;if (maxn
ewfaces > 0) { for ( i =
0 ; i < maxnewfaces ; i++
) {if (bendfacelist[i].f
aceid <= 0) {numnewfaces
= i + 1 ;break ;}}part_nu
mface += numnewfaces;}//f
irst create integer topol
ogical matrix to record a
ll the topological relati
onsint j ;imatrix = new i
nt *[part_numface] ;for
( i = 0 ; i <part_numface
; i++ ) {imatrix[i] = ne
w int [part_numface] ;for
( j = 0 ;j < part_numfac
e; j++ ) imatrix[i][j] =
0;}for ( i = 0 ; i < num_
of_bendlines ; i++ ) {//
save the bendline entry +
1 in imatrixif (bendline
list[i].bendlineid) {face
_1 = bendlinelist[i].face
1 ;face_2 = bendlinelist
[i].face2 ;imatrix[face_1
−1][face_2−1] = i+1 ;imat
rix[face_2−1][face_1−1]=
i+1 ;}}// from imatrix to
find the number of bendl
ines of each face, nbl_fa
ce[i],// and to verify th
at each face has at least
one bendlinenbl_face = n
ew int [part_numface] ;fo
r ( i = 0 ; i < part_numf
ace ; i++ ) {nbl_face[i]
= 0 ;for ( j = 0 ; j < pa
rt_numface ; j++ ) {if (
imatrix[i][j] ) nbl_face
[i]++;}if (!nbl_face[i])
num_error++ ;}if (num_err
or > 0) {clean_up ( part_
numface, imatrix, nbl_fac
e, facelist, bendlineli
st, bendfacelist) ;return
( num_error ) ;}// creat
e the Cbpart’s topologica
l matrix’s input data FEN
T array// and initialize
it.part−>get_name( pname)
;parrank = part_numface
;int spsize = parrank*(p
arrank + 1)/2 + 1 ; // +
1 is for End of FENT arra
y indicator FENT *sp = ne
w FENT [ spsize ] ;for(i
= 0; i < spsize−1 ; i++ )
*(sp+i) = NoRelation ;*(s
p+spsize−1) = NullFent ;/
/ step 1: set up the posi
tive or negative bend//
The included FENT’
s are://*PosBend = ’
+’; // positive bend bet
ween two faces//*NegBend
= ’−’; // negative b
end between two faces
//*P90Bend= ’A’; //
90 deg positive bend ang
le//*N90Bend = ’B’; //
90 deg negative bend angl
e//MrPosBend = ’3’; //
multiple positive bendli
nes between two faces//Mr
NegBend = ’4’; // mult
iple negative bendlinesbe
tween two faces//* marks
what is currently impleme
nted.for ( i = 0 ; i< num
_of_bendlines ; i++ ) {if
(bendlinelist[i].bendlin
eid) {face_1 = bendlineli
st[i].face1 ;face_2 = ben
dlinelist[i].face2 ;FENT
btype = NegBend ;BM_BEND_
OP_REGULAR *bendopregular
= (BM_BEND_OP_REGULAR *)
bendlinelist[i].bendoppt;
if (bendopregular−>get_be
nd_type()) btype = PosBen
d ;double angle = bendopr
egular−>get_bend_angle()
;if (angle > PI) {// ang
le >PI => reverse bend di
rection and reset the ben
d angleangle = 2*PI − ang
le ;if (btype == PosBend)
btype = NegBend ;elsebtyp
e = PosBend ;}bendlinelis
t[i].bendangle = angle ;b
endlinelist[i].bendtype
= btype ;// set up 90 deg
ree bend typeif (angle ==
PI_over_2) {if (btype ==
PosBend)btype =P90Bend ;
elsebtype = N90Bend ;}//s
et_FENT (sp, face_1, face
_2, parrank,btype) ;}}//
step 2: set up the corner
relationships, which is
the relation//between two
faces that are connected
to a common face.// The
included FENT are://*Tou
chCnr = ’T’; // two
faces same bend dir//*Op
enCnr = ’O’; // tw
o faces same bend dir//*P
rllBend = ’P’; // t
wo parallel bendline same
bend angle dir opposite
bendline dir//*SerlBend
= ’S’; // two parall
el bendline same bend ang
le dir same bendline dir/
/*cLnrBend = ’L’; /
/ colinear bendline same
bend angle dir on one fac
e//*DfClnrBend = ’D’;
//colinear bendline same
bend angle on different
faces//*tHkOffBend = ’
H’; // tHickness offset
bendline same bend angle
dir on two neighboring fa
ce//*touchCnr = ’t’;
// two faces opposite b
end dir//*openCnr =
’o’; // two faces oppos
itebend dir//*prllBend
= ’p’; //two parallel
bendline opposite bend a
ngle dir opposite bendlin
e dir//*serlBend = ’
s’; // two parallel bend
line opposite bend angle
dir same bendline dir//*c
lnrBend = ’l’;//coli
near bendline opposite be
nd angle dir on one face/
/thkOffBend =’h’; // tHi
ckness offset bendline op
posite bend angle dir on
two neighboring face//* m
arks what is currently im
plemented.// Algorithm :
forevery face that has mo
re than one bend line the
n//a pair of any two bend
lines will have relations
hip.for ( i = 0 ; i < par
t_numface ; i++ ) {if(nbl
_face[i] > 1) {int face_c
= i + 1 ;// create a lis
t of faces that are conne
cted to this face.for ( j
= 0 ; j < part_numface ;
j++ ) {if ( imatrix[i]
[j] ) {int bl_1 = imatrix
[i][j] ;face_1 = j + 1 ;f
or ( int k =j+1 ;k < part
_numface ; k++ ) {if ( im
atrix[i][k] ) {int bl_2 =
imatrix[i][k] ;face_2 =
k + 1 ;// define the rela
tion ship between the two
bendlinesset_bendline_re
l_FENT ( sp, parrank,face
list, face_c, face_1, fac
e_2,bendlinelist, bl_1, b
l_2, outfile) ;}}}}}}//*t
HkOffBend = ’H’; // t
Hickness offset bendline
same bend angle dir on tw
o neighboring face// from
imatrix to find the face
s that may be of the thic
kness offset bendlines//a
nd verify these faces fir
st based on touch corneri
nfomation then based on//
the bendlines’ distance
and parallel condition.fo
r ( i = 0 ; i< part_numfa
ce ; i++ ) {if ( nbl_face
[i] < 2 ) continue ;// fa
ce i should have at least
2 bendlinesfor ( j = i+1
; j < part_numface ; j++
) {if( !imatrix[i][j] ||
nbl_face[j] < 2 ) contin
ue ;// faces i and j must
have a common bendline//
and face j should have a
t least 2 bendlinesfor (i
nt i2 = 0 ; i2 < part_num
face ; i2++ ) {if ( !imat
rix[i][i2] || i2 ==j ) co
ntinue ;// faces i and i2
must have a common bendl
ine// and face i2 is diff
erent from j// first requ
irement − bendlines imatr
ix[i][j] and// imatrix[i]
[i2] form a touch corneri
f ( get_FENT(sp, j+1, i2+
1, parrank) != TouchCnr )
continue ;for ( int j2 =
0 ; j2 < part_numface ;
j2++ ){if ( !imatrix[j][j
2] || j2 == i ) continue
;// second requirement −
bendlines imatrix[i][j]
and// imatrix[j][j2] also
form a touch cornerif (
get_FENT(sp, i+1, j2+1, p
arrank) != TouchCnr ) con
tinue ;// comes here, we
have obtained a candidate
for the // thickness offset bendlines, t
hetwo candidate // bendlines are imatrix[i,i2] an
d imatrix[j][j2] int bl_1 = imatrix[i][i2] ;int b
l_2 = imatrix[j][j2] ;check_thkoffbend ( sp, parra
nk,facelist, i+1, i2+1, j+1,j2+1,bendlinelist, bl_
1, bl_2, thickness, outfile);}}}}//DfClnrBend =
'D'; //colinear bendline same bend angle on diff
erent faces// Here is to find all the colinear ben
ds that arecolinear but not related to each other/
/ with a common face.int num_undetermined = 0 ;UND
ETERMINED *undetermined = new UNDETERMINED [num_of
_bendlines] ;UNDETERMINED *undetpt = undetermined
;for ( i = 0 ; i < num_of_bendlines ; i++ ) {if
(bendlinelist[i].bendlineid) {int face_i1 = bendli
nelist[i].face1 ;int face_i2 = bendlinelist[i].fac
e2 ;for ( j = i+1 ; j <num_of_bendlines ; j++ ) {i
f (bendlinelist[j].bendlineid) {int face_j1= bendl
inelist[j].face1 ;int face_j2 = bendlinelist[j].fa
ce2 ;if ( face_i1 == face_j1 || face_i1 == face_j2
||face_i2 == face_j1 || face_i2 == face_j2 ) cont
inue ;if ( bendlinelist[j].bendtype != bendlineli
st[j].bendtype ) continue ;if ( bendlinelist[j].b
endangle != bendlinelist[j].bendangle ) continue ;
// come here when the two bend lines have the same
bend angle and type,// and they do not share a co
mmon face.// now examinewhether they are colineari
nt bl_i = i + 1 ;int bl_j = j + 1 ;int unknown= ch
eck_DfClnrBend ( sp, parrank, facelist,face_i1, fa
ce_i2, face_j1, face_j2,bendlinelist, bl_i, bl_j,p
art_numface, imatrix, outfile) ;if (unknown) {unde
termined[num_undetermined].bendline_i = bl_i ;unde
termined[num_undetermined].bendline_j = bl_j ;num_
undetermined++ ;}}}}}// Note: ifnum_undetermined i
s not zero, then there are confirmed DfClnrBend//b
ut with undetermined faces for specify this FENT./
/A tree structure of all the faces that records th
e connectivity between//faces need to be construct
ed. And then each pair of undetermined//bendlines
need to be processed to determine which two faces
of the four//that connected with the twobendlines
should be used torecord this FENT.// Currently, w
e will neglect these information and simply delete
// undetermined array, which will not be used any
more. delete [] undetermined ;// transfer all the
data back *inp_part_numface = part_numface ;*inp_p
arrank = parrank ;*inp_part_numbend = part_numbend
;*inp_part_maxface = part_maxface ;*inp_sp = sp ;
num_error = fclose (outfile) ;clean_up ( part_numf
ace, imatrix, nbl_face,facelist, bendlinelist, ben
dfacelist) ;return ( num_error ) ; }付録B 相似性指数特性の例。2つの部分のトポロジカルマトリ
クスを比較し、それらの最良の相似性指数を求める。相
似性指数は、2つの部分のFENTマトリクストポロジ
カルマトリクス)の不一致FENTsの全てのペナルテ
イの和として与えられる。最良の相似性指数は最小値を
持つものである。
【0358】int matrix_similarity_index ( FENT
*newmatrix,int newmatrixdim,int *newmatchlist,
FENT *oldmatrix,int oldmatrixdim,int *oldmatchli
st, int nfacefixed,int requiredvalue,int *minimum
value){ //input //newmatrix- new part topolog
ical matrix to be matched on// by the oldmatrix//
newmatrixdim- matrix dimension of newmatrix//newma
tchlist- the first nfacefixed entries should// co
ntain the entries (faces) of the new part//matrix
that has already been fixed for// matching with t
he old part matrix. //oldmatrix- old part matri
x to match with the new part // topological matr
ix//oldmatrixdim- matrix dimension of oldmatrix//o
ldmatchlist- the first nfacefixed entries should//
contain the entries (faces)of the old part// ma
trix that has already been fixed for// matching w
ith the new part matrix.//nfacefixed- the number o
f entries in matchlistthat// has already been mat
ched. Enter 0 when// there is no prematched entr
ies.//requiredvalue- the known or interested upper
bound on the//minimum similarity index. When thi
s value// is inputed as a positivevalue, then a//
branch of the search tree in finding the// mini
mum value of the similarity index may// be cut of
f when the branch's current value// 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
new part// matrix that has already been fixed for
// matching with the old part matrix.//oldmatchli
st- the first nfacefixed entries should// contain
the entries (faces) of the old part// matrix tha
t has already been fixed for// matching with the
new part matrix.//minimumvalue- the minimum simila
rity index, which is the//smallest possible value
of summation of all// the penalties of the mismat
ched FENTs of the// two part's FENT matrix (topol
ogical matrix).//This value may not exist, if the
original// inputed value (which is therequiremen
t) is// too small.//return- index on whether or n
ot found the minimum// value.//= 1, found the min
ium value and its match. //= 0, anew minium value
cannot be reached.//= -1, error in the input data
newmatchlist.//= -2, error in the input data oldma
tchlist.//= -3, error, theminimum similarity index
of// the given matrices are larger than the//inp
uted minimumvalue.// create two integer pointer ar
rays to keep track the // corresponding entries of
the two matrices that matches.int matrixdim = new
matrixdim ;if (matrixdim < oldmatrixdim) matrixdim
= oldmatrixdim ;int *pnewmatchlist = new int[ mat
rixdim ];int *poldmatchlist = newint[ matrixdim ];
if ( poldmatchlist && pnewmatchlist ) {int *p1 = p
newmatchlist;int *p2 = poldmatchlist;for ( int ico
l = 1; icol <= matrixdim;icol++,p1++,p2++)*p1 = *p
2 = icol;}elsecout << "Unable to allocate memor
y..." << endl ;// if there are already fixed entri
es (nfacefixed > 0),then reset// the temporary wor
king pointer arrays (newmatchlist & oldmatchlist)/
/ to contain those fixed face list.if (nfacefixed
> 0){for (int icol = 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
theinputed face number "iface"// from newmatchlis
t is wrongreturn (-1) ; }iface = *(oldmatchlist+ic
ol) ;for ( jcol = icol; jcol < matrixdim; jcol++)
{if (iface == *(poldmatchlist+jcol)) {if (jcol !=
icol) {*(poldmatchlist+jcol) = *(poldmatchlist+ico
l) ;*(poldmatchlist+icol) = iface ;}break;}// come
s here only if the inputed face number "iface"// f
rom oldmatchlist is wrongreturn (-2) ; }}}// conve
rt the FENT matrix to the counterpart of integer m
atrix// at the same time, expand the smaller matri
x tohave the same dimension.int *pnewmatrix = new
int[matrixdim*matrixdim];int *poldmatrix = new int
[matrixdim*matrixdim];convert_fent_to_int (newmatr
ix, newmatrixdim, pnewmatrix, matrixdim) ;convert_
fent_to_int (oldmatrix, oldmatrixdim, poldmatrix,
matrixdim) ;// define required valueint requiredv
= requiredvalue ;if (requiredv <= 0) requiredv = m
atrixdim * 400;// create the FENT counters and use
calculate_partial_similarity_index// to calculate
the initial similarity index and set the initial
FENT//counts for each column of the fixed faces an
d that of all the// unfixedfaces.FENTCOUNT *pcnew
= new FENTCOUNT[matrixdim+1];FENTCOUNT *pcold = ne
w FENTCOUNT[matrixdim+1];int currentvalue = calcul
ate_partial_similarity_index ( pnewmatrix, pnew
matchlist, pcnew, poldmatrix, poldmatchlist,
pcold, matrixdim, nfacefixed ) ;if (currentvalue
> requiredv) return (-3) ;// reset the unfixed fa
ces in pnewmatchlist to be in the sequence of// it
s total weighting.int ncandidates = matrixdim - n
facefixed;int *pcandidates = new int [ncandidates]
;int *pweights = new int [ncandidates] ;for ( int
i = 0 ; i < ncandidates ; i++ ) {int facenew = *
(pnewmatchlist+nfacefixed+i) ;*(pcandidates+i) = f
acenew ;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 (pc
andidates, pweights, ncandidates) ;for (i = 0 ; i
< ncandidates ; i++ ) *(pnewmatchlist+nfacefixed+
i) = *(pcandidates+ncandidates-1-i) ;delete [] pca
ndidates ;delete [] pweights ;// call the internal
routine recursively to perform similarity index//
search.*minimumvalue = requiredv ;int recursive_l
evel = 0;int *newminmatchlist= new int[matrixdim];
int *oldminmatchlist = new int[matrixdim];int *ret
urnlevelcounts = new int[matrixdim];int errorcode
= matrix_similarity_index_loop ( pnewmatrix, pn
ewmatchlist, newminmatchlist, poldmatrix, pol
dmatchlist, oldminmatchlist, pcnew, pcold, &curre
ntvalue, matrixdim, nfacefixed, &recursive_level,
minimumvalue, returnlevelcounts) ;//clean updele
te [] pnewmatchlist ;delete [] poldmatchlist ;dele
te [] pnewmatrix ;delete [] poldmatrix ;delete []
pcnew ;delete [] pcold ;delete[] returnlevelcounts
;delete [] newminmatchlist ;delete [] oldminmatch
list ;return (errorcode);}// 新しい部分マトリクス
と一致する既存の部分マトリクスからエントリのリスト
を抽出する。部分マトリクスのデイメンシヨンはトポロ
ジカルマトリクスのデイメンシヨンより大きいか等しく
なければならない。注意:一致リストの第一要素は初期
化されてトポロジカルマトリクスの第一面との一致のた
め部分マトリクスの面番号を含まなければならない。
nmatchedが0より大きいときは、マッチリスト
の第一のnmatchedエントリは正の番号を含んで
部分マトリクスの既に一致されたエントリを示さなけれ
ばならない。//int matrix_similarity_index_loop
( int *pnewmatrix, int *pnewmatchlist, int *new
minmatchlist, int *poldmatrix, int *poldma
tchlist, int *oldminmatchlist, FENTCOUNT *pcnew,
FENTCOUNT *pcold,int *currentvalue, int matrixd
im, int nfacefixed, int *recursive_level,
int *minimumvalue, int *returnlevelcounts){// i
nput//pnewmatrix- the new part's topological matri
x, where// the FENT content
s have been changed to// th
eir representing integers.//
(integer array of matrixdim* matrixdim)//pnewmat
chlist- the list of entries of the newmatrix that/
/ has been matched by the oldmatrix.//
(integerarray of matrixdim)//newminma
tchlist- the list of entries of the newmatrix that
// has been matched by the oldmatrix that// pro
vides the minimum value.//
(integer array of matrixdim) //poldmatrix- the
old parts's topological matrix, where//the FENT co
ntents have been changed to//
their representing integers.//
(int array of matrixdim * matrixdim)//poldm
atchlist- the list of entries of the oldmatrix tha
t // has matched with the newmatrix.//
(integerarray of matrixdim)//oldminma
tchlist- the list of entries of the oldmatrix that
// has matched with the oldmatrix that// provid
es the minimumvalue.// (int
eger array of matrixdim)//matrixdim-the matrix dim
ension of both matrices//nfacematched- the number
of entries (faces) that has// been fixed in match
ing the two matrices.// recursive_level- this keep
the number of times this procedure// has been ca
lled recursivly. This provides a// way to detect
the error before goinginto a// infinite loop. (i
nteger pointer)// output//return- error index,//=
0 means there is no error,//> 0 error code.//// ve
rify the recursive levelif ( *recursive_level > ma
trixdim ) {cout << "??? Error - the recursive leve
l is too high. ???\n";cout << " The matrix dime
nsion is "<< matrixdim << ".\n";cout << " The r
ecursive level is " << *recursive_level << ".\n";
return (9) ;}// Step 1) Choose a row to be matched
with in the new matrix.// ( Currently, it uses wh
atever the next row in line. Therefore,// nothi
ng to do at this moment.// This may need to be c
hanged to be properly matching up with// the alg
orithm that may beused in defining the sequence of
the// candidate list.// Note: If facenew is n
ot next to the nfacefixed position, then//
it should be changed to that position. )int face
new = *(pnewmatchlist+nfacefixed);// Step 2) Creat
e a list of candidate face list in the old matrix.
//and calculate the increases in the similarity in
dex for//each of the candidates.// ( Currently we
are using what ever the sequence that is inside//
the poldmatchlist.// One may choose to use the
faces that at least matches up with// the face
connectivity of the chosen face in the new matrix.
// Note: The sequence of faces in pcandidatesdoe
s not need to// be corresponding to that i
n poldmatchlist. )int ncandidates = matrixdim - n
facefixed ;int *pcandidates = new int [ncandidate
s] ;int *pincreases = new int [ncandidates] ;for
( int i = 0 ;i < ncandidates ; i++ ) {int faceold
= *(poldmatchlist+nfacefixed+i) ;*(pcandidates+i)
= faceold ;int increase = increase_on_similarity_i
ndex( pnewmatrix,pnewmatchlist,facenew, pol
dmatrix,poldmatchlist,faceold, pcnew,pcold,curr
entvalue, matrixdim,nfacefixed,minimumvalue);*
(pincreases+i) = increase ;}// Step 3) Sort the ca
ndidate face basedon the increased values//
the candidates with the lower increasewill be tr
ied first.sort_the_candidates (pcandidates, pincre
ases, ncandidates) ;// Step 4) change the FENT cou
nters of the newmatrix for fixingfacenewint errorc
ode = change_counts_for_fix_one_face ( pnewmatr
ix,pnewmatchlist, facenew, pcnew, matrixdim, nface
fixed) ;if (errorcode !=0) return (errorcode) ;//
Step 5) Loop thru the candidate face and basedon t
he increased value// determines whether or
not to continueto the lower level match.for ( int
icandi = 0 ; icandi < ncandidates ; icandi++ ) {/
/ get the candidate face number of the old matrix
and// itscorresponding amount of increase on simil
arity index.int faceold = *(pcandidates+icandi) ;i
nt increase = *(pincreases+icandi) ; // Now check
whether it is any need to continue the matching//
If the current value plusthe increase has already
exceed the // minimum value, then there is noneed
to continue the matching.// add the returnlevelcou
nt and go to thenext candidates.if (*currentvalue
+ increase >= *minimumvalue) {returnlevelcounts[nf
acefixed] += 1 ;}else if (nfacefixed+1 == matrixdi
m) {// A new minimum similarity index has been fou
nd, update// the minimum value*minimumvalue = *cur
rentvalue + increase ;for ( i = 0 ; i < matrixdim
; i++ ) {newminmatchlist[i] = pnewmatchlist[i] ;o
ldminmatchlist[i] = poldmatchlist[i] ;}}else {// I
t is necessary to go down another level in this re
cursive// call to define the similarity index.// c
hange the FENT counters of the oldmatrix for fixin
g faceolderrorcode = change_counts_for_fix_one_fac
e ( poldmatrix, poldmatchlist, faceold, pcold,
matrixdim, nfacefixed) ;if (errorcode != 0) return
(errorcode) ;// call recursively*currentvalue +=
increase ;*recursive_level += 1 ;errorcode = matri
x_similarity_index_loop ( pnewmatrix,pnewmatc
hlist,newminmatchlist, poldmatrix,poldmatchli
st,oldminmatchlist, pcnew, pcold,currentvalue,
matrixdim,nfacefixed+1,recursive_level, minimumv
alue,returnlevelcounts) ;if (errorcode != 0) retur
n (errorcode) ;*recursive_level -= 1 ;*currentvalu
e -= increase ;// change the FENT counters of the
oldmatrix for unfixing faceoldchange_counts_for_un
fix_one_face ( poldmatrix, poldmatchlist, pcol
d, matrixdim, nfacefixed+1) ;}}// change the FENT
counters of the newmatrix for unfixing facenewchan
ge_counts_for_unfix_one_face ( pnewmatrix, pnew
matchlist, pcnew, matrixdim, nfacefixed+1) ;//clea
n updelete [] pcandidates ;delete [] pincreases ;r
eturn (0);}///////////////////////////////////////
/////////////////////////// 1以上の面を固定するた
めのカウンターを更新する。////////////////////////
////////////////////////////////////////////int ch
ange_counts_for_fix_one_face ( int *pnewmatrix,
int *pnewmatchlist, int facenew, FENTCOUNT *p
cnew, int matrixdim, int nfacefixed){// inp
ut//pnewmatrix- the new part's topological matrix,
where// the FENT contents
have been changed to// thei
r representing integers.//(integer array of matrix
dim * matrixdim)//pnewmatchlist-the list of entrie
s of the newmatrix that // has been matched by th
e oldmatrix.// (integer arr
ay of matrixdim)//facenew- the face that is to be
fixed.//pcnew- the FENTCOUNT of all the faces.//ma
trixdim- the matrix dimension of both matrices//nf
acematched- the number of entries (faces) that has
// been fixed in matching the two matrices.// out
put//pnewmatchlist- the updated list of entries of
the// newmatrix matched by the oldmatrix,// wit
h the facenew entry is moved to the// nfacefixed+
1 location. //pcnew- the updated FENTCOUNT of all
the faces// switch the to be fixed face to the loc
ation of nfacefixed+1// in the pnewmatchlistint if
ound = 0 ;for ( int i = nfacefixed ; i < matrixdi
m; i++ ) {if (*(pnewmatchlist+i) == facenew) {*(pn
ewmatchlist+i) = *(pnewmatchlist+nfacefixed) ;*(pn
ewmatchlist+nfacefixed) = facenew ;ifound++;}}if
( ifound != 1 ) {cout << "Fatal error from change_
counts_for_fix_one_face /n" ;return ( 91 ) ;}// de
fine the pointer to the FENT on the tobe fixed fac
eint *pnewrow = pnewmatrix + (facenew-1)*matrixdim
;// first change the counters for the previously
fixed facesfor ( i = 0 ; i < nfacefixed ; i++ ) {i
nt newcol = *(pnewmatchlist+i) ;int pnewv = *(pne
wrow + newcol - 1) ;pcnew[newcol].count[pnewv]-- ;
int igroup = fent_group (pnewv) ;pcnew[newcol].gco
unt[igroup]-- ;if ( pcnew[newcol].count[pnewv]< 0
|| pcnew[newcol].gcount[igroup] < 0 ) {cout <<
"Fatal error fromchange_counts_for_fix_one_face /
n" ;return ( 92 ) ;}}// second change the counters
for the unfixed faces// use count_specified_fents
to initialize the FENTCOUNT of// the newly selete
d face and count the numbers of fents of // the un
determined columns on the to be fixed rowsint list
dim =matrixdim - nfacefixed ;pcnew[facenew] = coun
t_specified_fents ( pnewrow, pnewmatchlist+nfacefi
xed, matrixdim, listdim ) ; // decrease the FENTCO
UNT of the newly seleted face from that// in remai
ning unfixed facesfor ( i = 0; i < NumIntFent; i++
) pcnew[0].count[i] -= pcnew[facenew].count[i] ;f
or ( i = 0; i < NumIntFentGroup; i++ ) pcnew[0].gc
ount[i] -= pcnew[facenew].gcount[i] ;return (0) ;}
//////////////////////////////////////////////////
//////////////////// この関数はカウンタを更新して
固定面を開放する。解放された面は現在nface////
fixed位置にある面である。////////////////////
//////////////////////////////////////////////////
void change_counts_for_unfix_one_face ( int *pn
ewmatrix, int *pnewmatchlist, FENTCOUNT *pcne
w, int matrixdim, int nfacefixed){// input/
/pnewmatrix- the new part's topological matrix, wh
ere//the FENT contents have been changed to//their
representing integers.//
(integer array of matrixdim * matrixdim)//pnewmatc
hlist- the list of entries of the newmatrix that /
/ has been matched by the oldmatrix.//(integer ar
ray of matrixdim)//pcnew- the FENTCOUNT of all the
faces.//matrixdim- the matrix dimension of both m
atrices//nfacematched- the number of entries (face
s) that has// been fixed in matching the two matr
ices.// output//pcnew- the updated FENTCOUNT of al
l the faces// get the tobe unfixed face number and
// define the pointer to the FENT on the to be fix
ed faceint facenew = *(pnewmatchlist+nfacefixed-1)
;int *pnewrow =pnewmatrix + (facenew-1)*matrixdim
;// first change the counters for thepreviously f
ixed facesfor ( int i = 0 ; i < nfacefixed-1 ; i++
) {int newcol = *(pnewmatchlist+i) ;int pnewv =
*(pnewrow + newcol - 1) ;pcnew[newcol].count[pnew
v]++ ;int igroup = fent_group (pnewv) ;pcnew[newco
l].gcount[igroup]++ ;}// second change the counter
s for the unfixed faces by// adding the FENTCOUNT
of the to be released face to that// of the remain
ing unfixed facesfor ( i = 0; i < NumIntFent; i++
) pcnew[0].count[i]+= pcnew[facenew].count[i] ;fo
r ( i = 0; i < NumIntFentGroup; i++ ) pcnew[0].gco
unt[i] += pcnew[facenew].gcount[i] ;}/////////////
//////////////////////////////////////////////////
////////// この関数は所与のintfentの配列に
おけるFENTsの個数をカウントす//// る。//////
//////////////////////////////////////////////////
/////////////////FENTCOUNT count_fents ( int *pint
fentarray, int arraydim){// input//pintfentarray-
the pointer to the intfent array//arraydim- the di
mension of the intfent array// output//return- FEN
TCOUNT, the FENT count of the// input array//defi
ne an FENT count and initialize itstatic FENTCOUNT
fentc ;for ( intj = 0; j < NumIntFent; j++ ) fent
c.count[j] = 0 ;for ( j = 0; j < NumIntFentGroup;
j++ ) fentc.gcount[j] = 0 ;// Count the numbers of
fents inan array of intfentfor ( int *i = pintfen
tarray ; i < pintfentarray+arraydim ; i++ ) {fent
c.count[*i]++ ;fentc.gcount[fent_group(*i)]++ ;}re
turn(fentc) ;}////////////////////////////////////
////////////////////////////////// この関数は特定
の組のintfent配列におけるFENTsの個数を
カウント//// する。//////////////////////////////
////////////////////////////////////////FENTCOUNT
count_specified_fents ( int *pintfentarray,int *lo
cationlist, int arraydim, int listdim){// input//p
intfentarray- the pointer to the intfent array//lo
cationlist- the locations in the intfent array//
that are to be included in counting//arraydim- the
dimension of the intfent array//listdim- the dime
nsion of the location list//output//return- FENTCO
UNT, the FENT count of the// selected elements in
the input array// define an FENT count and initia
lize itstatic FENTCOUNT fentc ;for ( int j = 0; j
< NumIntFent; j++ ) fentc.count[j] = 0 ;for( j =
0; j < NumIntFentGroup; j++ ) fentc.gcount[j] = 0
;// Count the numbers of fents in an array of int
fentfor ( int *i = locationlist ; i <locationlist+
listdim ; i++ ) {int intfent = *(pintfentarray+(*
i)-1) ;fentc.count[intfent]++ ;fentc.gcount[fent_g
roup(intfent)]++ ;}return (fentc) ;}//////////////
//////////////////////////////////////////////////
///////////// この関数は特定の組のintfentマトリク
スにおけるFENTsの個数をカウントする。////注
意:intfentマトリクスは対称である。マトリク
スの半分だけがカウントに含ま//// れる。//////
//////////////////////////////////////////////////
/////////////////////FENTCOUNT count_specified_fen
ts_matrix ( int *pintfentmatrix,int *locationlist,
int matrixdim,int listdim){// input//pintfentmatr
ix- the pointer to the intfent matrix//locationlis
t- the locations in the intfent matrix// that are
to be included in counting//matrixdim- the dimens
ion of the intfent matrix//listdim- the dimension
of the location list// output//return- FENTCOUNT,
theFENT count of the// selected elements in the i
nput matrix// define anFENT count and initialize i
tstatic FENTCOUNT fentc ;for ( int j = 0; j <NumIn
tFent; j++ ) fentc.count[j] = 0 ;for ( j = 0; j <
NumIntFentGroup;j++ ) fentc.gcount[j] = 0 ;// Coun
t the numbers of fents in an matrix of intfentfor
( int i = 0 ; i < listdim ; i++ ) {int facenum = *
(locationlist+i) ;int *pintfentrow = pintfentmatri
x + (facenum - 1)*matrixdim ;//Note: only half of
the symmetric matrix is counted =>// the k i
satarted from i (diagonal included).for ( int k =
i ; k < listdim ; k++ ){ int intfent = *(pintfentr
ow+(*(locationlist+k))-1) ;fentc.count[intfent]++
;fentc.gcount[fent_group(intfent)]++ ;}}return (f
entc) ;}//////////////////////////////////////////
/////////////////////////// この関数は不一致な対
のFENTに対してペナルテイを戻す。//////////////////
//////////////////////////////////////////////////
/int penalty_of_fent_pair ( int intfent1, int intf
ent2){// input//intfent1- the intfent of part 1//i
ntfent2- the intfent of part 2// output//return- t
he penalty for the mismatched intfents.// No penal
ty, if they are the sameif (intfent1 == intfent2)r
eturn (0) ;// add the penalty for mismatching the
individual intfentintindexvalue = 0;indexvalue +=
fent_weight(intfent1) ;indexvalue += fent_weight(i
ntfent2) ;// add the penalty for mismatching their
fent groupintfentgroup1 = fent_group(intfent1) ;i
nt fentgroup2 = fent_group(intfent2) ;if (fentgrou
p1 != fentgroup2) {indexvalue += fent_group_weight
(fentgroup1) ;indexvalue += fent_group_weight(fent
group2) ;}return (indexvalue);}///////////////////
/////////////////////////////////////////////////
この関数は2つの最小可能不一致に対して最小ペナルテ
イを戻す。////////////////////////////////////////
////////////////////////////int penalty_of_FENTCOU
NT_pair ( FENTCOUNT const &fentcount1,FENTCOUNT co
nst &fentcount2){// input//fentcount1- the FENTCOU
NT of part 1//fentcount2- the FENTCOUNT of part 2/
/ output//return- the minimum penalty on the misma
tches//of two FENTCOUNTs.// Now loop thru the FENT
COUNT, // currently method uses the penalty of the
minimum possible // individualmismatches as the
penalty plus the penalty of// the minimum possible
mismatched groupsint indexvalue = 0;for ( int i =
1; i < NumIntFent; i++ )if ( fentcount1.count[i]
!= fentcount2.count[i] )indexvalue += fent_weight
(i) * abs ( fentcount1.count[i] - fentcount2.count
[i] ) ;for ( i = 1; i< NumIntFentGroup; i++ )if (
fentcount1.gcount[i] != fentcount2.gcount[i] )inde
xvalue += fent_group_weight(i) * abs ( fentcount1.
gcount[i] - fentcount2.gcount[i] ) ;return (indexv
alue) ;}//////////////////////////////////////////
////////////////////////// この関数は不一致対のF
ENTのペナルテイを戻す。////////////////////////
//////////////////////////////////////////int chan
ge_from_seperate_fent_sets ( int ntnew, int ntold,
int nsnew, int nsold ){// input//ntnew- number of
FENT in the whole set of the new part.//ntold- nu
mber of FENT in the whole set of the old part.//ns
new- number of FENT in the sub-set of the new par
t.//nsold- number of FENT in the sub-set of the ol
d 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-ns
old ) ;int diffnew = abs( ntnew-nsnew-ntold+nsold
) ;intchange = diffsub + diffnew - difforg ;retur
n ( 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 - tobe seperated FENT
of the new part//intfentold_separ - to be seperate
d FENT of the old part// output//return- the incre
ase in the penalty due tothe//
seperation of the FENTs.static int ntnew, ntold, i
group ;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 ) ;n
tnew = 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_group
_weight(igroup) *change_from_seperate_fent_sets(nt
new, ntold, 0, 1 ) ;}}return (increase) ;}////////
//////////////////////////////////////////////////
/////////////////// この関数は2つのFENTCO
UNTの最小可能不一致に対する最小ペネルテイを戻
す。//////////////////////////////////////////////
///////////////////////////////int increase_from_s
eparate_a_pair_of_fentcount (FENTCOUNT const &pcne
w_total,FENTCOUNT const &pcold_total,FENTCOUNT con
st &pcnew_separ,FENTCOUNT const &pcold_separ){// i
nput//pcnew_total- the total FENTCOUNT of the new
part//pcold_total- the total FENTCOUNT of the old
part//pcnew_separ- to be seperated FENTCOUNT of th
e new part//pcold_separ- to be seperated FENTCOUNT
of the old part// output//return- the increase in
the penalty due to the//seperation of the FENTCOU
NTs.// Now loop thru the FENTCOUNT, // currently m
ethod uses the penalty of the minimum possible //
individual mismatches as the penalty plus the pen
alty of// the minimum possible mismatched groupsin
t change, increase ;increase = 0;for ( int i = 1;
i < NumIntFent; i++ ) {change = change_from_seper
ate_fent_sets (pcnew_total.count[i], pcold_total.c
ount[i],pcnew_separ.count[i], pcold_separ.count[i]
) ;if ( change != 0 ) increase += fent_weight(i)
* change ;}for( i = 1; i < NumIntFentGroup; i++ )
{change = change_from_seperate_fent_sets (pcnew_to
tal.gcount[i], pcold_total.gcount[i],pcnew_separ.g
count[i], pcold_separ.gcount[i] ) ;if ( change !=
0 ) increase += fent_group_weight(i) * change ;}re
turn (increase) ;}////////////////////////////////
////////////////////////////////////////// この関
数は特定の固定した面までの所与の組の面に対して相似
の指数を計算する。//// 注意:マトリクスの半分だけ
が計算に含まれる。////////////////////////////////
//////////////////////////////////////////int dire
ct_calculate_similarity_index ( int *pnewmatri
x, int *pnewmatchlist, int *poldmatrix,
int *poldmatchlist,int matrixdim){// loop thru th
e faces and calculate the similarity indexint inde
xvalue = 0 ;for (int iface = 0; iface < matrixdim;
iface++) {int facenew = *(pnewmatchlist+iface) ;i
nt faceold = *(poldmatchlist+iface) ;int *pnewrow
= pnewmatrix + (facenew - 1)*matrixdim ;int *poldr
ow = poldmatrix + (faceold - 1)*matrixdim ;// firs
t from the mismatches of the fixed faces.// Note:
the diagonal terms of the matrix are always iNoRel
ation.// therefore, they are skip in the loo
p.// also due to the symmetry, only half of
the matrix are// included in thecalculation
of the similarity indexfor (int icol = iface; icol
< matrixdim; icol++) {int newcol = *(pnewmatchlis
t+icol) ;int oldcol = *(poldmatchlist+icol) ;int p
newv = *(pnewrow + newcol - 1) ;int poldv = *(pold
row+ oldcol - 1) ;if ( pnewv != poldv ) indexvalue
+= penalty_of_fent_pair(pnewv,poldv) ;}}return (i
ndexvalue) ;}/////////////////////////////////////
/////////////////////////////////// この関数は特
定の固定した面までの所与の組の面に対する相似の指数
を計算する。//////////////////////////////////////
//////////////////////////////////int calculate_pa
rtial_similarity_index ( int *pnewmatrix, in
t *pnewmatchlist,FENTCOUNT *pcnew,int *poldmatrix,
int *poldmatchlist, FENTCOUNT *pcold, int m
atrixdim, int nfacefixed){// loop thru the fa
ces and calculate the similarity indexint indexval
ue = 0 ;for (int iface = 0 ; iface < nfacefixed; i
face++) {int facenew = *(pnewmatchlist+iface) ;int
faceold = *(poldmatchlist+iface) ;int *pnewrow =
pnewmatrix + (facenew - 1)*matrixdim ;int *poldrow
= poldmatrix + (faceold - 1)*matrixdim ;// first
from the mismatches of the fixed faces.// Note: th
e diagonal terms of the matrix arealways iNoRelati
on.// therefore, they are skip in the loop./
/also due to the symmetry, only half of the matrix
are// included in the calculation of the si
milarity indexfor (int icol = iface ; icol< nfacef
ixed; icol++) {int newcol = *(pnewmatchlist+icol)
;int oldcol =*(poldmatchlist+icol) ;int pnewv = *
(pnewrow + newcol - 1) ;int poldv =*(poldrow + old
col - 1) ;if ( pnewv != poldv ) indexvalue += pena
lty_of_fent_pair(pnewv,poldv) ;}// use count_speci
fied_fents to initialize theFENTCOUNT of// the fac
enew and faceold and to count the numbers of fents
of // the columns of the unfixed facesint listdim
= matrixdim - nfacefixed ;pcnew[facenew] = count_
specified_fents ( pnewrow, pnewmatchlist+nfacefixe
d, matrixdim, listdim ) ;pcold[faceold] = count_sp
ecified_fents (poldrow, poldmatchlist+nfacefixed,
matrixdim, listdim ) ;// Now loop thru the FENTCOU
NT of the facenew and faceold// and calculate the
penaltyof their mismatches.indexvalue += penalty_o
f_FENTCOUNT_pair ( pcnew[facenew], pcold[faceold]
) ;}// use count_specified_fents_matrix to get th
eFENTCOUNT// of the unfixed faces of both matrices
int listdim = matrixdim - nfacefixed ;pcnew[0] =
count_specified_fents_matrix ( pnewmatrix, pnewmat
chlist+nfacefixed, matrixdim, listdim ) ;pcold[0]
= count_specified_fents_matrix ( poldmatrix, poldm
atchlist+nfacefixed, matrixdim, listdim ) ;// Fina
lly calculate the penalty of the FENTCOUNT// of th
e unfixedfaces of the two matrices.indexvalue += p
enalty_of_FENTCOUNT_pair ( pcnew[0], pcold[0] ) ;
// Return the amount of penalty on the two partial
lyfixed// part matrices as its minimum possible si
milarity index.return (indexvalue);}/
/////////////////////////
/////////////////////////
////////////////////// こ
の関数は所与のfacenewとfaceoldのミス
マッチに対する相似の指//// 数の増加を計算する。/
//////////////////////////////////////////////////
//////////////////////int increase_on_similarity_i
ndex ( int *pnewmatrix, int *pnewmatchlist,
int facenew, int *poldmatrix, int *poldmat
chlist, int faceold, FENTCOUNT *pcnew,FENTCOUNT *
pcold, int *currentvalue, int matrixdim, i
nt nfacefixed, int *minimumvalue){// loop thru
the faces to see how much increase is in the// cu
rrent value.int increase = 0 ;int *pnewrow = pnewm
atrix+ (facenew-1)*matrixdim ;int *poldrow = poldm
atrix + (faceold-1)*matrixdim ;// first loop thru
the previously fixed faces and calculate// the inc
rease for the mismatches between the chosen column
sfor ( int i = 0; i< nfacefixed; i++ ) {int newcol
= *(pnewmatchlist+i) ;int oldcol = *(poldmatchlis
t+i) ;int pnewv = *(pnewrow + newcol - 1) ;int pol
dv = *(poldrow + oldcol - 1) ;if ( pnewv != poldv
) {FENTCOUNT pcnewcol = pcnew[newcol] ;FENTCOUNT
pcoldcol = pcold[oldcol] ;increase += increase_fro
m_separate_a_pair_of_fent (pcnewcol, pcoldcol, pne
wv, poldv ) ;}}// use count_specified_fents to ini
tialize the FENTCOUNT of// the newly seleted face
and count the numbers of fents of // the undetermi
ned columns on the to befixed rowsint listdim = ma
trixdim - nfacefixed ;pcnew[facenew] = count_speci
fied_fents ( pnewrow, pnewmatchlist+nfacefixed, ma
trixdim, listdim) ;pcold[faceold] = count_specifie
d_fents ( poldrow, poldmatchlist+nfacefixed, matri
xdim, listdim ) ;increase += increase_from_separat
e_a_pair_of_fentcount (pcnew[0], pcold[0], pcnew[f
acenew], pcold[faceold] ) ;// Return the amount of
increase in the similarity index for// the matchi
ng of the chosen two faces, facenew in new part//
and the faceold in the oldpart.return (increase);}
付録C // コメントを含むベンドライン検出の例。このモジュ
ールはBM PART:: 自動ベンド( )の実施を含む。
【0359】//* ********** ********** ********** *
********** ********* これは、部分の設計と構成に供
する主要な高レベルベンドモデル関数である。その目的
は、(もし可能なら)部分が接続されるようになるよう
に面間にベンドラインを形成することにある。 この関
数は部分の形成を容易にすることにある。通常は、第三
パーテイの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 variables will be u
sed to do a quick check if these two// facescan po
ssible touch each otherdouble distance_plane_to_bl
oop1, distance_plane_to_bloop2,distance_plane_to_b
loop3, distance_plane_to_bloop4 ;intdistance_plane
_to_bloop_count ;if (! bloop2->is_bbox_up_to_dat
e()) bloop2->recompute_bbox() ;if (! BM_distance_b
etween_point_and_plane(bloop2->get_bbox_p1(), (BM_
PLANE&) (*surface1), &distance_plane_to_bloop1, NU
LL))return 0 ;if (! BM_distance_between_point_and_
plane(bloop2->get_bbox_p2(), (BM_PLANE&) (*surface
1), &distance_plane_to_bloop2, NULL)) return 0;if
(! BM_distance_between_point_and_plane(bloop2->get
_bbox_p3(), (BM_PLANE&) (*surface1), &distance_pla
ne_to_bloop3, NULL)) return 0 ;if (! BM_distance_b
etween_point_and_plane(bloop2->get_bbox_p4(), (BM_
PLANE&) (*surface1), &distance_plane_to_bloop4, NU
LL)) return 0 ;distance_plane_to_bloop_count = 0 ;
if (fabs(distance_plane_to_bloop1) >= local_tolera
nce) distance_plane_to_bloop_count++ ;if (fabs(dis
tance_plane_to_bloop2) >= local_tolerance) distanc
e_plane_to_bloop_count++ ;if (fabs(distance_plane_
to_bloop3) >= local_tolerance) distance_plane_to_b
loop_count++ ;if (fabs(distance_plane_to_bloop4) >
= local_tolerance) distance_plane_to_bloop_count++
;if (distance_plane_to_bloop_count > 2) {// at mo
st one of the bloop corners is on the plane.// tha
t means, bbox itself is not in contactwith face1./
/ however, it could be that different corners of b
box are on different sides of the plane.// here we
will return if all bloop2 points are on one side
of plane1// ie. these two faces cannot be in conta
ct// // note : at most one of the 4 distance_plane
_to_bloop-i can be zero.// // in the next line we
pick "distance_plane_to_bloop1" for checking not b
ecause it is special,// but because any of the 4 w
ould do.if (fabs(distance_plane_to_bloop1) >= loca
l_tolerance) {if (distance_plane_to_bloop1*distanc
e_plane_to_bloop2 >= 0.0 &&distance_plane_to_bloop
1*distance_plane_to_bloop3 >= 0.0 &&distance_plane
_to_bloop1*distance_plane_to_bloop4>= 0.0) return
1 ;}else {if (distance_plane_to_bloop2*distance_pl
ane_to_bloop3 >= 0.0 &&distance_plane_to_bloop2*di
stance_plane_to_bloop4 >= 0.0) return 1 ;}}// if t
he count is 0, 1 or 2, it means that 2, 3 or 4 bbo
x corners are on the plane.// that means, it is po
ssible that there is acontact./* ここで、我々は、
面2に関してbボックス1に対して同じものをチェック
する。*/if (! bloop1->is_bbox_up_to_date()) bloop1
->recompute_bbox() ;if (! BM_distance_between_poin
t_and_plane(bloop1->get_bbox_p1(), (BM_PLANE&) (*s
urface2), &distance_plane_to_bloop1, NULL)) return
0 ;if (! BM_distance_between_point_and_plane(bloo
p1->get_bbox_p2(), (BM_PLANE&)(*surface2), &distan
ce_plane_to_bloop2, NULL)) return 0 ;if (! BM_dist
ance_between_point_and_plane(bloop1->get_bbox_p
3(), (BM_PLANE&) (*surface2), &distance_plane_to_b
loop3, NULL)) return 0 ;if (! BM_distance_between_
point_and_plane(bloop1->get_bbox_p4(), (BM_PLANE&)
(*surface2), &distance_plane_to_bloop4, NULL)) re
turn 0 ;distance_plane_to_bloop_count = 0;if (fabs
(distance_plane_to_bloop1) >= local_tolerance) dis
tance_plane_to_bloop_count++ ;if (fabs(distance_pl
ane_to_bloop2) >= local_tolerance)distance_plane_t
o_bloop_count++ ;if (fabs(distance_plane_to_bloop
3) >= local_tolerance) distance_plane_to_bloop_cou
nt++ ;if (fabs(distance_plane_to_bloop4) >= local_
tolerance) distance_plane_to_bloop_count++ ;if (di
stance_plane_to_bloop_count > 2) {// at most one o
f the bloop corners ison the plane.// here we will
return if all bloop1 points are on one sideof pla
ne2// ie. these two faces cannot be in contactif
(fabs(distance_plane_to_bloop1) >= local_toleranc
e) {if (distance_plane_to_bloop1*distance_plane_to
_bloop2 >= 0.0 &&distance_plane_to_bloop1*distance
_plane_to_bloop3 >= 0.0 &&distance_plane_to_bloop1
*distance_plane_to_bloop4 >= 0.0)return 1 ;}else
{if (distance_plane_to_bloop2*distance_plane_to_bl
oop3>= 0.0 &&distance_plane_to_bloop2*distance_pla
ne_to_bloop4 >= 0.0) return 1 ;}}/*********** ****
****** ********** ********** ********** **********
********** ********** ********** 両面のラインの
全数をカウントする。メモリを割当てる必要がある。
注意:ラインのみがベンドラインを作ることが出来るの
でラインであるエッジを単にカウントする。 注意:ユ
ーザが特定のベンドエッジを持つか否かをチェックす
る。ユーザは、どのエッジが可能なベンドエッジとして
考えられるかを、それらのエッジの名称を設定すること
により限定することが出来る。********** **********
********** ********** ******************** *******
*** ********** ***********/long face1_has_user_def
ined_bend_edges = 0 ; // the number of user-speici
fed bend edges in face1long face2_has_user_defined
_bend_edges = 0 ; // the number of user-speicifed
bend edges in face2long face1_line_count = 0, face
2_line_count = 0 ;long line_count ; // sum of line
s in faces 1 and 2 participating in the sweep.BM_L
OOP *holes ;BM_EDGE *edges ;for (edges = bloop1->g
et_first_edge() ; edges ; edges = (BM_EDGE *) edge
s->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE))
continue ;if (edges->get_name() == face2.get_id
x()) face1_has_user_defined_bend_edges++ ;face1_li
ne_count++ ;}for (holes = body1->get_first_hole()
; holes ; holes = (BM_LOOP *) holes->next()) {for
(edges = holes->get_first_edge() ; edges ; edges
= (BM_EDGE *) edges->next()) {if (! edges->is(BM_E
NTITY_TYPE_LINE)) continue ;if (edges->get_name()=
= face2.get_idx()) face1_has_user_defined_bend_edg
es++ ;face1_line_count++ ;}}for (edges = bloop2->g
et_first_edge() ; edges ; edges = (BM_EDGE*) edges
->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE)) c
ontinue ;if (edges->get_name() == face1.get_idx())
face2_has_user_defined_bend_edges++ ;face2_line_c
ount++ ;}for (holes = body2->get_first_hole() ; ho
les ; holes = (BM_LOOP *) holes->next()) {for (edg
es = holes->get_first_edge(); edges ; edges = (BM_
EDGE *) edges->next()) {if (! edges->is(BM_ENTITY_
TYPE_LINE)) continue ;if (edges->get_name() == fac
e1.get_idx()) face2_has_user_defined_bend_edges++
;face2_line_count++ ;}}// if there are no lines,
we are successfully doneif (face1_has_user_defined
_bend_edges) face1_line_count = face1_has_user_def
ined_bend_edges ;if (face2_has_user_defined_bend_e
dges) face2_line_count = face2_has_user_defined_be
nd_edges ;if (face1_line_count < 1 || face2_line_c
ount < 1) return 1 ;line_count =face1_line_count +
face2_line_count ;/*********** ********** *******
************* ********** ********** ********** ***
******* **********メモリを割り当てる。********** *
********* ********** ********** ********** *******
*** ********** ********** ***********/if (NULL ==
(line_pointers = new BM_LINE*[line_count])) return
0 ;if (NULL == (line_start_coordinates= new doubl
e[line_count])) {delete [] line_pointers ;}/******
***** ********** ********** ********** **********
********** ********** ********************先ず、ラ
インポインタ配列を充填する。必要なら、ユーザが特定
したエッジだけを取る。********** ********** ******
**** ********** ******************** ********** **
******** ***********/i = 0 ;for (edges = bloop1->g
et_first_edge() ; edges ; edges = (BM_EDGE *) edge
s->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE))
continue ;if (face1_has_user_defined_bend_edges &&
edges->get_name() != face2.get_idx()) continue ;l
ine_pointers[i++] = (BM_LINE *) edges ;}for (holes
= body1->get_first_hole() ; holes; holes = (BM_LO
OP *) holes->next()) {for (edges = holes->get_firs
t_edge() ; edges ; edges = (BM_EDGE *) edges->next
()) {if (! edges->is(BM_ENTITY_TYPE_LINE)) continu
e ;if (face1_has_user_defined_bend_edges && edges-
>get_name() != face2.get_idx()) continue ;line_poi
nters[i++] = (BM_LINE*) edges ;}}for (edges = bloo
p2->get_first_edge() ; edges ; edges = (BM_EDGE *)
edges->next()) {if (! edges->is(BM_ENTITY_TYPE_LI
NE)) continue ;if (face2_has_user_defined_bend_edg
es && edges->get_name() != face1.get_idx()) contin
ue ;line_pointers[i++] = (BM_LINE *) edges ;}for
(holes = body2->get_first_hole() ; holes ; holes =
(BM_LOOP *) holes->next()) {for(edges = holes->ge
t_first_edge() ; edges ; edges = (BM_EDGE *) edges
->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE)) c
ontinue ;if (face2_has_user_defined_bend_edges &&
edges->get_name() != face1.get_idx()) continue;lin
e_pointers[i++] = (BM_LINE *) edges ;}}/**********
* ********** ********** ********** ********** ****
****** ********** ********** **********X座標によ
り、つぎにZ座標により、さらにYによりラインの配列
を分類する。********** ********** ********** *****
***** ********** ********** ********** **********
***********/{ // this is a block of code for sorti
ng the array// first, construct the array of point
s and lines associated with themfor (i = 0 ; i < l
ine_count ; i++) {p = BM_get_greater_point_by_XZY
((line_pointers[i])->get_startpt(),(line_pointers
[i])->get_endpt()) ;line_start_coordinates[i] = p.
X() ;}// sort by XDBM_QuickSort_double(line_start_
coordinates, line_count, (long *) line_pointers) ;
// sort by Zdouble first_in_set_Z = line_start_coo
rdinates[0] ;long set_Z_size = 1, first_in_set_Z_i
dx = 0 ;p = BM_get_greater_point_by_XZY((line_poin
ters[0])->get_startpt(),(line_pointers[0])->get_en
dpt()) ;line_start_coordinates[0] = p.Z() ;for (i
= 1 ; i <= line_count ; i++) {if (i < line_count)
{p =BM_get_greater_point_by_XZY((line_pointers[i])
->get_startpt(),(line_pointers[i])->get_endpt()) ;
if (line_start_coordinates[i] == first_in_set_Z)
{set_Z_size++ ;line_start_coordinates[i] = p.Z() ;
continue ;}}// elsewe have passed the end of the X
-sequenceif (set_Z_size > 1) DBM_QuickSort_double
(line_start_coordinates + first_in_set_Z_idx, set_
Z_size, (long*) line_pointers + first_in_set_Z_id
x) ;// sort by Ylong set_Z_end = first_in_set_Z_id
x + set_Z_size ;double first_in_set_Y = line_start
_coordinates[first_in_set_Z_idx] ;long set_Y_size
= 1, first_in_set_Y_idx = first_in_set_Z_idx ;BM_P
OINT pY(BM_get_greater_point_by_XZY((line_pointers
[first_in_set_Z_idx])->get_startpt(),(line_pointer
s[first_in_set_Z_idx])->get_endpt())) ;line_start_
coordinates[first_in_set_Z_idx] = pY.Y() ;for(j =
first_in_set_Z_idx + 1 ; j <= set_Z_end ; j++) {if
(j < set_Z_end){pY = BM_get_greater_point_by_XZY
((line_pointers[j])->get_startpt(),(line_pointers
[j])->get_endpt()) ;if (line_start_coordinates[j]
== first_in_set_Y) {set_Y_size++ ;line_start_coord
inates[j] = pY.Y() ;continue ;}}//else, we have pa
ssed the end of the Z-sequenceif (set_Y_size > 1)
DBM_QuickSort_double(line_start_coordinates + firs
t_in_set_Y_idx, set_Y_size,(long *) line_pointers
+ first_in_set_Y_idx) ;if (j < set_Z_end) {set_Y_s
ize = 1 ;first_in_set_Y_idx = j ;first_in_set_Y =
line_start_coordinates[j] ;line_start_coordinates
[j] = pY.Y() ;}}if (i < line_count) {set_Z_size =
1 ;first_in_set_Z_idx = i ;first_in_set_Z = line_s
tart_coordinates[i] ;line_start_coordinates[i] =
p.Z() ;}}} // end of the block of codefor sorting
the array/*********** ********** ********** ******
**** ********** ********** ********** ********** *
*********ライン開始座標はこれ以上不要なので、削除
する。********** ********** ********** **********
********** ********** ********** ********** ******
*****/if (line_start_coordinates) {delete [] line_
start_coordinates ;line_start_coordinates = NULL;}
/*********** ********** ********** ********** 主
ループ。2面を掃引する。 開放ラインのトラックを常
に保持する(出発点を我々が見たライン、しかし終点は
未だ見ていないライン-実際には、開始-そして-終了-点
ではなくて、XZYオーダリングに対してより大きくか
つより小さい端点)。 始めに、開放ラインの組は空で
ある。 全ての繰り返しの間次のことを行う: -開
放であったが、今は閉じられるべき全てのラインを除去
する、 -現在のラインが開放ラインと重なるか否か
をチェックする、 -このラインを開放ラインの組に
加える。*/// these represent lists of contactsBM_L
INKED_LIST_NODE *face1_list, *face2_list ;BM_LINKE
D_LIST_NODE *last_face1_list, *last_face2_list;BM_
LINKED_LIST_NODE *left, *right ;BM_LINKED_LIST_NOD
E *new_left = NULL, *new_right = NULL ;BM_LINE *li
ne_in_left, *line_in_right ;// these are the two l
ines we will be comparingBM_2D_BODY *face_of_line
1, *face_of_line2 ;BM_LINE *line_in_face1, *line_i
n_face2 ;BM_LINE *line ;double k,dotp ;BM_POINT p_
open ;BM_VECTOR v ;long num_of_contacts = 0 ;long
open_line_idx ;for (i = line_count - 1 ; i >= 0 ;
i--) {// initially face_of_line1 is the face of th
e current line.// however, later we will sort thec
urrent-sweep-line and current-open-line pointers.f
ace_of_line1 = ((line_pointers[i])->get_loop())->g
et_2D_body() ;p = BM_get_greater_point_by_XZY((lin
e_pointers[i])->get_startpt(),(line_pointers[i])->
get_endpt()) ;// compare this current line against
all open lines in order to detect overlaps, ie. b
endlines.for (open_line_idx = i + 1 ; open_line_id
x < line_count ; open_line_idx++) {line = line_poi
nters[open_line_idx] ;if (NULL== line) {// time-sa
ving trick. if this is the last pointer, there is
no need to try it again.// reduce the index.if (op
en_line_idx == line_count - 1) {--line_count ;brea
k ;}continue ;}// ********** ********** **********
********** **********// check if this open line s
hould really be removed.// it should be removed if
its endpoint is larger than p (ie. the// startpoi
nt of this line).// ********** ********** ********
** ********** **********p_open = BM_get_smaller_po
int_by_XZY(line->get_startpt(),line->get_endpt())
;if (BM_compare_points_by_XZY(p_open,p)) {// time
-saving trick.// if the line we are removing from
the open list is the last one, reduce the index//
instead of setting the pointer to NULL. next timew
e don't even try this element// in the array, beca
use it would be beyond the boundaryif (open_line_i
dx == line_count - 1) {--line_count ;break;}line_p
ointers[open_line_idx] = NULL ;continue ;}// *****
***** ********** ********** ********** **********/
/ first, check if both lines are inthe same face.
if yes, skip it.// ********** ********** *********
* ********** **********face_of_line2 = (line->get_
loop())->get_2D_body() ;if (face_of_line1 == face_
of_line2) continue ;// ********** ********** *****
***** ********** **********// Check if this line a
nd the open line overlap.// ********** **********
********** ********** **********// First check if
the startpoint is on the (open) line segment.if (!
line->is_point_on_line(p,&k)) continue ;// Note t
hat parameter k has to be in [0,1] now,because// t
he line "line" is open still, ie. it startpoint is
"before"p// and endpoint is "after" p.// Now chec
k if vectors are parallel.v = (line->get_v()) *
((line_pointers[i])->get_v()) ;if (v.Len() > BM_PR
ECISION) continue ;// Last thing, it could be that
only endpoints of the lines overlap.dotp = (line-
>get_v()) % ((line_pointers[i])->get_v()) ;if (dot
p < 0.0) { // lines are opposite// startpoint-star
tpoint/endpoint-endpoint should not matchif ((line
->get_startpt()) == ((line_pointers[i])->get_start
pt()) || (line->get_endpt()) == ((line_pointers
[i])->get_endpt())) continue ;}else { // lines hav
e the same direction// startpoint-endpoint/endpoin
t-startpoint should not matchif ((line->get_endp
t()) == ((line_pointers[i])->get_startpt()) || (li
ne->get_startpt()) == ((line_pointers[i])->get_end
pt())) continue ;}// ********** ********** *******
*** ********** **********// Ok, these two lines ov
erlap.// First, sort lines according to which face
they are in// ********** ********** ********** **
******** **********if (&face1 == (BM_FACE *) face_
of_line1->get_3D_body()){line_in_face1 = line_poin
ters[i] ;line_in_face2 = line ;p_face1 = p ;p_face
2 = BM_get_greater_point_by_XZY(line->get_startp
t(),line->get_endpt()) ;}else {line_in_face1 = lin
e ;line_in_face2 = line_pointers[i] ;p_face1 = BM_
get_greater_point_by_XZY(line->get_startpt(),line-
>get_endpt());p_face2 = p ;}// ********** ********
** ********** ********** **********// Scan all kno
wn contacts and check if this contact should be//
addedto an existing contact// ********** *********
* ********** ********** **********for (j = 0, last
_face2_list = NULL ; j < num_of_contacts ; j++) {i
f (NULL == last_face2_list) {last_face1_list = con
tacts ;last_face2_list = last_face1
_list−>next() ;}else {las
t_face1_list = last_face2
_list−>next() ;last_face2
_list = last_face1_list−>
next() ;}left = (BM_LINKE
D_LIST_NODE *) last_face1
_list−>get_obj() ;right =
(BM_LINKED_LIST_NODE *)
last_face2_list−>get_ob
j() ;line_in_left = (BM_L
INE *) left−>get_obj() ;l
ine_in_right = (BM_LINE
*) right−>get_obj() ;// C
heck if the line of thise
xisting contact overlaps
the new contact.// condit
ion is : point on the lin
e and vectors are paralle
l.if (! line_in_left−>is_
point_on_line(p_face1,&
k)) continue ;v = (line_i
n_left−>get_v()) * (line_
in_face1−>get_v()) ;if
(v.Len() > BM_PRECISION)
continue ;// Check that l
ines in face1 and face2 a
nd exact extensions of le
ft and right in this cont
act// this is because we
want every contact in the
list of contacts to be a
”closed”contact// note i
t could be that one of th
e new lines in already in
thiscontact.// then we d
on’t need to check.if (li
ne_in_left != line_in_fac
e1) {dotp = (line_in_left
−>get_v()) % (line_in_fac
e1−>get_v()) ;if (dotp<
0.0) { // lines are oppos
ite// startpoints must ma
tchif ((line_in_left−>get
_startpt()) != (line_in_f
ace1−>get_startpt()) &&(l
ine_in_left−>get_endpt())
!= (line_in_face1−>get_e
ndpt())) continue ;}else
{ // lines have the same
direction// endpoints mus
t matchif ((line_in_left−
>get_endpt()) != (line_in
_face1−>get_startpt()) &&
(line_in_left−>get_startp
t()) !=(line_in_face1−>ge
t_endpt())) continue ;}}i
f (line_in_right != line_
in_face2) {dotp = (line_i
n_right−>get_v()) % (line
_in_face2−>get_v()) ;if
(dotp < 0.0) { // lines a
re opposite// startpoints
must matchif ((line_in_r
ight−>get_startpt()) !=
(line_in_face2−>get_start
pt()) &&(line_in_right−>g
et_endpt()) != (line_in_f
ace2−>get_endpt())) conti
nue ;}else { // lines hav
e the same direction// en
dpoints must matchif ((li
ne_in_right−>get_endpt())
!= (line_in_face2−>get_s
tartpt()) &&(line_in_righ
t−>get_startpt()) != (lin
e_in_face2−>get_endpt()))
continue ;}}// everythin
g is fine.add lines to th
is contact.// note that i
s could be that the line
is already in the contac
t.if (line_in_left != lin
e_in_face1) {if (NULL ==
(new_left = new BM_LINKED
_LIST_NODE(line_in_face1,
NULL,left))) goto failur
e;last_face1_list−>set_ob
j((BM_BASIC *) new_left)
;new_left = NULL ;}if (l
ine_in_right != line_in_f
ace2) {if (NULL == (new_r
ight = new BM_LINKED_LIST
_NODE(line_in_face2,NULL,
right))) goto failure ;la
st_face2_list−>set_obj((B
M_BASIC *) new_right) ;ne
w_right = NULL ;}// now w
e have to breakout of her
e. we added this contact
to an existing contact.br
eak ;}// check if we chec
ked all contacts and coul
d not find a matchif (j <
num_of_contacts) continu
e ;// ********** ********
** ********** **********
**********// Create a new
contact.// ********** **
******** ********** *****
***** **********// First,
create nodes for both li
nes.if (NULL == (left =ne
w BM_LINKED_LIST_NODE(lin
e_in_face1))) goto failur
e ;if (NULL == (right = n
ew BM_LINKED_LIST_NODE(li
ne_in_face2))) {delete le
ft ;goto failure;}// Crea
te lists for both sides o
f the contact.if (NULL ==
(face2_list= new BM_LINK
ED_LIST_NODE((BM_BASIC *)
right))) {delete left ;d
elete right ;goto failure
;}if (NULL == (face1_lis
t = new BM_LINKED_LIST_NO
DE((BM_BASIC *) left,NUL
L,face2_list))) {delete l
eft ;delete right ;delete
face2_list ;goto failure
;}// add the new contact
to the list of contactsi
f(num_of_contacts < 1) co
ntacts = face1_list ;else
last_face2_list−>add_aft
er(face1_list) ;++num_of_
contacts ;}// we use i to
index line_pointers[] ar
ray.// since i will be de
cremented shortly, line_p
ointers[i] willbe ”implic
tly” put on // the open l
ist of sweep lines.}/****
******* ********** ******
**** **********必要ならメモリを自由
にする。********** ********** ********** *********
**/if (line_start_coordinates) delete [] line_star
t_coordinates ;if (line_pointers) delete [] line_p
ointers ;// finally, create a node for the number
of contactsif (NULL == (left = new BM_LINKED_LIST_
NODE((BM_BASIC *) num_of_contacts,NULL,contacts)))
goto failure ;*list_of_contacts = left ;return 1
;failure :// free memory if necessaryif (line_sta
rt_coordinates) delete [] line_start_coordinates ;
if (line_pointers) delete [] line_pointers ;BM_LIN
KED_LIST_NODE *list, *next_list ;BM_LINKED_LIST_NO
DE *line_in_list, *next_line_in_list ;for (list =
contacts ; list ; list = next_list) {next_list = l
ist->next() ;for (line_in_list = (BM_LINKED_LIST_N
ODE *) list->get_obj() ; line_in_list ; line_in_li
st = next_line_in_list) {next_line_in_list = line_
in_list->next() ;delete line_in_list ;}delete list
;}if (new_left) delete new_left ;if (new_right) d
elete new_right ;return 0 ;}/* この関数は2つの面
の間のコンタクトのリストを掃引する (BMにより殆
ど同様に生成される 全ての面から面の接点を計算す
る)そして全ての、ただし最大の接点を除去する。 基
本的には、それは接点のリストを”濾過”し、最も長い
接触部に属さない接触部を除去する。一般に、最も長い
接触部は同時的なベンドラインのリストである点に注目
されたい。かくして、接触部リストの基本構造は同じで
ある。 例えば、リスト中の第一のノードは最も長いコ
ンタクト中のコンタクトの数である。 この関数はまた
最も長いコンタクトの長さに戻す。 この関数において
は、全てのコンタクトが閉じられ、従ってコンタクト中
のラインのリストにおいて、ラインの端点は次のライン
の出発点に等しくなるという事実を利用している。 こ
の方法で唯一のトリッキーな部分は、第一の、および最
後のラインにおける重なり部分の長さを計算することに
ある。次に、リストの中間でラインの長さを付加する。
前の関数を参照されたい。*/static double BM_keep_
largest_contact_remove_the_rest(BM_LINKED_LIST_NOD
E **list_of_contacts){long i, j ;if (NULL == list_
of_contacts) return 0.0 ;BM_LINKED_LIST_NODE *cont
acts = *list_of_contacts ;if (NULL == contacts) re
turn 0.0 ;// some of the most important parameters
we compute in this function.double length_of_larg
est_contact =0.0 ;long largest_contact_i = -1 ;//
we need to keep track of the lengths of contacts./
/ we need to store the length of every contact.//
// NOTICE : here we try to save some heap allocati
on/release time by using a pre-allocated// array i
f the list of contacts is not very long.// static
double static_contact_len_array[32] ;double *dynam
ic_contact_len_array =NULL ;double *contact_len_ar
ray = NULL ;// get the number of contactslong num_
of_contacts = (long) contacts->get_obj() ;contacts
= contacts->next() ;// if no contacts, delete the
entire listif (num_of_contacts < 1) {// there is
no list. delete node 0 as well.delete *list_of_con
tacts ;*list_of_contacts = NULL ;return 0.0 ;}// a
llocate memory for the contact length arrayif (num
_of_contacts <= 32) {contact_len_array = static_co
ntact_len_array ;}else {if (NULL == (dynamic_conta
ct_len_array = new double[num_of_contacts])) goto
computation_done__clean_up ;contact_len_array =dyn
amic_contact_len_array ;}// Scan all known contact
s and compute the length of every contact.// later
we use these values to find the longestcontact (w
hich could be a simultaneous bendline).BM_LINKED_L
IST_NODE *last_face1_list, *last_face2_list ;BM_LI
NKED_LIST_NODE *line_in_list ;double k ;double fir
st_k1, first_k2 ;double last_k1, last_k2 ;last_fac
e2_list = NULL ;for (i = 0 ; i < num_of_contacts ;
i++) {if (NULL == last_face2_list) last_face1_lis
t = contacts ;else last_face1_list = last_face2_li
st->next() ;last_face2_list = last_face1_list->nex
t() ;BM_LINKED_LIST_NODE *left = (BM_LINKED_LIST_N
ODE *) last_face1_list->get_obj() ;BM_LINKED_LIST_
NODE *right = (BM_LINKED_LIST_NODE *) last_face2_l
ist->get_obj() ;BM_LINE *first_line_in_left = (BM_
LINE *) left->get_obj() ;BM_LINE *first_line_in_ri
ght = (BM_LINE *) right->get_obj() ;// here is wha
t we do. we know that the first lines in left and
right have to have// an overlapping part. we compu
te overlapping parameters k1 and k2 with respect t
o the// first line on the left, between the first
lines. // the idea is thatone of the points that c
orresponds to these parameters (k1 and k2)// isthe
extreme point of the contact. we just don't know
yet which one.// then we find the last points in b
oth lists. we know that they must have non-empty//
overlapping part as well. we compute k1 and k2 fo
r these twolines as well.// then we compate k1,k2
for the first and last pairs to find the two// ext
reme points of the contact. distance between them
is the length of the contact.// compute k1 and k2
for the first lines.first_line_in_left->is_point_o
n_line(first_line_in_right->get_startpt(),&first_
k1) ;first_line_in_left−>
is_point_on_line(first_li
ne_in_right−>get_endpt(),
&first_k2) ;// we only wa
nt k1 and k2 within the f
irst lineif (first_k1 <
0.0) first_k1 = 0.0 ;else
if (first_k1 > 1.0) firs
t_k1 = 1.0 ;if (first_k2
< 0.0) first_k2 = 0.0 ;el
se if (first_k2 > 1.0) fi
rst_k2 = 1.0 ;// sort k1
and k2if (first_k1 > firs
t_k2) { k = first_k1 ; fi
rst_k1 = first_k2 ; first
_k2 = k ; }// find the la
st line in the left.for
(line_in_list = left−>nex
t() ; line_in_list ; line
_in_list = line_in_list−>
next()) {left = line_in_l
ist ;}// ”left” is the la
st node in the left now.B
M_LINE *last_line_in_left
= (BM_LINE *) left−>get_
obj() ;// find the last l
ine in the right.for (lin
e_in_list = right−>next()
; line_in_list ; line_in
_list = line_in_list−>nex
t()) {right = line_in_lis
t ;}// ”right” is the las
t node in the left now.BM
_LINE *last_line_in_right
= (BM_LINE *) right−>get
_obj() ;// compute k1 and
k2 for the first lines.l
ast_line_in_left−>is_poin
t_on_line(last_line_in_ri
ght−>get_startpt(),&last_
k1) ;last_line_in_left−>i
s_point_on_line(last_line
_in_right−>get_endpt(),&l
ast_k2);// we only want k
1 and k2 within the last
lineif (last_k1 < 0.0) la
st_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 comp
ute last k1 and k2 with r
espect to the last line i
n the left.// we really n
eed last k1 and k2 with r
espect to the first line
in the left.BM_POINT last
k1(last_line_in_left−>get
_startpt() + last_k1*(las
t_line_in_left−>get_v()))
;BM_POINT lastk2(last_li
ne_in_left−>get_startpt()
+ last_k2*(last_line_in_
left−>get_v())) ;first_li
ne_in_left−>is_point_on_l
ine(lastk1,&last_k1) ;fir
st_line_in_left−>is_point
_on_line(lastk2,&last_k2)
;//sort k1 and k2if (las
t_k1 > last_k2) { k = las
t_k1 ; last_k1 = last_k2;
last_k2 = k ; }// now we
need to take the extreme
points of these twopairs
if (first_k1 > last_k1) f
irst_k1 = last_k1 ;if (fi
rst_k2 < last_k2)first_k2
= last_k2 ;contact_len_a
rray[i] = (first_k2 − fir
st_k1)*(first_line_in_lef
t−>get_len()) ;}// find t
he longest contact.// the
main feature here is to
check for simultaneous be
ndlineslast_face2_list =
NULL ;for (i = 0 ; i < nu
m_of_contacts ; i++) {if
(NULL == last_face2_list)
last_face1_list = contac
ts ;else last_face1_list
= last_face2_list−>nex
t();last_face2_list = las
t_face1_list−>next() ;//
make sure we don’t accept
contacts that have zero l
ength.if (contact_len_arr
ay[i] < BM_PRECISION)cont
inue ;BM_LINKED_LIST_NODE
*left = (BM_LINKED_LIST_
NODE *) last_face1_list−>
get_obj() ;BM_LINE *first
_line_in_left = (BM_LINE
*) left−>get_obj() ;// ch
eck if this contact is pa
rt of a simultaneous bend
line.// ifyes, add its le
ngth to the first bendlin
e in the simultaneous ben
dline and// set this leng
th here to −1.0, so that
we know it laterBM_LINKED
_LIST_NODE *temp_last_fac
e1_list, *temp_last_face2
_list = NULL ;for (j = 0
;j < i ; j++) {if (conta
ct_len_array[i] < BM_PREC
ISION) continue ; // alre
ady part of something els
eif (NULL == temp_last_fa
ce2_list) temp_last_face1
_list = contacts ;else te
mp_last_face1_list = temp
_last_face2_list−>next()
;temp_last_face2_list =
temp_last_face1_list−>nex
t() ;BM_LINKED_LIST_NODE
*temp_left = (BM_LINKED_L
IST_NODE *) temp_last_fac
e1_list−>get_obj() ;BM_LI
NE *temp_first_line_in_le
ft = (BM_LINE *) temp_lef
t−>get_obj() ;// check if
the lines overlapif (! f
irst_line_in_left−>is_poi
nt_on_line(temp_first_lin
e_in_left−>get_startpt(),
NULL)) continue ;if (! fi
rst_line_in_left−>is_poin
t_on_line(temp_first_line
_in_left−>get_endpt(),NUL
L)) continue ;// ok, they
overlap// add the length
to the first in simultan
eous bend and set this to
−1.0contact_len_array[j]
+= contact_len_array[i]
;contact_len_array[i] =
−1.0 ;break ;}}// in this
loop we actuallyfind the
largestfor (i = 0 ; i <
num_of_contacts ; i++) {/
/ check to see if this ne
w contact is the largesti
f (length_of_largest_cont
act < contact_len_array
[i]) {length_of_largest_c
ontact = contact_len_arra
y[i] ;largest_contact_i =
i ;}}computation_done__c
lean_up :// remove all ot
her contacts that are not
largestBM_LINKED_LIST_NO
DE *next_last_face1_list,
*next_last_face2_list =
NULL ;BM_LINKED_LIST_NODE
*largest_contact_list_f1
= NULL, *largest_contact_
list_f2 ;last_face1_list
= contacts ;last_face2_li
st = last_face1_list−>nex
t() ;for (i = j = 0 ; i <
num_of_contacts ;i++) {n
ext_last_face1_list = las
t_face2_list−>next() ;if
(next_last_face1_list) ne
xt_last_face2_list = next
_last_face1_list−>next()
;else next_last_face2_li
st = NULL ;// make sure w
e don’t delete the larges
t contact// note : we ski
p two lists, face1 list a
nd face2 listif (contact_
len_array[i] < 0.0 || lar
gest_contact_i == i) {if
(NULL == largest_contact_
list_f1) largest_contact_
list_f1 = last_face1_list
;else largest_contact_li
st_f2−>add_after(last_fac
e1_list) ;largest_contact
_list_f2 = last_face2_lis
t ;// count the number of
contacts++j ;last_face1_
list = next_last_face1_li
st ;last_face2_list = nex
t_last_face2_list ;contin
ue ;}// ok, thisis not th
e largest contact, delete
both face1 and face2 sid
es of the contactBM_LINKE
D_LIST_NODE *next_line_in
_list ;for (line_in_list
= (BM_LINKED_LIST_NODE *)
last_face1_list−>get_obj
() ; line_in_list ; line_
in_list = next_line_in_li
st) {next_line_in_list =
line_in_list−>next() ;del
eteline_in_list ;}for (li
ne_in_list = (BM_LINKED_L
IST_NODE *) last_face2_li
st−>get_obj() ; line_in_l
ist ; line_in_list = next
_line_in_list) {next_line
_in_list = line_in_list−>
next() ;delete line_in_li
st ;}delete last_face1_li
st ;delete last_face2_lis
t ;last_face1_list = next
_last_face1_list ;last_fa
ce2_list = next_last_face
2_list ;}// end the conta
ct list witha NULL pointe
rif (largest_contact_list
_f2) largest_contact_list
_f2−>add_after(NULL) ;//
write the number of conta
cts left in node 0. also,
setthe correct beginning
of the list.// however,
if there is no contact, e
rase the entire list.if
(NULL == largest_contact_
list_f1) {// there is nol
ist. delete node 0 as wel
l.delete *list_of_contact
s ;*list_of_contacts= NUL
L ;}else {(*list_of_conta
cts)−>set_obj((BM_BASIC
*) j) ;(*list_of_contact
s)−>add_after(largest_con
tact_list_f1) ;}// delete
dynamic_contact_len_arra
y if it was allocatedif
(dynamic_contact_len_arra
y) delete []dynamic_conta
ct_len_array ;return leng
th_of_largest_contact ;}/
* この関数は、サブルーチンとして静的なint B
M create ベンドライン(...)によっての
み用いられる。 現在の大きな問題は、我々が幾つかの
ラインを削除しているということである。 この問題
は、我々が同時ベンドを持つとき、他のコンタクトはな
お我々が丁度削除したこれらのラインを参照しているこ
とが出来るということである。 我々は進んでそれをチ
ェックしなければならず、もし真なら、有効な参照によ
りポインタを我々が変更し/削除したラインに置き換え
なければならない。 すなわち、影響されたラインは左
側の最初のそして最後のラインである。 潜在的には、
それらに対する参照は11および13を参照して置き換
えられる必要がある。*/static void check_references
_in_remaining_contacts(BM_LINKED_LIST_NODE *side_
1, // current list we are workingwithBM_LINKED_LIS
T_NODE *side_2, // list on the other side of the c
ontactBM_LINE *line1, BM_LINE *line3, // these are
old references, to be checked if still validBM_LI
NE *l1, BM_LINE *l3 // l1 and l3 are the new refer
ences){BM_LINKED_LIST_NODE *side1 = side_1, *side2
= side_2 ;process_next_contact :// find the begin
nings of lists in the next contactBM_LINKED_LIST_N
ODE *contact_list ;if (NULL == (contact_list = sid
e1->next())) return ; // done, no more listsif (NU
LL == (side1 = contact_list->next())) return ; //
done, no more listsif (NULL == (contact_list = sid
e2->next())) return ; // done, no more listsif (NU
LL == (side2 = contact_list->next())) return ; //
done, no more lists// now we need to check the beg
inning of this contact and the end of this contact
exactly the same way.//we describe checking the b
eginning, check the end is the same.// whenever we
find a match, we can go to the next list (ie. do
n't have to continue with the// current list).// /
/ we take first lines is side1 and side2. if the f
irst line in side1 is either line1 or line3,// we
check whichof l1 and l3 overlaps the first line in
side2. we know that exactly oneof// l1 and l3 has
to overlap. then we replace the reference to line
1/line3 with a reference to the// one of l1/l3 tha
t overlaps the first linein side2.BM_LINKED_LIST_N
ODE *start_side1 = (BM_LINKED_LIST_NODE *) side1->
get_obj() ;BM_LINKED_LIST_NODE *start_side2 = (BM_
LINKED_LIST_NODE *)side2->get_obj() ;// check the
beginning of the contactBM_LINE *line_in_side1 =
(BM_LINE *) start_side1->get_obj() ;BM_LINE *line_
in_side2 = (BM_LINE *) start_side2->get_obj() ;if
(line_in_side1 == line1 || line_in_side1 == line3)
{if (l1) { // check if l1 overlaps first line in
side2if(line_in_side2->is_point_on_line_segment(l1
->get_startpt(), NULL) ||line_in_side2->is_point_o
n_line_segment(l1->get_endpt(), NULL)) {start_side
1->set_obj(l1) ;goto process_next_contact ;}}if (l
3) { // 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 process_next_contact ;}BM_LINKED_LI
ST_NODE *line_in_list, *prev_line_in_list ;// find
the lastline in side2.for (line_in_list = start_s
ide2->next() ; line_in_list ; line_in_list = line_
in_list->next()) {prev_line_in_list = line_in_list
;}// "prev_line_in_list" is the last node in the
left now.line_in_side2 =(BM_LINE *) prev_line_in_l
ist->get_obj() ;// find the last line in side1.for
(line_in_list = start_side1->next() ; line_in_lis
t ; line_in_list =line_in_list->next()) {prev_line
_in_list = line_in_list ;}// "prev_line_in_list" i
s the last node in side1 now.line_in_side1 = (BM_L
INE *) prev_line_in_list->get_obj() ;// check the
end of the contactif (line_in_side1 == line1 || li
ne_in_side1 == line3) {if (l1) { // check if l1 ov
erlaps first line in side2if (line_in_side2->is_po
int_on_line_segment(l1->get_startpt(), NULL) ||lin
e_in_side2->is_point_on_line_segment(l1->get_endpt
(), NULL)) {prev_line_in_list->set_obj(l1) ;goto p
rocess_next_contact ;}}if (l3) { // check if l3 ov
erlaps first line in side2if (line_in_side2->is_po
int_on_line_segment(l3->get_startpt(), NULL) ||lin
e_in_side2->is_point_on_line_segment(l3->get_endpt
(), NULL)) prev_line_in_list->set_obj(l3) ;}}goto
process_next_contact ;}/* この関数は、入力として
与えられたコンタクトリストに基づいて、2つの面間に
簡単な(規則的な)ベンドラインを形成する。一端これ
がなされると、それはコンタクトリストを消去する。
この関数では、面のエッジは左手の規則に従って分類さ
れると仮定する。 この関数は、もし全てがファインの
ときは、TRUEに戻す。 NB!ここでの問題点は、
新しいベンドラインを形成したとき、何かを部分的に無
効にすることではない。 それを完成するために、我々
は、分離であるベンドopを形成し(ベンドライン無し
に)(原文理解出来ず)、後にそれをベンドラインに付
加する。 更に、我々は、ベンドラインが形成され、部
分に付加された後にのみトポロジーを形成する。 この
関数は、面1(主として、垂直な面1)に一致するベン
ドライン情報を形成する点に注目されたい。 ただし、
垂直な面2はこの情報と不一致でもよいが、後に固定さ
れなければならない。*/static int BM_create_bendlin
e(BM_PART & part, BM_LINKED_LIST_NODE **contact, B
M_BENDLINE **bendline_created /* OUT */){// so fa
r, nothing is created*bendline_created = NULL ;//
it is possible, that we are building bendlines for
the flat version of the part.// if this variables
is TRUE, we are building bendlines for the 3D-ver
sion, otherwise for the flat.int using_3D_version
= 1 ;// laterwe need to create a bendline centerli
ne// these are the start-end points of the bendlin
e centerline// note that they are points p1 and p2
on the face1 side of the bendline// this is done
because sometimes (when thebendline is not bent) w
e use the// face1 surface as the bendline surface,
ie. the bendline orientation is defined// with re
spect to face1BM_POINT bendline_centerline_p1, ben
dline_centerline_p2 ;// contact list parametersBM_
LINKED_LIST_NODE *line_in_list, *next_line_in_list
;BM_LINKED_LIST_NODE *left, *right ;int number_of
_lists = (long) (*contact)->get_obj();BM_LINKED_LI
ST_NODE *contact_list = (*contact)->next() ;left =
(BM_LINKED_LIST_NODE *) contact_list->get_obj() ;
right = (BM_LINKED_LIST_NODE *) (contact_list->nex
t())->get_obj() ;BM_LINE *first_line_in_left = (BM
_LINE *) left->get_obj() ;BM_LINE *first_line_in_r
ight = (BM_LINE *) right->get_obj() ;BM_LINE *last
_line_in_left ;BM_LINE *left_line, *right_line;//
get loops in both bodiesBM_LOOP *face1_loop = firs
t_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-bodie
s of eitherfaceBM_2D_BODY *face1_body = face1_loop
->get_2D_body() ;BM_2D_BODY *face2_body = face2_lo
op->get_2D_body() ;if (NULL == face1_body || NULL
== face2_body) 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 ;// check whether we are using the flat version
of the part, or 3D-version of the part.if (face1-
>get_current_3D_version() != face1_body || face2->
get_current_3D_version() != face2_body) using_3D_v
ersion = 0 ;// get surfaces of either facesBM_PLAN
E *face1_plane, *face2_plane ;face1_plane = (BM_PL
ANE *)face1_body->get_surface() ;face2_plane = (BM
_PLANE *) face2_body->get_surface() ;/* 先ず、ベ
ンドラインと共にしなければならない全てのこと、ベン
ドラインを形成する、ベンドopを形成する、ベンドo
pパラメータを設定する、ベンドラインに対するシリン
ダを形成、設定する、ベンドライン、センタラインを設
定するなどを行う。*/// try to figure out whether w
e have a FRONT or BACK bend.BM_VECTOR v_face2_body
((face2_plane->get_normal())*(first_line_in_right-
>get_v())) ; // this vector// points towards the i
nside of face2 on the plane of face2BM_VECTOR v_fa
ce2_normal(v_face2_body*(first_line_in_left->get_v
())) ; // this is the correct normal for face2 ?//
compute the angle between facesdouble angle = v_f
ace2_normal ∧ (face1_plane->get_normal()) ;// com
pute bend type (FRONT/BACK)if (fabs(angle) <= BM_A
NGLE_TOLERANCE) angle = PI ;else {BM_VECTOR v((fac
e1_plane->get_normal())*v_face2_normal) ;if (v %
(first_line_in_left->get_v()) > 0.0) angle =PI + a
ngle ; // BACK bendelse angle = PI - angle ; // FR
ONT bend}// create a new empty bendline and add it
to the partBM_2D_BODY *new_auto_bendline = new BM
_2D_BODY ;if (NULL == new_auto_bendline) return 0
;BM_BENDLINE *new_bendline = new BM_BENDLINE(&par
t, using_3D_version ? NULL : new_auto_bendline, us
ing_3D_version ? new_auto_bendline : NULL) ;if (NU
LL == new_bendline) {delete new_auto_bendline ;ret
urn 0 ;}// create a regular bend op for the bendli
neBM_BEND_OP_REGULAR *new_bend_op = new BM_BEND_OP
_REGULAR(NULL,angle,0.0,0.0) ; // don't attach to
bendline yetif (NULL== new_bend_op) {delete new_be
ndline ;return 0 ;}// attach this bend opto the be
ndline. this will just assign the bend_op variable
in the bendlinenew_bendline->attach_bend_op(new_b
end_op) ;// create bendline surface. if angle is n
ot 180 degrees, we create a cylinder, otherwise a
(face1) plane.BM_SURFACE *bend_surface ;if (fabs(a
ngle - PI) <= BM_ANGLE_TOLERANCE) { // bendline no
t being bent// note : face1 plane is the bendlines
urfacebend_surface = new BM_PLANE(*face1_plane) ;n
ew_bendline->Do_This_Bend(0) ; // this will invali
date 3D version as well. later we validateit.// se
t sense to the same as face1 sensenew_auto_bendlin
e->set_sense(face1_body->get_sense()) ;}else {// f
irst, compute vxBM_VECTOR v_face1_body((face1_plan
e->get_normal())*(first_line_in_left->get_v())) ;/
/ v_face1_body 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) ; // invert and normalize// this is the vx
vector of the bendline surfaceBM_VECTOR vx(v_face1
_body + v_face2_body) ;bend_surface = new BM_CYLIN
DER(first_line_in_left->get_startpt(), first_line_
in_left->get_endpt(), vx, 0.0) ;new_bendline->Do_T
his_Bend(1) ; // this will invalidate 3Dversion as
well. later we validate it.// set sense to 0, bec
ause we wantthe bendline (cylinder) to represent e
xplicitly OUTSIDE// ie. thicknessvector is opposit
e to the normal (= radius vector).new_auto_bendlin
e->set_sense(0) ;}if (NULL == bend_surface) {delet
e new_bendline ;return 0 ;}new_auto_bendline->set_
surface(bend_surface) ;// lastly we need to create
the bendline centerline, but for that we need to
know its length, and// start-end-points. However,
for that we need to process the contact list which
contains the// lines that are adjacent. We will d
o that next, and when done, will create bendline c
enterline./* 第二に、必要なら、幾つかのラインを破
断し、全ての隣接ラインを1つの隣接ラインに結合す
る。更に、面1-ベンドラインと面2-ベンドラインの間
の隣接情報を形成する。*/// notice that processing
one side of the contact is independent of the othe
r side.// moreover, the logic is exactly the same.
therefore, we will use the following code// to pr
ocess both face1' side and face2' side.char face2_
processed = 0 ;process_one_side_of_the_contact ://
in general, the contact line (on the side of eith
er face (face1 and face2)) will consist//of three
lines - we have a list of lines, first line is the
line beforethe contact, the// second line is the
contact line, the last line is theline after the c
ontact.// these variables will be used to compute
thesethree lines.double k ;double k0, k1, k2, k3 ;
// parameters k for the first line in the leftdou
ble end_k1, end_k2 ; // parameters k for the last
line in the left listBM_POINT p0, p1, p2, p3 ; //
p0 - p3 are the endpoints of the edges that will b
e left (ie. endpoint of left_line, l2, l3).// p0 a
nd p3 and the two extreme endpoints and trivial to
find. we really need to compute only p1 and p2.BM
_LINE *l1, *l2, *l3 ; // l1 is the line before l2,
l2 is the line that is adjacent, l3 is the one af
ter it.// process first line of the left sidek0 =
0.0 ;k3 = 1.0 ;first_line_in_left->is_point_on_lin
e(first_line_in_right->get_startpt(),&k1) ;first_l
ine_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) k1 = 0.0 ;if (k2 > 1.0) k2 = 1.0 ;else
if (k2 < 0.0) k2 = 0.0 ;if (k2 < k1) { k = k1 ; k
1 = k2 ; k2 = k ;}// note that we cannot yet compu
te p0, p1 and p3 because we don't knowthe relative
order// of the first and last lines in the left l
ist// findand process the last linefor (line_in_li
st = left ; line_in_list ; line_in_list = next_lin
e_in_list) {if (NULL == (next_line_in_list = line_
in_list->next())) {left_line = (BM_LINE *) line_in
_list->get_obj() ;// first, we have to find the en
d of the face2 listfor (line_in_list = right ;line
_in_list ; line_in_list = next_line_in_list) {if
(NULL == (next_line_in_list = line_in_list->nex
t())) break ;}right_line = (BM_LINE *) line_in_lis
t->get_obj() ;left_line->is_point_on_line(right_li
ne->get_startpt(),&end_k1) ;left_line->is_point_on
_line(right_line->get_endpt(),&end_k2);if (end_k1
> 1.0) end_k1 = 1.0 ;else if (end_k1 < 0.0) end_k1
= 0.0 ;if (end_k2 > 1.0) end_k2 = 1.0 ;else if (e
nd_k2 < 0.0) end_k2 = 0.0 ;if (end_k2 < end_k1) {
k = end_k1 ; end_k1 = end_k2 ; end_k2 = k ; }break
;}}// now we have to compute points p0, p1, p2 an
d p3.// but first we needto convert end-k paramete
rs to equivalent parameters with respect to the //
first line in the leftp0 = left_line->get_startpt
() ;p1 = left_line->get_startpt() + end_k1 * (left
_line->get_v()) ;p2 = left_line->get_startpt() + e
nd_k2 * (left_line->get_v()) ;p3 = left_line->get_
endpt() ;//check k0first_line_in_left->is_point_on
_line(p0,&k) ;if (k < k0) k0 = k;// check k1first_
line_in_left->is_point_on_line(p1,&k) ;if (k < k1)
k1= k ;// check k2first_line_in_left->is_point_on
_line(p2,&k) ;if (k > k2)k2 = k ;// check k3first_
line_in_left->is_point_on_line(p3,&k) ;if (k >k3)
k3 = k ;// here we can compute p0, p1 and p3. late
r we compute p2.p0 = first_line_in_left->get_start
pt() + k0 * (first_line_in_left->get_v()) ;p1 = fi
rst_line_in_left->get_startpt() + k1 * (first_line
_in_left->get_v()) ;p2 = first_line_in_left->get_s
tartpt() + k2 * (first_line_in_left->get_v()) ;p3
= first_line_in_left->get_startpt() + k3 * (first_
line_in_left->get_v()) ;// ok, we have computed p0
-p3. now we will erase leftlist, except for the fi
rst line.// we need the first line later.// actual
ly, the first line will, in the future, point to n
ew line l2.BM_LOOP *left_loop = first_line_in_left
->get_loop() ;last_line_in_left = NULL ; // the la
st line in the left. we need it later to replace o
ut-of-date pointers with valid ones.line_in_list =
left->next() ; // this is the second line in the
left list.left->add_after(NULL) ;// note : we will
erase all lines in the left list, starting from t
he second line.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 linel
ast_line_in_left = (BM_LINE *) line_in_list->get_o
bj() ;left_loop->remove_edge(last_line_in_left) ;d
elete last_line_in_left ;delete line_in_list ;}//
finally, create the adjacent line l2, and two more
lines (l1 and l3) if necessary.if (p0 != p1) {l1
= first_line_in_left ;l1->set(p0,p1) ;l2 = new BM_
LINE(p1,p2);left_loop->add_edge_after(l1,l2) ;}els
e {l1 = NULL ;l2 = first_line_in_left ;l2->set(p0,
p2) ;}if (p2 != p3) {l3 = new BM_LINE(p2,p3) ;left
_loop->add_edge_after(l2,l3) ;}else l3 = NULL ;//
last thing, create topologyby making this line adj
acent to the bendlinel2->make_body_adjacent(new_be
ndline) ;// a big problem now is that we have dele
ted some lines.// the problem is that if we have a
simultaneous bend, other contacts could still be
refering// to these lines we just deleted.// we ha
ve to go and check that, and if true, replace poin
ters to the lines we have changed/deleted// with v
alid references.// // namely, lines that are affec
ted arethe first and last lines in the left.// pot
entially references to them need to be replaced wi
th references to l1 and l3.if (l1 || l3) check_ref
erences_in_remaining_contacts(face2_processed ? co
ntact_list->next() : contact_list, // current list
we are working withface2_processed ? contact_list
: contact_list->next(), // list on the other side
of the contactfirst_line_in_left, last_line_in_le
ft, // these are old references, to bechecked if s
till validl1, l3 // l1 and l3 are the new referenc
es) ;// wewill use the same piece of code to proce
ss both sides of the contact.//if face2 side has n
ot been processed, do it now.// however, first we
need to set some values of variables that are comm
only 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 beco
mes the right line.left->set_obj(l2) ;// now we ne
ed to switch left and right sides// switch linesfi
rst_line_in_left = first_line_in_right ;first_line
_in_right =l2 ;// switch listsline_in_list = left
;left = right ;right = line_in_list ;// s
tore bendline centerline
start−end pointsbendline_
centerline_p1= p1 ;bendli
ne_centerline_p2 = p2 ;go
to process_one_side_of_th
e_contact;}/*ここで、コンタクトリスト
を削除することが出来る。*/BM_LINKED_LIST_NODE *lis
t, *next_list ;int lists_deleted = 0 ; // note, we
can only deletefirst two listsfor (list = contact
_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 ;}// set the correctnumber of contacts left
and update the pointerslong num_contacts = (long)
(*contact)->get_obj() ;if (--num_contacts < 1) {//
if no contacts left, erase the whole contacts lis
tdelete *contact ;*contact = NULL ;}else {(*contac
t)->set_obj((BM_BASIC *) num_contacts) ;(*contact)
->add_after(list) ;}/* 最後に、センタラインを形成
する。方向と長さが正しいことを確かにする。 p1と
p2は面1に関して規定される点に注目されたい。 す
なわち、p1->p2は面1の側のコンタクトに対する
方向である。*/BM_LINE centerline(bendline_centerli
ne_p1,bendline_centerline_p2) ;if (fabs(angle - P
I) <= BM_ANGLE_TOLERANCE) { // bendline not being
bent// face1 plane is thebendline surfaceif (face1
->get_idx() > face2->get_idx()) centerline.reverse
_line() ;}else if (angle < PI) {if (face1->get_idx
() < face2->get_idx()) centerline.reverse_line()
;}else { // angle is > PIif (face1->get_idx() > f
ace2->get_idx()) centerline.reverse_line() ;}new_a
uto_bendline->set_center_line(centerline) ;// if w
e are building bendlines for the 3D-version of the
part, // make sure 3D-version of the bendline is
validatedbecause most likely we // want to UNFOLD
right away.if (using_3D_version) new_bendline->val
idate_3D_version() ;*bendline_created = new_bendli
ne;return 1 ;}/* この関数の目的は、面からなる切断
された要素を持つ部分であって、この部分が、これらの
新しいベンドラインを付加すると、接続されるようにな
るように最小数のベンドラインを形成することにある。
This function assumes that the part has thickness
0.The basic idea we use in this function is maximu
m spanning tree.We model the part by an undirected
graph, where faces are the nodes of the graph and
there is an edge between two nodes iff these two f
aces are in contact (ie. are touching each other),
thecost (or length) of the edge is the length of t
he longest contact between these two faces (ie. th
e length of the longest possible bendline between
the two faces).In order to create bendlines we com
pute a maximum spanning tree for this graph and cr
eate abendline for every edge of the graph that is
in the maximum spanning tree.There are two proble
ms however :-It could be that the part already con
tains some bendlines (ie. some faces are already
connected).- When we compute the maximum spanning
tree,we can have two fringe-edges that have the
same length. In that case,we don't want to break t
ies randomly, but instead choose an edge thatwou
ld minimize the diameter of the spanning tree (the
maximum distance between any two vertices of the
tree).Algorithm :-----------We will process faces
one-by-one, starting from the first faces of the
part and proceedinguntil the last faces, and build
ing the maximum spanning tree alongthe way as we g
o.For every pair of faces, such that at least one
of theis not yet in the spanning tree,we keep the
longest contact between them. When we expand the s
panning tree, we choosethe contact between a facei
n the tree and a face not in the tree that is the
longest contactbetween any face in the tree and a
face outside. If there is a tie, we choosean edge
thatwould minimize the *//* 面(面1)を与える
と、この構造はこの面と他の面の間のコンタクトについ
ての情報を含む。 任意の2つの面に対して、これらの
面の間にコンタクトが有るか否かを知る必要があり、も
しイエスなら、何がその長さであるかを知る必要があ
る。このデータを処理する最も簡単な方法はそれを二次
元配列として記憶することにより与えられる。しかし、
これは多くのスペースを取り、その殆どは無駄に使わ
れ、というのは、通常は、多くの面があるときは、それ
らの殆どはそれらの面の間で何らのコンタクトも持たな
いことによる。 代わりに、我々は全ての面に対してこ
の情報を構造のリストとして記憶することになる。我々
は、2つの面の間のコンタクトの長さが0より大きいと
きにのみこの記録を(すなわち、構造)生成する。*/ty
pedef struct CONTACT_INFO {// here we will keep tr
ack what is the length of the longest contact betw
een any two faces// this is really a two-dimension
al arraydouble length ;// here we keep a pointer t
o the other faceBM_FACE *face2 ;//here we will kee
p the longest 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 p
ointer to the next structure in a listCONTACT_INFO
*next ;} contact_info ;/*これは、このファイルに
おいて多くの関数により用いられる非常に基本的な関数
である。 それはコンタクトリストを削除する。*/stat
ic void delete_contact_info_list(contact_info *lis
t){contact_info*c, *c_next ;BM_LINKED_LIST_NODE *c
list, *next_clist ;BM_LINKED_LIST_NODE *line_in_li
st, *next_line_in_list ;for (c = list ; c ; c = c_
next) {c_next = c->next ;if (c->contact) {// skip
the header = num of contactsfor(clist = (c->contac
t)->next() ; clist ; clist = next_clist) {next_cli
st= clist->next() ;// delete the 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_list->next() ;delete
line_in_list ;}delete clist ;}// delete the header
delete c->contact ;}delete c ;}}static void delete
_contact_info_structure(contact_info *c){BM_LINKED
_LIST_NODE *clist, *next_clist ;BM_LINKED_LIST_NOD
E *line_in_list, *next_line_in_list ;if (NULL ==
c) return ;if (c->contact) {// skip the headerfor
(clist= (c->contact)->next() ; clist ; clist = nex
t_clist) {next_clist = clist->next() ;// delete th
e listfor (line_in_list = (BM_LINKED_LIST_NODE *)c
list->get_obj() ; line_in_list ; line_in_list = ne
xt_line_in_list) {next_line_in_list = line_in_list
->next() ;delete line_in_list ;}delete clist ;}//
delete the headerdelete c->contact ;}delete c ;}/*
この関数は2つの面の間で最良の(すなわち、最も長
い)コンタクトを計算し、格納する。*/static int com
pute_the_longest_contact_between_faces(BM_FACE & f
ace1 /*IN */, BM_FACE & face2 /* IN */,contact_inf
o **computed_contact_list /*OUT */){// so far we h
ave computed nothing*computed_contact_list = NULL;
BM_LINKED_LIST_NODE *contact_list ; // a list of a
ll contacts between face1 and face2 we will comput
eif (! BM_compute_all_face_to_face_contacts(face1,
face2, &contact_list)) return 0 ;double x = BM_ke
ep_largest_contact_remove_the_rest(&contact_list)
;if (x < BM_PRECISION) return 1 ; //no contact be
tween these two facescontact_info *c ;if (NULL ==
(c = newcontact_info)) {// delete contact listBM_L
INKED_LIST_NODE *clist, *next_clist ;BM_LINKED_LIS
T_NODE *line_in_list, *next_line_in_list ;for (cli
st= contact_list->next() ; clist ; clist = next_cl
ist) {next_clist = clist->next() ;// delete the li
stfor (line_in_list = (BM_LINKED_LIST_NODE *)clist
->get_obj() ; line_in_list ; line_in_list = next_l
ine_in_list) {next_line_in_list = line_in_list->ne
xt() ;delete line_in_list ;}delete clist ;}delete
contact_list ;return 0 ;}// initialize the structu
rec->contact = contact_list ;c->next = NULL ;c->fa
ce2 = &face2 ;c->length = x ;*computed_contact_lis
t = c ;return 1 ;}/* この関数は現在接続された要素
に新しい面を付加する。 それはまた、この新しい面
と、処理されていない他の全ての面の間の最も長いコン
タクトを計算する。*/static int add_face_to_connect
ed_component(BM_PART *part, BM_FACE *face2 /* this
is the face we are adding to the connected compon
ent */, long *end_id /* an index of the lastface i
n the connected component. this is where face2 is.
*/, contact_info **all_contacts /* all contact in
fo between face2 and other outside faces will be h
ere *//* we will compute it and construct this lis
t in thisfunction */,BM_FACE **idx_to_face_mappin
g){BM_FACE *current_face ;contact_info *last_clist
= NULL, *cl ;// just in case face2 has no adjacen
t faces outside the connected componentall_contact
s[*end_id] = NULL ;// inthis loop we want to compu
te all contacts between face2 and all other//faces
not yet in any connected component.for (current_f
ace = part->get_face_list() ; cur
rent_face ; current_face
= (BM_FACE *) current_fac
e−>next()) {if (current_f
ace−>get_user_id() >= 0)
continue ; // current_fac
e is in some other connec
ted component// compute t
he best contact between f
ace2 and current_faceif
(! compute_the_longest_co
ntact_between_faces(*face
2, *current_face, &cl)) r
eturn 0 ;if (NULL == cl)
continue ; // thereis no
contact between these two
facesif (NULL == last_cl
ist) all_contacts[*end_i
d] = cl ;else last_clist−
>next = cl ;last_clist =
cl ;}face2−>set_user_id(*
end_id) ;idx_to_face_mapp
ing[*end_id] = face2 ;++
(*end_id) ;return 1 ;}/*
これらの2つの関数は、ユーザがトポロジーグラフにお
ける2つの面の間の距離を設定し得ることを許容する。
dist btw 面は二次元配列の上部右半部である。*/st
atic long get_face2face_dist(unsigned char *dist_b
tw_faces,long number_of_faces, long dist_array_siz
e, long j, long i){longk ;// distance between face
_i and face_i is zeroif (i == j) return 0 ;//sort
indecesif (j < i) { k = i ; i = j ; j = k ; }k = n
umber_of_faces -i ;return dist_btw_faces[dist_arra
y_size - ((k*(k-1)) >> 1) + (j - i) -1] ;}static v
oid set_face2face_dist(unsigned char *dist_btw_fac
es,longnumber_of_faces, long dist_array_size, long
j, long i, unsigned char distance){long k ;// dis
tance between face_i and face_i cannot be setif (i
== j) return ;// sort indecesif (j < i) { k = i ;
i = j ; j = k ; }k = number_of_faces - i ;dist_btw
_faces[dist_array_size - ((k*(k-1)) >> 1) +(j - i)
- 1] = distance ;}/* この関数は接続された要素に
おける所定の面と他の面の間の最大距離を戻す。*/stat
ic long get_largest_distance_for_face(unsigned cha
r *dist_btw_faces,long number_of_faces, long dist_
array_size, long start_id, long end_id, long face_
id){long j, k ;if (NULL == dist_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_siz
e,j,face_id) ;if (k > current_face_to_face_distanc
e) current_face_to_face_distance = k ;}return curr
ent_face_to_face_distance ;}/* これは主要なAut
obend関数である。その目的は部分に対するベンド
ラインを自動的に生成することにある。*/int BM_PAR
T::auto_bend(void){long i, j, k ;BM_FACE *current_
face ;BM_FORMING *current_forming ;BM_BENDLINE *cu
rrent_bendline ;// at end of the function we relea
se memory.this code for releasing memory is shared
// between the cases when thisfunction fails, or s
ucceeds.// therefore, before we get to that code,
wehave to know the return code.int ret_value ;// t
hese are the two faceswe will be creating a bendli
ne for (ie. between these two faces).BM_FACE*face
1, *face2 ;// here we keep a list of information a
bout contacts between every face and other faces./
/ this is an array lists.contact_info**all_contact
s = NULL ;// here we will keep track what face cor
respondsto each row in face_to_face_length[] and a
ll_contacts[] arraysBM_FACE **idx_to_face_mapping
= NULL ;// this (two-dimensional) array is used to
store distances between faces in the TOPOLOGY GRA
PH.// these distance values are used to break ties
in the maximum spanning tree algorithm when//two
edges have the same length. Note that the distance
between (i,j) isthe same as// the distance betwee
n (j,i). This means that the distancematrix is a s
ymmetric matrix, and we// only need to store one h
alf (upper right triangle) to save space.// we wil
l use this method of breaking ties only when the n
umber of faces is less than 256.// this has two ad
vantages : 1) the distance between any two faces i
s always less than 256,//and therefore we only nee
d a char (8 bits) to store the distance values, 2)
since we only// need a char for a pair, the total
this array can take is 32K bytes, which is not to
o much memory.unsigned char *dist_btw_faces = NULL
;// this will be the size of the distance array,
given some number of faceslong dist_array_size ;//
we will have to create a heap because some portio
n of the part can already be connected// and we ne
ed tomake sure we don't create any bendlines for t
hat portion of the part.//we will use a heap to tr
averse that portion of the part.long body_priority
= number_of_formings + number_of_faces + number_o
f_bendlines ;// Check if there are any bodies. If
no, we are done.if (body_priority < 1) return 1 ;/
/ this is the heap we will allocate. this is used
when we add aface to the connected component// to
add all other faces connected to itas well. the pr
oblem is that the part could already// contain som
e bendlines.DBM_HEAP *heap = NULL ;// this is the
start-index (in face_to_face_length[] and all_cont
acts[]) arrays // of the current connected compone
ntlong start_id = 0 ;// this is the end-index (in
face_to_face_length[]and all_contacts[]) arrays //
of the current connected componentlong end_id = 0
;// if TRUE, we are starting a new connected comp
onentint starting_new_connected_component = 1 ;//
allocate memory for local variablesif(NULL == (all
_contacts = new contact_info*[number_of_faces])) g
oto failure ;if (NULL == (idx_to_face_mapping = ne
w BM_FACE*[number_of_faces]))goto failure ;if (NUL
L == (heap = new DBM_HEAP(0,NULL,NULL,body_priorit
y))) goto failure ;if (number_of_faces < 256) { //
allocate memory for the face-face distance array
only when // the number of faces is not too larged
ist_array_size = (number_of_faces*(number_of_faces
- 1)) >> 1 ;if (NULL == (dist_btw_faces = new uns
igned char[dist_array_size])) goto failure ;}++bod
y_priority ; // just in case, we don't want the pr
iority to go to 0 later.// initialize arraysfor (i
= 0 ; i < number_of_faces ; i++){all_contacts[i]
= NULL ;idx_to_face_mapping[i] = NULL ;}// initial
ly mark all faces as not processedfor (i = 0, curr
ent_face = first_face ; current_face ; current_fac
e = (BM_FACE *) current_face->next()) {current_fac
e->this_body_already_processed = 0 ;// this will t
ell us whether thisface has been already processe
d.// if yes, this id is the index in face_to_face_
length[] and all_contacts[] arrays.current_face->s
et_user_id(-1);}/* 先ず、面の現在接続された要素の
最大スパンツリーを拡大することを試みる。*/// these
two variables are used in tie-breakinglong best_f
ace_to_face_distance, current_face_to_face_distanc
e ;// this is the length ofthe best contact so far
(ie. the longest contact)double best_length ;//th
is is a pointer to the best contact_info structure
found so farcontact_info *best_cntct ;expand_span
ning_tree :// first, check if all faces have been
processed// end_id is where we will put the next f
ace we add tothe connected componentif (end_id >=
number_of_faces) goto done ;contact_info *cntct, *
cntct_next, *cntct_prev ;best_length = -1.0 ;best_
face_to_face_distance = 999999 ; // a really large
number// in this loop we check all faces already
in the connected component and try// to find a fac
ethat has the largest contact between itself and a
n adjacent face outside the// current connected co
mponent.for (i = start_id ; i < end_id ; i++) {//
in this loop we are checking for a largest contact
between the current face// in the connected compo
nent and all of its adjacent faces outside the con
nected component.cntct_prev = NULL ;for (cntct = a
ll_contacts[i] ; cntct ; cntct = cntct_next) {cntc
t_next = cntct->next ;// check if this adjacent fa
ce is already processedif ((cntct->face2)->get_use
r_id() >= 0) {// this means that face2 has already
been added to the connected component// and we do
n't really need the contact info stored in thisstr
ucture any more.// we will delete it.// this will
some time in the future and free up some space.del
ete_contact_info_structure(cntct) ;if (NULL == cnt
ct_prev) all_contacts[i] = cntct_next ;else cntct_
prev->next =cntct_next ;continue ;}// ok, this adj
acent face not processed. // checkif it is better
than the previously known best.// first check if t
hereis a tie, and if we have allocated a face-face
distance array// then usethe face-to-face distanc
es to break the tieif (fabs(cntct->length - best_l
ength) <= distance_tolerance && dist_btw_faces) {/
/ if tie-breaking is used, compute the largest dis
tance for this face (ie. face1)current_face_to_fac
e_distance = get_largest_distance_for_face(dist_bt
w_faces,number_of_faces, dist_array_size, start_i
d, end_id, i) ;// prefer the one with the smaller
largest distanceif (current_face_to_face_distance
< best_face_to_face_distance) {face1 = idx_to_face
_mapping[i] ;face2 = cntct->face2 ;best_
length = cntct−>length ;b
est_cntct = cntct ;best_f
ace_to_face_distance = cu
rrent_face_to_face_distan
ce ;}}// take simply the
one thatis betterelse if
(cntct−>length > best_len
gth) {face1 = idx_to_face
_mapping[i] ;face2 = cntc
t−>face2 ;best_length = c
ntct−>length ;best_cntct
=cntct ;// if tie−breakin
g is used, compute the la
rgest distance for thisfa
ce (ie. face1)best_face_t
o_face_distance = current
_face_to_face_distance =
get_largest_distance_for_
face(dist_btw_faces,numbe
r_of_faces, dist_array_si
ze, start_id, end_id, i)
;}cntct_prev = cntct ;}}
// at the endof this loo
p,// face1, face2, best_c
ntct should have correct
values, ifbest_length >
0.0, // that means we can
expand the tree./* 我々がスパ
ンツリーを拡大出来るか否かをチェックする。 我々が
接続要素を拡大することに戻るまでまでのこの点に対し
て、我々は単に面2を用いつつあり、すなわち、我々は
面1を必要としていない。 唯一の場合は、我々が新し
いベンドラインを生成するときであるが、我々はコンタ
クトリストから面idを抽出することが出来る。*/if
(best_length < distance_tolerance) {// looks like
we cannot expand the spanning tree// none of the f
aces in the current connected component has any ad
jacent faces// outside the connected component.//
most likely this connected component is finished a
nd, since there must be stillfaces left,// there i
s more than one connected component.// // next wet
ry to find the first face in the next connected co
mponent so that we//can continue and create all be
ndlines for this new conencted component.for (curr
ent_face = first_face ; current_face ; current_fac
e = (BM_FACE *) current_face->next()) {if (current
_face->get_user_id() < 0) break ;}if(NULL == curre
nt_face) goto done ; // we should never get here//
first,we can delete all contact information about
the current (now old) connected componentfor (i =
start_id ; i < end_id ; i++) {delete_contact_info
_list(all_contacts[i]) ;all_contacts[i] = NULL ;}/
/ here we will be starting a new connected compone
ntstarting_new_connected_component = 1 ;start_id =
end_id ;// we will skip the bendline creation nor
mally needed when adding a face to a connected com
ponentface2 = current_face ;}else {//ok, we are in
the middle of a conencted componentstarting_new_c
onnected_component = 0 ;// create a bendline betwe
en face1 and face2// notice : we might have to cre
ate a simultaneous bendlong num_contacts = (long)
(best_cntct->contact)->get_obj() ;BM_BEND_PROPERTY
_SIMULTANEOUS *sim_bend =NULL ;if (num_contacts >
1) {sim_bend = new BM_BEND_PROPERTY_SIMULTANEOUS(t
his, num_contacts, NULL) ;if (NULL == sim_bend) go
to failure ;}BM_BENDLINE *new_bendline ;for (long
contacts_done = 0 ; contacts_done < num_contacts ;
contacts_done++) {if (! BM_create_bendline(*this,
&(best_cntct->contact),&new_bendline)) goto failu
re ;// note that this function will delete one con
tact for which a bendline was created as wellif (n
um_contacts > 1) {// add this bendline to the simu
ltaneous propertynew_bendline->add_property(sim_be
nd) ;}}}// store "1 + the current index of the las
t 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 it.// if yes, we will be
adding that stuff to this connected component righ
t away,// but in that case there is no need for us
to compute contacts between face2 and that other/
/ stuff in the first place.// Therefore, we will j
ust remember that face2 should be added, will proc
essadjacent stuff first,// and then will actually
add face2 (and some morestuff may-be) to the conne
cted component.// // Note : we will actully put fa
ce2 in the heap, and when we remove it from the he
ap,// we will remember to add it to the connected
component/* ここで,我々は、この面(すなわち、面
2)がそれに接続された他の任意の3D体を有するか否
かをチェックする必要がある。 もし、イエスなら、我
々は、面2に接続された全ての面を現在接続された要素
に付加するために、これらの接続を追求する必要があ
る。*/heap->empty() ;if (! heap->insert(body_prior
ity--, (long) face2)) goto failure ;face2->this_bo
dy_already_processed = 1 ;// check if face2 has a
parent face or not. if not, set the id in local ar
ray equal to // face2'sown id. this way we know it
has no parent face.// // IMPORTANT : normally use
r_id of every face is a pointer to its index in th
e contact-info array.// temporarily we will use th
is information to keep track which of the faces al
ready processed// is the parent-face (in the topol
ogy graph)of every new face added to the connected
component.// this information will be used later
to compute distances in the face topology graph.//
thefollowing loop (controlled by the heap) stores
all faces not yet in theconnected// component, bu
t connected to this face2.// later when the actual
y adding of new faces to the conencted component i
s done,// we overwrite user_id with the correct va
lue.if (! starting_new_connected_component) face2-
>set_user_id(face1->get_user_id()) ;else face2->se
t_user_id(end_id) ;// in the following while loop
we will use this_body_already_processed member var
iable to keep// track whether a varible is process
ed; not processed, but sitting in the heap; or uns
een yet.// 0 - unseen body//1 - body in the heap//
2 - body already finished// also, in this whilelo
op we will be using the user_defined_id of every 3
D-body to keep// track of the parent face of every
3D-body we traverse.// this has two benefits : 1)
we will remember the parent face of every face an
d can compute// distances between faces later, and
// 2) this way when faces are lateradded to the s
panning tree, distance between some other // face
and this face will not be computed, since it is no
t necessary.BM_3D_BODY *body;BM_TOPOLOGY_RECORD *t
oplgy ;while (heap->get_size() > 0) {if (! heap->r
emove(&i,(long *) &body)) goto failure ;// a safet
y checkif (NULL == body) continue ;// check if thi
s body is already finishedif (body->this_body_alre
ady_processed > 1) continue ;// get body topologyt
oplgy = body->get_adj_list() ;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 ;// memorize to add this face
to the connected component lateridx_to_fa
ce_mapping[j++] = face2
;}body−>this_body_alread
y_processed = 2;// proces
s all adjacent bodiesfor
(current_face = (BM_FACE
*) toplgy−>get_first_face
() ; current_face ; curre
nt_face = (BM_FACE *) top
lgy−>get_next_face()) {//
make sure that we don’t
process faces twiceif (cu
rrent_face−>this_body_alr
eady_processed) continue
;if (! heap−>insert(body
_priority−−,(long) curren
t_face)) goto failure ;cu
rrent_face−>this_body_alr
eady_processed = 1 ;// ma
ke sure we memorize the p
arent face index in the l
ocal spanning tree arrayc
urrent_face−>set_user_id
(body−>get_user_id()) ;}f
or (current_forming = (BM
_FORMING *) toplgy−>get_f
irst_forming() ;current_f
orming ; current_forming
= (BM_FORMING *) toplgy−>
get_next_forming()) {if
(current_forming−>this_bo
dy_already_processed) con
tinue ;if (! heap−>insert
(body_priority−−,(long) c
urrent_forming)) goto fai
lure ;current_forming−>th
is_body_already_processed
= 1 ;// make sure we mem
orizethe parent face inde
x in the local spanning t
ree arrayif (body−>is(BM_
ENTITY_TYPE_FACE)) curren
t_forming−>set_user_id(j−
1) ;else current_forming−
>set_user_id(body−>get_us
er_id()) ;}for (current_b
endline = (BM_BENDLINE *)
toplgy−>get_first_bendli
ne() ; current_bendline ;
current_bendline= (BM_BE
NDLINE *) toplgy−>get_nex
t_bendline()) {if (curren
t_bendline−>this_body_alr
eady_processed) continue
;if (! heap−>insert(body
_priority−−,(long) curren
t_bendline)) goto failure
;current_bendline−>this_
body_already_processed =
1 ;// make sure we memori
ze the parent face index
in the local spanning tre
e arrayif (body−>is(BM_EN
TITY_TYPE_FACE)) current_
bendline−>set_user_id(j−
1) ;else current_bendline
−>set_user_id(body−>get_u
ser_id()) ;}}// finally w
e need to compute contact
s between this face and a
ll other faces, that we p
ostponed// and add them t
o the connected componen
t.long face1_id ;for (i =
end_id ; i < j ; i++) {f
ace2 = idx_to_face_mappin
g[i] ;// first, compute d
istances in the TOPOLOGY
GRAPH betweenthis face (i
e. face2) // and all face
s previously in the conne
cted component.// we will
use the parent face id i
n the local spanning tree
arrayfor that.face1_id =
face2−>get_user_id() ; /
/ note : face1_id is the
parent id of face2 (ie. t
here is a bendline betwee
n face1_id and face2 that
we count).if (dist_btw_fa
ces && face1_id != i) { /
/ if equal −> face2 has n
o parents, // ie. a new c
onnected component (must
be start_id = end_id).//
actually, it must be here
true that face1_id < ifo
r (k = start_id; k < end_
id ; k++) {set_face2face_
dist(dist_btw_faces, numb
er_of_faces, dist_array_s
ize, k, i, get_face2face_
dist(dist_btw_faces,numbe
r_of_faces,dist_array_siz
e,k,face1_id) + 1) ;}}//
else if equal, it must be
thati == ’the end_id’ in
the beginning of this fo
r−loop.// note that the n
ext function (add_face_to
_connected_componen
t(...)) will increment en
d_id.if (! add_face_to_co
nnected_component(this, f
ace2, &end_id, all_contac
ts, idx_to_face_mapping))
goto failure ;}// ok, th
e current connected compo
nent has no connections t
o the outside.// try to e
xpand the spanning tree.g
oto expand_spanning_tree
;done :ret_value = 1 ;go
to release_memory_and_ret
urn ;failure :ret_value =
0 ;release_memory_and_re
turn :// free memory if n
ecessaryfor (i = 0 ; i <
number_of_faces ; i++) {d
elete_contact_info_list(a
ll_contacts[i]) ;}if (all
_contacts) delete [] all_
contacts;if (idx_to_face_
mapping) delete [] idx_to
_face_mapping ;if (heap)
delete heap ;if (dist_btw
_faces) delete [] dist_bt
w_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//#undefDEBUG//
// Following is the definition of the global varia
bles//#ifdef CKWINint TopViewNum, IsometricViewNu
m;// These variables are used only with CADKEY wh
en changing to TopView or Isometric view.#endif//
by Ji Feb.14,1996double F2dCleanUpTolerance = 0.0
1;//undo flag ( set a No. for views )extern int
F2dCleanUpExcutedNo = 0;extern int WorkLevel,
TrimLevel, VW3DLevel; // T
hree layers are useD: WorkLevel is used to highlig
ht views and display temporary drawings.//TrimLeve
l is used to store the trimmed drawing.//VW3DLevel
is used to store the projected 3D drawing.// thes
e are the four drawings used.extern struct drawing
input_drawing,projected_drawing, trim_drawing, fi
nal_drawing; // Three drawing structures are cons
tructed:// InputDrawing is
constructed from the input entities //
takenfrom from all the la
yers that are turned on.//
TrimmedDrawing is constructed from the trimmed ent
ities. Once the//Trimmed Drawing is constructed, t
he InputDrawing is not used.//
ProjectedDrawing is constructed from the entit
ies projected in a single flange.//If 'DoneProject
ion' is selected, then these entities are saved on
VW3DLevel.// If 'UndoProjec
tion' is selected, these entities are discarded.ex
tern struct planar_flange *AllFlanges;// this is a
pointer to the list of flangesextern char Message
s[MaxMessages][80];// This array stores the messag
es read from the message file.externint message_fl
ag;// This variable is assigned to '1' if the mess
ages were read successfully from the message file.
// Otherwise, it is set to '0'.extern int number_o
f_views;// This vairbale stores the number of disc
onnected components discovered in the *input* draw
ing.extern int number_of_entities;// This variable
stores the number of entities loaded for thecurre
nt drawing.extern int number_trimmed_entities;// T
his variable stores the number of entities loaded
for the trimmed drawing.extern int n_edges;// This
variable stores the number of connecting edges be
tween the trimmed entities.extern double MatchTole
rance, ConnectivityTolerance;// ConnectivityTolera
nce is used to determine whether two entities are
closeenough to be considered connected.// Matching
Tolerance is used to determine whether two entiti
es on different views are matching.extern doubleAr
rowHeadAngle, ArrowHeadLength;// These variuables
define the structure of an arrow for the 2D clean
up funciton.extern double view_boundaries[MaxNumbe
rOfViews+1][4];// This array is used to store the
bounding boxof each connected component of the inp
ut drawing.// once the viewsare detected, sev
eral components might be mapped to a single view.e
xternint type_of_view[MaxNumberOfViews+1];// Th
is array maps every view to its type, namely to on
e of Top, Left, Right, Front, Back view.// Its con
tent is valid only after 'DoneViews' was called.//
int view_rotation_flag[MaxNumberOfViews+1];// This
array is used for marking rotated views.// If the
i'th element is '1' then the view is rotated.//ex
tern static char original_lvmask[32] ;// At the be
ginning we save the (on,off) statusof all the laye
rs.//extern static char twoDmask[32] ;//extern sta
tic char threeDmask[32] ;// The masks used to disp
lay the 2D and 3D models.//extern static int origi
nal_worklevel ;// Specifies the original work leve
l of the user when fold is started// static int or
iginal_setup_available= 0 ; // true iff original
(layer) setup is available, ie. can be restoredext
ern int dialog_open_flag = 0;// This variable is a
flag which specifies whether some dialog boxes we
re opened.extern int AtrimLineTypeSwitch, AtrimCol
orSwitch, AtrimWidthSwitch, AtrimCenterLineSwitch;
// these switches are used to specify in which cas
es AutoTrim will trim lines.//struct node *F2dClea
nUpInputEntity(char *, struct drawing *);//static
intselect_flange(struct resbuf *rb);typedefstruct
Vector {doublex,y,z;};extern double BBminX,BBmaxX,
BBminY,BBmaxY,BBminZ,BBmaxZ;/*関数: 名称: TestFi
ndBoundaryDescription: It is a manual function. Wh
en user selected aboundary's entity of a view, the
function would find all of the connected entities
for the view.戻り値:< 0: Error= 0: No proccess>
0: Completedsuccessfully; the Number is the counte
r of found entities.パラメータ:副関数:int F2dCl
eanUpFindArrowlook for arrow type entityint F2dCle
anUpFindArrowEndEntityfind arrow end lineint F2dCl
eanUpFindArrowCenterEntityfind arrow center linein
t F2dCleanUpFindArrowOneSideOpenEntityfind one sid
e open entity for arrow typeint F2dCleanUpComputeC
enterLineAnglecomputecenter line angleint F2dClean
UpCheckStartEndEntitycheck start and end entitiesi
nt F2dCleanUpFindOutSideLooplook for out side loop
entitiesint F2dCleanUpFindOutNextEntitylook for c
onnected entity with out side loop entitiesstruct
node *F2dCleanUpFindGroupMinXlook for minimum X-va
lue fora entities groupstruct node_list *F2dCleanU
pFindGrouplook for a group entities connected with
input entitystruct node *F2dCleanUpInputEntity (
old function )look for a selected entity on screen
int F2dCleanUpLineAnglecompute a line type entity'
s angle int F2dCleanUpArcAnglecompute a arc type e
ntity's angle.int F2dCleanUpChangeChildrenFlagchan
ge entity's children flagsint F2dCleanUpChangeArro
wVertexFlagchange arrow top vertex's flags and set
arrow center line coordinatesint F2dCleanUpChange
Colorchangeentity's colorint F2dCleanUpFindOneSide
OpenEntitylook for one side openentities and they
are vertical with arrow type entities double F2dCl
eanUpLineLengthcompute line type entity's length==
==================================================
=============*/intTestFindBoundary(){//externalfun
ctionsint F2dCleanUpFindArrow();int F2dCleanUpChan
geColor();int F2dCleanUpFindOneSideOpenEntity();in
t F2dCleanUpFindOutSideLoop();int F2dCleanUpChange
DrawingColor();struct node *F2dCleanUpInputEntit
y();struct node *F2dCleanUpFindGroupMinX();struct
node_list *F2dCleanUpFindGroup();//entities counte
r and flagsint count = 0,assistant_line_flag = 0;/
/link list and temp liststruct node_list*Entities_
change_color_list1; //selectedentity and temp enti
tiesstruct node *entity,*MinXvalueEntity;//Begin/
/----------------------------------//Step_1://chec
k the number of entites// get count of all entiti
es// if an error occurred, exit immidiately.if (nu
mber_of_entities<0) return -1;for( ; ; ){//------
---------------------------//Step_2:select one ent
ityentity = F2dCleanUpInputEntity("Select a Bounda
ry Entity for a view",&trim_drawing);if ( entity =
= 0 )return0;if ( entity->flags != 0 )continue;//-
--------------------------------//Step_3: find a c
onnected entities groupEntities_change_color_list1
= F2dCleanUpFindGroup( entity, &count );if ( Entit
ies_change_color_list1 == 0 )return0;//-----------
----------------------//Step_4: find arrowlineF2dC
leanUpFindArrow( Entities_change_color_list1 );//-
--------------------------------//Step_5:find one
side open entitiesassistant_line_flag = F2dCleanUp
FindOneSideOpenEntity( Entities_change_color_list1
);//---------------------------------//Step_6:fin
d outside loop entities without assistant entities
//check a flag for outside loop processif ( count
<1 )continue;MinXvalueEntity = F2dCleanUpFindGroup
MinX(Entities_change_color_list1);if ( MinXvalueEn
tity == 0 )continue;//----------------------------
-----//Step_7://find outside loop entitiesF2dClean
UpFindOutSideLoop( MinXvalueEntity );//-----------
----------------------//Step_X://changecolor to Ma
genta for a selected boundary // turn off input
levelsck_levels(CK_OFF,1,255);#ifdef CKWINF2dClea
nUpChangeColor(Entities_change_color_list1);#endif
#ifdef VELLUMF2dCleanUpChangeDrawingColor(&trim_dr
awing);#endif//clear a flag for outside loop proce
ssassistant_line_flag= 0;// turn ON the level used
to store the trimmed entities. ck_levels(CK_O
N,TrimLevel, TrimLevel);#ifdef CKWINif ( *SwitchRe
draw == 1)ck_redraw( CK_PRIME_VP );#endif}return c
ount;}/*==========================================
=======================関数: 名称: F2dCleanUpFin
dGroup記述: look for a group entities connected w
ith input entity 戻り値:= 0: Completed successful
ly;パラメータ:入力: Entity: a entity出力:NodeLi
st:a node list connected with input entity =======
==================================================
========*/struct node_list *F2dCleanUpFindGroup(st
ruct node *Entity, int *Cnt ){//entities counter a
nd flagsint count =0;//link list and temp liststru
ct node_list*EntitiesList1,*Out_temp_list,*temp_li
st, *temp_list1,*open_temp_list, *open_list; //sel
ected entityand temp entitiesstruct node *Next_ent
ity;//initializeEntitiesList1 =(struct node_list *
) calloc ( 1, sizeof ( struct node_list ));open_l
ist=( struct node_list * ) calloc ( 1, sizeof ( st
ruct node_list ));//set aflag for the boundary ent
itycount = 0;//set pointer to first entityopen_lis
t->car = Entity;//set a open flagto the nodeopen_l
ist->car->flags =1;//set link addressopen_list->cd
r = NULL;//set the pointer to output node listEnti
tiesList1->car = open_list->car;EntitiesList1->cdr
= open_list->cdr;//------------------------------
---//Step_3://find connected entitiesfor( temp_lis
t = open_list; ( temp_list //&&(temp_list
->cdr!= 0) ); ) {if ( temp_list->car == NU
LL )break;//get a pointerfrom open listNext_entity
= temp_list->car;//set a closed flag to the nodeN
ext_entity->flags = 2;//close the node ( delete th
e node from open list )open_list = open_list->cdr;
//count the number of entitiescount++;//look for f
irst connected entity whose flags=0.for (temp_list
1=Next_entity->connected_nodes; // temp_list1
&& temp_list1->car->flags==1;( temp_list1!=0 &&
temp_list1->car!=0 ); temp_list1=temp_l
ist1->cdr){ if ( temp_list1->car == NULL )brea
k; // if found an unmarked connected entityif (tem
p_list1 && temp_list1->car->flags==0&& Entity->lin
e_type == temp_list1->car->line_type&& Entity->col
or == temp_list1->car->color&& Entity->is_thicknes
s == temp_list1->car->is_thickness ){// allocate
memory for open list elementopen_temp_list = ( st
ruct node_list * ) calloc ( 1, sizeof ( struct nod
e_list ));// allocate memory foroutput node list e
lementOut_temp_list = ( struct node_list * ) callo
c (1, sizeof ( struct node_list ));// add this ent
ity to the open listopen_temp_list->car = temp_lis
t1->car;// add this entity to the output nodelist
Out_temp_list->car = temp_list1->car;//set a open
flagto the nodeopen_temp_list->car->flags = 1; //
connect to the open listopen_temp_list->cdr = open
_list;// move the pointer of open list to the topo
pen_list =open_temp_list;// connect to the output
node listOut_temp_list->cdr = EntitiesList1;// mov
e the pointer of output node list to the topEntiti
esList1 = Out_temp_list;}}// assign value to the l
oop variabletemp_list = open_list;}*Cnt = count;re
turn EntitiesList1; }/*===========================
====================================== 関数: 名
称: F2dCleanUpArcAngle 記述:アーク形エンテ
ィティの角度を計算する。 戻り値:RotateVertexFla
g:方向フラグ =1:vertex1は回転ポ
イントである。=2:vertex2は回転ポイントである。 パ
ラメータ:入力: 1 OriginVertex:回転
頂点 2 Entity:アーク形エンティティ
出力: 1 EntityAngle:方向角度
(ラジアン) 2 EntityAngleAnother:
他のサイド方向角度================================
================================*/int F2dCleanUpAr
cAngle(//inputstructplanar_vertex *OriginVertex,st
ructnode *Entity,//outputdouble*EntityAngle,double
*EntityAngleAnother){//return value intRotateVerte
xFlag=0;//length and angledoubleTolerance = 0.0;//
set toleranceTolerance = F2dCleanUpTolerance;//sel
ect connected side of entityif ( Entity->vertex1 =
= OriginVertex ){//get arc start-angle//( directio
n : from circle-center to start-point )RotateVerte
xFlag= 1;*EntityAngle = ( Entity->AngBegin ) * pi
/ 180.0;//change angle to oppsite direction//( dir
ection : from start-point to circle-center )*Entit
yAngle = *EntityAngle +pi;//check angle if ( *Enti
tyAngle >(2.0*pi)) *EntityAngle = *EntityAngle -
2.0*pi;if ( fabs(*EntityAngle-2.0*pi) < Tolerance
) *EntityAngle =0.0;//compute tangentline angle f
or the arc end-angle//( direction : from start-poi
nt to end-point )*EntityAngle = *EntityAngle + 1.5
* pi;//check angle if ( *EntityAngle >(2.0*pi)) *
EntityAngle = *EntityAngle - 2.0*pi;if ( fabs(*Ent
ityAngle-2.0*pi) < Tolerance ) *EntityAngle = 0.0;
//getanother side data//get arc start-angle//( dir
ection : from circle-center to end-point )*EntityA
ngleAnother = ( Entity->AngEnd ) * pi / 180.0;//ch
ange angle to oppsite direction//( direction : fro
m end-point to circle-center )*EntityAngleAnother
= *EntityAngleAnother + pi;//check angle if ( *Ent
ityAngleAnother > 2.0*pi )*EntityAngleAnother = *E
ntityAngleAnother - 2.0 * pi;elseif ( fabs(*Entity
AngleAnother-2.0*pi) < Tolerance ) *EntityAngleAno
ther = 0.0;//compute tangentline angle for the arc
end-angle//( direction : from end-point to start-
point )*EntityAngleAnother = *EntityAngleAnother +
0.5 * pi;//check angle if ( *EntityAngleAnother >
2.0*pi )*EntityAngleAnother = *EntityAngleAnother
- 2.0 * pi;else if ( fabs(*EntityAngleAnother-2.0
*pi) < Tolerance ) *EntityAngleAnother = 0.0;}else
{//get arc end-angle//( direction : from circle-ce
nter to end-point)RotateVertexFlag= 2;*EntityAngle
= ( Entity->AngEnd ) * pi / 180.0;//change angle t
o oppsite direction//( direction : from end-point
to circle-center )*EntityAngle = *EntityAngle + p
i;if ( *EntityAngle > 2.0*pi ) *EntityAngle = *Ent
ityAngle - 2.0*pi;if ( fabs(*EntityAngle - 2.0*pi)
< Tolerance )*EntityAngle = 0.0;//compute tangent
line angle for the arc end-angle//( direction : fr
om end-point to start-point )*EntityAngle = *Entit
yAngle + 0.5 * pi;if ( *EntityAngle > 2.0*pi ) *En
tityAngle = *EntityAngle - 2.0*pi;if ( fabs(*Entit
yAngle - 2.0*pi) < Tolerance )*EntityAngle =0.0;//
get another side data//get arc start-angle//( dire
ction : from circle-center to start-point )*Entity
AngleAnother = ( Entity->AngBegin ) *pi / 180.0;//
change angle to oppsite direction//( direction : f
rom start-point to circle-center )*EntityAngleAnot
her = *EntityAngleAnother + pi;if ( *EntityAngleAn
other > 2.0*pi )*EntityAngleAnother = *EntityAngle
Another - 2.0 * pi;if ( fabs(*EntityAngleAnother -
2.0*pi ) < Tolerance )*EntityAngleAnother = 0.0;/
/compute tangentline angle for the arc start-angle
//( direction : from start-point to end-point )*En
tityAngleAnother =*EntityAngleAnother + 1.5 * pi;i
f ( *EntityAngleAnother > 2.0*pi )*EntityAngleAnot
her = *EntityAngleAnother - 2.0 * pi;if ( fabs(*En
tityAngleAnother - 2.0*pi ) < Tolerance )*EntityAn
gleAnother = 0.0;}//the end of this functionreturn
RotateVertexFlag;}/*=============================
====================================関数: 名称:
F2dCleanUpLineAngle記述: It is a function for con
trol how to compute a line typeentity's angle. 戻
り値:RotateVertexFlag: direction flag=1: vertex1
is rotate point=2: vertex2 is rotate pointパラメー
タ:入力: 1 OriginVertex: rotationary vertex2 Ent
ity: line type entity 出力:1 EntityAngle: directi
on angle ( radian )2 EntityAngleAnother: another s
ide direction angle===============================
=================================*/int F2dCleanUpL
ineAngle(//inputstructplanar_vertex *OriginVertex,
structnode *Entity,//outputdouble*EntityAngle,doub
le*EntityAngleAnother){//return value intRotateVer
texFlag=0;//selected entity and temp entitiesstruc
t planar_vertex*VertexTemp,*VertexAnotherTemp;//le
ngth and angledoublediff_x = 0.0,diff_y = 0.0,Tole
rance = 0.0;//set toleranceTolerance = F2dCleanUpT
olerance;//select connected side of entityif ( Ent
ity->vertex1 == OriginVertex ){//get vertex1->vert
ex2 RotateVertexFlag= 1;VertexTemp= Entity->vertex
1;VertexAnotherTemp= Entity->vertex2;}else{ //get
vertex2->vertex1 RotateVertexFlag=2;VertexTemp =
Entity->vertex2;VertexAnotherTemp= Entity->vertex
1;}//compute angleif ( fabs( VertexTemp->X - Verte
xAnotherTemp->X ) < Tolerance){//angle = 0.5 * pii
f ( VertexTemp->Y < VertexAnotherTemp->Y )*EntityA
ngle = 0.5 * pi;//angle = 1.5 * pielse*EntityAngle
= 1.5 * pi;}else{ //-pi< angle < pidiff_y = Vert
exAnotherTemp->Y - VertexTemp->Y;if ( fabs( diff_y
) > Tolerance ){diff_x = VertexAnotherTemp->X - V
ertexTemp->X; *EntityAngle = atan2( diff_y, diff
_x );//-pi < angle < 0.0if ( *EntityAngle < 0.0 )
*EntityAngle = *EntityAngle + 2.0*pi; }else{ //an
gle = 0.0orpiif ( VertexAnotherTemp->X > VertexTem
p->X )*EntityAngle = 0.0;else*EntityAngle = pi;}}i
f ( fabs(*EntityAngle - 2.0*pi) < Tolerance ) *Ent
ityAngle = 0.0;//get another side angle*EntityAngl
eAnother = *EntityAngle +pi;// check angleif ( *E
ntityAngleAnother > ( 2.0 * pi ) ){*EntityAngleAno
ther = *EntityAngleAnother - 2.0 * pi;}if ( fabs(*
EntityAngleAnother- 2.0*pi) < Tolerance ) {*Entity
AngleAnother = 0.0;}//the end of this functionretu
rn RotateVertexFlag;}/*===========================
====================================== 関数: 名
称: F2dCleanUpChangeColor 記述: エンティ
ティの色を変更する関数。 戻り値: =0:成
功裏に完了 パラメータ: 入力:
Entities_change_color_list :変更された色で
あるノードリスト==================================
===============================*/int F2dCleanUpCha
ngeColor(struct node_list *Entities_change_color_l
ist){//link list and temp liststruct node_list*Col
or_temp_list;//selected entity and temp entitiesst
ruct node *Next_entity;//entity's specifitysCK_EN
TATTattr;//specificity of entitiesint CountPrompt
= 0;charmessage[64];#ifdef VELLUMCountPrompt++;spr
intf( message,"Start Change Color Entity %d", Coun
tPrompt );ck_prompt( message );#endif#ifdef VELLUM
// clear views highlighting ck_erase_leve
l("VW_2D");// ck_erase_level("VW_TRIM");#endif/
/check all of entities on the listfor( Color_temp_
list=Entities_change_color_list; Color_temp_list;
Color_temp_list = Color_temp_list->cdr){if ( Col
or_temp_list->car ==NULL )break;Next_entity = Colo
r_temp_list->car;switch ( Next_entity->flags ){cas
e 1:attr.color = CK_GREEN;ck_setattr( Next_entity-
>id, CK_COLOR,NULL, &attr );break;case 3:attr.colo
r = CK_GRAY;ck_setattr( Next_entity->id, CK_COLOR,
NULL, &attr );break;case 4:attr.color = CK_MAGENT
A;ck_setattr( Next_entity->id, CK_COLOR, NULL, &at
tr );break;}}#ifdef VELLUMCountPrompt++;sprintf( m
essage,"Finished change color Entity %d", CountPro
mpt );ck_prompt( message ); #endifreturn 0;}/*===
==================================================
============ 関数: 名称: F2dCleanUpChange
DrawingColor 記述: エンティティの色を変更す
る関数。 復帰値: =0:成功裏に完了; パラ
メータ: 入力:1 In drawing:図中で1:変
更された色である図================================
=================================*/int F2dCleanUpC
hangeDrawingColor(struct drawing *In_drawing){//ex
tern functionsvoid draw_entity();//selected entity
and temp entitiesstruct node *entity;int CountPro
mpt = 0;charmessage[64];//entity's specifitysCK_EN
TATTattr;//specificity of entities#ifdef VELLUM
// clear views highlighting ck_erase_level("VW
_2D");// ck_erase_level("VW_TRIM");CountPrompt+
+;sprintf( message,"Start Change Color Sheet Entit
y %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_entit
y( entity, entity->color );break;case3:draw_entity
( entity, CK_BLUE );break;case 4: draw_entity( ent
ity, CK_MAGENTA );break;case 5:draw_entity( entit
y, entity->color );break;case 6:draw_entity( entit
y, CK_RED );break;case 7:draw_entity( entity, CK_Y
ELLOW );break;case 8:draw_entity( entity, entity->
color );break;case 9:draw_entity( entity, entity->
color );break;case 10:draw_entity( entity, CK_CYAN
);break;case 11:draw_entity( entity, entity->colo
r );break; #endif #ifdef CKWINcase 1:attr.color =
CK_L_GREEN;ck_setattr( entity->id, CK_COLOR, NULL,
&attr );break;case 3:attr.color = CK_L_GRAY;ck_se
tattr( entity->id, CK_COLOR, NULL, &attr );break;c
ase 4:attr.color = CK_MAGENTA;ck_setattr( entity->
id, CK_COLOR, NULL, &attr );break;case 6:attr.colo
r = 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 VELLUMCount
Prompt++;sprintf( message,"Finished change color S
heet Entity %d", CountPrompt );ck_prompt( message
); #endifreturn 0;}/*===========================
====================================== 関数: 名
称: F2dCleanUpUndoPre 記述: 取消関
数のためのデータフラグを準備すること。 復帰値:
=0:成功裏に完了; パラメータ: 入
力:1 In drawing: 変更ステータスである図。======
==================================================
=========*/int F2dCleanUpUndoPre(structdrawing *In
_drawing){//selected entity and temp entitiesstruc
t node *entity;
//set flagF2dCleanUpExcutedNo =2;//check all of
entities on the listfor( entity=In_drawing->object
s;entity; entity = entity->next){entity->status =
entity->flags;if ( entity->next == NULL )break;}re
turn 0;}/*========================================
=========================関数: 名称: F2dCleanUpU
ndo記述: To undo.戻り値:= 0: Completed successfu
lly;パラメータ:入力: 1 In_drawing: drawing that
will be undoed status=============================
====================================*/int F2dClean
UpUndo(struct drawing *In_drawing){//selected enti
ty and temp entitiesstruct node *entity;//flagint
NoChangeFlag = 0;//check flagif ( F2dCleanUpExcute
dNo == 0)return NoChangeFlag;//check all of entiti
es on the listfor( entity=In_drawing->objects; en
tity; entity = entity->next){if ( entity->status !
=entity->flags ){NoChangeFlag = 1;entity->flags =
entity->status;}if ( entity->next == NULL )break;}
//check views flagif ( F2dCleanUpExcutedNo == 1 )
In_drawing->views = NULL;//reset flag for viewsF2d
CleanUpExcutedNo= 0;return NoChangeFlag;}/*=======
==================================================
======== 関数: 名称: F2dCleanUpChangeDraw
ingFlag記述: エンティティのフラグを変更する
関数。 復帰値: =0:成功裏に完了; パラメー
タ: 入力: 1 In drawing: 変
更された色である図================================
=================================*/int F2dCleanUpC
hangeDrawingFlag(struct drawing *In_drawing){//sel
ected entity and temp entitiesstruct node *entity;
int CountPrompt =0;charmessage[64];#ifdef VELLUMCo
untPrompt++;sprintf( message,"Start Flag Sheet Ent
ity %d", CountPrompt );ck_prompt( message ); #end
if//check all of entities on the listfor( entity=I
n_drawing->objects; entity; entity = entity->nex
t){if ( entity->flags == 4 ) entity->flags = 3;#i
fdefVELLUM//CountPrompt++;//sprintf( message,"Flag
Sheet Entity %d", CountPrompt );//ck_prompt( mess
age ); #endifif ( entity->next == NULL )break;}#i
fdef VELLUMCountPrompt++;sprintf( message,"Finishe
d Flag Sheet Entity%d", CountPrompt );ck_prompt( m
essage ); #endifreturn 0;}/*=====================
============================================ 関
数: 名称:F2dCleanUpFindSameColorEntity 記述:
同じ色のエンティティを見出す。 復帰値:
=0: 成功裏に完了; パラメータ: 入力:
1 In entity: エンティティ 2 In drawin
g: 変更された色である図==========================
======================================*/int F2dCle
anUpFindSameColorEntity(struct node *In_entity,str
uctdrawing *In_drawing){//selected entity and temp
entitiesstruct node *entity;int CountPrompt = 0;c
harmessage[64];#ifdef VELLUMCountPrompt++;sprintf
( message,"Start Find same color Entity %d", Count
Prompt );ck_prompt(message ); #endif//check all o
f entities on the listfor( entity=In_drawing->obje
cts; entity; entity = entity->next){if ( entity-
>color == In_entity->color && entity->flags == 0)
entity->flags = 3;if ( entity->next== NULL )brea
k;}#ifdef VELLUMCountPrompt++;sprintf( message,"Fi
nished find same color Entity %d", CountPrompt );c
k_prompt( message ); #endifreturn 0;}/*==========
==================================================
===== 関数: 名称: F2dCleanUpClearDrawingEnt
ity 記述: それは復帰エンティティの色である。
復帰値: =0:成功裏に完了; パラメー
タ: 入力: 1 In drawing: 変更さ
れた色である図====================================
==========================*/int F2dCleanUpClearDra
wingEntity(struct drawing *In_drawing){//selected
entity and temp entitiesstruct node *entity;//enti
ty's specifitysCK_ENTATTattr;//specificity of enti
tiesint CountPrompt = 0;charmessage[64];#ifdef VEL
LUM // clear views highlighting ck_erase_lev
el("VW_2D");// ck_erase_level("VW_TRIM");//Coun
tPrompt++;//sprintf( message,"Start Clear Entity %
d", CountPrompt );//ck_prompt( message ); #endif/
/check all of entities on the listfor( entity=In_d
rawing->objects; entity; entity = entity->next)
{ if ( entity == NULL )break;switch ( entity->flag
s ){case 0:case 1:case 2:case 3:case 4:case 5:case
6:case 7:case 8:case 9:case 10:entity->flags = 0;
draw_entity( entity, entity->color );//attr.color
= entity->color;//ck_setattr( entity->id, CK_COLO
R, NULL, &attr );default:break;}}#ifdef VELLUM//Co
untPrompt++;//sprintf( message,"Finished clear Ent
ity %d",CountPrompt );//ck_prompt( message ); #en
dif//clear views connectedIn_drawing->views = NUL
L;return 0;}/*====================================
=============================関数: 名称:F2dClea
nUpClearDrawingKeepFlags 記述: エンティティの
色を復帰させるが、フラグは保持する。 復帰値:
=0:成功裏に完了;パラメータ: 入力:
1 In drawing:変更された色である図========
==================================================
=======*/int F2dCleanUpClearDrawingKeepFlags(struc
t drawing *In_drawing){//selected entity and temp
entitiesstruct node *entity;//entity's specifitysC
K_ENTATTattr;//specificity of entitiesint CountPro
mpt = 0;charmessage[64];#ifdef VELLUM // clear
views highlighting ck_erase_level("VW_2D");#end
if//check all of entities on the listfor( entity=I
n_drawing->objects;entity; entity = entity->next)
{switch ( entity->flags ){case 0:case 1:case 2:cas
e 3:case 4:case 5:case 6:case 7:case 8:case 9:case
10://centerlinedraw_entity( entity, entity->color
);//attr.color = entity->color;//ck_setattr( enti
ty->id, CK_COLOR, NULL, &attr );}if ( entity->next
== NULL )break;}return 0;}/*=====================
=========================================== 関
数: 名称: F2dCleanUpDeleteViews 記述:
それは削除ビユーに対する関数である。 復帰値:
=0:成功裏に完了;パラメータ: 入力:
1 In drawing:図==========================
=======================================*/int F2dCl
eanUpDeleteViews(struct drawing *In_drawing){//che
ck drawingif ( In_drawing == NULL )return 0; //
delete views ( Not release memory )In_drawing->vie
ws == NULL;return 0;}/*===========================
====================================== 関数: 名
称: F2dCleanUpDeleteDrawingEntity 記述:
それは削除エンティティに対する関数である。 復帰
値: =0:成功裏に完了; パラメータ:
入力: 1 In drawing:図================
=================================================*
/int F2dCleanUpDeleteDrawingEntity(struct drawing
*In_drawing){//selected entity and temp entitiesst
ruct node *entity;struct group *Gp;//groupstruct n
ode_list *ETL;//Entity Temp ListintCountPrompt =
0;charmessage[64];#ifdef VELLUMCountPrompt++;sprin
tf( message,"Start Delete 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->flag
s == 3|| entity->flags == 6 || entity->flags == 0
|| entity->flags == 10 ){#ifdef CKWINck_delent( e
ntity->id );#endif#ifdef VELLUM// remov
e_entity ( entity, In_drawing );#endifentity->fla
gs = 99;}if ( entity->next == NULL )break;}if ( In
_drawing->views == NULL )return 0;//unuse group en
titiesfor( Gp=In_drawing->views; Gp; Gp = Gp->nex
t){if ( Gp == NULL )break;if ( Gp->index != 0 )con
tinue;for ( ETL = Gp->entities; ETL; ETL = ETL->cd
r ){#ifdef CKWINck_delent( ETL->car->id );#endif#i
fdef VELLUM // remove_entity ( ETL->car,
In_drawing );#endifETL->car->flags = 99; if ( ET
L->cdr == NULL )break;}if ( Gp->next == NULL )brea
k;}#ifdef VELLUMCountPrompt++;sprintf( message,"Fi
nished Delete Entity %d",CountPrompt );ck_prompt(
message ); #endifreturn 0;}/*====================
=============================================関
数: 名称: F2dCleanUpCheckEntityExist記述: check
an entity for current drawingif the entityis not
same to database, drawing was changed 戻り値:= 0:
No change;= 1:Changed;パラメータ:入力: 1 In_dra
wing: drawing ====================================
============================*/int F2dCleanUpCheckE
ntityExist(struct drawing *In_drawing){//selected
entity and temp entitiesstructnode *entity;//defin
eint 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,ang1=0.0,ang
2=0.0;//entity's specifitysCK_ENTATTattr;//specifi
city of entities//check all of entities on thelist
if ( In_drawing->objects == NULL ) return1;for( e
ntity=In_drawing->objects; entity; entity = enti
ty->next){if ( entity->flags == 99 )continue;Retur
nCode = ck_getentid( entity->id, &etype );if ( Ret
urnCode ==CK_NO_ENT )return1;else{//check all of e
ntities on the listswitch ( entity->type ){case CK
_ARC:ck_getarc ( entity->id, &x1,&y1,&z1, &rad,&a
ng1,&ang2, &attr );break; case CK_LINE: ck_getlin
e( entity->id, &x1,&y1,&z1, &x2,&y2,&z2, &attr );
break;}if ( attr.level == 191 )return0;elsereturn
1;}if ( entity->next == NULL )break;}return 1;}/*=
==================================================
============= 関数: 名称: F2dCleanUpChangeA
rrowVertexFlag 記述: アラウトップ頂点フラグ
を変更し、アローセンタライン座標を設定する。 復帰
値: =0:成功裏に完了; パラメータ:
入力: 1 Flags:フラグ 2
TopVertex:アロートップ頂点 3 Entiry:
アローセンタラインエンティティ==================
===============================================*/i
ntF2dCleanUpChangeArrowVertexFlag(//inputint *flag
s,structplanar_vertex *TopVertex,structnode *Entit
y){//set flag to arrow top vertexTopVertex->flags
= *flags;//set arrow center line coordinatesTopVer
tex->ArrowCenterLine_X1 = Entity->X1;TopVertex->Ar
rowCenterLine_Y1 = Entity->Y1;TopVertex->ArrowCent
erLine_Z1 = Entity->Z1;TopVertex->ArrowCenterLine_
X2 = Entity->X2;TopVertex->ArrowCenterLine_Y2 = En
tity->Y2;TopVertex->ArrowCenterLine_Z2 = Entity->Z
2;//endreturn 0;}/*===============================
================================== 関数: 名称:
F2dCleanUpFindArrowCenterEntity 記述: ア
ローセンタラインを見出し、フラグをアローメンバに設
定する。 復帰値: =0:アロー無し; =
1:アロー パラメータ: 入力: 1
Nodes:接続されたノード 2 TopVertex:アロ
ートップ頂点 3 StartEntity:アロースター
トラインエンティティ 4 EndEntity:アロー
エンドラインエンティティ 5 CenterLineAngl
eTemp:アローセンタライン角度=====================
============================================*/int
F2dCleanUpFindArrowCenterEntity(//inputstruct node
_list *Nodes,structplanar_vertex *TopVertex,struct
node*StartEntity,structnode *EndEntity,double*Cent
erLineAngleTemp ){//external functionsint F2dClean
UpLineAngle(); int F2dCleanUpChangeChildrenFlag();
int F2dCleanUpChangeArrowVertexFlag();double F2dCl
eanUpLineLength();//nodesstructnode *CenterEntity;
//link list and temp liststruct node_list*temp_lis
t;//flagsint ReturnFlag = 0,ArrowFlags = 3; //doub
ledoubleCenterParentLength = 0.0,CenterParentAngle
= 0.0,CenterParentAngleAnother = 0.0;doubleTolera
nce = 0.0;//set valueTolerance = F2dCleanUpToleran
ce;// look for arrow center linefor( temp_list = N
odes; temp_list; temp_list =temp_list->cdr){//che
ck pointer addressif ( StartEntity == temp_list->c
ar || EndEntity == temp_list->car)continue;//get
new entityCenterEntity= temp_list->car;//check fla
gs//if ( CenterEntity->flags != 2 //&& CenterEnt
ity->flags != 3 )continue; if ( CenterEntity->type
!= CK_LINE )continue; if ( CenterEntity->line_ty
pe != StartEntity->line_type && CenterEntity->co
lor != StartEntity->color && CenterEntity->is_th
ickness !=StartEntity->is_thickness ) continue; if
( CenterEntity->no_connected_1< 2 && CenterEntit
y->no_connected_2 < 2 ) continue; //check lengt
hCenterParentLength = F2dCleanUpLineLength( Center
Entity->parent );if ( CenterParentLength < Toleran
ce ) continue;//arrow central-entity angleF2dClean
UpLineAngle(//inputTopVertex, CenterEntity->paren
t,//output&CenterParentAngle, &CenterParentAngleAn
other );//check the angle for central entity if (
fabs( CenterParentAngle - *CenterLineAngleTemp )>
Tolerance )continue;// set flags for arrow's entit
iesReturnFlag = 1;//look for arrow entity's childr
enF2dCleanUpChangeChildrenFlag( StartEntity->paren
t );F2dCleanUpChangeChildrenFlag( EndEntity->paren
t );F2dCleanUpChangeChildrenFlag( CenterEntity->pa
rent );//set flag to arrow top vertexF2dCleanUpCha
ngeArrowVertexFlag( &ArrowFlags, TopVertex, Center
Entity );return ReturnFlag;if ( temp_list->cdr ==
NULL )break;}return ReturnFlag;}/* 関数:名称:
F2dCleanUpFindArrowOneSideOpenEntity 記述:
1つのサイドオープンエンティティを見出す。 復帰
値: =0: ノーオープン; =1: オープン
=2: オープン パラメータ: 入力:
1 Nodes:接続されたノード======================
==========================================*/int F2
dCleanUpFindArrowOneSideOpenEntity( struct node_li
st*Nodes ){//link list and temp liststruct node_li
st*temp_list;//entitiescounter and flagsint open_e
ntity_flag = 0;//startfor( temp_list = Nodes; tem
p_list; temp_list = temp_list->cdr){//ckeck anoth
er side connected's counterif ( temp_list->car->no
_connected_1 == 0 && temp_list->car->no_connected_
2 > 1 ){open_entity_flag = 1;break;}if ( temp_list
->car->no_connected_2 == 0 && temp_list->car->no_c
onnected_1 > 1 ){open_entity_flag = 2;break;}if (
temp_list->cdr == NULL )break;}return open_entity_
flag;}/*==========================================
=======================関数: 名称: F2dClaenU
pCheckStartEndEntity 記述: 開始および終了エン
ティティをチェックする 復帰値: =0: ノ
ーアロー;= 1: goodパラメータ:入力: 1 StartEntit
y: アロー開始ラインエンティティ2 EndEntity: アロー
終了ラインエンティティ============================
=====================================*/int F2dClea
nUpCheckStartEndEntity(//inputstructnode *StartEnt
ity,structnode *EndEntity ){//external functionsdo
ubleF2dCleanUpLineLength();//doubledoublearrow_sta
rt_parent_length = 0.0,arrow_end_parent_length =
0.0,arrow_tolerance = 0.0;//set tolerancearrow_tol
erance = F2dCleanUpTolerance;//start//compute enti
ties' parent lengtharrow_start_parent_length = F2d
CleanUpLineLength( StartEntity );arrow_end_parent_
length = F2dCleanUpLineLength( EndEntity );//che
ck lengthif (arrow_start_parent_length < arrow_tol
erance )return 0; if ( arrow_end_parent_length < a
rrow_tolerance )return 0; //check tloeranceif ( fa
bs( arrow_start_parent_length - arrow_end_parent_l
ength )> arrow_tolerance )return 0; //check angl
e:if entities are parallel, STOPif (sqrt(fabs((( S
tartEntity->X1 - StartEntity->X2 ) * ( EndEntit
y->Y1 - EndEntity->Y2)) -(( EndEntity->X1 -
EndEntity->X2 ) * ( StartEntity->Y1 - StartEnt
ity->Y2 ))))< arrow_tolerance )return 0;//normal e
ndreturn 1;}/*====================================
============================関数: 名称: F2dClean
UpComputeCenterLineAngle記述: センタライン角度を
計算する。戻り値:= 0: ノーアロー;= 1: 良好パラメ
ータ:入力: 1 TopVertex: アロートップ頂点2 StartE
ntity: アロー開始ラインエンティティ 3 EndEntity:
アロー終了ラインエンティティ出力:1 CenterLineAngl
e: アローセンターライン角度=======================
=========================================*/int F2d
CleanUpComputeCenterLineAngle(//inputstructplanar_
vertex *TopVertex,structnode *StartEntity,structno
de *EndEntity,//outputdouble*CenterLineAngle ){//e
xternal functionsint F2dCleanUpLineAngle();//entit
ies counter and flagsint ReturnFlag = 0;//doubledo
ublearrow_start_parent_angle = 0.0,arrow_end_paren
t_angle = 0.0,arrow_center_diff_angle = 0.0,Rotate
AxisAngleAnotherTemp = 0.0,arrow_center_parent_ang
le_temp = 0.0,arrow_tolerance= 0.0;//set tolerance
arrow_tolerance = F2dCleanUpTolerance;//start// co
mpute central angle of arrow////angle_center = 0.5
* ( angle_start + angle_end )//atan2 returns the
arctangent of y/x//atan2 returns a value in the ra
nge -pi to pi radians//get arrow start angleF2dCle
anUpLineAngle(//inputTopVertex, StartEntity,//outp
ut&arrow_start_parent_angle, &RotateAxisAngleAnoth
erTemp);//arrow end angleF2dCleanUpLineAngle(//inp
utTopVertex, EndEntity,//output&arrow_end_parent_a
ngle, &RotateAxisAngleAnotherTemp);//get differenc
e anglearrow_center_diff_angle = fabs( arrow_end_p
arent_angle - arrow_start_parent_angle );//same
angleif ( arrow_center_diff_angle < arrow_toleranc
e )return 0;if ( arrow_center_diff_angle < pi ){//
diff < piarrow_center_parent_angle_temp = 0.5 * (a
rrow_end_parent_angle+ arrow_start_parent_angle
);}else{//diff > pi ( take opposite angle )arrow_
center_parent_angle_temp = 0.5 * (arrow_end_parent
_angle + arrow_start_parent_angle ) + pi;//angle >
2*piif ( fabs ( arrow_center_parent_angle_temp -
2.0 * pi )< arrow_tolerance ){arrow_center_parent_
angle_temp= 0.0;}else{if ( arrow_center_parent_ang
le_temp > ( 2.0 * pi ) ){arrow_center_parent_angle
_temp = arrow_center_parent_angle_temp - 2.0 * p
i;}}}*CenterLineAngle = arrow_center_parent_angle_
temp;//normal endreturn 1;}/*=====================
============================================関数:
名称: F2dCleanUpFindArrowEndEntity記述: アロー
終了ラインを見出す戻り値:= 0: ノーアロー;= 1: ア
ローパラメータ:入力: 1 Nodes: 接続ノード2TopVert
ex: アロートップ頂点3 StartEntity: アロー開始エン
ティティ==========================================
======================*/int F2dCleanUpFindArrowEnd
Entity(//inputstruct node_list *Nodes,structplanar
_vertex *TopVertex,structnode *StartEntity ){//ext
ernal functionsint F2dCleanUpFindArrowOneSideOpenE
ntity();int F2dCleanUpComputeCenterLineAngle();int
F2dCleanUpCheckStartEndEntity();int F2dCleanUpFin
dArrowCenterEntity();//link list and temp liststru
ct node_list*temp_list; //selected entity and temp
entitiesstruct node *Next_entity,*arrow_start_ent
ity_parent,*arrow_end_entity,*arrow_end_entity_par
ent;//entities counter and flagsint assistant_line
_flag = 0,ReturnFlag = 0;//doubledoublearrow_cente
r_parent_angle_temp = 0.0;//startfor( temp_list=No
des; temp_list; temp_list = temp_list->cdr){ if
( 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->l
ine_type != StartEntity->line_type )continue;if (
Next_entity->color != StartEntity->color )continu
e;if ( Next_entity->is_thickness != StartEntity->i
s_thickness )continue; //set parentarrow_start_e
ntity_parent = StartEntity->parent; arrow_end_enti
ty_parent = Next_entity->parent; //look for brok
en entity's another side ReturnFlag = F2dCleanUpFi
ndArrowOneSideOpenEntity( arrow_end_entity_parent-
>children ); if ( ReturnFlag == 0)continue;//check
parents entitiesReturnFlag = F2dCleanUpCheckStart
EndEntity( //inputarrow_start_entity_parent, arro
w_end_entity_parent );if (ReturnFlag == 0 )continu
e;// look for central entityof arrowReturnFlag =F2
dCleanUpComputeCenterLineAngle(//inputTopVertex, a
rrow_start_entity_parent, arrow_end_entity_parent,
//output&arrow_center_parent_angle_temp );if ( Ret
urnFlag == 0 )continue;// get central entity of ar
rowassistant_line_flag = F2dCleanUpFindArrowCenter
Entity(//inputNodes, TopVertex, StartEntity, arrow
_end_entity, &arrow_center_parent_angle_temp );ret
urn assistant_line_flag;}return assistant_line_fla
g;}/*=============================================
====================関数: 名称: F2dCleanUpChange
ChildrenFlag記述: エンティティのチルドレンフラグ
を変更する関数戻り値:=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 li
ght grayTemp_list->car->flags = 3; if ( Temp_list-
>cdr == NULL )break;}return 0;}/*=================
================================================関
数: 名称: F2dCleanUpLineLength記述: ライン形エ
ンティティの長さを計算する関数 戻り値:= 長さ;パラ
メータ:入力: エンティティ: ペアレントエンティテ
ィ================================================
================*/double F2dCleanUpLineLength(stru
ct node *Entity){//definationdoubleEntityLength=0.
0;//compute entities' parent lengthEntityLength =
sqrt( ( Entity->X1 - Entity->X2 ) * ( Entity->X1
- Entity->X2 )+ ( Entity->Y1 - Entity->Y2 ) *( Ent
ity->Y1 - Entity->Y2 ));returnEntityLength;}/*====
==================================================
===========関数: 名称: F2dCleanUpFindArrow記述:
アロー型エンティティを求め、フラグをそれらに設定
する。 戻り値:= 0: 成功裏に完了;パラメータ:入
力: 1 Entities_list: チェックされるノードリスト==
==================================================
============*/int F2dCleanUpFindArrow( struct node
_list *Entities_list ){//external functionsint F2d
CleanUpLineAngle();int F2dCleanUpFindArrowEndEntit
y(); //link list andtemp liststruct node_list*temp
_nodes1,*arrow_list,*temp_list; //selectedentity a
nd temp entitiesstruct node *Next_entity;struct pl
anar_vertex*top_vertex;//entities counter and flag
sint bug_flag = 0,ReturnFlag = 0,assistant_line_fl
ag = 0;int CountPrompt = 0;charmessage[64];#ifdef
VELLUMCountPrompt++;sprintf( message,"Start Find A
rrow Entity %d", CountPrompt);ck_prompt( message
); #endif// Step_1:look for one side open entity
//arrow start entityfor( temp_list=Entities_list;
temp_list; temp_list =temp_list->cdr){Next_entit
y = temp_list->car;//if ( Next_entity->flags!= 2 )
continue;if ( Next_entity->type != CK_LINE ) cont
inue;if ( Next_entity->no_connected_1 == 0&& Next
_entity->no_connected_2 < 2 ) continue;if ( Next_
entity->no_connected_1 < 2&& Next_entity->no_co
nnected_2== 0 ) continue; //select entity's si
deif ( Next_entity->no_connected_1 == 0 ){// clear
bug_flagbug_flag = 0;//look for broken entity's a
nother side for( arrow_list = Next_entity->parent-
>children; arrow_list;arrow_list = arrow_list->cd
r){//ckeck another side vertex's pointerif (Next_e
ntity->parent->vertex2 == arrow_list->car->vertex
2 ){ bug_flag =1; break;}if ( arrow_list->cdr ==
NULL )break;}if ( bug_flag == 1 ){top_vertex = Ne
xt_entity->parent->vertex2;temp_nodes1 = arrow_lis
t->car->connected_nodes_2;}}else{// clear bug_flag
bug_flag = 0;//look for brokenentity's another sid
e for( arrow_list = Next_entity->parent->children;
arrow_list; arrow_list = arrow_list->cdr){//ckeck
another side vertex'spointerif ( Next_entity->par
ent->vertex1 == arrow_list->car->vertex1 ){ bug_
flag = 1; break;}if ( arrow_list->cdr == NULL )br
eak;}if ( bug_flag == 1 ){top_vertex = Next_entity
->parent->vertex1;temp_nodes1 = arrow_list->car->c
onnected_nodes_1;}}if ( bug_flag != 1 ) contin
ue;// getend entity of arrowReturnFlag = F2dCleanU
pFindArrowEndEntity(//inputtemp_nodes1, top_verte
x, Next_entity );if ( ReturnFlag == 1 )assistant_l
ine_flag = 1;if ( temp_list->cdr == NULL )break;}#
ifdef VELLUMCountPrompt++;sprintf( message,"Finish
ed find arrows Entity %d", CountPrompt );ck_prompt
( message ); #endifreturnassistant_line_flag;}/*=
==================================================
==============関数: 名称: F2dCleanUpFindOneSideO
penEntity記述: look for one side open entities an
d they are vertical with arrow type entities. 戻り
値:= 0: Completed successfully andNo found;= NUM:
Open entities' numberパラメータ:入力: 1 Entitie
s_list: a node list that will be checked==========
==================================================
====*/int F2dCleanUpFindOneSideOpenEntity( structn
ode_list *Entities_list ){//external functionsint
F2dCleanUpChangeChildrenFlag();//link list and tem
p liststruct node_list *temp_list; //selected enti
ty and temp entitiesstruct node *Next_entity;//ent
ities counter and flagsint count = 0;//doubledoubl
eassistant_line_angle = 0.0,arrow_tolerance = 0.0;
int CountPrompt = 0;charmessage[64];//set toleranc
earrow_tolerance = F2dCleanUpTolerance;#ifdef VELL
UMCountPrompt++;sprintf( message,"Start Find One s
ide open Entity %d", CountPrompt );ck_prompt( mess
age); #endif // check all of entities which co
nnected with outside loop for( temp_list=Entiti
es_list; temp_list; temp_list = temp_list->cdr)
{ if ( temp_list->car == NULL )break;Next_entity =
temp_list->car;//check flags//if ( Next_entity->f
lags !=2 )continue;//check vertex' flagif( Next_en
tity->vertex1->flags != 3 && Next_entity->vertex2-
>flags != 3)continue;//check lines verticallyif (
Next_entity->vertex1->flags == 3){assistant_line_a
ngle = fabs ( ( Next_entity->X1 - Next_entity->X
2 )*(Next_entity->vertex1->ArrowCenterLine_X1
- Next_entity->vertex1->ArrowCenterLine_X2 ) + ( N
ext_entity->Y1 - Next_entity->Y2 ) * (Next_entity-
>vertex1->ArrowCenterLine_Y1 - Next_entity->ve
rtex1->ArrowCenterLine_Y2 ) );}else{assistant_line
_angle = fabs ( ( Next_entity->X1 - Next_entity-
>X2 )* (Next_entity->vertex2->ArrowCenterLine_X1
- Next_entity->vertex2->ArrowCenterLine_X2 ) +
( Next_entity->Y1 - Next_entity->Y2) * (Next_entit
y->vertex2->ArrowCenterLine_Y1 - Next_entity->
vertex2->ArrowCenterLine_Y2 ) );}//check the angle
for central entity if ( sqrt(assistant_line_angl
e) > arrow_tolerance ) continue;//look for childre
nF2dCleanUpChangeChildrenFlag( Next_entity->parent
);count++;}#ifdef VELLUMCountPrompt++;sprintf( me
ssage,"Finished find one side open Entity %d", Cou
ntPrompt );ck_prompt( message ); #endif//normal e
ndreturn count;}/*================================
=================================関数:名称: F2dC
leanUpFindOneSideOpenEntity2記述: ビユーを見出し
た後に一側がオープンのエンティティとビユーの境界を
横切るエンティティを見出す。戻り値:= 0: 成功裏に
完了し、何も見出されない;= NUM: オープンエンティテ
ィの個数パラメータ:入力: 1 In_drawing: 図=======
==================================================
=======*/int F2dCleanUpFindOneSideOpenEntity2( str
uct drawing *In_drawing ){//external functionsint
F2dCleanUpChangeChildrenFlag();//link list and tem
p liststruct node_list *temp_list, *ConnectedNode;
//selected entity and temp entitiesstruct node *E
ntity;//defineflagintBoundaryFlag = 0; int CountPr
ompt = 0;charmessage[64];#ifdef VELLUMCountPrompt+
+;sprintf( message,"2 Start Find Oneside Open Ent
ity %d", CountPrompt );ck_prompt( message ); #end
if //check node listif ( In_drawing == NULL )ret
urn-1;if ( In_drawing->objects == NULL )return-1;/
/ check all of entities which connected with outsi
de loop for( Entity=In_drawing->objects;Entity;
Entity = Entity->next ){//check connectednodes cou
ntif ( Entity == NULL )break;if (( Entity->no_conn
ected_1 == 0) &&( Entity->no_connected_2 == 0 ))c
ontinue;//check flagsif (( Entity->flags == 3 ) &&
( Entity->type == CK_LINE ) &&(( Entity->no_conne
cted_1 == 0 ) ||( Entity->no_connected_2 == 0
))){//one side open and linetypeif ( Entity->no_c
onnected_2 == 0 ) ConnectedNode = Entity->conne
cted_nodes_1;else ConnectedNode = Entity->connecte
d_nodes_2;//clear foundboundary's flagBoundaryFlag
= 0;//check across with views' boundaryif (Connec
tedNode != NULL ){for ( temp_list = ConnectedNode;
temp_list;temp_list = temp_list->cdr ){//check wr
ong dataif ( temp_list->car == NULL )break;if ( te
mp_list->car->flags == 4 ){//find boundary's entit
yBoundaryFlag = 1;break;}if ( temp_list->cdr == NU
LL )break;}if ( BoundaryFlag ==1 ) //look for chi
ldren F2dCleanUpChangeChildrenFlag( Entity->parent
);}}//check arc if (( Entity->type == CK_ARC ) &
&( Entity->flags != 99 )&&(( Entity->no_connected_
1 == 0 ) ||( Entity->no_connected_2 == 0 ))){//l
ook for childrenF2dCleanUpChangeChildrenFlag( Enti
ty->parent );}if( Entity->next == NULL )break;}#if
def VELLUMCountPrompt++;sprintf( message,"Finished
2 one side open Entity %d", CountPrompt );ck_prom
pt( message ); #endif//normal endreturn 0;}/*====
==================================================
==========関数: 名称: F2dCleanUpFindGroupMinX記
述:エンティティグループに対する最小X値を求める。
戻り値:= 0: 成功裏に完了し、エンティティ無し;パラ
メータ:入力: 1 Entities_list: チェックされるノー
ドリスト出力:1 Entity: エンティティは最小のX値
を含む。==========================================
======================*/struct node *F2dCleanUpFin
dGroupMinX( struct node_list *Entities_list ){//do
uble F2dCleanUpLineLength();//entities counter and
flagsint open_entity_flag = 0;//link list and tem
p liststruct node_list*EntitiesList2,*Out_temp_lis
t2,*open_temp_list2, *open_list2, *temp_list1, *te
mp_list2; //selected entity and temp entitiesstruc
t node *Next_entity, *MinXvalueEntity;//length an
dangledoubleMinXvalueGroup = 0.0;//check all of en
tities which connectedwith outside loop//initializ
eEntitiesList2 =( struct node_list * ) calloc ( 1,
sizeof ( struct node_list ));open_list2 = ( struc
t node_list * )calloc ( 1, sizeof ( struct node_li
st ));//check first entity//search connected entit
y until real entity be foundfor ( temp_list2 = Ent
ities_list;//entity->connected_nodes; ( temp_list
2!=0 && temp_list2->car!=0 ); temp_lis
t2=temp_list2->cdr){if ( temp_list2->car == NULL )
break;if ( temp_list2->car->no_connected_1 == 0 )
continue;if ( temp_list2->car->no_connected_2 == 0
) continue;if ( temp_list2->car->flags == 2 ){//s
et pointer to first entityopen_list2->car = temp_l
ist2->car;//set minimum X valueMinXvalueGroup = te
mp_list2->car->Min_X;MinXvalueEntity = temp_list2-
>car;break;}if ( temp_list2->cdr == NULL )break;}i
f ( open_list2->car == 0 )return 0;//set link addr
essopen_list2->cdr = NULL;//set the pointer to out
put node listEntitiesList2->car = open_list2->car;
EntitiesList2->cdr = open_list2->cdr;////Step_6_1:
//find connected entitiesfor( temp_list1 = open_li
st2; ( temp_list1 //&&(temp_list->cdr!=
0) ); ) {//get a pointer from open listi
f ( temp_list1->car== NULL )break;Next_entity = te
mp_list1->car;//set a closed flag to thenode//Next
_entity->flags = 1;//close the node ( delete the n
ode from open list )open_list2 = open_list2->cdr;/
/ look for first connected entitywhose flags=0.for
( temp_list2 = Next_entity->connected_nodes; ( t
emp_list2!=0 && temp_list2->car!=0 );
temp_list2=temp_list2->cdr){ if ( temp_list2->
car == NULL ) break;// if found an unmarked connec
ted entityif ( temp_list2 && temp_list2->car->flag
s==2&& MinXvalueEntity->line_type == temp_list2->c
ar->line_type&& MinXvalueEntity->color == temp_lis
t2->car->color&& MinXvalueEntity->is_thickness ==
temp_list2->car->is_thickness ) {//check mini
mum Xif ( temp_list2->car->Min_X < MinXvalueGroup
){//change minimum X valueMinXvalueGroup = temp_
list2->car->Min_X;MinXvalueEntity = temp_list2->ca
r; }// allocate memory for openlist elementopen_te
mp_list2 = ( struct node_list * ) calloc ( 1, size
of( struct node_list ));// allocate memory for out
put node list elementOut_temp_list2 = ( struct nod
e_list * ) calloc ( 1, sizeof ( struct node_list
));// add this entity to the open listopen_temp_l
ist2->car = temp_list2->car;// add this entity to
the output node list Out_temp_list2->car =temp_lis
t2->car;//set a open flagto the nodeopen_temp_list
2->car->flags= 1; // connect to the open listopen_
temp_list2->cdr = open_list2;// move the pointer o
f open list to the topopen_list2 = open_temp_list
2;// connect to the output node listOut_temp_list2
->cdr = EntitiesList2;// movethe pointer of output
node list to the topEntitiesList2 = Out_temp_list
2;}if ( temp_list2->cdr == NULL )break;}// assign
value to the loop variabletemp_list1 = open_list
2;}return MinXvalueEntity;}/*=====================
============================================関数:
名称: F2dCleanUpFindOutNextEntity記述: アウトサ
イドループエンティティに接続されたエンティティを求
める。戻り値:= 0: 成功裏に完了;パラメータ:入力:
1 In_entity: 軸エンティティを回転 2 In_Nodes: エ
ンティティのノード3 In_Vertex: エンティティの頂点4
*In_Angle: エンティティの角度====================
============================================*/int
F2dCleanUpFindOutNextEntity(//input struct node*In
_entity,struct node_list *In_Nodes, struct planar_
vertex *In_Vertex,double *In_Angle){//external fun
ctionsint F2dCleanUpArcAngle(); int F2dCleanUpLine
Angle();//link list and temp liststruct node_list*
temp_list, *RotateNodes,*RotateNodesTemp,*RotateNo
desAnother,*RotateNodesAnotherTemp;//selected enti
ty and temp entitiesstruct node *Next_entity, *Ro
tateEntity;struct planar_vertex*RotateVertex,*Rota
teVertexTemp,*RotateVertexAnother,*RotateVertexAno
therTemp;int RotateVertexFlag =0,RotateAxisEntityT
ype = 0,RotateAxisEntityVertexFlag = 0,FindNextFla
g= 0;//length and angledoubleRotateAxisAngleAnothe
r = 0.0,RotateAxisAngleAnotherTemp = 0.0,RotateMin
AngleTemp = 0.0,RotateDiffAngleTemp = 0.0,RotateAx
isAngle = 0.0,RotateAxisAngleTemp = 0.0;//set tole
rance TolerancedoubleTolerance = 0.0;Tolerance =
F2dCleanUpTolerance;//initializeRotateAxisAngleAno
ther= *In_Angle;RotateEntity= In_entity;RotateNode
sAnother= In_Nodes;RotateVertexAnother= In_Vertex;
//check all of entities which connected with outsi
de loopfor( ; ; ){//set flag for first entity on
loopFindNextFlag = 0;RotateEntity->flags= 4;Rotate
AxisEntityType = RotateEntity->type;if ( RotateEnt
ity->vertex1 == RotateVertexAnother )RotateAxisEnt
ityVertexFlag = 1;else RotateAxisEntityVertexFlag
= 2;//set standard axis for first searchRotateAxis
Angle = RotateAxisAngleAnother;RotateMinAngleTemp=
2.0 * pi;RotateNodes= RotateNodesAnother;RotateVe
rtex= RotateVertexAnother; //check next connect
ed entityif ( RotateNodes == 0 )break;//start loop
process for( temp_list=RotateNodes; temp_lis
t; temp_list = temp_list->cdr){if ( temp_list->ca
r == NULL )break;Next_entity = temp_list->car;//ch
eck flagsif ( Next_entity->flags == 4 )break;if (
Next_entity->flags != 1 )continue;switch ( Next_en
tity->type ){//arc type entitycaseCK_ARC:RotateVe
rtexFlag = F2dCleanUpArcAngle(//inputRotateVertex,
Next_entity,//output&RotateAxisAngleTemp, &Rotate
AxisAngleAnotherTemp);break;//line type entitycas
eCK_LINE:RotateVertexFlag = F2dCleanUpLineAngle(//
inputRotateVertex, Next_entity,//output&RotateAxis
AngleTemp, &RotateAxisAngleAnotherTemp);break;//wr
ong type entitydefault:break;}//select connected s
ide of entityif ( RotateVertexFlag == 1 ){//get st
art->end//set rotation vertex nodeRotateNodesTemp
= Next_entity->connected_nodes_1;RotateVertexTemp=
Next_entity->vertex1;//set another side vertex no
deRotateNodesAnotherTemp = Next_entity->connected_
nodes_2;RotateVertexAnotherTemp= Next_entity->vert
ex2;}else{//set rotation vertex nodeRotateNodesTem
p = Next_entity->connected_nodes_2;RotateVertexTem
p = Next_entity->vertex2;//set another side vertex
nodeRotateNodesAnotherTemp = Next_entity->connect
ed_nodes_1;RotateVertexAnotherTemp= Next_entity->v
ertex1;}//compute diff angle//for change current e
ntityRotateDiffAngleTemp = RotateAxisAngleTemp - R
otateAxisAngle;if ( fabs( RotateDiffAngleTemp ) <
Tolerance ) {switch( RotateAxisEntityType ){caseCK
_ARC:switch( RotateAxisEntityVertexFlag ){case1:Ro
tateDiffAngleTemp = 2.0 * pi;break;case2:RotateDif
fAngleTemp = 0.0;break;}break;caseCK_LINE:switch(
RotateVertexFlag ){case1:RotateDiffAngleTemp = 0.
0;break;case2:RotateDiffAngleTemp = 2.0 * pi;brea
k;}break;}}if ( RotateDiffAngleTemp < 0.0 ){Rotate
DiffAngleTemp = RotateDiffAngleTemp + 2.0 * pi;}if
( fabs( RotateDiffAngleTemp - RotateMinAngleTemp
) < Tolerance ) {switch( Next_entity->type ){case
CK_ARC:switch( RotateEntity->type ){caseCK_ARC:swi
tch( RotateVertexFlag ){case1://nochangebreak;case
2:RotateEntity= Next_entity;RotateNodes = Rotate
NodesTemp;RotateVertex= RotateVertexTemp;RotateNod
esAnother = RotateNodesAnotherTemp;RotateVertexAno
ther = RotateVertexAnotherTemp;RotateAxisAngleAnot
her = RotateAxisAngleAnotherTemp;break;}break;case
CK_LINE:switch( RotateVertexFlag ){case1://no chan
gebreak;case2:RotateEntity= Next_entity;RotateNode
s = RotateNodesTemp;RotateVertex= RotateVertexTe
mp;RotateNodesAnother = RotateNodesAnotherTemp;Rot
ateVertexAnother = RotateVertexAnotherTemp;RotateA
xisAngleAnother = RotateAxisAngleAnotherTemp;brea
k;}break;}caseCK_LINE:switch( RotateEntity->type )
{caseCK_ARC:if ( RotateEntity->vertex1 == RotateVe
rtex ){RotateEntity= Next_entity;RotateNodes = R
otateNodesTemp;RotateVertex= RotateVertexTemp;Rota
teNodesAnother = RotateNodesAnotherTemp;RotateVert
exAnother = RotateVertexAnotherTemp;RotateAxisAngl
eAnother = RotateAxisAngleAnotherTemp;}break;}}}if
( RotateDiffAngleTemp < RotateMinAngleTemp ){Find
NextFlag = 1;RotateMinAngleTemp = RotateDiffAngleT
emp;//set rotation entityRotateEntity= Next_entit
y;RotateNodes= RotateNodesTemp;RotateVertex= Rotat
eVertexTemp;RotateNodesAnother = RotateNodesAnothe
rTemp;RotateVertexAnother = RotateVertexAnotherTem
p;RotateAxisAngleAnother = RotateAxisAngleAnotherT
emp;}}//check flags//if loopmeet closed entity if
( Next_entity->flags == 4 )break;if ( FindNextFlag
== 0 ) break;}return 0;}/*=======================
==========================================関数:
名称: F2dCleanUpFindOutSideLoop記述: アウトサイ
ドループエンティティを求める。戻り値:= 0: アウト
サイドループエンティティを求める。;= NUM: アウトサ
イドエンティティの個数パラメータ:入力: 1 Entit
y: エンティティはループの最小X値を含む。========
==================================================
======*/int F2dCleanUpFindOutSideLoop( struct node
*MinXvalueEntity ){//external functionsint F2dCle
anUpArcAngle(); int F2dCleanUpLineAngle();int F2dC
leanUpFindOutFirstEntity();int F2dCleanUpFindOutNe
xtEntity(); //entities counter and flagsint count=
0,count2 = 0,open_entity_flag = 0,RotateVertexFla
g = 0,assistant_line_flag = 0;//link list and temp
liststruct node_list*outside_loop_temp_list3, *Ro
tateNodes,*RotateNodesTemp,*RotateNodesAnother,*Ro
tateNodesAnotherTemp;//selected entity and temp en
titiesstruct node *Next_entity, *RotateEntity;str
uct planar_vertex*RotateVertex,*RotateVertexTemp,*
RotateVertexAnother,*RotateVertexAnotherTemp;//len
gth and angledoubleassistant_line_angle = 0.0,MinX
valueGroup = 0.0,RotateAxisAngleAnother = 0.0,Rota
teAxisAngleAnotherTemp = 0.0,RotateMinAngleTemp =
0.0,RotateDiffAngle = 0.0,RotateDiffAngleTemp = 0.
0,RotateAxisAngle = 0.0,RotateAxisAngleTemp = 0.0;
//set tolerance Tolerancedoubleloop_tolerance =
0.00;loop_tolerance= F2dCleanUpTolerance;//loop di
rection : counter-clock//check a flag foroutside l
oop process//if ( count2 > 0 ){//step_7_1:find fir
st entity for the group//set standard axis for fir
st searchRotateAxisAngle = 1.5 * pi;RotateMinAngle
Temp= 2.0 * pi;//step_7_1_1: only one entity//chec
k entities' angle//arc case : special case ( no ve
rtex on min_x )if ( MinXvalueEntity->type == CK_AR
C && ( fabs ( MinXvalueEntity->Min_X - MinXvalueE
ntity->vertex1->X ) > loop_tolerance ) && ( fabs
( MinXvalueEntity->Min_X - MinXvalueEntity->vertex
2->X ) > loop_tolerance ) ){//set rotation vertex
nodeRotateNodesAnother = MinXvalueEntity->connecte
d_nodes_2;RotateVertexAnother = MinXvalueEntity->v
ertex2;RotateEntity= MinXvalueEntity;//get arc end
-angle //( direction : from circle-center to end-p
oint )RotateAxisAngleAnotherTemp = ( MinXvalueEnti
ty->AngEnd ) * pi / 180.0;//change angle to oppsit
e direction//( direction : from end-point to circl
e-center )RotateAxisAngleAnotherTemp = RotateAxisA
ngleAnotherTemp + pi;//check angle if ( RotateAxis
AngleAnotherTemp > ( 2.0 * pi )){ RotateAxisAngleA
notherTemp = RotateAxisAngleAnotherTemp - 2.0 * p
i;}if ( fabs ( RotateAxisAngleAnotherTemp - ( 2.0
* pi )) < loop_tolerance ){RotateAxisAngleAnotherT
emp = 0.0;}//compute tangentline angle for the arc
end-angle//( direction : from end-point to start-
point )RotateAxisAngleAnotherTemp = RotateAxisAngl
eAnotherTemp + 0.5 * pi;//check angle if ( RotateA
xisAngleAnotherTemp > ( 2.0 * pi )){ RotateAxisAng
leAnotherTemp = RotateAxisAngleAnotherTemp - 2.0 *
pi;}if ( fabs ( RotateAxisAngleAnotherTemp - ( 2.
0 *pi )) < loop_tolerance ){RotateAxisAngleAnother
Temp = 0.0;}//set rotation standard angle ( clock
direction )RotateAxisAngleAnother = RotateAxisAn
gleAnotherTemp;}//step_7_
1_2: multiple entities ar
ound Min_xelse{//select c
onnected side of entityif
( fabs ( MinXvalueEntity
−>Min_X − MinXvalueEntity
−>vertex1−>X ) < loop_tol
erance )//get start−>end
//set rotationvertex node
RotateVertex= MinXvalueEn
tity−>vertex1;elseRotateV
ertex= MinXvalueEntity−>v
ertex2;switch ( MinXvalue
Entity−>type ){//arc typ
e entitycaseCK_ARC:Rotate
VertexFlag = F2dCleanUpAr
cAngle(//inputRotateVerte
x, MinXvalueEntity,//outp
ut&RotateAxisAngleTemp, &
RotateAxisAngleAnotherTem
p);break;//line type ent
itycaseCK_LINE:RotateVert
exFlag = F2dCleanUpLineAn
gle(//inputRotateVertex,
MinXvalueEntity,//output&
RotateAxisAngleTemp,&Rota
teAxisAngleAnotherTemp);b
reak;default:break;} //se
lect connected side of en
tityif ( RotateVertexFlag
== 1 ){//get start−>end
//set rotationvertex node
RotateNodesTemp = MinXval
ueEntity−>connected_nodes
_1;RotateVertexTemp= MinX
valueEntity−>vertex1;//se
t another side vertex nod
eRotateNodesAnotherTemp =
MinXvalueEntity−>connect
ed_nodes_2;RotateVertexAn
otherTemp= MinXvalueEntit
y−>vertex2;}else{//set ro
tation vertex nodeRotateN
odesTemp = MinXvalueEntit
y−>connected_nodes_2;Rota
teVertexTemp = MinXvalueE
ntity−>vertex2;//set anot
her side vertex nodeRotat
eNodesAnotherTemp =MinXva
lueEntity−>connected_node
s_1;RotateVertexAnotherTe
mp= MinXvalueEntity−>vert
ex1;}//compute diff angle
//for change current enti
tyRotateDiffAngleTemp = R
otateAxisAngleTemp − Rota
teAxisAngle;if ( RotateDi
ffAngleTemp < 0.0 ){Rotat
eDiffAngleTemp = RotateDi
ffAngleTemp + 2.0 * pi;}i
f ( RotateDiffAngleTemp <
RotateMinAngleTemp ){Rot
ateMinAngleTemp = RotateD
iffAngleTemp;//set rotati
on entityRotateEntity= Mi
nXvalueEntity;RotateNodes
= RotateNodesTemp;RotateV
ertex= RotateVertexTemp;R
otateNodesAnother =Rotate
NodesAnotherTemp;RotateVe
rtexAnother = RotateVerte
xAnotherTemp;RotateAxisAn
gleAnother = RotateAxisAn
gleAnotherTemp;}//step_7_
1_3: find next connected
entity with first entity
around Min_x−vertex//chec
k all of entities which c
onnected with first entit
y if ( RotateNodes !=
0 ){for( outside_loop_tem
p_list3=RotateNodes; out
side_loop_temp_list3; ou
tside_loop_temp_list3 = o
utside_loop_temp_list3−>c
dr){if ( outside_loop_tem
p_list3−>car == NULL )bre
ak;Next_entity = outside_
loop_temp_list3−>car;//ch
eck flagsif ( Next_entity
−>flags !=1 )continue;swi
tch ( Next_entity−>type )
{//arc type entitycaseCK
_ARC:RotateVertexFlag = F
2dCleanUpArcAngle(//input
RotateVertex, Next_entit
y, //output&RotateAxisAng
leTemp, &RotateAxisAngleA
notherTemp);break;//line
type entitycaseCK_LINE:R
otateVertexFlag = F2dClea
nUpLineAngle(//inputRotat
eVertex, Next_entity, //o
utput&RotateAxisAngleTem
p, &RotateAxisAngleAnothe
rTemp);break;//wrong type
entitydefault:break;}//s
elect connected side of e
ntityif ( RotateVertexFla
g == 1 ){//get start−>end
//set rotation vertex no
deRotateNodesTemp = Next_
entity−>connected_nodes_
1;RotateVertexTemp= Next_
entity−>vertex1;//set ano
ther side vertex nodeRota
teNodesAnotherTemp = Next
_entity−>connected_nodes_
2;RotateVertexAnotherTemp
= Next_entity−>vertex2;}e
lse{//set rotation vertex
nodeRotateNodesTemp = Ne
xt_entity−>connected_node
s_2;RotateVertexTemp = Ne
xt_entity−>vertex2;//set
another side vertex nodeR
otateNodesAnotherTemp = N
ext_entity−>connected_nod
es_1;RotateVertexAnotherT
emp=Next_entity−>vertex
1;}//compute diff angle//
for change current entity
RotateDiffAngleTemp = Rot
ateAxisAngleTemp − Rotate
AxisAngle;if ( RotateDiff
AngleTemp < 0.0 ){RotateD
iffAngleTemp = RotateDiff
AngleTemp + 2.0 * pi;}if
( fabs( RotateDiffAngleTe
mp − RotateMinAngleTemp )
< loop_tolerance ){switc
h( Next_entity−>type ){ca
seCK_ARC:switch( RotateEn
tity−>type ){caseCK_ARC:s
witch( RotateVertexFlag )
{case1://no changebreak;c
ase2:RotateEntity= Next_e
ntity;RotateNodes = Rot
ateNodesTemp;RotateVertex
= RotateVertexTemp;Rotate
NodesAnother = RotateNode
sAnotherTemp;RotateVertex
Another = RotateVertexAno
therTemp;RotateAxisAngleA
nother = RotateAxisAngleA
notherTemp;break;}break;c
aseCK_LINE:switch( Rotate
VertexFlag ){case1://no c
hangebreak;case2:RotateEn
tity= Next_entity;RotateN
odes = RotateNodesTemp;
RotateVertex= RotateVerte
xTemp;RotateNodesAnother
= RotateNodesAnotherTemp;
RotateVertexAnother = Rot
ateVertexAnotherTemp;Rota
teAxisAngleAnother = Rota
teAxisAngleAnotherTemp;br
eak;}break;}caseCK_LINE:s
witch( RotateEntity−>type
){caseCK_ARC:if ( Rotate
Entity−>vertex1 == Rotate
Vertex ){RotateEntity= Ne
xt_entity;RotateNodes =
RotateNodesTemp;RotateVe
rtex= RotateVertexTemp;Ro
tateNodesAnother = Rotate
NodesAnotherTemp;RotateVe
rtexAnother = RotateVerte
xAnotherTemp;RotateAxisAn
gleAnother = RotateAxisAn
gleAnotherTemp;}break;}}}
if ( RotateDiffAngleTemp
< RotateMinAngleTemp ){Ro
tateMinAngleTemp = Rotate
DiffAngleTemp;//set rotat
ion entityRotateEntity= N
ext_entity;RotateNodes
= RotateNodesTemp;RotateV
ertex= RotateVertexTemp;R
otateNodesAnother = Rotat
eNodesAnotherTemp;RotateV
ertexAnother =RotateVerte
xAnotherTemp;RotateAxisAn
gleAnother = RotateAxisAn
gleAnotherTemp;}}}}//step
_7_2: find next connected
entity with first entity
alongthe loopF2dCleanUpF
indOutNextEntity(//input
RotateEntity, RotateNodes
Another, RotateVertexAnot
her, &RotateAxisAngleAnot
her );return 0;}/*=======
=========================
=========================
========関数: 名称:TestFindArrowControl
記述: 手動関数。ビユーに対して全てのアロー型エン
ティティを求める。戻り値:< 0: エラー= 0: プロセス
なし> 0: 成功裏に完了;個数は見出されたエンティティ
のカウンタ値である。パラメータ:副関数:struct nod
e_list *F2dCleanUpPickUpAllOneSideOpenEntity一側オ
ープンのエンティティを求める。int F2dCleanUpFindAr
rowアロー型エンティティを求める。int F2dCleanUpFin
dArrowEndEntityアローエンドラインを見出す。int F2d
CleanUpFindArrowCenterEntityアローセンターラインを
見出す。int F2dCleanUpFindArrowOneSideOpenEntityア
ロー型の一側オープンのエンティティを見出す。int F2
dCleanUpComputeCenterLineAngleセンターライン角度を
計算する。int F2dCleanUpCheckStartEndEntityスター
トエンティティおよびエンドエンティティをチェックす
る。int F2dCleanUpLineAngleラインタイプエンティテ
ィの角度を計算する。int F2dCleanUpArcAngle弓形のエ
ンティティの角度を計算する。int F2dCleanUpChangeCh
ildrenFlagエンティティのチルドレンフラグを変更す
る。int F2dCleanUpChangeArrowVertexFlagアロー頂点
のフラグを変更し、アローセンターライン座標を設定す
る。int F2dCleanUpChangeDrawingColorエンティティの
色を変更する。 double F2dCleanUpLineLengthライン型
エンティティの長さを計算する。====================
============================================*/intT
estFindArrowControl( int *SwitchRedraw ){//externa
l functionsint F2dCleanUpFindArrow();int F2dCleanU
pChangeDrawingColor();struct node_list *F2dCleanUp
PickUpAllOneSideOpenEntity();//entities counter an
d flagsint count = 0,assistant_line_flag = 0;//lin
k list and temp liststruct node_list*Entities_chan
ge_color_list1; //Begin//-------------------------
---------//Step_1://check the number of entites//
get count of all entities// if an error occurred,
exit immidiately. if (number_of_entities<0) r
eturn -1;//---------------------------------//Step
_3: pickup all one side open entitiesEntities_chan
ge_color_list1 = F2dCleanUpPickUpAllOneSideOpenEnt
ity(&trim_drawing ); if (Entities_change_color_
list1 == 0) return 0;//--------------------------
-------//Step_4: find arrow lineF2dCleanUpFindArro
w( Entities_change_color_list1 );//---------------
------------------//Step_X://change color to Magen
ta for a selected boundary // turn offinput lev
els#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels(C
K_OFF,1,255);#endifif ( *SwitchRedraw == 1)F2dClea
nUpChangeDrawingColor(&trim_drawing);//clear a fla
g for outside loop processassistant_line_flag = 0;
// turn ON the level used to store the trimmed ent
ities.#ifdef CKWINif ( *SwitchRedraw == 1)ck_level
s(CK_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw =
= 1)ck_redraw( CK_PRIME_VP );#endifreturn count;}/
*=================================================
================関数: 名称: TestFindOneSideOpen2
Control記述: 手動関数。 一側がオープンで、ビユー
の境界を横切るエンティティを全て見出す。 戻り値:<
0: エラー= 0: プロセスなしパラメータ:副関数:int
F2dCleanUpFindOneSideOpenEntity2一側がオープン
で、ビユーの境界を横切るエンティティを全て求める。
int F2dCleanUpChangeDrawingColorエンティティの色を
変更する。========================================
========================*/intTestFindOneSideOpen2C
ontrol( int *SwitchRedraw ){//external functionsin
t F2dCleanUpFindOneSideOpenEntity2();int F2dCleanU
pChangeDrawingColor();//Step_1:check the number of
entites// if an erroroccurred, exit immidiately.
if (number_of_entities<0) return -1;//Step_2:p
ickup all one side open entitiesF2dCleanUpFindOneS
ideOpenEntity2(&trim_drawing );//Step_X:change col
or to Magenta for a selected boundary // turn o
ff input levels#ifdef CKWINif ( *SwitchRedraw ==
1)ck_levels(CK_OFF,1,255);#endifif ( *SwitchRedraw
== 1)F2dCleanUpChangeDrawingColor(&trim_drawing);
// turn ON the level used to store the trimmed ent
ities.#ifdef CKWINif ( *SwitchRedraw == 1)ck_level
s(CK_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw =
= 1)ck_redraw( CK_PRIME_VP );#endifreturn 0;}/*===
==================================================
============関数:名称: TestFindOneSideOpenContro
l記述: 手動関数。 ビユーに対して、一側が開放でア
ロー型エンティティに対して垂直のものを見出す。戻り
値:< 0: エラー= 0: プロセスなし> 0: 成功裏に完了;
この数は、見出されたエンティティの個数。パラメー
タ:副関数:struct node_list *F2dCleanUpPickUpAllO
neSideOpenEntity一側開放エンティティを求める。int
F2dCleanUpChangeChildrenFlagエンティティのチルドレ
ンフラグを変更する。int F2dCleanUpChangeDrawingCol
orエンティティの色を変更する。int F2dCleanUpFindOn
eSideOpenEntity一側開放エンティティを求め、それら
はアロー型エンティティに対して垂直である。========
==================================================
======*/intTestFindOneSideOpenControl( int *Switch
Redraw ){//external functionsint F2dCleanUpFindOne
SideOpenEntity();int F2dCleanUpChangeDrawingColo
r();struct node_list *F2dCleanUpPickUpAllOneSideOp
enEntity();//entities counter andflagsint count =
0,assistant_line_flag = 0;//link list and temp lis
tstruct node_list*Entities_list; //Begin//--------
--------------------------//Step_1://check the num
ber of entites// if an error occurred, exit immidi
ately. if (number_of_entities<0) return -1;//-
--------------------------------//Step_2: pickup a
ll one side open entitiesEntities_list = F2dCleanU
pPickUpAllOneSideOpenEntity( &trim_drawing ); i
f (Entities_list == 0) return 0;//---------------
------------------//Step_3: find lines vertical wi
th arrow type entitiesF2dCleanUpFindOneSideOpenEnt
ity( Entities_list );//---------------------------
------//Step_X://change color to Magenta for a sel
ected boundary // turn off input levels#ifdef C
KWINif ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,25
5);#endifif ( *SwitchRedraw == 1)F2dCleanUpChangeD
rawingColor(&trim_drawing);//clear a flag for outs
ide loop processassistant_line_flag = 0;// turn ON
the level used to store the trimmed entities.#ifd
ef CKWINif ( *SwitchRedraw == 1)ck_levels(CK_ON,Tr
imLevel, TrimLevel);if ( *SwitchRedraw == 1)ck_red
raw( CK_PRIME_VP );#endifreturn count;}/*=========
==================================================
======関数: 名称: F2dCleanUpPickUpAllOneSideOpen
Entity記述: 選択図の全ての一側開放エンティティを
求める。戻り値:= 0: 成功裏に完了;パラメータ:入
力: In_drawing: 図出力:NodeList:全ての一側開放エ
ンティティに対するノードリスト====================
============================================*/stru
ct node_list *F2dCleanUpPickUpAllOneSideOpenEntity
(struct drawing *In_drawing ){//entities counter a
nd flagsint count =0;//link list and temp liststru
ct node_list*EntitiesList1,*Out_temp_list; //selec
ted entity and temp entitiesstruct node *entity;//
initializeEntitiesList1 =( struct node_list * ) ca
lloc ( 1, sizeof ( struct node_list));//set a flag
for the boundary entitycount = 0;//check pointer
aboutfirst entityif ( In_drawing->objects == 0 )
return0;//set a open flagtothe node//open_list->ca
r->flags = 1;//set the pointer to output node list
//set pointer to first entityfor (entity=In_drawin
g->objects; entity && (count<number_trimmed_e
ntities); entity=entity->next) {if( entity
== NULL )break;if ( entity->no_connected_1 > 0 &&
entity->no_connected_2 > 0 )continue;if ( entity-
>no_connected_1 == 0 && entity->no_connected_2 ==
0 )continue; if ( entity->type != CK_LINE )
continue;EntitiesList1->car = entity;break;}//set
link addressEntitiesList1->cdr = NULL;//----------
-----------------------//find connected entitiesif
( EntitiesList1 == 0 ) return 0; if ( entity ==
0 ) return 0; if (entity->next == 0 ) return E
ntitiesList1; for (entity=entity->next;entity &
& (count<number_trimmed_entities); entity=
entity->next) {count++;if ( entity == NULL )brea
k; if ( entity->type != CK_LINE )continue;i
f ( entity->no_connected_1 > 0 && entity->no_conne
cted_2 > 0 )continue;if ( entity->no_connected_1 =
= 0 && entity->no_connected_2 == 0 )continue;// al
locate memory for output node list elementOut_temp
_list = ( struct node_list * ) calloc ( 1, sizeof
( struct node_list ));// add this entity to the ou
tput node list Out_temp_list->car = entity;// conn
ect to the output node listOut_temp_list->cdr = En
titiesList1;//move the pointer of output node list
to the topEntitiesList1 = Out_temp_list;if ( enti
ty->next == NULL )break;} if (count>=number_tr
immed_entities) return 0;
else return EntitiesList1;}/*===============
==================================================
関数: 名称: F2dCleanUpPickUpAllArcEntity記述:
選択図の全てのアークエンティティを求める。戻り値:
= 0: 成功裏に完了;パラメータ:入力: In_drawing:
図出力:NodeList: 全てのアークエンティティに対する
ノードリスト======================================
==========================*/struct node_list *F2dC
leanUpPickUpAllArcEntity(struct drawing *In_drawin
g ){//entities counter and flagsint count = 0;//li
nk list and temp liststruct node_list*EntitiesList
1,*Out_temp_list; //selected entity and temp entit
iesstruct node *entity;//initializeEntitiesList1 =
( struct node_list * ) calloc ( 1, sizeof ( struct
node_list ));//set a flag for the boundary entity
count = 0;//check pointer about first entityif ( I
n_drawing->objects ==0 ) return0;//set pointer to
first entityfor (entity=In_drawing->objects;
entity && (count<number_trimmed_entities);
entity=entity->next) { if ( entity == NUL
L )break; if ( entity->type != CK_ARC )cont
inue;EntitiesList1->car = entity;break;}//set link
addressEntitiesList1->cdr = NULL;//--------------
-------------------//find connected entitiesif ( E
ntitiesList1 == 0 ) return 0; if ( entity == 0
)return 0; if ( entity
−>next == 0 ) return Enti
tiesList1; for (entity
=entity−>next; entit
y && (count<number_trimme
d_entities);entity=entity
−>next) {count++;if ( ent
ity == NULL )break;
if ( entity−>type != CK
_ARC )continue;// allocat
e memory for output node
listelementOut_temp_list
= ( struct node_list * )
calloc ( 1, sizeof ( stru
ct node_list ));// add th
is entity to the output n
ode list Out_temp_list−>c
ar = entity;// connect to
the output node listOut_
temp_list−>cdr = Entities
List1;// move the pointer
of output node list to t
he topEntitiesList1 = Out
_temp_list;if ( entity−>n
ext == NULL )break;} i
f (count>=number_trimmed_
entities) return 0;

else returnEntitiesList
1;}/*====================
=========================
====================関数: 名
称: F2dCleanUpFindCenterLineEntity記述: アークの
センタラインエンティティを求める。 戻り値:= 0: 成
功裏に完了し、何も見出されない。= NUM: 開放エンテ
ィティの個数副関数:int F2dCleanUpChangeChildrenFl
ag未使用エンティティに対してフラグを設定する。doub
leF2dDistancePointLineアークの中心点からエンティテ
ィまでの距離を計算する。パラメータ:入力: 1 In_Dr
awing: a図2 In_Entities_list: 全てのアークに対する
ノードリスト======================================
==========================*/int F2dCleanUpFindCent
erLineEntity( struct drawing *In_drawing, struct n
ode_list *In_Entities_list ){//external functionsi
nt F2dCleanUpChangeChildrenFlag();doubleF2dDistanc
ePointLine();double F2dCleanUpLineLength();//linkl
ist and temp liststruct node_list *temp_list, *tem
p_list2, *temp_list3,*temp_list4; //selected entit
y and temp entitiesstruct node *ArcEntity,*ViewEnt
ity;//define 3D coordinates struct VectorVsp, Vep,
Vp;//entitiescounter and flagsint count = 0;//dou
bledoubleDistance = 0.0,DistanceViewEntity2Center
= 0.0,DX = 0.0,DY = 0.0,ViewEntityLength = 0.0,Tol
erance= 0.0;int CountPrompt = 0;charmessage[64];//
set toleranceTolerance = F2dCleanUpTolerance;#ifde
f VELLUMCountPrompt++;sprintf( message,"Start Find
Center Entity %d", CountPrompt );ck_prompt( messag
e ); #endif // check all of entities which con
nected with outside loop for( temp_list=In_Enti
ties_list; temp_list; temp_list = temp_list->cd
r){ if ( temp_list->car == NULL )break;ArcEntity =
temp_list->car;//check all of entities in the vie
wfor( ViewEntity=In_drawing->objects; ViewEntity;
ViewEntity = ViewEntity->next){//check flags: on
ly no marks entities if ( ViewEntity->flags !=0 &&
ViewEntity->flags !=10 )continue;//check type : o
nlyline if ( ViewEntity->type != CK_LINE )continu
e;//check open side: onlyopen lineif ( ViewEntity-
>no_connected_1 > 0 && ViewEntity->no_connected_2
> 0 )continue;//check open side: two side open lin
e ( delete )if ( ViewEntity->no_connected_1 == 0 &
& ViewEntity->no_connected_2 == 0&& ViewEntity->li
ne_type != CK_CENTER ){ViewEntity->flags = 3;conti
nue;}//checkparent open sideif ( ViewEntity->no_co
nnected_1 == 0&& ViewEntity->line_type != CK_CENTE
R ){//set center line flags ( look for children )f
or( temp_list2=ViewEntity->parent->children; temp
_list2 && temp_list2->cdr;temp_list2 = temp_list2-
>cdr){//change flag to light grayif ( temp_list2->
car == NULL ) break;if ( temp_list2->car->vertex2
== ViewEntity->parent->vertex2 ) break;}if ( temp_
list2->car->no_connected_2 != 0) continue;}if ( Vi
ewEntity->no_connected_2 == 0&& ViewEntity->line_t
ype != CK_CENTER ){//set center line flags ( look
for children )for( temp_list3=ViewEntity->parent->
children; temp_list3 && temp_list3->cdr; temp_li
st3 = temp_list3->cdr){//change flag to light gray
if ( temp_list3->car == NULL )break;if ( temp_list
3->car->vertex1 == ViewEntity->parent->vertex1 ) b
reak;}if ( temp_list3->car->no_connected_1 != 0) c
ontinue;}//check distance from arc's center to lin
e entityVsp.x=ViewEntity->X1;Vsp.y=ViewEntity->Y1;
Vsp.z=ViewEntity->Z1;Vep.x=ViewEntity->X2;Vep.y=Vi
ewEntity->Y2;Vep.z=ViewEntity->Z2;Vp.x=ArcEntity->
CenterX;Vp.y=ArcEntity->CenterY;Vp.z=ArcEntity->Ce
nterZ;Distance = F2dDistancePointLine( Vsp, Vep, V
p );if ( Distance > Tolerance ) continue;//check b
ounding box : only outside and notouchif (( ViewEn
tity->parent->Max_X >= ArcEntity->Min_X && ViewEn
tity->parent->Max_X <= ArcEntity->Max_X )&& ( View
Entity->parent->Max_Y >= ArcEntity->Min_Y && Vie
wEntity->parent->Max_Y <= ArcEntity->Max_Y )) {F2d
CleanUpChangeChildrenFlag( ViewEntity->parent );co
ntinue;}if (( ViewEntity->parent->Min_X >= ArcEnti
ty->Min_X && ViewEntity->parent->Min_X <=ArcEntit
y->Max_X )&& ( ViewEntity->parent->Min_Y >= ArcEnt
ity->Min_Y&& ViewEntity->parent->Min_Y <= ArcEntit
y->Max_Y )) {F2dCleanUpChangeChildrenFlag( ViewEnt
ity->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 )) {F2dCleanUpChangeCh
ildrenFlag( ViewEntity->parent );continue;}if (( A
rcEntity->Min_X >= ViewEntity->parent->Min_X && A
rcEntity->Min_X <= ViewEntity->parent->Max_X )&&
( ArcEntity->Min_Y >= ViewEntity->parent->Min_Y
&& ArcEntity->Min_Y <= ViewEntity->parent->Max_Y
)) {F2dCleanUpChangeChildrenFlag( ViewEntity->par
ent );continue;}//check distance from arc to entit
yViewEntityLength = F2dCleanUpLineLength(ViewEntit
y->parent);DX = 0.5*(ViewEntity->parent->Min_X+Vie
wEntity->parent->Max_X) - ArcEntity->CenterX;DY =
0.5*(ViewEntity->parent->Min_Y+ViewEntity->parent-
>Max_Y) - ArcEntity->CenterY;DistanceViewEntity2Ce
nter = sqrt(DX*DX+DY*DY) - ArcEntity->Radius - 0.5
*ViewEntityLength;if( DistanceViewEntity2Center <=
ViewEntityLength ){F2dCleanUpChangeChildrenFlag(
ViewEntity->parent );continue;}//set center line f
lags ( look for children )for( temp_list4=ViewEnti
ty->parent->children; temp_list4;temp_list4 = tem
p_list4->cdr){//change flag to light grayif ( temp
_list4->car == NULL ) break;temp_list4->car->flags
= 10;count++;}if ( ViewEntity->next == NULL )brea
k;}}#ifdef VELLUMCountPrompt++;sprintf( message,"F
inished find center Entity %d", CountPrompt );ck_p
rompt( message ); #endif//normal endreturn coun
t;}/*=============================================
====================関数: 名称: F2dCleanUpFindIn
SideEntity記述:アウトサイドループに対するインサイ
ドエンティティを求める。戻り値:= 0:成功裏に完了
し、何も見出されない;= NUM: 開放エンティティの個数
副関数:intF2dCleanUpChangeChildrenFlag未使用エンテ
ィティに対するフラグを設定する。パラメータ:入力:
1 In_Drawing: a図2 In_Entities_list: 外側ループに
対するノードリスト================================
================================*/int F2dCleanUpFi
ndInSideEntity( struct drawing *In_drawing, struct
node_list *In_Entities_list ){//external function
sint F2dCleanUpChangeChildrenFlag();//link list an
d temp liststruct node_list *temp_list,*temp_list
2,*NewNodeList, *NewNodeListTemp; struct group *Ne
wGroup,*temp_group_list; struct bounding_box *New
BoundBox;//selected entity and temp entitiesstruct
node *OutsideEntity,*ViewEntity;//entities counte
r andflagsint count = 0,NoFlag = 0;//doubledoubleT
olerance = 0.0;//set toleranceTolerance = F2dClean
UpTolerance;//initializeNewGroup = (struct group*)
calloc(1,sizeof(struct group ));NewBoundBox = (str
uct bounding_box *)calloc(1,sizeof(struct bounding
_box ));NewNodeList = (struct node_list *)calloc
(1,sizeof(struct node_list ));//set group dataNewG
roup->next = NULL;NewGroup->box = NewBoundBox;// c
heck all of entities which connected with outside
loop for( temp_list=In_Entities_list; temp_lis
t; //&& temp_list->cdr; temp_list = temp_list->cd
r){if ( temp_list->car == NULL )break;OutsideEntit
y = temp_list->car;//check entity : only boundary
group ( flags = 1 and 4 ) if ( OutsideEntity->flag
s != 1 && OutsideEntity->flags != 4 )continue;if
( !OutsideEntity ){NoFlag = 1;break;}NewGroup->box
->Min_X = OutsideEntity->Min_X;NewGroup->box->Max_
X = OutsideEntity->Max_X;NewGroup->box->Min_Y = Ou
tsideEntity->Min_Y;NewGroup->box->Max_Y =OutsideEn
tity->Max_Y;break;}if ( NoFlag == 1 )return0; N
ewNodeList->car = OutsideEntity;NewNodeList->cdr =
NULL;// check first groupif( In_drawing->views ==
NULL ){NewGroup->index = 1;In_drawing->views = Ne
wGroup;}else{//check group number for( temp_gro
up_list= In_drawing->views;temp_group_list; //&& t
emp_group_list->next; temp_group_list = temp_grou
p_list->next){if ( temp_group_list->next == NULL )
{NewGroup->index = (temp_group_list->index)+1;temp
_group_list->next = NewGroup;break;}}} // check
connected entity if ( !temp_list->cdr && temp_
list->car->type!= CK_ARC )return 0; // check al
l of entities which connected with outside loop
if ( temp_list->cdr ){ for( temp_list2 = temp_
list->cdr; temp_list2;// && temp_list2->cdr; tem
p_list2 = temp_list2->cdr){if( temp_list2->car ==
NULL ) break;OutsideEntity = temp_list2->car;//che
ck entity : only boundary group ( flags = 1 and 4
) if ( OutsideEntity->flags != 1 && OutsideEntity
->flags != 4 )continue;if ( NewGroup->box->Min_X >
OutsideEntity->Min_X )NewGroup->box->Min_X = Outs
ideEntity->Min_X;if ( NewGroup->box->Max_X < Outsi
deEntity->Max_X )NewGroup->box->Max_X =OutsideEnti
ty->Max_X;if ( NewGroup->box->Min_Y > OutsideEntit
y->Min_Y )NewGroup->box->Min_Y = OutsideEntity->Mi
n_Y;if ( NewGroup->box->Max_Y < OutsideEntity->Max
_Y )NewGroup->box->Max_Y = OutsideEntity->Max_Y;//
allocate memory for node list NewNodeListTemp = (s
truct node_list *)calloc(1,sizeof(struct node_list
));//add this entity to node list NewNodeListTemp
->car = OutsideEntity;//connect to the node list N
ewNodeListTemp->cdr =NewNodeList;//move the pointe
r of the node list to the topNewNodeList =NewNodeL
istTemp;count++;}}//check all of entities in the v
iewfor( ViewEntity=In_drawing->objects; ViewEntit
y; ViewEntity = ViewEntity->next){//check flags:
only no marks entities if ( ViewEntity == NULL )b
reak;if( ViewEntity->flags !=0 )continue;//check
bounding box: only inside entities if (( NewGroup-
>box->Min_X <= ViewEntity->Min_X ) &&( NewGroup->
box->Max_X >= ViewEntity->Max_X ) &&( NewGroup->b
ox->Min_Y <= ViewEntity->Min_Y ) &&( NewGroup->bo
x->Max_Y >= ViewEntity->Max_Y )){//set flagViewEnt
ity->flags = 7;//allocate memory for node list New
NodeListTemp =(struct node_list *)calloc(1,sizeof
(struct node_list ));//add this entity to node lis
t NewNodeListTemp->car = ViewEntity;//connect to t
he node list NewNodeListTemp->cdr = NewNodeList;//
move the pointer of the node list to the topNewNod
eList = NewNodeListTemp;count++;}}//set node list
togroup NewGroup->entities = NewNodeList;//normal
endreturn count;}/*===============================
==================================関数: 名称: F2
dCleanUpFindOnesideOpenConnectEntityNext記述: 一
側オープンエンティティに接続された次のエンティティ
を求める。戻り値:= Out_entity: 成功裏に完了;パラ
メータ:入力: 1 In_entity: エンティティ =========
==================================================
=====*/struct node *F2dCleanUpFindOnesideOpenConne
ctEntityNext(struct node *In_entity){//selected en
tity and temp entitiesstruct node *Out_entity;//li
nk list and temp liststruct node_list *TempList1,
*TempList2, *TempList3, *NextNodes;//defineintFlag
1= 0,Flag2 = 0,Count = 0;int CountPrompt = 0;charm
essage[64];#ifdef VELLUMCountPrompt++;sprintf( mes
sage,"Start Find One Side Open Connected Entity %
d", CountPrompt );ck_prompt( message ); #endif//i
nitializeOut_entity = NULL;//check input entityif
( !In_entity )returnOut_entity;//checkopen sidefor
( TempList1=In_entity->connected_nodes_1; TempList
1; //&& TempList1->cdr; TempList1 = TempList1->cd
r){if ( TempList1->car == NULL )break;if ( TempLis
t1->car->flags == 6 )Flag1 = 1;}for( TempList2=In_
entity->connected_nodes_2; TempList2; //&& TempLis
t2->cdr; TempList2 = TempList2->cdr){if ( TempList
2->car == NULL )break;if ( TempList2->car->flags==
6 )Flag2 = 1;}//first entity caseif ( Flag1 == 0
&& Flag2 == 0 ) {if( In_entity->no_connected_1 ==
0 )Flag1 = 1;if ( In_entity->no_connected_2 == 0
)Flag2 = 1;}//finish case: returnif (( Flag1 == 0
&& Flag2 == 0) ||( Flag1 == 1 && Flag2 == 1 ))r
eturnOut_entity;//check all of entities connected
with input entityif ( Flag1 == 1 )NextNodes = In_e
ntity->connected_nodes_2;elseNextNodes = In_entity
->connected_nodes_1;for( TempList3= NextNodes; Tem
pList3; //&& TempList3->cdr; TempList3 = TempList
3->cdr){if ( TempList3->car == NULL )break;if ( Te
mpList3->car->flags ==0 ){Out_entity = TempList3->
car;Count++;}}//check resultif ( Count != 1)Out_en
tity = NULL;#ifdef VELLUMCountPrompt++;sprintf( me
ssage,"Finishedone side open connected Entity %d",
CountPrompt );ck_prompt( message );#endifreturnOu
t_entity;}/*======================================
===========================関数: 名称: F2dCleanU
pFindOnesideOpenConnectEntity記述: 一側オープンエ
ンティティおよびそれに接続された単一エンティティを
求める。。戻り値:= 0: 成功裏に完了;副関数:struct
node *F2dCleanUpFindOnesideOpenConnectEntityNext
一側開放エンティティに接続された次のエンティティを
求める。パラメータ:入力: 1 In_drawing: 図 ======
==================================================
========*/int F2dCleanUpFindOnesideOpenConnectEnti
ty(struct drawing *In_drawing){//external function
sstruct node *F2dCleanUpFindOnesideOpenConnectEnti
tyNext();//selected entity and temp entitiesstruct
node *entity, *FindEntity, *NextEntity;//check al
l ofentities on the listfor( entity=In_drawing->ob
jects; entity; entity =entity->next){if ( entity
== NULL )break; if ( entity->flags != 0 )continu
e; if ( entity->type != CK_LINE )continue; if ( en
tity->no_connected_1 > 0 && entity->no_connected_2
> 0 )continue;if ( entity->no_connected_1 == 0 &&
entity->no_connected_2 == 0 )continue;if ((entity
->no_connected_1 == 0 && entity->no_connected_2 >=
1) ||(entity->no_connected_2 == 0&& entity->no_c
onnected_1 >= 1)) {//set flagentity->flags =6;Find
Entity= entity;//find connected entityfor (;;){Nex
tEntity = F2dCleanUpFindOnesideOpenConnectEntityNe
xt( FindEntity );if ( NextEntity == NULL )break;//
set flagFindEntity = NextEntity;FindEntity->flags
=6;}}}return 0;}/*================================
=================================関数: 名称: F2d
CleanUpFindLongestEntity記述: 図に対して最も長い
エンティティを求める。戻り値:= Entity: 成功裏に
完了;= 0: エンティティ無し;パラメータ:入力: 1 I
n_drawing: 図 ====================================
============================*/struct node *F2dClea
nUpFindLongestEntity(struct drawing *In_drawing){/
/selected entity and temp entitiesstruct node *ent
ity, *LongestEntity;//definedoubleLongestLength =
0.0,ArcLength = 0.0;//check all of entities on the
listfor( entity=In_drawing->objects; entity;enti
ty = entity->next){//only not usedif ( entity == N
ULL )break;if (entity->flags != 0 )continue;//chec
k lengthif ( entity->parent->length <= LongestLeng
th )continue; //check arc lengthif ( entity->type
== CK_ARC ){ArcLength = 2.0 * entity->parent->Rad
ius;if ( entity->parent->length< ArcLength)ArcLeng
th = entity->parent->length;if ( ArcLength > Longe
stLength ){//change max value and entityLongestLen
gth = ArcLength;LongestEntity = entity;}}else{//ch
ange max value and entityLongestLength = entity->p
arent->length;LongestEntity = entity;}}if ( Longes
tLength == 0.0 )returnNULL;elsereturnLongestEntit
y;}/*=============================================
====================関数: 名称: F2dCleanUpFindVi
ews記述: 図に対するビユーのグループを求める。戻り
値:= Entity: 成功裏に完了;= 0:エンティティなし;
副関数:struct node *F2dCleanUpFindLongestEntity図
に対する最も長いエンティティを求める。struct node_
list *F2dCleanUpFindGroup入力エンティティと接続さ
れたグループエンティティを求める。struct node *F2d
CleanUpFindGroupMinXエンティティグループに対する最
小X値を求める。intF2dCleanUpFindOutSideLoopエンテ
ィティグループに対する最小X値を求める。int F2dCle
anUpFindInSideEntity外側ループパラメータに対するイ
ンサイドエンティティを求める。パラメータ:入力: 1
In_drawing: 図 ==================================
==============================*/int F2dCleanUpFind
Views(struct drawing *In_drawing ){//external func
tionsstruct node *F2dCleanUpFindLongestEntity();st
ruct node_list *F2dCleanUpFindGroup();struct node*
F2dCleanUpFindGroupMinX();int F2dCleanUpFindOutSid
eLoop();int F2dCleanUpFindInSideEntity();//selecte
d entity and temp entitiesstruct node *LongestEnti
ty, *MinXvalueEntity;struct node_list *ViewGroup;/
/defineint ReturnFlag = 1,NoGroup = 0,Count = 0;do
ubleLongestLength = 0.0;int CountPrompt = 0;charme
ssage[64];//check all viewswhile( ReturnFlag ){#if
def VELLUMCountPrompt++;sprintf( message,"Start Fi
nd Views Entity %d", CountPrompt );ck_prompt( mess
age ); #endif//Step_1:find a longest entity for a
drawingLongestEntity = F2dCleanUpFindLongestEntit
y( In_drawing );if ( LongestEntity == NULL )Return
Flag = 0;else {//set flagNoGroup = 1; //clearcoun
terCount = 0;//Step_2:find connected group with th
e longest entityViewGroup = F2dCleanUpFindGroup( L
ongestEntity, &Count ); //Step_3:find outside loop
entities//check a flag for outside loop processif
( Count >1 )MinXvalueEntity = F2dCleanUpFindGroup
MinX( ViewGroup );elseMinXvalueEntity = LongestEnt
ity;if ( MinXvalueEntity == 0 )continue;//Step_4:f
indoutside loop entitiesif ( Count > 1 )F2dCleanUp
FindOutSideLoop( MinXvalueEntity );elseMinXvalueEn
tity->flags = 4;//Step_5:find inside entitiesF2dCl
eanUpFindInSideEntity( In_drawing, ViewGroup );}#i
fdef VELLUMCountPrompt++;sprintf( message,"Finishe
d find view Entity %d", CountPrompt );ck_prompt( m
essage ); #endif}if ( NoGroup == 0 )return-1;else
return0;}/*=======================================
==========================関数: 名称: F2dCleanUp
FindRelativeViews記述: 相対ビユーを求める。 戻り
値:= 0:成功裏に完了;= 1: 相対ビユーが見出される。
パラメータ:入力: 1 In_Drawing: 図2 In_Group:グル
ープ3 In_ToleranceViews: ビユーに対する公差=======
==================================================
=======*/int F2dCleanUpFindRelativeViews( struct d
rawing*In_drawing,struct group*In_Group,double *In
_ToleranceViews ) {//link list and temp liststruct
group *TempGroup;struct group_list *TempGroupLis
t; //entities counter and flagsint ReturnFlag = 0;
//doubledoubleTolerance = 0.0;//set toleranceToler
ance = *In_ToleranceViews;//check viewsif( In_draw
ing->views == NULL )return0;if( In_Group == NULL )
return0;for( TempGroup= In_drawing->views; TempGr
oup; //&& TempGroup->next; TempGroup = TempGroup-
>next){//check same groupif( TempGroup == NULL )br
eak;if ( TempGroup == In_Group )continue;//Step_1:
check top and bottom directionif ((TempGroup->box-
>Max_X>=((In_Group->box->Max_X)-Tolerance )) &&
(TempGroup->box->Max_X<=((In_Group->box->Max_X)+To
lerance )) &&(TempGroup->box->Min_X>=((In_Group->
box->Min_X)-Tolerance )) &&(TempGroup->box->Min_
X<=((In_Group->box->Min_X)+Tolerance ))) {//set re
turn flagReturnFlag = 1;//Step_1_1:check top direc
tionif ( TempGroup->box->Min_Y > In_Group->box->Ma
x_Y ){//check top directionrelative viewsif ( In_G
roup->to_top == NULL ){TempGroupList = (struct gro
up_list *)calloc(1,sizeof(struct group_list ));Tem
pGroupList->car = TempGroup;TempGroupList->cdr = N
ULL;In_Group->to_top = TempGroupList;}else{//check
distanceif ( In_Group->to_top->car->box->Min_Y >
TempGroup->box->Min_Y ){//change top viewIn_Group-
>to_top->car = TempGroup;}}}else//Step_1_2:check b
ottom directionif ( TempGroup->box->Max_Y < In_Gro
up->box->Min_Y){//check top directionrelative view
sif ( In_Group->to_bottom == NULL ){TempGroupList
= (struct group_list *)calloc(1,sizeof(struct grou
p_list));TempGroupList->car = TempGroup;TempGroupL
ist->cdr = NULL;In_Group->to_bottom = TempGroupLis
t;}else{//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 ((Te
mpGroup->box->Max_Y>=((In_Group->box->Max_Y)-Toler
ance )) &&(TempGroup->box->Max_Y<=((In_Group->bo
x->Max_Y)+Tolerance )) &&(TempGroup->box->Min_Y>=
((In_Group->box->Min_Y)-Tolerance )) &&(TempGrou
p->box->Min_Y<=((In_Group->box->Min_Y)+Tolerance
))) {//set return flagReturnFlag= 1;//Step_2_1:ch
eck right directionif ( TempGroup->box->Min_X > In
_Group->box->Max_X ){//check right direction relat
ive viewsif ( In_Group->to_right == NULL ){TempGro
upList = (struct group_list *)calloc(1,sizeof(stru
ct group_list ));TempGroupList->car = TempGroup;Te
mpGroupList->cdr = NULL;In_Group->to_right = TempG
roupList;}else{//check distanceif ( In_Group->to_r
ight->car->box->Min_X > TempGroup->box->Min_X ){//
change 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 ReturnFla
g;}/*=============================================
====================関数: 名称: F2dCleanUpFindVi
ewsRelation記述: 図に対するビユー関係を求める。
戻り値:= 0: 成功裏に完了するが、何も見出されな
い。;= NUM: ビユーの個数副関数:int F2dCleanUpFind
RelativeViews相対ビユーを求める。パラメータ:入
力: 1 In_Drawing: a図============================
====================================*/int F2dClean
UpFindViewsRelation( struct drawing*In_drawing )
{//external functionsint F2dCleanUpFindRelativeVie
ws();//link list and temp liststruct group *MaxGro
up,*TempGroup,*NextGroup;struct group_list*OpenGro
upList,*TempOpenGroupList,*TempGroupList; struct n
ode_list *ETL;//Entity Temp List//entities counter
and flagsint NoFlag = 0;//doubledoubleBiggestSize
= 0.0, BiggestSizeTemp = 0.0;doubleTolerance = 0.
0,ToleranceViews = 0.0;//set toleranceTolerance =
F2dCleanUpTolerance;//check viewsif( In_drawing->v
iews == NULL )return0;//Step_1:get the biggest gro
up's sizefor( TempGroup= In_drawing->views; TempG
roup; //&& TempGroup->next; TempGroup = TempGroup
->next){// clear flagsTempGroup->index = 0;// comp
ute size for boxBiggestSizeTemp = fabs( TempGroup-
>box->Max_X - TempGroup->box->Min_X ) + fabs( Tem
pGroup->box->Max_Y - TempGroup->box->Min_Y );//che
ck sizeif ( BiggestSizeTemp > BiggestSize ){Bigges
tSize = BiggestSizeTemp;MaxGroup= TempGroup;}//che
ck last oneif ( TempGroup->next == NULL )break;}//
check views toleranceToleranceViews = 0.01 * Bigge
stSize;if ( ToleranceViews < Tolerance ) Tolerance
Views = Tolerance;//Step_2:find relationship for e
ach view//initialize a open list OpenGroupList =
(struct group_list *)calloc(1,sizeof(struct group_
list ));OpenGroupList->car = MaxGroup;OpenGroupLis
t->cdr = NULL;// set a open flag to the groupMaxGr
oup->index = 1;for ( TempGroupList = OpenGroupLis
t; TempGroupList; ){//get a pointer from open list
if ( TempGroupList->car == NULL )break;NextGroup
= TempGroupList->car;//set a closed flag to the gr
oupNextGroup->index = 2;//close the group( delete
the group from open list )OpenGroupList = OpenGrou
pList->cdr;//get relationNoFlag = F2dCleanUpFindRe
lativeViews( In_drawing, NextGroup,&ToleranceViews
);if ( NoFlag == 0 )break;//check each direction
for the viewif ( NextGroup->to_top != NULL ){if (
NextGroup->to_top->car->index == 0 ){TempOpenGroup
List = (struct group_list *)calloc(1,sizeof(struct
group_list ));TempOpenGroupList->car = NextGroup->
to_top->car;TempOpenGroupList->cdr = OpenGroupLis
t;TempOpenGroupList->car->index = 1;OpenGroupList
= TempOpenGroupList;}}if ( NextGroup->to_bottom !=
NULL ){if ( NextGroup->to_bottom->car->index == 0
){TempOpenGroupList = (struct group_list *)calloc
(1,sizeof(struct group_list ));TempOpenGroupList->
car = NextGroup->to_bottom->car;TempOpenGroupList-
>cdr = OpenGroupList;TempOpenGroupList->car->index
= 1;OpenGroupList = TempOpenGroupList;}}if ( Next
Group->to_left != NULL ){if ( NextGroup->to_left->
car->index == 0 ){TempOpenGroupList = (struct grou
p_list *)calloc(1,sizeof(struct group_list ));Temp
OpenGroupList->car = NextGroup->to_left->car;TempO
penGroupList->cdr =OpenGroupList;TempOpenGroupList
->car->index = 1;OpenGroupList = TempOpenGroupLis
t;}}if ( NextGroup->to_right != NULL ){if ( NextGr
oup->to_right->car->index == 0 ){TempOpenGroupList
= (struct group_list *)calloc(1,sizeof(struct gro
up_list ));TempOpenGroupList->car = NextGroup->to_
right->car;TempOpenGroupList->cdr = OpenGroupList;
TempOpenGroupList->car->index= 1;OpenGroupList = T
empOpenGroupList;}}//assign value to the loop vari
ableTempGroupList = OpenGroupList;}//Step_3:clear
flags for no relative groupsfor( NextGroup=In_draw
ing->views; NextGroup; NextGroup = NextGroup->nex
t){if ( NextGroup == NULL )break;if ( NextGroup->i
ndex != 0 )continue;for ( ETL=NextGroup->entities;
ETL; ETL=ETL->cdr ) {ETL->car->flags = 0;if ( ETL
->cdr == NULL )break;}}//normal endreturn 0;}/*==
==================================================
=============関数: 名称:F2dCleanUpFindDrawingShe
et記述: 図に対する描画シートを求める。戻り値:=-
1: エラーデータ;= 0: 成功裏に完了;= 1: シートな
し;副関数:struct node_list *F2dCleanUpFindGroup入
力エンティティと接続されたグループエンティティを求
める。パラメータ:入力: 1 In_drawing: 図 ========
==================================================
======*/int F2dCleanUpFindDrawingSheet(struct draw
ing *In_drawing,struct bounding_box *InOut_BB,int
*In_TimesFlag ){//external functionsstruct node_li
st *F2dCleanUpFindGroup();//selected entity and te
mp entitiesstruct node *entity, *LongestEntityX, *
LongestEntityY;struct node_list*SheetGroup, *temp_
list2; //bounding boxstruct bounding_box BB, EBB;/
/defineintSheetFlag = 0, count = 0,CountPrompt= 0;
doubleLongestLengthX = 0.0,LongestLengthY = 0.0,Al
phaX = 0.0, AlphaY = 0.0;charmessage[64]; doubleTo
lerance = 0.0;//set toleranceTolerance= F2dCleanUp
Tolerance;#ifdef VELLUMCountPrompt++;sprintf( mess
age,"StartFind Sheet Entity %d", CountPrompt );ck_
prompt( message ); #endif//STEP_1:look for the lo
ngest line type parent entity //check all of entit
ieson the listfor( entity=In_drawing->objects; en
tity; entity = entity->next){//only line typeif
( entity == NULL )break;if ( entity->type != CK_LI
NE )continue; //only not usedif ( entity->flags !=
0 )continue;//check lengthif (( entity->parent->l
ength <= LongestLengthX ) &&( entity->parent->len
gth <= LongestLengthY ))continue; //check horizon
tally and vertically //if angle(alpha) was smaller
than ( sin ( alpha ) = alpha )AlphaX = fabs( ( en
tity->parent->Max_X - entity->parent->Min_X )/ ent
ity->parent->length );AlphaY = fabs( ( entity->par
ent->Max_Y - entity->parent->Min_Y )/ entity->pare
nt->length );if ( ( AlphaX > Tolerance ) && ( Alph
aY > Tolerance ) )continue;//change max value and
entityif ( AlphaY < Tolerance ){ if ( entity->pare
nt->length > LongestLengthX ){ LongestLengthX = e
ntity->parent->length;LongestEntityX = entity;}}el
se{ if ( entity->parent->length > LongestLengthY )
{ LongestLengthY = entity->parent->length;Longest
EntityY = entity;}} #ifdef VELLUM//CountPrompt++;/
/sprintf( message,"Sheet Entity %d", CountPrompt
);//ck_prompt( message ); #endif}//check the lon
gest entitiy's lengthif (( LongestLengthX < Tolera
nce )||( LongestLengthY < Tolerance ))return-1;
//set boundingboxBB.Min_X = LongestEnt
ityX->parent->Min_X;BB.Max_X = LongestEntityX->par
ent->Max_X;BB.Min_Y = LongestEntityY->parent->Min_
Y;BB.Max_Y = LongestEntityY->parent->Max_Y;//check
inside drawing sheet sizeif ( *In_TimesFlag == 1)
*InOut_BB = BB; //set valueselse{if ( (InOut_BB->
Min_X == 0.0 ) && (InOut_BB->Max_X == 0.0 ) &&(InO
ut_BB->Min_Y == 0.0 ) && (InOut_BB->Max_Y == 0.0
)) return0;if (( BB.Max_X - BB.Min_X ) < Toleranc
e )return0;if ( fabs(( InOut_BB->Max_X - InOut_BB-
>Min_X ) / ( BB.Max_X - BB.Min_X )) > 1.2 )return
0;}//seta flag to entityLongestEntityX->flags = 3;
//STEP_2:look for connectedentities group and mak
e boundarySheetGroup = F2dCleanUpFindGroup( Longes
tEntityX, &count );if ( SheetGroup == 0 )return0;/
/STEP_3:clear flagsforall entitiesfor( entity=In_d
rawing->objects; entity; entity = entity->next)
{if ( entity == NULL )break;if ( entity->flags ==
3 )continue;if (entity->flags == 4 )continue;entit
y->flags = 0; }//STEP_4:set flags thegroupfor ( te
mp_list2 = SheetGroup; ( temp_list2!=0 && t
emp_list2->car!=0 ); temp_list2=temp_list2->c
dr){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.Max_X ) - (BB.Min_X ));EBB.Max_X = ( B
B.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.Max_Y ) - ( BB.Min_Y ));//STEP_6:che
ck outside entity( out of the bounding box ) in th
e DRAWING//ifany entity was found, no sheet was fo
und for this drawingfor( entity=In_drawing->object
s; entity; entity = entity->next){if ( entity ==
NULL)break; if ( entity->flags != 0 )continue;//l
ook for out side entity if( entity->Max_X > EBB.Ma
x_X ){ SheetFlag = 1;break;}if ( entity->Max_Y >EB
B.Max_Y ){ SheetFlag = 1;break;}if ( entity->Min_X
< EBB.Min_X ){ SheetFlag = 1;break;}if ( entity->
Min_Y < EBB.Min_Y ){ SheetFlag = 1;break;}}//STEP_
7:look for sheet data ( out side of the boundary )
if ( SheetFlag == 0 ){//look for sheet data for( e
ntity=In_drawing->objects; entity;entity = entity
->next){if ( entity == NULL )break; if ( entity->f
lags== 3 )entity->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 f
lagentity->flags =4;}//Goodreturn 0;}//STEP_8:clea
r flags ( No sheet was found ! )for( entity=In_dra
wing->objects; entity; entity = entity->next){if
( entity == NULL )break;if ( entity->flags == 4 )
continue; entity->flags = 0; }if ( SheetFlag != 0
)return 1;#ifdef VELLUMCountPrompt++;sprintf( mes
sage,"Finished find Sheet Entity %d", CountPrompt
);ck_prompt( message ); #endifreturn 0;}/*======
==================================================
=========関数: 名称: TestFindDrawingSheetControl
記述: 手動関数。図に対する描画シートを求める。戻
り値:< 0: エラー= 0: プロセスなし> 0: 成功裏に完
了;個数は見出されたエンティティのカウンタ値であ
る。パラメータ:副関数:int F2dCleanUpFindDrawingS
heet成功裏に完了;個数は見出されたエンティティのカ
ウンタ値である。intF2dCleanUpChangeDrawingFlagエン
ティティのフラグを変更する( 4 >> 3 )==============
==================================================
*/intTestFindDrawingSheetControl( int *SwitchRedra
w ){//external functionsint F2dCleanUpFindDrawingS
heet();int F2dCleanUpChangeDrawingColor();intF2dCl
eanUpChangeDrawingFlag();//definestruct bounding_b
ox BB;intReturnFlag = 0; intTimesFlag = 0;//------
----------------------------//Step_1:check thenumb
er of entites// if an error occurred, exit immidia
tely. if (number_of_entities<0) return -1;//--
-------------------------------//Step_2:find cente
r line entitiesTimesFlag = 1;ReturnFlag = F2dClean
UpFindDrawingSheet( &trim_drawing, &BB, &TimesFlag
);if( ReturnFlag == 1 ) return 0;if( ReturnFlag =
= -1 ) return 0;TimesFlag = 2;F2dCleanUpFindDrawin
gSheet( &trim_drawing, &BB, &TimesFlag );//-------
--------------------------//Step_3: change flagsF2
dCleanUpChangeDrawingFlag( &trim_drawing );//-----
----------------------------//Step_X:change color
to light gray for a selected center lines // tu
rn off input levels#ifdef CKWINif ( *SwitchRedraw
== 1)ck_levels(CK_OFF,1,255);#endifif ( *SwitchRed
raw == 1)F2dCleanUpChangeDrawingColor(&trim_drawin
g);// turn ON the level used to storethe trimmed e
ntities.#ifdef CKWINif ( *SwitchRedraw == 1)ck_lev
els(CK_ON,TrimLevel, TrimLevel);//if ( *SwitchRedr
aw == 1)ck_redraw( CK_PRIME_VP);#endifreturn 0;}/*
==================================================
===============関数: 名称: TestFindViewsControl
記述: 手動関数。 図に対する描画シートを求める。戻
り値:< 0: 図= 0: プロセスなし> 0: 成功裏に完了;
個数は見出されたエンティティのカウンタ値である。パ
ラメータ:副関数:int F2dCleanUpFindViews図に対す
るビューのグループを求める。int F2dCleanUpFindView
sRelation図に対するビュー関係を求める。int F2dClea
nUpChangeDrawingColor=============================
===================================*/intTestFindVi
ewsControl( int *SwitchRedraw ){//external functio
nsintF2dCleanUpFindViews();int F2dCleanUpFindViews
Relation();int F2dCleanUpChangeDrawingColor();//St
ep_1:check the number of entites// if an error occ
urred, exit immidiately. if (number_of_entities
<0) return -1;//Step_2: find views' group if ( F2
dCleanUpFindViews( &trim_drawing ) == -1) return
-1;//Step_3: find views' relationship //move to de
lete function( Mar. 29,1996 )//F2dCleanUpFindViews
Relation( &trim_drawing );//Step_X:change color to
light gray for a selected center lines // turn
off input levels#ifdef CKWINif ( *SwitchRedraw ==
1)ck_levels(CK_OFF,1,255);#endifif ( *SwitchRedra
w == 1)F2dCleanUpChangeDrawingColor(&trim_drawin
g);// turn ON the level used to store the trimmed
entities.#ifdef CKWINif( *SwitchRedraw == 1)ck_lev
els(CK_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw
== 1)ck_redraw( CK_PRIME_VP );#endifreturn 0;}/*=
==================================================
==============関数: 名称: TestFindBoundaryContro
l記述: 手動関数。 ユーザがビユーの境界のエンティ
ティを選択したとき、この関数はビユーに対する接続さ
れたエンティティの全てを見出す。戻り値:< 0: エラ
ー= 0: プロセスなし> 0: 成功裏に完了; 成功裏に完了
パラメータ:副関数:int F2dCleanUpFindOutSideLoop
サイドループのエンティティを求める。int F2dCleanUp
FindInSideEntity外側ループに対するサイドエンティテ
ィを求める。int F2dCleanUpFindOutNextEntity外側ル
ープエンティティと接続されたエンティティを求める。
struct node *F2dCleanUpFindGroupMinXエンティティグ
ループに対する最小X値を求める。struct node_list *
F2dCleanUpFindGroup入力エンティティと接続されたグ
ループエンティティを求める。ystruct node *F2dClean
UpInputEntity ( old function )画面上の選択されたエ
ンティティを求める。int F2dCleanUpLineAngleライン
形エンティティの角度を計算する。int F2dCleanUpArcA
ngleアーク形エンティティの角度を求める。int F2dCle
anUpChangeChildrenFlagエンティティのチルドレンフラ
グを変更する。int F2dCleanUpChangeArrowVertexFlag
アロートップ頂点のフラグを変更し、アローセンタライ
ン座標を設定する。int F2dCleanUpFindViewsRelationl
図に対するビユー関係を求める。int F2dCleanUpChange
Colorエンティティの色を変更する。 double F2dCleanU
pLineLengthライン形エンティティの長さを計算する。=
==================================================
=============*/intTestFindBoundaryControl( int *Sw
itchRedraw ){//external functionsint F2dCleanUpCha
ngeDrawingColor();int F2dCleanUpFindOutSideLoop();
int F2dCleanUpFindInSideEntity();int F2dCleanUpFin
dViewsRelation();struct node *F2dCleanUpInputEntit
y();struct node *F2dCleanUpFindGroupMinX();struct
node_list *F2dCleanUpFindGroup();//entities counte
r and flagsint count = 0;//link list and temp list
struct node_list *Entities_list; //selected entity
and temp entitiesstruct node *entity,*MinXvalueE
ntity;//Begin//----------------------------------/
/Step_1://check the number of entites// get count
of all entities// if an error occurred, exit immi
diately. if (number_of_entities<0) return -1;f
or( ; ; ){//---------------------------------//Ste
p_2:select one entityentity = F2dCleanUpInputEntit
y( "Select a Boundary Entity for a view",&trim_dra
wing);if ( entity ==0 )return0;if ( entity->flags
!= 0 )continue;//---------------------------------
//Step_3: find a connected entities groupEntities_
list = F2dCleanUpFindGroup( entity, &count );//---
------------------------------//Step_4:find outsid
e loop entities without assistant entities//check
a flagfor outside loop processif ( count < 1 )cont
inue;MinXvalueEntity = F2dCleanUpFindGroupMinX( En
tities_list);if ( MinXvalueEntity == 0 )continue;/
/---------------------------------//Step_5:find ou
tside loop entitiesF2dCleanUpFindOutSideLoop( MinX
valueEntity );//---------------------------------/
/Step_6:find inside entitiesF2dCleanUpFindInSideEn
tity( &trim_drawing, Entities_list );//-----------
----------------------//Step_7: find views' relati
onship //move delete function (Mar.29, 1996 By Ji
)//F2dCleanUpFindViewsRelation( &trim_drawing );/
/---------------------------------//Step_X:change
color to Magenta for a selected boundary // tur
n offinput levels#ifdef CKWINif ( *SwitchRedraw ==
1)ck_levels(CK_OFF,1,255);#endifF2dCleanUpChangeD
rawingColor(&trim_drawing);// turn ON the leveluse
d to store the trimmed entities.#ifdef CKWINif ( *
SwitchRedraw == 1)ck_levels(CK_ON,TrimLevel, TrimL
evel);if ( *SwitchRedraw == 1)ck_redraw(CK_PRIME_V
P );#endif}return count;}/*=======================
==========================================関数:
名称: TestFindCenterLineControl記述: 手動関数。
ビユー中の全てのアークに対するセンタラインを見出
す。戻り値:< 0: エラー= 0: プロセスなし> 0: 成功
理に完了; 成功理に完了パラメータ:副関数:struct n
ode_list *F2dCleanUpPickUpAllArcEntity選択された図
中の全てのアークエンティティを求める。int F2dClean
UpChangeDrawingColorエンティティの色を変更する。==
==================================================
============*/intTestFindCenterLineControl( int *S
witchRedraw ){//external functionsint F2dCleanUpFi
ndCenterLineEntity();int F2dCleanUpChangeDrawingCo
lor();struct node_list *F2dCleanUpPickUpAllArcEnti
ty();//linklist and temp liststruct node_list*Enti
ties_list; //Begin//------------------------------
----//Step_1:check the number of entites// if an e
rroroccurred, exit immidiately. if (number_of_e
ntities<0) return -1;//--------------------------
-------//Step_2: pickup all arc entitiesEntities_l
ist = F2dCleanUpPickUpAllArcEntity( &trim_drawing
); if (Entities_list == 0) return 0;//-------
--------------------------//Step_3: find center li
ne entitiesF2dCleanUpFindCenterLineEntity( &trim_d
rawing, Entities_list );//------------------------
---------//Step_X:change color to 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;}/*===================
==============================================関
数: 名称: TestFindOneSideOpenConnectControl 記
述: 手動関数。 一側オープン接続エンティティを見出
す。戻り値:< 0:エラー= 0: プロセスなし> 0: 成功裏
に完了; 数は見出されたエンティティのカウンタ値であ
る。パラメータ:副関数:int F2dCleanUpFindOnesideO
penConnectEntity一側開放接続エンティティを求める。
==================================================
==============*/intTestFindOneSideOpenConnectContr
ol(int *SwitchRedraw ){//external functionsint F2d
CleanUpFindOnesideOpenConnectEntity();int F2dClean
UpChangeDrawingColor();//-------------------------
---------//Step_1:check the number of entites// if
an error occurred,exit immidiately. if (number
_of_entities<0) return -1;//---------------------
------------//Step_2: find center line entitiesF2d
CleanUpFindOnesideOpenConnectEntity( &trim_drawing
);//---------------------------------//Step_X:cha
nge color to light gray for a selected center line
s // turn off input levels#ifdef CKWINif ( *Swi
tchRedraw == 1)ck_levels(CK_OFF,1,255);#endifif (
*SwitchRedraw == 1)F2dCleanUpChangeDrawingColor(&t
rim_drawing);// turn ON the level used to store th
e trimmed entities.#ifdef CKWINif ( *SwitchRedraw
== 1)ck_levels(CK_ON,TrimLevel, TrimLevel);if ( *S
witchRedraw == 1)ck_redraw( CK_PRIME_VP );#endifre
turn 0;}/*========================================
=========================関数: 名称:TestFindSame
ColorControl記述: 手動関数。同じ色のエンティティ
を見出す。戻り値:= 0: 成功裏に完了;数は見出され
たエンティティのカウンタ値である。パラメータ:副関
数:struct node *F2dCleanUpInputEntity ( old funct
ion)画面上の選択されたエンティティを求める。int F2
dCleanUpFindSameColorEntity選択されたエンティティ
により同じ色のエンティティを求める。int F2dCleanUp
ChangeDrawingColorエンティティの色を変更する。====
==================================================
==========*/intTestFindSameColorControl(){//extern
al functionsint F2dCleanUpChangeDrawingColor();int
F2dCleanUpFindSameColorEntity();struct node *F2dC
leanUpInputEntity();//selected entity and temp ent
itiesstruct node*entity;//Begin//-----------------
-----------------//Step_1://check the number of en
tites// if an error occurred,exit immidiately.
if (number_of_entities<0) return -1;for( ; ; ){//
---------------------------------//Step_2:select o
ne entityentity = F2dCleanUpInputEntity( "Select a
Unuse Color Entity",&trim_drawing);if ( entity ==
0 )return0;if ( entity->flags != 0 )continue;//--
-------------------------------//Step_3: find a co
nnected entities groupF2dCleanUpFindSameColorEntit
y( entity, &trim_drawing );//---------------------
------------//Step_X:change color to Magenta for a
selected boundary // turn offinput levels#ifde
f CKWIN ck_levels(CK_OFF,1,255);#endifF2dCleanU
pChangeDrawingColor(&trim_drawing);// turn ON the
level used to store the trimmed entities.#ifdef CK
WIN ck_levels(CK_ON,TrimLevel, TrimLevel);if( *
SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );#endif}
return 0;}/*======================================
===========================関数: 名称:TestFindSe
lectSingleControl記述: 手動関数。使用エンティティ
を見出す。戻り値:= 0: 成功裏に完了; パラメータ:
副関数:struct node *F2dCleanUpInputEntity ( 古い
関数 )画面上の選択されたエンティティを求める。====
==================================================
==========*/intTestFindSelectSingleControl(){//ext
ernal functionsstruct node *F2dCleanUpInputEntit
y();//selected entity and temp entitiesstruct node
*entity;//entity's specifitysCK_ENTATTattr;//speci
ficity of entities//Begin//-----------------------
-----------//Step_1:check the number of entites//
if an error occurred, exit immidiately. if (num
ber_of_entities<0) return -1;for( ; ; ){//-------
--------------------------//Step_2:select one enti
tyentity = F2dCleanUpInputEntity( "Select an Unuse
Entity", &trim_drawing);if ( entity== 0 )return0;
//---------------------------------//Step_3: chang
e flagif ( entity->flags == 7 ){entity->flags = 0;
attr.color = CK_BLUE;}elseif ( entity->flags
== 0 ){entity->flags = 7;attr.color = CK_YELL
OW;}elsereturn0;//--------------------------------
-//Step_X:changecolor to light gray for unuse enti
ty // turn off input levels// ck_levels(CK_O
FF,1,255);ck_setattr( entity->id, CK_COLOR, NULL,
&attr );//turn ON the level used to store the trim
med entities.// ck_levels(CK_ON,TrimLevel, Trim
Level);ck_redraw( CK_PRIME_VP );}return 0;}/*=====
==================================================
==========関数: 名称: TestUnselectSingleControl
記述: 手動関数。使用エンティティをクリアする。戻
り値:= 0: 成功裏に完了;パラメータ:副関数:struct
node *F2dCleanUpInputEntity ( old function )画面
上の選択されたエンティティを求める。==============
==================================================
*/intTestUnselectSingleControl(){//external functi
onsstruct node *F2dCleanUpInputEntity();//selected
entity and temp entitiesstruct node*entity;//enti
ty's specifitysCK_ENTATTattr;//specificity of enti
ties//Begin//----------------------------------//S
tep_1:check the number of entites// if an error oc
curred, exit immidiately. if (number_of_entitie
s<0) return -1;for( ; ;){//----------------------
-----------//Step_2:select one entityentity =F2dCl
eanUpInputEntity( "Select an Entity to release",&t
rim_drawing);if (entity == 0 )return0;//----------
-----------------------//Step_3: change flagif ( e
ntity->flags != 3&& entity->flags != 4 && entity->
flags != 10 ) continue;entity->flags = 0;//-------
--------------------------//Step_X:change color to
light gray for unuse entity // turn off input
levels ck_levels(CK_OFF,1,255);attr.color = ent
ity->color;ck_setattr( entity->id, CK_COLOR, NULL,
&attr );// turn ON the level used to store thetri
mmed entities. ck_levels(CK_ON,TrimLevel, TrimL
evel);ck_redraw( CK_PRIME_VP );}return 0;}/*======
==================================================
=========関数: 名称: TestClearKeepFlagsControl記
述: 手動関数。全ての選択されたエンティティを戻
す。戻り値:= 0: 成功裏に完了;パラメータ:副関数:
int F2dCleanUpClearDrawingKeepFlagsエンティティの
色を元に変更するが、フラグは維持する。============
==================================================
==*/intTestClearKeepFlagsControl( int *SwitchRedra
w ){//external functionsint F2dCleanUpClearDrawing
KeepFlags();//Begin//-----------------------------
-----//check the number of entites// if an erroroc
curred, exit immidiately. if (number_of_entitie
s<0) return -1;//--------------------------------
- // turn off input levels#ifdef CKWINif ( *Swi
tchRedraw == 1)ck_levels(CK_OFF,1,255);#endifF2dCl
eanUpClearDrawingKeepFlags(&trim_drawing);if ( *Sw
itchRedraw == 1)ck_redraw( CK_PRIME_VP );// turn O
N the levelused to store the trimmed entities.#ifd
ef CKWINif ( *SwitchRedraw == 1)ck_levels(CK_ON,Tr
imLevel, TrimLevel);if ( *SwitchRedraw == 1)ck_red
raw(CK_PRIME_VP );#endifreturn0;}/*===============
==================================================
関数: 名称: TestClearControl記述: 手動関数。全
ての選択されたエンティティを元に戻す。戻り値:= 0:
成功裏に完了;パラメータ:副関数:int F2dCleanUpCl
earDrawingEntityエンティティの色を元に戻す。======
==================================================
========*/intTestClearControl( int *SwitchRedraw )
{//external functionsint F2dCleanUpClearDrawingEnt
ity();//Begin//----------------------------------/
/check the number of entites// if an error occurre
d, exit immidiately. if (number_of_entities<0)
return -1;//---------------------------------
//turn off input levels#ifdef CKWINif ( *SwitchRed
raw == 1)ck_levels(CK_OFF,1,255);#endifF2dCleanUpC
learDrawingEntity(&trim_drawing);// turn ON the le
vel used to store the trimmed entities.#ifdef CKWI
Nif ( *SwitchRedraw == 1)ck_levels(CK_ON,TrimLeve
l, TrimLevel);if ( *SwitchRedraw == 1)ck_redraw( C
K_PRIME_VP );#endifreturn0;}/*====================
=============================================関
数: 名称: TestDeleteControl記述:手動関数。全て
の選択されたエンティティを削除する。戻り値:= 0: C
ompletedsuccessfully;パラメータ:副関数:int F2dCl
eanUpDeleteDrawingEntity全てエンティティを削除す
る。==============================================
==================*/intTestDeleteControl( int *Swi
tchRedraw ){//external functionsint F2dCleanUpDele
teDrawingEntity();//Begin//-----------------------
-----------//check the number of entites// if an e
rror occurred, exit immidiately. if (number_of_
entities<0) return -1; //Step_7:find views'
relationship //move from find boundary function
(Mar.29, 1996 By Ji )F2dCleanUpFindViewsRelation(
&trim_drawing );//--------------------------------
-#ifdef CKWIN
if( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);
#endif// turn ON the levelused to store the trimme
d entities.F2dCleanUpDeleteDrawingEntity(&trim_dra
wing);#ifdef VELLUMif ( *SwitchRedraw == 1)F2dClea
nUpChangeDrawingColor(&trim_drawing);#endif#ifdef
CKWINif ( *SwitchRedraw == 1)ck_levels(CK_ON,TrimL
evel, TrimLevel);if ( *SwitchRedraw == 1)ck_redraw
( CK_PRIME_VP);#endifreturn0;}/*==================
===============================================関
数: 名称: TestBackColorControl記述: 元に戻す。
戻り値:=0: 成功裏に完了;パラメータ:副関数:int F
2dCleanUpUndo元に戻す。===========================
=====================================*/intTestBack
ColorControl(int *SwitchRedraw ){//external functi
onsint F2dCleanUpChangeDrawingColor();if ( *Switch
Redraw == 1)F2dCleanUpChangeDrawingColor(&trim_dra
wing);return0;}/*=================================
================================関数: 名称: Test
UndoControl記述: 元に戻す。戻り値:= 0: 成功裏に
完了;パラメータ:副関数:int F2dCleanUpUndo元に戻
す。==============================================
==================*/intTestUndoControl( int *Switc
hRedraw ){//external functionsint F2dCleanUpUnd
o();//check the numberof entites : if an error oc
curred, exit immidiately. if (number_of_entitie
s<0) return -1;//Step_1: get flags if ( F2dCleanU
pUndo( &trim_drawing ) == 0 ) return 0;#ifdef CKWI
Nif ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#
endif// turn ON thelevel used to store the trimmed
entities.#ifdef VELLUMif ( *SwitchRedraw == 1)F2d
CleanUpChangeDrawingColor(&trim_drawing);#endif#if
def CKWINif( *SwitchRedraw == 1)ck_levels(CK_ON,Tr
imLevel, TrimLevel);if ( *SwitchRedraw == 1)ck_red
raw( CK_PRIME_VP );#endifreturn0;}/*==============
==================================================
=関数: 名称: TestUndoPreControl記述: 元に戻す準
備をする。戻り値:= 0: 成功裏に完了; パラメータ:
副関数:int F2dCleanUpUndoPre元に戻す準備をする。=
==================================================
=============*/intTestUndoPreControl( int *SwitchR
edraw ){//external functionsint F2dCleanUpUndoPr
e();//check the number of entites: if an error occ
urred, exit immidiately. if (number_of_entities
<0) return -1;//Step_1: get flags F2dCleanUpUndoP
re( &trim_drawing );return0;}/*===================
==============================================関
数: 名称: TestSetUndoFlagViewsControl記述: 元に
戻すためフラグを設定する。flag=0:ビューが存在しな
い。flag=1: ビューが存在する。戻り値:= 0: 成功裏
に完了; パラメータ:==============================
==================================*/intTestSetUndo
FlagViewsControl( int *SwitchRedraw ){ //set fl
ag F2dCleanUpExcutedNo = 1; return0;}/*関
数: =============================================
===================名称: TestDeleteViewsControl記
述: ビユーを削除する。戻り値:= 0: 成功裏に完了;
パラメータ:副関数:int F2dCleanUpDeleteViewsビユ
ーを削除する。====================================
============================*/intTestDeleteViewsCo
ntrol( int *SwitchRedraw ){//external functionsint
F2dCleanUpDeleteViews();//check the number of ent
ites: if an error occurred, exit immidiately. i
f (number_of_entities<0) return -1;//delete views
F2dCleanUpDeleteViews( &trim_drawing );return0;}s
truct node *F2dCleanUpInputEntity(char *prompt, s
truct drawing *select_drawing){int etype, count, s
tat;unsigned long entid;struct node *entity;//CK_
ENTATT attr;if (( ck_getent(prompt, &etype, &enti
d) != CK_NOERROR) || ( stat == CK_BACKUP )|| ( sta
t == CK_ESCAPE )) return 0;#ifdef DEBUGprint("ID:
%ld; #",entid);#endifcount=0; for (entity=selec
t_drawing->objects; entity&& (count<numbe
r_trimmed_entities) && (entity->id !=entid) && (en
tity->highlighted_id !=entid); entity=ent
ity->next) count++; if (count>=numb
er_trimmed_entities) return 0;else return entity;}
/*================================================
=================関数: 名称: F2dVector記述: ラ
インのユニットベクトルを計算する。戻り値:= Out_v:
成功裏に完了;パラメータ:入力: 1 In_sp: ラインエ
ンティティ開始点座標2 In_ep: インエンティティ終了
点座標出力:1 Out_v: ラインエンティティベクトル===
==================================================
===========*/struct Vector F2dVector( struct Vecto
rIn_sp, struct Vector In_ep ){struct VectorOut_v;O
ut_v.x = In_ep.x - In_sp.x;Out_v.y = In_ep.y - In_
sp.y;Out_v.z = In_ep.z - In_sp.z;returnOut_v;}/*==
==================================================
=============関数: 名称: F2dVectorUnit記述: ラ
インのユニットベクトルを計算する。戻り値:= Out_n:
成功裏に完了;< 0: エラーパラメータ:入力: 1 In_
v: ラインエンティティベクトル 出力:1 Out_n: ライ
ンエンティティユニットベクトル====================
=============================================*/str
uct VectorF2dVectorUnit(struct VectorIn_v){struct
VectorOut_n;doubleLength = 0.0;//tolerancedoubleto
lerance = 0.0;tolerance = F2dCleanUpTolerance;Leng
th= sqrt( In_v.x*In_v.x + In_v.y*In_v.y + In_v.z*I
n_v.z );//check lengthif ( Length < tolerance )ret
urnOut_n;Out_n.x = In_v.x / Length;Out_n.y =In_v.y
/ Length;Out_n.z = In_v.z / Length;returnOut_n;}/
*=================================================
================関数: 名称: F2dDistancePointLine
記述: 点からラインまでの距離を計算する。戻り値:=
0: 成功裏に完了;パラメータ:入力: 1 In_sp: ライ
ンエンティティ開始点座標2 In_ep:ラインエンティティ
終了点座標3 In_p: 点座標出力:1 Out_d: 距離 =====
==================================================
=========*/doubleF2dDistancePointLine(//inputstruc
t Vector In_sp, struct Vector In_ep, struct Vector
In_p ){//external functionsstruct Vector F2dVecto
r();struct Vector F2dVectorUnit();//definestruct V
ectorVe, Vne, Vp;double Out_d=0.0;//get vectorVe =
F2dVector( In_sp, In_ep );Vp = F2dVector( In_sp,
In_p );//get unit vectorVne = F2dVectorUnit( 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メンバ
関数の実施およびメニュー駆動関数の実施を含む。
【0360】//#include "stdafx.h"// include all BM
API files#include "ALLBMAPI.HXX"//RW_DRAW library
include file.#include "RW_DRAW.HXX"#include "BendC
AD.h"#include "BendCADDoc.h"#include "BendCADViewP
art.h"// RenderWare includefiles; found in \rwwin\
include#include "rwlib.h"// OpenGL include files.#
include "gl\gl.h"#include "gl\glu.h"// GL_LIST lib
rary include file.#include "GL_LIST.HXX"#include <
stdlib.h> // Orthoview dialog include file#inclu
de "OrthoViewDlg.h"///////////////////////////////
//////////////////////////////////////////////#def
ine WINDOWTITLE "BAJA CAD SYSTEM"static void multi
ply_pt_by_matrix(BM_POINT *point, float rot_matrix
[4][4]);static RwClump * RWCALLBACK do_transformat
ions(RwClump *clump, void *matrix);static RwClump
* RWCALLBACK clear_scene(RwClump *clump);static Rw
Polygon3d * RWCALLBACK SetPolygonColor(RwPolygon3d
*polygon, void *color);// The following variables
are defined to set up the color palette of the sc
reen.unsigned char threeto8[8] = {0, 0111>>1, 0222
>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377};uns
igned char twoto8[4] = {0, 0x55, 0xaa, 0xff};unsig
ned char oneto8[2] = {0, 255};static int defaultOv
erride[13] ={0, 3, 24, 27, 64, 67, 88, 173, 181, 2
36, 247, 164, 91};static PALETTEENTRY defaultPalEn
try[20] = {{ 0, 0, 0, 0 },{ 0x80,0, 0,
0 },{ 0, 0x80,0, 0 },{ 0x80,0x80,0, 0 },
{ 0, 0, 0x80, 0 },{ 0x80,0, 0x80, 0 },{ 0,
0x80,0x80, 0 },{ 0xC0,0xC0,0xC0, 0 },{ 192, 220,1
92, 0 },{ 166, 202, 240, 0 },{ 255, 251, 240, 0
},{ 160, 160, 164,0 },{ 0x80,0x80,0x80, 0 },{ 0xF
F,0, 0, 0 },{ 0, 0xFF,0, 0 },{0xFF,0xFF,
0, 0 },{ 0, 0, 0xFF, 0 },{ 0xFF,0, 0xFF,
0 },{ 0, 0xFF,0xFF, 0 },{ 0xFF,0xFF,0xFF, 0 }};v
oid PrintString(char *s){}// Thisfunction initiali
zes the RenderWare library, creates a scene, camer
a andlight.int CBendCADViewPart::Init3D(HWND windo
w) {BOOL berr = FALSE;// Open the RenderWare libra
ry. if (!RwOpen("MSWindows", NULL)) {::Messa
geBox(window, "Could not open th
e RenderWarelibrary", WINDOWTITL
E, MB_OK | MB_ICONSTOP | MB_APPLMODAL); ret
urn 0; }// Create a camera.RwInt32 x_size, y_si
ze; 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) { ::Me
ssageBox(window, "Could not create camera",
WINDOWTITLE, MB_OK | MB_ICONSTOP | MB
_APPLMODAL);return 0;}else { RwSetCameraProjectio
n(m_camera, rwPARALLEL); RwWCMoveCamera(m_camer
a, 0.0f, 0.0f, 10000.0f); // Move camera far away
from xy plane. RwSetCameraViewport(m_camera, 0,
0, x_size, y_size); // Default sizes of viewing vo
lume RwSetCameraViewwindow(m_camera, (float)
(x_size), (float)(y_size)); // and viewport.}// Cr
eate a scene. m_scene = RwCreateScene(); if
(m_scene == NULL) { RwDestroyCamera(m_ca
mera); m_camera = NULL; RwClose();
::MessageBox(window, "Could not create the 3
D Scene", WINDOWTITLE, MB_OK | M
B_ICONSTOP | MB_APPLMODAL); return 0; }/
/ Createlights.m_lights.RemoveAll();RwLight* light
1 = RwCreateLight(rwDIRECTIONAL, 0.7f, -0.7f, -0.7
f, 0.8f); //- good cornerRwLight* light2 = RwCreat
eLight(rwDIRECTIONAL, -1.0f, 1.0f, -1.0f, 0.25f);R
wLight* light3 = RwCreateLight(rwPOINT, CREAL(0.
0), CREAL(0.0), CREAL(0.0), CREAL(1.0));if(light1)
{m_lights.Add(light1);RwAddLightToScene(m_scene,
light1);}elseberr =TRUE;if(light2) {m_lights.Add
(light2);RwAddLightToScene(m_scene, light2);}elseb
err = TRUE;if(light3) {m_lights.Add(light3);RwAdd
LightToScene(m_scene, light3);}elseberr = TRUE;if
(berr) AfxMessageBox("Could not create light sourc
e");//RwSetLightState(m_light, rwON);//RwSetLightC
olor(m_light, CREAL(1.0), CREAL(1.0), CREAL(1.0));
return 1;}// This function isused by the document
class to initialize certain // parameters whenever
a new part is loaded. What we do here is compute t
he centroid,// prepare RenderWare clumps and show
the part as requested - wireframe/shaded ifshow_so
lid is 0/1,// flat/3d version of part if show_3d i
s 0/1.void CBendCADViewPart::new_part_init(int sho
w_solid, int show_3d){ int i; BM_PART *part = NU
LL; CBendCADDoc* pDoc = GetDocument(); ASSERT_VA
LID(pDoc); part = pDoc->get_part(); if(! part)
{ mi_part_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 p
art centroids. compute_part_centroid(part, 1, &m_
3d_part_centroid); m_part_centroid = m_3d_part_c
entroid; mi_show_3d = show_3d; mi_s
how_solid = show_solid; // Clear out an
y RenderWare clumps around. if(m_flat_base_clump)
{ RwRemoveClumpFromScene(m_flat_base_clump);
RwDestroyClump(m_flat_base_clump); m_flat_bas
e_clump = NULL; } if(m_3d_base_clump) {
RwRemoveClumpFromScen
e(m_3d_base_clump); Rw
DestroyClump(m_3d_base_cl
ump); m_3d_base_clump
= NULL; } m_base_clump
= NULL;if(mi_show_3d) {
// Prepare 3d solid or
3d wireframe. m_part_
centroid = m_3d_part_cent
roid; if(! mi_show_soli
d) { // Prepare wirefra
me. i = prepare_dis
play_list(part, mi_show_3
d, 1, 0, 1, 1, md_face_co
lor, md_bendline_color);
if(! i) { mi_
display_list_is_up_to_dat
e = 0; return;
} mi_display_list_i
s_up_to_date = 1;mi_3d_is
_up_to_date = 1; mi_fl
at_is_up_to_date = 0; }
else {// Prepare solid.
i = facet_part_rw(pa
rt, &m_3d_base_clump, mi_
show_3d, md_part_color);
if( (! i) || (! m_3d_b
ase_clump) ) return;m_bas
e_clump = m_3d_base_clum
p; RwAddClumpToScene(m
_scene, m_base_clump);
mi_display_list_is_up_
to_date = 0; mi_3d_i
s_up_to_date = 0; mi_f
lat_is_up_to_date = 0; }
} else {
// Prepare flat solid or
flat wireframe. m_par
t_centroid = m_flat_part_
centroid; if(! mi_show_
solid) { // Prepare wir
eframe. i = prepare
_display_list(part, mi_sh
ow_3d, 1, 0, 1, 1, md_fac
e_color, md_bendline_colo
r); if(! i) {
mi_display_list_is_up_to
_date = 0; return;
} mi_display_lis
t_is_up_to_date = 1;
mi_flat_is_up_to_date =
1; mi_3d_is_up_to_da
te = 0; } else {
// Prepare solid.
i = facet_part_rw(part, &
m_flat_base_clump, mi_sho
w_3d, md_part_color);
if( (! i) || (! m_flat_ba
se_clump) ) return; m_
base_clump = m_flat_base_
clump; RwAddClumpToSce
ne(m_scene, m_base_clum
p);mi_display_list_is_up_
to_date = 0; mi_3d_i
s_up_to_date = 0; mi_f
lat_is_up_to_date = 0; }
} mi_bbox_is_up_t
o_date = 0; ml_num_faces
= part−>get_number_of_fa
ces(); ml_num_bendlines
= part−>get_number_of_ben
dlines(); ml_num_forming
s = part−>get_number_of_f
ormings(); clear_selecti
on_set(); reset_selectio
n_buffer(); OnViewIsomet
ric();}// This function d
estroys all parent clumps
in the scene, and hence
all clumps in the scene./
/ It always returns NULL.
static RwClump * RWCALLBA
CK clear_scene(RwClump *c
lump){ int i = RwGetClum
pNumChildren(clump); if
(i)RwDestroyClump(clump);
return NULL;} // T
his allows other classest
o signal that the part ha
s changed, and hence// cu
rrent clumps/displaylists
are no longer valid. We
recompute centroids, prep
are new clumps//or displa
y lists, and show the par
t in its current orientat
ion and zoom.void CBendCA
DViewPart::invalidate_dis
play(void) { int i; BM_
PART *part= NULL; CBendC
ADDoc* pDoc = GetDocument
(); ASSERT_VALID(pDoc);
part= pDoc−>get_part();
if(! part) { mi_part_
is_up_to_date = 0; retur
n;} mi_part_is_up_to_dat
e = 1; compute_part_cent
roid(part, 0, &m_flat_par
t_centroid); // Compute 3
d and flat part centroid
s. compute_part_centroid
(part, 1, &m_3d_part_cent
roid); mi_3d_is_up_to_d
ate = 0; mi_flat_is_up_
to_date = 0; // Clear ou
t any RenderWare clumps a
round. if(m_flat_base_cl
ump) { RwRemoveClumpFr
omScene(m_flat_base_clum
p); RwDestroyClump(m_f
lat_base_clump); m_fla
t_base_clump = NULL; }
if(m_3d_base_clump) {
RwRemoveClumpFromScene(m_
3d_base_clump); RwDest
royClump(m_3d_base_clum
p); m_3d_base_clump =
NULL; } m_base_clump =
NULL;if(mi_show_3d) {
// Prepare 3d solid or 3
d wireframe. m_part_ce
ntroid = m_3d_part_centro
id; if(! mi_show_solid)
{ // Prepare wireframe.
i = prepare_displa
y_list(part, mi_show_3d,
1, 0, 1, 1, md_face_colo
r, md_bendline_color);
if(! i) { mi_di
splay_list_is_up_to_date
= 0; return; }
mi_display_list_is_u
p_to_date = 1;mi_3d_is_up
_to_date = 1; mi_flat_
is_up_to_date = 0; } el
se {// Prepare solid.
i = facet_part_rw(part,
&m_3d_base_clump,mi_show
_3d, md_part_color); i
f( (! i) || (! m_3d_base_
clump) ) return; m_bas
e_clump = m_3d_base_clum
p; RwAddClumpToScene(m
_scene, m_base_clump); }
} else {
// Prepare flat solid or
flat wireframe. m_par
t_centroid = m_flat_part_
centroid; if(! mi_show_
solid){ // Prepare wire
frame. i = prepare_
display_list(part, mi_sho
w_3d, 1, 0, 1, 1, md_face
_color, md_bendline_colo
r); if(! i) {mi_disp
lay_list_is_up_to_date =
0; return; }
mi_display_list_is_up_
to_date = 1; mi_flat
_is_up_to_date = 1;
mi_3d_is_up_to_date = 0;
} else { // Pre
pare solid. i = face
t_part_rw(part, &m_flat_b
ase_clump, mi_show_3d, md
_part_color); if( (!
i) ||(! m_flat_base_clum
p) ) return; m_base_cl
ump = m_flat_base_clump;R
wAddClumpToScene(m_scene,
m_base_clump); } } mi
_bbox_is_up_to_date =0;
ml_num_faces = part−>get_
number_of_faces(); ml_nu
m_bendlines = part−>get_n
umber_of_bendlines(); ml
_num_formings = part−>get
_number_of_formings(); c
lear_selection_set(); re
set_selection_buffer();
ml_last_function_chosen =
RETURN_FROM_DIALOG_MODE;
DrawPart(m_hdc); ml_la
st_function_chosen = NO_F
UNCTION_MODE;}void CBendC
ADViewPart::OnShowFlat()
{ if(! mi_show_3d) retur
n; // Flat is already be
ing shown. int i; BM_
PART *part = NULL; CBend
CADDoc* pDoc = GetDocumen
t(); ASSERT_VALID(pDoc);
part = pDoc−>get_par
t(); if(! part) { mi_
part_is_up_to_date = 0;re
turn; } // Store the cu
rrent 3d view parameters.
md_old_x_trans =md_x_tr
ans; md_old_y_trans = md
_y_trans; for(i=0; i <
3; ++i) { md_old_part_
bbox_size[i] = md_part_bb
ox_size[i]; md_old_view_
vol[i] = md_current_view_
vol[i]; } if(md_old_rot
_matrix) RwDestroyMatrix
(md_old_rot_matrix); md_
old_rot_matrix = RwDuplic
ateMatrix(md_rot_matrix);
mi_show_3d = 0; m_part
_centroid = m_flat_part_c
entroid; if(! mi_show_s
olid){// Compute the fla
t’s display list. if
(! mi_flat_is_up_to_date)
{i = prepare_display_li
st(part, mi_show_3d, 1,
0, 1, 1, md_face_color, m
d_bendline_color); i
f(! i) { mi_displa
y_list_is_up_to_date = 0;
return; } }
mi_display_list_is_up
_to_date = 1;mi_flat_is_u
p_to_date = 1; mi_3d_is_
up_to_date = 0; } else
{// Compute flat’s clump
if not already done. i
f(m_3d_base_clump) RwRemo
veClumpFromScene(m_3d_bas
e_clump); m_base_clump =
NULL; if(! m_flat_base
_clump) { i = facet_
part_rw(part, &m_flat_bas
e_clump, mi_show_3d, md_p
art_color); if( (!
i) || (! m_flat_base_clum
p) ) { mi_display_
list_is_up_to_date = 0;
return; } }
m_base_clump = m_flat_ba
se_clump;// Set the base
clump to be the flat’s ba
se clump. RwAddClumpTo
Scene(m_scene, m_base_clu
mp); } mi_bbox_is_up_to
_date = 0; OnViewTop();
}// Here we show the 3d
version, in its old orien
tation andzoom (before fl
at was// asked to be show
n).void CBendCADViewPar
t::OnShow3d() { if(mi_sh
ow_3d) return; // 3D v
iew is already being show
n.int i; BM_PART *part =
NULL; CBendCADDoc* pDoc
= GetDocument(); ASSERT
_VALID(pDoc); part = pDo
c−>get_part(); if(! par
t) { mi_part_is_up_to_
date = 0; return; } //
Restore the old 3d view
parameters. md_x_trans =
md_old_x_trans; md_y_tr
ans = md_old_y_trans; fo
r(i=0; i < 3; ++i) { m
d_part_bbox_size[i] = md_
old_part_bbox_size[i]; m
d_current_view_vol[i] = m
d_old_view_vol[i]; } if
(md_rot_matrix) RwDestroy
Matrix(md_rot_matrix); m
d_rot_matrix = RwDuplicat
eMatrix(md_old_rot_matri
x); mi_show_3d = 1; m_p
art_centroid = m_3d_part_
centroid; if(! mi_show_s
olid){ if(! mi_3d_is_u
p_to_date) { i = pr
epare_display_list(part,
mi_show_3d, 1, 0, 1, 1, m
d_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 {// Comp
ute the 3d_version’s clum
ps ifhave not already don
e so. if(m_flat_base_c
lump) RwRemoveClumpFromSc
ene(m_flat_base_clump);
m_base_clump = NULL; i
f(! m_3d_base_clump) {i =
facet_part_rw(part, &m_3
d_base_clump, mi_show_3d,
md_part_color); if
( (! i) || (! m_3d_base_c
lump) ) { mi_displ
ay_list_is_up_to_date =
0; return; }
} m_base_clump = m_3d
_base_clump;// Set the ba
se clump to be the 3d ver
sion’s base clump. RwA
ddClumpToScene(m_scene, m
_base_clump); } mi_bbox
_is_up_to_date = 0; md_c
urrent_view_vol[1] = md_c
urrent_view_vol[0]/md_asp
ect; RwSetCameraViewwin
dow(m_camera, (float)(md_
current_view_vol[0]), (fl
oat)(md_current_view_vol
[1])); glMatrixMode(GL_
PROJECTION); glLoadIdent
ity(); glOrtho(− md_curr
ent_view_vol[0],md_curren
t_view_vol[0],− md_curren
t_view_vol[1], md_current
_view_vol[1],//− 50000.0,
50000.0); − md_
current_view_vol[2], md_c
urrent_view_vol[2]); glM
atrixMode(GL_MODELVIEW);
DrawPart(m_hdc); }void
CBendCADViewPart::OnHide3
d() { OnShowFlat();// Fo
r now, just switch to sho
wing flat.}void CBendCADV
iewPart::OnHideFlat() {
OnShow3d();// For now, ju
st switch to showing 3D.}
void CBendCADViewPart::On
ViewWireframe() { if(! m
i_show_solid) return;
// Wireframe already bein
g shown. int i; CreateR
GBPalette(m_hdc);// when
wireframe −− recreatethe
palette −− AK HGLRC hrc
= wglGetCurrentContext();
// The renderingcontext
of OpenGL. wglMakeCurren
t(NULL, NULL); wglMakeCu
rrent(m_hdc, hrc);
// Associate the renderi
ng context with this vie
w. BM_PART*part = NULL;
CBendCADDoc* pDoc = GetD
ocument(); ASSERT_VALID
(pDoc);part = pDoc−>get_p
art(); if(! part) { m
i_part_is_up_to_date = 0;
return; } mi_show_sol
id = 0; if(mi_show_3d)
{ if(! mi_3d_is_up_to_
date) { i = prepare
_display_list(part, mi_sh
ow_3d, 1, 0, 1, 1, md_fac
e_color, md_bendline_colo
r); if(! i) {
mi_display_list_is_up_to
_date = 0; return;
} mi_display_lis
t_is_up_to_date =1; mi
_3d_is_up_to_date = 1;
mi_flat_is_up_to_date =
0; } } else { if
(! mi_flat_is_up_to_date)
{ i = prepare_disp
lay_list(part, mi_show_3
d, 1, 0, 1, 1, md_face_co
lor, md_bendline_color);
if(!i) { mi_d
isplay_list_is_up_to_date
= 0; return; }
mi_display_list_is_up_to_
date = 1; mi_3d_is_up_
to_date = 0; mi_flat_i
s_up_to_date = 1; } }
ml_last_function_chosen
= WIREFRAME_MODE;DrawPar
t(m_hdc); ml_last_functi
on_chosen = NO_FUNCTION_M
ODE; }voidCBendCADView
Part::OnViewShaded() { i
f(mi_show_solid) return;
//Solid already be
ing shown. int i; BM_PA
RT *part = NULL; CBendCA
DDoc*pDoc = GetDocumen
t(); ASSERT_VALID(pDoc);
part = pDoc−>get_par
t(); if(! part) { mi_
part_is_up_to_date = 0;
return; } mi_show_solid
= 1;if(mi_show_3d) {
if(! m_3d_base_clump) {
i = facet_part_rw(pa
rt, &m_3d_base_clump, mi_
show_3d, md_part_color);
if( (! i) || (! m_3d
_base_clump) ) { m
i_display_list_is_up_to_d
ate = 0; return;
} }RwRemoveClumpFrom
Scene(m_base_clump); m
_base_clump = m_3d_base_c
lump;// Set the base clum
p to be the 3d version’s
base clump.RwAddClumpToSc
ene(m_scene, m_base_clum
p); } else { if(! m_
flat_base_clump) {
i = facet_part_rw(part, &
m_flat_base_clump, mi_sho
w_3d, md_part_color);
if( (! i) || (! m_flat_
base_clump) ) { mi
_display_list_is_up_to_da
te = 0; return;
} }RwRemoveClumpFromS
cene(m_base_clump); m_
base_clump = m_flat_base_
clump;// Set the base clu
mp to be the 3d version’s
base clump. RwAddClum
pToScene(m_scene,m_base_c
lump); } ml_last_functi
on_chosen = SOLID_MODE;
DrawPart(m_hdc); ml_last
_function_chosen = NO_FUN
CTION_MODE; }void CBend
CADViewPart::OnZoomWindow
() { ml_last_function_ch
osen = ZOOM_WINDOW_MODE;
mi_bbox_is_up_to_date
= 0;}void CBendCADViewPar
t::OnUpdateZoomWindow(CCm
dUI*pCmdUI) {pCmdUI−>SetC
heck((ZOOM_WINDOW_MODE ==
ml_last_function_chosen)
? TRUE : FALSE);}void CBe
ndCADViewPart::OnZoomInOu
t() { ml_last_function_c
hosen = ZOOM_IN_OUT_MODE;
mi_bbox_is_up_to_date
= 0;}void CBendCADViewPa
rt::OnUpdateZoomInOut(CCm
dUI* pCmdUI) {pCmdUI−>Set
Check((ZOOM_IN_OUT_MODE =
= ml_last_function_chose
n) ? TRUE : FALSE);}void
CBendCADViewPart::OnZoomA
ll() { BM_PART *part = N
ULL; CBendCADDoc* pDoc;
BM_VECTORoffset; if(! m
i_bbox_is_up_to_date) {
pDoc = GetDocument();
ASSERT_VALID(pDoc);
part = pDoc−>get_part();
if(! part) return;if(!
mi_part_is_up_to_date)

// By now we expect t
he centroid to have alrea
dycompute_part_centroid(p
art, 0, &m_flat_part_cent
roid); // been computed;
this is only a safety ch
eck. compute_part_centroi
d(part, 1, &m_3d_part_cen
troid); if(mi_show_3d) m_
part_centroid = m_3d_part
_centroid;else m_part_cen
troid = m_flat_part_cent
roid;}compute_part_bbox(p
art, mi_show_3d, md_rot_m
atrix, m_part_centroid, m
d_part_bbox_size, &offse
t); mi_bbox_is_up_to_d
ate = 1;md_x_trans = −(of
fset.X()); // Adjust
for the fact that bbox ce
nter maymd_y_trans = −(of
fset.Y()); // not coi
ncide with centroid of pa
rt. } set_new_view_volu
me(md_part_bbox_size[0],
md_part_bbox_size[1]); m
l_last_function_chosen =Z
OOM_ALL_MODE; DrawPart(m
_hdc); ml_last_function_
chosen = NO_FUNCTION_MOD
E; }void CBendCADViewPar
t::OnUpdateZoomAll(CCmdUI
* pCmdUI) {pCmdUI−>SetChe
ck((ZOOM_ALL_MODE == ml_l
ast_function_chosen) ? TR
UE : FALSE);}void CBendCA
DViewPart::OnViewIsometri
c() { ml_last_function_c
hosen = ISOMETRIC_VIEW_MO
DE; mi_bbox_is_up_to_dat
e = 0; md_z_angle = 270.
0; md_y_angle = 305.2643
897;// 270 + tan^−1(1/sqr
t(2)) RwRotateMatrix(RwS
cratchMatrix(), 0.0f, 0.0
f, 1.0f, CREAL(md_z_angl
e), rwREPLACE); RwRotate
Matrix(RwScratchMatrix(),
0.0f, 1.0f, 0.0f, CREAL
(md_y_angle), rwPRECONCA
T);md_z_angle = 45.0; Rw
RotateMatrix(RwScratchMat
rix(), 0.0f, 0.0f, 1.0f,C
REAL(md_z_angle), rwPRECO
NCAT); if(md_rot_matrix)
RwDestroyMatrix(md_rot_m
atrix); md_rot_matrix =
RwDuplicateMatrix(RwScrat
chMatrix());// glPushMat
rix();// glLoadIdentit
y();// glRotated(md_z_an
gle, 0.0, 0.0, 1.0); //
Rotation about z axis.//
glRotated(md_y_angle,
0.0, 1.0, 0.0); // Rotat
ion about y axis.// md_z
_angle = 45.0;// glRotat
ed(md_z_angle, 0.0, 0.0,
1.0);// glGetDoublev(GL_
MODELVIEW_MATRIX, md_rot_
matrix);// glPopMatri
x(); OnZoomAll();}void C
BendCADViewPart::OnViewRi
ght() {ml_last_function_c
hosen = RIGHT_VIEW_MODE;
mi_bbox_is_up_to_date =
0;md_z_angle = 270.0; md
_y_angle = 270.0; md_x_a
ngle = 0.0; RwRotateMatr
ix(RwScratchMatrix(), 0.0
f, 0.0f, 1.0f, CREAL(md_z
_angle), rwREPLACE); RwR
otateMatrix(RwScratchMatr
ix(), 0.0f, 1.0f, 0.0f, C
REAL(md_y_angle), rwPRECO
NCAT); if(md_rot_matrix)
RwDestroyMatrix(md_rot_m
atrix); md_rot_matrix =
RwDuplicateMatrix(RwScrat
chMatrix());// glPushMat
rix();//glLoadIdentity();
// glRotated(md_z_angle,
0.0, 0.0, 1.0); // Rot
ationabout z axis.// glR
otated(md_y_angle, 0.0,
1.0, 0.0); // Rotation a
bout y axis.// glGetDoub
lev(GL_MODELVIEW_MATRIX,
md_rot_matrix);// glPopM
atrix(); OnZoomAll();}vo
id CBendCADViewPart::OnVi
ewFront() { ml_last_func
tion_chosen = FRONT_VIEW_
MODE; mi_bbox_is_up_to_d
ate = 0; md_y_angle = 0.
0; md_z_angle = 0.0; md
_x_angle = 270.0; RwRota
teMatrix(RwScratchMatri
x(), 1.0f, 0.0f, 0.0f, CR
EAL(md_x_angle), rwREPLAC
E); if(md_rot_matrix) Rw
DestroyMatrix(md_rot_matr
ix); md_rot_matrix = RwD
uplicateMatrix(RwScratchM
atrix());// glPushMatrix
(); // glLoadIdentity();
// glRotated(md_x_angle,
1.0, 0.0, 0.0); // Rot
ation about x axis.// gl
GetDoublev(GL_MODELVIEW_M
ATRIX, md_rot_matrix);//
glPopMatrix(); OnZoomAl
l();}void CBendCADViewPar
t::OnViewTop() { ml_last
_function_chosen = TOP_VI
EW_MODE; mi_bbox_is_up_t
o_date = 0; RwIdentityMa
trix(md_rot_matrix);OnZoo
mAll();}void CBendCADView
Part::OnViewsOrtho() {if
(NULL == GetDocument()−>g
et_part()) { // no partre
turn ;} COrthoViewDlg orh
odlg(NULL, GetDocument()−
>get_part(), this) ;int r
et = orhodlg.DoModal() ;/
/ if we are in a Client M
ode, the user cannot have
entered anything.// we h
ave toredisplay the main
client menu bar.if (BENDC
AD_CLIENT_MODE) {::PostMe
ssage(this−>GetSafeHwn
d(),WM_COMMAND,MAKEWPARAM
(ID_DISPLAY_CLIENT_MENU,
1),NULL) ;return ;}// whe
n OK pressed, get return
valuesif (IDOK == ret)
{}}void CBendCADViewPar
t::OnViewBack() { ml_la
st_function_chosen = BACK
_VIEW_MODE; mi_bbox_is_u
p_to_date = 0; md_x_angl
e = 270.0; md_y_angle=
0.0; md_z_angle = 180.0;
RwRotateMatrix(RwScratc
hMatrix(), 1.0f, 0.0f, 0.
0f, CREAL(md_x_angle), rw
REPLACE); RwRotateMatrix
(RwScratchMatrix(), 0.0f,
0.0f, 0.1f, CREAL(md_z_a
ngle), rwPRECONCAT); if
(md_rot_matrix)RwDestroyM
atrix(md_rot_matrix); md
_rot_matrix = RwDuplicate
Matrix(RwScratchMatri
x()); OnZoomAll();}void
CBendCADViewPart::OnViewB
ottom() { ml_last_functi
on_chosen = BOTTOM_VIEW_M
ODE; mi_bbox_is_up_to_da
te = 0;md_x_angle = 0.0;
md_y_angle = 180.0; md_
z_angle = 0.0; RwRotateM
atrix(RwScratchMatrix(),
0.0f, 1.0f, 0.0f, CREAL(m
d_y_angle), rwREPLACE);
if(md_rot_matrix) RwDestr
oyMatrix(md_rot_matrix);
md_rot_matrix = RwDuplic
ateMatrix(RwScratchMatrix
()); OnZoomAll();}void C
BendCADViewPart::OnViewLe
ft() { ml_last_function_
chosen = LEFT_VIEW_MODE;
mi_bbox_is_up_to_date =
0; md_z_angle = 90.0; m
d_y_angle = 90.0; md_x_a
ngle = 0.0; RwRotateMatr
ix(RwScratchMatrix(), 0.0
f, 0.0f, 1.0f, CREAL(md_z
_angle), rwREPLACE); RwR
otateMatrix(RwScratchMatr
ix(), 0.0f, 1.0f, 0.0f, C
REAL(md_y_angle), rwPRECO
NCAT); if(md_rot_matrix)
RwDestroyMatrix(md_rot_m
atrix); md_rot_matrix =
RwDuplicateMatrix(RwScrat
chMatrix()); OnZoomAl
l();}void CBendCADViewPar
t::OnRotate() { ml_last_
function_chosen = ROTATIO
N_MODE; mi_bbox_is_up_to
_date = 0;}void CBendCADV
iewPart::OnUpdateRotate(C
CmdUI* pCmdUI) {pCmdUI−>S
etCheck((ROTATION_MODE ==
ml_last_function_chosen)
? TRUE : FALSE);}void CB
endCADViewPart::OnPan()
{ ml_last_function_cho
sen = PAN_MODE; mi_bbo
x_is_up_to_date = 0;}void
CBendCADViewPart::OnUpda
tePan(CCmdUI* pCmdUI) {pC
mdUI−>SetCheck((PAN_MODE
== ml_last_function_chose
n) ? TRUE : FALSE);}// Th
is function computes the
rotation angles about x a
nd y axes.// It is called
on mouse movement, if th
e rotation mode is on.voi
d CBendCADViewPart::compu
te_rotation_angles(int x_
flag){ double x_dir = (d
ouble)(m_current_point.x
− m_previous_point.x);dou
ble y_dir = (double)(m_cu
rrent_point.y − m_previou
s_point.y); double mag =
sqrt(x_dir*x_dir + y_dir
*y_dir); // Create the r
otation matrixcorrespondi
ng to the axis computed.
if(mag > 0.1) { RwRot
ateMatrix(RwScratchMatrix
(), CREAL(y_dir/mag), CRE
AL(x_dir/mag), CREAL(0.
0),CREAL(360.0*mag/(1.414
*m_old_rect.bottom)), rwR
EPLACE);RwTransformMatrix
(RwScratchMatrix(), md_ro
t_matrix, rwPRECONCAT);
if(md_rot_matrix) RwDes
troyMatrix(md_rot_matri
x); md_rot_matrix = Rw
DuplicateMatrix(RwScratch
Matrix()); } // glPu
shMatrix();// glLoadIden
tity();// glRotated(md_y
_angle, 0.0, 1.0, 0.0);
// Rotation about yaxi
s.// if(x_flag)// glR
otated(md_x_angle, 1.0,
0.0, 1.0); // Rotation a
bout x axis.// else//
glRotated(md_z_angle,
0.0, 0.0, 1.0);// Rotatio
n about z axis.// glMult
Matrixd(md_rot_matrix);//
glGetDoublev(GL_MODELVI
EW_MATRIX, md_rot_matri
x);// glPopMatrix(); }
// This function computes
the x and y translation
values.// It is called on
mouse movement, if the p
an mode is on.void CBendC
ADViewPart::compute_pan_t
ranslation(void){ double
x; if( (x = (double)m_o
ld_rect.right) > 0.0 )
md_x_trans += (m_current
_point.x − m_previous_poi
nt.x)*md_current_view_vol
[0]/x; if( (x = (double)
m_old_rect.bottom) > 0.0
)md_y_trans += −(m_curre
nt_point.y − m_previous_p
oint.y)* // −ve signfor
md_y_trans
md_current_view_vol
[1]/x;// bec. y axis poin
ts up screen.
}// This funciton compu
tes translation values wh
en user zooms in/out.void
CBendCADViewPart::comput
e_zoom_in_out_translation
(void){ double x; if(
(x = (double)m_old_rect.r
ight) > 0.0 ) md_x_tra
ns += −(m_current_point.x
− m_previous_point.x)*
md_curre
nt_view_vol[0]/x;}// This
funciton computes transl
ation values when user zo
oms into a // selected re
ctangularregion.void CBen
dCADViewPart::compute_zoo
m_region_translation(voi
d){ double x1 = ((doubl
e)(m_lt_btn_down_point.x
+ m_lt_btn_up_point.x))/
2.0;double delta_x = x1 −
((double)m_old_rect.righ
t)/2.0; double y1 = ((do
uble)(m_lt_btn_down_poin
t.y + m_lt_btn_up_point.
y))/2.0; double delta_y=
−( y1 − ((double)m_old_r
ect.bottom)/2.0 ); md_x_
trans −= //m_part_centroi
d.X() − md_x_trans +
delta_x*2.0*md
_current_view_vol[0]/((do
uble)m_old_rect.right);
md_y_trans −= //m_part_ce
ntroid.Y() − md_y_trans +
delta_y*
2.0*md_current_view_vol
[1]/((double)m_old_rect.b
ottom);}// This function
computes the new view vol
ume when the user zooms i
n/out.// The part has alr
eady been translated appr
opriately.void CBendCADVi
ewPart::compute_zoom_in_o
ut_view_volume(void){ do
ublex = −(m_current_poin
t.y − m_previous_point.
y); md_current_view_vol
[0] −= md_current_view_vo
l[0]*x/(double)m_old_rec
t.bottom; md_current_vie
w_vol[1] = md_current_vie
w_vol[0]/md_aspect; RwSe
tCameraViewwindow(m_camer
a, (float)(md_current_vie
w_vol[0]), (float)(md_cur
rent_view_vol[1]));glMatr
ixMode(GL_PROJECTION); g
lLoadIdentity(); glOrtho
(− md_current_view_vol
[0],md_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]); glMatrixMo
de(GL_MODELVIEW);}// This
function computes and se
ts the new view volume wh
en the user zooms into //
a selectedrectangular re
gion. (In the case of zoo
m all, the selected// reg
ion is simply the boundin
g box of the part).// The
part has already been tr
anslated appropriately.vo
id CBendCADViewPart::set_
new_view_volume(double x_
extent, double y_extent)
{ double longer = __max
(x_extent, y_extent); do
uble shorter = __min(x_ex
tent, y_extent); if(long
er == x_extent) { // T
he x extent is longer.
if(longer/md_aspect < sh
orter) // yextent
does not fit screen. lon
ger = shorter*md_aspect;m
d_current_view_vol[0] =
0.55*longer;md_current_vi
ew_vol[1] = 0.55*longer/m
d_aspect;md_current_view_
vol[2] = __max(longer, md
_part_bbox_size[2]); }
else { //The y extent is
longer. if(longer*md_
aspect < shorter) /
/ x extent does not fit s
creen. longer = shorter/
md_aspect;md_current_view
_vol[0] = 0.55*longer*md_
aspect;md_current_view_vo
l[1] = 0.55*longer;md_cur
rent_view_vol[2] = __max
(longer, md_part_bbox_siz
e[2]); } RwSetCameraVie
wwindow(m_camera, (float)
(md_current_view_vol[0]),
(float)(md_current_view_
vol[1])); glMatrixMode
(GL_PROJECTION); glLoadI
dentity(); glOrtho(− md_
current_view_vol[0],md_cu
rrent_view_vol[0],− md_cu
rrent_view_vol[1], md_cur
rent_view_vol[1],//− 5000
0.0, 50000.0); −
md_current_view_vol[2],
md_current_view_vol[2]);
glMatrixMode(GL_MODELVIE
W); glLoadIdentity();}//
This function draws a pa
rt on the view window. It
is called by OnDraw.void
CBendCADViewPart::DrawPa
rt(HDC draw_dc) { long si
ze,i, parent_tag, key;sta
tic long *selected_items
= NULL;RwClump *picked_cl
ump, *parent_clump; stat
ic double red_color[3] =
{1.0, 0.0, 0.0}; static
double green_color[3] =
{0.0, 1.0, 0.0};double ar
ray[16];BV_SELECT_DATA *d
ata = NULL;static RwMatri
x4d *old_matrix[50];stati
c float rw_array[4][4];if
(mi_simulation_is_on) {//
Set camera parameters to
view windowvalues. RwSe
tCameraViewport(m_camera,
0, 0, m_old_rect.right,
m_old_rect.bottom); gl
Viewport(0, 0, m_old_rec
t.right, m_old_rect.botto
m);RwSetCameraViewwindow
(m_camera, (float)(md_cur
rent_view_vol[0]), (floa
t)(md_current_view_vol
[1])); glMatrixMode(GL_PR
OJECTION);glLoadIdentit
y();glOrtho(− md_current_
view_vol[0],md_current_vi
ew_vol[0],− md_current_vi
ew_vol[1], md_current_vie
w_vol[1],//− 50000.0, 500
00.0);− md_current_view_v
ol[2], md_current_view_vo
l[2]);glMatrixMode(GL_MOD
ELVIEW);}if(! mi_show_sol
id){ // Wireframe dra
wing; use OpenGL drawing
commands. glPushMatri
x();glTranslated(m_camera
_position.X(), m_camera_p
osition.Y(), m_camera_pos
ition.Z());gluLookAt(m_ca
mera_position.X(), m_came
ra_position.Y(), m_camera
_position.Z(), m_camera_
target.X(),m_camera_targe
t.Y(), m_camera_target.
Z(), m_camera_lo
ok_up.X(),m_camera_look_u
p.Y(), m_camera_look_up.Z
()); glTranslated(md_x
_trans, md_y_trans, 0.0);
convert_rw_matrix_to_gl
_array(md_rot_matrix, arr
ay); glMultMatrixd(arra
y); glTranslated(− m_par
t_centroid.X(), − m_part_
centroid.Y(), − m_part_ce
ntroid.Z()); glClearCo
lor(0.0f, 0.0f, 0.0f, 1.0
f); glClear(GL_COLOR_B
UFFER_BIT | GL_DEPTH_BUFF
ER_BIT); if(ml_last_func
tion_chosen == SELECT_OBJ
ECTS_MODE) glRenderMo
de(GL_SELECT); else g
lRenderMode(GL_RENDER);
glSelectBuffer(512, mw_
selected_objects); glIni
tNames(); glPushName(0);
if(! mi_simulation_is_o
n) { // First draw the s
elected items in red, if
any.size = m_selection_se
t.list_size();if(size) {s
elected_items = new long
[size*2 + 1]; // +1 for
safety.m_selection_set.di
splay(size, selected_item
s);glColor3d(1.0, 0.0, 0.
0);for(i=0; i < size; ++
i) { data = (BV_SELECT_D
ATA *)selected_items[i*2+
1];if(! data) continue;if
(data−>edge) {// Edge is
available, => not a trivi
al glCallList((unsigned
int)selected_items[i<<
1]); // bendline or body
of something.}else {// Bo
dy of face/forming/bendli
ne picked; highlight whol
e thing.key = selected_it
ems[i<<1]/100000;glCallLi
st((unsigned int)key*1000
00);}} } } glCallList
(1); glFinish(); glPo
pMatrix(); SwapBuffer
s(wglGetCurrentDC());} e
lse { // Solid drawing;
use RenderWare. // Trans
form the part if necessar
y. if(ml_last_function_c
hosen != NO_FUNCTION_MOD
E) { RwTranslateMatr
ix(RwScratchMatrix(), CRE
AL(md_x_trans), CREAL(md_
y_trans), CREAL(0.0), rwR
EPLACE); RwTransfor
mMatrix(RwScratchMatri
x(), md_rot_matrix, rwPRE
CONCAT); RwTranslate
Matrix(RwScratchMatrix(),
CREAL(− m_part_centroid.
X()), CREAL(− m_part_cent
roid.Y()),CREAL(− m_part_
centroid.Z()), rwPRECONCA
T); // RwForAllClum
psInScenePointer(m_scene,
do_transformations, (voi
d *)RwScratchMatrix());Rw
TransformClump(m_base_clu
mp, RwScratchMatrix(), rw
REPLACE); }/*RwClump *c
lump; for(i=0; i < ml_nu
m_faces + ml_num_bendline
s + ml_num_formings; ++i)
{ clump = RwFindT
aggedClump(m_base_clump,
i + 10001);if(! clump) co
ntinue;old_matrix[i] = Rw
CreateMatrix(); // clump
の現在のモデル化マトリクスを記憶する. RwGetClum
pMatrix(clump, old_matrix[i]);RwGetMatrixElements
(old_matrix[i], rw_array); RwTranslateMatrix(Rw
ScratchMatrix(), CREAL(md_x_trans), CREAL(md_y_tra
ns), CREAL(0.0), rwREPLACE); RwTransformMatrix
(RwScratchMatrix(), md_rot_matrix, rwPRECONCAT);
RwTranslateMatrix(RwScratchMatrix(), CREAL(- m_p
art_centroid.X()),CREAL(- m_part_centroid.Y()),
CREAL(- m_part_centroid.Z()),
rwPRECONCAT); //RwForAllClumpsInScenePointer(m_sce
ne, do_transformations, (void *)RwScratchMatri
x());RwTransformClump(clump, RwScratchMatrix(), rw
POSTCONCAT); }*///Now set the color of the clump
s in the selection set to red.size = m_selection_s
et.list_size();if(size) {selected_items = new long
[(size << 1) + 1]; // +1 for safety.m_selection_
set.display(size, selected_items);for(i=0; i < siz
e; ++i) {data = (BV_SELECT_DATA *)selected_items[i
*2 +1];if(! data) continue;if(data->edge) {// Edge
is available, => not a trivial bendline or body o
f something.parent_tag = (selected_items[i<<1]/100
000) + 10000;parent_clump = RwFindTaggedClump(m_ba
se_clump, parent_tag);}else {key = selected_items
[i<<1]%100000; // Check if it is a trivial bendli
ne.if((key/10000) == 6) {parent_tag = (selected_it
ems[i<<1]/100000) + 10000;parent_clump = RwFindTag
gedClump(m_base_clump, parent_tag);}else parent_cl
ump = m_base_clump;}key = selected_items[i<<1]%100
000;picked_clump = RwFindTaggedClump(parent_clump,
key);RwForAllPolygonsInClumpPointer(picked_clump,
SetPolygonColor, (void *)red_color); }} // In ca
se simulation is going on, we don't want to show t
he m_sim_base_clump, only m_base_clump. if(mi_sim
ulation_is_on) {if(m_sim_base_clump) RwRemoveClump
FromScene(m_sim_base_clump);if(mi_show_3d) {m_base
_clump = m_3d_base_clump;RwAddClumpToScene(m_scen
e, m_base_clump);}else {m_base_clump = m_flat_base
_clump;RwAddClumpToScene(m_scene, m_base_clump);
} } // Now draw the part. RwInvalidateCam
eraViewport(m_camera);
RwBeginCameraUpdate(m_camera, (void *)m_hwnd);
RwClearCameraViewport(m_camera); i =RwGetSc
eneNumClumps(m_scene); // Render the sce
ne. RwRenderScene(m_scene); RwEndCameraUpdate
(m_camera); RwShowCameraImage(m_camera, (void*)
(DWORD)draw_dc); //Show the image on the view w
indow./*for(i=0; i < ml_num_faces + ml_num_bendlin
es + ml_num_formings; ++i) {clump = RwFindTaggedCl
ump(m_base_clump, i + 10001);if(! clump) continue;
RwTransformClump(clump, old_matrix[i], rwREPLACE);
RwGetClumpMatrix(clump, old_matrix[i]); Rw
GetMatrixElements(old_matrix[i], rw_array);if(old_
matrix[i]) RwDestroyMatrix(old_matrix[i]);} */ //
Put the simulation clump back in the scene so tha
t simulation can see it. if(mi_simulation_is_on)
{if(m_sim_base_clump) RwAddClumpToScene(m_scene, m
_sim_base_clump);if(mi_show_3d) RwRemoveClumpFromS
cene(m_3d_base_clump);else RwRemoveClumpFromScene
(m_flat_base_clump);m_base_clump = NULL; } // No
wset the color of the clumps in the selection set
back to their originalcolors. if(size) { m_sel
ection_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 so
mething.parent_tag = (selected_items[i<<1]/100000)
+ 10000;parent_clump = RwFindTaggedClump(m_base_c
lump, parent_tag);}else {key= selected_items[i<<1]
%100000; // Check if it is a trivial bend
line.if((key/10000) == 6) {parent_tag = (selected_
items[i<<1]/100000) +10000;parent_clump = RwFindTa
ggedClump(m_base_clump, parent_tag); } else pa
rent_clump = m_base_clump; }key = selected_items
[i<<1]%100000;picked_clump = RwFindTaggedClump(par
ent_clump, key);if( (! data->edge) && ((key/10000)
== 6) ) // Trivial bendline.RwForAllPolygonsInCl
umpPointer(picked_clump, SetPolygonColor, (void *)
green_color); elseRwForAllPolygonsInClumpPointer(p
icked_clump, SetPolygonColor, (void *)md_part_colo
r); } } if(selected_items) delete [] selecte
d_items; selected_items= NULL;}if(mi_simulation_i
s_on) { // Restore camera parameters to simulati
on values. RwSetCameraViewport(m_camera, 0, 0, mi
_bitmap_w , mi_bitmap_h); glViewport(0, 0, mi_b
itmap_w, mi_bitmap_h); RwSetCameraVie
wwindow(m_camera, (float)(md_sim_view_vol[0]), (fl
oat)(md_sim_view_vol[1])); glMatrixMode(GL_PROJECT
ION);glLoadIdentity();glOrtho(- md_sim_view_vol
[0], md_sim_view_vol[0],- md_sim_view_vol[1], md_s
im_view_vol[1],//- 50000.0, 50000.0); -
md_current_view_vol[2], md_current_view_vol[2]);g
lMatrixMode(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_ite
ms[i<<1]%100000)/10000; if((three_d_type >= 3) &&
(three_d_type < 6)) three_d_type = BM_ENTITY_TYPE
_FACE; else if((three_d_type >= 6) && (three_d_ty
pe < 9)) three_d_type = BM_ENTITY_TYPE_BENDLINE;
else if(three_d_type >= 9) three_d_type = BM_ENTIT
Y_TYPE_FORMING; parent_tag = (selected_items[i<<
1]/100000) + 10000; parent_clump = RwFindTaggedCl
ump(m_base_clump, parent_tag);}else { CBe
ndCADDoc* pDoc = GetDocument(); ASSERT_VA
LID(pDoc); BM_PART *part = pDoc->get_part
(); if(! part)return; // 注意: この段階
で部分がNULLであることを期待しない。BM_TOPOLOGY *t
opology = part->get_topology(); if(! topo
logy)return; three_d_type = selected_items[i<<1]/
100000; // 用語の注意: three_d_type は実際
ではない。 b3 = topology->map_id_into_poi
nter(three_d_type); // b3->get_type()までthree_d_t
ype. three_d_type =b3->get_type(); parent_clump
= m_base_clump;}if(three_d_type == BM_ENTITY_TYPE_
FACE) { for(j=0; j < 3; ++j) original_color
[j] = md_face_color[j];}else if(three_d_type == BM
_ENTITY_TYPE_BENDLINE) { for(j=0;j < 3; ++j)
original_color[j] = md_bendline_color[j];}else if
(three_d_type == BM_ENTITY_TYPE_FORMING) { fo
r(j=0; j < 3; ++j) original_color[j] = md_forming_
color[j];}key = selected_items[i<<1];key = key%100
000;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 thisautomatica
lly transforms child clumps as well.static RwClump
* RWCALLBACK do_transformations(RwClump *clump, v
oid *matrix) { int i = RwGetClumpNumChildren(clum
p); if(i) {if( !(i = RwGetClumpNumPolygons(clum
p)) )RwSetClumpState(clump, rwOFF);// Do not rende
r this clump if it hasno polygons. RwTransformC
lump(clump, (RwMatrix4d *)matrix, rwREPLACE); }
return clump;}// This callback function sets
the color of the polygon to the required color.st
atic RwPolygon3d * RWCALLBACK SetPolygonColor(RwPo
lygon3d *polygon, void *color) { polygon = RwS
etPolygonColor(polygon, CREAL(((double *)color)
[0]), CREAL(((double *)color)[1]),CREAL(((double
*)color)[2]));returnpolygon;}// This function sets
the pixel format of the view window to the kind t
hat// OpenGL likes. Note: Pixel format of a window
should be set only once.BOOL CBendCADViewPart::Se
tupPixelFormat(HDC hDC){ staticPIXELFORMATDESCR
IPTOR pfd = { sizeof(PIXELFORMATDESCRIPTO
R), //size of this pfd 1,
// version number PFD_DRAW_TO_
WINDOW | // support window PFD
_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER,// double buffered PFD
_TYPE_RGBA, //RGBA type 2
4, // 24-bit color dep
th0, 0, 0, 0, 0, 0, // color bits ig
nored 0,// no alpha buffer 0,// shif
t bit ignored 0,// no accumulation buffer
0, 0, 0, 0, // accum bit
s ignored 32, /
/ 32-bit z-buffer 0,
// no stencil buffer 0,// no auxilia
ry buffer PFD_MAIN_PLANE, /
/ main layer 0,// reserved 0, 0, 0
// layer masks ignored
}; int pixelformat; if ( (pixelformat = Cho
osePixelFormat(hDC, &pfd)) == 0 ) { Mess
ageBox("ChoosePixelFormat failed");return FALSE;
} if (SetPixelFormat(hDC, pixelformat, &pfd)
== FALSE) { MessageBox("SetPixelFormat f
ailed"); return FALSE; } // don't nee
d this call any more; the function will be called
from OnActivateView()// and on OnViewWireframe() -
- AK//CreateRGBPalette(hDC); return TRUE;}unsig
ned char CBendCADViewPart::ComponentFromIndex(int
i, UINT nbits, UINT shift){ unsigned char val;
val = (unsigned char) (i >> shift); switch
(nbits) { case 1: val &= 0x1; ret
urn oneto8[val]; case 2: val &= 0x3;
return twoto8[val]; case 3: val &= 0
x7; return threeto8[val]; default:
return 0; }}void CBendCADViewPart::CreateRGBP
alette(HDC hDC){ PIXELFORMATDESCRIPTOR pfd;
LOGPALETTE *pPal; intn, i; CDC dc; n = ::
GetPixelFormat(hDC); ::DescribePixelFormat(hDC,
n, sizeof(PIXELFORMATDESCRIPTOR), &pfd); if (p
fd.dwFlags & PFD_NEED_PALETTE) { n = 1 <
< pfd.cColorBits; pPal = (PLOGPALETTE)Local
Alloc(LMEM_FIXED, sizeof(LOGPALETTE) +
n * sizeof(PALETTEENTRY)); pPal->palVer
sion = 0x300; pPal->palNumEntries = n;
for (i=0; i<n; i++) { pPal->p
alPalEntry[i].peRed = Component
FromIndex(i, pfd.cRedBits, pfd.cRedShift);
pPal->palPalEntry[i].peGreen =ComponentFromInd
ex(i, pfd.cGreenBits, pfd.cGreenShift);
pPal->palPalEntry[i].peBlue =
ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShif
t); pPal->palPalEntry[i].peFlags =0;
} /* 省略時GDIパレットを含むようにパレ
ットを固定する */if ((pfd.cColorBits == 8)
&&(pfd.cRedBits == 3) && (pf
d.cRedShift == 0) && (pfd.cGreenBits
== 3) && (pfd.cGreenShift == 3) && (pf
d.cBlueBits ==2) && (pfd.cBlueShift == 6)
) {for (i = 1 ; i <= 12 ;i++)
pPal->palPalEntry[defaultOverride[i]] = defa
ultPalEntry[i]; } dc.Attach(hDC);CPa
lette*pOldPal; // since we call this functi
on not only when creating a view,// but also each
time activating, delete the prev palette (if any)
-- AKint resp = m_cPal.DeleteObject(); m_cP
al.CreatePalette(pPal); LocalFree(pPal);
pOldPal = dc.SelectPalette(&m_cPal, FALSE);
dc.RealizePalette(); dc.Detach();
}}// This function computes the bounding box para
meters of the given part -// the x, y and z extent
s, in globalcoordinates, for the orientation speci
fied by orient_matrix.// The computation is done w
ith respect to the BM_POINT centroid as origin.//
It does so by taking the bbox of each face, projec
ting each onto the coordinate // axes, and then fi
nding the extents along each axis. If threeD_flagi
s non-zero, the// three-d version's bbox is comput
ed; else, the flat'sbbox is computed. The results
of the// computation are put into the arry bbox_si
ze[3]; if this pointer is zero, no computation// i
s performed.The offset, ie. the vector from the ce
ntroid's coords to the bbox center's coords,// is
passed back in the pointer to the BM_VECTOR.// Ret
urns 1if successful, 0 otherwise.int CBendCADViewP
art::compute_part_bbox(BM_PART *part, int threeD_f
lag, RwMatrix4d *orient_matrix,BM_POINT centroid,
double *bbox_size, BM_VECTOR *offset) { BM_FACE *
face = NULL; BM_BENDLINE *bendline = NULL; BM_2D
_BODY*two_d_body = NULL; BM_LOOP *loop = NULL; B
M_POINT dot1, dot2, dot3, dot4; double left, righ
t, top, bot, front, back; // First two refert
o x direction, // last two to z direction. BM_V
ECTOR vec1; int first_pass = 1; float rot_matrix
[4][4]; if(! part) return 0; if( (part->get_num
ber_of_faces() == 0) && (part->get_number_of_bendl
ines() == 0) )return 0; if(! bbox_size) return 0;
if(! part->get_number_of_faces()) { // In this c
ase, find bendline bboxes. for(bendline = part-
>get_bendline_list(); bendline; bendline = (BM_BEN
DLINE *)bendline->next()){ // First check that th
e bbox of the bloop is up to date; if not compute
bbox. if(threeD_flag) two_d_body = bendline->g
et_3D_version(); else two_d_body = bendline->g
et_flat(); if(two_d_body) loop = two_d_body->get_
bloop(); else continue; if(! loop) continue; if
(!(loop->is_bbox_up_to_date())) loop->recompute_bb
ox(); // Now find the envelope (union) of the pro
jected bboxes. vec1 = BM_VECTOR(centroid.X(), cen
troid.Y(), centroid.Z()); dot1 = loop->get_bbox_p
1() + (-1.0)*vec1;// The bboxcoordinates, dot2 =
loop->get_bbox_p2() + (-1.0)*vec1;// with respectt
o the dot3 = loop->get_bbox_p3() + (-1.0)*vec1;//
centroid as origin.dot4 = loop->get_bbox_p4() +
(-1.0)*vec1; RwGetMatrixElements(orient_matrix, r
ot_matrix); multiply_pt_by_matrix(&dot1, rot_matr
ix);// Transform coords by the current multiply_p
t_by_matrix(&dot2, rot_matrix);// rotation matrix.
multiply_pt_by_matrix(&dot3, rot_matrix); multi
ply_pt_by_matrix(&dot4, rot_matrix); if(first_pas
s) { left = __min(dot1.X(), dot2.X()); righ
t = __max(dot1.X(), dot2.X()); bot = __min(do
t1.Y(), dot2.Y()); top = __max(dot1.Y(), dot
2.Y()); back = __min(dot1.Z(), dot2.Z()); f
ront = __max(dot1.Z(), dot2.Z()); first_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()); b
ack = __min(back , dot1.Z()); back = __min(ba
ck , 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, dot4.X()); bot= __min(bot , dot3.Y());
bot = __min(bot , dot4.Y()); top = __max(top
, dot3.Y()); top = __max(top , dot4.Y()); b
ack = __min(back , dot3.Z()); back = __min(back
, dot4.Z()); front = __max(front, dot3.Z()); fr
ont = __max(front, dot4.Z()); } bbox_size[0]
= right- left;bbox_size[1] = top - bot;// Copy
bbox size into the array passed.bbox_size[2] = fro
nt - back;if(offset) // Copy the bbox center i
nto the pointer passed. *offset = BM_VECTOR((righ
t + left)/2.0, (top + bot)/2.0, (front + back)/2.
0);mi_bbox_is_up_to_date = 1; return 1; } //Fac
es are available, so find bbox of faces. for(face
= part->get_face_list(); face; face = (BM_FACE *)
face->next()) { if(! face) break;// First check
that the bbox of the bloop is up to date; if not
computebbox.if(threeD_flag) two_d_body = face->ge
t_3D_version();else two_d_body = face->get_fla
t();if(two_d_body) loop = two_d_body->get_bloop();
elsecontinue;if(! loop) continue;if(!(loop->is_bbo
x_up_to_date())) loop->recompute_bbox();// Now fin
d the envelope (union) of the projected bboxes.vec
1 = BM_VECTOR(centroid.X(), centroid.Y(), centroi
d.Z());dot1 = loop->get_bbox_p1() + (-1.0)*vec1;//
The bbox coordinates,dot2 = loop->get_bbox_p2() +
(-1.0)*vec1;// with respect to thedot3 = loop->ge
t_bbox_p3() +(-1.0)*vec1;// centroid as origin.dot
4 = loop->get_bbox_p4() + (-1.0)*vec1; RwGetMat
rixElements(orient_matrix, rot_matrix);multiply_pt
_by_matrix(&dot1, rot_matrix);// Transform coords
by the currentmultiply_pt_by_matrix(&dot2, rot_mat
rix);// rotation matrix.multiply_pt_by_matrix(&dot
3, rot_matrix);multiply_pt_by_matrix(&dot4, rot_ma
trix);if(first_pass) {left = __min(dot1.X(), dot
2.X()); right = __max(dot1.X(), dot2.X());bot =
__min(dot1.Y(), dot2.Y()); top = __max(dot1.
Y(), dot2.Y());back = __min(dot1.Z(), dot2.Z());
front = __max(dot1.Z(), dot2.Z());first_pass =
0;}else { left = __min(left, dot1.X()); left
= __min(left, dot2.X()); right = __max(right, do
t1.X()); right = __max(right,dot2.X()); bot =
__min(bot , dot1.Y()); bot = __min(bot , dot
2.Y()); top = __max(top , dot1.Y()); top =
__max(top , dot2.Y());back = __min(back , dot1.Z
()); back = __min(back , dot2.Z()); front= __ma
x(front, dot1.Z()); front = __max(front, dot2.
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(b
ack ,dot4.Z());front = __max(front, dot3.Z());fron
t = __max(front, dot4.Z());} bbox_size[0] = right
- left; bbox_size[1] = top - bot;// Copy bbox
size into the array passed. bbox_size[2] = front
- back; if(offset)// Copy the bbox center into th
e pointer passed.*offset = BM_VECTOR((right + lef
t)/2.0, (top + bot)/2.0, (front + back)/2.0); mi_
bbox_is_up_to_date = 1; return 1;}// This functio
n computes the part's centroid.This is done with r
espect to// the original (given) coordinates of th
epart. If threeD_flag is non-zero, the// three-d v
ersion's centroid is computed; else, the flat's ce
ntroid is computed.// The results are passedback i
n the pointer to a BM_POINT; if this pointer is NU
LL, no// computation is done. Returns 1 if success
ful, 0 otherwise.int CBendCADViewPart::compute_par
t_centroid(BM_PART *part, int threeD_flag, BM_POIN
T *centroid) { BM_FACE *face; BM_2D_BODY *two_
d_body; BM_LOOP *loop; BM_POINT dot1, dot2, dot
3, dot4; double left, right, top, bot, front, bac
k; // First two refer to x direction, // last tw
o 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(face = part->get
_face_list(); face; face = (BM_FACE *)face->nex
t()) { if(! face) break; // First check that
the bbox of thebloop is up to date; if not comput
e bbox.if(threeD_flag) two_d_body = face->get_3D_
version();else two_d_body = face->get_flat();if(t
wo_d_body)loop = two_d_body->get_bloop();else cont
inue;if(! loop) continue;if(!(loop->is_bbox_up_to_
date())) loop->recompute_bbox();// Now find the en
velope (union) of the projected bboxes.dot1 = loop
->get_bbox_p1();dot2 = loop->get_bbox_p2();dot3 =
loop->get_bbox_p3(); dot4 = loop->get_bbox_p4(); 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(rig
ht, dot1.X());right = __max(right, dot2.X()); bot
= __min(bot , dot1.Y()); bot= __min(bot , do
t2.Y()); top = __max(top , dot1.Y()); top =
__max(top , dot2.Y()); back = __min(back , dot
1.Z()); back = __min(back , dot2.Z()); front =
__max(front, dot1.Z()); front = __max(front, dot
2.Z());}left = __min(left, dot3.X());left = __m
in(left, dot4.X());right = __max(right, dot3.
X());right = __max(right, dot4.X());bot = __min
(bot , dot3.Y());bot = __min(bot , dot4.Y());t
op = __max(top ,dot3.Y());top = __max(top ,
dot4.Y());back = __min(back , dot3.Z());back = _
_min(back , dot4.Z());front = __max(front, dot3.
Z());front = __max(front, dot4.Z()); } *centroid
= BM_POINT((right + left)/2.0, (top+ bot )/2.0,
(front + back)/2.0); // Copy centroid into/*// ポ
インタが供給される。 if(threeD_flag) { m_3d_pa
rt_centroid.set_X((right + left)/2.0); m_3d_par
t_centroid.set_Y((top + bot )/2.0); // このpar
tは3d重心である。 m_3d_part_centroid.set_Z((fro
nt + back)/2.0); } else { m_flat_part_centroi
d.set_X((right + left)/2.0); m_flat_part_centro
id.set_Y((top + bot )/2.0); // このpartは平面
重心である。 m_flat_part_centroid.set_Z((front
+ back)/2.0); }*/ return 1;}// This function mul
tiplies a bend model point by a 4x4 RenderWare tra
nsform matrix.// The function is destructive.It is
NOT a BMAPPView member function.// Note that the
point is considered to be a row vector; this is//
RenderWare's (and the Bend Model's) convention. st
atic void multiply_pt_by_matrix(BM_POINT *point, f
loat rot_matrix[4][4]) { double x = point->X();do
uble y = point->Y(); double z = point->Z(); poin
t->set_X((x*rot_matrix[0][0] + y*rot_matrix[1][0]
+ z*rot_matrix[2][0])); point->set_Y((x*rot_matri
x[0][1] + y*rot_matrix[1][1] + z*rot_matrix[2]
[1])); point->set_Z((x*rot_matrix[0][2] + y*rot_m
atrix[1][2] + z*rot_matrix[2][2]));}// This functi
on outlines the rectangular region selected by the
user.void CBendCADViewPart::outline_region(void)
{ CClientDC view_dc(this); CPoint corner1_curr =
m_lt_btn_down_point, corner2_curr = m_lt_btn_down
_point; CPoint corner1_prev = m_lt_btn_down_poin
t, corner2_prev = m_lt_btn_down_point; corner1_cu
rr.Offset(m_current_point.x - m_lt_btn_down_point.
x, 0); corner2_curr.Offset(0, m_current_point.y -
m_lt_btn_down_point.y); corner1_prev.Offset(m_pr
evious_point.x - m_lt_btn_down_point.x, 0);corner2
_prev.Offset(0, m_previous_point.y - m_lt_btn_down
_point.y); view_dc.SetROP2(R2_NOT); view_dc.Move
To(m_lt_btn_down_point); view_dc.LineTo(corner1_p
rev); view_dc.MoveTo(m_lt_btn_down_point); view_
dc.LineTo(corner2_prev); view_dc.MoveTo(corner1_p
rev); view_dc.LineTo(m_previous_point); view_dc.
MoveTo(corner2_prev); view_dc.LineTo(m_previous_p
oint); view_dc.MoveTo(m_lt_btn_down_point); view
_dc.LineTo(corner1_curr);view_dc.MoveTo(m_lt_btn_d
own_point); view_dc.LineTo(corner2_curr); view_d
c.MoveTo(corner1_curr); view_dc.LineTo(m_current_
point); view_dc.MoveTo(corner2_curr); view_dc.Li
neTo(m_current_point);}// This functionprocesses t
he hits record to pick out the edge(s) selected by
the// user. If add_hit_to_list is non-zero, which
it is if the control button isheld down,// the cu
rrent hit, if any, is added to the selection set;
else, the selection set// is cleared and only the
current hit is added tothe list. If there is no h
it, the // selection set is cleared as well, unles
s add_to_list is non-zero, in which case // nothin
g happens. // Thisfunction recognizes trivial bend
lines and formings and modifies the selection set/
/ appropriately. void CBendCADViewPart::process_hi
ts_record(int add_hit_to_list){ RwClump *picked_c
lump = NULL; RwClump *parent_clump = NULL;RwV3d v
ert; long parent_tag, clump_tag, three_d_type =
0, offset = 0, key = 0; int num_hits = -3, j; un
signed long z_max = 0UL, z_min = ULONG_MAX, name_i
d = 0UL; unsigned int *ptr = mw_selected_objects;
BM_EDGE *edge = NULL;long old_data; if(mi_show_so
lid) {// RenderWarepicking. if(m_pick.type == r
wNAPICKOBJECT) { // No clump was
picked. if(add_hit_to_list) return;else clear
_selection_set();return; } else if(m_pick.ty
pe == rwPICKCLUMP) {// Some clump was picked; proc
ess it. picked_clump = m_pick.object.clump.cl
ump;vert = m_pick.object.clump.wcpoint; RwTra
nslateMatrix(RwScratchMatrix(), CREAL(md_x_trans),
CREAL(md_y_trans), CREAL(0.0), rwREPLACE);
RwTransformMatrix(RwScratchMatrix(), md_rot_matri
x, rwPRECONCAT); RwTranslateMatrix(RwScratchM
atrix(), CREAL(- m_part_centroid.X()), CREAL(- m_p
art_centroid.Y()), CREAL(-
m_part_centroid.Z()), rwPRECONCAT); RwMatrix4d
*inverse = RwCreateMatrix();RwInvertMatrix(RwScra
tchMatrix(), inverse);RwTransformPoint(&vert, inve
rse);RwDestroyMatrix(inverse);parent_clump = RwGet
ClumpParent(picked_clump);parent_tag = RwGetClumpT
ag(parent_clump);clump_tag = RwGetClumpTag(picked_
clump);if(parent_tag == 1) {// The body of a face/
bendline/forming was picked.key = (clump_tag%1000
0)*100000 + clump_tag; if(m_selection_set.find
(key, NULL)) { m_selection_set.remov
e(key, &old_data); // Remove clump from sel
ection set (toggle).if(old_data) delete (BV_SELECT
_DATA *)old_data;return;}else {if(! add_hit_to_lis
t) clear_selection_set(); // Remove everything el
se in selection set,BV_SELECT_DATA *data = new BV_
SELECT_DATA;data->key = key;data->edge = NULL;
(data->world_pt) = BM_POINT(vert.x, vert.y,
vert.z);m_selection_set.insert(key, (long)data);//
insert this key and data.return;}}// Now an edge
was picked.key = (parent_tag%10000)*100000 + clump
_tag; if(clump_tag) {// Safety check; we expect cl
ump_tag to be non-zero.if(m_selection_set.find(ke
y, NULL)){ m_selection_set.remove(key, &old_dat
a);// Remove clump from selection set (toggle).if
(old_data) delete (BV_SELECT_DATA *)old_data;} el
se {if(! add_hit_to_list) clear_selection_set();
// Remove everything else in selection set. edge =
map_list_name_to_bm_edge(parent_tag, clump_tag);B
V_SELECT_DATA *data = new BV_SELECT_DATA;data->key
= key;data->edge = edge; (data->world_p
t) = BM_POINT(vert.x, vert.y, vert.z);m_selection_
set.insert(key, (long)data);//insert this key and
data.}} } } else {// OpenGL Picking. num_h
its = glRenderMode(GL_RENDER); //
The number of hits.if(num_hits == -1) {
// Selection buffer has overflowed.
AfxMessageBox("Too many entities selected; ch
ange view andtry again.");return; } if(num_h
its == 0) {// No hit; only a miss. if(add_hit
_to_list) return;else clear_selection_set();retur
n; } // Process the hits : find the edge wit
h LOWEST z value of all the edges picked. for(j
=0; j < num_hits; ++j) {ptr += 1;
// Skip the 1st element bec. itwill always be
1, if( (unsigned long)(*ptr) < (unsigned lon
g)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 an
dadd it to the selection set. if(name_id) {// S
omething was selected. if(m_selection_set.fin
d(name_id,NULL)) {m_selection_set.remove(name_id,
&old_data); // Remove edge fromselection set (t
oggle).if(old_data) delete (BV_SELECT_DATA *)old_d
ata;}else {if(! add_hit_to_list) clear_selection_s
et();// First, we massagethe name_id into the form
at RenderWare picking uses.parent_tag = name_id/10
0000 + 10000;clump_tag = name_id%100000;edge = map
_list_name_to_bm_edge(parent_tag, clump_tag);BV_SE
LECT_DATA *data = new BV_SELECT_DATA;data->key = k
ey;data->edge = edge; (data->world_pt) = BM
_POINT(0.0,0.0, 0.0);m_selection_set.insert(name_i
d, (long)data);// insert this keyand data.} }
} return;}// This function maps a RenderWare par
ent clump and child clump pair to the // Bend Mode
l edge which the child clump represents. The point
er to the edge is returned.// This function onlyne
eds to deal with "real" edges, ie. trivial bendlin
es and// formings are filtered out by process_hits
_records itself.BM_EDGE *CBendCADViewPart::map_lis
t_name_to_bm_edge(long parent_tag, long clump_tag)
{ long three_d_name, three_d_type, loop_name, ed
ge_name, count = 0, offset = 0; BM_3D_BODY *three
_d_body = NULL; BM_2D_BODY *two_d_body = NULL; B
M_LOOP *loop = NULL; BM_EDGE *edge = NULL; BM_PA
RT *part = NULL; BM_TOPOLOGY*topology = NULL; CB
endCADDoc* pDoc = GetDocument(); ASSERT_VALID(pDo
c); part = pDoc->get_part(); if(! part) return N
ULL; // Note: we do not expect part to be NULL a
t this stage. topology = part->get_topology(); i
f(! topology) return NULL; three_d_name = parent_
tag%10000; three_d_body = topology->map_id_into_p
ointer(three_d_name); // Now we havea pointer to
the face/bendline to which the picked edge belong
s. three_d_type = three_d_body->get_type(); if(t
hree_d_type == BM_ENTITY_TYPE_FACE)offset = 30000;
if(three_d_type == BM_ENTITY_TYPE_BENDLINE)offse
t =60000; if(three_d_type == BM_ENTITY_TYPE_FORMI
NG)offset = 90000; loop_name = (clump_tag - offse
t)/100; edge_name = (clump_tag - offset)%100;if(l
oop_name == 0) return NULL; // This should never
be the case. //Now have the edge_name-th edge in
the loop_name-th loop of the face/bendline/formin
g. // Now we have the face/bendline to which the
edge belongs. if(mi_show_3d) two_d_body = three_d
_body->get_3D_version(); elsetwo_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->nex
t()) { if(! loop) return NULL; ++count; if(coun
t == loop_name) break;} } // Now we have the loo
p to which the edge belongs. if(loop == NULL) ret
urn NULL; // A trivial bendline was pic
ked. count= 0; for(edge = loop->get_first_edg
e(); edge; edge = (BM_EDGE *)edge->next()) {if(! e
dge) break;++count;if(count == edge_name) break;
} // Now we have the edge itself. return edge;/
* three_d_name = list_name/10000; loop_name = li
st_name%10000; // loop_name-th の中の edge_name
番目の edge loop_name /= 100; // loop of the t
hree_d_name 番目のthree-d-body, edge_name = list_
name%100; //最初のthree-d-bodyとして最初のベンド
ラインと共にに開始. if(three_d_name > (ml_num_ben
dlines + ml_num_faces)) return NULL;
// 描かれるものはフォーミングである。 if(! l
oop_name) return NULL; // 描かれるものはトリビア
ルなベンドラインである。 if(three_d_name > ml_n
um_bendlines) { // three_d_bodyは面である。 fo
r(three_d_body = part->get_face_list(); three_d_bo
dy;three_d_body = (BM_3D_BODY *)three_d_body->next
()) { if(! three_d_body) return NULL; ++coun
t; if((ml_num_bendlines + count) == three_d_name)
break;} } else { // three_d_body はベンドライ
ンである。 for(three_d_body = part->get_bendlin
e_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_s
how_3d) two_d_body = three_d_body->get_3D_versio
n();else two_d_body = three_d_body->get_flat(); i
f(! two_d_body) return NULL; if(loop_name == 1) l
oop = two_d_body->get_bloop(); else { count=
1; for(loop = two_d_body->get_first_hole(); loo
p; loop = (BM_LOOP*)loop->next()) { if(! loop) re
turn NULL; ++count; if(count == loop_name) brea
k;} }// この時点でエッジが属するループを持つ。 c
ount = 0; for(edge = loop->get_first_edge(); edg
e; edge = (BM_EDGE *)edge->next()) {if(! edge) bre
ak;++count;if(count == edge_name) break; } retur
n edge;*/} // This function returns the number of
items currently in the selection set.long CBendCA
DViewPart::get_number_of_selected_items(void){ re
turn m_selection_set.list_size();}/* これにより、
他のクラスが選択セットを得ることができる。選択され
た項目は、配列selected_items_array 内でパスバック
される; それは、この配列が十分な大きさであることを
保証するユーザの義務である。サイズnum_requested*2
の配列は確かに十分である。この関数は、もし多くのも
のが得られるときは、 num_requested 項目までパスバ
ックする。戻り値は、実際にパスバックされた項目の個
数である。配列中の復帰された項目のフォーマットは次
のように与えられる。 selected_items_array[2*i -2]
は描かれたエッジのOpenGL Display List idを含み、ま
たselected_items_array[2*i -1] はそのエッジに対す
るベンドモデルポインタを含む。例えば、 selected_it
ems_array[0], selected_items_array[1]は, 選択セッ
トなど, 選択セット中のnum_requested番目の項目に対
する配列[2*num_requested -2], 配列array[2*num_requ
ested -1] までの全てのものを含む。エッジポインタが
NULLのときは更に、N をこのエッジのopenG1 display l
ist id (N は長いタイプ)とする必要がある。ケース
A): もし N/10000 > (num_bendlines_in_part + num_f
aces_in_part) ならば、ユーザはN-(num bendlines +
num faces)のフォーミングを取り上げている。例えば、
num bendlines = 4, num faces = 3, num formings =
5,N/10000 =9, などのエッジポインタは空である。こ
のとき、ユーザは二回目のフォーミングを取り上げてい
る。ケースB): もし(N%10000)/100 == 0 (すなわち、N
の100 番目の桁がゼロ) ならば、ユーザはトリビアル
(曲げられてない)なベンドラインのセンタラインを取り
上げている。ベンドラインは(N/10000) 番目のベンドラ
インである。例えば、N/10000 = 3, エッジポインタは
NULLであり,(N%10000)/100=0 である。ユーザは、たま
たま曲げてない第三番面目のベンドラインを取り上げて
いる。(あなたが驚いても、この部分は少なくとも3 個
のベンドラインを持つことが保証される。)*/long CBen
dCADViewPart::get_selected_items(long num_requeste
d, long *selected_items_array) { if(selected_item
s_array == NULL) return 0; long i = m_selection_s
et.display(num_requested,selected_items_array); r
eturn i;} // This allows others to clear the sele
ction set.void CBendCADViewPart::clear_selection_s
et(void){int size =m_selection_set.list_size(); lo
ng *array = new long[(size<<1) + 1];m_selection_se
t.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();de
lete [] array;}// This function writes aRenderWare
matrix's rotation part into an array[16], which c
an be usedby// OpenGL. int CBendCADViewPart::conve
rt_rw_matrix_to_gl_array(RwMatrix4d *rw_matrix, do
uble *array){ RwReal rw_array[4][4], *test; test
= RwGetMatrixElements(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] = arra
y[7] = array[11] = 0.0; return 1;} // This fun
ction allows you to set the drawing mode:show_soli
d = 1 for solid, 0 for wireframe.// This function
assumes thatthe part has not changed.void CBendCAD
ViewPart::set_drawing_mode(int show_solid){ if(sh
ow_solid) OnViewShaded();else OnViewWireframe();}/
/ Thisfunction allows you to set the current view
of the part: show_3d = 1 for 3d version,// 0 for f
lat.// This function assumes that the part has not
changed.void CBendCADViewPart::set_current_view(i
nt show_3d){if(show_3d) OnShow3d();else OnShowFlat
();}// This allows you to set both solid/wireframe
(show_solid = 0/1) and flat/3d_version (show_3d =
0/1).// If flat is asked for, the picture shown i
s top view, zoomed-all.// If 3d is asked for and f
lat is currently in view, the picture shown is 3d,
isometric, zoomed-all.// If 3d is asked for and 3
d is already currently in view,the view volume is
not changed.// If part_has_changed is not zero, re
-faceting is done.void CBendCADViewPart::set_drawi
ng_view_mode(int show_solid, int show_3d, int part
_has_changed){int show_3d_isometric = 0;if( (!mi_s
how_3d) && (show_3d) )show_3d_isometric = 1;mi_sho
w_solid = show_solid;mi_show_3d = show_3d; 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; } mi_part_is_up_to_date = 1;if(part_ha
s_changed) { compute_part_centroid(part, 0, &m_
flat_part_centroid); // Compute 3d and flat part c
entroids. compute_part_centroid(part, 1, &m_3d_
part_centroid); }if(mi_show_solid) { // Renderwa
re stuff.if(mi_show_3d) { if(part_has_changed ||
(! m_3d_base_clump)){ i = facet_part_rw(par
t, &m_3d_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_3d_base_clump) ) return;}RwR
emoveClumpFromScene(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(par
t, &m_flat_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_3d_base_clump) ) return;}R
wRemoveClumpFromScene(m_base_clump); m_base_clu
mp = m_flat_base_clump;RwAddClumpToScene(m_scene,
m_base_clump);}}else {// OpenGl stuff. i= prep
are_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; if(mi_show_3d)
{mi_3d_is_up_to_date = 1; mi_flat_is_up_to_dat
e = 0;}else {mi_3d_is_up_to_date = 0; mi_flat_i
s_up_to_date = 1;}} mi_bbox_is_up_to_date = 0;if
(mi_show_3d) m_part_centroid = m_3d_part_centroid;
else m_part_centroid = m_flat_part_centroid;if(par
t_has_changed) {ml_num_faces= part->get_number_of_
faces();ml_num_bendlines = part->get_number_of_ben
dlines();ml_num_formings = part->get_number_of_for
mings();} ml_last_function_chosen = RETURN_FROM_D
IALOG_MODE;if(show_3d_isometric) { OnZoomAll();re
turn;}if(! mi_show_3d) { OnViewTop();return;}retu
rn;} 付録F コメント付きファイルを含むメインを自動寸法化するBM
APIの例/*一般的注意:---------------***************
---------------一般的注意:−自動寸法化パッケージ
はそのパートが既に更新されている(すなわちパートの
3Dバージヨンが既に計算されている)と仮定する。そ
のパートの現在の3Dバージヨンを取り、それを用い
る。−04/02/96付の自動寸法化は、単にパートの3Dバ
ージヨンに対する寸法を生成する。−04/02/96付の自動
寸法化は、パートが厚みを持って示されていると仮定す
る(すなわち、それは、我々が薄板の一側を示していな
いと仮定する。)。概要 :---------------***********
****---------------自動寸法は2種類の描画を行う:-
全てのベンドラインに対するフランジ長さ- 全てのベン
ドラインに対するベンドライン情報ベンドライン情報
は、それが係わるベンドラインを指示する小さなinfo-b
ox内に描かれれる。このinfo-boxを描画する際の唯一の
問題点は、ベンドラインが可視であるか、どこにinfo-b
oxを描くか(すなわち、それが良好に見え、他の成分に
干渉せず、例えば、他の事物と重ならないようにそれを
描く画面上の場所)、如何にそれをベンドラインと関係
付けるかということにある。この成分は比較的容易であ
る。ベンドラインのフランジ長さは、ベンドラインとこ
のベンドラインの側部の隣接フランジとの間の最大外側
距離により与えられる。ベンドラインは高々2つの隣接
フランジを持つことが出来、従って両隣接フランジに対
してフランジ長さを描かなければならないという点に注
意されたい。実際、フランジ長さは、我々がディメンシ
ョンポイントと呼ぶ点の間で(距離として)描かれる。
ここには2種類のディメンションポイントがある。第一
のものはベンドラインディメンションポイントである。
フランジ長さはベンドラインと隣接フランジの間の(最
大外側)距離なので、ベンドラインの側部のこれらのデ
ィメンションポイントはベンドラインディメンションポ
イントと呼ばれる。それらの位置は厳密にベンドライン
により定義される。1本のベンドラインは隣接フランジ
の各々に関して正確に2つのベンドラインディメンショ
ンポイントを持つことが出来る(少なくとも、 BendMod
el/BendCADの現在のバージヨンでは)という点に注意さ
れたい。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_DIMENSIONは、トップレベルのAuto
-Dimension対象物であり、通常はBM_PARTと共にBendCAD
書類の一部である。それは、自動寸法が描かれるBM_PART
に対するポインタ、並びに書類、ビユーおよびデバイス
コンテクトポインタを含む。それは更に、ビユーウイン
ドサイズ、ベンドラインの個数、 BM_AD_bendline対象
物などのようなハイレベルの情報を含む。将来(現在0
4/03/96),それは、ラインカラーやライン幅、
フォントサイズなどのようなペンやブラシ特性について
の情報を格納すべきである。BM_AD_bendline----------
----BM_AD_bendline は1つのBM ADベンドライン
に関係する全ての自動寸法情報を格納する。また、隣接
フランジの各々に対して内蔵の2つのベンドラインディ
メンションポイントを有する。また、隣接フランジの各
々に対してフランジディメンションポイントのリストへ
のポイントを有する。BM_AD_dim_corner--------------
--BM_AD_dim_cornerはディメンションポイント(ベンド
ラインかフランジのいずれか)である。ディメンション
ポイントは1または3BM_POINTのいずれかを有すること
が出来る。ディメンションポイントの1つの重要なメン
バは開放方向である。それは、このディメンションポイ
ントに関する実際のディメンションが描かれなければな
らない方向を指示する。更に、このディメンションポイ
ントが可視である方向を指示する。もしそれが可視のと
きは、それはそのBM_POINTの全ての画面座標を格納す
る。*/#ifndef BMAPI_AUTO_DIM_HXX_INCLUDED#define B
MAPI_AUTO_DIM_HXX_INCLUDED// include some BMAPI in
clude files#include "POINT.HXX"#include "VECTOR.HX
X"#include "LINE.HXX"#include "PLANE.HXX"#include
"CYLINDER.HXX"#include "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
classesclassCBendCADDoc ;class CBendCADViewPart ;
// Auto-Dimension classesclass BM_AD_dim_corner ;c
lass BM_AD_bendline ;class BM_AUTO_DIMENSION ;/***
******** ********** ********** ********** ********
** ********** ********** ********** ********** 自
動寸法定数********** ********** ********** *******
*** ********** ********** ********** ********** **
******** */// dimensionline length is 30 pixels#de
fine PIXELS_PER_DIMENSION_LINE30.0// arrow angle i
s 30 degrees//#define ARROW_ANGLE0.524// arrow len
gth is 15 pixels//#define PIXELS_PER_ARROW15.0// t
his is the distance tolerance used inAuto-Dimensio
n#define AUTODIM_DISTANCE_TOLERANCE0.001/*********
** ********** ********** ********** ********** ***
******* ********** ********** ********** この種の
対象物は、ディメンションを描くことが出来るディメン
ションポイントを表す。********** ********** ******
**** ********** ******************** ********** **
******** ********** */class BM_AD_dim_corner{frien
d BM_AUTO_DIMENSION ;friend BM_AD_bendline ;/*****
****** ********** ********** ********** **********
********** ********** ********** **********全ての
データメンバはPrivateなものである。********** ****
****** ********** ********** ********** **********
********** ********** ***********/private :// Aut
o-Dimension BM_AD_bendline object that owns this d
imension point// BM_AD_bendline *bend ;// this is
the 3D-body in the part thathas to be visible (act
ually some points on this// body have to be visibl
e) in order for this dimension point to be drawabl
e.// note : this is used only when we are in solid
mode.// // usually, for bend-dim points, this poi
nts to the bendline, and for flange-dim points //
points to the flange. // However, when this dimens
ion point contains only one point (point p), some
special // considerations come into effect.// BM_3
D_BODY *body_required_visible ;// this variable is
used only when we are drawing in a solid mode.//
if TRUE, we will ignore this dimension point as if
itwas not visible.// // in solid mode we will be
using this heuristic in order to save time.// when
two bendlines are using equivalent flange-dimensi
on points for (potentially)// displaying flange-le
ngth, we will onlycompute the visibility informati
on only// for the bendline (of these twobendlines)
which has the larger idx.// // this is initialize
d to FALSE,and set to TRUE only after all other di
m-point computations// have beendone.// int ignore
_in_solid_mode ;// Sometimes when the point in the
part for which we want to draw dimensions is a//
bendline (either inside or outside) such that the
radius and thickness both are not 0,// we haveto d
raw two short lines (as in the picture following)
that connect the//outsides of adjacent flanges. Ho
wever, sometimes (when both radius andthickness //
are 0, or the point is just an outside edge of a
face) we need only one point.// To capture these t
wo cases, we either compute three points between w
hich the // short line have to be drawn, or just o
ne point (in which case no short lines are neede
d).// // ------------ p2// | \|///
| p ----------bbFFFFFFFFFFFF// |
| bbb F// two | | bbb F// short
-----> | b F// lines | b bbFFFF
FFFFFFFF// |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 computed here. itis either 1 or 3.//
int num_of_points ;// // p is always the centerpo
int to which the dimension arrow should be connect
ed to// (actually it iswhat we call a 'dimension-l
ine-extension').// if we have computed more than 1
point, p1 and p2 are the side-points.// // IMPORT
ANT : p1 is on the plane of the adjacent body for
which the flange length is being drawn.// // Note
: point p is always computed.// BM_POINT p, p1, p
2 ;// this variable is used when this dimension po
int is a flange dimension point, and// the edge in
the flange, for which this flange dimension point
s wascomputed, // is adjacent to a bendline. adj_b
endline points to that bendline.// // this is used
to avoid drawing some flange-length twice. for ex
ample, in this picture// // B2-----------------/
/ |// | A// |//|// ----------
-----B1// // we want to draw dimensionsfor face A
in the middle only once. That means that if// we d
raw flangelength for bendline B1 with respect to
A, we should not draw it for // bendline B2 (with
respect to A).// BM_BENDLINE *adj_bendline ;// thi
s vector points to the direction in which the dime
nsion should be drawn for this dim-point.// // IMP
ORTANT : this vector should be normalized.// BM_VE
CTOR opening_direction ;// // if this is TRUE, we
can reverse the opening_direction if we need.// so
metimes the dimension point correcponds toan extre
me point of an arc. in that case it does// not mat
ter on which side we are drawing the dimension arc
(ie. we can reverse the opening direction).// int
can_reverse_opening_dir ;// // these variable are
used only when this dimension point is actually d
rawn.// pos_len is the lengthof the dimension-line
-extension drawn in the direction of the opening v
ector.// neg_len is the length of the dimension-li
ne-extension drawn in the direction opposite to //
the opening vector.// // they are initiallyset to
0 when the visibility of this point is computed./
/ // the purposeis that we can use them to avoid r
edrawing the same extension line, ifseveral // oth
er dimension points need it.// // Note : as of 04/
02/96 these points are not used. KK.// double pos_
len, neg_len ;// +1, this dimension point is visib
le and the dimension arc can be drawn for this poi
nt.// 0, this dimension point is not visible.// -
1, we don't know if thisdimension points is visibl
e.// // initially we set this to -1 and use it to
compute the visibility information on demand// (i
e. only when we want to know if this points is vis
ible. sometimes we don't care).// int visible ;//
these are the actual view window coordinates of al
l 3 points.// int screen_x, screen_x1, screen_x2 ;
int screen_y, screen_y1, screen_y2;// // this is t
he z-buffer value of the point p when rendered.//
double z_buf_value ;// this is used to construct l
ists of dim-points.// BM_AD_dim_corner *next ;/***
******** ********** ********** ********** ********
** ********** ********** ********** **********Priv
ateのメンバ関数。自動寸法によってのみ用いられる。*
********* ********** ********** ******************
** ********** ********** ********** ***********///
this functioncomputes the visibility of this dime
nsion point.// it handles wireframeand solid modes
separately.// this function checks strict visibil
ity.//void compute_visibility(CBendCADViewPart *vi
ew) ;// this function willdraw the dim-point in th
e given device context.// this is really just adeb
ug function.// void draw_with_dim_line(CBendCADVie
wPart *view, CDC *dc, double object_space_per_pixe
l) ;// given a bendline dimension point and a list
of flange dimension points, this function// retur
ns TRUE iff there is a way to display the flange-l
ength-dimension using these points// (ie. there is
a pair of points that is visible) or FALSE if no
t.// Ifit returns TRUE, it also returns the best f
lange dimension point ; as well as// the distance
between the bendline dimension point p and the bes
t flange dimension point p, // with respect to the
bendline dimension point.// // Note that the best
distance returned could be negative since it is t
he k-factor with respect// to the bendline-dimensi
on-opening-direction-vector.// Remember : bendline
-dimension-opening-direction-vector should be norm
alized.// // this function checks strict visibilit
y.// friend int compute_best_dim_pair(CBendCADView
Part *view, BM_AD_dim_corner *bend_dim_point,BM_AD
_dim_corner *flange_dim_list, double object_space_
per_pixel, // OUTPUT parametersdouble *best_distan
ce /* distance of the bestflange-dim points found
*/,BM_AD_dim_corner **best_flange_dim_point /*the
best flange-dim points */) ;// this function draws
one flange lengthdimension. the first argument is
a bendline dimension point,// the second is a fla
nge dimension point.// this function might allow c
ases wheresome dimension extension line is a littl
e-bit// outside the view window.// however, endpoi
nts of the dimension arrow have to be within the v
iewwindow.// friend void draw_dim_point(BM_AD_dim_
corner *bend_dim_point, BM_AD_dim_corner *flange_d
im_point, CBendCADViewPart *view, CDC *dc, double
object_space_per_pixel) ;/*********** ********** *
********* ********** ********** ********** *******
*** ********** **********公共のメンバ関数*********
* ********** ********** ********** ********** ****
****** ********** ********** ***********/public :B
M_AD_dim_corner(void) ;// this constructor is for
creating a dimension point that has only one point
(pointp) in it.// BM_AD_dim_corner(BM_POINT const
& p, BM_AD_bendline *bend, BM_3D_BODY *body_requir
ed_visible, BM_VECTOR const& opening_direction, in
t reverse_bit, BM_AD_dim_corner **prev, BM_BENDLIN
E *adj_bendline) ;// this constructor is for creat
ing a dimension point that has 3 points in 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_visible, BM_VECTOR const& o
pening_direction, int reverse_bit, BM_AD_dim_corne
r **prev,BM_BENDLINE *adj_bendline) ;// to assign
one dimension point to anotherdimension point// it
copies contents exactly. not sure if it is a very
useful function.// void operator=(BM_AD_dim_corne
r const &) ;// this function will return TRUE iff
the given point is, for the purpose of drawingdime
nsions,// the same as this point. // Two dimension
points points are equivalent iff the point p of o
ne of them is on the// line defined bythe line (po
int p, opening direction) of the other dimension p
oint,// and their opening directions match.// // h
ere we depend on the fact that opening vectors are
normalized.// // it returns 2 iff both points p m
atch, otherwise 1.// int operator==(BM_AD_dim_corn
er const& another_dim_point) ;} ;/*********** ****
****** ********** ********** ********** **********
********** ********** ********** この種の対象物
は、1ベンドラインに係わる自動寸法化データを表す。
ベンドラインに対する基本のAD操作は隣接するフラン
ジ長さを描くことである。技術的注意 :- tベンドライ
ンディメンションポイントとフランジディメンションポ
イントの開放方向ベクトルは相関付けされない。それ
は、あなたは、同じ開放方向を持つ2点に対シテチェッ
クするべきである。- アルゴリスム:先ず、我々は全て
のベンドラインに対する全てのベンドラインディメンシ
ョンポイントを計算する。次に、我々は、全てのベンド
ラインに対する全てのフランジディメンションポイント
を計算する。その理由は、我々がフランジディメンショ
ンポイントを計算するとき、フランジ内の、および他の
ベンドラインに隣接する幾つかのエッジがあるというこ
とである。全てのベンドラインディメンションを先ず計
算するときは、他のBM_AD_bendline構造のベンドライン
ディメンションポイントからこれらのベクトルを取るこ
とが出来る。********** ********** ********** *****
***** ********** ********** ******************** *
********* */class BM_AD_bendline{friend BM_AUTO_DI
MENSION ;friend BM_AD_dim_corner ;/*********** ***
******* ********** ********** ********** *********
* ********** ********** **********全てのデータメン
バはprivateなものである。********** ********** ***
******* ********** ********** ********** *********
* ********** ***********/private :/***************
****** ********** ********** ********** **********
********** ********** **********これらのデータメ
ンバはコンストラクタにより設定される。********** *
********* ********** ********** ********** *******
*** ********** ********** ***********/// informati
on stored in this BM_AD_bendline object refers to
this bendline.// ie. this dimension point is drawn
to show the flange length of this bendline.// BM_
BENDLINE *bend ;// this object belongs to this Aut
o-Dimension object.// BM_AUTO_DIMENSION *parent ;/
*********** ********** ********** ********** *****
***** ********** ********** ********** **********
これらのデータメンバは、ベンドラインディメンション
ポイントデータ構造が、 BM_AD_bendline::compute_BM_
AD_bendline(...).で計算されるとき計算される。*****
***** ********** ********** ******************** *
********* ********** ********** ***********/// if
FALSE, this data for this object has not been yet
computed, or the computation failed.// this means
that this object will always be ignored, no matter
what.// this can be set to TRUE only by BM_AD_ben
dline::compute_BM_AD_bendline(...).// int data_val
id ;// number of adjacent bodies for which we have
to draw dimensions. either 0, 1 or 2.// int num_o
f_adjacent_bodies ;// every bendline is adjacent t
o at most two bodies.// either of these can be NUL
L. you should always check for that.// // adj_body
1 is the adjacent body that has the smaller idx.//
adj_body2 is the adjacent body that has the large
r idx.// BM_3D_BODY *adj_body1 ;BM_3D_BODY *adj_bo
dy2 ;//this is the flange length with respect to e
ach of the adjacent bodies//double fl1 ;double fl2
;/*These parameters are computed some time during
the process and are needed later, so forperforman
ce reasons we store them so that we don't have to
recompute them later.Each of them is a vector poin
ting towards the adjacent body (from the bendline)
and ison a plane tangent to end end-point of the
bend-arc touching the adjacent body.*/BM_VECTOR si
de_vector1 ;BM_VECTOR side_vector2 ;/*これらのパラ
メータは、プロセス中にしばしば計算され、後に必要と
され、そこで性能理由に対して我々はそれらを、我々が
それらを後に再計算する必要がないように格納する。そ
れらの各々は(ベンドラインから)隣接体に向け指示す
るベクトルであり、隣接体に接触するベンドアークの端
点に対して接線をなす平面上にある。 これらは主要デ
ータ構造の幾つかである。 各々の隣接体に対して、ベ
ンドラインの各々の端点(すなわち、左および右)に対
して1つの2つ端点を持つ。これらの点は、フランジ長
に対する寸法がベンドラインで(すなわち、ベンドライ
ンの側部で)描くことが出来る点を特定する。注意:現
在(04/02/96)、我々は全てのベンドラインに
おいてディメンションを描くため正確に2つの可能な点
を考える。これらの2つの点はベンドラインセンタライ
ンの方向のベンドラインの2つの最端点である。注意:
これらはベンドラインのベンドラインディメンションポ
イントと呼ばれる。注意:これらの点は、例えadj
body1およびadjbody2が空であっても常に
計算される。*/BM_AD_dim_corner bend_body1_point_le
ft, bend_body1_point_right ;BM_AD_dim_corner bend_
body2_point_left, bend_body2_point_right ;// these
variables indicate whether the left(right) bendli
ne dimension points // with respect to adj-body1 a
nd adj-body2 are respectively equivalent.// these
points should be computed right after bend_body1_p
oint_left, bend_body1_point_right,// bend_body2_po
int_left, bend_body2_point_right are computed.// /
/ if 0, they are not equivalent.// if 2, they are
equivalent, and points p match.// if 1, they are e
quivalent, but points p don't match (ie. on the sa
me line, but somedistance apart).// // for us, equ
ivalence value 2 is the only really useful one, be
cause in that case we can // trust that when one i
s visible,the other is too, without checking. in t
hat case they have the// same screen coordinates a
s well.// // note the same means not the same poin
ters, but the contents are equivalent.// int body1
2_left_the_same ;int body12_right_the_same ;/*ここ
にディメンションポイントの2つのリストがある。1つ
はadj-bodyに関するもので、他はadj−body2に
関するものである。両リストはフランジ長ディメンショ
ンポイントである点を含む。注意:これらはベンドライ
ンのフランジディメンションポイントと呼ばれる。*/BM
_AD_dim_corner*body1_points ;BM_AD_dim_corner *bod
y2_points ;/*********** ******************** *****
***** ********** ********** ********** **********
**********これらのデータメンバは、ディメンションが
描かれるとき用いられる。********** ********** ****
****** ********** ********** ********** **********
********** ***********/// if this is TRUE, this be
ndline structure should be ignored for the purpose
of drawing dimensions.// this is usually used whe
n we have a simultaneous bendline. in that case we
have to draw//dimensions for only one of them, th
e rest should be ignored.// int ignore ;// if TRU
E, the adjacent body already has its flange length
drawn.//// if the value is 2, this bendline drew
the flange dimension with respect to the adj body.
// if the value is 1, some other bendline drew the
flange dimension with respect to the adj body.//
int body1_drawn ;int body2_drawn ;// when we draw
flange length for adjacent bodies, we will memoriz
e the point at which the// dimensions were drawn./
/ actually the dimensions are always drawn between
two points - one at the bendline,// theother at t
he farthest point on the adjacent body (ie. bendli
ne dimension point and// flange dimension point)./
/ // the reason we need to memorize these points i
s that sometimes the flange-length-dimension// wit
h respect to one bendline is also the flange-lengt
h dimension with respect tothe// other bendline. i
n that case we want to avoid drawing the same thin
g twice.// // the first two points are bendline di
mension points.// other two are flange dimension p
oints.// // reason #2 : when we draw bendline dime
nsions with respect to adj-body1 and adj-body2,//
it depends whether the bend angle is acute or not.
if the bend angle is not more than// 90 degrees,
then most likely we will be able to use the same d
imension-point at the bendline// to draw both flan
ge length's. However, if the bend angle is more th
an 90 degrees, we will// be using the tangent-dime
nsion-point at the bendline and these points are d
ifferent for// each adjacent body. In general, we
want to know, before we draw a dimension-pointat a
// bendline, if we can use any of the dimension-po
ints already drawn at this bendline.// // note the
se points do not have to part of this AD_bendline
structure.// BM_AD_dim_corner *drawn_bend_dim_poin
t1 ;BM_AD_dim_corner *drawn_bend_dim_point2 ;BM_AD
_dim_corner *drawn_flange_dim_point1 ;BM_AD_dim_co
rner *drawn_flange_dim_point2 ;/*********** ******
************** ********** ********** ********** **
******** ********** **********Privateメンバ−関数*
********* ********** ********** ********** *******
*** ********** ********** ********** ***********//
/ This function computes bendline dimension points
of this BM_AD_bendline structure.// Notethat bend
-dimension points will always be computed, even if
adj_body1 and adj_body2// are NULL.// int compute
_BM_AD_bendline(void) ;// This function computes f
lange dimensions points of this BM_AD_bendline str
ucture// with respect to one adjacent body.// int
compute_BM_AD_flange_points(BM_3D_BODY *adj_body)
;// This function computes the visibility of all
bendline dimension points of the bendline.// note
the the visibility of bend-dimension points with r
espect to adj-body1 is always// computed, even if
adj_body1 pointer is NULL.// This is needed for dr
awing bendline info-boxes.// void compute_bendline
_dim_points_visibility(void) ;// this function com
putes which dimension points are best to draw flan
ge length for this bendline.// // this function do
es it strictly for one bendline.// void compute_di
m_points_to_display_indiv(BM_AD_bendline *best_AD_
bendline[2] /* best AD_bendline structure so far *
/, BM_AD_dim_corner *bodies_bend_flange[6] /* 0,1
is bend-dim points; 3,4 is flange-dim points; 4,5i
s flange lists */,double distance_and_z[4] /* 0,1
is distance; 3,4 isz-buf */) ;// this function doe
s it for a given bendline, taking into account sim
ultaneous bendlines.// this function uses the prev
ious function.// void compute_dim_points_to_displa
y(void) ;// this function draws flange length dime
nsions for this bendline.// it uses the informatio
n computed by compute_dim_points_to_display() func
tion.// void draw_dimension_points(void) ;/*******
**** ********** ********** ********** ********** *
********* ********** ********** **********公共メン
バ−関数********** ********** ********** *********
* ********** ********** ********** ***************
******/ public :// some trivial const
ructors, destructors.BM_AD_bendline(BM_AUTO_DIMENS
ION *owner, BM_BENDLINE *bendline) ;~BM_AD_bendlin
e(void) ;} ;/*********** ********** ********** ***
******* ********** ********** ********** *********
* ********** この対象物は部分に対して自動ディメン
ションを生成するために用いることが出来る。********
** ********** ********** ********** ********** ***
******* ********** ********** ********** */class B
M_AUTO_DIMENSION{friend BM_AD_dim_corner ;friendBM
_AD_bendline ;/*********** ********** ********** *
********* ********** ********** ********** *******
*** **********すべてのデータメンバはprivateであ
る。********** ********** ********** ********** **
******** ********** ********** ********** ********
***/private :// this is the document to which this
auto-dim object is attached to.// also, this is w
here we get the part.// CBendCADDoc *doc ;// view
in which we draw the dimensions.// usually the vie
w attached to the document.// CBendCADViewPart *vi
ew ;int view_size_x, view_size_y ;// device contex
t in which we draw the dimensions.// CDC *dc ;// t
his is the part for which we will create dimension
s.// BM_PART *part ;// is TRUE iff 3D view is bein
g displayed, FALSE if flat.//int view_type ;// hal
f of the metal thickness// double half_metal_thick
ness ;// if TRUE, we need to recompute auto dimens
ion bendline and point data structures// int dirty
;// number of bendlines in the part// int num_of_
bendlines ;// this is an array of bendlines for wh
ich flange length has to be drawn.// BM_AD_bendlin
e **bends ;// this is the distance in object space
that gets mapped into one pixel on the screen.//
weuse it to draw lines of fixed pixel length (in t
hat case object-space length varies).// double obj
ect_space_per_pixel ;// if this variable is TRUE,
it will set the flag which will trigger// auto-dim
ensions to be drawn to FALSE in the view class, on
ce dimensions are drawn.// however, once it is don
e, this variable will be set to FALSE automaticall
y.// int reset_view_to_false_once_drawn ;// every
time we construct new dim-point data structures, w
e set this to FALSE.// when points which can be ig
noredin solid mode have been computed, we set it t
o TRUE.// int points_to_ignore_in_solid_computed ;
// pointer to mesh for determining clear areas of
the screen to draw dimension info//CAutoDimRgnMesh
*pMesh;// region tokeep track of dirty screen are
as//CRgn* pDirtyRegion;public:// Booleansfor the s
how state of dimension info//BOOL m_bShowFlangeDi
m;BOOL m_bShowBendDim;BOOL m_bShowPartDim;// COLOR
REFs for drawing dimensions//COLORREF m_crFlange;C
OLORREF m_crBend;COLORREF m_crPart;// pointers to
fonts//CFont* m_pFlangeFont;CFont* m_pBendFont;CFo
nt* m_pPartFont;// line and arrow parameters//int
m_nLineStyle;int m_nLineWeight;// in pixelsint m_n
ArrowStyle;int m_nArrowAngle;// in degreesint m_nA
rrowLength;// in pixels/*********** ********** ***
******* ********** ********** ********** *********
* ********** **********Privateメンバ関数**********
********** ********** ********** ********** *****
***** ********** ********** ***********/private :/
/ This function is used to propagate the effects o
f drawing aflange length for a given bendline,// t
o account for the fact that theflange dimension po
int is adjacent to the given adj-body.// it return
s TRUE iff the adj-bend will be marked as drawn as
well with respect to thegiven flange.// int compu
te_effects_flange_length_drawn(BM_BENDLINE *bendli
ne, BM_3D_BODY *adj_body /* flange length with res
pect to this bodyare being drawn */, BM_AD_dim_cor
ner *bend_dim_point /* bend dim point for bendline
*/, BM_AD_dim_corner *flange_dim_point /* flange
dim pointsfor bendline */, BM_BENDLINE *adj_bend /
* flange dim points is adjacentto this bendline *
/) ;// this function returns a pointer to the BM_A
D_bendline structure that contains data // about t
he given bendline.// BM_AD_bendline *get_AD_bend_s
tructure(BM_BENDLINE *bendline) ;// this function
will return TRUE iff adj_bend has a flange-dimensi
on point with respect to the// given flange, that
is adjacent to the given bendline.// // ahandy fun
ction.// int check_two_bendlines_adjacent_to_same_
flange(BM_BENDLINE *bendline, BM_3D_BODY *flange,
BM_BENDLINE *adj_bend) ;// just a debug function//
void test_draw(void) ;// Check if we can ignore s
ome points in solid mode.// // in solid mode we wi
ll be using this heuristic inorder to save time.//
when two bendlines are using equivalent flange-di
mension points for (potentially)// displaying flan
ge-length, we will only compute the visibility inf
ormation only// for the bendline (of these two ben
dlines) which has the higher idx.// void compute_p
oints_to_ignore_in_solid(void) ;// this function d
raws a box with bendline data for every bendline./
/ void draw_bendline_data(CDC *pdc) ;/***********
******************** ********** ********** *******
*** ********** ********** **********公共メンバ関数
********** ********** ********** ********** ******
**** ********** ********** ********** ***********/
public :BM_AUTO_DIMENSION(CBendCADDoc *BendCAD_do
c) ;~BM_AUTO_DIMENSION(void) ;// this function ret
urns a (p->p2) vector for a given bendline with re
spect to a given adj-body.// // It also computes a
line between the p2 points of the bend dimension
points of the adjacent bendline // with respect to
this flange.// BM_VECTOR const& compute_bend_dire
ction_vector(BM_BENDLINE *bendline,BM_3D_BODY *adj
_body, BM_LINE *p2_line) ;// destroy the contents
of thisAuto-Dimensions object,// void delete_conte
nts(void) ;// To set a new part. This updates the
view class pointer as well.// void set_part(BM_PAR
T *new_part) ;// to force AD to recompute the dime
nsion points.// inlinevoid invalidate(void) { dirt
y = 1 ; }// get current view type when points were
computed// inline int get_view_type(void) const
{ return view_type ; }// this function will build
auto dimension bendline and point datastructures./
/ // This is the main function for computing dimen
sion points.// int compute_auto_dimension_data(voi
d) ;// draw flange dimension data//void draw_dim_p
oint(BM_AD_dim_corner *bend_dim_point, BM_AD_dim_c
orner *flange_dim_point, CBendCADViewPart *view, C
DC *dc, double object_space_per_pixel);// to draw
part dimensions in this device context// int draw_
auto_dimensions(CDC *target_dc) ;// Used with draw
_auto_dimensions toconstruct a geometric pen// wit
h user-defined styles. This is necessaryto draw pa
tterned thick lines.//CPen* create_auto_dim_pen(CP
en* pPen, int nLineStyle, int nLineWeight, COLORRE
F cr) ;// this will enable us todraw part dimensio
n only once//inline void disable_view_dimensions_f
lag_next_time(void) { reset_view_to_false_once_dra
wn = 1 ; }} ;#endif // BMAPI_AUTO_DIM_HXX_INCLUDED 付録G 機能を描く自動寸法化の例。これらの関数は、デイメン
シヨンポイントが既に計算されていることを仮定する。
【0361】///*ディメンションポイントを計算する関
数は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 che
ck if points p1 and p2 actually// map into the sam
e bendline/flange points. in solid mode we need to
check.// check if we have solid or wireframe mod
e.if (view->get_drawing_mode()) goto solid_picture
;/*ワイヤフレームは、このディメンションポイントが
実際に最前面にある3D体か否かをチェックしない(原
文不明) ワイヤフレームモードでは、我々は、ビユー
ウインドにおける全ての事態が可視であると仮定する。
*/// get visibility datai = view->map_point_to_clo
sest_edge(p, &screen_x, &screen_y, &z_buf_value, N
ULL) ;if (! i) return ;if (num_of_points > 1) {i =
view->map_point_to_closest_edge(p1, &screen_x1, &s
creen_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 have to 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_requi
red_visible)->get_adj_list())->find_lowest_id_adj_
body() ;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 ;// handle cases when t
here 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
haveto check any of the adjacent bodies.if (num_o
f_points < 2) {// if thisis 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 ifpoints p1 and p2
are in the view window as well.i = view->map_poin
t_to_closest_edge(p1, &screen_x1, &screen_y1, &z_b
uf, NULL) ;if (! i) return ;i = view->map_point_to
_closest_edge(p2, &screen_x2, &screen_y2, &z_buf,N
ULL) ;if (! i) return ;BM_VECTOR v_pp1(p,p1) ;BM_V
ECTOR v_pp2(p,p2) ;BM_POINT p_center ;double angle
_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) ;doubl
e 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_b
ody_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, NUL
L, &i, &screen_x, &screen_y, &z_buf_value) ;if (!
i) return ;// ポイントp1およびp2は3D体上になければ
ならない。i = view->is_3d_body_near_point(p1, visi
ble_bodies, &visibility_count,&screen_x1, &screen_
y1, &z_buf) ;if (! i) return ;i = view->is_3d_body
_near_point(p2, visible_bodies, &visibility_count,
&screen_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_d
im_line(CBendCADViewPart *view, CDC *dc, double ob
ject_space_per_pixel){int i, j ;double x ;static P
OINT points[3] ;BOOL res ;// if this point is not
known to be visible, return.if (visible < 1) retur
n ;if (num_of_points < 1) return ;points[1].x = sc
reen_x ;points[1].y = screen_y ;// draw dimension
lineBM_POINT p_dim_line(p + (PIXELS_PER_DIMENSION_
LINE * object_space_per_pixel)*opening_direction)
;view->map_point_to_closest_edge(p_dim_line, &i,
&j, &x, NULL) ;points[2].x = i ;points[2].y =j ;if
(can_reverse_opening_dir) {p_dim_line = p + (-PIX
ELS_PER_DIMENSION_LINE * object_space_per_pixel)*o
pening_direction ;view->map_point_to_closest_edge
(p_dim_line, &i, &j, &x, NULL) ;points[1].x = i ;p
oints[1].y =j ;res = dc->Polyline(points + 1, 2) ;
points[1].x = screen_x ;points[1].y = screen_y ;}e
lse res = dc->Polyline(points + 1, 2) ;if (num_of_
points < 2) return ;points[0].x = screen_x1 ;point
s[0].y = screen_y1 ;points[2].x = screen_x2 ;point
s[2].y = screen_y2 ;res = dc->Polyline(points,
3);}/*この関数は1フランジ長ディメンションを描く。
第一の引数はベンドラインディメンションポイントで
あり、第二はフランジディメンションポイントである。
*/void BM_AUTO_DIMENSION::draw_dim_point(BM_AD_dim
_corner *bend_dim_point, BM_AD_dim_corner *flange_
dim_point, CBendCADViewPart *view, CDC *dc, double
object_space_per_pixel){int i, j ;double x, y, z,
dotp, half_dim_line ;BOOL res ;// points with scr
een coordinates. Windows type.static POINT points
[3] ;// these variable store the coordinates of th
e dim-line-extension endpointsdouble bend_end_x, f
lange_end_x ;BM_POINT bend_end_p, flange_end_p ;BM
_VECTOR end_v(bend_dim_point->opening_direction) ;
// these variables store arrow head endpointsBM_PO
INT bend_arrow_p, flange_arrow_p ;// compute the d
imension line extensionBM_VECTOR v((flange_dim_poi
nt->p) - (bend_dim_point->p)) ;x = v % (bend_dim_p
oint->opening_direction) ;if (fabs(x) > AUTODIM_DI
STANCE_TOLERANCE) { // we have to extend at least
one dimension linehalf_dim_line = (PIXELS_PER_DIME
NSION_LINE* object_space_per_pixel)/2.0 ;// here w
e will first compute extension lines, then the arr
ow, and then the dimension points themselvesif (x
< 0.0) {// here we assume that for bendline, we ca
nnot reverse the opening direction.// it must be t
hat the flange-dim points has a valid opening dire
ction in the same direction// as the bend-dim poin
t.// // arrow pointis to the right of the bend-dim
point.bend_arrow_p = (bend_dim_point->p)+ half_di
m_line*end_v ;if (! view->map_point_to_closest_edg
e(bend_arrow_p, &i, &j, &y, NULL)) return ;points
[0].x = i ;points[0].y = j ;flange_arrow_p = (flan
ge_dim_point->p) + (-x + half_dim_line)*end_v ;if
(! view->map_point_to_closest_edge(flange_arrow_p,
&i, &j, &y, NULL)) return ;points[1].x = i ;point
s[1].y = j ;half_dim_line *= 2.0 ;bend_end_x = hal
f_dim_line ;flange_end_x = -x + half_dim_line ;ben
d_end_p = bend_dim_point->p + bend_end_x*end_v ;fl
ange_end_p = flange_dim_point->p + flange_end_x*en
d_v ;}else {// here we assume that for bendline, w
e cannot reversethe opening direction.dotp = (bend
_dim_point->opening_direction) % (flange_dim_point
->opening_direction) ;// first lets try if we can
reverse the flange-dim point opening directionif
(dotp < 0.0 || flange_dim_point->can_reverse_openi
ng_dir) {// try to draw the arrow in the middle///
/ arrow point is midway between flange- and bend-d
im points.z = x/2.0 ;bend_arrow_p = (bend_dim_poin
t->p) + z*end_v ;if (! view->map_point_to_closest_
edge(bend_arrow_p, &i, &j, &y, NULL)) goto try_oth
er_direction ;points[0].x = i ;points[0].y = j ;fl
ange_arrow_p = (flange_dim_point->p) + (-z)*end_v
;if (! view->map_point_to_closest_edge(flange_arr
ow_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_lin
e ;bend_end_p = bend_dim_point->p + bend_end_x*end
_v ;flange_end_p = flange_dim_point->p + flange_en
d_x*end_v ;goto begin_to_draw ;}try_other_directio
n :if(dotp > 0.0 || flange_dim_point->can_reverse_
opening_dir) {// arrow point is to the right of th
e flange-dim point.bend_arrow_p = (bend_dim_point-
>p) + (x + half_dim_line)*end_v ;if (! view->map_p
oint_to_closest_edge(bend_arrow_p, &i, &j, &y, NUL
L)) return ;points[0].x = i ;points[0].y =j ;flang
e_arrow_p = (flange_dim_point->p) + half_dim_line*
end_v ;if (!view->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_en
d_x =x + half_dim_line ;flange_end_x = half_dim_li
ne ;bend_end_p = bend_dim_point->p + bend_end_x*en
d_v ;flange_end_p = flange_dim_point->p + flange_e
nd_x*end_v ;}else return ; // failure, cannot draw
because opening direction don't match or not visi
ble.}}else { // no need to extend dimensionlines//
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 ;fla
nge_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 arrow endpoi
ntsif (! view->map_point_to_closest_edge(bend_arro
w_p, &i, &j, &y, NULL)) return ;points[0].x = i ;p
oints[0].y = j ;if (! view->map_point_to_closest_e
dge(flange_arrow_p, &i, &j, &y, NULL)) return ;poi
nts[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->Polyli
ne(points, 2) ;// draw arrowsBM_VECTOR v_arrow(fla
nge_arrow_p - bend_arrow_p) ;x = v_arrow.Len() ; /
/ this is the real flange length// change to solid
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_DISTA
NCE_TOLERANCE) {if (dy/dx > 0.0) center_y -= font_
height ;}center_x += 3 ; // move the beginning to
the right so that it won't overlap the arrow line.
CString str;str.Format("%6.4f",x);CSize sizeTextEx
tent = dc->GetTextExtent(str);if (pDirtyRegion !=
NULL){CPoint pntText(center_x, center_y);CRect rec
tText(pntText, sizeTextExtent);if (!pDirtyRegion->
RectInRegion(&rectText))dc->TextOut(center_x, cent
er_y, str);CRgn rgn;rgn.CreateRectRgn(center_x, ce
nter_y, center_x + sizeTextExtent.cx, center_y + s
izeTextExtent.cy);pDirtyRegion->CombineRgn(pDirtyR
egion, &rgn, RGN_OR);}else{pDirtyRegion = new CRgn
();pDirtyRegion->CreateRectRgn(center_x, center_y,
center_x + sizeTextExtent.cx, center_y + sizeText
Extent.cy);dc->TextOut(center_x, center_y, str);}/
*bend-dim-pointsにp1,p2を描く必要があるならば*/poi
nts[1].x = bend_dim_point->screen_x ;points[1].y =
bend_dim_point->screen_y ;if (bend_dim_point->num
_of_points > 1) {points[0].x = bend_dim_point->scr
een_x1 ;points[0].y = bend_dim_point->screen_y1 ;p
oints[2].x = bend_dim_point->screen_x2 ;points[2].
y = bend_dim_point->screen_y2 ;res = dc->Polyline
(points, 3) ;}// draw dimension line extensionview
->map_point_to_closest_edge(bend_end_p, &i, &
j, &x, NULL) ;points[2].x
= i ;points[2].y = j ;re
s = dc−>Polyline(points +
1, 2) ;/*flange−dim−poin
tsに対してp1,p2を描く必要があるならば*/points
[1].x = flange_dim_point->screen_x ;points[1].y =
flange_dim_point->screen_y ;if (flange_dim_point->
num_of_points > 1) {points[0].x = flange_dim_point
->screen_x1 ;points[0].y = flange_dim_point->scree
n_y1 ;points[2].x = flange_dim_point->screen_x2 ;p
oints[2].y = flange_dim_point->screen_y2 ;res = dc
->Polyline(points, 3) ;}// draw dimension line ext
ensionview->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戻
す。もしそれがTRUEのときは、それは更に最良のフラン
ジディメンションポイントを戻し;同様にベンドライン
ディメンションポイントに関してベンドラインディメン
ションポイントpと最良のフランジディメンションポイ
ントpの間の距離を戻す。戻された最良の距離は、それ
が、bendline-dimension-opening-direction-vectorに
対してK因子のために負になり得る。ここでこの関数
は、dimension-extension-linesが:1つのdimension-ext
ension-lineが単位長さであり、また他のものが、第一
のものに達するのに必要な程度に長いように描かれるこ
とを仮定する。すなわち、この関数はディメンションポ
イントの1つに隣接するディメンションアローを描く。
すなわち、それは2つのディメンションポイントの間の
ラインの途中の或る点でディメンションポイントを描く
ことを試みない。想起:bendline-dimension-opening-d
irection-vectorは規格化されるべきである。注意:こ
こでこの関数は、dimension-extension-linesが:1つのd
imension-extension-lineが単位長さであり、また他の
ものが、第一のものに達するのに必要な程度に長いよう
に描かれることを仮定する。すなわち、この関数はディ
メンションポイントの1つに隣接するディメンションア
ローを描く。すなわち、それは2つのディメンションポ
イントの間のラインの途中の或る点でディメンションポ
イントを描くことを試みない。注意:この関数におい
て、dim pointが可視でない場合直接チェックしない
(別の関数を呼び出す)。表示されているウインドウの
中にいくつかのdimension-extension-lineがあるかをチ
ェックする。注意:この関数において、ディメンション
アローが進む点をチェックする。それらが厳密にビユー
領域内に有ることを要求される。注意:この関数におい
て、実際には近似位置を用いる。すなわち、発見手法と
して。*/intcompute_best_dim_pair(CBendCADViewPart
*view, BM_AD_dim_corner *bend_dim_point,BM_AD_dim_
corner *flange_dim_list, double object_space_per_p
ixel,// OUTPUT parametersdouble *best_distance /*
見出された最良のflange-dimpoints の距離 */,BM_AD_d
im_corner **best_flange_dim_point /* 最良のflange-
dim points */){BM_VECTOR v ;BM_POINT dim_arrow_poi
nt ;int i, j, k ;double x, y, dotp ;// if the bend
line dimension point is not known to be visible, r
eturn FALSE.// otherwise we might be wasting our t
ime.if (bend_dim_point->visible < 1) return 0 ;//
scan the list of flange dimension pointsBM_AD_dim_
corner *temp_point, *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つのベンドライン
がフランジ長を表示するために(潜在的に)等価なflan
ge-dimension pointsを用いているときは、我々は単
に、より高いidxを持つベンドライン(これらの2つの
ベンドラインの)に対してのみ可視度を計算する。*/if
(view->get_drawing_mode() && temp_point->ignore_i
n_solid_mode)continue ;// compute a vector from be
nd-dim-p to flange-dim-pv = (temp_point->p) - (ben
d_dim_point->p) ;x = v % (bend_dim_point->opening_
direction) ;// check that opening directions are v
alid.// idea : if both vectors points in opposite
directions are we cannot reverse them,// we cannot
use these two dimension points to draw dimensions.
dotp = (bend_dim_point->opening_direction) % (temp
_point->opening_direction) ;if (dotp < 0.0 && ! te
mp_point->can_reverse_opening_dir && ! bend_dim_po
int->can_reverse_opening_dir) continue ;// check t
hat the point where the dimension arrow would go i
s in the view area// note : we will use half-of-th
e-minimal-extension-length as the unit separating
// zero and non-zero length extension lines.if (fa
bs(x) > AUTODIM_DISTANCE_TOLERANCE) {k = 0 ; // if
k is TRUE at the end, we can draw the dimension a
rrow pointif (x < 0.0) {//note : add space for a l
ine segment where we will draw the arrow// // chec
k if the directions agree. // we check this first,
because it would give us a smaller distance.if (d
otp > 0.0) {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 ;}// check that the extension of
the bend-dim-line is visible.// in that case the
openingdirection of the flange-dime-line does not
matter.if (!k && bend_dim_point->can_reverse_openi
ng_dir) {dim_arrow_point = (bend_dim_point->p) +
(x)*(bend_dim_point->opening_direction) ;if (view-
>map_point_to_closest_edge(dim_arrow_point, &i, &
j, &y, NULL)) k = 1 ;}}else { // x > 0.0// note :
add space for a line segment where we will draw th
e arrow.// // check if the extension line is visib
le.// we check this first, because it would give u
s a smaller distance.if (dotp < 0.0 || temp_point-
>can_reverse_opening_dir) {dim_arrow_point = (temp
_point->p) + (-x)*(bend_dim_point->opening_directi
on) ;if (view->map_point_to_closest_edge(dim_arrow
_point, &i, &j, &y, NULL)) k = 1 ;}// otherwise ch
eck if the directions agree.if (!k) {dim_arrow_poi
nt = (bend_dim_point->p) + (x)*(bend_dim_point->op
ening_direction) ;if (view->map_point_to_closest_e
dge(dim_arrow_point, &i, &j, &y, NULL)) k = 1 ;}}i
f (!k) continue ; // cannot draw the dimension arr
ow point}// check if visibility information is alr
eady computed.//if not, compute it. if flange dime
nsion points not visible, continue.if(temp_point->
visible < 0) {temp_point->compute_visibility(view)
;if (!temp_point->visible) continue ;}// check if
this new distance is the best distanceif (best_fd
p) {if (fabs(best_distance_so_far) > fabs(x)) {bes
t_fdp = temp_point ;best_distance_so_far = x ;}}el
se {best_fdp = temp_point ;best_dist
ance_so_far = x ;}// chec
k if we are done.// if we
have a point with a dist
ance 0, we are done since
we cannot find a better
point.if (best_fdp && fab
s(best_distance_so_far) <
= AUTODIM_DISTANCE_TOLERA
NCE) break ;}if (best_fd
p) {*best_distance = best
_distance_so_far ;*best_f
lange_dim_point = best_fd
p ;return 1 ;}return 0 ;}
/*********** ************
******** ********** *****
***** ********** ********
** ********** **********B
M_AD_bendline クラススタッフ********
** ********** ********** ********** ********** ***
******* ********** ********** ***********//*この関
数はベンドラインの全てのベンドラインディメンション
ポイントの可視度を計算する。注意: 時間の節約のため
に、我々は、体1 、22の左( 右) ポイントが等価である
か否かをチェックする。*/void BM_AD_bendline::compu
te_bendline_dim_points_visibility(void){CBendCADVi
ewPart *view = parent->view ;// here wealways comp
ute the visibility of adj-body1 bend-dimension poi
nts,// eventhough we don't check if adj_body1 poin
ter is NULL or not,// because wemight want to know
the visibility even if they don't exist.// // in
practice this should not be a problem because almo
st always there are two//adjacent bodies.// bend_b
ody1_point_left.compute_visibility(view) ;bend_bod
y1_point_right.compute_visibility(view) ;if (adj_b
ody2) {if (2 == body12_left_the_same) {if (bend_bo
dy2_point_left.visible = bend_body1_point_left.vis
ible) {// note we are switching pointsbend_body2_p
oint_left.screen_x = bend_body1_point_left.screen_
x ;bend_body2_point_left.screen_y= bend_body1_poin
t_left.screen_y ;bend_body2_point_left.screen_x1 =
bend_body1_point_left.screen_x2 ;bend_body2_point
_left.screen_y1 = bend_body1_point_left.screen_y2
;bend_body2_point_left.screen_x2 = bend_body1_poi
nt_left.screen_x1 ;bend_body2_point_left.screen_y2
= bend_body1_point_left.screen_y1 ;bend_body2_poi
nt_left.z_buf_value = bend_body1_point_left.z_buf_
value ;}}else bend_body2_point_left.compute_visibi
lity(view) ;if (2 == body12_right_the_same) {if (b
end_body2_point_right.visible = bend_body1_point_r
ight.visible) {// note we are switching pointsbend
_body2_point_right.screen_x = bend_body1_point_rig
ht.screen_x ;bend_body2_point_right.screen_y = ben
d_body1_point_right.screen_y ;bend_body2_point_rig
ht.screen_x1 = bend_body1_point_right.screen_x2 ;b
end_body2_point_right.screen_y1 = bend_body1_point
_right.screen_y2 ;bend_body2_point_right.screen_x2
= bend_body1_point_right.screen_x1 ;bend_body2_po
int_right.screen_y2= bend_body1_point_right.screen
_y1 ;bend_body2_point_right.z_buf_value =bend_body
1_point_right.z_buf_value ;}}else bend_body2_point
_right.compute_visibility(view) ;}// else adj_body
2 is NULL and there is nothing tocompute}/*この関
数はそれを1つのベンドラインに対して厳密に行う。重
要:それは単に、どの方法が最良なものかを決定する
が、ADが実際にそれをそのように行うか否かを決定す
ることはない。ここで、それは他のデータ構造を更新す
る何らかかの方法を実施する。端的には、それはADデ
ータ構造のいずれかを変えることはない。注意:始めは
何らのチェックもなされない。アイデア:この関数にお
いて、我々は、異なるbend-flange-dimポイントの組み
合わせに対する値を割り当てる発見的手法を用いる。最
終的には、我々は最良の組み合わせを選択する。我々が
用いる発見的手法は、ベンドおよびフランジdimポイン
トの間の距離の組み合わせ、プラスビユー画面からのbe
nd-pointの距離である。実際的なトリック:先ず我々
は、最も良く知られた距離の値が既に0であるか否かを
チェックする。もし0であるなら、我々は、この新しい
bend−dimポイントが良好なz−buf値を持つ
ときにのみ他のbend-dimポイントに対して最良の一致を
見出そうとする。注意:4部分のテストの後、私は、こ
れが丁度非常にわずかな改善を与えることを見出す。そ
れは恐らく5−10%KKである(原文不明)。*/void
BM_AD_bendline::compute_dim_points_to_display_ind
iv(BM_AD_bendline*best_AD_bendline[2] /* これまで
の最良のADベンドライン構造*/,BM_AD_dim_corner *bod
ies_bend_flange[6] /* 0、1はbend-dim構造であり、
3、4はflange-dimポイントであり、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 already have a distance 0 bend-flange
-dim points. if yes, go in only if the// new bend-
dim points has a strictlybetter z-buf value.if ((N
ULL == best_AD_bendline[0]) || distance_and_z[2] >
(bend_body1_point_left.z_buf_value + AUTODIM_DIST
ANCE_TOLERANCE) ||distance_and_z[0] > AUTODIM_DIST
ANCE_TOLERANCE) {if (compute_best_dim_pair(parent-
>view, &bend_body1_point_left, body1_points, paren
t->object_space_per_pixel, &best_distance, &best_f
dp)) {best_distance = fabs(best_distance) ;// chec
k 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_left.z_buf_value) < (distance_and_z[0]
+ distance_and_z[2])) {best_AD_bendline[0] = this
;bodies_bend_flange[0]= &bend_body1_point_left ;b
odies_bend_flange[2] = best_fdp ;bodies_bend_flang
e[4] = body1_points ;distance_and_z[0] = best_dist
ance ;distance_and_z[2] = bend_body1_point_left.z_
buf_value ;}}else {best_AD_bendline[0]= this ;bodi
es_bend_flange[0] = &bend_body1_point_left ;bodies
_bend_flange[2] = best_fdp ;bodies_bend_flange[4]
= body1_points ;distance_and_z[0] = best_distance
;distance_and_z[2] = bend_body1_point_left.z_buf_
value ;}}}// check if we already 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 (distance_and_z[2] > (bend_body1_point_r
ight.z_buf_value + AUTODIM_DISTANCE_TOLERANCE) ||
(NULL == best_AD_bendline[0]) || distance_and_z[0]
> AUTODIM_DISTANCE_TOLERANCE) {if (compute_best_d
im_pair(parent->view, &bend_body1_point_right, bod
y1_points, parent->object_space_per_pixel, &best_d
istance, &best_fdp)) {best_distance = fabs(best_di
stance);// check if the new point is betterif (bes
t_AD_bendline[0]) {// heuristic : if the sum of th
e z-buf value and distance is smallerif ((best_dis
tance + bend_body1_point_right.z_buf_value) < (dis
tance_and_z[0] + distance_and_z[2])) {best_AD_bend
line[0] = this ;bodies_bend_flange[0] = &bend_body
1_point_right ;bodies_bend_flange[2] = best_fdp ;b
odies_bend_flange[4] = body1_points ;distance_and_
z[0] = best_distance ;distance_and_z[2]= ben
d_body1_point_right.z_buf
_value ;}}else {best_AD_b
endline[0] = this ;bodies
_bend_flange[0] = &bend_b
ody1_point_right ;bodies_
bend_flange[2] = best_fdp
;bodies_bend_flange[4] =
body1_points ;distance_a
nd_z[0] =best_distance ;d
istance_and_z[2] = bend_b
ody1_point_right.z_buf_va
lue ;}}}}// check adjacen
t body2if (adj_body2 && !
(body2_drawn)) {// check
ifwe already have a dist
ance 0 bend−flange−dim po
ints. if yes, go in onlyi
f the// new bend−dim poin
ts has a strictly better
z−buf value.if ((NULL ==
best_AD_bendline[1]) || d
istance_and_z[3] > (bend_
body2_point_left.z_buf_va
lue + AUTODIM_DISTANCE_TO
LERANCE) || distance_and_
z[1] > AUTODIM_DISTANCE_T
OLERANCE) {if (compute_be
st_dim_pair(parent−>view,
&bend_body2_point_left,
body2_points, parent−>obj
ect_space_per_pixel, &bes
t_distance, &best_fdp))
{best_distance = fabs(bes
t_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_left.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_left ;bodies_
bend_flange[3] = best_fdp
;bodies_bend_flange[5] =
body2_points ;distance_a
nd_z[1] = best_distance ;
distance_and_z[3] = bend_
body2_point_left.z_buf_va
lue ;}}else {best_AD_bend
line[1] = this ;bodies_be
nd_flange[1] = &bend_body
2_point_left ;bodies_bend
_flange[3] = best_fdp ;bo
dies_bend_flange[5] = bod
y2_points ;distance_and_z
[1] = best_distance ;dist
ance_and_z[3] = bend_body
2_point_left.z_buf_value
;}}}// check if we alrea
dyhave a distance 0 bend−
flange−dim points. if ye
s, go in only if the// ne
w bend−dim points has a s
trictly better z−buf valu
e.if (distance_and_z[3] >
(bend_body2_point_right.
z_buf_value + AUTODIM_DIS
TANCE_TOLERANCE) || (NULL
== best_AD_bendline[1])
|| distance_and_z[1] > AU
TODIM_DISTANCE_TOLERANCE)
{if (compute_best_dim_pa
ir(parent−>view, &bend_bo
dy2_point_right, body2_po
ints, parent−>object_spac
e_per_pixel, &best_distan
ce, &best_fdp)) {best_dis
tance = fabs(best_distanc
e) ;// check if the new p
oint is betterif (best_AD
_bendline[1]) {// heurist
ic : if the sum of the z−
bufvalue and distance is
smallerif ((best_distance
+ bend_body2_point_righ
t.z_buf_value) < (distanc
e_and_z[1] + distance_and
_z[3])) {best_AD_bendline
[1] = this ;bodies_bend_f
lange[1] = &bend_body2_po
int_right ;bodies_bend_fl
ange[3] = best_fdp ;bodie
s_bend_flange[5] = body2_
points ;distance_and_z[1]
= best_distance ;distanc
e_and_z[3] = bend_body2_p
oint_right.z_buf_value
;}}else {best_AD_bendlin
e[1] = this ;bodies_bend_
flange[1] = &bend_body2_p
oint_right ;bodies_bend_f
lange[3] = best_fdp ;bodi
es_bend_flange[5] = body2
_points ;distance_and_z
[1] = best_distance ;dist
ance_and_z[3] = bend_body
2_point_right.z_buf_value
;}}}}}/*この関数は、ベンドラインに対する
フランジ長さを描く方法を決定する。これは、サブルー
チントシテ以前の関数を用いるものにおける以前の関数
とは異なっている。それは、ベンドラインに対するフラ
ンジ長ディメンションを描く方法、従って全てのデータ
構造を更新する方法を決定する。更に、それは同時のベ
ンドラインを考慮する。*/voidBM_AD_bendline::comput
e_dim_points_to_display(void){// qualification che
ckif (NULL == bend) return ;BM_AD_bendline *bl ;lo
ng i ;// these variable store the bendline dimensi
on data that will be used later to draw //0,1 is w
ith respect to adj-body1; 2,3 is with respect to a
dj-body2BM_AD_dim_corner *bodies_bend_flange_list
[6] ; // 0,1 is bend-dim points; 2,3is flange-dim
points; 4,5 is flange listsdouble distance_and_z
[4] ; // 0,1 is distance; 2,3 is z-buf// this is t
he bendline for which we will bedrawing the dimens
ions.// this is trivial when there is no simultane
ousbendlines.BM_AD_bendline *best_AD_bendline[2] =
{ NULL, NULL } ;/*フランジ長を描く最良の方法を計
算する。同時のベンドラインを考慮する。*/// these v
ariables are for handling simultaneous bendline pr
operty things.BM_BEND_PROPERTY *prop ;BM_LINKED_LI
ST_NODE *prop_list ;DBM_ARRAY *bendlines;BM_BENDLI
NE *bnd ;long size, this_bend_seen = 0 ;for (prop_
list = bend->get_properties() ; prop_list ; prop_l
ist = prop_list->next()) {prop =(BM_BEND_PROPERTY
*) prop_list->get_obj() ;if (prop->is(BM_TYPE_BEND
_SIMULTANEOUS)) {bendlines = (DBM_ARRAY *) prop->g
et_bendlines() ;size = bendlines->get_size() ;for
(i = 0 ; i < size ; i++) {// get a bendline in the
bend property objectif (NULL == (bnd = (BM_BENDLI
NE *) bendlines->get(i))) continue ;bl = parent->g
et_AD_bend_structure(bnd) ;if (NULL == bl)continue
;if (bl == this) this_bend_seen = 1 ;if (! bl->da
ta_valid || bl->ignore) continue ;// compute how t
o draw flange length dimensions forthis one bendli
ne.bl->compute_dim_points_to_display_indiv(best_AD
_bendline, bodies_bend_flange_list, distance_and_
z) ;}}}if (! this_bend_seen){ // make sure this be
ndline gets processedbl = parent->get_AD_bend_stru
cture(bend) ;if (bl && bl->data_valid && ! bl->ign
ore) {bl->compute_dim_points_to_display_indiv(best
_AD_bendline, bodies_bend_flange_list, distance_an
d_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 *) b
endlines->get(i))) continue ;bl = parent->get_AD_b
end_structure(bnd) ;if (NULL == bl) continue ;// m
ark as ignoreif (bl->adj_body1 && ! (bl->body1_dra
wn) && bl != best_AD_bendline[0]) {bl->body1_drawn
= 1 ;bl->drawn_bend_dim_point1 = bodies_bend_flan
ge_list[0];bl->drawn_flange_dim_point1 = bodies_be
nd_flange_list[2] ;}if (bl->adj_body1 && ! (bl->bo
dy2_drawn) && bl != best_AD_bendline[1]) {bl->body
2_drawn = 1 ;bl->drawn_bend_dim_point2 = bodies_be
nd_flange_list[1] ;bl->drawn_flange_dim_point2 = b
odies_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_fla
nge_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 = bo
dies_bend_flange_list[1] ;best_AD_bendline[1]->dra
wn_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_fl
ange_list[4] ; temp_point ; temp_point = temp_poin
t->next) {if (NULL == temp_point->adj_bendline) co
ntinue ;(best_AD_bendline[0]->parent)->compute_eff
ects_flange_length_drawn(best_AD_bendline[0]->ben
d,best_AD_bendline[0]->adj_body1, bodies_bend_flan
ge_list[0], bodies_bend_flange_list[2], temp_point
->adj_bendline) ;}}if (best_AD_bendline[1]) {for
(temp_point = bodies_bend_flange_list[5] ; temp_po
int; temp_point = temp_point->next) {if (NULL == t
emp_point->adj_bendline)continue ;(best_AD_bendlin
e[1]->parent)->compute_effects_flange_length_drawn
(best_AD_bendline[1]->bend,best_AD_bendline[1]->ad
j_body2, bodies_bend_flange_list[1], bodies_bend_f
lange_list[3], temp_point->adj_bendline);}}}/*この
関数はこのベンドラインに対するフランジ長さを描く。
それは、compute dim points to display()関数により
計算された情報を用いる。TODO : この関数において
は、われわれは、ベンドラインデイメンシヨンポイント
が既に描かれているトラックを保持することが出来る。
adj-body1およびadj-body2に対するベンドラインデイメ
ンシヨンポイントは一致する。その場合、それを一回だ
け実際に描くべきである。*/void BM_AD_bendline::dra
w_dimension_points(){//qualification checkif (! da
ta_valid || ignore) return ;if (adj_body1 &&2 == b
ody1_drawn) {parent->draw_dim_point(drawn_bend_dim
_point1, drawn_flange_dim_point1, parent->view, pa
rent->dc, parent->object_space_per_pixel) ;}if (ad
j_body2 && 2 == body2_drawn) {parent->draw_dim_poi
nt(drawn_bend_dim_point2, drawn_flange_dim_point2,
parent->view, parent->dc, parent->object_space_pe
r_pixel) ;}}/*********** ********** ********** ***
******* ********** ********** ********** *********
* **********BM_AUTO_DIMENSION class stuff.********
** ********** ********** ********** ********** ***
******* ********** ********** ***********//*これは
デバッグ関数である。*/void BM_AUTO_DIMENSION::test
_draw(void){BM_AD_dim_corner *temp_point ;int i ;f
or (i = 0 ; i < num_of_bendlines ; i++) {if (! ben
ds[i]->data_valid) continue ;if (bends[i]->adj_bod
y1) {(bends[i]->bend_body1_point_left).draw_with_d
im_line(view,dc,object_space_per_pixel) ;(bends[i]
->bend_body1_point_right).draw_with_dim_line(view,
dc,object_space_per_pixel) ;for (temp_point = bend
s[i]->body1_points ; temp_point ; temp_point = tem
p_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 =
temp_point->next) {temp_point->draw_with_dim_line
(view,dc,object_space_per_pixel) ;}}}}/*この関数は
全てのベンドラインに対してベンドラインデータと共に
info−boxを描く。アイデア:われわれは、ソリ
ッドモードではレンダウエアはその種の情報を提示しな
いため、ビユー領域における部分の可視部分のbounding
ボックスをチェックしない。更に、しばしば、ユーザは
部分のデイメンシヨンを診るためにズームインし、その
場合、部分によりカバーされないビユーポートの部位は
なく、すなわちboundingボックスは全体のビー
領域をカバーし、実際には無用である。代わりに、我々
はビユー領域のエッジに沿いベンドライン情報ボックス
を描いていることになる。我々はビユー領域を4領域に
分割し、info−boxが関係するベンドポイントに
どれがより近くても、それらの領域にベンドラインin
foボックスを配置する。ここで当然、我々はビユーポ
ートの左−右垂直エッジに沿いそれらのボックスを描
く。*/void BM_AUTO_DIMENSION::draw_bendline_data(C
DC *pdc){int i, j ;// these variables are used toc
alculate the info-box size and to draw itint font_
height = 21 ;int font_avg_char_width = 8 ; // aver
age width of a characterint box_height = (font_hei
ght << 1) /* テキストの2列 */ ;int half_box_height
= box_height >> 1 ;int box_width = font_avg_char_
width * 15 ; // space for 15 charactersint box_x ;
int vert_space_per_box ;int offset ;// compute max
imum number of info-boxes we can draw.int half_max
_num_info_boxes = view_size_y /box_height ;if (hal
f_max_num_info_boxes < 1) return ; // not enough s
creen spaceint max_num_info_boxes = half_max_num_
info_boxes << 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 ;//
remember, visibility of adj_body1 bend-dimension
points is always computed.// here we only check vi
sibility with respect to adj_body1.// most likely
visibility with respect to adj_body1 and adj_body2
is the same.if ((bends[i]->bend_body1_point_lef
t).visible || (bends[i]->bend_body1_point_right).v
isible) {++num_bends_to_be_drawn ;}else continue ;
if (num_bends_to_be_drawn >= max_num_info_boxes) b
reak ; // out of view space}// check if there are
any bendlines to be drawnif (0 == num_bends_to_be_
drawn) return ;/*ベンドラインポインタおよびエンド
ポイントのy座標を記憶するためのスペースを割り当て
る。*/BM_AD_bendline **bendlines = new BM_AD_bendl
ine*[num_bends_to_be_drawn] ;if (NULL ==bendlines)
return ; // out of spacedouble *bend_y_coordinate
s = new double[num_bends_to_be_drawn] ;if (NULL ==
bend_y_coordinates) { // out of spacedelete [] be
ndlines ; return ; }BM_AD_dim_corner **bend_points
= newBM_AD_dim_corner*[num_bends_to_be_drawn] ;if
(NULL == bend_points) {delete [] bendlines ; dele
te [] bend_y_coordinates ; return ; }/*ベンドライ
ンポインタおよびbend−dim−pointポイン
タを集める。*/for (i =j = 0 ; i < num_of_bendlines
; i++) {if (! bends[i]->data_valid || NULL== bend
s[i]->bend) continue ;if (! (bends[i]->bend_body1_
point_left).visible && ! (bends[i]->bend_body1_poi
nt_right).visible) continue ;// first, decide whic
h of the endpoints we will usebendlines[j] = bends
[i] ;if((bends[i]->bend_body1_point_left).visible)
{if (! (bends[i]->bend_body1_point_right).visibl
e) bend_points[j] = &(bends[i]->bend_body1_point_l
eft) ;else {if ((bends[i]->bend_body1_point_left).
z_buf_value < (bends[i]->bend_body1_point_right).z
_buf_value) bend_points[j] = &(bends[i]->bend_body
1_point_left) ;else bend_points[j] = &(bends[i]->b
end_body1_point_right) ;}}else bend_points[j] = &
(bends[i]->bend_body1_point_right) ;if (++j >= num
_bends_to_be_drawn) break ; // out of view space}/
*info-boxが画面のどの側にあるべきかに従ってポイン
トを分類する。bend-line-dim-pointが画面の左側にな
い全てのボックスを含む(少なくとも始めは)。*/int
half_screen = (view_size_x >> 1) ;i = 0 ; // i wil
l be topj = num_bends_to_be_drawn - 1 ; // j will
be bottom// we will use these to temporarily store
stuffBM_AD_bendline *p_bend ;BM_AD_dim_corner *p_
bend_point ;while (i < j) {while (i < j && bend_po
ints[i]->screen_x < half_screen) i++ ;while (i< j
&& bend_points[j]->screen_x >= half_screen) j-- ;/
/ switch i and jif (i < j) {p_bend = bendlines[i]
;p_bend_point = bend_points[i] ;bendlines[i] = be
ndlines[j] ;bend_points[i] = bend_points[j] ;bendl
ines[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-boxを有さないことをチェックする。*/if (i > ha
lf_max_num_info_boxes) {// too many boxes on the l
eft side.// sort them according to x-coordinates./
/ this way we will movepoints with the largest x-c
oordiates 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, (unsig
ned long) i, (long *) bendlines) ;i =half_max_num_
info_boxes ;}else if ((num_bends_to_be_drawn - i)
> half_max_num_info_boxes) {// too many boxes on t
he right side.// sort them according to x-coordina
tes.// this way we will move points with the small
estx-coordiates to the left side.for (j = i ; j <
num_bends_to_be_drawn ;j++) bend_y_coordinates[j]
= bend_points[j]->screen_x ;DBM_QuickSort_double(b
end_y_coordinates + i, (unsigned long) (num_bends_
to_be_drawn - i),(long *) (bendlines + i)) ;i = nu
m_bends_to_be_drawn - half_max_num_info_boxes ;}//
it could have been that when we chose a point for
a bendline, it is not the best point.// (although
this point was used to place this point on the le
ft-right side).// imagine a point on the left. it
could be that both endpoints are visible, but// ou
t point is not the best, because the other endpoin
t of the bendline is actually to the// left of our
point.for (j = 0 ; j < i ; j++) {// check if we h
ave choiceif (! (bendlines[j]->bend_body1_point_le
ft).visible || ! (bendlines[j]->bend_body1_point_r
ight).visible) continue ;if ((bendlines[j]->bend_b
ody1_point_left).screen_x < (bendlines[j]->bend_bo
dy1_point_right).screen_x) bend_points[j] = &(bend
lines[j]->bend_body1_point_left) ;else bend_points
[j] = &(bendlines[j]->bend_body1_point_right) ;}fo
r (j = i ; j < num_bends_to_be_drawn ; j++) {// ch
eck if we have choiceif (! (bendlines[j]->bend_bod
y1_point_left).visible || ! (bendlines[j]->bend_bo
dy1_point_right).visible) continue ;if ((bendlines
[j]->bend_body1_point_left).screen_x > (bendlines
[j]->bend_body1_point_right).screen_x) bend_points
[j] = &(bendlines[j]->bend_body1_point_left) ;else
bend_points[j] = &(bendlines[j]->bend_body1_point
_right) ;}// store the y-coordinate for Quicksortf
or (j = 0 ; j< num_bends_to_be_drawn ; j++) bend_y
_coordinates[j] = bend_points[j]->screen_y ;// sor
t both sides according to the screen y-coordinate/
/ notea glitch : while the bendlines[] array has b
een permuted, the bend_points[] array has not bee
n.// in the next paragraph we restore the point ar
ray. TODO : may-be there is a better solution.//we
could resort the array, but then we need to get o
riginal y-coordinates array.//we could justcompute
a separate permutation array, but then we need sp
ace for it, and//the code to compute the permutati
on, which is non-tirivial.// anyway,for now we jus
t do it the easy way.if (i > 0) DBM_QuickSort_doub
le(bend_y_coordinates, (unsigned long) i, (long *)
bendlines) ;if ((num_bends_to_be_drawn - i) > 0)
DBM_QuickSort_double(bend_y_coordinates + i, (unsi
gned long) (num_bends_to_be_drawn - i), (long *)
(bendlines + i)) ;for (j= 0 ; j < i ;
j++) {if ((bendlines[j]−
>bend_body1_point_left).v
isible) {if (! (bendlines
[j]−>bend_body1_point_rig
ht).visible) bend_points
[j] = &(bendlines[j]−>ben
d_body1_point_left) ;else
{if ((bendlines[j]−>bend
_body1_point_left).screen
_x < (bendlines[j]−>bend_
body1_point_right).screen
_x) bend_points[j] = &(be
ndlines[j]−>bend_body1_po
int_left) ;else bend_poin
ts[j] = &(bendlines[j]−>b
end_body1_point_right)
;}}else bend_points[j]=
&(bendlines[j]−>bend_body
1_point_right) ;}for (j =
i ; j < num_bends_to_be_
drawn ; j++) {if ((bendli
nes[j]−>bend_body1_point_
left).visible) {if (! (be
ndlines[j]−>bend_body1_po
int_right).visible) bend_
points[j] = &(bendlines
[j]−>bend_body1_point_lef
t) ;else {if ((bendlines
[j]−>bend_body1_point_lef
t).screen_x > (bendlines
[j]−>bend_body1_point_rig
ht).screen_x) bend_points
[j] = &(bendlines[j]−>ben
d_body1_point_left) ;else
bend_points[j] = &(bendl
ines[j]−>bend_body1_point
_right) ;}}else bend_poin
ts[j]= &(bendlines[j]−>be
nd_body1_point_right) ;}/
*ここで描画の準備が完了する。*/static char info_b
ox_text[256] ;static POINT box_corners[5] ;static
POINT arrow[3] ;BM_BENDLINE *b ;BM_BEND_OP *bop ;B
M_2D_BODY *b_body ;/*左側を描く。*/int left = 3 ;i
nt top ;if (0 == i) goto draw_right_side ;// compu
te vertical space per info-boxvert_space_per_box =
view_size_y /i ;// compute vertical offset for th
e top-left corner of the info-boxoffset = (vert_sp
ace_per_box - box_height) >> 1 ;box_corners[0].x =
box_corners[3].x = box_corners[4].x = left ;box_c
orners[1].x = box_corners[2].x = left + box_width
;for (j = 0 ; j < i ; j++) {b = bendlines[j]->ben
d;bop = b->get_bend_op() ;if (NULL == bop) continu
e ;// 043996KKif (view_type) b_body = b->get_curre
nt_3D_version() ;else b_body = b->get_flat();top =
j*vert_space_per_box + offset ;box_corners[0].y =
box_corners[1].y = box_corners[4].y = top ;box_co
rners[2].y = box_corners[3].y = top +box_height ;s
printf(info_box_text,"A:%5.1f,L:%6.2f",(bop->get_b
end_angle2())*57.29578,(b_body->get_current_center
_line()).get_len()) ;pdc->TextOut(5, top, info_box
_text, strlen(info_box_text)) ;switch (bop->get_ty
pe()) {case BM_TYPE_BEND_OP_REGULAR :sprintf(info_
box_text,"R:%5.2f,D:%5.2f",((BM_BEND_OP_REGULAR *)
bop)->get_bend_radius(),bop->get_bend_deductio
n()) ;pdc->TextOut(5, top + font_height, info_box_
text, strlen(info_box_text)) ;break ;case BM_TYPE_
BEND_OP_CONIC :// TODO : implement conic bend op.b
reak ;}// draw boxpdc->Polyline(box_corners, 5) ;/
/ draw arrowarrow[0].x = left + box_width ;arrow
[0].y = top + half_box_height ;// calculate arrow
tip at fixed percentage length in from end pointCP
oint ptLeft(bendlines[j]->bend_body1_point_left.sc
reen_x, bendlines[j]->bend_body1_point_left.screen
_y);CPoint ptRight(bendlines[j]->bend_body1_point_
right.screen_x, bendlines[j]->bend_body1_point_rig
ht.screen_y);CSize sizeDiff= ptRight - ptLeft;CPoi
nt ptArrowTip;if ( bend_points[j] == &(bendlines
[j]->bend_body1_point_left) ){ptArrowTip.x = ptLef
t.x + sizeDiff.cx/8;ptArrowTip.y = ptLeft.y + size
Diff.cy/8;}else{ptArrowTip.x = ptRight.x - sizeDif
f.cx/8;ptArrowTip.y = ptRight.y - sizeDiff.cy/8;}a
rrow[1].x = ptArrowTip.x;arrow[1].y = ptArrowTip.
y;pdc->Polyline(arrow, 2) ;// change tosolid pen f
or arrow headsCPen* pArrowPen = new CPen(PS_SOLID,
BCAD_context.m_nBendLineWeight, BCAD_context.m_cr
Bend);CPen* pOldPen = pdc->SelectObject(pArrowPe
n);// compute arrow headCAutoDimArrow arrowBend(pt
ArrowTip,CPoint(arrow[0].x,arrow[0].y),BCAD_contex
t.m_nArrowAngle,BCAD_context.m_nArrowLength);// dr
aw arrow headarrowBend.DrawHead(dc);pdc->SelectObj
ect(pOldPen);delete pArrowPen;}/*右側を描く。*/dra
w_right_side :if (0 ==num_bends_to_be_drawn - i) g
oto done ;box_x = view_size_x - box_width -3 ;left
= box_x ;// compute vertical space per info-boxve
rt_space_per_box = view_size_y / (num_bends_to_be_
drawn - i) ;// compute vertical offset for the top
-left corner of the info-boxoffset = (vert_space_p
er_box -box_height) >> 1 ;box_corners[0].x = box_c
orners[3].x = box_corners[4].x= left ;box_corners
[1].x = box_corners[2].x = left + box_width ;box_x
+= 2 ;for (j = i ; j < num_bends_to_be_drawn ; j+
+) {b = bendlines[j]->bend ;bop = b->get_bend_op()
;if (NULL == bop) continue ;// 043996KKif (view_t
ype) b_body = b->get_current_3D_version() ;else b_
body = b->get_flat() ;top = (j - i)*vert_space_per
_box + offset ;box_corners[0].y = box_corners[1].y
= box_corners[4].y = top ;box_corners[2].y = box_
corners[3].y= top + box_height ;sprintf(info_box_t
ext,"A:%5.1f,L:%6.2f",(bop->get_bend_angle2())*57.
29578,(b_body->get_current_center_line()).get_le
n()) ;pdc->TextOut(box_x, top, info_box_text, strl
en(info_box_text)) ;switch (bop->get_type()) {case
BM_TYPE_BEND_OP_REGULAR :sprintf(info_box_text,"
R:%5.2f,D:%5.2f",((BM_BEND_OP_REGULAR *) bop)->get
_bend_radius(),bop->get_bend_deduction()) ;pdc->Te
xtOut(box_x, top + font_height, info_box_text,strl
en(info_box_text)) ;break ;case BM_TYPE_BEND_OP_CO
NIC :// TODO : implement conic bend op.break ;}//
draw boxpdc->Polyline(box_corners, 5) ;// draw arr
owarrow[0].x = left ;arrow[0].y = top + half_box_h
eight ;// calculate arrow tip at fixed percentage
length in from end pointCPoint ptLeft(bendlines[j]
->bend_body1_point_left.screen_x, bendlines[j]->be
nd_body1_point_left.screen_y);CPoint ptRight(bendl
ines[j]->bend_body1_point_right.screen_x, bendline
s[j]->bend_body1_point_right.screen_y);CSize sizeD
iff = ptRight - ptLeft;CPoint ptArrowTip;if ( bend
_points[j] == &(bendlines[j]->bend_body1_point_lef
t) ){ptArrowTip.x = ptLeft.x + sizeDiff.cx/8;ptArr
owTip.y = ptLeft.y + sizeDiff.cy/8;}else{ptArrowTi
p.x = ptRight.x- sizeDiff.cx/8;ptArrowTip.y = ptRi
ght.y - sizeDiff.cy/8;}arrow[1].x =ptArrowTip.x;ar
row[1].y = ptArrowTip.y;pdc->Polyline(arrow, 2) ;/
/ change to solid pen for arrow headsCPen* pArrowP
en = new CPen(PS_SOLID, BCAD_context.m_nBendLineWe
ight, BCAD_context.m_crBend);CPen* pOldPen = pdc->
SelectObject(pArrowPen);// compute arrow headCAuto
DimArrow arrowBend(ptArrowTip,CPoint(arrow[0].x,ar
row[0].y),BCAD_context.m_nArrowAngle,BCAD_context.
m_nArrowLength);// draw arrow headarrowBend.DrawHe
ad(dc);pdc->SelectObject(pOldPen);delete pArrowPe
n;}/*割り当てたメモリを開放する。*/done:delete []
bend_points ;delete [] bend_y_coordinates ;delete
[] bendlines ;}/*デバイスコンテクストに部分デイメ
ンシヨンを描く。*/int BM_AUTO_DIMENSION::draw_auto
_dimensions(CDC *target_dc){BM_AD_dim_corner *temp
_point;int i ;// check that we have a valid dcif
(NULL == target_dc) return 0;// check if we need t
o recompute the data structuresif (dirty) {if (!co
mpute_auto_dimension_data()) return 0 ;if (dirty)
return 0 ;}if (NULL== part) return 1 ;dc = target_
dc ;// get view sizeview_size_x = view->get_viewpo
rt_width() ;view_size_y = view->get_viewport_heigh
t() ;// create a mesh to determine clear spaces to
draw dimensions & datapMesh = newCAutoDimRgnMesh
(view_size_x, view_size_y);// check if we need to
computepoints to ignore in solidif (view->get_draw
ing_mode() && ! points_to_ignore_in_solid_compute
d) {compute_points_to_ignore_in_solid() ;}object_s
pace_per_pixel = view->get_object_to_device_rati
o() ;// initially set all"ignore" flags to FALSE.
we should not ignore anything.// also, nothingis d
rawn yet.for (i = 0 ; i < num_of_bendlines ; i++)
{bends[i]->ignore= 0 ;bends[i]->body1_drawn = bend
s[i]->body2_drawn = 0 ;}/*全てのベンドラインの全て
のベンドラインデイメンシヨンポイントのビジビリテイ
を計算する。*/for (i = 0 ; i < num_of_bendlines ;
i++) {if (! bends[i]->data_valid) continue ;bends
[i]->compute_bendline_dim_points_visibility() ;if
(bends[i]->adj_body1) {for (temp_point = bends[i]-
>body1_points ; temp_point; temp_point = temp_poin
t->next) temp_point->visible = -1 ;}if (bends[i]->
adj_body2) {for (temp_point = bends[i]->body1_poin
ts ; temp_point ; temp_point = temp_point->next) t
emp_point->visible = -1 ;}}/*全てのベンドラインに
対して、描くべきデイメンシヨンポイントを計算する。
*/for (i = 0 ;i < num_of_bendlines ; i++) {if (! b
ends[i]->data_valid || bends[i]->ignore) continue
;bends[i]->compute_dim_points_to_display() ;}/*パ
ートを描くペンを生成する。フランジデイメンシヨンを
描くペンを生成する。*/// create the pen : type, (l
ine)width, color.CPen penFlange;CPen* pFlangePen =
create_auto_dim_pen(&penFlange, BCAD_context.m_nF
langeLineStyle, BCAD_context.m_nFlangeLineWeight,
BCAD_context.m_crFlange);// select new pen, save o
ld penCPen* pOldPen = dc->SelectObject(pFlangePe
n);COLORREF oldtextcolor = dc->SetTextColor(BCAD_c
ontext.m_crFlange) ;int old_bk_mode = dc->SetBkMod
e(TRANSPARENT) ;/*フランジ長さディメンシヨンを表示
する。*/if (BCAD_context.m_bShowFlangeDim){for (i
= 0 ; i < num_of_bendlines ; i++) {if (! bends[i]-
>data_valid || bends[i]->ignore) continue ;bends
[i]->draw_dimension_points();}}/*// ダーテイ領域の
表示をテストする。CBrush brRed(RGB(255,0,0));CBrus
h* pOldBrush = dc->SelectObject(&brRed);dc->PaintR
gn(pDirtyRegion);dc->SelectObject(pOldBrush);*/del
ete pDirtyRegion;pDirtyRegion = NULL;/*ベンドライ
ンinfoを描くペンを生成する。*/// create the pen :t
ype, (line)width, color.CPen penBend;CPen* pBendPe
n = create_auto_dim_pen(&penBend, BCAD_context.m_n
BendLineStyle, BCAD_context.m_nBendLineWeight, BCA
D_context.m_crBend);// select the new pendc->Selec
tObject(pBendPen);dc->SetTextColor(BCAD_context.m_
crBend);/*ベンドラインinfoを描く。*/if (BCAD_conte
xt.m_bShowBendDim)draw_bendline_data(dc) ;// Delet
e the mesh now that we are finished with it.//dele
te pMesh;/*古いペンを復帰させる。*/dc->SelectObjec
t(pOldPen) ;dc->SetTextColor(oldtextcolor) ;dc->Se
tBkMode(old_bk_mode) ;// see if we have to disable
auto-dimensioning in the view classif (reset_view
_to_false_once_drawn) {reset_view_to_false_once_dr
awn = 0 ;view->set_auto_dimensions(0) ;}return 1
;}CPen* BM_AUTO_DIMENSION::create_auto_dim_pen(CP
en* pPen, int nLineStyle, int nLineWeight, COLORRE
F cr){if (nLineWeight == 1 || nLineStyle == PS_SOL
ID)pPen->CreatePen(nLineStyle, nLineWeight, cr);//
for speedelse{CBrush brushNew(cr);LOGBRUSH lb;bru
shNew.GetLogBrush(&lb);DWORD dwStyleArray[6];int n
StyleCount = 2;DWORD dwDashLength = 2 + (nLineWeig
ht * 4);DWORD dwDotLength = dwDashLength / 4;DWORD
dwGapLength = dwDashLength / 2;switch (nLineStyl
e){case PS_DASH:dwStyleArray[0] = dwDashLength;//
pixels ondwStyleArray[1]= dwGapLength;// pixels of
fnStyleCount = 2;break;case PS_DOT:dwStyleArray[0]
= dwDotLength;// ondwStyleArray[1] = dwGapLength;
// offnStyleCount= 2;break;case PS_DASHDOT:dwStyle
Array[0] = dwDashLength;// ondwStyleArray[1] = dwG
apLength;// offdwStyleArray[2] = dwDotLength;// on
dwStyleArray[3] = dwGapLength;// offnStyleCount =
4;break;case PS_DASHDOTDOT:dwStyleArray[0] = dwDas
hLength;// ondwStyleArray[1] = dwGapLength;// offd
wStyleArray[2] = dwDotLength;// ondwStyleArray[3]
= dwGapLength;// offdwStyleArray[4] = dwDotLength;
// ondwStyleArray[5] = dwGapLength;// offnStyleCou
nt = 6;break;}pPen->CreatePen(PS_GEOMETRIC | PS_US
ERSTYLE, nLineWeight, &lb, nStyleCount, dwStyleArr
ay);}return pPen;}void CBendCADDoc::OnDrawAutoDi
m() {// if we have no dimension object, do nothin
g.if (NULL == auto_dim) {auto_dim = new BM_AUTO_DI
MENSION(this) ;}if (NULL == auto_dim) return ;CBen
dCADViewPart *pActiveView = (CBendCADViewPart *) g
et_view(BENDCAD_VIEW_TYPE_PART) ;if (NULL == pActi
veView) return ;if (! pActiveView->get_auto_dimens
ions()) auto_dim->disable_view_dimensions_flag_nex
t_time() ;pActiveView->set_auto_dimensions(1) ;//
always recompute dimensionpointsauto_dim->invalida
te() ;pActiveView->Invalidate(0) ;} 付録H ディメンションポイントを計算する自動寸法化関数の
例。ディメンションポイントは、フランジ長ディメンシ
ョンが描かれる前に計算される。
【0362】//#include "stdafx.h"#include "BendCA
D.h"#include "BendCADDoc.h"#include"BendCADViewPar
t.h"#include "AUTODIM.HXX"/*********** **********
********** ********** ********** ********** ******
**** ********** **********BM_AD_bendline class stu
ff.********** ********** ********** ********** ***
******* ********** ********** ********** *********
**//*これは、所与の基準点とエッジポイントの間の距
離を計算するBM_AD_bendline::compute_BM_AD_flange_p
oints(..)に用いられるローカルな関数である。この関
数はポイントが基準ラインの1つの間違った側である場
合にFALSEを戻す。 ベクトルdirはユニットベクトルで
あるべきである。*/static int compute_distance_from
_ref_point(BM_POINT const& pt /* given reference p
oint */,BM_VECTOR const& dir /*direction vector *
/, BM_POINT *p /* point whose distance we want to
compute */, double &distance){BM_VECTOR v(*p - pt)
;double x = v % dir ;if (x < -AUTODIM_DISTANCE_TO
LERANCE) return 0 ;distance = x ;return 1 ;}/*BM_A
D_bendline::compute_BM_AD_flange_points(...)により
用いられるローカル関数。注意:参照するディメンショ
ンリストはフランジディメンションポイントのリストで
ある。”左”に開放したリスト中のディメンションポイ
ントの個数が”右”に開放したリスト中のディメンショ
ンポイントの個数に等しくないとき、ディメンションリ
ストは開放である。これは通常リストに付加した最後の
フランジディメンションポイントが”閉じる”に一致す
るフランジディメンションポイントを持たないことを意
味する。これらはすべて、実際には小片に分解されたラ
イン(1つのラインのように見える)を我々が持つこと
が出来る可能性によりもたらされる。その場合、ユーザ
はそれらの小片を見ず(1つのラインのように見え
る)、また我々はポイントを途中で正当なフランジディ
メンションポイントと考えることを望まない。この関数
は、我々が所与のエッジをスキップし、ディメンション
ポイントを開放のままにすることが出来るときはTRUEを
戻し、また、我々が、現在のエッジのエンドポイントの
1つから左側ディメンションポイントを生成することに
より開放ディメンションを閉じる必要があるときはFALS
Eを戻す。基本的には、この関数は、ループ中の次のエ
ッジが無視されないラインであるときはTRUEを戻す。実
際には、更に幾つかの条件を付加する。注意:この関数
は、エッジのエンドポイントがフランジ長距離にあり、
また我々が、このエンドポイントに対する(フランジ)
ディメンションポイントを描くべきかを考えているとき
に求められる。*/static int leave_dimension_open(BM
_EDGE *edge /* current edge */,BM_LOOP *bloop /* l
oop where the current edge belongs to */,BM_VECTOR
const& side_vector /* side vector for the current
bendline-ajd_flange pair */, BM_VECTOR const& nor
mal /* normal of the plane underlying the adjacent
flange */){BM_EDGE *next_edge = (BM_EDGE *) edge-
>next();if (NULL == next_edge) next_edge = bloop->
get_first_edge() ;if (next_edge->is(BM_ENTITY_TYPE
_LINE)) {// problem. if the next edge (which is al
ine) will be ignored, we need to// close the dimen
sion here.BM_VECTOR temp_v((((BM_LINE *) next_edg
e)->get_v()) * side_vector) ;// if the nextline wi
ll not be ignored we can skip the current edge.if
(temp_v.Len() >AUTODIM_DISTANCE_TOLERANCE && (temp
_v % normal) < 0.0) {// next edge isa line that wi
ll not be ignored.// note that there is a problem.
if this edge is a line, and one of the two lines
// (rememeber, next edge is aline) is adjacent to
a bendline that // the other is not adjacent to, w
e should close the dimension.if (! edge->is(BM_ENT
ITY_TYPE_LINE)) return1 ;BM_3D_BODY *ab = edge->ge
t_adj_body() ;BM_3D_BODY *ab_next = next_edge->get
_adj_body() ;if (! ab) {if (! ab_next) return 1 ;i
f (! ab_next->is(BM_ENTITY_TYPE_BENDLINE)) return
1 ;return 0 ;}if (! ab_next) {if (! ab->is(BM_ENTI
TY_TYPE_BENDLINE)) return 1 ;return 0 ;}if ((! ab-
>is(BM_ENTITY_TYPE_BENDLINE) && ! ab_next->is(BM_E
NTITY_TYPE_BENDLINE)) ||ab == ab_next) return 1
;}}// if next edge is not a line, we have to clos
e theopen dimensionreturn 0 ;}/*BM_AD_bendline::co
mpute_BM_AD_flange_points(...)により用いられるロー
カルな関数この関数は最も一般的な形態でディメンショ
ンポイントを生成する。我々は、我々がラインに対する
ディメンションポイントを生成していると仮定する。こ
のラインはベンドラインに隣接することが出来る。*/st
atic BM_AD_dim_corner *create_dim_point(double d /
* bendline arcoutside length projected onto our pl
ane */, // these are basic parameters needed to dr
aw any dimension pointBM_POINT const& p /* point p
in theflange dimension point */,BM_VECTOR const&
rv /* reference vector to make sure point p in the
flange dimension point is on the same plane as de
fined by the bendline dimension point */,BM_VECTOR
const& opening_direction_vector /* for flange dim
ension point */, int opening_vector_reverse_bit,BM
_AD_bendline *owner,BM_3D_BODY *Body_required_visi
ble,BM_AD_dim_corner **prev /* previous flange dim
ension point in the list of flange dimpoints */,BM
_VECTOR const& side_vector, // these parameters ar
e used when the line for which we are computing th
e dimension point is adjacent//to another bendlin
e.double d_proj_side_vector /* d projected onto th
e side-vector : angle_factor*d in compute_BM_AD_fl
ange_points(...) */,BM_VECTOR & bend_arc_direction
/* direction of the bend arc projected onto our p
lane *//* should be line->v * plane_normal */,BM_V
ECTOR & bend_direction /* points to the direction
in which the bendline "turns" *//* depends on whet
her the bend angle is acute or not. *//* if acute
then tangentto the other end of bend arc *//* if n
ot acute, then an endpoint of thetangent approxima
tion *//* basically this is the (p->p2) vector for
theother bendline with respect to this flange */,
BM_BENDLINE *adj_bendline/* if the line is adjacen
t to a bendline this is a pointer to it *//* this
parameter is stored to avoid drawing some dimenion
s twice */,BM_LINEconst& adj_bend_p2_line /* this
is the line between p2 points of the bend-dimensio
n *//* points of the adjacent bendline with respec
t to this flange *//* note that our p2 point has t
o be on that line. *//* usually our p->p2 vector i
s perpendicular to this line, although not always
*/){//this our local copy of the adj-bendline-poin
terBM_3D_BODY *adj_bend = adj_bendline ;BM_POINT p
_local(p + rv) ;// note : even if this line is adj
acent to another bendline, // but if the line we a
re creating the flange dimension point for is not
perpendicular to// the side-vector, we should not
memorize that this flange dimension point is adjac
ent to // a bendline, because the flange length di
mension drawn at this flange dimension point // is
not parallel to the side-vector of the adjacent b
endline with respect to this flange.if (adj_bendli
ne && fabs(bend_arc_direction %side_vector) < (ben
d_arc_direction.Len() - AUTODIM_DISTANCE_TOLERANC
E)){// not perpendicularadj_bendline = NULL ;}// c
heck if the line is attached to a bendlineif (d <=
AUTODIM_DISTANCE_TOLERANCE) {// not attachedto a
bendline, or both thickness and bendline radius ar
e 0.// create a 1-point flange-dimension point.//
note that body_required_visible pointsto the flang
e with respect to which // the dimension point is
computed.return new BM_AD_dim_corner(p_local, owne
r, Body_required_visible, opening_direction_vecto
r, opening_vector_reverse_bit, prev, adj_bendline)
;}//note that since we have 3 points now, this li
ne is adjacent to anotherbendline.// compute p1. p
_local is p1.// compute pBM_POINT dim_p(p_local+ d
_proj_side_vector*side_vector) ;// compute p2bend_
arc_direction.set_length(d) ;BM_POINT dim_p2(p_loc
al + bend_arc_direction) ;// now the problem is th
at with respect to the adjacent bendline, our flan
ge dimensionpoints// p and p1 might not be on the
outside - they could be on the inside.// the dista
nce from p to p2 depends on that.// however, we kn
ow the p2-line of the adjacent bendline (with resp
ect to our flange),// so wewill compute the distan
ce between that p2-line and dim_p2. // we will use
that to compute the correct p2 point for our flan
ge dimension (note that// our p2 point has to be o
n the p2-line of the adjacent bendline).double dis
tance ;BM_distance_between_point_and_line(dim_p2,
adj_bend_p2_line, &distance, (BM_POINT *) NULL) ;b
end_direction.set_length(distance) ;dim_p2 = dim_p
2 + bend_direction ;// note that the body_required
_visiblepointer points not to this flange, but to
the // adjacent-bendline instead, ALWAYS, even if
this flange dim point will not be marked as// adja
cent to another bendline.return new BM_AD_dim_corn
er(dim_p, p_local, dim_p2, owner, adj_bend ? adj_b
end : Body_required_visible, opening_direction_vec
tor, opening_vector_reverse_bit, prev, adj_bendlin
e) ;}/*この関数は隣接フランジに対するフランジディ
メンションポイントを計算する。注意:この関数の直前
に計算した基準ポイントは、我々が任意の種類のadj-bo
dy面を操作出来るを確実にするために与えられる。第一
の問題は、我々が、adj-bodyの3次元- バージヨンの2
次元- bodyがOUTSIDEまたはINSIDEを表すかどうか解ら
ないということである。我々は、ベンドラインに対する
ベンドラインディメンションポイントがOUTSIDEポイン
トであることを知っている。ただし、 adj-bodyが明瞭
にINSIDEを表すということがあり得る。その場合、ここ
で計算しようとしている全てのポイントをシフトさせる
並進ベクトルを計算する基準ポイント(これはadj-body
の外側面上にある)に対して用いられる。更に、この並
進ベクトルを用いて、フランジディメンションポイント
のポイントp1およびp2が正しいということを確認するた
めに用いる。(もし、adj-bodyがinsideを表すときは、
我々はoutsideに対して実際にディメンションポイント
を計算し、ライン(p->p2)は注意して構成されなければ
ならず、それはライン(p->p1)より短い。)注意:この
関数は、我々がここでより多くの仮定を行うがBMAPI's
BM_2D_BODY::compute_outside_width(...)関数に非常に
よく相似している。*/int BM_AD_bendline::compute_BM
_AD_flange_points(BM_3D_BODY *adj_body){// flange
dimension points we aregoing to compute will be st
ored hereBM_AD_dim_corner **list_of_points ;// lis
t_of_points is where we write the pointer to the /
/ next flange dimension pointBM_AD_dim_corner *tem
p_dp ;// these parameters are used asinput to this
function.double flange_length ; /* it is importan
t that the flange length be the correct flange len
gth */BM_POINT ref_point ; /* reference point, def
ines the right plane for flange dimension points *
/BM_VECTOR side_vector ; /* should be normalized *
/// check which adjacentbody we computeif (adj_bod
y == adj_body1) {flange_length = fl1 ;list_of_poin
ts = &body1_points ;ref_point = bend_body1_point_l
eft.p ;side_vector= side_vector1 ;}else if (adj_bo
dy == adj_body2) {flange_length = fl2 ;list_of_poi
nts = &body2_points ;ref_point = bend_body2_point_
left.p ;side_vector = side_vector2 ;}else return 0
; // not an adjcent body// variables to store tem
porary valuesBM_VECTOR temp_v ;double temp_x ;// p
arameters for fixing the reference pointBM_POINT r
p(ref_point) ; // this a local copy of the referen
ce point. we will modify it.BM_VECTOR rv ; // a ve
ctor for translating flange dimension points.int r
ef_vector_valid = 0 ;// if this is TRUE, we need t
o translate all flange dimension points.//if TRUE,
the only really tricky part is to construct the p
2 point in the flange dimension point.// qualifica
tion checkBM_2D_BODY *adj_displayed_version ;if (p
arent->get_view_type()) adj_displayed_version = ad
j_body->get_current_3D_version() ;else adj_display
ed_version = adj_body->get_flat() ;if (NULL == adj
_displayed_version) return 0 ;BM_SURFACE *surface
=adj_displayed_version->get_surface() ;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 w
e scan the loop.double distance1, distance2 ; // h
ere we will store the distance of points we seedou
ble d1, d2 ; // here we store distance that has to
be addedbecause of a bend arc. for lines adjacent
to a bendline.double td1, td2; // here we store t
he total distance which is the sum of distanceX +
dX.BM_3D_BODY *ab ; // here we store a pointer to
a body that is adjacentto the current edge.BM_BEND
_OP *bop ; // here we store a pointer to thebend o
p associated with the bendline that is// adjacent
to the edge we scan (valid only iff the body adjac
ent to the edge is a bendline).BM_VECTOR right_ope
ning_direction ; // this is the right-side opening
directionvector. BM_VECTOR left_opening_direction
; // this is the left-side opening direction vect
or. int fl_dim_open = 0 ; // if this is TRUE, we h
avecreated a right-side flange dimension point, bu
t// no corresponding left-side dimension point. Th
at is, the dimension is "open".BM_VECTOR bend_arc_
direction ; // direction of the bend arc projected
onto our plane//should be line->v * plane_normal.
Used when a line is adjacent to a bendline.BM_VEC
TOR bend_direction ; // points in the direction in
which thebendline "turns"// depends on whether th
e bend angle is acute or not. //if acute then tang
ent to the other end of bend arc.// if not acute,
then an endpoint of the tangent approximation.// b
asically this is the (p->p2) vector for the other
bendline with respect to this flange.// this isuse
d when a line is adjacent to a bendline, to comput
e the p2 point for// the flange dimension point.BM
_LINE adj_bend_p2_line ; // this is theleft-right-
p2 line, of the adjacent bendline,// with respect
to this flange.// this is used when a line is adja
cent to a bendline, to compute the p2 point for //
the flange dimension point.double bend_arc_outsid
e_length_proj ; // bendline arc outside length pro
jected onto our plane/*表面のタイプを操作する。*/i
f (surface->is(BM_TYPE_PLANE)) goto handle_planes
;/*********** ********** ********** ********** **
******** ******************** ********** *********
* 一時的拘束:我々は単に平面である表面を操作する。
TODO:他の表面タイプを操作する。********** *******
*** ********** ********** ********** ********** **
******** ********** ***********///unknown surfacer
eturn 0 ;/*ここで、平面を操作する。*/handle_planes
: BM_PLANE *plane = (BM_PLANE *) surface ;// we a
ssume that the reference point correctly defines t
he plane (which is parallel to our plane)// thatis
the OUTSIDE plane.// check if reference point is
on our plane. If not(in that case our plane repres
ents the INSIDE// plane) compute a translation vec
tor for moving from our plane to reference plane,/
/ and move the reference point to our plane.rv = p
lane->get_normal() ;rv.normalise();temp_v = rp -
(plane->get_pt()) ;temp_x = temp_v % rv ;if (fabs
(temp_x)> AUTODIM_DISTANCE_TOLERANCE) {// ok, need
to translate all dimension points. reference poin
t not on the plane.ref_vector_valid = 1 ;rv.set_le
ngth(temp_x) ;rp = rp + (-rv) ;}else rv = BM_null_
vector ;// compute right- and left-side opening ve
ctors.right_opening_direction = side_vector *(plan
e->get_normal()) ;right_opening_direction.normalis
e() ;left_opening_direction = -(right_opening_dire
ction) ;/*********** ********** ********** *******
*** ********** ********** ********** ********** **
********この関数の主要部分。adj_bodyの束縛ループを
掃引し、ディメンションポイントを構成する。所与のラ
インから最も遠く離れたエッジはbloop内になければな
らないので我々は単にbloopを掃引する必要がある点に
注意されたい。******************** ********** ****
****** ********** ********** ********** **********
********** 注意:ディメンションリストが開放のと
き、生成される最後の右-側ディメンションポイント
は、ループの始めにおいて現在のエッジの開始-点から
異なっていなければならない。********** **********
********** ********** ********** ********** ******
**** ********** ********** */// scan alledges in t
he bloop// first, we have a problem where to start
scanning.// if we start from the first edge, we b
asically start from an arbitraryedge.// this might
not be good since we might create dimension point
s wedon't really want.// therefore we will find an
edge that is adjacent toour bendline and start fr
om that and// finish when we get back to it.BM_EDG
E *start_edge, *stop_edge, *next_edge ;for (start_
edge = bloop->get_first_edge() ; start_edge ; star
t_edge = (BM_EDGE *) start_edge->next()){if (start
_edge->get_adj_body() == bend) break ; // edge adj
acent to this bendline is a good start-edgeelse if
(! start_edge->is(BM_ENTITY_TYPE_LINE)) break ; /
/ any non-line is a good start-edgeelse { // any l
ine that will be ignored is also a good place to s
tarttemp_v = (((BM_LINE *)start_edge)->get_v()) *
side_vector ;// in these two cases this line will
be ignoredif (temp_v.Len() <= AUTODIM_DISTANCE_TOL
ERANCE) break ; // line parallel to the side-vecto
rif ((temp_v % plane->get_normal()) > 0.0)break ;
// material "above" the line}}if (NULL == start_ed
ge) {*list_of_points = NULL ;return 1 ;}// this is
the main loop.// initially we setstop_edge to NUL
L. we would like to set it to start-edge, but we c
annot,// because in that case we would never enter
the loop. therefore we setit to NULL and right //
after we enter the loop, we set it to start_edge.
// (this is important in the case when the loop co
nsists of only one circle).stop_edge = NULL ;for
(edge = start_edge ; edge != stop_edge ; edge = ne
xt_edge) {stop_edge = start_edge ;// compute the n
ext edge we willscannext_edge = (BM_EDGE *) edge->
next() ;if (NULL == next_edge) next_edge = bloop->
get_first_edge() ;switch (edge->get_type()) {case
BM_ENTITY_TYPE_LINE : { // compute distance for st
art- and end-points// first, wewant to ignore line
s that are parallel to the side-vector.// we also
want to ignore lines that have material "above" th
em when looking in the//side-vector direction (bec
ause they cannot have to largest width, sincemater
ial is// "above" them, there must be some other ed
ge bounding thebody from above).temp_v = (((BM_LIN
E *) edge)->get_v()) * side_vector ;if (temp_v.Len
() <= AUTODIM_DISTANCE_TOLERANCE) continue ; // li
ne parallel to the side-vectorif ((temp_v % plane-
>get_normal()) > 0.0) continue; // material "abov
e" the line// note that this leaves only lines who
sedirection-vector goes to the "left"// of the sid
e-vector.// we need to check if this line is adjac
ent to a bendlineab = edge->get_adj_body() ;//chec
k if this line is adjacent to a valid bendline (i
e. one that is notthe // bendline associated with
this BM_AD_bendline object).d1 = d2 = bend_arc_out
side_length_proj = 0.0 ;if (ab && ab != bend && ab
->is(BM_ENTITY_TYPE_BENDLINE)) {// check if the be
ndline is being bentbop = ((BM_BENDLINE *) ab)->ge
t_bend_op() ;if ((parent->get_view_type()) /* have
to have a 3D view */ && ((BM_BENDLINE *) ab)->get
_bending_status() && bop) {// a problem : it could
be that the bendline is not perpendicular to thes
ide-vector.// in that case we need to project the
bend-arc-approximation-value onto the side-vector.
// for example, if the bendline is parallel to the
side-vector, we should not add// the approximatio
n value at all, since it plays no role in the widt
h computation.temp_x = side_vector ∧(((BM_LINE *)
edge)->get_v()) ; // temp_x is "angle_factor"if
(temp_x >PI_over_2) temp_x = PI - temp_x ;temp_x =
sin(temp_x) ;switch (bop->get_type()) {case BM_TY
PE_BEND_OP_REGULAR :bend_arc_outside_length_proj =
((BM_BEND_OP_REGULAR *) bop)->compute_3D_outside_
approx_per_side() ;d1 =temp_x*bend_arc_outside_len
gth_proj ;d2 = d1 ; // d2 is the same as d1 !break
;// TODO : implement more bend operations here.de
fault : ; // unknown bend op}// compute some neede
d parameters// compute : direction of the bend arc
projected onto our planebend_arc_direction = (((B
M_LINE *) edge)->get_v()) * plane->get_normal() ;b
end_direction = parent->compute_bend_direction_vec
tor((BM_BENDLINE *) ab, adj_body, &adj_bend_p2_lin
e) ;}}else ab = NULL ; // make sure ab does not po
int to anything we don't want to.// handle two cas
es separately - depending on whether the dimension
list is open or not.if (fl_dim_open) {// if the d
imension is open, wedon't need to check the start-
point of the line,// since it is at the flange
length distance anyway./
/ // first we will check
if the line is perpendicu
lar to the side−vectorif
(fabs(side_vector % ((BM_
LINE *) edge)−>get_v()) >
AUTODIM_DISTANCE_TOLERAN
CE) {// not perpendicula
r.// this line has to be
”coming down” (because i
t is not perpendicular to
the// side−vector and th
e dimension is open, ie.
it cannot be ”going up”).
// now we have to close t
he dimension by creating
a left−hand−side dimensio
n point// from the start−
point of the line.if (tem
p_dp = create_dim_point(b
end_arc_outside_length_pr
oj, ((BM_LINE *) edge)−>g
et_startpt(), rv, left_op
ening_direction, 0, this,
adj_body, list_of_point
s, side_vector, d1, bend_
arc_direction, bend_direc
tion, (BM_BENDLINE *) ab,
adj_bend_p2_line)){list_
of_points = &(temp_dp−>ne
xt) ;}fl_dim_open = 0 ;}e
lse {// is perpendicular.
// here we need to check
the type of the next edg
e.// if it isnot line, we
need to close the dimens
ion here by creating // a
left−hand−side dimension
point from the end−point
of the line.// if the ne
xt edge is a line, we can
just continue.if (leave_
dimension_open(edge,bloo
p,side_vector,plane−>get_
normal())) break ;if (tem
p_dp = create_dim_point(b
end_arc_outside_length_pr
oj, ((BM_LINE *) edge)−>g
et_endpt(), rv, left_open
ing_direction, 0, this, a
dj_body, list_of_points,
side_vector, d1, bend_arc
_direction, bend_directio
n, (BM_BENDLINE *) ab, ad
j_bend_p2_line)){list_of_
points = &(temp_dp−>next)
;}// ok, close the dimen
sion.fl_dim_open = 0 ;//
this is a small trick tha
t will save us some time.
// if thenext 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() ;}}br
eak ;}if (! compute_dista
nce_from_ref_point(rp,sid
e_vector, edge−>get_edge_
startpoint(), distance1))
continue ;if (! compute_
distance_from_ref_point(r
p, side_vector, edge−>get
_edge_endpoint(), distanc
e2)) continue ;td1 = dist
ance1 + d1 ;td2 = distanc
e2 + d2 ;//check if the s
tart−point is a flange di
mension pointif (fabs(td1
− flange_length) <= AUTO
DIM_DISTANCE_TOLERANCE)
{// check if the second p
oint is a flange dimensio
n pointif (fabs(td2 − fla
nge_length) > AUTODIM_DIS
TANCE_TOLERANCE) {// only
start−point is a flange
dimension point.// create
a left−right (ie. in both
directions) flange dim p
oint and continue.if(temp
_dp = create_dim_point(be
nd_arc_outside_length_pro
j, ((BM_LINE *) edge)−>ge
t_startpt(), rv, right_op
ening_direction, 1, this,
adj_body, list_of_point
s, side_vector, d1, bend_
arc_direction, bend_direc
tion, (BM_BENDLINE *) ab,
adj_bend_p2_line)) {list
_of_points = &(temp_dp−>n
ext) ;}break ;}// else op
en the dimension list// c
reate right flange dimens
ion point from start−poin
tif (temp_dp = create_dim
_point(bend_arc_outside_l
ength_proj, ((BM_LINE *)
edge)−>get_startpt(), rv,
right_opening_direction,
0, this, adj_body, list_o
f_points, side_vector, d
1, bend_arc_direction,ben
d_direction, (BM_BENDLINE
*) ab, adj_bend_p2_lin
e)) {list_of_points= &(te
mp_dp−>next) ;}// check i
f we can leave the dimens
ion list open and continu
eif (leave_dimension_open
(edge,bloop,side_vector,p
lane−>get_normal())) {fl_
dim_open = 1 ;break ;}//
create left flange dim po
int from end−point.if (te
mp_dp = create_dim_point
(bend_arc_outside_length_
proj, ((BM_LINE *) edge)−
>get_endpt(), rv, left_op
ening_direction, 0, this,
adj_body, list_of_point
s, side_vector, d1, bend_
arc_direction, bend_direc
tion, (BM_BENDLINE *) ab,
adj_bend_p2_line)) {list
_of_points = &(temp_dp−>n
ext) ;}// ok, close the d
imension list.fl_dim_open
= 0 ;// this is a small
trick that will save us s
ome time.// if the next e
dge is a line thatwill be
ignored, we can skip is
right now here.if (next_e
dge−>is(BM_ENTITY_TYPE_LI
NE) && next_edge != stop_
edge) {next_edge = (BM_ED
GE *) edge−>next() ;if (N
ULL == next_edge) next_ed
ge = bloop−>get_first_edg
e() ;}break ;}else if (fa
bs(td2 − flange_length) >
AUTODIM_DISTANCE_TOLERAN
CE) {// the start−point i
s not a flange dimension
point// if the end−point
isalso not a flange dimen
sion point, we can contin
ue.continue ;}// ok, only
the end−point is a flang
e dimension point.// two
possibilities. if wecan l
eave the dimension list o
pen (right now dimension
is // closed!) wedon’t ev
en have to open it, we ca
n just continue.if (leave
_dimension_open(edge,bloo
p,side_vector,plane−>get_
normal())) break ;// seco
nd possibility. now we ha
ve to create a left−right
flange dimension point./
/ dimension list stays cl
osed.if (temp_dp = create
_dim_point(bend_arc_outsi
de_length_proj, ((BM_LINE
*) edge)−>get_endpt(), r
v, right_opening_directio
n, 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= &(t
emp_dp−>next) ;}// this i
s a small trick that will
save us some time.// if
the next edge is a line t
hat will be ignored, we c
an skip is right now her
e.if (next_edge−>is(BM_EN
TITY_TYPE_LINE) && next_e
dge != stop_edge) {next_e
dge = (BM_EDGE *) edge−>n
ext() ;if (NULL == next_e
dge) next_edge = bloop−>g
et_first_edge() ;}}break
;case BM_ENTITY_TYPE_ARC
: {//note : we can alway
s ignore the start−point
of the arc !// because of
the way we keep track of
the open dimension list.
// make sure the dimensio
n list will be closed.fl_
dim_open = 0 ;// first, c
ompute start− and end−ang
les of the arc with respe
ct to the side vector.//
ie. convert start−and end
−angles so as if the side
−vector was the 0−angle v
ector.double startang =
((BM_ARC *) edge)−>get_st
artang() ;double endang =
((BM_ARC *)edge)−>get_en
dang() ;temp_v = side_vec
tor*(((BM_ARC *) edge)−>g
et_vx());double delta_ang
le = (temp_v.Len())/(((BM
_ARC *) edge)−>get_rad())
;if(delta_angle < −1.0)
delta_angle = −1.0 ;else
if (delta_angle > 1.0) de
lta_angle = 1.0 ;delta_an
gle = asin(delta_angle) ;
if (fabs((((BM_ARC *)edg
e)−>get_normal())%temp_v)
> 0.0) {startang += delt
a_angle ;endang +=delta_a
ngle ;if (startang > PI_t
imes_2) startang −= PI_ti
mes_2 ;if (endang > PI_ti
mes_2) endang −= PI_times
_2 ;}else {startang −= de
lta_angle ;endang −= delt
a_angle ;if (startang <
0.0) startang += PI_times
_2 ;if (endang < 0.0) end
ang += PI_times_2 ;}// co
mpute the extreme pointBM
_POINTarc_extreme_point ;
// 0−angle point is the e
xtreme pointif (endang <
startang) arc_extreme_poi
nt = ((BM_ARC *) edge)−>g
et_center() + (((BM_ARC
*) edge)−>get_rad())*side
_vector ;else arc_extreme
_point = *(((BM_ARC *)edg
e)−>get_edge_endpoint())
;// check the distance o
f the extreme pointif (!
compute_distance_from_ref
_point(rp, side_vector, &
arc_extreme_point, distan
ce1)) continue ;if (fabs
(distance1 − flange_lengt
h) <= AUTODIM_DISTANCE_TO
LERANCE) {// if we have t
he 0−angle point, create
a left−rightflange dimens
ion point.// otherwise if
next line is a non−ignor
ed line,don’t do anythin
g,// otherwise create a l
eft−right flange dimensio
n point.if (endang >= sta
rtang && leave_dimension_
open(edge,bloop,side_vect
or,plane−>get_normal()))
{continue ;}// create a l
eft−right flange dimensio
n point. dimension list s
tays closed.// this is a
1−point flange dimension
point.if (temp_dp = new B
M_AD_dim_corner(rv + arc_
extreme_point, this, adj_
body,right_opening_direct
ion, 1, list_of_points, N
ULL)) {list_of_points = &
(temp_dp−>next) ;}}}break
;case BM_ENTITY_TYPE_CIR
CLE : // circles are a mu
ch simpler version of the
arc case.{BM_POINT circl
e_extreme_point = ((BM_CI
RCLE *) edge)−>get_center
() + (((BM_CIRCLE *) edg
e)−>get_rad())*side_vecto
r ;// we won’t check the
distance since it must be
a flange dimension point
// create a left−right fl
ange dimension point.// t
his is a 1−point flange d
imension point.if (temp_d
p = new BM_AD_dim_corner
(rv + circle_extreme_poin
t, this, adj_body,right_o
pening_direction, 1,list_
of_points, NULL)) {list_o
f_points = &(temp_dp−>nex
t) ;}}break ;caseBM_ENTIT
Y_TYPE_ELLIPSE : // TODO
: implement ellipse her
e. should be similar to t
he way arc is handled.con
tinue ;break ;default : c
ontinue ; //unknown edge
type}}/* OK、全て終了。*/*list_of_points
= NULL ;return 1;}/*この関数は1つのBM_AD_bendline
構造に対するベンドラインディメンションポイントを計
算する。注意: p1は、フランジ長が描かれる隣接体の
平面上にある。pはセンタポイントである。 p2はベンド
ラインの側部のポイントである。注意:この関数におい
ては、我々は常にadj-body1およびadj-body2に対するベ
ンド-ディメンションポイントを計算する。このベンド
ラインは1または0の隣接体を持つことになるが、我々は
将来これらのポイントのビジビリテイを知る必要があ
る。*/int BM_AD_bendline::compute_BM_AD_bendline(v
oid){double metal_thickness ; // thickness of the
sheetmetalBM_2D_BODY *bendline_displayed_version ;
// 3D-version of the bendlineBM_VECTOR temp_v ; /
/ vector usedfor very short periods for storing te
mporary stuff// initally mark the 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 (NULL
== bend->get_part()) return 0 ;// this bendline ha
sto have a 3D-versionif (parent->get_view_type())
{if (NULL == (bendline_displayed_version = bend->g
et_current_3D_version())) return 0 ;}else {if (NUL
L == (bendline_displayed_version = bend->get_fla
t())) return 0 ;}metal_thickness = (bend->get_part
())->get_metal_thickness() ;/* ********** ********
** ********** ********** ********** ********** ***
******* ********** **********これは一時的な測度で
ある。我々は単に規則的なベンドラインを処理する。す
なわち、円錐ベンドラインは無視する。03/16/96. KK.
*/if (bend->get_bending_status() && bend->get_bend
_op() && ! (bend->get_bend_op())->is(BM_TYPE_BEND_
OP_REGULAR)) return 0 ;/* ********** ********** **
******** ********** ********** ********** ********
** ********** ********** */// get the number of ad
jacent bodies.adj_body1 = (bend->get_adj_list())->
find_lowest_id_adj_body() ;adj_body2 = (bend->get_
adj_list())->find_second_lowest_id_adj_body() ;num
_of_adjacent_bodies = (adj_body1 ? 1 :0) + (adj_bo
dy2 ? 1 : 0) ;/*サイドベクトルを計算する。*/if (ad
j_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_vect
or2)) return 0 ;side_vector2.normalise() ;}/*ベン
ドラインディメンションポイントを計算する。*/if (!
bend->get_bending_status() /* bendline not bent */
|| ! parent->get_view_type() /* flat view */) {//
note : here we don't know whether the dimension p
oint is OUTSIDE or INSIDE.// this has to be taken
into account later.// however, itshould 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 both adjacent bodies are the samebe
nd_body2_point_left.num_of_points = bend_body2_poi
nt_right.num_of_points = 1 ;bend_body2_point_left.
can_reverse_opening_dir = bend_body2_point_right.c
an_reverse_opening_dir = 0 ;bend_body2_point_righ
t.opening_direction = bend_body1_point_right.openi
ng_direction ;bend_body2_point_left.opening_direct
ion = bend_body1_point_left.opening_direction ;ben
d_body2_point_left.p = bend_body1_point_left.p ;be
nd_body2_point_right.p = bend_body1_point_right.p
;}else {// first, get some bending parametersBM_S
URFACE *surface = bendline_displayed_version->get_
surface() ;if (NULL == surface) return 0 ;BM_BEND_
OP *bop = bend->get_bend_op() ;if (NULL == bop) re
turn 0 ;double bend_angle = bop->get_bend_angle2()
;double bend_arc_angle = PI - bend_angle ;double
half_bend_arc_angle= bend_arc_angle/2.0 ;switch (s
urface->get_type()) {case BM_TYPE_CYLINDER : { //
note that the bend op can be both regular and coni
cBM_CYLINDER*cylinder = (BM_CYLINDER *) surface ;d
ouble radius = cylinder->get_rad() ;double outside
_radius = radius ;if (bendline_displayed_version->
get_sense()) outside_radius += metal_thickness ;//
set some common valuesbend_body1_point_left.can_r
everse_opening_dir = bend_body1_point_right.can_r
everse_opening_dir = 0 ;b
end_body1_point_right.ope
ning_direction = (bendlin
e_displayed_version−>get_
current_center_line()).ge
t_v() ;(bend_body1_point_
right.opening_direction).
normalise() ;bend_body1_p
oint_left.opening_directi
on = −(bend_body1_point_r
ight.opening_direction) ;
if (outside_radius <= AUT
ODIM_DISTANCE_TOLERANCE)
{// special case : outsid
e radius 0− trivial dimen
sion point.bend_body1_poi
nt_left.num_of_points = b
end_body1_point_right.num
_of_points = 1 ;bend_body
1_point_left.p = (bendlin
e_displayed_version−>get_
current_center_line()).ge
t_startpt() ;bend_body1_p
oint_right.p = (bendline_
displayed_version−>get_cu
rrent_center_line()).get_
endpt() ;bend_body2_point
_left.num_of_points = ben
d_body2_point_right.num_o
f_points = 1 ;bend_body2_
point_left.can_reverse_op
ening_dir = bend_body2_po
int_right.can_reverse_ope
ning_dir = 0 ;bend_body2_
point_right.opening_direc
tion = bend_body1_point_r
ight.opening_direction ;b
end_body2_point_left.open
ing_direction = bend_body
1_point_left.opening_dire
ction ;bend_body2_point_l
eft.p = bend_body1_point_
left.p ;bend_body2_point_
right.p = bend_body1_poin
t_right.p ;}else {bend_bo
dy1_point_left.num_of_poi
nts = bend_body1_point_ri
ght.num_of_points = 3 ;//
compute points p1 foradj
_body1bend_body1_point_le
ft.p1 = (bendline_display
ed_version−>get_current_c
enter_line()).get_startpt
() ;bend_body1_point_righ
t.p1 = (bendline_displaye
d_version−>get_current_ce
nter_line()).get_endpt()
;// the problem now is t
hat it could be that thes
e centerline points (whic
h are// onthe surface of
the bendline), could be o
nly inside surface of the
bendline.if (bendline_di
splayed_version−>get_sens
e() && metal_thickness >
AUTODIM_DISTANCE_TOLERANC
E) {temp_v = cylinder−>ge
t_vx() ;temp_v.set_length
(metal_thickness) ;bend_b
ody1_point_left.p1 = bend
_body1_point_left.p1 +tem
p_v ;bend_body1_point_rig
ht.p1 = bend_body1_point_
right.p1 + temp_v ;}// a
break in the computation
of adj_body1.p1.// store
current p1 values for adj
_body2 as well. this will
save some time.// // not
e that we should not real
ly compute adj_body2 poin
ts unless adj_body2 point
er// is not NULL. Howeve
r, this point (adj_body2.
p1) is very useful for co
mputing// adj_body1.p2 (i
f angle is acute). so we
compute it anyway.bend_bo
dy2_point_left.p1 = bend_
body1_point_left.p1 ;bend
_body2_point_right.p1 = b
end_body1_point_right.p1
;// finish adj_body1.p1.
rotate points p1 into th
eir final correct locatio
n.// note we rotate in th
e negative direction sinc
e adj_body1 is the smalle
st−index// adjacent body
as is ”to−the−left−of−the
−bendline−centerline”, wh
ich means// rotating to t
he left.// first, compute
the right vector for the
rotation line.BM_VECTOR
rot_v(cylinder−>get_v())
;if (rot_v % ((bendline_
displayed_version−>get_cu
rrent_center_line()).get_
v()) < 0.0) {rot_v.revers
e() ;}BM_rotate_point_aro
und_line(&(bend_body1_poi
nt_left.p1), cylinder−>ge
t_pt1(), rot_v, −half_ben
d_arc_angle) ;BM_rotate_p
oint_around_line(&(bend_b
ody1_point_right.p1), cyl
inder−>get_pt1(), rot_v,
−half_bend_arc_angle) ;//
finish also adj_body2.p
1. rotate points p1 into
their final correct locat
ion.BM_rotate_point_aroun
d_line(&(bend_body2_point
_left.p1), cylinder−>get_
pt1(), rot_v, half_bend_a
rc_angle) ;BM_rotate_poin
t_around_line(&(bend_body
2_point_right.p1), cylind
er−>get_pt1(), rot_v, hal
f_bend_arc_angle) ;// com
pute points pfor adj_body
1.double x ;if (bop−>is(B
M_TYPE_BEND_OP_REGULAR))
{x = ((BM_BEND_OP_REGULAR
*) bop)−>compute_3D_outs
ide_approx_per_side() ;}e
lse if(bop−>is(BM_TYPE_BE
ND_OP_CONIC)) {// TODO :
implement conic bendline
herereturn 0 ;}temp_v = −
x*side_vector1 ;bend_body
1_point_left.p = bend_bod
y1_point_left.p1 + temp_v
;bend_body1_point_right.
p = bend_body1_point_righ
t.p1 + temp_v ;// note :
adj_body1.p2 and adj_body
2.p, adj_body2.p2are yet
to be computed.// now the
re are two cases : 1) the
bend arc angle is acute
(ie. no more than 90 degr
ees),// 2) the bend arc a
ngle is more than 90 degr
ees.if (bend_arc_angle >
(PI_over_2 + BM_ANGLE_TOL
ERANCE)){ // use tangent
approximation// we will f
inish computing adj_body
1. adj_body1.p2 is left./
/ idea : notice that adj_
body1 is to the left of t
hebendline−centerline// b
ecause it is the lowest−i
ndex neighbor. Therefore
the cross−product// of ce
nterline−v by temp_v poin
ts towards the cylinder
(actually it is tangent//
to the cylinder).BM_VECT
OR tangent_v(bend_body1_p
oint_right.opening_direct
ion * temp_v) ;tangent_v.
set_length(x) ;bend_body1
_point_left.p2 = bend_bod
y1_point_left.p + tangent
_v ;bend_body1_point_righ
t.p2 = bend_body1_point_r
ight.p + tangent_v ;// no
te adj_body2.p1 is alread
y computed. first set som
e common values.bend_body
2_point_left.num_of_point
s = bend_body2_point_righ
t.num_of_points = 3 ;bend
_body2_point_left.can_rev
erse_opening_dir = bend_b
ody2_point_right.can_reve
rse_opening_dir = 0 ;bend
_body2_point_right.openin
g_direction = bend_body1_
point_right.opening_direc
tion ;bend_body2_point_le
ft.opening_direction = be
nd_body1_point_left.openi
ng_direction ;// now comp
ute adj_body2.ptemp_v = −
x*side_vector2 ;bend_body
2_point_left.p = bend_bod
y2_point_left.p1 + temp_v
;bend_body2_point_right.
p = bend_body2_point_righ
t.p1 + temp_v ;// finall
y, compute adj_body2.p2//
note the order in the cr
oss−product !tangent_v =
temp_v * bend_body2_point
_right.opening_direction
; tangent_v.set_length
(x) ;bend_body2_point_lef
t.p2 = bend_body2_point_l
eft.p+ tangent_v ;bend_bo
dy2_point_right.p2 = bend
_body2_point_right.p + ta
ngent_v ;}else { // use i
ntersection approximation
// note : adj_body2.p2is
the same as asj_body1.p1.
bend_body1_point_left.p2
= bend_body2_point_left.p
1 ;bend_body1_point_righ
t.p2 = bend_body2_point_r
ight.p1 ;// whenusing int
ersection approximation,
dimensions points with re
spect to// both adjacent
bodies are the same, so w
e just copy them.bend_bod
y2_point_left.num_of_poin
ts = bend_body2_point_rig
ht.num_of_points = 3 ;ben
d_body2_point_left.can_re
verse_opening_dir = bend_
body2_point_right.can_rev
erse_opening_dir = 0 ;ben
d_body2_point_right.openi
ng_direction = bend_body1
_point_right.opening_dire
ction ;bend_body2_point_l
eft.opening_direction =be
nd_body1_point_left.openi
ng_direction ;// note we
are switching pointsbend_
body2_point_left.p2 = ben
d_body1_point_left.p1 ;be
nd_body2_point_right.p2 =
bend_body1_point_right.p
1 ;bend_body2_point_left.
p = bend_body1_point_lef
t.p ;bend_body2_point_rig
ht.p = bend_body1_point_r
ight.p ;}}}break ;case BM
_TYPE_CONE :break ;defaul
t : ; // unknown or illeg
al surface ;}}/*隣接体の各々に対す
るフランジ長を計算する。*/if (adj_body1) {// if th
e flange length computation fails, pretend the adj
acent body does not exist. for simplicity.if (! be
nd->compute_flange_length(parent->get_view_type(),
adj_body1,fl1)) {adj_body1 = NULL ;--num_of_adjace
nt_bodies ;}}if (adj_body2) {if (! bend->compute_f
lange_length(parent->get_view_type(),adj_body2,fl
2)) {adj_body2 = NULL ;--num_of_adjacent_bodies
;}}/*よし、データを有効なものとしてマークする。ベ
ンドラインディメンションポイントが全てのベンドライ
ンに対して計算されると、我々は同様に巣手のベンドラ
インに対してフランジディメンションポイントを計算す
ることが出来る。*/data_valid = 1 ;// before we can
return, we have to check if body1,2 left(right)be
ndline dimension points // are the same.// note th
e same means not the same pointers, but the conten
ts are equivalent.if (adj_body1 && adj_body2) {bod
y12_left_the_same = (bend_body1_point_left == bend
_body2_point_left) ;body12_right_the_same = (bend_
body1_point_right == bend_body2_point_right) ;}/*
重要:ベンド-ディメンションポイントのいずれかが1ポ
イント(ポイントp)のみを含むときは、実際には見る
べきベンドラインがないのでbody_required_visibleポ
インタは隣接体を指示するべきである。*/if (1 == ben
d_body1_point_left.num_of_points) bend_body1_point
_left.body_required_visible = adj_body1 ;if (1 ==
bend_body1_point_right.num_of_points) bend_body1_p
oint_right.body_required_visible = adj_body1 ;if
(1 == bend_body2_point_left.num_of_points) bend_bo
dy2_point_left.body_required_visible = adj_body2 ;
if (1 == bend_body2_point_right.num_of_points) ben
d_body2_point_right.body_required_visible = adj_bo
dy2 ;return 1 ;}/*********** ********** **********
********** ********** ********** ********** *****
***** **********BM_AUTO_DIMENSION class stuff.****
****** ********** ********** ********** **********
********** ********** ********** ***********//*確
実な発見的手法:ソリッドモードにおいて幾つかのポイ
ントを我々が無視出来るか否かをチェックする。ソリッ
ドモードにおいては、我々は時間の節約のためにこの発
見的手法を用いている。2つのベンドラインがフランジ
-長を表示するために(潜在的に)等価なフランジ-ディ
メンションポイントを用いているときは、我々は単に、
より高いidxを持つベンドライン(これらの2つのベン
ドラインに対する)に対してのみビジビリテイ情報を計
算する。*/void BM_AUTO_DIMENSION::compute_points_t
o_ignore_in_solid(void){int i ;BM_AD_dim_corner *t
emp_point ;for (i = 0 ; i < num_of_bendlines ; i+
+) {if (! bends[i]->data_valid) continue ;if (bend
s[i]->adj_body1) {for (temp_point = bends[i]->body
1_points ; temp_point ; temp_point = temp_point->n
ext) {if (NULL == temp_point->adj_bendline) contin
ue ;if ((temp_point->adj_bendline)->get_idx() > (b
ends[i]->bend)->get_idx()) continue ;if (check_two
_bendlines_adjacent_to_same_flange(bends[i]->bend,
bends[i]->adj_body1,temp_point->adj_bendline)) {te
mp_point->ignore_in_solid_mode = 1 ;}}}if (bends
[i]->adj_body2) {for (temp_point = bends[i]->body2
_points ; temp_point ; temp_point= temp_point->nex
t) {if (NULL == temp_point->adj_bendline) continue
;if((temp_point->adj_bendline)->get_idx() > (bend
s[i]->bend)->get_idx()) continue ;if (check_two_be
ndlines_adjacent_to_same_flange(bends[i]->bend,ben
ds[i]->adj_body2,temp_point->adj_bendline)) {temp_
point->ignore_in_solid_mode = 1 ;}}}}points_to_ign
ore_in_solid_computed = 1 ;}/*この関数は自動寸法化
ベンドラインを構成し、データ構造を指示する。これは
ディメンションポイントを計算する主要関数である。*/
int BM_AUTO_DIMENSION::compute_auto_dimension_data
(void){int i ;// have to have a documentif (NULL =
= doc)return 0 ;// if no part, try to get a new pa
rt from the documentif (NULL == part) {set_part(do
c->get_part()) ;}if (NULL == part) {dirty = 0 ;ret
urn 1 ;}points_to_ignore_in_solid_computed = 0 ;/*
ビユータイプを得る。*/if (view) {view_type = view-
>get_current_view() ;}else {// we are screwedretur
n 0 ;}/*全てのベンドラインに対して全てのベンドライ
ンディメンションポイントを計算する。*/for (i = 0 ;
i < num_of_bendlines ; i++) {bends[i]->compute_BM
_AD_bendline() ;}/*全てのベンドラインに対してフラ
ンジディメンションポイントを計算する。*/for (i = 0
; i < num_of_bendlines ; i++){if (bends[i]->data_
valid) {if (bends[i]->adj_body1) bends[i]->compute
_BM_AD_flange_points(bends[i]->adj_body1) ;if (ben
ds[i]->adj_body2) bends[i]->compute_BM_AD_flange_p
oints(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_DIM
ENSION:: ̄BM_AUTO_DIMENSIO
N(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 bends[i] ;}delete [] bends ;
bends = NULL ;}num_of_bendlines = 0 ;points_to_ign
ore_in_solid_computed = 0 ;part = NULL ;dirty= 1
;}/*この関数は所定のベンドラインに係わるディメン
ションデータを含むBM_AD_bendline構造に対するポイン
タを戻す。*/BM_AD_bendline *BM_AUTO_DIMENSION::get
_AD_bend_structure(BM_BENDLINE *bendline){int i ;f
or (i = 0 ; i< num_of_bendlines ; i++) {if (bends
[i]->bend == bendline) return bends[i] ;}return NU
LL ;}/*この関数は所定のadj-bodyに対する所定のベン
ドラインに対する(p->p2)ベクトルを戻す。それはまた
このフランジに対する隣接ベンドラインのベンドディメ
ンションポイントのp2ポイントの間のラインを計算す
る。*/BM_VECTOR const& BM_AUTO_DIMENSION::compute_
bend_direction_vector(BM_BENDLINE *bendline, BM_3D
_BODY *adj_body, BM_LINE *p2_line){static BM_VECTO
R v ;int i ;for (i = 0 ; i < num_of_bendlines ; i+
+) {if (bends[i]->data_valid && bends[i]->bend ==
bendline) {if (bends[i]->adj_body1 == adj_body) {v
= (bends[i]->bend_body1_point_left).p2 - (bends
[i]->bend_body1_point_left).p ;p2_line->set((bends
[i]->bend_body1_point_left).p2,(bends[i]->bend_bod
y1_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_lef
t).p ;p2_line->set((bends[i]->bend_body2_point_lef
t).p2,(bends[i]->bend_body2_point_right).p2) ;retu
rn v ;}}}return BM_null_vector ;}/*この関数は、フ
ランジディメンションポイントが所定のadj-bodyに隣接
するという事実を考慮するため所定のベンドラインに対
するフランジ長を描く効果を伝搬させるために用いられ
る。それは、 adj-bendが所定のフランジに対して同様
に描かれるものとしてマークされるときTRUEを戻す。*/
int BM_AUTO_DIMENSION::compute_effects_flange_leng
th_drawn(BM_BENDLINE *bendline, BM_3D_BODY *adj_bo
dy, BM_AD_dim_corner *bend_dim_point /* bend dim p
oint for bendline */, BM_AD_dim_corner *flange_dim
_point /* flange dim points forbendline */, BM_BEN
DLINE *adj_bend){BM_AD_dim_corner **p_body_points
;int *p_body_drawn ;BM_AD_dim_corner **p_drawn_be
nd_dim_point ;BM_AD_dim_corner **p_drawn_flange_di
m_point ;int i ;// first we have to find a BM_AD_b
endline structure for this adj-bendfor (i = 0 ; i
< num_of_bendlines ;i++) {if (! bends[i]->data_val
id || bends[i]->bend != adj_bend || bends[i]->igno
re) continue ;if (bends[i]->adj_body1 == adj_body)
{if (bends[i]->body1_drawn) return 0 ;p_body_poin
ts = &(bends[i]->body1_points) ;p_body_drawn = &(b
ends[i]->body1_drawn) ;p_drawn_bend_dim_point= &(b
ends[i]->drawn_bend_dim_point1) ;p_drawn_flange_di
m_point= &(bends[i]->drawn_flange_dim_point1) ;bre
ak ;}else if (bends[i]->adj_body2 == adj_body) {if
(bends[i]->body2_drawn) return 0 ;p_body_points =
&(bends[i]->body2_points) ;p_body_drawn = &(bends
[i]->body2_drawn) ;p_drawn_bend_dim_point = &(bend
s[i]->drawn_bend_dim_point2) ;p_drawn_flange_dim_p
oint = &(bends[i]->drawn_flange_dim_point2) ;break
;}else return 0 ;}if (i >= num_of_bendlines) retu
rn 0 ;// now we need to check if the list of flang
e dimensionpoints for this newly found // BM_AD_be
ndline structure contains any flange dimension poi
nts that are adjacent to our bendlineBM_AD_dim_cor
ner*temp_point ;for (temp_point = *p_body_points ;
temp_point ; temp_point= temp_point->next) {if (t
emp_point->adj_bendline == bendline) break ;}if (N
ULL == temp_point) return 0 ;// mark the flange le
ngth for the adj-bend drawn with respect to this a
dj-body*p_body_drawn = 1 ;*p_drawn_bend_dim_point
= flange_dim_point ;*p_drawn_flange_dim_point = be
nd_dim_point;return 1 ;}/*この関数は、 adj_bend
が、所定のベンドラインに隣接する所定のフランジに対
してフランジ-ディメンションポイントを持つときTRUE
を戻す。*/int BM_AUTO_DIMENSION::check_two_bendlin
es_adjacent_to_same_flange(BM_BENDLINE *bendline,
BM_3D_BODY *flange, BM_BENDLINE *adj_bend){BM_AD_d
im_corner **p_body_points ;int i ;// first we have
to find a BM_AD_bendlinestructure for this adj-be
ndfor (i = 0 ; i < num_of_bendlines ; i++) {if(! b
ends[i]->data_valid || bends[i]->bend != adj_bend)
continue ;if (bends[i]->adj_body1 == flange) {p_b
ody_points = &(bends[i]->body1_points);break ;}els
e if (bends[i]->adj_body2 == flange) {p_body_point
s = &(bends[i]->body2_points) ;break ;}else return
0 ;}if (i >= num_of_bendlines)return 0 ;// now we
need to check if the list of flange dimension poi
ntsfor this newly found // BM_AD_bendline structur
e contains a flange dimension points that is adjac
ent to our bendlineBM_AD_dim_corner *temp_point ;f
or (temp_point = *p_body_points ; temp_point ; tem
p_point = temp_point->next) {if (temp_point->adj_b
endline == bendline) return 1 ;}return 0;}/*新しい
部分を設定する。これは同様にビユークラスポインタを
更新し、幾つかの他のパラメータを設定する。*/void B
M_AUTO_DIMENSION::set_part(BM_PART *new_part){BM_B
ENDLINE *bendlist ;int i ;delete_contents() ;if (N
ULL== doc) return ;part = new_part ;if (NULL == pa
rt) return ;half_metal_thickness = (part->get_meta
l_thickness())/2.0 ;// allocate the bendlistif(0 =
= (num_of_bendlines = part->get_number_of_bendline
s())) return ;if (NULL == (bends = new BM_AD_bendl
ine*[num_of_bendlines])) goto failure ;bendlist =
part->get_bendline_list() ;for (i = 0 ; i < num_of
_bendlines ;i++) {if (bendlist) {bends[i] = new BM
_AD_bendline(this,bendlist) ;bendlist = (BM_BENDLI
NE *) bendlist->next() ;}else bends[i] = NULL ;}//
note, dirty is TRUEreturn ;failure :delete_conten
ts() ;} 付録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_edg
e){ 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 so by
calling either // map_3d_to_screen_solid or map_3
d_to_screen_wire, depending on whether wireframe o
r solid is being shown. // On return, iff *x_pos,
*y_pos are both zero, the point was not mapped ont
o the screen atall.int CBendCADViewPart::map_3d_to
_screen(BM_POINT three_d_point, int*x_pos, int *y_
pos, double *z_depth){ int visible; if(mi_show_
solid)visible = map_3d_to_screen_solid(three_d_poi
nt, x_pos, y_pos, z_depth);else visible = map_3d_t
o_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 OpenGLutilities // (ie. when wireframe is
on). If return value is 0, point isnot mapped ont
o screen, ie. not visible.int CBendCADViewPart::ma
p_3d_to_screen_wire(BM_POINT three_d_point, int *x
_pos, int *y_pos, double *z_depth){ int viewpor
t[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,v
iewport, &width, &height, &depth); if( ((int)widt
h > m_old_rect.right) || ((int)width < 0) ) visibl
e = 0; if( ((int)height > m_old_rect.bottom) ||
((int)height < 0) ) visible = 0; if(x_pos)*x_pos
= (int) width; if(y_pos) *y_pos = (m_old_rect.bot
tom - (int) height); if(z_depth) *z_depth = 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, gi
ven the three-dimensional worldcoordinates of the
point, using RenderWare utilities // (ie. when sol
idis on). If return value is 0, point is not mappe
d onto the screen, ie.not visible.// Note: At pres
ent, same as map_3d_to_screen_wire.int CBendCADVie
wPart::map_3d_to_screen_solid(BM_POINT three_d_poi
nt, int *x_pos,int *y_pos, double *z_depth){ in
t viewport[4], visible = 1; double width, height,
depth; double model_mat[16], proj_mat[16], array
[16]; //Get the current viewport coords. glGetIn
tegerv(GL_VIEWPORT, viewport);// Now build a model
view matrix out of the current set of transformati
ons. glMatrixMode(GL_MODELVIEW); glPushMatrix();
glTranslated(md_x_trans, md_y_trans, 0.0);conv
ert_rw_matrix_to_gl_array(md_rot_matrix, array);gl
MultMatrixd(array);glTranslated(- m_part_centroid.
X(), - m_part_centroid.Y(), - m_part_centroid.
Z()); glGetDoublev(GL_MODELVIEW_MATRIX,model_ma
t); glGetDoublev(GL_PROJECTION_MATRIX, proj_ma
t); glPopMatrix(); gluProject(three_d_point.X(),
three_d_point.Y(), three_d_point.Z(), model_mat,
proj_mat, viewport, &width,
&height,&depth); if( ((int)width > m_old_rect.rig
ht) || ((int)width < 0) ) visible = 0; if( ((int)
height > m_old_rect.bottom) || ((int)height < 0) )
visible = 0; if(x_pos) *x_pos = (int) width; if
(y_pos) *y_pos = (m_old_rect.bottom - (int) heigh
t); if(z_depth) *z_depth = depth; return visib
le; }// This function picks the point indicated b
y map_3d_to_screen, using RenderWare picking, so t
his is// called only when solid is beingshown. Not
e that the pick position is with respect to the to
p left// corner of the view window being (0,0). If
the pick results in an edge, a pointer to the edg
e is// passed back in picked_edge; else, picked_ed
ge isset to null. This does not modify the selecti
on// set in any way.void CBendCADViewPart::pick_po
int_rw(int x_pos, int y_pos, BM_EDGE **picked_edg
e) { if(picked_edge == NULL) return; if( (x_pos
> m_old_rect.right) || (y_pos > m_old_rect.botto
m)) { // Make sure point given is within*picked_e
dge = NULL;// viewport.return; } RwClump *picke
d_clump = NULL;RwClump *parent_clump = NULL; long
parent_tag, clump_tag, key = 0; BM_EDGE *edge =
NULL; if(! RwPickScene(m_scene, x_pos, y_pos, m_c
amera, &m_pick)) { // Picking command was not succ
essful. *picked_edge = NULL;return; } if(m_pi
ck.type == rwNAPICKOBJECT) { //
Noclump was picked.*picked_edge = NULL;return; }
else if(m_pick.type ==rwPICKCLUMP) {
// Some clump was picked; process it.picked_
clump = m_pick.object.clump.clump;parent_clump = R
wGetClumpParent(picked_clump);parent_tag = RwGetCl
umpTag(parent_clump);clump_tag = RwGetClumpTag(pic
ked_clump);if(parent_tag == 1) { *picked_edge = N
ULL; return;
// A trivial bendline or forming was picked.
} // Now some real edge was picked.key = (pare
nt_tag%10000)*100000 + clump_tag; if(clump_tag) //
Safety check; we expectclump_tag to be non-zero.
*picked_edge = map_list_name_to_bm_edge(paren
t_tag, clump_tag); }} // This function retur
ns the ratio of the view volume dimension (object
space dimensions) to// the viewport dimension (dev
ice 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.right); else ratio =
0.0;return ratio;}/* Given a BM_POINT, which repr
esents a point in world coordinates, one can proje
ct it onto view window coordinates. This function
first checks if the projected point is within the
viewing volume. If it IS within viewing volume, th
e pointer "visible" carries value 1; else,0. If th
e point is not visible, no other parameters have a
ny meaning; the return value is 0. Now suppose th
e point is visible. A) If the display is showing
the SOLID version of the part, this function check
s if ANY of the three_d_bodies in the array "three
_db_array" lies "approximately under" the projecte
d point. If the answer is yes, return value is 1;
else, return value is zero. The x_pos, y_pos, and
z_depth pointers carrythe view windo
w coordinates (with top l
eft corner as (0,0)) and
the z−buffer value. The a
rray ”thee_db_array” must
be terminated by a NULL
pointer to indicate end o
f array. B) If the displ
ay is showing the WIREFRA
MEversion of the part the
return value is always z
ero. If the point is wit
hin view volume, *visible
is set to 1; else, 0. If
*visible is 1, x_pos, y_
pos and z_depth values ha
ve the meaning mentioned
above. */int CBendCADView
Part::is_3d_body_near_poi
nt(BM_POINT const& three_
d_point, BM_3D_BODY **thr
ee_db_array,

int *visible, int *x_po
s, int *y_pos, double *z_
depth){ int x, y, is_vis
ible = 1; double z; int
found = 0; is_visible =
map_3d_to_screen(three_d
_point, &x, &y, &z); if
( ! is_visible) {
// Point is outside
viewing volume.if(x_pos)
*x_pos = x;if(y_pos) *y_p
os = y;if(z_depth) *z_dep
th = z;if(visible) *visib
le = 0;return 0; } // N
ow point is inside view v
olume. if(x_pos) *x_pos
= x; if(y_pos) *y_pos =
y; if(z_depth) *z_depth
= z; if(visible) *visibl
e = 1; if(! mi_show_soli
d) {// Wireframe being dr
awn; just return that poi
nt is return 1; // within
view volume. } // Now
solid is being shown. if
(! three_db_array)return
0; // Point is within vi
ew volume. Pick pixels in
a triangle around that p
oint. 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_d
b_array); if(found) retu
rn 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; return 0;}// This
function picks the point
indicated, using RenderW
are picking, so this is c
alled only when solid is
// being shown. Notethat
the pick position is with
respect to the top left
corner of the view window
being // (0,0). If the p
ick results in a three_d_
body’s clump,and the pick
ed clump corresponds to A
NY of the// three_d_bodi
es in thearray passed, re
turn value is 1; if no ma
tch or no three_d_body, r
eturnis 0.// This does no
t modify the selection se
t in any way.int CBendCAD
ViewPart::pick_point_for_
3db_rw(int x_pos, int y_p
os, BM_3D_BODY **three_db
_array) { if(three_db_ar
ray == NULL) return 0; i
f( (x_pos > m_old_rect.ri
ght) || (y_pos > m_old_re
ct.bottom)) { // Make su
re point given iswithinre
turn 0;
// viewport. }
RwClump *picked_clump
= NULL; RwClump *parent_
clump = NULL; long paren
t_tag, clump_tag, require
d_id;int found = 0; if
(! RwPickScene(m_scene, x
_pos, y_pos, m_camera, &m
_pick)) { // Picking comm
and was not successful.re
turn 0; } if(m_pick.typ
e == rwNAPICKOBJECT) {
// No clu
mpwas picked.return 0; }
else if(m_pick.type ==
rwPICKCLUMP) {// Some clu
mp was picked; process i
t. picked_clump = m_pi
ck.object.clump.clump;par
ent_clump = RwGetClumpPar
ent(picked_clump);parent_
tag = RwGetClumpTag(paren
t_clump);clump_tag = RwGe
tClumpTag(picked_clump);i
f(parent_tag == 1) {
// Body of fa
ce/bendline/formingwas pi
cked.for(int i=0; three_d
b_array[i]; ++i) { // Che
ck if it matchesany of th
e ones in array.if(three_
db_array[i] == NULL) brea
k;required_id= three_db_a
rray[i]−>get_idx();if(clu
mp_tag%10000 == required_
id) {found = 1;break;}}re
turn found;} // Now so
me edge’s clump was picke
d. Check if it matches an
y of the ones in array.fo
r(int i=0; three_db_array
[i]; ++i) {if(three_db_ar
ray[i] == NULL) break;req
uired_id = three_db_array
[i]−>get_idx();if(parent_
tag%10000 == required_id)
{found = 1;break;}} }
return found;} // This
allows the user to inser
t items into the selectio
n set. ”list” is an array
of pointers// to three−d
−bodies, terminated by NU
LL to indicate end of arr
ay. If list is passed as
NULL, every // three−d−bo
dy in the part is inserte
d into the selection set.
voidCBendCADViewPart::in
sert_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 s
election set.BM_PART *par
t = NULL;CBendCADDoc*pDoc
= GetDocument();ASSERT_V
ALID(pDoc);part = pDoc−>g
et_part();if(! part) retu
rn; BM_FACE *face = NUL
L;BM_BENDLINE *bendline =
NULL;BM_FORMING*forming
= NULL;for(face = part−>g
et_face_list(); face; fac
e = (BM_FACE*)face−>nex
t()) { if(! face) contin
ue;tag = 100000*(face−>ge
t_idx()) +10000 + face−>g
et_idx();if(! m_selection
_set.find(tag, NULL)) {da
ta = new BV_SELECT_DATA;d
ata−>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(bend
line = part−>get_bendline
_list(); bendline; bendli
ne = (BM_BENDLINE *)bendl
ine−>next()) { if(! bend
line) continue;tag = 1000
00*(bendline−>get_idx())
+ 10000 + bendline−>get_i
dx();if(! m_selection_se
t.find(tag, NULL)){data =
new BV_SELECT_DATA;data−
>key = tag;data−>edge = N
ULL;data−>world_pt = BM_P
OINT(0.0, 0.0, 0.0);m_sel
ection_set.insert(tag, (l
ong)data);}}for(forming =
part−>get_forming_lis
t(); forming; forming =
(BM_FORMING*)forming−>nex
t()) { if(! forming) con
tinue;tag = 100000*(formi
ng−>get_idx()) + 10000 +
forming−>get_idx();if(! m
_selection_set.find(tag,
NULL)) {data = new BV_SEL
ECT_DATA;data−>key = tag;
data−>edge = NULL;data−>w
orld_pt = BM_POINT(0.0,
0.0, 0.0);m_selection_se
t.insert(tag, (long)dat
a);}}DrawPart(m_hdc);retu
rn;}BM_3D_BODY *three_d_b
ody;long i;for(i=0, three
_d_body = list[0]; three_
d_body; ++i, three_d_body
= list[i]) { if(! three
_d_body) break;tag = 1000
00*(three_d_body−>get_idx
()) + 10000 + three_d_bod
y−>get_idx();if(! m_selec
tion_set.find(tag, NULL))
{data = new BV_SELECT_DA
TA;data−>key = tag;data−>
edge = NULL;data−>world_p
t = BM_POINT(0.0, 0.0, 0.
0);m_selection_set.insert
(tag, (long)data);}}DrawP
art(m_hdc);return;}// Thi
s function returns the la
rgest of the x, y and z p
rojections of the part’s/
/ bounding box.double CBe
ndCADViewPart::get_approx
_part_size(void){ if(md_
part_bbox_size) { doub
le size = __max(md_part_b
box_size[0], md_part_bbox
_size[1]); size = __ma
x(size, md_part_bbox_size
[2]); return size; }
else return 0.0;}// This
function passes back the
bounding box size of the
part in its original ori
entation, in the// array
”dimensions”. This array
should be at least of si
ze 3. Returns 1if success
ful, 0 otherwise.// Cauti
on: This is a quick and h
ence not very accurate ca
lculation; if you want gr
eater precision,// write
your ownfunction.int CBen
dCADViewPart::get_part_di
mensions(double *dimensio
ns){CBendCADDoc* pDoc = G
etDocument();if(! pDoc) r
eturn 0;BM_PART *part =pD
oc−>get_part();if(! part)
return 0;if(! dimension
s) return 0;int i;BM_POIN
T centroid;RwMatrix4d *te
mp = RwCreateMatrix();i =
compute_part_centroid(pa
rt, 1, &centroid);if(! i)
return 0; i = compute_p
art_bbox(part,1, temp, ce
ntroid, dimensions, NUL
L); if(! i) return 0;RwDe
stroyMatrix(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-dat
e'とマークされる。我々がこの古い変換マトリクスを用
いたときは、結果は悪くなる。従って、我々は実際に古
い(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 *first
_hole ;BM_BENDLINE *first_bendline ;BM_FORMING *fi
rst_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_face
s_adjacent_to_bendlines(...)をコールせよ。更に、新
しい厚さを設定し、次に隣接面を一致させると共に新し
い最新の2D->3D変換を計算するset_metal_thickness_up
date_part(...)を用いよ。*/void set_metal_thickness
(double thickness) ;void set_metal_thickness_updat
e_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
_bendline_dimensions_status(void) const { return b
endline_dimensions_status ; }// to set the new sta
tus.// for example, if we set it to TRUE, then fro
m this point on, BMAPI//will try to keep to curren
t part dimensions constant.void set_bendline_dimen
sions_status(int new_bendline_dimensions_status) ;
/*ベンドシーケンス関係関数*/void delete_bend_seque
nce(void) ;inline long get_bend_sequence_size(voi
d) const { return bend_sequence_size ; }// this fu
nction returns the number of bendlines copied into
OUT arrayint get_bend_sequence(BM_BENDLINE *bendl
ines[], long bendlines_array_length) ;// this func
tionsets a new bend sequence for this bendlineint
set_bend_sequence(BM_BENDLINE **bendlines, long be
ndlines_array_length) ;// this function checks is
a bendline is in the current bend sequence of the
part.// if yes, it returns its index in the bend s
equence (ie. the number of this bendline//in the b
end sequence order). This index is from 0 through
sequence_lenght - 1.// if this bendline is not in
the bend sequence, it returns -1.int is_bendline_i
n_bend_sequence(BM_BENDLINE *bendline) ;// this fu
nctionremoves a bendline from the bend sequence.//
note that if the bendline is in a simultaneous be
nd property, it will replace the bendline// with a
nother bendline from the simultaneous bend propert
y that is not alreadyin the bend sequence.void rem
ove_bendline_from_bend_sequence(BM_BENDLINE*bendli
ne) ;// this function deletes the current bend seq
uence (if oneexists) and creates a default // bend
sequence.void create_default_bend_sequence(void)
;/*この関数は、孔を含まない全てのベンドラインのフ
ラットバージヨンを排除する。この関数は、部分がアン
フォルドされた後有用になり得る。通常は、部分のフォ
ルドされたバージヨンはトリビアルでないベンドライン
(すなわち、0でないインサイド半径および/または厚
さ)を含む。部分がアンフォルドされたとき、BMAPIは
これらのベンドラインを、それらが有るように正確にフ
ラットバージヨンに変換する。たとえば、ゼロ以外の厚
みまたは半径を有するベンドラインの3D-バージョンに
は通常、曲がった弧が描かれる。これは平面バージョン
のベンドラインにマッピングされる。これはパートの平
面バージョンにおいて、ベンドラインに対応する2つの
面の間に長方形が存在することを意味する。ただし我々
は、この矩形を見たくないときがある。この関数は、単
純な平面(つまり平面に穴がない)を有し、2つの面に
正確に隣接するベンドラインだけを処理する。 この関
数は、隣接するすべての面を切り取って(トリミン
グ)、ベンドラインの中心線に接触させ、ベンドライン
平面におけるすべての輪(ループ)を削除する。この関
数は通常UNFOLDの直後に使われることに注意せよ。いっ
たん平面がトリミングされると、それは隣接する面にも
適合する。これは、この関数がいくつかの特殊なトリミ
ング値を計算および設定し、後ほど我々がパートをたた
む(フォルドする)ときに、面がベンドラインに正確に
接する正しい3D-バージョンを得ることを意味する。こ
の関数はベンドラインを変えない。*/voideliminate_si
mple_bendlines_in_flat_version_A(void) ;/*この関数
は、パートにおけるすべての3D-ボディを走査して(フ
ォーミングを除く)、それらの平面バージョンを整え
る。基本的にこの関数は、パートにおけるすべての3D_b
ody(フォーミングを除く)に対してBM_2D_BODY::fix_f
lat()関数を呼び出す。この関数は現行の平面バージョ
ンのみをチェックするので注意せよ。この関数は、何ら
かの操作が失敗するか(つまりメモリー割り当て)、ま
たはこの関数が解決できない問題を発見したときにFAIL
UREを返す。*/int fix_flat(void) ;/*この関数は、フ
ェース・ノーマル(face normal)がベンドラインの定
義に合致していることをチェックする。たとえば、face
1が法線を持ち(0,0,1)、face1とface2との間に90度のFR
ONTベンドがある場合、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バージョンを強制的に計算させる。具体的にBM
APIは、面−穴−ベンドラインのすべてをチェックし、3
Dバージョンが新しくなければ、BMAPIは2D->3D変形を用
いてフラットから最新の3Dバージョンを計算する。2D->
3D変形が新しくない場合、BMAPIは最新の有効な2D->3D
変形の計算を試みる。また、あるベンドラインについて
新しい3D-バージョンが計算されるとき、BMAPIは初めに
隣接するベンドラインを適合させる。*/void bring_3D_
up_to_date(void) ;/*********** ********** ********
** ********** ********** ********** ********** ***
******* **********2D->3D変形関数********** *******
*** ********** ********** ********** ********** **
******** ********** ***********//*この関数はすべて
の変形をアイデンティティ変形(identity transformat
ion)にリセットする。さらにこの関数は、すべてのベ
ンドラインにおける'bending_status'変数をFALSEに設
定する。さらにこの関数は、すべての面のすべての3Dバ
ージョンを'not-up-to-date'(非最新)と記すが、ただ
しその再計算は行なわない。3D->2D変形はリセットでき
ないので、この関数が2D->3D変形のみをリセットするこ
とに注意せよ。*/void reset_all_transformations(voi
d) ;/*パートの2D->3D変形をリセットする。'body'は、
アイデンティティ変形になる変形を持つ面である。他の
ボディは、この基本ボディ(ベース・ボディ)に関する
屈曲情報に従って、各々の変形を設定する。この関数
は、すべての変形母体(マトリックス)を更新する。基
本的にこの関数では、ユーザーがパート全体に行なった
回転や移動のすべてを取り消し(アンドゥー)できる。
*/void reset_part_2Dto3D_transformations(BM_3D_BOD
Y *base_body) ;/*********** ********** **********
********** ********** ********** ********** ******
**** **********これらの関数は、ユーザーにパートの
回転または移動を実施させる。たとえば、屈曲のとき、
ユーザーはパートの反転を希望することがある。これら
の関数は、パート全体に均一に作用する。すなわち、す
べての面−穴−ベンドラインが全く同様に変化する。こ
れらの関数が2D->3D変形であることに注意せよ。すなわ
ち、これらの関数はパートの3Dバージョンだけを変更す
るが、これらの関数はパートの平面バージョンの計算を
要する。基本的にこれらの関数が実施する唯一のこと
は、すべてのボディに付随する2D-3D変形を変更し、す
べてのボディの3D-バージョンを'not-up-to-date'(非
最新)と記すことである。********** ********** ****
****** ********** ********** ********** **********
********** ***********//*パート全体を線を軸に一定
の角度(ラジアン単位)で回転させる。正の方向は、線
の方向を見たときの時計回りである。*/void rotate(BM
_LINE const& line, double const angle) ;/*パート全
体をこのベクトルで移動する*/void translate(BM_VECT
OR const& translation_vector) ;/*この変形をパート
に適用する*/void transform(BM_TRANSFORM const& tra
nsformation) ;/*********** ********** ********** *
********* ********** ********** ********** *******
*** **********FOLD関数。FOLD.CPPモジュール内******
**** ********** ********** ********** ********** *
********* ********** ********** ***********//*パー
トの3Dバージョンを計算する。この関数は、ベース・ボ
ディに従ってパートの3Dバージョンを計算する。つま
り、'base_body'は留まり、パートの残りの部分は動
く。これまでパート全体に回転や移動を実行した場合、
回転または移動はこの操作の後にも有効であるので注意
せよ。通常ユーザーは、いくつかのベンドライン・パラ
メータを設定してから、この関数を呼び出してパートを
更新することを希望する。この関数は、変化する(最小
限度の変化)ボディの変形母体だけを計算する。各ボデ
ィの3Dバージョンは要求に応じて(ユーザーが計算を要
求するときのみ)計算される。この関数は、各ベンドラ
インのメンバ変数'bending_status'を用いて、ベンドラ
インを屈曲するか否かを決める。ベース-ボディの2D->3
D変形が新しくない場合、FOLDはそれをアイデンティテ
ィ変形にリセットするので注意せよ。*/int fold(BM_3D
_BODY *base_body) ;/*この関数は、各ベンドラインの
メンバ変数'bending_status'がFALSEであると想定し(F
ALSEでない場合は、この関数が'bending_status'をFALS
Eに設定する)、さらに屈曲するベンドラインのリスト
が配列'bendline_array'にあると想定する(配列の長さ
は'number_of_bendlines')ことを除き、同じことを実
行する。この関数が終るときに、各ベンドラインのメン
バ変数'bending_status'は、ベンドラインが屈曲された
か否かを表示する。*/int fold(BM_3D_BODY *base_bod
y, BM_BENDLINE *bendline_array[], long number_of_b
endlines);/*この関数は、パートの屈曲順位における最
初のnベンドラインをフォルドする。*/int fold_sequen
ce(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 *curre
nt_bendline /* bendline whose transformation we ar
e computing */, BM_TRANSFORM *tf /* startwith this
transformation */) ;/*ベンドラインがすでに完成し
ており、我々が3Dボディを計算していることを除き、同
じ。This function is used by FOLD.*/int bend_3D_bo
dy_wrt_bendline(BM_BENDLINE *current_bendline /* f
inishedbendline */, BM_3D_BODY *body /* body whose
transformation we are computing */, BM_TRANSFORM
*tf /* start with this transformation */) ;/******
***** ********** ********** ********** **********
********** ********** ********** **********UNFOLD
関数。UNFOLD.CPPモジュール内********** **********
********** ********** ********** ********** ******
**** ********** ***********//*この関数はパート全体
をアンフォルドする。この関数は、接続されたパートの
各コンポーネントにつき、デフォルトのベース・ボディ
を選択する。この関数は、パートがアンフォルドされる
ときに、ベース・ボディが原点(0,0,0)に重なるように
パートをX-Y平面に移動させる。この関数は最初に各3D
ボディについて3D->2D変形を計算し、それから各3D-ボ
ディについてWflatを計算し、次にWflatをトリミング
し、最後に平面を計算する。この関数は、ベース-ボデ
ィとして非-NULLの法線を持ち、最小idを持つ面を選択
する。これが不可能である場合、この関数は、ベース-
ボディとして非-NULLの法線を計算することができる基
礎のサーフェスを有する最初のベンドラインを選択す
る。この関数は、BM_PART::unfold(BM_3D_BODY *base_b
ody)を用いて、パートの接続されたコンポーネントのす
べてをアンフォルドする。この関数は、全面的に成功し
た場合に1を返し、パートの一部でアンフォルドに失敗
した場合には0を返す。この関数はまず初めに、すべて
のフェース・ノーマルが現行のベンドラインに対して適
正であることをチェックする。この関数は、各3D-ボデ
ィの現行3D-バージョンを使用することに注意せよ。ア
ンフォルドを行なうには、すべての3D-バージョンが新
しくなっていなければならない。この関数は3Dボディが
新しいか否かをチェックせず、実際にはすべての3D-ボ
ディを最新と記す。さらにこの関数は、すべてのベンド
ラインが有効な3D-中心線を持っていると想定する。こ
こでもこの関数は3D-中心線をチェックせず、かわりに
現行の中心線をただ単に批准する。*/int unfold(voi
d);/*この関数は、ベース-ボディの周囲を中心とするパ
ートの接続コンポーネントだけをアンフォルドする。こ
の関数は、パート全体をアンフォルドするBM_PART::unf
old(void)関数によって使われる。この関数は、接続コ
ンポーネントの各3D-ボディについて新しい3D->2D変形
を計算し、次にBM_3D_BODY::compute_flat_from_3D()関
数を用いて各3D-ボディについて新しい平面バージョン
を計算する。ベース・ボディが面であり、入力フラグが
TRUEに設定されている場合、この関数が最初に実行する
ことは、すべてのフェース・ノーマルが現行のベンドラ
インに対して適正であることをチェックすることであ
る。ただしこれは、そのベース・ボディ(面)を中心と
する接続コンポーネントに限られる。この関数は各3D-
ボディの現行3D-バージョンを使用するので注意せよ。
この関数を呼び出す前に、すべての3D-バージョンが最
新であることを確認せよ。この関数は実際、それが処理
するすべての3D-ボディを最新と記す。*/int unfold(BM
_3D_BODY *base_body, int check_face_normals = 0) ;
/*3Dボディの3D->2D変形母体がすでに計算済みの場合、
この関数は所定のベンドラインについて変形母体を計算
する。この関数は数々の事柄を想定する(これらの事柄
はチェックされない):-このベンドラインはボディに隣
接している。-このボディはすでに最新の変形母体を有
する。-このベンドラインは最新のcenter_line_3Dを有
する。これら2つの関数では、ベンドラインが中心線を
有することが要求されるので注意せよ。これはまた、ベ
ンドラインが非-NULLの3D-バージョンであることをも意
味する。性能上の理由から、これらの関数はベンドライ
ンが非-NULLの3D-バージョンであることをチェックせ
ず、かわりにベンドラインが非-NULLの3D-バージョンで
あるものと想定し、それを直接的に参照する。この関数
はUNFOLDによって使われる。この関数は実際にはbend_b
endline_wrt_3D_body(...)の逆であることに注意せよ。
*/int unfold_bendline_wrt_3D_body(BM_3D_BODY *body
/* finished body */, BM_BENDLINE *current_bendlin
e /* bendline whose transformation we are computin
g */, BM_TRANSFORM *tf /* start with this transfor
mation */) ;/*ベンドラインがすでに完成しており、我
々が3Dボディを計算していることを除き、同じ。この関
数はUNFOLDによって使われる。この関数は実際にはbend
_3D_body_wrt_bendline(...)の逆であることに注意せ
よ。*/int unfold_3D_body_wrt_bendline(BM_BENDLINE
*current_bendline /* bendline終了*/, BM_3D_BODY *b
ody /* 我々が変形を計算しているところのボディ */,
BM_TRANSFORM *tf /* この変形から開始する*/) ;/****
******* ********** ********** ********** *********
* ******************** ********** **********この関
数は"paper model of this part"(このパートのペーパ
ー・モデル)を返す。ペーパー・モデルとは、厚みが0
であり、ベンドラインの半径と屈曲控除も0であるパー
トである。必要に応じこの関数は、ベンドラインのユー
ザ-id'から'内部半径'と'屈曲控除'をマッピングした結
果を返す。********** ********** ********** *******
*** ********** ********** ********** ********** **
*********/BM_PART *make_paper_model(double**inside
_radius /* OUT */, double **bend_deduction /* OUT
*/) ;/*この関数は、現行のパートを所定のファイルにP
GF形式で保存する。PGF形式はCMUのBendCADプログラム
によって使われる。戻り値:万事良好でパートが保存さ
れた場合にTRUEを返す。*/int save_PGF_file(FILE *fi
le) ;int save_PGF_file(char *filename) ;/*ロード関
数はPART_LOAD_x.CPPにある。*/virtual int load(FILE
*file) ;virtual int load(char *filename /* must n
ot be NULL */) ;int BM_PART_Load(FILE *file, long
version) ;/*保存関数はPART_SAVE.CPPにある。*/virtu
al int save(FILE *file) ;virtual int save(char *fi
lename /* must notbe NULL */) ;} ;#endif // BM_PAR
T_HXX_INCLUDED 付録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_
equivalent();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_t
o_list = 1;if(! mi_show_solid) { // Wireframe b
eing displayed, which means OpenGL picking.glGetIn
tegerv(GL_VIEWPORT, viewport);glMatrixMode(GL_PROJ
ECTION);glPushMatrix();glLoadIdentity();gluPickMat
rix((double)point.x, (double)(m_old_rect.bottom -
point.y), 3.0, 3.0, viewport);glOrtho(- md_current
_view_vol[0], md_current_view_vol[0],- md_current_
view_vol[1], md_current_view_vol[1],- md_current_v
iew_vol[2], md_current_view_vol[2]);glMatrixMode(G
L_MODELVIEW);DrawPart(m_hdc); // Draw the part i
n selection mode.glMatrixMode(GL_PROJECTION);glPop
Matrix();glMatrixMode(GL_MODELVIEW);process_hits_r
ecord(add_hit_to_list);ml_last_function_chosen = N
O_FUNCTION_MODE;DrawPart(m_hdc); reset_selection_b
uffer();}else { // Solid being shown, so RenderWar
e 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_MO
DE;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 further zoomed in. compute_no
n_dyn_equivalent();RwIdentityMatrix(md_dyn_rot_mat
rix);}// Now turn on dynamic rotation center if ne
ed be.if( (md_part_bbox_size[0] > 2.2*md_current_v
iew_vol[0]) || // User has zoomed in so that not
all (md_part_bbox_size[1] > 2.2*md_current_view
_vol[1]) ) { // ofthe part is in view volume.mi_bb
ox_is_up_to_date = 0;// Even though bboxcomputed,
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
ump to rotate around.if(RwPickScene(m_scene, m_old
_rect.right/2, m_old_rect.bottom/2, m_camera, &m_p
ick)) {if(m_pick.type == rwNAPICKOBJECT) {// No cl
ump was picked. m_dynamic_rot_center = BM_POI
NT(0.0, 0.0, 0.0);}else if(m_pick.type == rwPICKCL
UMP) { //Some clump was picked; pr
ocess it.vert = m_pick.object.clump.wcpoint;m_dyna
mic_rot_center = 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 {if
(mi_dynamic_rot_center_on) {compute_non_dyn_equiva
lent();if(md_dyn_rot_matrix) RwDestroyMatrix(md_dy
n_rot_matrix);md_dyn_rot_matrix= NULL;mi_dynamic_r
ot_center_on = 0;}}break; default: break;};ml_las
t_function_chosen = NO_FUNCTION_MODE;CBendCADVie
w::OnLButtonUp(nFlags, point);}
【図面の簡単な説明】
【図1】この発明の実施例に基づいて構成された、進歩
的板金製造設備のブロックダイヤグラム図である。
【図2】この発明の他の実施例に基づいて構成された進
歩的板金製造設備のブロックダイヤグラム図である。
【図3】この発明の1つの側面による、サーバモジュー
ル、データベース及びステーションモジュールの間のそ
れぞれのデータの流れを図示する。
【図4】この発明の他の側面による、サーバモジュール
により実行される一般的な工程及び操作のフローチャー
トである。
【図5】この発明の教示による、前記ステーションモジ
ュールの各々により実行される基本的工程及び操作の代
表的フローチャートである。
【図6】この発明の一側面による類似パーツ検索アルゴ
リズム或いは工程の論理フローを説明するフローチャー
トである。
【図7】この発明の一側面による類似パーツ検索アルゴ
リズム或いは工程の論理フローを説明するフローチャー
トである。
【図8】図8(a)、(b)、(c)はこの発明の側面
による、接触した角部を有する4曲げ箱及び開放された
角部を有する4曲げ箱についての特徴抽出操作を説明す
る。
【図9】図9(a)、(b)、(c)及び(d)はこの
発明の側面による、接触した角部を有する4曲げ箱及び
開放された角部を有する4曲げ箱についての特徴抽出操
作を説明する。
【図10】図10(a),(b)及び(c)は、この発
明の他の側面による、4曲げ箱、ブリッジ及び他の4曲
げ箱を有するパーツについての検索キーを特定するため
の特徴関連操作及び工程を説明する。
【図11】図11は、折り曲げアルゴリズムを用いて、
2次元単一図面図から3次元モデルを生成するためにな
される工程及び操作の論理フローを説明するフローチャ
ートである。
【図12】面検出工程のための図面を作成するために行
なわれる自動トリミング機能及びクリーンアップ機能の
例を説明する。
【図13】図13(a)、(b)、(c)は、面検出工
程のための図面を作成するために行なわれる自動トリミ
ング機能及びクリーンアップ機能の例を説明する。
【図14】面検出工程のための図面を作成するために行
なわれる自動トリミング機能及びクリーンアップ機能の
例を説明する。
【図15】図15(a)、(b)、(c)、(d)はこ
の発明の側面による、面検出工程においてなされる種々
の工程及び操作を説明する。
【図16】図16(a)、(b)、(c)、(d)はこ
の発明の側面による、面検出工程においてなされる種々
の工程及び操作を説明する。
【図17】この発明の側面による、面検出工程及び曲げ
線検出工程の実行から最終曲げグラフデータの生成を説
明する。
【図18】この発明の側面による、面検出工程及び曲げ
線検出工程の実行から最終曲げグラフデータの生成を説
明する。
【図19】この発明の教示による、展開アルゴリズム及
び他の工程を用いて最初の3次元図面(厚さを有しな
い)に基づいて2次元モデルを生成するための基本的論
理フローのフローチャートである。
【図20】この発明の側面による、2次元クリーンアッ
プ操作を用いて最初の2次元3面図に基づいて3次元モ
デルを生成するための基本的論理フローのフローチャー
トである。
【図21】この発明の側面による、2次元3面図に対し
て2次元クリーンアップ操作を行なうための工程及び操
作の基本的論理フローのフローチャートである。
【図22】図22(a)及び(b)は、この発明の2次
元クリーンアップ操作により加工される代表的2次元3
面図の図及び側面を説明する。
【図23】図23(a)はこの発明の2次元クリーンア
ップ操作の回転された図の特徴を説明する。図23
(b)はこの発明の側面による、この発明の2次元クリ
ーンアップ操作に関連する標準形態を説明する。
【図24】図24(a)及び(b)は、この発明の教示
による、厚さを有する2次元3面図及び厚さ除去工程を
用いて生成される厚さを有しない簡単化された2次元3
面図を説明する。図24(c)はこの発明の側面によ
る、代表的パーツの横断厚さ線分及び厚さ円弧の図であ
る。
【図25】本発明の側面による、厚さを有する3次元図
面から厚さを有しない3次元モデルを展開するために実
行される種々の工程及び操作の論理フローのフローチャ
ートである。
【図26】例えばオブジェクト指向プログラム技術を通
して本発明を実行する際に、使用される曲げモデルの代
表的データ構造及びアクセスアルゴリズムを説明する。
【図27】この発明の他の側面による、曲げモデルビュ
ーアの構造のブロックダイヤグラムを説明する。
【図28】表示スクリーンへ出力として提供される代表
的ソリッド図ウインドウ表示を説明する。
【図29】表示スクリーンへ出力として提供される代表
的ワイヤフレーム図ウインドウを説明する。
【図30】表示スクリーンへ出力として提供される2次
元平面スクリーン像ウインドウ表示を説明する。
【図31】表示スクリーンへ出力として提供される正射
影図スクリーン像を説明する。
【図32】この発明の自動寸法付けモードにおいて表示
される種々の寸法事項の例を説明する。
【図33】図33(a)、(b)及び(c)は、この発
明の1つの側面による、種々の異なるパーツについてフ
ランジ長さが定義される態様を図示する。
【図34】図34(a)及び(b)は、この発明の他の
側面による、2つの異なるタイプのパーツについて補助
的なフランジ長さを追加することを図示する。
【図35】図35(a)、(b)及び(c)は、この発
明の更に他の側面による、厚さを備えて表示される種々
のパーツについてフランジ長さが指示される態様を図示
する。
【図36】図36(a)及び(b)は、この発明の接線
寸法方法及び交差寸法方法による、鋭角曲げ角度を有す
るパーツのフランジ長さが表示される態様を示す。
【図37】この発明の他の側面による、図形的ユーザイ
ンタフェースの使用により曲げプランが生成されるため
に行なわれる工程及び操作の論理フローのフローチャー
トである。
【図38】曲げ順を生成するために曲げオペレータに対
して表示される曲げ順入力スクリーン像の例を図示す
る。
【図39】図39(a)及び(b)は、この発明の他の
側面による、曲げ順の選択及び挿入方向の修正の例を示
す。
【図40】曲げ順入力スクリーン画像及び関連するスク
リーン表示の更なる例を示す。
【図41】曲げ順入力スクリーン画像及び関連するスク
リーン表示の更なる例を示す。
【図42】この発明の1つの側面による、オペレータが
提案された曲げ順を修正し且つ編集するのを容易にする
ために設けられるドラッグ及びドロップ編集特性を示
す。
【図43】曲げオペレータが工具を選択するのを支援す
るために図形的に表示される種々の表示メニュー及びデ
ータテーブルの例を示す。
【図44】提案された曲げプランにおいて工具のセット
アップを容易にするために曲げオペレータに対して表示
される代表的工具セットアップウインドウを示す。
【図45】張り付けられたアイコンの使用を介して、添
付された音声及び映像情報を有する3次元ソリッド図ウ
インド表示の例を示す。
【図46】この発明の一側面による、格納された音声及
び映像情報を読み出すためのアイコンと共に組み込まれ
た表示ウインドウの他の例を示す。
【図47】この発明の教示に基づいて実行されるイメー
ジ編集ウインドウの例を示す。
【図48】図形的ユーザインタフェースを介して実行さ
れるこの発明の干渉チェック機能の例を示す。
【図49】図形的ユーザインタフェースを介して実行さ
れるこの発明の干渉チェック機能の例を示す。
【図50】図50(a)及び(b)は、例えばジョイス
ティックを用いて3次元幾何学形状の回転及び表示を操
作するための、この発明の操作システムを示す。
【図51】例えばジョイスティック及びズームボタンを
用いて3次元幾何学形状のズーミング及び表示を操作す
るためのこの発明の操作システムを示す。
【図52】例えばジョイスティック及びパンボタンを用
いて、3次元幾何学形状のパンニング及び表示を操作す
るための、この発明の操作システムを示す。
【図53】この発明の3次元ナビゲーション及び操作シ
ステムを実行するために、実行される工程及び操作の代
表的フローチャートである。
【図54】この発明の側面による、ジョイスティック運
動をカーソル運動へ写像する例を示す。
【図55】表示されたパーツの回転軸を動力学的に計算
するためになされる工程及び操作の代表的フローチャー
トである。
【図56】例えばステーションモジュールにおいて設け
られ且つ表示されるメインメニューウインドウ表示の例
を示す。
【図57】ユーザがパーツ情報を入力し且つ修正するこ
とを可能とするように設けられた代表的パーツ情報ウイ
ンドウ表示を示す。
【図58】ユーザが曲げ情報を入力し且つ修正すること
を可能とするように設けられた代表的曲げ線情報ウイン
ドウ表示を示す。
【図59】板金パーツの中間的曲げ段階を観察するため
の、この発明の代表的曲げ順ウインドウ表示を示す。
【図60】板金パーツの中間曲げ段階をシミュレートす
るための、この発明の代表的曲げシミュレーションウイ
ンドウ表示を示す。
【図61】2次元から3次元への変換のためユーザに対
して設けられ且つ表示される、この発明の代表的メニュ
ースクリーン図及び構造である。
【図62】この発明の2次元クリーンアップ操作のため
の代表的メニュースクリーン図及び構造である。
【図63】一端が開放された線分が除去される前のパー
ツの3次元表示の例を示す。
【図64】パーツの2次元3面図からパーツの3次元モ
デルを生成する際に使用されるこの発明の3次元クリー
ンアップ工程による、前記一方が開放された線分が3次
元表示から除去された後のパーツを示す。
【図65】曲げ線が特定される前のパーツの代表的3次
元表現を示す。
【図66】この発明の3次元クリーンアップ工程による
モールド線が追加された後のパーツを示す。
【図67】曲げ線をきれいにし且つ面をトリミングする
前のパーツの代表的部分を示す。
【図68】この発明の3次元クリーンアップ工程による
前記正常化及びトリミングが行なわれた後のパーツの部
分を示す。
───────────────────────────────────────────────────── フロントページの続き (31)優先権主張番号 08/688,860 (32)優先日 平成8年7月31日(1996.7.31) (33)優先権主張国 米国(US) 前置審査 (72)発明者 サトシ サカイ アメリカ合衆国 92657 カリフォルニ ア州 ニューポート コースト アヴィ グノン 9 (58)調査した分野(Int.Cl.7,DB名) G06F 17/50 610 G06T 17/40

Claims (10)

    (57)【特許請求の範囲】
  1. 【請求項1】 スクリーン上に表示される部品の表示
    画像を操作するためのシステムにして、前記部品の表示画像を変更するための所定の観察機能に
    関連する 指令信号を生成するための入力装置; 前記表示画像現在ビュー前記部品の向きおよびズー
    ム比率により決定するための現在ビュー決定システム
    と; 前記現在ビューに基づいて前記部品の回転軸を動的に設
    定するための設定システム; 前記指令信号および前記回転軸に基づいて、前記部品の
    前記表示画像を前記観察機能に応じて変更するための画
    像変更システム; を備え、前記観察機能は、回転機能、ズーミング機能、パンニン
    グ機能のうち少なくとも1つを含み、 前記現在ビュー決定システムは、前記現在ビューが前記
    部品の全体の姿であるか或いは部分的な姿であるかを決
    定するように構成され、 前記設定システムは、前記現在ビュー決定システムによ
    り前記現在ビューが全体の姿であると決定された時、前
    記回転軸が前記部品の幾何学的中心を通るように設定
    し、前記現在ビューが部分的な姿であると決定された
    時、前記回転軸が前記スクリーンの中心を通るように設
    定することを特徴とする部品表示画像操作システム。
  2. 【請求項2】 請求項1によるシステムにして、前記所
    定の観察機能は、回転機能を含み、前記画像変更システ
    ムは、前記指令信号に基づいて前記回転軸を中心として
    前記部品の表示画像を回転するようにされている。
  3. 【請求項3】 請求項によるシステムにして、前記現
    在ビューが部分的な姿であると決定された時において、
    それは更に、前記部品の一部が前記スクリーンの中心に
    表示されているか否かを前記現在ビューに基づいて決定
    する部品可視性システムを備え、前記部品可視性システ
    ムが前記部品の一部がスクリーンの中 心に表示されてい
    ことを決定する時、前記設定システムは、前記スクリ
    ーンの中心における前記部品の一部を前記回転軸が通る
    ように設定する。
  4. 【請求項4】 請求項によるシステムにして、前記部
    品可視性システムが前記部品の一部は前記スクリーンの
    中心に表示されていないと決定する時、前記設定システ
    ムは、前記部品の幾何学的中心と等しいZ座標における
    前記スクリーンの中心を前記回転軸が通るように設定す
    る。
  5. 【請求項5】 請求項1によるシステムにして、前記入
    力装置はジョイスティック装置を備え、前記指令信号
    は、前記ジョイスティック装置の所定の運動に基づいて
    生成される。
  6. 【請求項6】 スクリーン上に表示される部品の表示画
    像を操作するための方法にして、前記方法は、 入力装置から生成された指令信号を受信する工程にし
    て、ここに前記指令信号は、前記部品の表示画像を変更
    するための所定の観察機能に関連するもの; 前記スクリーン上において前記部品の表示画像の現在
    ューを決定する工程; 前記部品の前記現在ビューに基づいて前記部品の回転軸
    を動的に設定する工程; 前記指令信号および前記回転軸に基づいて、前記部品の
    表示画像を前記観察機能に応じて変更する工程; からなり、前記観察機能は、回転機能、ズーミング機能、パンニン
    グ機能のうち少なくとも1つを含み、 現在ビューを決定する工程は、前記現在ビューが前記部
    品の全体の姿であるか或いは部分的な姿であるかを決定
    する操作を含み、 回転軸を設定する工程は、前記現在ビュー決定システム
    により前記現在ビューが全体の姿であると決定された
    時、前記回転軸が前記部品の幾何学的中心を通るように
    設定する操作と、前記現在ビューが部分的な姿であると
    決定された時、前記回転軸が前記スクリーンの中心を通
    るように設定する操作とを含むことを特徴とする部品表
    示画像操作方法
  7. 【請求項7】 請求項による方法にして、それは更
    に、ジョイスティック装置でもって指令信号を生成する
    操作を含み、前記指令信号は前記ジョイスティック装置
    の所定の運動に基づいて生成される。
  8. 【請求項8】 スクリーン上に表示される部品の表示画
    像を操作するためのプログラムを記憶した記憶媒体(メ
    モリ)にして、 前記プログラムはコンピュータを、 前記表示画像の現在ビューを決定するための現在ビュー
    決定システム;及び前記表示画像の前記現在ビューに基
    づいて前記部品の回転軸を動的に設定するための設定シ
    ステム;及び入力装置により生成された、前記部品の表
    示画像を変更するための所定の観察機能に関連する指令
    信号および前記回転軸に基づいて、前記部品の前記表示
    画像を前記観察機能に応じて変更するための画像変更シ
    ステム; として機能させ 前記観察機能は、回転機能、ズーミング機能、パンニン
    グ機能のうち少なくとも1つを含み、 前記現在ビュー決定システムは、前記現在ビューが前記
    部品の全体の姿であるか或いは部分的な姿であるかを決
    定するように構成され、 前記設定システムは、前記現在ビュー決定システムによ
    り前記現在ビューが全体の姿であると決定された時、前
    記回転軸が前記部品の幾何学的中心を通るように設定
    し、前記現在ビューが部分的な姿であると決定された
    時、前記回転軸が前記スクリーンの中心を通るように設
    定する ことを特徴とするプログラムを記憶した記憶媒体
    (メモリ)。
  9. 【請求項9】 スクリーン上に表示される部品の表示画
    像を操作するためのプログラムを記憶した記憶媒体(メ
    モリ)にして、 前記プログラムはコンピュータに、 入力装置から生成された指令信号を受信する工程にし
    て、ここに前記指令信号は、前記部品の表示画像を変更
    するための所定の観察機能に関連するもの;及び前記ス
    クリーン上において前記部品の表示画像の現在ビュー
    決定する工程;及び前記部品の前記現在ビューに基づい
    て前記部品の回転軸を動的に設定する工程;及び前記指
    令信号および前記回転軸に基づいて、前記部品の表示画
    像を前記観察機能に応じて変更する工程; を実行させ、前記観察機能は、回転機能、ズーミング機能、パンニン
    グ機能のうち少なくとも1つを含み、 現在ビューを決定する工程は、前記現在ビューが前記部
    品の全体の姿であるか或いは部分的な姿であるかを決定
    する操作を含み、 回転軸を設定する工程は、前記現在ビュー決定システム
    により前記現在ビューが全体の姿であると決定された
    時、前記回転軸が前記部品の幾何学的中心を通るように
    設定する操作と、前記現在ビューが部分的な姿であると
    決定された時、前記回転軸が前記スクリーンの中心を通
    るように設定する操作とを含む ことを特徴とするプログ
    ラムを記憶した記憶媒体(メモリ)。
  10. 【請求項10】 請求項による記憶媒体にして、前記
    操作は更に、ジョイスティック装置でもって指令信号を
    生成する操作を含み、前記指令信号は前記ジョイスティ
    ック装置の所定の運動に基づいて生成される。
JP21933297A 1996-07-31 1997-07-30 部品表示画像操作システムおよび方法 Expired - Fee Related JP3308869B2 (ja)

Applications Claiming Priority (8)

Application Number Priority Date Filing Date Title
US08/690,671 US5886897A (en) 1996-05-06 1996-07-31 Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US08/690,671 1996-07-31
US08/690,084 1996-07-31
US08/700,671 1996-07-31
US08/688,860 US5828575A (en) 1996-05-06 1996-07-31 Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US08/688,860 1996-07-31
US08/690,084 US5864482A (en) 1996-05-06 1996-07-31 Apparatus and method for managing distributing design and manufacturing information throughout a sheet metal production facility
US08/700,671 US5971589A (en) 1996-05-06 1996-07-31 Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility

Related Child Applications (1)

Application Number Title Priority Date Filing Date
JP2001020132A Division JP2001265834A (ja) 1996-07-31 2001-01-29 板金製造設備全体にわたって設計製造情報を管理し分配する装置及び方法

Publications (2)

Publication Number Publication Date
JPH10149206A JPH10149206A (ja) 1998-06-02
JP3308869B2 true JP3308869B2 (ja) 2002-07-29

Family

ID=27505415

Family Applications (2)

Application Number Title Priority Date Filing Date
JP21933297A Expired - Fee Related JP3308869B2 (ja) 1996-07-31 1997-07-30 部品表示画像操作システムおよび方法
JP2001020132A Pending JP2001265834A (ja) 1996-07-31 2001-01-29 板金製造設備全体にわたって設計製造情報を管理し分配する装置及び方法

Family Applications After (1)

Application Number Title Priority Date Filing Date
JP2001020132A Pending JP2001265834A (ja) 1996-07-31 2001-01-29 板金製造設備全体にわたって設計製造情報を管理し分配する装置及び方法

Country Status (1)

Country Link
JP (2) JP3308869B2 (ja)

Families Citing this family (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP3171830B2 (ja) 1998-08-26 2001-06-04 株式会社エヌ・シー・エヌ 建築構造部材の処理装置
JP4902567B2 (ja) * 2008-02-18 2012-03-21 オリンパス株式会社 作業手順書作成システム、及び、作業手順書作成プログラム
JP4787864B2 (ja) * 2008-07-24 2011-10-05 千代田工業株式会社 曲げ加工シミュレーション装置
JP2015035006A (ja) 2012-04-26 2015-02-19 インターナショナル・ビジネス・マシーンズ・コーポレーションInternational Business Machines Corporation 複数の要素の結合結果を識別する情報処理装置、プログラムおよび方法
JP6613581B2 (ja) * 2015-03-11 2019-12-04 村田機械株式会社 データ生成装置、加工装置、及びデータ生成プログラム
KR102261396B1 (ko) * 2020-11-18 2021-06-07 디케이소프트 주식회사 정확성을 높인 용접부 정보 자동생성방법

Also Published As

Publication number Publication date
JP2001265834A (ja) 2001-09-28
JPH10149206A (ja) 1998-06-02

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
US5864482A (en) Apparatus and method for managing 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
Brenner Towards fully automatic generation of city models
Guéziec et al. Cutting and stitching: Converting sets of polygons to manifold surfaces
WO1997042608A9 (en) Apparatus and method for generating a sheet-metal bend model
JP2000090145A (ja) 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法
JP3308869B2 (ja) 部品表示画像操作システムおよび方法
Cayiroglu A new method for machining feature extracting of objects using 2D technical drawings
Pueyo et al. Structuring urban data
EP1830323A2 (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
JP3766857B2 (ja) 3次元モデルの開発支援システム
Haaraniemi Geometrical and topological defects in infrastructure corridor design models and automatic model repair
CN117746373A (zh) 一种基于管状交并比损失函数的三维车道线检测方法
JPH07129791A (ja) 自動面作成方法および装置

Legal Events

Date Code Title Description
FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20090517

Year of fee payment: 7

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

Free format text: PAYMENT UNTIL: 20100517

Year of fee payment: 8

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

Free format text: PAYMENT UNTIL: 20100517

Year of fee payment: 8

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

Free format text: PAYMENT UNTIL: 20110517

Year of fee payment: 9

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

Free format text: PAYMENT UNTIL: 20120517

Year of fee payment: 10

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

Free format text: PAYMENT UNTIL: 20130517

Year of fee payment: 11

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

Free format text: PAYMENT UNTIL: 20140517

Year of fee payment: 12

S533 Written request for registration of change of name

Free format text: JAPANESE INTERMEDIATE CODE: R313533

R350 Written notification of registration of transfer

Free format text: JAPANESE INTERMEDIATE CODE: R350

LAPS Cancellation because of no payment of annual fees