Пример #1
0
void carveHole(std::vector<T*> &elements, double distance, ANNkd_tree *kdtree)
{
  // delete all elements that have at least one vertex closer than
  // 'distance' from the carving surface vertices
  ANNidxArray index = new ANNidx[1];
  ANNdistArray dist = new ANNdist[1];
  std::vector<T*> temp;
  for(unsigned int i = 0; i < elements.size(); i++){
    for(int j = 0; j < elements[i]->getNumVertices(); j++){
      MVertex *v = elements[i]->getVertex(j);
      double xyz[3] = {v->x(), v->y(), v->z()};
      kdtree->annkSearch(xyz, 1, index, dist);
      double d = sqrt(dist[0]);
      if(d < distance){
        delete elements[i];
        break;
      }
      else if(j == elements[i]->getNumVertices() - 1){
        temp.push_back(elements[i]);
      }
    }
  }
  elements = temp;
  delete [] index;
  delete [] dist;
}
Пример #2
0
void copyMesh(GEdge *from, GEdge *to, int direction)
{  
  Range<double> u_bounds = from->parBounds(0);
  double u_min = u_bounds.low();
  double u_max = u_bounds.high();

  Range<double> to_u_bounds = to->parBounds(0);
  double to_u_min = to_u_bounds.low();
  double to_u_max = to_u_bounds.high();

  for(unsigned int i = 0; i < from->mesh_vertices.size(); i++){
    int index = (direction < 0) ? (from->mesh_vertices.size() - 1 - i) : i;
    MVertex *v = from->mesh_vertices[index];
    double u; v->getParameter(0, u);
    double newu = (direction > 0) ? (u-u_min+to_u_min) : (u_max-u+to_u_min);
    GPoint gp = to->point(newu);
    MEdgeVertex *vv = new MEdgeVertex(gp.x(), gp.y(), gp.z(), to, newu);
    to->mesh_vertices.push_back(vv);
    to->correspondingVertices[vv] = v;
  }
  for(unsigned int i = 0; i < to->mesh_vertices.size() + 1; i++){
    MVertex *v0 = (i == 0) ?
      to->getBeginVertex()->mesh_vertices[0] : to->mesh_vertices[i - 1];
    MVertex *v1 = (i == to->mesh_vertices.size()) ?
      to->getEndVertex()->mesh_vertices[0] : to->mesh_vertices[i];
    to->lines.push_back(new MLine(v0, v1));
  }
}
Пример #3
0
double approximationError(simpleFunction<double> &f, MElement *element)
{
  std::vector<double> VALS(element->getNumVertices());

  for(std::size_t i = 0; i < element->getNumVertices(); i++) {
    MVertex *v = element->getVertex(i);
    VALS[i] = f(v->x(), v->y(), v->z());
  }

  int npts;
  IntPt *pts;
  element->getIntegrationPoints(2 * element->getPolynomialOrder() + 2, &npts,
                                &pts);
  double errSqr = 0.0;
  for(int k = 0; k < npts; k++) {
    const double u = pts[k].pt[0];
    const double v = pts[k].pt[1];
    const double w = pts[k].pt[2];
    SPoint3 p;
    element->pnt(u, v, w, p);
    const double Jac = element->getJacobianDeterminant(u, v, w);
    const double C = element->interpolate(&VALS[0], u, v, w);
    const double F = f(p.x(), p.y(), p.z());
    errSqr += pts[k].weight * Jac * std::pow(C - F, 2);
  }
  return std::sqrt(errSqr);
}
Пример #4
0
void frameFieldBackgroundMesh2D::exportCrossField(const std::string &filename)
{
    FILE *f = Fopen(filename.c_str(), "w");
    if(!f) {
        Msg::Error("Could not open file '%s'", filename.c_str());
        return;
    }
    fprintf(f,"View \"Cross Field\"{\n");
    std::vector<double> deltas(2);
    deltas[0] = 0.;
    deltas[1] = M_PI;

    for (std::vector<MVertex*>::iterator it = beginvertices(); it!=endvertices(); it++) {
        MVertex *v = *it;
        double angle_current = angle(v);
        GPoint p = get_GPoint_from_MVertex(v);
        for (int i=0; i<2; i++) {
            Pair<SVector3, SVector3> dirs = compute_crossfield_directions(v->x(),v->y(),angle_current+deltas[i]);
            fprintf(f,"VP(%g,%g,%g) {%g,%g,%g};\n",p.x(),p.y(),p.z(),dirs.first()[0], dirs.first()[1], dirs.first()[2]);
            fprintf(f,"VP(%g,%g,%g) {%g,%g,%g};\n",p.x(),p.y(),p.z(),dirs.second()[0], dirs.second()[1], dirs.second()[2]);
        }
    }
    fprintf(f,"};\n");
    fclose(f);
}
Пример #5
0
// use real space + projection at the end
static double _relocateVertex2(GFace *gf, MVertex *ver,
                               const std::vector<MElement *> &lt, double tol)
{
  SPoint3 p1(0, 0, 0);
  std::size_t counter = 0;
  for(std::size_t i = 0; i < lt.size(); i++) {
    for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) {
      MVertex *v = lt[i]->getVertex(j);
      p1 += SPoint3(v->x(), v->y(), v->z());
      counter++;
    }
  }
  p1 *= 1.0 / (double)counter;
  SPoint3 p2(ver->x(), ver->y(), ver->z());
  double worst;
  double xi = Maximize_Quality_Golden_Section(ver, gf, p1, p2, lt, tol, worst);

  SPoint3 p = p1 * (1 - xi) + p2 * xi;
  double initialGuess[2] = {0, 0};
  GPoint pp = gf->closestPoint(p, initialGuess);
  if(!pp.succeeded()) return 2.0;
  ver->x() = pp.x();
  ver->y() = pp.y();
  ver->z() = pp.z();
  return worst;
}
Пример #6
0
static int getExtrudedVertices(MElement *ele, ExtrudeParams *ep, int j, int k,
                               MVertexRTree &pos, std::vector<MVertex*> &verts)
{
  double x[8], y[8], z[8];
  int n = ele->getNumVertices();
  for(int p = 0; p < n; p++){
    MVertex *v = ele->getVertex(p);
    x[p] = x[p + n] = v->x();
    y[p] = y[p + n] = v->y();
    z[p] = z[p + n] = v->z();
  }
  for(int p = 0; p < n; p++){
    ep->Extrude(j, k, x[p], y[p], z[p]);
    ep->Extrude(j, k + 1, x[p + n], y[p + n], z[p + n]);
  }
  for(int p = 0; p < 2 * n; p++){
    MVertex *tmp = pos.find(x[p], y[p], z[p]);
    if(!tmp)
      Msg::Error("Could not find extruded vertex (%.16g, %.16g, %.16g)",
                 x[p], y[p], z[p]);
    else
      verts.push_back(tmp);
  }
  return verts.size();
}
Пример #7
0
SOrientedBoundingBox GEdge::getOBB()
{
  if (!_obb) {
    std::vector<SPoint3> vertices;
    if(getNumMeshVertices() > 0) {
      int N = getNumMeshVertices();
      for (int i = 0; i < N; i++) {
        MVertex* mv = getMeshVertex(i);
        vertices.push_back(mv->point());
      }
      // Don't forget to add the first and last vertices...
      SPoint3 pt1(getBeginVertex()->x(), getBeginVertex()->y(), getBeginVertex()->z());
      SPoint3 pt2(getEndVertex()->x(), getEndVertex()->y(), getEndVertex()->z());
      vertices.push_back(pt1);
      vertices.push_back(pt2);
    }
    else if(geomType() != DiscreteCurve && geomType() != BoundaryLayerCurve){
      Range<double> tr = this->parBounds(0);
      // N can be choosen arbitrarily, but 10 points seems reasonable
      int N = 10;
      for (int i = 0; i < N; i++) {
        double t = tr.low() + (double)i / (double)(N - 1) * (tr.high() - tr.low());
        GPoint p = point(t);
        SPoint3 pt(p.x(), p.y(), p.z());
        vertices.push_back(pt);
      }
    }
    else {
      SPoint3 dummy(0, 0, 0);
      vertices.push_back(dummy);
    }
    _obb = SOrientedBoundingBox::buildOBB(vertices);
  }
  return SOrientedBoundingBox(_obb);
}
Пример #8
0
bool Mesh::bndDistAndGradients(int iEl, double &f , std::vector<double> &gradF, double eps)
{
  MElement *element = _el[iEl];
  f = 0.;
  // dommage ;-)
  if (element->getDim() != 2)
    return false;

  int currentId = 0;
  std::vector<int> vertex2param(element->getNumVertices());
  for (size_t i = 0; i < element->getNumVertices(); ++i) {
    if (_el2FV[iEl][i] >= 0) {
      vertex2param[i] = currentId;
      currentId += _nPCFV[_el2FV[iEl][i]];
    }
    else
      vertex2param[i] = -1;
  }
  gradF.clear();
  gradF.resize(currentId, 0.);

  const nodalBasis &elbasis = *element->getFunctionSpace();
  bool edgeFound = false;
  for (int iEdge = 0; iEdge < element->getNumEdges(); ++iEdge) {
    int clId = elbasis.getClosureId(iEdge, 1);
    const std::vector<int> &closure = elbasis.closures[clId];
    std::vector<MVertex *> vertices;
    GEdge *edge = NULL;
    for (size_t i = 0; i < closure.size(); ++i) {
      MVertex *v = element->getVertex(closure[i]);
      vertices.push_back(v);
      // only valid in 2D
      if ((int)i >= 2 && v->onWhat() && v->onWhat()->dim() == 1) {
        edge = v->onWhat()->cast2Edge();
      }
    }
    if (edge) {
      edgeFound = true;
      std::vector<double> localgrad;
      std::vector<SPoint3> nodes(closure.size());
      std::vector<double> params(closure.size());
      std::vector<bool> onedge(closure.size());
      for (size_t i = 0; i < closure.size(); ++i) {
        nodes[i] = _xyz[_el2V[iEl][closure[i]]];
        onedge[i] = element->getVertex(closure[i])->onWhat() == edge && _el2FV[iEl][closure[i]] >= 0;
        if (onedge[i]) {
          params[i] = _uvw[_el2FV[iEl][closure[i]]].x();
        }else
          reparamMeshVertexOnEdge(element->getVertex(closure[i]), edge, params[i]);
      }
      f += computeBndDistAndGradient(edge, params, vertices, *BasisFactory::getNodalBasis(elbasis.getClosureType(clId)), nodes, onedge, localgrad, eps);
      for (size_t i = 0; i < closure.size(); ++i) {
        if (onedge[i])
	  gradF[vertex2param[closure[i]]] += localgrad[i];
      }
    }
  }
  return edgeFound;
}
Пример #9
0
SOrientedBoundingBox GRegion::getOBB()
{
  if (!_obb) {
    std::vector<SPoint3> vertices;
    std::list<GFace*> b_faces = faces();
    for (std::list<GFace*>::iterator b_face = b_faces.begin();
         b_face != b_faces.end(); b_face++) {
      if((*b_face)->getNumMeshVertices() > 0) {
        int N = (*b_face)->getNumMeshVertices();
        for (int i = 0; i < N; i++) {
          MVertex* mv = (*b_face)->getMeshVertex(i);
          vertices.push_back(mv->point());
        }
        std::list<GEdge*> eds = (*b_face)->edges();
        for(std::list<GEdge*>::iterator ed = eds.begin(); ed != eds.end(); ed++) {
          int N2 = (*ed)->getNumMeshVertices();
          for (int i = 0; i < N2; i++) {
            MVertex* mv = (*ed)->getMeshVertex(i);
            vertices.push_back(mv->point());
          }
          // Don't forget to add the first and last vertices...
          SPoint3 pt1((*ed)->getBeginVertex()->x(),
                      (*ed)->getBeginVertex()->y(),
                      (*ed)->getBeginVertex()->z());
          SPoint3 pt2((*ed)->getEndVertex()->x(),
                      (*ed)->getEndVertex()->y(),
                      (*ed)->getEndVertex()->z());
          vertices.push_back(pt1);
          vertices.push_back(pt2);
        }
      }
      else if ((*b_face)->buildSTLTriangulation()) {
        for (unsigned int i = 0; i < (*b_face)->stl_vertices.size(); i++){
          GPoint p = (*b_face)->point((*b_face)->stl_vertices[i]);
          vertices.push_back(SPoint3(p.x(), p.y(), p.z()));
        }
      }
      else {
        int N = 10;
        std::list<GEdge*> b_edges = (*b_face)->edges();
        for (std::list<GEdge*>::iterator b_edge = b_edges.begin();
             b_edge != b_edges.end(); b_edge++) {
          Range<double> tr = (*b_edge)->parBounds(0);
          for (int j = 0; j < N; j++) {
            double t = tr.low() + (double)j / (double)(N - 1) * (tr.high() - tr.low());
            GPoint p = (*b_edge)->point(t);
            SPoint3 pt(p.x(), p.y(), p.z());
            vertices.push_back(pt);
          }
        }
      }
    }
    _obb = SOrientedBoundingBox::buildOBB(vertices);
  }
  return SOrientedBoundingBox(_obb);
}
Пример #10
0
int GModel::writeMAIL(const std::string &name, bool saveAll, double scalingFactor)
{
  // CEA triangulation (.mail format) for Eric Darrigrand. Note that
  // we currently don't save the edges of the triangulation (the last
  // part of the file).
  FILE *fp = Fopen(name.c_str(), "w");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  if(noPhysicalGroups()) saveAll = true;

  int numVertices = indexMeshVertices(saveAll), numTriangles = 0;
  for(fiter it = firstFace(); it != lastFace(); ++it)
    if(saveAll || (*it)->physicals.size())
      numTriangles += (*it)->triangles.size();

  fprintf(fp, " %d %d\n", numVertices, numTriangles);

  std::vector<GEntity*> entities;
  getEntities(entities);
  for(unsigned int i = 0; i < entities.size(); i++){
    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
      MVertex *v = entities[i]->mesh_vertices[j];
      fprintf(fp, " %19.10E %19.10E %19.10E\n", v->x() * scalingFactor,
              v->y() * scalingFactor, v->z() * scalingFactor);
    }
  }

  for(fiter it = firstFace(); it != lastFace(); ++it){
    if(saveAll || (*it)->physicals.size()){
      for(unsigned int i = 0; i < (*it)->triangles.size(); i++){
        MTriangle *t = (*it)->triangles[i];
        fprintf(fp, " %d %d %d\n", t->getVertex(0)->getIndex(),
                t->getVertex(1)->getIndex(), t->getVertex(2)->getIndex());
      }
    }
  }

  // TODO write edges (with signs)
  for(fiter it = firstFace(); it != lastFace(); ++it){
    if(saveAll || (*it)->physicals.size()){
      for(unsigned int i = 0; i < (*it)->triangles.size(); i++){
        //MTriangle *t = (*it)->triangles[i];
        fprintf(fp, " %d %d %d\n", 0, 0, 0);
      }
    }
  }

  fclose(fp);
  return 1;
}
Пример #11
0
void highOrderTools::moveToStraightSidedLocation(MElement *e) const
{
  for(int i = 0; i < e->getNumVertices(); i++){
    MVertex *v = e->getVertex(i);
    std::map<MVertex*,SVector3>::const_iterator it = _straightSidedLocation.find(v);
    if (it != _straightSidedLocation.end()){
      v->x() = it->second.x();
      v->y() = it->second.y();
      v->z() = it->second.z();
    }
  }
}
Пример #12
0
std::set<MVertex *> BGMBase::get_vertices_of_maximum_dim(int dim)
{
  std::set<MVertex *> bnd_vertices;
  for(unsigned int i = 0; i < gf->getNumMeshElements(); i++) {
    MElement *element = gf->getMeshElement(i);
    for(std::size_t j = 0; j < element->getNumVertices(); j++) {
      MVertex *vertex = element->getVertex(j);
      if(vertex->onWhat()->dim() <= dim) bnd_vertices.insert(vertex);
    }
  }
  return bnd_vertices;
}
Пример #13
0
void Centerline::importFile(std::string fileName)
{
  current = GModel::current();
  std::vector<GFace*> currentFaces(current->firstFace(), current->lastFace());
  for (unsigned int i = 0; i < currentFaces.size(); i++){
    GFace *gf = currentFaces[i];
     if (gf->geomType() == GEntity::DiscreteSurface){
     	for(unsigned int j = 0; j < gf->triangles.size(); j++)
     	  triangles.push_back(gf->triangles[j]);
	if (is_cut){
	  gf->triangles.clear();
	  gf->deleteVertexArrays();
	  current->remove(gf);
	}
     }
  }

  if(triangles.empty()){
    Msg::Error("Current GModel has no triangles ...");
    return;
  }

  mod = new GModel();
  mod->load(fileName);
  mod->removeDuplicateMeshVertices(1.e-8);
  current->setAsCurrent();
  current->setVisibility(1);

  int maxN = 0.0;
  std::vector<GEdge*> modEdges(mod->firstEdge(), mod->lastEdge());
  MVertex *vin = modEdges[0]->lines[0]->getVertex(0);
  ptin = SPoint3(vin->x(), vin->y(), vin->z());
  for (unsigned int i = 0; i < modEdges.size(); i++){
    GEdge *ge = modEdges[i];
    for(unsigned int j = 0; j < ge->lines.size(); j++){
      MLine *l = ge->lines[j];
      MVertex *v0 = l->getVertex(0);
      MVertex *v1 = l->getVertex(1);
      std::map<MVertex*, int>::iterator it0 = colorp.find(v0);
      std::map<MVertex*, int>::iterator it1 = colorp.find(v1);
      if (it0 == colorp.end() || it1 == colorp.end()){
	lines.push_back(l);
	colorl.insert(std::make_pair(l, ge->tag()));
	maxN = std::max(maxN, ge->tag());
       }
      if (it0 == colorp.end()) colorp.insert(std::make_pair(v0, ge->tag()));
      if (it1 == colorp.end()) colorp.insert(std::make_pair(v1, ge->tag()));
    }
 }

  createBranches(maxN);
}
Пример #14
0
void print_nodal_info(string filename, map<MVertex*, T> &mapp)
{
  ofstream out(filename.c_str());

  out << "View \"\"{" << endl;
  for (typename map<MVertex*, T>::iterator it = mapp.begin();it!=mapp.end();it++){
    MVertex *v = it->first;
    out << "SP( " << v->x() << "," << v->y() << "," << v->z() << "){" << it->second << "};" << endl;;
  }
  out << "};" << endl;

  out.close();
}
Пример #15
0
void GEdge::relocateMeshVertices()
{
  for(unsigned int i = 0; i < mesh_vertices.size(); i++){
    MVertex *v = mesh_vertices[i];
    double u0 = 0;
    if(v->getParameter(0, u0)){
      GPoint p = point(u0);
      v->x() = p.x();
      v->y() = p.y();
      v->z() = p.z();
    }
  }
}
Пример #16
0
void Centerline::createFaces()
{
  std::vector<std::vector<MTriangle*> > faces;

  std::multimap<MEdge, MTriangle*, Less_Edge> e2e;
  for(unsigned int i = 0; i < triangles.size(); ++i)
    for(int j = 0; j < 3; j++)
      e2e.insert(std::make_pair(triangles[i]->getEdge(j), triangles[i]));
  while(!e2e.empty()){
    std::set<MTriangle*> group;
    std::set<MEdge, Less_Edge> touched;
    group.clear();
    touched.clear();
    std::multimap<MEdge, MTriangle*, Less_Edge>::iterator ite = e2e.begin();
    MEdge me = ite->first;
    while (theCut.find(me) != theCut.end()){
      ite++;
      me = ite->first;
    }
    recurConnectByMEdge(me,e2e, group, touched, theCut);
    std::vector<MTriangle*> temp;
    temp.insert(temp.begin(), group.begin(), group.end());
    faces.push_back(temp);
    for(std::set<MEdge, Less_Edge>::iterator it = touched.begin();
        it != touched.end(); ++it)
      e2e.erase(*it);
  }
  Msg::Info("Centerline: action (cutMesh) has cut surface mesh in %d faces ",
            (int)faces.size());

  //create discFaces
  for(unsigned int i = 0; i < faces.size(); ++i){
    int numF = current->getMaxElementaryNumber(2) + 1;
    discreteFace *f = new discreteFace(current, numF);
    current->add(f);
    discFaces.push_back(f);
    std::set<MVertex*> myVertices;
    std::vector<MTriangle*> myFace = faces[i];
    for(unsigned int j= 0; j< myFace.size(); j++){
      MTriangle *t = myFace[j];
      f->triangles.push_back(t);
      for (int k= 0; k< 3; k++){
	MVertex *v = t->getVertex(k);
	myVertices.insert(v);
	v->setEntity(f);
      }
    }
    f->mesh_vertices.insert(f->mesh_vertices.begin(),
  			    myVertices.begin(), myVertices.end());
  }
}
Пример #17
0
void exportMeshToDassault(GModel *gm, const std::string &fn, int dim)
{
  FILE *f = fopen(fn.c_str(),"w");

  int numVertices = gm->indexMeshVertices(true);
  std::vector<GEntity*> entities;
  gm->getEntities(entities);
  fprintf(f,"%d %d\n", numVertices, dim);
  for(unsigned int i = 0; i < entities.size(); i++)
    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
      MVertex *v = entities[i]->mesh_vertices[j];
      if (dim == 2)
        fprintf(f,"%d %22.15E %22.15E\n", v->getIndex(), v->x(), v->y());
      else if (dim == 3)
        fprintf(f,"%d %22.15E %22.15E %22.5E\n", v->getIndex(), v->x(),
                v->y(), v->z());
    }

  if (dim == 2){
    int nt = 0;
    int order  = 0;
    for (GModel::fiter itf = gm->firstFace(); itf != gm->lastFace(); ++itf){
      std::vector<MTriangle*> &tris = (*itf)->triangles;
      nt += tris.size();
      if (tris.size())order = tris[0]->getPolynomialOrder();
    }
    fprintf(f,"%d %d\n", nt,(order+1)*(order+2)/2);
    int count = 1;
    for (GModel::fiter itf = gm->firstFace(); itf != gm->lastFace(); ++itf){
      std::vector<MTriangle*> &tris = (*itf)->triangles;
      for (size_t i=0;i<tris.size();i++){
	MTriangle *t = tris[i];
	fprintf(f,"%d ", count++);
	for (int j=0;j<t->getNumVertices();j++){
	  fprintf(f,"%d ", t->getVertex(j)->getIndex());
	}
	fprintf(f,"\n");
      }
    }
    int ne = 0;
    for (GModel::eiter ite = gm->firstEdge(); ite != gm->lastEdge(); ++ite){
      std::vector<MLine*> &l = (*ite)->lines;
      ne += l.size();
    }
    fprintf(f,"%d %d\n", ne,(order+1));
    count = 1;
    for (GModel::eiter ite = gm->firstEdge(); ite != gm->lastEdge(); ++ite){
      std::vector<MLine*> &l = (*ite)->lines;
      for (size_t i=0;i<l.size();i++){
	MLine *t = l[i];
	fprintf(f,"%d ", count++);
	for (int j=0;j<t->getNumVertices();j++){
	  fprintf(f,"%d ", t->getVertex(j)->getIndex());
	}
	fprintf(f,"%d \n",(*ite)->tag());
      }
    }
  }
  fclose(f);
}
Пример #18
0
void print_nodal_info(const std::string &filename,
                      std::map<MVertex *, T> const &map)
{
  std::ofstream out(filename.c_str());

  out << "View \"\"{" << std::endl;
  for(typename std::map<MVertex *, T>::const_iterator it = map.begin();
      it != map.end(); it++) {
    MVertex *v = it->first;
    out << "SP( " << v->x() << "," << v->y() << "," << v->z() << "){"
        << it->second << "};" << std::endl;
  }
  out << "};" << std::endl;

  out.close();
}
Пример #19
0
static double _relocateVertex(GFace *gf, MVertex *ver,
                              const std::vector<MElement *> &lt, double tol)
{
  if(ver->onWhat()->dim() != 2) return 2.0;

  SPoint2 p1(0, 0);
  SPoint2 p2;
  if(ver->getParameter(0, p2[0])) {
    ver->getParameter(1, p2[1]);
  }
  else {
    return _relocateVertex2(gf, ver, lt, tol);
  }

  std::size_t counter = 0;
  for(std::size_t i = 0; i < lt.size(); i++) {
    for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) {
      MVertex *v = lt[i]->getVertex(j);
      SPoint2 pp;
      reparamMeshVertexOnFace(v, gf, pp);
      counter++;
      if(v->onWhat()->dim() == 1) {
        GEdge *ge = dynamic_cast<GEdge *>(v->onWhat());
        // do not take any chance
        if(ge->isSeam(gf)) return 2.0;
      }
      p1 += pp;
    }
  }
  p1 *= 1. / (double)counter;
  double worst;
  double xi = Maximize_Quality_Golden_Section(ver, gf, p1, p2, lt, tol, worst);
  // if (xi != 0) printf("xi = %g\n",xi);
  SPoint2 p = p1 * (1 - xi) + p2 * xi;
  GPoint pp = gf->point(p);
  if(!pp.succeeded()) return 2.0;
  ver->x() = pp.x();
  ver->y() = pp.y();
  ver->z() = pp.z();
  ver->setParameter(0, pp.u());
  ver->setParameter(1, pp.v());
  return worst;
}
Пример #20
0
void Centerline::buildKdTree()
{
  FILE * f = Fopen("myPOINTS.pos","w");
  fprintf(f, "View \"\"{\n");

  int nbPL = 3;  //10 points per line
  //int nbNodes  = (lines.size()+1) + (nbPL*lines.size());
  int nbNodes  = (colorp.size()) + (nbPL*lines.size());

  ANNpointArray nodes = annAllocPts(nbNodes, 3);
  int ind = 0;
  std::map<MVertex*, int>::iterator itp = colorp.begin();
  while (itp != colorp.end()){
     MVertex *v = itp->first;
     nodes[ind][0] = v->x();
     nodes[ind][1] = v->y();
     nodes[ind][2] = v->z();
     itp++; ind++;
  }
  for(unsigned int k = 0; k < lines.size(); ++k){
   MVertex *v0 = lines[k]->getVertex(0);
   MVertex *v1 = lines[k]->getVertex(1);
   SVector3 P0(v0->x(),v0->y(), v0->z());
   SVector3 P1(v1->x(),v1->y(), v1->z());
   for (int j= 1; j < nbPL+1; j++){
     double inc = (double)j/(double)(nbPL+1);
     SVector3 Pj = P0+inc*(P1-P0);
     nodes[ind][0] = Pj.x();
     nodes[ind][1] = Pj.y();
     nodes[ind][2] = Pj.z();
     ind++;
   }
 }

 kdtree = new ANNkd_tree(nodes, nbNodes, 3);

 for(int i = 0; i < nbNodes; ++i){
   fprintf(f, "SP(%g,%g,%g){%g};\n",
	   nodes[i][0], nodes[i][1],nodes[i][2],1.0);
 }
 fprintf(f,"};\n");
 fclose(f);
}
Пример #21
0
PView *GMSH_NewViewPlugin::execute(PView * v)
{
  if(GModel::current()->getMeshStatus() < 1){
    Msg::Error("No mesh available to create the view: please mesh your model!");
    return v ;
  }
  std::map<int, std::vector<double> > d;
  std::vector<GEntity*> entities;
  GModel::current()->getEntities(entities);
  for(unsigned int i = 0; i < entities.size(); i++){
    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
      MVertex *ve = entities[i]->mesh_vertices[j];
      d[ve->getNum()].push_back(0.);
    }
  }

  PView *vn = new PView("New view", "NodeData", GModel::current(), d);
  return vn ;
}
Пример #22
0
bool GEdge::computeDistanceFromMeshToGeometry (double &d2, double &dmax)
{
  d2 = 0.0; dmax = 0.0;
  if (geomType() == Line) return true;
  if (!lines.size())return false;
  IntPt *pts;
  int npts;
  lines[0]->getIntegrationPoints(2*lines[0]->getPolynomialOrder(), &npts, &pts);

  for (unsigned int i = 0; i < lines.size(); i++){
    MLine *l = lines[i];
    double t[256];

    for (int j=0; j< l->getNumVertices();j++){
      MVertex *v = l->getVertex(j);
      if (v->onWhat() == getBeginVertex()){
	t[j] = getLowerBound();
      }
      else if (v->onWhat() == getEndVertex()){
	t[j] = getUpperBound();
      }
      else {
	v->getParameter(0,t[j]);
      }
    }
    for (int j=0;j<npts;j++){
      SPoint3 p;
      l->pnt(pts[j].pt[0],0,0,p);
      double tinit = l->interpolate(t,pts[j].pt[0],0,0);
      GPoint pc = closestPoint(p, tinit);
      if (!pc.succeeded())continue;
      double dsq =
	(pc.x()-p.x())*(pc.x()-p.x()) +
	(pc.y()-p.y())*(pc.y()-p.y()) +
	(pc.z()-p.z())*(pc.z()-p.z());
      d2 += pts[i].weight * fabs(l->getJacobianDeterminant(pts[j].pt[0],0,0)) * dsq;
      dmax = std::max(dmax,sqrt(dsq));
    }
  }
  d2 = sqrt(d2);
  return true;
}
Пример #23
0
/*

  A vertex is connected to beams. The question
  is how many bars are rotuled

  We define 2 dofs per node

 */
