// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle // // See the LICENSE.txt file for license information. Please report all // bugs and problems to the public mailing list <gmsh@geuz.org>. #include "GmshMessage.h" #include "Geo.h" #include "ExtrudeParams.h" smooth_data* ExtrudeParams::normals[2] = {0, 0}; std::vector<SPoint3> ExtrudeParams::normalsCoherence; // Added by Trevor Strickler to scale last layer size locally // If one section of the boundary layer index = 0 or 1 is not supposed to be // scaled...that section's normals will have scaleFactor = 1.0 (exactly 1.0 to all sig figs) // ...however, if that non-scaled // section borders a scaled section, the boundary normals will extrude consistently (an // average of scaled and non-scaled heights). bool ExtrudeParams::calcLayerScaleFactor[2] = {0,0}; // Added by Trevor Strickler static void Projette(double p[3], double mat[3][3]) { double X = p[0] * mat[0][0] + p[1] * mat[0][1] + p[2] * mat[0][2]; double Y = p[0] * mat[1][0] + p[1] * mat[1][1] + p[2] * mat[1][2]; double Z = p[0] * mat[2][0] + p[1] * mat[2][1] + p[2] * mat[2][2]; p[0] = X; p[1] = Y; p[2] = Z; } ExtrudeParams::ExtrudeParams(int ModeEx) { geo.Mode = ModeEx; geo.Source = -1; mesh.ExtrudeMesh = false; mesh.Recombine = false; mesh.QuadToTri = NO_QUADTRI; //added by Trevor Strickler 07/07/2013 (determines if a layer is scaled by source grid size (1) or not (0))...only meant for boundary layers mesh.ScaleLast = false; mesh.ViewIndex = -1; mesh.BoundaryLayerIndex = 0; } void ExtrudeParams::fill(int type, double T0, double T1, double T2, double A0, double A1, double A2, double X0, double X1, double X2, double angle) { geo.trans[0] = T0; geo.trans[1] = T1; geo.trans[2] = T2; geo.axe[0] = A0; geo.axe[1] = A1; geo.axe[2] = A2; geo.pt[0] = X0; geo.pt[1] = X1; geo.pt[2] = X2; geo.angle = angle; geo.Type = type; } void ExtrudeParams::Extrude(int iLayer, int iElemLayer, double &x, double &y, double &z) { double t = u(iLayer, iElemLayer); // Trevor Strickler (this definitely relies on fixing lateral boundary // extruded surfaces if mesh.ScaleLast is changed by ReplaceDuplicates. This // is done in BoundaryLayers.cpp right now. if(geo.Type == BOUNDARY_LAYER && iLayer == mesh.NbLayer-1 && mesh.BoundaryLayerIndex >= 0 && mesh.BoundaryLayerIndex <= 1 && calcLayerScaleFactor[mesh.BoundaryLayerIndex] && normals[mesh.BoundaryLayerIndex]){ double scale = 1.0; normals[mesh.BoundaryLayerIndex]->get_scale(x, y, z, &scale); if(fabs(scale-1.0) <= xyzv::eps) scale = 1.0; else{ if(mesh.NbLayer <= 1) t = t * scale; else t = (t-mesh.hLayer[mesh.NbLayer-2])*scale + mesh.hLayer[mesh.NbLayer-2]; } } Extrude(t, x, y, z); } void ExtrudeParams::Rotate(double matr[3][3]) { Projette(geo.trans, matr); Projette(geo.axe, matr); Projette(geo.pt, matr); geo.angle = -geo.angle; } void ExtrudeParams::Extrude(double t, double &x, double &y, double &z) { double dx, dy, dz, angle; double n[3] = {0., 0., 0.}; switch (geo.Type) { case TRANSLATE: dx = geo.trans[0] * t; dy = geo.trans[1] * t; dz = geo.trans[2] * t; x += dx; y += dy; z += dz; break; case ROTATE: angle = geo.angle; geo.angle = geo.angle * t; ProtudeXYZ(x, y, z, this); geo.angle = angle; break; case TRANSLATE_ROTATE: angle = geo.angle; geo.angle = geo.angle * t; ProtudeXYZ(x, y, z, this); geo.angle = angle; dx = geo.trans[0] * t; dy = geo.trans[1] * t; dz = geo.trans[2] * t; x += dx; y += dy; z += dz; break; case BOUNDARY_LAYER: if(mesh.BoundaryLayerIndex >= 0 && mesh.BoundaryLayerIndex <= 1 && normals[mesh.BoundaryLayerIndex]) normals[mesh.BoundaryLayerIndex]->get(x, y, z, 3, n); x += n[0] * t; y += n[1] * t; z += n[2] * t; break; default: Msg::Error("Unknown extrusion type"); break; } } double ExtrudeParams::u(int iLayer, int iElemLayer) { double t0, t1; if(!iLayer) { t0 = 0.0; t1 = mesh.hLayer[0]; } else { t0 = mesh.hLayer[iLayer - 1]; t1 = mesh.hLayer[iLayer]; } double t = (double)iElemLayer / (double)mesh.NbElmLayer[iLayer]; return t0 + t * (t1 - t0); }