• 検索結果がありません。

PowerPoint プレゼンテーション

N/A
N/A
Protected

Academic year: 2021

シェア "PowerPoint プレゼンテーション"

Copied!
27
0
0

読み込み中.... (全文を見る)

全文

(1)

複雑系科学演習1

コンピュータグラフィックス

担当 畔上秀幸

(2)

今日の話題

†

STLファイルを読み込んで表示する.

„

STLデータをどのようなデータ構造に格納しているか?

†

配列を用いる方法

†

構造体を用いる方法

„

読み込んだデータをどのように使うか?

†

lesson8_1.cの説明

solid NOTITLE

facet normal 0.000000e+00 0.0000000e+00 1.000000e+00 outer loop

vertex 0.000000e+00 1.000000e+00 0.000000e+00 vertex 0.000000e+00 0.000000e+00 0.000000e+00 vertex 1.000000e+00 0.000000e+00 0.000000e+00 endloop

endface

facet normal 0.0000000e+00 0.000000e+00 1.000000e+00 outer loop

vertex 0.000000e+00 1.000000e+00 0.000000e+00 vertex 1.000000e+00 0.000000e+00 0.000000e+00 vertex 1.000000e+00 1.000000e+00 0.000000e+00 endloop

endface endsolid NOTITLE

(3)

STLデータ,要素,節点

A

B

y

x

節点

(node)

要素

(element)

a

b

c

d

e

f

a

b

c

d

e

f

A

B

solid NOTITLE

facet normal 0.000000e+00 0.0000000e+00 1.000000e+00 outer loop

vertex 0.000000e+00 1.000000e+00 0.000000e+00 vertex 0.000000e+00 0.000000e+00 0.000000e+00 vertex 1.000000e+00 0.000000e+00 0.000000e+00 endloop

endface

facet normal 0.0000000e+00 0.000000e+00 1.000000e+00 outer loop

vertex 0.000000e+00 1.000000e+00 0.000000e+00 vertex 1.000000e+00 0.000000e+00 0.000000e+00 vertex 1.000000e+00 1.000000e+00 0.000000e+00 endloop

endface

endsolid NOTITLE

x

y

z

(4)

STLデータを読み込む

†

手順

„

データ構造を考える.

(fem_struct.h)

„

行単位で読み込むプログラムを作る.

(idc.c)

†

一行分のデータを

文字

数字

に分けて読み込む.

„

通常

,

gets系

scanf系

関数を使う.

„

lesson8_1.cではidc.cを関数を使っている.

†

バイナリデータの場合は方法が異なる.

„

データを代入するプログラムを作る.

(stl_utl.c)

†

読み込んだデータを確認しつつ,必要なデータを取捨選択

しながら読み込む.

†

想定外のデータがあった場合の対処

(5)

データ構造

:

配列を用いる方法

†

まず,データを見る.

facet normal 0.000000e+00 0.0000000e+00 1.000000e+00 outer loop

vertex 0.000000e+00 1.000000e+00 0.000000e+00

vertex 0.000000e+00 0.000000e+00 0.000000e+00

vertex 1.000000e+00 0.000000e+00 0.000000e+00

endloop endface

†

1要素につき,法線1つと節点3つ

„

OpenGLでポリゴン表示するには全部必要

„

しかし,まれに法線が間違っている

STLが存在する.

† 今回は法線を無視し,自力で計算する.

„

節点の並びが,時計回りか反時計回りかは表示してみないとわからない.

„

一つの要素を

double型の配列9個で格納できる

法線

節点

(6)

配列

†

定義

„ 型 識別子[定数式];

†

node

という名前の

double型

の値が

9個

入る配列の宣言

†

double node[9];

†

配列の初期化

†

double node[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};

†

値の代入

„

節点

aの値の代入

node[0] = 0.000000e+00; /* x */ node[1] = 1.000000e+00; /* y */ node[2] = 0.000000e+00; /* z */

„

節点

bの値の代入

node[3] = 0.000000e+00; /* x */ node[4] = 0.000000e+00; /* y */ node[5] = 0.000000e+00; /* z */

(7)

配列

(Cont.)

†

二次元配列の

定義

„ 型 識別子[定数式] [定数式];

†

node