void frameSolver2d::createDofs()
{
  //  printf("coucou %d fixations\n",_fixations.size());
  for(std::size_t i = 0; i < _fixations.size(); ++i) {
    const gmshFixation &f = _fixations[i];
    //    printf("f._vertex(%d) = %p %d
    //    %g\n",i,f._vertex,f._direction,f._value);
    MVertex *v = f._vertex->mesh_vertices[0];
    Dof DOF(v->getNum(), f._direction);
    pAssembler->fixDof(DOF, f._value);
  }

  //  printf("coucou2\n");
  computeRotationTags();
  //  printf("coucou3\n");
  for(std::size_t i = 0; i < _beams.size(); i++) {
    //    printf("beam[%d] rot %d
    //    %d\n",i,_beams[i]._rotationTags[0],_beams[i]._rotationTags[1]);
    for(std::size_t j = 0; j < 2; j++) {
      MVertex *v = _beams[i]._element->getVertex(j);
      Dof theta(v->getNum(),
                Dof::createTypeWithTwoInts(2, _beams[i]._rotationTags[j]));
      pAssembler->numberDof(theta);
      Dof U(v->getNum(), 0);
      pAssembler->numberDof(U);
      Dof V(v->getNum(), 1);
      pAssembler->numberDof(V);
    }
  }
  //  printf("%d dofs\n",pAssembler->sizeOfR());
}
Пример #24
0
void Mesh::getGEntityPositions(std::vector<SPoint3> &xyz,
			       std::vector<SPoint3> &uvw) 
{
  xyz.resize(nVert());
  uvw.resize(nFV());
  for (int iV = 0; iV < nVert(); iV++)
    xyz[iV] = SPoint3(_vert[iV]->x(),_vert[iV]->y(),_vert[iV]->z());
  for (int iFV = 0; iFV < nFV(); iFV++){
    MVertex *v = _freeVert[iFV];
    if (v->onWhat()->dim() == 1){
      double t;
      v->getParameter(0,t);
      uvw[iFV] = SPoint3(t,0,0);
    }
    if (v->onWhat()->dim() == 2){
      double uu,vv;
      v->getParameter(0,uu);
      v->getParameter(1,vv);
      uvw[iFV] = SPoint3(uu,vv,0);
    }
  }
}
Пример #25
0
void MSubPoint::getIntegrationPoints(int pOrder, int *npts, IntPt **pts)
{
  // invariable regardless of the order
  if(!_pts)
  {
    if(!_orig) return;

    _pts = new IntPt[1];
    // work in the parametric space of the parent element
    MVertex *vi = getVertex(0);
    double v_xyz[3] = {vi->x(), vi->y(), vi->z()};
    double v_uvw[3];
    _orig->xyz2uvw(v_xyz, v_uvw);
    double jac[3][3];
    double origJac = _orig->getJacobian(v_uvw[0], v_uvw[1], v_uvw[2], jac);
    _pts[0].pt[0] = v_uvw[0];
    _pts[0].pt[1] = v_uvw[1];
    _pts[0].pt[2] = v_uvw[2];
    _pts[0].weight = 1./origJac;
  }
  *npts = 1;
  *pts = _pts;
}
Пример #26
0
void Centerline::distanceToSurface()
{
  Msg::Info("Centerline: computing distance to surface mesh ");

  //COMPUTE WITH REVERSE ANN TREE (SURFACE POINTS IN TREE)
  std::set<MVertex*> allVS;
  for(unsigned int j = 0; j < triangles.size(); j++)
    for(int k = 0; k<3; k++) allVS.insert(triangles[j]->getVertex(k));
  int nbSNodes = allVS.size();
  ANNpointArray nodesR = annAllocPts(nbSNodes, 3);
  vertices.resize(nbSNodes);
  int ind = 0;
  std::set<MVertex*>::iterator itp = allVS.begin();
  while (itp != allVS.end()){
    MVertex *v = *itp;
    nodesR[ind][0] = v->x();
    nodesR[ind][1] = v->y();
    nodesR[ind][2] = v->z();
    vertices[ind] = v;
    itp++; ind++;
  }
  kdtreeR = new ANNkd_tree(nodesR, nbSNodes, 3);

  for(unsigned int i = 0; i < lines.size(); i++){
    MLine *l = lines[i];
    MVertex *v1 = l->getVertex(0);
    MVertex *v2 = l->getVertex(1);
    double midp[3] = {0.5*(v1->x()+v2->x()), 0.5*(v1->y()+v1->y()),0.5*(v1->z()+v2->z())};
    ANNidx index[1];
    ANNdist dist[1];
    kdtreeR->annkSearch(midp, 1, index, dist);
    double minRad = sqrt(dist[0]);
    radiusl.insert(std::make_pair(lines[i], minRad));
  }

}
Пример #27
0
void frameSolver2d::solve()
{
#if defined(HAVE_PETSC)
  linearSystemPETSc<double> *lsys = new linearSystemPETSc<double>;
#elif defined(HAVE_GMM)
  linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>;
  lsys->setGmres(1);
  lsys->setNoisy(1);
#else
  linearSystemFull<double> *lsys = new linearSystemFull<double>;
#endif

  if(pAssembler) delete pAssembler;
  pAssembler = new dofManager<double>(lsys);

  // fix dofs and create free ones
  createDofs();

  // force vector
  std::vector<std::pair<GVertex *, std::vector<double> > >::iterator it =
    _nodalForces.begin();
  for(; it != _nodalForces.end(); ++it) {
    MVertex *v = it->first->mesh_vertices[0];
    const std::vector<double> &F = it->second;
    Dof DOFX(v->getNum(), 0);
    Dof DOFY(v->getNum(), 1);
    pAssembler->assemble(DOFX, F[0]);
    pAssembler->assemble(DOFY, F[1]);
  }

  // stifness matrix
  for(std::size_t i = 0; i < _beams.size(); i++) {
    fullMatrix<double> K(6, 6);
    computeStiffnessMatrix(i, K);
    _beams[i]._stiffness = K;
    MVertex *v0 = _beams[i]._element->getVertex(0);
    MVertex *v1 = _beams[i]._element->getVertex(1);
    Dof theta0(v0->getNum(),
               Dof::createTypeWithTwoInts(2, _beams[i]._rotationTags[0]));
    Dof theta1(v1->getNum(),
               Dof::createTypeWithTwoInts(2, _beams[i]._rotationTags[1]));
    Dof U0(v0->getNum(), 0);
    Dof U1(v1->getNum(), 0);
    Dof V0(v0->getNum(), 1);
    Dof V1(v1->getNum(), 1);
    Dof DOFS[6] = {U0, V0, theta0, U1, V1, theta1};
    for(int j = 0; j < 6; j++) {
      for(int k = 0; k < 6; k++) {
        pAssembler->assemble(DOFS[j], DOFS[k], K(j, k));
      }
    }
  }
  lsys->systemSolve();

  // save the solution
  for(std::size_t i = 0; i < _beams.size(); i++) {
    MVertex *v0 = _beams[i]._element->getVertex(0);
    MVertex *v1 = _beams[i]._element->getVertex(1);
    Dof theta0(v0->getNum(),
               Dof::createTypeWithTwoInts(2, _beams[i]._rotationTags[0]));
    Dof theta1(v1->getNum(),
               Dof::createTypeWithTwoInts(2, _beams[i]._rotationTags[1]));
    Dof U0(v0->getNum(), 0);
    Dof U1(v1->getNum(), 0);
    Dof V0(v0->getNum(), 1);
    Dof V1(v1->getNum(), 1);
    Dof DOFS[6] = {U0, V0, theta0, U1, V1, theta1};
    for(int j = 0; j < 6; j++) {
      pAssembler->getDofValue(DOFS[j], _beams[i]._displacement[j]);
    }
  }
  delete lsys;
  delete pAssembler;
}
Пример #28
0
int GModel::writeDIFF(const std::string &name, bool binary, bool saveAll,
                      double scalingFactor)
{
  if(binary){
    Msg::Error("Binary DIFF output is not implemented");
    return 0;
  }

  FILE *fp = Fopen(name.c_str(), binary ? "wb" : "w");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  if(noPhysicalGroups()) saveAll = true;

  // get the number of vertices and index the vertices in a continuous
  // sequence
  int numVertices = indexMeshVertices(saveAll);

  // tag the vertices according to which surface they belong to (Note
  // that we use a brute force approach here, so that we can deal with
  // models with incomplete topology. For example, when we merge 2 STL
  // triangulations we don't have the boundary information between the
  // faces, and the vertices would end up categorized on either one.)
  std::vector<std::list<int> > vertexTags(numVertices);
  std::list<int> boundaryIndicators;
  for(riter it = firstRegion(); it != lastRegion(); it++){
    std::list<GFace*> faces = (*it)->faces();
    for(std::list<GFace*>::iterator itf = faces.begin(); itf != faces.end(); itf++){
      GFace *gf = *itf;
      boundaryIndicators.push_back(gf->tag());
      for(unsigned int i = 0; i < gf->getNumMeshElements(); i++){
        MElement *e = gf->getMeshElement(i);
        for(int j = 0; j < e->getNumVertices(); j++){
          MVertex *v = e->getVertex(j);
          if(v->getIndex() > 0)
            vertexTags[v->getIndex() - 1].push_back(gf->tag());
        }
      }
    }
  }
  boundaryIndicators.sort();
  boundaryIndicators.unique();
  for(int i = 0; i < numVertices; i++){
    vertexTags[i].sort();
    vertexTags[i].unique();
  }

  // get all the entities in the model
  std::vector<GEntity*> entities;
  getEntities(entities);

  // find max dimension of mesh elements we need to save
  int dim = 0;
  for(unsigned int i = 0; i < entities.size(); i++)
    if(entities[i]->physicals.size() || saveAll)
      for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++)
        dim = std::max(dim, entities[i]->getMeshElement(j)->getDim());

  // loop over all elements we need to save
  int numElements = 0, maxNumNodesPerElement = 0;
  for(unsigned int i = 0; i < entities.size(); i++){
    if(entities[i]->physicals.size() || saveAll){
      for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
        MElement *e = entities[i]->getMeshElement(j);
        if(e->getStringForDIFF() && e->getDim() == dim){
          numElements++;
          maxNumNodesPerElement = std::max(maxNumNodesPerElement, e->getNumVertices());
        }
      }
    }
  }

  fprintf(fp, "\n\n");
  fprintf(fp, " Finite element mesh (GridFE):\n\n");
  fprintf(fp, " Number of space dim. =   3\n");
  fprintf(fp, " Number of elements   =  %d\n", numElements);
  fprintf(fp, " Number of nodes      =  %d\n\n", numVertices);
  fprintf(fp, " All elements are of the same type : dpTRUE\n");
  fprintf(fp, " Max number of nodes in an element: %d \n", maxNumNodesPerElement);
  fprintf(fp, " Only one subdomain               : dpFALSE\n");
  fprintf(fp, " Lattice data                     ? 0\n\n\n\n");
  fprintf(fp, " %d Boundary indicators:  ", (int)boundaryIndicators.size());
  for(std::list<int>::iterator it = boundaryIndicators.begin();
      it != boundaryIndicators.end(); it++)
    fprintf(fp, " %d", *it);

  fprintf(fp, "\n\n\n");
  fprintf(fp,"  Nodal coordinates and nodal boundary indicators,\n");
  fprintf(fp,"  the columns contain:\n");
  fprintf(fp,"   - node number\n");
  fprintf(fp,"   - coordinates\n");
  fprintf(fp,"   - no of boundary indicators that are set (ON)\n");
  fprintf(fp,"   - the boundary indicators that are set (ON) if any.\n");
  fprintf(fp,"#\n");

  // write mesh vertices
  for(unsigned int i = 0; i < entities.size(); i++){
    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
      MVertex *v = entities[i]->mesh_vertices[j];
      if(v->getIndex() > 0){
        v->writeDIFF(fp, binary, scalingFactor);
        fprintf(fp, " [%d] ", (int)vertexTags[v->getIndex() - 1].size());
        for(std::list<int>::iterator it = vertexTags[v->getIndex() - 1].begin();
            it != vertexTags[v->getIndex() - 1].end(); it++)
          fprintf(fp," %d ", *it);
        fprintf(fp,"\n");
      }
    }
  }

  fprintf(fp, "\n");
  fprintf(fp, "\n");
  fprintf(fp,     "  Element types and connectivity\n");
  fprintf(fp,     "  the columns contain:\n");
  fprintf(fp,     "   - element number\n");
  fprintf(fp,     "   - element type\n");
  fprintf(fp,     "   - subdomain number \n");
  fprintf(fp,     "   - the global node numbers of the nodes in the element.\n");
  fprintf(fp,     "#\n");

  // write mesh elements
  int num = 0;
  for(unsigned int i = 0; i < entities.size(); i++){
    if(entities[i]->physicals.size() || saveAll){
      for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
        MElement *e = entities[i]->getMeshElement(j);
        if(e->getStringForDIFF() && e->getDim() == dim)
          e->writeDIFF(fp, ++num, binary, entities[i]->tag());
      }
    }
  }
  fprintf(fp, "\n");

  fclose(fp);
  return 1;
}
Пример #29
0
int GModel::writeP3D(const std::string &name, bool saveAll,
                     double scalingFactor)
{
  FILE *fp = Fopen(name.c_str(), "w");
  if(!fp) {
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  if(noPhysicalGroups()) saveAll = true;

  std::vector<GFace *> faces;
  for(fiter it = firstFace(); it != lastFace(); ++it)
    if((*it)->transfinite_vertices.size() &&
       (*it)->transfinite_vertices[0].size() &&
       ((*it)->physicals.size() || saveAll))
      faces.push_back(*it);

  std::vector<GRegion *> regions;
  for(riter it = firstRegion(); it != lastRegion(); ++it)
    if((*it)->transfinite_vertices.size() &&
       (*it)->transfinite_vertices[0].size() &&
       (*it)->transfinite_vertices[0][0].size() &&
       ((*it)->physicals.size() || saveAll))
      regions.push_back(*it);

  if(faces.empty() && regions.empty()) {
    Msg::Warning("No structured grids to save");
    fclose(fp);
    return 0;
  }

  fprintf(fp, "%d\n", (int)(faces.size() + regions.size()));

  for(std::size_t i = 0; i < faces.size(); i++)
    fprintf(fp, "%d %d 1\n", (int)faces[i]->transfinite_vertices.size(),
            (int)faces[i]->transfinite_vertices[0].size());

  for(std::size_t i = 0; i < regions.size(); i++)
    fprintf(fp, "%d %d %d\n", (int)regions[i]->transfinite_vertices.size(),
            (int)regions[i]->transfinite_vertices[0].size(),
            (int)regions[i]->transfinite_vertices[0][0].size());

  for(std::size_t i = 0; i < faces.size(); i++) {
    GFace *gf = faces[i];
    for(int coord = 0; coord < 3; coord++) {
      for(std::size_t k = 0; k < gf->transfinite_vertices[0].size(); k++) {
        for(std::size_t j = 0; j < gf->transfinite_vertices.size(); j++) {
          MVertex *v = gf->transfinite_vertices[j][k];
          double d = (coord == 0) ? v->x() : (coord == 1) ? v->y() : v->z();
          fprintf(fp, "%.16g ", d * scalingFactor);
        }
        fprintf(fp, "\n");
      }
    }
  }

  for(std::size_t i = 0; i < regions.size(); i++) {
    GRegion *gr = regions[i];
    for(int coord = 0; coord < 3; coord++) {
      for(std::size_t l = 0; l < gr->transfinite_vertices[0][0].size(); l++) {
        for(std::size_t k = 0; k < gr->transfinite_vertices[0].size(); k++) {
          for(std::size_t j = 0; j < gr->transfinite_vertices.size(); j++) {
            MVertex *v = gr->transfinite_vertices[j][k][l];
            double d = (coord == 0) ? v->x() : (coord == 1) ? v->y() : v->z();
            fprintf(fp, "%.16g ", d * scalingFactor);
          }
          fprintf(fp, "\n");
        }
      }
    }
  }

  fclose(fp);
  return 1;
}
Пример #30
0
void GMSH_DistancePlugin::printView(std::vector<GEntity*> _entities,
                                    std::map<MVertex*, double > _distance_map)
{
  _fileName = DistanceOptions_String[0].def;
  _minScale = (double) DistanceOptions_Number[4].def;
  _maxScale = (double) DistanceOptions_Number[5].def;

  double minDist=1.e4;
  double maxDist=0.0;
  for (std::map<MVertex*,double >::iterator itv=_distance_map.begin();
       itv != _distance_map.end(); ++itv){
    double dist = itv->second;
    if (dist>maxDist) maxDist = dist;
    if (dist<minDist) minDist = dist;
    itv->second = dist;
  }

  Msg::Info("Writing %s", _fileName.c_str());
  FILE *fName = Fopen(_fileName.c_str(),"w");
  fprintf(fName, "View \"distance \"{\n");

  for (unsigned int ii=0; ii<_entities.size(); ii++) {
    if (_entities[ii]->dim() == _maxDim) {
      for (unsigned int i=0; i<_entities[ii]->getNumMeshElements(); i++) {
        MElement *e = _entities[ii]->getMeshElement(i);
        int numNodes = e->getNumVertices();
        if (e->getNumChildren())
          numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices();
        std::vector<double> x(numNodes), y(numNodes), z(numNodes);
        std::vector<double> *out = _data->incrementList(1, e->getType(), numNodes);
        std::vector<MVertex*> nods;

        if (!e->getNumChildren())
          for(int i = 0; i < numNodes; i++)
            nods.push_back(e->getVertex(i));
        else
          for(int i = 0; i < e->getNumChildren(); i++)
            for(int j = 0; j < e->getChild(i)->getNumVertices(); j++)
              nods.push_back(e->getChild(i)->getVertex(j));

        for (int nod = 0; nod < numNodes; nod++) out->push_back((nods[nod])->x());
        for (int nod = 0; nod < numNodes; nod++) out->push_back((nods[nod])->y());
        for (int nod = 0; nod < numNodes; nod++) out->push_back((nods[nod])->z());

        if (_maxDim == 2)
          switch (numNodes) {
            case 2: fprintf(fName,"SL("); break;
            case 3: fprintf(fName,"ST("); break;
            case 4: fprintf(fName,"SQ("); break;
            default: Msg::Error("Error in Plugin 'Distance' (numNodes=%d)",
                                numNodes); break;
          }
        else if (_maxDim == 3)
          switch (numNodes) {
            case 4: fprintf(fName,"SS("); break;
            case 8: fprintf(fName,"SH("); break;
            case 6: fprintf(fName,"SI("); break;
            case 5: fprintf(fName,"SY("); break;
            default: Msg::Error("Error in Plugin 'Distance' (numNodes=%d)",
                                numNodes); break;
          }

        std::vector<double> dist;
        for (int j=0; j<numNodes; j++) {
          MVertex *v =  nods[j];
          if (j)
            fprintf(fName, ",%.16g,%.16g,%.16g", v->x(), v->y(), v->z());
          else
            fprintf(fName, "%.16g,%.16g,%.16g", v->x(), v->y(), v->z());
          std::map<MVertex*, double>::iterator it = _distance_map.find(v);
          dist.push_back(it->second);
        }

        fprintf(fName,"){");
        for (unsigned int i=0; i<dist.size(); i++) {
          if (_minScale>0 && _maxScale>0)
            dist[i] = _minScale + ((dist[i] - minDist) / (maxDist - minDist)) *
              (_maxScale - _minScale);
          else if (_minScale>0 && _maxScale<0)
            dist[i] = _minScale + dist[i];
          out->push_back(dist[i]);
          if (i)
            fprintf(fName, ",%.16g", dist[i]);
          else
            fprintf(fName, "%.16g", dist[i]);
        }
        fprintf(fName,"};\n");

      }
    }
  }
  fprintf(fName,"};\n");

  fclose(fName);
}