// $Id: CutGrid.cpp,v 1.11 2004-12-27 09:17:44 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // // Please report all bugs and problems to <gmsh@geuz.org>. #include "OctreePost.h" #include "CutGrid.h" #include "List.h" #include "Context.h" #if defined(HAVE_FLTK) #include "GmshUI.h" #include "Draw.h" #endif extern Context_T CTX; StringXNumber CutGridOptions_Number[] = { {GMSH_FULLRC, "X0", GMSH_CutGridPlugin::callbackX0, -1.}, {GMSH_FULLRC, "Y0", GMSH_CutGridPlugin::callbackY0, -1.}, {GMSH_FULLRC, "Z0", GMSH_CutGridPlugin::callbackZ0, 0.}, {GMSH_FULLRC, "X1", GMSH_CutGridPlugin::callbackX1, -1.}, {GMSH_FULLRC, "Y1", GMSH_CutGridPlugin::callbackY1, 0.}, {GMSH_FULLRC, "Z1", GMSH_CutGridPlugin::callbackZ1, 0.}, {GMSH_FULLRC, "X2", GMSH_CutGridPlugin::callbackX2, 0.}, {GMSH_FULLRC, "Y2", GMSH_CutGridPlugin::callbackY2, -1.}, {GMSH_FULLRC, "Z2", GMSH_CutGridPlugin::callbackZ2, 0.}, {GMSH_FULLRC, "nPointsU", GMSH_CutGridPlugin::callbackU, 20}, {GMSH_FULLRC, "nPointsV", GMSH_CutGridPlugin::callbackV, 20}, {GMSH_FULLRC, "iView", NULL, -1.} }; extern "C" { GMSH_Plugin *GMSH_RegisterCutGridPlugin() { return new GMSH_CutGridPlugin(); } } GMSH_CutGridPlugin::GMSH_CutGridPlugin() { ; } void GMSH_CutGridPlugin::draw() { #if defined(HAVE_FLTK) glColor4ubv((GLubyte *) & CTX.color.fg); double p[3]; glBegin(GL_LINES); for(int i = 0; i < getNbU(); ++i){ getPoint(i, 0, p); glVertex3d(p[0], p[1], p[2]); getPoint(i, getNbV()-1, p); glVertex3d(p[0], p[1], p[2]); } for(int i = 0; i < getNbV(); ++i){ getPoint(0, i, p); glVertex3d(p[0], p[1], p[2]); getPoint(getNbU()-1, i, p); glVertex3d(p[0], p[1], p[2]); } glEnd(); #endif } void GMSH_CutGridPlugin::callback() { #if defined(HAVE_FLTK) CTX.post.plugin_draw_function = draw; if(CTX.fast_redraw){ CTX.post.draw = 0; CTX.mesh.draw = 0; } if(!CTX.batch) Draw(); CTX.post.plugin_draw_function = NULL; CTX.post.draw = 1; CTX.mesh.draw = 1; #endif } double GMSH_CutGridPlugin::callbackXYZ(int num, int action, double value, double *opt) { switch(action){ // configure the input field case 1: return CTX.lc/200.; case 2: return -CTX.lc; case 3: return CTX.lc; default: break; } *opt = value; callback(); return 0.; } double GMSH_CutGridPlugin::callbackX0(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[0].def); } double GMSH_CutGridPlugin::callbackY0(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[1].def); } double GMSH_CutGridPlugin::callbackZ0(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[2].def); } double GMSH_CutGridPlugin::callbackX1(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[3].def); } double GMSH_CutGridPlugin::callbackY1(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[4].def); } double GMSH_CutGridPlugin::callbackZ1(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[5].def); } double GMSH_CutGridPlugin::callbackX2(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[6].def); } double GMSH_CutGridPlugin::callbackY2(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[7].def); } double GMSH_CutGridPlugin::callbackZ2(int num, int action, double value) { return callbackXYZ(num, action, value, &CutGridOptions_Number[8].def); } double GMSH_CutGridPlugin::callbackU(int num, int action, double value) { switch(action){ // configure the input field case 1: return 1; case 2: return 2; case 3: return 100; default: break; } CutGridOptions_Number[9].def = value; callback(); return 0.; } double GMSH_CutGridPlugin::callbackV(int num, int action, double value) { switch(action){ // configure the input field case 1: return 1; case 2: return 2; case 3: return 100; default: break; } CutGridOptions_Number[10].def = value; callback(); return 0.; } void GMSH_CutGridPlugin::getName(char *name) const { strcpy(name, "Cut grid"); } void GMSH_CutGridPlugin::getInfos(char *author, char *copyright, char *help_text) const { strcpy(author, "J.-F. Remacle (remacle@scorec.rpi.edu)"); strcpy(copyright, "DGR (www.multiphysics.com)"); strcpy(help_text, "Plugin(CutGrid) cuts a tetrahedron view with a\n" "rectangular grid defined by the 3 points (`X0',`Y0',`Z0')\n" "(origin), (`X1',`Y1',`Z1') (axis of U) and (`X2',`Y2',`Z2')\n" "(axis of V). The number of points along U and V is set\n" "with the options `nPointsU' and `nPointsV'. If\n" "`iView' < 0, the plugin is run on the current view.\n" "\n" "Plugin(CutGrid) creates one new view.\n"); } int GMSH_CutGridPlugin::getNbOptions() const { return sizeof(CutGridOptions_Number) / sizeof(StringXNumber); } StringXNumber *GMSH_CutGridPlugin::getOption(int iopt) { return &CutGridOptions_Number[iopt]; } void GMSH_CutGridPlugin::catchErrorMessage(char *errorMessage) const { strcpy(errorMessage, "CutGrid failed..."); } int GMSH_CutGridPlugin::getNbU() { return (int)CutGridOptions_Number[9].def; } int GMSH_CutGridPlugin::getNbV() { return (int)CutGridOptions_Number[10].def; } void GMSH_CutGridPlugin::getPoint(int iU, int iV, double *X) { double u = getNbU() > 1 ? (double)iU / (double)(getNbU() - 1.) : 0.; double v = getNbV() > 1 ? (double)iV / (double)(getNbV() - 1.) : 0.; X[0] = CutGridOptions_Number[0].def + u * (CutGridOptions_Number[3].def-CutGridOptions_Number[0].def) + v * (CutGridOptions_Number[6].def-CutGridOptions_Number[0].def) ; X[1] = CutGridOptions_Number[1].def + u * (CutGridOptions_Number[4].def-CutGridOptions_Number[1].def) + v * (CutGridOptions_Number[7].def-CutGridOptions_Number[1].def) ; X[2] = CutGridOptions_Number[2].def + u * (CutGridOptions_Number[5].def-CutGridOptions_Number[2].def) + v * (CutGridOptions_Number[8].def-CutGridOptions_Number[2].def) ; } Post_View * GMSH_CutGridPlugin::GenerateView(Post_View * v) const { Post_View * View = BeginView(1); double X1[3],X2[3],X3[3],X4[3]; double *VALUES1 = new double [9*v->NbTimeStep]; double *VALUES2 = new double [9*v->NbTimeStep]; double *VALUES3 = new double [9*v->NbTimeStep]; double *VALUES4 = new double [9*v->NbTimeStep]; OctreePost o(v); for(int i = 0; i < getNbU()-1; ++i){ for(int j = 0; j < getNbV()-1; ++j){ getPoint(i , j , X1); getPoint(i+1, j , X2); getPoint(i+1, j+1, X3); getPoint(i , j+1, X4); if(v->NbSS){ List_Add(View->SQ, &X1[0]); List_Add(View->SQ, &X2[0]); List_Add(View->SQ, &X3[0]); List_Add(View->SQ, &X4[0]); List_Add(View->SQ, &X1[1]); List_Add(View->SQ, &X2[1]); List_Add(View->SQ, &X3[1]); List_Add(View->SQ, &X4[1]); List_Add(View->SQ, &X1[2]); List_Add(View->SQ, &X2[2]); List_Add(View->SQ, &X3[2]); List_Add(View->SQ, &X4[2]); View->NbSQ ++; o.searchScalar(X1[0], X1[1], X1[2], VALUES1); o.searchScalar(X2[0], X2[1], X2[2], VALUES2); o.searchScalar(X3[0], X3[1], X3[2], VALUES3); o.searchScalar(X4[0], X4[1], X4[2], VALUES4); for(int k = 0; k < v->NbTimeStep; ++k){ List_Add(View->SQ, &VALUES1[k]); List_Add(View->SQ, &VALUES2[k]); List_Add(View->SQ, &VALUES3[k]); List_Add(View->SQ, &VALUES4[k]); } } if(v->NbVS){ List_Add(View->VQ, &X1[0]); List_Add(View->VQ, &X2[0]); List_Add(View->VQ, &X3[0]); List_Add(View->VQ, &X4[0]); List_Add(View->VQ, &X1[1]); List_Add(View->VQ, &X2[1]); List_Add(View->VQ, &X3[1]); List_Add(View->VQ, &X4[1]); List_Add(View->VQ, &X1[2]); List_Add(View->VQ, &X2[2]); List_Add(View->VQ, &X3[2]); List_Add(View->VQ, &X4[2]); View->NbVQ ++; double sizeElem; o.searchVector(X1[0],X1[1],X1[2], &sizeElem, VALUES1); o.searchVector(X2[0],X2[1],X2[2], &sizeElem, VALUES2); o.searchVector(X3[0],X3[1],X3[2], &sizeElem, VALUES3); o.searchVector(X4[0],X4[1],X4[2], &sizeElem, VALUES4); for(int k = 0; k < v->NbTimeStep; ++k){ List_Add(View->VQ, &VALUES1[3*i]); List_Add(View->VQ, &VALUES1[3*i+1]); List_Add(View->VQ, &VALUES1[3*i+2]); List_Add(View->VQ, &VALUES2[3*i]); List_Add(View->VQ, &VALUES2[3*i+1]); List_Add(View->VQ, &VALUES2[3*i+2]); List_Add(View->VQ, &VALUES3[3*i]); List_Add(View->VQ, &VALUES3[3*i+1]); List_Add(View->VQ, &VALUES3[3*i+2]); List_Add(View->VQ, &VALUES4[3*i]); List_Add(View->VQ, &VALUES4[3*i+1]); List_Add(View->VQ, &VALUES4[3*i+2]); } } } } char name[1024], filename[1024]; sprintf(name, "%s_CutGrid", v->Name); sprintf(filename, "%s_CutGrid.pos", v->Name); EndView(View, v->NbTimeStep, filename, name); delete [] VALUES1; delete [] VALUES2; delete [] VALUES3; delete [] VALUES4; return View; } Post_View *GMSH_CutGridPlugin::execute(Post_View * v) { int iView = (int)CutGridOptions_Number[11].def; if(iView < 0) iView = v ? v->Index : 0; if(!List_Pointer_Test(CTX.post.list, iView)) { Msg(GERROR, "View[%d] does not exist", iView); return v; } Post_View *v1 = *(Post_View **)List_Pointer(CTX.post.list, iView); return GenerateView(v1); }