という名前の

double型

の値が

3x3個

入る

配列の宣言

†

double node[3][3];

†

配列の初期化

†

double node[

3

][

3

] = {

{

0.0, 0.0, 0.0

}

,

{

0.0, 0.0, 0.0

}

,

{

0.0, 0.0, 0.0

}

};

(8)

配列

(Cont.)

†

値の代入

„

節点

aの値の代入

node[0][0] = 0.000000e+00; /* x */ node[0][1] = 1.000000e+00; /* y */ node[0][2] = 0.000000e+00; /* z */

„

節点

bの値の代入

node[1][0] = 0.000000e+00; /* x */ node[1][1] = 0.000000e+00; /* y */ node[1][2] = 0.000000e+00; /* z */

†

配列の値を出力

for(ii1=0; ii1<3; ii1++){

for(ii2=0; ii2<3; ii2++){

fprintf(stderr, “node[%d][%d] = %e¥n”, ii1, ii2,

node[

ii1

][

ii2

]

);

}

(9)

データ構造

:

配列を用いる方法

(Cont.)

†

3次元配列も同じ.

†

STLデータを3次元配列で読み込む事を考える.

„

double model[要素数][節点数][座標値];

„

double model[

?

][3][3];

„

要素数がわからない.

†

3次元形状計測装置で取得したデータ量(要素数)は人に

よってまちまち

„

解決策

†

要素数に巨大な数字を指定する.

„ スタックオーバーフローが起こる.

†

静的な配列を使わずに

動的に配列を確保する

(10)

†

配列の動的確保:1次元配列の場合の例

int allocate1D (int size, double **array) {

int ii1;

if(size <= 0) return(1); /* サイズのチェック */ /* 配列の動的確保 */

(*array) = (double *)malloc(size * sizeof(double)) );

if(*array == NULL) return(1); /* mallocが失敗してないかチェック */ /* 配列の初期化 */

for(ii1=0; ii1<size; ii1++){ (*array)[ii1] = 0.0; } return(0); }

データ構造

:

配列を用いる方法

(Cont.)

array[size]になると考えればよい.

(11)

データ構造再考

†

三次元配列を動的に確保すれば,データは格

納できる.

†

しかし,配列のデータ構造にはいくつかの問題

がある.

„ 重複した節点を格納している.

†

a-d, c-eは同じ座標値

.格納効率が悪い.

†

節点が移動した場合

,その節点を含む要素を

探索し,修正する必要がある.

„

二次元三角形のSTLの場合はまだ良いが,有限要

素モデルのように内部にもメッシュ構造を持つ三次

元モデルの場合,

ほとんどが重複節点

である.

„

節点の番号がない場合,移動する節点と共通の座

標を持つ節点を

誤差計算をしながら全配列から探

査する

必要がある.

A

B

y

x

a

b

c

d

e

f

(12)

データ構造

:構造体

を用いる方法

†

要素と節点を分けて格納する.

„

この方法は有限要素法に用いることを前提にした

azlibの場合であって,必ずしも全ての状況におい

て最善というわけではない.

„

要素と節点に数字のラベルをつける.

A

B

y

x

a

b

c

d

e

f

3

5

y

x

11

12

13

14

(13)

データ構造

:構造体

を用いる方法

(Cont.)

†

要素と節点の持つべきデータを考える

.

„

要素

†

ラベル

[

3

]

†

構成されている節点

[

11

,

12

,

13

]

„

節点

†

ラベル

[

11

]

†

座標値

[

0.0000

,

1.0000

,

0.0000

]

3

y

x

11

12

13

(14)

データ構造

:構造体を用いる方法(Cont.)

†

要素と節点を分けて格納すると

要素ラベル

要素を構成

する節点

11

13

11

13

5

14

12

3

3

5

y

x

11

12

13

14

0.0000 0.0000 0.0000 0.0000 0.0000 1.0000 0.0000 12 13 0.0000 14 0.0000 1.0000 1.0000 1.0000 節点座標 11 節点ラベル

要素のデータ構造配列

節点のデータ構造配列

(15)

構造体

†

定義

„

struct タグ名 {メンバ宣言子並び} 宣言子並び

„

通常

typedefを用いて型として宣言する.

†

