Skip to content
Snippets Groups Projects
Select Git revision
  • d6a6334540822bdbc5774522240e8b5655406162
  • master default protected
  • alphashapes
  • quadMeshingTools
  • cygwin_conv_path
  • macos_arm64
  • add-transfiniteautomatic-to-geo
  • patch_releases_4_10
  • HierarchicalHDiv
  • isuruf-master-patch-63355
  • hyperbolic
  • hexdom
  • hxt_update
  • jf
  • 1618-pythonocc-and-gmsh-api-integration
  • octreeSizeField
  • hexbl
  • alignIrregularVertices
  • getEdges
  • patch_releases_4_8
  • isuruf-master-patch-51992
  • gmsh_4_11_0
  • gmsh_4_10_5
  • gmsh_4_10_4
  • gmsh_4_10_3
  • gmsh_4_10_2
  • gmsh_4_10_1
  • gmsh_4_10_0
  • gmsh_4_9_5
  • gmsh_4_9_4
  • gmsh_4_9_3
  • gmsh_4_9_2
  • gmsh_4_9_1
  • gmsh_4_9_0
  • gmsh_4_8_4
  • gmsh_4_8_3
  • gmsh_4_8_2
  • gmsh_4_8_1
  • gmsh_4_8_0
  • gmsh_4_7_1
  • gmsh_4_7_0
41 results

OptHomRun.cpp

