JPH05324774A - 立体モデル生成装置および方法 - Google Patents

立体モデル生成装置および方法

Info

Publication number
JPH05324774A
JPH05324774A JP3328318A JP32831891A JPH05324774A JP H05324774 A JPH05324774 A JP H05324774A JP 3328318 A JP3328318 A JP 3328318A JP 32831891 A JP32831891 A JP 32831891A JP H05324774 A JPH05324774 A JP H05324774A
Authority
JP
Japan
Prior art keywords
color
short
struct
double
map
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
JP3328318A
Other languages
English (en)
Inventor
Liangpin Chen
リアンピン・チェン
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.)
International Business Machines Corp
Original Assignee
International Business Machines Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by International Business Machines Corp filed Critical International Business Machines Corp
Publication of JPH05324774A publication Critical patent/JPH05324774A/ja
Pending legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06TIMAGE DATA PROCESSING OR GENERATION, IN GENERAL
    • G06T15/003D [Three Dimensional] image rendering
    • G06T15/50Lighting effects

Landscapes

  • Engineering & Computer Science (AREA)
  • Computer Graphics (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Theoretical Computer Science (AREA)
  • Image Generation (AREA)
  • Processing Or Creating Images (AREA)
  • Medicines That Contain Protein Lipid Enzymes And Other Medicines (AREA)

Abstract

(57)【要約】 【目的】本発明の目的は、設計図面を設計し、動的に変
更し表示するための設計システムを提供することであ
る。 【構成】本発明によれば、ユーザは表示画面から現活動
オブジェクトとして立体オブジェクトを選択する。次い
で、ユーザは前景内に提示したい表面を選択する。次い
で、システムは個々の画素の照度を修正することによ
り、前景表面にアクセントをつけるため表示データ構造
を修正する。 【効果】この技法により、表示画面上の領域に陰影をつ
ける効果が得られ、図面の重要な特徴を強調表示するこ
とができる。

Description

【発明の詳細な説明】
【0001】
【産業上の利用分野】本発明は、全般的にはコンピュー
タ支援設計(CAD)システムの改良に関するものであ
り、具体的には表面に陰影をつけて、その知覚性を高め
る技法に関する。
【0002】
【従来の技術】CAD応用例では、オブジェクトの2次
元表現を立体表現に変形できることが重要である。自動
車産業と航空機産業が、機械組み立てのためにこの機能
を最初に開発した産業のうちの2つである。一般的なC
ADシステムの例が、米国特許第4962472号、第
4849913号および第4912664号明細書に開
示されている。
【0003】米国特許第4849913号明細書には、
複合部品に含まれる各プライの幾何的定義を論理的に決
定することによって、複合部品の設計と構成を行なうた
めの方法が開示されている。この情報を、後で分析ルー
チンで使用して、部品の製造に最適の方法を決定するこ
とができる。すなわち、各部品の物理的な関係及びそれ
らの相関する特徴が、システムで使用できるようにな
る。しかしながら、このCADシステムには、複数の面
同士の間隔の変化に基づいて、ある立体の寸法を動的に
変更する能力が欠けている。
【0004】面は、無境界の平面を指すのに使用され
る。無境界とは、平面の寸法に制限がないことを指す。
ループとは、ある面の、境界で囲まれた領域である。境
界要素は、ループを含む。たとえば、平面の辺を形成す
る4本の線は、境界要素である。頂点とは、辺の終点で
ある。頂点は、3つの相交わる平面方程式の交点を見つ
けることによって計算される。ループ・テーブルには、
ある立体オブジェクトに含まれる全てのループを定義す
る情報が含まれる。
【従来の技術】
【0005】本発明は、従来技術の制約を克服して、図
形表示装置上での3次元図面の正確で写実的な表現を提
供するものである。
【0006】
【発明が解決しようとする課題】本発明の目的は、3次
元立体表現の設計、動的な変更および表示のための改良
された装置および方法を提供することである。
【0007】
【課題を解決するための手段】本発明は、現在の図形表
示装置の制約を克服して、3次元表面の明確な表現を生
成するものである。本発明は、陰影用の色テーブルを構
築するアルゴリズムを使用し、ユーザが表面の法線を反
転して写実的な像を得られるようにして、3次元表面の
表示機能を拡張する。色テーブルは、200色のエント
リを含む。線形増分関数の上に非線形強度ファクタを追
加して、下から上まで連続した色テーブル強度を生成す
る。色テーブルは、ユーザが陰影色を変更するごとに再
生成される。色テーブル内の現在値に基づいて、陰影を
つけた表面に、視点と光源の位置に応じたアクセントが
付けられる。ユーザが正しくない表面を選択すると、シ
ステムは、消去された表面の表面法線を反転し、その表
面に陰影をつけ直して、写実的な図にアクセントを付け
る。
【0008】図1を参照すると、本発明の装置は、IB
MがPS/2の製品名で市販しているものなど標準のマ
イクロプロセッサである。CPU10は、たとえば80
386または80486プロセッサとすることができ
る。CPU10は、RAM20、ディスク30およびデ
ィスケット40への直接メモリ・アクセス(DMA)を
有する。CPU10はまた、通信リンク50を介して情
報を送出することができる。
【0009】またCPU10は、接続された図形表示装
置と通信して、EGA、VGAまたは他の高解像度モー
ドで情報を表示する。マウス70は、任意選択のカーソ
ル・ポインティング装置であり、キーボード80の矢印
キーを補完して、図形表示装置60上での正確なポイン
ティングを指定するのに使用される。キーボードは、C
PU10内のバッファ手段を含むキーボード・アダプタ
82によって制御される。最後に、図面のハードコピー
を作成するために、プリンタまたはプロッタ89をCP
U10に接続することができる。
【0010】本発明のハードウェアの独特な特徴機能を
呼び出すのに使用されるソフトウェアは、ディスク30
に常駐し、本発明を使用する設計者によって作成された
図面も同様である。このソフトウェアは、マウス/キー
ボードからの信号を適当なシステム動作に変換する責任
も負う。
【0011】図2は、本発明による論理を示す流れ図で
ある。2次元の図面から立体を生成するために、機能ブ
ロック200で、まず図面をコンピュータ・メモリにロ
ードする。この図面は、あるオブジェクトの複数の2次
元投影図を含んでいなければならない。その後入力ブロ
ック210で、ユーザは適当なメニュー選択項目を選択
する。次に、入力ブロック220で、ユーザは、押出し
操作用の輪郭を形成するための要素を選択する。これら
の要素は、2次元投影図上の直線と円であり、これらか
ら立体モデルが生成される。選択された要素を指すポイ
ンタが、下記のデータ構造に記憶される。 /*: :PART V - The temporary records for keeping 2D elements : :...................................... : :option: 1- extrusion : 2- taper : 3- pyramid : 4- rotation : :operation: : : 1- add : -1- subtract : :tip[2] :a temporary cadam pointer to a point of a pyramid (not used) :front, back :record front face and back face pointer (pointer to line) :numbdry :number of boundary segments in the bdry array :bdry :pointer to line and circle :bdry1 bdry2 :only case 2 will use both index ( for taper only ) : rest of the cases use bdry1 : :......................................... : :IDENTIFICATION: : :AUTHOR ..... ALLEN CHEN :DATE ..... 10/15/89 : :.......................................... */ struct bdrytype { short numbdry; short bdry[maxbdry][2]; }; struct frametype { short option; short operator; short front[2], back[2]; short tip[2]; struct bdrytype * bdry1; struct bdrytype * bdry2; }; struct film { short numframe; struct frametype * frame[maxframe]; }; 幾何形状要素は、時計回りまたは反時計回りの順序で選
択される。必要な全ての要素を選択し終えると、メニュ
ー項目ENDを選択して、完了を示す。上記のデータ構
造を使用して、本発明による後続の処理で扱いやすい形
でこの情報を記憶する。
【0012】入力ブロック230で、ユーザは、輪郭図
以外の投影図に含まれる線を選択することによって、前
と後の切断面を選択する。次に、入力ブロック240
で、選択された2次元要素が、3次元幾何形状に変換さ
れる。すなわち、たとえば直線は無境界の平面になり、
円は無境界の円筒になり、スプラインは線織面になる。
これらの面は、下記のPFaceデータ構造体に記憶さ
れる。
【0013】Face Tableは、ある立体の境界
を形成する面のリストである。Face Tableに
は、平面、円筒および自由表面の情報が含まれる。Fa
ceTableは、パラメータ設計と立体モデラの間の
インターフェースとして働く。PFaceテーブルは、
パラメータ設計に使用される特定の面テーブルである。
これは、パラメータ化された面、パラメータ・テーブ
ル、およびそれらの面から立体を構築するための構造リ
ストを含む。構造リストは、立体の各部分がどのように
して作成されるかと、その構成要素を形成するのにどの
面が使用されるかの記述を含む。 /*============================================= : :PART I - CONSTANT DEFINITIONS FOR FACE TABLE :........................... */ #define FSIZE 200 #define MXSIZE 20 #define maxbdry 100 #define maxframe 100 #define VARSIZE 100 /*===================================================== : :PART II - THE FACE TABLE & PARAMETRIC TABLE : :............................... : :PFace : :FaceType: : : 1- PlaneFace : subtype function : ______ _________________________ : 0 original plane face : 1 define offset plane, define : pointer to variable table : which defines the : offset value or formula : 2 angled face : 11 define chamfer plane : : : 2- Circular Cylinder : subtype function : ______ _________________________ : 0 original Cylinder, defines xy and R : 1 define offset cylinder, define dR : 2 define location : 11 define round : 12 define fillet : : 3- ConicFace : 4- RuledFace : 5- FreeFormFace : x-Arc define cylinder number, A1, A2 : :................................. : :Fcode - mark the usage of the face : : bit 1: solid faces : 2: construction faces : 3: symmetric faces (shall be defined by its children) : 4: datum face (??? unknown yet) : : note: bit map 15,14,13 ...... 3,2,1 : :....................................... : :ModVar - count how many var were changed, : indicate the necessity of updating Var : table by bringing SmallTalk parser : not implemented in current version. : :................................ : :struct PlaneSym : : pair: stores the other symmetric face to the base : base: the base face : :................................ : :struct PlaneChm : : p1,p2,pw - pointer to plane faces : vi,v2 - pointer to variable table : :................................ : :struct Parameter : : mode - 1: value : 2: text */ #define ORGPLANE 0 #define OFFPLANE 1 #define SYMPLANE 2 #define CHMPLANE 11 struct PlaneOrg { double A,B,C,D; }; struct PlaneOff { short base; short varid; }; struct PlaneSym { short base,pair; short varid; }; struct PlaneChm { short p1,p2,pw; short v1,v2; }; union plane_ptr { struct PlaneOrg Porg; struct PlaneSym Psym; struct PlaneOff Poff; struct PlaneChm Pchm; }; struct PPlane { short subtype; union plane_ptr pclass; }; struct PCylinder { double R,X,Y,A1,A2,Z1,Z2; short MatrixIndex; short Udisp; struct POINT *Vertics[2][13]; }; struct PCone { double R1,R2,X,Y,A1,A2,Z1,Z2; short MatrixIndex; short Udisp; struct POINT *Vertics[2][13]; }; struct PRuled { short MatrixIndex; short Udisp; struct BSPLINE Bspl; }; struct PFreeForm { int NU,NW;double *ControlPoints[50][50]; }; struct Parameter { char Label[8]; double value; char text[72]; short mode; }; union face_ptr { struct PPlane *PlaneFace; struct PCylinder *CirularCylinder; struct PCone *ConicFace; struct PRuled *RuledFace; struct PFreeForm *FreeFormFace; }; struct PFace { short FaceType; short Fcode; union face_ptr fclass; }; struct Matrix { double p1[3],p2[3],p3[3],p4[3]; }; struct PFaces { short NumberFaces; short NumberMatrix; short NumberVar; short ModVar; struct PFace *Face [FSIZE]; struct Matrix *Matrix [MXSIZE]; struct Parameter *Var [VARSIZE]; }; 次のステップ250で、立体モデラに入力するため、P
Faceデータ構造体をFaceデータ構造体に変換す
る。Faceデータ構造体を下記に示す。 /*===================================================== =========== : :PART III - THE FACE TABE FOR INTERFACING WITH SOLID MODULE : :.................................. : :define face table interface to solid : :define face tables : :MatrixIndex stores the index to matrix list :SameFace stores the index to the first equivalent face : shall be maintained every time a object was created :Matrix the array will start from 13 to 39. : :FaceTable : : FaceType: 1- PlaneFace : 2- Circular Cylinder : 3- ConeFace : 4- RuledFace : 5- FreeFormFace : :.................................. : :IDENTIFICATION: : :AUTHOR ......FRANK NIU :DATE ...... --/--/89 : :.......................... */ struct PlaneFace { double A,B,C,D; }; struct CircularCylinder { double R,X,Y,A1,A2,Z1,Z2; short MatrixIndex; short Udisp; struct POINT *Vertics[2][13]; }; struct ConeFace { double R1,R2,X,Y,A1,A2,Z1,Z2; short MatrixIndex; short Udisp; struct POINT *Vertics[2][13]; }; struct RuledFace { short MatrixIndex; short Udisp; struct BSPLINE Bspl; }; struct FreeFormFace { int NU,NW;double *ControlPoints[50][50]; }; struct FaceTable { short FaceType; struct PlaneFace *PlaneFace; struct CircularCylinder *CircularCylinder; struct ConeFace *ConeFace; struct RuledFace *RuledFace; struct FreeFormFace *FreeFormFace; }; struct Faces { short NumberFaces; short NumberMatrix; struct FaceTable *FaceTable [FSIZE]; struct Matrix *Matrix [MXSIZE]; }; その後、機能ブロック260で、このFaceデータ構
造体が立体モデラに入力されて、押出しテーパ操作が行
なわれる。下記のデータ構造は、このタスクの実行中に
使用される。 /*===================================================== : :PART IV - The construction tree : :................................... : :component list : : .operator: 0 disabled component : 1 add component : -1 substract component : : .component type: 1 extrusion : 2 taper : 3 pyramid : 4 rotation : :.................................. : :IDENTIFICATION: : :AUTHOR ...... ALLEN CHEN :DATE ...... 10/15/89 : :.................................. */ struct OneComponent { short option; short operator; short numbdry; short bondary[maxbdry]; short front,back; }; struct Comphd { short NumberComponent; struct OneComponent * component[maxframe]; }; 最後に、出力ブロック270で、この立体オブジェクト
が図形表示装置で表示される。下記のリストは、様々な
変形と図形情報の表示を実施するのに使用されるソース
・コードである。 /*********************************************************************** * Common Header files *********************************************************************** */ #include <math.h> #include <malloc.h> #include "3dgm1.f" #include "3dut1.f" #include "3dmi1.f" #include "units.h" #include "bspline.h" #include "param.h" #include "stb.h" /*********************************************************************** * Header files for C_gm_telsld() *********************************************************************** */ #includ "fkgp3d.h" /*********************************************************************** * Header files for C_gm_trsld3x() *********************************************************************** */ #include "gt3d.h" /*********************************************************************** * Definitions for C_gm_telsld() *********************************************************************** */ #define OrgPlane fclass.PlaneFace->pclass.Porg #define Cylinder fclass.CircularCylinder #define ConFace fclass.ConicFace /*********************************************************************** * Definitions for C_gm_trsld3x() *********************************************************************** */ #define OrgPlane fclass.PlaneFace->pclass.Porg /*********************************************************************** * Function declearations for C_gm_telsld() *********************************************************************** */ static void C_gm_1_remake_ABCD ( short,double[], double,double,double,double, double*,double*,double*,double*); static void C_gm_1_remake_matrix ( short,double[], double[][3],double[][3]); static void C_gm_2_point_on_plane ( double,double,double,double, double,double,double, double*,double*,double*); static void C_gm_2_rotate_point ( double[],double[],double[]); static void C_gm_2_mirror_point ( double[],double[],double[]); /*********************************************************************** * Function declearations for C_gm_trsld3x() *********************************************************************** */ short C_trplnorm ( short,double[],double[],double,double[],double *); short C_trmxab ( double[],double[],double[],double[],double[]); short C_trmxlc ( double[],double[],double[],double[],double[]); /*********************************************************************** * [Function Name] * iret = C_gm_telsld( iopt,tdata,solid_ptr ) * *[Category] * Geometric Calculation ( Translation of element ) * *[Description] * Transform SOLID * *[Parameters] * (i) short iopt -- Processing Option * 1: Translation (Move) * 2: Mirroring * 3: Rotation * 4: Scaling * * (i) double tdata[] -- Data for Translation * iopt=1=> tdata[3]: DX,DY,DZ * iopt=2=> tdata[12]: Data of Mirror Plane * iopt=3=> tdata[7]: X,Y,Z (Point on Axis) * A,B,C (Vextor of Axis) * ANG (Rotation Angle) * iopt=4=> tdata[4]: X,Y,Z (Center of Scale) * SCL (Scaling Factor) * * (i) short solid_ptr[2] -- Pointer of Solid (In) * * (o) short iret -- Return Code (0:OK, 1:Error) * *[External Variables] * struct PFaces PFaces * struct Comphd CompList * *[Calls] * Retv_Solid ( defparam.c ) * Q_subtype ( " ) * Q_Plane_ABCD ( " ) * Save_Parameters ( " ) * Save_Solid ( " ) * del_solid_polygons ( entersd.c ) * *[Restriction] * *[Algorithm] * * 1. Get face table from elmptr * 2. Transform face table * 3. Transform working plane * 4. Validate the transformed solid * 5. Save the transformed solid * ************************************************************************ * * Created by .... Eiji Nakano * Date .... 2/23/90 * ************************************************************************ * * Modified by .... Allen Chen * Date .... 6/25/90 * Nature(#1) .... Change stb.h and param.h * * Modified by .... Allen Chen * Date .... 10/3/90 * Nature(#2) .... use local variables (PFaces,Solid,Complist) * copy solid is a special case, done by cpysld() in * solidmi.c. * Fix error in scaling face table and working plane. * ************************************************************************ */ short C_gm_telsld( iopt,tdata,solid_ptr ) short iopt; short solid_ptr[]; doulbe tdata[]; { char sname[128]; char lbl[8],str[72]; short fid,stype; short ftype; short iret; short i; short ihdata[10]; short pid,mode; double value; double A,B,C,D; double AA,BB,CC,DD; double new_matrix[4][3],old_matrix[4][3]; struct PFaces *PFaces; struct Comphd *CompList; struct SolidTable *Solid; PFaces = (struct PFaces *) malloc (sizeof (struct PFaces)); if (PFaces == 0) return 200; CompList = (struct Comphd *) malloc (sizeof(struct Comphd)); if (CompList == 0) { free(PFaces); return 200; } Solid = (struct SolidTable *) malloc (sizeof(struct SolidTable)); if (Solid == 0) { free(PFaces); free(CompList); return 200; } ihdata[0] = 0; Retv_Solid( solid_ptr,PFaces,CompList,sname ); for( fid=1;fid<=PFaces->NumberFaces; fid++ ) { ftype = PFaces ->Face[fid]->FaceType; /*********/ /* plane */ /*********/ if( ftype == 1 ) { /*..................................... :Allen Chen 10/9/90 :offset faces shall be scaled with scaling value :...................................... */ Q_subtype( PFaces,fid,&stype ); if( stype != 0 ) { if(iopt == 4) { iret = Q_OffFace(PFaces,fid,&pid,lbl,&value,str,&mode); if (iret == 0) { value *= tdata[3] iret = Mod_OffFace((short)1,PFaces,pid,fid,value,str); } } } else { Q_Plane_ABCD( PFaces,fid,&A,&B,&C,&D ); C_gm_1_remake_ABCD( iopt,tdata,A,B,C,D, &AA,&BB,&CC,&DD ); PFaces->Face[fid]->OrgPlane.A = AA; PFaces->Face[fid]->OrgPlane.B = BB; PFaces->Face[fid]->OrgPlane.C = CC; PFaces->Face[fid]->OrgPlane.D = DD; } } /***********************************/ /* cylinder or conic and scaling */ /***********************************/ else if((ftype == 2 ‖ftype == 3)&& iopt == 4 ) { /************/ /* cylinder */ /************/ if( ftype == 2 ) { PFaces->Face[fid]->Cylinder->R *= tdata[3]; PFaces->Face[fid]->Cylinder->X *= tdata[3]; PFaces->Face[fid]->Cylinder->Y *= tdata[3]; } /*********/ /* conic */ /*********/ else if( ftype == 3 ) { PFaces->Face[fid]->ConFace->R1 *= tdata[3] PFaces->Face[fid]->ConFace->R2 *= tdata[3] PFaces->Face[fid]->ConFace->X *= tdata[3] PFaces->Face[fid]->ConFace->Y *= tdata[3] } } } for( i=1; i<=PFaces->NumberMatrix; i++ ) { C_ut_dpsto( 3,PFaces->Matrix[i]->p1,old_matrix[0] ); C_ut_dpsto( 3,PFaces->Matrix[i]->p2,old_matrix[1] ); C_ut_dpsto( 3,PFaces->Matrix[i]->p3,old_matrix[2] ); C_ut_dpsto( 3,PFaces->Matrix[i]->p4,old_matrix[3] ); C_gm_1_remake_matrix( iopt,tdata,old_matrix,new_matrix ); C_ut_dpsto( 3,new_matrix[0],PFaces->Matrix[i]->p1 ); C_ut_dpsto( 3,new_matrix[1],PFaces->Matrix[i]->p2 ); C_ut_dpsto( 3,new_matrix[2],PFaces->Matrix[i]->p3 ); C_ut_dpsto( 3,new_matrix[3],PFaces->Matrix[i]->p4 ); } /*.................................. :Allen Chen 10/2/90 :option 1 is replacing the model block with the new data. :See "solidmi.c" for details. :................................... */ iret = mksolid (PFaces,CompList,Solid); if (iret == 0) iret = C_mi_sdstore((short)1,PFaces,CompList,sname,ihdata,solid_ ptr); C_sd_cpftabale(PFaces); C_sd_ccompl(CompList); FreeSolid(Solid); free(Solid); free(CompList); free(PFaces); if(iret != 0) iret = 1; return (iret); } /*===================================================== ===================== :static void C_gm_1_remake_ABCD( iopt,tdata,A,B,C,D,AA,BB,CC,DD ) : :make new plane data from old plane data : :input short iopt --- 1 move : 2 mirror : 3 rotate : 4 scale : double tdata[] -- Data for Translation : iopt=1=> tdata[3]:DX,DY,DZ : iopt=2=> tdata[12]*Data of Mirror Plane : iopt=3=> tdata[7]:X,Y,Z (Point on Axis) : A,B,C(Vextor of Axis) : ANG (Rotation Angle) : iopt=4=> tdata[4]:X,Y,Z(Center of Scale) : SCL (Scaling Factor) : double A,B,C,D - old plane data : :output double *AA,*BB,*CC,*DD - new plane data :................................... :Allen Chen 10/8/90 :make the vector [AA,BB,CC] as unit vector :................................... */ static void C_gm_1_remake_ABCD( iopt,tdata,A,B,C,D,AA,BB,CC,DD ) short iopt; double tdata[]; double A,B,C,D; double *AA,*BB,*CC,*DD; { double pt1[3],pt2[3],dist[3] double d; /********/ /* move */ /********/ if( iopt == 1 ) { *AA = A; *BB = B; *CC = C; *DD = A*tdata[0] + B*tdata[1] + C*tdata[2] + D; } /**********/ /* mirror */ /**********/ else if( iopt == 2 ) { C_gm_2_point_on_plane( A,B,C,D,0.0,0.0,0.0, &pt1[0],&pt1[1],&pt1[2] ); pt2[0] = pt1[0] + A; pt2[1] = pt1[1] + B; pt2[2] = pt1[2] + C; C_gm_2_mirror_point( pt1,tdata,pt1 ); C_gm_2_mirror_point( pt2,tdata,pt2 ); *AA = pt2[0] - pt1[0]; *BB = pt2[1] - pt1[1]; *CC = pt2[2] - pt1[2]; d = sqrt((*AA)*(*AA) + (*BB)*(*BB) + (*CC)*(*CC)); *AA /= d; *BB /= d; *CC /= d; *DD = *AA*pt1[0] + *BB*pt[1] + *CC*pt1[2]; } /**********/ /* rotate */ /**********/ else if( iopt == 3 ) { C_gm_2_point_on_plane( A,B,C,D,0.0,0.0,0.0, &pt1[0],&pt1[1],&pt1[2] ); pt2[0] = pt1[0] + A; pt2[1] = pt1[1] + B; pt2[2] = pt1[2] + C; C_gm_2_rotate_point( pt1,tdata,pt1 ); C_gm_2_rotate_point( pt2,tdata,pt2 ); *AA = pt2[0] - pt1[0]; *BB = pt2[1] - pt1[1]; *CC = pt2[2] - pt1[2]; d = sqrt((*AA)*(*AA)+(*BB)*(*BB)+(*CC)*(*CC)); *AA /= d; *BB /= d; *CC /= d; *DD = *AA*pt1[0]+*BB*pt1[1]+*CC*pt1[2]; } /*********/ /* scale */ /*********/ else if( iopt == 4 ) { C_gm_2_point_on_plane( A,B,C,D,tdata[0],tdata[1],tdata[2], &pt1[0],&pt1[1],&pt1[2] ); C_ut_dpsub( 3 pt1, tdata, dist ); C_ut_dpmult( 3, tdata[3],dist,dist ); C_ut_dpadd( 3,tdata,dist,pt1 ); *AA = A / tdata[3]; *BB = B / tdata[3]; *CC = C / tdata[3]; d = sqrt((*AA)*(*AA)+(*BB)*(*BB)+(*CC)*(*CC)); *AA /= d; *BB /= d; *CC /= d; *DD = *AA*pt1[0]+*BB*pt1[1]+*CC*pt1[2]; } } /*===================================================== ===================== :static void C_gm_1_remake_matrix( iopt,tdata,old_matrix,new_ : matrix ) : :make new matrix data from old matrix : :input short iopt -- 1 move : 2 mirror : 3 rotate : 4 scale : double tdata[] -- Data for Translation : iopt=1=> tdata[3]:DX,DY,DZ : iopt=2=> tdata[12]:Data of Mirror Plane : iopt=3=> tdata[7]:X,Y,X(Point on Axis) : A,B,C(Vextor or Axis) : ANG (Rotation Angle) : iopt=4=> tdata[4]:X,Y,Z(Center of Scale) : SCL (Scaling Factor) : double old_matrix[4][3] -- present matrix :output double new_matrix[4][3] -- regenerated matrix */ static void C_gm_1_remake_matrix( iopt,tdata,old_matrix,new_matrix ) short iopt; double tdata[]; double old_matrix[][3]; double new_matrix[][3]; { short i; double pt1[3],pt2[3]; double dist[3]; /********/ /* move */ /********/ if( iopt == 1 ) { C_ut_dpadd( 3,old_matrix[3],tdata,new_matrix[3]); C_ut_dpsto( 3,old_matrix[0],new_matrix[0]); C_ut_dpsto( 3,old_matrix[1],new_matrix[1]); C_ut_dpsto( 3,old_matrix[2],new_matrix[2]); } /**********/ /* mirror */ /**********/ else if( iopt == 2 ) { pt1[0]=pt1[1]=pt1[2]=0.0; C_gm_2_mirror_point( pt1,tdata,pt1 ); for( i=0;i<3;i++) { C_gm_2_mirror_point( old_matrix[i],tdata,pt2 ); C_ut_dpsub( 3,pt2,pt1,new_matrix[i] ); } C_gm_2_mirror_point( old_matrix[3],tdata,new_matrix[3] ); } /**********/ /* rotate */ /**********/ else if( iopt == 3 ) { pt1[0]=pt1[1]=pt1[2]=0.0; C_gm_2_rotate_point( pt1,tdata,pt1 ); for( i=0,i<3;i++) { C_gm_2_rotate_point( old_matrix[i],tdata,pt2 ); C_ut_dpsub( 3,pt2,pt1,new_matrix[i]); } C_gm_2_rotate_point( old_matrix[3],tdata,new_matrix[3] ); } /*********/ /* scale */ /*********/ else if( iopt == 4 ) { C_ut_dpsub( 3,old_matrix[3],tdata,dist ); C_ut_dpmult( 3,tdata[3],dist,dist ); C_ut_dpadd( 3,tdata,dist,new_matrix[3] ); C_ut_dpsto( 3,old_matrix[0],new_matrix[0] ); C_ut_dpsto( 3,old_matrix[1],new_matrix[1] ); C_ut_dpsto( 3,old_matrix[2],new_matrix[2] ); } } /*===================================================== ===================== :static void C_gm_2_point_on_plane(A,B,C,D,px,py,pz,x,y,z) : ............................. : :by Allen Chen (2/28/90) : : : :find intersecting point of the plane(Ax+By+Cz=D) : :and the 3D line (vector(A,B,C)& point(px,py,pz)). : : : :Note: the vector of the 3D line has to be the same as : : the normal vector of the plane. : : ............................. : :input double A,B,C,D plane data : double px,py,pz 3D point : :output double *x,*y,*z intersecting point */ static void C_gm_2_point_on_plane(A,B,C,D,px,py,pz,x,y,z) double A,B,C,D; double px,py,pz; double *x,*y,*z; { double tvalue; tvalue = ( D - ( A*px + B*py + C*pz ))/( A*A + B*B + C*C ); *x = px + tvalue * A; *y = py + tvalue * B; *z = pz + tvalue * C; } /*===================================================== ===================== : :static void C_gm_2_rotate_point( pt1,tdata,pt2 ) : :find the point after rotation : :input double pt1[3] -- 3D point : double tdata[7] -- rotating data: X,Y,Z(Point on Axis) : A,B,C(Vextor of Axis) : ANG (Rotation Angle) :output double pt2[3] -- rotated point */ static void C_gm_2_rotate_point( pt1,tdata,pt2 ) double pt1[]; double tdata[]; double pt2[]; { double ptw[3],ptw2[3]; double matrix[4][3]; C_gm_ptxln3( pt1,tdata,ptw ); if( C_ut_dpdist( 3,pt1,ptw )<UNITS.toler ) { C_ut_dpsto( 3,pt1,pt2 ); return; } C_ut_dpadd( 3,tdata,&tdata[3],ptw ); C_gm_crtpln( tdata,ptw,pt1,matrix[0] ); C_gm_tran3d( 2,matrix[0],ptw,pt1 ); ptw2[0] = ptw[0]; ptw2[1] = ptw[1] * cos( tdata[6] ); ptw2[2] = ptw[1] * sin( tdata[6] ); C_gm_tran3d(1,matrix[0],ptw2,pt2 ); } /*===================================================== ===================== :static C_gm_2_mirror_point( pt1,tdata,pt2 ) : :find the mirroring point : :input double pt1[3] -- 3D point : double tdata[12] -- plane data :output double pt2[3] -- mirroring point */ static void C_gm_2_mirror_point( pt1,tdata,pt2 ) double pt1[]; double tdata[]; double pt2[]; { double ptw[3],dist[3]; C_gm_ptxpl3( pt1,tdata,ptw ); C_ut_dpsub( 3,ptw,pt1,dist ); C_ut_dpadd( 3,ptw,dist,pt2 ); } /*********************************************************************** *[Function Name] * iret = C_gm_trsld3x( iopt,mtrx,ptr ) * *[Category] * Geomatry Calculation * *[Description] * Convert 3D Ruled Surface * *[Parameters] * (i) short iopt -- Processing Option * 1: Local(mtrx) ==> Absolute * 2: Absolute ==> Local(mtrx) * * (i) double mtrx[4][3] - matrix of coordinate convention * * (i/o) short ptr[2] --- pointer to Solid model block * * (o) short iret -- Return code(o:OK,1:NG) * * *[External Variables] * *[Calls] * *[Restriction] * *[Algorithm] * ************************************************************************ * * Created by .... Allen Chen * Date ..... 10/23/90 * ************************************************************************ * * Modified by .... * Date .... * Nature(#1) .... ************************************************************************ */ short C_gm_trsld3x( iopt,mtrx,ptr ) short iopt,ptr[]; double mtrx[]; { char sname[128]; short fid,stype; short ftype; short iret; short i; short ihdata[10]; double D; double DD; double pn[3],pnn[3]; struct PFaces *PFaces; struct Comphd *CompList; struct SolidTable *Solid; PFaces = (struct PFaces *)malloc(sizeof(struct PFaces)); if(PFaces == 0) return 200; CompList = (struct Comphd *)malloc(sizeof(struct Comphd)); if(CompList == 0) { free(PFaces); return 200; } Solid = (struct SolidTable *)malloc(sizeof(struct SolidTable)); if(Solid == 0) { free(PFaces); free(CompList); return 200; } Retv_Solid( ptr,PFaces,CompList,sname ); for( fid=1;fid<=PFaces->NumberFaces;fid++ ) { ftype = PFaces->Face[fid]->FaceType; if( ftype == 1 ) { /* ................................. :Allen Chen 10/9/90 :offset faces shall be scaled with scaling value : .................................. */ Q_subtype( PFaces,fid,&stype ); if ( stype == 0 ) { Q_Plane_ABCD( PFaces,fid,&pn[0],&pn[1],&pn[2],&D ); iret = C_trplnorm( iopt,mtrx,pn,D,pnn,&DD ); PFaces->Face[fid]->OrgPlane.A = pnn[0]; PFaces->Face[fid]->OrgPlane.B = pnn[1]; PFaces->Face[fid]->OrgPlane.C = pnn[2]; PFaces->Face[fid]->OrgPlane.D = DD; } } } if(iopt == 1 ) for( i=1;i<=PFaces->NumberMatrix;i++ ) { iret = C_trmxlc ( mtrx,PFaces->Matrix[i]->p1, PFaces->Matrix[i]->p2,PFaces->Matrix[i]->p3, PFaces->Matrix[i]->p4); } else if(iopt == 2) for( i=1;i<=PFaces->NumberMatrix;i++ ) { iret = C_trmxlc ( mtrx,PFaces->Matrix[i]->p1, PFaces->Matrix[i]->p2,PFaces->Matrix[i]->p3, PFaces->Matrix[i]->p4); } iret = mksolid (PFaces,CompList,Solid); if(iret == 0) iret = C_mi_sdstore((short)1,PFaces,CompList,sname,ihdata,ptr ); C_sd_cpftable(PFaces); C_sd_ccompl(CompList); FreeSolid(Solid); free(Solid); free(PFaces); free(CompList); if (iret != 0) iret = 1; return( iret ); } short C_trplnorm( iopt,mtrx,n,D,nn,DD) short iopt; double mtrx[]; double n[],D; double nn[], *DD; { double t; double p[3],q[3]; p[0] = D * n[0]; p[1] = D * n[1]; p[2] = D * n[2]; if(iopt == 1) { C_gm_tran3d( 11,mtrx,n,nn); C_gm_tran3d( 1,mtrx,p,q); } else if(iopt == 2) { C_gm_tran3d( 12,mtrx,nn,n); C_gm_tran3d( 2,mtrx,q,p); } t = sqrt(nn[0]*nn[0]+nn[1]*nn[1]+nn[2]*nn[2]); if(t<1.e-6)return 1; else if (fabs(t-1.0)>1.e-6) { nn[0] /=t; nn[1] /=t; nn[2] /=t; } *DD = nn[0]*q[0]+nn[1]*q[1]+nn[2]*q[2]; return 0; } short C_trmxab( mtrx,p1,p2,p3,p4) double mtrx[]; doulb p1[],p2[],p3[],p4[]; { double v[3],o[3],tv[3],len; C_gm_tran3d( 1,mtrx,p4,o); v[0] = p1[0]+p4[0]; v[1] = p1[1]+p4[1]; v[2] = p1[2]+p4[2]; C_gm_tran3d( 1,mtrx,v,tv); tv[0] -= o[0]; tv[1] -= o[1]; tv[2] -= o[2]; len =sqrt(tv[0]*tv[0]+tv[1]*tv[1]+tv[2]*tv[2]); p1[0] = tv[0]/len; p1[1] = tv[1]/len; p1[2] = tv[2]/len; v[0] = p2[0]+p4[0]; v[1] = p2[1]+p4[1]; v[2] = p2[2]+p4[2]; C_gm_tran3d( 1,mtrx,v,tv); tv[0] -= o[0]; tv[1] -= o[1]; tv[2] -= o[2]; len =sqrt(tv[0]*tv[0]+tv[1]*tv[1]+tv[2]*tv[2]); p2[0] = tv[0]/len; p2[1] = tv[1]/len; p2[2] = tv[2]/len; v[0] = p3[0]+p4[0]; v[1] = p3[1]+p4[1]; v[2] = p3[2]+p4[2]; C_gm_tran3d( 1,mtrx,v,tv); tv[0] -= o[0]; tv[1] -= o[1]; tv[2] -= o[2]; len =sqrt(tv[0]*tv[0]+tv[1]*tv[1]+tv[2]*tv[2]); p3[0] = tv[0]/len; p3[1] = tv[1]/len; p3[2] = tv[2]/len; C_ut_dpsto ( 3,o,p4); return 0; } short C_trmxlc( mtrx,p1,p2,p3,p4) double mtrx[]; double p1[],p2[],p3[],p4[]; { double v[3],tv[3],o[3],len; C_gm_tran3d( 2,mtrx,o,p4); v[0] = p1[0]+p4[0]; v[1] = p1[1]+p4[1]; v[2] = p1[2]+p4[2]; C_gm_tran3d( 2,mtrx,v,tv); tv[0] -= o[0]; tv[1] -= o[1]; tv[2] -= o[2]; len =sqrt(tv[0]*tv[0]+tv[1]*tv[1]+tv[2]*tv[2]); p1[0] = tv[0]/len; p1[1] = tv[1]/len; p1[2] = tv[2]/len; v[0] = p2[0]+p4[0]; v[1] = p2[1]+p4[1]; v[2] = p2[2]+p4[2]; C_gm_tran3d( 2,mtrx,v,tv); tv[0] -= o[0]; tv[1] -= o[1]; tv[2] -= o[2]; len =sqrt(tv[0]*tv[0]+tv[1]*tv[1]+tv[2]*tv[2]); p2[0] = tv[0]/len; p2[1] = tv[1]/len; p2[2] = tv[2]/len; v[0] = p3[0]+p4[0]; v[1] = p3[1]+p4[1]; v[2] = p3[2]+p4[2]; C_gm_tran3d( 2,mtrx,tv,v); tv[0] -= o[0]; tv[1] -= o[1]; tv[2] -= o[2]; len =sqrt(tv[0]*tv[0]+tv[1]*tv[1]+tv[2]*tv[2]); p3[0] = tv[0]/len; p3[1] = tv[1]/len; p3[2] = tv[2]/len; C_ut_dpsto ( 3,o,p4); return 0; }
【0014】本発明の代替実施例では、立体オブジェク
トのテーパ付き表示を生成することができる。この機能
を実施する論理を、図3に示す。機能ブロック300に
示された最初のステップは、上記の立体生成の場合と同
じである。2次元の図面がロードされる。入力ブロック
310で、ユーザは、立体テーパ・メニュー機能を選択
する。その後入力ブロック320で、前切断面を表す平
面を選択するようユーザに指示が出る。この選択は、輪
郭図以外の線の上にカーソルを合わせることによって行
なう。次に、入力ブロック330で、前切断面の輪郭を
形成する要素を選択するようユーザに指示が出る。ユー
ザは、テーパの輪郭を形成するのに必要な、輪郭図内の
2次元幾何形状を選択する。その後、終了のメニュー項
目を選択して、輪郭処理の完了を示す。
【0015】次に、入力ブロック340で、ユーザは、
後切断面を選択する。入力ブロック350で、ユーザ
は、輪郭図以外の投影図から線を選択して、テーパ操作
用の輪郭を形成する。選択処理が完了すると、終了のメ
ニュー項目を選択する。その後、機能ブロック360
で、2次元の幾何形状が3次元の面に変換され、機能ブ
ロック370で、立体表現が生成される。この処理に
は、2次元幾何形状から3次元幾何形状への変換と、そ
れに対応する上記データ構造の変換が含まれる。最後
に、出力ブロック380で、立体が表示される。下記の
データ構造は、後で表示するために立体オブジェクトを
記憶するのに使用される。 /********************************************* * * * HEADER FILE FOR MICRO CADAM WRITTEN C LANGUAGE * * * ********************************************** * * * HEADER FILE NAME: PARAM.H * * * ********************************************** * * * IDENTIFICATION: * * * * AUTHOR ..... Frank Niu * * DATE ..... 10/15/89 * * * * MODIFIED ..... Allen Chen * * DATE ..... 4/16/90 * * NATURE ..... Add Spline * * * * MODIFIED ..... * * DATE ..... * * NATURE ..... * * * * * ********************************************** * * * NOTE ON USE: * * * ********************************************** #define SSIZE 20 #define LSIZE 400 #define ESIZE 600 #define VSIZE 600 #define BSIZE 50 #define CHLDSZ 100 #define SD_LINE 1 #define SD_CIRCLE 2 #define SD_SPLINE 4 #define F0 0.4142136 #define F1 0.5857864 struct LOOP_LIST { short EdgeIndex; struct LOOP_LIST *back,*next; struct LOOP_LIST *link; short used; }; struct VertexTable { short f1,f2,f3; double x,y,z; }; struct LINE { short StartVertex; short EndVertex; }; struct CIRCLE { short fid; short StartVertex; short EndVertex; double A1,A2; struct POINT *Vertics[13]; }; struct SPLINE { short fid; /* face number */ short StartVertex; short EndVertex; struct BSPLINE Bspl; }; struct EdgeTable { short LeftLoop; short RightLoop; short EdgeType; struct LINE *Line; struct CIRCLE *Circle; struct SPLINE *Spline; }; struct LoopTable { short FaceIndex; short NumberEdges; struct LOOP_LIST *ListHead; struct LOOP_LIST *ListPtr; short DividingLoopEdge; struct LoopTable *Ploop; struct LoopTable *Cloop; }; struct SolidTable { char name[40]; short NumberLoops; short NumberEdges; short NumberVertics; struct LoopTable *LoopTable [LSIZE]; struct EdgeTable *EdgeTable [ESIZE]; struct VertexTable *VertexTable[VSIZE]; }; /**********************************************************************/ /* */ /* hole.h */ /* */ /**********************************************************************/ struct POLYNODE { float x,y,z; short Show_Edge; struct POLYNODE *next, *back; }; struct POLYGON_AND_BOX { struct POLYNODE *header, *ptr; float Xmin,Xmax,Ymin,Ymax,Zmin,Zmax; }; struct POLYGONS { struct POLYGON_AND_BOX *Parent; short NumberChildren; struct POLYGON_AND_BOX *Children[CHLDSZ]; }; struct INTERSECTION { struct POLYNODE *NodePtr; short PolyIndex; };
【0016】図4ないし図8に、本発明を使用した立体
生成の例が示されている。図4で、2次元オブジェクト
の正面図と側面図が、400および410で提示され
る。2つの2次元投影図の立体表現を生成するため、ユ
ーザは、まず420で、前面での押出し用の輪郭として
4本の線を選択する。次に430で、側面図から後面を
選択し、最後に440で、後面の4本の線を選択して、
輪郭を形成する。この情報は、450で3次元立体オブ
ジェクトの生成に使用される。
【0017】図5は、押出しのもう1つの例である。ま
ず500で、3本の線と1本の円弧が、押出し用の輪郭
として選択される。その後、510で、側面図から2本
の線を選択して、操作を完了する。その後、520で、
立体オブジェクトが生成される。
【0018】図6は、立体生成のもう1つの例である。
600で、やはりまず2つの2次元図面が最初にロード
され、表示される。その後、610で、一方の2次元図
面の前面が選択される。次に620で、この前面の輪郭
が選択される。次に630で、後面が選択される。最後
に640で、後面の輪郭が選択され、図7の650で、
3次元立体が生成される。
【0019】図8は、円の押出しを示す図である。80
0で、まずオブジェクトの2つの投影図が描画される。
その後、810で、前面が選択される。次に820で、
前面の輪郭が選択される。最後に830で、後面が選択
され、840で、後面の輪郭も選択される。850で、
その結果得られた立体が表示される。
【0020】パラメータ・エンティティ図9には、立体
機能のパラメータ修正メニューのオプションがリストさ
れ、それらの機能が詳述されている。100に、メニュ
ー・オプションが、CAD表示装置に表示される状態で
示されている。ユーザが1100のDefParent
(親の定義)を選択した場合、ある立体の、親平面とし
て機能する平面を指すようユーザに指示が出る。この平
面は、その間隔がユーザが変更しようとする変数であ
る、平行なオフセット平面と対にならなければならな
い。
【0021】1120に、Define Offset
(オフセットの定義)メニュー・オプションがリストさ
れている。このオプションを用いて、ユーザは、立体の
親平面に平行な平面をオフセット平面として定義するこ
とができる。1130に、Change Parame
ter(パラメータの変更)メニュー・オプションが示
されている。この項目を選択すると、親平面とオフセッ
ト平面の間隔の値が表示される。1140に、Show
All(すべて表示)メニュー・オプションが示され
ている。このオプションを選択すると、その立体オブジ
ェクトの現在表示されていない全ての平面が表示され
る。1150は、No Show(表示しない)オプシ
ョンである。これは、現立体の選択された平面の表示を
一時的に抑制して、隠れた平面を選択できるようにする
オプションである。
【0022】パラメータ設計を開始するため、図11の
機能ブロック1300で、ユーザは、図10の1200
に示すような、表示画面から立体オブジェクトを1つ選
択する。任意選択として、図11の機能ブロック131
0で、ユーザはNo Show機能を使用して、立体オ
ブジェクトからいくつかの面を取り除くことができる。
その後、機能ブロック1320で、ユーザは、図10の
1290に示すような、その立体の多角形を1つ選択す
ることによって、親面を定義する。次に、機能ブロック
1330で、図10の1270および1250に示すよ
うな、最初の面に平行なオフセット面群を選択する。オ
フセット面群の間隔1252と、親面と第1のオフセッ
ト面の間隔1254が計算される。間隔D1 1254
は、後で調節される可変間隔である。一方、間隔D2
1252は、この操作の間一定に保たれる固定間隔であ
る。
【0023】ユーザがNo Show機能を選択する場
合には、図12に記載の論理が使用されて、その面がデ
ィスプレイ上で見えなくなる。機能ブロック1410
で、ユーザは、まずある立体の多角形(面)を1つ選択
し、そのポインタをループ識別子に変換する。その後、
PFaceテーブルを探索してこのループを含む面を探
すことによって、この面を検証する。判断ブロック14
20でこの面が見つかった場合、選択された多角形は、
有効な面である。そうでない場合、制御はブロック14
10に移る。この面が有効である場合、ブロック143
0で、システムは、選択された多角形の属性を「可視性
オフ」にセットする。
【0024】親面を定義するための論理を図13に示
す。上記と同様に、機能ブロック1510で、ユーザ
は、まず立体オブジェクトの多角形を1つ選択する。そ
の後、機能ブロック1520で、システムはPFace
テーブルを探索して、そのループを含む面を識別する。
判断ブロック1530で面が識別されている場合には、
機能ブロック1540で、その面識別子が親面識別子と
してセットされる。しかし、面識別子が見つからない場
合には、機能ブロック1550で、親面識別子が0値
(NULL)にセットされる。
【0025】オフセット面を定義するための論理を図1
4に示す。機能ブロック1610で、ユーザは、まず立
体オブジェクトの多角形を1つ選択しなければならな
い。その後、機能ブロック1620で、PFaceテー
ブルを探索して、選択された多角形の含む面識別子を探
す。次に、探索を行なってその面のタイプを決定163
0し、そのタイプに基づいて、機能ブロック1640ま
たは1660のどちらかに制御が渡される。その面のタ
イプが「通常」であれば、制御は機能ブロック1660
に渡され、そこで親面とオフセット面の間隔が計算さ
れ、パラメータ・テーブルに変更を反映するエントリが
作成される。最後に、面のタイプもオフセット面に変更
される。面のタイプが既にオフセット面である場合に
は、機能ブロック1640で無効な多角形が選択された
ので、制御をエラー・ルーチンに渡す。オフセット面
を、別のオフセット面の親面として再定義して、入れ子
関係を形成することができる。
【0026】図15は、Change Paramet
er機能を実施する論理を示す図である。最初のステッ
プである機能ブロック1700で、図形表示装置に表示
された立体から多角形を1つ選択する。次に、機能ブロ
ック1710で、システムは、PFaceテーブルを探
索して、選択された多角形に関連する面識別子を探す。
続いて、判断ブロック1720で、この面識別子を使用
して面のタイプを決定する。面のタイプが「通常」の面
である場合は、機能ブロック1730で、その多角形が
表示装置上で強調表示され、原点からその面までの距離
が表示され、制御が機能ブロック1760に渡される。
しかし、面のタイプがオフセット面である場合は、機能
ブロック1740で、PFaceテーブルを探索して、
親面と関連する多角形の識別子を捜す。その後、機能ブ
ロック1750で、2つのオフセット面の間隔が計算さ
れ、表示され、これらの多角形が強調表示される。
【0027】次のステップである機能ブロック1760
で、キーボードから新しい間隔の値を入力するようユー
ザに指示が出る。この新しい値を使用して、パラメータ
・テーブルが更新される。多角形がオフセット・タイプ
である場合には、選択された面のパラメータが修正され
る。通常の面である場合には、通常の面のパラメータが
修正される。その後、機能ブロック1770で、PFa
ceテーブルがFace Tableに変換される。最
後に、機能ブロック1780で、このFaceTabl
eと構造リストを立体モデラに送って修正された立体を
生成することによって、この立体が再生成される。
【0028】図10は、本発明によるパラメータ・エン
ティティ機能を使用して、第1の立体1200と第2の
立体1210を修正して、完成アセンブリ1220を生
成する様子を示す図である。アセンブリを正しく完成す
るには、立体1200内の間隔D1 1254を、間隔
D3 1256と相関させなければならない。したがっ
て、ユーザはまず、P1 1290からO1 1270
までの可変間隔としてD1 1254を選択する。間隔
D2は固定間隔として定義され、前記の可変間隔はD3
1256と等しくされる。その後、システムは、D3
1256に合うようにD1 1221を拡大し、アセ
ンブリを完成させる。
【0029】面法線の表示 通常のCADシステムでは、向きとは無関係に表面を生
成できる。しかし、1つの表面には2つの面があり、そ
の表面の複合オブジェクト内での位置または配向に応じ
て、その一方は内向き、もう一方は外向きである。表面
法線は、ある表面の向きを示す基準である。これは、陰
影値を計算するためのベクトルでもある。表面法線は表
面の生成中には指定されないので、陰影をつけた表面の
像が正しく見えないことがある。
【0030】本発明を使用した処理の論理を、図16お
よび17に示す。図18は、本発明の論理の一部を実施
するのに使用される数式に含まれる変数を示す図であ
る。最後に、この論理を実施するのに使用されるソース
・コードとデータ構造の詳細を以下に提示し、説明す
る。
【0031】図16の機能ブロック1800は、ユーザ
が陰影付けを指定していない表面に陰影をつけて表示す
る最初のステップである。表面に陰影をつけるため、シ
ステムは、その表面を近似する多角形群を生成する。各
多角形を、その多角形の各頂点での表面の法線に従って
陰影をつけることによって、陰影のついた表面が適切に
示される。
【0032】多角形に陰影をつけるため、システムは、
陰影用の色テーブルを用意し、その多角形の各頂点の強
度を計算する。色テーブルを作成するためのアルゴリズ
ムを、下記の“C”リストに示す。この論理には2つの
ステップがある。ステップ1:赤、緑、青(RGB)の
色値を別々に線形補間して、指定された周囲光値からオ
ブジェクトの完全な色まで一定の値で増分された、3つ
のテーブル(RGB)を生成する。現在の表示装置で生
成される陰影の色は、200段階ある。
【0033】ステップ2: このアルゴリズムは、ステ
ップ1の結果に対して余弦関数を使用して、陰影色の範
囲を拡張する。最終的な色テーブルは、指定された周囲
光の値から、表面上の光源の反射光が目に入った時に陰
影をつけたオブジェクトに輝く点を与える、明るく輝く
色までの範囲に及ぶ。 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Function name : Build_xxxxxx_Color_Map () * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Category : COLOR MAP MANAGEMENT * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Description : Three major routines set up the color map * * for three shading modes. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Input : * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Output : - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Input/Output : - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Function returns: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Identification : * * AUTHOR ....... Chris Chen * * DATE ...... 04/12/90 * * * * MODIFIED BY ...... Allen Chen * * DATE ...... 04/27/90 * * NATURE (#1) ...... modify cal_indices * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Calls : - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Called by : - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Algorithm : Color map has been devided into three * * different sections, CADAM MAP, USERS MAP, * * and SHADE MAP. Their sizes are defined * * in file "shade.h". * * CADAM MAP contains the RGB values of 16 * * CADAM colors. * * * * USERS MAP stores the RGB values of those * * colors used by button, window, icon, and * * text. Currently, 16 entries are allocated * * for USERS MAP. * * * * SHADE MAP includes 216 entries which are * * the shading colors for surface display. * * * * In Dither shading mode, 216 "fixed colors" * * are reserved for HOOPS standard shading. * * * * In Constant shading mode, 216 colors are * * separated into 12 sections for the default * * color and 11 CADAM object colors. Each * * section contains 18 shade levels of the * * standard colors. * * * * In Smooth shading mode, all colors are * * the different shade level of the selected * * shading color (first entry of USERS MAP). * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Glossary : - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Notes on use : Normally, two colors are reserved for the * * display of mouse cursor, so the total * * number of the available cor is 254. * * These colors can be classified into three * * catagories: * * * * The "regular color" is generated by the * * use of Set_Color_By_Value routines. Each * * color of different RGB value occupy one * * entry on the hardware color lookup table, * * and their value can not be changed or * * delete by any HOOPS routine. * * * * The "fixed color" is used by the HOOPS to * * generate the dither shading. * * * * The "map color" is stored in the virtual * * color map of each segment. Its RGB value * * can be changed by the programmer. * * * * Due to the arrangement of the color map, * * there is only one shading mode can exist * * at any time. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <stdio.h> #include <math.h> #include "constd.h" #include "color.h" #include "shade.h" "include "mltwdw.h" /*---------------------------------------------------------------*/ /* */ /* RGB color value for 64 EGA emulation colors */ /* */ /*---------------------------------------------------------------*/ short color_table[64][3]= { {0,0,0},{0,0,66},{0,66,0},{0,66,66},{66,0,0},{66,0,66},{66,66,0}, {66,66,66,},{0,0,33},{0,0,99},{0,66,33},{0,66,99},{66,0,33},{66,0,99}, {66,66,33},{66,66,99},{0,33,0},{0,33,66},{0,99,0},{0,99,66},{66,33,0}, {66,33,66},{66,99,0},{66,99,66},{0,33,33},{0,33,99},{0,99,33},{0,99,99} , {66,33,33},{66,33,99},{66,99,33},{66,99,99},{33,0,0},{33,0,66},{33,66,0 }, {33,66,66},{99,0,0},{99,0,66},{99,66,0},{99,66,66},{33,0,33},{33,0,99}, {33,66,33},{33,66,99},{99,0,33},{99,0,99},{99,66,33},{99,66,99}, {33,33,0},{33,33,66},{33,99,0},{33,99,66},{99,33,0},{99,33,66}, {99,99,0},{99,99,66},{33,33,33},{33,33,99},{33,99,33},{33,99,99}, {99,33,33},{99,33,99},{99,99,33},{99,99,99} }; RGB Color_Map[COLOR_MAP_SIZE]; void MC_Build_Color_ Map (); void Show_Color_By_RGB (short index, short *R, short *G, short *B); void Show_Color_By_Value (short index, short *value); void Set_Color_By_RGB (short index, short R, short G, short B); void Set_Color_By_Value (short index, short value); static void Build_Normal_Color_Map (); static void Build_Dither_Color_Map (); static void Build_Constant_Color_Map (); static void Build_Gouraud_Color_Map (); static void Set_Cadam_Color_Map (); static void Set_Users_Color_Map (); /*---------------------------------------------------------------*/ /* */ /* Initialize_Color_Map : Initialize color map. */ /* */ /*---------------------------------------------------------------*/ void Initialize_Color_Map (short level) { switch (level) { case 0: COLOR.clmod = 0; /* Modal color number */ COLOR.clcur = 1; /* Current color number on side bar */ case 1: COLOR.clmct[0] = 63; COLOR.clmct[1] = 26; COLOR.clmct[2] = 63; COLOR.clmct[3] = 0; COLOR.clmct[4] = 0; COLOR.clmct[5] = 18; COLOR.clmct[6] = 27; COLOR.clmct[7] = 36; COLOR.clmct[8] = 54; COLOR.clmct[9] = 37; COLOR.clmct[10] = 26; COLOR.clmct[11] = 60; COLOR.clmct[12] = 52; COLOR.clmct[13] = 25; COLOR.clmct[14] = 9; COLOR.clmct[15] = 40; case 2: COLOR.cldef[0] = COLOR.clmct[0]; /* DEFAULT COLOR */ COLOR.cldef[1] = 0; COLOR.clbrt[0] = COLOR.clmct[1]; /* BRIGHT COLOR */ COLOR.clbrt[1] = 1; COLOR.clcsr[0] = COLOR.clmct[2]; /* CURSOR COLOR */ COLOR.clcsr[1] = 2; COLOR.clblk[0] = COLOR.clmct[3]; /* MESSAGE BACKGROUND */ COLOR.clblk[1] = 3; COLOR.clbgr[0] = COLOR.clmct[4]; /* MODEL BACKGROUND */ COLOR.clbgr[1] = 4; COLOR.clshd = 57; /* SHADING COLOR */ } Set_Cadam_Color_Map (); Set_Users_Color_Map (); MC_Build_Color_Map (); } /*---------------------------------------------------------------*/ /* */ /* Show_Color_By_RGB: Inquire color RGB value of a color index. */ /* */ /*---------------------------------------------------------------*/ void Show_Color_By_RGB (short index, short *R, short *G, short *B) { *R = color_table[COLOR.clmct[index]][0]; *G = color_table[COLOR.clmct[index]][1]; *B = color_table[COLOR.clmct[index]][2]; } /*---------------------------------------------------------------*/ /* */ /* Show_Color_By_Value: Inquire color value of a color index. */ /* */ /*---------------------------------------------------------------*/ void Show_Color_By_Value (short index, short *value) { if(index == 16) *value = COLOR.clshd; else *value = COLOR.clmct[index]; } /*---------------------------------------------------------------*/ /* */ /* Set_Color_By_RGB: Modify color RGB value of a color index. */ /* */ /*---------------------------------------------------------------*/ void Set_Color_By_RGB (short index, short R, short G, short B) { color_table[COLOR.clmct[index]][0] = R; color_table[COLOR.clmct[index]][1] = G; color_table[COLOR.clmct[index]][2] = B; } /*---------------------------------------------------------------*/ /* */ /* Set_Color_By_Value: Modify color value of a color index. */ /* */ /*---------------------------------------------------------------*/ void Set_Color_By_Value (short index, short value) { if(index == 16) COLOR.clshd = value; else COLOR.clmct[index] = value; Color_Map[CADAM_MAP0+index].R = color_table[value][0]/99.0; Color_Map[CADAM_MAP0+index].G = color_table[value][1]/99.0; Color_Map[CADAM_MAP0+index].B = color_table[value][2]/99.0; HC_QModify_Color_Map_By_Value("?picture",(int)index,"RGB", (int)1, &Color_Map[index].R); switch(SHADE.mode) { case -1: break; case 0: break; case 1: break; case 2: if(index > 4) Build_Constant_Color_Map (); break; case 3: if(index == 16)Build_Gouraud_Color_Map (); break; default: /* do nothing */; } } /*---------------------------------------------------------------*/ /* */ /* MC_Build_Color_Map (): Build color map for any shading condition*/ /* */ /*---------------------------------------------------------------*/ void MC_Build_Color_Map () { switch (SHADE.mode) { case -1: case 0: Build_Normal_Color_Map (); break; case 1: Build_Dither_Color_Map (); break; case 2: Build_Constant_Color_Map (); break; case 3: Build_Gouraud_Color_Map (); break; default: /* do nothing */; } } /*---------------------------------------------------------------*/ /* */ /* Build_Normal_Color_Map : Set up normal wireframe color map. */ /* */ /*---------------------------------------------------------------*/ static void Build_Normal_Color_Map () { if(COLOR.cldpf <= 16) { HC_Open_Segment("?picture"); HC_UnSet_Color_Map (); HC_Set_Driver_Options ("fixed colors = 0"); HC_Set_Color_Map_By_Value("RGB", CADAM_MAP_SIZE, Color_Map); HC_Close_Segment(); } else { HC_Open_Segment("?picture"); HC_UnSet_Color_Map (); HC_Set_Color_Map_By_Value("RGB", BASIC_MAP_SIZE, Color_Map); #ifdef NTH HC_Set_Driver_Options ("fixed colors = 125"); #else HC_Set_Driver_Options ("fixed colors = 216"); #endif HC_Close_Segment(); } } /*---------------------------------------------------------------*/ /* */ /* Build_Dither_Color_Map: Set up dither shading mode color map. */ /* */ /*---------------------------------------------------------------*/ static void Build_Dither_Color_Map () { if(COLOR.cldpf <= 16) { HC_Open_Segment("?picture"); HC_UnSet_Color_Map (); HC_Set_Color_Map_By_Value("RGB", COLOR.cldpf-8, Color_Map); HC_Set_Driver_Options ("fixed colors = 8"); HC_Close_Segment(); } else { HC_Open_Segment("?picture"); HC_UnSet_Color_Map (); HC_Set_Color_Map_By_Value("RGB", BASIC_MAP_SIZE, Color_Map); #ifdef NTH HC_Set_Driver_Options ("fixed colors = 125"); #else HC_Set_Driver_Options ("fixed color = 216"); #endif HC_Close_Segment(); } } /*---------------------------------------------------------------*/ /* */ /* Build_Constant_Color_Map: Set up constant shading color map. */ /* */ /*---------------------------------------------------------------*/ static void Build_Constant_Color_Map () { short i, j, k, lstart, index; float x; if(COLOR.cldpf <= 16) return; /* .................................. :by A. Chen : :MAXLEV: The maximum number of gray level. : This value is defined in file "shade.h" :LEVEL : number of gray levels to be used for fine shading :................................... */ /* Calculate gray level for default & 11 CADAM colors */ lstart = MAXLEV - LEVEL; for(i = 0; i<= 11; i++) { if(i == 0) index = COLOR.cldef[0]; else index = COLOR.clmct[i+4]; for(j = SHADE_MAP0 + i*LEVEL, k = 0; k < LEVEL; j++, k++) { x = 0.01 * (lstart + k)/MAXLEV; Color_Map[j].R = color_table[index][0] * x; Color_Map[j].G = color_table[index][1] * x; Color_Map[j].B = color_table[index][2] * x; } } HC_Open_Segment("?picture"); HC_UnSet_Color_Map (); HC_Set_Driver_Options ("fixed colors = 0"); HC_Set_Color_Map_By_Value("RGB", COLOR_MAP_SIZE, Color_Map); HC_Close_Segment(); } /*---------------------------------------------------------------*/ /* */ /* Build_Gouraud_Color_Map: Set up Gouraud shading mode color map. */ /* */ /*---------------------------------------------------------------*/ static void Build_Gouraud_Color_Map () { short i; RGB Camb, M; float pai, Rstep, Gstep, Bstep; float cosa[GOURAUD_COLOR_SIZE]; float PI = 3.1415926; float range; float amb; if(COLOR.cldpf <= 16) return; /*............................. :Allen Chen,4/25/90 :amb: ambient factor will be referenced as a :global variable which can be defined by users. :The factor makes the range of gouraud color map :run between amb and 1.0. It discards the colors :under amb and gives more gray leves to visible :range. :if amb is defined as global variable then the :color map will range from amb to somewhere close :to 1.0. Thus, the routine calculate_indices() :shall be rewritten to produce correct indices. :For now, the value of amb is set to 0.0. :................................ */ amb = 0.0; range = (float)((GOURAUD_COLOR_SIZE - 1) * (short)100); pai = (float)(PI_D / (double)((short)GOURAUD_COLOR_SIZE * (short)2)); for (i= 0; i <GOURAUD_COLOR_SIZE;i++) cosa[GOURAUD_COLOR_SZE-1-i]= pow(cos(i*pai), 5); /*........................ :Allen Chen, 4/25/90 :find ambient color of RGB. :RGB step is adjusted by ambient color :.......................... */ Camb.R = color_table[COLOR.clshd][0] * amb; Camb.G = color_table[COLOR.clshd][1] * amb; Camb.B = color_table[COLOR.clshd][2] * amb; Rstep = (color_table[COLOR.clshd][0] - Camb.R)/range; Gstep = (color_table[COLOR.clshd][1] - Camb.G)/range; Bstep = (color_table[COLOR.clshd][2] - Camb.B)/range; for(i = 0;i < GOURAUD_COLOR_SIZE; i++) { M.R = i *Rstep + Camb.R; M.G = i *Gstep + Camb.G; M.B = i *Bstep + Camb.B; Color_Map[SHADE_MAP0 + i].R = M.R+(1-M.R) * cosa[i] * 0.5; Color_Map[SHADE_MAP0 + i].G = M.G+(1-M.G) * cosa[i] * 0.5; Color_Map[SHADE_MAP0 + i].B = M.B+(1-M.B) * cosa[i] * 0.5; #ifdef DEBUG printf("colormap[%d]=(%lf,%lf,%lf)\n",COLOR_MAP_SIZE-1-i, Color_Map[SHADE_MAP0 + i].R, Color_Map[SHADE_MAP0 + i].G, Color_Map[SHADE_MAP0 + i].B); #endif } HC_Open_Segment ("?picture"); HC_UnSet_Color_Map (); HC_Set_Driver_Options ("fixed colors = 0"); HC_Set_Color_Map_By_Value("RGB", COLOR_MAP_SIZE, Color_Map); HC_Close_Segment(); } /*---------------------------------------------------------------*/ /* */ /* Set_Cadam_Color_Map: Set sixteen CADAM basic color map. */ /* */ /*---------------------------------------------------------------*/ static void Set_Cadam_Color_Map () { short i; for (i = 0, i < CADAM_MAP_SIZE; i++) { Color_Map[CADAM_MAP0 + i].R = color_table[COLOR.clmct[i]][0]/99.0; Color_Map[CADAM_MAP0 + i].G = color_table[COLOR.clmct[i]][1]/99.0; Color_Map[CADAM_MAP0 + i].B = color_table[COLOR.clmct[i]][2]/99.0; } } /*---------------------------------------------------------------*/ /* */ /* Set_Users_Color_Map: Set user shading color map. */ /* */ /*---------------------------------------------------------------*/ static void Set_Users_Color_Map () { short i; float gray; RGB white, brite; Color_Map[USERS_MAP0].R = color_table[COLOR.clshd][0]/99.0; Color_Map[USERS_MAP0].G = color_table[COLOR.clshd][1]/99.0; Color_Map[USERS_MAP0].B = color_table[COLOR.clshd][2]/99.0; /* set 5 gray shades */ white.R = 0.75; white.G = 1.0; white.B = 1.0; brite.R = color_table[COLOR.clbrt[0]][0]/99.0; brite.G = color_table[COLOR.clbrt[0]][1]/99.0; brite.B = color_table[COLOR.clbrt[0]][2]/99.0; for (i = 1,i< = 5; i++) { switch (i) { case 1: gray = 0.125; break; case 2: gray = 0.195; break; case 3: gray = 0.306; break; case 4: gray = 0.479; break; case 5: gray = 0.75; } Color_Map[USERS_MAP0+i].R = white.R * gray; Color_Map[USERS_MAP0+i].G = white.G * gray; Color_Map[USERS_MAP0+i].B = white.B * gray; Color_Map[USERS_MAP0+5+i].R = brite.R * gray; Color_Map[USERS_MAP0+5+i].G = brite.G * gray; Color_Map[USERS_MAP0+5+i].B = brite.B * gray; } for (i = USERS_MAP0+11 ; i < USERS_MAP_SIZE; i++) { Color_Map[USERS_MAP0+i].R = 1.0; Color_Map[USERS_MAP0+i].G = 1.0; Color_Map[USERS_MAP0+i].B = 1.0; } }
【0034】多角形に陰影をつけるには、各頂点の照度
の値を計算しなければならない。照度(I)は、次式を
用いて計算される。 I = Amb * Ka + Lv * Kd * (L×N) + Ks * (R×V)m 図18を参照すると、Ambは、周囲光の値である。K
aは、オブジェクトの表面から反射される周囲光の量を
表す。Lvは、光源の強さである。L2400は、光の
ベクトルである。N2410は、その頂点での表面の法
線である。(L×N)2440は、ベクトルLとベクト
ルNの間の角度の余弦の値である。Kdは、表面から反
射される拡散光の量を表す。R2420は、反射ベクト
ルである。V2430は、頂点から視点に向かうベクト
ルである。(R×V)2460は、ベクトルRとベクト
ルVの間の角度の余弦の値である。
【0035】照度の値は、周囲光、拡散光および鏡面光
沢の各係数の和なので、その結果が許容範囲に納まらな
いことがある。特に、複数の光源があり、図形ハードウ
ェアの解像度が限られている時にはそうである。したが
って、元の式に下記の修正を加えて、陰影機能を改善す
る。 I = Max(I[1], I[2], I[3],... I[n]) I[i] = A+(1−A) * D[i] + (1−A−(1−A)*D[i])* S[i] ただし、n個の光源の場合、i = 1,2,..nで
ある。I[i]は、i番目の光源の照度である。A=a
mb*Ka、D[i]=Lv[i]*(L[i]×
N)、S[i]=(R×V)mである。
【0036】多角形の各頂点の強度が解けると、その強
度が色テーブルの指標に変換される。(下記のデータ構
造を参照されたい) /*********************************************************************** * * * Calculate Indices * * * *--------------------------------------------------------------------* * * * The routine returns the index to the color map for the given Normal * * and my_lights[4]. * * * * eye vector: come form window matrix (zvector) * * light vector: was transformed form world system to window system * (active) * * * * * * * *--------------------------------------------------------------------* * Author : Allen Chen * * * * * * * /*********************************************************************** */ void calculate_indices( Normal, my_lights, index ) double Normal[]; VECTOR my_lights[4]; short *index; { VECTOR eye, refraction, norm; float amb, difus; float t1,t2,coso,cosa,cosr,ta; float max_color; short light_num; float range /*................................ :................................ */ range = (float)(GOURAUD_COLOR_SIZE - 1); amb = 0.1; difus = 0.5; eye.x = WDW3D.wzvec[0]; eye.y = WDW3D.wzvec[1]; eye.z = WDW3D.wzvec[2]; norm.x = (float)Normal[0]; norm.y = (float)Normal[1]; norm.z = (float)Normal[2]; dot_vectors ( & cosr, eye,norm ); if(cosr <= 1.e-3) cosr = 0.0; max_color= 0.0; for ( light_num=0; light_num< 4; light_num++) { if( SHADE.light[light_num ==ON ) { coso = my_lights[light_num].x*norm.x + my_lights[light_num].y*norm.y + my_lights[light_num].z*norm.z; if((coso <= 0.0 ||(coso > 1.0)) coso = 0.0; refraction.x = -my_lights[light_num].x + 2*coso * norm.x; refraction.y = -my_lights[light_num].y + 2*coso * norm.y; refraction.z = -my_lights[light_num].z + 2*coso * norm.z; t1 = sqrt ( refraction.x * refraction.x + refraction.y * refraction.y + refraction.z * refraction.z); refraction.x /= t1; refraction.y /= t1; refraction.z /= t1; dot_vectors ( &cosa, refraction, eye ); if((coso > 0.0 )&&(cosa > 0.0)&&(cosr > 0.0)) { ta = cosa * cosa; cosa = ta*ta*cosa; } else { cosa = 0.0; } t1 = amb + coso * ( 1.0 - amb ) *difus;/*ambient + diffuse*/ t2 = t1 + ( 1.0 - t1 ) *cosa; /*complement factor */ } else t2 = amb; if( t2 > max_color )max_color = t2; } *index = (short)SHADE_MAP0 + (short)(max_color * range +(float)0.5); } その後、機能ブロック1810で、表示したい特定の表
面を選択するようユーザに指示が出る。面は、カーソル
で指示し、ポインタの座標を使ってCADAMデータ・
ベースから適当な表面を選択することによって選択され
る。次に、機能ブロック1820で、選択した表面が消
去される。その後、機能ブロック1830で、表面デー
タが再配置される。
【0037】4種類の表面データ、すなわち、線織面、
回転面、境界面およびスキン面が再配置できる。これら
の表面のデータ構造を以下に示す。 /*................................ :Allen Chen 8/23/90 : :The files include this header : ----------------------------- */ #ifndef BSPLINE_H_FILE #define BSPLINE_H_FILE #defineMAXSplineKnots 50 #define MAXKnots 56 #define MAXControlPoints 52 #difine GLOBAL_TO_LOCAL 1 #define LOCAL_TO_GLOBAL 2 struct BSPLINE { /*............................. :A. Chen : :Attributes : Bclosed 0/open 1/closed : Bperiodic 0/nonperiodic 1/periodic : Brational 0/nonrational 1/rational : Bplanar 0/nonplanar 1/planar : :Data : Order : order of the B spline : Nknots : the number of knots in the array KnotSequence[] : Ncp : the number of control points in ControlPoints[] : Start : starting knot sequence of the curve (relimit data) : End : ending knot sequence of the curve (relimit data) :............................... */ short Bclosed; short Bperiodic; short Brational; short Bplanar; short Order; short Nknots; short Ncp; double Start, End; double KnotSequence [MAXKnots]; struct POINT *ControlPoints [MAXControlPoints]; }; struct SURFACE { short Udisp, Wdisp; short BUclosed, BWclosed; short BUperiodic, BWperiodic; short BUrational, BWrational; short Uorder, Worder; short NknotsU, NknotsW; double KnotSequenceU[MAXKnots],KnotSequenceW[MAXKnots]; struct POINT *ControlPoints[MAXControlPoints][MAXControlPoints]; }; struct RULEDSURFACE { short Udisp, Wdisp; struct BSPLINE B_Spline1, B_Spline2; }; struct ROTATIONAL_SURFACE { double A[3],B[3],C[3],Origin[3]; double A1,A2; short Udisp, Wdisp; struct BSPLINE *B_Spline; }; struct EDGE_SURFACE { short Udisp, Wdisp; struct BSPLINE B_Spline[4]; }; #endif
【0038】線織面または回転面の場合、制御点の順序
を逆にし、そのスプラインのノット・シーケンスを計算
する。境界面の場合、スプライン1および2の制御点の
順序を逆にし、そのノット・シーケンスを再計算する。
スプライン3と4を交換する。スキン面の場合、各輪郭
スプラインの対応する制御点を逆にし、ノット・シーケ
ンスを再計算する。図17は、機能ブロック1830お
よび1840に示された論理の詳細を示す図である。
【0039】最後に、機能ブロック1840で、選択さ
れた表面が、再配置された情報に基づいて陰影をつけら
れる。
【0040】境界面 前述したように、境界面は、その表面の閉じた境界を形
成する4つのスプラインを記憶している。この表面法線
処理の論理を以下に示す。 short C_sf_rnormbsf(ptr) short ptr[]; { short ret; short i,j; short w2,w,j2; double tx,ty,tz; struct SURFACE*SkinSurface; SkinSurface = (struct SURFACE*) malloc(sizeof(struct SURFACE)); if(SkinSurface == 0) return 200; ret = ssr_GetSurfaceData( ptr,SkinSurface ); if( ret == 0) { w = SkinSurface->NknotsW-4; w2 = w/2; for( i=0; i<SkinSurface->NknotsU-4;i++) for( j=0;j<w2;j++ ) { j2 = w-j-1; tx = SkinSurface->ControlPoints[i][j]->x; ty = SkinSurface->ControlPoints[i][j]->y; tz = SkinSurface->ControlPoints[i][j]->z; SkinSurface->ControlPoints[i][j]->x = SkinSurface-> controlPoints[i][j2]->x; SkinSurface->ControlPoints[i][j]->y = SkinSurface-> ControlPoints[i][j2]->y; SkinSurface->ControlPoints[i][j]->z = SkinSurface-> ControlPoints[i][j2]->z; SkinSurface->ControlPoints[i][j2]->x = tx; SkinSurface->ControlPoints[i][j2]->y = ty; SkinSurface->ControlPoints[i][j2]->z = tz; } w = SkinSurface->NknotsW; w2 = w/2; tz = SkinSurface->KnotSequenceW[w-1]; for( j=0,j<w2;j++ ) { j2 = w-j-1; tx = SkinSurface->KnotSequenceW[j]; SkinSurface->KnotSequenceW[j] = tz - SkinSurface->KnotSequenceW [j2]; SkinSurface->KnotSequenceW[j2]=tz-tx; } if((w%2) == 1) SkinSurface->KnotSequenceW[w2] = tz - SkinSurface->KnotSequenceW [w2]; C_mi_sfstobsf((short)SF_REPLC,SkinSurface,ptr); free_skincntl(SkinSurface); } free(SkinSurface); return 0; } #under SF_STORE #under SF_REPLC short C_sf_rnormbnd(ptr) short ptr[]; { short ret; struct EDGE_SURFACE*EdgeSurface; EdgeSurface = (struct EDGE_SURFACE *)malloc(sizeof(struct EDGE_ SURFACE)); if(EdgeSurface == 0) return 200; ret = getbdrysf(ptr,EdgeSurface); if(ret == 0) { bsflip(&EdgeSurface->B_Spline[0]); bsflip(&EdgeSurface->B_Spline[1]); ret = swap_bspl(&EdgeSurface->B_Spline[2],&EdgeSurface->B_Spline [3]); if(ret != 0) return ret; ret=C _mi_sfstobnd((short)SF_REPLC,EdgeSurface,ptr ); freeEdgeSurf(EdgeSurface); } free(EdgeSurface); return ret; } #undef SF_STORE #undef SF_REPLC short C_sf_rnormrul(ptr) short ptr[]; { struct RULEDSURFACE *RuledSurface; short ret; RuledSurface = (struct RULEDSURFACE *)malloc(sizeof(struct RULEDSURFACE)); if(RuledSurface == 0) return 200; ret = getrulsf(ptr,RuledSurface); if(ret == 0) { bsflip(&RuledSurface->B_Spline1); bsflip(&RuledSurface->B_Spline2); ret=C_mi_sfstorul((short)1,RuledSurface,ptr); (void)free_CntlPnts(&RuledSurface->B_Spline1); (void)free_CntlPnts(&RuledSurface->B_Spline2); } free(RuledSurface); return ret; } short C_sf_rnormrot(ptr) short ptr[]; { struct ROTATIONAL_SURFACE *rotsrf; short ret; rotsrf = (struct ROTATIONAL_SURFACE *)malloc(sizeof(struct ROTATIONAL_SURFACE)); if(rotsrf == 0) return 200; ret = ssr_GetRotational( ptr,rotsrf ); ir( ret == 0 ) { bsflip(rotsrf->B_Spline); ret = C_mi_sfstorev((short)SF_REPLC,rotsrf,ptr); free_CntlPnts(rotsrf->B_Spline); } free(rotsrf); return ret; }
【0041】特定のシステム環境内の好ましい実施例に
関して本発明を説明してきたが、特許請求の範囲の趣旨
と範囲を逸脱することなく、他の異なるハードウェアお
よびソフトウェア環境において、修正を加えて本発明を
実施できることは、当業者の理解するところである。
【図面の簡単な説明】
【図1】本発明によるコンピュータのブロック図であ
る。
【図2】本発明による立体論理の流れ図である。
【図3】本発明によるテーパ付き立体用の立体論理の流
れ図である。
【図4】本発明による押出し立体の生成に使用されるス
テップを示す図である。
【図5】本発明による押出し立体の生成に使用されるス
テップを示す図である。
【図6】本発明によるテーパ付き立体の生成に使用され
るステップを示す図である。
【図7】本発明によるテーパ付き立体の生成に使用され
る1ステップを示す図である。
【図8】本発明によるテーパ付き立体の生成に使用され
る1組のステップを示す図である。
【図9】本発明によるパラメータ機能メニュー・オプシ
ョンを示す図である。
【図10】本発明によるパラメータ・エンティティの相
関を示す図である。
【図11】本発明による立体オブジェクトの面同士の関
係を定義する論理を示す流れ図である。
【図12】本発明によるNo Show機能の論理を示
す流れ図である。
【図13】本発明による親面の定義を実施する論理を示
す流れ図である。
【図14】本発明によるオフセット面の定義を実施する
論理を示す流れ図である。
【図15】本発明によるChange Paramet
er機能を実施する論理を示す流れ図である。
【図16】本発明による表面法線の陰影付けの論理を示
す流れ図である。
【図17】本発明による表面データ再配置の論理を示す
流れ図である。
【図18】本発明によるディスプレイからの屈折光を示
す図である。
【符号の説明】
10 CPU 20 RAM 30 ディスク 40 ディスケット 50 通信リンク 60 図形表示装置 70 マウス 80 キーボード 82 キーボード・アダプタ 89 プリンタまたはプロッタ

Claims (12)

    【特許請求の範囲】
  1. 【請求項1】(a)図形表示装置上で3次元図面を定義
    する情報を記憶する手段と、 (b)前記情報に基づいて図形表示装置上で図面を生成
    する手段と、 (c)前記図面の1表面を選択する手段と、 (d)前記情報を修正し、前記の選択された表面が前記
    図形表示装置の前景に現れる状態で前記図面を表示する
    手段とを含む、図形表示装置上で3次元図面を修正する
    ための1組の表示操作を実行するための装置。
  2. 【請求項2】さらに、図形表示装置上で3次元面の写実
    的な陰影付けを行なうために3次元図面情報を記憶する
    手段を含む、請求項1の装置。
  3. 【請求項3】さらに、表面のタイプに基づいて前記情報
    を修正するための事前に定義された規則を含む、請求項
    1の装置。
  4. 【請求項4】さらに、前記図形表示装置上の個々の画素
    の照度を修正する手段を含む、請求項1の装置。
  5. 【請求項5】さらに、前記図形表示装置上で前記図面が
    現れる位置を指定する手段を含む、請求項1の装置。
  6. 【請求項6】さらに、前記図面の個々のスプラインのノ
    ード・シーケンスに基づいて前記情報を修正する手段を
    含む、請求項1の装置。
  7. 【請求項7】(a)図形表示装置上で3次元図面を定義
    する情報を記憶するステップと、 (b)前記情報に基づいて図形表示装置上で図面を生成
    するステップと、 (c)前記図面の表面を選択するステップと、 (d)前記情報を修正し、前記の選択された表面が前記
    図形表示装置の前景に現れる状態で前記図面を表示する
    ステップとを含む、図形表示装置上で3次元図面を修正
    するための1組の表示操作を実行するための方法。
  8. 【請求項8】さらに、3次元図面情報をデータ構造に記
    憶するステップを含む、請求項7の方法。
  9. 【請求項9】さらに、表面のタイプに基づいて前記情報
    を修正するための規則を事前に定義するステップを含
    む、請求項7の方法。
  10. 【請求項10】さらに、前記図形表示装置上の個々の画
    素の照度を修正するステップを含む、請求項7の方法。
  11. 【請求項11】さらに、前記図形表示装置上で前記図面
    が現れる位置を指定するステップを含む、請求項7の方
    法。
  12. 【請求項12】さらに、前記図面の個々のスプラインの
    ノード・シーケンスに基づいて前記情報を修正するステ
    ップを含む、請求項7の方法。
JP3328318A 1990-11-26 1991-11-18 立体モデル生成装置および方法 Pending JPH05324774A (ja)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US61770590A 1990-11-26 1990-11-26
US617705 1990-11-26

Publications (1)

Publication Number Publication Date
JPH05324774A true JPH05324774A (ja) 1993-12-07

Family

ID=24474693

Family Applications (1)

Application Number Title Priority Date Filing Date
JP3328318A Pending JPH05324774A (ja) 1990-11-26 1991-11-18 立体モデル生成装置および方法

Country Status (3)

Country Link
EP (1) EP0488578A3 (ja)
JP (1) JPH05324774A (ja)
CA (1) CA2055587A1 (ja)

Families Citing this family (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP3454914B2 (ja) * 1994-04-07 2003-10-06 株式会社ソニー・コンピュータエンタテインメント 画像生成方法および画像生成装置

Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPS638882A (ja) * 1986-06-27 1988-01-14 Sony Corp 陰影表示方法
JPS6324363A (ja) * 1986-07-16 1988-02-01 Honda Motor Co Ltd 形状モデルの変更方法

Family Cites Families (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
FR2574009B1 (fr) * 1984-11-30 1991-02-22 Telemecanique Electrique Systeme pour l'aide a la creation et a l'industrialisation d'objets obtenus par decoupe et deformation a partir de metaux en feuille
US4821214A (en) * 1986-04-17 1989-04-11 Brigham Young University Computer graphics method for changing the shape of a geometric model using free-form deformation

Patent Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPS638882A (ja) * 1986-06-27 1988-01-14 Sony Corp 陰影表示方法
JPS6324363A (ja) * 1986-07-16 1988-02-01 Honda Motor Co Ltd 形状モデルの変更方法

Also Published As

Publication number Publication date
EP0488578A3 (en) 1993-09-22
EP0488578A2 (en) 1992-06-03
CA2055587A1 (en) 1992-05-27

Similar Documents

Publication Publication Date Title
JPH05324776A (ja) 機能強化された立体モデル生成装置
Gallagher et al. Computer visualization: graphics techniques for engineering and scientific analysis
Van Hook Real-time shaded NC milling display
Heckbert Discontinuity meshing for radiosity
Boyse et al. GMSolid: Interactive modeling for design and analysis of solids
Buss 3D computer graphics: a mathematical introduction with OpenGL
Drettakis et al. A fast shadow algorithm for area light sources using backprojection
Ferguson Practical algorithms for 3D computer graphics
US5710878A (en) Method for facilitating material application for a group of objects of a computer graphic
Gortler Foundations of 3D computer graphics
Van Wijk Ray tracing objects defined by sweeping planar cubic splines
US20120249742A1 (en) Method for visualizing freeform surfaces by means of ray tracing
US5742292A (en) System and method for realistically displaying images indicating the effects of lighting on an object in three dimensional space
JPH05324775A (ja) コンピュータ支援設計装置および方法
Akman et al. Sweeping with all graphical ingredients in a topological picturebook
US9734616B1 (en) Tetrahedral volumes from segmented bounding boxes of a subdivision
Levene A framework for non-realistic projections
JPH05324774A (ja) 立体モデル生成装置および方法
JPH03211686A (ja) コンピュータ制御デイスプレイ方法および装置
Kumar et al. Development of CAD algorithms for bezier curves/surfaces independent of operating system
Lennings et al. An efficient integration of algorithms to evaluate the quality of freeform surfaces
Романюк et al. INTERACTIVE SHAPE MODELING USING FUNCTIONALLY DEFINED OBJECTS
Goldman et al. Three-dimensional computation visualization for computer graphics rendering algorithms
Verma et al. Computer Graphics and CAD
Hubbold et al. GKS-3D and PHIGS—Theory and Practice