VECT3D

という名前のベクトルもしくは3次元座標を格納する構造体の宣言

typedef struct

{

double x;

double y;

double z;

}

VECT3D;

†

pを宣言

VECT3D

p;

†

初期化はメンバ毎に行う.通常初期化する関数を作る.

p.x = 0.0;

p.y = 0.0;

p.z = 0.0;

構造体のメンバにアクセスするときは「

.」で指定する.

(16)

データ構造

:構造体

を用いる方法

(Cont.)

†

節点の構造体

typedef struct {

int label; /* label of node(if < 0 then unused) */

VECT3D p; /* x,y,z coordinate value */

int renum; /* for renumbering */

int i_info[NODE_INFO]; /* the other informations(int) */ double d_info[NODE_INFO]; /* the other informations(double) */

} NODE; 節点ラベル 節点座標 0.0000 1.0000 0.0000 11

y

x

11

p

label

(17)

データ構造

:構造体

を用いる方法

(Cont.)

†

要素の構造体

#define MAX_NODE 20

typedef struct {

int label; /* label of element(if < 0 then unused) */

ELEM_TYPE type; /* element type */

int material; /* material property label */ int physical; /* physical property label */

int node_num; /* number of node */

int node[MAX_NODE]; /* node labels */

double volume; /* volume or area of element */

int i_info[ELEMENT_INFO]; /* another information (int) */ double d_info[ELEMENT_INFO]; /* another information (double) */

} ELEMENT;

3

y

x

11

12

13

要素ラベル 要素を構成す る節点 11 13 12 3

(18)

データ構造

:構造体

を用いる方法

(Cont.)

†

節点配列の構造体

typedef struct

{

int size;

int alloc_size;

DATA_TYPE source;

NODE *array;

RENUMBER_FLAG renum_flag;

ARRAY_SORT_FLAG sort_flag;

}

NODE_ARRAY

;

y

x

11

12

13

14

節点ラベル 節点座標 0.0000 1.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 12 13 1.0000 1.0000 1.0000 14 0.0000 11

array[?]

NODE

(19)

データ構造

:構造体

を用いる方法

(Cont.)

†

要素配列の構造体

typedef struct

{

int size;

int alloc_size;

DATA_TYPE source;

ELEMENT *array;

ARRAY_SORT_FLAG sort_flag;

}

ELEMENT_ARRAY

;

要素ラベル

要素を構成

する節点

11

13

11

13

5

14

12

3

3

5

y

x

11

12

13

14

ELEMENT

(20)

lesson8_1.c

21

行目から

/* グローバル変数 */

static GLint drag_state; static GLint begin_x = 0; static GLint begin_y = 0; static float quat[4];

static NODE_ARRAY node;

static ELEMENT_ARRAY element;

static VECT3D min, max, center; static double radius;

57

行目から

/* STLファイルからモデルデータを読み込む */

rc_fopen(argv[1], "r", &fp); /* ファイルを開く */

input_stl_3dface(fp, &element, &node); /* STLファイルの読み込み */

rc_fclose(fp); /* ファイルを閉じる */ /* 節点と要素の数 */

fprintf(stderr, "node.size = %d¥n", node.size);

(21)

lesson8_1.c(Cont.)

141

行目から

/* STLモデルを描画 */

glPushMatrix();

/* 大きさを正規化して,STLモデルを原点に移動 */

glScalef(1.0/radius, 1.0/radius, 1.0/radius); glTranslatef(-center.x, -center.y, -center.z);

/* Bounding Box */ glDisable(GL_LIGHTING); /* 線,点を描画する時はライトOFF */ glColor3f(R(100), G(100), B(100)); draw_bounding_box(min, max); /* STLモデルを描画 */ glEnable(GL_LIGHTING); /* ライトON */ glColor3f(R(32), G(165), B(237)); draw_stl_model(GL_POLYGON); /* GL_LINE_LOOPにすると線で表示 */ glPopMatrix();

(22)

lesson8_1.c(Cont.)

290

行目から

void draw_stl_model(GLenum mode)

{

int ii1;

……

for(ii1=0; ii1<element.size; ii1++){

/* 要素数で繰り返し */

/* 要素配列の labelが -1 の要素は使われていないのでスキップ */

if(element.array[ii1].label < 0){

continue;

}

……

}

……

}