Blame
  • Forked from gmsh / gmsh
    Source project has a limited visibility.
    Iso.cpp 11.78 KiB
    // $Id: Iso.cpp,v 1.28 2004-07-02 23:15:04 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 "Gmsh.h"
    #include "GmshUI.h"
    #include "Geo.h"
    #include "Mesh.h"
    #include "Draw.h"
    #include "Context.h"
    #include "Views.h"
    #include "Numeric.h"
    
    extern Context_T CTX;
    
    // Iso line computation for triangles.
    
    void CutTriangle1D(double *X, double *Y, double *Z, double *Val,
                       double V, double *Xp, double *Yp, double *Zp, int *nb)
    {
      *nb = 0;
      if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 0, 1, &Xp[*nb], &Yp[*nb], &Zp[*nb]);
        (*nb)++;
      }
      if((Val[0] >= V && Val[2] <= V) || (Val[2] >= V && Val[0] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 0, 2, &Xp[*nb], &Yp[*nb], &Zp[*nb]);
        (*nb)++;
      }
      if((Val[1] >= V && Val[2] <= V) || (Val[2] >= V && Val[1] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 1, 2, &Xp[*nb], &Yp[*nb], &Zp[*nb]);
        (*nb)++;
      }
    }
    
    // Contour computation for triangles
    
    void CutTriangle2D(double *X, double *Y, double *Z, double *Val,
    		   double V1, double V2, double *Xp2, double *Yp2,
    		   double *Zp2, int *Np2, double *Vp2)
    {
      int i, io[3], j, iot, Np, Fl;
      double Xp[10], Yp[10], Zp[10], Vp[10];
    
      *Np2 = 0;
    
      for(i = 0; i < 3; i++)
        io[i] = i;
    
      for(i = 0; i < 2; i++) {
        for(j = i + 1; j < 3; j++) {
          if(Val[io[i]] > Val[io[j]]) {
            iot = io[i];
            io[i] = io[j];
            io[j] = iot;
          }
        }
      }
    
      // io[] contains an indexing of nodes such that Val[io[i]] > Val[io[j]] if i > j
    
      if(Val[io[0]] > V2)
        return;
      if(Val[io[2]] < V1)
        return;
    
      if(V1 <= Val[io[0]] && Val[io[2]] <= V2) {
        for(i = 0; i < 3; i++) {
          Vp2[i] = Val[i];
          Xp2[i] = X[i];
          Yp2[i] = Y[i];
          Zp2[i] = Z[i];
        }
        *Np2 = 3;
        return;
      }
    
      Np = 0;
      if(V1 <= Val[io[0]]) {
        Vp[Np] = Val[io[0]];
        Xp[Np] = X[io[0]];
        Yp[Np] = Y[io[0]];
        Zp[Np] = Z[io[0]];
        Np++;
        Fl = 1;
      }
      else if(Val[io[0]] < V1 && V1 <= Val[io[1]]) {
        Vp[Np] = V1;
        InterpolateIso(X, Y, Z, Val, V1, io[0], io[2], &Xp[Np], &Yp[Np], &Zp[Np]);
        Np++;
        Vp[Np] = V1;
        InterpolateIso(X, Y, Z, Val, V1, io[0], io[1], &Xp[Np], &Yp[Np], &Zp[Np]);
        Np++;
        Fl = 1;
      }
      else {
        Vp[Np] = V1;
        InterpolateIso(X, Y, Z, Val, V1, io[0], io[2], &Xp[Np], &Yp[Np], &Zp[Np]);
        Np++;
        Vp[Np] = V1;
        InterpolateIso(X, Y, Z, Val, V1, io[1], io[2], &Xp[Np], &Yp[Np], &Zp[Np]);
        Np++;
        Fl = 0;
      }
    
      if(V2 == Val[io[0]]) {
        return;
      }
      else if((Val[io[0]] < V2) && (V2 < Val[io[1]])) {
        Vp[Np] = V2;
        InterpolateIso(X, Y, Z, Val, V2, io[0], io[1], &Xp[Np], &Yp[Np], &Zp[Np]);
        Np++;
        Vp[Np] = V2;
        InterpolateIso(X, Y, Z, Val, V2, io[0], io[2], &Xp[Np], &Yp[Np], &Zp[Np]);
        Np++;
      }
      else if(V2 < Val[io[2]]) {
        if(Fl) {
          Vp[Np] = Val[io[1]];
          Xp[Np] = X[io[1]];
          Yp[Np] = Y[io[1]];
          Zp[Np] = Z[io[1]];
          Np++;
        }
        Vp[Np] = V2;
        InterpolateIso(X, Y, Z, Val, V2, io[1], io[2], &Xp[Np], &Yp[Np], &Zp[Np]);
        Np++;
        Vp[Np] = V2;
        InterpolateIso(X, Y, Z, Val, V2, io[0], io[2], &Xp[Np], &Yp[Np], &Zp[Np]);
        Np++;
      }
      else {
        if(Fl) {
          Vp[Np] = Val[io[1]];
          Xp[Np] = X[io[1]];
          Yp[Np] = Y[io[1]];
          Zp[Np] = Z[io[1]];
          Np++;
        }
        Vp[Np] = Val[io[2]];
        Xp[Np] = X[io[2]];
        Yp[Np] = Y[io[2]];
        Zp[Np] = Z[io[2]];
        Np++;
      }
    
      Vp2[0] = Vp[0];
      Xp2[0] = Xp[0];
      Yp2[0] = Yp[0];
      Zp2[0] = Zp[0];
      *Np2 = 1;
    
      for(i = 1; i < Np; i++) {
        if((Xp[i] != Xp2[(*Np2) - 1]) || (Yp[i] != Yp2[(*Np2) - 1]) || 
           (Zp[i] != Zp2[(*Np2) - 1])) {
          Vp2[*Np2] = Vp[i];
          Xp2[*Np2] = Xp[i];
          Yp2[*Np2] = Yp[i];
          Zp2[*Np2] = Zp[i];
          (*Np2)++;
        }
      }
    
      if(Xp2[0] == Xp2[(*Np2) - 1] && Yp2[0] == Yp2[(*Np2) - 1] && 
         Zp2[0] == Zp2[(*Np2) - 1]) {
        (*Np2)--;
      }
    
      // check and fix orientation
      double in1[3] = { X[1]-X[0], Y[1]-Y[0], Z[1]-Z[0]};
      double in2[3] = { X[2]-X[0], Y[2]-Y[0], Z[2]-Z[0]};
      double inn[3];
      prodve(in1, in2, inn);
      double out1[3] = { Xp2[1]-Xp2[0], Yp2[1]-Yp2[0], Zp2[1]-Zp2[0]};
      double out2[3] = { Xp2[2]-Xp2[0], Yp2[2]-Yp2[0], Zp2[2]-Zp2[0]};
      double outn[3];
      prodve(out1, out2, outn);
      double res;
      prosca(inn, outn, &res);
      if(res < 0){
        for(i = 0; i < *Np2; i++){
          Vp[i] = Vp2[*Np2-i-1];
          Xp[i] = Xp2[*Np2-i-1];
          Yp[i] = Yp2[*Np2-i-1];
          Zp[i] = Zp2[*Np2-i-1];
        }
        for(i = 0; i < *Np2; i++){
          Vp2[i] = Vp[i];
          Xp2[i] = Xp[i];
          Yp2[i] = Yp[i];
          Zp2[i] = Zp[i];
        }
      }
    }
    
    // Iso for lines
    
    void CutLine0D(double *X, double *Y, double *Z, double *Val,
                   double V, double *Xp, double *Yp, double *Zp, int *nb)
    {
      *nb = 0;
    
      if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 0, 1, Xp, Yp, Zp);
        *nb = 1;
      }
    }
    
    void CutLine1D(double *X, double *Y, double *Z, double *Val,
                   double V1, double V2, double *Xp2, double *Yp2, double *Zp2,
                   int *Np2, double *Vp2)
    {
      int i, io[2];
    
      if(Val[0] < Val[1]) {
        io[0] = 0;
        io[1] = 1;
      }
      else {
        io[0] = 1;
        io[1] = 0;
      }
    
      // io[] contains an indexing of nodes such that Val[io[i]] > Val[io[j]] if i > j
    
      *Np2 = 0;
    
      if(Val[io[0]] > V2)
        return;
      if(Val[io[1]] < V1)
        return;
    
      *Np2 = 2;
    
      if(V1 <= Val[io[0]] && Val[io[1]] <= V2) {
        for(i = 0; i < 2; i++) {
          Vp2[i] = Val[i];
          Xp2[i] = X[i];
          Yp2[i] = Y[i];
          Zp2[i] = Z[i];
        }
        return;
      }
    
      if(V1 <= Val[io[0]]) {
        Vp2[0] = Val[io[0]];
        Xp2[0] = X[io[0]];
        Yp2[0] = Y[io[0]];
        Zp2[0] = Z[io[0]];
      }
      else {
        Vp2[0] = V1;
        InterpolateIso(X, Y, Z, Val, V1, io[0], io[1], &Xp2[0], &Yp2[0], &Zp2[0]);
      }
    
      if(V2 >= Val[io[1]]) {
        Vp2[1] = Val[io[1]];
        Xp2[1] = X[io[1]];
        Yp2[1] = Y[io[1]];
        Zp2[1] = Z[io[1]];
      }
      else {
        Vp2[1] = V2;
        InterpolateIso(X, Y, Z, Val, V2, io[0], io[1], &Xp2[1], &Yp2[1], &Zp2[1]);
      }
    }
    
    // compute the gradient of a linear interpolation in a tetrahedron
    
    void EnhanceSimplexPolygon(Post_View * View, int nb,    // nb of points in polygon 
                               double *Xp,  // x positions
                               double *Yp,  // y positions
                               double *Zp,  // z positions
                               double *Valp,        // values at points
                               double *X,   // x positions of the simplex
                               double *Y,   // y positions of the simplex
                               double *Z,   // z posistions of the simplex
                               double *Val, // values at simplex points
                               double *norms,       // output : normals at points
                               int preproNormals    // do we compute normals or do we get them
      )
    {
      /*
         3 possibilities for quads
         -) 0,2,5,3
         -) 0,1,5,4
         -) 1,2,4,3
         in all cases, simply invert the 2 last ones
         for having the quads ordered      
       */
      int i;
      double Xpi[6], Ypi[6], Zpi[6];
    
      if(nb == 4) {
        double xx = Xp[3];
        double yy = Yp[3];
        double zz = Zp[3];
        Xp[3] = Xp[2];
        Yp[3] = Yp[2];
        Zp[3] = Zp[2];
        Xp[2] = xx;
        Yp[2] = yy;
        Zp[2] = zz;
      }
    
      /*
         for having a nice isosurface, we should have n . grad v > 0
         n = normal to the polygon
         v = unknown field we wanna draw
       */
    
      double v1[3] = { Xp[2] - Xp[0], Yp[2] - Yp[0], Zp[2] - Zp[0] };
      double v2[3] = { Xp[1] - Xp[0], Yp[1] - Yp[0], Zp[1] - Zp[0] };
      double gr[3];
      double n[3], xx;
      prodve(v1, v2, n);
      norme(n);
      gradSimplex(X, Y, Z, Val, gr);
      prosca(gr, n, &xx);
    
      if(xx > 0) {
        for(i = 0; i < nb; i++) {
          Xpi[i] = Xp[i];
          Ypi[i] = Yp[i];
          Zpi[i] = Zp[i];
        }
        for(i = 0; i < nb; i++) {
          Xp[i] = Xpi[nb - i - 1];
          Yp[i] = Ypi[nb - i - 1];
          Zp[i] = Zpi[nb - i - 1];
        }
      }
      else {
        n[0] = -n[0];
        n[1] = -n[1];
        n[2] = -n[2];
      }
    
      if(View->SmoothNormals) {
        if(preproNormals) {
          for(i = 0; i < nb; i++) {
            View->add_normal(Xp[i], Yp[i], Zp[i], n[0], n[1], n[2]);
          }
          return;
        }
        else {
          for(i = 0; i < nb; i++) {
            norms[3 * i] = n[0];
            norms[3 * i + 1] = n[1];
            norms[3 * i + 2] = n[2];
            View->get_normal
    	  (Xp[i], Yp[i], Zp[i], norms[3 * i], norms[3 * i + 1], norms[3 * i + 2]);
          }
        }
      }
      else {
        for(i = 0; i < nb; i++) {
          norms[3 * i] = n[0];
          norms[3 * i + 1] = n[1];
          norms[3 * i + 2] = n[2];
        }
      }
    }
    
    void IsoSimplex(Post_View * View, int preproNormals,
                    double *X, double *Y, double *Z, double *Val,
                    double V, unsigned int color)
    {
      int nb;
      double Xp[6], Yp[6], Zp[6], PVals[6];
      double norms[12];
    
      nb = 0;
      if((Val[0] >= V && Val[1] <= V) || (Val[1] >= V && Val[0] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 0, 1, &Xp[nb], &Yp[nb], &Zp[nb]);
        nb++;
      }
      if((Val[0] >= V && Val[2] <= V) || (Val[2] >= V && Val[0] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 0, 2, &Xp[nb], &Yp[nb], &Zp[nb]);
        nb++;
      }
      if((Val[0] >= V && Val[3] <= V) || (Val[3] >= V && Val[0] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 0, 3, &Xp[nb], &Yp[nb], &Zp[nb]);
        nb++;
      }
      if((Val[1] >= V && Val[2] <= V) || (Val[2] >= V && Val[1] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 1, 2, &Xp[nb], &Yp[nb], &Zp[nb]);
        nb++;
      }
      if((Val[1] >= V && Val[3] <= V) || (Val[3] >= V && Val[1] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 1, 3, &Xp[nb], &Yp[nb], &Zp[nb]);
        nb++;
      }
      if((Val[2] >= V && Val[3] <= V) || (Val[3] >= V && Val[2] <= V)) {
        InterpolateIso(X, Y, Z, Val, V, 2, 3, &Xp[nb], &Yp[nb], &Zp[nb]);
        nb++;
      }
    
      if(nb < 3 || nb > 4)
        return;
    
      EnhanceSimplexPolygon(View, nb, Xp, Yp, Zp, PVals, X, Y, Z, Val, norms,
                            preproNormals);
    
      if(preproNormals)
        return;
    
      if(View->TriVertexArray && View->TriVertexArray->fill){
        for(int i = 2; i < nb; i++){
          View->TriVertexArray->add(Xp[0] + View->Raise[0] * V,
    				Yp[0] + View->Raise[1] * V,
    				Zp[0] + View->Raise[2] * V,
    				norms[0], norms[1], norms[2], color);
          View->TriVertexArray->add(Xp[i-1] + View->Raise[0] * V,
    				Yp[i-1] + View->Raise[1] * V,
    				Zp[i-1] + View->Raise[2] * V,
    				norms[3*(i-1)], norms[3*(i-1)+1], norms[3*(i-1)+2], color);
          View->TriVertexArray->add(Xp[i] + View->Raise[0] * V,
    				Yp[i] + View->Raise[1] * V,
    				Zp[i] + View->Raise[2] * V,
    				norms[3*i], norms[3*i+1], norms[3*i+2], color);
          View->TriVertexArray->num++;
        }
      }
      else{
        if(View->Light) glEnable(GL_LIGHTING);
        glColor4ubv((GLubyte *) & color);
        glBegin(GL_TRIANGLES);
        for(int i = 2; i < nb; i++){
          if(View->Light) glNormal3dv(&norms[0]);
          glVertex3d(Xp[0] + View->Raise[0] * V, 
    		 Yp[0] + View->Raise[1] * V, 
    		 Zp[0] + View->Raise[2] * V);
          if(View->Light) glNormal3dv(&norms[3*(i-1)]);
          glVertex3d(Xp[i-1] + View->Raise[0] * V, 
    		 Yp[i-1] + View->Raise[1] * V, 
    		 Zp[i-1] + View->Raise[2] * V);
          if(View->Light) glNormal3dv(&norms[3*i]);
          glVertex3d(Xp[i] + View->Raise[0] * V, 
    		 Yp[i] + View->Raise[1] * V, 
    		 Zp[i] + View->Raise[2] * V);
        }
        glEnd();
        glDisable(GL_LIGHTING);
      }
    }