LoginSignup
8
6

More than 5 years have passed since last update.

Hemeshチュートリアル その1

Last updated at Posted at 2016-08-11

HemeshはProcessingで3Dオブジェクトを作る時に役に立つライブラリです。
githubはこちら

基本的な紹介

Hemeshはhalf-edged mesh geometryの略で、立体を表現する際にhalf-edged mesh geometryという方式を利用しています。
(half-edged mesh geometryについてはこちら)

Hemeshで扱うクラスには基本的に4種類あって、全ての形を

  • HE_ : メッシュ関係のデータ
  • HEC_ : 基本的な幾何学・配置

の2種類のクラスで作ります。

そして、HEM_クラスで変形等を指定します。WBクラスというものが演算・レンダリングを担当します。

基本ロジック

HE_Meshでメッシュ初期化して、HEC_でメッシュを作るというのが基本。
HE_Meshではコアとなるデータにアクセスできるし、HEC_ではいろんな形と、それに関係するメソッドにアクセスできます。
例えばHEC_Cubeクラスを使うとedge, segment height, width, depth, inner/mid/outer radius等のメソッドを使うことができます。

サンプルプログラム

A_cube_basic_setup.pde
/*
PLEASE READ INTRO TAB
*/

/////////////////////////// GLOBALS ////////////////////////////
// LIBRARY IMPORT
import wblut.math.*;
import wblut.processing.*;
import wblut.core.*;
import wblut.hemesh.*;
import wblut.geom.*;
import processing.opengl.*;

// HEMESH CLASSES & OBJECTS
HE_Mesh MESH; // Our mesh object
WB_Render RENDER; // Our render object

// CAM
import peasy.*;
PeasyCam CAM;

/////////////////////////// SETUP ////////////////////////////

void setup() {
  size(800, 600, OPENGL);
  CAM = new PeasyCam(this, 150);  

  // OUR CREATOR 
  HEC_Cube creator = new HEC_Cube(); 

  //CREATOR PARMAMETERS
  creator.setEdge(70); // edge length in pixels

  MESH = new HE_Mesh(creator); // add our creator object to our mesh object
  RENDER = new WB_Render(this); // RENDER object initialise
}

/////////////////////////// DRAW ////////////////////////////
void draw() {
  background(255);
  // CAMERA
  CAM.beginHUD(); // this method disables PeasyCam for the commands between beginHUD & endHUD
  directionalLight(255, 255, 255, 1, 1, -1);
  directionalLight(127, 127, 127, -1, -1, 1);
  CAM.endHUD();

  // HEMESH
  // We draw our faces using the RENDER object
  noStroke();
  fill(0, 255, 255);
  RENDER.drawFaces( MESH ); // Draw MESH faces

  stroke(255, 0, 0);
  RENDER.drawEdges( MESH ); // Draw MESH edges
}

実行結果
スクリーンショット 2016-08-11 19.57.15.png

セットアップ

まずglobalで

HE_Mesh MESH;

を宣言。
そして、processingのsetup()関数内で

HEC_Cube creator = new HEC_Cube();

のようにメッシュを作るobjectをつくった後、

MESH = new HE_Mesh(creator);

としてHE_Meshインスタンスとしてコールします。

また、WB_Renderクラスはライブラリ内の全ての関数を提供するもので、コードの最初に初期化しておきます。画面への結果表示にも使います。

  1. globalで WB_Render RENDER;
  2. setup();で RENDER = new WB_Render(this);
  3. draw();で RENDER.drawFaces( MESH ); // Notice we add the mesh object within the parentheses.

PeasyCam

座標変換やマウスとのインタラクション用にPeasyCamライブラリも使うと吉です。
http://mrfeinberg.com/peasycam/

基本メソッド

HEC_Cube creatorのメソッドを紹介します。

B_cube_basic_setup.pde
/*
PLEASE READ INTRO TAB
*/

/////////////////////////// GLOBALS ////////////////////////////
// LIBRARY IMPORT
import wblut.math.*;
import wblut.processing.*;
import wblut.core.*;
import wblut.hemesh.*;
import wblut.geom.*;
import processing.opengl.*;

// HEMESH CLASSES & OBJECTS
HE_Mesh MESH; // Our mesh object
WB_Render RENDER; // Our render object

// CAM
import peasy.*;
PeasyCam CAM;

/////////////////////////// SETUP ////////////////////////////