要素ラベル 要素を構成 する節点 11 13 11 13 5 14 12 3

(23)

lesson8_1.c(Cont.)

†

要素と節点を分けて格納したので節点を検索する必要が

ある.

303

行目から

/* * 各要素を成す節点(三角形の頂点)の配列上の位置を探索する * node : 節点の配列などを含む「節点の構造体」 * element : 要素の配列などを含む「要素の構造体」 * element.array[??] : 要素配列中の一つの要素 * element.array[??].node[0] : 要素を成す節点(三角形の頂点)の一つ目 * index[?] : ある番号を持つ節点が節点配列の何番目にあるかを示す数字 */

index[0] = search_node_label(node, element.array[ii1].node[0]); index[1] = search_node_label(node, element.array[ii1].node[1]); index[2] = search_node_label(node, element.array[ii1].node[2]); /* 何れかの節点が無い時はプログラム終了 */

if( (index[0] < 0) || (index[1] < 0) || (index[2] < 0)){ fprintf(stderr, "search_node_label[%d|?] < ", ii1); exit(1); } 要素ラベル 要素を構成 する節点 11 13 11 13 5 14 12 3

(24)

lesson8_1.c(Cont.)

†

配列の位置とラベルは違う.

†

index[0] = search_node_label(node, element.array[0].node[0]);

配列の

番号

要素ラ

ベル

要素を構成

する節点

11

3

13

11

13

1

5

14

12

0

14 13 12 11 節点ラベル 0.0000 0.0000 0.0000 0.0000 0.0000 1.0000 0.0000 1 2 0.0000 3 0.0000 1.0000 1.0000 1.0000 節点座標 0 配列の番号

(25)

lesson8_1.c(Cont.)

†

法線ベクトルの計算

321

行目から

/* * 簡易法線計算 * node.array[index[0]].p : 節点配列の index[0]番目にある節点の座標点 p * sub_vect3d() : ベクトルの差 * outer_product3d() : 外積 */

v1 = sub_vect3d( node.array[index[1]].p, node.array[index[0]].p ); v2 = sub_vect3d( node.array[index[2]].p, node.array[index[0]].p ); nvect = outer_product3d(v1, v2);

y

x

11

12

13

v1

v2

(26)

lesson8_1.c(Cont.)

331

行目から

glBegin(mode);

glNormal3d

(nvect.x, nvect.y, nvect.z);

/* 面の法線を指定 */

/* 三角形の頂点 */

glVertex3d( node.array[index[0]].p.x,

node.array[index[0]].p.y,

node.array[index[0]].p.z);

glVertex3d( node.array[index[1]].p.x,

node.array[index[1]].p.y,

node.array[index[1]].p.z);

glVertex3d( node.array[index[2]].p.x,

node.array[index[2]].p.y,

node.array[index[2]].p.z);

glEnd();

(27)

演習

†

いくつかのモデルを見てみる.

„

model.tar.gz

†

大きなモデルを読み込んだときのメモリの使用状況を

見てみる.

(foot1.stl, foot2.stl, foot3.stl)

„

ターミナルで

topコマンドを使う.

†

155行目を変更して,ポリゴン,線,点で描画したとき

参照

関連したドキュメント

2022年3月現在 ドライブレコーダー搭載 11.1型デジタルミラー / 11.1型デジタルミラー

葛ら(2005):構造用鋼材の延性き裂発生の限界ひずみ,第 8

• 自動溶接を行う場合、「金属アーク溶接等作 業」には、自動溶接機による溶接中に溶接機

●Gartner Magic QuadrantにてクラウドHCM Suiteにおけるリーダーの評価.. Copyright © 2022 Nomura System Corporation Co, Ltd. All Rights Reserved.. Copyright © 2022 Nomura

節の構造を取ると主張している。 ( 14b )は T-ing 構文、 ( 14e )は TP 構文である が、 T-en 構文の例はあがっていない。 ( 14a

本研究は,地震時の構造物被害と良い対応のある震害指標を,構造物の疲労破壊の

ドリフト流がステップ上段方向のときは拡散係数の小さいD2構造がテラス上を

[r]