#ifndef ATS_DXF_H #define ATS_DXF_H #include #include #include #include #include "ats_point.h" #include "ats_component.h" #include "ats_composite.h" #include "ats_leaf.h" #include "ats_exception.h" namespace ats { template class Dxf : public Leaf3D { protected: std::vector m_pnt_array; std::vector m_idx_array; std::vector m_nrm_array; T m_scale; // 0 xmax 1 xmin 2 ymax 3 ymin 4 zmax 5 zmin Point m_box[6]; virtual void cul_normal(); virtual void read_pnt(::ifstream& dxf); virtual void set_scale(); public: Dxf(const char* filename); virtual void Draw(); virtual void UpdateTime(double) {}; }; // コンストラクタ ----------------------------------------------------- template Dxf::Dxf(const char* filename) { ::ifstream dxf(filename, ios::nocreate); if(!dxf.is_open()){ throw cant_open_file("DXF::DXF ファイルが開けません"); } read_pnt(dxf); cul_normal(); dxf.close(); set_scale(); } // 描画関数 ----------------------------------------------------------- template void Dxf::Draw() { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDisable(GL_LIGHTING); glPushMatrix(); glScaled(m_scale, m_scale, m_scale); glColor3f(1.0, 1.0, 1.0); glVertexPointer(3, GL_DOUBLE, 0, reinterpret_cast(m_pnt_array.begin()) ); glNormalPointer(GL_DOUBLE, 0, reinterpret_cast(m_nrm_array.begin()) ); glDrawElements(GL_QUADS, m_idx_array.size(), GL_UNSIGNED_INT, reinterpret_cast(m_idx_array.begin())); glPopMatrix(); } // 法線計算 ------------------------------------------------------------ template void Dxf::cul_normal() { m_nrm_array.resize(m_pnt_array.size()); for(int i=0; i < m_pnt_array.size(); i+=3){ // normal(&m_pnt_array[i], &m_pnt_array[i+1], &m_nrm_array[i]); } } // ポイント読み込み ---------------------------------------------------- template void Dxf::read_pnt(::ifstream& dxf) { std::vector pnt_array(::filelength( dxf.fd() ) / 5); /**************************************************** * char command[1024]バッファはSTLのfstreamの速度が * 改善した時点でstringに変更すること。 ****************************************************/ char command[1024] = {0}; static int i=0; do { dxf >> command; if(!strcmp(command, "3DFACE")) { char tmp[256]; while(strcmp("10", tmp)){ dxf >> tmp; } for(int j=i; i < j+12; i+=3) { dxf >> pnt_array[i] >> tmp >> pnt_array[i+1] >> tmp >> pnt_array[i+2] >> tmp; // 10 もしくは最後の0 } } } while(strcmp(command, "EOF")); int pnt_size = i - 3; m_pnt_array.resize(pnt_size); for(i=0; i <= pnt_size; i++){ m_pnt_array[i] = pnt_array[i]; } m_idx_array.resize(pnt_size/3); int j; for(j=0; j < pnt_size/3; j++) { m_idx_array[j] = j; } cout << "first : " << m_pnt_array[0] << ' ' << m_pnt_array[1] << ' ' << m_pnt_array[2] << endl; cout << "point : " << m_pnt_array.size() << endl << "polygon : " << m_idx_array.size() << endl; } // オブジェクトの最大値がsizeで表示されるように ------------------------- // スケールを設定 template void Dxf::set_scale() { for(int i=0; i < m_pnt_array.size() /3; i++){ if(m_box[0].X() < m_pnt_array[i*3]){ m_box[0].X(m_pnt_array[i*3]); m_box[0].Y(m_pnt_array[i*3+1]); m_box[0].Z(m_pnt_array[i*3+2]); } if(m_box[1].X() > m_pnt_array[i*3]){ m_box[1].X(m_pnt_array[i*3]); m_box[1].Y(m_pnt_array[i*3+1]); m_box[1].Z(m_pnt_array[i*3+2]); } if(m_box[2].Y() < m_pnt_array[i*3+1]){ m_box[2].X(m_pnt_array[i*3]); m_box[2].Y(m_pnt_array[i*3+1]); m_box[2].Z(m_pnt_array[i*3+2]); } if(m_box[3].Y() > m_pnt_array[i*3+1]){ m_box[3].X(m_pnt_array[i*3]); m_box[3].Y(m_pnt_array[i*3+1]); m_box[3].Z(m_pnt_array[i*3+2]); } if(m_box[4].Z() < m_pnt_array[i*3+2]){ m_box[4].X(m_pnt_array[i*3]); m_box[4].Y(m_pnt_array[i*3+1]); m_box[4].Z(m_pnt_array[i*3+2]); } if(m_box[5].Z() > m_pnt_array[i*3+2]){ m_box[5].X(m_pnt_array[i*3]); m_box[5].Y(m_pnt_array[i*3+1]); m_box[5].Z(m_pnt_array[i*3+2]); } } T obj_size, scale_size = 1.5; obj_size = fabs(m_box[0].X() - m_box[1].X()); obj_size = (obj_size == 0) ? 0.000000000001 : obj_size; T sx = scale_size / obj_size; obj_size = fabs(m_box[2].Y() - m_box[3].Y()); obj_size = (obj_size == 0) ? 0.000000000001 : obj_size; T sy = scale_size / obj_size; obj_size = fabs(m_box[4].Z() - m_box[5].Z()); obj_size = (obj_size == 0) ? 0.000000000001 : obj_size; T sz = scale_size / obj_size; m_scale = (sx < sy) ? sx : sy; m_scale = (m_scale < sz) ? m_scale : sz; cout << "scale : " << m_scale << endl; } } #endif // ATS_DXF_H