void setup() {
  size(800, 600, OPENGL);
  CAM = new PeasyCam(this, 150);  

  // OUR CREATOR
  HEC_Cube creator = new HEC_Cube(); 

  //CREATOR PARMAMETERS
  creator.setEdge(70); // edge length in pixels
  creator.setWidthSegments(4).setHeightSegments(4).setDepthSegments(4); // keep these small

  //alternatively 
  //creator.setRadius(50);
  //creator.setInnerRadius(50);// radius of sphere inscribed in cube
  //Try these two
  //creator.setOuterRadius(25);// radius of sphere circumscribing cube
  //creator.setMidRadius(10);// radius of sphere tangential to edges

  // These params set the initial position & need to be initialised seperately 
  // from other params such as height / setWidthSegments / edges ...
  creator.setCenter(0, 0, 0).setZAxis(1, 1, 1).setZAngle(PI/4);

  MESH = new HE_Mesh(creator);

  //MESH.triangulate(); // this is one of many methods we can access from the HE_Mesh class
  RENDER = new WB_Render(this); // RENDER object initialise
}

/////////////////////////// DRAW ////////////////////////////
void draw() {
  background(255);
  // CAMERA
  CAM.beginHUD(); // this method disables PeasyCam for the commands between beginHUD & endHUD
  directionalLight(255, 255, 255, 1, 1, -1);
  directionalLight(127, 127, 127, -1, -1, 1);
  CAM.endHUD();

  // HEMESH
  // We draw our faces, vertices and edges using the RENDER object
  noStroke();
  fill(0, 0, 255);
  RENDER.drawFaces( MESH ); // Draw MESH faces

  fill(0, 255, 0);
  RENDER.drawVertices( 2, MESH ); // Draw MESH vertices


  stroke(255,0,0);
  RENDER.drawEdges( MESH ); // Draw MESH edges
  //RENDER.drawFaceNormals( 10, MESH );
}

void keyPressed() {
    if (key == 's') {
    saveFrame("screenShot_###.png");
    println("screen shot taken");
   }

}

実行結果
スクリーンショット 2016-08-11 20.57.03.png

draw();内にfaces, edges, vertices, normals(法線)を見るためのメソッドも含んでいます。

RENDER.drawFaces( MESH );
RENDER.drawVertices( 2, MESH );
RENDER.drawEdges( MESH );
RENDER.drawFaceNormals( 10, MESH );

setup()でコメントアウトしているtriangulationメソッドをアクティベートすると、cubesが違う方法で描画されるようになるのがわかります。上記メソッドはデパッグにも便利です。
スクリーンショット 2016-08-11 20.58.57.png

drawVertex, drawVertexNormalsとかも便利そうです。

Modifires

Modifiersを使うには、まずHEM_modifierクラスを選択して、いろいろパラメータをいじって、modify()を実行してメッシュに反映させます。

C_cube_modif_extrude.pde
/*
PLEASE READ INTRO TAB
 */

/////////////////////////// GLOBALS ////////////////////////////
// LIBRARY IMPORT
import wblut.math.*;
import wblut.processing.*;
import wblut.core.*;
import wblut.hemesh.*;
import wblut.geom.*;
import processing.opengl.*;

// HEMESH CLASSES & OBJECTS
HE_Mesh MESH; // Our mesh object
WB_Render RENDER; // Our render object

// CAM
import peasy.*;
PeasyCam CAM;

/////////////////////////// SETUP ////////////////////////////

void setup() {
  size(800, 600, OPENGL);
  CAM = new PeasyCam(this, 400);  

  // OUR CREATOR
  HEC_Cube creator = new HEC_Cube(); 

  //CREATOR PARMAMETERS
  creator.setEdge(70); 
  creator.setCenter(0, 0, 0).setZAxis(1, 1, 1).setZAngle(PI/4);
  // Activate this line to see what happens
  //creator.setWidthSegments(4).setHeightSegments(4).setDepthSegments(4); // keep these small

  MESH = new HE_Mesh(creator); // add our creator object to our mesh object

  // MODIFIER : SIMPLE EXTRUSION MODIFIER 
  HEM_Extrude extrude = new HEM_Extrude().setDistance(70);
  MESH.modify( extrude ); // ADD OUR MODIFIER TO THE MESH

  RENDER = new WB_Render(this); 
}

