2016-06-18 15 views
0

私は現在libiglに取り組んでおり、別のボディの中にあるサーフェスの部分をつかみようとしています。しかし、libiglは閉鎖されたボディでしか動作しないようです:libiglを使用して薄い表面でブール演算を実行する方法は?

ここは閉じたボディで動作するコードです。例えば様以下、

#include <igl/readOFF.h> 
//#define IGL_NO_CORK 
//#undef IGL_STATIC_LIBRARY 
#include <igl/copyleft/cgal/mesh_boolean.h> 
#include <igl/viewer/Viewer.h> 

#include <Eigen/Core> 
#include <iostream> 

Eigen::MatrixXd VA,VB,VC; 
Eigen::VectorXi J,I; 
Eigen::MatrixXi FA,FB,FC; 
igl::MeshBooleanType boolean_type(
    igl::MESH_BOOLEAN_TYPE_UNION); 

const char * MESH_BOOLEAN_TYPE_NAMES[] = 
{ 
    "Union", 
    "Intersect", 
    "Minus", 
    "XOR", 
    "Resolve", 
}; 

bool key_down(igl::viewer::Viewer &viewer, unsigned char key, int mods) 
{ 
    switch(key) 
    { 
    default: 
     return false; 
    case 'A': 
     viewer.data.clear(); 
     std::cout << "Loading A" << std::endl; 
     viewer.data.set_mesh(VA, FA); 
     break; 
    case 'B': 
     viewer.data.clear(); 
     std::cout << "Loading B" << std::endl; 
     viewer.data.set_mesh(VB, FB); 
     break; 
    case 'C': 
     viewer.data.clear(); 
     std::cout << "Loading C" << std::endl; 
     viewer.data.set_mesh(VC, FC); 
     return true; 
    } 
    return true; 
} 

int main(int argc, char *argv[]) 
{ 
    using namespace Eigen; 
    using namespace std; 

    double prismSize = 150; 
    double Heigh = 300; 
    VA.resize(6, 3); 
    VA << -prismSize, prismSize, 0, 
     prismSize, prismSize, 0, 
     0, 2 * prismSize, 0, 
     -prismSize, prismSize, Heigh, 
     prismSize, prismSize, Heigh, 
     0, 2 * prismSize, Heigh; 
    FA.resize(8, 3); 
    FA << 1, 0, 2, 
     5, 3, 4, 
     4, 1, 2, 
     2, 5, 4, 
     3, 5, 2, 
     2, 0, 3, 
     0, 1, 4, 
     4, 3, 0; 

    double tetsize = 300; 
    VB.resize(4, 3); 
    VB << 0, 0, tetsize, 
     -tetsize, 0, 0, 
     tetsize, 0, 0, 
     0, tetsize*2, 0; 
    FB.resize(4, 3); 
    FB << 2, 1, 3, 
     2, 0, 1, 
     3, 0, 2, 
     1, 0, 3; 


    igl::copyleft::cgal::mesh_boolean(VA, FA, VB, FB, igl::MESH_BOOLEAN_TYPE_INTERSECT, VC, FC); 

    std::cout 
     << "VA:" << std::endl << VA << std::endl << "==============" << std::endl 
     << "FA:" << std::endl << FA << std::endl << "==============" << std::endl 
     << "VB:" << std::endl << VB << std::endl << "==============" << std::endl 
     << "FB:" << std::endl << FB << std::endl << "==============" << std::endl 
     << "VC:" << std::endl << VC << std::endl << "==============" << std::endl 
     << "FC:" << std::endl << FC << std::endl << "==============" << std::endl; 

    // Plot the mesh with pseudocolors 
    igl::viewer::Viewer viewer; 

    viewer.data.set_mesh(VA, FA); 
    //viewer.data.set_mesh(VB, FB); 
    //viewer.data.set_mesh(VC, FC); 

    viewer.core.show_lines = true; 
    viewer.callback_key_down = &key_down; 
    viewer.core.camera_dnear = 3.9; 
    cout<< 
    "Press '.' to switch to next boolean operation type."<<endl<< 
    "Press ',' to switch to previous boolean operation type."<<endl<< 
    "Press ']' to push near cutting plane away from camera."<<endl<< 
    "Press '[' to pull near cutting plane closer to camera."<<endl<< 
    "Hint: investigate _inside_ the model to see orientation changes."<<endl; 
    viewer.launch(); 
} 

しかし、私はA又はBから表面のいずれかを削除した場合:VAVFFBが四面体であり、三角プリズムとVBある

//FA.resize(8, 3); 
FA.resize(7, 3); 
//FA << 1, 0, 2, 
FA << 5, 3, 4, 
     4, 1, 2, 
     2, 5, 4, 
     3, 5, 2, 
     2, 0, 3, 
     0, 1, 4, 
     4, 3, 0; 

結果メッシュCは空になります(閉じたボディの代わりに開いた薄いサーフェスを取得したい)。私は間違った機能を使っていると思う。誰でもこれを行う方法を知っていますか?

答えて

1

igl::copyleft::cgal::trim_with_solidをお探しの場合があります。これはあなたが任意のメッシュAを持っていて、別の閉じたメッシュ(実際にはソリッドまたはPWNメッシュ)Bを持っていることを前提としています。出力はAと同じサーフェスのメッシュになりますが、新しいエッジが追加されているため、すべてのフェースにB、またはBの外側にフラグが立てられます。出力リストDのフラグを使用して、Aの部分を「トリムされた」Bで抽出するのは簡単です。

igl::copyleft::cgal::trim_with_solid(VA,FA,VB,FB,V,F,D,J); 
+0

'J'は何のために使われますか?booleanに関連するAPIには 'J'が頻繁に出現するようですが、明確な情報は見つかりませんでした。 –

+0

'J'は、_output_の各面から_input_のどの面が来ているかを教えてくれるでしょう。あなたの入力の各面が異なる色をしているとしたら、 'J'は出力メッシュの色を正しく合わせる方法を教えてくれるでしょう。 –

1

ブールジオメトリでは、すべてのサーフェスが境界のないマニフォールドである必要があります。それ以外の場合は空のセットになります。あなたの質問に

Manifolds

...ともっと推論:ここではマニホールドの簡単なexplinationがある

@Ericビショフで説明したようにBoolean Operations

0

、ブールジオメトリは、すべての面であることが必要ですマニホールド。しかし、私は、少なくとも私の要件に適合しており、このための回避策を見つけました:

Aは任意の開放面であるとBが閉じられたマニホールドで、あなたが表面Aの外側の部分を切断するとします。

私が説明したい問題を回避するには、まずそれマニホールド(A')にするAを完成させることです。次に、BからA'を引いて、新しく作成されたファセットを見つけます。ファセットは、あなたが望む開いた薄い表面を正確に構成します。

+1

私はあなたのデータセットと使用例を知らないんだが: あなたはすべての連続した境界をクローズアップできます。あなたがハーフエッジデータ構造にアクセスできるならば、ちょうど隣接する1つの顔を持つ隣接エッジを見つけることができると思います。これはすべてのケースでうまくいくわけではありませんが、データによってはほとんどの場合動作します。 –

+0

それは私がlibiglを使ったことがないので、それを取ることができる限りです。幸運:) –

+0

@ user5454506はい、私のデータ構造は特別なので、私はこのルートを使用することができます。最近、私は簡単に閉じられない新しいジオメトリに直面しています。 @Alec Jacobsonによって提案された 'igl :: copyleft :: cgal :: trim_with_solid(VA、FA、VB、FB、V、F、D、J);'しようとしています –

関連する問題