JP2001265834A - 板金製造設備全体にわたって設計製造情報を管理し分配する装置及び方法 - Google Patents

板金製造設備全体にわたって設計製造情報を管理し分配する装置及び方法

Info

Publication number
JP2001265834A
JP2001265834A JP2001020132A JP2001020132A JP2001265834A JP 2001265834 A JP2001265834 A JP 2001265834A JP 2001020132 A JP2001020132 A JP 2001020132A JP 2001020132 A JP2001020132 A JP 2001020132A JP 2001265834 A JP2001265834 A JP 2001265834A
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.)
Pending
Application number
JP2001020132A
Other languages
English (en)
Inventor
Hazama Kensuke
ハザマ ケンスケ
Yearn-Tzuo Hwang
ハワン ヤーンーツォ
Satoshi Sakai
サカイ サトシ
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/700,671 external-priority patent/US5971589A/en
Priority claimed from US08/690,084 external-priority patent/US5864482A/en
Priority claimed from US08/690,671 external-priority patent/US5886897A/en
Priority claimed from US08/688,860 external-priority patent/US5828575A/en
Application filed by Amada Co Ltd filed Critical Amada Co Ltd
Publication of JP2001265834A publication Critical patent/JP2001265834A/ja
Pending 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)
  • Multi-Process Working Machines And Systems (AREA)
  • Control By Computers (AREA)
  • Management, Administration, Business Operations System, And Electronic Commerce (AREA)
  • Bending Of Plates, Rods, And Pipes (AREA)
  • Processing Or Creating Images (AREA)

Abstract

(57)【要約】 (修正有) 【課題】曲げ薄板金属部品のような部品の製作を促進す
るために、設計と製造情報を全工場に亘って管理し、分
配する装置と方法に関し、各顧客の注文の設計と製造情
報の双方を、論理的に記憶する装置と方法を備えること
によって、工場のどの場所でも容易にアクセスでき、検
索できるようにすること。 【解決手段】この発明にかかる装置は、部品を製作する
情報処理機能をもち、以前この装置で製作された部品に
関する仕事情報を記憶するデータベースが備えられてい
る。各以前に製作された部品の以前の仕事情報には、各
以前に製作された部品の特色に関連した以前の設計デー
タも含められる。さらに現在の仕事要請に応えて装置に
よって製作される現在の部品に関する現在の情報を受け
るシステムを備えることもできる。この現在の仕事情報
には現在の部品の提案された特色に関する提案された設
計データも含められる。

Description

【発明の詳細な説明】
【0001】関連出願データ 本出願は1996年5月6日出願の「薄板金属製作設備全体に
亘って設計製作情報を管理し分配する装置と方法」と題
したU.S.仮出願No. 60/016,948に準拠し、その明細書を
全般的に参照する事によって本明細書に明白にとりいれ
ていることを主張する。
【0002】著作権についての注意書き 本特許文書の明細書の一部は、著作権保護の対象になっ
ている。著作権保有者はU.S.特許・商標局の特許フアイ
ルや記録に記載されている特許明細書の何人かによる複
写には異議を申し立てないが、それ以外のものについて
は著作権保有者は著作権すべてを保留する。
【0003】発明の背景 発明の分野 本発明は一般的に、製造分野及び薄板金属部品のような
部品の製作に関するものである。特に、本発明は曲げ薄
板金属部品の製作を容易にするために設計・製作情報を
工場全体にわたって管理・分配する装置と方法に関する
ものである。
【0004】背景情報 伝統的に、たとえば薄板金属の進歩的な製造設備での曲
げ薄板金属の製作は、連続的な製作製造段階を含む。第
一段階は設計段階で、そこでは顧客の仕様にもとづいて
薄板金属部品の設計が行われる。通例顧客は特定の薄板
金属部品の設備での製作を注文する。顧客の注文は通
例、部品を工場で製造するのに必要な製品と設計の情報
を含んでいる。この情報は、たとえば部品の幾何学的寸
法、部品に必要な材料(たとえば鋼鉄、ステインレス
鋼、またはアルミニウム)、特殊な成形の情報、分量、
引き渡し年月日等を含むことがある。客先から要請され
た薄板金属部品は広範囲の種類の応用に設計・製作する
ことが出来る。たとえば、製作された部品は最終的には
コンピュータのケース、配電盤、航空機の肘掛け、また
は自動車のドアのパネルに使われるかもしれない。設計
段階では、薄板金属部品の設計は、適当なコンピュータ
支援設計(CAD)システムによって製造設備の設計部で
なされる。顧客の仕様に応じて、プログラマーがCADシ
ステムを用いて薄板金属部品の2次元(2ーD)モデルを作
成することもできる。通例、客先は部品の重要な幾何学
的寸法を含む青写真を提供する。この青写真は、部品に
含まれる特別の成形や記号、または薄板金属部品の表面
の孔や他の開口を示すこともある。設計プログラマーは
CADシステムで2ーDモデルを作成するため、この青写真を
度々用いる。この2ーDモデルはまた、薄板金属部品の曲
げ線及び/または寸法情報を含む平面図と、一つまたは
一つ以上の透視図を含むこともある。
【0005】実際に薄板金属部品の曲げ加工を開始する
前に、先ず原材料から部品を打ち抜き切断するか/また
は切断しなければならない。在庫材料の処理に当たっ
て、打ち抜きプレスやプラズマまたはレーザー切断機を
制御作動するのに、普通コンピュータ数値制御(CNC)
または数値制御(NC)が用いられる。この在庫材料の処
理を容易にするため、設計プログラマーは、コンピュー
タ支援製造(CAM)システムまたはCAD/CAM システムを
用いて2ーDモデルにもとづいた制御コードを作成するこ
とが出来る。この制御コードには、打ち抜きプレス及び
/または切断機にとりいれて、在庫材料からの薄板金属
部品の打ち抜き、または切断に利用できる部品プログラ
ムが含められていることもある。
【0006】製造プロセスの次の段階は曲げ加工計画段
階である.この段階で、曲げ加工計画が作業場で曲げ加
工オペレータによって立てられる。オペレータには通常
切断または打ち抜かれた一つまたは一つ以上の在庫材料
とともに、部品の青写真または2ーD図面が渡される。こ
れらの材料で曲げ加工オペレータは使用する工具と実施
される曲げの手順を定める曲げ加工計画を立てる。曲げ
作業場には、オペレータがデータを入力した曲げコー
ド、または曲げ計画にもとづいたプログラムが作成でき
るCNCプレスブレーキのようなCNC金属曲げ機も含まれ
る。
【0007】曲げ加工計画が作成されると、オペレータ
は曲げ加工の順序の初期テストのための作業場を設置す
る。このテスト段階では、打ち抜きまたは切断された材
料はプレスブレーキに手で組み込まれ、プレスブレーキ
はプログラムされた順序に従って製作品に曲げを加工す
るように操作される。オペレータは出来上がった曲げ薄
板金属部品を分析して顧客の仕様に適合しているかどう
かを検査する。このプレスブレーキの初期作業の結果に
よって、オペレータは曲げプログラムを編集し、曲げ順
序を修正することもある。オペレータはまた、薄板金属
部品の設計が適当に修正出来るように、設計部に結果を
フイードバックすることもある。テストは通常曲げ薄板
金属部品が要求されている設計仕様内におさまるまで続
けて行われる。
【0008】製作プロセスの最後の段階の一つは曲げ段
階である。曲げ計画が作成され、テストされた後、曲げ
オペレータは曲げ加工場に必要な工具を装備し、曲げ計
画と記憶されている曲げプログラムまたはコードに従っ
てプレスブレーキを作動する。曲げ加工場に必要な量の
打ち抜きまたは切断された材料が確保されるように、ま
た他の作業が指定された引き渡し年月日までに完了して
いるように、作業日程も作成される。作業日程は製作過
程の初期段階と/または全過程に平行して作業場監督に
よって作成または修正されることもある。最後の曲げ薄
板金属部品の製作が完了すると、顧客への引き渡しのた
めに部品は集められ、梱包される。
【0009】通常の製作、製造過程は幾つかの欠点や不
利な点がある。たとえば、各々顧客の設計製造データは
通常物理的に(たとえば紙によってフアイルキャビネッ
トに)、電子的に(たとえばデイスクまたは磁気テープ
に)保管されるが、こうしたデータは普通別々に保管さ
れていて検索するのが容易でない。さらに、多くの工場
環境では、重要な仕事情報の分配は工場全体にわたって
配布される仕事または企画用紙の形をとる。その結果、
データがしばしば紛失または損傷し、以前または類似の
仕事に関する設計製造データを検索するのが困難にな
る。加うるに、データの保管方法の不備によって、設計
製造情報を全工場の作業場やその他の場所に配布するの
に貴重な時間が失われる。また部品の設計や曲げ計画の
作成は、主として設計プログラマーと曲げオペレータに
よって行われ、個人の知識、手腕と経験によるところが
大きいので、薄板金属部品と曲げ計画の作成の間に製造
時間がかなり失われる。
【0010】近年、慣習的な薄板金属製造過程を改善
し、過程全体にわたる効率を改善するための開発と試み
がなされてきた。たとえば、市販のCAD/CAMシステムに
おける2次元(2-D)および3次元(3-D)モデル作成の使
用と開発によって曲げ薄板金属の製作過程とモデル作成
を促進され、改善された。今では設計プログラマーやオ
ペレーターは2ーD及び3ーD表示を用いて、部品の形状をよ
りよく理解し、部品設計と曲げコードの順序をより効率
的’に作成出来るようになっている。データを電子的に
記憶し、トランスフアーする機能は、設計部から作業場
への情報の流れを改善した。コンピュータとデータ通信
ネットワークの進歩により、最早古い紙テープや磁気デ
イスクをキャビネットまたはフアイルから探し出すこと
が不要になった。
【0011】こうした進歩があるにもかかわらず、組織
と工場環境全体にわたる設計と製造情報の組織化と流れ
を改善する必要がまだある。たとえば、在来の製造シス
テムでは、各顧客の注文の重要な設計及び製造情報が、
工場のどの場所でも容易にアクセスでき、検索できるよ
うな論理的関係づけがなされていない。今までのシステ
ムはまた、薄板金属部品の特徴や特質のような、色々な
特色にもとづいた仕事情報を探索する機能をもたない。
たとえば同一または類似の部品の探索にもとづいた、以
前の仕事情報が探索でき、検索出来ることは、全体的な
製作プロセスを大幅に増強し、将来の仕事の必要製造時
間を短縮する。
【0012】過去の試みはまた、設計プログラマーや作
業場オペレータによる薄板金属部品の設計を容易にする
ことに欠けている。2ーDや3ーDモデリング・システムによ
って、設計者は部品の形状や幾何学をよりよく理解出来
るようになったが、このシステムによって設計プログラ
マーや作業場オペレータに科せられた負担は軽減されて
いない。たとえば、これらのシステムによって設計プロ
グラマーが現存の2ーDCADモデルを簡単に3ーD表示に変換
することはできない。また作業場オペレータに曲げ加工
計画を立てる助けとなる部品の2ーD及び/また3-D図面が
提供されても、オペレータは必要な工具や曲げ手順を手
で/または試行によって決めなければならない。
【0013】発明の要約 上記に照らして、本発明は、発明の一つまたは一つ以上
の見地、実施例及び/または特色あるいはサブコンポー
ネントを通して、以下に特記する一つまたは一つ以上の
目的と利点をもたらすために供するものである。
【0014】本発明の一般的な目的は、曲げ薄板金属部
品のような部品の製作を促進するために、設計と製造情
報を全工場に亘って管理し、分配する装置と方法の提供
である。
【0015】さらに本発明の目的としては、たとえば進
歩的な薄板金属製作設備における重要な仕事情報の紛失
または破壊を防止し、専門的知識の蓄積の有効活用と整
理を助長する装置と方法の提供がある。
【0016】もう一つの本発明の目的は、各顧客の注文
の設計と製造情報の双方を、論理的に記憶する装置と方
法を備えることによって、工場のどの場所でも容易にア
クセスでき、検索できるようにすることにある。
【0017】さらにもう一つの本発明の目的は、仕事デ
ータが中央のデータベースまたはフアイルサーバーに、
全工場のどの場所でも容易に探索し、検索できるよう論
理的に記憶されている設計と製造情報を管理し、分配す
る装置と方法の提供にある。仕事データは仕事に関連し
た設計と製造情報ばかりでなく、必要な曲げ操作を遂行
するための実際の曲げコードも提供できる。
【0018】またさらに本発明の目的は、色々な探索基
準にもとづいた、設計と製造情報を含む以前の仕事情報
を探索する装置と方法の提供である。探索基準は、たと
えばこれから製造される薄板金属部品の特色や特徴を含
むことができ、これによって同一または類似の部品に関
連した以前の仕事情報を、将来の仕事の全体的な製造時
間の短縮に利用できる。
【0019】本発明のもう一つの目的は、各顧客の注文
に関連した従来の書類仕事または企画用紙を、工場の何
処からでも瞬間的にアクセスできる電子的ジョッブシー
トに置き換えることである。電子的なジョッブシートは
どの場所でも表示でき、部品の2ーD及び/または3-Dモデ
ル像、工具の選択、最適曲げ手順、必要なステイジング
情報やバーコードまたは認識番号を含む、仕事に関連し
た重要な設計と製造情報を含む。この電子的ジョッブシ
ートには、曲げオペレータによって将来再び同じ、また
は類似の仕事を行うときに役立つと思われる、特別の指
図または手順を録音録画したオーデイオ及び/またはビ
デオ部も備えられる。
【0020】本発明のもう一つの目的は薄板金属部品の
2ーDと3-Dコンピュータ画像を提供することによって部品
図面の解析に要する時間を短縮する事にある。ソリッド
3ーD画像モード、3ーDワイヤフレーム画像モード、2-D平
面画像モード及び正射画像モードを含む、色々な画像が
提供できる。薄板金属部品の解析に役立つズーミング、
パンニング、回転及び自動寸法入れを含む色々な異なる
画像機能も備えられる。
【0021】さらに本発明は設計者の薄板金属部品の設
計と曲げ計画の製作を容易にする装置と方法を提供する
目的を持つ。たとえば、現存する部品の2ーDモデルから
部品の3ーD表示を容易に製作することができるようにす
るのも本発明の目的である。さらにもう一つの本発明の
目的として、曲げ計画とプログラムされた曲げコードを
作成する時間を短縮するためのグラフィックスインター
フエイスの提供がある。
【0022】本発明は従って、部品を製作する情報処理
機能をもつ設備と、かかる設備において部品を製作する
方法に向けられたものである。以前この設備で製作され
た部品に関する仕事情報を記憶するデータベースが備え
られている。各以前に製作された部品の以前の仕事情報
には、各以前に製作された部品の特色に関連した以前の
設計データも含められる。さらに現在の仕事要請に応え
て設備によって製作される現在の部品に関する現在の情
報を受けるシステムを備えることもできる。この現在の
仕事情報には現在の部品の提案された特色に関する提案
された設計データも含められる。
【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】更に前記初期パーツ情報は、前記パーツエ
ンティティーデータとテキストに関連する余分の情報と
を特定するためのキーワードを含み、前記操作の工程
は、前記キーワードに基づいてテキストに関連する余分
の情報を削除する工程を含む。この発明の他の特徴によ
れば、前記パーツ厚さを選択的に消去する工程は、前記
複数の図面の各々において消去されるべきパーツ厚さ表
現を特定し且つ前記複数の図面の各々において残される
べきパーツの寸法を特定するようにユーザに促す操作を
含む。前記パーツの寸法は、前記パーツの外側寸法又は
内側寸法の1つを含む。更に前記生成の工程は、前記2
次元空間におけるパーツの修正された表現に基づいて3
次元空間におけるパーツの表現を生成するための射影操
作を行なうことを含む。前記射影操作は、前記複数の図
面の各々の相対的な深さを検出し且つ前記複数の図面の
各々を3次元空間へ射影することを含む。
【0070】又、この発明は設備において製造されるべ
きパーツ(例えば板金パーツ)を表現するためにコンピ
ュータ可読媒体に格納されたオブジェクト指向ベンドモ
デルに向けられる。このオブジェクト指向ベンドモデル
は、前記パーツの特徴に関連するパーツ情報及びこのパ
ーツになされる曲げ操作に関連する曲げ情報を有する複
数のオブジェクトを含むパーツクラスを備える。前記パ
ーツ情報は、パーツの設計及び製造情報を含む。前記パ
ーツ設計情報は2次元及び3次元座標空間における前記
パーツの表現に関連する。更に、前記曲げ情報は、前記
パーツの曲げ線において曲げ操作を行なうための曲げデ
ータ及び命令を備えた一群のオブジェクトを有する。曲
げデータは、曲げ角度量及び曲げ半径量を含む。
【0071】この発明の1つの側面によれば、前記パー
ツクラスは前記曲げ操作が前記パーツになされるところ
の順番に関連する曲げシーケンス情報を備える属性を含
む。前記属性はパーツ材質タイプ及びパーツ厚さを備え
る。更に上記複数のオブジェクトは、面オブジェクトを
備え、この面オブジェクトは、前記パーツの各面の寸法
に関連する設計データ及び少なくとも1つの座標空間内
における前記パーツの各面の表現に関連する位置データ
を含む。前記複数のオブジェクトは更に、曲げ線オブジ
ェクトを含む。前記曲げ線オブジェクトは前記パーツの
各曲げ線の寸法に関連する設計データ及び少なくとも1
つの所定の座標空間内での前記パーツの各曲げ線の表現
に関連する位置データを含む。前記曲げ線オブジェクト
は更に、前記パーツになされる曲げ操作に関連する曲げ
製造データを含む。前記曲げ製造データは、前記パーツ
の各曲げ線についてのV幅データ及び曲げピッチ及び配
向データを含む。
【0072】前記曲げモデルの複数のオブジェクトはま
た穴オブジェクト及び成形オブジェクトを含む。この穴
オブジェクトは、前記パーツにおける少なくとも1つの
穴の寸法に関連する設計データ及び少なくとも1つの所
定の座標空間内での前記パーツの各穴の表現に関連する
位置データとを含む。前記成形オブジェクトは、前記パ
ーツの各々の成形部の寸法に関連する設計データ及び少
なくとも1つの座標空間内における前記パーツの各成形
部の表現に関連する位置データとを含む。トポロジーオ
ブジェクトと曲げ特性オブジェクトが更に設けてある。
前記トポロジーオブジェクトは、前記パーツの特徴に関
連するパーツトポロジーデータを含み、前記パーツの特
徴は、前記パーツの面または穴または成形部または曲げ
線の少なくとも1つを含む。更に前記曲げ特性オブジェ
クトは、前記パーツに関連する製造拘束データを含む。
この発明はまた製造設備において製造されるべき板金パ
ーツを表現するための、コンピュータ可読媒体に格納さ
れたオブジェクト指向曲げモデルに向けられる。前記オ
ブジェクト指向モデルは、複数のパーツ特性を有するパ
ーツオブジェクトと2次元座標空間及び3次元座標空間
において板金パーツを表現するための複数のオブジェク
トを含むパーツクラスを備える。前記複数のオブジェク
トは、前記板金パーツの特徴に関連する設計情報及び前
記板金パーツに少なくとも1つの曲げ操作を行なうため
の曲げ情報を含む。前記パーツの特徴は、面及び穴及び
成形部及びまたは曲げ線を含み、前記複数のオブジェク
トは、面オブジェクト及び穴オブジェクト及び成形オブ
ジェクト及びまたは曲げ線オブジェクトを備える。
【0073】前記曲げ情報は、前記板金パーツになされ
る複数の曲げ操作に関連する。前記曲げ情報は、前記板
金パーツに少なくとも1つの曲げ操作を行なうための曲
げデータ及び命令を備えた一群のオブジェクトを備え
る。前記曲げデータは、例えば、曲げ角度量及び曲げ半
径量を含む。更に前記曲げ属性は、前記曲げ操作が前記
板金パーツに対してなされる順番に関連する曲げシーケ
ンス情報を備える。前記パーツ属性はまた、パーツ材料
タイプ及びパーツ厚さを備える。
【0074】この発明の他の側面によれば、コンピュー
タ制御システムにおいて用いられるように構成されたオ
ブジェクト指向曲げモデルビューアが提供される。前記
コンピュータ制御システムは、前記パーツに関連する曲
げモデルデータを格納するデータベースと前記パーツの
画像を表示するための表示装置とを含む。前記オブジェ
クト指向曲げモデルビューアは、曲げモデルビューア観
察クラスを備え、この曲げモデルビューア観察クラス
は、観察モデル属性(ビューモデル属性)と前記ベンド
モデルビューア観察クラスの要素機能として実行される
少なくとも1つの観察機能とを含む。前記パーツの少な
くとも1つの画像が、前記曲げモデルデータ及び観察モ
デル属性とに基づいて、前記コンピュータ制御システム
の表示装置上に表示される。
【0075】種々の追加的特徴が、この発明のオブジェ
クト指向曲げモデルビューアに設けてある。例えば、前
記観察モデル属性は所定の観察モード或いは複数のモー
ドに関連する表示情報を備え、前記所定の観察モード或
いは複数の観察モードはソリッド観察モードまたはワイ
ヤフレーム観察モード、2次元平面図モード、及びまた
は斜視図モードを含む。前記曲げモデルビューア観察ク
ラスはまた、1つまたはそれ以上の観察機能に応じて前
記パーツの画像を修正するための情報を含む。前記観察
機能は、例えば、ズーミング機能または回転機能または
パンニング機能及びまたは寸法付け機能を含む。前記ズ
ーミング機能は、表示装置上で前記パーツの画像をズー
ムするための操作を含み、前記回転機能は前記パーツの
画像を回転するための操作を含む。前記パンニング機能
は、前記表示装置上で前記パーツの画像をパンニングす
る操作を含み、前記寸法機能は、前記パーツの少なくと
も1つの特徴に関連する寸法情報を追加的に表示するた
めに前記パーツの画像を修正する操作を含む。前記寸法
情報は、前記パーツの少なくとも1つの曲げ線の長さま
たは前記パーツの各曲げ線の曲げ角度及びまたは前記パ
ーツの少なくとも1つのフランジ部の長さを含む。
【0076】前記オブジェクト指向曲げモデルビューア
は、前記パーツの画像の現在表示されている姿(ビュ
ー)に基づいて前記表示装置上において観察可能な前記
パーツの特徴に関連する観察可能性情報を維持し提供す
るための観察可能性機能を有する。前記曲げモデルビュ
ーア観察クラスは、少なくとも1つの観察機能に応じて
パーツの画像を修正するための情報を含む。前記観察機
能は、観察可能性情報に基づいて前記パーツの画像を修
正しパーツの観察可能な特徴に関連する寸法情報を表現
するための操作を含む寸法機能を備える。更にオブジェ
クト指向曲げモデルビューアは、前記表示装置上のパー
ツの画像の現在表示されている姿のズーム係数に関連す
るズーム係数情報を含む。
【0077】本発明の更に他の側面によれば、パーツの
表示されている画像を操作するためのシステムが提供さ
れる。前記パーツの表示されているイメージは3次元座
標空間においてスクリーン上に表示される。このシステ
ムは以下を含む:指令信号を生成するための入力装置
(例えばジョイスティック装置或いはマウス装置)、こ
こに前記指令信号は前記パーツの表示されている画像を
修正するように構成された少なくとも1つの所定の観察
機能に関連する;表示されている画像の現在の姿を決定
するための現在姿決定システム;表示されているイメー
ジの現在の姿に基づいて前記パーツの回転軸を動力学的
に設定するための設定システム。前記観察機能に応じ
て、前記指令信号及び回転軸に基づいて前記パーツの表
示されている画像を修正するための画像修正システム。
【0078】所定の観察機能は、回転機能を備え、前記
画像修正システムは前記指令信号に基づいて前記回転軸
を中心としてパーツの表示されている画像を回転するよ
うに構成されている。更に現在姿決定システムは、パー
ツの表示されている画像の現在の姿がパーツの全体の姿
であるか或いはパーツの部分的姿であるかを決定するよ
うに構成されている。前記設定システムは、前記現在姿
決定システムが前記パーツの表示されているイメージの
現在の姿は全体の姿であると決定する時、前記パーツの
幾何学的中心を前記パーツの回転軸が通るように設定す
るように構成されている。更に前記設定システムは、前
記現在姿決定システムがパーツの表示されている現在の
姿が部分的姿であると決定する時、前記パーツの回転軸
が前記スクリーンのセンターを通るように設定するよう
に構成されている。
【0079】前記システムには他の特徴が設けてある。
例えばパーツ観察可能システムが設けてあり、それは現
在の姿に基づいてパーツの一部がスクリーンの中心に観
察可能であるか否かを決定する。その場合には、前記パ
ーツ観察可能性システムが前記パーツの前記一部が観察
可能であると決定する時前記回転軸が前記スクリーンの
中心における前記パーツの前記一部を通るように設定す
るように構成されている。更に前記設定システムは、前
記パーツ観察可能性システムが前記パーツの前記部分が
スクリーンの中心において観察可能ではないと決定する
時、前記パーツの幾何学的中心のZ座標において前記ス
クリーンの中心を前記回転軸が通るように設定するよう
に構成されている。
【0080】前記現在姿決定システムがパーツの表示さ
れている画像の現在の姿は部分的姿であると決定する
時、前記スクリーンの中心に位置し且つ前記スクリーン
のカメラ視野に最も近い前記パーツの部分を特定するた
めのシステムが設けてある。前記パーツの特定された部
分が前記パーツの開口部に対応するかどうかを決定する
ためのオブジェクト検出システムがまた設けてある。こ
のオブジェクト検出システムが、パーツの特定された部
分はパーツの開口部に関係しないと決定する時、前記計
算システムは、前記回転軸が前記パーツの前記特定され
た部分を通るように設定するように構成されている。更
に前記オブジェクト検出システムが前記パーツの特定さ
れた部分が当該パーツの開口部に関連すると決定する
時、前記回転軸が、前記パーツの幾何学的中心のZ座標
に対応する深さにおいて前記スクリーンの中心を通るよ
うに設定されるように前記設定システムは構成されてい
る。
【0081】前記入力装置はジョイスティック装置及び
またはマウス装置を備えている。前記ジョイスティック
装置は、ジョイスティック仮想空間を含み、当該装置か
らの指令信号は前記ジョイスティック仮想空間内での前
記ジョイスティック装置の移動に関連する情報を含む。
前記画像修正システムは、前記ジョイスティック仮想空
間内でのジョイスティック装置の移動をスクリーンのス
クリーン空間内での仮想の移動に写像するための写像シ
ステムを有する。従って、前記画像修正システムはジョ
イスティック移動から写像されたカーソルの移動に基づ
いて前記パーツの表示された画像を修正する。前記写像
システムは、前記ジョイスティック仮想空間の寸法に対
する前記スクリーン空間の寸法の比率に基づいて、前記
ジョイスティック装置の移動を前記スクリーン空間内で
のカーソルの移動へ写像するように構成されている。例
えば前記カーソルの移動は以下の式に基づいて前記写像
システムにより写像される。
【0082】 現在位置=従前位置+(スケール係数×V) ここに現在位置はスクリーン空間内でのカーソルの現在
の位置であり、従前位置は前記スクリーン空間内でのカ
ーソルの従前の位置であり、スケール係数はジョイステ
ィック仮想空間の寸法に対するスクリーン空間の寸法の
比率であり、Vは前記ジョイスティック仮想空間内での
ジョイスティック原点からジョイスティック現在位置へ
のジョイスティック装置の移動及び方向に関連するベク
トルである。
【0083】この発明の他の特徴によれば、前記写像シ
ステムは、前記写像システムにより必要されるスケール
係数を調整するためのスケール調整システムを備える。
このスケール調整システムは、前記スクリーン空間の寸
法の前記ジョイスティック仮想空間の寸法に対する比率
に所定の調整係数を掛け合わせ調整されたスケール係数
を提供するように構成されている。前記写像システムは
前記ジョイスティック運動を写像する際にこの調整され
たスケール係数を用いるように構成されている。非限定
的な事例として、3という調整係数が使用される。
【0084】この発明はまたパーツの表示された画像を
操作する方法を含む。ここに前記パーツの前記表示され
た画像は3次元座標空間においてスクリーン上に表示さ
れる。前記方法は以下の工程を含む:入力装置から生成
された指令信号を受け取る工程、ここに前記指令信号は
前記パーツの表示された画像を修正するように構成され
た少なくとも1つの所定の観察機能に関連する;スクリ
ーン上においてパーツの表示された画像の現在の姿を決
定する工程;前記パーツの現在の姿に基づいて前記パー
ツの回転軸を動力学的に設定する工程;前記観察機能に
応じて、前記指令信号及び回転軸に基づいて前記パーツ
の表示された画像を修正する工程。
【0085】この発明の上記した方法によれば、前記所
定の観察機能は、回転機能を備え、これにより前記パー
ツの表示された画像は指令信号に基づいて前記回転軸を
中心として回転される。更に前記設定の工程は、前記パ
ーツの表示された画像の現在の姿が全体の姿であると決
定される時、前記パーツの幾何学的中心を前記パーツの
回転軸が通るように設定する操作を含む。前記設定の工
程はまた、前記パーツの表示された画像の現在の姿が部
分的な姿であると決定される時、前記パーツの回転軸が
前記スクリーンの中心を通るように設定する操作を含
む。
【0086】この発明の他の側面によれば、パーツの画
像と共に寸法情報をスクリーン上に表示するシステム及
び方法が提供される。前記方法は以下の工程を含む:前
記パーツの表示された画像の現在の姿を決定し且つ前記
現在の姿に基づいてスクリーン上で複数の特徴のうちの
いずれが観察可能であるかを決定する工程;前記パーツ
の表示された画像と共にスクリーン上に、スクリーン上
で観察可能であると決定されたパーツの特徴の各々につ
いてのみの寸法情報を選択的に表示する工程。前記方法
は更に、前記パーツに関連する曲げモデルデータにアク
セスし、この曲げモデルデータに基づいて前記パーツの
特徴の各々についての寸法情報を表示するためのスクリ
ーン上の全ての可能な位置を決定する。更に、前記選択
的に表示する工程は所定のヒューリスティックを適用
し、前記可能な位置に基づいて前記観察可能な特徴の寸
法情報を表示する場所を決定する。前記ヒューリスティ
ックは、前記パーツの表示された画像の外側に存在する
スクリーン上の位置に前記寸法情報を表示する動作と観
察者の観察点に近い方のスクリーン上の位置に前記寸法
情報を表示する動作と及びまたはスクリーン上で寸法情
報が重なり合わないように前記寸法情報を表示する動作
を備える。
【0087】表示される前記寸法情報は、前記パーツの
各曲げ線についての曲げ長さ及び曲げ角度を備える。前
記寸法情報はまた、前記パーツの各曲げ線に関連する内
側曲げ半径及び曲げ縮小量を含む。ここに前記表示の工
程は、前記現在姿に基づいて観察可能であると決定され
る前記パーツの各曲げ線についての曲げ線長さ、曲げ角
度、曲げ半径及びまたは曲げ縮小量を表示する。前記パ
ーツの各フランジ部のフランジ長さのような他の寸法情
報も表示される。追加の情報、例えばパーツの幅及び深
さ及び高さも表示される。
【0088】選択的に表示する工程は、パーツの所定の
特徴のみの寸法情報を表示するための自動寸法付け操作
を行なうことを含む。従って観察可能であると決定され
る所定の特徴のみについて寸法情報が表示される。更に
前記選択的表示の工程は、パーツの特徴に関連するユー
ザにより選択された寸法情報を表示するためのマニュア
ル寸法付け操作を実行することを含む。従ってユーザに
選択された寸法情報の各々は観察可能であると決定され
るパーツの特徴についてのみ表示される。スクリーン上
に表示されたパーツの画像と共に寸法情報を表示するシ
ステムも提供される。このシステムはパーツの表示され
た画像の現在の姿を決定し且つ現在の姿に基づいて複数
の特徴のうちのいずれがスクリーン上で観察可能である
かを決定するためのシステムと、前記パーツの表示され
たイメージと共にスクリーン上に、スクリーン上で観察
可能であると決定されたパーツの特徴のみについて寸法
情報を選択的に表示するシステムとを含む。
【0089】パーツに関連する曲げモデルデータにアク
セスするためのアクセスシステムのみならずこの曲げモ
デルデータに基づいてパーツの複数の特徴の各々につい
ての寸法情報を表示するためのスクリーン上の全ての可
能な位置を決定するためのシステムが設けてある。前記
選択的表示システムは、所定のヒューリスティックを適
用し前記可能な位置に基づいて観察可能な特徴の寸法情
報を表示すべき場所を決定するためのシステムを含む。
表示される前記寸法情報は、前記現在姿に基づいて観察
可能であると判断される前記パーツの各曲げ線について
の曲げ線長さ、曲げ角度、曲げ半径及びまたは曲げ縮小
量を含む。他の寸法情報、例えばパーツの各フランジ部
のフランジ長さはまた表示される。追加の情報、例えば
パーツの幅及び深さ及び高さもこの発明によれば表示さ
れる。
【0090】又この発明は、図形的ユーザインタフェー
スを使用して曲げプラン(曲げ計画)を生成するために
設けられたシステム及び方法に向けられる。ここに前記
曲げプランは、設備におけるパーツの製造において使用
されるように構成されている。前記システムは表示装置
上に曲げ順入力ウィンドウを生成且つ表示する曲げ順表
示システムを含み、前記曲げ順入力ウィンドウはパーツ
の2次元平面画像を有する。工具表示システムが更に設
けられそれは表示装置上に工具立て情報を生成し且つ表
示する入力装置が設けられ、それは前記パーツの2次元
平面画像に基づいて曲げ順を入力し且つ前記表示装置上
に表示された工具立て情報(工具構成情報)に基づいて
工具立て(工具構成)を選択する。更にシステムは前記
曲げ順に基づく前記パーツのための曲げプラン及び前記
入力装置により入力され且つ選択された工具立てを格納
するための曲げプラン格納システムを含む。
【0091】前記パーツの2次元平面画像は前記パーツ
の各曲げ線の表現を含む。そして前記入力装置は前記パ
ーツの前記2次元平面画像において表示される曲げ線の
各々を選択することにより曲げ順を入力するように構成
されている。前記入力装置はまた曲げ線が選択されると
ころの順番に基づいて曲げ順を入力するように構成され
ている。前記の代わりに或いはこれらと組み合わせて、
前記入力装置はまた前記各曲げ線が選択される時、前記
入力装置により入力される曲げ順番号に基づいて曲げ順
を入力するように構成されている。ここに開示されるよ
うに、前記システムと共に用いられる入力装置はジョイ
スティック装置またはマウス装置を含む。
【0092】システムは更に前記表示装置上に前記入力
装置により入力される曲げ順に基づいて前記曲げ線の各
々についての曲げ順番号を表示するための曲げ順番号表
示システムを含む。入力方向決定システムが、前記パー
ツの曲げ線の各々についての挿入方向情報を前記表示装
置上で決定し且つ表示するために設けられる。前記挿入
方向情報は、各曲げ線のための挿入方向を表現するため
の、表示される矢印を含む。更に前記曲げ線の各々は前
記パーツを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つを表示することを
含む。
【0107】前記表示の工程はまた、複数の工具タイプ
アイコンを有する第1のスクリーン表示を前記表示装置
上に表示するように設けられる。前記工具タイプアイコ
ンの各々は工具タイプを表す。更に前記方法は、前記入
力装置により前記工具タイプアイコンの1つを選択する
工程と前記工具タイプアイコンの1つの選択に応じて前
記表示装置上に第2のスクリーン表示を表示する工程と
を含む。ここに前記第2のスクリーン表示は複数の工具
形状アイコンを含み、前記工具形状アイコンの各々は前
記入力装置により選択された工具タイプアイコンに関連
する。前記方法はまた前記入力装置により前記工具形状
アイコンの1つを選択する工程と前記工具形状アイコン
の1つの選択に応じて前記表示装置上に工具寸法データ
のテーブルを表示する工程とを含む。前記工具寸法デー
タは複数の工具に関連し前記複数の工具の各々は前記入
力装置により選択された工具形状アイコンに関連する。
【0108】上記の特徴に加えて、さらに特徴と/また
はその変形を設けることができる、たとえば、発明を上
述した特徴の色々な組み合わせ、または再組み合わせ及
び/または下記の詳細な記述にある幾つかの特徴の組み
合わせとの再組み合わせに適用させることができる。
【0109】上に列記したものや他の本発明の対象物、
特徴及び利点については、この後により詳細に記述す
る。
【0110】付録の要約 本発明の詳細な記述をさらに促進するため、付記の限定
されない本発明の望ましい実施例の例に沿っての発明の
色々な特徴、操作及び機能に関するソースコードの例や
コメントを記した、以下の多数の付録を参照する:付録
Aはたとえば一つの類似部品を探索するときの特徴抽出
演算実行の典型的なソースコードであり;付録Bはたと
えば本発明の幾つかの類似部品の探索時に類似指数演算
を行使する典型的なソースコードであり;付録Cはこの
発明で曲げ線検出操作を行う典型的なソースコードであ
り;付録Dは本発明の2ーDクリーンアップを実行するため
の典型的なソースコードであり、これによって薄板金属
部品の3ーDモデルを元の3方向からの2ーD図面にもとづい
て作成するのに使用出来;付録Eは本発明の曲げモデル
ビューアーに色々なビュー モードや機能を実行するた
めの典型的ソースコードであり;付録F,G,HとIは本発明
の自動寸法入れ特性を実行するための典型的なソースコ
ードとコメントであり;付録Jは本発明の曲げモデルビ
ューアーの、部品・エンテイテイの観察可能性機能を実
行するための典型的なソースコードであり;付録Kは曲
げモデルの実施と部品構造の構成に関する、本発明の色
々な教訓をふまえた一般的なコメントを含み、付録Lは
与えられた部品の回転軸の動的計算による3ーD操作とナ
ビゲーションシステムを実行する典型的なソースコード
である。
【0111】本発明はこの後の詳細記述で限定されない
本発明の望ましい実施例の例についての多数の図面を参
照しながら記述されており、記述の中の同じ参照番号は
全図面中の類似の部品を示す。
【0112】詳細な説明 本発明の見地に沿って、全工場に亘って設計製造情報を
管理分配し、工場内での部品の製造を促進するための装
置と方法が具備される。この本発明の特徴は広範囲の工
場環境や装置に利用することができ、特にこの発明は一
続きの製作製造段階が異なる場所で行われる工場環境の
充足に利用できる。限定されない実施例や種々の例を通
じて、本発明を、たとえば進歩的な薄板金属製造設備に
おける曲げ薄板金属部品の製作を参照しながら記述す
る。
【0113】図1に、本発明の実施例に従って、進歩的
な薄板金属製造設備38一般が、ブロック線図で図示され
ている。図1に示すように、薄板金属製造設備または工
場38は全工場に分散している多数の場所10,12,14...20
をもつ。
【0114】これらの場所には設計事務所10、出荷作業
場14、打ち抜き作業場16、曲げ作業場18及び溶接作業場
20が含まれる。図1に画かれている薄板金属工場38には
分離した場所が六つしかないが、勿論工場は六つ以上の
分離した場所をもちうるし、また図1に画かれている各
タイプの事務所または作業場は一つ以上の場所を占める
こともある。たとえば設備38の大きさと製産必要容量に
より、一つ以上の打ち抜き作業場16、曲げ作業場18と/
または溶接作業場20を設けることができる。さらに工場
38は一つ以上の設計事務所10、組立作業場12または出荷
作業場14をもちうるし、曲げ薄板金属部品の製作製造を
促進するための他のタイプの場所をもちうる。
【0115】工場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打ち抜きプレ
スと/または切断機を制御する部品プログラムが作成で
きる。
【0116】打ち抜き作業場16と曲げ作業場18は各々CN
C及び/またはNC機械工具のどのような組み合わせでも備
えられる。たとえば打ち抜き作業場16は、コマ・シリー
ズ及び/またはペガ・シリーズのアマダ・タレット打ち
抜きプレス、あるいは他の市販されているCNC及び/また
はNC打ち抜きプレス一つまたは一つ以上もつことがで
き、また曲げ作業場18は、RGシリーズ アマダ・プレス
ブレーキまたは他の市販されている多軸ゲージング・プ
レスブレーキのようなCNC及び/またはNCプレスブレーキ
を一つまたは一つ以上もつことができる。さらに溶接作
業場20は、薄板金属部品に対して必要な如何なる溶接を
も果たすために適当な溶接機器を備えることができる。
打ち抜き作業場16、曲げ作業場18と溶接作業場20は設備
38の工場内のどの場所にも設置出来、熟練オペレータ
(たとえば打ち抜きプレスオペレータ、曲げ機オペレー
タ等)によって手動で動かすことができる機械も備えて
いる。アマダ セルロボミニやアマダ プロムキャムの
ような全自動またはロボット支援機械もこれらの場所に
備えることができる。必要な打ち抜きと曲げの作業、あ
るいは必要な如何なる溶接作業もこれらの作業場で製作
過程中に行うことができる。
【0117】さらに図1に示すように、進歩的な薄板金
属設備38は組立作業場12と出荷作業場14も含む。組立作
業場12と出荷作業場14には、顧客への製造部品の組立と
出荷を促進するために必要な梱包、ルート割り当て及び
/または輸送機器も含まれる。部品の組立と出荷は工場
職員によって手動で行使または管理されるが、機械自動
化及び/または機械支援にすることもできる。さらに組
立作業場12と出荷作業場14は、物理的に工場作業場(た
とえば打ち抜き作業場16、曲げ作業場18及び/または’
溶接作業場20に近接した)に近い場所に置くか、または
薄板金属工場38とは別の設備または区域に置くことがで
きる。本発明の見地に沿って、重要な設計と製造情報の
管理と分配は、設計と製造情報を電子的に記憶し、分配
することによって行われる。伝統的な紙上の仕事の段取
りまたはワークシートを、工場のどの場所からでも瞬時
的にアクセスできる電子的なジョッブシートに置き換
え、または補足することによって、本発明は工場の全体
的な効率を改善することができる。加えて、本発明の色
々な側面や特徴によって、記憶された設計製造情報の編
成とアクセスが改善される。さらに類似または同一の薄
板金属部品に関する以前の仕事情報のアクセスや検索
が、この発明の色々な特徴を通じて出来るようになって
いる。
【0118】この目的のため、本発明の色々な側面は、
サーバーモジュール32とデータベース30を薄板金属設備
38内の多数の場所10,12,14...20各々と結ぶ通信ネット
ワーク26を設けることによって実行される。このあと論
ずるように、各場所10,12,14...20は通信ネットワーク2
6とデータベース30にインターフエイスするステーショ
ンモジュールをもつ。図1、2と3に発明のこれらの特
色と実装の限定されない例を示す。
【0119】図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のような機械類のインターフエイス/制御
システムの一部であるコンピュータであってもよい。
【0120】サーバーモジュール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を介してつなぐことができる。
【0121】本発明の望ましい実施例に沿った限定され
ない例として、サーバーモジュール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)サーバーの全面的な支援を具備で
きる。
【0122】色々なデータベース言語と管理システムは
またデータベースに記憶された情報を創りだしたり、保
持したり見たりすることに用いられる。構造的問い合わ
せ言語(SQL)のようなデータベース言語をデータベー
ス30のデータを確定したり、操作したり、制御したりす
るのに用いることができる。たとえば、SQLサーバー
(マイクロソフト社から入手できる小売り製品)は本発
明の実施に利用できる。さらに、この発明は開放データ
ベース連結オープン・データベース・コネクテイビテイ
ー(ODBC)互換ドライバーを備えることによって通信ネ
ットワーク26を通してのデータベース30からの情報のア
クセスを促進できる。ODBCに関するより詳しい情報はマ
イクロソフトオープン・データベース。コネクテイビテ
イー・ソフトウエア開発キットプログラマー用レフアラ
ンス・マニュエルでえられる。
【0123】図2は本発明の別の実施例に従って建設さ
れた進歩的な薄板金属製造設備のブロック線図である。
図2の実施例では、データベース30とサーバーモジュー
ル32は別々に設置されており、データベース30はネット
ワークデータベースモジュール34を介して通信ネットワ
ーク26につながれている。上記のように、本発明はこの
構成に限定されたものではなく、データベース30とサー
バーモジュール32は一緒に設置でき(たとえば図1に示
すように)、ネットワークデータベースモジュール34の
データベースにアクセスする機能をサーバーモジュール
に取り入れることができる。図2はまた、薄板金属製造
設備38内の色々な場所10,12,14...20に設置できるステ
イションモジュール36の例を示す。図示の目的で、図2
には曲げステイション18に設置されたステイションモジ
ュール36が例示されている。図2の例には示されていな
いが、同様のステーションモジュール36を設備38内の他
の場所にも設置できる。
【0124】図2に示すように、各モジュール(サーバ
ーモジュール32、ネットワークデータベースモジュール
34及びステイションモジュール36)はネットワークイン
ターフエイスカードまたはポート42を介して通信ネット
ワーク26につなぐことができる。ネットワークインター
フエイスカード26はベンダー専用で、選ばれた通信ネッ
トワークの形式にもとづいて選択できる。 各モジュー
ル32、34、36は通信ネットワーク26とインターフエイス
するためのネットワークソフトウエアまたはプログラム
された論理を含むことができる。 通信ネットワーク26
はイーサネット(登録商標)(Ethernet(登録
商標))で、10ベース/T(ツイスト対)、10ベース/2
(同軸)、または10ベース/5(厚膜ケーブル)のような
多くのタイプの市販ケーブルから設備38の大きさと必要
なケーブル長さにもとづいて選んだタイプのケーブルを
用いたものであってもよい。
【0125】図2でサーバモジュール32はデイスプレイ
モニターまたはCRT44とキーボード、マウス及び/または
ジョイステイックを含む入力/出力デバイスをもつパソ
コンを含めうる。ネットワークインターフエスカード42
は備えられている拡張スロットまたはパソコン40のポー
トに挿入できる。さらに、パソコン40は100ー200MHzの処
理速度とペンテイアムまたはペンテイアム・プロ マイ
クロプロセッサーを含むことができる。パソコン40はま
た、たとえば32MBまたはそれ以上の主記憶装置と1.2GB
またはそれ以上のランダムアクセス記憶装置(RAM)を
含むことができる。デイスプレイ44は高解像度の表示画
面、たとえば800×600の解像度をもつ市販のSVGAモニタ
ーを含むことができる。デイスプレイ44に表示された色
々なグラフ一クスや情報を支援するため、パソコン40は
また、PCIグラフイックス・カードのような市販のグラフ
イックスクス・カードを含むことができる。さらに、コ
ンピュータ40はサウンド・ブラスター、または互換の音
声及びゲームポートアダプターカードを含み、入力/出
力装置46はキーボード、ジョイステイックと/またはマ
ウスを含むことができる。
【0126】この発明の色々な特徴を実行するために、
サーバーモジュール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サーバー
を、データをリンクするために備えることができる。
【0127】図2の実施例では、データベース30はサー
バーモジュール32から分離して備えられており、ネット
ワーク データベース モジュール34を経由して通信ネ
ットワーク26につなげられている。先に述べたように、
データベース30は工場38の規模と、データベースに記憶
させる部品情報の量にもとづいて選ばれた、適当な記憶
スペースをもったSCSIデイスク(たとえば1-4 GB)を含
むことができる。ネットワーク データベース モジュ
ール34は、ペンテイウム マイクロプロセッサーを備え
たIBM互換機のようなパソコン40と、通信ネットワーク2
6とインターフェースするためのネットワーク インタ
ーフエース カード42を備えた拡張スロットを含むこと
ができる。データベース30はデータ母線を介してパソコ
ン40に連結でき、パソコン40は標準的なデイスプレイや
デイスプレイ モニターまたはCRTとキーボードのよう
な入力/出力デバイス(図2には示されていない)も含
む。
【0128】SQLに基づいたデータベース30へのアクセ
スを容易にするため、ネットワークデータベース モジ
ュール 34のパソコン40は、 マイクロソフトSQLサー
バーやオラクルSQLサーバーのような、市販のSQLサーバ
ーと合わせて設置することができる。OLE2サーバーのよ
うなOLEサーバーをデータをリンクするために備えてお
くことができる。パソコン40もDOSやマイクロソフト・
ウインドウズNT(サーバー バージョン)のような、色
々なソフトウエアを備えておくことができる。
【0129】図2の実施例は一つのステーションモジュ
ール36の典型的な実装例を含んでいる。この実施例で
は、ステーションモジュール36は、曲げステーション18
に装備されている。図2に示すように、ステーションモ
ジュール36はサーバーモジュール32と同様のハードウエ
アを含んでいる。つまり、各ステーションモジュール
(たとえば図1に示す他のステーション)はデイスプレ
イ モニターまたはCRT44と、ジョイステイックまたは
マウスを含む入力/出力デバイス46をもつコンピュータ4
8を備えている。ネットワーク・インターフエイス・カ
ード42はコンピュータ40に備えられている拡張スロット
またはポートに差し込むことができる。前に論じたよう
に、ステーションモジュール36のコンピュータは 独立
型、またはパソコン、またはその場所に備えられた装置
または機械類のインターフエイス ・デバイスの一部で
ある汎用コンピュータであってもよい。たとえば、コン
ピュータ48は、100ー200 MHzの動作速度とペンテイウム
またはペンテイウム プロマイクロプロセッサーをもつ
IBM互換機のような自立型パソコンであってもよいし、
コンピュータ48はアマダAMNCシステムのような機械類の
インターフエイス/制御システムの一部、あるいはシス
テムに組み込まれたコンピュータであってもよい。コン
ピュータ48はまた、たとえば32MBまたはそれ以上の主記
憶と、1.2GBまたはすれ以上のランダム・アクセス記憶
(RAM)を保有することができる。デイスプレイ44は高
解像度デイスプレイ画面、市販のたとえば解像度800×6
00 をもつSVGAモニターを含みうる。デイスプレイ44に
デイスプレイされる色々なグラフイックスや情報を支援
するために、コンピュータ48はPCIグラフイックス・カ
ードのような市販のグラフイックス・カードを備えるこ
とができる。さらに、コンピュータ48はサウンド・ブラ
スター、または互換できる音響及びゲームポート・アダ
プターとそれを支援する入力/出力デバイス46のジョイ
ステイックまたはマウスを含むことができる。
【0130】この発明の色々な特徴を実行するために、
ステイション・モジュール36はソフトウエアといろいろ
な市販ソフトウエアが配置されている。たとえば、ステ
ーション・モジュール36はマイクロソフト・ウインドウ
ズ95またはウインドウズNT(ワークステーション版)の
ような基本ソフトが備えられている。さらに、ステーシ
ョン・モジュールに、この発明固有の機能と特徴をもた
せるために(たとえば図5を見よ)、ステーション・モ
ジュール36にソフトウエアまたはプログラム化論理装備
ルチーンが備えられる。後でより詳しく論ずるように、
これらのルチーンは高レベルのプログラム言語、たとえ
ばC++、及びオブジェクト指向プログラミング技術を用
いることによって開発できる。データをアクセスし、リ
ンクするために、ステーション・モジュール36はマイク
ロシフトOBCDドライバーとOLE2サーバーのようなOLEサ
ーバーが含まれている。サーバー・モジュール32と同
様、ステーション・モジュールもSQLをデータベース30
からデータをアクセスする基準に用いることができる。
【0131】曲げステーション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)の組み込みコンピュータに通常備わっ
ている機能をシミュレートできる。
【0132】図3はデータのサーバー・モジュール32、
データベース30と薄板金属製造設備38の間のそれぞれの
データの流れを示す実施例の典型である。図で表すため
と実施例におけるそれぞれのデータの流れの記述を容易
にするため、図3ではサーバー・モジュール32とデータ
ベース30(ネットワーク・データベース・モジュール34
に統合されている)は、各々別々に通信ネットワーク26
と直接に接続されていて、これらの構成要素間のデータ
の流れは通信ネットワークを通して行われる。勿論、こ
の技術に熟練した人なら分かるように、これら構成要素
間には多種多様のデータの流れ方式を用いることができ
る;また、データベース30がサーバー・モジュール32に
直接接続されている場合、データと情報はサーバー・モ
ジュールからデータベースに直接に、通信ネットワーク
26を用いることなく伝達できる。さらに、記述を容易に
するため、図3の通信ネットワーク26は簡略化されてお
り、図には打ち抜きステーション16と曲げステーション
18しか示されていない。しかしながら、場所10,12,1
4...20(工場内の他のあらゆる場所や区域も含めて)か
らのデータのやりとりの流れは、打ち抜きステーション
16と曲げステーション18について示したのと同様の方法
で行うことができる。
【0133】各顧客の注文に関連した設計製造情報は、
編成してデータベース30に記憶することができる。最初
に顧客から注文を受けると、基本的な製品と設計情報が
サーバー・モジュール32に入力され、それからデータベ
ース30に伝送され、記憶される。前に論じたように、サ
ーバー・モジュール32は、キーボードを備えたパソコン
等のような、データを入力する適当な手段を備えてい
る。サーバー・モジュール32でパソコンが用いられると
き、工場職員によるデータの入力を容易にするため、メ
ニュー方式画面を生成するソフトウエアを備えることが
できる。データ入力プログラムは、たとえばマイクロソ
フト・ウインドウズをベースとしたアプリケーション
で、ヘルプ及び/またはメニュー画面をもつものであっ
てよい。限定されない例として、サーバー・モジュール
32に入力され/または作成されて、データベース30に転
送されたデータは、図3に一般的に示してあるように、
部品情報、曲げモデル、特徴抽出データ及び曲げ線情報
を含むことができる。
【0134】部品情報は、たとえば部品または注文参照
番号、顧客の名前、部品の簡単な説明、バッチの大きさ
または量及び引き渡し予定日を含むことができる。曲げ
モデルデータは、たとえば部品の全体的な寸法(たとえ
ば幅、高さ、深さ)と材料のタイプ(たとえば鋼鉄、ス
テインレス鋼またはアルミニウム)、厚さ及び引っ張り
強さのような部品材料の情報を含むことができる。さら
に、特徴抽出データは手動による入力と/または自動的
に生成することによって、部品の主要な特徴を識別し、
データベースの類似部品の探索やその他の探索を容易に
する。特徴抽出データはデータベース30の別のフアイル
に格納するか、曲げモデルデータや各部品の仕事情報と
一緒に格納することができる。特徴抽出データは、たと
えば表面や面の数、曲げタイプの数(たとえば二面間の
正の折り曲げ、または二面間の負の折り曲げ)、面の間
の関係及び/または部品にある孔や他のタイプの開口の
数を含むことができる。後でより詳しく論ずるように、
このようなデータは特徴ベース部品マトリクスと/また
は逐次探索キー(たとえば下記の図6ー10を見よ)に
よって表現し、編成できる。最後に、曲げ線情報はデー
タベース30に格納するため、サーバー・モジュール32に
入力できる。曲げ線情報は、たとえば部品の各折り曲げ
の曲げ角度、曲げ長さ、曲げの内半径(IR)、縮小量及
び曲げ方向(たとえば前方または後方)を含む主要な曲
げ線情報を含む。
【0135】通信ネットワーク26を通じてデータベース
30へデータを送受信するため、各場所10,12,14...20は
通信ネットワークに接続されているステーション・モジ
ュール(前に述べたステーション・モジュール36のよう
な)を含めることができる。図3には、打ち抜きステー
ション16と曲げステーション18は一般的にステーション
・モジュールと合わせたブロック線図で示されている。
前に論じたように、ステーション・モジュールは、たと
えばソフトウエア、または制御論理と独立型パソコン、
またはその場所に備えられた装置または機械類の一部で
ある汎用コンピュータを含む。各顧客の注文に応じて、
設計製造情報(部品情報、曲げ線情報および曲げモデル
・データを含む)が、所定参照番号またはコードを入力
することによってアクセスでき、検索できる。参照番号
またはコードは手動(たとえばキーボードまたはデジタ
ル入力パッドによって)またはバー・コードを、ステー
ション・モジュールに備えられているバー・コード読み
とり装置またはスキャナーでスキャンすることによって
入力できる。さらに、本発明の見地に沿って、以前の仕
事情報はデータベース30から、工場内のどの場所10,12,
14...20からでも、同様の部品探索を行うことによって
アクセスし、検索できる。引き続く詳しい記述で論ずる
ように、類似部品の探索は、特徴抽出データ、またはデ
ータベース30に記憶されている探索キーにもとづいて行
うことができ、これによって同一または類似の部品に関
する以前の仕事情報が検索され、将来の仕事の全体的な
製造時間の短縮に利用できる。
【0136】データベース30から検索された製造情報
は、作業場オペレータが曲げ計画を作成し、テストする
のに用いられる。たとえば、曲げステーション18の曲げ
オペレータは、薄板金属部品に必要な工具や最適な曲げ
手順を決めるために、データベース30から部品情報、曲
げ線情報や曲げモデル・データをアクセスし、検索する
ことができる。本発明の見地に沿って、ODBCドライバー
を備えることにより、各ステーション・モジュールがデ
ータベース30とインターフエースし、データベースに記
憶されている情報を表示できるようにすることができ
る。さらに、サーバー・モジュール32またはデータベー
ス30のネットワーク・データベース・モジュールは、デ
ータベースに記憶されているデータのアクセスと検索を
容易にするために、SQLサーバーを含むことができる。
最終曲げ計画に基づいて曲げコードがプログラムされる
と、曲げコードは曲げ手順とともに、図3に一般的に示
すように通信ネットワーク30を通じて、曲げステーショ
ンのステーション・モジュール18からデータベース30に
送られる。この情報は、当該の仕事に関連する他の設計
製造情報とともに記憶される。
【0137】他の情報もデータベース30に記憶すること
ができる。たとえば、部品の2ーD及び/または3-D画像表
現は曲げモデルデータとともに記憶することができる。
この2ーDまたは3-D画像表現は設計ステーション10または
他の場所でCAD/CAMシステムを用いて作成し、設計ステ
ーション(あるいは他の適当な場所)のステーション・
モジュールを介して通信ネットワーク26を通じ、データ
ベース30に転送できる。あるいはまた、2ーDまたは3-D画
像はサーバー・モジュール32で、後でより詳しく述べる
ように、適当なCAD/CAMシステムまたはモデル化ソフト
ウエアを用いて、一連の機能または演算を実行すること
によって作成できる。
【0138】図4と5を参照しながら、サーバー・モジ
ュール32と各場所10,12,14...20においてプログラムさ
れ実行される処理や演算について詳述する。図4と5は
サーバー・モジュール32と薄板金属製造設備38内の各場
所10,12,14...20で実行される基本論理の流れの流れ図
である。図5は、たとえば曲げステーション18で実行さ
れる典型的な処理や操作に対するものであるが、設備38
内の特定な場所で実行される操作によっては、これ以外
の処理やステップも実行できることは理解できよう。以
下に述べる処理や操作はソフトウエア、または多種類の
プログラム作成言語と技法の一つを利用することによっ
て実施できる。たとえば、本発明の見地に沿って、関連
図面を参照しながら記述する下記の処理や操作は、C++
のような高レベルのプログラム作成言語とオブジェクト
指向プログラミング技法を用いることによって実施でき
る。さらに、限定されない例として、ウインドウズ・ベ
ース アプリケーション用にマイクロソフト社が作成し
た、プログラム作成言語のバージョンであるヴイジュア
ルC++を利用することができる。
【0139】図4は本発明の見地に沿って、サーバー・
モジュール 32が行う基本的な処理と操作の流れ図であ
る。図4はサーバー・モジュール32がソフトウエアまた
はプログラム化論理によって実行する処理と操作の基本
論理フローである。サーバー・モジュール32は、オペレ
ータまたはユーザーがサーバー・モジュールの色々な処
理や操作の選択と実行を支援するためにツール・バーや
ヘルプ及び/またはメニュー画面をもつウインドウズ・
ベース アプリケーションを含むことができる。処理は
薄板金属製造設備38で顧客の注文を受けたステップS.1
から開始される。顧客の注文は通常部品が工場で製造す
るのに必要な製品と設計の情報を含む。この情報は、た
とえば部品の幾何学的寸法、部品に必要な材料や他の設
計情報も含む。顧客から受けた情報をもとに、サーバー
・モジュール32は、ステップS.3に画かれているよう
に、データベース30に記憶されている以前の仕事情報の
探索を実行する。データベース30に記憶されている仕事
情報は多様な探索基準にもとづいて探索できる。たとえ
ば、情報は事前定義参照または仕事番号にもとづいて探
索でき、あるいは類似部品の探索は部品のある設計特徴
にもとづいて実行でき、これによって同一または類似の
部品に関する以前の仕事情報が現在の仕事のために検索
でき、利用できる。利用できる類似部品探索のさらに詳
しい記述は、図6ー10を参照しながら以下に記す。
【0140】ステップS.5では、データベースの検索結
果が解析され、現在の顧客の注文が新しい部品か、以前
の仕事に類似の部品か、あるいは以前の仕事の繰り返し
かが決定される。同一の照合が見いだされる(たとえば
同じ部品または参照番号が見いだされる)と、顧客の現
在の注文は工場で行った以前の仕事の完全な繰り返しに
なり、仕事情報に対するこれ以上の修正は不必要で、以
前の仕事情報をデータベース30からアクセスしてステッ
プS.11に示すように現在の顧客の注文の遂行に利用でき
る。データベースの探索は以前の仕事の部品または参照
番号及び/またはフアイル名を与え、それによってサー
バー・モジュール32またはどのステーション・モジュー
ルにいるオペレータでもデータベースから仕事情報をア
クセスすることができる。部品または参照番号しかえら
れない場合、変換テーブルを備えることによって、オペ
レータが部品参照または仕事番号を入力することによっ
て以前の仕事情報のフアイル名を決定し、アクセスでき
る。従って、たとえばサーバー・モジュール32にいるオ
ペレータは、仕事情報と2ーDと3-Dモデル化情報をデータ
ベース30からアクセスすることによって部品の幾何学を
解析し、繰り返しの注文と類似であることを確認するこ
とができる。注文が繰り返しの注文であることが確認さ
れると、曲げステーション18のステーション・モジュー
ルにいる曲げオペレータは、さらに以前の仕事情報をア
クセスし、曲げコードのデータと工具段取り情報を含む
製造情報を曲げと部品の製作に利用することができる。
かかる記憶された専門的知識を利用することによって、
このようにして、繰り返しの注文をより効率的に、以前
に入力され開発された仕事情報を必要とせずに製造する
ことを可能にする。
【0141】しかしステップS.5で、もし現在の顧客の
注文が以前の仕事と類似か、以前の仕事と同じである
が、たとえば仕事または参照番号またはバッチの大きさ
等の修正が必要と決定されれば、ステップS.7での探索
で捜し出した以前の仕事情報データはデータベース30か
ら検索され、サーバー・モジュール32にいるオペレータ
によって編集し、修正される。編集機能を備えることに
よって、以前の仕事データを編集し、修正して新しい仕
事データを作成し、現在の顧客の注文のためにデータベ
ース30に格納できる。必要とする編集の量は、以前の仕
事と現在の仕事間の類似性の程度による。編集の量は、
参照または仕事番号またはバッチの大きさの単なる修正
から/または、部品の寸法や定められた曲げ手順の編集
のような、より広範囲な修正を含むものにわたる。以前
の仕事情報の編集が終わると、修正された仕事情報はス
テップS.9でデータベース30に格納される。修正された
仕事情報は新しい参照または仕事番号で格納できる。さ
らに、色々なデータベース管理機能(コーピー、削除、
保管、再命名等)を備えることによって、特別なコマン
ドの入力でデータベース30の以前の仕事情報の保持、ま
たは以前の仕事情報の消去または上書きができる。
【0142】現在の仕事に適合する類似または同一のも
のが無く、従って現在の顧客の注文は新しい仕事に関係
することが決定されると、論理フローは図4に示すステ
ップS.15に進む。この場合、現在の仕事は新しい仕事に
関するものになるので、設計製造情報を独立に作成し、
入力しなければならない。サーバー・モジュール32から
メニュー及び/またはヘルプ画面を提供することによっ
て、オペレータが必要な仕事情報すべてを入力するのを
支援することができる。本発明の見地に沿って、サーバ
ー・モジュール32のオペレータは、最初に新しい仕事の
基本的な部品情報を入力することによって新しいフアイ
ルを作成できる。部品情報は、たとえば参照または仕事
番号、顧客の名前、部品の簡単な記述、仕事に必要なバ
ッチの大きさまたは量及び予定引き渡し年月日を含む。
特徴抽出データまたは探索キーもステップS.15で入力で
きるし、また、以下に記すように、このデータを自動的
に作成するか、曲げモデルデータの作成と同時に抽出す
ることができる。他のデータや情報もステップS.15で入
力するか、部品の各曲げ線の曲げ角度、半径や長さを含
む曲げ線情報のような曲げモデルデータの入力後か入力
中に入力できる。ステップS.15に引き続き、論理フロー
は図4に示すように、オペレータによって曲げモデルデ
ータがサーバー・モジュール32で開発され、入力される
ように進む。
【0143】曲げモデルの開発と入力は、顧客から提供
された原図や情報に依存する。顧客の注文は、たとえば
製造される部品の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図面の提
供と表現は、設計プログラマー、曲げオペレータや他の
ユーザがより容易に解釈され理解される部品のモデリン
グとシミュレーションの図を与える。厚さ情報を省くこ
とはまた、サーバー・モジュールやステーション・モジ
ュールで、文中に記述の本発明の色々な特徴を実行し達
成するのに要する処理時間を短縮し、改善する。このよ
うな特徴のより詳細な記述や、本発明で利用することが
できる折りたたみと展開アルゴりズムについては、以下
に付図を参照しながら記述する。
【0144】図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に取り入れられ
る。
【0145】一方向平面図が提供された場合は、曲げモ
デルを作成する処理は、図4に示すようにステップS.19
から始められる。ステップS.19で、受理または作成され
た2-D平面図はサーバー・モジュール32に入力される。
部品の全体的な寸法(幅、高さ、深さ)のような他の曲
げモデルデータ及び部品材料情報もステップS.19で入力
できる。その後、折りたたみアルゴリズムまたは処理を
用いて、ステップS.21に一般的に示されているように、
元の2ーD一方向図面にもとづいて3ーDモデル(材料の厚さ
のない)を作成することができる。2ーD平面図から3-Dモ
デルを作成するのに行われる処理や操作の例は、図11
ー18を参照しながら後で述べる。
【0146】部品の3ーDワイヤーフレーム図(材料厚さ
の無い)が受理または作成された場合、図の情報はステ
ップS.27で入力される。さらに、他の曲げモデルデー
タ、たとえば部品の全体的な寸法(幅、高さ、深さ)及
び部品材料情報もステップS.27で入力できる。この後
に、ステップS.27に示すように、部品の2ーDモデルを作
成するために、サーバー・モジュール32で展開のアルゴ
リズムまたは処理が実行される。2ーDモデルを3ーD図面
(厚さのない)から作成するために行われる処理と操作
の例は、たとえば図19を参照しながら後で述べる。
【0147】部品の2ーDと3-Dモデル表示は、その部品の
ための曲げモデルの一部として格納される。さらに、前
に注記したように、2ーDと3-Dモデルの作成と格納の間
に、他の曲げモデルデータ(部品材料情報やその他の製
造情報のような)も入力し、曲げモデルデータとともに
データベース30に格納できる。曲げモデルデータを編成
し、格納するために実施できる、いろいろな機能やデー
タ構造配列についてはあとでより詳しく記述する(たと
えば図26と27を見よ)。
【0148】図4に示すように、簡単な3ーD図面(材料
厚さなしの)がもともと作成または受理されていない場
合は、最終的な2ーDモデルを作成するのに必要な展開ア
ルゴリズムまたは処理を行う前に、部品の3ーDモデル
(厚さなし)を作成するための付加的な処理が必要とな
る。ステップS.23、S.25、S.31とS.33 は、ステップS.2
9で展開アルゴリズムを実行し、2ーDモデルを作成する前
に、サーバー・モジュール32で一般に実施される付加的
な処理と操作を示す。
【0149】たとえば、部品の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を参照し
ながら述べる。
【0150】しかしながら、もし材料厚さが入っている
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を参照しながら下記に述べる。
【0151】図4に示すように、すべての重要な情報が
作成され、入力された後、顧客の注文に関連する部品情
報、曲げモデル情報及びその他のデータは、ステップS.
35でサーバー・モジュール32からデータベース30に移さ
れて格納される。データベース30に格納されたデータ
は、データベース探索を行うときに利用できる特徴抽出
または探索データも含む。下記に述べるように、特徴抽
出または探索データは、各仕事に関連した部品の基本的
または主要な特徴を指示するデータも含まれ、これによ
って仕事情報や格納されている同一または類似部品に関
する専門的知識の探索が実施できる。サーバー・モジュ
ール32に入力されたデータと情報は、たとえば図3に示
すように、直接データベース30に、または通信ネットワ
ーク26を介して転送することができる。上述のように、
曲げモデルデータを作成するときに、色々な図面に対し
て実施できる各種の処理や操作についての詳しい記述
は、下記に付図を参照しながら記す。
【0152】図5は薄板製造設備38の場所10,12,14...2
0に設けられ、各ステーション・モジュールで実施され
る基本的な処理や操作の流れ図を示す。例証のため、図
5は、たとえば曲げステーション18に置かれたステーシ
ョン・モジュールで実施される基本的な処理や操作の基
本論理の流れの例を示す。本発明の教示にもとづく技術
に熟練した者には理解できるように、図5に示す論理の
流れは、各場所で実施される操作や処理の性格により、
各ステーション・モジュールで修正できることは勿論で
ある。さらに、サーバー・モジュール32と同様、下記に
述べるステーション・モジュールでの処理や操作にはソ
フトウエアまたはプログラム化論理を装備できる。加う
るに、ステーション・モジュールは、オペレータまたは
ユーザーによる色々な処理や操作の選択と実施を容易に
するために、ツール・バー・アイコンまたはヘルプ及び
/またはメニュー画面をもつウインドウズ・ベース・ア
プリケーションを含むことができる。このようなヘルプ
及び/またはメニュー画面は、ステーション・モジュー
ルにおいてデータの入力または転送を容易にするために
も設けることができる。
【0153】図5に示すように、ステップS.51でステー
ション・モジュールを初期設定した後、オペレータはス
テップS.53で一つまたは一つ以上のデータベース探索基
準またはキー項目を入力することができる。探索基準
は、データベース30に格納されている以前の仕事情報、
または新しいまたは現在の仕事に関する仕事情報を捜し
出すために入力できる。オペレータは、たとえばデータ
ベース30から特定の仕事情報を検索するために、予め定
められた番号またはコードを入力できる。たとえば、本
発明の見地に沿って、バーコード をルーチングシート
に付すか、せん孔された材料につけて、ステーション・
モジュールでバーコード読みとり装置でスキャンするこ
とによって情報をアクセスすることができる。あるい
は、参照コードまたは番号を、ステーション・モジュー
ルでキーボードまたはデイジタル入力パッドを介して手
動で入力できる。変換テーブルを備えることによって、
部品参照または仕事番号のオペレータによる入力によっ
て、以前の仕事情報を定めることもできる。さらに、探
索基準またはキーを入力することによって、以前に格納
した仕事情報の類似部品探索を行うことも予想される。
このような探索は、部品の色々な設計特性または特徴抽
出データにもとづいて行うことができる。本発明の見地
に沿って実行できる類似部品探索の説明は、下記に図6
ー10を参照しながら記す。
【0154】探索基準をステップS.53で入力した後、ス
テーション・モジュールはステップS.55で、通信ネット
ワーク26とネットワーク・データベース・モジュール34
を介してデータベース30の探索を実行できる。探索の結
果はステーション・モジュールに戻され、ステップS.57
でオペレータまたはユーザーが新しい仕事または類似の
以前の仕事に関する情報を要請したのか、または要請が
以前の仕事の完全な繰り返しに関するものなのかを決め
るために解析される。
【0155】同一のものが見いだされる(たとえば同じ
部品または参照番号が突きとめられる)と、以前の仕事
の繰り返しが決定され、仕事に関する格納されている設
計と製造情報がデータベース30からステーション・モジ
ュールに転送され、ステップS.59に一般的に示している
ように、オペレータが見られるように表示される。ステ
ーション・モジュールは一つまたは一つ以上のメニュー
表示画面または登録簿をもち、オペレータがデータベー
ス30から検索された色々な情報を選択し、表示できるよ
うになっている。オペレータは表示された情報をレビュ
ーし、ステップS.61における3ーD曲げシミュレーション
のような、色々なシミュレーションを走らせて、その仕
事の曲げ手順の色々な段階を観察し、部品の幾何学を理
解することができる。オペレータはまた、必要工具や仕
事情報に記録されている他の特別な命令やメッセージの
ような他の情報をレビューすることもできる。仕事情報
の確認が終わると、オペレータは曲げ、または他の必要
な機械類を構成し(組立)、機械を操作して指定された
薄板金属部品を製作することができる。データベース30
から検索された仕事情報は、たとえば曲げステーション
18の機械類を制御する曲げコードを含む最終曲げ計画デ
ータを含む。機械類の構成と実際の操作は、このように
して図5のステップS.63に一般的に示してあるように、
オペレータによって遂行される。
【0156】もし同一または類似の仕事情報が捜し出さ
れず、情報が新しい仕事(つまりサーバー・モジュール
32には予備的な仕事情報のみ入力され、完全な仕事情報
が作成されていない)に関するものであることが決定し
た場合、部分的な部品情報と曲げモデルデータはデータ
ベース30から引き出されてステーション・モジュールに
送られ、ステップS.77 でオペレータによって観察され
る。要請した情報は新しい仕事に関するものなので、オ
ペレータは必要な工具と曲げ手順を含む曲げ計画を作成
し、入力する必要がある。下記により詳しくのべるよう
に、曲げオペレータによる曲げ計画の作成を容易にする
ため、ステーション・モジュールにグラフイカル・ユー
ザー・インターフエース(GUI)や他の機能を備えるこ
とができる。GUIは、たとえば工具の選択、部品と工具
間の潜在的な不一致の自動点検、及び提案された曲げ手
順の各中間段階のシミュレーションを表示することによ
ってオペレータが曲げ計画を作成するのを支援するため
に設けることができる。サーバー・モジュールで曲げ計
画を作成し、入力したオペレータは、ステップS.80で曲
げコード(曲げ機械で曲げ手順を実行するためのCNCま
たはNCコード)を生成するために曲げ手順をプログラム
する。曲げコードは直接サーバー・モジュールで入力す
るか、曲げ機械類のCNCまたはNC制御装置とインター
フエースしてサーバー・モジュールに取り入れることが
できる。しかる後、オペレータはステップS.81で、曲げ
作業ステーションにおいてセットアップし、曲げ計画を
テストすることができる。曲げ計画に必要なすべてのテ
ストと必要な修正が完了すると、ステップS.83で最終的
な曲げデータをデータベース30に入力し格納する。最終
的な曲げデータは、曲げプログラムとともに、曲げ手順
と工具構成情報を含む。この情報は、たとえば曲げステ
ーション18のステーション・モジュールからデータベー
ス30に送られ、新しい仕事に関する他の設計製造情報と
ともに格納される。
【0157】図5のステップS.57で、情報が以前の仕事
の類似部品または同じ部品に関係しているが、たとえば
異なる参照あるいは仕事番号またはバッチ量等をもつこ
とが決定されれば、論理の流れはステップS.65に進む。
ステップS.65では、以前の仕事情報がデータベース30か
ら検索され、曲げステーション18で表示される。曲げオ
ペレータまたはユーザーはデータを見て、類似部品に必
要なデータの変更が何かを決める。この場合もステーシ
ョン・モジュールは一連のメニュー表示画面または登録
簿(ディレクトリ)を備えて、オペレータが、表示する
情報と、情報をどのように表示または修正するかの選択
ができるようにされている。たとえば、ステップS.69で
は、オペレータの類似部品の曲げ計画の作成を容易にす
るため、検索された情報にもとづいた3ーD曲げシミュレ
ーションを備えることができる。以前の仕事情報をレビ
ューした後、オペレータはステップS.70で、曲げプログ
ラムとともに、工具と曲げ情報を修正する。部品の寸
法、参照番号やバッチ量のような他の仕事情報もステッ
プS.70で修正し、編集することができる。これが終わる
と、ステップS.71で実際の工具セットアップとテスト
が、オペレータによって作業場において、修正された曲
げ計画をテストするために行われる。テストと曲げ計画
をさらに修正することが完了すれば、オペレータはステ
ップS.73で最終的な曲げデータを入力し、それに新しい
参照番号または仕事番号をつけてデータベース30に格納
する。上記のように、以前の仕事情報もデータベース30
に、他の格納された仕事フアイルとともに保持できる。
さらに、色々なデータベース管理機能を、データベース
に格納されているフアイルを格納、消去、再命名等する
ために備えることができる。
【0158】次に図6ー10を参照しながら、本発明の
教えるところに従って実行できる類似部品探索機能の例
を詳しく述べる。本発明の見地に沿って、特徴ベース形
態類似性探索アルゴリズムを利用する類似部品探索手続
きを、データベース30から以前の仕事情報を探索し、検
索するのに備えることができる。類似部品探索は製作さ
れる部品に関する設計特徴及び/または製造情報にもと
づいた同一及び/または類似部品の探索を含むことがあ
る。また類似部品探索は、たとえばサーバー・モジュー
ル32及び/または工場38内の色々なステーション・モジ
ュールにあるソフトウエアまたはプログラム化論理の使
用によっても実施できる。類似部品探索はサーバー・モ
ジュール32または薄板金属曲げ工場38内の場所10,12,1
4...20のいずれかで実行できる。C++またはマイクロソ
フト社のビジュアルC++プログラム言語のような、高レ
ベルのプログラム言語とオブジェクト指向プログラム技
法が類似部品探索の色々な処理や操作を実施するのに利
用することができる。
【0159】図6と7は利用できる類似部品探索アルゴ
リズムまたは処理の論理の流れを示す。図6に示すよう
に、重要な部品モデルデータフアイルはステップS.100
でアクセスできる。部品モデルには、たとえば設計事務
所10に置かれたCADシステムで作成された曲げモデルデ
ータ及び/またはサーバー・モジュール32で作成され、
入力されたデータが含まれる。部品モデルには、たとえ
ば部品の色々な表面または面及び曲げ線の向き、幾何学
的関係及び相対位置を表す部品形態データ(部品トポロ
ジーデータ)が含まれる。部品モデルデータが検索さ
れ、または曲げモデルデータが手動で入力された後、ス
テップS.102で、当該部品の曲げモデル及び/または部品
形態データにもとづいた特徴抽出データを自動的に導出
するための特徴抽出操作を行うことができる。
【0160】本発明の見地に沿って、特徴抽出データ
は、薄板金属部品の色々な特徴を解析することによって
導出できる。たとえば、部品の色々な面の解析によっ
て、隣り合わせの面が開放または接触コーナーをもつか
どうかを決めることができる。平行曲げ、直列曲げ、共
線曲げまた対向曲げのような他の特徴も、各部品の明確
かつ独特な特徴を決定し、抽出するために解析すること
ができる。
【0161】表1は類似部品探索を行うときに解析され
る色々な曲げと面の特徴を示す。特徴抽出操作に含めな
ければならない抽出特徴は、正の曲げ、負の曲げ特徴と
ともに接触コーナー、開放コーナー特徴である。さらに
特徴抽出操作は、少なくとも平行曲げ、直列曲げ、共線
曲げ、異相共線曲げ及び厚さオフセット曲げの特徴解析
を含まなければならない。
【0162】ステップS.102で行った特徴抽出操作は、
各特徴の曲げモデルデータと形態(トポロジー)の解
析、形態の修正、今後の解析のための形態にもとづく特
徴ベース行列(特徴に基づく行列)の作成からなる一連
の操作を含むこともある。例証のため、図8(a)―9
(d)に接触コーナーをもつ4折り曲げ箱部品と開放コ
ーナーをもつ4折り曲げ箱部品に対する特徴抽出操作を
示す。
【0163】
【表1】 例証のため、図8(a)-9(d)には隣接面のコーナ
ー関係にもとづく特徴抽出が示されている。図8(a)
に示す五つの面(1ー5)をもつ閉じた4折り曲げ箱や、図
8(b)に示す五つの面(1ー5)をもつ開いた4折り曲げ
箱については、いずれの部品を表すにも、図8(c)に
示す同じ簡単な面形態が提供される。この形態は部品ま
たは曲げモデルデータとともに格納し、提供することが
できる。しかしながら、図8(c)の単純な面形態(面
トポロジー)は、部品の面(1ー5)の間の関係の基本的な
情報しか与えず、隣接する面間のコーナーの関係や曲げ
の種類のような部品の色々な特徴の情報は与えない。従
って、特徴抽出操作時に、部品または曲げモデルデータ
とともに格納されている関連面形態をを解析することに
より、基本的な面形態が部品の色々な特徴についての付
加的な情報を含むように修正することができる。
【0164】たとえば、図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゜負の曲げ角度等)も
行列の中に示すことができる。
【0165】上記のように、ステップ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、ビユー行列、半径、角度開始、角度
終了)で指定することができる。部品形態データも、部
品の色々な面や曲げ線の場所やこれらの間の幾何学的関
係を示すために提供することができる。各面は線と/ま
たは弧の集合または連結データリストで定義することが
できる。
【0166】部品の特徴を抽出するため、曲げモデルと
形態データの特徴抽出操作を行い、解析することによっ
て、ある特徴が部品に存在するかどうかを定めることが
できる。このプロセスは、抽出する各特徴間の色々な特
色や関係にもとづく、曲げモデルと形態データの解析を
含むこともできる。各特徴の特色と関係を知るための曲
げモデルと形態データの解析によって、ある特徴(たと
えば面間の接触コーナー、開放コーナー特性、または平
行または直列曲げ特性)の存在が検出できる。異なるプ
ロセスを、各特徴の特定の特性と関係を特徴抽出操作で
検出するために備えることもできる。解析される各特徴
間の特性と関係の類似性にもとづいて、部品に一つ以上
の特徴が存在するかどうかをチェックするために幾つか
のプロセスを組み合わせるか作成することもできる。
【0167】限定されない例として、ステップS.102に
おける特徴抽出操作の際に、コーナーの特徴、たとえば
同じ曲げ方向をもつ二つ面の接触コーナー特徴(表1のT
ouchCnr特徴)を抽出し、検出するために行うことがで
きるプロセスについて述べる。下記のプロセスは、他の
特徴の検出、たとえば逆曲げ方向をもつ二つの面の接触
コーナー特徴(表1のtouchCnr特徴)または同じまたは
逆曲げ方向を持つ二つの面の開放コーナー特徴(表1のO
penCnrとopenCnr特徴)に用いることもできる。プロセ
スを修正することによって、他の特徴も検出できる(た
とえば平行曲げ、直列曲げ等)。さらに、面の可能な各
組み合わせに関するデータを、抽出される各特徴の特性
と関係を知るために解析することができる。
【0168】たとえば、接触コーナーの特徴をもつTouc
hCnrの場合、検出する特徴または関係は:共通の面を持
つ二つの面;同じ曲げ線方向;同じ頂点を(または頂点
間の距離が事前に定めた範囲内にある頂点)をもつ曲げ
線を含む。接触コーナーの特徴をもつtouchCnrの場合、
同様の特性または関係を検出しなければならない;ただ
同じ方向の曲げ線をもつ面ではなく、面は逆方向の曲げ
線をもっていなければならない(たとえば表1をみ
よ)。開放コーナー特徴OpenCnrとopenCnrも同様に検出
できるが、各特徴に接触コーナー関係の代わりに、面間
に開放コーナーが存在する(たとえば面の曲げ線が事前
設定の範囲の距離より大きく隔たっている)ことと、同
じまたは逆の曲げ線方向(たとえば表1と表中のOpenCnr
とopenCnrの定義をみよ)をもつ曲げ線を検出し、解析
しなければならない。
【0169】接触コーナー特徴(たとえば表1のTouchCn
r特徴)を検出するためには、先ずある二つの面を解析
し、二つの面が共通の面に接続しているかを決定する。
これは各面の曲げ線データと各曲げ線の曲げ線ー面関係
データを探索して、共通面が存在するかどうかを決定す
ることによって検出できる。もし二つの面が共通の面に
接続していれば、各面の曲げ線方向を解析して同じ曲げ
線方向(または、たとえばtouchCnr特徴を検出する場合
は逆の曲げ線方向)をもつかを見る。これは、たとえば
各面の曲げ線方向を示すベクトルデータを解析する事に
よって決められる。
【0170】二つの面が共通の面をもち、曲げモデルと
形態データにもとづいて同じ曲げ線方向をもつことが決
定されると、データを検査することによって曲げ線が平
行かどうかが検出される。色々な方法を用いて、曲げモ
デルと形態データにもとづいて曲げ線が平行かどうかを
検出することができる。たとえば、平行曲げ線の検出
は、曲げ線方向を定めるベクトルの外積をとることによ
って決められる。もしベクトルの外積がゼロ(または近
似的にゼロ)であれば、曲げ線は平行であると決定され
る。もしベクトルの外積がゼロでなければ(または近似
的にゼロでない)、二つの面の曲げ線は平行でない。
【0171】二つの面が共通の面をもち、曲げ線方向が
同じで曲げ線は平行ではないことが決まった後、面の間
のコーナーの関係(たとえば接触か開放か)を決めるた
めに、曲げモデルデータが解析される。二つの面のコー
ナー関係は、曲げモデルデータから、面の曲げ線が共通
の頂点をもつかどうかを検出することによって決められ
る。曲げ線が共通の頂点をもっていれば、二つの面は同
じ曲げ線方向の接触コーナー関係(表1のTouchCnr特
徴)をもつ。曲げ線は共通の頂点をもっているが、二つ
の面の曲げ線方向が異なることが決まれば、二つの面は
逆方向の接触コーナー関係(たとえば表1のtouchCnr特
徴)をもつと決められる。
【0172】二つの面が共通の頂点をもっていない場合
でも、頂点間の距離が予め定められた範囲内であれば、
二つの面は接触コーナー関係をもつと決定できる。しば
しば部品の隣接する面の間に、たとえばパンチ工具を通
すためのすき間として最小限のスペースが設けられるこ
とがある。このスペースは、通常フランジの高さのとこ
ろでの工具の幅で決められる。例をあげれば、二つの面
の曲げ線の頂点間の距離が0ー5mm以内であれば、接触コ
ーナー特徴の存在が決定できる。もし二つの面のコーナ
ー間のスペースが、事前に定められた範囲より大きけれ
ば、開放コーナー特徴の存在が決定できる(たとえば表
1のOpenCnrまたはopenCnr特徴)。
【0173】上記のプロセスは部品の面のあらゆる組み
合わせについて、各面のコーナー特徴を決めるために実
施することができる。部品の面や曲げ線に関連する他の
特徴も、同じように部品幾何学と形態データの解析によ
って行うことができる。ステップS.102における特徴抽
出操作を実行するための典型的なコードを付録Aに示
す。このコードはC++プログラム言語で書かれており、
表1に記してあるような特徴を抽出検出するための色々
なプロセスを含む。付録Aのコードには、使用されてい
る論理やアルゴリズムの解析を容易にするためのコメン
トがついている。またこのコード例では、色々な特徴の
理解を助けるために、表1と同じ特徴の用語が使われて
いる。
【0174】部品の色々な特徴が検出されると、部品の
基本的な形態は修正され、抽出された特徴が含められ
る。特徴ベース形態を提供することは有用かもしれない
が、このような形態をお互いに比較することは容易でな
い。その代わりに、本応用の発明者達は行列の形で提供
された特徴抽出情報を比較する方が、より有効で容易で
あることを発見した。従って、本発明の一つの特徴とし
て、特徴抽出操作の際に、検出された特徴にもとづいた
特徴ベース部品行列(図9(c)と9(d)に示す代表
的な行列のような)が作成される。作成された部品の特
徴ベース行列は、他の所定の、格納された行列と比較す
ることによって、どのような基本的な形や特徴が部品に
含まれているかを決定する。
【0175】特徴ベース行列は、部品の色々な特徴を検
出し、抽出した後に、部品毎に作成され、格納される。
図9(c)と9(d)に示すように、行列は対称的な2
次元行列で部品の面の数に等しい次数をもつ。行列は部
品のすべての検出された特徴情報を含み、各面の間の色
々な特徴が行列の各場所に提供されている。特徴ベース
行列は、一時的にサーバーまたはステーションモジュー
ルの記憶装置に格納し、類似部品探索を実行するときに
のみ使用し、所定の行列と比較することができる。ある
いは、特徴ベース部品行列を永久的に他の仕事情報とと
もにデータベース30に格納し、工場内のどの場所でもア
クセスできるようにすることができる。
【0176】図6に戻ると、特徴抽出操作を行った後、
引き出した特徴抽出データ行列を、特徴形態ライブラリ
に備えられている所定の特徴抽出データ行列と比較する
ことができる。特徴形態ライブラリは、別のデータフア
イルとして、データベース30のようなデータベース、ま
たはサーバー・モジュールかステーション・モジュール
に格納しておくことができる。特徴ライブラリは、基本
的または基礎的な部品の形状(たとえば4折り曲げ箱、
橋梁等)に対応するまたは定義する特徴抽出データを含
む所定の行列よりなる。各所定特徴ベース行列は、特徴
ベース部品行列とともに、ASCIIまたはテキストフアイ
ルとして格納できる。ステップS.104のおける比較は、
ステップS.106に図示されているように、薄板金属部品
に存在する基本的または基礎的な形状/特徴を決めるた
めに行われる。格納されたルックアップテーブルを、ど
の基礎的な形状が各所定特徴行列に対応するかを示すた
めにを備えておくことができる。一致するものが見いだ
されると、ステップS.106でどの基礎的形状が存在する
かを決めるために、ルックアップテーブルがアクセスさ
れる。事前定義ライブラリに存在する一致する行列は、
特徴ベース部品行列と同じ次数であるか(この場合は部
品はただ一つの基礎的形状を含み、精確に対応すること
が決定される)、または部品行列のサブ行列かもしれな
い(この場合は部品は一つ以上の基礎的形状を含むかも
しれない)。
【0177】特徴ベース部品行列を事前定義ライブラリ
にある行列と比較するために再帰プログラミング技法を
利用することができる。含まれている情報を比較すると
き、行列の指標を入れ替えることによって、データ割り
当ての使用が避けられ、必要なプロセス時間が短縮され
る。再帰プログラミング技法と指標の入れ替えはまた、
異なる次数と異なる基底面をもつ行列の比較を容易にす
る。
【0178】本発明の見地に沿って、ステップS.104で
実施される比較操作は、一連の比較よりなり、最初によ
り複雑な形状(たとえば多数の曲げ、またはタブのよう
な複雑な成形を含む形状)に関する行列の比較から開始
し、より複雑でない形状(たとえば、より少ない曲げ、
またはより複雑でない曲げ、より少ない数の面をもつ形
状)へと進む。この一連の比較は部品に、所定数の基本
的形状が見いだされるまで行われる。たとえば、比較操
作はある特定の部品の三つの最も複雑な特徴または形状
を抽出するために行うことができる。さらに、この操作
を最初に、薄板金属部品によく、または度々みられる形
状に関する行列のグループに対する一連の比較から始
め、次により一般的でない形状に進むこともできる。部
品を事前定義ライブラリと比較するために、色々な方法
を有用な結果をうるために行うことができる。
【0179】たとえば、一連の比較操作を先ず、多数の
直角曲げを持つ長方形や正方形形状や直角曲げをもつ単
純な部品のような、直角曲げをもつ基本形状を含む行列
の直角グループに適用することができる。この行列のグ
ループは、グループの中の、より複雑な行列(たとえ
ば、タブをもつ四つ折り曲げ箱に対応する行列)からグ
ループの中のより単純な行列(たとえば、単純ハット部
品に関する行列)へと進める一連の比較にもとづいて探
索することができる。それから一連の比較を多角形部品
グループの行列に、さらに特別特徴グループの行列へ適
用することができる。多角形部品グループは五つ以上の
側面と、少なくとも90度以上の曲げを一つもつ部品を定
める行列を含みうる。特別特徴グループの行列は、Zー
曲げまたは縁取り曲げのような、特別な特徴または成形
をもつ部品に関係する事前定義ライブラリ内の行列を含
みうる。ここでもまた、部品の特徴ベース行列と各グル
ープの所定行列との間の一連の比較は、複雑性の度合い
の減少に従って行われる。この後に、部品の一つの面に
二つまたは二つ以上の特徴をもつ多重特徴グループのよ
うな、所定行列の他のグループを比較することができ
る。
【0180】複雑性の度合いに従って部品を事前定義ラ
イブラリの行列と比較し、実現と使用頻度にもとづく行
列のグループの一連の比較をすることによって、部品に
存在する基本的な形状の決定するためのライブラリとの
より効果的で有効な比較ができる。さらに、検出特徴の
重複が防がれ、より複雑な形状のみが識別される。
【0181】ステップS,108では、部品にある基本的な
特徴または形状間の関係を決めるために特徴関係操作を
行う。特徴または形状間の関係は距離によって定められ
る。二つの形状間の距離は、各々形状の基底面(基本
面)の間の曲げ線または面の数にもとづいて決められ
る。あるいは、特徴間の関係は、部品及び、各特徴の基
底面の相対位置と間隔を幾何学的に解析することによ
り、特徴間の物理的な距離または実際の寸法によって定
めることができる。
【0182】例示のため、ステップS.106で決定した部
品の三つの最も複雑な特徴または形状は、図10(a)
に示す4折り曲げ箱と、ブリッジと、もう一つの4折り曲
げ箱とであるとしよう。このような部品については、特
徴関係操作を、たとえば各基本的特徴の基底表面または
面の間の曲げ線の数を決めるために行うことができる。
図10(b)で示すように、第一の4折り曲げ箱の基底
(1)とブリッジの基底(2)の間の特徴関係は、二つの
曲げ線の間隔である。さらに、第一の4折り曲げ箱の基
底(1)と第二の4折り曲げ箱の基底(3)の間の関係
は、四つの曲げ線の間隔であり、ブリッジの基底(2)
と第二の4折り曲げ箱の基底(3)の間の関係は、二つの
曲げ線の間隔である。
【0183】いろいろなプロセスによって、部品の基本
形状の基底面間の曲げ線の数を決めることができる。た
とえば、特徴ベース部品行列と所定形状行列を利用し
て、ステップS.108で特徴関係を決めることができる。
最初に、部品行列にある各基本形状に対応する基底面を
捜し出す。これは所定形状行列の基底面を、部品行列の
面指標と相関することによって行うことができる。前に
論じたように、比較操作で切り離した所定形状行列は、
部品行列のサブ行列かもしれない。部品行列で各基本形
状に対応する基底面を捜し出すには、部品行列内の形状
行列の位置と行列の指標の間の相関を解析する。各基本
形状の基底面は、予め定められており形状行列の第1列
に位置しているので、部品行列内の対応する位置と基底
面を捜しだすことができる。
【0184】特徴ベース部品行列内の各基本形状の基底
面を決定した後、特徴関係を決めるために、各形状の基
底面間の距離を解析する。この解析は、如何なる二つの
基底面間の距離をも同定する探索プロセスを含んでい
る。部品行列内の特徴と曲げ線情報を見ることによっ
て、どの二つの基底面間の曲げ線の数でも決定できる。
二つの面の間に一つ以上の経路が可能な場合には、最小
距離を用いてステップS.108において特徴関係を定義す
ることができる。
【0185】特徴関係操作を終えた後の論理の流れはス
テップS.110に続く。図7に示すように、ステップS.110
では、データベースの類似部品探索に用いる探索キーを
決めるために、データベース探索キーの同定が行われ
る。探索キーは、部品に同定された特徴や特徴関係の幾
通りもの組み合わせを含みうる。さらに、探索キーをア
センブルするのに、どのような基準の階層も用いること
ができる。限定されない例として、下記の基準に従って
探索キーを作成することができる:(i)部品に同定さ
れた一番目と二番目に複雑な特徴または形状;(ii)最
も複雑な二つの特徴間の距離または特徴関係;(iii)
部品に同定された三番目に複雑な特徴または形状;及び
(iv)部品に同定された一番目に複雑な特徴と三番目に
複雑な特徴間の特徴関係または距離、及び二番目に複雑
な特徴と三番目に複雑な特徴間の距離または特徴関係。
図10(c)に図10(a)の例にもとづいて開発され
た探索キーを示す。
【0186】データベースの探索を容易にするために、
探索キーは、形状ライブラリで定義された色々な基本形
状に割り当てられた所定コードをもつ整数の列で表すこ
とができる。たとえば、4折り曲げ箱に整数コード”1
6”が割り当てられ、ブリッジに整数コード”32”が割
り当てられたとしよう。この場合、図10(c)の例の
探索キーは、整数列”16,16,4,32,2,2”で表され、この
なかで”4”と”2”は基本形状または特徴間の色々な距
離を表す。しかしながら、探索キーの表示は、整数列に
限定されるものではなく、どのような組み合わせの整数
及び/または文字列を探索キーの表示に用いることがで
きる。
【0187】各部品の探索キーは、仕事情報とともに
(別のフアイルまたは同じフアイルに)、データべー
ス、たとえばデータベース30、に格納できる。特徴抽出
データの代表的な探索キーは、手動で入力するか、上記
のように自動的に作成できる。特徴ベース部品行列のよ
うな付加的特徴抽出データは、探索キーを用いて格納で
きる。探索キーが別のフアイルに格納してあるときに
は、各探索キーのセットと関連する部品情報を捜し出す
ための参照用テーブルを用意できる。あるいは、探索キ
ーは部品情報を同定する(たとえば部品または参照番号
によって)データフイールドとともに格納しておくこと
ができる。
【0188】ステップS.112では、同定された探索キー
にもとづくデータベースの協調探索が行われる。協調探
索は、協調データベース探索技法を用いる探索である。
協調探索技法は、同一の探索キーをもつ部品ばかりでな
く、類似の探索キーを持つ部品を捜し出す。これによっ
てデータベースにある、類似および同一部品を同定する
ことができる。特定の部品についての探索を行うと、そ
の部品のものと同定された探索キーを、データベースに
ある他の探索キーデータと比較することができる。ステ
ップS.112で行われる協調探索は、探索キーの順序を緩
めるか修正することによって、データベースにある項目
で、探索キーによって同定された特定の部品と正確に一
致するか又は最も類似している項目を同定するように構
成される。色々なプロセスと方法を、協調探索において
探索キーを適合させるのに用いることができる。たとえ
ば、最初にデータベースの探索を、探索する部品のもの
と同定されたものと正確に一致する探索キーの順序をも
つ部品を同定するために行うとする。これは同定された
探索キーをデータベースに格納されている探索キーと比
較することによって行われる。同じ探索キーをもつ部品
(もしあれば)を同定した後、引き続き他の類似部品を
捜しだすために、異なる修正された探索キー順序に基づ
くデータベースの探索を行うことができる。最初探索キ
ーにある、あまり重要または敏感でない項目または基準
(特徴関係または距離のような)は、より重要または敏
感な探索項目(部品にある基本的な特徴または形状のよ
うな)を修正する前に修正し、探索することができる。
さらに、これらの各項目は、項目の重要度に従って修正
し、部品にある一番目と二番目に複雑な特徴または形状
に関連する項目に、より高い重みまたは重要度を当てる
ことができる。たとえば、ひき続き最初に行う探索は、
三番目に複雑な特徴と一番目、二番目に複雑な特徴間の
定義された距離を修正した後に行うことができる。この
距離は、所定曲げ線数(たとえば1ー3)だけ変更し又は
現在の距離に基づいた距離の所定範囲を定義することに
よって修正できる。しかる後、一番目と二番目に複雑な
特徴または形状間の距離を変更して、データベース探索
用の修正された探索キーの組をもう一つ備えることがで
きる。部品の特徴関係または距離の探索キーを修正した
後、同定された形状を、協調探索における付加的な修正
探索キーを導くために変えることができる。たとえば、
三番目に複雑な特徴または形状に関する探索キー項目
を、現在扱っているものの特徴または形状によって、関
連するがより複雑でない形状に変えることができる(た
とえばタブのある4折り曲げ箱を単純な4折り曲げ箱
に)。さらに、一番目と二番目に複雑な特徴の探索キー
を同じように変えることによって、さらに協調探索のた
めの修正探索キーを加えることができる。
【0189】探索キーに関係する距離と特徴/形状の、
協調探索中の修正は、いろいろな方法と技法によって実
行できる。上記のように、どのくらい距離を変えるか
は、距離の現在値に依存する。距離の大きさ(たとえば
4曲げ線)を、探索を拡張し、より協調的にするために
距離の範囲(たとえば3ー5)で修正することができる。
特徴または形状についても、類似部品を同定するために
探索キーを修正できる。特徴または形状は、特徴タイプ
の階層構造を通して修正できる。たとえば、現在扱って
いる特徴タイプ(たとえば4折り曲げ箱)を、関連し同
じ特徴タイプに属するより複雑でない特徴タイプ(たと
えば3折り曲げ箱)に修正することができる。特徴/形状
を修正するに用いる階層構造は、複数の異なる技法、た
とえば型抽象化階層(TAH)に基づいて事前に定義でき
作成できる。TAHとTAH世代に関する詳しい情報は、たと
えばチューら、ウエスリー、W(CHUWesley W.)による"
型抽象化階層による協調的問い合わせ応答"(Cooperati
ve Query Answering via Type Abstraction Hierarchy)
CSD-900032,1990年10月、カリフォニア大学ロスアンジ
ェレス(University of California,LosAngeles,Octobe
r 1990)および1995年、コンピュータ科学哲学博士の博
士論文、クオーロン・チアング”協調的問い合わせ応答
のための型抽象化階層の自動生成”(CHIANG,Kuorong,A
utomatic Generation of Type Abstraction Hierarch
ies for Cooperative Query Answering )にあり、そこ
に開示されている情報すべてを参照することによってこ
こに取り入れられている。
【0190】協調探索の間に、他のプロセスやステップ
を実施するこができる。たとえば、部品の特徴に関連し
ていると同定された探索キーに基づいたデータベースの
探索に加えて、部品の製造情報に関連した探索基準に基
づいて探索することもできる。たとえば、付加的な探索
キーを利用して、一例として各部品に必要な機械構成を
比較することができる。機械構成情報は機械のタイプま
たは部品を製作するために必要な機械類、部品を製作す
るために用いる工具類や工具構成および/または機械類
のバックゲージング設定を含む。付加的探索キーは、機
械構成情報および/または他の製造情報に基づいて開発
することができ、本発明の協調探索をする際に、同定さ
れた探索キーとともに用いることができる。その結果、
製作される部品と同一または類似な部品は、部品の設計
と製造特徴両方に基づいて同定することができる。
【0191】最も類似した部品を選ぶために、選択部品
探索をステップS.114で実行し、協調探索の結果のより
詳しい比較と、探索された部品と同じまたは最も類似し
ている部品を所定数だけ選ぶ。選択部品探索は、協調探
索で同定された各部品に対する付加的な情報や特性の解
析を伴いうる。これは部品の寸法や部品にある孔や開口
の形のような、捜し出された部品の色々な特徴の解析を
含む。さらに各部品に要する機械構成のような、捜し出
された各部品の製造情報の比較も含みうる。上記のよう
に、機械構成情報は、部品の製作に要する機械の種類ま
たは機械類、部品の製作に用いる工具や工具構成、及び
/または機械類のバックゲージング設定を含む。選択部
品探索を行うために、各部品の曲げモデルや他の仕事情
報が、協調探索で同定された探索キーに基づいてデータ
ベースからアクセスされる。上記のように、各探索キー
の組に対応する仕事参照番号またはコードを提供するた
めに、ルックアップ表や付加的データフイルドを設ける
ことができる。データベースから部品情報を検索した
後、各部品の付加的情報(たとえば部品寸法、材料のタ
イプ、特別な成形、部品の孔または開口等)を、どの部
品が探索された部品に最も類似しているかを決めるため
に解析できる。このプロセスはオプションで、データベ
ースの部品で、当該部品に最も類似の部品を選び集約す
る付加的な選択プロセスの役割を果たす。この部品の付
加的情報または特性を解析し、照合することによって、
選択部品探索を、所定の数または組の最類似部品を同定
または選択するために行うことができる。たとえば、選
択部品探索で、照合探索キーの数と付加的部品特性の照
合に基づいて、五つの最類似部品を同定できる。選択部
品探索で選択される部品の数は五つに限らず、工場の必
要性とデータベースに実際に格納されている部品の数に
基づいて選ぶことができる。この数は、より有効で役立
つ探索結果をうるために選択的に修正でき、またユーザ
ーに探索の組を変えるために、この数を修正する機会を
与えることもできる。
【0192】選択部品探索を行った後、ステップS.116
で部品をランク付けする(特徴の類似性や突き合わせ探
索キーの数に従って)ために、類似性指標を計算するこ
とができる。類似性指標はステップS.116で計算され、
サーバーまたはステーションモジュールの出力として提
供され、これによってユーザーはどの仕事フアイルをデ
ータベースから検索し、画面に映し出すかを選択でき
る。類似性指標によって、選択された部品と探索部品の
特徴の類似性の程度に基づいて、選択部品のランク付け
(たとえば各部品の仕事または参照番号を付してランク
1から5)ができる。このためには各部品の特徴ベース行
列を探索部品のものと比較する。特徴ベース行列の比較
は、選択部品と探索部品の間の類似性をよりよく示す。
前のべたように、特徴ベース部品行列は各部品の探索キ
ーとともに格納できる。しかしながら、各以前の仕事の
特徴ベース部品行列を探索キーとともに永久格納するこ
とは、不必要に大きな記憶スペースを占有する(特にデ
ータベースに多数の部品が格納されている場合)。従っ
て各部品の探索キー・データのみを格納し、類似部品探
索を行うときに自動的に各選択部品の特徴ベース行列を
生成することしかできない。 従って、選択部品の曲げ
モデルと他の仕事情報を検索した後、前にステップS.10
2についてのべたように、特徴ベース行列は本発明の特
徴ベース抽出操作を通じて作成する。そのあとで、類似
部品探索時に一時的に格納した探索部品の特徴ベース行
列を、作成した選択部品の特徴ベース行列の各々と比較
できる。色々な方法とプロセスを、部品の特徴ベース行
列の比較と部品間の類似性の決定に利用できる。たとえ
ば、各選択部品の特徴ベース行列について、行列内の場
所を探索部品のものと比較できる。行列内の各場所は、
再帰的プログラム技法に基づいて比較できる。行列内の
情報は、各行列内の対応する基底面の場所を決め、行列
の指標を交換することによって比較できる。選択部品は
探索部品の副特徴に対応するか又はその形状をもつこと
もあり、又行列の指標が同一でないか、または同じ番号
付けがされていないこともあるので、含まれている情報
を比較するときに、部品行列内で比較できる面を捜しだ
して指標を振り替えなければならない。さらに探索部品
の中に一つ以上の副特徴が存在する場合、行列内の情報
を比較するとき、同じ次数の行列を提供するために、一
つまたは一つ以上の擬似面(行列の行と列で情報が無い
か空白のもの)を導入しなければならないことがある。
【0193】行列の情報を比較するときに、各選択部品
と探索部品の類似性の程度を決めるために、複数の異な
る順序づけ方式を用いることができる。たとえば、所定
ペナルティレベルまたは量を、行列内の整合しない各位
置に割り当てるペナルティベース順序づけ方式を用いる
ことができる。行列内のすべての情報を比較した後、各
選択部品の総ペナルティレベルを用いて類似性の程度を
決めることができる。最も低いペナルティレベルをもつ
選択部品が、探索部品に最も類似した部品と決定され
る。他の選択部品も、各部品に付せられた総ペナルティ
レベルに基づいて順序づけできる(たとえばペナルティ
レベルが低いほど類似指標が高い)。
【0194】本発明のさらなる見地に沿って、各非整合
位置のペナルティレベルは、その位置にある情報のタイ
プに基づいて割り当てることができる。ペナルティレベ
ルは整数量で非整合情報の重大性または重要性に応じて
変えることができる。たとえば、異なる、関係のない特
徴グループ(たとえば平行曲げ特徴対直列曲げ特徴)に
関する非整合位置に対しては、高いペナルティレベルま
たは量を割り当てることができる。これと対照的なの
は、異なるが類似の特徴グループ(たとえば同じ曲げ線
方向をもつ接触コーナー特徴対逆の曲げ線方向をもつ接
触コーナー特徴)である。ペナルティレベルまたは量
は、非整合位置に存在する情報のタイプと相違のタイプ
に従って事前に定義、類別される。
【0195】ステップS.116における類似性指標操作の
典型的なコードは付録Bに示されている。このコードはC
++言語で書かれており、上に記述した行列の比較と非整
合位置に対するペナルティレベルの割り当てに関する色
々なプロセスと操作を含んでいる。上に付記したよう
に、比較された各選択部品の結果としてえられた総ペナ
ルティレベルは、類似性指標を導き、表示するのに用い
ることができる。付録Bにあるコード・リステイングに
は、記されている典型プログラム・コードの理解を助け
るためのコメントも含まれている。
【0196】次に図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モデルを作成するのに利用できる。
【0197】図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によって自動
クリーニングやクリーンアップ機能を実施することもで
きる。
【0198】本発明の自動トリミングとクリーンアップ
機能は、2ーD平面図を、処理に対して準備するために備
えられている。2ーD平面図は、薄板金属部品の展開状態
の2-D表示で、部品の幾何学を構成し表現する線及び曲
線の如き部品要素(エンティティ)を含むとともに、部
品に存在する開口または孔の位置を示す。通常このよう
な2ーD平面図の構成要素(エンティティ)は、CADまたは
CAD/CAMシステムを使用して入力し、作成する。しか
し、2ーD平面図を作成するとき、このような要素はしば
しば誤って連結または重ね合わされ、一つの要素が一つ
以上の面の境界を示すのに用いられることがある。さら
に、部品の境界を決めている外側線が、境界の隣接する
コーナーで分断されていて、部品と各面の外側の寸法の
検出を難しくしている。さらに、2ーD平面図は、寸法情
報やテキストのような本質的でない情報を含みうる。こ
のような異常は、元の2ーD図面を正確に解析し、部品の
面や曲げ線を均一に検出するのを難しくする。本発明の
自動トリミングとクリーンアップ操作を備えることによ
って、各面は連結された要素の一義的なセット(セッ
ト)で表現できる。その結果、2ーD平面図は、引き続き
行われる処理と最終的に行われる3ーDモデル表現作成の
ための折りたたみのために、より簡単かつ効率よく解析
できる。
【0199】図12に示すように、元の2ーD図面では面
間のトリミングがされておらず、図中の一つの線要素が
一つ以上の面の外側境界または複数の境界を定めている
ことがある。上記で論じたように、このような配置は各
々の面の検出を困難にする。本発明の自動トリミング機
能は、連結性情報を決定し、上記のような要素を交点で
断ち切るために、各部品要素(線、弧や曲げ線のよう
な)の終点と交点を解析するのに備えられている。この
ようなトリミング機能は、断ち切られた各要素の終点を
決められた交点に設定する機能ももつ。たとえば、図1
2に図示されている交点をトリミングすることによっ
て、各々が交点に終点を共有する三つの要素(二つの線
と一つの曲げ線)がえられる。このようなトリミング機
能を備えることによって、要素解析と連結に基づいて部
品の面をより容易に検出することができる。実施できる
面検出操作のさらに詳しい記述は、下記に図15(a)
-16(c)を参照しながら提供される。
【0200】色々なプロセスや操作を用いて2ーD図面の
要素の交点を検出することができる。このようなプロセ
スは、2ーD図面のフアイルのデータのフオーマットと配
列に基づいて作成できる。通例2ーD平面図は幾何学デー
タ(色々な部品要素を定義する)と非幾何学データ(た
とえばテキスト等)を含む。幾何学データは、データの
各行またはシーケンスにあるキーワードによって非幾何
学データと区別できる。このようなキーワードは2ーD図
面のデータ書式に従って設定される。2ーD、3-D図面によ
く用いられる書式としてDXFとTGES書式がある。各要素
の幾何学データを解析することによって要素の終点や交
点が検出でき、適当であればトリミングができる。
【0201】上記で論じたように、線、曲げ線や他の要
素は終点及び/またはベクトルで定義できる。たとえば2
ーD平面図では、各2ーD線は2ーD終点の組(たとえばX1,Y1
とX2,Y2)で特定することができ、曲げ線は曲げ線の2ーD
空間位置とともに方向を示すベクトルで表すことができ
る。さらに2ーD弧は2ーD空間データ(たとえば中心X、中
心Y、半径、開始角度、終了角度)で特定することがで
きる。幾何学データはまた、色々なタイプの線要素(た
とえば弧、実線、破線、鎖線等)を区別する属性をも
つ。通常弧要素は薄板金属部品の孔や開口を、実線は部
品の境界や形状を示すのに用いられる。曲げ線は普通破
線で示され、部品の中心線は鎖線で示される。
【0202】元の2ーD図面の幾何学データを解析し、各
要素の交点を決めることができる。データ割り当てやデ
ータ反復のような、色々なデータ解析手法を2ーD図面の
各要素の幾何学データの解析に用いることができる。各
要素の終点及び/または他の2ーD空間データに基づいて、
線や他の要素が交差するかどうかを決める簡単な幾何学
解析をすることができる。二つの要素が交差することが
決まれば、各要素を決定された交点で断ち切り、残った
要素の終点には交点で定められた共有点を割り当てるこ
とができる。
【0203】トリミングの方法は、交差することが検出
された要素のタイプに基づいて行われる。たとえば二つ
の実線が交差することが検出されると、図13(a)に
示すように、各線要素を断ち切ることによって、定めら
れた交点で接する四つの線要素がえられる。また線要素
と弧要素が、図13(b)に示すように交差することが
決まると、各要素を断ち切ることによって共通の終点を
もつ二つの線要素と二つの弧要素をうることができる。
しかしながら、要素の交差が検出されても、トリミング
を必要としないこともある。たとえば、如何なる要素で
も中心線(たとえば鎖線要素)と交差することが決定し
た場合、どの部品の中心線も部品の面または曲げ線を定
めたり区別したりすることはないので、トリミングの必
要はない。また、連結しない要素でも、開いている交点
または面積が、所定の許容度内であれば切断できる。た
とえば、潜在的に交差する線の終点が、実際に他の要素
と交差するときの交点と、事前に定義した許容度または
距離ε(たとえば0.0-0.01mmまたは0.0-0.001インチ)以内
であれば、要素は投影された点で連結交差しているもの
と扱ってよい;そしてたとえば図13(c)に示すよう
に、要素を断ち切ることができる。
【0204】自動トリミングをした後、えられたデータ
を、非連結要素を検出し修正するためにクリーンアップ
機能で処理することができる。しかしながら、本発明は
このような処理のみに限られていない;処理時間を短縮
するためにクリーンアップ機能を、各要素が解析されて
いる間に、自動トリミング機能と同時に行うことができ
る。クリーンアップの間に、2ーD図面の幾何学データ
が、隣接する要素間の開いた交点または領域を検出する
ために解析される。自動トリミング機能と同様に、要素
間の開いた交点の領域を検出するために、各要素の終点
や他の2ーD空間データも解析できる。このようなデータ
に簡単な幾何学的解析を加えることによって、要素の終
点が互いに事前に定義した許容度または距離(0.0-0.01
mmまたは0.0-0.001インチ)内にあるかどうかが決定でき
る。要素の終点がこのような開いた交点をもつことが決
定されると、要素を連結し、図14に示すように共通の
終点を割り当てることができる。
【0205】ここでもまた、クリーンアップ機能をどの
ように行うかは、開いた交点をもつことが検出された要
素のタイプによる。二つの実線が開いた交点をもつこと
が検出された場合、各終点に共通の終点を割り当てるこ
とができる(たとえば図14を見よ)。しかしある要素
が部品の中心線(たとえば鎖線要素)と開いた交点をも
つことが決まったときには、要素を連結したり共通の終
点を割り当るべきでは無く、中心線は無視しなければな
らない。またクリーンアップ機能は、2ーD図面から非幾
何学データ(テキスト等)を消去するための付加的なプ
ロセスまたは操作を含みうる。前述べたように、非幾何
学データは、2ーD図面データとともに用意されているキ
ーワードに基づいて幾何学データと区別できる。クリー
ンアップ機能にはまた、後で本発明の2ーDクリーンアッ
プ機能を参照しながらより詳しく説明するような、他の
クリーンアップ機能を組み込むことができる(たとえば
図21-23(b)を見よ)。
【0206】ステップS.122で自動トリミングとクリー
ンアップ機能を行った後、ステップS.124で処理された2
-D図面について面検出の手続きを行うことができる。本
発明の見地に沿って、面検出手順は要素(線や弧)とル
ープ解析に基づいた部品の面の検出と定義付けを含む。
図15(a)-16(d)に面検出手続きで行われる色
々なプロセスと操作の例を示す。ループ検出技法を本発
明で部品の面を検出し、決定するのに用いることができ
る。面検出手続きは、たとえばサーバー・モジュール32
にあるソフトウエアまたはプログラムされた論理によっ
て実施できる。
【0207】本発明の見地に沿って、部品の外側境界の
ループ検出解析に引き続く、部品の最小または内側ルー
プの解析を用いて、面の各々を検出できる。薄板金属部
品のユニークな幾何学のため、面と部品にある開口は、
相対的極大(たとえば外側)と極小(たとえば内側)ル
ープの順序の解析によって検出することができる。下記
に論じるように、ループ解析は部品の線と弧要素の連結
性にもとづいて行うことができる。ループ解析を部品の
外側から部品の中心に向かって行うことにより、部品の
開口や面を、循環順序(たとえば面材料、開口、面材
料、開口等)に従って定義されたループ間の境界に基づ
いて検出することができる。
【0208】図15(a)に示すような、図示の各面の
各種の線要素を含む2ーD平面図が提供されたとしよう。
上記のように、ループと要素解析は部品の外側から始め
るように行う。部品の外側境界にあるどの要素を初期参
照点にとってもよい。限定されない例として、図15
(b)に示すように、最も左側の線要素を検出し、初期
参照点に用いる。最も左側の線要素は、2ーD図面にある
各要素の幾何学データを比較し、どの要素が最も小さい
X座標の値をもつかを決めることによって検出できる。
最も左側の線要素を検出した後、点P1から部品の外観が
導かれ、図15(c)に示すように部品の外側境界を検
出される。点P1を決めるには、最も左側の線要素のいず
れの終点を用いてもよい。図15(c)に示す実施例で
は、上側の終点(つまり最も大きなY座標の値をもつ終
点)が点P1に用いられている。
【0209】部品の外観、またはまわりのループを導く
のには、通常のループ解析技法を使うことができる。た
とえば、リード線ベクトルを、部品の外観を追ってゆく
に従って、始点P1と連結している要素の終点から投影し
てゆくことができる。一つ一つの要素が検出され、通過
される毎に、要素が選ばれたことを示すフラグを設定す
ることができる(たとえば記憶内のフラグは、一度選ば
れたことを示すために1に設定する)。ループの経路は
始点P1からどちらの方向にも始められる。たとえば、リ
ード線ベクトルを点P1から反時計方向(たとえばリード
線ベクトルをY座標方向に投影する)に投影することが
できる。ループはループ経路が始点(つまり点P1)に戻
ったところで完結する。
【0210】上記のように、始点P1からリード線ベクト
ルを反時計方向に投影できる(たとえば最初のリード線
ベクトルをY座標方向から始めることによって)。引き
続きループの経路にある最初の要素を検出するために、
各未検出要素が点P1 のまわりにリード線ベクトルとな
す角度を座標枠に基づいて測定し、解析してリード線ベ
クトルと最も小さい角度をもつ要素を選ぶ。外側ループ
では、 各角度は要素線がリード線ベクトルとなす外側
角度を測る。点P1の回りの要素は、どの要素が点P1と終
点を共有するかによって決められる。各要素の未選択状
況は、各要素に付したフラグを解析することによって決
定できる。図15(c)に示すように、図示の2ーD図面
例では二つの要素線(X座標方向のものとY座標方向のも
の)がP1のまわりにある。これらの要素の解析では、Y
座標方向の線要素が、リード線ベクトルとなす角度(0
度)が他の線要素がなす角度(270度)より小さいので
選ばれる。
【0211】続いてループ解析は選択された他の線要素
の終点に進み、選択されたことを示すためにフラグが設
定される。その終点で、別のリード線ベクトルが投影さ
れ、その点のまわりの非選択要素を比較することによっ
て、どの要素がリード線ベクトルと最小の角度をもつか
を決める。ここでもまた、角度はリード線の外側から測
り、座標フレームを用いて角度の大きさを決める。弧要
素に出会った場合は、リード線ベクトルの外側から弧の
接線までの角度を測らなければならない。また、次の終
点にある要素が一つのみであれば(部品のコーナー位置
のように)、比較の必要はなく、単にその要素を選択し
てループに含めればよい。
【0212】部品の外観に沿ってループ経路が進むにつ
れ、選択された各要素は、ループ内の要素の連結性を示
すためにリンクされたリストに含めることができる。経
路が始点P1に戻るとサイクルは完了し、外観と、部品の
外側境界を示す要素または線のリンクされたリストに基
づいてループを(L4)と定義できる。ループL4内の各線
または要素は、各終点で連結できる。ループL4の方向
を、外側ループであることを示すために、図15(d)
に示すように、反対方向(つまり時計方向)に変えるこ
とができ。ループの方向は、ループL4で線がリンクされ
る順序に基づいて定義することができる;従って方向
を、リンクされたリストの順序を逆にすることによって
変えることができる。
【0213】外側ループの完了後、外側ループ解析に用
いたのと類似のプロセスで部品の内側ループの解析を行
うことができる。ただ内側ループの解析では、各非選択
要素は各要素がリード線ベクトルの内側となす角度に基
づいて比較される。さらに、内側ループ解析では、ある
点のまわりの両方の要素がすでに選択されていると示さ
れた場合(たとえば面を境する二つの外側線要素を比較
するとき)でも、二つの要素が既に二度選択(2のフラ
ッグ設定)されてない限り、二つの要素を比較すること
ができる。少なくとも一度選択された要素(たとえば外
側要素)と選択されていない要素の場合は比較は行わ
ず、非選択要素をループの一部分として選択する。図1
6(a)-16(c)に、図15(a)に示す部品の面
を検出し、規定するのに行うことができる内側ループが
例示してある。
【0214】内側ループ解析は、どの外側要素の終点か
らでも、あるいは選択されていない要素を検出すること
によって開始することができる。たとえば点P1を、内側
ループ解析の始点に選び、リード線ベクトルを投影する
のに用いることができる;あるいは外側ループ解析の際
に選ばなかった内側の線要素の一つも解析の始点に用い
ることができる。外側ループ解析と同じように、リード
線ベクトルを反時計方向(たとえば一番目のリード線ベ
クトルをY座標方向から始める)に延ばしてゆくことが
できる。次いで点P1のまわりの各要素を比較し、どの要
素がリード線ベクトルと最小の角度をもつかを決める。
リード線ベクトルとなす角度を決めるのに、座標枠を用
いることができる。前記のように、内側ループ解析に際
には、要素の比較は各要素がリード線ベクトルの外側で
なく、内側となす角度をもとに行う。最初の要素が選ば
れ、ループのリンクされたリストに含めたら、そのフラ
グを1だけ増分し、つぎのリード線ベクトルを投影する
ことによって解析を進めることができる。このプロセス
はループが最初の始点に戻るまで続けられ、そこで第一
の内側ループが、対応する要素のリンクされたリストに
よって定義(たとえばL1)される。
【0215】さらに部品の内部に進んで、同じように内
側ループ解析を行うことができる。次の始点は、どの要
素が一度しか選ばれていないかを決めることによって選
ぶことができる。二度選ばれたフラグをもつ要素は、そ
の要素がすでに外側ループ(たとえばL4)と少なくとも
内側ループの一つ(たとえばL1)で選ばれた外側要素で
あることを示す。ここでもまた、各要素が選ばれるたび
に、それが内側ループのリンク・リストに含まれたこと
を示すために、フラグを1だけ増分する。
【0216】すべての内側ループが定められた後(たと
えば図16(c)の例ですべての要素が二度選ばれた
後)、えられたループを用いてループツリー(ループ
木)を作成することができる。図16(d)に、検出さ
れたループL1-L4に基づいて作成したループツリーの例
を示す。部品の外側ループ(L4)はツリーの根(ルー
ツ)と定義し、外側ループと共通の要素をもつ各内側ル
ープ(L1ーL3)は、根の子どもと定義されている。共通
要素の存在は、各ループを規定する要素のリンクされた
リストの解析と比較によって検出できる。内側ループ内
に、さらに要素(たとえば孔または開口)が検出された
場合には、これらのループを、それが位置する内側ルー
プの子ども(つまりループツリーの根の孫)と定義する
ことができる。
【0217】ステップS.124で面検出手続きを行った
後、ステップS.126で曲げ線検出操作を行うことができ
る。たとえば図17に示すように、ステップS.124で部
品のループを検出し解析するときに、本発明の面検出論
理は、面情報を規定し、検出された面を曲げグラフ・デ
ータ構造にノードとして格納するのに、ループツリーを
利用することができる。部品の面は、ループツリーにお
ける外側と内側ループの順序から検出できる。上記のよ
うに、各ループは要素または線のリンクされたリストを
含む。これらの要素は、部品の各面の境界を定めるのに
用いられる。従ってステップS.126において曲げ線検出
操作を行い、部品の面と曲げ線の間の関係を決めること
ができる。ステップS.126の曲げ線検出操作は、ある二
つの隣接する面が共有する端または線要素を検出するこ
とによって、部品の色々な面間のすべての曲げ線を検出
する曲げ線検出論理を含むことができる。また一つ以上
の領域で接続している面(たとえば3ーDモデルに曲げ線
検出アルゴリズムを適用する場合ーたとえば下記に論ず
る図19を見よ)については、いろいろな発見的方法
(ヒューリスティク)を適用して、部品の曲げ線の最小
数を検出し、選択することができる。検出された曲げ線
は、たとえば図18に示すように、最終的な曲げグラフ
・データ構造を作成するための、面の節(ノード)の間
の連結エージェントとして格納しておこことができる。
【0218】本発明の曲げ線検出操作は、たとえばサー
バー・モジュール32に備えたソフトウエアまたはプログ
ラムされた論理によって実施できる。曲げ線検出操作の
目的は、部品が最も少ない数の曲げ線で連結されるよう
に、部品の曲げ線を検出し、選択することにある。曲げ
線検出操作は、部品の2ーDと3-Dバージョン両方に備える
ことができる。原3ーDモデルについての曲げ線検出の適
用は、下記に図19を参照しながら論ずる。上記のよう
に、検出された曲げ線は、最終的な曲げグラフ・データ
構造を作成するための面の節の間の連結エージェントと
して格納できる。この最終的曲げグラフ・データ構造
は、2ーDデータ・モデルから折りたたんで部品の3-Dバー
ジョンを作成するのに利用できる。
【0219】図11のステップS.120で入力として提供
された2ーD図面は、曲げ線情報を含まないか、曲げ線情
報が不明確で、一義的にまたは矛盾なく定義されていな
いことがある。その場合、曲げ線検出操作を、曲げ線を
検出し、部品の検出された面との関係を検出するために
行うことができる。このプロセスの間に、各面を定義す
る要素(エンティティ)のリンクされたリストを解析
し、各面が部品の他の面と共にもつ隣接する端または線
要素を決めることができる。これはある与えられた二つ
の面の間の可能なすべての接触を解析することによって
行うことができる。接触は、長さが0以上の(つまり線
要素が点ではなく、実際の線である)、共通する線要素
(またはお互いに事前に定めた距離許容度にある複数の
線要素)の存在によって決定できる。リンクされたリス
トにある幾何学データを解析することによって、部品の
すべての二つの面間のこのような接触の存在を決めるこ
とができる。
【0220】ある特定の面が、他の面と共通の端または
接触領域を一つしかもっていない場合、両方の面に共通
の要素は曲げ線であると定義することができる。一つ以
上の領域で共通接触を持つ複数の面(たとえば3ーDモデ
ル;ただし2ーDモデルでも起こりうる)については、色
々な発見的方法(ヒューリスティック)を用いて部品の
最小数の曲げ線を検出し、選択することができる。使用
する発見的方法は、複数の面が曲げ線で連結され、複数
の面にわたる連続ループが形成されないようになってい
なければならない(このような曲げ薄板金属部品の製作
は不可能なため)。
【0221】利用できる発見的方法の例として、共通す
る領域で最も長い接触領域をもつものを曲げ線に選ぶ方
法がある。ある面が、他の面と一つ以上の共通端をもっ
ている場合、この発見的方法によって最も長い長さをも
つ共通要素を面の曲げ線に選ぶことができる。この発見
的方法は、曲げ薄板金属部品を製作するときに、通常長
い接触領域を持っている方が良いという原則にもとづい
ている。使用できるもう一つの発見的方法は、異なる可
能な曲げ線の組み合わせ(3ーDモデルの曲げ線を決める
ときのような)に関係する。この発見的方法では、すべ
ての可能な共通領域が検出され、曲げ線の色々な組み合
わせが選択されると、曲げ線の組み合わせで最小の曲げ
線の数をもつ組み合わせが選ばれる。
【0222】曲げ線が検出されると、部品の面と決めら
れた曲げ線は確認のためにオペレータに表示される。オ
ペレータが部品の曲げ線の選択に満足しない場合には、
曲げ線検出操作に手動選択機能を備えることによって、
サーバー・モジュール32でオペレータが選択的に、薄板
金属部品に好ましい曲げ線を指示できるようにすること
ができる。オペレータは、マウスやキーボード等、適当
な入力手段を用いて、曲げ線を保持するか変更するかを
指示することができる。しかる後、オペレータによって
選ばれた修正された曲げ線を用いて、最終的な3ーD(ま
たは2-D)部品を作成することができる。
【0223】本発明の曲げ線検出操作を実施するため
に、色々なプロセスや操作を備えることができる。曲げ
線検出操作を実施するためのコードの例を、付記の付録
Cに与える。例示のコードはC++プログラム言語で書かれ
ており、記述の論理フローの理解を助けるためのコメン
トが含まれている。例示コードは、2ーDまたは3-Dモデル
について行うことができる曲げ線検出操作の実施例で、
曲げ線の最適選択を決める発見的方法(上述のような)
を含む。
【0224】検出された面と曲げ線情報は、本発明の折
りたたみと展開プロセスに利用することができる。折り
たたみまたは展開の際、各曲げ線の回りに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-幅によっ
て、実際の薄板金属部品は薄板金属部品を折りたたむと
きに、差引高だけ引き伸ばされる傾向がある。
【0225】前記モデルでこの効果を補償するために、
差引高情報を利用して、折りたたみ操作で3ーDモデルを
作成するときに、曲げ線の各側で部品の面の寸法を差引
高の半分だけ引き延ばす。本発明の見地に沿って、この
差引高はユーザーによってサーバー・モジュール32に入
力(たとえばキーボード等によって)できる。あるい
は、部品の材料のタイプと厚さにもとづいた差引高を含
む材料表をオペレータに表示することができる。材料表
は、異なる曲げ角度やVー幅に対する色々な差引高を示
す。ユーザーは、サーバー・モジュール32で表示された
材料表から適切なVー幅と曲げ角度を選ぶ(たとえばマ
ウスまたはキーボードを用いて)ことによって、自動的
に差引高をセットすることができる。曲げ角度の内側半
径も、適切なVー幅を選ぶときに、材料表を介してユー
ザーによって自動的にセットできる。
【0226】オペレータが入力する(あるいはオペレー
タによる入力後に変換される)差引高は、部品幾何学デ
ータを表すものと同じ長さの単位(たとえばmm)であ
る。折りたたみ操作時に、曲げ線の各側の各面の長さ寸
法を、注目している曲げ線の差引高の半量だけ増やす。
面の曲げ線に垂直な長さ寸法は、曲げ線の各側にある面
の境界を定める要素の終点を引き伸ばすことによって増
やすことができる。このような差引高補償は、各折り曲
げについてオペレータによって供給された差引高にもと
づいて、部品の他の曲げ線の各々について行うことがで
きる。
【0227】ステップS.132では、加工された2ーD平面図
にもとづいて、3-Dモデルを作成するための、差引高補
償を含めた折りたたみ操作が行われる。前記のように、
折りたたみ手続きは、行列変換の使用と最終的曲げグラ
フ・データ構造で定義されたそれぞれの曲げ線を回転軸
に用いることを含む通常の幾何学的模型化法によって遂
行することができる。さらに、差引高の効果を補償する
ために、3ーDモデルを作成する折りたたみの際に、部品
の面を曲げ線の各側で差引高の半量だけ引き伸ばすこと
によって、薄板金属を実際に折り曲げるときの面の寸法
の変化をより正確に反映することができる。
【0228】たとえば、ステップS.132で折りたたみ操
作を行う時に、曲げパラメータ(たとえば曲げ角度、内
側半径)とともに、部品幾何学と形態データ(または曲
げグラフ構造)を利用することができる。2ーD空間で表
わされた部品の各面、曲げ線、孔と成形についての変換
行列を計算できる。通常の行列変換を、2ーD平面図に適
用することによって、3ーD空間データをうることができ
る。変換は一般に回転に続く並進を含む。上記のよう
に、回転は曲げ角度の大きさに従って、各曲げ線軸の回
りに行われる。並進操作は、幾何学データを空間の中で
移したり、動かしたりすることによって行われる。この
ような並進操作は、曲げ半径、曲げ角度と各曲げの差引
高にもとづいて決められる。折りたたみの際に、差引高
補償は前述べたように曲げ線の各側で、面の寸法を差引
高の半量だけ伸ばすか増やすことによって行われる。こ
のような差引高補償は、曲げ機で曲げられる2ーD薄板金
属部品の寸法を、より正確に反映する部品の3ーD表現を
与える。
【0229】幾何学的モデル化と変換のさらに進んだ情
報は、たとえば、その明細を全般的に参照することによ
って本文書に明白に取り入れられているモルテンソン、
マイケル M著、幾何学的モデル化、ジョン・ワイリー&
サンズ、ニューヨーク(1988年)及びフオリーら著、ジ
ェイムス システム・プログラミング・シリーズ:会話
形コンピュータ・グラフイックスの基礎、アデイソン・
ウエスリー出版、レデイング、マセチューセッツ(1983
年)を見られたい。モルテンソンの8章には、並進と回
転を含む幾何学的変換が論じられている(たとえば345ー
354頁参照)。さらにフオリーらは7章、245ー265頁で、2ー
Dと3-D変換の行列表示を含む、幾何学的変換の情報を与
えている。モデル化と幾何学的変換についての付加的情
報は、その明細を全般的に参照することによって本文書
に明白に取り入れられている、マンテイラ、マルッテイ
著、ソリッドモデル化入門、コンピュータ・サイエンス
出版社、ロックビル、メリーランド(1988年)にも与え
られている。座標変換に関する情報は、マンテイラの36
5ー367頁にある。
【0230】次に図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によって、引き続き行われる面検出や他のプ
ロセスのための図面の準備のために、自動トリミングと
クリーンアップ操作が行われる。
【0231】図12-14に関連して論じたように、自
動トリミングとクリーンアップ機能は、部品の色々な面
が適正に検出定義されされるように、構成要素や表面を
切り離したり、連結したりする。
【0232】図11と12、13に関連した上記の自動
トリミングとクリーンアップ操作は、図19のステップ
S.140で入力した3ーD図面の幾何学データに対しても、同
じように適用できる。データを2ーD空間で解析する(2ーD
平面図の場合のように)代わりに、3ーD図面に図示され
ている各構成要素(たとえば線、弧等)は、図中の3ーD
座標と空間情報にもとづいて解析することができる。交
点と開放交差領域は、各構成要素(エンティティ)を個
別的に解析し、他の構成要素の一つ一つと比較すること
によって解析できる。ここでもまた、構成要素の終点や
他の属性の基本的な幾何学的解析を用いて、許容度内で
交点と開放交差領域を決めることができる。
【0233】前記3次元図面に対しての自動トリミング
及びクリーンアップ機能を実行した後、ステップS14
4で、前記板金パーツの面の各々を検出し定義するため
に面検出操作が行なわれる。前記3次元図面についての
面検出は2次元空間における各面を分析し且つ検出し且
つ上記と同様にしてループツリーを生成することにより
行なわれる。面検出は任意の所定のエンティティで開始
することにより実行される。例えば、一番左側のエンテ
ィティ(即ち最小のx座標を有するエンティティ)が最
初のエンティティとして使用される。その後、1つの面
は前記最初の線分エンティティ及び他の連結するまたは
隣接する線エンティティ(即ち前記最初のエンティティ
と共通の端点を有する任意のエンティティ)を取出すこ
とにより定義される。面検出操作は次に、図15(a)
−16(d)に関連して上記に説明したようにループ及
びエンティティ解析を用いて行なわれる。各エンティテ
ィは前記定義された2次元平面内で検出されるため、種
々の外側及び内側ループが定義され、且つ前記エンティ
ティがマークされ(即ち前記選択されたエンティティの
フラグを設定し或いは増加することにより)、それら
が、前記面における複数のループの1つを定義する連結
されたリストに選択され且つ含まれたことを示す。
【0234】引き続くループ解析は、次に前記3次元図
面を構成する他の2次元平面において行なわれる。前記
他のエンティティのループ解析を行なうために、前記3
次元図面内でのマークされてない或いは選択されてない
エンティティを検索することにより追加の平面が定義さ
れる。そのような平面は、2つの選択されてないエンテ
ィティの間或いは選択されてないエンティティと以前に
選択されたエンティティとの間に定義される。追加の2
次元平面の各々において、更なるループ解析が行なわれ
前記内側及び外側ループを検出する。再び連結されたエ
ンティティの連結リストが保持され、前記複数のループ
経路の各々が定義されるにつれて、前記選択されたエン
ティティがマークされる(即ち前記選択されたエンティ
ティに付随するフラグを増加することにより)。
【0235】全てのエンティティが検出された後、すで
に解析された2次元平面の各々についてのループツリー
を生成するために、結果の複数のループが使用される。
すでに述べたように、ループツリーは、板金パーツにお
ける複数の面及び開口部及び穴を定義するために提供さ
れる。3次元の図面については、ループツリーは、前記
板金パーツの各面について生成される。各面内で検出さ
れた複数のループは、各ループツリーを生成するために
グループ化され分析される。各ツリーのルーツ(根)は
前記平面において検出された外側ループとして定義され
る。前記外側ループと共通のエンティティを有する前記
平面の各内側ループは前記ツールの子供として定義され
る。共通エンティティの存在は、各ループを定義する連
結されたエンティティのリストの分析及び比較に基づい
て検出される。追加のエンティティ(即ち穴或いは開口
部)が前記平面の内側ループにおいて検出される時、こ
れらのループはそれらがその内部に存在する内側ループ
の子供(即ち前記ループツリーのルーツの孫)として定
義される。生成された複数のループツリーは次に、前記
3次元図面の全ての面を検出するために用いられる。検
出された面は次に曲げグラフデータ構造におけるノード
(節)として格納される。
【0236】前記結果としての曲げグラフ構造はステッ
プS146における曲げ線検出操作の実行の後、連結す
る曲げ線連結エージェントにより補足される。曲げ線検
出操作及び最終曲げグラフ構造またはパーツ・トポロジ
ーの生成は図17及び18を参照して上記したと同様の
やり方で実行される。
【0237】上記したように、前記曲げ線検出操作を実
行するための代表的なコードがここに添付された付録C
に提供される。このサンプルコードは、2次元或いは3
次元モデルに対してなされる曲げ線検出操作のための代
表的実行例であり、曲げ線の最適選択を決定するための
ヒューリスティック(例えば上記したような)を含む。
前記曲げ線検出操作は、検出された曲げ線に満足しない
時、サーバモジュール32におけるオペレータが前記板
金パーツのための好ましい曲げ線を選択的に指定するこ
とを許すマニュアル選択特性を含む。前記オペレータ
は、マウスあるいはキーボード等のごとき適宜の入力手
段により曲げ線を維持し或いは変更することを指示す
る。前記オペレータにより選択され改定された曲げ線は
最終的2次元パーツを生成するために用いられる。
【0238】最終的曲げグラフ構造の複数の曲げ線を中
心とする展開工程を実行する前に、ユーザは、ステップ
S148でV幅、材料タイプ及びまたは縮小量について
促される。上記したように、板金は折り曲げられる時伸
びる傾向を有するため、3次元パーツの寸法は前記2次
元平面パーツのそれより少し大きい。従って、板金パー
ツの展開の過程で、パーツの寸法は、選択された材料タ
イプ及びV幅に基づく縮小量だけ縮み或いは減少され
る。従ってこの発明の1つの側面によれば、3次元モデ
ルを展開する際、前記2次元モデル及びその表面の各々
の寸法をより正確に生成するために縮小操作が行なわれ
る。上記したように、前記縮小量は、前記ユーザにより
直接入力され或いは所望のV幅及び曲げ角度を選択する
ことによりユーザが自動的に前記縮小量を設定すること
ができるように、材料テーブルが表示される。
【0239】前記オペレータにより入力される前記縮小
量は前記パーツ幾何学データにより表現されるそれと同
じ長さの単位(例えばミリメートル)である(或いはオ
ペレータによる入力の後その単位に変換される)。展開
操作の間に、前記曲げ線の両側の面の各々の寸法長さは
前記所定の曲げ線について入力された縮小量の半分だけ
減少される。前記曲げ線に直交する前記面の寸法長さは
前記曲げ線の両側に位置する前記面の境界を定義するエ
ンティティの終点を減少することにより減少される。前
記縮小補償は、各曲げについて前記オペレータにより提
供される前記縮小量に基づいて、前記パーツの他の曲げ
線のそれぞれにおいて行なわれる。
【0240】前記全ての必要なデータの入力の後、ステ
ップS150で、前記2次元モデルを生成するために展
開プロセスが行なわれる。前記3次元曲げモデルを展開
するために通常の方法が用いられ、それは前記複数の曲
げ線の各々を回転軸として用いるマトリックス変換の使
用を含む。この展開プロセスの間に各曲げ角度が測定さ
れ、前記平面曲げモデルを生成するために前記曲げ角度
量だけ前記パーツは展開される。更に、前記入力された
縮小量に基づいて、前記板金材料の物理的性質及び前記
3次元及び2次元モデルの間の差をより正確にシミュレ
ートするために、前記曲げ線の両側で前記縮小量の半分
だけの前記面の寸法の縮小或いは減少が行なわれる。
【0241】ステップS150で前記展開工程を実行す
る時、前記パーツの寸法及びトポロジーデータ(または
曲げグラフ構造)が前記曲げパラメータ(例えば曲げ角
度、内側半径等)と共に用いられる。前記3次元空間に
おいて表現された前記パーツにおける各面及び曲げ線及
び穴及び成形部についての変換マトリックスが計算され
る。通常のマトリックス変換が前記2次元空間データを
得るために前記3次元データに対して適用される。前記
変換は一般的に回転を含み、その後に並進がくる。上記
したように、回転は、曲げ角度量に応じて各曲げ線の周
りに行なわれる。展開のために、2つの面の間に180
°が存在するまで(即ち面が平面になるまで)回転は逆
方向に行なわれる。並進は空間内で前記幾何学的データ
をシフトし移動するために行なわれる。そのような並進
は、各曲げについての前記曲げ半径及び曲げ角度及び縮
小量に基づいて決定される。展開の間、縮小補償は上記
したように、曲げ線の両側で前記縮小量の半分だけ前記
複数の面の寸法を縮め或いは減少せしめるために行なわ
れる。そのような縮小補償はそれが曲げ工程の間に折り
曲げられる前の前記板金パーツの寸法をより正確に反映
する前記パーツの2次元表示を提供する。
【0242】再び幾何学的モデル化及び変換についての
情報はモルテンソン、フォリー等及びマンティラに見出
される。上記したように、モルテンソンの8章は変換及
び回転(例えば345〜354頁を見よ)を含む幾何学
的変換の議論を提供する。更にフォリー等は、7章の2
45〜265頁で2次元及び3次元変換のマトリックス
表示を含む幾何学的変換についての情報を提供する。更
に座標変換についての情報はマンティラの365頁〜3
67頁に見出される。
【0243】図4を参照して上記したように、前記顧客
の注文に基づいて、2次元3面図或いは厚さを有しない
3次元ワイヤフレーム図が最初に提供され或いは生成さ
れる場合、厚さを有しない3次元モデルを生成するため
に更なる工程が必要とされる。そしてその後、前記厚さ
を有しない生成された3次元モデルは展開プロセス或い
はアルゴリズムを適用することにより2次元モデルを生
成するために用いられる。図20−24は、最初の2次
元3面図に基づいて3次元モデルを生成するために適用
される種々のプロセス或いは操作を図示する。更に図2
5は、この発明の他の側面に応じて、厚さを有する最初
の3次元ワイヤフレーム図から厚さを有しない3次元モ
デルを生成するために適用される追加のプロセス或いは
操作を図示する。再び、図20−25において図示され
る種々のプロセス及び操作は、例えば前記サーバモジュ
ール32に存在するソフトウエア及びまたはプログラム
論理により実行される。
【0244】図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により前記クリーンアップ操作が行なわれる
際実行される種々のプロセスの論理フローの例を図示す
る。
【0245】図21に示されるように、最初に2次元図
面が前記サーバモジュール32により、ステップS18
0でデータファイルから読み取られ或いはロードされ
る。しかる後ステップS182でサーバモジュールは、
2次元図面において各々のエンティティ或いは幾何学デ
ータを分析し次の工程のための図面を作成するために種
々のエンティティを分割する。ステップS182におい
て行なわれる前記分割或いはトリミング機能は、この発
明の前記自動トリミング及びクリーンアップ機能に関連
して上記に記載したと同様な方法で実行される。従って
ステップS182で前記2次元3面図における全ての幾
何学的データは、エンティティの交差点及び所定の誤差
範囲内にある空白(開放)交差部を検出するために分析
される。任意の交差線は分断され、結果のエンティティ
は交差点により定義される共通の終点で出会う。更に所
定の誤差の範囲内にある(例えば0.0−0.01mm
或いは0.0−0.001インチ)空白交差領域を有す
るエンティティについてはそれらのエンティティは、例
えば図12―14に関連して上で記載されたと同様の方
法で結合される。
【0246】ステップS184で前記2次元図面シート
の周辺が検索され任意の外部の線分またはデータ(例え
ば境界線分及び座標格子及び数字等)が消去される。図
22(a)に示されるように2次元3面図は、しばしば
図面シート上に提供される。前記図面シートは前記板金
パーツの種々の図面を生成するために必要でない余分な
及び非幾何学的な情報を含む。従ってステップS184
で、本発明の2次元クリーンアッププロセスを利用し
て、前記3次元モデルを展開するにあたってこのタイプ
の情報が検出され前記2次元図面から消去される。
【0247】前記2次元図面データはそこに含まれるデ
ータのタイプ(例えば幾何学的或いは非幾何学的/テキ
スト)を指示するためのキーワード或いはタイプフィー
ルドを含む。従ってこれらのキーワードあるいはタイプ
フィールド(それらは図面ファイルのデータフォーマッ
トに基づいて提供される)はテキスト或いは他の非幾何
学的データのごとき種々の余分の情報を削除するために
用いられる。しかし全ての不必要な図面シートデータを
正しく削除するためには更なる操作が通常必要である。
しばしば、前記境界線或いは他の外側情報はエンティテ
ィー(例えば線分等)として保存され、それらは前記デ
ータキーワード或いはタイプフィールドに基づいて容易
に識別することができない。従ってこの発明の1つの側
面によれば、前記2次元図面のデータを分析する際に連
結性グラフ構造が生成される。この連結性グラフ構造は
各エンティティーについて複数の付随的頂点のリスト及
び連結されたエンティティーのリストを示す。各頂点に
ついては、隣接する複数の頂点のリスト及びそれが付随
するところのエンティティーのリストが提供される。こ
のグラフ構造により、(それはステップS182の分断
及びトリミング機能を実行する際に生成されるが)、ど
のエンティティーがくっつき合う終点により結合される
かが決定される。結果として、境界線及び情報ボックス
及び他の非幾何学的データのような余分なデータは削除
される。これは、このデータは典型的に連結されたエン
ティティーで構成されることがなくまたそれを含まない
からである。
【0248】上記したように、2次元3面図は寸法線及
び矢印線及び中心線及びテキストのような余分の情報を
含み、それらは前記パーツの実際の幾何学形状を表現し
ない。これらのエンティティーはステップS186で検
出され、次の工程のための2次元図面を作成するために
前記2次元データファイルから削除される。これらの余
分のエンティティーの検出はサーバモジュール32によ
り自動的に行なわれる(例えば前記パーツの実際の幾何
学形状に関連しない2次元データファイル中の項目を検
出することにより)。例えば、前記連結性データグラフ
構造を用いて、両端が開放されたエンティティー(例え
ばテキストにアンダーラインをするため或いは寸法或い
はパーツの中心線を示すために用いられる複数の線)が
検出され消去される。矢印のごとき他のエンティティー
もまた、浮動する終点或いはそのようなエンティティー
の他の特徴の存在に基づいて検出される。全ての不必要
なデータを効果的に削除するために、サーバモジュール
32は前記2次元図面中のいずれの項目が消去されるべ
きかを(例えばマウスまたはキーボードにより)オペレ
ータをして指示することができるようにするためのマニ
ュアル編集機能を提供する。オペレータのこの援助或い
は確認により、追加の余分の情報が図面から除去され
る。
【0249】ステップS186の後、前記2次元図面の
種々の図が、ステップS188でグループ化され且つそ
れぞれ定義される。この発明の1つの側面によれば、サ
ーバモジュール32は、図22(b)及び23(a)に
示されるような平面図(上面図)及び正面図、右側面の
配置のごとき、予め定められた或いは標準的な図と向き
をサポートする。平面図及び正面或いは背面図及び右或
いは左図のような他の図及びレイアウトもまたサポート
され得る。更に以下に記載されるように、サーバモジュ
ール32はまた前記2次元図面の図を前記パーツの3次
元表現へ加工するために、回転された図(例えば図23
(a)を見よ)もサポートする。いずれにしても、パー
ツの3次元モデルが構成されるためには、厚さ表現を有
するパーツの少なくとも2つ(そして好ましくは3つ)
の異なる図が提供される必要がある。連結性グラフ構造
において前記エンティティーの連結性及びグループ化を
解析することにより、サーバモジュール32は、複数の
図の各々の相対的位置及び/又は座標位置に基づいて前
記複数の図を分類し且つ定義する。
【0250】限定しない事例として、サーバモジュール
32による前記図の定義は、予め定義された或いは通常
の配置或いは前記データファイルにおける図の解析をす
るためのレイアウトにより、及び/又は前記複数の図の
向きの検出及び前記図面の各々の図のそれぞれにおける
前記パーツの種々の寸法の重ね合わせに基づいて実行さ
れる。図23(b)において示されるそれのごとき予め
定義された或いは標準的フォームは、潜在的な図のタイ
プに応じて前記図の各々を決定し定義するために用いら
れる。種々の終点及び各グループを定義する複数のエン
ティティーの間の関係の幾何学的比較は、前記ステップ
S188を実行するために行なわれる。サーバモジュー
ル32の図検出特性(図検出機能)は、複数の潜在的図
面タイプ(例えば平面図、正面図、背面図、左図、右
図)の1つに応じて前記図面の各々にラベルを付ける。
前記複数の図の各々の検出は、予め定義された或いは標
準的図の配置或いは形状及び存在する図の各々の間の検
出された関係に基づく。種々の工程或いは操作が、ステ
ップS188で、前記2次元3面図における複数の図を
分類し且つ定義するために使用される。例えば前記加工
された2次元3面図にアクセスした後、前記サーバモジ
ュール32はまずこの図面データにおけるパーツの平面
図を特定する。前記平面図は、予め定義された或いは標
準的な形状または図配置(例えば図23(b)における
それのような)に基づいて検出される。仮に3つの異な
る図が水平方向或いは垂直方向において検出される場合
には、中央の図が平面図であると定義される。更に仮に
3つの別個の図が検出されず且つ垂直方向においてただ
2つの別個の図が検出される場合には、上側の図が平面
図であると定義される。再び前記連結性グラフ構造にお
ける前記エンティティーの連結性及びグループ化が前記
複数の図の各々を検出するために使用される。前記予め
定義された或いは標準的形態を表現する、格納されたル
ックアップテーブル或いはマトリックスが前記2次元図
面の各図を比較し且つ複数の図の各々を検出するために
用いられる。
【0251】前記2次元3面図データから平面図を検出
した後、前記パーツの他の図は前記検出された平面図に
対する前記複数の図の各々の相対的位置に基づいて検出
される。例えば、図23(b)の標準的レイアウトに基
づいて、例えば図グループが前記平面図の上に位置して
いる場合には、その図は背面図であると定義される。し
かしもし図グループが前記平面図の下に位置している場
合には、その図は前記パーツの正面図であると定義され
る。更に右図及び左図は、前記平面図のそれぞれ対応す
る右側及び左側におけるそれらの相対的位置に基づいて
検出される。しかる後、前記標準的形態(例えば図23
(b))に合致しない任意の残りの図は前記検出された
図(例えば検出された背面図或いは正面図)に対するそ
れらの相対的位置に基づいて検出される。例えば図23
(a)に示されるレイアウトBについて、前記右図は前
記平面図に対して回転された位置に設けてある。しかし
ながらレイアウトBにおける右図は前記検出された正面
図に対するその関係に基づいて検出される。即ち検出さ
れた背面図或いは正面図の右側或いは左側に存在する検
出されていない図はそれぞれ前記パーツの右図或いは左
図として定義される。
【0252】種々の予め定義された或いは標準的な図の
レイアウトが前記2次元3面図図面において複数の図を
検出し且つ定義するために用いられる。標準的な形態
(例えば図23(b)または図23(a)におけるそ
れ)は、製造設備において広く行き渡っており或いは選
択され/要求される図レイアウトに基づいて、及び/又
はサポートされている図タイプの基づいて選択される。
仮にいずれの図も検出されない場合には、サーバモジュ
ールにより警告信号が提供され、オペレータは、好まし
い図面レイアウトに応じて前記2次元3面図データを変
形したり、他の適当な動作を行なう。前記2次元図面に
おける複数の図を検出するための予め定められた或いは
標準的形態の提供に加えて、予め定められた標準的形態
(例えば図23(a)のレイアウトAのように)は検出
された図を加工し前記パーツの3次元モデルを生成する
ために設けられる。従って更なる加工が行なわれる前に
前記標準的形態に基づいて検出された図を正しく分類す
るために、回転された図の特徴が提供される。
【0253】上記したように、前記2次元クリーンアッ
プ操作は図面において複数の図を検出するための予め定
められた、或いは標準的形態に合致しない回転された複
数の図をサポートし且つ検出する。回転された図のオプ
ションでは、検出された標準的でない複数の図は、パー
ツの3次元モデルを加工し且つ生成するために、前記複
数の図の各々が前記予め定められた或いは標準的な図の
形態に合致するように、回転され或いは並行移動され
る。前記パーツの複数の図を検出するために図23
(b)に図示されるそれのような標準的形態を仮定し
て、図23(a)におけるレイアウトBにおける複数の
図の各々は、上記したように、前記平面図及び他の検出
された図に対する当該複数の図の相対的な位置に基づい
て検出される。例えば仮に図23(a)のレイアウトA
が、平面図及び正面図及び右図を有する2次元図面にお
ける種々の図を加工するための予め定められた或いは標
準的図レイアウトとして使用される場合、ステップS1
88でレイアウトBにおける右図は90度回転されレイ
アウトAと同様な、前記パーツの変形された図レイアウ
トを提供する。前記パーツの右図が前記パーツの平面図
の右側に位置するように前記レイアウトBにおいて右図
を90度回転することにより、図面中の前記複数の図は
レイアウトAで表現される標準的な形態に応じて加工さ
れる。格納されたルックアップテーブル或いは予め定め
られた或いは標準的な形態を表現するマトリックスが、
前記2次元図面の複数の図を比較し且つどの図が回転或
いは並進運動を必要とするかを決定するために用いられ
る。
【0254】前記2次元図面における複数の図から前記
パーツの正確な3次元モデルが生成されることを保証す
るために、前記複数の図の各々においてそれぞれの寸法
が相互に矛盾がないか或いは一致しているかチェックさ
れる。図21において更に示されるようにステップS1
90で前記データファイルにおける前記複数の図の境界
が、それぞれの図の全ての寸法が相互に同じ寸法である
かを確認するために検出される。仮に複数の図が所定の
誤差の範囲内で(例えば0.0−0.01インチ)一致
しないことが判断されるとステップS190で、全ての
複数の図が同じスケールになるように任意の特定の図の
寸法を変更するために適宜の修正が行なわれる。図面の
寸法が相互に一致せず現在存在する2次元図面データに
対して必要な修正が行なわれるようにユーザに警告する
ためにサーバモジュール32に警報要素が設けられる。
【0255】前記パーツの各々の図における寸法の一貫
性を検出し且つ確認するために種々の操作或いは工程が
使用される。例えば、前記複数の図の各々の対応する寸
法が、それらが相互に所定の誤差の範囲内にあるかどう
かを決定するために比較される。そのような解析は、前
記パーツの各図の境界線を定義する線分エンティティー
を比較することを含む。図23(b)における標準的な
形態を仮定して以下のようであれば平面図は右図または
左図と一致すると検出される。即ちそれぞれの図につい
て、最大Y座標位置と最小Y座標位置が所定の誤差範囲
(例えば0.0−0.01インチ)内にある。更に前記
平面図は、以下の場合には正面図または背面図と一致す
ると検出される。即ち各図について、最大X座標位置と
最小X座標位置とが所定の誤差範囲(例えば0.0−
0.01インチ)内にある。更に左図または右図は、最
大Y座標位置と最小Y座標位置との間の差に比較して最
大X座標位置と最小X座標位置との差が所定の誤差範囲
(例えば0.0−0.01インチ)内にあれば正面図ま
たは背面図と一致すると決定される。再び前記図の寸法
或いは関連する面の寸法が一致しないとき前記2次元図
面データに対して必要な修正が加えられるようにユーザ
に警告するように、サーバモジュール32に警告要素或
いはモジュールが設けられる。
【0256】最後にステップS192で、本発明の面検
出方法の教示に基づいて、前記パーツの内側ループ及び
穴及び形状が検出される。各図の複数の面の内側に設け
られている種々の穴或いは形状は、前記パーツの種々の
線及び境界を通ってパーツの外側から中央へ向かってル
ープを形成していくことにより検出される。ループ及び
エンティティーの分析は、前記2次元図面における前記
パーツの各図に対してなされる。前記パーツの外側から
作用的に中央へ向かって内側へ各々の図を分析すること
により、検出されたループは前記パーツの物質と開口部
の境界及び領域を、周期的順番(即ち物質、開口部、物
質等)に基づいて決定する。図16(d)におけるそれ
のごときループツリーが複数の面の位置及び各々の面の
内部の任意の穴の位置を決定するために各図面について
生成される。浮遊する円弧或いは線分のごとき前記パー
ツの面の内部で連結されないエンティティーは、ステッ
プS192の中で検出され消去される。
【0257】本発明の前記2次元クリーンアップ操作を
行なうための代表的なコードは付録Dに提供される。こ
のコードはC++プログラム言語で記載されており、そ
こに使用される論理及びアルゴリズムの解析を円滑にす
るためのコメントを含む。そのコードは、図21−22
(b)を参照して上で議論したそれらのごとき、2次元
クリーンアップモードの種々の工程及び操作を含む。
【0258】図20を再び参照するに、2次元クリーン
アップ操作が行なわれた後論理フローはステップS16
4へ連続しそこで前記2次元図面が材料の厚さを表現し
または含むか否か(即ち前記2次元図面が厚さを有する
か否か)が決定される。もし前記2次元図面が厚さの量
を含むと判断される場合には、ステップS166で3次
元モデルへの引き続く操作のための2次元図面を作成す
るためにサーバモジュール32により厚さ消去手続きが
行なわれる。前記2次元図面における厚さの存在の判断
は図面のデータに基づいてサーバモジュール32により
自動的に行なわれ、或いはオペレータからの援助或いは
応答を介して前記サーバモジュールにより行なわれる
(オペレータは厚さ除去が必要であるか或いは好ましい
かを指示するように促される)。前記パーツの厚さは全
ての板金パーツの独特の対称性により消去される。前記
パーツの厚さを消去することにより、厚さを有しない、
結果としての板金パーツは板金オペレータ或いは設計者
により、より容易に分析される。更にこの出願の発明者
は、前記2次元3面図の厚さを除去することにより、2
次元図面を変換し3次元モデルを生成するに必要な時間
が著しく短縮されることを見出した。
【0259】殆どの2次元3面図は材料厚さ量を含むた
め、オペレータはしばしば、2次元図面から3次元モデ
ルを作成するためにいずれの曲げ線が選択されなければ
ならないかで混乱する。結果として、2次元3面図が3
次元モデルへ変換されるように適切な曲げ線を選択する
際に相当の時間が無駄になる。厚さを有する2次元3面
図の例が図24に示されている。この発明の1つの側面
によれば、材質厚さを持つことなく表現され且つ処理さ
れるが、当該材質厚さ量及び前記パーツの内側及び外側
寸法を曲げモデルデータ中に保有する簡単化された2次
元3面図モデルを表示するように、厚さ除去手続きが設
けられている。図24(b)は前記厚さ除去工程を行な
った後、前記サーバモジュール32において前記オペレ
ータに対して観察され且つ表示される簡単化された2次
元3面図を図示する。
【0260】前記厚さ除去手続きが実行される時、ユー
ザは、2次元3面図表示における材質厚さを特定するよ
うに促されてもよく、また前記表示内においていずれの
寸法(即ち外側寸法或いは内側寸法)が保持されるべき
であるかを特定するように促されても良い。オペレータ
は、例えばマウスを用いて複数の図の中の1つにおいて
保持される厚さ及び表面を指示する。このユーザにより
入力されたデータに基づいて、サーバモジュール32は
前記2次元3面図を修正し、ユーザにより指示された材
料厚さを消去し、前記オペレータの選択に基づいて内側
或いは外側寸法を残す。
【0261】前記2次元3面図図面において厚さを消去
するために、前記サーバモジュール32は前記オペレー
タにより行なわれた選択に基づいて前記3つの図の各々
を分析する。選択された表面は幾何学的計算により(即
ち選択されたエンティティー線分或いは表面と同じX座
標或いはY座標射影に存在する対応するエンティティー
を検出することにより)他の図の1つへ射影され、前記
複数の図の各々における対応するエンティティー及び線
分を検出する。対応するエンティティーは、マークされ
且つ保持され、合致しないエンティティー或いは表面は
削除され或いは図24(b)に示されるそれのように、
スクリーン上に表示されない。更にオペレータにより指
示される厚さ寸法線は他の図の各々へ同様に射影され、
合致する厚さ寸法線或いはエンティティーは図24
(b)の例に更に示されるように削除される。結果とし
て、図面内の複数の図の各々は適宜に修正され、前記サ
ーバモジュール32においてユーザに対して表示され
る。厚さを有しない、結果としての2次元3面図は前記
パーツの3次元モデルを生成するために次の工程で使用
される。
【0262】この発明の厚さ削除手続は、各図において
削除されるべき厚さ線及び残されるべき表面エンティテ
ィーをオペレータが選択的に指示するようにするための
マニュアル厚さ消去モードを含む。表示された図の各々
においてどの領域が削除されるべきであり、どの表面が
残されるべきであるかを指示するためにマウス或いは他
の適当な入力装置がオペレータにより使用される。前記
オペレータにより入力されるデータに基づいて前記サー
バモジュール32は、厚さを有しない図面を提供するた
めに、前記2次元3面図からオペレータにより選択され
る各線分エンティティーを削除する。
【0263】この発明はまた全ての厚さ表現が前記2次
元3面図図面において正しく特定されたか否かを分析し
且つ検出し且つ、マークされない厚さ要素が存在する時
及び/又は図面データ中に矛盾が存在する時、ユーザに
警告するための警告システム或いはモジュールを含む。
例えば厚さ警告要素は、前記表示スクリーン上で潜在的
なマークされない厚さ部分を強調するために設けられ、
面警告要素は面の寸法が他の図における厚さのマークと
一致しない時、前記スクリーン上で潜在的な一致しない
面を強調するために設けられる。曲げ線警告要素は、ま
た矛盾する曲げ線を強調し及び一致しない厚さ曲線を強
調するために設けられる。曲線は、この曲線上に射影さ
れる少なくとも1つの曲げ線が2つの横断厚さ線分(厚
み横断線)により挟まれないとき強調される。例えば図
24(c)は、2つ或いは他の零でない偶数の横断厚さ
線分(即ち各図において厚さを横断する短い線)により
正しく挟まれている厚さ曲線を図示する。各曲げ線は2
つ又は他の零でない偶数の横断厚さ線分により挟まれる
べきである。各図面における前記パーツのこれらのエン
ティティーの分析は、ループ分析を実行し且つ各図を作
り上げる線分及び円弧エンティティーの連結性を解析す
ることに基づく。開放された厚さ線分は他の厚さ線分或
いは曲線と接続しない少なくとも1つの端点を有する厚
さ線分に基づいて定義される。1つの開放厚さ線分を含
むサイドは開放厚さサイドと定義される。厚さ線分は、
開放厚さ線分の開放厚さサイドが最小ループの境界ボッ
クスに一致しない場合に強調される。前記加工された2
次元3面図の像に関連する警告をユーザに与えることに
より、ユーザは図面データ中の矛盾を警告され、ユーザ
はパーツの3次元モデルを生成するために更に加工を行
なう前に、前記図面データを修正及び/又は訂正するこ
とができる。そのような警告システム及びユーザとの相
互作用を含むことが3次元モデルによる前記パーツの表
現の精密さを改善する。
【0264】図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)。これらの開示はここにそれらの全てにお
いて明示的に取り込まれる。
【0265】ステップS168で3次元モデルを展開す
る際、結果としての3次元モデルを更に加工し且つ精密
化するために追加のクリーンアップ工程が含まれる。こ
の発明の1つの側面によれば、3次元クリーンアップ工
程は、前記パーツの2次元3面図において存在し且つ前
記パーツの生成された3次元表現において余計な或いは
過剰な情報を生成する不明瞭さを補償するために設けら
れる。当業者に理解されるように、パーツの2次元3面
図表現は3次元座標空間における前記パーツの種々の特
徴の表現に関連して不明瞭さを含む。前記2次元3面図
から3次元モデルを生成する際余計な且つ過剰な情報が
これらの不明瞭さの結果として生成される。従ってこの
発明の側面によれば、前記3次元クリーンアップ工程
は、1つの端部がつながっていない線分を検出し且つ除
去すると共に曲げ線を検出し且つきれいにすると共に面
をトリミングする工程を含む。前記3次元クリーンアッ
ププロセスは前記パーツの結果としての3次元モデルを
生成する際に自動的に行なわれ或いは前記生成された3
次元モデルが追加の工程を要求すると判断される時、オ
ペレータからの入力に基づいて選択的に行なわれる。
【0266】前記3次元クリーンアップ工程によれば、
前記生成された3次元図面データを分析することによ
り、一端部において他のエンティティーと接続されない
と判断される全ての線分或いは曲線が特定され片側開放
線分として定義される。片側開放線分であると判断され
る任意のエンティティーは前記パーツの3次元表現から
除去される。一旦開放線分が除去されると、それは他の
線分或いはエンティティーが開放されることを導くかも
しれない。従って新しい片側開放線分がまた特定され、
全ての開放線分或いはエンティティーが除去されるま
で、繰り返し除去される。図63は片側開放線分が除去
される前のパーツの3次元表現の例を図示し、図64は
片側開放線分が前記3次元表現から除去された後の前記
パーツを図示する。
【0267】上記したように、ステップS168で行な
われる3次元クリーンアップ工程は曲げ線を検出しきれ
いにする工程も含む。曲げ線は、3次元空間におけるパ
ーツの面情報の検出を促進するために特定され且つきれ
いにされる(例えばモールド線分を加えることによ
り)。前記生成された3次元モデルデータに基づいて、
各曲げ線は、それぞれの中心により定義される同一の法
線を有する一対の3次元曲線(例えばそれは図面データ
における曲線エンティティーにより表現される)の検出
に基づいて同定される。この過程において、特定された
前記曲げ線に対してモールド(形取り)線分が付加され
る。前記モールド線分は、3次元曲線の各対において対
応する終点を特定し且つ前記3次元曲線の対応する終点
の間でモールド線分(例えば線分エンティティーで表現
される)を延長することにより追加される。図65は曲
げ線が特定される前のパーツの代表的3次元表示を図示
し図66は前記モールド線分(図において破線で表現さ
れる)が追加された後のパーツを図示する。
【0268】曲げ線が特定され且つモールド線分が追加
された後、3次元クリーンアップ工程は更に前記パーツ
の全ての曲げ線をきれいにし且つ面をトリミングするた
めに前記パーツの3次元表現を加工する。前記2次元3
面図データの図における頻繁に生ずる不明瞭さにより、
前記パーツの3次元表現に前記面の過剰な部分が生成さ
れる。前記3次元クリーンアップ工程は前記面の過剰な
部分を特定しそして板金領域知識(例えば何が折り畳め
ないかについての知識)を用いて前記面をトリミングす
る。余分な穴或いは開口部のような他の余分な情報も特
定され除去される。結果として前記パーツの過剰な部分
は除去され前記3次元表現は前記板金パーツのより精密
な表現を提供する。図67は前記曲げ線をきれいにし且
つ前記面をトリミングする前のパーツの代表的な部分を
図示し、図68は正常化及びトリミングがなされた後の
パーツの前記部分を示す。
【0269】図25は材料厚さを持つ最初の3次元図面
から材料厚さを持たない3次元図面を生成するためにな
される工程及び操作の論理フローの例を示す。ステップ
S200で、材料厚さを有する最初の3次元図面が入力
されサーバモジュール32へ搬入される。前記3次元モ
デルは材料厚さを有する3次元のワイヤフレーム図面
で、DXF或いはIGESファイルのごときCAD図面
ファイルである。前記3次元図面が前記サーバモジュー
ル32へ搬入された後、厚さ除去工程がステップS20
4で行なわれる。ステップS204における前記3次元
モデルに対する厚さ除去工程は上記したアマダUNFO
LDソフトウエア・システムにおいて提供されると同じ
方法で行なわれる。前記3次元モデルにおいて厚さを消
去するために、オペレータはまず厚さを指示し且つ残さ
れる面を選択するように促される。このオペレータの選
択に基づいて厚さを定義するエンティティー線分の終点
を解析することにより厚さが測定される。しかる後、選
択された表面の境界が、前記ループ及びエンティティー
解析工程に関連して上記したと類似の方法により探索さ
れる。そして保持されるエンティティーはマークされ
(例えばフラグを設定し或いは増加することにより)、
対応する厚さエンティティーは除去される。前記3次元
パーツのエンティティーを探索する際、前記エンティテ
ィーは、ユーザにより選択された厚さエンティティーの
長さに基づいて識別される。一般的に前記厚さエンティ
ティーと同じ長さを有する全てのエンティティーは選択
されず除去され、同じ長さでない他のエンティティーが
マークされ残される。前記3次元パーツの表面の探索で
マークされなかった残りのエンティティーもまた除去さ
れることがある。再びサーバモジュール32はマニュア
ル厚さ除去モードを提供し、そこではオペレータは除去
されるべき3次元パーツにおける各エンティティーを手
動で指示する。
【0270】ステップS204の後、厚さを有しない、
結果としての3次元モデルがステップS206で展開さ
れ及び/又はオペレータに対して表示される。展開アル
ゴリズム或いは工程が次にその材料厚さを有しない3次
元モデルに適用され上に詳細に説明したように、曲げモ
デルデータについての単一の2次元平面図を生成する。
【0271】上記したように前記データベース30に格
納されるデザイン及び製造情報は、板金要素についての
製造データのみならず板金の幾何学形状及びトポロジー
を含む曲げモデル・データファイルを含む。更にこの発
明の種々の特徴を実行するために使用されるソフトウエ
アはC++のごとき高度のプログラム言語を用い且つオ
ブジェクト指向プログラム技術を用いて生成される。こ
の発明の種々の特徴を実行するためには、Booch或
いはOMTのごとき異なるオブジェクト指向技術も使用
される。オブジェクト指向プログラムが使用される場合
は、前記板金パーツを表現するためにオブジェクト指向
データが使用され、前記パーツのための曲げモデルは完
全に自己充足的クラス・ライブラリを介して実行され
る。この発明の1つの側面により、オブジェクト指向プ
ログラム技術に基づく、前記曲げモデルのための代表的
データ構造及びアクセス・アルゴリズムの記述が提供さ
れる。
【0272】図26は、本願発明をオブジェクト指向プ
ログラムにより実行する際使用される前記曲げモデルの
代表的データ構造及びアクセスアルゴリズムを図示す
る。オブジェクト指向プログラムは、データを含む複数
のオブジェクト或いはモジュールのみならずそのデータ
に作用する複数の指示を結合することにより現実世界を
モデル化することができるソフトウエア展開の1つのタ
イプ或いは形態である。オブジェクト指向プログラムに
おいては、オブジェクトは板金パーツのごとき、何か物
理的なものをモデル化するソフトウエアエンティティー
であり、或いはそれらはビジネス上の商取引のごとき仮
想的な何かをモデル化するものである。オブジェクトは
そのオブジェクトの状態を集合的に定義する1つもしく
はそれ以上の属性(即ちフィールド)を含み、且つ全て
の他のオブジェクトからそれを識別するための識別子を
含む。更にオブジェクトはある種の条件の存在に基づい
て、前記属性を修正し或いは前記オブジェクトに対して
作用をなす一群の方法(即ち手続き)により定義される
振る舞いを含む。
【0273】この発明の実施例によれば、前記板金パー
ツはオブジェクト指向データモデルとして表現される。
図26に示されるように板金パーツの曲げモデルは完全
に自己充足的なクラスライブラリとして定義される。前
記板金パーツのための全ての要求されるデータ操作及び
機能(例えば折曲げ、展開等)はこのクラスライブラリ
の要素機能として取り込まれる。全ての幾何学的或いは
トポロジーデータは前記曲げモデルの中で分類される複
数のオブジェクトの内部で定義される。前記曲げモデル
クラスライブラリは複数のクラス或いはオブジェクトの
階層であり、パーツクラスはその階層の最上レベルのク
ラスである。前記パーツクラスは種々のパーツ属性を有
するパーツオブジェクトを含み、前記パーツ及び前記パ
ーツに対してなされる複数の作用を定義する種々のオブ
ジェクトを含む。
【0274】図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次元空間位置データ、及
び端及び表面データを含む。
【0275】図26の実施例に更に示されるように、パ
ーツクラス50は更にトポロジー・オブジェクト62及
び曲げ特性オブジェクト64を含む。前記トポロジーオ
ブジェクト62は、前記パーツの前記面、穴、成形部及
び曲げ線についてのパーツトポロジーデータを含む。前
記トポロジーオブジェクト62におけるデータは前記パ
ーツの前記種々の特徴の構造的及び幾何学的関係を示
す。前記曲げ特性オブジェクト64は前記パーツの1つ
或いはそれ以上の特徴についての特殊な製造上の拘束に
関する情報を含む。例えば如何に前記板金パーツが曲げ
られるべきであるかに関する曲げ特性情報が、前記曲げ
特性オブジェクト64に設けられる。前記曲げ特性情報
は、異なる曲げ特性タイプ(例えば同時曲げ、同一直線
上曲げ、Z曲げ等)についての特殊製造データを含む。
【0276】前記曲げ線オブジェクト60は、また行な
われる曲げに関連する製造特殊データを含む。従って、
各曲げ線についての幾何学的或いは寸法データ、2次元
及び3次元空間位置データ、端データに加えて、前記曲
げ線オブジェクト60はまた、各曲げ線についてのV幅
データ、曲げピッチデータ、曲げ数データ及び/又は配
向データを含む。各曲げ線は、図26に示すように付随
する曲げ操作を含む。この曲げ操作は、各曲げ線におい
て曲げを行なうためのデータ及び操作/指示を有する一
群のオブジェクトとして実行される。仮にオブジェクト
として提供されると、各曲げ操作は、曲げ角度、曲げ半
径及び/又は曲げ縮小量のごとき固有の曲げデータのみ
ならず、如何に或いはどのタイプの曲げを行なうべきか
(例えば円錐曲げ、Z曲げ、ヘミング、円弧曲げ等)を
指示するデータ及び指令を含む。
【0277】前記パーツの曲げモデルを、オブジェクト
指向データモデルを介して実行することにより、全ての
複雑な数学的計算、計算幾何学及びマトリックス変換が
単一のクラスライブラリに組み込まれる。ヘミング、Z
曲げ及び円弧曲げのごとき特殊な曲げ操作もそのクラス
ライブラリに取り込まれる。更にV幅及び曲げ縮小量及
び曲げ順のごとき製造情報もそのクラスライブラリに取
り込まれる。前記曲げモデルにより、前記2次元平面モ
デル及び3次元モデルの同時二重表示が図26に示すよ
うに行なわれる。更に、前記曲げモデルの曲げ線オブジ
ェクト60に応じて曲げ加工が行なわれる。前記曲げモ
デル及びパーツ構造並びにそれらについての実行に関連
する一般的なコメントはここに添付した付録Kに提供さ
れる。
【0278】曲げモデルビューアが前記曲げモデルを解
釈し、2次元及び/又は3次元表現における前記パーツ
の視覚的な画像を表示するために設けられる。図27
は、この発明の他の側面による、前記曲げモデルビュー
アの構造と前記曲げモデルとの関係のブロック図を図示
する。前記曲げモデルビューアはオブジェクト指向プロ
グラム技術を介して実行され、前記設備38における種
々の場所10,12,14,…20の前記ステーション
モジュールにおけるユーザが前記曲げモデルに設けた情
報に基づいて前記パーツの種々の図を表示できるように
するウインドウズに基づくアプリケーションである。前
記曲げモデルビューアは、前記板金パーツを視覚化する
ために用いられる一群のアプリケーション・ライブラリ
・モジュールを含む。更に、前記曲げモデルビューア
は、ウインドウズ・アプリケーションの画像クラスとし
て設計され、従ってそれは任意のウインドウズ・アプリ
ケーションについての基本的画像クラスとして使用され
る。前記2次元及び3次元モデルを見るための殆どの標
準的操作(例えばズーム92、回転96、パン100、
寸法102等)は前記曲げモデルビューアの要素機能と
して実行される。幾何学的変換及び基本的コンピュータ
グラフィックス技術は、画像操作を実行する際に前記曲
げモデルオブジェクトに対して適用される。更に、前記
曲げモデルビューアは、画像モデル属性88を含み、そ
れはソリッド画像、ワイヤフレーム画像、2次元平面画
像及び正射影画像を含む4つの主なる画像モードを有す
る。
【0279】この発明の1つの側面によれば、前記曲げ
モデルクラスライブラリ80は、選択された画像(例え
ばソリッド、ワイヤ、2次元平面又は正射影画像)に応
じて、前記板金パーツに作用する一群の手続き又は機能
を含む。前記曲げモデルビューア観察クラス84は、ズ
ーム92、回転96、パン100及び寸法102のごと
き、一連の標準的操作を含む。そして、前記曲げモデル
ビューアの状態に応じて、前記曲げモデルビューア観察
クラスは、前記曲げモデル・クラス・ライブラリ80か
ら複数の機能を呼び出す。図27に示されるように、ユ
ーザにより選択される前記種々の観察モデル属性或いは
特徴88は、ソリッド画像、ワイヤフレーム画像、2次
元平面画像及び正射影画像を含む。この発明に設けてあ
るこれらの種々の観察モードの記述は図28−31を参
照して以下に提供される。
【0280】基本的コンピュータグラフィックス及び幾
何学的モデル化技術、例えば幾何学的変換及び3次元幾
何学的技術は、前記曲げモデルの種々の特徴を実行し且
つ異なる観察モード或いは機能を提供するために使用さ
れる。コンピュータに基づいた2次元及び3次元のモデ
ル化及びシミュレーションにおける最近の発展及び展
開、例えばグラフィックライブラリ或いはパッケージの
効用はこの発明のこれらの特徴を実行するために適用さ
れる。更に、コンピュータグラフィックス及びモデル化
については広い種類の刊行物或いは文献が利用可能であ
る。例えば、モルテンソン、フォリー等、マンティラを
見よ。それらの各々は上に記載した。
【0281】この発明の種々の観察及びモデル化の特徴
を提供するために各ステーションモジュール及びサーバ
モジュールは、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)を見よ。
【0282】前記パーツの種々の画像を表示するため
に、前記曲げモデルは例えばオペレータのステーション
モジュールにより前記データベース30からアクセスさ
れる。前記曲げモデルデータは、使用されているグラフ
ィック・ライブラリ或いはパッケージ(例えばオープン
GL又はレンダウェア)により使用されるデータフォー
マットに応じて再フォーマット化される。しかる後、前
記グラフィックデータは、オペレータにより選択された
観察モード(ワイヤ、ソリッド等)を表示し、或いは前
記ユーザにより実行された観察機能(ズーム、パン等)
を実行するために種々のプログラムされた順序に従って
加工される。
【0283】特定の観察モードがオペレータにより選択
される時、選択された観察モードは、前記画像の現在の
ズーム比率或いはファクター及び向きと共に検出され
る。この情報は、次に前記現在の表示を更新するために
前記グラフィックパッケージに対して機能コールを行な
うために使用される。前記グラフィックパッケージに対
する機能コールは、表示される観察モード並びに実行さ
れるズーム或いはその他の観察機能に応じて行なわれ
る。これらの機能コールに基づいて前記グラフィックパ
ッケージは必要なデータを提供し、従って前記ステーシ
ョンモジュールは前記オペレータに対して前記パーツの
画像を表示する。前記ユーザによる前記2次元又は3次
元表現の修正(例えばジョイスティック或いはマウスを
移動することにより)に基づいて前記表示された画像を
更新するために追加の機能コールは前記グラフィックラ
イブラリに対してなされる。
【0284】前記パーツのワイヤフレーム画像を提供す
るために、前記グラフィックパッケージに対して前記パ
ーツの線分エンティティーデータが提供され必要なグラ
フィック計算がなされる。しかし、ソリッド画像につい
ては、前記面の各々について1つもしくはそれ以上の多
角形(ポリゴン)が引き出され、前記画像を表示するた
めに前記グラフィックパッケージへ入力として提供され
る。オープンGL及びレンダウェアのようなグラフィッ
クパッケージは、多角形データを入力として取得し、ソ
リッド画像を提供するために前記多角形により定義され
る領域を満たす。前記多角形は、前記曲げモデルにおけ
る面及び曲げ線情報から導出され各面の境界を決定する
ことにより導出される。前記多角形は前記パーツの各面
を表示し且つ定義するために生成されなければならな
い。これらの面は次に、板金パーツ全体を表示するため
に、前記曲げモデルにおける前記パーツトポロジー及び
他のデータに基づいて接続される。仮に面が開口部或い
は穴を有する場合には、そのような開口部を囲まない幾
つかの多角形を有する面を定義することが必要となる。
正射図については、個々の図の各々(それはワイヤフレ
ーム又はソリッドである。)についてのデータは前記グ
ラフィックパッケージに送られ、図31に示されるごと
く、結果としての複数の図が単一の表示スクリーン上で
結合される。前記曲げモデル像の種々の観察モード及び
機能を実行するための代表的コードは付録Eに提供され
る。このサンプルコードはC++で記載され前記プロセ
ス及びそこで実行される操作に関連する複数のコメント
を含む。適当なグラフィックパッケージ(例えばオープ
ンGL及びレンダウェア)との結合における前記コード
は異なった図(例えば2次元及び3次元ワイヤフレーム
或いはソリッド)を表示するために使用されるだけでな
く、前記観察機能(例えばズーム、回転、パン等)の各
々の機能を提供する。表示される種々の観察モード表示
スクリーンの簡単な説明が以下に与えられる。
【0285】ソリッド図モードは、前記曲げモデルによ
り定義される前記パーツの、ソリッドで表示される3次
元図を表示する。図28は前記板金設備38内での位置
10,12,14,…20のいずれかにおいて設けてあ
る表示スクリーンへ出力として提供される代表的ソリッ
ド図ウインドウを図示する。このソリッド図モードにお
いて、ユーザ或いはオペレータは、3次元空間でのナビ
ゲーション及び3次元自動寸法付けを操作するための複
数の観察機能を与えられる。前記パーツのソリッド図を
変更するために設けられる基本的な機能は回転、ズーミ
ング、パンニング、及び/又は標準図選択を含む。前記
ユーザにより与えられ或いは選択される前記標準図は以
下を含む。即ち等測投影法図、平面図、底面図、正面
図、背面図、左図、及び右図。自動及びマニュアル寸法
付け操作がまた提供され、現在の観察角度に基づいて前
記パーツの重要な寸法を表示する。この発明の寸法付け
特性の代表的例が、図32−36を参照して以下に提供
される。
【0286】図28に示されるようにソリッド図ウイン
ドウはウインドウズに基づいたアプリケーションであ
り、従って前記パーツの複数のウインドウ或いは部分図
が提供される。前記複数の図のウインドウは、ウインド
ウの中で1つの極めてクローズアップされた単一の図を
提供する拡大図及び単一のウインドウにおいて前記パー
ツの極めて遠くからの図を与える鳥瞰図を含む。前記部
分図はユーザにより選択されたオブジェクトの部分図を
与える。前記種々の観察機能を制御するために、前記場
所10,12,14,…20の各々の前記サーバモジュ
ール32及びステーションモジュールに、ジョイスティ
ックインタフェースが設けられる。前記ジョイスティッ
クだけ及び/又はキーボード上の所定のキー(例えばシ
フトキー又はコントロールキー)の操作との組み合わせ
の操作が、回転及びパンニング及びズーミングのごとき
種々の機能を実行するためにユーザにより行なわれる。
更に、前記パーツのソリッド図の表示される生地は、デ
ータベース内での前記パーツについて特定された材質を
シミュレートするように選択される。この目的のため
に、スチール、ステンレススチール、アルミニウム等の
ごとき材料の生地のライブラリを有する材料生地ライブ
ラリが提供される。格納された材料生地ライブラリはソ
リッド図が存在する時オペレータによりアクセスされ適
用される。従って、表示されるパーツの表面は前記板金
パーツの実際の生地をより忠実にシミュレートする。
【0287】前記ワイヤフレーム図モードは、前記板金
パーツのワイヤフレーム図のウインドウズに基づいた表
示を提供する。ワイヤフレームウインドウの例が図29
に示されている。前記ワイヤフレームにおける3次元空
間ナビゲーション及び3次元寸法付けを提供するための
キーの機能は、前記ソリッド図に関して上に記載したと
類似である。例えば回転、ズーミング、パンニング及び
標準図の選択のごとき機能が提供される。自動寸法付
け、多重図ウインドウ及び断面図オプションも前記ワイ
ヤフレーム図モードにおいて提供される。更に、ジョイ
スティック及び/又はキーボードインタフェースが、ユ
ーザが前記種々の観察機能を選択し且つ活性化すること
ができるように提供される。
【0288】前記2次元平面図モードはワイヤフレーム
表示において、前記パーツの展開された2次元平面図を
表示する。2次元平面図ウインドウの例が図30に示さ
れている。この2次元平面図モードはユーザがウインド
ウ中の図を変更し又は改造するのを可能とするための複
数の観察機能を有する。例えばユーザが前記2次元平面
ワイヤフレーム図を選択的にズームし且つパンするのを
可能とするようにズーミング及びパンニング機能が設け
てある。更に、寸法付け及び多重ウインドウ観察機能
が、前記ソリッド図モードに関して上記したと同様の態
様で設けてある。ジョイスティック及び/又はキーボー
ドインタフェースはユーザがパンし、ズームし他の観察
機能を制御するのを可能とするように設けてある。前記
パーツに設けられている特殊な成形部または形状は、特
殊な成形部の指示又は記載と共に、前記成形領域の前記
最も外側の境界についての成形または形状として表示さ
れる。
【0289】図31に図示されるような正射図ウインド
ウも前記曲げモデルビューアの一部として提供される。
前記正射図モードはワイヤフレーム表示において平面
図、正面図、右図及び等測投影法図を表示する。隠れ線
オプションが、観察角度に基づいてブロックされた線を
見えなくするために設けられる。この隠れ線オプション
は各図のウインドウを簡単化するために用いられる。前
記正射図モードにおいても種々の観察機能が提供され、
ユーザが前記ウインドウにおいて現在の図を選択的に操
作し且つ変更するのを可能とする。例えば、ズーミング
及びパンニング機能が寸法付け及び多重ウインドウ観察
機能と共に設けられる。上記したように、多重ウインド
ウ観察機能が設けられ、ユーザが、多重ウインドウにお
いて前記正射図の拡大図及び/又は鳥瞰図を選択的に表
示することを可能とする。ジョイスティック及び/又は
キーボードインタフェースが、前記複数の場所の各々に
設けられ、ユーザが、前記正射図モードにおいて前記複
数の観察機能の各々を選択的に活性化し且つ操作するの
を可能とする。
【0290】上記した種々の図の表示の各々を表示せし
めるのに加えて、前記曲げモデルビューア観察クラスは
他の特徴と共に実行される。例えば前記曲げモデルビュ
ーアはオペレータにより選択され強調されている、現在
の図における複数の項目或いはエンティティーを指示す
るための選択集合を含み且つ維持する。この発明の1つ
の側面によれば、オペレータは、選択された項目に関連
するデータを修正し或いは前記パーツのそれらの項目の
所定の操作を行なうために、前記表示されたパーツの面
及び曲げ線及び他の特徴を選択することを可能とされ
る。例えばオペレータは、表示されたパーツの面を選択
し、その面のその幅或いは長さに沿っての寸法データを
変更することができる。オペレータはまた曲げ角度又は
V幅のごとき各曲げ線に付随する種々の曲げデータを修
正することができる。
【0291】前記曲げモデルビューアはユーザにより選
択されたエンティティー或いは項目(例えば面、曲げ
線、面或いは曲げ線の端等)のリストを保持する。観察
者はそのリストを更新する。従ってオペレータにより現
在選択されている現在の項目は前記選択リストに常に保
持される。この発明におけるソフトウエアの他の部分
は、異なる手順(例えばマニュアル寸法付け等)を実行
し或いは行なう際、選択されたエンティティーの前記現
在のリストの図面クラスを呼び出す。
【0292】更に前記曲げモデルビューアは観察可能性
機能を提供する。それは現在表示されている図に基づい
て観察可能性情報及び座標情報を提供する。以下に更に
十分に説明されるように、前記観察可能性機能は前記パ
ーツの特定な部分或いはエンティティーがスクリーン上
で現在観察可能であるか否かについての情報を提供し且
つスクリーンエンティティーが現在位置する場所につい
ての座標情報を提供する。前記曲げモデルビューアの観
察可能性機能は、前記パーツのどの部分が現在スクリー
ン上で観察可能であるかを決定するためにこの発明の寸
法付け特性により呼び出される。従ってスクリーン上で
観察可能である前記パーツの部分の寸法情報のみが観察
者に対して表示される。この発明の寸法付け及び観察可
能性機能のより詳細な説明は以下に提供される。更に前
記曲げモデルビューアの観察可能性機能を実行するため
の代表的コードはここに添付する付録Jに提供される。
【0293】図32−36を参照するに、この発明の1
つの側面に基づく、寸法付け特性の事例が説明される。
上記したように、観察モードの各々は現在の観察方向に
基づいて、前記パーツの寸法を自動的に表示する寸法付
け機能を含む。自動寸法付け機能は、現在の観察角度に
おいては見ることができないフランジ或いは曲げ線の寸
法がユーザに対して表示されないように提供される。前
記自動寸法付け機能或いはモードが活性化される時、前
記パーツの観察可能な寸法のみが、現在の観察角度に基
づいて表示される。更に、自動寸法付けモードにおいて
は、所定の寸法(即ち前記曲げ操作に対して重要である
寸法)のみが現在の観察角度の状態に基づいて表示され
る。マニュアルの寸法付けモードも提供され、ユーザが
どの寸法が表示されるべきであるかを選択的に指示する
ことを可能とする。このマニュアル寸法付けモードにお
いては、ユーザにより選択された寸法事項のみが、現在
のパーツの観察角度に基づいて表示される。いずれの寸
法付けモードにおいても、表示された寸法事項は、前記
パーツがズーム化され或いはパンされる時ウインドウ表
示から消去され或いは除去される。
【0294】図32は自動寸法付けモードにおいて表示
される種々の寸法事項の例を図示する。前記自動寸法付
けモードにおいて表示される寸法事項は、曲げ操作に重
要な事項(例えばフランジ長さ、曲げ線長さ、曲げ角度
等)からなり、パンチ加工された穴或いは開口部の寸法
のような余分な寸法事項ではない。前記表示される寸法
事項は例えば前記板金パーツの幅、深さ、及び高さ並び
にフランジ長さを含む。更に、各曲げ線の前記曲げ線長
さL、曲げ角度A、内側半径R及び曲げ縮小Dは単独で
或いは一緒に、1つのウインドウに或いはグループ情報
ボックスに表示される。上記したように、現在の観察角
度に基づいて観察可能な寸法事項のみが表示される。更
に前記オペレータが、前記パーツの観察角度を変えるた
めに回転、ズーミング或いはパンニングをする時全ての
寸法は表示から消去され或いは除去され、各操作が完了
した時それらの寸法は再び表示される。表示情報(任意
のテキスト或いは参照矢印)の寸法及び向きは、現在の
ズームの比率或いは観察角度ではなくスクリーンの寸法
に対して常に寸法調整される。しかしながら、前記寸法
情報の可読性を改良するために前記寸法情報の色、スタ
イル、重み及び/又はフォントはユーザがそれらを変更
できるように形成可能である。結果としてオペレータ或
いはデザイナーは、前記寸法情報の特殊の色、フォント
サイズ等を選択することによりパーツにおける重要な寸
法を強調することができる。例えば、寸法テキストの
色、寸法又はフォント又は、寸法参照事項、線又は矢印
の色、線の重み或いはスタイルは、パーツにおける重要
な寸法を指示するために強調され或いは選択的に変更さ
れる。オペレータはまたウインドウ情報ボックスを色付
けし満たし或いはスタイル付けし或いは特定の曲げ線を
色付けし或いはパーツ内の他の重要な寸法を強調する。
【0295】この発明の寸法付け特性を実行するために
種々のプロセス或いは操作が利用される。更に上記した
ように本発明の寸法付け特性に対して観察可能性情報を
提供する観察可能性機能を、前記曲げモデルビューアは
備える。これらの機能或いは特性は、例えばサーバモジ
ュール32及び/又は工場全体に位置するステーション
モジュールのそれぞれでソフトウエアにより実行され
る。この発明の自動寸法付け特性を実行するための代表
的コードが付録F−Iに設けてある。更に、曲げモデル
ビューアの観察可能性機能のためのサンプルコードが付
録Jに設けてある。これらの付録におけるコードはC+
+プログラム言語で書かれており、そこで行なわれる手
続き及び操作の論理フローの理解を容易にするためのコ
メントを含む。
【0296】この発明の寸法付け特性の論理フローは一
般的に3つの段階に分類される。第1の段階で、前記パ
ーツの曲げモデル幾何形状及びトポロジーデータがデー
タベース30からアクセスされ、前記パーツの全ての寸
法並びにそれらの寸法が表示され得る全ての態様を計算
するために使用される。前記パーツの各曲げ線及び面に
ついて、データが表示され得る全ての最も遠い点が計算
され、これらの点について、寸法線或いは矢印が表示さ
れ得る全ての方法が計算される。前記寸法データ或いは
他の情報が表示され得る場所を決定する際に一定のヒュ
ーリスティックが適用される。例えば一般的なルールと
して、全ての情報は前記パーツの外側にのみ表示される
と決定される。このようなヒューリスティックが、前記
ビューアに対してより意味のあるそしてより込み合わな
い情報の表示を提供するために適用される。
【0297】上記した第1の段階は、本発明の寸法付け
特性がオペレータにより活性化された際常に実行され
る。或いは、前記第1段階の計算は前記パーツが最初に
オペレータにより観察された際にのみ行なわれる。この
ような場合に、前記計算されたデータは次の使用のため
にメモリに格納され、前記パーツの寸法或いは他の幾何
学的データがユーザにより修正され或いは変更された時
変更される。更に前記第1段階の全ての計算は図面スク
リーンに対してではなくパーツの幾何学形状に対して行
なわれる。従って前記データは、現在の図面に関わりな
く或いはその図面が変更されても何時でも再び使用され
得る。
【0298】この発明の自動寸法付け特性の第2段階は
前記パーツの図面が更新された時常に行なわれる。この
第2段階の主たる目的は、変更された図において前記パ
ーツのどのエンティティーが観察可能であるかに基づい
て前記第1段階中に生成されたデータをふるいにかける
ことである。この第2段階において、現在の図において
観察可能でない全てのデータはふるいにかけられ、現在
観察可能である、前記第1段階において計算されたデー
タのみが残る。前記パーツのいずれの点あるいは部分が
現在観察可能であるかを決定するために前記曲げモデル
ビューアに対する機能コールがなされる。上記したよう
に、前記曲げモデルビューアは、表示されている現在の
図に基づいて前記パーツの観察可能な部分についての情
報を保持し且つ提供する観察機能を含む。前記パーツの
向きに基づいて前記曲げモデルビューアは前記パーツの
どの面及び曲げ線(並びにそれらの面及び曲げ線のどの
端或いは部分)が観察可能であるか、そして何がスクリ
ーン上で隠されているかを決定する。
【0299】上記したように、前記曲げモデルビューア
の観察可能機能を実行するためのサンプルコードは付録
Jに提供される。前記パーツのいずれの点あるいは部分
が観察可能であるかを決定するために、前記曲げモデル
ビューアは前記パーツの現在の図の向き及び現在のズー
ム面又は表示されているパーツの比率を決定し且つ維持
する。前記曲げモデルビューアはこの現在の図の向きを
決定し維持するために従来の透視図射影技術(モルテン
ソンの例えば12章を見よ)を使用する。前記パーツの
任意の点の観察可能性を決定する際に前記点の世界座標
(即ちそこにおいて前記パーツが表現されているところ
の座標)を前記観察可能性機能は獲得する。次に、前記
現在の図面の向き及びズーム面あるいは比率に基づいて
その点について、前記世界座標に対応するスクリーン座
標(即ちスクリーン上の画素の位置)が決定される。そ
の後、前記スクリーン座標に基づいて、前記スクリーン
の観察点の眺めから前記部品の任意のエンティティー或
いは部分が問題の点の前方にあるか否かが決定される。
前記パーツの上の点の隠されている特性は、前記パーツ
の他のエンティティー或いは部分が問題の点と同じスク
リーン上の点を割り当てられているかどうかに基づいて
も決定され得る。グラフィックパッケージ或いはライブ
ラリ(例えばオープンGLあるいはレンダウェア)への
機能コールは、前記パーツの1つの点以上が同じスクリ
ーン上の点に割り当てられているかどうかを決定するた
めに使用される。もし何かが同じスクリーン上の点に割
り当てられているならば、それらの点のそれぞれのZバ
ッファ深さに基づいて、前記パーツの点がそれの後ろに
あるかどうかが決定される。前記Zバッファ深さはオー
プンGL或いはレンダウェアのごときグラフィックパッ
ケージにより使用され、観察点或いはカメラ位置からそ
れぞれの点への距離を定義する。前記Z深さは、興味の
ある前記パーツの複数の点について前記グラフィックパ
ッケージへ機能コールを行なうことにより決定される。
【0300】前記曲げモデルビューアの観察可能性機能
の前記プロセスはこの発明の自動寸法付け特性から前記
曲げモデルビューアへ催促がある時いつでも実行され
る。そのようなプロセスは従って前記オペレータにより
表示されているパーツの現在の図が修正され或いは変更
される時いつでも実行される。上記したように、前記曲
げモデルビューアは、表示された画像の向きに対して変
更がなされる時は常に、現在の図の向き及びズーム比の
状態を維持し且つ更新し、従って要求される時観察可能
性情報を正確に提供する。
【0301】どのデータが観察可能であるかを決定した
後、自動寸法付け機能は、(例えば第1段階での計算に
基づいて)前記寸法データ或いは他の情報が表示され得
る全ての可能な方法及び位置を決定する。前記データが
表示され得る全ての可能な方法からデータを表示するた
めの最適の方法を選択するために一群のヒューリスティ
ックが適用される。例えば第1のヒューリスティック
は、観察者の観察点により近いスクリーン上の領域が好
ましいと要求する。第2のヒューリスティックは、前記
寸法を定義するための2つの可能な点の間の距離が最小
であるところの領域により近い領域にデータは表示され
るべきであると規定する。他のヒューリスティックはま
た、スクリーン上での重なり合い或いは混雑を避けるた
めに、他の寸法データ或いは他の情報の相対的位置に基
づいて適用される。
【0302】前記パーツの観察可能な部分及び前記観察
可能な領域についての情報を表示するための最適の領域
を決定した後、前記自動寸法付け機能の第3の段階は前
記表示スクリーン上で種々の情報を描くために実行され
る。例えば、前記情報を表示するための領域の選択に基
づいて、寸法情報は前記パーツの観察可能な寸法の各々
についてスクリーン上に表示される。更にどの曲げ線が
観察可能であるかに基づいて、曲げ線情報がまた、他の
パーツ情報とオーバーラップしないスクリーンの領域に
おいて情報ボックス(例えば図32に示されるそれ)に
表示される。前記パーツの幅、高さ、及び深さを含むパ
ーツの寸法はまた前記スクリーン上の所定の位置(例え
ば前記パーツの右下)或いは前記パーツに最も近く他の
情報にオーバーラップしない或いはそれを邪魔しない位
置に表示される。
【0303】図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)に示されるそれのごとき交差寸法方法が使用
される。オペレータは、前記フランジ長さを表示するた
めに前記接線寸法或いは交差寸法方法のうちから選択す
ることを可能とされ、及び/又は特定の寸法方法(例え
ば接線寸法方法)はデフォルト設定として提供される。
【0304】曲げコード順番の生成を促進するために、
種々の表示機能を有した図形的ユーザインタフェースが
設けられ、オペレータによる曲げプランの生成を助け
る。図37−44はこの発明の他の側面により、図形的
ユーザインタフェースの使用により曲げコード順番を生
成するために実行される種々の手続き及び操作を図示す
る。通常、最初の曲げモデルデータ及び他の作業情報は
サーバモジュール32において重要な幾何学的及び製造
データを入力することにより設計プログラマにより生成
される。結果としての曲げモデルファイルは次にデータ
ベース30に格納される。板金パーツが製造される前
に、曲げオペレータが、所望の曲げ操作を実行するため
の曲げ順を生成する必要がある。この曲げオペレータ
は、どのタイプの工具が必要であるかを決定し且つ前記
曲げ機械装置について工具取付けを定義しなければなら
ない。この曲げプラン生成の工程は、図形的ユーザイン
タフェースの使用によりまたこの発明の種々の教示によ
り援助され、且つより効率的となる。
【0305】前記曲げプランを生成するために、例えば
曲げステーション18の曲げオペレータは、前記データ
ベース30から前記曲げモデル及び他の作業情報へアク
セスし且つダウンロードする。前記関連するパーツにつ
いての曲げモデルは前記コミュニケーションネットワー
ク26を介して曲げステーション18における工場フロ
ア上のステーションモジュールへ搬入され或いは移入さ
れる。この工程は、一般的に図37のステップS220
に示される。その後、ステップS224で曲げオペレー
タは、前記曲げモデルビューアを用いて前記パーツの形
状及び寸法を調べる。ここで、前記曲げオペレータは、
前記曲げステーションに位置付けられた表示スクリーン
で前記パーツの種々の2次元及び3次元図を選択的にズ
ームし且つパンする。この発明の自動寸法付け特性を活
性化することにより、前記曲げオペレータはまた曲げ操
作を実行するために前記パーツの重要な曲げ寸法を観察
する。
【0306】一旦オペレータが前記パーツの形状及び寸
法を理解すると、この曲げオペレータはステップS22
8で曲げ順入力ウインドウを選択し且つ表示することに
より前記曲げプランを生成することを開始する。前記曲
げ順入力ウインドウは、曲げオペレータが曲げ順を生成
し且つ修正し且つ消去するのを援助するために図形的ユ
ーザインタフェースを提供し且つオペレータが、前記曲
げ順における各段階についての種々の製造パラメータ
(例えばバックゲージ位置、工具、NCデータ等)を特
定し且つ入力することを可能とする。前記曲げ順入力ウ
インドウは前記スクリーンの一部(例えばスクリーンの
中央部或いはスクリーンの左側の方)に表示される前記
パーツの2次元平面図画像を含む。前記2次元平面図画
像は、前記パーツのフランジ、穴及び開口部を含む、前
記展開パーツの種々の特徴を含む。前記曲げオペレータ
が前記複数の曲げ線及び各曲げ線についての曲げ順を選
択し且つ指示すると、各曲げ段階における前記中間的パ
ーツ形状のソリッド2次元或いは3次元画像が現れ、例
えば図38に示されるように、スクリーンの右側の端の
ごときスクリーンの一部にそれらが提供される。前記中
間パーツ形状の画像は入力された曲げ順に対応した順番
で表示され且つ(図38の例に示されるように)前記パ
ーツの2次元平面図と共にスクリーン上に同時に表示さ
れ、或いは別個のスクリーン表示に別個に表示される。
【0307】更に各曲げ線が選択されるにつれて、前記
曲げ線は強調され、図39(a)に一例として示される
ように、曲げ順番号及び挿入方向(例えば矢印で表現さ
れる)が前記曲げ線の上或いは近くに表示される。各曲
げ線についての前記曲げ線番号は、それが選択される順
番に基づいて自動的に設定され、或いは各曲げ線が選択
された後オペレータによりマニュアルで入力される。曲
げ角度、曲げ線長さ、及びバックゲージ位置のごとき曲
げ線に関連する他の製造情報も、図40及び41に例と
して示されるように、各曲げ線が選択され強調されると
き入力され及び/又はスクリーン上に表示される。図4
0及び41に示すように、ダイアログ或いは情報ボック
スがスクリーン上に表示され、曲げオペレータが各曲げ
線に関連する製造情報及び他のパラメータを選択し、入
力し或いは修正することを可能とする。
【0308】前記ダイアログ或いは情報ボックスは、曲
げオペレータが曲げ線を強調し或いは選択するのを可能
とする。ホット機能キー或いは高速スイッチキーが前記
曲げシーケンス入力ウインドウに表示され、オペレータ
が工具立てを選択し或いは入力し且つNCデータを監視
し且つ修正するのを可能とする。例えば曲げオペレータ
は、工具機能キーを選択し、前記曲げ順入力ウインドウ
から、工具立て情報を入力するための工具入力表示スク
リーン或いは複数の表示スクリーンへ切替える。NC機
能制御キー(例えばNC9EX)も設けられ、オペレー
タが実行されるべき曲げ操作に関連するNCデータを監
視し及び/又は修正するのを可能とする。
【0309】更に図40及び41に示されるように、曲
げ線を定義し及び/又は修正すること及び関連する製造
情報に関連して他の機能キー及び制御部が設けられてい
る。例えばZOOM ALLキーが、前記2次元平面図
画像をズームイン及びズームアウトするために設けられ
ている。バックゲージキーは、前記バックゲージの位置
を選択し或いは設定するために設けられている。グルー
プ化及びグループ解除化制御キーは、一緒に曲げられる
複数の曲げ線を可能とし或いは制御するために表示され
る。更に制御キー(例えばアマ曲げ)が特殊な曲げ操作
を定義するために設けられている。他の機能キーも表示
されオペレータが前記曲げ順を選択し、修正し及び/又
は消去するために設けられている(例えばREMOVE
CLEAR FWD、CLEAR ALL、OK、C
ANCELL)。この曲げ順入力ウインドウにより、曲
げオペレータは、前記曲げ順及び種々の製造情報を効率
的に監視し且つ修正することが可能となる。
【0310】更にこの発明の他の側面によれば、前記パ
ーツの断面図及び/又はパーツの曲げシミュレーション
が、前記曲げ順における各曲げ工程についてスクリーン
上に表示される(例えば図41を見よ)。前記断面図及
び曲げシミュレーションは前記スクリーン上に選択的に
表示され、或いは曲げオペレータにより各曲げ線が選択
される時表示される。前記断面図及び曲げシミュレーシ
ョンは、例えば上下曲げ工具(例えばパンチ及びダイ)
又はバックゲージ位置・設定の表現を含み、それらは前
記2次元平面図画像と共に同時にスクリーン上に表示さ
れ或いは異なるスクリーン表示上に別個に表示される。
前記バックゲージ位置は前記パーツのトポロジーに基づ
いて自動的に決定され或いはオペレータにより設定され
或いは修正される。前記曲げ線のための工具立て情報が
入力されておらず或いは曲げオペレータにより設定され
る場合には、前記断面図及び/又は曲げシミュレーショ
ンはスクリーン上に表示されず又は前記中間パーツ形状
の表現及び計算され或いは定義されたバックゲージ位置
のみが表示される。前記曲げシミュレーションは、前記
パーツの所望の反転、前記パーツの操作及び配向動作及
び/又は各曲げ線でなされる前記パーツの曲げ加工の表
示されるシミュレーションを含む。前記表示スクリーン
上に前記パーツの2次元平面図画像と共に、曲げ工程の
前のパーツの断面図及び曲げ工程がなされた後の前記パ
ーツの断面図を同時に表示することもまた可能である
(例えば図41を見よ)。これらの断面図は、スクリー
ンの右側に提供され前記曲げ順における各曲げ工程につ
いての前記上下曲げ工具及びバックゲージの表現を含
む。更にズーム制御或いは機能キー(ZOOM IN及
びZOOM OUT)が表示され、オペレータが、前記
曲げ前及び曲げ後断面図に関連してズームの比或いは向
きを制御することを可能とする。日本公告公報平7−1
21418(丹羽等の名前で1995年12月15日に
発行)及び日本公開公報平1−309728(長沢等の
名前で1989年12月14日に発行)に開示されるそ
れと類似の技術及び手続きが前記パーツの断面図或いは
曲げシミュレーションを表示するために使用される。前
記文献の開示はここにその全体において参考により積極
的に取り込まれる。
【0311】この発明の1つの側面によれば、選択され
た曲げ線に関連して前記パーツの短い或いは小さいサイ
ドを計算することにより前記曲げについて挿入方向を自
動的に決定するためのソフトウエア或いはプログラム論
理が提供される。この発明の特徴に基づいて、各曲げ線
はそのパーツを2つのサイドに分断するために使用され
る。挿入方向は、より小さい或いは短い長さ(例えば前
記曲げ線に直交する辺の寸法)を有する前記パーツのサ
イドに基づいて或いは、より小さい全体的面積を有する
サイドに基づいて各曲げ線について決定される。もしオ
ペレータが前記選択された挿入方向に満足しない場合に
は、図39(b)に図示されるように、オペレータは挿
入方向を反転する。オペレータは挿入方向を、例えば曲
げ線が強調されている際にマウス或いはキーパッドの選
択ボタンをクリックすることにより変更し或いは反転す
る。挿入方向情報は、曲げ装置或いは機械装置で前記パ
ーツを曲げ加工するために、前記曲げ線により定義され
るフランジの挿入方向を指示するための矢印及び/又は
テキストを含む。前記挿入方向情報は、曲げ線の上或い
は近く(例えば図39(a)及び39(b)を見よ)或
いは関連するフランジの端の上或いは近く(例えば図4
0を見よ)に表示される。更に前記挿入方向情報は、各
曲げ線が選択された時に表示され或いはジョイスティッ
ク装置、マウス装置、或いはキーボード装置から受け取
った入力に基づいて選択的に表示される。
【0312】従って図形的ユーザインタフェースの使用
を介して、曲げオペレータは、種々の中間形状及び最終
パーツの形を、オペレータにより入力された選択された
曲げ順に基づいて見ることができる。再び、オペレータ
はジョイスティックインタフェース、マウスインタフェ
ース及び又はキーボードインタフェースのごとき適宜の
入力装置を通して前記スクリーン上にデータを入力し選
択することができる。曲げオペレータが提案された曲げ
順に満足しない場合には、曲げオペレータは、ステップ
S232に一般的に示されるように曲げプランを最終化
する前に曲げ順を編集する。この曲げ順の編集は種々の
やり方及び方法において実行される。特にこの発明の1
つの側面によれば、ドラッグ及びドロップ編集特性が提
供され図42に示されるようにオペレータは単に、前記
スクリーンの左側或いは右側に提供された中間的パーツ
形状アイコン或いは表示の1つをつかみ且つそれを前記
順番の所望の位置へドロップすることにより選択された
曲げ順を編集する。その後、前記曲げ順に対する曲げオ
ペレータの修正に基づいて前記スクリーン上の前記種々
の中間パーツ形状が修正され、改定された曲げ順に基づ
く中間的曲げ段階を示す。更に前記曲げオペレータの前
記曲げ順のドラッグ及びドロップ編集に基づいて、前記
2次元平面図画像上の曲げ順番号が改定される。
【0313】前記曲げ順が決定された後、オペレータ
は、ステップS236に示すように、格納された工具立
てデータのライブラリから工具を選択することによりど
のタイプの工具立てが使用されるべきであるかを決定す
る。関連する工具立て情報は、工場フロアの曲げオペレ
ータに対して表示され、曲げオペレータが前記ライブラ
リから工具立てを選択するのを図形的に支援するために
表示メニューが提供される。一旦特定の工具が前記ライ
ブラリから選択されると、前記工具に関連するデータが
スクリーン上に表示される。図43は、マニュアル工具
選択のために前記曲げオペレータに対して図形的に表示
される種々の表示メニュー及びデータテーブルの事例を
図示する。図43の例では前記曲げオペレータが前記工
具ライブラリから特定の工具を取り出すのを支援するた
めに、連続的な表示メニュー或いはスクリーン表示が図
形的に表示される。連続的に表示されるスクリーン表示
は前記表示装置上に連続的に表示され(例えばオーバー
ラップする或いはカスケードする態様で)或いはそれは
個々に表示され、そのスクリーンは次の引き続くスクリ
ーン表示が表示される前にクリアされる。一旦特定の工
具が選択されると、その工具に対する特定のデータがテ
ーブルに提供され且つオペレータに表示される。工具ラ
イブラリにおけるデータは、前記ソフトウエアの最初の
セットアップ手続きにおいて、(例えばデータベース3
0の中に)予め定義され且つ可能されている。
【0314】この発明のマニュアル工具選択特性はオペ
レータが工具タイプを選択し且つ各タイプにおいて工具
の形状を選択することを可能とする。例えば、パンチ、
ダイ、ダイホルダ、及びダイレールを含む種々の工具タ
イプが選択される。各タイプは多数の形状からなり、且
つ各形状に対して異なったサイズ及び寸法の多数の工具
が存在する。1つの工具を選択するために、ユーザは、
図43に示されるような、表示される工具タイプアイコ
ンから1つのアイコンを選択することにより1つの工具
タイプをまず特定する。その後ユーザは選択された工具
について利用できる異なる形状のメニューを提供され
る。工具形状を分析した後、ユーザは選択された工具に
ついて、表示された形状アイコンから1つの形状アイコ
ンを選択することにより工具形状を選択する(例えば図
43では、グースネック形状パンチが選択された)。最
後にユーザは選択された工具形状について適当なサイズ
及び寸法を選択する。図43に更に示されるように、選
択された工具形状に対して利用可能な工具の異なるサイ
ズ及び寸法を示すためのテーブルがユーザに対して表示
される。このテーブルから1つの項目を選択することに
より、選択された工具がアイコンとして表示され一般的
な工具タイプアイコンに置き変わり、且つ工具の選択を
確認する。
【0315】ステップS240で、曲げオペレータは次
に図形インタフェースの支援により、プレスブレーキに
おける種々の工具段階(工具ステージ)を設定する。図
44は前記曲げプランにおいて使用される工具セットア
ップ(工具取り付け)の定義を容易にするために曲げオ
ペレータに対して与えられる代表的工具セットアップウ
インドウを図示する。図44に例として示されるよう
に、種々のパンチ、ダイ及びレールのデータが前記ツー
ルセットアップウインドウに表示される。前記板金パー
ツのための工具及びダイの情報はオペレータにより入力
される。ジョイスティックが曲げオペレータのステーシ
ョンモジュールに提供され曲げオペレータが工具位置を
指示し且つ利用可能な工具及びダイのリストから工具及
びリストを選択することを可能とする。この工具セット
アップウインドウにおいてスクリーンの左側は現在の工
具セットアップの断面形状を表し、スクリーンの右側は
プレスブレーキにおける現在のセットアップの位置を表
示する。現在のセットアップの位置は図44に示される
ように強調され或いは影が付けられる。
【0316】最後にオペレータが曲げ順に満足すると前
記工具立て及び曲げシーケンスを含む曲げプラン情報
が、図37におけるステップS242に一般的に示され
るように、前記データベース30の中に前記曲げモデル
と共に保存される。前記曲げ順の実際のテストが、前記
曲げオペレータにより選択された曲げ順を確認するため
にプレスブレーキにより行なわれる。もし必要なら、前
記工具立ての定義或いは曲げ順に対する更なる修正が、
前記ステーションモジュールにおけるオペレータ或いは
デザイナーにより実行される。
【0317】この発明の種々の他の特徴は、前記曲げプ
ランの生成における前記曲げオペレータを支援するため
に設けられる。例えばこの発明の他の側面によれば、工
具立てエキスパートが設けられ、前記曲げオペレータに
対して前記曲げモデルに格納されたパーツ形状及び他の
情報に基づいて、工具立て及び曲げ順の示唆を自動的に
与える。前記工具立てエキスパートからの示唆は当該示
唆の分析の後、曲げオペレータにより改定される。更
に、より複雑な工具立てエキスパートシステムが提供さ
れ、前記曲げファイルにおける前記パーツの形状、及び
潜在的な衝突及び干渉をチェックするための工具の形状
分析に基づいて更に複雑な操作について工具立て示唆及
び曲げ順示唆を行なう。そのようなエキスパートシステ
ムは手動或いはロボットにより支援された曲げ機械装置
により使用され実行される。限定しない例として、この
発明はデービッドAボーン等の名前による「板金曲げプ
ランを生成し且つ実行するための知的システム」と題さ
れる米国特許出願第08−386.369、及びデービ
ッドAボーン等の名前による「ロボットウインドウの計
画/制御の方法」と題される米国特許出願第08−33
8.115号に開示される特徴及び教示により実行され
る。これらの開示はここに全体として参照により積極的
に取り込まれる。上記したように図形的ユーザインタフ
ェース或いは種々の機能は、板金パーツのための曲げプ
ランを生成する際に曲げオペレータを支援するために設
けられる。この発明の他の側面によれば、追加の特徴が
更に設けられ、前記パーツの設計及び製造において支援
を行なう。以下に更に十分に説明するように、音声的或
いは視覚的情報の格納のごとき種々のマルチメディア機
能が本発明において実行され前記曲げプランを生成し或
いは曲げ順を実行する際に曲げオペレータに対して追加
の支援を行なう。更に、中間の曲げ段階の各々において
前記工具及びパーツの間の潜在的干渉及び衝突を自動的
にチェックする衝突チェック機能が提供される。この衝
突チェック機能は、工具形状及び、パーツにおける間隔
の面倒で時間のかかるマニュアルチェックに置き変わる
ために提供される。前記マニュアルチェックは曲げプラ
ンを生成する際曲げオペレータにより通常行なわれる。
これらの機能及びその他のものは添付する図面を参照し
て今から説明される。
【0318】この発明の1つの側面によれば、前記曲げ
モデルデータと共に音声及び映像情報を格納するための
方法が設けられる。種々の音声及び映像情報は、工場フ
ロアにおいて記録され、例えば板金パーツの操作及び曲
げ加工に関連する特殊な指令を提供する。この目的のた
めCCDカメラ又はディジタルカメラが音声マイクロフ
ォンと共に種々の場所10,12,14,…20のステ
ーションモジュールの各々に設けられる。他の装置、例
えばオーディオマイクロフォンを有するビデオカメラが
オペレータ或いはユーザが音声或いは映像の情報を記録
することを可能とするために前記ステーションモジュー
ルに設けられる。前記種々の記録装置は工場フロアにお
けるステーションモジュールコンピュータに接続され
る。限定しない事例としてインテルのPROSHARE
個人会議CCDカメラ(インテル株式会社から入手可
能)が音声及び映像情報を記録するために使用される。
他の商業的に入手可能なCCDカメラ或いはディジタル
カメラもそのような情報を記録するために使用される。
【0319】前記曲げモデルデータと共に格納された種
々の音声及び映像情報は種々の方法及び手続きにより、
ユーザによりアクセスされ且つ読み出される。例えば格
納された音声及び映像情報を再生するために、前記ステ
ーションモジュールによりメニューオプションが表示さ
れる。更に、この発明の好適な実施例によれば、オペレ
ータは、観察ウインドウに表示されるアイコンを選択し
且つ生成することにより、格納されている音声及び映像
情報を種々の表示スクリーン及びパーツの図に付随させ
る能力を有する。この機能は、ソフトウエア及びオブジ
ェクト指向プログラム技術により実行される。これによ
りアイコンオブジェクトは曲げモデルデータ構造の中に
生成され且つ格納される。このアイコンオブジェクト
は、ある種の条件(例えばマウスのダブルクリック或い
はジョイスティック或いは他の入力手段の使用による選
択の指示によるオペレータによるアイコンの選択)に基
づいてメモリから付随された音声及び映像情報を読み出
すための手続きを含む。この発明のアイコンの特徴によ
りオペレータは異なる音声及び映像メッセージ或いは情
報を前記板金パーツの異なる部分及び任意の表示に関連
させる。このアイコンを前記パーツの表現に組み込むこ
とにより、前記アイコンは、スクリーン上で画面が変わ
るにつれて前記パーツの2次元及び/又は3次元モデル
の表示と共にズームし、回転し並進運動するように構成
される。
【0320】図45は前記パーツの3次元ソリッドモデ
ルに張り付けられたアイコンの使用を介して音声及び映
像情報を添付する事例を図示する。ユーザが前記音声及
び映像情報を記録した後、オペレータが前記3次元モデ
ルウインドウの任意の位置にアイコンを張り付ける。前
記アイコンがオペレータ或いはユーザにより次に選択さ
れる時、格納された音声及び映像情報は再生され、前記
ウインドウに表示され、そのアイコンが配置された前記
パーツのある部分或いは領域に関する特殊な指令又はメ
ッセージを提供する。他の情報、例えば前記曲げ運動の
シミュレーション或いは記録は前記パーツの種々の曲げ
線の近傍にアイコンを置くことにより前記パーツに関連
される。前記曲げ運動に関連する映像情報は次に前記ア
イコンが選択される時ユーザに対して再生される。
【0321】オペレータ或いはユーザは、音声及び映像
情報を記録し、或いは単に1つの音声メッセージ或いは
静止或いは運動映像信号を記録し、それらはユーザに対
して選択的に再生される。前記ウインドウ表示に対して
付着されたアイコンは格納された情報のタイプを図形的
に指示する(例えば、音声情報が格納されていることを
示しているためにマイクロフォンのアイコンが表示され
又は映像情報が格納されていることを示すために表示モ
ニタのアイコンが表示される)。特殊なアイコンは、そ
のアイコンに音声及び映像情報が関連されていることを
示すために設けられる(例えば「A/V」の記号或いは
マイクロフォンを含むビデオカメラのアイコン)。アイ
コンの一覧が設けられ且つ表示され、ユーザが、前記ス
クリーン表示或いは画像に対して音声及び或いは映像情
報を添付する際に種々のアイコンから選択することを可
能とする。
【0322】図46は格納された音声及び映像情報を読
み出すためのアイコンを組み込んだ表示ウインドウの他
の事例を図示する。図46に表示された表示ウインドウ
は、図42を参照して上で説明したそれのごとき、工具
セットアップスクリーン画像に関連する。図46の例で
は、音声情報が格納され、マイクロフォンのアイコンに
より読み出される。そして別個の映像情報が格納され、
前記表示ウインドウに対してビデオアイコンを張り付け
ることにより読み出される。前記音声及び映像情報は工
具セットアップ或いは操作に関連する特殊な指令或いは
情報に関連する。更に現在活性化されているウインドウ
表示のタイプに関係なく、オペレータは、異なる音声及
び映像情報を後に読み出すために、前記ウインドウ表示
における種々の領域に必要なだけ多数のアイコンを張り
付けることができる。
【0323】この発明の他の側面によれば、画像編集ウ
インドウ特性が提供され、オペレータが格納された画像
を選択しそれらを異なるスクリーンへ適用するのを容易
にする。前記画像編集ウインドウ特性はウインドウに基
づくアプリケーションとして提供され、それは例えばサ
ーバモジュール32或いは製造設備を通して設けられた
ステーションモジュールのいずれかにおいてアクセスさ
れる。図47は、この発明の教示により実行される画像
編集(イメージ編集)ウインドウの例を図示する。前記
イメージ編集ウインドウに表示される画像はディジタル
カメラ或いはCADコーダによる画像写真を含む。前記
スクリーンに表示される画像はオペレータにより(例え
ばマウス或いは他の適当なデータ入力手段により)選択
的に選ばれ、他のスクリーンにコピーされ、それらはパ
ーツの特定のモデルの図に関連させられる。オペレータ
は次にその画像或いはアイコンを前記モデルのウインド
ウ(例えば図46に関連して上で示したそれのごとき前
記パーツの3次元ソリッドモデルウインドウ)へ張り付
ける。図45、46及び47の画像は実際のスクリーン
画像の写真再生である。実際の画像イメージは、使用さ
れるカメラ或いはスクリーンの解像度に応じてそれ自体
更に明瞭である。前記画像は例えば、曲げ操作に関連す
る特殊な操作或いは他の指令を議論し或いは図示する曲
げオペレータの静止或いは運動映像イメージを含み、或
いは板金曲げ操作の映像イメージである。換言するば、
有用であると思われる実際の画像が取られ後に表示され
る。従って図45−47に示される実際の画像は例示的
な目的のためのみのものである。
【0324】図48及び49を参照するに、この発明の
衝突チェック機能の例が設けてある。この発明の1つの
側面によれば、衝突チェック機能が設けられ、ユーザは
前記パーツ及びパンチ工具の間の潜在的な衝突を、図形
的ユーザインタフェースの使用によりチェックすること
を可能とする。前記衝突チェック機能はウインドウズに
基づくアプリケーションであり、前記製造設備における
任意のステーションモジュール或いは場所でアクセスさ
れる。この発明の自動的衝突チェック機能は、前記曲げ
プランを生成する際に通常行なわれている伝統的なそし
て面倒なマニュアルの形状チェックに変わり曲げオペレ
ータにより使用される。
【0325】伝統的には、板金パーツの曲げプランを生
成する際、曲げオペレータはまず前記パーツの曲げ順を
決定する。前記曲げ順は前記板金パーツが製造の間に曲
げられる順番或いは態様を決定する。その曲げ順が決定
された後、曲げオペレータはその曲げ操作の各々を実行
するために使用される工具を選択し定義する。この過程
で、選択された前記工具の形状及び前記パーツの中間的
形状が、前記曲げ工程の各々を実行する際に前記工具と
パーツとの間の干渉あるいは衝突が存在しないことを確
実にするために解析される。衝突或いは干渉が検出され
る場合には、選択された工具のタイプ(或いは必要に応
じて曲げ順)は、前記工具と板金パーツとの間の干渉或
いは衝突を生ずることなく曲げ操作が実行されるように
修正されなければならない。
【0326】潜在的な衝突或いは干渉を検出する際に、
前記工具の形状と板金要素の曲げられた部分或いは形状
との間のクリアランスを分析するために、曲げオペレー
タは伝統的にマニュアルの方法に頼っていた。典型的に
は、曲げオペレータにより工具形状のモデルが構成され
使用されている。工具形状モデルは、板金の種々の中間
的形状の工学的或いは技術的図面(前記工具形状モデル
と同じスケールの寸法を有する)に対してマニュアルで
合わせられ或いはその上に置かれる。この工具形状モデ
ルを前記パーツの図面に対して適合させ及び合わせるこ
とにより前記曲げオペレータは、曲げ工程の各々におい
て工具とパーツとの間に十分な空間或いはクリアランス
があるかどうかを決定することができる。しかしながら
この工程は面倒で且つ時間を浪費する傾向がある。
【0327】この発明は自動的干渉チェック機能を設け
ることにより、そのような伝統的な方法の不利益を克服
することである。この発明の干渉チェック機能は、図形
的ユーザインタフェースを介して実行され、曲げオペレ
ータが所定の曲げ順における各中間的工程において衝突
をチェックするのを可能とする。図48及び49は図形
的ユーザインタフェースを介して実行される衝突チェッ
ク機能の例を図示する。活性化される時、前記衝突チェ
ック機能は前記曲げ順における前記パーツの各中間的形
状とその順番に対して定義されるパンチ工具或いは複数
の工具との間の衝突を自動的にチェックする。前記中間
形状はスクリーンに表示され(例えば図48及び49を
見よ)、衝突が発見されると、当該衝突が検出される工
程がスクリーン上に強調される。更にテキストのごとき
他の表示示唆が検出された衝突の数を指示するために提
供される。図48及び49の例では、前記衝突情報は表
示ウインドウの右上領域に提供される。更に、前記衝突
がチェックされたパンチ工具或いは複数の工具のタイプ
は表示ウインドウの左上領域に表示され或いは指示され
る。
【0328】衝突が、オペレータにより選択されたパン
チ工具について検出される時、衝突が検出される中間的
形状或いは段階がスクリーン上に強調される。この場
合、オペレータはその特定の曲げ段階について他のパン
チ工具を選択することもでき、前記パンチ工具の第2の
選択について衝突が起きるか否か決定するために前記衝
突チェック機能が再び実行される。オペレータは、各曲
げについてパンチ工具を選択し、前記衝突チェック機能
により衝突をチェックすることができる。ドラッグ及び
ドロップ編集が、中間的曲げ形状をドラッグし、それを
前記提案された曲げ順内の所望の位置へドロップするこ
とにより、前記ウインドウ表示中に表示された曲げ順を
オペレータが変更することを可能とするように設けられ
てもよい。前記曲げ順は図44を参照して上に記載した
それと同様の対応で、オペレータによりなされた前記ド
ラッグ及びドロップ編集に基づいて修正される。
【0329】この発明の衝突チェック機能を実行するた
めに種々の手続き及び操作が使用される。例えば潜在的
な衝突を検出するために、選択された工具の幾何形状と
中間的形状におけるパーツの幾何形状とがアクセスされ
る。各中間工程における前記パーツに関連する幾何形状
データは前記曲げ順及びパーツ寸法及びトポロジーデー
タに基づいて生成される。前記パーツの各フランジは、
前記曲げ順における各中間段階における前記パーツを表
示するために、曲げデータ(例えば曲げ角度、曲げ線位
置、縮小量等)に応じて折り曲げられる。上記折り曲げ
工程及びこの発明の縮小量補償特性は各中間段階での前
記パーツに対する幾何形状データを生成する際に適用さ
れる。この工具及びパーツの幾何形状により、前記曲げ
段階の各々において前記工具の先端をパーツの曲げ線へ
置くことにより、前記工具及びパーツが相互に配向され
る。衝突は、前記幾何学的データ及び前記工具とパーツ
との境界を分析し、前記工具及びパーツにおいて共通な
点或いは重なり合う点が存在するか否かを決定すること
により検出される。衝突は、特定の曲げ工程で検出され
る時、その工程は、ユーザに対して衝突の検出を示すた
めにスクリーン上で強調される。衝突を検出するために
使用される工具データは、ユーザによりなされる工具選
択に基づいて、工具形状ライブラリから積極的に取り出
される。任意の中間曲げ工程での衝突の再計算は異なる
工具形状或いは曲げ順の修正に基づいて行なわれる。そ
のような機能を設け、ここに記載されるごとき、図形的
ユーザインタファースを用いてそのような情報を表示す
ることにより、衝突の可能性は、曲げオペレータによ
り、より容易に決定され且つ修正される。
【0330】上記したように、ジョイスティック或いは
マウス装置は、板金パーツの表示されるモデルを観察す
る際、ユーザが選択的に種々の観察機能(例えばズー
ム、パン、回転等)を活性化し及び制御することを可能
とするために、前記製造設備を通して前記ステーション
モジュールの各々及びそれらの場所に設けられる。前記
ジョイスティック装置は多重の軸を有するジョイスティ
ックで、選択或いは制御ボタンを有する。前記ジョイス
ティックはマイクロソフト・サイドワインダ・ジョイス
ティックを含む種々の商業的に入手可能なジョイスティ
ック装置を介して実行され、各ステーションモジュール
及び/又は当該設備の他の位置のコンピュータのゲーム
ポートに差し込まれる。前記マウスはまたウンドウズ9
5或いはウインドウズNTのごとき任意の商業的に入手
可能なマウスをサポートするソフトウエア及び、各設備
位置におけるコンピュータのゲームポート或いはマウス
ポートに差し込まれる任意の商業的に入手可能なマウス
装置により実行される。
【0331】限定しない事例として図50−55は、ジ
ョイスティック装置或いはマウス装置を用いて、3次元
幾何学的形状を操作し且つ前記パーツを表示するための
システムの種々の側面を図示する。この発明の3次元ナ
ビゲーションシステムは、ユーザが回転、ズーミング及
びパンニングのごとき種々の観察機能を制御することを
可能とする。この発明の1つの側面によれば、システム
はまた3次元モデルを観察する際に、現在のズーム画像
に基づいて計算される動力学的回転軸を用いる。この側
面によれば、回転の中心は現在の図及びズーム比或いは
係数に基づいて動力学的に変化され且つ計算され、従っ
て前記パーツのズームされた領域は前記パーツが例えば
高いズーム比或いは係数において回転される時、前記ス
クリーンから消えることがない。
【0332】この発明の1つの側面によれば、3次元操
作及びナビゲーションシステムが前記設備のステーショ
ンモジュール及び/又はサーバモジュールに提供され
る。3次元ナビゲーションシステムの工程及び操作は、
ソフトウエア或いはプログラムされた論理を介して且つ
広い範囲のプログラム言語及び教示の1つを用いて実行
される。例えば前記システムはC++のごとき高レベル
のプログラム言語を用いて且つオブジェクト指向プログ
ラム技術を用いて実行される。更に限定しない例とし
て、VISUAL C++が使用される。それはウィン
ドウズに基づくアプリケーションのためにマイクロソフ
ト株式会社により提供されるC++プログラム言語の1
つのバージョンである。前記観察機能(例えばズーム、
回転、パン等)は上記した本発明の曲げモデルビューア
の観察クラスの要素機能として実行される(例えば図2
7及び上記関連の開示を見よ)。前記現在ズーム係数及
びパーツの位置(例えば3次元空間におけるパーツの位
置)に関する情報は、また、前記動力学的回転軸を計算
し且つ所望の観察機能を提供するために前記曲げモデル
ビューアからアクセスされる。
【0333】種々のハードウエア成分及びインタフェー
スが、本発明の3次元ナビゲーションシステムを実行す
るために提供される。例えばシステムを実行するために
使用されるソフトウエアが前記ステーションモジュール
及びサーバモジュールのコンピュータ或いはパーソナル
コンピュータに設けて有り或いは存在する。上で議論し
たように、前記コンピュータ或いはパーソナルコンピュ
ータは、板金パーツの3次元表示をユーザに対して表示
するために、高解像度モニタのごとき図形カード及び表
示スクリーン或いはターミナルを含む。前記コンピュー
タ或いはパーソナルコンピュータはまた、前記マウス或
いはジョイスティック装置と接続し及びインタフェース
するためのマウス或いはゲームポートアダプタを含む。
商業的に入手可能なソフトウエアも設けられており、ユ
ーザにより操作されるマウス或いはジョイスティック装
置からマウス或いはゲームアダプタカードにより受信さ
れる指令信号を解釈する。
【0334】図50a及び50bは、例えば単純な3次
元箱形状パーツを回転するために多重軸ジョイスティッ
ク112により行われる回転機能の例を図示する。上に
述べたように、ジョイスティックは設備を通して設けら
れているステーションモジュール及び/又はサーバモジ
ュールに設けられているコンピュータ或いは装置に設け
られ且つ接続されている。図50a及び50bに示すよ
うに、前記パーツの回転は、前記ジョイスティック11
2を前後に且つ左右に移動することにより行なわれる。
前記回転軸の方向或いは向きは前記ジョイスティック1
12(或いはマウス)の移動に基づいて設定される。例
えば前記ジョイスティック112を前後に移動させるこ
とは、パーツを前記X座標軸に沿って定義される回転軸
の周りに時計方向或いは反時計方向に回転させることを
もたらす(例えば図50aを見よ)。更に前記ジョイス
ティック112を左右に動かすことは、前記パーツを前
記Y座標軸に沿って定義される回転軸を中心として時計
方向或いは反時計方向に回転させることをもたらす(例
えば図50bを見よ)。
【0335】現在の図のズーム比或いは係数が低く、パ
ーツの全体表示がスクリーン上に提供される時、前記回
転軸は前記パーツの幾何学的中心或いは図芯を通るよう
に定義される。上記したように、前記ズーム係数及びス
クリーン上のパーツの観察可能性は、本発明の曲げモデ
ルビューアにより提供される観察可能性機能に基づいて
決定される。スクリーン上にパーツ全体が表示されると
判断される時(図50a及び50bにおけるそれのよう
に)、回転軸を定義しそしてその回転軸を前記パーツの
幾何学中心へ設定するために座標幾何技術が用いられ
る。前記パーツの回転は、次に、前記ジョイスティック
装置のユーザにより定義された移動に基づき、且つこの
発明の曲げモデルビューアの回転要素観察機能を介して
実行される。
【0336】しかし仮に前記オブジェクトの一部のみが
画面に表示され、前記パーツの幾つかの部分は見えない
場合(例えば高いズーム係数或いは比率が選択された
時)、前記回転軸は、前記パーツの幾何学中心或いは図
芯に維持されるべきではない。それはそのようにするこ
とは、回転中に前記パーツのズーム化された部分がスク
リーンから消えるからである。実際この発明によれば、
ズーム比が増大される時、回転軸は動力学的に再計算さ
れ、前記スクリーンのセンターにおける観察点(或いは
カメラ視野)に最も近い点の座標を通る。前記ズーム係
数の変化に基づいて、前記回転軸を動力学的に再計算す
ることにより、前記パーツは、前記パーツの観察可能な
部分が回転の間に画面からはみ出すことにならない軸を
中心として回転される。
【0337】前記3次元モデルのズーミング及びパンニ
ングを行なうために、前記ジョイスティック或いはマウ
ス装置と別個に或いはそれと共に設けられたキーパッド
に追加の制御ボタンが設けられる。例えばズームボタン
114を押すと共に、ジョイスティック112を前後に
移動することにより、図51に示すように、所定の割合
で前記パーツはズームインまたはズームアウトされる。
上記したように、前記回転軸は各ズームウィンドウの中
で再計算され、回転がなされる時、ユーザが前記パーツ
のズーム化された部分を観察することができるようにす
る。更に、3次元形状のパンニングは、図52に示すよ
うに、パンボタン116を押圧し或いは活性化し且つジ
ョイスティック112を移動することにより、ユーザに
より制御される。前記ズームボタン114の場合と同様
に、パンボタン116は前記設備の種々の位置の各々に
おける前記ジョイスティックまたはマウス装置と別個に
或いはそれらと一緒に設けられたディジタル入力パッド
の上に設けてある。
【0338】この発明の代表的な実施例に応じて、前記
3次元ナビゲーション及び操作を実行するために設けら
れた種々の工程及び操作が図53−55を参照して以下
に記載される。上に示したように、前記3次元ナビゲー
ションシステムの必要な工程及び操作はソフトウエア或
いはプログラムロジック及びハードウエア成分及びイン
タフェースの組み合わせを介して実行される。ジョイス
ティック或いはマウス装置のごときユーザにより制御さ
れる装置からの入力信号は所望の表示されたパーツの運
動及び再配向の量を決めるように解釈される。この発明
によれば、表示されたパーツの回転軸は、回転中にパー
ツのズーム化された領域が画面から消えるのを防止する
ため、現在の画面及びズーム係数に基づいて動力学的に
計算される。
【0339】表示されたパーツの現在の画面を更新する
際に、図53のステップS301に一般的に示されるよ
うに、前記ジョイスティック或いはマウス装置の操作に
基づいてユーザからの信号が受信される。ユーザにより
前記ジョイスティック或いはマウス装置の特定の方向の
運動及び/又は特殊な制御ボタンの活性化との組み合わ
せが、所定の観察機能(例えば回転、ズーム、パン等)
及び表示されたパーツの所定の方向(例えば時計回り或
いは反時計回り、ズームイン又はズームアウト、右又は
左等)の運動を、図50−52に例えば示されるよう
に、引き起こす。受信された信号は、それらがジョイス
ティックからであるかマウス装置であるかを問わず、カ
ーソルの移動に写像され、ユーザにより所望されるスク
リーン上の移動量を決定する。ユーザが前記観察機能モ
ードのうちの1つに存在しない場合(例えばユーザがス
クリーン上の情報を選択しているか或いはダイアログボ
ックス或いはウィンドウ内の情報を観察している場
合)、前記受信した信号の写像は要求されない。
【0340】当業者により理解されるように、通常のジ
ョイスティック或いはマウス装置から受信される信号は
スクリーン空間のそれとは異なる座標或いは参照システ
ムに基づいており、従ってそれらは前記スクリーン上の
カーソル移動に関する意味のある情報を提供するために
翻訳されなければならない。従って前記ユーザからの入
力信号を受け取った後、ステップS303に示されるよ
うに、回転軸の計算及び表示されたパーツの現在の図を
更新する前に受信された信号はカーソル移動に写像され
る。
【0341】ユーザにより制御される装置からの入力信
号をスクリーン空間上のカーソル運動に翻訳及び写像す
るために異なる方法及び工程が使用される。伝統的に
は、マウス装置の移動は、商業的に入手可能なソフトウ
エアによりカーソル移動へ翻訳され且つ写像されてい
た。例えばウィンドウズ95及びウィンドウズNTは、
マウス移動をカーソル移動へ翻訳するためのソフトウエ
アルーチンを含む。従って、マウス装置の移動は、その
ような商業的に入手可能なソフトウエアによりカーソル
移動に写像される。しかしながらユーザにジョイスティ
ックインタフェースが与えられている場合、有用な情報
を提供するには、前記ジョイスティック運動もカーソル
運動へ翻訳され且つ写像されなければならない。前記ジ
ョイスティック仮想空間におけるジョイスティックの運
動をスクリーン空間におけるカーソル運動へ写像するた
めに種々の方法及び技術が使用される。例えば、ジョイ
スティックの移動信号は、最終的にカーソル運動へ写像
される前に、まずマウス運動へ加工され且つ翻訳され
る。或いは、前記ジョイスティック仮想空間のサイズに
対するスクリーン空間のサイズの比率の関数として、前
記ジョイスティック信号は直接カーソル運動へ写像され
る。
【0342】図54は、この発明の1つの側面に基づ
く、ジョイスティック運動のスクリーン空間内でのカー
ソル運動への写像の例を図示する。上に示したように、
ジョイスティック装置は自身の仮想的座標システム或い
は空間218を含む。前記ジョイスティック仮想空間2
18は、前記ジョイスティックが中心或いは中立位置
(即ちジョイスティックが移動しない位置)に存在する
位置に対応する原点J1を含む。前記ジョイスティック
が新しい位置(例えば図54に示されるように現在の位
置J2)へ移動する時、前記ジョイスティック装置は前
記ジョイスティックの仮想空間内での新しい或いは現在
の位置を示す信号を生成する。前記ジョイスティック仮
想空間218は、しばしばスクリーン空間212よりも
大きい(画素の意味で)ので、前記ジョイスティックの
仮想座標及び移動は、所望のカーソル移動従ってスクリ
ーン上でのパーツの移動を決定するためにスクリーン座
標へ翻訳されなければならない。
【0343】前記ジョイスティックの仮想座標移動をス
クリーン座標移動へ写像し且つ翻訳するために種々の方
法及び工程が使用される。例えば、前記ジョイスティッ
ク仮想空間サイズに対するスクリーン空間サイズの比率
に基づいて、ジョイスティック運動はスクリーンカーソ
ル運動へ写像される。より詳細には、観察機能モード
(例えばズーム、回転、パン等)が活性化され、ジョイ
スティック装置がユーザにより操作された時、前回の点
C1から現在の点C2へのカーソルの実際の移動は次の
式で決定される。
【0344】 現在の点=前回の点+(スケール係数x V) ここに「現在の点」はカーソルの現在の点C2であり、
「前回の点」は前記カーソルの前回の点C1であり、
「スケール係数」はジョイスティック仮想空間サイズに
対するスクリーンサイズの比であり(いずれも画素にお
いて)、「V」はジョイスティック原点J1からジョイ
スティック現在位置J2へのジョイスティックの運動及
び方向を表すベクトルである。従ってジョイスティック
運動をカーソル運動へ写像するために、ジョイスティッ
ク装置がユーザにより操作される時ジョイスティック装
置から受け取られる信号に基づいて、前記原点J1から
現在位置J2へのジョイスティックの方向及び運動を示
すベクトル「V」が最初に計算される。このベクトル
「V」が計算された後、前記ジョイスティック運動は、
前記方程式における前記ベクトル「V」量及び前記「ス
ケール係数」量を用いてカーソル運動へ写像される。即
ち、前記カーソルの新しい或いは現在の位置C2は、前
記ベクトル「V」に前記ジョイスティック空間サイズに
対するスクリーンサイズの比(即ちスケール係数)を掛
け合わせ、次にこの計算の結果を以前のカーソル位置C
1に足し合わせることにより計算される。
【0345】前記スケール係数に応じて、前記スケール
或いは運動の割合を所定の或いはユーザにより選択され
た調整係数だけ増大し又は減少することが必要となる。
そのような場合には、そしてユーザの好みにより、前記
スケールの割合を増大し又は減少するために、前記カー
ソルの現在位置を計算する時に、前記スケール係数に調
整係数が掛けられる。例えば、前記ジョイスティック空
間サイズに対するスクリーンサイズの割合がスケール係
数1/64を与える場合、ジョイスティックの運動とス
クリーン上の表示されたパーツの運動の割合との間の一
層満足できる関係を与えるために、スケールの割合を増
大するのが望ましい。限定的でない例として、スケール
係数1/64について、前記表示されたパーツをズーム
し或いは回転する際調整係数3が用いられる。更にスケ
ール係数1/64について、表示されたパーツのパンニ
ングが行なわれる際には調整係数6が使用される。勿
論、スケーリング(縮尺)の割合は、ユーザの特定の必
要に基づいて修正され、前記調整係数は予め決定され或
いはユーザが、前記スケールの割合を修正するための調
整係数を調整或いは選択するためにオプションを与え
る。更に上に議論した事例において示したように、前記
調整係数は複数の観察機能の各々について同じ量に設定
されてもよいし、前記観察機能の各々について、同じ或
いは異なる量に個別に設定されてもよい。
【0346】受信された信号が適当に写像され翻訳され
た後、前記パーツの回転軸が、図53のステップS30
5に一般的に示されるように動力学的に計算される。前
記パーツの現在の図に依存して、前記パーツが例えば高
いズーム比率或いはファクターで回転される時、前記パ
ーツのズーム化された領域がスクリーンから消えないよ
うに、前記回転軸は前記パーツの中心を通るか或いは他
の点を通るか決定される。現在のズーム図に基づいて、
前記パーツの回転軸を動力学的に再計算するために種々
の方法及び工程が使用される。この発明の他の側面に応
じて、図55は前記パーツの図がユーザにより修正され
た時常に前記回転軸を計算するために行なわれるプロセ
ス及び工程の代表的論理フロー及び手順を図示する。
【0347】図55に示されるように、現在のズーム係
数或いは比率及びパーツの位置及び現在の図がステップ
S311及びS313で決定される。ユーザにより選択
された表示パーツのズーム係数及び向きが、パーツ全体
をスクリーン上で観察可能にする(即ち全体図)か、或
いは前記パーツの一部のみをスクリーン上で観察可能に
する(即ち部分図)。従って現在のズーム係数及びパー
ツの向きが、表示パーツの回転軸を適正に設定するため
に定められなければならない。前記パーツの現在の図を
決定するために種々の方法及び工程が使用される。上に
記載したように、観察可能性機能は、本発明の曲げモデ
ルビューアを備え、表示される画像に対する変更が存在
する場合には何時も、現在の図の向き及びズーム比率の
状態を維持しそして更新する。前記曲げモデルビューア
に対する機能コールがなされ、前記パーツのどの点或い
は部分が現在観察可能であるかを決定する。スクリーン
上に前記パーツの全てが表示されているかどうかは画像
体積をパーツの境界基本線サイズと比較することにより
決定される。
【0348】ステップS315でパーツの全体図が現在
スクリーン上で観察可能であると決定される場合には、
ステップS317で前記回転軸は前記パーツの中心を通
るように設定される。全体図が存在する時、前記パーツ
の中心を前記回転軸が通るように設定することは可能で
ある。というのは全体が表示されたパーツはユーザによ
り回転される時スクリーン上で観察可能であるからであ
る。スクリーン上で全てのパーツが観察可能である時、
回転軸はパーツの幾何学中心或いは図芯を取るように定
義される。従来の座標幾何学技術が、前記パーツの幾何
学中心へ前記回転軸を定義し設定するために用いられ
る。更に前記回転軸の方向は、前記前回のカーソル位置
から現在のカーソル位置へのベクトルに直交するベクト
ルとして定義されることもできる。
【0349】ステップS315で、スクリーン上にパー
ツの部分図のみが現在観察可能であると判断される場
合、ズーム化されたパーツがユーザにより回転される時
表示されたパーツの一部がスクリーンから消えないよう
にするために、回転軸を計算するために、前記論理フロ
ーはステップS319−S325へ引き続く。上記した
ように、ユーザにより高いズーム係数が選択され前記パ
ーツの一部のみがスクリーン上に表示される時、前記回
転軸は、前記パーツの幾何学中心を通るように設定され
てはならない。というのは、そのようにすることは、回
転中に表示されたパーツのズーム化された部分(ズーム
アップされた部分)がスクリーンから消えるからであ
る。パーツの表示された部分がスクリーンから見えなく
なり或いは消えることを防止するために、スクリーンの
中心における観察点(即ちカメラ)に最も近い点の座標
を前記回転軸が通るようにされなければならない。その
ような場合、回転軸の向きは前回のカーソル位置から今
回のカーソル位置へのベクトルに直交するベクトルとし
て定義されても良い。
【0350】従ってステップS319で、スクリーンの
中心が決定され、カメラに最も近いスクリーンの中心に
おけるオブジェクト或いは前記パーツの部分が選択され
る。即ち、スクリーンのセンターに位置する表示パーツ
の部分及びカメラに最も近い或いはスクリーンのユーザ
の観察点に最も近い表示パーツの部分が取り出される。
ステップS321で、前記カメラにおけるオブジェクト
が存在すること(例えば前記スクリーンの中心に位置し
且つ前記カメラに最も近い前記パーツのソリッド部分が
存在すること)が決定される場合、ステップS325で
前記回転軸は前記取り出された点を通るように設定され
る。上記したように、回転軸の方向は前回のカーソル位
置から今回のカーソル位置へのベクトルに直交するベク
トルとして定義されても良い。
【0351】ステップS321でカメラにおけるオブジ
ェクトが存在しない(例えば前記パーツは前記スクリー
ンの中心に位置し且つ前記カメラに最も近い穴或いは開
口部を含む)と判断される場合、論理フローはステップ
S323へ引き続く。ステップS323で、前記回転軸
は前記スクリーンの中心(例えば前記スクリーンの物理
的中心のX及びY座標)を通り且つ前記パーツの幾何学
中心に等しいZ座標(深さ)にあるように定義される。
従って回転軸は前記X,Y,Z座標を通るように設定さ
れ、回転軸の向きは前回のカーソル位置から今回のカー
ソル位置へのベクトルに直交するベクトルとして定義さ
れても良い。
【0352】図53を再び参照するに、前記動力学的回
転軸が決定された後、選択された観察機能(例えばズー
ム、回転、パン等)がステップS307で呼び出され
る。上記したように3次元操作システムの種々の観察機
能は前記曲げモデルビューア観察クラスの要素機能とし
て定義され実行される(例えば図27及び関連する上記
開示を見よ)。そのような場合、ユーザにより選択され
た観察機能に基づいて、機能コールが前記曲げモデルビ
ューアになされ、ステップS309で表示されたパーツ
の現在の図が更新される。前記パーツの現在の図及び向
きは、ユーザにより選択された観察機能及びユーザによ
り操作された入力装置(マウス或いはジョイスティック
装置)からの受信された写像カーソル運動に基づいて更
新される。オープンGL或いはレンダウェアのごときグ
ラフィックパッケージが、ユーザに提供される現在の図
の更新を容易にするために提供される。図53及び55
の代表的フローチャートにおいて行なわれる論理フロー
及びプロセスはソフトウエアにより及び広い種類のプロ
グラム言語及び技術を用いて実行される。例えばオブジ
ェクト指向プログラム技術及びC++が前記プロセス或
いは操作を実行するために使用される。この発明の3次
元操作システムを実行するための代表的コードが付録L
に提供される。代表的コードはC++プログラム言語で
書かれ、前記動力学的回転軸を計算するための種々の工
程及び操作を含む。付録Lのコードにはコメントが提供
され、そこに使用される論理及びアルゴリズムの解析を
容易にする。
【0353】上記3次元操作システムはジョイスティッ
ク装置及び制御ボタンの使用に関して記載されている
が、このシステムは、マウス或いはキーボードを含む他
の特定のタイプの入力手段により実行されることもでき
る。更に図51−52の上記実施例では、前記オブジェ
クトのスクリーンから無限への又はその反対のズーミン
グ或いはパンニングを制限するために境界が定義され
る。というのは連続的なズーミング或いはパンニングは
システムを故障させ或いは破壊させるからである。
【0354】更に、前記ジョイスティックインタフェー
スに関連して種々の他の機能が実行される。例えば、前
記観察機能のいずれかにおける移動は、ジョイスティッ
クがジョイスティックセンター位置から所定の範囲或い
は距離を越えて移動されなければ実行されない。パーツ
の移動が許される前にそのようなジョイスティックの移
動のしきい値を要求することは、前記中心点からの前記
ジョイスティックの不注意な操作或いは押圧に基づい
て、表示されたパーツの偶然の移動の発生を防止する。
ユーザとのジョイスティックインタフェース及びシステ
ム相互作用を改善するために他の機能がまた設けられ
る。例えばユーザによるジョイスティックの単一の操作
に基づいて、前記観察機能(例えばズーム、回転、パン
等)のいずれか1つにおける連続的或いは増加的(例え
ばステップごと)の移動が提供される。前記連続的或い
は増加的移動の選択はまた単一の方向におけるジョイス
ティックの移動の量或いは時間に基づいて提供される。
必要ならば表示されるパーツのスケール或いは移動の割
合は、任意の方向におけるジョイスティックの運動の程
度或いは時間に基づいて増加される。上記した速度調整
係数の修正はまた、ユーザが前記スケールの比率を増加
し或いは減少するために、マニュアルで調整係数に対す
る補正を入力することを可能とすることにより実行され
る。
【0355】工場における部品の設計及び製造における
支援を行なうために、本発明において種々の他の機能及
び実施例が実行される。例えば各顧客のオーダに関する
情報を追跡し且つアクセスするためにバーコードシステ
ムが実行される。所定の参照番号或いは作業番号を有す
るバーコードが顧客により注文される各部品へ割り当て
られる。このバーコードはデータベース30にアクセス
し作業情報を読み取るために用いられる。ユタ、サンデ
ィにおけるゼブラテクノロジVTIからのバーコード・
エニシング・バーコードSCAN CCDセンサのごと
きバーコードリーダ或いはスキャナが各場所に設けら
れ、ユーザが前記サーバモジュール或いはステーション
モジュールにおいて所定の作業のためのバーコードをス
キャンすることを可能にし、またデータベース30に格
納されているそのパーツに付随する重要な設計及び製造
情報をアクセスし読み出すことを可能にする。前記バー
コードリーダは各ステーションモジュール及び/或いは
サーバモジュールのコンピュータに差し込まれている。
前記バーコードは任意の通常のバーコードフォーマット
に基づいてフォーマット化されている。例えばUPS−
A CODA BARCODE39 EAN/JAN−
8或いはPLESSEYである。そして結果としてのバ
ーコードナンバーはルックアップテーブルに基づいて翻
訳され、前記データベースから作業情報を読み出すため
に、対応する作業参照番号及び/又はファイル名を検出
する。或いは、前記作業番号は、工場全体にわたって存
在する任意のステーションにおいて表示される指示へタ
イプ入力され或いはそこから選択され、瞬時にユーザの
位置で作業情報を読み出し表示する。そのような情報を
瞬時に読み出す能力は、コミュニケーションネットワー
ク26の使用及びデータベース30のごとき中央に位置
するデータベースへの前記デザイン及び情報の格納によ
り支援される。
【0356】この発明の更に他の側面によれば、作業を
スケジュールし割り当てるための装置及び方法が提案さ
れるシステムに設けられる。従来、製造設備にわたる作
業のスケジュール化及び割り当てはショップ或いは工場
の工場長により行なわれた。工場長は、機械装置の現在
のセットアップ及び利用可能性のみならず現在の仕事の
状態を決定する。これらの情報を集め且つ分析した後、
ショップ或いは工場の工場長はスケジュールを生成し且
つ工場における種々の場所においてなされる作業につい
て割り当てを分配する(例えば工場フロアに分配される
作業スケジュールシートの形態で)。作業のスケジュー
ル割り当ては、各顧客の作業がタイミングの良い形態で
且つ所定の出荷日までに完了することを確実にするため
に行なわれる。作業のスケジュール化及び割り当ての従
来の工程はしかし骨の折れるものであり、通常工場長に
よりマニュアルで行なわれていた。
【0357】この発明の1つの側面によれば、ショップ
或いは工場の工場長がその工場についての作業のスケジ
ュールを立てることを支援するために、作業割り当て及
びスケジュールシステムが設けられている。そのシステ
ムはコミュニケーションネットワーク及びデータベース
30に格納されている曲げモデル情報を利用し、自動的
に必要な情報を集め、従って工場長はより容易に作業ス
ケジュールを生成することができる。このシステムは、
前記サーバモジュール或いは工場にわたって配置されて
いるステーションモジュールにおいてソフトウエア又は
プログラムロジックを介して実行される。スケジュール
されるべき種々の作業を入力することにより、システム
ソフトウエアはデザイン及びパーツ情報を分析し所定の
作業を行なうためにどの機械が最も適しているかを決定
する。この目的のため、工場における機械の現在の状態
及びセットアップが定義され、データベース30に格納
され、作業スケジュールソフトウエアによりアクセスさ
れる。種々の条件に基づいて、表示の形態で、特定の作
業を実行するためにどの機械が利用可能であるか及びど
の機械が他の仕事を実行することができないかを示唆す
る。この点について、特定の作業について機械の利用可
能性をランク付けし且つ提案作業スケジュールを提供す
るテーブルが表示される。前記提案作業スケジュールは
工場長により実行され或いは修正される。作業スケジュ
ールを設定し且つ推薦するために使用される条件は広い
種類の条件を含む。そしてそれは、工場における各マシ
ンの現在のセットアップ、各作業について必要とされる
曲げのタイプ及び工具、及び同じ時間枠或いは時間の間
に実行されなければならない他のタイプの作業を含む。
どの機械が特定の作業を実行できるかを決定するため
に、前記曲げ角度、フランジ長さ及び曲げのタイプを含
む各パーツについての曲げモデルファイルからの情報が
利用される。例えばデータベース30に格納されている
テーブルは前記工場フロアにおけるパンチング及び曲げ
機械の各々の現在のセットアップ及び能力についての重
要な情報を含む。
【0358】提案された作業スケジュールに基づいて、
工場長は、工場の生産及び出力能力を最大限にするため
に、複数の作業を工場全体にわたる種々の場所へ割り当
てる。最後の作業スケジュール或いは割り当ては電子的
に入力されコミュニケーションネットワーク26を介し
て機械の各々へ送られる。
【0359】LEDのごときパイロットランプが曲げ及
び機械装置ワークステーションの各々に設けられ、その
ステーションに作業が割り当てられ転送されたことを指
示し且つ確認する。前記作業割り当て及びスケジュール
は、工場内の任意の位置から瞬時にアクセス可能なサー
バモジュールのファイルに格納される。上記機能に加え
て、その他の機能が、この発明の教示に応じて実行され
る。例えば種々のステーションモジュール或いは位置に
メニュースクリーンが設けられ且つ表示され、ユーザが
この発明の種々の表示及び機能モードを選択するのを容
易にする。例えば図56に示されるそれのごときメイン
のメニュースクリーンが、前記ステーションモジュール
が開始される際にユーザに対して提供される。このメイ
ンメニューウインドウ表示はステーションモジュールに
より提供される利用可能なウインドウ表示及び観察モー
ドの各々のアイコン画像を含む。このメインメニュース
クリーンはメニューボタン(例えばF1キー)が選択さ
れるとき何時でも現れる。ユーザは、強調されたブロッ
クを所望のウインドウアイコンへ移動しそれを選択する
ことによりそのウインドウを選択する。そのような操作
は、キーボード、マウス或いはジョイスティックの使用
を介して行なわれる。
【0360】他のウインドウスクリーンもユーザに対し
て提供され且つ表示され作業情報の入力及び表示を容易
にする。例えばパーツ情報ウインドウは、ユーザがパー
ツ情報を入力し或いは修正するのを可能にするために表
示される。パーツ情報ウインドウ表示の例が図57に与
えられる。このパーツ情報ウインドウは全ての関連する
パーツ情報(例えばパーツ番号、材料タイプ、寸法等)
を含み、板金パーツの2次元平面図及び等測投影法図を
含む。曲げ線情報ウインドウ(例えば図58に示される
もの)は、ユーザが各曲げ線についての曲げ順及び縮小
量を含む種々の曲げ線情報を監視することを可能とする
ために設けられる。前記曲げ線情報ウインドウはユーザ
が、各曲げについての曲げ線情報を入力し或いは修正す
るのを可能とし、板金パーツの2次元平面図及び等測投
影図を含む。
【0361】オペレータの曲げ順の分析を容易にするた
めに、追加のウインドウ表示が提供される。例えば曲げ
順ウインドウ表示及び曲げシミュレーションウインドウ
表示が提供され、前記パーツの種々の曲げ段階を表示
し、且つ曲げ操作中におけるパーツの向きをシミュレー
トする。図59に示されるような曲げ順ウインドウは前
記メインメニュースクリーンから選択され曲げ順の各段
階における前記パーツの(静止状態における)中間形状
をユーザに対して表示する。曲げシミュレーションウイ
ンドウ(例えば図60を見よ)もユーザにより選択さ
れ、曲げ段階の静止情報(スクリーンの右側に提供され
るパーツアイコンの形態で)及び、曲げ順における各段
階で行なわれる位置付け及び曲げの動的シミュレーショ
ン(表示装置の中央において)を提供する。スクリーン
上のパーツアイコンを間欠的に選択することにより、ユ
ーザは選択されたパーツアイコンにより表現される段階
における、曲げ加工中でのパーツの向きの動的シミュレ
ーションを見ることができる。各曲げ順を動的にシミュ
レートするために、パーツは反転され、並進移動され、
曲げ線の周りで曲げられ/回転される。
【0362】図57−60の上記ウインドウ表示の各々
は、図56のメインメニューウインドウ表示からユーザ
に対して選択され且つ表示される。更に、任意のステー
ションモジュールにおけるユーザは、メインメニューウ
インドウ表示において適宜のウインドウアイコンを選択
し、この発明の観察モード(例えば2次元平面、ワイヤ
フレーム、ソリッド、正射図)に応じて表示されるパー
ツの2次元及び/又は3次元表示を得る。これは図28
−31を参照して上で詳細に説明された。種々のメニュ
ーウインドウがまた例えばステーションモジュールに設
けられ、この発明の特性及び機能の操作を容易にする。
図61は2次元から3次元操作のために表示される代表
的メニューを図示する。更に図62はこの発明の2次元
クリーンアップ操作のための代表的メニュー構造を図示
する。この発明はしかしこれらのメニュー配置に限定さ
れるものではなく、他のメニュースクリーン及び/又は
工具アイコンバーが設けられ、ユーザのシステムとの相
互作用を容易にする。
【0363】他の特性もまたこの発明において実行され
る。例えば、高いレベルの自動装置も提供され曲げプラ
ンの生成を容易にする。例えば曲げ及び工具立てエキス
パートシステムが提供され、各作業についてのパーツの
幾何形状及び形状に基づいて工具立てセットアップ及び
曲げ順を生成し且つ提案する。それは例えば米国特許出
願出願番号08/386.369及び08/338.1
15に開示されるようなものである。
【0364】この発明は幾つかの代表的な実施例を参照
して記載されたがここで用いられた用語は、限定の用語
ではなく、記載及び説明の用語である。この発明の範囲
及び精神及び種々の側面から逸脱することなく種々の変
形がなされ得る。この発明はここで特定の手段、材料及
び実施例を参照して記載されたが、発明はここに開示さ
れた特定のものに限定されるように意図されるものでは
ない。むしろ発明は全ての機能的に等価な構造、方法及
び使用に広がる。
【0365】付録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 the
number of errors in the partint face_1, face_2, b
end_1, bend_0, i ;long num_of_faces, num_of_bendli
nes, entity_id;BM_FACE *face;BM_BENDLINE *bend
line;BM_2D_BODY *two_d_body;BM_3D_BODY *three_d_
body;BM_BEND_OP *bend_op;BM_TOPOLOGY_RECORD *top
ology_record;// get name and number of faces and b
endlines of the partpart->get_name( pname ) ;doubl
e thickness = part->get_metal_thickness();num_of_f
aces = part->get_number_of_faces() ;num_of_bendlin
es = part->get_number_of_bendlines();if (num_of_fa
ces == 0 || num_of_bendlines == 0)return ( -1 );//
create local working arrayfacelist = new BENDFACE
[num_of_faces];bendlinelist = new BENDLINE [num_o
f_bendlines];// count number of faces defined.doub
le maxfacearea = -1.0 ;part_maxface = 0 ;part_numf
ace = 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 ;faceli
st[i].facept =NULL ;facelist[i].twodpt = NULL ;fac
elist[i].threedpt = NULL ;facelist[i].topologyrecp
t = NULL ;facelist[i].numadjbody = 0 ;facelist[i].
numadjbend = 0 ;facelist[i].numadjhole = 0 ;faceli
st[i].numadjface = 0 ;facelist[i].face_area = 0. ;
if (face == NULL) break ;two_d_body = face->get_3D
_version() ;if (two_d_body == NULL) continue ;// I
t is considered as a valid face, when its BM_2D_BO
DY exists.part_numface++ ;facelist[i].faceid =part
_numface ;facelist[i].facept = face ;facelist[i].t
wodpt = two_d_body ;facelist[i].face_area = area_o
f_a_2D_body(two_d_body) ;if (maxfacearea < facelis
t[i].face_area) {maxfacearea = facelist[i].face_ar
ea ;part_maxface = facelist[i].faceid ;} three_d_b
ody = two_d_body->get_3D_body() ;facelist[i].three
dpt = three_d_body ;if (three_d_body == NULL) cont
inue;entity_id = three_d_body->get_name() ;facelis
t[i].org_entity = entity_id ;topology_record = thr
ee_d_body->get_adj_list() ;facelist[i].topologyrec
pt = topology_record ;if (topology_record == NULL)
continue ;facelist[i].numadjbody = (int)topology_
record->get_number_of_adjacent_bodies() ;facelist
[i].numadjface = (int)topology_record->get_number_
of_adjacent_faces() ;facelist[i].numadjhole = (in
t)topology_record->get_number_of_adjacent_holes()
;facelist[i].numadjbend = (int)topology_record->g
et_number_of_adjacent_bendlines() ;}if (num_error
> 0) {clean_up ( part_numface, imatrix, nbl_face,
facelist,bendlinelist, bendfacelist) ;return ( num
_error ) ;}if (part_numface == 1) {// this is a tr
ivial case, where the partonly has one flat face.*
inp_part_numface = part_numface ;*inp_parrank =par
t_numface ;*inp_part_numbend = 0 ;*inp_part_maxfac
e = 1 ;*inp_sp = new FENT [2] ;*inp_sp[2] = NullFe
nt ;clean_up ( part_numface, imatrix, nbl_face, fa
celist, bendlinelist, bendfacelist) ;return ( 0 )
;}// varify all the valid face, the current requi
rements are://1) A face cannot be adjacent to anot
her face.//2)A face without an adjacent bendline i
s not allowed.//(Note: The single faced part has b
een processed.)// Also, creata pointer array that
links assigned part_face_id// to the netry in thef
acelist.int *fid_pt = new int [part_numface] ;for
( 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_BEND
LINE *)(bendline->next())) {// initialize the stru
ctbendlinelist[i].bendlineid = 0 ; bendlinelist
[i].bendlinept = NULL ;// BM_BENDLINE pointer bend
linelist[i].bendoppt= NULL ;// BM_BEND_OP pointerb
endlinelist[i].twodpt = NULL ;// BM_2D_BODY poi
nterbendlinelist[i].threedpt = NULL ;// BM_3D_BO
DY pointerbendlinelist[i].topologyrecpt = NULL ;//
BM_TOPOLOGY_RECORD pointerbendlinelist[i].numadjb
ody = 0 ;bendlinelist[i].numadjbend = 0 ;bendlinel
ist[i].numadjhole = 0 ;bendlinelist[i].numadjface
= 0 ; if (bendline == NULL) break ;two_d_body =
bendline->get_3D_version() ;if (two_d_body == NUL
L) continue ;// It is considered as a valid bendli
ne, when its BM_2D_BODY exists.part_numbend++ ;ben
dlinelist[i].bendlineid = part_numbend ; bendlinel
ist[i].bendlinept = bendline ;// BM_BENDLINE point
er bendlinelist[i].twodpt = two_d_body ; // BM_2D_
BODY pointerbend_op = bendline->get_bend_op() ; be
ndlinelist[i].bendoppt = bend_op ;// BM_BEND_OP po
interif (bend_op == NULL) num_error++ ;// Note: Be
nd operation must be defined for each // ben
dline, otherwise it is an error.three_d_body = two
_d_body->get_3D_body() ;bendlinelist[i].threedpt =
three_d_body ; // BM_3D_BODY pointerif (three_d_b
ody == NULL) continue ;entity_id = three_d_body->g
et_name() ;facelist[i].org_entity = entity_id ;top
ology_record = three_d_body->get_adj_list() ;bendl
inelist[i].topologyrecpt = topology_record ;if (to
pology_record == NULL) continue ;bendlinelist[i].n
umadjbody = (int) topology_record->get_number_of_a
djacent_bodies() ;bendlinelist[i].numadjface = (in
t) topology_record->get_number_of_adjacent_faces()
;bendlinelist[i].numadjhole = (int) topology_reco
rd->get_number_of_adjacent_holes() ;bendlinelist
[i].numadjbend = (int) topology_record->get_number
_of_adjacent_bendlines() ;}if (num_error > 0) {cle
an_up ( part_numface, imatrix, nbl_face, facelist,
bendlinelist, bendfacelist) ;return ( num_error )
;}// varify all the valid bendlines, the current
requirements are://1) The total number of bendline
s should not be less than// the totalnumber of
faces minus 1.// 2) A bendline without an adjacen
t face or bendline is not allowed.// 3) A bendline
with more than two adjacent faces and bendlines i
s not allowed.//4)The adjacent face or bendline of
a bendline must bea valid face or// bendline t
hat is defined in the facelist or bendlinelist.//
5) Two adjacent faces, face1 and face2, will be de
fined for each bendline// a) If the bendline ha
s an adjacent faces,then the face’s faceid is use
d// as face1 or face2.//b) If the bendline h
as an adjacent bendline, thena bendline_only_face/
/ will be created inbetween these two bendli
nes. The faceid of the // bendline_only_face will
be used as face1 or face2.//c)If the bendline has
only one adjacent face or adjacent bendline, then
//a bendline_only_face will becreated for this ben
dline. The faceid of// the bendline_only_fa
ce is face2.// maxnewfaces is the maximum number o
f bendline_only_face need to be created// without
encounter error in the part.if (part_numbend> part
_numface-1) num_error++ ; // condition 1if (num_er
ror > 0) {clean_up ( part_numface, imatrix, nbl_fa
ce, facelist, bendlinelist, bendfacelist) ;retur
n ( num_error ) ;}int maxnewfaces = part_numbend +
1 - part_numface ;if (maxnewfaces > 0) {bendfacel
ist = new ARTIFICIAL_FACE [maxnewfaces] ;bendfacel
ist[0].faceid = -part_numface ;}for ( i = 0 ; i <
num_of_bendlines ; i++) {if (bendlinelist[i].bendl
ineid) {bend_0 = bendlinelist[i].bendlineid ;intnu
madj = bendlinelist[i].numadjface + bendlinelist
[i].numadjbend ;if (numadj < 1 || numadj > 2) num_
error++ ; // condition2 & 3else {if (bendlinelist
[i].numadjface > 0) { // condition 4 - firstfaceth
ree_d_body = bendlinelist[i].topologyrecpt->get_fi
rst_face() ;face_1 = find_face_id( three_d_body, f
acelist, num_of_faces ) ;if (face_1 <= 0) num_erro
r++ ;else bendlinelist[i].face1 = face_1 ; }if (be
ndlinelist[i].numadjface == 2) { // condition 4 -
second facethree_d_body = bendlinelist[i].topology
recpt->get_next_face() ;face_1 = find_face_id( thr
ee_d_body, facelist, num_of_faces ) ;if (face_1 <=
0) num_error++ ;else bendlinelist[i].face2 = face
_1 ; }if (bendlinelist[i].numadjbend > 0) { // c
ondition 4 - first bendlinethree_d_body = bendline
list[i].topologyrecpt->get_first_bendline() ;bend_
1 = find_bendline_id( three_d_body, bendlinelist,
num_of_bendlines ) ;if (bend_1 <= 0) num_error++ ;
else {face_1= define_bendline_only_face ( bend_1,
bend_0,bendfacelist, maxnewfaces);if (face_1 <= 0)
num_error++ ;else {if (bendlinelist[i].numadjface
> 0) bendlinelist[i].face2 = face_1 ;else bendli
nelist[i].face1 = face_1 ;}}}if (bendlinelist[i].n
umadjbend == 2) { // condition 4 - second bendli
nethree_d_body = bendlinelist[i].topologyrecpt->ge
t_next_bendline() ;bend_1 = find_bendline_id( thre
e_d_body, bendlinelist, num_of_bendlines );if (ben
d_1 <= 0) num_error++ ;else {face_1 = define_bendl
ine_only_face( bend_1, bend_0, bendfacelist, maxne
wfaces ) ;if (face_1 <= 0) num_error++ ;else bendl
inelist[i].face2 = face_1 ;}}if (numadj == 1) {fac
e_1 =define_bendline_only_face ( bend_0, 0,bendfac
elist, maxnewfaces ) ;if (face_1 <= 0) num_error++
;else bendlinelist[i].face2 = face_1 ;}}}}if (num
_error > 0) {clean_up ( part_numface, imatrix, nbl
_face, facelist, bendlinelist, bendfacelist) ;re
turn ( num_error ) ;}// now check whether there is
any bendline only face been created// increase th
e part_numfaceif there is.int numregfaces = part_n
umface ;int numnewfaces = 0 ;if (maxnewfaces > 0)
{ for ( i = 0 ; i < maxnewfaces ; i++ ) {if (bendf
acelist[i].faceid <= 0) {numnewfaces = i + 1 ;brea
k ;}}part_numface += numnewfaces ;}//first create
integer topological matrix to record all the topol
ogical relationsint j ;imatrix = new int *[part_nu
mface] ;for ( i = 0 ; i< part_numface ; i++ ) {ima
trix[i] = new int [part_numface] ;for( j = 0; j <
part_numface; j++ ) imatrix[i][j] = 0;}for ( i = 0
; i < num_of_bendlines ; i++ ) {// save the bendl
ine entry + 1 in imatrixif (bendlinelist[i].bendli
neid) {face_1 = bendlinelist[i].face1 ;face_2 = be
ndlinelist[i].face2 ;imatrix[face_1-1][face_2-1] =
i+1 ;imatrix[face_2-1][face_1-1] = i+1 ;}}// from
imatrix to find the number of bendlines of each f
ace,nbl_face[i],// and to verify that each face ha
s at least one bendlinenbl_face = new int [part_nu
mface] ;for ( i = 0 ; i < part_numface ; i++ ){nbl
_face[i] = 0 ;for ( j = 0 ; j < part_numface ; j++
) {if ( imatrix[i][j] ) nbl_face[i]++;}if (!nbl_f
ace[i]) num_error++ ;}if (num_error > 0){clean_up
( part_numface, imatrix, nbl_face, facelist, ben
dlinelist,bendfacelist) ;return ( num_error ) ;}//
create the Cbpart’s topological matrix’s input
data FENT array// and initialize it.part->get_name
( pname ) ;parrank = part_numface ;int spsize = pa
rrank*(parrank + 1)/2 + 1; // +1 is for End of FE
NT array indicator FENT *sp = new FENT [ spsize] ;
for(i = 0; i < spsize-1 ; i++ )*(sp+i) = NoRelatio
n ;*(sp+spsize-1)= NullFent ;// step 1: set up the
positive or negative bend// The included
FENT’s are://*PosBend = ’+’; // positive b
end betweentwo faces//*NegBend = ’-’; // ne
gative bend between two faces//*P90Bend= ’A’;
// 90 deg positive bend angle//*N90Bend =’B’; /
/ 90 deg negative bend angle//MrPosBend = ’3’;
// multiple positive bendlines between two faces
//MrNegBend = ’4’; // multiple negative bendl
ines between two faces//* marks what is currently
implemented.for ( i = 0 ; i < num_of_bendlines ; i
++ ) {if (bendlinelist[i].bendlineid) {face_1 = be
ndlinelist[i].face1 ;face_2 = bendlinelist[i].face
2 ;FENT btype = NegBend ;BM_BEND_OP_REGULAR *bendo
pregular = (BM_BEND_OP_REGULAR *)bendlinelist[i].b
endoppt;if (bendopregular->get_bend_type()) btype
= PosBend ;double angle = bendopregular->get_bend_
angle() ;if (angle> PI) {// angle > PI => reverse
bend direction and reset the bend angleangle = 2*P
I - angle ;if (btype == PosBend)btype = NegBend ;e
lsebtype = PosBend ;}bendlinelist[i].bendangle = a
ngle ;bendlinelist[i].bendtype =btype ;// set up
90 degree bend typeif (angle == PI_over_2) {if (bt
ype== PosBend)btype = P90Bend ;elsebtype = N90Bend
;}//set_FENT (sp, face_1,face_2, parrank, btype)
;}}// step 2: set up the corner relationships,whi
ch is the relation//between two faces that are con
nected to a commonface.// The included FENT are:/
/*TouchCnr = ’T’; // two facessame bend di
r//*OpenCnr = ’O’; // two faces same bend
dir//*PrllBend = ’P’; // two parallel ben
dline same bend angle dir opposite bendline dir//*
SerlBend = ’S’; // two parallel bendline s
ame bend angle dir same bendline dir//*cLnrBend
= ’L’; // colinear bendline same bend angle
dir on one face//*DfClnrBend = ’D’; //coline
ar bendline same bend angle on different faces//*t
HkOffBend = ’H’;// tHickness offset bendline
same bend angle dir on two neighboring face//*touc
hCnr = ’t’; // two faces opposite bend dir
//*openCnr= ’o’; // two faces opposite bend
dir//*prllBend = ’p’;//two parallel bendlin
e opposite bend angle dir opposite bendline dir//*
serlBend = ’s’; // two parallel bendline o
pposite bend angle dirsame bendline dir//*clnrBend
= ’l’; //colinear bendline opposite bend
angle dir on one face//thkOffBend = ’h’; //
tHickness offset bendline opposite bend angle dir
on two neighboring face//* marks whatis currently
implemented.// Algorithm : for every face that has
more than one bend line then//a pair of any two b
end lines will have relationship.for ( i = 0 ; i <
part_numface ; i++ ) {if (nbl_face[i] > 1) {int f
ace_c = i + 1 ;// create a list of faces that are
connected to this face.for ( j = 0 ; j < part_numf
ace ; j++ ) {if ( imatrix[i][j] ) {int bl_1 =imatr
ix[i][j] ;face_1 = j + 1 ;for ( int k = j+1 ;k < p
art_numface ; k++) {if ( imatrix[i][k] ) {int bl_2
= imatrix[i][k] ;face_2 = k + 1 ;// define the re
lation ship between the two bendlinesset_bendline_
rel_FENT (sp, parrank,facelist, face_c, face_1, fa
ce_2,bendlinelist, bl_1, bl_2,outfile) ;}}}}}}//*t
HkOffBend = ’H’; // tHickness offset bendlin
esame bend angle dir on two neighboring face// fro
m imatrix to find thefaces that may be of the thic
kness offset bendlines//and verify these faces fir
st based on touch cornerinfomation then based on//
the bendlines’distance and parallel condition.fo
r ( i = 0 ; i < part_numface ; i++ ){if ( nbl_face
[i] < 2 ) continue ;// face i should have at least
2 bendlinesfor ( j = i+1 ; j < part_numface ; j++
) {if ( !imatrix[i][j] || nbl_face[j] < 2 ) conti
nue ;// faces i and j must have a common bendline/
/and face j should have at least 2 bendlinesfor (
int i2 = 0 ; i2 < part_numface ; i2++ ) {if ( !ima
trix[i][i2] || i2 == j ) continue ;// faces iand i
2 must have a common bendline// and face i2 is dif
ferent from j//first requirement - bendlines imatr
ix[i][j] and// imatrix[i][i2] form atouch cornerif
( get_FENT(sp, j+1, i2+1, parrank) != TouchCnr )
continue;for ( int j2 = 0 ; j2 < part_numface ; j2
++ ) {if ( !imatrix[j][j2] ||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, parrank) != TouchCnr ) contin
ue ;// comes here, we have obtained a candidate fo
r the // thickness offset bendlines, the two cand
idate // bendlines are imatrix[i,i2] and imatrix
[j][j2] int bl_1 = imatrix[i][i2] ;intbl_2 = imat
rix[j][j2] ;check_thkoffbend ( sp, parrank,facelis
t, i+1, i2+1, j+1,j2+1,bendlinelist, bl_1, bl_2, t
hickness, outfile);}}}}//DfClnrBend = ’D’; /
/colinear bendline same bend angle on different fa
ces// Here is to find all the colinear bends that
are colinear but not related to each other// with
a common face.int num_undetermined = 0 ;UNDETERMIN
ED *undetermined = new UNDETERMINED [num_of_bendli
nes] ;UNDETERMINED *undetpt = undetermined ;for (
i = 0 ; i < num_of_bendlines ; i++ ) {if (bendline
list[i].bendlineid) {int face_i1 = bendlinelist
[i].face1 ;int face_i2 = bendlinelist[i].face2 ;fo
r ( j = i+1 ; j < num_of_bendlines ; j++ ) {if (be
ndlinelist[j].bendlineid) {int face_j1 = bendlinel
ist[j].face1 ;int face_j2 = bendlinelist[j].face2
;if ( face_i1 == face_j1 || face_i1 == face_j2 ||
face_i2 == face_j1 || face_i2 == face_j2 ) continu
e ;if( bendlinelist[j].bendtype != bendlinelist
[j].bendtype ) continue ;if( bendlinelist[j].bend
angle != bendlinelist[j].bendangle ) continue ;//c
ome here when the two bend lines have the same ben
d angle and type,//and they do not share a common
face.// now examine whether they are colinearint b
l_i = i + 1 ;int bl_j = j + 1 ;int unknown = check
_DfClnrBend (sp, parrank, facelist,face_i1, face_i
2, face_j1, face_j2,bendlinelist,bl_i, bl_j,part_n
umface, imatrix, outfile) ;if (unknown) {undetermi
ned[num_undetermined].bendline_i = bl_i ;undetermi
ned[num_undetermined].bendline_j = bl_j ;num_undet
ermined++ ;}}}}}// Note: if num_undetermined is no
t zero, then there are confirmed DfClnrBend//but w
ith undetermined facesfor specify this FENT.//A tr
ee structure of all the faces that recordsthe conn
ectivity between//faces need to be constructed. A
nd then eachpair of undetermined//bendlines need t
o be processed to determine which two faces of the
four//that connected with the two bendlines shoul
d be used torecord this FENT.// Currently, we will
neglect these information and simply delete// und
etermined array, which will not be used any more.
delete [] undetermined ;// transfer all the data b
ack *inp_part_numface =part_numface ;*inp_parrank
= parrank ;*inp_part_numbend = part_numbend;*inp_p
art_maxface = part_maxface ;*inp_sp = sp ;num_erro
r = fclose (outfile) ;clean_up ( part_numface, ima
trix, nbl_face, facelist, bendlinelist, bendface
list) ;return ( num_error ) ; } 付録B 相似性指数特性の例。2つの部分のトポロジカルマトリ
クスを比較し、それらの最良の相似性指数を求める。相
似性指数は、2つの部分のFENTマトリクストポロジ
カルマトリクス)の不一致FENTsの全てのペナルテ
イの和として与えられる。最良の相似性指数は最小値を
持つものである。
【0366】int matrix_similarity_index ( FENT
*newmatrix,int newmatrixdim,int *newmatchlist,
FENT *oldmatrix,int oldmatrixdim,int *oldmatchli
st, int nfacefixed,int requiredvalue,int *minimum
value){ //input //newmatrix- new part topolog
ical matrix to be matched on// by the oldmatrix//
newmatrixdim- matrix dimension of newmatrix//newma
tchlist- the first nfacefixed entries should// co
ntain the entries (faces) of the new part//matrix
that has already been fixed for// matching with t
he old part matrix. //oldmatrix- old part matri
x to match with the new part // topological matr
ix//oldmatrixdim- matrix dimension of oldmatrix//o
ldmatchlist- the first nfacefixed entries should//
contain the entries (faces)of the old part// ma
trix that has already been fixed for// matching w
ith the new part matrix.//nfacefixed- the number o
f entries in matchlistthat// has already been mat
ched. Enter 0 when// there is no prematched entr
ies.//requiredvalue- the known or interested upper
bound on the//minimum similarity index. When thi
s value// is inputed as a positivevalue, then a//
branch of the search tree in finding the// mini
mum value of the similarity index may// be cut of
f when the branch’s currentvalue// becomes great
er than this minimum value.// set to 0 or a negat
ive value when there is// no restriction. In thi
s case, a minimumvalue// and its corresponding ma
cthlists will always// be found and returned.
//output//newmatchlist- the first nfacefixed ent
ries should//contain the entries (faces) of the ne
w part// matrix that has alreadybeen fixed for//
matching with the old part matrix.//oldmatchlist
- the first nfacefixed entries should// contain t
he entries (faces) of the oldpart// matrix that h
as already been fixed for// matching with the new
part matrix.//minimumvalue- the minimum similarity
index, which is the// smallest possible value of
summation of all// the penalties of the mismatch
ed FENTs of the// two part’s FENT matrix (topolo
gical matrix).// This value may not exist, if the
original// inputed value (which isthe requiremen
t) is// too small.//return- index on whether or n
ot foundthe minimum// value.//= 1, found the mini
um value and its match. //= 0, a new minium value
cannot be reached.//= -1, error in the input data
newmatchlist.//= -2, error in the input data oldma
tchlist.//= -3, error,the minimum similarity index
of// the given matrices are larger than the// i
nputed minimumvalue.// create two integer pointer
arrays to keep track the // corresponding entries
of the two matrices that matches.int matrixdim = n
ewmatrixdim ;if (matrixdim < oldmatrixdim) matrixd
im = oldmatrixdim ;int *pnewmatchlist = new int[ m
atrixdim ];int *poldmatchlist =new int[ matrixdim
];if ( poldmatchlist && pnewmatchlist ) {int *p1
= pnewmatchlist;int *p2 = poldmatchlist;for ( int
icol = 1; icol <= matrixdim; icol++,p1++,p2++)*p1
= *p2 = icol;}elsecout << "Unable to allocate memo
ry..." << endl ;// if there are already fixed entr
ies (nfacefixed > 0),then reset// the temporary wo
rking pointer arrays (newmatchlist & oldmatchlist)
// to contain those fixed face list.if (nfacefixed
> 0){for (inticol = 0; icol < nfacefixed; icol++)
{int iface = *(newmatchlist+icol);for ( int jcol
= icol; jcol < matrixdim; jcol++) {if (iface == *
(pnewmatchlist+jcol)) {if (jcol != icol) {*(pnewma
tchlist+jcol) = *(pnewmatchlist+icol) ;*(pnewmatch
list+icol) = iface ;}break ;}// comes here only if
the inputed face number "iface"// from newmatchlis
t is wrongreturn (-1); }iface = *(oldmatchlist+ico
l) ;for ( jcol = icol; jcol < matrixdim; jcol++)
{if (iface == *(poldmatchlist+jcol)) {if (jcol !=
icol) {*(poldmatchlist+jcol) = *(poldmatchlist+ico
l) ;*(poldmatchlist+icol) = iface ;}break ;}// com
es here only if the inputed face number "iface"//
from oldmatchlist is wrongreturn (-2) ; }}}// conv
ert the FENT matrix to the counter part of integer
matrix// at the same time, expand the smaller mat
rixto have the same dimension.int *pnewmatrix = ne
w int[matrixdim*matrixdim];int *poldmatrix = new i
nt[matrixdim*matrixdim];convert_fent_to_int (newma
trix, newmatrixdim, pnewmatrix, matrixdim) ;conver
t_fent_to_int (oldmatrix, oldmatrixdim, poldmatri
x, matrixdim) ;// define required valueintrequired
v = requiredvalue ;if (requiredv <= 0) requiredv =
matrixdim *400 ;// create the FENT counters and u
se calculate_partial_similarity_index// to calcula
te the initial similarity index and set the initia
l FENT// counts for each column of the fixed faces
and that of all the// unfixed faces.FENTCOUNT *pc
new = new FENTCOUNT[matrixdim+1];FENTCOUNT *pcold=
new FENTCOUNT[matrixdim+1];int currentvalue = cal
culate_partial_similarity_index ( pnewmatrix, p
newmatchlist, pcnew, poldmatrix, poldmatchlis
t, pcold, matrixdim, nfacefixed ) ;if (currentva
lue > requiredv) return (-3) ;// reset the unfixed
faces in pnewmatchlist to be in thesequence of//
its total weighting.int ncandidates = matrixdim -
nfacefixed ;int *pcandidates = new int [ncandidat
es] ;int *pweights = new int [ncandidates] ;for (
int i = 0 ; i < ncandidates ; i++ ) {int facenew =
*(pnewmatchlist+nfacefixed+i) ;*(pcandidates+i) =
facenew ;int weight = 0;int *pnewi = pnewmatrix +
(facenew-1)*matrixdim ;for ( int j = 0 ; j <matri
xdim ; j++, pnewi++ )weight += fent_weight(*pnewi)
;*(pweights+i)= weight ;}sort_the_candidates (pca
ndidates, pweights, ncandidates) ;for( i = 0 ; i <
ncandidates ; i++ ) *(pnewmatchlist+nfacefixed+i)
= *(pcandidates+ncandidates-1-i) ;delete [] pcand
idates ;delete [] pweights ;//call the internal ro
utine recursively to perform similarity index// se
arch.*minimumvalue = requiredv ;int recursive_leve
l = 0;int *newminmatchlist = new int[matrixdim];in
t *oldminmatchlist = new int[matrixdim];int *retur
nlevelcounts = new int[matrixdim];int errorcode =
matrix_similarity_index_loop ( pnewmatrix, pnew
matchlist, newminmatchlist, poldmatrix, poldm
atchlist, oldminmatchlist, pcnew, pcold, &current
value, matrixdim, nfacefixed, &recursive_level, m
inimumvalue, returnlevelcounts);// clean updelete
[] pnewmatchlist ;delete [] poldmatchlist ;delete
[]pnewmatrix ;delete [] poldmatrix ;delete [] pcn
ew ;delete [] pcold ;delete [] returnlevelcounts ;
delete [] newminmatchlist ;delete [] oldminmatchli
st ;return (errorcode);}// 新しい部分マトリクスと
一致する既存の部分マトリクスからエントリのリストを
抽出する。部分マトリクスのデイメンシヨンはトポロジ
カルマトリクスのデイメンシヨンより大きいか等しくな
ければならない。注意:一致リストの第一要素は初期化
されてトポロジカルマトリクスの第一面との一致のため
部分マトリクスの面番号を含まなければならない。 n
matchedが0より大きいときは、マッチリストの
第一のnmatchedエントリは正の番号を含んで部
分マトリクスの既に一致されたエントリを示さなければ
ならない。//int matrix_similarity_index_loop (
int *pnewmatrix, int *pnewmatchlist, int *newmi
nmatchlist, int *poldmatrix, int *poldmatc
hlist, int *oldminmatchlist, FENTCOUNT *pcnew,
FENTCOUNT *pcold, int *currentvalue, int matrix
dim, int nfacefixed, int *recursive_leve
l, int *minimumvalue, int *returnlevelcounts){//
input//pnewmatrix- the new part’s topological ma
trix, where//the FENT contents have been changed t
o//their representing integers.//
(integer array of matrixdim * matrixdim)//
pnewmatchlist- the list of entries of the newmatri
xthat // has been matched by the oldmatrix.//
(integer array of matrixdim)//
newminmatchlist- the list of entries of the newmat
rix that // has been matched by the oldmatrix tha
t// provides theminimum value.//
(integer array of matrixdim)//poldmatrix-
the old parts’s topological matrix, where//the FE
NT contents have been changed to//their representi
ng integers.//(int array ofmatrixdim * matrixdim)/
/poldmatchlist- the list of entries of the oldmatr
ix that // has matched with the newmatrix.//
(integer array of matrixdim)//
oldminmatchlist- the list of entries of theoldmatr
ix that // has matched with the oldmatrix that//
provides theminimum value.//
(integer array of matrixdim)//matrixdim- the m
atrix dimension of both matrices//nfacematched- th
e numberof entries (faces) that has// been fixed
in matching the two matrices.// recursive_level- t
his keep the number of times this procedure// has
been called recursivly. This provides a// way t
o detect the error before going into a// infinite
loop. (integer pointer)// output//return- error i
ndex,//= 0 means there is no error,//> 0 error cod
e.//// verify therecursive levelif ( *recursive_le
vel > matrixdim ) {cout << "??? Error-the recursiv
e level is too high. ???\n";cout << " The matri
x dimension is " << matrixdim << ".\n";cout << "
The recursive level is " <<*recursive_level <<
".\n";return (9) ;}// Step 1) Choose a row to be
matched with in the new matrix.// ( Currently, it
uses whatever the next row in line. Therefore,//
nothing to do at this moment.// This may need
to be changed to be properly matching up with//
the algorithm thatmay be used in defining the seq
uence of the// candidate list.// Note: If face
new is not next to the nfacefixed position, then//
it should be changed to that position. )i
nt facenew = *(pnewmatchlist+nfacefixed) ;// Step
2) Create a list of candidate face list in the ol
d matrix.// and calculate the increases in
the similarity index for//each of the candidates.
// ( Currently we are using what ever thesequence
that is inside// the poldmatchlist.// One may
choose to usethe faces that at least matches up wi
th// the face connectivity of the chosen face in
the new matrix.// Note: The sequence of faces i
n pcandidates does not need to// be corres
ponding to that in poldmatchlist. )int ncandidate
s = matrixdim - nfacefixed ;int *pcandidates = new
int [ncandidates] ;int *pincreases = new int [ncan
didates] ;for ( int i= 0 ; i < ncandidates ; i++ )
{int faceold = *(poldmatchlist+nfacefixed+i) ;*(p
candidates+i) = faceold ;int increase = increase_o
n_similarity_index ( pnewmatrix,pnewmatchlist,f
acenew, poldmatrix,poldmatchlist,faceold,
pcnew,pcold,currentvalue, matrixdim,nfacefixe
d,minimumvalue) ;*(pincreases+i) = increase ;}// S
tep 3) Sort the candidate facebased on the increas
ed values// the candidates with the lower
increase will be tried first.sort_the_candidates
(pcandidates, pincreases, ncandidates) ;// Step 4)
change the FENT counters of the newmatrix forfixi
ng facenewint errorcode = change_counts_for_fix_on
e_face ( pnewmatrix, pnewmatchlist, facenew, pc
new, matrixdim, nfacefixed) ;if (errorcode != 0) r
eturn (errorcode) ;// Step 5) Loop thru the candid
ate face and based on the increased value//
determines whether or not to continue to the lo
wer level match.for ( int icandi = 0 ; icandi < nc
andidates ; icandi++ ) {// get the candidate face
number of the old matrix and// its corresponding a
mount of increase on similarity index.int faceold=
*(pcandidates+icandi) ;int increase = *(pincrease
s+icandi) ; // Now check whether it is any need to
continue the matching// If the current value plus
the increase has already exceed the // minimum va
lue, then thereis no need to continue the matchin
g.// add the returnlevelcount and goto the next ca
ndidates.if (*currentvalue + increase >= *minimumv
alue) {returnlevelcounts[nfacefixed] += 1 ;}else i
f (nfacefixed+1 == matrixdim){// A new minimum sim
ilarity index has been found, update// the minimum
value*minimumvalue = *currentvalue + increase ;for
( i = 0 ; i < matrixdim ; i++ ) {newminmatchlist
[i] = pnewmatchlist[i] ;oldminmatchlist[i] =poldma
tchlist[i] ;}}else {// It is necessary to go down
another level inthis recursive// call to define th
e similarity index.// change the FENTcounters of t
he oldmatrix for fixing faceolderrorcode = change_
counts_for_fix_one_face ( poldmatrix, poldmatch
list, faceold, pcold, matrixdim, nfacefixed) ;if
(errorcode != 0) return (errorcode) ;// call recur
sively*currentvalue += increase ;*recursive_level
+= 1 ;errorcode = matrix_similarity_index_loop
( pnewmatrix,pnewmatchlist,newminmatchlist,poldm
atrix,poldmatchlist,oldminmatchlist, pcnew, pco
ld,currentvalue, matrixdim,nfacefixed+1,recursive
_level, minimumvalue,returnlevelcounts) ;if (erro
rcode != 0) return (errorcode) ;*recursive_level -
= 1 ;*currentvalue -= increase ;// change the FENT
counters of the oldmatrix for unfixing faceoldcha
nge_counts_for_unfix_one_face ( poldmatrix, pol
dmatchlist, pcold, matrixdim, nfacefixed+1) ;}}//
change the FENT counters of the newmatrix for unfi
xing facenewchange_counts_for_unfix_one_face( pnew
matrix, pnewmatchlist, pcnew, matrixdim, nfacef
ixed+1) ;//cleanupdelete [] pcandidates ;delete []
pincreases ;return (0);}/////////////////////////
///////////////////////////////////////// 1以上の
面を固定するためのカウンターを更新する。//////////
//////////////////////////////////////////////////
////////int change_counts_for_fix_one_face ( in
t*pnewmatrix, int *pnewmatchlist, int facenew,
FENTCOUNT *pcnew, int matrixdim, int nfac
efixed){// input//pnewmatrix- the new part’stopol
ogical matrix, where// the
FENT contents have been changed to//
their representing integers.//
(integer array of matrixdim * matrix
dim)//pnewmatchlist- the list of entries of the ne
wmatrix that // has been matchedby the oldmatrix.
// (integer array of matrix
dim)//facenew- the face that is to be fixed.//pcne
w- the FENTCOUNT of all the faces.//matrixdim- the
matrix dimension of both matrices//nfacematched-
the number of entries (faces) that has// been fix
ed in matching the two matrices.// output//pnewmat
chlist- the updated list of entries of the// newm
atrix matched by the oldmatrix,// with the facene
w entry is moved to the // nfacefixed+1 location.
//pcnew- the updated FENTCOUNT of all the faces//
switch the to be fixed face to the location of nf
acefixed+1// in the pnewmatchlistint ifound = 0 ;f
or ( int i = nfacefixed ; i <matrixdim ; i++ ) {if
(*(pnewmatchlist+i) == facenew) {*(pnewmatchlist+
i) = *(pnewmatchlist+nfacefixed) ;*(pnewmatchlist+
nfacefixed) = facenew ;ifound++ ;}}if ( ifound !=
1 ) {cout << "Fatal error from change_counts_for_f
ix_one_face /n" ;return ( 91 ) ;}// define the poi
nter to the FENTon the to be fixed faceint *pnewro
w = pnewmatrix + (facenew-1)*matrixdim;// first ch
ange the counters for the previously fixed facesfo
r ( i = 0; i < nfacefixed ; i++ ) {int newcol = *
(pnewmatchlist+i) ;int pnewv =*(pnewrow + newcol
- 1) ;pcnew[newcol].count[pnewv]-- ;int igroup = f
ent_group (pnewv) ;pcnew[newcol].gcount[igroup]--
;if ( pcnew[newcol].count[pnewv] < 0 || pcnew
[newcol].gcount[igroup] < 0 ) {cout << "Fatal erro
r from change_counts_for_fix_one_face /n" ;return
( 92 ) ;}}// secondchange the counters for the unf
ixed faces// use count_specified_fents to initiali
ze the FENTCOUNT of// the newly seleted face and c
ount the numbers of fents of // the undetermined c
olumns on the to be fixed rowsintlistdim = matrixd
im - nfacefixed ;pcnew[facenew] = count_specified_
fents( pnewrow, pnewmatchlist+nfacefixed, matrixdi
m, listdim ) ; // decreasethe FENTCOUNT of the new
ly seleted face from that// in remaining unfixed f
acesfor ( i = 0; i < NumIntFent; i++ ) pcnew[0].co
unt[i] -= pcnew[facenew].count[i] ;for ( i = 0; i
< NumIntFentGroup; i++ ) pcnew[0].gcount[i] -= pcn
ew[facenew].gcount[i] ;return (0) ;}//////////////
//////////////////////////////////////////////////
////// この関数はカウンタを更新して固定面を開放す
る。解放された面は現在nface////fixed位置
にある面である。//////////////////////////////////
////////////////////////////////////void change_co
unts_for_unfix_one_face ( int *pnewmatrix, i
nt *pnewmatchlist, FENTCOUNT *pcnew, int matrix
dim, int nfacefixed){// input//pnewmatrix- th
e new part’s topological matrix, where//the FENT
contents have been changed to//their representing
integers.//(integer array of matrixdim * matrixdi
m)//pnewmatchlist- the list of entriesof the newma
trix that // has been matched by the oldmatrix.//
(integer array of matrixdim)//pcnew- the FENTCOUNT
of all the faces.//matrixdim- the matrix dimensio
n of both matrices//nfacematched- the number of en
tries (faces) that has// been fixed in matching t
he two matrices.// output//pcnew- the updated FENT
COUNT of all the faces// get the to be unfixed fac
e number and// define the pointer to the FENT on t
he to be fixed faceint facenew = *(pnewmatchlist+n
facefixed-1) ;int *pnewrow = pnewmatrix + (facenew
-1)*matrixdim ;// first change the counters for th
e previously fixed facesfor ( int i = 0 ; i < nfac
efixed-1 ;i++ ) {int newcol = *(pnewmatchlist+i) ;
int pnewv = *(pnewrow + newcol- 1) ;pcnew[newco
l].count[pnewv]++ ;int igroup = fent_group (pnewv)
;pcnew[newcol].gcount[igroup]++ ;}// second chang
e the counters for the unfixed faces by// adding t
he FENTCOUNT of the to be released face to that//
of the remaining unfixed facesfor ( i = 0; i < Num
IntFent; i++ ) pcnew[0].count[i] += pcnew[facene
w].count[i] ;for ( i = 0; i < NumIntFentGroup; i++
) pcnew[0].gcount[i] += pcnew[facenew].gcount[i]
;}///////////////////////////////////////////////
////////////////////////// この関数は所与のint
fentの配列におけるFENTsの個数をカウントす
//// る。
【0367】//////////////////////////////////////
///////////////////////////////////FENTCOUNT count
_fents ( int *pintfentarray, int arraydim){// inpu
t//pintfentarray- the pointer to the intfent array
//arraydim- the dimension ofthe intfent array// ou
tput//return- FENTCOUNT, the FENT count of the//in
put array// define an FENT count and initialize it
static FENTCOUNT fentc ;for ( int j = 0; j < NumIn
tFent; j++ ) fentc.count[j] = 0 ;for ( j= 0; j < N
umIntFentGroup; j++ ) fentc.gcount[j] = 0 ;// Coun
t the numbers of fents in an array of intfentfor
( int *i = pintfentarray ; i < pintfentarray+array
dim ; i++ ) {fentc.count[*i]++ ;fentc.gcount[fent_
group(*i)]++ ;}return (fentc) ;}//////////////////
//////////////////////////////////////////////////
// この関数は特定の組のintfent配列における
FENTsの個数をカウント//// する。////////////
//////////////////////////////////////////////////
////////FENTCOUNT count_specified_fents ( int *pin
tfentarray,int *locationlist, int arraydim, int li
stdim){// input//pintfentarray- the pointer to the
intfent array//locationlist- the locations in the
intfent array// that are to be included in count
ing//arraydim- the dimension of the intfent array/
/listdim- the dimension of the location list// out
put//return- FENTCOUNT, the FENT count of the// s
elected elements in the input array// define an FE
NT count and initialize itstatic FENTCOUNT fentc ;
for ( int j = 0; j < NumIntFent; j++ ) fentc.count
[j] = 0 ;for ( j = 0; j < NumIntFentGroup; j++ ) f
entc.gcount[j] = 0 ;// Count the numbers of fents
in an array of intfentfor ( int *i = locationlist
; i < locationlist+listdim ; i++ ) {int intfent =
*(pintfentarray+(*i)-1) ;fentc.count[intfent]++ ;
fentc.gcount[fent_group(intfent)]++ ;}return (fent
c) ;}/////////////////////////////////////////////
//////////////////////////////// この関数は特定の
組のintfentマトリクスにおけるFENTsの個数をカ
ウントする。////注意:intfentマトリクスは対
称である。マトリクスの半分だけがカウントに含ま////
れる。//////////////////////////////////////
///////////////////////////////////////FENTCOUNTco
unt_specified_fents_matrix ( int *pintfentmatrix,i
nt *locationlist, int matrixdim, int listdim){// i
nput//pintfentmatrix- the pointer to theintfent ma
trix//locationlist- the locations in the intfent m
atrix// that are to be included in counting//matr
ixdim- the dimension of the intfent matrix//listdi
m- the dimension of the location list// output//re
turn-FENTCOUNT, the FENT count of the// selected
elements in the input matrix// define an FENT coun
t and initialize itstatic FENTCOUNT fentc ;for (in
t j = 0; j < NumIntFent; j++ ) fentc.count[j] = 0
;for ( j = 0; j < NumIntFentGroup; j++ ) fentc.gc
ount[j] = 0 ;// Count the numbers of fentsin an ma
trix of intfentfor ( int i = 0 ; i < listdim ; i++
) {int facenum = *(locationlist+i) ;int *pintfent
row = pintfentmatrix + (facenum - 1)*matrixdim ;//
Note: only half of the symmetric matrix is counte
d =>//the k is atarted from i (diagonal included).
for ( int k = i ; k <listdim ; k++ ) { int intfent
= *(pintfentrow+(*(locationlist+k))-1) ;fentc.cou
nt[intfent]++ ;fentc.gcount[fent_group(intfent)]++
;}}return (fentc) ;}/////////////////////////////
//////////////////////////////////////// この関数
は不一致な対のFENTに対してペナルテイを戻す。//////
//////////////////////////////////////////////////
/////////////int penalty_of_fent_pair ( int intfen
t1, int intfent2){// input//intfent1- the intfent
of part 1//intfent2- the intfent of part 2// outpu
t//return- the penalty forthe mismatched intfents.
// No penalty, if they are the sameif (intfent1==
intfent2) return (0) ;// add the penalty for misma
tching the individual intfentint indexvalue = 0;in
dexvalue += fent_weight(intfent1) ;indexvalue += f
ent_weight(intfent2) ;// add the penalty for misma
tching theirfent groupint fentgroup1 = fent_group
(intfent1) ;int fentgroup2 = fent_group(intfent2)
;if (fentgroup1 != fentgroup2) {indexvalue += fen
t_group_weight(fentgroup1) ;indexvalue += fent_gro
up_weight(fentgroup2) ;}return (indexvalue) ;}////
//////////////////////////////////////////////////
////////////// この関数は2つの最小可能不一致に対
して最小ペナルテイを戻す。////////////////////////
////////////////////////////////////////////int pe
nalty_of_FENTCOUNT_pair ( FENTCOUNT const &fentcou
nt1,FENTCOUNT const &fentcount2){// input//fentcou
nt1- the FENTCOUNT of part 1//fentcount2- the FENT
COUNT of part 2// output//return- the minimum pena
lty on themismatches// of two F
ENTCOUNTs.// Now loop thru theFENTCOUNT, // curren
tly method uses the penalty of the minimum possibl
e// individual mismatches as the penalty plus the
penalty of// the minimum possible mismatched group
sint indexvalue = 0;for ( int i = 1; i < NumIntFen
t; i++ )if ( fentcount1.count[i] != fentcount2.cou
nt[i] )indexvalue += fent_weight(i) * abs ( fentco
unt1.count[i] - fentcount2.count[i] );for ( i = 1;
i < NumIntFentGroup; i++ )if ( fentcount1.gcount
[i] != fentcount2.gcount[i] )indexvalue += fent_gr
oup_weight(i) * abs ( fentcount1.gcount[i] - fentc
ount2.gcount[i] ) ;return (indexvalue) ;}/////////
//////////////////////////////////////////////////
///////// この関数は不一致対のFENTのペナルテ
イを戻す。////////////////////////////////////////
//////////////////////////int change_from_seperate
_fent_sets ( int ntnew, int ntold, int nsnew, int
nsold ){// input//ntnew- number of FENT inthe whol
e set of the new part.//ntold- number of FENT in t
he whole setof the old part.//nsnew- number of FEN
T in the sub-set of the new part.//nsold- number o
f FENT in the sub-set of the old part.// output//r
eturn-the change in the number of counts of the mi
smatch// due to the separation of the sub-set fro
m the // whole set.int difforg = abs( ntnew-ntold
) ;int diffsub = abs( nsnew-nsold ) ;int diffnew
= abs( ntnew-nsnew-ntold+nsold ) ;int change = dif
fsub + diffnew - difforg ;return ( change );}/////
//////////////////////////////////////////////////
//////////////////////// この関数は2つのFENT
COUNTの最小可能不一致に対する最小ペナルテイを
戻す。////////////////////////////////////////////
///////////////////////////////////int increase_fr
om_separate_a_pair_of_fent (FENTCOUNT const &pcnew
_total,FENTCOUNT const &pcold_total,int intfentnew
_separ,int intfentold_separ ){// input//pcnew_tota
l- the total FENTCOUNT of the new part//pcold_tota
l- the total FENTCOUNT of the old part//intfentnew
_separ - to be seperated FENT of the new part//int
fentold_separ - tobe seperated FENT of the old par
t// output//return- the increase in thepenalty due
to the// seperation of the FEN
Ts.staticint ntnew, ntold, igroup ;static int incr
ease ;if (intfentnew_separ ==intfentold_separ) {nt
new = pcnew_total.count[intfentnew_separ] ;ntold =
pcold_total.count[intfentnew_separ] ;increase = f
ent_weight(intfentnew_separ) *change_from_seperate
_fent_sets(ntnew, ntold, 1, 1 ) ;igroup = fent_gro
up(intfentnew_separ) ;ntnew = pcnew_total.gcount[i
group] ;ntold = pcold_total.gcount[igroup] ;increa
se += fent_group_weight(igroup) *change_from_seper
ate_fent_sets(ntnew, ntold, 1, 1 ) ;}else {ntnew =
pcnew_total.count[intfentnew_separ] ;ntold = pcol
d_total.count[intfentnew_separ] ;increase = fent_w
eight(intfentnew_separ) *change_from_seperate_fent
_sets(ntnew, ntold, 1, 0 ) ;ntnew = pcnew_total.co
unt[intfentold_separ] ;ntold= pcold_total.count[in
tfentold_separ] ;increase += fent_weight(intfentol
d_separ) *change_from_seperate_fent_sets(ntnew, nt
old, 0, 1 ) ;if (fent_group(intfentnew_separ) == f
ent_group(intfentold_separ)) {igroup = fent_group
(intfentnew_separ) ;ntnew = pcnew_total.gcount[igr
oup] ;ntold = pcold_total.gcount[igroup] ;increase
+= fent_group_weight(igroup) *change_from_seperat
e_fent_sets(ntnew, ntold, 1, 1 ) ;}else {igroup =
fent_group(intfentnew_separ) ;ntnew = pcnew_total.
gcount[igroup] ;ntold = pcold_total.gcount[igroup]
;increase += fent_group_weight(igroup) *change_fr
om_seperate_fent_sets(ntnew, ntold, 1, 0 ) ;igroup
= fent_group(intfentold_separ) ;ntnew = pcnew_tot
al.gcount[igroup] ;ntold = pcold_total.gcount[igro
up] ;increase += fent_group_weight(igroup) *change
_from_seperate_fent_sets(ntnew, ntold, 0, 1 ) ;}}r
eturn (increase) ;}///////////////////////////////
////////////////////////////////////////////// こ
の関数は2つのFENTCOUNTの最小可能不一致に
対する最小ペネルテイを戻す。//////////////////////
//////////////////////////////////////////////////
/////intincrease_from_separate_a_pair_of_fentcount
(FENTCOUNT const &pcnew_total,FENTCOUNT const &pc
old_total,FENTCOUNT const &pcnew_separ,FENTCOUNT c
onst &pcold_separ ){// input//pcnew_total- the tot
al FENTCOUNT of the newpart//pcold_total- the tota
l FENTCOUNT of the old part//pcnew_separ- tobe sep
erated FENTCOUNT of the new part//pcold_separ- to
be seperated FENTCOUNT of the old part// output//r
eturn- the increase in the penalty due to the//
seperation of the FENTCOUNTs.//
Now loop thru the FENTCOUNT, // currently method u
ses the penalty of the minimum possible // indivi
dual mismatches as the penalty plus the penalty of
// the minimum possible mismatched groupsint chang
e, increase ;increase = 0;for ( int i = 1; i < Nu
mIntFent; i++ ) {change = change_from_seperate_fen
t_sets (pcnew_total.count[i], pcold_total.count
[i],pcnew_separ.count[i], pcold_separ.count[i] ) ;
if ( change != 0 ) increase += fent_weight(i)* cha
nge ;}for ( i = 1; i < NumIntFentGroup; i++ ) {cha
nge = change_from_seperate_fent_sets (pcnew_total.
gcount[i], pcold_total.gcount[i],pcnew_separ.gcoun
t[i], pcold_separ.gcount[i] ) ;if ( change != 0 )
increase += fent_group_weight(i) * change ;}return
(increase) ;}////////////////////////////////////
////////////////////////////////////// この関数は
特定の固定した面までの所与の組の面に対して相似の指
数を計算する。//// 注意:マトリクスの半分だけが計
算に含まれる。////////////////////////////////////
//////////////////////////////////////int direct_c
alculate_similarity_index ( int *pnewmatrix,
int *pnewmatchlist, int *poldmatrix,int *po
ldmatchlist,int matrixdim){// loop thru the faces
and calculate the similarity indexint indexvalue =
0 ;for (int iface = 0; iface < matrixdim; iface+
+) {int facenew = *(pnewmatchlist+iface) ;int face
old =*(poldmatchlist+iface) ;int *pnewrow = pnewma
trix + (facenew - 1)*matrixdim ;int *poldrow = pol
dmatrix + (faceold - 1)*matrixdim ;// first fromth
e mismatches of the fixed faces.// Note: the diago
nal terms of the matrix are always iNoRelation.//
therefore, they are skip in the loop.//
also due to the symmetry, only half of the matr
ix are//included in the calculation of the similar
ity indexfor (int icol= iface; icol < matrixdim; i
col++) {int newcol = *(pnewmatchlist+icol) ;int ol
dcol = *(poldmatchlist+icol) ;int pnewv = *(pnewro
w + newcol - 1) ;int poldv = *(poldrow + oldcol -
1) ;if ( pnewv != poldv ) indexvalue += penalty_of
_fent_pair(pnewv,poldv) ;}}return (indexvalue) ;}/
//////////////////////////////////////////////////
///////////////////// この関数は特定の固定した面
までの所与の組の面に対する相似の指数を計算する。//
//////////////////////////////////////////////////
////////////////////int calculate_partial_similari
ty_index ( int *pnewmatrix, int *pnewmatchli
st,FENTCOUNT *pcnew, int *poldmatrix, int
*poldmatchlist, FENTCOUNT*pcold, int matrixdim,
int nfacefixed){// loop thru the faces andca
lculate the similarity indexint indexvalue = 0 ;fo
r (int iface = 0 ;iface < nfacefixed; iface++) {in
t facenew = *(pnewmatchlist+iface) ;int faceold =
*(poldmatchlist+iface) ;int *pnewrow = pnewmatrix
+ (facenew -1)*matrixdim ;int *poldrow = poldmatri
x + (faceold - 1)*matrixdim ;// first from the mis
matches of the fixed faces.// Note: the diagonal t
erms of the matrix are always iNoRelation.//
therefore, they are skip inthe loop.// also
due to the symmetry, only half of the matrix are/
/ included in the calculation of the similar
ity indexfor (int icol = iface ; icol < nfacefixe
d; icol++) {int newcol = *(pnewmatchlist+icol) ;in
t oldcol = *(poldmatchlist+icol) ;int pnewv = *(pn
ewrow + newcol -1) ;int poldv = *(poldrow + oldcol
- 1) ;if ( pnewv != poldv ) indexvalue += penalty
_of_fent_pair(pnewv,poldv) ;}// use count_specifie
d_fents to initialize the FENTCOUNT of// the facen
ew and faceold and to count thenumbers of fents of
// the columns of the unfixed facesint listdim =
matrixdim - nfacefixed ;pcnew[facenew] = count_spe
cified_fents ( pnewrow,pnewmatchlist+nfacefixed, m
atrixdim, listdim ) ;pcold[faceold] = count_specif
ied_fents ( poldrow, poldmatchlist+nfacefixed, mat
rixdim, listdim );// Now loop thru the FENTCOUNT o
f the facenew and faceold// and calculate the pena
lty of their mismatches.indexvalue += penalty_of_F
ENTCOUNT_pair ( pcnew[facenew], pcold[faceold] )
;}// use count_specified_fents_matrix to get the
FENTCOUNT// of the unfixed faces of both matrices
int listdim = matrixdim - nfacefixed ;pcnew[0] = c
ount_specified_fents_matrix( pnewmatrix, pnewmatch
list+nfacefixed, matrixdim, listdim ) ;pcold[0]= c
ount_specified_fents_matrix ( poldmatrix, poldmatc
hlist+nfacefixed,matrixdim, listdim ) ;// Finally
calculate the penalty of the FENTCOUNT//of the unf
ixed faces of the two matrices.indexvalue += penal
ty_of_FENTCOUNT_pair ( pcnew[0], pcold[0] ) ;// R
eturn the amount of penalty on the two partially f
ixed// part matrices as its minimum possible simil
arityindex.return (indexvalue);}//////////////////
//////////////////////////////////////////////////
///// この関数は所与のfacenewとfaceo
ldのミスマッチに対する相似の指//// 数の増加を
計算する。////////////////////////////////////////
/////////////////////////////////int increase_on_s
imilarity_index ( int *pnewmatrix, int *pnew
matchlist, intfacenew, int *poldmatrix, in
t *poldmatchlist, int faceold, FENTCOUNT *pcnew,
FENTCOUNT *pcold, int *currentvalue, int mat
rixdim,int nfacefixed, int *minimumvalue){// l
oop thru the faces to seehow much increase is in t
he// current value.int increase = 0 ;int *pnewrow
= pnewmatrix + (facenew-1)*matrixdim ;int *poldrow
= poldmatrix + (faceold-1)*matrixdim ;// first lo
op thru the previously fixed faces and calculate//
the increase for the mismatches between the chose
n columnsfor( int i = 0; i < nfacefixed; i++ ) {in
t newcol = *(pnewmatchlist+i) ;int oldcol = *(pold
matchlist+i) ;int pnewv = *(pnewrow + newcol - 1)
;intpoldv = *(poldrow + oldcol - 1) ;if ( pnewv !
= poldv ) {FENTCOUNT pcnewcol = pcnew[newcol] ;FEN
TCOUNT pcoldcol = pcold[oldcol] ;increase += incre
ase_from_separate_a_pair_of_fent (pcnewcol, pcoldc
ol, pnewv, poldv ) ;}}// use count_specified_fents
to initialize the FENTCOUNT of// the newlyseleted
face and count the numbers of fents of // the und
etermined columns on the to be fixed rowsint listd
im = matrixdim - nfacefixed ;pcnew[facenew] = coun
t_specified_fents ( pnewrow, pnewmatchlist+nfacefi
xed, matrixdim, listdim ) ;pcold[faceold] = count_
specified_fents ( poldrow, poldmatchlist+nfacefixe
d, matrixdim, listdim ) ;increase += increase_from
_separate_a_pair_of_fentcount (pcnew[0], pcold[0],
pcnew[facenew], pcold[faceold] ) ;// Return the a
mount of increase in the similarity index for// th
e matching of the chosen two faces, facenew in new
part// and the faceold in the old part.return (in
crease);} 付録C // コメントを含むベンドライン検出の例。このモジュ
ールはBM PART:: 自動ベンド( )の実施を含む。
【0368】//* ********** ********** ********** *
********** ********* これは、部分の設計と構成に供
する主要な高レベルベンドモデル関数である。その目的
は、(もし可能なら)部分が接続されるようになるよう
に面間にベンドラインを形成することにある。 この関
数は部分の形成を容易にすることにある。通常は、第三
パーテイのCADプログラムの部分を描画する。ベンド
モデルはCADシステムにわたる制御をもたず、我々の
目的に対してこの描画は丁度一組のエッジである。従っ
て、この図は部分の構造を検出するために解析されなけ
ればならない。その後、我々は部分の面とベンドライン
を形成することが出来る。しかし、入力された図はしば
しば曖昧であり、ベンドラインは一意には定義されな
い。その場合、我々は一連の発見的手法を用いてベンド
ラインを形成する。この発見的手法は、多くのものが可
能のとき一つの出力を取り出すための優先基準を規定す
る。
【0369】この問題は多くの応用に対して共通なの
で、この関数はベンドモデルの一部である。更に、ベン
ドモデルにおいてこの関数を実施すると、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
バージヨンを有する。-いずれかの面における全てのル
ープは閉じられる。
【0370】要件:-両面は同じ面内になければならな
い。リターン:-コンタクトのリストこのリターンされ
たリストは構造を有する:ノード0:objは”コンタ
クトの個数”である。ノード2i-1:objは”コン
タクトiの面l側のリストのヘッド”である。ノード2
i: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 local
_tolerance = (face1.get_part())->get_distance_tole
rance() ;// first try 3D-versions of faces. if bot
h of them are empty, try flat versions.BM_2D_BODY
*body1 = face1.get_current_3D_version() ;BM_2D_BOD
Y *body2 = face2.get_current_3D_version() ;if (NUL
L == body1 && NULL == body2) {body1 = face1.get_fl
at() ;body2 = face2.get_flat() ;}// if either of t
he 3D-bodiesis NULL we are successfully done.if (N
ULL == body1 || NULL == body2) return 1 ;// both f
aces must have a plane as the underlying surfaceBM
_SURFACE *surface1 = body1->get_surface() ;BM_SURF
ACE *surface2 = body2->get_surface() ;if (NULL ==
surface2 || NULL == surface2) return 0 ;if (! surf
ace2->is(BM_TYPE_PLANE) || ! surface2->is(BM_TYPE_
PLANE)) return 0 ;//if any of the faces has an emp
ty bloop, we are successfully doneBM_LOOP*bloop1 =
body1->get_bloop() ;BM_LOOP *bloop2 = body2->get_
bloop() ;if(NULL == bloop1 || NULL == bloop2) retu
rn 1 ;/*********** ********** ********** *********
* ********** ********** ********** ********** ****
******ここで、我々は、これらの面がともかく接触出来
るか否かの非常に迅速なチェックを行う。 ここで、我
々は、面2のbループが接触するか(1点以上で)、面
1の平面に交差するか否かをチェックする。 これは、
これらの2つの面が明らかに接触出来ない時間を節約す
ることになる。********** ********** ********** ***
******* ********** ********** ********** *********
* ***********/// these variables will be used to d
o a quick check if these two// facescan possible t
ouch each otherdouble distance_plane_to_bloop1, di
stance_plane_to_bloop2,distance_plane_to_bloop3, d
istance_plane_to_bloop4 ;intdistance_plane_to_bloo
p_count ;if (! bloop2->is_bbox_up_to_date()) bloop
2->recompute_bbox() ;if (! BM_distance_between_poi
nt_and_plane(bloop2->get_bbox_p1(), (BM_PLANE&) (*
surface1), &distance_plane_to_bloop1, NULL))return
0 ;if (! BM_distance_between_point_and_plane(bloo
p2->get_bbox_p2(), (BM_PLANE&) (*surface1), &dista
nce_plane_to_bloop2, NULL)) return 0;if (! BM_dist
ance_between_point_and_plane(bloop2->get_bbox_p
3(), (BM_PLANE&) (*surface1), &distance_plane_to_b
loop3, NULL)) return 0 ;if (! BM_distance_between_
point_and_plane(bloop2->get_bbox_p4(), (BM_PLANE&)
(*surface1), &distance_plane_to_bloop4, NULL)) re
turn 0 ;distance_plane_to_bloop_count = 0 ;if (fab
s(distance_plane_to_bloop1) >= local_tolerance) di
stance_plane_to_bloop_count++ ;if (fabs(distance_p
lane_to_bloop2) >= local_tolerance) distance_plane
_to_bloop_count++ ;if (fabs(distance_plane_to_bloo
p3) >= local_tolerance) distance_plane_to_bloop_co
unt++ ;if (fabs(distance_plane_to_bloop4) >= local
_tolerance) distance_plane_to_bloop_count++ ;if (d
istance_plane_to_bloop_count > 2) {// at most one
of the bloop corners is on the plane.// that mean
s, bbox itself is not in contactwith face1.// howe
ver, it could be that different corners of bbox ar
e on different sides of the plane.// here we will
return if all bloop2 points are on one side of pla
ne1// ie. these two faces cannot be in contact// /
/ note : at most one of the 4 distance_plane_to_bl
oop-i can be zero.// // in the next line we pick "
distance_plane_to_bloop1" for checking not because
it is special,// but because any of the 4 would d
o.if (fabs(distance_plane_to_bloop1) >= local_tole
rance) {if (distance_plane_to_bloop1*distance_plan
e_to_bloop2 >= 0.0 &&distance_plane_to_bloop1*dist
ance_plane_to_bloop3 >= 0.0 &&distance_plane_to_bl
oop1*distance_plane_to_bloop4>= 0.0) return 1 ;}el
se {if (distance_plane_to_bloop2*distance_plane_to
_bloop3 >= 0.0 &&distance_plane_to_bloop2*distance
_plane_to_bloop4 >= 0.0) return 1 ;}}// if the cou
nt is 0, 1 or 2, it means that 2, 3 or 4 bbox corn
ers are on the plane.// that means, it is possible
that there is acontact./* ここで、我々は、面2に
関してbボックス1に対して同じものをチェックする。
*/if (! bloop1->is_bbox_up_to_date()) bloop1->reco
mpute_bbox() ;if (! BM_distance_between_point_and_
plane(bloop1->get_bbox_p1(), (BM_PLANE&) (*surface
2), &distance_plane_to_bloop1, NULL)) return 0 ;if
(! BM_distance_between_point_and_plane(bloop1->ge
t_bbox_p2(), (BM_PLANE&)(*surface2), &distance_pla
ne_to_bloop2, NULL)) return 0 ;if (! BM_distance_b
etween_point_and_plane(bloop1->get_bbox_p3(), (BM_
PLANE&) (*surface2), &distance_plane_to_bloop3, NU
LL)) return 0 ;if (! BM_distance_between_point_and
_plane(bloop1->get_bbox_p4(), (BM_PLANE&) (*surfac
e2), &distance_plane_to_bloop4, NULL)) return 0 ;d
istance_plane_to_bloop_count = 0;if (fabs(distance
_plane_to_bloop1) >= local_tolerance) distance_pla
ne_to_bloop_count++ ;if (fabs(distance_plane_to_bl
oop2) >= local_tolerance)distance_plane_to_bloop_c
ount++ ;if (fabs(distance_plane_to_bloop3) >=local
_tolerance) distance_plane_to_bloop_count++ ;if (f
abs(distance_plane_to_bloop4) >= local_tolerance)
distance_plane_to_bloop_count++ ;if (distance_plan
e_to_bloop_count > 2) {// at most one of the bloop
corners ison the plane.// here we will return if
all bloop1 points are on one sideof plane2// ie. t
hese two faces cannot be in contactif (fabs(distan
ce_plane_to_bloop1) >= local_tolerance) {if (dista
nce_plane_to_bloop1*distance_plane_to_bloop2 >= 0.
0 &&distance_plane_to_bloop1*distance_plane_to_blo
op3 >= 0.0 &&distance_plane_to_bloop1*distance_pla
ne_to_bloop4 >= 0.0)return 1 ;}else {if (distance_
plane_to_bloop2*distance_plane_to_bloop3>= 0.0 &&d
istance_plane_to_bloop2*distance_plane_to_bloop4 >
= 0.0) return 1 ;}}/*********** ********** *******
*** ********** ********** ********** ********** **
******** ********** 両面のラインの全数をカウント
する。
【0371】メモリを割当てる必要がある。 注意:ラ
インのみがベンドラインを作ることが出来るのでライン
であるエッジを単にカウントする。 注意:ユーザが特
定のベンドエッジを持つか否かをチェックする。ユーザ
は、どのエッジが可能なベンドエッジとして考えられる
かを、それらのエッジの名称を設定することにより限定
することが出来る。********** ********** **********
********** ******************** ********** ******
**** ***********/long face1_has_user_defined_bend_
edges = 0 ; // the number of user-speicifed bend e
dges in face1long face2_has_user_defined_bend_edge
s = 0 ; // the number of user-speicifed bend edges
in face2long face1_line_count = 0, face2_line_cou
nt = 0 ;long line_count ; // sum of lines in faces
1 and 2 participating in the sweep.BM_LOOP *holes
;BM_EDGE *edges ;for (edges = bloop1->get_first_e
dge() ; edges ; edges = (BM_EDGE *) edges->next())
{if (! edges->is(BM_ENTITY_TYPE_LINE)) continue ;
if (edges->get_name() == face2.get_idx()) face1_ha
s_user_defined_bend_edges++ ;face1_line_count++ ;}
for (holes = body1->get_first_hole() ; holes ; hol
es = (BM_LOOP *) holes->next()) {for (edges = hole
s->get_first_edge() ; edges ; edges = (BM_EDGE *)
edges->next()) {if (! edges->is(BM_ENTITY_TYPE_LIN
E)) continue ;if (edges->get_name()== face2.get_id
x()) face1_has_user_defined_bend_edges++ ;face1_li
ne_count++ ;}}for (edges = bloop2->get_first_edg
e() ; edges ; edges = (BM_EDGE*) edges->next()) {i
f (! edges->is(BM_ENTITY_TYPE_LINE)) continue ;if
(edges->get_name() == face1.get_idx()) face2_has_u
ser_defined_bend_edges++ ;face2_line_count++ ;}for
(holes = body2->get_first_hole() ; holes ; holes
= (BM_LOOP *) holes->next()) {for (edges = holes->
get_first_edge(); edges ; edges = (BM_EDGE *) edge
s->next()) {if (! edges->is(BM_ENTITY_TYPE_LINE))
continue ;if (edges->get_name() == face1.get_id
x()) face2_has_user_defined_bend_edges++ ;face2_li
ne_count++ ;}}// if there are no lines, we are suc
cessfully doneif (face1_has_user_defined_bend_edge
s) face1_line_count = face1_has_user_defined_bend_
edges ;if (face2_has_user_defined_bend_edges) face
2_line_count = face2_has_user_defined_bend_edges ;
if (face1_line_count < 1 || face2_line_count < 1)
return 1 ;line_count =face1_line_count + face2_lin
e_count ;/*********** ********** *****************
*** ********** ********** ********** ********** **
********メモリを割り当てる。********** **********
********** ********** ********** ********** ******
**** ********** ***********/if (NULL == (line_poin
ters = new BM_LINE*[line_count])) return 0 ;if (NU
LL == (line_start_coordinates= new double[line_cou
nt])) {delete [] line_pointers ;}/*********** ****
****** ********** ********** ********** **********
********** ********************先ず、ラインポイン
タ配列を充填する。必要なら、ユーザが特定したエッジ
だけを取る。********** ********** ********** *****
***** ******************** ********** ********** *
**********/i = 0 ;for (edges = bloop1->get_first_e
dge() ; edges ; edges = (BM_EDGE *) edges->next())
{if (! edges->is(BM_ENTITY_TYPE_LINE)) continue ;
if (face1_has_user_defined_bend_edges && edges->ge
t_name() != face2.get_idx()) continue ;line_pointe
rs[i++] = (BM_LINE *) edges ;}for (holes = body1->
get_first_hole() ; holes; holes = (BM_LOOP *) hole
s->next()) {for (edges = holes->get_first_edge() ;
edges ; edges = (BM_EDGE *) edges->next()) {if (!
edges->is(BM_ENTITY_TYPE_LINE)) continue ;if (fac
e1_has_user_defined_bend_edges && edges->get_nam
e() != face2.get_idx()) continue ;line_pointers[i+
+] = (BM_LINE*) edges ;}}for (edges = bloop2->get_
first_edge() ; edges ; edges = (BM_EDGE *) edges->
next()) {if (! edges->is(BM_ENTITY_TYPE_LINE)) con
tinue ;if (face2_has_user_defined_bend_edges && ed
ges->get_name() != face1.get_idx()) continue ;line
_pointers[i++] = (BM_LINE *) edges ;}for (holes =
body2->get_first_hole() ; holes ; holes = (BM_LOOP
*) holes->next()) {for(edges = holes->get_first_e
dge() ; edges ; edges = (BM_EDGE *) edges->next())
{if (! edges->is(BM_ENTITY_TYPE_LINE)) continue ;
if (face2_has_user_defined_bend_edges && edges->ge
t_name() != face1.get_idx()) continue;line_pointer
s[i++] = (BM_LINE *) edges ;}}/*********** *******
*** ********** ********** ********** ********** **
******** ********** **********X座標により、つぎに
Z座標により、さらにYによりラインの配列を分類す
る。********** ********** ********** ********** **
******** ********** ********** ********** ********
***/{ // this is a block of code for sorting the a
rray// first, construct the array of points and li
nes associated with themfor (i = 0 ; i < line_coun
t ; i++) {p = BM_get_greater_point_by_XZY((line_po
inters[i])->get_startpt(),(line_pointers[i])->get_
endpt()) ;line_start_coordinates[i] = p.X() ;}// s
ort by XDBM_QuickSort_double(line_start_coordinate
s, line_count, (long *) line_pointers) ;// sort by
Zdouble first_in_set_Z = line_start_coordinates
[0] ;long set_Z_size = 1, first_in_set_Z_idx = 0 ;
p = BM_get_greater_point_by_XZY((line_pointers[0])
->get_startpt(),(line_pointers[0])->get_endpt()) ;
line_start_coordinates[0] = p.Z() ;for (i = 1 ; i
<= line_count ; i++) {if (i < line_count) {p =BM_g
et_greater_point_by_XZY((line_pointers[i])->get_st
artpt(),(line_pointers[i])->get_endpt()) ;if (line
_start_coordinates[i] == first_in_set_Z) {set_Z_si
ze++ ;line_start_coordinates[i] = p.Z() ;continue
;}}// elsewe have passed the end of the X-sequenc
eif (set_Z_size > 1) DBM_QuickSort_double(line_sta
rt_coordinates + first_in_set_Z_idx, set_Z_size,
(long*) line_pointers + first_in_set_Z_idx) ;// so
rt by Ylong set_Z_end = first_in_set_Z_idx + set_Z
_size ;double first_in_set_Y = line_start_coordina
tes[first_in_set_Z_idx] ;long set_Y_size = 1, firs
t_in_set_Y_idx = first_in_set_Z_idx ;BM_POINT pY(B
M_get_greater_point_by_XZY((line_pointers[first_in
_set_Z_idx])->get_startpt(),(line_pointers[first_i
n_set_Z_idx])->get_endpt())) ;line_start_coordinat
es[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_poi
nters[j])->get_startpt(),(line_pointers[j])->get_e
ndpt()) ;if (line_start_coordinates[j] == first_in
_set_Y) {set_Y_size++ ;line_start_coordinates[j] =
pY.Y() ;continue ;}}//else, we have passed the en
d of the Z-sequenceif (set_Y_size > 1) DBM_QuickSo
rt_double(line_start_coordinates + first_in_set_Y_
idx, set_Y_size,(long *) line_pointers + first_in_
set_Y_idx) ;if (j < set_Z_end) {set_Y_size = 1 ;fi
rst_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_start_coordin
ates[i] ;line_start_coordinates[i] = p.Z() ;}}} //
end of the block of codefor sorting the array/***
******** ********** ********** ********** ********
** ********** ********** ********** **********ライ
ン開始座標はこれ以上不要なので、削除する。********
** ********** ********** ********** ********** ***
******* ********** ********** ***********/if (line
_start_coordinates) {delete [] line_start_coordina
tes ;line_start_coordinates = NULL;}/*********** *
********* ********** ********** 主ループ。2面を
掃引する。 開放ラインのトラックを常に保持する(出
発点を我々が見たライン、しかし終点は未だ見ていない
ライン-実際には、開始-そして-終了-点ではなくて、X
ZYオーダリングに対してより大きくかつより小さい端
点)。 始めに、開放ラインの組は空である。 全ての
繰り返しの間次のことを行う: -開放であったが、
今は閉じられるべき全てのラインを除去する、 -現
在のラインが開放ラインと重なるか否かをチェックす
る、 -このラインを開放ラインの組に加える。*///
these represent lists of contactsBM_LINKED_LIST_NO
DE *face1_list, *face2_list ;BM_LINKED_LIST_NODE *
last_face1_list, *last_face2_list;BM_LINKED_LIST_N
ODE *left, *right ;BM_LINKED_LIST_NODE *new_left =
NULL, *new_right = NULL ;BM_LINE *line_in_left, *
line_in_right ;// these are the two lines we will
be comparingBM_2D_BODY *face_of_line1, *face_of_li
ne2 ;BM_LINE *line_in_face1, *line_in_face2 ;BM_LI
NE *line ;double k,dotp ;BM_POINT p_open ;BM_VECTO
R v ;long num_of_contacts = 0 ;long open_line_idx
;for (i = line_count - 1 ; i >= 0 ; i--) {// init
ially face_of_line1 is the face of the current lin
e.// however, later we will sort thecurrent-sweep-
line and current-open-line pointers.face_of_line1
= ((line_pointers[i])->get_loop())->get_2D_body()
;p = BM_get_greater_point_by_XZY((line_pointers
[i])->get_startpt(),(line_pointers[i])->get_endp
t()) ;// compare this current line against all ope
n lines in order to detect overlaps, ie. bendline
s.for (open_line_idx = i + 1 ; open_line_idx < lin
e_count ; open_line_idx++) {line = line_pointers[o
pen_line_idx] ;if (NULL== line) {// time-saving tr
ick. if this is the last pointer, there is no need
to try it again.// reduce the index.if (open_line
_idx == line_count - 1) {--line_count ;break ;}con
tinue ;}// ********** ********** ********** ******
**** **********// check if this open line should r
eally be removed.// it should be removed if its en
dpoint is larger than p (ie. the// startpoint of t
his line).// ********** ********** ********** ****
****** **********p_open = BM_get_smaller_point_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 timewe don’t
even try this element// in the array, because it
would be beyond the boundaryif (open_line_idx == l
ine_count - 1) {--line_count ;break;}line_pointers
[open_line_idx] = NULL ;continue ;}// ********** *
********* ********** ********** **********// firs
t, check if both lines are inthe same face. if ye
s, skip it.// ********** ********** ********** ***
******* **********face_of_line2 = (line->get_loo
p())->get_2D_body() ;if (face_of_line1 == face_of_
line2) continue ;// ********** ********** ********
** ********** **********// Check if this line and
the open line overlap.// ********** ********** ***
******* ********** **********// First check if the
startpoint is on the (open) line segment.if (! li
ne->is_point_on_line(p,&k)) continue ;// Note that
parameter k has to be in [0,1] now, because// the
line "line" is open still, ie. it startpoint is "
before"p// and endpoint is "after" p.// Now check
if vectors are parallel.v =(line->get_v()) * ((lin
e_pointers[i])->get_v()) ;if (v.Len() > BM_PRECISI
ON) continue ;// Last thing, it could be that only
endpoints of the lines overlap.dotp = (line->get_
v()) % ((line_pointers[i])->get_v()) ;if (dotp <
0.0) { // lines are opposite// startpoint-startpoi
nt/endpoint-endpoint should not matchif ((line->ge
t_startpt()) == ((line_pointers[i])->get_startp
t()) || (line->get_endpt()) == ((line_pointers[i])
->get_endpt())) continue ;}else { // lines have th
e same direction// startpoint-endpoint/endpoint-st
artpoint should not matchif ((line->get_endpt()) =
= ((line_pointers[i])->get_startpt()) || (line->ge
t_startpt()) == ((line_pointers[i])->get_endpt()))
continue ;}// ********** ********** ********** **
******** **********// Ok, these two lines overlap.
// First, sort lines according to which face they
are in// ********** ********** ********** ********
** **********if (&face1 == (BM_FACE *) face_of_lin
e1->get_3D_body()) {line_in_face1 = line_pointers
[i] ;line_in_face2 = line ;p_face1 = p ;p_face2 =
BM_get_greater_point_by_XZY(line->get_startpt(),li
ne->get_endpt()) ;}else {line_in_face1 = line ;lin
e_in_face2 = line_pointers[i] ;p_face1 = BM_get_gr
eater_point_by_XZY(line->get_startpt(),line->get_e
ndpt()) ;p_face2 = p ;}// ********** ********** **
******** ********** **********// Scan all known co
ntacts and check if this contact should be// added
to an existing contact// ********** ********** ***
******* ********** **********for (j = 0, last_face
2_list = NULL ; j < num_of_contacts ; j++){if (NUL
L == last_face2_list) {last_face1_list = contacts
;last_face2_list = last_face1_list->next() ;}else
{last_face1_list = last_face2_list->next() ;last_
face2_list = last_face1_list->next() ;}left = (BM_
LINKED_LIST_NODE *) last_face1_list->get_obj() ;ri
ght = (BM_LINKED_LIST_NODE *) last_face2_list->get
_obj() ;line_in_left = (BM_LINE *) left->get_obj()
;line_in_right = (BM_LINE *) right->get_obj() ;//
Check if the line of this existing contact overla
ps the new contact.// condition is : point on the
line and vectors are parallel.if (! line_in_left->
is_point_on_line(p_face1,&k)) continue ;v = (line_
in_left->get_v()) * (line_in_face1->get_v()) ;if
(v.Len() > BM_PRECISION) continue ;// Check that l
ines in face1and face2 and exact extensions of lef
t and right in this contact// thisis because we wa
nt every contact in the list of contacts to be a "
closed" contact// note it could be that one of the
new lines in already in this contact.// then we d
on’t need to check.if (line_in_left != line_in_fa
ce1) {dotp = (line_in_left->get_v()) % (line_in_fa
ce1->get_v()) ;if (dotp < 0.0) { // lines are oppo
site// startpoints must matchif ((line_in_left->ge
t_startpt()) != (line_in_face1->get_startpt()) &&
(line_in_left->get_endpt()) != (line_in_face1->get
_endpt())) continue ;}else { // lines have the sam
e direction// endpoints must matchif ((line_in_lef
t->get_endpt()) != (line_in_face1->get_startpt())
&&(line_in_left->get_startpt()) != (line_in_face1-
>get_endpt())) continue ;}}if (line_in_right != li
ne_in_face2) {dotp = (line_in_right->get_v()) % (l
ine_in_face2->get_v()) ;if(dotp < 0.0) { // lines
are opposite// startpoints must matchif ((line_in_
right->get_startpt()) != (line_in_face2->get_start
pt()) &&(line_in_right->get_endpt()) != (line_in_f
ace2->get_endpt())) continue ;}else { // lines hav
e the same direction// endpoints must matchif ((li
ne_in_right->get_endpt()) != (line_in_face2->get_s
tartpt()) &&(line_in_right->get_startpt()) != (lin
e_in_face2->get_endpt())) continue ;}}// everythin
g is fine. add lines to this contact.// note that
is could be that the line is already in the contac
t.if (line_in_left != line_in_face1) {if (NULL ==
(new_left = new BM_LINKED_LIST_NODE(line_in_face1,
NULL,left))) goto failure ;last_face1_list->set_ob
j((BM_BASIC *) new_left) ;new_left = NULL ;}if(lin
e_in_right != line_in_face2) {if (NULL == (new_rig
ht = new BM_LINKED_LIST_NODE(line_in_face2,NULL,ri
ght))) goto failure ;last_face2_list->set_obj((BM_
BASIC *) new_right) ;new_right = NULL ;}// now we
have to break out of here. we added this contact t
o an existing contact.break ;}//check if we checke
d all contacts and could not find a matchif (j < n
um_of_contacts) continue ;// ********** **********
********** ********** **********// Create a new c
ontact.// ********** ********** ********** *******
*** **********// First, create nodes for both line
s.if (NULL == (left= new BM_LINKED_LIST_NODE(line_
in_face1))) goto failure ;if (NULL == (right = new
BM_LINKED_LIST_NODE(line_in_face2))) {delete left
;goto failure ;}// Create lists for both sides of
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_NODE((BM_BASIC *) left,NUL
L,face2_list))) {delete left ;delete right ;delete
face2_list ;goto failure ;}// add the new contact
to the list of contactsif (num_of_contacts < 1) c
ontacts = face1_list ;else last_face2_list->add_af
ter(face1_list) ;++num_of_contacts ;}// we use i t
o index line_pointers[] array.// since i will be d
ecremented shortly, line_pointers[i] will be "impl
ictly" put on // the open list of sweep lines.}/**
********* ********** ********** **********必要なら
メモリを自由にする。********** ********** ********
** ***********/if (line_start_coordinates) delete
[] line_start_coordinates ;if (line_pointers) dele
te [] line_pointers ;// finally, create a node for
the number of contactsif (NULL == (left = new BM_
LINKED_LIST_NODE((BM_BASIC *) num_of_contacts,NUL
L,contacts))) goto failure ;*list_of_contacts = le
ft ;return 1 ;failure :// free memory if necessary
if (line_start_coordinates) delete [] line_start_c
oordinates ;if (line_pointers) delete [] line_poin
ters ;BM_LINKED_LIST_NODE *list, *next_list ;BM_LI
NKED_LIST_NODE *line_in_list, *next_line_in_list ;
for (list =contacts ; list ; list = next_list) {ne
xt_list = list->next() ;for (line_in_list = (BM_LI
NKED_LIST_NODE *) list->get_obj() ; line_in_list ;
line_in_list = next_line_in_list) {next_line_in_l
ist = line_in_list->next();delete line_in_list ;}d
elete list ;}if (new_left) delete new_left ;if(new
_right) delete new_right ;return 0 ;}/* この関数
は2つの面の間のコンタクトのリストを掃引する (B
Mにより殆ど同様に生成される 全ての面から面の接点
を計算する)そして全ての、ただし最大の接点を除去す
る。 基本的には、それは接点のリストを”濾過”し、
最も長い接触部に属さない接触部を除去する。一般に、
最も長い接触部は同時的なベンドラインのリストである
点に注目されたい。かくして、接触部リストの基本構造
は同じである。 例えば、リスト中の第一のノードは最
も長いコンタクト中のコンタクトの数である。 この関
数はまた最も長いコンタクトの長さに戻す。 この関数
においては、全てのコンタクトが閉じられ、従ってコン
タクト中のラインのリストにおいて、ラインの端点は次
のラインの出発点に等しくなるという事実を利用してい
る。 この方法で唯一のトリッキーな部分は、第一の、
および最後のラインにおける重なり部分の長さを計算す
ることにある。次に、リストの中間でラインの長さを付
加する。
【0372】前の関数を参照されたい。*/static doubl
e BM_keep_largest_contact_remove_the_rest(BM_LINKE
D_LIST_NODE **list_of_contacts){long i, j ;if (NUL
L == list_of_contacts) return 0.0 ;BM_LINKED_LIST_
NODE *contacts = *list_of_contacts ;if (NULL == co
ntacts) return 0.0 ;// some of the most importantp
arameters we compute in this function.double lengt
h_of_largest_contact= 0.0 ;long largest_contact_i
= -1 ;// we need to keep track of the lengths of c
ontacts.// we need to store the length of every co
ntact.// // NOTICE : here we try to save some heap
allocation/release time by using apre-allocated//
array if the list of contacts is not very long.//
staticdouble static_contact_len_array[32] ;double
*dynamic_contact_len_array= NULL ;double *contact
_len_array = NULL ;// get the number of contactslo
ng num_of_contacts = (long) contacts->get_obj() ;c
ontacts = contacts->next() ;// if no contacts, del
ete the entire listif (num_of_contacts < 1){// the
re is no list. delete node 0 as well.delete *list_
of_contacts ;*list_of_contacts = NULL ;return 0.0
;}// allocate memory for the contactlength arrayi
f (num_of_contacts <= 32) {contact_len_array = sta
tic_contact_len_array ;}else {if (NULL == (dynamic
_contact_len_array = new double[num_of_contacts]))
goto computation_done__clean_up ;contact_len_arra
y= dynamic_contact_len_array ;}// Scan all known c
ontacts and compute thelength of every contact.//
later we use these values to find the longest cont
act (which could be a simultaneous bendline).BM_LI
NKED_LIST_NODE *last_face1_list, *last_face2_list
;BM_LINKED_LIST_NODE *line_in_list ;double k ;dou
ble first_k1, first_k2 ;double last_k1, last_k2 ;l
ast_face2_list = NULL ;for (i = 0 ; i < num_of_con
tacts ; i++) {if (NULL == last_face2_list) last_fa
ce1_list = contacts ;else last_face1_list = last_f
ace2_list->next() ;last_face2_list = last_face1_li
st->next() ;BM_LINKED_LIST_NODE *left = (BM_LINKED
_LIST_NODE *) last_face1_list->get_obj() ;BM_LINKE
D_LIST_NODE *right = (BM_LINKED_LIST_NODE *) last_
face2_list->get_obj();BM_LINE *first_line_in_left
= (BM_LINE *) left->get_obj() ;BM_LINE *first_line
_in_right = (BM_LINE *) right->get_obj() ;// here
is what we do.we know that the first lines in left
and right have to have// an overlapping part. we
compute overlapping parameters k1 and k2 with resp
ect tothe// first line on the left, between the fi
rst lines. // the idea is that one of the points t
hat corresponds to these parameters (k1 and k2)//i
s the extreme point of the contact. we just don’t
know yet which one.// then we find the last point
s in both lists. we know that they must have non-e
mpty// overlapping part as well. we compute k1 and
k2 for these two lines as well.// then we compate
k1,k2 for the first and last pairs to find the tw
o// extreme points of the contact. distance betwee
n them isthe length of the contact.// compute k1 a
nd k2 for the first lines.first_line_in_left->is_p
oint_on_line(first_line_in_right->get_startpt(),&f
irst_k1) ;first_line_in_left->is_point_on_line(fir
st_line_in_right->get_endpt(),&first_k2) ;// we on
ly want k1 and k2 within the first lineif (first_k
1 < 0.0) first_k1 = 0.0 ;else if (first_k1 > 1.0)
first_k1 = 1.0 ;if(first_k2 < 0.0) first_k2 = 0.0
;else if (first_k2 > 1.0) first_k2 = 1.0 ;// sort
k1 and k2if (first_k1 > first_k2) { k = first_k1
; first_k1 =first_k2 ; first_k2 = k ; }// find th
e last line in the left.for (line_in_list = left->
next() ; line_in_list ; line_in_list = line_in_lis
t->next()) {left = line_in_list ;}// "left" is the
last node in the left now.BM_LINE *last_line_in_l
eft = (BM_LINE *) left->get_obj() ;// find the las
t line in the right.for (line_in_list = right->nex
t() ; line_in_list ; line_in_list = line_in_list->
next()) {right = line_in_list ;}// "right" is the
last node in the left now.BM_LINE *last_line_in_ri
ght = (BM_LINE *) right->get_obj() ;// compute k1
and k2 for the first lines.last_line_in_left->is_p
oint_on_line(last_line_in_right->get_startpt(),&la
st_k1) ;last_line_in_left->is_point_on_line(last_l
ine_in_right->get_endpt(),&last_k2) ;// we only wa
nt k1 and k2 within the last lineif (last_k1 < 0.
0) last_k1 = 0.0 ;else if (last_k1 > 1.0) last_k1
= 1.0 ;if (last_k2 < 0.0) last_k2 = 0.0 ;else if
(last_k2 > 1.0) last_k2 = 1.0 ;// note that we hav
e compute last k1 and k2 with respect to the last
line in the left.// wereally need last k1 and k2 w
ith respect to the first line in the left.BM_POINT
lastk1(last_line_in_left->get_startpt() + last_k1
*(last_line_in_left->get_v())) ;BM_POINT lastk2(la
st_line_in_left->get_startpt() + last_k2*(last_lin
e_in_left->get_v())) ;first_line_in_left->is_point
_on_line(lastk1,&last_k1) ;first_line_in_left->is_
point_on_line(lastk2,&last_k2);// sort k1 and k2if
(last_k1 > last_k2) { k = last_k1 ; last_k1 = las
t_k2 ; last_k2 = k ; }// now we need to take the e
xtreme points of these two pairsif (first_k1 > las
t_k1) first_k1 = last_k1 ;if (first_k2 < last_k2)
first_k2 = last_k2 ;contact_len_array[i] = (first_
k2 - first_k1)*(first_line_in_left->get_len()) ;}/
/ find the longest contact.// the main feature her
e is to check for simultaneous bendlineslast_face2
_list = NULL;for (i = 0 ; i < num_of_contacts ; i+
+) {if (NULL == last_face2_list)last_face1_list =
contacts ;else last_face1_list = last_face2_list->
next() ;last_face2_list = last_face1_list->next()
;// make sure we don’t accept contacts that have
zero length.if (contact_len_array[i] < BM_PRECISI
ON) continue ;BM_LINKED_LIST_NODE *left = (BM_LINK
ED_LIST_NODE *) last_face1_list->get_obj() ;BM_LIN
E *first_line_in_left = (BM_LINE *) left->get_ob
j() ;// check if this contact is part of a simulta
neous bendline.//if yes, add its length to the fir
st bendline in the simultaneous bendline and// set
this length here to -1.0, so that we know it late
rBM_LINKED_LIST_NODE *temp_last_face1_list, *temp_
last_face2_list = NULL ;for (j =0 ; j < i ; j++)
{if (contact_len_array[i] < BM_PRECISION) continue
; // already part of something elseif (NULL == te
mp_last_face2_list) temp_last_face1_list = contact
s ;else temp_last_face1_list = temp_last_face2_lis
t->next() ;temp_last_face2_list = temp_last_face1_
list->next() ;BM_LINKED_LIST_NODE *temp_left = (BM
_LINKED_LIST_NODE *) temp_last_face1_list->get_obj
() ;BM_LINE *temp_first_line_in_left = (BM_LINE *)
temp_left->get_obj() ;// check if the lines overl
apif (! first_line_in_left->is_point_on_line(temp_
first_line_in_left->get_startpt(),NULL)) continue
;if (! first_line_in_left->is_point_on_line(temp_
first_line_in_left->get_endpt(),NULL)) continue ;/
/ ok, they overlap// add the length to the first i
n simultaneous bend and set this to -1.0contact_le
n_array[j] += contact_len_array[i] ;contact_len_ar
ray[i] = -1.0 ;break ;}}// in this loop we actuall
y find the largestfor (i = 0 ; i < num_of_contacts
; i++) {// check to see if this new contact is th
e largestif (length_of_largest_contact <contact_le
n_array[i]) {length_of_largest_contact = contact_l
en_array[i];largest_contact_i = i ;}}computation_d
one__clean_up :// remove all other contacts that a
re not largestBM_LINKED_LIST_NODE *next_last_face1
_list, *next_last_face2_list = NULL ;BM_LINKED_LIS
T_NODE *largest_contact_list_f1 = NULL, *largest_c
ontact_list_f2 ;last_face1_list = contacts ;last_f
ace2_list = last_face1_list->next() ;for (i = j =
0 ; i < num_of_contacts ; i++) {next_last_face1_li
st = last_face2_list->next() ;if (next_last_face1_
list) next_last_face2_list = next_last_face1_list-
>next() ;else next_last_face2_list = NULL ;// make
sure we don’t delete the largest contact// note
: we skip two lists, face1 list and face2 listif
(contact_len_array[i] < 0.0 || largest_contact_i =
= i) {if (NULL == largest_contact_list_f1) largest
_contact_list_f1 = last_face1_list ;else largest_c
ontact_list_f2->add_after(last_face1_list) ;larges
t_contact_list_f2 = last_face2_list ;// count the
number of contacts++j ;last_face1_list = next_last
_face1_list ;last_face2_list = next_last_face2_lis
t ;continue ;}// ok,this is not the largest contac
t, delete both face1 and face2 sides of the contac
tBM_LINKED_LIST_NODE *next_line_in_list ;for (line
_in_list = (BM_LINKED_LIST_NODE *) last_face1_list
->get_obj() ; line_in_list ; line_in_list = next_l
ine_in_list) {next_line_in_list = line_in_list->ne
xt() ;delete line_in_list ;}for (line_in_list = (B
M_LINKED_LIST_NODE *) last_face2_list->get_obj() ;
line_in_list ; line_in_list = next_line_in_list)
{next_line_in_list = line_in_list->next() ;delete
line_in_list ;}delete last_face1_list ;delete last
_face2_list ;last_face1_list = next_last_face1_lis
t ;last_face2_list = next_last_face2_list ;}// end
the contact listwith a NULL pointerif (largest_co
ntact_list_f2) largest_contact_list_f2->add_after
(NULL) ;// write the number of contacts left in no
de 0. also,set the correct beginning of the list./
/ however, if there is no contact, erase the entir
e list.if (NULL == largest_contact_list_f1) {// th
ereis no list. delete node 0 as well.delete *list_
of_contacts ;*list_of_contacts = NULL ;}else {(*li
st_of_contacts)->set_obj((BM_BASIC *) j) ;(*list_o
f_contacts)->add_after(largest_contact_list_f1) ;}
// delete dynamic_contact_len_array if it was allo
catedif (dynamic_contact_len_array) delete [] dyna
mic_contact_len_array ;return length_of_largest_co
ntact ;}/*この関数は、サブルーチンとして静的なin
t BM create ベンドライン(...)によ
ってのみ用いられる。 現在の大きな問題は、我々が幾
つかのラインを削除しているということである。 この
問題は、我々が同時ベンドを持つとき、他のコンタクト
はなお我々が丁度削除したこれらのラインを参照してい
ることが出来るということである。 我々は進んでそれ
をチェックしなければならず、もし真なら、有効な参照
によりポインタを我々が変更し/削除したラインに置き
換えなければならない。 すなわち、影響されたライン
は左側の最初のそして最後のラインである。 潜在的に
は、それらに対する参照は11および13を参照して置
き換えられる必要がある。*/static void check_refere
nces_in_remaining_contacts(BM_LINKED_LIST_NODE *si
de_1, // current list we are working withBM_LINKED
_LIST_NODE *side_2, // list on the other side of t
hecontactBM_LINE *line1, BM_LINE *line3, // these
are old references, tobe checked if still validBM_
LINE *l1, BM_LINE *l3 // l1 and l3 are thenew refe
rences){BM_LINKED_LIST_NODE *side1 = side_1, *side
2 = side_2 ;process_next_contact :// find the begi
nnings of lists in the next contactBM_LINKED_LIST_
NODE *contact_list ;if (NULL == (contact_list = si
de1->next())) return ; // done, no more listsif (N
ULL == (side1 = contact_list->next())) return ; //
done, no more listsif (NULL == (contact_list = si
de2->next())) return ; // done, no more listsif (N
ULL == (side2 = contact_list->next())) return ; //
done, no more lists// now we need to check thebeg
inning of this contact and the end of this contact
exactly the sameway.// 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 tocontinue 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
checkwhich of l1 and l3 overlaps the first line in
side2. we know that exactly one of// l1 and l3 ha
s to overlap. then we replace the reference to lin
e1/line3 with a reference to the// one of l1/l3 th
at overlaps the first line in side2.BM_LINKED_LIST
_NODE *start_side1 = (BM_LINKED_LIST_NODE*) side1-
>get_obj() ;BM_LINKED_LIST_NODE *start_side2 = (BM
_LINKED_LIST_NODE *) side2->get_obj() ;// check th
e 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 == line
3) {if (l1) { // check if l1 overlaps first line i
nside2if (line_in_side2->is_point_on_line_segment
(l1->get_startpt(), NULL) ||line_in_side2->is_poin
t_on_line_segment(l1->get_endpt(), NULL)) {start_s
ide1->set_obj(l1) ;goto process_next_contact ;}}if
(l3) { // check if l3 overlaps first line in side
2if (line_in_side2->is_point_on_line_segment(l3->g
et_startpt(), NULL) ||line_in_side2->is_point_on_l
ine_segment(l3->get_endpt(), NULL)) start_side1->s
et_obj(l3) ;}goto process_next_contact ;}BM_LINKED
_LIST_NODE *line_in_list, *prev_line_in_list ;// f
ind the last line in side2.for (line_in_list = sta
rt_side2->next() ; line_in_list ; line_in_list = l
ine_in_list->next()) {prev_line_in_list = line_in_
list ;}// "prev_line_in_list" is the last node in
the left now.line_in_side2 = (BM_LINE *) prev_line
_in_list->get_obj() ;// find the last line in side
1.for (line_in_list = start_side1->next() ; line_i
n_list ; line_in_list = line_in_list->next()) {pre
v_line_in_list = line_in_list ;}// "prev_line_in_l
ist" is the last node in side1 now.line_in_side1 =
(BM_LINE*) prev_line_in_list->get_obj() ;// check
the end of the contactif (line_in_side1 == line1
|| line_in_side1 == line3) {if (l1) { // check if
l1overlaps first line in side2if (line_in_side2->i
s_point_on_line_segment(l1->get_startpt(), NULL) |
|line_in_side2->is_point_on_line_segment(l1->get_e
ndpt(), NULL)) {prev_line_in_list->set_obj(l1) ;go
to process_next_contact ;}}if (l3) { // check if l
3 overlaps first line in side2if (line_in_side2->i
s_point_on_line_segment(l3->get_startpt(), NULL) |
|line_in_side2->is_point_on_line_segment(l3->get_e
ndpt(), NULL)) prev_line_in_list->set_obj(l3) ;}}g
oto process_next_contact ;}/* この関数は、入力と
して与えられたコンタクトリストに基づいて、2つの面
間に簡単な(規則的な)ベンドラインを形成する。一端
これがなされると、それはコンタクトリストを消去す
る。 この関数では、面のエッジは左手の規則に従って
分類されると仮定する。
【0373】この関数は、もし全てがファインのとき
は、TRUEに戻す。 NB!ここでの問題点は、新し
いベンドラインを形成したとき、何かを部分的に無効に
することではない。 それを完成するために、我々は、
分離であるベンドopを形成し(ベンドライン無しに)
(原文理解出来ず)、後にそれをベンドラインに付加す
る。 更に、我々は、ベンドラインが形成され、部分に
付加された後にのみトポロジーを形成する。 この関数
は、面1(主として、垂直な面1)に一致するベンドラ
イン情報を形成する点に注目されたい。 ただし、垂直
な面2はこの情報と不一致でもよいが、後に固定されな
ければならない。*/static int BM_create_bendline(BM
_PART & part, BM_LINKED_LIST_NODE **contact, BM_BE
NDLINE **bendline_created /* OUT */){// so far, no
thing is created*bendline_created= NULL ;// it is
possible, that we are building bendlines for the f
latversion of the part.// if this variables is TRU
E, we are building bendlines for the 3D-version, o
therwise for the flat.int using_3D_version = 1 ;//
later we need to create a bendline centerline// t
hese are the start-end points of the bendline cent
erline// note that they are points p1 andp2 on the
face1 side of the bendline// this is done because
sometimes (when the bendline is not bent) we use
the// face1 surface as the bendlinesurface, ie. th
e bendline orientation is defined// with respect t
o face1BM_POINT bendline_centerline_p1, bendline_c
enterline_p2 ;// contact list parametersBM_LINKED_
LIST_NODE *line_in_list, *next_line_in_list ;BM_LI
NKED_LIST_NODE *left, *right ;int number_of_lists
= (long) (*contact)->get_obj() ;BM_LINKED_LIST_NOD
E *contact_list = (*contact)->next() ;left =(BM_LI
NKED_LIST_NODE *) contact_list->get_obj() ;right =
(BM_LINKED_LIST_NODE *) (contact_list->next())->g
et_obj() ;BM_LINE *first_line_in_left= (BM_LINE *)
left->get_obj() ;BM_LINE *first_line_in_right =
(BM_LINE*) right->get_obj() ;BM_LINE *last_line_in
_left ;BM_LINE *left_line, *right_line ;// get loo
ps in both bodiesBM_LOOP *face1_loop = first_line_
in_left->get_loop() ;BM_LOOP *face2_loop = first_l
ine_in_right->get_loop();if (NULL == face1_loop ||
NULL == face2_loop) return 0 ;// 2D-bodies of eit
her faceBM_2D_BODY *face1_body = face1_loop->get_2
D_body() ;BM_2D_BODY *face2_body = face2_loop->get
_2D_body() ;if (NULL == face1_body || NULL == face
2_body) return 0 ;// get face1 and face2BM_FACE *f
ace1 = (BM_FACE *) face1_body->get_3D_body() ;BM_F
ACE *face2 = (BM_FACE *) face2_body->get_3D_body()
;if (NULL == face1 || NULL == face2) return 0 ;//
check whether we are using the flat version of th
e part, or 3D-version of the part.if (face1->get_c
urrent_3D_version() != face1_body || face2->get_cu
rrent_3D_version() != face2_body) using_3D_version
= 0 ;// get surfacesof either facesBM_PLANE *face
1_plane, *face2_plane ;face1_plane = (BM_PLANE *)
face1_body->get_surface() ;face2_plane = (BM_PLANE
*) face2_body->get_surface() ;/* 先ず、ベンドラ
インと共にしなければならない全てのこと、ベンドライ
ンを形成する、ベンドopを形成する、ベンドopパラ
メータを設定する、ベンドラインに対するシリンダを形
成、設定する、ベンドライン、センタラインを設定する
などを行う。*/// try to figure out whether we have
aFRONT or BACK bend.BM_VECTOR v_face2_body((face2
_plane->get_normal())*(first_line_in_right->get_
v())) ; // this vector// points towards the inside
of face2 on the plane of face2BM_VECTOR v_face2_n
ormal(v_face2_body*(first_line_in_left->get_v()))
; // this is the correct normal for face2?// comp
ute the angle between facesdouble angle = v_face2_
normal ^ (face1_plane->get_normal()) ;// compute b
end type (FRONT/BACK)if (fabs(angle) <= BM_ANGLE_T
OLERANCE) angle = PI ;else {BM_VECTOR v((face1_pla
ne->get_normal())*v_face2_normal) ;if (v % (first_
line_in_left->get_v()) > 0.0)angle = PI + angle ;
// BACK bendelse angle = PI - angle ; // FRONT ben
d}// create a new empty bendline and add it to the
partBM_2D_BODY *new_auto_bendline = new BM_2D_BOD
Y ;if (NULL == new_auto_bendline) return 0 ;BM_BEN
DLINE *new_bendline = new BM_BENDLINE(&part, using
_3D_version ? NULL : new_auto_bendline, using_3D_v
ersion ? new_auto_bendline : NULL) ;if(NULL == new
_bendline) {delete new_auto_bendline ;return 0 ;}/
/ createa regular bend op for the bendlineBM_BEND_
OP_REGULAR *new_bend_op = newBM_BEND_OP_REGULAR(NU
LL,angle,0.0,0.0) ; // don’t attach to bendline y
etif (NULL == new_bend_op) {delete new_bendline ;r
eturn 0 ;}// attach this bend op to the bendline.
this will just assign the bend_op variable inthe b
endlinenew_bendline->attach_bend_op(new_bend_op) ;
// create bendline surface. if angle is not 180 de
grees, we create a cylinder, otherwisea (face1) pl
ane.BM_SURFACE *bend_surface ;if (fabs(angle - PI)
<= BM_ANGLE_TOLERANCE) { // bendline not being be
nt// note : face1 plane is thebendline surfacebend
_surface = new BM_PLANE(*face1_plane) ;new_bendlin
e->Do_This_Bend(0) ; // this will invalidate 3D ve
rsion as well. later wevalidate it.// set sense to
the same as face1 sensenew_auto_bendline->set_sen
se(face1_body->get_sense()) ;}else {// first, comp
ute vxBM_VECTOR v_face1_body((face1_plane->get_nor
mal())*(first_line_in_left->get_v())) ;// v_face1_
body points towards the inside of face1 on the pla
ne of face1v_face1_body.set_length(-1.0) ; // inve
rt and normalizev_face2_body.set_length(-1.0) ; //
invert and normalize// this is the vx vector of t
he bendline surfaceBM_VECTOR vx(v_face1_body + v_f
ace2_body) ;bend_surface =new BM_CYLINDER(first_li
ne_in_left->get_startpt(), first_line_in_left->get
_endpt(), vx, 0.0) ;new_bendline->Do_This_Bend(1)
; // this will invalidate 3D version as well. lat
er we validate it.// set sense to 0, because we wa
nt the bendline (cylinder) to represent explicitly
OUTSIDE// ie.thickness vector is opposite to the
normal (= radius vector).new_auto_bendline->set_se
nse(0) ;}if (NULL == bend_surface) {delete new_ben
dline ;return 0 ;}new_auto_bendline->set_surface(b
end_surface) ;// lastly we need to create the bend
line 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 do that ne
xt, and when done, will create bendline centerlin
e./* 第二に、必要なら、幾つかのラインを破断し、全
ての隣接ラインを1つの隣接ラインに結合する。更に、
面1-ベンドラインと面2-ベンドラインの間の隣接情報
を形成する。
【0374】*/// notice that processing one side o
f the contact is independent of the other side.//
moreover, the logic is exactly the same. therefor
e, we will use the following code// to process bot
h face1’ side and face2’ side.char face2_process
ed = 0 ;process_one_side_of_the_contact :// in gen
eral, the contact line (on the side of either face
(face1 and face2)) will consist// of three lines
- we have a list of lines, first line is theline b
efore the contact, the// second line is the contac
t line, the lastline is the line after the contac
t.// these variables will be used to compute these
three lines.double k ;double k0, k1, k2, k3 ; //
parametersk for the first line in the leftdouble e
nd_k1, end_k2 ; // parameters kfor the last line i
n the left listBM_POINT p0, p1, p2, p3 ; // p0 - p
3are the endpoints of the edges that will be left
(ie. endpoint of left_line, l2, l3).// p0 and p3 a
nd 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 t
he line that is adjacent, l3 is the one after it./
/ process first line of the left sidek0 = 0.0 ;k3
= 1.0 ;first_line_in_left->is_point_on_line(first_
line_in_right->get_startpt(),&k1) ;first_line_in_l
eft->is_point_on_line(first_line_in_right->get_end
pt(),&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 ; k1 = k2;
k2 = k ; }// note that we cannot yet compute p0,
p1 and p3 because wedon’t know the relative order
// of the first and last lines in the left list//
find and process the last linefor (line_in_list =
left ; line_in_list ; line_in_list = next_line_in_
list) {if (NULL == (next_line_in_list = line_in_li
st->next())) {left_line = (BM_LINE *) line_in_list
->get_obj() ;// first, we have to find the end of
the face2 listfor (line_in_list = right ; line_in_
list ; line_in_list = next_line_in_list) {if (NULL
== (next_line_in_list = line_in_list->next())) bre
ak ;}right_line = (BM_LINE *) line_in_list->get_ob
j() ;left_line->is_point_on_line(right_line->get_s
tartpt(),&end_k1) ;left_line->is_point_on_line(rig
ht_line->get_endpt(),&end_k2) ;if (end_k1 > 1.0) e
nd_k1 = 1.0 ;else if (end_k1 < 0.0) end_k1 = 0.0 ;
if (end_k2 > 1.0) end_k2 = 1.0 ;else if (end_k2 <
0.0) end_k2 = 0.0 ;if (end_k2 < end_k1) { k = end_
k1 ; end_k1 = end_k2 ; end_k2 =k ; }break ;}}// no
w we have to compute points p0, p1, p2 and p3.// b
utfirst we need to convert end-k parameters to equ
ivalent parameters withrespect to the // first lin
e in the leftp0 = left_line->get_startpt() ;p1 = l
eft_line->get_startpt() + end_k1 * (left_line->get
_v()) ;p2 = left_line->get_startpt() + end_k2 * (l
eft_line->get_v()) ;p3 = left_line->get_endpt() ;/
/ check k0first_line_in_left->is_point_on_line(p0,
&k) ;if (k< k0) k0 = k ;// check k1first_line_in_l
eft->is_point_on_line(p1,&k) ;if(k < k1) k1 = k ;/
/ check k2first_line_in_left->is_point_on_line(p2,
&k);if (k > k2) k2 = k ;// check k3first_line_in_l
eft->is_point_on_line(p3,&k) ;if (k > k3) k3 = k ;
// here we can compute p0, p1 and p3. later wecomp
ute p2.p0 = first_line_in_left->get_startpt() + k0
* (first_line_in_left->get_v()) ;p1 = first_line_
in_left->get_startpt() + k1 * (first_line_in_left-
>get_v()) ;p2 = first_line_in_left->get_startpt()
+ k2 * (first_line_in_left->get_v()) ;p3 = first_l
ine_in_left->get_startpt() + k3 *(first_line_in_le
ft->get_v()) ;// ok, we have computed p0-p3. now w
e will erase left list, except for the first line.
// we need the first linelater.// actually, the fi
rst line will, in the future, point to new linel2.
BM_LOOP *left_loop = first_line_in_left->get_loo
p() ;last_line_in_left = NULL ; // the last line i
n the left. we need it later to replace out-of-dat
e pointers with valid ones.line_in_list = left->ne
xt() ; // thisis the second line in the left list.
left->add_after(NULL) ;// note : wewill erase all
lines in the left list, starting from the second l
ine.for (; line_in_list ; line_in_list = next_line
_in_list) {next_line_in_list= line_in_list->next()
;// store a pointer to the last linelast_line_in_
left = (BM_LINE *) line_in_list->get_obj() ;left_l
oop->remove_edge(last_line_in_left) ;delete last_l
ine_in_left ;delete line_in_list ;}// finally, cre
ate the adjacent line l2, and two more lines (l1 a
nd l3) if necessary.if (p0 != p1) {l1 = first_line
_in_left ;l1->set(p0,p1) ;l2 = new BM_LINE(p1,p2)
;left_loop->add_edge_after(l1,l2) ;}else {l1 = NU
LL ;l2 = first_line_in_left ;l2->set(p0,p2) ;}if
(p2 != p3) {l3 = new BM_LINE(p2,p3) ;left_loop->ad
d_edge_after(l2,l3) ;}else l3 = NULL ;// last thin
g, create topology by making this line adjacent to
the bendlinel2->make_body_adjacent(new_bendline)
;// a big problem now is that we have deleted som
e lines.// the problem is that if we have a simult
aneous bend, other contacts could still be referin
g// to these lines we just deleted.// we have to g
o and check that, and if true, replace pointers to
the lines we have changed/deleted// with valid re
ferences.// // namely, lines that areaffected are
the first and last lines in the left.// potentiall
y references to them need to be replaced with refe
rences to l1 and l3.if (l1 || l3) check_references
_in_remaining_contacts(face2_processed ? contact_l
ist->next() : contact_list, // current list we are
working withface2_processed ? contact_list : cont
act_list->next(), // list on the other side ofthe
contactfirst_line_in_left, last_line_in_left, // t
hese are old references, to be checked if still va
lidl1, l3 // l1 and l3 are the new references) ;//
we will use the same piece of code to process bot
h sides of the contact.// if face2 side has not be
en processed, do it now.// however, first we need
to set some values of variables that are commonly
used.if (! face2_processed) {face2_processed = 1 ;
// first, l2 should be the left line.// l2 is the
real adjacent line (on the left). now it becomes t
he right line.left->set_obj(l2) ;// now we need to
switch left and rightsides// switch linesfirst_li
ne_in_left = first_line_in_right ;first_line_in_ri
ght = l2 ;// switch listsline_in_list = left ;left
= right ;right= line_in_list ;// store bendline c
enterline start-end pointsbendline_centerline_p1 =
p1 ;bendline_centerline_p2 = p2 ;goto process_one
_side_of_the_contact ;}/*ここで、コンタクトリスト
を削除することが出来る。*/BM_LINKED_LIST_NODE *lis
t, *next_list ;int lists_deleted = 0 ; // note, we
can only delete first two listsfor (list = contac
t_list ; lists_deleted <2 && list ; list = next_li
st) {next_list = list->next() ;// delete thelistfo
r (line_in_list = (BM_LINKED_LIST_NODE *) list->ge
t_obj() ; line_in_list ; line_in_list = next_line_
in_list) {next_line_in_list = line_in_list->next()
;delete line_in_list ;}delete list ;++lists_delet
ed ;}// setthe correct number of contacts left and
update the pointerslong num_contacts = (long) (*c
ontact)->get_obj() ;if (--num_contacts < 1) {// if
nocontacts left, erase the whole contacts listdel
ete *contact ;*contact =NULL ;}else {(*contact)->s
et_obj((BM_BASIC *) num_contacts) ;(*contact)->add
_after(list) ;}/* 最後に、センタラインを形成す
る。方向と長さが正しいことを確かにする。 p1とp
2は面1に関して規定される点に注目されたい。 すな
わち、p1->p2は面1の側のコンタクトに対する方
向である。*/BM_LINE centerline(bendline_centerline
_p1,bendline_centerline_p2) ;if (fabs(angle - PI)
<= BM_ANGLE_TOLERANCE) { // bendline not being ben
t// face1plane is the bendline surfaceif (face1->g
et_idx() > face2->get_idx()) centerline.reverse_li
ne() ;}else if (angle < PI) {if (face1->get_idx()
<face2->get_idx()) centerline.reverse_line() ;}els
e { // angle is > PIif(face1->get_idx() > face2->g
et_idx()) centerline.reverse_line() ;}new_auto_ben
dline->set_center_line(centerline) ;// if we are b
uilding bendlines for the 3D-version of the part,
// make sure 3D-version of the bendline is validat
ed because most likely we // want to UNFOLD right
away.if (using_3D_version) new_bendline->validate_
3D_version() ;*bendline_created= new_bendline ;ret
urn 1 ;}/* この関数の目的は、面からなる切断された
要素を持つ部分であって、この部分が、これらの新しい
ベンドラインを付加すると、接続されるようになるよう
に最小数のベンドラインを形成することにある。This f
unction assumes that the part has thickness 0.The
basic idea we usein this function is maximum spann
ing tree.We model the part by an undirected graph,
where faces are the nodes of the graph andthere i
s an edge between two nodes iff these two faces ar
e in contact (ie. are touching each other),the cos
t (or length) of the edge is the length of the lon
gestcontact between these two faces (ie. the lengt
h of the longest possiblebendline between the two
faces).In order to create bendlines we computea ma
ximum spanning tree for this graph and create aben
dline for every edge of the graph that is in the m
aximum spanning tree.There are two problems howeve
r :- It could be that the part already contains so
me bendlines(ie. some faces are already connecte
d).- When we compute the maximum spanning tree, we
can have two fringe-edges that have the same le
ngth.In that case, we don’t want to break ties ra
ndomly, but instead choosean edge that would min
imize the diameter of the spanning tree (the maxim
um distance between any two vertices of the tre
e).Algorithm :-----------We will process faces one
-by-one, starting from the first faces of the part
and proceedinguntil the last faces, and building
the maximum spanning tree along the way as we go.F
or every pair of faces, such that at least one of
the is not yet in the spanning tree,we keep the lo
ngest contact between them. When we expand the spa
nning tree, we choosethe contactbetween a face in
the tree and a face not in the tree that is the lo
ngest contactbetween any face in the tree and a fa
ce outside. If there is atie, we choose an edge th
atwould minimize the *//* 面(面1)を与えると、
この構造はこの面と他の面の間のコンタクトについての
情報を含む。 任意の2つの面に対して、これらの面の
間にコンタクトが有るか否かを知る必要があり、もしイ
エスなら、何がその長さであるかを知る必要がある。こ
のデータを処理する最も簡単な方法はそれを二次元配列
として記憶することにより与えられる。しかし、これは
多くのスペースを取り、その殆どは無駄に使われ、とい
うのは、通常は、多くの面があるときは、それらの殆ど
はそれらの面の間で何らのコンタクトも持たないことに
よる。 代わりに、我々は全ての面に対してこの情報を
構造のリストとして記憶することになる。我々は、2つ
の面の間のコンタクトの長さが0より大きいときにのみ
この記録を(すなわち、構造)生成する。*/typedef st
ruct CONTACT_INFO {// here we will keep track what
is the length of the longest contact between any
two faces// this is really a two-dimensional array
double length ;// here we keep a pointer to the ot
her faceBM_FACE *face2 ;// here we will keep the l
ongest contact for any two faces// this is really
a two-dimensional array stored as a linked list of
lists.BM_LINKED_LIST_NODE *contact ;// a pointer
to the next structure in alistCONTACT_INFO *next
;} contact_info ;/*これは、このファイルにおいて
多くの関数により用いられる非常に基本的な関数であ
る。 それはコンタクトリストを削除する。*/static v
oid delete_contact_info_list(contact_info *list){c
ontact_info *c, *c_next ;BM_LINKED_LIST_NODE *clis
t, *next_clist ;BM_LINKED_LIST_NODE *line_in_list,
*next_line_in_list ;for (c = list ; c ;c = c_nex
t) {c_next = c->next ;if (c->contact) {// skip the
header = num of contactsfor (clist = (c->contact)
->next() ; clist ; clist = next_clist) {next_clist
= clist->next() ;// delete the listfor (line_in_l
ist =(BM_LINKED_LIST_NODE *) clist->get_obj() ; li
ne_in_list ; line_in_list=next_line_in_list) {next
_line_in_list = line_in_list->next() ;delete line_
in_list ;}delete clist ;}// delete the headerdelet
e c->contact ;}delete c ;}}static void delete_cont
act_info_structure(contact_info *c){BM_LINKED_LIST
_NODE *clist, *next_clist ;BM_LINKED_LIST_NODE *li
ne_in_list, *next_line_in_list ;if (NULL == c) ret
urn ;if (c->contact) {// skip the headerfor (clist
= (c->contact)->next() ; clist ; clist = next_cli
st) {next_clist = clist->next() ;// delete the lis
tfor (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 ;}// dele
te the headerdelete c->contact ;}delete c ;}/* こ
の関数は2つの面の間で最良の(すなわち、最も長い)
コンタクトを計算し、格納する。*/static int compute
_the_longest_contact_between_faces(BM_FACE & face1
/* IN */, BM_FACE & face2 /* IN */,contact_info *
*computed_contact_list /* OUT */){// so far we hav
e computed nothing*computed_contact_list = NULL ;B
M_LINKED_LIST_NODE *contact_list ; // a list of al
l contacts between face1 and face2 we will compute
if (! BM_compute_all_face_to_face_contacts(face1,
face2, &contact_list)) return 0 ;double x = BM_kee
p_largest_contact_remove_the_rest(&contact_list) ;
if (x < BM_PRECISION) return 1 ; // no contact bet
ween these two facescontact_info *c ;if (NULL ==
(c = new contact_info)) {// delete contact listBM_
LINKED_LIST_NODE *clist, *next_clist ;BM_LINKED_LI
ST_NODE *line_in_list, *next_line_in_list ;for (cl
ist = contact_list->next() ; clist ; clist = next_
clist) {next_clist = clist->next() ;// delete the
listfor (line_in_list = (BM_LINKED_LIST_NODE *) cl
ist->get_obj() ; line_in_list ; line_in_list = nex
t_line_in_list) {next_line_in_list = line_in_list-
>next() ;delete line_in_list ;}delete clist ;}dele
te contact_list ;return 0 ;}// initialize the stru
cturec->contact = contact_list ;c->next = NULL ;c-
>face2 = &face2 ;c->length = x ;*computed_contact_
list = c ;return 1 ;}/* この関数は現在接続された
要素に新しい面を付加する。 それはまた、この新しい
面と、処理されていない他の全ての面の間の最も長いコ
ンタクトを計算する。*/static int add_face_to_conne
cted_component(BM_PART *part, BM_FACE *face2 /* th
is is the face we are adding to the connected comp
onent */, long *end_id /* an index of the last fac
e in the connected component. this is where face2
is. */, contact_info **all_contacts /* all contact
info between face2 andother outside faces will be
here *//* we will compute it and constructthis li
st in this function */,BM_FACE **idx_to_face_mappi
ng){BM_FACE *current_face ;contact_info *last_clis
t = NULL, *cl ;// just in case face2 has no adjace
nt faces outside the connected componentall_contac
ts[*end_id] = NULL ;// in this loop we want to com
pute all contacts between face2and all other// fac
es not yet in any connected component.for (current
_face = part->get_face_list() ; current_face ; cur
rent_face = (BM_FACE *) current_face->next()) {if
(current_face->get_user_id() >= 0) continue ; // c
urrent_face is in some other connected component//
compute the best contact between face2 and curren
t_faceif (! compute_the_longest_contact_between_fa
ces(*face2, *current_face, &cl)) return 0 ;if (NUL
L == cl) continue ; // there is no contact between
these two facesif (NULL == last_clist) all_contac
ts[*end_id] = cl ;else last_clist->next = cl ;last
_clist= cl ;}face2->set_user_id(*end_id) ;idx_to_f
ace_mapping[*end_id] = face2;++(*end_id) ;return 1
;}/* これらの2つの関数は、ユーザがトポロジーグ
ラフにおける2つの面の間の距離を設定し得ることを許
容する。 dist btw 面は二次元配列の上部右半部であ
る。*/static long get_face2face_dist(unsigned char
*dist_btw_faces,long number_of_faces, long dist_a
rray_size, longj, long i){long k ;// distance betw
een face_i and face_i is zeroif (i ==j) return 0 ;
// sort indecesif (j < i) { k = i ; i = j ; j = k
; }k = number_of_faces - i ;return dist_btw_faces
[dist_array_size - ((k*(k-1)) >> 1) + (j - i) - 1]
;}static void set_face2face_dist(unsigned char *d
ist_btw_faces,long number_of_faces, long dist_arra
y_size, long j, long i, unsigned char distance){lo
ng k ;// distance 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 ;}/* この関数は接続
された要素における所定の面と他の面の間の最大距離を
戻す。*/static long get_largest_distance_for_face
(unsigned char *dist_btw_faces,long number_of_face
s, longdist_array_size, long start_id, long end_i
d, long face_id){long j, k ;if (NULL == dist_btw_f
aces) return 0 ;long current_face_to_face_distance
= 0 ;for (j = start_id ; j < end_id ; j++) {k = ge
t_face2face_dist(dist_btw_faces,number_of_faces,di
st_array_size,j,face_id) ;if (k > current_face_to_
face_distance) current_face_to_face_distance = k
;}return current_face_to_face_distance ;}/* これ
は主要なAutobend関数である。その目的は部分
に対するベンドラインを自動的に生成することにある。
*/int BM_PART::auto_bend(void){long i, j, k ;BM_FA
CE *current_face ;BM_FORMING *current_forming ;BM_
BENDLINE *current_bendline ;// at end of the funct
ion werelease memory. this code for releasing memo
ry is shared// between thecases when this function
fails, or succeeds.// therefore, before we getto
that code, we have to know the return code.int ret
_value ;// these are the two faces we will be crea
ting a bendline for (ie. between these two faces).
BM_FACE *face1, *face2 ;// here we keep a list of
information about contacts between every face and
other faces.// this is an array lists.contact_info
**all_contacts = NULL ;// here we will keep track
what face corresponds to each row in face_to_face
_length[] and all_contacts[]arraysBM_FACE **idx_to
_face_mapping = NULL ;// this (two-dimensional) ar
ray is used to store distances between faces in th
e TOPOLOGY GRAPH.// these distance values are used
to break ties in the maximum spanning treealgorit
hm when// two edges have the same length. Note tha
t the distancebetween (i,j) is the same as// the d
istance between (j,i). This means that the distanc
e matrix is a symmetric matrix, and we// only need
to store one half (upper right triangle) to save
space.// we will use this method of breaking ties
only when the number of faces is less than 256.//
this has two advantages : 1) the distance between
any two faces is alwaysless than 256,// and theref
ore we only need a char (8 bits) to store thedista
nce values, 2) since we only// need a char for a p
air, the total this array can take is 32K bytes, w
hich is not too much memory.unsigned char *dist_bt
w_faces = NULL ;// this will be the size of the di
stance array, given some number of faceslong dist_
array_size ;// we will have to create a heap becau
se some portion of the part can already be connect
ed//and we need to make sure we don’t create any
bendlines for that portion of the part.// we will
use a heap to traverse that portion of the part.lo
ng body_priority = number_of_formings + number_of_
faces + number_of_bendlines ;// Check if there are
any bodies. If no, we are done.if (body_priority
< 1) return 1 ;// this is the heap we will allocat
e. this is used when we add a face to the connecte
d component// to add all other faces connected to
it as well. the problem is that the part could alr
eady//contain some bendlines.DBM_HEAP *heap = NULL
;// this is the start-index(in face_to_face_lengt
h[] and all_contacts[]) arrays // of the currentco
nnected componentlong start_id = 0 ;// this is the
end-index (in face_to_face_length[] and all_conta
cts[]) arrays // of the current connectedcomponent
long end_id = 0 ;// if TRUE, we are starting a new
connected componentint starting_new_connected_com
ponent = 1 ;// allocate memory forlocal variablesi
f (NULL == (all_contacts = new contact_info*[numbe
r_of_faces])) goto failure ;if (NULL == (idx_to_fa
ce_mapping = new BM_FACE*[number_of_faces])) goto
failure ;if (NULL == (heap = new DBM_HEAP(0,NULL,N
ULL,body_priority))) goto failure ;if (number_of_f
aces < 256) { // allocate memory for the face-face
distance array only when // the number of faces i
s not too largedist_array_size = (number_of_faces*
(number_of_faces- 1)) >> 1 ;if (NULL == (dist_btw_
faces = new unsigned char[dist_array_size])) goto
failure ;}++body_priority ; // just in case, we do
n’t wantthe priority to go to 0 later.// initiali
ze arraysfor (i = 0 ; i < number_of_faces ; i++)
{all_contacts[i] = NULL ;idx_to_face_mapping[i] =
NULL ;}// initially mark all faces as not processe
dfor (i = 0, current_face= first_face ; current_fa
ce ; current_face = (BM_FACE *) current_face->next
()) {current_face->this_body_already_processed = 0
;// this will tell us whether this face has been
already processed.// if yes, this id isthe index i
n face_to_face_length[] and all_contacts[] arrays.
current_face->set_user_id(-1) ;}/* 先ず、面の現在
接続された要素の最大スパンツリーを拡大することを試
みる。*/// these two variables are used in tie-bre
akinglong best_face_to_face_distance, current_face
_to_face_distance ;// thisis the length of the bes
t contact so far (ie. the longest contact)double b
est_length ;// this is a pointer to the best conta
ct_info structure found so farcontact_info *best_c
ntct ;expand_spanning_tree :// first, check if all
faces have been processed// end_id is where we wi
ll put the next face we add to the connected compo
nentif (end_id >= number_of_faces)goto done ;conta
ct_info *cntct, *cntct_next, *cntct_prev ;best_len
gth =-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 face that has the largest contact betw
een itself and an adjacent face outside the// curr
ent connected component.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 component and all of itsadjacent faces o
utside the connected component.cntct_prev = NULL ;
for (cntct = all_contacts[i] ; cntct ; cntct = cnt
ct_next) {cntct_next = cntct->next ;// check if th
is adjacent face is already processedif ((cntct->f
ace2)->get_user_id() >= 0) {// this means that fac
e2 has already been added to the connected compone
nt// and we don’t really need the contact info st
ored in this structure any more.// we will delete
it.// this willsome time in the future and free up
some space.delete_contact_info_structure(cntct) ;
if (NULL == cntct_prev) all_contacts[i] = cntct_ne
xt ;elsecntct_prev->next = cntct_next ;continue ;}
// ok, this adjacent face notprocessed. // check i
f it is better than the previously known best.// f
irst check if there is a tie, and if we have alloc
ated a face-face distance array// then use the fac
e-to-face distances to break the tieif (fabs(cntct
->length - best_length) <= distance_tolerance && d
ist_btw_faces) {// if tie-breaking is used, comput
e the largest distance for this face (ie. face1)cu
rrent_face_to_face_distance = get_largest_distance
_for_face(dist_btw_faces,number_of_faces, dist_arr
ay_size, start_id, end_id, i) ;//prefer the one wi
th the smaller largest distanceif (current_face_to
_face_distance < best_face_to_face_distance) {face
1 = idx_to_face_mapping[i];face2 = cntct->face2 ;b
est_length = cntct->length ;best_cntct = cntct;bes
t_face_to_face_distance = current_face_to_face_dis
tance ;}}// takesimply the one that is betterelse
if (cntct->length > best_length) {face1= idx_to_fa
ce_mapping[i] ;face2 = cntct->face2 ;best_length =
cntct->length ;best_cntct = cntct ;// if tie-brea
king is used, compute the largest distance for thi
s face (ie. face1)best_face_to_face_distance = cur
rent_face_to_face_distance = get_largest_distance_
for_face(dist_btw_faces,number_of_faces, dist_arra
y_size, start_id, end_id, i) ;}cntct_prev = cntct
;}}// at the end of this loop,// face1, face2, be
st_cntct should havecorrect values, if best_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 faces in the current connected compo
nent has any adjacent faces// outside the connecte
dcomponent.// most likely this connected component
is finished and, sincethere must be still faces l
eft,// there is more than one connected component.
// // next we try to find the first face in the ne
xt connected component so that we// can continue a
nd create all bendlines for this new conencted com
ponent.for (current_face = first_face ; current_fa
ce ; current_face = (BM_FACE *) current_face->next
()) {if (current_face->get_user_id() < 0) break ;}
if (NULL == current_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++){de
lete_contact_info_list(all_contacts[i]) ;all_conta
cts[i] = NULL ;}//here we will be starting a new c
onnected componentstarting_new_connected_component
= 1 ;start_id = end_id ;// we will skip the bendl
ine creationnormally needed when adding a face to
a connected componentface2 = current_face ;}else
{// ok, we are in the middle of a conencted compon
entstarting_new_connected_component = 0 ;// create
a bendline between face1 and face2// notice : we
might have to create a simultaneous bendlong num_c
ontacts = (long) (best_cntct->contact)->get_obj()
;BM_BEND_PROPERTY_SIMULTANEOUS *sim_bend = NULL ;
if (num_contacts > 1) {sim_bend = new BM_BEND_PROP
ERTY_SIMULTANEOUS(this, num_contacts, NULL) ;if (N
ULL == sim_bend)goto failure ;}BM_BENDLINE *new_be
ndline ;for (long contacts_done = 0 ;contacts_done
< num_contacts ; contacts_done++) {if (! BM_creat
e_bendline(*this, &(best_cntct->contact),&new_bend
line)) goto failure ;// note that this function wi
ll delete one contact for which a bendline was cre
ated as wellif (num_contacts > 1) {// add this ben
dline to the simultaneouspropertynew_bendline->add
_property(sim_bend) ;}}}// store "1 + the current
index of the last connected-component-face"j = end
_id ;// we could add face2 to the connected compon
ent right away, but we could save some time by// f
irst checking if face2 has any other stuff (outsid
e this connected component) connected to it.// if
yes, we will be adding that stuffto this connected
component right away,// but in that case there is
noneed for us to compute contacts between face2 a
nd that other// stuff in the first place.// Theref
ore, we will just remember that face2 should beadd
ed, will process adjacent stuff first,// and then
will actually addface2 (and some more stuff may-b
e) to the connected component.// // Note: we will
actully put face2 in the heap, and when we remove
it from theheap,// we will remember to add it to t
he connected component/* ここで,我々は、この面
(すなわち、面2)がそれに接続された他の任意の3D
体を有するか否かをチェックする必要がある。 もし、
イエスなら、我々は、面2に接続された全ての面を現在
接続された要素に付加するために、これらの接続を追求
する必要がある。*/heap->empty() ;if (! heap->inser
t(body_priority--, (long) face2)) goto failure ;fa
ce2->this_body_already_processed = 1 ;// check if
face2 has a parent face or not. if not, set the id
in local arrayequal to // face2’s own id. this w
ay we know it has no parent face.//// IMPORTANT :
normally user_id of every face is a pointer to its
index in the contact-info array.// temporarily we
will use this information tokeep track which of t
he faces already processed// is the parent-face (i
nthe topology graph) of every new face added to th
e connected component.// this information will be
used later to compute distances in the facetopolog
y graph.// the following loop (controlled by the h
eap) stores allfaces not yet in the connected// co
mponent, but connected to this face2.// later when
the actualy adding of new faces to the conencted
component is done,// we overwrite user_id with the
correct value.if (! starting_new_connected_compon
ent) face2->set_user_id(face1->get_user_id()) ;els
eface2->set_user_id(end_id) ;// in the following w
hile loop we will usethis_body_already_processed m
ember variable to keep// track whether a varible i
s processed; not processed, but sitting in the hea
p; or unseen yet.// 0 - unseen body// 1 - body in
the heap// 2 - body already finished//also, in thi
s while loop we will be using the user_defined_id
of every3D-body to keep// track of the parent face
of every 3D-body we traverse.// this has two bene
fits : 1) we will remember the parent face of ever
yface and can compute// distances between faces la
ter, and // 2) this waywhen faces are later added
to the spanning tree, distance between someother /
/ face and this face will not be computed, since i
t is not necessary.BM_3D_BODY *body ;BM_TOPOLOGY_R
ECORD *toplgy ;while (heap->get_size() > 0) {if (!
heap->remove(&i,(long *) &body)) goto failure ;//
a safetycheckif (NULL == body) continue ;// check
if this body is already finishedif (body->this_bo
dy_already_processed > 1) continue ;// get body to
pologytoplgy = body->get_adj_list() ;if (NULL == t
oplgy) continue ;// check if the body is a face. i
f yes, memorize.if (body->is(BM_ENTITY_TYPE_FACE))
{face2 = (BM_FACE *) body ;// memorize to add thi
s face to the connected component lateridx_to_face
_mapping[j++] = face2 ;}body->this_body_already_pr
ocessed = 2 ;// process all adjacent bodiesfor (cu
rrent_face =(BM_FACE *) toplgy->get_first_face() ;
current_face ; current_face = (BM_FACE *) toplgy-
>get_next_face()) {// make sure that we don’t pro
cessfaces twiceif (current_face->this_body_already
_processed) continue ;if(! heap->insert(body_prior
ity--,(long) current_face)) goto failure ;current_
face->this_body_already_processed = 1 ;// make sur
e we memorize the parent face index in the local s
panning tree arraycurrent_face->set_user_id(body->
get_user_id()) ;}for (current_forming = (BM_FORMIN
G *) toplgy->get_first_forming() ; current_forming
; current_forming = (BM_FORMING *)toplgy->get_nex
t_forming()) {if (current_forming->this_body_alrea
dy_processed) continue ;if (! heap->insert(body_pr
iority--,(long) current_forming)) goto failure ;cu
rrent_forming->this_body_already_processed = 1 ;//
make sure we memorize the parent face index in the
local spanning treearrayif (body->is(BM_ENTITY_TY
PE_FACE)) current_forming->set_user_id(j-1) ;else
current_forming->set_user_id(body->get_user_id())
;}for (current_bendline = (BM_BENDLINE *) toplgy-
>get_first_bendline() ; current_bendline ; current
_bendline = (BM_BENDLINE *) toplgy->get_next_bendl
ine()) {if (current_bendline->this_body_already_pr
ocessed) continue ;if (! heap->insert(body_priorit
y--,(long) current_bendline)) goto failure ;curren
t_bendline->this_body_already_processed = 1 ;// ma
ke sure we memorize the parent face index in the l
ocal spanning tree arrayif (body->is(BM_ENTITY_TYP
E_FACE)) current_bendline->set_user_id(j-1) ;else
current_bendline->set_user_id(body->get_user_id())
;}}// finally we need to compute contacts between
this face and all other faces, that we postponed/
/ and add them to the connected component.long fac
e1_id ;for (i = end_id ; i < j ; i++) {face2 = idx
_to_face_mapping[i] ;// first, compute distances i
n the TOPOLOGY GRAPH between this face (ie. face2)
// and all faces previouslyin the connected compo
nent.// we will use the parent face id in the loca
l spanning tree array for that.face1_id = face2->g
et_user_id() ; // note: face1_id is the parent id
of face2 (ie. there is a bendline between face1_id
and face2 that we count).if (dist_btw_faces && fa
ce1_id != i) {// if equal -> face2 has no parents,
// ie. a new connected component (must be start_i
d = end_id).// actually, it must be here true that
face1_id < ifor (k = start_id ; k < end_id ; k++)
{set_face2face_dist(dist_btw_faces, number_of_fac
es, dist_array_size, k, i, get_face2face_dist(dist
_btw_faces,number_of_faces,dist_array_size,k,face1
_id) + 1) ;}}// else ifequal, it must be that i ==
’the end_id’ in the beginning of this for-loop.
// note that the next function (add_face_to_connec
ted_component(...)) will increment end_id.if (! ad
d_face_to_connected_component(this, face2, &end_i
d, all_contacts, idx_to_face_mapping)) goto failur
e ;}// ok, the current connected component has no
connections to the outside.// tryto expand the spa
nning tree.goto expand_spanning_tree ;done :ret_va
lue=1 ;goto release_memory_and_return ;failure :re
t_value = 0 ;release_memory_and_return :// free me
mory if necessaryfor (i = 0 ; i < number_of_faces
; i++) {delete_contact_info_list(all_contacts[i])
;}if (all_contacts)delete [] all_contacts ;if (id
x_to_face_mapping) delete [] idx_to_face_mapping ;
if (heap) delete heap ;if (dist_btw_faces) delete
[] dist_btw_faces ;return ret_value ;} 付録D 2dクリーアップ関数の例 #include <stdio.h>#include <stdlib.h> #include <
math.h>#include <memory.h>#include <string.h>/* F
unction名称:1 control levelTestFindBoundaryTestFi
ndDrawingSheetControlTestFindViewsControlTestFindB
oundaryControlTestFindArrowControlTestFindOneSideO
penControlTestFindOneSideOpen2ControlTestFindCente
rLineControlTestFindOneSideOpenConnectControlTestF
indSameColorControlTestFindSelectSingleControlTest
UnselectSingleControlTestClearControlTestClearKeep
FlagsControlTestDeleteControlTestUndoControlTestUn
doPreControlTestDeleteViewsControlTestSetUndoFlagV
iewsControl TestBackColorControl2 applicate
levelF2dCleanUpFindDrawingSheetF2dCleanUpFindView
sF2dCleanUpFindSameColorEntityF2dCleanUpFindCenter
LineEntityF2dCleanUpFindOnesideOpenConnectEntityF2
dCleanUpFindOneSideOpenEntity2F2dCleanUpClearDrawi
ngEntityF2dCleanUpDeleteDrawingEntityF2dCleanUpDel
eteViewsF2dCleanUpUndoF2dCleanUpUndoPreF2dCleanUpP
ickUpAllOneSideOpenEntityF2dCleanUpPickUpAllArcEnt
ityF2dCleanUpFindLongestEntityF2dCleanUpFindGroupF
2dCleanUpCheckEntityExistF2dCleanUpFindViewsRelati
onF2dCleanUpFindRelativeViewsF2dCleanUpFindOutSide
LoopF2dCleanUpFindInSideEntityF2dCleanUpFindOneSid
eOpenEntityF2dCleanUpFindGroupMinXF2dCleanUpFindOu
tNextEntityF2dCleanUpFindOnesideOpenConnectEntityN
extF2dCleanUpFindArrowF2dCleanUpFindArrowOneSideOp
enEntityF2dCleanUpFindArrowEndEntityF2dCleanUpChec
kStartEndEntityF2dCleanUpComputeCenterLineAngleF2d
CleanUpFindArrowCenterEntityF2dCleanUpChangeArrowV
ertexFlagF2dCleanUpArcAngleF2dCleanUpLineAngleF2dC
leanUpLineLengthF2dCleanUpChangeColorF2dCleanUpCha
ngeDrawingColorF2dCleanUpChangeChildrenFlagF2dClea
nUpChangeDrawingFlagF2dCleanUpClearDrawingKeepFlag
sF2dVectorF2dVectorUnitF2dDistancePointLine*/#ifde
f VELLUM#include "ck_cdlc.h"// VCI_VLM.DLL include
files#include "system.h"// CadKey emulation files
#include "vlm_ck.h"#endif#ifdef CKWIN#include "ck_
cdlc.h"#include "ck_cde.h"#include <ckcdll.h>#incl
ude <ck_attr.h>#define ck_setattr2ck_setattr#endif
#ifdef AUTOCAD#include <ACAD_VCI.H>#endif// 2d3d f
iles#include "view3D.h"//#include "Proto.h" // in
cludes prototypes of all functions.#define VLM_ID_
2DTO3D32#define Regular 0#define ThreeViews 1//
#define SECURITY// Some definitions//#undef DEBUG/
/// Following is the definition of the global vari
ables//#ifdefCKWINint TopViewNum, IsometricViewNu
m;// These variables are used onlywith CADKEY whe
n changing to TopView or Isometric view.#endif// b
y Ji Feb.14,1996double F2dCleanUpTolerance = 0.01;
//undo flag ( set a No. for views )extern int F
2dCleanUpExcutedNo = 0;extern int WorkLevel, Tr
imLevel, VW3DLevel; // Thr
ee layers are useD: WorkLevel is used to highlight
views and display temporary drawings.//TrimLevel
is used to store the trimmed drawing.//VW3DLevel i
s used to store the projected 3D drawing.// these
are the four drawings used.extern struct drawing i
nput_drawing, projected_drawing, trim_drawing, fin
al_drawing; // Three drawing structures are const
ructed:// InputDrawing is c
onstructed from the input entities //
taken from from all the l
ayers that are turned on.//TrimmedDrawing is const
ructed from the trimmed entities. Once the//Trimme
d Drawing is constructed, theInput Drawing is not
used.// ProjectedDrawing is
constructed from the entities projected in a sing
le flange.//If ’DoneProjection’ is selected, the
n these entities are saved on VW3DLevel.//
If ’UndoProjection’ is selected,
these entities are discarded.extern struct planar
_flange *AllFlanges;// this is a pointer to the li
st of flangesextern char Messages[MaxMessages][8
0];// This array stores the messages read from the
message file.extern int message_flag;// This vari
able is assigned to ’1’ if the messages were rea
d successfully from the message file.// Otherwise,
it isset to ’0’.extern int number_of_views;// T
his vairbale stores the number of disconnected com
ponents discovered in the *input* drawing.externin
t number_of_entities;// This variable stores the n
umber of entities loaded for the current drawing.e
xtern int number_trimmed_entities;// Thisvariable
stores the number of entities loaded for the trimm
ed drawing.extern int n_edges;// This variable sto
res the number of connecting edgesbetween the trim
med entities.extern double MatchTolerance, Connect
ivityTolerance;// ConnectivityTolerance is used to
determine whether two entities are close enough t
o be considered connected.// Matching Tolerance is
used to determine whether two entities on differen
t views are matching.extern double ArrowHeadAngle,
ArrowHeadLength;// These variuables definethe str
ucture of an arrow for the 2D clean up funciton.ex
tern double view_boundaries[MaxNumberOfViews+1]
[4];// This array is used to store thebounding box
of each connected component of the input drawing.
// once the views are detected, several compo
nents might be mapped to a single view.extern int
type_of_view[MaxNumberOfViews+1];// This array
mapsevery view to its type, namely to one of Top,
Left, Right, Front, Backview.// Its content is va
lid only after ’DoneViews’ was called.//intview_
rotation_flag[MaxNumberOfViews+1];// This array is
used for markingrotated views. // If the i’th el
ement is ’1’ then the view is rotated.//extern s
tatic char original_lvmask[32] ;// At the beginnin
g we save the (on,off) status of all the layers.//
extern static char twoDmask[32] ;//extern static c
har threeDmask[32] ;// The masks used to display t
he 2Dand 3D models.//extern static int original_wo
rklevel ;// Specifies theoriginal work level of th
e user when fold is started// static int original_
setup_available = 0 ; // true iff original (layer)
setup is available, ie. can be restoredextern int
dialog_open_flag = 0;// This variable isa flag wh
ich specifies whether some dialog boxes were opene
d.extern intAtrimLineTypeSwitch, AtrimColorSwitch,
AtrimWidthSwitch, AtrimCenterLineSwitch;// these
switches are used to specify in which cases AutoTr
im will trim lines.//struct node *F2dCleanUpInputE
ntity(char *, struct drawing *);//static int selec
t_flange(struct resbuf *rb);typedefstruct Vector{d
oublex,y,z;};extern double BBminX,BBmaxX,BBminY,BB
maxY,BBminZ,BBmaxZ;/*関数: 名称: TestFindBoundar
yDescription: It is a manual function. When user s
elected a boundary’s entity of a view, the functi
on would findall of the connected entities for the
view.戻り値:< 0: Error= 0: No proccess> 0: Compl
eted successfully; the Number is the counter of f
ound entities.パラメータ:副関数:int F2dCleanUpFi
ndArrowlook for arrow type entityint F2dCleanUpFin
dArrowEndEntityfind arrow end lineint F2dCleanUpFi
ndArrowCenterEntityfind arrow center lineint F2dCl
eanUpFindArrowOneSideOpenEntityfind one side open
entity for arrow typeint F2dCleanUpComputeCenterLi
neAnglecompute center line angleint F2dCleanUpChec
kStartEndEntitycheck start and end entitiesint F2d
CleanUpFindOutSideLooplook for out sideloop entiti
esint F2dCleanUpFindOutNextEntitylook for connecte
d entity with out side loop entitiesstruct node *F
2dCleanUpFindGroupMinXlook for minimum X-value for
a entities groupstruct node_list *F2dCleanUpFindG
rouplook for a group entities connected with input
entitystruct node *F2dCleanUpInputEntity ( old fu
nction )look for a selected entity on screenintF2d
CleanUpLineAnglecompute a line type entity’s angl
e int F2dCleanUpArcAnglecompute a arc type entit
y’s angle.int F2dCleanUpChangeChildrenFlagchange
entity’s children flagsint F2dCleanUpChangeArrowV
ertexFlagchangearrow top vertex’s flags and set a
rrow center line coordinatesint F2dCleanUpChangeCo
lorchange entity’s colorint F2dCleanUpFindOneSide
OpenEntitylook for one side open entities and they
are vertical with arrow typeentities double F2dCl
eanUpLineLengthcompute line type entity’s length=
==================================================
==============*/intTestFindBoundary(){//external f
unctionsint F2dCleanUpFindArrow();int F2dCleanUpCh
angeColor();int F2dCleanUpFindOneSideOpenEntity();
int F2dCleanUpFindOutSideLoop();int F2dCleanUpChan
geDrawingColor();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; //selected entity and temp ent
itiesstruct node *entity,*MinXvalueEntity;//Begin
//----------------------------------//Step_1://che
ck the number of entites// get count of all entit
ies// if an error occurred, exit immidiately. i
f (number_of_entities<0) return -1;for( ;; ){//--
-------------------------------//Step_2:select one
entityentity= F2dCleanUpInputEntity( "Select a Bo
undary Entity for a view",&trim_drawing);if ( enti
ty == 0 )return0;if ( entity->flags != 0 )continu
e;//---------------------------------//Step_3: fin
d a connected entities groupEntities_change_color_
list1 = F2dCleanUpFindGroup( entity, &count );if
( Entities_change_color_list1 == 0 )return0;//----
-----------------------------//Step_4: find arrow
lineF2dCleanUpFindArrow( Entities_change_color_lis
t1 );//---------------------------------//Step_5:f
ind one side open entitiesassistant_line_flag = F2
dCleanUpFindOneSideOpenEntity( Entities_change_col
or_list1 );//---------------------------------//St
ep_6:find outside loop entities without assistant
entities//check a flag for outsideloop processif
( count < 1 )continue;MinXvalueEntity = F2dCleanUp
FindGroupMinX(Entities_change_color_list1);if ( Mi
nXvalueEntity == 0 )continue;//-------------------
--------------//Step_7://find outside loop entitie
sF2dCleanUpFindOutSideLoop( MinXvalueEntity );//--
-------------------------------//Step_X://change c
olor to Magenta for a selected boundary //turn
off input levels ck_levels(CK_OFF,1,255);#ifdef
CKWINF2dCleanUpChangeColor(Entities_change_color_
list1);#endif#ifdef VELLUMF2dCleanUpChangeDrawingC
olor(&trim_drawing);#endif//clear a flag for outsi
de loop processassistant_line_flag = 0;// turn ON
the level used to store the trimmed entities. c
k_levels(CK_ON,TrimLevel, TrimLevel);#ifdef CKWINi
f (*SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );#en
dif}return count;}/*==============================
===================================関数: 名称: F
2dCleanUpFindGroup記述: look for a group entities
connected with input entity 戻り値:= 0: Complete
d successfully;パラメータ:入力: Entity: a entity
出力:NodeList: a node list connected with input e
ntity ============================================
=====================*/struct node_list *F2dCleanU
pFindGroup(struct node *Entity, int *Cnt ){//entit
ies counter and flagsint count = 0;//link list and
temp liststruct node_list*EntitiesList1,*Out_temp
_list,*temp_list, *temp_list1,*open_temp_list, *op
en_list; //selected entity and temp entitiesstruct
node *Next_entity;//initializeEntitiesList1 =( st
ruct node_list * ) calloc ( 1, sizeof ( struct nod
e_list ));open_list =( struct node_list * ) calloc
( 1, sizeof ( struct node_list ));//set a flag fo
r the boundary entitycount = 0;//set pointer to fi
rst entityopen_list->car = Entity;//set a open fla
gto the nodeopen_list->car->flags = 1;//set link a
ddressopen_list->cdr = NULL;//set the pointer to o
utput node listEntitiesList1->car = open_list->ca
r;EntitiesList1->cdr = open_list->cdr;//----------
-----------------------//Step_3://find connected e
ntitiesfor( temp_list = open_list; ( temp_lis
t //&&(temp_list->cdr != 0) ); ) {if
( temp_list->car == NULL )break;//get a pointer fr
om open listNext_entity = temp_list->car;//set a c
losed flag to the nodeNext_entity->flags = 2;//clo
se the node ( delete the node from open list )open
_list = open_list->cdr;//count the number of entit
iescount++;// look for first connected entity whos
e flags=0.for (temp_list1=Next_entity->connected_n
odes; // temp_list1 && temp_list1->car->flags=
=1; ( temp_list1!=0 && temp_list1->car
!=0); temp_list1=temp_list1->cdr){ if ( t
emp_list1->car == NULL )break; // if found an unma
rked connected entityif (temp_list1 && temp_list1-
>car->flags==0&& Entity->line_type == temp_list1->
car->line_type&& Entity->color == temp_list1->car-
>color&& Entity->is_thickness == temp_list1->car->
is_thickness ) {// allocate memory for open list
elementopen_temp_list = ( struct node_list * ) ca
lloc ( 1, sizeof ( struct node_list));// allocate
memory for output node list elementOut_temp_list =
( struct node_list * ) calloc ( 1, sizeof ( struc
t node_list ));// add this entity to the open list
open_temp_list->car = temp_list1->car;// add thise
ntity to the output node list 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 po
inter of open list to the topopen_list = open_temp
_list;// connect to the output node listOut_temp_l
ist->cdr = EntitiesList1;// move the pointer of ou
tput nodelist to the topEntitiesList1 = Out_temp_l
ist;}}// assign value to the loop variabletemp_lis
t = open_list;}*Cnt = count;return EntitiesList1;
}/*==============================================
=================== 関数: 名称: F2dCleanU
pArcAngle 記述:アーク形エンティティの角度を計算
する。 戻り値:RotateVertexFlag:方向フラグ
=1:vertex1は回転ポイントである。
=2:vertex2は回転ポイントである。
パラメータ: 入力: 1 Origin
Vertex:回転頂点 2 Entity:アーク形エン
ティティ 出力:1 EntityAngle:方向角度(ラ
ジアン) 2 EntityAngleAnother: 他の
サイド方向角度====================================
============================*/int F2dCleanUpArcAng
le(//inputstructplanar_vertex *OriginVertex,struct
node *Entity,//outputdouble*EntityAngle,double*Ent
ityAngleAnother){//return value intRotateVertexFla
g=0;//length and angledoubleTolerance = 0.0;//set
toleranceTolerance = F2dCleanUpTolerance;//select
connected side of entityif ( Entity->vertex1 == Or
iginVertex ){//get arc start-angle//( direction :
from circle-center to start-point )RotateVertexFla
g= 1;*EntityAngle = ( Entity->AngBegin ) * pi / 18
0.0;//change angleto oppsite direction//( directio
n : from start-point to circle-center )*EntityAngl
e = *EntityAngle + pi;//check angle if ( *EntityAn
gle >(2.0*pi)) *EntityAngle = *EntityAngle - 2.0*p
i;if ( fabs(*EntityAngle-2.0*pi) <Tolerance ) *Ent
ityAngle = 0.0;//compute tangentline angle for the
arcend-angle//( direction : from start-point to e
nd-point )*EntityAngle =*EntityAngle + 1.5 * pi;//
check angle if ( *EntityAngle >(2.0*pi)) *EntityAn
gle = *EntityAngle - 2.0*pi;if ( fabs(*EntityAngle
-2.0*pi) < Tolerance ) *EntityAngle = 0.0;//get an
other side data//get arc start-angle//( direction
: from circle-center to end-point )*EntityAngleAn
other = ( Entity->AngEnd ) * pi / 180.0;//change a
ngle to oppsite direction//( direction : from end-
point to circle-center )*EntityAngleAnother = *Ent
ityAngleAnother + pi;//check angle if ( *EntityAng
leAnother > 2.0*pi )*EntityAngleAnother = *EntityA
ngleAnother - 2.0 * pi;elseif ( fabs(*EntityAngleA
nother-2.0*pi) < Tolerance ) *EntityAngleAnother =
0.0;//compute tangentline angle for the arc end-a
ngle//( direction : from end-point to start-point
)*EntityAngleAnother = *EntityAngleAnother + 0.5
* pi;//check angleif ( *EntityAngleAnother > 2.0*p
i )*EntityAngleAnother = *EntityAngleAnother - 2.0
* pi;else if ( fabs(*EntityAngleAnother-2.0*pi) <
Tolerance )*EntityAngleAnother = 0.0;}else{//get
arc end-angle//( direction : fromcircle-center to
end-point )RotateVertexFlag= 2;*EntityAngle= ( Ent
ity->AngEnd ) * pi / 180.0;//change angle to oppsi
te direction//( direction: from end-point to circl
e-center )*EntityAngle = *EntityAngle + pi;if(*Ent
ityAngle > 2.0*pi ) *EntityAngle = *EntityAngle -
2.0*pi;if ( fabs(*EntityAngle - 2.0*pi) < Toleranc
e )*EntityAngle = 0.0;//compute tangentline angle
for the arc end-angle//( direction : from end-poin
t to start-point )*EntityAngle = *EntityAngle + 0.
5 * pi;if ( *EntityAngle > 2.0*pi) *EntityAngle =
*EntityAngle - 2.0*pi;if ( fabs(*EntityAngle - 2.0
*pi)< Tolerance )*EntityAngle = 0.0;//get another
side data//get arc start-angle//( direction : from
circle-center to start-point )*EntityAngleAnother
= ( Entity->AngBegin ) * pi / 180.0;//change angl
e to oppsite direction//( direction : from start-p
oint to circle-center )*EntityAngleAnother = *Enti
tyAngleAnother + pi;if ( *EntityAngleAnother > 2.0
*pi )*EntityAngleAnother = *EntityAngleAnother -
2.0 * pi;if ( fabs(*EntityAngleAnother - 2.0*pi )
< Tolerance )*EntityAngleAnother = 0.0;//compute t
angentline angle for the arc start-angle//( direct
ion : from start-point to end-point )*EntityAngleA
nother = *EntityAngleAnother + 1.5 * pi;if ( *Enti
tyAngleAnother > 2.0*pi )*EntityAngleAnother = *En
tityAngleAnother - 2.0 *pi;if ( fabs(*EntityAngleA
nother - 2.0*pi ) < Tolerance )*EntityAngleAnother
= 0.0;}//the end of this functionreturn RotateVer
texFlag;}/*=======================================
==========================関数: 名称:F2dCleanUpL
ineAngle記述: It is a function for control how to
compute aline typeentity’s angle. 戻り値:Rotate
VertexFlag: direction flag=1: vertex1 is rotate po
int=2: vertex2 is rotate pointパラメータ:入力: 1
OriginVertex: rotationary vertex2 Entity: line ty
pe entity 出力:1 EntityAngle: direction angle ( r
adian )2 EntityAngleAnother: another side directio
n angle===========================================
=====================*/int F2dCleanUpLineAngle(//i
nputstructplanar_vertex *OriginVertex,structnode *
Entity,//outputdouble*EntityAngle,double*EntityAng
leAnother){//return value intRotateVertexFlag=0;//
selected entity and temp entitiesstruct planar_ver
tex*VertexTemp,*VertexAnotherTemp;//length and ang
ledoublediff_x = 0.0,diff_y = 0.0,Tolerance = 0.0;
//set toleranceTolerance = F2dCleanUpTolerance;//s
elect connected side of entityif ( Entity->vertex1
== OriginVertex ){//get vertex1->vertex2 RotateVer
texFlag= 1;VertexTemp=Entity->vertex1;VertexAnothe
rTemp= Entity->vertex2;}else{ //get vertex2->vert
ex1 RotateVertexFlag= 2;VertexTemp = Entity->verte
x2;VertexAnotherTemp= Entity->vertex1;}//compute a
ngleif ( fabs( VertexTemp->X - VertexAnotherTemp->
X ) < Tolerance ){//angle = 0.5 * piif ( VertexTem
p->Y < VertexAnotherTemp->Y )*EntityAngle = 0.5 *
pi;//angle = 1.5 * pielse*EntityAngle = 1.5 * pi;}
else{ //-pi< angle < pidiff_y = VertexAnotherTemp
->Y- VertexTemp->Y;if ( fabs( diff_y ) > Tolerance
){diff_x = VertexAnotherTemp->X - VertexTemp->X;
*EntityAngle = atan2( diff_y, diff_x );//-pi< a
ngle < 0.0if ( *EntityAngle < 0.0 ) *EntityAngle =
*EntityAngle + 2.0*pi; }else{ //angle = 0.0or pi
if ( VertexAnotherTemp->X > VertexTemp->X )*Entity
Angle = 0.0;else*EntityAngle = pi;}}if ( fabs(*Ent
ityAngle - 2.0*pi) < Tolerance ) *EntityAngle = 0.
0;//get another side angle*EntityAngleAnother = *E
ntityAngle + pi;// check angleif ( *EntityAngleAn
other> ( 2.0 * pi ) ){*EntityAngleAnother = *Entit
yAngleAnother - 2.0 * pi;}if ( fabs(*EntityAngleAn
other - 2.0*pi) < Tolerance ) {*EntityAngleAnother
= 0.0;}//the end of this functionreturn RotateVer
texFlag;}/*=======================================
========================== 関数: 名称:F2dClean
UpChangeColor 記述: エンティティの色を変更す
る関数。
【0375】戻り値: =0:成功裏に完了 パ
ラメータ: 入力:Entities_change_color_
list :変更された色であるノードリスト=============
==================================================
==*/int F2dCleanUpChangeColor(struct node_list *En
tities_change_color_list){//link list and temp lis
tstruct node_list*Color_temp_list;//selected entit
y and temp entitiesstruct node *Next_entity;//ent
ity’s specifitysCK_ENTATTattr;//specificity of en
titiesint CountPrompt = 0;charmessage[64];#ifdef V
ELLUMCountPrompt++;sprintf( message,"Start Change
Color Entity %d", CountPrompt );ck_prompt( message
); #endif#ifdef VELLUM // clear views highlig
hting ck_erase_level("VW_2D");// ck_erase_le
vel("VW_TRIM");#endif//check all of entities on th
e listfor( Color_temp_list=Entities_change_color_l
ist; Color_temp_list; Color_temp_list = Color_te
mp_list->cdr){if ( Color_temp_list->car == NULL )b
reak;Next_entity = Color_temp_list->car;switch ( N
ext_entity->flags ){case 1:attr.color = CK_GREEN;c
k_setattr( Next_entity->id, CK_COLOR, NULL, &attr
);break;case 3:attr.color =CK_GRAY;ck_setattr( Ne
xt_entity->id, CK_COLOR, NULL, &attr );break;case
4:attr.color = CK_MAGENTA;ck_setattr( Next_entity-
>id, CK_COLOR, NULL,&attr );break;}}#ifdef VELLUMC
ountPrompt++;sprintf( message,"Finished change col
or Entity %d", CountPrompt );ck_prompt( message );
#endifreturn0;}/*===============================
==================================関数: 名称:
F2dCleanUpChangeDrawingColor 記述: エン
ティティの色を変更する関数。 復帰値: =0:
成功裏に完了; パラメータ:入力: 1
In drawing:図中で1:変更された色である図=========
==================================================
======*/intF2dCleanUpChangeDrawingColor(struct dra
wing *In_drawing){//extern functionsvoid draw_enti
ty();//selected entity and temp entitiesstruct nod
e *entity;int CountPrompt = 0;charmessage[64];//en
tity’s specifitysCK_ENTATTattr;//specificity of e
ntities#ifdef VELLUM // clear views highlightin
g ck_erase_level("VW_2D");// ck_erase_leve
l("VW_TRIM");CountPrompt++;sprintf( message,"Start
Change Color Sheet Entity %d", CountPrompt);ck_pr
ompt( 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_entity( entity, entity->color
);break;case 3:draw_entity( entity, CK_BLUE );bre
ak;case 4: draw_entity( entity, CK_MAGENTA );brea
k;case 5:draw_entity( entity, entity->color );brea
k;case 6: draw_entity( entity, CK_RED );break;case
7:draw_entity( entity, CK_YELLOW );break;case 8:d
raw_entity( entity, entity->color );break;case 9:d
raw_entity( entity, entity->color );break;case 10:
draw_entity( entity, CK_CYAN );break;case 11:draw_
entity( entity,entity->color );break; #endif #ifde
f CKWINcase 1:attr.color = CK_L_GREEN;ck_setattr(
entity->id, CK_COLOR, NULL, &attr );break;case 3:a
ttr.color = CK_L_GRAY;ck_setattr( entity->id, CK_C
OLOR, NULL, &attr );break;case4:attr.color = CK_MA
GENTA;ck_setattr( entity->id, CK_COLOR, NULL, &att
r);break;case 6:attr.color = CK_L_RED;ck_setattr(
entity->id, CK_COLOR,NULL, &attr );break;case 7:at
tr.color = CK_YELLOW;ck_setattr( entity->id, CK_CO
LOR, NULL, &attr );break;case 10:attr.color = CK_L
_CYAN;ck_setattr( entity->id, CK_COLOR, NULL, &att
r );break; #endif} if ( entity->next== NULL ) brea
k;}#ifdef VELLUMCountPrompt++;sprintf( message,"Fi
nishedchange color Sheet Entity %d", CountPrompt
);ck_prompt( message ); #endifreturn 0;}/*======
==================================================
========= 関数: 名称: F2dCleanUpUndoPre
記述: 取消関数のためのデータフラグを準備す
ること。 復帰値: =0:成功裏に完了;パラメ
ータ: 入力: 1 In drawing:
変更ステータスである図。==========================
=======================================*/int F2dCl
eanUpUndoPre(struct drawing *In_drawing){//selecte
d entity and temp entitiesstruct node *entity;//se
t flagF2dCleanUpExcutedNo = 2;//check all of entit
ies on the listfor( entity=In_drawing->objects; e
ntity; entity = entity->next){entity->status = ent
ity->flags;if ( entity->next == NULL )break;}retur
n 0;}/*===========================================
======================関数: 名称: F2dCleanUpUndo
記述: To undo. 戻り値:= 0: Completed successfull
y;パラメータ:入力: 1 In_drawing: drawing that wi
ll be undoed status===============================
==================================*/int F2dCleanUp
Undo(struct drawing *In_drawing){//selected entity
and temp entitiesstruct node *entity;//flagint No
ChangeFlag = 0;//checkflagif ( F2dCleanUpExcutedNo
== 0 )return NoChangeFlag;//check all of entities
on the listfor( entity=In_drawing->objects; enti
ty; entity = entity->next){if ( entity->status !=
entity->flags ){NoChangeFlag = 1;entity->flags = e
ntity->status;}if ( entity->next == NULL )break;}
//check views flagif ( F2dCleanUpExcutedNo == 1 )I
n_drawing->views = NULL;//resetflag for viewsF2dCl
eanUpExcutedNo = 0;return NoChangeFlag;}/*========
==================================================
======= 関数: 名称:F2dCleanUpChangeDrawingFlag
記述: エンティティのフラグを変更する関数。
復帰値: =0:成功裏に完了; パラメータ:
入力: 1 In drawing: 変更され
た色である図======================================
===========================*/int F2dCleanUpChangeD
rawingFlag(struct drawing *In_drawing){//selected
entity and temp entitiesstruct node *entity;int Co
untPrompt = 0;charmessage[64];#ifdef VELLUMCountPr
ompt++;sprintf( message,"Start Flag Sheet Entity %
d", CountPrompt );ck_prompt( message ); #endif//c
heck all of entities on the listfor( entity=In_dra
wing->objects; entity; entity = entity->next){if
( entity->flags== 4 ) entity->flags = 3;#ifdef V
ELLUM//CountPrompt++;//sprintf( message,"Flag Shee
t Entity %d", CountPrompt );//ck_prompt( message
); #endifif ( entity->next == NULL )break;}#ifde
f VELLUMCountPrompt++;sprintf( message,"Finished F
lag Sheet Entity %d", CountPrompt );ck_prompt( mes
sage ); #endifreturn 0;}/*=======================
========================================== 関数:
名称: F2dCleanUpFindSameColorEntity 記
述: 同じ色のエンティティを見出す。 復帰値:
=0: 成功裏に完了; パラメータ:
入力: 1 In entity: エンティティ2 In d
rawing: 変更された色である図=====================
===========================================*/int F
2dCleanUpFindSameColorEntity(struct node *In_entit
y,struct drawing *In_drawing){//selected entity an
d temp entitiesstruct node *entity;int CountPrompt
= 0;charmessage[64];#ifdef VELLUMCountPrompt++;sp
rintf( message,"Start Find same color Entity%d", C
ountPrompt );ck_prompt( message ); #endif//check
all of entitieson the listfor( entity=In_drawing->
objects; entity; entity = entity->next){if ( ent
ity->color == In_entity->color && entity->flags ==
0) entity->flags = 3;if ( entity->next == NULL )b
reak;}#ifdef VELLUMCountPrompt++;sprintf( messag
e,"Finished find same color Entity %d", CountPromp
t );ck_prompt( message ); #endifreturn 0;}/*=====
==================================================
========== 関数: 名称: F2dCleanUpClearDrawi
ngEntity 記述: それは復帰エンティティの色であ
る。 復帰値:=0:成功裏に完了; パラメータ:
入力: 1 In drawing: 変更された色
である図==========================================
====================*/int F2dCleanUpClearDrawingEn
tity(struct drawing *In_drawing){//selected entity
and temp entitiesstruct node *entity;//entity’ss
pecifitysCK_ENTATTattr;//specificity of entitiesin
t CountPrompt = 0;charmessage[64];#ifdef VELLUM
// clear views highlighting ck_erase_level("V
W_2D");// ck_erase_level("VW_TRIM");//CountProm
pt++;//sprintf(message,"Start Clear Entity %d", Co
untPrompt );//ck_prompt( message );#endif//check a
ll of entities on the listfor( entity=In_drawing->
objects; entity; entity = entity->next){ if ( en
tity == NULL )break;switch (entity->flags ){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_ent
ity( entity, entity->color );//attr.color = entity
->color;//ck_setattr( entity->id, CK_COLOR, NULL,
&attr );default:break;}}#ifdef VELLUM//CountPrompt
++;//sprintf( message,"Finished clear Entity %d",
CountPrompt );//ck_prompt( message ); #endif//cle
ar views connectedIn_drawing->views = NULL;return
0;}/*=============================================
==================== 関数: 名称:F2dCleanUpClea
rDrawingKeepFlags 記述: エンティティの色を復
帰させるが、フラグは保持する。
【0376】復帰値: =0:成功裏に完了; パラ
メータ: 入力:1 In drawing:変更された色
である図==========================================
=======================*/int F2dCleanUpClearDrawin
gKeepFlags(structdrawing *In_drawing){//selected e
ntity and temp entitiesstruct node *entity;//entit
y’s specifitysCK_ENTATTattr;//specificity of enti
tiesint CountPrompt = 0;charmessage[64];#ifdef VEL
LUM // clear views highlighting ck_erase_lev
el("VW_2D");#endif//check all of entities on the l
istfor( entity=In_drawing->objects; entity; enti
ty = entity->next){switch( entity->flags ){case 0:
case 1:case 2:case 3:case 4:case 5:case 6:case7:ca
se 8:case 9:case 10://center linedraw_entity( enti
ty, entity->color);//attr.color = entity->color;//
ck_setattr( entity->id, CK_COLOR, NULL,&attr );}if
( entity->next == NULL )break;}return 0;}/*======
==================================================
======== 関数: 名称: F2dCleanUpDeleteViews
記述: それは削除ビユーに対する関数である。
復帰値: =0:成功裏に完了; パラメータ:
入力: 1 Indrawing:図===========
==================================================
====*/int F2dCleanUpDeleteViews(struct drawing *In
_drawing){//check drawingif ( In_drawing == NULL )
return 0; //delete views ( Not release memory )
In_drawing->views == NULL;return 0;}/*============
==================================================
=== 関数: 名称: F2dCleanUpDeleteDrawingEnti
ty 記述: それは削除エンティティに対する関数で
ある。
【0377】復帰値: =0:成功裏に完了; パ
ラメータ: 入力:1 In drawing:図==========
==================================================
=====*/int F2dCleanUpDeleteDrawingEntity(struct dr
awing *In_drawing){//selected entity and temp enti
tiesstruct node *entity;struct group *Gp;//groupst
ruct node_list *ETL;//Entity Temp ListintCountProm
pt = 0;charmessage[64];#ifdef VELLUMCountPrompt++;
sprintf( message,"Start Delete Entity %d", CountPr
ompt );ck_prompt( message ); #endif//check all of
entities on the listfor( entity=In_drawing->objec
ts; entity; entity = entity->next){if ( entity->
flags == 3 || entity->flags == 6 || entity->flags
== 0 || entity->flags == 10 ){#ifdef CKWINck_delen
t( entity->id );#endif#ifdef VELLUM// r
emove_entity ( entity, In_drawing );#endifentity-
>flags = 99;}if ( entity->next == NULL )break;}if
( In_drawing->views == NULL )return 0;//unuse grou
p entitiesfor( Gp=In_drawing->views;Gp; Gp = Gp->n
ext){if ( Gp == NULL )break;if ( Gp->index != 0 )c
ontinue;for ( ETL = Gp->entities; ETL; ETL = ETL->
cdr ){#ifdef CKWINck_delent( ETL->car->id );#endif
#ifdef VELLUM // remove_entity ( ETL->ca
r,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 entity is not
same to database, drawing was changed 戻り値:=
0: No change;= 1: Changed;パラメータ:入力: 1 In_
drawing: drawing =================================
===============================*/int F2dCleanUpChe
ckEntityExist(struct drawing *In_drawing){//select
ed entity and temp entitiesstruct node *entity;//d
efineint 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,
ang2=0.0;//entity’s specifitysCK_ENTATTattr;//spe
cificity of entities//check all of entities on the
listif ( In_drawing->objects == NULL )return1;for
( entity=In_drawing->objects; entity; entity = e
ntity->next){if ( entity->flags == 99 )continue;Re
turnCode = ck_getentid( entity->id, &etype );if (
ReturnCode == CK_NO_ENT )return1;else{//check all
ofentities on the listswitch ( entity->type ){case
CK_ARC:ck_getarc ( entity->id, &x1,&y1,&z1, &ra
d,&ang1,&ang2, &attr );break; case CK_LINE: ck_ge
tline( entity->id, &x1,&y1,&z1, &x2,&y2,&z2, &att
r );break;}if ( attr.level == 191 )return0;elseret
urn1;}if ( entity->next == NULL )break;}return 1;}
/*================================================
================ 関数: 名称: F2dCleanUpChan
geArrowVertexFlag 記述: アラウトップ頂点フ
ラグを変更し、アローセンタライン座標を設定する。
復帰値:=0:成功裏に完了; パラメータ:
入力: 1 Flags:フラグ 2 T
opVertex:アロートップ頂点 3 Entiry:
アローセンタラインエンティティ====================
=============================================*/int
F2dCleanUpChangeArrowVertexFlag(//inputint *flag
s,structplanar_vertex *TopVertex,structnode *Entit
y){//set flagto arrow top vertexTopVertex->flags =
*flags;//set arrow center line coordinatesTopVert
ex->ArrowCenterLine_X1 = Entity->X1;TopVertex->Arr
owCenterLine_Y1 = Entity->Y1;TopVertex->ArrowCente
rLine_Z1 = Entity->Z1;TopVertex->ArrowCenterLine_X
2 = Entity->X2;TopVertex->ArrowCenterLine_Y2 = Ent
ity->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*Cen
terLineAngleTemp ){//external functionsint F2dClea
nUpLineAngle(); int F2dCleanUpChangeChildrenFla
g();int F2dCleanUpChangeArrowVertexFlag();double F
2dCleanUpLineLength();//nodesstructnode *CenterEnt
ity;//linklist and temp liststruct node_list*temp_
list;//flagsint ReturnFlag = 0,ArrowFlags = 3; //d
oubledoubleCenterParentLength = 0.0,CenterParentAn
gle= 0.0,CenterParentAngleAnother = 0.0;doubleTole
rance = 0.0;//set valueTolerance = F2dCleanUpToler
ance;// look for arrow center linefor( temp_list =
Nodes; temp_list; temp_list = temp_list->cdr){//
check pointer addressif ( StartEntity == temp_list
->car || EndEntity == temp_list->car)continue;//g
et new entityCenterEntity = temp_list->car;//check
flags//if (CenterEntity->flags != 2 //&& Center
Entity->flags != 3 )continue; if( CenterEntity->ty
pe != CK_LINE )continue; if ( CenterEntity->line_
type!= StartEntity->line_type && CenterEntity->col
or != StartEntity->color && CenterEntity->is_thi
ckness != StartEntity->is_thickness ) continue; if
( CenterEntity->no_connected_1 < 2 && CenterEnti
ty->no_connected_2 < 2 ) continue; //check leng
thCenterParentLength = F2dCleanUpLineLength( Cente
rEntity->parent );if ( CenterParentLength < Tolera
nce ) continue;//arrow central-entity angleF2dClea
nUpLineAngle(//inputTopVertex, CenterEntity->paren
t,//output&CenterParentAngle, &CenterParentAngleAn
other);//check the angle for central entity if ( f
abs( CenterParentAngle - *CenterLineAngleTemp )> T
olerance ) continue;// set flags for arrow’s ent
itiesReturnFlag = 1;//look for arrow entity’s chi
ldrenF2dCleanUpChangeChildrenFlag( StartEntity->pa
rent );F2dCleanUpChangeChildrenFlag( EndEntity->pa
rent );F2dCleanUpChangeChildrenFlag( CenterEntity-
>parent );//set flag to arrow top vertexF2dCleanUp
ChangeArrowVertexFlag( &ArrowFlags,TopVertex, Cent
erEntity );return ReturnFlag;if ( temp_list->cdr =
= NULL)break;}return ReturnFlag;}/* 関数: 名
称: F2dCleanUpFindArrowOneSideOpenEntity 記
述: 1つのサイドオープンエンティティを見出す。
復帰値: =0: ノーオープン; =1: オー
プン =2: オープンパラメータ: 入力:
1 Nodes:接続されたノード=================
===============================================*/i
nt F2dCleanUpFindArrowOneSideOpenEntity( struct no
de_list *Nodes ){//link list and temp liststruct n
ode_list*temp_list;//entities counter and flagsint
open_entity_flag = 0;//startfor( temp_list = Node
s; temp_list; temp_list = temp_list->cdr){//ckec
k another side connected’s counterif ( temp_list-
>car->no_connected_1 == 0 && temp_list->car->no_co
nnected_2 > 1 ){open_entity_flag = 1;break;}if ( t
emp_list->car->no_connected_2 == 0 && temp_list->c
ar->no_connected_1 > 1 ){open_entity_flag = 2;brea
k;}if ( temp_list->cdr== NULL )break;}return open_
entity_flag;}/*===================================
============================== 関数: 名称:
F2dClaenUpCheckStartEndEntity 記述: 開始およ
び終了エンティティをチェックする 復帰値:
=0: ノーアロー;= 1: goodパラメータ:入力: 1
StartEntity: アロー開始ラインエンティティ2 EndEnti
ty: アロー終了ラインエンティティ==================
===============================================*/i
nt F2dCleanUpCheckStartEndEntity(//inputstructnode
*StartEntity,structnode *EndEntity ){//external f
unctionsdouble F2dCleanUpLineLength();//doubledoub
learrow_start_parent_length = 0.0,arrow_end_parent
_length = 0.0,arrow_tolerance = 0.0;//set toleranc
earrow_tolerance = F2dCleanUpTolerance;//start//co
mpute entities’ parent lengtharrow_start_parent_l
ength = F2dCleanUpLineLength( StartEntity );arrow_
end_parent_length = F2dCleanUpLineLength( EndEnt
ity );//check lengthif ( arrow_start_parent_length
< arrow_tolerance )return 0; if ( arrow_end_paren
t_length < arrow_tolerance )return 0; //check tloe
ranceif ( fabs( arrow_start_parent_length - arrow_
end_parent_length )> arrow_tolerance )return 0; /
/check angle:if entitiesare parallel, STOPif (sqrt
(fabs((( StartEntity->X1 - StartEntity->X2 )* ( En
dEntity->Y1 - EndEntity->Y2 )) -(( EndEntity-
>X1 - EndEntity->X2 ) * ( StartEntity->Y1 - S
tartEntity->Y2 ))))< arrow_tolerance )return 0;//n
ormal endreturn 1;}/*=============================
===================================関数: 名称: F
2dCleanUpComputeCenterLineAngle記述: センタライン
角度を計算する。戻り値:= 0: ノーアロー;= 1: 良好
パラメータ:入力: 1 TopVertex: アロートップ頂点2
StartEntity: アロー開始ラインエンティティ 3 EndEnt
ity: アロー終了ラインエンティティ出力:1 CenterLin
eAngle: アローセンターライン角度 ================
================================================*/
int F2dCleanUpComputeCenterLineAngle(//inputstruct
planar_vertex *TopVertex,structnode *StartEntity,s
tructnode*EndEntity,//outputdouble*CenterLineAngle
){//external functionsint F2dCleanUpLineAngle();/
/entities counter and flagsint ReturnFlag = 0;//do
ubledoublearrow_start_parent_angle = 0.0,arrow_end
_parent_angle = 0.0,arrow_center_diff_angle = 0.0,
RotateAxisAngleAnotherTemp = 0.0,arrow_center_pare
nt_angle_temp = 0.0,arrow_tolerance = 0.0;//set to
lerancearrow_tolerance = F2dCleanUpTolerance;//sta
rt// compute central angle of arrow////angle_cente
r = 0.5 * ( angle_start + angle_end )//atan2 retur
ns the arctangent of y/x//atan2 returns a value in
the range -pi to pi radians//getarrow start angle
F2dCleanUpLineAngle(//inputTopVertex, StartEntity,
//output&arrow_start_parent_angle, &RotateAxisAngl
eAnotherTemp);//arrow end angleF2dCleanUpLineAngle
(//inputTopVertex, EndEntity,//output&arrow_end_pa
rent_angle, &RotateAxisAngleAnotherTemp);//get dif
ference anglearrow_center_diff_angle = fabs( arrow
_end_parent_angle - arrow_start_parent_angle );/
/same angleif ( arrow_center_diff_angle < arrow_to
lerance )return0;if ( arrow_center_diff_angle < pi
){//diff < piarrow_center_parent_angle_temp = 0.5
* (arrow_end_parent_angle + arrow_start_parent_an
gle );}else{//diff > pi ( take opposite angle ) ar
row_center_parent_angle_temp =0.5 * (arrow_end_par
ent_angle + arrow_start_parent_angle ) + pi;//angl
e> 2*piif ( fabs ( arrow_center_parent_angle_temp
- 2.0 * pi )< arrow_tolerance ){arrow_center_paren
t_angle_temp = 0.0;}else{if ( arrow_center_parent_
angle_temp > ( 2.0 * pi ) ){arrow_center_parent_an
gle_temp = arrow_center_parent_angle_temp - 2.0 *
pi;}}}*CenterLineAngle = arrow_center_parent_angle
_temp;//normal endreturn 1;}/*====================
=============================================関
数: 名称: F2dCleanUpFindArrowEndEntity記述: ア
ロー終了ラインを見出す戻り値:= 0: ノーアロー;= 1:
アローパラメータ:入力: 1 Nodes: 接続ノード2 Top
Vertex: アロートップ頂点3 StartEntity: アロー開始
エンティティ======================================
==========================*/int F2dCleanUpFindArro
wEndEntity(//inputstructnode_list *Nodes,structpla
nar_vertex *TopVertex,structnode *StartEntity){//e
xternal functionsint F2dCleanUpFindArrowOneSideOpe
nEntity();int F2dCleanUpComputeCenterLineAngle();i
nt F2dCleanUpCheckStartEndEntity();intF2dCleanUpFi
ndArrowCenterEntity();//link list and temp liststr
uct node_list*temp_list; //selected entity and tem
p entitiesstruct node *Next_entity,*arrow_start_en
tity_parent,*arrow_end_entity,*arrow_end_entity_pa
rent;//entities counter and flagsint assistant_lin
e_flag = 0,ReturnFlag = 0;//doubledoublearrow_cent
er_parent_angle_temp = 0.0;//startfor( temp_list=N
odes; temp_list; temp_list = temp_list->cdr){ i
f ( temp_list->car== NULL )break;Next_entity = tem
p_list->car;arrow_end_entity = temp_list->car;//if
( Next_entity->flags != 2 )continue;if ( Next_ent
ity->type !=CK_LINE )continue;if ( Next_entity->li
ne_type != StartEntity->line_type)continue;if ( Ne
xt_entity->color != StartEntity->color )continue;i
f (Next_entity->is_thickness != StartEntity->is_th
ickness )continue; //set parentarrow_start_entit
y_parent = StartEntity->parent; arrow_end_entity_p
arent = Next_entity->parent; //look for broken e
ntity’s another side ReturnFlag = F2dCleanUpFindA
rrowOneSideOpenEntity( arrow_end_entity_parent->ch
ildren ); if ( ReturnFlag == 0 )continue;//check p
arents entitiesReturnFlag = F2dCleanUpCheckStartEn
dEntity( //inputarrow_start_entity_parent, arrow_
end_entity_parent );if ( ReturnFlag == 0 )continu
e;// look for central entityof arrowReturnFlag = F
2dCleanUpComputeCenterLineAngle(//inputTopVertex,
arrow_start_entity_parent, arrow_end_entity_paren
t,//output&arrow_center_parent_angle_temp );if ( R
eturnFlag == 0 )continue;// get central entity of
arrowassistant_line_flag = F2dCleanUpFindArrowCent
erEntity(//inputNodes, TopVertex, StartEntity, arr
ow_end_entity, &arrow_center_parent_angle_temp );r
eturn assistant_line_flag;}return assistant_line_f
lag;}/*===========================================
======================関数: 名称: F2dCleanUpChan
geChildrenFlag記述: エンティティのチルドレンフラ
グを変更する関数戻り値:= 0: 成功裏に完了;パラメー
タ:入力: =======================================
==========================*/int F2dCleanUpChangeCh
ildrenFlag(struct node *Entity){//temp liststruct
node_list*Temp_list;//check all of children of the
entityfor( Temp_list=Entity->children; Temp_lis
t; Temp_list = Temp_list->cdr){//change flag to l
ight grayTemp_list->car->flags = 3; if ( Temp_list
->cdr == NULL )break;}return 0;}/*================
=================================================
関数: 名称: F2dCleanUpLineLength記述: ライン形
エンティティの長さを計算する関数 戻り値:= 長さ;パ
ラメータ:入力: エンティティ: ペアレントエンティ
ティ==============================================
==================*/double F2dCleanUpLineLength(st
ruct node *Entity){//definationdoubleEntityLength=
0.0;//compute entities’ parent lengthEntityLength
=sqrt( ( Entity->X1 - Entity->X2 ) * ( Entity->X
1 - Entity->X2 )+ ( Entity->Y1 - Entity->Y2 ) *( E
ntity->Y1 - Entity->Y2 ));returnEntityLength;}/*==
==================================================
=============関数: 名称: F2dCleanUpFindArrow記
述: アロー型エンティティを求め、フラグをそれらに
設定する。 戻り値:= 0: 成功裏に完了;パラメータ:
入力: 1 Entities_list: チェックされるノードリスト
==================================================
==============*/int F2dCleanUpFindArrow( struct no
de_list *Entities_list ){//external functionsint F
2dCleanUpLineAngle();int F2dCleanUpFindArrowEndEnt
ity(); //link list and temp liststruct node_list*t
emp_nodes1,*arrow_list,*temp_list; //selected enti
ty and temp entitiesstruct node *Next_entity;struc
t planar_vertex*top_vertex;//entities counter and
flagsint bug_flag = 0,ReturnFlag = 0,assistant_lin
e_flag = 0;int CountPrompt = 0;charmessage[64];#if
def VELLUMCountPrompt++;sprintf( message,"Start Fi
nd Arrow Entity %d", CountPrompt );ck_prompt( mess
age ); #endif// Step_1:look for one side open ent
ity//arrow start entityfor( temp_list=Entities_lis
t; temp_list; temp_list = temp_list->cdr){Next_e
ntity =temp_list->car;//if ( Next_entity->flags !=
2 ) continue;if ( Next_entity->type != CK_LINE )
continue;if ( Next_entity->no_connected_1 == 0&&N
ext_entity->no_connected_2 < 2 ) continue;if ( Ne
xt_entity->no_connected_1 < 2&& Next_entity->no
_connected_2 == 0 ) continue; //selectentity’
s sideif ( Next_entity->no_connected_1 == 0 ){// c
lear bug_flagbug_flag = 0;//look for broken entit
y’s another side for( arrow_list = Next_entity->p
arent->children; arrow_list; arrow_list = arrow_
list->cdr){//ckeck another side vertex’s pointeri
f ( Next_entity->parent->vertex2 == arrow_list->c
ar->vertex2 ){ bug_flag = 1; break;}if ( arrow_l
ist->cdr == NULL )break;}if ( bug_flag == 1 ){top_
vertex = Next_entity->parent->vertex2;temp_nodes1
= arrow_list->car->connected_nodes_2;}}else{//clea
r bug_flagbug_flag = 0;//look for broken entity’s
another side for(arrow_list = Next_entity->parent
->children; arrow_list; arrow_list =arrow_list->
cdr){//ckeck another side vertex’s pointerif ( Ne
xt_entity->parent->vertex1 == arrow_list->car->ve
rtex1 ){ bug_flag = 1; break;}if ( arrow_list->c
dr == NULL )break;}if ( bug_flag == 1 ){top_vertex
= Next_entity->parent->vertex1;temp_nodes1 = arro
w_list->car->connected_nodes_1;}}if ( bug_flag !=
1 ) continue;// get end entity of arrowReturnF
lag = F2dCleanUpFindArrowEndEntity(//inputtemp_nod
es1, top_vertex, Next_entity );if ( ReturnFlag ==
1 )assistant_line_flag = 1;if ( temp_list->cdr ==
NULL )break;}#ifdef VELLUMCountPrompt++;sprintf( m
essage,"Finished find arrows Entity %d", CountProm
pt );ck_prompt( message ); #endifreturnassistant_
line_flag;}/*=====================================
============================関数: 名称: F2dClean
UpFindOneSideOpenEntity記述:look for one side ope
n entities and they are vertical with arrow type e
ntities. 戻り値:= 0: Completed successfully and N
o found;= NUM: Open entities’ numberパラメータ:
入力: 1 Entities_list: a node list that willbe ch
ecked=============================================
===================*/int F2dCleanUpFindOneSideOpen
Entity( struct node_list *Entities_list){//externa
l functionsint F2dCleanUpChangeChildrenFlag();//li
nk list and temp liststruct node_list *temp_list;
//selected entity and temp entitiesstruct node *Ne
xt_entity;//entities counter and flagsint count =
0;//doubledoubleassistant_line_angle = 0.0,arrow_t
olerance = 0.0;int CountPrompt = 0;charmessage[6
4];//set tolerancearrow_tolerance = F2dCleanUpTole
rance;#ifdef VELLUMCountPrompt++;sprintf( messag
e,"Start Find One side open Entity %d", CountPromp
t );ck_prompt( message ); #endif // checkall o
f entities which connected with outside loop fo
r( temp_list=Entities_list; temp_list; temp_list
= temp_list->cdr){ if ( temp_list->car== NULL )br
eak;Next_entity = temp_list->car;//check flags//if
( Next_entity->flags !=2 )continue;//check verte
x’ flagif ( Next_entity->vertex1->flags != 3 && N
ext_entity->vertex2->flags != 3 )continue;//check
linesverticallyif ( Next_entity->vertex1->flags ==
3 ){assistant_line_angle= fabs ( ( Next_entity-
>X1 - Next_entity->X2 )* (Next_entity->vertex1->Ar
rowCenterLine_X1 - Next_entity->vertex1->Arrow
CenterLine_X2 ) + (Next_entity->Y1 - Next_entity->
Y2 ) * (Next_entity->vertex1->ArrowCenterLine_Y1
- Next_entity->vertex1->ArrowCenterLine_Y2 )
);}else{assistant_line_angle = fabs ( ( Next_en
tity->X1 - Next_entity->X2 )* (Next_entity->vertex
2->ArrowCenterLine_X1 - Next_entity->vertex2->
ArrowCenterLine_X2 ) + ( Next_entity->Y1 - Next_en
tity->Y2 ) * (Next_entity->vertex2->ArrowCenterLin
e_Y1 - Next_entity->vertex2->ArrowCenterLine_Y
2 ));}//check the angle for central entity if ( sq
rt(assistant_line_angle)> arrow_tolerance ) contin
ue;//look for childrenF2dCleanUpChangeChildrenFlag
( Next_entity->parent );count++;}#ifdef VELLUMCoun
tPrompt++;sprintf( message,"Finished find one side
open Entity %d", CountPrompt );ck_prompt( message
); #endif//normal endreturn count;}/*===========
==================================================
====関数: 名称: F2dCleanUpFindOneSideOpenEntity2
記述: ビユーを見出した後に一側がオープンのエンテ
ィティとビユーの境界を横切るエンティティを見出す。
戻り値:= 0: 成功裏に完了し、何も見出されない;= NU
M: オープンエンティティの個数パラメータ:入力: 1I
n_drawing: 図=====================================
===========================*/int F2dCleanUpFindOne
SideOpenEntity2( struct drawing *In_drawing ){//ex
ternal functionsint F2dCleanUpChangeChildrenFla
g();//link list and temp liststruct node_list *tem
p_list, *ConnectedNode; //selected entity and temp
entitiesstruct node *Entity;//define flagintBound
aryFlag = 0; int CountPrompt = 0;charmessage[64];#
ifdef VELLUMCountPrompt++;sprintf( message,"2 Star
t Find Oneside Open Entity %d", CountPrompt );ck_
prompt( message ); #endif //check node listif
( In_drawing == NULL )return-1;if ( In_drawing->ob
jects == NULL )return-1; // check all of entiti
es which connected with outside loop for( Entit
y=In_drawing->objects;Entity;Entity = Entity->next
){//check connected nodes countif ( Entity== NULL
)break;if (( Entity->no_connected_1 == 0 ) &&( E
ntity->no_connected_2 == 0 ))continue;//check flag
sif (( Entity->flags == 3 ) &&( Entity->type == CK
_LINE ) &&(( Entity->no_connected_1 == 0 ) ||(
Entity->no_connected_2 == 0 ))){//one side open an
d line typeif ( Entity->no_connected_2 == 0 ) C
onnectedNode = Entity->connected_nodes_1;else Conn
ectedNode = Entity->connected_nodes_2;//clear foun
d boundary’s flagBoundaryFlag = 0;//check across
with views’ boundaryif ( ConnectedNode != NULL){f
or ( temp_list = ConnectedNode; temp_list;temp_lis
t = temp_list->cdr){//check wrong dataif ( temp_li
st->car == NULL )break;if ( temp_list->car->flags
== 4 ){//find boundary’s entityBoundaryFlag = 1;b
reak;}if (temp_list->cdr == NULL )break;}if ( Boun
daryFlag == 1 ) //look for children F2dCleanUpCha
ngeChildrenFlag( Entity->parent );}}//check arc if
((Entity->type == CK_ARC ) &&( Entity->flags !=
99 ) &&(( Entity->no_connected_1 == 0 ) ||( Ent
ity->no_connected_2 == 0 ))){//look for childrenF2
dCleanUpChangeChildrenFlag( Entity->parent );}if
( Entity->next == NULL )break;}#ifdef VELLUMCountP
rompt++;sprintf( message,"Finished 2 one side open
Entity %d", CountPrompt );ck_prompt( message );
#endif//normalendreturn 0;}/*=====================
===========================================関数:
名称: F2dCleanUpFindGroupMinX記述: エンティティ
グループに対する最小X値を求める。戻り値:= 0: 成
功裏に完了し、エンティティ無し;パラメータ:入力:
1 Entities_list: チェックされるノードリスト出力:1
Entity: エンティティは最小のX値を含む。========
==================================================
======*/struct node *F2dCleanUpFindGroupMinX( stru
ct node_list *Entities_list ){//double F2dCleanUpL
ineLength();//entities counter and flagsint open_e
ntity_flag = 0;//link list and temp liststruct nod
e_list*EntitiesList2,*Out_temp_list2,*open_temp_li
st2, *open_list2, *temp_list1, *temp_list2; //sele
cted entity and temp entitiesstructnode *Next_ent
ity, *MinXvalueEntity;//length and angledoubleMinX
valueGroup = 0.0;//check all of entities which con
nected with outside loop//initializeEntitiesList2
=( struct node_list * ) calloc ( 1, sizeof ( struc
t node_list ));open_list2 = ( struct node_list * )
calloc ( 1, sizeof (struct node_list ));//check f
irst entity//search connected entity untilreal ent
ity be foundfor ( temp_list2 = Entities_list;//ent
ity->connected_nodes; ( temp_list2!=0 && t
emp_list2->car!=0 ); temp_list2=temp_list2->c
dr){if ( temp_list2->car == NULL )break;if ( temp_
list2->car->no_connected_1 == 0 ) continue;if ( te
mp_list2->car->no_connected_2== 0 ) continue;if (
temp_list2->car->flags == 2 ){//set pointer to fir
st entityopen_list2->car = temp_list2->car;//set m
inimum X valueMinXvalueGroup = temp_list2->car->Mi
n_X;MinXvalueEntity = temp_list2->car;break;}if (
temp_list2->cdr == NULL )break;}if ( open_list2->c
ar == 0 )return 0;//set link addressopen_list2->cd
r = NULL;//set the pointer to output node listEnti
tiesList2->car = open_list2->car;EntitiesList2->cd
r = open_list2->cdr;////Step_6_1://find connected
entitiesfor ( temp_list1 = open_list2; ( tem
p_list1 //&&(temp_list->cdr != 0) );
) {//get a pointer from open listif ( temp_list1
->car == NULL )break;Next_entity = temp_list1->ca
r;//set a closed flag to the node//Next_entity->fl
ags = 1;//close the node ( delete the node from op
en list )open_list2 = open_list2->cdr;// look for
first connected entity whose flags=0.for ( temp_li
st2 = Next_entity->connected_nodes; ( temp_list2!
=0 && temp_list2->car!=0 ); temp_list2
=temp_list2->cdr){ if ( temp_list2->car == NUL
L ) break;// if found an unmarked connected entity
if ( temp_list2 && temp_list2->car->flags==2&& Min
XvalueEntity->line_type == temp_list2->car->line_t
ype&& MinXvalueEntity->color == temp_list2->car->c
olor&& MinXvalueEntity->is_thickness == temp_list2
->car->is_thickness ){//check minimum Xif ( t
emp_list2->car->Min_X < MinXvalueGroup ){//change
minimum X valueMinXvalueGroup = temp_list2->car->
Min_X;MinXvalueEntity = temp_list2->car; }// alloc
ate memory for open list elementopen_temp_list2 =
( struct node_list * ) calloc ( 1, sizeof ( struct
node_list ));// allocate memory for output node l
ist elementOut_temp_list2 = ( structnode_list * )
calloc ( 1, sizeof ( struct node_list ));// add th
is entity to the open listopen_temp_list2->car = t
emp_list2->car;// add this entity to the output no
de list Out_temp_list2->car = temp_list2->car;//se
ta open flagto the nodeopen_temp_list2->car->flags
= 1; // connect to the open listopen_temp_list2->
cdr = open_list2;// move the pointer of openlist t
o the topopen_list2 = open_temp_list2;// connect t
o the output node listOut_temp_list2->cdr = Entiti
esList2;// move the pointer of outputnode list to
the topEntitiesList2 = Out_temp_list2;}if ( temp_l
ist2->cdr == NULL )break;}// assign value to the l
oop variabletemp_list1 = open_list2;}return MinXva
lueEntity;}/*=====================================
============================関数: 名称: F2dClean
UpFindOutNextEntity記述: アウトサイドループエンテ
ィティに接続されたエンティティを求める。戻り値:=
0: 成功裏に完了;パラメータ:入力: 1 In_entity: 軸
エンティティを回転 2 In_Nodes: エンティティのノー
ド3 In_Vertex: エンティティの頂点4 *In_Angle: エン
ティティの角度====================================
============================*/int F2dCleanUpFindOu
tNextEntity(//input struct node*In_entity,struct n
ode_list *In_Nodes, struct planar_vertex *In_Verte
x,double *In_Angle){//external functionsint F2dCle
anUpArcAngle(); int F2dCleanUpLineAngle();//link l
ist and temp liststruct node_list*temp_list, *Rota
teNodes,*RotateNodesTemp,*RotateNodesAnother,*Rota
teNodesAnotherTemp;//selected entity and temp enti
tiesstruct node *Next_entity, *RotateEntity;struc
t planar_vertex*RotateVertex,*RotateVertexTemp,*Ro
tateVertexAnother,*RotateVertexAnotherTemp;int Rot
ateVertexFlag = 0,RotateAxisEntityType = 0,RotateA
xisEntityVertexFlag = 0,FindNextFlag = 0;//length
and angledoubleRotateAxisAngleAnother = 0.0,Rotate
AxisAngleAnotherTemp = 0.0,RotateMinAngleTemp = 0.
0,RotateDiffAngleTemp = 0.0,RotateAxisAngle = 0.0,
RotateAxisAngleTemp = 0.0;//set tolerance Toleranc
edoubleTolerance = 0.0;Tolerance = F2dCleanUpTole
rance;//initializeRotateAxisAngleAnother= *In_Angl
e;RotateEntity= In_entity;RotateNodesAnother= In_N
odes;RotateVertexAnother= In_Vertex;//check all of
entities which connected with outside loopfor( ;
; ){//set flag for first entity on loopFindNextF
lag = 0;RotateEntity->flags= 4;RotateAxisEntityTyp
e = RotateEntity->type;if ( RotateEntity->vertex1
== RotateVertexAnother )RotateAxisEntityVertexFlag
= 1;else RotateAxisEntityVertexFlag = 2;//set sta
ndard axis for first searchRotateAxisAngle = Rotat
eAxisAngleAnother;RotateMinAngleTemp= 2.0 * pi;Rot
ateNodes= RotateNodesAnother;RotateVertex= RotateV
ertexAnother; //check next connected entityif
( RotateNodes == 0 )break;//start loop processfor
( temp_list=RotateNodes; temp_list; temp_list =
temp_list->cdr){if ( temp_list->car == NULL )brea
k;Next_entity = temp_list->car;//checkflagsif ( Ne
xt_entity->flags == 4 )break;if ( Next_entity->fla
gs != 1 )continue;switch ( Next_entity->type ){//a
rc type entitycaseCK_ARC:RotateVertexFlag = F2dCl
eanUpArcAngle(//inputRotateVertex, Next_entity,//o
utput&RotateAxisAngleTemp, &RotateAxisAngleAnother
Temp);break;//line typeentitycaseCK_LINE:RotateVe
rtexFlag = F2dCleanUpLineAngle(//inputRotateVerte
x, Next_entity,//output&RotateAxisAngleTemp, &Rota
teAxisAngleAnotherTemp);break;//wrong type entityd
efault:break;}//select connected side ofentityif
( RotateVertexFlag == 1 ){//get start->end //set r
otation vertex nodeRotateNodesTemp = Next_entity->
connected_nodes_1;RotateVertexTemp=Next_entity->ve
rtex1;//set another side vertex nodeRotateNodesAno
therTemp = Next_entity->connected_nodes_2;RotateVe
rtexAnotherTemp= Next_entity->vertex2;}else{//set
rotation vertex nodeRotateNodesTemp = Next_entity-
>connected_nodes_2;RotateVertexTemp = Next_entity-
>vertex2;//set anotherside vertex nodeRotateNodesA
notherTemp = Next_entity->connected_nodes_1;Rotate
VertexAnotherTemp= Next_entity->vertex1;}//compute
diff angle//for change current entityRotateDiffAn
gleTemp = RotateAxisAngleTemp - RotateAxisAngle;if
( fabs( RotateDiffAngleTemp ) < Tolerance ) {swit
ch( RotateAxisEntityType ){caseCK_ARC:switch( Rota
teAxisEntityVertexFlag ){case1:RotateDiffAngleTemp
= 2.0 * pi;break;case2:RotateDiffAngleTemp = 0.0;
break;}break;caseCK_LINE:switch( RotateVertexFlag
){case1:RotateDiffAngleTemp = 0.0;break;case2:Rot
ateDiffAngleTemp = 2.0 * pi;break;}break;}}if (Rot
ateDiffAngleTemp < 0.0 ){RotateDiffAngleTemp = Rot
ateDiffAngleTemp +2.0 * pi;}if ( fabs( RotateDiffA
ngleTemp - RotateMinAngleTemp ) < Tolerance ) {swi
tch( Next_entity->type ){caseCK_ARC:switch( Rotate
Entity->type){caseCK_ARC:switch( RotateVertexFlag
){case1://no changebreak;case2:RotateEntity= Next
_entity;RotateNodes = RotateNodesTemp;RotateVert
ex= RotateVertexTemp;RotateNodesAnother = RotateNo
desAnotherTemp;RotateVertexAnother = RotateVertexA
notherTemp;RotateAxisAngleAnother = RotateAxisAngl
eAnotherTemp;break;}break;caseCK_LINE:switch( Rota
teVertexFlag ){case1://no changebreak;case2:Rotate
Entity= Next_entity;RotateNodes = RotateNodesTem
p;RotateVertex= RotateVertexTemp;RotateNodesAnothe
r = RotateNodesAnotherTemp;RotateVertexAnother = R
otateVertexAnotherTemp;RotateAxisAngleAnother = Ro
tateAxisAngleAnotherTemp;break;}break;}caseCK_LIN
E:switch( RotateEntity->type ){caseCK_ARC:if ( Rot
ateEntity->vertex1 == RotateVertex ){RotateEntity=
Next_entity;RotateNodes = RotateNodesTemp;Rotat
eVertex= RotateVertexTemp;RotateNodesAnother = Rot
ateNodesAnotherTemp;RotateVertexAnother = RotateVe
rtexAnotherTemp;RotateAxisAngleAnother = RotateAxi
sAngleAnotherTemp;}break;}}}if ( RotateDiffAngleTe
mp < RotateMinAngleTemp ){FindNextFlag = 1;RotateM
inAngleTemp = RotateDiffAngleTemp;//set rotation e
ntityRotateEntity= Next_entity;RotateNodes = Rot
ateNodesTemp;RotateVertex= RotateVertexTemp;Rotate
NodesAnother = RotateNodesAnotherTemp;RotateVertex
Another = RotateVertexAnotherTemp;RotateAxisAngleA
nother =RotateAxisAngleAnotherTemp;}}//check flags
//if loop meet closed entityif ( Next_entity->flag
s == 4 )break;if ( FindNextFlag == 0 ) break;}retu
rn 0;}/*==========================================
=======================関数: 名称: F2dCleanUpFin
dOutSideLoop記述: アウトサイドループエンティティ
を求める。戻り値:= 0: アウトサイドループエンティ
ティを求める。;= NUM: アウトサイドエンティティの個
数パラメータ:入力: 1 Entity: エンティティはルー
プの最小X値を含む。==============================
==================================*/int F2dCleanUp
FindOutSideLoop( struct node *MinXvalueEntity ){//
external functionsint F2dCleanUpArcAngle(); int F2
dCleanUpLineAngle();int F2dCleanUpFindOutFirstEnti
ty();int F2dCleanUpFindOutNextEntity(); //entities
counter and flagsint count = 0,count2 = 0,open_en
tity_flag = 0,RotateVertexFlag = 0,assistant_line_
flag = 0;//link list and temp liststruct node_list
*outside_loop_temp_list3, *RotateNodes,*RotateNode
sTemp,*RotateNodesAnother,*RotateNodesAnotherTemp;
//selected entity and temp entitiesstruct node *N
ext_entity, *RotateEntity;struct planar_vertex*Rot
ateVertex,*RotateVertexTemp,*RotateVertexAnother,*
RotateVertexAnotherTemp;//length and angledoubleas
sistant_line_angle = 0.0,MinXvalueGroup = 0.0,Rota
teAxisAngleAnother = 0.0,RotateAxisAngleAnotherTem
p =0.0,RotateMinAngleTemp = 0.0,RotateDiffAngle =
0.0,RotateDiffAngleTemp=0.0,RotateAxisAngle = 0.0,
RotateAxisAngleTemp = 0.0;//set tolerance Toleranc
edoubleloop_tolerance = 0.00;loop_tolerance = F2d
CleanUpTolerance;//loop direction : counter-clock/
/check a flag for outside loop process//if ( count
2 > 0 ){//step_7_1:find first entity for the group
//set standard axis for first searchRotateAxisAngl
e = 1.5 * pi;RotateMinAngleTemp=2.0 * pi;//step_7_
1_1: only one entity//check entities’ angle//arc
case: special case ( no vertex on min_x )if ( MinX
valueEntity->type == CK_ARC && ( fabs ( MinXvalue
Entity->Min_X - MinXvalueEntity->vertex1->X ) >loo
p_tolerance ) && ( fabs ( MinXvalueEntity->Min_X -
MinXvalueEntity->vertex2->X ) > loop_tolerance )
){//set rotation vertex nodeRotateNodesAnother =
MinXvalueEntity->connected_nodes_2;RotateVertexAno
ther = MinXvalueEntity->vertex2;RotateEntity= MinX
valueEntity;//get arc end-angle //(direction : fro
m circle-center to end-point )RotateAxisAngleAnoth
erTemp= ( MinXvalueEntity->AngEnd ) * pi / 180.0;/
/change angle to oppsite direction//( direction :
from end-point to circle-center )RotateAxisAngleAn
otherTemp = RotateAxisAngleAnotherTemp + pi;//chec
k angle if ( RotateAxisAngleAnotherTemp > ( 2.0 *
pi )){ RotateAxisAngleAnotherTemp = RotateAxisAngl
eAnotherTemp - 2.0 * pi;}if ( fabs ( RotateAxisAng
leAnotherTemp -( 2.0 * pi )) < loop_tolerance ){Ro
tateAxisAngleAnotherTemp = 0.0;}//compute tangentl
ine angle for the arc end-angle//( direction : fro
m end-point to start-point )RotateAxisAngleAnother
Temp = RotateAxisAngleAnotherTemp + 0.5 * pi;//che
ck angle if ( RotateAxisAngleAnotherTemp > ( 2.0 *
pi )){ RotateAxisAngleAnotherTemp = RotateAxisAng
leAnotherTemp - 2.0 * pi;}if ( fabs ( RotateAxisAn
gleAnotherTemp - ( 2.0 * pi )) < loop_tolerance )
{RotateAxisAngleAnotherTemp = 0.0;}//set rotation
standard angle ( clock direction )RotateAxisAngleA
nother = RotateAxisAngleAnotherTemp;}//step_7_1_2:
multiple entities around Min_xelse{//select conne
cted side ofentityif ( fabs ( MinXvalueEntity->Min
_X - MinXvalueEntity->vertex1->X)< loop_tolerance
)//get start->end //set rotation vertex nodeRotat
eVertex= MinXvalueEntity->vertex1;elseRotateVertex
= MinXvalueEntity->vertex2;switch ( MinXvalueEntit
y->type ){//arc type entitycaseCK_ARC:RotateVerte
xFlag = F2dCleanUpArcAngle(//inputRotateVertex, Mi
nXvalueEntity,//output&RotateAxisAngleTemp, &Rotat
eAxisAngleAnotherTemp);break;//line type entityca
seCK_LINE:RotateVertexFlag = F2dCleanUpLineAngle(/
/inputRotateVertex, MinXvalueEntity,//output&Rotat
eAxisAngleTemp, &RotateAxisAngleAnotherTemp);brea
k;default:break;} //select connected side of entit
yif ( RotateVertexFlag == 1 ){//get start->end //s
et rotation vertex nodeRotateNodesTemp = MinXvalue
Entity->connected_nodes_1;RotateVertexTemp= MinXva
lueEntity->vertex1;//set another side vertex nodeR
otateNodesAnotherTemp = MinXvalueEntity->connected
_nodes_2;RotateVertexAnotherTemp= MinXvalueEntity-
>vertex2;}else{//set rotation vertex nodeRotateNod
esTemp = MinXvalueEntity->connected_nodes_2;Rotate
VertexTemp = MinXvalueEntity->vertex2;//set anothe
r side vertex nodeRotateNodesAnotherTemp = MinXval
ueEntity->connected_nodes_1;RotateVertexAnotherTem
p= MinXvalueEntity->vertex1;}//compute diff angle/
/for change current entityRotateDiffAngleTemp = Ro
tateAxisAngleTemp - RotateAxisAngle;if ( RotateDif
fAngleTemp < 0.0 ){RotateDiffAngleTemp = RotateDif
fAngleTemp + 2.0 * pi;}if ( RotateDiffAngleTemp <
RotateMinAngleTemp ){RotateMinAngleTemp = RotateDi
ffAngleTemp;//set rotation entityRotateEntity= Min
XvalueEntity;RotateNodes = RotateNodesTemp;Rotat
eVertex= RotateVertexTemp;RotateNodesAnother = Rot
ateNodesAnotherTemp;RotateVertexAnother = RotateVe
rtexAnotherTemp;RotateAxisAngleAnother =RotateAxis
AngleAnotherTemp;}//step_7_1_3: find next connecte
d entity with first entity around Min_x-vertex//ch
eck all of entities which connected with first ent
ity if ( RotateNodes != 0 ){ for( outside_lo
op_temp_list3=RotateNodes; outside_loop_temp_list
3; outside_loop_temp_list3= outside_loop_temp_lis
t3->cdr){if ( outside_loop_temp_list3->car == NULL
)break;Next_entity = outside_loop_temp_list3->ca
r;//check flagsif ( Next_entity->flags !=1 )contin
ue;switch ( Next_entity->type ){//arc typeentityc
aseCK_ARC:RotateVertexFlag = F2dCleanUpArcAngle(//
inputRotateVertex, Next_entity, //output&RotateAxi
sAngleTemp, &RotateAxisAngleAnotherTemp);break;//l
ine type entitycaseCK_LINE:RotateVertexFlag = F2d
CleanUpLineAngle(//inputRotateVertex, Next_entity,
//output&RotateAxisAngleTemp,&RotateAxisAngleAnot
herTemp);break;//wrong type entitydefault:break;}/
/select connected side of entityif ( RotateVertexF
lag == 1 ){//get start->end //set rotation vertex
nodeRotateNodesTemp = Next_entity->connected_nodes
_1;RotateVertexTemp= Next_entity->vertex1;//set an
other side vertexnodeRotateNodesAnotherTemp = Next
_entity->connected_nodes_2;RotateVertexAnotherTemp
= Next_entity->vertex2;}else{//set rotation vertex
nodeRotateNodesTemp = Next_entity->connected_node
s_2;RotateVertexTemp = Next_entity->vertex2;//set
another side vertex nodeRotateNodesAnotherTemp = N
ext_entity->connected_nodes_1;RotateVertexAnotherT
emp= Next_entity->vertex1;}//compute diff angle//f
or change current entityRotateDiffAngleTemp = Rota
teAxisAngleTemp - RotateAxisAngle;if ( RotateDiffA
ngleTemp < 0.0 ){RotateDiffAngleTemp = RotateDiffA
ngleTemp + 2.0 * pi;}if ( fabs( RotateDiffAngleTem
p - RotateMinAngleTemp ) < loop_tolerance ) {switc
h( Next_entity->type ){caseCK_ARC:switch( RotateEn
tity->type ){caseCK_ARC:switch( RotateVertexFlag )
{case1://no changebreak;case2:RotateEntity= Next_e
ntity;RotateNodes = RotateNodesTemp;RotateVertex
= RotateVertexTemp;RotateNodesAnother = RotateNode
sAnotherTemp;RotateVertexAnother = RotateVertexAno
therTemp;RotateAxisAngleAnother = RotateAxisAngleA
notherTemp;break;}break;caseCK_LINE:switch( Rotate
VertexFlag ){case1://no changebreak;case2:RotateEn
tity= Next_entity;RotateNodes = RotateNodesTemp;
RotateVertex= RotateVertexTemp;RotateNodesAnother
= RotateNodesAnotherTemp;RotateVertexAnother = Rot
ateVertexAnotherTemp;RotateAxisAngleAnother = Rota
teAxisAngleAnotherTemp;break;}break;}caseCK_LINE:s
witch( RotateEntity->type ){caseCK_ARC:if ( Rotate
Entity->vertex1 == RotateVertex ){RotateEntity= Ne
xt_entity;RotateNodes = RotateNodesTemp;RotateVe
rtex= RotateVertexTemp;RotateNodesAnother = Rotate
NodesAnotherTemp;RotateVertexAnother = RotateVerte
xAnotherTemp;RotateAxisAngleAnother = RotateAxisAn
gleAnotherTemp;}break;}}}if ( RotateDiffAngleTemp
< RotateMinAngleTemp ){RotateMinAngleTemp =RotateD
iffAngleTemp;//set rotation entityRotateEntity= Ne
xt_entity;RotateNodes = RotateNodesTemp;RotateVe
rtex= RotateVertexTemp;RotateNodesAnother = Rotate
NodesAnotherTemp;RotateVertexAnother = RotateVerte
xAnotherTemp;RotateAxisAngleAnother = RotateAxisAn
gleAnotherTemp;}}}}//step_7_2:find next connected
entity with first entity along the loopF2dCleanUpF
indOutNextEntity(//input RotateEntity, RotateNodes
Another, RotateVertexAnother, &RotateAxisAngleAnot
her );return 0;}/*================================
=================================関数: 名称: Tes
tFindArrowControl記述: 手動関数。ビユーに対して全
てのアロー型エンティティを求める。戻り値:< 0: エ
ラー= 0: プロセスなし> 0: 成功裏に完了; 個数は見出
されたエンティティのカウンタ値である。パラメータ:
副関数:struct node_list *F2dCleanUpPickUpAllOneSi
deOpenEntity一側オープンのエンティティを求める。in
t F2dCleanUpFindArrowアロー型エンティティを求め
る。int F2dCleanUpFindArrowEndEntityアローエンドラ
インを見出す。int F2dCleanUpFindArrowCenterEntity
アローセンターラインを見出す。int F2dCleanUpFindAr
rowOneSideOpenEntityアロー型の一側オープンのエンテ
ィティを見出す。int F2dCleanUpComputeCenterLineAng
leセンターライン角度を計算する。int F2dCleanUpChec
kStartEndEntityスタートエンティティおよびエンドエ
ンティティをチェックする。int F2dCleanUpLineAngle
ラインタイプエンティティの角度を計算する。int F2dC
leanUpArcAngle弓形のエンティティの角度を計算する。
int F2dCleanUpChangeChildrenFlagエンティティのチル
ドレンフラグを変更する。int F2dCleanUpChangeArrowV
ertexFlagアロー頂点のフラグを変更し、アローセンタ
ーライン座標を設定する。int F2dCleanUpChangeDrawin
gColorエンティティの色を変更する。 double F2dClean
UpLineLengthライン型エンティティの長さを計算する。
==================================================
==============*/intTestFindArrowControl( int*Switc
hRedraw ){//external functionsint F2dCleanUpFindAr
row();int F2dCleanUpChangeDrawingColor();struct no
de_list *F2dCleanUpPickUpAllOneSideOpenEntity();//
entities counter and flagsint count = 0,assistant_
line_flag= 0;//link list and temp liststruct node_
list*Entities_change_color_list1; //Begin//-------
---------------------------//Step_1://check the nu
mber of entites// get count of all entities// if
an error occurred, exit immidiately. if (number
_of_entities<0) return -1;//---------------------
------------//Step_3: pickup all one side open ent
itiesEntities_change_color_list1 = F2dCleanUpPickU
pAllOneSideOpenEntity( &trim_drawing );if (Entitie
s_change_color_list1 == 0) return 0;//-----------
----------------------//Step_4: find arrow lineF2d
CleanUpFindArrow( Entities_change_color_list1 );//
---------------------------------//Step_X://change
color to Magenta for a selected boundary // tu
rn off input levels#ifdefCKWINif ( *SwitchRedraw =
= 1)ck_levels(CK_OFF,1,255);#endifif ( *SwitchRedr
aw == 1)F2dCleanUpChangeDrawingColor(&trim_drawin
g);//clear a flag for outside loop processassistan
t_line_flag = 0;// turn ON the level usedto store
the trimmed entities.#ifdef CKWINif ( *SwitchRedra
w == 1)ck_levels(CK_ON,TrimLevel, TrimLevel);if (
*SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );#endif
return count;}/*==================================
===============================関数: 名称: TestF
indOneSideOpen2Control記述:手動関数。 一側がオー
プンで、ビユーの境界を横切るエンティティを全て見出
す。 戻り値:< 0: エラー= 0: プロセスなしパラメー
タ:副関数:int F2dCleanUpFindOneSideOpenEntity2一
側がオープンで、ビユーの境界を横切るエンティティを
全て求める。int F2dCleanUpChangeDrawingColorエンテ
ィティの色を変更する。============================
====================================*/intTestFindO
neSideOpen2Control( int *SwitchRedraw ){//external
functionsint F2dCleanUpFindOneSideOpenEntity2();i
nt F2dCleanUpChangeDrawingColor();//Step_1:check t
he number of entites// if an error occurred, exit
immidiately. if (number_of_entities<0) return
-1;//Step_2:pickup all oneside open entitiesF2dCle
anUpFindOneSideOpenEntity2( &trim_drawing );//Step
_X:change color to Magenta for a selected boundary
// turn off input levels#ifdef CKWINif ( *Swit
chRedraw == 1)ck_levels(CK_OFF,1,255);#endifif ( *
SwitchRedraw == 1)F2dCleanUpChangeDrawingColor(&tr
im_drawing);// turn ON the level used to store the
trimmed entities.#ifdef CKWINif (*SwitchRedraw ==
1)ck_levels(CK_ON,TrimLevel, TrimLevel);if ( *Swi
tchRedraw == 1)ck_redraw( CK_PRIME_VP );#endifretu
rn 0;}/*==========================================
=======================関数: 名称: TestFindOneSi
deOpenControl記述: 手動関数。 ビユーに対して、一
側が開放でアロー型エンティティに対して垂直のものを
見出す。戻り値:< 0: エラー= 0: プロセスなし> 0:
成功裏に完了; この数は、見出されたエンティティの個
数。パラメータ:副関数:struct node_list *F2dClean
UpPickUpAllOneSideOpenEntity一側開放エンティティを
求める。int F2dCleanUpChangeChildrenFlagエンティテ
ィのチルドレンフラグを変更する。int F2dCleanUpChan
geDrawingColorエンティティの色を変更する。int F2dC
leanUpFindOneSideOpenEntity一側開放エンティティを
求め、それらはアロー型エンティティに対して垂直であ
る。==============================================
==================*/intTestFindOneSideOpenControl
( int *SwitchRedraw ){//external functionsint F2dC
leanUpFindOneSideOpenEntity();int F2dCleanUpChange
DrawingColor();struct node_list *F2dCleanUpPickUpA
llOneSideOpenEntity();//entities counter and flags
int count = 0,assistant_line_flag = 0;//link list
and temp liststruct node_list*Entities_list; //Beg
in//----------------------------------//Step_1://c
heck thenumber of entites// if an error occurred,
exit immidiately. if (number_of_entities<0) re
turn -1;//---------------------------------//Step_
2:pickup all one side open entitiesEntities_list =
F2dCleanUpPickUpAllOneSideOpenEntity( &trim_drawi
ng ); if (Entities_list == 0) return 0;//-----
----------------------------//Step_3: find lines v
ertical with arrow type entitiesF2dCleanUpFindOneS
ideOpenEntity( Entities_list );//-----------------
----------------//Step_X://change color to Magenta
for a selected boundary // turn off input leve
ls#ifdef CKWINif ( *SwitchRedraw== 1)ck_levels(CK_
OFF,1,255);#endifif ( *SwitchRedraw == 1)F2dCleanU
pChangeDrawingColor(&trim_drawing);//clear a flag
for outside loop processassistant_line_flag = 0;//
turn ON the level used to store the trimmed entit
ies.#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels
(CK_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw ==
1)ck_redraw( CK_PRIME_VP );#endifreturn count;}/*
==================================================
===============関数: 名称: F2dCleanUpPickUpAllOn
eSideOpenEntity記述: 選択図の全ての一側開放エンテ
ィティを求める。戻り値:= 0: 成功裏に完了;パラメー
タ:入力: In_drawing: 図出力:NodeList:全ての一側
開放エンティティに対するノードリスト==============
==================================================
*/struct node_list *F2dCleanUpPickUpAllOneSideOpen
Entity(struct drawing *In_drawing ){//entities cou
nter and flagsint count = 0;//link list and temp l
iststruct node_list*EntitiesList1,*Out_temp_list;
//selected entityand temp entitiesstruct node *ent
ity;//initializeEntitiesList1 =( structnode_list *
) calloc ( 1, sizeof ( struct node_list ));//set
a flag forthe boundary entitycount = 0;//check poi
nter about first entityif ( In_drawing->objects ==
0 ) return0;//set a open flagto the node//open_l
ist->car->flags = 1;//set the pointer to output no
de list//set pointer to first entityfor (entity=In
_drawing->objects; entity && (count<number_tr
immed_entities); 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_connec
ted_2 == 0 )continue; if ( entity->type !=
CK_LINE )continue;EntitiesList1->car= entity;brea
k;}//set link addressEntitiesList1->cdr = NULL;//-
--------------------------------//find connected e
ntitiesif ( EntitiesList1 == 0) return 0; if (
entity == 0 ) return 0; if ( entity->next == 0
)return EntitiesList1; for (entity=entity->nex
t; entity && (count<number_trimmed_entities);
entity=entity->next) {count++;if ( entity
== NULL )break; if ( entity->type != CK_L
INE )continue;if( entity->no_connected_1 > 0 && en
tity->no_connected_2 > 0 )continue;if( entity->no_
connected_1 == 0 && entity->no_connected_2 == 0 )c
ontinue;// allocate memory for output node list el
ementOut_temp_list = ( struct node_list * ) calloc
( 1, sizeof ( struct node_list ));// add this ent
ityto the output node list Out_temp_list->car = en
tity;// connect to the output node listOut_temp_li
st->cdr = EntitiesList1;// move the pointer ofoutp
ut node list to the topEntitiesList1 = Out_temp_li
st;if ( entity->next == NULL )break;} if (coun
t>=number_trimmed_entities) return 0;else return E
ntitiesList1;}/*==================================
===============================関数: 名称: F2dCl
eanUpPickUpAllArcEntity記述: 選択図の全てのアーク
エンティティを求める。戻り値:= 0: 成功裏に完了;パ
ラメータ:入力: In_drawing: 図出力:NodeList:全て
のアークエンティティに対するノードリスト==========
==================================================
====*/struct node_list *F2dCleanUpPickUpAllArcEnti
ty(struct drawing *In_drawing ){//entities counter
and flagsint count = 0;//link list and temp lists
truct node_list*EntitiesList1,*Out_temp_list; //se
lected entity and temp entitiesstruct node *entit
y;//initializeEntitiesList1 =( struct node_list *
) calloc ( 1, sizeof ( struct node_list ));//set
a flag for the boundary entitycount = 0;//check po
inter about first entityif ( In_drawing->objects =
= 0 ) return0;//set pointer to first entityfor (e
ntity=In_drawing->objects; entity && (count<n
umber_trimmed_entities); entity=entity->ne
xt) { if (entity == NULL )break; if
( entity->type != CK_ARC )continue;EntitiesList1->
car = entity;break;}//set link addressEntitiesList
1->cdr = NULL;//---------------------------------/
/find connected entitiesif ( EntitiesList1 == 0 )
return 0; if ( entity == 0 ) return 0; if (
entity->next == 0 ) return EntitiesList1; for
(entity=entity->next;entity && (count<number_trimm
ed_entities); entity=entity->next){count+
+;if ( entity == NULL )break; if ( entity->
type != CK_ARC)continue;// allocate memory for out
put node list elementOut_temp_list=( struct node_l
ist * ) calloc ( 1, sizeof ( struct node_list ));/
/ addthis entity to the output node list Out_temp_
list->car = entity;// connect to the output node l
istOut_temp_list->cdr = EntitiesList1;// move thep
ointer of output node list to the topEntitiesList1
= Out_temp_list;if( entity->next == NULL )break;}
if (count>=number_trimmed_entities)return 0;
else return EntitiesL
ist1;}/*==========================================
=======================関数: 名称: F2dCleanUpFin
dCenterLineEntity記述: アークのセンタラインエンテ
ィティを求める。 戻り値:= 0: 成功裏に完了し、何も
見出されない。= NUM: 開放エンティティの個数副関
数:int F2dCleanUpChangeChildrenFlag未使用エンティ
ティに対してフラグを設定する。doubleF2dDistancePoi
ntLineアークの中心点からエンティティまでの距離を計
算する。パラメータ:入力: 1 In_Drawing: a図2In_En
tities_list: 全てのアークに対するノードリスト=====
==================================================
=========*/int F2dCleanUpFindCenterLineEntity( str
uct drawing *In_drawing, struct node_list *In_Enti
ties_list ){//external functionsint F2dCleanUpChan
geChildrenFlag();doubleF2dDistancePointLine();doub
le F2dCleanUpLineLength();//link list and temp lis
tstruct node_list *temp_list, *temp_list2, *temp_l
ist3, *temp_list4; //selected entity and temp enti
tiesstruct node *ArcEntity,*ViewEntity;//define 3D
coordinates struct VectorVsp, Vep, Vp;//entities
counter and flagsintcount = 0;//doubledoubleDistan
ce = 0.0,DistanceViewEntity2Center = 0.0,DX = 0.0,
DY = 0.0,ViewEntityLength = 0.0,Tolerance = 0.0;in
t CountPrompt= 0;charmessage[64];//set toleranceTo
lerance = F2dCleanUpTolerance;#ifdef VELLUMCountPr
ompt++;sprintf( message,"Start Find Center Entity
%d", CountPrompt );ck_prompt( message ); #endif
// check all of entities which connected with ou
tside loop for( temp_list=In_Entities_list; te
mp_list; temp_list = temp_list->cdr){ if ( temp_l
ist->car == NULL )break;ArcEntity = temp_list->ca
r;//check all of entities in the viewfor( ViewEnti
ty=In_drawing->objects; ViewEntity; ViewEntity =
ViewEntity->next){//check flags: only no marks en
tities if ( ViewEntity->flags !=0 && ViewEntity->f
lags !=10 )continue;//check type : only line if (
ViewEntity->type != CK_LINE )continue;//check open
side: only open lineif ( ViewEntity->no_connected
_1 > 0 && ViewEntity->no_connected_2 > 0 )continu
e;//check open side: two side open line ( delete )
if ( ViewEntity->no_connected_1 == 0 && ViewEntity
->no_connected_2 == 0&& ViewEntity->line_type != C
K_CENTER ){ViewEntity->flags = 3;continue;}//check
parent open sideif ( ViewEntity->no_connected_1 =
= 0&& ViewEntity->line_type != CK_CENTER ){//set c
enter line flags ( look for children )for( temp_li
st2=ViewEntity->parent->children; temp_list2 && t
emp_list2->cdr; temp_list2 = temp_list2->cdr){//c
hange flag to light grayif ( temp_list2->car == NU
LL ) break;if ( temp_list2->car->vertex2 == ViewEn
tity->parent->vertex2 ) break;}if( temp_list2->car
->no_connected_2 != 0) continue;}if ( ViewEntity->
no_connected_2 == 0&& ViewEntity->line_type != CK_
CENTER ){//set center lineflags ( look for childre
n )for( temp_list3=ViewEntity->parent->children;
temp_list3 && temp_list3->cdr; temp_list3 = temp_
list3->cdr){//change flag to light grayif ( temp_l
ist3->car == NULL ) break;if ( temp_list3->car->ve
rtex1 == ViewEntity->parent->vertex1 ) break;}if
( temp_list3->car->no_connected_1 != 0) continue;}
//check distance from arc’s centerto line entityV
sp.x=ViewEntity->X1;Vsp.y=ViewEntity->Y1;Vsp.z=Vie
wEntity->Z1;Vep.x=ViewEntity->X2;Vep.y=ViewEntity-
>Y2;Vep.z=ViewEntity->Z2;Vp.x=ArcEntity->CenterX;V
p.y=ArcEntity->CenterY;Vp.z=ArcEntity->CenterZ;Dis
tance = F2dDistancePointLine( Vsp, Vep, Vp );if (
Distance > Tolerance )continue;//check bounding bo
x : only outside and no touchif (( ViewEntity->par
ent->Max_X >= ArcEntity->Min_X && ViewEntity->par
ent->Max_X <= ArcEntity->Max_X )&& ( ViewEntity->p
arent->Max_Y >= ArcEntity->Min_Y &&ViewEntity->p
arent->Max_Y <= ArcEntity->Max_Y )) {F2dCleanUpCha
ngeChildrenFlag( ViewEntity->parent );continue;}if
(( ViewEntity->parent->Min_X >= ArcEntity->Min_X
&& ViewEntity->parent->Min_X <= ArcEntity->Max_X
)&&( ViewEntity->parent->Min_Y >= ArcEntity->Min_
Y && ViewEntity->parent->Min_Y <= ArcEntity->Max
_Y )) {F2dCleanUpChangeChildrenFlag( ViewEntity->p
arent );continue;}if (( ArcEntity->Max_X >= ViewEn
tity->parent->Min_X&& ArcEntity->Max_X <= ViewEnti
ty->parent->Max_X )&& ( ArcEntity->Max_Y >= ViewEn
tity->parent->Min_Y && ArcEntity->Max_Y <= ViewE
ntity->parent->Max_Y )) {F2dCleanUpChangeChildrenF
lag( ViewEntity->parent );continue;}if (( ArcEntit
y->Min_X >= ViewEntity->parent->Min_X && ArcEntit
y->Min_X <= ViewEntity->parent->Max_X )&& ( ArcEnt
ity->Min_Y >= ViewEntity->parent->Min_Y && ArcEn
tity->Min_Y <= ViewEntity->parent->Max_Y )) {F2dCl
eanUpChangeChildrenFlag( ViewEntity->parent );cont
inue;}//check distance from arc to entityViewEntit
yLength = F2dCleanUpLineLength(ViewEntity->paren
t);DX = 0.5*(ViewEntity->parent->Min_X+ViewEntity-
>parent->Max_X) -ArcEntity->CenterX;DY = 0.5*(View
Entity->parent->Min_Y+ViewEntity->parent->Max_Y) -
ArcEntity->CenterY;DistanceViewEntity2Center = sq
rt(DX*DX+DY*DY) - ArcEntity->Radius - 0.5*ViewEnti
tyLength;if ( DistanceViewEntity2Center <= ViewEnt
ityLength ){F2dCleanUpChangeChildrenFlag( ViewEnti
ty->parent );continue;}//set center line flags ( l
ook for children )for( temp_list4=ViewEntity->pare
nt->children; temp_list4; temp_list4 = temp_list
4->cdr){//change flag to light grayif ( temp_list4
->car == NULL ) break;temp_list4->car->flags = 10;
count++;}if ( ViewEntity->next == NULL )break;}}#i
fdef VELLUMCountPrompt++;sprintf( message,"Finishe
d find centerEntity %d", CountPrompt );ck_prompt(
message ); #endif//normal endreturn count;}/*====
==================================================
===========関数: 名称: F2dCleanUpFindInSideEntit
y記述: アウトサイドループに対するインサイドエンテ
ィティを求める。戻り値:= 0: 成功裏に完了し、何も
見出されない;= NUM: 開放エンティティの個数副関数:i
nt F2dCleanUpChangeChildrenFlag未使用エンティティ
に対するフラグを設定する。パラメータ:入力:1 In_D
rawing: a図2 In_Entities_list: 外側ループに対する
ノードリスト======================================
==========================*/int F2dCleanUpFindInSi
deEntity( struct drawing *In_drawing, struct node_
list *In_Entities_list ){//external functionsint F
2dCleanUpChangeChildrenFlag();//link list and temp
liststruct node_list *temp_list, *temp_list2,*New
NodeList, *NewNodeListTemp; struct group *NewGrou
p,*temp_group_list; struct bounding_box *NewBound
Box;//selected entity and temp entitiesstruct node
*OutsideEntity,*ViewEntity;//entities counter and
flagsint count = 0,NoFlag = 0;//doubledoubleTolera
nce = 0.0;//set toleranceTolerance = F2dCleanUpTol
erance;//initializeNewGroup = (struct group *)call
oc(1,sizeof(struct group ));NewBoundBox = (struct
bounding_box *)calloc(1,sizeof(structbounding_box
));NewNodeList = (struct node_list *)calloc(1,siz
eof(struct node_list ));//set group dataNewGroup->
next = NULL;NewGroup->box = NewBoundBox;// check a
ll of entities which connected with outside loop
for( temp_list=In_Entities_list; temp_list; //&
& temp_list->cdr; temp_list = temp_list->cdr){if
( temp_list->car == NULL ) break;OutsideEntity= te
mp_list->car;//check entity : only boundary group
( flags = 1 and 4) if ( OutsideEntity->flags != 1
&& OutsideEntity->flags != 4 )continue;if ( !Outsi
deEntity ){NoFlag = 1;break;}NewGroup->box->Min_X
= OutsideEntity->Min_X;NewGroup->box->Max_X = Outs
ideEntity->Max_X;NewGroup->box->Min_Y = OutsideEnt
ity->Min_Y;NewGroup->box->Max_Y = OutsideEntity->M
ax_Y;break;}if ( NoFlag == 1 )return0; NewNodeL
ist->car = OutsideEntity;NewNodeList->cdr = NULL;/
/ check first groupif( In_drawing->views == NULL)
{NewGroup->index = 1;In_drawing->views = NewGrou
p;}else{//check groupnumber for( temp_group_lis
t= In_drawing->views; temp_group_list; //&&temp_g
roup_list->next; temp_group_list = temp_group_lis
t->next){if ( temp_group_list->next == NULL ){NewG
roup->index = (temp_group_list->index)+1;temp_grou
p_list->next = NewGroup;break;}}} // check conn
ected entity if ( !temp_list->cdr && temp_list-
>car->type != CK_ARC )return 0;// check all of ent
ities which connected with outside loop if ( te
mp_list->cdr ){ for( temp_list2 = temp_list->cd
r; temp_list2;// &&temp_list2->cdr; temp_list2 =
temp_list2->cdr){if ( temp_list2->car ==NULL ) br
eak;OutsideEntity = temp_list2->car;//check entity
: only boundary group ( flags = 1 and 4 ) if ( Ou
tsideEntity->flags != 1 && OutsideEntity->flags !=
4 )continue;if ( NewGroup->box->Min_X > OutsideEn
tity->Min_X )NewGroup->box->Min_X = OutsideEntity-
>Min_X;if ( NewGroup->box->Max_X < OutsideEntity->
Max_X )NewGroup->box->Max_X = OutsideEntity->Max_
X;if ( NewGroup->box->Min_Y > OutsideEntity->Min_Y
)NewGroup->box->Min_Y =OutsideEntity->Min_Y;if (
NewGroup->box->Max_Y < OutsideEntity->Max_Y )NewGr
oup->box->Max_Y = OutsideEntity->Max_Y;//allocate
memory for node list NewNodeListTemp = (struct nod
e_list *)calloc(1,sizeof(struct node_list ));//add
this entity to node list NewNodeListTemp->car = O
utsideEntity;//connect to the node list NewNodeLis
tTemp->cdr = NewNodeList;//move the pointer of the
node list to the topNewNodeList = NewNodeListTem
p;count++;}}//check all of entities in the viewfor
( ViewEntity=In_drawing->objects; ViewEntity; Vi
ewEntity = ViewEntity->next){//check flags: only n
o marks entities if ( ViewEntity == NULL )break;i
f ( ViewEntity->flags!=0 )continue;//check boundi
ng box: only inside entities if (( NewGroup->box->
Min_X <= ViewEntity->Min_X ) &&( NewGroup->box->M
ax_X >= ViewEntity->Max_X ) &&( NewGroup->box->Mi
n_Y <= ViewEntity->Min_Y ) &&( NewGroup->box->Max
_Y >= ViewEntity->Max_Y )){//set flag ViewEntity->
flags = 7;//allocate memory for node list NewNodeL
istTemp = (struct node_list *)calloc(1,sizeof(stru
ct node_list ));//add this entity to node list New
NodeListTemp->car = ViewEntity;//connect to the no
de list NewNodeListTemp->cdr = NewNodeList;//move
the pointer of the node list to the topNewNodeList
= NewNodeListTemp;count++;}}//set node list to gr
oup NewGroup->entities = NewNodeList;//normal endr
eturn count;}/*===================================
==============================関数: 名称: F2dCle
anUpFindOnesideOpenConnectEntityNext記述: 一側オ
ープンエンティティに接続された次のエンティティを求
める。戻り値:= Out_entity: 成功裏に完了;パラメー
タ:入力: 1 In_entity: エンティティ =============
==================================================
=*/struct node *F2dCleanUpFindOnesideOpenConnectEn
tityNext(struct node *In_entity){//selected entity
and temp entitiesstructnode *Out_entity;//link li
st and temp liststruct node_list *TempList1,*TempL
ist2, *TempList3, *NextNodes;//defineintFlag1 = 0,
Flag2 = 0,Count= 0;int CountPrompt = 0;charmessage
[64];#ifdef VELLUMCountPrompt++;sprintf( message,"
Start Find One Side Open Connected Entity %d", Cou
ntPrompt);ck_prompt( message ); #endif//initializ
eOut_entity = NULL;//check input entityif ( !In_en
tity )returnOut_entity;//check open sidefor( TempL
ist1=In_entity->connected_nodes_1; TempList1; //&&
TempList1->cdr; TempList1 = TempList1->cdr){if (
TempList1->car == NULL )break;if ( TempList1->car-
>flags == 6 )Flag1 = 1;}for( TempList2=In_entity->
connected_nodes_2;TempList2; //&& TempList2->cdr;
TempList2 = TempList2->cdr){if ( TempList2->car ==
NULL )break;if ( TempList2->car->flags == 6 )Flag
2 = 1;}//first entity caseif ( Flag1 == 0 && Flag2
== 0 ) {if ( In_entity->no_connected_1 == 0 )Fla
g1 = 1;if ( In_entity->no_connected_2 == 0 )Flag2
= 1;}//finish case: returnif (( Flag1 == 0 && Flag
2 == 0 ) ||( Flag1 == 1 && Flag2 == 1 ))returnOu
t_entity;//check all of entities connected with in
put entityif ( Flag1 == 1 )NextNodes = In_entity->
connected_nodes_2;elseNextNodes = In_entity->conne
cted_nodes_1;for( TempList3= NextNodes; TempList3;
//&& TempList3->cdr; TempList3 = TempList3->cdr)
{if ( TempList3->car == NULL )break;if ( TempList3
->car->flags == 0 ){Out_entity = TempList3->car;Co
unt++;}}//check resultif ( Count != 1 )Out_entity
= NULL;#ifdef VELLUMCountPrompt++;sprintf( messag
e,"Finished one side open connected Entity %d", Co
untPrompt );ck_prompt( message ); #endifreturnOut
_entity;}/*=======================================
==========================関数: 名称: F2dCleanUp
FindOnesideOpenConnectEntity記述: 一側オープンエ
ンティティおよびそれに接続された単一エンティティを
求める。。戻り値:=0: 成功裏に完了;副関数:struct
node *F2dCleanUpFindOnesideOpenConnectEntityNext一
側開放エンティティに接続された次のエンティティを求
める。パラメータ:入力: 1 In_drawing: 図 ========
==================================================
======*/int F2dCleanUpFindOnesideOpenConnectEntity
(struct drawing *In_drawing){//external functionss
truct node *F2dCleanUpFindOnesideOpenConnectEntity
Next();//selected entity and temp entitiesstruct n
ode *entity, *FindEntity, *NextEntity;//check all
of entities on the listfor( entity=In_drawing->obj
ects; entity; entity = entity->next){if (entity
== NULL )break; if ( entity->flags != 0 )continue;
if ( entity->type != CK_LINE )continue; if ( enti
ty->no_connected_1 > 0 && entity->no_connected_2 >
0 )continue;if ( entity->no_connected_1 == 0 && e
ntity->no_connected_2 == 0 )continue;if ((entity->
no_connected_1 == 0 && entity->no_connected_2 >=
1) ||(entity->no_connected_2 == 0 && entity->no_c
onnected_1 >= 1)) {//set flagentity->flags =6;Find
Entity = entity;//find connected entityfor (;;){Ne
xtEntity = F2dCleanUpFindOnesideOpenConnectEntityN
ext( FindEntity );if ( NextEntity == NULL )break;/
/set flagFindEntity= NextEntity;FindEntity->flags
=6;}}}return 0;}/*================================
=================================関数: 名称: F2d
CleanUpFindLongestEntity記述: 図に対して最も長い
エンティティを求める。戻り値:= Entity: 成功裏に
完了;= 0: エンティティ無し;パラメータ:入力: 1 I
n_drawing: 図 ====================================
============================*/struct node *F2dClea
nUpFindLongestEntity(struct drawing *In_drawing){/
/selected entity and temp entitiesstruct node *ent
ity, *LongestEntity;//definedoubleLongestLength =
0.0,ArcLength = 0.0;//check all of entitieson the
listfor( entity=In_drawing->objects; entity; ent
ity = entity->next){//only not usedif ( entity ==
NULL )break;if ( entity->flags != 0 )continue;//ch
eck lengthif ( entity->parent->length <= LongestLe
ngth )continue; //check arc lengthif ( entity->ty
pe == CK_ARC ){ArcLength = 2.0* entity->parent->Ra
dius;if ( entity->parent->length < ArcLength)ArcLe
ngth = entity->parent->length;if ( ArcLength > Lon
gestLength ){//change max value and entityLongestL
ength = ArcLength;LongestEntity = entity;}}else{//
change max value and entityLongestLength = entity-
>parent->length;LongestEntity = entity;}}if ( Long
estLength == 0.0 )returnNULL;elsereturnLongestEnti
ty;}/*============================================
=====================関数: 名称: F2dCleanUpFindV
iews記述: 図に対するビユーのグループを求める。戻
り値:= Entity: 成功裏に完了;= 0: エンティティな
し;副関数:struct node *F2dCleanUpFindLongestEntit
y図に対する最も長いエンティティを求める。struct no
de_list *F2dCleanUpFindGroup入力エンティティと接続
されたグループエンティティを求める。struct node *F
2dCleanUpFindGroupMinXエンティティグループに対する
最小X値を求める。int F2dCleanUpFindOutSideLoopエ
ンティティグループに対する最小X値を求める。int F2
dCleanUpFindInSideEntity外側ループパラメータに対す
るインサイドエンティティを求める。パラメータ:入
力: 1 In_drawing: 図 ============================
====================================*/int F2dClean
UpFindViews( struct drawing *In_drawing ){//extern
al functionsstruct node *F2dCleanUpFindLongestEnti
ty();struct node_list *F2dCleanUpFindGroup();struc
t node *F2dCleanUpFindGroupMinX();int F2dCleanUpFi
ndOutSideLoop();int F2dCleanUpFindInSideEntity();/
/selected entity and temp entitiesstruct node *Lon
gestEntity, *MinXvalueEntity;struct node_list *Vie
wGroup;//defineint ReturnFlag = 1,NoGroup= 0,Count
= 0;doubleLongestLength = 0.0;int CountPrompt =
0;charmessage[64];//check all viewswhile( ReturnFl
ag ){#ifdef VELLUMCountPrompt++;sprintf( message,"
Start Find Views Entity %d", CountPrompt );ck_prom
pt( message ); #endif//Step_1:find a longest enti
ty for a drawingLongestEntity= F2dCleanUpFindLonge
stEntity( In_drawing );if ( LongestEntity == NULL)
ReturnFlag = 0;else {//set flagNoGroup = 1; //cle
ar counterCount = 0;//Step_2:find connected group
with the longest entityViewGroup = F2dCleanUpFindG
roup( LongestEntity, &Count ); //Step_3:find outsi
de loop entities//check a flag for outside loop pr
ocessif ( Count > 1 )MinXvalueEntity =F2dCleanUpFi
ndGroupMinX( ViewGroup );elseMinXvalueEntity = Lon
gestEntity;if ( MinXvalueEntity == 0 )continue;//S
tep_4:find outside loop entitiesif ( Count > 1 )F2
dCleanUpFindOutSideLoop( MinXvalueEntity );elseMin
XvalueEntity->flags = 4;//Step_5:find inside entit
iesF2dCleanUpFindInSideEntity( In_drawing, ViewGro
up );}#ifdef VELLUMCountPrompt++;sprintf( messag
e,"Finished find view Entity %d", CountPrompt );ck
_prompt( message );#endif}if ( NoGroup == 0 )retur
n-1;elsereturn0;}/*===============================
==================================関数: 名称: F2
dCleanUpFindRelativeViews記述: 相対ビユーを求め
る。 戻り値:= 0: 成功裏に完了;= 1:相対ビユーが見
出される。パラメータ:入力: 1 In_Drawing: 図2 In_
Group:グループ3 In_ToleranceViews: ビユーに対する
公差==============================================
==================*/int F2dCleanUpFindRelativeView
s(struct drawing*In_drawing,struct group*In_Group,
double *In_ToleranceViews ) {//link list and temp
liststruct group *TempGroup;struct group_list*Temp
GroupList; //entities counter and flagsint ReturnF
lag = 0;//doubledoubleTolerance = 0.0;//set tolera
nceTolerance = *In_ToleranceViews;//check viewsif
( In_drawing->views == NULL )return0;if( In_Group
== NULL )return0;for( TempGroup= In_drawing->view
s; TempGroup; //&& TempGroup->next; TempGroup =
TempGroup->next){//check same groupif ( TempGroup
== NULL)break;if ( TempGroup == In_Group )continu
e;//Step_1:check top and bottom directionif ((Temp
Group->box->Max_X>=((In_Group->box->Max_X)-Toleran
ce )) &&(TempGroup->box->Max_X<=((In_Group->box-
>Max_X)+Tolerance )) &&(TempGroup->box->Min_X>=
((In_Group->box->Min_X)-Tolerance )) &&(TempGrou
p->box->Min_X<=((In_Group->box->Min_X)+Tolerance
))) {//set return flagReturnFlag = 1;//Step_1_1:c
heck top directionif ( TempGroup->box->Min_Y > In_
Group->box->Max_Y ){//check top directionrelative
viewsif ( In_Group->to_top == NULL ){TempGroupList
= (struct group_list *)calloc(1,sizeof(struct gro
up_list ));TempGroupList->car = TempGroup;TempGrou
pList->cdr = NULL;In_Group->to_top = TempGroupLis
t;}else{//check distanceif ( In_Group->to_top->car
->box->Min_Y > TempGroup->box->Min_Y ){//change to
p viewIn_Group->to_top->car = TempGroup;}}}else//S
tep_1_2:check bottom directionif ( TempGroup->box-
>Max_Y < In_Group->box->Min_Y ){//check top direct
ionrelative viewsif ( In_Group->to_bottom == NULL
){TempGroupList = (struct group_list *)calloc(1,s
izeof(struct group_list ));TempGroupList->car = Te
mpGroup;TempGroupList->cdr = NULL;In_Group->to_bot
tom = TempGroupList;}else{//check distanceif ( In_
Group->to_bottom->car->box->Max_Y < TempGroup->box
->Max_Y ){//change top viewIn_Group->to_bottom->ca
r = TempGroup;}}}}else//Step_2:check left and righ
t directionif ((TempGroup->box->Max_Y>=((In_Group-
>box->Max_Y)-Tolerance )) &&(TempGroup->box->Max
_Y<=((In_Group->box->Max_Y)+Tolerance )) &&(TempG
roup->box->Min_Y>=((In_Group->box->Min_Y)-Toleranc
e )) &&(TempGroup->box->Min_Y<=((In_Group->box->
Min_Y)+Tolerance ))) {//set return flagReturnFlag
= 1;//Step_2_1:check right directionif ( TempGroup
->box->Min_X > In_Group->box->Max_X ){//check righ
t direction relative viewsif ( In_Group->to_right
== NULL ){TempGroupList = (struct group_list *)cal
loc(1,sizeof(struct group_list ));TempGroupList->c
ar = TempGroup;TempGroupList->cdr = NULL;In_Group-
>to_right = TempGroupList;}else{//check distanceif
( In_Group->to_right->car->box->Min_X > TempGroup
->box->Min_X ){//change left viewIn_Group->to_righ
t->car = TempGroup;}}}else//Step_2_2:check left di
rectionif ( TempGroup->box->Max_X < In_Group->box-
>Min_X ){//check left directionrelative viewsif (
In_Group->to_left == NULL ){TempGroupList = (struc
t group_list *)calloc(1,sizeof(struct group_list
));TempGroupList->car = TempGroup;TempGroupList->
cdr = NULL;In_Group->to_left = TempGroupList;}else
{//check distanceif ( In_Group->to_left->car->box-
>Max_X < TempGroup->box->Max_X ){//change right vi
ewIn_Group->to_left->car = TempGroup;}}}}}//normal
endreturn ReturnFlag;}/*=========================
========================================関数: 名
称: F2dCleanUpFindViewsRelation記述: 図に対する
ビユー関係を求める。 戻り値:= 0: 成功裏に完了する
が、何も見出されない。;=NUM: ビユーの個数副関数:i
nt F2dCleanUpFindRelativeViews相対ビユーを求める。
パラメータ:入力: 1 In_Drawing: a図==============
==================================================
*/int F2dCleanUpFindViewsRelation( struct drawing*
In_drawing ) {//external functionsint F2dCleanUpFi
ndRelativeViews();//link list and temp liststruct
group *MaxGroup,*TempGroup,*NextGroup;struct group
_list*OpenGroupList,*TempOpenGroupList,*TempGroupL
ist;struct node_list *ETL;//Entity Temp List//enti
ties counter and flagsintNoFlag = 0;//doubledouble
BiggestSize = 0.0, BiggestSizeTemp = 0.0;doubleTol
erance = 0.0,ToleranceViews = 0.0;//set toleranceT
olerance = F2dCleanUpTolerance;//check viewsif( In
_drawing->views == NULL )return0;//Step_1:get the
biggest group’s sizefor( TempGroup= In_drawing->v
iews; TempGroup; //&& TempGroup->next; TempGroup
= TempGroup->next){// clear flagsTempGroup->index
= 0;// compute size for boxBiggestSizeTemp = fabs
( TempGroup->box->Max_X - TempGroup->box->Min_X )
+ fabs( TempGroup->box->Max_Y - TempGroup->box->
Min_Y );//check sizeif ( BiggestSizeTemp > Biggest
Size ){BiggestSize = BiggestSizeTemp;MaxGroup= Tem
pGroup;}//check last oneif ( TempGroup->next == NU
LL )break;}//check views toleranceToleranceViews =
0.01 * BiggestSize;if ( ToleranceViews < Toleranc
e ) ToleranceViews = Tolerance;//Step_2:find relat
ionship for each view//initialize a open list Open
GroupList = (struct group_list *)calloc(1,sizeof(s
truct group_list ));OpenGroupList->car = MaxGroup;
OpenGroupList->cdr = NULL;// seta open flag to the
groupMaxGroup->index = 1;for ( TempGroupList = Op
enGroupList; TempGroupList; ){//get a pointer from
open list if ( TempGroupList->car == NULL )break;
NextGroup = TempGroupList->car;//set a closed flag
to the groupNextGroup->index = 2;//close the grou
p ( delete the groupfrom open list )OpenGroupList
= OpenGroupList->cdr;//get relationNoFlag= F2dClea
nUpFindRelativeViews( In_drawing, NextGroup, &Tole
ranceViews );if ( NoFlag == 0 )break;//check each
direction for the viewif ( NextGroup->to_top != NU
LL ){if ( NextGroup->to_top->car->index == 0 ){Tem
pOpenGroupList = (struct group_list *)calloc(1,siz
eof(struct group_list ));TempOpenGroupList->car =
NextGroup->to_top->car;TempOpenGroupList->cdr = Op
enGroupList;TempOpenGroupList->car->index = 1;Open
GroupList = TempOpenGroupList;}}if ( NextGroup->to
_bottom != NULL ){if ( NextGroup->to_bottom->car->
index == 0 ){TempOpenGroupList = (struct group_lis
t *)calloc(1,sizeof(struct group_list ));TempOpenG
roupList->car = NextGroup->to_bottom->car;TempOpen
GroupList->cdr = OpenGroupList;TempOpenGroupList->
car->index= 1;OpenGroupList = TempOpenGroupList;}}
if ( NextGroup->to_left != NULL){if ( NextGroup->t
o_left->car->index == 0 ){TempOpenGroupList = (str
uct group_list *)calloc(1,sizeof(struct group_list
));TempOpenGroupList->car = NextGroup->to_left->c
ar;TempOpenGroupList->cdr = OpenGroupList;TempOpen
GroupList->car->index = 1;OpenGroupList = TempOpen
GroupList;}}if ( NextGroup->to_right != NULL ){if
( NextGroup->to_right->car->index == 0 ){TempOpenG
roupList = (struct group_list *)calloc(1,sizeof(st
ruct group_list ));TempOpenGroupList->car = NextGr
oup->to_right->car;TempOpenGroupList->cdr = OpenGr
oupList;TempOpenGroupList->car->index = 1;OpenGrou
pList= TempOpenGroupList;}}//assign value to the l
oop variableTempGroupList=OpenGroupList;}//Step_3:
clear flags for no relative groupsfor( NextGroup=I
n_drawing->views; NextGroup; NextGroup = NextGroup
->next){if ( NextGroup == NULL )break;if ( NextGro
up->index != 0 )continue;for ( ETL=NextGroup->enti
ties; ETL; ETL=ETL->cdr ) {ETL->car->flags = 0;if
( ETL->cdr == NULL )break;}}//normal endreturn
0;}/*=============================================
====================関数: 名称: F2dCleanUpFindDr
awingSheet記述: 図に対する描画シートを求める。戻
り値:= -1: エラーデータ;= 0: 成功裏に完了;= 1:
シートなし;副関数:struct node_list *F2dCleanUpFin
dGroup入力エンティティと接続されたグループエンティ
ティを求める。パラメータ:入力: 1 In_drawing: 図
==================================================
==============*/int F2dCleanUpFindDrawingSheet(str
uct drawing*In_drawing,struct bounding_box *InOut_
BB,int *In_TimesFlag ){//externalfunctionsstruct n
ode_list *F2dCleanUpFindGroup();//selected entity
andtemp entitiesstruct node *entity, *LongestEntit
yX, *LongestEntityY;struct node_list*SheetGroup, *
temp_list2; //bounding boxstruct bounding_box BB,
EBB;//defineintSheetFlag = 0, count = 0,CountPromp
t = 0;doubleLongestLengthX = 0.0,LongestLengthY =
0.0,AlphaX = 0.0, AlphaY = 0.0;charmessage[64]; do
ubleTolerance = 0.0;//set toleranceTolerance = F2d
CleanUpTolerance;#ifdef VELLUMCountPrompt++;sprint
f( message,"Start Find Sheet Entity%d", CountPromp
t );ck_prompt( message ); #endif//STEP_1:look for
the longest line type parent entity //check all o
f entities on the listfor( entity=In_drawing->obje
cts; entity; entity = entity->next){//only linet
ypeif ( entity == NULL )break;if ( entity->type !=
CK_LINE )continue;//only not usedif ( entity->fla
gs != 0 )continue;//check lengthif (( entity->pare
nt->length <= LongestLengthX ) &&( entity->parent
->length <= LongestLengthY ))continue; //check ho
rizontally and vertically //if angle(alpha) was sm
aller than ( sin ( alpha ) = alpha )AlphaX = fabs
( ( entity->parent->Max_X - entity->parent->Min_X
)/ entity->parent->length );AlphaY = fabs( ( enti
ty->parent->Max_Y - entity->parent->Min_Y )/ entit
y->parent->length );if ( ( AlphaX > Tolerance ) &&
( AlphaY > Tolerance ) )continue;//change max val
ue and entityif ( AlphaY < Tolerance ){ if ( entit
y->parent->length > LongestLengthX ){ LongestLeng
thX = entity->parent->length;LongestEntityX = enti
ty;}}else{ if ( entity->parent->length > LongestLe
ngthY ){ LongestLengthY = entity->parent->length;
LongestEntityY= entity;}} #ifdef VELLUM//CountProm
pt++;//sprintf( message,"Sheet Entity %d", CountPr
ompt );//ck_prompt( message ); #endif}//check the
longest entitiy’s lengthif (( LongestLengthX < T
olerance ) ||( LongestLengthY < Tolerance ))retur
n-1; //set bounding boxBB.Min_X = Lo
ngestEntityX->parent->Min_X;BB.Max_X = LongestEnti
tyX->parent->Max_X;BB.Min_Y = LongestEntityY->pare
nt->Min_Y;BB.Max_Y = LongestEntityY->parent->Max_
Y;//check inside drawing sheet sizeif ( *In_TimesF
lag == 1)*InOut_BB= BB; //set valueselse{if ( (In
Out_BB->Min_X ==0.0 ) && (InOut_BB->Max_X == 0.0 )
&&(InOut_BB->Min_Y == 0.0 ) && (InOut_BB->Max_Y =
= 0.0 )) return0;if (( BB.Max_X - BB.Min_X ) < Tol
erance )return0;if ( fabs(( InOut_BB->Max_X - InOu
t_BB->Min_X ) / ( BB.Max_X - BB.Min_X )) > 1.2 )re
turn0;}//set a flag to entityLongestEntityX->flags
= 3; //STEP_2:look for connected entities group a
nd make boundarySheetGroup = F2dCleanUpFindGroup(
LongestEntityX, &count);if ( SheetGroup == 0 )retu
rn0;//STEP_3:clear flagsfor all entitiesfor(entity
=In_drawing->objects; entity; entity = entity->n
ext){if ( entity == NULL )break;if ( entity->flags
== 3 )continue;if ( entity->flags ==4 )continue;e
ntity->flags = 0; }//STEP_4:set flags the groupfor
( temp_list2 = SheetGroup; ( temp_list2!=0 &&
temp_list2->car!=0 );temp_list2=temp_list2->cd
r){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:check
outside entity( out of the bounding box ) in the
DRAWING//if any entity wasfound, no sheet was foun
d for this drawingfor( entity=In_drawing->objects;
entity; entity = entity->next){if ( entity == N
ULL )break; if ( entity->flags != 0 )continue;//lo
ok for out side entity if ( entity->Max_X> EBB.Max
_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:lookfor sheet data ( out side of the boundary )i
f ( SheetFlag == 0 ){//lookfor sheet data for( ent
ity=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 )c
ontinue; entity->flags = 0; }if ( SheetFlag != 0 )
return 1;#ifdef VELLUMCountPrompt++;sprintf( messa
ge,"Finished find SheetEntity %d", CountPrompt );c
k_prompt( message ); #endifreturn 0;}/*==========
==================================================
=====関数: 名称: TestFindDrawingSheetControl 記
述: 手動関数。図に対する描画シートを求める。戻り
値:< 0: エラー= 0: プロセスなし> 0: 成功裏に完
了;個数は見出されたエンティティのカウンタ値であ
る。パラメータ:副関数:int F2dCleanUpFindDrawingS
heet成功裏に完了;個数は見出されたエンティティのカ
ウンタ値である。intF2dCleanUpChangeDrawingFlagエン
ティティのフラグを変更する( 4 >>3 )===============
=================================================*
/intTestFindDrawingSheetControl( int *SwitchRedraw
){//external functionsint F2dCleanUpFindDrawingSh
eet();int F2dCleanUpChangeDrawingColor();intF2dCle
anUpChangeDrawingFlag();//definestruct bounding_bo
x BB;intReturnFlag= 0; intTimesFlag = 0;//--------
--------------------------//Step_1:check the numbe
r of entites// if an error occurred, exit immidiat
ely. if (number_of_entities<0)return -1;//-----
----------------------------//Step_2: find center
line entitiesTimesFlag = 1;ReturnFlag = F2dCleanUp
FindDrawingSheet( &trim_drawing, &BB, &TimesFlag
);if( ReturnFlag == 1 ) return 0;if( ReturnFlag==
-1 ) return 0;TimesFlag = 2;F2dCleanUpFindDrawing
Sheet( &trim_drawing, &BB, &TimesFlag );//--------
-------------------------//Step_3: changeflagsF2dC
leanUpChangeDrawingFlag( &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_le
vels(CK_ON,TrimLevel, TrimLevel);//if ( *SwitchRed
raw == 1)ck_redraw( CK_PRIME_VP );#endifreturn0;}/
*=================================================
================関数: 名称: TestFindViewsControl
記述: 手動関数。 図に対する描画シートを求める。
戻り値:< 0: 図= 0: プロセスなし> 0: 成功裏に完了;
個数は見出されたエンティティのカウンタ値である。
パラメータ:副関数:int F2dCleanUpFindViews図に対
するビューのグループを求める。int F2dCleanUpFindVi
ewsRelation図に対するビュー関係を求める。int F2dCl
eanUpChangeDrawingColor===========================
=====================================*/intTestFind
ViewsControl( int *SwitchRedraw ){//external funct
ionsint F2dCleanUpFindViews();int F2dCleanUpFindVi
ewsRelation();int F2dCleanUpChangeDrawingColor();/
/Step_1:check the number of entites// if an error
occurred, exit immidiately. if (number_of_entit
ies<0) return -1;//Step_2: find views’ group if
( F2dCleanUpFindViews( &trim_drawing ) == -1 ) re
turn -1;//Step_3: find views’ relationship //move
to delete function ( Mar. 29,1996 )//F2dCleanUpFi
ndViewsRelation( &trim_drawing );//Step_X:change c
olorto light gray for a selected center lines /
/ turn off input levels#ifdef CKWINif ( *SwitchRed
raw == 1)ck_levels(CK_OFF,1,255);#endifif ( *Switc
hRedraw == 1)F2dCleanUpChangeDrawingColor(&trim_dr
awing);// turn ON the level used to store the trim
med entities.#ifdef CKWINif ( *SwitchRedraw == 1)c
k_levels(CK_ON,TrimLevel, TrimLevel);if ( *SwitchR
edraw == 1)ck_redraw( CK_PRIME_VP );#endifreturn
0;}/*=============================================
====================関数: 名称: TestFindBoundary
Control記述: 手動関数。 ユーザがビユーの境界のエ
ンティティを選択したとき、この関数はビユーに対する
接続されたエンティティの全てを見出す。戻り値:< 0:
エラー= 0: プロセスなし> 0: 成功裏に完了; 成功裏に
完了パラメータ:副関数:int F2dCleanUpFindOutSideL
oopサイドループのエンティティを求める。int F2dClea
nUpFindInSideEntity外側ループに対するサイドエンテ
ィティを求める。int F2dCleanUpFindOutNextEntity外
側ループエンティティと接続されたエンティティを求め
る。struct node *F2dCleanUpFindGroupMinXエンティテ
ィグループに対する最小X値を求める。struct node_li
st *F2dCleanUpFindGroup入力エンティティと接続され
たグループエンティティを求める。ystruct node *F2dC
leanUpInputEntity ( old function )画面上の選択され
たエンティティを求める。intF2dCleanUpLineAngleライ
ン形エンティティの角度を計算する。int F2dCleanUpAr
cAngleアーク形エンティティの角度を求める。int F2dC
leanUpChangeChildrenFlagエンティティのチルドレンフ
ラグを変更する。int F2dCleanUpChangeArrowVertexFla
gアロートップ頂点のフラグを変更し、アローセンタラ
イン座標を設定する。int F2dCleanUpFindViewsRelatio
nl図に対するビユー関係を求める。int F2dCleanUpChan
geColorエンティティの色を変更する。 double F2dClea
nUpLineLengthライン形エンティティの長さを計算す
る。==============================================
==================*/intTestFindBoundaryControl( in
t *SwitchRedraw ){//external functions
int F2dCleanUpChangeDrawingCol
or();int F2dCleanUpFindOutSideLoop();int F2dCleanU
pFindInSideEntity();int F2dCleanUpFindViewsRelatio
n();struct node *F2dCleanUpInputEntity();struct no
de *F2dCleanUpFindGroupMinX();struct node_list *F2
dCleanUpFindGroup();//entities counter and flagsin
t count = 0;//link list and temp liststruct node_l
ist *Entities_list; //selected entity and temp ent
itiesstruct node *entity,*MinXvalueEntity;//Begin
//----------------------------------//Step_1://che
ck the number of entites// get count of all entit
ies// if an error occurred, exit immidiately. i
f (number_of_entities<0) return -1;for( ; ; ){//-
--------------------------------//Step_2:select on
e entityentity = F2dCleanUpInputEntity( "Select aB
oundary Entity for a view",&trim_drawing);if ( ent
ity == 0 )return0;if( entity->flags != 0 )continu
e;//---------------------------------//Step_3: fin
d a connected entities groupEntities_list = F2dCle
anUpFindGroup(entity, &count );//-----------------
----------------//Step_4:find outside loop entitie
s without assistant entities//check a flag for out
side loop processif ( count < 1 )continue;MinXvalu
eEntity = F2dCleanUpFindGroupMinX( Entities_list);
if ( MinXvalueEntity == 0 )continue;//------------
---------------------//Step_5:find outside loop en
titiesF2dCleanUpFindOutSideLoop( MinXvalueEntity
);//---------------------------------//Step_6:fin
d inside entitiesF2dCleanUpFindInSideEntity( &trim
_drawing, Entities_list );//----------------------
-----------//Step_7: find views’ relationship //m
ove delete function (Mar.29, 1996 By Ji )//F2dClea
nUpFindViewsRelation( &trim_drawing );//----------
-----------------------//Step_X:change color to Ma
genta for a selected boundary // turn off input
levels#ifdef CKWINif ( *SwitchRedraw == 1)ck_leve
ls(CK_OFF,1,255);#endifF2dCleanUpChangeDrawingColo
r(&trim_drawing);// turn ON the level used to stor
ethe trimmed entities.#ifdef CKWINif ( *SwitchRedr
aw == 1)ck_levels(CK_ON,TrimLevel, TrimLevel);if
( *SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );#end
if}return count;}/*===============================
==================================関数: 名称: Te
stFindCenterLineControl記述: 手動関数。ビユー中の
全てのアークに対するセンタラインを見出す。戻り値:
< 0: エラー= 0: プロセスなし> 0: 成功理に完了; 成
功理に完了パラメータ:副関数:struct node_list *F2
dCleanUpPickUpAllArcEntity選択された図中の全てのア
ークエンティティを求める。int F2dCleanUpChangeDraw
ingColorエンティティの色を変更する。==============
==================================================
*/intTestFindCenterLineControl( int *SwitchRedraw
){//external functionsint F2dCleanUpFindCenterLin
eEntity();int F2dCleanUpChangeDrawingColor();struc
t node_list *F2dCleanUpPickUpAllArcEntity();//link
list and templiststruct node_list*Entities_list;
//Begin//----------------------------------//Step_
1:check the number of entites// if an error occurr
ed, exitimmidiately. if (number_of_entities<0)
return -1;//---------------------------------//S
tep_2: pickup all arc entitiesEntities_list = F2dC
leanUpPickUpAllArcEntity( &trim_drawing ); if
(Entities_list == 0) return 0;//-----------------
----------------//Step_3: find center line entitie
sF2dCleanUpFindCenterLineEntity( &trim_drawing, En
tities_list );//---------------------------------/
/Step_X:change color to light gray for aselected c
enter lines // turn off input levels#ifdef CKWI
Nif ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#
endifif ( *SwitchRedraw == 1)F2dCleanUpChangeDrawi
ngColor(&trim_drawing);// turn ON the level used t
o store the trimmed entities.#ifdef CKWINif ( *Swi
tchRedraw == 1)ck_levels(CK_ON,TrimLevel, TrimLeve
l);if ( *SwitchRedraw == 1)ck_redraw( CK_PRIME_V
P);#endifreturn 0;}/*=============================
====================================関数: 名称:
TestFindOneSideOpenConnectControl 記述: 手動関
数。 一側オープン接続エンティティを見出す。戻り
値:< 0: エラー= 0: プロセスなし> 0: 成功裏に完了;
数は見出されたエンティティのカウンタ値である。パ
ラメータ:副関数:int F2dCleanUpFindOnesideOpenCon
nectEntity一側開放接続エンティティを求める。======
==================================================
========*/intTestFindOneSideOpenConnectControl( in
t *SwitchRedraw ){//external functionsint F2dClean
UpFindOnesideOpenConnectEntity();int F2dCleanUpCha
ngeDrawingColor();//------------------------------
----//Step_1:check the number of entites// if an e
rror occurred, exit immidiately. if (number_of_
entities<0) return -1;//-------------------------
--------//Step_2: find center line entitiesF2dClea
nUpFindOnesideOpenConnectEntity( &trim_drawing );/
/---------------------------------//Step_X:change
color to light gray for a selected center lines
// turn off input levels#ifdef CKWINif ( *Switch
Redraw == 1)ck_levels(CK_OFF,1,255);#endifif ( *Sw
itchRedraw == 1)F2dCleanUpChangeDrawingColor(&trim
_drawing);// turn ON the level used to store the t
rimmed entities.#ifdef CKWINif( *SwitchRedraw ==
1)ck_levels(CK_ON,TrimLevel, TrimLevel);if ( *Swit
chRedraw == 1)ck_redraw( CK_PRIME_VP );#endifretur
n 0;}/*===========================================
======================関数: 名称: TestFindSameCo
lorControl記述: 手動関数。同じ色のエンティティを
見出す。戻り値:= 0:成功裏に完了;数は見出されたエ
ンティティのカウンタ値である。パラメータ:副関数:
struct node *F2dCleanUpInputEntity ( old function
)画面上の選択されたエンティティを求める。int F2dC
leanUpFindSameColorEntity選択されたエンティティに
より同じ色のエンティティを求める。int F2dCleanUpCh
angeDrawingColorエンティティの色を変更する。======
==================================================
========*/intTestFindSameColorControl(){//external
functionsint F2dCleanUpChangeDrawingColor();int F2
dCleanUpFindSameColorEntity();struct node *F2dClea
nUpInputEntity();//selected entity and tempentitie
sstruct node*entity;//Begin//---------------------
-------------//Step_1://check the number of entite
s// if an error occurred, exit immidiately. if
(number_of_entities<0) return -1;for( ; ; ){//---
------------------------------//Step_2:select one
entityentity = F2dCleanUpInputEntity( "Select a Un
use Color Entity",&trim_drawing);if ( entity == 0
)return0;if ( entity->flags != 0 )continue;//----
-----------------------------//Step_3: find a conn
ected entities groupF2dCleanUpFindSameColorEntity
( entity, &trim_drawing );//----------------------
-----------//Step_X:change color to Magenta for a
selected boundary // turn off input levels#ifde
f CKWIN ck_levels(CK_OFF,1,255);#endifF2dCleanU
pChangeDrawingColor(&trim_drawing);// turn ON the
level used to store the trimmed entities.#ifdef CK
WIN ck_levels(CK_ON,TrimLevel, TrimLevel);if (
*SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );#endi
f}return 0;}/*====================================
=============================関数: 名称: TestFin
dSelectSingleControl記述: 手動関数。使用エンティ
ティを見出す。戻り値:= 0:成功裏に完了; パラメー
タ:副関数:struct node *F2dCleanUpInputEntity (古
い関数 )画面上の選択されたエンティティを求める。==
==================================================
============*/intTestFindSelectSingleControl(){//e
xternal functionsstruct node *F2dCleanUpInputEntit
y();//selectedentity and temp entitiesstruct node*
entity;//entity’s specifitysCK_ENTATTattr;//speci
ficity of entities//Begin//-----------------------
-----------//Step_1:check the number of entites//
if an error occurred, exit immidiately. if (num
ber_of_entities<0) return -1;for( ; ; ){//-------
--------------------------//Step_2:select one enti
tyentity = F2dCleanUpInputEntity( "Select an Unuse
Entity", &trim_drawing);if ( entity == 0 )return
0;//---------------------------------//Step_3: cha
nge flagif ( entity->flags == 7 ){entity->flags =
0;attr.color = CK_BLUE; }elseif ( entity
->flags == 0 ){entity->flags = 7;attr.color =
CK_YELLOW;}elsereturn0;//------------------------
---------//Step_X:change color tolight gray for un
use entity // turn off input levels// ck_lev
els(CK_OFF,1,255);ck_setattr( entity->id, CK_COLO
R, NULL, &attr );// turn ONthe level used to store
the trimmed entities.// ck_levels(CK_ON,TrimLe
vel, TrimLevel);ck_redraw( CK_PRIME_VP );}return
0;}/*=============================================
====================関数: 名称: TestUnselectSing
leControl記述: 手動関数。使用エンティティをクリア
する。戻り値:=0: 成功裏に完了;パラメータ:副関
数:struct node *F2dCleanUpInputEntity(old functio
n )画面上の選択されたエンティティを求める。=======
==================================================
=======*/intTestUnselectSingleControl(){//external
functionsstruct node *F2dCleanUpInputEntity();//s
elected entity and temp entitiesstruct node*entit
y;//entity’s specifitysCK_ENTATTattr;//specificit
y of entities//Begin//----------------------------
------//Step_1:check the number of entites// if an
error occurred, exitimmidiately. if (number_of
_entities<0) return -1;for( ; ; ){//-------------
--------------------//Step_2:select one entityenti
ty = F2dCleanUpInputEntity( "Select an Entity to r
elease",&trim_drawing);if ( entity == 0 )return0;/
/---------------------------------//Step_3: change
flagif( entity->flags != 3&& entity->flags != 4 &
& entity->flags != 10 ) continue;entity->flags =
0;//---------------------------------//Step_X:chan
gecolor to light gray for unuse entity // turn
off input levels ck_levels(CK_OFF,1,255);attr.c
olor = entity->color;ck_setattr( entity->id,CK_COL
OR, NULL, &attr );// turn ON the level used to sto
re the trimmedentities. ck_levels(CK_ON,TrimLev
el, TrimLevel);ck_redraw( CK_PRIME_VP);}return 0;}
/*================================================
=================関数: 名称: TestClearKeepFlagsC
ontrol記述: 手動関数。全ての選択されたエンティテ
ィを戻す。戻り値:= 0: 成功裏に完了;パラメータ:副
関数:int F2dCleanUpClearDrawingKeepFlagsエンティ
ティの色を元に変更するが、フラグは維持する。======
==================================================
========*/intTestClearKeepFlagsControl( int *Switc
hRedraw ){//external functionsint F2dCleanUpClearD
rawingKeepFlags();//Begin//-----------------------
-----------//check the number of entites// if an e
rror occurred, exit immidiately. if (number_of_
entities<0) return -1;//-------------------------
-------- // turn off input levels#ifdef CKWINif
( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#end
ifF2dCleanUpClearDrawingKeepFlags(&trim_drawing);i
f ( *SwitchRedraw == 1)ck_redraw( CK_PRIME_VP );//
turn ON the level used tostore the trimmed entiti
es.#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels(C
K_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw ==
1)ck_redraw( CK_PRIME_VP );#endifreturn0;}/*======
==================================================
=========関数: 名称: TestClearControl記述: 手動
関数。全ての選択されたエンティティを元に戻す。戻り
値:= 0: 成功裏に完了;パラメータ:副関数:int F2dC
leanUpClearDrawingEntityエンティティの色を元に戻
す。==============================================
==================*/intTestClearControl( int *Swit
chRedraw ){//external functionsint F2dCleanUpClear
DrawingEntity();//Begin//-------------------------
---------//check the number of entites// if an err
or occurred, exit immidiately. if (number_of_en
tities<0) return -1;//---------------------------
------ // turn off input levels#ifdef CKWINif
( *SwitchRedraw == 1)ck_levels(CK_OFF,1,255);#endi
fF2dCleanUpClearDrawingEntity(&trim_drawing);// tu
rn ON the levelused to store the trimmed entities.
#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels(CK_O
N,TrimLevel, TrimLevel);if ( *SwitchRedraw == 1)ck
_redraw(CK_PRIME_VP );#endifreturn0;}/*===========
==================================================
====関数: 名称: TestDeleteControl記述: 手動関
数。全ての選択されたエンティティを削除する。戻り
値:= 0: Completed successfully;パラメータ:副関
数:int F2dCleanUpDeleteDrawingEntity全てエンティ
ティを削除する。==================================
==============================*/intTestDeleteContr
ol( int *SwitchRedraw ){//external functionsint F2
dCleanUpDeleteDrawingEntity();//Begin//-----------
-----------------------//check the number of entit
es// if an error occurred, exit immidiately. if
(number_of_entities<0) return -1; //Step_
7: find views’ relationship //move from find boun
dary function (Mar.29, 1996 By Ji)F2dCleanUpFindVi
ewsRelation( &trim_drawing );//-------------------
--------------#ifdef CKWIN
if ( *SwitchRedraw == 1)ck_levels
(CK_OFF,1,255);#endif// turn ON the level used tos
tore the trimmed entities.F2dCleanUpDeleteDrawingE
ntity(&trim_drawing);#ifdef VELLUMif ( *SwitchRedr
aw == 1)F2dCleanUpChangeDrawingColor(&trim_drawin
g);#endif#ifdef CKWINif ( *SwitchRedraw == 1)ck_le
vels(CK_ON,TrimLevel, TrimLevel);if ( *SwitchRedra
w == 1)ck_redraw( CK_PRIME_VP );#endifreturn0;}/*=
==================================================
==============関数: 名称: TestBackColorControl記
述: 元に戻す。戻り値:= 0: 成功裏に完了;パラメー
タ:副関数:int F2dCleanUpUndo元に戻す。==========
==================================================
====*/intTestBackColorControl( int *SwitchRedraw )
{//external functionsint F2dCleanUpChangeDrawingCo
lor();if( *SwitchRedraw == 1)F2dCleanUpChangeDrawi
ngColor(&trim_drawing);return0;}/*================
=================================================
関数: 名称: TestUndoControl記述: 元に戻す。戻り
値:= 0: 成功裏に完了;パラメータ:副関数:int F2dC
leanUpUndo元に戻す。==============================
==================================*/intTestUndoCon
trol( int *SwitchRedraw ){//external functionsint
F2dCleanUpUndo();//check the number of entites :
if an error occurred, exit immidiately. if (num
ber_of_entities<0) return -1;//Step_1: get flags
if ( F2dCleanUpUndo( &trim_drawing) == 0 ) return
0;#ifdef CKWIN
if ( *SwitchRedraw == 1)ck_levels(CK_OFF,1,25
5);#endif// turn ON the level used to store the tr
immed entities.#ifdef VELLUMif ( *SwitchRedraw ==
1)F2dCleanUpChangeDrawingColor(&trim_drawing);#end
if#ifdef CKWINif ( *SwitchRedraw == 1)ck_levels(CK
_ON,TrimLevel, TrimLevel);if ( *SwitchRedraw== 1)c
k_redraw( CK_PRIME_VP );#endifreturn0;}/*=========
==================================================
======関数: 名称: TestUndoPreControl記述: 元に
戻す準備をする。戻り値:= 0: 成功裏に完了; パラメ
ータ:副関数:int F2dCleanUpUndoPre元に戻す準備を
する。============================================
====================*/intTestUndoPreControl( int *
SwitchRedraw ){//external functionsint F2dCleanUpU
ndoPre();//check the numberof entites: if an error
occurred, exit immidiately. if (number_of_enti
ties<0) return -1;//Step_1: get flags F2dCleanUpU
ndoPre( &trim_drawing );return0;}/*===============
==================================================
関数: 名称: TestSetUndoFlagViewsControl記述: 元
に戻すためフラグを設定する。flag=0:ビューが存在し
ない。flag=1: ビューが存在する。戻り値:= 0: 成功
裏に完了; パラメータ:============================
====================================*/intTestSetUn
doFlagViewsControl( int *SwitchRedraw ){ //set
flag F2dCleanUpExcutedNo = 1; return0;}/*関
数:==============================================
==================名称:TestDeleteViewsControl記
述: ビユーを削除する。戻り値:= 0: 成功裏に完了;
パラメータ:副関数:int F2dCleanUpDeleteViewsビユ
ーを削除する。====================================
============================*/intTestDeleteViewsCo
ntrol( int *SwitchRedraw ){//external functionsint
F2dCleanUpDeleteViews();//check the number of ent
ites: if an error occurred, exit immidiately. i
f (number_of_entities<0) return -1;//delete views
F2dCleanUpDeleteViews( &trim_drawing );return0;}s
truct node *F2dCleanUpInputEntity(char *prompt, s
truct drawing *select_drawing){int etype, count, s
tat;unsigned long entid;struct node *entity;//CK_
ENTATT attr;if (( ck_getent(prompt, &etype, &enti
d) != CK_NOERROR) || ( stat == CK_BACKUP ) || (sta
t == CK_ESCAPE )) return 0;#ifdef DEBUGprint("ID:
%ld; #",entid);#endifcount=0; for (entity=selec
t_drawing->objects; entity && (count<numb
er_trimmed_entities) && (entity->id !=entid) && (e
ntity->highlighted_id !=entid); entity=en
tity->next) count++;if (count>=number_
trimmed_entities) return 0;else return entity;}/*=
==================================================
==============関数: 名称: F2dVector記述: ライン
のユニットベクトルを計算する。戻り値:= Out_v: 成
功裏に完了;パラメータ:入力: 1 In_sp: ラインエン
ティティ開始点座標2 In_ep: インエンティティ終了点
座標出力:1Out_v: ラインエンティティベクトル======
==================================================
========*/struct Vector F2dVector( struct Vector I
n_sp, struct Vector In_ep ){struct VectorOut_v;Out
_v.x = In_ep.x - In_sp.x;Out_v.y = In_ep.y - In_s
p.y;Out_v.z = In_ep.z - In_sp.z;returnOut_v;}/*===
==================================================
============関数: 名称: F2dVectorUnit記述: ライ
ンのユニットベクトルを計算する。戻り値:= Out_n:
成功裏に完了;< 0: エラーパラメータ:入力: 1 In_v:
ラインエンティティベクトル 出力:1 Out_n: ライン
エンティティユニットベクトル======================
===========================================*/struc
t VectorF2dVectorUnit(struct VectorIn_v){struct Ve
ctorOut_n;doubleLength = 0.0;//tolerancedoubletole
rance = 0.0;tolerance = F2dCleanUpTolerance;Length
= sqrt( In_v.x*In_v.x + In_v.y*In_v.y + In_v.z*In
_v.z );//check lengthif (Length < tolerance )retur
nOut_n;Out_n.x = In_v.x / Length;Out_n.y = In_v.y
/ Length;Out_n.z = In_v.z / Length;returnOut_n;}/*
==================================================
===============関数: 名称: F2dDistancePointLine
記述: 点からラインまでの距離を計算する。戻り値:=
0: 成功裏に完了;パラメータ:入力: 1 In_sp: ライ
ンエンティティ開始点座標2 In_ep: ラインエンティテ
ィ終了点座標3 In_p: 点座標出力:1 Out_d: 距離 ===
==================================================
===========*/doubleF2dDistancePointLine(//inputstr
uct Vector In_sp, struct Vector In_ep, struct Vect
or In_p ){//external functionsstruct Vector F2dVec
tor();struct Vector F2dVectorUnit();//definestruct
VectorVe, Vne, Vp;double Out_d=0.0;//get vectorVe
= F2dVector( In_sp, In_ep );Vp = F2dVector( In_s
p, In_p );//get unitvectorVne = F2dVectorUnit( Ve
);//compute distanceOut_d = sqrt( Vp.x*Vp.x + V
p.y*Vp.y-(Vp.x*Vne.x + Vp.y*Vne.y) * (Vp.x*Vne.x +
Vp.y*Vne.y) );return Out_d;} 付録E ベンドモデルビユワ実施の例; CBendCADViewPartメンバ
関数の実施およびメニュー駆動関数の実施を含む。
【0378】//#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 }};vo
id PrintString(char *s){}// Thisfunction initializ
es the RenderWare library, creates a scene, camera
andlight.int CBendCADViewPart::Init3D(HWND windo
w) {BOOL berr = FALSE;// Open the RenderWare libra
ry. if (!RwOpen("MSWindows", NULL)) {::Messa
geBox(window, "Could not open th
e RenderWare library", WINDOWTIT
LE, MB_OK | MB_ICONSTOP | MB_APPLMODAL); re
turn 0; }// Create a camera.RwInt32 x_size, y_s
ize;x_size = GetSystemMetrics(SM_CXFULLSCREEN); //
The camera should be ableto displayy_size = GetSy
stemMetrics(SM_CYFULLSCREEN); // on the maximumsiz
e allowed by the screen. m_camera = RwCreateCam
era(x_size, y_size, NULL);if( ! m_camera) { ::M
essageBox(window, "Could not create camera",
WINDOWTITLE, MB_OK | MB_ICONSTOP | M
B_APPLMODAL); return 0;}else { RwSetCameraProj
ection(m_camera, rwPARALLEL); RwWCMoveCamera(m_c
amera, 0.0f, 0.0f, 10000.0f); // Move camera far a
way from xy plane. RwSetCameraViewport(m_camera,
0, 0, x_size, y_size); // Default sizes of viewing
volume RwSetCameraViewwindow(m_camera, (floa
t)(x_size), (float)(y_size)); // and viewport.}//
Create a scene. m_scene = RwCreateScene(); i
f (m_scene == NULL) { RwDestroyCamera(m_
camera); m_camera = NULL; RwClose();
::MessageBox(window, "Could not create the
3D Scene", WINDOWTITLE, MB_OK |
MB_ICONSTOP | MB_APPLMODAL); return 0;
}// Createlights.m_lights.RemoveAll();RwLight* l
ight1 = RwCreateLight(rwDIRECTIONAL, 0.7f, -0.7f,
-0.7f, 0.8f); //- good cornerRwLight* light2 = RwC
reateLight(rwDIRECTIONAL, -1.0f, 1.0f, -1.0f, 0.25
f);RwLight* light3 = RwCreateLight(rwPOINT, CREAL
(0.0), CREAL(0.0), CREAL(0.0), CREAL(1.0));if(ligh
t1) {m_lights.Add(light1);RwAddLightToScene(m_sce
ne, light1);}elseberr= TRUE;if(light2) {m_lights.
Add(light2);RwAddLightToScene(m_scene, light2);}el
seberr = TRUE;if(light3) {m_lights.Add(light3);Rw
AddLightToScene(m_scene, light3);}elseberr = TRUE;
if (berr) AfxMessageBox("Could not create light so
urce");//RwSetLightState(m_light, rwON);//RwSetLig
htColor(m_light, CREAL(1.0), CREAL(1.0), CREAL(1.
0));return 1;}// This function is used by the docu
ment class to initialize certain // parameters whe
never a new part is loaded. What we do here is com
pute the centroid,// prepare RenderWare clumps and
show the part as requested - wireframe/shaded if
show_solid is 0/1,// flat/3d version of part if sh
ow_3d is 0/1.void CBendCADViewPart::new_part_init
(int show_solid, int show_3d){ int i; BM_PART *p
art = NULL; CBendCADDoc* pDoc = GetDocument(); A
SSERT_VALID(pDoc); part = pDoc->get_part(); if(!
part) { mi_part_is_up_to_date = 0; return; }
mi_part_is_up_to_date = 1; compute_part_centroi
d(part, 0, &m_flat_part_centroid); // Compute 3d a
nd flat part centroids. compute_part_centroid(par
t, 1, &m_3d_part_centroid); m_part_centroid = m_
3d_part_centroid; mi_show_3d = show_3d;
mi_show_solid = show_solid; // Cle
ar out any RenderWare clumps around. if(m_flat_ba
se_clump) { RwRemoveClumpFromScene(m_flat_base_
clump); RwDestroyClump(m_flat_base_clump); m
_flat_base_clump = NULL; } if(m_3d_base_clump)
{ RwRemoveClumpFromScene(m_3d_base_clump); R
wDestroyClump(m_3d_base_clump); m_3d_base_clump
= NULL; } m_base_clump = NULL;if(mi_show_3d)
{ // Prepare 3d solid or 3d wireframe. m_pa
rt_centroid = m_3d_part_centroid; if(! mi_show_so
lid) { // Prepare wireframe. i = prepare_d
isplay_list(part, mi_show_3d, 1, 0, 1, 1, md_face_
color, md_bendline_color); if(! i) { m
i_display_list_is_up_to_date = 0; return;
} mi_display_list_is_up_to_date = 1;mi_3d_i
s_up_to_date = 1; mi_flat_is_up_to_date = 0; }
else {// Prepare solid. i = facet_part_rw(p
art, &m_3d_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_3d_base_clump) ) return;
m_base_clump = m_3d_base_clump; RwAddClumpToSce
ne(m_scene, m_base_clump); mi_display_list_is
_up_to_date = 0; mi_3d_is_up_to_date = 0;
mi_flat_is_up_to_date = 0; } } else {
// Prepare flat solid or flat wireframe. m
_part_centroid = m_flat_part_centroid; if(! mi_s
how_solid) { // Prepare wireframe. i = pre
pare_display_list(part, mi_show_3d, 1, 0, 1, 1, md
_face_color, md_bendline_color); if(! i) {
mi_display_list_is_up_to_date = 0; retu
rn; } mi_display_list_is_up_to_date = 1;
mi_flat_is_up_to_date = 1; mi_3d_is_up_
to_date = 0; } else { // Preparesolid.
i = facet_part_rw(part, &m_flat_base_clump, mi
_show_3d, md_part_color); if( (! i) || (! m_fla
t_base_clump) ) return; m_base_clump = m_flat_b
ase_clump; RwAddClumpToScene(m_scene, m_base_cl
ump);mi_display_list_is_up_to_date = 0; mi_3d
_is_up_to_date = 0;mi_flat_is_up_to_date = 0; }
} mi_bbox_is_up_to_date = 0; ml_num_faces
= part->get_number_of_faces(); ml_num_bendlines
= part->get_number_of_bendlines(); ml_num_forming
s = part->get_number_of_formings();clear_selection
_set(); reset_selection_buffer(); OnViewIsometri
c();}//This function destroys all parent clumps in
the scene, and hence all clumps in the scene.// I
t always returns NULL.static RwClump * RWCALLBACKc
lear_scene(RwClump *clump){ int i = RwGetClumpNum
Children(clump); if(i) RwDestroyClump(clump);
return NULL;} // This allows other classes to s
ignal that the part has changed, and hence// curre
nt clumps/display lists are no longer valid. We re
compute centroids, prepare new clumps// or display
lists, and show the part in its current orientati
on and zoom.void CBendCADViewPart::invalidate_disp
lay(void) { int i; BM_PART *part = NULL; CBendC
ADDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);
part = pDoc->get_part(); if(! part) { mi_par
t_is_up_to_date = 0; return; } mi_part_is_up_to
_date = 1; compute_part_centroid(part, 0, &m_flat
_part_centroid); // Compute 3d and flat part centr
oids. compute_part_centroid(part, 1, &m_3d_part_c
entroid); mi_3d_is_up_to_date = 0; mi_flat_is_
up_to_date = 0; // Clear out any RenderWare clump
s around. if(m_flat_base_clump) { RwRemoveClum
pFromScene(m_flat_base_clump); RwDestroyClump(m
_flat_base_clump); m_flat_base_clump = NULL; }
if(m_3d_base_clump) { RwRemoveClumpFromScene
(m_3d_base_clump); RwDestroyClump(m_3d_base_clu
mp); m_3d_base_clump = NULL; } m_base_clump =
NULL; if(mi_show_3d) { // Prepare 3d solid o
r 3d wireframe. m_part_centroid = m_3d_part_cen
troid; if(! mi_show_solid) { // Prepare wirefra
me. i = prepare_display_list(part, mi_show_3
d, 1, 0, 1, 1, md_face_color, md_bendline_color);
if(! i) { mi_display_list_is_up_to_da
te = 0; return; } mi_display_list_i
s_up_to_date =1; mi_3d_is_up_to_date = 1;
mi_flat_is_up_to_date = 0; } else{ // Pr
epare solid. i = facet_part_rw(part, &m_3d_ba
se_clump, mi_show_3d, md_part_color); if( (! i)
|| (! m_3d_base_clump) ) return; m_base_clump
= m_3d_base_clump; RwAddClumpToScene(m_scene, m
_base_clump); } } else { // Prepa
re flat solid or flatwireframe. m_part_centroid
= m_flat_part_centroid; if(! mi_show_solid) {
// Prepare wireframe. i = prepare_display_l
ist(part, mi_show_3d, 1, 0, 1, 1, md_face_color, m
d_bendline_color); if(! i) {mi_display_list_i
s_up_to_date = 0; return; } mi_disp
lay_list_is_up_to_date = 1; mi_flat_is_up_to_
date = 1; mi_3d_is_up_to_date = 0; } else
{ // Prepare solid. i = facet_part_rw
(part, &m_flat_base_clump, mi_show_3d, md_part_col
or); if( (! i)|| (! m_flat_base_clump) ) retur
n; m_base_clump = m_flat_base_clump;RwAddClumpT
oScene(m_scene, m_base_clump); } } mi_bbox_is_u
p_to_date = 0; ml_num_faces = part->get_number_of
_faces(); ml_num_bendlines =part->get_number_of_b
endlines(); ml_num_formings = part->get_number_of
_formings(); clear_selection_set(); reset_select
ion_buffer(); ml_last_function_chosen = RETURN_FR
OM_DIALOG_MODE; DrawPart(m_hdc); ml_last_functio
n_chosen = NO_FUNCTION_MODE;}void CBendCADViewPar
t::OnShowFlat() {if(! mi_show_3d) return; // Flat
is already being shown. int i; BM_PART *part
= NULL; CBendCADDoc* pDoc = GetDocument(); ASSER
T_VALID(pDoc); part = pDoc->get_part(); if(! par
t) { mi_part_is_up_to_date =0; return; } //
Store the current 3d view parameters. md_old_x_tr
ans = md_x_trans; md_old_y_trans = md_y_trans; f
or(i=0; i < 3; ++i) {md_old_part_bbox_size[i] = md
_part_bbox_size[i]; md_old_view_vol[i]=md_current
_view_vol[i]; } if(md_old_rot_matrix) RwDestroyM
atrix(md_old_rot_matrix); md_old_rot_matrix = RwD
uplicateMatrix(md_rot_matrix); mi_show_3d = 0; m
_part_centroid = m_flat_part_centroid; if(! mi_s
how_solid) {// Compute the flat’s display list.
if(! mi_flat_is_up_to_date) { i = prepare
_display_list(part, mi_show_3d, 1, 0, 1, 1, md_fac
e_color, md_bendline_color); if(! i) {
mi_display_list_is_up_to_date = 0; return;
} } mi_display_list_is_up_to_date= 1;
mi_flat_is_up_to_date = 1; mi_3d_is_up_to_date
= 0; } else {//Compute flat’s clump if not alre
ady done. if(m_3d_base_clump) RwRemoveClumpFrom
Scene(m_3d_base_clump); m_base_clump = NULL; if
(! m_flat_base_clump) { i = facet_part_rw(par
t, &m_flat_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_flat_base_clump) ) {
mi_display_list_is_up_to_date = 0; return;
} } m_base_clump= m_flat_base_clump;// S
et the base clump to be the flat’s base clump.RwA
ddClumpToScene(m_scene, m_base_clump); } mi_bbox
_is_up_to_date= 0; OnViewTop(); }// Here we show
the 3d version, in its old orientation and zoom
(before flat was// asked to be shown).void CBendCA
DViewPart::OnShow3d() { if(mi_show_3d) return;
// 3D view is already being shown. int i; BM
_PART *part = NULL; CBendCADDoc* pDoc = GetDocume
nt(); ASSERT_VALID(pDoc); part = pDoc->get_par
t(); if(! part) { mi_part_is_up_to_date = 0;
return; } // Restore the old 3d view parameters.
md_x_trans = md_old_x_trans; md_y_trans = md_old_
y_trans; for(i=0; i< 3; ++i) { md_part_bbox_si
ze[i] = md_old_part_bbox_size[i]; md_current_view
_vol[i] = md_old_view_vol[i]; } if(md_rot_matri
x) RwDestroyMatrix(md_rot_matrix); md_rot_matrix
= RwDuplicateMatrix(md_old_rot_matrix); mi_show_3
d = 1; m_part_centroid = m_3d_part_centroid; if
(! mi_show_solid) { if(! mi_3d_is_up_to_date)
{ i = prepare_display_list(part, mi_show_3d,
1, 0, 1, 1, md_face_color, md_bendline_color);
if(! i) { mi_display_list_is_up_to_date
= 0; return; }mi_display_list_is_up_to_
date = 1; mi_3d_is_up_to_date = 1;mi_flat_is_
up_to_date = 0; } } else {// Compute the 3d_v
ersion’s clumps if have not already done so. i
f(m_flat_base_clump) RwRemoveClumpFromScene(m_flat
_base_clump); m_base_clump = NULL; if(! m_3d_b
ase_clump) { i = facet_part_rw(part, &m_3d_b
ase_clump, mi_show_3d, md_part_color); if( (!
i) || (! m_3d_base_clump) ) { mi_display_l
ist_is_up_to_date = 0; return; } }
m_base_clump = m_3d_base_clump;// Set the base c
lump to be the 3d version’s base clump.RwAddClump
ToScene(m_scene, m_base_clump); } mi_bbox_is_up_
to_date= 0;md_current_view_vol[1] = md_current_vie
w_vol[0]/md_aspect; RwSetCameraViewwindow(m_came
ra, (float)(md_current_view_vol[0]), (float)(md_cu
rrent_view_vol[1])); glMatrixMode(GL_PROJECTIO
N); glLoadIdentity(); glOrtho(- md_current_view_
vol[0],md_current_view_vol[0],- md_current_view_vo
l[1], md_current_view_vol[1],//- 50000.0, 50000.
0); - md_current_view_vol[2], md_current_
view_vol[2]); glMatrixMode(GL_MODELVIEW); DrawPa
rt(m_hdc); }void CBendCADViewPart::OnHide3d() {
OnShowFlat();// For now, just switch to showing fl
at.}void CBendCADViewPart::OnHideFlat(){ OnShow3d
();// For now, just switch to showing 3D.}void CBe
ndCADViewPart::OnViewWireframe() { if(! mi_show_s
olid) return; // Wireframe already being shown.
int i; CreateRGBPalette(m_hdc);// when wirefram
e --recreate the palette -- AK HGLRC hrc = wglGet
CurrentContext(); // Therendering context of OpenG
L. wglMakeCurrent(NULL, NULL); wglMakeCurrent(m_
hdc, hrc); // Associate the rendering conte
xt with this view.BM_PART *part = NULL; CBendCADD
oc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pa
rt = pDoc->get_part(); if(! part) { mi_part_is
_up_to_date = 0; return; } mi_show_solid = 0;
if(mi_show_3d) { if(! mi_3d_is_up_to_date) {
i = prepare_display_list(part, mi_show_3d, 1,
0, 1, 1, md_face_color, md_bendline_color);
if(! i) { mi_display_list_is_up_to_date =
0; return; } mi_display_list_is_up_
to_date = 1; mi_3d_is_up_to_date = 1; mi_fla
t_is_up_to_date = 0;} } else { if(! mi_flat_i
s_up_to_date) { i = prepare_display_list(par
t, mi_show_3d, 1, 0, 1, 1, md_face_color, md_bendl
ine_color);if(! i) { mi_display_list_is_up_
to_date = 0; return;} mi_display_list_is
_up_to_date = 1; mi_3d_is_up_to_date =0; mi_
flat_is_up_to_date = 1; } } ml_last_function_
chosen = WIREFRAME_MODE; DrawPart(m_hdc); ml_las
t_function_chosen = NO_FUNCTION_MODE; }void CBe
ndCADViewPart::OnViewShaded() { if(mi_show_solid)
return;// Solid already being shown. int i; BM_
PART *part = NULL; CBendCADDoc* pDoc = GetDocumen
t(); ASSERT_VALID(pDoc); part = pDoc->get_par
t(); if(! part) { mi_part_is_up_to_date = 0;
return; } mi_show_solid = 1; if(mi_show_3d) {
if(! m_3d_base_clump) { i = facet_part_rw
(part, &m_3d_base_clump, mi_show_3d, md_part_colo
r); if( (!i) || (! m_3d_base_clump) ) {
mi_display_list_is_up_to_date = 0;return; }
}RwRemoveClumpFromScene(m_base_clump); m_ba
se_clump = m_3d_base_clump;// Set the base clump t
o be the 3d version’s base clump. RwAddClumpTo
Scene(m_scene, m_base_clump); } else { if(! m
_flat_base_clump) { i = facet_part_rw(part,
&m_flat_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_flat_base_clump) ){ m
i_display_list_is_up_to_date = 0; return;
} }RwRemoveClumpFromScene(m_base_clump); m
_base_clump = m_flat_base_clump;//Set the base clu
mp to be the 3d version’s base clump. RwAddClu
mpToScene(m_scene, m_base_clump); } ml_last_func
tion_chosen = SOLID_MODE;DrawPart(m_hdc); ml_last
_function_chosen = NO_FUNCTION_MODE; }voidCBendC
ADViewPart::OnZoomWindow() { ml_last_function_cho
sen = ZOOM_WINDOW_MODE; mi_bbox_is_up_to_date =
0;}void CBendCADViewPart::OnUpdateZoomWindow(CCmd
UI* pCmdUI) {pCmdUI->SetCheck((ZOOM_WINDOW_MODE ==
ml_last_function_chosen) ? TRUE : FALSE);}void CB
endCADViewPart::OnZoomInOut() { ml_last_function_
chosen = ZOOM_IN_OUT_MODE; mi_bbox_is_up_to_dat
e = 0;}void CBendCADViewPart::OnUpdateZoomInOut(CC
mdUI* pCmdUI) {pCmdUI->SetCheck((ZOOM_IN_OUT_MODE
== ml_last_function_chosen) ? TRUE : FALSE);}voidC
BendCADViewPart::OnZoomAll() { BM_PART *part = NU
LL; CBendCADDoc* pDoc; BM_VECTOR offset; 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 nowwe expect th
e centroid to have alreadycompute_part_centroid(pa
rt, 0, &m_flat_part_centroid); // been computed;
this is only a safety check. compute_part_centroid
(part, 1, &m_3d_part_centroid); if(mi_show_3d) m_p
art_centroid = m_3d_part_centroid;else m_part_cent
roid = m_flat_part_centroid;}compute_part_bbox(pa
rt, mi_show_3d, md_rot_matrix, m_part_centroid,md_
part_bbox_size, &offset); mi_bbox_is_up_to_date
= 1;md_x_trans =-(offset.X()); // Adjust for
the fact that bbox center maymd_y_trans= -(offset.
Y()); // not coincide with centroid of part.
} set_new_view_volume(md_part_bbox_size[0], md_
part_bbox_size[1]); ml_last_function_chosen = ZOO
M_ALL_MODE; DrawPart(m_hdc); ml_last_function_ch
osen =NO_FUNCTION_MODE; }void CBendCADViewPart::O
nUpdateZoomAll(CCmdUI* pCmdUI) {pCmdUI->SetCheck
((ZOOM_ALL_MODE == ml_last_function_chosen) ? TRU
E: FALSE);}void CBendCADViewPart::OnViewIsometri
c() { ml_last_function_chosen = ISOMETRIC_VIEW_MO
DE; mi_bbox_is_up_to_date = 0; md_z_angle = 270.
0; md_y_angle = 305.2643897;// 270 + tan^-1(1/sqr
t(2)) RwRotateMatrix(RwScratchMatrix(), 0.0f, 0.0
f, 1.0f, CREAL(md_z_angle), rwREPLACE);RwRotateMat
rix(RwScratchMatrix(), 0.0f, 1.0f, 0.0f, CREAL(md_
y_angle),rwPRECONCAT); md_z_angle = 45.0; RwRota
teMatrix(RwScratchMatrix(), 0.0f, 0.0f, 1.0f, CREA
L(md_z_angle), rwPRECONCAT); if(md_rot_matrix) Rw
DestroyMatrix(md_rot_matrix); md_rot_matrix = RwD
uplicateMatrix(RwScratchMatrix());// glPushMatrix
();// glLoadIdentity();// glRotated(md_z_angle,
0.0, 0.0, 1.0); // Rotation about z axis.// glR
otated(md_y_angle,0.0, 1.0, 0.0); // Rotation abo
ut y axis.// md_z_angle = 45.0;// glRotated(md_z
_angle, 0.0, 0.0, 1.0);// glGetDoublev(GL_MODELVI
EW_MATRIX, md_rot_matrix);// glPopMatrix(); OnZo
omAll();}void CBendCADViewPart::OnViewRight() { m
l_last_function_chosen = RIGHT_VIEW_MODE; mi_bbox
_is_up_to_date = 0; md_z_angle = 270.0; md_y_ang
le = 270.0; md_x_angle = 0.0; RwRotateMatrix(RwS
cratchMatrix(), 0.0f, 0.0f, 1.0f, CREAL(md_z_angl
e), rwREPLACE); RwRotateMatrix(RwScratchMatrix(),
0.0f, 1.0f, 0.0f, CREAL(md_y_angle), rwPRECONCA
T); if(md_rot_matrix) RwDestroyMatrix(md_rot_matr
ix); md_rot_matrix = RwDuplicateMatrix(RwScratchM
atrix());// glPushMatrix();// glLoadIdentity();/
/ glRotated(md_z_angle, 0.0, 0.0, 1.0);// Rotatio
n about z axis.// glRotated(md_y_angle, 0.0, 1.
0, 0.0);// Rotation about y axis.// glGetDoublev
(GL_MODELVIEW_MATRIX, md_rot_matrix);// glPopMatr
ix(); OnZoomAll();}void CBendCADViewPart::OnViewF
ront() { ml_last_function_chosen = FRONT_VIEW_MOD
E; mi_bbox_is_up_to_date= 0; md_y_angle = 0.0;
md_z_angle = 0.0; md_x_angle = 270.0; RwRotateMa
trix(RwScratchMatrix(), 1.0f, 0.0f, 0.0f, CREAL(md
_x_angle), rwREPLACE); if(md_rot_matrix) RwDestro
yMatrix(md_rot_matrix); md_rot_matrix =RwDuplicat
eMatrix(RwScratchMatrix());// glPushMatrix(); //
glLoadIdentity();// glRotated(md_x_angle, 1.0,
0.0, 0.0); // Rotation about x axis.// glGetDou
blev(GL_MODELVIEW_MATRIX, md_rot_matrix);// glPop
Matrix(); OnZoomAll();}void CBendCADViewPart::OnV
iewTop() { ml_last_function_chosen = TOP_VIEW_MOD
E; mi_bbox_is_up_to_date = 0; RwIdentityMatrix(m
d_rot_matrix); OnZoomAll();}void CBendCADViewPar
t::OnViewsOrtho() {if (NULL == GetDocument()->get_
part()) { // no partreturn ;} COrthoViewDlg orhodl
g(NULL, GetDocument()->get_part(), this) ;int ret
= orhodlg.DoModal() ;// if we are in a Client Mod
e, the user cannot have entered anything.// we hav
e to redisplay the main client menu bar.if (BENDCA
D_CLIENT_MODE) {::PostMessage(this->GetSafeHwnd(),
WM_COMMAND,MAKEWPARAM(ID_DISPLAY_CLIENT_MENU,1),NU
LL) ;return ;}// when OK pressed, get return value
sif (IDOK == ret) {}}void CBendCADViewPart::OnView
Back() { ml_last_function_chosen = BACK_VIEW_MOD
E; mi_bbox_is_up_to_date = 0; md_x_angle = 270.
0; md_y_angle = 0.0; md_z_angle = 180.0; RwRota
teMatrix(RwScratchMatrix(), 1.0f, 0.0f, 0.0f, CREA
L(md_x_angle), rwREPLACE); RwRotateMatrix(RwScrat
chMatrix(), 0.0f, 0.0f, 0.1f, CREAL(md_z_angle), r
wPRECONCAT); if(md_rot_matrix) RwDestroyMatrix(md
_rot_matrix); md_rot_matrix = RwDuplicateMatrix(R
wScratchMatrix()); OnZoomAll();}void CBendCADView
Part::OnViewBottom() { ml_last_function_chosen =
BOTTOM_VIEW_MODE; mi_bbox_is_up_to_date = 0; md_
x_angle = 0.0; md_y_angle = 180.0; md_z_angle =
0.0;RwRotateMatrix(RwScratchMatrix(), 0.0f, 1.0f,
0.0f, CREAL(md_y_angle),rwREPLACE); if(md_rot_mat
rix) RwDestroyMatrix(md_rot_matrix); md_rot_matri
x = RwDuplicateMatrix(RwScratchMatrix()); OnZoomA
ll();}void CBendCADViewPart::OnViewLeft() { ml_la
st_function_chosen = LEFT_VIEW_MODE; mi_bbox_is_u
p_to_date = 0; md_z_angle = 90.0; md_y_angle = 9
0.0; md_x_angle = 0.0; RwRotateMatrix(RwScratchM
atrix(), 0.0f, 0.0f, 1.0f, CREAL(md_z_angle), rwRE
PLACE); RwRotateMatrix(RwScratchMatrix(), 0.0f,
1.0f,0.0f, CREAL(md_y_angle), rwPRECONCAT); if(md
_rot_matrix) RwDestroyMatrix(md_rot_matrix); md_r
ot_matrix = RwDuplicateMatrix(RwScratchMatrix());O
nZoomAll();} void CBendCADViewPart::OnRotate()
{ ml_last_function_chosen = ROTATION_MODE; mi_bb
ox_is_up_to_date = 0;}void CBendCADViewPart::OnUpd
ateRotate(CCmdUI* pCmdUI) {pCmdUI->SetCheck((ROTAT
ION_MODE == ml_last_function_chosen) ? TRUE : FALS
E);}void CBendCADViewPart::OnPan() {ml_last_functi
on_chosen = PAN_MODE; mi_bbox_is_up_to_date =
0;}void CBendCADViewPart::OnUpdatePan(CCmdUI* pCmd
UI) {pCmdUI->SetCheck((PAN_MODE == ml_last_functio
n_chosen) ? TRUE : FALSE);}// This function comput
es the rotation angles about x and y axes.// It is
called on mouse movement, if the rotation mode is
on.void CBendCADViewPart::compute_rotation_angles
(int x_flag){ double x_dir = (double)(m_current_p
oint.x - m_previous_point.x); double y_dir = (dou
ble)(m_current_point.y - m_previous_point.y); dou
ble mag = sqrt(x_dir*x_dir + y_dir*y_dir); // Cre
ate the rotation matrix corresponding to the axis
computed. if(mag > 0.1) { RwRotateMatrix(RwScr
atchMatrix(), CREAL(y_dir/mag), CREAL(x_dir/mag),
CREAL(0.0), CREAL(360.0*mag/(1.
414*m_old_rect.bottom)),rwREPLACE); RwTransform
Matrix(RwScratchMatrix(), md_rot_matrix, rwPRECONC
AT); if(md_rot_matrix) RwDestroyMatrix(md_rot_m
atrix); md_rot_matrix = RwDuplicateMatrix(RwScr
atchMatrix()); } // glPushMatrix();// glLoad
Identity();// glRotated(md_y_angle, 0.0, 1.0, 0.
0); // Rotation about y axis.// if(x_flag)//
glRotated(md_x_angle, 1.0, 0.0,1.0); // Rota
tion about x axis.// else// glRotated(md_z_ang
le, 0.0, 0.0, 1.0); // Rotation about z axis.//
glMultMatrixd(md_rot_matrix);// glGetDoublev(GL
_MODELVIEW_MATRIX, md_rot_matrix);// glPopMatri
x();} // This function computes the x and y transl
ation values.// It is called on mouse movement, if
the pan mode is on.void CBendCADViewPart::compute
_pan_translation(void){ double x; if( (x = (doub
le)m_old_rect.right) > 0.0 ) md_x_trans += (m_c
urrent_point.x - m_previous_point.x)*md_current_vi
ew_vol[0]/x; if( (x = (double)m_old_rect.bottom)
> 0.0 ) md_y_trans += -(m_current_point.y - m_p
revious_point.y)* // -ve sign for md_y_trans
md_current_view_vol[1]/x;
// bec. y axis points up screen.
}// This funciton computes translation value
s when user zooms in/out.void CBendCADViewPart::co
mpute_zoom_in_out_translation(void){ double x; i
f( (x= (double)m_old_rect.right) > 0.0 ) md_x_t
rans += -(m_current_point.x - m_previous_point.x)*
md_current_view_vol[0]/x;}//Thi
s funciton computes translation values when user z
ooms into a // selected rectangular region.void CB
endCADViewPart::compute_zoom_region_translation(vo
id){ double x1 = ((double)(m_lt_btn_down_point.x
+ m_lt_btn_up_point.x))/2.0; double delta_x = x1
- ((double)m_old_rect.right)/2.0;double y1 = ((dou
ble)(m_lt_btn_down_point.y + m_lt_btn_up_point.y))
/2.0;double delta_y = -( y1 - ((double)m_old_rect.
bottom)/2.0 ); md_x_trans -= //m_part_centroid.
X() - md_x_trans + delta_x*2.0*md_c
urrent_view_vol[0]/((double)m_old_rect.right); md
_y_trans -= //m_part_centroid.Y() - md_y_trans +
delta_y*2.0*md_current_view_vol[1]/
((double)m_old_rect.bottom);}// This function comp
utes the new view volume when the user zooms in/ou
t.// The part has already been translated appropri
ately.void CBendCADViewPart::compute_zoom_in_out_v
iew_volume(void){ double x = -(m_current_point.y
- m_previous_point.y); md_current_view_vol[0] -=
md_current_view_vol[0]*x/(double)m_old_rect.botto
m; md_current_view_vol[1] = md_current_view_vol
[0]/md_aspect; RwSetCameraViewwindow(m_camera, (f
loat)(md_current_view_vol[0]), (float)(md_current_
view_vol[1])); glMatrixMode(GL_PROJECTION); glL
oadIdentity(); glOrtho(- md_current_view_vol[0],m
d_current_view_vol[0],- md_current_view_vol[1], md
_current_view_vol[1],//- 50000.0, 50000.0);
- md_current_view_vol[2], md_current_view_vol
[2]); glMatrixMode(GL_MODELVIEW);}// This functio
n computes and sets the new view volume when the u
ser zooms into // a selected rectangular region.
(In the case of zoom all, the selected// region is
simply the bounding box of the part).// The part
has already been translated appropriately.void CBe
ndCADViewPart::set_new_view_volume(double x_exten
t, double y_extent){ double longer = __max(x_ext
ent, y_extent); double shorter = __min(x_extent,
y_extent); if(longer ==x_extent) { // The x ex
tent is longer. if(longer/md_aspect < shorter)
// y extent does not fit screen. longer =
shorter*md_aspect;md_current_view_vol[0] = 0.55*l
onger;md_current_view_vol[1] = 0.55*longer/md_aspe
ct;md_current_view_vol[2] = __max(longer, md_part_
bbox_size[2]); } else { // The y extent is long
er. if(longer*md_aspect < shorter) // x e
xtent does not fit screen. longer = shorter/md_as
pect;md_current_view_vol[0] = 0.55*longer*md_aspec
t;md_current_view_vol[1] = 0.55*longer;md_current_
view_vol[2] = __max(longer, md_part_bbox_size
[2]);} RwSetCameraViewwindow(m_camera, (float)(md
_current_view_vol[0]), (float)(md_current_view_vol
[1])); glMatrixMode(GL_PROJECTION); glLoadIdent
ity(); glOrtho(- md_current_view_vol[0],md_curren
t_view_vol[0],- md_current_view_vol[1], md_current
_view_vol[1],//- 50000.0, 50000.0);- md_current_vi
ew_vol[2], md_current_view_vol[2]); glMatrixMode
(GL_MODELVIEW); glLoadIdentity();}// This functio
n draws a part on the viewwindow. It is called by
OnDraw.void CBendCADViewPart::DrawPart(HDC draw_d
c) { long size, i, parent_tag, key;static long *se
lected_items = NULL;RwClump *picked_clump, *parent
_clump; static double red_color[3] = {1.0, 0.0,
0.0}; static double green_color[3] = {0.0, 1.0,
0.0};double array[16];BV_SELECT_DATA *data = NULL;
static RwMatrix4d *old_matrix[50];static float rw_
array[4][4];if(mi_simulation_is_on) {// Set camera
parameters to view window values. RwSetCameraVie
wport(m_camera, 0, 0, m_old_rect.right, m_old_rec
t.bottom); glViewport(0, 0, m_old_rect.right, m
_old_rect.bottom); RwSetCameraVieww
indow(m_camera, (float)(md_current_view_vol[0]),
(float)(md_current_view_vol[1])); glMatrixMode(GL_
PROJECTION);glLoadIdentity();glOrtho(- md_current_
view_vol[0],md_current_view_vol[0],- md_current_vi
ew_vol[1], md_current_view_vol[1],//- 50000.0, 500
00.0); - md_current_view_vol[2], md_cur
rent_view_vol[2]);glMatrixMode(GL_MODELVIEW);}if(!
mi_show_solid){ // Wireframe drawing; use Ope
nGL drawing commands. glPushMatrix();glTranslated
(m_camera_position.X(), m_camera_position.Y(), m_c
amera_position.Z());gluLookAt(m_camera_position.
X(), m_camera_position.Y(), m_camera_position.Z(),
m_camera_target.X(), m_camera_target.Y(), m_came
ra_target.Z(), m_camera_look_up.X(), m_ca
mera_look_up.Y(), m_camera_look_up.Z()); glTran
slated(md_x_trans, md_y_trans, 0.0); convert_rw_m
atrix_to_gl_array(md_rot_matrix, array); glMultMa
trixd(array); glTranslated(- m_part_centroid.X(),
- m_part_centroid.Y(), - m_part_centroid.Z());
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear
(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if(m
l_last_function_chosen == SELECT_OBJECTS_MODE)
glRenderMode(GL_SELECT); else glRenderMode(GL
_RENDER); glSelectBuffer(512,mw_selected_object
s); glInitNames(); glPushName(0); if(! mi_simul
ation_is_on) { // First draw the selected items i
n red, if any.size = m_selection_set.list_size();i
f(size) {selected_items = new long [size*2 + 1];//
+1 for safety.m_selection_set.display(size, selec
ted_items);glColor3d(1.0, 0.0, 0.0);for(i=0; i < s
ize; ++i) { data = (BV_SELECT_DATA *)selected_ite
ms[i*2 +1];if(! data) continue;if(data->edge) {//
Edge is available, => not a trivial glCallList((u
nsigned int)selected_items[i<<1]); // bendline or
body of something.}else {// Body of face/forming/b
endline picked; highlight whole thing.key = select
ed_items[i<<1]/100000;glCallList((unsigned int)key
*100000);}} } } glCallList(1); glFinish();
glPopMatrix(); SwapBuffers(wglGetCurrentD
C());} else { // Solid drawing; use RenderWare.
// Transform the part if necessary. if(ml_last_
function_chosen != NO_FUNCTION_MODE) { RwTran
slateMatrix(RwScratchMatrix(), CREAL(md_x_trans),
CREAL(md_y_trans), CREAL(0.0), rwREPLACE); R
wTransformMatrix(RwScratchMatrix(), md_rot_matrix,
rwPRECONCAT); RwTranslateMatrix(RwScratchMat
rix(), CREAL(- m_part_centroid.X()), CREAL(- m_par
t_centroid.Y()),CREAL(- m_part_centroid.Z()), rwPR
ECONCAT);// RwForAllClumpsInScenePointer(m_scene,
do_transformations, (void *)RwScratchMatrix());
RwTransformClump(m_base_clump, RwScratchMatrix
(), rwREPLACE); }/*RwClump *clump; for(i=0; i <
ml_num_faces + ml_num_bendlines + ml_num_forming
s; ++i) { clump = RwFindTaggedClump(m_base_
clump, i + 10001);if(! clump) continue;old_matrix
[i] = RwCreateMatrix();// clump の現在のモデル化マ
トリクスを記憶する. RwGetClumpMatrix(clump, old
_matrix[i]);RwGetMatrixElements(old_matrix[i], rw_
array); RwTranslateMatrix(RwScratchMatrix(), CR
EAL(md_x_trans), CREAL(md_y_trans), CREAL(0.0), rw
REPLACE); RwTransformMatrix(RwScratchMatrix(),
md_rot_matrix, rwPRECONCAT); RwTranslateMatrix
(RwScratchMatrix(), CREAL(- m_part_centroid.X()),
CREAL(- m_part_centroid.Y()),
CREAL(- m_part_centroid.Z()), rwPRECONCAT); //R
wForAllClumpsInScenePointer(m_scene, do_transforma
tions, (void *)RwScratchMatrix());RwTransformClump
(clump, RwScratchMatrix(), rwPOSTCONCAT); }*///N
ow set the color of the clumps in the selection se
t to red.size = m_selection_set.list_size();if(siz
e) {selected_items = new long [(size << 1) + 1];
// +1 for safety.m_selection_set.display(size, sel
ected_items);for(i=0; i < size; ++i){data = (BV_SE
LECT_DATA *)selected_items[i*2 +1];if(! data) cont
inue;if(data->edge) { // Edge is availabl
e, => not a trivial bendline orbody of something.p
arent_tag = (selected_items[i<<1]/100000) + 10000;
parent_clump = RwFindTaggedClump(m_base_clump, par
ent_tag);}else {key = selected_items[i<<1]%100000;
// Check if it is a trivial bendline.if((key/100
00) == 6) {parent_tag = (selected_items[i<<1]/1000
00) + 10000;parent_clump = RwFindTaggedClump(m_bas
e_clump, parent_tag);}else parent_clump= m_base_cl
ump;}key = selected_items[i<<1]%100000;picked_clum
p = RwFindTaggedClump(parent_clump, key);RwForAllP
olygonsInClumpPointer(picked_clump, SetPolygonColo
r, (void *)red_color); }} // In case simulation i
s going on, we don’t want to show the m_sim_base_
clump, only m_base_clump.if(mi_simulation_is_on)
{if(m_sim_base_clump) RwRemoveClumpFromScene(m_sim
_base_clump);if(mi_show_3d) {m_base_clump = m_3d_b
ase_clump;RwAddClumpToScene(m_scene, m_base_clum
p);}else {m_base_clump = m_flat_base_clump;RwAddCl
umpToScene(m_scene, m_base_clump); } } //
Now draw the part. RwInvalidateCameraViewport(m_
camera); RwBeginCameraU
pdate(m_camera, (void *)m_hwnd); RwClearCamer
aViewport(m_camera); i = RwGetSceneNumClumps
(m_scene); // Render the scene. RwRen
derScene(m_scene); RwEndCameraUpdate(m_camera);
RwShowCameraImage(m_camera, (void*)(DWORD)draw_d
c); //Show the image onthe view window./* for
(i=0; i < ml_num_faces + ml_num_bendlines + ml_num
_formings; ++i) { clump = RwFindTaggedClump(m_b
ase_clump, i + 10001);if(! clump) continue;RwTrans
formClump(clump, old_matrix[i], rwREPLACE);RwGetCl
umpMatrix(clump, old_matrix[i]); RwGetMatrixEleme
nts(old_matrix[i], rw_array);if(old_matrix[i]) RwD
estroyMatrix(old_matrix[i]);}*/ // Put the simula
tion clump back in the scene so that simulation ca
nsee it. if(mi_simulation_is_on) {if(m_sim_base_c
lump) RwAddClumpToScene(m_scene, m_sim_base_clum
p);if(mi_show_3d) RwRemoveClumpFromScene(m_3d_base
_clump);else RwRemoveClumpFromScene(m_flat_base_cl
ump);m_base_clump= NULL; } // Now set the color
of the clumps in the selection set backto their or
iginal colors. if(size) { m_selection_set.disp
lay(size,selected_items); for(i=0; i < size; ++
i) {data = (BV_SELECT_DATA *)selected_items[i*2 +
1];if(data->edge) { // Edge is available,
=> not a trivial bendline or body of something.par
ent_tag = (selected_items[i<<1]/100000) + 10000;pa
rent_clump = RwFindTaggedClump(m_base_clump, paren
t_tag);}else {key = selected_items[i<<1]%100000;
// Check ifit is a trivial bendline.if((ke
y/10000) == 6) {parent_tag = (selected_items[i<<1]
/100000) + 10000;parent_clump = RwFindTaggedClump
(m_base_clump,parent_tag); } else parent_clump
= m_base_clump; }key = selected_items[i<<1]%100
000;picked_clump = RwFindTaggedClump(parent_clump,
key);if( (! data->edge) && ((key/10000) == 6) )
// Trivial bendline.RwForAllPolygonsInClumpPointer
(picked_clump, SetPolygonColor, (void *)green_colo
r); elseRwForAllPolygonsInClumpPointer(picked_clum
p, SetPolygonColor, (void *)md_part_color); }
} if(selected_items) delete [] selected_items;
selected_items = NULL;}if(mi_simulation_is_on)
{ // Restore camera parameters to simulation val
ues. RwSetCameraViewport(m_camera, 0, 0,mi_bitmap
_w , mi_bitmap_h); glViewport(0, 0, mi_bitmap_
w, mi_bitmap_h); RwSetCameraViewwindo
w(m_camera, (float)(md_sim_view_vol[0]), (float)(m
d_sim_view_vol[1])); glMatrixMode(GL_PROJECTION);g
lLoadIdentity();glOrtho(- md_sim_view_vol[0], md_s
im_view_vol[0],- md_sim_view_vol[1], md_sim_view_v
ol[1],//- 50000.0, 50000.0); - md_curre
nt_view_vol[2], md_current_view_vol[2]);glMatrixMo
de(GL_MODELVIEW);}}/*if(size) { for(i=0 ; i < siz
e; ++i) { BM_3D_BODY *b3;long three_d_type;if(s
elected_items[i*2 +1]) { // エッジ
が得られる => trivalベンドラインまたはフォーミング
ではない. three_d_type = (selected_items[i<<1]%1
00000)/10000; if((three_d_type >= 3) && (three_d_
type < 6)) three_d_type = BM_ENTITY_TYPE_FACE; el
se if((three_d_type >= 6) && (three_d_type < 9)) t
hree_d_type = BM_ENTITY_TYPE_BENDLINE; else if(th
ree_d_type >= 9) three_d_type = BM_ENTITY_TYPE_FOR
MING; parent_tag = (selected_items[i<<1]/100000)
+ 10000; parent_clump = RwFindTaggedClump(m_base_
clump, parent_tag);}else { CBendCADDoc* p
Doc = GetDocument();ASSERT_VALID(pDoc); B
M_PART *part = pDoc->get_part();if(! part) return;
// 注意: この段階で部分がNULLであることを期待し
ない。 BM_TOPOLOGY *topology = part->get_
topology();if(! topology) return; three_d_type =
selected_items[i<<1]/100000;// 用語の注意: three_d
_type は実際ではない。 b3 = topology->map
_id_into_pointer(three_d_type); // b3->get_type()
までthree_d_type. 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) o
riginal_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_col
or[j];}else if(three_d_type == BM_ENTITY_TYPE_FORM
ING) { for(j=0; j < 3;++j) original_color[j]
= md_forming_color[j];}key = selected_items[i<<1];
key = key%100000; picked_clump = RwFindTaggedCl
ump(parent_clump, key); RwForAllPolygonsInClump
Pointer(picked_clump, SetPolygonColor, (void *)ori
ginal_color); }}*/// This callback function perf
orms the necessary transformations on each clump i
n the scene.// Transform only parentclumps, since
this automatically transforms child clumps as wel
l.staticRwClump * RWCALLBACK do_transformations(Rw
Clump *clump, void *matrix) {int i = RwGetClumpNum
Children(clump); if(i) {if( !(i = RwGetClumpNumPo
lygons(clump)) ) RwSetClumpState(clump, rwOF
F);// Do not render this clump if it has no polygo
ns. RwTransformClump(clump, (RwMatrix4d *)matri
x, rwREPLACE); } return clump;}// This cal
lback function sets the color of the polygon to th
e required color.static RwPolygon3d *RWCALLBACK Se
tPolygonColor(RwPolygon3d *polygon, void *color)
{ polygon = RwSetPolygonColor(polygon, CREAL
(((double *)color)[0]), CREAL(((double *)color)
[1]), CREAL
(((double *)color)[2]));return polygon;}// This fu
nction sets the pixel format of the view window to
the kind that// OpenGL likes. Note: Pixel format
of awindow should be set only once.BOOL CBendCADVi
ewPart::SetupPixelFormat(HDC hDC){ static PIXEL
FORMATDESCRIPTOR pfd = { sizeof(PIXELFORMAT
DESCRIPTOR), // size of this pfd 1,// vers
ion number PFD_DRAW_TO_WINDOW |
// supportwindow PFD_SUPPORT_OPENGL |
// support OpenGLPFD_DOUBLEBUFFER,
// double buffered PFD_TYPE_RGBA,// RGBA
type 24, //24-
bit color depth 0, 0, 0, 0, 0, 0,
// color bitsignored 0,
// no alpha buffer0,
// shift bit ignored 0,// n
o accumulation buffer 0, 0, 0,0,// accum bi
ts ignored 32,// 32-bit z-buffer 0,/
/ no stencil buffer 0,
// no auxiliary buffer PFD_MAIN_P
LANE, // main layer 0,// re
served 0, 0, 0// layer masks ignored };
int pixelformat; if ( (pixelformat =ChooseP
ixelFormat(hDC, &pfd)) == 0 ) { MessageB
ox("ChoosePixelFormat failed"); return FALS
E; } if (SetPixelFormat(hDC, pixelformat, &p
fd) == FALSE) { MessageBox("SetPixelForm
at failed"); return FALSE; } // don’
t need this call any more; thefunction will be cal
led from OnActivateView()// and on OnViewWireframe
() -- AK//CreateRGBPalette(hDC); return TRUE;}u
nsigned char CBendCADViewPart::ComponentFromIndex
(int i, UINT nbits, UINT shift){ unsigned char
val; val = (unsigned char) (i >> shift); swi
tch (nbits) { case 1: val &= 0x1;
return oneto8[val]; case 2: val &= 0x
3; return twoto8[val]; case 3: va
l &= 0x7;return threeto8[val]; default:
return 0; }}void CBendCADViewPart::CreateRGBPal
ette(HDC hDC){ PIXELFORMATDESCRIPTOR pfd; LO
GPALETTE *pPal; int n, i; CDC dc; n = ::G
etPixelFormat(hDC);::DescribePixelFormat(hDC, n, s
izeof(PIXELFORMATDESCRIPTOR), &pfd);if (pfd.dwFlag
s & PFD_NEED_PALETTE) { n = 1 << pfd.cCo
lorBits; pPal = (PLOGPALETTE)LocalAlloc(LME
M_FIXED, sizeof(LOGPALETTE)+ n * si
zeof(PALETTEENTRY)); pPal->palVersion = 0x3
00; pPal->palNumEntries = n; for (i=
0; i<n; i++) {pPal->palPalEntry[i].peRed =
ComponentFromIndex(i, pfd.cRed
Bits, pfd.cRedShift); pPal->palPalEntry
[i].peGreen = ComponentFromInde
x(i, pfd.cGreenBits, pfd.cGreenShift);
pPal->palPalEntry[i].peBlue =ComponentFromIndex(i,
pfd.cBlueBits, pfd.cBlueShift); pPal->
palPalEntry[i].peFlags = 0; } /* 省
略時GDIパレットを含むようにパレットを固定する */
if ((pfd.cColorBits == 8)&& (pfd.
cRedBits == 3) && (pfd.cRedShift == 0) &&
(pfd.cGreenBits == 3) && (pfd.cGreenShift
== 3) &&(pfd.cBlueBits == 2) && (pfd.cBlueShift
== 6) ){for (i = 1 ; i <= 12 ; i++)
pPal->palPalEntry[defaultOverride[i]]
= defaultPalEntry[i]; } dc.Attach(hD
C);CPalette*pOldPal; // since we call this
function not only when creating a view,// but also
each time activating, delete the prev palette (if
any) -- AKint resp = m_cPal.DeleteObject();
m_cPal.CreatePalette(pPal); LocalFree(pPa
l); pOldPal = dc.SelectPalette(&m_cPal, FAL
SE); dc.RealizePalette(); dc.Detac
h(); }}// Thisfunction computes the bounding bo
x parameters of the given part -// thex, y and z e
xtents, in global coordinates, for the orientation
specifiedby orient_matrix.// The computation is d
one with respect to the BM_POINT centroid as origi
n.// It does so by taking the bbox of each face, p
rojecting each onto the coordinate // axes, and th
en finding the extents along each axis. If threeD_
flag is non-zero, the// three-d version’s bboxis
computed; else, the flat’s bbox is computed. The
results of the// computation are put into the arry
bbox_size[3]; if this pointer is zero,no computat
ion// is performed. The offset, ie. the vector fro
m the centroid’s coords to the bbox center’s coo
rds,// is passed back in the pointer to the BM_VEC
TOR.// Returns 1 if successful, 0 otherwise.int CB
endCADViewPart::compute_part_bbox(BM_PART *part, i
nt threeD_flag, RwMatrix4d*orient_matrix,
BM_POINT centroid,dou
ble *bbox_size, BM_VECTOR *offset) { BM_FACE *fac
e = NULL; BM_BENDLINE *bendline = NULL; BM_2D_BO
DY *two_d_body = NULL; BM_LOOP *loop = NULL; BM_
POINT dot1, dot2, dot3, dot4; double left, right,
top, bot, front, back; // First two refer to
x direction, // last two to z direction. BM_VE
CTOR vec1; int first_pass = 1; float rot_matrix
[4][4];if(! part) return 0; if( (part->get_number
_of_faces() == 0) && (part->get_number_of_bendline
s() == 0) ) return 0; if(! bbox_size) return
0; if(! part->get_number_of_faces()) { // In this
case, find bendline bboxes. for(bendline = par
t->get_bendline_list(); bendline; bendline =(BM_BE
NDLINE *)bendline->next()) { // First check that
the bbox of thebloop 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 bbox coordinates, dot2 =
loop->get_bbox_p2() + (-1.0)*vec1;// with respect
to the dot3 = loop->get_bbox_p3() + (-1.0)*vec1;
// centroid as origin. dot4 = loop->get_bbox_p4()
+ (-1.0)*vec1; RwGetMatrixElements(orient_matri
x, rot_matrix); multiply_pt_by_matrix(&dot1, rot_
matrix);// Transform coords by the current multip
ly_pt_by_matrix(&dot2, rot_matrix);// rotation mat
rix. multiply_pt_by_matrix(&dot3, rot_matrix); m
ultiply_pt_by_matrix(&dot4, rot_matrix); if(first
_pass) { left = __min(dot1.X(), dot2.X());
right = __max(dot1.X(),dot2.X()); bot = __min
(dot1.Y(), dot2.Y()); top = __max(dot1.Y(), d
ot2.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,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 = __m
ax(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 = __m
in(back ,dot4.Z()); front = __max(front, dot3.
Z()); front = __max(front, dot4.Z()); } bbo
x_size[0] = right - left;bbox_size[1] = top - bo
t;// Copy bbox size into the array passed.bbox_siz
e[2] = front - back;if(offset) // Copy the bbo
x center into the pointer passed. *offset = BM_VE
CTOR((right + left)/2.0, (top + bot)/2.0, (front +
back)/2.0);mi_bbox_is_up_to_date = 1; return 1;
} // Faces are available, so find bbox offaces.
for(face = part->get_face_list(); face; face =
(BM_FACE *)face->next()) { if(! face) break;
// First check that the bbox of the bloop is up
to date; if not compute bbox.if(threeD_flag) two_
d_body = face->get_3D_version();else two_d_body =
face->get_flat();if(two_d_body) loop = two_d_body
->get_bloop();else continue;if(! loop) continue;if
(!(loop->is_bbox_up_to_date())) loop->recompute_bb
ox();// Now find the envelope (union) of the proje
cted bboxes.vec1 = BM_VECTOR(centroid.X(), centroi
d.Y(), centroid.Z());dot1 = loop->get_bbox_p1() +
(-1.0)*vec1;// The bbox coordinates,dot2 = loop->g
et_bbox_p2() + (-1.0)*vec1;// with respect to thed
ot3 = loop->get_bbox_p3() + (-1.0)*vec1;// centroi
d as origin.dot4= loop->get_bbox_p4() + (-1.0)*vec
1; RwGetMatrixElements(orient_matrix, rot_matri
x);multiply_pt_by_matrix(&dot1, rot_matrix);// Tra
nsform coords by the currentmultiply_pt_by_matrix
(&dot2, rot_matrix);// rotationmatrix.multiply_pt_
by_matrix(&dot3, rot_matrix);multiply_pt_by_matrix
(&dot4, rot_matrix);if(first_pass) { left = __mi
n(dot1.X(), dot2.X()); right = __max(dot1.X(), do
t2.X()); bot = __min(dot1.Y(), dot2.Y()); top
= __max(dot1.Y(), dot2.Y()); back = __min(dot
1.Z(), dot2.Z()); front = __max(dot1.Z(), dot2.
Z()); first_pass = 0;}else { left = __min(left,
dot1.X()); left = __min(left, dot2.X()); rig
ht = __max(right, dot1.X()); right = __max(right,
dot2.X()); bot = __min(bot , dot1.Y()); bot
= __min(bot , dot2.Y()); top = __max(top ,
dot1.Y());top = __max(top , dot2.Y()); back
= __min(back , dot1.Z()); back= __min(back , dot
2.Z()); front = __max(front, dot1.Z()); front =
__max(front, dot2.Z());}left = __min(left, dot3.
X());left = __min(left,dot4.X());right = __max(ri
ght, dot3.X());right = __max(right, dot4.X());bot
= __min(bot , dot3.Y());bot = __min(bot , d
ot4.Y());top =__max(top , dot3.Y());top = __m
ax(top , dot4.Y());back = __min(back, dot3.Z());
back = __min(back , dot4.Z());front = __max(fron
t, dot3.Z());front = __max(front, dot4.Z()); } b
box_size[0] = right - left; bbox_size[1] = top
- bot;// Copy bbox size into the array passed. bb
ox_size[2] = front - back; if(offset) // Copy
the bbox center into thepointer passed.*offset =
BM_VECTOR((right + left)/2.0, (top + bot)/2.0,(fro
nt + back)/2.0); mi_bbox_is_up_to_date = 1; retu
rn 1;}// This function computes the part’s centro
id. This is done with respect to// the original (g
iven) coordinates of the part. If threeD_flag is n
on-zero, the// three-d version’s centroid is comp
uted; else, the flat’s centroid is computed.// Th
e results are passed back in the pointer to a BM_P
OINT;if this pointer is NULL, no// computation is
done. Returns 1 if successful, 0 otherwise.int CBe
ndCADViewPart::compute_part_centroid(BM_PART *par
t, int threeD_flag, BM_POINT *centroid) { BM_FA
CE *face; BM_2D_BODY*two_d_body; BM_LOOP *loop;
BM_POINT dot1, dot2, dot3, dot4; doubleleft, ri
ght, top, bot, front, back; // First two refer to
x direction,// last two to z direction. int firs
t_pass = 1; if(! part) return 0;if( (part->get_nu
mber_of_faces == 0) && (part->get_number_of_bendli
nes== 0) ) return 0; if(! centroid) return 0;
for(face = part->get_face_list(); face; face =
(BM_FACE *)face->next()) { if(! face) break;//
First check that the bbox of the bloop is up to da
te; if not compute bbox.if(threeD_flag) two_d_bod
y = face->get_3D_version();else two_d_body = face
->get_flat();if(two_d_body) loop = two_d_body->get
_bloop();else continue;if(! loop) continue;if(!(lo
op->is_bbox_up_to_date())) loop->recompute_bbox();
// Now find the envelope (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(); if(first_pass) { left = __min
(dot1.X(), dot2.X()); right = __max(dot1.X(), dot
2.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()); rig
ht = __max(right, dot1.X()); right = __max(right,
dot2.X());bot = __min(bot , dot1.Y()); bot
= __min(bot , dot2.Y()); top= __max(top , dot1.
Y()); top = __max(top , dot2.Y()); back = __
min(back , dot1.Z()); back = __min(back , dot2.Z
()); front = __max(front, dot1.Z()); front = __m
ax(front, dot2.Z());}left = __min(left, dot3.
X());left = __min(left, dot4.X());right = __max
(right, dot3.X());right = __max(right, dot4.X());b
ot = __min(bot , dot3.Y());bot = __min(bot ,
dot4.Y());top = __max(top , dot3.Y());top =
__max(top , dot4.Y());back = __min(back , dot3.Z
());back = __min(back , dot4.Z());front = __max(f
ront, 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_part_centroid.set_X((right + left)/2.0);
m_3d_part_centroid.set_Y((top + bot )/2.0); //
このpartは3d重心である。 m_3d_part_centroid.se
t_Z((front + back)/2.0); } else { m_flat_part
_centroid.set_X((right + left)/2.0); m_flat_par
t_centroid.set_Y((top + bot )/2.0);// このpartは
平面重心である。 m_flat_part_centroid.set_Z((fr
ont +back)/2.0); }*/ return 1;}// This function
multiplies a bend model point by a 4x4 RenderWare
transform matrix.// The function is destructive.It
is NOT a BMAPPView member function.// Note that t
he point is considered to be a row vector; this is
// RenderWare’s (and the Bend Model’s) conventio
n. static void multiply_pt_by_matrix(BM_POINT *poi
nt, float rot_matrix[4][4]) { double x = point->X
(); double y = point->Y(); double z= point->Z();
point->set_X((x*rot_matrix[0][0] + y*rot_matrix
[1][0] +z*rot_matrix[2][0])); point->set_Y((x*rot
_matrix[0][1] + y*rot_matrix[1][1] + z*rot_matrix
[2][1])); point->set_Z((x*rot_matrix[0][2] + y*ro
t_matrix[1][2] + z*rot_matrix[2][2]));}// This fun
ction outlines the rectangular region selected by
the user.void CBendCADViewPart::outline_region(voi
d) { CClientDC view_dc(this); CPoint corner1_cur
r = m_lt_btn_down_point, corner2_curr = m_lt_btn_d
own_point; CPoint corner1_prev = m_lt_btn_down_po
int, corner2_prev = m_lt_btn_down_point; corner1_
curr.Offset(m_current_point.x - m_lt_btn_down_poin
t.x, 0); corner2_curr.Offset(0, m_current_point.y
- m_lt_btn_down_point.y); corner1_prev.Offset(m_
previous_point.x - m_lt_btn_down_point.x, 0); cor
ner2_prev.Offset(0, m_previous_point.y - m_lt_btn_
down_point.y); view_dc.SetROP2(R2_NOT); view_dc.
MoveTo(m_lt_btn_down_point); view_dc.LineTo(corne
r1_prev); view_dc.MoveTo(m_lt_btn_down_point); v
iew_dc.LineTo(corner2_prev); view_dc.MoveTo(corne
r1_prev); view_dc.LineTo(m_previous_point); view
_dc.MoveTo(corner2_prev); view_dc.LineTo(m_previo
us_point); view_dc.MoveTo(m_lt_btn_down_point);
view_dc.LineTo(corner1_curr); view_dc.MoveTo(m_lt
_btn_down_point); view_dc.LineTo(corner2_curr);
view_dc.MoveTo(corner1_curr); view_dc.LineTo(m_cu
rrent_point); view_dc.MoveTo(corner2_curr); view
_dc.LineTo(m_current_point);}// This function proc
esses the hits record to pick out the edge(s) sele
cted by the// user. If add_hit_to_list is non-zer
o, which it is if the control button is held down,
// the current hit, ifany, is added to the selecti
on set; else, the selection set// is cleared and
only the current hit is added to the list. If ther
e is no hit, the // selection set is cleared as we
ll, unless add_to_list is non-zero, in which case
// nothing happens. // This function recognizes tr
ivial bendlines and formings and modifies the sele
ction set// appropriately. voidCBendCADViewPart::p
rocess_hits_record(int add_hit_to_list){ RwClump
*picked_clump = NULL; RwClump *parent_clump = NUL
L;RwV3d vert; long parent_tag, clump_tag, three_d
_type = 0, offset = 0, key = 0; int num_hits= -3,
j; unsigned long z_max = 0UL, z_min = ULONG_MAX,
name_id = 0UL;unsigned int *ptr = mw_selected_obj
ects; BM_EDGE *edge = NULL;long old_data; if(mi_
show_solid) {// RenderWare picking. if(m_pick.t
ype == rwNAPICKOBJECT) { // No cl
ump was picked. if(add_hit_to_list) return;el
se clear_selection_set();return; } else if(m
_pick.type == rwPICKCLUMP) { // So
me clump was picked; process it. picked_clump
= m_pick.object.clump.clump;vert = m_pick.object.
clump.wcpoint; RwTranslateMatrix(RwScratchMat
rix(), CREAL(md_x_trans), CREAL(md_y_trans), CREAL
(0.0), rwREPLACE); RwTransformMatrix(RwScrat
chMatrix(), md_rot_matrix, rwPRECONCAT); RwTr
anslateMatrix(RwScratchMatrix(), CREAL(- m_part_ce
ntroid.X()), CREAL(- m_part_centroid.Y()),
CREAL(- m_part_centroid.Z()), rwP
RECONCAT); RwMatrix4d *inverse = RwCreateMatri
x();RwInvertMatrix(RwScratchMatrix(), inverse);RwT
ransformPoint(&vert, inverse);RwDestroyMatrix(inve
rse);parent_clump = RwGetClumpParent(picked_clum
p);parent_tag = RwGetClumpTag(parent_clump);clump_
tag = RwGetClumpTag(picked_clump);if(parent_tag==
1) {// The body of a face/bendline/forming was pic
ked.key = (clump_tag%10000)*100000 + clump_tag;
if(m_selection_set.find(key, NULL)) {m_selectio
n_set.remove(key, &old_data); // Removeclum
p from selection set (toggle).if(old_data) delete
(BV_SELECT_DATA *)old_data;return;}else {if(! add_
hit_to_list) clear_selection_set(); //Remove ever
ything else 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, (lon
g)data);// insert this key and data.return;}}// No
w an edge was picked.key =(parent_tag%10000)*10000
0 + clump_tag; if(clump_tag) {// Safety check;we e
xpect clump_tag to be non-zero.if(m_selection_set.
find(key, NULL)){m_selection_set.remove(key, &old_
data); // Remove clump from selection set
(toggle).if(old_data) delete (BV_SELECT_DATA *)old
_data;} else {if(! add_hit_to_list) clear_selecti
on_set(); // Remove everything else in selection
set. edge = map_list_name_to_bm_edge(parent_tag, c
lump_tag);BV_SELECT_DATA *data = new BV_SELECT_DAT
A;data->key = key;data->edge= edge; (data
->world_pt) = BM_POINT(vert.x, vert.y, vert.z);m_s
election_set.insert(key, (long)data);// insert thi
s key and data.}}} } else {// OpenGL Picking.
num_hits = glRenderMode(GL_RENDER);// The number
of hits. if(num_hits == -1) {// Selection buff
er has overflowed. AfxMessageBox("Too many en
tities selected; change view and try again.");retu
rn; } if(num_hits == 0) {
// No hit; only a miss.if(add_hit_to_list)
return;else clear_selection_set();return; }//
Process the hits : find the edge with LOWEST z val
ue of all the edgespicked. for(j=0; j < num_hit
s; ++j) { ptr += 1;// Skip the 1st elem
ent bec. it will always be 1,if( (unsigned long)(*
ptr) < (unsigned long)z_min) {z_min = (unsigned lo
ng)(*ptr); ptr += 2;name_id = (long)(*ptr); ++pt
r;}else ptr += 3; } // Find the bm edge c
orresp. to the name and add it to the selection se
t.if(name_id) { /
/ Something was selected. if(m_selection_set.
find(name_id, NULL)) {m_selection_set.remove(name_
id, &old_data); // Remove edge fromselection se
t (toggle).if(old_data) delete (BV_SELECT_DATA *)o
ld_data;}else {if(! add_hit_to_list)clear_selectio
n_set();// First, we massage the name_id into the
formatRenderWare picking uses.parent_tag = name_id
/100000 + 10000;clump_tag =name_id%100000;edge = m
ap_list_name_to_bm_edge(parent_tag, clump_tag);BV_
SELECT_DATA *data = new BV_SELECT_DATA;data->key =
key;data->edge = edge; (data->world_pt) =
BM_POINT(0.0, 0.0, 0.0);m_selection_set.insert(nam
e_id, (long)data);// insert this key and data.}
} } return;}// This function maps a RenderWare
parent clump and child clump pair tothe // Bend M
odel edge which the child clump represents. The po
inter tothe edge is returned.// This function only
needs to deal with "real" edges, ie. trivial bend
lines and// formings are filtered out by process_h
its_records itself.BM_EDGE *CBendCADViewPart::map_
list_name_to_bm_edge(long parent_tag, long clump_t
ag) { long three_d_name, three_d_type, loop_name,
edge_name, count = 0, offset = 0; BM_3D_BODY *th
ree_d_body = NULL;BM_2D_BODY *two_d_body = NULL;
BM_LOOP *loop = NULL; BM_EDGE *edge =NULL; BM_PA
RT *part = NULL; BM_TOPOLOGY *topology = NULL; C
BendCADDoc* pDoc = GetDocument(); ASSERT_VALID(pD
oc); part = pDoc->get_part();if(! part) return NU
LL; // Note: we do not expect part to be NULL at
this stage. topology = part->get_topology(); if
(! topology) return NULL; three_d_name = parent_t
ag%10000; three_d_body = topology->map_id_into_po
inter(three_d_name); // Now we have a 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_FORM
ING)offset = 90000; loop_name = (clump_tag - offs
et)/100; edge_name = (clump_tag - offset)%100; i
f(loop_name == 0) return NULL; // This should ne
ver be the case. // Now have the edge_name-th edg
e in the loop_name-th loop of the face/bendline/fo
rming. // Now we have the face/bendline to which
the edge belongs. if(mi_show_3d) two_d_body = thr
ee_d_body->get_3D_version(); else two_d_body = t
hree_d_body->get_flat(); if(! two_d_body) return
NULL; if(loop_name == 1) loop = two_d_body->get_b
loop(); else { count = 1; for(loop = two_d_
body->get_first_hole(); loop; loop = (BM_LOOP *)lo
op->next()) { if(! loop) return NULL; ++count;
if(count == loop_name) break;} } // Now we have
the loop to which the edge belongs. if(loop == NU
LL) return NULL;// A trivial bendline was picked.
count = 0; for(edge = loop->get_first_edge(); e
dge; edge = (BM_EDGE *)edge->next()) {if(! edge) b
reak;++count;if(count == edge_name) break; } //
Now we have the edge itself.return edge;/* three_
d_name = list_name/10000; loop_name = list_name%1
0000; // loop_name-th の中の edge_name 番目の ed
ge loop_name /= 100; // loop of the three_d_na
me 番目のthree-d-body, edge_name = list_name%100;
//最初のthree-d-bodyとして最初のベンドラインと
共にに開始. if(three_d_name > (ml_num_bendlines +
ml_num_faces)) return NULL;// 描かれるものは
フォーミングである。 if(! loop_name) returnNULL;
// 描かれるものはトリビアルなベンドラインであ
る。 if(three_d_name > ml_num_bendlines) { //
three_d_body は面である。 for(three_d_body = pa
rt->get_face_list(); three_d_body;
three_d_body = (BM_3D_BODY *)three_d_bo
dy->next()) { if(! three_d_body) return NULL;
++count; if((ml_num_bendlines + count) == three
_d_name) break;} } else { // three_d_body はベ
ンドラインである。 for(three_d_body = part->get
_bendline_list(); three_d_body;three_d_body = (BM_
3D_BODY *)three_d_body->next()) { if(! three_
d_body) return NULL; ++count; if(count == three_
d_name) break;} }// この時点でエッジが属する面/ベ
ンドラインを持つ。 if(mi_show_3d) two_d_body = th
ree_d_body->get_3D_version(); else two_d_body = t
hree_d_body->get_flat(); if(! two_d_body) return
NULL; if(loop_name == 1) loop= two_d_body->get_bl
oop(); else { count = 1; for(loop = two_d_b
ody->get_first_hole(); loop; loop = (BM_LOOP *)loo
p->next()) { if(! loop) return NULL; ++count; i
f(count == loop_name) break;} }// この時点でエッ
ジが属するループを持つ。 count = 0; for(edge = l
oop->get_first_edge(); edge; edge = (BM_EDGE *)edg
e->next()) {if(! edge) break;++count;if(count == e
dge_name) break; } return edge;*/} // This func
tion returnsthe number of items currently in the s
election set.long CBendCADViewPart::get_number_of_
selected_items(void){ return m_selection_set.list
_size();}/* これにより、他のクラスが選択セットを得
ることができる。選択された項目は、配列selected_ite
ms_array 内でパスバックされる; それは、この配列が
十分な大きさであることを保証するユーザの義務であ
る。サイズnum_requested*2 の配列は確かに十分であ
る。この関数は、もし多くのものが得られるときは、 n
um_requested 項目までパスバックする。戻り値は、実
際にパスバックされた項目の個数である。配列中の復帰
された項目のフォーマットは次のように与えられる。 s
elected_items_array[2*i -2] は描かれたエッジのOpen
GL Display List idを含み、またselected_items_array
[2*i -1] はそのエッジに対するベンドモデルポインタ
を含む。例えば、 selected_items_array[0], selected
_items_array[1]は, 選択セットなど, 選択セット中のn
um_requested番目の項目に対する配列[2*num_requested
-2], 配列array[2*num_requested -1] までの全てのも
のを含む。エッジポインタがNULLのときは更に、 N を
このエッジのopenG1 display list id (N は長いタイ
プ)とする必要がある。ケース A): もし N/10000> (n
um_bendlines_in_part + num_faces_in_part) ならば、
ユーザはN-(num bendlines + num faces)のフォーミン
グを取り上げている。例えば、num bendlines = 4, num
faces = 3, num formings = 5, N/10000 =9, などの
エッジポインタは空である。このとき、ユーザは二回目
のフォーミングを取り上げている。
【0379】ケースB): もし(N%10000)/100 == 0 (すな
わち、N の100 番目の桁がゼロ) ならば、ユーザはトリ
ビアル(曲げられてない)なベンドラインのセンタライン
を取り上げている。ベンドラインは(N/10000) 番目のベ
ンドラインである。例えば、N/10000 = 3, エッジポイ
ンタはNULLであり,(N%10000)/100=0 である。ユーザ
は、たまたま曲げてない第三番面目のベンドラインを取
り上げている。(あなたが驚いても、この部分は少なく
とも3 個のベンドラインを持つことが保証される。
【0380】)*/long CBendCADViewPart::get_selected
_items(long num_requested, long *selected_items_ar
ray) { if(selected_items_array == NULL) return 0;
longi = m_selection_set.display(num_requested, s
elected_items_array); return i;} // This allows
others to clear the selection set.void CBendCADVie
wPart::clear_selection_set(void){int size = m_sele
ction_set.list_size(); long *array = new long[(siz
e<<1) + 1]; m_selection_set.display
(size, array);for(long i=0; i < size; ++i) { if(a
rray[(i<<1) + 1]) delete (BV_SELECT_DATA *)array
[(i<<1) + 1];} m_selection_set.remove();delete []
array;}// This function writes a RenderWare matri
x’s rotation part into an array[16], which can be
used by// OpenGL. int CBendCADViewPart::convert_r
w_matrix_to_gl_array(RwMatrix4d *rw_matrix, double
*array){ RwReal rw_array[4][4], *test; test = R
wGetMatrixElements(rw_matrix, rw_array); if(! tes
t) return 0; int i, j; for(i=0; i < 4; ++i) {for
(j=0; j < 4; ++j) array[4*i + j] = rw_array
[i][j]; } array[15] = 1.0; array[3] = array[7]
= array[11] = 0.0; return 1;} // Thisfunction
allows you to set the drawing mode: show_solid = 1
for solid,0for wireframe.// This function assumes
that the part has not changed.void CBendCADViewPa
rt::set_drawing_mode(int show_solid){ if(show_sol
id) OnViewShaded();else OnViewWireframe();}// This
function allows you to setthe current view of the
part: show_3d = 1 for 3d version,// 0 for flat.//
This function assumes that the part has not chang
ed.void CBendCADViewPart::set_current_view(int sho
w_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 pictureshown is top vi
ew, zoomed-all.// If 3d is asked for and flat is c
urrently in view, the picture shown is 3d, isometr
ic, zoomed-all.// If 3d is asked for and 3d is alr
eady currently in view, the view volume is not cha
nged.// If part_has_changed is not zero, re-faceti
ng is done.void CBendCADViewPart::set_drawing_view
_mode(int show_solid, int show_3d, int part_has_ch
anged){int show_3d_isometric = 0;if( (! mi_show_3
d) && (show_3d) )show_3d_isometric = 1;mi_show_sol
id = show_solid;mi_show_3d = show_3d;int i; BM_PA
RT *part = NULL; CBendCADDoc* pDoc = GetDocumen
t(); ASSERT_VALID(pDoc); part = pDoc->get_par
t(); if(! part) { mi_part_is_up_to_date = 0;
return; } mi_part_is_up_to_date = 1;if(part_has_
changed){ compute_part_centroid(part, 0, &m_fla
t_part_centroid); // Compute3d and flat part centr
oids. compute_part_centroid(part, 1, &m_3d_part
_centroid); }if(mi_show_solid) { // Renderware s
tuff.if(mi_show_3d) {if(part_has_changed || (! m_3
d_base_clump)) { i = facet_part_rw(part, &m
_3d_base_clump, mi_show_3d, md_part_color); i
f( (! i) || (! m_3d_base_clump) ) return;}RwRemove
ClumpFromScene(m_base_clump); m_base_clump = m_
3d_base_clump; RwAddClumpToScene(m_scene, m_bas
e_clump);}else { if(part_has_changed || (! m_flat
_base_clump)) { i = facet_part_rw(part, &m_
flat_base_clump, mi_show_3d, md_part_color);
if( (! i) || (! m_3d_base_clump) ) return;}RwRemov
eClumpFromScene(m_base_clump); m_base_clump = m
_flat_base_clump; RwAddClumpToScene(m_scene, m_
base_clump);}}else {// OpenGl stuff. i = prepa
re_display_list(part, mi_show_3d, 1, 0, 1, 1, md_f
ace_color, md_bendline_color); if(!i) { mi
_display_list_is_up_to_date = 0; return; }
mi_display_list_is_up_to_date = 1; if(mi_show_3
d) { mi_3d_is_up_to_date= 1; mi_flat_is
_up_to_date = 0;}else { mi_3d_is_up_to_date =
0;mi_flat_is_up_to_date = 1;}} mi_bbox_is_up_to_
date = 0;if(mi_show_3d) m_part_centroid = m_3d_par
t_centroid;else m_part_centroid = m_flat_part_cent
roid;if(part_has_changed) {ml_num_faces = part->ge
t_number_of_faces();ml_num_bendlines = part->get_n
umber_of_bendlines();ml_num_formings= part->get_nu
mber_of_formings();} ml_last_function_chosen = RE
TURN_FROM_DIALOG_MODE;if(show_3d_isometric) { OnZ
oomAll();return;}if(! mi_show_3d) { OnViewTop();r
eturn;}return;} 付録F コメント付きファイルを含むメインを自動寸法化するBM
APIの例/*一般的注意:---------------***************
---------------一般的注意:−自動寸法化パッケージ
はそのパートが既に更新されている(すなわちパートの
3Dバージヨンが既に計算されている)と仮定する。そ
のパートの現在の3Dバージヨンを取り、それを用い
る。−04/02/96付の自動寸法化は、単にパートの3Dバ
ージヨンに対する寸法を生成する。−04/02/96付の自動
寸法化は、パートが厚みを持って示されていると仮定す
る(すなわち、それは、我々が薄板の一側を示していな
いと仮定する。)。概要 :---------------***********
****---------------自動寸法は2種類の描画を行う:-
全てのベンドラインに対するフランジ長さ- 全てのベン
ドラインに対するベンドライン情報ベンドライン情報
は、それが係わるベンドラインを指示する小さなinfo-b
ox内に描かれれる。このinfo-boxを描画する際の唯一の
問題点は、ベンドラインが可視であるか、どこにinfo-b
oxを描くか(すなわち、それが良好に見え、他の成分に
干渉せず、例えば、他の事物と重ならないようにそれを
描く画面上の場所)、如何にそれをベンドラインと関係
付けるかということにある。この成分は比較的容易であ
る。ベンドラインのフランジ長さは、ベンドラインとこ
のベンドラインの側部の隣接フランジとの間の最大外側
距離により与えられる。ベンドラインは高々2つの隣接
フランジを持つことが出来、従って両隣接フランジに対
してフランジ長さを描かなければならないという点に注
意されたい。実際、フランジ長さは、我々がディメンシ
ョンポイントと呼ぶ点の間で(距離として)描かれる。
ここには2種類のディメンションポイントがある。第一
のものはベンドラインディメンションポイントである。
フランジ長さはベンドラインと隣接フランジの間の(最
大外側)距離なので、ベンドラインの側部のこれらのデ
ィメンションポイントはベンドラインディメンションポ
イントと呼ばれる。それらの位置は厳密にベンドライン
により定義される。
【0381】1本のベンドラインは隣接フランジの各々
に関して正確に2つのベンドラインディメンションポイ
ントを持つことが出来る(少なくとも、 BendModel/Ben
dCADの現在のバージヨンでは)という点に注意された
い。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 inorder to save time.// when
two bendlines are using equivalent flange-dimensio
n points for (potentially)// displaying flange-len
gth, we will onlycompute the visibility informatio
n only// for the bendline (of these twobendlines)
which has the larger idx.// // this is initialized
to FALSE,and set to TRUE only after all other dim
-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// b
endline (either inside or outside) such that the r
adius and thickness both are not 0,// we haveto dr
aw two short lines (as in the picture following) t
hat connect the//outsides of adjacent flanges. How
ever, sometimes (when both radius andthickness //
are 0, or the point is just an outside edge of a f
ace) weneed only one point.// To capture these two
cases, we either compute three points between whi
ch the // short line have to be drawn, or just one
point (in which case no short lines are needed)./
/ // ------------ p2// | \|///
| p ----------bbFFFFFFFFFFFF// ||
bbb F// two | | bbb F// short --
---> | b F// lines | b bbFFFFFFF
FFFFF// |b b // |b b // bb //
b b// p1 FFFFFFFF// F F// F F// F F/
/ FF// F F// // this is the number of points tha
t we have computed here. itis either 1 or 3.// int
num_of_points ;// // p is always the centerpoint
to which the dimension arrow should be connected t
o// (actually it iswhat we call a ’dimension-line
-extension’).// if we have computed morethan 1 po
int, p1 and p2 are the side-points.// // IMPORTANT
: p1 is onthe plane of the adjacent body for whic
h the flange length is being drawn.// // Note : po
int p is always computed.// BM_POINT p, p1, p2 ;//
thisvariable is used when this dimension point is
a flange dimension point,and// the edge in the fl
ange, for which this flange dimension points was c
omputed, // is adjacent to a bendline. adj_bendlin
e points to that bendline.// // this is used to av
oid drawing some flange-length twice. forexample,
in this picture// // B2-----------------// |//
| A// |// |// --------------
-B1// // we want to draw dimensions for face A in
the middle only once. That means that if// we draw
flange length for bendline B1 with respect to A,
we should not draw it for //bendline B2 (with resp
ect to A).// BM_BENDLINE *adj_bendline ;// this ve
ctor points to the direction in which the dimensio
n should be drawn forthis dim-point.// // IMPORTAN
T : this vector should be normalized.// BM_VECTOR
opening_direction ;// // if this is TRUE, we can r
everse the opening_direction if we need.// sometim
es the dimension point correcponds to an extreme p
oint of an arc. in that case it does// not matter
on whichside 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 drawn./
/ pos_len is the length of the dimension-line-exte
nsion drawn in the direction of the openingvector.
// neg_len is the length of the dimension-line-ext
ension drawn inthe direction opposite to // the op
ening vector.// // they are initially set to 0 whe
n the visibility of this point is computed.// // t
he purpose is that we can use them to avoid redraw
ing the same extension line, if several // other d
imension points need it.// // Note : as of 04/02/9
6these points are not used. KK.// double pos_len,
neg_len ;// +1, this dimension point is visible an
d the dimension arc can be drawn for this point.//
0, this dimension point is not visible.// -1, we
don’t know if this dimension points is visible./
/ // initially we set this to -1 and use it to com
pute the visibility information on demand// (ie. o
nly when wewant to know if this points is visible.
sometimes we don’t care).// int visible ;// thes
e are the actual view window coordinates of all 3
points.// int screen_x, screen_x1, screen_x2 ;int
screen_y, screen_y1, screen_y2 ;// // this is the
z-buffer value of the point p when rendered.// dou
ble z_buf_value ;// this is used to construct list
s of dim-points.// BM_AD_dim_corner *next ;/******
***** ********** ********** ********** **********
********** ********** ********** **********Private
のメンバ関数。
【0382】自動寸法によってのみ用いられる。******
**** ********** ********** ********** ********** *
********* ********** ********** ***********/// thi
s function computes the visibility of this dimensi
on point.// it handles wireframe and solid modes s
eparately.// this function checks strict visibilit
y.// void compute_visibility(CBendCADViewPart *vie
w) ;// this function will draw the dim-point in th
e given device context.// this is really just a de
bug function.// void draw_with_dim_line(CBendCADVi
ewPart *view, CDC *dc, double object_space_per_pix
el) ;// given a bendline dimension point and a lis
t of flange dimension points, this function// retu
rns TRUE iff there is a way to display the flange-
length-dimension using these points // (ie. there
is a pair of points that is visible) or FALSE if n
ot.// If it returns TRUE, it also returns the best
flange dimension point ;as well as// the distance
between the bendline dimension point p and thebes
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_p
er_pixel, // OUTPUT parametersdouble *best_distanc
e /* distance of thebest flange-dim points found *
/,BM_AD_dim_corner **best_flange_dim_point/* the b
est flange-dim points */) ;// this function draws
one flange length dimension. the first argument is
a bendline dimension point,// thesecond is a flan
ge dimension point.// this function might allow ca
ses where some 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
iew window.// friend void 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) ;/*********** ********** *
********* ********** ********** ********** *******
*** ********** **********公共のメンバ関数*********
* ********** ********** ********** ********** ****
****** ********** ********** ***********/public :B
M_AD_dim_corner(void) ;// thisconstructor is for c
reating a dimension point that has only one point
(point p) 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 pointsin it.// BM
_AD_dim_corner(BM_POINT const& p, BM_POINT const&
p1, BM_POINT const& p2, BM_AD_bendline *bend, BM_3
D_BODY *body_required_visible, BM_VECTOR const& op
ening_direction, int reverse_bit, BM_AD_dim_corner
**prev, BM_BENDLINE *adj_bendline) ;// to assign
one dimension point to another dimension point// i
t copies contents exactly. not sure if it is a ver
y useful function.// void operator=(BM_AD_dim_corn
er const &) ;// thisfunction will return TRUE iff
the given point is, for the purpose of drawing dim
ensions,// the same as this point. // Two dimensio
n points points are equivalent iff the point p of
one of them is on the// line definedby the line (p
oint p, opening direction) of the other dimension
point,// and their opening directions match.// //
here we depend on the fact that opening vectors ar
e normalized.// // it returns 2 iff both points p
match, otherwise 1.// int operator==(BM_AD_dim_cor
ner const& another_dim_point) ;} ;/*********** ***
******* ********** ********** ********** *********
* ********** ********** ********** この種の対象物
は、1ベンドラインに係わる自動寸法化データを表す。
ベンドラインに対する基本のAD操作は隣接するフラン
ジ長さを描くことである。技術的注意 :- tベンドライ
ンディメンションポイントとフランジディメンションポ
イントの開放方向ベクトルは相関付けされない。それ
は、あなたは、同じ開放方向を持つ2点に対シテチェッ
クするべきである。- アルゴリスム:先ず、我々は全て
のベンドラインに対する全てのベンドラインディメンシ
ョンポイントを計算する。次に、我々は、全てのベンド
ラインに対する全てのフランジディメンションポイント
を計算する。その理由は、我々がフランジディメンショ
ンポイントを計算するとき、フランジ内の、および他の
ベンドラインに隣接する幾つかのエッジがあるというこ
とである。全てのベンドラインディメンションを先ず計
算するときは、他のBM_AD_bendline構造のベンドライン
ディメンションポイントからこれらのベクトルを取るこ
とが出来る。
【0383】********** ********** ********** *****
***** ********** ********** ********** **********
********** */class BM_AD_bendline{friend BM_AUTO_D
IMENSION ;friend BM_AD_dim_corner ;/*********** **
******** ********** ********** ********** ********
** ********** ********** **********全てのデータメ
ンバはprivateなものである。********** ********** *
********* ********** ********** ********** *******
*** ********** ***********/private :/*********** *
********* ********** ********** ********** *******
*** ********** ********** **********これらのデータ
メンバはコンストラクタにより設定される。**********
********** ********** ********** ********** *****
***** ********** ********** ***********/// informa
tion stored in this BM_AD_bendline object refers t
o this bendline.// ie. this dimension point is dra
wn to show the flange length of this bendline.// B
M_BENDLINE *bend ;// thisobject belongs to this Au
to-Dimension object.// BM_AUTO_DIMENSION *parent ;
/*********** ********** ********** ********** ****
****** ********** ********** ********** **********
これらのデータメンバは、ベンドラインディメンション
ポイントデータ構造が、 BM_AD_bendline::compute_BM_
AD_bendline(...).で計算されるとき計算される。*****
***** ********** ********** ********** **********
********** ********** ********** ***********/// if
FALSE, this data for this object has not been yet
computed, or the computation failed.// this means
that this object will always be ignored, no matte
r what.// this can be set to TRUE only by BM_AD_be
ndline::compute_BM_AD_bendline(...).// int data_va
lid ;// number of adjacent bodies for whichwe have
to draw dimensions. either 0, 1 or 2.// int num_o
f_adjacent_bodies ;// every bendline is adjacent t
o at most two bodies.// either of these can be NUL
L. you should always check for that.// // adj_body
1 is theadjacent body that has the smaller idx.//
adj_body2 is the adjacent bodythat has the larger
idx.// BM_3D_BODY *adj_body1 ;BM_3D_BODY *adj_body
2;// this is the flange length with respect to eac
h of the adjacent bodies// double fl1 ;double fl2
;/*These parameters are computed some time during
the process and are needed later, so forperforman
ce reasons we store them so that we don’t have to
recompute them later.Each of them is avector poin
ting towards the adjacent body (from the bendline)
and isona plane tangent to end end-point of the b
end-arc touching the adjacentbody.*/BM_VECTOR side
_vector1 ;BM_VECTOR side_vector2 ;/*これらのパラメ
ータは、プロセス中にしばしば計算され、後に必要とさ
れ、そこで性能理由に対して我々はそれらを、我々がそ
れらを後に再計算する必要がないように格納する。
【0384】それらの各々は(ベンドラインから)隣接
体に向け指示するベクトルであり、隣接体に接触するベ
ンドアークの端点に対して接線をなす平面上にある。
これらは主要データ構造の幾つかである。 各々の隣接
体に対して、ベンドラインの各々の端点(すなわち、左
および右)に対して1つの2つ端点を持つ。これらの点
は、フランジ長に対する寸法がベンドラインで(すなわ
ち、ベンドラインの側部で)描くことが出来る点を特定
する。注意:現在(04/02/96)、我々は全ての
ベンドラインにおいてディメンションを描くため正確に
2つの可能な点を考える。これらの2つの点はベンドラ
インセンタラインの方向のベンドラインの2つの最端点
である。注意:これらはベンドラインのベンドラインデ
ィメンションポイントと呼ばれる。注意:これらの点
は、例えadj body1およびadj body2
が空であっても常に計算される。*/BM_AD_dim_corner b
end_body1_point_left, bend_body1_point_right ;BM_A
D_dim_corner bend_body2_point_left, bend_body2_poi
nt_right ;// these variables indicate whether thel
eft(right) bendline dimension points // with respe
ct to adj-body1 andadj-body2 are respectively equi
valent.// these points should be computedright aft
er bend_body1_point_left, bend_body1_point_right,/
/ bend_body2_point_left, bend_body2_point_right ar
e computed.// // if 0, they are notequivalent.// i
f 2, they are equivalent, and points p match.// if
1, they are equivalent, but points p don’t match
(ie. on the same line, butsome distance apart).//
// for us, equivalence value 2 is the only really
useful one, because in that case we can // trust
that when one is visible, the other is too, withou
t checking. in that case they have the// same scre
en coordinates as well.// // note the same means n
ot the same pointers, but the contents are equival
ent.// int body12_left_the_same ;intbody12_right_t
he_same ;/*ここにディメンションポイントの2つのリ
ストがある。1つはadj-bodyに関するもので、他はad
j−body2に関するものである。両リストはフラン
ジ長ディメンションポイントである点を含む。注意:こ
れらはベンドラインのフランジディメンションポイント
と呼ばれる。*/BM_AD_dim_corner *body1_points ;BM_A
D_dim_corner *body2_points ;/*********** *********
* ********** ********** ********** ********** ****
****** ********************これらのデータメンバ
は、ディメンションが描かれるとき用いられる。******
**** ********** ********** ********** ********** *
********* ********** ********** ***********/// if
this is TRUE, this bendline structure should be ig
nored for the purpose of drawing dimensions.// thi
s is usually used when we have a simultaneous bend
line. in that case we have todraw// dimensions for
only one of them, the rest should be ignored.// i
nt ignore ;// if TRUE, the adjacent body already h
as its flange length drawn.// // if the value is
2, this bendline drew the flange dimension with re
spect to the adj body.// if the value is 1, some o
ther bendline drewthe flange dimension with respec
t to the adj body.// int body1_drawn ;int body2_dr
awn ;// when we draw flange length for adjacent bo
dies, we will memorize the point at which the// di
mensions were drawn.// actually the dimensions are
always drawn between two points - one at the bend
line,// the other at the farthest point on the adj
acent body (ie. bendline dimension point and// fla
nge dimension point).// // the reason we need tome
morize these points is that sometimes the flange-l
ength-dimension// with respect to one bendline is
also the flange-length dimension with respect to t
he// other bendline. in that case we want to avoid
drawing the same thing twice.// // the first two
points are bendline dimension points.// other two
are flange dimension points.// // reason #2 : when
we drawbendline dimensions with respect to adj-bo
dy1 and adj-body2,// it depends whether the bend a
ngle is acute or not. if the bend angle is not mor
ethan// 90 degrees, then most likely we will be ab
le to use the same dimension-point at the bendline
// to draw both flange length’s. However, if the
bend angle is more than 90 degrees, we will// be u
sing the tangent-dimension-point at the bendline a
nd these points are different for// each adjacent
body. In general, we want to know, before we draw
a dimension-point at a// bendline, if we can use a
ny of the dimension-points already drawn at this b
endline.// // note these points do not have to par
t ofthis AD_bendline structure.// BM_AD_dim_corner
*drawn_bend_dim_point1 ;BM_AD_dim_corner *drawn_b
end_dim_point2 ;BM_AD_dim_corner *drawn_flange_dim
_point1 ;BM_AD_dim_corner *drawn_flange_dim_point2
;/*********** ********** ********** ********** **
******** ********** ********** *******************
*Privateメンバ−関数********** ********** ********
** ********** ********** ********** ********** ***
******* ***********/// This function computes bend
line dimension points of this BM_AD_bendline struc
ture.// Note that bend-dimension points will alway
s be computed, even if adj_body1 and adj_body2// a
re NULL.// int compute_BM_AD_bendline(void) ;// Th
is function computes flange dimensions points of t
his BM_AD_bendline structure // with respect to on
e 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-d
imension points with respect to adj-body1 is alway
s// computed, even if adj_body1 pointer is NULL.//
This is needed for drawing bendline info-boxes.//
void compute_bendline_dim_points_visibility(void)
;//this function computes which dimension points
are best to draw flange length for this bendline./
/ // this function does it strictly for one bendli
ne.// void compute_dim_points_to_display_indiv(BM_
AD_bendline *best_AD_bendline[2] /* best AD_bendli
ne structure so far */, BM_AD_dim_corner*bodies_be
nd_flange[6] /* 0,1 is bend-dim points; 3,4 is fla
nge-dim points; 4,5 is flange lists */,double dist
ance_and_z[4] /* 0,1 is distance;3,4 is z-buf */)
;// this function does it for a given bendline, t
akinginto account simultaneous bendlines.// this f
unction uses the previousfunction.// void compute_
dim_points_to_display(void) ;// this function draw
s flange length dimensions for this bendline.// it
uses the information computed by compute_dim_poin
ts_to_display() function.// void draw_dimension_po
ints(void) ;/*********** ********** ********** ***
******* ********** ********** ********** *********
* **********公共メンバ−関数********** **********
********** ********** ********** ********** ******
**** ********** ***********/ public :
// some trivial constructors,destructors.BM_AD_ben
dline(BM_AUTO_DIMENSION *owner, BM_BENDLINE *bendl
ine) ;~BM_AD_bendline(void) ;} ;/*********** *****
***** ********** ********** ********** **********
********** ********** ********** この対象物は部分
に対して自動ディメンションを生成するために用いるこ
とが出来る。********** ********** ********** *****
***** ********** ********** ********** **********
********** */class BM_AUTO_DIMENSION{friend BM_AD_
dim_corner ;friend BM_AD_bendline ;/*********** **
******** ********** ********** ********** ********
** ********** ********** **********すべてのデータ
メンバはprivateである。********** ********** *****
***** ********** ******************** ********** *
********* ***********/private :// this is the docu
ment to which this auto-dim object is attached to.
// also, this is where we get the part.// CBendCAD
Doc *doc ;// view in which we draw the dimensions.
// usually the view attached to the document.// CB
endCADViewPart*view ;int view_size_x, view_size_y
;// device context in which we drawthe dimension
s.// CDC *dc ;// this is the part for which we wil
l createdimensions.// BM_PART *part ;// is TRUE if
f 3D view is being displayed,FALSE if flat.//int v
iew_type ;// half of the metal thickness// doubleh
alf_metal_thickness ;// if TRUE, we need to recomp
ute auto dimension bendline and point data structu
res// int dirty ;// number of bendlines in the par
t// int num_of_bendlines ;// this is an array of b
endlines for which flange length has to be drawn./
/ BM_AD_bendline **bends ;// this is the distance
in object space that gets mapped into one pixel on
the screen.// we use it to draw lines of fixed pi
xel length (in that case object-space length varie
s).// double object_space_per_pixel ;// if this va
riable is TRUE, it will set the flag which will tr
igger// auto-dimensions tobe drawn to FALSE in the
view class, once dimensions are drawn.// however,
once it is done, this variable will be set to FAL
SE automatically.//int reset_view_to_false_once_dr
awn ;// every time we construct new dim-point data
structures, we set this to FALSE.// when points w
hich can beignored in solid mode have been compute
d, we set it to TRUE.// int points_to_ignore_in_so
lid_computed ;// pointer to mesh for determining c
learareas of the screen to draw dimension info//CA
utoDimRgnMesh *pMesh;// region to keep track of di
rty screen areas//CRgn* pDirtyRegion;public:// Boo
leans for the show state of dimension info//BOOL m
_bShowFlangeDim;BOOLm_bShowBendDim;BOOL m_bShowPar
tDim;// COLORREFs for drawing dimensions//COLORREF
m_crFlange;COLORREF m_crBend;COLORREF m_crPart;//
pointers tofonts//CFont* m_pFlangeFont;CFont* m_p
BendFont;CFont* m_pPartFont;// line and arrow para
meters//int m_nLineStyle;int m_nLineWeight;// in p
ixelsint m_nArrowStyle;int m_nArrowAngle;// in deg
reesint m_nArrowLength;// inpixels/*********** ***
******* ********** ********** ********** *********
* ********** ********** **********Privateメンバ関
数********** ********** ********** ********** ****
****** ********** ********** ********** **********
*/private :// This function is used to propagate t
he effects of drawing a flange length for a given
bendline,// to account for the fact that the flang
e dimension point is adjacent to the given adj-bod
y.// it returns TRUE iff the adj-bend will be mark
ed as drawn as well with respectto the given flang
e.// int compute_effects_flange_length_drawn(BM_BE
NDLINE *bendline, BM_3D_BODY *adj_body /* flange l
ength with respect to this body are being drawn *
/, BM_AD_dim_corner *bend_dim_point /* bend dimpoi
nt for bendline */, BM_AD_dim_corner *flange_dim_p
oint /* flange dimpoints for bendline */, BM_BENDL
INE *adj_bend /* flange dim points is adjacent to
this bendline */) ;// this function returns a poin
ter to the BM_AD_bendline structure that contains
data // about the given bendline.// BM_AD_bendline
*get_AD_bend_structure(BM_BENDLINE *bendline) ;//
thisfunction will return TRUE iff adj_bend has a
flange-dimension point withrespect to the// given
flange, that is adjacent to the given bendline.//
// a handy function.// int check_two_bendlines_adj
acent_to_same_flange(BM_BENDLINE *bendline, BM_3D_
BODY *flange, BM_BENDLINE *adj_bend) ;// just a de
bug function// void test_draw(void) ;// Check if w
e can ignore some points in solid mode.// // in so
lid mode we will be using this heuristic in order
to save time.// when two bendlines are using equiv
alent flange-dimension points for (potentially)//
displaying flange-length, we will only compute the
visibility information only// for the bendline (o
fthese two bendlines) which has the higher idx.//
void compute_points_to_ignore_in_solid(void) ;// t
his function draws a box with bendline data for ev
ery bendline.// void draw_bendline_data(CDC *pdc)
;/*********** ********** ********** ********** **
******** ********** ********** ********** ********
**公共メンバ関数********** ********** ********** *
********* ********** ********** ********** *******
*** ***********/public :BM_AUTO_DIMENSION(CBendCAD
Doc *BendCAD_doc) ;~BM_AUTO_DIMENSION(void) ;// th
is function returns a (p->p2) vector for a given b
endline with respect to a given adj-body.// // It
also computes a line between the p2 points of theb
end dimension points of the adjacent bendline // w
ith respect to thisflange.// BM_VECTOR const& comp
ute_bend_direction_vector(BM_BENDLINE *bendline, B
M_3D_BODY *adj_body, BM_LINE *p2_line) ;// destroy
the contentsof this Auto-Dimensions object,// voi
d delete_contents(void) ;// To seta new part. This
updates the view class pointer as well.// void se
t_part(BM_PART *new_part) ;// to force AD to recom
pute the dimension points.//inline void invalidate
(void) { dirty = 1 ; }// get current view type whe
n points were computed// inline int get_view_type
(void) const { returnview_type ; }// this function
will build auto dimension bendline and point data
structures.// // This is the main function for co
mputing dimension points.// int compute_auto_dimen
sion_data(void) ;// draw flange dimension data//vo
id draw_dim_point(BM_AD_dim_corner *bend_dim_poin
t, BM_AD_dim_corner *flange_dim_point, CBendCADVie
wPart *view, CDC *dc, double object_space_per_pixe
l);// to draw part dimensions in this device conte
xt//int draw_auto_dimensions(CDC *target_dc) ;// U
sed with draw_auto_dimensions to construct a geome
tric pen// with user-defined styles. This is neces
sary to draw patterned thick lines.//CPen* create_
auto_dim_pen(CPen*pPen, int nLineStyle, int nLineW
eight, COLORREF cr) ;// this will enableus to draw
part dimension only once//inline void disable_vie
w_dimensions_flag_next_time(void) { reset_view_to_
false_once_drawn = 1 ; }} ;#endif// BMAPI_AUTO_DIM
_HXX_INCLUDED 付録G 機能を描く自動寸法化の例。これらの関数は、デイメン
シヨンポイントが既に計算されていることを仮定する。
【0385】///*ディメンションポイントを計算する関
数はAD_POINTS.CPP内にある。先ず、どのディメンショ
ンポイントが可視であるか、そうでないかを検出する必
要がある。次に、フランジ長ディメンションを描く方法
を決定しなければならない。*/#include "stdafx.h"#in
clude "BendCAD.h"#include "BendCADDoc.h"#include "
BendCADViewPart.h"#include "BCAD_CTXT.HXX"#include
"AD_Arrow.h"#include"AUTODIM.HXX"/*********** ***
******* ********** ********** ********** *********
* ********** ********** **********BM_AD_dim_corner
クラススタッフ********** ********** ********** ***
******* ********** ********** ********** *********
* ***********//*この関数はディメンションポイントの
可視度を計算する。*/void BM_AD_dim_corner::compute
_visibility(CBendCADViewPart *view){int i, j, k ;d
ouble z_buf ;// by default, the points is not visi
blevisible = 0 ;if (num_of_points < 1) return ;//
note : when in wireframemode, we don’t have to ch
eck if points p1 and p2 actually// map into the sa
me bendline/flange points. in solid mode we need t
o check.// checkif we have solid or wireframe mod
e.if (view->get_drawing_mode()) goto solid_picture
;/*ワイヤフレームは、このディメンションポイントが
実際に最前面にある3D体か否かをチェックしない(原
文不明) ワイヤフレームモードでは、我々は、ビユー
ウインドにおける全ての事態が可視であると仮定する。
*///get visibility datai = view->map_point_to_clos
est_edge(p, &screen_x, &screen_y, &z_buf_value, NU
LL) ;if (! i) return ;if (num_of_points > 1) {i= v
iew->map_point_to_closest_edge(p1, &screen_x1, &sc
reen_y1, &z_buf, NULL) ;if (! i) return ;i = view-
>map_point_to_closest_edge(p2, &screen_x2, &screen
_y2, &z_buf, NULL) ;if (! i) return ;}// process v
isibility datapos_len = neg_len = 0.0 ;visible = 1
;return ;/*ソリッドモードで示されたパート*/solid_
picture :// here we keep pointers to 3D-bodies tha
t haveto be visible.BM_3D_BODY *visible_bodies[4]
;visible_bodies[0] = body_required_visible ;if (b
ody_required_visible->is(BM_ENTITY_TYPE_BENDLINE))
{visible_bodies[1] = (((BM_BENDLINE *) body_requir
ed_visible)->get_adj_list())->find_lowest_id_adj_b
ody() ;visible_bodies[2] = (((BM_BENDLINE *) body_
required_visible)->get_adj_list())->find_second_lo
west_id_adj_body() ;visible_bodies[3] = NULL ;}els
e visible_bodies[1] = NULL ;// handlecases when th
ere is just one point differently from when there
are 3 points.// if there is only 1 point, we have
a complete paper-part - thickness and radius both
0.// in that case there is really no bendline. we
have to check any of the adjacent bodies.if (num_o
f_points < 2) {// if this is a bend-dimension poin
t, the body_required_visible pointer should point
to the // adjacent body with respect to this dimen
sion point is computed.i = view->is_3d_body_near_p
oint(p, visible_bodies, &i, &screen_x, &screen_y,
&z_buf_value) ;if (! i) return ;}else {/*ソリッド
発見手法:これはソリッドモードを操作する新しいバー
ジヨンである。先ず、全ての3点p,p1および2がビ
ユーウインド内にあるかをチェックする。もし真なら、
我々は、ベンドアークのサイドプロフィルのセンタ点を
計算し、この点におけるベンドラインが実際に可視か否
かをチェックする。*/i = view->map_point_to_closest
_edge(p, &screen_x, &screen_y, &z_buf_value, NULL)
;if (! i) return ;/*ソリッド発見手法 :開放方向が
反転出来ないとき、それが指示していないかをチェック
する。if (! can_reverse_opening_dir) {BM_POINT p_o
pening_direction(p+ opening_direction) ;view->map_
point_to_closest_edge(p_opening_direction, &j, &k,
&z_buf, NULL) ;if (z_buf > (z_buf_value + 0.001))
return ; // ここで、特定の大きな公差を用いる// 開
放方向は指示している}*/// check if points p1 and p
2 are in the view window as well.i = view->map_poi
nt_to_closest_edge(p1, &screen_x1, &screen_y1, &z_
buf, NULL) ;if (! i) return;i = view->map_point_to
_closest_edge(p2, &screen_x2, &screen_y2, &z_buf,
NULL) ;if (! i) return ;BM_VECTOR v_pp1(p,p1) ;BM_
VECTOR v_pp2(p,p2) ;BM_POINT p_center ;double angl
e_alpha = (v_pp1 ^ v_pp2)/2.0 ;if (angle_alpha < P
I_over_2) {BM_VECTOR v_p1p2(0.5*(p2 - p1)) ;BM_POI
NT temp_p(p1 +v_p1p2) ;BM_VECTOR v_tip(p,temp_p) ;
double z = (v_pp1.Len())/cos(angle_alpha) ;double
y = z*sin(angle_alpha) ;v_tip.set_length((z - y) +
(bend->parent)->half_metal_thickness) ;p_center =
p + v_tip ;}else p_center =p ;i = view->is_3d_bod
y_near_point(p_center, visible_bodies, &i, &j, &k,
&z_buf) ;if (! i) return ;/* これはソリッドモード
を操作する古いバージヨンである。ここで我々は、ポイ
ントpがビユーウインド内にあるか否かをチェックし、
更にポイントp1およびp2が基礎をなす可視の3D体を持
つか否かをチェックする。// もし我々が3点を持つと
きは、点pは3D体上にはない。従って、我々は、それ
が有るか否かをチェックするのみである。// ビユーウ
インド内に。view->is_3d_body_near_point(p, NULL, &
i, &screen_x, &screen_y, &z_buf_value) ;if (! i) r
eturn ;// ポイントp1およびp2は3D体上になければなら
ない。i = view->is_3d_body_near_point(p1, visible_
bodies, &visibility_count, &screen_x1, &screen_y1,
&z_buf) ;if (! i) return ;i = view->is_3d_body_ne
ar_point(p2, visible_bodies, &visibility_count, &s
creen_x2, &screen_y2, &z_buf) ;if (! i) return ;*
/}// process visibility datapos_len = neg_len = 0.
0 ;visible = 1 ;}/*この関数は所定のデバイスコンテ
クスト内にdim-pointを描く。これは実際にはデバッグ
関数である。*/void BM_AD_dim_corner::draw_with_dim
_line(CBendCADViewPart *view, CDC *dc, double obje
ct_space_per_pixel){int i, j ;double x ;static POI
NT points[3] ;BOOL res ;// if this point is not kn
own to be visible, return.if (visible < 1) return
;if(num_of_points < 1) return ;points[1].x = scre
en_x ;points[1].y = screen_y ;// draw dimension li
neBM_POINT p_dim_line(p + (PIXELS_PER_DIMENSION_LI
NE * object_space_per_pixel)*opening_direction) ;v
iew->map_point_to_closest_edge(p_dim_line, &i, &j,
&x, NULL) ;points[2].x = i ;points[2].y= j ;if (c
an_reverse_opening_dir) {p_dim_line = p + (-PIXELS
_PER_DIMENSION_LINE * object_space_per_pixel)*open
ing_direction ;view->map_point_to_closest_edge(p_d
im_line, &i, &j, &x, NULL) ;points[1].x = i ;point
s[1].y= j ;res = dc->Polyline(points + 1, 2) ;poin
ts[1].x = screen_x ;points[1].y = screen_y ;}else
res = dc->Polyline(points + 1, 2) ;if (num_of_poin
ts < 2) return ;points[0].x = screen_x1 ;points
[0].y = screen_y1 ;points[2].x = screen_x2 ;points
[2].y = screen_y2 ;res = dc->Polyline(points,3) ;}
/*この関数は1フランジ長ディメンションを描く。 第
一の引数はベンドラインディメンションポイントであ
り、第二はフランジディメンションポイントである。*/
void BM_AUTO_DIMENSION::draw_dim_point(BM_AD_dim_c
orner *bend_dim_point, BM_AD_dim_corner *flange_di
m_point, CBendCADViewPart *view, CDC*dc, double ob
ject_space_per_pixel){int i, j ;double x, y, z, do
tp, half_dim_line ;BOOL res ;// points with screen
coordinates. Windows type.static POINT points[3]
;// these variable store the coordinates of the d
im-line-extension endpointsdouble bend_end_x, flan
ge_end_x ;BM_POINT bend_end_p, flange_end_p ;BM_VE
CTOR end_v(bend_dim_point->opening_direction);// t
hese variables store arrow head endpointsBM_POINT
bend_arrow_p, flange_arrow_p ;// compute the dimen
sion line extensionBM_VECTOR v((flange_dim_point->
p) - (bend_dim_point->p)) ;x = v % (bend_dim_point
->opening_direction) ;if (fabs(x) > AUTODIM_DISTAN
CE_TOLERANCE) { // we have to extend at least one
dimension linehalf_dim_line = (PIXELS_PER_DIMENSIO
N_LINE * object_space_per_pixel)/2.0 ;// here we w
ill first compute extensionlines, then the arrow,
and then the dimension points themselvesif (x <0.
0) {// here we assume that for bendline, we cannot
reverse the openingdirection.// it must be that t
he flange-dim points has a valid openingdirection
in the same direction// as the bend-dim point.// /
/ arrow point is to the right of the bend-dim poin
t.bend_arrow_p = (bend_dim_point->p) + half_dim_li
ne*end_v ;if (! view->map_point_to_closest_edge(be
nd_arrow_p, &i, &j, &y, NULL)) return ;points[0].x
= i ;points[0].y = j ;flange_arrow_p = (flange_di
m_point->p) + (-x + half_dim_line)*end_v ;if (! vi
ew->map_point_to_closest_edge(flange_arrow_p, &i,
&j, &y, NULL)) return;points[1].x = i ;points[1].y
= j ;half_dim_line *= 2.0 ;bend_end_x = half_dim_
line ;flange_end_x = -x + half_dim_line ;bend_end_
p = bend_dim_point->p + bend_end_x*end_v ;flange_e
nd_p = flange_dim_point->p + flange_end_x*end_v ;}
else {// here we assume that for bendline, we cann
ot reverse the opening direction.dotp = (bend_dim_
point->opening_direction) % (flange_dim_point->ope
ning_direction) ;// first lets try if we can rever
sethe flange-dim point opening directionif (dotp <
0.0 || flange_dim_point->can_reverse_opening_dir)
{// try to draw the arrow in the middle//// arrow
point is midway between flange- and bend-dim poin
ts.z = x/2.0 ;bend_arrow_p = (bend_dim_point->p) +
z*end_v ;if (! view->map_point_to_closest_edge(be
nd_arrow_p, &i, &j, &y, NULL)) goto try_other_dire
ction ;points[0].x = i ;points[0].y = j ;flange_ar
row_p = (flange_dim_point->p) + (-z)*end_v ;if (!
view->map_point_to_closest_edge(flange_arrow_p, &
i, &j,&y, NULL)) goto try_other_direction ;points
[1].x = i ;points[1].y = j ;bend_end_x = z + half_
dim_line ;flange_end_x = -x - half_dim_line ;bend_
end_p = bend_dim_point->p + bend_end_x*end_v ;flan
ge_end_p = flange_dim_point->p + flange_end_x*end_
v ;goto begin_to_draw ;}try_other_direction :if (d
otp > 0.0 || flange_dim_point->can_reverse_opening
_dir) {// arrow point is to the right of the flang
e-dim point.bend_arrow_p = (bend_dim_point->p) +
(x + half_dim_line)*end_v ;if (! view->map_point_t
o_closest_edge(bend_arrow_p, &i, &j, &y, NULL)) re
turn ;points[0].x = i ;points[0].y= j ;flange_arro
w_p = (flange_dim_point->p) + half_dim_line*end_v
;if (! view->map_point_to_closest_edge(flange_arr
ow_p, &i, &j, &y, NULL)) return ;points[1].x = i ;
points[1].y = j ;half_dim_line *= 2.0 ;bend_end_x=
x + half_dim_line ;flange_end_x = half_dim_line ;
bend_end_p = bend_dim_point->p + bend_end_x*end_v
;flange_end_p = flange_dim_point->p + flange_end_
x*end_v ;}else return ; // failure, cannot draw be
cause opening direction don’t match or not visibl
e.}}else { // no need to extend dimension lines//
check the direction of opening vectorif (end_v %
(flange_dim_point->opening_direction) < 0.0) {if
(! flange_dim_point->can_reverse_opening_dir) end_
v.reverse() ;}bend_end_x = flange_end_x = (PIXELS_
PER_DIMENSION_LINE * object_space_per_pixel) ;bend
_end_p = bend_dim_point->p +bend_end_x*end_v ;flan
ge_end_p = flange_dim_point->p + flange_end_x*end_
v ;bend_arrow_p = bend_dim_point->p + (bend_end_x/
2.0)*end_v ;flange_arrow_p = flange_dim_point->p +
(flange_end_x/2.0)*end_v ;// compute arrowendpoin
tsif (! view->map_point_to_closest_edge(bend_arrow
_p, &i, &j, &y, NULL)) return ;points[0].x = i ;po
ints[0].y = j ;if (! view->map_point_to_closest_ed
ge(flange_arrow_p, &i, &j, &y, NULL)) return ;poin
ts[1].x= i ;points[1].y = j ;}begin_to_draw :/*ア
ローを描く。*/// draw arrow line. points[0] is the
bend-dim-points side of the arrow.res = dc->Polyl
ine(points, 2) ;// draw arrowsBM_VECTOR v_arrow(fl
ange_arrow_p - bend_arrow_p) ;x = v_arrow.Len() ;
// this is the real flange length// change tosolid
pen for arrow headsCPen* pArrowPen = new CPen(PS_
SOLID, BCAD_context.m_nFlangeLineWeight, BCAD_cont
ext.m_crFlange);CPen* pOldPen = dc->SelectObject(p
ArrowPen);// compute arrow head at bend sideCAutoD
imArrow arrowBend(CPoint(points[0].x,points[0].y),
CPoint(points[1].x,points[1].y),BCAD_context.m_nAr
rowAngle,BCAD_context.m_nArrowLength);arrowBend.Dr
awHead(dc);// compute arrow head at flange sideCAu
toDimArrow arrowFlange(CPoint(points[1].x,points
[1].y),CPoint(points[0].x,points[0].y),BCAD_contex
t.m_nArrowAngle,BCAD_context.m_nArrowLength);arrow
Flange.DrawHead(dc);dc->SelectObject(pOldPen);dele
te pArrowPen;// write flange length on the screeni
nt center_x = (points[0].x + points[1].x) >> 1 ;in
t center_y = (points[0].y + points[1].y) >> 1 ;int
font_height = 21 ;double dx = (double)(points[1].
x - points[0].x) ;double dy = (double) (points[1].
y - points[0].y) ;if (fabs(dx) > AUTODIM_DISTANCE_
TOLERANCE) {if (dy/dx > 0.0) center_y -= font_heig
ht ;}center_x += 3 ; // move the beginning to the
right so that it won’t overlap the arrow line.CSt
ring str;str.Format("%6.4f",x);CSize sizeTextExten
t = dc->GetTextExtent(str);if (pDirtyRegion != NUL
L){CPoint pntText(center_x, center_y);CRect rectTe
xt(pntText, sizeTextExtent);if (!pDirtyRegion->Rec
tInRegion(&rectText))dc->TextOut(center_x,center_
y, str);CRgn rgn;rgn.CreateRectRgn(center_x, cente
r_y, center_x+ sizeTextExtent.cx, center_y + sizeT
extExtent.cy);pDirtyRegion->CombineRgn(pDirtyRegio
n, &rgn, RGN_OR);}else{pDirtyRegion = new CRgn();p
DirtyRegion->CreateRectRgn(center_x, center_y, cen
ter_x + sizeTextExtent.cx, center_y + sizeTextExte
nt.cy);dc->TextOut(center_x, center_y, str);}/*ben
d-dim-pointsにp1,p2を描く必要があるならば*/points
[1].x = bend_dim_point->screen_x ;points[1].y = be
nd_dim_point->screen_y ;if (bend_dim_point->num_of
_points > 1) {points[0].x = bend_dim_point->screen
_x1 ;points[0].y =bend_dim_point->screen_y1 ;point
s[2].x = bend_dim_point->screen_x2 ;points[2].y =
bend_dim_point->screen_y2 ;res = dc->Polyline(poin
ts, 3) ;}//draw dimension line extensionview->map_
point_to_closest_edge(bend_end_p, &i, &j, &x, NUL
L) ;points[2].x = i ;points[2].y = j ;res = dc->Po
lyline(points + 1, 2) ;/*flange-dim-pointsに対して
p1,p2を描く必要があるならば*/points[1].x = flange_
dim_point->screen_x ;points[1].y = flange_dim_poin
t->screen_y ;if (flange_dim_point->num_of_points >
1) {points[0].x = flange_dim_point->screen_x1 ;po
ints[0].y = flange_dim_point->screen_y1 ;points
[2].x = flange_dim_point->screen_x2 ;points[2].y =
flange_dim_point->screen_y2 ;res = dc->Polyline(p
oints, 3) ;}// draw dimension line extensionview->
map_point_to_closest_edge(flange_end_p, &i, &j, &
x, NULL) ;points[2].x = i ;points[2].y = j ;res =
dc->Polyline(points + 1, 2) ;}/*ベンドラインディメ
ンションポイントおよびフランジディメンションポイン
トが与えられると、この関数は、もしこれらのポイント
を用いてflange-length-dimensionを表示する方法が有
るときはTRUEを戻し、(すなわち、全てが可視である)
またはもしそうでないときはFALSEWO戻す。もしそれがT
RUEのときは、それは更に最良のフランジディメンショ
ンポイントを戻し;同様にベンドラインディメンション
ポイントに関してベンドラインディメンションポイント
pと最良のフランジディメンションポイントpの間の距離
を戻す。戻された最良の距離は、それが、bendline-dim
ension-opening-direction-vectorに対してK因子のた
めに負になり得る。ここでこの関数は、dimension-exte
nsion-linesが:1つのdimension-extension-lineが単位
長さであり、また他のものが、第一のものに達するのに
必要な程度に長いように描かれることを仮定する。すな
わち、この関数はディメンションポイントの1つに隣接
するディメンションアローを描く。すなわち、それは2
つのディメンションポイントの間のラインの途中の或る
点でディメンションポイントを描くことを試みない。想
起:bendline-dimension-opening-direction-vectorは
規格化されるべきである。注意:ここでこの関数は、di
mension-extension-linesが:1つのdimension-extension
-lineが単位長さであり、また他のものが、第一のもの
に達するのに必要な程度に長いように描かれることを仮
定する。
【0386】すなわち、この関数はディメンションポイ
ントの1つに隣接するディメンションアローを描く。す
なわち、それは2つのディメンションポイントの間のラ
インの途中の或る点でディメンションポイントを描くこ
とを試みない。注意:この関数において、dim pointが
可視でない場合直接チェックしない(別の関数を呼び出
す)。表示されているウインドウの中にいくつかのdime
nsion-extension-lineがあるかをチェックする。注意:
この関数において、ディメンションアローが進む点をチ
ェックする。それらが厳密にビユー領域内に有ることを
要求される。注意:この関数において、実際には近似位
置を用いる。すなわち、発見手法として。
【0387】*/int compute_best_dim_pair(CBendCADVi
ewPart *view, BM_AD_dim_corner *bend_dim_point,BM_
AD_dim_corner *flange_dim_list, double object_spac
e_per_pixel, // OUTPUT parametersdouble *best_dist
ance /* 見出された最良のflange-dim points の距離 *
/,BM_AD_dim_corner **best_flange_dim_point /* 最良
のflange-dim points */){BM_VECTOR v ;BM_POINT dim_
arrow_point ;int i, j,k ;double x, y, dotp ;// if
the bendline dimension point is not known to be vi
sible, return FALSE.// otherwise we might be wasti
ng our time.if(bend_dim_point->visible < 1) return
0 ;// scan the list of flange dimension pointsBM_
AD_dim_corner *temp_point, *best_fdp = NULL ;doubl
e best_distance_so_far ;for (temp_point = flange_d
im_list ; temp_point ; temp_point = temp_point->ne
xt) {if (! temp_point->visible) continue ;/*ソリッ
ド発見手法 :ソリッドモードにおいて、我々は時間を節
約するためにこの発見的手法を用いている。2つのベン
ドラインがフランジ長を表示するために(潜在的に)等
価なflange-dimension pointsを用いているときは、我
々は単に、より高いidxを持つベンドライン(これらの
2つのベンドラインの)に対してのみ可視度を計算す
る。*/if (view->get_drawing_mode() && temp_point->
ignore_in_solid_mode) continue ;// compute a vecto
r from bend-dim-p to flange-dim-pv = (temp_point->
p) - (bend_dim_point->p) ;x = v % (bend_dim_point-
>opening_direction) ;// check that opening directi
ons are valid.// idea : if bothvectors points in o
pposite directions are we cannot reverse them,// w
ecannot use these two dimension points to draw dim
ensions.dotp = (bend_dim_point->opening_direction)
% (temp_point->opening_direction) ;if (dotp <0.0
&& ! temp_point->can_reverse_opening_dir && ! bend
_dim_point->can_reverse_opening_dir) continue ;//
check that the point where the dimension arrow wou
ld go is in the view area// note : we will use hal
f-of-the-minimal-extension-length as the unit sepa
rating // zero and non-zero length extension line
s.if (fabs(x) > AUTODIM_DISTANCE_TOLERANCE) {k = 0
; //if k is TRUE at the end, we can draw the dime
nsion arrow pointif (x < 0.0) {// note : add space
for a line segment where we will draw the arrow//
// check if the directions agree. // we check thi
s first, because it would give us a smaller distan
ce.if (dotp > 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 ;}// checkthat the exten
sion of the bend-dim-line is visible.// in that ca
se theopening direction of the flange-dime-line do
es not matter.if (!k && bend_dim_point->can_revers
e_opening_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// no
te : add space for a line segment where we will dr
aw the arrow.// // check if the extension line is
visible.// we check this first, becauseit would gi
ve us a smaller distance.if (dotp < 0.0 || temp_po
int->can_reverse_opening_dir) {dim_arrow_point =
(temp_point->p) + (-x)*(bend_dim_point->opening_di
rection) ;if (view->map_point_to_closest_edge(dim_
arrow_point, &i, &j, &y, NULL)) k = 1 ;}// otherwi
se check if the directionsagree.if (!k) {dim_arrow
_point = (bend_dim_point->p) + (x)*(bend_dim_point
->opening_direction) ;if (view->map_point_to_close
st_edge(dim_arrow_point, &i, &j, &y, NULL)) k = 1
;}}if (!k) continue ; // cannot draw the dimensio
n arrow point}// check if visibility information i
s already computed.// if not, compute it. if flang
e dimension points not visible, continue.if (temp_
point->visible < 0) {temp_point->compute_visibilit
y(view) ;if (! temp_point->visible) continue ;}//
check if this new distance is the best distanceif
(best_fdp) {if (fabs(best_distance_so_far) > fabs
(x)){best_fdp = temp_point ;best_distance_so_far =
x ;}}else {best_fdp = temp_point ;best_distance_s
o_far = x ;}// check if we are done.// if we have
a point with a distance 0, we are done since we ca
nnot find a betterpoint.if (best_fdp && fabs(best_
distance_so_far) <= AUTODIM_DISTANCE_TOLERANCE) br
eak ;}if (best_fdp) {*best_distance = best_distanc
e_so_far ;*best_flange_dim_point = best_fdp ;retur
n 1 ;}return 0 ;}/*********** ********** *********
* ********** ********** ********** ********** ****
****************BM_AD_bendline クラススタッフ*****
***** ********** ******************** ********** *
********* ********** ********** ***********//*この
関数はベンドラインの全てのベンドラインディメンショ
ンポイントの可視度を計算する。注意: 時間の節約のた
めに、我々は、体1 、22の左( 右) ポイントが等価であ
るか否かをチェックする。*/void BM_AD_bendline::com
pute_bendline_dim_points_visibility(void){CBendCAD
ViewPart *view = parent->view ;// here we always c
ompute the visibility of adj-body1 bend-dimension
points,// even though we don’t check if adj_body1
pointer is NULL or not,// because we might want t
o know the visibility even if they don’t exist.//
// in practice this should not be a problem becau
se almost always there are two// adjacent bodies./
/ bend_body1_point_left.compute_visibility(view) ;
bend_body1_point_right.compute_visibility(view) ;i
f (adj_body2) {if(2 == body12_left_the_same) {if
(bend_body2_point_left.visible = bend_body1_point_
left.visible) {// note we are switching pointsbend
_body2_point_left.screen_x = bend_body1_point_lef
t.screen_x ;bend_body2_point_left.screen_y = bend_
body1_point_left.screen_y ;bend_body2_point_left.s
creen_x1 = bend_body1_point_left.screen_x2 ;bend_b
ody2_point_left.screen_y1 = bend_body1_point_left.
screen_y2 ;bend_body2_point_left.screen_x2 = bend_
body1_point_left.screen_x1 ;bend_body2_point_left.
screen_y2 = bend_body1_point_left.screen_y1 ;bend_
body2_point_left.z_buf_value = bend_body1_point_le
ft.z_buf_value ;}}else bend_body2_point_left.compu
te_visibility(view) ;if (2 == body12_right_the_sam
e) {if (bend_body2_point_right.visible= bend_body1
_point_right.visible) {// note we are switching po
intsbend_body2_point_right.screen_x = bend_body1_p
oint_right.screen_x ;bend_body2_point_right.screen
_y = bend_body1_point_right.screen_y ;bend_body2_p
oint_right.screen_x1 = bend_body1_point_right.scre
en_x2 ;bend_body2_point_right.screen_y1 = bend_bod
y1_point_right.screen_y2 ;bend_body2_point_right.s
creen_x2 = bend_body1_point_right.screen_x1 ;bend_
body2_point_right.screen_y2 = bend_body1_point_rig
ht.screen_y1 ;bend_body2_point_right.z_buf_value =
bend_body1_point_right.z_buf_value ;}}else bend_b
ody2_point_right.compute_visibility(view) ;}// els
e adj_body2 is NULL and there is nothing to comput
e}/*この関数はそれを1つのベンドラインに対して厳密
に行う。
【0388】重要:それは単に、どの方法が最良なもの
かを決定するが、ADが実際にそれをそのように行うか
否かを決定することはない。ここで、それは他のデータ
構造を更新する何らかかの方法を実施する。端的には、
それはADデータ構造のいずれかを変えることはない。
注意:始めは何らのチェックもなされない。アイデア:
この関数において、我々は、異なるbend-flange-dimポ
イントの組み合わせに対する値を割り当てる発見的手法
を用いる。最終的には、我々は最良の組み合わせを選択
する。我々が用いる発見的手法は、ベンドおよびフラン
ジdimポイントの間の距離の組み合わせ、プラスビユー
画面からのbend-pointの距離である。実際的なトリッ
ク:先ず我々は、最も良く知られた距離の値が既に0で
あるか否かをチェックする。もし0であるなら、我々
は、この新しいbend−dimポイントが良好なz−
buf値を持つときにのみ他のbend-dimポイントに対し
て最良の一致を見出そうとする。注意:4部分のテスト
の後、私は、これが丁度非常にわずかな改善を与えるこ
とを見出す。それは恐らく5−10%KKである(原文
不明)。*/void BM_AD_bendline::compute_dim_points_
to_display_indiv(BM_AD_bendline *best_AD_bendline
[2] /* これまでの最良のADベンドライン構造*/,BM_AD_
dim_corner *bodies_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_distanc
e ;// check adjacent body1if (adj_body1 && ! (body
1_drawn)) {// check if we already have a distance
0 bend-flange-dim points. if yes, go in only if th
e// new bend-dim points has astrictly better z-buf
value.if ((NULL == best_AD_bendline[0]) || distan
ce_and_z[2] > (bend_body1_point_left.z_buf_value +
AUTODIM_DISTANCE_TOLERANCE) || distance_and_z[0]
> AUTODIM_DISTANCE_TOLERANCE) {if (compute_best_di
m_pair(parent->view, &bend_body1_point_left, body1
_points, parent->object_space_per_pixel, &best_dis
tance, &best_fdp)) {best_distance = fabs(best_dist
ance) ;// check if the new point is betterif (best
_AD_bendline[0]) {// heuristic : if the sum of the
z-buf value and distance is smallerif ((best_dist
ance + bend_body1_point_left.z_buf_value) < (dista
nce_and_z[0] + distance_and_z[2])) {best_AD_bendli
ne[0] = this ;bodies_bend_flange[0] = &bend_body1_
point_left ;bodies_bend_flange[2] = best_fdp ;bodi
es_bend_flange[4] = body1_points ;distance_and_z
[0] = best_distance ;distance_and_z[2] = bend_body
1_point_left.z_buf_value ;}}else {best_AD_bendline
[0] = this ;bodies_bend_flange[0] = &bend_body1_po
int_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_po
int_left.z_buf_value ;}}}// check if we already ha
ve a distance 0 bend-flange-dimpoints. if yes, go
in only if the// new bend-dim points has a strictl
ybetter z-buf value.if (distance_and_z[2] > (bend_
body1_point_right.z_buf_value + AUTODIM_DISTANCE_T
OLERANCE) || (NULL == best_AD_bendline[0]) ||dista
nce_and_z[0] > AUTODIM_DISTANCE_TOLERANCE) {if (co
mpute_best_dim_pair(parent->view, &bend_body1_poin
t_right, body1_points, parent->object_space_per_pi
xel, &best_distance, &best_fdp)) {best_distance =
fabs(best_distance) ;// check if the new point is
betterif (best_AD_bendline[0]) {// heuristic : if
the sum of the z-buf value and distance is smaller
if ((best_distance + bend_body1_point_right.z_buf_
value) < (distance_and_z[0]+ distance_and_z[2]))
{best_AD_bendline[0] = this ;bodies_bend_flange[0]
= &bend_body1_point_right ;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_right.z_buf_value ;}}else
{best_AD_bendline[0] = this ;bodies_bend_flange[0]
= &bend_body1_point_right ;bodies_bend_flange[2]
= best_fdp ;bodies_bend_flange[4] = body1_points ;
distance_and_z[0] = best_distance ;distance_and_z
[2] = bend_body1_point_right.z_buf_value ;}}}}// c
heck adjacent body2if (adj_body2 && ! (body2_draw
n)) {//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 valu
e.if ((NULL == best_AD_bendline[1]) || distance_an
d_z[3] > (bend_body2_point_left.z_buf_value + AUTO
DIM_DISTANCE_TOLERANCE) || distance_and_z[1]> AUTO
DIM_DISTANCE_TOLERANCE) {if (compute_best_dim_pair
(parent->view,&bend_body2_point_left, body2_point
s, parent->object_space_per_pixel, &best_distance,
&best_fdp)) {best_distance = fabs(best_distance)
;// checkif the new point is betterif (best_AD_be
ndline[1]) {// heuristic : if the sum of the z-buf
value and distance is smallerif ((best_distance +
bend_body2_point_left.z_buf_value) < (distance_an
d_z[1] + distance_and_z[3])) {best_AD_bendline[1]
= this ;bodies_bend_flange[1] = &bend_body2_point_
left ;bodies_bend_flange[3] = best_fdp ;bodies_ben
d_flange[5] = body2_points ;distance_and_z[1] = be
st_distance ;distance_and_z[3] = bend_body2_point_
left.z_buf_value ;}}else {best_AD_bendline[1] = th
is ;bodies_bend_flange[1] = &bend_body2_point_left
;bodies_bend_flange[3] = best_fdp ;bodies_bend_fl
ange[5] = body2_points ;distance_and_z[1] = best_d
istance;distance_and_z[3] = bend_body2_point_left.
z_buf_value ;}}}// check ifwe already have a dista
nce 0 bend-flange-dim points. if yes, go in only i
f the// new bend-dim points has a strictly better
z-buf value.if (distance_and_z[3] > (bend_body2_po
int_right.z_buf_value + AUTODIM_DISTANCE_TOLERANC
E) || (NULL == best_AD_bendline[1]) || distance_an
d_z[1] > AUTODIM_DISTANCE_TOLERANCE) {if (compute_
best_dim_pair(parent->view, &bend_body2_point_righ
t, body2_points, parent->object_space_per_pixel, &
best_distance, &best_fdp)) {best_distance = fabs(b
est_distance) ;// check if the new point is better
if (best_AD_bendline[1]) {// heuristic : if the su
m ofthe z-buf value and distance is smallerif ((be
st_distance + bend_body2_point_right.z_buf_value)
< (distance_and_z[1] + distance_and_z[3])) {best_A
D_bendline[1] = this ;bodies_bend_flange[1] = &ben
d_body2_point_right;bodies_bend_flange[3] = best_f
dp ;bodies_bend_flange[5] = body2_points;distance_
and_z[1] = best_distance ;distance_and_z[3] = bend
_body2_point_right.z_buf_value ;}}else {best_AD_be
ndline[1] = this ;bodies_bend_flange[1] = &bend_bo
dy2_point_right ;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_right.z_buf_value ;}}}}}/*この関数は、
ベンドラインに対するフランジ長さを描く方法を決定す
る。これは、サブルーチントシテ以前の関数を用いるも
のにおける以前の関数とは異なっている。それは、ベン
ドラインに対するフランジ長ディメンションを描く方
法、従って全てのデータ構造を更新する方法を決定す
る。更に、それは同時のベンドラインを考慮する。*/vo
id BM_AD_bendline::compute_dim_points_to_display(v
oid){// qualification checkif (NULL == bend) retur
n ;BM_AD_bendline *bl ;long i ;// these variable s
tore the bendline dimension data that will be used
later to draw // 0,1 is with respect to adj-body
1; 2,3 is with respect to adj-body2BM_AD_dim_corne
r *bodies_bend_flange_list[6] ; // 0,1 is bend-dim
points; 2,3 is flange-dim points; 4,5 is flange l
istsdouble distance_and_z[4] ; // 0,1 is distance;
2,3 is z-buf// this is the bendline for whichwe w
ill be drawing the dimensions.// this is trivial w
hen there is no simultaneous bendlines.BM_AD_bendl
ine *best_AD_bendline[2] = { NULL, NULL} ;/*フラン
ジ長を描く最良の方法を計算する。同時のベンドライン
を考慮する。*/// these variables are for handling
simultaneous bendline property things.BM_BEND_PROP
ERTY *prop ;BM_LINKED_LIST_NODE *prop_list ;DBM_AR
RAY*bendlines ;BM_BENDLINE *bnd ;long size, this_b
end_seen = 0 ;for (prop_list = bend->get_propertie
s() ; prop_list ; prop_list = prop_list->next())
{prop = (BM_BEND_PROPERTY *) prop_list->get_obj()
;if (prop->is(BM_TYPE_BEND_SIMULTANEOUS)) {bendli
nes = (DBM_ARRAY *) prop->get_bendlines() ;size =
bendlines->get_size() ;for (i = 0 ; i < size ; i+
+) {// get a bendline in the bend property objecti
f (NULL == (bnd = (BM_BENDLINE *) bendlines->get
(i))) continue ;bl = parent->get_AD_bend_structure
(bnd) ;if (NULL == bl) continue ;if (bl == this) t
his_bend_seen = 1 ;if (! bl->data_valid || bl->ign
ore) continue ;// compute how to draw flange lengt
h dimensions for this one bendline.bl->compute_dim
_points_to_display_indiv(best_AD_bendline, bodies_
bend_flange_list, distance_and_z) ;}}}if (! this_b
end_seen) { // make sure this bendline gets proces
sedbl = parent->get_AD_bend_structure(bend) ;if (b
l && bl->data_valid && ! bl->ignore) {bl->compute_
dim_points_to_display_indiv(best_AD_bendline, bodi
es_bend_flange_list, distance_and_z) ;}}/*同時のベ
ンドにおける全ての他のベンドラインを"ignore"として
マークする。*/for (prop_list = bend->get_propertie
s() ; prop_list ; prop_list = prop_list->next())
{prop = (BM_BEND_PROPERTY *) prop_list->get_obj()
;if (prop->is(BM_TYPE_BEND_SIMULTANEOUS)) {bendli
nes =(DBM_ARRAY *) prop->get_bendlines() ;size = b
endlines->get_size() ;for(i = 0 ; i < size ; i++)
{// get next bendline in the bend property objecti
f (NULL == (bnd = (BM_BENDLINE *) bendlines->get
(i))) continue ;bl = parent->get_AD_bend_structure
(bnd) ;if (NULL == bl) continue ;// mark asignorei
f (bl->adj_body1 && ! (bl->body1_drawn) && bl != b
est_AD_bendline[0]) {bl->body1_drawn = 1 ;bl->draw
n_bend_dim_point1 = bodies_bend_flange_list[0] ;bl
->drawn_flange_dim_point1 = bodies_bend_flange_lis
t[2] ;}if(bl->adj_body1 && ! (bl->body2_drawn) &&
bl != best_AD_bendline[1]) {bl->body2_drawn = 1 ;b
l->drawn_bend_dim_point2 = bodies_bend_flange_list
[1] ;bl->drawn_flange_dim_point2 = bodies_bend_fla
nge_list[3] ;}}}}/*このベンドラインを図に対してマ
ークする。*/if (best_AD_bendline[0]) {best_AD_bend
line[0]->body1_drawn = 2 ;best_AD_bendline[0]->dra
wn_bend_dim_point1= bodies_bend_flange_list[0] ;be
st_AD_bendline[0]->drawn_flange_dim_point1 = bodie
s_bend_flange_list[2] ;}if (best_AD_bendline[1])
{best_AD_bendline[1]->body2_drawn = 2 ;best_AD_ben
dline[1]->drawn_bend_dim_point2 =bodies_bend_flang
e_list[1] ;best_AD_bendline[1]->drawn_flange_dim_p
oint2= bodies_bend_flange_list[3] ;}/*flange-dimポ
イントがベンドラインに隣接するか否かをチェックす
る。ここではわれわれは同時的なベンドはチェックしな
い、何故なら、我々が今ここで持つようにそれらは正確
に同じフランジリストを持つべきだからである。*/BM_A
D_dim_corner *temp_point ;if (best_AD_bendline[0])
{for (temp_point = bodies_bend_flange_list[4] ; t
emp_point ; temp_point = temp_point->next) {if (NU
LL == temp_point->adj_bendline) continue ;(best_AD
_bendline[0]->parent)->compute_effects_flange_leng
th_drawn(best_AD_bendline[0]->bend,best_AD_bendlin
e[0]->adj_body1, bodies_bend_flange_list[0], bodie
s_bend_flange_list[2], temp_point->adj_bendline)
;}}if(best_AD_bendline[1]) {for (temp_point = bod
ies_bend_flange_list[5] ; temp_point ; temp_point
= temp_point->next) {if (NULL == temp_point->adj_b
endline) continue ;(best_AD_bendline[1]->parent)->
compute_effects_flange_length_drawn(best_AD_bendli
ne[1]->bend,best_AD_bendline[1]->adj_body2,bodies_
bend_flange_list[1], bodies_bend_flange_list[3], t
emp_point->adj_bendline) ;}}}/*この関数はこのベン
ドラインに対するフランジ長さを描く。
【0389】それは、compute dim points to displa
y()関数により計算された情報を用いる。TODO : この関
数においては、われわれは、ベンドラインデイメンシヨ
ンポイントが既に描かれているトラックを保持すること
が出来る。adj-body1およびadj-body2に対するベンドラ
インデイメンシヨンポイントは一致する。その場合、そ
れを一回だけ実際に描くべきである。*/void BM_AD_ben
dline::draw_dimension_points(){// qualification ch
eckif (! data_valid || ignore) return ;if (adj_bod
y1 && 2 == body1_drawn) {parent->draw_dim_point(dr
awn_bend_dim_point1, drawn_flange_dim_point1, pare
nt->view, parent->dc, parent->object_space_per_pix
el) ;}if (adj_body2 && 2 == body2_drawn) {parent->
draw_dim_point(drawn_bend_dim_point2, drawn_flange
_dim_point2, parent->view, parent->dc, parent->obj
ect_space_per_pixel) ;}}/*********** ********** **
******** ********** ********** ********** ********
** ********** **********BM_AUTO_DIMENSION class st
uff.********** ********** ********** *************
******* ********** ********** ********** *********
**//*これはデバッグ関数である。*/void BM_AUTO_DIME
NSION::test_draw(void){BM_AD_dim_corner *temp_poin
t ;int i ;for (i = 0 ; i < num_of_bendlines ; i++)
{if (! bends[i]->data_valid) continue ;if (bends
[i]->adj_body1) {(bends[i]->bend_body1_point_lef
t).draw_with_dim_line(view,dc,object_space_per_pix
el) ;(bends[i]->bend_body1_point_right).draw_with_
dim_line(view,dc,object_space_per_pixel) ;for (tem
p_point = bends[i]->body1_points ; temp_point ; te
mp_point = temp_point->next) {temp_point->draw_wit
h_dim_line(view,dc,object_space_per_pixel) ;}}if
(bends[i]->adj_body2) {(bends[i]->bend_body2_point
_left).draw_with_dim_line(view,dc,object_space_per
_pixel) ;(bends[i]->bend_body2_point_right).draw_w
ith_dim_line(view,dc,object_space_per_pixel) ;for
(temp_point = bends[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ボックスをチェックしない。更
に、しばしば、ユーザは部分のデイメンシヨンを診るた
めにズームインし、その場合、部分によりカバーされな
いビユーポートの部位はなく、すなわちboundin
gボックスは全体のビー領域をカバーし、実際には無用
である。代わりに、我々はビユー領域のエッジに沿いベ
ンドライン情報ボックスを描いていることになる。我々
はビユー領域を4領域に分割し、info−boxが関
係するベンドポイントにどれがより近くても、それらの
領域にベンドラインinfoボックスを配置する。ここ
で当然、我々はビユーポートの左−右垂直エッジに沿い
それらのボックスを描く。*/void BM_AUTO_DIMENSION::
draw_bendline_data(CDC *pdc){int i, j ;// these va
riablesare used to calculate the info-box size and
to draw itint font_height =21 ;int font_avg_char_
width = 8 ; // average width of a characterint box
_height = (font_height << 1) /* テキストの2列 */ ;
int half_box_height =box_height >> 1 ;int box_widt
h = font_avg_char_width * 15 ; // space for15 char
actersint box_x ;int vert_space_per_box ;int offse
t ;// computemaximum number of info-boxes we can d
raw.int half_max_num_info_boxes =view_size_y / box
_height ;if (half_max_num_info_boxes < 1) return ;
// not enough screen spaceint max_num_info_boxes
= half_max_num_info_boxes << 1 ;/*我々が表示出来
るベンドの個数を計算する。*/int num_bends_to_be_dr
awn = 0 ;for (i = 0 ; i < num_of_bendlines ; i++)
{if (! bends[i]->data_valid || NULL == bends[i]->b
end) continue ;// remember, visibility of adj_body
1 bend-dimension points is always computed.// here
we only check visibility with respect to adj_body
1.// most likely visibility with respect to adj_bo
dy1 and adj_body2 is the same.if ((bends[i]->bend_
body1_point_left).visible || (bends[i]->bend_body1
_point_right).visible) {++num_bends_to_be_drawn ;}
else continue ;if (num_bends_to_be_drawn >= max_nu
m_info_boxes) break ; // out of view space}// chec
k if there are any bendlines to be drawnif (0 == n
um_bends_to_be_drawn) return ;/*ベンドラインポイン
タおよびエンドポイントのy座標を記憶するためのスペ
ースを割り当てる。*/BM_AD_bendline **bendlines = n
ew BM_AD_bendline*[num_bends_to_be_drawn] ;if (NUL
L == bendlines) return ; // out of spacedouble *be
nd_y_coordinates = new double[num_bends_to_be_draw
n] ;if (NULL == bend_y_coordinates) {// out of spa
cedelete [] bendlines ; return ; }BM_AD_dim_corner
**bend_points = new BM_AD_dim_corner*[num_bends_t
o_be_drawn] ;if (NULL == bend_points) {delete [] b
endlines ; delete [] bend_y_coordinates ; return ;
}/*ベンドラインポインタおよびbend−dim−p
ointポインタを集める。*/for (i = j = 0 ; i < n
um_of_bendlines ; i++) {if (! bends[i]->data_valid
|| NULL == bends[i]->bend) continue ;if (! (bends
[i]->bend_body1_point_left).visible && ! (bends[i]
->bend_body1_point_right).visible) continue ;// fi
rst, decide which of the endpoints we will usebend
lines[j] = bends[i] ;if ((bends[i]->bend_body1_poi
nt_left).visible) {if (! (bends[i]->bend_body1_poi
nt_right).visible) bend_points[j] = &(bends[i]->be
nd_body1_point_left) ;else {if ((bends[i]->bend_bo
dy1_point_left).z_buf_value< (bends[i]->bend_body1
_point_right).z_buf_value) bend_points[j] = &(bend
s[i]->bend_body1_point_left) ;else bend_points[j]
= &(bends[i]->bend_body1_point_right) ;}}else bend
_points[j] = &(bends[i]->bend_body1_point_right) ;
if (++j >= num_bends_to_be_drawn) break ; // out o
f view space}/*info-boxが画面のどの側にあるべきか
に従ってポイントを分類する。bend-line-dim-pointが
画面の左側にない全てのボックスを含む(少なくとも始
めは)。*/int half_screen = (view_size_x >> 1) ;i
= 0 ; // i will be topj = num_bends_to_be_drawn -
1 ; // j will be bottom// we will use these to tem
porarily store stuffBM_AD_bendline *p_bend ;BM_AD_
dim_corner *p_bend_point ;while (i < j) {while (i
< j && bend_points[i]->screen_x < half_screen) i++
;while (i < j && bend_points[j]->screen_x >= half
_screen) j-- ;// switch i and jif (i < j) {p_bend
= bendlines[i] ;p_bend_point = bend_points[i] ;ben
dlines[i] = bendlines[j] ;bend_points[i] = bend_po
ints[j] ;bendlines[j] = p_bend ;bend_points[j] = p
_bend_point ;}}if (bend_points[i]->screen_x < half
_screen) i++ ;// i points to the first info-box on
the right side/*どちらの側も(すなわち、左−右)
余りに多くのinfo-boxを有さないことをチェックする。
*/if (i > half_max_num_info_boxes) {// too many bo
xeson the left side.// sort them according to x-co
ordinates.// this way wewill move points with the
largest x-coordiates to the right side.for (j= 0 ;
j < i ; j++) bend_y_coordinates[j] = bend_points
[j]->screen_x ;DBM_QuickSort_double(bend_y_coordin
ates, (unsigned long) i, (long *) bendlines) ;i =
half_max_num_info_boxes ;}else if ((num_bends_to_b
e_drawn - i)> half_max_num_info_boxes) {// too man
y boxes on the right side.// sortthem according to
x-coordinates.// this way we will move points wit
h the smallest x-coordiates to the left side.for
(j = i ; j < num_bends_to_be_drawn ; j++) bend_y_c
oordinates[j] = bend_points[j]->screen_x ;DBM_Quic
kSort_double(bend_y_coordinates + i, (unsigned lon
g) (num_bends_to_be_drawn - i), (long *) (bendline
s + i)) ;i = num_bends_to_be_drawn - half_max_num_
info_boxes ;}// it could have been that when we ch
ose a point fora bendline, it is not the best poin
t.// (although this point was used to place this p
oint on the left-right side).// imagine a point on
the left. it could be that both endpoints are vis
ible, but// out point is not the best, because the
other endpoint of the bendline is actually to the
//left of our point.for (j = 0 ; j < i ; j++) {//
check if we have choiceif (! (bendlines[j]->bend_b
ody1_point_left).visible || ! (bendlines[j]->bend_
body1_point_right).visible) continue ;if ((bendlin
es[j]->bend_body1_point_left).screen_x < (bendline
s[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) ;}for (j = i ; j < num_bends_to_be_drawn ;
j++) {// check if we have choiceif (! (bendlines
[j]->bend_body1_point_left).visible || ! (bendline
s[j]->bend_body1_point_right).visible) continue ;i
f ((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
Quicksortfor(j = 0 ; j < num_bends_to_be_drawn ;
j++) bend_y_coordinates[j] = bend_points[j]->scree
n_y ;// sort both sides according to the screen y-
coordinate// note a glitch : while the bendlines[]
array has been permuted, thebend_points[] array h
as not been.// in the next paragraph we restore th
e point array. TODO : may-be there is a better sol
ution.//we could resort the array, but then we nee
d to get original y-coordinates array.//we could j
ust compute a separate permutation array, but then
we need space for it, and//the code to compute th
e permutation, which is non-tirivial.// anyway, fo
r now we just do it the easy way.if (i > 0) DBM_Qu
ickSort_double(bend_y_coordinates, (unsigned long)
i, (long *) bendlines) ;if ((num_bends_to_be_draw
n - i) > 0) DBM_QuickSort_double(bend_y_coordinate
s +i, (unsigned long) (num_bends_to_be_drawn - i),
(long *) (bendlines + i)) ;for (j = 0 ; j < i ; j
++) {if ((bendlines[j]->bend_body1_point_left).vis
ible) {if (! (bendlines[j]->bend_body1_point_righ
t).visible) bend_points[j] = &(bendlines[j]->bend_
body1_point_left) ;else {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) ;}}e
lse bend_points[j] = &(bendlines[j]->bend_body1_po
int_right) ;}for (j = i ; j <num_bends_to_be_drawn
; j++) {if ((bendlines[j]->bend_body1_point_lef
t).visible) {if (! (bendlines[j]->bend_body1_point
_right).visible) bend_points[j] = &(bendlines[j]->
bend_body1_point_left) ;else {if ((bendlines[j]->b
end_body1_point_left).screen_x > (bendlines[j]->be
nd_body1_point_right).screen_x) bend_points[j] = &
(bendlines[j]->bend_body1_point_left) ;else bend_p
oints[j] = &(bendlines[j]->bend_body1_point_right)
;}}else bend_points[j] = &(bendlines[j]->bend_bod
y1_point_right) ;}/*ここで描画の準備が完了する。*/
static char info_box_text[256] ;static POINT box_c
orners[5] ;static POINT arrow[3] ;BM_BENDLINE *b ;
BM_BEND_OP *bop ;BM_2D_BODY*b_body ;/*左側を描く。
*/int left = 3 ;int top ;if (0 == i) goto draw_rig
ht_side ;// compute vertical space per info-boxver
t_space_per_box = view_size_y / i ;// compute vert
ical offset for the top-left corner of theinfo-box
offset = (vert_space_per_box - box_height) >> 1 ;b
ox_corners[0].x = box_corners[3].x = box_corners
[4].x = left ;box_corners[1].x = box_corners[2].x
= left + box_width ;for (j = 0 ; j < i ; j++) {b =
bendlines[j]->bend ;bop = b->get_bend_op() ;if (N
ULL == bop) continue ;// 043996KKif (view_type) b_
body = b->get_current_3D_version() ;else b_body =
b->get_flat() ;top = j*vert_space_per_box + offset
;box_corners[0].y = box_corners[1].y = box_corner
s[4].y = top ;box_corners[2].y = box_corners[3].y
= top + box_height ;sprintf(info_box_text,"A:%5.1
f,L:%6.2f",(bop->get_bend_angle2())*57.29578,(b_bo
dy->get_current_center_line()).get_len()) ;pdc->Te
xtOut(5, top, info_box_text, strlen(info_box_tex
t)) ;switch (bop->get_type()) {case BM_TYPE_BEND_O
P_REGULAR :sprintf(info_box_text,"R:%5.2f,D:%5.2
f",((BM_BEND_OP_REGULAR *) bop)->get_bend_radiu
s(),bop->get_bend_deduction()) ;pdc->TextOut(5, to
p + font_height, info_box_text, strlen(info_box_te
xt)) ;break ;case BM_TYPE_BEND_OP_CONIC :// TODO :
implementconic bend op.break ;}// draw boxpdc->Po
lyline(box_corners, 5) ;// drawarrowarrow[0].x = l
eft + box_width ;arrow[0].y = top + half_box_heigh
t;// calculate arrow tip at fixed percentage lengt
h in from end pointCPoint ptLeft(bendlines[j]->ben
d_body1_point_left.screen_x, bendlines[j]->bend_bo
dy1_point_left.screen_y);CPoint ptRight(bendlines
[j]->bend_body1_point_right.screen_x, bendlines[j]
->bend_body1_point_right.screen_y);CSizesizeDiff =
ptRight - ptLeft;CPoint ptArrowTip;if ( bend_poin
ts[j] == &(bendlines[j]->bend_body1_point_left) )
{ptArrowTip.x = ptLeft.x + sizeDiff.cx/8;ptArrowTi
p.y = ptLeft.y + sizeDiff.cy/8;}else{ptArrowTip.x
= ptRight.x - sizeDiff.cx/8;ptArrowTip.y = ptRigh
t.y - sizeDiff.cy/8;}arrow[1].x = ptArrowTip.x;arr
ow[1].y = ptArrowTip.y;pdc->Polyline(arrow, 2) ;//
change to solid pen for arrow headsCPen* pArrowPen
= new CPen(PS_SOLID,BCAD_context.m_nBendLineWeigh
t, BCAD_context.m_crBend);CPen* pOldPen =pdc->Sele
ctObject(pArrowPen);// compute arrow headCAutoDimA
rrow arrowBend(ptArrowTip,CPoint(arrow[0].x,arrow
[0].y),BCAD_context.m_nArrowAngle,BCAD_context.m_n
ArrowLength);// draw arrow headarrowBend.DrawHead
(dc);pdc->SelectObject(pOldPen);delete pArrowPen;}
/*右側を描く。*/draw_right_side:if (0 == num_bends
_to_be_drawn - i) goto done ;box_x = view_size_x -
box_width - 3 ;left = box_x ;// compute vertical
space per info-boxvert_space_per_box = view_size_y
/ (num_bends_to_be_drawn - i) ;// compute vertica
l offset for the top-left corner of the info-boxof
fset = (vert_space_per_box - box_height) >> 1 ;box
_corners[0].x = box_corners[3].x = box_corners[4].
x = left ;box_corners[1].x = box_corners[2].x = le
ft + box_width ;box_x += 2 ;for (j = i ; j < num_b
ends_to_be_drawn ; j++) {b = bendlines[j]->bend ;b
op = b->get_bend_op() ;if (NULL == bop) continue ;
// 043996KKif (view_type) b_body = b->get_current_
3D_version() ;else b_body = b->get_flat() ;top =
(j - i)*vert_space_per_box + offset ;box_corners
[0].y = box_corners[1].y = box_corners[4].y = top
;box_corners[2].y = box_corners[3].y = top + box_
height ;sprintf(info_box_text,"A:%5.1f,L:%6.2f",(b
op->get_bend_angle2())*57.29578,(b_body->get_curre
nt_center_line()).get_len()) ;pdc->TextOut(box_x,
top, info_box_text, strlen(info_box_text));switch
(bop->get_type()) {case BM_TYPE_BEND_OP_REGULAR :s
printf(info_box_text,"R:%5.2f,D:%5.2f",((BM_BEND_O
P_REGULAR *) bop)->get_bend_radius(),bop->get_bend
_deduction()) ;pdc->TextOut(box_x, top + font_heig
ht, info_box_text, strlen(info_box_text)) ;break ;
case BM_TYPE_BEND_OP_CONIC ://TODO : implement con
ic bend op.break ;}// draw boxpdc->Polyline(box_co
rners, 5) ;// draw arrowarrow[0].x = left ;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;CPo
int ptArrowTip;if ( bend_points[j]== &(bendlines
[j]->bend_body1_point_left) ){ptArrowTip.x = ptLef
t.x + sizeDiff.cx/8;ptArrowTip.y = ptLeft.y + size
Diff.cy/8;}else{ptArrowTip.x =ptRight.x - sizeDif
f.cx/8;ptArrowTip.y = ptRight.y - sizeDiff.cy/8;}a
rrow[1].x = ptArrowTip.x;arrow[1].y = ptArrowTip.
y;pdc->Polyline(arrow, 2);// change to solid pen f
or arrow headsCPen* pArrowPen = new CPen(PS_SOLID,
BCAD_context.m_nBendLineWeight, BCAD_context.m_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;}/*割り当てたメモリ
を開放する。*/done :delete [] bend_points ;delete
[] bend_y_coordinates ;delete[] bendlines ;}/*デバ
イスコンテクストに部分デイメンシヨンを描く。*/intB
M_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) retu
rn 0 ;// check if we need to recompute the data st
ructuresif (dirty) {if (! compute_auto_dimension_d
ata()) return 0 ;if (dirty) return 0;}if (NULL ==
part) return 1 ;dc = target_dc ;// get view sizevi
ew_size_x = view->get_viewport_width() ;view_size_
y = view->get_viewport_height() ;// create a mesh
to determine clear spaces to draw dimensions & dat
apMesh = new CAutoDimRgnMesh(view_size_x, view_siz
e_y);// check if we needto compute points to ignor
e in solidif (view->get_drawing_mode() && ! points
_to_ignore_in_solid_computed) {compute_points_to_i
gnore_in_solid();}object_space_per_pixel = view->g
et_object_to_device_ratio() ;// initially set all
"ignore" flags to FALSE. we should not ignore any
thing.// also, nothing is drawn yet.for (i = 0 ; i
< num_of_bendlines ; i++) {bends[i]->ignore = 0 ;
bends[i]->body1_drawn = bends[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_p
oint ; temp_point = temp_point->next) temp_point->
visible = -1 ;}if (bends[i]->adj_body2) {for (temp
_point = bends[i]->body1_points ; temp_point ; tem
p_point = temp_point->next) temp_point->visible =
-1 ;}}/*全てのベンドラインに対して、描くべきデイメ
ンシヨンポイントを計算する。*/for (i = 0 ; i < num
_of_bendlines ; i++) {if (! bends[i]->data_valid |
|bends[i]->ignore) continue ;bends[i]->compute_dim
_points_to_display() ;}/*パートを描くペンを生成す
る。フランジデイメンシヨンを描くペンを生成する。*/
// create the pen : type, (line)width, color.CPen
penFlange;CPen* pFlangePen = create_auto_dim_pen(&
penFlange, BCAD_context.m_nFlangeLineStyle, BCAD_c
ontext.m_nFlangeLineWeight, BCAD_context.m_crFlang
e);// selectnew pen, save old penCPen* pOldPen = d
c->SelectObject(pFlangePen);COLORREF oldtextcolor
= dc->SetTextColor(BCAD_context.m_crFlange) ;int o
ld_bk_mode = dc->SetBkMode(TRANSPARENT) ;/*フラン
ジ長さディメンシヨンを表示する。*/if (BCAD_contex
t.m_bShowFlangeDim){for (i = 0 ; i < num_of_bendli
nes ; i++) {if (! bends[i]->data_valid || bends[i]
->ignore) continue ;bends[i]->draw_dimension_point
s();}}/*// ダーテイ領域の表示をテストする。CBrush
brRed(RGB(255,0,0));CBrush* pOldBrush = dc->Select
Object(&brRed);dc->PaintRgn(pDirtyRegion);dc->Sele
ctObject(pOldBrush);*/delete pDirtyRegion;pDirtyRe
gion = NULL;/*ベンドラインinfoを描くペンを生成す
る。*/// create the pen : type, (line)width, colo
r.CPen penBend;CPen* pBendPen = create_auto_dim_pe
n(&penBend, BCAD_context.m_nBendLineStyle, BCAD_co
ntext.m_nBendLineWeight, BCAD_context.m_crBend);//
select the new pendc->SelectObject(pBendPen);dc->
SetTextColor(BCAD_context.m_crBend);/*ベンドライン
infoを描く。*/if (BCAD_context.m_bShowBendDim)draw
_bendline_data(dc) ;// Delete the mesh now that we
are finished with it.//delete pMesh;/*古いペンを
復帰させる。*/dc->SelectObject(pOldPen) ;dc->SetTe
xtColor(oldtextcolor) ;dc->SetBkMode(old_bk_mode)
;// see if we have to disable auto-dimensioning i
n the view classif (reset_view_to_false_once_draw
n) {reset_view_to_false_once_drawn = 0 ;view->set_
auto_dimensions(0) ;}return 1 ;}CPen* BM_AUTO_DIME
NSION::create_auto_dim_pen(CPen* pPen, int nLineSt
yle, intnLineWeight, COLORREF cr){if (nLineWeight
== 1 || nLineStyle == PS_SOLID)pPen->CreatePen(nLi
neStyle, nLineWeight, cr);// for speedelse{CBrush
brushNew(cr);LOGBRUSH lb;brushNew.GetLogBrush(&l
b);DWORD dwStyleArray[6];int nStyleCount = 2;DWORD
dwDashLength = 2 + (nLineWeight * 4);DWORD dwDotL
ength = dwDashLength / 4;DWORD dwGapLength = dwDas
hLength / 2;switch(nLineStyle){case PS_DASH:dwStyl
eArray[0] = dwDashLength;// pixels ondwStyleArray
[1] = dwGapLength;// pixels offnStyleCount = 2;bre
ak;case PS_DOT:dwStyleArray[0] = dwDotLength;// on
dwStyleArray[1] = dwGapLength;// offnStyleCount =
2;break;case PS_DASHDOT:dwStyleArray[0] = dwDashLe
ngth;//ondwStyleArray[1] = dwGapLength;// offdwSty
leArray[2] = dwDotLength;//ondwStyleArray[3] = dwG
apLength;// offnStyleCount = 4;break;case PS_DASHD
OTDOT:dwStyleArray[0] = dwDashLength;// ondwStyleA
rray[1] = dwGapLength;// offdwStyleArray[2] = dwDo
tLength;// ondwStyleArray[3] = dwGapLength;// offd
wStyleArray[4] = dwDotLength;// ondwStyleArray[5]
= dwGapLength;// offnStyleCount = 6;break;}pPen->C
reatePen(PS_GEOMETRIC | PS_USERSTYLE,nLineWeight,
&lb, nStyleCount, dwStyleArray);}return pPen;}void
CBendCADDoc::OnDrawAutoDim() {// if we have no di
mension object, do nothing.if(NULL == auto_dim) {a
uto_dim = new BM_AUTO_DIMENSION(this) ;}if (NULL =
=auto_dim) return ;CBendCADViewPart *pActiveView =
(CBendCADViewPart *)get_view(BENDCAD_VIEW_TYPE_PA
RT) ;if (NULL == pActiveView) return ;if (!pActive
View->get_auto_dimensions()) auto_dim->disable_vie
w_dimensions_flag_next_time() ;pActiveView->set_au
to_dimensions(1) ;// always recompute dimension po
intsauto_dim->invalidate() ;pActiveView->Invalidat
e(0) ;} 付録H ディメンションポイントを計算する自動寸法化関数の
例。ディメンションポイントは、フランジ長ディメンシ
ョンが描かれる前に計算される。
【0390】//#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を戻す。
【0391】基本的には、この関数は、ループ中の次の
エッジが無視されないラインであるときはTRUEを戻す。
実際には、更に幾つかの条件を付加する。注意:この関
数は、エッジのエンドポイントがフランジ長距離にあ
り、また我々が、このエンドポイントに対する(フラン
ジ)ディメンションポイントを描くべきかを考えている
ときに求められる。*/static int leave_dimension_ope
n(BM_EDGE *edge /* current edge */,BM_LOOP *bloop
/* loop where the current edge belongs to */,BM_VE
CTOR const& side_vector /* side vector for the cur
rent bendline-ajd_flange pair */, BM_VECTOR const&
normal /* normal of the plane underlying the adja
cent flange */){BM_EDGE *next_edge = (BM_EDGE *) e
dge->next();if (NULL == next_edge) next_edge = blo
op->get_first_edge() ;if (next_edge->is(BM_ENTITY_
TYPE_LINE)) {// problem. if the next edge (which i
s aline) will be ignored, we need to// close the d
imension here.BM_VECTORtemp_v((((BM_LINE *) next_e
dge)->get_v()) * side_vector) ;// if the nextline
will not be ignored we can skip the current edge.i
f (temp_v.Len()>AUTODIM_DISTANCE_TOLERANCE && (tem
p_v % normal) < 0.0) {// next edge isa line that w
ill not be ignored.// note that there is a proble
m. if this edge is a line, and one of the two line
s // (rememeber, next edge is aline) is adjacent t
o a bendline that // the other is not adjacent to,
we should close the dimension.if (! edge->is(BM_E
NTITY_TYPE_LINE)) return1 ;BM_3D_BODY *ab = edge->
get_adj_body() ;BM_3D_BODY *ab_next = next_edge->g
et_adj_body() ;if (! ab) {if (! ab_next) return 1
;if (! ab_next->is(BM_ENTITY_TYPE_BENDLINE)) retu
rn 1 ;return 0 ;}if (! ab_next) {if (! ab->is(BM_E
NTITY_TYPE_BENDLINE)) return 1 ;return 0 ;}if ((!
ab->is(BM_ENTITY_TYPE_BENDLINE) && ! ab_next->is(B
M_ENTITY_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 a1-point flange-dimension point.// n
ote that body_required_visible pointsto the flange
with respect to which // the dimension point is c
omputed.return new BM_AD_dim_corner(p_local, owne
r, Body_required_visible, opening_direction_vecto
r, opening_vector_reverse_bit, prev, adj_bendline)
;}//note that since we have 3 points now, this li
ne is adjacent to anotherbendline.// compute p1. p
_local is p1.// compute pBM_POINT dim_p(p_local+ d
_proj_side_vector*side_vector) ;// compute p2bend_
arc_direction.set_length(d) ;BM_POINT dim_p2(p_loc
al + bend_arc_direction) ;// now the problem is th
at with respect to the adjacent bendline, our flan
ge dimensionpoints// p and p1 might not be on the
outside - they could be on the inside.// the dista
nce from p to p2 depends on that.// however, we kn
ow the p2-line of the adjacent bendline (with resp
ect to our flange),// so wewill compute the distan
ce between that p2-line and dim_p2. // we will use
that to compute the correct p2 point for our flan
ge dimension (note that// our p2 point has to be o
n the p2-line of the adjacent bendline).double dis
tance ;BM_distance_between_point_and_line(dim_p2,
adj_bend_p2_line, &distance, (BM_POINT *) NULL) ;b
end_direction.set_length(distance) ;dim_p2 = dim_p
2 + bend_direction ;// note that the body_required
_visiblepointer points not to this flange, but to
the // adjacent-bendline instead, ALWAYS, even if
this flange dim point will not be marked as// adja
cent to another bendline.return new BM_AD_dim_corn
er(dim_p, p_local, dim_p2, owner, adj_bend ? adj_b
end : Body_required_visible, opening_direction_vec
tor, opening_vector_reverse_bit, prev, adj_bendlin
e) ;}/*この関数は隣接フランジに対するフランジディ
メンションポイントを計算する。注意:この関数の直前
に計算した基準ポイントは、我々が任意の種類のadj-bo
dy面を操作出来るを確実にするために与えられる。第一
の問題は、我々が、adj-bodyの3次元- バージヨンの2
次元- bodyがOUTSIDEまたはINSIDEを表すかどうか解ら
ないということである。我々は、ベンドラインに対する
ベンドラインディメンションポイントがOUTSIDEポイン
トであることを知っている。ただし、 adj-bodyが明瞭
にINSIDEを表すということがあり得る。その場合、ここ
で計算しようとしている全てのポイントをシフトさせる
並進ベクトルを計算する基準ポイント(これはadj-body
の外側面上にある)に対して用いられる。更に、この並
進ベクトルを用いて、フランジディメンションポイント
のポイントp1およびp2が正しいということを確認するた
めに用いる。(もし、adj-bodyがinsideを表すときは、
我々はoutsideに対して実際にディメンションポイント
を計算し、ライン(p->p2)は注意して構成されなければ
ならず、それはライン(p->p1)より短い。)注意:この
関数は、我々がここでより多くの仮定を行うがBMAPI’s
BM_2D_BODY::compute_outside_width(...)関数に非常
によく相似している。*/int BM_AD_bendline::compute_
BM_AD_flange_points(BM_3D_BODY *adj_body){// flang
e dimension points we aregoing to compute will be
stored hereBM_AD_dim_corner **list_of_points ;// l
ist_of_points is where we write the pointer to the
// next flange dimension pointBM_AD_dim_corner *t
emp_dp ;// these parameters are used asinput to th
is function.double flange_length ; /* it is import
ant that the flange length be the correct flange l
ength */BM_POINT ref_point ; /*reference point, de
fines the right plane for flange dimension points
*/BM_VECTOR side_vector ; /* should be normalized
*/// check which adjacentbody we computeif (adj_bo
dy == adj_body1) {flange_length = fl1 ;list_of_poi
nts = &body1_points ;ref_point = bend_body1_point_
left.p ;side_vector = side_vector1 ;}else if (adj_
body == adj_body2) {flange_length = fl2;list_of_po
ints = &body2_points ;ref_point = bend_body2_point
_left.p ;side_vector = side_vector2 ;}else return
0 ; // not an adjcent body// variables to store te
mporary valuesBM_VECTOR temp_v ;double temp_x ;//
parameters for fixing the reference pointBM_POINT
rp(ref_point) ; // this a local copy of the refere
nce point. we will modify it.BM_VECTOR rv ; // ave
ctor for translating flange dimension points.int r
ef_vector_valid = 0; // if this is TRUE, we need t
o translate all flange dimension points.// if TRU
E, the only really tricky part is to construct the
p2 point in the flange dimension point.// qualifi
cation checkBM_2D_BODY *adj_displayed_version ;if
(parent->get_view_type()) adj_displayed_version =
adj_body->get_current_3D_version() ;else adj_displ
ayed_version = adj_body->get_flat() ;if (NULL == a
dj_displayed_version) return 0 ;BM_SURFACE *surfac
e= adj_displayed_version->get_surface() ;if (NULL
== surface) return 0 ;BM_LOOP *bloop = adj_display
ed_version->get_bloop() ;if (NULL == bloop) return
0 ;BM_EDGE *edge ; // here we will store edges as
we scan the loop.double distance1, distance2 ; //
here we will store the distance of points we seed
ouble d1, d2 ; // here we store distance that has
to be addedbecause of a bend arc. for lines adjace
nt to a bendline.double td1, td2; // here we store
the total distance which is the sum of distanceX
+ dX.BM_3D_BODY *ab ; // here we store a pointer t
o a body that is adjacentto the current edge.BM_BE
ND_OP *bop ; // here we store a pointer to thebend
op associated with the bendline that is// adjacen
t to the edge wescan (valid only iff the body adja
cent to the edge is a bendline).BM_VECTOR r
ight_opening_direction ;
// this is the right−side
opening direction vecto
r. BM_VECTOR left_opening
_direction ; // this is t
he left−side opening dire
ction vector. int fl_dim_
open = 0 ; // if this is
TRUE, we have created a r
ight−side flange dimensio
n point, but// no corresp
onding left−side dimensio
n point. That is, the dim
ension is ”open”.BM_VECTO
R bend_arc_direction ; //
direction of the bend ar
c projected onto our plan
e//should be line−>v * pl
ane_normal. Used when a l
ine is adjacent to a bend
line.BM_VECTOR bend_direc
tion ; // points in the d
irection in which thebend
line ”turns”// depends on
whether the bend angle i
s acute or not. // if acu
te then tangent to the ot
her end of bend arc.// if
not acute, then an endpo
int of the tangent approx
imation.// basically this
is the (p−>p2) vector fo
r the other bendline with
respect to this flange./
/ this is used when a lin
e is adjacent to a bendli
ne, to compute the p2 poi
nt for // the flange dime
nsion point.BM_LINE adj_b
end_p2_line ; // this is
the left−right−p2 line, o
f the adjacent bendline,/
/ with respect to this fl
ange.// this is used when
a line is adjacent to a
bendline, to computethe p
2 point for // the flange
dimension point.double b
end_arc_outside_length_pr
oj ; // bendline arc outs
ide length projected onto
our plane/*表面のタイプを操作する。*/
if (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 a
n edge that is adjacent to our bendline and start
from that and// finish when we get back to it.BM_E
DGE *start_edge, *stop_edge, *next_edge ;for (star
t_edge = bloop->get_first_edge() ; start_edge ; st
art_edge = (BM_EDGE *) start_edge->next()) {if (st
art_edge->get_adj_body() == bend) break ; // edge
adjacent 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 { // a
ny linethat will be ignored is also a good place t
o starttemp_v = (((BM_LINE *)start_edge)->get_v())
* side_vector ;// in these two cases this line wi
ll be ignoredif (temp_v.Len() <= AUTODIM_DISTANCE_
TOLERANCE) break ; //line parallel to the side-vec
torif ((temp_v % plane->get_normal()) > 0.0) break
; // material "above" the line}}if (NULL == start
_edge) {*list_of_points = NULL ;return 1 ;}// this
is the main loop.// initially we setstop_edge to
NULL. we would like to set it to start-edge, but w
e cannot,// because in that case we would never en
ter the loop. therefore we setit to NULL and right
// after we enter the loop, we set it to start_ed
ge.// (this is important in the case when the loop
consists of only one circle).stop_edge = NULL ;fo
r (edge = start_edge ; edge != stop_edge ; edge =
next_edge) {stop_edge = start_edge ;// compute the
next edge we will scannext_edge = (BM_EDGE *) edg
e->next() ;if (NULL == next_edge) next_edge = bloo
p->get_first_edge() ;switch (edge->get_type()) {ca
se BM_ENTITY_TYPE_LINE : { // compute distance for
start- and end-points// first, we want to ignore
lines that are parallel to the side-vector.// we a
lso want to ignore lines that have material "abov
e" them when looking in the// side-vector directio
n (because they cannot have to largest width, sinc
e material is// "above" them, there must be some o
ther edge bounding thebody from above).temp_v =
(((BM_LINE *) edge)->get_v()) * side_vector ;if (t
emp_v.Len() <= AUTODIM_DISTANCE_TOLERANCE) continu
e ; // line parallel to the side-vectorif ((temp_v
% plane->get_normal()) > 0.0) continue; // materi
al "above" the line// note that this leaves only l
ines whosedirection-vector goes to the "left"// of
the side-vector.// we need tocheck if this line i
s adjacent to a bendlineab = edge->get_adj_body()
;// check if this line is adjacent to a valid ben
dline (ie. one that is not the // bendline associa
ted with this BM_AD_bendline object).d1 = d2 =bend
_arc_outside_length_proj = 0.0 ;if (ab && ab != be
nd && ab->is(BM_ENTITY_TYPE_BENDLINE)) {// check i
f the bendline is being bentbop = ((BM_BENDLINE *)
ab)->get_bend_op() ;if ((parent->get_view_type())
/* have tohave a 3D view */ && ((BM_BENDLINE *) a
b)->get_bending_status() && bop){// a problem : it
could be that the bendline is not perpendicular t
o the side-vector.// in that case we need to proje
ct 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 appro
ximation value at all, since it plays no role in t
he width computation.temp_x = side_vector^ (((BM_L
INE *) edge)->get_v()) ; // temp_x is "angle_facto
r"if (temp_x> PI_over_2) temp_x = PI - temp_x ;tem
p_x = sin(temp_x) ;switch (bop->get_type()) {case
BM_TYPE_BEND_OP_REGULAR :bend_arc_outside_length_p
roj =((BM_BEND_OP_REGULAR *) bop)->compute_3D_outs
ide_approx_per_side() ;d1=temp_x*bend_arc_outside_
length_proj ;d2 = d1 ; // d2 is the same as d1!bre
ak ;// TODO : implement more bend operations here.
default : ; // unknown bend op}// compute some nee
ded parameters// compute : direction ofthe bend ar
c projected onto our planebend_arc_direction =
(((BM_LINE *)edge)->get_v()) * plane->get_normal()
;bend_direction = parent->compute_bend_direction_
vector((BM_BENDLINE *) ab, adj_body, &adj_bend_p2_
line) ;}}else ab = NULL ; // make sure ab does not
point to anything we don’twant to.// handle two
cases separately - depending on whether the dimens
ion list is open or not.if (fl_dim_open) {// if th
e dimension is open, we don’t need to check the s
tart-point of the line,// since it is at theflange
length distance anyway.// // first we will check
if the line isperpendicular to the side-vectorif
(fabs(side_vector % ((BM_LINE *) edge)->get_v()) >
AUTODIM_DISTANCE_TOLERANCE) {// not perpendicula
r.// thisline has to be "coming down" (because it
is not perpendicular to the//side-vector and the d
imension is open, ie. it cannot be "going up").//
now we have to close the dimension by creating a l
eft-hand-side dimensionpoint// from the start-poin
t of the line.if (temp_dp = create_dim_point(bend_
arc_outside_length_proj, ((BM_LINE *) edge)->get_s
tartpt(), rv, left_opening_direction, 0, this, adj
_body, list_of_points, side_vector, d1,bend_arc_di
rection, bend_direction, (BM_BENDLINE *) ab, adj_b
end_p2_line)) {list_of_points = &(temp_dp->next)
;}fl_dim_open = 0 ;}else {// is perpendicular.//
here we need to check the type of the next edge.//
if itis not line, we need to close the dimension
here by creating // a left-hand-side dimension poi
nt from the end-point of the line.// if the nexted
ge is a line, we can just continue.if (leave_dimen
sion_open(edge,bloop,side_vector,plane->get_normal
())) break ;if (temp_dp = create_dim_point(bend_ar
c_outside_length_proj, ((BM_LINE *) edge)->get_end
pt(), rv, left_opening_direction, 0, this, adj_bod
y, list_of_points, side_vector, d1,bend_arc_direct
ion, bend_direction, (BM_BENDLINE *) ab, adj_bend_
p2_line)) {list_of_points = &(temp_dp->next) ;}//
ok, close the dimension.fl_dim_open = 0 ;// this i
s a small trick that will save us some time.// if
the next edge is a line that will be ignored, we c
an skip is right now here.if (next_edge->is(BM_ENT
ITY_TYPE_LINE) && next_edge != stop_edge) {next_ed
ge = (BM_EDGE *) edge->next() ;if (NULL == next_ed
ge) next_edge = bloop->get_first_edge() ;}}break
;}if (! compute_distance_from_ref_point(rp, side_
vector, edge->get_edge_startpoint(), distance1)) c
ontinue ;if (! compute_distance_from_ref_point(rp,
side_vector, edge->get_edge_endpoint(), distance
2)) continue ;td1 = distance1 + d1 ;td2 = distance
2 + d2 ;// check if the start-point is a flange di
mension pointif (fabs(td1 - flange_length) <= AUTO
DIM_DISTANCE_TOLERANCE) {// check if the second po
int is a flange dimension pointif (fabs(td2 - flan
ge_length) > AUTODIM_DISTANCE_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(b
end_arc_outside_length_proj, ((BM_LINE *) edge)->g
et_startpt(), rv, right_opening_direction, 1, thi
s, adj_body,list_of_points, side_vector, d1, bend_
arc_direction, bend_direction, (BM_BENDLINE *) ab,
adj_bend_p2_line)) {list_of_points = &(temp_dp->n
ext) ;}break ;}// else open the dimension list// c
reate right flange dimensionpoint from start-point
if (temp_dp = create_dim_point(bend_arc_outside_le
ngth_proj, ((BM_LINE *) edge)->get_startpt(), rv,
right_opening_direction, 0, this, adj_body, list_o
f_points, side_vector, d1, bend_arc_direction, ben
d_direction, (BM_BENDLINE *) ab, adj_bend_p2_lin
e)) {list_of_points = &(temp_dp->next) ;}// check
if we can leave the dimension list openand continu
eif (leave_dimension_open(edge,bloop,side_vector,p
lane->get_normal())) {fl_dim_open = 1 ;break ;}//
create left flange dim point from end-point.if (te
mp_dp = create_dim_point(bend_arc_outside_length_p
roj,((BM_LINE *) edge)->get_endpt(), rv, left_open
ing_direction, 0, this, adj_body, list_of_points,
side_vector, d1, bend_arc_direction, bend_directio
n, (BM_BENDLINE *) ab, adj_bend_p2_line)) {list_of
_points = &(temp_dp->next) ;}// ok, close the dime
nsion list.fl_dim_open = 0 ;// this is asmall tric
k that will save us some time.// if the next edge
is a line that will be ignored, we can skip is rig
ht now here.if (next_edge->is(BM_ENTITY_TYPE_LINE)
&& next_edge != stop_edge) {next_edge = (BM_EDGE
*) edge->next() ;if (NULL == next_edge) next_edge
= bloop->get_first_edge() ;}break ;}else if (fabs
(td2 - flange_length) > AUTODIM_DISTANCE_TOLERANC
E){// the start-point is not a flange dimension po
int// if the end-pointis also not a flange dimensi
on point, we can continue.continue ;}// ok,only th
e end-point is a flange dimension point.// two pos
sibilities. ifwe can leave the dimension list open
(right now dimension is // closed!)we don’t even
have to open it, we can just continue.if (leave_d
imension_open(edge,bloop,side_vector,plane->get_no
rmal())) break ;// second possibility. now we have
to create a left-right flange dimension point.//
dimension list stays closed.if (temp_dp = create_d
im_point(bend_arc_outside_length_proj, ((BM_LINE
*) edge)->get_endpt(), rv, right_opening_directio
n, 1, this, adj_body, list_of_points, side_vector,
d1, bend_arc_direction, bend_direction, (BM_BENDL
INE *) ab, adj_bend_p2_line)) {list_of_points = &
(temp_dp->next) ;}// this is a small trick that wi
ll save us some time.// if the next edge is a line
that will be ignored, we can skip is right now he
re.if (next_edge->is(BM_ENTITY_TYPE_LINE) && next_
edge !=stop_edge) {next_edge = (BM_EDGE *) edge->n
ext() ;if (NULL == next_edge)next_edge = bloop->ge
t_first_edge() ;}}break ;case BM_ENTITY_TYPE_ARC :
{// note : we can always ignore the start-point of
the arc !// becauseof the way we keep track of th
e open dimension list.// make sure the dimension l
ist will be closed.fl_dim_open = 0 ;// first, comp
ute start- andend-angles of the arc with respect t
o the side vector.// ie. convert start- and end-an
gles so as if the side-vector was the 0-angle vect
or.double startang = ((BM_ARC *) edge)->get_starta
ng() ;double endang = ((BM_ARC *) edge)->get_endan
g() ;temp_v = side_vector*(((BM_ARC *) edge)->get_
vx()) ;double delta_angle = (temp_v.Len())/(((BM_A
RC *) edge)->get_rad());if (delta_angle < -1.0) de
lta_angle = -1.0 ;else if (delta_angle > 1.0) delt
a_angle = 1.0 ;delta_angle = asin(delta_angle) ;if
(fabs((((BM_ARC*) edge)->get_normal())%temp_v) >
0.0) {startang += delta_angle ;endang+= delta_angl
e ;if (startang > PI_times_2) startang -= PI_times
_2 ;if (endang > PI_times_2) endang -= PI_times_2
;}else {startang -= delta_angle ;endang -= delta_
angle ;if (startang < 0.0) startang += PI_times_2
;if(endang < 0.0) endang += PI_times_2 ;}// compu
te the extreme pointBM_POINT arc_extreme_point ;//
0-angle point is the extreme pointif (endang <sta
rtang) arc_extreme_point = ((BM_ARC *) edge)->get_
center() + (((BM_ARC *) edge)->get_rad())*side_vec
tor ;else arc_extreme_point = *(((BM_ARC*) edge)->
get_edge_endpoint()) ;// check the distance of the
extreme pointif (! compute_distance_from_ref_poin
t(rp, side_vector, &arc_extreme_point, distance1))
continue ;if (fabs(distance1 - flange_length) <=
AUTODIM_DISTANCE_TOLERANCE) {// if we have the 0-a
ngle point, create a left-right flange dimension p
oint.// otherwise if next line is a non-ignored li
ne, don’t do anything,// otherwise create a left-
right flange dimension point.if (endang >= startan
g && leave_dimension_open(edge,bloop,side_vector,p
lane->get_normal())) {continue ;}// create a left-
right flange dimension point. dimension list stays
closed.// this is a 1-point flange dimension poin
t.if (temp_dp = new BM_AD_dim_corner(rv + arc_extr
eme_point, this, adj_body,right_opening_direction,
1, list_of_points, NULL)) {list_of_points = &(tem
p_dp->next) ;}}}break ;case BM_ENTITY_TYPE_CIRCLE
: // circles are a much simpler version of the ar
c case.{BM_POINT circle_extreme_point = ((BM_CIRCL
E *) edge)->get_center() + (((BM_CIRCLE *) edge)->
get_rad())*side_vector ;// we won’t check the dis
tance since it mustbe a flange dimension point// c
reate a left-right flange dimension point.// this
is a 1-point flange dimension point.if (temp_dp =
new BM_AD_dim_corner(rv + circle_extreme_point, th
is, adj_body,right_opening_direction, 1, list_of_p
oints, NULL)) {list_of_points = &(temp_dp->next)
;}}break;case BM_ENTITY_TYPE_ELLIPSE : // TODO :
implement ellipse here. shouldbe similar to the wa
y arc is handled.continue ;break ;default : contin
ue ; // unknown edge type}}/* OK、全て終了。*/*li
st_of_points = NULL ;return 1 ;}/*この関数は1つの
BM_AD_bendline構造に対するベンドラインディメンショ
ンポイントを計算する。注意: p1は、フランジ長が描
かれる隣接体の平面上にある。pはセンタポイントであ
る。 p2はベンドラインの側部のポイントである。注
意:この関数においては、我々は常にadj-body1およびa
dj-body2に対するベンド-ディメンションポイントを計
算する。このベンドラインは1または0の隣接体を持つこ
とになるが、我々は将来これらのポイントのビジビリテ
イを知る必要がある。*/int BM_AD_bendline::compute_
BM_AD_bendline(void){double metal_thickness ; // t
hickness of the sheetmetalBM_2D_BODY *bendline_dis
played_version ; // 3D-version of the bendlineBM_V
ECTOR temp_v ; // vectorused for very short period
s for storing temporary stuff// initally markthe b
endline data as invalid, in case we fail here.data
_valid = 0 ;// qualification checkif (NULL == ben
d) return 0 ;if (NULL == bend->get_adj_list()) ret
urn 0 ;if (NULL == bend->get_part()) return 0 ;//
this bendline has to have a 3D-versionif (parent->
get_view_type()) {if (NULL == (bendline_displayed_
version = bend->get_current_3D_version())) return
0 ;}else {if (NULL == (bendline_displayed_version
= bend->get_flat())) return0 ;}metal_thickness =
(bend->get_part())->get_metal_thickness() ;/* ****
****** ********** ********** ********** **********
********** ********** ********** **********これは
一時的な測度である。我々は単に規則的なベンドライン
を処理する。すなわち、円錐ベンドラインは無視する。
03/16/96. KK.*/if (bend->get_bending_status() && b
end->get_bend_op() && ! (bend->get_bend_op())->is
(BM_TYPE_BEND_OP_REGULAR)) return 0 ;/* **********
********** ********** ********** ********** *****
***** ********** ********** ********** */// get th
e number of adjacent bodies.adj_body1 = (bend->get
_adj_list())->find_lowest_id_adj_body() ;adj_body2
= (bend->get_adj_list())->find_second_lowest_id_a
dj_body() ;num_of_adjacent_bodies = (adj_body1? 1
: 0) + (adj_body2 ? 1 : 0) ;/*サイドベクトルを計
算する。*/if (adj_body1) {if (! bendline_displayed
_version->compute_vector_perp_towards_adj_body(adj
_body1, side_vector1)) return 0 ;side_vector1.norm
alise() ;}if(adj_body2) {if (! bendline_displayed_
version->compute_vector_perp_towards_adj_body(adj_
body2, side_vector2)) return 0 ;side_vector2.norma
lise();}/*ベンドラインディメンションポイントを計算
する。*/if (! bend->get_bending_status() /* bendli
ne not bent */ || ! parent->get_view_type() /* fla
t view */) {// note : here we don’t know whether
the dimension point is OUTSIDE or INSIDE.// this h
as to be taken into account later.// however, it s
hould work either way.bend_body1_point_left.num_of
_points = bend_body1_point_right.num_of_points = 1
;bend_body1_point_left.can_reverse_opening_dir =
bend_body1_point_right.can_reverse_opening_dir = 0
;bend_body1_point_left.p = (bendline_displayed_ve
rsion->get_current_center_line()).get_startpt() ;b
end_body1_point_right.p = (bendline_displayed_vers
ion->get_current_center_line()).get_endpt() ;// no
te opening directions. left will get start-point,
right will get end-point, ie. vector goes left->ri
ght.bend_body1_point_right.opening_direction = (be
ndline_displayed_version->get_current_center_lin
e()).get_v() ;(bend_body1_point_right.opening_dire
ction).normalise() ;bend_body1_point_left.opening_
direction = -(bend_body1_point_right.opening_direc
tion) ;// points with respect to bothadjacent bodi
es are the samebend_body2_point_left.num_of_points
= bend_body2_point_right.num_of_points = 1 ;bend_
body2_point_left.can_reverse_opening_dir = bend_bo
dy2_point_right.can_reverse_opening_dir = 0 ;bend_
body2_point_right.opening_direction = bend_body1_p
oint_right.opening_direction ;bend_body2_point_lef
t.opening_direction = bend_body1_point_left.openin
g_direction ;bend_body2_point_left.p = bend_body1_
point_left.p ;bend_body2_point_right.p = bend_body
1_point_right.p ;}else {// first, get some bending
parametersBM_SURFACE *surface = bendline_displaye
d_version->get_surface() ;if (NULL == surface) ret
urn 0 ;BM_BEND_OP *bop = bend->get_bend_op() ;if
(NULL == bop) return 0 ;double bend_angle = bop->g
et_bend_angle2() ;double bend_arc_angle = PI - ben
d_angle ;double half_bend_arc_angle = bend_arc_ang
le/2.0 ;switch (surface->get_type()) {case BM_TYPE
_CYLINDER : { // note that the bend op can be both
regular and conicBM_CYLINDER *cylinder = (BM_CYLI
NDER *) surface ;double radius = cylinder->get_rad
() ;double outside_radius = radius ;if (bendline_d
isplayed_version->get_sense()) outside_radius += m
etal_thickness ;// set some common valuesbend_body
1_point_left.can_reverse_opening_dir = bend_body1_
point_right.can_reverse_opening_dir = 0 ;bend_body
1_point_right.opening_direction =(bendline_display
ed_version->get_current_center_line()).get_v() ;(b
end_body1_point_right.opening_direction).normalise
() ;bend_body1_point_left.opening_direction = -(be
nd_body1_point_right.opening_direction) ;if (outsi
de_radius <= AUTODIM_DISTANCE_TOLERANCE) {// speci
al case : outside radius 0 - trivial dimension poi
nt.bend_body1_point_left.num_of_points = bend_body
1_point_right.num_of_points = 1 ;bend_body1_point_
left.p = (bendline_displayed_version->get_current_
center_line()).get_startpt() ;bend_body1_point_rig
ht.p = (bendline_displayed_version->get_current_ce
nter_line()).get_endpt() ;bend_body2_point_left.nu
m_of_points = bend_body2_point_right.num_of_points
= 1 ;bend_body2_point_left.can_reverse_opening_di
r= bend_body2_point_right.can_reverse_opening_dir
= 0 ;bend_body2_point_right.opening_direction = be
nd_body1_point_right.opening_direction ;bend_body2
_point_left.opening_direction = bend_body1_point_l
eft.opening_direction ;bend_body2_point_left.p = b
end_body1_point_left.p ;bend_body2_point_right.p =
bend_body1_point_right.p ;}else {bend_body1_point
_left.num_of_points = bend_body1_point_right.num_o
f_points = 3 ;// compute points p1 for adj_body1be
nd_body1_point_left.p1 = (bendline_displayed_versi
on->get_current_center_line()).get_startpt() ;bend
_body1_point_right.p1 = (bendline_displayed_versio
n->get_current_center_line()).get_endpt() ;// thep
roblem now is that it could be that these centerli
ne points (which are// on the surface of the bendl
ine), could be only inside surface of thebendline.
if (bendline_displayed_version->get_sense() && met
al_thickness> AUTODIM_DISTANCE_TOLERANCE) {temp_v
= cylinder->get_vx() ;temp_v.set_length(metal_thic
kness) ;bend_body1_point_left.p1 = bend_body1_poin
t_left.p1 + temp_v ;bend_body1_point_right.p1 = be
nd_body1_point_right.p1 + temp_v ;}// a break in t
he computation of adj_body1.p1.// store current p1
values for adj_body2 as well. this will save some
time.// // note thatwe should not really compute a
dj_body2 points unless adj_body2 pointer//is not N
ULL. However, this point (adj_body2.p1) is very us
eful for computing// adj_body1.p2 (if angle is acu
te). so we compute it anyway.bend_body2_point_lef
t.p1 = bend_body1_point_left.p1 ;bend_body2_point_
right.p1= bend_body1_point_right.p1 ;// finish adj
_body1.p1. rotate points p1 into their final corre
ct location.// note we rotate in the negative dire
ction since adj_body1 is the smallest-index// adja
cent body as is "to-the-left-of-the-bendline-cente
rline", which means// rotating to the left.//firs
t, compute the right vector for the rotation line.
BM_VECTOR rot_v(cylinder->get_v()) ;if (rot_v %
((bendline_displayed_version->get_current_center_l
ine()).get_v()) < 0.0) {rot_v.reverse() ;}BM_rotat
e_point_around_line(&(bend_body1_point_left.p1), c
ylinder->get_pt1(), rot_v, -half_bend_arc_angle) ;
BM_rotate_point_around_line(&(bend_body1_point_rig
ht.p1),cylinder->get_pt1(), rot_v, -half_bend_arc_
angle) ;// finish also adj_body2.p1. rotate points
p1 into their final correct location.BM_rotate_po
int_around_line(&(bend_body2_point_left.p1), cylin
der->get_pt1(), rot_v,half_bend_arc_angle) ;BM_rot
ate_point_around_line(&(bend_body2_point_right.p
1), cylinder->get_pt1(), rot_v, half_bend_arc_angl
e) ;// compute points p for adj_body1.double x ;if
(bop->is(BM_TYPE_BEND_OP_REGULAR)) {x= ((BM_BEND_
OP_REGULAR *) bop)->compute_3D_outside_approx_per_
side() ;}else if (bop->is(BM_TYPE_BEND_OP_CONIC))
{// TODO : implement conic bendline herereturn 0
;}temp_v = -x*side_vector1 ;bend_body1_point_lef
t.p = bend_body1_point_left.p1 + temp_v ;bend_body
1_point_right.p = bend_body1_point_right.p1 + temp
_v ;// note : adj_body1.p2 and adj_body2.p, adj_bo
dy2.p2 are yet to be computed.// now there are two
cases : 1) the bend arc angle is acute (ie. no mo
re than 90 degrees),// 2) the bend arc angleis mor
e than 90 degrees.if (bend_arc_angle > (PI_over_2
+ BM_ANGLE_TOLERANCE)) { // use tangent approximat
ion// we will finish computing adj_body1. adj_body
1.p2 is left.// idea : notice that adj_body1 is to
the leftof the bendline-centerline// because it i
s the lowest-index neighbor. Therefore the cross-p
roduct// of centerline-v by temp_v points towards
thecylinder (actually it is tangent// to the cylin
der).BM_VECTOR tangent_v(bend_body1_point_right.op
ening_direction * temp_v) ;tangent_v.set_length(x)
;bend_body1_point_left.p2 = bend_body1_point_lef
t.p + tangent_v ;bend_body1_point_right.p2 = bend_
body1_point_right.p + tangent_v ;// noteadj_body2.
p1 is already computed. first set some common valu
es.bend_body2_point_left.num_of_points = bend_body
2_point_right.num_of_points = 3 ;bend_body2_point_
left.can_reverse_opening_dir = bend_body2_point_ri
ght.can_reverse_opening_dir = 0 ;bend_body2_point_
right.opening_direction = bend_body1_point_right.o
pening_direction ;bend_body2_point_left.opening_di
rection = bend_body1_point_left.opening_direction
;// now compute adj_body2.ptemp_v = -x*side_vecto
r2 ;bend_body2_point_left.p = bend_body2_point_lef
t.p1 + temp_v ;bend_body2_point_right.p = bend_bod
y2_point_right.p1+ temp_v ;// finally, compute adj
_body2.p2// note the order in the cross-product !t
angent_v = temp_v * bend_body2_point_right.opening
_direction; tangent_v.set_length(x) ;bend_body2_po
int_left.p2 = bend_body2_point_left.p + tangent_v
;bend_body2_point_right.p2 = bend_body2_point_rig
ht.p+ tangent_v ;}else { // use intersection appro
ximation// note : adj_body2.p2 is the same as asj_
body1.p1.bend_body1_point_left.p2 = bend_body2_poi
nt_left.p1 ;bend_body1_point_right.p2 = bend_body2
_point_right.p1 ;//when using intersection approxi
mation, dimensions points with respect to// both a
djacent bodies are the same, so we just copy them.
bend_body2_point_left.num_of_points = bend_body2_p
oint_right.num_of_points = 3 ;bend_body2_point_lef
t.can_reverse_opening_dir = bend_body2_point_righ
t.can_reverse_opening_dir = 0 ;bend_body2_point_ri
ght.opening_direction = bend_body1_point_right.ope
ning_direction ;bend_body2_point_left.opening_dire
ction = bend_body1_point_left.opening_direction ;/
/ note we are switchingpointsbend_body2_point_lef
t.p2 = bend_body1_point_left.p1 ;bend_body2_point_
right.p2 = bend_body1_point_right.p1 ;bend_body2_p
oint_left.p = bend_body1_point_left.p ;bend_body2_
point_right.p = bend_body1_point_right.p ;}}}break
;case BM_TYPE_CONE :break ;default : ; // unknown
or illegalsurface ;}}/*隣接体の各々に対するフラン
ジ長を計算する。*/if (adj_body1){// if the flange
length computation fails, pretend the adjacent bod
y does not exist. for simplicity.if (! bend->compu
te_flange_length(parent->get_view_type(),adj_body
1,fl1)) {adj_body1 = NULL ;--num_of_adjacent_bodie
s ;}}if (adj_body2) {if (! bend->compute_flange_le
ngth(parent->get_view_type(),adj_body2,fl2)) {adj_
body2 = NULL ;--num_of_adjacent_bodies ;}}/*よし、
データを有効なものとしてマークする。ベンドラインデ
ィメンションポイントが全てのベンドラインに対して計
算されると、我々は同様に巣手のベンドラインに対して
フランジディメンションポイントを計算することが出来
る。*/data_valid = 1 ;// before we can return, we
have to check if body1,2 left(right) bendline dime
nsion points // are the same.// note the same mean
snot the same pointers, but the contents are equiv
alent.if (adj_body1 &&adj_body2) {body12_left_the_
same = (bend_body1_point_left == bend_body2_point_
left) ;body12_right_the_same = (bend_body1_point_r
ight == bend_body2_point_right) ;}/*重要:ベンド-
ディメンションポイントのいずれかが1ポイント(ポイ
ントp)のみを含むときは、実際には見るべきベンドラ
インがないのでbody_required_visibleポインタは隣接
体を指示するべきである。*/if (1 ==bend_body1_point
_left.num_of_points) bend_body1_point_left.body_re
quired_visible = adj_body1 ;if (1 == bend_body1_po
int_right.num_of_points) bend_body1_point_right.bo
dy_required_visible = adj_body1 ;if (1 == bend_bod
y2_point_left.num_of_points) bend_body2_point_lef
t.body_required_visible= adj_body2 ;if (1 == bend_
body2_point_right.num_of_points) bend_body2_point_
right.body_required_visible = adj_body2 ;return 1
;}/*********** ********** ********** ********** *
********* ********** ********** ********** *******
***BM_AUTO_DIMENSION class stuff.********** ******
**** ********** ********** ********** ********** *
********* ********** ***********//*確実な発見的手
法:ソリッドモードにおいて幾つかのポイントを我々が
無視出来るか否かをチェックする。ソリッドモードにお
いては、我々は時間の節約のためにこの発見的手法を用
いている。2つのベンドラインがフランジ-長を表示す
るために(潜在的に)等価なフランジ-ディメンション
ポイントを用いているときは、我々は単に、より高いid
xを持つベンドライン(これらの2つのベンドラインに
対する)に対してのみビジビリテイ情報を計算する。*/
void BM_AUTO_DIMENSION::compute_points_to_ignore_i
n_solid(void){int i ;BM_AD_dim_corner*temp_point ;
for (i = 0 ; i < num_of_bendlines ; i++) {if (! be
nds[i]->data_valid) continue ;if (bends[i]->adj_bo
dy1) {for (temp_point = bends[i]->body1_points ; t
emp_point ; temp_point = temp_point->next) {if (NU
LL== temp_point->adj_bendline) continue ;if ((temp
_point->adj_bendline)->get_idx() > (bends[i]->ben
d)->get_idx()) continue ;if (check_two_bendlines_a
djacent_to_same_flange(bends[i]->bend,bends[i]->ad
j_body1,temp_point->adj_bendline)) {temp_point->ig
nore_in_solid_mode = 1 ;}}}if (bends[i]->adj_body
2) {for (temp_point = bends[i]->body2_points ; tem
p_point ; temp_point = temp_point->next) {if (NULL
== temp_point->adj_bendline) continue ;if ((temp_
point->adj_bendline)->get_idx() > (bends[i]->bend)
->get_idx()) continue ;if (check_two_bendlines_adj
acent_to_same_flange(bends[i]->bend,bends[i]->adj_
body2,temp_point->adj_bendline)) {temp_point->igno
re_in_solid_mode = 1 ;}}}}points_to_ignore_in_soli
d_computed = 1 ;}/*この関数は自動寸法化ベンドライ
ンを構成し、データ構造を指示する。これはディメンシ
ョンポイントを計算する主要関数である。*/int BM_AUT
O_DIMENSION::compute_auto_dimension_data(void){int
i ;// have to have a documentif (NULL == doc) ret
urn 0 ;// if no part, try to get a new part from t
he documentif (NULL == part) {set_part(doc->get_pa
rt()) ;}if (NULL == part) {dirty =0 ;return 1 ;}po
ints_to_ignore_in_solid_computed = 0 ;/*ビユータイ
プを得る。*/if (view) {view_type = view->get_curre
nt_view() ;}else {// we are screwedreturn 0 ;}/*全
てのベンドラインに対して全てのベンドラインディメン
ションポイントを計算する。*/for (i = 0 ; i < num_o
f_bendlines ; i++) {bends[i]->compute_BM_AD_bendli
ne() ;}/*全てのベンドラインに対してフランジディメ
ンションポイントを計算する。*/for (i = 0 ; i < num
_of_bendlines; i++) {if (bends[i]->data_valid) {if
(bends[i]->adj_body1) bends[i]->compute_BM_AD_fla
nge_points(bends[i]->adj_body1) ;if (bends[i]->adj
_body2)bends[i]->compute_BM_AD_flange_points(bends
[i]->adj_body2) ;}}dirty = 0;return 1 ;} 付録I 幾つかの基本的自動寸法化関数、コンストラクタ、デス
トラクタおよび幾つかの他の基本的関数の例 //#include "stdafx.h"#include "BendCAD.h"#include
"BendCADDoc.h"#include"BendCADViewPart.h"#include
"AUTODIM.HXX"/*********** ********** ********** *
********* ********** ********** ********** *******
*** **********BM_AD_dim_corner class stuff.*******
*** ********** ********** ********** ********** **
******** ********** ********** ***********/BM_AD_d
im_corner::BM_AD_dim_corner(void) {visible = -1 ;n
um_of_points = 0 ;bend = NULL ;next = NULL ;adj_be
ndline = NULL ;body_required_visible = NULL ;ignor
e_in_solid_mode = 0 ;}/*このコンストラクタは中にた
だ1つのポイント(ポイントp)を持つディメンション
ポイントを生成するためのものである。*/BM_AD_dim_co
rner::BM_AD_dim_corner(BM_POINT const& P, BM_AD_be
ndline *B, BM_3D_BODY*Body_required_visible,BM_VEC
TOR const& OD, int RB, BM_AD_dim_corner **prev, BM
_BENDLINE *adj_bend){visible = -1 ;num_of_points =
1 ;p = P ;bend = B ;opening_direction = OD ;can_r
everse_opening_dir = RB ;next = NULL;body_required
_visible = Body_required_visible ;adj_bendline = a
dj_bend;ignore_in_solid_mode = 0 ;if (prev) *prev
= this ;}/*このコンストラクタは中に3ポイントを持つ
ディメンションポイントを生成するためのものである。
*/BM_AD_dim_corner::BM_AD_dim_corner(BM_POINT cons
t& P, BM_POINT const& P1, BM_POINT const& P2, BM_A
D_bendline *B, BM_3D_BODY *Body_required_visible,B
M_VECTOR const& OD, int RB, BM_AD_dim_corner **pre
v, BM_BENDLINE*adj_bend){visible = -1 ;num_of_poin
ts = 3 ;p = P ;p1 = P1 ;p2 = P2 ;bend = B ;opening
_direction = OD ;can_reverse_opening_dir = RB ;nex
t = NULL ;body_required_visible = Body_required_vi
sible ;adj_bendline = adj_bend ;ignore_in_solid_mo
de = 0 ;if (prev) *prev = this ;}/*1つのディメン
ションポイントを他のディメンションポイントに割り当
てる。この関数は内容を正確にコピーする。それが非常
に有用な関数であるか否かは確実ではない。*/voidBM_A
D_dim_corner::operator=(BM_AD_dim_corner const& gi
ven_point){num_of_points = given_point.num_of_poin
ts ;p = given_point.p ;p1 = given_point.p1 ;p2 = g
iven_point.p2 ;bend = given_point.bend ;opening_di
rection = given_point.opening_direction ;can_rever
se_opening_dir = given_point.can_reverse_opening_d
ir ;visible = given_point.visible ;screen_x = give
n_point.screen_x ;screen_y = given_point.screen_y
;z_buf_value = given_point.z_buf_value ;ignore_in
_solid_mode = given_point.ignore_in_solid_mode ;}/
*この関数は、もしディメンションを描くために所定の
ポイントがこのポイントと同じときはTRUEを戻す。2つ
のディメンションポイントは、それらの1つのポイント
pが他のディメンションポイントのライン(ポイントp,
開放方向)により定義されるライン上にあるとき、また
それらの開放方向が一致するとき、等価である。ここで
我々は、開放ベクトルが規格化されるという事実に依存
する。it returns 2 iff both points p match, otherw
ise 1.*/int BM_AD_dim_corner::operator==(BM_AD_dim
_corner const& another_dim_point){int ret_val = 1
;double k ;if (num_of_points < 1 || another_dim_p
oint.num_of_points < 1) return 0 ;// point has to
be on the lineif (! BM_is_point_on_line(p, opening
_direction, another_dim_point.p, &k)) return 0 ;if
(fabs(k) <= BM_PRECISION) ret_val = 2 ;// since b
oth vectors should be normalized, the dot-product
is the cos of the angle.double x = opening_directi
on % another_dim_point.opening_direction ;// check
if both vectors agreeif (x > 0.99) return ret_val
;// check if they have opposite direction and one
of the can be reversedif (x < -0.99) {if (can_rev
erse_opening_dir || another_dim_point.can_reverse_
opening_dir) return ret_val ;}return 0 ;}/********
************* ********** ********** ********** ***
******* ********** ********** **********BM_AD_bend
line class stuff.********** ********** **********
********** ********** ********** ********** ******
**** ***********/BM_AD_bendline::BM_AD_bendline(BM
_AUTO_DIMENSION *owner, BM_BENDLINE *bendline){par
ent = owner ;bend = bendline ;data_valid = 0 ; //
data not valid - no data computed yetbend_body1_po
int_left.bend = bend_body1_point_right.bend = this
;bend_body2_point_left.bend = bend_body2_point_ri
ght.bend = this ;bend_body1_point_left.body_requir
ed_visible = bend_body1_point_right.body_required_
visible = bend ;bend_body2_point_left.body_require
d_visible = bend_body2_point_right.body_required_v
isible = bend ;body1_points = NULL ;body2_points =
NULL ;}BM_AD_bendline::~BM_AD_bendline(void){BM_A
D_dim_corner *temp_point, *temp_p ;// delete lists
of pointsfor (temp_point = body1_points ; temp_po
int ; temp_point = temp_p) {temp_p = temp_point->n
ext ;delete temp_point ;}for (temp_point = body2_p
oints ; temp_point ; temp_point = temp_p) {temp_p
= temp_point->next ;delete temp_point ;}}/********
*** ********** ********** ********** ********** **
******** ********** ********** **********BM_AUTO_D
IMENSION class stuff.********** ********** *******
*** ********** ********** ********** *************
******* ***********/BM_AUTO_DIMENSION::BM_AUTO_DIM
ENSION(CBendCADDoc*BendCAD_doc){doc = BendCAD_doc
;view = (CBendCADViewPart *) doc->get_view(BENDCA
D_VIEW_TYPE_PART) ;dc = NULL ;part = NULL ;dirty =
1 ;view_type= 1 ; // 3D viewreset_view_to_false_o
nce_drawn = 0 ;points_to_ignore_in_solid_computed
= 0 ;num_of_bendlines = 0 ;bends = NULL ;// initia
lize show states for dimension infom_bShowFlangeDi
m = TRUE;m_bShowBendDim = TRUE;m_bShowPartDim = FA
LSE;// initialize Auto-Dim colorsm_crFlange = RGB
(0,0,255);m_crBend = RGB(0,0,255);m_crPart = RGB
(0,0,255);// initialize font pointersm_pFlangeFont
= NULL;m_pBendFont = NULL;m_pPartFont = NULL;// i
nitialize line and arrow stylesm_nLineStyle = PS_S
OLID;m_nLineWeight= 1;// in pixelsm_nArrowStyle =
1;m_nArrowAngle = 30;// in degreesm_nArrowLength =
15;// in pixels// initialize dirty region pointer
pDirtyRegion= NULL;}BM_AUTO_DIMENSION::~BM_AUTO_DI
MENSION(void){delete_contents() ;}/*この自動-寸法
化対象を破壊する。*/void BM_AUTO_DIMENSION::delete
_contents(void){int i ;if (bends) {for (i = 0 ; i
< num_of_bendlines ; i++) {if (bends[i]) delete be
nds[i] ;}delete [] bends ;bends = NULL ;}num_of_be
ndlines = 0 ;points_to_ignore_in_solid_computed =
0 ;part = NULL ;dirty= 1 ;}/*この関数は所定のベン
ドラインに係わるディメンションデータを含むBM_AD_be
ndline構造に対するポインタを戻す。*/BM_AD_bendline
*BM_AUTO_DIMENSION::get_AD_bend_structure(BM_BEND
LINE *bendline){int i ;for (i = 0 ; i< num_of_bend
lines ; i++) {if (bends[i]->bend == bendline) retu
rn bends[i] ;}return NULL ;}/*この関数は所定のadj-
bodyに対する所定のベンドラインに対する(p->p2)ベク
トルを戻す。それはまたこのフランジに対する隣接ベン
ドラインのベンドディメンションポイントのp2ポイント
の間のラインを計算する。
【0392】*/BM_VECTOR const& BM_AUTO_DIMENSION::
compute_bend_direction_vector(BM_BENDLINE *bendlin
e, BM_3D_BODY *adj_body, BM_LINE *p2_line){static
BM_VECTOR v ;int i ;for (i = 0 ; i < num_of_bendli
nes ; 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]->b
end_body1_point_right).p2) ;return v ;}else if (be
nds[i]->adj_body2== adj_body) {v = (bends[i]->bend
_body2_point_left).p2 - (bends[i]->bend_body2_poin
t_left).p ;p2_line->set((bends[i]->bend_body2_poin
t_left).p2,(bends[i]->bend_body2_point_right).p2)
;return v ;}}}return BM_null_vector ;}/*この関数
は、フランジディメンションポイントが所定のadj-body
に隣接するという事実を考慮するため所定のベンドライ
ンに対するフランジ長を描く効果を伝搬させるために用
いられる。それは、 adj-bendが所定のフランジに対し
て同様に描かれるものとしてマークされるときTRUEを戻
す。*/int BM_AUTO_DIMENSION::compute_effects_flang
e_length_drawn(BM_BENDLINE *bendline, BM_3D_BODY *
adj_body, BM_AD_dim_corner *bend_dim_point /* bend
dim point for bendline */, BM_AD_dim_corner *flan
ge_dim_point /* flange dim points forbendline */,
BM_BENDLINE *adj_bend){BM_AD_dim_corner **p_body_p
oints ;int *p_body_drawn ;BM_AD_dim_corner **p_dra
wn_bend_dim_point ;BM_AD_dim_corner **p_drawn_flan
ge_dim_point ;int i ;// first we have to find a BM
_AD_bendline structure for this adj-bendfor (i = 0
; i < num_of_bendlines ;i++) {if (! bends[i]->dat
a_valid || bends[i]->bend != adj_bend || bends[i]-
>ignore) continue ;if (bends[i]->adj_body1 == adj_
body) {if (bends[i]->body1_drawn) return 0 ;p_body
_points = &(bends[i]->body1_points) ;p_body_drawn
= &(bends[i]->body1_drawn) ;p_drawn_bend_dim_point
= &(bends[i]->drawn_bend_dim_point1) ;p_drawn_flan
ge_dim_point= &(bends[i]->drawn_flange_dim_point1)
;break ;}else if (bends[i]->adj_body2 == adj_bod
y) {if(bends[i]->body2_drawn) return 0 ;p_body_poi
nts = &(bends[i]->body2_points) ;p_body_drawn = &
(bends[i]->body2_drawn) ;p_drawn_bend_dim_point =
&(bends[i]->drawn_bend_dim_point2) ;p_drawn_flange
_dim_point = &(bends[i]->drawn_flange_dim_point2)
;break ;}else return 0 ;}if (i >= num_of_bendline
s) return 0 ;// now we need to check if the list o
f flange dimensionpoints for this newly found // B
M_AD_bendline structure contains any flange dimens
ion points that are adjacent to our bendlineBM_AD_
dim_corner*temp_point ;for (temp_point = *p_body_p
oints ; temp_point ; temp_point= temp_point->next)
{if (temp_point->adj_bendline == bendline) break
;}if (NULL == temp_point) return 0 ;// mark the f
lange length for the adj-bend drawn with respect t
o this adj-body*p_body_drawn = 1 ;*p_drawn_bend_di
m_point = flange_dim_point ;*p_drawn_flange_dim_po
int = bend_dim_point;return 1 ;}/*この関数は、 adj
_bendが、所定のベンドラインに隣接する所定のフラン
ジに対してフランジ-ディメンションポイントを持つと
きTRUEを戻す。*/int BM_AUTO_DIMENSION::check_two_b
endlines_adjacent_to_same_flange(BM_BENDLINE *bend
line, BM_3D_BODY *flange, BM_BENDLINE *adj_bend){B
M_AD_dim_corner **p_body_points ;int i ;// first w
e have to find a BM_AD_bendlinestructure for this
adj-bendfor (i = 0 ; i < num_of_bendlines ; i++)
{if(! bends[i]->data_valid || bends[i]->bend != ad
j_bend) continue ;if (bends[i]->adj_body1 == flang
e) {p_body_points = &(bends[i]->body1_points);brea
k ;}else if (bends[i]->adj_body2 == flange) {p_bod
y_points = &(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 dimens
ion pointsfor this newly found // BM_AD_bendline s
tructure contains a flange dimension points that i
s adjacent to our bendlineBM_AD_dim_corner *temp_p
oint ;for (temp_point = *p_body_points ; temp_poin
t ; temp_point = temp_point->next) {if (temp_point
->adj_bendline == bendline) return 1 ;}return 0;}/
*新しい部分を設定する。これは同様にビユークラスポ
インタを更新し、幾つかの他のパラメータを設定する。
*/void BM_AUTO_DIMENSION::set_part(BM_PART *new_pa
rt){BM_BENDLINE *bendlist ;int i ;delete_content
s() ;if (NULL== doc) return ;part = new_part ;if
(NULL == part) return ;half_metal_thickness = (par
t->get_metal_thickness())/2.0 ;// allocate the ben
dlistif(0 == (num_of_bendlines = part->get_number_
of_bendlines())) return ;if(NULL == (bends = new B
M_AD_bendline*[num_of_bendlines])) goto failure ;b
endlist = part->get_bendline_list() ;for (i = 0 ;
i < num_of_bendlines ;i++) {if (bendlist) {bends
[i] = new BM_AD_bendline(this,bendlist) ;bendlist
= (BM_BENDLINE *) bendlist->next() ;}else bends[i]
= NULL ;}// note, dirty is TRUEreturn ;failure :d
elete_contents() ;} 付録J 薄板部分に対するエンティティビジビリテイ関数を含む
ベンドモデルビユワ実施の例 #include "stdafx.h"// include all BMAPI files#incl
ude "ALLBMAPI.HXX"// RW_DRAW library include file.
#include "RW_DRAW.HXX"#include "BendCADDoc.h"#incl
ude "BendCADViewPart.h"// RenderWare include file
s; found in \rwwin\include#include "rwlib.h"// Ope
nGL include files.#include "gl\gl.h"#include "gl\g
lu.h"// GL_LIST library include file.#include "GL_
LIST.HXX"#include <stdlib.h> /* ワールド座標に
おけるポイントを表すBM_POINTが与えられると、人はそ
れをビユーウインド座標上に射影することが出来る。
A) Ifthe display is showing the SOLID version of t
he part, this function passes back a pointer to th
e edge closest to the camera that lies undert
hat projected point. The x_pos, y_pos, and z_depth
pointers carry theview window coordinates (with t
op left corner as (0,0) and the z-buffervalue. If
the projected point is not in the viewing volume,
the returnvalue is 0; then of course the edge poi
nter is meaningless, and is set to NULL. If the pr
ojected point IS within the viewing volume, then
thereturn value is 1, and the edge pointer points
to the edge that lies under the projected point.
If the pointer is NULL, no edge lies under thepr
ojected point. B) If the display is showing the W
IREFRAME version ofthe part, only the return valu
e: 1 if within view volume, 0 otherwise - shou
ld be examined. If return value is 1, x_pos, y_pos
and z_depth values have meaning. The edge pointer
is always NULL.*/int CBendCADViewPart::map_point_
to_closest_edge(BM_POINT const& three_d_point, int
*x_pos,int *y_pos,
double *z_depth,BM_EDGE **closest_ed
ge){ int x, y, visible = 1; double z; visible
= map_3d_to_screen(three_d_point, &x, &y, &z); if
( ! visible ) {// Point is outside viewing volume.
if(closest_edge) *closest_edge = NULL;if(x_po
s) *x_pos = x;if(y_pos) *y_pos = y;if(z_depth) *z_
depth = z;return 0; } // Now point is inside vie
w volume. if(x_pos) *x_pos = x; if(y_pos) *y_pos
= y; if(z_depth) *z_depth = z; if(! mi_show_sol
id) { // Wireframe being drawn; ju
st return that point is if(closest_edge) *clos
est_edge = NULL; // within view vol.return 1; }
// Now solid is being shown. if(! closest_edge) r
eturn 1; //Point is within view volume. Pick that
point. pick_point_rw(x, y, closest_edge); retur
n 1;}// This function returns the view window coor
dinates of a point, with top left corner as (0,0),
and the // z-buffer depth,given the three-dimensi
onal world coordinates of the point. It does soby
calling either // map_3d_to_screen_solid or map_3d
_to_screen_wire, depending on whether wireframe or
solid is being shown. // On return, iff*x_pos, *y
_pos are both zero, the point was not mapped onto
the screenat all.int CBendCADViewPart::map_3d_to_s
creen(BM_POINT three_d_point, int*x_pos, int *y_po
s, double *z_depth){ int visible; if(mi_show_so
lid)visible = map_3d_to_screen_solid(three_d_poin
t, x_pos, y_pos, z_depth);else visible = map_3d_to
_screen_wire(three_d_point, x_pos, y_pos, z_dept
h); return visible;}// This function returns the
view window coordinates of a point, with top left
corner as (0,0), and the// z-buffer depth,given th
e three-dimensional world coordinates of the poin
t, using OpenGL utilities // (ie. when wireframe i
s on). If return value is 0, point is not mapped o
nto screen, ie. not visible.int CBendCADViewPart::
map_3d_to_screen_wire(BM_POINT three_d_point, int
*x_pos, int *y_pos, double *z_depth){ int viewp
ort[4], visible = 1; double width, height, depth;
double model_mat[16], proj_mat[16], array[16]; //
Get the current viewport coords. glGetIntegerv(G
L_VIEWPORT, viewport); // Now build a modelview m
atrix out of the current set of transformations.
glMatrixMode(GL_MODELVIEW); glPushMatrix(); gl
Translated(md_x_trans, md_y_trans, 0.0);convert_rw
_matrix_to_gl_array(md_rot_matrix, array);glMultMa
trixd(array);glTranslated(- m_part_centroid.X(), -
m_part_centroid.Y(), - m_part_centroid.Z()); g
lGetDoublev(GL_MODELVIEW_MATRIX, model_mat); gl
GetDoublev(GL_PROJECTION_MATRIX, proj_mat); glPop
Matrix(); gluProject(three_d_point.X(), three_d_p
oint.Y(), three_d_point.Z(), model_mat, proj_mat,
viewport, &width, &height,
&depth); if( ((int)width > m_old_rect.right) ||
((int)width < 0) ) visible = 0; if( ((int)height
> m_old_rect.bottom) || ((int)height < 0) ) visibl
e = 0; if(x_pos) *x_pos = (int) width; if(y_pos)
*y_pos = (m_old_rect.bottom - (int) height); if
(z_depth) *z_depth = depth; return visible;}
// This function returns the view window coordin
ates of a point, with top left corner as (0,0), an
d the// z-buffer depth, given the three-dimensiona
l world coordinates of the point, using RenderWare
utilities // (ie. when solid is on). If return va
lue is 0, point is not mapped onto the screen, ie.
not visible.// Note: At present, same as map_3d_to
_screen_wire.int CBendCADViewPart::map_3d_to_scree
n_solid(BM_POINT three_d_point, int *x_pos,int *y_
pos, double *z_depth){ int viewport[4], visible
= 1; doublewidth, height, depth; double model_m
at[16], proj_mat[16], array[16];// Get the current
viewport coords. glGetIntegerv(GL_VIEWPORT, view
port); // Now build a modelview matrix out of the
current set of transformations. glMatrixMode(GL_
MODELVIEW); glPushMatrix(); glTranslated(md_x_
trans, md_y_trans, 0.0);convert_rw_matrix_to_gl_ar
ray(md_rot_matrix, array);glMultMatrixd(array);glT
ranslated(- m_part_centroid.X(), - m_part_centroi
d.Y(), - m_part_centroid.Z()); glGetDoublev(GL_
MODELVIEW_MATRIX, model_mat); glGetDoublev(GL_P
ROJECTION_MATRIX, proj_mat); glPopMatrix(); gluP
roject(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.right) || ((int)width <
0) ) visible = 0; if( ((int)height > m_old_rect.b
ottom) || ((int)height < 0) )visible = 0; if(x_po
s) *x_pos = (int) width; if(y_pos) *y_pos = (m_ol
d_rect.bottom - (int) height); if(z_depth) *z_dep
th = depth; returnvisible; }// This function p
icks the point indicated by map_3d_to_screen, usin
g RenderWare picking, so this is// called only whe
n solid is being shown. Note that the pick positio
n is with respect to the top left// corner of the
view window being (0,0). If the pick results in an
edge, apointer to the edge is// passed back in pi
cked_edge; else, picked_edgeis set to null. This d
oes not modify the selection// set in any way.void
CBendCADViewPart::pick_point_rw(int x_pos, int y_p
os, BM_EDGE **picked_edge) { if(picked_edge == NU
LL) return; if( (x_pos > m_old_rect.right)|| (y_p
os > m_old_rect.bottom)) { // Make sure point giv
en is within*picked_edge = NULL;// viewport.retur
n; } RwClump *picked_clump = NULL;RwClump *pare
nt_clump = NULL; long parent_tag, clump_tag, key
= 0; BM_EDGE *edge = NULL; if(! RwPickScene(m_sc
ene, x_pos, y_pos, m_camera,&m_pick)) { // Picking
command was not successful. *picked_edge = NUL
L;return; } if(m_pick.type == rwNAPICKOBJECT)
{ // No clump was picked.*picked
_edge = NULL;return; } else if(m_pick.type == rw
PICKCLUMP) { // Some clump was p
icked; process it.picked_clump = m_pick.object.clu
mp.clump;parent_clump = RwGetClumpParent(picked_cl
ump);parent_tag = RwGetClumpTag(parent_clump);clum
p_tag =RwGetClumpTag(picked_clump);if(parent_tag =
= 1) { *picked_edge = NULL;return;
// A trivial bendline orf
orming was picked. } // Now some real edge w
as picked.key = (parent_tag%10000)*100000 + clump_
tag; if(clump_tag) // Safety check; we expect clum
p_tag to be non-zero. *picked_edge = map_list
_name_to_bm_edge(parent_tag, clump_tag); }}
// This function returns the ratio of the view vol
ume dimension (object space dimensions) to// the v
iewportdimension (device space dimensions).double
CBendCADViewPart::get_object_to_device_ratio(void)
{ double ratio; if(m_old_rect.right) ratio =
2.0*md_current_view_vol[0]/(double)(m_old_rect.rig
ht); else ratio = 0.0; return ratio;}/* Given a
BM_POINT, which represents a point in worldcoordi
nates, one can project it onto view window coordin
ates. This function first checks if the projected
point is within the viewing volume. If it IS withi
n viewing volume, the pointer "visible" carries va
lue 1; else, 0. If the point is not visible, no ot
her parameters have any meaning; the return value
is 0. Now suppose the point is visible. A) If th
e display is showing the SOLID version of the par
t, this function checks ifANY of the three_d_bodie
s in the array "three_db_array" lies "approximatel
y under" the projected point. If the answer is ye
s, return value is 1; else, return value is zero.
The x_pos, y_pos, and z_depth pointers carry the v
iew window coordinates (with top left corner as
(0,0)) and the z-buffer value. The array "thee_db_
array" must be terminated by a NULL pointer to ind
icate end of array. B) If the display is showing
the WIREFRAME version of the part the return value
is always zero. If the point is within view volu
me, *visible is set to 1; else, 0. If *visible is
1, x_pos, y_pos and z_depth values have the meanin
g mentioned above. */int CBendCADViewPart::is_3d_b
ody_near_point(BM_POINT const& three_d_point, BM_3
D_BODY **three_db_array,
int *visible, int *x_pos, int *y_po
s, double *z_depth){ int x, y, is_visible= 1; do
uble z; int found = 0; is_visible = map_3d_to_sc
reen(three_d_point, &x, &y, &z); if( ! is_visibl
e) { // Point is outsideviewing volum
e.if(x_pos) *x_pos = x;if(y_pos) *y_pos = y;if(z_d
epth) *z_depth = z;if(visible) *visible = 0;return
0; } // Now point is insideview volume. if(x_p
os) *x_pos = x; if(y_pos) *y_pos = y; if(z_dept
h)*z_depth = z; if(visible) *visible = 1; if(! m
i_show_solid) {// Wireframe being drawn; just retu
rn that point is return 1; // within view volume.
} // Now solid is being shown. if(! three_db_a
rray) return 0; // Point is within view volume. P
ick pixels in a triangle around that point. found
= pick_point_for_3db_rw((x - 2), (y - 2), three_d
b_array); if(found) return 1; found = pick_point
_for_3db_rw((x -2), (y + 2), three_db_array); if
(found) return 1; found = pick_point_for_3db_rw
((x + 2), (y + 2), three_db_array); if(found) ret
urn 1; found= pick_point_for_3db_rw((x + 2), (y -
2), three_db_array); if(found) return 1; return
0;}// This function picks the point indicated, us
ing RenderWare picking, so this is called only whe
n solid is // being shown. Note that the pick posi
tion is with respect to the top left corner of the
view window being // (0,0). If the pick results in
a three_d_body’s clump, and the picked clump cor
responds to ANY of the// three_d_bodies inthe arr
ay passed, return value is 1; if no match or no th
ree_d_body, return is 0.// This does not modify th
e selection set in any way.int CBendCADViewPart::p
ick_point_for_3db_rw(int x_pos, int y_pos, BM_3D_B
ODY **three_db_array) { if(three_db_array == NUL
L) return 0; if( (x_pos > m_old_rect.right) || (y
_pos > m_old_rect.bottom)) { // Make sure point g
iven is withinreturn 0;
// viewport. } RwClump *picked_clump = NULL;
RwClump *parent_clump = NULL; long parent_tag,c
lump_tag, required_id;int found = 0; if(! RwPick
Scene(m_scene, x_pos, y_pos, m_camera, &m_pick))
{ // Picking command was not successful.return 0;
} if(m_pick.type == rwNAPICKOBJECT) {
// No clump was picked.return 0; } else
if(m_pick.type == rwPICKCLUMP) {// Some clump was
picked; process it. picked_clump= m_pick.objec
t.clump.clump;parent_clump = RwGetClumpParent(pick
ed_clump);parent_tag = RwGetClumpTag(parent_clum
p);clump_tag = RwGetClumpTag(picked_clump);if(pare
nt_tag == 1) { // Body of face/ben
dline/formingwas picked.for(int i=0; three_db_arra
y[i]; ++i) { // Check if it matches any of the one
s in array.if(three_db_array[i] == NULL) break;req
uired_id = three_db_array[i]->get_idx();if(clump_t
ag%10000 == required_id){found = 1;break;}}return
found;} // Now some edge’s clump was picked. C
heck if it matches any of the ones in array.for(in
t i=0; three_db_array[i]; ++i) {if(three_db_array
[i] == NULL) break;required_id = three_db_array[i]
->get_idx();if(parent_tag%10000 == required_id) {f
ound = 1;break;} } } return found;} // Thi
s allows the user to insert itemsinto the selectio
n set. "list" is an array of pointers// to three-d
-bodies, terminated by NULL to indicate end of arr
ay. If list is passed as NULL, every // three-d-bo
dy in the part is inserted into the selection set.
void CBendCADViewPart::insert_selection_set(BM_3D
_BODY **list){ int tag;BV_SELECT_DATA *data = NUL
L; if(! list) { // Insert every th
ree_d_body in part into selection set.BM_PART *par
t = NULL;CBendCADDoc* pDoc = GetDocument();ASSERT_
VALID(pDoc);part = pDoc->get_part();if(! part) ret
urn; BM_FACE *face = NULL;BM_BENDLINE *bendline =
NULL;BM_FORMING *forming = NULL;for(face = part->
get_face_list(); face; face = (BM_FACE *)face->nex
t()) { if(! face) continue;tag = 100000*(face->ge
t_idx()) + 10000 + face->get_idx();if(! m_selectio
n_set.find(tag, NULL)) {data = new BV_SELECT_DATA;
data->key = tag;data->edge = NULL;data->world_pt =
BM_POINT(0.0, 0.0, 0.0);m_selection_set.insert(ta
g, (long)data);}}for(bendline = part->get_bendline
_list(); bendline; bendline = (BM_BENDLINE *)bendl
ine->next()) { if(! bendline) continue;tag = 1000
00*(bendline->get_idx()) + 10000 + bendline->get_i
dx();if(! m_selection_set.find(tag,NULL)) {data =
new BV_SELECT_DATA;data->key = tag;data->edge = NU
LL;data->world_pt = BM_POINT(0.0, 0.0, 0.0);m_sele
ction_set.insert(tag, (long)data);}}for(forming =
part->get_forming_list(); forming; forming = (BM_F
ORMING *)forming->next()) { if(! forming) continu
e;tag = 100000*(forming->get_idx()) + 10000 + form
ing->get_idx();if(! m_selection_set.find(tag, NUL
L)) {data = new BV_SELECT_DATA;data->key = tag;dat
a->edge = NULL;data->world_pt = BM_POINT(0.0, 0.0,
0.0);m_selection_set.insert(tag, (long)data);}}Dr
awPart(m_hdc);return;}BM_3D_BODY *three_d_body;lon
g i;for(i=0, three_d_body = list[0]; three_d_body;
++i, three_d_body = list[i]) {if(! three_d_body)
break;tag = 100000*(three_d_body->get_idx()) + 100
00+ three_d_body->get_idx();if(! m_selection_set.f
ind(tag, NULL)) {data =new BV_SELECT_DATA;data->ke
y = tag;data->edge = NULL;data->world_pt = BM_POIN
T(0.0, 0.0, 0.0);m_selection_set.insert(tag, (lon
g)data);}}DrawPart(m_hdc);return;}// This function
returns the largest of the x, y and z projections
of the part’s// bounding box.double CBendCADView
Part::get_approx_part_size(void){ if(md_part_bbox
_size) { double size = __max(md_part_bbox_size
[0], md_part_bbox_size[1]); size = __max(size,
md_part_bbox_size[2]); return size; } else re
turn 0.0;}// This function passes back the boundin
g box size of the part in its original orientatio
n,in the// array "dimensions". This array should b
e at least of size 3. Returns 1 if successful, 0 o
therwise.// Caution: This is a quick and hence not
very accurate calculation; if you want greater pr
ecision,// writeyour own function.int CBendCADView
Part::get_part_dimensions(double *dimensions){ CB
endCADDoc* pDoc = GetDocument();if(! pDoc) return
0;BM_PART*part = pDoc->get_part();if(! part) retur
n 0;if(! dimensions) return 0;int i;BM_POINT centr
oid;RwMatrix4d *temp = RwCreateMatrix();i = comput
e_part_centroid(part, 1, &centroid);if(! i) return
0; i = compute_part_bbox(part, 1, temp, centroi
d, dimensions, NULL); if(! i) return 0;RwDestroyMa
trix(temp);return 1;} 付録K PART.HXXはベンドモデルおよび部分構造などに関するコ
メント /*このファイルはBMAPI BM_PARTクラスの定義を含む。
部分関数の殆どはPART.CPPにある。コンストラクタとデ
ストラクタはPART_NEW.CPPにある。シリアル化関数はPA
RT_LOAD_x.CPPおよびPART_SAVE.CPPにある。フォルデイ
ング関数はFOLD.CPPおよび3D_FUNC.CPPにある。アンフ
ォルデイング関数はUNFOLD.CPPにある。***** ********
********* ********* ********* ********* *********
議論:-BMAPIの設計原理の1つは、全体の部分を厚さと
全てのもので正確に表そうとすることである。これの利
点の1つは、我々が何かを問い合わせ、迅速に答えを得
ることが出来るということにある。答えがあからさまに
は表されなくても、それは容易に計算される。それの他
の利点は、我々は"中実な部分"として部分を表している
ので、部分を3Dモデル化することが直ちに出来るという
ことにある。-薄板の特殊な性質の1つは、それが対称
的であることである。我々は、我々がその部分を表し、
それについて理由付けするときこの事実の利点を用いる
ことが出来る。
【0393】例えば、我々は薄板の1つの側のみを、そ
の他側は我々が厚さベクトルを知ると定義されるので、
表すことが出来る。-1つの問題は、我々が部分のフラ
ットバージヨンを与えられたとき(それは通常は厚さを
含まない)如何に我々はそれから部分を構成するかとい
うことにある。このフラットは部分の中性ラインを表す
ということを採用するか?このBMAPIにおいて、我々は、
ベンドモデルであからさまに表される部分のフラットバ
ージヨンは、部分がトップビユー(上面図)にあるとき
薄板のボトム側であるということを採用している。他の
重要な点は、このフラットバージヨンがX-Y面上にある
ということである。この方法では、例え厚さが変化して
も、我々のモデルに対する変化は最小である。- フラッ
トは薄板のボトム側を表すが、フラットのデイメンシヨ
ンは中性ラインデイメンシヨンを表す。すなわち、我々
が部分を曲げたとき、曲げた部分の中性ラインのデイメ
ンシヨンはフラットデイメンシヨンに一致する(また
は、ベンドデダクシヨンにより定義される量だけずらさ
れる)。これは、それらに対して内側=中性ライン=外側
なので面に対して不適切である。しかし、それはベンド
ラインに対して重要である。それは、ベンドラインの基
礎をなすフラットがベンドアークの中性ライン上にマッ
プされるということを意味する。- 部分が畳まれると
き、BMAPIは通常はベース-ボデイの2D->3D変換を変化さ
せることはない。しかし、ベース-ボデイがベンドライ
ンであり、ベンパラメータの幾つかを(例えば、ベンド
角)変える時は2D->3D変換マトリクスは’not-up-to-da
te’とマークされる。我々がこの古い変換マトリクスを
用いたときは、結果は悪くなる。従って、我々は実際に
古い(out-of-date)変換マトリクスを用いることは出来
ない。しかし、その場合、我々は、変換マトリクスを一
致マトリクスにリセットすることより行うべき更によい
ものを持つことはない。-全ての3D体のサイズは2通り
の方法で変化することが出来る。先ず、もし面が、ベン
ドデダクシヨンの半分の量に等しい量によりトリムされ
る。第二に、全てのボデイは隣接するベンドラインに関
してそれに係わるトリミング値を持つことが出来る。隣
接ベンドラインが曲げられるとき、このボデイはこの量
によりトリムされる。-BM APIはBMAPIファイルの全ての
公知の(すなわち、最近のおよび全ての初期の)バージ
ヨンをロードすることが出来る。-部分がフォルドされ
たとき、2D->3D変換のみが直ちに計算される。計算の残
部は要求に応じて、すなわち必要なときは常になされ
る。我々が部分をアンフォルドするときは、全ての事
態、すなわち3D-2D変換および部分のフラットバージヨ
ンが直ちに計算される。-部分がアンフォルドされると
きは、BMAPIは、3D-ボデイの現在の3D-バージヨンを、
それらがup-to-dateとしてマークされるか否かとは無関
係に、用いる。-BM_PARTクラスは部分の生成を容易にす
る幾つかのハイレベルの関数を有する。例えば、それ
は、部分のフラットバージヨンを検査し、見出された問
題点を固定する関数を有する。更に、それは、1組の面
のみが与えられたとき部分に対するベンドラインを生成
する関数を有する。これらは、多くの用途において共通
のタスクであるハイ-レベルの関数である。-部分のベン
ドラインに対しては、それらが特定のセンタラインを持
つことが絶対必要である。センタラインがないと、ベン
ドラインは殆ど無用であり、それはフォルドされること
もアンフォルドされることも出来ない。ベンドラインセ
ンタラインは3つの目的のために用いられる:-ベンド
ラインフォルデイング-アンフォルデイングのため。
【0394】-ベンドラインが空のときベンドラインン
を表すため。-ベンドラインの向きを決定するため。セ
ンタラインは、フラットバージヨンが一定の向きを持つ
ので(すなわち、法線は(0,0,1)でなければならな
い。)、部分の2D(すなわち、フラット)バージヨンに
おいて最も"目的的"であるという点に注意されたい。部
分の3Dバージヨンにおいては、センタラインは、その意
味が、変化可能な基礎となる表面により定義されるの
で、幾らか"主観的"である。例えば、我々は、表面(こ
れは必然的に薄板を変化させない)部分をフリップする
ことが出来、また結果としてベンドラインの向きを同じ
に保つために同様にセンタラインを反転させなければな
らない。-全てのベンドラインはそれに係わるンドデダ
クシヨンを持つ。 このベンドデダクシヨンは、部分が
フォルドまたはアンフォルドされるとき部分デイメンシ
ヨンが(このベンドラインにおいて)如何に変化するか
を制御する。ベンドデダクシヨン値は正および負の両者
を取ることが出来る。それが正であり、我々が部分をフ
ォルドするときは部分のデイメンシヨンは拡大し、それ
が負のときは部分デイメンシヨンは収縮する。正のベン
ドデダクシヨンはアンフォルデイング時に部分をフォル
ドしシュリンクするとき部分を拡大することを意味し、
そして従って負のベンドデダクシヨンはアンフォルデイ
ング時に部分をフォルドし、拡大するとき部分を収縮さ
せることを意味する産業基準である(と言われた)。-B
M_PARTは、部分のデイメンシヨンを制御するパラメータ
bendline_dimensions_statusを持つ。それは、部分の設
計と生成を容易にするために付加される。ユーザが(例
えば)外側から外側へ部分デイメンシヨンを与えられと
いうことはしばしば起こる。これらのデイメンシヨンは
カスタマにより固定され、特定される。薄板設計プロセ
スのゴールは、コノフラットがフォルドされるときその
デイメンシヨンが所定のデイメンシヨンに正確に一致す
るようにこの部分のフラットを生成することにある。設
計プロセスにおいては、ユーザは一連の方法で部分を変
化させることが出来る。ただし、これが与えられたと
き、我々は常に部分デイメンシヨンを変化しないように
することを望む。 bendline_dimensions_statusがTRUE
のとき、BMAPIは、ユーザが部分/ベンドラインパラメ
ータ(薄板の厚さまたはベンドラインの半径などのよう
な)を変化させるとき、可能んらば常に部分デイメンシ
ヨンを(全てのベンドラインにおいて)一定に保とうと
する。さもなければ、我々は注意しない。-以前の問題
と関連して生じる他の問題は、部分寸法が通常はOUTSID
E/INSIDE/NEUTRALデイメンシヨンとして特定されるとい
うことである。例えば、ユーザは、ボックスが与えら
れ、その外側デイメンシヨンは100x100であると特定す
る。技術的には、ユーザは、フラット上でこのボックス
内の全てのベンドラインが外側デイメンシヨンを表すと
いうことを特定している。
【0395】例えば、ユーザが後に薄板の厚さを変えた
とき、外側デイメンシヨンは同じままであり、すなわち
全ての付加された厚さは”ボックスの内側に行かなけれ
ばならない”一般に、ユーザ(またはカスタマ)は、同
じ面内でも、部分デイメンシヨンをOUTSIDE/INSIDE/NEU
TRALデイメンシヨンと特定する。例えば、ユーザは、ボ
ックスを横切ってデイメンシヨンが、1側の薄板の内側
から他側の薄板の外側へとして与えられるということが
出来る。 我々は、ユーザが部分デイメンシヨンを一定
に保ことを望むか否かのトラックを保持する変数を部分
内に有する。もしこの変数が、ユーザが、部分デイメン
シヨンが一定に保持されることを要求しないように設定
されるとき、このINSIDE/OUTSIDE/NUETRAL-LINEのホワ
イルビジネスは無視される。*/#ifndef BM_PART_HXX_IN
CLUDED#define BM_PART_HXX_INCLUDED#include <stdio.
h>#include "GLOBAL.HXX"#include "ENTITY.HXX"#inclu
de "TOPOLOGY.HXX"class BM_PART : public BM_ENTITY
{friend BM_FACE ;friend BM_HOLE ;friend BM_BENDLIN
E ;friend BM_FORMING ;friend BM_TOPOLOGY ;friendBM
_TOPOLOGY_RECORD ;friend BM_BEND_PROPERTY ;friend
BM_BEND_PROPERTY_SIMULTANEOUS ;// every part has a
(user-defined) name that it inherits fromBM_ENTIT
Y.// also, the type (BM_ENTITY_TYPE_PART) is store
d in BM_ENTITY.protected :/*これらの変数は、ユーザ
をして名前や、数、材料の種類などのパラメータを部分
と関係させる。*/char material_type[256] ;char name
[256];char number[32] ;/*これらの変数は材料とメタ
ル特性を記述する。*/doublemetal_thickness ;/*この
部分内では、2つのポイントは、もしそれらの間の距離
がこの値程度のときは同じであると考えられる。*/doub
le distance_tolerance;/*全ての部分はベンド特性のリ
ストを有する。ベンドラインがベンド特性を持つとき
は、この特性の対象は部分に係わるベンド特性のリスト
上になければならない。これは、我々が部分をセーブま
たはロードするとき必要とされる。これらの変数は、内
部にのみ使用される。BMAPIのユーザは、これらの変数
にアクセスを持たない。*/long number_of_bend_proper
ties ;BM_BEND_PROPERTY *list_of_bend_properties ;/
*部分のトポロジーここでボデイをリストに直接付加す
ることは可能ではないことに注意されたい。これは、ボ
デイが部分トポロジーに付加されるときにのみなされ
る。*/BM_TOPOLOGY topology ;// number of different
3D bodies in the part.// these numbers should be c
onsistent with the part topology.long number_of_fa
ces ;long number_of_holes ;long number_of_bendline
s ;long number_of_formings ;// lists of faces, hol
es and bendlines of the part// Note that these are
lists of BM_3D_BODY’s.BM_FACE *first_face ;BM_HO
LE *first_hole ;BM_BENDLINE *first_bendline ;BM_FO
RMING *first_forming ;/*これらのパラメータは部分に
係わるベンドシーケンスを表す。*/long bend_sequence
_size ;BM_LINKED_LIST_NODE *bend_sequence ;/*この
パラメータは部分デイメンシヨンを制御する。それがTR
UEのときは、BMAPIは、ユーザが(薄板の厚さまたはベ
ンドラインの半径などの)部分/ベンドラインパラメー
タを変えるとき、可能なときは常に、部分のデイメンシ
ヨンを(全てのベンドラインにおいて)一定に保とうと
試みる。さもなければ、我々は注意しない。デフォール
ト値は0であり、デイメンシヨンを一定に保持する必要
はない。*/charbendline_dimensions_status ;public :
/*コンストラクタとデストラクタ。PART_NEW.CPPにおい
て。*/BM_PART(void) ;BM_PART(BM_PART *existing_par
t) ;~BM_PART(void) ;// use this to erase the conte
nt of the part. the part willbe empty.// it will u
se topology::erase_content() to destroy the topolo
gy and will then // destroy all bodies in the par
t.void erase_content(void) ;void get_material_type
(char *out_mat_type) ;void set_material_type(char
*in_mat_type) ;void get_name(char *out_name) ;void
set_name(char *in_name) ;void get_part_number(cha
r *out_number) ;void set_part_number(char *in_numb
er) ;// get number of faces, holes, bendlinesinlin
e long get_number_of_faces(void) const { return nu
mber_of_faces ; }inline long get_number_of_holes(v
oid) const { return number_of_holes ; }inline long
get_number_of_bendlines(void) const { return numb
er_of_bendlines ; }inline long get_number_of_formi
ngs(void) const { return number_of_formings ; }//g
et pointers to lists of faces, holes and bendlines
inline BM_FACE *get_face_list(void) const { return
first_face ; }inline BM_HOLE *get_hole_list(void)
const { return first_hole ; }inline BM_BENDLINE *
get_bendline_list(void) const { return first_bendl
ine ; }inline BM_FORMING *get_forming_list(void) c
onst { return first_forming ; }// To get the numbe
r of bendproperties and the first property object
on the list.inline BM_BEND_PROPERTY *get_list_of_b
end_properties(void) const { return list_of_bend_p
roperties ; }inline long get_number_of_bend_proper
ties(void) const { return number_of_bend_propertie
s ; }// this function tries to find a good default
base face.// it chooses a face that has the large
st bbox.BM_FACE *get_default_base_face(void) ;/*部
分に係わる距離公差を獲得し変化させる関数*/inline d
ouble get_distance_tolerance(void) const { return
distance_tolerance ; }void set_distance_tolerance
(double new_distance_tolerance) ;/*この部分の現在
のメタル厚さを得る。*/inline double get_metal_thic
kness(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_al
l_faces_adjacent_to_bendlines(...)をコールせよ。更
に、新しい厚さを設定し、次に隣接面を一致させると共
に新しい最新の2D->3D変換を計算するset_metal_thickn
ess_update_part(...)を用いよ。*/void set_metal_thi
ckness(doublethickness) ;void set_metal_thickness_
update_part(double thickness) ;/*この関数は、3Dス
ペースにおいてそれらがそれらに隣接するベンドライン
に正確に触れるように全ての面をトリムする(必要に応
じて)。この関数は、厚さが変化した後にまたはベンド
ラインパラメータが変化した後にコールするのによい。
*/void match_all_faces_adjacent_to_bendlines(void)
;/*3Dボデイ(面、孔、フォーミングまたはベンドライ
ン)を部分に付加する。付加出来ないときはFALSEを戻
す。この関数は、基本的にはトポロジーのadd_body() m
ember関数をコールする。*/int add_3d_body(BM_3D_BOD
Y *body) ;// get part topologyinline BM_TOPOLOGY *
get_topology(void) const { return (BM_TOPOLOGY *)
&topology ;}/*これらの関数は、ユーザが、ベンドライ
ンにおける部分デイメンシヨンが可能なときは常に一定
に保たれるべきか否かを照会し、特定することを許容す
る。
【0396】*/// to get the current statusinline i
nt get_bendline_dimensions_status(void) const { re
turn bendline_dimensions_status ; }// to set the n
ew status.// for example, if we set it to TRUE, th
en from this point on, BMAPI// will try to keep to
current part dimensions constant.void set_bendlin
e_dimensions_status(int new_bendline_dimensions_st
atus) ;/*ベンドシーケンス関係関数*/void delete_ben
d_sequence(void) ;inline long get_bend_sequence_si
ze(void) const { return bend_sequence_size ; }// t
his function returns the number of bendlines copie
d into OUT arrayint get_bend_sequence(BM_BENDLINE
*bendlines[], long bendlines_array_length) ;// thi
s function sets a new bend sequence for this bendl
ineint set_bend_sequence(BM_BENDLINE **bendlines,
long bendlines_array_length) ;// this function che
cksis a bendline is in the current bend sequence o
f the part.// if yes, itreturns its index in the b
end sequence (ie. the number of this bendline// in
the bend sequence order). This index is from 0 th
rough sequence_lenght - 1.// if this bendline is n
ot in the bend sequence, it returns -1.int is_bend
line_in_bend_sequence(BM_BENDLINE *bendline) ;// t
his function removes a bendline from the bend sequ
ence.// note that if the bendlineis in a simultane
ous bend property, it will replace the bendline//
withanother bendline from the simultaneous bend pr
operty that is not already in the bend sequence.vo
id remove_bendline_from_bend_sequence(BM_BENDLINE
*bendline) ;// this function deletes the current b
end sequence (if one exists) and creates a default
// bend sequence.void create_default_bend_sequenc
e(void) ;/*この関数は、孔を含まない全てのベンドラ
インのフラットバージヨンを排除する。この関数は、部
分がアンフォルドされた後有用になり得る。通常は、部
分のフォルドされたバージヨンはトリビアルでないベン
ドライン(すなわち、0でないインサイド半径および/ま
たは厚さ)を含む。部分がアンフォルドされたとき、BM
APIはこれらのベンドラインを、それらが有るように正
確にフラットバージヨンに変換する。たとえば、ゼロ以
外の厚みまたは半径を有するベンドラインの3D-バージ
ョンには通常、曲がった弧が描かれる。これは平面バー
ジョンのベンドラインにマッピングされる。これはパー
トの平面バージョンにおいて、ベンドラインに対応する
2つの面の間に長方形が存在することを意味する。ただ
し我々は、この矩形を見たくないときがある。この関数
は、単純な平面(つまり平面に穴がない)を有し、2つ
の面に正確に隣接するベンドラインだけを処理する。
この関数は、隣接するすべての面を切り取って(トリミ
ング)、ベンドラインの中心線に接触させ、ベンドライ
ン平面におけるすべての輪(ループ)を削除する。この
関数は通常UNFOLDの直後に使われることに注意せよ。い
ったん平面がトリミングされると、それは隣接する面に
も適合する。これは、この関数がいくつかの特殊なトリ
ミング値を計算および設定し、後ほど我々がパートをた
たむ(フォルドする)ときに、面がベンドラインに正確
に接する正しい3D-バージョンを得ることを意味する。
この関数はベンドラインを変えない。*/void eliminate
_simple_bendlines_in_flat_version_A(void) ;/*この
関数は、パートにおけるすべての3D-ボディを走査して
(フォーミングを除く)、それらの平面バージョンを整
える。基本的にこの関数は、パートにおけるすべての3D
_body(フォーミングを除く)に対してBM_2D_BODY::fix
_flat()関数を呼び出す。この関数は現行の平面バージ
ョンのみをチェックするので注意せよ。この関数は、何
らかの操作が失敗するか(つまりメモリー割り当て)、
またはこの関数が解決できない問題を発見したときにFA
ILUREを返す。*/int fix_flat(void) ;/*この関数は、
フェース・ノーマル(face normal)がベンドラインの
定義に合致していることをチェックする。たとえば、fa
ce1が法線を持ち(0,0,1)、face1とface2との間に90度の
FRONTベンドがある場合、face2の法線は(-1,0,0)になら
なければならない。本来とは逆の法線がある場合、この
関数はそれを整える。さもなくば、この関数は問題を見
つけるとFAILUREを返す。入力面が与えられる場合、こ
の関数はその面の中心に位置する接続されたコンポーネ
ントだけをチェックする。さもなくば、この関数はパー
ト全体をチェックする。この場合、この関数が面をチェ
ックする順番は、面インデックスの順番である。この関
数は必要なチェックをいくつか行なう(たとえば、ベン
ドラインが曲げられるとき、それはbend op, a3D-バー
ジョン(それは空のこともある)およびサーフェスを持
たなければならない)。この関数は、すべての面および
ベンドラインの3D-バージョンが最新のものであるか否
かをチェックする。いずれかが最新のものでない場合に
は、この関数はFAILUREを返す。この関数は、現行バー
ジョンが最新であるか否かをチェックするだけであり、
現行バージョンが最新でない場合は、新しい3D-バージ
ョンを計算しない(この関数は通常展開(アンフォル
ド)の後に使われるので、この時点では何も計算したく
ない)。この関数は穴とフォーミング(formings)を無
視する。In 3D_FUNC.CPP.*/int fix_3D_face_normals(B
M_FACE *given_base_face = NULL) ;/*この関数は、パ
ートにおける3D-ボディをチェックし、これが見つける
問題を解決する。この関数は現行の3D-バージョンのみ
をチェックするので注意せよ。さらにこの関数は、何も
のをも無効にしない。只今この関数は:フェース・ノー
マル(face normal)がベンドラインの定義に合致して
いることをチェックする。たとえば、face1が法線を持
ち(0,0,1)、face1とface2との間に90度のFRONTベンドが
ある場合、face2の法線は(-1,0,0)にならなければなら
ない。
【0397】この関数は、何らかの操作が失敗するか
(つまりメモリー割り当て)、またはこの関数が解決で
きない問題を発見したときにFAILUREを返す。In 3D_FUN
C.CPP.*/int fix_3D(void) ;/*********** **********
********** ********** ********** ********** ******
**** ********** **********これは、パートの設計およ
び建造に用いる主要な高水準Bend Model機能である。そ
の用途は次の通りである:-パートが結合されるように
(可能である場合)、面と面との間にベンドラインを作
る。この関数は、パート制作を合理化するために作られ
た。通常はパートを描くのにサードパーティのCADプロ
グラムが使われる。Bend ModelはCADシステムをコント
ロールしないので、我々の目的にとってこの描画(ドロ
ーイング)は単なるエッジの集合である。このため、パ
ートの構造を見つけるには、ドローイングを分析しなけ
ればならない。その後に我々は、パートのベンドライン
と面を作ることができる。ただし、この入力ドローイン
グはしばしば曖昧である。つまり、面、そして特にベン
ドラインは一意に定義されていない。このことが多くの
アプリケーションに共通する問題であるため、この関数
がBend Modelの一部になっている。さらに、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-バージョンを平面バージョンに
移さなければならない。この関数は、この目的のために
のみ設計されており、他のいかなる目的にも使用するべ
きでない。
【0398】この関数の誤用は、システムをクラッシュ
する。この関数はまず初めに、ボディの平面バージョン
(FLAT)がNULLであるか否かをチェックする。これがNU
LLでない場合、この関数は3D-バージョンを移さない。
TODO : right now, it only moves faces.*/void BM_PA
RT::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ボディを各
々の屈曲パラメータに従って個別に計算する。一般に、
これらの変形では、パート内のすべてのボディが’fla
t’バージョンかまたは’3D-version’を有することが
要求される。つまり、当初3Dバージョンのパートがある
場合、2D->3D変形を使用する前に、それをアンフォルド
しなければならない。アンフォルドは’flat’を作り出
す。フォルドは’3D-version’を作り出す。ユーザーは
最初に、フラット・バージョンか3D-バージョンのいず
れかを指定しなければならない。********** *********
* ********** ********** ********** ********** ****
**************** ***********//*この関数は、BMAPIに
(フラットから)パートの3Dバージョンを強制的に計算
させる。具体的にBMAPIは、面−穴−ベンドラインのす
べてをチェックし、3Dバージョンが新しくなければ、BM
APIは2D->3D変形を用いてフラットから最新の3Dバージ
ョンを計算する。2D->3D変形が新しくない場合、BMAPI
は最新の有効な2D->3D変形の計算を試みる。また、ある
ベンドラインについて新しい3D-バージョンが計算され
るとき、BMAPIは初めに隣接するベンドラインを適合さ
せる。*/void bring_3D_up_to_date(void) ;/*********
** ********** ********** ********** ********** ***
******* ********** ********** **********2D->3D変形
関数********** ********** ********** ********** **
******** ********** ********** ********** ********
***//*この関数はすべての変形をアイデンティティ変形
(identity transformation)にリセットする。さらに
この関数は、すべてのベンドラインにおける’bending_
status’変数をFALSEに設定する。さらにこの関数は、
すべての面のすべての3Dバージョンを’not-up-to-dat
e’(非最新)と記すが、ただしその再計算は行なわな
い。3D->2D変形はリセットできないので、この関数が2D
->3D変形のみをリセットすることに注意せよ。*/void r
eset_all_transformations(void) ;/*パートの2D->3D変
形をリセットする。’body’は、アイデンティティ変形
になる変形を持つ面である。他のボディは、この基本ボ
ディ(ベース・ボディ)に関する屈曲情報に従って、各
々の変形を設定する。この関数は、すべての変形母体
(マトリックス)を更新する。基本的にこの関数では、
ユーザーがパート全体に行なった回転や移動のすべてを
取り消し(アンドゥー)できる。*/void reset_part_2D
to3D_transformations(BM_3D_BODY *base_body) ;/****
******* ********** ********** ********** *********
* ********** ********** ********** **********これ
らの関数は、ユーザーにパートの回転または移動を実施
させる。たとえば、屈曲のとき、ユーザーはパートの反
転を希望することがある。これらの関数は、パート全体
に均一に作用する。すなわち、すべての面−穴−ベンド
ラインが全く同様に変化する。これらの関数が2D->3D変
形であることに注意せよ。すなわち、これらの関数はパ
ートの3Dバージョンだけを変更するが、これらの関数は
パートの平面バージョンの計算を要する。基本的にこれ
らの関数が実施する唯一のことは、すべてのボディに付
随する2D-3D変形を変更し、すべてのボディの3D-バージ
ョンを’not-up-to-date’(非最新)と記すことであ
る。********** ********** ********** ********** **
******** ********** ********** ********** ********
***//*パート全体を線を軸に一定の角度(ラジアン単
位)で回転させる。正の方向は、線の方向を見たときの
時計回りである。*/void rotate(BM_LINE const& line,
double constangle) ;/*パート全体をこのベクトルで
移動する*/void translate(BM_VECTORconst& translati
on_vector) ;/*この変形をパートに適用する*/void tra
nsform(BM_TRANSFORM const& transformation) ;/*****
****** ********** ******************** **********
********** ********** ********** **********FOLD関
数。FOLD.CPPモジュール内********** ********** ****
****** ********** ********** ********** **********
********** ***********//*パートの3Dバージョンを計
算する。この関数は、ベース・ボディに従ってパートの
3Dバージョンを計算する。つまり、’base_body’は留
まり、パートの残りの部分は動く。これまでパート全体
に回転や移動を実行した場合、回転または移動はこの操
作の後にも有効であるので注意せよ。通常ユーザーは、
いくつかのベンドライン・パラメータを設定してから、
この関数を呼び出してパートを更新することを希望す
る。この関数は、変化する(最小限度の変化)ボディの
変形母体だけを計算する。各ボディの3Dバージョンは要
求に応じて(ユーザーが計算を要求するときのみ)計算
される。この関数は、各ベンドラインのメンバ変数’be
nding_status’を用いて、ベンドラインを屈曲するか否
かを決める。ベース-ボディの2D->3D変形が新しくない
場合、FOLDはそれをアイデンティティ変形にリセットす
るので注意せよ。
【0399】*/int fold(BM_3D_BODY *base_body) ;/*
この関数は、各ベンドラインのメンバ変数’bending_st
atus’がFALSEであると想定し(FALSEでない場合は、こ
の関数が’bending_status’をFALSEに設定する)、さ
らに屈曲するベンドラインのリストが配列’bendline_a
rray’にあると想定する(配列の長さは’number_of_be
ndlines’)ことを除き、同じことを実行する。この関
数が終るときに、各ベンドラインのメンバ変数’bendin
g_status’は、ベンドラインが屈曲されたか否かを表示
する。*/int fold(BM_3D_BODY *base_body, BM_BENDLIN
E *bendline_array[], long number_of_bendlines) ;/*
この関数は、パートの屈曲順位における最初のnベンド
ラインをフォルドする。*/int fold_sequence(BM_3D_BO
DY *base_body, int n) ;/*3Dボディがすでにその2D->3
D変形母体を計算している場合、この関数は所定のベン
ドラインについて変形母体を計算する。この関数は数々
の事柄を想定する(これらの事柄はチェックされな
い):-このベンドラインはボディに隣接している。-こ
のボディはすでに最新の変形母体を有する。-このベン
ドラインは最新のcenter_line_2Dを有する。これら2つ
の関数では、ベンドラインが2D中心線を有することが要
求されるので注意せよ。これはまた、ベンドラインに平
面があることをも意味する。性能上の理由から、これら
の関数はベンドラインにおける平面の有無をチェックせ
ず、かわりにベンドラインに平面があるものと想定し、
それを直接的に参照する。この関数はFOLDによって使わ
れる。*/int bend_bendline_wrt_3D_body(BM_3D_BODY *
body /* finished body */, BM_BENDLINE*current_bend
line /* bendline whose transformation we are compu
ting */,BM_TRANSFORM *tf /* start with this transf
ormation */) ;/*ベンドラインがすでに完成しており、
我々が3Dボディを計算していることを除き、同じ。This
function is used by FOLD.*/int bend_3D_body_wrt_b
endline(BM_BENDLINE *current_bendline /* finished
bendline */, BM_3D_BODY *body /* body whose transf
ormation we are computing */, BM_TRANSFORM *tf /*
start with this transformation */) ;/*********** *
********* ********** ********** ********** *******
*** ********** ********** **********UNFOLD関数。UN
FOLD.CPPモジュール内********** ********** ********
** ********** ********** ********** ********** ***
******* ***********//*この関数はパート全体をアンフ
ォルドする。この関数は、接続されたパートの各コンポ
ーネントにつき、デフォルトのベース・ボディを選択す
る。この関数は、パートがアンフォルドされるときに、
ベース・ボディが原点(0,0,0)に重なるようにパートをX
-Y平面に移動させる。この関数は最初に各3Dボディにつ
いて3D->2D変形を計算し、それから各3D-ボディについ
てWflatを計算し、次にWflatをトリミングし、最後に平
面を計算する。この関数は、ベース-ボディとして非-NU
LLの法線を持ち、最小idを持つ面を選択する。これが不
可能である場合、この関数は、ベース-ボディとして非-
NULLの法線を計算することができる基礎のサーフェスを
有する最初のベンドラインを選択する。この関数は、BM
_PART::unfold(BM_3D_BODY *base_body)を用いて、パー
トの接続されたコンポーネントのすべてをアンフォルド
する。この関数は、全面的に成功した場合に1を返し、
パートの一部でアンフォルドに失敗した場合には0を返
す。この関数はまず初めに、すべてのフェース・ノーマ
ルが現行のベンドラインに対して適正であることをチェ
ックする。この関数は、各3D-ボディの現行3D-バージョ
ンを使用することに注意せよ。アンフォルドを行なうに
は、すべての3D-バージョンが新しくなっていなければ
ならない。この関数は3Dボディが新しいか否かをチェッ
クせず、実際にはすべての3D-ボディを最新と記す。さ
らにこの関数は、すべてのベンドラインが有効な3D-中
心線を持っていると想定する。ここでもこの関数は3D-
中心線をチェックせず、かわりに現行の中心線をただ単
に批准する。*/int unfold(void) ;/*この関数は、ベー
ス-ボディの周囲を中心とするパートの接続コンポーネ
ントだけをアンフォルドする。この関数は、パート全体
をアンフォルドするBM_PART::unfold(void)関数によっ
て使われる。この関数は、接続コンポーネントの各3D-
ボディについて新しい3D->2D変形を計算し、次にBM_3D_
BODY::compute_flat_from_3D()関数を用いて各3D-ボデ
ィについて新しい平面バージョンを計算する。ベース・
ボディが面であり、入力フラグがTRUEに設定されている
場合、この関数が最初に実行することは、すべてのフェ
ース・ノーマルが現行のベンドラインに対して適正であ
ることをチェックすることである。ただしこれは、その
ベース・ボディ(面)を中心とする接続コンポーネント
に限られる。この関数は各3D-ボディの現行3D-バージョ
ンを使用するので注意せよ。この関数を呼び出す前に、
すべての3D-バージョンが最新であることを確認せよ。
この関数は実際、それが処理するすべての3D-ボディを
最新と記す。*/int unfold(BM_3D_BODY *base_body, in
t check_face_normals = 0) ;/*3Dボディの3D->2D変形
母体がすでに計算済みの場合、この関数は所定のベンド
ラインについて変形母体を計算する。この関数は数々の
事柄を想定する(これらの事柄はチェックされない):-
このベンドラインはボディに隣接している。-このボデ
ィはすでに最新の変形母体を有する。-このベンドライ
ンは最新のcenter_line_3Dを有する。これら2つの関数
では、ベンドラインが中心線を有することが要求される
ので注意せよ。これはまた、ベンドラインが非-NULLの3
D-バージョンであることをも意味する。性能上の理由か
ら、これらの関数はベンドラインが非-NULLの3D-バージ
ョンであることをチェックせず、かわりにベンドライン
が非-NULLの3D-バージョンであるものと想定し、それを
直接的に参照する。この関数はUNFOLDによって使われ
る。この関数は実際にはbend_bendline_wrt_3D_bod
y(...)の逆であることに注意せよ。*/int unfold_bendl
ine_wrt_3D_body(BM_3D_BODY *body /* finished body
*/, BM_BENDLINE *current_bendline /* bendline whos
e transformation we are computing */, BM_TRANSFORM
*tf /* start with this transformation */) ;/*ベン
ドラインがすでに完成しており、我々が3Dボディを計算
していることを除き、同じ。この関数はUNFOLDによって
使われる。この関数は実際にはbend_3D_body_wrt_bendl
ine(...)の逆であることに注意せよ。*/int unfold_3D_
body_wrt_bendline(BM_BENDLINE *current_bendline /*
bendline終了*/, BM_3D_BODY *body /* 我々が変形を
計算しているところのボディ */, BM_TRANSFORM *tf /*
この変形から開始する */) ;/*********** **********
********** ********** ********** ********** *****
***** ********** **********この関数は"paper model
of this part"(このパートのペーパー・モデル)を返
す。ペーパー・モデルとは、厚みが0であり、ベンドラ
インの半径と屈曲控除も0であるパートである。必要に
応じこの関数は、ベンドラインのユーザ-id’から’内
部半径’と’屈曲控除’をマッピングした結果を返す。
********** ********** ********** ********** ******
**** ********** ********** ********** ***********/
BM_PART *make_paper_model(double **inside_radius /
* OUT */, double **bend_deduction /* OUT */) ;/*こ
の関数は、現行のパートを所定のファイルにPGF形式で
保存する。PGF形式はCMUのBendCADプログラムによって
使われる。戻り値:万事良好でパートが保存された場合
にTRUEを返す。*/int save_PGF_file(FILE *file) ;int
save_PGF_file(char *filename) ;/*ロード関数はPART
_LOAD_x.CPPにある。*/virtual int load(FILE *file)
;virtual int load(char *filename/* must not be NU
LL */) ;int BM_PART_Load(FILE *file, long version)
;/*保存関数はPART_SAVE.CPPにある。*/virtual int s
ave(FILE *file) ;virtual int save(char *filename /
* must not be NULL */) ;} ;#endif // BM_PART_HXX_I
NCLUDED 付録L 3次元操作および回転軸の動的計算によるナビゲーショ
ンの例 void CBendCADViewPart::OnLButtonUp(UINT nFlags, CP
oint point) {::ReleaseCapture();::ClipCursor(NUL
L);// Release mouse, free cursor.m_lt_btn_up_point
= point;double x_extent, y_extent;int add_hit_to_
list = 0;int viewport[4];BM_VECTOR offset;BM_PART
*part = GetDocument()->get_part();RwV3dvert;switch
(ml_last_function_chosen){ case(ZOOM_WINDOW_MOD
E):if(mi_dynamic_rot_center_on) {// User has furth
er zoomed in. compute_non_dyn_equivalent();RwIdent
ityMatrix(md_dyn_rot_matrix);}compute_zoom_region_
translation();x_extent = fabs((double)(m_lt_btn_do
wn_point.x - m_lt_btn_up_point.x))* 2.0*md_cu
rrent_view_vol[0]/(double)(m_old_rect.right);y_ext
ent = fabs((double)(m_lt_btn_down_point.y - m_lt_b
tn_up_point.y))* 2.0*md_current_view_vol[1]/
(double)(m_old_rect.bottom);set_new_view_volume(x_
extent, y_extent); compute_part_bbox(part, mi_s
how_3d, md_rot_matrix, m_part_centroid, md_part_bb
ox_size, &offset); mi_bbox_is_up_to_date = 0;//
Even though bbox computed, we mark as not up to da
te so that zoom-allDrawPart(m_hdc);// will work co
rrectly.// Now turn on dynamic rotation center if
need be.if( (md_part_bbox_size[0] >2.2*md_curr
ent_view_vol[0]) || // User has zoomed in so that
not all (md_part_bbox_size[1] > 2.2*md_current
_view_vol[1]) ) { // of the part is in view volum
e.if(! md_dyn_rot_matrix) md_dyn_rot_matrix = RwCr
eateMatrix(); if(mi_show_solid) {// Pick the cen
ter of the screen to find point on clump to rotate
around.if(RwPickScene(m_scene, m_old_rect.right/
2, m_old_rect.bottom/2, m_camera, &m_pick)) {if(m_
pick.type == rwNAPICKOBJECT) {// No clump was pick
ed. m_dynamic_rot_center = BM_POINT(0.0, 0.0,
0.0);}else if(m_pick.type == rwPICKCLUMP) {
// Some clump was picked; process it.ve
rt = m_pick.object.clump.wcpoint;m_dynamic_rot_cen
ter = BM_POINT(vert.x, vert.y, vert.z);}}}else {m_
dynamic_rot_center = BM_POINT(0.0, 0.0, 0.0);}mi_d
ynamic_rot_center_on =1;}else {compute_non_dyn_equ
ivalent();if(md_dyn_rot_matrix) RwDestroyMatrix(md
_dyn_rot_matrix);md_dyn_rot_matrix = NULL; mi_dyn
amic_rot_center_on = 0;} break; case(SELECT_OBJE
CTS_MODE): if(nFlags & MK_CONTROL)add_hit_to_li
st = 1;if(! mi_show_solid) { // Wireframe being
displayed, which means OpenGL picking.glGetIntege
rv(GL_VIEWPORT, viewport);glMatrixMode(GL_PROJECTI
ON);glPushMatrix();glLoadIdentity();gluPickMatrix
((double)point.x, (double)(m_old_rect.bottom - poi
nt.y), 3.0, 3.0, viewport);glOrtho(- md_current_vi
ew_vol[0], md_current_view_vol[0],- md_current_vie
w_vol[1], md_current_view_vol[1],- md_current_view
_vol[2], md_current_view_vol[2]);glMatrixMode(GL_M
ODELVIEW);DrawPart(m_hdc); // Draw the part in s
election mode.glMatrixMode(GL_PROJECTION);glPopMat
rix();glMatrixMode(GL_MODELVIEW);process_hits_reco
rd(add_hit_to_list);ml_last_function_chosen = NO_F
UNCTION_MODE;DrawPart(m_hdc); reset_selection_buff
er();}else { // Solid being shown, so RenderWare p
icking.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_MODE;
DrawPart(m_hdc); }break;case(ZOOM_IN_OUT_MODE):
compute_part_bbox(part, mi_show_3d, md_rot_matri
x, m_part_centroid, md_part_bbox_size, &offset);
mi_bbox_is_up_to_date = 0;if(mi_dynamic_rot_cente
r_on) {// User has furtherzoomed in. compute_non_d
yn_equivalent();RwIdentityMatrix(md_dyn_rot_matri
x);}// Now turn on dynamic rotation center if need
be.if( (md_part_bbox_size[0] > 2.2*md_current_vie
w_vol[0]) || // User has zoomed in so thatnot all
(md_part_bbox_size[1] > 2.2*md_current_view_vo
l[1]) ) { // of the part is in view volume.mi_bbox
_is_up_to_date = 0;// Even though bbox computed, w
e mark as not up to date so that zoom-allif(! md_d
yn_rot_matrix) md_dyn_rot_matrix = RwCreateMatri
x(); // will work correctly.if(mi_show_solid) {/
/ Pick the center of the screen to find point on c
lumpto 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; process it.vert =
m_pick.object.clump.wcpoint; m_dynamic_rot_ce
nter = 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_equivalent();if(md_dy
n_rot_matrix) RwDestroyMatrix(md_dyn_rot_matrix);m
d_dyn_rot_matrix = NULL;mi_dynamic_rot_center_on =
0;}}break; default: break;};ml_last_function_cho
sen = NO_FUNCTION_MODE;CBendCADView::OnLButtonUp(n
Flags,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

Claims (16)

    【特許請求の範囲】
  1. 【請求項1】 コンピュータ読取可能媒体に格納され、
    且つ、ある設備により製造されるべき部品を表現するた
    めのオブジェクト指向曲げモデルにして、前記オブジェ
    クト指向曲げモデルは部品クラスを有し、この部品クラ
    スは、前記部品の複数の特徴に関連する部品情報を有す
    る複数のオブジェクトと、前記部品になされる複数の曲
    げ動作に関連する曲げ情報と、を含む。
  2. 【請求項2】 請求項1のオブジェクト指向曲げモデル
    にして、前記部品情報は、部品デザインおよび部品製造
    情報を含み、前記部品デザインは、2次元座標空間およ
    び3次元座標空間における前記部品の表現に関連する。
  3. 【請求項3】 請求項1のオブジェクト指向曲げモデル
    にして、前記部品クラスは複数の属性を有し、前記複数
    の属性は、前記曲げ動作が前記部品に対してなされる順
    番に関連する曲げシーケンス情報を有する。
  4. 【請求項4】 請求項1のオブジェクト指向曲げモデル
    にして、前記設備において製造される前記部品は板金部
    品を含む。
  5. 【請求項5】 請求項1のオブジェクト指向曲げモデル
    にして、前記曲げ情報は、曲げデータを備える一組のオ
    ブジェクトと、前記部品の曲げ線において曲げ動作を行
    うための指令を含み、前記曲げデータは、曲げ角度量お
    よび曲げ縮小量および曲げ半径量を含む。
  6. 【請求項6】 請求項1のオブジェクト指向曲げモデル
    にして、前記複数のオブジェクトは面のオブジェクトを
    含み、前記面のオブジェクトは、前記部品の各面の寸法
    に関連するデザインデータと、少なくとも一つの所定の
    座標空間における前記部品の各面の表現に関連する位置
    データと、を含む。
  7. 【請求項7】 請求項1のオブジェクト指向曲げモデル
    にして、前記複数のオブジェクトは曲げ線のオブジェク
    トを含み、前記曲げ線のオブジェクトは、前記部品の各
    曲げ線の寸法に関連するデザインデータと少なくとも一
    つの所定の座標空間内における前記部品の各曲げ線の表
    現に関連する位置データとを含む。
  8. 【請求項8】 請求項1のオブジェクト指向曲げモデル
    にして、前記複数のオブジェクトは穴のオブジェクトを
    含み、前記穴のオブジェクトは、前記部品における少な
    くとも一つの部品の寸法に関連するデザインデータと、
    少なくとも一つの所定の座標空間内における前記部品の
    前記穴の表現に関連する位置データとを有する。
  9. 【請求項9】 請求項1のオブジェクト指向曲げモデル
    にして、前記複数のオブジェクトはフォーミングのオブ
    ジェクトを含み、前記フォーミングのオブジェクトは、
    前記部品の各フォーミングの寸法に関連するデザインデ
    ータと、少なくとも一つの所定の座標空間内における前
    記部品の前記フォーミングの表現に関連する位置データ
    とを有する。
  10. 【請求項10】 請求項1のオブジェクト指向曲げモデ
    ルにして、前記複数のオブジェクトはトポロジーのオブ
    ジェクトを含み、前記トポロジーのオブジェクトは前記
    部品の特徴に関連する部品・トポロジーデータを含む。
  11. 【請求項11】 請求項1のオブジェクト指向曲げモデ
    ルにして、前記複数のオブジェクトは曲げ特性のオブジ
    ェクトを含み、前記曲げ特性のオブジェクトは、前記部
    品の少なくとも一つの曲げ特性タイプに関連する製造束
    縛データを含む。
  12. 【請求項12】 コンピュータにより読み出し可能の媒
    体に格納され、かつ、ある製造設備において製造される
    べき板金部品を表現するためのオブジェクト指向曲げモ
    デルにして、 前記オブジェクト指向曲げモデルは部品クラスを含み、 前記部品クラスは、複数の部品属性および、2次元座標
    空間および3次元座標空間における前記板金部品を表現
    するための複数のオブジェクトを有する部品オブジェク
    トを含む、前記複数のオブジェクトは、前記板金部品の
    特徴に関連するデザイン情報と、前記板金部品への少な
    くとも一つの曲げ動作を行うための曲げ情報と、を含
    む。
  13. 【請求項13】 請求項12によるオブジェクト指向曲
    げモデルにして、前記部品の前記特徴は、少なくとも1
    つの面及び穴及び成形部及び曲げ線を備え、前記複数の
    オブジェクトは、少なくとも1つの面オブジェクト及び
    穴オブジェクト及び成形部オブジェクト及び曲げ線オブ
    ジェクトを備える。
  14. 【請求項14】 請求項12によるオブジェクト指向曲
    げモデルにして、前記複数のオブジェクトは、曲げ特性
    オブジェクトを含み、この曲げ特性オブジェクトは、前
    記板金部品の少なくとも1つの曲げ特性タイプに関連す
    る製造制限データを含む。
  15. 【請求項15】 請求項12のオブジェクト指向曲げモ
    デルにして、前記曲げ情報は、前記板金部品に対して成
    される複数の曲げ操作に関連する。
  16. 【請求項16】 請求項12によるオブジェクト指向曲
    げモデルにして、前記曲げ情報は、曲げデータ及び前記
    板金部品に対する前記少なくとも1つの曲げ動作を行な
    うための指令を有する一群のオブジェクトを含む。
JP2001020132A 1996-07-31 2001-01-29 板金製造設備全体にわたって設計製造情報を管理し分配する装置及び方法 Pending JP2001265834A (ja)

Applications Claiming Priority (8)

Application Number Priority Date Filing Date Title
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
US08/690,084 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/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/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,671 1996-07-31

Related Parent Applications (1)

Application Number Title Priority Date Filing Date
JP21933297A Division JP3308869B2 (ja) 1996-07-31 1997-07-30 部品表示画像操作システムおよび方法

Publications (1)

Publication Number Publication Date
JP2001265834A true JP2001265834A (ja) 2001-09-28

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 Before (1)

Application Number Title Priority Date Filing Date
JP21933297A Expired - Fee Related JP3308869B2 (ja) 1996-07-31 1997-07-30 部品表示画像操作システムおよび方法

Country Status (1)

Country Link
JP (2) JP3308869B2 (ja)

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2009193489A (ja) * 2008-02-18 2009-08-27 Olympus Corp 作業手順書作成システム
KR102261396B1 (ko) * 2020-11-18 2021-06-07 디케이소프트 주식회사 정확성을 높인 용접부 정보 자동생성방법

Families Citing this family (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP3171830B2 (ja) * 1998-08-26 2001-06-04 株式会社エヌ・シー・エヌ 建築構造部材の処理装置
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 村田機械株式会社 データ生成装置、加工装置、及びデータ生成プログラム

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2009193489A (ja) * 2008-02-18 2009-08-27 Olympus Corp 作業手順書作成システム
KR102261396B1 (ko) * 2020-11-18 2021-06-07 디케이소프트 주식회사 정확성을 높인 용접부 정보 자동생성방법

Also Published As

Publication number Publication date
JPH10149206A (ja) 1998-06-02
JP3308869B2 (ja) 2002-07-29

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
WO1997042608A9 (en) Apparatus and method for generating a sheet-metal bend model
JP3884195B2 (ja) 薄板金属製作設備全体にわたって設計製作情報を分配する装置および方法
JP3308869B2 (ja) 部品表示画像操作システムおよび方法
Kalay Worldview: An integrated geometric-modeling/drafting system
Herman Representation and incremental construction of a three-dimensional scene model
JP3766857B2 (ja) 3次元モデルの開発支援システム
EP1830323A2 (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
JP2003067746A (ja) 形状特徴マイニング方法およびその装置
JP2003271681A (ja) フィレット作成方法、及び3次元cadプログラム
Midha Conversion of 2-dimensional drawings into 3-dimensional solid model
Tibbitts Solid modelling and the representation of buildings