/////////////////////////// DRAW ////////////////////////////
void draw() {
  background(255);
  // CAMERA
  CAM.beginHUD(); 
  directionalLight(255, 255, 255, 1, 1, -1);
  directionalLight(127, 127, 127, -1, -1, 1);
  CAM.endHUD();

  // HEMESH
  // To visualise better what is happening, I've activated the edges and disactivated the faces.
  /*
  noStroke();
  fill(0, 0, 255);
  RENDER.drawFaces( MESH ); // Draw MESH faces
  */

  stroke(0, 0, 255);
  strokeWeight(5);
  RENDER.drawEdges( MESH ); // Draw MESH edges
}

void keyPressed() {
  if (key == 'r') {
    setup();
  }
  if (key == 's') {
    saveFrame("screenShot.png");
  }
}

実行結果
スクリーンショット 2016-08-11 21.03.26.png

要は押し出しです

HEM_Extrude extrude = new HEM_Extrude().setDistance(70);
MESH.modify( extrude ); // ADD OUR MODIFIER TO THE MESH

segment width, height, depthはデフォルトでは1です。
creator.setWidthSegments(4).setHeightSegments(4);
などと指定すると、
スクリーンショット 2016-08-11 21.07.45.png
こんな風になります。

Modifierの組み合わせ

C_cube_modif_chamfer.pde
/*
PLEASE READ INTRO TAB
 */

/////////////////////////// GLOBALS ////////////////////////////
// LIBRARY
import wblut.math.*;
import wblut.processing.*;
import wblut.core.*;
import wblut.hemesh.*;
import wblut.geom.*;
import processing.opengl.*;


// HEMESH CLASSES & OBJECTS
HE_Mesh MESH; // Our mesh object
WB_Render RENDER; // Our render object
HEC_Cube creator; // Our creator object

// CAM
import peasy.*;
PeasyCam CAM;

/////////////////////////// SETUP ////////////////////////////

void setup() {
  size(800, 600, OPENGL);
  CAM = new PeasyCam(this, 150);  

  creator = new HEC_Cube(); // Our creator 

  //CREATOR PARMAMETERS
  creator.setEdge(60); 
  MESH = new HE_Mesh(creator);  // ADD OUR CREATOR PARAMETERS TO OUR MESH

  // SIMPLE CHAMFER MODIFIER
  HEM_ChamferCorners chamfer = new HEM_ChamferCorners().setDistance(20);
  HEM_ChamferEdges edges = new HEM_ChamferEdges().setDistance(5);

  MESH.modify( chamfer ); // ADD OUR MODIFIER TO THE MESH
  MESH.modify( edges );

  RENDER = new WB_Render(this); // RENDER MESH
}

/////////////////////////// DRAW ////////////////////////////
void draw() {
  background(255);
  //CAMERA
  CAM.beginHUD(); // this method disables PeasyCam for the commands between beginHUD & endHUD
  directionalLight(255, 255, 255, 1, 1, -1);
  directionalLight(127, 127, 127, -1, -1, 1);
  CAM.endHUD();

  //HEMESH
  /*
  noStroke();
  fill(0, 0, 255);
  RENDER.drawFaces( MESH ); // Draw MESH faces
*/

  stroke(0, 0, 255);
  strokeWeight( 5 );
   RENDER.drawEdges( MESH ); //Draw MESH edges

}

// SOME KEYS INTERACTION
void keyPressed() {

  if (key == 'e') {
    // Hemesh includes a method for exporting geometry
    // in stl file format wich is very handy for 3D printing ;–)
    HET_Export.saveToSTL(MESH, sketchPath("export.stl"), "test");
  }

   if (key == 's') {
    saveFrame("screenShot_###.png");
    println("screen shot taken");
   }
  if (key == 'o') {
    // reset camera origin positions  - do this before
    // exporting your shape so your shape is positioned
    // on a flat plane ready for 3D printing
    CAM.reset(1000);
  }
  // Print camera position - could be helpful
  if (key == 'p') {
    float[] camPos = CAM.getPosition();
    println(camPos);
  }
}

実行結果
スクリーンショット 2016-08-11 21.22.11.png

chamferの数値をいじるとちがった形にもなります。
スクリーンショット 2016-08-11 21.24.13.png

ここでstlに書き出そうとすると、壊れてしまいました。
スクリーンショット 2016-08-11 21.24.59.png

これは保存する前にMESH.triangulate()を実行することで解決できました。
スクリーンショット 2016-08-11 21.28.16.png

ここにチュートリアルがあります。

8
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6